diff options
author | Anders Carlsson <andersca@src.gnome.org> | 2005-11-25 08:22:12 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@src.gnome.org> | 2005-11-25 08:22:12 +0000 |
commit | ea706a3742ec4477ee66649226c48a2203b947e6 (patch) | |
tree | fdce091578b0823c05cd43c0f8168a57d98d8538 | |
parent | 77e7f93abaeeae3ca3cd419113dd627e5d25d5a6 (diff) | |
download | pango-ea706a3742ec4477ee66649226c48a2203b947e6.tar.gz |
Forgot to add this
-rw-r--r-- | modules/basic/basic-atsui.c | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/modules/basic/basic-atsui.c b/modules/basic/basic-atsui.c new file mode 100644 index 00000000..f1054e7f --- /dev/null +++ b/modules/basic/basic-atsui.c @@ -0,0 +1,234 @@ +/* Pango + * basic-atsui.c + * + * Copyright (C) 2005 Imendio AB + * + * 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 <glib.h> +#include <string.h> +#include <Carbon/Carbon.h> +#include "pango-engine.h" +#include "pango-utils.h" +#include "pango-fontmap.h" +#include "pangoatsui.h" +#include "pangocairo-atsuifont.h" + +/* No extra fields needed */ +typedef PangoEngineShape BasicEngineATSUI; +typedef PangoEngineShapeClass BasicEngineATSUIClass ; + +#define SCRIPT_ENGINE_NAME "BasicScriptEngineATSUI" +#define RENDER_TYPE PANGO_RENDER_TYPE_ATSUI + +static PangoEngineScriptInfo basic_scripts[] = { + { PANGO_SCRIPT_ARMENIAN, "*" }, + { PANGO_SCRIPT_BOPOMOFO, "*" }, + { PANGO_SCRIPT_CHEROKEE, "*" }, + { PANGO_SCRIPT_COPTIC, "*" }, + { PANGO_SCRIPT_CYRILLIC, "*" }, + { PANGO_SCRIPT_DESERET, "*" }, + { PANGO_SCRIPT_ETHIOPIC, "*" }, + { PANGO_SCRIPT_GEORGIAN, "*" }, + { PANGO_SCRIPT_GOTHIC, "*" }, + { PANGO_SCRIPT_GREEK, "*" }, + { PANGO_SCRIPT_HAN, "*" }, + { PANGO_SCRIPT_HIRAGANA, "*" }, + { PANGO_SCRIPT_KATAKANA, "*" }, + { PANGO_SCRIPT_LATIN, "*" }, + { PANGO_SCRIPT_OGHAM, "*" }, + { PANGO_SCRIPT_OLD_ITALIC, "*" }, + { PANGO_SCRIPT_RUNIC, "*" }, + { PANGO_SCRIPT_CANADIAN_ABORIGINAL, "*" }, + { PANGO_SCRIPT_YI, "*" }, + { PANGO_SCRIPT_BRAILLE, "*" }, + { PANGO_SCRIPT_CYPRIOT, "*" }, + { PANGO_SCRIPT_LIMBU, "*" }, + { PANGO_SCRIPT_OSMANYA, "*" }, + { PANGO_SCRIPT_SHAVIAN, "*" }, + { PANGO_SCRIPT_LINEAR_B, "*" }, + { PANGO_SCRIPT_UGARITIC, "*" }, + + { PANGO_SCRIPT_COMMON, "" } +}; + +static PangoEngineInfo script_engines[] = { + { + SCRIPT_ENGINE_NAME, + PANGO_ENGINE_TYPE_SHAPE, + RENDER_TYPE, + basic_scripts, G_N_ELEMENTS(basic_scripts) + } +}; + +static void +set_glyph (PangoFont *font, + PangoGlyphString *glyphs, + int i, + int offset, + PangoGlyph glyph) +{ + PangoRectangle logical_rect; + + glyphs->glyphs[i].glyph = glyph; + + glyphs->glyphs[i].geometry.x_offset = 0; + glyphs->glyphs[i].geometry.y_offset = 0; + + glyphs->log_clusters[i] = offset; + pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph, NULL, &logical_rect); + glyphs->glyphs[i].geometry.width = logical_rect.width; +} + +static void +basic_engine_shape (PangoEngineShape *engine, + PangoFont *font, + const char *text, + gint length, + PangoAnalysis *analysis, + PangoGlyphString *glyphs) +{ + gunichar2 *utf16; + long n16; + ATSUTextLayout text_layout; + ATSLayoutRecord *layout_records; + OSStatus err; + ItemCount glyph_count; + int i; + const char *p; + PangoCairoATSUIFont *cafont = PANGO_CAIRO_ATSUI_FONT (font); + ATSUStyle style; + ATSUFontID fontID; + ATSUAttributeTag styleTags[] = + { kATSUFontTag }; + ATSUAttributeValuePtr styleValues[] = { &fontID }; + ByteCount styleSizes[] = + { sizeof(ATSUFontID) }; + + utf16 = g_utf8_to_utf16 (text, length, NULL, &n16, NULL); + + err = ATSUCreateTextLayout (&text_layout); + err = ATSUSetTextPointerLocation (text_layout, utf16, 0, n16, n16); + + err = ATSUCreateStyle(&style); + fontID = pango_cairo_atsui_font_get_atsu_font_id (cafont); + + err = ATSUSetAttributes(style, + sizeof(styleTags) / sizeof(styleTags[0]), + styleTags, styleSizes, styleValues); + + err = ATSUSetRunStyle(text_layout, + style, kATSUFromTextBeginning, kATSUToTextEnd); + + err = ATSUDirectGetLayoutDataArrayPtrFromTextLayout (text_layout, 0, + kATSUDirectDataLayoutRecordATSLayoutRecordCurrent, + (void *)&layout_records, + &glyph_count); + + + p = text; + pango_glyph_string_set_size (glyphs, glyph_count - 1); + + for (i = 0; i < glyph_count - 1; i++) + { + gunichar wc; + gunichar mirrored_ch; + + wc = g_utf8_get_char (p); + + if (analysis->level % 2) + if (pango_get_mirror_char (wc, &mirrored_ch)) + wc = mirrored_ch; + + if (wc == 0xa0) /* non-break-space */ + wc = 0x20; + + if (pango_is_zero_width (wc)) + { + set_glyph (font, glyphs, i, p - text, 0); + } + else + { + set_glyph (font, glyphs, i, p - text, layout_records[i].glyphID); + + if (g_unichar_type (wc) == G_UNICODE_NON_SPACING_MARK) + { + if (i > 0) + { + PangoRectangle logical_rect, ink_rect; + + glyphs->glyphs[i].geometry.width = MAX (glyphs->glyphs[i-1].geometry.width, + glyphs->glyphs[i].geometry.width); + glyphs->glyphs[i-1].geometry.width = 0; + glyphs->log_clusters[i] = glyphs->log_clusters[i-1]; + + /* Some heuristics to try to guess how overstrike glyphs are + * done and compensate + */ + pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph, &ink_rect, &logical_rect); + if (logical_rect.width == 0 && ink_rect.x == 0) + glyphs->glyphs[i].geometry.x_offset = (glyphs->glyphs[i].geometry.width - ink_rect.width) / 2; + } + } + } + + p = g_utf8_next_char (p); + } + + ATSUDirectReleaseLayoutDataArrayPtr (NULL, kATSUDirectDataLayoutRecordATSLayoutRecordCurrent, + (void *)&layout_records); + + ATSUDisposeTextLayout (text_layout); +} + +static void +basic_engine_atsui_class_init (PangoEngineShapeClass *class) +{ + class->script_shape = basic_engine_shape; +} + +PANGO_ENGINE_SHAPE_DEFINE_TYPE (BasicEngineATSUI, basic_engine_atsui, + basic_engine_atsui_class_init, NULL); + +void +PANGO_MODULE_ENTRY(init) (GTypeModule *module) +{ + basic_engine_atsui_register_type (module); +} + +void +PANGO_MODULE_ENTRY(exit) (void) +{ +} + +void +PANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines, + int *n_engines) +{ + *engines = script_engines; + *n_engines = G_N_ELEMENTS (script_engines); +} + +PangoEngine * +PANGO_MODULE_ENTRY(create) (const char *id) +{ + if (!strcmp (id, SCRIPT_ENGINE_NAME)) + return g_object_new (basic_engine_atsui_type, NULL); + else + return NULL; +} + |