xfttextrendererfactory.cpp

来自「khtml在gtk上的移植版本」· C++ 代码 · 共 250 行

CPP
250
字号
/* * Copyright (c) 2004 Nokia. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * Neither the name of Nokia nor the names of its contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */#include <assert.h>#include <gdk/gdk.h>#include <gdk/gdkx.h>#include <gtk/gtk.h> //pango stuff#include "XftTextRendererFactory.h"void XftTextRendererFactory::useAsSharedFactory(){    static XftTextRendererFactory singleton;    m_sharedFactory = &singleton;}XftNSFont::XftNSFont(XftTextRendererFactory* acreator, XftFont* afont, gpointer ahash)    :xftFont(afont)     ,hash(ahash)     ,creator(acreator){    assert(xftFont);    xdisplay = GDK_DISPLAY(); //FIXME: How to propagate this    ascent = xftFont->ascent;    descent = xftFont->descent;    lineSpacing = xftFont->height;    // measure x height    XftChar8 charx = 'x';    XGlyphInfo extents;        XftTextExtents8(xdisplay,		    xftFont,		    &charx,		    1,		    &extents);        xHeight = extents.height;    // measure space width. Needed because we don't draw '\n' -chars, just skip them    charx = ' ';    XftTextExtents8(xdisplay,		    xftFont,		    &charx,		    1,		    &extents);        spaceWidth = extents.xOff; // .width == width of the glyph, .xOff == where the next glyph starts    int spacing = 0;    if (FcPatternGetInteger(xftFont->pattern, FC_SPACING, 0, &spacing) == FcResultMatch) {	fixedPitch = (spacing == FC_MONO);    } else {	fixedPitch = false;    }}XftNSFont::~XftNSFont(){    if (xftFont)	XftFontClose(xdisplay, xftFont);         if (creator) creator->fontDeleted(this);}gpointer XftNSFont::createHash(const gchar * const * families, NSFontTraitMask traits, float size){    int hash = 0;    for (int i = 0;families[i]; i++)	hash ^=  g_direct_hash(families[i]);	    hash ^= (((int)traits) << 16);    hash ^= ((int)size*100);    return (gpointer) hash;}/** * Loads Xft font * from fontconfig(3) * Fontconfig  performs matching by measuring the distance from a provided * pattern to all of the available  fonts  in  the  system.   The  closest * matching  font  is  selected.   This ensures that a font will always be * returned, but doesn't ensure that it is  anything  like  the  requested * pattern. * * cannot fail (sure..) * @return font (must be freed) */static XftFont* try_load_font(const char* const * family, double size, int weight, int slant){    assert(family);    FcPattern *pattern,*matched;    FcResult result;    pattern = FcPatternBuild(0,			     FC_WEIGHT, FcTypeInteger, weight,			     FC_SLANT,  FcTypeInteger, slant,			     FC_PIXEL_SIZE, FcTypeDouble, size,			     FC_DPI, FcTypeDouble, 96.0,			     FC_SCALE, FcTypeDouble, 1.0,			     NULL);    while (*family) {	FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast<const FcChar8*>(*family));	family++;    }    matched = XftFontMatch(GDK_DISPLAY(),0,pattern, &result);    if (!matched) {	FcPatternDestroy(pattern);	//g_warning("%s Font Matching Failed.", __PRETTY_FUNCTION__);	return 0;    }        XftFont *f = XftFontOpenPattern(GDK_DISPLAY(), matched);    // FontConfig should destroy the pattern    return f;}extern "C" {staticvoid nsfonts_key_destroy(gpointer data){}void nsfonts_value_destroy(gpointer data){}void nsfonts_value_detach(gpointer key, gpointer value, gpointer user_data){    XftNSFont *f = static_cast<XftNSFont*>(value);    assert(f);    f->detach();}}XftTextRendererFactory::XftTextRendererFactory(){    nsfonts = g_hash_table_new_full(g_direct_hash, 				    g_direct_equal, 				    nsfonts_key_destroy, 				    nsfonts_value_destroy);}XftTextRendererFactory::~XftTextRendererFactory(){    g_hash_table_foreach(nsfonts, nsfonts_value_detach, this);    g_hash_table_destroy(nsfonts);}// Assume families[0..] are atomic string ptrs// assumes hashing is perfect and no clashes occur. FIXME!!!!NSFont* XftTextRendererFactory::fontWithFamilies(const gchar * const * families, NSFontTraitMask traits, float size){    assert(families);    gpointer hash = XftNSFont::createHash(families, traits, size);    XftNSFont* font = static_cast<XftNSFont*>(g_hash_table_lookup(nsfonts, hash));    if (!font) {	// font cache miss	int w,s;        	w = FC_WEIGHT_MEDIUM;	s = FC_SLANT_ROMAN;		if (traits & NSBoldFontMask)	    w = FC_WEIGHT_BOLD;		if (traits & NSItalicFontMask) 	    s = FC_SLANT_ITALIC;		XftFont* xftfont = try_load_font(families, size, w, s);	assert(xftfont);	font = new XftNSFont(this, xftfont, hash);        //FIXME: store families too, in case of hashing clashes	g_hash_table_insert(nsfonts, hash, font);    }    return font;}XftTextRenderer* XftTextRendererFactory::rendererWithFont(NSFont *nsfont, bool isPrinterFont){    assert(nsfont);    XftNSFont* font = static_cast<XftNSFont*>(nsfont);     return new XftTextRenderer(this, font);}void XftTextRendererFactory::rendererDeleted(XftTextRenderer* renderer){}void XftTextRendererFactory::fontDeleted(XftNSFont* font){    bool ret =  g_hash_table_remove(nsfonts, font->hash);    assert(ret);}bool XftTextRendererFactory::isFontFixedPitch(NSFont* nsfont){    XftNSFont* font = static_cast<XftNSFont*>(nsfont);         return font->fixedPitch;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?