hb-uniscribe.cc revision 5b95c148cc485f79fd7018bc4520b4cb5f728a18
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 280fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 29027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod#define HB_SHAPER uniscribe 30027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod#include "hb-shaper-impl-private.hh" 310fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 32b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod#include <windows.h> 33b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod#include <usp10.h> 34b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod 35b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbodtypedef ULONG WIN_ULONG; 36b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod 370fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod#include "hb-uniscribe.h" 380fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 397a750ac33ec482e2c4856c19ea607f3563741c24Behdad Esfahbod#include "hb-ot-name-table.hh" 400fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod#include "hb-ot-tag.h" 410fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 420fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 430fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod#ifndef HB_DEBUG_UNISCRIBE 440fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod#define HB_DEBUG_UNISCRIBE (HB_DEBUG+0) 450fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod#endif 460fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 470fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 480fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod/* 490fbb2dc83132a89201ad8b56c6909610437d2da0Behdad EsfahbodDWORD GetFontData( 500fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod __in HDC hdc, 510fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod __in DWORD dwTable, 520fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod __in DWORD dwOffset, 530fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod __out LPVOID lpvBuffer, 540fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod __in DWORD cbData 550fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod); 560fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod*/ 570fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 58892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbodstatic bool 590fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbodpopulate_log_font (LOGFONTW *lf, 60892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod hb_font_t *font) 610fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod{ 620fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod memset (lf, 0, sizeof (*lf)); 633fd2b5bece28c81e3e379352f09eee39d19ac372Behdad Esfahbod lf->lfHeight = -font->y_scale; 64dbffa4c83d29c689ee4cd8a1c53e84521028c711Behdad Esfahbod lf->lfCharSet = DEFAULT_CHARSET; 650fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 66892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod hb_blob_t *blob = Sanitizer<name>::sanitize (hb_face_reference_table (font->face, HB_TAG ('n','a','m','e'))); 67892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod const name *name_table = Sanitizer<name>::lock_instance (blob); 68892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod unsigned int len = name_table->get_name (3, 1, 0x409, 4, 69892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod lf->lfFaceName, 70892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod sizeof (lf->lfFaceName[0]) * LF_FACESIZE) 71892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod / sizeof (lf->lfFaceName[0]); 72826e22732dd8697600a1392f48af21b7b3ce6271Behdad Esfahbod hb_blob_destroy (blob); 73826e22732dd8697600a1392f48af21b7b3ce6271Behdad Esfahbod 74892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod if (unlikely (!len)) { 75892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod DEBUG_MSG (UNISCRIBE, NULL, "Didn't find English name table entry"); 760594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return false; 77892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod } 78892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod if (unlikely (len >= LF_FACESIZE)) { 79892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod DEBUG_MSG (UNISCRIBE, NULL, "Font name too long"); 800594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return false; 81892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod } 82e9c71fab30fd1d5b163c8a072f9e2d3eb8ba3a92Behdad Esfahbod 83892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod for (unsigned int i = 0; i < len; i++) 84892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod lf->lfFaceName[i] = hb_be_uint16 (lf->lfFaceName[i]); 85892eb2e462b40451b8f73879eab66310d884386aBehdad Esfahbod lf->lfFaceName[len] = 0; 86e9c71fab30fd1d5b163c8a072f9e2d3eb8ba3a92Behdad Esfahbod 870594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return true; 880fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod} 890fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 90bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod 91027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod/* 92027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod * shaper face data 93027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod */ 9471388b3ee71c7d3b79f842db7588bd683691797cBehdad Esfahbod 95027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbodstruct hb_uniscribe_shaper_face_data_t { 96bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod HANDLE fh; 97027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod}; 98bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod 99027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbodhb_uniscribe_shaper_face_data_t * 100027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod_hb_uniscribe_shaper_face_data_create (hb_face_t *face) 101bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod{ 102027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod hb_uniscribe_shaper_face_data_t *data = (hb_uniscribe_shaper_face_data_t *) calloc (1, sizeof (hb_uniscribe_shaper_face_data_t)); 103bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod if (unlikely (!data)) 104027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod return NULL; 105a3bd8a0e1862212a2d4141b973039bd000a3054fBehdad Esfahbod 106bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod hb_blob_t *blob = hb_face_reference_blob (face); 107bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod unsigned int blob_length; 108bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod const char *blob_data = hb_blob_get_data (blob, &blob_length); 109bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod if (unlikely (!blob_length)) 110bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod DEBUG_MSG (UNISCRIBE, face, "Face has empty blob"); 111bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod 112bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod DWORD num_fonts_installed; 113bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod data->fh = AddFontMemResourceEx ((void *) blob_data, blob_length, 0, &num_fonts_installed); 114bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod hb_blob_destroy (blob); 115027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod if (unlikely (!data->fh)) { 116bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod DEBUG_MSG (UNISCRIBE, face, "Face AddFontMemResourceEx() failed"); 117027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod free (data); 118027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod return NULL; 119bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod } 120bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod 121bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod return data; 122bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod} 123bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod 124027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbodvoid 125027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod_hb_uniscribe_shaper_face_data_destroy (hb_uniscribe_shaper_face_data_t *data) 126027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod{ 127027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod if (data->fh) 128027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod RemoveFontMemResourceEx (data->fh); 129027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod free (data); 130027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod} 131bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod 132027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod 133027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod/* 134027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod * shaper font data 135027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod */ 136027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod 137027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbodstruct hb_uniscribe_shaper_font_data_t { 138bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod HDC hdc; 139d6660356dd81358033743f72d8a5fbf2fc70eaf7Behdad Esfahbod LOGFONTW log_font; 140bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod HFONT hfont; 141bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod SCRIPT_CACHE script_cache; 142027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod}; 143bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod 144027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbodhb_uniscribe_shaper_font_data_t * 145027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod_hb_uniscribe_shaper_font_data_create (hb_font_t *font) 146027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod{ 147027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod hb_uniscribe_shaper_font_data_t * data = (hb_uniscribe_shaper_font_data_t *) calloc (1, sizeof (hb_uniscribe_shaper_font_data_t)); 148027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod if (unlikely (!data)) 149027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod return NULL; 150027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod 151027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod data->hdc = GetDC (NULL); 152027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod 153027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod if (unlikely (!populate_log_font (&data->log_font, font))) { 154027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod DEBUG_MSG (UNISCRIBE, font, "Font populate_log_font() failed"); 155027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod _hb_uniscribe_shaper_font_data_destroy (data); 156027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod return NULL; 157027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod } 158027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod 159027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod data->hfont = CreateFontIndirectW (&data->log_font); 160027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod if (unlikely (!data->hfont)) { 161027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod DEBUG_MSG (UNISCRIBE, font, "Font CreateFontIndirectW() failed"); 162027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod _hb_uniscribe_shaper_font_data_destroy (data); 163027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod return NULL; 164027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod } 165027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod 166027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod if (!SelectObject (data->hdc, data->hfont)) { 167027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod DEBUG_MSG (UNISCRIBE, font, "Font SelectObject() failed"); 168027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod _hb_uniscribe_shaper_font_data_destroy (data); 169027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod return NULL; 170027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod } 171027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod 172027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod return data; 173027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod} 174027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod 175027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbodvoid 176027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod_hb_uniscribe_shaper_font_data_destroy (hb_uniscribe_shaper_font_data_t *data) 177bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod{ 178bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod if (data->hdc) 179bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod ReleaseDC (NULL, data->hdc); 180bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod if (data->hfont) 181bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod DeleteObject (data->hfont); 182bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod if (data->script_cache) 183bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod ScriptFreeCache (&data->script_cache); 184bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod free (data); 185bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod} 186bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod 187027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod 188027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod/* 189027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod * shaper shape_plan data 190027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod */ 191027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod 192027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbodstruct hb_uniscribe_shaper_shape_plan_data_t {}; 193027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod 194027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbodhb_uniscribe_shaper_shape_plan_data_t * 1955b95c148cc485f79fd7018bc4520b4cb5f728a18Behdad Esfahbod_hb_uniscribe_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan, 1965b95c148cc485f79fd7018bc4520b4cb5f728a18Behdad Esfahbod const hb_feature_t *user_features, 1975b95c148cc485f79fd7018bc4520b4cb5f728a18Behdad Esfahbod unsigned int num_user_features) 198bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod{ 199027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod return (hb_uniscribe_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED; 200027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod} 201bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod 202027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbodvoid 203027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod_hb_uniscribe_shaper_shape_plan_data_destroy (hb_uniscribe_shaper_shape_plan_data_t *data) 204027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod{ 205027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod} 206bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod 207bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod 208027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod/* 209027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod * shaper 210027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod */ 211027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbodstatic hb_user_data_key_t hb_uniscribe_data_key; 212027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod 213027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbodstatic hb_uniscribe_shaper_face_data_t * 214027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod_hb_uniscribe_face_get_data (hb_face_t *face) 215027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod{ 216027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod hb_uniscribe_shaper_face_data_t *data = (hb_uniscribe_shaper_face_data_t *) hb_face_get_user_data (face, &hb_uniscribe_data_key); 217027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod if (likely (data)) return data; 218027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod 219027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod data = _hb_uniscribe_shaper_face_data_create (face); 220027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod if (!data) return NULL; 221027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod 222027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod if (unlikely (!hb_face_set_user_data (face, &hb_uniscribe_data_key, data, 223027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod (hb_destroy_func_t) _hb_uniscribe_shaper_face_data_destroy, 224027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod false))) 225027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod { 226027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod _hb_uniscribe_shaper_face_data_destroy (data); 227027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod data = (hb_uniscribe_shaper_face_data_t *) hb_face_get_user_data (face, &hb_uniscribe_data_key); 228bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod } 229bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod 230027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod return data; 231027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod} 232027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod 233027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod 234027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbodstatic hb_uniscribe_shaper_font_data_t * 235027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod_hb_uniscribe_font_get_data (hb_font_t *font) 236027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod{ 237027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod hb_uniscribe_shaper_font_data_t *data = (hb_uniscribe_shaper_font_data_t *) hb_font_get_user_data (font, &hb_uniscribe_data_key); 238027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod if (likely (data)) return data; 239027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod 240027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod data = _hb_uniscribe_shaper_font_data_create (font); 241027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod if (unlikely (!data)) 242027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod return NULL; 243027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod 2445072934c35bddc23d6bcb07a41010da51eb1b090Behdad Esfahbod if (unlikely (!hb_font_set_user_data (font, &hb_uniscribe_data_key, data, 245027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod (hb_destroy_func_t) _hb_uniscribe_shaper_font_data_destroy, 2460594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod false))) 247bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod { 248027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod _hb_uniscribe_shaper_font_data_destroy (data); 249027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod data = (hb_uniscribe_shaper_font_data_t *) hb_font_get_user_data (font, &hb_uniscribe_data_key); 250bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod } 251bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod 252bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod return data; 253bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod} 254bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod 255d6660356dd81358033743f72d8a5fbf2fc70eaf7Behdad EsfahbodLOGFONTW * 256d6660356dd81358033743f72d8a5fbf2fc70eaf7Behdad Esfahbodhb_uniscribe_font_get_logfontw (hb_font_t *font) 257d6660356dd81358033743f72d8a5fbf2fc70eaf7Behdad Esfahbod{ 258027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod hb_uniscribe_shaper_font_data_t *font_data = _hb_uniscribe_font_get_data (font); 259d6660356dd81358033743f72d8a5fbf2fc70eaf7Behdad Esfahbod if (unlikely (!font_data)) 260d6660356dd81358033743f72d8a5fbf2fc70eaf7Behdad Esfahbod return NULL; 261d6660356dd81358033743f72d8a5fbf2fc70eaf7Behdad Esfahbod return &font_data->log_font; 262d6660356dd81358033743f72d8a5fbf2fc70eaf7Behdad Esfahbod} 263d6660356dd81358033743f72d8a5fbf2fc70eaf7Behdad Esfahbod 264d6660356dd81358033743f72d8a5fbf2fc70eaf7Behdad EsfahbodHFONT 265d6660356dd81358033743f72d8a5fbf2fc70eaf7Behdad Esfahbodhb_uniscribe_font_get_hfont (hb_font_t *font) 266d6660356dd81358033743f72d8a5fbf2fc70eaf7Behdad Esfahbod{ 267027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod hb_uniscribe_shaper_font_data_t *font_data = _hb_uniscribe_font_get_data (font); 268d6660356dd81358033743f72d8a5fbf2fc70eaf7Behdad Esfahbod if (unlikely (!font_data)) 269d6660356dd81358033743f72d8a5fbf2fc70eaf7Behdad Esfahbod return 0; 270d6660356dd81358033743f72d8a5fbf2fc70eaf7Behdad Esfahbod return font_data->hfont; 271d6660356dd81358033743f72d8a5fbf2fc70eaf7Behdad Esfahbod} 272d6660356dd81358033743f72d8a5fbf2fc70eaf7Behdad Esfahbod 273bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod 27402aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbodhb_bool_t 275bd26b4d21f59312805d294f46f15182adbcc47daBehdad Esfahbod_hb_uniscribe_shape (hb_shape_plan_t *shape_plan, 276bd26b4d21f59312805d294f46f15182adbcc47daBehdad Esfahbod hb_font_t *font, 2776bd9b479b8b2befbb0847282e93beade197c8038Behdad Esfahbod hb_buffer_t *buffer, 2786bd9b479b8b2befbb0847282e93beade197c8038Behdad Esfahbod const hb_feature_t *features, 2796bd9b479b8b2befbb0847282e93beade197c8038Behdad Esfahbod unsigned int num_features) 2800fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod{ 28102aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod buffer->guess_properties (); 28202aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod 283bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod#define FAIL(...) \ 284bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod HB_STMT_START { \ 285bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod DEBUG_MSG (UNISCRIBE, NULL, __VA_ARGS__); \ 2860594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return false; \ 287bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod } HB_STMT_END; 288bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod 289027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod hb_uniscribe_shaper_face_data_t *face_data = _hb_uniscribe_face_get_data (font->face); 290a9057eb3f38018faa1ece53c4aaeeba798b41fd1Behdad Esfahbod if (unlikely (!face_data->fh)) 291bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod FAIL ("Couldn't get face data"); 292bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod 293027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod hb_uniscribe_shaper_font_data_t *font_data = _hb_uniscribe_font_get_data (font); 294a9057eb3f38018faa1ece53c4aaeeba798b41fd1Behdad Esfahbod if (unlikely (!font_data->hfont)) 295bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod FAIL ("Couldn't get font font"); 2960fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 29702aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod if (unlikely (!buffer->len)) 2980594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return true; 2990fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 300bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod HRESULT hr; 301bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1Behdad Esfahbod 3020fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbodretry: 3030fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 3040fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod unsigned int scratch_size; 3050fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod char *scratch = (char *) buffer->get_scratch_buffer (&scratch_size); 3060fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 3070fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod /* Allocate char buffers; they all fit */ 3080fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 3090fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod#define ALLOCATE_ARRAY(Type, name, len) \ 3100fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod Type *name = (Type *) scratch; \ 31191e721ea8693205f4f738bca97a5055ee75cf463Behdad Esfahbod scratch += (len) * sizeof ((name)[0]); \ 31291e721ea8693205f4f738bca97a5055ee75cf463Behdad Esfahbod scratch_size -= (len) * sizeof ((name)[0]); 3130fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 3140fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod#define utf16_index() var1.u32 3150fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 3160fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod WCHAR *pchars = (WCHAR *) scratch; 3170fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod unsigned int chars_len = 0; 3180fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod for (unsigned int i = 0; i < buffer->len; i++) { 3190fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod hb_codepoint_t c = buffer->info[i].codepoint; 3200fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod buffer->info[i].utf16_index() = chars_len; 3210fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod if (likely (c < 0x10000)) 3220fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod pchars[chars_len++] = c; 3230fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod else if (unlikely (c >= 0x110000)) 3240fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod pchars[chars_len++] = 0xFFFD; 3250fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod else { 3260fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod pchars[chars_len++] = 0xD800 + ((c - 0x10000) >> 10); 3270fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod pchars[chars_len++] = 0xDC00 + ((c - 0x10000) & ((1 << 10) - 1)); 3280fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod } 3290fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod } 3300fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 3310fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod ALLOCATE_ARRAY (WCHAR, wchars, chars_len); 3320fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod ALLOCATE_ARRAY (WORD, log_clusters, chars_len); 3330fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod ALLOCATE_ARRAY (SCRIPT_CHARPROP, char_props, chars_len); 3340fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 3350fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod /* On Windows, we don't care about alignment...*/ 3360fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod unsigned int glyphs_size = scratch_size / (sizeof (WORD) + 3370fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod sizeof (SCRIPT_GLYPHPROP) + 3380fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod sizeof (int) + 3390fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod sizeof (GOFFSET) + 3400fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod sizeof (uint32_t)); 3410fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 3420fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod ALLOCATE_ARRAY (WORD, glyphs, glyphs_size); 3430fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod ALLOCATE_ARRAY (SCRIPT_GLYPHPROP, glyph_props, glyphs_size); 3440fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod ALLOCATE_ARRAY (int, advances, glyphs_size); 3450fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod ALLOCATE_ARRAY (GOFFSET, offsets, glyphs_size); 3460fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod ALLOCATE_ARRAY (uint32_t, vis_clusters, glyphs_size); 3470fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 34891e721ea8693205f4f738bca97a5055ee75cf463Behdad Esfahbod#undef ALLOCATE_ARRAY 3490fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 350872969126756456a69bf958f3df6e56a26e57b0aBehdad Esfahbod#define MAX_ITEMS 256 3510fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 3520fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod SCRIPT_ITEM items[MAX_ITEMS + 1]; 3535c299343118d1eaff32ffb2a5dac077cfff67deeBehdad Esfahbod SCRIPT_CONTROL bidi_control = {0}; 3540fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod SCRIPT_STATE bidi_state = {0}; 355b492299eb3c398701557e452f6c2c9bd370fbbf3Behdad Esfahbod WIN_ULONG script_tags[MAX_ITEMS]; 3560fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod int item_count; 3570fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 3585c299343118d1eaff32ffb2a5dac077cfff67deeBehdad Esfahbod /* MinGW32 doesn't define fMergeNeutralItems, so we bruteforce */ 3590594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod //bidi_control.fMergeNeutralItems = true; 3605c299343118d1eaff32ffb2a5dac077cfff67deeBehdad Esfahbod *(uint32_t*)&bidi_control |= 1<<24; 3615c299343118d1eaff32ffb2a5dac077cfff67deeBehdad Esfahbod 3620fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod bidi_state.uBidiLevel = HB_DIRECTION_IS_FORWARD (buffer->props.direction) ? 0 : 1; 36329eac8f591fdb86f1c4fdc0a6ab63910ff286b84Behdad Esfahbod bidi_state.fOverrideDirection = 1; 3640fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 3650fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod hr = ScriptItemizeOpenType (wchars, 3660fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod chars_len, 3670fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod MAX_ITEMS, 3685c299343118d1eaff32ffb2a5dac077cfff67deeBehdad Esfahbod &bidi_control, 3690fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod &bidi_state, 3700fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod items, 3710fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod script_tags, 3720fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod &item_count); 3730fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod if (unlikely (FAILED (hr))) 3742eb474afb4a09f4da8f14b444bd6066769010224Behdad Esfahbod FAIL ("ScriptItemizeOpenType() failed: 0x%08xL", hr); 3750fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 3760fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod#undef MAX_ITEMS 3770fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 3780fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod int *range_char_counts = NULL; 3790fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod TEXTRANGE_PROPERTIES **range_properties = NULL; 3800fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod int range_count = 0; 3810fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod if (num_features) { 3825c299343118d1eaff32ffb2a5dac077cfff67deeBehdad Esfahbod /* TODO setup ranges */ 3830fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod } 3840fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 385fcd6f5326166e993b8f5222efbaffe916da98f0aBehdad Esfahbod OPENTYPE_TAG language_tag = hb_uint32_swap (hb_ot_tag_from_language (buffer->props.language)); 3860fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 3870fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod unsigned int glyphs_offset = 0; 3880fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod unsigned int glyphs_len; 389b069c3c31bfbbf160eb897c7474be9ea90ed4fc1Behdad Esfahbod bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction); 390b069c3c31bfbbf160eb897c7474be9ea90ed4fc1Behdad Esfahbod for (unsigned int j = 0; j < item_count; j++) 3910fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod { 3920dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod unsigned int i = backward ? item_count - 1 - j : j; 3930dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod unsigned int chars_offset = items[i].iCharPos; 3940dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod unsigned int item_chars_len = items[i + 1].iCharPos - chars_offset; 3950dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod 396e9c0f152a38cb2e76650a3e43f7fdcda266af696Behdad Esfahbod retry_shape: 3970dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod hr = ScriptShapeOpenType (font_data->hdc, 3980dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod &font_data->script_cache, 3990dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod &items[i].a, 400e9c0f152a38cb2e76650a3e43f7fdcda266af696Behdad Esfahbod script_tags[i], 4010dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod language_tag, 4020dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod range_char_counts, 4030dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod range_properties, 4040dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod range_count, 4050dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod wchars + chars_offset, 4060dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod item_chars_len, 4070dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod glyphs_size - glyphs_offset, 4080dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod /* out */ 4090dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod log_clusters + chars_offset, 4100dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod char_props + chars_offset, 4110dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod glyphs + glyphs_offset, 4120dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod glyph_props + glyphs_offset, 4130dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod (int *) &glyphs_len); 4140dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod 4150dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod if (unlikely (items[i].a.fNoGlyphIndex)) 4160dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod FAIL ("ScriptShapeOpenType() set fNoGlyphIndex"); 4170dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod if (unlikely (hr == E_OUTOFMEMORY)) 4180dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod { 4190dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod buffer->ensure (buffer->allocated * 2); 4200dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod if (buffer->in_error) 4210dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod FAIL ("Buffer resize failed"); 4220dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod goto retry; 4230dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod } 4240dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod if (unlikely (hr == USP_E_SCRIPT_NOT_IN_FONT)) 425e9c0f152a38cb2e76650a3e43f7fdcda266af696Behdad Esfahbod { 426e9c0f152a38cb2e76650a3e43f7fdcda266af696Behdad Esfahbod if (items[i].a.eScript == SCRIPT_UNDEFINED) 427e9c0f152a38cb2e76650a3e43f7fdcda266af696Behdad Esfahbod FAIL ("ScriptShapeOpenType() failed: Font doesn't support script"); 428e9c0f152a38cb2e76650a3e43f7fdcda266af696Behdad Esfahbod items[i].a.eScript = SCRIPT_UNDEFINED; 429e9c0f152a38cb2e76650a3e43f7fdcda266af696Behdad Esfahbod goto retry_shape; 430e9c0f152a38cb2e76650a3e43f7fdcda266af696Behdad Esfahbod } 4310dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod if (unlikely (FAILED (hr))) 432e9c0f152a38cb2e76650a3e43f7fdcda266af696Behdad Esfahbod { 4330dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod FAIL ("ScriptShapeOpenType() failed: 0x%08xL", hr); 434e9c0f152a38cb2e76650a3e43f7fdcda266af696Behdad Esfahbod } 435e9c0f152a38cb2e76650a3e43f7fdcda266af696Behdad Esfahbod 436e9c0f152a38cb2e76650a3e43f7fdcda266af696Behdad Esfahbod for (unsigned int j = chars_offset; j < chars_offset + item_chars_len; j++) 437e9c0f152a38cb2e76650a3e43f7fdcda266af696Behdad Esfahbod log_clusters[j] += glyphs_offset; 4380dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod 4390dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod hr = ScriptPlaceOpenType (font_data->hdc, 4400dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod &font_data->script_cache, 4410dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod &items[i].a, 442e9c0f152a38cb2e76650a3e43f7fdcda266af696Behdad Esfahbod script_tags[i], 4430dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod language_tag, 4440dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod range_char_counts, 4450dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod range_properties, 4460dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod range_count, 4470dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod wchars + chars_offset, 4480dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod log_clusters + chars_offset, 4490dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod char_props + chars_offset, 4500dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod item_chars_len, 4510dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod glyphs + glyphs_offset, 4520dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod glyph_props + glyphs_offset, 4530dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod glyphs_len, 4540dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod /* out */ 4550dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod advances + glyphs_offset, 4560dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod offsets + glyphs_offset, 4570dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod NULL); 4580dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod if (unlikely (FAILED (hr))) 4590dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod FAIL ("ScriptPlaceOpenType() failed: 0x%08xL", hr); 4600dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod 4610dd86f9f6849d82d60a99e66b6928795cfb2a3c7Behdad Esfahbod glyphs_offset += glyphs_len; 4620fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod } 4630fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod glyphs_len = glyphs_offset; 4640fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 4650fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod /* Ok, we've got everything we need, now compose output buffer, 4660fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod * very, *very*, carefully! */ 4670fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 4680fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod /* Calculate visual-clusters. That's what we ship. */ 4695c299343118d1eaff32ffb2a5dac077cfff67deeBehdad Esfahbod for (unsigned int i = 0; i < glyphs_len; i++) 4705c299343118d1eaff32ffb2a5dac077cfff67deeBehdad Esfahbod vis_clusters[i] = -1; 471577326b86af80cc137eea81f4cc1e30adf9232b1Behdad Esfahbod for (unsigned int i = 0; i < buffer->len; i++) { 472577326b86af80cc137eea81f4cc1e30adf9232b1Behdad Esfahbod uint32_t *p = &vis_clusters[log_clusters[buffer->info[i].utf16_index()]]; 473577326b86af80cc137eea81f4cc1e30adf9232b1Behdad Esfahbod *p = MIN (*p, buffer->info[i].cluster); 474577326b86af80cc137eea81f4cc1e30adf9232b1Behdad Esfahbod } 475b069c3c31bfbbf160eb897c7474be9ea90ed4fc1Behdad Esfahbod if (!backward) { 4765c299343118d1eaff32ffb2a5dac077cfff67deeBehdad Esfahbod for (unsigned int i = 1; i < glyphs_len; i++) 4778e7beba7c3b3dea3cb3b7e280c5aab4f13b92d31Behdad Esfahbod if (vis_clusters[i] == -1) 4785c299343118d1eaff32ffb2a5dac077cfff67deeBehdad Esfahbod vis_clusters[i] = vis_clusters[i - 1]; 4795c299343118d1eaff32ffb2a5dac077cfff67deeBehdad Esfahbod } else { 4805c299343118d1eaff32ffb2a5dac077cfff67deeBehdad Esfahbod for (int i = glyphs_len - 2; i >= 0; i--) 4818e7beba7c3b3dea3cb3b7e280c5aab4f13b92d31Behdad Esfahbod if (vis_clusters[i] == -1) 4825c299343118d1eaff32ffb2a5dac077cfff67deeBehdad Esfahbod vis_clusters[i] = vis_clusters[i + 1]; 4835c299343118d1eaff32ffb2a5dac077cfff67deeBehdad Esfahbod } 4840fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 4850fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod#undef utf16_index 4860fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 4870fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod buffer->ensure (glyphs_len); 4880fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod if (buffer->in_error) 48902aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod FAIL ("Buffer in error"); 4900fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 49102aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod#undef FAIL 4920fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 4930fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod /* Set glyph infos */ 494d753ac78da5619a0a545cdaf7a8e65787e996570Behdad Esfahbod buffer->len = 0; 4950fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod for (unsigned int i = 0; i < glyphs_len; i++) 4960fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod { 497d753ac78da5619a0a545cdaf7a8e65787e996570Behdad Esfahbod hb_glyph_info_t *info = &buffer->info[buffer->len++]; 4980fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 4990fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod info->codepoint = glyphs[i]; 5000fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod info->cluster = vis_clusters[i]; 5010fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 5020fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod /* The rest is crap. Let's store position info there for now. */ 5030fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod info->mask = advances[i]; 5040fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod info->var1.u32 = offsets[i].du; 5050fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod info->var2.u32 = offsets[i].dv; 5060fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod } 5070fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 5080fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod /* Set glyph positions */ 5090fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod buffer->clear_positions (); 5100fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod for (unsigned int i = 0; i < glyphs_len; i++) 5110fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod { 5120fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod hb_glyph_info_t *info = &buffer->info[i]; 5130fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod hb_glyph_position_t *pos = &buffer->pos[i]; 5140fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 5150fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod /* TODO vertical */ 5160fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod pos->x_advance = info->mask; 5170fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod pos->x_offset = info->var1.u32; 5180fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod pos->y_offset = info->var2.u32; 5190fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod } 5200fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 5210fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod /* Wow, done! */ 5220594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod return true; 5230fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod} 5240fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 5250fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 526