Use more approriate font mentrics in graph and hex views

* fix excessive graph padding for some fonts
* refactor code to make the position calculations more maintainable
* reduce graph view padding from 2 to 1 character widths in monospace
fonts
This commit is contained in:
Kārlis Seņko 2021-05-29 17:32:31 +03:00 committed by xarkes
parent 90f5f2d4cc
commit 26c9dcc76c
5 changed files with 32 additions and 33 deletions

View File

@ -90,7 +90,6 @@ CutterGraphView::CutterGraphView(QWidget *parent)
QPoint CutterGraphView::getTextOffset(int line) const
{
int padding = static_cast<int>(2 * charWidth);
return QPoint(padding, padding + line * charHeight);
}
@ -99,7 +98,12 @@ void CutterGraphView::initFont()
setFont(Config()->getFont());
QFontMetricsF metrics(font());
baseline = int(metrics.ascent());
charWidth = metrics.maxWidth();
#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
ACharWidth = metrics.width('A');
#else
ACharWidth = metrics.horizontalAdvance('A');
#endif
padding = ACharWidth;
charHeight = static_cast<int>(metrics.height());
charOffset = 0;
mFontMetrics.reset(new CachedFontMetrics<qreal>(font()));

View File

@ -124,10 +124,11 @@ protected:
// Font data
std::unique_ptr<CachedFontMetrics<qreal>> mFontMetrics;
qreal charWidth;
qreal ACharWidth; // width of character A
int charHeight;
int charOffset;
int baseline;
qreal padding;
// colors
QColor disassemblyBackgroundColor;

View File

@ -347,8 +347,9 @@ void DisassemblerGraphView::prepareGraphNode(GraphBlock &block)
height += 1;
}
}
int extra = static_cast<int>(4 * charWidth + 4);
block.width = static_cast<int>(width + extra + charWidth);
int extra = static_cast<int>(2 * padding + 4);
qreal indent = ACharWidth;
block.width = static_cast<int>(width + extra + indent);
block.height = (height * charHeight) + extra;
}
@ -356,8 +357,6 @@ void DisassemblerGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block,
{
QRectF blockRect(block.x, block.y, block.width, block.height);
const qreal padding = 2 * charWidth;
p.setPen(Qt::black);
p.setBrush(Qt::gray);
p.setFont(Config()->getFont());
@ -412,12 +411,14 @@ void DisassemblerGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block,
// Stop rendering text when it's too small
auto transform = p.combinedTransform();
QRect screenChar = transform.mapRect(QRect(0, 0, charWidth, charHeight));
QRect screenChar = transform.mapRect(QRect(0, 0, ACharWidth, charHeight));
if (screenChar.width() < Config()->getGraphMinFontSize()) {
return;
}
qreal indent = ACharWidth;
// Highlight selected tokens
if (interactive && highlight_token != nullptr) {
int y = firstInstructionY;
@ -436,20 +437,21 @@ void DisassemblerGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block,
}
qreal widthBefore = mFontMetrics->width(instr.plainText.left(pos));
if (charWidth * 3 + widthBefore > block.width - (10 + padding)) {
qreal textOffset = padding + indent;
if (textOffset + widthBefore > block.width - (10 + padding)) {
continue;
}
qreal highlightWidth = tokenWidth;
if (charWidth * 3 + widthBefore + tokenWidth >= block.width - (10 + padding)) {
if (textOffset + widthBefore + tokenWidth >= block.width - (10 + padding)) {
highlightWidth = block.width - widthBefore - (10 + 2 * padding);
}
QColor selectionColor = ConfigColor("wordHighlight");
p.fillRect(QRectF(block.x + charWidth * 3 + widthBefore, y, highlightWidth,
charHeight),
selectionColor);
p.fillRect(
QRectF(block.x + textOffset + widthBefore, y, highlightWidth, charHeight),
selectionColor);
}
y += int(instr.text.lines.size()) * charHeight;
@ -467,7 +469,7 @@ void DisassemblerGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block,
auto bih = Core()->getBIHighlighter();
for (const Instr &instr : db.instrs) {
const QRect instrRect = QRect(static_cast<int>(block.x + charWidth), y,
const QRect instrRect = QRect(static_cast<int>(block.x + indent), y,
static_cast<int>(block.width - (10 + padding)),
int(instr.text.lines.size()) * charHeight);
@ -489,17 +491,8 @@ void DisassemblerGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block,
}
for (auto &line : instr.text.lines) {
int rectSize = qRound(charWidth);
if (rectSize % 2) {
rectSize++;
}
// Assume charWidth <= charHeight
// TODO: Breakpoint/Cip stuff
QRectF bpRect(x - rectSize / 3.0, y + (charHeight - rectSize) / 2.0, rectSize,
rectSize);
Q_UNUSED(bpRect);
RichTextPainter::paintRichText<qreal>(&p, x + charWidth, y, block.width - charWidth,
RichTextPainter::paintRichText<qreal>(&p, x + indent, y, block.width - padding,
charHeight, 0, line, mFontMetrics.get());
y += charHeight;
}
@ -615,7 +608,7 @@ QRectF DisassemblerGraphView::getInstrRect(GraphView::GraphBlock &block, RVA add
}
QPointF topLeft = getInstructionOffset(db, static_cast<int>(firstLineWithAddr));
return QRectF(topLeft,
QSizeF(block.width - 4 * charWidth,
QSizeF(block.width - 2 * padding,
charHeight * int(currentLine - firstLineWithAddr)));
}
currentLine += instr.text.lines.size();
@ -771,7 +764,7 @@ void DisassemblerGraphView::copySelection()
DisassemblerGraphView::Token *DisassemblerGraphView::getToken(Instr *instr, int x)
{
x -= (int)(3 * charWidth); // Ignore left margin
x -= (int)(padding + ACharWidth); // Ignore left margin
if (x < 0) {
return nullptr;
}

View File

@ -1168,7 +1168,11 @@ void HexWidget::updateMetrics()
{
QFontMetricsF fontMetrics(this->monospaceFont);
lineHeight = fontMetrics.height();
charWidth = fontMetrics.maxWidth();
#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
charWidth = fontMetrics.width('A');
#else
charWidth = fontMetrics.horizontalAdvance('A');
#endif
updateCounts();
updateAreasHeight();

View File

@ -88,8 +88,6 @@ void SimpleTextGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block, b
{
QRectF blockRect(block.x, block.y, block.width, block.height);
const qreal padding = charWidth;
p.setPen(Qt::black);
p.setBrush(Qt::gray);
p.setFont(Config()->getFont());
@ -113,7 +111,7 @@ void SimpleTextGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block, b
// Stop rendering text when it's too small
auto transform = p.combinedTransform();
QRect screenChar = transform.mapRect(QRect(0, 0, charWidth, charHeight));
QRect screenChar = transform.mapRect(QRect(0, 0, ACharWidth, charHeight));
if (screenChar.width() < Config()->getGraphMinFontSize()) {
return;
@ -156,9 +154,8 @@ void SimpleTextGraphView::addBlock(GraphLayout::GraphBlock block, const QString
int height = 1;
int width = mFontMetrics->width(text);
int extra = static_cast<int>(2 * charWidth);
block.width = static_cast<int>(width + extra);
block.height = (height * charHeight) + extra;
block.width = static_cast<int>(width + padding);
block.height = (height * charHeight) + padding;
GraphView::addBlock(std::move(block));
}