summaryrefslogtreecommitdiff
path: root/dist/fontconfig/src
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@cvs.openbsd.org>2016-08-09 18:57:46 +0000
committerMatthieu Herrb <matthieu@cvs.openbsd.org>2016-08-09 18:57:46 +0000
commit1ddbe601f7002743a659e4cde7607b070461b8c3 (patch)
tree39607e584b65014357f55f57587cf4065767250d /dist/fontconfig/src
parent63b9c1ad3c9c5032399263622895776547eec2d5 (diff)
Update to fontconfig 2.12.1.
Tested by krw@, dcoppa@, ok dcoppa@.
Diffstat (limited to 'dist/fontconfig/src')
-rw-r--r--dist/fontconfig/src/Makefile.am3
-rw-r--r--dist/fontconfig/src/Makefile.in215
-rw-r--r--dist/fontconfig/src/fcarch.c5
-rw-r--r--dist/fontconfig/src/fcatomic.c2
-rw-r--r--dist/fontconfig/src/fcatomic.h18
-rw-r--r--dist/fontconfig/src/fcblanks.c27
-rw-r--r--dist/fontconfig/src/fccache.c259
-rw-r--r--dist/fontconfig/src/fccfg.c128
-rw-r--r--dist/fontconfig/src/fccharset.c262
-rw-r--r--dist/fontconfig/src/fccompat.c4
-rw-r--r--dist/fontconfig/src/fcdbg.c85
-rw-r--r--dist/fontconfig/src/fcdefault.c49
-rw-r--r--dist/fontconfig/src/fcdir.c131
-rw-r--r--dist/fontconfig/src/fcfreetype.c875
-rw-r--r--dist/fontconfig/src/fchash.c317
-rw-r--r--dist/fontconfig/src/fcinit.c56
-rw-r--r--dist/fontconfig/src/fcint.h118
-rw-r--r--dist/fontconfig/src/fclang.c27
-rw-r--r--dist/fontconfig/src/fclist.c4
-rw-r--r--dist/fontconfig/src/fcmatch.c150
-rw-r--r--dist/fontconfig/src/fcname.c43
-rw-r--r--dist/fontconfig/src/fcobjs.c31
-rw-r--r--dist/fontconfig/src/fcobjs.h8
-rw-r--r--dist/fontconfig/src/fcobjshash.gperf2
-rw-r--r--dist/fontconfig/src/fcobjshash.h317
-rw-r--r--dist/fontconfig/src/fcpat.c79
-rw-r--r--dist/fontconfig/src/fcrange.c161
-rw-r--r--dist/fontconfig/src/fcstat.c86
-rw-r--r--dist/fontconfig/src/fcstdint.h9
-rw-r--r--dist/fontconfig/src/fcstr.c99
-rw-r--r--dist/fontconfig/src/fcweight.c109
-rw-r--r--dist/fontconfig/src/fcwindows.h7
-rw-r--r--dist/fontconfig/src/fcxml.c245
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 (&reg, (const char *)regex, cflags)) != 0)
- {
- if (FcDebug () & FC_DBG_MATCHV)
- {
- char buf[512];
-
- regerror (ret, &reg, buf, 512);
- printf("Regexp compile error: %s\n", buf);
- }
- return FcFalse;
- }
- ret = regexec (&reg, (const char *)s, 0, NULL, eflags);
- if (ret != 0)
- {
- if (FcDebug () & FC_DBG_MATCHV)
- {
- char buf[512];
-
- regerror (ret, &reg, buf, 512);
- printf("Regexp exec error: %s\n", buf);
- }
- }
- regfree (&reg);
-
- 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))
{