SkDataTable* SkFontConfigInterfaceDirect::getFamilyNames() {
    SkAutoMutexAcquire ac(mutex_);

    FcPattern* pat = FcPatternCreate();
    SkAutoTCallVProc<FcPattern, FcPatternDestroy> autoDestroyPat(pat);
    if (NULL == pat) {
        return NULL;
    }

    FcObjectSet* os = FcObjectSetBuild(FC_FAMILY, (char *)0);
    SkAutoTCallVProc<FcObjectSet, FcObjectSetDestroy> autoDestroyOs(os);
    if (NULL == os) {
        return NULL;
    }

    FcFontSet* fs = FcFontList(NULL, pat, os);
    SkAutoTCallVProc<FcFontSet, FcFontSetDestroy> autoDestroyFs(fs);
    if (NULL == fs) {
        return NULL;
    }

    SkTDArray<const char*> names;
    SkTDArray<size_t> sizes;
    for (int i = 0; i < fs->nfont; ++i) {
        FcPattern* match = fs->fonts[i];
        const char* famName = get_name(match, FC_FAMILY);
        if (famName && !find_name(names, famName)) {
            *names.append() = famName;
            *sizes.append() = strlen(famName) + 1;
        }
    }

    return SkDataTable::NewCopyArrays((const void*const*)names.begin(),
                                      sizes.begin(), names.count());
}
Ejemplo n.º 2
0
static void findfont(char *fontname, char *fontpath)
{
    FcPattern *p = NULL;
    FcChar8 *strval = NULL;
    FcObjectSet *attr = NULL;

    if (!FcInit())
        return;

    attr = FcObjectSetBuild (FC_FILE, (char *) 0);

    p = FcNameParse((FcChar8*)fontname);
    if (p == NULL)
        return;

    FcFontSet *fs = FcFontList (0, p, attr);
    if (fs->nfont == 0)
        return;

    if (FcPatternGetString(fs->fonts[0], FC_FILE, 0, &strval) == FcResultTypeMismatch
                || strval == NULL)
        return;

    strcpy(fontpath, strval);

    FcFontSetDestroy(fs);
    FcObjectSetDestroy(attr);
    FcPatternDestroy(p);
    FcFini();

    return;
}
Ejemplo n.º 3
0
void
XeTeXFontMgr_FC::initialize()
{
	if (FcInit() == FcFalse) {
		fprintf(stderr, "fontconfig initialization failed!\n");
		exit(9);
	}

	if (gFreeTypeLibrary == 0 && FT_Init_FreeType(&gFreeTypeLibrary) != 0) {
		fprintf(stderr, "FreeType initialization failed!\n");
		exit(9);
	}

	UErrorCode	err = U_ZERO_ERROR;
	macRomanConv = ucnv_open("macintosh", &err);
	utf16beConv = ucnv_open("UTF16BE", &err);
	utf8Conv = ucnv_open("UTF8", &err);
	if (err != 0) {
		fprintf(stderr, "internal error; cannot read font names\n");
		exit(3);
	}

	FcPattern*		pat = FcNameParse((const FcChar8*)":outline=true");
	FcObjectSet*	os = FcObjectSetBuild(FC_FAMILY, FC_STYLE, FC_FILE, FC_INDEX,
											FC_FULLNAME, FC_WEIGHT, FC_WIDTH, FC_SLANT, NULL);
	allFonts = FcFontList(FcConfigGetCurrent(), pat, os);
	FcObjectSetDestroy(os);
	FcPatternDestroy(pat);
	
	cachedAll = false;
}
Ejemplo n.º 4
0
GeeArrayList *
FcListFiles(void)
{
    int          i;
    FcPattern    * pattern;
    FcFontSet    * fontset;
    FcObjectSet  * objectset = 0;
    GeeArrayList * filelist = gee_array_list_new(G_TYPE_STRING,
                                                (GBoxedCopyFunc) g_strdup,
                                                (GDestroyNotify) g_free0,
                                                NULL,
                                                NULL,
                                                NULL);
    g_assert(FcInit());
    pattern = FcNameParse((FcChar8 *) ":");
    objectset = FcObjectSetBuild (FC_FILE, NULL);
    fontset = FcFontList(NULL, pattern, objectset);

    for (i = 0; i < fontset->nfont; i++) {
        FcChar8 * file;
        if (FcPatternGetString(fontset->fonts[i], FC_FILE, 0, &file) == FcResultMatch)
            gee_abstract_collection_add((GeeAbstractCollection *) filelist, file);
    }

    if (objectset)
        FcObjectSetDestroy(objectset);
    if (pattern)
        FcPatternDestroy(pattern);
    if (fontset)
        FcFontSetDestroy(fontset);

    return filelist;
}
Ejemplo n.º 5
0
gchar* find_font_with_property (FcConfig* fontconfig, const gchar* characters, const gchar* property) {
	FcPattern* pattern;
	FcCharSet* character_set;
	FcObjectSet* font_properties;
	FcFontSet* fonts;
	FcPattern* font;
	FcChar8* path;
	gchar* result;
	gchar* remaining_characters;
	gunichar character;
	
	if (fontconfig == NULL) {
		g_warning("Font config not loaded.");
		return NULL;
	}
	
	result = NULL;
	pattern = FcPatternCreate ();
	
	character_set = FcCharSetCreate ();
	
	remaining_characters = (gchar*) characters;
	while (TRUE) {
		character = g_utf8_get_char (remaining_characters);
		
		if (character == '\0') {
			break;
		}
		
		FcCharSetAddChar(character_set, character);
				
		remaining_characters = g_utf8_next_char (remaining_characters);
	}

	FcPatternAddCharSet (pattern, FC_CHARSET, character_set);
	FcCharSetDestroy (character_set);
	FcPatternAddInteger (pattern, FC_SLANT, FC_SLANT_ROMAN);
	
	FcPatternAddBool(pattern, FC_SCALABLE, FcTrue);
	font_properties = FcObjectSetBuild (property, NULL);	
	fonts = FcFontList (fontconfig, pattern, font_properties);
	
	if (fonts && fonts->nfont > 0) {
		font = fonts->fonts[0];
		if (FcPatternGetString(font, property, 0, &path) == FcResultMatch) {
			result = g_strdup ((gchar*) path);
		}
	}

	if (fonts) {
		FcFontSetDestroy(fonts);
	}

	if (pattern) {
		FcPatternDestroy(pattern);
	}

	return result;
}
Ejemplo n.º 6
0
FcPattern* BC_Resources::find_similar_font(FT_ULong char_code, FcPattern *oldfont)
{
	FcPattern *pat, *font;
	FcFontSet *fs;
	FcObjectSet *os;
	FcCharSet *fcs;
	FcChar8 *file;
	double dval;
	int ival;

	// Do not search control codes
	if(char_code < ' ')
		return 0;

	fontconfig_lock.lock("BC_Resources::find_similar_font");
	pat = FcPatternCreate();
	os = FcObjectSetBuild(FC_FILE, FC_CHARSET, FC_SCALABLE, FC_FAMILY,
		FC_SLANT, FC_WEIGHT, FC_WIDTH, (char *)0);

	FcPatternAddBool(pat, FC_SCALABLE, true);
	fcs = FcCharSetCreate();
	if(FcCharSetAddChar(fcs, char_code))
		FcPatternAddCharSet(pat, FC_CHARSET, fcs);
	FcCharSetDestroy(fcs);
	for(int i = 0; i < LEN_FCPROP; i++)
	{
		if(FcPatternGetInteger(oldfont, fc_properties[i], 0, &ival) == FcResultMatch)
			FcPatternAddInteger(pat, fc_properties[i], ival);
	}
	fs = FcFontList(0, pat, os);

	for(int i = LEN_FCPROP - 1; i >= 0 && fs->nfont == 0; i--)
	{
		FcFontSetDestroy(fs);
		FcPatternDel(pat, fc_properties[i]);
		fs = FcFontList(0, pat, os);
	}
	FcPatternDestroy(pat);
	FcObjectSetDestroy(os);

	pat = 0;

	for (int i = 0; i < fs->nfont; i++)
	{
		font = fs->fonts[i];
		if(FcPatternGetCharSet(font, FC_CHARSET, 0, &fcs) == FcResultMatch)
		{
			if(FcCharSetHasChar(fcs, char_code))
			{
				pat =  FcPatternDuplicate(font);
				break;
			}
		}
	}
	FcFontSetDestroy(fs);
	fontconfig_lock.unlock();

	return pat;
}
Ejemplo n.º 7
0
/* make sure the font list is valid */
static void
ensure_font_list (FontViewModel *self)
{
    FcPattern *pat;
    FcObjectSet *os;
    gint i;
    FcChar8 *file;
    gchar *font_name, *collation_key;
    GdkPixbuf *pix;

    if (self->priv->font_list) {
            FcFontSetDestroy (self->priv->font_list);
            self->priv->font_list = NULL;
    }

    gtk_list_store_clear (GTK_LIST_STORE (self));

    /* always reinitialize the font database */
    if (!FcInitReinitialize())
        return;

    pat = FcPatternCreate ();
    os = FcObjectSetBuild (FC_FILE, FC_FAMILY, FC_WEIGHT, FC_SLANT, NULL);

    self->priv->font_list = FcFontList (NULL, pat, os);

    FcPatternDestroy (pat);
    FcObjectSetDestroy (os);

    if (!self->priv->font_list)
        return;

    for (i = 0; i < self->priv->font_list->nfont; i++) {
	FcPatternGetString (self->priv->font_list->fonts[i], FC_FILE, 0, &file);
        font_name = font_utils_get_font_name_for_file (self->priv->library, (const gchar *) file);

        if (!font_name)
            continue;

        pix = get_fallback_icon ();
        collation_key = g_utf8_collate_key (font_name, -1);

        gtk_list_store_insert_with_values (GTK_LIST_STORE (self), NULL, -1,
                                           COLUMN_NAME, font_name,
                                           COLUMN_POINTER, self->priv->font_list->fonts[i],
                                           COLUMN_PATH, file,
                                           COLUMN_ICON, pix,
                                           COLUMN_COLLATION_KEY, collation_key,
                                           -1);

        ensure_thumbnail (self, (const gchar *) file);

        g_free (font_name);
        g_free (collation_key);
        g_object_unref (pix);
    }
}
Ejemplo n.º 8
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;
}
Ejemplo n.º 9
0
int fontconf()
{
	FcFontSet* fs = NULL;
	FcPattern* pat = NULL;
	FcObjectSet* os = NULL;
	FcChar8* strpat = (FcChar8*) ":lang=ja";
	pat = FcNameParse(strpat);
	os = FcObjectSetBuild(FC_FAMILY, FC_CHARSET, FC_FILE, (char *) 0);
	fs = FcFontList(0, pat, os);
	if (os)
		FcObjectSetDestroy(os);
	os = NULL;
	FcPatternDestroy(pat);
	pat = NULL;
	if (!fs || fs->nfont <= 0)
		goto nofont;
	FcChar8 *family;
	FcChar8 *file;
	FcCharSet* cs;
	FcChar32 ch;
	FcUtf8ToUcs4((FcChar8*) "��", &ch, 3);
	int i;
	for (i = 0; i < fs->nfont; i++)
	{
		if (FcPatternGetCharSet(fs->fonts[i], FC_CHARSET, 0, &cs)
				!= FcResultMatch)
		{

			fprintf(stderr, "no match\n");

			FcPatternPrint(fs->fonts[i]);

			goto nofont;
		}
		if(FcPatternGetString(fs->fonts[i], FC_FAMILY, 1, &family) !=FcResultMatch)

	 if(FcPatternGetString(fs->fonts[i], FC_FAMILY, 0, &family) != FcResultMatch)
	  goto nofont;
	  printf("[%d] %s ", i, (char *)family);
	  if(FcPatternGetString(fs->fonts[i], FC_FILE, 0, &file) != FcResultMatch)

	 goto nofont;
	  printf("(%s): ", (char *)file);
	  if(FcCharSetHasChar(cs, ch)){

	 puts("Yes");
	  }else{

	 puts("No");
	  }
	}
	FcFontSetDestroy(fs);
	return 0;
	nofont: return 1;
}
Ejemplo n.º 10
0
bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, int winlangid, SetFallbackFontCallback *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);
	/* We only want to know the filename. */
	FcObjectSet *os = FcObjectSetBuild(FC_FILE, 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) {
		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;
			}

			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));

			bool missing = callback(NULL);
			DEBUG(freetype, 1, "Font \"%s\" misses%s glyphs", file, missing ? "" : " no");

			if (!missing) {
				ret = true;
				break;
			}
		}

		/* Clean up the list of filenames. */
		FcFontSetDestroy(fs);
	}

	FcFini();
	return ret;
}
Ejemplo n.º 11
0
void *gp_enumerate_fonts_init(gs_memory_t *mem)
{
#ifdef HAVE_FONTCONFIG
    unix_fontenum_t *state;
    FcPattern *pat;
    FcObjectSet *os;

    state = (unix_fontenum_t *)malloc(sizeof(unix_fontenum_t));
    if (state == NULL)
        return NULL;    /* Failed to allocate state */

    state->index     = 0;
    state->fc        = NULL;
    state->font_list = NULL;

    /* Load the fontconfig library */
    state->fc = FcInitLoadConfigAndFonts();
    if (state->fc == NULL) {
        free(state);
        state = NULL;
        dlprintf("destroyed state - fontconfig init failed");
        return NULL;  /* Failed to open fontconfig library */
    }

    /* load the font set that we'll iterate over */
    pat = FcPatternBuild(NULL,
            FC_OUTLINE, FcTypeBool, 1,
            FC_SCALABLE, FcTypeBool, 1,
            NULL);
    os = FcObjectSetBuild(FC_FILE, FC_OUTLINE,
            FC_FAMILY, FC_WEIGHT, FC_SLANT,
            NULL);
    state->font_list = FcFontList(0, pat, os);
    FcPatternDestroy(pat);
    FcObjectSetDestroy(os);
    if (state->font_list == NULL) {
        free(state);
        state = NULL;
        return NULL;  /* Failed to generate font list */
    }
    return (void *)state;
#else
    return NULL;
#endif
}
Ejemplo n.º 12
0
int lltxplatform_get_installed_fonts_impl(struct lltxplatform_fontinfo **const fonts, unsigned int *const count) {
  int status = -1;
  FcPattern *const pattern = FcPatternCreate();
  if (pattern != NULL) {
    FcObjectSet *const objects = FcObjectSetBuild(FC_FULLNAME, FC_FILE, NULL);
    if (objects != NULL) {
      FcFontSet *const list = FcFontList(NULL, pattern, objects);
      if (list != NULL) {
        if (list->nfont > 0) {
          const unsigned int cnt = (unsigned int) list->nfont;
          struct lltxplatform_fontinfo *const array = (struct lltxplatform_fontinfo *) calloc((size_t) cnt, sizeof(struct lltxplatform_fontinfo));
          if (array != NULL) {
            unsigned int i;
            status = 0;
            for (i = 0; i < cnt; ++i) {
              struct lltxplatform_fontinfo *const info = &array[i];
              FcPattern *const font = list->fonts[i];
              FcChar8 *value;
              if (FcPatternGetString(font, FC_FULLNAME, 0, &value) == FcResultMatch) {
                info->name = strdup((char *) value);
              } else {
                info->name = NULL;
              }
              if (FcPatternGetString(font, FC_FILE, 0, &value) == FcResultMatch) {
                info->path = strdup((char *) value);
              } else {
                info->path = NULL;
              }
            }
            *count = cnt;
            *fonts = array;
          }
        } else {
          status = 0;
          *count = 0;
          *fonts = NULL;
        }
        FcFontSetDestroy(list);
      }
      FcObjectSetDestroy(objects);
    }
    FcPatternDestroy(pattern);
  }
  return status;
}
Ejemplo n.º 13
0
GeeArrayList *
FcListFonts(gchar * family_name)
{
    int          i;
    FcPattern    * pattern;
    FcFontSet    * fontset;
    FcObjectSet  * objectset = 0;
    GeeArrayList * fontlist = gee_array_list_new(G_TYPE_OBJECT,
                                                        NULL,
                                                        NULL,
                                                        NULL,
                                                        NULL,
                                                        NULL);
    g_assert(FcInit());
    if (family_name)
        pattern = FcPatternBuild (NULL, FC_FAMILY, FcTypeString, family_name, NULL);
    else
        pattern = FcNameParse((FcChar8 *) ":");

    objectset = FcObjectSetBuild (FC_FILE,
                                  FC_INDEX,
                                  FC_FAMILY,
                                  FC_STYLE,
                                  FC_SLANT,
                                  FC_WEIGHT,
                                  FC_WIDTH,
                                  FC_SPACING,
                                  NULL);
    fontset = FcFontList(NULL, pattern, objectset);

    for (i = 0; i < fontset->nfont; i++) {
        FontConfigFont * font = font_config_font_new();
        get_font_details_from_pattern(font, fontset->fonts[i]);
        gee_abstract_collection_add((GeeAbstractCollection *) fontlist, font);
    }

    if (objectset)
        FcObjectSetDestroy(objectset);
    if (pattern)
        FcPatternDestroy(pattern);
    if (fontset)
        FcFontSetDestroy(fontset);

    return fontlist;
}
Ejemplo n.º 14
0
	void configureFontConfig()
	{
		if (fontConfigHasBeenInitialized)
			return ;
		fontConfigHasBeenInitialized = true;

		if (!FcInit())
		{
			INCD_ERROR("could not initialize fontconfig.");
			return ;
		}

		fontConfigConfig = FcConfigGetCurrent();
		FcConfigSetRescanInterval(fontConfigConfig, 0);
		fontConfigPattern = FcPatternCreate();
		fontConfigObjectSet = FcObjectSetBuild(FC_FAMILY, FC_FILE, (char *)0);
		fontConfigFontSet = FcFontList(fontConfigConfig, fontConfigPattern, fontConfigObjectSet);
	}
