diff -r b371d4b36bf9 qt/ScintillaEditBase/ScintillaQt.cpp --- a/qt/ScintillaEditBase/ScintillaQt.cpp Sat Mar 07 10:27:10 2026 +1100 +++ b/qt/ScintillaEditBase/ScintillaQt.cpp Sat Mar 07 10:55:12 2026 +1100 @@ -804,6 +804,13 @@ PRectangle rcClient = GetClientRectangle(); paintingAllText = rcPaint.Contains(rcClient); + QWidget *device = static_cast(wMain.GetID()); + const qreal scale = device->devicePixelRatioF(); + // Including 1.5 as unscaled to demonstrate seaming + bool scaled = !(scale == 1.0 || scale == 2.0 || scale == 1.5); + + vs.seamOverDraw = (scaled && !view.bufferedDraw && view.LinesOverlap()) ? 1.0 : 0.0; + AutoSurface surfacePaint(this); Paint(surfacePaint, rcPaint); surfacePaint->Release(); diff -r b371d4b36bf9 src/EditView.cxx --- a/src/EditView.cxx Sat Mar 07 10:27:10 2026 +1100 +++ b/src/EditView.cxx Sat Mar 07 10:55:12 2026 +1100 @@ -931,7 +931,7 @@ } const bool drawEOLSelection = eolInSelection && vsDraw.selection.eolFilled && (line < model.pdoc->LinesTotal() - 1); - const PRectangle rcArea = Clamp(rcLine, Edge::left, left); // Limit to right side of line from 'left' + const PRectangle rcArea = vsDraw.ApplySeam(Clamp(rcLine, Edge::left, left)); // Limit to right side of line from 'left' const ColourRGBA selectionBack = drawEOLSelection ? SelectionBackground(model, vsDraw, eolInSelection) : ColourRGBA{}; ColourRGBA base = vsDraw.styles[StyleDefault].back; @@ -1080,9 +1080,9 @@ blobsWidth += rcBlob.Width(); const ColourRGBA textBack = TextBackground(model, vsDraw, ll, background, eolInSelection, false, styleMain, eolPos); if (drawEOLSelection && (vsDraw.selection.layer == Layer::Base)) { - surface->FillRectangleAligned(rcBlob, Fill(selectionBack.Opaque())); + surface->FillRectangleAligned(vsDraw.ApplySeam(rcBlob), Fill(selectionBack.Opaque())); } else { - surface->FillRectangleAligned(rcBlob, Fill(textBack)); + surface->FillRectangleAligned(vsDraw.ApplySeam(rcBlob), Fill(textBack)); } ColourRGBA blobText = textBack; if (drawEOLSelection && (vsDraw.selection.layer == Layer::UnderText)) { @@ -1113,9 +1113,9 @@ } else if (const Style &styleLast = vsDraw.styles[ll->LastStyle()]; styleLast.eolFilled) { base = styleLast.back; } - surface->FillRectangleAligned(rcEOLIsSelected, Fill(base.Opaque())); + surface->FillRectangleAligned(vsDraw.ApplySeam(rcEOLIsSelected), Fill(base.Opaque())); if (drawEOLSelection && (vsDraw.selection.layer != Layer::Base)) { - surface->FillRectangleAligned(rcEOLIsSelected, selectionBack); + surface->FillRectangleAligned(vsDraw.ApplySeam(rcEOLIsSelected), selectionBack); } const bool drawEOLAnnotationStyledText = (vsDraw.eolAnnotationVisible != EOLAnnotationVisible::Hidden) && model.pdoc->EOLAnnotationStyledText(line).text; @@ -1286,7 +1286,7 @@ // 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. - surface->FillRectangleAligned(rcSegment, Fill(textBack)); + surface->FillRectangleAligned(vsDraw.ApplySeam(rcSegment), Fill(textBack)); FillLineRemainder(surface, model, vsDraw, ll, line, rcLine, rcSegment.right, subLine); } @@ -1684,7 +1684,7 @@ inIndentation = false; } } - surface->FillRectangleAligned(rcSegment, Fill(textBack)); + surface->FillRectangleAligned(vsDraw.ApplySeam(rcSegment), Fill(textBack)); if (!ts.representation) { // Normal text display if (vsDraw.viewWhitespace != WhiteSpace::Invisible) { @@ -1697,7 +1697,7 @@ if (drawWhitespaceBackground && vsDraw.WhiteSpaceVisible(inIndentation)) { const PRectangle rcSpace = Intersection(rcLine, ll->Span(cpos + ts.start, cpos + ts.start + countSpaces).Offset(horizontalOffset)); - surface->FillRectangleAligned(rcSpace, + surface->FillRectangleAligned(vsDraw.ApplySeam(rcSpace), vsDraw.ElementColourForced(Element::WhiteSpaceBack).Opaque()); } cpos += countSpaces; @@ -2520,6 +2520,8 @@ double durCopy = 0.0; ElapsedPeriod epWhole; #endif + // This is temporary to make any scaling seams obvious + surface->FillRectangleAligned(rcTextArea, Fill(ColourRGBA(0,0,0))); const bool bracesIgnoreStyle = ((vsDraw.braceHighlightIndicatorSet && (model.bracesMatchStyle == StyleBraceLight)) || (vsDraw.braceBadLightIndicatorSet && (model.bracesMatchStyle == StyleBraceBad))); @@ -2691,6 +2693,7 @@ // Don't show indentation guides // If this ever gets changed, cached pixmap would need to be recreated if technology != Technology::Default vsPrint.viewIndentationGuides = IndentView::None; + vsPrint.seamOverDraw = 0; // Not on screen so don't need screen scaling fix // Don't show the selection when printing vsPrint.selection.visible = false; vsPrint.elementColours.clear(); diff -r b371d4b36bf9 src/ViewStyle.cxx --- a/src/ViewStyle.cxx Sat Mar 07 10:27:10 2026 +1100 +++ b/src/ViewStyle.cxx Sat Mar 07 10:55:12 2026 +1100 @@ -310,6 +310,7 @@ whitespaceSize = source.whitespaceSize; viewIndentationGuides = source.viewIndentationGuides; viewEOL = source.viewEOL; + seamOverDraw = source.seamOverDraw; extraFontFlag = source.extraFontFlag; extraAscent = source.extraAscent; extraDescent = source.extraDescent; @@ -762,6 +763,10 @@ return (caretStyle <= CaretStyle::Block) ? static_cast(caretStyle) : CaretShape::line; } +PRectangle ViewStyle::ApplySeam(const PRectangle &rc) const noexcept { + return PRectangle(rc.left, rc.top, rc.right + seamOverDraw, rc.bottom + seamOverDraw); +} + void ViewStyle::AllocStyles(size_t sizeNew) { size_t i=styles.size(); styles.resize(sizeNew); diff -r b371d4b36bf9 src/ViewStyle.h --- a/src/ViewStyle.h Sat Mar 07 10:27:10 2026 +1100 +++ b/src/ViewStyle.h Sat Mar 07 10:55:12 2026 +1100 @@ -154,6 +154,7 @@ int whitespaceSize; Scintilla::IndentView viewIndentationGuides; bool viewEOL; + XYPOSITION seamOverDraw = 0; CaretAppearance caret; @@ -246,6 +247,8 @@ bool DrawCaretInsideSelection(bool inOverstrike, bool imeCaretBlockOverride) const noexcept; CaretShape CaretShapeForMode(bool inOverstrike, bool isMainSelection) const noexcept; + PRectangle ApplySeam(const PRectangle &rc) const noexcept; + private: void AllocStyles(size_t sizeNew); void CreateAndAddFont(const FontSpecification &fs);