📄 pango-context.c
字号:
state->free_attr_iter = TRUE; } else { state->attr_iter = NULL; state->free_attr_iter = FALSE; } if (state->attr_iter) { state->font_desc = NULL; state->lang = NULL; advance_attr_iterator_to (state->attr_iter, start_index); update_attr_iterator (state); } else { state->font_desc = pango_font_description_copy_static (desc ? desc : state->context->font_desc); state->lang = state->context->language; state->extra_attrs = NULL; state->copy_extra_attrs = FALSE; state->attr_end = state->end; state->enable_fallback = TRUE; } /* Initialize the script iterator */ state->script_iter = pango_script_iter_new (text + start_index, length); pango_script_iter_get_range (state->script_iter, NULL, &state->script_end, &state->script); update_end (state); if (pango_font_description_get_set_fields (state->font_desc) & PANGO_FONT_MASK_GRAVITY) state->font_desc_gravity = pango_font_description_get_gravity (state->font_desc); else state->font_desc_gravity = PANGO_GRAVITY_AUTO; state->gravity = PANGO_GRAVITY_AUTO; state->centered_baseline = PANGO_GRAVITY_IS_VERTICAL (state->context->resolved_gravity); state->gravity_hint = state->context->gravity_hint; state->resolved_gravity = PANGO_GRAVITY_AUTO; state->derived_lang = NULL; state->lang_engine = NULL; state->current_fonts = NULL; state->cache = NULL; state->exact_engines = NULL; state->fallback_engines = NULL; state->base_font = NULL; state->changed = EMBEDDING_CHANGED | SCRIPT_CHANGED | LANG_CHANGED | FONT_CHANGED;}static gbooleanitemize_state_next (ItemizeState *state){ if (state->run_end == state->end) return FALSE; state->changed = 0; state->run_start = state->run_end; if (state->run_end == state->embedding_end) { update_embedding_end (state); } if (state->run_end == state->attr_end) { pango_attr_iterator_next (state->attr_iter); update_attr_iterator (state); } if (state->run_end == state->script_end) { pango_script_iter_next (state->script_iter); pango_script_iter_get_range (state->script_iter, NULL, &state->script_end, &state->script); state->changed |= SCRIPT_CHANGED; } update_end (state); return TRUE;}static GSList *copy_attr_slist (GSList *attr_slist){ GSList *new_list = NULL; GSList *l; for (l = attr_slist; l; l = l->next) new_list = g_slist_prepend (new_list, pango_attribute_copy (l->data)); return g_slist_reverse (new_list);}static voiditemize_state_fill_shaper (ItemizeState *state, PangoEngineShape *shape_engine, PangoFont *font){ GList *l; for (l = state->result; l; l = l->next) { PangoItem *item = l->data; if (item->analysis.shape_engine) break; if (font) item->analysis.font = g_object_ref (font); else item->analysis.font = NULL; item->analysis.shape_engine = shape_engine; }}static voiditemize_state_add_character (ItemizeState *state, PangoEngineShape *shape_engine, PangoFont *font, gboolean force_break, const char *pos){ if (state->item) { if (!state->item->analysis.shape_engine && shape_engine) { itemize_state_fill_shaper (state, shape_engine, font); } else if (state->item->analysis.shape_engine && !shape_engine) { font = state->item->analysis.font; shape_engine = state->item->analysis.shape_engine; } if (!force_break && state->item->analysis.lang_engine == state->lang_engine && state->item->analysis.shape_engine == shape_engine && state->item->analysis.font == font) { state->item->num_chars++; return; } state->item->length = (pos - state->text) - state->item->offset; } state->item = pango_item_new (); state->item->offset = pos - state->text; state->item->length = 0; state->item->num_chars = 1; state->item->analysis.shape_engine = shape_engine; state->item->analysis.lang_engine = state->lang_engine; if (font) g_object_ref (font); state->item->analysis.font = font; state->item->analysis.level = state->embedding; state->item->analysis.gravity = state->resolved_gravity; /* The level vs. gravity dance: * - If gravity is SOUTH, leave level untouched. * - If gravity is NORTH, step level one up, to * not get mirrored upside-down text. * - If gravity is EAST, step up to an even level, as * it's a clockwise-rotated layout, so the rotated * top is unrotated left. * - If gravity is WEST, step up to an odd level, as * it's a counter-clockwise-rotated layout, so the rotated * top is unrotated right. * * A similar dance is performed in pango-layout.c: * line_set_resolved_dir(). Keep in synch. */ switch (state->item->analysis.gravity) { case PANGO_GRAVITY_SOUTH: default: break; case PANGO_GRAVITY_NORTH: state->item->analysis.level++; break; case PANGO_GRAVITY_EAST: state->item->analysis.level += 1; state->item->analysis.level &= ~1; break; case PANGO_GRAVITY_WEST: state->item->analysis.level |= 1; break; } state->item->analysis.flags = state->centered_baseline ? PANGO_ANALYSIS_FLAG_CENTERED_BASELINE : 0; state->item->analysis.script = state->script; state->item->analysis.language = state->derived_lang; if (state->copy_extra_attrs) { state->item->analysis.extra_attrs = copy_attr_slist (state->extra_attrs); } else { state->item->analysis.extra_attrs = state->extra_attrs; state->copy_extra_attrs = TRUE; } state->result = g_list_prepend (state->result, state->item);}static voidget_engines (PangoContext *context, PangoLanguage *lang, PangoScript script, GSList **exact_engines, GSList **fallback_engines){ const char *engine_type = pango_font_map_get_shape_engine_type (context->font_map); PangoMap *shaper_map = pango_find_map (lang, g_quark_from_string (PANGO_ENGINE_TYPE_SHAPE), g_quark_from_string (engine_type)); pango_map_get_engines (shaper_map, script, exact_engines, fallback_engines);}typedef struct { PangoLanguage *lang; gunichar wc; GSList *engines; PangoEngineShape *shape_engine; PangoFont *font;} GetShaperFontInfo;static gbooleanget_shaper_and_font_foreach (PangoFontset *fontset, PangoFont *font, gpointer data){ GetShaperFontInfo *info = data; GSList *l; for (l = info->engines; l; l = l->next) { PangoEngineShape *engine = l->data; PangoCoverageLevel level; level = _pango_engine_shape_covers (engine, font, info->lang, info->wc); if (level != PANGO_COVERAGE_NONE) { info->shape_engine = engine; info->font = g_object_ref (font); return TRUE; } } return FALSE;}static PangoFont *get_base_font (ItemizeState *state){ if (!state->base_font) state->base_font = pango_font_map_load_font (state->context->font_map, state->context, state->font_desc); return state->base_font;}static gbooleanget_shaper_and_font (ItemizeState *state, gunichar wc, PangoEngineShape **shape_engine, PangoFont **font){ GetShaperFontInfo info; /* We'd need a separate cache when fallback is disabled, but since lookup * with fallback disabled is faster anyways, we just skip caching */ if (state->enable_fallback && shaper_font_cache_get (state->cache, wc, shape_engine, font)) return *shape_engine != NULL; if (!state->exact_engines && !state->fallback_engines) { /* Always use a basic shaper for vertical layout (ie, east/west gravity) * as we do not support vertical shaping as of now. */ PangoScript script; if (PANGO_GRAVITY_IS_VERTICAL (state->resolved_gravity)) script = PANGO_SCRIPT_COMMON; else script = state->script; get_engines (state->context, state->derived_lang, script, &state->exact_engines, &state->fallback_engines); } info.lang = state->derived_lang; info.wc = wc; info.shape_engine = NULL; info.font = NULL; info.engines = state->exact_engines; if (state->enable_fallback) pango_fontset_foreach (state->current_fonts, get_shaper_and_font_foreach, &info); else get_shaper_and_font_foreach (NULL, get_base_font (state), &info); if (info.shape_engine) { *shape_engine = info.shape_engine; *font = info.font; /* skip caching if fallback disabled (see above) */ if (state->enable_fallback) shaper_font_cache_insert (state->cache, wc, *shape_engine, *font); return TRUE; } info.engines = state->fallback_engines; if (state->enable_fallback) pango_fontset_foreach (state->current_fonts, get_shaper_and_font_foreach, &info); else get_shaper_and_font_foreach (NULL, get_base_font (state), &info); *shape_engine = info.shape_engine; *font = info.font; /* skip caching if fallback disabled (see above) */ if (state->enable_fallback) shaper_font_cache_insert (state->cache, wc, *shape_engine, *font); return *shape_engine != NULL;}static voiditemize_state_reset_shape_engines (ItemizeState *state){ g_slist_free (state->exact_engines); state->exact_engines = NULL; g_slist_free (state->fallback_engines); state->fallback_engines = NULL;}static PangoLanguage *compute_derived_language (PangoLanguage *lang, PangoScript script){ PangoLanguage *derived_lang; /* Make sure the language tag is consistent with the derived * script. There is no point in marking up a section of * Arabic text with the "en" language tag. */ if (lang && pango_language_includes_script (lang, script)) derived_lang = lang; else { derived_lang = pango_script_get_sample_language (script); /* If we don't find a sample language for the script, we * use a language tag that shouldn't actually be used * anywhere. This keeps fontconfig (for the PangoFc* * backend) from using the language tag to affect the * sort order. I don't have a reference for 'xx' being * safe here, though Keith Packard claims it is. */ if (!derived_lang) derived_lang = pango_language_from_string ("xx"); } return derived_lang;}static PangoMap *get_lang_map (PangoLanguage *lang){ static guint engine_type_id = 0; static guint render_type_id = 0; if (engine_type_id == 0) { engine_type_id = g_quark_from_static_string (PANGO_ENGINE_TYPE_LANG); render_type_id = g_quark_from_static_string (PANGO_RENDER_TYPE_NONE); } return pango_find_map (lang, engine_type_id, render_type_id);}static voiditemize_state_update_for_new_run (ItemizeState *state){ /* This block should be moved to update_attr_iterator, but I'm too lazy to * do it right now */ if (state->changed & (FONT_CHANGED | SCRIPT_CHANGED)) { PangoGravity old_gravity = state->resolved_gravity; if (state->font_desc_gravity != PANGO_GRAVITY_AUTO) { state->resolved_gravity = state->font_desc_gravity; } else { PangoGravity gravity = state->gravity;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -