summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJason Rumney <jasonr@gnu.org>2009-01-26 14:32:34 +0000
committerJason Rumney <jasonr@gnu.org>2009-01-26 14:32:34 +0000
commit19ae3e619fa28dd7308ed4661faf869d36f3b3cf (patch)
tree7a749a04f4cefe46b38b13a0e6ff6fea0a03ec44 /src
parentbfe9b8c1f1acc2d8fb5629b0d156e3ec62ce0039 (diff)
downloademacs-19ae3e619fa28dd7308ed4661faf869d36f3b3cf.tar.gz
(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 @@
+2009-01-26 Jason Rumney <jasonr@gnu.org>
+
+ * w32font.c (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.
+
2009-01-25 Adrian Robert <Adrian.B.Robert@gmail.com>
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)
bzero (&match_data.pattern, sizeof (LOGFONT));
fill_in_logfont (f, &match_data.pattern, font_spec);
+ /* If the charset is unrecognized, then we won't find a font, so don't
+ waste time looking for one. */
+ if (match_data.pattern.lfCharSet == DEFAULT_CHARSET)
+ {
+ Lisp_Object spec_charset = AREF (font_spec, FONT_REGISTRY_INDEX);
+ if (!NILP (spec_charset)
+ && !EQ (spec_charset, Qiso10646_1)
+ && !EQ (spec_charset, Qunicode_bmp)
+ && !EQ (spec_charset, Qunicode_sip)
+ && !EQ (spec_charset, Qunknown))
+ return Qnil;
+ }
+
match_data.opentype_only = opentype_only;
if (opentype_only)
match_data.pattern.lfOutPrecision = OUT_OUTLINE_PRECIS;
@@ -751,7 +764,7 @@ w32font_list_internal (frame, font_spec, opentype_only)
release_frame_dc (f, dc);
}
- return NILP (match_data.list) ? Qnil : match_data.list;
+ return match_data.list;
}
/* Internal implementation of w32font_match.
@@ -1386,88 +1399,104 @@ add_font_entity_to_list (logical_font, physical_font, font_type, lParam)
struct font_callback_data *match_data
= (struct font_callback_data *) lParam;
Lisp_Object backend = match_data->opentype_only ? Quniscribe : Qgdi;
+ Lisp_Object entity;
+
+ int is_unicode = physical_font->ntmFontSig.fsUsb[3]
+ || physical_font->ntmFontSig.fsUsb[2]
+ || physical_font->ntmFontSig.fsUsb[1]
+ || physical_font->ntmFontSig.fsUsb[0] & 0x3fffffff;
+
+ /* Skip non matching fonts. */
+
+ /* For uniscribe backend, consider only truetype or opentype fonts
+ that have some unicode coverage. */
+ if (match_data->opentype_only
+ && ((!physical_font->ntmTm.ntmFlags & NTMFLAGS_OPENTYPE
+ && !(font_type & TRUETYPE_FONTTYPE))
+ || !is_unicode))
+ return 1;
+
+ /* Ensure a match. */
+ if (!logfonts_match (&logical_font->elfLogFont, &match_data->pattern)
+ || !font_matches_spec (font_type, physical_font,
+ match_data->orig_font_spec, backend,
+ &logical_font->elfLogFont)
+ || !w32font_coverage_ok (&physical_font->ntmFontSig,
+ match_data->pattern.lfCharSet))
+ return 1;
- if ((!match_data->opentype_only
- || (((physical_font->ntmTm.ntmFlags & NTMFLAGS_OPENTYPE)
- || (font_type & TRUETYPE_FONTTYPE))
- /* For the uniscribe backend, only consider fonts that claim
- to cover at least some part of Unicode. */
- && (physical_font->ntmFontSig.fsUsb[3]
- || physical_font->ntmFontSig.fsUsb[2]
- || physical_font->ntmFontSig.fsUsb[1]
- || (physical_font->ntmFontSig.fsUsb[0] & 0x3fffffff))))
- && logfonts_match (&logical_font->elfLogFont, &match_data->pattern)
- && font_matches_spec (font_type, physical_font,
- match_data->orig_font_spec, backend,
- &logical_font->elfLogFont)
- && w32font_coverage_ok (&physical_font->ntmFontSig,
- match_data->pattern.lfCharSet)
- /* Avoid substitutions involving raster fonts (eg Helv -> MS Sans Serif)
- We limit this to raster fonts, because the test can catch some
- genuine fonts (eg the full name of DejaVu Sans Mono Light is actually
- DejaVu Sans Mono ExtraLight). Helvetica -> Arial substitution will
- therefore get through this test. Since full names can be prefixed
- by a foundry, we accept raster fonts if the font name is found
- anywhere within the full name. */
- && (logical_font->elfLogFont.lfOutPrecision != OUT_STRING_PRECIS
- || strstr (logical_font->elfFullName,
- logical_font->elfLogFont.lfFaceName))
+ /* Avoid substitutions involving raster fonts (eg Helv -> MS Sans Serif)
+ We limit this to raster fonts, because the test can catch some
+ genuine fonts (eg the full name of DejaVu Sans Mono Light is actually
+ DejaVu Sans Mono ExtraLight). Helvetica -> Arial substitution will
+ therefore get through this test. Since full names can be prefixed
+ by a foundry, we accept raster fonts if the font name is found
+ anywhere within the full name. */
+ if ((logical_font->elfLogFont.lfOutPrecision == OUT_STRING_PRECIS
+ && strstr (logical_font->elfFullName,
+ logical_font->elfLogFont.lfFaceName))
/* Check for well known substitutions that mess things up in the
presence of Type-1 fonts of the same name. */
- && (match_data->pattern.lfFaceName[0]
- && check_face_name (&logical_font->elfLogFont,
- logical_font->elfFullName)))
+ || (match_data->pattern.lfFaceName[0]
+ && !check_face_name (&logical_font->elfLogFont,
+ logical_font->elfFullName)))
+ return 1;
+
+ /* Make a font entity for the font. */
+ entity = w32_enumfont_pattern_entity (match_data->frame, logical_font,
+ physical_font, font_type,
+ &match_data->pattern,
+ backend);
+
+ if (!NILP (entity))
{
- Lisp_Object entity
- = w32_enumfont_pattern_entity (match_data->frame, logical_font,
- physical_font, font_type,
- &match_data->pattern,
- backend);
- if (!NILP (entity))
- {
- Lisp_Object spec_charset = AREF (match_data->orig_font_spec,
- FONT_REGISTRY_INDEX);
-
- /* If registry was specified as iso10646-1, only report
- ANSI and DEFAULT charsets, as most unicode fonts will
- contain one of those plus others. */
- if ((EQ (spec_charset, Qiso10646_1)
- || EQ (spec_charset, Qunicode_bmp))
- && logical_font->elfLogFont.lfCharSet != DEFAULT_CHARSET
- && logical_font->elfLogFont.lfCharSet != ANSI_CHARSET)
- return 1;
- /* unicode-sip fonts must contain characters beyond the BMP,
- so look for bit 57 (surrogates) in the Unicode subranges. */
- else if (EQ (spec_charset, Qunicode_sip)
- && (!(physical_font->ntmFontSig.fsUsb[1] & 0x02000000)
- || !(physical_font->ntmFontSig.fsUsb[1] & 0x28000000)))
+ Lisp_Object spec_charset = AREF (match_data->orig_font_spec,
+ FONT_REGISTRY_INDEX);
+
+ /* iso10646-1 fonts must contain unicode mapping tables. */
+ if (EQ (spec_charset, Qiso10646_1))
+ {
+ if (!is_unicode)
return 1;
- /* If registry was specified, but did not map to a windows
- charset, don't report any fonts. */
- else if (!NILP (spec_charset)
- && !EQ (spec_charset, Qiso10646_1)
- && !EQ (spec_charset, Qunicode_bmp)
- && !EQ (spec_charset, Qunicode_sip)
- && match_data->pattern.lfCharSet == DEFAULT_CHARSET)
- return 0;
-
- /* If registry was specified, ensure it is reported as the same. */
- if (!NILP (spec_charset))
- ASET (entity, FONT_REGISTRY_INDEX, spec_charset);
-
- match_data->list = Fcons (entity, match_data->list);
-
- /* If no registry specified, duplicate iso8859-1 truetype fonts
- as iso10646-1. */
- if (NILP (spec_charset)
- && font_type == TRUETYPE_FONTTYPE
- && logical_font->elfLogFont.lfCharSet == ANSI_CHARSET)
- {
- Lisp_Object tem = Fcopy_font_spec (entity);
- ASET (tem, FONT_REGISTRY_INDEX, Qiso10646_1);
- match_data->list = Fcons (tem, match_data->list);
- }
- }
+ }
+ /* unicode-bmp fonts must contain characters from the BMP. */
+ else if (EQ (spec_charset, Qunicode_bmp))
+ {
+ if (!physical_font->ntmFontSig.fsUsb[3]
+ && !(physical_font->ntmFontSig.fsUsb[2] & 0xFFFFFF9E)
+ && !(physical_font->ntmFontSig.fsUsb[1] & 0xE81FFFFF)
+ && !(physical_font->ntmFontSig.fsUsb[0] & 0x007F001F))
+ return 1;
+ }
+ /* unicode-sip fonts must contain characters in unicode plane 2.
+ so look for bit 57 (surrogates) in the Unicode subranges, plus
+ the bits for CJK ranges that include those characters. */
+ else if (EQ (spec_charset, Qunicode_sip))
+ {
+ if (!physical_font->ntmFontSig.fsUsb[1] & 0x02000000
+ || !physical_font->ntmFontSig.fsUsb[1] & 0x28000000)
+ return 1;
+ }
+
+ /* This font matches. */
+
+ /* If registry was specified, ensure it is reported as the same. */
+ if (!NILP (spec_charset))
+ ASET (entity, FONT_REGISTRY_INDEX, spec_charset);
+
+ /* Otherwise if using the uniscribe backend, report ANSI and DEFAULT
+ fonts as unicode and skip other charsets. */
+ else if (match_data->opentype_only)
+ {
+ if (logical_font->elfLogFont.lfCharSet == ANSI_CHARSET
+ || logical_font->elfLogFont.lfCharSet == DEFAULT_CHARSET)
+ ASET (entity, FONT_REGISTRY_INDEX, Qiso10646_1);
+ else
+ return 1;
+ }
+
+ /* Add this font to the list. */
+ match_data->list = Fcons (entity, match_data->list);
}
return 1;
}