/* ======================================================================================== * FontConfig (unix) support * ======================================================================================== */ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face) { FT_Error err = FT_Err_Cannot_Open_Resource; if (!FcInit()) { ShowInfoF("Unable to load font configuration"); } else { FcPattern *match; FcPattern *pat; FcFontSet *fs; FcResult result; char *font_style; char *font_family; /* Split & strip the font's style */ font_family = stredup(font_name); font_style = strchr(font_family, ','); if (font_style != NULL) { font_style[0] = '\0'; font_style++; while (*font_style == ' ' || *font_style == '\t') font_style++; } /* Resolve the name and populate the information structure */ pat = FcNameParse((FcChar8*)font_family); if (font_style != NULL) FcPatternAddString(pat, FC_STYLE, (FcChar8*)font_style); FcConfigSubstitute(0, pat, FcMatchPattern); FcDefaultSubstitute(pat); fs = FcFontSetCreate(); match = FcFontMatch(0, pat, &result); if (fs != NULL && match != NULL) { int i; FcChar8 *family; FcChar8 *style; FcChar8 *file; FcFontSetAdd(fs, match); for (i = 0; err != FT_Err_Ok && i < fs->nfont; i++) { /* Try the new filename */ if (FcPatternGetString(fs->fonts[i], FC_FILE, 0, &file) == FcResultMatch && FcPatternGetString(fs->fonts[i], FC_FAMILY, 0, &family) == FcResultMatch && FcPatternGetString(fs->fonts[i], FC_STYLE, 0, &style) == FcResultMatch) { /* The correct style? */ if (font_style != NULL && strcasecmp(font_style, (char*)style) != 0) continue; /* Font config takes the best shot, which, if the family name is spelled * wrongly a 'random' font, so check whether the family name is the * same as the supplied name */ if (strcasecmp(font_family, (char*)family) == 0) { err = FT_New_Face(_library, (char *)file, 0, face); } } } } free(font_family); FcPatternDestroy(pat); FcFontSetDestroy(fs); FcFini(); } return err; }
int main (int argc, char **argv) { int verbose = 0; int sort = 0; int i; FcFontSet *fs; FcPattern *pat; FcResult result; #if HAVE_GETOPT_LONG || HAVE_GETOPT int c; #if HAVE_GETOPT_LONG while ((c = getopt_long (argc, argv, "Vv?", longopts, NULL)) != -1) #else while ((c = getopt (argc, argv, "sVv?")) != -1) #endif { switch (c) { case 's': sort = 1; break; case 'V': fprintf (stderr, "fontconfig version %d.%d.%d\n", FC_MAJOR, FC_MINOR, FC_REVISION); exit (0); case 'v': verbose = 1; break; default: usage (argv[0]); } } i = optind; #else i = 1; #endif if (!FcInit ()) { fprintf (stderr, "Can't init font config library\n"); return 1; } if (argv[i]) pat = FcNameParse ((FcChar8 *) argv[i]); else pat = FcPatternCreate (); FcConfigSubstitute (0, pat, FcMatchPattern); FcDefaultSubstitute (pat); if (sort) fs = FcFontSort (0, pat, FcTrue, 0, &result); else { FcPattern *match; fs = FcFontSetCreate (); match = FcFontMatch (0, pat, &result); if (match) FcFontSetAdd (fs, match); } if (pat) FcPatternDestroy (pat); if (fs) { int j; for (j = 0; j < fs->nfont; j++) { if (verbose) { FcPatternPrint (fs->fonts[j]); } else { FcChar8 *family; FcChar8 *style; FcChar8 *file; if (FcPatternGetString (fs->fonts[j], FC_FILE, 0, &file) != FcResultMatch) file = "<unknown filename>"; else { FcChar8 *slash = strrchr (file, '/'); if (slash) file = slash+1; } if (FcPatternGetString (fs->fonts[j], FC_FAMILY, 0, &family) != FcResultMatch) family = "<unknown family>"; if (FcPatternGetString (fs->fonts[j], FC_STYLE, 0, &style) != FcResultMatch) file = "<unknown style>"; printf ("%s: \"%s\" \"%s\"\n", file, family, style); } } FcFontSetDestroy (fs); } return 0; }
void FontCache::platformInit() { // It's fine to call FcInit multiple times per the documentation. if (!FcInit()) ASSERT_NOT_REACHED(); }
/** * \brief Init fontconfig. * \param library libass library object * \param ftlibrary freetype library object * \param family default font family * \param path default font path * \return pointer to fontconfig private data */ fc_instance_t* fontconfig_init(ass_library_t* library, FT_Library ftlibrary, const char* family, const char* path, int fc) { int rc; fc_instance_t* priv = calloc(1, sizeof(fc_instance_t)); const char* dir = library->fonts_dir; int i; if (!fc) { mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FontconfigDisabledDefaultFontWillBeUsed); goto exit; } rc = FcInit(); assert(rc); priv->config = FcConfigGetCurrent(); if (!priv->config) { mp_msg(MSGT_ASS, MSGL_FATAL, MSGTR_LIBASS_FcInitLoadConfigAndFontsFailed); goto exit; } for (i = 0; i < library->num_fontdata; ++i) process_fontdata(priv, library, ftlibrary, i); if (dir) { if (FcDirCacheValid((const FcChar8 *)dir) == FcFalse) { mp_msg(MSGT_ASS, MSGL_INFO, MSGTR_LIBASS_UpdatingFontCache); if (FcGetVersion() >= 20390 && FcGetVersion() < 20400) mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_BetaVersionsOfFontconfigAreNotSupported); // FontConfig >= 2.4.0 updates cache automatically in FcConfigAppFontAddDir() if (FcGetVersion() < 20390) { FcFontSet* fcs; FcStrSet* fss; fcs = FcFontSetCreate(); fss = FcStrSetCreate(); rc = FcStrSetAdd(fss, (const FcChar8*)dir); if (!rc) { mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FcStrSetAddFailed); goto ErrorFontCache; } rc = FcDirScan(fcs, fss, NULL, FcConfigGetBlanks(priv->config), (const FcChar8 *)dir, FcFalse); if (!rc) { mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FcDirScanFailed); goto ErrorFontCache; } rc = FcDirSave(fcs, fss, (const FcChar8 *)dir); if (!rc) { mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FcDirSave); goto ErrorFontCache; } ErrorFontCache: ; } } rc = FcConfigAppFontAddDir(priv->config, (const FcChar8*)dir); if (!rc) { mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FcConfigAppFontAddDirFailed); } } priv->family_default = family ? strdup(family) : NULL; exit: priv->path_default = path ? strdup(path) : NULL; priv->index_default = 0; return priv; }
// translated to utf8_main int main(int argc, char *argv[]) { int res = 0; #if defined(SDLMAME_X11) && !(SDLMAME_SDL2) XInitThreads(); #endif #if defined(SDLMAME_WIN32) #if !(SDLMAME_SDL2) /* Load SDL dynamic link library */ if ( SDL_Init(SDL_INIT_NOPARACHUTE) < 0 ) { fprintf(stderr, "WinMain() error: %s", SDL_GetError()); return(FALSE); } SDL_SetModuleHandle(GetModuleHandle(NULL)); #endif #endif // disable I/O buffering setvbuf(stdout, (char *) NULL, _IONBF, 0); setvbuf(stderr, (char *) NULL, _IONBF, 0); // FIXME: this should be done differently #ifdef SDLMAME_UNIX sdl_entered_debugger = 0; #if (!defined(SDLMAME_MACOSX)) && (!defined(SDLMAME_HAIKU)) && (!defined(SDLMAME_EMSCRIPTEN)) FcInit(); #endif #endif #ifdef SDLMAME_OS2 MorphToPM(); #endif #if defined(SDLMAME_X11) && (SDL_MAJOR_VERSION == 1) && (SDL_MINOR_VERSION == 2) if (SDL_Linked_Version()->patch < 10) /* workaround for SDL choosing a 32-bit ARGB visual */ { Display *display; if ((display = XOpenDisplay(NULL)) && (DefaultDepth(display, DefaultScreen(display)) >= 24)) { XVisualInfo vi; char buf[130]; if (XMatchVisualInfo(display, DefaultScreen(display), 24, TrueColor, &vi)) { snprintf(buf, sizeof(buf), "0x%lx", vi.visualid); osd_setenv(SDLENV_VISUALID, buf, 0); } } if (display) XCloseDisplay(display); } #endif { sdl_options options; sdl_osd_interface osd(options); osd.register_options(); cli_frontend frontend(options, osd); res = frontend.execute(argc, argv); } #ifdef SDLMAME_UNIX #if (!defined(SDLMAME_MACOSX)) && (!defined(SDLMAME_HAIKU)) && (!defined(SDLMAME_EMSCRIPTEN)) if (!sdl_entered_debugger) { FcFini(); } #endif #endif exit(res); }
static void setupFontconfig() { // We wish to make the layout tests reproducable with respect to fonts. Skia // uses fontconfig to resolve font family names from WebKit into actual font // files found on the current system. This means that fonts vary based on the // system and also on the fontconfig configuration. // // To avoid this we initialise fontconfig here and install a configuration // which only knows about a few, select, fonts. // We have fontconfig parse a config file from our resources file. This // sets a number of aliases ("sans"->"Arial" etc), but doesn't include any // font directories. FcInit(); char drtPath[PATH_MAX + 1]; int drtPathSize = readlink("/proc/self/exe", drtPath, PATH_MAX); if (drtPathSize < 0 || drtPathSize > PATH_MAX) { fputs("Unable to resolve /proc/self/exe.", stderr); exit(1); } drtPath[drtPathSize] = 0; std::string drtDirPath(drtPath); size_t lastPathPos = drtDirPath.rfind("/"); ASSERT(lastPathPos != std::string::npos); drtDirPath.erase(lastPathPos + 1); FcConfig* fontcfg = FcConfigCreate(); std::string fontconfigPath = drtDirPath + "fonts.conf"; if (!FcConfigParseAndLoad(fontcfg, reinterpret_cast<const FcChar8*>(fontconfigPath.c_str()), true)) { fputs("Failed to parse fontconfig config file\n", stderr); exit(1); } // This is the list of fonts that fontconfig will know about. It // will try its best to match based only on the fonts here in. The // paths are where these fonts are found on our Ubuntu boxes. static const char *const fonts[] = { "/usr/share/fonts/truetype/kochi/kochi-gothic.ttf", "/usr/share/fonts/truetype/kochi/kochi-mincho.ttf", "/usr/share/fonts/truetype/msttcorefonts/Arial.ttf", "/usr/share/fonts/truetype/msttcorefonts/Arial_Bold.ttf", "/usr/share/fonts/truetype/msttcorefonts/Arial_Bold_Italic.ttf", "/usr/share/fonts/truetype/msttcorefonts/Arial_Italic.ttf", "/usr/share/fonts/truetype/msttcorefonts/Comic_Sans_MS.ttf", "/usr/share/fonts/truetype/msttcorefonts/Comic_Sans_MS_Bold.ttf", "/usr/share/fonts/truetype/msttcorefonts/Courier_New.ttf", "/usr/share/fonts/truetype/msttcorefonts/Courier_New_Bold.ttf", "/usr/share/fonts/truetype/msttcorefonts/Courier_New_Bold_Italic.ttf", "/usr/share/fonts/truetype/msttcorefonts/Courier_New_Italic.ttf", "/usr/share/fonts/truetype/msttcorefonts/Georgia.ttf", "/usr/share/fonts/truetype/msttcorefonts/Georgia_Bold.ttf", "/usr/share/fonts/truetype/msttcorefonts/Georgia_Bold_Italic.ttf", "/usr/share/fonts/truetype/msttcorefonts/Georgia_Italic.ttf", "/usr/share/fonts/truetype/msttcorefonts/Impact.ttf", "/usr/share/fonts/truetype/msttcorefonts/Trebuchet_MS.ttf", "/usr/share/fonts/truetype/msttcorefonts/Trebuchet_MS_Bold.ttf", "/usr/share/fonts/truetype/msttcorefonts/Trebuchet_MS_Bold_Italic.ttf", "/usr/share/fonts/truetype/msttcorefonts/Trebuchet_MS_Italic.ttf", "/usr/share/fonts/truetype/msttcorefonts/Times_New_Roman.ttf", "/usr/share/fonts/truetype/msttcorefonts/Times_New_Roman_Bold.ttf", "/usr/share/fonts/truetype/msttcorefonts/Times_New_Roman_Bold_Italic.ttf", "/usr/share/fonts/truetype/msttcorefonts/Times_New_Roman_Italic.ttf", "/usr/share/fonts/truetype/msttcorefonts/Verdana.ttf", "/usr/share/fonts/truetype/msttcorefonts/Verdana_Bold.ttf", "/usr/share/fonts/truetype/msttcorefonts/Verdana_Bold_Italic.ttf", "/usr/share/fonts/truetype/msttcorefonts/Verdana_Italic.ttf", // The DejaVuSans font is used by the css2.1 tests. "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf", "/usr/share/fonts/truetype/ttf-indic-fonts-core/lohit_hi.ttf", "/usr/share/fonts/truetype/ttf-indic-fonts-core/lohit_ta.ttf", "/usr/share/fonts/truetype/ttf-indic-fonts-core/MuktiNarrow.ttf", }; for (size_t i = 0; i < arraysize(fonts); ++i) { if (access(fonts[i], R_OK)) { fprintf(stderr, "You are missing %s. Try re-running build/install-build-deps.sh. Also see " "http://code.google.com/p/chromium/wiki/LayoutTestsLinux", fonts[i]); exit(1); } if (!FcConfigAppFontAddFile(fontcfg, (FcChar8 *) fonts[i])) { fprintf(stderr, "Failed to load font %s\n", fonts[i]); exit(1); } } if (!checkAndLoadFontFile(fontcfg, "/usr/share/fonts/truetype/thai/Garuda.ttf", "/usr/share/fonts/truetype/tlwg/Garuda.ttf")) exit(1); // We special case these fonts because they're only needed in a // few layout tests. checkAndLoadFontFile(fontcfg, "/usr/share/fonts/truetype/ttf-indic-fonts-core/lohit_pa.ttf", "/usr/share/fonts/truetype/ttf-punjabi-fonts/lohit_pa.ttf"); // Also load the layout-test-specific "Ahem" font. std::string ahemPath = drtDirPath + "AHEM____.TTF"; if (!FcConfigAppFontAddFile(fontcfg, reinterpret_cast<const FcChar8*>(ahemPath.c_str()))) { fprintf(stderr, "Failed to load font %s\n", ahemPath.c_str()); exit(1); } if (!FcConfigSetCurrent(fontcfg)) { fputs("Failed to set the default font configuration\n", stderr); exit(1); } }
FcFontSet *fcinfo_families_index(const FcPattern *filter) { int unused_int, f, nfamilies; FcPattern *pattern, *match; FcFontSet *fontset, *tmp, *families; FcResult r; FcChar8 *family, *next_family, *normal_style, *style; FcInit(); pattern = FcPatternDuplicate(filter); fontset = fcinfo(NULL, filter, FcFalse, 5, FC_FAMILY, FC_STYLE, FC_LANG,/* fonts like Misc Fixed need to be sorted by LANG (subset-like) */ FC_PIXEL_SIZE, FC_FILE); /* for identifying the best font in FC_LANG terms */ if (fontset->nfont == 0) return fontset; tmp = fcinfo_match(fontset, pattern); FcFontSetDestroy(fontset); fontset = tmp; if (FcPatternGetInteger(pattern, FC_WEIGHT, 0, &unused_int) != FcResultMatch) FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_REGULAR); if (FcPatternGetInteger(pattern, FC_SLANT, 0, &unused_int) != FcResultMatch) FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN); if (FcPatternGetInteger(pattern, FC_WIDTH, 0, &unused_int) != FcResultMatch) FcPatternAddInteger(pattern, FC_WIDTH, FC_WIDTH_NORMAL); /* choose 'normal' styles according to pattern */ families = FcFontSetCreate(); nfamilies = 0; for (f = 0; f < fontset->nfont; ) { assert(fcinfo_get_translated_string(fontset->fonts[f], FC_FAMILY, LANG_EN, &family) == FcResultMatch); FcPatternDel(pattern, FC_FAMILY); FcPatternAddString(pattern, FC_FAMILY, family); match = FcFontSetMatch(NULL, &fontset, 1, pattern, &r); assert(fcinfo_get_translated_string(match, FC_STYLE, LANG_EN, &normal_style) == FcResultMatch); do { assert(fcinfo_get_translated_string(fontset->fonts[f], FC_STYLE, LANG_EN, &style) == FcResultMatch); if (FcStrCmpIgnoreCase(style, normal_style) == 0) FcFontSetAdd(families, FcPatternDuplicate(fontset->fonts[f])); if (++f == fontset->nfont) break; assert(fcinfo_get_translated_string(fontset->fonts[f], FC_FAMILY, LANG_EN, &next_family) == FcResultMatch); } while (FcStrCmpIgnoreCase(family, next_family) == 0); nfamilies++; } FcPatternDestroy(pattern); FcFontSetDestroy(fontset); return families; }
static cairo_test_status_t cairo_test_for_target (cairo_test_context_t *ctx, const cairo_boilerplate_target_t *target, int dev_offset, cairo_bool_t similar) { cairo_test_status_t status; cairo_surface_t *surface = NULL; cairo_t *cr; const char *empty_str = ""; char *offset_str; char *base_name, *base_path; char *out_png_path; char *ref_path = NULL, *ref_png_path, *cmp_png_path = NULL; char *new_path = NULL, *new_png_path; char *xfail_path = NULL, *xfail_png_path; char *base_ref_png_path; char *base_new_png_path; char *base_xfail_png_path; char *diff_png_path; char *test_filename = NULL, *pass_filename = NULL, *fail_filename = NULL; cairo_test_status_t ret; cairo_content_t expected_content; cairo_font_options_t *font_options; const char *format; cairo_bool_t have_output = FALSE; cairo_bool_t have_result = FALSE; void *closure; double width, height; cairo_bool_t have_output_dir; #if HAVE_MEMFAULT int malloc_failure_iterations = ctx->malloc_failure; int last_fault_count = 0; #endif /* Get the strings ready that we'll need. */ format = cairo_boilerplate_content_name (target->content); if (dev_offset) xasprintf (&offset_str, ".%d", dev_offset); else offset_str = (char *) empty_str; xasprintf (&base_name, "%s.%s.%s%s%s", ctx->test_name, target->name, format, similar ? ".similar" : "", offset_str); if (offset_str != empty_str) free (offset_str); ref_png_path = cairo_test_reference_filename (ctx, base_name, ctx->test_name, target->name, target->basename, format, CAIRO_TEST_REF_SUFFIX, CAIRO_TEST_PNG_EXTENSION); new_png_path = cairo_test_reference_filename (ctx, base_name, ctx->test_name, target->name, target->basename, format, CAIRO_TEST_NEW_SUFFIX, CAIRO_TEST_PNG_EXTENSION); xfail_png_path = cairo_test_reference_filename (ctx, base_name, ctx->test_name, target->name, target->basename, format, CAIRO_TEST_XFAIL_SUFFIX, CAIRO_TEST_PNG_EXTENSION); base_ref_png_path = cairo_test_reference_filename (ctx, base_name, ctx->test_name, NULL, NULL, format, CAIRO_TEST_REF_SUFFIX, CAIRO_TEST_PNG_EXTENSION); base_new_png_path = cairo_test_reference_filename (ctx, base_name, ctx->test_name, NULL, NULL, format, CAIRO_TEST_NEW_SUFFIX, CAIRO_TEST_PNG_EXTENSION); base_xfail_png_path = cairo_test_reference_filename (ctx, base_name, ctx->test_name, NULL, NULL, format, CAIRO_TEST_XFAIL_SUFFIX, CAIRO_TEST_PNG_EXTENSION); if (target->file_extension != NULL) { ref_path = cairo_test_reference_filename (ctx, base_name, ctx->test_name, target->name, target->basename, format, CAIRO_TEST_REF_SUFFIX, target->file_extension); new_path = cairo_test_reference_filename (ctx, base_name, ctx->test_name, target->name, target->basename, format, CAIRO_TEST_NEW_SUFFIX, target->file_extension); xfail_path = cairo_test_reference_filename (ctx, base_name, ctx->test_name, target->name, target->basename, format, CAIRO_TEST_XFAIL_SUFFIX, target->file_extension); } have_output_dir = _cairo_test_mkdir (ctx->output); xasprintf (&base_path, "%s/%s", have_output_dir ? ctx->output : ".", base_name); xasprintf (&out_png_path, "%s" CAIRO_TEST_OUT_PNG, base_path); xasprintf (&diff_png_path, "%s" CAIRO_TEST_DIFF_PNG, base_path); if (ctx->test->requirements != NULL) { const char *required; required = target->is_vector ? "target=raster" : "target=vector"; if (strstr (ctx->test->requirements, required) != NULL) { cairo_test_log (ctx, "Error: Skipping for %s target %s\n", target->is_vector ? "vector" : "raster", target->name); ret = CAIRO_TEST_UNTESTED; goto UNWIND_STRINGS; } required = target->is_recording ? "target=!recording" : "target=recording"; if (strstr (ctx->test->requirements, required) != NULL) { cairo_test_log (ctx, "Error: Skipping for %s target %s\n", target->is_recording ? "recording" : "non-recording", target->name); ret = CAIRO_TEST_UNTESTED; goto UNWIND_STRINGS; } } width = ctx->test->width; height = ctx->test->height; if (width && height) { width += dev_offset; height += dev_offset; } #if HAVE_MEMFAULT REPEAT: MEMFAULT_CLEAR_FAULTS (); MEMFAULT_RESET_LEAKS (); ctx->last_fault_count = 0; last_fault_count = MEMFAULT_COUNT_FAULTS (); /* Pre-initialise fontconfig so that the configuration is loaded without * malloc failures (our primary goal is to test cairo fault tolerance). */ #if HAVE_FCINIT FcInit (); #endif MEMFAULT_ENABLE_FAULTS (); #endif have_output = FALSE; have_result = FALSE; /* Run the actual drawing code. */ ret = CAIRO_TEST_SUCCESS; surface = (target->create_surface) (base_path, target->content, width, height, ctx->test->width + 25 * NUM_DEVICE_OFFSETS, ctx->test->height + 25 * NUM_DEVICE_OFFSETS, CAIRO_BOILERPLATE_MODE_TEST, &closure); if (surface == NULL) { cairo_test_log (ctx, "Error: Failed to set %s target\n", target->name); ret = CAIRO_TEST_UNTESTED; goto UNWIND_STRINGS; } #if HAVE_MEMFAULT if (ctx->malloc_failure && MEMFAULT_COUNT_FAULTS () - last_fault_count > 0 && cairo_surface_status (surface) == CAIRO_STATUS_NO_MEMORY) { goto REPEAT; } #endif if (cairo_surface_status (surface)) { MF (MEMFAULT_PRINT_FAULTS ()); cairo_test_log (ctx, "Error: Created an error surface: %s\n", cairo_status_to_string (cairo_surface_status (surface))); ret = CAIRO_TEST_FAILURE; goto UNWIND_STRINGS; } /* Check that we created a surface of the expected type. */ if (cairo_surface_get_type (surface) != target->expected_type) { MF (MEMFAULT_PRINT_FAULTS ()); cairo_test_log (ctx, "Error: Created surface is of type %d (expected %d)\n", cairo_surface_get_type (surface), target->expected_type); ret = CAIRO_TEST_UNTESTED; goto UNWIND_SURFACE; } /* Check that we created a surface of the expected content, * (ignore the artificial CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED value). */ expected_content = cairo_boilerplate_content (target->content); if (cairo_surface_get_content (surface) != expected_content) { MF (MEMFAULT_PRINT_FAULTS ()); cairo_test_log (ctx, "Error: Created surface has content %d (expected %d)\n", cairo_surface_get_content (surface), expected_content); ret = CAIRO_TEST_FAILURE; goto UNWIND_SURFACE; } if (cairo_surface_set_user_data (surface, &cairo_boilerplate_output_basename_key, base_path, NULL)) { #if HAVE_MEMFAULT cairo_surface_destroy (surface); if (target->cleanup) target->cleanup (closure); goto REPEAT; #else ret = CAIRO_TEST_FAILURE; goto UNWIND_SURFACE; #endif } cairo_surface_set_device_offset (surface, dev_offset, dev_offset); cr = cairo_create (surface); if (cairo_set_user_data (cr, &_cairo_test_context_key, (void*) ctx, NULL)) { #if HAVE_MEMFAULT cairo_destroy (cr); cairo_surface_destroy (surface); if (target->cleanup) target->cleanup (closure); goto REPEAT; #else ret = CAIRO_TEST_FAILURE; goto UNWIND_CAIRO; #endif } if (similar) cairo_push_group_with_content (cr, expected_content); /* Clear to transparent (or black) depending on whether the target * surface supports alpha. */ cairo_save (cr); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); cairo_restore (cr); /* Set all components of font_options to avoid backend differences * and reduce number of needed reference images. */ font_options = cairo_font_options_create (); cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_NONE); cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_ON); cairo_font_options_set_antialias (font_options, CAIRO_ANTIALIAS_GRAY); cairo_set_font_options (cr, font_options); cairo_font_options_destroy (font_options); cairo_save (cr); alarm (ctx->timeout); status = (ctx->test->draw) (cr, ctx->test->width, ctx->test->height); alarm (0); cairo_restore (cr); if (similar) { cairo_pop_group_to_source (cr); cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_paint (cr); } #if HAVE_MEMFAULT MEMFAULT_DISABLE_FAULTS (); /* repeat test after malloc failure injection */ if (ctx->malloc_failure && MEMFAULT_COUNT_FAULTS () - last_fault_count > 0 && (status == CAIRO_TEST_NO_MEMORY || cairo_status (cr) == CAIRO_STATUS_NO_MEMORY || cairo_surface_status (surface) == CAIRO_STATUS_NO_MEMORY)) { cairo_destroy (cr); cairo_surface_destroy (surface); if (target->cleanup) target->cleanup (closure); cairo_debug_reset_static_data (); #if HAVE_FCFINI FcFini (); #endif if (MEMFAULT_COUNT_LEAKS () > 0) { MEMFAULT_PRINT_FAULTS (); MEMFAULT_PRINT_LEAKS (); } goto REPEAT; } #endif /* Then, check all the different ways it could fail. */ if (status) { cairo_test_log (ctx, "Error: Function under test failed\n"); ret = status; goto UNWIND_CAIRO; } #if HAVE_MEMFAULT if (MEMFAULT_COUNT_FAULTS () - last_fault_count > 0 && MEMFAULT_HAS_FAULTS ()) { VALGRIND_PRINTF ("Unreported memfaults..."); MEMFAULT_PRINT_FAULTS (); } #endif if (target->finish_surface != NULL) { #if HAVE_MEMFAULT /* We need to re-enable faults as most recording-surface processing * is done during cairo_surface_finish(). */ MEMFAULT_CLEAR_FAULTS (); last_fault_count = MEMFAULT_COUNT_FAULTS (); MEMFAULT_ENABLE_FAULTS (); #endif /* also check for infinite loops whilst replaying */ alarm (ctx->timeout); status = target->finish_surface (surface); alarm (0); #if HAVE_MEMFAULT MEMFAULT_DISABLE_FAULTS (); if (ctx->malloc_failure && MEMFAULT_COUNT_FAULTS () - last_fault_count > 0 && status == CAIRO_STATUS_NO_MEMORY) { cairo_destroy (cr); cairo_surface_destroy (surface); if (target->cleanup) target->cleanup (closure); cairo_debug_reset_static_data (); #if HAVE_FCFINI FcFini (); #endif if (MEMFAULT_COUNT_LEAKS () > 0) { MEMFAULT_PRINT_FAULTS (); MEMFAULT_PRINT_LEAKS (); } goto REPEAT; } #endif if (status) { cairo_test_log (ctx, "Error: Failed to finish surface: %s\n", cairo_status_to_string (status)); ret = CAIRO_TEST_FAILURE; goto UNWIND_CAIRO; } } /* Skip image check for tests with no image (width,height == 0,0) */ if (ctx->test->width != 0 && ctx->test->height != 0) { cairo_surface_t *ref_image; cairo_surface_t *test_image; cairo_surface_t *diff_image; buffer_diff_result_t result; cairo_status_t diff_status; if (ref_png_path == NULL) { cairo_test_log (ctx, "Error: Cannot find reference image for %s\n", base_name); /* we may be running this test to generate reference images */ _xunlink (ctx, out_png_path); /* be more generous as we may need to use external renderers */ alarm (4 * ctx->timeout); test_image = target->get_image_surface (surface, 0, ctx->test->width, ctx->test->height); alarm (0); diff_status = cairo_surface_write_to_png (test_image, out_png_path); cairo_surface_destroy (test_image); if (diff_status) { if (cairo_surface_status (test_image) == CAIRO_STATUS_INVALID_STATUS) ret = CAIRO_TEST_CRASHED; else ret = CAIRO_TEST_FAILURE; cairo_test_log (ctx, "Error: Failed to write output image: %s\n", cairo_status_to_string (diff_status)); } have_output = TRUE; ret = CAIRO_TEST_XFAILURE; goto UNWIND_CAIRO; } if (target->file_extension != NULL) { /* compare vector surfaces */ char *filenames[] = { ref_png_path, ref_path, new_png_path, new_path, xfail_png_path, xfail_path, base_ref_png_path, base_new_png_path, base_xfail_png_path, }; xasprintf (&test_filename, "%s.out%s", base_path, target->file_extension); xasprintf (&pass_filename, "%s.pass%s", base_path, target->file_extension); xasprintf (&fail_filename, "%s.fail%s", base_path, target->file_extension); if (cairo_test_file_is_older (pass_filename, filenames, ARRAY_SIZE (filenames))) { _xunlink (ctx, pass_filename); } if (cairo_test_file_is_older (fail_filename, filenames, ARRAY_SIZE (filenames))) { _xunlink (ctx, fail_filename); } if (cairo_test_files_equal (out_png_path, ref_path)) { cairo_test_log (ctx, "Vector surface matches reference.\n"); have_output = FALSE; ret = CAIRO_TEST_SUCCESS; goto UNWIND_CAIRO; } if (cairo_test_files_equal (out_png_path, new_path)) { cairo_test_log (ctx, "Vector surface matches current failure.\n"); have_output = FALSE; ret = CAIRO_TEST_NEW; goto UNWIND_CAIRO; } if (cairo_test_files_equal (out_png_path, xfail_path)) { cairo_test_log (ctx, "Vector surface matches known failure.\n"); have_output = FALSE; ret = CAIRO_TEST_XFAILURE; goto UNWIND_CAIRO; } if (cairo_test_files_equal (test_filename, pass_filename)) { /* identical output as last known PASS */ cairo_test_log (ctx, "Vector surface matches last pass.\n"); have_output = TRUE; ret = CAIRO_TEST_SUCCESS; goto UNWIND_CAIRO; } if (cairo_test_files_equal (test_filename, fail_filename)) { /* identical output as last known FAIL, fail */ cairo_test_log (ctx, "Vector surface matches last fail.\n"); have_result = TRUE; /* presume these were kept around as well */ have_output = TRUE; ret = CAIRO_TEST_FAILURE; goto UNWIND_CAIRO; } } /* be more generous as we may need to use external renderers */ alarm (4 * ctx->timeout); test_image = target->get_image_surface (surface, 0, ctx->test->width, ctx->test->height); alarm (0); if (cairo_surface_status (test_image)) { cairo_test_log (ctx, "Error: Failed to extract image: %s\n", cairo_status_to_string (cairo_surface_status (test_image))); if (cairo_surface_status (test_image) == CAIRO_STATUS_INVALID_STATUS) ret = CAIRO_TEST_CRASHED; else ret = CAIRO_TEST_FAILURE; cairo_surface_destroy (test_image); goto UNWIND_CAIRO; } _xunlink (ctx, out_png_path); diff_status = cairo_surface_write_to_png (test_image, out_png_path); if (diff_status) { cairo_test_log (ctx, "Error: Failed to write output image: %s\n", cairo_status_to_string (diff_status)); cairo_surface_destroy (test_image); ret = CAIRO_TEST_FAILURE; goto UNWIND_CAIRO; } have_output = TRUE; /* binary compare png files (no decompression) */ if (target->file_extension == NULL) { char *filenames[] = { ref_png_path, new_png_path, xfail_png_path, base_ref_png_path, base_new_png_path, base_xfail_png_path, }; xasprintf (&test_filename, "%s", out_png_path); xasprintf (&pass_filename, "%s.pass.png", base_path); xasprintf (&fail_filename, "%s.fail.png", base_path); if (cairo_test_file_is_older (pass_filename, filenames, ARRAY_SIZE (filenames))) { _xunlink (ctx, pass_filename); } if (cairo_test_file_is_older (fail_filename, filenames, ARRAY_SIZE (filenames))) { _xunlink (ctx, fail_filename); } if (cairo_test_files_equal (test_filename, pass_filename)) { cairo_test_log (ctx, "PNG file exactly matches last pass.\n"); have_result = TRUE; cairo_surface_destroy (test_image); ret = CAIRO_TEST_SUCCESS; goto UNWIND_CAIRO; } if (cairo_test_files_equal (out_png_path, ref_png_path)) { cairo_test_log (ctx, "PNG file exactly matches reference image.\n"); have_result = TRUE; cairo_surface_destroy (test_image); ret = CAIRO_TEST_SUCCESS; goto UNWIND_CAIRO; } if (cairo_test_files_equal (out_png_path, new_png_path)) { cairo_test_log (ctx, "PNG file exactly matches current failure image.\n"); have_result = TRUE; cairo_surface_destroy (test_image); ret = CAIRO_TEST_NEW; goto UNWIND_CAIRO; } if (cairo_test_files_equal (out_png_path, xfail_png_path)) { cairo_test_log (ctx, "PNG file exactly matches known failure image.\n"); have_result = TRUE; cairo_surface_destroy (test_image); ret = CAIRO_TEST_XFAILURE; goto UNWIND_CAIRO; } if (cairo_test_files_equal (test_filename, fail_filename)) { cairo_test_log (ctx, "PNG file exactly matches last fail.\n"); have_result = TRUE; /* presume these were kept around as well */ cairo_surface_destroy (test_image); ret = CAIRO_TEST_FAILURE; goto UNWIND_CAIRO; } } else { if (cairo_test_files_equal (out_png_path, ref_png_path)) { cairo_test_log (ctx, "PNG file exactly matches reference image.\n"); have_result = TRUE; cairo_surface_destroy (test_image); ret = CAIRO_TEST_SUCCESS; goto UNWIND_CAIRO; } if (cairo_test_files_equal (out_png_path, new_png_path)) { cairo_test_log (ctx, "PNG file exactly matches current failure image.\n"); have_result = TRUE; cairo_surface_destroy (test_image); ret = CAIRO_TEST_NEW; goto UNWIND_CAIRO; } if (cairo_test_files_equal (out_png_path, xfail_png_path)) { cairo_test_log (ctx, "PNG file exactly matches known failure image.\n"); have_result = TRUE; cairo_surface_destroy (test_image); ret = CAIRO_TEST_XFAILURE; goto UNWIND_CAIRO; } } if (cairo_test_files_equal (out_png_path, base_ref_png_path)) { cairo_test_log (ctx, "PNG file exactly reference image.\n"); have_result = TRUE; cairo_surface_destroy (test_image); ret = CAIRO_TEST_SUCCESS; goto UNWIND_CAIRO; } if (cairo_test_files_equal (out_png_path, base_new_png_path)) { cairo_test_log (ctx, "PNG file exactly current failure image.\n"); have_result = TRUE; cairo_surface_destroy (test_image); ret = CAIRO_TEST_NEW; goto UNWIND_CAIRO; } if (cairo_test_files_equal (out_png_path, base_xfail_png_path)) { cairo_test_log (ctx, "PNG file exactly known failure image.\n"); have_result = TRUE; cairo_surface_destroy (test_image); ret = CAIRO_TEST_XFAILURE; goto UNWIND_CAIRO; } /* first compare against the ideal reference */ ref_image = cairo_test_get_reference_image (ctx, base_ref_png_path, target->content == CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED); if (cairo_surface_status (ref_image)) { cairo_test_log (ctx, "Error: Cannot open reference image for %s: %s\n", base_ref_png_path, cairo_status_to_string (cairo_surface_status (ref_image))); cairo_surface_destroy (test_image); ret = CAIRO_TEST_FAILURE; goto UNWIND_CAIRO; } diff_image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, ctx->test->width, ctx->test->height); cmp_png_path = base_ref_png_path; diff_status = image_diff (ctx, test_image, ref_image, diff_image, &result); _xunlink (ctx, diff_png_path); if (diff_status || image_diff_is_failure (&result, target->error_tolerance)) { /* that failed, so check against the specific backend */ ref_image = cairo_test_get_reference_image (ctx, ref_png_path, target->content == CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED); if (cairo_surface_status (ref_image)) { cairo_test_log (ctx, "Error: Cannot open reference image for %s: %s\n", ref_png_path, cairo_status_to_string (cairo_surface_status (ref_image))); cairo_surface_destroy (test_image); ret = CAIRO_TEST_FAILURE; goto UNWIND_CAIRO; } cmp_png_path = ref_png_path; diff_status = image_diff (ctx, test_image, ref_image, diff_image, &result); if (diff_status) { cairo_test_log (ctx, "Error: Failed to compare images: %s\n", cairo_status_to_string (diff_status)); ret = CAIRO_TEST_FAILURE; } else if (image_diff_is_failure (&result, target->error_tolerance)) { ret = CAIRO_TEST_FAILURE; diff_status = cairo_surface_write_to_png (diff_image, diff_png_path); if (diff_status) { cairo_test_log (ctx, "Error: Failed to write differences image: %s\n", cairo_status_to_string (diff_status)); } else { have_result = TRUE; } cairo_test_copy_file (test_filename, fail_filename); } else { /* success */ cairo_test_copy_file (test_filename, pass_filename); } } else { /* success */ cairo_test_copy_file (test_filename, pass_filename); } /* If failed, compare against the current image output, * and attempt to detect systematic failures. */ if (ret == CAIRO_TEST_FAILURE) { char *image_out_path; image_out_path = cairo_test_reference_filename (ctx, base_name, ctx->test_name, "image", "image", format, CAIRO_TEST_OUT_SUFFIX, CAIRO_TEST_PNG_EXTENSION); if (image_out_path != NULL) { if (cairo_test_files_equal (out_png_path, image_out_path)) { ret = CAIRO_TEST_XFAILURE; } else { ref_image = cairo_image_surface_create_from_png (image_out_path); if (cairo_surface_status (ref_image) == CAIRO_STATUS_SUCCESS) { diff_status = image_diff (ctx, test_image, ref_image, diff_image, &result); if (diff_status == CAIRO_STATUS_SUCCESS && !image_diff_is_failure (&result, target->error_tolerance)) { ret = CAIRO_TEST_XFAILURE; } cairo_surface_destroy (ref_image); } } free (image_out_path); } } cairo_surface_destroy (test_image); cairo_surface_destroy (diff_image); } if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) { cairo_test_log (ctx, "Error: Function under test left cairo status in an error state: %s\n", cairo_status_to_string (cairo_status (cr))); ret = CAIRO_TEST_ERROR; goto UNWIND_CAIRO; } UNWIND_CAIRO: free (test_filename); free (fail_filename); free (pass_filename); test_filename = fail_filename = pass_filename = NULL; #if HAVE_MEMFAULT if (ret == CAIRO_TEST_FAILURE) MEMFAULT_PRINT_FAULTS (); #endif cairo_destroy (cr); UNWIND_SURFACE: cairo_surface_destroy (surface); if (target->cleanup) target->cleanup (closure); #if HAVE_MEMFAULT cairo_debug_reset_static_data (); #if HAVE_FCFINI FcFini (); #endif if (MEMFAULT_COUNT_LEAKS () > 0) { if (ret != CAIRO_TEST_FAILURE) MEMFAULT_PRINT_FAULTS (); MEMFAULT_PRINT_LEAKS (); } if (ret == CAIRO_TEST_SUCCESS && --malloc_failure_iterations > 0) goto REPEAT; #endif if (have_output) cairo_test_log (ctx, "OUTPUT: %s\n", out_png_path); if (have_result) { if (cmp_png_path == NULL) { /* XXX presume we matched the normal ref last time */ cmp_png_path = ref_png_path; } cairo_test_log (ctx, "REFERENCE: %s\nDIFFERENCE: %s\n", cmp_png_path, diff_png_path); } UNWIND_STRINGS: free (out_png_path); free (ref_png_path); free (base_ref_png_path); free (ref_path); free (new_png_path); free (base_new_png_path); free (new_path); free (xfail_png_path); free (base_xfail_png_path); free (xfail_path); free (diff_png_path); free (base_path); free (base_name); return ret; }
int main(int argc, char **argv) { int res = 0; #else /* gee */ extern "C" DECLSPEC void SDLCALL SDL_SetModuleHandle(void *hInst); // translated to utf8_main int main(int argc, char *argv[]) { int res = 0; #if !(SDLMAME_SDL2) /* Load SDL dynamic link library */ if ( SDL_Init(SDL_INIT_NOPARACHUTE) < 0 ) { fprintf(stderr, "WinMain() error: %s", SDL_GetError()); return(FALSE); } SDL_SetModuleHandle(GetModuleHandle(NULL)); #endif #endif // disable I/O buffering setvbuf(stdout, (char *) NULL, _IONBF, 0); setvbuf(stderr, (char *) NULL, _IONBF, 0); #ifdef SDLMAME_UNIX sdl_entered_debugger = 0; #if (!defined(SDLMAME_MACOSX)) && (!defined(SDLMAME_HAIKU)) && (!defined(SDLMAME_EMSCRIPTEN)) #if !(SDLMAME_SDL2) if (TTF_Init() == -1) { printf("SDL_ttf failed: %s\n", TTF_GetError()); } #endif FcInit(); #endif #endif #ifdef SDLMAME_OS2 MorphToPM(); #endif #if defined(SDLMAME_X11) && (SDL_MAJOR_VERSION == 1) && (SDL_MINOR_VERSION == 2) if (SDL_Linked_Version()->patch < 10) /* workaround for SDL choosing a 32-bit ARGB visual */ { Display *display; if ((display = XOpenDisplay(NULL)) && (DefaultDepth(display, DefaultScreen(display)) >= 24)) { XVisualInfo vi; char buf[130]; if (XMatchVisualInfo(display, DefaultScreen(display), 24, TrueColor, &vi)) { snprintf(buf, sizeof(buf), "0x%lx", vi.visualid); osd_setenv(SDLENV_VISUALID, buf, 0); } } if (display) XCloseDisplay(display); } #endif osd_init_midi(); // this is a blues riff in B, watch me for the changes and try to keep up... { sdl_osd_interface osd; sdl_options options; cli_frontend frontend(options, osd); res = frontend.execute(argc, argv); } #ifdef MALLOC_DEBUG { void check_unfreed_mem(void); check_unfreed_mem(); } #endif // already called... //SDL_Quit(); #ifdef SDLMAME_UNIX #if (!defined(SDLMAME_MACOSX)) && (!defined(SDLMAME_HAIKU)) && (!defined(SDLMAME_EMSCRIPTEN)) #if !(SDLMAME_SDL2) TTF_Quit(); #endif if (!sdl_entered_debugger) { FcFini(); } #endif #endif osd_shutdown_midi(); exit(res); return res; }
FcFontSet * fcinfo_match(FcFontSet *fontset, const FcPattern *filter) { int f; FcFontSet *result; FcChar8 *family, *style, *file; FcChar8 *next_family, *next_style; double size; FcBool scalable; FcPattern *pat, *match = NULL; FcResult r; FcInit(); if (fontset->nfont == 0) { result = FcFontSetCreate(); return result; } /* fc-match "Misc Fixed:style=Bold" gives many files with various pixelsizes plus two "encodings" ('general' and 'ISO8859-1', ISO8859-1 is subset of general) we want only one card for family,style pair for MiscFixedBold.html we will take informations from file 9x18B.pcf.gz (biggest size and general encoding) from fcinfo(), fontset is sorted a way that pattern created from 9x18B.pcf.gz comes first in "Misc Fixed:style=Bold" interval (the biggest pixel size and subset of supported languages, see pattern_compare()). */ result = FcFontSetCreate(); for (f = 0; f < fontset->nfont; ) { /* bitmap fonts: */ /* we are here always on the best file in FC_LANG terms */ /* we need it for displaying the widest range of supported languages */ /* identify it by FC_FILE for FcFontMatch() */ if (filter) pat = FcPatternDuplicate(filter); else pat = FcPatternCreate(); assert(fcinfo_get_translated_string(fontset->fonts[f], FC_FAMILY, LANG_EN, &family) == FcResultMatch); FcPatternAddString(pat, FC_FAMILY, family); if (fcinfo_get_translated_string(fontset->fonts[f], FC_STYLE, LANG_EN, &style) == FcResultMatch) FcPatternAddString(pat, FC_STYLE, style); if (FcPatternGetString(fontset->fonts[f], FC_FILE, 0, &file) == FcResultMatch) FcPatternAddString(pat, FC_FILE, file); FcConfigSubstitute(NULL, pat, FcMatchPattern); FcDefaultSubstitute(pat); match = FcFontMatch(NULL, pat, &r); assert(r == FcResultMatch); /* should not be needed: FcConfigSubstitute(NULL, match, FcMatchFont); */ FcPatternDestroy(pat); assert(FcPatternGetBool(match, FC_SCALABLE, 0, &scalable) == FcResultMatch); /* fprintf(stdout, "Family: %s Style: %s\n", next_family, next_style); fprintf(stdout, " %s\n", file);*/ /* figure out sizes font provide (needed for specimen) and skip same */ /* family,style pairs (see e. g. Misc Fixed) */ if (! scalable) { next_family = family; next_style = style; /* unfortunately e. g. 'ETL Fixed' and 'ETL fixed' are present on my system */ while (FcStrCmpIgnoreCase(next_family, family) == 0 && FcStrCmpIgnoreCase(next_style, style) == 0) { if (FcPatternGetDouble(fontset->fonts[f], FC_PIXEL_SIZE, 0, &size) == FcResultMatch) { if (! pattern_contains_size(match, size)) { FcPatternAddDouble(match, FC_PIXEL_SIZE, size); if (FcPatternGetString(fontset->fonts[f], FC_FILE, 0, &file) == FcResultMatch) FcPatternAddString(match, FC_FILE, file); /*fprintf(stdout, " %s\n", file);*/ } } if (f + 1 == fontset->nfont) /* last family,style pair at all */ { f++; break; } assert(fcinfo_get_translated_string(fontset->fonts[f + 1], FC_FAMILY, LANG_EN, &next_family) == FcResultMatch); assert(fcinfo_get_translated_string(fontset->fonts[f + 1], FC_STYLE, LANG_EN, &next_style) == FcResultMatch); f++; } } else /* family Efont Serif Regular is spread (unintentionally) over */ { /* 5 files (Efont Serif <X> should be spread over 2 files, */ /* normal and 'Alternate'), so this is needed anyway: */ FcPatternDel(match, FC_FILE); next_family = family; next_style = style; while (FcStrCmpIgnoreCase(next_family, family) == 0 && FcStrCmpIgnoreCase(next_style, style) == 0) { if (FcPatternGetString(fontset->fonts[f], FC_FILE, 0, &file) == FcResultMatch) FcPatternAddString(match, FC_FILE, file); if (f + 1 == fontset->nfont) /* last family,style pair at all */ { f++; break; } assert(fcinfo_get_translated_string(fontset->fonts[f + 1], FC_FAMILY, LANG_EN, &next_family) == FcResultMatch); assert(fcinfo_get_translated_string(fontset->fonts[f + 1], FC_STYLE, LANG_EN, &next_style) == FcResultMatch); f++; } } /* don't add ethio16f-uni.pcf, johabg16.pcf and similar with reported empty charset */ if (! empty_charset(match)) FcFontSetAdd(result, FcPatternDuplicate(match)); } if (match) FcPatternDestroy(match); return result; }
/* void ft_failure_2s( const char *one, const char *two ) { buffer b = alloc_buffer(one); buffer_append(b,two); val_throw(buffer_to_string(b)); } void ft_failure_v( const char *one, value v ) { buffer b = alloc_buffer(one); val_buffer(b,v); val_throw(buffer_to_string(b)); } */ void fc_init() { if( !FcInit() ) failure("Could not initialize FreeType"); }
int main (int argc, char **argv) { int index_set = 0; int set_index = 0; FcChar8 *format = NULL; int err = 0; int i; FcBlanks *blanks; #if HAVE_GETOPT_LONG || HAVE_GETOPT int c; #if HAVE_GETOPT_LONG while ((c = getopt_long (argc, argv, "i:f:Vh", longopts, NULL)) != -1) #else while ((c = getopt (argc, argv, "i:f:Vh")) != -1) #endif { switch (c) { case 'i': index_set = 1; set_index = atoi (optarg); break; case 'f': format = (FcChar8 *) strdup (optarg); break; case 'V': fprintf (stderr, "fontconfig version %d.%d.%d\n", FC_MAJOR, FC_MINOR, FC_REVISION); exit (0); case 'h': usage (argv[0], 0); default: usage (argv[0], 1); } } i = optind; #else i = 1; #endif if (i == argc) usage (argv[0], 1); if (!FcInit ()) { fprintf (stderr, "Can't init font config library\n"); return 1; } blanks = FcConfigGetBlanks (NULL); for (; i < argc; i++) { int index; int count = 0; index = set_index; do { FcPattern *pat; pat = FcFreeTypeQuery ((FcChar8 *) argv[i], index, blanks, &count); if (pat) { if (format) { FcChar8 *s; s = FcPatternFormat (pat, format); if (s) { printf ("%s", s); free (s); } } else { FcPatternPrint (pat); } FcPatternDestroy (pat); } else { fprintf (stderr, "Can't query face %d of font file %s\n", index, argv[i]); err = 1; } index++; } while (!index_set && index < count); } FcFini (); return err; }
void inititializeFontConfigSetting() { FcInit(); // If a test resulted a font being added or removed via the @font-face rule, then // we want to reset the FontConfig configuration to prevent it from affecting other tests. static int numFonts = 0; FcFontSet* appFontSet = FcConfigGetFonts(0, FcSetApplication); if (appFontSet && numFonts && appFontSet->nfont == numFonts) return; // Load our configuration file, which sets up proper aliases for family // names like sans, serif and monospace. FcConfig* config = FcConfigCreate(); GOwnPtr<gchar> fontConfigFilename(g_build_filename(FONTS_CONF_DIR, "fonts.conf", NULL)); if (!g_file_test(fontConfigFilename.get(), G_FILE_TEST_IS_REGULAR)) g_error("Cannot find fonts.conf at %s\n", fontConfigFilename.get()); if (!FcConfigParseAndLoad(config, reinterpret_cast<FcChar8*>(fontConfigFilename.get()), true)) g_error("Couldn't load font configuration file from: %s", fontConfigFilename.get()); static const char *const fontDirectories[] = { "/usr/share/fonts/truetype/liberation", "/usr/share/fonts/truetype/ttf-liberation", "/usr/share/fonts/liberation", "/usr/share/fonts/truetype/ttf-dejavu", "/usr/share/fonts/dejavu", "/usr/share/fonts/opentype/stix", "/usr/share/fonts/stix" }; static const char *const fontPaths[] = { "LiberationMono-BoldItalic.ttf", "LiberationMono-Bold.ttf", "LiberationMono-Italic.ttf", "LiberationMono-Regular.ttf", "LiberationSans-BoldItalic.ttf", "LiberationSans-Bold.ttf", "LiberationSans-Italic.ttf", "LiberationSans-Regular.ttf", "LiberationSerif-BoldItalic.ttf", "LiberationSerif-Bold.ttf", "LiberationSerif-Italic.ttf", "LiberationSerif-Regular.ttf", "DejaVuSans.ttf", "DejaVuSerif.ttf", // MathML tests require the STIX fonts. "STIXGeneral.otf", "STIXGeneralBolIta.otf", "STIXGeneralBol.otf", "STIXGeneralItalic.otf" }; // TODO: Some tests use Lucida. We should load these as well, once it becomes // clear how to install these fonts easily on Fedora. for (size_t font = 0; font < G_N_ELEMENTS(fontPaths); font++) { bool found = false; for (size_t path = 0; path < G_N_ELEMENTS(fontDirectories); path++) { GOwnPtr<gchar> fullPath(g_build_filename(fontDirectories[path], fontPaths[font], NULL)); if (g_file_test(fullPath.get(), G_FILE_TEST_EXISTS)) { found = true; if (!FcConfigAppFontAddFile(config, reinterpret_cast<const FcChar8*>(fullPath.get()))) g_error("Could not load font at %s!", fullPath.get()); else break; } } if (!found) { GOwnPtr<gchar> directoriesDescription; for (size_t path = 0; path < G_N_ELEMENTS(fontDirectories); path++) directoriesDescription.set(g_strjoin(":", directoriesDescription.release(), fontDirectories[path], NULL)); g_error("Could not find font %s in %s. Either install this font or file a bug " "at http://bugs.webkit.org if it is installed in another location.", fontPaths[font], directoriesDescription.get()); } } // Ahem is used by many layout tests. GOwnPtr<gchar> ahemFontFilename(g_build_filename(FONTS_CONF_DIR, "AHEM____.TTF", NULL)); if (!FcConfigAppFontAddFile(config, reinterpret_cast<FcChar8*>(ahemFontFilename.get()))) g_error("Could not load font at %s!", ahemFontFilename.get()); static const char* fontFilenames[] = { "WebKitWeightWatcher100.ttf", "WebKitWeightWatcher200.ttf", "WebKitWeightWatcher300.ttf", "WebKitWeightWatcher400.ttf", "WebKitWeightWatcher500.ttf", "WebKitWeightWatcher600.ttf", "WebKitWeightWatcher700.ttf", "WebKitWeightWatcher800.ttf", "WebKitWeightWatcher900.ttf", 0 }; for (size_t i = 0; fontFilenames[i]; ++i) { GOwnPtr<gchar> fontFilename(g_build_filename(FONTS_CONF_DIR, "..", "..", "fonts", fontFilenames[i], NULL)); if (!FcConfigAppFontAddFile(config, reinterpret_cast<FcChar8*>(fontFilename.get()))) g_error("Could not load font at %s!", fontFilename.get()); } // A font with no valid Fontconfig encoding to test https://bugs.webkit.org/show_bug.cgi?id=47452 GOwnPtr<gchar> fontWithNoValidEncodingFilename(g_build_filename(FONTS_CONF_DIR, "FontWithNoValidEncoding.fon", NULL)); if (!FcConfigAppFontAddFile(config, reinterpret_cast<FcChar8*>(fontWithNoValidEncodingFilename.get()))) g_error("Could not load font at %s!", fontWithNoValidEncodingFilename.get()); if (!FcConfigSetCurrent(config)) g_error("Could not set the current font configuration!"); numFonts = FcConfigGetFonts(config, FcSetApplication)->nfont; }
FontConfigDirect::FontConfigDirect() : next_file_id_(0) { FcInit(); }
int main(int argc, char* argv[]) { #ifdef Q_WS_X11 FcInit(); WebCore::DumpRenderTree::initializeFonts(); #if QT_VERSION >= 0x040500 QApplication::setGraphicsSystem("raster"); #endif #endif QApplication app(argc, argv); #ifdef Q_WS_X11 QX11Info::setAppDpiY(0, 96); QX11Info::setAppDpiX(0, 96); #endif QFont f("Sans Serif"); f.setPointSize(9); f.setWeight(QFont::Normal); f.setStyle(QFont::StyleNormal); app.setFont(f); app.setStyle(QLatin1String("Plastique")); signal(SIGILL, crashHandler); /* 4: illegal instruction (not reset when caught) */ signal(SIGTRAP, crashHandler); /* 5: trace trap (not reset when caught) */ signal(SIGFPE, crashHandler); /* 8: floating point exception */ signal(SIGBUS, crashHandler); /* 10: bus error */ signal(SIGSEGV, crashHandler); /* 11: segmentation violation */ signal(SIGSYS, crashHandler); /* 12: bad argument to system call */ signal(SIGPIPE, crashHandler); /* 13: write on a pipe with no reader */ signal(SIGXCPU, crashHandler); /* 24: exceeded CPU time limit */ signal(SIGXFSZ, crashHandler); /* 25: exceeded file size limit */ QStringList args = app.arguments(); if (args.count() < 2) { qDebug() << "Usage: DumpRenderTree [-v] filename"; exit(0); } // supress debug output from Qt if not started with -v if (!args.contains(QLatin1String("-v"))) qInstallMsgHandler(messageHandler); WebCore::DumpRenderTree dumper; if (args.contains("--pixel-tests")) dumper.setDumpPixels(true); QString dbDir = QDesktopServices::storageLocation(QDesktopServices::DataLocation) + QDir::separator() + "qtwebkitdrt"; QWebSettings::setOfflineStoragePath(dbDir); QWebDatabase::removeAllDatabases(); if (args.last() == QLatin1String("-")) { dumper.open(); } else { if (!args.last().startsWith("/") && !args.last().startsWith("file:") && !args.last().startsWith("http:") && !args.last().startsWith("https:")) { QString path = QDir::currentPath(); if (!path.endsWith('/')) path.append('/'); args.last().prepend(path); } dumper.open(QUrl(args.last())); } return app.exec(); #ifdef Q_WS_X11 FcConfigSetCurrent(0); #endif }
int main (int argc, char **argv) { int verbose = 0; int sort = 0, all = 0; const FcChar8 *format = NULL; int i; FcObjectSet *os = 0; FcFontSet *fs; FcPattern *pat; FcResult result; #if HAVE_GETOPT_LONG || HAVE_GETOPT int c; #if HAVE_GETOPT_LONG while ((c = getopt_long (argc, argv, "asvf:Vh", longopts, NULL)) != -1) #else while ((c = getopt (argc, argv, "asvf:Vh")) != -1) #endif { switch (c) { case 'a': all = 1; break; case 's': sort = 1; break; case 'v': verbose = 1; break; case 'f': format = (FcChar8 *) strdup (optarg); break; case 'V': fprintf (stderr, "fontconfig version %d.%d.%d\n", FC_MAJOR, FC_MINOR, FC_REVISION); exit (0); case 'h': usage (argv[0], 0); default: usage (argv[0], 1); } } i = optind; #else i = 1; #endif if (!FcInit ()) { fprintf (stderr, "Can't init font config library\n"); return 1; } if (argv[i]) { pat = FcNameParse ((FcChar8 *) argv[i]); while (argv[++i]) { if (!os) os = FcObjectSetCreate (); FcObjectSetAdd (os, argv[i]); } } else pat = FcPatternCreate (); if (!pat) return 1; FcConfigSubstitute (0, pat, FcMatchPattern); FcDefaultSubstitute (pat); fs = FcFontSetCreate (); if (sort || all) { FcFontSet *font_patterns; int j; font_patterns = FcFontSort (0, pat, all ? FcFalse : FcTrue, 0, &result); if (!font_patterns || font_patterns->nfont == 0) { fputs("No fonts installed on the system\n", stderr); return 1; } for (j = 0; j < font_patterns->nfont; j++) { FcPattern *font_pattern; font_pattern = FcFontRenderPrepare (NULL, pat, font_patterns->fonts[j]); if (font_pattern) FcFontSetAdd (fs, font_pattern); } FcFontSetSortDestroy (font_patterns); } else { FcPattern *match; match = FcFontMatch (0, pat, &result); if (match) FcFontSetAdd (fs, match); } FcPatternDestroy (pat); if (!format) { if (os) format = (const FcChar8 *) "%{=unparse}\n"; else format = (const FcChar8 *) "%{=fcmatch}\n"; } if (fs) { int j; for (j = 0; j < fs->nfont; j++) { FcPattern *font; font = FcPatternFilter (fs->fonts[j], os); if (verbose) { FcPatternPrint (font); } else { FcChar8 *s; s = FcPatternFormat (font, format); if (s) { printf ("%s", s); free (s); } } FcPatternDestroy (font); } FcFontSetDestroy (fs); } if (os) FcObjectSetDestroy (os); FcFini (); return 0; }
bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, int winlangid, const char *str) { if (!FcInit()) return false; bool ret = false; /* Fontconfig doesn't handle full language isocodes, only the part * before the _ of e.g. en_GB is used, so "remove" everything after * the _. */ char lang[16]; strecpy(lang, language_isocode, lastof(lang)); char *split = strchr(lang, '_'); if (split != NULL) *split = '\0'; FcPattern *pat; FcPattern *match; FcResult result; FcChar8 *file; FcFontSet *fs; FcValue val; val.type = FcTypeString; val.u.s = (FcChar8*)lang; /* First create a pattern to match the wanted language */ pat = FcPatternCreate(); /* And fill it with the language and other defaults */ if (pat == NULL || !FcPatternAdd(pat, "lang", val, false) || !FcConfigSubstitute(0, pat, FcMatchPattern)) { goto error_pattern; } FcDefaultSubstitute(pat); /* Then create a font set and match that */ match = FcFontMatch(0, pat, &result); if (match == NULL) { goto error_pattern; } /* Find all fonts that do match */ fs = FcFontSetCreate(); FcFontSetAdd(fs, match); /* And take the first, if it exists */ if (fs->nfont <= 0 || FcPatternGetString(fs->fonts[0], FC_FILE, 0, &file)) { goto error_fontset; } strecpy(settings->small_font, (const char*)file, lastof(settings->small_font)); strecpy(settings->medium_font, (const char*)file, lastof(settings->medium_font)); strecpy(settings->large_font, (const char*)file, lastof(settings->large_font)); ret = true; error_fontset: FcFontSetDestroy(fs); error_pattern: if (pat != NULL) FcPatternDestroy(pat); FcFini(); return ret; }
void QFontconfigDatabase::populateFontDatabase() { FcInit(); FcFontSet *fonts; { FcObjectSet *os = FcObjectSetCreate(); FcPattern *pattern = FcPatternCreate(); const char *properties [] = { FC_FAMILY, FC_STYLE, FC_WEIGHT, FC_SLANT, FC_SPACING, FC_FILE, FC_INDEX, FC_LANG, FC_CHARSET, FC_FOUNDRY, FC_SCALABLE, FC_PIXEL_SIZE, FC_WIDTH, FC_FAMILYLANG, #if FC_VERSION >= 20297 FC_CAPABILITY, #endif (const char *)0 }; const char **p = properties; while (*p) { FcObjectSetAdd(os, *p); ++p; } fonts = FcFontList(0, pattern, os); FcObjectSetDestroy(os); FcPatternDestroy(pattern); } for (int i = 0; i < fonts->nfont; i++) populateFromPattern(fonts->fonts[i]); FcFontSetDestroy (fonts); struct FcDefaultFont { const char *qtname; const char *rawname; bool fixed; }; const FcDefaultFont defaults[] = { { "Serif", "serif", false }, { "Sans Serif", "sans-serif", false }, { "Monospace", "monospace", true }, { 0, 0, false } }; const FcDefaultFont *f = defaults; // aliases only make sense for 'common', not for any of the specials QSupportedWritingSystems ws; ws.setSupported(QFontDatabase::Latin); while (f->qtname) { QString familyQtName = QString::fromLatin1(f->qtname); registerFont(familyQtName,QString(),QString(),QFont::Normal,QFont::StyleNormal,QFont::Unstretched,true,true,0,f->fixed,ws,0); registerFont(familyQtName,QString(),QString(),QFont::Normal,QFont::StyleItalic,QFont::Unstretched,true,true,0,f->fixed,ws,0); registerFont(familyQtName,QString(),QString(),QFont::Normal,QFont::StyleOblique,QFont::Unstretched,true,true,0,f->fixed,ws,0); ++f; } //Lighthouse has very lazy population of the font db. We want it to be initialized when //QApplication is constructed, so that the population procedure can do something like this to //set the default font // const FcDefaultFont *s = defaults; // QFont font("Sans Serif"); // font.setPointSize(9); // QApplication::setFont(font); }
XAP_UnixApp::XAP_UnixApp(const char * szAppName) : XAP_App(szAppName), m_dialogFactory(this), m_controlFactory(), m_szTmpFile(NULL) { int fc_inited = FcInit(); UT_UNUSED(fc_inited); // TODO actually deal with the error here UT_ASSERT(fc_inited); _setAbiSuiteLibDir(); memset(&m_geometry, 0, sizeof(m_geometry)); // create an instance of UT_UUIDGenerator or appropriate derrived class _setUUIDGenerator(new UT_UUIDGenerator()); // register graphics allocator GR_GraphicsFactory * pGF = getGraphicsFactory(); UT_ASSERT( pGF ); if(pGF) { bool bSuccess; bSuccess = pGF->registerClass(GR_UnixCairoGraphics::graphicsAllocator, GR_UnixCairoGraphics::graphicsDescriptor, GR_UnixCairoGraphics::s_getClassId()); UT_ASSERT( bSuccess ); if(bSuccess) { pGF->registerAsDefault(GR_UnixCairoGraphics::s_getClassId(), true); } bSuccess = pGF->registerClass(CairoNull_Graphics::graphicsAllocator, CairoNull_Graphics::graphicsDescriptor, CairoNull_Graphics::s_getClassId()); UT_ASSERT( bSuccess ); #if !GTK_CHECK_VERSION(3,0,0) bSuccess = pGF->registerClass(GR_UnixPangoPixmapGraphics::graphicsAllocator, GR_UnixPangoPixmapGraphics::graphicsDescriptor, GR_UnixPangoPixmapGraphics::s_getClassId()); if(bSuccess) { pGF->registerAsDefault(GR_UnixPangoPixmapGraphics::s_getClassId(), false); } UT_ASSERT( bSuccess ); #endif /* We need to link CairoNull_Graphics because the AbiCommand * plugin uses it. * * We do not need to keep an instance of it around though, as the * plugin constructs its own (I wonder if there is a more elegant way * to force the linker into including it). */ { GR_CairoNullGraphicsAllocInfo ai; nullgraphics = (CairoNull_Graphics*) XAP_App::getApp()->newGraphics((UT_uint32)GRID_CAIRO_NULL, ai); delete nullgraphics; nullgraphics = NULL; } } }
/** * grx_font_load_full: * @family: (nullable): the font family name or %NULL * @size: the preferred size in points or -1 for any size * @dpi: the screen resolution or -1 to ignore dpi * @weight: the font weight (e.g. bold) or -1 for any weight * @slant: the font slant (e.g. italic) or -1 for any slant * @width: the font width (e.g. narrow) or -1 for any width * @monospace: set to %TRUE to prefer a monospace font * @lang: (nullable): a RFC-3066-style language code or %NULL * @script: (nullable): an ISO 15924 script code or %NULL * @err: pointer to hold an error * * Loads the font that best matches the parameters. * * Uses fontconfig for font matching. * * Returns: (transfer full) (nullable): the font or %NULL if there was an error */ GrxFont *grx_font_load_full(const gchar *family, gint size, gint dpi, GrxFontWeight weight, GrxFontSlant slant, GrxFontWidth width, gboolean monospace, const gchar *lang, const gchar *script, GError **err) { FcPattern *pattern, *match; FcResult result; GrxFont *font; FcChar8 *file; if (!FcInit()) { g_set_error_literal(err, GRX_ERROR, GRX_ERROR_FONT_ERROR, "Failed to init fontconfig"); return NULL; } pattern = FcPatternCreate(); FcPatternAddBool(pattern, FC_SCALABLE, FcFalse); FcPatternAddBool(pattern, FC_OUTLINE, FcFalse); FcPatternAddString(pattern, FC_FONTFORMAT, (FcChar8 *)"PCF"); if (family) { FcPatternAddString(pattern, FC_FAMILY, (FcChar8 *)family); } if (size >= 0) { FcPatternAddDouble(pattern, FC_SIZE, size); } if (dpi >= 0) { FcPatternAddDouble(pattern, FC_DPI, dpi); } switch (weight) { case GRX_FONT_WEIGHT_REGULAR: FcPatternAddInteger(pattern, FC_WEIGHT, 80); break; case GRX_FONT_WEIGHT_BOLD: FcPatternAddInteger(pattern, FC_WEIGHT, 200); break; } switch (slant) { case GRX_FONT_SLANT_REGULAR: FcPatternAddInteger(pattern, FC_SLANT, 0); break; case GRX_FONT_SLANT_ITALIC: FcPatternAddInteger(pattern, FC_SLANT, 100); break; } switch (width) { case GRX_FONT_WIDTH_NARROW: FcPatternAddInteger(pattern, FC_WIDTH, 75); break; case GRX_FONT_WIDTH_REGULAR: FcPatternAddInteger(pattern, FC_WIDTH, 100); break; case GRX_FONT_WIDTH_WIDE: FcPatternAddInteger(pattern, FC_WIDTH, 125); break; } if (monospace) { FcPatternAddInteger(pattern, FC_SPACING, 100); } if (lang) { FcPatternAddString(pattern, FC_LANG, (FcChar8 *)lang); } if (script) { FcPatternAddCharSet(pattern, FC_CHARSET, script_to_charset(script)); } { FcChar8 *pattern_str; pattern_str = FcNameUnparse(pattern); g_debug("searching for pattern: %s", pattern_str); free(pattern_str); } FcConfigSubstitute(NULL, pattern, FcMatchPattern); FcDefaultSubstitute(pattern); match = FcFontMatch(NULL, pattern, &result); if (!match) { // TODO: use result for better error g_set_error_literal(err, GRX_ERROR, GRX_ERROR_FONT_ERROR, "Failed to find match"); FcPatternDestroy(pattern); return NULL; } if (FcPatternGetString(match, FC_FILE, 0, &file) != FcResultMatch) { g_set_error_literal(err, GRX_ERROR, GRX_ERROR_FONT_ERROR, "Failed to get file name"); FcPatternDestroy(match); FcPatternDestroy(pattern); return NULL; } font = grx_font_load_from_file((gchar *)file, err); FcPatternDestroy(match); FcPatternDestroy(pattern); return font; }
FontInfo * get_font_info_list (int *num) { FcInit(); *num = -1; FcPattern *pat = FcPatternCreate(); if (!pat) { fprintf(stderr, "Create FcPattern Failed\n"); return NULL; } FcObjectSet *os = FcObjectSetBuild( FC_FAMILY, FC_FAMILYLANG, FC_STYLE, FC_FILE, FC_LANG, FC_SPACING, NULL); if (!os) { fprintf(stderr, "Build FcObjectSet Failed\n"); FcPatternDestroy(pat); return NULL; } FcFontSet *fs = FcFontList(0, pat, os); FcObjectSetDestroy(os); FcPatternDestroy(pat); if (!fs) { fprintf(stderr, "List Font Failed\n"); return NULL; } int i; int cnt = 0; FontInfo *list = NULL; for (i = 0; i < fs->nfont; i++) { FontInfo *info = calloc(1, sizeof(FontInfo)); if (!info) { fprintf(stderr, "Alloc memory failed"); continue; } info->family = (char*)FcPatternFormat(fs->fonts[i], (FcChar8*)"%{family}"); info->familylang = (char*)FcPatternFormat(fs->fonts[i], (FcChar8*)"%{familylang}"); info->style = (char*)FcPatternFormat(fs->fonts[i], (FcChar8*)"%{style}"); info->filename = (char*)FcPatternFormat(fs->fonts[i], (FcChar8*)"%{file}"); info->lang = (char*)FcPatternFormat(fs->fonts[i], (FcChar8*)"%{lang}"); info->spacing = (char*)FcPatternFormat(fs->fonts[i], (FcChar8*)"%{spacing}"); if (!info->family || !info->familylang || !info->style || !info->filename || !info->lang || !info->spacing) { font_info_free(info); continue; } FontInfo *tmp = malloc((cnt+1) * sizeof(FontInfo)); if (!tmp) { fprintf(stderr, "Alloc memory failed\n"); font_info_free(info); continue; } memcpy(tmp+cnt, info, sizeof(FontInfo)); free(info); if (cnt != 0 ) { memcpy(tmp, list, cnt * sizeof(FontInfo)); free(list); list = NULL; } list = tmp; tmp = NULL; cnt++; } FcFontSetDestroy(fs); FcFini(); // Error: FcCacheFini *num = cnt; return list; }
void initializeFontConfigSetting() { if (g_getenv("WEBKIT_SKIP_WEBKITTESTRUNNER_FONTCONFIG_INITIALIZATION")) return; FcInit(); // If a test resulted a font being added or removed via the @font-face rule, then // we want to reset the FontConfig configuration to prevent it from affecting other tests. static int numFonts = 0; FcFontSet* appFontSet = FcConfigGetFonts(0, FcSetApplication); if (appFontSet && numFonts && appFontSet->nfont == numFonts) return; // Load our configuration file, which sets up proper aliases for family // names like sans, serif and monospace. FcConfig* config = FcConfigCreate(); GOwnPtr<gchar> fontConfigFilename(g_build_filename(FONTS_CONF_DIR, "fonts.conf", NULL)); if (!g_file_test(fontConfigFilename.get(), G_FILE_TEST_IS_REGULAR)) g_error("Cannot find fonts.conf at %s\n", fontConfigFilename.get()); if (!FcConfigParseAndLoad(config, reinterpret_cast<FcChar8*>(fontConfigFilename.get()), true)) g_error("Couldn't load font configuration file from: %s", fontConfigFilename.get()); CString fontsPath = getFontsPath(); if (fontsPath.isNull()) g_error("Could not locate test fonts at %s. Is WEBKIT_TOP_LEVEL set?", fontsPath.data()); GOwnPtr<GDir> fontsDirectory(g_dir_open(fontsPath.data(), 0, 0)); while (const char* directoryEntry = g_dir_read_name(fontsDirectory.get())) { if (!g_str_has_suffix(directoryEntry, ".ttf") && !g_str_has_suffix(directoryEntry, ".otf")) continue; GOwnPtr<gchar> fontPath(g_build_filename(fontsPath.data(), directoryEntry, NULL)); if (!FcConfigAppFontAddFile(config, reinterpret_cast<const FcChar8*>(fontPath.get()))) g_error("Could not load font at %s!", fontPath.get()); } // Ahem is used by many layout tests. GOwnPtr<gchar> ahemFontFilename(g_build_filename(FONTS_CONF_DIR, "AHEM____.TTF", NULL)); if (!FcConfigAppFontAddFile(config, reinterpret_cast<FcChar8*>(ahemFontFilename.get()))) g_error("Could not load font at %s!", ahemFontFilename.get()); static const char* fontFilenames[] = { "WebKitWeightWatcher100.ttf", "WebKitWeightWatcher200.ttf", "WebKitWeightWatcher300.ttf", "WebKitWeightWatcher400.ttf", "WebKitWeightWatcher500.ttf", "WebKitWeightWatcher600.ttf", "WebKitWeightWatcher700.ttf", "WebKitWeightWatcher800.ttf", "WebKitWeightWatcher900.ttf", 0 }; for (size_t i = 0; fontFilenames[i]; ++i) { GOwnPtr<gchar> fontFilename(g_build_filename(FONTS_CONF_DIR, "..", "..", "fonts", fontFilenames[i], NULL)); if (!FcConfigAppFontAddFile(config, reinterpret_cast<FcChar8*>(fontFilename.get()))) g_error("Could not load font at %s!", fontFilename.get()); } // A font with no valid Fontconfig encoding to test https://bugs.webkit.org/show_bug.cgi?id=47452 GOwnPtr<gchar> fontWithNoValidEncodingFilename(g_build_filename(FONTS_CONF_DIR, "FontWithNoValidEncoding.fon", NULL)); if (!FcConfigAppFontAddFile(config, reinterpret_cast<FcChar8*>(fontWithNoValidEncodingFilename.get()))) g_error("Could not load font at %s!", fontWithNoValidEncodingFilename.get()); if (!FcConfigSetCurrent(config)) g_error("Could not set the current font configuration!"); numFonts = FcConfigGetFonts(config, FcSetApplication)->nfont; }
int main (int argc, char **argv) { FcChar8 *format = NULL; int i; FcFontSet *fs; #if HAVE_GETOPT_LONG || HAVE_GETOPT int c; #if HAVE_GETOPT_LONG while ((c = getopt_long (argc, argv, "f:Vh", longopts, NULL)) != -1) #else while ((c = getopt (argc, argv, "f:Vh")) != -1) #endif { switch (c) { case 'f': format = (FcChar8 *) strdup (optarg); break; case 'V': fprintf (stderr, "fontconfig version %d.%d.%d\n", FC_MAJOR, FC_MINOR, FC_REVISION); exit (0); case 'h': usage (argv[0], 0); default: usage (argv[0], 1); } } i = optind; #else i = 1; #endif if (i == argc) usage (argv[0], 1); if (!FcInit ()) { fprintf (stderr, "Can't init font config library\n"); return 1; } fs = FcFontSetCreate (); for (; i < argc; i++) { const FcChar8 *file = (FcChar8*) argv[i]; if (!FcFileIsDir (file)) FcFileScan (fs, NULL, NULL, NULL, file, FcTrue); else { FcStrSet *dirs = FcStrSetCreate (); FcStrList *strlist = FcStrListCreate (dirs); do { FcDirScan (fs, dirs, NULL, NULL, file, FcTrue); } while ((file = FcStrListNext (strlist))); FcStrListDone (strlist); FcStrSetDestroy (dirs); } } for (i = 0; i < fs->nfont; i++) { FcPattern *pat; pat = fs->fonts[i]; if (format) { FcChar8 *s; s = FcPatternFormat (pat, format); if (s) { printf ("%s", s); free (s); } } else { FcPatternPrint (pat); } } FcFontSetDestroy (fs); FcFini (); return i > 0 ? 0 : 1; }
void fontconfig_cache_init (void) { FcInit (); }
static void SearchFont(VALUE rbFilePathOrName, VALUE* volatile rbRealFilePath, int* ttcIndex) { *rbRealFilePath = Qnil; if (ttcIndex != NULL) { *ttcIndex = -1; } *rbRealFilePath = strb_GetCompletePath(rbFilePathOrName, false); if (!NIL_P(*rbRealFilePath)) { return; } volatile VALUE rbFontNameSymbol = ID2SYM(rb_intern_str(rbFilePathOrName)); FontFileInfo* info = fontFileInfos; while (info) { if (info->rbFontNameSymbol == rbFontNameSymbol) { *rbRealFilePath = rb_str_new2(rb_id2name(SYM2ID(info->rbFileNameSymbol))); #ifdef WIN32 volatile VALUE rbTemp = rb_str_new2(rb_id2name(SYM2ID(rbWindowsFontDirPathSymbol))); *rbRealFilePath = rb_str_concat(rb_str_cat2(rbTemp, "\\"), *rbRealFilePath); #endif if (ttcIndex != NULL) { *ttcIndex = info->ttcIndex; } return; } info = info->next; } #ifdef HAVE_FONTCONFIG_FONTCONFIG_H if (!FcInit()) { FcFini(); rb_raise(strb_GetStarRubyErrorClass(), "can't initialize fontconfig library"); return; } int nameLength = RSTRING_LEN(rbFilePathOrName) + 1; char name[nameLength]; strncpy(name, StringValueCStr(rbFilePathOrName), nameLength); char* delimiter = strchr(name, ','); char* style = NULL; if (delimiter) { *delimiter = '\0'; style = delimiter + 1; char* nameTail = delimiter - 1; while (*nameTail == ' ') { *nameTail = '\0'; nameTail--; } while (*style == ' ') { style++; } } FcPattern* pattern = FcPatternBuild(NULL, FC_FAMILY, FcTypeString, name, NULL); if (style && 0 < strlen(style)) { FcPatternAddString(pattern, FC_STYLE, (FcChar8*)style); } FcObjectSet* objectSet = FcObjectSetBuild(FC_FAMILY, FC_FILE, NULL); FcFontSet* fontSet = FcFontList(NULL, pattern, objectSet); if (objectSet) { FcObjectSetDestroy(objectSet); } if (pattern) { FcPatternDestroy(pattern); } if (fontSet) { for (int i = 0; i < fontSet->nfont; i++) { FcChar8* fileName = NULL; if (FcPatternGetString(fontSet->fonts[i], FC_FILE, 0, &fileName) == FcResultMatch) { FcChar8* fontName = FcNameUnparse(fontSet->fonts[i]); *rbRealFilePath = rb_str_new2((char*)fileName); volatile VALUE rbFontName = rb_str_new2((char*)fontName); free(fontName); fontName = NULL; if (ttcIndex != NULL && strchr(StringValueCStr(rbFontName), ',')) { *ttcIndex = 0; } } } FcFontSetDestroy(fontSet); } FcFini(); if (!NIL_P(*rbRealFilePath)) { return; } #endif return; }
static int parse_font(AVFilterContext *ctx) { DrawTextContext *s = ctx->priv; #if !CONFIG_LIBFONTCONFIG if (!s->fontfile) { av_log(ctx, AV_LOG_ERROR, "No font filename provided\n"); return AVERROR(EINVAL); } return 0; #else FcPattern *pat, *best; FcResult result = FcResultMatch; FcBool fc_bool; FcChar8* fc_string; int err = AVERROR(ENOENT); if (s->fontfile) return 0; if (!FcInit()) return AVERROR_UNKNOWN; if (!(pat = FcPatternCreate())) return AVERROR(ENOMEM); FcPatternAddString(pat, FC_FAMILY, s->font); FcPatternAddBool(pat, FC_OUTLINE, FcTrue); FcPatternAddDouble(pat, FC_SIZE, (double)s->fontsize); FcDefaultSubstitute(pat); if (!FcConfigSubstitute(NULL, pat, FcMatchPattern)) { FcPatternDestroy(pat); return AVERROR(ENOMEM); } best = FcFontMatch(NULL, pat, &result); FcPatternDestroy(pat); if (!best || result == FcResultNoMatch) { av_log(ctx, AV_LOG_ERROR, "Cannot find a valid font for the family %s\n", s->font); goto fail; } if (FcPatternGetBool(best, FC_OUTLINE, 0, &fc_bool) != FcResultMatch || !fc_bool) { av_log(ctx, AV_LOG_ERROR, "Outline not available for %s\n", s->font); goto fail; } if (FcPatternGetString(best, FC_FAMILY, 0, &fc_string) != FcResultMatch) { av_log(ctx, AV_LOG_ERROR, "No matches for %s\n", s->font); goto fail; } if (FcPatternGetString(best, FC_FILE, 0, &fc_string) != FcResultMatch) { av_log(ctx, AV_LOG_ERROR, "No file path for %s\n", s->font); goto fail; } s->fontfile = av_strdup(fc_string); if (!s->fontfile) err = AVERROR(ENOMEM); else err = 0; fail: FcPatternDestroy(best); return err; #endif }
int main(int argc, char* argv[]) { #ifdef Q_OS_WIN _setmode(1, _O_BINARY); _setmode(2, _O_BINARY); #endif #ifdef Q_WS_X11 FcInit(); WebCore::DumpRenderTree::initializeFonts(); #endif QApplication::setGraphicsSystem("raster"); QApplication::setStyle(new QWindowsStyle); QFont f("Sans Serif"); f.setPointSize(9); f.setWeight(QFont::Normal); f.setStyle(QFont::StyleNormal); QApplication::setFont(f); QApplication app(argc, argv); #ifdef Q_WS_X11 QX11Info::setAppDpiY(0, 96); QX11Info::setAppDpiX(0, 96); #endif #if HAVE(SIGNAL_H) signal(SIGILL, crashHandler); /* 4: illegal instruction (not reset when caught) */ signal(SIGTRAP, crashHandler); /* 5: trace trap (not reset when caught) */ signal(SIGFPE, crashHandler); /* 8: floating point exception */ signal(SIGBUS, crashHandler); /* 10: bus error */ signal(SIGSEGV, crashHandler); /* 11: segmentation violation */ signal(SIGSYS, crashHandler); /* 12: bad argument to system call */ signal(SIGPIPE, crashHandler); /* 13: write on a pipe with no reader */ signal(SIGXCPU, crashHandler); /* 24: exceeded CPU time limit */ signal(SIGXFSZ, crashHandler); /* 25: exceeded file size limit */ #endif QStringList args = app.arguments(); if (args.count() < 2) { qDebug() << "Usage: DumpRenderTree [-v|--pixel-tests] filename [filename2..n]"; qDebug() << "Or folder containing test files: DumpRenderTree [-v|--pixel-tests] dirpath"; exit(0); } // Suppress debug output from Qt if not started with -v if (!args.contains(QLatin1String("-v"))) qInstallMsgHandler(messageHandler); WebCore::DumpRenderTree dumper; if (args.contains(QLatin1String("--pixel-tests"))) dumper.setDumpPixels(true); QWebDatabase::removeAllDatabases(); if (args.contains(QLatin1String("-"))) { QObject::connect(&dumper, SIGNAL(ready()), &dumper, SLOT(readLine()), Qt::QueuedConnection); QTimer::singleShot(0, &dumper, SLOT(readLine())); } else dumper.processArgsLine(args); return app.exec(); #ifdef Q_WS_X11 FcConfigSetCurrent(0); #endif }
bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, int winlangid, MissingGlyphSearcher *callback) { if (!FcInit()) return false; bool ret = false; /* Fontconfig doesn't handle full language isocodes, only the part * before the _ of e.g. en_GB is used, so "remove" everything after * the _. */ char lang[16]; seprintf(lang, lastof(lang), ":lang=%s", language_isocode); char *split = strchr(lang, '_'); if (split != NULL) *split = '\0'; /* First create a pattern to match the wanted language. */ //FcPattern *pat = FcNameParse((FcChar8*)lang); FcPattern *pat = FcPatternCreate(); /* We only want to know the filename. */ FcObjectSet *os = FcObjectSetBuild(FC_FILE, FC_SPACING, FC_SLANT, FC_WEIGHT, NULL); /* Get the list of filenames matching the wanted language. */ FcFontSet *fs = FcFontList(NULL, pat, os); /* We don't need these anymore. */ FcObjectSetDestroy(os); FcPatternDestroy(pat); if (fs != NULL) { int best_weight = -1; const char *best_font = NULL; int best_missing_glypths = 65536; for (int i = 0; i < fs->nfont; i++) { FcPattern *font = fs->fonts[i]; FcChar8 *file = NULL; FcResult res = FcPatternGetString(font, FC_FILE, 0, &file); if (res != FcResultMatch || file == NULL) { continue; } DEBUG(freetype, 1, "Got font %s", file); int missing = 0; /* Get a font with the right spacing .*/ int value = 0; FcPatternGetInteger(font, FC_SPACING, 0, &value); if (callback->Monospace() != (value == FC_MONO) && value != FC_DUAL) missing += 1; /* Do not use those that explicitly say they're slanted. */ FcPatternGetInteger(font, FC_SLANT, 0, &value); if (value != 0) missing += 1; /* We want the fatter font as they look better at small sizes. */ FcPatternGetInteger(font, FC_WEIGHT, 0, &value); if (value <= best_weight) missing += 1; callback->SetFontNames(settings, (const char*)file); missing = callback->FindMissingGlyphs(NULL); DEBUG(freetype, 1, "Font \"%s\" misses %d glyphs for lang %s", file, missing, lang); if (missing < best_missing_glypths) { best_weight = value; best_font = (const char *)file; best_missing_glypths = missing; if (missing == 0) break; } } if (best_font != NULL) { ret = true; callback->SetFontNames(settings, best_font); InitFreeType(callback->Monospace()); DEBUG(freetype, 1, "Selected font %s for lang %s", best_font, lang); } /* Clean up the list of filenames. */ FcFontSetDestroy(fs); } FcFini(); return ret; }
int main(int argc, char* argv[]) { #ifdef Q_WS_X11 FcInit(); FcConfig *config = FcConfigCreate(); QByteArray fontDir = getenv("WEBKIT_TESTFONTS"); if (fontDir.isEmpty() || !QDir(fontDir).exists()) { fprintf(stderr, "\n\n" "--------------------------------------------------------------------\n" "WEBKIT_TESTFONTS environment variable is not set correctly.\n" "This variable has to point to the directory containing the fonts\n" "you can checkout from svn://labs.trolltech.com/svn/webkit/testfonts\n" "--------------------------------------------------------------------\n" ); exit(1); } char currentPath[PATH_MAX+1]; getcwd(currentPath, PATH_MAX); QByteArray configFile = currentPath; configFile += "/WebKitTools/DumpRenderTree/qt/fonts.conf"; if (!FcConfigParseAndLoad (config, (FcChar8*) configFile.data(), true)) qFatal("Couldn't load font configuration file"); if (!FcConfigAppFontAddDir (config, (FcChar8*) fontDir.data())) qFatal("Couldn't add font dir!"); FcConfigSetCurrent(config); #endif QApplication app(argc, argv); #ifdef Q_WS_X11 QX11Info::setAppDpiY(0, 96); QX11Info::setAppDpiX(0, 96); #endif QFont f("Sans Serif"); f.setPointSize(9); f.setWeight(QFont::Normal); f.setStyle(QFont::StyleNormal); app.setFont(f); app.setStyle(QLatin1String("Plastique")); signal(SIGILL, crashHandler); /* 4: illegal instruction (not reset when caught) */ signal(SIGTRAP, crashHandler); /* 5: trace trap (not reset when caught) */ signal(SIGFPE, crashHandler); /* 8: floating point exception */ signal(SIGBUS, crashHandler); /* 10: bus error */ signal(SIGSEGV, crashHandler); /* 11: segmentation violation */ signal(SIGSYS, crashHandler); /* 12: bad argument to system call */ signal(SIGPIPE, crashHandler); /* 13: write on a pipe with no reader */ signal(SIGXCPU, crashHandler); /* 24: exceeded CPU time limit */ signal(SIGXFSZ, crashHandler); /* 25: exceeded file size limit */ QStringList args = app.arguments(); if (args.count() < 2) { qDebug() << "Usage: DumpRenderTree [-v] filename"; exit(0); } // supress debug output from Qt if not started with -v if (!args.contains(QLatin1String("-v"))) qInstallMsgHandler(messageHandler); WebCore::DumpRenderTree dumper; if (args.last() == QLatin1String("-")) { dumper.open(); } else { if (!args.last().startsWith("/") && !args.last().startsWith("file:") && !args.last().startsWith("http:") && !args.last().startsWith("https:")) { QString path = QDir::currentPath(); if (!path.endsWith('/')) path.append('/'); args.last().prepend(path); } dumper.open(QUrl(args.last())); } return app.exec(); #ifdef Q_WS_X11 FcConfigSetCurrent(0); #endif }