Re: Correction of '_cairo_quartz_ucs4_to_index'.
Andrea Canciani <[email protected]>
| Newsgroups | gmane.comp.lib.cairo |
|---|---|
| Message-ID | <CAN_5=BAu_AOTFMNEe6TipNf=c0wBGuguYkjBeZEZvcQ9tNUGUA@mail.gmail.com> |
On Wed, Mar 15, 2017 at 12:14 PM, Clerk Ma <[email protected]> wrote: > I found that '_cairo_quartz_ucs4_to_index' in cairo-quartz-font.c was > broken > (ucs4 was cast to uint16_t/UniChar). A workable patch is here: > > static unsigned long > _cairo_quartz_ucs4_to_index (void *abstract_font, > uint32_t ucs4) > { > cairo_quartz_scaled_font_t *font = (cairo_quartz_scaled_font_t*) > abstract_font; > cairo_quartz_font_face_t *ffont = _cairo_quartz_scaled_to_face(font); > CGGlyph glyph[2]; > UniChar utf16[2]; > > size_t len = CFStringGetSurrogatePairForLongCharacter (ucs4, utf16) ? > 2 : 1; > CGFontGetGlyphsForUnicharsPtr (ffont->cgFont, utf16, glyph, len); > > return glyph[0]; > } > The lack of documentation on CGFontGetGlyphsForUnichars() (and its older implementation CGFontGetGlyphsForUnicodes()) left me wondering if it is actually able to handle surrogate pairs or not. I wrote a test (attached) that confirms they both work as expected :D Even on 10.4 you can get the glyphs for surrogate pairs using CGFontGetGlyphsForUnicodes() Unfortunately CFStringGetSurrogatePairForLongCharacter() is only available since 10.6. Luckily it is easy to refactor the UCS4 to UTF16 conversion from cairo-unicode.c into a separate function and reuse it :) I published a branch that should fix this at https://cgit.freedesktop.org/~ranma42/cairo/log/?h=quartz-ucs4-to-utf16 Can you confirm it fixes the issue? A better fix would probably involve CTFontGetGlyphsForCharacters(), but that is probably best suited for the (much desired, but not really a high priority in my todo-list) CoreText-based font backend. Andrea -- cairo mailing list [email protected] https://lists.cairographics.org/mailman/listinfo/cairo
minitest.c
(text/x-csrc, 1 KB)
/*
Assuming that the Sazanami-Hanazono·Mincho font is installed, this
test can be compiled and run as follows:
cc -Xlinker -framework -Xlinker ApplicationServices -undefined dynamic_lookup -Wall minitest.c
./a.out
*/
#include <ApplicationServices/ApplicationServices.h>
extern CGFontRef CGFontCreateWithName (const char *) __attribute__((weak_import));
extern void CGFontGetGlyphsForUnichars (CGFontRef, const UniChar[], const CGGlyph[], size_t) __attribute__((weak_import));
extern void CGFontGetGlyphsForUnicodes (CGFontRef, const UniChar[], const CGGlyph[], size_t) __attribute__((weak_import));
int main()
{
UniChar utf16[2] = { 0xD840, 0xDC40 };
CGGlyph glyphs[2];
CGFontRef cgFont = CGFontCreateWithName ("Sazanami-Hanazono Mincho");
printf ("font: %p\n", cgFont);
CGFontGetGlyphsForUnicodes (cgFont, utf16, glyphs, 2);
printf ("CGFontGetGlyphsForUnicodes: %04X %04X\n", glyphs[0], glyphs[1]);
CGFontGetGlyphsForUnichars (cgFont, utf16, glyphs, 2);
printf ("CGFontGetGlyphsForUnichars: %04X %04X\n", glyphs[0], glyphs[1]);
return 0;
}