Ejemplo n.º 15
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;
}
Ejemplo n.º 16
0
Vector<String> FontCache::systemFontFamilies()
{
    RefPtr<FcPattern> scalablesOnlyPattern = adoptRef(FcPatternCreate());
    FcPatternAddBool(scalablesOnlyPattern.get(), FC_SCALABLE, FcTrue);

    FcUniquePtr<FcObjectSet> familiesOnly(FcObjectSetBuild(FC_FAMILY, nullptr));
    FcUniquePtr<FcFontSet> fontSet(FcFontList(nullptr, scalablesOnlyPattern.get(), familiesOnly.get()));

    Vector<String> fontFamilies;
    for (int i = 0; i < fontSet->nfont; i++) {
        FcPattern* pattern = fontSet->fonts[i];
        FcChar8* family = nullptr;
        FcPatternGetString(pattern, FC_FAMILY, 0, &family);
        if (family)
            fontFamilies.appendVector(patternToFamilies(*pattern));
    }

    return fontFamilies;
}
Ejemplo n.º 17
0
FcStrSet *fcinfo_languages(const FcPattern *filter)
{
  FcObjectSet *objectset;
  FcFontSet *fontset;
  FcLangSet *union_langset;
  FcStrSet *result;
  int f;

  FcInit();
  objectset = FcObjectSetBuild(FC_LANG, NULL);
  fontset = FcFontList(NULL, (FcPattern *)filter, objectset);
  FcObjectSetDestroy(objectset);

  union_langset = FcLangSetCreate();
  for (f = 0; f < fontset->nfont; f++)
  {
    FcLangSet *langset;
    FcStrList *strlist;
    FcChar8 *lang;

    if (FcPatternGetLangSet(fontset->fonts[f], FC_LANG, 0, &langset)
        != FcResultMatch)
      continue;
    if (! langset)
      continue;

    strlist = FcStrListCreate(FcLangSetGetLangs(langset));
    while ((lang = FcStrListNext(strlist)))
      if (FcLangSetHasLang(union_langset, lang))
       FcLangSetAdd(union_langset, FcStrCopy(lang));
  }

  result = FcLangSetGetLangs(union_langset);
  
  FcFontSetDestroy(fontset);
  FcLangSetDestroy(union_langset);
  return result;
}
Ejemplo n.º 18
0
// coverity[+alloc : arg-*0]
GpStatus
GdipNewInstalledFontCollection (GpFontCollection **font_collection)
{
    if (!font_collection)
        return InvalidParameter;

    /*
     * Ensure we leak this data only a single time, because:
     * (a) there is no API to free it;
     * (b) other libgdiplus structures depends on that allocated data;
     */
    if (!system_fonts) {
        FcObjectSet *os = FcObjectSetBuild (FC_FAMILY, FC_FOUNDRY, NULL);
        FcPattern *pat = FcPatternCreate ();
        FcValue val;
        FcFontSet *col;

        /* Only Scalable fonts for now */
        val.type = FcTypeBool;
        val.u.b = FcTrue;
        FcPatternAdd (pat, FC_SCALABLE, val, TRUE);
        FcObjectSetAdd (os, FC_SCALABLE);

        col = FcFontList (0, pat, os);
        FcPatternDestroy (pat);
        FcObjectSetDestroy (os);

        system_fonts = (GpFontCollection *) GdipAlloc (sizeof (GpFontCollection));
        if (system_fonts) {
            system_fonts->fontset = col;
            system_fonts->config = NULL;
        }
    }

    *font_collection = system_fonts;
    return Ok;
}
Ejemplo n.º 19
0
static void
gimp_font_list_load_names (GimpFontList *list,
                           PangoFontMap *fontmap,
                           PangoContext *context)
{
  FcObjectSet *os;
  FcPattern   *pat;
  FcFontSet   *fontset;
  gint         i;

  os = FcObjectSetBuild (FC_FAMILY, FC_STYLE,
                         FC_SLANT, FC_WEIGHT, FC_WIDTH,
                         NULL);

  pat = FcPatternCreate ();

  fontset = FcFontList (NULL, pat, os);

  FcPatternDestroy (pat);
  FcObjectSetDestroy (os);

  for (i = 0; i < fontset->nfont; i++)
    {
      PangoFontDescription *desc;

      desc = pango_fc_font_description_from_pattern (fontset->fonts[i], FALSE);
      gimp_font_list_add_font (list, context, desc);
      pango_font_description_free (desc);
    }

  /*  only create aliases if there is at least one font available  */
  if (fontset->nfont > 0)
    gimp_font_list_load_aliases (list, context);

  FcFontSetDestroy (fontset);
}
Ejemplo n.º 20
0
MagickExport MagickBooleanType LoadFontConfigFonts(SplayTreeInfo *type_list,
  ExceptionInfo *exception)
{
#if !defined(FC_FULLNAME)
#define FC_FULLNAME "fullname"
#endif

  char
    extension[MaxTextExtent],
    name[MaxTextExtent];

  FcChar8
    *family,
    *file,
    *fullname,
    *style;

  FcConfig
    *font_config;

  FcFontSet
    *font_set;

  FcObjectSet
    *object_set;

  FcPattern
    *pattern;

  FcResult
    status;

  int
    slant,
    width,
    weight;

  register ssize_t
    i;

  TypeInfo
    *type_info;

  /*
    Load system fonts.
  */
  (void) exception;
  font_config=FcInitLoadConfigAndFonts();
  if (font_config == (FcConfig *) NULL)
    return(MagickFalse);
  font_set=(FcFontSet *) NULL;
  object_set=FcObjectSetBuild(FC_FULLNAME,FC_FAMILY,FC_STYLE,FC_SLANT,
    FC_WIDTH,FC_WEIGHT,FC_FILE,(char *) NULL);
  if (object_set != (FcObjectSet *) NULL)
    {
      pattern=FcPatternCreate();
      if (pattern != (FcPattern *) NULL)
        {
          font_set=FcFontList(0,pattern,object_set);
          FcPatternDestroy(pattern);
        }
      FcObjectSetDestroy(object_set);
    }
  if (font_set == (FcFontSet *) NULL)
    {
      FcConfigDestroy(font_config);
      return(MagickFalse);
    }
  for (i=0; i < (ssize_t) font_set->nfont; i++)
  {
    status=FcPatternGetString(font_set->fonts[i],FC_FAMILY,0,&family);
    if (status != FcResultMatch)
      continue;
    status=FcPatternGetString(font_set->fonts[i],FC_FILE,0,&file);
    if (status != FcResultMatch)
      continue;
    *extension='\0';
    GetPathComponent((const char *) file,ExtensionPath,extension);
    if ((*extension != '\0') && (LocaleCompare(extension,"gz") == 0))
      continue;
    type_info=(TypeInfo *) AcquireMagickMemory(sizeof(*type_info));
    if (type_info == (TypeInfo *) NULL)
      continue;
    (void) ResetMagickMemory(type_info,0,sizeof(*type_info));
    type_info->path=ConstantString("System Fonts");
    type_info->signature=MagickSignature;
    (void) CopyMagickString(name,"Unknown",MaxTextExtent);
    status=FcPatternGetString(font_set->fonts[i],FC_FULLNAME,0,&fullname);
    if ((status == FcResultMatch) && (fullname != (FcChar8 *) NULL))
      (void) CopyMagickString(name,(const char *) fullname,MaxTextExtent);
    else
      {
        if (family != (FcChar8 *) NULL)
          (void) CopyMagickString(name,(const char *) family,MaxTextExtent);
        status=FcPatternGetString(font_set->fonts[i],FC_STYLE,0,&style);
        if ((status == FcResultMatch) && (style != (FcChar8 *) NULL) &&
            (LocaleCompare((const char *) style,"Regular") != 0))
          {
            (void) ConcatenateMagickString(name," ",MaxTextExtent);
            (void) ConcatenateMagickString(name,(const char *) style,
              MaxTextExtent);
          }
      }
    type_info->name=ConstantString(name);
    (void) SubstituteString(&type_info->name," ","-");
    type_info->family=ConstantString((const char *) family);
    status=FcPatternGetInteger(font_set->fonts[i],FC_SLANT,0,&slant);
    type_info->style=NormalStyle;
    if (slant == FC_SLANT_ITALIC)
      type_info->style=ItalicStyle;
    if (slant == FC_SLANT_OBLIQUE)
      type_info->style=ObliqueStyle;
    status=FcPatternGetInteger(font_set->fonts[i],FC_WIDTH,0,&width);
    type_info->stretch=NormalStretch;
    if (width >= FC_WIDTH_ULTRACONDENSED)
      type_info->stretch=UltraCondensedStretch;
    if (width >= FC_WIDTH_EXTRACONDENSED)
      type_info->stretch=ExtraCondensedStretch;
    if (width >= FC_WIDTH_CONDENSED)
      type_info->stretch=CondensedStretch;
    if (width >= FC_WIDTH_SEMICONDENSED)
      type_info->stretch=SemiCondensedStretch;
    if (width >= FC_WIDTH_NORMAL)
      type_info->stretch=NormalStretch;
    if (width >= FC_WIDTH_SEMIEXPANDED)
      type_info->stretch=SemiExpandedStretch;
    if (width >= FC_WIDTH_EXPANDED)
      type_info->stretch=ExpandedStretch;
    if (width >= FC_WIDTH_EXTRAEXPANDED)
      type_info->stretch=ExtraExpandedStretch;
    if (width >= FC_WIDTH_ULTRAEXPANDED)
      type_info->stretch=UltraExpandedStretch;
    type_info->weight=400;
    status=FcPatternGetInteger(font_set->fonts[i],FC_WEIGHT,0,&weight);
    if (weight >= FC_WEIGHT_THIN)
      type_info->weight=100;
    if (weight >= FC_WEIGHT_EXTRALIGHT)
      type_info->weight=200;
    if (weight >= FC_WEIGHT_LIGHT)
      type_info->weight=300;
    if (weight >= FC_WEIGHT_NORMAL)
      type_info->weight=400;
    if (weight >= FC_WEIGHT_MEDIUM)
      type_info->weight=500;
    if (weight >= FC_WEIGHT_DEMIBOLD)
      type_info->weight=600;
    if (weight >= FC_WEIGHT_BOLD)
      type_info->weight=700;
    if (weight >= FC_WEIGHT_EXTRABOLD)
      type_info->weight=800;
    if (weight >= FC_WEIGHT_BLACK)
      type_info->weight=900;
    type_info->glyphs=ConstantString((const char *) file);
    (void) AddValueToSplayTree(type_list,type_info->name,type_info);
  }
  FcFontSetDestroy(font_set);
  FcConfigDestroy(font_config);
  return(MagickTrue);
}
Ejemplo n.º 21
0
int BC_Resources::init_fontconfig(const char *search_path)
{
	if( fontlist ) return 0;
	fontlist = new ArrayList<BC_FontEntry*>;

#define get_str(str,sep,ptr,cond) do { char *out = str; \
  while( *ptr && !strchr(sep,*ptr) && (cond) ) *out++ = *ptr++; \
  *out = 0; \
} while(0)

