fix: font style not correct when painting
This commit is contained in:
parent
16053882d4
commit
9672ebd079
|
@ -17,6 +17,8 @@ APP_NAME = RedPandaCPP
|
||||||
|
|
||||||
APP_VERSION = 2.27
|
APP_VERSION = 2.27
|
||||||
|
|
||||||
|
APP_VERSION_SUFFIX = alpha
|
||||||
|
|
||||||
# TEST_VERSION = beta2
|
# TEST_VERSION = beta2
|
||||||
system(git rev-list HEAD --count): TEST_VERSION = $$system(git rev-list HEAD --count)
|
system(git rev-list HEAD --count): TEST_VERSION = $$system(git rev-list HEAD --count)
|
||||||
|
|
||||||
|
@ -57,9 +59,9 @@ DEFINES += PREFIX=\\\"$${PREFIX}\\\"
|
||||||
DEFINES += LIBEXECDIR=\\\"$${LIBEXECDIR}\\\"
|
DEFINES += LIBEXECDIR=\\\"$${LIBEXECDIR}\\\"
|
||||||
DEFINES += APP_NAME=\\\"$${APP_NAME}\\\"
|
DEFINES += APP_NAME=\\\"$${APP_NAME}\\\"
|
||||||
isEmpty(TEST_VERSION) {
|
isEmpty(TEST_VERSION) {
|
||||||
DEFINES += REDPANDA_CPP_VERSION=\\\"$${APP_VERSION}\\\"
|
DEFINES += REDPANDA_CPP_VERSION=\\\"$${APP_VERSION}$${APP_VERSION_SUFFIX}\\\"
|
||||||
} else {
|
} else {
|
||||||
DEFINES += REDPANDA_CPP_VERSION=\\\"$${APP_VERSION}.$${TEST_VERSION}\\\"
|
DEFINES += REDPANDA_CPP_VERSION=\\\"$${APP_VERSION}$${APP_VERSION_SUFFIX}.$${TEST_VERSION}\\\"
|
||||||
}
|
}
|
||||||
win32 {
|
win32 {
|
||||||
_WINDOWS_PREFER_OPENCONSOLE = $$(WINDOWS_PREFER_OPENCONSOLE)
|
_WINDOWS_PREFER_OPENCONSOLE = $$(WINDOWS_PREFER_OPENCONSOLE)
|
||||||
|
|
|
@ -5159,10 +5159,6 @@
|
||||||
<source>Toggle Readonly</source>
|
<source>Toggle Readonly</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Line: %1 Col: %2 Lines: %3</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Newline</source>
|
<source>Newline</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
|
@ -5420,7 +5416,11 @@
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Line: %1 Col: %2 Sel:%3 Lines: %4</source>
|
<source>Line: %1 Char: %2 Sel:%3 Lines: %4</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Line: %1 Char: %2 Lines: %3</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -4868,10 +4868,6 @@
|
||||||
<source>Toggle Readonly</source>
|
<source>Toggle Readonly</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Line: %1 Col: %2 Lines: %3</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Newline</source>
|
<source>Newline</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
|
@ -5133,7 +5129,11 @@
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Line: %1 Col: %2 Sel:%3 Lines: %4</source>
|
<source>Line: %1 Char: %2 Sel:%3 Lines: %4</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Line: %1 Char: %2 Lines: %3</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
|
|
@ -21,8 +21,6 @@ qsynedit.depends = redpanda_qt_utils
|
||||||
|
|
||||||
APP_NAME = RedPandaCPP
|
APP_NAME = RedPandaCPP
|
||||||
|
|
||||||
APP_VERSION = 2.27
|
|
||||||
|
|
||||||
win32: {
|
win32: {
|
||||||
SUBDIRS += \
|
SUBDIRS += \
|
||||||
redpanda-win-git-askpass
|
redpanda-win-git-askpass
|
||||||
|
|
|
@ -895,6 +895,14 @@ int Document::stringWidth(const QString &str, int left) const
|
||||||
return right - left;
|
return right - left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Document::stringWidth(const QString &str, int left, const QFontMetrics &asciFontMetrics, const QFontMetrics &nonAsciiFontMetrics)
|
||||||
|
{
|
||||||
|
QList<int> glyphStartCharList = calcGlyphStartCharList(str);
|
||||||
|
int right;
|
||||||
|
calcGlyphPositionList(str, glyphStartCharList, asciFontMetrics, nonAsciiFontMetrics, left, right);
|
||||||
|
return right - left;
|
||||||
|
}
|
||||||
|
|
||||||
int Document::glyphCount(int line)
|
int Document::glyphCount(int line)
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&mMutex);
|
QMutexLocker locker(&mMutex);
|
||||||
|
@ -929,20 +937,7 @@ int Document::glyphWidth(int line, int glyphIdx)
|
||||||
|
|
||||||
int Document::glyphWidth(const QString &glyph, int left) const
|
int Document::glyphWidth(const QString &glyph, int left) const
|
||||||
{
|
{
|
||||||
int glyphWidth;
|
return glyphWidth(glyph,left,mFontMetrics, mNonAsciiFontMetrics);
|
||||||
if (glyph.length()==1 && glyph[0].unicode()<0xFF) {
|
|
||||||
QChar ch = glyph[0];
|
|
||||||
if (ch == '\t') {
|
|
||||||
glyphWidth = tabWidth() - left % tabWidth();
|
|
||||||
} else {
|
|
||||||
glyphWidth = mFontMetrics.horizontalAdvance(ch);
|
|
||||||
//qDebug()<<glyph<<glyphCols<<width<<mCharWidth;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
glyphWidth = mNonAsciiFontMetrics.horizontalAdvance(glyph);
|
|
||||||
//qDebug()<<glyph<<glyphCols<<width<<mCharWidth;
|
|
||||||
}
|
|
||||||
return glyphWidth;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Document::charToGlyphIndex(int line, int charIdx)
|
int Document::charToGlyphIndex(int line, int charIdx)
|
||||||
|
@ -975,12 +970,33 @@ QList<int> Document::calcLineWidth(const QString &lineText, const QList<int> &gl
|
||||||
return calcGlyphPositionList(lineText,glyphStartCharList,0,width);
|
return calcGlyphPositionList(lineText,glyphStartCharList,0,width);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<int> Document::calcGlyphPositionList(const QString &lineText, const QList<int> &glyphStartCharList, const QFontMetrics &fontMetrics, const QFontMetrics &nonAsciiFontMetrics, int left, int &right) const
|
||||||
|
{
|
||||||
|
right = std::max(0,left);
|
||||||
|
int start,end;
|
||||||
|
QList<int> glyphPostionList;
|
||||||
|
for (int i=0;i<glyphStartCharList.length();i++) {
|
||||||
|
start = glyphStartCharList[i];
|
||||||
|
if (i+1<glyphStartCharList.length()) {
|
||||||
|
end = glyphStartCharList[i+1];
|
||||||
|
} else {
|
||||||
|
end = lineText.length();
|
||||||
|
}
|
||||||
|
QString glyph = lineText.mid(start,end-start);
|
||||||
|
int gWidth = glyphWidth(glyph, right, fontMetrics, nonAsciiFontMetrics);
|
||||||
|
glyphPostionList.append(right);
|
||||||
|
right += gWidth;
|
||||||
|
}
|
||||||
|
return glyphPostionList;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int Document::xposToGlyphIndex(int line, int xpos)
|
int Document::xposToGlyphIndex(int line, int xpos)
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&mMutex);
|
QMutexLocker locker(&mMutex);
|
||||||
if (line<0 || line>=count())
|
if (line<0 || line>=count())
|
||||||
return 0;
|
return 0;
|
||||||
QList<int> glyphPositionList = mLines[line]->glyphPositionList();
|
QList<int> glyphPositionList = mLines[line]->glyphStartPositionList();
|
||||||
return xposToGlyphIndex(mLines[line]->width(), glyphPositionList, xpos);
|
return xposToGlyphIndex(mLines[line]->width(), glyphPositionList, xpos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1010,7 +1026,7 @@ int Document::xposToGlyphStartChar(int line, int xpos)
|
||||||
QMutexLocker locker(&mMutex);
|
QMutexLocker locker(&mMutex);
|
||||||
if (line<0 || line>=count())
|
if (line<0 || line>=count())
|
||||||
return 0;
|
return 0;
|
||||||
QList<int> glyphPositionList = mLines[line]->glyphPositionList();
|
QList<int> glyphPositionList = mLines[line]->glyphStartPositionList();
|
||||||
int glyphIdx = xposToGlyphIndex(mLines[line]->width(), glyphPositionList, xpos);
|
int glyphIdx = xposToGlyphIndex(mLines[line]->width(), glyphPositionList, xpos);
|
||||||
return mLines[line]->glyphStartChar(glyphIdx);
|
return mLines[line]->glyphStartChar(glyphIdx);
|
||||||
}
|
}
|
||||||
|
@ -1040,7 +1056,7 @@ int Document::xposToGlyphStartChar(int line, const QString newStr, int xpos)
|
||||||
QList<int> glyphPositionList;
|
QList<int> glyphPositionList;
|
||||||
int width;
|
int width;
|
||||||
if (mLines[line]->lineText() == newStr) {
|
if (mLines[line]->lineText() == newStr) {
|
||||||
glyphPositionList = mLines[line]->glyphPositionList();
|
glyphPositionList = mLines[line]->glyphStartPositionList();
|
||||||
width = mLines[line]->width();
|
width = mLines[line]->width();
|
||||||
} else {
|
} else {
|
||||||
glyphPositionList = calcGlyphPositionList(mLines[line]->lineText(), width);
|
glyphPositionList = calcGlyphPositionList(mLines[line]->lineText(), width);
|
||||||
|
@ -1124,24 +1140,24 @@ void Document::internalClear()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Document::setLineWidth(int line, const QString &lineText, int newWidth, const QList<int> glyphStartPositionList)
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&mMutex);
|
||||||
|
if (line<0 || line>=count())
|
||||||
|
return ;
|
||||||
|
if (lineText != mLines[line]->lineText())
|
||||||
|
return;
|
||||||
|
mLines[line]->mWidth = newWidth;
|
||||||
|
mLines[line]->mGlyphStartPositionList = glyphStartPositionList;
|
||||||
|
Q_ASSERT(mLines[line]->mGlyphStartPositionList.length() == mLines[line]->mGlyphStartCharList.length());
|
||||||
|
}
|
||||||
|
|
||||||
QList<int> Document::calcGlyphPositionList(const QString &lineText, const QList<int> &glyphStartCharList, int left, int &right) const
|
QList<int> Document::calcGlyphPositionList(const QString &lineText, const QList<int> &glyphStartCharList, int left, int &right) const
|
||||||
{
|
{
|
||||||
right = std::max(0,left);
|
return calcGlyphPositionList(lineText, glyphStartCharList,
|
||||||
int start,end;
|
mFontMetrics,
|
||||||
QList<int> glyphPostionList;
|
mNonAsciiFontMetrics,
|
||||||
for (int i=0;i<glyphStartCharList.length();i++) {
|
left,right);
|
||||||
start = glyphStartCharList[i];
|
|
||||||
if (i+1<glyphStartCharList.length()) {
|
|
||||||
end = glyphStartCharList[i+1];
|
|
||||||
} else {
|
|
||||||
end = lineText.length();
|
|
||||||
}
|
|
||||||
QString glyph = lineText.mid(start,end-start);
|
|
||||||
int gWidth = glyphWidth(glyph, right);
|
|
||||||
glyphPostionList.append(right);
|
|
||||||
right += gWidth;
|
|
||||||
}
|
|
||||||
return glyphPostionList;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1151,6 +1167,21 @@ QList<int> Document::calcGlyphPositionList(const QString &lineText, int &width)
|
||||||
return calcGlyphPositionList(lineText,glyphStartCharList,0,width);
|
return calcGlyphPositionList(lineText,glyphStartCharList,0,width);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<int> Document::getGlyphStartCharList(int line, const QString &lineText)
|
||||||
|
{
|
||||||
|
if (line<0 || line>=count() || mLines[line]->lineText()!=lineText)
|
||||||
|
return calcGlyphStartCharList(lineText);
|
||||||
|
return mLines[line]->glyphStartCharList();
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<int> Document::getGlyphStartPositionList(int line, const QString &lineText, int &lineWidth)
|
||||||
|
{
|
||||||
|
if (line<0 || line>=count() || mLines[line]->lineText()!=lineText)
|
||||||
|
return calcGlyphPositionList(lineText,lineWidth);
|
||||||
|
lineWidth = mLines[line]->width();
|
||||||
|
return mLines[line]->glyphStartPositionList();
|
||||||
|
}
|
||||||
|
|
||||||
NewlineType Document::getNewlineType()
|
NewlineType Document::getNewlineType()
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&mMutex);
|
QMutexLocker locker(&mMutex);
|
||||||
|
@ -1212,21 +1243,21 @@ int DocumentLine::glyphStartPosition(int i)
|
||||||
return 0;
|
return 0;
|
||||||
if (mWidth<0)
|
if (mWidth<0)
|
||||||
updateWidth();
|
updateWidth();
|
||||||
if (i>=mGlyphPositionList.length())
|
if (i>=mGlyphStartPositionList.length())
|
||||||
return mWidth;
|
return mWidth;
|
||||||
return mGlyphPositionList[i];
|
return mGlyphStartPositionList[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
int DocumentLine::glyphWidth(int i)
|
int DocumentLine::glyphWidth(int i)
|
||||||
{
|
{
|
||||||
if (i<0 || i>=mGlyphPositionList.length())
|
if (i<0 || i>=mGlyphStartPositionList.length())
|
||||||
return 0;
|
return 0;
|
||||||
if( mWidth <0)
|
if( mWidth <0)
|
||||||
updateWidth();
|
updateWidth();
|
||||||
int start = glyphStartPosition(i);
|
int start = glyphStartPosition(i);
|
||||||
int end;
|
int end;
|
||||||
if (i+1<mGlyphPositionList.length()) {
|
if (i+1<mGlyphStartPositionList.length()) {
|
||||||
end = mGlyphPositionList[i+1];
|
end = mGlyphStartPositionList[i+1];
|
||||||
} else {
|
} else {
|
||||||
end = mWidth;
|
end = mWidth;
|
||||||
}
|
}
|
||||||
|
@ -1250,15 +1281,15 @@ void DocumentLine::setLineText(const QString &newLineText)
|
||||||
void DocumentLine::updateWidth()
|
void DocumentLine::updateWidth()
|
||||||
{
|
{
|
||||||
Q_ASSERT(mUpdateWidthFunc!=nullptr);
|
Q_ASSERT(mUpdateWidthFunc!=nullptr);
|
||||||
mGlyphPositionList = mUpdateWidthFunc(mLineText, mGlyphStartCharList, mWidth);
|
mGlyphStartPositionList = mUpdateWidthFunc(mLineText, mGlyphStartCharList, mWidth);
|
||||||
// qDebug()<<"Update Width"<<mLineText<<mWidth<<mGlyphPositionList;
|
// qDebug()<<"Update Width"<<mLineText<<mWidth<<mGlyphPositionList;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QList<int> &DocumentLine::glyphPositionList()
|
const QList<int> &DocumentLine::glyphStartPositionList()
|
||||||
{
|
{
|
||||||
if(mWidth<0)
|
if(mWidth<0)
|
||||||
updateWidth();
|
updateWidth();
|
||||||
return mGlyphPositionList;
|
return mGlyphStartPositionList;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DocumentLine::glyphStartChar(int i) const
|
int DocumentLine::glyphStartChar(int i) const
|
||||||
|
@ -1703,4 +1734,64 @@ int searchForSegmentIdx(const QList<int> segList, int minVal, int maxVal, int va
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Document::updateGlyphStartPositionList(
|
||||||
|
const QString &lineText,
|
||||||
|
const QList<int> &glyphStartCharList, int startChar, int endChar,
|
||||||
|
const QFontMetrics &fontMetrics, const QFontMetrics &nonAsciiFontMetrics,
|
||||||
|
QList<int> &glyphStartPositionList, int left, int &right, int &startGlyph, int &endGlyph) const
|
||||||
|
{
|
||||||
|
right = std::max(0,left);
|
||||||
|
startGlyph = searchForSegmentIdx(glyphStartCharList,0,lineText.length(),startChar);
|
||||||
|
endGlyph = searchForSegmentIdx(glyphStartCharList,0,lineText.length(),endChar);
|
||||||
|
for (int i=startGlyph;i<endGlyph;i++) {
|
||||||
|
int start = glyphStartCharList[i];
|
||||||
|
int end;
|
||||||
|
if (i+1<glyphStartCharList.length()) {
|
||||||
|
end = glyphStartCharList[i+1];
|
||||||
|
} else {
|
||||||
|
end = lineText.length();
|
||||||
|
}
|
||||||
|
QString glyph = lineText.mid(start,end-start);
|
||||||
|
int gWidth = glyphWidth(glyph, right, fontMetrics, nonAsciiFontMetrics);
|
||||||
|
glyphStartPositionList[i] = right;
|
||||||
|
right += gWidth;
|
||||||
|
}
|
||||||
|
return right-left;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Document::glyphWidth(const QString &glyph, int left, const QFontMetrics &fontMetrics, const QFontMetrics &nonAsciiFontMetrics) const
|
||||||
|
{
|
||||||
|
int glyphWidth;
|
||||||
|
if (glyph.length()==1 && glyph[0].unicode()<0xFF) {
|
||||||
|
QChar ch = glyph[0];
|
||||||
|
if (ch == '\t') {
|
||||||
|
glyphWidth = tabWidth() - left % tabWidth();
|
||||||
|
} else {
|
||||||
|
glyphWidth = fontMetrics.horizontalAdvance(ch);
|
||||||
|
//qDebug()<<glyph<<glyphCols<<width<<mCharWidth;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
glyphWidth = nonAsciiFontMetrics.horizontalAdvance(glyph);
|
||||||
|
//qDebug()<<glyph<<glyphCols<<width<<mCharWidth;
|
||||||
|
}
|
||||||
|
return glyphWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
void expandGlyphStartCharList(const QString &strAdded, int oldStrLen, QList<int> glyphStartCharList)
|
||||||
|
{
|
||||||
|
QList<int> addedList = calcGlyphStartCharList(strAdded);
|
||||||
|
for (int i=0;i<addedList.length();i++) {
|
||||||
|
glyphStartCharList.append(addedList[i]+oldStrLen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int calcSegmentInterval(const QList<int> segList, int maxVal, int idx)
|
||||||
|
{
|
||||||
|
if (idx<0 || idx>=segList.length())
|
||||||
|
return 0;
|
||||||
|
if (idx == segList.length()-1)
|
||||||
|
return maxVal - segList[idx];
|
||||||
|
return segList[idx+1]-segList[idx];
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,8 +31,9 @@
|
||||||
namespace QSynedit {
|
namespace QSynedit {
|
||||||
|
|
||||||
int searchForSegmentIdx(const QList<int> segList, int minVal, int maxVal, int value);
|
int searchForSegmentIdx(const QList<int> segList, int minVal, int maxVal, int value);
|
||||||
|
int calcSegmentInterval(const QList<int> segList, int maxVal, int idx);
|
||||||
QList<int> calcGlyphStartCharList(const QString &text);
|
QList<int> calcGlyphStartCharList(const QString &text);
|
||||||
|
void expandGlyphStartCharList(const QString& strAdded, int oldStrLen, QList<int> glyphStartCharList);
|
||||||
|
|
||||||
class Document;
|
class Document;
|
||||||
|
|
||||||
|
@ -83,7 +84,7 @@ private:
|
||||||
* @brief get list of start position of the glyphs in the line text
|
* @brief get list of start position of the glyphs in the line text
|
||||||
* @return start positions of the glyph (in pixel)
|
* @return start positions of the glyph (in pixel)
|
||||||
*/
|
*/
|
||||||
const QList<int>& glyphPositionList();
|
const QList<int>& glyphStartPositionList();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief get start index of the chars representing the specified glyph.
|
* @brief get start index of the chars representing the specified glyph.
|
||||||
|
@ -145,7 +146,7 @@ private:
|
||||||
|
|
||||||
void setLineText(const QString &newLineText);
|
void setLineText(const QString &newLineText);
|
||||||
void updateWidth();
|
void updateWidth();
|
||||||
void invalidateWidth() { mWidth = -1; mGlyphPositionList.clear(); }
|
void invalidateWidth() { mWidth = -1; mGlyphStartPositionList.clear(); }
|
||||||
private:
|
private:
|
||||||
QString mLineText; /* the unicode code points of the text */
|
QString mLineText; /* the unicode code points of the text */
|
||||||
/**
|
/**
|
||||||
|
@ -160,11 +161,11 @@ private:
|
||||||
* @brief start columns of the glyphs
|
* @brief start columns of the glyphs
|
||||||
*
|
*
|
||||||
* A glyph may occupy more than one columns in the screen.
|
* A glyph may occupy more than one columns in the screen.
|
||||||
* Each elements of mGlyphPositionList is the columns occupied by the glyph.
|
* Each elements of mGlyphStartPositionList is the columns occupied by the glyph.
|
||||||
* The width of a glyph is affected by the font used to display,
|
* The width of a glyph is affected by the font used to display,
|
||||||
* so it must be recalculated each time the font is changed.
|
* so it must be recalculated each time the font is changed.
|
||||||
*/
|
*/
|
||||||
QList<int> mGlyphPositionList;
|
QList<int> mGlyphStartPositionList;
|
||||||
/**
|
/**
|
||||||
* @brief state of the syntax highlighter after this line is parsed
|
* @brief state of the syntax highlighter after this line is parsed
|
||||||
*
|
*
|
||||||
|
@ -441,6 +442,8 @@ public:
|
||||||
*/
|
*/
|
||||||
int stringWidth(const QString &str, int left) const;
|
int stringWidth(const QString &str, int left) const;
|
||||||
|
|
||||||
|
int stringWidth(const QString &str, int left, const QFontMetrics &asciFontMetrics, const QFontMetrics &nonAsciiFontMetrics);
|
||||||
|
|
||||||
int glyphCount(int line);
|
int glyphCount(int line);
|
||||||
/**
|
/**
|
||||||
* @brief get start index of the chars representing the specified glyph in the specified line.
|
* @brief get start index of the chars representing the specified glyph in the specified line.
|
||||||
|
@ -515,6 +518,14 @@ public:
|
||||||
int charToGlyphStartPosition(int line, const QString newStr, int charPos);
|
int charToGlyphStartPosition(int line, const QString newStr, int charPos);
|
||||||
int xposToGlyphStartChar(int line, const QString newStr, int xpos);
|
int xposToGlyphStartChar(int line, const QString newStr, int xpos);
|
||||||
|
|
||||||
|
int updateGlyphStartPositionList(
|
||||||
|
const QString& lineText,
|
||||||
|
const QList<int> &glyphStartCharList,
|
||||||
|
int startChar, int endChar,
|
||||||
|
const QFontMetrics &fontMetrics, const QFontMetrics &nonAsciiFontMetrics,
|
||||||
|
QList<int> &glyphStartPositionList,
|
||||||
|
int left, int &right, int &startGlyph, int &endGlyph) const;
|
||||||
|
|
||||||
bool getAppendNewLineAtEOF();
|
bool getAppendNewLineAtEOF();
|
||||||
void setAppendNewLineAtEOF(bool appendNewLineAtEOF);
|
void setAppendNewLineAtEOF(bool appendNewLineAtEOF);
|
||||||
|
|
||||||
|
@ -554,11 +565,22 @@ protected:
|
||||||
void putTextStr(const QString& text);
|
void putTextStr(const QString& text);
|
||||||
void internalClear();
|
void internalClear();
|
||||||
private:
|
private:
|
||||||
|
void setLineWidth(int line, const QString& lineText, int newWidth, const QList<int> glyphStartPositionList);
|
||||||
|
|
||||||
|
int glyphWidth(const QString& glyph, int left,
|
||||||
|
const QFontMetrics &fontMetrics, const QFontMetrics &nonAsciiFontMetrics) const;
|
||||||
|
|
||||||
int xposToGlyphIndex(int strWidth, QList<int> glyphPositionList, int xpos) const;
|
int xposToGlyphIndex(int strWidth, QList<int> glyphPositionList, int xpos) const;
|
||||||
int charToGlyphIndex(const QString& str, QList<int> glyphStartCharList, int charPos) const;
|
int charToGlyphIndex(const QString& str, QList<int> glyphStartCharList, int charPos) const;
|
||||||
QList<int> calcLineWidth(const QString& lineText, const QList<int> &glyphStartCharList, int &width);
|
QList<int> calcLineWidth(const QString& lineText, const QList<int> &glyphStartCharList, int &width);
|
||||||
|
QList<int> calcGlyphPositionList(const QString& lineText, const QList<int> &glyphStartCharList,
|
||||||
|
const QFontMetrics &fontMetrics,
|
||||||
|
const QFontMetrics &nonAsciiFontMetrics,
|
||||||
|
int left, int &right) const;
|
||||||
QList<int> calcGlyphPositionList(const QString& lineText, const QList<int> &glyphStartCharList, int left, int &right) const;
|
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> calcGlyphPositionList(const QString& lineText, int &width) const;
|
||||||
|
QList<int> getGlyphStartCharList(int line, const QString &lineText);
|
||||||
|
QList<int> getGlyphStartPositionList(int line, const QString &lineText, int &lineWidth);
|
||||||
bool tryLoadFileByEncoding(QByteArray encodingName, QFile& file);
|
bool tryLoadFileByEncoding(QByteArray encodingName, QFile& file);
|
||||||
void loadUTF16BOMFile(QFile& file);
|
void loadUTF16BOMFile(QFile& file);
|
||||||
void loadUTF32BOMFile(QFile& file);
|
void loadUTF32BOMFile(QFile& file);
|
||||||
|
@ -588,6 +610,8 @@ private:
|
||||||
#else
|
#else
|
||||||
QMutex mMutex;
|
QMutex mMutex;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
friend class QSynEditPainter;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class ChangeReason {
|
enum class ChangeReason {
|
||||||
|
|
|
@ -354,7 +354,12 @@ int QSynEditPainter::fixXValue(int xpos)
|
||||||
}
|
}
|
||||||
|
|
||||||
void QSynEditPainter::paintToken(
|
void QSynEditPainter::paintToken(
|
||||||
const QString &token, int tokenWidth, int tokenLeft,
|
const QString& lineText,
|
||||||
|
const QList<int> &glyphStartCharList,
|
||||||
|
const QList<int> &glyphStartPositionList,
|
||||||
|
int startGlyph,
|
||||||
|
int endGlyph,
|
||||||
|
int tokenWidth, int tokenLeft,
|
||||||
int first, int last, bool /*isSelection*/, const QFont& font,
|
int first, int last, bool /*isSelection*/, const QFont& font,
|
||||||
const QFont& fontForNonAscii, bool showGlyphs)
|
const QFont& fontForNonAscii, bool showGlyphs)
|
||||||
{
|
{
|
||||||
|
@ -362,8 +367,12 @@ void QSynEditPainter::paintToken(
|
||||||
int nX;
|
int nX;
|
||||||
bool lastGlyphAscii = false;
|
bool lastGlyphAscii = false;
|
||||||
bool fontInited = false;
|
bool fontInited = false;
|
||||||
|
int tokenRight = tokenWidth+tokenLeft;
|
||||||
|
|
||||||
// qDebug()<<"Paint token"<<token<<tokenWidth<<tokenLeft<<first<<last<<rcToken;
|
//qDebug()<<"Paint token"<<lineText<<tokenWidth<<tokenLeft<<first<<last<<rcToken;
|
||||||
|
// qDebug()<<glyphStartCharList;
|
||||||
|
// qDebug()<<glyphStartPositionList;
|
||||||
|
// qDebug()<<startGlyph<<endGlyph;
|
||||||
|
|
||||||
if (last >= first && rcToken.right() > rcToken.left()) {
|
if (last >= first && rcToken.right() > rcToken.left()) {
|
||||||
nX = fixXValue(first);
|
nX = fixXValue(first);
|
||||||
|
@ -375,14 +384,12 @@ void QSynEditPainter::paintToken(
|
||||||
} else {
|
} else {
|
||||||
int tokenWidth=0;
|
int tokenWidth=0;
|
||||||
startPaint = false;
|
startPaint = false;
|
||||||
QList<int> glyphStartCharList = calcGlyphStartCharList(token);
|
for (int i=startGlyph; i<endGlyph;i++) {
|
||||||
// qDebug()<<"painting:"<<token;
|
|
||||||
for (int i=0; i< glyphStartCharList.length();i++) {
|
|
||||||
int glyphStart = glyphStartCharList[i];
|
int glyphStart = glyphStartCharList[i];
|
||||||
int glyphEnd =(i+1<glyphStartCharList.length())?glyphStartCharList[i+1]:token.length();
|
int glyphLen = calcSegmentInterval(glyphStartCharList,lineText.length(),i);
|
||||||
QString glyph = token.mid(glyphStart,glyphEnd-glyphStart);
|
QString glyph = lineText.mid(glyphStart,glyphLen);
|
||||||
int glyphWidth = mEdit->document()->glyphWidth(glyph, tokenLeft+tokenWidth);
|
int glyphWidth = calcSegmentInterval(glyphStartPositionList, tokenRight, i);
|
||||||
// qDebug()<<glyph<<charCols;
|
// qDebug()<<"painting:"<<glyph<<glyphWidth<<tokenWidth+glyphWidth<<first<<last;
|
||||||
if (tokenWidth+glyphWidth>first) {
|
if (tokenWidth+glyphWidth>first) {
|
||||||
if (!startPaint ) {
|
if (!startPaint ) {
|
||||||
nX-= (first - tokenWidth - 1) ;
|
nX-= (first - tokenWidth - 1) ;
|
||||||
|
@ -410,8 +417,8 @@ void QSynEditPainter::paintToken(
|
||||||
QString textToPaint = glyph;
|
QString textToPaint = glyph;
|
||||||
while(i+1<glyphStartCharList.length()) {
|
while(i+1<glyphStartCharList.length()) {
|
||||||
int glyphStart = glyphStartCharList[i+1];
|
int glyphStart = glyphStartCharList[i+1];
|
||||||
int glyphEnd =(i+2<glyphStartCharList.length())?glyphStartCharList[i+2]:token.length();
|
int glyphLen = calcSegmentInterval(glyphStartCharList,lineText.length(),i+1);
|
||||||
QString glyph2 = token.mid(glyphStart,glyphEnd-glyphStart);
|
QString glyph2 = lineText.mid(glyphStart,glyphLen);
|
||||||
// if (!OperatorGlyphs.contains(glyph))
|
// if (!OperatorGlyphs.contains(glyph))
|
||||||
// break;
|
// break;
|
||||||
if (isAscii) {
|
if (isAscii) {
|
||||||
|
@ -428,7 +435,7 @@ void QSynEditPainter::paintToken(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
i+=1;
|
i+=1;
|
||||||
glyphWidth += mEdit->document()->glyphWidth(glyph2,0);
|
glyphWidth += calcSegmentInterval(glyphStartPositionList, tokenLeft+tokenWidth, i);
|
||||||
textToPaint+=glyph2;
|
textToPaint+=glyph2;
|
||||||
if (tokenWidth + glyphWidth > last )
|
if (tokenWidth + glyphWidth > last )
|
||||||
break;
|
break;
|
||||||
|
@ -544,7 +551,10 @@ void QSynEditPainter::paintEditAreas(const EditingAreaList &areaList)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QSynEditPainter::paintHighlightToken(bool bFillToEOL)
|
void QSynEditPainter::paintHighlightToken(const QString& lineText,
|
||||||
|
const QList<int> &glyphStartCharList,
|
||||||
|
const QList<int> &glyphStartPositionsList,
|
||||||
|
bool bFillToEOL)
|
||||||
{
|
{
|
||||||
bool isComplexToken;
|
bool isComplexToken;
|
||||||
int nC1, nC2, nC1Sel, nC2Sel;
|
int nC1, nC2, nC1Sel, nC2Sel;
|
||||||
|
@ -578,16 +588,7 @@ void QSynEditPainter::paintHighlightToken(bool bFillToEOL)
|
||||||
|
|
||||||
// if (bSpecialLine && mEdit->mOptions.testFlag(eoSpecialLineDefaultFg))
|
// if (bSpecialLine && mEdit->mOptions.testFlag(eoSpecialLineDefaultFg))
|
||||||
// colFG = TokenAccu.FG;
|
// colFG = TokenAccu.FG;
|
||||||
QFont font = mEdit->font();
|
|
||||||
font.setBold(mTokenAccu.style & FontStyle::fsBold);
|
|
||||||
font.setItalic(mTokenAccu.style & FontStyle::fsItalic);
|
|
||||||
font.setStrikeOut(mTokenAccu.style & FontStyle::fsStrikeOut);
|
|
||||||
font.setUnderline(mTokenAccu.style & FontStyle::fsUnderline);
|
|
||||||
QFont nonAsciiFont = mEdit->fontForNonAscii();
|
|
||||||
nonAsciiFont.setBold(mTokenAccu.style & FontStyle::fsBold);
|
|
||||||
nonAsciiFont.setItalic(mTokenAccu.style & FontStyle::fsItalic);
|
|
||||||
nonAsciiFont.setStrikeOut(mTokenAccu.style & FontStyle::fsStrikeOut);
|
|
||||||
nonAsciiFont.setUnderline(mTokenAccu.style & FontStyle::fsUnderline);
|
|
||||||
|
|
||||||
// Paint the chars
|
// Paint the chars
|
||||||
if (isComplexToken) {
|
if (isComplexToken) {
|
||||||
|
@ -596,24 +597,47 @@ void QSynEditPainter::paintHighlightToken(bool bFillToEOL)
|
||||||
setDrawingColors(false);
|
setDrawingColors(false);
|
||||||
rcToken.setRight(fixXValue(mLineSelStart));
|
rcToken.setRight(fixXValue(mLineSelStart));
|
||||||
paintToken(
|
paintToken(
|
||||||
mTokenAccu.s,mTokenAccu.width,mTokenAccu.left,nC1,mLineSelStart,false,font,nonAsciiFont, mTokenAccu.showSpecialGlyphs);
|
lineText,
|
||||||
|
glyphStartCharList,
|
||||||
|
glyphStartPositionsList,
|
||||||
|
mTokenAccu.startGlyph,
|
||||||
|
mTokenAccu.endGlyph,
|
||||||
|
mTokenAccu.width,mTokenAccu.left,nC1,mLineSelStart,false,mTokenAccu.font,mTokenAccu.nonAsciiFont, mTokenAccu.showSpecialGlyphs);
|
||||||
}
|
}
|
||||||
// selected part of the token
|
// selected part of the token
|
||||||
setDrawingColors(true);
|
setDrawingColors(true);
|
||||||
nC1Sel = std::max(mLineSelStart, nC1);
|
nC1Sel = std::max(mLineSelStart, nC1);
|
||||||
nC2Sel = std::min(mLineSelEnd, nC2);
|
nC2Sel = std::min(mLineSelEnd, nC2);
|
||||||
rcToken.setRight(fixXValue(nC2Sel));
|
rcToken.setRight(fixXValue(nC2Sel));
|
||||||
paintToken(mTokenAccu.s, mTokenAccu.width, mTokenAccu.left, nC1Sel, nC2Sel,true,font,nonAsciiFont, mTokenAccu.showSpecialGlyphs);
|
paintToken(
|
||||||
|
lineText,
|
||||||
|
glyphStartCharList,
|
||||||
|
glyphStartPositionsList,
|
||||||
|
mTokenAccu.startGlyph,
|
||||||
|
mTokenAccu.endGlyph,
|
||||||
|
mTokenAccu.width, mTokenAccu.left, nC1Sel, nC2Sel,true,mTokenAccu.font,mTokenAccu.nonAsciiFont, mTokenAccu.showSpecialGlyphs);
|
||||||
// second unselected part of the token
|
// second unselected part of the token
|
||||||
if (bU2) {
|
if (bU2) {
|
||||||
setDrawingColors(false);
|
setDrawingColors(false);
|
||||||
rcToken.setRight(fixXValue(nC2));
|
rcToken.setRight(fixXValue(nC2));
|
||||||
paintToken(mTokenAccu.s, mTokenAccu.width, mTokenAccu.left, mLineSelEnd, nC2,false,font,nonAsciiFont, mTokenAccu.showSpecialGlyphs);
|
paintToken(
|
||||||
|
lineText,
|
||||||
|
glyphStartCharList,
|
||||||
|
glyphStartPositionsList,
|
||||||
|
mTokenAccu.startGlyph,
|
||||||
|
mTokenAccu.endGlyph,
|
||||||
|
mTokenAccu.width, mTokenAccu.left, mLineSelEnd, nC2,false,mTokenAccu.font,mTokenAccu.nonAsciiFont, mTokenAccu.showSpecialGlyphs);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setDrawingColors(bSel);
|
setDrawingColors(bSel);
|
||||||
rcToken.setRight(fixXValue(nC2));
|
rcToken.setRight(fixXValue(nC2));
|
||||||
paintToken(mTokenAccu.s, mTokenAccu.width, mTokenAccu.left, nC1, nC2,bSel,font,nonAsciiFont, mTokenAccu.showSpecialGlyphs);
|
paintToken(
|
||||||
|
lineText,
|
||||||
|
glyphStartCharList,
|
||||||
|
glyphStartPositionsList,
|
||||||
|
mTokenAccu.startGlyph,
|
||||||
|
mTokenAccu.endGlyph,
|
||||||
|
mTokenAccu.width, mTokenAccu.left, nC1, nC2,bSel,mTokenAccu.font,mTokenAccu.nonAsciiFont, mTokenAccu.showSpecialGlyphs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -658,9 +682,15 @@ void QSynEditPainter::paintHighlightToken(bool bFillToEOL)
|
||||||
// Store the token chars with the attributes in the TokenAccu
|
// Store the token chars with the attributes in the TokenAccu
|
||||||
// record. This will paint any chars already stored if there is
|
// record. This will paint any chars already stored if there is
|
||||||
// a (visible) change in the attributes.
|
// a (visible) change in the attributes.
|
||||||
void QSynEditPainter::addHighlightToken(const QString &token, int tokenLeft,
|
void QSynEditPainter::addHighlightToken(
|
||||||
int tokenWidth, int line, PTokenAttribute attri,
|
const QString& lineText,
|
||||||
bool showGlyphs)
|
const QString& token, int tokenLeft,
|
||||||
|
int line, PTokenAttribute attri, bool showGlyphs,
|
||||||
|
const QList<int> glyphStartCharList,
|
||||||
|
int tokenStartChar,
|
||||||
|
int tokenEndChar,
|
||||||
|
QList<int> &glyphStartPositionList,
|
||||||
|
int &tokenWidth)
|
||||||
{
|
{
|
||||||
bool bCanAppend;
|
bool bCanAppend;
|
||||||
QColor foreground, background;
|
QColor foreground, background;
|
||||||
|
@ -706,20 +736,52 @@ void QSynEditPainter::addHighlightToken(const QString &token, int tokenLeft,
|
||||||
}
|
}
|
||||||
// If we can't append it, then we have to paint the old token chars first.
|
// If we can't append it, then we have to paint the old token chars first.
|
||||||
if (!bCanAppend)
|
if (!bCanAppend)
|
||||||
paintHighlightToken(false);
|
paintHighlightToken(lineText, glyphStartCharList, glyphStartPositionList, false);
|
||||||
}
|
}
|
||||||
// Don't use AppendStr because it's more expensive.
|
if (!bCanAppend) {
|
||||||
if (bCanAppend) {
|
mTokenAccu.font = mEdit->font();
|
||||||
mTokenAccu.s.append(token);
|
mTokenAccu.font.setBold(style & FontStyle::fsBold);
|
||||||
mTokenAccu.width+=tokenWidth;
|
mTokenAccu.font.setItalic(style & FontStyle::fsItalic);
|
||||||
} else {
|
mTokenAccu.font.setStrikeOut(style & FontStyle::fsStrikeOut);
|
||||||
mTokenAccu.width = tokenWidth;
|
mTokenAccu.font.setUnderline(style & FontStyle::fsUnderline);
|
||||||
mTokenAccu.s = token;
|
mTokenAccu.nonAsciiFont = mEdit->fontForNonAscii();
|
||||||
mTokenAccu.left = tokenLeft;
|
mTokenAccu.nonAsciiFont.setBold(style & FontStyle::fsBold);
|
||||||
mTokenAccu.foreground = foreground;
|
mTokenAccu.nonAsciiFont.setItalic(style & FontStyle::fsItalic);
|
||||||
mTokenAccu.background = background;
|
mTokenAccu.nonAsciiFont.setStrikeOut(style & FontStyle::fsStrikeOut);
|
||||||
mTokenAccu.style = style;
|
mTokenAccu.nonAsciiFont.setUnderline(style & FontStyle::fsUnderline);
|
||||||
mTokenAccu.showSpecialGlyphs = showGlyphs;
|
}
|
||||||
|
//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),
|
||||||
|
QFontMetrics(mTokenAccu.nonAsciiFont),
|
||||||
|
glyphStartPositionList,
|
||||||
|
tokenLeft,
|
||||||
|
tokenRight,
|
||||||
|
startGlyph,
|
||||||
|
endGlyph);
|
||||||
|
|
||||||
|
// Only accumulate tokens if it's visible.
|
||||||
|
if (tokenLeft < mRight) {
|
||||||
|
if (bCanAppend) {
|
||||||
|
mTokenAccu.width += tokenWidth;
|
||||||
|
Q_ASSERT(startGlyph == mTokenAccu.endGlyph);
|
||||||
|
mTokenAccu.endGlyph = endGlyph;
|
||||||
|
} else {
|
||||||
|
mTokenAccu.width = tokenWidth;
|
||||||
|
mTokenAccu.left = tokenLeft;
|
||||||
|
mTokenAccu.startGlyph = startGlyph;
|
||||||
|
mTokenAccu.endGlyph = endGlyph;
|
||||||
|
mTokenAccu.foreground = foreground;
|
||||||
|
mTokenAccu.background = background;
|
||||||
|
mTokenAccu.style = style;
|
||||||
|
mTokenAccu.showSpecialGlyphs = showGlyphs;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -864,8 +926,6 @@ void QSynEditPainter::paintLines()
|
||||||
EditingAreaList areaList;
|
EditingAreaList areaList;
|
||||||
PCodeFoldingRange foldRange;
|
PCodeFoldingRange foldRange;
|
||||||
PTokenAttribute preeditAttr;
|
PTokenAttribute preeditAttr;
|
||||||
int nFold;
|
|
||||||
QString sFold;
|
|
||||||
|
|
||||||
// Initialize rcLine for drawing. Note that Top and Bottom are updated
|
// Initialize rcLine for drawing. Note that Top and Bottom are updated
|
||||||
// inside the loop. Get only the starting point for this.
|
// inside the loop. Get only the starting point for this.
|
||||||
|
@ -950,32 +1010,60 @@ void QSynEditPainter::paintLines()
|
||||||
|
|
||||||
mIsLineSelected = (!mIsComplexLine) && (mLineSelStart > 0);
|
mIsLineSelected = (!mIsComplexLine) && (mLineSelStart > 0);
|
||||||
rcToken = rcLine;
|
rcToken = rcLine;
|
||||||
|
|
||||||
|
int lineWidth;
|
||||||
|
QList<int> glyphStartCharList = mEdit->mDocument->getGlyphStartCharList(vLine-1,sLine);
|
||||||
|
QList<int> glyphStartPositionsList = mEdit->mDocument->getGlyphStartPositionList(vLine-1,sLine, lineWidth);
|
||||||
|
|
||||||
if (!mEdit->mSyntaxer || !mEdit->mSyntaxer->enabled()) {
|
if (!mEdit->mSyntaxer || !mEdit->mSyntaxer->enabled()) {
|
||||||
sToken = sLine;
|
sToken = sLine;
|
||||||
if (mIsCurrentLine) {
|
tokenWidth = lineWidth;
|
||||||
tokenWidth = mEdit->document()->lineWidth(vLine-1, sLine);
|
|
||||||
} else {
|
|
||||||
tokenWidth = mEdit->document()->lineWidth(vLine-1);
|
|
||||||
}
|
|
||||||
if (mEdit->mOptions.testFlag(eoShowLineBreaks) && (!mIsLineSelected) && (!mIsSpecialLine) && (tokenWidth <= mLeft)) {
|
if (mEdit->mOptions.testFlag(eoShowLineBreaks) && (!mIsLineSelected) && (!mIsSpecialLine) && (tokenWidth <= mLeft)) {
|
||||||
sToken = sToken + LineBreakGlyph;
|
expandGlyphStartCharList(LineBreakGlyph, sLine.length(), glyphStartCharList);
|
||||||
tokenWidth += mEdit->document()->glyphWidth(LineBreakGlyph,0);
|
int width = mEdit->document()->glyphWidth(LineBreakGlyph,0);
|
||||||
|
glyphStartPositionsList.append(tokenWidth);
|
||||||
|
sLine+=LineBreakGlyph;
|
||||||
|
tokenWidth += width;
|
||||||
}
|
}
|
||||||
if (mIsComplexLine) {
|
if (mIsComplexLine) {
|
||||||
setDrawingColors(true);
|
setDrawingColors(true);
|
||||||
rcToken.setLeft(std::max(rcLine.left(), fixXValue(mLineSelStart)));
|
rcToken.setLeft(std::max(rcLine.left(), fixXValue(mLineSelStart)));
|
||||||
rcToken.setRight(std::min(rcLine.right(), fixXValue(mLineSelEnd)));
|
rcToken.setRight(std::min(rcLine.right(), fixXValue(mLineSelEnd)));
|
||||||
paintToken(sToken, tokenWidth, 0, mLineSelStart, mLineSelEnd,false,mEdit->font(),mEdit->fontForNonAscii(),false);
|
paintToken(
|
||||||
|
sLine,
|
||||||
|
glyphStartCharList,
|
||||||
|
glyphStartPositionsList,
|
||||||
|
0,
|
||||||
|
glyphStartCharList.length(),
|
||||||
|
tokenWidth, 0, mLineSelStart, mLineSelEnd,false,mEdit->font(),mEdit->fontForNonAscii(),false);
|
||||||
setDrawingColors(false);
|
setDrawingColors(false);
|
||||||
rcToken.setLeft(std::max(rcLine.left(), fixXValue(mLeft)));
|
rcToken.setLeft(std::max(rcLine.left(), fixXValue(mLeft)));
|
||||||
rcToken.setRight(std::min(rcLine.right(), fixXValue(mLineSelStart)));
|
rcToken.setRight(std::min(rcLine.right(), fixXValue(mLineSelStart)));
|
||||||
paintToken(sToken, tokenWidth, 0, mLeft, mLineSelStart,false,mEdit->font(),mEdit->fontForNonAscii(),false);
|
paintToken(
|
||||||
|
sLine,
|
||||||
|
glyphStartCharList,
|
||||||
|
glyphStartPositionsList,
|
||||||
|
0,
|
||||||
|
glyphStartCharList.length(),
|
||||||
|
tokenWidth, 0, mLeft, mLineSelStart,false,mEdit->font(),mEdit->fontForNonAscii(),false);
|
||||||
rcToken.setLeft(std::max(rcLine.left(), fixXValue(mLineSelEnd)));
|
rcToken.setLeft(std::max(rcLine.left(), fixXValue(mLineSelEnd)));
|
||||||
rcToken.setRight(std::min(rcLine.right(), fixXValue(mRight)));
|
rcToken.setRight(std::min(rcLine.right(), fixXValue(mRight)));
|
||||||
paintToken(sToken, tokenWidth, 0, mLineSelEnd, mRight,true, mEdit->font(), mEdit->fontForNonAscii(),false);
|
paintToken(
|
||||||
|
sLine,
|
||||||
|
glyphStartCharList,
|
||||||
|
glyphStartPositionsList,
|
||||||
|
0,
|
||||||
|
glyphStartCharList.length(),
|
||||||
|
tokenWidth, 0, mLineSelEnd, mRight,true, mEdit->font(), mEdit->fontForNonAscii(),false);
|
||||||
} else {
|
} else {
|
||||||
setDrawingColors(mIsLineSelected);
|
setDrawingColors(mIsLineSelected);
|
||||||
paintToken(sToken, tokenWidth, 0, mLeft, mRight, mIsLineSelected,mEdit->font(),mEdit->fontForNonAscii(),false);
|
paintToken(
|
||||||
|
sLine,
|
||||||
|
glyphStartCharList,
|
||||||
|
glyphStartPositionsList,
|
||||||
|
0,
|
||||||
|
glyphStartCharList.length(),
|
||||||
|
tokenWidth, 0, mLeft, mRight, mIsLineSelected,mEdit->font(),mEdit->fontForNonAscii(),false);
|
||||||
}
|
}
|
||||||
//Paint editingAreaBorders
|
//Paint editingAreaBorders
|
||||||
if (mIsCurrentLine && mEdit->mInputPreeditString.length()>0) {
|
if (mIsCurrentLine && mEdit->mInputPreeditString.length()>0) {
|
||||||
|
@ -1007,105 +1095,124 @@ void QSynEditPainter::paintLines()
|
||||||
// Test first whether anything of this token is visible.
|
// Test first whether anything of this token is visible.
|
||||||
while (!mEdit->mSyntaxer->eol()) {
|
while (!mEdit->mSyntaxer->eol()) {
|
||||||
sToken = mEdit->mSyntaxer->getToken();
|
sToken = mEdit->mSyntaxer->getToken();
|
||||||
// Work-around buggy highlighters which return empty tokens.
|
|
||||||
if (sToken.isEmpty()) {
|
if (sToken.isEmpty()) {
|
||||||
mEdit->mSyntaxer->next();
|
continue;
|
||||||
if (mEdit->mSyntaxer->eol())
|
// mEdit->mSyntaxer->next();
|
||||||
break;
|
// if (mEdit->mSyntaxer->eol())
|
||||||
sToken = mEdit->mSyntaxer->getToken();
|
// break;
|
||||||
// Maybe should also test whether GetTokenPos changed...
|
// sToken = mEdit->mSyntaxer->getToken();
|
||||||
if (sToken.isEmpty()) {
|
// // Maybe should also test whether GetTokenPos changed...
|
||||||
//qDebug()<<QSynEdit::tr("The highlighter seems to be in an infinite loop");
|
// if (sToken.isEmpty()) {
|
||||||
throw BaseError(QSynEdit::tr("The syntaxer seems to be in an infinite loop"));
|
// //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"));
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
//nTokenColumnsBefore = edit->charToColumn(sLine,edit->mHighlighter->getTokenPos()+1)-1;
|
int tokenStartChar = mEdit->mSyntaxer->getTokenPos();
|
||||||
tokenWidth = mEdit->stringWidth(sToken, tokenLeft);
|
int tokenEndChar = tokenStartChar + sToken.length();
|
||||||
if ( tokenLeft + tokenWidth >= mLeft) {
|
|
||||||
if (tokenLeft + tokenWidth >= mRight) {
|
|
||||||
if (tokenLeft >= mRight)
|
|
||||||
break; //*** BREAK ***
|
|
||||||
tokenWidth = mRight - tokenLeft;
|
|
||||||
}
|
|
||||||
// It's at least partially visible. Get the token attributes now.
|
|
||||||
attr = mEdit->mSyntaxer->getTokenAttribute();
|
|
||||||
|
|
||||||
//rainbow parenthesis
|
// It's at least partially visible. Get the token attributes now.
|
||||||
if (sToken == "["
|
attr = mEdit->mSyntaxer->getTokenAttribute();
|
||||||
|| sToken == "("
|
|
||||||
|| sToken == "{"
|
//rainbow parenthesis
|
||||||
) {
|
if (sToken == "["
|
||||||
SyntaxState rangeState = mEdit->mSyntaxer->getState();
|
|| sToken == "("
|
||||||
getBraceColorAttr(rangeState.bracketLevel
|
|| sToken == "{"
|
||||||
+rangeState.braceLevel
|
) {
|
||||||
+rangeState.parenthesisLevel
|
SyntaxState rangeState = mEdit->mSyntaxer->getState();
|
||||||
,attr);
|
getBraceColorAttr(rangeState.bracketLevel
|
||||||
} else if (sToken == "]"
|
+rangeState.braceLevel
|
||||||
|| sToken == ")"
|
+rangeState.parenthesisLevel
|
||||||
|| sToken == "}"
|
,attr);
|
||||||
){
|
} else if (sToken == "]"
|
||||||
SyntaxState rangeState = mEdit->mSyntaxer->getState();
|
|| sToken == ")"
|
||||||
getBraceColorAttr(rangeState.bracketLevel
|
|| sToken == "}"
|
||||||
+rangeState.braceLevel
|
){
|
||||||
+rangeState.parenthesisLevel+1,
|
SyntaxState rangeState = mEdit->mSyntaxer->getState();
|
||||||
attr);
|
getBraceColorAttr(rangeState.bracketLevel
|
||||||
}
|
+rangeState.braceLevel
|
||||||
//input method
|
+rangeState.parenthesisLevel+1,
|
||||||
if (mIsCurrentLine && mEdit->mInputPreeditString.length()>0) {
|
attr);
|
||||||
int startPos = mEdit->mSyntaxer->getTokenPos()+1;
|
|
||||||
int endPos = mEdit->mSyntaxer->getTokenPos() + sToken.length();
|
|
||||||
//qDebug()<<startPos<<":"<<endPos<<" - "+sToken+" - "<<edit->mCaretX<<":"<<edit->mCaretX+edit->mInputPreeditString.length();
|
|
||||||
if (!(endPos < mEdit->mCaretX
|
|
||||||
|| startPos >= mEdit->mCaretX+mEdit->mInputPreeditString.length())) {
|
|
||||||
if (!preeditAttr) {
|
|
||||||
preeditAttr = attr;
|
|
||||||
} else {
|
|
||||||
attr = preeditAttr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bool showGlyph=false;
|
|
||||||
if (attr && attr->tokenType() == TokenType::Space) {
|
|
||||||
int pos = mEdit->mSyntaxer->getTokenPos();
|
|
||||||
if (pos==0) {
|
|
||||||
showGlyph = mEdit->mOptions.testFlag(eoShowLeadingSpaces);
|
|
||||||
} else if (pos+sToken.length()==sLine.length()) {
|
|
||||||
showGlyph = mEdit->mOptions.testFlag(eoShowTrailingSpaces);
|
|
||||||
} else {
|
|
||||||
showGlyph = mEdit->mOptions.testFlag(eoShowInnerSpaces);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
addHighlightToken(sToken, tokenLeft,
|
|
||||||
tokenWidth, vLine,attr, showGlyph);
|
|
||||||
}
|
}
|
||||||
|
//input method
|
||||||
|
if (mIsCurrentLine && mEdit->mInputPreeditString.length()>0) {
|
||||||
|
int startPos = mEdit->mSyntaxer->getTokenPos()+1;
|
||||||
|
int endPos = mEdit->mSyntaxer->getTokenPos() + sToken.length();
|
||||||
|
//qDebug()<<startPos<<":"<<endPos<<" - "+sToken+" - "<<edit->mCaretX<<":"<<edit->mCaretX+edit->mInputPreeditString.length();
|
||||||
|
if (!(endPos < mEdit->mCaretX
|
||||||
|
|| startPos >= mEdit->mCaretX+mEdit->mInputPreeditString.length())) {
|
||||||
|
if (!preeditAttr) {
|
||||||
|
preeditAttr = attr;
|
||||||
|
} else {
|
||||||
|
attr = preeditAttr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool showGlyph=false;
|
||||||
|
if (attr && attr->tokenType() == TokenType::Space) {
|
||||||
|
int pos = mEdit->mSyntaxer->getTokenPos();
|
||||||
|
if (pos==0) {
|
||||||
|
showGlyph = mEdit->mOptions.testFlag(eoShowLeadingSpaces);
|
||||||
|
} else if (pos+sToken.length()==sLine.length()) {
|
||||||
|
showGlyph = mEdit->mOptions.testFlag(eoShowTrailingSpaces);
|
||||||
|
} else {
|
||||||
|
showGlyph = mEdit->mOptions.testFlag(eoShowInnerSpaces);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addHighlightToken(
|
||||||
|
sLine,
|
||||||
|
sToken,
|
||||||
|
tokenLeft,
|
||||||
|
vLine, attr,showGlyph,
|
||||||
|
glyphStartCharList,
|
||||||
|
tokenStartChar,
|
||||||
|
tokenEndChar,
|
||||||
|
glyphStartPositionsList,
|
||||||
|
tokenWidth);
|
||||||
tokenLeft+=tokenWidth;
|
tokenLeft+=tokenWidth;
|
||||||
// Let the highlighter scan the next token.
|
// Let the highlighter scan the next token.
|
||||||
mEdit->mSyntaxer->next();
|
mEdit->mSyntaxer->next();
|
||||||
}
|
}
|
||||||
// Paint folding
|
mEdit->mDocument->setLineWidth(vLine-1, sLine, tokenLeft, glyphStartPositionsList);
|
||||||
foldRange = mEdit->foldStartAtLine(vLine);
|
if (tokenLeft<mRight) {
|
||||||
if ((foldRange) && foldRange->collapsed) {
|
QString addOnStr;
|
||||||
sFold = mEdit->syntaxer()->foldString(sLine);
|
|
||||||
nFold = mEdit->stringWidth(sFold,mEdit->mDocument->lineWidth(vLine-1));
|
// Paint folding
|
||||||
attr = mEdit->mSyntaxer->symbolAttribute();
|
foldRange = mEdit->foldStartAtLine(vLine);
|
||||||
getBraceColorAttr(mEdit->mSyntaxer->getState().braceLevel,attr);
|
if ((foldRange) && foldRange->collapsed) {
|
||||||
addHighlightToken(
|
addOnStr = mEdit->syntaxer()->foldString(sLine);
|
||||||
sFold, mEdit->mDocument->lineWidth(vLine-1)
|
} else {
|
||||||
, nFold, vLine, attr,false);
|
// Draw LineBreak glyph.
|
||||||
} else {
|
if (mEdit->mOptions.testFlag(eoShowLineBreaks)
|
||||||
// Draw LineBreak glyph.
|
&& (!mIsLineSelected)
|
||||||
if (mEdit->mOptions.testFlag(eoShowLineBreaks)
|
&& (!mIsSpecialLine)
|
||||||
&& (!mIsLineSelected)
|
&& (mEdit->mDocument->lineWidth(vLine-1) < mRight)) {
|
||||||
&& (!mIsSpecialLine)
|
addOnStr = LineBreakGlyph;
|
||||||
&& (mEdit->mDocument->lineWidth(vLine-1) < mRight)) {
|
}
|
||||||
addHighlightToken(LineBreakGlyph,
|
}
|
||||||
mEdit->mDocument->lineWidth(vLine-1),
|
if (!addOnStr.isEmpty()) {
|
||||||
mEdit->mDocument->glyphWidth(LineBreakGlyph,0),vLine, mEdit->mSyntaxer->whitespaceAttribute(),false);
|
expandGlyphStartCharList(addOnStr, sLine.length(), glyphStartCharList);
|
||||||
|
for (int i=0;i<glyphStartCharList.length()-glyphStartPositionsList.length();i++) {
|
||||||
|
glyphStartPositionsList.append(tokenLeft);
|
||||||
|
}
|
||||||
|
attr = mEdit->mSyntaxer->symbolAttribute();
|
||||||
|
getBraceColorAttr(mEdit->mSyntaxer->getState().braceLevel,attr);
|
||||||
|
int oldLen = sLine.length();
|
||||||
|
sLine += addOnStr;
|
||||||
|
addHighlightToken(
|
||||||
|
sLine,
|
||||||
|
addOnStr,
|
||||||
|
tokenLeft,
|
||||||
|
vLine, attr, false,
|
||||||
|
glyphStartCharList,
|
||||||
|
oldLen,
|
||||||
|
sLine.length(),
|
||||||
|
glyphStartPositionsList,
|
||||||
|
tokenWidth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Draw anything that's left in the TokenAccu record. Fill to the end
|
// Draw anything that's left in the TokenAccu record. Fill to the end
|
||||||
// of the invalid area with the correct colors.
|
// of the invalid area with the correct colors.
|
||||||
paintHighlightToken(true);
|
paintHighlightToken(sLine, glyphStartCharList, glyphStartPositionsList, true);
|
||||||
|
|
||||||
//Paint editingAreaBorders
|
//Paint editingAreaBorders
|
||||||
foreach (const PEditingArea& area, areaList) {
|
foreach (const PEditingArea& area, areaList) {
|
||||||
|
|
|
@ -31,10 +31,14 @@ class QSynEditPainter
|
||||||
struct SynTokenAccu {
|
struct SynTokenAccu {
|
||||||
int width;
|
int width;
|
||||||
int left;
|
int left;
|
||||||
QString s;
|
int startGlyph;
|
||||||
|
int endGlyph;
|
||||||
|
// QString s;
|
||||||
QColor foreground;
|
QColor foreground;
|
||||||
QColor background;
|
QColor background;
|
||||||
FontStyles style;
|
FontStyles style;
|
||||||
|
QFont font;
|
||||||
|
QFont nonAsciiFont;
|
||||||
bool showSpecialGlyphs;
|
bool showSpecialGlyphs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -54,13 +58,29 @@ private:
|
||||||
void computeSelectionInfo();
|
void computeSelectionInfo();
|
||||||
void setDrawingColors(bool selected);
|
void setDrawingColors(bool selected);
|
||||||
int fixXValue(int xpos);
|
int fixXValue(int xpos);
|
||||||
void paintToken(const QString& token, int tokenWidth, int tokenLeft,
|
void paintToken(
|
||||||
int first, int last, bool isSelection, const QFont& font,
|
const QString& lineText,
|
||||||
const QFont& fontForNonAscii, bool showGlyphs);
|
const QList<int> &glyphStartCharList,
|
||||||
|
const QList<int> &glyphStartPositionList,
|
||||||
|
int startGlyph,
|
||||||
|
int endGlyph,
|
||||||
|
int tokenWidth, int tokenLeft,
|
||||||
|
int first, int last, bool isSelection, const QFont& font,
|
||||||
|
const QFont& fontForNonAscii, bool showGlyphs);
|
||||||
void paintEditAreas(const EditingAreaList& areaList);
|
void paintEditAreas(const EditingAreaList& areaList);
|
||||||
void paintHighlightToken(bool bFillToEOL);
|
void paintHighlightToken(const QString& lineText,
|
||||||
void addHighlightToken(const QString& token, int tokenLeft, int tokenWidth,
|
const QList<int> &glyphStartCharList,
|
||||||
int line, PTokenAttribute p_Attri, bool showGlyphs);
|
const QList<int> &glyphStartPositionsList, bool bFillToEOL);
|
||||||
|
void addHighlightToken(
|
||||||
|
const QString& lineText,
|
||||||
|
const QString& token, int tokenLeft,
|
||||||
|
int line, PTokenAttribute p_Attri, bool showGlyphs,
|
||||||
|
const QList<int> glyphStartCharList,
|
||||||
|
int tokenStartChar,
|
||||||
|
int tokenEndChar,
|
||||||
|
QList<int> &glyphStartPositionList,
|
||||||
|
int &tokenWidth
|
||||||
|
);
|
||||||
|
|
||||||
void paintFoldAttributes();
|
void paintFoldAttributes();
|
||||||
void getBraceColorAttr(int level, PTokenAttribute &attr);
|
void getBraceColorAttr(int level, PTokenAttribute &attr);
|
||||||
|
|
|
@ -4288,29 +4288,29 @@
|
||||||
<context>
|
<context>
|
||||||
<name>QSynedit::Document</name>
|
<name>QSynedit::Document</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="qsynedit/document.cpp" line="590"/>
|
<location filename="qsynedit/document.cpp" line="616"/>
|
||||||
<source>Can't open file '%1' for read!</source>
|
<source>Can't open file '%1' for read!</source>
|
||||||
<translation>无法读取文件"%1".</translation>
|
<translation>无法读取文件"%1".</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="qsynedit/document.cpp" line="630"/>
|
<location filename="qsynedit/document.cpp" line="656"/>
|
||||||
<location filename="qsynedit/document.cpp" line="753"/>
|
<location filename="qsynedit/document.cpp" line="779"/>
|
||||||
<source>Can't load codec '%1'!</source>
|
<source>Can't load codec '%1'!</source>
|
||||||
<translation>无法加载字符编码"%1"!</translation>
|
<translation>无法加载字符编码"%1"!</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="qsynedit/document.cpp" line="649"/>
|
<location filename="qsynedit/document.cpp" line="675"/>
|
||||||
<source>'%1' is a binaray File!</source>
|
<source>'%1' is a binaray File!</source>
|
||||||
<oldsource>This is a binaray File!</oldsource>
|
<oldsource>This is a binaray File!</oldsource>
|
||||||
<translation>'%1'是二进制文件!</translation>
|
<translation>'%1'是二进制文件!</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="qsynedit/document.cpp" line="756"/>
|
<location filename="qsynedit/document.cpp" line="782"/>
|
||||||
<source>Can't open file '%1' for save!</source>
|
<source>Can't open file '%1' for save!</source>
|
||||||
<translation>无法保存文件"%1"!</translation>
|
<translation>无法保存文件"%1"!</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="qsynedit/document.cpp" line="779"/>
|
<location filename="qsynedit/document.cpp" line="805"/>
|
||||||
<source>Data not correctly writed to file '%1'.</source>
|
<source>Data not correctly writed to file '%1'.</source>
|
||||||
<translation>数据未能正确写入文件"%1"。</translation>
|
<translation>数据未能正确写入文件"%1"。</translation>
|
||||||
</message>
|
</message>
|
||||||
|
@ -4318,7 +4318,7 @@
|
||||||
<context>
|
<context>
|
||||||
<name>QSynedit::QSynEdit</name>
|
<name>QSynedit::QSynEdit</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="qsynedit/painter.cpp" line="967"/>
|
<location filename="qsynedit/painter.cpp" line="1019"/>
|
||||||
<source>The syntaxer seems to be in an infinite loop</source>
|
<source>The syntaxer seems to be in an infinite loop</source>
|
||||||
<oldsource>The highlighter seems to be in an infinite loop</oldsource>
|
<oldsource>The highlighter seems to be in an infinite loop</oldsource>
|
||||||
<translation>代码分析器似乎死循环了。</translation>
|
<translation>代码分析器似乎死循环了。</translation>
|
||||||
|
|
Loading…
Reference in New Issue