📄 pangocairo-fcfont.c
字号:
/* Pango * pangocairofc-font.c: Cairo font handling, fontconfig backend * * Copyright (C) 2000-2005 Red Hat Software * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */#include <config.h>#include <math.h>#include <stdlib.h>#include <cairo-ft.h>#include "pango-fontmap.h"#include "pangocairo-private.h"#include "pangocairo-fc.h"#include "pangofc-private.h"#include "pango-impl-utils.h"#define PANGO_TYPE_CAIRO_FC_FONT (pango_cairo_fc_font_get_type ())#define PANGO_CAIRO_FC_FONT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_CAIRO_FC_FONT, PangoCairoFcFont))#define PANGO_CAIRO_FC_FONT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_CAIRO_FC_FONT, PangoCairoFcFontClass))#define PANGO_CAIRO_IS_FONT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_CAIRO_FC_FONT))#define PANGO_CAIRO_FC_FONT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_CAIRO_FC_FONT, PangoCairoFcFontClass))typedef struct _PangoCairoFcFont PangoCairoFcFont;typedef struct _PangoCairoFcFontClass PangoCairoFcFontClass;typedef struct _GlyphExtentsCacheEntry GlyphExtentsCacheEntry;#define GLYPH_CACHE_NUM_ENTRIES 256 /* should be power of two */#define GLYPH_CACHE_MASK (GLYPH_CACHE_NUM_ENTRIES - 1)/* An entry in the fixed-size cache for the glyph -> ink_rect mapping. * The cache is indexed by the lower N bits of the glyph (see * GLYPH_CACHE_NUM_ENTRIES). For scripts with few glyphs, * this should provide pretty much instant lookups. */struct _GlyphExtentsCacheEntry{ PangoGlyph glyph; int width; PangoRectangle ink_rect;};struct _PangoCairoFcFont{ PangoFcFont font; cairo_font_face_t *font_face; cairo_scaled_font_t *scaled_font; cairo_matrix_t font_matrix; cairo_matrix_t ctm; cairo_font_options_t *options; PangoGravity gravity; PangoRectangle font_extents; GlyphExtentsCacheEntry *glyph_extents_cache;};struct _PangoCairoFcFontClass{ PangoFcFontClass parent_class;};GType pango_cairo_fc_font_get_type (void);static cairo_font_face_t *pango_cairo_fc_font_get_font_face (PangoCairoFont *font);/******************************* * Utility functions * *******************************/static cairo_font_face_t *pango_cairo_fc_font_get_font_face (PangoCairoFont *font){ PangoCairoFcFont *cffont = (PangoCairoFcFont *) (font); PangoFcFont *fcfont = (PangoFcFont *) (cffont); if (!cffont->font_face) { cffont->font_face = cairo_ft_font_face_create_for_pattern (fcfont->font_pattern); /* Unable to create FT2 cairo scaled font. * This means out of memory or a cairo/fontconfig/FreeType bug, */ if (!cffont->font_face) return NULL; } return cffont->font_face;}static cairo_scaled_font_t *pango_cairo_fc_font_get_scaled_font (PangoCairoFont *font){ PangoCairoFcFont *cffont = (PangoCairoFcFont *)font; if (!cffont->scaled_font) { cairo_font_face_t *font_face; font_face = pango_cairo_fc_font_get_font_face (font); if (!font_face) return NULL; cffont->scaled_font = cairo_scaled_font_create (font_face, &cffont->font_matrix, &cffont->ctm, cffont->options); /* Unable to create FT2 cairo scaled font. * This means out of memory or a cairo/fontconfig/FreeType bug, * or a missing font... */ if (!cffont->scaled_font) return NULL; } return cffont->scaled_font;}/******************************** * Method implementations * ********************************/static gbooleanpango_cairo_fc_font_install (PangoCairoFont *font, cairo_t *cr){ PangoCairoFcFont *cffont = (PangoCairoFcFont *) (font); cairo_set_font_face (cr, pango_cairo_fc_font_get_font_face (font)); cairo_set_font_matrix (cr, &cffont->font_matrix); cairo_set_font_options (cr, cffont->options); return TRUE;}static voidcairo_font_iface_init (PangoCairoFontIface *iface){ iface->install = pango_cairo_fc_font_install; iface->get_font_face = pango_cairo_fc_font_get_font_face; iface->get_scaled_font = pango_cairo_fc_font_get_scaled_font;}G_DEFINE_TYPE_WITH_CODE (PangoCairoFcFont, pango_cairo_fc_font, PANGO_TYPE_FC_FONT, { G_IMPLEMENT_INTERFACE (PANGO_TYPE_CAIRO_FONT, cairo_font_iface_init) })static voidpango_cairo_fc_font_finalize (GObject *object){ PangoCairoFcFont *cffont = (PangoCairoFcFont *) (object); if (cffont->font_face) cairo_font_face_destroy (cffont->font_face); if (cffont->scaled_font) cairo_scaled_font_destroy (cffont->scaled_font); if (cffont->options) cairo_font_options_destroy (cffont->options); if (cffont->glyph_extents_cache) { g_free (cffont->glyph_extents_cache); } G_OBJECT_CLASS (pango_cairo_fc_font_parent_class)->finalize (object);}/* This function is cut-and-pasted from pangocairo-fcfont.c - it might be * better to add a virtual fcfont->create_context (font). */static PangoFontMetrics *pango_cairo_fc_font_get_metrics (PangoFont *font, PangoLanguage *language){ PangoFcFont *fcfont = (PangoFcFont *) (font); PangoCairoFcFont *cffont = (PangoCairoFcFont *) (font); PangoFcMetricsInfo *info = NULL; /* Quiet gcc */ GSList *tmp_list; const char *sample_str = pango_language_get_sample_string (language); tmp_list = fcfont->metrics_by_lang; while (tmp_list) { info = tmp_list->data; if (info->sample_str == sample_str) /* We _don't_ need strcmp */ break; tmp_list = tmp_list->next; } if (!tmp_list) { PangoContext *context; int height, shift; if (!fcfont->fontmap) return pango_font_metrics_new (); info = g_slice_new0 (PangoFcMetricsInfo); fcfont->metrics_by_lang = g_slist_prepend (fcfont->metrics_by_lang, info); info->sample_str = sample_str; context = pango_fc_font_map_create_context (PANGO_FC_FONT_MAP (fcfont->fontmap)); pango_context_set_language (context, language); pango_cairo_context_set_font_options (context, cffont->options); info->metrics = pango_fc_font_create_metrics_for_context (fcfont, context); /* We may actually reuse ascent/descent we got from cairo here. that's * in cffont->font_extents. */ height = info->metrics->ascent + info->metrics->descent; switch (cffont->gravity) { default: case PANGO_GRAVITY_AUTO: case PANGO_GRAVITY_SOUTH: break; case PANGO_GRAVITY_NORTH: info->metrics->ascent = info->metrics->descent; break; case PANGO_GRAVITY_EAST: case PANGO_GRAVITY_WEST: info->metrics->ascent = height / 2; } shift = (height - info->metrics->ascent) - info->metrics->descent; if (fcfont->is_hinted) shift &= ~(PANGO_SCALE - 1); info->metrics->descent += shift; info->metrics->underline_position -= shift; info->metrics->strikethrough_position -= shift; info->metrics->ascent = height - info->metrics->descent; g_object_unref (context); } return pango_font_metrics_ref (info->metrics);}static FT_Facepango_cairo_fc_font_lock_face (PangoFcFont *font){ PangoCairoFont *cfont = (PangoCairoFont *)font; cairo_scaled_font_t *scaled_font = pango_cairo_fc_font_get_scaled_font (cfont); if (G_UNLIKELY (!scaled_font)) return NULL; return cairo_ft_scaled_font_lock_face (scaled_font);}static voidpango_cairo_fc_font_unlock_face (PangoFcFont *font){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -