From fa45959bde31bb2c01eccfe0ddf50856d545ec8e Mon Sep 17 00:00:00 2001 From: Akira TAGOH Date: Fri, 30 Jul 2010 19:38:05 +0900 Subject: [PATCH] Add fc-missingglyph cmdline tool --- .gitignore | 2 + Makefile.am | 3 +- configure.in | 1 + fc-missingglyph/Makefile.am | 60 ++++++++ fc-missingglyph/fc-missingglyph.c | 250 ++++++++++++++++++++++++++++++++++ fc-missingglyph/fc-missingglyph.sgml | 180 ++++++++++++++++++++++++ 6 files changed, 495 insertions(+), 1 deletions(-) create mode 100644 fc-missingglyph/Makefile.am create mode 100644 fc-missingglyph/fc-missingglyph.c create mode 100644 fc-missingglyph/fc-missingglyph.sgml diff --git a/.gitignore b/.gitignore index 4c336d2..d01d868 100644 --- a/.gitignore +++ b/.gitignore @@ -85,6 +85,8 @@ fc-list/fc-list fc-list/fc-list.1 fc-match/fc-match fc-match/fc-match.1 +fc-missingglyph/fc-missingglyph +fc-missingglyph/fc-missingglyph.1 fc-query/fc-query fc-query/fc-query.1 fc-scan/fc-scan diff --git a/Makefile.am b/Makefile.am index 2309a19..b510b6d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -23,7 +23,8 @@ DOCSRC=@DOCSRC@ SUBDIRS=fontconfig fc-case fc-lang fc-glyphname fc-arch src \ - fc-cache fc-cat fc-list fc-match fc-pattern fc-query fc-scan \ + fc-cache fc-cat fc-list fc-match fc-missingglyph \ + fc-pattern fc-query fc-scan \ conf.d $(DOCSRC) test EXTRA_DIST = \ diff --git a/configure.in b/configure.in index f8ae501..68f8b5f 100644 --- a/configure.in +++ b/configure.in @@ -542,6 +542,7 @@ fc-cache/Makefile fc-cat/Makefile fc-list/Makefile fc-match/Makefile +fc-missingglyph/Makefile fc-pattern/Makefile fc-query/Makefile fc-scan/Makefile diff --git a/fc-missingglyph/Makefile.am b/fc-missingglyph/Makefile.am new file mode 100644 index 0000000..166490f --- /dev/null +++ b/fc-missingglyph/Makefile.am @@ -0,0 +1,60 @@ +# +# fontconfig/fc-misingglyph/Makefile.am +# +# 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 Keith Packard not be used in +# advertising or publicity pertaining to distribution of the software without +# specific, written prior permission. Keith Packard makes 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. + +bin_PROGRAMS=fc-missingglyph + +DOC2MAN = docbook2man + +FC_MISSINGGLYPH_SRC=${top_srcdir}/fc-missingglyph + +SGML = ${FC_MISSINGGLYPH_SRC}/fc-missingglyph.sgml + +INCLUDES=-I${top_srcdir} $(WARN_CFLAGS) + +BUILT_MANS=fc-missingglyph.1 + +if ENABLE_DOCS +man_MANS=${BUILT_MANS} +endif + +EXTRA_DIST=fc-missingglyph.sgml $(BUILT_MANS) + +fc_missingglyph_LDADD = ${top_builddir}/src/libfontconfig.la $(FREETYPE_LIBS) +fc_missingglyph_CFLAGS = -I${top_srcdir}/src $(FREETYPE_CFLAGS) + +if USEDOCBOOK + +${man_MANS}: ${SGML} + $(RM) $@ + $(DOC2MAN) ${SGML} + $(RM) manpage.* + +all-local: $(man_MANS) + +clean-local: + $(RM) $(man_MANS) + +else +all-local: +clean-local: +endif diff --git a/fc-missingglyph/fc-missingglyph.c b/fc-missingglyph/fc-missingglyph.c new file mode 100644 index 0000000..7e0b467 --- /dev/null +++ b/fc-missingglyph/fc-missingglyph.c @@ -0,0 +1,250 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * fontconfig/fc-missingglyph/fc-missingglyph.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 Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes 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. + */ + +#ifdef HAVE_CONFIG_H +#include +#else +#ifdef linux +#define HAVE_GETOPT_LONG 1 +#endif +#define HAVE_GETOPT 1 +#endif + +#define ___GNUC___ __GNUC__ +#undef __GNUC__ +#include "fcint.h" +#define __GNUC__ ___GNUC___ +#undef ___GNUC___ +#include "fontconfig/fontconfig.h" +#include +#include +#include +#include +#include +#include FT_FREETYPE_H + +#ifndef HAVE_GETOPT +#define HAVE_GETOPT 0 +#endif +#ifndef HAVE_GETOPT_LONG +#define HAVE_GETOPT_LONG 0 +#endif + +#if HAVE_GETOPT_LONG +#undef _GNU_SOURCE +#define _GNU_SOURCE +#include +static const struct option longopts[] = { + {"version", 0, 0, 'V'}, + {"help", 0, 0, 'h'}, + {"lang", 1, 0, 'l'}, + {"verbose", 0, 0, 'v'}, + {NULL,0,0,0}, +}; +#else +#if HAVE_GETOPT +extern char *optarg; +extern int optind, opterr, optopt; +#endif +#endif + +static void +usage (char *program, int error) +{ + FILE *file = error ? stderr : stdout; +#if HAVE_GETOPT_LONG + fprintf (file, "usage: %s [-Vhv] [-l LANG] [--lang=LANG] [--verbose] [--version] [--help] font-file...\n", + program); +#else + fprintf (file, "usage: %s [-Vhv] [-l LANG] font-file...\n", + program); +#endif + fprintf (file, "List missing glyphs for LANG\n"); + fprintf (file, "\n"); +#if HAVE_GETOPT_LONG + fprintf (file, " -V, --version display font config version and exit\n"); + fprintf (file, " -l, --lang=LANG use LANG to check the glyph coverage\n"); + fprintf (file, " -v, --verbose display entire glyph coverage in the font\n"); + fprintf (file, " -h, --help display this help and exit\n"); +#else + fprintf (file, " -V (version) display font config version and exit\n"); + fprintf (file, " -l LANG (lang) perform config substitution on pattern\n"); + fprintf (file, " -v, (verbose) display entire glyph coverage in the font\n"); + fprintf (file, " -h (help) display this help and exit\n"); +#endif + exit (error); +} + +int +main (int argc, char **argv) +{ + int do_verbose = 0; + FcChar8 *lang = NULL, *llcc = NULL; + int h, i, j, k; + const FcCharSet *charset; + FT_Library ftlib; + FT_Face face; + intptr_t *leaves; + FcChar16 *numbers; +#if HAVE_GETOPT_LONG || HAVE_GETOPT + int c; + + setlocale (LC_ALL, ""); +#if HAVE_GETOPT_LONG + while ((c = getopt_long (argc, argv, "Vhl:v", longopts, NULL)) != -1) +#else + while ((c = getopt (argc, argv, "Vhl:v")) != -1) +#endif + { + switch (c) { + case 'V': + fprintf (stderr, "fontconfig version %d.%d.%d\n", + FC_MAJOR, FC_MINOR, FC_REVISION); + exit (0); + case 'h': + usage (argv[0], 0); + case 'l': + lang = (FcChar8 *) strdup (optarg); + break; + case 'v': + do_verbose = 1; + break; + default: + usage (argv[0], 1); + } + } + h = optind; +#else + h = 1; +#endif + + if (h == argc) + usage (argv[0], 1); + + if (!FcInit ()) { + fprintf (stderr, "Can't init font config library\n"); + return 1; + } + if (FT_Init_FreeType (&ftlib)) { + fprintf (stderr, "Can't init FreeType library\n"); + return 1; + } + if (!lang) { + char *l, *ll, *p; + + l = setlocale(LC_CTYPE, NULL); + if (l == NULL || l[0] == 'C') { + fprintf(stderr, "Unable to guess the language from current locale. please use -l option instead."); + return 1; + } + ll = strdup (l); + p = strchr (ll, '.'); + if (p) + *p = 0; + p = strchr (ll, '@'); + if (p) + *p = 0; + p = strchr (ll, '_'); + if (p) + *p = '-'; + for (p = ll; *p; p++) + *p = tolower(*p); + llcc = (FcChar8 *) strdup (ll); + p = strchr(ll, '-'); + if (p) { + *p = 0; + lang = (FcChar8 *) strdup (ll); + } else { + lang = llcc; + llcc = NULL; + } + free(ll); + } + + retry_charset: + charset = FcLangGetCharSet (lang); + if (charset == NULL) { + if (llcc) { + free(lang); + lang = llcc; + llcc = NULL; + goto retry_charset; + } + fprintf (stderr, "Unable to obtain character sets for lang %s\n", lang); + return 1; + } + leaves = FcCharSetLeaves (charset); + numbers = FcCharSetNumbers (charset); + for (; h < argc; h++) { + const FcChar8 *file = (FcChar8 *) argv[h]; + int idx = 0, idx_count = 1; + + do { + if (FT_New_Face (ftlib, (const char *) file, idx, &face)) { + fprintf (stderr, "Unable to open %s\n", file); + break; + } + if (!idx) + idx_count = face->num_faces; + if (do_verbose) { + printf ("Font file: %s\n", file); + printf ("Face(s): %d/%d\n", idx + 1, idx_count); + printf ("Family: %s\n", face->family_name); + printf ("Lang: %s\n", lang); + } + for (i = 0; i < charset->num; i++) { + intptr_t leaf_offset = leaves[i]; + FcCharLeaf *leaf = FcOffsetToPtr (leaves, leaf_offset, FcCharLeaf); + + for (j = 0; j < 256/32; j++) { + FcChar32 x = leaf->map[j]; + + for (k = 0; k < 32; k++) { + if ((x & 1)) { + FcChar32 c = (numbers[i] << 8) | (j << 5) | k; + + if (!FT_Get_Char_Index (face, c)) { + printf ("%sU+%x\n", do_verbose ? "missing " : " ", c); + } else { + if (do_verbose) + printf (" U+%x\n", c); + } + } + x >>= 1; + } + } + } + FT_Done_Face (face); + } while (++idx < idx_count); + } + if (lang) + free(lang); + if (llcc) + free(llcc); + + FcFini (); + + return 0; +} diff --git a/fc-missingglyph/fc-missingglyph.sgml b/fc-missingglyph/fc-missingglyph.sgml new file mode 100644 index 0000000..d6f0425 --- /dev/null +++ b/fc-missingglyph/fc-missingglyph.sgml @@ -0,0 +1,180 @@ + manpage.1'. You may view + the manual page with: `docbook-to-man manpage.sgml | nroff -man | + less'. A typical entry in a Makefile or Makefile.am is: + +manpage.1: manpage.sgml + docbook-to-man $< > $@ + + + The docbook-to-man binary is found in the docbook-to-man package. + Please remember that if you create the nroff version in one of the + debian/rules file targets (such as build), you will need to include + docbook-to-man in your Build-Depends control field. + + --> + + + Akira"> + TAGOH"> + + Jul 30, 2010"> + + 1"> + akira@tagoh.org"> + + fc-missingglyph"> + + + GNU"> + GPL"> +]> + + + +
+ &dhemail; +
+ + &dhfirstname; + &dhsurname; + + + 2010 + &dhusername; + + &dhdate; +
+ + &dhucpackage; + + &dhsection; + + + &dhpackage; + + indicate missing glyphs in font files + + + + &dhpackage; + + + + + + + + + + + + + + + + DESCRIPTION + + &dhpackage; indicates + which glyphs are missing in file(s) + to be used for the language lang. + + + + OPTIONS + + This program follows the usual &gnu; command line syntax, + with long options starting with two dashes (`-'). A summary of + options is included below. + + + + + + + + Show version of the program and exit. + + + + + + + + + Check a character set for lang instead of the default one from current locale. + + + + + + + + Show entire character code that file(s) actually have. + + + + + + + Show summary of options. + + + + + + + Check file recursively for font faces. + + + + + + + RETURN CODES + fc-missingglyph returns error code 0 if at least one font + was found or 1 otherwise. + + + + SEE ALSO + + + fc-query(1) + fc-cat(1) + fc-cache(1) + fc-match(1) + fc-pattern(1) + + + The fontconfig user's guide, in HTML format: + /usr/share/doc/fontconfig/fontconfig-user.html. + + + + AUTHOR + + This manual page was updated by &dhusername; &dhemail;. + + +
+ + -- 1.7.2