Notice (2018-05-24): bugzilla.xamarin.com is now in
Please join us on
Visual Studio Developer Community and in the
Mono organizations on
GitHub to continue tracking issues. Bugzilla will remain
available for reference in read-only mode. We will continue to work
on open Bugzilla bugs, copy them to the new locations
as needed for follow-up, and add the new items under Related
Our sincere thanks to everyone who has contributed on this bug
tracker over the years. Thanks also for your understanding as we
make these adjustments and improvements for the future.
Please create a new report on
Developer Community or GitHub with
your current version information, steps to reproduce, and relevant error
messages or log files if you are hitting an issue that looks similar to
this resolved bug and you do not yet see a matching new report.
Created attachment 18759 [details]
VS2015 Xamarin Android (Native) project referencing SkiaSharp 1.55.1
1. Open attached project. Nuget for SkiaSharp is omitted to save space so go into 'Manage NuGet Packages' and add a reference to any version of SkiSharp. I tried with 1.49.1 and 1.55.1. Note that because of a breaking change in the SKColorType enumeration, you will have to change the 'Rgba999' constant to 'Rgba_888' to compile in 1.49.1.
2. Run the project in an emulator or device (I used a Google Nexus 7 (Android 4.4 - API 19)). The sample uses SKCanvas.DrawText to draw a string, "Unicode: [ 年 月 ]" to a View.
The Japanese characters (年, 月) are missing, and the string that appears is "Unicode: [ ]".
The Japanese characters should appear inline along with the rest of the string.
I tried various different typefaces, and even set the language on the device to 'ja-JP', to no avail.
The Japanese characters are not garbled, or wrong, or wacky looking, they just plain aren't there.
This issue is being tracked here: https://github.com/mono/SkiaSharp/issues/232
The real issue is that Skia does not support character fallbacks. If the typeface does not contain the character, it will print a block. The GitHub issue has more information.
Thanks for looking into this. If I understood the resolution correctly, the caller has to arbitrarily choose some character to pass to the MatchCharacter method in order to obtain a typeface that supports it.
This isn't really a viable solution. In my case, I was trying to localize an application, so I have a culture name (say 'ja-JP'), and at the time I decide what typeface to use, I might not have any characters available. Now, I could defer selecting a typeface until I have an actual string, but then what - do I have to analyze every character in that string to determine what typeface is appropriate? The obvious workaround there is to just use some hardcoded character that I *think* will yield a typeface appropriate for the given culture, but that would imply that I have to construct some kind of table that cross-references each culture I want to support with some character that is guaranteed to yield the most ideal typeface for that culture. This sounds extremely hacky.
Did I miss something here?
I'll admit it does appear quite weird why Google chose to do it this way.
They wrote this: https://groups.google.com/forum/#!topic/skia-discuss/O4ClH4ziwVo
This is more likely to do with font fallback. In previous versions of Skia
font fallback (font chaining) was implicit. Basically, every font was
'extended' with all of the characters/glyphs in all of the fallback fonts.
This became unsupportable (as the number of glyphs became too large and
meant that fallback could not be controlled in a app locale dependent
manner). As a result, you'll need to use
SkTypeface::matchFamilyStyleCharacter to discover a font to use with
glyphs which cannot be mapped.
I am not quite sure how they would expect one to support a typeface for multiple cultures. But, since you already know what culture are working with, you can select the appropriate typeface - when 'ja-JP', then use font X, and if 'en', then use font Y.
But, probably the best thing would be to ask on that forum topic, and maybe present your use case. They made a decision, and they didn't really provide a way to properly draw text. I'll be watching that post, and if they point out any members that you should use, I'll make sure that they are bound.
I think you're right, the simplest and cleanest solution is to explicitly set a typeface based on the culture. I guess I was thinking about this with my Windows hat on; Windows resolves the ambient font based on the current culture, but that functionality doesn't seem to be quite as intrinsic on other platforms, hence this seemingly missing functionality.
Thanks again for looking into this.