#define skip_str(sep, ptr) do { \
  while( *ptr && strchr(sep,*ptr) ) ++ptr; \
} while(0)

	char find_command[BCTEXTLEN];
	sprintf(find_command,
		"find %s -name 'fonts.dir' -print -exec cat {} \\;",
		search_path);
	FILE *in = popen(find_command, "r");

	FT_Library freetype_library = 0;
//	FT_Face freetype_face = 0;
//	FT_Init_FreeType(&freetype_library);

	char line[BCTEXTLEN], current_dir[BCTEXTLEN];
	current_dir[0] = 0;

	while( !feof(in) && fgets(line, BCTEXTLEN, in) ) {
		if(!strlen(line)) break;

		char *in_ptr = line;

// Get current directory
		if(line[0] == '/') {
			get_str(current_dir, "\n", in_ptr,1);
			for( int i=strlen(current_dir); --i>=0 && current_dir[i]!='/'; )
				current_dir[i] = 0;
			continue;
		}

//printf("TitleMain::build_fonts %s\n", line);
		BC_FontEntry *entry = new BC_FontEntry;
		char string[BCTEXTLEN];
// Path
		get_str(string, "\n", in_ptr, in_ptr[0]!=' ' || in_ptr[1]!='-');
		entry->path = cstrcat(2, current_dir, string);
// Foundary
		skip_str(" -", in_ptr);
		get_str(string, " -\n", in_ptr, 1);
		if( !string[0] ) { delete entry;  continue; }
		entry->foundry = cstrdup(string);
		if(*in_ptr == '-') in_ptr++;
// Family
		get_str(string, "-\n", in_ptr, 1);
		if( !string[0] ) { delete entry;  continue; }
		entry->family = cstrdup(string);
		if(*in_ptr == '-') in_ptr++;
// Weight
		get_str(string, "-\n", in_ptr, 1);
		entry->weight = cstrdup(string);
		if(*in_ptr == '-') in_ptr++;
// Slant
		get_str(string, "-\n", in_ptr, 1);
		entry->slant = cstrdup(string);
		if(*in_ptr == '-') in_ptr++;
// SWidth
		get_str(string, "-\n", in_ptr, 1);
		entry->swidth = cstrdup(string);
		if(*in_ptr == '-') in_ptr++;
// Adstyle
		get_str(string, "-\n", in_ptr, 1);
		entry->adstyle = cstrdup(string);
		if(*in_ptr == '-') in_ptr++;
// pixelsize
		get_str(string, "-\n", in_ptr, 1);
		entry->pixelsize = atol(string);
		if(*in_ptr == '-') in_ptr++;
// pointsize
		get_str(string, "-\n", in_ptr, 1);
		entry->pointsize = atol(string);
		if(*in_ptr == '-') in_ptr++;
// xres
		get_str(string, "-\n", in_ptr, 1);
		entry->xres = atol(string);
		if(*in_ptr == '-') in_ptr++;
// yres
		get_str(string, "-\n", in_ptr, 1);
		entry->yres = atol(string);
		if(*in_ptr == '-') in_ptr++;
// spacing
		get_str(string, "-\n", in_ptr, 1);
		entry->spacing = cstrdup(string);
		if(*in_ptr == '-') in_ptr++;
// avg_width
		get_str(string, "-\n", in_ptr, 1);
		entry->avg_width = atol(string);
		if(*in_ptr == '-') in_ptr++;
// registry
		get_str(string, "-\n", in_ptr, 1);
		entry->registry = cstrdup(string);
		if(*in_ptr == '-') in_ptr++;
// encoding
		get_str(string, "-\n", in_ptr, 1);
		entry->encoding = cstrdup(string);
		if(*in_ptr == '-') in_ptr++;

// Add to list
//printf("TitleMain::build_fonts 1 %s\n", entry->path);
// This takes a real long time to do.  Instead just take all fonts
// 		if(!load_freetype_face(freetype_library,
// 			freetype_face, entry->path) )
// Fix parameters
		sprintf(line, "%s (%s)", entry->family, entry->foundry);
		entry->displayname = cstrdup(line);

		if(!strcasecmp(entry->weight, "demibold")) {
			entry->fixed_style |= BC_FONT_BOLD;
			entry->style |= FL_WEIGHT_DEMIBOLD;
		}
		else if(!strcasecmp(entry->weight, "bold")) {
			entry->fixed_style |= BC_FONT_BOLD;
			entry->style |= FL_WEIGHT_BOLD;
		}
		else {
			entry->style |= FL_WEIGHT_NORMAL;
		}

		if(!strcasecmp(entry->slant, "r")) {
			entry->style |= FL_SLANT_ROMAN;
		}
		else if(!strcasecmp(entry->slant, "i")) {
			entry->style |= FL_SLANT_ITALIC;
			entry->fixed_style |= BC_FONT_ITALIC;
		}
		else if(!strcasecmp(entry->slant, "o")) {
			entry->style |= FL_SLANT_OBLIQUE;
			entry->fixed_style |= BC_FONT_ITALIC;
		}

		if(!strcasecmp(entry->swidth, "normal"))
			entry->style = FL_WIDTH_NORMAL;
		else if(!strcasecmp(entry->swidth, "ultracondensed"))
			entry->style = FL_WIDTH_ULTRACONDENSED;
		else if(!strcasecmp(entry->swidth, "extracondensed"))
			entry->style = FL_WIDTH_EXTRACONDENSED;
		else if(!strcasecmp(entry->swidth, "condensed"))
			entry->style = FL_WIDTH_CONDENSED;
		else if(!strcasecmp(entry->swidth, "semicondensed"))
			entry->style = FL_WIDTH_SEMICONDENSED;
		else if(!strcasecmp(entry->swidth, "semiexpanded"))
			entry->style = FL_WIDTH_SEMIEXPANDED;
		else if(!strcasecmp(entry->swidth, "expanded"))
			entry->style = FL_WIDTH_EXPANDED;
		else if(!strcasecmp(entry->swidth, "extraexpanded"))
			entry->style = FL_WIDTH_EXTRAEXPANDED;
		else if(!strcasecmp(entry->swidth, "ultraexpanded"))
			entry->style = FL_WIDTH_ULTRAEXPANDED;
		else
			entry->style = FL_WIDTH_NORMAL;

		fontlist->append(entry);
//		printf("TitleMain::build_fonts %s: success\n",	entry->path);
//printf("TitleMain::build_fonts 2\n");
	}
	pclose(in);


