Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/analyzer.c | 293 +++++++++++++++++++++-------------------- 1 file changed, 147 insertions(+), 146 deletions(-)
diff --git a/dlls/dwrite/analyzer.c b/dlls/dwrite/analyzer.c index 5547531b86..c6bcdfa4dd 100644 --- a/dlls/dwrite/analyzer.c +++ b/dlls/dwrite/analyzer.c @@ -36,8 +36,7 @@ extern const unsigned short wine_scripts_table[] DECLSPEC_HIDDEN;
struct dwritescript_properties { DWRITE_SCRIPT_PROPERTIES props; - UINT32 scripttag; /* OpenType script tag */ - UINT32 scriptalttag; /* Version 2 tag, 0 if not defined */ + UINT32 scripttags[3]; /* Maximum 2 script tags, 0-terminated. */ BOOL is_complex; const struct scriptshaping_ops *ops; }; @@ -49,145 +48,145 @@ static const struct dwritescript_properties dwritescripts_properties[Script_Last { /* Zzzz */ { 0x7a7a7a5a, 999, 15, 0x0020, 0, 0, 0, 0, 0, 0, 0 } }, { /* Zyyy */ { 0x7979795a, 998, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 } }, { /* Zinh */ { 0x686e695a, 994, 15, 0x0020, 1, 0, 0, 0, 0, 0, 0 } }, - { /* Arab */ { 0x62617241, 160, 8, 0x0640, 0, 1, 0, 0, 0, 1, 1 }, _OT('a','r','a','b'), 0, TRUE }, - { /* Armn */ { 0x6e6d7241, 230, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('a','r','m','n') }, - { /* Avst */ { 0x74737641, 134, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('a','v','s','t') }, - { /* Bali */ { 0x696c6142, 360, 15, 0x0020, 1, 0, 1, 0, 0, 0, 0 }, _OT('b','a','l','i') }, - { /* Bamu */ { 0x756d6142, 435, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, _OT('b','a','m','u') }, - { /* Batk */ { 0x6b746142, 365, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('b','a','t','k') }, - { /* Beng */ { 0x676e6542, 325, 15, 0x0020, 1, 1, 0, 0, 0, 1, 0 }, _OT('b','e','n','g'), _OT('b','n','g','2'), TRUE }, - { /* Bopo */ { 0x6f706f42, 285, 1, 0x0020, 0, 0, 1, 1, 0, 0, 0 }, _OT('b','o','p','o') }, - { /* Brah */ { 0x68617242, 300, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('b','r','a','h') }, - { /* Brai */ { 0x69617242, 570, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('b','r','a','i'), 0, TRUE }, - { /* Bugi */ { 0x69677542, 367, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('b','u','g','i') }, - { /* Buhd */ { 0x64687542, 372, 8, 0x0020, 0, 0, 1, 0, 0, 0, 0 }, _OT('b','u','h','d') }, - { /* Cans */ { 0x736e6143, 440, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('c','a','n','s'), 0, TRUE }, - { /* Cari */ { 0x69726143, 201, 1, 0x0020, 0, 0, 1, 0, 0, 0, 0 }, _OT('c','a','r','i') }, - { /* Cham */ { 0x6d616843, 358, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, _OT('c','h','a','m') }, - { /* Cher */ { 0x72656843, 445, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('c','h','e','r'), 0, TRUE }, - { /* Copt */ { 0x74706f43, 204, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('c','o','p','t') }, - { /* Xsux */ { 0x78757358, 20, 1, 0x0020, 0, 0, 1, 1, 0, 0, 0 }, _OT('x','s','u','x') }, - { /* Cprt */ { 0x74727043, 403, 1, 0x0020, 0, 0, 1, 0, 0, 0, 0 }, _OT('c','p','r','t') }, - { /* Cyrl */ { 0x6c727943, 220, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('c','y','r','l') }, - { /* Dsrt */ { 0x74727344, 250, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('d','s','r','t'), 0, TRUE }, - { /* Deva */ { 0x61766544, 315, 15, 0x0020, 1, 1, 0, 0, 0, 1, 0 }, _OT('d','e','v','a'), _OT('d','e','v','2'), TRUE }, - { /* Egyp */ { 0x70796745, 50, 1, 0x0020, 0, 0, 1, 1, 0, 0, 0 }, _OT('e','g','y','p') }, - { /* Ethi */ { 0x69687445, 430, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('e','t','h','i'), 0, TRUE }, - { /* Geor */ { 0x726f6547, 240, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('g','e','o','r') }, - { /* Glag */ { 0x67616c47, 225, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('g','l','a','g') }, - { /* Goth */ { 0x68746f47, 206, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('g','o','t','h') }, - { /* Grek */ { 0x6b657247, 200, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('g','r','e','k') }, - { /* Gujr */ { 0x726a7547, 320, 15, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, _OT('g','u','j','r'), _OT('g','j','r','2'), TRUE }, - { /* Guru */ { 0x75727547, 310, 15, 0x0020, 1, 1, 0, 0, 0, 1, 0 }, _OT('g','u','r','u'), _OT('g','u','r','2'), TRUE }, - { /* Hani */ { 0x696e6148, 500, 8, 0x0020, 0, 0, 1, 1, 0, 0, 0 }, _OT('h','a','n','i') }, - { /* Hang */ { 0x676e6148, 286, 8, 0x0020, 1, 1, 1, 1, 0, 0, 0 }, _OT('h','a','n','g'), 0, TRUE }, - { /* Hano */ { 0x6f6e6148, 371, 8, 0x0020, 0, 0, 1, 0, 0, 0, 0 }, _OT('h','a','n','o') }, - { /* Hebr */ { 0x72626548, 125, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, _OT('h','e','b','r'), 0, TRUE }, - { /* Hira */ { 0x61726948, 410, 8, 0x0020, 0, 0, 1, 1, 0, 0, 0 }, _OT('k','a','n','a') }, - { /* Armi */ { 0x696d7241, 124, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('a','r','m','i') }, - { /* Phli */ { 0x696c6850, 131, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('p','h','l','i') }, - { /* Prti */ { 0x69747250, 130, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('p','r','t','i') }, - { /* Java */ { 0x6176614a, 361, 15, 0x0020, 1, 0, 1, 0, 0, 0, 0 }, _OT('j','a','v','a') }, - { /* Kthi */ { 0x6968744b, 317, 15, 0x0020, 1, 1, 0, 0, 0, 1, 0 }, _OT('k','t','h','i') }, - { /* Knda */ { 0x61646e4b, 345, 15, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, _OT('k','n','d','a'), _OT('k','n','d','2'), TRUE }, - { /* Kana */ { 0x616e614b, 411, 8, 0x0020, 0, 0, 1, 1, 0, 0, 0 }, _OT('k','a','n','a') }, - { /* Kali */ { 0x696c614b, 357, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('k','a','l','i') }, - { /* Khar */ { 0x7261684b, 305, 15, 0x0020, 1, 0, 1, 0, 0, 0, 0 }, _OT('k','h','a','r') }, - { /* Khmr */ { 0x726d684b, 355, 8, 0x0020, 1, 0, 1, 0, 1, 0, 0 }, _OT('k','h','m','r'), 0, TRUE }, - { /* Laoo */ { 0x6f6f614c, 356, 8, 0x0020, 1, 0, 1, 0, 1, 0, 0 }, _OT('l','a','o',' '), 0, TRUE }, - { /* Latn */ { 0x6e74614c, 215, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('l','a','t','n'), 0, FALSE, &latn_shaping_ops }, - { /* Lepc */ { 0x6370654c, 335, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, _OT('l','e','p','c') }, - { /* Limb */ { 0x626d694c, 336, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, _OT('l','i','m','b') }, - { /* Linb */ { 0x626e694c, 401, 1, 0x0020, 0, 0, 1, 1, 0, 0, 0 }, _OT('l','i','n','b') }, - { /* Lisu */ { 0x7573694c, 399, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('l','i','s','u') }, - { /* Lyci */ { 0x6963794c, 202, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('l','y','c','i') }, - { /* Lydi */ { 0x6964794c, 116, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('l','y','d','i') }, - { /* Mlym */ { 0x6d796c4d, 347, 15, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, _OT('m','l','y','m'), _OT('m','l','m','2'), TRUE }, - { /* Mand */ { 0x646e614d, 140, 8, 0x0640, 0, 1, 0, 0, 0, 1, 1 }, _OT('m','a','n','d') }, - { /* Mtei */ { 0x6965744d, 337, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, _OT('m','t','e','i') }, - { /* Mong */ { 0x676e6f4d, 145, 8, 0x0020, 0, 1, 0, 0, 0, 1, 1 }, _OT('m','o','n','g'), 0, TRUE }, - { /* Mymr */ { 0x726d794d, 350, 15, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, _OT('m','y','m','r'), 0, TRUE }, - { /* Talu */ { 0x756c6154, 354, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, _OT('t','a','l','u'), 0, TRUE }, - { /* Nkoo */ { 0x6f6f6b4e, 165, 8, 0x0020, 0, 1, 0, 0, 0, 1, 1 }, _OT('n','k','o',' '), 0, TRUE }, - { /* Ogam */ { 0x6d61674f, 212, 1, 0x1680, 0, 1, 0, 0, 0, 1, 0 }, _OT('o','g','a','m'), 0, TRUE }, - { /* Olck */ { 0x6b636c4f, 261, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('o','l','c','k') }, - { /* Ital */ { 0x6c617449, 210, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('i','t','a','l') }, - { /* Xpeo */ { 0x6f657058, 30, 1, 0x0020, 0, 1, 1, 1, 0, 0, 0 }, _OT('x','p','e','o'), 0, TRUE }, - { /* Sarb */ { 0x62726153, 105, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('s','a','r','b') }, - { /* Orkh */ { 0x686b724f, 175, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('o','r','k','h') }, - { /* Orya */ { 0x6179724f, 327, 15, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, _OT('o','r','y','a'), _OT('o','r','y','2'), TRUE }, - { /* Osma */ { 0x616d734f, 260, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('o','s','m','a'), 0, TRUE }, - { /* Phag */ { 0x67616850, 331, 8, 0x0020, 0, 1, 0, 0, 0, 1, 1 }, _OT('p','h','a','g'), 0, TRUE }, - { /* Phnx */ { 0x786e6850, 115, 1, 0x0020, 0, 0, 1, 0, 0, 0, 0 }, _OT('p','h','n','x') }, - { /* Rjng */ { 0x676e6a52, 363, 8, 0x0020, 1, 0, 1, 0, 0, 0, 0 }, _OT('r','j','n','g') }, - { /* Runr */ { 0x726e7552, 211, 1, 0x0020, 0, 0, 1, 0, 0, 0, 0 }, _OT('r','u','n','r'), 0, TRUE }, - { /* Samr */ { 0x726d6153, 123, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('s','a','m','r') }, - { /* Saur */ { 0x72756153, 344, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, _OT('s','a','u','r') }, - { /* Shaw */ { 0x77616853, 281, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('s','h','a','w') }, - { /* Sinh */ { 0x686e6953, 348, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, _OT('s','i','n','h'), 0, TRUE }, - { /* Sund */ { 0x646e7553, 362, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, _OT('s','u','n','d') }, - { /* Sylo */ { 0x6f6c7953, 316, 8, 0x0020, 1, 1, 0, 0, 0, 1, 0 }, _OT('s','y','l','o') }, - { /* Syrc */ { 0x63727953, 135, 8, 0x0640, 0, 1, 0, 0, 0, 1, 1 }, _OT('s','y','r','c'), 0, TRUE }, - { /* Tglg */ { 0x676c6754, 370, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('t','g','l','g') }, - { /* Tagb */ { 0x62676154, 373, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('t','a','g','b') }, - { /* Tale */ { 0x656c6154, 353, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('t','a','l','e'), 0, TRUE }, - { /* Lana */ { 0x616e614c, 351, 8, 0x0020, 1, 0, 1, 0, 0, 0, 0 }, _OT('l','a','n','a') }, - { /* Tavt */ { 0x74766154, 359, 8, 0x0020, 1, 0, 1, 0, 1, 0, 0 }, _OT('t','a','v','t') }, - { /* Taml */ { 0x6c6d6154, 346, 15, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, _OT('t','a','m','l'), _OT('t','m','l','2'), TRUE }, - { /* Telu */ { 0x756c6554, 340, 15, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, _OT('t','e','l','u'), _OT('t','e','l','2'), TRUE }, - { /* Thaa */ { 0x61616854, 170, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, _OT('t','h','a','a'), 0, TRUE }, - { /* Thai */ { 0x69616854, 352, 8, 0x0020, 1, 0, 1, 0, 1, 0, 0 }, _OT('t','h','a','i'), 0, TRUE }, - { /* Tibt */ { 0x74626954, 330, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, _OT('t','i','b','t'), 0, TRUE }, - { /* Tfng */ { 0x676e6654, 120, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, _OT('t','f','n','g'), 0, TRUE }, - { /* Ugar */ { 0x72616755, 40, 1, 0x0020, 0, 0, 1, 1, 0, 0, 0 }, _OT('u','g','a','r') }, - { /* Vaii */ { 0x69696156, 470, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('v','a','i',' '), 0, TRUE }, - { /* Yiii */ { 0x69696959, 460, 1, 0x0020, 0, 0, 1, 1, 0, 0, 0 }, _OT('y','i',' ',' '), 0, TRUE }, - { /* Cakm */ { 0x6d6b6143, 349, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, _OT('c','a','k','m') }, - { /* Merc */ { 0x6372654d, 101, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('m','e','r','c') }, - { /* Mero */ { 0x6f72654d, 100, 1, 0x0020, 0, 1, 1, 1, 0, 0, 0 }, _OT('m','e','r','o') }, - { /* Plrd */ { 0x64726c50, 282, 8, 0x0020, 1, 0, 1, 0, 0, 0, 0 }, _OT('p','l','r','d') }, - { /* Shrd */ { 0x64726853, 319, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, _OT('s','h','r','d') }, - { /* Sora */ { 0x61726f53, 398, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, _OT('s','o','r','a') }, - { /* Takr */ { 0x726b6154, 321, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, _OT('t','a','k','r') }, - { /* Bass */ { 0x73736142, 259, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('b','a','s','s') }, - { /* Aghb */ { 0x62686741, 239, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('a','g','h','b') }, - { /* Dupl */ { 0x6c707544, 755, 8, 0x0020, 0, 1, 0, 0, 0, 1, 1 }, _OT('d','u','p','l') }, - { /* Elba */ { 0x61626c45, 226, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('e','l','b','a') }, - { /* Gran */ { 0x6e617247, 343, 15, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, _OT('g','r','a','n') }, - { /* Khoj */ { 0x6a6f684b, 322, 15, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, _OT('k','h','o','j') }, - { /* Sind */ { 0x646e6953, 318, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, _OT('s','i','n','d') }, - { /* Lina */ { 0x616e694c, 400, 1, 0x0020, 0, 0, 1, 1, 0, 0, 0 }, _OT('l','i','n','a') }, - { /* Mahj */ { 0x6a68614d, 314, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('m','a','h','j') }, - { /* Mani */ { 0x696e614d, 139, 8, 0x0640, 0, 1, 0, 0, 0, 1, 1 }, _OT('m','a','n','i') }, - { /* Mend */ { 0x646e654d, 438, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('m','e','n','d') }, - { /* Modi */ { 0x69646f4d, 324, 15, 0x0020, 1, 1, 0, 0, 0, 1, 0 }, _OT('m','o','d','i') }, - { /* Mroo */ { 0x6f6f724d, 199, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('m','r','o','o') }, - { /* Nbat */ { 0x7461624e, 159, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, _OT('n','b','a','t') }, - { /* Narb */ { 0x6272614e, 106, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('n','a','r','b') }, - { /* Perm */ { 0x6d726550, 227, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('p','e','r','m') }, - { /* Hmng */ { 0x676e6d48, 450, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('h','m','n','g') }, - { /* Palm */ { 0x6d6c6150, 126, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, _OT('p','a','l','m') }, - { /* Pauc */ { 0x63756150, 263, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('p','a','u','c') }, - { /* Phlp */ { 0x706c6850, 132, 8, 0x0640, 0, 1, 0, 0, 0, 1, 1 }, _OT('p','h','l','p') }, - { /* Sidd */ { 0x64646953, 302, 8, 0x0020, 1, 0, 1, 1, 0, 0, 0 }, _OT('s','i','d','d') }, - { /* Tirh */ { 0x68726954, 326, 15, 0x0020, 1, 1, 0, 0, 0, 1, 0 }, _OT('t','i','r','h') }, - { /* Wara */ { 0x61726157, 262, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('w','a','r','a') }, - { /* Adlm */ { 0x6d6c6441, 166, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('a','d','l','m') }, - { /* Ahom */ { 0x6d6f6841, 338, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('a','h','o','m') }, - { /* Hluw */ { 0x77756c48, 80, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('h','l','u','w') }, - { /* Bhks */ { 0x736b6842, 334, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('b','h','k','s') }, - { /* Hatr */ { 0x72746148, 127, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('h','a','t','r') }, - { /* Marc */ { 0x6372614d, 332, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('m','a','r','c') }, - { /* Mult */ { 0x746c754d, 323, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('m','u','l','t') }, - { /* Newa */ { 0x6177654e, 333, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('n','e','w','a') }, - { /* Hung */ { 0x676e7548, 176, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('h','u','n','g') }, - { /* Osge */ { 0x6567734f, 219, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('o','s','g','e') }, - { /* Sgnw */ { 0x776e6753, 95, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('s','g','n','w') }, - { /* Tang */ { 0x676e6154, 520, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('t','a','n','g') }, - { /* Gonm */ { 0x6d6e6f47, 313, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('g','o','n','m') }, - { /* Nshu */ { 0x7568734e, 499, 1, 0x0020, 0, 0, 1, 1, 0, 0, 0 }, _OT('n','s','h','u') }, - { /* Soyo */ { 0x6f796f53, 329, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('s','o','y','o') }, - { /* Zanb */ { 0x626e615a, 339, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, _OT('z','a','n','b') }, + { /* Arab */ { 0x62617241, 160, 8, 0x0640, 0, 1, 0, 0, 0, 1, 1 }, { _OT('a','r','a','b') }, TRUE }, + { /* Armn */ { 0x6e6d7241, 230, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('a','r','m','n') } }, + { /* Avst */ { 0x74737641, 134, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('a','v','s','t') } }, + { /* Bali */ { 0x696c6142, 360, 15, 0x0020, 1, 0, 1, 0, 0, 0, 0 }, { _OT('b','a','l','i') } }, + { /* Bamu */ { 0x756d6142, 435, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, { _OT('b','a','m','u') } }, + { /* Batk */ { 0x6b746142, 365, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('b','a','t','k') } }, + { /* Beng */ { 0x676e6542, 325, 15, 0x0020, 1, 1, 0, 0, 0, 1, 0 }, { _OT('b','n','g','2'), _OT('b','e','n','g') }, TRUE }, + { /* Bopo */ { 0x6f706f42, 285, 1, 0x0020, 0, 0, 1, 1, 0, 0, 0 }, { _OT('b','o','p','o') } }, + { /* Brah */ { 0x68617242, 300, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('b','r','a','h') } }, + { /* Brai */ { 0x69617242, 570, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('b','r','a','i') }, TRUE }, + { /* Bugi */ { 0x69677542, 367, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('b','u','g','i') } }, + { /* Buhd */ { 0x64687542, 372, 8, 0x0020, 0, 0, 1, 0, 0, 0, 0 }, { _OT('b','u','h','d') } }, + { /* Cans */ { 0x736e6143, 440, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('c','a','n','s') }, TRUE }, + { /* Cari */ { 0x69726143, 201, 1, 0x0020, 0, 0, 1, 0, 0, 0, 0 }, { _OT('c','a','r','i') } }, + { /* Cham */ { 0x6d616843, 358, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, { _OT('c','h','a','m') } }, + { /* Cher */ { 0x72656843, 445, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('c','h','e','r') }, TRUE }, + { /* Copt */ { 0x74706f43, 204, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('c','o','p','t') } }, + { /* Xsux */ { 0x78757358, 20, 1, 0x0020, 0, 0, 1, 1, 0, 0, 0 }, { _OT('x','s','u','x') } }, + { /* Cprt */ { 0x74727043, 403, 1, 0x0020, 0, 0, 1, 0, 0, 0, 0 }, { _OT('c','p','r','t') } }, + { /* Cyrl */ { 0x6c727943, 220, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('c','y','r','l') } }, + { /* Dsrt */ { 0x74727344, 250, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('d','s','r','t') }, TRUE }, + { /* Deva */ { 0x61766544, 315, 15, 0x0020, 1, 1, 0, 0, 0, 1, 0 }, { _OT('d','e','v','2'), _OT('d','e','v','a') }, TRUE }, + { /* Egyp */ { 0x70796745, 50, 1, 0x0020, 0, 0, 1, 1, 0, 0, 0 }, { _OT('e','g','y','p') } }, + { /* Ethi */ { 0x69687445, 430, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('e','t','h','i') }, TRUE }, + { /* Geor */ { 0x726f6547, 240, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('g','e','o','r') } }, + { /* Glag */ { 0x67616c47, 225, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('g','l','a','g') } }, + { /* Goth */ { 0x68746f47, 206, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('g','o','t','h') } }, + { /* Grek */ { 0x6b657247, 200, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('g','r','e','k') } }, + { /* Gujr */ { 0x726a7547, 320, 15, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, { _OT('g','j','r','2'), _OT('g','u','j','r') }, TRUE }, + { /* Guru */ { 0x75727547, 310, 15, 0x0020, 1, 1, 0, 0, 0, 1, 0 }, { _OT('g','u','r','2'), _OT('g','u','r','u') }, TRUE }, + { /* Hani */ { 0x696e6148, 500, 8, 0x0020, 0, 0, 1, 1, 0, 0, 0 }, { _OT('h','a','n','i') } }, + { /* Hang */ { 0x676e6148, 286, 8, 0x0020, 1, 1, 1, 1, 0, 0, 0 }, { _OT('h','a','n','g') }, TRUE }, + { /* Hano */ { 0x6f6e6148, 371, 8, 0x0020, 0, 0, 1, 0, 0, 0, 0 }, { _OT('h','a','n','o') } }, + { /* Hebr */ { 0x72626548, 125, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, { _OT('h','e','b','r') }, TRUE }, + { /* Hira */ { 0x61726948, 410, 8, 0x0020, 0, 0, 1, 1, 0, 0, 0 }, { _OT('k','a','n','a') } }, + { /* Armi */ { 0x696d7241, 124, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('a','r','m','i') } }, + { /* Phli */ { 0x696c6850, 131, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('p','h','l','i') } }, + { /* Prti */ { 0x69747250, 130, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('p','r','t','i') } }, + { /* Java */ { 0x6176614a, 361, 15, 0x0020, 1, 0, 1, 0, 0, 0, 0 }, { _OT('j','a','v','a') } }, + { /* Kthi */ { 0x6968744b, 317, 15, 0x0020, 1, 1, 0, 0, 0, 1, 0 }, { _OT('k','t','h','i') } }, + { /* Knda */ { 0x61646e4b, 345, 15, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, { _OT('k','n','d','2'), _OT('k','n','d','a') }, TRUE }, + { /* Kana */ { 0x616e614b, 411, 8, 0x0020, 0, 0, 1, 1, 0, 0, 0 }, { _OT('k','a','n','a') } }, + { /* Kali */ { 0x696c614b, 357, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('k','a','l','i') } }, + { /* Khar */ { 0x7261684b, 305, 15, 0x0020, 1, 0, 1, 0, 0, 0, 0 }, { _OT('k','h','a','r') } }, + { /* Khmr */ { 0x726d684b, 355, 8, 0x0020, 1, 0, 1, 0, 1, 0, 0 }, { _OT('k','h','m','r') }, TRUE }, + { /* Laoo */ { 0x6f6f614c, 356, 8, 0x0020, 1, 0, 1, 0, 1, 0, 0 }, { _OT('l','a','o',' ') }, TRUE }, + { /* Latn */ { 0x6e74614c, 215, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('l','a','t','n') }, FALSE, &latn_shaping_ops }, + { /* Lepc */ { 0x6370654c, 335, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, { _OT('l','e','p','c') } }, + { /* Limb */ { 0x626d694c, 336, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, { _OT('l','i','m','b') } }, + { /* Linb */ { 0x626e694c, 401, 1, 0x0020, 0, 0, 1, 1, 0, 0, 0 }, { _OT('l','i','n','b') } }, + { /* Lisu */ { 0x7573694c, 399, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('l','i','s','u') } }, + { /* Lyci */ { 0x6963794c, 202, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('l','y','c','i') } }, + { /* Lydi */ { 0x6964794c, 116, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('l','y','d','i') } }, + { /* Mlym */ { 0x6d796c4d, 347, 15, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, { _OT('m','l','m','2'), _OT('m','l','y','m') }, TRUE }, + { /* Mand */ { 0x646e614d, 140, 8, 0x0640, 0, 1, 0, 0, 0, 1, 1 }, { _OT('m','a','n','d') } }, + { /* Mtei */ { 0x6965744d, 337, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, { _OT('m','t','e','i') } }, + { /* Mong */ { 0x676e6f4d, 145, 8, 0x0020, 0, 1, 0, 0, 0, 1, 1 }, { _OT('m','o','n','g') }, TRUE }, + { /* Mymr */ { 0x726d794d, 350, 15, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, { _OT('m','y','m','r') }, TRUE }, + { /* Talu */ { 0x756c6154, 354, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, { _OT('t','a','l','u') }, TRUE }, + { /* Nkoo */ { 0x6f6f6b4e, 165, 8, 0x0020, 0, 1, 0, 0, 0, 1, 1 }, { _OT('n','k','o',' ') }, TRUE }, + { /* Ogam */ { 0x6d61674f, 212, 1, 0x1680, 0, 1, 0, 0, 0, 1, 0 }, { _OT('o','g','a','m') }, TRUE }, + { /* Olck */ { 0x6b636c4f, 261, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('o','l','c','k') } }, + { /* Ital */ { 0x6c617449, 210, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('i','t','a','l') } }, + { /* Xpeo */ { 0x6f657058, 30, 1, 0x0020, 0, 1, 1, 1, 0, 0, 0 }, { _OT('x','p','e','o') }, TRUE }, + { /* Sarb */ { 0x62726153, 105, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('s','a','r','b') } }, + { /* Orkh */ { 0x686b724f, 175, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('o','r','k','h') } }, + { /* Orya */ { 0x6179724f, 327, 15, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, { _OT('o','r','y','2'), _OT('o','r','y','a') }, TRUE }, + { /* Osma */ { 0x616d734f, 260, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('o','s','m','a') }, TRUE }, + { /* Phag */ { 0x67616850, 331, 8, 0x0020, 0, 1, 0, 0, 0, 1, 1 }, { _OT('p','h','a','g') }, TRUE }, + { /* Phnx */ { 0x786e6850, 115, 1, 0x0020, 0, 0, 1, 0, 0, 0, 0 }, { _OT('p','h','n','x') } }, + { /* Rjng */ { 0x676e6a52, 363, 8, 0x0020, 1, 0, 1, 0, 0, 0, 0 }, { _OT('r','j','n','g') } }, + { /* Runr */ { 0x726e7552, 211, 1, 0x0020, 0, 0, 1, 0, 0, 0, 0 }, { _OT('r','u','n','r') }, TRUE }, + { /* Samr */ { 0x726d6153, 123, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('s','a','m','r') } }, + { /* Saur */ { 0x72756153, 344, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, { _OT('s','a','u','r') } }, + { /* Shaw */ { 0x77616853, 281, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('s','h','a','w') } }, + { /* Sinh */ { 0x686e6953, 348, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, { _OT('s','i','n','h') }, TRUE }, + { /* Sund */ { 0x646e7553, 362, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, { _OT('s','u','n','d') } }, + { /* Sylo */ { 0x6f6c7953, 316, 8, 0x0020, 1, 1, 0, 0, 0, 1, 0 }, { _OT('s','y','l','o') } }, + { /* Syrc */ { 0x63727953, 135, 8, 0x0640, 0, 1, 0, 0, 0, 1, 1 }, { _OT('s','y','r','c') }, TRUE }, + { /* Tglg */ { 0x676c6754, 370, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('t','g','l','g') } }, + { /* Tagb */ { 0x62676154, 373, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('t','a','g','b') } }, + { /* Tale */ { 0x656c6154, 353, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('t','a','l','e') }, TRUE }, + { /* Lana */ { 0x616e614c, 351, 8, 0x0020, 1, 0, 1, 0, 0, 0, 0 }, { _OT('l','a','n','a') } }, + { /* Tavt */ { 0x74766154, 359, 8, 0x0020, 1, 0, 1, 0, 1, 0, 0 }, { _OT('t','a','v','t') } }, + { /* Taml */ { 0x6c6d6154, 346, 15, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, { _OT('t','m','l','2'), _OT('t','a','m','l') }, TRUE }, + { /* Telu */ { 0x756c6554, 340, 15, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, { _OT('t','e','l','2'), _OT('t','e','l','u') }, TRUE }, + { /* Thaa */ { 0x61616854, 170, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, { _OT('t','h','a','a') }, TRUE }, + { /* Thai */ { 0x69616854, 352, 8, 0x0020, 1, 0, 1, 0, 1, 0, 0 }, { _OT('t','h','a','i') }, TRUE }, + { /* Tibt */ { 0x74626954, 330, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, { _OT('t','i','b','t') }, TRUE }, + { /* Tfng */ { 0x676e6654, 120, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, { _OT('t','f','n','g') }, TRUE }, + { /* Ugar */ { 0x72616755, 40, 1, 0x0020, 0, 0, 1, 1, 0, 0, 0 }, { _OT('u','g','a','r') } }, + { /* Vaii */ { 0x69696156, 470, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('v','a','i',' ') }, TRUE }, + { /* Yiii */ { 0x69696959, 460, 1, 0x0020, 0, 0, 1, 1, 0, 0, 0 }, { _OT('y','i',' ',' ') }, TRUE }, + { /* Cakm */ { 0x6d6b6143, 349, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, { _OT('c','a','k','m') } }, + { /* Merc */ { 0x6372654d, 101, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('m','e','r','c') } }, + { /* Mero */ { 0x6f72654d, 100, 1, 0x0020, 0, 1, 1, 1, 0, 0, 0 }, { _OT('m','e','r','o') } }, + { /* Plrd */ { 0x64726c50, 282, 8, 0x0020, 1, 0, 1, 0, 0, 0, 0 }, { _OT('p','l','r','d') } }, + { /* Shrd */ { 0x64726853, 319, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, { _OT('s','h','r','d') } }, + { /* Sora */ { 0x61726f53, 398, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, { _OT('s','o','r','a') } }, + { /* Takr */ { 0x726b6154, 321, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, { _OT('t','a','k','r') } }, + { /* Bass */ { 0x73736142, 259, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('b','a','s','s') } }, + { /* Aghb */ { 0x62686741, 239, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('a','g','h','b') } }, + { /* Dupl */ { 0x6c707544, 755, 8, 0x0020, 0, 1, 0, 0, 0, 1, 1 }, { _OT('d','u','p','l') } }, + { /* Elba */ { 0x61626c45, 226, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('e','l','b','a') } }, + { /* Gran */ { 0x6e617247, 343, 15, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, { _OT('g','r','a','n') } }, + { /* Khoj */ { 0x6a6f684b, 322, 15, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, { _OT('k','h','o','j') } }, + { /* Sind */ { 0x646e6953, 318, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, { _OT('s','i','n','d') } }, + { /* Lina */ { 0x616e694c, 400, 1, 0x0020, 0, 0, 1, 1, 0, 0, 0 }, { _OT('l','i','n','a') } }, + { /* Mahj */ { 0x6a68614d, 314, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('m','a','h','j') } }, + { /* Mani */ { 0x696e614d, 139, 8, 0x0640, 0, 1, 0, 0, 0, 1, 1 }, { _OT('m','a','n','i') } }, + { /* Mend */ { 0x646e654d, 438, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('m','e','n','d') } }, + { /* Modi */ { 0x69646f4d, 324, 15, 0x0020, 1, 1, 0, 0, 0, 1, 0 }, { _OT('m','o','d','i') } }, + { /* Mroo */ { 0x6f6f724d, 199, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('m','r','o','o') } }, + { /* Nbat */ { 0x7461624e, 159, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, { _OT('n','b','a','t') } }, + { /* Narb */ { 0x6272614e, 106, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('n','a','r','b') } }, + { /* Perm */ { 0x6d726550, 227, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('p','e','r','m') } }, + { /* Hmng */ { 0x676e6d48, 450, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('h','m','n','g') } }, + { /* Palm */ { 0x6d6c6150, 126, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, { _OT('p','a','l','m') } }, + { /* Pauc */ { 0x63756150, 263, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('p','a','u','c') } }, + { /* Phlp */ { 0x706c6850, 132, 8, 0x0640, 0, 1, 0, 0, 0, 1, 1 }, { _OT('p','h','l','p') } }, + { /* Sidd */ { 0x64646953, 302, 8, 0x0020, 1, 0, 1, 1, 0, 0, 0 }, { _OT('s','i','d','d') } }, + { /* Tirh */ { 0x68726954, 326, 15, 0x0020, 1, 1, 0, 0, 0, 1, 0 }, { _OT('t','i','r','h') } }, + { /* Wara */ { 0x61726157, 262, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('w','a','r','a') } }, + { /* Adlm */ { 0x6d6c6441, 166, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('a','d','l','m') } }, + { /* Ahom */ { 0x6d6f6841, 338, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('a','h','o','m') } }, + { /* Hluw */ { 0x77756c48, 80, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('h','l','u','w') } }, + { /* Bhks */ { 0x736b6842, 334, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('b','h','k','s') } }, + { /* Hatr */ { 0x72746148, 127, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('h','a','t','r') } }, + { /* Marc */ { 0x6372614d, 332, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('m','a','r','c') } }, + { /* Mult */ { 0x746c754d, 323, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('m','u','l','t') } }, + { /* Newa */ { 0x6177654e, 333, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('n','e','w','a') } }, + { /* Hung */ { 0x676e7548, 176, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('h','u','n','g') } }, + { /* Osge */ { 0x6567734f, 219, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('o','s','g','e') } }, + { /* Sgnw */ { 0x776e6753, 95, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('s','g','n','w') } }, + { /* Tang */ { 0x676e6154, 520, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('t','a','n','g') } }, + { /* Gonm */ { 0x6d6e6f47, 313, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('g','o','n','m') } }, + { /* Nshu */ { 0x7568734e, 499, 1, 0x0020, 0, 0, 1, 1, 0, 0, 0 }, { _OT('n','s','h','u') } }, + { /* Soyo */ { 0x6f796f53, 329, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('s','o','y','o') } }, + { /* Zanb */ { 0x626e615a, 339, 8, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('z','a','n','b') } }, }; #undef _OT
@@ -1812,6 +1811,7 @@ static HRESULT WINAPI dwritetextanalyzer2_GetTypographicFeatures(IDWriteTextAnal UINT32 max_tagcount, UINT32 *actual_tagcount, DWRITE_FONT_FEATURE_TAG *tags) { const struct dwritescript_properties *props; + const DWORD *scripts; HRESULT hr = S_OK; UINT32 language;
@@ -1825,11 +1825,12 @@ static HRESULT WINAPI dwritetextanalyzer2_GetTypographicFeatures(IDWriteTextAnal props = &dwritescripts_properties[sa.script]; *actual_tagcount = 0;
- if (props->scriptalttag) - hr = opentype_get_typographic_features(fontface, props->scriptalttag, language, max_tagcount, actual_tagcount, tags); - - if (*actual_tagcount == 0) - hr = opentype_get_typographic_features(fontface, props->scripttag, language, max_tagcount, actual_tagcount, tags); + scripts = props->scripttags; + while (*scripts && !*actual_tagcount) + { + hr = opentype_get_typographic_features(fontface, *scripts, language, max_tagcount, actual_tagcount, tags); + scripts++; + }
return hr; };
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/analyzer.c | 15 +++++++-------- dlls/dwrite/dwrite_private.h | 5 +++++ dlls/dwrite/font.c | 5 ----- 3 files changed, 12 insertions(+), 13 deletions(-)
diff --git a/dlls/dwrite/analyzer.c b/dlls/dwrite/analyzer.c index c6bcdfa4dd..69e6b11587 100644 --- a/dlls/dwrite/analyzer.c +++ b/dlls/dwrite/analyzer.c @@ -192,8 +192,7 @@ static const struct dwritescript_properties dwritescripts_properties[Script_Last
const char *debugstr_sa_script(UINT16 script) { - return script < Script_LastId ? debugstr_an((char*)&dwritescripts_properties[script].props.isoScriptCode, 4): - "undefined"; + return script < Script_LastId ? debugstr_tag(dwritescripts_properties[script].props.isoScriptCode) : "undefined"; }
/* system font falback configuration */ @@ -1054,7 +1053,7 @@ done:
static UINT32 get_opentype_language(const WCHAR *locale) { - UINT32 language = DWRITE_FONT_FEATURE_TAG_DEFAULT; + UINT32 language = DWRITE_MAKE_OPENTYPE_TAG('d','f','l','t');
if (locale) { WCHAR tag[5]; @@ -1145,7 +1144,7 @@ static void analyzer_dump_user_features(DWRITE_TYPOGRAPHIC_FEATURES const **feat for (i = 0, start = 0; i < feature_ranges; start += feature_range_lengths[i++]) { TRACE("feature range [%u,%u)\n", start, start + feature_range_lengths[i]); for (j = 0; j < features[i]->featureCount; j++) - TRACE("feature %s, parameter %u\n", debugstr_an((char *)&features[i]->features[j].nameTag, 4), + TRACE("feature %s, parameter %u\n", debugstr_tag(features[i]->features[j].nameTag), features[i]->features[j].parameter); } } @@ -1836,11 +1835,11 @@ static HRESULT WINAPI dwritetextanalyzer2_GetTypographicFeatures(IDWriteTextAnal };
static HRESULT WINAPI dwritetextanalyzer2_CheckTypographicFeature(IDWriteTextAnalyzer2 *iface, - IDWriteFontFace *face, DWRITE_SCRIPT_ANALYSIS sa, const WCHAR *localeName, - DWRITE_FONT_FEATURE_TAG feature, UINT32 glyph_count, const UINT16 *indices, UINT8 *feature_applies) + IDWriteFontFace *face, DWRITE_SCRIPT_ANALYSIS sa, const WCHAR *locale, DWRITE_FONT_FEATURE_TAG feature, + UINT32 glyph_count, const UINT16 *glyphs, UINT8 *feature_applies) { - FIXME("(%p %u %s %x %u %p %p): stub\n", face, sa.script, debugstr_w(localeName), feature, glyph_count, indices, - feature_applies); + FIXME("(%p %u %s %s %u %p %p): stub\n", face, sa.script, debugstr_w(locale), debugstr_tag(feature), glyph_count, + glyphs, feature_applies); return E_NOTIMPL; }
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index a19380a636..b8fb25026f 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -76,6 +76,11 @@ static inline const char *debugstr_matrix(const DWRITE_MATRIX *m) m->dx, m->dy); }
+static inline const char *debugstr_tag(DWORD tag) +{ + return debugstr_an((char *)&tag, 4); +} + const char *debugstr_sa_script(UINT16) DECLSPEC_HIDDEN;
static inline unsigned short get_table_entry(const unsigned short *table, WCHAR ch) diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 97b99f9775..c657eeb205 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -320,11 +320,6 @@ static inline struct dwrite_fontfacereference *impl_from_IDWriteFontFaceReferenc return CONTAINING_RECORD(iface, struct dwrite_fontfacereference, IDWriteFontFaceReference_iface); }
-static inline const char *debugstr_tag(UINT32 tag) -{ - return debugstr_an((char*)&tag, 4); -} - static HRESULT get_cached_glyph_metrics(struct dwrite_fontface *fontface, UINT16 glyph, DWRITE_GLYPH_METRICS *metrics) { static const DWRITE_GLYPH_METRICS nil;
This should be implemented as a part of shaping pass.
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/analyzer.c | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-)
diff --git a/dlls/dwrite/analyzer.c b/dlls/dwrite/analyzer.c index 69e6b11587..a1d9f25ad1 100644 --- a/dlls/dwrite/analyzer.c +++ b/dlls/dwrite/analyzer.c @@ -1161,9 +1161,8 @@ static HRESULT WINAPI dwritetextanalyzer_GetGlyphs(IDWriteTextAnalyzer2 *iface, DWRITE_NUMBER_SUBSTITUTION_METHOD method; struct scriptshaping_context context; struct scriptshaping_cache *cache = NULL; - BOOL update_cluster, need_vertical; WCHAR digits[NATIVE_DIGITS_LEN]; - IDWriteFontFace1 *fontface1; + BOOL update_cluster; WCHAR *string; UINT32 i, g; HRESULT hr = S_OK; @@ -1225,12 +1224,6 @@ static HRESULT WINAPI dwritetextanalyzer_GetGlyphs(IDWriteTextAnalyzer2 *iface, glyph_props[i].reserved = 0; }
- hr = IDWriteFontFace_QueryInterface(fontface, &IID_IDWriteFontFace1, (void**)&fontface1); - if (FAILED(hr)) - WARN("failed to get IDWriteFontFace1\n"); - - need_vertical = is_sideways && fontface1 && IDWriteFontFace1_HasVerticalGlyphVariants(fontface1); - for (i = 0, g = 0, update_cluster = FALSE; i < length; i++) { UINT32 codepoint;
@@ -1245,14 +1238,6 @@ static HRESULT WINAPI dwritetextanalyzer_GetGlyphs(IDWriteTextAnalyzer2 *iface, if (FAILED(hr)) goto done;
- if (need_vertical) { - UINT16 vertical; - - hr = IDWriteFontFace1_GetVerticalGlyphVariants(fontface1, 1, &glyph_indices[g], &vertical); - if (hr == S_OK) - glyph_indices[g] = vertical; - } - g++; } else { @@ -1294,8 +1279,6 @@ static HRESULT WINAPI dwritetextanalyzer_GetGlyphs(IDWriteTextAnalyzer2 *iface, hr = default_shaping_ops.set_text_glyphs_props(&context, clustermap, glyph_indices, *actual_glyph_count, text_props, glyph_props);
done: - if (fontface1) - IDWriteFontFace1_Release(fontface1); release_scriptshaping_cache(cache); heap_free(string);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/dwrite_private.h | 9 ++++--- dlls/dwrite/font.c | 4 +-- dlls/dwrite/freetype.c | 4 +-- dlls/dwrite/layout.c | 51 +++++++++++++++++++++--------------- 4 files changed, 39 insertions(+), 29 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index b8fb25026f..6ee59cfd02 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -252,13 +252,14 @@ extern HRESULT bidi_computelevels(const WCHAR*,UINT32,UINT8,UINT8*,UINT8*) DECLS extern WCHAR bidi_get_mirrored_char(WCHAR) DECLSPEC_HIDDEN;
/* FreeType integration */ -struct dwrite_glyphbitmap { +struct dwrite_glyphbitmap +{ IDWriteFontFace4 *fontface; DWORD simulations; - FLOAT emsize; + float emsize; BOOL nohint; BOOL aliased; - UINT16 index; + UINT16 glyph; INT pitch; RECT bbox; BYTE *buf; @@ -276,7 +277,7 @@ extern UINT16 freetype_get_glyphcount(IDWriteFontFace4*) DECLSPEC_HIDDEN; extern void freetype_get_glyphs(IDWriteFontFace4*,INT,UINT32 const*,UINT32,UINT16*) DECLSPEC_HIDDEN; extern BOOL freetype_has_kerning_pairs(IDWriteFontFace4*) DECLSPEC_HIDDEN; extern INT32 freetype_get_kerning_pair_adjustment(IDWriteFontFace4*,UINT16,UINT16) DECLSPEC_HIDDEN; -extern void freetype_get_glyph_bbox(struct dwrite_glyphbitmap*) DECLSPEC_HIDDEN; +extern void freetype_get_glyph_bbox(struct dwrite_glyphbitmap *bitmap_desc) DECLSPEC_HIDDEN; extern BOOL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap*) DECLSPEC_HIDDEN; extern INT freetype_get_charmap_index(IDWriteFontFace4*,BOOL*) DECLSPEC_HIDDEN; extern INT32 freetype_get_glyph_advance(IDWriteFontFace4*,FLOAT,UINT16,DWRITE_MEASURING_MODE,BOOL*) DECLSPEC_HIDDEN; diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index c657eeb205..b10096de20 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -5060,7 +5060,7 @@ static void glyphrunanalysis_get_texturebounds(struct dwrite_glyphrunanalysis *a RECT *bbox = &glyph_bitmap.bbox; UINT32 bitmap_size;
- glyph_bitmap.index = analysis->run.glyphIndices[i]; + glyph_bitmap.glyph = analysis->run.glyphIndices[i]; freetype_get_glyph_bbox(&glyph_bitmap);
bitmap_size = get_glyph_bitmap_pitch(analysis->rendering_mode, bbox->right - bbox->left) * @@ -5161,7 +5161,7 @@ static HRESULT glyphrunanalysis_render(struct dwrite_glyphrunanalysis *analysis) int x, y, width, height; BOOL is_1bpp;
- glyph_bitmap.index = analysis->run.glyphIndices[i]; + glyph_bitmap.glyph = analysis->run.glyphIndices[i]; freetype_get_glyph_bbox(&glyph_bitmap);
if (IsRectEmpty(bbox)) diff --git a/dlls/dwrite/freetype.c b/dlls/dwrite/freetype.c index ffdd8a8f1e..d3036537f0 100644 --- a/dlls/dwrite/freetype.c +++ b/dlls/dwrite/freetype.c @@ -686,7 +686,7 @@ void freetype_get_glyph_bbox(struct dwrite_glyphbitmap *bitmap) imagetype.height = bitmap->emsize; imagetype.flags = needs_transform ? FT_LOAD_NO_BITMAP : FT_LOAD_DEFAULT;
- if (pFTC_ImageCache_Lookup(image_cache, &imagetype, bitmap->index, &glyph, NULL) == 0) { + if (pFTC_ImageCache_Lookup(image_cache, &imagetype, bitmap->glyph, &glyph, NULL) == 0) { if (needs_transform) { FT_Glyph glyph_copy;
@@ -844,7 +844,7 @@ BOOL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap) imagetype.height = bitmap->emsize; imagetype.flags = needs_transform ? FT_LOAD_NO_BITMAP : FT_LOAD_DEFAULT;
- if (pFTC_ImageCache_Lookup(image_cache, &imagetype, bitmap->index, &glyph, NULL) == 0) { + if (pFTC_ImageCache_Lookup(image_cache, &imagetype, bitmap->glyph, &glyph, NULL) == 0) { FT_Glyph glyph_copy;
if (needs_transform) { diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c index a5629270e1..f27fe9fbec 100644 --- a/dlls/dwrite/layout.c +++ b/dlls/dwrite/layout.c @@ -3604,16 +3604,6 @@ static HRESULT WINAPI dwritetextlayout_GetMetrics(IDWriteTextLayout3 *iface, DWR return hr; }
-static void scale_glyph_bbox(RECT *bbox, FLOAT emSize, UINT16 units_per_em, D2D1_RECT_F *ret) -{ -#define SCALE(x) ((FLOAT)x * emSize / (FLOAT)units_per_em) - ret->left = SCALE(bbox->left); - ret->right = SCALE(bbox->right); - ret->top = SCALE(bbox->top); - ret->bottom = SCALE(bbox->bottom); -#undef SCALE -} - static void d2d_rect_offset(D2D1_RECT_F *rect, FLOAT x, FLOAT y) { rect->left += x; @@ -3652,27 +3642,46 @@ static void layout_get_erun_bbox(struct dwrite_textlayout *layout, struct layout const struct regular_layout_run *regular = &run->run->u.regular; UINT32 start_glyph = regular->clustermap[run->start]; const DWRITE_GLYPH_RUN *glyph_run = ®ular->run; - DWRITE_FONT_METRICS font_metrics; D2D1_POINT_2F origin = { 0 }; + float rtl_factor; UINT32 i;
- if (run->bbox.top == run->bbox.bottom) { - IDWriteFontFace_GetMetrics(glyph_run->fontFace, &font_metrics); + if (run->bbox.top == run->bbox.bottom) + { + struct dwrite_glyphbitmap glyph_bitmap; + RECT *bbox; + + memset(&glyph_bitmap, 0, sizeof(glyph_bitmap)); + glyph_bitmap.fontface = (IDWriteFontFace4 *)glyph_run->fontFace; + glyph_bitmap.simulations = IDWriteFontFace_GetSimulations(glyph_run->fontFace); + glyph_bitmap.emsize = glyph_run->fontEmSize; + glyph_bitmap.nohint = layout->measuringmode == DWRITE_MEASURING_MODE_NATURAL; + + bbox = &glyph_bitmap.bbox;
+ rtl_factor = glyph_run->bidiLevel & 1 ? -1.0f : 1.0f; for (i = 0; i < run->glyphcount; i++) { D2D1_RECT_F glyph_bbox; - RECT design_bbox;
- freetype_get_design_glyph_bbox((IDWriteFontFace4 *)glyph_run->fontFace, font_metrics.designUnitsPerEm, - glyph_run->glyphIndices[i + start_glyph], &design_bbox); + /* FIXME: take care of vertical/rtl */ + if (glyph_run->bidiLevel & 1) + origin.x -= glyph_run->glyphAdvances[i + start_glyph]; + + glyph_bitmap.glyph = glyph_run->glyphIndices[i + start_glyph]; + freetype_get_glyph_bbox(&glyph_bitmap); + + glyph_bbox.left = bbox->left; + glyph_bbox.top = bbox->top; + glyph_bbox.right = bbox->right; + glyph_bbox.bottom = bbox->bottom; + + d2d_rect_offset(&glyph_bbox, origin.x + rtl_factor * glyph_run->glyphOffsets[i + start_glyph].advanceOffset, + origin.y - glyph_run->glyphOffsets[i + start_glyph].ascenderOffset);
- scale_glyph_bbox(&design_bbox, glyph_run->fontEmSize, font_metrics.designUnitsPerEm, &glyph_bbox); - d2d_rect_offset(&glyph_bbox, origin.x + glyph_run->glyphOffsets[i + start_glyph].advanceOffset, - origin.y + glyph_run->glyphOffsets[i + start_glyph].ascenderOffset); d2d_rect_union(&run->bbox, &glyph_bbox);
- /* FIXME: take care of vertical/rtl */ - origin.x += glyph_run->glyphAdvances[i + start_glyph]; + if (!(glyph_run->bidiLevel & 1)) + origin.x += glyph_run->glyphAdvances[i + start_glyph]; } }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/font.c | 229 +++++++++++++++++++++++---------------------- 1 file changed, 116 insertions(+), 113 deletions(-)
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index b10096de20..735c7c7180 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -920,40 +920,77 @@ static BOOL WINAPI dwritefontface1_IsMonospacedFont(IDWriteFontFace4 *iface) return !!(This->flags & FONTFACE_IS_MONOSPACED); }
+static int fontface_get_design_advance(struct dwrite_fontface *fontface, DWRITE_MEASURING_MODE measuring_mode, + float emsize, float ppdip, const DWRITE_MATRIX *transform, UINT16 glyph, BOOL is_sideways) +{ + unsigned int adjustment = fontface_get_horz_metric_adjustment(fontface); + BOOL has_contours; + int advance; + + if (is_sideways) + FIXME("Sideways mode is not supported.\n"); + + switch (measuring_mode) + { + case DWRITE_MEASURING_MODE_NATURAL: + advance = freetype_get_glyph_advance(&fontface->IDWriteFontFace4_iface, fontface->metrics.designUnitsPerEm, + glyph, measuring_mode, &has_contours); + if (has_contours) + advance += adjustment; + + return advance; + case DWRITE_MEASURING_MODE_GDI_NATURAL: + case DWRITE_MEASURING_MODE_GDI_CLASSIC: + emsize *= ppdip; + if (emsize == 0.0f) + return 0.0f; + + if (transform && memcmp(transform, &identity, sizeof(*transform))) + FIXME("Transform is not supported.\n"); + + advance = freetype_get_glyph_advance(&fontface->IDWriteFontFace4_iface, emsize, glyph, measuring_mode, + &has_contours); + if (has_contours) + advance = round_metric(advance * fontface->metrics.designUnitsPerEm / emsize + adjustment); + else + advance = round_metric(advance * fontface->metrics.designUnitsPerEm / emsize); + + return advance; + default: + WARN("Unknown measuring mode %u.\n", measuring_mode); + return 0; + } +} + static HRESULT WINAPI dwritefontface1_GetDesignGlyphAdvances(IDWriteFontFace4 *iface, UINT32 glyph_count, UINT16 const *glyphs, INT32 *advances, BOOL is_sideways) { struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); - UINT32 adjustment = fontface_get_horz_metric_adjustment(This); - UINT32 i; + unsigned int i;
TRACE("(%p)->(%u %p %p %d)\n", This, glyph_count, glyphs, advances, is_sideways);
if (is_sideways) FIXME("sideways mode not supported\n");
- for (i = 0; i < glyph_count; i++) { - BOOL has_contours; - - advances[i] = freetype_get_glyph_advance(iface, This->metrics.designUnitsPerEm, glyphs[i], - DWRITE_MEASURING_MODE_NATURAL, &has_contours); - if (has_contours) - advances[i] += adjustment; + for (i = 0; i < glyph_count; ++i) + { + advances[i] = fontface_get_design_advance(This, DWRITE_MEASURING_MODE_NATURAL, This->metrics.designUnitsPerEm, + 1.0f, NULL, glyphs[i], is_sideways); }
return S_OK; }
static HRESULT WINAPI dwritefontface1_GetGdiCompatibleGlyphAdvances(IDWriteFontFace4 *iface, - FLOAT em_size, FLOAT ppdip, const DWRITE_MATRIX *m, BOOL use_gdi_natural, + float em_size, float ppdip, const DWRITE_MATRIX *transform, BOOL use_gdi_natural, BOOL is_sideways, UINT32 glyph_count, UINT16 const *glyphs, INT32 *advances) { struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); - UINT32 adjustment = fontface_get_horz_metric_adjustment(This); - DWRITE_MEASURING_MODE mode; + DWRITE_MEASURING_MODE measuring_mode; UINT32 i;
- TRACE("(%p)->(%.2f %.2f %p %d %d %u %p %p)\n", This, em_size, ppdip, m, + TRACE("(%p)->(%.2f %.2f %p %d %d %u %p %p)\n", This, em_size, ppdip, transform, use_gdi_natural, is_sideways, glyph_count, glyphs, advances);
if (em_size < 0.0f || ppdip <= 0.0f) { @@ -961,24 +998,16 @@ static HRESULT WINAPI dwritefontface1_GetGdiCompatibleGlyphAdvances(IDWriteFontF return E_INVALIDARG; }
- em_size *= ppdip; if (em_size == 0.0f) { memset(advances, 0, sizeof(*advances) * glyph_count); return S_OK; }
- if (m && memcmp(m, &identity, sizeof(*m))) - FIXME("transform is not supported, %s\n", debugstr_matrix(m)); - - mode = use_gdi_natural ? DWRITE_MEASURING_MODE_GDI_NATURAL : DWRITE_MEASURING_MODE_GDI_CLASSIC; - for (i = 0; i < glyph_count; i++) { - BOOL has_contours; - - advances[i] = freetype_get_glyph_advance(iface, em_size, glyphs[i], mode, &has_contours); - if (has_contours) - advances[i] = round_metric(advances[i] * This->metrics.designUnitsPerEm / em_size + adjustment); - else - advances[i] = round_metric(advances[i] * This->metrics.designUnitsPerEm / em_size); + measuring_mode = use_gdi_natural ? DWRITE_MEASURING_MODE_GDI_NATURAL : DWRITE_MEASURING_MODE_GDI_CLASSIC; + for (i = 0; i < glyph_count; ++i) + { + advances[i] = fontface_get_design_advance(This, measuring_mode, em_size, ppdip, transform, + glyphs[i], is_sideways); }
return S_OK; @@ -5348,14 +5377,36 @@ static inline void transform_point(D2D_POINT_2F *point, const DWRITE_MATRIX *m) *point = ret; }
+static float fontface_get_scaled_design_advance(struct dwrite_fontface *fontface, DWRITE_MEASURING_MODE measuring_mode, + float emsize, float ppdip, const DWRITE_MATRIX *transform, UINT16 glyph, BOOL is_sideways) +{ + unsigned int upem = fontface->metrics.designUnitsPerEm; + int advance; + + if (is_sideways) + FIXME("Sideways mode is not supported.\n"); + + advance = fontface_get_design_advance(fontface, measuring_mode, emsize, ppdip, transform, glyph, is_sideways); + + switch (measuring_mode) + { + case DWRITE_MEASURING_MODE_NATURAL: + return (float)advance * emsize / (float)upem; + case DWRITE_MEASURING_MODE_GDI_NATURAL: + case DWRITE_MEASURING_MODE_GDI_CLASSIC: + return ppdip > 0.0f ? floorf(advance * emsize * ppdip / upem + 0.5f) / ppdip : 0.0f; + default: + WARN("Unknown measuring mode %u.\n", measuring_mode); + return 0.0f; + } +} + HRESULT create_glyphrunanalysis(const struct glyphrunanalysis_desc *desc, IDWriteGlyphRunAnalysis **ret) { struct dwrite_glyphrunanalysis *analysis; - DWRITE_FONT_METRICS metrics; - IDWriteFontFace1 *fontface1; + struct dwrite_fontface *fontface; D2D_POINT_2F origin; FLOAT rtl_factor; - HRESULT hr; UINT32 i;
*ret = NULL; @@ -5425,42 +5476,29 @@ HRESULT create_glyphrunanalysis(const struct glyphrunanalysis_desc *desc, IDWrit
memcpy(analysis->glyphs, desc->run->glyphIndices, desc->run->glyphCount*sizeof(*desc->run->glyphIndices));
- IDWriteFontFace_GetMetrics(desc->run->fontFace, &metrics); - if (FAILED(hr = IDWriteFontFace_QueryInterface(desc->run->fontFace, &IID_IDWriteFontFace1, (void **)&fontface1))) - WARN("Failed to get IDWriteFontFace1, %#x.\n", hr); + fontface = unsafe_impl_from_IDWriteFontFace(desc->run->fontFace);
origin.x = desc->origin.x; origin.y = desc->origin.y; - for (i = 0; i < desc->run->glyphCount; i++) { - FLOAT advance; + for (i = 0; i < desc->run->glyphCount; ++i) + { + float advance;
/* Use nominal advances if not provided by caller. */ if (desc->run->glyphAdvances) advance = rtl_factor * desc->run->glyphAdvances[i]; - else { - INT32 a; - - advance = 0.0f; - switch (desc->measuring_mode) - { - case DWRITE_MEASURING_MODE_NATURAL: - if (SUCCEEDED(IDWriteFontFace1_GetDesignGlyphAdvances(fontface1, 1, desc->run->glyphIndices + i, &a, - desc->run->isSideways))) - advance = rtl_factor * get_scaled_advance_width(a, desc->run->fontEmSize, &metrics); - break; - case DWRITE_MEASURING_MODE_GDI_CLASSIC: - case DWRITE_MEASURING_MODE_GDI_NATURAL: - if (SUCCEEDED(IDWriteFontFace1_GetGdiCompatibleGlyphAdvances(fontface1, desc->run->fontEmSize, - 1.0f, desc->transform, desc->measuring_mode == DWRITE_MEASURING_MODE_GDI_NATURAL, - desc->run->isSideways, 1, desc->run->glyphIndices + i, &a))) - advance = rtl_factor * floorf(a * desc->run->fontEmSize / metrics.designUnitsPerEm + 0.5f); - break; - default: - ; - } - } + else + advance = rtl_factor * fontface_get_scaled_design_advance(fontface, desc->measuring_mode, + desc->run->fontEmSize, 1.0f, desc->transform, desc->run->glyphIndices[i], desc->run->isSideways);
analysis->origins[i] = origin; + if (desc->run->bidiLevel & 1) + { + if (desc->run->isSideways) + analysis->origins[i].y += advance; + else + analysis->origins[i].x += advance; + }
/* Offsets are optional, appled to pre-transformed origin. */ if (desc->run->glyphOffsets) { @@ -5486,8 +5524,6 @@ HRESULT create_glyphrunanalysis(const struct glyphrunanalysis_desc *desc, IDWrit origin.x += advance; }
- IDWriteFontFace1_Release(fontface1); - *ret = &analysis->IDWriteGlyphRunAnalysis_iface; return S_OK; } @@ -5689,40 +5725,34 @@ static const IDWriteColorGlyphRunEnumeratorVtbl colorglyphenumvtbl = { colorglyphenum_GetCurrentRun };
-HRESULT create_colorglyphenum(FLOAT originX, FLOAT originY, const DWRITE_GLYPH_RUN *run, const DWRITE_GLYPH_RUN_DESCRIPTION *rundescr, - DWRITE_MEASURING_MODE measuring_mode, const DWRITE_MATRIX *transform, UINT32 palette, IDWriteColorGlyphRunEnumerator **ret) +HRESULT create_colorglyphenum(float originX, float originY, const DWRITE_GLYPH_RUN *run, + const DWRITE_GLYPH_RUN_DESCRIPTION *rundescr, DWRITE_MEASURING_MODE measuring_mode, + const DWRITE_MATRIX *transform, unsigned int palette, IDWriteColorGlyphRunEnumerator **ret) { struct dwrite_colorglyphenum *colorglyphenum; BOOL colorfont, has_colored_glyph; - IDWriteFontFace4 *fontface; - HRESULT hr; - UINT32 i; + struct dwrite_fontface *fontface; + unsigned int i;
*ret = NULL;
- hr = IDWriteFontFace_QueryInterface(run->fontFace, &IID_IDWriteFontFace4, (void**)&fontface); - if (FAILED(hr)) { - WARN("failed to get IDWriteFontFace4, 0x%08x\n", hr); - return hr; - } + fontface = unsafe_impl_from_IDWriteFontFace(run->fontFace);
- colorfont = IDWriteFontFace4_IsColorFont(fontface) && IDWriteFontFace4_GetColorPaletteCount(fontface) > palette; - if (!colorfont) { - hr = DWRITE_E_NOCOLOR; - goto failed; - } + colorfont = IDWriteFontFace4_IsColorFont(&fontface->IDWriteFontFace4_iface) && + IDWriteFontFace4_GetColorPaletteCount(&fontface->IDWriteFontFace4_iface) > palette; + if (!colorfont) + return DWRITE_E_NOCOLOR;
colorglyphenum = heap_alloc_zero(sizeof(*colorglyphenum)); - if (!colorglyphenum) { - hr = E_OUTOFMEMORY; - goto failed; - } + if (!colorglyphenum) + return E_OUTOFMEMORY;
colorglyphenum->IDWriteColorGlyphRunEnumerator_iface.lpVtbl = &colorglyphenumvtbl; colorglyphenum->ref = 1; colorglyphenum->origin_x = originX; colorglyphenum->origin_y = originY; - colorglyphenum->fontface = fontface; + colorglyphenum->fontface = &fontface->IDWriteFontFace4_iface; + IDWriteFontFace4_AddRef(colorglyphenum->fontface); colorglyphenum->glyphs = NULL; colorglyphenum->run = *run; colorglyphenum->run.glyphIndices = NULL; @@ -5731,7 +5761,7 @@ HRESULT create_colorglyphenum(FLOAT originX, FLOAT originY, const DWRITE_GLYPH_R colorglyphenum->palette = palette; memset(&colorglyphenum->colr, 0, sizeof(colorglyphenum->colr)); colorglyphenum->colr.exists = TRUE; - get_fontface_table(fontface, MS_COLR_TAG, &colorglyphenum->colr); + get_fontface_table(&fontface->IDWriteFontFace4_iface, MS_COLR_TAG, &colorglyphenum->colr); colorglyphenum->current_layer = 0; colorglyphenum->max_layer_num = 0;
@@ -5764,7 +5794,7 @@ HRESULT create_colorglyphenum(FLOAT originX, FLOAT originY, const DWRITE_GLYPH_R memcpy(colorglyphenum->offsets, run->glyphOffsets, run->glyphCount * sizeof(*run->glyphOffsets)); }
- colorglyphenum->colorrun.glyphRun.fontFace = (IDWriteFontFace*)fontface; + colorglyphenum->colorrun.glyphRun.fontFace = run->fontFace; colorglyphenum->colorrun.glyphRun.fontEmSize = run->fontEmSize; colorglyphenum->colorrun.glyphRun.glyphIndices = colorglyphenum->glyphindices; colorglyphenum->colorrun.glyphRun.glyphAdvances = colorglyphenum->color_advances; @@ -5773,43 +5803,16 @@ HRESULT create_colorglyphenum(FLOAT originX, FLOAT originY, const DWRITE_GLYPH_R
if (run->glyphAdvances) memcpy(colorglyphenum->advances, run->glyphAdvances, run->glyphCount * sizeof(FLOAT)); - else { - DWRITE_FONT_METRICS metrics; - - IDWriteFontFace_GetMetrics(run->fontFace, &metrics); - for (i = 0; i < run->glyphCount; i++) { - HRESULT hr; - INT32 a; - - switch (measuring_mode) - { - case DWRITE_MEASURING_MODE_NATURAL: - hr = IDWriteFontFace4_GetDesignGlyphAdvances(fontface, 1, run->glyphIndices + i, &a, run->isSideways); - if (FAILED(hr)) - a = 0; - colorglyphenum->advances[i] = get_scaled_advance_width(a, run->fontEmSize, &metrics); - break; - case DWRITE_MEASURING_MODE_GDI_CLASSIC: - case DWRITE_MEASURING_MODE_GDI_NATURAL: - hr = IDWriteFontFace4_GetGdiCompatibleGlyphAdvances(fontface, run->fontEmSize, 1.0f, transform, - measuring_mode == DWRITE_MEASURING_MODE_GDI_NATURAL, run->isSideways, 1, run->glyphIndices + i, &a); - if (FAILED(hr)) - colorglyphenum->advances[i] = 0.0f; - else - colorglyphenum->advances[i] = floorf(a * run->fontEmSize / metrics.designUnitsPerEm + 0.5f); - break; - default: - ; - } - } + else + { + for (i = 0; i < run->glyphCount; ++i) + colorglyphenum->advances[i] = fontface_get_scaled_design_advance(fontface, measuring_mode, + run->fontEmSize, 1.0f, transform, run->glyphIndices[i], run->isSideways); }
*ret = &colorglyphenum->IDWriteColorGlyphRunEnumerator_iface; - return S_OK;
-failed: - IDWriteFontFace4_Release(fontface); - return hr; + return S_OK; }
/* IDWriteFontFaceReference */