diff options
| author | Jason Rumney | 2009-01-26 14:32:34 +0000 |
|---|---|---|
| committer | Jason Rumney | 2009-01-26 14:32:34 +0000 |
| commit | 19ae3e619fa28dd7308ed4661faf869d36f3b3cf (patch) | |
| tree | 7a749a04f4cefe46b38b13a0e6ff6fea0a03ec44 /src | |
| parent | bfe9b8c1f1acc2d8fb5629b0d156e3ec62ce0039 (diff) | |
| download | emacs-19ae3e619fa28dd7308ed4661faf869d36f3b3cf.tar.gz emacs-19ae3e619fa28dd7308ed4661faf869d36f3b3cf.zip | |
(w32font_list_internal): Return quickly if registry is
unknown. Simplify final return.
(add_font_entity_to_list): Break complex logic down into more
manageable chunks. Move unknown registry check to
w32font_list_internal.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 8 | ||||
| -rw-r--r-- | src/w32font.c | 185 |
2 files changed, 115 insertions, 78 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 9e29eb5704f..95c7dd6a63e 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,11 @@ | |||
| 1 | 2009-01-26 Jason Rumney <jasonr@gnu.org> | ||
| 2 | |||
| 3 | * w32font.c (w32font_list_internal): Return quickly if registry is | ||
| 4 | unknown. Simplify final return. | ||
| 5 | (add_font_entity_to_list): Break complex logic down into more | ||
| 6 | manageable chunks. Move unknown registry check to | ||
| 7 | w32font_list_internal. | ||
| 8 | |||
| 1 | 2009-01-25 Adrian Robert <Adrian.B.Robert@gmail.com> | 9 | 2009-01-25 Adrian Robert <Adrian.B.Robert@gmail.com> |
| 2 | 10 | ||
| 3 | Changes to remove Feval calls from GUI under NS. | 11 | Changes to remove Feval calls from GUI under NS. |
diff --git a/src/w32font.c b/src/w32font.c index 922a377f826..ac0360c2be4 100644 --- a/src/w32font.c +++ b/src/w32font.c | |||
| @@ -731,6 +731,19 @@ w32font_list_internal (frame, font_spec, opentype_only) | |||
| 731 | bzero (&match_data.pattern, sizeof (LOGFONT)); | 731 | bzero (&match_data.pattern, sizeof (LOGFONT)); |
| 732 | fill_in_logfont (f, &match_data.pattern, font_spec); | 732 | fill_in_logfont (f, &match_data.pattern, font_spec); |
| 733 | 733 | ||
| 734 | /* If the charset is unrecognized, then we won't find a font, so don't | ||
| 735 | waste time looking for one. */ | ||
| 736 | if (match_data.pattern.lfCharSet == DEFAULT_CHARSET) | ||
| 737 | { | ||
| 738 | Lisp_Object spec_charset = AREF (font_spec, FONT_REGISTRY_INDEX); | ||
| 739 | if (!NILP (spec_charset) | ||
| 740 | && !EQ (spec_charset, Qiso10646_1) | ||
| 741 | && !EQ (spec_charset, Qunicode_bmp) | ||
| 742 | && !EQ (spec_charset, Qunicode_sip) | ||
| 743 | && !EQ (spec_charset, Qunknown)) | ||
| 744 | return Qnil; | ||
| 745 | } | ||
| 746 | |||
| 734 | match_data.opentype_only = opentype_only; | 747 | match_data.opentype_only = opentype_only; |
| 735 | if (opentype_only) | 748 | if (opentype_only) |
| 736 | match_data.pattern.lfOutPrecision = OUT_OUTLINE_PRECIS; | 749 | match_data.pattern.lfOutPrecision = OUT_OUTLINE_PRECIS; |
| @@ -751,7 +764,7 @@ w32font_list_internal (frame, font_spec, opentype_only) | |||
| 751 | release_frame_dc (f, dc); | 764 | release_frame_dc (f, dc); |
| 752 | } | 765 | } |
| 753 | 766 | ||
| 754 | return NILP (match_data.list) ? Qnil : match_data.list; | 767 | return match_data.list; |
| 755 | } | 768 | } |
| 756 | 769 | ||
| 757 | /* Internal implementation of w32font_match. | 770 | /* Internal implementation of w32font_match. |
| @@ -1386,88 +1399,104 @@ add_font_entity_to_list (logical_font, physical_font, font_type, lParam) | |||
| 1386 | struct font_callback_data *match_data | 1399 | struct font_callback_data *match_data |
| 1387 | = (struct font_callback_data *) lParam; | 1400 | = (struct font_callback_data *) lParam; |
| 1388 | Lisp_Object backend = match_data->opentype_only ? Quniscribe : Qgdi; | 1401 | Lisp_Object backend = match_data->opentype_only ? Quniscribe : Qgdi; |
| 1402 | Lisp_Object entity; | ||
| 1403 | |||
| 1404 | int is_unicode = physical_font->ntmFontSig.fsUsb[3] | ||
| 1405 | || physical_font->ntmFontSig.fsUsb[2] | ||
| 1406 | || physical_font->ntmFontSig.fsUsb[1] | ||
| 1407 | || physical_font->ntmFontSig.fsUsb[0] & 0x3fffffff; | ||
| 1408 | |||
| 1409 | /* Skip non matching fonts. */ | ||
| 1410 | |||
| 1411 | /* For uniscribe backend, consider only truetype or opentype fonts | ||
| 1412 | that have some unicode coverage. */ | ||
| 1413 | if (match_data->opentype_only | ||
| 1414 | && ((!physical_font->ntmTm.ntmFlags & NTMFLAGS_OPENTYPE | ||
| 1415 | && !(font_type & TRUETYPE_FONTTYPE)) | ||
| 1416 | || !is_unicode)) | ||
| 1417 | return 1; | ||
| 1418 | |||
| 1419 | /* Ensure a match. */ | ||
| 1420 | if (!logfonts_match (&logical_font->elfLogFont, &match_data->pattern) | ||
| 1421 | || !font_matches_spec (font_type, physical_font, | ||
| 1422 | match_data->orig_font_spec, backend, | ||
| 1423 | &logical_font->elfLogFont) | ||
| 1424 | || !w32font_coverage_ok (&physical_font->ntmFontSig, | ||
| 1425 | match_data->pattern.lfCharSet)) | ||
| 1426 | return 1; | ||
| 1389 | 1427 | ||
| 1390 | if ((!match_data->opentype_only | 1428 | /* Avoid substitutions involving raster fonts (eg Helv -> MS Sans Serif) |
| 1391 | || (((physical_font->ntmTm.ntmFlags & NTMFLAGS_OPENTYPE) | 1429 | We limit this to raster fonts, because the test can catch some |
| 1392 | || (font_type & TRUETYPE_FONTTYPE)) | 1430 | genuine fonts (eg the full name of DejaVu Sans Mono Light is actually |
| 1393 | /* For the uniscribe backend, only consider fonts that claim | 1431 | DejaVu Sans Mono ExtraLight). Helvetica -> Arial substitution will |
| 1394 | to cover at least some part of Unicode. */ | 1432 | therefore get through this test. Since full names can be prefixed |
| 1395 | && (physical_font->ntmFontSig.fsUsb[3] | 1433 | by a foundry, we accept raster fonts if the font name is found |
| 1396 | || physical_font->ntmFontSig.fsUsb[2] | 1434 | anywhere within the full name. */ |
| 1397 | || physical_font->ntmFontSig.fsUsb[1] | 1435 | if ((logical_font->elfLogFont.lfOutPrecision == OUT_STRING_PRECIS |
| 1398 | || (physical_font->ntmFontSig.fsUsb[0] & 0x3fffffff)))) | 1436 | && strstr (logical_font->elfFullName, |
| 1399 | && logfonts_match (&logical_font->elfLogFont, &match_data->pattern) | 1437 | logical_font->elfLogFont.lfFaceName)) |
| 1400 | && font_matches_spec (font_type, physical_font, | ||
| 1401 | match_data->orig_font_spec, backend, | ||
| 1402 | &logical_font->elfLogFont) | ||
| 1403 | && w32font_coverage_ok (&physical_font->ntmFontSig, | ||
| 1404 | match_data->pattern.lfCharSet) | ||
| 1405 | /* Avoid substitutions involving raster fonts (eg Helv -> MS Sans Serif) | ||
| 1406 | We limit this to raster fonts, because the test can catch some | ||
| 1407 | genuine fonts (eg the full name of DejaVu Sans Mono Light is actually | ||
| 1408 | DejaVu Sans Mono ExtraLight). Helvetica -> Arial substitution will | ||
| 1409 | therefore get through this test. Since full names can be prefixed | ||
| 1410 | by a foundry, we accept raster fonts if the font name is found | ||
| 1411 | anywhere within the full name. */ | ||
| 1412 | && (logical_font->elfLogFont.lfOutPrecision != OUT_STRING_PRECIS | ||
| 1413 | || strstr (logical_font->elfFullName, | ||
| 1414 | logical_font->elfLogFont.lfFaceName)) | ||
| 1415 | /* Check for well known substitutions that mess things up in the | 1438 | /* Check for well known substitutions that mess things up in the |
| 1416 | presence of Type-1 fonts of the same name. */ | 1439 | presence of Type-1 fonts of the same name. */ |
| 1417 | && (match_data->pattern.lfFaceName[0] | 1440 | || (match_data->pattern.lfFaceName[0] |
| 1418 | && check_face_name (&logical_font->elfLogFont, | 1441 | && !check_face_name (&logical_font->elfLogFont, |
| 1419 | logical_font->elfFullName))) | 1442 | logical_font->elfFullName))) |
| 1443 | return 1; | ||
| 1444 | |||
| 1445 | /* Make a font entity for the font. */ | ||
| 1446 | entity = w32_enumfont_pattern_entity (match_data->frame, logical_font, | ||
| 1447 | physical_font, font_type, | ||
| 1448 | &match_data->pattern, | ||
| 1449 | backend); | ||
| 1450 | |||
| 1451 | if (!NILP (entity)) | ||
| 1420 | { | 1452 | { |
| 1421 | Lisp_Object entity | 1453 | Lisp_Object spec_charset = AREF (match_data->orig_font_spec, |
| 1422 | = w32_enumfont_pattern_entity (match_data->frame, logical_font, | 1454 | FONT_REGISTRY_INDEX); |
| 1423 | physical_font, font_type, | 1455 | |
| 1424 | &match_data->pattern, | 1456 | /* iso10646-1 fonts must contain unicode mapping tables. */ |
| 1425 | backend); | 1457 | if (EQ (spec_charset, Qiso10646_1)) |
| 1426 | if (!NILP (entity)) | 1458 | { |
| 1427 | { | 1459 | if (!is_unicode) |
| 1428 | Lisp_Object spec_charset = AREF (match_data->orig_font_spec, | ||
| 1429 | FONT_REGISTRY_INDEX); | ||
| 1430 | |||
| 1431 | /* If registry was specified as iso10646-1, only report | ||
| 1432 | ANSI and DEFAULT charsets, as most unicode fonts will | ||
| 1433 | contain one of those plus others. */ | ||
| 1434 | if ((EQ (spec_charset, Qiso10646_1) | ||
| 1435 | || EQ (spec_charset, Qunicode_bmp)) | ||
| 1436 | && logical_font->elfLogFont.lfCharSet != DEFAULT_CHARSET | ||
| 1437 | && logical_font->elfLogFont.lfCharSet != ANSI_CHARSET) | ||
| 1438 | return 1; | ||
| 1439 | /* unicode-sip fonts must contain characters beyond the BMP, | ||
| 1440 | so look for bit 57 (surrogates) in the Unicode subranges. */ | ||
| 1441 | else if (EQ (spec_charset, Qunicode_sip) | ||
| 1442 | && (!(physical_font->ntmFontSig.fsUsb[1] & 0x02000000) | ||
| 1443 | || !(physical_font->ntmFontSig.fsUsb[1] & 0x28000000))) | ||
| 1444 | return 1; | 1460 | return 1; |
| 1445 | /* If registry was specified, but did not map to a windows | 1461 | } |
| 1446 | charset, don't report any fonts. */ | 1462 | /* unicode-bmp fonts must contain characters from the BMP. */ |
| 1447 | else if (!NILP (spec_charset) | 1463 | else if (EQ (spec_charset, Qunicode_bmp)) |
| 1448 | && !EQ (spec_charset, Qiso10646_1) | 1464 | { |
| 1449 | && !EQ (spec_charset, Qunicode_bmp) | 1465 | if (!physical_font->ntmFontSig.fsUsb[3] |
| 1450 | && !EQ (spec_charset, Qunicode_sip) | 1466 | && !(physical_font->ntmFontSig.fsUsb[2] & 0xFFFFFF9E) |
| 1451 | && match_data->pattern.lfCharSet == DEFAULT_CHARSET) | 1467 | && !(physical_font->ntmFontSig.fsUsb[1] & 0xE81FFFFF) |
| 1452 | return 0; | 1468 | && !(physical_font->ntmFontSig.fsUsb[0] & 0x007F001F)) |
| 1453 | 1469 | return 1; | |
| 1454 | /* If registry was specified, ensure it is reported as the same. */ | 1470 | } |
| 1455 | if (!NILP (spec_charset)) | 1471 | /* unicode-sip fonts must contain characters in unicode plane 2. |
| 1456 | ASET (entity, FONT_REGISTRY_INDEX, spec_charset); | 1472 | so look for bit 57 (surrogates) in the Unicode subranges, plus |
| 1457 | 1473 | the bits for CJK ranges that include those characters. */ | |
| 1458 | match_data->list = Fcons (entity, match_data->list); | 1474 | else if (EQ (spec_charset, Qunicode_sip)) |
| 1459 | 1475 | { | |
| 1460 | /* If no registry specified, duplicate iso8859-1 truetype fonts | 1476 | if (!physical_font->ntmFontSig.fsUsb[1] & 0x02000000 |
| 1461 | as iso10646-1. */ | 1477 | || !physical_font->ntmFontSig.fsUsb[1] & 0x28000000) |
| 1462 | if (NILP (spec_charset) | 1478 | return 1; |
| 1463 | && font_type == TRUETYPE_FONTTYPE | 1479 | } |
| 1464 | && logical_font->elfLogFont.lfCharSet == ANSI_CHARSET) | 1480 | |
| 1465 | { | 1481 | /* This font matches. */ |
| 1466 | Lisp_Object tem = Fcopy_font_spec (entity); | 1482 | |
| 1467 | ASET (tem, FONT_REGISTRY_INDEX, Qiso10646_1); | 1483 | /* If registry was specified, ensure it is reported as the same. */ |
| 1468 | match_data->list = Fcons (tem, match_data->list); | 1484 | if (!NILP (spec_charset)) |
| 1469 | } | 1485 | ASET (entity, FONT_REGISTRY_INDEX, spec_charset); |
| 1470 | } | 1486 | |
| 1487 | /* Otherwise if using the uniscribe backend, report ANSI and DEFAULT | ||
| 1488 | fonts as unicode and skip other charsets. */ | ||
| 1489 | else if (match_data->opentype_only) | ||
| 1490 | { | ||
| 1491 | if (logical_font->elfLogFont.lfCharSet == ANSI_CHARSET | ||
| 1492 | || logical_font->elfLogFont.lfCharSet == DEFAULT_CHARSET) | ||
| 1493 | ASET (entity, FONT_REGISTRY_INDEX, Qiso10646_1); | ||
| 1494 | else | ||
| 1495 | return 1; | ||
| 1496 | } | ||
| 1497 | |||
| 1498 | /* Add this font to the list. */ | ||
| 1499 | match_data->list = Fcons (entity, match_data->list); | ||
| 1471 | } | 1500 | } |
| 1472 | return 1; | 1501 | return 1; |
| 1473 | } | 1502 | } |