optimize painter.
This commit is contained in:
parent
3e1e4b0f01
commit
72481d7de8
|
@ -2245,6 +2245,7 @@ void Editor::onTooltipTimer()
|
|||
void Editor::onEndParsing()
|
||||
{
|
||||
mIdentCache.clear();
|
||||
document()->invalidateAllLineWidth();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
|
@ -5562,7 +5563,8 @@ void Editor::applyColorScheme(const QString& schemeName)
|
|||
mCurrentHighlighWordForeground = selectedForeground();
|
||||
mCurrentHighlighWordBackground = selectedBackground();
|
||||
}
|
||||
this->invalidate();
|
||||
document()->invalidateAllLineWidth();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
void Editor::updateCaption(const QString& newCaption) {
|
||||
|
|
|
@ -1155,6 +1155,13 @@ void Document::internalClear()
|
|||
}
|
||||
}
|
||||
|
||||
bool Document::lineWidthValid(int line)
|
||||
{
|
||||
if (line<0 || line>=mLines.count())
|
||||
return false;
|
||||
return mLines[line]->mWidth>=0 && !mLines[line]->mIsTempWidth;
|
||||
}
|
||||
|
||||
void Document::beginSetLinesWidth()
|
||||
{
|
||||
if (mSetLineWidthLockCount == 0) {
|
||||
|
@ -1172,15 +1179,15 @@ void Document::endSetLinesWidth()
|
|||
}
|
||||
}
|
||||
|
||||
void Document::setLineWidth(int line, const QString &lineText, int newWidth, const QList<int> glyphStartPositionList)
|
||||
void Document::setLineWidth(int line, int newWidth, const QList<int> glyphStartPositionList)
|
||||
{
|
||||
QMutexLocker locker(&mMutex);
|
||||
if (line<0 || line>=count())
|
||||
return ;
|
||||
if (lineText != mLines[line]->lineText())
|
||||
return;
|
||||
int oldWidth = mLines[line]->mWidth;
|
||||
//qDebug()<<line<<oldWidth<<newWidth;
|
||||
mLines[line]->mWidth = newWidth;
|
||||
mLines[line]->mIsTempWidth = false;
|
||||
mLines[line]->mGlyphStartPositionList = glyphStartPositionList;
|
||||
if (mIndexOfLongestLine<0) {
|
||||
mIndexOfLongestLine = line;
|
||||
|
@ -1246,6 +1253,23 @@ QList<int> Document::getGlyphStartCharList(int line, const QString &lineText)
|
|||
return mLines[line]->glyphStartCharList();
|
||||
}
|
||||
|
||||
QList<int> Document::getGlyphStartCharList(int line)
|
||||
{
|
||||
if (line<0 || line>=count())
|
||||
return QList<int>();
|
||||
return mLines[line]->glyphStartCharList();
|
||||
}
|
||||
|
||||
QList<int> Document::getGlyphStartPositionList(int line)
|
||||
{
|
||||
return mLines[line]->glyphStartPositionList();
|
||||
}
|
||||
|
||||
int Document::getLineWidth(int line)
|
||||
{
|
||||
return mLines[line]->mWidth;
|
||||
}
|
||||
|
||||
NewlineType Document::getNewlineType()
|
||||
{
|
||||
QMutexLocker locker(&mMutex);
|
||||
|
@ -1276,6 +1300,7 @@ void Document::invalidateAllLineWidth()
|
|||
DocumentLine::DocumentLine(DocumentLine::UpdateWidthFunc updateWidthFunc):
|
||||
mSyntaxState{},
|
||||
mWidth{-1},
|
||||
mIsTempWidth{true},
|
||||
mUpdateWidthFunc{updateWidthFunc}
|
||||
{
|
||||
}
|
||||
|
|
|
@ -147,7 +147,7 @@ private:
|
|||
|
||||
void setLineText(const QString &newLineText);
|
||||
void updateWidth();
|
||||
void invalidateWidth() { mWidth = -1; mGlyphStartPositionList.clear(); }
|
||||
void invalidateWidth() { mWidth = -1; mGlyphStartPositionList.clear(); mIsTempWidth = true;}
|
||||
private:
|
||||
QString mLineText; /* the unicode code points of the text */
|
||||
/**
|
||||
|
@ -181,7 +181,7 @@ private:
|
|||
* so it must be recalculated each time the font is changed.
|
||||
*/
|
||||
int mWidth;
|
||||
|
||||
bool mIsTempWidth;
|
||||
UpdateWidthFunc mUpdateWidthFunc;
|
||||
|
||||
friend class Document;
|
||||
|
@ -576,9 +576,10 @@ protected:
|
|||
void putTextStr(const QString& text);
|
||||
void internalClear();
|
||||
private:
|
||||
bool lineWidthValid(int line);
|
||||
void beginSetLinesWidth();
|
||||
void endSetLinesWidth();
|
||||
void setLineWidth(int line, const QString& lineText, int newWidth, const QList<int> glyphStartPositionList);
|
||||
void setLineWidth(int line, int newWidth, const QList<int> glyphStartPositionList);
|
||||
void updateMaxLineWidthChanged();
|
||||
void updateMaxLineWidthAndNotify();
|
||||
|
||||
|
@ -595,6 +596,9 @@ private:
|
|||
QList<int> calcGlyphPositionList(const QString& lineText, const QList<int> &glyphStartCharList, int left, int &right) const;
|
||||
QList<int> calcGlyphPositionList(const QString& lineText, int &width) const;
|
||||
QList<int> getGlyphStartCharList(int line, const QString &lineText);
|
||||
QList<int> getGlyphStartCharList(int line);
|
||||
QList<int> getGlyphStartPositionList(int line);
|
||||
int getLineWidth(int line);
|
||||
bool tryLoadFileByEncoding(QByteArray encodingName, QFile& file);
|
||||
void loadUTF16BOMFile(QFile& file);
|
||||
void loadUTF32BOMFile(QFile& file);
|
||||
|
|
|
@ -707,9 +707,25 @@ void QSynEditPainter::addHighlightToken(
|
|||
const QList<int> glyphStartCharList,
|
||||
int tokenStartChar,
|
||||
int tokenEndChar,
|
||||
bool calcGlyphPosition,
|
||||
QList<int> &glyphStartPositionList,
|
||||
int &tokenWidth)
|
||||
{
|
||||
int tokenRight;
|
||||
int startGlyph, endGlyph;
|
||||
if (!calcGlyphPosition) {
|
||||
tokenRight = std::max(0,tokenLeft);
|
||||
startGlyph = searchForSegmentIdx(glyphStartCharList,0,lineText.length(),tokenStartChar);
|
||||
endGlyph = searchForSegmentIdx(glyphStartCharList,0,lineText.length(),tokenEndChar);
|
||||
for (int i=startGlyph;i<endGlyph;i++) {
|
||||
int gWidth = calcSegmentInterval(glyphStartPositionList, mCurrentLineWidth, i);
|
||||
tokenRight += gWidth;
|
||||
}
|
||||
tokenWidth = tokenRight-tokenLeft;
|
||||
if (tokenRight<mLeft) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
QColor foreground, background;
|
||||
FontStyles style;
|
||||
|
||||
|
@ -767,22 +783,22 @@ void QSynEditPainter::addHighlightToken(
|
|||
mTokenAccu.font.setUnderline(style & FontStyle::fsUnderline);
|
||||
}
|
||||
//calculate width of the token ( and update it's glyph start positions )
|
||||
int tokenRight;
|
||||
int startGlyph, endGlyph;
|
||||
tokenWidth = mEdit->mDocument->updateGlyphStartPositionList(
|
||||
lineText,
|
||||
glyphStartCharList,
|
||||
tokenStartChar,
|
||||
tokenEndChar,
|
||||
QFontMetrics(mTokenAccu.font),
|
||||
glyphStartPositionList,
|
||||
tokenLeft,
|
||||
tokenRight,
|
||||
startGlyph,
|
||||
endGlyph);
|
||||
if (calcGlyphPosition) {
|
||||
tokenWidth = mEdit->mDocument->updateGlyphStartPositionList(
|
||||
lineText,
|
||||
glyphStartCharList,
|
||||
tokenStartChar,
|
||||
tokenEndChar,
|
||||
QFontMetrics(mTokenAccu.font),
|
||||
glyphStartPositionList,
|
||||
tokenLeft,
|
||||
tokenRight,
|
||||
startGlyph,
|
||||
endGlyph);
|
||||
}
|
||||
|
||||
// Only accumulate tokens if it's visible.
|
||||
if (tokenLeft < mRight) {
|
||||
if (tokenLeft < mRight && tokenRight>mLeft) {
|
||||
if (bCanAppend) {
|
||||
mTokenAccu.width += tokenWidth;
|
||||
Q_ASSERT(startGlyph == mTokenAccu.endGlyph);
|
||||
|
@ -951,6 +967,7 @@ void QSynEditPainter::paintLines()
|
|||
BufferCoord selectionEnd= mEdit->blockEnd();
|
||||
for (int row = mFirstRow; row<=mLastRow; row++) {
|
||||
int vLine = mEdit->rowToLine(row);
|
||||
bool lineTextChanged = false;
|
||||
if (vLine > mEdit->mDocument->count() && mEdit->mDocument->count() != 0)
|
||||
break;
|
||||
|
||||
|
@ -966,6 +983,7 @@ void QSynEditPainter::paintLines()
|
|||
int ch = mEdit->mDocument->charToGlyphStartChar(mEdit->mCaretY-1,mEdit->mCaretX-1);
|
||||
sLine = sLine.left(ch) + mEdit->mInputPreeditString
|
||||
+ sLine.mid(ch);
|
||||
lineTextChanged = true;
|
||||
}
|
||||
// Initialize the text and background colors, maybe the line should
|
||||
// use special values for them.
|
||||
|
@ -1036,10 +1054,23 @@ void QSynEditPainter::paintLines()
|
|||
|
||||
mRcToken = mRcLine;
|
||||
|
||||
QList<int> glyphStartCharList = mEdit->mDocument->getGlyphStartCharList(vLine-1,sLine);
|
||||
QList<int> glyphStartCharList;
|
||||
if (lineTextChanged) {
|
||||
glyphStartCharList = mEdit->mDocument->getGlyphStartCharList(vLine-1,sLine);
|
||||
} else {
|
||||
glyphStartCharList = mEdit->mDocument->getGlyphStartCharList(vLine-1);
|
||||
}
|
||||
// Ensure the list has the right number of elements.
|
||||
// Values in it doesn't matter, we'll recalculate them.
|
||||
QList<int> glyphStartPositionsList = glyphStartCharList;
|
||||
QList<int> glyphStartPositionsList;
|
||||
bool lineWidthValid = mEdit->mDocument->lineWidthValid(vLine-1);
|
||||
bool calculateGlyphPositions = ( mHasSelectionInLine || lineTextChanged || !lineWidthValid);
|
||||
if (calculateGlyphPositions) {
|
||||
glyphStartPositionsList = glyphStartCharList;
|
||||
} else {
|
||||
glyphStartPositionsList = mEdit->mDocument->getGlyphStartPositionList(vLine-1);
|
||||
mCurrentLineWidth = mEdit->mDocument->getLineWidth(vLine-1);
|
||||
}
|
||||
// Initialize highlighter with line text and range info. It is
|
||||
// necessary because we probably did not scan to the end of the last
|
||||
// line - the internal highlighter range might be wrong.
|
||||
|
@ -1061,15 +1092,6 @@ void QSynEditPainter::paintLines()
|
|||
sToken = mEdit->mSyntaxer->getToken();
|
||||
if (sToken.isEmpty()) {
|
||||
continue;
|
||||
// mEdit->mSyntaxer->next();
|
||||
// if (mEdit->mSyntaxer->eol())
|
||||
// break;
|
||||
// sToken = mEdit->mSyntaxer->getToken();
|
||||
// // Maybe should also test whether GetTokenPos changed...
|
||||
// if (sToken.isEmpty()) {
|
||||
// //qDebug()<<QSynEdit::tr("The highlighter seems to be in an infinite loop");
|
||||
// throw BaseError(QSynEdit::tr("The syntaxer seems to be in an infinite loop"));
|
||||
// }
|
||||
}
|
||||
int tokenStartChar = mEdit->mSyntaxer->getTokenPos();
|
||||
int tokenEndChar = tokenStartChar + sToken.length();
|
||||
|
@ -1130,13 +1152,21 @@ void QSynEditPainter::paintLines()
|
|||
glyphStartCharList,
|
||||
tokenStartChar,
|
||||
tokenEndChar,
|
||||
calculateGlyphPositions,
|
||||
glyphStartPositionsList,
|
||||
tokenWidth);
|
||||
tokenLeft+=tokenWidth;
|
||||
//We don't need to calculate line width,
|
||||
//So we just quit if already out of the right edge of the editor
|
||||
if (
|
||||
(!calculateGlyphPositions || lineTextChanged)
|
||||
&& (tokenLeft>mRight))
|
||||
break;
|
||||
// Let the highlighter scan the next token.
|
||||
mEdit->mSyntaxer->next();
|
||||
}
|
||||
mEdit->mDocument->setLineWidth(vLine-1, sLine, tokenLeft, glyphStartPositionsList);
|
||||
if (!lineWidthValid)
|
||||
mEdit->mDocument->setLineWidth(vLine-1, tokenLeft, glyphStartPositionsList);
|
||||
if (tokenLeft<mRight) {
|
||||
QString addOnStr;
|
||||
|
||||
|
@ -1170,6 +1200,7 @@ void QSynEditPainter::paintLines()
|
|||
glyphStartCharList,
|
||||
oldLen,
|
||||
sLine.length(),
|
||||
calculateGlyphPositions,
|
||||
glyphStartPositionsList,
|
||||
tokenWidth);
|
||||
tokenLeft += tokenWidth;
|
||||
|
|
|
@ -96,6 +96,7 @@ private:
|
|||
const QList<int> glyphStartCharList,
|
||||
int tokenStartChar,
|
||||
int tokenEndChar,
|
||||
bool calcGlyphPosition,
|
||||
QList<int> &glyphStartPositionList,
|
||||
int &tokenWidth
|
||||
);
|
||||
|
@ -121,6 +122,7 @@ private:
|
|||
// info about selection of the current line
|
||||
int mLineSelStart, mLineSelEnd;
|
||||
bool mHasSelectionInLine;
|
||||
int mCurrentLineWidth;
|
||||
// painting the background and the text
|
||||
QRect mRcLine, mRcToken;
|
||||
int mFirstLine, mLastLine;
|
||||
|
|
|
@ -4678,6 +4678,7 @@ void QSynEdit::setSyntaxer(const PSyntaxer &syntaxer)
|
|||
reparseDocument();
|
||||
mDocument->endUpdate();
|
||||
}
|
||||
mDocument->invalidateAllLineWidth();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue