diff options
author | Behdad Esfahbod <behdad@gnome.org> | 2006-01-28 20:29:18 +0000 |
---|---|---|
committer | Behdad Esfahbod <behdad@src.gnome.org> | 2006-01-28 20:29:18 +0000 |
commit | 19a52f4677f20874eb614cfc70beeb53baf4adcc (patch) | |
tree | d98623635aea6625c499d820be1b91286cc14c2c /pango/pango-ot-buffer.c | |
parent | a42f978ef2c7ca0788ca66539a6ff3187f8a87e8 (diff) | |
download | pango-19a52f4677f20874eb614cfc70beeb53baf4adcc.tar.gz |
Removed.
2006-01-28 Behdad Esfahbod <behdad@gnome.org>
* pango/opentype/pango-ot-*: Removed.
* pango/pango-ot-*: Added.
* pango/Makefile.am, pango/opentype/Makefile.am: Adjusted.
Diffstat (limited to 'pango/pango-ot-buffer.c')
-rw-r--r-- | pango/pango-ot-buffer.c | 339 |
1 files changed, 339 insertions, 0 deletions
diff --git a/pango/pango-ot-buffer.c b/pango/pango-ot-buffer.c new file mode 100644 index 00000000..f649ae62 --- /dev/null +++ b/pango/pango-ot-buffer.c @@ -0,0 +1,339 @@ +/* Pango + * pango-ot-buffer.c: Buffer of glyphs for shaping/positioning + * + * Copyright (C) 2004 Red Hat Software + * + * 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 "pango-ot-private.h" + +#define PANGO_SCALE_26_6 (PANGO_SCALE / (1<<6)) +#define PANGO_UNITS_26_6(d) (PANGO_SCALE_26_6 * (d)) + +/** + * pango_ot_buffer_new + * @font: a #PangoFcFont + * + * Return value: the new #PangoOTBuffer + * + * Since: 1.4 + **/ +PangoOTBuffer * +pango_ot_buffer_new (PangoFcFont *font) +{ + /* We lock the font here immediately for the silly reason + * of getting the FT_Memory; otherwise we'd have to + * add a new operation to PangoFcFontmap; callers will + * probably already have the font locked, however, + * so there is little performance penalty. + */ + PangoOTBuffer *buffer = g_slice_new (PangoOTBuffer); + FT_Face face = pango_fc_font_lock_face (font); + + if (otl_buffer_new (face->memory, &buffer->buffer) != FT_Err_Ok) + g_error ("Allocation of OTLBuffer failed"); + + buffer->font = g_object_ref (font); + buffer->applied_gpos = FALSE; + buffer->rtl = FALSE; + buffer->zero_width_marks = FALSE; + + pango_fc_font_unlock_face (font); + + return buffer; +} + +/** + * pango_ot_buffer_destroy + * @buffer: a #PangoOTBuffer + * + * Since: 1.4 + **/ +void +pango_ot_buffer_destroy (PangoOTBuffer *buffer) +{ + otl_buffer_free (buffer->buffer); + g_object_unref (buffer->font); + g_slice_free (PangoOTBuffer, buffer); +} + +/** + * pango_ot_buffer_clear + * @buffer: a #PangoOTBuffer + * + * Since: 1.4 + **/ +void +pango_ot_buffer_clear (PangoOTBuffer *buffer) +{ + otl_buffer_clear (buffer->buffer); + buffer->applied_gpos = FALSE; +} + +/** + * pango_ot_buffer_add_glyph + * @buffer: a #PangoOTBuffer + * @glyph_index: + * @properties: + * @cluster: + * + * Since: 1.4 + **/ +void +pango_ot_buffer_add_glyph (PangoOTBuffer *buffer, + guint glyph_index, + guint properties, + guint cluster) +{ + otl_buffer_add_glyph (buffer->buffer, + glyph_index, properties, cluster); + +} + +/** + * pango_ot_buffer_set_rtl + * @buffer: a #PangoOTBuffer + * @rtl: %TRUE for right-to-left + * + * Since: 1.4 + **/ +void +pango_ot_buffer_set_rtl (PangoOTBuffer *buffer, + gboolean rtl) +{ + buffer->rtl = rtl != FALSE; +} + +/** + * pango_ot_buffer_set_zero_width_marks: + * @buffer: a #PangoOTBuffer + * @zero_width_marks: %TRUE if characters with a mark class should + * be forced to zero width. + * + * Sets whether characters with a mark class should be forced to zero width. + * This setting is needed for proper positioning of Arabic accents, + * but will produce incorrect results with standard OpenType indic + * fonts. + * + * Since: 1.6 + **/ +void +pango_ot_buffer_set_zero_width_marks (PangoOTBuffer *buffer, + gboolean zero_width_marks) +{ + buffer->zero_width_marks = zero_width_marks != FALSE; +} + +/** + * pango_ot_buffer_get_glyphs + * @buffer: a #PangoOTBuffer + * @glyphs: + * @n_glyphs: + * + * Since: 1.4 + **/ +void +pango_ot_buffer_get_glyphs (PangoOTBuffer *buffer, + PangoOTGlyph **glyphs, + int *n_glyphs) +{ + if (glyphs) + *glyphs = (PangoOTGlyph *)buffer->buffer->in_string; + + if (n_glyphs) + *n_glyphs = buffer->buffer->in_length; +} + +static void +swap_range (PangoGlyphString *glyphs, int start, int end) +{ + int i, j; + + for (i = start, j = end - 1; i < j; i++, j--) + { + PangoGlyphInfo glyph_info; + gint log_cluster; + + glyph_info = glyphs->glyphs[i]; + glyphs->glyphs[i] = glyphs->glyphs[j]; + glyphs->glyphs[j] = glyph_info; + + log_cluster = glyphs->log_clusters[i]; + glyphs->log_clusters[i] = glyphs->log_clusters[j]; + glyphs->log_clusters[j] = log_cluster; + } +} + +static void +apply_gpos_ltr (PangoGlyphString *glyphs, + OTL_Position positions) +{ + int i; + + for (i = 0; i < glyphs->num_glyphs; i++) + { + FT_Pos x_pos = positions[i].x_pos; + FT_Pos y_pos = positions[i].y_pos; + int back = i; + int j; + + while (positions[back].back != 0) + { + back -= positions[back].back; + x_pos += positions[back].x_pos; + y_pos += positions[back].y_pos; + } + + for (j = back; j < i; j++) + glyphs->glyphs[i].geometry.x_offset -= glyphs->glyphs[j].geometry.width; + + glyphs->glyphs[i].geometry.x_offset += PANGO_UNITS_26_6(x_pos); + glyphs->glyphs[i].geometry.y_offset -= PANGO_UNITS_26_6(y_pos); + + if (positions[i].new_advance) + glyphs->glyphs[i].geometry.width = PANGO_UNITS_26_6(positions[i].x_advance); + else + glyphs->glyphs[i].geometry.width += PANGO_UNITS_26_6(positions[i].x_advance); + } +} + +static void +apply_gpos_rtl (PangoGlyphString *glyphs, + OTL_Position positions) +{ + int i; + + for (i = 0; i < glyphs->num_glyphs; i++) + { + int i_rev = glyphs->num_glyphs - i - 1; + int back_rev = i_rev; + int back; + FT_Pos x_pos = positions[i_rev].x_pos; + FT_Pos y_pos = positions[i_rev].y_pos; + int j; + + while (positions[back_rev].back != 0) + { + back_rev -= positions[back_rev].back; + x_pos += positions[back_rev].x_pos; + y_pos += positions[back_rev].y_pos; + } + + back = glyphs->num_glyphs - back_rev - 1; + + for (j = i; j < back; j++) + glyphs->glyphs[i].geometry.x_offset += glyphs->glyphs[j].geometry.width; + + glyphs->glyphs[i].geometry.x_offset += PANGO_UNITS_26_6(x_pos); + glyphs->glyphs[i].geometry.y_offset -= PANGO_UNITS_26_6(y_pos); + + if (positions[i_rev].new_advance) + glyphs->glyphs[i].geometry.width = PANGO_UNITS_26_6(positions[i_rev].x_advance); + else + glyphs->glyphs[i].geometry.width += PANGO_UNITS_26_6(positions[i_rev].x_advance); + } +} + +/** + * pango_ot_buffer_output + * @buffer: a #PangoOTBuffer + * @glyphs: a #PangoGlyphString + * + * Since: 1.4 + **/ +void +pango_ot_buffer_output (PangoOTBuffer *buffer, + PangoGlyphString *glyphs) +{ + FT_Face face; + PangoOTInfo *info; + TTO_GDEF gdef = NULL; + unsigned int i; + int last_cluster; + + face = pango_fc_font_lock_face (buffer->font); + g_assert (face); + + /* Copy glyphs into output glyph string */ + pango_glyph_string_set_size (glyphs, buffer->buffer->in_length); + + last_cluster = -1; + for (i = 0; i < buffer->buffer->in_length; i++) + { + OTL_GlyphItem item = &buffer->buffer->in_string[i]; + + glyphs->glyphs[i].glyph = item->gindex; + + glyphs->log_clusters[i] = item->cluster; + if (glyphs->log_clusters[i] != last_cluster) + glyphs->glyphs[i].attr.is_cluster_start = 1; + else + glyphs->glyphs[i].attr.is_cluster_start = 0; + + last_cluster = glyphs->log_clusters[i]; + } + + info = pango_ot_info_get (face); + gdef = pango_ot_info_get_gdef (info); + + /* Apply default positioning */ + for (i = 0; i < (unsigned int)glyphs->num_glyphs; i++) + { + if (glyphs->glyphs[i].glyph) + { + PangoRectangle logical_rect; + + FT_UShort property; + + if (buffer->zero_width_marks && + gdef && + TT_GDEF_Get_Glyph_Property (gdef, glyphs->glyphs[i].glyph, &property) == FT_Err_Ok && + (property == TTO_MARK || (property & IGNORE_SPECIAL_MARKS) != 0)) + { + glyphs->glyphs[i].geometry.width = 0; + } + else + { + pango_font_get_glyph_extents ((PangoFont *)buffer->font, glyphs->glyphs[i].glyph, NULL, &logical_rect); + glyphs->glyphs[i].geometry.width = logical_rect.width; + } + } + else + glyphs->glyphs[i].geometry.width = 0; + + glyphs->glyphs[i].geometry.x_offset = 0; + glyphs->glyphs[i].geometry.y_offset = 0; + } + + if (buffer->rtl) + { + /* Swap all glyphs */ + swap_range (glyphs, 0, glyphs->num_glyphs); + } + + if (buffer->applied_gpos) + { + if (buffer->rtl) + apply_gpos_rtl (glyphs, buffer->buffer->positions); + else + apply_gpos_ltr (glyphs, buffer->buffer->positions); + } + + pango_fc_font_unlock_face (buffer->font); +} |