hb-uniscribe.cc revision eb56f6ae96260c5b4bcd4e1dfb7ab733a230f3a8
10fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod/* 21c1233e57686d77d89fe3ac1dc53de9ee60798c1Behdad Esfahbod * Copyright © 2011,2012 Google, Inc. 30fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod * 40fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod * This is part of HarfBuzz, a text shaping library. 50fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod * 60fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod * Permission is hereby granted, without written agreement and without 70fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod * license or royalty fees, to use, copy, modify, and distribute this 80fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod * software and its documentation for any purpose, provided that the 90fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod * above copyright notice and the following two paragraphs appear in 100fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod * all copies of this software. 110fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod * 120fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 130fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 140fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 150fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 160fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod * DAMAGE. 170fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod * 180fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 190fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 200fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 210fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 220fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 230fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod * 240fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod * Google Author(s): Behdad Esfahbod 250fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod */ 260fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 27552bf3a9f9651311084b7979805dbdc18c0335caBehdad Esfahbod#define _WIN32_WINNT 0x0600 28eb56f6ae96260c5b4bcd4e1dfb7ab733a230f3a8Behdad Esfahbod#define WIN32_LEAN_AND_MEAN 290fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 30027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod#define HB_SHAPER uniscribe 31027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod#include "hb-shaper-impl-private.hh" 320fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 33b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod#include <windows.h> 34b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod#include <usp10.h> 35b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod 36b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbodtypedef ULONG WIN_ULONG; 37b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod 380fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod#include "hb-uniscribe.h" 390fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 407a750ac33ec482e2c4856c19ea607f3563741c24Behdad Esfahbod#include "hb-ot-name-table.hh" 410fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod#include "hb-ot-tag.h" 420fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 430fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 440fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod#ifndef HB_DEBUG_UNISCRIBE 450fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod#define HB_DEBUG_UNISCRIBE (HB_DEBUG+0) 460fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod#endif 470fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 480fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 490fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod/* 500fbb2dc83132a89201ad8b56c6909610437d2da0Behdad EsfahbodDWORD GetFontData( 510fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod __in HDC hdc, 520fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod __in DWORD dwTable, 530fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod __in DWORD dwOffset, 540fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod __out LPVOID lpvBuffer, 550fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod __in DWORD cbData 560fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod); 570fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod*/ 580fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 59bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod 60cfe9882610489e1b917e09a74dfbf6bbba2e4a57Behdad EsfahbodHB_SHAPER_DATA_ENSURE_DECLARE(uniscribe, face) 61cfe9882610489e1b917e09a74dfbf6bbba2e4a57Behdad EsfahbodHB_SHAPER_DATA_ENSURE_DECLARE(uniscribe, font) 62cfe9882610489e1b917e09a74dfbf6bbba2e4a57Behdad Esfahbod 63cfe9882610489e1b917e09a74dfbf6bbba2e4a57Behdad Esfahbod 64027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod/* 65027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod * shaper face data 66027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod */ 6771388b3ee71c7d3b79f842db7588bd683691797cBehdad Esfahbod 68027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbodstruct hb_uniscribe_shaper_face_data_t { 69bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod HANDLE fh; 70027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod}; 71bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod 72027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbodhb_uniscribe_shaper_face_data_t * 73027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod_hb_uniscribe_shaper_face_data_create (hb_face_t *face) 74bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod{ 75027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod hb_uniscribe_shaper_face_data_t *data = (hb_uniscribe_shaper_face_data_t *) calloc (1, sizeof (hb_uniscribe_shaper_face_data_t)); 76bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod if (unlikely (!data)) 77027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod return NULL; 78a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 79bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod hb_blob_t *blob = hb_face_reference_blob (face); 80bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod unsigned int blob_length; 81bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod const char *blob_data = hb_blob_get_data (blob, &blob_length); 82bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod if (unlikely (!blob_length)) 83bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod DEBUG_MSG (UNISCRIBE, face, "Face has empty blob"); 84bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod 85bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod DWORD num_fonts_installed; 86bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod data->fh = AddFontMemResourceEx ((void *) blob_data, blob_length, 0, &num_fonts_installed); 87bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod hb_blob_destroy (blob); 88027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod if (unlikely (!data->fh)) { 89bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod DEBUG_MSG (UNISCRIBE, face, "Face AddFontMemResourceEx() failed"); 90027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod free (data); 91027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod return NULL; 92bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod } 93bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod 94bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod return data; 95bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod} 96bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod 97027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbodvoid 98027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod_hb_uniscribe_shaper_face_data_destroy (hb_uniscribe_shaper_face_data_t *data) 99027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod{ 100713914d3203109a8e9213f5a1d3b384730703ce9Behdad Esfahbod RemoveFontMemResourceEx (data->fh); 101027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod free (data); 102027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod} 103bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod 104027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod 105027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod/* 106027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod * shaper font data 107027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod */ 108027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod 109027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbodstruct hb_uniscribe_shaper_font_data_t { 110bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod HDC hdc; 111d6660356dd81358033743f72d8a5fbf2fc70eaf7Behdad Esfahbod LOGFONTW log_font; 112bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod HFONT hfont; 113bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod SCRIPT_CACHE script_cache; 114027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod}; 115bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod 116b6b7ba1313bf686e6ed567183466104c90504a67Behdad Esfahbodstatic bool 117b6b7ba1313bf686e6ed567183466104c90504a67Behdad Esfahbodpopulate_log_font (LOGFONTW *lf, 118b6b7ba1313bf686e6ed567183466104c90504a67Behdad Esfahbod hb_font_t *font) 119b6b7ba1313bf686e6ed567183466104c90504a67Behdad Esfahbod{ 120b6b7ba1313bf686e6ed567183466104c90504a67Behdad Esfahbod memset (lf, 0, sizeof (*lf)); 121b6b7ba1313bf686e6ed567183466104c90504a67Behdad Esfahbod lf->lfHeight = -font->y_scale; 122b6b7ba1313bf686e6ed567183466104c90504a67Behdad Esfahbod lf->lfCharSet = DEFAULT_CHARSET; 123b6b7ba1313bf686e6ed567183466104c90504a67Behdad Esfahbod 124b6b7ba1313bf686e6ed567183466104c90504a67Behdad Esfahbod hb_blob_t *blob = Sanitizer<name>::sanitize (hb_face_reference_table (font->face, HB_TAG ('n','a','m','e'))); 125b6b7ba1313bf686e6ed567183466104c90504a67Behdad Esfahbod const name *name_table = Sanitizer<name>::lock_instance (blob); 126b6b7ba1313bf686e6ed567183466104c90504a67Behdad Esfahbod unsigned int len = name_table->get_name (3, 1, 0x409, 4, 127b6b7ba1313bf686e6ed567183466104c90504a67Behdad Esfahbod lf->lfFaceName, 128b6b7ba1313bf686e6ed567183466104c90504a67Behdad Esfahbod sizeof (lf->lfFaceName[0]) * LF_FACESIZE) 129b6b7ba1313bf686e6ed567183466104c90504a67Behdad Esfahbod / sizeof (lf->lfFaceName[0]); 130b6b7ba1313bf686e6ed567183466104c90504a67Behdad Esfahbod hb_blob_destroy (blob); 131b6b7ba1313bf686e6ed567183466104c90504a67Behdad Esfahbod 132b6b7ba1313bf686e6ed567183466104c90504a67Behdad Esfahbod if (unlikely (!len)) { 133b6b7ba1313bf686e6ed567183466104c90504a67Behdad Esfahbod DEBUG_MSG (UNISCRIBE, NULL, "Didn't find English name table entry"); 134b6b7ba1313bf686e6ed567183466104c90504a67Behdad Esfahbod return false; 135b6b7ba1313bf686e6ed567183466104c90504a67Behdad Esfahbod } 136b6b7ba1313bf686e6ed567183466104c90504a67Behdad Esfahbod if (unlikely (len >= LF_FACESIZE)) { 137b6b7ba1313bf686e6ed567183466104c90504a67Behdad Esfahbod DEBUG_MSG (UNISCRIBE, NULL, "Font name too long"); 138b6b7ba1313bf686e6ed567183466104c90504a67Behdad Esfahbod return false; 139b6b7ba1313bf686e6ed567183466104c90504a67Behdad Esfahbod } 140b6b7ba1313bf686e6ed567183466104c90504a67Behdad Esfahbod 141b6b7ba1313bf686e6ed567183466104c90504a67Behdad Esfahbod for (unsigned int i = 0; i < len; i++) 142b6b7ba1313bf686e6ed567183466104c90504a67Behdad Esfahbod lf->lfFaceName[i] = hb_be_uint16 (lf->lfFaceName[i]); 143b6b7ba1313bf686e6ed567183466104c90504a67Behdad Esfahbod lf->lfFaceName[len] = 0; 144b6b7ba1313bf686e6ed567183466104c90504a67Behdad Esfahbod 145b6b7ba1313bf686e6ed567183466104c90504a67Behdad Esfahbod return true; 146b6b7ba1313bf686e6ed567183466104c90504a67Behdad Esfahbod} 147b6b7ba1313bf686e6ed567183466104c90504a67Behdad Esfahbod 148027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbodhb_uniscribe_shaper_font_data_t * 149027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod_hb_uniscribe_shaper_font_data_create (hb_font_t *font) 150027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod{ 151713914d3203109a8e9213f5a1d3b384730703ce9Behdad Esfahbod if (unlikely (!hb_uniscribe_shaper_face_data_ensure (font->face))) return NULL; 152713914d3203109a8e9213f5a1d3b384730703ce9Behdad Esfahbod 153e82061e8db922f0ddbefd5a184ee2f9f967b9a05Behdad Esfahbod hb_uniscribe_shaper_font_data_t *data = (hb_uniscribe_shaper_font_data_t *) calloc (1, sizeof (hb_uniscribe_shaper_font_data_t)); 154027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod if (unlikely (!data)) 155027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod return NULL; 156027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod 157027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod data->hdc = GetDC (NULL); 158027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod 159027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod if (unlikely (!populate_log_font (&data->log_font, font))) { 160027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod DEBUG_MSG (UNISCRIBE, font, "Font populate_log_font() failed"); 161027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod _hb_uniscribe_shaper_font_data_destroy (data); 162027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod return NULL; 163027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod } 164027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod 165027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod data->hfont = CreateFontIndirectW (&data->log_font); 166027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod if (unlikely (!data->hfont)) { 167027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod DEBUG_MSG (UNISCRIBE, font, "Font CreateFontIndirectW() failed"); 168027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod _hb_uniscribe_shaper_font_data_destroy (data); 169027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod return NULL; 170027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod } 171027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod 172027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod if (!SelectObject (data->hdc, data->hfont)) { 173027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod DEBUG_MSG (UNISCRIBE, font, "Font SelectObject() failed"); 174027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod _hb_uniscribe_shaper_font_data_destroy (data); 175027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod return NULL; 176027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod } 177027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod 178027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod return data; 179027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod} 180027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod 181027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbodvoid 182027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod_hb_uniscribe_shaper_font_data_destroy (hb_uniscribe_shaper_font_data_t *data) 183bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod{ 184bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod if (data->hdc) 185bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod ReleaseDC (NULL, data->hdc); 186bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod if (data->hfont) 187bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod DeleteObject (data->hfont); 188bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod if (data->script_cache) 189bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod ScriptFreeCache (&data->script_cache); 190bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod free (data); 191bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod} 192bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod 193027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod 194027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod/* 195027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod * shaper shape_plan data 196027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod */ 197027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod 198027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbodstruct hb_uniscribe_shaper_shape_plan_data_t {}; 199027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod 200027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbodhb_uniscribe_shaper_shape_plan_data_t * 2015b95c148cc485f79fd7018bc4520b4cb5f728a18Behdad Esfahbod_hb_uniscribe_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan, 2025b95c148cc485f79fd7018bc4520b4cb5f728a18Behdad Esfahbod const hb_feature_t *user_features, 2035b95c148cc485f79fd7018bc4520b4cb5f728a18Behdad Esfahbod unsigned int num_user_features) 204bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod{ 205027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod return (hb_uniscribe_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED; 206027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod} 207bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod 208027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbodvoid 209027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod_hb_uniscribe_shaper_shape_plan_data_destroy (hb_uniscribe_shaper_shape_plan_data_t *data) 210027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod{ 211027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod} 212bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod 213bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod 214027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod/* 215027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod * shaper 216027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod */ 217bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod 218d6660356dd81358033743f72d8a5fbf2fc70eaf7Behdad EsfahbodLOGFONTW * 219d6660356dd81358033743f72d8a5fbf2fc70eaf7Behdad Esfahbodhb_uniscribe_font_get_logfontw (hb_font_t *font) 220d6660356dd81358033743f72d8a5fbf2fc70eaf7Behdad Esfahbod{ 221713914d3203109a8e9213f5a1d3b384730703ce9Behdad Esfahbod if (unlikely (!hb_uniscribe_shaper_font_data_ensure (font))) return NULL; 222a00ad60bc0fe74bf0e11d73da563239f3392f351Behdad Esfahbod return NULL; 223b6b7ba1313bf686e6ed567183466104c90504a67Behdad Esfahbod hb_uniscribe_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font); 224d6660356dd81358033743f72d8a5fbf2fc70eaf7Behdad Esfahbod return &font_data->log_font; 225d6660356dd81358033743f72d8a5fbf2fc70eaf7Behdad Esfahbod} 226d6660356dd81358033743f72d8a5fbf2fc70eaf7Behdad Esfahbod 227d6660356dd81358033743f72d8a5fbf2fc70eaf7Behdad EsfahbodHFONT 228d6660356dd81358033743f72d8a5fbf2fc70eaf7Behdad Esfahbodhb_uniscribe_font_get_hfont (hb_font_t *font) 229d6660356dd81358033743f72d8a5fbf2fc70eaf7Behdad Esfahbod{ 230713914d3203109a8e9213f5a1d3b384730703ce9Behdad Esfahbod if (unlikely (!hb_uniscribe_shaper_font_data_ensure (font))) return NULL; 231b6b7ba1313bf686e6ed567183466104c90504a67Behdad Esfahbod hb_uniscribe_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font); 232d6660356dd81358033743f72d8a5fbf2fc70eaf7Behdad Esfahbod return font_data->hfont; 233d6660356dd81358033743f72d8a5fbf2fc70eaf7Behdad Esfahbod} 234d6660356dd81358033743f72d8a5fbf2fc70eaf7Behdad Esfahbod 235bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod 23602aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbodhb_bool_t 237bd26b4d21f59312805d294f46f15182adbcc47daBehdad Esfahbod_hb_uniscribe_shape (hb_shape_plan_t *shape_plan, 238bd26b4d21f59312805d294f46f15182adbcc47daBehdad Esfahbod hb_font_t *font, 2396bd9b479b8b2befbb0847282e93beade197c8038Behdad Esfahbod hb_buffer_t *buffer, 2406bd9b479b8b2befbb0847282e93beade197c8038Behdad Esfahbod const hb_feature_t *features, 2416bd9b479b8b2befbb0847282e93beade197c8038Behdad Esfahbod unsigned int num_features) 2420fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod{ 243b6b7ba1313bf686e6ed567183466104c90504a67Behdad Esfahbod hb_face_t *face = font->face; 244b6b7ba1313bf686e6ed567183466104c90504a67Behdad Esfahbod hb_uniscribe_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face); 245b6b7ba1313bf686e6ed567183466104c90504a67Behdad Esfahbod hb_uniscribe_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font); 24602aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod 247bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod#define FAIL(...) \ 248bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod HB_STMT_START { \ 249bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod DEBUG_MSG (UNISCRIBE, NULL, __VA_ARGS__); \ 2500594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return false; \ 251bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod } HB_STMT_END; 252bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod 253bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod HRESULT hr; 254bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod 2550fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbodretry: 2560fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 2570fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod unsigned int scratch_size; 2580fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod char *scratch = (char *) buffer->get_scratch_buffer (&scratch_size); 2590fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 2600fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod /* Allocate char buffers; they all fit */ 2610fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 2620fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod#define ALLOCATE_ARRAY(Type, name, len) \ 2630fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod Type *name = (Type *) scratch; \ 26491e721ea8693205f4f738bca97a5055ee75cf463Behdad Esfahbod scratch += (len) * sizeof ((name)[0]); \ 26591e721ea8693205f4f738bca97a5055ee75cf463Behdad Esfahbod scratch_size -= (len) * sizeof ((name)[0]); 2660fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 2670fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod#define utf16_index() var1.u32 2680fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 2690fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod WCHAR *pchars = (WCHAR *) scratch; 2700fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod unsigned int chars_len = 0; 2710fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod for (unsigned int i = 0; i < buffer->len; i++) { 2720fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod hb_codepoint_t c = buffer->info[i].codepoint; 2730fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod buffer->info[i].utf16_index() = chars_len; 2740fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod if (likely (c < 0x10000)) 2750fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod pchars[chars_len++] = c; 2760fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod else if (unlikely (c >= 0x110000)) 2770fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod pchars[chars_len++] = 0xFFFD; 2780fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod else { 2790fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod pchars[chars_len++] = 0xD800 + ((c - 0x10000) >> 10); 2800fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod pchars[chars_len++] = 0xDC00 + ((c - 0x10000) & ((1 << 10) - 1)); 2810fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod } 2820fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod } 2830fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 2840fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod ALLOCATE_ARRAY (WCHAR, wchars, chars_len); 2850fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod ALLOCATE_ARRAY (WORD, log_clusters, chars_len); 2860fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod ALLOCATE_ARRAY (SCRIPT_CHARPROP, char_props, chars_len); 2870fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 2880fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod /* On Windows, we don't care about alignment...*/ 2890fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod unsigned int glyphs_size = scratch_size / (sizeof (WORD) + 2900fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod sizeof (SCRIPT_GLYPHPROP) + 2910fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod sizeof (int) + 2920fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod sizeof (GOFFSET) + 2930fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod sizeof (uint32_t)); 2940fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 2950fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod ALLOCATE_ARRAY (WORD, glyphs, glyphs_size); 2960fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod ALLOCATE_ARRAY (SCRIPT_GLYPHPROP, glyph_props, glyphs_size); 2970fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod ALLOCATE_ARRAY (int, advances, glyphs_size); 2980fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod ALLOCATE_ARRAY (GOFFSET, offsets, glyphs_size); 2990fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod ALLOCATE_ARRAY (uint32_t, vis_clusters, glyphs_size); 3000fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 30191e721ea8693205f4f738bca97a5055ee75cf463Behdad Esfahbod#undef ALLOCATE_ARRAY 3020fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 303872969126756456a69bf958f3df6e56a26e57b0aBehdad Esfahbod#define MAX_ITEMS 256 3040fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 3050fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod SCRIPT_ITEM items[MAX_ITEMS + 1]; 3065c299343118d1eaff32ffb2a5dac077cfff67deeBehdad Esfahbod SCRIPT_CONTROL bidi_control = {0}; 3070fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod SCRIPT_STATE bidi_state = {0}; 308b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod WIN_ULONG script_tags[MAX_ITEMS]; 3090fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod int item_count; 3100fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 3115c299343118d1eaff32ffb2a5dac077cfff67deeBehdad Esfahbod /* MinGW32 doesn't define fMergeNeutralItems, so we bruteforce */ 3120594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod //bidi_control.fMergeNeutralItems = true; 3135c299343118d1eaff32ffb2a5dac077cfff67deeBehdad Esfahbod *(uint32_t*)&bidi_control |= 1<<24; 3145c299343118d1eaff32ffb2a5dac077cfff67deeBehdad Esfahbod 3150fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod bidi_state.uBidiLevel = HB_DIRECTION_IS_FORWARD (buffer->props.direction) ? 0 : 1; 31629eac8f591fdb86f1c4fdc0a6ab63910ff286b84Behdad Esfahbod bidi_state.fOverrideDirection = 1; 3170fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 3180fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod hr = ScriptItemizeOpenType (wchars, 3190fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod chars_len, 3200fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod MAX_ITEMS, 3215c299343118d1eaff32ffb2a5dac077cfff67deeBehdad Esfahbod &bidi_control, 3220fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod &bidi_state, 3230fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod items, 3240fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod script_tags, 3250fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod &item_count); 3260fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod if (unlikely (FAILED (hr))) 3272eb474afb4a09f4da8f14b444bd6066769010224Behdad Esfahbod FAIL ("ScriptItemizeOpenType() failed: 0x%08xL", hr); 3280fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 3290fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod#undef MAX_ITEMS 3300fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 3310fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod int *range_char_counts = NULL; 3320fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod TEXTRANGE_PROPERTIES **range_properties = NULL; 3330fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod int range_count = 0; 3340fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod if (num_features) { 3355c299343118d1eaff32ffb2a5dac077cfff67deeBehdad Esfahbod /* TODO setup ranges */ 3360fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod } 3370fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 338fcd6f5326166e993b8f5222efbaffe916da98f0aBehdad Esfahbod OPENTYPE_TAG language_tag = hb_uint32_swap (hb_ot_tag_from_language (buffer->props.language)); 3390fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 3400fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod unsigned int glyphs_offset = 0; 3410fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod unsigned int glyphs_len; 342b069c3c31bfbbf160eb897c7474be9ea90ed4fc1Behdad Esfahbod bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction); 343b069c3c31bfbbf160eb897c7474be9ea90ed4fc1Behdad Esfahbod for (unsigned int j = 0; j < item_count; j++) 3440fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod { 3450dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod unsigned int i = backward ? item_count - 1 - j : j; 3460dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod unsigned int chars_offset = items[i].iCharPos; 3470dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod unsigned int item_chars_len = items[i + 1].iCharPos - chars_offset; 3480dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod 349e9c0f152a38cb2e76650a3e43f7fdcda266af696Behdad Esfahbod retry_shape: 3500dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod hr = ScriptShapeOpenType (font_data->hdc, 3510dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod &font_data->script_cache, 3520dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod &items[i].a, 353e9c0f152a38cb2e76650a3e43f7fdcda266af696Behdad Esfahbod script_tags[i], 3540dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod language_tag, 3550dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod range_char_counts, 3560dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod range_properties, 3570dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod range_count, 3580dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod wchars + chars_offset, 3590dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod item_chars_len, 3600dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod glyphs_size - glyphs_offset, 3610dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod /* out */ 3620dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod log_clusters + chars_offset, 3630dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod char_props + chars_offset, 3640dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod glyphs + glyphs_offset, 3650dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod glyph_props + glyphs_offset, 3660dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod (int *) &glyphs_len); 3670dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod 3680dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod if (unlikely (items[i].a.fNoGlyphIndex)) 3690dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod FAIL ("ScriptShapeOpenType() set fNoGlyphIndex"); 3700dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod if (unlikely (hr == E_OUTOFMEMORY)) 3710dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod { 3720dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod buffer->ensure (buffer->allocated * 2); 3730dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod if (buffer->in_error) 3740dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod FAIL ("Buffer resize failed"); 3750dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod goto retry; 3760dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod } 3770dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod if (unlikely (hr == USP_E_SCRIPT_NOT_IN_FONT)) 378e9c0f152a38cb2e76650a3e43f7fdcda266af696Behdad Esfahbod { 379e9c0f152a38cb2e76650a3e43f7fdcda266af696Behdad Esfahbod if (items[i].a.eScript == SCRIPT_UNDEFINED) 380e9c0f152a38cb2e76650a3e43f7fdcda266af696Behdad Esfahbod FAIL ("ScriptShapeOpenType() failed: Font doesn't support script"); 381e9c0f152a38cb2e76650a3e43f7fdcda266af696Behdad Esfahbod items[i].a.eScript = SCRIPT_UNDEFINED; 382e9c0f152a38cb2e76650a3e43f7fdcda266af696Behdad Esfahbod goto retry_shape; 383e9c0f152a38cb2e76650a3e43f7fdcda266af696Behdad Esfahbod } 3840dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod if (unlikely (FAILED (hr))) 385e9c0f152a38cb2e76650a3e43f7fdcda266af696Behdad Esfahbod { 3860dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod FAIL ("ScriptShapeOpenType() failed: 0x%08xL", hr); 387e9c0f152a38cb2e76650a3e43f7fdcda266af696Behdad Esfahbod } 388e9c0f152a38cb2e76650a3e43f7fdcda266af696Behdad Esfahbod 389e9c0f152a38cb2e76650a3e43f7fdcda266af696Behdad Esfahbod for (unsigned int j = chars_offset; j < chars_offset + item_chars_len; j++) 390e9c0f152a38cb2e76650a3e43f7fdcda266af696Behdad Esfahbod log_clusters[j] += glyphs_offset; 3910dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod 3920dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod hr = ScriptPlaceOpenType (font_data->hdc, 3930dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod &font_data->script_cache, 3940dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod &items[i].a, 395e9c0f152a38cb2e76650a3e43f7fdcda266af696Behdad Esfahbod script_tags[i], 3960dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod language_tag, 3970dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod range_char_counts, 3980dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod range_properties, 3990dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod range_count, 4000dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod wchars + chars_offset, 4010dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod log_clusters + chars_offset, 4020dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod char_props + chars_offset, 4030dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod item_chars_len, 4040dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod glyphs + glyphs_offset, 4050dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod glyph_props + glyphs_offset, 4060dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod glyphs_len, 4070dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod /* out */ 4080dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod advances + glyphs_offset, 4090dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod offsets + glyphs_offset, 4100dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod NULL); 4110dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod if (unlikely (FAILED (hr))) 4120dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod FAIL ("ScriptPlaceOpenType() failed: 0x%08xL", hr); 4130dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod 4140dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod glyphs_offset += glyphs_len; 4150fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod } 4160fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod glyphs_len = glyphs_offset; 4170fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 4180fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod /* Ok, we've got everything we need, now compose output buffer, 4190fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod * very, *very*, carefully! */ 4200fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 4210fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod /* Calculate visual-clusters. That's what we ship. */ 4225c299343118d1eaff32ffb2a5dac077cfff67deeBehdad Esfahbod for (unsigned int i = 0; i < glyphs_len; i++) 4235c299343118d1eaff32ffb2a5dac077cfff67deeBehdad Esfahbod vis_clusters[i] = -1; 424577326b86af80cc137eea81f4cc1e30adf9232b1Behdad Esfahbod for (unsigned int i = 0; i < buffer->len; i++) { 425577326b86af80cc137eea81f4cc1e30adf9232b1Behdad Esfahbod uint32_t *p = &vis_clusters[log_clusters[buffer->info[i].utf16_index()]]; 426577326b86af80cc137eea81f4cc1e30adf9232b1Behdad Esfahbod *p = MIN (*p, buffer->info[i].cluster); 427577326b86af80cc137eea81f4cc1e30adf9232b1Behdad Esfahbod } 428b069c3c31bfbbf160eb897c7474be9ea90ed4fc1Behdad Esfahbod if (!backward) { 4295c299343118d1eaff32ffb2a5dac077cfff67deeBehdad Esfahbod for (unsigned int i = 1; i < glyphs_len; i++) 4308e7beba7c3b3dea3cb3b7e280c5aab4f13b92d31Behdad Esfahbod if (vis_clusters[i] == -1) 4315c299343118d1eaff32ffb2a5dac077cfff67deeBehdad Esfahbod vis_clusters[i] = vis_clusters[i - 1]; 4325c299343118d1eaff32ffb2a5dac077cfff67deeBehdad Esfahbod } else { 4335c299343118d1eaff32ffb2a5dac077cfff67deeBehdad Esfahbod for (int i = glyphs_len - 2; i >= 0; i--) 4348e7beba7c3b3dea3cb3b7e280c5aab4f13b92d31Behdad Esfahbod if (vis_clusters[i] == -1) 4355c299343118d1eaff32ffb2a5dac077cfff67deeBehdad Esfahbod vis_clusters[i] = vis_clusters[i + 1]; 4365c299343118d1eaff32ffb2a5dac077cfff67deeBehdad Esfahbod } 4370fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 4380fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod#undef utf16_index 4390fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 4400fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod buffer->ensure (glyphs_len); 4410fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod if (buffer->in_error) 44202aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod FAIL ("Buffer in error"); 4430fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 44402aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod#undef FAIL 4450fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 4460fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod /* Set glyph infos */ 447d753ac78da5619a0a545cdaf7a8e65787e996570Behdad Esfahbod buffer->len = 0; 4480fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod for (unsigned int i = 0; i < glyphs_len; i++) 4490fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod { 450d753ac78da5619a0a545cdaf7a8e65787e996570Behdad Esfahbod hb_glyph_info_t *info = &buffer->info[buffer->len++]; 4510fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 4520fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod info->codepoint = glyphs[i]; 4530fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod info->cluster = vis_clusters[i]; 4540fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 4550fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod /* The rest is crap. Let's store position info there for now. */ 4560fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod info->mask = advances[i]; 4570fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod info->var1.u32 = offsets[i].du; 4580fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod info->var2.u32 = offsets[i].dv; 4590fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod } 4600fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 4610fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod /* Set glyph positions */ 4620fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod buffer->clear_positions (); 4630fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod for (unsigned int i = 0; i < glyphs_len; i++) 4640fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod { 4650fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod hb_glyph_info_t *info = &buffer->info[i]; 4660fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod hb_glyph_position_t *pos = &buffer->pos[i]; 4670fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 4680fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod /* TODO vertical */ 4690fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod pos->x_advance = info->mask; 4700fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod pos->x_offset = info->var1.u32; 4710fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod pos->y_offset = info->var2.u32; 4720fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod } 4730fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 4740fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod /* Wow, done! */ 4750594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return true; 4760fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod} 4770fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 4780fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 479