Opened 14 months ago

Last modified 10 months ago

#18151 new defect

wxGTK - wxHTML::SetLayoutDirection doesn't work with GTK+ 3

Reported by: swt2c Owned by:
Priority: normal Milestone:
Component: wxGTK Version: 3.0.3
Keywords: Cc: swt@…
Blocked By: Blocking:
Patch: no

Description

wxHTML::SetLayoutDirection(wxLayout_RightToLeft) doesn't appear to work with GTK+ 3. It does work with GTK+ 2. This is with GTK+ 3.22.30 on Fedora 28. The attached patch to html sample reproduces it.

Attachments (1)

html_rtl.patch download (1.5 KB) - added by swt2c 14 months ago.

Download all attachments as: .zip

Change History (14)

Changed 14 months ago by swt2c

comment:1 Changed 14 months ago by vadz

Sorry, no time to debug this, is this wxHTML-specific? Or would e.g. wxGenericStaticText show the same problem with GTK+ 3?

comment:2 follow-up: Changed 14 months ago by swt2c

  • Cc swt@… added

I tried wxGenericStaticText - what's weird is that it displays that text (Hebrew I believe?) correctly, regardless of what I pass to SetLayoutDirection. I must admit I'm not very familiar with Right-To-Left languages.

comment:3 in reply to: ↑ 2 Changed 14 months ago by vadz

Replying to swt2c:

I tried wxGenericStaticText - what's weird is that it displays that text (Hebrew I believe?) correctly, regardless of what I pass to SetLayoutDirection.

This is somewhat mysterious. Could there be an explicit RLM marker (U+200F) in the text? Or does Pango text drawing routine (which we must end up calling here) really recognize the text direction automatically? This would explain why it doesn't work for wxHTML which (also) sets the layout direction on the DC...

comment:4 follow-up: Changed 14 months ago by swt2c

I have done a little more debugging on this, but haven't gotten to the bottom of it.

I checked and there doesn't appear to be an RLM marker in the string I'm testing with. In the case of wxGenericStaticText, perhaps GTK+ is checking the UTF-8 codepoints and automatically switching to RLT mode?

Anyway, I'm looking at what happens in the wxCairoContext on GTK+ 3 - it appears that when DrawText() is called there, it is called with one code point at a time. I'm trying to compare that to what happens on GTK+ 2 but I can't for the life of me find where the GTK+ 2 implementation of wxGraphicsContext::DrawText() / DoDrawText() is.

comment:5 in reply to: ↑ 4 ; follow-up: Changed 14 months ago by vadz

Replying to swt2c:

I'm trying to compare that to what happens on GTK+ 2 but I can't for the life of me find where the GTK+ 2 implementation of wxGraphicsContext::DrawText() / DoDrawText() is.

Just in case you're still looking: it's in src/generic/graphicc.cpp, i.e. wxCairoContext::DoDrawText().

comment:6 in reply to: ↑ 5 ; follow-up: Changed 14 months ago by swt2c

Replying to vadz:

Replying to swt2c:

I'm trying to compare that to what happens on GTK+ 2 but I can't for the life of me find where the GTK+ 2 implementation of wxGraphicsContext::DrawText() / DoDrawText() is.

Just in case you're still looking: it's in src/generic/graphicc.cpp, i.e. wxCairoContext::DoDrawText().

Oh. For some reason I was thinking only GTK+ 3 used the Cairo implementation, but GTK+ 2 used something else.

comment:7 in reply to: ↑ 6 Changed 14 months ago by pcor

Replying to swt2c:

Oh. For some reason I was thinking only GTK+ 3 used the Cairo implementation, but GTK+ 2 used something else.

This is correct. The GTK+2 wxDC implementation does not use Cairo. Most of it, including DoDrawText(), is in src/gtk/dcclient.cpp. Cairo will only be used on GTK+2 if you are explicitly using wxGraphicsContext or wxGCDC.

comment:8 Changed 14 months ago by vadz

Paul, the question in comment:5 I was replying to was explicitly about wxGraphicsContext, not wxDC. Otherwise what you're saying is, of course, totally correct.

comment:9 Changed 10 months ago by swt2c

Okay, so I spent some more time looking into this. The problem with the GTK+3 (Cairo) implementation is that the words are drawn left-to-right. The individual characters within words appear to be drawn correctly right-to-left. Presumably this is being done by Pango automatically detecting the language being used.

In the case of the GTK+2 implementation (which works), the words are being drawn right-to-left due to gtk_widget_set_direction() being called on the widget that is being drawn on.

In the case of GTK+3, the gtk_widget_set_direction() doesn't really seem to have an effect as the drawing isn't done with a gtk function, but using Cairo. So, I'm not sure of the best way to solve this - do we have to apply some transformation to the coordinates being passed to Cairo?

comment:10 Changed 10 months ago by vadz

We actually use Pango for text drawing with both GTK+ 3, see GTK-specific code in wxCairoContext::DoDrawText(). So I think that perhaps we just need to call pango_context_set_base_dir() on the PangoContext. I'm not sure how to get the latter from CairoContext, but presumably it should be possible, somehow?

comment:11 Changed 10 months ago by swt2c

Sorry - I wasn't clear in my previous comment. wxHTML seems to call wxDC::DrawText() one word at a time. The individual calls to DrawText() are drawn properly, so Pango is doing its job correctly. The issue is that the words are not drawn correctly with respect to each other.

comment:12 Changed 10 months ago by vadz

So it means that wxDC::SetLayoutDirection() doesn't work correctly in wxGTK3, right? This looks plausible because I don't see any code dealing with it neither in wxGTKCairoDCImpl nor in its base wxGCDCImpl class, while wxGTK2 code in src/gtk/dcclient.cpp does check the layout direction in many places.

comment:13 Changed 10 months ago by swt2c

That's correct.

Note: See TracTickets for help on using tickets.