4 * Copyright (C) 2005 Imendio AB
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
25 #include <Carbon/Carbon.h>
26 #include "pango-engine.h"
27 #include "pango-utils.h"
28 #include "pango-fontmap.h"
29 #include "pangoatsui.h"
31 /* No extra fields needed */
32 typedef PangoEngineShape BasicEngineATSUI;
33 typedef PangoEngineShapeClass BasicEngineATSUIClass ;
35 #define SCRIPT_ENGINE_NAME "BasicScriptEngineATSUI"
36 #define RENDER_TYPE PANGO_RENDER_TYPE_ATSUI
38 static PangoEngineScriptInfo basic_scripts[] = {
39 { PANGO_SCRIPT_COMMON, "" }
42 static PangoEngineInfo script_engines[] = {
45 PANGO_ENGINE_TYPE_SHAPE,
47 basic_scripts, G_N_ELEMENTS(basic_scripts)
52 set_glyph (PangoFont *font,
53 PangoGlyphString *glyphs,
58 PangoRectangle logical_rect;
60 glyphs->glyphs[i].glyph = G_UNLIKELY (glyph == kATSDeletedGlyphcode) ?
61 PANGO_GLYPH_EMPTY : glyph;
63 glyphs->glyphs[i].geometry.x_offset = 0;
64 glyphs->glyphs[i].geometry.y_offset = 0;
66 glyphs->log_clusters[i] = offset;
67 pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph, NULL, &logical_rect);
68 glyphs->glyphs[i].geometry.width = logical_rect.width;
72 basic_engine_shape (PangoEngineShape *engine,
76 const PangoAnalysis *analysis,
77 PangoGlyphString *glyphs)
81 ATSUTextLayout text_layout;
82 ATSLayoutRecord *layout_records;
84 ItemCount glyph_count;
87 PangoATSUIFont *afont = PANGO_ATSUI_FONT (font);
90 ATSUAttributeTag styleTags[] = { kATSUFontTag };
91 ATSUAttributeValuePtr styleValues[] = { &fontID };
92 ByteCount styleSizes[] = { sizeof (CGFontRef) };
94 utf16 = g_utf8_to_utf16 (text, length, NULL, &n16, NULL);
96 err = ATSUCreateTextLayout (&text_layout);
97 err = ATSUSetTextPointerLocation (text_layout, utf16, 0, n16, n16);
99 err = ATSUCreateStyle(&style);
100 fontID = pango_atsui_font_get_cgfont (afont);
102 err = ATSUSetAttributes(style,
103 sizeof(styleTags) / sizeof(styleTags[0]),
104 styleTags, styleSizes, styleValues);
106 err = ATSUSetRunStyle(text_layout,
107 style, kATSUFromTextBeginning, kATSUToTextEnd);
109 err = ATSUDirectGetLayoutDataArrayPtrFromTextLayout (text_layout, 0,
110 kATSUDirectDataLayoutRecordATSLayoutRecordCurrent,
111 (void *)&layout_records,
115 pango_glyph_string_set_size (glyphs, glyph_count - 1);
117 for (i = 0; i < glyph_count - 1; i++)
120 gunichar mirrored_ch;
122 wc = g_utf8_get_char (p);
124 if (analysis->level % 2)
125 if (pango_get_mirror_char (wc, &mirrored_ch))
128 if (wc == 0xa0) /* non-break-space */
131 if (pango_is_zero_width (wc))
133 set_glyph (font, glyphs, i, p - text, PANGO_GLYPH_EMPTY);
137 set_glyph (font, glyphs, i, p - text, layout_records[i].glyphID);
139 if (g_unichar_type (wc) == G_UNICODE_NON_SPACING_MARK)
143 PangoRectangle logical_rect, ink_rect;
145 glyphs->glyphs[i].geometry.width = MAX (glyphs->glyphs[i-1].geometry.width,
146 glyphs->glyphs[i].geometry.width);
147 glyphs->glyphs[i-1].geometry.width = 0;
148 glyphs->log_clusters[i] = glyphs->log_clusters[i-1];
150 /* Some heuristics to try to guess how overstrike glyphs are
151 * done and compensate
153 pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph, &ink_rect, &logical_rect);
154 if (logical_rect.width == 0 && ink_rect.x == 0)
155 glyphs->glyphs[i].geometry.x_offset = (glyphs->glyphs[i].geometry.width - ink_rect.width) / 2;
160 p = g_utf8_next_char (p);
163 ATSUDirectReleaseLayoutDataArrayPtr (NULL, kATSUDirectDataLayoutRecordATSLayoutRecordCurrent,
164 (void *)&layout_records);
166 ATSUDisposeStyle (style);
167 ATSUDisposeTextLayout (text_layout);
173 basic_engine_atsui_class_init (PangoEngineShapeClass *class)
175 class->script_shape = basic_engine_shape;
178 PANGO_ENGINE_SHAPE_DEFINE_TYPE (BasicEngineATSUI, basic_engine_atsui,
179 basic_engine_atsui_class_init, NULL);
182 PANGO_MODULE_ENTRY(init) (GTypeModule *module)
184 basic_engine_atsui_register_type (module);
188 PANGO_MODULE_ENTRY(exit) (void)
193 PANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines,
196 *engines = script_engines;
197 *n_engines = G_N_ELEMENTS (script_engines);
201 PANGO_MODULE_ENTRY(create) (const char *id)
203 if (!strcmp (id, SCRIPT_ENGINE_NAME))
204 return g_object_new (basic_engine_atsui_type, NULL);