diff options
Diffstat (limited to 'src/EditView.cxx')
-rw-r--r-- | src/EditView.cxx | 94 |
1 files changed, 93 insertions, 1 deletions
diff --git a/src/EditView.cxx b/src/EditView.cxx index 9599e293f..290106a49 100644 --- a/src/EditView.cxx +++ b/src/EditView.cxx @@ -1050,7 +1050,8 @@ void EditView::DrawEOL(Surface *surface, const EditModel &model, const ViewStyle rcSegment.left = rcLine.left; rcSegment.right = rcLine.right; - const bool fillRemainder = !lastSubLine || !model.GetFoldDisplayText(line); + bool drawEOLAnnotationStyledText = (vsDraw.eolAnnotationVisible != EOLANNOTATION_HIDDEN) && model.pdoc->EOLAnnotationStyledText(line).text; + const bool fillRemainder = (!lastSubLine || (!model.GetFoldDisplayText(line) && !drawEOLAnnotationStyledText)); if (fillRemainder) { // Fill the remainder of the line FillLineRemainder(surface, model, vsDraw, ll, line, rcSegment, subLine); @@ -1285,6 +1286,95 @@ void EditView::DrawFoldDisplayText(Surface *surface, const EditModel &model, con } } +void EditView::DrawEOLAnnotationText(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, Sci::Line line, int xStart, PRectangle rcLine, int subLine, XYACCUMULATOR subLineStart, DrawPhase phase) { + + const bool lastSubLine = subLine == (ll->lines - 1); + if (!lastSubLine) + return; + + if (vsDraw.eolAnnotationVisible == EOLANNOTATION_HIDDEN) { + return; + } + const StyledText stEOLAnnotation = model.pdoc->EOLAnnotationStyledText(line); + if (!stEOLAnnotation.text || !ValidStyledText(vsDraw, vsDraw.eolAnnotationStyleOffset, stEOLAnnotation)) { + return; + } + const std::string_view eolAnnotationText(stEOLAnnotation.text, stEOLAnnotation.length); + const size_t style = stEOLAnnotation.style + vsDraw.eolAnnotationStyleOffset; + + PRectangle rcSegment = rcLine; + FontAlias fontText = vsDraw.styles[style].font; + const int widthEOLAnnotationText = static_cast<int>(surface->WidthText(fontText, eolAnnotationText)); + + const XYPOSITION spaceWidth = vsDraw.styles[ll->EndLineStyle()].spaceWidth; + const XYPOSITION virtualSpace = model.sel.VirtualSpaceFor( + model.pdoc->LineEnd(line)) * spaceWidth; + rcSegment.left = xStart + + static_cast<XYPOSITION>(ll->positions[ll->numCharsInLine] - subLineStart) + + virtualSpace + vsDraw.aveCharWidth; + + const char *textFoldDisplay = model.GetFoldDisplayText(line); + if (textFoldDisplay) { + const std::string_view foldDisplayText(textFoldDisplay); + rcSegment.left += (static_cast<int>(surface->WidthText(fontText, foldDisplayText)) + vsDraw.aveCharWidth); + } + rcSegment.right = rcSegment.left + static_cast<XYPOSITION>(widthEOLAnnotationText); + + const ColourOptional background = vsDraw.Background(model.pdoc->GetMark(line), model.caret.active, ll->containsCaret); + ColourDesired textFore = vsDraw.styles[style].fore; + const ColourDesired textBack = TextBackground(model, vsDraw, ll, background, false, + false, static_cast<int>(style), -1); + + if (model.trackLineWidth) { + if (rcSegment.right + 1> lineWidthMaxSeen) { + // EOL Annotation text border drawn on rcSegment.right with width 1 is the last visible object of the line + lineWidthMaxSeen = static_cast<int>(rcSegment.right + 1); + } + } + + if (phase & drawBack) { + surface->FillRectangle(rcSegment, textBack); + + // Fill Remainder of the line + PRectangle rcRemainder = rcSegment; + rcRemainder.left = rcRemainder.right; + if (rcRemainder.left < rcLine.left) + rcRemainder.left = rcLine.left; + rcRemainder.right = rcLine.right; + FillLineRemainder(surface, model, vsDraw, ll, line, rcRemainder, subLine); + } + + if (phase & drawText) { + if (phasesDraw != phasesOne) { + surface->DrawTextTransparent(rcSegment, fontText, + rcSegment.top + vsDraw.maxAscent, eolAnnotationText, + textFore); + } else { + surface->DrawTextNoClip(rcSegment, fontText, + rcSegment.top + vsDraw.maxAscent, eolAnnotationText, + textFore, textBack); + } + } + + if (phase & drawIndicatorsFore) { + if (vsDraw.eolAnnotationVisible == EOLANNOTATION_BOXED ) { + surface->PenColour(textFore); + PRectangle rcBox = rcSegment; + rcBox.left = std::round(rcSegment.left); + rcBox.right = std::round(rcSegment.right); + const IntegerRectangle ircBox(rcBox); + surface->MoveTo(ircBox.left, ircBox.top); + surface->LineTo(ircBox.left, ircBox.bottom); + surface->MoveTo(ircBox.right, ircBox.top); + surface->LineTo(ircBox.right, ircBox.bottom); + surface->MoveTo(ircBox.left, ircBox.top); + surface->LineTo(ircBox.right, ircBox.top); + surface->MoveTo(ircBox.left, ircBox.bottom - 1); + surface->LineTo(ircBox.right, ircBox.bottom - 1); + } + } +} + static constexpr bool AnnotationBoxedOrIndented(int annotationVisible) noexcept { return annotationVisible == ANNOTATION_BOXED || annotationVisible == ANNOTATION_INDENTED; } @@ -2039,6 +2129,7 @@ void EditView::DrawLine(Surface *surface, const EditModel &model, const ViewStyl DrawBackground(surface, model, vsDraw, ll, rcLine, lineRange, posLineStart, xStart, subLine, background); DrawFoldDisplayText(surface, model, vsDraw, ll, line, xStart, rcLine, subLine, subLineStart, drawBack); + DrawEOLAnnotationText(surface, model, vsDraw, ll, line, xStart, rcLine, subLine, subLineStart, drawBack); phase = static_cast<DrawPhase>(phase & ~drawBack); // Remove drawBack to not draw again in DrawFoldDisplayText DrawEOL(surface, model, vsDraw, ll, rcLine, line, lineRange.end, xStart, subLine, subLineStart, background); @@ -2069,6 +2160,7 @@ void EditView::DrawLine(Surface *surface, const EditModel &model, const ViewStyl } DrawFoldDisplayText(surface, model, vsDraw, ll, line, xStart, rcLine, subLine, subLineStart, phase); + DrawEOLAnnotationText(surface, model, vsDraw, ll, line, xStart, rcLine, subLine, subLineStart, phase); if (phasesDraw == phasesOne) { DrawEOL(surface, model, vsDraw, ll, rcLine, line, lineRange.end, |