GUI: used CachedFontMetrics to improve performance on drawing unicode text (although it's still pretty wank)
This commit is contained in:
parent
505aea109e
commit
521ed96254
|
|
@ -2,7 +2,9 @@
|
|||
#include <QStyleOptionButton>
|
||||
#include "Configuration.h"
|
||||
|
||||
AbstractTableView::AbstractTableView(QWidget* parent) : QAbstractScrollArea(parent)
|
||||
AbstractTableView::AbstractTableView(QWidget* parent)
|
||||
: QAbstractScrollArea(parent),
|
||||
mFontMetrics(nullptr)
|
||||
{
|
||||
// Class variable initialization
|
||||
mTableOffset = 0;
|
||||
|
|
@ -75,6 +77,8 @@ void AbstractTableView::updateColors()
|
|||
void AbstractTableView::updateFonts()
|
||||
{
|
||||
setFont(ConfigFont("AbstractTableView"));
|
||||
puts("updateFonts()");
|
||||
mFontMetrics = new CachedFontMetrics(this, font());
|
||||
}
|
||||
|
||||
void AbstractTableView::updateShortcuts()
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include "Configuration.h"
|
||||
#include "MenuBuilder.h"
|
||||
#include "QActionLambda.h"
|
||||
#include "CachedFontMetrics.h"
|
||||
|
||||
//Hacky class that fixes a really annoying cursor problem
|
||||
class AbstractTableScrollBar : public QScrollBar
|
||||
|
|
@ -204,6 +205,9 @@ protected:
|
|||
QColor headerTextColor;
|
||||
QColor selectionColor;
|
||||
|
||||
// Font metrics
|
||||
CachedFontMetrics* mFontMetrics;
|
||||
|
||||
//action helpers
|
||||
private:
|
||||
struct ActionShortcut
|
||||
|
|
|
|||
|
|
@ -424,7 +424,7 @@ QString Disassembly::paintContent(QPainter* painter, dsint rowBase, int rowOffse
|
|||
curByte.textColor = mBytesColor;
|
||||
richBytes.push_back(curByte);
|
||||
}
|
||||
RichTextPainter::paintRichText(painter, x, y, getColumnWidth(col), getRowHeight(), jumpsize + funcsize, richBytes, font());
|
||||
RichTextPainter::paintRichText(painter, x, y, getColumnWidth(col), getRowHeight(), jumpsize + funcsize, richBytes, mFontMetrics);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -467,7 +467,7 @@ QString Disassembly::paintContent(QPainter* painter, dsint rowBase, int rowOffse
|
|||
else
|
||||
CapstoneTokenizer::TokenToRichText(token, richText, 0);
|
||||
int xinc = 4;
|
||||
RichTextPainter::paintRichText(painter, x + loopsize, y, getColumnWidth(col) - loopsize, getRowHeight(), xinc, richText, font());
|
||||
RichTextPainter::paintRichText(painter, x + loopsize, y, getColumnWidth(col) - loopsize, getRowHeight(), xinc, richText, mFontMetrics);
|
||||
token.x = x + loopsize + xinc;
|
||||
}
|
||||
break;
|
||||
|
|
@ -648,7 +648,7 @@ void Disassembly::mousePressEvent(QMouseEvent* event)
|
|||
if(rowOffset < mInstBuffer.size())
|
||||
{
|
||||
CapstoneTokenizer::SingleToken token;
|
||||
if(CapstoneTokenizer::TokenFromX(mInstBuffer.at(rowOffset).tokens, token, event->x(), font()))
|
||||
if(CapstoneTokenizer::TokenFromX(mInstBuffer.at(rowOffset).tokens, token, event->x(), mFontMetrics))
|
||||
{
|
||||
if(CapstoneTokenizer::IsHighlightableToken(token) && !CapstoneTokenizer::TokenEquals(&token, &mHighlightToken))
|
||||
mHighlightToken = token;
|
||||
|
|
|
|||
|
|
@ -465,7 +465,7 @@ QString HexDump::paintContent(QPainter* painter, dsint rowBase, int rowOffset, i
|
|||
|
||||
RichTextPainter::List richText;
|
||||
getColumnRichText(col, wRva, richText);
|
||||
RichTextPainter::paintRichText(painter, x, y, w, h, 4, richText, font());
|
||||
RichTextPainter::paintRichText(painter, x, y, w, h, 4, richText, mFontMetrics);
|
||||
|
||||
return "";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ QString SearchListViewTable::paintContent(QPainter* painter, dsint rowBase, int
|
|||
}
|
||||
|
||||
//paint the rich text
|
||||
RichTextPainter::paintRichText(painter, x + 1, y, w, h, 4, richText, font());
|
||||
RichTextPainter::paintRichText(painter, x + 1, y, w, h, 4, richText, mFontMetrics);
|
||||
text = "";
|
||||
}
|
||||
return text;
|
||||
|
|
|
|||
|
|
@ -171,16 +171,15 @@ void CapstoneTokenizer::TokenToRichText(const InstructionToken & instr, RichText
|
|||
}
|
||||
}
|
||||
|
||||
bool CapstoneTokenizer::TokenFromX(const InstructionToken & instr, SingleToken & token, int x, const QFont & font)
|
||||
bool CapstoneTokenizer::TokenFromX(const InstructionToken & instr, SingleToken & token, int x, CachedFontMetrics* fontMetrics)
|
||||
{
|
||||
if(x < instr.x) //before the first token
|
||||
return false;
|
||||
int len = int(instr.tokens.size());
|
||||
QFontMetrics metrics(font);
|
||||
for(int i = 0, xStart = instr.x; i < len; i++)
|
||||
{
|
||||
const auto & curToken = instr.tokens.at(i);
|
||||
int curWidth = metrics.width(curToken.text);
|
||||
int curWidth = fontMetrics->width(curToken.text);
|
||||
int xEnd = xStart + curWidth;
|
||||
if(x >= xStart && x < xEnd)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ public:
|
|||
static void UpdateColors();
|
||||
static void UpdateStringPool();
|
||||
static void TokenToRichText(const InstructionToken & instr, RichTextPainter::List & richTextList, const SingleToken* highlightToken);
|
||||
static bool TokenFromX(const InstructionToken & instr, SingleToken & token, int x, const QFont & font);
|
||||
static bool TokenFromX(const InstructionToken & instr, SingleToken & token, int x, CachedFontMetrics* fontMetrics);
|
||||
static bool IsHighlightableToken(const SingleToken & token);
|
||||
static bool TokenEquals(const SingleToken* a, const SingleToken* b, bool ignoreSize = true);
|
||||
|
||||
|
|
|
|||
|
|
@ -260,7 +260,7 @@ QString ScriptView::paintContent(QPainter* painter, dsint rowBase, int rowOffset
|
|||
}
|
||||
|
||||
//paint the rich text
|
||||
RichTextPainter::paintRichText(painter, x + 1, y, w, h, xadd, richText, font());
|
||||
RichTextPainter::paintRichText(painter, x + 1, y, w, h, xadd, richText, mFontMetrics);
|
||||
returnString = "";
|
||||
}
|
||||
else //no syntax highlighting
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef CACHEDFONTMETRICS_H
|
||||
#define CACHEDFONTMETRICS_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QFont>
|
||||
#include <QFontMetrics>
|
||||
|
||||
class CachedFontMetrics : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CachedFontMetrics(QObject* parent, const QFont & font)
|
||||
: QObject(parent),
|
||||
mFontMetrics(font)
|
||||
{
|
||||
}
|
||||
|
||||
int width(const QChar & ch)
|
||||
{
|
||||
auto unicode = ch.unicode();
|
||||
if(!mWidths[unicode])
|
||||
return mWidths[unicode] = mFontMetrics.width(ch);
|
||||
return mWidths[unicode];
|
||||
}
|
||||
|
||||
int width(const QString & text)
|
||||
{
|
||||
int result = 0;
|
||||
for(const QChar & ch : text)
|
||||
result += width(ch);
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
QFontMetrics mFontMetrics;
|
||||
ushort mWidths[65536];
|
||||
};
|
||||
|
||||
#endif // CACHEDFONTMETRICS_H
|
||||
|
|
@ -1,16 +1,15 @@
|
|||
#include "RichTextPainter.h"
|
||||
|
||||
//TODO: fix performance
|
||||
void RichTextPainter::paintRichText(QPainter* painter, int x, int y, int w, int h, int xinc, const List & richText, const QFont & font)
|
||||
//TODO: fix performance (possibly use QTextLayout?)
|
||||
void RichTextPainter::paintRichText(QPainter* painter, int x, int y, int w, int h, int xinc, const List & richText, CachedFontMetrics* fontMetrics)
|
||||
{
|
||||
QPen pen;
|
||||
QPen highlightPen;
|
||||
highlightPen.setWidth(2);
|
||||
QBrush brush(Qt::cyan);
|
||||
QFontMetrics metrics(font);
|
||||
for(const auto & curRichText : richText)
|
||||
{
|
||||
int textWidth = metrics.width(curRichText.text);
|
||||
int textWidth = fontMetrics->width(curRichText.text);
|
||||
int backgroundWidth = textWidth;
|
||||
if(backgroundWidth + xinc > w)
|
||||
backgroundWidth = w - xinc;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include <QString>
|
||||
#include <QColor>
|
||||
#include <QPainter>
|
||||
#include "CachedFontMetrics.h"
|
||||
|
||||
class RichTextPainter
|
||||
{
|
||||
|
|
@ -30,7 +31,7 @@ public:
|
|||
typedef std::vector<CustomRichText_t> List;
|
||||
|
||||
//functions
|
||||
static void paintRichText(QPainter* painter, int x, int y, int w, int h, int xinc, const List & richText, const QFont & font);
|
||||
static void paintRichText(QPainter* painter, int x, int y, int w, int h, int xinc, const List & richText, CachedFontMetrics* fontMetrics);
|
||||
};
|
||||
|
||||
#endif // RICHTEXTPAINTER_H
|
||||
|
|
|
|||
|
|
@ -247,7 +247,8 @@ HEADERS += \
|
|||
Src/Utils/LongLongValidator.h \
|
||||
Src/Utils/MiscUtil.h \
|
||||
Src/Gui/XrefBrowseDialog.h \
|
||||
Src/Gui/CodepageSelectionDialog.h
|
||||
Src/Gui/CodepageSelectionDialog.h \
|
||||
Src/Utils/CachedFontMetrics.h
|
||||
|
||||
FORMS += \
|
||||
Src/Gui/MainWindow.ui \
|
||||
|
|
|
|||
Loading…
Reference in New Issue