Decreasing seams in scaled windows

26 views
Skip to first unread message

Neil

unread,
Mar 4, 2026, 1:08:24 AM (6 days ago) Mar 4
to scintilla-interest
In some circumstances, when a Scintilla window is scaled by a fractional amount like 1.5x or 1.25x, visual anomalies occur between filled rectangles. The window background may show through because the rectangles before and after or above and below only partially draw shared pixels.

This can be seen in this image with Qt 6 on Win32 with 1.25x scaling.

This was reported in some bug tracker issues and in the "Scintilla GTK 4 port" thread.
In that thread, a couple of patches decrease the severity of the seams but do not eliminate them.

I believe the highest quality output will be produced when Scintilla is drawing to raw screen pixels and the text is scaled to match the window scaling factor. However, some platforms may make this difficult or impossible to accomplish so some improvements can be made.

[Overdraw by 1 pixel]

One technique to cover seams is to draw more than required to ensure that each pixel is completely covered by at least one filled rectangle call. Extending the area of each opaque background rectangle by 1 (logical) pixel horizontally and vertically can achieve this. Almost all background drawing occurs left-to-right & top-to-bottom, so each of these oversized rectangles will then have a following rectangle merge nicely on its leading pixel as it will only see the colour of the preceding rectangle, with no trace of the window background.

If the scaling factor is less than 1.0x (0.5x?), a larger extension may be needed.

This technique improves over the proposal to clear the whole window to a global background colour as it will work better with areas (like JavaScript in a HTML page) that use a different background colour.

There are problems with extending this to translucent drawing as a translucent drawing call will have different results when performed more times.

An incomplete implementation of this is available from

The results can be seen with the same text as above.
There are faint seams in the selection as it uses translucency and these will be more prominent when the selection colour differs more from the text background. There is a vertical seam between the line number and marker margins as the implementation is currently only for EditView. 

This code is slower and could potentially cause flicker due to drawing some pixels multiple times. It only works in unbuffered mode and with SCI_SETPHASESDRAW(SC_PHASES_MULTIPLE) since it draws outside the strict line rectangles used in other modes.

This mode could be controlled by the application or Scintilla platform layer code or a combination. It is really only helpful when the window is scaled fractionally and this may be determined by the platform layer. It may change as the window is moved between screens and will be an extra chore for the application to manage.

Its likely that the referenced patch will grow as more elements need to handle it. I think the visible line end mode is one that needs to change. The way seamOverDraw is passed around is ugly and may have unforeseen effects: this could cause different results when printing, for example.

Neil

Mitchell

unread,
Mar 4, 2026, 10:25:19 AM (6 days ago) Mar 4
to scintilla...@googlegroups.com
Hi Neil,
The curses (terminal) platform treats each pixel as a cell, so it is very sensitive to any rectangle size changes. I haven’t tested this patch, but I’d like to know if this “overdrawing” can be optional. Or maybe the overdraw parameters can be ignored by the platform? (It’s hard for me to understand the patch by reading it by itself.)

I’d appreciate any thoughts you might have on this.

Cheers,
Mitchell

Neil

unread,
Mar 4, 2026, 4:19:42 PM (5 days ago) Mar 4
to scintilla-interest
Mitchell:
I haven’t tested this patch, but I’d like to know if this “overdrawing” can be optional. Or maybe the overdraw parameters can be ignored by the platform? (It’s hard for me to understand the patch by reading it by itself.)

Yes, the overdraw will be optional and it may be up to the platform layer to enable it.

Perhaps overdraw is completely determined by the platform layer. Or there could be an API.

The decision could be a combination of the platform layer and an API.

There are other APIs like `SCI_SETTECHNOLOGY` and `SCI_SETBIDIRECTIONAL` where some platform layers intercept the call to restrict the possibilities such as refusing bidirectional mode.

Sometimes scaling information is available at an application level but is not easily available from a widget. On Win32, for example, some messages only go to topmost windows.

In the opposite direction, requiring applications to use an API means this will be less automatic which will lead to a poorer default experience.

The patch does not include an API or any platform enabling since its just trying to see if the idea is workable.

Neil 

John Ehresman

unread,
Mar 4, 2026, 11:40:46 PM (5 days ago) Mar 4
to scintilla...@googlegroups.com
Apologies for not looking into this sooner. I think Qt can render to the raw screen or device pixels (or at least the backing pixmap that Qt draws to before sending to the screen).

The way to simulate / adjust the scaling factor is to use the QT_SCALE_FACTOR environment variable; e.g QT_SCALE_FACTOR=1.5 testprogram

One way to draw to raw pixels is to render to a full size pixmap, set the device pixel ratio to match the widget, then render the pixmap to the widget.

It also may be possible to set the scale on a painter to 1 / device-pixel-ratio and then draw.

I may be able to try to fix this in scintilla, but it probably won’t be immediately.

John
> --
> You received this message because you are subscribed to the Google Groups "scintilla-interest" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to scintilla-inter...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/scintilla-interest/5530760c-3b48-4610-8c57-0ec3fc6381den%40googlegroups.com.

Neil

unread,
Mar 6, 2026, 7:17:37 PM (3 days ago) Mar 6
to scintilla-interest
John:

One way to draw to raw pixels is to render to a full size pixmap, set the device pixel ratio to match the widget, then render the pixmap to the widget.

It also may be possible to set the scale on a painter to 1 / device-pixel-ratio and then draw.

These will be better approaches.

The earlier patch on this thread is improved a bit in case it is needed for other platforms.

This applies to the current repository state since a recent commit reduced draw calls for visible whitespace background by using a single call for a sequence of spaces instead on one call per space. Its faster and removes seams between spaces.

The Larger3.patch change moves the controlling variable to ViewState where it can be set differently for screen and printer. The decision is now made in the platform layer inside ScintillaQt.cpp. Seam overdraw is turned off for integer scaling 1x and 2x and also, to allow experimentation, for 1.5x.

Neil
Reply all
Reply to author
Forward
0 new messages