Mercurial > emacs
comparison src/w32font.c @ 101518:280a537a4f06
(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.
author | Jason Rumney <jasonr@gnu.org> |
---|---|
date | Mon, 26 Jan 2009 14:31:29 +0000 |
parents | 21dea33fa8fd |
children | a36cf7879fb6 |
comparison
equal
deleted
inserted
replaced
101517:9f423e131117 | 101518:280a537a4f06 |
---|---|
729 match_data.frame = frame; | 729 match_data.frame = frame; |
730 | 730 |
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; |
737 | 750 |
738 if (match_data.pattern.lfFaceName[0] == '\0') | 751 if (match_data.pattern.lfFaceName[0] == '\0') |
749 (FONTENUMPROC) add_font_entity_to_list, | 762 (FONTENUMPROC) add_font_entity_to_list, |
750 (LPARAM) &match_data, 0); | 763 (LPARAM) &match_data, 0); |
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. |
758 Additional parameter opentype_only restricts the returned fonts to | 771 Additional parameter opentype_only restricts the returned fonts to |
759 opentype fonts, which can be used with the Uniscribe backend. */ | 772 opentype fonts, which can be used with the Uniscribe backend. */ |
1384 LPARAM lParam; | 1397 LPARAM lParam; |
1385 { | 1398 { |
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; |
1389 | 1402 Lisp_Object entity; |
1390 if ((!match_data->opentype_only | 1403 |
1391 || (((physical_font->ntmTm.ntmFlags & NTMFLAGS_OPENTYPE) | 1404 int is_unicode = physical_font->ntmFontSig.fsUsb[3] |
1392 || (font_type & TRUETYPE_FONTTYPE)) | 1405 || physical_font->ntmFontSig.fsUsb[2] |
1393 /* For the uniscribe backend, only consider fonts that claim | 1406 || physical_font->ntmFontSig.fsUsb[1] |
1394 to cover at least some part of Unicode. */ | 1407 || physical_font->ntmFontSig.fsUsb[0] & 0x3fffffff; |
1395 && (physical_font->ntmFontSig.fsUsb[3] | 1408 |
1396 || physical_font->ntmFontSig.fsUsb[2] | 1409 /* Skip non matching fonts. */ |
1397 || physical_font->ntmFontSig.fsUsb[1] | 1410 |
1398 || (physical_font->ntmFontSig.fsUsb[0] & 0x3fffffff)))) | 1411 /* For uniscribe backend, consider only truetype or opentype fonts |
1399 && logfonts_match (&logical_font->elfLogFont, &match_data->pattern) | 1412 that have some unicode coverage. */ |
1400 && font_matches_spec (font_type, physical_font, | 1413 if (match_data->opentype_only |
1401 match_data->orig_font_spec, backend, | 1414 && ((!physical_font->ntmTm.ntmFlags & NTMFLAGS_OPENTYPE |
1402 &logical_font->elfLogFont) | 1415 && !(font_type & TRUETYPE_FONTTYPE)) |
1403 && w32font_coverage_ok (&physical_font->ntmFontSig, | 1416 || !is_unicode)) |
1404 match_data->pattern.lfCharSet) | 1417 return 1; |
1405 /* Avoid substitutions involving raster fonts (eg Helv -> MS Sans Serif) | 1418 |
1406 We limit this to raster fonts, because the test can catch some | 1419 /* Ensure a match. */ |
1407 genuine fonts (eg the full name of DejaVu Sans Mono Light is actually | 1420 if (!logfonts_match (&logical_font->elfLogFont, &match_data->pattern) |
1408 DejaVu Sans Mono ExtraLight). Helvetica -> Arial substitution will | 1421 || !font_matches_spec (font_type, physical_font, |
1409 therefore get through this test. Since full names can be prefixed | 1422 match_data->orig_font_spec, backend, |
1410 by a foundry, we accept raster fonts if the font name is found | 1423 &logical_font->elfLogFont) |
1411 anywhere within the full name. */ | 1424 || !w32font_coverage_ok (&physical_font->ntmFontSig, |
1412 && (logical_font->elfLogFont.lfOutPrecision != OUT_STRING_PRECIS | 1425 match_data->pattern.lfCharSet)) |
1413 || strstr (logical_font->elfFullName, | 1426 return 1; |
1414 logical_font->elfLogFont.lfFaceName)) | 1427 |
1428 /* Avoid substitutions involving raster fonts (eg Helv -> MS Sans Serif) | |
1429 We limit this to raster fonts, because the test can catch some | |
1430 genuine fonts (eg the full name of DejaVu Sans Mono Light is actually | |
1431 DejaVu Sans Mono ExtraLight). Helvetica -> Arial substitution will | |
1432 therefore get through this test. Since full names can be prefixed | |
1433 by a foundry, we accept raster fonts if the font name is found | |
1434 anywhere within the full name. */ | |
1435 if ((logical_font->elfLogFont.lfOutPrecision == OUT_STRING_PRECIS | |
1436 && strstr (logical_font->elfFullName, | |
1437 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))) |
1420 { | 1443 return 1; |
1421 Lisp_Object entity | 1444 |
1422 = w32_enumfont_pattern_entity (match_data->frame, logical_font, | 1445 /* Make a font entity for the font. */ |
1423 physical_font, font_type, | 1446 entity = w32_enumfont_pattern_entity (match_data->frame, logical_font, |
1424 &match_data->pattern, | 1447 physical_font, font_type, |
1425 backend); | 1448 &match_data->pattern, |
1426 if (!NILP (entity)) | 1449 backend); |
1427 { | 1450 |
1428 Lisp_Object spec_charset = AREF (match_data->orig_font_spec, | 1451 if (!NILP (entity)) |
1429 FONT_REGISTRY_INDEX); | 1452 { |
1430 | 1453 Lisp_Object spec_charset = AREF (match_data->orig_font_spec, |
1431 /* If registry was specified as iso10646-1, only report | 1454 FONT_REGISTRY_INDEX); |
1432 ANSI and DEFAULT charsets, as most unicode fonts will | 1455 |
1433 contain one of those plus others. */ | 1456 /* iso10646-1 fonts must contain unicode mapping tables. */ |
1434 if ((EQ (spec_charset, Qiso10646_1) | 1457 if (EQ (spec_charset, Qiso10646_1)) |
1435 || EQ (spec_charset, Qunicode_bmp)) | 1458 { |
1436 && logical_font->elfLogFont.lfCharSet != DEFAULT_CHARSET | 1459 if (!is_unicode) |
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 } |
1474 | 1503 |
1475 /* Callback function for EnumFontFamiliesEx. | 1504 /* Callback function for EnumFontFamiliesEx. |