work save: can display glyphs with code points > 0xFFFF now

This commit is contained in:
Roy Qu 2024-02-22 22:51:48 +08:00
parent 2489148da6
commit cf994d2ac6
4 changed files with 42 additions and 11 deletions

View File

@ -837,6 +837,22 @@ QString Document::glyphAt(int line, int charPos)
return mLines[line]->glyph(glyphIdx); return mLines[line]->glyph(glyphIdx);
} }
int Document::charToGlyphStartChar(int line, int charPos)
{
QMutexLocker locker(&mMutex);
QList<int> glyphPositions = mLines[line]->glyphPositions();
int glyphIdx = charToGlyphIndex(glyphPositions, charPos);
return mLines[line]->glyphStart(glyphIdx);
}
// int Document::columnToGlyphStartColumn(int line, int charPos)
// {
// QMutexLocker locker(&mMutex);
// QList<int> glyphColumnsList = mLines[line]->glyphColumnsList();
// int glyphIdx = columnToGlyphIndex(glyphColumnsList, charPos);
// return mLines[line]->glyphStartColumn(glyphIdx);
// }
QList<int> calcGlyphPositions(const QString &text) QList<int> calcGlyphPositions(const QString &text)
{ {
QList<int> glyphPositions; QList<int> glyphPositions;
@ -847,10 +863,15 @@ QList<int> calcGlyphPositions(const QString &text)
QChar ch = text[i]; QChar ch = text[i];
if (ch.isHighSurrogate() && i+1<text.length() && QChar::isLowSurrogate(text[i+1].unicode())) { if (ch.isHighSurrogate() && i+1<text.length() && QChar::isLowSurrogate(text[i+1].unicode())) {
//character that larger than 0xffff //character that larger than 0xffff
int ucs4 = QChar::surrogateToUcs4(ch, text[i+1]); uint ucs4 = QChar::surrogateToUcs4(ch, text[i+1]);
if (QChar::combiningClass(ucs4)==0 || glyphPositions.isEmpty()) { if (QChar::combiningClass(ucs4)!=0 && !glyphPositions.isEmpty()) {
//a Combining character
} else if (ucs4>=0xE0100 && ucs4 <= 0xE01EF) {
//variation selector
} else {
if (!consecutive) if (!consecutive)
glyphPositions.append(i); glyphPositions.append(i);
consecutive = false;
} }
i+=2; i+=2;
continue; continue;
@ -858,13 +879,17 @@ QList<int> calcGlyphPositions(const QString &text)
consecutive = true; consecutive = true;
} else if (ch.combiningClass()!=0 && !glyphPositions.isEmpty()) { } else if (ch.combiningClass()!=0 && !glyphPositions.isEmpty()) {
//a Combining character //a Combining character
} else if (ch.unicode()>=0xFE00 && ch.unicode()<=0xFE0F) {
//variation selector
} else { } else {
//qDebug("%x %d", ch.unicode(), ch.combiningClass());
if (!consecutive) if (!consecutive)
glyphPositions.append(i); glyphPositions.append(i);
consecutive = false; consecutive = false;
} }
i++; i++;
} }
//qDebug()<<text<<glyphPositions;
return glyphPositions; return glyphPositions;
} }
@ -910,13 +935,17 @@ int Document::glyphColumns(const QString &glyph, int colsBefore) const
} else { } else {
int width = mFontMetrics.horizontalAdvance(ch); int width = mFontMetrics.horizontalAdvance(ch);
glyphCols = std::max(1.0, std::ceil(width / (double)mCharWidth)); glyphCols = std::max(1.0, std::ceil(width / (double)mCharWidth));
//qDebug()<<glyph<<glyphCols<<width<<mCharWidth;
} }
} else { } else {
int width = mNonAsciiFontMetrics.horizontalAdvance(glyph); int width = mNonAsciiFontMetrics.horizontalAdvance(glyph);
glyphCols = std::max(1.0, std::ceil(width / (double)mCharWidth)); glyphCols = std::max(1.0, std::ceil(width / (double)mCharWidth));
int modular = width % mCharWidth;
if (modular >0 && (modular <= (mCharWidth/5)) )
glyphCols--;
//qDebug()<<glyph<<glyphCols<<width<<mCharWidth;
} }
return glyphCols; return glyphCols;
} }
int Document::charToGlyphIndex(int line, int charIdx) int Document::charToGlyphIndex(int line, int charIdx)

