mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-18 19:06:10 +00:00
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:
parent
90f5f2d4cc
commit
26c9dcc76c
@ -90,7 +90,6 @@ CutterGraphView::CutterGraphView(QWidget *parent)
|
|||||||
|
|
||||||
QPoint CutterGraphView::getTextOffset(int line) const
|
QPoint CutterGraphView::getTextOffset(int line) const
|
||||||
{
|
{
|
||||||
int padding = static_cast<int>(2 * charWidth);
|
|
||||||
return QPoint(padding, padding + line * charHeight);
|
return QPoint(padding, padding + line * charHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +98,12 @@ void CutterGraphView::initFont()
|
|||||||
setFont(Config()->getFont());
|
setFont(Config()->getFont());
|
||||||
QFontMetricsF metrics(font());
|
QFontMetricsF metrics(font());
|
||||||
baseline = int(metrics.ascent());
|
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());
|
charHeight = static_cast<int>(metrics.height());
|
||||||
charOffset = 0;
|
charOffset = 0;
|
||||||
mFontMetrics.reset(new CachedFontMetrics<qreal>(font()));
|
mFontMetrics.reset(new CachedFontMetrics<qreal>(font()));
|
||||||
|
@ -124,10 +124,11 @@ protected:
|
|||||||
|
|
||||||
// Font data
|
// Font data
|
||||||
std::unique_ptr<CachedFontMetrics<qreal>> mFontMetrics;
|
std::unique_ptr<CachedFontMetrics<qreal>> mFontMetrics;
|
||||||
qreal charWidth;
|
qreal ACharWidth; // width of character A
|
||||||
int charHeight;
|
int charHeight;
|
||||||
int charOffset;
|
int charOffset;
|
||||||
int baseline;
|
int baseline;
|
||||||
|
qreal padding;
|
||||||
|
|
||||||
// colors
|
// colors
|
||||||
QColor disassemblyBackgroundColor;
|
QColor disassemblyBackgroundColor;
|
||||||
|
@ -347,8 +347,9 @@ void DisassemblerGraphView::prepareGraphNode(GraphBlock &block)
|
|||||||
height += 1;
|
height += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int extra = static_cast<int>(4 * charWidth + 4);
|
int extra = static_cast<int>(2 * padding + 4);
|
||||||
block.width = static_cast<int>(width + extra + charWidth);
|
qreal indent = ACharWidth;
|
||||||
|
block.width = static_cast<int>(width + extra + indent);
|
||||||
block.height = (height * charHeight) + extra;
|
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);
|
QRectF blockRect(block.x, block.y, block.width, block.height);
|
||||||
|
|
||||||
const qreal padding = 2 * charWidth;
|
|
||||||
|
|
||||||
p.setPen(Qt::black);
|
p.setPen(Qt::black);
|
||||||
p.setBrush(Qt::gray);
|
p.setBrush(Qt::gray);
|
||||||
p.setFont(Config()->getFont());
|
p.setFont(Config()->getFont());
|
||||||
@ -412,12 +411,14 @@ void DisassemblerGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block,
|
|||||||
|
|
||||||
// Stop rendering text when it's too small
|
// Stop rendering text when it's too small
|
||||||
auto transform = p.combinedTransform();
|
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()) {
|
if (screenChar.width() < Config()->getGraphMinFontSize()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qreal indent = ACharWidth;
|
||||||
|
|
||||||
// Highlight selected tokens
|
// Highlight selected tokens
|
||||||
if (interactive && highlight_token != nullptr) {
|
if (interactive && highlight_token != nullptr) {
|
||||||
int y = firstInstructionY;
|
int y = firstInstructionY;
|
||||||
@ -436,20 +437,21 @@ void DisassemblerGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block,
|
|||||||
}
|
}
|
||||||
|
|
||||||
qreal widthBefore = mFontMetrics->width(instr.plainText.left(pos));
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal highlightWidth = tokenWidth;
|
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);
|
highlightWidth = block.width - widthBefore - (10 + 2 * padding);
|
||||||
}
|
}
|
||||||
|
|
||||||
QColor selectionColor = ConfigColor("wordHighlight");
|
QColor selectionColor = ConfigColor("wordHighlight");
|
||||||
|
|
||||||
p.fillRect(QRectF(block.x + charWidth * 3 + widthBefore, y, highlightWidth,
|
p.fillRect(
|
||||||
charHeight),
|
QRectF(block.x + textOffset + widthBefore, y, highlightWidth, charHeight),
|
||||||
selectionColor);
|
selectionColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
y += int(instr.text.lines.size()) * charHeight;
|
y += int(instr.text.lines.size()) * charHeight;
|
||||||
@ -467,7 +469,7 @@ void DisassemblerGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block,
|
|||||||
|
|
||||||
auto bih = Core()->getBIHighlighter();
|
auto bih = Core()->getBIHighlighter();
|
||||||
for (const Instr &instr : db.instrs) {
|
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)),
|
static_cast<int>(block.width - (10 + padding)),
|
||||||
int(instr.text.lines.size()) * charHeight);
|
int(instr.text.lines.size()) * charHeight);
|
||||||
|
|
||||||
@ -489,17 +491,8 @@ void DisassemblerGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (auto &line : instr.text.lines) {
|
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());
|
charHeight, 0, line, mFontMetrics.get());
|
||||||
y += charHeight;
|
y += charHeight;
|
||||||
}
|
}
|
||||||
@ -615,7 +608,7 @@ QRectF DisassemblerGraphView::getInstrRect(GraphView::GraphBlock &block, RVA add
|
|||||||
}
|
}
|
||||||
QPointF topLeft = getInstructionOffset(db, static_cast<int>(firstLineWithAddr));
|
QPointF topLeft = getInstructionOffset(db, static_cast<int>(firstLineWithAddr));
|
||||||
return QRectF(topLeft,
|
return QRectF(topLeft,
|
||||||
QSizeF(block.width - 4 * charWidth,
|
QSizeF(block.width - 2 * padding,
|
||||||
charHeight * int(currentLine - firstLineWithAddr)));
|
charHeight * int(currentLine - firstLineWithAddr)));
|
||||||
}
|
}
|
||||||
currentLine += instr.text.lines.size();
|
currentLine += instr.text.lines.size();
|
||||||
@ -771,7 +764,7 @@ void DisassemblerGraphView::copySelection()
|
|||||||
|
|
||||||
DisassemblerGraphView::Token *DisassemblerGraphView::getToken(Instr *instr, int x)
|
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) {
|
if (x < 0) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -1168,7 +1168,11 @@ void HexWidget::updateMetrics()
|
|||||||
{
|
{
|
||||||
QFontMetricsF fontMetrics(this->monospaceFont);
|
QFontMetricsF fontMetrics(this->monospaceFont);
|
||||||
lineHeight = fontMetrics.height();
|
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();
|
updateCounts();
|
||||||
updateAreasHeight();
|
updateAreasHeight();
|
||||||
|
@ -88,8 +88,6 @@ void SimpleTextGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block, b
|
|||||||
{
|
{
|
||||||
QRectF blockRect(block.x, block.y, block.width, block.height);
|
QRectF blockRect(block.x, block.y, block.width, block.height);
|
||||||
|
|
||||||
const qreal padding = charWidth;
|
|
||||||
|
|
||||||
p.setPen(Qt::black);
|
p.setPen(Qt::black);
|
||||||
p.setBrush(Qt::gray);
|
p.setBrush(Qt::gray);
|
||||||
p.setFont(Config()->getFont());
|
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
|
// Stop rendering text when it's too small
|
||||||
auto transform = p.combinedTransform();
|
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()) {
|
if (screenChar.width() < Config()->getGraphMinFontSize()) {
|
||||||
return;
|
return;
|
||||||
@ -156,9 +154,8 @@ void SimpleTextGraphView::addBlock(GraphLayout::GraphBlock block, const QString
|
|||||||
|
|
||||||
int height = 1;
|
int height = 1;
|
||||||
int width = mFontMetrics->width(text);
|
int width = mFontMetrics->width(text);
|
||||||
int extra = static_cast<int>(2 * charWidth);
|
block.width = static_cast<int>(width + padding);
|
||||||
block.width = static_cast<int>(width + extra);
|
block.height = (height * charHeight) + padding;
|
||||||
block.height = (height * charHeight) + extra;
|
|
||||||
GraphView::addBlock(std::move(block));
|
GraphView::addBlock(std::move(block));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user