diff options
| author | Jason Rumney | 2008-04-08 13:52:21 +0000 |
|---|---|---|
| committer | Jason Rumney | 2008-04-08 13:52:21 +0000 |
| commit | 8f112d5210cf530f35c77172a4d44e12703be53a (patch) | |
| tree | bf96336df00c4cd672cfbb8e78e960f146b37d1b /src | |
| parent | 20e3d3f1cad9f6b6c69f04fb613a5d2ad2232566 (diff) | |
| download | emacs-8f112d5210cf530f35c77172a4d44e12703be53a.tar.gz emacs-8f112d5210cf530f35c77172a4d44e12703be53a.zip | |
(Qja, Qko, Qzh): New symbols.
(syms_of_w32font): Initialise them.
(font_matches_spec): Use them to filter by language.
(recompute_cached_metrics): Remove function.
(compute_metrics, clear_cached_metrics): New functions.
(w32font_encode_char): Use them to manage metric cache.
(w32font_text_extents): Cache metrics for all glyphs on demand.
Delay converting glyph indices to WORD until needed.
(w32font_open_internal): Initialize metric cache to empty.
(registry_to_w32_charset): Charset should always be a symbol.
(fill_in_logfont, list_all_matching_fonts): Family should always be a symbol.
Diffstat (limited to 'src')
| -rw-r--r-- | src/w32font.c | 285 |
1 files changed, 168 insertions, 117 deletions
diff --git a/src/w32font.c b/src/w32font.c index 866b86e2287..6bd0376810c 100644 --- a/src/w32font.c +++ b/src/w32font.c | |||
| @@ -59,6 +59,9 @@ extern Lisp_Object QCantialias, QCotf, QClanguage; /* defined in font.c */ | |||
| 59 | extern Lisp_Object Qnone; /* reuse from w32fns.c */ | 59 | extern Lisp_Object Qnone; /* reuse from w32fns.c */ |
| 60 | static Lisp_Object Qstandard, Qsubpixel, Qnatural; | 60 | static Lisp_Object Qstandard, Qsubpixel, Qnatural; |
| 61 | 61 | ||
| 62 | /* languages */ | ||
| 63 | static Lisp_Object Qja, Qko, Qzh; | ||
| 64 | |||
| 62 | /* scripts */ | 65 | /* scripts */ |
| 63 | static Lisp_Object Qlatin, Qgreek, Qcoptic, Qcyrillic, Qarmenian, Qhebrew; | 66 | static Lisp_Object Qlatin, Qgreek, Qcoptic, Qcyrillic, Qarmenian, Qhebrew; |
| 64 | static Lisp_Object Qarabic, Qsyriac, Qnko, Qthaana, Qdevanagari, Qbengali; | 67 | static Lisp_Object Qarabic, Qsyriac, Qnko, Qthaana, Qdevanagari, Qbengali; |
| @@ -82,18 +85,18 @@ static Lisp_Object Qphonetic; | |||
| 82 | /* Font spacing symbols - defined in font.c. */ | 85 | /* Font spacing symbols - defined in font.c. */ |
| 83 | extern Lisp_Object Qc, Qp, Qm; | 86 | extern Lisp_Object Qc, Qp, Qm; |
| 84 | 87 | ||
| 85 | static void fill_in_logfont P_ ((FRAME_PTR f, LOGFONT *logfont, | 88 | static void fill_in_logfont P_ ((FRAME_PTR, LOGFONT *, Lisp_Object)); |
| 86 | Lisp_Object font_spec)); | ||
| 87 | 89 | ||
| 88 | static BYTE w32_antialias_type P_ ((Lisp_Object type)); | 90 | static BYTE w32_antialias_type P_ ((Lisp_Object)); |
| 89 | static Lisp_Object lispy_antialias_type P_ ((BYTE type)); | 91 | static Lisp_Object lispy_antialias_type P_ ((BYTE)); |
| 90 | 92 | ||
| 91 | static Lisp_Object font_supported_scripts P_ ((FONTSIGNATURE * sig)); | 93 | static Lisp_Object font_supported_scripts P_ ((FONTSIGNATURE *)); |
| 92 | static int w32font_full_name P_ ((LOGFONT * font, Lisp_Object font_obj, | 94 | static int w32font_full_name P_ ((LOGFONT *, Lisp_Object, int, char *, int)); |
| 93 | int pixel_size, char *name, int nbytes)); | 95 | static void compute_metrics P_ ((HDC, struct w32font_info *, unsigned int, |
| 94 | static void recompute_cached_metrics P_ ((HDC dc, struct w32font_info * font)); | 96 | struct w32_metric_cache *)); |
| 97 | static void clear_cached_metrics P_ ((struct w32font_info *)); | ||
| 95 | 98 | ||
| 96 | static Lisp_Object w32_registry P_ ((LONG w32_charset, DWORD font_type)); | 99 | static Lisp_Object w32_registry P_ ((LONG, DWORD)); |
| 97 | 100 | ||
| 98 | /* EnumFontFamiliesEx callbacks. */ | 101 | /* EnumFontFamiliesEx callbacks. */ |
| 99 | static int CALLBACK add_font_entity_to_list P_ ((ENUMLOGFONTEX *, | 102 | static int CALLBACK add_font_entity_to_list P_ ((ENUMLOGFONTEX *, |
| @@ -126,10 +129,10 @@ struct font_callback_data | |||
| 126 | 129 | ||
| 127 | /* Handles the problem that EnumFontFamiliesEx will not return all | 130 | /* Handles the problem that EnumFontFamiliesEx will not return all |
| 128 | style variations if the font name is not specified. */ | 131 | style variations if the font name is not specified. */ |
| 129 | static void list_all_matching_fonts P_ ((struct font_callback_data *match)); | 132 | static void list_all_matching_fonts P_ ((struct font_callback_data *)); |
| 130 | 133 | ||
| 131 | /* From old font code in w32fns.c */ | 134 | /* From old font code in w32fns.c */ |
| 132 | char * w32_to_x_charset P_ ((int charset, char * matching)); | 135 | char * w32_to_x_charset P_ ((int, char *)); |
| 133 | 136 | ||
| 134 | 137 | ||
| 135 | static int | 138 | static int |
| @@ -336,7 +339,8 @@ w32font_encode_char (font, c) | |||
| 336 | /* Mark this font as not supporting glyph indices. This can happen | 339 | /* Mark this font as not supporting glyph indices. This can happen |
| 337 | on Windows9x, and maybe with non-Truetype fonts on NT etc. */ | 340 | on Windows9x, and maybe with non-Truetype fonts on NT etc. */ |
| 338 | w32_font->glyph_idx = 0; | 341 | w32_font->glyph_idx = 0; |
| 339 | recompute_cached_metrics (dc, w32_font); | 342 | /* Clear metrics cache. */ |
| 343 | clear_cached_metrics (w32_font); | ||
| 340 | 344 | ||
| 341 | return c; | 345 | return c; |
| 342 | } | 346 | } |
| @@ -359,24 +363,13 @@ w32font_text_extents (font, code, nglyphs, metrics) | |||
| 359 | HDC dc = NULL; | 363 | HDC dc = NULL; |
| 360 | struct frame * f; | 364 | struct frame * f; |
| 361 | int total_width = 0; | 365 | int total_width = 0; |
| 362 | WORD *wcode = alloca(nglyphs * sizeof (WORD)); | 366 | WORD *wcode = NULL; |
| 363 | SIZE size; | 367 | SIZE size; |
| 364 | 368 | ||
| 365 | /* TODO: Frames can come and go, and their fonts outlive them. So we | ||
| 366 | can't cache the frame in the font structure. Use selected_frame | ||
| 367 | until the API is updated to pass in a frame. */ | ||
| 368 | f = XFRAME (selected_frame); | ||
| 369 | |||
| 370 | if (metrics) | 369 | if (metrics) |
| 371 | { | 370 | { |
| 372 | GLYPHMETRICS gm; | ||
| 373 | MAT2 transform; | ||
| 374 | struct w32font_info *w32_font = (struct w32font_info *) font; | 371 | struct w32font_info *w32_font = (struct w32font_info *) font; |
| 375 | 372 | ||
| 376 | /* Set transform to the identity matrix. */ | ||
| 377 | bzero (&transform, sizeof (transform)); | ||
| 378 | transform.eM11.value = 1; | ||
| 379 | transform.eM22.value = 1; | ||
| 380 | metrics->width = 0; | 373 | metrics->width = 0; |
| 381 | metrics->ascent = font->ascent; | 374 | metrics->ascent = font->ascent; |
| 382 | metrics->descent = font->descent; | 375 | metrics->descent = font->descent; |
| @@ -384,65 +377,67 @@ w32font_text_extents (font, code, nglyphs, metrics) | |||
| 384 | 377 | ||
| 385 | for (i = 0; i < nglyphs; i++) | 378 | for (i = 0; i < nglyphs; i++) |
| 386 | { | 379 | { |
| 387 | if (*(code + i) < 128) | 380 | struct w32_metric_cache *char_metric; |
| 388 | { | 381 | int block = *(code + i) / CACHE_BLOCKSIZE; |
| 389 | /* Use cached metrics for ASCII. */ | 382 | int pos_in_block = *(code + i) % CACHE_BLOCKSIZE; |
| 390 | struct font_metrics *char_metric | 383 | |
| 391 | = &w32_font->ascii_metrics[*(code+i)]; | 384 | if (block >= w32_font->n_cache_blocks) |
| 392 | 385 | { | |
| 393 | /* If we couldn't get metrics when caching, use fallback. */ | 386 | if (!w32_font->cached_metrics) |
| 394 | if (char_metric->width == 0) | 387 | w32_font->cached_metrics |
| 395 | break; | 388 | = xmalloc ((block + 1) |
| 396 | 389 | * sizeof (struct w32_cached_metric *)); | |
| 397 | metrics->lbearing = min (metrics->lbearing, | 390 | else |
| 398 | metrics->width + char_metric->lbearing); | 391 | w32_font->cached_metrics |
| 399 | metrics->rbearing = max (metrics->rbearing, | 392 | = xrealloc (w32_font->cached_metrics, |
| 400 | metrics->width + char_metric->rbearing); | 393 | (block + 1) |
| 401 | metrics->width += char_metric->width; | 394 | * sizeof (struct w32_cached_metric *)); |
| 402 | } | 395 | bzero (w32_font->cached_metrics + w32_font->n_cache_blocks, |
| 403 | else | 396 | ((block + 1 - w32_font->n_cache_blocks) |
| 404 | { | 397 | * sizeof (struct w32_cached_metric *))); |
| 405 | if (dc == NULL) | 398 | w32_font->n_cache_blocks = block + 1; |
| 406 | { | 399 | } |
| 400 | |||
| 401 | if (!w32_font->cached_metrics[block]) | ||
| 402 | { | ||
| 403 | w32_font->cached_metrics[block] | ||
| 404 | = xmalloc (CACHE_BLOCKSIZE * sizeof (struct font_metrics)); | ||
| 405 | bzero (w32_font->cached_metrics[block], | ||
| 406 | CACHE_BLOCKSIZE * sizeof (struct font_metrics)); | ||
| 407 | } | ||
| 408 | |||
| 409 | char_metric = w32_font->cached_metrics[block] + pos_in_block; | ||
| 410 | |||
| 411 | if (char_metric->status == W32METRIC_NO_ATTEMPT) | ||
| 412 | { | ||
| 413 | if (dc == NULL) | ||
| 414 | { | ||
| 415 | /* TODO: Frames can come and go, and their fonts | ||
| 416 | outlive them. So we can't cache the frame in the | ||
| 417 | font structure. Use selected_frame until the API | ||
| 418 | is updated to pass in a frame. */ | ||
| 419 | f = XFRAME (selected_frame); | ||
| 420 | |||
| 407 | dc = get_frame_dc (f); | 421 | dc = get_frame_dc (f); |
| 408 | old_font = SelectObject (dc, ((W32FontStruct *) | 422 | old_font = SelectObject (dc, ((W32FontStruct *) |
| 409 | (font->font.font))->hfont); | 423 | (font->font.font))->hfont); |
| 410 | } | 424 | } |
| 411 | if (GetGlyphOutlineW (dc, *(code + i), | 425 | compute_metrics (dc, w32_font, *(code + i), char_metric); |
| 412 | GGO_METRICS | 426 | } |
| 413 | | w32_font->glyph_idx | ||
| 414 | ? GGO_GLYPH_INDEX : 0, | ||
| 415 | &gm, 0, NULL, &transform) != GDI_ERROR) | ||
| 416 | { | ||
| 417 | int new_val = metrics->width + gm.gmBlackBoxX | ||
| 418 | + gm.gmptGlyphOrigin.x; | ||
| 419 | metrics->rbearing = max (metrics->rbearing, new_val); | ||
| 420 | new_val = metrics->width + gm.gmptGlyphOrigin.x; | ||
| 421 | metrics->lbearing = min (metrics->lbearing, new_val); | ||
| 422 | metrics->width += gm.gmCellIncX; | ||
| 423 | } | ||
| 424 | else | ||
| 425 | { | ||
| 426 | if (w32_font->glyph_idx) | ||
| 427 | { | ||
| 428 | /* Disable glyph indexing for this font, as we can't | ||
| 429 | handle the metrics. Abort this run, our recovery | ||
| 430 | strategies rely on having unicode code points here. | ||
| 431 | This will cause a glitch in display, but in practice, | ||
| 432 | any problems should be caught when initialising the | ||
| 433 | metrics cache. */ | ||
| 434 | w32_font->glyph_idx = 0; | ||
| 435 | recompute_cached_metrics (dc, w32_font); | ||
| 436 | SelectObject (dc, old_font); | ||
| 437 | release_frame_dc (f, dc); | ||
| 438 | return 0; | ||
| 439 | } | ||
| 440 | /* Rely on an estimate based on the overall font metrics. */ | ||
| 441 | break; | ||
| 442 | } | ||
| 443 | } | ||
| 444 | } | ||
| 445 | 427 | ||
| 428 | if (char_metric->status == W32METRIC_SUCCESS) | ||
| 429 | { | ||
| 430 | metrics->lbearing = min (metrics->lbearing, | ||
| 431 | metrics->width + char_metric->lbearing); | ||
| 432 | metrics->rbearing = max (metrics->rbearing, | ||
| 433 | metrics->width + char_metric->rbearing); | ||
| 434 | metrics->width += char_metric->width; | ||
| 435 | } | ||
| 436 | else | ||
| 437 | /* If we couldn't get metrics for a char, | ||
| 438 | use alternative method. */ | ||
| 439 | break; | ||
| 440 | } | ||
| 446 | /* If we got through everything, return. */ | 441 | /* If we got through everything, return. */ |
| 447 | if (i == nglyphs) | 442 | if (i == nglyphs) |
| 448 | { | 443 | { |
| @@ -460,19 +455,27 @@ w32font_text_extents (font, code, nglyphs, metrics) | |||
| 460 | /* For non-truetype fonts, GetGlyphOutlineW is not supported, so | 455 | /* For non-truetype fonts, GetGlyphOutlineW is not supported, so |
| 461 | fallback on other methods that will at least give some of the metric | 456 | fallback on other methods that will at least give some of the metric |
| 462 | information. */ | 457 | information. */ |
| 463 | for (i = 0; i < nglyphs; i++) | 458 | if (!wcode) { |
| 464 | { | 459 | wcode = alloca (nglyphs * sizeof (WORD)); |
| 465 | if (code[i] < 0x10000) | 460 | for (i = 0; i < nglyphs; i++) |
| 466 | wcode[i] = code[i]; | 461 | { |
| 467 | else | 462 | if (code[i] < 0x10000) |
| 468 | { | 463 | wcode[i] = code[i]; |
| 469 | /* TODO: Convert to surrogate, reallocating array if needed */ | 464 | else |
| 470 | wcode[i] = 0xffff; | 465 | { |
| 471 | } | 466 | /* TODO: Convert to surrogate, reallocating array if needed */ |
| 472 | } | 467 | wcode[i] = 0xffff; |
| 473 | 468 | } | |
| 469 | } | ||
| 470 | } | ||
| 474 | if (dc == NULL) | 471 | if (dc == NULL) |
| 475 | { | 472 | { |
| 473 | /* TODO: Frames can come and go, and their fonts outlive | ||
| 474 | them. So we can't cache the frame in the font structure. Use | ||
| 475 | selected_frame until the API is updated to pass in a | ||
| 476 | frame. */ | ||
| 477 | f = XFRAME (selected_frame); | ||
| 478 | |||
| 476 | dc = get_frame_dc (f); | 479 | dc = get_frame_dc (f); |
| 477 | old_font = SelectObject (dc, ((W32FontStruct *) | 480 | old_font = SelectObject (dc, ((W32FontStruct *) |
| 478 | (font->font.font))->hfont); | 481 | (font->font.font))->hfont); |
| @@ -792,8 +795,8 @@ w32font_open_internal (f, font_entity, pixel_size, w32_font) | |||
| 792 | 795 | ||
| 793 | w32_font->glyph_idx = ETO_GLYPH_INDEX; | 796 | w32_font->glyph_idx = ETO_GLYPH_INDEX; |
| 794 | 797 | ||
| 795 | /* Cache ASCII metrics. */ | 798 | w32_font->cached_metrics = NULL; |
| 796 | recompute_cached_metrics (dc, w32_font); | 799 | w32_font->n_cache_blocks = 0; |
| 797 | 800 | ||
| 798 | SelectObject (dc, old_font); | 801 | SelectObject (dc, old_font); |
| 799 | release_frame_dc (f, dc); | 802 | release_frame_dc (f, dc); |
| @@ -1226,6 +1229,36 @@ font_matches_spec (type, font, spec, backend, logfont) | |||
| 1226 | return 0; | 1229 | return 0; |
| 1227 | } | 1230 | } |
| 1228 | } | 1231 | } |
| 1232 | else if (EQ (key, QClanguage) && SYMBOLP (val)) | ||
| 1233 | { | ||
| 1234 | /* Just handle the CJK languages here, as the language | ||
| 1235 | parameter is used to select a font with appropriate | ||
| 1236 | glyphs in the cjk unified ideographs block. Other fonts | ||
| 1237 | support for a language can be solely determined by | ||
| 1238 | its character coverage. */ | ||
| 1239 | if (EQ (val, Qja)) | ||
| 1240 | { | ||
| 1241 | if (font->ntmTm.tmCharSet != SHIFTJIS_CHARSET) | ||
| 1242 | return 0; | ||
| 1243 | } | ||
| 1244 | else if (EQ (val, Qko)) | ||
| 1245 | { | ||
| 1246 | if (font->ntmTm.tmCharSet != HANGUL_CHARSET | ||
| 1247 | && font->ntmTm.tmCharSet != JOHAB_CHARSET) | ||
| 1248 | return 0; | ||
| 1249 | } | ||
| 1250 | else if (EQ (val, Qzh)) | ||
| 1251 | { | ||
| 1252 | if (font->ntmTm.tmCharSet != GB2312_CHARSET | ||
| 1253 | && font->ntmTm.tmCharSet != CHINESEBIG5_CHARSET) | ||
| 1254 | return 0; | ||
| 1255 | } | ||
| 1256 | else | ||
| 1257 | /* Any other language, we don't recognize it. Fontset | ||
| 1258 | spec should have a fallback, as some backends do | ||
| 1259 | not recognize language at all. */ | ||
| 1260 | return 0; | ||
| 1261 | } | ||
| 1229 | else if (EQ (key, QCotf) && CONSP (val)) | 1262 | else if (EQ (key, QCotf) && CONSP (val)) |
| 1230 | { | 1263 | { |
| 1231 | /* OTF features only supported by the uniscribe backend. */ | 1264 | /* OTF features only supported by the uniscribe backend. */ |
| @@ -1345,8 +1378,6 @@ registry_to_w32_charset (charset) | |||
| 1345 | return ANSI_CHARSET; | 1378 | return ANSI_CHARSET; |
| 1346 | else if (SYMBOLP (charset)) | 1379 | else if (SYMBOLP (charset)) |
| 1347 | return x_to_w32_charset (SDATA (SYMBOL_NAME (charset))); | 1380 | return x_to_w32_charset (SDATA (SYMBOL_NAME (charset))); |
| 1348 | else if (STRINGP (charset)) | ||
| 1349 | return x_to_w32_charset (SDATA (charset)); | ||
| 1350 | else | 1381 | else |
| 1351 | return DEFAULT_CHARSET; | 1382 | return DEFAULT_CHARSET; |
| 1352 | } | 1383 | } |
| @@ -1449,8 +1480,6 @@ fill_in_logfont (f, logfont, font_spec) | |||
| 1449 | user input. */ | 1480 | user input. */ |
| 1450 | else if (SYMBOLP (tmp)) | 1481 | else if (SYMBOLP (tmp)) |
| 1451 | strncpy (logfont->lfFaceName, SDATA (SYMBOL_NAME (tmp)), LF_FACESIZE); | 1482 | strncpy (logfont->lfFaceName, SDATA (SYMBOL_NAME (tmp)), LF_FACESIZE); |
| 1452 | else if (STRINGP (tmp)) | ||
| 1453 | strncpy (logfont->lfFaceName, SDATA (tmp), LF_FACESIZE); | ||
| 1454 | } | 1483 | } |
| 1455 | 1484 | ||
| 1456 | tmp = AREF (font_spec, FONT_ADSTYLE_INDEX); | 1485 | tmp = AREF (font_spec, FONT_ADSTYLE_INDEX); |
| @@ -1550,10 +1579,10 @@ list_all_matching_fonts (match_data) | |||
| 1550 | families = CDR (families); | 1579 | families = CDR (families); |
| 1551 | if (NILP (family)) | 1580 | if (NILP (family)) |
| 1552 | continue; | 1581 | continue; |
| 1553 | else if (STRINGP (family)) | 1582 | else if (SYMBOLP (family)) |
| 1554 | name = SDATA (family); | ||
| 1555 | else | ||
| 1556 | name = SDATA (SYMBOL_NAME (family)); | 1583 | name = SDATA (SYMBOL_NAME (family)); |
| 1584 | else | ||
| 1585 | continue; | ||
| 1557 | 1586 | ||
| 1558 | strncpy (match_data->pattern.lfFaceName, name, LF_FACESIZE); | 1587 | strncpy (match_data->pattern.lfFaceName, name, LF_FACESIZE); |
| 1559 | match_data->pattern.lfFaceName[LF_FACESIZE - 1] = '\0'; | 1588 | match_data->pattern.lfFaceName[LF_FACESIZE - 1] = '\0'; |
| @@ -1807,38 +1836,55 @@ w32font_full_name (font, font_obj, pixel_size, name, nbytes) | |||
| 1807 | } | 1836 | } |
| 1808 | 1837 | ||
| 1809 | 1838 | ||
| 1810 | static void | 1839 | static void compute_metrics (dc, w32_font, code, metrics) |
| 1811 | recompute_cached_metrics (dc, w32_font) | ||
| 1812 | HDC dc; | 1840 | HDC dc; |
| 1813 | struct w32font_info *w32_font; | 1841 | struct w32font_info *w32_font; |
| 1842 | unsigned int code; | ||
| 1843 | struct w32_metric_cache *metrics; | ||
| 1814 | { | 1844 | { |
| 1815 | GLYPHMETRICS gm; | 1845 | GLYPHMETRICS gm; |
| 1816 | MAT2 transform; | 1846 | MAT2 transform; |
| 1817 | unsigned int i; | 1847 | unsigned int options = GGO_METRICS; |
| 1848 | |||
| 1849 | if (w32_font->glyph_idx) | ||
| 1850 | options |= GGO_GLYPH_INDEX; | ||
| 1818 | 1851 | ||
| 1819 | bzero (&transform, sizeof (transform)); | 1852 | bzero (&transform, sizeof (transform)); |
| 1820 | transform.eM11.value = 1; | 1853 | transform.eM11.value = 1; |
| 1821 | transform.eM22.value = 1; | 1854 | transform.eM22.value = 1; |
| 1822 | 1855 | ||
| 1823 | for (i = 0; i < 128; i++) | 1856 | if (GetGlyphOutlineW (dc, code, options, &gm, 0, NULL, &transform) |
| 1857 | != GDI_ERROR) | ||
| 1858 | { | ||
| 1859 | metrics->lbearing = gm.gmptGlyphOrigin.x; | ||
| 1860 | metrics->rbearing = gm.gmptGlyphOrigin.x + gm.gmBlackBoxX; | ||
| 1861 | metrics->width = gm.gmCellIncX; | ||
| 1862 | metrics->status = W32METRIC_SUCCESS; | ||
| 1863 | } | ||
| 1864 | else | ||
| 1824 | { | 1865 | { |
| 1825 | struct font_metrics* char_metric = &w32_font->ascii_metrics[i]; | ||
| 1826 | unsigned int options = GGO_METRICS; | ||
| 1827 | if (w32_font->glyph_idx) | 1866 | if (w32_font->glyph_idx) |
| 1828 | options |= GGO_GLYPH_INDEX; | 1867 | { |
| 1829 | 1868 | /* Can't use glyph indexes after all. | |
| 1830 | if (GetGlyphOutlineW (dc, i, options, &gm, 0, NULL, &transform) | 1869 | Avoid it in future, and clear any metrics that were based on |
| 1831 | != GDI_ERROR) | 1870 | glyph indexes. */ |
| 1832 | { | 1871 | w32_font->glyph_idx = 0; |
| 1833 | char_metric->lbearing = gm.gmptGlyphOrigin.x; | 1872 | clear_cached_metrics (w32_font); |
| 1834 | char_metric->rbearing = gm.gmBlackBoxX + gm.gmptGlyphOrigin.x; | 1873 | } |
| 1835 | char_metric->width = gm.gmCellIncX; | 1874 | metrics->status = W32METRIC_FAIL; |
| 1836 | } | ||
| 1837 | else | ||
| 1838 | char_metric->width = 0; | ||
| 1839 | } | 1875 | } |
| 1840 | } | 1876 | } |
| 1841 | 1877 | ||
| 1878 | static void | ||
| 1879 | clear_cached_metrics (w32_font) | ||
| 1880 | struct w32font_info *w32_font; | ||
| 1881 | { | ||
| 1882 | int i; | ||
| 1883 | for (i = 0; i < w32_font->n_cache_blocks; i++) | ||
| 1884 | bzero (w32_font->cached_metrics[i], | ||
| 1885 | CACHE_BLOCKSIZE * sizeof (struct font_metrics)); | ||
| 1886 | } | ||
| 1887 | |||
| 1842 | struct font_driver w32font_driver = | 1888 | struct font_driver w32font_driver = |
| 1843 | { | 1889 | { |
| 1844 | 0, /* Qgdi */ | 1890 | 0, /* Qgdi */ |
| @@ -1898,6 +1944,11 @@ syms_of_w32font () | |||
| 1898 | DEFSYM (Qsubpixel, "subpixel"); | 1944 | DEFSYM (Qsubpixel, "subpixel"); |
| 1899 | DEFSYM (Qnatural, "natural"); | 1945 | DEFSYM (Qnatural, "natural"); |
| 1900 | 1946 | ||
| 1947 | /* Languages */ | ||
| 1948 | DEFSYM (Qja, "ja"); | ||
| 1949 | DEFSYM (Qko, "ko"); | ||
| 1950 | DEFSYM (Qzh, "zh"); | ||
| 1951 | |||
| 1901 | /* Scripts */ | 1952 | /* Scripts */ |
| 1902 | DEFSYM (Qlatin, "latin"); | 1953 | DEFSYM (Qlatin, "latin"); |
| 1903 | DEFSYM (Qgreek, "greek"); | 1954 | DEFSYM (Qgreek, "greek"); |