aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJason Rumney2009-01-26 14:32:34 +0000
committerJason Rumney2009-01-26 14:32:34 +0000
commit19ae3e619fa28dd7308ed4661faf869d36f3b3cf (patch)
tree7a749a04f4cefe46b38b13a0e6ff6fea0a03ec44 /src
parentbfe9b8c1f1acc2d8fb5629b0d156e3ec62ce0039 (diff)
downloademacs-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/ChangeLog8
-rw-r--r--src/w32font.c185
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 @@
12009-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
12009-01-25 Adrian Robert <Adrian.B.Robert@gmail.com> 92009-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}