Пример #1
0
MenuGraphic::MenuGraphic(Menu* menu) :
    menu_(menu) {
        const char* fontFamily = "Anonymous Pro";
        const char* fontStyle = "Bold";
        const char* fontSpacing = "Monospace";
        char* font;
        FcPattern* fontPattern = FcPatternCreate();
        FcResult fontResult = FcResultMatch;
        int fontSize = 74;
        FcPatternAddString(fontPattern, FC_FAMILY, 
                (const FcChar8*) fontFamily);
        FcPatternAddDouble(fontPattern, FC_SIZE, fontSize);
        FcPatternAddString(fontPattern, FC_SPACING, 
                (const FcChar8*) fontSpacing);
        FcPatternAddString(fontPattern, FC_STYLE, 
                (const FcChar8*) fontStyle);
        FcDefaultSubstitute(fontPattern);
        FcPattern* fontMatch = FcFontMatch(NULL, fontPattern, &fontResult);
        FcPatternGetString(fontMatch, FC_FILE, 0, (FcChar8**) &font);
        for (int i = 0; i < Menu::NUM_MENU; ++i) {
            // Create a new SubmenuGraphic for each Submenu
            menuGraphics_[i] = new SubmenuGraphic(menu->getMenu(i));
            Submenu* submenu = menu->getMenu(i);
            // Add buttons and labels
            for (std::vector<GuiElement*>::iterator j = 
                    submenu->buttons.begin(); j < submenu->buttons.end(); ++j) {
                labels_.push_back(new Label(font, ((Button*) (*j))->getText(), 
                            fontSize, .5, .1));
                menuGraphics_[i]->addButton((*j), labels_.back(), 
                        (*j)->isSelected());
            }
        }
}
Пример #2
0
// ----------------------------------------- font_manager_match_description ---
char *
font_manager_match_description( font_manager_t * self,
                                const char * family,
                                const float size,
                                const int bold,
                                const int italic )
{
// Use of fontconfig is disabled by default.
#if 1
    return 0;
#else
#  if defined _WIN32 || defined _WIN64
      fprintf( stderr, "\"font_manager_match_description\" not implemented for windows.\n" );
      return 0;
#  endif
    char *filename = 0;
    int weight = FC_WEIGHT_REGULAR;
    int slant = FC_SLANT_ROMAN;
    if ( bold )
    {
        weight = FC_WEIGHT_BOLD;
    }
    if( italic )
    {
        slant = FC_SLANT_ITALIC;
    }
    FcInit();
    FcPattern *pattern = FcPatternCreate();
    FcPatternAddDouble( pattern, FC_SIZE, size );
    FcPatternAddInteger( pattern, FC_WEIGHT, weight );
    FcPatternAddInteger( pattern, FC_SLANT, slant );
    FcPatternAddString( pattern, FC_FAMILY, (FcChar8*) family );
    FcConfigSubstitute( 0, pattern, FcMatchPattern );
    FcDefaultSubstitute( pattern );
    FcResult result;
    FcPattern *match = FcFontMatch( 0, pattern, &result );
    FcPatternDestroy( pattern );

    if ( !match )
    {
        fprintf( stderr, "fontconfig error: could not match family '%s'", family );
        return 0;
    }
    else
    {
        FcValue value;
        FcResult result = FcPatternGet( match, FC_FILE, 0, &value );
        if ( result )
        {
            fprintf( stderr, "fontconfig error: could not match family '%s'", family );
        }
        else
        {
            filename = strdup( (char *)(value.u.s) );
        }
    }
    FcPatternDestroy( match );
    return filename;
#endif
}
Пример #3
0
static void
pk_font_not_found (PangoLanguage *language)
{
	FcPattern *pat = NULL;
	gchar *tag = NULL;
	const gchar *lang;

	g_return_if_fail (language != NULL);

	/* convert to language */
	lang = pango_language_to_string (language);
	if (lang == NULL || lang[0] == '\0') {
		g_warning ("failed to convert language to string");
		goto out;
	}

	/* create the font tag used in as a package provides */
	pat = FcPatternCreate ();
	FcPatternAddString (pat, FC_LANG, (FcChar8 *) lang);
	tag = (gchar *) FcNameUnparse (pat);
	if (tag == NULL || tag[0] == '\0') {
		g_warning ("failed to create font tag: %s", lang);
		goto out;
	}

	/* add to array for processing in idle callback */
	queue_install_fonts_tag (tag);

out:
	if (pat != NULL)
		FcPatternDestroy (pat);
	if (tag != NULL)
		free (tag);
}
Пример #4
0
static void initfonts(void)
{
    FcResult result;
    FcPattern *pat = FcPatternCreate();
    FcPatternAddString(pat, FC_FAMILY, (uint8_t*)"Roboto");
    FcConfigSubstitute(0, pat, FcMatchPattern);
    FcDefaultSubstitute(pat);
    fs = FcFontSort(NULL, pat, 0, &charset, &result);

    FcPatternDestroy(pat);

     #define F(x) (x * SCALE / 2.0)
    font[FONT_TEXT][0] = XftFontOpen(display, screen, XFT_FAMILY, XftTypeString, "Roboto", XFT_PIXEL_SIZE, XftTypeDouble, F(12.0), NULL);

    font[FONT_TITLE][0] = XftFontOpen(display, screen, XFT_FAMILY, XftTypeString, "Roboto", XFT_PIXEL_SIZE, XftTypeDouble, F(12.0), XFT_WEIGHT, XftTypeInteger, FC_WEIGHT_BOLD, NULL);

    font[FONT_SELF_NAME][0] = XftFontOpen(display, screen, XFT_FAMILY, XftTypeString, "Roboto", XFT_PIXEL_SIZE, XftTypeDouble, F(14.0), XFT_WEIGHT, XftTypeInteger, FC_WEIGHT_BOLD, NULL);
    font[FONT_STATUS][0] = XftFontOpen(display, screen, XFT_FAMILY, XftTypeString, "Roboto", XFT_PIXEL_SIZE, XftTypeDouble, F(11.0), NULL);

    font[FONT_LIST_NAME][0] = XftFontOpen(display, screen, XFT_FAMILY, XftTypeString, "Roboto", XFT_PIXEL_SIZE, XftTypeDouble, F(12.0), NULL);

    font[FONT_MSG][0] = XftFontOpen(display, screen, XFT_FAMILY, XftTypeString, "Roboto", XFT_PIXEL_SIZE, XftTypeDouble, F(11.0), XFT_WEIGHT, XftTypeInteger, FC_WEIGHT_LIGHT, NULL);
    font[FONT_MSG_NAME][0] = XftFontOpen(display, screen, XFT_FAMILY, XftTypeString, "Roboto", XFT_PIXEL_SIZE, XftTypeDouble, F(10.0), XFT_WEIGHT, XftTypeInteger, FC_WEIGHT_LIGHT, NULL);
    font[FONT_MISC][0] = XftFontOpen(display, screen, XFT_FAMILY, XftTypeString, "Roboto", XFT_PIXEL_SIZE, XftTypeDouble, F(10.0), NULL);
    font[FONT_MSG_LINK][0] = font[FONT_MSG][0];
    #undef F
}
Пример #5
0
// also handle an xlfd with %d for size?
static char*
makeFontOfSize(char *font, int size, char *fallback)
{
    FcPattern *pattern;
    char *result;

    if (font[0]=='-') {
        char *fname;

        fname = fixXLFD(font, size);
        pattern = XftXlfdParse(fname, False, False);
        wfree(fname);
    } else {
        pattern = FcNameParse(font);
    }

    //FcPatternPrint(pattern);
    if (size > 0) {
        FcPatternDel(pattern, "pixelsize");
        FcPatternAddDouble(pattern, "pixelsize", (double)size);
    } else if (size==0 && !hasProperty(pattern, "size") &&
               !hasProperty(pattern, "pixelsize")) {
        FcPatternAddDouble(pattern, "pixelsize", (double)DEFAULT_SIZE);
    }

    if (fallback && !hasPropertyWithStringValue(pattern, "family", fallback)) {
        FcPatternAddString(pattern, "family", fallback);
    }

    result = FcNameUnparse(pattern);
    FcPatternDestroy(pattern);

    return result;
}
Пример #6
0
FcPattern *fcinfo_get_font(const FcChar8 *request)
{
  FcPattern *pattern, *match;
  FcResult r;
  FcChar8 *string;
  int integer;
  double double_num;

  pattern = fcinfo_name_parse((FcChar8 *) request);
  if (FcPatternGetString(pattern, FC_FAMILY, 0, &string)
      != FcResultMatch)
    FcPatternAddString(pattern, FC_FAMILY, (FcChar8 *)"sans-serif");
  if (FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &double_num)
      != FcResultMatch)
    FcPatternAddDouble(pattern, FC_PIXEL_SIZE, 12.0);
  if (FcPatternGetInteger(pattern, FC_WEIGHT, 0, &integer)
      != FcResultMatch)
    FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_REGULAR);
  if (FcPatternGetInteger(pattern, FC_SLANT, 0, &integer)
      != FcResultMatch)
    FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN);
  if (FcPatternGetInteger(pattern, FC_WIDTH, 0, &integer)
      != FcResultMatch)
    FcPatternAddInteger(pattern, FC_WIDTH, FC_WIDTH_NORMAL);

  FcConfigSubstitute(NULL, pattern, FcMatchPattern);
  FcDefaultSubstitute(pattern);
  match = FcFontMatch(0, pattern, &r);
  assert(r == FcResultMatch);

  FcPatternDestroy(pattern);
  return match;
}
Пример #7
0
FcFontSet *fcinfo_fontformat_family_index(const FcChar8 *format,
                                          const FcPattern *filter)
{
  FcFontSet *fontset, *result;
  FcPattern *pattern;
  FcPattern *font;
  FcResult r;
  int f;

  pattern = FcPatternDuplicate(filter);
  FcPatternAddString(pattern, FC_FONTFORMAT, format);

  fontset = fcinfo(NULL, pattern, FcTrue, 1, FC_FAMILY);

  result = FcFontSetCreate();
  for (f = 0; f < fontset->nfont; f++)
  {
    font = FcFontMatch(NULL, fontset->fonts[f], &r);
    assert(r == FcResultMatch);
    /* don't add ethio16f-uni.pcf, johabg16.pcf and similar with reported 
       empty charset */
    /* could be done with fcinfo_match(), but that is superfluous
       there like for fcinfo_language_font_index() - it will be needed
       when we will need to display some kind of specimen in fontformat 
       index */
    if (!empty_charset(font))
      FcFontSetAdd(result, FcPatternDuplicate(fontset->fonts[f]));
    FcPatternDestroy(font);
  }

  FcPatternDestroy(pattern);
  FcFontSetDestroy(fontset);
  return result;
}
Пример #8
0
FcFontSet *fcinfo_styles_index(const FcChar8 *family, const FcPattern *filter,
                               family_info_t *fi)
{
  FcFontSet *fontset, *result;
  FcPattern *pattern;

  pattern = FcPatternDuplicate(filter);
  FcPatternDel(pattern, FC_FAMILY); /* perhaps shouldn't be needed */
  FcPatternAddString(pattern, FC_FAMILY, family);
  fontset = fcinfo(NULL, pattern, 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 */
  FcPatternDestroy(pattern);

  if (fontset->nfont == 0)
    return fontset;

  result = fcinfo_match(fontset, filter);
  /* assuming family_info entries all same
     for each style of family; might not be true always */
  if (fi)
    family_info(result->fonts[0], fi);

  FcFontSetDestroy(fontset);
  return result;
}
Пример #9
0
claro_font_t * claro_ft2_load_font(claro_font_backend_t * backend, claro_font_pattern_t * pattern, const char * lang_id)
{
    claro_ft2_backend * ft2_backend = (claro_ft2_backend *)backend;
    FcPattern * real_pattern = NULL, * test_pattern;
    int res;
    
    claro_font_t * font;    
    
    g_return_val_if_fail(ft2_backend != NULL, NULL);
    g_return_val_if_fail(pattern != NULL, NULL);
    // lang_id can be unspecified

    test_pattern = (FcPattern *)pattern->native;

    if(lang_id)
        FcPatternAddString (test_pattern, FC_LANG, lang_id);

    g_return_val_if_fail(FcConfigSubstitute(ft2_backend->config, test_pattern, FcMatchPattern), NULL);
    FcDefaultSubstitute(test_pattern);

    //TODO this sets res to "134524017" wtf?
    real_pattern = FcFontMatch(ft2_backend->config, test_pattern, NULL);                

    if(res != FcResultMatch)
    {
        printf("%s: res = %d\n", __FUNCTION__, res);
        FcPatternDestroy(real_pattern);     
        return NULL; 
    }
   
    font = _claro_ft2_make_font(real_pattern);

    return font;
}
static AliasStrength strengthOfFirstAlias(const FcPattern& original)
{
    // Ideally there would exist a call like
    // FcResult FcPatternIsWeak(pattern, object, id, FcBool* isWeak);
    //
    // However, there is no such call and as of Fc 2.11.0 even FcPatternEquals ignores the weak bit.
    // Currently, the only reliable way of finding the weak bit is by its effect on matching.
    // The weak bit only affects the matching of FC_FAMILY and FC_POSTSCRIPT_NAME object values.
    // A element with the weak bit is scored after FC_LANG, without the weak bit is scored before.
    // Note that the weak bit is stored on the element, not on the value it holds.
    FcValue value;
    FcResult result = FcPatternGet(&original, FC_FAMILY, 0, &value);
    if (result != FcResultMatch)
        return AliasStrength::Done;

    RefPtr<FcPattern> pattern = adoptRef(FcPatternDuplicate(&original));
    FcBool hasMultipleFamilies = true;
    while (hasMultipleFamilies)
        hasMultipleFamilies = FcPatternRemove(pattern.get(), FC_FAMILY, 1);

    // Create a font set with two patterns.
    // 1. the same FC_FAMILY as pattern and a lang object with only 'nomatchlang'.
    // 2. a different FC_FAMILY from pattern and a lang object with only 'matchlang'.
    FcUniquePtr<FcFontSet> fontSet(FcFontSetCreate());

    FcUniquePtr<FcLangSet> strongLangSet(FcLangSetCreate());
    FcLangSetAdd(strongLangSet.get(), reinterpret_cast<const FcChar8*>("nomatchlang"));
    // Ownership of this FcPattern will be transferred with FcFontSetAdd.
    FcPattern* strong = FcPatternDuplicate(pattern.get());
    FcPatternAddLangSet(strong, FC_LANG, strongLangSet.get());

    FcUniquePtr<FcLangSet> weakLangSet(FcLangSetCreate());
    FcLangSetAdd(weakLangSet.get(), reinterpret_cast<const FcChar8*>("matchlang"));
    // Ownership of this FcPattern will be transferred via FcFontSetAdd.
    FcPattern* weak = FcPatternCreate();
    FcPatternAddString(weak, FC_FAMILY, reinterpret_cast<const FcChar8*>("nomatchstring"));
    FcPatternAddLangSet(weak, FC_LANG, weakLangSet.get());

    FcFontSetAdd(fontSet.get(), strong);
    FcFontSetAdd(fontSet.get(), weak);

    // Add 'matchlang' to the copy of the pattern.
    FcPatternAddLangSet(pattern.get(), FC_LANG, weakLangSet.get());

    // Run a match against the copy of the pattern.
    // If the first element was weak, then we should match the pattern with 'matchlang'.
    // If the first element was strong, then we should match the pattern with 'nomatchlang'.

    // Note that this config is only used for FcFontRenderPrepare, which we don't even want.
    // However, there appears to be no way to match/sort without it.
    RefPtr<FcConfig> config = adoptRef(FcConfigCreate());
    FcFontSet* fontSets[1] = { fontSet.get() };
    RefPtr<FcPattern> match = adoptRef(FcFontSetMatch(config.get(), fontSets, 1, pattern.get(), &result));

    FcLangSet* matchLangSet;
    FcPatternGetLangSet(match.get(), FC_LANG, 0, &matchLangSet);
    return FcLangEqual == FcLangSetHasLang(matchLangSet, reinterpret_cast<const FcChar8*>("matchlang"))
        ? AliasStrength::Weak : AliasStrength::Strong;
}
Пример #11
0
FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family)
{
    // The CSS font matching algorithm (http://www.w3.org/TR/css3-fonts/#font-matching-algorithm)
    // says that we must find an exact match for font family, slant (italic or oblique can be used)
    // and font weight (we only match bold/non-bold here).
    RefPtr<FcPattern> pattern = adoptRef(FcPatternCreate());
    String familyNameString(getFamilyNameStringFromFontDescriptionAndFamily(fontDescription, family));
    if (!FcPatternAddString(pattern.get(), FC_FAMILY, reinterpret_cast<const FcChar8*>(familyNameString.utf8().data())))
        return 0;

    bool italic = fontDescription.italic();
    if (!FcPatternAddInteger(pattern.get(), FC_SLANT, italic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN))
        return 0;
    if (!FcPatternAddInteger(pattern.get(), FC_WEIGHT, fontWeightToFontconfigWeight(fontDescription.weight())))
        return 0;
    if (!FcPatternAddDouble(pattern.get(), FC_PIXEL_SIZE, fontDescription.computedPixelSize()))
        return 0;

    // The strategy is originally from Skia (src/ports/SkFontHost_fontconfig.cpp):

    // Allow Fontconfig to do pre-match substitution. Unless we are accessing a "fallback"
    // family like "sans," this is the only time we allow Fontconfig to substitute one
    // family name for another (i.e. if the fonts are aliased to each other).
    FcConfigSubstitute(0, pattern.get(), FcMatchPattern);
    FcDefaultSubstitute(pattern.get());

    FcChar8* fontConfigFamilyNameAfterConfiguration;
    FcPatternGetString(pattern.get(), FC_FAMILY, 0, &fontConfigFamilyNameAfterConfiguration);
    String familyNameAfterConfiguration = String::fromUTF8(reinterpret_cast<char*>(fontConfigFamilyNameAfterConfiguration));

    FcResult fontConfigResult;
    RefPtr<FcPattern> resultPattern = adoptRef(FcFontMatch(0, pattern.get(), &fontConfigResult));
    if (!resultPattern) // No match.
        return 0;

    FcChar8* fontConfigFamilyNameAfterMatching;
    FcPatternGetString(resultPattern.get(), FC_FAMILY, 0, &fontConfigFamilyNameAfterMatching);
    String familyNameAfterMatching = String::fromUTF8(reinterpret_cast<char*>(fontConfigFamilyNameAfterMatching));

    // If Fontconfig gave use a different font family than the one we requested, we should ignore it
    // and allow WebCore to give us the next font on the CSS fallback list. The only exception is if
    // this family name is a commonly used generic family.
    if (!equalIgnoringCase(familyNameAfterConfiguration, familyNameAfterMatching)
            && !(equalIgnoringCase(familyNameString, "sans") || equalIgnoringCase(familyNameString, "sans-serif")
                 || equalIgnoringCase(familyNameString, "serif") || equalIgnoringCase(familyNameString, "monospace")
                 || equalIgnoringCase(familyNameString, "fantasy") || equalIgnoringCase(familyNameString, "cursive")))
        return 0;

    // Verify that this font has an encoding compatible with Fontconfig. Fontconfig currently
    // supports three encodings in FcFreeTypeCharIndex: Unicode, Symbol and AppleRoman.
    // If this font doesn't have one of these three encodings, don't select it.
    FontPlatformData* platformData = new FontPlatformData(resultPattern.get(), fontDescription);
    if (!platformData->hasCompatibleCharmap()) {
        delete platformData;
        return 0;
    }

    return platformData;
}
Пример #12
0
static Vector<String> strongAliasesForFamily(const String& family)
{
    RefPtr<FcPattern> pattern = adoptRef(FcPatternCreate());
    if (!FcPatternAddString(pattern.get(), FC_FAMILY, reinterpret_cast<const FcChar8*>(family.utf8().data())))
        return Vector<String>();

    FcConfigSubstitute(nullptr, pattern.get(), FcMatchPattern);
    FcDefaultSubstitute(pattern.get());

    FcUniquePtr<FcObjectSet> familiesOnly(FcObjectSetBuild(FC_FAMILY, nullptr));
    RefPtr<FcPattern> minimal = adoptRef(FcPatternFilter(pattern.get(), familiesOnly.get()));

    // We really want to match strong (preferred) and same (acceptable) only here.
    // If a family name was specified, assume that any weak matches after the last strong match
    // are weak (default) and ignore them.
    // The reason for is that after substitution the pattern for 'sans-serif' looks like
    // "wwwwwwwwwwwwwwswww" where there are many weak but preferred names, followed by defaults.
    // So it is possible to have weakly matching but preferred names.
    // In aliases, bindings are weak by default, so this is easy and common.
    // If no family name was specified, we'll probably only get weak matches, but that's ok.
    int lastStrongId = -1;
    int numIds = 0;
    for (int id = 0; ; ++id) {
        AliasStrength result = strengthOfFirstAlias(*minimal);
        if (result == AliasStrength::Done) {
            numIds = id;
            break;
        }
        if (result == AliasStrength::Strong)
            lastStrongId = id;
        if (!FcPatternRemove(minimal.get(), FC_FAMILY, 0))
            return Vector<String>();
    }

    // If they were all weak, then leave the pattern alone.
    if (lastStrongId < 0)
        return Vector<String>();

    // Remove everything after the last strong.
    for (int id = lastStrongId + 1; id < numIds; ++id) {
        if (!FcPatternRemove(pattern.get(), FC_FAMILY, lastStrongId + 1)) {
            ASSERT_NOT_REACHED();
            return Vector<String>();
        }
    }

    // Take the resulting pattern and remove everything but the families.
    minimal = adoptRef(FcPatternFilter(pattern.get(), familiesOnly.get()));
    // Convert the pattern to a string, and cut out the non-family junk that gets added to the end.
    char* patternChars = reinterpret_cast<char*>(FcPatternFormat(pattern.get(), reinterpret_cast<const FcChar8*>("%{family}")));
    String patternString = String::fromUTF8(patternChars);
    free(patternChars);

    Vector<String> results;
    patternString.split(',', results);
    return results;
}
static cairo_scaled_font_t *
create_scaled_font (cairo_t * cr)
{
    FcPattern *pattern, *resolved;
    FcResult result;
    cairo_font_face_t *font_face;
    cairo_scaled_font_t *scaled_font;
    cairo_font_options_t *font_options;
    cairo_matrix_t font_matrix, ctm;
    double pixel_size;

    font_options = cairo_font_options_create ();

    cairo_get_font_options (cr, font_options);

    pattern = FcPatternCreate ();

    FcPatternAddString (pattern, FC_FAMILY, (FcChar8 *)"Bitstream Vera Sans");
    FcPatternAddDouble (pattern, FC_PIXEL_SIZE, TEXT_SIZE);
    FcConfigSubstitute (NULL, pattern, FcMatchPattern);

    cairo_ft_font_options_substitute (font_options, pattern);

    FcDefaultSubstitute (pattern);
    resolved = FcFontMatch (NULL, pattern, &result);

    /* set layout to vertical */
    FcPatternDel (resolved, FC_VERTICAL_LAYOUT);
    FcPatternAddBool (resolved, FC_VERTICAL_LAYOUT, FcTrue);

    FcPatternGetDouble (resolved, FC_PIXEL_SIZE, 0, &pixel_size);

    font_face = cairo_ft_font_face_create_for_pattern (resolved);

    cairo_matrix_init_translate (&font_matrix, 10, 30);
    cairo_matrix_rotate (&font_matrix, M_PI_2/3);
    cairo_matrix_scale (&font_matrix, pixel_size, pixel_size);

    cairo_get_matrix (cr, &ctm);

    scaled_font = cairo_scaled_font_create (font_face,
					    &font_matrix,
					    &ctm,
					    font_options);

    cairo_font_options_destroy (font_options);
    cairo_font_face_destroy (font_face);
    FcPatternDestroy (pattern);
    FcPatternDestroy (resolved);

    return scaled_font;
}
Пример #14
0
WMFont*
WMCopyFontWithStyle(WMScreen *scrPtr, WMFont *font, WMFontStyle style)
{
    FcPattern *pattern;
    WMFont *copy;
    char *name;

    if (!font)
        return NULL;

    pattern = FcNameParse(WMGetFontName(font));
    switch (style) {
    case WFSNormal:
        FcPatternDel(pattern, "weight");
        FcPatternDel(pattern, "slant");
        FcPatternAddString(pattern, "weight", "regular");
        FcPatternAddString(pattern, "weight", "medium");
        FcPatternAddString(pattern, "slant", "roman");
        break;
    case WFSBold:
        FcPatternDel(pattern, "weight");
        FcPatternAddString(pattern, "weight", "bold");
        break;
    case WFSEmphasized:
        FcPatternDel(pattern, "slant");
        FcPatternAddString(pattern, "slant", "italic");
        FcPatternAddString(pattern, "slant", "oblique");
        break;
    case WFSBoldEmphasized:
        FcPatternDel(pattern, "weight");
        FcPatternDel(pattern, "slant");
        FcPatternAddString(pattern, "weight", "bold");
        FcPatternAddString(pattern, "slant", "italic");
        FcPatternAddString(pattern, "slant", "oblique");
        break;
    }

    name = FcNameUnparse(pattern);
    copy = WMCreateFont(scrPtr, name);
    FcPatternDestroy(pattern);
    wfree(name);

    return copy;
}
Пример #15
0
// ------------------------------------------------------ match_description ---
char *
//match_description( char * description )
match_description( const char * face, bool bold=false, bool italic=false )
{

#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
    fprintf( stderr, "\"font_manager_match_description\" "
                     "not implemented for windows.\n" );
    return 0;
#endif

    char *filename = 0;
    FcInit();
    //FcPattern *pattern = FcNameParse((const FcChar8*)description);
    FcPattern *pattern = FcPatternCreate();
    if(!pattern)
    {
        fprintf( stderr, "fontconfig error: could not match face '%s'", face );
        return 0;
    }
    FcPatternAddString(pattern, FC_FAMILY, (const FcChar8*)face);
    FcPatternAddInteger(pattern, FC_WEIGHT, bold?FC_WEIGHT_BOLD:FC_WEIGHT_REGULAR);
    FcPatternAddInteger(pattern, FC_SLANT, italic?FC_SLANT_ITALIC:FC_SLANT_ROMAN);
    FcConfigSubstitute( 0, pattern, FcMatchPattern );
    FcDefaultSubstitute( pattern );
    FcResult result;
    FcPattern *match = FcFontMatch( 0, pattern, &result );
    FcPatternDestroy( pattern );

    if ( !match )
    {
        fprintf( stderr, "fontconfig error: could not match face '%s'", face );
        return 0;
    }
    else
    {
        FcValue value;
        FcResult result = FcPatternGet( match, FC_FILE, 0, &value );
        if ( result )
        {
            fprintf( stderr, "fontconfig error: could not match face '%s'", face );
        }
        else
        {
            filename = strdup( (char *)(value.u.s) );
        }
    }
    FcPatternDestroy( match );
    return filename;
}
Пример #16
0
FcPattern *CreateFcPattern(Font font)
{
	LTIMING("CreateXftFont");
	int hg = abs(font.GetHeight());
	if(hg == 0) hg = 10;
	String face = font.GetFaceName();
	FcPattern *p = FcPatternCreate();
	FcPatternAddString(p, FC_FAMILY, (FcChar8*)~face);
	FcPatternAddInteger(p, FC_SLANT, font.IsItalic() ? FC_SLANT_ITALIC : FC_SLANT_ROMAN);
	FcPatternAddInteger(p, FC_PIXEL_SIZE, hg);
	FcPatternAddInteger(p, FC_WEIGHT, font.IsBold() ? FC_WEIGHT_BOLD : FC_WEIGHT_NORMAL);
	FcPatternAddBool(p, FC_MINSPACE, 1);
	FcConfigSubstitute(0, p, FcMatchPattern);
	FcDefaultSubstitute(p);
	FcResult result;
	FcPattern *m = FcFontMatch(0, p, &result);
	FcPatternDestroy(p);
	return m;
}
Пример #17
0
/** Find a font file from its family name.
 * @param font_config fontconfig instance
 * @param font_name name of the font
 * @return full path to the font file
 */