View File

@ -435,6 +435,9 @@ public:
QString glyph(int line, int glyphIdx); QString glyph(int line, int glyphIdx);
QString glyphAt(int line, int charPos); QString glyphAt(int line, int charPos);
int charToGlyphStartChar(int line, int charPos);
//int columnToGlyphStartColumn(int line, int charPos);
/** /**
* @brief calculate display width (in columns) of a string * @brief calculate display width (in columns) of a string
* *

View File

@ -399,12 +399,13 @@ void QSynEditPainter::paintToken(const QString &token, int tokenCols, int column
int tokenColLen=0; int tokenColLen=0;
startPaint = false; startPaint = false;
QList<int> glyphPositions = calcGlyphPositions(token); QList<int> glyphPositions = calcGlyphPositions(token);
qDebug()<<"painting:"<<token;
for (int i=0; i< glyphPositions.length();i++) { for (int i=0; i< glyphPositions.length();i++) {
int glyphStart = glyphPositions[i]; int glyphStart = glyphPositions[i];
int glyphEnd =(i+1<glyphPositions.length())?glyphPositions[i+1]:token.length(); int glyphEnd =(i+1<glyphPositions.length())?glyphPositions[i+1]:token.length();
QString glyph = token.mid(glyphStart,glyphEnd-glyphStart); QString glyph = token.mid(glyphStart,glyphEnd-glyphStart);
int charCols = edit->document()->glyphColumns(glyph, columnsBefore+tokenColLen); int charCols = edit->document()->glyphColumns(glyph, columnsBefore+tokenColLen);
//qDebug()<<glyph<<charCols; qDebug()<<glyph<<charCols;
if (tokenColLen+charCols>=first) { if (tokenColLen+charCols>=first) {
if (!startPaint && (tokenColLen+1!=first)) { if (!startPaint && (tokenColLen+1!=first)) {
nX-= (first - tokenColLen - 1) * edit->mCharWidth; nX-= (first - tokenColLen - 1) * edit->mCharWidth;

View File

@ -726,11 +726,9 @@ DisplayCoord QSynEdit::pixelsToNearestRowColumn(int aX, int aY) const
DisplayCoord QSynEdit::pixelsToRowColumn(int aX, int aY) const DisplayCoord QSynEdit::pixelsToRowColumn(int aX, int aY) const
{ {
return { int line = std::max(1, mTopLine + (aY / mTextHeight));
std::max(1, (int)(mLeftChar + (aX - mGutterWidth - 2.0) / mCharWidth)), int col = std::max(1, (int)(mLeftChar + (aX - mGutterWidth - 2.0) / mCharWidth));
std::max(1, mTopLine + (aY / mTextHeight)) return DisplayCoord{col, line};
};
} }
QPoint QSynEdit::rowColumnToPixels(const DisplayCoord &coord) const QPoint QSynEdit::rowColumnToPixels(const DisplayCoord &coord) const
@ -864,7 +862,7 @@ int QSynEdit::columnToChar(int aLine, int aColumn) const
//Q_ASSERT( (aLine <= mDocument->count()) && (aLine >= 1)); //Q_ASSERT( (aLine <= mDocument->count()) && (aLine >= 1));
if (aLine <= mDocument->count()) { if (aLine <= mDocument->count()) {
QString s = getDisplayStringAtLine(aLine); QString s = getDisplayStringAtLine(aLine);
return mDocument->columnToChar(aLine,s,aColumn)+1; return mDocument->columnToChar(aLine-1,s,aColumn)+1;
} }
return aColumn; return aColumn;
} }
@ -872,7 +870,7 @@ int QSynEdit::columnToChar(int aLine, int aColumn) const
int QSynEdit::columnToChar(int aLine, const QString &s, int aColumn) const int QSynEdit::columnToChar(int aLine, const QString &s, int aColumn) const
{ {
if (aLine <= mDocument->count()) { if (aLine <= mDocument->count()) {
return mDocument->columnToChar(aLine,s,aColumn)+1; return mDocument->columnToChar(aLine-1,s,aColumn)+1;
} }
return aColumn; return aColumn;
} }