static gboolean
language_has_font (const gchar *locale)
{
        const FcCharSet *charset;
        FcPattern       *pattern;
        FcObjectSet     *object_set;
        FcFontSet       *font_set;
        gchar           *language_code;
        gboolean         is_displayable;

        is_displayable = FALSE;
        pattern = NULL;
        object_set = NULL;
        font_set = NULL;

        if (!gdm_parse_language_name (locale, &language_code, NULL, NULL, NULL))
                return FALSE;

        charset = FcLangGetCharSet ((FcChar8 *) language_code);
        if (!charset) {
                /* fontconfig does not know about this language */
                is_displayable = TRUE;
        }
        else {
                /* see if any fonts support rendering it */
                pattern = FcPatternBuild (NULL, FC_LANG, FcTypeString, language_code, NULL);

                if (pattern == NULL)
                        goto done;

                object_set = FcObjectSetCreate ();

                if (object_set == NULL)
                        goto done;

                font_set = FcFontList (NULL, pattern, object_set);

                if (font_set == NULL)
                        goto done;

                is_displayable = (font_set->nfont > 0);
        }

 done:
        if (font_set != NULL)
                FcFontSetDestroy (font_set);

        if (object_set != NULL)
                FcObjectSetDestroy (object_set);

        if (pattern != NULL)
                FcPatternDestroy (pattern);

        g_free (language_code);

        return is_displayable;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
0
	std::string FontConfig::match_font(const std::string &typeface_name, const FontDescription &desc) const
	{
		FcPattern * fc_pattern = nullptr;
		FcPattern * fc_match = nullptr;
		try
		{
			int weight = static_cast<int>(desc.get_weight());

			// Build font matching pattern.
			fc_pattern = FcPatternBuild(nullptr,
				FC_FAMILY, FcTypeString, typeface_name.c_str(),
				FC_PIXEL_SIZE, FcTypeDouble, (double)std::abs(desc.get_height()),
				FC_WEIGHT, FcTypeInteger, (weight > 0) ? (int)(weight * (FC_WEIGHT_HEAVY / 900.0)) : FC_WEIGHT_NORMAL,
				FC_SLANT, FcTypeInteger, (desc.get_style() == clan::FontStyle::italic) ? FC_SLANT_ITALIC : ((desc.get_style() == clan::FontStyle::oblique) ? FC_SLANT_OBLIQUE : FC_SLANT_ROMAN),
				FC_SPACING, FcTypeInteger, FC_PROPORTIONAL,
				(char*) nullptr
				);
			if (!fc_pattern)
			{
				throw Exception("CL_FontConfig: Building FontConfig pattern failed.");
			}

			// Execute any needed param substitutions required by the system config.
			if (FcTrue != FcConfigSubstitute(fc_config, fc_pattern, FcMatchPattern))
			{
				throw Exception("CL_FontConfig: Font config substitutions failed.");
			}

			// Supply default values for underspecified font patterns. Never fails.
			FcDefaultSubstitute(fc_pattern);

			// Find best match for pattern and extract filename.
			FcResult match_result; // Doesn't appear to be actually updated.
			fc_match = FcFontMatch(fc_config, fc_pattern, &match_result);
			FcChar8 * fc_font_file_path = nullptr;
			if (FcResultMatch != FcPatternGetString(fc_match, FC_FILE, 0, &fc_font_file_path))
			{
				throw Exception("CL_FontConfig: Could not resolve font pattern to a font file.");
			}

			// Release resources and return results.
			std::string cl_font_file_path((char*)fc_font_file_path);
			FcPatternDestroy(fc_match);
			FcPatternDestroy(fc_pattern);
			return cl_font_file_path;
		}
		catch (...)
		{
			// If any exceptions thrown, ensure fontconfig resources are released.
			if (fc_match) FcPatternDestroy(fc_match);
			if (fc_pattern) FcPatternDestroy(fc_pattern);
			throw;
		}
	}
Ejemplo n.º 4
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.º 5
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.º 6
0
static inline XftFont *
get_font(Display *xdisplay, FT_Face face, gint size, FcCharSet *charset)
{
    FcPattern *pattern;
    XftFont *font;
    int screen = DefaultScreen (xdisplay);

    pattern = FcPatternBuild(NULL,
			     FC_FT_FACE, FcTypeFTFace, face,
			     FC_PIXEL_SIZE, FcTypeDouble, (double)size,
			     NULL);

    if (charset)
	FcPatternAddCharSet (pattern, "charset", charset);

    FcConfigSubstitute (NULL, pattern, FcMatchPattern);
    XftDefaultSubstitute (xdisplay, screen, pattern);

    font = XftFontOpenPattern(xdisplay, pattern);

    return font;
}
Ejemplo n.º 7
0
static int find_font(info_rec* info, char* family, char* path)
{
    FcPattern*	pattern;
    FcPattern*	matchedPattern;
    FcResult	result;
    FcChar8*	s;

    pattern = FcPatternBuild(NULL, FC_FAMILY, FcTypeString, family,
                             (char*) NULL);
    if (pattern == NULL)
        return YUV_fontconfig;
    if (FcConfigSubstitute(info->config, pattern, FcMatchPattern) != FcTrue)
        return YUV_fontconfig;
    FcDefaultSubstitute(pattern);
    matchedPattern = FcFontMatch(info->config, pattern, &result);
    FcPatternDestroy(pattern);
    if (FcPatternGetString(matchedPattern, FC_FILE, 0, &s) != FcResultMatch)
        return YUV_fontconfig;
    strcpy(path, (char*)s);
    FcPatternDestroy(matchedPattern);
    return YUV_OK;
}
Ejemplo n.º 8
0
std::string PdfFontCache::GetFontConfigFontPath( FcConfig* pConfig, const char* pszFontName, bool bBold, bool bItalic )
{
    FcPattern*  pattern;
    FcPattern*  matched;
    FcResult    result = FcResultMatch;
    FcValue     v;
    std::string sPath;

    // Build a pattern to search using fontname, bold and italic
    pattern = FcPatternBuild (0, FC_FAMILY, FcTypeString, pszFontName, 
                              FC_WEIGHT, FcTypeInteger, (bBold ? FC_WEIGHT_BOLD : FC_WEIGHT_MEDIUM),
                              FC_SLANT, FcTypeInteger, (bItalic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN),  
                              static_cast<char*>(0));

    FcDefaultSubstitute( pattern );

    if( !FcConfigSubstitute( pConfig, pattern, FcMatchFont ) )
    {
        FcPatternDestroy( pattern );
        return sPath;
    }

    matched = FcFontMatch( pConfig, pattern, &result );
    if( result != FcResultNoMatch )
    {
        result = FcPatternGet( matched, FC_FILE, 0, &v );
        sPath = reinterpret_cast<const char*>(v.u.s);
#ifdef PODOFO_VERBOSE_DEBUG
        printf("Got Font %s for for %s\n", sPath.c_str(), pszFontname );
#endif // PODOFO_DEBUG
    }

    FcPatternDestroy( pattern );
    FcPatternDestroy( matched );
    return sPath;
}
static void setup_font_sample(GtkWidget* darea, Antialiasing antialiasing, Hinting hinting)
{
	const char* string1 = "abcfgop AO ";
	const char* string2 = "abcfgop";

	XftColor black, white;
	XRenderColor rendcolor;

	Display* xdisplay = gdk_x11_get_default_xdisplay();

#if GTK_CHECK_VERSION (3, 0, 0)
	Colormap xcolormap = DefaultColormap(xdisplay, 0);
#else
	GdkColormap* colormap = gdk_rgb_get_colormap();
	Colormap xcolormap = GDK_COLORMAP_XCOLORMAP(colormap);
#endif

#if GTK_CHECK_VERSION (3, 0, 0)
	GdkVisual* visual = gdk_visual_get_system ();
#else
	GdkVisual* visual = gdk_colormap_get_visual(colormap);
#endif
	Visual* xvisual = GDK_VISUAL_XVISUAL(visual);

	FcPattern* pattern;
	XftFont* font1;
	XftFont* font2;
	XGlyphInfo extents1 = { 0 };
	XGlyphInfo extents2 = { 0 };
#if !GTK_CHECK_VERSION (3, 0, 0)
	GdkPixmap* pixmap;
#endif
	XftDraw* draw;
	GdkPixbuf* tmp_pixbuf;
	GdkPixbuf* pixbuf;

	int width, height;
	int ascent, descent;

	pattern = FcPatternBuild (NULL,
		FC_FAMILY, FcTypeString, "Serif",
		FC_SLANT, FcTypeInteger, FC_SLANT_ROMAN,
		FC_SIZE, FcTypeDouble, 18.,
		NULL);
	font1 = open_pattern (pattern, antialiasing, hinting);
	FcPatternDestroy (pattern);

	pattern = FcPatternBuild (NULL,
		FC_FAMILY, FcTypeString, "Serif",
		FC_SLANT, FcTypeInteger, FC_SLANT_ITALIC,
		FC_SIZE, FcTypeDouble, 20.,
		NULL);
	font2 = open_pattern (pattern, antialiasing, hinting);
	FcPatternDestroy (pattern);

	ascent = 0;
	descent = 0;
	
	if (font1)
	{
		XftTextExtentsUtf8 (xdisplay, font1, (unsigned char*) string1,
		strlen (string1), &extents1);
		ascent = MAX (ascent, font1->ascent);
		descent = MAX (descent, font1->descent);
	}

	if (font2)
	{
		XftTextExtentsUtf8 (xdisplay, font2, (unsigned char*) string2, strlen (string2), &extents2);
		ascent = MAX (ascent, font2->ascent);
		descent = MAX (descent, font2->descent);
	}

	width = extents1.xOff + extents2.xOff + 4;
	height = ascent + descent + 2;

#if !GTK_CHECK_VERSION (3, 0, 0)
	pixmap = gdk_pixmap_new (NULL, width, height, visual->depth);
#endif

#if GTK_CHECK_VERSION (3, 0, 0)
	draw = XftDrawCreate (xdisplay, GDK_WINDOW_XID (gdk_screen_get_root_window (gdk_screen_get_default ())), xvisual, xcolormap);
#else
	draw = XftDrawCreate (xdisplay, GDK_DRAWABLE_XID (pixmap), xvisual, xcolormap);
#endif

	rendcolor.red = 0;
	rendcolor.green = 0;
	rendcolor.blue = 0;
	rendcolor.alpha = 0xffff;
	
	XftColorAllocValue(xdisplay, xvisual, xcolormap, &rendcolor, &black);

	rendcolor.red = 0xffff;
	rendcolor.green = 0xffff;
	rendcolor.blue = 0xffff;
	rendcolor.alpha = 0xffff;
	
	XftColorAllocValue(xdisplay, xvisual, xcolormap, &rendcolor, &white);
	XftDrawRect(draw, &white, 0, 0, width, height);
	
	if (font1)
	{
		XftDrawStringUtf8(draw, &black, font1, 2, 2 + ascent, (unsigned char*) string1, strlen(string1));
	}
	
	if (font2)
	{
		XftDrawStringUtf8(draw, &black, font2, 2 + extents1.xOff, 2 + ascent, (unsigned char*) string2, strlen(string2));
	}

	XftDrawDestroy(draw);

	if (font1)
	{
		XftFontClose(xdisplay, font1);
	}
	
	if (font2)
	{
		XftFontClose(xdisplay, font2);
	}

#if GTK_CHECK_VERSION (3, 0, 0)
	tmp_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE,8, width, height);
#else
	tmp_pixbuf = gdk_pixbuf_get_from_drawable(NULL, pixmap, colormap, 0, 0, 0, 0, width, height);
#endif
	pixbuf = gdk_pixbuf_scale_simple(tmp_pixbuf, 1 * width, 1 * height, GDK_INTERP_TILES);

#if !GTK_CHECK_VERSION (3, 0, 0)
	g_object_unref(pixmap);
#endif
	g_object_unref(tmp_pixbuf);

	g_object_set_data_full(G_OBJECT(darea), "sample-pixbuf", pixbuf, (GDestroyNotify) g_object_unref);

#if GTK_CHECK_VERSION (3, 0, 0)
	gtk_widget_set_size_request  (GTK_WIDGET(darea), width + 2, height + 2);
	g_signal_connect(darea, "draw", G_CALLBACK(sample_draw), NULL);
#else
	g_signal_connect(darea, "size_request", G_CALLBACK(sample_size_request), NULL);
	g_signal_connect(darea, "expose_event", G_CALLBACK(sample_expose), NULL);
#endif
}
Ejemplo n.º 10
0
/**
* Init and load font
**/
OpenGLFont::OpenGLFont(RenderOpenGL* render, string name, Mod* mod, float size)
{
	int error;

	// Basics
	this->pmpl = new OpenGLFont_Implementation();
	this->render = render;
	this->size = size;

	// Init freetype
	// TODO: Should we share the tf ptr between OpenGLFont instances
	error = FT_Init_FreeType(&this->pmpl->ft);
	if (error) {
		reportFatalError("Freetype: Unable to init library.");
	}

	// On Linux, the system font is found using fontconfig
	#if defined(__linux__)
		FcConfig* config = FcInitLoadConfigAndFonts();

		FcPattern* pat = FcPatternBuild(
			NULL,
			FC_FAMILY, FcTypeString, reinterpret_cast<const char*>(name.c_str()),
			NULL
		);
		FcConfigSubstitute(config, pat, FcMatchPattern);
		FcDefaultSubstitute(pat);

		FcResult result;
		FcPattern* font = FcFontMatch(config, pat, &result);
		if (font == NULL) {
			reportFatalError("Fontconfig: Unable to find font " + name);
		}

		FcChar8* filename = NULL;
		if (FcPatternGetString(font, FC_FILE, 0, &filename) != FcResultMatch) {
			reportFatalError("Fontconfig: No filename in fontconfig match");
		}

		error = FT_New_Face(this->pmpl->ft, reinterpret_cast<const char*>(filename), 0, &this->pmpl->face);

		FcPatternDestroy(font);
		FcPatternDestroy(pat);

	#else
		// All other systems use a file in the cr/ mod
		Sint64 len;
		name.append(".ttf");
		this->pmpl->buf = mod->loadBinary(name, &len);
		if (this->pmpl->buf == NULL) {
			reportFatalError("Freetype: Unable to load data");
		}

		error = FT_New_Memory_Face(this->pmpl->ft, (const FT_Byte *) this->pmpl->buf, (FT_Long)len, 0, &this->pmpl->face);
	#endif

	// Handle errors
	if (error == FT_Err_Unknown_File_Format) {
		reportFatalError("Freetype: Unsupported font format");
	} else if (error) {
		reportFatalError("Freetype: Unable to load font");
	}

	// Set character size
	error = FT_Set_Char_Size(this->pmpl->face, 0, size * 64, 72, 72);
	if (error) {
		reportFatalError("Freetype: Unable to load font size");
	}
}
Ejemplo n.º 11
0
void ScreenPainter::drawGlyph(const GlyphLayout gl)
{
	bool showControls = (m_item->doc()->guidesPrefs().showControls) &&
			    (gl.glyph == font().char2CMap(QChar(' ')) || gl.glyph >= ScFace::CONTROL_GLYPHS);
#if CAIRO_HAS_FC_FONT
	if (m_painter->fillMode() == 1 && m_painter->maskMode() <= 0 && !showControls)
	{
		m_painter->save();

		setupState(false);

		cairo_t* cr = m_painter->context();
		double r, g, b;
		m_painter->brush().getRgbF(&r, &g, &b);
		cairo_set_source_rgba(cr, r, g, b, m_painter->brushOpacity());
		m_painter->setRasterOp(m_painter->blendModeFill());

		if (m_fontPath != font().fontFilePath() || m_faceIndex != font().faceIndex() || m_cairoFace == NULL)
		{
			m_fontPath = font().fontFilePath();
			m_faceIndex = font().faceIndex();
			// A very ugly hack as we can’t use the font().ftFace() because
			// Scribus liberally calls FT_Set_CharSize() with all sorts of
			// crazy values, breaking any subsequent call to the layout
			// painter.  FIXME: drop the FontConfig dependency here once
			// Scribus font handling code is made sane!
			FcPattern *pattern = FcPatternBuild(NULL,
							    FC_FILE, FcTypeString, QFile::encodeName(font().fontFilePath()).data(),
							    FC_INDEX, FcTypeInteger, font().faceIndex(),
							    NULL);
			m_cairoFace = cairo_ft_font_face_create_for_pattern(pattern);
			FcPatternDestroy(pattern);
		}

		cairo_set_font_face(cr, m_cairoFace);
		cairo_set_font_size(cr, fontSize());

		cairo_scale(cr, gl.scaleH, gl.scaleV);
		cairo_glyph_t glyph = { gl.glyph, 0, 0 };
		cairo_show_glyphs(cr, &glyph, 1);

		m_painter->restore();
		return;
	}
#endif
	m_painter->save();

	setupState(false);

	bool fr = m_painter->fillRule();
	m_painter->setFillRule(false);

	uint gid = gl.glyph;
	if (showControls)
	{
		bool stroke = false;
		if (gid >= ScFace::CONTROL_GLYPHS)
			gid -= ScFace::CONTROL_GLYPHS;
		else
			gid = 32;
		QTransform chma, chma4;
		FPointArray outline;
		if (gid == SpecialChars::TAB.unicode())
		{
			outline = m_item->doc()->symTab.copy();
			chma4.translate(gl.xadvance - fontSize() * gl.scaleH * 0.7, -fontSize() * gl.scaleV * 0.5);
		}
		else if (gid == SpecialChars::COLBREAK.unicode())
		{
			outline = m_item->doc()->symNewCol.copy();
			chma4.translate(0, -fontSize() * gl.scaleV * 0.6);
		}
		else if (gid == SpecialChars::FRAMEBREAK.unicode())
		{
			outline = m_item->doc()->symNewFrame.copy();
			chma4.translate(0, -fontSize() * gl.scaleV * 0.6);
		}
		else if (gid == SpecialChars::PARSEP.unicode())
		{
			outline = m_item->doc()->symReturn.copy();
			chma4.translate(0, -fontSize() * gl.scaleV * 0.8);
		}
		else if (gid == SpecialChars::LINEBREAK.unicode())
		{
			outline = m_item->doc()->symNewLine.copy();
			chma4.translate(0, -fontSize() * gl.scaleV * 0.4);
		}
		else if (gid == SpecialChars::NBSPACE.unicode() || gid == 32)
		{
			stroke = (gid == 32);
			outline = m_item->doc()->symNonBreak.copy();
			chma4.translate(0, -fontSize() * gl.scaleV * 0.4);
		}
		else if (gid == SpecialChars::NBHYPHEN.unicode())
		{
			outline = font().glyphOutline(font().char2CMap(QChar('-')), fontSize());
			chma4.translate(0, -fontSize() * gl.scaleV);
		}
		else if (gid == SpecialChars::SHYPHEN.unicode())
		{
			outline.resize(0);
			outline.addQuadPoint(0, -10, 0, -10, 0, -6, 0, -6);
			stroke = true;
		}
		else if (gid == SpecialChars::OBJECT.unicode())
		{
			//for showing marks entries as control chars
			outline.resize(0);
			outline.addQuadPoint(0, -8, 1, -8, 0, -6, 1, -6);
			stroke = true;
		}
		else // ???
		{
			outline.resize(0);
			outline.addQuadPoint(0, -10, 0, -10, 0, -9, 0, -9);
			outline.addQuadPoint(0, -9, 0, -9, 1, -9, 1, -9);
			outline.addQuadPoint(1, -9, 1, -9, 1, -10, 1, -10);
			outline.addQuadPoint(1, -10, 1, -10, 0, -10, 0, -10);
		}
		chma.scale(gl.scaleH * fontSize() / 10.0, gl.scaleV * fontSize() / 10.0);
		outline.map(chma * chma4);
		m_painter->setupPolygon(&outline, true);
		QColor oldBrush = m_painter->brush();
		// FIXME
		/* p->setBrush( (flags & ScLayout_SuppressSpace) ? Qt::green
				: PrefsManager::instance()->appPrefs.displayPrefs.controlCharColor);*/
		m_painter->setBrush(PrefsManager::instance()->appPrefs.displayPrefs.controlCharColor);
		if (stroke)
		{
			QColor tmp = m_painter->pen();
			m_painter->setStrokeMode(1);
			m_painter->setPen(m_painter->brush(), 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
			m_painter->setLineWidth(fontSize() * gl.scaleV / 20.0);
			m_painter->strokePath();
			m_painter->setPen(tmp, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
		}
		else
		{
			m_painter->setFillMode(1);
			m_painter->fillPath();
		}
		m_painter->setBrush(oldBrush);
	}
	else
	{
		m_painter->translate(0, -(fontSize() * gl.scaleV));
		double scaleH = gl.scaleH * fontSize() / 10.0;
		double scaleV = gl.scaleV * fontSize() / 10.0;
		m_painter->scale(scaleH, scaleV);
		FPointArray outline = font().glyphOutline(gid);
		m_painter->setupPolygon(&outline, true);
		if (outline.size() > 3)
			m_painter->fillPath();
	}
	m_painter->setFillRule(fr);

	m_painter->restore();
}
Ejemplo n.º 12
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;
}
int PsychRebuildFont(void)
{
	// Destroy old font object, if any:
	if (faceT || faceM) {
		// Delete OGLFT face object:
		if (faceT) delete(faceT);
		faceT = NULL;
		
		if (faceM) delete(faceM);
		faceM = NULL;

		if (_verbosity > 3) fprintf(stderr, "libptbdrawtext_ftgl: Destroying old font face...\n");
		
		// Delete underlying FreeType representation:
		FT_Done_Face(ft_face);
		ft_face = NULL;
	}

	if (_useOwnFontmapper) {
		FcResult result;
		FcPattern* target = NULL;
		
		if (_fontName[0] == '-') {
			// _fontName starts with a '-' dash: This is not a simple font family string but a special
			// fontspec string in FontConfig's special format. It contains many possible required font
			// properties encoded in the string. Parse it into a font matching pattern:
			target = FcNameParse((FcChar8*) &(_fontName[1]));
			
			// Need to manually add the current _fontSize, otherwise inconsistent stuff may happen:
			FcPatternAddDouble(target, FC_PIXEL_SIZE, _fontSize);
		}
		else {
			// _fontName contains only font family name: Build matching pattern based on _fontSize and
			// the flags provided in _fontStyle, according to the conventions in Psychtoolbox Screen('TextStyle'):
			target = FcPatternBuild (0, FC_FAMILY, FcTypeString, _fontName, FC_PIXEL_SIZE, FcTypeDouble, _fontSize,
									 FC_WEIGHT, FcTypeInteger, ((_fontStyle & 1) ? FC_WEIGHT_BOLD : FC_WEIGHT_NORMAL),
									 FC_SLANT, FcTypeInteger, ((_fontStyle & 2) ?  FC_SLANT_ITALIC : FC_SLANT_ROMAN),
									 FC_OUTLINE, FcTypeBool, ((_fontStyle & 8) ? true : false),
									 FC_WIDTH, FcTypeInteger, ( (_fontStyle & 32) ?  FC_WIDTH_CONDENSED : ((_fontStyle & 64) ?  FC_WIDTH_EXPANDED : FC_WIDTH_NORMAL) ),
									 FC_DPI, FcTypeDouble, (double) 72.0,
									 FC_SCALABLE, FcTypeBool, true,
									 FC_ANTIALIAS, FcTypeBool, ((_antiAliasing != 0) ? true : false), 
									 NULL);
		}

		FcDefaultSubstitute(target);
		
		// Have a matching pattern:
		if (_verbosity > 3) {
			fprintf(stderr, "libptbdrawtext_ftgl: Trying to find font that closely matches following specification:\n");
			FcPatternPrint(target);
		}

		// Perform font matching for the font in the default configuration (0) that best matches the
		// specified target pattern:
		FcPattern* matched = FcFontMatch(0, target, &result);
		if (result == FcResultNoMatch) {
			// Failed!
			if (_verbosity > 1) fprintf(stderr, "libptbdrawtext_ftgl: FontConfig failed to find a matching font for family %s, size %f pts and style flags %i.\n", _fontName, (float) _fontSize, _fontStyle);
			FcPatternDestroy(target);
			return(1);
		}

		// Success: Extract relevant information for Freetype-2, the font filename and faceIndex:
		if (_verbosity > 3) {
			fprintf(stderr, "libptbdrawtext_ftgl: Best matching font which will be selected for drawing has following specs:\n");
			FcPatternPrint(matched);
		}

		// Retrieve font filename for matched font:
		FcChar8* localfontFileName = NULL;
		if (FcPatternGetString(matched, FC_FILE, 0, (FcChar8**) &localfontFileName) != FcResultMatch) {
			// Failed!
			if (_verbosity > 1) fprintf(stderr, "libptbdrawtext_ftgl: FontConfig did not find filename for font with family %s, size %f pts and style flags %i.\n", _fontName, (float) _fontSize, _fontStyle);
			FcPatternDestroy(target);
			FcPatternDestroy(matched);
			return(1);
		}

		strcpy(_fontFileName, (char*) localfontFileName);

		// Retrieve faceIndex within fontfile:
		if (FcPatternGetInteger(matched, FC_INDEX, 0, &_faceIndex) != FcResultMatch)  {
			// Failed!
			if (_verbosity > 1) fprintf(stderr, "libptbdrawtext_ftgl: FontConfig did not find faceIndex for font file %s, family %s, size %f pts and style flags %i.\n", _fontFileName, _fontName, (float) _fontSize, _fontStyle);
			FcPatternDestroy(target);
			FcPatternDestroy(matched);
			return(1);
		}

		// Release target pattern and matched pattern objects:
		FcPatternDestroy(target);
		FcPatternDestroy(matched);
	}
	else {
		// Use "raw" values as passed by calling client code:
		strcpy(_fontFileName, _fontName);
		_faceIndex = (int) _fontStyle;
	}
	
	// Load & Create new font and face object, based on current spec settings:
	// We directly use the Freetype library, so we can spec the faceIndex for selection of textstyle, which wouldn't be
	// possible with the higher-level OGLFT constructor...
    FT_Error error = FT_New_Face( OGLFT::Library::instance(), _fontFileName, _faceIndex, &ft_face );
	if (error) {
		if (_verbosity > 1) fprintf(stderr, "libptbdrawtext_ftgl: Freetype did not load face with index %i from font file %s.\n", _faceIndex, _fontFileName);
		return(1);
	}
	else {
		if (_verbosity > 3) fprintf(stderr, "libptbdrawtext_ftgl: Freetype loaded face %p with index %i from font file %s.\n", ft_face, _faceIndex, _fontFileName);
	}

	// Create FTGL face from Freetype face with given size and a 72 DPI resolution, aka _fontSize == pixelsize:
	if (_antiAliasing != 0) {
		faceT = new OGLFT::TranslucentTexture(ft_face, _fontSize, 72);
		// Test the created face to make sure it will work correctly:
		if (!faceT->isValid()) {
			if (_verbosity > 1) fprintf(stderr, "libptbdrawtext_ftgl: Freetype did not recognize %s as a font file.\n", _fontName);
			return(1);
		}
	}
	else {
		faceM = new OGLFT::MonochromeTexture(ft_face, _fontSize, 72);
		// Test the created face to make sure it will work correctly:
		if (!faceM->isValid()) {
			if (_verbosity > 1) fprintf(stderr, "libptbdrawtext_ftgl: Freetype did not recognize %s as a font file.\n", _fontName);
			return(1);
		}
	}

	// Ready!
	_needsRebuild = false;
	
	return(0);
}
Ejemplo n.º 14
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.º 15
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;
}
Ejemplo n.º 16
0
bool sui_font_fromfamily(sui_font *font, sui_library *l, char **error, const char *family)
{
    return sui_font_fromfc(font, l, error,
                           FcPatternBuild(0, FC_FAMILY, FcTypeString, family, (char*)0));
}