gchar* find_font_file (FcConfig* font_config, const gchar* font_name) {
	const FcChar8* name;
	FcPattern* search_pattern;
	FcPattern* font;
	FcChar8* file;
	gchar* path;
	FcObjectSet* font_properties;
	FcFontSet* fonts;
	int i;

	if (font_config == NULL) {
		g_warning("Font config not loaded.");
		return NULL;
	}
	
	path = NULL;
	name = font_name;

	search_pattern = FcPatternCreate ();
	FcPatternAddString (search_pattern, FC_FAMILY, name);
	FcPatternAddBool (search_pattern, FC_SCALABLE, FcTrue);
	FcPatternAddInteger (search_pattern, FC_WEIGHT, FC_WEIGHT_MEDIUM);
	FcPatternAddInteger (search_pattern, FC_SLANT, FC_SLANT_ROMAN);
		
	font_properties = FcObjectSetBuild (FC_FILE, NULL);
	fonts = FcFontList (font_config, search_pattern, font_properties);
	
	if (fonts->nfont > 0) {
		for (i = 0; i < fonts->nfont; i++) {
			font = fonts->fonts[i];
			
			if (FcPatternGetString(font, FC_FILE, 0, &file) == FcResultMatch) {
				path = g_strdup ((gchar*) file);
				break;
			}
		}
		FcPatternDestroy (font);
	}

	FcPatternDestroy (search_pattern);
	
	return path;
}
Пример #18
0
/* Ask the fontgod for a generic, standard issue "Arial" font */
const char *graph_init_fontconfig(void)
{
    /* Offer fontgod sacrificial pointers to hold his highness */
    FcConfig *fc_config = FcInitLoadConfigAndFonts();
    FcPattern *fc_pattern = FcPatternCreate();
    /* Ask the deity for a user-specified gift of typography */
    FcPatternAddString(fc_pattern, FC_FAMILY, (const FcChar8 *)option->fontname);
    /* Ask fontgod not to blind our eyes for our insolence */
    FcPatternAddBool(fc_pattern, FC_ANTIALIAS, 1);
    /* Summon a fontdemon which shall transmit the gifts of our god */
    FcResult fc_result;
    /* Incantation for our omnipotence to recognize our request: */
    FcDefaultSubstitute(fc_pattern);
    FcConfigSubstitute(fc_config, fc_pattern, FcMatchPattern);
    /* "We ask you, oh you in the sky, for your attention..." */
    FcPattern *fc_font_chosen = FcFontMatch(fc_config, fc_pattern, &fc_result);
    FcValue fc_value;
    /* SHOW US YOUR POWER, INVOKE ANCIENT KNOWLEDGE, GIVE US THE LOCATION! */
    FcPatternGet(fc_font_chosen, "file", 0, &fc_value);
    /* Fontgod has given us a sacred filename, hail FONTCONFIG! */
    pprintf(PRI_SPAM, "[FC] Font path received = %s\n", (char *)fc_value.u.s);
    return (const char *)fc_value.u.s;
}
Пример #19
0
int main(int argc, char* argv[]) {
	msgbuf = malloc(256);
	msgbuf[0] = 0;

	currentLayer = 0;
	cache = true;

	int longIndex;
	int opt;
	do {
		opt = getopt_long(argc, argv, optString, longOpts, &longIndex);
		if (opt != -1) {
			switch( opt ) {
				case 'l':
					currentLayer = strtol(optarg, NULL, 10);
					break;

				case 'w':
					extrusionWidth = strtof(optarg, NULL);
					break;

				case 'n':
					printf("DISABLING CACHE\n");
					cache = false;
					break;

				case 'h':   /* fall-through is intentional */
				case '?':
					display_usage();
					break;

				case 0:     /* long option without a short arg */
					//if( strcmp( "randomize", longOpts[longIndex].name ) == 0 ) {
					//	globalArgs.randomized = 1;
					//}
					break;

				default:
					/* You won't actually get here. */
					break;
			}
		}
	}
	while (opt != -1);

	if (optind >= argc)
		display_usage();

	int fd = open(argv[optind], 0);
	if (fd == -1)
		die("Open ", argv[optind]);

	struct stat filestats;
	if (fstat(fd, &filestats) == -1)
		die("fstat ", argv[optind]);

	filesz = filestats.st_size;

	printf("File is %d long\n", filesz);

#ifdef __linux__
	gcodefile = mmap(NULL, filesz, PROT_READ, MAP_PRIVATE | MAP_POPULATE, fd, 0);
#elif defined __APPLE__
	gcodefile = mmap(NULL, filesz, PROT_READ, MAP_PRIVATE, fd, 0);
#else
	#error "don't know how to mmap on this system!"
#endif

	if (gcodefile == MAP_FAILED)
		die("mmap ", argv[optind]);
	gcodefile_end = &gcodefile[filesz];

	busy = BUSY_SCANFILE;

	scanLines();

	if (currentLayer >= layerCount)
		currentLayer = layerCount - 1;

	//for (int i = 0; i < layerCount; i++)
	//	printf("Layer %3d starts at %7d and is %7d bytes long\n", i, layer[i].index - gcodefile, layer[i].size);

	Running = true;
	Surf_Display = NULL;

	if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
		die("SDL_init", "");

	if (FcInitLoadConfigAndFonts() == ((void *) FcTrue))
		die("FontConfig Init","");

	// from http://www.spinics.net/lists/font-config/msg03050.html
		FcPattern *pat, *match;
		FcResult result;
		char *file;
		int index;
		pat = FcPatternCreate();
		FcPatternAddString(pat, FC_FAMILY, (FcChar8 *) "Mono");
		FcConfigSubstitute(NULL, pat, FcMatchPattern);
		FcDefaultSubstitute(pat);
		match = FcFontMatch(NULL, pat, &result);
		FcPatternGetString(match, FC_FILE, 0, (FcChar8 **) &file);
		FcPatternGetInteger(match, FC_INDEX, 0, &index);


	font = ftglCreateExtrudeFont(file);
	if (!font)
		die("FTGL createFont", "");

	FcPatternDestroy (match);
	FcPatternDestroy (pat);

	#ifdef	OPENGL
		transX = transY = 0.0;
		zoomFactor = 1.0;

		resize(600, 600);
	#else
		viewPortL = viewPortT = 0.0;
		viewPortR = viewPortB = 200.0;
		zoomFactor = 3.0;
		resize(viewPortR * zoomFactor, viewPortB * zoomFactor);
	#endif

	SDL_WM_SetCaption("gcodeview", 0);

	drawLayer(currentLayer);

	layerVelocity = 0;

	timerIdle = SDL_AddTimer(20, &timerCallback, (void *) TIMER_IDLE);

	SDL_Event Event;
	while(Running != false) {
		if (busy) {
			Event.type = SDL_NOEVENT;
			SDL_PollEvent(&Event);
		}
		else {
			if (SDL_WaitEvent(&Event) == 0)
				die("SDL_WaitEvent", "");
		}
		//SDL_RemoveTimer(timerIdle);
		switch (Event.type) {
			case SDL_NOEVENT:
				if (busy & BUSY_SCANFILE) {
					// TODO: scan next layer
					scanLine();
					if ((busy & BUSY_SCANFILE) == 0) {
						if (cache) {
							printf("File scanned, rendering...\n");
							busy = BUSY_RENDER;
						}
						else {
							printf("File scanned.\n");
							busy = 0;
						}
					}
				}
				else if ((busy & BUSY_RENDER) && cache) {
					bool allRendered = true;
					int i;
					// TODO: render next layer in background
					for (i = 0; i < layerCount; i++) {
						if (layer[i].glList == 0) {
							layer[i].glList = glGenLists(1);
							glNewList(layer[i].glList, GL_COMPILE);
							glBegin(GL_QUADS);
							for (int j = SHADOW_LAYERS; j >= 1; j--) {
								if (i - j > 0)
									render_layer(i - j, SHADOW_ALPHA - (j - 1) * (SHADOW_ALPHA / SHADOW_LAYERS));
							}
							render_layer(i, 1.0);
							glEnd();
							glEndList();
							layer[i].flags |= LD_LISTGENERATED;
							allRendered = false;
							break;
						}
					}
					if (allRendered) {
						printf("All %d layers rendered\n", i);
						busy &= ~BUSY_RENDER;
					}
				}
				break;
			case SDL_QUIT:
				Running = false;
				break;
			case SDL_VIDEORESIZE:
				resize(Event.resize.w, Event.resize.h);
				break;
			case SDL_VIDEOEXPOSE:
				render();
				break;
			case SDL_MOUSEBUTTONDOWN:
				handle_mousedown(Event.button);
				break;
			case SDL_MOUSEBUTTONUP:
				handle_mouseup(Event.button);
				break;
			case SDL_MOUSEMOTION:
				handle_mousemove(Event.motion);
				break;
			case SDL_ACTIVEEVENT: // lose or gain focus
				break;
			case SDL_KEYDOWN:
				handle_keydown(Event.key);
				break;
			case SDL_KEYUP:
				handle_keyup(Event.key);
				break;
			case SDL_USEREVENT:
				handle_userevent(Event.user);
				break;
			default:
				printf("SDL Event %d\n", Event.type);
				break;
		}
		//idle code
		//if (busy)
		//	timerIdle = SDL_AddTimer(20, &timerCallback, (void *) TIMER_IDLE);
	}
	if (timerKeyRepeat)
		SDL_RemoveTimer(timerKeyRepeat);
	if (timerDragRender)
		SDL_RemoveTimer(timerDragRender);
	free(layer);
	SDL_FreeSurface(Surf_Display);
	SDL_Quit();
	return 0;
}
Пример #20
0
std::unique_ptr<FontPlatformData> FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family)
{
    // The CSS font matching algorithm (http://www.w3.org/TR/css3-fonts/#font-matching-algorithm)
    // says that we must find an exact match for font family, slant (italic or oblique can be used)
    // and font weight (we only match bold/non-bold here).
    RefPtr<FcPattern> pattern = adoptRef(FcPatternCreate());
    // Never choose unscalable fonts, as they pixelate when displayed at different sizes.
    FcPatternAddBool(pattern.get(), FC_SCALABLE, FcTrue);
    String familyNameString(getFamilyNameStringFromFamily(family));
    if (!FcPatternAddString(pattern.get(), FC_FAMILY, reinterpret_cast<const FcChar8*>(familyNameString.utf8().data())))
        return nullptr;

    bool italic = fontDescription.italic();
    if (!FcPatternAddInteger(pattern.get(), FC_SLANT, italic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN))
        return nullptr;
    if (!FcPatternAddInteger(pattern.get(), FC_WEIGHT, fontWeightToFontconfigWeight(fontDescription.weight())))
        return nullptr;
    if (!FcPatternAddDouble(pattern.get(), FC_PIXEL_SIZE, fontDescription.computedPixelSize()))
        return nullptr;

    // The strategy is originally from Skia (src/ports/SkFontHost_fontconfig.cpp):
    //
    // We do not normally allow fontconfig to substitute one font family for another, since this
    // would break CSS font family fallback: the website should be in control of fallback. During
    // normal font matching, the only font family substitution permitted is for generic families
    // (sans, serif, monospace) or for strongly-aliased fonts (which are to be treated as
    // effectively identical). This is because the font matching step is designed to always find a
    // match for the font, which we don't want.
    //
    // Fontconfig is used in two stages: (1) configuration and (2) matching. During the
    // configuration step, before any matching occurs, we allow arbitrary family substitutions,
    // since this is an exact matter of respecting the user's font configuration.
    FcConfigSubstitute(nullptr, pattern.get(), FcMatchPattern);
    FcDefaultSubstitute(pattern.get());

    FcChar8* fontConfigFamilyNameAfterConfiguration;
    FcPatternGetString(pattern.get(), FC_FAMILY, 0, &fontConfigFamilyNameAfterConfiguration);
    String familyNameAfterConfiguration = String::fromUTF8(reinterpret_cast<char*>(fontConfigFamilyNameAfterConfiguration));

    FcResult fontConfigResult;
    RefPtr<FcPattern> resultPattern = adoptRef(FcFontMatch(nullptr, pattern.get(), &fontConfigResult));
    if (!resultPattern) // No match.
        return nullptr;

    FcChar8* fontConfigFamilyNameAfterMatching;
    FcPatternGetString(resultPattern.get(), FC_FAMILY, 0, &fontConfigFamilyNameAfterMatching);
    String familyNameAfterMatching = String::fromUTF8(reinterpret_cast<char*>(fontConfigFamilyNameAfterMatching));

    // If Fontconfig gave us a different font family than the one we requested, we should ignore it
    // and allow WebCore to give us the next font on the CSS fallback list. The exceptions are if
    // this family name is a commonly-used generic family, or if the families are strongly-aliased.
    // Checking for a strong alias comes last, since it is slow.
    if (!equalIgnoringCase(familyNameAfterConfiguration, familyNameAfterMatching)
        && !(equalIgnoringCase(familyNameString, "sans") || equalIgnoringCase(familyNameString, "sans-serif")
          || equalIgnoringCase(familyNameString, "serif") || equalIgnoringCase(familyNameString, "monospace")
          || equalIgnoringCase(familyNameString, "fantasy") || equalIgnoringCase(familyNameString, "cursive"))
        && !areStronglyAliased(familyNameAfterConfiguration, familyNameAfterMatching))
        return nullptr;

    // Verify that this font has an encoding compatible with Fontconfig. Fontconfig currently
    // supports three encodings in FcFreeTypeCharIndex: Unicode, Symbol and AppleRoman.
    // If this font doesn't have one of these three encodings, don't select it.
    auto platformData = std::make_unique<FontPlatformData>(resultPattern.get(), fontDescription);
    if (!platformData->hasCompatibleCharmap())
        return nullptr;

    return platformData;
}
Пример #21
0
static TTF_Font *search_font_config(astring name, bool bold, bool italic, bool underline, bool &bakedstyles)
{
	TTF_Font *font = (TTF_Font *)NULL;
	FcConfig *config;
	FcPattern *pat;
	FcObjectSet *os;
	FcFontSet *fontset;
	FcValue val;

	config = FcConfigGetCurrent();
	pat = FcPatternCreate();
	os = FcObjectSetCreate();
	FcPatternAddString(pat, FC_FAMILY, (const FcChar8 *)name.cstr());

	// try and get a font with the requested styles baked-in
	if (bold)
	{
		if (italic)
		{
			FcPatternAddString(pat, FC_STYLE, (const FcChar8 *)"Bold Italic");
		}
		else
		{
			FcPatternAddString(pat, FC_STYLE, (const FcChar8 *)"Bold");
		}
	}
	else if (italic)
	{
		FcPatternAddString(pat, FC_STYLE, (const FcChar8 *)"Italic");
	}
	else
	{
		FcPatternAddString(pat, FC_STYLE, (const FcChar8 *)"Regular");
	}

	FcPatternAddString(pat, FC_FONTFORMAT, (const FcChar8 *)"TrueType");

	FcObjectSetAdd(os, FC_FILE);
	fontset = FcFontList(config, pat, os);

	for (int i = 0; i < fontset->nfont; i++)
	{
		if (FcPatternGet(fontset->fonts[i], FC_FILE, 0, &val) != FcResultMatch)
		{
			continue;
		}

		if (val.type != FcTypeString)
		{
			continue;
		}

		mame_printf_verbose("Matching font: %s\n", val.u.s);
		{
			astring match_name((const char*)val.u.s);
			font = TTF_OpenFont_Magic(match_name, POINT_SIZE);
		}

		if (font)
		{
			bakedstyles = true;
			break;
		}
	}

	// didn't get a font above?  try again with no baked-in styles
	if (!font)
	{
		FcPatternDestroy(pat);
		FcFontSetDestroy(fontset);

		pat = FcPatternCreate();
		FcPatternAddString(pat, FC_FAMILY, (const FcChar8 *)name.cstr());
		FcPatternAddString(pat, FC_STYLE, (const FcChar8 *)"Regular");
		FcPatternAddString(pat, FC_FONTFORMAT, (const FcChar8 *)"TrueType");
		fontset = FcFontList(config, pat, os);

		for (int i = 0; i < fontset->nfont; i++)
		{
			if (FcPatternGet(fontset->fonts[i], FC_FILE, 0, &val) != FcResultMatch)
			{
				continue;
			}

			if (val.type != FcTypeString)
			{
				continue;
			}

			mame_printf_verbose("Matching unstyled font: %s\n", val.u.s);
			{
				astring match_name((const char*)val.u.s);
				font = TTF_OpenFont_Magic(match_name, POINT_SIZE);
			}

			if (font)
			{
				break;
			}
		}
	}

	FcPatternDestroy(pat);
	FcObjectSetDestroy(os);
	FcFontSetDestroy(fontset);
	return font;
}
Пример #22
0
nsresult
gfxQtPlatform::ResolveFontName(const nsAString& aFontName,
                                FontResolverCallback aCallback,
                                void *aClosure,
                                PRBool& aAborted)
{

    nsAutoString name(aFontName);
    ToLowerCase(name);

    nsRefPtr<FontFamily> ff;
    if (gPlatformFonts->Get(name, &ff) ||
        gPlatformFontAliases->Get(name, &ff)) {
        aAborted = !(*aCallback)(ff->Name(), aClosure);
        return NS_OK;
    }

    nsCAutoString utf8Name = NS_ConvertUTF16toUTF8(aFontName);

    FcPattern *npat = FcPatternCreate();
    FcPatternAddString(npat, FC_FAMILY, (FcChar8*)utf8Name.get());
    FcObjectSet *nos = FcObjectSetBuild(FC_FAMILY, NULL);
    FcFontSet *nfs = FcFontList(NULL, npat, nos);

    for (int k = 0; k < nfs->nfont; k++) {
        FcChar8 *str;
        if (FcPatternGetString(nfs->fonts[k], FC_FAMILY, 0, (FcChar8 **) &str) != FcResultMatch)
            continue;
        nsAutoString altName = NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str)));
        ToLowerCase(altName);
        if (gPlatformFonts->Get(altName, &ff)) {
            printf("Adding alias: %s -> %s\n", utf8Name.get(), str);
            gPlatformFontAliases->Put(name, ff);
            aAborted = !(*aCallback)(NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str))), aClosure);
            goto DONE;
        }
    }

    FcPatternDestroy(npat);
    FcObjectSetDestroy(nos);
    FcFontSetDestroy(nfs);

    {
    npat = FcPatternCreate();
    FcPatternAddString(npat, FC_FAMILY, (FcChar8*)utf8Name.get());
    FcPatternDel(npat, FC_LANG);
    FcConfigSubstitute(NULL, npat, FcMatchPattern);
    FcDefaultSubstitute(npat);

    nos = FcObjectSetBuild(FC_FAMILY, NULL);
    nfs = FcFontList(NULL, npat, nos);

    FcResult fresult;

    FcPattern *match = FcFontMatch(NULL, npat, &fresult);
    if (match)
        FcFontSetAdd(nfs, match);

    for (int k = 0; k < nfs->nfont; k++) {
        FcChar8 *str;
        if (FcPatternGetString(nfs->fonts[k], FC_FAMILY, 0, (FcChar8 **) &str) != FcResultMatch)
            continue;
        nsAutoString altName = NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str)));
        ToLowerCase(altName);
        if (gPlatformFonts->Get(altName, &ff)) {
            printf("Adding alias: %s -> %s\n", utf8Name.get(), str);
            gPlatformFontAliases->Put(name, ff);
            aAborted = !(*aCallback)(NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str))), aClosure);
            goto DONE;
        }
    }
    }
 DONE:
    FcPatternDestroy(npat);
    FcObjectSetDestroy(nos);
    FcFontSetDestroy(nfs);

    return NS_OK;
}
Пример #23
0
static int load_font_fontconfig(AVFilterContext *ctx)
{
    DrawTextContext *s = ctx->priv;
    FcConfig *fontconfig;
    FcPattern *pat, *best;
    FcResult result = FcResultMatch;
    FcChar8 *filename;
    int index;
    double size;
    int err = AVERROR(ENOENT);

    fontconfig = FcInitLoadConfigAndFonts();
    if (!fontconfig) {
        av_log(ctx, AV_LOG_ERROR, "impossible to init fontconfig\n");
        return AVERROR_UNKNOWN;
    }
    pat = FcNameParse(s->fontfile ? s->fontfile :
                          (uint8_t *)(intptr_t)"default");
    if (!pat) {
        av_log(ctx, AV_LOG_ERROR, "could not parse fontconfig pat");
        return AVERROR(EINVAL);
    }

    FcPatternAddString(pat, FC_FAMILY, s->font);
    if (s->fontsize)
        FcPatternAddDouble(pat, FC_SIZE, (double)s->fontsize);

    FcDefaultSubstitute(pat);

    if (!FcConfigSubstitute(fontconfig, pat, FcMatchPattern)) {
        av_log(ctx, AV_LOG_ERROR, "could not substitue fontconfig options"); /* very unlikely */
        FcPatternDestroy(pat);
        return AVERROR(ENOMEM);
    }

    best = FcFontMatch(fontconfig, pat, &result);
    FcPatternDestroy(pat);

    if (!best || result != FcResultMatch) {
        av_log(ctx, AV_LOG_ERROR,
               "Cannot find a valid font for the family %s\n",
               s->font);
        goto fail;
    }

    if (
        FcPatternGetInteger(best, FC_INDEX, 0, &index   ) != FcResultMatch ||
        FcPatternGetDouble (best, FC_SIZE,  0, &size    ) != FcResultMatch) {
        av_log(ctx, AV_LOG_ERROR, "impossible to find font information");
        return AVERROR(EINVAL);
    }

    if (FcPatternGetString(best, FC_FILE, 0, &filename) != FcResultMatch) {
        av_log(ctx, AV_LOG_ERROR, "No file path for %s\n",
               s->font);
        goto fail;
    }

    av_log(ctx, AV_LOG_INFO, "Using \"%s\"\n", filename);
    if (!s->fontsize)
        s->fontsize = size + 0.5;

    err = load_font_file(ctx, filename, index);
    if (err)
        return err;
    FcConfigDestroy(fontconfig);
fail:
    FcPatternDestroy(best);
    return err;
}
Пример #24
0
FcPattern *
FcNameParse (const FcChar8 *name)
{
    FcChar8		*save;
    FcPattern		*pat;
    double		d;
    FcChar8		*e;
    FcChar8		delim;
    FcValue		v;
    FcMatrix		m;
    const FcObjectType	*t;
    const FcConstant	*c;

    /* freed below */
    save = malloc (strlen ((char *) name) + 1);
    if (!save)
	goto bail0;
    pat = FcPatternCreate ();
    if (!pat)
	goto bail1;

    for (;;)
    {
	name = FcNameFindNext (name, "-,:", save, &delim);
	if (save[0])
	{
	    if (!FcPatternAddString (pat, FC_FAMILY, save))
		goto bail2;
	}
	if (delim != ',')
	    break;
    }
    if (delim == '-')
    {
	for (;;)
	{
	    name = FcNameFindNext (name, "-,:", save, &delim);
	    d = strtod ((char *) save, (char **) &e);
	    if (e != save)
	    {
		if (!FcPatternAddDouble (pat, FC_SIZE, d))
		    goto bail2;
	    }
	    if (delim != ',')
		break;
	}
    }
    while (delim == ':')
    {
	name = FcNameFindNext (name, "=_:", save, &delim);
	if (save[0])
	{
	    if (delim == '=' || delim == '_')
	    {
		t = FcNameGetObjectType ((char *) save);
		for (;;)
		{
		    name = FcNameFindNext (name, ":,", save, &delim);
		    if (t)
		    {
			v = FcNameConvert (t->type, save, &m);
			if (!FcPatternAdd (pat, t->object, v, FcTrue))
			{
			    switch (v.type) {
			    case FcTypeCharSet:
				FcCharSetDestroy ((FcCharSet *) v.u.c);
				break;
			    case FcTypeLangSet:
				FcLangSetDestroy ((FcLangSet *) v.u.l);
				break;
			    default:
				break;
			    }
			    goto bail2;
			}
			switch (v.type) {
			case FcTypeCharSet:
			    FcCharSetDestroy ((FcCharSet *) v.u.c);
			    break;
			case FcTypeLangSet:
			    FcLangSetDestroy ((FcLangSet *) v.u.l);
			    break;
			default:
			    break;
			}
		    }
		    if (delim != ',')
			break;
		}
	    }
	    else
	    {
		if ((c = FcNameGetConstant (save)))
		{
		    if (!FcPatternAddInteger (pat, c->object, c->value))
			goto bail2;
		}
	    }
	}
    }

    free (save);
    return pat;

bail2:
    FcPatternDestroy (pat);
bail1:
    free (save);
bail0:
    return 0;
}
FontPlatformData::FontPlatformData(const FontDescription& fontDescription, const AtomicString& familyName)
    : m_pattern(0)
    , m_fallbacks(0)
    , m_size(fontDescription.computedSize())
    , m_syntheticBold(false)
    , m_syntheticOblique(false)
    , m_scaledFont(0)
    , m_face(0)
{
    FontPlatformData::init();

    CString familyNameString = familyName.string().utf8();
    const char* fcfamily = familyNameString.data();

    int fcslant = FC_SLANT_ROMAN;
    // FIXME: Map all FontWeight values to fontconfig weights.
    int fcweight = FC_WEIGHT_NORMAL;
    float fcsize = fontDescription.computedSize();
    if (fontDescription.italic())
        fcslant = FC_SLANT_ITALIC;
    if (fontDescription.weight() >= FontWeight600)
        fcweight = FC_WEIGHT_BOLD;

    FcConfig *config = FcConfigGetCurrent();

    //printf("family = %s\n", fcfamily);

    int type = fontDescription.genericFamily();

    FcPattern* pattern = FcPatternCreate();
    
    if (!FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast<const FcChar8*>(fcfamily)))
        goto freePattern;

    switch (type) {
        case FontDescription::SerifFamily:
            fcfamily = "serif";
            break;
        case FontDescription::SansSerifFamily:
            fcfamily = "sans-serif";
            break;
        case FontDescription::MonospaceFamily:
            fcfamily = "monospace";
            break;
        case FontDescription::NoFamily:
        case FontDescription::StandardFamily:
        default:
            fcfamily = "sans-serif";
    }

    if (!FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast<const FcChar8*>(fcfamily)))
        goto freePattern;
    if (!FcPatternAddInteger(pattern, FC_SLANT, fcslant))
        goto freePattern;
    if (!FcPatternAddInteger(pattern, FC_WEIGHT, fcweight))
        goto freePattern;
    if (!FcPatternAddDouble(pattern, FC_PIXEL_SIZE, fcsize))
        goto freePattern;

    FcConfigSubstitute(config, pattern, FcMatchPattern);
    FcDefaultSubstitute(pattern);

    FcResult fcresult;
    m_pattern = FcFontMatch(config, pattern, &fcresult);
    FcPatternReference(m_pattern);
    // FIXME: should we set some default font?
    if (!m_pattern)
        goto freePattern;

    FcChar8 *fc_filename;
    char *filename;
    int id;
    id = 0;

    if (FcPatternGetString(m_pattern, FC_FILE, 0, &fc_filename) != FcResultMatch) {
        LOG(FontEngine, "cannot retrieve font\n");
        goto freePattern;
    }

    filename = (char *) fc_filename; //use C cast as FcChar is a fontconfig type
    //printf("filename = %s\n", filename);

    if (FcPatternGetInteger(m_pattern, FC_INDEX, 0, &id) != FcResultMatch) {
        LOG(FontEngine, "cannot retrieve font index\n");
        goto freePattern;
    }
    
    if (FT_Error error = FT_New_Face(m_library, filename, id, &m_face)) {
    //if (FT_Error error = FT_New_Face(m_library, too, id, &m_face)) {
        LOG(FontEngine, "fail to open fonti %s with index %d (error = 0x%x)\n", filename, id, error);
        m_face = 0;
        goto freePattern;
    }

    FT_Set_Pixel_Sizes(m_face, 0, static_cast<uint> (fontDescription.computedSize()));
    //DBGML(MODULE_FONTS, LEVEL_INFO, "open font %s with size %d\n", filename, static_cast<uint> (fontDescription.specifiedSize()));