// Load all the fonts from fontconfig
	FcPattern *pat;
	FcFontSet *fs;
	FcObjectSet *os;
	FcChar8 *family, *file, *foundry, *style, *format;
	int slant, spacing, width, weight;
	int force_style = 0;
// if you want limit search to TrueType put 1
	int limit_to_trutype = 1;
	FcConfig *config;
	int i;
	char tmpstring[BCTEXTLEN];
	if(!FcInit())
		return 1;
	config = FcConfigGetCurrent();
	FcConfigSetRescanInterval(config, 0);

	pat = FcPatternCreate();
	os = FcObjectSetBuild ( FC_FAMILY, FC_FILE, FC_FOUNDRY, FC_WEIGHT,
		FC_WIDTH, FC_SLANT, FC_FONTFORMAT, FC_SPACING, FC_STYLE, (char *) 0);
	FcPatternAddBool(pat, FC_SCALABLE, true);

	if(language[0]) {
		char langstr[LEN_LANG * 3];
		strcpy(langstr, language);

		if(region[0]) {
			strcat(langstr, "-");
			strcat(langstr, region);
		}

		FcLangSet *ls =  FcLangSetCreate();
		if(FcLangSetAdd(ls, (const FcChar8*)langstr))
		if(FcPatternAddLangSet(pat, FC_LANG, ls))
		FcLangSetDestroy(ls);
	}

	fs = FcFontList(config, pat, os);
	FcPatternDestroy(pat);
	FcObjectSetDestroy(os);

	for (i = 0; fs && i < fs->nfont; i++) {
		FcPattern *font = fs->fonts[i];
		force_style = 0;
		FcPatternGetString(font, FC_FONTFORMAT, 0, &format);
		//on this point you can limit font search
		if(limit_to_trutype && strcmp((char *)format, "TrueType"))
			continue;

		sprintf(tmpstring, "%s", format);
		BC_FontEntry *entry = new BC_FontEntry;
		if(FcPatternGetString(font, FC_FILE, 0, &file) == FcResultMatch) {
			entry->path = cstrdup((char*)file);
		}

		if(FcPatternGetString(font, FC_FOUNDRY, 0, &foundry) == FcResultMatch) {
			entry->foundry = cstrdup((char*)foundry);
		}

		if(FcPatternGetInteger(font, FC_WEIGHT, 0, &weight) == FcResultMatch) {
			switch(weight) {
			case FC_WEIGHT_THIN:
			case FC_WEIGHT_EXTRALIGHT:
			case FC_WEIGHT_LIGHT:
			case FC_WEIGHT_BOOK:
				force_style = 1;
				entry->weight = cstrdup("medium");
				break;

			case FC_WEIGHT_NORMAL:
			case FC_WEIGHT_MEDIUM:
			default:
				entry->weight = cstrdup("medium");
				break;

			case FC_WEIGHT_BLACK:
			case FC_WEIGHT_SEMIBOLD:
			case FC_WEIGHT_BOLD:
				entry->weight = cstrdup("bold");
				entry->fixed_style |= BC_FONT_BOLD;
				break;

			case FC_WEIGHT_EXTRABOLD:
			case FC_WEIGHT_EXTRABLACK:
				force_style = 1;
				entry->weight = cstrdup("bold");
				entry->fixed_style |= BC_FONT_BOLD;
				break;
			}
		}

		if(FcPatternGetString(font, FC_FAMILY, 0, &family) == FcResultMatch)
			entry->family = cstrdup((char*)family);

		if(FcPatternGetInteger(font, FC_SLANT, 0, &slant) == FcResultMatch) {
			switch(slant) {
			case FC_SLANT_ROMAN:
			default:
				entry->slant = cstrdup("r");
				entry->style |= FL_SLANT_ROMAN;
				break;
			case FC_SLANT_ITALIC:
				entry->slant = cstrdup("i");
				entry->style |= FL_SLANT_ITALIC;
				entry->fixed_style |= BC_FONT_ITALIC;
				break;
			case FC_SLANT_OBLIQUE:
				entry->slant = cstrdup("o");
				entry->style |= FL_SLANT_OBLIQUE;
				entry->fixed_style |= BC_FONT_ITALIC;
				break;
			}
		}

		if(FcPatternGetInteger(font, FC_WIDTH, 0, &width) == FcResultMatch) {
			switch(width) {
			case FC_WIDTH_ULTRACONDENSED:
				entry->swidth = cstrdup("ultracondensed");
				break;

			case FC_WIDTH_EXTRACONDENSED:
				entry->swidth = cstrdup("extracondensed");
				break;

			case FC_WIDTH_CONDENSED:
				entry->swidth = cstrdup("condensed");
				break;
			case FC_WIDTH_SEMICONDENSED:
				entry->swidth = cstrdup("semicondensed");
				break;

			case FC_WIDTH_NORMAL:
			default:
				entry->swidth = cstrdup("normal");
				break;

			case FC_WIDTH_SEMIEXPANDED:
				entry->swidth = cstrdup("semiexpanded");
				break;

			case FC_WIDTH_EXPANDED:
				entry->swidth = cstrdup("expanded");
				break;

			case FC_WIDTH_EXTRAEXPANDED:
				entry->swidth = cstrdup("extraexpanded");
				break;

			case FC_WIDTH_ULTRAEXPANDED:
				entry->swidth = cstrdup("ultraexpanded");
				break;
			}
		}

		if(FcPatternGetInteger(font, FC_SPACING, 0, &spacing) == FcResultMatch) {
			switch(spacing) {
			case 0:
			default:
				entry->spacing = cstrdup("p");
				break;

			case 90:
				entry->spacing = cstrdup("d");
				break;

			case 100:
				entry->spacing = cstrdup("m");
				break;

			case 110:
				entry->spacing = cstrdup("c");
				break;
			}
		}

		// Add fake stuff for compatibility
		entry->adstyle = cstrdup(" ");
		entry->pixelsize = 0;
		entry->pointsize = 0;
		entry->xres = 0;
		entry->yres = 0;
		entry->avg_width = 0;
		entry->registry = cstrdup("utf");
		entry->encoding = cstrdup("8");

		if(!FcPatternGetString(font, FC_STYLE, 0, &style) == FcResultMatch)
			force_style = 0;

		// If font has a style unmanaged by titler plugin, force style to be displayed on name
		// in this way we can shown all available fonts styles.
		if(force_style) {
			sprintf(tmpstring, "%s (%s)", entry->family, style);
			entry->displayname = cstrdup(tmpstring);
		}
		else {
			if(strcmp(entry->foundry, "unknown")) {
				sprintf(tmpstring, "%s (%s)", entry->family, entry->foundry);
				entry->displayname = cstrdup(tmpstring);
			}
			else {
				sprintf(tmpstring, "%s", entry->family);
				entry->displayname = cstrdup(tmpstring);
			}

		}
		fontlist->append(entry);
	}

	FcFontSetDestroy(fs);
	if(freetype_library)
		FT_Done_FreeType(freetype_library);
