work save:

Optimization for text render
This commit is contained in:
Roy Qu 2024-02-24 15:05:46 +08:00
parent cb2b119e46
commit 322c4bba4f
6 changed files with 65 additions and 34 deletions

View File

@ -1826,13 +1826,22 @@ void Editor::onStatusChanged(QSynedit::StatusChanges changes)
// scSelection includes anything caret related
if (changes.testFlag(QSynedit::StatusChange::scSelection)) {
if (!selAvail() && pSettings->editor().highlightCurrentWord()) {
mCurrentHighlightedWord = wordAtCursor();
} else if (selAvail() && blockBegin() == wordStart()
&& blockEnd() == wordEnd()){
mCurrentHighlightedWord = selText();
} else {
mCurrentHighlightedWord = "";
QString token;
QSynedit::PTokenAttribute attri;
if (getTokenAttriAtRowCol(caretXY(), token,attri)
&& (
(attri->tokenType()==QSynedit::TokenType::Identifier)
|| (attri->tokenType() == QSynedit::TokenType::Keyword)
|| (attri->tokenType() == QSynedit::TokenType::Preprocessor)
)) {
if (!selAvail() && pSettings->editor().highlightCurrentWord()) {
mCurrentHighlightedWord = token;
} else if (selAvail() && blockBegin() == wordStart()
&& blockEnd() == wordEnd()){
mCurrentHighlightedWord = selText();
} else {
mCurrentHighlightedWord = "";
}
}
if (mOldHighlightedWord != mCurrentHighlightedWord) {

View File

@ -46,6 +46,7 @@ Document::Document(const QFont& font, const QFont& nonAsciiFont, QObject *parent
mIndexOfLongestLine = -1;
mUpdateCount = 0;
mCharWidth = mFontMetrics.horizontalAdvance("M");
mSpaceWidth = mFontMetrics.horizontalAdvance(" ");
mUpdateDocumentLineWidthFunc = std::bind(&Document::calcLineWidth,
this,
std::placeholders::_1,
@ -594,6 +595,7 @@ void Document::setFontMetrics(const QFont &newFont, const QFont& newNonAsciiFont
{
mFontMetrics = QFontMetrics(newFont);
mCharWidth = mFontMetrics.horizontalAdvance("M");
mSpaceWidth = mFontMetrics.horizontalAdvance(" ");
mNonAsciiFontMetrics = QFontMetrics(newNonAsciiFont);
invalidateAllLineWidth();
}
@ -1020,7 +1022,10 @@ int Document::charToGlyphStartPosition(int line, const QString newStr, int charP
else
glyphStartCharList = calcGlyphStartCharList(newStr);
int glyphIdx = charToGlyphIndex(mLines[line]->lineText(), glyphStartCharList, charPos);
return mLines[line]->glyphStartPosition(glyphIdx);
if (glyphIdx<glyphStartCharList.length())
return glyphStartCharList[glyphIdx];
else
return newStr.length();
}
int Document::xposToGlyphStartChar(int line, const QString newStr, int xpos)

View File

@ -526,7 +526,7 @@ public:
}
int tabWidth() const {
return mTabSize * mCharWidth;
return mTabSize * mSpaceWidth;
}
void setTabSize(int newTabSize);
@ -574,6 +574,7 @@ private:
QFontMetrics mNonAsciiFontMetrics;
int mTabSize;
int mCharWidth;
int mSpaceWidth;
//int mCount;
//int mCapacity;
NewlineType mNewlineType;

View File

@ -51,7 +51,8 @@ QSynEditPainter::QSynEditPainter(QSynEdit *edit, QPainter *painter, int firstRow
mFirstRow{firstRow},
mLastRow{lastRow},
mLeft{left},
mRight{right}
mRight{right},
mLastGlyphAscii{false}
{
}
@ -131,7 +132,7 @@ void QSynEditPainter::paintGutter(const QRect& clip)
if (mEdit->mGutter.useFontStyle()) {
mPainter->setFont(mEdit->mGutter.font());
} else {
QFont newFont = mPainter->font();
QFont newFont = mEdit->font();
newFont.setBold(false);
newFont.setItalic(false);
newFont.setStrikeOut(false);
@ -368,7 +369,6 @@ void QSynEditPainter::paintToken(
first -= tokenLeft;
last -= tokenLeft;
QRect rcTokenBack = rcToken;
rcTokenBack.setWidth(rcTokenBack.width()-1);
mPainter->fillRect(rcTokenBack,mPainter->brush());
if (first > tokenWidth) {
} else {
@ -407,7 +407,10 @@ void QSynEditPainter::paintToken(
glyphWidth += mEdit->document()->glyphWidth(glyph2,0);
textToPaint+=glyph2;
}
if (!mLastGlyphAscii)
mPainter->setFont(font);
mPainter->drawText(nX,rcToken.bottom()-mPainter->fontMetrics().descent() , textToPaint);
mLastGlyphAscii = true;
drawed = true;
}
if (!drawed) {
@ -429,12 +432,18 @@ void QSynEditPainter::paintToken(
} else {
ch=glyph;
}
mPainter->drawText(nX+padding,rcToken.bottom()-mPainter->fontMetrics().descent() , ch);
if (ch!=" " && ch!="\t") {
if (!mLastGlyphAscii)
mPainter->setFont(font);
mPainter->drawText(nX+padding,rcToken.bottom()-mPainter->fontMetrics().descent() , ch);
mLastGlyphAscii = true;
}
//qDebug()<<"Drawing"<<glyph<<nX<<glyphWidth;
} else {
mPainter->setFont(fontForNonAscii);
if (mLastGlyphAscii)
mPainter->setFont(fontForNonAscii);
mPainter->drawText(nX,rcToken.bottom()-mPainter->fontMetrics().descent() , glyph);
mPainter->setFont(font);
mLastGlyphAscii = false;
}
drawed = true;
}
@ -541,6 +550,7 @@ void QSynEditPainter::paintHighlightToken(bool bFillToEOL)
font.setStrikeOut(mTokenAccu.style & FontStyle::fsStrikeOut);
font.setUnderline(mTokenAccu.style & FontStyle::fsUnderline);
mPainter->setFont(font);
mLastGlyphAscii=true;
QFont nonAsciiFont = mEdit->fontForNonAscii();
nonAsciiFont.setBold(mTokenAccu.style & FontStyle::fsBold);
nonAsciiFont.setItalic(mTokenAccu.style & FontStyle::fsItalic);
@ -825,6 +835,8 @@ void QSynEditPainter::paintLines()
int nFold;
QString sFold;
mLastGlyphAscii = false;
// Initialize rcLine for drawing. Note that Top and Bottom are updated
// inside the loop. Get only the starting point for this.
rcLine = mClip;

View File

@ -91,6 +91,8 @@ private:
int mFirstRow, mLastRow, mLeft, mRight;
SynTokenAccu mTokenAccu;
bool mLastGlyphAscii;
static QSet<QString> OperatorGlyphs;
};

View File

@ -673,12 +673,12 @@ void QSynEdit::invalidateGutterLine(int aLine)
invalidateGutterLines(aLine, aLine);
}
void QSynEdit::invalidateGutterLines(int FirstLine, int LastLine)
void QSynEdit::invalidateGutterLines(int firstLine, int lastLine)
{
QRect rcInval;
if (!isVisible())
return;
if (FirstLine == -1 && LastLine == -1) {
if (firstLine == -1 && lastLine == -1) {
rcInval = QRect(0, 0, mGutterWidth, clientHeight());
if (mStateFlags.testFlag(StateFlag::sfLinesChanging))
mInvalidateRect = mInvalidateRect.united(rcInval);
@ -686,21 +686,21 @@ void QSynEdit::invalidateGutterLines(int FirstLine, int LastLine)
invalidateRect(rcInval);
} else {
// find the visible lines first
if (LastLine < FirstLine)
std::swap(LastLine, FirstLine);
if (lastLine < firstLine)
std::swap(lastLine, firstLine);
if (mUseCodeFolding) {
FirstLine = lineToRow(FirstLine);
if (LastLine <= mDocument->count())
LastLine = lineToRow(LastLine);
firstLine = lineToRow(firstLine);
if (lastLine <= mDocument->count())
lastLine = lineToRow(lastLine);
else
LastLine = INT_MAX;
lastLine = INT_MAX;
}
FirstLine = std::max(FirstLine, mTopLine);
LastLine = std::min(LastLine, mTopLine + mLinesInWindow);
firstLine = std::max(firstLine, mTopLine);
lastLine = std::min(lastLine, mTopLine + mLinesInWindow);
// any line visible?
if (LastLine >= FirstLine) {
rcInval = {0, mTextHeight * (FirstLine - mTopLine),
mGutterWidth, mTextHeight * (LastLine - mTopLine + 1)};
if (lastLine >= firstLine) {
rcInval = {0, mTextHeight * (firstLine - mTopLine),
mGutterWidth, mTextHeight * (lastLine - firstLine + 1)};
if (mStateFlags.testFlag(StateFlag::sfLinesChanging)) {
mInvalidateRect = mInvalidateRect.united(rcInval);
} else {
@ -1015,6 +1015,7 @@ void QSynEdit::invalidateLines(int firstLine, int lastLine)
if (!isVisible())
return;
//qDebug()<<"invalidate lines:"<<firstLine<<lastLine;
if (firstLine == -1 && lastLine == -1) {
QRect rcInval = clientRect();
rcInval.setLeft(rcInval.left()+mGutterWidth);
@ -1051,7 +1052,7 @@ void QSynEdit::invalidateLines(int firstLine, int lastLine)
QRect rcInval = {
clientLeft()+mGutterWidth,
mTextHeight * (firstLine - mTopLine),
clientWidth(), mTextHeight * (lastLine - mTopLine + 1)
clientWidth(), mTextHeight * (lastLine - firstLine + 1)
};
if (mStateFlags.testFlag(StateFlag::sfLinesChanging))
mInvalidateRect = mInvalidateRect.united(rcInval);
@ -1072,6 +1073,8 @@ void QSynEdit::invalidateRect(const QRect &rect)
{
if (mPainterLock>0)
return;
// if (rect.height()>mTextHeight)
// qDebug()<<"invalidate rect"<<rect;
viewport()->update(rect);
}
@ -1079,6 +1082,7 @@ void QSynEdit::invalidate()
{
if (mPainterLock>0)
return;
// qDebug()<<"invalidate";
viewport()->update();
}
@ -2518,7 +2522,7 @@ QRect QSynEdit::calculateCaretRect() const
QString sLine = lineText().left(mCaretX-1)
+ mInputPreeditString
+ lineText().mid(mCaretX-1);
coord.x = charToGlyphLeft(mCaretY, sLine,mCaretX+mInputPreeditString.length());
coord.x = charToGlyphLeft(mCaretY, sLine, mCaretX+mInputPreeditString.length());
}
int rows=1;
if (mActiveSelectionMode == SelectionMode::Column) {
@ -4813,15 +4817,12 @@ void QSynEdit::moveCaretHorz(int deltaX, bool isSelection)
int row = lineToRow(ptDst.line);
row++;
int line = rowToLine(row);
// qDebug()<<line<<ptDst.Line;
if (line!=ptDst.line && line<=mDocument->count()) {
ptDst.line = line;
ptDst.ch = 1;
}
} else {
// qDebug()<<"Move caret horizontal"<<ptDst.line<<ptDst.ch<<glyphIndex<<deltaX;
ptDst.ch = std::max(1, mDocument->glyphStartChar(ptDst.line-1, glyphIndex + deltaX)+1);
qDebug()<<ptDst.ch;
// don't go past last char when ScrollPastEol option not set
if ((deltaX > 0) && bChangeY)
ptDst.ch = std::min(ptDst.ch, nLineLen + 1);
@ -6062,7 +6063,7 @@ void QSynEdit::paintEvent(QPaintEvent *event)
if (rcCaret == rcClip) {
// only update caret
// calculate the needed invalid area for caret
//qDebug()<<"update caret"<<rcCaret;
// qDebug()<<"update caret"<<rcCaret;
QRectF cacheRC;
qreal dpr = mContentImage->devicePixelRatioF();
cacheRC.setLeft(rcClip.left()*dpr);
@ -6071,6 +6072,7 @@ void QSynEdit::paintEvent(QPaintEvent *event)
cacheRC.setHeight(rcClip.height()*dpr);
painter.drawImage(rcCaret,*mContentImage,cacheRC);
} else {
//qDebug()<<"paint event:"<<rcClip;
QRect rcDraw;
int nL1, nL2, nX1, nX2;
// Compute the invalid area in lines / columns.