From c3d51036009e68d97fcbf9069a4fa956a29c5b28 Mon Sep 17 00:00:00 2001 From: Akira TAGOH Date: Mon, 12 Jul 2010 17:55:40 +0900 Subject: small code to check fonts which glyphs are missing comparing to a orth file in fontconfig --- missing-glyph-checker/src/Makefile.am | 29 ++++++ missing-glyph-checker/src/main.c | 181 ++++++++++++++++++++++++++++++++++ 2 files changed, 210 insertions(+) create mode 100644 missing-glyph-checker/src/Makefile.am create mode 100644 missing-glyph-checker/src/main.c (limited to 'missing-glyph-checker/src') diff --git a/missing-glyph-checker/src/Makefile.am b/missing-glyph-checker/src/Makefile.am new file mode 100644 index 0000000..4cc75c8 --- /dev/null +++ b/missing-glyph-checker/src/Makefile.am @@ -0,0 +1,29 @@ +NULL = +INCLUDES = \ + $(GLIB_CFLAGS) \ + $(FONTCONFIG_CFLAGS) \ + $(FREETYPE_CFLAGS) \ + $(NULL) +LIBS = \ + $(GLIB_LIBS) \ + $(FONTCONFIG_LIBS) \ + $(FREETYPE_LIBS) \ + $(NULL) +EXTRA_DIST = \ + $(NULL) + +DISTCLEANFILES = \ + $(NULL) + +## +# +bin_PROGRAMS = \ + mgc \ + $(NULL) +# +mgc_SOURCES = \ + main.c \ + $(NULL) +# +# +# diff --git a/missing-glyph-checker/src/main.c b/missing-glyph-checker/src/main.c new file mode 100644 index 0000000..c79b0b4 --- /dev/null +++ b/missing-glyph-checker/src/main.c @@ -0,0 +1,181 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * main.c + * Copyright (C) 2010 Red Hat, Inc. + * + * Authors: + * Akira TAGOH + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include FT_FREETYPE_H + +/** from fcint.h **/ +#define FcCharSetLeaves(c) FcOffsetMember(c,leaves_offset,intptr_t) +#define FcCharSetNumbers(c) FcOffsetMember(c,numbers_offset,FcChar16) +#define FcOffsetMember(s,m,t) FcOffsetToPtr(s,(s)->m,t) +#define FcOffsetToPtr(b,o,t) ((t *) ((intptr_t) (b) + (o))) +struct _FcCharSet { + int ref; /* reference count */ + int num; /* size of leaves and numbers arrays */ + intptr_t leaves_offset; + intptr_t numbers_offset; +}; +typedef struct _FcCharLeaf { + FcChar32 map[256/32]; +} FcCharLeaf; + +int +main(int argc, + char **argv) +{ + gchar *arg_lang = NULL; + gboolean arg_verbose = FALSE; + GOptionContext *ctxt = g_option_context_new(NULL); + GOptionEntry entries[] = { + {"lang", 'l', 0, G_OPTION_ARG_STRING, &arg_lang, "Specify the language to check glyphs from fontconfig orth file", "LANG"}, + {"verbose", 'v', 0, G_OPTION_ARG_NONE, &arg_verbose, "more output for debugging", NULL}, + {NULL}, + }; + GError *err = NULL; + gint i, j, k; + GPtrArray *lang_array; + const FcCharSet *charset; + FT_Library ft; + FT_Error fterr; + FT_Face face; + + setlocale(LC_ALL, ""); + g_option_context_add_main_entries(ctxt, entries, NULL); + if (!g_option_context_parse(ctxt, &argc, &argv, &err)) { + if (err) { + g_print("%s (code: %d)\n", + err->message, err->code); + } else { + g_print("Unknown error on parsing options\n"); + } + exit(1); + } + g_option_context_free(ctxt); + + if (argc < 2) { + g_print("No font specified.\n"); + exit(1); + } + lang_array = g_ptr_array_new(); + if (arg_lang == NULL) { + gchar *lang, *s, *p; + + lang = setlocale(LC_CTYPE, NULL); + if (lang == NULL || lang[0] == 'C') { + g_print("E: No lang specified nor unable to guess.\n"); + exit(1); + } + s = g_strdup(lang); + p = strchr(s, '.'); + if (p) + *p = 0; + p = strchr(s, '@'); + if (p) + *p = 0; + p = strchr(s, '_'); + if (p) + *p = '-'; + for (p = s; *p != 0; p++) + *p = g_ascii_tolower(*p); + g_ptr_array_add(lang_array, g_strdup(s)); + p = strchr(s, '-'); + if (p) { + *p = 0; + g_ptr_array_add(lang_array, g_strdup(s)); + } + g_free(s); + } else { + g_ptr_array_add(lang_array, g_strdup(arg_lang)); + } + if (arg_verbose) { + g_print("D: entering in the verbose mode\n"); + g_print("D: target font filename: %s\n", argv[1]); + g_print("D: target lang: "); + for (i = 0; i < lang_array->len; i++) { + g_print("%s ", (gchar *)g_ptr_array_index(lang_array, i)); + } + g_print("\n"); + } + FcInit(); + fterr = FT_Init_FreeType(&ft); + if (fterr) { + g_print("E: Unable to initialize the FreeType library.\n"); + exit(1); + } + fterr = FT_New_Face(ft, argv[1], 0, &face); + if (fterr) { + g_print("E: Unable to obtain the face information for %s\n", argv[1]); + exit(1); + } + + for (i = 0; i < lang_array->len; i++) { + FcChar8 *slang = g_ptr_array_index(lang_array, i); + intptr_t *leaves; + FcChar16 *numbers; + + g_print("I: checking lang `%s'\n", slang); + charset = FcLangGetCharSet(slang); + if (charset == NULL) { + g_print("W: Unable to obtain charset for lang `%s'\n", slang); + continue; + } + leaves = FcCharSetLeaves (charset); + numbers = FcCharSetNumbers (charset); + 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) != 0) { + gunichar c = (numbers[i] << 8) | (j << 5) | k; + + if (FT_Get_Char_Index(face, c) != 0) { + if (arg_verbose) + g_print("I: %x\n", c); + } else { + g_print("W: U+%X [not supported]\n", c); + } + } + x >>= 1; + } + } + } + } + FT_Done_Face(face); + + FcFini(); + + return 0; +} -- cgit