Example #1
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);
}
Example #2
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;
}
	map<string, string> populateHelper()
	{
		map<string, string> rtn;
		for (int i = 0; fontConfigFontSet != NULL && i < fontConfigFontSet->nfont; i++)
		{
			FcPattern *font = fontConfigFontSet->fonts[i];
			string s = string((char *)FcNameUnparse(font));
			rtn[s.substr(0, s.find(":"))] = s.substr(s.find("=")+1);
		}
		return rtn;
	}
Example #4
0
Bool
XftNameUnparse (XftPattern *pat, char *dest, int len)
{
    FcChar8 *name = FcNameUnparse (pat);
    if (!name)
        return FcFalse;
    if (strlen ((char *) name) > len - 1)
    {
        free (name);
        return FcFalse;
    }
    strcpy (dest, (void *) name);
    free (name);
    return FcTrue;
}
Example #5
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;
}
Example #6
0
/**
 * using fontconfig for just getting the font file name by a wanted font name and style.
 */
char *get_font_filename(const char *family, const char *style) {
	//initialize fontconfig
	if (!FcInit()) {
		throw util::Error{MSG(err) << "Failed to initialize fontconfig."};
	}

	//FcPattern *font_pattern = FcNameParse((const unsigned char *)"DejaVu Serif:style=Book");
	FcPattern *font_pattern = FcPatternBuild(nullptr, FC_FAMILY, FcTypeString, family, nullptr);
	FcPatternBuild(font_pattern, FC_STYLE, FcTypeString, style, nullptr);

	//debug output: display above pattern as parsable string.
	FcChar8 *query_string = FcNameUnparse(font_pattern);
	log::log(MSG(info) << "Font queried: " << query_string);
	free(query_string);

	//tell fontconfig to find the best match
	FcResult font_match_result;
	FcPattern *font_match = FcFontMatch(nullptr, font_pattern, &font_match_result);

	/*
	//debug output: display matching font pattern as parsable string
	FcChar8 *match_string = FcNameUnparse(font_match);
	log::dbg2("resulting font: %s", match_string);
	free(match_string);
	*/

	//get attibute FC_FILE (= filename) of best-matched font
	FcChar8 *font_filename_tmp;
	if (FcPatternGetString(font_match, FC_FILE, 0, &font_filename_tmp) != FcResultMatch) {
		throw util::Error(MSG(err) << "Fontconfig could not provide font " << family << " " << style);
	}

	//copy the font filename because it will be freed when the pattern is destroyed.
	char *font_filename = util::copy((const char *)font_filename_tmp);

	log::log(MSG(info) << "Font file: " << font_filename);

	//deinitialize fontconfig.
	FcPatternDestroy(font_match);
	FcPatternDestroy(font_pattern);
	FcFini();

	return font_filename;
}
Example #7
0
void
JXFontManager::GetMonospaceFontNames
	(
	JPtrArray<JString>* fontNames
	)
	const
{
	if (itsMonoFontNames != NULL)
		{
		fontNames->CopyObjects(*itsMonoFontNames, fontNames->GetCleanUpAction(), kJFalse);
		}
	else
		{
		(JXGetApplication())->DisplayBusyCursor();

		fontNames->CleanOut();
		fontNames->SetCompareFunction(JCompareStringsCaseInsensitive);
		fontNames->SetSortOrder(JOrderedSetT::kSortAscending);

		JPtrArray<JString> allFontNames(JPtrArrayT::kDeleteAll);
		allFontNames.SetCompareFunction(JCompareStringsCaseInsensitive);
		allFontNames.SetSortOrder(JOrderedSetT::kSortAscending);

		JString name;

#if ENABLE_TRUE_TYPE

		FcFontSet* set =
			XftListFonts(*itsDisplay, itsDisplay->GetScreen(),
						 FC_SPACING, FcTypeInteger, FC_MONO, NULL,
						 FC_FAMILY, NULL);
		for (int i=0; i < set->nfont; i++)
			{
			FcChar8* s = FcNameUnparse(set->fonts[i]);
			name.Set((JCharacter*) s);
//			cout << "tt  mono: " << name << endl;

#if ONLY_STD_MONOSPACE

			if (!name.BeginsWith("Courier") &&
				!name.BeginsWith("Consolas") &&
				!name.Contains(" Mono")     &&
				name != "LucidaTypewriter")
				{
				FcStrFree(s);
				continue;
				}

#endif

			if (IsUseless(name))
				{
				FcStrFree(s);
				continue;
				}

			JBoolean isDuplicate;
			const JIndex index =
				allFontNames.GetInsertionSortIndex(&name, &isDuplicate);
			if (!isDuplicate)
				{
				allFontNames.InsertAtIndex(index, name);

				JString* n = new JString(name);
				assert( n != NULL );
				const JBoolean ok = fontNames->InsertSorted(n, kJFalse);
				assert( ok );
				}

			FcStrFree(s);
			}
		FcFontSetDestroy(set);

#else

		for (int j=0; j<kMonospaceFontPatternCount; j++)
			{
			int nameCount;
			char** nameList = XListFonts(*itsDisplay, kMonospaceFontPattern[j],
										 INT_MAX, &nameCount);
			if (nameList == NULL)
				{
				return;
				}

			for (int i=0; i<nameCount; i++)
				{
				const std::string s(nameList[i], strlen(nameList[i]));
				std::istringstream input(s);
				input.ignore();						// initial dash
				JIgnoreUntil(input, '-');			// foundry name
				name = JReadUntil(input, '-');		// font name

				if (name.IsEmpty() || name == "nil")
					{
					continue;
					}

				ConvertToPSFontName(&name);
//				cout << "std mono: " << name << endl;

#if ONLY_STD_MONOSPACE

				if (name != "Clean" && name != "Fixed" && name != "Terminal" &&
					name != "Courier" && name != "Lucidatypewriter" &&
					name != "Profontwindows")
					{
					continue;
					}

#endif

				if (IsUseless(name))
					{
					continue;
					}

				JBoolean isDuplicate;
				const JIndex index =
					allFontNames.GetInsertionSortIndex(&name, &isDuplicate);
				if (!isDuplicate)
					{
					allFontNames.InsertAtIndex(index, name);

					XFontStruct* xfont = XLoadQueryFont(*itsDisplay, nameList[i]);
					if (xfont != NULL)
						{
						if (xfont->min_bounds.width == xfont->max_bounds.width)
							{
							JString* n = new JString(name);
							assert( n != NULL );
							const JBoolean ok = fontNames->InsertSorted(n, kJFalse);
							assert( ok );
							}
						XFreeFont(*itsDisplay, xfont);
						}
					}
				}

			XFreeFontNames(nameList);
			}

#endif

		// save names for next time

		itsMonoFontNames = new JDCCPtrArray<JString>(*fontNames, JPtrArrayT::kDeleteAll);
		assert( itsMonoFontNames != NULL );
		}
}
Example #8
0
void
JXFontManager::GetFontNames
	(
	JPtrArray<JString>* fontNames
	)
	const
{
	if (itsAllFontNames != NULL)
		{
		fontNames->CopyObjects(*itsAllFontNames, fontNames->GetCleanUpAction(), kJFalse);
		}
	else
		{
		fontNames->CleanOut();
		fontNames->SetCompareFunction(JCompareStringsCaseInsensitive);
		fontNames->SetSortOrder(JOrderedSetT::kSortAscending);

		JString name;

#if ENABLE_TRUE_TYPE

		FcFontSet* set = XftListFonts(*itsDisplay, itsDisplay->GetScreen(), NULL, FC_FAMILY, NULL);
		for (int i=0; i < set->nfont; i++)
			{
			FcChar8* s = FcNameUnparse(set->fonts[i]);
			name.Set((JCharacter*) s);
//			cout << "tt  font: " << name << endl;

			if (!IsPostscript(name) || IsUseless(name))
				{
				FcStrFree(s);
				continue;
				}

			JBoolean isDuplicate;
			const JIndex index = fontNames->GetInsertionSortIndex(&name, &isDuplicate);
			if (!isDuplicate)
				{
				fontNames->InsertAtIndex(index, name);
				}

			FcStrFree(s);
			}
		FcFontSetDestroy(set);

#endif

		int nameCount;
		char** nameList = XListFonts(*itsDisplay, "-*-*-medium-r-normal-*-*-*-75-75-*-*-*-*",
									 INT_MAX, &nameCount);
		if (nameList == NULL)
			{
			return;
			}

		for (int i=0; i<nameCount; i++)
			{
			const std::string s(nameList[i], strlen(nameList[i]));
			std::istringstream input(s);
			input.ignore();						// initial dash
			JIgnoreUntil(input, '-');			// foundry name
			name = JReadUntil(input, '-');		// font name

			if (name.IsEmpty() || name == "nil")
				{
				continue;
				}

			ConvertToPSFontName(&name);
//			cout << "std font: " << name << endl;

			if (!IsPostscript(name) || IsUseless(name))
				{
				continue;
				}

			JBoolean isDuplicate;
			const JIndex index = fontNames->GetInsertionSortIndex(&name, &isDuplicate);
			if (!isDuplicate)
				{
				fontNames->InsertAtIndex(index, name);
				}
			}

		XFreeFontNames(nameList);

		// save names for next time

		itsAllFontNames = new JDCCPtrArray<JString>(*fontNames, JPtrArrayT::kDeleteAll);
		assert( itsAllFontNames != NULL );
		}
}
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;
}
Example #10
0
/**
 * grx_font_load_full:
 * @family: (nullable): the font family name or %NULL
 * @size: the preferred size in points or -1 for any size
 * @dpi: the screen resolution or -1 to ignore dpi
 * @weight: the font weight (e.g. bold) or -1 for any weight
 * @slant: the font slant (e.g. italic) or -1 for any slant
 * @width: the font width (e.g. narrow) or -1 for any width
 * @monospace: set to %TRUE to prefer a monospace font
 * @lang: (nullable): a RFC-3066-style language code or %NULL
 * @script: (nullable): an ISO 15924 script code or %NULL
 * @err: pointer to hold an error
 *
 * Loads the font that best matches the parameters.
 *
 * Uses fontconfig for font matching.
 *
 * Returns: (transfer full) (nullable): the font or %NULL if there was an error
 */
