2 * basic-fc.c: Basic shaper for FreeType-based backends
4 * Copyright (C) 2000, 2007 Red Hat Software
6 * Owen Taylor <otaylor@redhat.com>
7 * Behdad Esfahbod <behdad@behdad.org>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 * Boston, MA 02111-1307, USA.
28 #include <glib/gprintf.h>
29 #include "pango-engine.h"
30 #include "pango-utils.h"
31 #include "pangofc-font.h"
34 /* No extra fields needed */
35 typedef PangoEngineShape BasicEngineFc;
36 typedef PangoEngineShapeClass BasicEngineFcClass;
38 #define SCRIPT_ENGINE_NAME "BasicScriptEngineFc"
39 #define RENDER_TYPE PANGO_RENDER_TYPE_FC
41 static PangoEngineScriptInfo basic_scripts[] = {
42 /* Listed in OpenType "Standard scripts" standard */
43 { PANGO_SCRIPT_LATIN, "*" },
44 { PANGO_SCRIPT_CYRILLIC, "*" },
45 { PANGO_SCRIPT_GREEK, "*" },
46 { PANGO_SCRIPT_ARMENIAN, "*" },
47 { PANGO_SCRIPT_GEORGIAN, "*" },
48 { PANGO_SCRIPT_RUNIC, "*" },
49 { PANGO_SCRIPT_OGHAM, "*" },
51 /* The following are simple and can be shaped easily too */
53 { PANGO_SCRIPT_BOPOMOFO, "*" },
54 { PANGO_SCRIPT_CHEROKEE, "*" },
55 { PANGO_SCRIPT_COPTIC, "*" },
56 { PANGO_SCRIPT_DESERET, "*" },
57 { PANGO_SCRIPT_ETHIOPIC, "*" },
58 { PANGO_SCRIPT_GOTHIC, "*" },
59 { PANGO_SCRIPT_HAN, "*" },
60 { PANGO_SCRIPT_HIRAGANA, "*" },
61 { PANGO_SCRIPT_KATAKANA, "*" },
62 { PANGO_SCRIPT_OLD_ITALIC, "*" },
63 { PANGO_SCRIPT_CANADIAN_ABORIGINAL, "*" },
64 { PANGO_SCRIPT_YI, "*" },
66 /* Unicode-4.0 additions */
67 { PANGO_SCRIPT_BRAILLE, "*" },
68 { PANGO_SCRIPT_CYPRIOT, "*" },
69 { PANGO_SCRIPT_LIMBU, "*" },
70 { PANGO_SCRIPT_OSMANYA, "*" },
71 { PANGO_SCRIPT_SHAVIAN, "*" },
72 { PANGO_SCRIPT_LINEAR_B, "*" },
73 { PANGO_SCRIPT_UGARITIC, "*" },
75 /* Unicode-4.1 additions */
76 { PANGO_SCRIPT_GLAGOLITIC, "*" },
78 /* Unicode-5.0 additions */
79 { PANGO_SCRIPT_CUNEIFORM, "*" },
80 { PANGO_SCRIPT_PHOENICIAN, "*" },
82 /* In fact any script we don't know how to shape can go here */
83 { PANGO_SCRIPT_COMMON, "" }
86 static PangoEngineInfo script_engines[] = {
89 PANGO_ENGINE_TYPE_SHAPE,
91 basic_scripts, G_N_ELEMENTS(basic_scripts)
95 static const PangoOTFeatureMap gsub_features[] =
97 {"ccmp", PANGO_OT_ALL_GLYPHS},
98 {"locl", PANGO_OT_ALL_GLYPHS},
99 {"liga", PANGO_OT_ALL_GLYPHS},
100 {"clig", PANGO_OT_ALL_GLYPHS}
103 static const PangoOTFeatureMap gpos_features[] =
105 {"kern", PANGO_OT_ALL_GLYPHS},
106 {"mark", PANGO_OT_ALL_GLYPHS},
107 {"mkmk", PANGO_OT_ALL_GLYPHS}
110 static const PangoOTFeatureMap vertical_gsub_features[] =
112 {"ccmp", PANGO_OT_ALL_GLYPHS},
113 {"locl", PANGO_OT_ALL_GLYPHS},
114 {"vert", PANGO_OT_ALL_GLYPHS}
117 static const PangoOTFeatureMap vertical_gpos_features[] =
119 {"vkrn", PANGO_OT_ALL_GLYPHS}
123 basic_engine_shape (PangoEngineShape *engine G_GNUC_UNUSED,
127 const PangoAnalysis *analysis,
128 PangoGlyphString *glyphs)
130 PangoFcFont *fc_font;
132 PangoOTRulesetDescription desc;
133 const PangoOTRuleset *ruleset;
134 PangoOTBuffer *buffer;
140 g_return_if_fail (font != NULL);
141 g_return_if_fail (text != NULL);
142 g_return_if_fail (length >= 0);
143 g_return_if_fail (analysis != NULL);
145 fc_font = PANGO_FC_FONT (font);
146 face = pango_fc_font_lock_face (fc_font);
150 buffer = pango_ot_buffer_new (fc_font);
151 pango_ot_buffer_set_rtl (buffer, analysis->level % 2 != 0);
153 n_chars = g_utf8_strlen (text, length);
154 pango_glyph_string_set_size (glyphs, n_chars);
157 for (i=0; i < n_chars; i++)
162 wc = g_utf8_get_char (p);
164 if (g_unichar_type (wc) != G_UNICODE_NON_SPACING_MARK)
167 if (pango_is_zero_width (wc))
168 glyph = PANGO_GLYPH_EMPTY;
173 if (analysis->level % 2)
174 g_unichar_get_mirror_char (c, &c);
176 glyph = pango_fc_font_get_glyph (fc_font, c);
180 glyph = PANGO_GET_UNKNOWN_GLYPH (wc);
182 pango_ot_buffer_add_glyph (buffer, glyph, 0, cluster);
184 p = g_utf8_next_char (p);
187 desc.script = analysis->script;
188 desc.language = analysis->language;
190 if (PANGO_GRAVITY_IS_VERTICAL (analysis->gravity))
192 desc.n_static_gsub_features = G_N_ELEMENTS (vertical_gsub_features);
193 desc.static_gsub_features = vertical_gsub_features;
194 desc.n_static_gpos_features = G_N_ELEMENTS (vertical_gpos_features);
195 desc.static_gpos_features = vertical_gpos_features;
199 desc.n_static_gsub_features = G_N_ELEMENTS (gsub_features);
200 desc.static_gsub_features = gsub_features;
201 desc.n_static_gpos_features = G_N_ELEMENTS (gpos_features);
202 desc.static_gpos_features = gpos_features;
205 /* TODO populate other_features from analysis->extra_attrs */
206 desc.n_other_features = 0;
207 desc.other_features = NULL;
209 ruleset = pango_ot_ruleset_get_for_description (pango_ot_info_get (face), &desc);
211 pango_ot_ruleset_substitute (ruleset, buffer);
212 pango_ot_ruleset_position (ruleset, buffer);
213 pango_ot_buffer_output (buffer, glyphs);
215 pango_ot_buffer_destroy (buffer);
217 pango_fc_font_unlock_face (fc_font);
221 basic_engine_fc_class_init (PangoEngineShapeClass *class)
223 class->script_shape = basic_engine_shape;
226 PANGO_ENGINE_SHAPE_DEFINE_TYPE (BasicEngineFc, basic_engine_fc,
227 basic_engine_fc_class_init, NULL)
230 PANGO_MODULE_ENTRY(init) (GTypeModule *module)
232 basic_engine_fc_register_type (module);
236 PANGO_MODULE_ENTRY(exit) (void)
241 PANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines,
244 *engines = script_engines;
245 *n_engines = G_N_ELEMENTS (script_engines);
249 PANGO_MODULE_ENTRY(create) (const char *id)
251 if (!strcmp (id, SCRIPT_ENGINE_NAME))
252 return g_object_new (basic_engine_fc_type, NULL);