summaryrefslogtreecommitdiffstats
path: root/missing-glyph-checker/src/main.c
diff options
context:
space:
mode:
authorAkira TAGOH <akira@tagoh.org>2010-07-12 17:55:40 +0900
committerAkira TAGOH <akira@tagoh.org>2010-07-12 17:55:40 +0900
commitc3d51036009e68d97fcbf9069a4fa956a29c5b28 (patch)
treed4d19d0a09aa1227369e3e01b606e6beb1a580fa /missing-glyph-checker/src/main.c
parent58dfe4a3a564f7a563d3634d98a1878bf254bedc (diff)
downloadfonts-sig-c3d51036009e68d97fcbf9069a4fa956a29c5b28.tar.gz
fonts-sig-c3d51036009e68d97fcbf9069a4fa956a29c5b28.tar.xz
fonts-sig-c3d51036009e68d97fcbf9069a4fa956a29c5b28.zip
small code to check fonts which glyphs are missing comparing to a orth file in fontconfig
Diffstat (limited to 'missing-glyph-checker/src/main.c')
-rw-r--r--missing-glyph-checker/src/main.c181
1 files changed, 181 insertions, 0 deletions
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 <tagoh@redhat.com>
+ *
+ * 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 <locale.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fontconfig/fontconfig.h>
+#include <glib.h>
+#include <ft2build.h>
+#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;
+}