diff options
-rw-r--r-- | src/EditView.cxx | 695 | ||||
-rw-r--r-- | src/EditView.h | 35 | ||||
-rw-r--r-- | src/Editor.cxx | 2 |
3 files changed, 373 insertions, 359 deletions
diff --git a/src/EditView.cxx b/src/EditView.cxx index fde8a937e..9bc074677 100644 --- a/src/EditView.cxx +++ b/src/EditView.cxx @@ -75,22 +75,9 @@ PrintParameters::PrintParameters() noexcept { wrapState = Wrap::Word; } -namespace Scintilla::Internal { - -bool ValidStyledText(const ViewStyle &vs, size_t styleOffset, const StyledText &st) noexcept { - if (st.multipleStyles) { - for (size_t iStyle = 0; iStyle<st.length; iStyle++) { - if (!vs.ValidStyle(styleOffset + st.styles[iStyle])) - return false; - } - } else { - if (!vs.ValidStyle(styleOffset + st.style)) - return false; - } - return true; -} +namespace { -static int WidthStyledText(Surface *surface, const ViewStyle &vs, int styleOffset, +int WidthStyledText(Surface *surface, const ViewStyle &vs, int styleOffset, const char *text, const unsigned char *styles, size_t len) { int width = 0; size_t start = 0; @@ -107,6 +94,23 @@ static int WidthStyledText(Surface *surface, const ViewStyle &vs, int styleOffse return width; } +} + +namespace Scintilla::Internal { + +bool ValidStyledText(const ViewStyle &vs, size_t styleOffset, const StyledText &st) noexcept { + if (st.multipleStyles) { + for (size_t iStyle = 0; iStyle<st.length; iStyle++) { + if (!vs.ValidStyle(styleOffset + st.styles[iStyle])) + return false; + } + } else { + if (!vs.ValidStyle(styleOffset + st.style)) + return false; + } + return true; +} + int WidestLineWidth(Surface *surface, const ViewStyle &vs, int styleOffset, const StyledText &st) { int widthMax = 0; size_t start = 0; @@ -279,51 +283,6 @@ void EditView::DropGraphics() noexcept { pixmapIndentGuideHighlight.reset(); } -static const char *ControlCharacterString(unsigned char ch) noexcept { - const char * const reps[] = { - "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL", - "BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI", - "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB", - "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US" - }; - if (ch < std::size(reps)) { - return reps[ch]; - } else { - return "BAD"; - } -} - -static void DrawTabArrow(Surface *surface, PRectangle rcTab, int ymid, - const ViewStyle &vsDraw, Stroke stroke) { - - const XYPOSITION halfWidth = stroke.width / 2.0; - - const XYPOSITION leftStroke = std::round(std::min(rcTab.left + 2, rcTab.right - 1)) + halfWidth; - const XYPOSITION rightStroke = std::max(leftStroke, std::round(rcTab.right) - 1.0f - halfWidth); - const XYPOSITION yMidAligned = ymid + halfWidth; - const Point arrowPoint(rightStroke, yMidAligned); - if (rightStroke > leftStroke) { - // When not enough room, don't draw the arrow shaft - surface->LineDraw(Point(leftStroke, yMidAligned), arrowPoint, stroke); - } - - // Draw the arrow head if needed - if (vsDraw.tabDrawMode == TabDrawMode::LongArrow) { - XYPOSITION ydiff = std::floor(rcTab.Height() / 2.0f); - XYPOSITION xhead = rightStroke - ydiff; - if (xhead <= rcTab.left) { - ydiff -= rcTab.left - xhead; - xhead = rcTab.left; - } - const Point ptsHead[] = { - Point(xhead, yMidAligned - ydiff), - arrowPoint, - Point(xhead, yMidAligned + ydiff) - }; - surface->PolyLine(ptsHead, std::size(ptsHead), stroke); - } -} - void EditView::RefreshPixMaps(Surface *surfaceWindow, const ViewStyle &vsDraw) { if (!pixmapIndentGuide) { // 1 extra pixel in height so can handle odd/even positions and so produce a continuous line @@ -983,9 +942,7 @@ ColourOptional SelectionForeground(const EditModel &model, const ViewStyle &vsDr return vsDraw.ElementColour(element); } -} - -static ColourRGBA TextBackground(const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, +ColourRGBA TextBackground(const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, ColourOptional background, InSelection inSelection, bool inHotspot, int styleMain, Sci::Position i) { if (inSelection && (vsDraw.selection.layer == Layer::Base)) { return SelectionBackground(model, vsDraw, inSelection).Opaque(); @@ -1006,15 +963,21 @@ static ColourRGBA TextBackground(const EditModel &model, const ViewStyle &vsDraw } } -void EditView::DrawIndentGuide(Surface *surface, Sci::Line lineVisible, int lineHeight, XYPOSITION start, PRectangle rcSegment, bool highlight) { - const Point from = Point::FromInts(0, ((lineVisible & 1) && (lineHeight & 1)) ? 1 : 0); - const PRectangle rcCopyArea(start + 1, rcSegment.top, - start + 2, rcSegment.bottom); - surface->Copy(rcCopyArea, from, - highlight ? *pixmapIndentGuideHighlight : *pixmapIndentGuide); +const char *ControlCharacterString(unsigned char ch) noexcept { + const char *const reps[] = { + "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL", + "BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI", + "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB", + "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US" + }; + if (ch < std::size(reps)) { + return reps[ch]; + } else { + return "BAD"; + } } -static void DrawTextBlob(Surface *surface, const ViewStyle &vsDraw, PRectangle rcSegment, +void DrawTextBlob(Surface *surface, const ViewStyle &vsDraw, PRectangle rcSegment, std::string_view text, ColourRGBA textBack, ColourRGBA textFore, bool fillBackground) { if (rcSegment.Empty()) return; @@ -1039,41 +1002,34 @@ static void DrawTextBlob(Surface *surface, const ViewStyle &vsDraw, PRectangle r textBack, textFore); } -static void DrawCaretLineFramed(Surface *surface, const ViewStyle &vsDraw, const LineLayout *ll, PRectangle rcLine, int subLine) { - const ColourOptional caretlineBack = vsDraw.ElementColour(Element::CaretLineBack); - if (!caretlineBack) { - return; +void FillLineRemainder(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, + Sci::Line line, PRectangle rcArea, int subLine) { + InSelection eolInSelection = InSelection::inNone; + if (vsDraw.selection.visible && (subLine == (ll->lines - 1))) { + eolInSelection = model.LineEndInSelection(line); } - const ColourRGBA colourFrame = (vsDraw.caretLine.layer == Layer::Base) ? - caretlineBack->Opaque() : *caretlineBack; - - const int width = vsDraw.GetFrameWidth(); - - // Avoid double drawing the corners by removing the left and right sides when drawing top and bottom borders - const PRectangle rcWithoutLeftRight = rcLine.Inset(Point(width, 0.0)); - - if (subLine == 0 || ll->wrapIndent == 0 || vsDraw.caretLine.layer != Layer::Base || vsDraw.caretLine.subLine) { - // Left - surface->FillRectangleAligned(Side(rcLine, Edge::left, width), colourFrame); - } - if (subLine == 0 || vsDraw.caretLine.subLine) { - // Top - surface->FillRectangleAligned(Side(rcWithoutLeftRight, Edge::top, width), colourFrame); - } - if (subLine == ll->lines - 1 || vsDraw.caretLine.layer != Layer::Base || vsDraw.caretLine.subLine) { - // Right - surface->FillRectangleAligned(Side(rcLine, Edge::right, width), colourFrame); - } - if (subLine == ll->lines - 1 || vsDraw.caretLine.subLine) { - // Bottom - surface->FillRectangleAligned(Side(rcWithoutLeftRight, Edge::bottom, width), colourFrame); + if (eolInSelection && vsDraw.selection.eolFilled && (line < model.pdoc->LinesTotal() - 1) && (vsDraw.selection.layer == Layer::Base)) { + surface->FillRectangleAligned(rcArea, Fill(SelectionBackground(model, vsDraw, eolInSelection).Opaque())); + } else { + const ColourOptional background = vsDraw.Background(model.GetMark(line), model.caret.active, ll->containsCaret); + if (background) { + surface->FillRectangleAligned(rcArea, Fill(*background)); + } else if (vsDraw.styles[ll->styles[ll->numCharsInLine]].eolFilled) { + surface->FillRectangleAligned(rcArea, Fill(vsDraw.styles[ll->styles[ll->numCharsInLine]].back)); + } else { + surface->FillRectangleAligned(rcArea, Fill(vsDraw.styles[StyleDefault].back)); + } + if (eolInSelection && vsDraw.selection.eolFilled && (line < model.pdoc->LinesTotal() - 1) && (vsDraw.selection.layer != Layer::Base)) { + surface->FillRectangleAligned(rcArea, SelectionBackground(model, vsDraw, eolInSelection)); + } } } +} + void EditView::DrawEOL(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, - PRectangle rcLine, Sci::Line line, Sci::Position lineEnd, int xStart, int subLine, XYACCUMULATOR subLineStart, - ColourOptional background) { + Sci::Line line, int xStart, PRectangle rcLine, int subLine, Sci::Position lineEnd, XYACCUMULATOR subLineStart, ColourOptional background) { const Sci::Position posLineStart = model.pdoc->LineStart(line); PRectangle rcSegment = rcLine; @@ -1251,139 +1207,6 @@ void EditView::DrawEOL(Surface *surface, const EditModel &model, const ViewStyle } } -static void DrawIndicator(int indicNum, Sci::Position startPos, Sci::Position endPos, Surface *surface, const ViewStyle &vsDraw, - const LineLayout *ll, int xStart, PRectangle rcLine, Sci::Position secondCharacter, int subLine, Indicator::State state, - int value, bool bidiEnabled, int tabWidthMinimumPixels) { - - const XYPOSITION subLineStart = ll->positions[ll->LineStart(subLine)]; - const XYPOSITION horizontalOffset = xStart - subLineStart; - - std::vector<PRectangle> rectangles; - - const XYPOSITION left = ll->XInLine(startPos) + horizontalOffset; - const XYPOSITION right = ll->XInLine(endPos) + horizontalOffset; - const PRectangle rcIndic(left, rcLine.top + vsDraw.maxAscent, right, - std::max(rcLine.top + vsDraw.maxAscent + 3, rcLine.bottom)); - - if (bidiEnabled) { - ScreenLine screenLine(ll, subLine, vsDraw, rcLine.right - xStart, tabWidthMinimumPixels); - const Range lineRange = ll->SubLineRange(subLine, LineLayout::Scope::visibleOnly); - - std::unique_ptr<IScreenLineLayout> slLayout = surface->Layout(&screenLine); - std::vector<Interval> intervals = slLayout->FindRangeIntervals( - startPos - lineRange.start, endPos - lineRange.start); - for (const Interval &interval : intervals) { - PRectangle rcInterval = rcIndic; - rcInterval.left = interval.left + xStart; - rcInterval.right = interval.right + xStart; - rectangles.push_back(rcInterval); - } - } else { - rectangles.push_back(rcIndic); - } - - for (const PRectangle &rc : rectangles) { - PRectangle rcFirstCharacter = rc; - // Allow full descent space for character indicators - rcFirstCharacter.bottom = rcLine.top + vsDraw.maxAscent + vsDraw.maxDescent; - if (secondCharacter >= 0) { - rcFirstCharacter.right = ll->XInLine(secondCharacter) + horizontalOffset; - } else { - // Indicator continued from earlier line so make an empty box and don't draw - rcFirstCharacter.right = rcFirstCharacter.left; - } - vsDraw.indicators[indicNum].Draw(surface, rc, rcLine, rcFirstCharacter, state, value); - } -} - -static void DrawIndicators(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, - Sci::Line line, int xStart, PRectangle rcLine, int subLine, Sci::Position lineEnd, bool under, int tabWidthMinimumPixels) { - // Draw decorators - const Sci::Position posLineStart = model.pdoc->LineStart(line); - const Sci::Position lineStart = ll->LineStart(subLine); - const Sci::Position posLineEnd = posLineStart + lineEnd; - - for (const IDecoration *deco : model.pdoc->decorations->View()) { - if (under == vsDraw.indicators[deco->Indicator()].under) { - Sci::Position startPos = posLineStart + lineStart; - while (startPos < posLineEnd) { - const Range rangeRun(deco->StartRun(startPos), deco->EndRun(startPos)); - const Sci::Position endPos = std::min(rangeRun.end, posLineEnd); - const int value = deco->ValueAt(startPos); - if (value) { - const bool hover = vsDraw.indicators[deco->Indicator()].IsDynamic() && - rangeRun.ContainsCharacter(model.hoverIndicatorPos); - const Indicator::State state = hover ? Indicator::State::hover : Indicator::State::normal; - const Sci::Position posSecond = model.pdoc->MovePositionOutsideChar(rangeRun.First() + 1, 1); - DrawIndicator(deco->Indicator(), startPos - posLineStart, endPos - posLineStart, - surface, vsDraw, ll, xStart, rcLine, posSecond - posLineStart, subLine, state, - value, model.BidirectionalEnabled(), tabWidthMinimumPixels); - } - startPos = endPos; - } - } - } - - // Use indicators to highlight matching braces - if ((vsDraw.braceHighlightIndicatorSet && (model.bracesMatchStyle == StyleBraceLight)) || - (vsDraw.braceBadLightIndicatorSet && (model.bracesMatchStyle == StyleBraceBad))) { - const int braceIndicator = (model.bracesMatchStyle == StyleBraceLight) ? vsDraw.braceHighlightIndicator : vsDraw.braceBadLightIndicator; - if (under == vsDraw.indicators[braceIndicator].under) { - const Range rangeLine(posLineStart + lineStart, posLineEnd); - for (size_t brace = 0; brace <= 1; brace++) { - if (rangeLine.ContainsCharacter(model.braces[brace])) { - const Sci::Position braceOffset = model.braces[brace] - posLineStart; - if (braceOffset < ll->numCharsInLine) { - const Sci::Position braceEnd = model.pdoc->MovePositionOutsideChar(model.braces[brace] + 1, 1) - posLineStart; - DrawIndicator(braceIndicator, braceOffset, braceEnd, - surface, vsDraw, ll, xStart, rcLine, braceEnd, subLine, Indicator::State::normal, - 1, model.BidirectionalEnabled(), tabWidthMinimumPixels); - } - } - } - } - } - - if (FlagSet(model.changeHistoryOption, ChangeHistoryOption::Indicators)) { - // Draw editions - constexpr int indexHistory = static_cast<int>(IndicatorNumbers::HistoryRevertedToOriginInsertion); - { - // Draw insertions - Sci::Position startPos = posLineStart + lineStart; - while (startPos < posLineEnd) { - const Range rangeRun(startPos, model.pdoc->EditionEndRun(startPos)); - const Sci::Position endPos = std::min(rangeRun.end, posLineEnd); - const int edition = model.pdoc->EditionAt(startPos); - if (edition != 0) { - const int indicator = (edition - 1) * 2 + indexHistory; - const Sci::Position posSecond = model.pdoc->MovePositionOutsideChar(rangeRun.First() + 1, 1); - DrawIndicator(indicator, startPos - posLineStart, endPos - posLineStart, - surface, vsDraw, ll, xStart, rcLine, posSecond - posLineStart, subLine, Indicator::State::normal, - 1, model.BidirectionalEnabled(), tabWidthMinimumPixels); - } - startPos = endPos; - } - } - { - // Draw deletions - Sci::Position startPos = posLineStart + lineStart; - while (startPos <= posLineEnd) { - const unsigned int editions = model.pdoc->EditionDeletesAt(startPos); - const Sci::Position posSecond = model.pdoc->MovePositionOutsideChar(startPos + 1, 1); - for (unsigned int edition=0; edition<4; edition++) { - if (editions & (1 << edition)) { - const int indicator = edition * 2 + indexHistory + 1; - DrawIndicator(indicator, startPos - posLineStart, posSecond - posLineStart, - surface, vsDraw, ll, xStart, rcLine, posSecond - posLineStart, subLine, Indicator::State::normal, - 1, model.BidirectionalEnabled(), tabWidthMinimumPixels); - } - } - startPos = model.pdoc->EditionNextDelete(startPos); - } - } - } -} - void EditView::DrawFoldDisplayText(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); @@ -1463,7 +1286,8 @@ 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) { +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) @@ -1615,10 +1439,14 @@ void EditView::DrawEOLAnnotationText(Surface *surface, const EditModel &model, c } } -static constexpr bool AnnotationBoxedOrIndented(AnnotationVisible annotationVisible) noexcept { +namespace { + +constexpr bool AnnotationBoxedOrIndented(AnnotationVisible annotationVisible) noexcept { return annotationVisible == AnnotationVisible::Boxed || annotationVisible == AnnotationVisible::Indented; } +} + void EditView::DrawAnnotation(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, Sci::Line line, int xStart, PRectangle rcLine, int subLine, DrawPhase phase) { const int indent = static_cast<int>(model.pdoc->GetLineIndentation(line) * vsDraw.spaceWidth); @@ -1678,7 +1506,9 @@ void EditView::DrawAnnotation(Surface *surface, const EditModel &model, const Vi } } -static void DrawBlockCaret(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, +namespace { + +void DrawBlockCaret(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, int subLine, int xStart, Sci::Position offset, Sci::Position posCaret, PRectangle rcCaret, ColourRGBA caretColour) { const Sci::Position lineStart = ll->LineStart(subLine); @@ -1744,6 +1574,8 @@ static void DrawBlockCaret(Surface *surface, const EditModel &model, const ViewS caretColour); } +} + void EditView::DrawCarets(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, Sci::Line lineDoc, int xStart, PRectangle rcLine, int subLine) const { // When drag is active it is the only caret drawn @@ -1901,11 +1733,9 @@ InSelection CharacterInCursesSelection(Sci::Position iDoc, const EditModel &mode return (caretAtStart || caretAtEnd) ? InSelection::inNone : InSelection::inMain; } -} - -void EditView::DrawBackground(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, - PRectangle rcLine, Range lineRange, Sci::Position posLineStart, int xStart, - int subLine, ColourOptional background) const { +void DrawBackground(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, + int xStart, PRectangle rcLine, int subLine, Range lineRange, Sci::Position posLineStart, + ColourOptional background) { const bool selBackDrawn = vsDraw.SelectionBackgroundDrawn(); bool inIndentation = subLine == 0; // Do not handle indentation except on first subline. @@ -1981,8 +1811,8 @@ void EditView::DrawBackground(Surface *surface, const EditModel &model, const Vi } } -static void DrawEdgeLine(Surface *surface, const ViewStyle &vsDraw, const LineLayout *ll, PRectangle rcLine, - Range lineRange, int xStart) { +void DrawEdgeLine(Surface *surface, const ViewStyle &vsDraw, const LineLayout *ll, + int xStart, PRectangle rcLine, Range lineRange) { if (vsDraw.edgeState == EdgeVisualStyle::Line) { PRectangle rcSegment = rcLine; const int edgeX = static_cast<int>(vsDraw.theEdge.column * vsDraw.spaceWidth); @@ -2007,7 +1837,7 @@ static void DrawEdgeLine(Surface *surface, const ViewStyle &vsDraw, const LineLa } // Draw underline mark as part of background if on base layer -static void DrawMarkUnderline(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, +void DrawMarkUnderline(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, Sci::Line line, PRectangle rcLine) { int marks = model.GetMark(line); for (int markBit = 0; (markBit < 32) && marks; markBit++) { @@ -2021,8 +1851,8 @@ static void DrawMarkUnderline(Surface *surface, const EditModel &model, const Vi } } -static void DrawTranslucentSelection(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, - Sci::Line line, PRectangle rcLine, int subLine, Range lineRange, int xStart, int tabWidthMinimumPixels, Layer layer) { +void DrawTranslucentSelection(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, + Sci::Line line, int xStart, PRectangle rcLine, int subLine, Range lineRange, int tabWidthMinimumPixels, Layer layer) { if (vsDraw.selection.layer == layer) { const Sci::Position posLineStart = model.pdoc->LineStart(line); const XYACCUMULATOR subLineStart = ll->positions[lineRange.start]; @@ -2085,8 +1915,41 @@ static void DrawTranslucentSelection(Surface *surface, const EditModel &model, c } } +void DrawCaretLineFramed(Surface *surface, const ViewStyle &vsDraw, const LineLayout *ll, + PRectangle rcLine, int subLine) { + const ColourOptional caretlineBack = vsDraw.ElementColour(Element::CaretLineBack); + if (!caretlineBack) { + return; + } + + const ColourRGBA colourFrame = (vsDraw.caretLine.layer == Layer::Base) ? + caretlineBack->Opaque() : *caretlineBack; + + const int width = vsDraw.GetFrameWidth(); + + // Avoid double drawing the corners by removing the left and right sides when drawing top and bottom borders + const PRectangle rcWithoutLeftRight = rcLine.Inset(Point(width, 0.0)); + + if (subLine == 0 || ll->wrapIndent == 0 || vsDraw.caretLine.layer != Layer::Base || vsDraw.caretLine.subLine) { + // Left + surface->FillRectangleAligned(Side(rcLine, Edge::left, width), colourFrame); + } + if (subLine == 0 || vsDraw.caretLine.subLine) { + // Top + surface->FillRectangleAligned(Side(rcWithoutLeftRight, Edge::top, width), colourFrame); + } + if (subLine == ll->lines - 1 || vsDraw.caretLine.layer != Layer::Base || vsDraw.caretLine.subLine) { + // Right + surface->FillRectangleAligned(Side(rcLine, Edge::right, width), colourFrame); + } + if (subLine == ll->lines - 1 || vsDraw.caretLine.subLine) { + // Bottom + surface->FillRectangleAligned(Side(rcWithoutLeftRight, Edge::bottom, width), colourFrame); + } +} + // Draw any translucent whole line states -static void DrawTranslucentLineState(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, +void DrawTranslucentLineState(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, Sci::Line line, PRectangle rcLine, int subLine, Layer layer) { if ((model.caret.active || vsDraw.caretLine.alwaysShow) && vsDraw.ElementColour(Element::CaretLineBack) && ll->containsCaret && vsDraw.caretLine.layer == layer) { @@ -2119,9 +1982,234 @@ static void DrawTranslucentLineState(Surface *surface, const EditModel &model, c } } +void DrawTabArrow(Surface *surface, PRectangle rcTab, int ymid, + const ViewStyle &vsDraw, Stroke stroke) { + + const XYPOSITION halfWidth = stroke.width / 2.0; + + const XYPOSITION leftStroke = std::round(std::min(rcTab.left + 2, rcTab.right - 1)) + halfWidth; + const XYPOSITION rightStroke = std::max(leftStroke, std::round(rcTab.right) - 1.0f - halfWidth); + const XYPOSITION yMidAligned = ymid + halfWidth; + const Point arrowPoint(rightStroke, yMidAligned); + if (rightStroke > leftStroke) { + // When not enough room, don't draw the arrow shaft + surface->LineDraw(Point(leftStroke, yMidAligned), arrowPoint, stroke); + } + + // Draw the arrow head if needed + if (vsDraw.tabDrawMode == TabDrawMode::LongArrow) { + XYPOSITION ydiff = std::floor(rcTab.Height() / 2.0f); + XYPOSITION xhead = rightStroke - ydiff; + if (xhead <= rcTab.left) { + ydiff -= rcTab.left - xhead; + xhead = rcTab.left; + } + const Point ptsHead[] = { + Point(xhead, yMidAligned - ydiff), + arrowPoint, + Point(xhead, yMidAligned + ydiff) + }; + surface->PolyLine(ptsHead, std::size(ptsHead), stroke); + } +} + +void DrawIndicator(int indicNum, Sci::Position startPos, Sci::Position endPos, Surface *surface, const ViewStyle &vsDraw, + const LineLayout *ll, int xStart, PRectangle rcLine, Sci::Position secondCharacter, int subLine, Indicator::State state, + int value, bool bidiEnabled, int tabWidthMinimumPixels) { + + const XYPOSITION subLineStart = ll->positions[ll->LineStart(subLine)]; + const XYPOSITION horizontalOffset = xStart - subLineStart; + + std::vector<PRectangle> rectangles; + + const XYPOSITION left = ll->XInLine(startPos) + horizontalOffset; + const XYPOSITION right = ll->XInLine(endPos) + horizontalOffset; + const PRectangle rcIndic(left, rcLine.top + vsDraw.maxAscent, right, + std::max(rcLine.top + vsDraw.maxAscent + 3, rcLine.bottom)); + + if (bidiEnabled) { + ScreenLine screenLine(ll, subLine, vsDraw, rcLine.right - xStart, tabWidthMinimumPixels); + const Range lineRange = ll->SubLineRange(subLine, LineLayout::Scope::visibleOnly); + + std::unique_ptr<IScreenLineLayout> slLayout = surface->Layout(&screenLine); + std::vector<Interval> intervals = slLayout->FindRangeIntervals( + startPos - lineRange.start, endPos - lineRange.start); + for (const Interval &interval : intervals) { + PRectangle rcInterval = rcIndic; + rcInterval.left = interval.left + xStart; + rcInterval.right = interval.right + xStart; + rectangles.push_back(rcInterval); + } + } else { + rectangles.push_back(rcIndic); + } + + for (const PRectangle &rc : rectangles) { + PRectangle rcFirstCharacter = rc; + // Allow full descent space for character indicators + rcFirstCharacter.bottom = rcLine.top + vsDraw.maxAscent + vsDraw.maxDescent; + if (secondCharacter >= 0) { + rcFirstCharacter.right = ll->XInLine(secondCharacter) + horizontalOffset; + } else { + // Indicator continued from earlier line so make an empty box and don't draw + rcFirstCharacter.right = rcFirstCharacter.left; + } + vsDraw.indicators[indicNum].Draw(surface, rc, rcLine, rcFirstCharacter, state, value); + } +} + +void DrawIndicators(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, + Sci::Line line, int xStart, PRectangle rcLine, int subLine, Sci::Position lineEnd, bool under, int tabWidthMinimumPixels) { + // Draw decorators + const Sci::Position posLineStart = model.pdoc->LineStart(line); + const Sci::Position lineStart = ll->LineStart(subLine); + const Sci::Position posLineEnd = posLineStart + lineEnd; + + for (const IDecoration *deco : model.pdoc->decorations->View()) { + if (under == vsDraw.indicators[deco->Indicator()].under) { + Sci::Position startPos = posLineStart + lineStart; + while (startPos < posLineEnd) { + const Range rangeRun(deco->StartRun(startPos), deco->EndRun(startPos)); + const Sci::Position endPos = std::min(rangeRun.end, posLineEnd); + const int value = deco->ValueAt(startPos); + if (value) { + const bool hover = vsDraw.indicators[deco->Indicator()].IsDynamic() && + rangeRun.ContainsCharacter(model.hoverIndicatorPos); + const Indicator::State state = hover ? Indicator::State::hover : Indicator::State::normal; + const Sci::Position posSecond = model.pdoc->MovePositionOutsideChar(rangeRun.First() + 1, 1); + DrawIndicator(deco->Indicator(), startPos - posLineStart, endPos - posLineStart, + surface, vsDraw, ll, xStart, rcLine, posSecond - posLineStart, subLine, state, + value, model.BidirectionalEnabled(), tabWidthMinimumPixels); + } + startPos = endPos; + } + } + } + + // Use indicators to highlight matching braces + if ((vsDraw.braceHighlightIndicatorSet && (model.bracesMatchStyle == StyleBraceLight)) || + (vsDraw.braceBadLightIndicatorSet && (model.bracesMatchStyle == StyleBraceBad))) { + const int braceIndicator = (model.bracesMatchStyle == StyleBraceLight) ? vsDraw.braceHighlightIndicator : vsDraw.braceBadLightIndicator; + if (under == vsDraw.indicators[braceIndicator].under) { + const Range rangeLine(posLineStart + lineStart, posLineEnd); + for (size_t brace = 0; brace <= 1; brace++) { + if (rangeLine.ContainsCharacter(model.braces[brace])) { + const Sci::Position braceOffset = model.braces[brace] - posLineStart; + if (braceOffset < ll->numCharsInLine) { + const Sci::Position braceEnd = model.pdoc->MovePositionOutsideChar(model.braces[brace] + 1, 1) - posLineStart; + DrawIndicator(braceIndicator, braceOffset, braceEnd, + surface, vsDraw, ll, xStart, rcLine, braceEnd, subLine, Indicator::State::normal, + 1, model.BidirectionalEnabled(), tabWidthMinimumPixels); + } + } + } + } + } + + if (FlagSet(model.changeHistoryOption, ChangeHistoryOption::Indicators)) { + // Draw editions + constexpr int indexHistory = static_cast<int>(IndicatorNumbers::HistoryRevertedToOriginInsertion); + { + // Draw insertions + Sci::Position startPos = posLineStart + lineStart; + while (startPos < posLineEnd) { + const Range rangeRun(startPos, model.pdoc->EditionEndRun(startPos)); + const Sci::Position endPos = std::min(rangeRun.end, posLineEnd); + const int edition = model.pdoc->EditionAt(startPos); + if (edition != 0) { + const int indicator = (edition - 1) * 2 + indexHistory; + const Sci::Position posSecond = model.pdoc->MovePositionOutsideChar(rangeRun.First() + 1, 1); + DrawIndicator(indicator, startPos - posLineStart, endPos - posLineStart, + surface, vsDraw, ll, xStart, rcLine, posSecond - posLineStart, subLine, Indicator::State::normal, + 1, model.BidirectionalEnabled(), tabWidthMinimumPixels); + } + startPos = endPos; + } + } + { + // Draw deletions + Sci::Position startPos = posLineStart + lineStart; + while (startPos <= posLineEnd) { + const unsigned int editions = model.pdoc->EditionDeletesAt(startPos); + const Sci::Position posSecond = model.pdoc->MovePositionOutsideChar(startPos + 1, 1); + for (unsigned int edition = 0; edition < 4; edition++) { + if (editions & (1 << edition)) { + const int indicator = edition * 2 + indexHistory + 1; + DrawIndicator(indicator, startPos - posLineStart, posSecond - posLineStart, + surface, vsDraw, ll, xStart, rcLine, posSecond - posLineStart, subLine, Indicator::State::normal, + 1, model.BidirectionalEnabled(), tabWidthMinimumPixels); + } + } + startPos = model.pdoc->EditionNextDelete(startPos); + } + } + } +} + +void DrawFoldLines(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, + Sci::Line line, PRectangle rcLine, int subLine) { + const bool lastSubLine = subLine == (ll->lines - 1); + const bool expanded = model.pcs->GetExpanded(line); + const FoldLevel level = model.pdoc->GetFoldLevel(line); + const FoldLevel levelNext = model.pdoc->GetFoldLevel(line + 1); + if (LevelIsHeader(level) && + (LevelNumber(level) < LevelNumber(levelNext))) { + const ColourRGBA foldLineColour = vsDraw.ElementColour(Element::FoldLine).value_or( + vsDraw.styles[StyleDefault].fore); + // Paint the line above the fold + if ((subLine == 0) && + ((expanded && (FlagSet(model.foldFlags, FoldFlag::LineBeforeExpanded))) + || + (!expanded && (FlagSet(model.foldFlags, FoldFlag::LineBeforeContracted))))) { + surface->FillRectangleAligned(Side(rcLine, Edge::top, 1.0), foldLineColour); + } + // Paint the line below the fold + if (lastSubLine && + ((expanded && (FlagSet(model.foldFlags, FoldFlag::LineAfterExpanded))) + || + (!expanded && (FlagSet(model.foldFlags, FoldFlag::LineAfterContracted))))) { + surface->FillRectangleAligned(Side(rcLine, Edge::bottom, 1.0), foldLineColour); + // If contracted fold line drawn then don't overwrite with hidden line + // as fold lines are more specific then hidden lines. + if (!expanded) { + return; + } + } + } + if (lastSubLine && model.pcs->GetVisible(line) && !model.pcs->GetVisible(line + 1)) { + if (const ColourOptional hiddenLineColour = vsDraw.ElementColour(Element::HiddenLine)) { + surface->FillRectangleAligned(Side(rcLine, Edge::bottom, 1.0), *hiddenLineColour); + } + } +} + +ColourRGBA InvertedLight(ColourRGBA orig) noexcept { + unsigned int r = orig.GetRed(); + unsigned int g = orig.GetGreen(); + unsigned int b = orig.GetBlue(); + const unsigned int l = (r + g + b) / 3; // There is a better calculation for this that matches human eye + const unsigned int il = 0xff - l; + if (l == 0) + return ColourRGBA(0xff, 0xff, 0xff); + r = r * il / l; + g = g * il / l; + b = b * il / l; + return ColourRGBA(std::min(r, 0xffu), std::min(g, 0xffu), std::min(b, 0xffu)); +} + +} + +void EditView::DrawIndentGuide(Surface *surface, Sci::Line lineVisible, int lineHeight, XYPOSITION start, PRectangle rcSegment, bool highlight) { + const Point from = Point::FromInts(0, ((lineVisible & 1) && (lineHeight & 1)) ? 1 : 0); + const PRectangle rcCopyArea(start + 1, rcSegment.top, + start + 2, rcSegment.bottom); + surface->Copy(rcCopyArea, from, + highlight ? *pixmapIndentGuideHighlight : *pixmapIndentGuide); +} + void EditView::DrawForeground(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, - Sci::Line lineVisible, PRectangle rcLine, Range lineRange, Sci::Position posLineStart, int xStart, - int subLine, ColourOptional background) { + int xStart, PRectangle rcLine, int subLine, Sci::Line lineVisible, Range lineRange, Sci::Position posLineStart, + ColourOptional background) { const bool selBackDrawn = vsDraw.SelectionBackgroundDrawn(); const bool drawWhitespaceBackground = vsDraw.WhitespaceBackgroundDrawn() && !background; @@ -2331,7 +2419,7 @@ void EditView::DrawForeground(Surface *surface, const EditModel &model, const Vi } void EditView::DrawIndentGuidesOverEmpty(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, - Sci::Line line, Sci::Line lineVisible, PRectangle rcLine, int xStart, int subLine) { + Sci::Line line, int xStart, PRectangle rcLine, int subLine, Sci::Line lineVisible) { if ((vsDraw.viewIndentationGuides == IndentView::LookForward || vsDraw.viewIndentationGuides == IndentView::LookBoth) && (subLine == 0)) { const Sci::Position posLineStart = model.pdoc->LineStart(line); @@ -2415,14 +2503,15 @@ void EditView::DrawLine(Surface *surface, const EditModel &model, const ViewStyl if (phasesDraw != PhasesDraw::One) { if (FlagSet(phase, DrawPhase::back)) { - DrawBackground(surface, model, vsDraw, ll, rcLine, lineRange, posLineStart, xStart, - subLine, background); + DrawBackground(surface, model, vsDraw, ll, + xStart, rcLine, subLine, lineRange, posLineStart, + background); DrawFoldDisplayText(surface, model, vsDraw, ll, line, xStart, rcLine, subLine, subLineStart, DrawPhase::back); DrawEOLAnnotationText(surface, model, vsDraw, ll, line, xStart, rcLine, subLine, subLineStart, DrawPhase::back); // Remove drawBack to not draw again in DrawFoldDisplayText phase = static_cast<DrawPhase>(static_cast<int>(phase) & ~static_cast<int>(DrawPhase::back)); - DrawEOL(surface, model, vsDraw, ll, rcLine, line, lineRange.end, - xStart, subLine, subLineStart, background); + DrawEOL(surface, model, vsDraw, ll, + line, xStart, rcLine, subLine, lineRange.end, subLineStart, background); if (vsDraw.IsLineFrameOpaque(model.caret.active, ll->containsCaret)) DrawCaretLineFramed(surface, vsDraw, ll, rcLine, subLine); } @@ -2430,22 +2519,24 @@ void EditView::DrawLine(Surface *surface, const EditModel &model, const ViewStyl if (FlagSet(phase, DrawPhase::indicatorsBack)) { DrawIndicators(surface, model, vsDraw, ll, line, xStart, rcLine, subLine, lineRangeIncludingEnd.end, true, tabWidthMinimumPixels); - DrawEdgeLine(surface, vsDraw, ll, rcLine, lineRange, xStart); + DrawEdgeLine(surface, vsDraw, ll, xStart, rcLine, lineRange); DrawMarkUnderline(surface, model, vsDraw, line, rcLine); } } if (FlagSet(phase, DrawPhase::text)) { if (vsDraw.selection.visible) { - DrawTranslucentSelection(surface, model, vsDraw, ll, line, rcLine, subLine, lineRange, xStart, tabWidthMinimumPixels, Layer::UnderText); + DrawTranslucentSelection(surface, model, vsDraw, ll, + line, xStart, rcLine, subLine, lineRange, tabWidthMinimumPixels, Layer::UnderText); } DrawTranslucentLineState(surface, model, vsDraw, ll, line, rcLine, subLine, Layer::UnderText); - DrawForeground(surface, model, vsDraw, ll, lineVisible, rcLine, lineRange, posLineStart, xStart, - subLine, background); + DrawForeground(surface, model, vsDraw, ll, + xStart, rcLine, subLine, lineVisible, lineRange, posLineStart, + background); } if (FlagSet(phase, DrawPhase::indentationGuides)) { - DrawIndentGuidesOverEmpty(surface, model, vsDraw, ll, line, lineVisible, rcLine, xStart, subLine); + DrawIndentGuidesOverEmpty(surface, model, vsDraw, ll, line, xStart, rcLine, subLine, lineVisible); } if (FlagSet(phase, DrawPhase::indicatorsFore)) { @@ -2457,16 +2548,17 @@ void EditView::DrawLine(Surface *surface, const EditModel &model, const ViewStyl DrawEOLAnnotationText(surface, model, vsDraw, ll, line, xStart, rcLine, subLine, subLineStart, phase); if (phasesDraw == PhasesDraw::One) { - DrawEOL(surface, model, vsDraw, ll, rcLine, line, lineRange.end, - xStart, subLine, subLineStart, background); + DrawEOL(surface, model, vsDraw, ll, + line, xStart, rcLine, subLine, lineRange.end, subLineStart, background); if (vsDraw.IsLineFrameOpaque(model.caret.active, ll->containsCaret)) DrawCaretLineFramed(surface, vsDraw, ll, rcLine, subLine); - DrawEdgeLine(surface, vsDraw, ll, rcLine, lineRange, xStart); + DrawEdgeLine(surface, vsDraw, ll, xStart, rcLine, lineRange); DrawMarkUnderline(surface, model, vsDraw, line, rcLine); } if (vsDraw.selection.visible && FlagSet(phase, DrawPhase::selectionTranslucent)) { - DrawTranslucentSelection(surface, model, vsDraw, ll, line, rcLine, subLine, lineRange, xStart, tabWidthMinimumPixels, Layer::OverText); + DrawTranslucentSelection(surface, model, vsDraw, ll, + line, xStart, rcLine, subLine, lineRange, tabWidthMinimumPixels, Layer::OverText); } if (FlagSet(phase, DrawPhase::lineTranslucent)) { @@ -2478,45 +2570,8 @@ void EditView::DrawLine(Surface *surface, const EditModel &model, const ViewStyl } } -static void DrawFoldLines(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, - Sci::Line line, PRectangle rcLine, int subLine) { - const bool lastSubLine = subLine == (ll->lines - 1); - const bool expanded = model.pcs->GetExpanded(line); - const FoldLevel level = model.pdoc->GetFoldLevel(line); - const FoldLevel levelNext = model.pdoc->GetFoldLevel(line + 1); - if (LevelIsHeader(level) && - (LevelNumber(level) < LevelNumber(levelNext))) { - const ColourRGBA foldLineColour = vsDraw.ElementColour(Element::FoldLine).value_or( - vsDraw.styles[StyleDefault].fore); - // Paint the line above the fold - if ((subLine == 0) && - ((expanded && (FlagSet(model.foldFlags, FoldFlag::LineBeforeExpanded))) - || - (!expanded && (FlagSet(model.foldFlags, FoldFlag::LineBeforeContracted))))) { - surface->FillRectangleAligned(Side(rcLine, Edge::top, 1.0), foldLineColour); - } - // Paint the line below the fold - if (lastSubLine && - ((expanded && (FlagSet(model.foldFlags, FoldFlag::LineAfterExpanded))) - || - (!expanded && (FlagSet(model.foldFlags, FoldFlag::LineAfterContracted))))) { - surface->FillRectangleAligned(Side(rcLine, Edge::bottom, 1.0), foldLineColour); - // If contracted fold line drawn then don't overwrite with hidden line - // as fold lines are more specific then hidden lines. - if (!expanded) { - return; - } - } - } - if (lastSubLine && model.pcs->GetVisible(line) && !model.pcs->GetVisible(line + 1)) { - if (const ColourOptional hiddenLineColour = vsDraw.ElementColour(Element::HiddenLine)) { - surface->FillRectangleAligned(Side(rcLine, Edge::bottom, 1.0), *hiddenLineColour); - } - } -} - -void EditView::PaintText(Surface *surfaceWindow, const EditModel &model, PRectangle rcArea, - PRectangle rcClient, const ViewStyle &vsDraw) { +void EditView::PaintText(Surface *surfaceWindow, const EditModel &model, const ViewStyle &vsDraw, + PRectangle rcArea, PRectangle rcClient) { // Allow text at start of line to overlap 1 pixel into the margin as this displays // serifs and italic stems for aliased text. const int leftTextOverlap = ((model.xOffset == 0) && (vsDraw.leftMarginWidth > 0)) ? 1 : 0; @@ -2712,47 +2767,9 @@ void EditView::PaintText(Surface *surfaceWindow, const EditModel &model, PRectan } } -void EditView::FillLineRemainder(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, - Sci::Line line, PRectangle rcArea, int subLine) const { - InSelection eolInSelection = InSelection::inNone; - if (vsDraw.selection.visible && (subLine == (ll->lines - 1))) { - eolInSelection = model.LineEndInSelection(line); - } - - if (eolInSelection && vsDraw.selection.eolFilled && (line < model.pdoc->LinesTotal() - 1) && (vsDraw.selection.layer == Layer::Base)) { - surface->FillRectangleAligned(rcArea, Fill(SelectionBackground(model, vsDraw, eolInSelection).Opaque())); - } else { - const ColourOptional background = vsDraw.Background(model.GetMark(line), model.caret.active, ll->containsCaret); - if (background) { - surface->FillRectangleAligned(rcArea, Fill(*background)); - } else if (vsDraw.styles[ll->styles[ll->numCharsInLine]].eolFilled) { - surface->FillRectangleAligned(rcArea, Fill(vsDraw.styles[ll->styles[ll->numCharsInLine]].back)); - } else { - surface->FillRectangleAligned(rcArea, Fill(vsDraw.styles[StyleDefault].back)); - } - if (eolInSelection && vsDraw.selection.eolFilled && (line < model.pdoc->LinesTotal() - 1) && (vsDraw.selection.layer != Layer::Base)) { - surface->FillRectangleAligned(rcArea, SelectionBackground(model, vsDraw, eolInSelection)); - } - } -} - // Space (3 space characters) between line numbers and text when printing. #define lineNumberPrintSpace " " -static ColourRGBA InvertedLight(ColourRGBA orig) noexcept { - unsigned int r = orig.GetRed(); - unsigned int g = orig.GetGreen(); - unsigned int b = orig.GetBlue(); - const unsigned int l = (r + g + b) / 3; // There is a better calculation for this that matches human eye - const unsigned int il = 0xff - l; - if (l == 0) - return ColourRGBA(0xff, 0xff, 0xff); - r = r * il / l; - g = g * il / l; - b = b * il / l; - return ColourRGBA(std::min(r, 0xffu), std::min(g, 0xffu), std::min(b, 0xffu)); -} - Sci::Position EditView::FormatRange(bool draw, CharacterRangeFull chrg, Rectangle rc, Surface *surface, Surface *surfaceMeasure, const EditModel &model, const ViewStyle &vs) { // Can't use measurements cached for screen diff --git a/src/EditView.h b/src/EditView.h index 33da5f294..c05703710 100644 --- a/src/EditView.h +++ b/src/EditView.h @@ -133,32 +133,29 @@ public: Sci::Line DisplayFromPosition(Surface *surface, const EditModel &model, Sci::Position pos, const ViewStyle &vs); Sci::Position StartEndDisplayLine(Surface *surface, const EditModel &model, Sci::Position pos, bool start, const ViewStyle &vs); - void DrawIndentGuide(Surface *surface, Sci::Line lineVisible, int lineHeight, XYPOSITION start, PRectangle rcSegment, bool highlight); - void DrawEOL(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, PRectangle rcLine, - Sci::Line line, Sci::Position lineEnd, int xStart, int subLine, XYACCUMULATOR subLineStart, - ColourOptional background); +private: + void DrawEOL(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, + Sci::Line line, int xStart, PRectangle rcLine, int subLine, Sci::Position lineEnd, XYACCUMULATOR subLineStart, ColourOptional background); void DrawFoldDisplayText(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, Sci::Line line, int xStart, PRectangle rcLine, int subLine, XYACCUMULATOR subLineStart, DrawPhase phase); void 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); void DrawAnnotation(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, Sci::Line line, int xStart, PRectangle rcLine, int subLine, DrawPhase phase); - void DrawCarets(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, Sci::Line lineDoc, - int xStart, PRectangle rcLine, int subLine) const; - void DrawBackground(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, PRectangle rcLine, - Range lineRange, Sci::Position posLineStart, int xStart, - int subLine, ColourOptional background) const; - void DrawForeground(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, Sci::Line lineVisible, - PRectangle rcLine, Range lineRange, Sci::Position posLineStart, int xStart, - int subLine, ColourOptional background); + void DrawCarets(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, + Sci::Line lineDoc, int xStart, PRectangle rcLine, int subLine) const; + void DrawIndentGuide(Surface *surface, Sci::Line lineVisible, int lineHeight, XYPOSITION start, PRectangle rcSegment, bool highlight); + void DrawForeground(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, + int xStart, PRectangle rcLine, int subLine, Sci::Line lineVisible, Range lineRange, Sci::Position posLineStart, + ColourOptional background); void DrawIndentGuidesOverEmpty(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, - Sci::Line line, Sci::Line lineVisible, PRectangle rcLine, int xStart, int subLine); - void DrawLine(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, Sci::Line line, - Sci::Line lineVisible, int xStart, PRectangle rcLine, int subLine, DrawPhase phase); - void PaintText(Surface *surfaceWindow, const EditModel &model, PRectangle rcArea, PRectangle rcClient, - const ViewStyle &vsDraw); - void FillLineRemainder(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, - Sci::Line line, PRectangle rcArea, int subLine) const; + Sci::Line line, int xStart, PRectangle rcLine, int subLine, Sci::Line lineVisible); + void DrawLine(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, + Sci::Line line, Sci::Line lineVisible, int xStart, PRectangle rcLine, int subLine, DrawPhase phase); + +public: + void PaintText(Surface *surfaceWindow, const EditModel &model, const ViewStyle &vsDraw, + PRectangle rcArea, PRectangle rcClient); Sci::Position FormatRange(bool draw, CharacterRangeFull chrg, Rectangle rc, Surface *surface, Surface *surfaceMeasure, const EditModel &model, const ViewStyle &vs); }; diff --git a/src/Editor.cxx b/src/Editor.cxx index 9a98b470c..3bf50b09e 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -1819,7 +1819,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { return; } - view.PaintText(surfaceWindow, *this, rcArea, rcClient, vs); + view.PaintText(surfaceWindow, *this, vs, rcArea, rcClient); if (horizontalScrollBarVisible && trackLineWidth && (view.lineWidthMaxSeen > scrollWidth)) { scrollWidth = view.lineWidthMaxSeen; |