// for(int i = 0; i < fonts->total; i++)
//	fonts->values[i]->dump();

	FcConfigAppFontAddDir(0, (const FcChar8*)search_path);
	FcConfigSetRescanInterval(0, 0);

	os = FcObjectSetBuild(FC_FAMILY, FC_FILE, FC_FOUNDRY, FC_WEIGHT,
		FC_WIDTH, FC_SLANT, FC_SPACING, FC_STYLE, (char *)0);
	pat = FcPatternCreate();
	FcPatternAddBool(pat, FC_SCALABLE, true);

	if(language[0])
	{
		char langstr[LEN_LANG * 3];
		strcpy(langstr, language);

		if(region[0])
		{
			strcat(langstr, "-");
			strcat(langstr, region);
		}

		FcLangSet *ls =  FcLangSetCreate();
		if(FcLangSetAdd(ls, (const FcChar8*)langstr))
			if(FcPatternAddLangSet(pat, FC_LANG, ls))
		FcLangSetDestroy(ls);
	}

	fs = FcFontList(0, pat, os);
	FcPatternDestroy(pat);
	FcObjectSetDestroy(os);

	for(int i = 0; i < fs->nfont; i++)
	{
		FcPattern *font = fs->fonts[i];
		BC_FontEntry *entry = new BC_FontEntry;

		FcChar8 *strvalue;
		if(FcPatternGetString(font, FC_FILE, 0, &strvalue) == FcResultMatch)
		{
			entry->path = new char[strlen((char*)strvalue) + 1];
			strcpy(entry->path, (char*)strvalue);
		}

		if(FcPatternGetString(font, FC_FOUNDRY, 0, &strvalue) == FcResultMatch)
		{
			entry->foundry = new char[strlen((char*)strvalue) + 1];
			strcpy(entry->foundry, (char *)strvalue);
		}

		if(FcPatternGetString(font, FC_FAMILY, 0, &strvalue) == FcResultMatch)
		{
			entry->family = new char[strlen((char*)strvalue) + 2];
			strcpy(entry->family, (char*)strvalue);
		}

		int intvalue;
		if(FcPatternGetInteger(font, FC_SLANT, 0, &intvalue) == FcResultMatch)
		{
			switch(intvalue)
			{
			case FC_SLANT_ROMAN:
			default:
				entry->style |= FL_SLANT_ROMAN;
				break;

			case FC_SLANT_ITALIC:
				entry->style |= FL_SLANT_ITALIC;
				break;

			case FC_SLANT_OBLIQUE:
				entry->style |= FL_SLANT_OBLIQUE;
				break;
			}
		}

		if(FcPatternGetInteger(font, FC_WEIGHT, 0, &intvalue) == FcResultMatch)
		{
			switch(intvalue)
			{
			case FC_WEIGHT_THIN:
				entry->style |= FL_WEIGHT_THIN;
				break;

			case FC_WEIGHT_EXTRALIGHT:
				entry->style |= FL_WEIGHT_EXTRALIGHT;
				break;

			case FC_WEIGHT_LIGHT:
				entry->style |= FL_WEIGHT_LIGHT;
				break;

			case FC_WEIGHT_BOOK:
				entry->style |= FL_WEIGHT_BOOK;
				break;

			case FC_WEIGHT_NORMAL:
			default:
				entry->style |= FL_WEIGHT_NORMAL;
				break;

			case FC_WEIGHT_MEDIUM:
				entry->style |= FL_WEIGHT_MEDIUM;
				break;

			case FC_WEIGHT_DEMIBOLD:
				entry->style |= FL_WEIGHT_DEMIBOLD;
				break;

			case FC_WEIGHT_BOLD:
				entry->style |= FL_WEIGHT_BOLD;
				break;

			case FC_WEIGHT_EXTRABOLD:
				entry->style |= FL_WEIGHT_EXTRABOLD;
				break;

			case FC_WEIGHT_BLACK:
				entry->style |= FL_WEIGHT_BLACK;
				break;

			case FC_WEIGHT_EXTRABLACK:
				entry->style |= FL_WEIGHT_EXTRABLACK;
				break;
			}
		}

		if(FcPatternGetInteger(font, FC_WIDTH, 0, &intvalue) == FcResultMatch)
		{
			switch(intvalue)
			{
			case FC_WIDTH_ULTRACONDENSED:
				entry->style |= FL_WIDTH_ULTRACONDENSED;
				break;

			case FC_WIDTH_EXTRACONDENSED:
				entry->style |= FL_WIDTH_EXTRACONDENSED;
				break;

			case FC_WIDTH_CONDENSED:
				entry->style |= FL_WIDTH_CONDENSED;
				break;

			case FC_WIDTH_SEMICONDENSED:
				entry->style = FL_WIDTH_SEMICONDENSED;
				break;

			case FC_WIDTH_NORMAL:
			default:
				entry->style |= FL_WIDTH_NORMAL;
				break;

			case FC_WIDTH_SEMIEXPANDED:
				entry->style |= FL_WIDTH_SEMIEXPANDED;
				break;

			case FC_WIDTH_EXPANDED:
				entry->style |= FL_WIDTH_EXPANDED;
				break;

			case FC_WIDTH_EXTRAEXPANDED:
				entry->style |= FL_WIDTH_EXTRAEXPANDED;
				break;

			case FC_WIDTH_ULTRAEXPANDED:
				entry->style |= FL_WIDTH_ULTRAEXPANDED;
				break;
			}
		}
		if(FcPatternGetInteger(font, FC_SPACING, 0, &intvalue) == FcResultMatch)
		{
			switch(intvalue)
			{
			case FC_PROPORTIONAL:
			default:
				entry->style |= FL_PROPORTIONAL;
				break;

			case FC_DUAL:
				entry->style |= FL_DUAL;
				break;

			case FC_MONO:
				entry->style |= FL_MONO;
				break;

			case FC_CHARCELL:
				entry->style |= FL_CHARCELL;
				break;
			}
		}
		if(entry->foundry && strcmp(entry->foundry, "unknown"))
		{
			char tempstr[BCTEXTLEN];
			sprintf(tempstr, "%s (%s)", entry->family, entry->foundry);
			entry->displayname = new char[strlen(tempstr) + 1];
			strcpy(entry->displayname, tempstr);
		}
		else
		{
			entry->displayname = new char[strlen(entry->family) + 1];
			strcpy(entry->displayname, entry->family);
		}
		fontlist->append(entry);
	}
	FcFontSetDestroy(fs);
	return 0;
}
Ejemplo n.º 22
0
    bool create(const QString &dir, CFontEngine &fe)
    {
        bool root(Misc::root()), added = false;
        QString fmapDir(Misc::dirSyntax(root ? KFI_ROOT_CFG_DIR : dir));
        CFile old(fmapDir);
        QStringList entries;
        int i;
        FcPattern *pat = FcPatternCreate();
        FcObjectSet *os = FcObjectSetBuild(FC_FILE, FC_SCALABLE, (void *)0);
        FcFontSet *fs = FcFontList(0, pat, os);

        FcPatternDestroy(pat);
        FcObjectSetDestroy(os);

        for(i = 0; i < fs->nfont; i++)
        {
            QString fName(Misc::fileSyntax(CFcEngine::getFcString(fs->fonts[i], FC_FILE)));
            FcBool scalable = FcFalse;

            if(!fName.isEmpty() && (root || dir.isEmpty() || 0 == fName.find(dir))
               && FcResultMatch == FcPatternGetBool(fs->fonts[i], FC_SCALABLE, 0, &scalable) && scalable)
            {
                const QStringList *existing = old.getEntries(fName);

                if(existing && existing->count())
                    entries += (*existing);
                else
                {
                    int face = 0, numFaces = 0;

                    do
                    {
                        if(fe.openFont(fName, face))
                        {
                            if(fe.hasPsInfo())
                            {
                                if(0 == numFaces)
                                    numFaces = fe.getNumFaces(); // Only really for TTC files...

                                //
                                // Add real
                                addEntry(entries, fe.getPsName(), fName, fmapDir);
                                added = true;

                                //
                                // Add fake entries for X11 generated names
                                switch(fe.getWeight())
                                {
                                    case CFontEngine::WEIGHT_MEDIUM:
                                    case CFontEngine::WEIGHT_REGULAR:
                                    {
                                        QString x11Ps(createX11PsName(fe.getFamilyName()));

                                        if(CFontEngine::ITALIC_ITALIC != fe.getItalic() && CFontEngine::ITALIC_OBLIQUE != fe.getItalic())
                                            addAliasEntry(entries, createName(x11Ps, "Roman", getItalicStr(fe.getItalic())), fe.getPsName());
                                        addAliasEntry(entries, createName(x11Ps, NULL, getItalicStr(fe.getItalic())), fe.getPsName());
                                        break;
                                    }
                                    case CFontEngine::WEIGHT_UNKNOWN:
                                        break;
                                    default:
                                        addAliasEntry(entries, createName(createX11PsName(fe.getFamilyName()), CFontEngine::weightStr(fe.getWeight()),
                                                                          getItalicStr(fe.getItalic())),
                                                      fe.getPsName());
                                }
                            }
                            fe.closeFont();
                        }
                    } while(++face < numFaces);
                }
            }
        }

        bool status = true;

        if(added || entries.count() != old.getLineCount())
        {
            KSaveFile out(fmapDir + FONTMAP);
            QTextStream *stream = out.textStream();

            if(stream)
            {
                QStringList::Iterator it;

                for(it = entries.begin(); it != entries.end(); ++it)
                    *stream << *it << endl;
            }
            else
                status = false;
        }

        //
        // Ensure GS's main Fontmap references our file...
        if(root && status)
        {
            static const char *constGhostscriptDirs[] = {"/usr/share/ghostscript/", "/usr/local/share/ghostscript/", "/usr/share/gs-esp/", NULL};

            QString gsFile = locateFile(FONTMAP, constGhostscriptDirs);

            if(!gsFile.isEmpty())
            {
                const int constMaxLineLen = 1024;
                const char *constRLF = ".runlibfile";

                char line[constMaxLineLen];
                ifstream in(QFile::encodeName(gsFile));

                if(in)
                {
                    QCString fmap(QFile::encodeName(fmapDir + FONTMAP));
                    int lineNum = 0, kfiLine = -1, gsLine = -1, ncLine = -1;

                    do
                    {
                        in.getline(line, constMaxLineLen);

                        if(in.good())
                        {
                            line[constMaxLineLen - 1] = '\0';

                            if(strstr(line, fmap.data()) != NULL && strstr(line, constRLF) != NULL)
                                kfiLine = lineNum;
                            else if(strstr(line, FONTMAP ".GS") != NULL && strstr(line, constRLF) != NULL)
                                gsLine = lineNum;
                            if(-1 == ncLine && '%' != line[0])
                                ncLine = lineNum;
                            lineNum++;
                        }
                    } while(!in.eof() && (-1 == kfiLine || -1 == gsLine));

                    //
                    // If the file doesn't already say to use our Fontmap file, then tell it to!
                    // Also, ensure ours is .runlibfile'd before the main GS one - else problems can occur
                    if(-1 == kfiLine || kfiLine > gsLine)
                    {
                        in.clear();
                        in.seekg(0, ios::end);
                        int size = (streamoff)in.tellg();
                        in.seekg(0, ios::beg);

                        char *buffer = new char[size + strlen(fmap) + strlen(constRLF) + 5];

                        if(buffer)
                        {
                            bool added = false;

                            buffer[0] = '\0';
                            lineNum = 0;

                            do
                            {
                                in.getline(line, constMaxLineLen);

                                if(in.good())
                                {
                                    line[constMaxLineLen - 1] = '\0';

                                    if(lineNum >= ncLine && !added)
                                    {
                                        strcat(buffer, "(");
                                        strcat(buffer, fmap);
                                        strcat(buffer, ") ");
                                        strcat(buffer, constRLF);
                                        strcat(buffer, "\n");
                                        added = true;
                                    }

                                    if(lineNum != kfiLine)
                                    {
                                        strcat(buffer, line);
                                        strcat(buffer, "\n");
                                    }
                                    lineNum++;
                                }
                            } while(!in.eof());

                            in.close();

                            if(added) // Don't re-write GS's Fontmap unless we've actually added something...
                            {
                                KSaveFile out(gsFile);
                                QTextStream *stream = out.textStream();

                                if(stream)
                                    *stream << buffer;
                            }
                            delete[] buffer;
                        }
                    }
                }
            }
        }

        return status;
    }
