aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJason Rumney2008-03-03 00:31:40 +0000
committerJason Rumney2008-03-03 00:31:40 +0000
commit34fd2d28e93778b6220719d8e1780ca1304c240d (patch)
tree50785cb9494d82576848abcee4bb5d735be52054 /src
parent500591f86bc07cf08e2ef7d37d6555cdeb928c76 (diff)
downloademacs-34fd2d28e93778b6220719d8e1780ca1304c240d.tar.gz
emacs-34fd2d28e93778b6220719d8e1780ca1304c240d.zip
(Quniscribe, QCformat): New symbols.
(syms_of_w32font): Define them. (w32font_has_char): Indicate uncertainty. (w32font_encode_char): Encode as glyph point. Make static. (recompute_cached_metrics): New function. (w32font_open_internal): Use it. Set font to use glyph points initially. Set format based on type of font. (w32font_text_extents, w32font_draw): Optionally use glyph points. (w32_enumfont_pattern_entity): Accept backend arg. Set type based on it. Set format based on information available here. (add_font_entity_to_list): Identify backend based on opentype_only.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog19
-rw-r--r--src/w32font.c217
2 files changed, 188 insertions, 48 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 0976b3175c9..01436686571 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,22 @@
12008-03-03 Jason Rumney <jasonr@gnu.org>
2
3 * w32font.h (NTM_PS_OPENTYPE, NTM_TT_OPENTYPE, NTM_TYPE1): Define
4 if system headers don't.
5 (struct w32font_info): Enlarge ascii_metrics. Add glyph_idx.
6 (w32font_encode_char): Don't declare here.
7
8 * w32font.c (Quniscribe, QCformat): New symbols.
9 (syms_of_w32font): Define them.
10 (w32font_has_char): Indicate uncertainty.
11 (w32font_encode_char): Encode as glyph point. Make static.
12 (recompute_cached_metrics): New function.
13 (w32font_open_internal): Use it. Set font to use glyph points
14 initially. Set format based on type of font.
15 (w32font_text_extents, w32font_draw): Optionally use glyph points.
16 (w32_enumfont_pattern_entity): Accept backend arg. Set type based
17 on it. Set format based on information available here.
18 (add_font_entity_to_list): Identify backend based on opentype_only.
19
12008-03-02 Andreas Schwab <schwab@suse.de> 202008-03-02 Andreas Schwab <schwab@suse.de>
2 21
3 * ftfont.c (ftfont_pattern_entity): Fix aliasing violations. 22 * ftfont.c (ftfont_pattern_entity): Fix aliasing violations.
diff --git a/src/w32font.c b/src/w32font.c
index fad3960180e..b5aa29d37b2 100644
--- a/src/w32font.c
+++ b/src/w32font.c
@@ -45,6 +45,8 @@ Boston, MA 02110-1301, USA. */
45extern struct font_driver w32font_driver; 45extern struct font_driver w32font_driver;
46 46
47Lisp_Object Qgdi; 47Lisp_Object Qgdi;
48Lisp_Object Quniscribe;
49static Lisp_Object QCformat;
48static Lisp_Object Qmonospace, Qsansserif, Qmono, Qsans, Qsans_serif; 50static Lisp_Object Qmonospace, Qsansserif, Qmono, Qsans, Qsans_serif;
49static Lisp_Object Qserif, Qscript, Qdecorative; 51static Lisp_Object Qserif, Qscript, Qdecorative;
50static Lisp_Object Qraster, Qoutline, Qunknown; 52static Lisp_Object Qraster, Qoutline, Qunknown;
@@ -78,9 +80,7 @@ static Lisp_Object lispy_antialias_type P_ ((BYTE type));
78static Lisp_Object font_supported_scripts P_ ((FONTSIGNATURE * sig)); 80static Lisp_Object font_supported_scripts P_ ((FONTSIGNATURE * sig));
79static int w32font_full_name P_ ((LOGFONT * font, Lisp_Object font_obj, 81static int w32font_full_name P_ ((LOGFONT * font, Lisp_Object font_obj,
80 int pixel_size, char *name, int nbytes)); 82 int pixel_size, char *name, int nbytes));
81 83static void recompute_cached_metrics P_ ((HDC dc, struct font * font));
82/* From old font code in w32fns.c */
83char * w32_to_x_charset P_ ((int charset, char * matching));
84 84
85static Lisp_Object w32_registry P_ ((LONG w32_charset)); 85static Lisp_Object w32_registry P_ ((LONG w32_charset));
86 86
@@ -117,12 +117,9 @@ struct font_callback_data
117 style variations if the font name is not specified. */ 117 style variations if the font name is not specified. */
118static void list_all_matching_fonts P_ ((struct font_callback_data *match)); 118static void list_all_matching_fonts P_ ((struct font_callback_data *match));
119 119
120/* From old font code in w32fns.c */
121char * w32_to_x_charset P_ ((int charset, char * matching));
120 122
121/* MingW headers only define this when _WIN32_WINNT >= 0x0500, but we
122 target older versions. */
123#ifndef GGI_MARK_NONEXISTING_GLYPHS
124#define GGI_MARK_NONEXISTING_GLYPHS 1
125#endif
126 123
127static int 124static int
128memq_no_quit (elt, list) 125memq_no_quit (elt, list)
@@ -263,20 +260,74 @@ w32font_has_char (entity, c)
263 260
264 script = CHAR_TABLE_REF (Vchar_script_table, c); 261 script = CHAR_TABLE_REF (Vchar_script_table, c);
265 262
266 return (memq_no_quit (script, supported_scripts)) ? 1 : 0; 263 return (memq_no_quit (script, supported_scripts)) ? -1 : 0;
267} 264}
268 265
269/* w32 implementation of encode_char for font backend. 266/* w32 implementation of encode_char for font backend.
270 Return a glyph code of FONT for characer C (Unicode code point). 267 Return a glyph code of FONT for characer C (Unicode code point).
271 If FONT doesn't have such a glyph, return FONT_INVALID_CODE. */ 268 If FONT doesn't have such a glyph, return FONT_INVALID_CODE. */
272unsigned 269static unsigned
273w32font_encode_char (font, c) 270w32font_encode_char (font, c)
274 struct font *font; 271 struct font *font;
275 int c; 272 int c;
276{ 273{
277 /* Avoid unneccesary conversion - all the Win32 APIs will take a unicode 274 struct frame *f;
278 character. */ 275 HDC dc;
279 return c; 276 HFONT old_font;
277 DWORD retval;
278 GCP_RESULTSW result;
279 wchar_t in[2];
280 wchar_t out[2];
281 int len;
282 struct w32font_info *w32_font = (struct w32font_info *) font;
283
284 /* If glyph indexing is not working for this font, just return the
285 unicode code-point. */
286 if (!w32_font->glyph_idx)
287 return c;
288
289 if (c > 0xFFFF)
290 {
291 /* TODO: Encode as surrogate pair and lookup the glyph. */
292 return FONT_INVALID_CODE;
293 }
294 else
295 {
296 in[0] = (wchar_t) c;
297 len = 1;
298 }
299
300 bzero (&result, sizeof (result));
301 result.lStructSize = sizeof (result);
302 result.lpGlyphs = out;
303 result.nGlyphs = 2;
304
305 f = XFRAME (selected_frame);
306
307 dc = get_frame_dc (f);
308 old_font = SelectObject (dc, ((W32FontStruct *) (font->font.font))->hfont);
309
310 retval = GetCharacterPlacementW (dc, in, len, 0, &result, 0);
311
312 SelectObject (dc, old_font);
313 release_frame_dc (f, dc);
314
315 if (retval)
316 {
317 if (result.nGlyphs != 1 || !result.lpGlyphs[0])
318 return FONT_INVALID_CODE;
319 return result.lpGlyphs[0];
320 }
321 else
322 {
323 int i;
324 /* Mark this font as not supporting glyph indices. This can happen
325 on Windows9x, and maybe with non-Truetype fonts on NT etc. */
326 w32_font->glyph_idx = 0;
327 recompute_cached_metrics (dc, font);
328
329 return c;
330 }
280} 331}
281 332
282/* w32 implementation of text_extents for font backend. 333/* w32 implementation of text_extents for font backend.
@@ -308,6 +359,7 @@ w32font_text_extents (font, code, nglyphs, metrics)
308 { 359 {
309 GLYPHMETRICS gm; 360 GLYPHMETRICS gm;
310 MAT2 transform; 361 MAT2 transform;
362 struct w32font_info *w32_font = (struct w32font_info *) font;
311 363
312 /* Set transform to the identity matrix. */ 364 /* Set transform to the identity matrix. */
313 bzero (&transform, sizeof (transform)); 365 bzero (&transform, sizeof (transform));
@@ -320,11 +372,11 @@ w32font_text_extents (font, code, nglyphs, metrics)
320 372
321 for (i = 0; i < nglyphs; i++) 373 for (i = 0; i < nglyphs; i++)
322 { 374 {
323 if (*(code + i) < 128 && *(code + i) > 32) 375 if (*(code + i) < 128)
324 { 376 {
325 /* Use cached metrics for ASCII. */ 377 /* Use cached metrics for ASCII. */
326 struct font_metrics *char_metric 378 struct font_metrics *char_metric
327 = &((struct w32font_info *)font)->ascii_metrics[*(code+i)-32]; 379 = &w32_font->ascii_metrics[*(code+i)];
328 380
329 /* If we couldn't get metrics when caching, use fallback. */ 381 /* If we couldn't get metrics when caching, use fallback. */
330 if (char_metric->width == 0) 382 if (char_metric->width == 0)
@@ -346,8 +398,11 @@ w32font_text_extents (font, code, nglyphs, metrics)
346 old_font = SelectObject (dc, ((W32FontStruct *) 398 old_font = SelectObject (dc, ((W32FontStruct *)
347 (font->font.font))->hfont); 399 (font->font.font))->hfont);
348 } 400 }
349 if (GetGlyphOutlineW (dc, *(code + i), GGO_METRICS, &gm, 0, 401 if (GetGlyphOutlineW (dc, *(code + i),
350 NULL, &transform) != GDI_ERROR) 402 GGO_METRICS
403 | w32_font->glyph_idx
404 ? GGO_GLYPH_INDEX : 0,
405 &gm, 0, NULL, &transform) != GDI_ERROR)
351 { 406 {
352 int new_val = metrics->width + gm.gmBlackBoxX 407 int new_val = metrics->width + gm.gmBlackBoxX
353 + gm.gmptGlyphOrigin.x; 408 + gm.gmptGlyphOrigin.x;
@@ -362,6 +417,20 @@ w32font_text_extents (font, code, nglyphs, metrics)
362 } 417 }
363 else 418 else
364 { 419 {
420 if (w32_font->glyph_idx)
421 {
422 /* Disable glyph indexing for this font, as we can't
423 handle the metrics. Abort this run, our recovery
424 strategies rely on having unicode code points here.
425 This will cause a glitch in display, but in practice,
426 any problems should be caught when initialising the
427 metrics cache. */
428 w32_font->glyph_idx = 0;
429 recompute_cached_metrics (dc, font);
430 SelectObject (dc, old_font);
431 release_frame_dc (f, dc);
432 return 0;
433 }
365 /* Rely on an estimate based on the overall font metrics. */ 434 /* Rely on an estimate based on the overall font metrics. */
366 break; 435 break;
367 } 436 }
@@ -449,8 +518,11 @@ w32font_draw (s, from, to, x, y, with_background)
449 struct glyph_string *s; 518 struct glyph_string *s;
450 int from, to, x, y, with_background; 519 int from, to, x, y, with_background;
451{ 520{
452 UINT options = 0; 521 UINT options;
453 HRGN orig_clip; 522 HRGN orig_clip;
523 struct w32font_info *w32font = (struct w32font_info *) s->face->font_info;
524
525 options = w32font->glyph_idx;
454 526
455 /* Save clip region for later restoration. */ 527 /* Save clip region for later restoration. */
456 GetClipRgn(s->hdc, orig_clip); 528 GetClipRgn(s->hdc, orig_clip);
@@ -709,34 +781,12 @@ w32font_open_internal (f, font_entity, pixel_size, w32_font)
709 GetTextMetrics (dc, &w32_font->metrics); 781 GetTextMetrics (dc, &w32_font->metrics);
710 782
711 /* Cache ASCII metrics. */ 783 /* Cache ASCII metrics. */
712 { 784 recompute_cached_metrics (dc, font);
713 GLYPHMETRICS gm;
714 MAT2 transform;
715 int i;
716
717 bzero (&transform, sizeof (transform));
718 transform.eM11.value = 1;
719 transform.eM22.value = 1;
720
721 for (i = 0; i < 96; i++)
722 {
723 struct font_metrics* char_metric = &w32_font->ascii_metrics[i];
724
725 if (GetGlyphOutlineW (dc, i + 32, GGO_METRICS, &gm, 0,
726 NULL, &transform) != GDI_ERROR)
727 {
728 char_metric->lbearing = -gm.gmptGlyphOrigin.x;
729 char_metric->rbearing = gm.gmBlackBoxX + gm.gmptGlyphOrigin.x;
730 char_metric->width = gm.gmCellIncX;
731 char_metric->ascent = -gm.gmptGlyphOrigin.y;
732 char_metric->descent = gm.gmBlackBoxY + gm.gmptGlyphOrigin.y;
733 }
734 else
735 char_metric->width = 0;
736 }
737 }
738 SelectObject (dc, old_font); 785 SelectObject (dc, old_font);
739 release_frame_dc (f, dc); 786 release_frame_dc (f, dc);
787
788 w32_font->glyph_idx = ETO_GLYPH_INDEX;
789
740 /* W32FontStruct - we should get rid of this, and use the w32font_info 790 /* W32FontStruct - we should get rid of this, and use the w32font_info
741 struct for any W32 specific fields. font->font.font can then be hfont. */ 791 struct for any W32 specific fields. font->font.font can then be hfont. */
742 font->font.font = xmalloc (sizeof (W32FontStruct)); 792 font->font.font = xmalloc (sizeof (W32FontStruct));
@@ -790,7 +840,20 @@ w32font_open_internal (f, font_entity, pixel_size, w32_font)
790 font->entity = font_entity; 840 font->entity = font_entity;
791 font->pixel_size = size; 841 font->pixel_size = size;
792 font->driver = &w32font_driver; 842 font->driver = &w32font_driver;
793 font->format = Qgdi; 843 /* Use format cached during list, as the information we have access to
844 here is incomplete. */
845 extra = AREF (font_entity, FONT_EXTRA_INDEX);
846 if (CONSP (extra))
847 {
848 val = assq_no_quit (QCformat, extra);
849 if (CONSP (val))
850 font->format = XCDR (val);
851 else
852 font->format = Qunknown;
853 }
854 else
855 font->format = Qunknown;
856
794 font->file_name = NULL; 857 font->file_name = NULL;
795 font->encoding_charset = -1; 858 font->encoding_charset = -1;
796 font->repertory_charset = -1; 859 font->repertory_charset = -1;
@@ -859,20 +922,22 @@ add_font_name_to_list (logical_font, physical_font, font_type, list_object)
859/* Convert an enumerated Windows font to an Emacs font entity. */ 922/* Convert an enumerated Windows font to an Emacs font entity. */
860static Lisp_Object 923static Lisp_Object
861w32_enumfont_pattern_entity (frame, logical_font, physical_font, 924w32_enumfont_pattern_entity (frame, logical_font, physical_font,
862 font_type, requested_font) 925 font_type, requested_font, backend)
863 Lisp_Object frame; 926 Lisp_Object frame;
864 ENUMLOGFONTEX *logical_font; 927 ENUMLOGFONTEX *logical_font;
865 NEWTEXTMETRICEX *physical_font; 928 NEWTEXTMETRICEX *physical_font;
866 DWORD font_type; 929 DWORD font_type;
867 LOGFONT *requested_font; 930 LOGFONT *requested_font;
931 Lisp_Object backend;
868{ 932{
869 Lisp_Object entity, tem; 933 Lisp_Object entity, tem;
870 LOGFONT *lf = (LOGFONT*) logical_font; 934 LOGFONT *lf = (LOGFONT*) logical_font;
871 BYTE generic_type; 935 BYTE generic_type;
936 BYTE full_type = physical_font->ntmTm.ntmFlags;
872 937
873 entity = Fmake_vector (make_number (FONT_ENTITY_MAX), Qnil); 938 entity = Fmake_vector (make_number (FONT_ENTITY_MAX), Qnil);
874 939
875 ASET (entity, FONT_TYPE_INDEX, Qgdi); 940 ASET (entity, FONT_TYPE_INDEX, backend);
876 ASET (entity, FONT_FRAME_INDEX, frame); 941 ASET (entity, FONT_FRAME_INDEX, frame);
877 ASET (entity, FONT_REGISTRY_INDEX, w32_registry (lf->lfCharSet)); 942 ASET (entity, FONT_REGISTRY_INDEX, w32_registry (lf->lfCharSet));
878 ASET (entity, FONT_OBJLIST_INDEX, Qnil); 943 ASET (entity, FONT_OBJLIST_INDEX, Qnil);
@@ -939,6 +1004,24 @@ w32_enumfont_pattern_entity (frame, logical_font, physical_font,
939 font_supported_scripts (&physical_font->ntmFontSig)); 1004 font_supported_scripts (&physical_font->ntmFontSig));
940 } 1005 }
941 1006
1007 /* This information is not fully available when opening fonts, so
1008 save it here. Only Windows 2000 and later return information
1009 about opentype and type1 fonts, so need a fallback for detecting
1010 truetype so that this information is not any worse than we could
1011 have obtained later. */
1012 if (full_type & NTM_TT_OPENTYPE || font_type & TRUETYPE_FONTTYPE)
1013 tem = intern ("truetype");
1014 else if (full_type & NTM_TYPE1)
1015 tem = intern ("type1");
1016 else if (full_type & NTM_PS_OPENTYPE)
1017 tem = intern ("postscript");
1018 else if (font_type & RASTER_FONTTYPE)
1019 tem = intern ("w32bitmap");
1020 else
1021 tem = intern ("w32vector");
1022
1023 font_put_extra (entity, QCformat, tem);
1024
942 return entity; 1025 return entity;
943} 1026}
944 1027
@@ -1166,7 +1249,9 @@ add_font_entity_to_list (logical_font, physical_font, font_type, lParam)
1166 Lisp_Object entity 1249 Lisp_Object entity
1167 = w32_enumfont_pattern_entity (match_data->frame, logical_font, 1250 = w32_enumfont_pattern_entity (match_data->frame, logical_font,
1168 physical_font, font_type, 1251 physical_font, font_type,
1169 &match_data->pattern); 1252 &match_data->pattern,
1253 match_data->opentype_only
1254 ? Quniscribe : Qgdi);
1170 if (!NILP (entity)) 1255 if (!NILP (entity))
1171 match_data->list = Fcons (entity, match_data->list); 1256 match_data->list = Fcons (entity, match_data->list);
1172 } 1257 }
@@ -1615,6 +1700,40 @@ w32font_full_name (font, font_obj, pixel_size, name, nbytes)
1615 return (p - name); 1700 return (p - name);
1616} 1701}
1617 1702
1703
1704static void
1705recompute_cached_metrics (dc, font)
1706 HDC dc;
1707 struct font *font;
1708{
1709 GLYPHMETRICS gm;
1710 MAT2 transform;
1711 int i;
1712 struct w32font_info *w32_font;
1713
1714 bzero (&transform, sizeof (transform));
1715 transform.eM11.value = 1;
1716 transform.eM22.value = 1;
1717
1718 for (i = 0; i < 128; i++)
1719 {
1720 struct font_metrics* char_metric = &w32_font->ascii_metrics[i];
1721
1722 if (GetGlyphOutlineW (dc, i + 32, GGO_METRICS
1723 | w32_font->glyph_idx ? GGO_GLYPH_INDEX : 0,
1724 &gm, 0, NULL, &transform) != GDI_ERROR)
1725 {
1726 char_metric->lbearing = -gm.gmptGlyphOrigin.x;
1727 char_metric->rbearing = gm.gmBlackBoxX + gm.gmptGlyphOrigin.x;
1728 char_metric->width = gm.gmCellIncX;
1729 char_metric->ascent = -gm.gmptGlyphOrigin.y;
1730 char_metric->descent = gm.gmBlackBoxY + gm.gmptGlyphOrigin.y;
1731 }
1732 else
1733 char_metric->width = 0;
1734 }
1735}
1736
1618struct font_driver w32font_driver = 1737struct font_driver w32font_driver =
1619 { 1738 {
1620 0, /* Qgdi */ 1739 0, /* Qgdi */
@@ -1650,6 +1769,8 @@ void
1650syms_of_w32font () 1769syms_of_w32font ()
1651{ 1770{
1652 DEFSYM (Qgdi, "gdi"); 1771 DEFSYM (Qgdi, "gdi");
1772 DEFSYM (Quniscribe, "uniscribe");
1773 DEFSYM (QCformat, ":format");
1653 1774
1654 /* Generic font families. */ 1775 /* Generic font families. */
1655 DEFSYM (Qmonospace, "monospace"); 1776 DEFSYM (Qmonospace, "monospace");