From 37eea51490ef76553ff0ae21f622016eb7c13869 Mon Sep 17 00:00:00 2001 From: Neil Date: Sun, 28 Mar 2021 12:05:42 +1100 Subject: Add shapes with curved and rounded ends to EOL annotations as EOLANNOTATION_*. --- doc/ScintillaDoc.html | 78 +++++++++++++++++++++++++++++++++++++++-- doc/ScintillaHistory.html | 3 ++ include/Scintilla.h | 15 ++++++-- include/Scintilla.iface | 15 ++++++-- src/EditView.cxx | 89 ++++++++++++++++++++++++++++++++++++++--------- 5 files changed, 175 insertions(+), 25 deletions(-) diff --git a/doc/ScintillaDoc.html b/doc/ScintillaDoc.html index ccbdf6550..8971f4d93 100644 --- a/doc/ScintillaDoc.html +++ b/doc/ScintillaDoc.html @@ -3835,7 +3835,7 @@ struct Sci_TextToFind { EOLANNOTATION_HIDDEN - 0 + 0x0 End of Line Annotations are not displayed. @@ -3843,7 +3843,7 @@ struct Sci_TextToFind { EOLANNOTATION_STANDARD - 1 + 0x1 End of Line Annotations are drawn left justified with no adornment. @@ -3851,11 +3851,83 @@ struct Sci_TextToFind { EOLANNOTATION_BOXED - 2 + 0x2 End of Line Annotations are indented to match the text and are surrounded by a box. + + EOLANNOTATION_STADIUM + + 0x100 + + Surround with a ◖stadium◗ - a rectangle with rounded ends. + + + + EOLANNOTATION_FLAT_CIRCLE + + 0x101 + + Surround with a |shape◗ with flat left end and curved right end. + + + + EOLANNOTATION_ANGLE_CIRCLE + + 0x102 + + Surround with a ◄shape◗ with angled left end and curved right end. + + + + EOLANNOTATION_CIRCLE_FLAT + + 0x110 + + Surround with a ◖shape| with curved left end and flat right end. + + + + EOLANNOTATION_FLATS + + 0x111 + + Surround with a |shape| with flat ends. + + + + EOLANNOTATION_ANGLE_FLAT + + 0x112 + + Surround with a ◄shape| with angled left end and flat right end. + + + + EOLANNOTATION_CIRCLE_ANGLE + + 0x120 + + Surround with a ◖shape▶ with curved left end and angled right end. + + + + EOLANNOTATION_FLAT_ANGLE + + 0x121 + + Surround with a |shape▶ with flat left end and angled right end. + + + + EOLANNOTATION_ANGLES + + 0x122 + + Surround with a ◄shape▶ with angles on each end. + + diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html index 614866e30..c518cd60e 100644 --- a/doc/ScintillaHistory.html +++ b/doc/ScintillaHistory.html @@ -605,6 +605,9 @@ SCI_MARKERSETBACKSELECTEDTRANSLUCENT, SCI_MARKERSETSTROKEWIDTH.
  • + Add shapes with curved and rounded ends to EOL annotations as EOLANNOTATION_*. +
  • +
  • Change graphics coordinates from float (32-bit) to double (64-bit). Fixes uneven line heights in large documents on Cocoa. Increases memory use. diff --git a/include/Scintilla.h b/include/Scintilla.h index 752c105a8..dd1dd78e4 100644 --- a/include/Scintilla.h +++ b/include/Scintilla.h @@ -1017,9 +1017,18 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_EOLANNOTATIONSETSTYLE 2742 #define SCI_EOLANNOTATIONGETSTYLE 2743 #define SCI_EOLANNOTATIONCLEARALL 2744 -#define EOLANNOTATION_HIDDEN 0 -#define EOLANNOTATION_STANDARD 1 -#define EOLANNOTATION_BOXED 2 +#define EOLANNOTATION_HIDDEN 0x0 +#define EOLANNOTATION_STANDARD 0x1 +#define EOLANNOTATION_BOXED 0x2 +#define EOLANNOTATION_STADIUM 0x100 +#define EOLANNOTATION_FLAT_CIRCLE 0x101 +#define EOLANNOTATION_ANGLE_CIRCLE 0x102 +#define EOLANNOTATION_CIRCLE_FLAT 0x110 +#define EOLANNOTATION_FLATS 0x111 +#define EOLANNOTATION_ANGLE_FLAT 0x112 +#define EOLANNOTATION_CIRCLE_ANGLE 0x120 +#define EOLANNOTATION_FLAT_ANGLE 0x121 +#define EOLANNOTATION_ANGLES 0x122 #define SCI_EOLANNOTATIONSETVISIBLE 2745 #define SCI_EOLANNOTATIONGETVISIBLE 2746 #define SCI_EOLANNOTATIONSETSTYLEOFFSET 2747 diff --git a/include/Scintilla.iface b/include/Scintilla.iface index 333362cc0..d0b8213e8 100644 --- a/include/Scintilla.iface +++ b/include/Scintilla.iface @@ -2878,9 +2878,18 @@ get int EOLAnnotationGetStyle=2743(line line,) fun void EOLAnnotationClearAll=2744(,) enu EOLAnnotationVisible=EOLANNOTATION_ -val EOLANNOTATION_HIDDEN=0 -val EOLANNOTATION_STANDARD=1 -val EOLANNOTATION_BOXED=2 +val EOLANNOTATION_HIDDEN=0x0 +val EOLANNOTATION_STANDARD=0x1 +val EOLANNOTATION_BOXED=0x2 +val EOLANNOTATION_STADIUM=0x100 +val EOLANNOTATION_FLAT_CIRCLE=0x101 +val EOLANNOTATION_ANGLE_CIRCLE=0x102 +val EOLANNOTATION_CIRCLE_FLAT=0x110 +val EOLANNOTATION_FLATS=0x111 +val EOLANNOTATION_ANGLE_FLAT=0x112 +val EOLANNOTATION_CIRCLE_ANGLE=0x120 +val EOLANNOTATION_FLAT_ANGLE=0x121 +val EOLANNOTATION_ANGLES=0x122 # Set the visibility for the end of line annotations for a view set void EOLAnnotationSetVisible=2745(EOLAnnotationVisible visible,) diff --git a/src/EditView.cxx b/src/EditView.cxx index 44c25ada0..f22b281c5 100644 --- a/src/EditView.cxx +++ b/src/EditView.cxx @@ -1288,7 +1288,45 @@ void EditView::DrawEOLAnnotationText(Surface *surface, const EditModel &model, c PRectangle rcSegment = rcLine; const Font *fontText = vsDraw.styles[style].font.get(); - const int widthEOLAnnotationText = static_cast(surface->WidthText(fontText, eolAnnotationText)); + + const Surface::Ends ends = static_cast(vsDraw.eolAnnotationVisible & 0xff); + const Surface::Ends leftSide = static_cast(static_cast(ends) & 0xf); + const Surface::Ends rightSide = static_cast(static_cast(ends) & 0xf0); + + XYPOSITION leftBoxSpace = 0; + XYPOSITION rightBoxSpace = 0; + if (vsDraw.eolAnnotationVisible >= EOLANNOTATION_BOXED) { + leftBoxSpace = 1; + rightBoxSpace = 1; + if (vsDraw.eolAnnotationVisible != EOLANNOTATION_BOXED) { + switch (leftSide) { + case Surface::Ends::leftFlat: + leftBoxSpace = 1; + break; + case Surface::Ends::leftAngle: + leftBoxSpace = rcLine.Height() / 2.0; + break; + case Surface::Ends::semiCircles: + default: + leftBoxSpace = rcLine.Height() / 3.0; + break; + } + switch (rightSide) { + case Surface::Ends::rightFlat: + rightBoxSpace = 1; + break; + case Surface::Ends::rightAngle: + rightBoxSpace = rcLine.Height() / 2.0; + break; + case Surface::Ends::semiCircles: + default: + rightBoxSpace = rcLine.Height() / 3.0; + break; + } + } + } + const int widthEOLAnnotationText = static_cast(surface->WidthTextUTF8(fontText, eolAnnotationText) + + leftBoxSpace + rightBoxSpace); const XYPOSITION spaceWidth = vsDraw.styles[ll->EndLineStyle()].spaceWidth; const XYPOSITION virtualSpace = model.sel.VirtualSpaceFor( @@ -1317,35 +1355,54 @@ void EditView::DrawEOLAnnotationText(Surface *surface, const EditModel &model, c } if (FlagSet(phase, DrawPhase::back)) { - surface->FillRectangleAligned(rcSegment, Fill(textBack)); - - // Fill Remainder of the line + // This fills in the whole remainder of the line even though + // it may be double drawing. This is to allow stadiums with + // curved or angled ends to have the area outside in the correct + // background colour. 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); } + PRectangle rcText = rcSegment; + rcText.left += leftBoxSpace; + rcText.right -= rightBoxSpace; + + // For single phase drawing, draw the text then any box over it if (FlagSet(phase, DrawPhase::text)) { - if (phasesDraw != PhasesDraw::one) { - surface->DrawTextTransparent(rcSegment, fontText, - rcSegment.top + vsDraw.maxAscent, eolAnnotationText, - textFore); - } else { - surface->DrawTextNoClip(rcSegment, fontText, - rcSegment.top + vsDraw.maxAscent, eolAnnotationText, + if (phasesDraw == PhasesDraw::one) { + surface->DrawTextNoClipUTF8(rcText, fontText, + rcText.top + vsDraw.maxAscent, eolAnnotationText, textFore, textBack); } } + // Draw any box or stadium shape if (FlagSet(phase, DrawPhase::indicatorsFore)) { - if (vsDraw.eolAnnotationVisible == EOLANNOTATION_BOXED ) { + if (vsDraw.eolAnnotationVisible >= EOLANNOTATION_BOXED) { PRectangle rcBox = rcSegment; rcBox.left = std::round(rcSegment.left); rcBox.right = std::round(rcSegment.right); - surface->RectangleFrame(rcBox, Stroke(textFore)); + if (vsDraw.eolAnnotationVisible == EOLANNOTATION_BOXED) { + surface->RectangleFrame(rcBox, Stroke(textFore)); + } else { + if (phasesDraw == PhasesDraw::one) { + // Draw an outline around the text + surface->Stadium(rcBox, FillStroke(ColourAlpha(textBack, 0), ColourAlpha(textFore), 1.0), ends); + } else { + // Draw with a fill to fill the edges of the shape. + surface->Stadium(rcBox, FillStroke(ColourAlpha(textBack), ColourAlpha(textFore), 1.0), ends); + } + } + } + } + + // For multi-phase drawing draw the text last as transparent over any box + if (FlagSet(phase, DrawPhase::text)) { + if (phasesDraw != PhasesDraw::one) { + surface->DrawTextTransparentUTF8(rcText, fontText, + rcText.top + vsDraw.maxAscent, eolAnnotationText, + textFore); } } } -- cgit v1.2.3