Changeset View
Changeset View
Standalone View
Standalone View
src/render/katerenderer.cpp
Show All 25 Lines | |||||
26 | #include "katedocument.h" | 26 | #include "katedocument.h" | ||
27 | #include "kateconfig.h" | 27 | #include "kateconfig.h" | ||
28 | #include "katehighlight.h" | 28 | #include "katehighlight.h" | ||
29 | #include "kateview.h" | 29 | #include "kateview.h" | ||
30 | #include "katerenderrange.h" | 30 | #include "katerenderrange.h" | ||
31 | #include "katetextlayout.h" | 31 | #include "katetextlayout.h" | ||
32 | #include "katebuffer.h" | 32 | #include "katebuffer.h" | ||
33 | 33 | | |||
34 | #include "ktexteditor/inlinenoteinterface.h" | ||||
35 | | ||||
34 | #include "katepartdebug.h" | 36 | #include "katepartdebug.h" | ||
35 | 37 | | |||
38 | #include <QFont> | ||||
36 | #include <QPainter> | 39 | #include <QPainter> | ||
37 | #include <QTextLine> | 40 | #include <QTextLine> | ||
38 | #include <QStack> | 41 | #include <QStack> | ||
39 | #include <QBrush> | 42 | #include <QBrush> | ||
40 | #include <QRegularExpression> | 43 | #include <QRegularExpression> | ||
41 | #include <QtMath> // qCeil | 44 | #include <QtMath> // qCeil | ||
42 | 45 | | |||
43 | static const QChar tabChar(QLatin1Char('\t')); | 46 | static const QChar tabChar(QLatin1Char('\t')); | ||
▲ Show 20 Lines • Show All 709 Lines • ▼ Show 20 Line(s) | 755 | if (x > xEnd) { | |||
753 | break; | 756 | break; | ||
754 | } | 757 | } | ||
755 | 758 | | |||
756 | paintNonPrintableSpaces(paint, x - xStart, y, text[charIndex]); | 759 | paintNonPrintableSpaces(paint, x - xStart, y, text[charIndex]); | ||
757 | } | 760 | } | ||
758 | } | 761 | } | ||
759 | } | 762 | } | ||
760 | 763 | | |||
764 | // Draw inline notes | ||||
765 | auto inlineNotes = m_view->inlineNotes(range->line()); | ||||
anthonyfieroni: const | |||||
766 | foreach (const KTextEditor::InlineNote& inlineNote, inlineNotes) { | ||||
anthonyfieroni: ```
for (const auto& inlineNote : inlineNotes) {
``` | |||||
767 | int column = inlineNote.column(); | ||||
768 | int viewLine = range->viewLineForColumn(column); | ||||
769 | | ||||
770 | // Determine the position where to paint the note. | ||||
771 | // We start by getting the x coordinate of cursor placed to the column. | ||||
772 | qreal x = range->viewLine(viewLine).lineLayout().cursorToX(column) - xStart; | ||||
773 | int textLength = range->length(); | ||||
774 | if (column == 0 || column < textLength) { | ||||
775 | // If the note is inside text or at the beginning, then there is a hole in the text where the | ||||
776 | // note should be painted and the cursor gets placed at the right side of it. So we have to | ||||
777 | // subtract the width of the note to get to left side of the hole. | ||||
778 | x -= inlineNote.width(lineHeight(), currentFont()); | ||||
779 | } else { | ||||
780 | // If the note is outside the text, then the X coordinate is located at the end of the line. | ||||
781 | // Add appropriate amount of spaces to reach the required column. | ||||
782 | x += spaceWidth() * (column - textLength); | ||||
783 | } | ||||
784 | | ||||
785 | qreal y = lineHeight() * viewLine; | ||||
786 | | ||||
787 | // Paint the note | ||||
788 | paint.save(); | ||||
789 | paint.translate(x, y); | ||||
790 | inlineNote.paint(lineHeight(), currentFont(), paint); | ||||
791 | paint.restore(); | ||||
792 | } | ||||
793 | | ||||
761 | // draw word-wrap-honor-indent filling | 794 | // draw word-wrap-honor-indent filling | ||
762 | if ((range->viewLineCount() > 1) && range->shiftX() && (range->shiftX() > xStart)) { | 795 | if ((range->viewLineCount() > 1) && range->shiftX() && (range->shiftX() > xStart)) { | ||
763 | if (backgroundBrushSet) | 796 | if (backgroundBrushSet) | ||
764 | paint.fillRect(0, lineHeight(), range->shiftX() - xStart, lineHeight() * (range->viewLineCount() - 1), | 797 | paint.fillRect(0, lineHeight(), range->shiftX() - xStart, lineHeight() * (range->viewLineCount() - 1), | ||
765 | backgroundBrush); | 798 | backgroundBrush); | ||
766 | paint.fillRect(0, lineHeight(), range->shiftX() - xStart, lineHeight() * (range->viewLineCount() - 1), | 799 | paint.fillRect(0, lineHeight(), range->shiftX() - xStart, lineHeight() * (range->viewLineCount() - 1), | ||
767 | QBrush(config()->wordWrapMarkerColor(), Qt::Dense4Pattern)); | 800 | QBrush(config()->wordWrapMarkerColor(), Qt::Dense4Pattern)); | ||
768 | } | 801 | } | ||
▲ Show 20 Lines • Show All 234 Lines • ▼ Show 20 Line(s) | 1002 | { | |||
1003 | } else { | 1036 | } else { | ||
1004 | opt.setAlignment(Qt::AlignLeft); | 1037 | opt.setAlignment(Qt::AlignLeft); | ||
1005 | opt.setTextDirection(Qt::LeftToRight); | 1038 | opt.setTextDirection(Qt::LeftToRight); | ||
1006 | } | 1039 | } | ||
1007 | 1040 | | |||
1008 | l->setTextOption(opt); | 1041 | l->setTextOption(opt); | ||
1009 | 1042 | | |||
1010 | // Syntax highlighting, inbuilt and arbitrary | 1043 | // Syntax highlighting, inbuilt and arbitrary | ||
1011 | l->setAdditionalFormats(decorationsForLine(textLine, lineLayout->line())); | 1044 | QList<QTextLayout::FormatRange> decorations = decorationsForLine(textLine, lineLayout->line()); | ||
1045 | | ||||
1046 | int firstLineOffset = 0; | ||||
1047 | | ||||
1048 | auto inlineNotes = m_view->inlineNotes(lineLayout->line()); | ||||
1049 | foreach (const KTextEditor::InlineNote& inlineNote, inlineNotes) { | ||||
anthonyfieroni: same as above | |||||
1050 | int column = inlineNote.column(); | ||||
1051 | int width = inlineNote.width(lineHeight(), currentFont()); | ||||
1052 | | ||||
1053 | // Make space for every inline note. | ||||
1054 | // If it is on column 0 (at the beginning of the line), we must offset the first line. | ||||
1055 | // If it is inside the text, we use absolute letter spacing to create space for it between the two letters. | ||||
1056 | // If it is outside of the text, we don't have to make space for it. | ||||
1057 | if (column == 0) { | ||||
1058 | firstLineOffset = width; | ||||
1059 | } else if (column < l->text().length()) { | ||||
1060 | QTextCharFormat text_char_format; | ||||
1061 | text_char_format.setFontLetterSpacing(width); | ||||
1062 | text_char_format.setFontLetterSpacingType(QFont::AbsoluteSpacing); | ||||
1063 | decorations.append(QTextLayout::FormatRange { column - 1, 1, text_char_format }); | ||||
1064 | } | ||||
1065 | } | ||||
1066 | | ||||
1067 | l->setAdditionalFormats(decorations); | ||||
1012 | 1068 | | |||
1013 | // Begin layouting | 1069 | // Begin layouting | ||
1014 | l->beginLayout(); | 1070 | l->beginLayout(); | ||
1015 | 1071 | | |||
1016 | int height = 0; | 1072 | int height = 0; | ||
1017 | int shiftX = 0; | 1073 | int shiftX = 0; | ||
1018 | 1074 | | |||
1019 | bool needShiftX = (maxwidth != -1) | 1075 | bool needShiftX = (maxwidth != -1) | ||
Show All 9 Lines | 1078 | forever { | |||
1029 | if (maxwidth > 0) | 1085 | if (maxwidth > 0) | ||
1030 | { | 1086 | { | ||
1031 | line.setLineWidth(maxwidth); | 1087 | line.setLineWidth(maxwidth); | ||
1032 | } | 1088 | } | ||
1033 | 1089 | | |||
1034 | // we include the leading, this must match the ::updateFontHeight code! | 1090 | // we include the leading, this must match the ::updateFontHeight code! | ||
1035 | line.setLeadingIncluded(true); | 1091 | line.setLeadingIncluded(true); | ||
1036 | 1092 | | |||
1037 | line.setPosition(QPoint(line.lineNumber() ? shiftX : 0, height)); | 1093 | line.setPosition(QPoint(line.lineNumber() ? shiftX : firstLineOffset, height)); | ||
1038 | 1094 | | |||
1039 | if (needShiftX && line.width() > 0) | 1095 | if (needShiftX && line.width() > 0) | ||
1040 | { | 1096 | { | ||
1041 | needShiftX = false; | 1097 | needShiftX = false; | ||
1042 | // Determine x offset for subsequent-lines-of-paragraph indenting | 1098 | // Determine x offset for subsequent-lines-of-paragraph indenting | ||
1043 | int pos = textLine->nextNonSpaceChar(0); | 1099 | int pos = textLine->nextNonSpaceChar(0); | ||
1044 | 1100 | | |||
1045 | if (pos > 0) { | 1101 | if (pos > 0) { | ||
▲ Show 20 Lines • Show All 107 Lines • Show Last 20 Lines |
const