Skip to content
Permalink
Browse files

wip

  • Loading branch information...
mrexodia committed Sep 7, 2019
1 parent 31443c2 commit ef6d6925b2c7fb8b9cc55ff6926388c10fb9b249
Showing with 105 additions and 1 deletion.
  1. +89 −1 src/gui/Src/BasicView/HexDump.cpp
  2. +4 −0 src/gui/Src/BasicView/HexDump.h
  3. +12 −0 src/gui/Src/Utils/RichTextPainter.h
@@ -11,6 +11,84 @@ static int dwordStringMaxLength(HexDump::DwordViewMode mode);
static int qwordStringMaxLength(HexDump::QwordViewMode mode);
static int twordStringMaxLength(HexDump::TwordViewMode mode);

class RichTextCache
{
void dbg(const QString & s) const
{
OutputDebugStringA(s.toUtf8().constData());
}
public:
struct CacheKey
{
int rowOffset;
int col;
// can be removed as long w and h are the same?
int x;
int y;
int w;
int h;

bool operator<(const CacheKey & o) const
{
return std::tie(rowOffset, col, x, y, w, h) < std::tie(o.rowOffset, o.col, o.x, o.y, o.w, o.h);
}
};

struct CacheValue
{
RichTextPainter::List richText;
QPixmap pixmap;
};

void paintRichText(QPainter* painter, int rowOffset, int col, int x, int y, int w, int h, int xinc, const RichTextPainter::List & richText, CachedFontMetrics* fontMetrics)
{
CacheKey key;
key.rowOffset = rowOffset;
key.col = col;
key.x = x;
key.y = y;
key.w = w;
key.h = h;
auto itr = mCache.find(key);
if(itr == mCache.end() || itr->second.richText != richText)
{
dbg(QString("[x64dbg] rowOffset: %2, col: %3, x: %4, y: %5, w: %6, h: %7").arg(rowOffset).arg(col).arg(x).arg(y).arg(w).arg(h));
itr = mCache.emplace(key, CacheValue()).first;
CacheValue & value = itr->second;
value.richText = richText;
value.pixmap = QPixmap(w, h);
value.pixmap.fill(Qt::transparent);
QPainter cachePainter(&value.pixmap);
cachePainter.setFont(QFont("Consolas", 8));
//cachePainter.setBackground(painter->background());
//cachePainter.setBackgroundMode(painter->backgroundMode());
//cachePainter.setBrush(painter->brush());
//cachePainter.setBrushOrigin(painter->brushOrigin());
//cachePainter.setFont(painter->font());
//cachePainter.setPen(painter->pen());
RichTextPainter::paintRichText(&cachePainter, 0, 0, w, h, xinc, richText, fontMetrics);
}
painter->drawPixmap(x, y, w, h, itr->second.pixmap);
}

void invalidate(duint tableOffsetRva, duint memBase, duint memSize)
{
if(tableOffsetRva == mTableOffsetRva && memBase == mMemBase && memSize == mMemSize)
return;
dbg("[x64dbg] RichTextCache::invalidate");
mTableOffsetRva = tableOffsetRva;
mMemBase = memBase;
mMemSize = memSize;
mCache.clear();
}

private:
duint mTableOffsetRva = 0;
duint mMemBase = 0;
duint mMemSize = 0;
std::map<CacheKey, CacheValue> mCache;
};

HexDump::HexDump(QWidget* parent)
: AbstractTableView(parent)
{
@@ -35,6 +113,7 @@ HexDump::HexDump(QWidget* parent)
mSyncAddrExpression = "";
mNonprintReplace = QChar('.'); //QChar(0x25CA);
mNullReplace = QChar('.'); //QChar(0x2022);
mRichTextCache = new RichTextCache();

// Slots
connect(Bridge::getBridge(), SIGNAL(updateDump()), this, SLOT(updateDumpSlot()));
@@ -626,11 +705,20 @@ void HexDump::keyPressEvent(QKeyEvent* event)
*/
}

void HexDump::paintEvent(QPaintEvent* event)
{
mRichTextCache->invalidate(getTableOffsetRva(), mMemPage->getBase(), mMemPage->getSize());
AbstractTableView::paintEvent(event);
}

QString HexDump::paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h)
{
// Reset byte offset when base address is reached
if(rowBase == 0 && mByteOffset != 0)
{
printDumpAt(mMemPage->getBase(), false, false);
mRichTextCache->invalidate(getTableOffsetRva(), mMemPage->getBase(), mMemPage->getSize());
}

// Compute RVA
int wBytePerRowCount = getBytePerRowCount();
@@ -641,7 +729,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, mFontMetrics);
mRichTextCache->paintRichText(painter, rowOffset, col, x, y, w, h, 4, richText, mFontMetrics);

return QString();
}
@@ -7,6 +7,8 @@
#include "VaHistory.h"
#include <QTextCodec>

class RichTextCache;

class HexDump : public AbstractTableView
{
Q_OBJECT
@@ -93,6 +95,7 @@ class HexDump : public AbstractTableView
void mousePressEvent(QMouseEvent* event) override;
void mouseReleaseEvent(QMouseEvent* event) override;
void keyPressEvent(QKeyEvent* event) override;
void paintEvent(QPaintEvent* event) override;

QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) override;
void paintGraphicDump(QPainter* painter, int x, int y, int addr);
@@ -139,6 +142,7 @@ class HexDump : public AbstractTableView
void setupCopyMenu();

VaHistory mHistory;
RichTextCache* mRichTextCache = nullptr;

signals:
void selectionUpdated();
@@ -30,6 +30,18 @@ class RichTextPainter
QColor highlightColor;
int highlightWidth = 2;
bool highlightConnectPrev = false;

bool operator==(const CustomRichText_t & o) const
{
return text == o.text
&& textColor == o.textColor
&& textBackground == o.textBackground
&& flags == o.flags
&& highlight == o.highlight
&& highlightColor == o.highlightColor
&& highlightWidth == o.highlightWidth
&& highlightConnectPrev == o.highlightConnectPrev;
}
};

typedef std::vector<CustomRichText_t> List;

0 comments on commit ef6d692

Please sign in to comment.
You can’t perform that action at this time.