Mercurial > hg > xemacs-beta
comparison src/font-mgr.c @ 4758:75975fd0b7fc
Implement more of the fontconfig API.
Improve implementation, avoiding nonsyntactic macros and compiler warnings.
Clean up some documentation.
Guard against freeing NULL pointers returned from fonconfig.
author | Stephen J. Turnbull <stephen@xemacs.org> |
---|---|
date | Wed, 18 Nov 2009 22:44:28 +0900 |
parents | a23ac8f90a49 |
children | ca99a807b025 e0db3c197671 |
comparison
equal
deleted
inserted
replaced
4757:a23ac8f90a49 | 4758:75975fd0b7fc |
---|---|
1 /* Lisp font handling implementation for X with Xft. | 1 /* Lisp font handling implementation for X with Xft. |
2 | 2 |
3 Copyright (C) 2003 Eric Knauel and Matthias Neubauer | 3 Copyright (C) 2003 Eric Knauel and Matthias Neubauer |
4 Copyright (C) 2005 Eric Knauel | 4 Copyright (C) 2005 Eric Knauel |
5 Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc. | 5 Copyright (C) 2004-2009 Free Software Foundation, Inc. |
6 | 6 |
7 Authors: Eric Knauel <knauel@informatik.uni-tuebingen.de> | 7 Authors: Eric Knauel <knauel@informatik.uni-tuebingen.de> |
8 Matthias Neubauer <neubauer@informatik.uni-freiburg.de> | 8 Matthias Neubauer <neubauer@informatik.uni-freiburg.de> |
9 Stephen J. Turnbull <stephen@xemacs.org> | 9 Stephen J. Turnbull <stephen@xemacs.org> |
10 Created: 27 Oct 2003 | 10 Created: 27 Oct 2003 |
11 Updated: 14 April 2007 by Stephen J. Turnbull | 11 Updated: 18 November 2009 by Stephen J. Turnbull |
12 | 12 |
13 This file is part of XEmacs. | 13 This file is part of XEmacs. |
14 | 14 |
15 XEmacs is free software; you can redistribute it and/or modify it | 15 XEmacs is free software; you can redistribute it and/or modify it |
16 under the terms of the GNU General Public License as published by the | 16 under the terms of the GNU General Public License as published by the |
72 /* Lisp_Object Qfc_result_match; */ /* FcResultMatch */ | 72 /* Lisp_Object Qfc_result_match; */ /* FcResultMatch */ |
73 Lisp_Object Qfc_result_type_mismatch; /* FcResultTypeMismatch */ | 73 Lisp_Object Qfc_result_type_mismatch; /* FcResultTypeMismatch */ |
74 Lisp_Object Qfc_result_no_match; /* FcResultNoMatch */ | 74 Lisp_Object Qfc_result_no_match; /* FcResultNoMatch */ |
75 Lisp_Object Qfc_result_no_id; /* FcResultNoId */ | 75 Lisp_Object Qfc_result_no_id; /* FcResultNoId */ |
76 Lisp_Object Qfc_internal_error; | 76 Lisp_Object Qfc_internal_error; |
77 Lisp_Object Qfc_match_pattern; | |
78 Lisp_Object Qfc_match_font; | |
77 Lisp_Object Vxlfd_font_name_regexp; /* #### Really needed? */ | 79 Lisp_Object Vxlfd_font_name_regexp; /* #### Really needed? */ |
78 Fixnum xft_version; | 80 Fixnum xft_version; |
79 Fixnum fc_version; | 81 Fixnum fc_version; |
80 Fixnum debug_xft; /* Set to 1 enables lots of obnoxious messages. | 82 Fixnum debug_xft; /* Set to 1 enables lots of obnoxious messages. |
81 Setting it to 2 or 3 enables even more. */ | 83 Setting it to 2 or 3 enables even more. */ |
487 default: | 489 default: |
488 return Qfc_internal_error; | 490 return Qfc_internal_error; |
489 } | 491 } |
490 } | 492 } |
491 | 493 |
492 DEFUN("fc-font-match", Ffc_font_match, 2, 2, 0, /* | 494 /* FcConfig handling functions. */ |
493 Return the font on DEVICE that most closely matches PATTERN. | 495 |
494 | 496 /* We obviously need to be careful about garbage collecting the current |
495 DEVICE is an X11 device. | 497 FcConfig. I infer from the documentation of FcConfigDestroy that that |
496 PATTERN is a fontconfig pattern object. | 498 is the only reference maintained by fontconfig. |
497 Returns a fontconfig pattern object representing the closest match to the | 499 So we keep track of our own references on a weak list, and only cons a |
498 given pattern, or an error code. Possible error codes are | 500 new object if we don't already have a reference to it there. */ |
499 `fc-result-no-match' and `fc-result-no-id'. */ | 501 |
500 (device, pattern)) | 502 enum DestroyFontsetP { DestroyNo = 0, DestroyYes = 1 }; |
501 { | 503 |
502 FcResult res; | 504 static Lisp_Object |
503 struct fc_pattern *res_fcpat; | 505 fc_config_create_using (FcConfig * (*create_function) ()) |
504 | 506 { |
505 CHECK_FCPATTERN(pattern); | 507 FcConfig *fc = (*create_function) (); |
506 if (NILP(device)) | 508 Lisp_Object configs = XWEAK_LIST_LIST (Vfc_config_weak_list); |
509 | |
510 /* Linear search: fc_configs are not going to multiply like conses. */ | |
511 { | |
512 LIST_LOOP_2 (cfg, configs) | |
513 if (fc == XFCCONFIG_PTR (cfg)) | |
514 return cfg; | |
515 } | |
516 | |
517 { | |
518 fc_config *fccfg = | |
519 ALLOC_LCRECORD_TYPE (struct fc_config, &lrecord_fc_config); | |
520 fccfg->fccfgPtr = fc; | |
521 configs = Fcons (wrap_fcconfig (fccfg), configs); | |
522 XWEAK_LIST_LIST (Vfc_config_weak_list) = configs; | |
523 return wrap_fcconfig (fccfg); | |
524 } | |
525 } | |
526 | |
527 static Lisp_Object | |
528 fc_strlist_to_lisp_using (FcStrList * (*getter) (FcConfig *), | |
529 Lisp_Object config) | |
530 { | |
531 FcChar8 *thing; | |
532 Lisp_Object value = Qnil; | |
533 FcStrList *thing_list; | |
534 | |
535 CHECK_FCCONFIG (config); | |
536 thing_list = (*getter) (XFCCONFIG_PTR(config)); | |
537 /* Yes, we need to do this check -- sheesh, Keith! */ | |
538 if (!thing_list) | |
507 return Qnil; | 539 return Qnil; |
508 CHECK_X_DEVICE(device); | 540 while ((thing = FcStrListNext (thing_list))) |
509 if (!DEVICE_LIVE_P(XDEVICE(device))) | 541 value = Fcons (build_fcapi_string (thing), value); |
510 return Qnil; | 542 FcStrListDone (thing_list); |
511 | 543 return value; |
512 res_fcpat = ALLOC_LCRECORD_TYPE (struct fc_pattern, &lrecord_fc_pattern); | 544 } |
513 { | |
514 FcPattern *p = XFCPATTERN_PTR(pattern); | |
515 FcConfig *fcc = FcConfigGetCurrent (); | |
516 | |
517 FcConfigSubstitute (fcc, p, FcMatchPattern); | |
518 FcDefaultSubstitute (p); | |
519 res_fcpat->fcpatPtr = FcFontMatch (fcc, p, &res); | |
520 } | |
521 | |
522 if (res_fcpat->fcpatPtr == NULL) | |
523 switch (res) { | |
524 case FcResultNoMatch: | |
525 return Qfc_result_no_match; | |
526 case FcResultNoId: | |
527 return Qfc_result_no_id; | |
528 default: | |
529 return Qfc_internal_error; | |
530 } | |
531 else | |
532 return wrap_fcpattern(res_fcpat); | |
533 } | |
534 | |
535 enum DestroyFontsetP { DestroyNo = 0, DestroyYes = 1 }; | |
536 | 545 |
537 static Lisp_Object | 546 static Lisp_Object |
538 fontset_to_list (FcFontSet *fontset, enum DestroyFontsetP destroyp) | 547 fontset_to_list (FcFontSet *fontset, enum DestroyFontsetP destroyp) |
539 { | 548 { |
540 int idx; | 549 int idx; |
555 if (destroyp) | 564 if (destroyp) |
556 FcFontSetDestroy (fontset); | 565 FcFontSetDestroy (fontset); |
557 return fontlist; | 566 return fontlist; |
558 } | 567 } |
559 | 568 |
560 /* #### fix this name to correspond to Ben's new nomenclature */ | |
561 DEFUN("fc-list-fonts-pattern-objects", Ffc_list_fonts_pattern_objects, | |
562 3, 3, 0, /* | |
563 Return a list of fonts on DEVICE that match PATTERN for PROPERTIES. | |
564 Each font is represented by a fontconfig pattern object. | |
565 | |
566 DEVICE is an X11 device. | |
567 PATTERN is a fontconfig pattern to be matched. | |
568 PROPERTIES is a list of property names (strings) that should match. | |
569 | |
570 #### DEVICE is unused, ignored, and may be removed if it's not needed to | |
571 match other font-listing APIs. */ | |
572 (UNUSED (device), pattern, properties)) | |
573 { | |
574 FcObjectSet *os; | |
575 FcFontSet *fontset; | |
576 | |
577 CHECK_FCPATTERN (pattern); | |
578 CHECK_LIST (properties); | |
579 | |
580 os = FcObjectSetCreate (); | |
581 string_list_to_fcobjectset (properties, os); | |
582 /* #### why don't we need to do the "usual substitutions"? */ | |
583 fontset = FcFontList (NULL, XFCPATTERN_PTR (pattern), os); | |
584 FcObjectSetDestroy (os); | |
585 | |
586 return fontset_to_list (fontset, DestroyYes); | |
587 | |
588 } | |
589 | |
590 /* #### maybe this can/should be folded into fc-list-fonts-pattern-objects? */ | |
591 DEFUN("fc-font-sort", Ffc_font_sort, 2, 4, 0, /* | |
592 Return a list of all fonts sorted by proximity to PATTERN. | |
593 Each font is represented by a fontconfig pattern object. | |
594 | |
595 DEVICE is an X11 device. | |
596 PATTERN is a fontconfig pattern to be matched. | |
597 Optional argument TRIM, if non-nil, means to trim trailing fonts that do not | |
598 contribute new characters to the union repertoire. | |
599 | |
600 #### Optional argument NOSUB, if non-nil, suppresses some of the usual | |
601 property substitutions. DON'T USE THIS in production code, it is intended | |
602 for exploring behavior of fontconfig and will be removed when this code is | |
603 stable. | |
604 | |
605 #### DEVICE is unused, ignored, and may be removed if it's not needed to | |
606 match other font-listing APIs. */ | |
607 (UNUSED (device), pattern, trim, nosub)) | |
608 { | |
609 CHECK_FCPATTERN (pattern); | |
610 | |
611 { | |
612 FcConfig *fcc = FcConfigGetCurrent(); | |
613 FcFontSet *fontset; | |
614 FcPattern *p = XFCPATTERN_PTR (pattern); | |
615 FcResult fcresult; | |
616 | |
617 if (NILP(nosub)) /* #### temporary debug hack */ | |
618 FcDefaultSubstitute (p); | |
619 FcConfigSubstitute (fcc, p, FcMatchPattern); | |
620 fontset = FcFontSort (fcc, p, !NILP(trim), NULL, &fcresult); | |
621 | |
622 return fontset_to_list (fontset, DestroyYes); | |
623 } | |
624 } | |
625 | |
626 #ifdef FONTCONFIG_EXPOSE_CONFIG | |
627 | |
628 /* Configuration routines --- for debugging | |
629 Don't depend on these routines being available in the future! | |
630 | |
631 3.2.10 Initialization | |
632 --------------------- | |
633 | |
634 An FcConfig object holds the internal representation of a configuration. | |
635 There is a default configuration which applications may use by passing | |
636 0 to any function using the data within an FcConfig. | |
637 */ | |
638 | |
639 static void | |
640 finalize_fc_config (void *header, int UNUSED (for_disksave)) | |
641 { | |
642 struct fc_config *p = (struct fc_config *) header; | |
643 if (p->fccfgPtr && p->fccfgPtr != FcConfigGetCurrent()) | |
644 { | |
645 /* If we get here, all of *our* references are garbage (see comment on | |
646 fc_config_create_using() for why), and the only reference that | |
647 fontconfig keeps is the current FcConfig. */ | |
648 FcConfigDestroy (p->fccfgPtr); | |
649 } | |
650 p->fccfgPtr = 0; | |
651 } | |
652 | |
653 static void | |
654 print_fc_config (Lisp_Object obj, Lisp_Object printcharfun, | |
655 int UNUSED(escapeflag)) | |
656 { | |
657 struct fc_config *c = XFCCONFIG (obj); | |
658 if (print_readably) | |
659 printing_unreadable_object ("#<fc-config 0x%x>", c->header.uid); | |
660 write_fmt_string (printcharfun, "#<fc-config 0x%x>", c->header.uid); | |
661 } | |
662 | |
663 static const struct memory_description fcconfig_description [] = { | |
664 /* #### nothing here, is this right?? */ | |
665 { XD_END } | |
666 }; | |
667 | |
668 DEFINE_LRECORD_IMPLEMENTATION("fc-config", fc_config, 0, | |
669 0, print_fc_config, finalize_fc_config, 0, 0, | |
670 fcconfig_description, | |
671 struct fc_config); | |
672 | |
673 /* We obviously need to be careful about garbage collecting the current | |
674 FcConfig. I infer from the documentation of FcConfigDestroy that that | |
675 is the only reference maintained by fontconfig. | |
676 So we keep track of our own references on a weak list, and only cons a | |
677 new object if we don't already have a reference to it there. */ | |
678 | |
679 static Lisp_Object | |
680 fc_config_create_using (FcConfig * (*create_function) ()) | |
681 { | |
682 FcConfig *fc = (*create_function) (); | |
683 Lisp_Object configs = XWEAK_LIST_LIST (Vfc_config_weak_list); | |
684 | |
685 /* Linear search: fc_configs are not going to multiply like conses. */ | |
686 { | |
687 LIST_LOOP_2 (cfg, configs) | |
688 if (fc == XFCCONFIG_PTR (cfg)) | |
689 return cfg; | |
690 } | |
691 | |
692 { | |
693 fc_config *fccfg = | |
694 ALLOC_LCRECORD_TYPE (struct fc_config, &lrecord_fc_config); | |
695 fccfg->fccfgPtr = fc; | |
696 configs = Fcons (wrap_fcconfig (fccfg), configs); | |
697 XWEAK_LIST_LIST (Vfc_config_weak_list) = configs; | |
698 return wrap_fcconfig (fccfg); | |
699 } | |
700 } | |
701 | |
702 DEFUN("fc-config-p", Ffc_config_p, 1, 1, 0, /* | 569 DEFUN("fc-config-p", Ffc_config_p, 1, 1, 0, /* |
703 Returns t if OBJECT is of type fc-config, nil otherwise. | 570 Returns t if OBJECT is of type fc-config, nil otherwise. |
704 */ | 571 */ |
705 (object)) | 572 (object)) |
706 { | 573 { |
725 FcConfigGetCurrent will place the library in an indeterminate | 592 FcConfigGetCurrent will place the library in an indeterminate |
726 state. */ | 593 state. */ |
727 (config)) | 594 (config)) |
728 { | 595 { |
729 signal_error (Qunimplemented, "No user-servicable parts!", | 596 signal_error (Qunimplemented, "No user-servicable parts!", |
730 intern ("fc-config-destroy"); | 597 intern ("fc-config-destroy")); |
731 } | 598 } |
732 #endif | 599 #endif |
733 | |
734 DEFUN("fc-config-get-current", Ffc_config_get_current, 0, 0, 0, /* | |
735 -- Function: FcConfig *FcConfigGetCurrent (void) | |
736 Returns the current default configuration. */ | |
737 ()) | |
738 { | |
739 return fc_config_create_using (&FcConfigGetCurrent); | |
740 } | |
741 | 600 |
742 DEFUN("fc-config-up-to-date", Ffc_config_up_to_date, 1, 1, 0, /* | 601 DEFUN("fc-config-up-to-date", Ffc_config_up_to_date, 1, 1, 0, /* |
743 -- Function: FcBool FcConfigUptoDate (FcConfig *config) | 602 -- Function: FcBool FcConfigUptoDate (FcConfig *config) |
744 Checks all of the files related to 'config' and returns whether the | 603 Checks all of the files related to 'config' and returns whether the |
745 in-memory version is in sync with the disk version. */ | 604 in-memory version is in sync with the disk version. */ |
762 if (FcConfigBuildFonts (XFCCONFIG_PTR (config)) == FcFalse) | 621 if (FcConfigBuildFonts (XFCCONFIG_PTR (config)) == FcFalse) |
763 out_of_memory ("FcConfigBuildFonts failed", config); | 622 out_of_memory ("FcConfigBuildFonts failed", config); |
764 return Qnil; | 623 return Qnil; |
765 } | 624 } |
766 | 625 |
767 /* Calls its argument on `config', which must be defined by the caller. */ | |
768 | |
769 #define FCSTRLIST_TO_LISP_USING(source) do { \ | |
770 FcChar8 *thing; \ | |
771 FcStrList *thing_list; \ | |
772 Lisp_Object value = Qnil; \ | |
773 CHECK_FCCONFIG (config); \ | |
774 thing_list = source (XFCCONFIG_PTR(config)); \ | |
775 /* Yes, we need to do this check -- sheesh, Keith! */ \ | |
776 if (!thing_list) \ | |
777 return Qnil; \ | |
778 while ((thing = FcStrListNext (thing_list))) \ | |
779 value = Fcons (build_fcapi_string (thing), value); \ | |
780 FcStrListDone (thing_list); \ | |
781 return value; \ | |
782 } while (0) | |
783 | |
784 DEFUN("fc-config-get-config-dirs", Ffc_config_get_config_dirs, 1, 1, 0, /* | 626 DEFUN("fc-config-get-config-dirs", Ffc_config_get_config_dirs, 1, 1, 0, /* |
785 -- Function: FcStrList *FcConfigGetConfigDirs (FcConfig *config) | 627 -- Function: FcStrList *FcConfigGetConfigDirs (FcConfig *config) |
786 Returns the list of font directories specified in the | 628 Returns the list of font directories specified in the |
787 configuration files for 'config'. Does not include any | 629 configuration files for 'config'. Does not include any |
788 subdirectories. */ | 630 subdirectories. */ |
789 (config)) | 631 (config)) |
790 { | 632 { |
791 FCSTRLIST_TO_LISP_USING (FcConfigGetConfigDirs); | 633 return fc_strlist_to_lisp_using (&FcConfigGetConfigDirs, config); |
792 } | 634 } |
793 | 635 |
794 DEFUN("fc-config-get-font-dirs", Ffc_config_get_font_dirs, 1, 1, 0, /* | 636 DEFUN("fc-config-get-font-dirs", Ffc_config_get_font_dirs, 1, 1, 0, /* |
795 -- Function: FcStrList *FcConfigGetFontDirs (FcConfig *config) | 637 -- Function: FcStrList *FcConfigGetFontDirs (FcConfig *config) |
796 Returns the list of font directories in 'config'. This includes the | 638 Returns the list of font directories in 'config'. This includes the |
797 configured font directories along with any directories below those | 639 configured font directories along with any directories below those |
798 in the filesystem. */ | 640 in the filesystem. */ |
799 (config)) | 641 (config)) |
800 { | 642 { |
801 FCSTRLIST_TO_LISP_USING (FcConfigGetFontDirs); | 643 return fc_strlist_to_lisp_using (&FcConfigGetFontDirs, config); |
802 } | 644 } |
803 | 645 |
804 DEFUN("fc-config-get-config-files", Ffc_config_get_config_files, 1, 1, 0, /* | 646 DEFUN("fc-config-get-config-files", Ffc_config_get_config_files, 1, 1, 0, /* |
805 -- Function: FcStrList *FcConfigGetConfigFiles (FcConfig *config) | 647 -- Function: FcStrList *FcConfigGetConfigFiles (FcConfig *config) |
806 Returns the list of known configuration files used to generate | 648 Returns the list of known configuration files used to generate |
807 'config'. Note that this will not include any configuration done | 649 'config'. Note that this will not include any configuration done |
808 with FcConfigParse. */ | 650 with FcConfigParse. */ |
809 (config)) | 651 (config)) |
810 { | 652 { |
811 FCSTRLIST_TO_LISP_USING (FcConfigGetConfigFiles); | 653 return fc_strlist_to_lisp_using (&FcConfigGetConfigFiles, config); |
812 } | 654 } |
813 | |
814 #undef FCSTRLIST_TO_LISP_USING | |
815 | 655 |
816 DEFUN("fc-config-get-cache", Ffc_config_get_cache, 1, 1, 0, /* | 656 DEFUN("fc-config-get-cache", Ffc_config_get_cache, 1, 1, 0, /* |
817 -- Function: char *FcConfigGetCache (FcConfig *config) | 657 -- Function: char *FcConfigGetCache (FcConfig *config) |
818 Returns the name of the file used to store per-user font | 658 Returns the name of the file used to store per-user font |
819 information. */ | 659 information. */ |
1020 the available fonts. Returns the resulting configuration. */ | 860 the available fonts. Returns the resulting configuration. */ |
1021 ()) | 861 ()) |
1022 { | 862 { |
1023 return fc_config_create_using (&FcInitLoadConfigAndFonts); | 863 return fc_config_create_using (&FcInitLoadConfigAndFonts); |
1024 } | 864 } |
865 | |
866 DEFUN("fc-config-get-current", Ffc_config_get_current, 0, 0, 0, /* | |
867 -- Function: FcConfig *FcConfigGetCurrent (void) | |
868 Returns the current default configuration. */ | |
869 ()) | |
870 { | |
871 return fc_config_create_using (&FcConfigGetCurrent); | |
872 } | |
873 | |
874 /* Pattern manipulation functions. */ | |
875 | |
876 DEFUN("fc-default-substitute", Ffc_default_substitute, 1, 1, 0, /* | |
877 Adds defaults for certain attributes if not specified in PATTERN. | |
878 FcPattern PATTERN is modified in-place, and nil is returned. | |
879 * Patterns without a specified style or weight are set to Medium | |
880 * Patterns without a specified style or slant are set to Roman | |
881 * Patterns without a specified pixel size are given one computed from any | |
882 specified point size (default 12), dpi (default 75) and scale (default 1). */ | |
883 (pattern)) | |
884 { | |
885 CHECK_FCPATTERN (pattern); | |
886 FcDefaultSubstitute (XFCPATTERN_PTR (pattern)); | |
887 return Qnil; | |
888 } | |
889 | |
890 /* -- Function: FcBool FcConfigSubstituteWithPat (FcConfig *config, | |
891 FcPattern *p, FcPattern *p_pat FcMatchKind kind) | |
892 OMITTED: use optional arguments in `fc-config-substitute'. */ | |
893 | |
894 DEFUN("fc-config-substitute", Ffc_config_substitute, 1, 4, 0, /* | |
895 Modifies PATTERN according to KIND and TESTPAT using operations from CONFIG. | |
896 PATTERN is modified in-place. Returns an undocumented Boolean value. | |
897 If optional KIND is `fc-match-pattern', then those tagged as pattern operations | |
898 are applied, else if KIND is `fc-match-font', those tagged as font operations | |
899 are applied and TESTPAT is used for <test> elements with target=pattern. KIND | |
900 defaults to `fc-match-font'. | |
901 If optional TESTPAT is nil, it is ignored. Otherwise it must be an FcPattern. | |
902 Optional CONFIG must be an FcConfig, defaulting to the current one. | |
903 | |
904 Note that this function actually corresponds to FcConfigSubstituteWithPat, and | |
905 the argument order is changed to take advantage of Lisp optional arguments. */ | |
906 (pattern, kind, testpat, config)) | |
907 { | |
908 FcMatchKind knd; | |
909 | |
910 /* There ought to be a standard idiom for this.... */ | |
911 if (NILP (kind) | |
912 || EQ (kind, Qfc_match_font)) { | |
913 knd = FcMatchFont; | |
914 } | |
915 else if (EQ (kind, Qfc_match_pattern)) { | |
916 knd = FcMatchPattern; | |
917 } | |
918 else { | |
919 Fsignal (Qwrong_type_argument, | |
920 list2 (build_string ("need `fc-match-pattern' or `fc-match-font'"), | |
921 kind)); | |
922 } | |
923 | |
924 /* Typecheck arguments */ | |
925 CHECK_FCPATTERN (pattern); | |
926 if (!NILP (testpat)) CHECK_FCPATTERN (testpat); | |
927 if (!NILP (config)) CHECK_FCCONFIG (config); | |
928 | |
929 return (FcConfigSubstituteWithPat | |
930 (NILP (config) ? FcConfigGetCurrent () : XFCCONFIG_PTR (config), | |
931 XFCPATTERN_PTR (pattern), | |
932 NILP (testpat) ? NULL : XFCPATTERN_PTR (testpat), | |
933 knd) == FcTrue) | |
934 ? Qt : Qnil; | |
935 } | |
936 | |
937 /* Pattern matching functions. */ | |
938 | |
939 /* The following functions return fonts that match a certain pattern. | |
940 `FcFontRenderPrepare' and `FcFontMatch' always return a single best | |
941 match. `FcFontList' returns the list of fonts that match a given | |
942 pattern on a certain set of properties. `FcFontSort' returns the | |
943 entire list of fonts, sorted in order of match quality, possibly | |
944 filtering out fonts that do not provide additional characters beyond | |
945 those provided by preferred fonts. */ | |
946 | |
947 DEFUN("fc-font-render-prepare", Ffc_font_render_prepare, 2, 3, 0, /* | |
948 Return a new pattern blending PATTERN and FONT. | |
949 Optional CONFIG is an FcConfig, defaulting to the current one. | |
950 The returned pattern consists of elements of FONT not appearing in PATTERN, | |
951 elements of PATTERN not appearing in FONT, and the best matching value from | |
952 PATTERN for elements appearing in both. The result is passed to | |
953 FcConfigSubstitute with 'kind' FcMatchFont and then returned. */ | |
954 (pattern, font, config)) | |
955 { | |
956 if (NILP (config)) { | |
957 config = Ffc_config_get_current (); | |
958 } | |
959 CHECK_FCPATTERN (pattern); | |
960 CHECK_FCPATTERN (font); | |
961 CHECK_FCCONFIG (config); | |
962 | |
963 /* I don't think this can fail? */ | |
964 return wrap_fcpattern (FcFontRenderPrepare (XFCCONFIG_PTR(config), | |
965 XFCPATTERN_PTR(font), | |
966 XFCPATTERN_PTR(pattern))); | |
967 } | |
968 | |
969 DEFUN("fc-font-match", Ffc_font_match, 2, 3, 0, /* | |
970 Return the font on DEVICE that most closely matches PATTERN. | |
971 | |
972 DEVICE is an X11 device. | |
973 PATTERN is a fontconfig pattern object. | |
974 Optional CONFIG is an FcConfig, defaulting to the current one. | |
975 Returns a fontconfig pattern object representing the closest match to the | |
976 given pattern, or an error code. Possible error codes are | |
977 `fc-result-no-match' and `fc-result-no-id'. | |
978 PATTERN is massaged with FcConfigSubstitute and FcDefaultSubstitute before | |
979 being processed by FcFontMatch. */ | |
980 (device, pattern, config)) | |
981 { | |
982 FcResult res; | |
983 struct fc_pattern *res_fcpat; | |
984 FcPattern *p; | |
985 FcConfig *fcc; | |
986 | |
987 CHECK_FCPATTERN(pattern); | |
988 if (NILP(device)) | |
989 return Qnil; | |
990 CHECK_X_DEVICE(device); | |
991 if (!DEVICE_LIVE_P(XDEVICE(device))) | |
992 return Qnil; | |
993 if (!NILP (config)) | |
994 CHECK_FCCONFIG (config); | |
995 | |
996 res_fcpat = ALLOC_LCRECORD_TYPE (struct fc_pattern, &lrecord_fc_pattern); | |
997 p = XFCPATTERN_PTR(pattern); | |
998 fcc = NILP (config) ? FcConfigGetCurrent () : XFCCONFIG_PTR (config); | |
999 | |
1000 FcConfigSubstitute (fcc, p, FcMatchPattern); | |
1001 FcDefaultSubstitute (p); | |
1002 res_fcpat->fcpatPtr = FcFontMatch (fcc, p, &res); | |
1003 | |
1004 if (res_fcpat->fcpatPtr == NULL) | |
1005 switch (res) { | |
1006 case FcResultNoMatch: | |
1007 return Qfc_result_no_match; | |
1008 case FcResultNoId: | |
1009 return Qfc_result_no_id; | |
1010 default: | |
1011 return Qfc_internal_error; | |
1012 } | |
1013 else | |
1014 return wrap_fcpattern(res_fcpat); | |
1015 } | |
1016 | |
1017 /* #### fix this name to correspond to Ben's new nomenclature */ | |
1018 DEFUN("fc-list-fonts-pattern-objects", Ffc_list_fonts_pattern_objects, | |
1019 3, 3, 0, /* | |
1020 Return a list of fonts on DEVICE that match PATTERN for PROPERTIES. | |
1021 Each font is represented by a fontconfig pattern object. | |
1022 | |
1023 DEVICE is an X11 device. | |
1024 PATTERN is a fontconfig pattern to be matched. | |
1025 PROPERTIES is a list of property names (strings) that should match. | |
1026 | |
1027 #### DEVICE is unused, ignored, and may be removed if it's not needed to | |
1028 match other font-listing APIs. */ | |
1029 (UNUSED (device), pattern, properties)) | |
1030 { | |
1031 FcObjectSet *os; | |
1032 FcFontSet *fontset; | |
1033 | |
1034 CHECK_FCPATTERN (pattern); | |
1035 CHECK_LIST (properties); | |
1036 | |
1037 os = FcObjectSetCreate (); | |
1038 string_list_to_fcobjectset (properties, os); | |
1039 /* #### why don't we need to do the "usual substitutions"? */ | |
1040 fontset = FcFontList (NULL, XFCPATTERN_PTR (pattern), os); | |
1041 FcObjectSetDestroy (os); | |
1042 | |
1043 return fontset_to_list (fontset, DestroyYes); | |
1044 | |
1045 } | |
1046 | |
1047 /* #### maybe this can/should be folded into fc-list-fonts-pattern-objects? */ | |
1048 DEFUN("fc-font-sort", Ffc_font_sort, 2, 4, 0, /* | |
1049 Return a list of all fonts sorted by proximity to PATTERN. | |
1050 Each font is represented by a fontconfig pattern object. | |
1051 | |
1052 DEVICE is an X11 device. | |
1053 PATTERN is a fontconfig pattern to be matched. | |
1054 Optional argument TRIM, if non-nil, means to trim trailing fonts that do not | |
1055 contribute new characters to the union repertoire. | |
1056 | |
1057 #### Optional argument NOSUB, if non-nil, suppresses some of the usual | |
1058 property substitutions. DON'T USE THIS in production code, it is intended | |
1059 for exploring behavior of fontconfig and will be removed when this code is | |
1060 stable. | |
1061 | |
1062 #### DEVICE is unused, ignored, and may be removed if it's not needed to | |
1063 match other font-listing APIs. */ | |
1064 (UNUSED (device), pattern, trim, nosub)) | |
1065 { | |
1066 CHECK_FCPATTERN (pattern); | |
1067 | |
1068 { | |
1069 FcConfig *fcc = FcConfigGetCurrent(); | |
1070 FcFontSet *fontset; | |
1071 FcPattern *p = XFCPATTERN_PTR (pattern); | |
1072 FcResult fcresult; | |
1073 | |
1074 if (NILP(nosub)) /* #### temporary debug hack */ | |
1075 FcDefaultSubstitute (p); | |
1076 FcConfigSubstitute (fcc, p, FcMatchPattern); | |
1077 fontset = FcFontSort (fcc, p, !NILP(trim), NULL, &fcresult); | |
1078 | |
1079 return fontset_to_list (fontset, DestroyYes); | |
1080 } | |
1081 } | |
1082 | |
1083 #ifdef FONTCONFIG_EXPOSE_CONFIG | |
1084 | |
1085 /* Configuration routines --- for debugging | |
1086 Don't depend on these routines being available in the future! | |
1087 | |
1088 3.2.10 Initialization | |
1089 --------------------- | |
1090 | |
1091 An FcConfig object holds the internal representation of a configuration. | |
1092 There is a default configuration which applications may use by passing | |
1093 0 to any function using the data within an FcConfig. | |
1094 */ | |
1095 | |
1096 static void | |
1097 finalize_fc_config (void *header, int UNUSED (for_disksave)) | |
1098 { | |
1099 struct fc_config *p = (struct fc_config *) header; | |
1100 if (p->fccfgPtr && p->fccfgPtr != FcConfigGetCurrent()) | |
1101 { | |
1102 /* If we get here, all of *our* references are garbage (see comment on | |
1103 fc_config_create_using() for why), and the only reference that | |
1104 fontconfig keeps is the current FcConfig. */ | |
1105 FcConfigDestroy (p->fccfgPtr); | |
1106 } | |
1107 p->fccfgPtr = 0; | |
1108 } | |
1109 | |
1110 static void | |
1111 print_fc_config (Lisp_Object obj, Lisp_Object printcharfun, | |
1112 int UNUSED(escapeflag)) | |
1113 { | |
1114 struct fc_config *c = XFCCONFIG (obj); | |
1115 if (print_readably) | |
1116 printing_unreadable_object ("#<fc-config 0x%x>", c->header.uid); | |
1117 write_fmt_string (printcharfun, "#<fc-config 0x%x>", c->header.uid); | |
1118 } | |
1119 | |
1120 static const struct memory_description fcconfig_description [] = { | |
1121 /* #### nothing here, is this right?? */ | |
1122 { XD_END } | |
1123 }; | |
1124 | |
1125 DEFINE_LRECORD_IMPLEMENTATION("fc-config", fc_config, 0, | |
1126 0, print_fc_config, finalize_fc_config, 0, 0, | |
1127 fcconfig_description, | |
1128 struct fc_config); | |
1025 | 1129 |
1026 DEFUN("fc-init", Ffc_init, 0, 0, 0, /* | 1130 DEFUN("fc-init", Ffc_init, 0, 0, 0, /* |
1027 -- Function: FcBool FcInit (void) | 1131 -- Function: FcBool FcInit (void) |
1028 Loads the default configuration file and the fonts referenced | 1132 Loads the default configuration file and the fonts referenced |
1029 therein and sets the default configuration to that result. | 1133 therein and sets the default configuration to that result. |
1190 FcObjectSetAdd (os, s); | 1294 FcObjectSetAdd (os, s); |
1191 } | 1295 } |
1192 } | 1296 } |
1193 | 1297 |
1194 void | 1298 void |
1195 syms_of_font_mgr (void) | 1299 syms_of_font_mgr (void) { |
1196 { | |
1197 INIT_LRECORD_IMPLEMENTATION(fc_pattern); | 1300 INIT_LRECORD_IMPLEMENTATION(fc_pattern); |
1198 | 1301 |
1199 DEFSYMBOL_MULTIWORD_PREDICATE(Qfc_patternp); | 1302 DEFSYMBOL_MULTIWORD_PREDICATE(Qfc_patternp); |
1200 | 1303 |
1201 DEFSYMBOL(Qfc_result_type_mismatch); | 1304 DEFSYMBOL(Qfc_result_type_mismatch); |
1202 DEFSYMBOL(Qfc_result_no_match); | 1305 DEFSYMBOL(Qfc_result_no_match); |
1203 DEFSYMBOL(Qfc_result_no_id); | 1306 DEFSYMBOL(Qfc_result_no_id); |
1204 DEFSYMBOL(Qfc_internal_error); | 1307 DEFSYMBOL(Qfc_internal_error); |
1308 DEFSYMBOL(Qfc_match_pattern); | |
1309 DEFSYMBOL(Qfc_match_font); | |
1205 DEFSYMBOL(Qfont_mgr); | 1310 DEFSYMBOL(Qfont_mgr); |
1206 | 1311 |
1207 DEFSUBR(Ffc_pattern_p); | 1312 DEFSUBR(Ffc_pattern_p); |
1208 DEFSUBR(Ffc_pattern_create); | 1313 DEFSUBR(Ffc_pattern_create); |
1209 DEFSUBR(Ffc_name_parse); | 1314 DEFSUBR(Ffc_name_parse); |
1213 DEFSUBR(Ffc_pattern_del); | 1318 DEFSUBR(Ffc_pattern_del); |
1214 DEFSUBR(Ffc_pattern_get); | 1319 DEFSUBR(Ffc_pattern_get); |
1215 DEFSUBR(Ffc_list_fonts_pattern_objects); | 1320 DEFSUBR(Ffc_list_fonts_pattern_objects); |
1216 DEFSUBR(Ffc_font_sort); | 1321 DEFSUBR(Ffc_font_sort); |
1217 DEFSUBR(Ffc_font_match); | 1322 DEFSUBR(Ffc_font_match); |
1323 DEFSUBR(Ffc_default_substitute); | |
1324 DEFSUBR(Ffc_config_substitute); | |
1325 DEFSUBR(Ffc_font_render_prepare); | |
1218 DEFSUBR(Fxlfd_font_name_p); | 1326 DEFSUBR(Fxlfd_font_name_p); |
1219 | 1327 |
1220 #ifdef FONTCONFIG_EXPOSE_CONFIG | 1328 #ifdef FONTCONFIG_EXPOSE_CONFIG |
1221 INIT_LRECORD_IMPLEMENTATION(fc_config); | 1329 INIT_LRECORD_IMPLEMENTATION(fc_config); |
1222 | 1330 |