diff options
author | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2016-08-09 18:57:46 +0000 |
---|---|---|
committer | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2016-08-09 18:57:46 +0000 |
commit | 1ddbe601f7002743a659e4cde7607b070461b8c3 (patch) | |
tree | 39607e584b65014357f55f57587cf4065767250d /dist/fontconfig/src | |
parent | 63b9c1ad3c9c5032399263622895776547eec2d5 (diff) |
Update to fontconfig 2.12.1.
Tested by krw@, dcoppa@, ok dcoppa@.
Diffstat (limited to 'dist/fontconfig/src')
33 files changed, 2234 insertions, 1697 deletions
diff --git a/dist/fontconfig/src/Makefile.am b/dist/fontconfig/src/Makefile.am index 066cc03e7..3757cf8f3 100644 --- a/dist/fontconfig/src/Makefile.am +++ b/dist/fontconfig/src/Makefile.am @@ -139,7 +139,6 @@ libfontconfig_la_SOURCES = \ fcformat.c \ fcfreetype.c \ fcfs.c \ - fchash.c \ fcinit.c \ fclang.c \ fclist.c \ @@ -151,9 +150,11 @@ libfontconfig_la_SOURCES = \ fcobjs.h \ fcobjshash.h \ fcpat.c \ + fcrange.c \ fcserialize.c \ fcstat.c \ fcstr.c \ + fcweight.c \ fcwindows.h \ fcxml.c \ ftglue.h \ diff --git a/dist/fontconfig/src/Makefile.in b/dist/fontconfig/src/Makefile.in index 76d21c12a..9ff9cb483 100644 --- a/dist/fontconfig/src/Makefile.in +++ b/dist/fontconfig/src/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.12.2 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2012 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -41,23 +41,61 @@ VPATH = @srcdir@ -am__make_dryrun = \ - { \ - am__dry=no; \ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ - echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ - | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ - *) \ - for am__flg in $$MAKEFLAGS; do \ - case $$am__flg in \ - *=*|--*) ;; \ - *n*) am__dry=yes; break;; \ - esac; \ - done;; \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ - test $$am__dry = yes; \ - } + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -78,17 +116,18 @@ build_triplet = @build@ host_triplet = @host@ noinst_PROGRAMS = fcarch$(EXEEXT) subdir = src -DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in $(top_srcdir)/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cc_for_build.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_symbol.m4 \ + $(top_srcdir)/m4/ax_cc_for_build.m4 \ $(top_srcdir)/m4/ax_create_stdint_h.m4 \ $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ - $(top_srcdir)/configure.ac + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ + $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -127,7 +166,8 @@ am_libfontconfig_la_OBJECTS = fcatomic.lo fcblanks.lo fccache.lo \ fccfg.lo fccharset.lo fccompat.lo fcdbg.lo fcdefault.lo \ fcdir.lo fcformat.lo fcfreetype.lo fcfs.lo fcinit.lo fclang.lo \ fclist.lo fcmatch.lo fcmatrix.lo fcname.lo fcobjs.lo fcpat.lo \ - fcserialize.lo fcstat.lo fcstr.lo fcxml.lo ftglue.lo + fcrange.lo fcserialize.lo fcstat.lo fcstr.lo fcweight.lo \ + fcxml.lo ftglue.lo libfontconfig_la_OBJECTS = $(am_libfontconfig_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -184,8 +224,26 @@ am__can_run_installinfo = \ esac DATA = $(noinst_DATA) HEADERS = $(noinst_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ @@ -227,6 +285,8 @@ FC_FONTPATH = @FC_FONTPATH@ FGREP = @FGREP@ FREETYPE_CFLAGS = @FREETYPE_CFLAGS@ FREETYPE_LIBS = @FREETYPE_LIBS@ +GIT = @GIT@ +GPERF = @GPERF@ GREP = @GREP@ HASDOCBOOK = @HASDOCBOOK@ HAVE_XMLPARSE_H = @HAVE_XMLPARSE_H@ @@ -251,6 +311,7 @@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ @@ -268,12 +329,19 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKGCONFIG_REQUIRES = @PKGCONFIG_REQUIRES@ +PKGCONFIG_REQUIRES_PRIVATELY = @PKGCONFIG_REQUIRES_PRIVATELY@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RM = @RM@ SED = @SED@ @@ -297,7 +365,6 @@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ -baseconfigdir = @baseconfigdir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -305,7 +372,6 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ -configdir = @configdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ @@ -330,19 +396,22 @@ mkdir_p = @mkdir_p@ ms_librarian = @ms_librarian@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ +pkgconfigdir = @pkgconfigdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ -templatedir = @templatedir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -xmldir = @xmldir@ EXTRA_DIST = makealias fcobjshash.gperf.h fcobjshash.gperf \ fcobjshash.h @OS_WIN32_TRUE@export_symbols = -export-symbols fontconfig.def @@ -351,7 +420,7 @@ EXTRA_DIST = makealias fcobjshash.gperf.h fcobjshash.gperf \ # Microsoft import library install/uninstall @MS_LIB_AVAILABLE_TRUE@noinst_DATA = fontconfig.lib -INCLUDES = \ +AM_CPPFLAGS = \ -I$(top_srcdir) \ -I$(top_srcdir)/src \ $(FREETYPE_CFLAGS) \ @@ -398,9 +467,11 @@ libfontconfig_la_SOURCES = \ fcobjs.h \ fcobjshash.h \ fcpat.c \ + fcrange.c \ fcserialize.c \ fcstat.c \ fcstr.c \ + fcweight.c \ fcwindows.h \ fcxml.c \ ftglue.h \ @@ -439,7 +510,6 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -457,6 +527,7 @@ $(top_srcdir)/configure: $(am__configure_deps) $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): + install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ @@ -491,6 +562,7 @@ clean-libLTLIBRARIES: echo rm -f $${locs}; \ rm -f $${locs}; \ } + libfontconfig.la: $(libfontconfig_la_OBJECTS) $(libfontconfig_la_DEPENDENCIES) $(EXTRA_libfontconfig_la_DEPENDENCIES) $(AM_V_CCLD)$(libfontconfig_la_LINK) -rpath $(libdir) $(libfontconfig_la_OBJECTS) $(libfontconfig_la_LIBADD) $(LIBS) @@ -502,6 +574,7 @@ clean-noinstPROGRAMS: list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list + fcarch$(EXEEXT): $(fcarch_OBJECTS) $(fcarch_DEPENDENCIES) $(EXTRA_fcarch_DEPENDENCIES) @rm -f fcarch$(EXEEXT) $(AM_V_CCLD)$(LINK) $(fcarch_OBJECTS) $(fcarch_LDADD) $(LIBS) @@ -533,9 +606,11 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fcname.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fcobjs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fcpat.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fcrange.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fcserialize.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fcstat.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fcstr.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fcweight.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fcxml.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftglue.Plo@am__quote@ @@ -544,14 +619,14 @@ distclean-compile: @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -566,26 +641,15 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ + $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ @@ -597,15 +661,11 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $$unique; \ fi; \ fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique @@ -614,9 +674,10 @@ GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am -cscopelist: $(HEADERS) $(SOURCES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP)'; \ +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ @@ -704,8 +765,8 @@ maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) -@ENABLE_SHARED_FALSE@uninstall-local: @ENABLE_SHARED_FALSE@install-data-local: +@ENABLE_SHARED_FALSE@uninstall-local: clean: clean-am clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ @@ -779,26 +840,30 @@ uninstall-am: uninstall-libLTLIBRARIES uninstall-local .MAKE: all check install install-am install-strip -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libLTLIBRARIES clean-libtool clean-noinstPROGRAMS \ - cscopelist ctags distclean distclean-compile distclean-generic \ - distclean-libtool distclean-tags distdir dvi dvi-am html \ - html-am info info-am install install-am install-data \ - install-data-am install-data-local install-dvi install-dvi-am \ - install-exec install-exec-am install-html install-html-am \ - install-info install-info-am install-libLTLIBRARIES \ - install-man install-pdf install-pdf-am install-ps \ - install-ps-am install-strip installcheck installcheck-am \ - installdirs maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \ - uninstall-am uninstall-libLTLIBRARIES uninstall-local + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-data-local install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am \ + install-libLTLIBRARIES install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES \ + uninstall-local + +.PRECIOUS: Makefile # gcc import library install/uninstall -@OS_WIN32_TRUE@install-libtool-import-lib: -@OS_WIN32_TRUE@ $(INSTALL) .libs/libfontconfig.dll.a $(DESTDIR)$(libdir) +@OS_WIN32_TRUE@install-libtool-import-lib: libfontconfig.la +@OS_WIN32_TRUE@ $(MKDIR_P) $(DESTDIR)$(libdir) +@OS_WIN32_TRUE@ $(INSTALL) .libs/libfontconfig.dll.a $(DESTDIR)$(libdir)/libfontconfig.dll.a @OS_WIN32_TRUE@ $(INSTALL) fontconfig.def $(DESTDIR)$(libdir)/fontconfig.def @OS_WIN32_TRUE@uninstall-libtool-import-lib: @@ -838,7 +903,7 @@ fcobjshash.gperf: fcobjshash.gperf.h fcobjs.h mv -f $@.tmp $@ || ( $(RM) $@.tmp && false ) fcobjshash.h: fcobjshash.gperf - $(AM_V_GEN) $(top_srcdir)/missing --run gperf -m 100 $< > $@.tmp && \ + $(AM_V_GEN) $(GPERF) -m 100 $< > $@.tmp && \ mv -f $@.tmp $@ || ( $(RM) $@.tmp && false ) @ENABLE_SHARED_TRUE@install-data-local: install-ms-import-lib install-libtool-import-lib diff --git a/dist/fontconfig/src/fcarch.c b/dist/fontconfig/src/fcarch.c index 398f4bbfc..6ca15a991 100644 --- a/dist/fontconfig/src/fcarch.c +++ b/dist/fontconfig/src/fcarch.c @@ -21,10 +21,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -#include <stdio.h> - #include "fcint.h" #include "fcarch.h" +#include <stdio.h> FC_ASSERT_STATIC (1 == sizeof (char)); FC_ASSERT_STATIC (2 == sizeof (FcChar16)); @@ -49,7 +48,7 @@ FC_ASSERT_STATIC (0x08 + 1*FC_MAX(SIZEOF_VOID_P,ALIGNOF_DOUBLE) == sizeof (FcVal FC_ASSERT_STATIC (0x00 + 2*SIZEOF_VOID_P == sizeof (FcPatternElt)); FC_ASSERT_STATIC (0x08 + 2*SIZEOF_VOID_P == sizeof (FcPattern)); FC_ASSERT_STATIC (0x08 + 2*SIZEOF_VOID_P == sizeof (FcCharSet)); -FC_ASSERT_STATIC (0x08 + 6*SIZEOF_VOID_P == sizeof (FcCache)); +FC_ASSERT_STATIC (0x10 + 6*SIZEOF_VOID_P == sizeof (FcCache)); int diff --git a/dist/fontconfig/src/fcatomic.c b/dist/fontconfig/src/fcatomic.c index c1daed938..d12d32408 100644 --- a/dist/fontconfig/src/fcatomic.c +++ b/dist/fontconfig/src/fcatomic.c @@ -131,7 +131,7 @@ FcAtomicLock (FcAtomic *atomic) return FcFalse; } ret = link ((char *) atomic->tmp, (char *) atomic->lck); - if (ret < 0 && errno == EPERM) + if (ret < 0 && (errno == EPERM || errno == ENOTSUP || errno == EACCES)) { /* the filesystem where atomic->lck points to may not supports * the hard link. so better try to fallback diff --git a/dist/fontconfig/src/fcatomic.h b/dist/fontconfig/src/fcatomic.h index 362e52164..cc28a883c 100644 --- a/dist/fontconfig/src/fcatomic.h +++ b/dist/fontconfig/src/fcatomic.h @@ -48,22 +48,22 @@ #include "fcwindows.h" -/* mingw32 does not have MemoryBarrier. - * MemoryBarrier may be defined as a macro or a function. - * Just make a failsafe version for ourselves. */ -#ifdef MemoryBarrier -#define HBMemoryBarrier MemoryBarrier -#else -static inline void HBMemoryBarrier (void) { +/* MinGW has a convoluted history of supporting MemoryBarrier + * properly. As such, define a function to wrap the whole + * thing. */ +static inline void _FCMemoryBarrier (void) { +#if !defined(MemoryBarrier) long dummy = 0; InterlockedExchange (&dummy, 1); -} +#else + MemoryBarrier (); #endif +} typedef LONG fc_atomic_int_t; #define fc_atomic_int_add(AI, V) InterlockedExchangeAdd (&(AI), (V)) -#define fc_atomic_ptr_get(P) (HBMemoryBarrier (), (void *) *(P)) +#define fc_atomic_ptr_get(P) (_FCMemoryBarrier (), (void *) *(P)) #define fc_atomic_ptr_cmpexch(P,O,N) (InterlockedCompareExchangePointer ((void **) (P), (void *) (N), (void *) (O)) == (void *) (O)) diff --git a/dist/fontconfig/src/fcblanks.c b/dist/fontconfig/src/fcblanks.c index 46698bcda..5132a510f 100644 --- a/dist/fontconfig/src/fcblanks.c +++ b/dist/fontconfig/src/fcblanks.c @@ -41,6 +41,8 @@ FcBlanksCreate (void) void FcBlanksDestroy (FcBlanks *b) { + if (b->sblank == -1) + return; if (b->blanks) free (b->blanks); free (b); @@ -56,6 +58,11 @@ FcBlanksAdd (FcBlanks *b, FcChar32 ucs4) if (b->blanks[sblank] == ucs4) return FcTrue; + if (b->sblank == -1) + { + fprintf (stderr, "Unable to update the static FcBlanks: 0x%04x\n", ucs4); + return FcTrue; + } if (b->nblank == b->sblank) { sblank = b->sblank + 32; @@ -75,11 +82,25 @@ FcBlanksAdd (FcBlanks *b, FcChar32 ucs4) FcBool FcBlanksIsMember (FcBlanks *b, FcChar32 ucs4) { - int i; + int lower = 0, higher = b->nblank, middle; - for (i = 0; i < b->nblank; i++) - if (b->blanks[i] == ucs4) + if (b->nblank == 0 || + b->blanks[0] > ucs4 || + b->blanks[b->nblank - 1] < ucs4) + return FcFalse; + while (1) + { + middle = (lower + higher) / 2; + if (b->blanks[middle] == ucs4) return FcTrue; + if (lower >= higher) + break; + if (b->blanks[middle] < ucs4) + lower = middle + 1; + else + higher = middle - 1; + } + return FcFalse; } #define __fcblanks__ diff --git a/dist/fontconfig/src/fccache.c b/dist/fontconfig/src/fccache.c index 5173e0be2..02ec30132 100644 --- a/dist/fontconfig/src/fccache.c +++ b/dist/fontconfig/src/fccache.c @@ -27,6 +27,7 @@ #include <fcntl.h> #include <dirent.h> #include <string.h> +#include <limits.h> #include <sys/types.h> #include <sys/stat.h> #include <assert.h> @@ -34,6 +35,9 @@ # include <unistd.h> # include <sys/mman.h> #endif +#if defined(_WIN32) +#include <sys/locking.h> +#endif #ifndef O_BINARY #define O_BINARY 0 @@ -177,19 +181,28 @@ FcDirCacheOpenFile (const FcChar8 *cache_file, struct stat *file_stat) */ static FcBool FcDirCacheProcess (FcConfig *config, const FcChar8 *dir, - FcBool (*callback) (int fd, struct stat *fd_stat, + FcBool (*callback) (FcConfig *config, int fd, struct stat *fd_stat, struct stat *dir_stat, void *closure), void *closure, FcChar8 **cache_file_ret) { int fd = -1; FcChar8 cache_base[CACHEBASE_LEN]; FcStrList *list; - FcChar8 *cache_dir; + FcChar8 *cache_dir, *d; struct stat file_stat, dir_stat; FcBool ret = FcFalse; + const FcChar8 *sysroot = FcConfigGetSysRoot (config); - if (FcStatChecksum (dir, &dir_stat) < 0) + if (sysroot) + d = FcStrBuildFilename (sysroot, dir, NULL); + else + d = FcStrdup (dir); + if (FcStatChecksum (d, &dir_stat) < 0) + { + FcStrFree (d); return FcFalse; + } + FcStrFree (d); FcDirCacheBasename (dir, cache_base); @@ -199,7 +212,6 @@ FcDirCacheProcess (FcConfig *config, const FcChar8 *dir, while ((cache_dir = FcStrListNext (list))) { - const FcChar8 *sysroot = FcConfigGetSysRoot (config); FcChar8 *cache_hashed; if (sysroot) @@ -210,7 +222,7 @@ FcDirCacheProcess (FcConfig *config, const FcChar8 *dir, break; fd = FcDirCacheOpenFile (cache_hashed, &file_stat); if (fd >= 0) { - ret = (*callback) (fd, &file_stat, &dir_stat, closure); + ret = (*callback) (config, fd, &file_stat, &dir_stat, closure); close (fd); if (ret) { @@ -245,6 +257,7 @@ struct _FcCacheSkip { dev_t cache_dev; ino_t cache_ino; time_t cache_mtime; + long cache_mtime_nano; FcCacheSkip *next[1]; }; @@ -372,12 +385,18 @@ FcCacheInsert (FcCache *cache, struct stat *cache_stat) s->cache_dev = cache_stat->st_dev; s->cache_ino = cache_stat->st_ino; s->cache_mtime = cache_stat->st_mtime; +#ifdef HAVE_STRUCT_STAT_ST_MTIM + s->cache_mtime_nano = cache_stat->st_mtim.tv_nsec; +#else + s->cache_mtime_nano = 0; +#endif } else { s->cache_dev = 0; s->cache_ino = 0; s->cache_mtime = 0; + s->cache_mtime_nano = 0; } /* @@ -465,6 +484,10 @@ FcCacheFindByStat (struct stat *cache_stat) s->cache_ino == cache_stat->st_ino && s->cache_mtime == cache_stat->st_mtime) { +#ifdef HAVE_STRUCT_STAT_ST_MTIM + if (s->cache_mtime != cache_stat->st_mtim.tv_nsec) + continue; +#endif FcRefInc (&s->ref); unlock_cache (); return s->cache; @@ -529,37 +552,134 @@ FcCacheFini (void) } static FcBool -FcCacheTimeValid (FcCache *cache, struct stat *dir_stat) +FcCacheTimeValid (FcConfig *config, FcCache *cache, struct stat *dir_stat) { struct stat dir_static; + FcBool fnano = FcTrue; if (!dir_stat) { - if (FcStatChecksum (FcCacheDir (cache), &dir_static) < 0) + const FcChar8 *sysroot = FcConfigGetSysRoot (config); + FcChar8 *d; + + if (sysroot) + d = FcStrBuildFilename (sysroot, FcCacheDir (cache), NULL); + else + d = FcStrdup (FcCacheDir (cache)); + if (FcStatChecksum (d, &dir_static) < 0) + { + FcStrFree (d); return FcFalse; + } + FcStrFree (d); dir_stat = &dir_static; } +#ifdef HAVE_STRUCT_STAT_ST_MTIM + fnano = (cache->checksum_nano == dir_stat->st_mtim.tv_nsec); + if (FcDebug () & FC_DBG_CACHE) + printf ("FcCacheTimeValid dir \"%s\" cache checksum %d.%ld dir checksum %d.%ld\n", + FcCacheDir (cache), cache->checksum, (long)cache->checksum_nano, (int) dir_stat->st_mtime, dir_stat->st_mtim.tv_nsec); +#else if (FcDebug () & FC_DBG_CACHE) printf ("FcCacheTimeValid dir \"%s\" cache checksum %d dir checksum %d\n", FcCacheDir (cache), cache->checksum, (int) dir_stat->st_mtime); - return cache->checksum == (int) dir_stat->st_mtime; +#endif + + return cache->checksum == (int) dir_stat->st_mtime && fnano; +} + +static FcBool +FcCacheOffsetsValid (FcCache *cache) +{ + char *base = (char *)cache; + char *end = base + cache->size; + intptr_t *dirs; + FcFontSet *fs; + int i, j; + + if (cache->dir < 0 || cache->dir > cache->size - sizeof (intptr_t) || + memchr (base + cache->dir, '\0', cache->size - cache->dir) == NULL) + return FcFalse; + + if (cache->dirs < 0 || cache->dirs >= cache->size || + cache->dirs_count < 0 || + cache->dirs_count > (cache->size - cache->dirs) / sizeof (intptr_t)) + return FcFalse; + + dirs = FcCacheDirs (cache); + if (dirs) + { + for (i = 0; i < cache->dirs_count; i++) + { + FcChar8 *dir; + + if (dirs[i] < 0 || + dirs[i] > end - (char *) dirs - sizeof (intptr_t)) + return FcFalse; + + dir = FcOffsetToPtr (dirs, dirs[i], FcChar8); + if (memchr (dir, '\0', end - (char *) dir) == NULL) + return FcFalse; + } + } + + if (cache->set < 0 || cache->set > cache->size - sizeof (FcFontSet)) + return FcFalse; + + fs = FcCacheSet (cache); + if (fs) + { + if (fs->nfont > (end - (char *) fs) / sizeof (FcPattern)) + return FcFalse; + + if (fs->fonts != 0 && !FcIsEncodedOffset(fs->fonts)) + return FcFalse; + + for (i = 0; i < fs->nfont; i++) + { + FcPattern *font = FcFontSetFont (fs, i); + FcPatternElt *e; + FcValueListPtr l; + + if ((char *) font < base || + (char *) font > end - sizeof (FcFontSet) || + font->elts_offset < 0 || + font->elts_offset > end - (char *) font || + font->num > (end - (char *) font - font->elts_offset) / sizeof (FcPatternElt)) + return FcFalse; + + + e = FcPatternElts(font); + if (e->values != 0 && !FcIsEncodedOffset(e->values)) + return FcFalse; + + for (j = font->num, l = FcPatternEltValues(e); j >= 0 && l; j--, l = FcValueListNext(l)) + if (l->next != NULL && !FcIsEncodedOffset(l->next)) + break; + if (j < 0) + return FcFalse; + } + } + + return FcTrue; } /* * Map a cache file into memory */ static FcCache * -FcDirCacheMapFd (int fd, struct stat *fd_stat, struct stat *dir_stat) +FcDirCacheMapFd (FcConfig *config, int fd, struct stat *fd_stat, struct stat *dir_stat) { FcCache *cache; FcBool allocated = FcFalse; - if (fd_stat->st_size < (int) sizeof (FcCache)) + if (fd_stat->st_size > INTPTR_MAX || + fd_stat->st_size < (int) sizeof (FcCache)) return NULL; cache = FcCacheFindByStat (fd_stat); if (cache) { - if (FcCacheTimeValid (cache, dir_stat)) + if (FcCacheTimeValid (config, cache, dir_stat)) return cache; FcDirCacheUnload (cache); cache = NULL; @@ -608,9 +728,10 @@ FcDirCacheMapFd (int fd, struct stat *fd_stat, struct stat *dir_stat) allocated = FcTrue; } if (cache->magic != FC_CACHE_MAGIC_MMAP || - cache->version < FC_CACHE_CONTENT_VERSION || + cache->version < FC_CACHE_VERSION_NUMBER || cache->size != (intptr_t) fd_stat->st_size || - !FcCacheTimeValid (cache, dir_stat) || + !FcCacheOffsetsValid (cache) || + !FcCacheTimeValid (config, cache, dir_stat) || !FcCacheInsert (cache, fd_stat)) { if (allocated) @@ -649,9 +770,9 @@ FcDirCacheUnload (FcCache *cache) } static FcBool -FcDirCacheMapHelper (int fd, struct stat *fd_stat, struct stat *dir_stat, void *closure) +FcDirCacheMapHelper (FcConfig *config, int fd, struct stat *fd_stat, struct stat *dir_stat, void *closure) { - FcCache *cache = FcDirCacheMapFd (fd, fd_stat, dir_stat); + FcCache *cache = FcDirCacheMapFd (config, fd, fd_stat, dir_stat); if (!cache) return FcFalse; @@ -668,6 +789,7 @@ FcDirCacheLoad (const FcChar8 *dir, FcConfig *config, FcChar8 **cache_file) FcDirCacheMapHelper, &cache, cache_file)) return NULL; + return cache; } @@ -683,7 +805,7 @@ FcDirCacheLoadFile (const FcChar8 *cache_file, struct stat *file_stat) fd = FcDirCacheOpenFile (cache_file, file_stat); if (fd < 0) return NULL; - cache = FcDirCacheMapFd (fd, file_stat, NULL); + cache = FcDirCacheMapFd (FcConfigGetCurrent (), fd, file_stat, NULL); close (fd); return cache; } @@ -693,7 +815,7 @@ FcDirCacheLoadFile (const FcChar8 *cache_file, struct stat *file_stat) * the magic number and the size field */ static FcBool -FcDirCacheValidateHelper (int fd, struct stat *fd_stat, struct stat *dir_stat, void *closure FC_UNUSED) +FcDirCacheValidateHelper (FcConfig *config, int fd, struct stat *fd_stat, struct stat *dir_stat, void *closure FC_UNUSED) { FcBool ret = FcTrue; FcCache c; @@ -702,12 +824,16 @@ FcDirCacheValidateHelper (int fd, struct stat *fd_stat, struct stat *dir_stat, v ret = FcFalse; else if (c.magic != FC_CACHE_MAGIC_MMAP) ret = FcFalse; - else if (c.version < FC_CACHE_CONTENT_VERSION) + else if (c.version < FC_CACHE_VERSION_NUMBER) ret = FcFalse; else if (fd_stat->st_size != c.size) ret = FcFalse; else if (c.checksum != (int) dir_stat->st_mtime) ret = FcFalse; +#ifdef HAVE_STRUCT_STAT_ST_MTIM + else if (c.checksum_nano != dir_stat->st_mtim.tv_nsec) + ret = FcFalse; +#endif return ret; } @@ -779,9 +905,12 @@ FcDirCacheBuild (FcFontSet *set, const FcChar8 *dir, struct stat *dir_stat, FcSt serialize->linear = cache; cache->magic = FC_CACHE_MAGIC_ALLOC; - cache->version = FC_CACHE_CONTENT_VERSION; + cache->version = FC_CACHE_VERSION_NUMBER; cache->size = serialize->size; cache->checksum = (int) dir_stat->st_mtime; +#ifdef HAVE_STRUCT_STAT_ST_MTIM + cache->checksum_nano = dir_stat->st_mtim.tv_nsec; +#endif /* * Serialize directory name @@ -969,6 +1098,11 @@ FcDirCacheWrite (FcCache *cache, FcConfig *config) skip->cache_dev = cache_stat.st_dev; skip->cache_ino = cache_stat.st_ino; skip->cache_mtime = cache_stat.st_mtime; +#ifdef HAVE_STRUCT_STAT_ST_MTIM + skip->cache_mtime_nano = cache_stat.st_mtim.tv_nsec; +#else + skip->cache_mtime_nano = 0; +#endif } unlock_cache (); } @@ -1058,15 +1192,22 @@ FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose) } else { + FcChar8 *s; + target_dir = FcCacheDir (cache); - if (stat ((char *) target_dir, &target_stat) < 0) + if (sysroot) + s = FcStrBuildFilename (sysroot, target_dir, NULL); + else + s = FcStrdup (target_dir); + if (stat ((char *) s, &target_stat) < 0) { if (verbose || FcDebug () & FC_DBG_CACHE) printf ("%s: %s: missing directory: %s \n", - dir, ent->d_name, target_dir); + dir, ent->d_name, s); remove = FcTrue; } FcDirCacheUnload (cache); + FcStrFree (s); } if (remove) { @@ -1086,6 +1227,82 @@ FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose) return ret; } +int +FcDirCacheLock (const FcChar8 *dir, + FcConfig *config) +{ + FcChar8 *cache_hashed = NULL; + FcChar8 cache_base[CACHEBASE_LEN]; + FcStrList *list; + FcChar8 *cache_dir; + const FcChar8 *sysroot = FcConfigGetSysRoot (config); + int fd = -1; + + FcDirCacheBasename (dir, cache_base); + list = FcStrListCreate (config->cacheDirs); + if (!list) + return -1; + + while ((cache_dir = FcStrListNext (list))) + { + if (sysroot) + cache_hashed = FcStrBuildFilename (sysroot, cache_dir, cache_base, NULL); + else + cache_hashed = FcStrBuildFilename (cache_dir, cache_base, NULL); + if (!cache_hashed) + break; + fd = FcOpen ((const char *)cache_hashed, O_RDWR); + FcStrFree (cache_hashed); + /* No caches in that directory. simply retry with another one */ + if (fd != -1) + { +#if defined(_WIN32) + if (_locking (fd, _LK_LOCK, 1) == -1) + goto bail; +#else + struct flock fl; + + fl.l_type = F_WRLCK; + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = 0; + fl.l_pid = getpid (); + if (fcntl (fd, F_SETLKW, &fl) == -1) + goto bail; +#endif + break; + } + } + FcStrListDone (list); + return fd; +bail: + FcStrListDone (list); + if (fd != -1) + close (fd); + return -1; +} + +void +FcDirCacheUnlock (int fd) +{ + if (fd != -1) + { +#if defined(_WIN32) + _locking (fd, _LK_UNLCK, 1); +#else + struct flock fl; + + fl.l_type = F_UNLCK; + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = 0; + fl.l_pid = getpid (); + fcntl (fd, F_SETLK, &fl); +#endif + close (fd); + } +} + /* * Hokey little macro trick to permit the definitions of C functions * with the same name as CPP macros diff --git a/dist/fontconfig/src/fccfg.c b/dist/fontconfig/src/fccfg.c index 6377fd7c6..9f8ee7c7e 100644 --- a/dist/fontconfig/src/fccfg.c +++ b/dist/fontconfig/src/fccfg.c @@ -27,6 +27,7 @@ #include "fcint.h" #include <dirent.h> #include <sys/types.h> +#include "../fc-blanks/fcblanks.h" #if defined (_WIN32) && !defined (R_OK) #define R_OK 4 @@ -109,7 +110,7 @@ FcConfigCreate (void) if (!config->cacheDirs) goto bail8; - config->blanks = 0; + config->blanks = &fcBlanks; config->substPattern = 0; config->substFont = 0; @@ -375,7 +376,7 @@ FcConfigAddDirList (FcConfig *config, FcSetName set, FcStrSet *dirSet) while ((dir = FcStrListNext (dirlist))) { if (FcDebug () & FC_DBG_FONTSET) - printf ("adding fonts from%s\n", dir); + printf ("adding fonts from %s\n", dir); cache = FcDirCacheRead (dir, FcFalse, config); if (!cache) continue; @@ -434,6 +435,7 @@ retry: if (!fc_atomic_ptr_cmpexch (&_fcConfig, cfg, config)) goto retry; + FcConfigReference (config); if (cfg) FcConfigDestroy (cfg); @@ -722,6 +724,21 @@ FcConfigPromote (FcValue v, FcValue u, FcValuePromotionBuffer *buf) v.u.l = FcLangSetPromote (v.u.s, buf); v.type = FcTypeLangSet; } + else if (v.type == FcTypeVoid && u.type == FcTypeLangSet) + { + v.u.l = FcLangSetPromote (NULL, buf); + v.type = FcTypeLangSet; + } + else if (v.type == FcTypeVoid && u.type == FcTypeCharSet) + { + v.u.c = FcCharSetPromote (buf); + v.type = FcTypeCharSet; + } + if (buf && v.type == FcTypeDouble && u.type == FcTypeRange) + { + v.u.r = FcRangePromote (v.u.d, buf); + v.type = FcTypeRange; + } return v; } @@ -894,6 +911,9 @@ FcConfigCompareValue (const FcValue *left_o, break; } break; + case FcTypeRange: + ret = FcRangeCompare (op, left.u.r, right.u.r); + break; } } else @@ -915,10 +935,11 @@ FcConfigCompareValue (const FcValue *left_o, static FcValue FcConfigEvaluate (FcPattern *p, FcPattern *p_pat, FcMatchKind kind, FcExpr *e) { - FcValue v, vl, vr; + FcValue v, vl, vr, vle, vre; FcMatrix *m; FcChar8 *str; FcOp op = FC_OP_GET_OP (e->op); + FcValuePromotionBuffer buf1, buf2; switch ((int) op) { case FcOpInteger: @@ -967,6 +988,11 @@ FcConfigEvaluate (FcPattern *p, FcPattern *p_pat, FcMatchKind kind, FcExpr *e) v.u.l = e->u.lval; v = FcValueSave (v); break; + case FcOpRange: + v.type = FcTypeRange; + v.u.r = e->u.rval; + v = FcValueSave (v); + break; case FcOpBool: v.type = FcTypeBool; v.u.b = e->u.bval; @@ -1033,28 +1059,28 @@ FcConfigEvaluate (FcPattern *p, FcPattern *p_pat, FcMatchKind kind, FcExpr *e) case FcOpDivide: vl = FcConfigEvaluate (p, p_pat, kind, e->u.tree.left); vr = FcConfigEvaluate (p, p_pat, kind, e->u.tree.right); - vl = FcConfigPromote (vl, vr, NULL); - vr = FcConfigPromote (vr, vl, NULL); - if (vl.type == vr.type) + vle = FcConfigPromote (vl, vr, &buf1); + vre = FcConfigPromote (vr, vle, &buf2); + if (vle.type == vre.type) { - switch ((int) vl.type) { + switch ((int) vle.type) { case FcTypeDouble: switch ((int) op) { case FcOpPlus: v.type = FcTypeDouble; - v.u.d = vl.u.d + vr.u.d; + v.u.d = vle.u.d + vre.u.d; break; case FcOpMinus: v.type = FcTypeDouble; - v.u.d = vl.u.d - vr.u.d; + v.u.d = vle.u.d - vre.u.d; break; case FcOpTimes: v.type = FcTypeDouble; - v.u.d = vl.u.d * vr.u.d; + v.u.d = vle.u.d * vre.u.d; break; case FcOpDivide: v.type = FcTypeDouble; - v.u.d = vl.u.d / vr.u.d; + v.u.d = vle.u.d / vre.u.d; break; default: v.type = FcTypeVoid; @@ -1071,11 +1097,11 @@ FcConfigEvaluate (FcPattern *p, FcPattern *p_pat, FcMatchKind kind, FcExpr *e) switch ((int) op) { case FcOpOr: v.type = FcTypeBool; - v.u.b = vl.u.b || vr.u.b; + v.u.b = vle.u.b || vre.u.b; break; case FcOpAnd: v.type = FcTypeBool; - v.u.b = vl.u.b && vr.u.b; + v.u.b = vle.u.b && vre.u.b; break; default: v.type = FcTypeVoid; @@ -1086,7 +1112,7 @@ FcConfigEvaluate (FcPattern *p, FcPattern *p_pat, FcMatchKind kind, FcExpr *e) switch ((int) op) { case FcOpPlus: v.type = FcTypeString; - str = FcStrPlus (vl.u.s, vr.u.s); + str = FcStrPlus (vle.u.s, vre.u.s); v.u.s = FcStrdup (str); FcStrFree (str); @@ -1105,7 +1131,7 @@ FcConfigEvaluate (FcPattern *p, FcPattern *p_pat, FcMatchKind kind, FcExpr *e) m = malloc (sizeof (FcMatrix)); if (m) { - FcMatrixMultiply (m, vl.u.m, vr.u.m); + FcMatrixMultiply (m, vle.u.m, vre.u.m); v.u.m = m; } else @@ -1122,13 +1148,13 @@ FcConfigEvaluate (FcPattern *p, FcPattern *p_pat, FcMatchKind kind, FcExpr *e) switch ((int) op) { case FcOpPlus: v.type = FcTypeCharSet; - v.u.c = FcCharSetUnion (vl.u.c, vr.u.c); + v.u.c = FcCharSetUnion (vle.u.c, vre.u.c); if (!v.u.c) v.type = FcTypeVoid; break; case FcOpMinus: v.type = FcTypeCharSet; - v.u.c = FcCharSetSubtract (vl.u.c, vr.u.c); + v.u.c = FcCharSetSubtract (vle.u.c, vre.u.c); if (!v.u.c) v.type = FcTypeVoid; break; @@ -1141,13 +1167,13 @@ FcConfigEvaluate (FcPattern *p, FcPattern *p_pat, FcMatchKind kind, FcExpr *e) switch ((int) op) { case FcOpPlus: v.type = FcTypeLangSet; - v.u.l = FcLangSetUnion (vl.u.l, vr.u.l); + v.u.l = FcLangSetUnion (vle.u.l, vre.u.l); if (!v.u.l) v.type = FcTypeVoid; break; case FcOpMinus: v.type = FcTypeLangSet; - v.u.l = FcLangSetSubtract (vl.u.l, vr.u.l); + v.u.l = FcLangSetSubtract (vle.u.l, vre.u.l); if (!v.u.l) v.type = FcTypeVoid; break; @@ -1518,15 +1544,52 @@ FcConfigSubstituteWithPat (FcConfig *config, FcStrList *l = FcStrListCreate (strs); FcChar8 *lang; FcValue v; + FcLangSet *lsund = FcLangSetCreate (); + FcLangSetAdd (lsund, (const FcChar8 *)"und"); FcStrSetDestroy (strs); while (l && (lang = FcStrListNext (l))) { + FcPatternElt *e = FcPatternObjectFindElt (p, FC_LANG_OBJECT); + + if (e) + { + FcValueListPtr ll; + + for (ll = FcPatternEltValues (e); ll; ll = FcValueListNext (ll)) + { + FcValue vv = FcValueCanonicalize (&ll->value); + + if (vv.type == FcTypeLangSet) + { + FcLangSet *ls = FcLangSetCreate (); + FcBool b; + + FcLangSetAdd (ls, lang); + b = FcLangSetContains (vv.u.l, ls); + FcLangSetDestroy (ls); + if (b) + goto bail_lang; + if (FcLangSetContains (vv.u.l, lsund)) + goto bail_lang; + } + else + { + if (FcStrCmpIgnoreCase (vv.u.s, lang) == 0) + goto bail_lang; + if (FcStrCmpIgnoreCase (vv.u.s, (const FcChar8 *)"und") == 0) + goto bail_lang; + } + } + } v.type = FcTypeString; v.u.s = lang; + FcPatternObjectAddWithBinding (p, FC_LANG_OBJECT, v, FcValueBindingWeak, FcTrue); } + bail_lang: FcStrListDone (l); + FcLangSetDestroy (lsund); } if (FcPatternObjectGet (p, FC_PRGNAME_OBJECT, 0, &v) == FcResultNoMatch) { @@ -1778,6 +1841,7 @@ FcConfigSubstitute (FcConfig *config, #if defined (_WIN32) static FcChar8 fontconfig_path[1000] = ""; /* MT-dontcare */ +FcChar8 fontconfig_instprefix[1000] = ""; /* MT-dontcare */ # if (defined (PIC) || defined (DLL_EXPORT)) @@ -1812,6 +1876,7 @@ DllMain (HINSTANCE hinstDLL, if (p && (FcStrCmpIgnoreCase (p + 1, (const FcChar8 *) "bin") == 0 || FcStrCmpIgnoreCase (p + 1, (const FcChar8 *) "lib") == 0)) *p = '\0'; + strcat ((char *) fontconfig_instprefix, (char *) fontconfig_path); strcat ((char *) fontconfig_path, "\\etc\\fonts"); } else @@ -1985,6 +2050,8 @@ FcConfigXdgCacheHome (void) const char *env = getenv ("XDG_CACHE_HOME"); FcChar8 *ret = NULL; + if (!_FcConfigHomeEnabled) + return NULL; if (env) ret = FcStrCopy ((const FcChar8 *)env); else @@ -2010,6 +2077,8 @@ FcConfigXdgConfigHome (void) const char *env = getenv ("XDG_CONFIG_HOME"); FcChar8 *ret = NULL; + if (!_FcConfigHomeEnabled) + return NULL; if (env) ret = FcStrCopy ((const FcChar8 *)env); else @@ -2035,6 +2104,8 @@ FcConfigXdgDataHome (void) const char *env = getenv ("XDG_DATA_HOME"); FcChar8 *ret = NULL; + if (!_FcConfigHomeEnabled) + return NULL; if (env) ret = FcStrCopy ((const FcChar8 *)env); else @@ -2134,7 +2205,7 @@ FcConfigAppFontAddFile (FcConfig *config, return FcFalse; } - subdirs = FcStrSetCreate (); + subdirs = FcStrSetCreateEx (FCSS_GROW_BY_64); if (!subdirs) return FcFalse; @@ -2181,7 +2252,7 @@ FcConfigAppFontAddDir (FcConfig *config, return FcFalse; } - dirs = FcStrSetCreate (); + dirs = FcStrSetCreateEx (FCSS_GROW_BY_64); if (!dirs) return FcFalse; @@ -2312,7 +2383,7 @@ void FcConfigSetSysRoot (FcConfig *config, const FcChar8 *sysroot) { - FcChar8 *s; + FcChar8 *s = NULL; FcBool init = FcFalse; if (!config) @@ -2332,9 +2403,12 @@ FcConfigSetSysRoot (FcConfig *config, } } - s = FcStrCopyFilename (sysroot); - if (!s) - return; + if (sysroot) + { + s = FcStrCopyFilename (sysroot); + if (!s) + return; + } if (config->sysRoot) FcStrFree (config->sysRoot); @@ -2344,6 +2418,10 @@ FcConfigSetSysRoot (FcConfig *config, { config = FcInitLoadOwnConfigAndFonts (config); FcConfigSetCurrent (config); + /* FcConfigSetCurrent() increases the refcount. + * decrease it here to avoid the memory leak. + */ + FcConfigDestroy (config); } } diff --git a/dist/fontconfig/src/fccharset.c b/dist/fontconfig/src/fccharset.c index c9f928cd4..3f1789230 100644 --- a/dist/fontconfig/src/fccharset.c +++ b/dist/fontconfig/src/fccharset.c @@ -43,6 +43,21 @@ FcCharSetCreate (void) } FcCharSet * +FcCharSetPromote (FcValuePromotionBuffer *vbuf) +{ + FcCharSet *fcs = (FcCharSet *) vbuf; + + FC_ASSERT_STATIC (sizeof (FcCharSet) <= sizeof (FcValuePromotionBuffer)); + + FcRefSetConst (&fcs->ref); + fcs->num = 0; + fcs->leaves_offset = 0; + fcs->numbers_offset = 0; + + return fcs; +} + +FcCharSet * FcCharSetNew (void) { return FcCharSetCreate (); @@ -149,6 +164,14 @@ FcCharSetPutLeaf (FcCharSet *fcs, unsigned int alloced = 8; leaves = malloc (alloced * sizeof (*leaves)); numbers = malloc (alloced * sizeof (*numbers)); + if (!leaves || !numbers) + { + if (leaves) + free (leaves); + if (numbers) + free (numbers); + return FcFalse; + } } else { @@ -157,8 +180,19 @@ FcCharSetPutLeaf (FcCharSet *fcs, alloced *= 2; new_leaves = realloc (leaves, alloced * sizeof (*leaves)); + if (!new_leaves) + return FcFalse; numbers = realloc (numbers, alloced * sizeof (*numbers)); - + if (!numbers) + { + /* Revert the reallocation of leaves */ + leaves = realloc (new_leaves, (alloced / 2) * sizeof (*new_leaves)); + /* unlikely to fail though */ + if (!leaves) + return FcFalse; + fcs->leaves_offset = FcPtrToOffset (fcs, leaves); + return FcFalse; + } distance = (intptr_t) new_leaves - (intptr_t) leaves; if (new_leaves && distance) { @@ -169,9 +203,6 @@ FcCharSetPutLeaf (FcCharSet *fcs, leaves = new_leaves; } - if (!leaves || !numbers) - return FcFalse; - fcs->leaves_offset = FcPtrToOffset (fcs, leaves); fcs->numbers_offset = FcPtrToOffset (fcs, numbers); } @@ -800,188 +831,123 @@ FcCharSetCoverage (const FcCharSet *a, FcChar32 page, FcChar32 *result) return page; } -/* - * ASCII representation of charsets. - * - * Each leaf is represented as 9 32-bit values, the code of the first character followed - * by 8 32 bit values for the leaf itself. Each value is encoded as 5 ASCII characters, - * only 85 different values are used to avoid control characters as well as the other - * characters used to encode font names. 85**5 > 2^32 so things work out, but - * it's not exactly human readable output. As a special case, 0 is encoded as a space - */ - -static const unsigned char charToValue[256] = { - /* "" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* "\b" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* "\020" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* "\030" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* " " */ 0xff, 0x00, 0xff, 0x01, 0x02, 0x03, 0x04, 0xff, - /* "(" */ 0x05, 0x06, 0x07, 0x08, 0xff, 0xff, 0x09, 0x0a, - /* "0" */ 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, - /* "8" */ 0x13, 0x14, 0xff, 0x15, 0x16, 0xff, 0x17, 0x18, - /* "@" */ 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, - /* "H" */ 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, - /* "P" */ 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, - /* "X" */ 0x31, 0x32, 0x33, 0x34, 0xff, 0x35, 0x36, 0xff, - /* "`" */ 0xff, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, - /* "h" */ 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, - /* "p" */ 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, - /* "x" */ 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0xff, - /* "\200" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* "\210" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* "\220" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* "\230" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* "\240" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* "\250" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* "\260" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* "\270" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* "\300" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* "\310" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* "\320" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* "\330" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* "\340" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* "\350" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* "\360" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* "\370" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -}; - -static const FcChar8 valueToChar[0x55] = { - /* 0x00 */ '!', '#', '$', '%', '&', '(', ')', '*', - /* 0x08 */ '+', '.', '/', '0', '1', '2', '3', '4', - /* 0x10 */ '5', '6', '7', '8', '9', ';', '<', '>', - /* 0x18 */ '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', - /* 0x20 */ 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', - /* 0x28 */ 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', - /* 0x30 */ 'W', 'X', 'Y', 'Z', '[', ']', '^', 'a', - /* 0x38 */ 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', - /* 0x40 */ 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', - /* 0x48 */ 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', - /* 0x50 */ 'z', '{', '|', '}', '~', -}; - -static FcChar8 * -FcCharSetParseValue (FcChar8 *string, FcChar32 *value) -{ - int i; - FcChar32 v; - FcChar32 c; - - if (*string == ' ') - { - v = 0; - string++; - } - else - { - v = 0; - for (i = 0; i < 5; i++) - { - if (!(c = (FcChar32) (unsigned char) *string++)) - return 0; - c = charToValue[c]; - if (c == 0xff) - return 0; - v = v * 85 + c; - } - } - *value = v; - return string; -} - static FcBool -FcCharSetUnparseValue (FcStrBuf *buf, FcChar32 value) +FcNameParseRange (FcChar8 **string, FcChar32 *pfirst, FcChar32 *plast) { - int i; - if (value == 0) - { - return FcStrBufChar (buf, ' '); - } - else - { - FcChar8 string[6]; - FcChar8 *s = string + 5; - string[5] = '\0'; - for (i = 0; i < 5; i++) + char *s = (char *) *string; + char *t; + long first, last; + + while (isspace(*s)) + s++; + t = s; + errno = 0; + first = last = strtol (s, &s, 16); + if (errno) + return FcFalse; + while (isspace(*s)) + s++; + if (*s == '-') { - *--s = valueToChar[value % 85]; - value /= 85; - } - for (i = 0; i < 5; i++) - if (!FcStrBufChar (buf, *s++)) + s++; + errno = 0; + last = strtol (s, &s, 16); + if (errno) return FcFalse; - } - return FcTrue; + } + + if (s == t || first < 0 || last < 0 || last < first || last > 0x10ffff) + return FcFalse; + + *string = (FcChar8 *) s; + *pfirst = first; + *plast = last; + return FcTrue; } FcCharSet * FcNameParseCharSet (FcChar8 *string) { FcCharSet *c; - FcChar32 ucs4; - FcCharLeaf *leaf; - FcCharLeaf temp; - FcChar32 bits; - int i; + FcChar32 first, last; c = FcCharSetCreate (); if (!c) goto bail0; while (*string) { - string = FcCharSetParseValue (string, &ucs4); - if (!string) - goto bail1; - bits = 0; - for (i = 0; i < 256/32; i++) - { - string = FcCharSetParseValue (string, &temp.map[i]); - if (!string) - goto bail1; - bits |= temp.map[i]; - } - if (bits) - { - leaf = malloc (sizeof (FcCharLeaf)); - if (!leaf) - goto bail1; - *leaf = temp; - if (!FcCharSetInsertLeaf (c, ucs4, leaf)) + FcChar32 u; + + if (!FcNameParseRange (&string, &first, &last)) goto bail1; - } + + for (u = first; u < last + 1; u++) + FcCharSetAddChar (c, u); } return c; bail1: - if (c->num) - { - free (FcCharSetLeaves (c)); - } - if (c->num) - { - free (FcCharSetNumbers (c)); - } - free (c); + FcCharSetDestroy (c); bail0: return NULL; } +static void +FcNameUnparseUnicode (FcStrBuf *buf, FcChar32 u) +{ + FcChar8 buf_static[64]; + snprintf ((char *) buf_static, sizeof (buf_static), "%x", u); + FcStrBufString (buf, buf_static); +} + FcBool FcNameUnparseCharSet (FcStrBuf *buf, const FcCharSet *c) { FcCharSetIter ci; + FcChar32 first, last; int i; #ifdef CHECK int len = buf->len; #endif + first = last = 0x7FFFFFFF; + for (FcCharSetIterStart (c, &ci); ci.leaf; FcCharSetIterNext (c, &ci)) { - if (!FcCharSetUnparseValue (buf, ci.ucs4)) - return FcFalse; for (i = 0; i < 256/32; i++) - if (!FcCharSetUnparseValue (buf, ci.leaf->map[i])) - return FcFalse; + { + FcChar32 bits = ci.leaf->map[i]; + FcChar32 u = ci.ucs4 + i * 32; + + while (bits) + { + if (bits & 1) + { + if (u != last + 1) + { + if (last != first) + { + FcStrBufChar (buf, '-'); + FcNameUnparseUnicode (buf, last); + } + if (last != 0x7FFFFFFF) + FcStrBufChar (buf, ' '); + /* Start new range. */ + first = u; + FcNameUnparseUnicode (buf, u); + } + last = u; + } + bits >>= 1; + u++; + } + } + } + if (last != first) + { + FcStrBufChar (buf, '-'); + FcNameUnparseUnicode (buf, last); } #ifdef CHECK { diff --git a/dist/fontconfig/src/fccompat.c b/dist/fontconfig/src/fccompat.c index bb2d70eff..e67cf3131 100644 --- a/dist/fontconfig/src/fccompat.c +++ b/dist/fontconfig/src/fccompat.c @@ -257,3 +257,7 @@ FcMakeDirectory (const FcChar8 *dir) FcStrFree (parent); return ret; } + +#define __fccompat__ +#include "fcaliastail.h" +#undef __fccompat__ diff --git a/dist/fontconfig/src/fcdbg.c b/dist/fontconfig/src/fcdbg.c index d74bc2769..c2853fff3 100644 --- a/dist/fontconfig/src/fcdbg.c +++ b/dist/fontconfig/src/fcdbg.c @@ -61,6 +61,9 @@ _FcValuePrintFile (FILE *f, const FcValue v) case FcTypeFTFace: fprintf (f, "face"); break; + case FcTypeRange: + fprintf (f, "[%g %g)", v.u.r->begin, v.u.r->end); + break; } } @@ -208,6 +211,84 @@ FcPatternPrint (const FcPattern *p) } void +FcPatternPrint2 (FcPattern *pp1, + FcPattern *pp2, + const FcObjectSet *os) +{ + int i, j, k, pos; + FcPatternElt *e1, *e2; + FcPattern *p1, *p2; + + if (os) + { + p1 = FcPatternFilter (pp1, os); + p2 = FcPatternFilter (pp2, os); + } + else + { + p1 = pp1; + p2 = pp2; + } + printf ("Pattern has %d elts (size %d), %d elts (size %d)\n", + p1->num, p1->size, p2->num, p2->size); + for (i = 0, j = 0; i < p1->num; i++) + { + e1 = &FcPatternElts(p1)[i]; + e2 = &FcPatternElts(p2)[j]; + if (!e2 || e1->object != e2->object) + { + pos = FcPatternPosition (p2, FcObjectName (e1->object)); + if (pos >= 0) + { + for (k = j; k < pos; k++) + { + e2 = &FcPatternElts(p2)[k]; + printf ("\t%s: (None) -> ", FcObjectName (e2->object)); + FcValueListPrint (FcPatternEltValues (e2)); + printf ("\n"); + } + j = pos; + goto cont; + } + else + { + printf ("\t%s:", FcObjectName (e1->object)); + FcValueListPrint (FcPatternEltValues (e1)); + printf (" -> (None)\n"); + } + } + else + { + cont: + printf ("\t%s:", FcObjectName (e1->object)); + FcValueListPrint (FcPatternEltValues (e1)); + printf (" -> "); + e2 = &FcPatternElts(p2)[j]; + FcValueListPrint (FcPatternEltValues (e2)); + printf ("\n"); + j++; + } + } + if (j < p2->num) + { + for (k = j; k < p2->num; k++) + { + e2 = &FcPatternElts(p2)[k]; + if (FcObjectName (e2->object)) + { + printf ("\t%s: (None) -> ", FcObjectName (e2->object)); + FcValueListPrint (FcPatternEltValues (e2)); + printf ("\n"); + } + } + } + if (p1 != pp1) + FcPatternDestroy (p1); + if (p2 != pp2) + FcPatternDestroy (p2); +} + +void FcOpPrint (FcOp op_) { FcOp op = FC_OP_GET_OP (op_); @@ -277,7 +358,9 @@ FcExprPrint (const FcExpr *expr) FcExprPrint (expr->u.mexpr->yy); printf ("]"); break; - case FcOpRange: break; + case FcOpRange: + printf ("(%g, %g)", expr->u.rval->begin, expr->u.rval->end); + break; case FcOpBool: printf ("%s", expr->u.bval ? "true" : "false"); break; case FcOpCharSet: printf ("charset\n"); break; case FcOpLangSet: diff --git a/dist/fontconfig/src/fcdefault.c b/dist/fontconfig/src/fcdefault.c index 4beda7c00..6647a8fe8 100644 --- a/dist/fontconfig/src/fcdefault.c +++ b/dist/fontconfig/src/fcdefault.c @@ -38,6 +38,7 @@ static const struct { { FC_GLOBAL_ADVANCE_OBJECT, FcTrue }, /* !FC_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH */ { FC_EMBEDDED_BITMAP_OBJECT, FcTrue }, /* !FC_LOAD_NO_BITMAP */ { FC_DECORATIVE_OBJECT, FcFalse }, + { FC_SYMBOL_OBJECT, FcFalse }, }; #define NUM_FC_BOOL_DEFAULTS (int) (sizeof FcBoolDefaults / sizeof FcBoolDefaults[0]) @@ -94,7 +95,6 @@ retry: { FcStrSet *langs = FcGetDefaultLangs (); lang = FcStrdup (langs->strs[0]); - FcStrSetDestroy (langs); if (!fc_atomic_ptr_cmpexch (&default_lang, NULL, lang)) { free (lang); @@ -219,6 +219,7 @@ FcDefaultSubstitute (FcPattern *pattern) { FcValue v, namelang, v2; int i; + double dpi, size, scale, pixelsize; if (FcPatternObjectGet (pattern, FC_WEIGHT_OBJECT, 0, &v) == FcResultNoMatch ) FcPatternObjectAddInteger (pattern, FC_WEIGHT_OBJECT, FC_WEIGHT_NORMAL); @@ -233,32 +234,30 @@ FcDefaultSubstitute (FcPattern *pattern) if (FcPatternObjectGet (pattern, FcBoolDefaults[i].field, 0, &v) == FcResultNoMatch) FcPatternObjectAddBool (pattern, FcBoolDefaults[i].field, FcBoolDefaults[i].value); - if (FcPatternObjectGet (pattern, FC_PIXEL_SIZE_OBJECT, 0, &v) == FcResultNoMatch) - { - double dpi, size, scale; + if (FcPatternObjectGetDouble (pattern, FC_SIZE_OBJECT, 0, &size) != FcResultMatch) + size = 12.0L; + if (FcPatternObjectGetDouble (pattern, FC_SCALE_OBJECT, 0, &scale) != FcResultMatch) + scale = 1.0; + if (FcPatternObjectGetDouble (pattern, FC_DPI_OBJECT, 0, &dpi) != FcResultMatch) + dpi = 75.0; - if (FcPatternObjectGetDouble (pattern, FC_SIZE_OBJECT, 0, &size) != FcResultMatch) - { - size = 12.0; - (void) FcPatternObjectDel (pattern, FC_SIZE_OBJECT); - FcPatternObjectAddDouble (pattern, FC_SIZE_OBJECT, size); - } - if (FcPatternObjectGetDouble (pattern, FC_SCALE_OBJECT, 0, &scale) != FcResultMatch) - { - scale = 1.0; - (void) FcPatternObjectDel (pattern, FC_SCALE_OBJECT); - FcPatternObjectAddDouble (pattern, FC_SCALE_OBJECT, scale); - } - size *= scale; - if (FcPatternObjectGetDouble (pattern, FC_DPI_OBJECT, 0, &dpi) != FcResultMatch) - { - dpi = 75.0; - (void) FcPatternObjectDel (pattern, FC_DPI_OBJECT); - FcPatternObjectAddDouble (pattern, FC_DPI_OBJECT, dpi); - } - size *= dpi / 72.0; - FcPatternObjectAddDouble (pattern, FC_PIXEL_SIZE_OBJECT, size); + if (FcPatternObjectGet (pattern, FC_PIXEL_SIZE_OBJECT, 0, &v) != FcResultMatch) + { + (void) FcPatternObjectDel (pattern, FC_SCALE_OBJECT); + FcPatternObjectAddDouble (pattern, FC_SCALE_OBJECT, scale); + pixelsize = size * scale; + (void) FcPatternObjectDel (pattern, FC_DPI_OBJECT); + FcPatternObjectAddDouble (pattern, FC_DPI_OBJECT, dpi); + pixelsize *= dpi / 72.0; + FcPatternObjectAddDouble (pattern, FC_PIXEL_SIZE_OBJECT, pixelsize); + } + else + { + size = v.u.d; + size = size / dpi * 72.0 / scale; } + (void) FcPatternObjectDel (pattern, FC_SIZE_OBJECT); + FcPatternObjectAddDouble (pattern, FC_SIZE_OBJECT, size); if (FcPatternObjectGet (pattern, FC_FONTVERSION_OBJECT, 0, &v) == FcResultNoMatch) { diff --git a/dist/fontconfig/src/fcdir.c b/dist/fontconfig/src/fcdir.c index 3bcd0b867..fd62a342f 100644 --- a/dist/fontconfig/src/fcdir.c +++ b/dist/fontconfig/src/fcdir.c @@ -23,6 +23,9 @@ */ #include "fcint.h" +#include "fcftint.h" +#include <ft2build.h> +#include FT_FREETYPE_H #include <dirent.h> FcBool @@ -65,12 +68,20 @@ FcFileScanFontConfig (FcFontSet *set, const FcChar8 *file, FcConfig *config) { + FT_Library ftLibrary; + FT_Face face; FcPattern *font; FcBool ret = FcTrue; + int num_faces = 0; + int num_instances = 0; + int face_num = 0; + int instance_num = 0; int id; - int count = 0; + const FcChar8 *sysroot = FcConfigGetSysRoot (config); + + if (FT_Init_FreeType (&ftLibrary)) + return FcFalse; - id = 0; do { font = 0; @@ -82,9 +93,39 @@ FcFileScanFontConfig (FcFontSet *set, printf ("\tScanning file %s...", file); fflush (stdout); } - font = FcFreeTypeQuery (file, id, blanks, &count); + + id = ((instance_num << 16) + face_num); + if (FT_New_Face (ftLibrary, (char *) file, id, &face)) + return FcFalse; + num_faces = face->num_faces; + num_instances = face->style_flags >> 16; + font = FcFreeTypeQueryFace (face, file, id, blanks); + FT_Done_Face (face); + if (FcDebug () & FC_DBG_SCAN) printf ("done\n"); + /* + * Get rid of sysroot here so that targeting scan rule may contains FC_FILE pattern + * and they should usually expect without sysroot. + */ + if (font && sysroot) + { + size_t len = strlen ((const char *)sysroot); + FcChar8 *f = NULL; + + if (FcPatternObjectGetString (font, FC_FILE_OBJECT, 0, &f) == FcResultMatch && + strncmp ((const char *)f, (const char *)sysroot, len) == 0) + { + FcChar8 *s = FcStrdup (f); + FcPatternObjectDel (font, FC_FILE_OBJECT); + if (s[len] != '/') + len--; + else if (s[len+1] == '/') + len++; + FcPatternObjectAddString (font, FC_FILE_OBJECT, &s[len]); + FcStrFree (s); + } + } /* * Edit pattern with user-defined rules @@ -113,10 +154,20 @@ FcFileScanFontConfig (FcFontSet *set, ret = FcFalse; } } - else if (font) - FcPatternDestroy (font); - id++; - } while (font && ret && id < count); + else + ret = FcFalse; + + if (instance_num < num_instances) + instance_num++; + else + { + face_num++; + instance_num = 0; + } + } while (font && ret && face_num < num_faces); + + FT_Done_FreeType (ftLibrary); + return ret; } @@ -128,7 +179,25 @@ FcFileScanConfig (FcFontSet *set, FcConfig *config) { if (FcFileIsDir (file)) - return FcStrSetAdd (dirs, file); + { + const FcChar8 *sysroot = FcConfigGetSysRoot (config); + const FcChar8 *d = file; + size_t len; + + if (sysroot) + { + len = strlen ((const char *)sysroot); + if (strncmp ((const char *)file, (const char *)sysroot, len) == 0) + { + if (file[len] != '/') + len--; + else if (file[len+1] == '/') + len++; + d = &file[len]; + } + } + return FcStrSetAdd (dirs, d); + } else { if (set) @@ -206,7 +275,7 @@ FcDirScanConfig (FcFontSet *set, goto bail; } - files = FcStrSetCreate (); + files = FcStrSetCreateEx (FCSS_ALLOW_DUPLICATES | FCSS_GROW_BY_64); if (!files) { ret = FcFalse; @@ -270,25 +339,34 @@ FcDirCacheScan (const FcChar8 *dir, FcConfig *config) FcFontSet *set; FcCache *cache = NULL; struct stat dir_stat; + const FcChar8 *sysroot = FcConfigGetSysRoot (config); + FcChar8 *d; + int fd = -1; + + if (sysroot) + d = FcStrBuildFilename (sysroot, dir, NULL); + else + d = FcStrdup (dir); if (FcDebug () & FC_DBG_FONTSET) - printf ("cache scan dir %s\n", dir); + printf ("cache scan dir %s\n", d); - if (FcStatChecksum (dir, &dir_stat) < 0) + if (FcStatChecksum (d, &dir_stat) < 0) goto bail; set = FcFontSetCreate(); if (!set) goto bail; - dirs = FcStrSetCreate (); + dirs = FcStrSetCreateEx (FCSS_GROW_BY_64); if (!dirs) goto bail1; + fd = FcDirCacheLock (dir, config); /* * Scan the dir */ - if (!FcDirScanConfig (set, dirs, NULL, dir, FcTrue, config)) + if (!FcDirScanConfig (set, dirs, NULL, d, FcTrue, config)) goto bail2; /* @@ -304,33 +382,46 @@ FcDirCacheScan (const FcChar8 *dir, FcConfig *config) FcDirCacheWrite (cache, config); bail2: + FcDirCacheUnlock (fd); FcStrSetDestroy (dirs); bail1: FcFontSetDestroy (set); bail: + FcStrFree (d); + return cache; } FcCache * FcDirCacheRescan (const FcChar8 *dir, FcConfig *config) { - FcCache *cache = FcDirCacheLoad (dir, config, NULL); + FcCache *cache; FcCache *new = NULL; struct stat dir_stat; FcStrSet *dirs; + const FcChar8 *sysroot = FcConfigGetSysRoot (config); + FcChar8 *d = NULL; + int fd = -1; + cache = FcDirCacheLoad (dir, config, NULL); if (!cache) - return NULL; - if (FcStatChecksum (dir, &dir_stat) < 0) goto bail; - dirs = FcStrSetCreate (); + + if (sysroot) + d = FcStrBuildFilename (sysroot, dir, NULL); + else + d = FcStrdup (dir); + if (FcStatChecksum (d, &dir_stat) < 0) + goto bail; + dirs = FcStrSetCreateEx (FCSS_GROW_BY_64); if (!dirs) goto bail; + fd = FcDirCacheLock (dir, config); /* * Scan the dir */ - if (!FcDirScanConfig (NULL, dirs, NULL, dir, FcTrue, config)) + if (!FcDirScanConfig (NULL, dirs, NULL, d, FcTrue, config)) goto bail1; /* * Rebuild the cache object @@ -345,8 +436,12 @@ FcDirCacheRescan (const FcChar8 *dir, FcConfig *config) FcDirCacheWrite (new, config); bail1: + FcDirCacheUnlock (fd); FcStrSetDestroy (dirs); bail: + if (d) + FcStrFree (d); + return new; } diff --git a/dist/fontconfig/src/fcfreetype.c b/dist/fontconfig/src/fcfreetype.c index 4b2d1d188..234e65175 100644 --- a/dist/fontconfig/src/fcfreetype.c +++ b/dist/fontconfig/src/fcfreetype.c @@ -62,6 +62,7 @@ #include FT_BDF_H #include FT_MODULE_H #endif +#include FT_MULTIPLE_MASTERS_H #include "ftglue.h" @@ -558,6 +559,139 @@ FcFontCapabilities(FT_Face face); #define NUM_FC_MAC_ROMAN_FAKE (int) (sizeof (fcMacRomanFake) / sizeof (fcMacRomanFake[0])) + +/* From http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/ROMAN.TXT */ +static const FcChar16 fcMacRomanNonASCIIToUnicode[128] = { + /*0x80*/ 0x00C4, /* LATIN CAPITAL LETTER A WITH DIAERESIS */ + /*0x81*/ 0x00C5, /* LATIN CAPITAL LETTER A WITH RING ABOVE */ + /*0x82*/ 0x00C7, /* LATIN CAPITAL LETTER C WITH CEDILLA */ + /*0x83*/ 0x00C9, /* LATIN CAPITAL LETTER E WITH ACUTE */ + /*0x84*/ 0x00D1, /* LATIN CAPITAL LETTER N WITH TILDE */ + /*0x85*/ 0x00D6, /* LATIN CAPITAL LETTER O WITH DIAERESIS */ + /*0x86*/ 0x00DC, /* LATIN CAPITAL LETTER U WITH DIAERESIS */ + /*0x87*/ 0x00E1, /* LATIN SMALL LETTER A WITH ACUTE */ + /*0x88*/ 0x00E0, /* LATIN SMALL LETTER A WITH GRAVE */ + /*0x89*/ 0x00E2, /* LATIN SMALL LETTER A WITH CIRCUMFLEX */ + /*0x8A*/ 0x00E4, /* LATIN SMALL LETTER A WITH DIAERESIS */ + /*0x8B*/ 0x00E3, /* LATIN SMALL LETTER A WITH TILDE */ + /*0x8C*/ 0x00E5, /* LATIN SMALL LETTER A WITH RING ABOVE */ + /*0x8D*/ 0x00E7, /* LATIN SMALL LETTER C WITH CEDILLA */ + /*0x8E*/ 0x00E9, /* LATIN SMALL LETTER E WITH ACUTE */ + /*0x8F*/ 0x00E8, /* LATIN SMALL LETTER E WITH GRAVE */ + /*0x90*/ 0x00EA, /* LATIN SMALL LETTER E WITH CIRCUMFLEX */ + /*0x91*/ 0x00EB, /* LATIN SMALL LETTER E WITH DIAERESIS */ + /*0x92*/ 0x00ED, /* LATIN SMALL LETTER I WITH ACUTE */ + /*0x93*/ 0x00EC, /* LATIN SMALL LETTER I WITH GRAVE */ + /*0x94*/ 0x00EE, /* LATIN SMALL LETTER I WITH CIRCUMFLEX */ + /*0x95*/ 0x00EF, /* LATIN SMALL LETTER I WITH DIAERESIS */ + /*0x96*/ 0x00F1, /* LATIN SMALL LETTER N WITH TILDE */ + /*0x97*/ 0x00F3, /* LATIN SMALL LETTER O WITH ACUTE */ + /*0x98*/ 0x00F2, /* LATIN SMALL LETTER O WITH GRAVE */ + /*0x99*/ 0x00F4, /* LATIN SMALL LETTER O WITH CIRCUMFLEX */ + /*0x9A*/ 0x00F6, /* LATIN SMALL LETTER O WITH DIAERESIS */ + /*0x9B*/ 0x00F5, /* LATIN SMALL LETTER O WITH TILDE */ + /*0x9C*/ 0x00FA, /* LATIN SMALL LETTER U WITH ACUTE */ + /*0x9D*/ 0x00F9, /* LATIN SMALL LETTER U WITH GRAVE */ + /*0x9E*/ 0x00FB, /* LATIN SMALL LETTER U WITH CIRCUMFLEX */ + /*0x9F*/ 0x00FC, /* LATIN SMALL LETTER U WITH DIAERESIS */ + /*0xA0*/ 0x2020, /* DAGGER */ + /*0xA1*/ 0x00B0, /* DEGREE SIGN */ + /*0xA2*/ 0x00A2, /* CENT SIGN */ + /*0xA3*/ 0x00A3, /* POUND SIGN */ + /*0xA4*/ 0x00A7, /* SECTION SIGN */ + /*0xA5*/ 0x2022, /* BULLET */ + /*0xA6*/ 0x00B6, /* PILCROW SIGN */ + /*0xA7*/ 0x00DF, /* LATIN SMALL LETTER SHARP S */ + /*0xA8*/ 0x00AE, /* REGISTERED SIGN */ + /*0xA9*/ 0x00A9, /* COPYRIGHT SIGN */ + /*0xAA*/ 0x2122, /* TRADE MARK SIGN */ + /*0xAB*/ 0x00B4, /* ACUTE ACCENT */ + /*0xAC*/ 0x00A8, /* DIAERESIS */ + /*0xAD*/ 0x2260, /* NOT EQUAL TO */ + /*0xAE*/ 0x00C6, /* LATIN CAPITAL LETTER AE */ + /*0xAF*/ 0x00D8, /* LATIN CAPITAL LETTER O WITH STROKE */ + /*0xB0*/ 0x221E, /* INFINITY */ + /*0xB1*/ 0x00B1, /* PLUS-MINUS SIGN */ + /*0xB2*/ 0x2264, /* LESS-THAN OR EQUAL TO */ + /*0xB3*/ 0x2265, /* GREATER-THAN OR EQUAL TO */ + /*0xB4*/ 0x00A5, /* YEN SIGN */ + /*0xB5*/ 0x00B5, /* MICRO SIGN */ + /*0xB6*/ 0x2202, /* PARTIAL DIFFERENTIAL */ + /*0xB7*/ 0x2211, /* N-ARY SUMMATION */ + /*0xB8*/ 0x220F, /* N-ARY PRODUCT */ + /*0xB9*/ 0x03C0, /* GREEK SMALL LETTER PI */ + /*0xBA*/ 0x222B, /* INTEGRAL */ + /*0xBB*/ 0x00AA, /* FEMININE ORDINAL INDICATOR */ + /*0xBC*/ 0x00BA, /* MASCULINE ORDINAL INDICATOR */ + /*0xBD*/ 0x03A9, /* GREEK CAPITAL LETTER OMEGA */ + /*0xBE*/ 0x00E6, /* LATIN SMALL LETTER AE */ + /*0xBF*/ 0x00F8, /* LATIN SMALL LETTER O WITH STROKE */ + /*0xC0*/ 0x00BF, /* INVERTED QUESTION MARK */ + /*0xC1*/ 0x00A1, /* INVERTED EXCLAMATION MARK */ + /*0xC2*/ 0x00AC, /* NOT SIGN */ + /*0xC3*/ 0x221A, /* SQUARE ROOT */ + /*0xC4*/ 0x0192, /* LATIN SMALL LETTER F WITH HOOK */ + /*0xC5*/ 0x2248, /* ALMOST EQUAL TO */ + /*0xC6*/ 0x2206, /* INCREMENT */ + /*0xC7*/ 0x00AB, /* LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */ + /*0xC8*/ 0x00BB, /* RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */ + /*0xC9*/ 0x2026, /* HORIZONTAL ELLIPSIS */ + /*0xCA*/ 0x00A0, /* NO-BREAK SPACE */ + /*0xCB*/ 0x00C0, /* LATIN CAPITAL LETTER A WITH GRAVE */ + /*0xCC*/ 0x00C3, /* LATIN CAPITAL LETTER A WITH TILDE */ + /*0xCD*/ 0x00D5, /* LATIN CAPITAL LETTER O WITH TILDE */ + /*0xCE*/ 0x0152, /* LATIN CAPITAL LIGATURE OE */ + /*0xCF*/ 0x0153, /* LATIN SMALL LIGATURE OE */ + /*0xD0*/ 0x2013, /* EN DASH */ + /*0xD1*/ 0x2014, /* EM DASH */ + /*0xD2*/ 0x201C, /* LEFT DOUBLE QUOTATION MARK */ + /*0xD3*/ 0x201D, /* RIGHT DOUBLE QUOTATION MARK */ + /*0xD4*/ 0x2018, /* LEFT SINGLE QUOTATION MARK */ + /*0xD5*/ 0x2019, /* RIGHT SINGLE QUOTATION MARK */ + /*0xD6*/ 0x00F7, /* DIVISION SIGN */ + /*0xD7*/ 0x25CA, /* LOZENGE */ + /*0xD8*/ 0x00FF, /* LATIN SMALL LETTER Y WITH DIAERESIS */ + /*0xD9*/ 0x0178, /* LATIN CAPITAL LETTER Y WITH DIAERESIS */ + /*0xDA*/ 0x2044, /* FRACTION SLASH */ + /*0xDB*/ 0x20AC, /* EURO SIGN */ + /*0xDC*/ 0x2039, /* SINGLE LEFT-POINTING ANGLE QUOTATION MARK */ + /*0xDD*/ 0x203A, /* SINGLE RIGHT-POINTING ANGLE QUOTATION MARK */ + /*0xDE*/ 0xFB01, /* LATIN SMALL LIGATURE FI */ + /*0xDF*/ 0xFB02, /* LATIN SMALL LIGATURE FL */ + /*0xE0*/ 0x2021, /* DOUBLE DAGGER */ + /*0xE1*/ 0x00B7, /* MIDDLE DOT */ + /*0xE2*/ 0x201A, /* SINGLE LOW-9 QUOTATION MARK */ + /*0xE3*/ 0x201E, /* DOUBLE LOW-9 QUOTATION MARK */ + /*0xE4*/ 0x2030, /* PER MILLE SIGN */ + /*0xE5*/ 0x00C2, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX */ + /*0xE6*/ 0x00CA, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX */ + /*0xE7*/ 0x00C1, /* LATIN CAPITAL LETTER A WITH ACUTE */ + /*0xE8*/ 0x00CB, /* LATIN CAPITAL LETTER E WITH DIAERESIS */ + /*0xE9*/ 0x00C8, /* LATIN CAPITAL LETTER E WITH GRAVE */ + /*0xEA*/ 0x00CD, /* LATIN CAPITAL LETTER I WITH ACUTE */ + /*0xEB*/ 0x00CE, /* LATIN CAPITAL LETTER I WITH CIRCUMFLEX */ + /*0xEC*/ 0x00CF, /* LATIN CAPITAL LETTER I WITH DIAERESIS */ + /*0xED*/ 0x00CC, /* LATIN CAPITAL LETTER I WITH GRAVE */ + /*0xEE*/ 0x00D3, /* LATIN CAPITAL LETTER O WITH ACUTE */ + /*0xEF*/ 0x00D4, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX */ + /*0xF0*/ 0xF8FF, /* Apple logo */ + /*0xF1*/ 0x00D2, /* LATIN CAPITAL LETTER O WITH GRAVE */ + /*0xF2*/ 0x00DA, /* LATIN CAPITAL LETTER U WITH ACUTE */ + /*0xF3*/ 0x00DB, /* LATIN CAPITAL LETTER U WITH CIRCUMFLEX */ + /*0xF4*/ 0x00D9, /* LATIN CAPITAL LETTER U WITH GRAVE */ + /*0xF5*/ 0x0131, /* LATIN SMALL LETTER DOTLESS I */ + /*0xF6*/ 0x02C6, /* MODIFIER LETTER CIRCUMFLEX ACCENT */ + /*0xF7*/ 0x02DC, /* SMALL TILDE */ + /*0xF8*/ 0x00AF, /* MACRON */ + /*0xF9*/ 0x02D8, /* BREVE */ + /*0xFA*/ 0x02D9, /* DOT ABOVE */ + /*0xFB*/ 0x02DA, /* RING ABOVE */ + /*0xFC*/ 0x00B8, /* CEDILLA */ + /*0xFD*/ 0x02DD, /* DOUBLE ACUTE ACCENT */ + /*0xFE*/ 0x02DB, /* OGONEK */ + /*0xFF*/ 0x02C7, /* CARON */ +}; + #if USE_ICONV #include <iconv.h> #endif @@ -696,6 +830,35 @@ FcSfntNameTranscode (FT_SfntName *sname) *u8 = '\0'; goto done; } + if (!strcmp (fromcode, FC_ENCODING_MAC_ROMAN)) + { + FcChar8 *src = sname->string; + int src_len = sname->string_len; + int olen; + FcChar8 *u8; + FcChar32 ucs4; + + /* + * Convert Latin1 to Utf8. Freed below + */ + utf8 = malloc (src_len * 3 + 1); + if (!utf8) + return 0; + + u8 = utf8; + while (src_len > 0) + { + ucs4 = *src++; + if (ucs4 >= 128) + ucs4 = fcMacRomanNonASCIIToUnicode[ucs4 - 128]; + src_len--; + olen = FcUcs4ToUtf8 (ucs4, u8); + u8 += olen; + } + *u8 = '\0'; + goto done; + } + #if USE_ICONV cd = iconv_open ("UTF-8", fromcode); if (cd && cd != (iconv_t) (-1)) @@ -816,76 +979,6 @@ FcNoticeFoundry(const FT_String *notice) return 0; } -static FcBool -FcVendorMatch(const FT_Char vendor[4], const FT_Char *vendor_string) -{ - /* vendor is not necessarily NUL-terminated. */ - int i, len; - - len = strlen((char *) vendor_string); - if (memcmp(vendor, vendor_string, len) != 0) - return FcFalse; - for (i = len; i < 4; i++) - if (vendor[i] != ' ' && vendor[i] != '\0') - return FcFalse; - return FcTrue; -} - -/* This table is partly taken from ttmkfdir by Joerg Pommnitz. */ - -/* It should not contain useless entries (such as UNKN) nor duplicate - entries for padding both with spaces and NULs. */ - -static const struct { - const FT_Char vendor[5]; - const FcChar8 foundry[13]; -} FcVendorFoundries[] = { - { "ADBE", "adobe"}, - { "AGFA", "agfa"}, - { "ALTS", "altsys"}, - { "APPL", "apple"}, - { "ARPH", "arphic"}, - { "ATEC", "alltype"}, - { "B&H", "b&h"}, - { "BITS", "bitstream"}, - { "CANO", "cannon"}, - { "CLM", "culmus"}, - { "DYNA", "dynalab"}, - { "EPSN", "epson"}, - { "FJ", "fujitsu"}, - { "IBM", "ibm"}, - { "ITC", "itc"}, - { "IMPR", "impress"}, - { "LARA", "larabiefonts"}, - { "LEAF", "interleaf"}, - { "LETR", "letraset"}, - { "LINO", "linotype"}, - { "MACR", "macromedia"}, - { "MONO", "monotype"}, - { "MS", "microsoft"}, - { "MT", "monotype"}, - { "NEC", "nec"}, - { "PARA", "paratype"}, - { "QMSI", "qms"}, - { "RICO", "ricoh"}, - { "URW", "urw"}, - { "Y&Y", "y&y"} -}; - -#define NUM_VENDOR_FOUNDRIES (int) (sizeof (FcVendorFoundries) / sizeof (FcVendorFoundries[0])) - -static const FcChar8 * -FcVendorFoundry(const FT_Char vendor[4]) -{ - int i; - - if (vendor) - for(i = 0; i < NUM_VENDOR_FOUNDRIES; i++) - if (FcVendorMatch (vendor, FcVendorFoundries[i].vendor)) - return FcVendorFoundries[i].foundry; - return 0; -} - typedef struct _FcStringConst { const FcChar8 *name; int value; @@ -933,6 +1026,8 @@ static const FcStringConst weightConsts[] = { { (FC8) "thin", FC_WEIGHT_THIN }, { (FC8) "extralight", FC_WEIGHT_EXTRALIGHT }, { (FC8) "ultralight", FC_WEIGHT_ULTRALIGHT }, + { (FC8) "demilight", FC_WEIGHT_DEMILIGHT }, + { (FC8) "semilight", FC_WEIGHT_SEMILIGHT }, { (FC8) "light", FC_WEIGHT_LIGHT }, { (FC8) "book", FC_WEIGHT_BOOK }, { (FC8) "regular", FC_WEIGHT_REGULAR }, @@ -1075,9 +1170,16 @@ FcFreeTypeQueryFace (const FT_Face face, #if 0 FcChar8 *family = 0; #endif - FcChar8 *complex_; + FcChar8 *complex_, *foundry_ = NULL; const FcChar8 *foundry = 0; int spacing; + + /* Support for glyph-variation named-instances. */ + FT_MM_Var *master = NULL; + FT_Var_Named_Style *instance = NULL; + double weight_mult = 1.0; + double width_mult = 1.0; + TT_OS2 *os2; #if HAVE_FT_GET_PS_FONT_INFO PS_FontInfoRec psfontinfo; @@ -1104,22 +1206,70 @@ FcFreeTypeQueryFace (const FT_Face face, char psname[256]; const char *tmp; - FcChar8 *hashstr = NULL; - FT_Error err; - FT_ULong len = 0, alen; + FcRange *r = NULL; + + FcBool symbol = FcFalse; + + FcInitDebug (); /* We might be called with no initizalization whatsoever. */ pat = FcPatternCreate (); if (!pat) goto bail0; - if (!FcPatternAddBool (pat, FC_OUTLINE, - (face->face_flags & FT_FACE_FLAG_SCALABLE) != 0)) - goto bail1; + { + int has_outline = !!(face->face_flags & FT_FACE_FLAG_SCALABLE); + int has_color = 0; - if (!FcPatternAddBool (pat, FC_SCALABLE, - (face->face_flags & FT_FACE_FLAG_SCALABLE) != 0)) - goto bail1; +#ifdef FT_FACE_FLAG_COLOR + has_color = !!(face->face_flags & FT_FACE_FLAG_COLOR); +#endif + + if (!FcPatternAddBool (pat, FC_OUTLINE, has_outline)) + goto bail1; + +#ifdef FT_FACE_FLAG_COLOR + if (!FcPatternAddBool (pat, FC_COLOR, has_color)) + goto bail1; +#endif + + /* All color fonts are designed to be scaled, even if they only have + * bitmap strikes. Client is responsible to scale the bitmaps. This + * is in constrast to non-color strikes... */ + if (!FcPatternAddBool (pat, FC_SCALABLE, has_outline || has_color)) + goto bail1; + } + + if (id >> 16) + { + if (!FT_Get_MM_Var (face, &master)) + instance = &master->namedstyle[(id >> 16) - 1]; + + if (instance) + { + /* Pull out weight and width from named-instance. */ + unsigned int i; + + for (i = 0; i < master->num_axis; i++) + { + double value = instance->coords[i] / (double) (1 << 16); + double default_value = master->axis[i].def / (double) (1 << 16); + double mult = value / default_value; + //printf ("named-instance, axis %d tag %lx value %g\n", i, master->axis[i].tag, value); + switch (master->axis[i].tag) + { + case FT_MAKE_TAG ('w','g','h','t'): + weight_mult = mult; + break; + + case FT_MAKE_TAG ('w','d','t','h'): + width_mult = mult; + break; + /* TODO optical size! */ + } + } + } + } /* * Get the OS/2 table @@ -1135,7 +1285,15 @@ FcFreeTypeQueryFace (const FT_Face face, */ if (os2 && os2->version >= 0x0001 && os2->version != 0xffff) - foundry = FcVendorFoundry(os2->achVendID); + { + if (os2->achVendID && os2->achVendID[0] != 0) + { + foundry_ = (FcChar8 *) malloc (sizeof (os2->achVendID) + 1); + memcpy ((void *)foundry_, os2->achVendID, sizeof (os2->achVendID)); + foundry_[sizeof (os2->achVendID)] = 0; + foundry = foundry_; + } + } if (FcDebug () & FC_DBG_SCANV) printf ("\n"); @@ -1170,6 +1328,19 @@ FcFreeTypeQueryFace (const FT_Face face, if (FT_Get_Sfnt_Name (face, snamei, &sname) != 0) continue; + + if (instance) + { + /* For named-instances, we regular style nameIDs, + * and map the instance's strid to FONT_SUBFAMILY. */ + if (sname.name_id == TT_NAME_ID_WWS_SUBFAMILY || + sname.name_id == TT_NAME_ID_PREFERRED_SUBFAMILY || + sname.name_id == TT_NAME_ID_FONT_SUBFAMILY) + continue; + if (sname.name_id == instance->strid) + sname.name_id = TT_NAME_ID_FONT_SUBFAMILY; + } + if (sname.name_id != nameid) continue; @@ -1283,10 +1454,10 @@ FcFreeTypeQueryFace (const FT_Face face, free (utf8); if (lang) { - /* pad lang list with 'xx' to line up with elt */ + /* pad lang list with 'und' to line up with elt */ while (*nlangp < *np) { - if (!FcPatternAddString (pat, eltlang, (FcChar8 *) "xx")) + if (!FcPatternAddString (pat, eltlang, (FcChar8 *) "und")) goto bail1; ++*nlangp; } @@ -1309,6 +1480,8 @@ FcFreeTypeQueryFace (const FT_Face face, printf ("using FreeType family \"%s\"\n", face->family_name); if (!FcPatternAddString (pat, FC_FAMILY, (FcChar8 *) face->family_name)) goto bail1; + if (!FcPatternAddString (pat, FC_STYLELANG, (FcChar8 *) "en")) + goto bail1; ++nfamily; } @@ -1319,10 +1492,12 @@ FcFreeTypeQueryFace (const FT_Face face, printf ("using FreeType style \"%s\"\n", face->style_name); if (!FcPatternAddString (pat, FC_STYLE, (FcChar8 *) face->style_name)) goto bail1; + if (!FcPatternAddString (pat, FC_STYLELANG, (FcChar8 *) "en")) + goto bail1; ++nstyle; } - if (!nfamily) + if (!nfamily && file && *file) { FcChar8 *start, *end; FcChar8 *family; @@ -1391,12 +1566,13 @@ FcFreeTypeQueryFace (const FT_Face face, } else { - strlcpy (psname, tmp, sizeof(psname)); + strncpy (psname, tmp, 255); + psname[255] = 0; } if (!FcPatternAddString (pat, FC_POSTSCRIPT_NAME, (const FcChar8 *)psname)) goto bail1; - if (!FcPatternAddString (pat, FC_FILE, file)) + if (file && *file && !FcPatternAddString (pat, FC_FILE, file)) goto bail1; if (!FcPatternAddInteger (pat, FC_INDEX, id)) @@ -1463,33 +1639,22 @@ FcFreeTypeQueryFace (const FT_Face face, if (os2 && os2->version != 0xffff) { - if (os2->usWeightClass == 0) - ; - else if (os2->usWeightClass < 150) - weight = FC_WEIGHT_THIN; - else if (os2->usWeightClass < 250) - weight = FC_WEIGHT_EXTRALIGHT; - else if (os2->usWeightClass < 350) - weight = FC_WEIGHT_LIGHT; - else if (os2->usWeightClass < 450) - weight = FC_WEIGHT_REGULAR; - else if (os2->usWeightClass < 550) - weight = FC_WEIGHT_MEDIUM; - else if (os2->usWeightClass < 650) - weight = FC_WEIGHT_SEMIBOLD; - else if (os2->usWeightClass < 750) - weight = FC_WEIGHT_BOLD; - else if (os2->usWeightClass < 850) - weight = FC_WEIGHT_EXTRABOLD; - else if (os2->usWeightClass < 925) - weight = FC_WEIGHT_BLACK; - else if (os2->usWeightClass < 1000) - weight = FC_WEIGHT_EXTRABLACK; + weight = os2->usWeightClass; + if (weight < 10 && weight_mult != 1.0) + { + /* Work around bad values by cleaning them up before + * multiplying by weight_mult. */ + weight = FcWeightToOpenType (FcWeightFromOpenType (weight)); + } + weight = FcWeightFromOpenType ((int) (weight * weight_mult + .5)); if ((FcDebug() & FC_DBG_SCANV) && weight != -1) - printf ("\tos2 weight class %d maps to weight %d\n", - os2->usWeightClass, weight); + printf ("\tos2 weight class %d multiplier %g maps to weight %d\n", + os2->usWeightClass, weight_mult, weight); - switch (os2->usWidthClass) { + /* TODO: + * Add FcWidthFromOpenType and FcWidthToOpenType, + * and apply width_mult post-conversion? */ + switch ((int) (os2->usWidthClass * width_mult + .5)) { case 1: width = FC_WIDTH_ULTRACONDENSED; break; case 2: width = FC_WIDTH_EXTRACONDENSED; break; case 3: width = FC_WIDTH_CONDENSED; break; @@ -1501,8 +1666,8 @@ FcFreeTypeQueryFace (const FT_Face face, case 9: width = FC_WIDTH_ULTRAEXPANDED; break; } if ((FcDebug() & FC_DBG_SCANV) && width != -1) - printf ("\tos2 width class %d maps to width %d\n", - os2->usWidthClass, width); + printf ("\tos2 width class %d multiplier %g maps to width %d\n", + os2->usWidthClass, width_mult, width); } if (os2 && (complex_ = FcFontCapabilities(face))) { @@ -1514,6 +1679,25 @@ FcFreeTypeQueryFace (const FT_Face face, free (complex_); } +#if defined (HAVE_TT_OS2_USUPPEROPTICALPOINTSIZE) && defined (HAVE_TT_OS2_USLOWEROPTICALPOINTSIZE) + if (os2 && os2->version >= 0x0005 && os2->version != 0xffff) + { + double lower_size, upper_size; + + /* usLowerPointSize and usUpperPointSize is actually twips */ + lower_size = os2->usLowerOpticalPointSize / 20.0L; + upper_size = os2->usUpperOpticalPointSize / 20.0L; + + r = FcRangeCreateDouble (lower_size, upper_size); + if (!FcPatternAddRange (pat, FC_SIZE, r)) + { + FcRangeDestroy (r); + goto bail1; + } + FcRangeDestroy (r); + } +#endif + /* * Type 1: Check for FontInfo dictionary information * Code from g2@magestudios.net (Gerard Escalante) @@ -1664,46 +1848,6 @@ FcFreeTypeQueryFace (const FT_Face face, if (!FcPatternAddBool (pat, FC_DECORATIVE, decorative)) goto bail1; - err = FT_Load_Sfnt_Table (face, 0, 0, NULL, &len); - if (err == FT_Err_Ok) - { - char *fontdata; - - alen = (len + 63) & ~63; - fontdata = malloc (alen); - if (!fontdata) - goto bail3; - err = FT_Load_Sfnt_Table (face, 0, 0, (FT_Byte *)fontdata, &len); - if (err != FT_Err_Ok) - { - free (fontdata); - goto bail3; - } - memset (&fontdata[len], 0, alen - len); - hashstr = FcHashGetSHA256DigestFromMemory (fontdata, len); - free (fontdata); - } - else if (err == FT_Err_Invalid_Face_Handle) - { - /* font may not support SFNT. falling back to - * read the font data from file directly - */ - hashstr = FcHashGetSHA256DigestFromFile (file); - } - else - { - goto bail3; - } - if (hashstr) - { - if (!FcPatternAddString (pat, FC_HASH, hashstr)) - { - free (hashstr); - goto bail1; - } - free (hashstr); - } -bail3: /* * Compute the unicode coverage for the font @@ -1712,6 +1856,11 @@ bail3: if (!cs) goto bail1; + /* The FcFreeTypeCharSetAndSpacing() chose the encoding; test it for symbol. */ + symbol = face->charmap && face->charmap->encoding == FT_ENCODING_MS_SYMBOL; + if (!FcPatternAddBool (pat, FC_SYMBOL, symbol)) + goto bail1; + #if HAVE_FT_GET_BDF_PROPERTY /* For PCF fonts, override the computed spacing with the one from the property */ @@ -1744,9 +1893,18 @@ bail3: if (!FcPatternAddCharSet (pat, FC_CHARSET, cs)) goto bail2; - ls = FcFreeTypeLangSet (cs, exclusiveLang); - if (!ls) - goto bail2; + if (!symbol) + { + ls = FcFreeTypeLangSet (cs, exclusiveLang); + if (!ls) + goto bail2; + } + else + { + /* Symbol fonts don't cover any language, even though they + * claim to support Latin1 range. */ + ls = FcLangSetCreate (); + } if (!FcPatternAddLangSet (pat, FC_LANG, ls)) { @@ -1786,6 +1944,13 @@ bail3: * Drop our reference to the charset */ FcCharSetDestroy (cs); + if (foundry_) + free (foundry_); + + if (master) + { + /* TODO: How to free master?! */ + } return pat; @@ -1793,6 +1958,8 @@ bail2: FcCharSetDestroy (cs); bail1: FcPatternDestroy (pat); + if (foundry_) + free (foundry_); bail0: return NULL; } @@ -1833,282 +2000,12 @@ bail: #warning "No FT_Get_Next_Char: Please install freetype version 2.1.0 or newer" #endif -typedef struct _FcCharEnt { - FcChar16 bmp; - unsigned char encode; -} FcCharEnt; - -struct _FcCharMap { - const FcCharEnt *ent; - int nent; -}; - -typedef struct _FcFontDecode { - FT_Encoding encoding; - const FcCharMap *map; - FcChar32 max; -} FcFontDecode; - -static const FcCharEnt AdobeSymbolEnt[] = { - { 0x0020, 0x20 }, /* SPACE # space */ - { 0x0021, 0x21 }, /* EXCLAMATION MARK # exclam */ - { 0x0023, 0x23 }, /* NUMBER SIGN # numbersign */ - { 0x0025, 0x25 }, /* PERCENT SIGN # percent */ - { 0x0026, 0x26 }, /* AMPERSAND # ampersand */ - { 0x0028, 0x28 }, /* LEFT PARENTHESIS # parenleft */ - { 0x0029, 0x29 }, /* RIGHT PARENTHESIS # parenright */ - { 0x002B, 0x2B }, /* PLUS SIGN # plus */ - { 0x002C, 0x2C }, /* COMMA # comma */ - { 0x002E, 0x2E }, /* FULL STOP # period */ - { 0x002F, 0x2F }, /* SOLIDUS # slash */ - { 0x0030, 0x30 }, /* DIGIT ZERO # zero */ - { 0x0031, 0x31 }, /* DIGIT ONE # one */ - { 0x0032, 0x32 }, /* DIGIT TWO # two */ - { 0x0033, 0x33 }, /* DIGIT THREE # three */ - { 0x0034, 0x34 }, /* DIGIT FOUR # four */ - { 0x0035, 0x35 }, /* DIGIT FIVE # five */ - { 0x0036, 0x36 }, /* DIGIT SIX # six */ - { 0x0037, 0x37 }, /* DIGIT SEVEN # seven */ - { 0x0038, 0x38 }, /* DIGIT EIGHT # eight */ - { 0x0039, 0x39 }, /* DIGIT NINE # nine */ - { 0x003A, 0x3A }, /* COLON # colon */ - { 0x003B, 0x3B }, /* SEMICOLON # semicolon */ - { 0x003C, 0x3C }, /* LESS-THAN SIGN # less */ - { 0x003D, 0x3D }, /* EQUALS SIGN # equal */ - { 0x003E, 0x3E }, /* GREATER-THAN SIGN # greater */ - { 0x003F, 0x3F }, /* QUESTION MARK # question */ - { 0x005B, 0x5B }, /* LEFT SQUARE BRACKET # bracketleft */ - { 0x005D, 0x5D }, /* RIGHT SQUARE BRACKET # bracketright */ - { 0x005F, 0x5F }, /* LOW LINE # underscore */ - { 0x007B, 0x7B }, /* LEFT CURLY BRACKET # braceleft */ - { 0x007C, 0x7C }, /* VERTICAL LINE # bar */ - { 0x007D, 0x7D }, /* RIGHT CURLY BRACKET # braceright */ - { 0x00A0, 0x20 }, /* NO-BREAK SPACE # space */ - { 0x00AC, 0xD8 }, /* NOT SIGN # logicalnot */ - { 0x00B0, 0xB0 }, /* DEGREE SIGN # degree */ - { 0x00B1, 0xB1 }, /* PLUS-MINUS SIGN # plusminus */ - { 0x00B5, 0x6D }, /* MICRO SIGN # mu */ - { 0x00D7, 0xB4 }, /* MULTIPLICATION SIGN # multiply */ - { 0x00F7, 0xB8 }, /* DIVISION SIGN # divide */ - { 0x0192, 0xA6 }, /* LATIN SMALL LETTER F WITH HOOK # florin */ - { 0x0391, 0x41 }, /* GREEK CAPITAL LETTER ALPHA # Alpha */ - { 0x0392, 0x42 }, /* GREEK CAPITAL LETTER BETA # Beta */ - { 0x0393, 0x47 }, /* GREEK CAPITAL LETTER GAMMA # Gamma */ - { 0x0394, 0x44 }, /* GREEK CAPITAL LETTER DELTA # Delta */ - { 0x0395, 0x45 }, /* GREEK CAPITAL LETTER EPSILON # Epsilon */ - { 0x0396, 0x5A }, /* GREEK CAPITAL LETTER ZETA # Zeta */ - { 0x0397, 0x48 }, /* GREEK CAPITAL LETTER ETA # Eta */ - { 0x0398, 0x51 }, /* GREEK CAPITAL LETTER THETA # Theta */ - { 0x0399, 0x49 }, /* GREEK CAPITAL LETTER IOTA # Iota */ - { 0x039A, 0x4B }, /* GREEK CAPITAL LETTER KAPPA # Kappa */ - { 0x039B, 0x4C }, /* GREEK CAPITAL LETTER LAMDA # Lambda */ - { 0x039C, 0x4D }, /* GREEK CAPITAL LETTER MU # Mu */ - { 0x039D, 0x4E }, /* GREEK CAPITAL LETTER NU # Nu */ - { 0x039E, 0x58 }, /* GREEK CAPITAL LETTER XI # Xi */ - { 0x039F, 0x4F }, /* GREEK CAPITAL LETTER OMICRON # Omicron */ - { 0x03A0, 0x50 }, /* GREEK CAPITAL LETTER PI # Pi */ - { 0x03A1, 0x52 }, /* GREEK CAPITAL LETTER RHO # Rho */ - { 0x03A3, 0x53 }, /* GREEK CAPITAL LETTER SIGMA # Sigma */ - { 0x03A4, 0x54 }, /* GREEK CAPITAL LETTER TAU # Tau */ - { 0x03A5, 0x55 }, /* GREEK CAPITAL LETTER UPSILON # Upsilon */ - { 0x03A6, 0x46 }, /* GREEK CAPITAL LETTER PHI # Phi */ - { 0x03A7, 0x43 }, /* GREEK CAPITAL LETTER CHI # Chi */ - { 0x03A8, 0x59 }, /* GREEK CAPITAL LETTER PSI # Psi */ - { 0x03A9, 0x57 }, /* GREEK CAPITAL LETTER OMEGA # Omega */ - { 0x03B1, 0x61 }, /* GREEK SMALL LETTER ALPHA # alpha */ - { 0x03B2, 0x62 }, /* GREEK SMALL LETTER BETA # beta */ - { 0x03B3, 0x67 }, /* GREEK SMALL LETTER GAMMA # gamma */ - { 0x03B4, 0x64 }, /* GREEK SMALL LETTER DELTA # delta */ - { 0x03B5, 0x65 }, /* GREEK SMALL LETTER EPSILON # epsilon */ - { 0x03B6, 0x7A }, /* GREEK SMALL LETTER ZETA # zeta */ - { 0x03B7, 0x68 }, /* GREEK SMALL LETTER ETA # eta */ - { 0x03B8, 0x71 }, /* GREEK SMALL LETTER THETA # theta */ - { 0x03B9, 0x69 }, /* GREEK SMALL LETTER IOTA # iota */ - { 0x03BA, 0x6B }, /* GREEK SMALL LETTER KAPPA # kappa */ - { 0x03BB, 0x6C }, /* GREEK SMALL LETTER LAMDA # lambda */ - { 0x03BC, 0x6D }, /* GREEK SMALL LETTER MU # mu */ - { 0x03BD, 0x6E }, /* GREEK SMALL LETTER NU # nu */ - { 0x03BE, 0x78 }, /* GREEK SMALL LETTER XI # xi */ - { 0x03BF, 0x6F }, /* GREEK SMALL LETTER OMICRON # omicron */ - { 0x03C0, 0x70 }, /* GREEK SMALL LETTER PI # pi */ - { 0x03C1, 0x72 }, /* GREEK SMALL LETTER RHO # rho */ - { 0x03C2, 0x56 }, /* GREEK SMALL LETTER FINAL SIGMA # sigma1 */ - { 0x03C3, 0x73 }, /* GREEK SMALL LETTER SIGMA # sigma */ - { 0x03C4, 0x74 }, /* GREEK SMALL LETTER TAU # tau */ - { 0x03C5, 0x75 }, /* GREEK SMALL LETTER UPSILON # upsilon */ - { 0x03C6, 0x66 }, /* GREEK SMALL LETTER PHI # phi */ - { 0x03C7, 0x63 }, /* GREEK SMALL LETTER CHI # chi */ - { 0x03C8, 0x79 }, /* GREEK SMALL LETTER PSI # psi */ - { 0x03C9, 0x77 }, /* GREEK SMALL LETTER OMEGA # omega */ - { 0x03D1, 0x4A }, /* GREEK THETA SYMBOL # theta1 */ - { 0x03D2, 0xA1 }, /* GREEK UPSILON WITH HOOK SYMBOL # Upsilon1 */ - { 0x03D5, 0x6A }, /* GREEK PHI SYMBOL # phi1 */ - { 0x03D6, 0x76 }, /* GREEK PI SYMBOL # omega1 */ - { 0x2022, 0xB7 }, /* BULLET # bullet */ - { 0x2026, 0xBC }, /* HORIZONTAL ELLIPSIS # ellipsis */ - { 0x2032, 0xA2 }, /* PRIME # minute */ - { 0x2033, 0xB2 }, /* DOUBLE PRIME # second */ - { 0x2044, 0xA4 }, /* FRACTION SLASH # fraction */ - { 0x20AC, 0xA0 }, /* EURO SIGN # Euro */ - { 0x2111, 0xC1 }, /* BLACK-LETTER CAPITAL I # Ifraktur */ - { 0x2118, 0xC3 }, /* SCRIPT CAPITAL P # weierstrass */ - { 0x211C, 0xC2 }, /* BLACK-LETTER CAPITAL R # Rfraktur */ - { 0x2126, 0x57 }, /* OHM SIGN # Omega */ - { 0x2135, 0xC0 }, /* ALEF SYMBOL # aleph */ - { 0x2190, 0xAC }, /* LEFTWARDS ARROW # arrowleft */ - { 0x2191, 0xAD }, /* UPWARDS ARROW # arrowup */ - { 0x2192, 0xAE }, /* RIGHTWARDS ARROW # arrowright */ - { 0x2193, 0xAF }, /* DOWNWARDS ARROW # arrowdown */ - { 0x2194, 0xAB }, /* LEFT RIGHT ARROW # arrowboth */ - { 0x21B5, 0xBF }, /* DOWNWARDS ARROW WITH CORNER LEFTWARDS # carriagereturn */ - { 0x21D0, 0xDC }, /* LEFTWARDS DOUBLE ARROW # arrowdblleft */ - { 0x21D1, 0xDD }, /* UPWARDS DOUBLE ARROW # arrowdblup */ - { 0x21D2, 0xDE }, /* RIGHTWARDS DOUBLE ARROW # arrowdblright */ - { 0x21D3, 0xDF }, /* DOWNWARDS DOUBLE ARROW # arrowdbldown */ - { 0x21D4, 0xDB }, /* LEFT RIGHT DOUBLE ARROW # arrowdblboth */ - { 0x2200, 0x22 }, /* FOR ALL # universal */ - { 0x2202, 0xB6 }, /* PARTIAL DIFFERENTIAL # partialdiff */ - { 0x2203, 0x24 }, /* THERE EXISTS # existential */ - { 0x2205, 0xC6 }, /* EMPTY SET # emptyset */ - { 0x2206, 0x44 }, /* INCREMENT # Delta */ - { 0x2207, 0xD1 }, /* NABLA # gradient */ - { 0x2208, 0xCE }, /* ELEMENT OF # element */ - { 0x2209, 0xCF }, /* NOT AN ELEMENT OF # notelement */ - { 0x220B, 0x27 }, /* CONTAINS AS MEMBER # suchthat */ - { 0x220F, 0xD5 }, /* N-ARY PRODUCT # product */ - { 0x2211, 0xE5 }, /* N-ARY SUMMATION # summation */ - { 0x2212, 0x2D }, /* MINUS SIGN # minus */ - { 0x2215, 0xA4 }, /* DIVISION SLASH # fraction */ - { 0x2217, 0x2A }, /* ASTERISK OPERATOR # asteriskmath */ - { 0x221A, 0xD6 }, /* SQUARE ROOT # radical */ - { 0x221D, 0xB5 }, /* PROPORTIONAL TO # proportional */ - { 0x221E, 0xA5 }, /* INFINITY # infinity */ - { 0x2220, 0xD0 }, /* ANGLE # angle */ - { 0x2227, 0xD9 }, /* LOGICAL AND # logicaland */ - { 0x2228, 0xDA }, /* LOGICAL OR # logicalor */ - { 0x2229, 0xC7 }, /* INTERSECTION # intersection */ - { 0x222A, 0xC8 }, /* UNION # union */ - { 0x222B, 0xF2 }, /* INTEGRAL # integral */ - { 0x2234, 0x5C }, /* THEREFORE # therefore */ - { 0x223C, 0x7E }, /* TILDE OPERATOR # similar */ - { 0x2245, 0x40 }, /* APPROXIMATELY EQUAL TO # congruent */ - { 0x2248, 0xBB }, /* ALMOST EQUAL TO # approxequal */ - { 0x2260, 0xB9 }, /* NOT EQUAL TO # notequal */ - { 0x2261, 0xBA }, /* IDENTICAL TO # equivalence */ - { 0x2264, 0xA3 }, /* LESS-THAN OR EQUAL TO # lessequal */ - { 0x2265, 0xB3 }, /* GREATER-THAN OR EQUAL TO # greaterequal */ - { 0x2282, 0xCC }, /* SUBSET OF # propersubset */ - { 0x2283, 0xC9 }, /* SUPERSET OF # propersuperset */ - { 0x2284, 0xCB }, /* NOT A SUBSET OF # notsubset */ - { 0x2286, 0xCD }, /* SUBSET OF OR EQUAL TO # reflexsubset */ - { 0x2287, 0xCA }, /* SUPERSET OF OR EQUAL TO # reflexsuperset */ - { 0x2295, 0xC5 }, /* CIRCLED PLUS # circleplus */ - { 0x2297, 0xC4 }, /* CIRCLED TIMES # circlemultiply */ - { 0x22A5, 0x5E }, /* UP TACK # perpendicular */ - { 0x22C5, 0xD7 }, /* DOT OPERATOR # dotmath */ - { 0x2320, 0xF3 }, /* TOP HALF INTEGRAL # integraltp */ - { 0x2321, 0xF5 }, /* BOTTOM HALF INTEGRAL # integralbt */ - { 0x2329, 0xE1 }, /* LEFT-POINTING ANGLE BRACKET # angleleft */ - { 0x232A, 0xF1 }, /* RIGHT-POINTING ANGLE BRACKET # angleright */ - { 0x25CA, 0xE0 }, /* LOZENGE # lozenge */ - { 0x2660, 0xAA }, /* BLACK SPADE SUIT # spade */ - { 0x2663, 0xA7 }, /* BLACK CLUB SUIT # club */ - { 0x2665, 0xA9 }, /* BLACK HEART SUIT # heart */ - { 0x2666, 0xA8 }, /* BLACK DIAMOND SUIT # diamond */ - { 0xF6D9, 0xD3 }, /* COPYRIGHT SIGN SERIF # copyrightserif (CUS) */ - { 0xF6DA, 0xD2 }, /* REGISTERED SIGN SERIF # registerserif (CUS) */ - { 0xF6DB, 0xD4 }, /* TRADE MARK SIGN SERIF # trademarkserif (CUS) */ - { 0xF8E5, 0x60 }, /* RADICAL EXTENDER # radicalex (CUS) */ - { 0xF8E6, 0xBD }, /* VERTICAL ARROW EXTENDER # arrowvertex (CUS) */ - { 0xF8E7, 0xBE }, /* HORIZONTAL ARROW EXTENDER # arrowhorizex (CUS) */ - { 0xF8E8, 0xE2 }, /* REGISTERED SIGN SANS SERIF # registersans (CUS) */ - { 0xF8E9, 0xE3 }, /* COPYRIGHT SIGN SANS SERIF # copyrightsans (CUS) */ - { 0xF8EA, 0xE4 }, /* TRADE MARK SIGN SANS SERIF # trademarksans (CUS) */ - { 0xF8EB, 0xE6 }, /* LEFT PAREN TOP # parenlefttp (CUS) */ - { 0xF8EC, 0xE7 }, /* LEFT PAREN EXTENDER # parenleftex (CUS) */ - { 0xF8ED, 0xE8 }, /* LEFT PAREN BOTTOM # parenleftbt (CUS) */ - { 0xF8EE, 0xE9 }, /* LEFT SQUARE BRACKET TOP # bracketlefttp (CUS) */ - { 0xF8EF, 0xEA }, /* LEFT SQUARE BRACKET EXTENDER # bracketleftex (CUS) */ - { 0xF8F0, 0xEB }, /* LEFT SQUARE BRACKET BOTTOM # bracketleftbt (CUS) */ - { 0xF8F1, 0xEC }, /* LEFT CURLY BRACKET TOP # bracelefttp (CUS) */ - { 0xF8F2, 0xED }, /* LEFT CURLY BRACKET MID # braceleftmid (CUS) */ - { 0xF8F3, 0xEE }, /* LEFT CURLY BRACKET BOTTOM # braceleftbt (CUS) */ - { 0xF8F4, 0xEF }, /* CURLY BRACKET EXTENDER # braceex (CUS) */ - { 0xF8F5, 0xF4 }, /* INTEGRAL EXTENDER # integralex (CUS) */ - { 0xF8F6, 0xF6 }, /* RIGHT PAREN TOP # parenrighttp (CUS) */ - { 0xF8F7, 0xF7 }, /* RIGHT PAREN EXTENDER # parenrightex (CUS) */ - { 0xF8F8, 0xF8 }, /* RIGHT PAREN BOTTOM # parenrightbt (CUS) */ - { 0xF8F9, 0xF9 }, /* RIGHT SQUARE BRACKET TOP # bracketrighttp (CUS) */ - { 0xF8FA, 0xFA }, /* RIGHT SQUARE BRACKET EXTENDER # bracketrightex (CUS) */ - { 0xF8FB, 0xFB }, /* RIGHT SQUARE BRACKET BOTTOM # bracketrightbt (CUS) */ - { 0xF8FC, 0xFC }, /* RIGHT CURLY BRACKET TOP # bracerighttp (CUS) */ - { 0xF8FD, 0xFD }, /* RIGHT CURLY BRACKET MID # bracerightmid (CUS) */ - { 0xF8FE, 0xFE }, /* RIGHT CURLY BRACKET BOTTOM # bracerightbt (CUS) */ +static const FT_Encoding fcFontEncodings[] = { + FT_ENCODING_UNICODE, + FT_ENCODING_MS_SYMBOL }; -static const FcCharMap AdobeSymbol = { - AdobeSymbolEnt, - sizeof (AdobeSymbolEnt) / sizeof (AdobeSymbolEnt[0]), -}; - -static const FcFontDecode fcFontDecoders[] = { - { ft_encoding_unicode, 0, (1 << 21) - 1 }, - { ft_encoding_symbol, &AdobeSymbol, (1 << 16) - 1 }, -}; - -#define NUM_DECODE (int) (sizeof (fcFontDecoders) / sizeof (fcFontDecoders[0])) - -static const FcChar32 prefer_unicode[] = { - 0x20ac, /* EURO SIGN */ -}; - -#define NUM_PREFER_UNICODE (int) (sizeof (prefer_unicode) / sizeof (prefer_unicode[0])) - -FcChar32 -FcFreeTypeUcs4ToPrivate (FcChar32 ucs4, const FcCharMap *map) -{ - int low, high, mid; - FcChar16 bmp; - - low = 0; - high = map->nent - 1; - if (ucs4 < map->ent[low].bmp || map->ent[high].bmp < ucs4) - return ~0; - while (low <= high) - { - mid = (high + low) >> 1; - bmp = map->ent[mid].bmp; - if (ucs4 == bmp) - return (FT_ULong) map->ent[mid].encode; - if (ucs4 < bmp) - high = mid - 1; - else - low = mid + 1; - } - return ~0; -} - -FcChar32 -FcFreeTypePrivateToUcs4 (FcChar32 private, const FcCharMap *map) -{ - int i; - - for (i = 0; i < map->nent; i++) - if (map->ent[i].encode == private) - return (FcChar32) map->ent[i].bmp; - return ~0; -} - -const FcCharMap * -FcFreeTypeGetPrivateMap (FT_Encoding encoding) -{ - int i; - - for (i = 0; i < NUM_DECODE; i++) - if (fcFontDecoders[i].encoding == encoding) - return fcFontDecoders[i].map; - return 0; -} +#define NUM_DECODE (int) (sizeof (fcFontEncodings) / sizeof (fcFontEncodings[0])) #include "../fc-glyphname/fcglyphname.h" @@ -2237,8 +2134,6 @@ FcFreeTypeCharIndex (FT_Face face, FcChar32 ucs4) { int initial, offset, decode; FT_UInt glyphindex; - FcChar32 charcode; - int p; initial = 0; @@ -2251,37 +2146,39 @@ FcFreeTypeCharIndex (FT_Face face, FcChar32 ucs4) if (face->charmap) { for (; initial < NUM_DECODE; initial++) - if (fcFontDecoders[initial].encoding == face->charmap->encoding) + if (fcFontEncodings[initial] == face->charmap->encoding) break; if (initial == NUM_DECODE) initial = 0; } - for (p = 0; p < NUM_PREFER_UNICODE; p++) - if (ucs4 == prefer_unicode[p]) - { - initial = 0; - break; - } /* * Check each encoding for the glyph, starting with the current one */ for (offset = 0; offset < NUM_DECODE; offset++) { decode = (initial + offset) % NUM_DECODE; - if (!face->charmap || face->charmap->encoding != fcFontDecoders[decode].encoding) - if (FT_Select_Charmap (face, fcFontDecoders[decode].encoding) != 0) + if (!face->charmap || face->charmap->encoding != fcFontEncodings[decode]) + if (FT_Select_Charmap (face, fcFontEncodings[decode]) != 0) continue; - if (fcFontDecoders[decode].map) - { - charcode = FcFreeTypeUcs4ToPrivate (ucs4, fcFontDecoders[decode].map); - if (charcode == ~0U) - continue; - } - else - charcode = ucs4; - glyphindex = FT_Get_Char_Index (face, (FT_ULong) charcode); + glyphindex = FT_Get_Char_Index (face, (FT_ULong) ucs4); if (glyphindex) return glyphindex; + if (ucs4 < 0x100 && face->charmap && + face->charmap->encoding == FT_ENCODING_MS_SYMBOL) + { + /* For symbol-encoded OpenType fonts, we duplicate the + * U+F000..F0FF range at U+0000..U+00FF. That's what + * Windows seems to do, and that's hinted about at: + * http://www.microsoft.com/typography/otspec/recom.htm + * under "Non-Standard (Symbol) Fonts". + * + * See thread with subject "Webdings and other MS symbol + * fonts don't display" on mailing list from May 2015. + */ + glyphindex = FT_Get_Char_Index (face, (FT_ULong) ucs4 + 0xF000); + if (glyphindex) + return glyphindex; + } } #if HAVE_FT_HAS_PS_GLYPH_NAMES /* @@ -2372,9 +2269,7 @@ FcFreeTypeCharSetAndSpacingForSize (FT_Face face, FcBlanks *blanks, int *spacing #endif FcCharSet *fcs; FcCharLeaf *leaf; - const FcCharMap *map; int o; - int i; FT_UInt glyph; FT_Pos advance, advance_one = 0, advance_two = 0; FcBool has_advance = FcFalse, fixed_advance = FcTrue, dual_advance = FcFalse; @@ -2397,62 +2292,9 @@ FcFreeTypeCharSetAndSpacingForSize (FT_Face face, FcBlanks *blanks, int *spacing #endif for (o = 0; o < NUM_DECODE; o++) { - if (FT_Select_Charmap (face, fcFontDecoders[o].encoding) != 0) + if (FT_Select_Charmap (face, fcFontEncodings[o]) != 0) continue; - map = fcFontDecoders[o].map; - if (map) - { - /* - * Non-Unicode tables are easy; there's a list of all possible - * characters - */ - for (i = 0; i < map->nent; i++) - { - ucs4 = map->ent[i].bmp; - glyph = FT_Get_Char_Index (face, map->ent[i].encode); - if (glyph && - FcFreeTypeCheckGlyph (face, ucs4, glyph, blanks, &advance, using_strike)) - { - /* - * ignore glyphs with zero advance. They’re - * combining characters, and while their behaviour - * isn’t well defined for monospaced applications in - * Unicode, there are many fonts which include - * zero-width combining characters in otherwise - * monospaced fonts. - */ - if (advance) - { - if (!has_advance) - { - has_advance = FcTrue; - advance_one = advance; - } - else if (!APPROXIMATELY_EQUAL (advance, advance_one)) - { - if (fixed_advance) - { - dual_advance = FcTrue; - fixed_advance = FcFalse; - advance_two = advance; - } - else if (!APPROXIMATELY_EQUAL (advance, advance_two)) - dual_advance = FcFalse; - } - } - leaf = FcCharSetFindLeafCreate (fcs, ucs4); - if (!leaf) - goto bail1; - leaf->map[(ucs4 & 0xff) >> 5] |= (1 << (ucs4 & 0x1f)); -#ifdef CHECK - if (ucs4 > font_max) - font_max = ucs4; -#endif - } - } - } - else { page = ~0; leaf = NULL; @@ -2497,6 +2339,23 @@ FcFreeTypeCharSetAndSpacingForSize (FT_Face face, FcBlanks *blanks, int *spacing } ucs4 = FT_Get_Next_Char (face, ucs4, &glyph); } + if (fcFontEncodings[o] == FT_ENCODING_MS_SYMBOL) + { + /* For symbol-encoded OpenType fonts, we duplicate the + * U+F000..F0FF range at U+0000..U+00FF. That's what + * Windows seems to do, and that's hinted about at: + * http://www.microsoft.com/typography/otspec/recom.htm + * under "Non-Standard (Symbol) Fonts". + * + * See thread with subject "Webdings and other MS symbol + * fonts don't display" on mailing list from May 2015. + */ + for (ucs4 = 0xF000; ucs4 < 0xF100; ucs4++) + { + if (FcCharSetHasChar (fcs, ucs4)) + FcCharSetAddChar (fcs, ucs4 - 0xF000); + } + } #ifdef CHECK for (ucs4 = 0; ucs4 < 0x10000; ucs4++) { @@ -2511,6 +2370,8 @@ FcFreeTypeCharSetAndSpacingForSize (FT_Face face, FcBlanks *blanks, int *spacing } #endif } + + break; } #if HAVE_FT_HAS_PS_GLYPH_NAMES /* @@ -2790,7 +2651,7 @@ FcFontCapabilities(FT_Face face) complex_[0] = '\0'; if (issilgraphitefont) - strcpy((char *) complex_, "ttable:Silf "); + strcpy((char *) complex_, "ttable:Silf "); while ((indx1 < gsub_count) || (indx2 < gpos_count)) { if (indx1 == gsub_count) { diff --git a/dist/fontconfig/src/fchash.c b/dist/fontconfig/src/fchash.c deleted file mode 100644 index 38300028c..000000000 --- a/dist/fontconfig/src/fchash.c +++ /dev/null @@ -1,317 +0,0 @@ -/* - * fontconfig/src/fchash.c - * - * Copyright © 2003 Keith Packard - * Copyright © 2013 Red Hat, Inc. - * Red Hat Author(s): Akira TAGOH - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of the author(s) not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. The authors make no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ -#include "fcint.h" -#include <stdio.h> -#include <string.h> - -#define ROTRN(w, v, n) ((((FcChar32)v) >> n) | (((FcChar32)v) << (w - n))) -#define ROTR32(v, n) ROTRN(32, v, n) -#define SHR(v, n) (v >> n) -#define Ch(x, y, z) ((x & y) ^ (~x & z)) -#define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z)) -#define SS0(x) (ROTR32(x, 2) ^ ROTR32(x, 13) ^ ROTR32(x, 22)) -#define SS1(x) (ROTR32(x, 6) ^ ROTR32(x, 11) ^ ROTR32(x, 25)) -#define ss0(x) (ROTR32(x, 7) ^ ROTR32(x, 18) ^ SHR(x, 3)) -#define ss1(x) (ROTR32(x, 17) ^ ROTR32(x, 19) ^ SHR(x, 10)) - - -static FcChar32 * -FcHashInitSHA256Digest (void) -{ - int i; - static const FcChar32 h[] = { - 0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, 0xa54ff53aUL, - 0x510e527fUL, 0x9b05688cUL, 0x1f83d9abUL, 0x5be0cd19UL - }; - FcChar32 *ret = malloc (sizeof (FcChar32) * 8); - - if (!ret) - return NULL; - - for (i = 0; i < 8; i++) - ret[i] = h[i]; - - return ret; -} - -static void -FcHashComputeSHA256Digest (FcChar32 *hash, - const char *block) -{ - static const FcChar32 k[] = { - 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, - 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, - 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, - 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, - 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, - 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, - 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, - 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, - 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, - 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, - 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, - 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, - 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, - 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, - 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, - 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL - }; - FcChar32 w[64], i, j, t1, t2; - FcChar32 a, b, c, d, e, f, g, h; - -#define H(n) (hash[n]) - - a = H(0); - b = H(1); - c = H(2); - d = H(3); - e = H(4); - f = H(5); - g = H(6); - h = H(7); - - for (i = 0; i < 16; i++) - { - j = (block[(i * 4) + 0] & 0xff) << (8 * 3); - j |= (block[(i * 4) + 1] & 0xff) << (8 * 2); - j |= (block[(i * 4) + 2] & 0xff) << (8 * 1); - j |= (block[(i * 4) + 3] & 0xff); - w[i] = j; - } - for (i = 16; i < 64; i++) - w[i] = ss1(w[i - 2]) + w[i - 7] + ss0(w[i - 15]) + w[i - 16]; - - for (i = 0; i < 64; i++) - { - t1 = h + SS1(e) + Ch(e, f, g) + k[i] + w[i]; - t2 = SS0(a) + Maj(a, b, c); - h = g; - g = f; - f = e; - e = d + t1; - d = c; - c = b; - b = a; - a = t1 + t2; - } - - H(0) += a; - H(1) += b; - H(2) += c; - H(3) += d; - H(4) += e; - H(5) += f; - H(6) += g; - H(7) += h; - -#undef H -} - -static FcChar8 * -FcHashSHA256ToString (FcChar32 *hash) -{ - FcChar8 *ret = NULL; - static const char hex[] = "0123456789abcdef"; - int i, j; - - if (hash) - { - ret = malloc (sizeof (FcChar8) * (8 * 8 + 7 + 1)); - if (!ret) - return NULL; - memcpy (ret, "sha256:", 7); -#define H(n) hash[n] - for (i = 0; i < 8; i++) - { - FcChar32 v = H(i); - - for (j = 0; j < 8; j++) - ret[7 + (i * 8) + j] = hex[(v >> (28 - j * 4)) & 0xf]; - } - ret[7 + i * 8] = 0; -#undef H - free (hash); - } - - return ret; -} - -FcChar8 * -FcHashGetSHA256Digest (const FcChar8 *input_strings, - size_t len) -{ - size_t i, round_len = len / 64; - char block[64]; - FcChar32 *ret = FcHashInitSHA256Digest (); - - if (!ret) - return NULL; - - for (i = 0; i < round_len; i++) - { - FcHashComputeSHA256Digest (ret, (const char *)&input_strings[i * 64]); - } - /* padding */ - if ((len % 64) != 0) - memcpy (block, &input_strings[len / 64], len % 64); - memset (&block[len % 64], 0, 64 - (len % 64)); - block[len % 64] = 0x80; - if ((64 - (len % 64)) < 9) - { - /* process a block once */ - FcHashComputeSHA256Digest (ret, block); - memset (block, 0, 64); - } - /* set input size at the end */ - len *= 8; - block[63 - 0] = (uint64_t)len & 0xff; - block[63 - 1] = ((uint64_t)len >> 8) & 0xff; - block[63 - 2] = ((uint64_t)len >> 16) & 0xff; - block[63 - 3] = ((uint64_t)len >> 24) & 0xff; - block[63 - 4] = ((uint64_t)len >> 32) & 0xff; - block[63 - 5] = ((uint64_t)len >> 40) & 0xff; - block[63 - 6] = ((uint64_t)len >> 48) & 0xff; - block[63 - 7] = ((uint64_t)len >> 56) & 0xff; - FcHashComputeSHA256Digest (ret, block); - - return FcHashSHA256ToString (ret); -} - -FcChar8 * -FcHashGetSHA256DigestFromFile (const FcChar8 *filename) -{ - FILE *fp = fopen ((const char *)filename, "rb"); - char ibuf[64]; - FcChar32 *ret; - size_t len; - struct stat st; - - if (!fp) - return NULL; - - if (FcStat (filename, &st)) - goto bail0; - - ret = FcHashInitSHA256Digest (); - if (!ret) - goto bail0; - - while (!feof (fp)) - { - if ((len = fread (ibuf, sizeof (char), 64, fp)) < 64) - { - uint64_t v; - - /* add a padding */ - memset (&ibuf[len], 0, 64 - len); - ibuf[len] = 0x80; - if ((64 - len) < 9) - { - /* process a block once */ - FcHashComputeSHA256Digest (ret, ibuf); - memset (ibuf, 0, 64); - } - /* set input size at the end */ - v = (long)st.st_size * 8; - ibuf[63 - 0] = v & 0xff; - ibuf[63 - 1] = (v >> 8) & 0xff; - ibuf[63 - 2] = (v >> 16) & 0xff; - ibuf[63 - 3] = (v >> 24) & 0xff; - ibuf[63 - 4] = (v >> 32) & 0xff; - ibuf[63 - 5] = (v >> 40) & 0xff; - ibuf[63 - 6] = (v >> 48) & 0xff; - ibuf[63 - 7] = (v >> 56) & 0xff; - FcHashComputeSHA256Digest (ret, ibuf); - break; - } - else - { - FcHashComputeSHA256Digest (ret, ibuf); - } - } - fclose (fp); - - return FcHashSHA256ToString (ret); - -bail0: - fclose (fp); - - return NULL; -} - -FcChar8 * -FcHashGetSHA256DigestFromMemory (const char *fontdata, - size_t length) -{ - char ibuf[64]; - FcChar32 *ret; - size_t i = 0; - - ret = FcHashInitSHA256Digest (); - if (!ret) - return NULL; - - while (i <= length) - { - if ((length - i) < 64) - { - uint64_t v; - size_t n; - - /* add a padding */ - n = length - i; - if (n > 0) - memcpy (ibuf, &fontdata[i], n); - memset (&ibuf[n], 0, 64 - n); - ibuf[n] = 0x80; - if ((64 - n) < 9) - { - /* process a block once */ - FcHashComputeSHA256Digest (ret, ibuf); - memset (ibuf, 0, 64); - } - /* set input size at the end */ - v = length * 8; - ibuf[63 - 0] = v & 0xff; - ibuf[63 - 1] = (v >> 8) & 0xff; - ibuf[63 - 2] = (v >> 16) & 0xff; - ibuf[63 - 3] = (v >> 24) & 0xff; - ibuf[63 - 4] = (v >> 32) & 0xff; - ibuf[63 - 5] = (v >> 40) & 0xff; - ibuf[63 - 6] = (v >> 48) & 0xff; - ibuf[63 - 7] = (v >> 56) & 0xff; - FcHashComputeSHA256Digest (ret, ibuf); - break; - } - else - { - FcHashComputeSHA256Digest (ret, &fontdata[i]); - } - i += 64; - } - - return FcHashSHA256ToString (ret); -} diff --git a/dist/fontconfig/src/fcinit.c b/dist/fontconfig/src/fcinit.c index b8d5d060c..5e7c2f156 100644 --- a/dist/fontconfig/src/fcinit.c +++ b/dist/fontconfig/src/fcinit.c @@ -36,13 +36,14 @@ #endif static FcConfig * -FcInitFallbackConfig (void) +FcInitFallbackConfig (const FcChar8 *sysroot) { FcConfig *config; config = FcConfigCreate (); if (!config) goto bail0; + FcConfigSetSysRoot (config, sysroot); if (!FcConfigAddDir (config, (FcChar8 *) FC_DEFAULT_FONTS)) goto bail1; if (!FcConfigAddCacheDir (config, (FcChar8 *) FC_CACHEDIR)) @@ -78,20 +79,35 @@ FcInitLoadOwnConfig (FcConfig *config) if (!FcConfigParseAndLoad (config, 0, FcTrue)) { + const FcChar8 *sysroot = FcConfigGetSysRoot (config); + FcConfig *fallback = FcInitFallbackConfig (sysroot); + FcConfigDestroy (config); - return FcInitFallbackConfig (); + + return fallback; } if (config->cacheDirs && config->cacheDirs->num == 0) { FcChar8 *prefix, *p; size_t plen; + FcBool have_own = FcFalse; + char *env_file, *env_path; - fprintf (stderr, - "Fontconfig warning: no <cachedir> elements found. Check configuration.\n"); - fprintf (stderr, - "Fontconfig warning: adding <cachedir>%s</cachedir>\n", - FC_CACHEDIR); + env_file = getenv ("FONTCONFIG_FILE"); + env_path = getenv ("FONTCONFIG_PATH"); + if ((env_file != NULL && env_file[0] != 0) || + (env_path != NULL && env_path[0] != 0)) + have_own = FcTrue; + + if (!have_own) + { + fprintf (stderr, + "Fontconfig warning: no <cachedir> elements found. Check configuration.\n"); + fprintf (stderr, + "Fontconfig warning: adding <cachedir>%s</cachedir>\n", + FC_CACHEDIR); + } prefix = FcConfigXdgCacheHome (); if (!prefix) goto bail; @@ -102,19 +118,26 @@ FcInitLoadOwnConfig (FcConfig *config) prefix = p; memcpy (&prefix[plen], FC_DIR_SEPARATOR_S "fontconfig", 11); prefix[plen + 11] = 0; - fprintf (stderr, - "Fontconfig warning: adding <cachedir prefix=\"xdg\">fontconfig</cachedir>\n"); + if (!have_own) + fprintf (stderr, + "Fontconfig warning: adding <cachedir prefix=\"xdg\">fontconfig</cachedir>\n"); if (!FcConfigAddCacheDir (config, (FcChar8 *) FC_CACHEDIR) || !FcConfigAddCacheDir (config, (FcChar8 *) prefix)) { + FcConfig *fallback; + const FcChar8 *sysroot; + bail: + sysroot = FcConfigGetSysRoot (config); fprintf (stderr, "Fontconfig error: out of memory"); if (prefix) FcStrFree (prefix); + fallback = FcInitFallbackConfig (sysroot); FcConfigDestroy (config); - return FcInitFallbackConfig (); + + return fallback; } FcStrFree (prefix); } @@ -169,6 +192,8 @@ FcFini (void) FcConfigFini (); FcCacheFini (); FcDefaultFini (); + FcObjectFini (); + FcConfigPathFini (); } /* @@ -178,11 +203,18 @@ FcBool FcInitReinitialize (void) { FcConfig *config; + FcBool ret; config = FcInitLoadConfigAndFonts (); if (!config) return FcFalse; - return FcConfigSetCurrent (config); + ret = FcConfigSetCurrent (config); + /* FcConfigSetCurrent() increases the refcount. + * decrease it here to avoid the memory leak. + */ + FcConfigDestroy (config); + + return ret; } FcBool @@ -191,6 +223,8 @@ FcInitBringUptoDate (void) FcConfig *config = FcConfigGetCurrent (); time_t now; + if (!config) + return FcFalse; /* * rescanInterval == 0 disables automatic up to date */ diff --git a/dist/fontconfig/src/fcint.h b/dist/fontconfig/src/fcint.h index cdf2daba0..ac911ad40 100644 --- a/dist/fontconfig/src/fcint.h +++ b/dist/fontconfig/src/fcint.h @@ -38,6 +38,8 @@ #include <assert.h> #include <errno.h> #include <limits.h> +#include <float.h> +#include <math.h> #include <unistd.h> #include <stddef.h> #include <sys/types.h> @@ -85,6 +87,7 @@ extern pfnSHGetFolderPathA pSHGetFolderPathA; #define FC_DBG_SCANV 256 #define FC_DBG_CONFIG 1024 #define FC_DBG_LANGSET 2048 +#define FC_DBG_MATCH2 4096 #define _FC_ASSERT_STATIC1(_line, _cond) typedef int _static_assert_on_line_##_line##_failed[(_cond)?1:-1] FC_UNUSED #define _FC_ASSERT_STATIC0(_line, _cond) _FC_ASSERT_STATIC1 (_line, (_cond)) @@ -161,6 +164,7 @@ typedef enum _FcValueBinding { #define FcValueString(v) FcPointerMember(v,u.s,FcChar8) #define FcValueCharSet(v) FcPointerMember(v,u.c,const FcCharSet) #define FcValueLangSet(v) FcPointerMember(v,u.l,const FcLangSet) +#define FcValueRange(v) FcPointerMember(v,u.r,const FcRange) typedef struct _FcValueList *FcValueListPtr; @@ -244,20 +248,26 @@ typedef struct _FcExprName { FcMatchKind kind; } FcExprName; +struct _FcRange { + double begin; + double end; +}; + typedef struct _FcExpr { FcOp op; union { - int ival; - double dval; - const FcChar8 *sval; - FcExprMatrix *mexpr; - FcBool bval; - FcCharSet *cval; - FcLangSet *lval; - - FcExprName name; - const FcChar8 *constant; + int ival; + double dval; + const FcChar8 *sval; + FcExprMatrix *mexpr; + FcBool bval; + FcCharSet *cval; + FcLangSet *lval; + FcRange *rval; + + FcExprName name; + const FcChar8 *constant; struct { struct _FcExpr *left, *right; } tree; @@ -329,11 +339,19 @@ struct _FcCharSet { FcCharLeaf)) #define FcCharSetNumbers(c) FcOffsetMember(c,numbers_offset,FcChar16) +#define FCSS_DEFAULT 0 /* default behavior */ +#define FCSS_ALLOW_DUPLICATES 1 /* allows for duplicate strings in the set */ +#define FCSS_GROW_BY_64 2 /* grows buffer by 64 elements instead of 1 */ + +#define FcStrSetHasControlBit(s,c) (s->control & c) +#define FcStrSetHasControlBits(s,c) ( (c) == (s->control & (c)) ) + struct _FcStrSet { FcRef ref; /* reference count */ int num; int size; FcChar8 **strs; + unsigned int control; /* control bits for set behavior */ }; struct _FcStrList { @@ -352,13 +370,14 @@ typedef struct _FcStrBuf { struct _FcCache { unsigned int magic; /* FC_CACHE_MAGIC_MMAP or FC_CACHE_ALLOC */ - int version; /* FC_CACHE_CONTENT_VERSION */ + int version; /* FC_CACHE_VERSION_NUMBER */ intptr_t size; /* size of file */ intptr_t dir; /* offset to dir name */ intptr_t dirs; /* offset to subdirs */ int dirs_count; /* number of subdir strings */ intptr_t set; /* offset to font set */ int checksum; /* checksum of directory state */ + int64_t checksum_nano; /* checksum of directory state */ }; #undef FcCacheDir @@ -444,7 +463,6 @@ typedef struct _FcCaseFold { #define FC_CACHE_MAGIC_MMAP 0xFC02FC04 #define FC_CACHE_MAGIC_ALLOC 0xFC02FC05 -#define FC_CACHE_CONTENT_VERSION 4 struct _FcAtomic { FcChar8 *file; /* original file name */ @@ -532,13 +550,6 @@ typedef struct _FcFileTime { typedef struct _FcCharMap FcCharMap; -typedef struct _FcRange FcRange; - -struct _FcRange { - FcChar32 begin; - FcChar32 end; -}; - typedef struct _FcStatFS FcStatFS; struct _FcStatFS { @@ -588,6 +599,13 @@ FcCacheFini (void); FcPrivate void FcDirCacheReference (FcCache *cache, int nref); +FcPrivate int +FcDirCacheLock (const FcChar8 *dir, + FcConfig *config); + +FcPrivate void +FcDirCacheUnlock (int fd); + /* fccfg.c */ FcPrivate FcBool @@ -701,6 +719,9 @@ FcPrivate FcLangSet * FcLangSetSerialize(FcSerialize *serialize, const FcLangSet *l); /* fccharset.c */ +FcPrivate FcCharSet * +FcCharSetPromote (FcValuePromotionBuffer *vbuf); + FcPrivate void FcLangCharSetPopulate (void); @@ -789,6 +810,9 @@ FcSubstPrint (const FcSubst *subst); FcPrivate void FcCharSetPrint (const FcCharSet *c); +FcPrivate void +FcPatternPrint2 (FcPattern *p1, FcPattern *p2, const FcObjectSet *os); + extern FcPrivate int FcDebugVal; #define FcDebug() (FcDebugVal) @@ -844,18 +868,6 @@ FcFontSetSerialize (FcSerialize *serialize, const FcFontSet * s); FcPrivate FcFontSet * FcFontSetDeserialize (const FcFontSet *set); -/* fchash.c */ -FcPrivate FcChar8 * -FcHashGetSHA256Digest (const FcChar8 *input_strings, - size_t len); - -FcPrivate FcChar8 * -FcHashGetSHA256DigestFromFile (const FcChar8 *filename); - -FcPrivate FcChar8 * -FcHashGetSHA256DigestFromMemory (const char *fontdata, - size_t length); - /* fcinit.c */ FcPrivate FcConfig * FcInitLoadOwnConfig (FcConfig *config); @@ -865,6 +877,9 @@ FcInitLoadOwnConfigAndFonts (FcConfig *config); /* fcxml.c */ FcPrivate void +FcConfigPathFini (void); + +FcPrivate void FcTestDestroy (FcTest *test); FcPrivate void @@ -1008,6 +1023,9 @@ FcPatternObjectAddBool (FcPattern *p, FcObject object, FcBool b); FcPrivate FcBool FcPatternObjectAddLangSet (FcPattern *p, FcObject object, const FcLangSet *ls); +FcPrivate FcBool +FcPatternObjectAddRange (FcPattern *p, FcObject object, const FcRange *r); + FcPrivate FcResult FcPatternObjectGetInteger (const FcPattern *p, FcObject object, int n, int *i); @@ -1029,9 +1047,15 @@ FcPatternObjectGetBool (const FcPattern *p, FcObject object, int n, FcBool *b); FcPrivate FcResult FcPatternObjectGetLangSet (const FcPattern *p, FcObject object, int n, FcLangSet **ls); +FcPrivate FcResult +FcPatternObjectGetRange (const FcPattern *p, FcObject object, int id, FcRange **r); + FcPrivate FcBool FcPatternAppend (FcPattern *p, FcPattern *s); +FcPrivate int +FcPatternPosition (const FcPattern *p, const char *object); + FcPrivate FcChar32 FcStringHash (const FcChar8 *s); @@ -1056,6 +1080,26 @@ extern FcPrivate const FcMatrix FcIdentityMatrix; FcPrivate void FcMatrixFree (FcMatrix *mat); +/* fcrange.c */ + +FcPrivate FcRange * +FcRangePromote (double v, FcValuePromotionBuffer *vbuf); + +FcPrivate FcBool +FcRangeIsInRange (const FcRange *a, const FcRange *b); + +FcPrivate FcBool +FcRangeCompare (FcOp op, const FcRange *a, const FcRange *b); + +FcPrivate FcChar32 +FcRangeHash (const FcRange *r); + +FcPrivate FcBool +FcRangeSerializeAlloc (FcSerialize *serialize, const FcRange *r); + +FcPrivate FcRange * +FcRangeSerialize (FcSerialize *serialize, const FcRange *r); + /* fcstat.c */ FcPrivate int @@ -1071,6 +1115,9 @@ FcPrivate FcBool FcIsFsMtimeBroken (const FcChar8 *dir); /* fcstr.c */ +FcPrivate FcStrSet * +FcStrSetCreateEx (unsigned int control); + FcPrivate FcBool FcStrSetAddLangs (FcStrSet *strs, const char *languages); @@ -1104,12 +1151,6 @@ FcStrCmpIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2); FcPrivate int FcStrCmpIgnoreCaseAndDelims (const FcChar8 *s1, const FcChar8 *s2, const FcChar8 *delims); -FcPrivate FcBool -FcStrRegexCmp (const FcChar8 *s, const FcChar8 *regex); - -FcPrivate FcBool -FcStrRegexCmpIgnoreCase (const FcChar8 *s, const FcChar8 *regex); - FcPrivate const FcChar8 * FcStrContainsIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2); @@ -1150,6 +1191,9 @@ FcStrSerialize (FcSerialize *serialize, const FcChar8 *str); /* fcobjs.c */ +FcPrivate void +FcObjectFini (void); + FcPrivate FcObject FcObjectLookupIdByName (const char *str); diff --git a/dist/fontconfig/src/fclang.c b/dist/fontconfig/src/fclang.c index 9f685f6fd..b1fd1bcae 100644 --- a/dist/fontconfig/src/fclang.c +++ b/dist/fontconfig/src/fclang.c @@ -720,19 +720,22 @@ FcLangSetPromote (const FcChar8 *lang, FcValuePromotionBuffer *vbuf) memset (buf->ls.map, '\0', sizeof (buf->ls.map)); buf->ls.map_size = NUM_LANG_SET_MAP; buf->ls.extra = 0; - id = FcLangSetIndex (lang); - if (id > 0) + if (lang) { - FcLangSetBitSet (&buf->ls, id); - } - else - { - buf->ls.extra = &buf->strs; - buf->strs.num = 1; - buf->strs.size = 1; - buf->strs.strs = &buf->str; - FcRefInit (&buf->strs.ref, 1); - buf->str = (FcChar8 *) lang; + id = FcLangSetIndex (lang); + if (id > 0) + { + FcLangSetBitSet (&buf->ls, id); + } + else + { + buf->ls.extra = &buf->strs; + buf->strs.num = 1; + buf->strs.size = 1; + buf->strs.strs = &buf->str; + FcRefInit (&buf->strs.ref, 1); + buf->str = (FcChar8 *) lang; + } } return &buf->ls; } diff --git a/dist/fontconfig/src/fclist.c b/dist/fontconfig/src/fclist.c index a365098a4..d7e8fc091 100644 --- a/dist/fontconfig/src/fclist.c +++ b/dist/fontconfig/src/fclist.c @@ -270,9 +270,11 @@ FcListValueHash (FcValue *value) case FcTypeCharSet: return FcCharSetCount (v.u.c); case FcTypeFTFace: - return (long) v.u.f; + return (intptr_t) v.u.f; case FcTypeLangSet: return FcLangSetHash (v.u.l); + case FcTypeRange: + return FcRangeHash (v.u.r); } return 0; } diff --git a/dist/fontconfig/src/fcmatch.c b/dist/fontconfig/src/fcmatch.c index 93e013f9b..40efbd3f6 100644 --- a/dist/fontconfig/src/fcmatch.c +++ b/dist/fontconfig/src/fcmatch.c @@ -189,6 +189,49 @@ FcCompareSize (FcValue *value1, FcValue *value2) } static double +FcCompareSizeRange (FcValue *v1, FcValue *v2) +{ + FcValue value1 = FcValueCanonicalize (v1); + FcValue value2 = FcValueCanonicalize (v2); + FcRange *r1 = NULL, *r2 = NULL; + double ret = -1.0; + + switch ((int) value1.type) { + case FcTypeDouble: + r1 = FcRangeCreateDouble (value1.u.d, value1.u.d); + break; + case FcTypeRange: + r1 = FcRangeCopy (value1.u.r); + break; + default: + goto bail; + } + switch ((int) value2.type) { + case FcTypeDouble: + r2 = FcRangeCreateDouble (value2.u.d, value2.u.d); + break; + case FcTypeRange: + r2 = FcRangeCopy (value2.u.r); + break; + default: + goto bail; + } + + if (FcRangeIsInRange (r1, r2)) + ret = 0.0; + else + ret = FC_MIN (fabs (r1->end - r2->begin), fabs (r1->begin - r2->end)); + +bail: + if (r1) + FcRangeDestroy (r1); + if (r2) + FcRangeDestroy (r2); + + return ret; +} + +static double FcCompareFilename (FcValue *v1, FcValue *v2) { const FcChar8 *s1 = FcValueString (v1), *s2 = FcValueString (v2); @@ -202,16 +245,8 @@ FcCompareFilename (FcValue *v1, FcValue *v2) return 3.0; } -static double -FcCompareHash (FcValue *v1, FcValue *v2) -{ - const FcChar8 *s1 = FcValueString (v1), *s2 = FcValueString (v2); - /* Do not match an empty string */ - if (!s1 || !s2 || !s1[0] || !s2[0]) - return 1.0; - return FcCompareString (v1, v2); -} +/* Define priorities to -1 for objects that don't have a compare function. */ #define PRI_NULL(n) \ PRI_ ## n ## _STRONG = -1, \ @@ -226,7 +261,7 @@ FcCompareHash (FcValue *v1, FcValue *v2) #define PRI_FcCompareCharSet(n) PRI1(n) #define PRI_FcCompareLang(n) PRI1(n) #define PRI_FcComparePostScript(n) PRI1(n) -#define PRI_FcCompareHash(n) PRI1(n) +#define PRI_FcCompareSizeRange(n) PRI1(n) #define FC_OBJECT(NAME, Type, Cmp) PRI_##Cmp(NAME) @@ -236,6 +271,9 @@ typedef enum _FcMatcherPriorityDummy { #undef FC_OBJECT + +/* Canonical match priority order. */ + #undef PRI1 #define PRI1(n) \ PRI_ ## n, \ @@ -243,10 +281,10 @@ typedef enum _FcMatcherPriorityDummy { PRI_ ## n ## _WEAK = PRI_ ## n typedef enum _FcMatcherPriority { - PRI1(HASH), PRI1(FILE), PRI1(FONTFORMAT), PRI1(SCALABLE), + PRI1(COLOR), PRI1(FOUNDRY), PRI1(CHARSET), PRI_FAMILY_STRONG, @@ -254,7 +292,9 @@ typedef enum _FcMatcherPriority { PRI1(LANG), PRI_FAMILY_WEAK, PRI_POSTSCRIPT_NAME_WEAK, + PRI1(SYMBOL), PRI1(SPACING), + PRI1(SIZE), PRI1(PIXEL_SIZE), PRI1(STYLE), PRI1(SLANT), @@ -337,7 +377,7 @@ FcCompareValueList (FcObject object, best = 1e99; bestStrong = 1e99; bestWeak = 1e99; - j = 1; + j = 0; for (v1 = v1orig; v1; v1 = FcValueListNext(v1)) { for (v2 = v2orig, k = 0; v2; v2 = FcValueListNext(v2), k++) @@ -445,7 +485,7 @@ FcFontRenderPrepare (FcConfig *config, { FcPattern *new; int i; - FcPatternElt *fe, *pe, *fel, *pel; + FcPatternElt *fe, *pe; FcValue v; FcResult result; @@ -470,36 +510,25 @@ FcFontRenderPrepare (FcConfig *config, fe->object == FC_STYLE_OBJECT || fe->object == FC_FULLNAME_OBJECT) { + FcPatternElt *fel, *pel; + FC_ASSERT_STATIC ((FC_FAMILY_OBJECT + 1) == FC_FAMILYLANG_OBJECT); FC_ASSERT_STATIC ((FC_STYLE_OBJECT + 1) == FC_STYLELANG_OBJECT); FC_ASSERT_STATIC ((FC_FULLNAME_OBJECT + 1) == FC_FULLNAMELANG_OBJECT); fel = FcPatternObjectFindElt (font, fe->object + 1); pel = FcPatternObjectFindElt (pat, fe->object + 1); - } - else - { - fel = NULL; - pel = NULL; - } - pe = FcPatternObjectFindElt (pat, fe->object); - if (pe) - { - const FcMatcher *match = FcObjectToMatcher (pe->object, FcFalse); - if (!FcCompareValueList (pe->object, match, - FcPatternEltValues(pe), - FcPatternEltValues(fe), &v, NULL, NULL, &result)) - { - FcPatternDestroy (new); - return NULL; - } if (fel && pel) { + /* The font has name languages, and pattern asks for specific language(s). + * Match on language and and prefer that result. + * Note: Currently the code only give priority to first matching language. + */ int n = 1, j; FcValueListPtr l1, l2, ln = NULL, ll = NULL; + const FcMatcher *match = FcObjectToMatcher (pel->object, FcTrue); - match = FcObjectToMatcher (pel->object, FcTrue); if (!FcCompareValueList (pel->object, match, FcPatternEltValues (pel), FcPatternEltValues (fel), NULL, NULL, &n, &result)) @@ -542,9 +571,10 @@ FcFontRenderPrepare (FcConfig *config, } else if (fel) { + /* Pattern doesn't ask for specific language. Copy all for name and + * lang. */ FcValueListPtr l1, l2; - copy_lang: l1 = FcValueListDuplicate (FcPatternEltValues (fe)); l2 = FcValueListDuplicate (FcPatternEltValues (fel)); FcPatternObjectListAdd (new, fe->object, l1, FcFalse); @@ -552,12 +582,23 @@ FcFontRenderPrepare (FcConfig *config, continue; } + } + + pe = FcPatternObjectFindElt (pat, fe->object); + if (pe) + { + const FcMatcher *match = FcObjectToMatcher (pe->object, FcFalse); + if (!FcCompareValueList (pe->object, match, + FcPatternEltValues(pe), + FcPatternEltValues(fe), &v, NULL, NULL, &result)) + { + FcPatternDestroy (new); + return NULL; + } FcPatternObjectAdd (new, fe->object, v, FcFalse); } else { - if (fel) - goto copy_lang; FcPatternObjectListAdd (new, fe->object, FcValueListDuplicate (FcPatternEltValues (fe)), FcTrue); @@ -648,6 +689,47 @@ FcFontSetMatchInternal (FcFontSet **sets, printf ("\n"); FcPatternPrint (best); } + if (FcDebug () & FC_DBG_MATCH2) + { + char *env = getenv ("FC_DBG_MATCH_FILTER"); + FcObjectSet *os = NULL; + + if (env) + { + char *ss, *s; + char *p; + FcBool f = FcTrue; + + ss = s = strdup (env); + os = FcObjectSetCreate (); + while (f) + { + size_t len; + char *x; + + if (!(p = strchr (s, ','))) + { + f = FcFalse; + len = strlen (s) + 1; + } + else + { + len = (p - s) + 1; + } + x = malloc (sizeof (char) * len); + strncpy (x, s, len - 1); + x[len - 1] = 0; + if (FcObjectFromName (x) > 0) + FcObjectSetAdd (os, x); + s = p + 1; + free (x); + } + free (ss); + } + FcPatternPrint2 (p, best, os); + if (os) + FcObjectSetDestroy (os); + } /* assuming that 'result' is initialized with FcResultNoMatch * outside this function */ if (best) diff --git a/dist/fontconfig/src/fcname.c b/dist/fontconfig/src/fcname.c index f302948dd..8be36c70c 100644 --- a/dist/fontconfig/src/fcname.c +++ b/dist/fontconfig/src/fcname.c @@ -87,6 +87,12 @@ FcObjectValidType (FcObject object, FcType type) if (type == FcTypeLangSet || type == FcTypeString) return FcTrue; break; + case FcTypeRange: + if (type == FcTypeRange || + type == FcTypeDouble || + type == FcTypeInteger) + return FcTrue; + break; default: if (type == t->type) return FcTrue; @@ -132,6 +138,8 @@ static const FcConstant _FcBaseConstants[] = { { (FcChar8 *) "thin", "weight", FC_WEIGHT_THIN, }, { (FcChar8 *) "extralight", "weight", FC_WEIGHT_EXTRALIGHT, }, { (FcChar8 *) "ultralight", "weight", FC_WEIGHT_EXTRALIGHT, }, + { (FcChar8 *) "demilight", "weight", FC_WEIGHT_DEMILIGHT, }, + { (FcChar8 *) "semilight", "weight", FC_WEIGHT_DEMILIGHT, }, { (FcChar8 *) "light", "weight", FC_WEIGHT_LIGHT, }, { (FcChar8 *) "book", "weight", FC_WEIGHT_BOOK, }, { (FcChar8 *) "regular", "weight", FC_WEIGHT_REGULAR, }, @@ -273,6 +281,8 @@ FcNameConvert (FcType type, FcChar8 *string) { FcValue v; FcMatrix m; + double b, e; + char *p; v.type = type; switch ((int) v.type) { @@ -307,6 +317,20 @@ FcNameConvert (FcType type, FcChar8 *string) if (!v.u.l) v.type = FcTypeVoid; break; + case FcTypeRange: + if (sscanf ((char *) string, "[%lg %lg)", &b, &e) != 2) + { + v.u.d = strtod ((char *) string, &p); + if (p != NULL && p[0] != 0) + { + v.type = FcTypeVoid; + break; + } + v.type = FcTypeDouble; + } + else + v.u.r = FcRangeCreateDouble (b, e); + break; default: break; } @@ -501,6 +525,9 @@ FcNameUnparseValue (FcStrBuf *buf, return FcNameUnparseLangSet (buf, v.u.l); case FcTypeFTFace: return FcTrue; + case FcTypeRange: + sprintf ((char *) temp, "[%g %g)", v.u.r->begin, v.u.r->end); + return FcNameUnparseString (buf, temp, 0); } return FcFalse; } @@ -533,12 +560,13 @@ FcNameUnparse (FcPattern *pat) FcChar8 * FcNameUnparseEscaped (FcPattern *pat, FcBool escape) { - FcStrBuf buf; - FcChar8 buf_static[8192]; + FcStrBuf buf, buf2; + FcChar8 buf_static[8192], buf2_static[256]; int i; FcPatternElt *e; FcStrBufInit (&buf, buf_static, sizeof (buf_static)); + FcStrBufInit (&buf2, buf2_static, sizeof (buf2_static)); e = FcPatternObjectFindElt (pat, FC_FAMILY_OBJECT); if (e) { @@ -548,10 +576,17 @@ FcNameUnparseEscaped (FcPattern *pat, FcBool escape) e = FcPatternObjectFindElt (pat, FC_SIZE_OBJECT); if (e) { - if (!FcNameUnparseString (&buf, (FcChar8 *) "-", 0)) + FcChar8 *p; + + if (!FcNameUnparseString (&buf2, (FcChar8 *) "-", 0)) goto bail0; - if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? (FcChar8 *) FC_ESCAPE_FIXED : 0)) + if (!FcNameUnparseValueList (&buf2, FcPatternEltValues(e), escape ? (FcChar8 *) FC_ESCAPE_FIXED : 0)) goto bail0; + p = FcStrBufDoneStatic (&buf2); + FcStrBufDestroy (&buf2); + if (strlen ((const char *)p) > 1) + if (!FcStrBufString (&buf, p)) + goto bail0; } for (i = 0; i < NUM_OBJECT_TYPES; i++) { diff --git a/dist/fontconfig/src/fcobjs.c b/dist/fontconfig/src/fcobjs.c index bad9824d4..16ff31c47 100644 --- a/dist/fontconfig/src/fcobjs.c +++ b/dist/fontconfig/src/fcobjs.c @@ -44,6 +44,28 @@ struct FcObjectOtherTypeInfo { FcObject id; } *other_types; +void +FcObjectFini (void) +{ + struct FcObjectOtherTypeInfo *ots, *ot; + +retry: + ots = fc_atomic_ptr_get (&other_types); + if (!ots) + return; + if (!fc_atomic_ptr_cmpexch (&other_types, ots, NULL)) + goto retry; + + while (ots) + { + ot = ots->next; + if (ots->object.object) + free (ots->object.object); + free (ots); + ots = ot; + } +} + static FcObjectType * _FcObjectLookupOtherTypeByName (const char *str, FcObject *id) { @@ -62,12 +84,19 @@ retry: if (!ot) return NULL; - ot->object.object = (const char *) FcStrdup (str); + ot->object.object = (char *) FcStrdup (str); ot->object.type = FcTypeUnknown; ot->id = fc_atomic_int_add (next_id, +1); + if (ot->id < (FC_MAX_BASE_OBJECT + FC_EXT_OBJ_INDEX)) + { + fprintf (stderr, "Fontconfig error: No object ID to assign\n"); + abort (); + } ot->next = ots; if (!fc_atomic_ptr_cmpexch (&other_types, ots, ot)) { + if (ot->object.object) + free (ot->object.object); free (ot); goto retry; } diff --git a/dist/fontconfig/src/fcobjs.h b/dist/fontconfig/src/fcobjs.h index a0ee0795b..1fc4f656b 100644 --- a/dist/fontconfig/src/fcobjs.h +++ b/dist/fontconfig/src/fcobjs.h @@ -31,7 +31,7 @@ FC_OBJECT (FULLNAMELANG, FcTypeString, NULL) FC_OBJECT (SLANT, FcTypeInteger, FcCompareNumber) FC_OBJECT (WEIGHT, FcTypeInteger, FcCompareNumber) FC_OBJECT (WIDTH, FcTypeInteger, FcCompareNumber) -FC_OBJECT (SIZE, FcTypeDouble, NULL) +FC_OBJECT (SIZE, FcTypeRange, FcCompareSizeRange) FC_OBJECT (ASPECT, FcTypeDouble, NULL) FC_OBJECT (PIXEL_SIZE, FcTypeDouble, FcCompareSize) FC_OBJECT (SPACING, FcTypeInteger, FcCompareNumber) @@ -44,7 +44,7 @@ FC_OBJECT (AUTOHINT, FcTypeBool, NULL) FC_OBJECT (GLOBAL_ADVANCE, FcTypeBool, NULL) /* deprecated */ FC_OBJECT (FILE, FcTypeString, FcCompareFilename) FC_OBJECT (INDEX, FcTypeInteger, NULL) -FC_OBJECT (RASTERIZER, FcTypeString, FcCompareString) +FC_OBJECT (RASTERIZER, FcTypeString, FcCompareString) /* deprecated */ FC_OBJECT (OUTLINE, FcTypeBool, FcCompareBool) FC_OBJECT (SCALABLE, FcTypeBool, FcCompareBool) FC_OBJECT (DPI, FcTypeDouble, NULL) @@ -66,6 +66,8 @@ FC_OBJECT (LCD_FILTER, FcTypeInteger, NULL) FC_OBJECT (NAMELANG, FcTypeString, NULL) FC_OBJECT (FONT_FEATURES, FcTypeString, NULL) FC_OBJECT (PRGNAME, FcTypeString, NULL) -FC_OBJECT (HASH, FcTypeString, FcCompareHash) +FC_OBJECT (HASH, FcTypeString, NULL) /* deprecated */ FC_OBJECT (POSTSCRIPT_NAME, FcTypeString, FcComparePostScript) +FC_OBJECT (COLOR, FcTypeBool, FcCompareBool) +FC_OBJECT (SYMBOL, FcTypeBool, FcCompareBool) /* ^-------------- Add new objects here. */ diff --git a/dist/fontconfig/src/fcobjshash.gperf b/dist/fontconfig/src/fcobjshash.gperf index f6534135f..80a023756 100644 --- a/dist/fontconfig/src/fcobjshash.gperf +++ b/dist/fontconfig/src/fcobjshash.gperf @@ -61,3 +61,5 @@ int id; "prgname",FC_PRGNAME_OBJECT "hash",FC_HASH_OBJECT "postscriptname",FC_POSTSCRIPT_NAME_OBJECT +"color",FC_COLOR_OBJECT +"symbol",FC_SYMBOL_OBJECT diff --git a/dist/fontconfig/src/fcobjshash.h b/dist/fontconfig/src/fcobjshash.h deleted file mode 100644 index 414059efc..000000000 --- a/dist/fontconfig/src/fcobjshash.h +++ /dev/null @@ -1,317 +0,0 @@ -/* ANSI-C code produced by gperf version 3.0.4 */ -/* Command-line: gperf -m 100 fcobjshash.gperf */ -/* Computed positions: -k'2-3' */ - -#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ - && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ - && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ - && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ - && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ - && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ - && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ - && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ - && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ - && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ - && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ - && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ - && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ - && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ - && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ - && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ - && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ - && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ - && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ - && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ - && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ - && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ - && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) -/* The character set is not based on ISO-646. */ -#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>." -#endif - -#line 1 "fcobjshash.gperf" - -#line 13 "fcobjshash.gperf" -struct FcObjectTypeInfo { -int name; -int id; -}; -#include <string.h> -/* maximum key range = 52, duplicates = 0 */ - -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static unsigned int -FcObjectTypeHash (register const char *str, register unsigned int len) -{ - static const unsigned char asso_values[] = - { - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 17, 12, 1, - 35, 0, 56, 27, 15, 0, 56, 56, 0, 7, - 7, 0, 22, 56, 21, 10, 13, 0, 56, 56, - 0, 26, 1, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56 - }; - return len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[1]]; -} - -struct FcObjectTypeNamePool_t - { - char FcObjectTypeNamePool_str4[sizeof("file")]; - char FcObjectTypeNamePool_str5[sizeof("size")]; - char FcObjectTypeNamePool_str6[sizeof("weight")]; - char FcObjectTypeNamePool_str7[sizeof("foundry")]; - char FcObjectTypeNamePool_str8[sizeof("fullname")]; - char FcObjectTypeNamePool_str9[sizeof("pixelsize")]; - char FcObjectTypeNamePool_str11[sizeof("decorative")]; - char FcObjectTypeNamePool_str12[sizeof("fullnamelang")]; - char FcObjectTypeNamePool_str13[sizeof("globaladvance")]; - char FcObjectTypeNamePool_str14[sizeof("hinting")]; - char FcObjectTypeNamePool_str15[sizeof("minspace")]; - char FcObjectTypeNamePool_str16[sizeof("hintstyle")]; - char FcObjectTypeNamePool_str17[sizeof("fontformat")]; - char FcObjectTypeNamePool_str18[sizeof("fontversion")]; - char FcObjectTypeNamePool_str19[sizeof("fontfeatures")]; - char FcObjectTypeNamePool_str20[sizeof("outline")]; - char FcObjectTypeNamePool_str21[sizeof("autohint")]; - char FcObjectTypeNamePool_str22[sizeof("slant")]; - char FcObjectTypeNamePool_str23[sizeof("scale")]; - char FcObjectTypeNamePool_str24[sizeof("postscriptname")]; - char FcObjectTypeNamePool_str25[sizeof("dpi")]; - char FcObjectTypeNamePool_str26[sizeof("scalable")]; - char FcObjectTypeNamePool_str27[sizeof("embolden")]; - char FcObjectTypeNamePool_str28[sizeof("lang")]; - char FcObjectTypeNamePool_str29[sizeof("antialias")]; - char FcObjectTypeNamePool_str30[sizeof("family")]; - char FcObjectTypeNamePool_str31[sizeof("hash")]; - char FcObjectTypeNamePool_str32[sizeof("namelang")]; - char FcObjectTypeNamePool_str33[sizeof("embeddedbitmap")]; - char FcObjectTypeNamePool_str34[sizeof("familylang")]; - char FcObjectTypeNamePool_str35[sizeof("verticallayout")]; - char FcObjectTypeNamePool_str36[sizeof("matrix")]; - char FcObjectTypeNamePool_str37[sizeof("rasterizer")]; - char FcObjectTypeNamePool_str38[sizeof("aspect")]; - char FcObjectTypeNamePool_str39[sizeof("charset")]; - char FcObjectTypeNamePool_str40[sizeof("width")]; - char FcObjectTypeNamePool_str41[sizeof("charwidth")]; - char FcObjectTypeNamePool_str42[sizeof("charheight")]; - char FcObjectTypeNamePool_str43[sizeof("rgba")]; - char FcObjectTypeNamePool_str44[sizeof("style")]; - char FcObjectTypeNamePool_str45[sizeof("lcdfilter")]; - char FcObjectTypeNamePool_str46[sizeof("spacing")]; - char FcObjectTypeNamePool_str47[sizeof("index")]; - char FcObjectTypeNamePool_str48[sizeof("stylelang")]; - char FcObjectTypeNamePool_str49[sizeof("capability")]; - char FcObjectTypeNamePool_str55[sizeof("prgname")]; - }; -static const struct FcObjectTypeNamePool_t FcObjectTypeNamePool_contents = - { - "file", - "size", - "weight", - "foundry", - "fullname", - "pixelsize", - "decorative", - "fullnamelang", - "globaladvance", - "hinting", - "minspace", - "hintstyle", - "fontformat", - "fontversion", - "fontfeatures", - "outline", - "autohint", - "slant", - "scale", - "postscriptname", - "dpi", - "scalable", - "embolden", - "lang", - "antialias", - "family", - "hash", - "namelang", - "embeddedbitmap", - "familylang", - "verticallayout", - "matrix", - "rasterizer", - "aspect", - "charset", - "width", - "charwidth", - "charheight", - "rgba", - "style", - "lcdfilter", - "spacing", - "index", - "stylelang", - "capability", - "prgname" - }; -#define FcObjectTypeNamePool ((const char *) &FcObjectTypeNamePool_contents) -#ifdef __GNUC__ -__inline -#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__ -__attribute__ ((__gnu_inline__)) -#endif -#endif -const struct FcObjectTypeInfo * -FcObjectTypeLookup (register const char *str, register unsigned int len) -{ - enum - { - TOTAL_KEYWORDS = 46, - MIN_WORD_LENGTH = 3, - MAX_WORD_LENGTH = 14, - MIN_HASH_VALUE = 4, - MAX_HASH_VALUE = 55 - }; - - static const struct FcObjectTypeInfo wordlist[] = - { - {-1}, {-1}, {-1}, {-1}, -#line 38 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str4,FC_FILE_OBJECT}, -#line 27 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str5,FC_SIZE_OBJECT}, -#line 25 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str6,FC_WEIGHT_OBJECT}, -#line 31 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str7,FC_FOUNDRY_OBJECT}, -#line 22 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str8,FC_FULLNAME_OBJECT}, -#line 29 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str9,FC_PIXEL_SIZE_OBJECT}, - {-1}, -#line 57 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str11,FC_DECORATIVE_OBJECT}, -#line 23 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str12,FC_FULLNAMELANG_OBJECT}, -#line 37 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str13,FC_GLOBAL_ADVANCE_OBJECT}, -#line 34 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str14,FC_HINTING_OBJECT}, -#line 46 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str15,FC_MINSPACE_OBJECT}, -#line 33 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str16,FC_HINT_STYLE_OBJECT}, -#line 54 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str17,FC_FONTFORMAT_OBJECT}, -#line 52 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str18,FC_FONTVERSION_OBJECT}, -#line 60 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str19,FC_FONT_FEATURES_OBJECT}, -#line 41 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str20,FC_OUTLINE_OBJECT}, -#line 36 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str21,FC_AUTOHINT_OBJECT}, -#line 24 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str22,FC_SLANT_OBJECT}, -#line 45 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str23,FC_SCALE_OBJECT}, -#line 63 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str24,FC_POSTSCRIPT_NAME_OBJECT}, -#line 43 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str25,FC_DPI_OBJECT}, -#line 42 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str26,FC_SCALABLE_OBJECT}, -#line 55 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str27,FC_EMBOLDEN_OBJECT}, -#line 51 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str28,FC_LANG_OBJECT}, -#line 32 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str29,FC_ANTIALIAS_OBJECT}, -#line 18 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str30,FC_FAMILY_OBJECT}, -#line 62 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str31,FC_HASH_OBJECT}, -#line 59 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str32,FC_NAMELANG_OBJECT}, -#line 56 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str33,FC_EMBEDDED_BITMAP_OBJECT}, -#line 19 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str34,FC_FAMILYLANG_OBJECT}, -#line 35 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str35,FC_VERTICAL_LAYOUT_OBJECT}, -#line 49 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str36,FC_MATRIX_OBJECT}, -#line 40 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str37,FC_RASTERIZER_OBJECT}, -#line 28 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str38,FC_ASPECT_OBJECT}, -#line 50 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str39,FC_CHARSET_OBJECT}, -#line 26 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str40,FC_WIDTH_OBJECT}, -#line 47 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str41,FC_CHAR_WIDTH_OBJECT}, -#line 48 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str42,FC_CHAR_HEIGHT_OBJECT}, -#line 44 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str43,FC_RGBA_OBJECT}, -#line 20 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str44,FC_STYLE_OBJECT}, -#line 58 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str45,FC_LCD_FILTER_OBJECT}, -#line 30 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str46,FC_SPACING_OBJECT}, -#line 39 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str47,FC_INDEX_OBJECT}, -#line 21 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str48,FC_STYLELANG_OBJECT}, -#line 53 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str49,FC_CAPABILITY_OBJECT}, - {-1}, {-1}, {-1}, {-1}, {-1}, -#line 61 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str55,FC_PRGNAME_OBJECT} - }; - - if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) - { - register int key = FcObjectTypeHash (str, len); - - if (key <= MAX_HASH_VALUE && key >= 0) - { - register int o = wordlist[key].name; - if (o >= 0) - { - register const char *s = o + FcObjectTypeNamePool; - - if (*str == *s && !strcmp (str + 1, s + 1)) - return &wordlist[key]; - } - } - } - return 0; -} diff --git a/dist/fontconfig/src/fcpat.c b/dist/fontconfig/src/fcpat.c index 986cca391..3ef1ed212 100644 --- a/dist/fontconfig/src/fcpat.c +++ b/dist/fontconfig/src/fcpat.c @@ -57,6 +57,9 @@ FcValueDestroy (FcValue v) case FcTypeLangSet: FcLangSetDestroy ((FcLangSet *) v.u.l); break; + case FcTypeRange: + FcRangeDestroy ((FcRange *) v.u.r); + break; default: break; } @@ -81,6 +84,10 @@ FcValueCanonicalize (const FcValue *v) new.u.l = FcValueLangSet(v); new.type = FcTypeLangSet; break; + case FcTypeRange: + new.u.r = FcValueRange(v); + new.type = FcTypeRange; + break; default: new = *v; break; @@ -112,6 +119,11 @@ FcValueSave (FcValue v) if (!v.u.l) v.type = FcTypeVoid; break; + case FcTypeRange: + v.u.r = FcRangeCopy (v.u.r); + if (!v.u.r) + v.type = FcTypeVoid; + break; default: break; } @@ -145,6 +157,9 @@ FcValueListDestroy (FcValueListPtr l) FcLangSetDestroy ((FcLangSet *) (l->value.u.l)); break; + case FcTypeRange: + FcRangeDestroy ((FcRange *) (l->value.u.r)); + break; default: break; } @@ -267,6 +282,8 @@ FcValueEqual (FcValue va, FcValue vb) return va.u.f == vb.u.f; case FcTypeLangSet: return FcLangSetEqual (va.u.l, vb.u.l); + case FcTypeRange: + return FcRangeIsInRange (va.u.r, vb.u.r); } return FcFalse; } @@ -320,6 +337,8 @@ FcValueHash (const FcValue *v) FcStringHash ((const FcChar8 *) ((FT_Face) v->u.f)->style_name); case FcTypeLangSet: return FcLangSetHash (FcValueLangSet(v)); + case FcTypeRange: + return FcRangeHash (v->u.r); } return 0; } @@ -406,6 +425,12 @@ FcPatternObjectPosition (const FcPattern *p, FcObject object) return -(mid + 1); } +int +FcPatternPosition (const FcPattern *p, const char *object) +{ + return FcPatternObjectPosition (p, FcObjectFromName (object)); +} + FcPatternElt * FcPatternObjectFindElt (const FcPattern *p, FcObject object) { @@ -841,6 +866,22 @@ FcPatternAddLangSet (FcPattern *p, const char *object, const FcLangSet *ls) return FcPatternAdd (p, object, v, FcTrue); } +FcBool +FcPatternObjectAddRange (FcPattern *p, FcObject object, const FcRange *r) +{ + FcValue v; + + v.type = FcTypeRange; + v.u.r = (FcRange *)r; + return FcPatternObjectAdd (p, object, v, FcTrue); +} + +FcBool +FcPatternAddRange (FcPattern *p, const char *object, const FcRange *r) +{ + return FcPatternObjectAddRange (p, FcObjectFromName (object), r); +} + FcResult FcPatternObjectGet (const FcPattern *p, FcObject object, int id, FcValue *v) { @@ -1025,6 +1066,31 @@ FcPatternGetLangSet(const FcPattern *p, const char *object, int id, FcLangSet ** return FcResultMatch; } +FcResult +FcPatternObjectGetRange (const FcPattern *p, FcObject object, int id, FcRange **r) +{ + FcValue v; + FcResult res; + + res = FcPatternObjectGet (p, object, id, &v); + if (res != FcResultMatch) + return res; + switch ((int)v.type) { + case FcTypeRange: + *r = (FcRange *)v.u.r; + break; + default: + return FcResultTypeMismatch; + } + return FcResultMatch; +} + +FcResult +FcPatternGetRange (const FcPattern *p, const char *object, int id, FcRange **r) +{ + return FcPatternObjectGetRange (p, FcObjectFromName (object), id, r); +} + FcPattern * FcPatternDuplicate (const FcPattern *orig) { @@ -1230,6 +1296,10 @@ FcValueListSerializeAlloc (FcSerialize *serialize, const FcValueList *vl) if (!FcLangSetSerializeAlloc (serialize, vl->value.u.l)) return FcFalse; break; + case FcTypeRange: + if (!FcRangeSerializeAlloc (serialize, vl->value.u.r)) + return FcFalse; + break; default: break; } @@ -1245,6 +1315,7 @@ FcValueListSerialize (FcSerialize *serialize, const FcValueList *vl) FcChar8 *s_serialized; FcCharSet *c_serialized; FcLangSet *l_serialized; + FcRange *r_serialized; FcValueList *head_serialized = NULL; FcValueList *prev_serialized = NULL; @@ -1303,6 +1374,14 @@ FcValueListSerialize (FcSerialize *serialize, const FcValueList *vl) l_serialized, FcLangSet); break; + case FcTypeRange: + r_serialized = FcRangeSerialize (serialize, vl->value.u.r); + if (!r_serialized) + return NULL; + vl_serialized->value.u.r = FcPtrToEncodedOffset (&vl_serialized->value, + r_serialized, + FcRange); + break; default: break; } diff --git a/dist/fontconfig/src/fcrange.c b/dist/fontconfig/src/fcrange.c new file mode 100644 index 000000000..f70226c55 --- /dev/null +++ b/dist/fontconfig/src/fcrange.c @@ -0,0 +1,161 @@ +/* + * fontconfig/src/fcrange.c + * + * Copyright © 2002 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the author(s) not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The authors make no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include "fcint.h" + + +FcRange * +FcRangeCreateDouble (double begin, double end) +{ + FcRange *ret = malloc (sizeof (FcRange)); + + if (ret) + { + ret->begin = begin; + ret->end = end; + } + + return ret; +} + +FcRange * +FcRangeCreateInteger (FcChar32 begin, FcChar32 end) +{ + FcRange *ret = malloc (sizeof (FcRange)); + + if (ret) + { + ret->begin = begin; + ret->end = end; + } + + return ret; +} + +void +FcRangeDestroy (FcRange *range) +{ + free (range); +} + +FcRange * +FcRangeCopy (const FcRange *range) +{ + return FcRangeCreateDouble (range->begin, range->end); +} + +FcBool +FcRangeGetDouble(const FcRange *range, double *begin, double *end) +{ + if (!range) + return FcFalse; + if (begin) + *begin = range->begin; + if (end) + *end = range->end; + + return FcTrue; +} + +FcRange * +FcRangePromote (double v, FcValuePromotionBuffer *vbuf) +{ + typedef struct { + FcRange r; + } FcRangePromotionBuffer; + FcRangePromotionBuffer *buf = (FcRangePromotionBuffer *) vbuf; + + FC_ASSERT_STATIC (sizeof (FcRangePromotionBuffer) <= sizeof (FcValuePromotionBuffer)); + buf->r.begin = v; + buf->r.end = v; + + return &buf->r; +} + +FcBool +FcRangeIsInRange (const FcRange *a, const FcRange *b) +{ + if (!a || !b) + return FcFalse; + + return a->begin >= b->begin && a->end <= b->end; +} + +FcBool +FcRangeCompare (FcOp op, const FcRange *a, const FcRange *b) +{ + switch ((int) op) { + case FcOpEqual: + case FcOpContains: + case FcOpListing: + return FcRangeIsInRange (a, b); + case FcOpNotEqual: + case FcOpNotContains: + return !FcRangeIsInRange (a, b); + case FcOpLess: + return a->begin < b->begin; + case FcOpLessEqual: + return a->begin <= b->begin; + case FcOpMore: + return a->end > b->end; + case FcOpMoreEqual: + return a->end >= b->end; + default: + break; + } + return FcFalse; +} + +FcChar32 +FcRangeHash (const FcRange *r) +{ + int b = (int) (r->begin * 100); + int e = (int) (r->end * 100); + + return b ^ (b << 1) ^ (e << 9); +} + +FcBool +FcRangeSerializeAlloc (FcSerialize *serialize, const FcRange *r) +{ + if (!FcSerializeAlloc (serialize, r, sizeof (FcRange))) + return FcFalse; + return FcTrue; +} + +FcRange * +FcRangeSerialize (FcSerialize *serialize, const FcRange *r) +{ + FcRange *r_serialize = FcSerializePtr (serialize, r); + + if (!r_serialize) + return NULL; + memcpy (r_serialize, r, sizeof (FcRange)); + + return r_serialize; +} + +#define __fcrange__ +#include "fcaliastail.h" +#undef __fcrange__ diff --git a/dist/fontconfig/src/fcstat.c b/dist/fontconfig/src/fcstat.c index 0a880975a..1734fa423 100644 --- a/dist/fontconfig/src/fcstat.c +++ b/dist/fontconfig/src/fcstat.c @@ -42,6 +42,7 @@ #ifdef HAVE_SYS_MOUNT_H #include <sys/mount.h> #endif +#include <errno.h> #ifdef _WIN32 #ifdef __GNUC__ @@ -164,21 +165,86 @@ FcDirChecksumScandirFilter(const struct dirent *entry) } #endif -#ifdef HAVE_SCANDIR static int FcDirChecksumScandirSorter(const struct dirent **lhs, const struct dirent **rhs) { return strcmp((*lhs)->d_name, (*rhs)->d_name); } -#elif HAVE_SCANDIR_VOID_P -static int -FcDirChecksumScandirSorter(const void *a, const void *b) + +static void +free_dirent (struct dirent **p) { - const struct dirent *lhs = a, *rhs = b; + struct dirent **x; + + for (x = p; *x != NULL; x++) + free (*x); - return strcmp(lhs->d_name, rhs->d_name); + free (p); +} + +int +FcScandir (const char *dirp, + struct dirent ***namelist, + int (*filter) (const struct dirent *), + int (*compar) (const struct dirent **, const struct dirent **)); + +int +FcScandir (const char *dirp, + struct dirent ***namelist, + int (*filter) (const struct dirent *), + int (*compar) (const struct dirent **, const struct dirent **)) +{ + DIR *d; + struct dirent *dent, *p, **dlist, **dlp; + size_t lsize = 128, n = 0; + + d = opendir (dirp); + if (!d) + return -1; + + dlist = (struct dirent **) malloc (sizeof (struct dirent *) * lsize); + if (!dlist) + { + closedir (d); + errno = ENOMEM; + + return -1; + } + *dlist = NULL; + while ((dent = readdir (d))) + { + if (!filter || (filter) (dent)) + { + size_t dentlen = FcPtrToOffset (dent, dent->d_name) + strlen (dent->d_name) + 1; + dentlen = ((dentlen + ALIGNOF_VOID_P - 1) & ~(ALIGNOF_VOID_P - 1)); + p = (struct dirent *) malloc (dentlen); + memcpy (p, dent, dentlen); + if ((n + 1) >= lsize) + { + lsize += 128; + dlp = (struct dirent **) realloc (dlist, sizeof (struct dirent *) * lsize); + if (!dlp) + { + free_dirent (dlist); + closedir (d); + errno = ENOMEM; + + return -1; + } + dlist = dlp; + } + dlist[n++] = p; + dlist[n] = NULL; + } + } + closedir (d); + + qsort (dlist, n, sizeof (struct dirent *), (int (*) (const void *, const void *))compar); + + *namelist = dlist; + + return n; } -#endif static int FcDirChecksum (const FcChar8 *dir, time_t *checksum) @@ -191,7 +257,7 @@ FcDirChecksum (const FcChar8 *dir, time_t *checksum) Adler32Init (&ctx); - n = scandir ((const char *)dir, &files, + n = FcScandir ((const char *)dir, &files, #ifdef HAVE_STRUCT_DIRENT_D_TYPE &FcDirChecksumScandirFilter, #else @@ -360,3 +426,7 @@ FcIsFsMtimeBroken (const FcChar8 *dir) return FcFalse; } + +#define __fcstat__ +#include "fcaliastail.h" +#undef __fcstat__ diff --git a/dist/fontconfig/src/fcstdint.h b/dist/fontconfig/src/fcstdint.h deleted file mode 100644 index 2cbe49fa9..000000000 --- a/dist/fontconfig/src/fcstdint.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _FONTCONFIG_SRC_FCSTDINT_H -#define _FONTCONFIG_SRC_FCSTDINT_H 1 -#ifndef _GENERATED_STDINT_H -#define _GENERATED_STDINT_H "fontconfig 2.11.1" -/* generated using gnu compiler gcc (GCC) 4.8.2 20131212 (Red Hat 4.8.2-7) */ -#define _STDINT_HAVE_STDINT_H 1 -#include <stdint.h> -#endif -#endif diff --git a/dist/fontconfig/src/fcstr.c b/dist/fontconfig/src/fcstr.c index 024dae325..b65492d84 100644 --- a/dist/fontconfig/src/fcstr.c +++ b/dist/fontconfig/src/fcstr.c @@ -26,9 +26,6 @@ #include <stdlib.h> #include <ctype.h> #include <string.h> -#ifdef HAVE_REGEX_H -#include <regex.h> -#endif /* Objects MT-safe for readonly access. */ @@ -242,55 +239,6 @@ FcStrCmp (const FcChar8 *s1, const FcChar8 *s2) return (int) c1 - (int) c2; } -#ifdef USE_REGEX -static FcBool -_FcStrRegexCmp (const FcChar8 *s, const FcChar8 *regex, int cflags, int eflags) -{ - int ret = -1; - regex_t reg; - - if ((ret = regcomp (®, (const char *)regex, cflags)) != 0) - { - if (FcDebug () & FC_DBG_MATCHV) - { - char buf[512]; - - regerror (ret, ®, buf, 512); - printf("Regexp compile error: %s\n", buf); - } - return FcFalse; - } - ret = regexec (®, (const char *)s, 0, NULL, eflags); - if (ret != 0) - { - if (FcDebug () & FC_DBG_MATCHV) - { - char buf[512]; - - regerror (ret, ®, buf, 512); - printf("Regexp exec error: %s\n", buf); - } - } - regfree (®); - - return ret == 0 ? FcTrue : FcFalse; -} -#else -# define _FcStrRegexCmp(_s_, _regex_, _cflags_, _eflags_) (FcFalse) -#endif - -FcBool -FcStrRegexCmp (const FcChar8 *s, const FcChar8 *regex) -{ - return _FcStrRegexCmp (s, regex, REG_EXTENDED | REG_NOSUB, 0); -} - -FcBool -FcStrRegexCmpIgnoreCase (const FcChar8 *s, const FcChar8 *regex) -{ - return _FcStrRegexCmp (s, regex, REG_EXTENDED | REG_NOSUB | REG_ICASE, 0); -} - /* * Return a hash value for a string */ @@ -932,7 +880,7 @@ FcStrBuildFilename (const FcChar8 *path, if (!path) return NULL; - sset = FcStrSetCreate (); + sset = FcStrSetCreateEx (FCSS_ALLOW_DUPLICATES | FCSS_GROW_BY_64); if (!sset) return NULL; @@ -1182,6 +1130,12 @@ FcStrCanonFilename (const FcChar8 *s) FcStrSet * FcStrSetCreate (void) { + return FcStrSetCreateEx (FCSS_DEFAULT); +} + +FcStrSet * +FcStrSetCreateEx (unsigned int control) +{ FcStrSet *set = malloc (sizeof (FcStrSet)); if (!set) return 0; @@ -1189,29 +1143,42 @@ FcStrSetCreate (void) set->num = 0; set->size = 0; set->strs = 0; + set->control = control; return set; } static FcBool +_FcStrSetGrow (FcStrSet *set, int growElements) +{ + /* accommodate an additional NULL entry at the end of the array */ + FcChar8 **strs = malloc ((set->size + growElements + 1) * sizeof (FcChar8 *)); + if (!strs) + return FcFalse; + if (set->num) + memcpy (strs, set->strs, set->num * sizeof (FcChar8 *)); + if (set->strs) + free (set->strs); + set->size = set->size + growElements; + set->strs = strs; + return FcTrue; +} + +static FcBool _FcStrSetAppend (FcStrSet *set, FcChar8 *s) { - if (FcStrSetMember (set, s)) + if (!FcStrSetHasControlBit (set, FCSS_ALLOW_DUPLICATES)) { - FcStrFree (s); - return FcTrue; + if (FcStrSetMember (set, s)) + { + FcStrFree (s); + return FcTrue; + } } if (set->num == set->size) { - FcChar8 **strs = malloc ((set->size + 2) * sizeof (FcChar8 *)); - - if (!strs) - return FcFalse; - if (set->num) - memcpy (strs, set->strs, set->num * sizeof (FcChar8 *)); - if (set->strs) - free (set->strs); - set->size = set->size + 1; - set->strs = strs; + int growElements = FcStrSetHasControlBit (set, FCSS_GROW_BY_64) ? 64 : 1; + if (!_FcStrSetGrow(set, growElements)) + return FcFalse; } set->strs[set->num++] = s; set->strs[set->num] = 0; diff --git a/dist/fontconfig/src/fcweight.c b/dist/fontconfig/src/fcweight.c new file mode 100644 index 000000000..036a518e8 --- /dev/null +++ b/dist/fontconfig/src/fcweight.c @@ -0,0 +1,109 @@ +/* + * fontconfig/src/fcweight.c + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the author(s) not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The authors make no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include "fcint.h" + +static const struct { + int ot; + int fc; +} map[] = { + { 0, FC_WEIGHT_THIN }, + { 100, FC_WEIGHT_THIN }, + { 200, FC_WEIGHT_EXTRALIGHT }, + { 350, FC_WEIGHT_DEMILIGHT }, + { 300, FC_WEIGHT_LIGHT }, + { 380, FC_WEIGHT_BOOK }, + { 400, FC_WEIGHT_REGULAR }, + { 500, FC_WEIGHT_MEDIUM }, + { 600, FC_WEIGHT_DEMIBOLD }, + { 700, FC_WEIGHT_BOLD }, + { 800, FC_WEIGHT_EXTRABOLD }, + { 900, FC_WEIGHT_BLACK }, + {1000, FC_WEIGHT_EXTRABLACK }, +}; + +static int lerp(int x, int x1, int x2, int y1, int y2) +{ + int dx = x2 - x1; + int dy = y2 - y1; + assert (dx > 0 && dy >= 0 && x1 <= x && x <= x2); + return y1 + (dy*(x-x1) + dx/2) / dx; +} + +int +FcWeightFromOpenType (int ot_weight) +{ + int i; + + /* Loosely based on WPF Font Selection Model's advice. */ + + if (ot_weight < 0) + return -1; + else if (1 <= ot_weight && ot_weight <= 9) + { + /* WPF Font Selection Model says do "ot_weight *= 100", + * but Greg Hitchcock revealed that GDI had a mapping + * reflected below: */ + switch (ot_weight) { + case 1: ot_weight = 80; break; + case 2: ot_weight = 160; break; + case 3: ot_weight = 240; break; + case 4: ot_weight = 320; break; + case 5: ot_weight = 400; break; + case 6: ot_weight = 550; break; + case 7: ot_weight = 700; break; + case 8: ot_weight = 800; break; + case 9: ot_weight = 900; break; + } + } + ot_weight = FC_MIN (ot_weight, map[(sizeof (map) / sizeof (map[0])) - 1].ot); + + for (i = 1; ot_weight > map[i].ot; i++) + ; + + if (ot_weight == map[i].ot) + return map[i].fc; + + /* Interpolate between two items. */ + return lerp (ot_weight, map[i-1].ot, map[i].ot, map[i-1].fc, map[i].fc); +} + +int +FcWeightToOpenType (int fc_weight) +{ + int i; + if (fc_weight < 0 || fc_weight > FC_WEIGHT_EXTRABLACK) + return -1; + + for (i = 1; fc_weight > map[i].fc; i++) + ; + + if (fc_weight == map[i].fc) + return map[i].ot; + + /* Interpolate between two items. */ + return lerp (fc_weight, map[i-1].fc, map[i].fc, map[i-1].ot, map[i].ot); +} + +#define __fcweight__ +#include "fcaliastail.h" +#undef __fcweight__ diff --git a/dist/fontconfig/src/fcwindows.h b/dist/fontconfig/src/fcwindows.h index 02489d9dc..a0eee675e 100644 --- a/dist/fontconfig/src/fcwindows.h +++ b/dist/fontconfig/src/fcwindows.h @@ -32,8 +32,13 @@ #endif #ifdef _WIN32 + /* Request Windows Vista for building. This is required to + * get MemoryBarrier on mingw32... */ +# if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0600 +# undef _WIN32_WINNT +# endif # ifndef _WIN32_WINNT -# define _WIN32_WINNT 0x0500 +# define _WIN32_WINNT 0x0600 # endif # define WIN32_LEAN_AND_MEAN # define WIN32_EXTRA_LEAN diff --git a/dist/fontconfig/src/fcxml.c b/dist/fontconfig/src/fcxml.c index 91d166f38..031a7da1f 100644 --- a/dist/fontconfig/src/fcxml.c +++ b/dist/fontconfig/src/fcxml.c @@ -54,8 +54,12 @@ #ifdef _WIN32 #include <mbstring.h> +extern FcChar8 fontconfig_instprefix[]; #endif +static FcChar8 *__fc_userdir = NULL; +static FcChar8 *__fc_userconf = NULL; + static void FcExprDestroy (FcExpr *e); @@ -78,6 +82,7 @@ FcRuleDestroy (FcRule *rule) case FcRuleEdit: FcEditDestroy (rule->u.edit); break; + case FcRuleUnknown: default: break; } @@ -169,6 +174,18 @@ FcExprCreateMatrix (FcConfig *config, const FcExprMatrix *matrix) } static FcExpr * +FcExprCreateRange (FcConfig *config, FcRange *range) +{ + FcExpr *e = FcConfigAllocExpr (config); + if (e) + { + e->op = FcOpRange; + e->u.rval = FcRangeCopy (range); + } + return e; +} + +static FcExpr * FcExprCreateBool (FcConfig *config, FcBool b) { FcExpr *e = FcConfigAllocExpr (config); @@ -258,6 +275,7 @@ FcExprDestroy (FcExpr *e) FcExprMatrixFree (e->u.mexpr); break; case FcOpRange: + FcRangeDestroy (e->u.rval); break; case FcOpCharSet: FcCharSetDestroy (e->u.cval); @@ -503,7 +521,7 @@ typedef struct _FcVStack { int integer; double _double; FcExprMatrix *matrix; - FcRange range; + FcRange *range; FcBool bool_; FcCharSet *charset; FcLangSet *langset; @@ -593,6 +611,9 @@ FcTypeName (FcType type) return "FT_Face"; case FcTypeLangSet: return "langset"; + case FcTypeRange: + return "range"; + case FcTypeUnknown: default: return "unknown"; } @@ -608,7 +629,9 @@ FcTypecheckValue (FcConfigParse *parse, FcType value, FcType type) if (value != type) { if ((value == FcTypeLangSet && type == FcTypeString) || - (value == FcTypeString && type == FcTypeLangSet)) + (value == FcTypeString && type == FcTypeLangSet) || + (value == FcTypeInteger && type == FcTypeRange) || + (value == FcTypeDouble && type == FcTypeRange)) return; if (type == FcTypeUnknown) return; @@ -651,6 +674,9 @@ FcTypecheckExpr (FcConfigParse *parse, FcExpr *expr, FcType type) case FcOpLangSet: FcTypecheckValue (parse, FcTypeLangSet, type); break; + case FcOpRange: + FcTypecheckValue (parse, FcTypeRange, type); + break; case FcOpNil: break; case FcOpField: @@ -785,6 +811,7 @@ FcRuleCreate (FcRuleType type, case FcRuleEdit: r->u.edit = (FcEdit *) p; break; + case FcRuleUnknown: default: free (r); r = NULL; @@ -865,11 +892,10 @@ FcVStackPushMatrix (FcConfigParse *parse, FcExprMatrix *matrix) static FcBool FcVStackPushRange (FcConfigParse *parse, FcRange *range) { - FcVStack *vstack = FcVStackCreateAndPush (parse); + FcVStack *vstack = FcVStackCreateAndPush (parse); if (!vstack) return FcFalse; - vstack->u.range.begin = range->begin; - vstack->u.range.end = range->end; + vstack->u.range = range; vstack->tag = FcVStackRange; return FcTrue; } @@ -1017,9 +1043,11 @@ FcVStackPopAndDestroy (FcConfigParse *parse) case FcVStackMatrix: FcExprMatrixFreeShallow (vstack->u.matrix); break; - case FcVStackRange: case FcVStackBool: break; + case FcVStackRange: + FcRangeDestroy (vstack->u.range); + break; case FcVStackCharSet: FcCharSetDestroy (vstack->u.charset); break; @@ -1232,7 +1260,11 @@ static void FcParseBlank (FcConfigParse *parse) { int n = FcVStackElements (parse); - FcChar32 i; +#if 0 + FcChar32 i, begin, end; +#endif + + FcConfigMessage (parse, FcSevereWarning, "blank doesn't take any effect anymore. please remove it from your fonts.conf"); while (n-- > 0) { FcVStack *v = FcVStackFetch (parse, n); @@ -1244,18 +1276,24 @@ FcParseBlank (FcConfigParse *parse) } switch ((int) v->tag) { case FcVStackInteger: +#if 0 if (!FcBlanksAdd (parse->config->blanks, v->u.integer)) goto bail; break; +#endif case FcVStackRange: - if (v->u.range.begin <= v->u.range.end) +#if 0 + begin = (FcChar32) v->u.range->begin; + end = (FcChar32) v->u.range->end; + if (begin <= end) { - for (i = v->u.range.begin; i <= v->u.range.end; i++) + for (i = begin; i <= end; i++) { if (!FcBlanksAdd (parse->config->blanks, i)) goto bail; } } +#endif break; default: FcConfigMessage (parse, FcSevereError, "invalid element in blank"); @@ -1314,7 +1352,11 @@ FcParseInt (FcConfigParse *parse) static double FcStrtod (char *s, char **end) { +#ifndef __BIONIC__ struct lconv *locale_data; +#endif + const char *decimal_point; + int dlen; char *dot; double v; @@ -1322,14 +1364,21 @@ FcStrtod (char *s, char **end) * Have to swap the decimal point to match the current locale * if that locale doesn't use 0x2e */ +#ifndef __BIONIC__ + locale_data = localeconv (); + decimal_point = locale_data->decimal_point; + dlen = strlen (decimal_point); +#else + decimal_point = "."; + dlen = 1; +#endif + if ((dot = strchr (s, 0x2e)) && - (locale_data = localeconv ()) && - (locale_data->decimal_point[0] != 0x2e || - locale_data->decimal_point[1] != 0)) + (decimal_point[0] != 0x2e || + decimal_point[1] != 0)) { char buf[128]; int slen = strlen (s); - int dlen = strlen (locale_data->decimal_point); if (slen + dlen > (int) sizeof (buf)) { @@ -1343,7 +1392,7 @@ FcStrtod (char *s, char **end) /* mantissa */ strncpy (buf, s, dot - s); /* decimal point */ - strcpy (buf + (dot - s), locale_data->decimal_point); + strcpy (buf + (dot - s), decimal_point); /* rest of number */ strcpy (buf + (dot - s) + dlen, dot + 1); buf_end = 0; @@ -1463,9 +1512,11 @@ static void FcParseRange (FcConfigParse *parse) { FcVStack *vstack; - FcRange r = {0, 0}; - FcChar32 n; + FcRange *r; + FcChar32 n[2] = {0, 0}; int count = 1; + double d[2] = {0.0L, 0.0L}; + FcBool dflag = FcFalse; while ((vstack = FcVStackPeek (parse))) { @@ -1476,31 +1527,52 @@ FcParseRange (FcConfigParse *parse) } switch ((int) vstack->tag) { case FcVStackInteger: - n = vstack->u.integer; + if (dflag) + d[count] = (double)vstack->u.integer; + else + n[count] = vstack->u.integer; + break; + case FcVStackDouble: + if (count == 0 && !dflag) + d[1] = (double)n[1]; + d[count] = vstack->u._double; + dflag = FcTrue; break; default: FcConfigMessage (parse, FcSevereError, "invalid element in range"); - n = 0; + if (dflag) + d[count] = 0.0L; + else + n[count] = 0; break; } - if (count == 1) - r.end = n; - else - r.begin = n; count--; FcVStackPopAndDestroy (parse); } - if (count < 0) + if (count >= 0) { - if (r.begin > r.end) + FcConfigMessage (parse, FcSevereError, "invalid range"); + return; + } + if (dflag) + { + if (d[0] > d[1]) { FcConfigMessage (parse, FcSevereError, "invalid range"); return; } - FcVStackPushRange (parse, &r); + r = FcRangeCreateDouble (d[0], d[1]); } else - FcConfigMessage (parse, FcSevereError, "invalid range"); + { + if (n[0] > n[1]) + { + FcConfigMessage (parse, FcSevereError, "invalid range"); + return; + } + r = FcRangeCreateInteger (n[0], n[1]); + } + FcVStackPushRange (parse, r); } static FcBool @@ -1536,7 +1608,7 @@ FcParseCharSet (FcConfigParse *parse) { FcVStack *vstack; FcCharSet *charset = FcCharSetCreate (); - FcChar32 i; + FcChar32 i, begin, end; int n = 0; while ((vstack = FcVStackPeek (parse))) @@ -1551,9 +1623,12 @@ FcParseCharSet (FcConfigParse *parse) n++; break; case FcVStackRange: - if (vstack->u.range.begin <= vstack->u.range.end) + begin = (FcChar32) vstack->u.range->begin; + end = (FcChar32) vstack->u.range->end; + + if (begin <= end) { - for (i = vstack->u.range.begin; i <= vstack->u.range.end; i++) + for (i = begin; i <= end; i++) { if (!FcCharSetAddChar (charset, i)) { @@ -1888,6 +1963,7 @@ FcPopExpr (FcConfigParse *parse) expr = FcExprCreateMatrix (parse->config, vstack->u.matrix); break; case FcVStackRange: + expr = FcExprCreateRange (parse->config, vstack->u.range); break; case FcVStackBool: expr = FcExprCreateBool (parse->config, vstack->u.bool_); @@ -1996,7 +2072,14 @@ FcParseDir (FcConfigParse *parse) attr = FcConfigGetAttribute (parse, "prefix"); if (attr && FcStrCmp (attr, (const FcChar8 *)"xdg") == 0) + { prefix = FcConfigXdgDataHome (); + /* home directory might be disabled. + * simply ignore this element. + */ + if (!prefix) + goto bail; + } data = FcStrBufDoneStatic (&parse->pstack->str); if (!data) { @@ -2087,11 +2170,18 @@ static void FcParseCacheDir (FcConfigParse *parse) { const FcChar8 *attr; - FcChar8 *prefix = NULL, *p, *data; + FcChar8 *prefix = NULL, *p, *data = NULL; attr = FcConfigGetAttribute (parse, "prefix"); if (attr && FcStrCmp (attr, (const FcChar8 *)"xdg") == 0) + { prefix = FcConfigXdgCacheHome (); + /* home directory might be disabled. + * simply ignore this element. + */ + if (!prefix) + goto bail; + } data = FcStrBufDone (&parse->pstack->str); if (!data) { @@ -2118,7 +2208,25 @@ FcParseCacheDir (FcConfigParse *parse) data = prefix; } #ifdef _WIN32 - if (strcmp ((const char *) data, "WINDOWSTEMPDIR_FONTCONFIG_CACHE") == 0) + else if (data[0] == '/' && fontconfig_instprefix[0] != '\0') + { + size_t plen = strlen ((const char *)fontconfig_instprefix); + size_t dlen = strlen ((const char *)data); + + prefix = malloc (plen + 1 + dlen + 1); + if (!prefix) + { + FcConfigMessage (parse, FcSevereError, "out of memory"); + goto bail; + } + strcpy ((char *) prefix, (char *) fontconfig_instprefix); + prefix[plen] = FC_DIR_SEPARATOR; + memcpy (&prefix[plen + 1], data, dlen); + prefix[plen + 1 + dlen] = 0; + FcStrFree (data); + data = prefix; + } + else if (strcmp ((const char *) data, "WINDOWSTEMPDIR_FONTCONFIG_CACHE") == 0) { int rc; FcStrFree (data); @@ -2174,16 +2282,35 @@ FcParseCacheDir (FcConfigParse *parse) FcStrFree (data); } +void +FcConfigPathFini (void) +{ + FcChar8 *s; + +retry_dir: + s = fc_atomic_ptr_get (&__fc_userdir); + if (!fc_atomic_ptr_cmpexch (&__fc_userdir, s, NULL)) + goto retry_dir; + free (s); + +retry_conf: + s = fc_atomic_ptr_get (&__fc_userconf); + if (!fc_atomic_ptr_cmpexch (&__fc_userconf, s, NULL)) + goto retry_conf; + free (s); +} + static void FcParseInclude (FcConfigParse *parse) { FcChar8 *s; const FcChar8 *attr; FcBool ignore_missing = FcFalse; +#ifndef _WIN32 FcBool deprecated = FcFalse; +#endif FcChar8 *prefix = NULL, *p; - static FcChar8 *userdir = NULL; - static FcChar8 *userconf = NULL; + FcChar8 *userdir = NULL, *userconf = NULL; s = FcStrBufDoneStatic (&parse->pstack->str); if (!s) @@ -2195,15 +2322,25 @@ FcParseInclude (FcConfigParse *parse) if (attr && FcConfigLexBool (parse, (FcChar8 *) attr) == FcTrue) ignore_missing = FcTrue; attr = FcConfigGetAttribute (parse, "deprecated"); +#ifndef _WIN32 if (attr && FcConfigLexBool (parse, (FcChar8 *) attr) == FcTrue) deprecated = FcTrue; +#endif attr = FcConfigGetAttribute (parse, "prefix"); if (attr && FcStrCmp (attr, (const FcChar8 *)"xdg") == 0) + { prefix = FcConfigXdgConfigHome (); + /* home directory might be disabled. + * simply ignore this element. + */ + if (!prefix) + goto bail; + } if (prefix) { size_t plen = strlen ((const char *)prefix); size_t dlen = strlen ((const char *)s); + FcChar8 *u; p = realloc (prefix, plen + 1 + dlen + 1); if (!p) @@ -2219,14 +2356,32 @@ FcParseInclude (FcConfigParse *parse) if (FcFileIsDir (s)) { userdir: + userdir = fc_atomic_ptr_get (&__fc_userdir); if (!userdir) - userdir = FcStrdup (s); + { + u = FcStrdup (s); + if (!fc_atomic_ptr_cmpexch (&__fc_userdir, userdir, u)) + { + free (u); + goto userdir; + } + userdir = u; + } } else if (FcFileIsFile (s)) { userconf: + userconf = fc_atomic_ptr_get (&__fc_userconf); if (!userconf) - userconf = FcStrdup (s); + { + u = FcStrdup (s); + if (!fc_atomic_ptr_cmpexch (&__fc_userconf, userconf, u)) + { + free (u); + goto userconf; + } + userconf = u; + } } else { @@ -2250,6 +2405,7 @@ FcParseInclude (FcConfigParse *parse) filename = FcConfigFilename(s); if (deprecated == FcTrue && filename != NULL && + userdir != NULL && !FcFileIsLink (filename)) { if (FcFileIsDir (filename)) @@ -2653,6 +2809,11 @@ FcPopValue (FcConfigParse *parse) if (value.u.l) value.type = FcTypeLangSet; break; + case FcVStackRange: + value.u.r = FcRangeCopy (vstack->u.range); + if (value.u.r) + value.type = FcTypeRange; + break; default: FcConfigMessage (parse, FcSevereWarning, "unknown pattern element %d", vstack->tag); @@ -3008,7 +3169,7 @@ FcConfigParseAndLoadDir (FcConfig *config, strcat ((char *) file, "/"); base = file + strlen ((char *) file); - files = FcStrSetCreate (); + files = FcStrSetCreateEx (FCSS_GROW_BY_64); if (!files) { ret = FcFalse; @@ -3069,11 +3230,12 @@ FcConfigParseAndLoad (FcConfig *config, { XML_Parser p; - FcChar8 *filename; + FcChar8 *filename, *f; int fd; int len; FcConfigParse parse; FcBool error = FcTrue; + const FcChar8 *sysroot = FcConfigGetSysRoot (config); #ifdef ENABLE_LIBXML2 xmlSAXHandler sax; @@ -3098,9 +3260,14 @@ FcConfigParseAndLoad (FcConfig *config, } #endif - filename = FcConfigFilename (name); - if (!filename) + f = FcConfigFilename (name); + if (!f) goto bail0; + if (sysroot) + filename = FcStrBuildFilename (sysroot, f, NULL); + else + filename = FcStrdup (f); + FcStrFree (f); if (FcStrSetMember (config->configFiles, filename)) { |