Opened 2 years ago

Last modified 12 months ago

#14735 confirmed defect

RichTextCtrl underline not working correctly on Windows

Reported by: transana Owned by:
Priority: normal Milestone:
Component: wxRichText Version:
Keywords: underline windows RichTextCtrl Cc:
Blocked By: Blocking:
Patch: no

Description

On Windows, ApplyUnderlineToSelection() doesn't always show up immediately. If you underline a selection, the underlining for that original selection won't show up until a subsequent Underline, Bold, or Italics call is made elsewhere.

Removing underlining always occurs immediately. Bold and Italics work immediately. Underlining works fine on lines that also contain bold or italics, but not when used alone. The same code that fails on Windows works correctly on Ubuntu and OS X.

I've verified this in wxPython 2.8.12.1 and 2.9.4.0, and was referred here by Robin Dunn, who suggested this was more likely a wxWidgets issue than a wxPython issue.

Attachments (2)

RTF Format Problem.py download (4.0 KB) - added by transana 2 years ago.
wxPython example of RichTextCtrl underline problem
Line Spacing.png download (62.2 KB) - added by transana 12 months ago.
Visual confirmation of the underlining problem, solved by changing line spacing

Download all attachments as: .zip

Change History (11)

Changed 2 years ago by transana

wxPython example of RichTextCtrl underline problem

comment:1 Changed 23 months ago by transana

I see a second variation of this problem sometimes, particularly near the end of a document that has little text or very few format changes. If I have a paragraph of several sentences, and I try to underline a single word or part of a word, the entire line will be underlined. If I pick a selection (even a single character) outside of what I had selected and turn underlining off, then all the underlining that should not have been drawn will disappear. If the word I'm trying to underline a word in the middle of the line and the whole line gets underlined, removing underlining from a character on one side of the original word will cause the underlining on BOTH sides of the original word to disappear.

Some users have reported that this behavior is different with different fonts. In my experience, Courier New is particularly susceptible to problems. Unfortunately, it's also a favorite font of a segment of my users who need a fixed-width font for their work with my program.

Changed 12 months ago by transana

Visual confirmation of the underlining problem, solved by changing line spacing

comment:2 Changed 12 months ago by transana

I've figured out the crucial dynamic behind this problem.

When line spacing is 10, underlines get covered over by the next line of text, rendering the underline formatting invisible. Simply changing line spacing to 11 causes all underlining to be visible as specified. See the attached file "Line Spacing.png", which is two screen shots that differ ONLY in that the line spacing is 10 for the top one and 11 for the bottom one.

comment:3 Changed 12 months ago by juliansmart

  • Status changed from new to confirmed

Hi, sorry I didn't see this report earlier.

I can reproduce the problem with 2.8 and 3.0 SVN on Windows 8 64-bit with Courier New. After resizing the window, the underlining appears again, and then Undo/Redo work correctly. Applying underlining explicitly again then fails until a resize. I tried invalidating and refreshing the control explicitly after applying underlining, but that didn't do it. Something about resizing clears the problem. Sorry I don't have an answer yet but I'll keep thinking; any suggestions welcome.

comment:4 Changed 12 months ago by transana

In playing with this yesterday, it's become clear to me that the central issue is the relationship between font size and line spacing.

Single line spacing, wx.TEXT_ATTR_LINE_SPACING_NORMAL is defined at 10 point. The font size I was using is 12 point.

With FontSize set to 12, and line spacing set to 10, underlining isn't show where a lower line is rendered (but does appear if the next line is blank or too short to reach the underline. Change the font size to 10, all underlining is shown. Leave the font at 12 but change the line spacing to 11 or 12, all underlining is shown.

My best guess is that when line spacing is sufficiently smaller than font size, the underlining gets over-written by the ascending space of the next line.

IIRC, the RichTextCtrl automatically adjusts line height to accommodate larger font sizes on a line when mixed font sizes are used. Perhaps this adjustment is just a pixel or two too small to correctly display underlining?

comment:5 Changed 12 months ago by juliansmart

Thanks for the further thoughts. I will look at this again as soon as I can. The puzzle is how it shows correctly after a resize, but not before, and apparently the spacing calculations are the same since I don't see the gap widen after resizing.

comment:6 Changed 12 months ago by juliansmart

We're not the only people with this problem; see: https://bitbucket.org/equalsraf/vim-qt/issue/59/undercurl-underline-or-even-underscore-not

I will see if we can get further metrics on Windows that we can use to extend the height when necessary.

comment:7 Changed 12 months ago by juliansmart

I'm still drawing a blank here. The problem still exists whatever the line spacing, and even when I add 10 pixels to the character height and descent to give more space. There's nothing that I can see is overwriting the text, such as DrawRectangle, and the clipping region is too large to affect it. However the underline is always redrawn after resizing the window. When I change to DejaVu Sans Mono, the underline is drawn immediately. Sorry, still scratching my head over this. All suggestions welcome for further lines of enquiry.

comment:8 Changed 12 months ago by ericj

I played around with this myself, my observations are slightly different though (XP, 32bit):

For me it's only a redraw problem.

Select text -> select underline -> no visual change -> move another window (from another application) over the RTC, underline becomes visible.

I noticed that the actual line is outside (below) the selection rectangle. My guess is that when clicking somewhere else to clear the selection, the area outside does not get repainted.

comment:9 Changed 12 months ago by juliansmart

Interesting; on Windows 8 I can't get the underline to be drawn when moving windows over the wxRTC; the control has a bitmap buffer so it shouldn't cause the drawing code to be called.

As you say, the underline is drawn outside the selection rectangle. I've checked that the size of the selection reflects the reported height of the font in the DC via GetCharHeight(), e.g. 18 pixels. So the underline is being drawn (if at all) outside of the reported height of the font. Trying to give the font more arbitrary space, as per my previous comment, doesn't seem to help with the drawing, so it's almost as if sometimes it's the actual drawing of the font that restricts itself to the reported height, and not any subsequent drawing by wxRTC. The underline is still missing even if there is no further text below the underlined text.

Note: See TracTickets for help on using tickets.