📄 pangocairo-fcfont.c
字号:
PangoCairoFont *cfont = (PangoCairoFont *)font; cairo_scaled_font_t *scaled_font = pango_cairo_fc_font_get_scaled_font (cfont); if (G_UNLIKELY (!scaled_font)) return; cairo_ft_scaled_font_unlock_face (scaled_font);}static voidpango_cairo_fc_font_glyph_extents_cache_init (PangoCairoFcFont *cffont){ PangoCairoFont *cfont = (PangoCairoFont *)cffont; cairo_scaled_font_t *scaled_font = pango_cairo_fc_font_get_scaled_font (cfont); cairo_font_extents_t font_extents; cairo_scaled_font_extents (scaled_font, &font_extents); cffont->font_extents.x = 0; cffont->font_extents.width = 0; cffont->font_extents.height = pango_units_from_double (font_extents.ascent + font_extents.descent); switch (cffont->gravity) { default: case PANGO_GRAVITY_AUTO: case PANGO_GRAVITY_SOUTH: cffont->font_extents.y = - pango_units_from_double (font_extents.ascent); break; case PANGO_GRAVITY_NORTH: cffont->font_extents.y = - pango_units_from_double (font_extents.descent); break; case PANGO_GRAVITY_EAST: case PANGO_GRAVITY_WEST: cffont->font_extents.y = - pango_units_from_double ((font_extents.ascent + font_extents.descent) * 0.5); } cffont->glyph_extents_cache = g_new0 (GlyphExtentsCacheEntry, GLYPH_CACHE_NUM_ENTRIES); /* Make sure all cache entries are invalid initially */ cffont->glyph_extents_cache[0].glyph = 1; /* glyph 1 cannot happen in bucket 0 */}/* Fills in the glyph extents cache entry */static voidcompute_glyph_extents (PangoCairoFcFont *cffont, PangoGlyph glyph, GlyphExtentsCacheEntry *entry){ cairo_text_extents_t extents; cairo_glyph_t cairo_glyph; cairo_glyph.index = glyph; cairo_glyph.x = 0; cairo_glyph.y = 0; cairo_scaled_font_glyph_extents (cffont->scaled_font, &cairo_glyph, 1, &extents); entry->glyph = glyph; entry->width = pango_units_from_double (extents.x_advance); entry->ink_rect.x = pango_units_from_double (extents.x_bearing); entry->ink_rect.y = pango_units_from_double (extents.y_bearing); entry->ink_rect.width = pango_units_from_double (extents.width); entry->ink_rect.height = pango_units_from_double (extents.height);}static GlyphExtentsCacheEntry *pango_cairo_fc_font_get_glyph_extents_cache_entry (PangoCairoFcFont *cffont, PangoGlyph glyph){ GlyphExtentsCacheEntry *entry; guint idx; idx = glyph & GLYPH_CACHE_MASK; entry = cffont->glyph_extents_cache + idx; if (entry->glyph != glyph) { compute_glyph_extents (cffont, glyph, entry); } return entry;}static voidpango_cairo_fc_font_get_glyph_extents (PangoFont *font, PangoGlyph glyph, PangoRectangle *ink_rect, PangoRectangle *logical_rect){ PangoCairoFcFont *cffont = (PangoCairoFcFont *)font; GlyphExtentsCacheEntry *entry; if (!pango_cairo_fc_font_get_scaled_font ((PangoCairoFont *)cffont)) { /* Get generic unknown-glyph extents. */ pango_font_get_glyph_extents (NULL, glyph, ink_rect, logical_rect); return; } /* We need to initialize the cache here, since we use cffont->font_extents */ if (cffont->glyph_extents_cache == NULL) pango_cairo_fc_font_glyph_extents_cache_init (cffont); if (glyph == PANGO_GLYPH_EMPTY) { if (ink_rect) ink_rect->x = ink_rect->y = ink_rect->width = ink_rect->height = 0; if (logical_rect) *logical_rect = cffont->font_extents; return; } else if (glyph & PANGO_GLYPH_UNKNOWN_FLAG) { _pango_cairo_get_glyph_extents_missing((PangoCairoFont *)font, glyph, ink_rect, logical_rect); return; } entry = pango_cairo_fc_font_get_glyph_extents_cache_entry (cffont, glyph); if (ink_rect) *ink_rect = entry->ink_rect; if (logical_rect) { *logical_rect = cffont->font_extents; logical_rect->width = entry->width; }}static voidpango_cairo_fc_font_shutdown (PangoFcFont *fcfont){ PangoCairoFcFont *cffont = (PangoCairoFcFont *) (fcfont); if (cffont->scaled_font) { cairo_scaled_font_destroy (cffont->scaled_font); cffont->scaled_font = NULL; } if (cffont->font_face) { cairo_font_face_destroy (cffont->font_face); cffont->font_face = NULL; }}static voidpango_cairo_fc_font_class_init (PangoCairoFcFontClass *class){ GObjectClass *object_class = G_OBJECT_CLASS (class); PangoFontClass *font_class = PANGO_FONT_CLASS (class); PangoFcFontClass *fc_font_class = PANGO_FC_FONT_CLASS (class); object_class->finalize = pango_cairo_fc_font_finalize; font_class->get_glyph_extents = pango_cairo_fc_font_get_glyph_extents; font_class->get_metrics = pango_cairo_fc_font_get_metrics; fc_font_class->lock_face = pango_cairo_fc_font_lock_face; fc_font_class->unlock_face = pango_cairo_fc_font_unlock_face; fc_font_class->shutdown = pango_cairo_fc_font_shutdown;}static voidpango_cairo_fc_font_init (PangoCairoFcFont *cffont){}/******************** * Private API * ********************/static doubleget_font_size (PangoCairoFcFontMap *cffontmap, PangoContext *context, const PangoFontDescription *desc, FcPattern *pattern, const PangoMatrix *matrix){ double size; /* The reason why we read FC_PIXEL_SIZE here rather than just * using the specified size is to support operations like clamping * a font to a minimal readable size in fonts.conf. This is pretty weird, * since it could mean that changing the Cairo CTM doesn't change the * font size, but it's just a more radical version of the non-linear * font scaling we already have due to hinting and due to bitmap * fonts being only available at a few sizes. * * If honoring FC_PIXEL_SIZE gets in the way of more useful features * it should be removed since it only matters in the unusual case * of people doing exotic stuff in fonts.conf. */ if (FcPatternGetDouble (pattern, FC_PIXEL_SIZE, 0, &size) == FcResultMatch) return size * PANGO_SCALE / pango_matrix_get_font_scale_factor (matrix); /* Just in case FC_PIXEL_SIZE got unset between pango_fc_make_pattern() * and here. */ if (pango_font_description_get_size_is_absolute (desc)) return pango_font_description_get_size (desc); else { double dpi = pango_cairo_context_get_resolution (context); if (dpi <= 0) dpi = cffontmap->dpi; return dpi * pango_font_description_get_size (desc) / 72.; }}PangoFcFont *_pango_cairo_fc_font_new (PangoCairoFcFontMap *cffontmap, PangoContext *context, const PangoFontDescription *desc, FcPattern *pattern){ PangoCairoFcFont *cffont; const PangoMatrix *pango_ctm; FcMatrix *fc_matrix; double size; g_return_val_if_fail (PANGO_IS_CAIRO_FC_FONT_MAP (cffontmap), NULL); g_return_val_if_fail (pattern != NULL, NULL); cffont = g_object_new (PANGO_TYPE_CAIRO_FC_FONT, "pattern", pattern, NULL); cffont->gravity = pango_font_description_get_gravity (desc); if (FcPatternGetMatrix (pattern, FC_MATRIX, 0, &fc_matrix) == FcResultMatch) { cairo_matrix_init (&cffont->font_matrix, fc_matrix->xx, - fc_matrix->yx, - fc_matrix->xy, fc_matrix->yy, 0., 0.); } else cairo_matrix_init_identity (&cffont->font_matrix); cairo_matrix_rotate(&cffont->font_matrix, pango_gravity_to_rotation (cffont->gravity)); pango_ctm = pango_context_get_matrix (context); size = get_font_size (cffontmap, context, desc, pattern, pango_ctm); cairo_matrix_scale (&cffont->font_matrix, size / PANGO_SCALE, size / PANGO_SCALE); if (pango_ctm) cairo_matrix_init (&cffont->ctm, pango_ctm->xx, pango_ctm->yx, pango_ctm->xy, pango_ctm->yy, 0., 0.); else cairo_matrix_init_identity (&cffont->ctm); cffont->options = cairo_font_options_copy (_pango_cairo_context_get_merged_font_options (context)); /* fcfont's is_hinted controls metric hinting */ ((PangoFcFont *)(cffont))->is_hinted = (cairo_font_options_get_hint_metrics(cffont->options) != CAIRO_HINT_METRICS_OFF); return (PangoFcFont *) (cffont);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -