Describe the bug
When you are selecting text in the control, you can see other text along the line "shift".
Expected vs observed behaviour
The text shouldn't shift.
Patch or snippet allowing to reproduce the problem
Using the wxRichTextCtrl sample, start selecting the line beginning with "What can you do with this thing?". After you select the W, you will see other text along that line shift.
Platform and version information
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
I cannot reproduce this on native Win10 or Win7 under VirtualBox.
However, when I run the sample and move it from the primary screen at 125% DPI to the secondary one with the standard DPI and attempt to select the sentence, selecting behaves erratically, selecting other parts than those dragged over by mouse. Sometimes it does work though.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
IIRC (from what was an old discussion on the same subject which nor I nor google can find) selected text is drawn separately from the rest of text. For partial word selection, it behaves as if there are 2 words next to each other, which renders differently from a single big word. A solution might be to change all that so that the background with the selected color was drawn before/under the text, rather than drawing the selected text separately from the unselected one.
IIRC this required significant changes to text rendering.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
Also experiencing this on wxWidgets 3.3.1 on macOS Ventura. It's not a big deal, but is a little unpolished.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
Yes, this looks bad and should definitely be fixed, but unfortunately this library doesn't have an active maintainer and I don't know it enough and don't use it myself, so it's hard to find the motivation to spend a lot of time on doing it. Of course, if somebody could contribute a fix for this, it would be great.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
Hi, guys, yeah I wasn't sure of a fix. What I did that seems to help it a bit was comment out this code in msw\dc.cpp DoGetTextExtent(). Not a real fix, but I just wanted to share.
/* const wxFont font2 = GetFont();
if ( font2.IsOk() && font2.GetStyle() != wxFONTSTYLE_NORMAL && len > 0 )
{
ABC width;
const wxChar chFirst = *string.begin();
if ( ::GetCharABCWidths(GetHdc(), chFirst, chFirst, &width) )
{
if ( width.abcA < 0 )
sizeRect.cx -= width.abcA;
if ( len > 1 )
{
const wxChar chLast = *string.rbegin();
::GetCharABCWidths(GetHdc(), chLast, chLast, &width);
}
//else: we already have the width of the last character
if ( width.abcC < 0 )
sizeRect.cx -= width.abcC;
}
//else: GetCharABCWidths() failed, not a TrueType font?
}*/
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
I've spent a fair amount of time this week digging into this.
Inside wxRichTextPlainText::Draw(), a line of text in which there is a partial selection—such as the line in which you're currently selecting text—is drawn in three segments via wxRichTextPlainText::DrawTabbedString(), which in turn calls wxDC::DrawText().
On canvasses with aggressive kerning and subpixel antialiasing, successive calls to DrawText() do not look the same, because font shaping is part of each call; it isn't cumulative.
This is why this jitter happens on all macOS (CoreGraphics) backends; happens on Windows with GDI+ backends but not GDI backends; and doesn't happen at all on Linux/GTK. The CoreGraphics and GDI+ implementations of wxDC appear to engage in heavy font hinting, meaning that DrawText("ABC"); appears different from DrawText("A"); DrawText("BC"); appears different from DrawText("AB"); DrawText("C");
There are basically three ways to fix this:
Try to disable font hinting at the platform implementation level. This is what @lsri2 was getting close to. However, lots of things use wxDC besides wxRichTextCtrl, so I'm hesitant to do that.
Brute-force disable of font hinting by drawing each character in its own DrawText() call. This might be tedious to code, especially taking into account some special handling of tabs. It would also likely look ugly and disable all font hinting. And I have no idea what the performance impact would be (i.e., what the overhead of each DrawText() call is aside from the actual rendering).
Print the entire line at once, all the time, even in partial selections. Draw the selection box independently of the text, and don't use font selection-color or selection-background in the DrawText() call, only when drawing the selection box. This has the additional advantage of significantly simplifying the code. It does require a minor API change to DrawTabbedString(), but it's a private method and it can be made backward compatible by providing default arguments to the new parameters.
I did a little proof of concept of approach number 3, and it seemed to work okay.
https://github.com/user-attachments/assets/38c9b4f4-f667-43a5-96d0-fd97cfbbd802
The code is the result of me messing around and trying different approaches, and littered with fprintfs to stderr so I could figure out what I'm doing. It is a total mess. I'll need to clean up the code significantly, and test on Windows and Linux, before I consider a PR.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
Thanks for looking into this!
I think (1) could be a simple solution if we provided functions for disabling it in wxDC: wxRTC could then call it to explicitly disable the font hinting without affecting anything else. But I agree that (3) is better, it's just that this requires more changes to wxRTC — but if you can make them, please do, TIA!
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()