Merge branch 'faster'

Results in 5x to 10x speedup in scanning.

Fixes https://bugs.freedesktop.org/show_bug.cgi?id=64766
This commit is contained in:
Behdad Esfahbod 2017-09-12 17:10:03 -04:00
commit c524522bb4
23 changed files with 182 additions and 1588 deletions

View File

@ -21,7 +21,7 @@
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
SUBDIRS=fontconfig fc-blanks fc-case fc-lang fc-glyphname src \
SUBDIRS=fontconfig fc-case fc-lang src \
fc-cache fc-cat fc-list fc-match fc-pattern fc-query fc-scan \
fc-validate conf.d test
if ENABLE_DOCS

View File

@ -760,8 +760,6 @@ AC_CONFIG_FILES([
Makefile
fontconfig/Makefile
fc-lang/Makefile
fc-glyphname/Makefile
fc-blanks/Makefile
fc-case/Makefile
src/Makefile
conf.d/Makefile

View File

@ -26,7 +26,8 @@
@TYPE1@ void
@PURPOSE@ Create an FcBlanks
@DESC@
Creates an empty FcBlanks object.
FcBlanks is deprecated.
This function always returns NULL.
@@
@RET@ void
@ -34,7 +35,8 @@ Creates an empty FcBlanks object.
@TYPE1@ FcBlanks * @ARG1@ b
@PURPOSE@ Destroy and FcBlanks
@DESC@
Destroys an FcBlanks object, freeing any associated memory.
FcBlanks is deprecated.
This function does nothing.
@@
@RET@ FcBool
@ -43,8 +45,8 @@ Destroys an FcBlanks object, freeing any associated memory.
@TYPE2@ FcChar32% @ARG2@ ucs4
@PURPOSE@ Add a character to an FcBlanks
@DESC@
Adds a single character to an FcBlanks object, returning FcFalse
if this process ran out of memory.
FcBlanks is deprecated.
This function always returns FALSE.
@@
@RET@ FcBool
@ -53,6 +55,6 @@ if this process ran out of memory.
@TYPE2@ FcChar32% @ARG2@ ucs4
@PURPOSE@ Query membership in an FcBlanks
@DESC@
Returns whether the specified FcBlanks object contains the indicated Unicode
value.
FcBlanks is deprecated.
This function always returns FALSE.
@@

View File

@ -181,11 +181,8 @@ If <parameter>config</parameter> is NULL, the current configuration is used.
@TYPE1@ FcConfig * @ARG1@ config
@PURPOSE@ Get config blanks
@DESC@
Returns the FcBlanks object associated with the given configuration, if no
blanks were present in the configuration, this function will return 0.
The returned FcBlanks object if not NULL, is valid as long as the owning
FcConfig is alive.
If <parameter>config</parameter> is NULL, the current configuration is used.
FcBlanks is deprecated.
This function always returns NULL.
@@
@RET@ int

View File

@ -47,10 +47,9 @@ higher level functions.
@TYPE2@ FcBlanks * @ARG2@ blanks
@PURPOSE@ compute Unicode coverage
@DESC@
Scans a FreeType face and returns the set of encoded Unicode chars. This scans
several encoding tables to build as complete a list as possible.
If 'blanks' is not 0, the glyphs in the font are examined and any blank glyphs
not in 'blanks' are not placed in the returned FcCharSet.
Scans a FreeType face and returns the set of encoded Unicode chars.
FcBlanks is deprecated, <parameter>blanks</parameter> is ignored and
accepted only for compatibility with older code.
@@
@SYNOPSIS@
@ -64,10 +63,8 @@ not in 'blanks' are not placed in the returned FcCharSet.
@PURPOSE@ compute Unicode coverage and spacing type
@DESC@
Scans a FreeType face and returns the set of encoded Unicode chars.
This scans
several encoding tables to build as complete a list as possible.
If 'blanks' is not 0, the glyphs in the font are examined and any blank glyphs
not in 'blanks' are not placed in the returned FcCharSet.
FcBlanks is deprecated, <parameter>blanks</parameter> is ignored and
accepted only for compatibility with older code.
<parameter>spacing</parameter> receives the computed spacing type of the
font, one of FC_MONO for a font where all glyphs have the same width,
FC_DUAL, where the font has glyphs in precisely two widths, one twice as
@ -88,6 +85,8 @@ widths.
@DESC@
Constructs a pattern representing the 'id'th font in 'file'. The number
of fonts in 'file' is returned in 'count'.
FcBlanks is deprecated, <parameter>blanks</parameter> is ignored and
accepted only for compatibility with older code.
@@
@SYNOPSIS@
@ -103,4 +102,6 @@ of fonts in 'file' is returned in 'count'.
@DESC@
Constructs a pattern representing 'face'. 'file' and 'id' are used solely as
data for pattern elements (FC_FILE, FC_INDEX and sometimes FC_FAMILY).
FcBlanks is deprecated, <parameter>blanks</parameter> is ignored and
accepted only for compatibility with older code.
@@

View File

@ -380,6 +380,11 @@ holds a list of Unicode chars which are expected to be blank; unexpectedly
blank chars are assumed to be invalid and are elided from the charset
associated with the font.
</para>
<para>
FcBlanks is deprecated and should not be used in newly written code.
It is still accepted by some functions for compatibility with
older code but will be removed in the future.
</para>
</sect2>
<sect2><title>FcFileCache</title>
<para>
@ -558,6 +563,11 @@ empty and not in this list will be assumed to be broken and not placed in
the FcCharSet associated with the font. This provides a significantly more
accurate CharSet for applications.
</para>
<para>
FcBlanks is deprecated and should not be used in newly written code.
It is still accepted by some functions for compatibility with
older code but will be removed in the future.
</para>
&fcblanks;
</sect2>
<sect2><title>FcAtomic</title>

View File

@ -1,46 +0,0 @@
# -*- encoding: utf-8 -*-
#
# Copyright © 2003 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.
NULL =
BLANKSPY = fc-blanks.py
BLANKS_H = fcblanks.h
TMPL = fcblanks.tmpl.h
noinst_SCRIPTS = $(BLANKSPY)
noinst_HEADERS = $(BLANKS_H)
$(BLANKS_H): $(TMPL) $(BLANKSPY)
if HAVE_PYTHON
$(AM_V_GEN) $(PYTHON) $(srcdir)/$(BLANKSPY) < $< > $(BLANKS_H).tmp && \
mv $(BLANKS_H).tmp $(BLANKS_H) || ($(RM) $(BLANKS_H).tmp && false)
else
@echo "No python installed. please install python to build $(BLANKS_H)."
@false
endif
EXTRA_DIST = \
$(BLANKSPY) \
$(BLANKS_H) \
$(TMPL) \
$(NULL)
DISTCLEANFILES = $(BLANKS_H)
-include $(top_srcdir)/git.mk

View File

@ -1,160 +0,0 @@
#! /usr/bin/python
from __future__ import absolute_import
from __future__ import print_function
try:
from urllib2 import urlopen
from urllib2 import URLError
except ImportError:
from urllib.request import urlopen
from urllib.error import URLError
import sys
import os
from lxml import html
from six.moves import range
datafile = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'list-unicodeset.html')
try:
fp = urlopen('http://unicode.org/cldr/utility/list-unicodeset.jsp?a=[%3AGC%3DZs%3A][%3ADI%3A]&abb=on&ucd=on&esc=on&g')
data = fp.read()
fp.close()
# check before writing if data isn't corrupted.
dom = html.fromstring(data)
x = dom.xpath('/html/body/form/p/text()')
p = x[1]
fp = open(datafile, 'wb');
fp.write(data);
fp.close();
except (URLError, IndexError):
# fall back reading the static data in repo
try:
fp = open(datafile)
data = fp.read()
fp.close()
except IOError:
sys.stderr.write("Error: No static data to generate the blank data. please make sure the network connection is reachable to Unicode.org\n")
sys.exit(1)
dom = html.fromstring(data)
x = dom.xpath('/html/body/form/p/text()')
p = x[1]
if p[0] == '[' and p[-1] == ']':
p = p.replace('[', '').replace(']', '')
else:
sys.exit(1)
fescape = False
funicode = False
frange = False
fprocess = False
v = 0
vbegin = 0
vend = 0
n = 0
l = []
def insert(db, begin, end):
db.append([begin, end])
for i in p:
if i == '\\':
if n > 0:
if frange == True and funicode == True:
vend = v
insert(l, vbegin, vend)
fprocess = True
elif funicode == True:
vbegin = v
vend = v
insert(l, vbegin, vend)
fprocess = True
funicode = False
fescape = True
elif i.lower() == 'u' and fescape == True:
funicode = True
fescape = False
elif i >= '0' and i <= '9' or i.lower() >= 'a' and i.lower() <= 'f':
if fescape == True:
raise RuntimeError("Unexpected escape code")
if funicode == True:
v <<= 4
v += int(i, 16)
else:
raise RuntimeError("Unable to parse Unicode")
elif i == ' ':
if fescape == True:
funicode = True
fescape = False
v = 0x20
if frange == True and funicode == True:
vend = v
insert(l, vbegin, vend)
fprocess = True
elif funicode == True:
vbegin = v
vend = v
insert(l, vbegin, vend)
fprocess = True
funicode = False
frange = False
elif i == '-':
if fescape == True:
raise RuntimeError("Unexpected escape code")
vbegin = v
v = 0
funicode = False
frange = True
else:
raise RuntimeError("Unable to parse Unicode: %s" % i)
if fprocess == True:
vbegin = 0
vend = 0
v = 0
fprocess = False
funicode = False
frange = False
n += 1
if frange == True and funicode == True:
vend = v
insert(l, vbegin, vend)
elif funicode == True:
vbegin = vend = v
insert(l, vbegin, vend)
ncode = 0
for i in l:
ncode += (i[1] - i[0] + 1)
a = int(x[0].split(' ')[0].replace(',', ''))
if a != ncode:
sys.stderr.write("Unexpected the amount of code points: %d (expected %d)\n" % (ncode, a))
sys.exit(1)
# exception; BRAILLE PATTERN BLANK
insert(l, 0x2800, 0x2800)
while True:
s = sys.stdin.readline().rstrip()
if s == "@@@":
break
print(s)
print("static FcChar32 _fcBlanks[%s] = {" % (ncode + 1))
k = 0
for i in sorted(l, key=lambda a: a[0]):
for j in range(i[0], i[1] + 1):
if k != 0:
print(",")
print(" 0x%04x" % j, end=' ')
k += 1
print("};")
print('''
static FcBlanks fcBlanks = {
%s,
-1,
_fcBlanks
};
''' % (ncode + 1))

View File

@ -1,25 +0,0 @@
/*
* fontconfig/fc-blanks/fcblanks.tmpl.h
*
* Copyright © 2003 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.
*/
@@@

View File

@ -1,119 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Language" content="en-us">
<meta name="GENERATOR" content="Microsoft FrontPage 6.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="index.css">
<title>Unicode Utilities: UnicodeSet</title>
</head>
<body>
<h1>Unicode Utilities: UnicodeSet </h1>
<p><a target="help" href="http://cldr.unicode.org/unicode-utilities/list-unicodeset"><b>help</b></a> | <a target="character" href="character.jsp">character</a>
| <a target="properties" href="properties.jsp">properties</a>
| <a target="confusables" href="confusables.jsp">confusables</a>
| <a target="list" href="list-unicodeset.jsp">unicode-set</a>
| <a target="compare" href="unicodeset.jsp">compare-sets</a>
| <a target="regex" href="regex.jsp">regex</a>
| <a target="bnf" href="bnf.jsp">bnf-regex</a>
| <a target="breaks" href="breaks.jsp">breaks</a>
| <a target="transform" href="transform.jsp">transform</a>
| <a target="bidi" href="bidi.jsp">bidi</a>
| <a target="idna" href="idna.jsp">idna</a>
| <a target="languageid" href="languageid.jsp">languageid</a></p>
<form name="myform">
<table border="1" cellpadding="0" cellspacing="0" style="border-collapse: collapse; width:100%">
<tr>
<th style="width: 50%">Input</th>
</tr>
<tr>
<td><textarea name="a" rows="8" cols="10" style="width: 100%">[:GC=Zs:][:DI:]</textarea></td>
</tr>
<tr>
<td>
<input id='main' type="submit" value="Show Set" onClick="window.location.href='list-unicodeset.jsp?a='+document.getElementById('main').value"/>&nbsp;&nbsp;
<input type="checkbox" checked name="abb"><label for="abb">Abbreviate</label>&nbsp;&nbsp;
<input type="checkbox" name="c"><label for="c">Collate</label>&nbsp;&nbsp;
<input type="checkbox" checked name="ucd"><label for="ucd">UCD format</label>&nbsp;&nbsp;
<input type="checkbox" checked name="esc"><label for="esc">Escape</label>&nbsp;&nbsp;
<label for="g">Group by:</label>
<input type="text" checked name="g" size="25" value="">
<label for="i">Info:</label>
<input type="text" checked name="i" size="25" value="">
</td>
</tr>
</table>
<p>4,190 Code Points</p>
<hr>
<p>[\ \u00A0\u00AD\u034F\u061C\u115F\u1160\u1680\u17B4\u17B5\u180B-\u180E\u2000-\u200F\u202A-\u202F\u205F-\u206F\u3000\u3164\uFE00-\uFE0F\uFEFF\uFFA0\uFFF0-\uFFF8\U0001BCA0-\U0001BCA3\U0001D173-\U0001D17A\U000E0000-\U000E0FFF]</p>
<hr>
<table width='100%'><tr><td colSpan='4'><tr><td class='charCell' width='3m'>   </td><td width='7m'><code><a target='c' href='character.jsp?a=0020'>0020</a></code></td><td>SPACE</td></tr>
<tr><td class='charCell' width='3m'>   </td><td width='7m'><code><a target='c' href='character.jsp?a=00A0'>00A0</a></code></td><td>NO-BREAK SPACE</td></tr>
<tr><td class='charCell' width='3m'>  </td><td width='7m'><code><a target='c' href='character.jsp?a=00AD'>00AD</a></code></td><td>SOFT HYPHEN</td></tr>
<tr><td class='charCell' width='3m'>  </td><td width='7m'><code><a target='c' href='character.jsp?a=034F'>034F</a></code></td><td>COMBINING GRAPHEME JOINER</td></tr>
<tr><td class='charCell' width='3m'>  </td><td width='7m'><code><a target='c' href='character.jsp?a=061C'>061C</a></code></td><td>ARABIC LETTER MARK</td></tr>
<tr><td class='charCell' width='3m'>  </td><td width='7m'><code><a target='c' href='character.jsp?a=115F'>115F</a></code></td><td>HANGUL CHOSEONG FILLER</td></tr>
<tr><td class='charCell' width='3m'>  </td><td width='7m'><code><a target='c' href='character.jsp?a=1160'>1160</a></code></td><td>HANGUL JUNGSEONG FILLER</td></tr>
<tr><td class='charCell' width='3m'>  </td><td width='7m'><code><a target='c' href='character.jsp?a=1680'>1680</a></code></td><td>OGHAM SPACE MARK</td></tr>
<tr><td class='charCell' width='3m'>  </td><td width='7m'><code><a target='c' href='character.jsp?a=17B4'>17B4</a></code></td><td>KHMER VOWEL INHERENT AQ</td></tr>
<tr><td class='charCell' width='3m'>  </td><td width='7m'><code><a target='c' href='character.jsp?a=17B5'>17B5</a></code></td><td>KHMER VOWEL INHERENT AA</td></tr>
<code><a target='c' href='character.jsp?a=180B'>180B</a></code>..<tr><td class='charCell' width='3m'>  </td><td width='7m'><code><a target='c' href='character.jsp?a=180E'>180E</a></code></td><td>MONGOLIAN VOWEL SEPARATOR</td></tr>
<code><a target='c' href='character.jsp?a=2000'>2000</a></code>..<tr><td class='charCell' width='3m'>  </td><td width='7m'><code><a target='c' href='character.jsp?a=200F'>200F</a></code></td><td>RIGHT-TO-LEFT MARK</td></tr>
<code><a target='c' href='character.jsp?a=202A'>202A</a></code>..<tr><td class='charCell' width='3m'>  </td><td width='7m'><code><a target='c' href='character.jsp?a=202F'>202F</a></code></td><td>NARROW NO-BREAK SPACE</td></tr>
<code><a target='c' href='character.jsp?a=205F'>205F</a></code>..<tr><td class='charCell' width='3m'>  </td><td width='7m'><code><a target='c' href='character.jsp?a=206F'>206F</a></code></td><td>NOMINAL DIGIT SHAPES</td></tr>
<tr><td class='charCell' width='3m'>   </td><td width='7m'><code><a target='c' href='character.jsp?a=3000'>3000</a></code></td><td>IDEOGRAPHIC SPACE</td></tr>
<tr><td class='charCell' width='3m'>  </td><td width='7m'><code><a target='c' href='character.jsp?a=3164'>3164</a></code></td><td>HANGUL FILLER</td></tr>
<code><a target='c' href='character.jsp?a=FE00'>FE00</a></code>..<tr><td class='charCell' width='3m'>  </td><td width='7m'><code><a target='c' href='character.jsp?a=FE0F'>FE0F</a></code></td><td>VARIATION SELECTOR-16</td></tr>
<tr><td class='charCell' width='3m'>  </td><td width='7m'><code><a target='c' href='character.jsp?a=FEFF'>FEFF</a></code></td><td>ZERO WIDTH NO-BREAK SPACE</td></tr>
<tr><td class='charCell' width='3m'>  </td><td width='7m'><code><a target='c' href='character.jsp?a=FFA0'>FFA0</a></code></td><td>HALFWIDTH HANGUL FILLER</td></tr>
<code><a target='c' href='character.jsp?a=FFF0'>FFF0</a></code>..<tr><td class='charCell' width='3m'>  </td><td width='7m'><code><a target='c' href='character.jsp?a=FFF8'>FFF8</a></code></td><td><i>&lt;unassigned-FFF8&gt;</i></td></tr>
<code><a target='c' href='character.jsp?a=1BCA0'>1BCA0</a></code>..<tr><td class='charCell' width='3m'>  </td><td width='7m'><code><a target='c' href='character.jsp?a=1BCA3'>1BCA3</a></code></td><td>SHORTHAND FORMAT UP STEP</td></tr>
<code><a target='c' href='character.jsp?a=1D173'>1D173</a></code>..<tr><td class='charCell' width='3m'>  </td><td width='7m'><code><a target='c' href='character.jsp?a=1D17A'>1D17A</a></code></td><td>MUSICAL SYMBOL END PHRASE</td></tr>
<code><a target='c' href='character.jsp?a=E0000'>E0000</a></code>..<tr><td class='charCell' width='3m'>  </td><td width='7m'><code><a target='c' href='character.jsp?a=E0FFF'>E0FFF</a></code></td><td><i>&lt;unassigned-E0FFF&gt;</i></td></tr>
</td></tr></table>
</form>
<hr>
<p style="font-size:80%"><b><a name="fonts">Fonts and Display.</a></b> If you don't have a good set of Unicode fonts (and modern browser),
you may not be able to read some of the characters.
Some suggested fonts that you can add for coverage are:
<a href="http://greekfonts.teilar.gr/" target="_blank">Unicode Fonts for Ancient Scripts</a>,
<a href="https://www.google.com/get/noto/" target="_blank">Noto Fonts site</a>,
<a href="http://www.alanwood.net/unicode/fonts.html" target="_blank">Large, multi-script Unicode fonts</a>.
See also: <a href="http://www.unicode.org/help/display_problems.html" target="_blank">Unicode Display Problems</a>.</p>
<p style="font-size:80%">Version 3.7;
ICU version: 57.0.1.0;
Unicode version: 8.0.0.0
</p>
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
try {
var pageTracker = _gat._getTracker("UA-8314904-1");
pageTracker._trackPageview();
} catch(err) {}
</script>
<hr>
</body>
</html>

View File

@ -1,33 +0,0 @@
# -*- encoding: utf-8 -*-
#
# Copyright © 2003 Keith Packard
# Copyright © 2013 Google, Inc.
#
# 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.
#
# Google Author(s): Behdad Esfahbod
TAG = glyphname
DEPS = $(srcdir)/zapfdingbats.txt
ARGS = $(srcdir)/zapfdingbats.txt
DIST = $(srcdir)/zapfdingbats.txt
include $(top_srcdir)/Tools.mk
-include $(top_srcdir)/git.mk

View File

@ -1,325 +0,0 @@
/*
* fontconfig/fc-glyphname/fc-glyphname.c
*
* Copyright © 2003 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"
static int
rawindex (const FcGlyphName *gn);
static void
scan (FILE *f, char *filename);
static int
isprime (int i);
static void
find_hash (void);
static FcChar32
FcHashGlyphName (const FcChar8 *name);
static void
insert (FcGlyphName *gn, FcGlyphName **table, FcChar32 h);
static void
dump (FcGlyphName * const *table, const char *name);
static FcGlyphName *
FcAllocGlyphName (FcChar32 ucs, FcChar8 *name)
{
FcGlyphName *gn;
gn = malloc (sizeof (FcGlyphName) + strlen ((char *) name));
if (!gn)
return 0;
gn->ucs = ucs;
strcpy ((char *) gn->name, (char *) name);
return gn;
}
static void
fatal (const char *file, int lineno, const char *msg)
{
if (lineno)
fprintf (stderr, "%s:%d: %s\n", file, lineno, msg);
else
fprintf (stderr, "%s: %s\n", file, msg);
exit (1);
}
#define MAX_GLYPHFILE 256
#define MAX_GLYPHNAME 10240
#define MAX_NAMELEN 1024
static FcGlyphName *raw[MAX_GLYPHNAME];
static int nraw;
static int max_name_len;
static FcGlyphName *name_to_ucs[MAX_GLYPHNAME*2];
static FcGlyphName *ucs_to_name[MAX_GLYPHNAME*2];
static unsigned int hash, rehash;
static int
rawindex (const FcGlyphName *gn)
{
int i;
for (i = 0; i < nraw; i++)
if (raw[i] == gn)
return i;
return -1;
}
static void
scan (FILE *f, char *filename)
{
char buf[MAX_NAMELEN];
char name[MAX_NAMELEN];
unsigned long ucs;
FcGlyphName *gn;
int lineno = 0;
int len;
while (fgets (buf, sizeof (buf), f))
{
lineno++;
if (sscanf (buf, "%[^;];%lx\n", name, &ucs) != 2)
continue;
gn = FcAllocGlyphName ((FcChar32) ucs, (FcChar8 *) name);
if (!gn)
fatal (filename, lineno, "out of memory");
len = strlen (name);
if (len > max_name_len)
max_name_len = len;
raw[nraw++] = gn;
}
}
static int compare_string (const void *a, const void *b)
{
const char *const *as = a, *const *bs = b;
return strcmp (*as, *bs);
}
static int compare_glyphname (const void *a, const void *b)
{
const FcGlyphName *const *ag = a, *const *bg = b;
return strcmp ((char *) (*ag)->name, (char *) (*bg)->name);
}
static int
isqrt (int a)
{
int l, h, m;
l = 2;
h = a/2;
while ((h-l) > 1)
{
m = (h+l) >> 1;
if (m * m < a)
l = m;
else
h = m;
}
return h;
}
static int
isprime (int i)
{
int l, t;
if (i < 2)
return FcFalse;
if ((i & 1) == 0)
{
if (i == 2)
return FcTrue;
return FcFalse;
}
l = isqrt (i) + 1;
for (t = 3; t <= l; t += 2)
if (i % t == 0)
return 0;
return 1;
}
/*
* Find a prime pair that leaves at least 25% of the hash table empty
*/
static void
find_hash (void)
{
int h;
h = nraw + nraw / 4;
if ((h & 1) == 0)
h++;
while (!isprime(h-2) || !isprime(h))
h += 2;
hash = h;
rehash = h-2;
}
static FcChar32
FcHashGlyphName (const FcChar8 *name)
{
FcChar32 h = 0;
FcChar8 c;
while ((c = *name++))
{
h = ((h << 1) | (h >> 31)) ^ c;
}
return h;
}
static void
insert (FcGlyphName *gn, FcGlyphName **table, FcChar32 h)
{
unsigned int i, r = 0;
i = (int) (h % hash);
while (table[i])
{
if (!r) r = (h % rehash + 1);
i += r;
if (i >= hash)
i -= hash;
}
table[i] = gn;
}
static void
dump (FcGlyphName * const *table, const char *name)
{
unsigned int i;
printf ("static const FcGlyphId %s[%d] = {\n", name, hash);
for (i = 0; i < hash; i++)
if (table[i])
printf (" %d,\n", rawindex(table[i]));
else
printf (" -1,\n");
printf ("};\n");
}
int
main (int argc FC_UNUSED, char **argv)
{
char *files[MAX_GLYPHFILE + 1];
char line[1024];
FILE *f;
int i;
const char *type;
i = 0;
while (argv[i+1])
{
if (i == MAX_GLYPHFILE)
fatal (*argv, 0, "Too many glyphname files");
files[i] = argv[i+1];
i++;
}
files[i] = 0;
qsort (files, i, sizeof (char *), compare_string);
for (i = 0; files[i]; i++)
{
f = fopen (files[i], "r");
if (!f)
fatal (files[i], 0, strerror (errno));
scan (f, files[i]);
fclose (f);
}
qsort (raw, nraw, sizeof (FcGlyphName *), compare_glyphname);
find_hash ();
for (i = 0; i < nraw; i++)
{
insert (raw[i], name_to_ucs, FcHashGlyphName (raw[i]->name));
insert (raw[i], ucs_to_name, raw[i]->ucs);
}
/*
* Scan the input until the marker is found
*/
while (fgets (line, sizeof (line), stdin))
{
if (!strncmp (line, "@@@", 3))
break;
fputs (line, stdout);
}
printf ("/* %d glyphnames in %d entries, %d%% occupancy */\n\n",
nraw, hash, nraw * 100 / hash);
printf ("#define FC_GLYPHNAME_HASH %u\n", hash);
printf ("#define FC_GLYPHNAME_REHASH %u\n", rehash);
printf ("#define FC_GLYPHNAME_MAXLEN %d\n\n", max_name_len);
if (nraw < 128)
type = "int8_t";
else if (nraw < 32768)
type = "int16_t";
else
type = "int32_t";
printf ("typedef %s FcGlyphId;\n\n", type);
/*
* Dump out entries
*/
printf ("static const struct { const FcChar32 ucs; const FcChar8 name[%d]; } _fc_glyph_names[%d] = {\n",
max_name_len + 1, nraw);
for (i = 0; i < nraw; i++)
printf (" { 0x%lx, \"%s\" },\n",
(unsigned long) raw[i]->ucs, raw[i]->name);
printf ("};\n");
/*
* Dump out name_to_ucs table
*/
dump (name_to_ucs, "_fc_name_to_ucs");
/*
* Dump out ucs_to_name table
*/
dump (ucs_to_name, "_fc_ucs_to_name");
while (fgets (line, sizeof (line), stdin))
fputs (line, stdout);
fflush (stdout);
exit (ferror (stdout));
}

View File

@ -1,25 +0,0 @@
/*
* fontconfig/fc-glyphname/fcglyphname.tmpl.h
*
* Copyright © 2003 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.
*/
@@@

View File

@ -1,212 +0,0 @@
# Name: ITC Zapf Dingbats Glyph List
# Table version: 2.0
# Date: September 20, 2002
#
# See http://partners.adobe.com/asn/developer/typeforum/unicodegn.html
#
# Format: Semicolon-delimited fields:
# (1) glyph name
# (2) Unicode scalar value
#
a100;275E
a101;2761
a102;2762
a103;2763
a104;2764
a105;2710
a106;2765
a107;2766
a108;2767
a109;2660
a10;2721
a110;2665
a111;2666
a112;2663
a117;2709
a118;2708
a119;2707
a11;261B
a120;2460
a121;2461
a122;2462
a123;2463
a124;2464
a125;2465
a126;2466
a127;2467
a128;2468
a129;2469
a12;261E
a130;2776
a131;2777
a132;2778
a133;2779
a134;277A
a135;277B
a136;277C
a137;277D
a138;277E
a139;277F
a13;270C
a140;2780
a141;2781
a142;2782
a143;2783
a144;2784
a145;2785
a146;2786
a147;2787
a148;2788
a149;2789
a14;270D
a150;278A
a151;278B
a152;278C
a153;278D
a154;278E
a155;278F
a156;2790
a157;2791
a158;2792
a159;2793
a15;270E
a160;2794
a161;2192
a162;27A3
a163;2194
a164;2195
a165;2799
a166;279B
a167;279C
a168;279D
a169;279E
a16;270F
a170;279F
a171;27A0
a172;27A1
a173;27A2
a174;27A4
a175;27A5
a176;27A6
a177;27A7
a178;27A8
a179;27A9
a17;2711
a180;27AB
a181;27AD
a182;27AF
a183;27B2
a184;27B3
a185;27B5
a186;27B8
a187;27BA
a188;27BB
a189;27BC
a18;2712
a190;27BD
a191;27BE
a192;279A
a193;27AA
a194;27B6
a195;27B9
a196;2798
a197;27B4
a198;27B7
a199;27AC
a19;2713
a1;2701
a200;27AE
a201;27B1
a202;2703
a203;2750
a204;2752
a205;276E
a206;2770
a20;2714
a21;2715
a22;2716
a23;2717
a24;2718
a25;2719
a26;271A
a27;271B
a28;271C
a29;2722
a2;2702
a30;2723
a31;2724
a32;2725
a33;2726
a34;2727
a35;2605
a36;2729
a37;272A
a38;272B
a39;272C
a3;2704
a40;272D
a41;272E
a42;272F
a43;2730
a44;2731
a45;2732
a46;2733
a47;2734
a48;2735
a49;2736
a4;260E
a50;2737
a51;2738
a52;2739
a53;273A
a54;273B
a55;273C
a56;273D
a57;273E
a58;273F
a59;2740
a5;2706
a60;2741
a61;2742
a62;2743
a63;2744
a64;2745
a65;2746
a66;2747
a67;2748
a68;2749
a69;274A
a6;271D
a70;274B
a71;25CF
a72;274D
a73;25A0
a74;274F
a75;2751
a76;25B2
a77;25BC
a78;25C6
a79;2756
a7;271E
a81;25D7
a82;2758
a83;2759
a84;275A
a85;276F
a86;2771
a87;2772
a88;2773
a89;2768
a8;271F
a90;2769
a91;276C
a92;276D
a93;276A
a94;276B
a95;2774
a96;2775
a97;275B
a98;275C
a99;275D
a9;2720
#-- end

View File

@ -52,7 +52,6 @@
#define _GNU_SOURCE
#include <getopt.h>
static const struct option longopts[] = {
{"ignore-blanks", 0, 0, 'b'},
{"format", 1, 0, 'f'},
{"version", 0, 0, 'V'},
{"help", 0, 0, 'h'},
@ -70,21 +69,19 @@ usage (char *program, int error)
{
FILE *file = error ? stderr : stdout;
#if HAVE_GETOPT_LONG
fprintf (file, "usage: %s [-Vbh] [-f FORMAT] [--ignore-blanks] [--format FORMAT] [--version] [--help] font-file...\n",
fprintf (file, "usage: %s [-Vh] [-f FORMAT] [--format FORMAT] [--version] [--help] font-file...\n",
program);
#else
fprintf (file, "usage: %s [-Vbh] [-f FORMAT] font-file...\n",
fprintf (file, "usage: %s [-Vh] [-f FORMAT] font-file...\n",
program);
#endif
fprintf (file, "Scan font files and directories, and print resulting pattern(s)\n");
fprintf (file, "\n");
#if HAVE_GETOPT_LONG
fprintf (file, " -b, --ignore-blanks ignore blanks to compute languages\n");
fprintf (file, " -f, --format=FORMAT use the given output format\n");
fprintf (file, " -V, --version display font config version and exit\n");
fprintf (file, " -h, --help display this help and exit\n");
#else
fprintf (file, " -b (ignore-blanks) ignore blanks to compute languages\n");
fprintf (file, " -f FORMAT (format) use the given output format\n");
fprintf (file, " -V (version) display font config version and exit\n");
fprintf (file, " -h (help) display this help and exit\n");
@ -97,9 +94,7 @@ main (int argc, char **argv)
{
FcChar8 *format = NULL;
int i;
int ignore_blanks = 0;
FcFontSet *fs;
FcBlanks *blanks = NULL;
#if HAVE_GETOPT_LONG || HAVE_GETOPT
int c;
@ -110,9 +105,6 @@ main (int argc, char **argv)
#endif
{
switch (c) {
case 'b':
ignore_blanks = 1;
break;
case 'f':
format = (FcChar8 *) strdup (optarg);
break;
@ -135,22 +127,20 @@ main (int argc, char **argv)
usage (argv[0], 1);
fs = FcFontSetCreate ();
if (!ignore_blanks)
blanks = FcConfigGetBlanks (NULL);
for (; i < argc; i++)
{
const FcChar8 *file = (FcChar8*) argv[i];
if (!FcFileIsDir (file))
FcFileScan (fs, NULL, NULL, blanks, file, FcTrue);
FcFileScan (fs, NULL, NULL, NULL, file, FcTrue);
else
{
FcStrSet *dirs = FcStrSetCreate ();
FcStrList *strlist = FcStrListCreate (dirs);
do
{
FcDirScan (fs, dirs, NULL, blanks, file, FcTrue);
FcDirScan (fs, dirs, NULL, NULL, file, FcTrue);
}
while ((file = FcStrListNext (strlist)));
FcStrListDone (strlist);

View File

@ -62,12 +62,8 @@ manpage.1: manpage.sgml
<cmdsynopsis>
<command>&dhpackage;</command>
<arg><option>-Vbh</option></arg>
<arg><option>-Vh</option></arg>
<sbr>
<group>
<arg><option>-b</option></arg>
<arg><option>--ignore-blanks</option></arg>
</group>
<group>
<arg><option>-f</option> <option><replaceable>format</replaceable></option></arg>
<arg><option>--format</option> <option><replaceable>format</replaceable></option></arg>
@ -94,14 +90,6 @@ manpage.1: manpage.sgml
options is included below.</para>
<variablelist>
<varlistentry>
<term><option>-b</option>
<option>--ignore-blanks</option>
</term>
<listitem>
<para>Ignore blanks to compute languages</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-f</option>
<option>--format</option>

View File

@ -89,7 +89,6 @@ ALIAS_FILES = fcalias.h fcaliastail.h fcftalias.h fcftaliastail.h
BUILT_SOURCES = $(ALIAS_FILES) \
../fc-case/fccase.h \
../fc-glyphname/fcglyphname.h \
../fc-lang/fclang.h \
stamp-fcstdint \
fcobjshash.h \
@ -99,8 +98,6 @@ noinst_PROGRAMS = fcarch
../fc-case/fccase.h:
cd ../fc-case && $(MAKE) $(AM_MAKEFLAGS) fccase.h
../fc-glyphname/fcglyphname.h:
cd ../fc-glyphname && $(MAKE) $(AM_MAKEFLAGS) fcglyphname.h
../fc-lang/fclang.h:
cd ../fc-lang && $(MAKE) $(AM_MAKEFLAGS) fclang.h
@ -130,7 +127,6 @@ libfontconfig_la_SOURCES = \
fcarch.h \
fcatomic.c \
fcatomic.h \
fcblanks.c \
fccache.c \
fccfg.c \
fccharset.c \

View File

@ -1,108 +0,0 @@
/*
* fontconfig/src/fcblanks.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"
FcBlanks *
FcBlanksCreate (void)
{
FcBlanks *b;
b = malloc (sizeof (FcBlanks));
if (!b)
return 0;
b->nblank = 0;
b->sblank = 0;
b->blanks = 0;
return b;
}
void
FcBlanksDestroy (FcBlanks *b)
{
if (b->sblank == -1)
return;
if (b->blanks)
free (b->blanks);
free (b);
}
FcBool
FcBlanksAdd (FcBlanks *b, FcChar32 ucs4)
{
FcChar32 *c;
int sblank;
for (sblank = 0; sblank < b->nblank; sblank++)
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;
if (b->blanks)
c = (FcChar32 *) realloc (b->blanks, sblank * sizeof (FcChar32));
else
c = (FcChar32 *) malloc (sblank * sizeof (FcChar32));
if (!c)
return FcFalse;
b->sblank = sblank;
b->blanks = c;
}
b->blanks[b->nblank++] = ucs4;
return FcTrue;
}
FcBool
FcBlanksIsMember (FcBlanks *b, FcChar32 ucs4)
{
int lower = 0, higher = b->nblank, middle;
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__
#include "fcaliastail.h"
#undef __fcblanks__

View File

@ -27,7 +27,6 @@
#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
@ -110,8 +109,6 @@ FcConfigCreate (void)
if (!config->cacheDirs)
goto bail8;
config->blanks = &fcBlanks;
config->substPattern = 0;
config->substFont = 0;
config->substScan = 0;
@ -276,9 +273,6 @@ FcConfigDestroy (FcConfig *config)
FcFontSetDestroy (config->acceptPatterns);
FcFontSetDestroy (config->rejectPatterns);
if (config->blanks)
FcBlanksDestroy (config->blanks);
FcSubstDestroy (config->substPattern);
FcSubstDestroy (config->substFont);
FcSubstDestroy (config->substScan);
@ -569,40 +563,49 @@ FcConfigSetFonts (FcConfig *config,
config->fonts[set] = fonts;
}
FcBlanks *
FcConfigGetBlanks (FcConfig *config)
FcBlanksCreate (void)
{
if (!config)
{
config = FcConfigGetCurrent ();
if (!config)
return 0;
/* Deprecated. */
return NULL;
}
return config->blanks;
void
FcBlanksDestroy (FcBlanks *b FC_UNUSED)
{
/* Deprecated. */
}
FcBool
FcConfigAddBlank (FcConfig *config,
FcChar32 blank)
FcBlanksAdd (FcBlanks *b FC_UNUSED, FcChar32 ucs4 FC_UNUSED)
{
FcBlanks *b, *freeme = 0;
/* Deprecated. */
return FcFalse;
}
b = config->blanks;
if (!b)
FcBool
FcBlanksIsMember (FcBlanks *b FC_UNUSED, FcChar32 ucs4 FC_UNUSED)
{
freeme = b = FcBlanksCreate ();
if (!b)
/* Deprecated. */
return FcFalse;
}
if (!FcBlanksAdd (b, blank))
FcBlanks *
FcConfigGetBlanks (FcConfig *config FC_UNUSED)
{
if (freeme)
FcBlanksDestroy (freeme);
/* Deprecated. */
return NULL;
}
FcBool
FcConfigAddBlank (FcConfig *config FC_UNUSED,
FcChar32 blank FC_UNUSED)
{
/* Deprecated. */
return FcFalse;
}
config->blanks = b;
return FcTrue;
}
int
FcConfigGetRescanInterval (FcConfig *config)
@ -2221,7 +2224,7 @@ FcConfigAppFontAddFile (FcConfig *config,
FcConfigSetFonts (config, set, FcSetApplication);
}
if (!FcFileScanConfig (set, subdirs, config->blanks, file, config))
if (!FcFileScanConfig (set, subdirs, file, config))
{
FcStrSetDestroy (subdirs);
return FcFalse;

View File

@ -64,7 +64,6 @@ FcFileIsFile (const FcChar8 *file)
static FcBool
FcFileScanFontConfig (FcFontSet *set,
FcBlanks *blanks,
const FcChar8 *file,
FcConfig *config)
{
@ -99,7 +98,7 @@ FcFileScanFontConfig (FcFontSet *set,
return FcFalse;
num_faces = face->num_faces;
num_instances = face->style_flags >> 16;
font = FcFreeTypeQueryFace (face, file, id, blanks);
font = FcFreeTypeQueryFace (face, file, id, NULL);
FT_Done_Face (face);
if (FcDebug () & FC_DBG_SCAN)
@ -174,7 +173,6 @@ FcFileScanFontConfig (FcFontSet *set,
FcBool
FcFileScanConfig (FcFontSet *set,
FcStrSet *dirs,
FcBlanks *blanks,
const FcChar8 *file,
FcConfig *config)
{
@ -201,7 +199,7 @@ FcFileScanConfig (FcFontSet *set,
else
{
if (set)
return FcFileScanFontConfig (set, blanks, file, config);
return FcFileScanFontConfig (set, file, config);
else
return FcTrue;
}
@ -211,11 +209,11 @@ FcBool
FcFileScan (FcFontSet *set,
FcStrSet *dirs,
FcFileCache *cache FC_UNUSED,
FcBlanks *blanks,
FcBlanks *blanks FC_UNUSED,
const FcChar8 *file,
FcBool force FC_UNUSED)
{
return FcFileScanConfig (set, dirs, blanks, file, FcConfigGetCurrent ());
return FcFileScanConfig (set, dirs, file, FcConfigGetCurrent ());
}
/*
@ -230,7 +228,6 @@ cmpstringp(const void *p1, const void *p2)
FcBool
FcDirScanConfig (FcFontSet *set,
FcStrSet *dirs,
FcBlanks *blanks,
const FcChar8 *dir,
FcBool force, /* XXX unused */
FcConfig *config)
@ -249,9 +246,6 @@ FcDirScanConfig (FcFontSet *set,
if (!set && !dirs)
return FcTrue;
if (!blanks)
blanks = FcConfigGetBlanks (config);
/* freed below */
file = (FcChar8 *) malloc (strlen ((char *) dir) + 1 + FC_MAX_FILE_LEN + 1);
if (!file) {
@ -302,7 +296,7 @@ FcDirScanConfig (FcFontSet *set,
* Scan file files to build font patterns
*/
for (i = 0; i < files->num; i++)
FcFileScanConfig (set, dirs, blanks, files->strs[i], config);
FcFileScanConfig (set, dirs, files->strs[i], config);
bail2:
FcStrSetDestroy (files);
@ -318,15 +312,15 @@ bail:
FcBool
FcDirScan (FcFontSet *set,
FcStrSet *dirs,
FcFileCache *cache, /* XXX unused */
FcBlanks *blanks,
FcFileCache *cache FC_UNUSED,
FcBlanks *blanks FC_UNUSED,
const FcChar8 *dir,
FcBool force /* XXX unused */)
FcBool force FC_UNUSED)
{
if (cache || !force)
return FcFalse;
return FcDirScanConfig (set, dirs, blanks, dir, force, FcConfigGetCurrent ());
return FcDirScanConfig (set, dirs, dir, force, FcConfigGetCurrent ());
}
/*
@ -368,7 +362,7 @@ FcDirCacheScan (const FcChar8 *dir, FcConfig *config)
/*
* Scan the dir
*/
if (!FcDirScanConfig (set, dirs, NULL, d, FcTrue, config))
if (!FcDirScanConfig (set, dirs, d, FcTrue, config))
goto bail2;
/*
@ -427,7 +421,7 @@ FcDirCacheRescan (const FcChar8 *dir, FcConfig *config)
/*
* Scan the dir
*/
if (!FcDirScanConfig (NULL, dirs, NULL, d, FcTrue, config))
if (!FcDirScanConfig (NULL, dirs, d, FcTrue, config))
goto bail1;
/*
* Rebuild the cache object

View File

@ -51,6 +51,7 @@
#include <string.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_ADVANCES_H
#include FT_TRUETYPE_TABLES_H
#include FT_SFNT_NAMES_H
#include FT_TRUETYPE_IDS_H
@ -1157,7 +1158,7 @@ FcPattern *
FcFreeTypeQueryFace (const FT_Face face,
const FcChar8 *file,
int id,
FcBlanks *blanks)
FcBlanks *blanks FC_UNUSED)
{
FcPattern *pat;
int slant = -1;
@ -2006,122 +2007,6 @@ static const FT_Encoding fcFontEncodings[] = {
#define NUM_DECODE (int) (sizeof (fcFontEncodings) / sizeof (fcFontEncodings[0]))
#include "../fc-glyphname/fcglyphname.h"
static FcChar32
FcHashGlyphName (const FcChar8 *name)
{
FcChar32 h = 0;
FcChar8 c;
while ((c = *name++))
{
h = ((h << 1) | (h >> 31)) ^ c;
}
return h;
}
#if HAVE_FT_HAS_PS_GLYPH_NAMES
/*
* Use Type1 glyph names for fonts which have reliable names
* and which export an Adobe Custom mapping
*/
static FcBool
FcFreeTypeUseNames (FT_Face face)
{
FT_Int map;
if (!FT_Has_PS_Glyph_Names (face))
return FcFalse;
for (map = 0; map < face->num_charmaps; map++)
if (face->charmaps[map]->encoding == ft_encoding_adobe_custom)
return FcTrue;
return FcFalse;
}
static const FcChar8 *
FcUcs4ToGlyphName (FcChar32 ucs4)
{
int i = (int) (ucs4 % FC_GLYPHNAME_HASH);
int r = 0;
FcGlyphId gn;
while ((gn = _fc_ucs_to_name[i]) != -1)
{
if (_fc_glyph_names[gn].ucs == ucs4)
return _fc_glyph_names[gn].name;
if (!r)
{
r = (int) (ucs4 % FC_GLYPHNAME_REHASH);
if (!r)
r = 1;
}
i += r;
if (i >= FC_GLYPHNAME_HASH)
i -= FC_GLYPHNAME_HASH;
}
return 0;
}
static FcChar32
FcGlyphNameToUcs4 (FcChar8 *name)
{
FcChar32 h = FcHashGlyphName (name);
int i = (int) (h % FC_GLYPHNAME_HASH);
int r = 0;
FcGlyphId gn;
while ((gn = _fc_name_to_ucs[i]) != -1)
{
if (!strcmp ((char *) name, (char *) _fc_glyph_names[gn].name))
return _fc_glyph_names[gn].ucs;
if (!r)
{
r = (int) (h % FC_GLYPHNAME_REHASH);
if (!r)
r = 1;
}
i += r;
if (i >= FC_GLYPHNAME_HASH)
i -= FC_GLYPHNAME_HASH;
}
return 0xffff;
}
/*
* Work around a bug in some FreeType versions which fail
* to correctly bounds check glyph name buffers and overwrite
* the stack. As Postscript names have a limit of 127 characters,
* this should be sufficient.
*/
#if FC_GLYPHNAME_MAXLEN < 127
# define FC_GLYPHNAME_BUFLEN 127
#else
# define FC_GLYPHNAME_BUFLEN FC_GLYPHNAME_MAXLEN
#endif
/*
* Search through a font for a glyph by name. This is
* currently a linear search as there doesn't appear to be
* any defined order within the font
*/
static FT_UInt
FcFreeTypeGlyphNameIndex (FT_Face face, const FcChar8 *name)
{
FT_UInt gindex;
FcChar8 name_buf[FC_GLYPHNAME_BUFLEN + 2];
for (gindex = 0; gindex < (FT_UInt) face->num_glyphs; gindex++)
{
if (FT_Get_Glyph_Name (face, gindex, name_buf, FC_GLYPHNAME_BUFLEN+1) == 0)
if (!strcmp ((char *) name, (char *) name_buf))
return gindex;
}
return 0;
}
#endif
/*
* Map a UCS4 glyph to a glyph index. Use all available encoding
* tables to try and find one that works. This information is expected
@ -2179,38 +2064,28 @@ FcFreeTypeCharIndex (FT_Face face, FcChar32 ucs4)
return glyphindex;
}
}
#if HAVE_FT_HAS_PS_GLYPH_NAMES
/*
* Check postscript name table if present
*/
if (FcFreeTypeUseNames (face))
{
const FcChar8 *name = FcUcs4ToGlyphName (ucs4);
if (name)
{
glyphindex = FcFreeTypeGlyphNameIndex (face, name);
if (glyphindex)
return glyphindex;
}
}
#endif
return 0;
}
static FcBool
FcFreeTypeCheckGlyph (FT_Face face, FcChar32 ucs4,
FT_UInt glyph, FcBlanks *blanks,
FT_Pos *advance,
FcBool using_strike)
static inline int fc_min (int a, int b) { return a <= b ? a : b; }
static inline int fc_max (int a, int b) { return a >= b ? a : b; }
static inline FcBool fc_approximately_equal (int x, int y)
{ return abs (x - y) * 33 <= fc_max (abs (x), abs (y)); }
FcCharSet *
FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks FC_UNUSED, int *spacing)
{
FcCharSet *fcs;
int o;
FT_Int load_flags = FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH | FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
FT_GlyphSlot slot;
FT_Pos advances[3];
unsigned int num_advances = 0;
if (using_strike)
load_flags &= ~FT_LOAD_NO_SCALE;
fcs = FcCharSetCreate ();
if (!fcs)
goto bail0;
/*
* When using scalable fonts, only report those glyphs
/* When using scalable fonts, only report those glyphs
* which can be scaled; otherwise those fonts will
* only be available at some sizes, and never when
* transformed. Avoid this by simply reporting bitmap-only
@ -2219,70 +2094,22 @@ FcFreeTypeCheckGlyph (FT_Face face, FcChar32 ucs4,
if (face->face_flags & FT_FACE_FLAG_SCALABLE)
load_flags |= FT_LOAD_NO_BITMAP;
if (FT_Load_Glyph (face, glyph, load_flags))
return FcFalse;
slot = face->glyph;
if (!glyph)
return FcFalse;
*advance = slot->metrics.horiAdvance;
switch ((int) slot->format) {
case ft_glyph_format_bitmap:
/*
* Bitmaps are assumed to be reasonable; if
* this proves to be a rash assumption, this
* code can be easily modified
*/
return FcTrue;
case ft_glyph_format_outline:
/*
* Glyphs with contours are always OK
*/
if (slot->outline.n_contours != 0)
return FcTrue;
/*
* Glyphs with no contours are only OK if
* they're members of the Blanks set specified
* in the configuration. If blanks isn't set,
* then allow any glyph to be blank
*/
if (!blanks || FcBlanksIsMember (blanks, ucs4))
return FcTrue;
/* fall through ... */
default:
break;
}
return FcFalse;
}
#define APPROXIMATELY_EQUAL(x,y) (FC_ABS ((x) - (y)) <= FC_MAX (FC_ABS (x), FC_ABS (y)) / 33)
static FcCharSet *
FcFreeTypeCharSetAndSpacingForSize (FT_Face face, FcBlanks *blanks, int *spacing, FT_Int strike_index)
{
FcChar32 page, off, ucs4;
#ifdef CHECK
FcChar32 font_max = 0;
#endif
FcCharSet *fcs;
FcCharLeaf *leaf;
int o;
FT_UInt glyph;
FT_Pos advance, advance_one = 0, advance_two = 0;
FcBool has_advance = FcFalse, fixed_advance = FcTrue, dual_advance = FcFalse;
FcBool using_strike = FcFalse;
fcs = FcCharSetCreate ();
if (!fcs)
goto bail0;
#if HAVE_FT_SELECT_SIZE
if (strike_index >= 0) {
if (!(face->face_flags & FT_FACE_FLAG_SCALABLE) &&
face->num_fixed_sizes > 0 &&
FT_Get_Sfnt_Table (face, ft_sfnt_head))
{
FT_Int strike_index = 0, i;
/* Select the face closest to 16 pixels tall */
for (i = 1; i < face->num_fixed_sizes; i++)
{
if (abs (face->available_sizes[i].height - 16) <
abs (face->available_sizes[strike_index].height - 16))
strike_index = i;
}
if (FT_Select_Size (face, strike_index) != FT_Err_Ok)
goto bail1;
using_strike = FcTrue;
}
#endif
@ -2291,34 +2118,43 @@ FcFreeTypeCharSetAndSpacingForSize (FT_Face face, FcBlanks *blanks, int *spacing
#endif
for (o = 0; o < NUM_DECODE; o++)
{
FcChar32 page, off, ucs4;
FcCharLeaf *leaf;
FT_UInt glyph;
if (FT_Select_Charmap (face, fcFontEncodings[o]) != 0)
continue;
{
page = ~0;
leaf = NULL;
ucs4 = FT_Get_First_Char (face, &glyph);
while (glyph != 0)
{
if (FcFreeTypeCheckGlyph (face, ucs4, glyph, blanks, &advance, using_strike))
FcBool good = FcTrue;
/* CID fonts built by Adobe used to make ASCII control chars to cid1
* (space glyph). As such, always check contour for those characters. */
if (ucs4 <= 0x001F)
{
if (advance)
{
if (!has_advance)
{
has_advance = FcTrue;
advance_one = advance;
if (FT_Load_Glyph (face, glyph, load_flags) ||
(face->glyph->format == FT_GLYPH_FORMAT_OUTLINE &&
face->glyph->outline.n_contours == 0))
good = FcFalse;
}
else if (!APPROXIMATELY_EQUAL (advance, advance_one))
if (good)
{
if (fixed_advance)
if (num_advances < 3)
{
dual_advance = FcTrue;
fixed_advance = FcFalse;
advance_two = advance;
}
else if (!APPROXIMATELY_EQUAL (advance, advance_two))
dual_advance = FcFalse;
FT_Pos advance = 0;
if (!FT_Get_Advance (face, glyph, load_flags, &advance) && advance)
{
unsigned int i;
for (i = 0; i < num_advances; i++)
if (fc_approximately_equal (advance, advances[i]))
break;
if (i == num_advances)
advances[num_advances++] = advance;
}
}
@ -2331,11 +2167,8 @@ FcFreeTypeCharSetAndSpacingForSize (FT_Face face, FcBlanks *blanks, int *spacing
}
off = ucs4 & 0xff;
leaf->map[off >> 5] |= (1 << (off & 0x1f));
#ifdef CHECK
if (ucs4 > font_max)
font_max = ucs4;
#endif
}
ucs4 = FT_Get_Next_Char (face, ucs4, &glyph);
}
if (fcFontEncodings[o] == FT_ENCODING_MS_SYMBOL)
@ -2356,7 +2189,7 @@ FcFreeTypeCharSetAndSpacingForSize (FT_Face face, FcBlanks *blanks, int *spacing
}
}
#ifdef CHECK
for (ucs4 = 0; ucs4 < 0x10000; ucs4++)
for (ucs4 = 0x0020; ucs4 < 0x10000; ucs4++)
{
FcBool FT_Has, FC_Has;
@ -2368,79 +2201,13 @@ FcFreeTypeCharSetAndSpacingForSize (FT_Face face, FcBlanks *blanks, int *spacing
}
}
#endif
}
break;
}
#if HAVE_FT_HAS_PS_GLYPH_NAMES
/*
* Add mapping from PS glyph names if available
*/
if (FcFreeTypeUseNames (face))
{
FcChar8 name_buf[FC_GLYPHNAME_BUFLEN + 2];
for (glyph = 0; glyph < (FT_UInt) face->num_glyphs; glyph++)
{
if (FT_Get_Glyph_Name (face, glyph, name_buf, FC_GLYPHNAME_BUFLEN+1) == 0)
{
ucs4 = FcGlyphNameToUcs4 (name_buf);
if (ucs4 != 0xffff &&
FcFreeTypeCheckGlyph (face, ucs4, glyph, blanks, &advance, using_strike))
{
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
}
}
}
}
#endif
#ifdef CHECK
printf ("%d glyphs %d encoded\n", (int) face->num_glyphs, FcCharSetCount (fcs));
for (ucs4 = 0; ucs4 <= font_max; ucs4++)
{
FcBool has_char = (glyph = FcFreeTypeCharIndex (face, ucs4)) != 0;
FcBool has_bit = FcCharSetHasChar (fcs, ucs4);
if (has_char && !has_bit)
{
if (!FcFreeTypeCheckGlyph (face, ucs4, glyph, blanks, &advance, using_strike))
printf ("Bitmap missing broken char 0x%x\n", ucs4);
else
printf ("Bitmap missing char 0x%x\n", ucs4);
}
else if (!has_char && has_bit)
printf ("Bitmap extra char 0x%x\n", ucs4);
}
#endif
if (fixed_advance)
if (num_advances <= 1)
*spacing = FC_MONO;
else if (dual_advance && APPROXIMATELY_EQUAL (2 * FC_MIN (advance_one, advance_two), FC_MAX (advance_one, advance_two)))
else if (num_advances == 2 &&
fc_approximately_equal (fc_min (advances[0], advances[1]) * 2,
fc_max (advances[0], advances[1])))
*spacing = FC_DUAL;
else
*spacing = FC_PROPORTIONAL;
@ -2452,36 +2219,7 @@ bail0:
}
FcCharSet *
FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks, int *spacing)
{
FcCharSet *cs;
/*
* Check for bitmap-only ttf fonts that are missing the glyf table.
* In that case, pick a size and look for glyphs in that size instead
*/
if (!(face->face_flags & FT_FACE_FLAG_SCALABLE) &&
face->num_fixed_sizes > 0 &&
FT_Get_Sfnt_Table (face, ft_sfnt_head))
{
FT_Int strike_index = 0;
int i;
/* Select the face closest to 16 pixels tall */
for (i = 1; i < face->num_fixed_sizes; i++) {
if (abs (face->available_sizes[i].height - 16) <
abs (face->available_sizes[strike_index].height - 16))
strike_index = i;
}
cs = FcFreeTypeCharSetAndSpacingForSize (face, blanks, spacing, strike_index);
}
else
cs = FcFreeTypeCharSetAndSpacingForSize (face, blanks, spacing, -1);
return cs;
}
FcCharSet *
FcFreeTypeCharSet (FT_Face face, FcBlanks *blanks)
FcFreeTypeCharSet (FT_Face face, FcBlanks *blanks FC_UNUSED)
{
int spacing;

View File

@ -101,7 +101,6 @@ extern pfnSHGetFolderPathA pSHGetFolderPathA;
#define FC_MIN(a,b) ((a) < (b) ? (a) : (b))
#define FC_MAX(a,b) ((a) > (b) ? (a) : (b))
#define FC_ABS(a) ((a) < 0 ? -(a) : (a))
/* slim_internal.h */
#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && defined(__ELF__) && !defined(__sun)
@ -471,12 +470,6 @@ struct _FcAtomic {
FcChar8 *tmp; /* tmpfile name (used for locking) */
};
struct _FcBlanks {
int nblank;
int sblank;
FcChar32 *blanks;
};
struct _FcConfig {
/*
* File names loaded from the configuration -- saved here as the
@ -484,11 +477,6 @@ struct _FcConfig {
* and those directives may occur in any order
*/
FcStrSet *configDirs; /* directories to scan for fonts */
/*
* Set of allowed blank chars -- used to
* trim fonts of bogus glyphs
*/
FcBlanks *blanks;
/*
* List of directories containing fonts,
* built by recursively scanning the set
@ -568,8 +556,6 @@ struct _FcValuePromotionBuffer {
} u;
};
/* fcblanks.c */
/* fccache.c */
FcPrivate FcCache *
@ -841,14 +827,12 @@ FcFileIsFile (const FcChar8 *file);
FcPrivate FcBool
FcFileScanConfig (FcFontSet *set,
FcStrSet *dirs,
FcBlanks *blanks,
const FcChar8 *file,
FcConfig *config);
FcPrivate FcBool
FcDirScanConfig (FcFontSet *set,
FcStrSet *dirs,
FcBlanks *blanks,
const FcChar8 *dir,
FcBool force,
FcConfig *config);

View File

@ -352,7 +352,6 @@ typedef enum _FcElement {
FcElementMatch,
FcElementAlias,
FcElementBlank,
FcElementRescan,
FcElementPrefer,
@ -415,7 +414,6 @@ static const struct {
{ "match", FcElementMatch },
{ "alias", FcElementAlias },
{ "blank", FcElementBlank },
{ "rescan", FcElementRescan },
{ "prefer", FcElementPrefer },
@ -1256,55 +1254,6 @@ FcStartElement(void *userData, const XML_Char *name, const XML_Char **attr)
return;
}
static void
FcParseBlank (FcConfigParse *parse)
{
int n = FcVStackElements (parse);
#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);
if (!parse->config->blanks)
{
parse->config->blanks = FcBlanksCreate ();
if (!parse->config->blanks)
goto bail;
}
switch ((int) v->tag) {
case FcVStackInteger:
#if 0
if (!FcBlanksAdd (parse->config->blanks, v->u.integer))
goto bail;
break;
#endif
case FcVStackRange:
#if 0
begin = (FcChar32) v->u.range->begin;
end = (FcChar32) v->u.range->end;
if (begin <= end)
{
for (i = begin; i <= end; i++)
{
if (!FcBlanksAdd (parse->config->blanks, i))
goto bail;
}
}
#endif
break;
default:
FcConfigMessage (parse, FcSevereError, "invalid element in blank");
break;
}
}
return;
bail:
FcConfigMessage (parse, FcSevereError, "out of memory");
}
static void
FcParseRescan (FcConfigParse *parse)
{
@ -2936,9 +2885,6 @@ FcEndElement(void *userData, const XML_Char *name FC_UNUSED)
FcParseAlias (parse);
break;
case FcElementBlank:
FcParseBlank (parse);
break;
case FcElementRescan:
FcParseRescan (parse);
break;