GrxFont *grx_font_load_full(const gchar *family, gint size, gint dpi,
                            GrxFontWeight weight, GrxFontSlant slant,
                            GrxFontWidth width, gboolean monospace,
                            const gchar *lang, const gchar *script, GError **err)
{
    FcPattern *pattern, *match;
    FcResult result;
    GrxFont *font;
    FcChar8 *file;

    if (!FcInit()) {
        g_set_error_literal(err, GRX_ERROR, GRX_ERROR_FONT_ERROR,
            "Failed to init fontconfig");
        return NULL;
    }

    pattern = FcPatternCreate();
    FcPatternAddBool(pattern, FC_SCALABLE, FcFalse);
    FcPatternAddBool(pattern, FC_OUTLINE, FcFalse);
    FcPatternAddString(pattern, FC_FONTFORMAT, (FcChar8 *)"PCF");
    if (family) {
        FcPatternAddString(pattern, FC_FAMILY, (FcChar8 *)family);
    }
    if (size >= 0) {
        FcPatternAddDouble(pattern, FC_SIZE, size);
    }
    if (dpi >= 0) {
        FcPatternAddDouble(pattern, FC_DPI, dpi);
    }
    switch (weight) {
    case GRX_FONT_WEIGHT_REGULAR:
        FcPatternAddInteger(pattern, FC_WEIGHT, 80);
        break;
    case GRX_FONT_WEIGHT_BOLD:
        FcPatternAddInteger(pattern, FC_WEIGHT, 200);
        break;
    }
    switch (slant) {
    case GRX_FONT_SLANT_REGULAR:
        FcPatternAddInteger(pattern, FC_SLANT, 0);
        break;
    case GRX_FONT_SLANT_ITALIC:
        FcPatternAddInteger(pattern, FC_SLANT, 100);
        break;
    }
    switch (width) {
    case GRX_FONT_WIDTH_NARROW:
        FcPatternAddInteger(pattern, FC_WIDTH, 75);
        break;
    case GRX_FONT_WIDTH_REGULAR:
        FcPatternAddInteger(pattern, FC_WIDTH, 100);
        break;
    case GRX_FONT_WIDTH_WIDE:
        FcPatternAddInteger(pattern, FC_WIDTH, 125);
        break;
    }
    if (monospace) {
        FcPatternAddInteger(pattern, FC_SPACING, 100);
    }
    if (lang) {
        FcPatternAddString(pattern, FC_LANG, (FcChar8 *)lang);
    }
    if (script) {
        FcPatternAddCharSet(pattern, FC_CHARSET, script_to_charset(script));
    }
    {
        FcChar8 *pattern_str;

        pattern_str = FcNameUnparse(pattern);
        g_debug("searching for pattern: %s", pattern_str);
        free(pattern_str);
    }

    FcConfigSubstitute(NULL, pattern, FcMatchPattern);
    FcDefaultSubstitute(pattern);
    match = FcFontMatch(NULL, pattern, &result);

    if (!match) {
        // TODO: use result for better error
        g_set_error_literal(err, GRX_ERROR, GRX_ERROR_FONT_ERROR,
            "Failed to find match");
        FcPatternDestroy(pattern);
        return NULL;
    }

    if (FcPatternGetString(match, FC_FILE, 0, &file) != FcResultMatch) {
        g_set_error_literal(err, GRX_ERROR, GRX_ERROR_FONT_ERROR,
            "Failed to get file name");
        FcPatternDestroy(match);
        FcPatternDestroy(pattern);
        return NULL;
    }

    font = grx_font_load_from_file((gchar *)file, err);

    FcPatternDestroy(match);
    FcPatternDestroy(pattern);

    return font;
}
Example #11
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;
}