Ejemplo n.º 23
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;
}
Ejemplo n.º 24
0
nsresult
gfxQtPlatform::UpdateFontList()
{
    FcPattern *pat = NULL;
    FcObjectSet *os = NULL;
    FcFontSet *fs = NULL;
    PRInt32 result = -1;

    pat = FcPatternCreate();
    os = FcObjectSetBuild(FC_FAMILY, FC_FILE, FC_INDEX, FC_WEIGHT, FC_SLANT, FC_WIDTH, NULL);

    fs = FcFontList(NULL, pat, os);


    for (int i = 0; i < fs->nfont; i++) {
        char *str;

        if (FcPatternGetString(fs->fonts[i], FC_FAMILY, 0, (FcChar8 **) &str) != FcResultMatch)
            continue;

        printf("Family: %s\n", str);

        nsAutoString name(NS_ConvertUTF8toUTF16(nsDependentCString(str)).get());
        nsAutoString key(name);
        ToLowerCase(key);
        nsRefPtr<FontFamily> ff;
        if (!gPlatformFonts->Get(key, &ff)) {
            ff = new FontFamily(name);
            gPlatformFonts->Put(key, ff);
        }

        FontEntry *fe = new FontEntry(ff->Name());
        ff->AddFontEntry(fe);

        if (FcPatternGetString(fs->fonts[i], FC_FILE, 0, (FcChar8 **) &str) == FcResultMatch) {
            fe->mFilename = nsDependentCString(str);
            printf(" - file: %s\n", str);
        }

        int x;
        if (FcPatternGetInteger(fs->fonts[i], FC_INDEX, 0, &x) == FcResultMatch) {
            printf(" - index: %d\n", x);
            fe->mFTFontIndex = x;
        } else {
            fe->mFTFontIndex = 0;
        }

        if (FcPatternGetInteger(fs->fonts[i], FC_WEIGHT, 0, &x) == FcResultMatch) {
            switch(x) {
            case 0:
                fe->mWeight = 100;
                break;
            case 40:
                fe->mWeight = 200;
                break;
            case 50:
                fe->mWeight = 300;
                break;
            case 75:
            case 80:
                fe->mWeight = 400;
                break;
            case 100:
                fe->mWeight = 500;
                break;
            case 180:
                fe->mWeight = 600;
                break;
            case 200:
                fe->mWeight = 700;
                break;
            case 205:
                fe->mWeight = 800;
                break;
            case 210:
                fe->mWeight = 900;
                break;
            default:
                // rough estimate
                fe->mWeight = (((x * 4) + 100) / 100) * 100;
                break;
            }
            printf(" - weight: %d\n", fe->mWeight);
        }

        fe->mItalic = PR_FALSE;
        if (FcPatternGetInteger(fs->fonts[i], FC_SLANT, 0, &x) == FcResultMatch) {
            switch (x) {
            case FC_SLANT_ITALIC:
            case FC_SLANT_OBLIQUE:
                fe->mItalic = PR_TRUE;
            }
            printf(" - slant: %d\n", x);
        }

        if (FcPatternGetInteger(fs->fonts[i], FC_WIDTH, 0, &x) == FcResultMatch)
            printf(" - width: %d\n", x);
        // XXX deal with font-stretch stuff later
    }

    if (pat)
        FcPatternDestroy(pat);
    if (os)
        FcObjectSetDestroy(os);
    if (fs)
        FcFontSetDestroy(fs);

    return sFontconfigUtils->UpdateFontList();
}
Ejemplo n.º 25
0
static XftFont *gui_find_font(winlist_t *win, FcChar32 ucs4)
{
    unsigned int i;
    int weight, slant, scalable;
    double font_size;
    FcFontSet *fontset;
    XftFont *font = NULL;

    /* 缺字列表有這個字,那就不用再找啦 */
    if (FcCharSetHasChar(gui->missing_chars, ucs4))
    {
	return NULL;
    }

    /* 找出 Cache 相符的字型 */
    for (i=0 ; i < gui->num_fonts ; i++)
    {
	XftPatternGetDouble(gui->xftfonts[i]->pattern, XFT_PIXEL_SIZE, 0, &font_size);
	if ((int)font_size == win->font_size &&
	    FcCharSetHasChar(gui->xftfonts[i]->charset, ucs4))
	{
	    return gui->xftfonts[i];
	}
    }

    /* 列出所有可能的字型 */
    FcObjectSet *os = FcObjectSetBuild(FC_FAMILY, FC_FILE, FC_INDEX, FC_CHARSET, NULL);
    /* 只要標準、非斜體、可縮放字型即可 */
    FcPattern *listpat = FcPatternBuild(NULL,
				FC_SLANT, FcTypeInteger, FC_SLANT_ROMAN,
				FC_SCALABLE, FcTypeBool, FcTrue,
				NULL);
    fontset = FcFontList(NULL, listpat, os);
    FcPatternDestroy(listpat);
    FcObjectSetDestroy(os);

    for (i=0; i< fontset->nfont; i++)
    {
	FcPattern *pat = fontset->fonts[i];
	FcCharSet *fcs = NULL;

	if (FcPatternGetCharSet(pat, FC_CHARSET, 0, &fcs) != FcResultMatch)
	    continue;

	if (!FcCharSetHasChar(fcs, ucs4))
	    continue;

	FcResult res;
	FcPattern *mpat = FcFontMatch(0, pat, &res);
	if (!mpat)
	    continue;

	XftPatternAddDouble(mpat, XFT_PIXEL_SIZE, (double)win->font_size);
	XftFont *chkfont = XftFontOpenPattern(gui->display, mpat);

        if (chkfont)
	{
	    gui->num_fonts ++;
	    gui->xftfonts = (XftFont **)oxim_realloc(gui->xftfonts, gui->num_fonts * sizeof(XftFont *));
	    if (!gui->xftfonts)
	    {
		FcPatternDestroy(mpat);
		continue;
	    }
	    gui->xftfonts[gui->num_fonts - 1] = chkfont;
	    font = chkfont;
	    break;
	}
	else
	{
	    FcPatternDestroy(mpat);
	}
    }

    FcFontSetDestroy(fontset);

    if (!font)
	FcCharSetAddChar(gui->missing_chars, ucs4);

    return font;
}
Ejemplo n.º 26
0
/* Constructor of the object : it allocates memory and initializes the member
 * of the new object.
 * The user must give the FcPattern of the font or the master (which may be NULL
 * in which case the character map will be empty).
 */