freePattern:
    FcPatternDestroy(pattern);
    FcConfigDestroy(config);
}
Пример #26
0
fz_error *
pdf_loadsystemfont(pdf_font *font, char *basefont, char *collection)
{
	fz_error *error;
	FcResult fcerr;
	int fterr;

	char fontname[200];
	FcPattern *searchpat;
	FcPattern *matchpat;
	FT_Face face;
	char *style;
	char *file;
	int index;

	error = initfontlibs();
	if (error)
		return error;

	/* parse windows-style font name descriptors Font,Style */
	/* TODO: reliable way to split style from Font-Style type names */
	strlcpy(fontname, basefont, sizeof fontname);
	style = strchr(fontname, ',');
	if (style)
		*style++ = 0;

	searchpat = FcPatternCreate();
	if (!searchpat)
		return fz_outofmem;

	error = fz_outofmem;

	if (!FcPatternAddString(searchpat, FC_FAMILY, fontname))
		goto cleanup;

	if (collection)
	{
		if (!strcmp(collection, "Adobe-GB1"))
			if (!FcPatternAddString(searchpat, FC_LANG, "zh-TW"))
				goto cleanup;
		if (!strcmp(collection, "Adobe-CNS1"))
			if (!FcPatternAddString(searchpat, FC_LANG, "zh-CN"))
				goto cleanup;
		if (!strcmp(collection, "Adobe-Japan1"))
			if (!FcPatternAddString(searchpat, FC_LANG, "ja"))
				goto cleanup;
		if (!strcmp(collection, "Adobe-Japan2"))
			if (!FcPatternAddString(searchpat, FC_LANG, "ja"))
				goto cleanup;
		if (!strcmp(collection, "Adobe-Korea1"))
			if (!FcPatternAddString(searchpat, FC_LANG, "ko"))
				goto cleanup;
	}

	if (style)
		if (!FcPatternAddString(searchpat, FC_STYLE, style))
			goto cleanup;

	if (font->flags & FD_SERIF)
		FcPatternAddString(searchpat, FC_FAMILY, "serif");
	else
		FcPatternAddString(searchpat, FC_FAMILY, "sans-serif");
	if (font->flags & FD_ITALIC)
		FcPatternAddString(searchpat, FC_STYLE, "Italic");
	if (font->flags & FD_FORCEBOLD)
		FcPatternAddString(searchpat, FC_STYLE, "Bold");

	if (!FcPatternAddBool(searchpat, FC_OUTLINE, 1))
		goto cleanup;

	file = FcNameUnparse(searchpat);
	pdf_logfont("fontconfig0 %s\n", file);
	free(file);

	fcerr = FcResultMatch;
/*	FcDefaultSubstitute(searchpat); */
	FcConfigSubstitute(fclib, searchpat, FcMatchPattern);

	file = FcNameUnparse(searchpat);
	pdf_logfont("fontconfig1 %s\n", file);
	free(file);

	matchpat = FcFontMatch(fclib, searchpat, &fcerr);
	if (fcerr != FcResultMatch)
		return fz_throw("fontconfig could not find font %s", basefont);

	fcerr = FcPatternGetString(matchpat, FC_FAMILY, 0, (FcChar8**)&file);
	if (file && strcmp(fontname, file))
		font->substitute = 1;

	fcerr = FcPatternGetString(matchpat, FC_STYLE, 0, (FcChar8**)&file);
	if (file && style && strcmp(style, file))
		font->substitute = 1;

	fcerr = FcPatternGetString(matchpat, FC_FILE, 0, (FcChar8**)&file);
	if (fcerr != FcResultMatch)
		return fz_throw("fontconfig could not find font %s", basefont);

	index = 0;
	fcerr = FcPatternGetInteger(matchpat, FC_INDEX, 0, &index);

	pdf_logfont("load font file %s %d\n", file, index);

	fterr = FT_New_Face(ftlib, file, index, &face);
	if (fterr) {
		FcPatternDestroy(matchpat);
		FcPatternDestroy(searchpat);
		return fz_throw("freetype could not load font file '%s': %s", file, pdf_fterrorstring(fterr));
	}

	FcPatternDestroy(matchpat);
	FcPatternDestroy(searchpat);

	font->ftface = face;

	return nil;

cleanup:
	FcPatternDestroy(searchpat);
	return error;
}
bool SkFontConfigInterfaceDirect::matchFamilyName(const char familyName[],
                                                  SkTypeface::Style style,
                                                  FontIdentity* outIdentity,
                                                  SkString* outFamilyName,
                                                  SkTypeface::Style* outStyle) {
    SkString familyStr(familyName ? familyName : "");
    if (familyStr.size() > kMaxFontFamilyLength) {
        return false;
    }

    SkAutoMutexAcquire ac(mutex_);

    FcPattern* pattern = FcPatternCreate();

    if (familyName) {
        FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName);
    }
    FcPatternAddInteger(pattern, FC_WEIGHT,
                        (style & SkTypeface::kBold) ? FC_WEIGHT_BOLD
                                                    : FC_WEIGHT_NORMAL);
    FcPatternAddInteger(pattern, FC_SLANT,
                        (style & SkTypeface::kItalic) ? FC_SLANT_ITALIC
                                                      : FC_SLANT_ROMAN);
    FcPatternAddBool(pattern, FC_SCALABLE, FcTrue);

    FcConfigSubstitute(NULL, pattern, FcMatchPattern);
    FcDefaultSubstitute(pattern);

    // Font matching:
    // CSS often specifies a fallback list of families:
    //    font-family: a, b, c, serif;
    // However, fontconfig will always do its best to find *a* font when asked
    // for something so we need a way to tell if the match which it has found is
    // "good enough" for us. Otherwise, we can return NULL which gets piped up
    // and lets WebKit know to try the next CSS family name. However, fontconfig
    // configs allow substitutions (mapping "Arial -> Helvetica" etc) and we
    // wish to support that.
    //
    // Thus, if a specific family is requested we set @family_requested. Then we
    // record two strings: the family name after config processing and the
    // family name after resolving. If the two are equal, it's a good match.
    //
    // So consider the case where a user has mapped Arial to Helvetica in their
    // config.
    //    requested family: "Arial"
    //    post_config_family: "Helvetica"
    //    post_match_family: "Helvetica"
    //      -> good match
    //
    // and for a missing font:
    //    requested family: "Monaco"
    //    post_config_family: "Monaco"
    //    post_match_family: "Times New Roman"
    //      -> BAD match
    //
    // However, we special-case fallback fonts; see IsFallbackFontAllowed().

    const char* post_config_family = get_name(pattern, FC_FAMILY);
    if (!post_config_family) {
        // we can just continue with an empty name, e.g. default font
        post_config_family = "";
    }

    FcResult result;
    FcFontSet* font_set = FcFontSort(0, pattern, 0, 0, &result);
    if (!font_set) {
        FcPatternDestroy(pattern);
        return false;
    }

    FcPattern* match = MatchFont(font_set, post_config_family, familyStr);
    if (!match) {
        FcPatternDestroy(pattern);
        FcFontSetDestroy(font_set);
        return false;
    }

    FcPatternDestroy(pattern);

    // From here out we just extract our results from 'match'

    post_config_family = get_name(match, FC_FAMILY);
    if (!post_config_family) {
        FcFontSetDestroy(font_set);
        return false;
    }

    const char* c_filename = get_name(match, FC_FILE);
    if (!c_filename) {
        FcFontSetDestroy(font_set);
        return false;
    }

    int face_index;
    if (FcPatternGetInteger(match, FC_INDEX, 0, &face_index) != FcResultMatch) {
        FcFontSetDestroy(font_set);
        return false;
    }

    FcFontSetDestroy(font_set);

    if (outIdentity) {
        outIdentity->fTTCIndex = face_index;
        outIdentity->fString.set(c_filename);
    }
    if (outFamilyName) {
        outFamilyName->set(post_config_family);
    }
    if (outStyle) {
        *outStyle = GetFontStyle(match);
    }
    return true;
}
Пример #28
0
static cairo_status_t
create_scaled_font (cairo_t * cr,
		    cairo_scaled_font_t **out)
{
    FcPattern *pattern, *resolved;
    FcResult result;
    cairo_font_face_t *font_face;
    cairo_scaled_font_t *scaled_font;
    cairo_font_options_t *font_options;
    cairo_matrix_t font_matrix, ctm;
    cairo_status_t status;
    double pixel_size;

    font_options = cairo_font_options_create ();

    cairo_get_font_options (cr, font_options);

    pattern = FcPatternCreate ();
    if (pattern == NULL)
	return CAIRO_STATUS_NO_MEMORY;

    FcPatternAddString (pattern, FC_FAMILY, (FcChar8 *)CAIRO_TEST_FONT_FAMILY " Sans");
    FcPatternAddDouble (pattern, FC_PIXEL_SIZE, TEXT_SIZE);
    FcConfigSubstitute (NULL, pattern, FcMatchPattern);

    cairo_ft_font_options_substitute (font_options, pattern);

    FcDefaultSubstitute (pattern);
    resolved = FcFontMatch (NULL, pattern, &result);
    if (resolved == NULL) {
	FcPatternDestroy (pattern);
	return CAIRO_STATUS_NO_MEMORY;
    }

    /* set layout to vertical */
    FcPatternDel (resolved, FC_VERTICAL_LAYOUT);
    FcPatternAddBool (resolved, FC_VERTICAL_LAYOUT, FcTrue);

    FcPatternGetDouble (resolved, FC_PIXEL_SIZE, 0, &pixel_size);

    font_face = cairo_ft_font_face_create_for_pattern (resolved);

    cairo_matrix_init_translate (&font_matrix, 10, 30);
    cairo_matrix_rotate (&font_matrix, M_PI_2/3);
    cairo_matrix_scale (&font_matrix, pixel_size, pixel_size);

    cairo_get_matrix (cr, &ctm);

    scaled_font = cairo_scaled_font_create (font_face,
					    &font_matrix,
					    &ctm,
					    font_options);

    cairo_font_options_destroy (font_options);
    cairo_font_face_destroy (font_face);
    FcPatternDestroy (pattern);
    FcPatternDestroy (resolved);

    status = cairo_scaled_font_status (scaled_font);
    if (status) {
	cairo_scaled_font_destroy (scaled_font);
	return status;
    }

    *out = scaled_font;
    return CAIRO_STATUS_SUCCESS;
}
bool SkFontConfigInterfaceDirect::matchFamilySet(const char inFamilyName[],
                                                 SkString* outFamilyName,
                                                 SkTArray<FontIdentity>* ids) {
    SkAutoMutexAcquire ac(mutex_);

#if 0
    SkString familyStr(familyName ? familyName : "");
    if (familyStr.size() > kMaxFontFamilyLength) {
        return false;
    }

    SkAutoMutexAcquire ac(mutex_);

    FcPattern* pattern = FcPatternCreate();

    if (familyName) {
        FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName);
    }
    FcPatternAddBool(pattern, FC_SCALABLE, FcTrue);

    FcConfigSubstitute(NULL, pattern, FcMatchPattern);
    FcDefaultSubstitute(pattern);

    // Font matching:
    // CSS often specifies a fallback list of families:
    //    font-family: a, b, c, serif;
    // However, fontconfig will always do its best to find *a* font when asked
    // for something so we need a way to tell if the match which it has found is
    // "good enough" for us. Otherwise, we can return NULL which gets piped up
    // and lets WebKit know to try the next CSS family name. However, fontconfig
    // configs allow substitutions (mapping "Arial -> Helvetica" etc) and we
    // wish to support that.
    //
    // Thus, if a specific family is requested we set @family_requested. Then we
    // record two strings: the family name after config processing and the
    // family name after resolving. If the two are equal, it's a good match.
    //
    // So consider the case where a user has mapped Arial to Helvetica in their
    // config.
    //    requested family: "Arial"
    //    post_config_family: "Helvetica"
    //    post_match_family: "Helvetica"
    //      -> good match
    //
    // and for a missing font:
    //    requested family: "Monaco"
    //    post_config_family: "Monaco"
    //    post_match_family: "Times New Roman"
    //      -> BAD match
    //
    // However, we special-case fallback fonts; see IsFallbackFontAllowed().

    const char* post_config_family = get_name(pattern, FC_FAMILY);

    FcResult result;
    FcFontSet* font_set = FcFontSort(0, pattern, 0, 0, &result);
    if (!font_set) {
        FcPatternDestroy(pattern);
        return false;
    }

    FcPattern* match = MatchFont(font_set, post_config_family, familyStr);
    if (!match) {
        FcPatternDestroy(pattern);
        FcFontSetDestroy(font_set);
        return false;
    }

    FcPatternDestroy(pattern);

    // From here out we just extract our results from 'match'

    if (FcPatternGetString(match, FC_FAMILY, 0, &post_config_family) != FcResultMatch) {
        FcFontSetDestroy(font_set);
        return false;
    }

    FcChar8* c_filename;
    if (FcPatternGetString(match, FC_FILE, 0, &c_filename) != FcResultMatch) {
        FcFontSetDestroy(font_set);
        return false;
    }

    int face_index;
    if (FcPatternGetInteger(match, FC_INDEX, 0, &face_index) != FcResultMatch) {
        FcFontSetDestroy(font_set);
        return false;
    }

    FcFontSetDestroy(font_set);

    if (outIdentity) {
        outIdentity->fTTCIndex = face_index;
        outIdentity->fString.set((const char*)c_filename);
    }
    if (outFamilyName) {
        outFamilyName->set((const char*)post_config_family);
    }
    if (outStyle) {
        *outStyle = GetFontStyle(match);
    }
    return true;

