/** * SECTION:hb-uniscribe * @title: hb-uniscribe * @short_description: Windows integration * @include: hb-uniscribe.h * * Functions for using HarfBuzz with Windows fonts.
**/
typedef HRESULT (WINAPI *SIOT) /*ScriptItemizeOpenType*/( const WCHAR *pwcInChars, int cInChars, int cMaxItems, const SCRIPT_CONTROL *psControl, const SCRIPT_STATE *psState,
SCRIPT_ITEM *pItems,
OPENTYPE_TAG *pScriptTags, int *pcItems
);
typedef HRESULT (WINAPI *SSOT) /*ScriptShapeOpenType*/(
HDC hdc,
SCRIPT_CACHE *psc,
SCRIPT_ANALYSIS *psa,
OPENTYPE_TAG tagScript,
OPENTYPE_TAG tagLangSys, int *rcRangeChars,
TEXTRANGE_PROPERTIES **rpRangeProperties, int cRanges, const WCHAR *pwcChars, int cChars, int cMaxGlyphs,
WORD *pwLogClust,
SCRIPT_CHARPROP *pCharProps,
WORD *pwOutGlyphs,
SCRIPT_GLYPHPROP *pOutGlyphProps, int *pcGlyphs
);
typedef HRESULT (WINAPI *SPOT) /*ScriptPlaceOpenType*/(
HDC hdc,
SCRIPT_CACHE *psc,
SCRIPT_ANALYSIS *psa,
OPENTYPE_TAG tagScript,
OPENTYPE_TAG tagLangSys, int *rcRangeChars,
TEXTRANGE_PROPERTIES **rpRangeProperties, int cRanges, const WCHAR *pwcChars,
WORD *pwLogClust,
SCRIPT_CHARPROP *pCharProps, int cChars, const WORD *pwGlyphs, const SCRIPT_GLYPHPROP *pGlyphProps, int cGlyphs, int *piAdvance,
GOFFSET *pGoffset,
ABC *pABC
);
/* face_name should point to a wchar_t[LF_FACESIZE] object. */ staticvoid
_hb_generate_unique_face_name (wchar_t *face_name, unsignedint *plen)
{ /* We'll create a private name for the font from a UUID using a simple,
* somewhat base64-like encoding scheme */ constchar *enc = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-";
UUID id;
UuidCreate ((UUID*) &id);
static_assert ((2 + 3 * (16/2) < LF_FACESIZE), ""); unsignedint name_str_len = 0;
face_name[name_str_len++] = 'F';
face_name[name_str_len++] = '_'; unsignedchar *p = (unsignedchar *) &id; for (unsignedint i = 0; i < 16; i += 2)
{ /* Spread the 16 bits from two bytes of the UUID across three chars of face_name, * using the bits in groups of 5,5,6 to select chars from enc. * This will generate 24 characters; with the 'F_' prefix we already provided, * the name will be 26 chars (plus the NUL terminator), so will always fit within
* face_name (LF_FACESIZE = 32). */
face_name[name_str_len++] = enc[p[i] >> 3];
face_name[name_str_len++] = enc[((p[i] << 2) | (p[i + 1] >> 6)) & 0x1f];
face_name[name_str_len++] = enc[p[i + 1] & 0x3f];
}
face_name[name_str_len] = 0; if (plen)
*plen = name_str_len;
}
/* Destroys blob. */ static hb_blob_t *
_hb_rename_font (hb_blob_t *blob, wchar_t *new_name)
{ /* Create a copy of the font data, with the 'name' table replaced by a * table that names the font with our private F_* name created above. * For simplicity, we just append a new 'name' table and update the * sfnt directory; the original table is left in place, but unused. * * The new table will contain just 5 name IDs: family, style, unique, * full, PS. All of them point to the same name data with our unique name.
*/
int font_size = font->face->get_upem (); /* Default... */ /* No idea if the following is even a good idea. */ if (font->y_ppem)
font_size = font->y_ppem;
void
_hb_uniscribe_shaper_font_data_destroy (hb_uniscribe_font_data_t *data)
{ if (data->hdc)
ReleaseDC (nullptr, data->hdc); if (data->hfont)
DeleteObject (data->hfont); if (data->script_cache)
ScriptFreeCache (&data->script_cache);
hb_free (data);
}
/** * hb_uniscribe_font_get_logfontw: * @font: The #hb_font_t to work upon * * Fetches the LOGFONTW structure that corresponds to the * specified #hb_font_t font. * * Return value: a pointer to the LOGFONTW retrieved *
**/
LOGFONTW *
hb_uniscribe_font_get_logfontw (hb_font_t *font)
{ const hb_uniscribe_font_data_t *data = font->data.uniscribe; return data ? &data->log_font : nullptr;
}
/** * hb_uniscribe_font_get_hfont: * @font: The #hb_font_t to work upon * * Fetches the HFONT handle that corresponds to the * specified #hb_font_t font. * * Return value: the HFONT retreieved *
**/
HFONT
hb_uniscribe_font_get_hfont (hb_font_t *font)
{ const hb_uniscribe_font_data_t *data = font->data.uniscribe; return data ? data->hfont : nullptr;
}
if (num_features)
{ /* Need log_clusters to assign features. */
chars_len = 0; for (unsignedint i = 0; i < buffer->len; i++)
{
hb_codepoint_t c = buffer->info[i].codepoint; unsignedint cluster = buffer->info[i].cluster;
log_clusters[chars_len++] = cluster; if (hb_in_range (c, 0x10000u, 0x10FFFFu))
log_clusters[chars_len++] = cluster; /* Surrogates. */
}
}
/* The -2 in the following is to compensate for possible
* alignment needed after the WORD array. sizeof(WORD) == 2. */ unsignedint glyphs_size = (scratch_size * sizeof (int) - 2)
/ (sizeof (WORD) + sizeof (SCRIPT_GLYPHPROP) + sizeof (int) + sizeof (GOFFSET) + sizeof (uint32_t));
/* Note: * We can't touch the contents of glyph_props. Our fallback * implementations of Shape and Place functions use that buffer * by casting it to a different type. It works because they * both agree about it, but if we want to access it here we * need address that issue first.
*/
/* Ok, we've got everything we need, now compose output buffer,
* very, *very*, carefully! */
/* Calculate visual-clusters. That's what we ship. */ for (unsignedint i = 0; i < glyphs_len; i++)
vis_clusters[i] = (uint32_t) -1; for (unsignedint i = 0; i < buffer->len; i++) {
uint32_t *p = &vis_clusters[log_clusters[buffer->info[i].utf16_index()]];
*p = hb_min (*p, buffer->info[i].cluster);
} for (unsignedint i = 1; i < glyphs_len; i++) if (vis_clusters[i] == (uint32_t) -1)
vis_clusters[i] = vis_clusters[i - 1];
#undef utf16_index
if (unlikely (!buffer->ensure (glyphs_len)))
FAIL ("Buffer in error");
#undef FAIL
/* Set glyph infos */
buffer->len = 0; for (unsignedint i = 0; i < glyphs_len; i++)
{
hb_glyph_info_t *info = &buffer->info[buffer->len++];
/* The rest is crap. Let's store position info there for now. */
info->mask = advances[i];
info->var1.i32 = offsets[i].du;
info->var2.i32 = offsets[i].dv;
}
/* Set glyph positions */
buffer->clear_positions (); double x_mult = font_data->x_mult, y_mult = font_data->y_mult; for (unsignedint i = 0; i < glyphs_len; i++)
{
hb_glyph_info_t *info = &buffer->info[i];
hb_glyph_position_t *pos = &buffer->pos[i];
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.