fc-validate.c revision a4e54154
1/* 2 * fontconfig/fc-validate/fc-validate.c 3 * 4 * Copyright © 2003 Keith Packard 5 * Copyright © 2012 Red Hat, Inc. 6 * Red Hat Author(s): Akira TAGOH 7 * 8 * Permission to use, copy, modify, distribute, and sell this software and its 9 * documentation for any purpose is hereby granted without fee, provided that 10 * the above copyright notice appear in all copies and that both that 11 * copyright notice and this permission notice appear in supporting 12 * documentation, and that the name of the author(s) not be used in 13 * advertising or publicity pertaining to distribution of the software without 14 * specific, written prior permission. The authors make no 15 * representations about the suitability of this software for any purpose. It 16 * is provided "as is" without express or implied warranty. 17 * 18 * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 19 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 20 * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR 21 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 22 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 23 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 24 * PERFORMANCE OF THIS SOFTWARE. 25 */ 26 27#ifdef HAVE_CONFIG_H 28#include <config.h> 29#else 30#ifdef linux 31#define HAVE_GETOPT_LONG 1 32#endif 33#define HAVE_GETOPT 1 34#endif 35 36#include <fontconfig/fontconfig.h> 37#include <fontconfig/fcfreetype.h> 38#include <stdio.h> 39#include <stdlib.h> 40#include <string.h> 41#include <locale.h> 42 43#ifdef HAVE_UNISTD_H 44#include <unistd.h> 45#endif 46 47#ifdef ENABLE_NLS 48#include <libintl.h> 49#define _(x) (dgettext(GETTEXT_PACKAGE, x)) 50#else 51#define dgettext(d, s) (s) 52#define _(x) (x) 53#endif 54 55#ifndef HAVE_GETOPT 56#define HAVE_GETOPT 0 57#endif 58#ifndef HAVE_GETOPT_LONG 59#define HAVE_GETOPT_LONG 0 60#endif 61 62#if HAVE_GETOPT_LONG 63#undef _GNU_SOURCE 64#define _GNU_SOURCE 65#include <getopt.h> 66static const struct option longopts[] = { 67 {"index", 1, 0, 'i'}, 68 {"lang", 1, 0, 'l'}, 69 {"verbose", 0, 0, 'v'}, 70 {"version", 0, 0, 'V'}, 71 {"help", 0, 0, 'h'}, 72 {NULL,0,0,0}, 73}; 74#else 75#if HAVE_GETOPT 76extern char *optarg; 77extern int optind, opterr, optopt; 78#endif 79#endif 80 81static void 82usage (char *program, int error) 83{ 84 FILE *file = error ? stderr : stdout; 85#if HAVE_GETOPT_LONG 86 fprintf (file, _("usage: %s [-Vhv] [-i index] [-l LANG] [--index index] [--lang LANG] [--verbose] [--version] [--help] font-file...\n"), 87 program); 88#else 89 fprintf (file, _("usage: %s [-Vhv] [-i index] [-l LANG] font-file...\n"), 90 program); 91#endif 92 fprintf (file, _("Validate font files and print result\n")); 93 fprintf (file, "\n"); 94#if HAVE_GETOPT_LONG 95 fprintf (file, _(" -i, --index INDEX display the INDEX face of each font file only\n")); 96 fprintf (file, _(" -l, --lang=LANG set LANG instead of current locale\n")); 97 fprintf (file, _(" -v, --verbose show more detailed information\n")); 98 fprintf (file, _(" -V, --version display font config version and exit\n")); 99 fprintf (file, _(" -h, --help display this help and exit\n")); 100#else 101 fprintf (file, _(" -i INDEX (index) display the INDEX face of each font file only\n")); 102 fprintf (file, _(" -l LANG (lang) set LANG instead of current locale\n")); 103 fprintf (file, _(" -v (verbose) show more detailed information\n")); 104 fprintf (file, _(" -V (version) display font config version and exit\n")); 105 fprintf (file, _(" -h (help) display this help and exit\n")); 106#endif 107 exit (error); 108} 109 110int 111main (int argc, char **argv) 112{ 113 int index_set = 0; 114 int set_index = 0; 115 FcChar8 *lang = NULL; 116 const FcCharSet *fcs_lang = NULL; 117 int err = 0; 118 int i; 119 FT_Library ftlib; 120 FcBool verbose = FcFalse; 121#if HAVE_GETOPT_LONG || HAVE_GETOPT 122 int c; 123 124 setlocale (LC_ALL, ""); 125 126#if HAVE_GETOPT_LONG 127 while ((c = getopt_long (argc, argv, "i:l:mVhv", longopts, NULL)) != -1) 128#else 129 while ((c = getopt (argc, argv, "i:l:mVhv")) != -1) 130#endif 131 { 132 switch (c) { 133 case 'i': 134 index_set = 1; 135 set_index = atoi (optarg); 136 break; 137 case 'l': 138 lang = (FcChar8 *) FcLangNormalize ((const FcChar8 *) optarg); 139 break; 140 case 'v': 141 verbose = FcTrue; 142 break; 143 case 'V': 144 fprintf (stderr, "fontconfig version %d.%d.%d\n", 145 FC_MAJOR, FC_MINOR, FC_REVISION); 146 exit (0); 147 case 'h': 148 usage (argv[0], 0); 149 default: 150 usage (argv[0], 1); 151 } 152 } 153 i = optind; 154#else 155 i = 1; 156 verbose = FcTrue; 157#endif 158 159 if (i == argc) 160 usage (argv[0], 1); 161 162 if (!lang) 163 lang = FcLangNormalize ((const FcChar8 *) setlocale (LC_CTYPE, NULL)); 164 165 if (lang) 166 fcs_lang = FcLangGetCharSet (lang); 167 168 if (FT_Init_FreeType (&ftlib)) 169 { 170 fprintf (stderr, _("Can't initialize FreeType library\n")); 171 return 1; 172 } 173 174 for (; i < argc; i++) 175 { 176 int index; 177 178 index = set_index; 179 180 do { 181 FT_Face face; 182 FcCharSet *fcs, *fcs_sub; 183 184 if (FT_New_Face (ftlib, argv[i], index, &face)) 185 { 186 if (!index_set && index > 0) 187 break; 188 fprintf (stderr, _("Unable to open %s\n"), argv[i]); 189 err = 1; 190 } 191 else 192 { 193 FcChar32 count; 194 195 fcs = FcFreeTypeCharSet (face, NULL); 196 fcs_sub = FcCharSetSubtract (fcs_lang, fcs); 197 198 count = FcCharSetCount (fcs_sub); 199 if (count > 0) 200 { 201 FcChar32 ucs4, pos, map[FC_CHARSET_MAP_SIZE]; 202 203 err = 1; 204 printf (_("%s:%d Missing %d glyph(s) to satisfy the coverage for %s language\n"), 205 argv[i], index, count, lang); 206 207 if (verbose) 208 { 209 for (ucs4 = FcCharSetFirstPage (fcs_sub, map, &pos); 210 ucs4 != FC_CHARSET_DONE; 211 ucs4 = FcCharSetNextPage (fcs_sub, map, &pos)) 212 { 213 int j; 214 215 for (j = 0; j < FC_CHARSET_MAP_SIZE; j++) 216 { 217 FcChar32 bits = map[j]; 218 FcChar32 base = ucs4 + j * 32; 219 int b = 0; 220 221 while (bits) 222 { 223 if (bits & 1) 224 printf (" 0x%04x\n", base + b); 225 bits >>= 1; 226 b++; 227 } 228 } 229 } 230 } 231 } 232 else 233 { 234 printf (_("%s:%d Satisfy the coverage for %s language\n"), argv[i], index, lang); 235 } 236 237 FcCharSetDestroy (fcs); 238 FcCharSetDestroy (fcs_sub); 239 240 FT_Done_Face (face); 241 } 242 243 index++; 244 } while (index_set == 0); 245 } 246 247 FT_Done_FreeType (ftlib); 248 249 if (lang) 250 FcStrFree (lang); 251 252 FcFini (); 253 return err; 254} 255