__GLCcharMap* __glcCharMapCreate(const __GLCmaster* inMaster,
				 const __GLCcontext* inContext)
{
  __GLCcharMap* This = NULL;

  assert(inContext);

  This = (__GLCcharMap*)__glcMalloc(sizeof(__GLCcharMap));
  if (!This) {
    __glcRaiseError(GLC_RESOURCE_ERROR);
    return NULL;
  }
  memset(This, 0, sizeof(__GLCcharMap));

  This->charSet = FcCharSetCreate();
  if (!This->charSet) {
    __glcRaiseError(GLC_RESOURCE_ERROR);
    __glcFree(This);
    return NULL;
  }

  if (inMaster) {
    FcCharSet* charSet = NULL;
    FcFontSet* fontSet = NULL;
    int i = 0;
    FcObjectSet* objectSet = NULL;
    FcPattern* pattern = FcPatternCreate();

    if (!pattern) {
      __glcRaiseError(GLC_RESOURCE_ERROR);
      FcCharSetDestroy(This->charSet);
      __glcFree(This);
      return NULL;
    }

    objectSet = FcObjectSetBuild(FC_FAMILY, FC_FOUNDRY, FC_SPACING, FC_OUTLINE,
				 FC_CHARSET, NULL);
    if (!objectSet) {
      __glcRaiseError(GLC_RESOURCE_ERROR);
      FcPatternDestroy(pattern);
      FcCharSetDestroy(This->charSet);
      __glcFree(This);
      return NULL;
    }

    fontSet = FcFontList(inContext->config, pattern, objectSet);
    FcObjectSetDestroy(objectSet);
    FcPatternDestroy(pattern);
    if (!fontSet) {
      __glcRaiseError(GLC_RESOURCE_ERROR);
      FcCharSetDestroy(This->charSet);
      __glcFree(This);
      return NULL;
    }

    for (i = 0; i < fontSet->nfont; i++) {
      FcChar8* family = NULL;
      int fixed = 0;
      FcChar8* foundry = NULL;
      FcBool outline = FcFalse;
      FcBool equal = FcFalse;
#ifdef DEBUGMODE
      FcResult result = FcResultMatch;

      result = FcPatternGetBool(fontSet->fonts[i], FC_OUTLINE, 0, &outline);
      assert(result != FcResultTypeMismatch);
#else
      FcPatternGetBool(fontSet->fonts[i], FC_OUTLINE, 0, &outline);
#endif

      /* Check whether the glyphs are outlines */
      if (!outline)
	continue;

#ifdef DEBUGMODE
      result = FcPatternGetString(fontSet->fonts[i], FC_FAMILY, 0, &family);
      assert(result != FcResultTypeMismatch);
      result = FcPatternGetString(fontSet->fonts[i], FC_FOUNDRY, 0, &foundry);
      assert(result != FcResultTypeMismatch);
      result = FcPatternGetInteger(fontSet->fonts[i], FC_SPACING, 0, &fixed);
      assert(result != FcResultTypeMismatch);
#else
      FcPatternGetString(fontSet->fonts[i], FC_FAMILY, 0, &family);
      FcPatternGetString(fontSet->fonts[i], FC_FOUNDRY, 0, &foundry);
      FcPatternGetInteger(fontSet->fonts[i], FC_SPACING, 0, &fixed);
#endif

      if (foundry)
	pattern = FcPatternBuild(NULL, FC_FAMILY, FcTypeString, family,
				 FC_FOUNDRY, FcTypeString, foundry, FC_SPACING,
				 FcTypeInteger, fixed, NULL);
      else
	pattern = FcPatternBuild(NULL, FC_FAMILY, FcTypeString, family,
				 FC_SPACING, FcTypeInteger, fixed, NULL);

      if (!pattern) {
	__glcRaiseError(GLC_RESOURCE_ERROR);
	FcCharSetDestroy(This->charSet);
	FcFontSetDestroy(fontSet);
	__glcFree(This);
	return NULL;
      }

      equal = FcPatternEqual(pattern, inMaster->pattern);
      FcPatternDestroy(pattern);
      if (equal) {
        FcCharSet* newCharSet = NULL;

#ifdef DEBUGMODE
        result = FcPatternGetCharSet(fontSet->fonts[i], FC_CHARSET, 0,
				     &charSet);
        assert(result != FcResultTypeMismatch);
#else
	FcPatternGetCharSet(fontSet->fonts[i], FC_CHARSET, 0, &charSet);
#endif

        newCharSet = FcCharSetUnion(This->charSet, charSet);
	if (!newCharSet) {
          __glcRaiseError(GLC_RESOURCE_ERROR);
          FcCharSetDestroy(This->charSet);
          FcFontSetDestroy(fontSet);
          __glcFree(This);
          return NULL;
	}

	FcCharSetDestroy(This->charSet);
	This->charSet = newCharSet;
      }
    }

    FcFontSetDestroy(fontSet);
  }

  /* The array 'map' will contain the actual character map */
  This->map = __glcArrayCreate(sizeof(__GLCcharMapElement));
  if (!This->map) {
    FcCharSetDestroy(This->charSet);
    __glcFree(This);
    return NULL;
  }

  return This;
}
Ejemplo n.º 27
0
int zaFont::fontconf(const char * charset)
{
	FcFontSet* fs = NULL;
	FcPattern* pat = NULL;
	FcObjectSet* os = NULL;
	//FcChar8* strpat = (FcChar8*)":lang=ja";
	string ls = ":lang=";
	ls.append(charset);

	FcChar8* strpat = (FcChar8*)ls.c_str();
	fprintf(stderr,"zaFont::fontconf charset %s\n",strpat);

	pat = FcNameParse(strpat);
	os = FcObjectSetBuild(FC_FAMILY, FC_CHARSET, FC_STYLE,FC_FILE, (char *)0);
	fs = FcFontList(0, pat, os);
	if(os)
	  FcObjectSetDestroy(os);
	os = NULL;
	  FcPatternDestroy(pat);
	pat = NULL;
	  if(!fs || fs->nfont <= 0)
	  goto nofont;
	 FcChar8 *family;
	FcChar8 *style;
	FcChar8 *file;
	FcCharSet* cs;
	FcChar32 ch;
	FcUtf8ToUcs4((FcChar8*)"这", &ch, 3);
	int i;
	for(i=0; i<fs->nfont; i++)
	{
		  if(FcPatternGetCharSet(fs->fonts[i], FC_CHARSET, 0, &cs) != FcResultMatch)
		  {
			  fprintf(stderr, "no match\n");
			  FcPatternPrint(fs->fonts[i]);
			  goto nofont;
		  }

		  if(FcPatternGetString(fs->fonts[i], FC_FAMILY, 1, &family) != FcResultMatch)
			 if(FcPatternGetString(fs->fonts[i], FC_FAMILY, 0, &family) != FcResultMatch)
			 goto nofont;

	//	  fprintf(stderr,"zaFont::fontconf [%d] %s \n", i, (char *)family);

		  if(FcPatternGetString(fs->fonts[i], FC_STYLE, 0, &style) != FcResultMatch)
			  goto nofont;
	//	  fprintf(stderr,"zaFont::fontconf [%d] %s \n", i, (char *)style);

		  if(FcPatternGetString(fs->fonts[i], FC_FILE, 0, &file) != FcResultMatch)
					  goto nofont;
	//	  fprintf(stderr, "zaFont::fontconf (%s): \n", (char *)file);
		  strcpy(m_charset,charset);
		  strcpy(this->m_path,(char *)file);

		  if(strstr((char*)file,"arial.ttf"))
			  break;

//		  if(FcCharSetHasChar(cs, ch))
//		  {
//			  puts("Yes");
//		  }else
//		  {
//			  puts("No");
//		  }
	}
	FcFontSetDestroy(fs);
	return 0;

	nofont:
		return 1;
}
Ejemplo n.º 28
0
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;
}
Ejemplo n.º 29
0
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;
}
Ejemplo n.º 30
0
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;
}