Wpf: LinearGradientBrush in Multi-language text element bug.

Created on 16 Dec 2018  ·  16Comments  ·  Source: dotnet/wpf

  <Window.Resources>
    <LinearGradientBrush x:Key="brush1" StartPoint="0,0.5" EndPoint="1,0.5">
      <GradientStop Offset="0" Color="Red" />
      <GradientStop Offset="1" Color="blue" />
    </LinearGradientBrush>
  </Window.Resources> 
  <TextBlock Foreground="{StaticResource brush1}" Text="我是abcdefg文本わたしは" /> 

Display result in view ↓ (bad):
bad image
This is default font (MS YaHei) in zh-cn OS.

issue-type-bug

All 16 comments

Could you bring the Text to geometry and draw the geometry with LinearGradientBrush?

How to bring the Text to geometry see https://stackoverflow.com/q/1036327/6116637

@a44281071 could you explain what is wrong with this rendering result? Brush is applied per-run, because those runs are rendered separately, did you expect it to apply to text as a whole?

@nsivov
the desired result is below ↓(font-family : STSong. Have full character set in one font file.)
desired image

I see, this is probably doable if you assemble lines yourself, on WPF side, and derive individual gradient parameters from that. Font with better character coverage won't always help, changing font size for subranges will bring the problem back. Converting it all to geometry implies discarding potentially preferable embedded bitmaps, and it will result in different rendering quality depending on font and font sizes.

In your example the text is split into several runs and each run has a fallback applied. Specifying a font family for the TextBlock that has all the required Glyphs will most likely result in one run and therefore has the brush applied "correctly". By not specifying the font family a fallback is used. So there is no real issue here.

All the comments explaining the issue are good.

@a44281071 I would add that you should follow our bug template as the information in there is pertinent. In this case, the OS you are running on may show different behaviors. WPF has different fallbacks per some OS versions and the fonts themselves have changed across OS versions (both removal, changing glyph sets, etc).

If you require this behavior I would be sure to specify the best font for the job and be careful of OS changes that may affect the available fonts and/or fallbacks.

The status of this is a bit unclear to me. It sounds like this behavior might be expected, although it's not immediately obvious why. @a44281071 can you answer the below questions?

  1. Does specifying a particular font family fix the issue?
  2. Does this only happen on certain versions of the OS compared to others?

@stevenbrix

  1. A font file contains multiple languages, problems not arise. When multiple font files are referenced at the same textblock run, problems arise.
  2. win10 existing problem. other OS untest.
  • No problem DrawingContext.DrawGeometry with System.Windows.Media.FormattedText

@a44281071, we believe this works as designed. If you break down your text into Run's, you can acheive the effect you need.

closing.

@vatsan-madhavan No, this TextBlock and Run bug. Not expected. Please fix the bug.

@a44281071 what @vatsan-madhavan is saying I believe is that it works as intended. If you want different behaviour you'll have to implement it yourself.

@nsivov I'm not quite sure what @vatsan-madhavan is suggesting either. As far as I understand it the problem gets created in the first place by the text engine implicitly breaking down the text into multiple runs when its not supposed to. How can manually breaking down the text into runs help?

Do you suggest writing analysis code which figures out where the WPF text engine will introduce hidden runs and inserting them manually instead? That sounds very error prone, WPF itself is in a better situation to fix the problem.

Just use a font that has all the glyphs you neeed in it. Otherwise the text engine has to create runs for each fallback.

@Gillibald That workaround already has been mentioned but not all applications have full control over the font, sometimes the user can select fonts. It's clear that this is not a candidate for 3.0 release since the bug is also in Desktop WPF but I certainly would like to keep the issue open and get it fixed some time later, because it is a bug that cannot be worked around by the application (besides not triggering it by using a different font, but thats not always an option)

And again. This is not a bug. I implemented this for Avalonia in the same way as the Wpf team did it without knowing the implementation. The only way to apply one brush is to convert the text to a path. Everything else isn't worth the effort. Just my opinion. Feel free to find a way to implement this.

@weltkante it is supposed to break it into multiple runs when fallback takes place, there is no way around that. Script as well as font are run attributes, with multiple scripts or multiple fonts you'll get multiple runs, that's not the problem. Issue happens only at rendering time, and only because runs are rendered separately from each other, and that's how DirectWrite works - effect spanning several runs will apply to all of them, but separately. It should be possible to workaround that when using native Direct2D, using opacity masks for bitmap mode or geometry fills for outline mode. No idea if WPF will offer something like that, actual rendering code wasn't published yet, I guess we'll see. My point is that it's not necessarily a bug, but the way it works, and it remains to be seen if you can patch Core WPF to do what you want.

@Gillibald that's obviously not an option in general case.

Was this page helpful?
0 / 5 - 0 ratings