////////////////////

        int count;
        FcPattern** match = MatchFont(font_set, post_config_family, &count);
        if (!match) {
            FcPatternDestroy(pattern);
            FcFontSetDestroy(font_set);
            return NULL;
        }

        FcPatternDestroy(pattern);

        SkTDArray<FcPattern*> trimmedMatches;
        for (int i = 0; i < count; ++i) {
            const char* justName = find_just_name(get_name(match[i], FC_FILE));
            if (!is_lower(*justName)) {
                *trimmedMatches.append() = match[i];
            }
        }

        SkFontStyleSet_FC* sset = new SkFontStyleSet_FC                                               (trimmedMatches.begin(),                                               trimmedMatches.count());
#endif
    return false;
}
Пример #30
0
QStringList QFontconfigDatabase::fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const
{
    QStringList fallbackFamilies;
    FcPattern *pattern = FcPatternCreate();
    if (!pattern)
        return fallbackFamilies;

    FcValue value;
    value.type = FcTypeString;
    QByteArray cs = family.toUtf8();
    value.u.s = (const FcChar8 *)cs.data();
    FcPatternAdd(pattern,FC_FAMILY,value,true);

    int slant_value = FC_SLANT_ROMAN;
    if (style == QFont::StyleItalic)
        slant_value = FC_SLANT_ITALIC;
    else if (style == QFont::StyleOblique)
        slant_value = FC_SLANT_OBLIQUE;
    FcPatternAddInteger(pattern, FC_SLANT, slant_value);

    Q_ASSERT(uint(script) < QChar::ScriptCount);
    if (*specialLanguages[script] != '\0') {
        FcLangSet *ls = FcLangSetCreate();
        FcLangSetAdd(ls, (const FcChar8*)specialLanguages[script]);
        FcPatternAddLangSet(pattern, FC_LANG, ls);
        FcLangSetDestroy(ls);
    } else if (!family.isEmpty()) {
        // If script is Common or Han, then it may include languages like CJK,
        // we should attach system default language set to the pattern
        // to obtain correct font fallback list (i.e. if LANG=zh_CN
        // then we normally want to use a Chinese font for CJK text;
        // while a Japanese font should be used for that if LANG=ja)
        FcPattern *dummy = FcPatternCreate();
        FcDefaultSubstitute(dummy);
        FcChar8 *lang = 0;
        FcResult res = FcPatternGetString(dummy, FC_LANG, 0, &lang);
        if (res == FcResultMatch)
            FcPatternAddString(pattern, FC_LANG, lang);
        FcPatternDestroy(dummy);
    }

    const char *stylehint = getFcFamilyForStyleHint(styleHint);
    if (stylehint) {
        value.u.s = (const FcChar8 *)stylehint;
        FcPatternAddWeak(pattern, FC_FAMILY, value, FcTrue);
    }

    FcConfigSubstitute(0, pattern, FcMatchPattern);
    FcDefaultSubstitute(pattern);

    FcResult result = FcResultMatch;
    FcFontSet *fontSet = FcFontSort(0,pattern,FcFalse,0,&result);
    FcPatternDestroy(pattern);

    if (fontSet) {
        for (int i = 0; i < fontSet->nfont; i++) {
            FcChar8 *value = 0;
            if (FcPatternGetString(fontSet->fonts[i], FC_FAMILY, 0, &value) != FcResultMatch)
                continue;
            //         capitalize(value);
            QString familyName = QString::fromUtf8((const char *)value);
            if (!fallbackFamilies.contains(familyName,Qt::CaseInsensitive) &&
                familyName.compare(family, Qt::CaseInsensitive)) {
                fallbackFamilies << familyName;
            }
        }
        FcFontSetDestroy(fontSet);
    }
//    qDebug() << "fallbackFamilies for:" << family << style << styleHint << script << fallbackFamilies;

    return fallbackFamilies;
}