- enhancement: Improvement in italic font support.

This commit is contained in:
Roy Qu 2024-03-22 11:12:06 +08:00
parent 3b85e8bec0
commit 72cd79eef5
4 changed files with 125 additions and 57 deletions

View File

@ -75,6 +75,8 @@ Red Panda C++ Version 2.27
- enhancement: Type induction for "auto &&" vars. - enhancement: Type induction for "auto &&" vars.
- enhancement: Syntax highlighting for c++ attributes. - enhancement: Syntax highlighting for c++ attributes.
- enhancement: Show "std::function" in the completion list. - enhancement: Show "std::function" in the completion list.
- enhancement: Improvement in italic font support.
Red Panda C++ Version 2.26 Red Panda C++ Version 2.26
- enhancement: Code suggestion for embedded std::vectors. - enhancement: Code suggestion for embedded std::vectors.

View File

@ -1407,7 +1407,6 @@ PStatement CppParser::addStatement(const PStatement& parent,
// if (newCommand.startsWith("::") && parent && kind!=StatementKind::skBlock ) { // if (newCommand.startsWith("::") && parent && kind!=StatementKind::skBlock ) {
// qDebug()<<command<<fileName<<line<<kind<<parent->fullName; // qDebug()<<command<<fileName<<line<<kind<<parent->fullName;
// } // }
if (kind == StatementKind::skConstructor if (kind == StatementKind::skConstructor
|| kind == StatementKind::skFunction || kind == StatementKind::skFunction
|| kind == StatementKind::skDestructor || kind == StatementKind::skDestructor

View File

@ -310,22 +310,20 @@ void QSynEditPainter::computeSelectionInfo()
} }
} }
void QSynEditPainter::setDrawingColors(bool selected) void QSynEditPainter::getDrawingColors(bool selected, QColor &foreground, QColor &background)
{ {
if (selected) { if (selected) {
if (colSelFG.isValid()) if (colSelFG.isValid())
mPainter->setPen(colSelFG); foreground = colSelFG;
else else
mPainter->setPen(colFG); foreground = colFG;
if (colSelBG.isValid()) if (colSelBG.isValid())
mPainter->setBrush(colSelBG); background = colSelBG;
else else
mPainter->setBrush(colBG); background = colBG;
mPainter->setBackground(mEdit->mBackgroundColor);
} else { } else {
mPainter->setPen(colFG); foreground = colFG;
mPainter->setBrush(colBG); background = colBG;
mPainter->setBackground(mEdit->mBackgroundColor);
} }
} }
@ -334,6 +332,37 @@ int QSynEditPainter::fixXValue(int xpos)
return mEdit->textOffset() + xpos; return mEdit->textOffset() + xpos;
} }
void QSynEditPainter::paintLine()
{
QRect rect = mRcLine;
for (int i=0;i<mLineTokenBackgrounds.length();i++) {
rect.setX(mLineTokenBackgrounds[i].left);
rect.setWidth(mLineTokenBackgrounds[i].width);
mPainter->fillRect(rect, mLineTokenBackgrounds[i].background);
}
QFont font;
QFontMetrics fm{font};
int lineHeight = mRcLine.height();
for (int i=0;i<mLineTokens.length();i++) {
if (font!=mLineTokens[i].font) {
font = mLineTokens[i].font;
fm = QFontMetrics{font};
}
int fontHeight = fm.descent() + fm.ascent();
int linePadding = (lineHeight - fontHeight) / 2;
int nY = mRcLine.bottom() - linePadding - fm.descent();
if (font!=mPainter->font())
mPainter->setFont(font);
QPen pen(mLineTokens[i].foreground);
if (pen!=mPainter->pen())
mPainter->setPen(pen);
mPainter->drawText(mLineTokens[i].left,nY, mLineTokens[i].token);
}
mLineTokens.clear();
mLineTokenBackgrounds.clear();
}
void QSynEditPainter::paintToken( void QSynEditPainter::paintToken(
const QString& lineText, const QString& lineText,
const QList<int> &glyphStartCharList, const QList<int> &glyphStartCharList,
@ -342,27 +371,24 @@ void QSynEditPainter::paintToken(
int endGlyph, int endGlyph,
int tokenWidth, int tokenLeft, int tokenWidth, int tokenLeft,
int first, int last, int first, int last,
QColor foreground,
QColor background,
const QFont& font, bool showGlyphs) const QFont& font, bool showGlyphs)
{ {
bool startPaint; bool startPaint;
bool fontInited = false;
int tokenRight = tokenWidth+tokenLeft; int tokenRight = tokenWidth+tokenLeft;
// qDebug()<<"Paint token"<<lineText<<tokenWidth<<tokenLeft<<first<<last<<rcToken;
// qDebug()<<glyphStartCharList;
// qDebug()<<glyphStartPositionList;
// qDebug()<<startGlyph<<endGlyph;
if (last >= first && mRcToken.right() > mRcToken.left()) { if (last >= first && mRcToken.right() > mRcToken.left()) {
int nX = fixXValue(first); int nX = fixXValue(first);
int lineHeight = mRcToken.height();
int fontHeight = mPainter->fontMetrics().descent() + mPainter->fontMetrics().ascent();
int linePadding = (lineHeight - fontHeight) / 2;
int nY = mRcToken.bottom() - linePadding - mPainter->fontMetrics().descent();
first -= tokenLeft; first -= tokenLeft;
last -= tokenLeft; last -= tokenLeft;
QRect rcTokenBack = mRcToken; QRect rcTokenBack = mRcToken;
mPainter->fillRect(rcTokenBack,mPainter->brush()); TokenBackgroundInfo backInfo;
backInfo.left=rcTokenBack.left();
backInfo.width=rcTokenBack.width();
backInfo.background=background;
mLineTokenBackgrounds.append(backInfo);
//mPainter->fillRect(rcTokenBack,mPainter->brush());
if (first > tokenWidth) { if (first > tokenWidth) {
} else { } else {
int tokenWidth=0; int tokenWidth=0;
@ -378,8 +404,6 @@ void QSynEditPainter::paintToken(
startPaint = true; startPaint = true;
} }
} }
// qDebug()<<"painting:"<<glyph<<glyphWidth<<nX<<tokenWidth+glyphWidth<<first<<last;
//painter->drawText(nX,rcToken.bottom()-painter->fontMetrics().descent()*edit->dpiFactor() , Token[i]);
if (startPaint) { if (startPaint) {
bool drawed = false; bool drawed = false;
if (mEdit->mOptions.testFlag(eoLigatureSupport)) { if (mEdit->mOptions.testFlag(eoLigatureSupport)) {
@ -393,7 +417,7 @@ void QSynEditPainter::paintToken(
} }
if (tryLigature) { if (tryLigature) {
QString textToPaint = glyph; QString textToPaint = glyph;
while(i+1<endGlyph) { while(i+1<endGlyph && tokenWidth + glyphWidth < last) {
int glyphStart = glyphStartCharList[i+1]; int glyphStart = glyphStartCharList[i+1];
int glyphLen = calcSegmentInterval(glyphStartCharList,lineText.length(),i+1); int glyphLen = calcSegmentInterval(glyphStartCharList,lineText.length(),i+1);
QString glyph2 = lineText.mid(glyphStart,glyphLen); QString glyph2 = lineText.mid(glyphStart,glyphLen);
@ -413,14 +437,13 @@ void QSynEditPainter::paintToken(
i++; i++;
glyphWidth += glyph2Width; glyphWidth += glyph2Width;
textToPaint += glyph2; textToPaint += glyph2;
if (tokenWidth + glyphWidth > last )
break;
} }
if (!fontInited) { TokenTextInfo tokenInfo;
mPainter->setFont(font); tokenInfo.left = nX;
fontInited = true; tokenInfo.token = textToPaint;
} tokenInfo.foreground=foreground;
mPainter->drawText(nX, nY, textToPaint); tokenInfo.font = font;
mLineTokens.append(tokenInfo);
drawed = true; drawed = true;
} }
} }
@ -442,12 +465,12 @@ void QSynEditPainter::paintToken(
} }
} }
if (textToPaint!=" " && textToPaint!="\t") { if (textToPaint!=" " && textToPaint!="\t") {
if (!fontInited) { TokenTextInfo tokenInfo;
mPainter->setFont(font); tokenInfo.left = nX+padding;
fontInited = true; tokenInfo.token = textToPaint;
} tokenInfo.foreground=foreground;
//qDebug()<<"Drawing"<<textToPaint; tokenInfo.font = font;
mPainter->drawText(nX+padding, nY, textToPaint); mLineTokens.append(tokenInfo);
} }
} }
drawed = true; drawed = true;
@ -468,14 +491,16 @@ void QSynEditPainter::paintEditAreas(const EditingAreaList &areaList)
{ {
QRect rc; QRect rc;
int x1,x2; int x1,x2;
//painter->setClipRect(rcLine);
rc=mRcLine; rc=mRcLine;
rc.setBottom(rc.bottom()-1); rc.setBottom(rc.bottom()-1);
setDrawingColors(false);
for (const PEditingArea& p:areaList) { for (const PEditingArea& p:areaList) {
int penWidth = std::max(1.0,std::round(mEdit->font().pixelSize() / 15.0)); int penWidth;
if (p->type == EditingAreaType::eatWaveUnderLine) if (mEdit->font().pixelSize()>=32)
penWidth = std::max(1.0,std::round(mEdit->font().pixelSize() / 15.0)); penWidth = mEdit->font().pixelSize() / 16;
else if (mEdit->font().pixelSize()>=14)
penWidth = 2;
else
penWidth = 1;
if (p->beginX > mRight) if (p->beginX > mRight)
continue; continue;
if (p->endX < mLeft) if (p->endX < mLeft)
@ -498,6 +523,7 @@ void QSynEditPainter::paintEditAreas(const EditingAreaList &areaList)
switch(p->type) { switch(p->type) {
case EditingAreaType::eatRectangleBorder: case EditingAreaType::eatRectangleBorder:
rc.setTop(rc.top()+penWidth/2); rc.setTop(rc.top()+penWidth/2);
rc.setRight(rc.right() + penWidth );
rc.setBottom(rc.bottom()-penWidth/2); rc.setBottom(rc.bottom()-penWidth/2);
mPainter->drawRect(rc); mPainter->drawRect(rc);
break; break;
@ -509,10 +535,14 @@ void QSynEditPainter::paintEditAreas(const EditingAreaList &areaList)
} }
break; break;
case EditingAreaType::eatWaveUnderLine: { case EditingAreaType::eatWaveUnderLine: {
int maxOffset = 3*penWidth; int lineHeight = rc.height();
int fontHeight = mPainter->fontMetrics().descent() + mPainter->fontMetrics().ascent();
int linePadding = (lineHeight - fontHeight) / 2;
int maxOffset = std::min(3*penWidth, mPainter->fontMetrics().descent());
maxOffset = std::max(3, maxOffset);
int offset = maxOffset; int offset = maxOffset;
int lastX=rc.left(); int lastX=rc.left();
int lastY=rc.bottom()-offset; int lastY=rc.bottom()-offset-linePadding;
int t = rc.left(); int t = rc.left();
while (t<rc.right()) { while (t<rc.right()) {
t+=maxOffset; t+=maxOffset;
@ -520,13 +550,13 @@ void QSynEditPainter::paintEditAreas(const EditingAreaList &areaList)
int diff = t - rc.right(); int diff = t - rc.right();
offset = (offset==0)?(maxOffset-diff):diff; offset = (offset==0)?(maxOffset-diff):diff;
t = rc.right(); t = rc.right();
mPainter->drawLine(lastX,lastY,t,rc.bottom()-offset); mPainter->drawLine(lastX,lastY,t,rc.bottom()-offset-linePadding);
} else { } else {
offset = maxOffset - offset; offset = maxOffset - offset;
mPainter->drawLine(lastX,lastY,t,rc.bottom()-offset); mPainter->drawLine(lastX,lastY,t,rc.bottom()-offset-linePadding);
} }
lastX = t; lastX = t;
lastY = rc.bottom()-offset; lastY = rc.bottom()-offset-linePadding;
} }
} }
break; break;
@ -576,7 +606,8 @@ void QSynEditPainter::paintHighlightToken(const QString& lineText,
if (isComplexToken) { if (isComplexToken) {
// first unselected part of the token // first unselected part of the token
if (bU1) { if (bU1) {
setDrawingColors(false); QColor foreground,background;
getDrawingColors(false,foreground,background);
mRcToken.setRight(fixXValue(mLineSelStart)); mRcToken.setRight(fixXValue(mLineSelStart));
paintToken( paintToken(
lineText, lineText,
@ -585,10 +616,12 @@ void QSynEditPainter::paintHighlightToken(const QString& lineText,
mTokenAccu.startGlyph, mTokenAccu.startGlyph,
mTokenAccu.endGlyph, mTokenAccu.endGlyph,
mTokenAccu.width,mTokenAccu.left,nC1,mLineSelStart, mTokenAccu.width,mTokenAccu.left,nC1,mLineSelStart,
foreground,background,
mTokenAccu.font, mTokenAccu.showSpecialGlyphs); mTokenAccu.font, mTokenAccu.showSpecialGlyphs);
} }
// selected part of the token // selected part of the token
setDrawingColors(true); QColor foreground,background;
getDrawingColors(true,foreground,background);
nC1Sel = std::max(mLineSelStart, nC1); nC1Sel = std::max(mLineSelStart, nC1);
nC2Sel = std::min(mLineSelEnd, nC2); nC2Sel = std::min(mLineSelEnd, nC2);
mRcToken.setRight(fixXValue(nC2Sel)); mRcToken.setRight(fixXValue(nC2Sel));
@ -599,10 +632,12 @@ void QSynEditPainter::paintHighlightToken(const QString& lineText,
mTokenAccu.startGlyph, mTokenAccu.startGlyph,
mTokenAccu.endGlyph, mTokenAccu.endGlyph,
mTokenAccu.width, mTokenAccu.left, nC1Sel, nC2Sel, mTokenAccu.width, mTokenAccu.left, nC1Sel, nC2Sel,
foreground,background,
mTokenAccu.font, mTokenAccu.showSpecialGlyphs); mTokenAccu.font, mTokenAccu.showSpecialGlyphs);
// second unselected part of the token // second unselected part of the token
if (bU2) { if (bU2) {
setDrawingColors(false); QColor foreground,background;
getDrawingColors(false,foreground,background);
mRcToken.setRight(fixXValue(nC2)); mRcToken.setRight(fixXValue(nC2));
paintToken( paintToken(
lineText, lineText,
@ -611,10 +646,12 @@ void QSynEditPainter::paintHighlightToken(const QString& lineText,
mTokenAccu.startGlyph, mTokenAccu.startGlyph,
mTokenAccu.endGlyph, mTokenAccu.endGlyph,
mTokenAccu.width, mTokenAccu.left, mLineSelEnd, nC2, mTokenAccu.width, mTokenAccu.left, mLineSelEnd, nC2,
foreground,background,
mTokenAccu.font, mTokenAccu.showSpecialGlyphs); mTokenAccu.font, mTokenAccu.showSpecialGlyphs);
} }
} else { } else {
setDrawingColors(bSel); QColor foreground,background;
getDrawingColors(bSel,foreground,background);
mRcToken.setRight(fixXValue(nC2)); mRcToken.setRight(fixXValue(nC2));
paintToken( paintToken(
lineText, lineText,
@ -623,6 +660,7 @@ void QSynEditPainter::paintHighlightToken(const QString& lineText,
mTokenAccu.startGlyph, mTokenAccu.startGlyph,
mTokenAccu.endGlyph, mTokenAccu.endGlyph,
mTokenAccu.width, mTokenAccu.left, nC1, nC2, mTokenAccu.width, mTokenAccu.left, nC1, nC2,
foreground,background,
mTokenAccu.font, mTokenAccu.showSpecialGlyphs); mTokenAccu.font, mTokenAccu.showSpecialGlyphs);
} }
} }
@ -633,15 +671,24 @@ void QSynEditPainter::paintHighlightToken(const QString& lineText,
colBG = colSpBG; colBG = colSpBG;
else else
colBG = colEditorBG(); colBG = colEditorBG();
QColor foreground,background;
if (mHasSelectionInLine) { if (mHasSelectionInLine) {
setDrawingColors(mIsLineEndSelected); getDrawingColors(mIsLineEndSelected,foreground,background);
mRcToken.setRight(mRcLine.right()); mRcToken.setRight(mRcLine.right());
mPainter->fillRect(mRcToken,mPainter->brush()); //mPainter->fillRect(mRcToken,mPainter->brush());
} else { } else {
setDrawingColors(false); getDrawingColors(false,foreground,background);
mRcToken.setRight(mRcLine.right()); mRcToken.setRight(mRcLine.right());
mPainter->fillRect(mRcToken,mPainter->brush()); //mPainter->fillRect(mRcToken,mPainter->brush());
} }
TokenBackgroundInfo backInfo;
backInfo.left=mRcToken.left();
backInfo.width=mRcToken.width();
backInfo.background=background;
mLineTokenBackgrounds.append(backInfo);
}
if (bFillToEOL) {
paintLine();
} }
} }

View File

@ -25,6 +25,20 @@
#include "gutter.h" #include "gutter.h"
namespace QSynedit { namespace QSynedit {
struct TokenTextInfo {
int left;
QString token;
QFont font;
QColor foreground;
};
struct TokenBackgroundInfo {
int left;
int width;
QColor background;
};
class QSynEdit; class QSynEdit;
class QSynEditPainter class QSynEditPainter
{ {
@ -55,8 +69,9 @@ public:
private: private:
QColor colEditorBG(); QColor colEditorBG();
void computeSelectionInfo(); void computeSelectionInfo();
void setDrawingColors(bool selected); void getDrawingColors(bool selected, QColor& foreground , QColor& background);
int fixXValue(int xpos); int fixXValue(int xpos);
void paintLine();
void paintToken( void paintToken(
const QString& lineText, const QString& lineText,
const QList<int> &glyphStartCharList, const QList<int> &glyphStartCharList,
@ -65,7 +80,10 @@ private:
int endGlyph, int endGlyph,
int tokenWidth, int tokenLeft, int tokenWidth, int tokenLeft,
int first, int last, int first, int last,
const QFont& fontForNonAscii, bool showGlyphs); QColor foreground,
QColor background,
const QFont& font, bool showGlyphs
);
void paintEditAreas(const EditingAreaList& areaList); void paintEditAreas(const EditingAreaList& areaList);
void paintHighlightToken(const QString& lineText, void paintHighlightToken(const QString& lineText,
const QList<int> &glyphStartCharList, const QList<int> &glyphStartCharList,
@ -106,6 +124,8 @@ private:
// painting the background and the text // painting the background and the text
QRect mRcLine, mRcToken; QRect mRcLine, mRcToken;
int mFirstLine, mLastLine; int mFirstLine, mLastLine;
QList<TokenTextInfo> mLineTokens;
QList<TokenBackgroundInfo> mLineTokenBackgrounds;
QRect mClip; QRect mClip;
int mFirstRow, mLastRow, mLeft, mRight; int mFirstRow, mLastRow, mLeft, mRight;