Mercurial > hg > xemacs-beta
comparison src/font-mgr.c @ 3360:316fddbf58e2
[xemacs-hg @ 2006-04-25 14:01:52 by stephent]
Repair broken commit to Xft code. <87aca9n4in.fsf@tleepslib.sk.tsukuba.ac.jp>
author | stephent |
---|---|
date | Tue, 25 Apr 2006 14:02:09 +0000 |
parents | 15fb91e3a115 |
children | 182c0df289b7 |
comparison
equal
deleted
inserted
replaced
3359:af8dab703edc | 3360:316fddbf58e2 |
---|---|
29 | 29 |
30 /* Synched up with: Not in GNU Emacs. */ | 30 /* Synched up with: Not in GNU Emacs. */ |
31 | 31 |
32 /* This module provides the Lisp interface to fonts in X11, including Xft, | 32 /* This module provides the Lisp interface to fonts in X11, including Xft, |
33 but (at least at first) not GTK+ or Qt. | 33 but (at least at first) not GTK+ or Qt. |
34 | |
35 It should be renamed to fonts-x.h. | |
36 | 34 |
37 Sealevel code should be in ../lwlib/lwlib-fonts.c or | 35 Sealevel code should be in ../lwlib/lwlib-fonts.c or |
38 ../lwlib/lwlib-colors.c. | 36 ../lwlib/lwlib-colors.c. |
39 */ | 37 */ |
40 | 38 |
67 . Implement FcConfigs. | 65 . Implement FcConfigs. |
68 DONE | 66 DONE |
69 . Fontconfig fontnames are encoded in UTF-8. | 67 . Fontconfig fontnames are encoded in UTF-8. |
70 */ | 68 */ |
71 | 69 |
72 Lisp_Object Qxft_font; | 70 Lisp_Object Qfont_mgr; |
73 Lisp_Object Qfc_patternp; | 71 Lisp_Object Qfc_patternp; |
74 Lisp_Object Qfc_fontsetp; | 72 Lisp_Object Qfc_fontsetp; |
75 /* Lisp_Object Qfc_result_match; */ /* FcResultMatch */ | 73 /* Lisp_Object Qfc_result_match; */ /* FcResultMatch */ |
76 Lisp_Object Qfc_result_type_mismatch; /* FcResultTypeMismatch */ | 74 Lisp_Object Qfc_result_type_mismatch; /* FcResultTypeMismatch */ |
77 Lisp_Object Qfc_result_no_match; /* FcResultNoMatch */ | 75 Lisp_Object Qfc_result_no_match; /* FcResultNoMatch */ |
120 names. I suppose that Qnative is the right encoding, the manual | 118 names. I suppose that Qnative is the right encoding, the manual |
121 doesn't say much about this topic. This functions assumes that STR | 119 doesn't say much about this topic. This functions assumes that STR |
122 is a Lisp string. | 120 is a Lisp string. |
123 */ | 121 */ |
124 #define extract_fcapi_string(str) \ | 122 #define extract_fcapi_string(str) \ |
125 ((FcChar8 *) NEW_LISP_STRING_TO_EXTERNAL ((str), Qnative)) | 123 ((FcChar8 *) NEW_LISP_STRING_TO_EXTERNAL ((str), Qfc_font_name_encoding)) |
126 | 124 |
127 /* fontconfig assumes that objects (property names) are statically allocated, | 125 /* #### This homebrew lashup should be replaced with FcConstants. |
126 | |
127 fontconfig assumes that objects (property names) are statically allocated, | |
128 and you will get bizarre results if you pass Lisp string data or strings | 128 and you will get bizarre results if you pass Lisp string data or strings |
129 allocated on the stack as objects. fontconfig _does_ copy values, so we | 129 allocated on the stack as objects. fontconfig _does_ copy values, so we |
130 (I hope) don't have to worry about that member. | 130 (I hope) don't have to worry about that member. |
131 | 131 |
132 Probably these functions don't get called so often that the memory leak | 132 Probably these functions don't get called so often that the memory leak |
133 due to strdup'ing every time we add a property would matter, but XEmacs | 133 due to strdup'ing every time we add a property would matter, but XEmacs |
134 _is_ a long-running process. So we hash them. | 134 _is_ a long-running process. So we hash them. |
135 | 135 |
136 I suspect that using symbol names or even keywords does not provide | 136 I suspect that using symbol names or even keywords does not provide |
137 assurance that the string won't move in memory. So we hash them | 137 assurance that the string won't move in memory. So we hash them |
138 ourselves; hash.c hashtables do not interpret the value pointers. */ | 138 ourselves; hash.c hashtables do not interpret the value pointers. |
139 static FcChar8 *fc_standard_properties[] = { | 139 |
140 "antialias", "aspect", "autohint", "charset", "dpi", "family", "file", | 140 This array should be FcChar8**, but GCC 4.x bitches about signedness. */ |
141 static Extbyte *fc_standard_properties[] = { | |
142 /* treated specially, ordered first */ | |
143 "family", "size", | |
144 /* remaining are alphabetized by group */ | |
145 /* standard properties in fontconfig and Xft v.2 */ | |
146 "antialias", "aspect", "autohint", "charset", "dpi", "file", | |
141 "foundry", "ftface", "globaladvance", "hinting", "index", "lang", | 147 "foundry", "ftface", "globaladvance", "hinting", "index", "lang", |
142 "minspace", "outline", "pixelsize", "rasterizer", "rgba", "scalable", | 148 "minspace", "outline", "pixelsize", "rasterizer", "rgba", "scalable", |
143 "scale", "size", "slant", "spacing", "style", "verticallayout", "weight", | 149 "scale", "slant", "spacing", "style", "verticallayout", "weight", |
150 /* common in modern fonts */ | |
151 "fontformat", "fontversion", | |
144 /* obsolete after Xft v. 1 */ | 152 /* obsolete after Xft v. 1 */ |
145 "charwidth", "charheight", "core", "encoding", "render" | 153 "charwidth", "charheight", "core", "encoding", "render" |
146 }; | 154 }; |
147 | 155 |
148 static struct hash_table *fc_property_name_hash_table; | 156 static struct hash_table *fc_property_name_hash_table; |
211 (pattern)) | 219 (pattern)) |
212 { | 220 { |
213 CHECK_FCPATTERN(pattern); | 221 CHECK_FCPATTERN(pattern); |
214 { | 222 { |
215 FcChar8 *temp = FcNameUnparse(XFCPATTERN_PTR(pattern)); | 223 FcChar8 *temp = FcNameUnparse(XFCPATTERN_PTR(pattern)); |
216 Lisp_Object res = build_ext_string (temp, Qxft_font_name_encoding); | 224 Lisp_Object res = build_ext_string (temp, Qfc_font_name_encoding); |
217 free (temp); | 225 free (temp); |
218 return res; | 226 return res; |
219 } | 227 } |
220 } | 228 } |
221 | 229 |
417 && !EQ (type, Qfloat)) | 425 && !EQ (type, Qfloat)) |
418 ? Qfc_result_type_mismatch : make_float (fc_value.u.d)); | 426 ? Qfc_result_type_mismatch : make_float (fc_value.u.d)); |
419 case FcTypeString: | 427 case FcTypeString: |
420 return ((!NILP (type) && !EQ (type, Qstring)) | 428 return ((!NILP (type) && !EQ (type, Qstring)) |
421 ? Qfc_result_type_mismatch | 429 ? Qfc_result_type_mismatch |
422 : build_ext_string (fc_value.u.s, Qxft_font_name_encoding)); | 430 : build_ext_string (fc_value.u.s, Qfc_font_name_encoding)); |
423 case FcTypeBool: | 431 case FcTypeBool: |
424 return ((!NILP (type) && !EQ (type, Qboolean)) | 432 return ((!NILP (type) && !EQ (type, Qboolean)) |
425 ? Qfc_result_type_mismatch : fc_value.u.b ? Qt : Qnil); | 433 ? Qfc_result_type_mismatch : fc_value.u.b ? Qt : Qnil); |
426 case FcTypeMatrix: | 434 case FcTypeMatrix: |
427 return Qfc_result_type_mismatch; | 435 return Qfc_result_type_mismatch; |
455 Returns a fontconfig pattern object representing the closest match to the | 463 Returns a fontconfig pattern object representing the closest match to the |
456 given pattern, or an error code. Possible error codes are | 464 given pattern, or an error code. Possible error codes are |
457 `fc-result-no-match' and `fc-result-no-id'. */ | 465 `fc-result-no-match' and `fc-result-no-id'. */ |
458 (device, pattern)) | 466 (device, pattern)) |
459 { | 467 { |
460 Display *dpy; | |
461 FcResult res; | 468 FcResult res; |
462 | 469 |
463 struct fc_pattern *res_fcpat = | 470 struct fc_pattern *res_fcpat = |
464 ALLOC_LCRECORD_TYPE (struct fc_pattern, &lrecord_fc_pattern); | 471 ALLOC_LCRECORD_TYPE (struct fc_pattern, &lrecord_fc_pattern); |
465 CHECK_FCPATTERN(pattern); /* #### MEMORY LEAKS!!! */ | 472 CHECK_FCPATTERN(pattern); /* #### MEMORY LEAKS!!! */ |
467 return Qnil; | 474 return Qnil; |
468 CHECK_X_DEVICE(device); | 475 CHECK_X_DEVICE(device); |
469 if (!DEVICE_LIVE_P(XDEVICE(device))) | 476 if (!DEVICE_LIVE_P(XDEVICE(device))) |
470 return Qnil; | 477 return Qnil; |
471 | 478 |
472 dpy = DEVICE_X_DISPLAY(XDEVICE(device)); | 479 { |
473 /* More Xft vs fontconfig brain damage? */ | 480 FcPattern *p = XFCPATTERN_PTR(pattern); |
474 res_fcpat->fcpatPtr = XftFontMatch(dpy, DefaultScreen (dpy), | 481 FcConfig *fcc = FcConfigGetCurrent (); |
475 XFCPATTERN_PTR(pattern), &res); | 482 |
476 | 483 FcConfigSubstitute (fcc, p, FcMatchPattern); |
484 FcDefaultSubstitute (p); | |
485 res_fcpat->fcpatPtr = FcFontMatch (fcc, p, &res); | |
486 } | |
487 | |
477 if (res_fcpat->fcpatPtr == NULL) | 488 if (res_fcpat->fcpatPtr == NULL) |
478 switch (res) { | 489 switch (res) { |
479 case FcResultNoMatch: | 490 case FcResultNoMatch: |
480 return Qfc_result_no_match; | 491 return Qfc_result_no_match; |
481 case FcResultNoId: | 492 case FcResultNoId: |
572 FcConfigSubstitute (fcc, p, FcMatchPattern); | 583 FcConfigSubstitute (fcc, p, FcMatchPattern); |
573 fontset = FcFontSort (fcc, p, !NILP(trim), NULL, &fcresult); | 584 fontset = FcFontSort (fcc, p, !NILP(trim), NULL, &fcresult); |
574 | 585 |
575 return fontset_to_list (fontset); | 586 return fontset_to_list (fontset); |
576 } | 587 } |
577 } | |
578 | |
579 /* #### this actually is an Xft function, should split those out | |
580 or get rid of them entirely? */ | |
581 /* #### be consistent about argument order. */ | |
582 DEFUN("fc-font-real-pattern", Ffc_font_real_pattern, 2, 2, 0, /* | |
583 Temporarily open FONTNAME (a string) and return the actual | |
584 fc pattern matched by the Fc library. */ | |
585 (fontname, xdevice)) | |
586 { | |
587 FcPattern *copy; | |
588 Display *dpy; | |
589 XftFont *font; | |
590 struct fc_pattern *fcpat = | |
591 ALLOC_LCRECORD_TYPE (struct fc_pattern, &lrecord_fc_pattern); | |
592 | |
593 CHECK_STRING (fontname); /* #### MEMORY LEAK?! maybe not ... */ | |
594 if (NILP(xdevice)) | |
595 return Qnil; | |
596 CHECK_X_DEVICE (xdevice); | |
597 if (!DEVICE_LIVE_P(XDEVICE(xdevice))) | |
598 return Qnil; | |
599 | |
600 /* #### these gymnastics should be unnecessary, just use FcFontMatch */ | |
601 dpy = DEVICE_X_DISPLAY (XDEVICE (xdevice)); | |
602 font = XftFontOpenName (dpy, DefaultScreen(dpy), | |
603 extract_fcapi_string (fontname)); | |
604 if (font == NULL) | |
605 return Qnil; | |
606 copy = FcPatternDuplicate(font->pattern); | |
607 XftFontClose(dpy, font); | |
608 if (copy == NULL) | |
609 return Qnil; | |
610 fcpat->fcpatPtr = copy; | |
611 return wrap_fcpattern(fcpat); | |
612 } | 588 } |
613 | 589 |
614 DEFUN("xlfd-font-name-p", Fxlfd_font_name_p, 1, 1, 0, /* | 590 DEFUN("xlfd-font-name-p", Fxlfd_font_name_p, 1, 1, 0, /* |
615 Check whether the string FONTNAME is a XLFD font name. */ | 591 Check whether the string FONTNAME is a XLFD font name. */ |
616 (fontname)) | 592 (fontname)) |
742 | 718 |
743 DEFSYMBOL(Qfc_result_type_mismatch); | 719 DEFSYMBOL(Qfc_result_type_mismatch); |
744 DEFSYMBOL(Qfc_result_no_match); | 720 DEFSYMBOL(Qfc_result_no_match); |
745 DEFSYMBOL(Qfc_result_no_id); | 721 DEFSYMBOL(Qfc_result_no_id); |
746 DEFSYMBOL(Qfc_internal_error); | 722 DEFSYMBOL(Qfc_internal_error); |
747 DEFSYMBOL(Qxft_font); | 723 DEFSYMBOL(Qfont_mgr); |
748 | 724 |
749 DEFSUBR(Ffc_pattern_p); | 725 DEFSUBR(Ffc_pattern_p); |
750 DEFSUBR(Ffc_pattern_create); | 726 DEFSUBR(Ffc_pattern_create); |
751 DEFSUBR(Ffc_name_parse); | 727 DEFSUBR(Ffc_name_parse); |
752 DEFSUBR(Ffc_name_unparse); | 728 DEFSUBR(Ffc_name_unparse); |
755 DEFSUBR(Ffc_pattern_del); | 731 DEFSUBR(Ffc_pattern_del); |
756 DEFSUBR(Ffc_pattern_get); | 732 DEFSUBR(Ffc_pattern_get); |
757 DEFSUBR(Ffc_list_fonts_pattern_objects); | 733 DEFSUBR(Ffc_list_fonts_pattern_objects); |
758 DEFSUBR(Ffc_font_sort); | 734 DEFSUBR(Ffc_font_sort); |
759 DEFSUBR(Ffc_font_match); | 735 DEFSUBR(Ffc_font_match); |
760 DEFSUBR(Ffc_font_real_pattern); | |
761 DEFSUBR(Fxlfd_font_name_p); | 736 DEFSUBR(Fxlfd_font_name_p); |
762 } | 737 } |
763 | 738 |
764 void | 739 void |
765 vars_of_font_mgr (void) | 740 vars_of_font_mgr (void) |
766 { | 741 { |
767 /* #### These two variables need to go somewhere else. */ | 742 /* #### The next two functions belong somewhere else. */ |
768 | 743 |
769 /* #### I know, but the right fix is use the generic debug facility. */ | 744 /* #### I know, but the right fix is use the generic debug facility. */ |
770 DEFVAR_INT ("xft-debug-level", &debug_xft /* | 745 DEFVAR_INT ("xft-debug-level", &debug_xft /* |
771 Level of debugging messages to issue to stderr for Xft. | 746 Level of debugging messages to issue to stderr for Xft. |
772 A nonnegative integer. Set to 0 to suppress all warnings. | 747 A nonnegative integer. Set to 0 to suppress all warnings. |
778 DEFVAR_LISP("xft-version", &Vxft_version /* | 753 DEFVAR_LISP("xft-version", &Vxft_version /* |
779 The major version number of the Xft library being used. | 754 The major version number of the Xft library being used. |
780 */ ); | 755 */ ); |
781 Vxft_version = make_int(XFT_VERSION); | 756 Vxft_version = make_int(XFT_VERSION); |
782 | 757 |
783 Fprovide (intern ("xft")); | 758 Fprovide (intern ("font-mgr")); |
784 } | 759 } |
785 | 760 |
786 void | 761 void |
787 complex_vars_of_font_mgr (void) | 762 complex_vars_of_font_mgr (void) |
788 { | 763 { |