1
0
Fork 0

GUI: used CachedFontMetrics to improve performance on drawing unicode text (although it's still pretty wank)

This commit is contained in:
mrexodia 2016-06-04 17:26:13 +02:00
parent 505aea109e
commit 521ed96254
No known key found for this signature in database
GPG Key ID: D72F9A4FAA0073B4
12 changed files with 64 additions and 17 deletions

View File

@ -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()

View File

@ -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

View File

@ -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;

View File

@ -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 "";
}

View File

@ -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;

View File

@ -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)
{

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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 \