diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/basic/Makefile.am | 17 | ||||
-rw-r--r-- | modules/basic/basic-coretext.c | 249 | ||||
-rw-r--r-- | modules/hebrew/hebrew-shaper.c | 2 |
3 files changed, 267 insertions, 1 deletions
diff --git a/modules/basic/Makefile.am b/modules/basic/Makefile.am index 646a61ec..70e4b6b1 100644 --- a/modules/basic/Makefile.am +++ b/modules/basic/Makefile.am @@ -54,6 +54,16 @@ libpango_basic_win32_la_SOURCES = basic-win32.c libpango_basic_win32_la_CFLAGS = -DPANGO_MODULE_PREFIX=_pango_basic_win32 if HAVE_CAIRO_ATSUI +if HAVE_CORE_TEXT +INCLUDES += $(CAIRO_CFLAGS) +if INCLUDE_BASIC_CORE_TEXT +noinst_LTLIBRARIES += libpango-basic-coretext.la +else +if DYNAMIC_BASIC_CORE_TEXT +module_LTLIBRARIES += pango-basic-coretext.la +endif +endif +else INCLUDES += $(ATSUI_CFLAGS) $(CAIRO_CFLAGS) if INCLUDE_BASIC_ATSUI noinst_LTLIBRARIES += libpango-basic-atsui.la @@ -63,6 +73,13 @@ module_LTLIBRARIES += pango-basic-atsui.la endif endif endif +endif + +pango_basic_coretext_la_LDFLAGS = -module $(MODULE_LIBTOOL_OPTIONS) -framework Carbon +pango_basic_coretext_la_LIBADD = $(pangocoretextlibs) +pango_basic_coretext_la_SOURCES = basic-coretext.c +libpango_basic_coretext_la_SOURCES = basic-coretext.c +libpango_basic_coretext_la_CFLAGS = -DPANGO_MODULE_PREFIX=_pango_basic_coretext pango_basic_atsui_la_LDFLAGS = -module $(MODULE_LIBTOOL_OPTIONS) -framework Carbon pango_basic_atsui_la_LIBADD = $(pangoatsuilibs) diff --git a/modules/basic/basic-coretext.c b/modules/basic/basic-coretext.c new file mode 100644 index 00000000..8dc3dbab --- /dev/null +++ b/modules/basic/basic-coretext.c @@ -0,0 +1,249 @@ +/* Pango + * basic-coretext.c + * + * Copyright (C) 2005 Imendio AB + * Copyright (C) 2010 Kristian Rietveld <kris@gtk.org> + * + * 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 "config.h" +#include <glib.h> +#include <string.h> +#include <Carbon/Carbon.h> +#include "pango-engine.h" +#include "pango-utils.h" +#include "pango-fontmap.h" +#include "pangocoretext.h" + +/* No extra fields needed */ +typedef PangoEngineShape BasicEngineCoreText; +typedef PangoEngineShapeClass BasicEngineCoreTextClass ; + +#define SCRIPT_ENGINE_NAME "BasicScriptEngineCoreText" +#define RENDER_TYPE PANGO_RENDER_TYPE_CORE_TEXT + +static PangoEngineScriptInfo basic_scripts[] = { + { 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, + const PangoAnalysis *analysis, + PangoGlyphString *glyphs) +{ + const char *p; + char *copy; + CTLineRef line; + CFStringRef cstr; + CFDictionaryRef attributes; + CFAttributedStringRef attstr; + PangoCoreTextFont *cfont = PANGO_CORE_TEXT_FONT (font); + PangoCoverage *coverage; + CFArrayRef runs; + CTRunRef run; + CTRunStatus run_status; + CFIndex i, glyph_count; + const CGGlyph *cgglyphs; + + CFTypeRef keys[] = { + (CFTypeRef) kCTFontAttributeName + }; + + CFTypeRef values[] = { + pango_core_text_font_get_ctfont (cfont) + }; + + attributes = CFDictionaryCreate (kCFAllocatorDefault, + (const void **)keys, + (const void **)values, + 1, + &kCFCopyStringDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + copy = g_strndup (text, length + 1); + copy[length] = 0; + + cstr = CFStringCreateWithCString (kCFAllocatorDefault, copy, + kCFStringEncodingUTF8); + g_free (copy); + + attstr = CFAttributedStringCreate (kCFAllocatorDefault, + cstr, + attributes); + + line = CTLineCreateWithAttributedString (attstr); + + runs = CTLineGetGlyphRuns (line); + + /* Since Pango divides things into runs already, we assume there is + * only a single run in this line. + */ + run = CFArrayGetValueAtIndex (runs, 0); + run_status = CTRunGetStatus (run); + glyph_count = CTRunGetGlyphCount (run); + cgglyphs = CTRunGetGlyphsPtr (run); + + p = text; + pango_glyph_string_set_size (glyphs, glyph_count); + coverage = pango_font_get_coverage (PANGO_FONT (cfont), + analysis->language); + + for (i = 0; i < glyph_count; i++) + { + CFIndex real_i, prev_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 (run_status & kCTRunStatusRightToLeft) + { + real_i = glyph_count - i - 1; + prev_i = real_i + 1; + } + else + { + real_i = i; + prev_i = real_i - 1; + } + + if (wc == 0xa0) /* non-break-space */ + wc = 0x20; + + if (pango_is_zero_width (wc)) + { + set_glyph (font, glyphs, real_i, p - text, PANGO_GLYPH_EMPTY); + } + else + { + PangoCoverageLevel result; + + result = pango_coverage_get (coverage, wc); + + if (result != PANGO_COVERAGE_NONE) + { + set_glyph (font, glyphs, real_i, p - text, cgglyphs[real_i]); + + if (g_unichar_type (wc) == G_UNICODE_NON_SPACING_MARK) + { + if (i > 0) + { + PangoRectangle logical_rect, ink_rect; + + glyphs->glyphs[real_i].geometry.width = MAX (glyphs->glyphs[prev_i].geometry.width, + glyphs->glyphs[prev_i].geometry.width); + glyphs->glyphs[prev_i].geometry.width = 0; + glyphs->log_clusters[real_i] = glyphs->log_clusters[prev_i]; + + /* Some heuristics to try to guess how overstrike glyphs are + * done and compensate + */ + pango_font_get_glyph_extents (font, glyphs->glyphs[real_i].glyph, &ink_rect, &logical_rect); + if (logical_rect.width == 0 && ink_rect.x == 0) + glyphs->glyphs[real_i].geometry.x_offset = (glyphs->glyphs[real_i].geometry.width - ink_rect.width) / 2; + } + } + } + else + { + set_glyph (font, glyphs, real_i, p - text, + PANGO_GET_UNKNOWN_GLYPH (wc)); + } + } + + p = g_utf8_next_char (p); + } + + CFRelease (line); + CFRelease (attstr); + CFRelease (cstr); + CFRelease (attributes); + pango_coverage_unref (coverage); +} + +static void +basic_engine_core_text_class_init (PangoEngineShapeClass *class) +{ + class->script_shape = basic_engine_shape; +} + +PANGO_ENGINE_SHAPE_DEFINE_TYPE (BasicEngineCoreText, basic_engine_core_text, + basic_engine_core_text_class_init, NULL); + +void +PANGO_MODULE_ENTRY(init) (GTypeModule *module) +{ + basic_engine_core_text_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_core_text_type, NULL); + else + return NULL; +} + diff --git a/modules/hebrew/hebrew-shaper.c b/modules/hebrew/hebrew-shaper.c index 8aa36381..db3055b7 100644 --- a/modules/hebrew/hebrew-shaper.c +++ b/modules/hebrew/hebrew-shaper.c @@ -167,7 +167,7 @@ static const gboolean compose_table[4][4] = { #define is_composible(cur_wc, nxt_wc) (compose_table[char_type_table[ucs2iso8859_8 (cur_wc)]]\ [char_type_table[ucs2iso8859_8 (nxt_wc)]]) -G_CONST_RETURN char * +const char * hebrew_shaper_get_next_cluster(const char *text, gint length, gunichar *cluster, |