[uniscribe] Make font selection work

Not tested yet.
This commit is contained in:
Behdad Esfahbod 2011-08-06 22:06:52 -04:00
parent b492299eb3
commit 892eb2e462
3 changed files with 60 additions and 8 deletions

View File

@ -39,6 +39,20 @@
struct NameRecord
{
static int cmp (const NameRecord *a, const NameRecord *b)
{
int ret;
ret = b->platformID.cmp (a->platformID);
if (ret) return ret;
ret = b->encodingID.cmp (a->encodingID);
if (ret) return ret;
ret = b->languageID.cmp (a->languageID);
if (ret) return ret;
ret = b->nameID.cmp (a->nameID);
if (ret) return ret;
return 0;
}
inline bool sanitize (hb_sanitize_context_t *c, void *base) {
TRACE_SANITIZE ();
/* We can check from base all the way up to the end of string... */
@ -60,6 +74,28 @@ struct name
{
static const hb_tag_t Tag = HB_OT_TAG_name;
inline unsigned int get_name (unsigned int platform_id,
unsigned int encoding_id,
unsigned int language_id,
unsigned int name_id,
void *buffer,
unsigned int buffer_length) const
{
NameRecord key;
key.platformID.set (platform_id);
key.encodingID.set (encoding_id);
key.languageID.set (language_id);
key.nameID.set (name_id);
NameRecord *match = (NameRecord *) bsearch (&key, nameRecord, count, sizeof (nameRecord[0]), (hb_compare_func_t) NameRecord::cmp);
if (!match)
return 0;
unsigned int length = MIN (buffer_length, (unsigned int) match->length);
memcmp (buffer, (this + stringOffset) + match->offset, length);
return length;
}
inline bool sanitize_records (hb_sanitize_context_t *c) {
TRACE_SANITIZE ();
unsigned int _count = count;
@ -70,6 +106,7 @@ struct name
inline bool sanitize (hb_sanitize_context_t *c) {
TRACE_SANITIZE ();
return true;
return c->check_struct (this) &&
likely (format == 0 || format == 1) &&
c->check_array (nameRecord, nameRecord[0].static_size, count) &&

View File

@ -58,19 +58,33 @@ DWORD GetFontData(
);
*/
static void
static bool
populate_log_font (LOGFONTW *lf,
HDC hdc,
hb_font_t *font,
hb_blob_t *blob)
hb_font_t *font)
{
memset (lf, 0, sizeof (*lf));
int dpi = GetDeviceCaps (hdc, LOGPIXELSY);
lf->lfHeight = MulDiv (font->x_scale, dpi, 72);
WCHAR family_name[] = {'n','a','z','l','i'};
for (unsigned int i = 0; family_name[i] && i < LF_FACESIZE - 1; i++)
lf->lfFaceName[i] = family_name[i];
hb_blob_t *blob = Sanitizer<name>::sanitize (hb_face_reference_table (font->face, HB_TAG ('n','a','m','e')));
const name *name_table = Sanitizer<name>::lock_instance (blob);
unsigned int len = name_table->get_name (3, 1, 0x409, 4,
lf->lfFaceName,
sizeof (lf->lfFaceName[0]) * LF_FACESIZE)
/ sizeof (lf->lfFaceName[0]);
if (unlikely (!len)) {
DEBUG_MSG (UNISCRIBE, NULL, "Didn't find English name table entry");
return FALSE;
}
if (unlikely (len >= LF_FACESIZE)) {
DEBUG_MSG (UNISCRIBE, NULL, "Font name too long");
return FALSE;
}
for (unsigned int i = 0; i < len; i++)
lf->lfFaceName[i] = hb_be_uint16 (lf->lfFaceName[i]);
lf->lfFaceName[len] = 0;
return TRUE;
}
hb_bool_t
@ -179,6 +193,7 @@ retry:
DWORD num_fonts_installed;
HANDLE fh = AddFontMemResourceEx ((void *) blob_data, blob_length, 0, &num_fonts_installed);
hb_blob_destroy (blob);
if (unlikely (!fh))
FAIL ("AddFontMemResourceEx() failed");
@ -187,7 +202,8 @@ retry:
HDC hdc = GetDC (NULL); /* XXX The DC should be cached on the face I guess? */
LOGFONTW log_font;
populate_log_font (&log_font, hdc, font, blob);
if (unlikely (!populate_log_font (&log_font, hdc, font)))
FAIL ("populate_log_font() failed");
HFONT hfont = CreateFontIndirectW (&log_font);
SelectObject (hdc, hfont);

View File

@ -38,7 +38,6 @@
#include <stdio.h>
int
main (int argc, char **argv)
{