hb-uniscribe.cc revision 0fbb2dc83132a89201ad8b56c6909610437d2da0
10fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod/* 20fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod * Copyright © 2011 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 270fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod#define _WIN32_WINNT 0x0500 280fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 290fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod#include "hb-private.hh" 300fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 310fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod#include "hb-uniscribe.h" 320fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 330fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod#include "hb-ot-tag.h" 340fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 350fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod#include "hb-font-private.hh" 360fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 370fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod#include "hb-buffer-private.hh" 380fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 390fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod#include <windows.h> 400fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod#include <usp10.h> 410fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 420fbb2dc83132a89201ad8b56c6909610437d2da0Behdad EsfahbodHB_BEGIN_DECLS 430fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 440fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 450fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod#ifndef HB_DEBUG_UNISCRIBE 460fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod#define HB_DEBUG_UNISCRIBE (HB_DEBUG+0) 470fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod#endif 480fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 490fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 500fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod/* 510fbb2dc83132a89201ad8b56c6909610437d2da0Behdad EsfahbodDWORD GetFontData( 520fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod __in HDC hdc, 530fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod __in DWORD dwTable, 540fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod __in DWORD dwOffset, 550fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod __out LPVOID lpvBuffer, 560fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod __in DWORD cbData 570fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod); 580fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod*/ 590fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 600fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbodstatic void 610fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbodfallback_shape (hb_font_t *font, 620fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod hb_buffer_t *buffer) 630fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod{ 640fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod DEBUG_MSG (UNISCRIBE, NULL, "Fallback shaper invoked"); 650fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod} 660fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 670fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbodstatic void 680fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbodpopulate_log_font (LOGFONTW *lf, 690fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod HDC hdc, 700fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod hb_font_t *font, 710fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod hb_blob_t *blob) 720fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod{ 730fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod memset (lf, 0, sizeof (*lf)); 740fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod int dpi = GetDeviceCaps (hdc, LOGPIXELSY); 750fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod lf->lfHeight = MulDiv (font->x_scale, dpi, 72); 760fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 770fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod WCHAR family_name[] = {'n','a','z','l','i'}; 780fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod for (unsigned int i = 0; family_name[i] && i < LF_FACESIZE - 1; i++) 790fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod lf->lfFaceName[i] = family_name[i]; 800fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod} 810fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 820fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbodvoid 830fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbodhb_uniscribe_shape (hb_font_t *font, 840fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod hb_buffer_t *buffer, 850fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod const hb_feature_t *features, 860fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod unsigned int num_features) 870fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod{ 880fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod HRESULT hr; 890fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 900fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod if (unlikely (!buffer->len)) { 910fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod fallback: 920fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod fallback_shape (font, buffer); 930fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod } 940fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 950fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbodretry: 960fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 970fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod unsigned int scratch_size; 980fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod char *scratch = (char *) buffer->get_scratch_buffer (&scratch_size); 990fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 1000fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod /* Allocate char buffers; they all fit */ 1010fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 1020fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod#define ALLOCATE_ARRAY(Type, name, len) \ 1030fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod Type *name = (Type *) scratch; \ 1040fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod scratch += len * sizeof (name[0]); \ 1050fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod scratch_size -= len * sizeof (name[0]); 1060fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 1070fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod#define utf16_index() var1.u32 1080fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 1090fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod WCHAR *pchars = (WCHAR *) scratch; 1100fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod unsigned int chars_len = 0; 1110fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod for (unsigned int i = 0; i < buffer->len; i++) { 1120fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod hb_codepoint_t c = buffer->info[i].codepoint; 1130fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod buffer->info[i].utf16_index() = chars_len; 1140fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod if (likely (c < 0x10000)) 1150fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod pchars[chars_len++] = c; 1160fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod else if (unlikely (c >= 0x110000)) 1170fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod pchars[chars_len++] = 0xFFFD; 1180fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod else { 1190fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod pchars[chars_len++] = 0xD800 + ((c - 0x10000) >> 10); 1200fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod pchars[chars_len++] = 0xDC00 + ((c - 0x10000) & ((1 << 10) - 1)); 1210fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod } 1220fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod } 1230fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 1240fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod ALLOCATE_ARRAY (WCHAR, wchars, chars_len); 1250fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod ALLOCATE_ARRAY (WORD, log_clusters, chars_len); 1260fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod ALLOCATE_ARRAY (SCRIPT_CHARPROP, char_props, chars_len); 1270fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 1280fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod /* On Windows, we don't care about alignment...*/ 1290fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod unsigned int glyphs_size = scratch_size / (sizeof (WORD) + 1300fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod sizeof (SCRIPT_GLYPHPROP) + 1310fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod sizeof (int) + 1320fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod sizeof (GOFFSET) + 1330fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod sizeof (uint32_t)); 1340fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 1350fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod ALLOCATE_ARRAY (WORD, glyphs, glyphs_size); 1360fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod ALLOCATE_ARRAY (SCRIPT_GLYPHPROP, glyph_props, glyphs_size); 1370fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod ALLOCATE_ARRAY (int, advances, glyphs_size); 1380fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod ALLOCATE_ARRAY (GOFFSET, offsets, glyphs_size); 1390fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod ALLOCATE_ARRAY (uint32_t, vis_clusters, glyphs_size); 1400fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 1410fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 1420fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod#define FALLBACK(...) \ 1430fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod HB_STMT_START { \ 1440fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod DEBUG_MSG (UNISCRIBE, NULL, __VA_ARGS__); \ 1450fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod goto fallback; \ 1460fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod } HB_STMT_END; 1470fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 1480fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 1490fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod#define MAX_ITEMS 10 1500fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 1510fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod SCRIPT_ITEM items[MAX_ITEMS + 1]; 1520fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod SCRIPT_STATE bidi_state = {0}; 1530fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod ULONG script_tags[MAX_ITEMS]; 1540fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod int item_count; 1550fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 1560fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod bidi_state.uBidiLevel = HB_DIRECTION_IS_FORWARD (buffer->props.direction) ? 0 : 1; 1570fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod bidi_state.fOverrideDirection = 1; 1580fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 1590fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod hr = ScriptItemizeOpenType (wchars, 1600fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod chars_len, 1610fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod MAX_ITEMS, 1620fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod NULL, 1630fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod &bidi_state, 1640fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod items, 1650fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod script_tags, 1660fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod &item_count); 1670fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod if (unlikely (FAILED (hr))) 1680fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod FALLBACK ("ScriptItemizeOpenType() failed: %d", hr); 1690fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 1700fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod#undef MAX_ITEMS 1710fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 1720fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod int *range_char_counts = NULL; 1730fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod TEXTRANGE_PROPERTIES **range_properties = NULL; 1740fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod int range_count = 0; 1750fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod if (num_features) { 1760fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod /* XXX setup ranges */ 1770fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod } 1780fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 1790fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod hb_blob_t *blob = hb_face_get_blob (font->face); 1800fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod unsigned int blob_length; 1810fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod const char *blob_data = hb_blob_get_data (blob, &blob_length); 1820fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod if (unlikely (!blob_length)) { 1830fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod hb_blob_destroy (blob); 1840fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod FALLBACK ("Empty font blob"); 1850fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod } 1860fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 1870fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod DWORD num_fonts_installed; 1880fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod HANDLE fh = AddFontMemResourceEx ((void *) blob_data, blob_length, 0, &num_fonts_installed); 1890fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod if (unlikely (!fh)) { 1900fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod hb_blob_destroy (blob); 1910fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod FALLBACK ("AddFontMemResourceEx() failed"); 1920fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod } 1930fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 1940fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod /* FREE stuff, specially when taking fallback... */ 1950fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 1960fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod HDC hdc = GetDC (NULL); /* XXX The DC should be cached on the face I guess? */ 1970fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 1980fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod LOGFONTW log_font; 1990fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod populate_log_font (&log_font, hdc, font, blob); 2000fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 2010fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod HFONT hfont = CreateFontIndirectW (&log_font); 2020fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod SelectObject (hdc, hfont); 2030fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 2040fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod SCRIPT_CACHE script_cache = NULL; 2050fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod OPENTYPE_TAG language_tag = hb_ot_tag_from_language (buffer->props.language); 2060fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 2070fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod unsigned int glyphs_offset = 0; 2080fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod unsigned int glyphs_len; 2090fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod for (unsigned int i = 0; i < item_count; i++) 2100fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod { 2110fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod unsigned int chars_offset = items[i].iCharPos; 2120fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod unsigned int item_chars_len = items[i + 1].iCharPos - chars_offset; 2130fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod OPENTYPE_TAG script_tag = script_tags[i]; /* XXX buffer->props.script */ 2140fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 2150fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod hr = ScriptShapeOpenType (hdc, 2160fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod &script_cache, 2170fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod &items[i].a, 2180fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod script_tag, 2190fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod language_tag, 2200fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod range_char_counts, 2210fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod range_properties, 2220fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod range_count, 2230fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod wchars + chars_offset, 2240fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod item_chars_len, 2250fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod glyphs_size - glyphs_offset, 2260fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod /* out */ 2270fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod log_clusters + chars_offset, 2280fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod char_props + chars_offset, 2290fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod glyphs + glyphs_offset, 2300fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod glyph_props + glyphs_offset, 2310fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod (int *) &glyphs_len); 2320fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 2330fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod if (unlikely (items[i].a.fNoGlyphIndex)) 2340fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod FALLBACK ("ScriptShapeOpenType() set fNoGlyphIndex"); 2350fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod if (unlikely (hr == E_OUTOFMEMORY)) 2360fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod { 2370fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod buffer->ensure (buffer->allocated * 2); 2380fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod if (buffer->in_error) 2390fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod FALLBACK ("Buffer resize failed"); 2400fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod goto retry; 2410fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod } 2420fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod if (unlikely (FAILED (hr))) 2430fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod FALLBACK ("ScriptShapeOpenType() failed: %d", hr); 2440fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 2450fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod hr = ScriptPlaceOpenType (hdc, 2460fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod &script_cache, 2470fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod &items[i].a, 2480fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod script_tag, 2490fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod language_tag, 2500fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod range_char_counts, 2510fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod range_properties, 2520fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod range_count, 2530fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod wchars + chars_offset, 2540fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod log_clusters + chars_offset, 2550fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod char_props + chars_offset, 2560fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod item_chars_len, 2570fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod glyphs + glyphs_offset, 2580fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod glyph_props + glyphs_offset, 2590fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod glyphs_len, 2600fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod /* out */ 2610fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod advances + glyphs_offset, 2620fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod offsets + glyphs_offset, 2630fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod NULL); 2640fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod if (unlikely (FAILED (hr))) 2650fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod FALLBACK ("ScriptPlaceOpenType() failed: %d", hr); 2660fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 2670fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod glyphs_offset += glyphs_len; 2680fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod } 2690fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod glyphs_len = glyphs_offset; 2700fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 2710fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod ReleaseDC (NULL, hdc); 2720fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod DeleteObject (hfont); 2730fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod RemoveFontMemResourceEx (fh); 2740fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 2750fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod /* Ok, we've got everything we need, now compose output buffer, 2760fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod * very, *very*, carefully! */ 2770fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 2780fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod /* Calculate visual-clusters. That's what we ship. */ 2790fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod for (unsigned int i = 0; i < buffer->len; i++) 2800fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod vis_clusters[log_clusters[buffer->info[i].utf16_index()]] = buffer->info[i].cluster; 2810fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod for (unsigned int i = 1; i < glyphs_len; i++) 2820fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod if (!glyph_props[i].sva.fClusterStart) 2830fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod vis_clusters[i] = vis_clusters[i - 1]; 2840fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 2850fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod#undef utf16_index 2860fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 2870fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod buffer->ensure (glyphs_len); 2880fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod if (buffer->in_error) 2890fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod FALLBACK ("Buffer in error"); 2900fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 2910fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod#undef FALLBACK 2920fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 2930fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod /* Set glyph infos */ 2940fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod for (unsigned int i = 0; i < glyphs_len; i++) 2950fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod { 2960fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod hb_glyph_info_t *info = &buffer->info[i]; 2970fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 2980fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod info->codepoint = glyphs[i]; 2990fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod info->cluster = vis_clusters[i]; 3000fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 3010fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod /* The rest is crap. Let's store position info there for now. */ 3020fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod info->mask = advances[i]; 3030fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod info->var1.u32 = offsets[i].du; 3040fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod info->var2.u32 = offsets[i].dv; 3050fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod } 3060fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 3070fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod /* Set glyph positions */ 3080fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod buffer->clear_positions (); 3090fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod for (unsigned int i = 0; i < glyphs_len; i++) 3100fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod { 3110fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod hb_glyph_info_t *info = &buffer->info[i]; 3120fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod hb_glyph_position_t *pos = &buffer->pos[i]; 3130fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 3140fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod /* TODO vertical */ 3150fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod pos->x_advance = info->mask; 3160fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod pos->x_offset = info->var1.u32; 3170fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod pos->y_offset = info->var2.u32; 3180fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod } 3190fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 3200fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod /* Wow, done! */ 3210fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod return; 3220fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod} 3230fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 3240fbb2dc83132a89201ad8b56c6909610437d2da0Behdad Esfahbod 3250fbb2dc83132a89201ad8b56c6909610437d2da0Behdad EsfahbodHB_END_DECLS 326