diff --git a/libs/qsynedit/qsynedit/document.cpp b/libs/qsynedit/qsynedit/document.cpp index 9c539b51..791458ff 100644 --- a/libs/qsynedit/qsynedit/document.cpp +++ b/libs/qsynedit/qsynedit/document.cpp @@ -46,6 +46,11 @@ Document::Document(const QFont& font, const QFont& nonAsciiFont, QObject *parent mIndexOfLongestLine = -1; mUpdateCount = 0; mCharWidth = mFontMetrics.horizontalAdvance("M"); + mUpdateDocumentLineWidthFunc = std::bind(&Document::calcLineWidth, + this, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3); } static void listIndexOutOfBounds(int index) { @@ -85,10 +90,7 @@ int Document::lineWidth(int line) { QMutexLocker locker(&mMutex); if (line>=0 && line < mLines.size()) { - if (mLines[line]->width() == -1) { - return calculateLineWidth(line); - } else - return mLines[line]->width(); + return mLines[line]->width(); } else return 0; } @@ -100,10 +102,7 @@ int Document::lineWidth(int line, const QString &newText) return 0; QString lineText = mLines[line]->lineText(); if (lineText==newText) { - if (mLines[line]->width() == -1) { - return calculateLineWidth(line); - } else - return mLines[line]->width(); + return mLines[line]->width(); } else { return stringWidth(newText,0); } @@ -187,7 +186,8 @@ SyntaxState Document::getSyntaxState(int line) void Document::insertItem(int line, const QString &s) { beginUpdate(); - PDocumentLine documentLine = std::make_shared(); + PDocumentLine documentLine = std::make_shared( + mUpdateDocumentLineWidthFunc); documentLine->setLineText(s); mIndexOfLongestLine = -1; mLines.insert(line,documentLine); @@ -197,7 +197,7 @@ void Document::insertItem(int line, const QString &s) void Document::addItem(const QString &s) { beginUpdate(); - PDocumentLine line = std::make_shared(); + PDocumentLine line = std::make_shared(mUpdateDocumentLineWidthFunc); line->setLineText(s); mIndexOfLongestLine = -1; mLines.append(line); @@ -469,7 +469,6 @@ void Document::putLine(int index, const QString &s, bool notify) { beginUpdate(); int oldColumns = mLines[index]->width(); mLines[index]->setLineText( s ); - calculateLineWidth(index); if (mIndexOfLongestLine == index && oldColumns>mLines[index]->width() ) mIndexOfLongestLine = -1; else if (mIndexOfLongestLine>=0 @@ -490,16 +489,6 @@ void Document::setUpdateState(bool Updating) emit changed(); } -int Document::calculateLineWidth(int line) -{ - PDocumentLine documentLine = mLines[line]; - QList glyphPositionList; - int width; - glyphPositionList = calcGlyphPositionList(documentLine->lineText(), documentLine->glyphStartCharList(), 0, width); - documentLine->setWidth(width, glyphPositionList); - return documentLine->width(); -} - void Document::insertLines(int index, int numLines) { QMutexLocker locker(&mMutex); @@ -516,7 +505,7 @@ void Document::insertLines(int index, int numLines) PDocumentLine line; mLines.insert(index,numLines,line); for (int i=index;i(); + line = std::make_shared(mUpdateDocumentLineWidthFunc); mLines[i]=line; } emit inserted(index,numLines); @@ -834,7 +823,7 @@ QString Document::glyphAt(int line, int charPos) { QMutexLocker locker(&mMutex); QList glyphStartCharList = mLines[line]->glyphStartCharList(); - int glyphIdx = charToGlyphIndex(glyphStartCharList, charPos); + int glyphIdx = charToGlyphIndex(mLines[line]->lineText(), glyphStartCharList, charPos); return mLines[line]->glyph(glyphIdx); } @@ -842,7 +831,7 @@ int Document::charToGlyphStartChar(int line, int charPos) { QMutexLocker locker(&mMutex); QList glyphStartCharList = mLines[line]->glyphStartCharList(); - int glyphIdx = charToGlyphIndex(glyphStartCharList, charPos); + int glyphIdx = charToGlyphIndex(mLines[line]->lineText(), glyphStartCharList, charPos); return mLines[line]->glyphStartChar(glyphIdx); } @@ -949,13 +938,17 @@ int Document::glyphWidth(const QString &glyph, int left) const int Document::charToGlyphIndex(int line, int charIdx) { QMutexLocker locker(&mMutex); + if (line<0 || line>count()) + return 0; QList glyphStartCharList = mLines[line]->glyphStartCharList(); - return charToGlyphIndex(glyphStartCharList, charIdx); + return charToGlyphIndex(mLines[line]->lineText(), glyphStartCharList, charIdx); } -int Document::charToGlyphIndex(QList glyphStartCharList, int charIdx) const +int Document::charToGlyphIndex(const QString& str, QList glyphStartCharList, int charIdx) const { Q_ASSERT(charIdx>=0); + if (charIdx>=str.length()) + return glyphStartCharList.length(); for (int i=0;icharIdx) { Q_ASSERT(i-1>=0); @@ -966,23 +959,29 @@ int Document::charToGlyphIndex(QList glyphStartCharList, int charIdx) const return glyphStartCharList.length()-1; } +QList Document::calcLineWidth(const QString &lineText, const QList &glyphStartCharList, int &width) +{ + return calcGlyphPositionList(lineText,glyphStartCharList,0,width); +} + int Document::xposToGlyphIndex(int line, int xpos) { QMutexLocker locker(&mMutex); + if (line<0 || line>=count()) + return 0; QList glyphPositionList = mLines[line]->glyphPositionList(); - return xposToGlyphIndex(glyphPositionList, xpos); + return xposToGlyphIndex(mLines[line]->width(), glyphPositionList, xpos); } -int Document::xposToGlyphIndex(QList glyphPositionList, int xpos) const +int Document::xposToGlyphIndex(int strWidth, QList glyphPositionList, int xpos) const { - Q_ASSERT(xpos>=0); + if (xpos>=strWidth) + return glyphPositionList.length(); for (int i=0;ixpos) { - Q_ASSERT(i-1>=0); return i-1; } } - Q_ASSERT(glyphPositionList.length()-1>=0); return glyphPositionList.length()-1; } @@ -990,15 +989,17 @@ int Document::charToGlyphStartPosition(int line, int charPos) { QMutexLocker locker(&mMutex); QList glyphStartCharList = mLines[line]->glyphStartCharList(); - int glyphIdx = charToGlyphIndex(glyphStartCharList, charPos); + int glyphIdx = charToGlyphIndex(mLines[line]->lineText(), glyphStartCharList, charPos); return mLines[line]->glyphStartPosition(glyphIdx); } int Document::xposToGlyphStartChar(int line, int xpos) { QMutexLocker locker(&mMutex); + if (line<0 || line>=count()) + return 0; QList glyphPositionList = mLines[line]->glyphPositionList(); - int glyphIdx = xposToGlyphIndex(glyphPositionList, xpos); + int glyphIdx = xposToGlyphIndex(mLines[line]->width(), glyphPositionList, xpos); return mLines[line]->glyphStartChar(glyphIdx); } @@ -1010,20 +1011,24 @@ int Document::charToGlyphStartPosition(int line, const QString newStr, int charP glyphStartCharList = mLines[line]->glyphStartCharList(); else glyphStartCharList = calcGlyphStartCharList(newStr); - int glyphIdx = charToGlyphIndex(glyphStartCharList, charPos); + int glyphIdx = charToGlyphIndex(mLines[line]->lineText(), glyphStartCharList, charPos); return mLines[line]->glyphStartPosition(glyphIdx); } int Document::xposToGlyphStartChar(int line, const QString newStr, int xpos) { QMutexLocker locker(&mMutex); + if (line<0 || line>=count()) + return 0; QList glyphPositionList; - if (mLines[line]->lineText() == newStr) + int width; + if (mLines[line]->lineText() == newStr) { glyphPositionList = mLines[line]->glyphPositionList(); - else { - glyphPositionList = calcGlyphPositionList(mLines[line]->lineText()); + width = mLines[line]->width(); + } else { + glyphPositionList = calcGlyphPositionList(mLines[line]->lineText(), width); } - int glyphIdx = xposToGlyphIndex(glyphPositionList, xpos); + int glyphIdx = xposToGlyphIndex(width, glyphPositionList, xpos); return mLines[line]->glyphStartChar(glyphIdx); } @@ -1122,11 +1127,11 @@ QList Document::calcGlyphPositionList(const QString &lineText, const QList< return glyphPostionList; } -QList Document::calcGlyphPositionList(const QString &lineText) const + +QList Document::calcGlyphPositionList(const QString &lineText, int &width) const { QList glyphStartCharList = calcGlyphStartCharList(lineText); - int right; - return calcGlyphPositionList(lineText,glyphStartCharList,0,right); + return calcGlyphPositionList(lineText,glyphStartCharList,0,width); } NewlineType Document::getNewlineType() @@ -1156,39 +1161,68 @@ void Document::invalidateAllLineWidth() } } -DocumentLine::DocumentLine(): +DocumentLine::DocumentLine(DocumentLine::UpdateWidthFunc updateWidthFunc): mSyntaxState{}, - mWidth{-1} + mWidth{-1}, + mUpdateWidthFunc{updateWidthFunc} { } int DocumentLine::glyphLength(int i) const { - Q_ASSERT(i>=0 && i=mGlyphStartCharList.length()) + return 0; int start = glyphStartChar(i); - int end; - if (i+1=0); - Q_ASSERT(i>=0 && i=mGlyphStartCharList.length()) + return QString(); + return mLineText.mid(glyphStartChar(i),glyphLength(i)); +} + +int DocumentLine::glyphStartPosition(int i) +{ + if (i<0) + return 0; + if (mWidth<0) + updateWidth(); + if (i>=mGlyphPositionList.length()) + return mWidth; + return mGlyphPositionList[i]; +} + +int DocumentLine::glyphWidth(int i) +{ + if (i<0 || i>=mGlyphPositionList.length()) + return 0; + if(mWidth<0) + updateWidth(); int start = glyphStartPosition(i); int end; if (i+1 &DocumentLine::glyphPositionList() +{ + if(mWidth<0) + updateWidth(); + return mGlyphPositionList; +} + +int DocumentLine::glyphStartChar(int i) const +{ + if (i<0) + return 0; + if (i>=mGlyphStartCharList.length()) + return mLineText.length(); + return mGlyphStartCharList[i]; +} + UndoList::UndoList():QObject() { mMaxUndoActions = 1024; diff --git a/libs/qsynedit/qsynedit/document.h b/libs/qsynedit/qsynedit/document.h index 19f5601c..1ba1d84e 100644 --- a/libs/qsynedit/qsynedit/document.h +++ b/libs/qsynedit/qsynedit/document.h @@ -34,6 +34,7 @@ QList calcGlyphStartCharList(const QString &text); class Document; +using SearchConfirmAroundProc = std::function; /** * @brief The DocumentLine class * @@ -50,7 +51,9 @@ class Document; */ class DocumentLine { public: - explicit DocumentLine(); + using UpdateWidthFunc = std::function(const QString&, const QList &, int &)>; + + explicit DocumentLine(UpdateWidthFunc updateWidthFunc); DocumentLine(const DocumentLine&)=delete; DocumentLine& operator=(const DocumentLine&)=delete; @@ -78,22 +81,14 @@ private: * @brief get list of start position of the glyphs in the line text * @return start positions of the glyph (in pixel) */ - const QList& glyphPositionList() const { - Q_ASSERT(mWidth>=0); - return mGlyphPositionList; - } + const QList& glyphPositionList(); /** * @brief get start index of the chars representing the specified glyph. * @param i index of the glyph in the line (starting from 0) * @return char index in the line text (start from 0) */ - int glyphStartChar(int i) const { - Q_ASSERT(i>=0); - if (i>=mGlyphStartCharList.length()) - return mLineText.length(); - return mGlyphStartCharList[i]; - } + int glyphStartChar(int i) const; /** * @brief get count of the chars representing the specified glyph. @@ -107,29 +102,21 @@ private: * @param i index of the glyph in the line (starting from 0) * @return the chars representing the specified glyph */ - QString glyph(int i) const { - return mLineText.mid(glyphStartChar(i),glyphLength(i)); - } + QString glyph(int i) const; /** * @brief get start position of the specified glyph. * @param i index of the glyph in the line (starting from 0) * @return start position in the line (pixel) */ - int glyphStartPosition(int i) const { - Q_ASSERT(mWidth>=0); - Q_ASSERT(i>=0); - if (i>mGlyphPositionList.length()) - return mWidth+1; - return mGlyphPositionList[i]; - } + int glyphStartPosition(int i); /** * @brief get width (pixels) of the specified glyph. * @param i index of the glyph of the line (starting from 0) * @return */ - int glyphWidth(int i) const; + int glyphWidth(int i); /** * @brief get the line text @@ -141,7 +128,7 @@ private: * @brief get the width (pixel) of the line text * @return the width (in width) */ - int width() const { return mWidth; } + int width(); /** * @brief get the state of the syntax highlighter after this line is parsed @@ -155,7 +142,7 @@ private: void setSyntaxState(const SyntaxState &newSyntaxState) { mSyntaxState = newSyntaxState; } void setLineText(const QString &newLineText); - void setWidth(int width, QList glyphPositionList) { mWidth = width; mGlyphPositionList = glyphPositionList; } + void updateWidth(); void invalidateWidth() { mWidth = -1; mGlyphPositionList.clear(); } private: QString mLineText; /* the unicode code points of the text */ @@ -191,6 +178,8 @@ private: */ int mWidth; + UpdateWidthFunc mUpdateWidthFunc; + friend class Document; }; @@ -506,7 +495,6 @@ public: * @return glyph index in the line (starting from 0) */ int charToGlyphIndex(int line, int charPos); - int charToGlyphIndex(QList glyphStartCharList, int charPos) const; /** * @brief get index of the glyph displayed on the specified column @@ -518,7 +506,6 @@ public: * @return glyph index in the line (starting from 0) */ int xposToGlyphIndex(int line, int xpos); - int xposToGlyphIndex(QList glyphColumnsList, int xpos) const; int charToGlyphStartPosition(int line, int charPos); int xposToGlyphStartChar(int line, int xpos); @@ -564,9 +551,11 @@ protected: void putTextStr(const QString& text); void internalClear(); private: - int calculateLineWidth(int line); + int xposToGlyphIndex(int strWidth, QList glyphPositionList, int xpos) const; + int charToGlyphIndex(const QString& str, QList glyphStartCharList, int charPos) const; + QList calcLineWidth(const QString& lineText, const QList &glyphStartCharList, int &width); QList calcGlyphPositionList(const QString& lineText, const QList &glyphStartCharList, int left, int &right) const; - QList calcGlyphPositionList(const QString& lineText) const; + QList calcGlyphPositionList(const QString& lineText, int &width) const; bool tryLoadFileByEncoding(QByteArray encodingName, QFile& file); void loadUTF16BOMFile(QFile& file); void loadUTF32BOMFile(QFile& file); @@ -576,6 +565,8 @@ private: private: DocumentLines mLines; + DocumentLine::UpdateWidthFunc mUpdateDocumentLineWidthFunc; + //SynEdit* mEdit; QFontMetrics mFontMetrics; diff --git a/libs/qsynedit/qsynedit/painter.cpp b/libs/qsynedit/qsynedit/painter.cpp index 48c51506..26bf032a 100644 --- a/libs/qsynedit/qsynedit/painter.cpp +++ b/libs/qsynedit/qsynedit/painter.cpp @@ -361,8 +361,9 @@ void QSynEditPainter::paintToken( bool startPaint; int nX; +// qDebug()<<"Paint token"<= first && rcToken.right() > rcToken.left()) { -// qDebug()<<"Paint Token"<drawText(nX+padding,rcToken.bottom()-mPainter->fontMetrics().descent() , ch); + //qDebug()<<"Drawing"<setFont(fontForNonAscii); mPainter->drawText(nX,rcToken.bottom()-mPainter->fontMetrics().descent() , glyph); @@ -443,7 +445,7 @@ void QSynEditPainter::paintToken( } } - rcToken.setLeft(rcToken.right()); + rcToken.setLeft(rcToken.right()+1); } } @@ -1038,23 +1040,6 @@ void QSynEditPainter::paintLines() // Let the highlighter scan the next token. mEdit->mSyntaxer->next(); } -// // Don't assume HL.GetTokenPos is valid after HL.GetEOL == True. -// //nTokenColumnsBefore += edit->stringColumns(sToken,nTokenColumnsBefore); -// if (edit->mSyntaxer->eol() && (nTokenColumnsBefore < vLastChar)) { -// int lineColumns = edit->mDocument->lineColumns(vLine-1); -// // Draw text that couldn't be parsed by the highlighter, if any. -// if (nTokenColumnsBefore < lineColumns) { -// if (nTokenColumnsBefore + 1 < vFirstChar) -// nTokenColumnsBefore = vFirstChar - 1; -// nTokenColumnLen = std::min(lineColumns, vLastChar) - (nTokenColumnsBefore + 1); -// if (nTokenColumnLen > 0) { -// sToken = edit->substringByColumns(sLine,nTokenColumnsBefore+1,nTokenColumnLen); -// addHighlightToken(sToken, nTokenColumnsBefore - (vFirstChar - FirstCol), -// nTokenColumnLen, vLine, PTokenAttribute(),false); -// } -// } -// } - // Paint folding foldRange = mEdit->foldStartAtLine(vLine); if ((foldRange) && foldRange->collapsed) { diff --git a/libs/qsynedit/qsynedit/qsynedit.cpp b/libs/qsynedit/qsynedit/qsynedit.cpp index 229e17ec..c5bab58f 100644 --- a/libs/qsynedit/qsynedit/qsynedit.cpp +++ b/libs/qsynedit/qsynedit/qsynedit.cpp @@ -722,10 +722,14 @@ DisplayCoord QSynEdit::pixelsToNearestGlyphPos(int aX, int aY) const int xpos = std::max(0, leftPos() + aX - mGutterWidth - 2); int row = yposToRow(aY); int line = rowToLine(row); - if (line<1 || line > mDocument->count() ) - return DisplayCoord{-1,-1}; - if (xpos<0 || xpos>mDocument->lineWidth(line-1)) - return DisplayCoord{-1,-1}; + if (line<1) + line = 1; + if (line>mDocument->count()) + line = mDocument->count(); + if (xpos<0) + xpos=0; + if (xpos>mDocument->lineWidth(line-1)) + xpos=mDocument->lineWidth(line-1)+1; int glyphIndex = mDocument->xposToGlyphIndex(line-1, xpos); xpos = mDocument->glyphStartPostion(line-1, glyphIndex); return DisplayCoord{xpos, row}; diff --git a/libs/qsynedit/qsynedit/qsynedit.h b/libs/qsynedit/qsynedit/qsynedit.h index 1921dc8a..f8f3f4e7 100644 --- a/libs/qsynedit/qsynedit/qsynedit.h +++ b/libs/qsynedit/qsynedit/qsynedit.h @@ -124,9 +124,9 @@ enum class TransientType { using SynPaintTransientProc = std::function; */ -using ProcessCommandProc = std::function; -using MouseCursorProc = std::function; -using PaintProc = std::function; +// using ProcessCommandProc = std::function; +// using MouseCursorProc = std::function; +// using PaintProc = std::function; using SearchMathedProc = std::function; using SearchConfirmAroundProc = std::function; @@ -737,12 +737,12 @@ private: int mPainterLock; // lock counter to prevent repaint while painting bool mUndoing; // event handlers - ProcessCommandProc mOnCommandProcessed; - MouseCursorProc mOnMouseCursor; - PaintProc mOnPaint; + // ProcessCommandProc mOnCommandProcessed; + // MouseCursorProc mOnMouseCursor; + // PaintProc mOnPaint; // SynPreparePaintHighlightTokenProc mOnPaintHighlightToken; - ProcessCommandProc mOnProcessingCommand; - ProcessCommandProc mOnProcessingUserCommand; + // ProcessCommandProc mOnProcessingCommand; + // ProcessCommandProc mOnProcessingUserCommand; // SynSpecialLineColorsProc mOnSpecialLineColors; // SynEditingAreasProc mOnEditingAreas;