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 {