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.
This commit is contained in:
parent
f45689bc65
commit
e040f68196
|
@ -1,19 +1,16 @@
|
||||||
## Process this file with automake to produce Makefile.in
|
## Process this file with automake to produce Makefile.in
|
||||||
|
|
||||||
INCLUDES = \
|
INCLUDES = \
|
||||||
-DG_LOG_DOMAIN=\"Pango\" \
|
|
||||||
-DPANGO_ENABLE_ENGINE \
|
|
||||||
-DSYSCONFDIR=\"$(sysconfdir)\" \
|
-DSYSCONFDIR=\"$(sysconfdir)\" \
|
||||||
-DLIBDIR=\"$(libdir)\" \
|
-DLIBDIR=\"$(libdir)\" \
|
||||||
$(PANGO_DEBUG_FLAGS) \
|
$(PANGO_DEBUG_FLAGS) \
|
||||||
|
-I$(top_srcdir) \
|
||||||
$(GLIB_CFLAGS) \
|
$(GLIB_CFLAGS) \
|
||||||
$(FREETYPE_CFLAGS) \
|
$(FREETYPE_CFLAGS)
|
||||||
$(X_CFLAGS) \
|
|
||||||
-I$(top_srcdir)
|
|
||||||
|
|
||||||
noinst_LTLIBRARIES = libpango-ot.la
|
noinst_LTLIBRARIES = libmini-harfbuzz.la
|
||||||
|
|
||||||
libpango_ot_la_SOURCES = \
|
libmini_harfbuzz_la_SOURCES = \
|
||||||
ftglue.h \
|
ftglue.h \
|
||||||
ftglue.c \
|
ftglue.c \
|
||||||
ftxopen.c \
|
ftxopen.c \
|
||||||
|
@ -26,13 +23,9 @@ libpango_ot_la_SOURCES = \
|
||||||
ftxgsub.c \
|
ftxgsub.c \
|
||||||
ftxgsub.h \
|
ftxgsub.h \
|
||||||
otlbuffer.c \
|
otlbuffer.c \
|
||||||
otlbuffer.h \
|
otlbuffer.h
|
||||||
pango-ot-buffer.c \
|
|
||||||
pango-ot-info.c \
|
|
||||||
pango-ot-private.h \
|
|
||||||
pango-ot-ruleset.c
|
|
||||||
|
|
||||||
libpango_ot_la_LIBADD = \
|
libmini_harfbuzz_la_LIBADD = \
|
||||||
$(x_ldflags) \
|
$(x_ldflags) \
|
||||||
$(x_libs) \
|
$(x_libs) \
|
||||||
$(GLIB_LIBS) \
|
$(GLIB_LIBS) \
|
||||||
|
@ -48,8 +41,11 @@ ottest_SOURCES = \
|
||||||
disasm.h
|
disasm.h
|
||||||
|
|
||||||
ottest_LDADD = \
|
ottest_LDADD = \
|
||||||
libpango-ot.la \
|
libmini-harfbuzz.la \
|
||||||
$(FREETYPE_LIBS)
|
$(FREETYPE_LIBS)
|
||||||
|
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
README
|
README \
|
||||||
|
FTL.TXT \
|
||||||
|
FT-license.txt
|
||||||
|
|
||||||
|
|
|
@ -1,339 +0,0 @@
|
||||||
/* 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);
|
|
||||||
}
|
|
|
@ -1,681 +0,0 @@
|
||||||
/* Pango
|
|
||||||
* pango-ot-info.c: Store tables for OpenType
|
|
||||||
*
|
|
||||||
* Copyright (C) 2000 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"
|
|
||||||
#include "../pango-utils.h"
|
|
||||||
#include "ftglue.h"
|
|
||||||
#include FT_MODULE_H
|
|
||||||
|
|
||||||
static void pango_ot_info_class_init (GObjectClass *object_class);
|
|
||||||
static void pango_ot_info_finalize (GObject *object);
|
|
||||||
|
|
||||||
static GObjectClass *parent_class;
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
INFO_LOADED_GDEF = 1 << 0,
|
|
||||||
INFO_LOADED_GSUB = 1 << 1,
|
|
||||||
INFO_LOADED_GPOS = 1 << 2
|
|
||||||
};
|
|
||||||
|
|
||||||
GType
|
|
||||||
pango_ot_info_get_type (void)
|
|
||||||
{
|
|
||||||
static GType object_type = 0;
|
|
||||||
|
|
||||||
if (!object_type)
|
|
||||||
{
|
|
||||||
static const GTypeInfo object_info =
|
|
||||||
{
|
|
||||||
sizeof (PangoOTInfoClass),
|
|
||||||
(GBaseInitFunc) NULL,
|
|
||||||
(GBaseFinalizeFunc) NULL,
|
|
||||||
(GClassInitFunc)pango_ot_info_class_init,
|
|
||||||
NULL, /* class_finalize */
|
|
||||||
NULL, /* class_data */
|
|
||||||
sizeof (PangoOTInfo),
|
|
||||||
0, /* n_preallocs */
|
|
||||||
NULL, /* init */
|
|
||||||
NULL, /* value_table */
|
|
||||||
};
|
|
||||||
|
|
||||||
object_type = g_type_register_static (G_TYPE_OBJECT,
|
|
||||||
I_("PangoOTInfo"),
|
|
||||||
&object_info, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return object_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
pango_ot_info_class_init (GObjectClass *object_class)
|
|
||||||
{
|
|
||||||
parent_class = g_type_class_peek_parent (object_class);
|
|
||||||
|
|
||||||
object_class->finalize = pango_ot_info_finalize;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
pango_ot_info_finalize (GObject *object)
|
|
||||||
{
|
|
||||||
PangoOTInfo *info = PANGO_OT_INFO (object);
|
|
||||||
|
|
||||||
if (info->gdef)
|
|
||||||
{
|
|
||||||
TT_Done_GDEF_Table (info->gdef);
|
|
||||||
info->gdef = NULL;
|
|
||||||
}
|
|
||||||
if (info->gsub)
|
|
||||||
{
|
|
||||||
TT_Done_GSUB_Table (info->gsub);
|
|
||||||
info->gsub = NULL;
|
|
||||||
}
|
|
||||||
if (info->gpos)
|
|
||||||
{
|
|
||||||
TT_Done_GPOS_Table (info->gpos);
|
|
||||||
info->gpos = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
parent_class->finalize (object);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
pango_ot_info_finalizer (void *object)
|
|
||||||
{
|
|
||||||
FT_Face face = object;
|
|
||||||
PangoOTInfo *info = face->generic.data;
|
|
||||||
|
|
||||||
info->face = NULL;
|
|
||||||
g_object_unref (info);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* pango_ot_info_get:
|
|
||||||
* @face: a #FT_Face.
|
|
||||||
* @returns: the #PangoOTInfo for @face. This object will
|
|
||||||
* have the same lifetime as @face.
|
|
||||||
*
|
|
||||||
* Returns the #PangoOTInfo structure for the given FreeType font.
|
|
||||||
*
|
|
||||||
* Since: 1.2
|
|
||||||
**/
|
|
||||||
PangoOTInfo *
|
|
||||||
pango_ot_info_get (FT_Face face)
|
|
||||||
{
|
|
||||||
PangoOTInfo *info;
|
|
||||||
|
|
||||||
if (face->generic.data)
|
|
||||||
return face->generic.data;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
info = face->generic.data = g_object_new (PANGO_TYPE_OT_INFO, NULL);
|
|
||||||
face->generic.finalizer = pango_ot_info_finalizer;
|
|
||||||
|
|
||||||
info->face = face;
|
|
||||||
}
|
|
||||||
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* There must be be a better way to do this
|
|
||||||
*/
|
|
||||||
static gboolean
|
|
||||||
is_truetype (FT_Face face)
|
|
||||||
{
|
|
||||||
return FT_IS_SFNT(face);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct _GlyphInfo GlyphInfo;
|
|
||||||
|
|
||||||
struct _GlyphInfo {
|
|
||||||
FT_UShort glyph;
|
|
||||||
FT_UShort class;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
|
||||||
compare_glyph_info (gconstpointer a,
|
|
||||||
gconstpointer b)
|
|
||||||
{
|
|
||||||
const GlyphInfo *info_a = a;
|
|
||||||
const GlyphInfo *info_b = b;
|
|
||||||
|
|
||||||
return (info_a->glyph < info_b->glyph) ? -1 :
|
|
||||||
(info_a->glyph == info_b->glyph) ? 0 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make a guess at the appropriate class for a glyph given
|
|
||||||
* a character code that maps to the glyph
|
|
||||||
*/
|
|
||||||
static gboolean
|
|
||||||
get_glyph_class (gunichar charcode,
|
|
||||||
FT_UShort *class)
|
|
||||||
{
|
|
||||||
/* For characters mapped into the Arabic Presentation forms, using properties
|
|
||||||
* derived as we apply GSUB substitutions will be more reliable
|
|
||||||
*/
|
|
||||||
if ((charcode >= 0xFB50 && charcode <= 0xFDFF) || /* Arabic Presentation Forms-A */
|
|
||||||
(charcode >= 0xFE70 && charcode <= 0XFEFF)) /* Arabic Presentation Forms-B */
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
switch (g_unichar_type (charcode))
|
|
||||||
{
|
|
||||||
case G_UNICODE_COMBINING_MARK:
|
|
||||||
case G_UNICODE_ENCLOSING_MARK:
|
|
||||||
case G_UNICODE_NON_SPACING_MARK:
|
|
||||||
*class = 3; /* Mark glyph (non-spacing combining glyph) */
|
|
||||||
return TRUE;
|
|
||||||
case G_UNICODE_UNASSIGNED:
|
|
||||||
case G_UNICODE_PRIVATE_USE:
|
|
||||||
return FALSE; /* Unknown, don't assign a class; classes get
|
|
||||||
* propagated during GSUB application */
|
|
||||||
default:
|
|
||||||
*class = 1; /* Base glyph (single character, spacing glyph) */
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
set_unicode_charmap (FT_Face face)
|
|
||||||
{
|
|
||||||
int charmap;
|
|
||||||
|
|
||||||
for (charmap = 0; charmap < face->num_charmaps; charmap++)
|
|
||||||
if (face->charmaps[charmap]->encoding == ft_encoding_unicode)
|
|
||||||
{
|
|
||||||
FT_Error error = FT_Set_Charmap(face, face->charmaps[charmap]);
|
|
||||||
return error == FT_Err_Ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Synthesize a GDEF table using the font's charmap and the
|
|
||||||
* unicode property database. We'll fill in class definitions
|
|
||||||
* for glyphs not in the charmap as we walk through the tables.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
synthesize_class_def (PangoOTInfo *info)
|
|
||||||
{
|
|
||||||
GArray *glyph_infos;
|
|
||||||
FT_UShort *glyph_indices;
|
|
||||||
FT_UShort *classes;
|
|
||||||
FT_ULong charcode;
|
|
||||||
FT_UInt glyph;
|
|
||||||
unsigned int i, j;
|
|
||||||
FT_CharMap old_charmap;
|
|
||||||
|
|
||||||
old_charmap = info->face->charmap;
|
|
||||||
|
|
||||||
if (!old_charmap || !old_charmap->encoding != ft_encoding_unicode)
|
|
||||||
if (!set_unicode_charmap (info->face))
|
|
||||||
return;
|
|
||||||
|
|
||||||
glyph_infos = g_array_new (FALSE, FALSE, sizeof (GlyphInfo));
|
|
||||||
|
|
||||||
/* Collect all the glyphs in the charmap, and guess
|
|
||||||
* the appropriate classes for them
|
|
||||||
*/
|
|
||||||
charcode = FT_Get_First_Char (info->face, &glyph);
|
|
||||||
while (glyph != 0)
|
|
||||||
{
|
|
||||||
GlyphInfo glyph_info;
|
|
||||||
|
|
||||||
if (glyph <= 65535)
|
|
||||||
{
|
|
||||||
glyph_info.glyph = glyph;
|
|
||||||
if (get_glyph_class (charcode, &glyph_info.class))
|
|
||||||
g_array_append_val (glyph_infos, glyph_info);
|
|
||||||
}
|
|
||||||
|
|
||||||
charcode = FT_Get_Next_Char (info->face, charcode, &glyph);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sort and remove duplicates
|
|
||||||
*/
|
|
||||||
g_array_sort (glyph_infos, compare_glyph_info);
|
|
||||||
|
|
||||||
glyph_indices = g_new (FT_UShort, glyph_infos->len);
|
|
||||||
classes = g_new (FT_UShort, glyph_infos->len);
|
|
||||||
|
|
||||||
for (i = 0, j = 0; i < glyph_infos->len; i++)
|
|
||||||
{
|
|
||||||
GlyphInfo *info = &g_array_index (glyph_infos, GlyphInfo, i);
|
|
||||||
|
|
||||||
if (j == 0 || info->glyph != glyph_indices[j - 1])
|
|
||||||
{
|
|
||||||
glyph_indices[j] = info->glyph;
|
|
||||||
classes[j] = info->class;
|
|
||||||
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
g_array_free (glyph_infos, TRUE);
|
|
||||||
|
|
||||||
TT_GDEF_Build_ClassDefinition (info->gdef, info->face->num_glyphs, j,
|
|
||||||
glyph_indices, classes);
|
|
||||||
|
|
||||||
g_free (glyph_indices);
|
|
||||||
g_free (classes);
|
|
||||||
|
|
||||||
if (old_charmap && info->face->charmap != old_charmap)
|
|
||||||
FT_Set_Charmap (info->face, old_charmap);
|
|
||||||
}
|
|
||||||
|
|
||||||
TTO_GDEF
|
|
||||||
pango_ot_info_get_gdef (PangoOTInfo *info)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (PANGO_IS_OT_INFO (info), NULL);
|
|
||||||
|
|
||||||
if (!(info->loaded & INFO_LOADED_GDEF))
|
|
||||||
{
|
|
||||||
FT_Error error;
|
|
||||||
|
|
||||||
info->loaded |= INFO_LOADED_GDEF;
|
|
||||||
|
|
||||||
if (is_truetype (info->face))
|
|
||||||
{
|
|
||||||
error = TT_Load_GDEF_Table (info->face, &info->gdef);
|
|
||||||
|
|
||||||
if (error && error != TT_Err_Table_Missing)
|
|
||||||
g_warning ("Error loading GDEF table %d", error);
|
|
||||||
|
|
||||||
if (!info->gdef)
|
|
||||||
error = TT_New_GDEF_Table (info->face, &info->gdef);
|
|
||||||
|
|
||||||
if (info->gdef && !info->gdef->GlyphClassDef.loaded)
|
|
||||||
synthesize_class_def (info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return info->gdef;
|
|
||||||
}
|
|
||||||
|
|
||||||
TTO_GSUB
|
|
||||||
pango_ot_info_get_gsub (PangoOTInfo *info)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (PANGO_IS_OT_INFO (info), NULL);
|
|
||||||
|
|
||||||
if (!(info->loaded & INFO_LOADED_GSUB))
|
|
||||||
{
|
|
||||||
FT_Error error;
|
|
||||||
TTO_GDEF gdef = pango_ot_info_get_gdef (info);
|
|
||||||
|
|
||||||
info->loaded |= INFO_LOADED_GSUB;
|
|
||||||
|
|
||||||
if (is_truetype (info->face))
|
|
||||||
{
|
|
||||||
error = TT_Load_GSUB_Table (info->face, &info->gsub, gdef);
|
|
||||||
|
|
||||||
if (error && error != TT_Err_Table_Missing)
|
|
||||||
g_warning ("Error loading GSUB table %d", error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return info->gsub;
|
|
||||||
}
|
|
||||||
|
|
||||||
TTO_GPOS
|
|
||||||
pango_ot_info_get_gpos (PangoOTInfo *info)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (PANGO_IS_OT_INFO (info), NULL);
|
|
||||||
|
|
||||||
if (!(info->loaded & INFO_LOADED_GPOS))
|
|
||||||
{
|
|
||||||
FT_Error error;
|
|
||||||
TTO_GDEF gdef = pango_ot_info_get_gdef (info);
|
|
||||||
|
|
||||||
info->loaded |= INFO_LOADED_GPOS;
|
|
||||||
|
|
||||||
if (is_truetype (info->face))
|
|
||||||
{
|
|
||||||
error = TT_Load_GPOS_Table (info->face, &info->gpos, gdef);
|
|
||||||
|
|
||||||
if (error && error != TT_Err_Table_Missing)
|
|
||||||
g_warning ("Error loading GPOS table %d", error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return info->gpos;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
get_tables (PangoOTInfo *info,
|
|
||||||
PangoOTTableType table_type,
|
|
||||||
TTO_ScriptList **script_list,
|
|
||||||
TTO_FeatureList **feature_list)
|
|
||||||
{
|
|
||||||
if (table_type == PANGO_OT_TABLE_GSUB)
|
|
||||||
{
|
|
||||||
TTO_GSUB gsub = pango_ot_info_get_gsub (info);
|
|
||||||
|
|
||||||
if (!gsub)
|
|
||||||
return FALSE;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (script_list)
|
|
||||||
*script_list = &gsub->ScriptList;
|
|
||||||
if (feature_list)
|
|
||||||
*feature_list = &gsub->FeatureList;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TTO_GPOS gpos = pango_ot_info_get_gpos (info);
|
|
||||||
|
|
||||||
if (!gpos)
|
|
||||||
return FALSE;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (script_list)
|
|
||||||
*script_list = &gpos->ScriptList;
|
|
||||||
if (feature_list)
|
|
||||||
*feature_list = &gpos->FeatureList;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* pango_ot_info_find_script:
|
|
||||||
* @info: a #PangoOTInfo.
|
|
||||||
* @table_type: the table type to obtain information about.
|
|
||||||
* @script_tag: the tag of the script to find.
|
|
||||||
* @script_index: location to store the index of the script, or %NULL.
|
|
||||||
* @returns: %TRUE if the script was found.
|
|
||||||
*
|
|
||||||
* Finds the index of a script.
|
|
||||||
**/
|
|
||||||
gboolean
|
|
||||||
pango_ot_info_find_script (PangoOTInfo *info,
|
|
||||||
PangoOTTableType table_type,
|
|
||||||
PangoOTTag script_tag,
|
|
||||||
guint *script_index)
|
|
||||||
{
|
|
||||||
TTO_ScriptList *script_list;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
g_return_val_if_fail (PANGO_IS_OT_INFO (info), FALSE);
|
|
||||||
|
|
||||||
if (!get_tables (info, table_type, &script_list, NULL))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
for (i=0; i < script_list->ScriptCount; i++)
|
|
||||||
{
|
|
||||||
if (script_list->ScriptRecord[i].ScriptTag == script_tag)
|
|
||||||
{
|
|
||||||
if (script_index)
|
|
||||||
*script_index = i;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* pango_ot_info_find_language:
|
|
||||||
* @info: a #PangoOTInfo.
|
|
||||||
* @table_type: the table type to obtain information about.
|
|
||||||
* @script_index: the index of the script whose languages are searched.
|
|
||||||
* @language_tag: the tag of the language to find.
|
|
||||||
* @language_index: location to store the index of the language, or %NULL.
|
|
||||||
* @required_feature_index: location to store the required feature index of
|
|
||||||
* the language, or %NULL.
|
|
||||||
* @returns: %TRUE if the language was found.
|
|
||||||
*
|
|
||||||
* Finds the index of a language and its required feature index.
|
|
||||||
**/
|
|
||||||
gboolean
|
|
||||||
pango_ot_info_find_language (PangoOTInfo *info,
|
|
||||||
PangoOTTableType table_type,
|
|
||||||
guint script_index,
|
|
||||||
PangoOTTag language_tag,
|
|
||||||
guint *language_index,
|
|
||||||
guint *required_feature_index)
|
|
||||||
{
|
|
||||||
TTO_ScriptList *script_list;
|
|
||||||
TTO_Script *script;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
g_return_val_if_fail (PANGO_IS_OT_INFO (info), FALSE);
|
|
||||||
|
|
||||||
if (!get_tables (info, table_type, &script_list, NULL))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
g_return_val_if_fail (script_index < script_list->ScriptCount, FALSE);
|
|
||||||
|
|
||||||
script = &script_list->ScriptRecord[script_index].Script;
|
|
||||||
|
|
||||||
for (i = 0; i < script->LangSysCount; i++)
|
|
||||||
{
|
|
||||||
if (script->LangSysRecord[i].LangSysTag == language_tag)
|
|
||||||
{
|
|
||||||
if (language_index)
|
|
||||||
*language_index = i;
|
|
||||||
if (required_feature_index)
|
|
||||||
*required_feature_index = script->LangSysRecord[i].LangSys.ReqFeatureIndex;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* pango_ot_info_find_feature:
|
|
||||||
* @info: a #PangoOTInfo.
|
|
||||||
* @table_type: the table type to obtain information about.
|
|
||||||
* @feature_tag: the tag of the feature to find.
|
|
||||||
* @script_index: the index of the script.
|
|
||||||
* @language_index: the index of the language whose features are searched,
|
|
||||||
* or 0xffff to use the default language of the script.
|
|
||||||
* @feature_index: location to store the index of the feature, or %NULL.
|
|
||||||
* @returns: %TRUE if the feature was found.
|
|
||||||
*
|
|
||||||
* Finds the index of a feature.
|
|
||||||
**/
|
|
||||||
gboolean
|
|
||||||
pango_ot_info_find_feature (PangoOTInfo *info,
|
|
||||||
PangoOTTableType table_type,
|
|
||||||
PangoOTTag feature_tag,
|
|
||||||
guint script_index,
|
|
||||||
guint language_index,
|
|
||||||
guint *feature_index)
|
|
||||||
{
|
|
||||||
TTO_ScriptList *script_list;
|
|
||||||
TTO_FeatureList *feature_list;
|
|
||||||
TTO_Script *script;
|
|
||||||
TTO_LangSys *lang_sys;
|
|
||||||
|
|
||||||
int i;
|
|
||||||
|
|
||||||
g_return_val_if_fail (PANGO_IS_OT_INFO (info), FALSE);
|
|
||||||
|
|
||||||
if (!get_tables (info, table_type, &script_list, &feature_list))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
g_return_val_if_fail (script_index < script_list->ScriptCount, FALSE);
|
|
||||||
|
|
||||||
script = &script_list->ScriptRecord[script_index].Script;
|
|
||||||
|
|
||||||
if (language_index == 0xffff)
|
|
||||||
lang_sys = &script->DefaultLangSys;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (language_index < script->LangSysCount, FALSE);
|
|
||||||
lang_sys = &script->LangSysRecord[language_index].LangSys;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < lang_sys->FeatureCount; i++)
|
|
||||||
{
|
|
||||||
FT_UShort index = lang_sys->FeatureIndex[i];
|
|
||||||
|
|
||||||
if (feature_list->FeatureRecord[index].FeatureTag == feature_tag)
|
|
||||||
{
|
|
||||||
if (feature_index)
|
|
||||||
*feature_index = index;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* pango_ot_info_list_scripts:
|
|
||||||
* @info: a #PangoOTInfo.
|
|
||||||
* @table_type: the table type to obtain information about.
|
|
||||||
* @returns: a newly-allocated array containing the tags of the
|
|
||||||
* available scripts.
|
|
||||||
*
|
|
||||||
* Obtains the list of available scripts.
|
|
||||||
**/
|
|
||||||
PangoOTTag *
|
|
||||||
pango_ot_info_list_scripts (PangoOTInfo *info,
|
|
||||||
PangoOTTableType table_type)
|
|
||||||
{
|
|
||||||
PangoOTTag *result;
|
|
||||||
TTO_ScriptList *script_list;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
g_return_val_if_fail (PANGO_IS_OT_INFO (info), NULL);
|
|
||||||
|
|
||||||
if (!get_tables (info, table_type, &script_list, NULL))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
result = g_new (PangoOTTag, script_list->ScriptCount + 1);
|
|
||||||
|
|
||||||
for (i=0; i < script_list->ScriptCount; i++)
|
|
||||||
result[i] = script_list->ScriptRecord[i].ScriptTag;
|
|
||||||
|
|
||||||
result[i] = 0;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* pango_ot_info_list_languages:
|
|
||||||
* @info: a #PangoOTInfo.
|
|
||||||
* @table_type: the table type to obtain information about.
|
|
||||||
* @script_index: the index of the script to list languages for.
|
|
||||||
* @language_tag: unused parameter.
|
|
||||||
* @returns: a newly-allocated array containing the tags of the
|
|
||||||
* available languages.
|
|
||||||
*
|
|
||||||
* Obtains the list of available languages for a given script.
|
|
||||||
**/
|
|
||||||
PangoOTTag *
|
|
||||||
pango_ot_info_list_languages (PangoOTInfo *info,
|
|
||||||
PangoOTTableType table_type,
|
|
||||||
guint script_index,
|
|
||||||
PangoOTTag language_tag)
|
|
||||||
{
|
|
||||||
PangoOTTag *result;
|
|
||||||
TTO_ScriptList *script_list;
|
|
||||||
TTO_Script *script;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
g_return_val_if_fail (PANGO_IS_OT_INFO (info), NULL);
|
|
||||||
|
|
||||||
if (!get_tables (info, table_type, &script_list, NULL))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
g_return_val_if_fail (script_index < script_list->ScriptCount, NULL);
|
|
||||||
|
|
||||||
script = &script_list->ScriptRecord[script_index].Script;
|
|
||||||
|
|
||||||
result = g_new (PangoOTTag, script->LangSysCount + 1);
|
|
||||||
|
|
||||||
for (i = 0; i < script->LangSysCount; i++)
|
|
||||||
result[i] = script->LangSysRecord[i].LangSysTag;
|
|
||||||
|
|
||||||
result[i] = 0;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* pango_ot_info_list_features:
|
|
||||||
* @info: a #PangoOTInfo.
|
|
||||||
* @table_type: the table type to obtain information about.
|
|
||||||
* @tag: unused parameter.
|
|
||||||
* @script_index: the index of the script to obtain information about.
|
|
||||||
* @language_index: the indes of the language to list features for, or
|
|
||||||
* 0xffff, to list features for the default language of the script.
|
|
||||||
* @returns: a newly-allocated array containing the tags of the available
|
|
||||||
* features.
|
|
||||||
*
|
|
||||||
* Obtains the list of features for the given language of the given script.
|
|
||||||
**/
|
|
||||||
PangoOTTag *
|
|
||||||
pango_ot_info_list_features (PangoOTInfo *info,
|
|
||||||
PangoOTTableType table_type,
|
|
||||||
PangoOTTag tag,
|
|
||||||
guint script_index,
|
|
||||||
guint language_index)
|
|
||||||
{
|
|
||||||
PangoOTTag *result;
|
|
||||||
|
|
||||||
TTO_ScriptList *script_list;
|
|
||||||
TTO_FeatureList *feature_list;
|
|
||||||
TTO_Script *script;
|
|
||||||
TTO_LangSys *lang_sys;
|
|
||||||
|
|
||||||
int i;
|
|
||||||
|
|
||||||
g_return_val_if_fail (PANGO_IS_OT_INFO (info), NULL);
|
|
||||||
|
|
||||||
if (!get_tables (info, table_type, &script_list, &feature_list))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
g_return_val_if_fail (script_index < script_list->ScriptCount, NULL);
|
|
||||||
|
|
||||||
script = &script_list->ScriptRecord[script_index].Script;
|
|
||||||
|
|
||||||
if (language_index == 0xffff)
|
|
||||||
lang_sys = &script->DefaultLangSys;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (language_index < script->LangSysCount, NULL);
|
|
||||||
lang_sys = &script->LangSysRecord[language_index].LangSys;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = g_new (PangoOTTag, lang_sys->FeatureCount + 1);
|
|
||||||
|
|
||||||
for (i = 0; i < lang_sys->FeatureCount; i++)
|
|
||||||
{
|
|
||||||
FT_UShort index = lang_sys->FeatureIndex[i];
|
|
||||||
|
|
||||||
result[i] = feature_list->FeatureRecord[index].FeatureTag;
|
|
||||||
}
|
|
||||||
|
|
||||||
result[i] = 0;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,105 +0,0 @@
|
||||||
/* Pango
|
|
||||||
* pango-ot-private.h: Implementation details for Pango OpenType code
|
|
||||||
*
|
|
||||||
* Copyright (C) 2000 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __PANGO_OT_PRIVATE_H__
|
|
||||||
#define __PANGO_OT_PRIVATE_H__
|
|
||||||
|
|
||||||
#include <glib-object.h>
|
|
||||||
|
|
||||||
#include <pango/pango-ot.h>
|
|
||||||
#include "ftxopen.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
#define PANGO_TYPE_OT_INFO (pango_ot_info_get_type ())
|
|
||||||
#define PANGO_OT_INFO(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_OT_INFO, PangoOTInfo))
|
|
||||||
#define PANGO_OT_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_OT_INFO, PangoOTInfoClass))
|
|
||||||
#define PANGO_IS_OT_INFO(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_OT_INFO))
|
|
||||||
#define PANGO_IS_OT_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_OT_INFO))
|
|
||||||
#define PANGO_OT_INFO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_OT_INFO, PangoOTInfoClass))
|
|
||||||
|
|
||||||
typedef struct _PangoOTInfoClass PangoOTInfoClass;
|
|
||||||
|
|
||||||
struct _PangoOTInfo
|
|
||||||
{
|
|
||||||
GObject parent_instance;
|
|
||||||
|
|
||||||
guint loaded;
|
|
||||||
|
|
||||||
FT_Face face;
|
|
||||||
|
|
||||||
TTO_GSUB gsub;
|
|
||||||
TTO_GDEF gdef;
|
|
||||||
TTO_GPOS gpos;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _PangoOTInfoClass
|
|
||||||
{
|
|
||||||
GObjectClass parent_class;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define PANGO_TYPE_OT_RULESET (pango_ot_ruleset_get_type ())
|
|
||||||
#define PANGO_OT_RULESET(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_OT_RULESET, PangoOTRuleset))
|
|
||||||
#define PANGO_OT_RULESET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_OT_RULESET, PangoOTRulesetClass))f
|
|
||||||
#define PANGO_OT_IS_RULESET(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_OT_RULESET))
|
|
||||||
#define PANGO_OT_IS_RULESET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_OT_RULESET))
|
|
||||||
#define PANGO_OT_RULESET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_OT_RULESET, PangoOTRulesetClass))
|
|
||||||
|
|
||||||
typedef struct _PangoOTRulesetClass PangoOTRulesetClass;
|
|
||||||
|
|
||||||
struct _PangoOTRuleset
|
|
||||||
{
|
|
||||||
GObject parent_instance;
|
|
||||||
|
|
||||||
GArray *rules;
|
|
||||||
PangoOTInfo *info;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _PangoOTRulesetClass
|
|
||||||
{
|
|
||||||
GObjectClass parent_class;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _PangoOTBuffer
|
|
||||||
{
|
|
||||||
OTL_Buffer buffer;
|
|
||||||
PangoFcFont *font;
|
|
||||||
guint rtl : 1;
|
|
||||||
guint zero_width_marks : 1;
|
|
||||||
guint applied_gpos : 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
GType pango_ot_info_get_type (void);
|
|
||||||
|
|
||||||
TTO_GDEF pango_ot_info_get_gdef (PangoOTInfo *info);
|
|
||||||
TTO_GSUB pango_ot_info_get_gsub (PangoOTInfo *info);
|
|
||||||
TTO_GPOS pango_ot_info_get_gpos (PangoOTInfo *info);
|
|
||||||
|
|
||||||
GType pango_ot_ruleset_get_type (void);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* __PANGO_OT_PRIVATE_H__ */
|
|
|
@ -1,225 +0,0 @@
|
||||||
/* Pango
|
|
||||||
* pango-ot-ruleset.c: Shaping using OpenType features
|
|
||||||
*
|
|
||||||
* Copyright (C) 2000 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/pango-ot.h>
|
|
||||||
#include "pango-ot-private.h"
|
|
||||||
#include "../pango-utils.h"
|
|
||||||
|
|
||||||
typedef struct _PangoOTRule PangoOTRule;
|
|
||||||
|
|
||||||
struct _PangoOTRule
|
|
||||||
{
|
|
||||||
gulong property_bit;
|
|
||||||
FT_UShort feature_index;
|
|
||||||
guint table_type : 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void pango_ot_ruleset_class_init (GObjectClass *object_class);
|
|
||||||
static void pango_ot_ruleset_init (PangoOTRuleset *ruleset);
|
|
||||||
static void pango_ot_ruleset_finalize (GObject *object);
|
|
||||||
|
|
||||||
static GObjectClass *parent_class;
|
|
||||||
|
|
||||||
GType
|
|
||||||
pango_ot_ruleset_get_type (void)
|
|
||||||
{
|
|
||||||
static GType object_type = 0;
|
|
||||||
|
|
||||||
if (!object_type)
|
|
||||||
{
|
|
||||||
static const GTypeInfo object_info =
|
|
||||||
{
|
|
||||||
sizeof (PangoOTRulesetClass),
|
|
||||||
(GBaseInitFunc) NULL,
|
|
||||||
(GBaseFinalizeFunc) NULL,
|
|
||||||
(GClassInitFunc)pango_ot_ruleset_class_init,
|
|
||||||
NULL, /* class_finalize */
|
|
||||||
NULL, /* class_data */
|
|
||||||
sizeof (PangoOTRuleset),
|
|
||||||
0, /* n_preallocs */
|
|
||||||
(GInstanceInitFunc)pango_ot_ruleset_init,
|
|
||||||
NULL /* value_table */
|
|
||||||
};
|
|
||||||
|
|
||||||
object_type = g_type_register_static (G_TYPE_OBJECT,
|
|
||||||
I_("PangoOTRuleset"),
|
|
||||||
&object_info, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return object_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
pango_ot_ruleset_class_init (GObjectClass *object_class)
|
|
||||||
{
|
|
||||||
parent_class = g_type_class_peek_parent (object_class);
|
|
||||||
|
|
||||||
object_class->finalize = pango_ot_ruleset_finalize;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
pango_ot_ruleset_init (PangoOTRuleset *ruleset)
|
|
||||||
{
|
|
||||||
ruleset->rules = g_array_new (FALSE, FALSE, sizeof (PangoOTRule));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
pango_ot_ruleset_finalize (GObject *object)
|
|
||||||
{
|
|
||||||
PangoOTRuleset *ruleset = PANGO_OT_RULESET (object);
|
|
||||||
|
|
||||||
g_array_free (ruleset->rules, TRUE);
|
|
||||||
g_object_unref (ruleset->info);
|
|
||||||
|
|
||||||
parent_class->finalize (object);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* pango_ot_ruleset_new:
|
|
||||||
* @info: a #PangoOTInfo.
|
|
||||||
* @returns: a new #PangoOTRuleset.
|
|
||||||
*
|
|
||||||
* Creates a new #PangoOTRuleset for the given OpenType info.
|
|
||||||
**/
|
|
||||||
PangoOTRuleset *
|
|
||||||
pango_ot_ruleset_new (PangoOTInfo *info)
|
|
||||||
{
|
|
||||||
PangoOTRuleset *ruleset;
|
|
||||||
|
|
||||||
ruleset = g_object_new (PANGO_TYPE_OT_RULESET, NULL);
|
|
||||||
|
|
||||||
ruleset->info = g_object_ref (info);
|
|
||||||
|
|
||||||
return ruleset;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* pango_ot_ruleset_add_feature:
|
|
||||||
* @ruleset: a #PangoOTRuleset.
|
|
||||||
* @table_type: the table type to add a feature to.
|
|
||||||
* @feature_index: the index of the feature to add.
|
|
||||||
* @property_bit: the property bit to use for this feature. Used to identify
|
|
||||||
* the glyphs that this feature should be applied to.
|
|
||||||
*
|
|
||||||
* Adds a feature to the ruleset.
|
|
||||||
**/
|
|
||||||
void
|
|
||||||
pango_ot_ruleset_add_feature (PangoOTRuleset *ruleset,
|
|
||||||
PangoOTTableType table_type,
|
|
||||||
guint feature_index,
|
|
||||||
gulong property_bit)
|
|
||||||
{
|
|
||||||
PangoOTRule tmp_rule;
|
|
||||||
|
|
||||||
g_return_if_fail (PANGO_OT_IS_RULESET (ruleset));
|
|
||||||
|
|
||||||
tmp_rule.table_type = table_type;
|
|
||||||
tmp_rule.feature_index = feature_index;
|
|
||||||
tmp_rule.property_bit = property_bit;
|
|
||||||
|
|
||||||
g_array_append_val (ruleset->rules, tmp_rule);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* pango_ot_ruleset_substitute:
|
|
||||||
* @ruleset: a #PangoOTRuleset.
|
|
||||||
* @buffer: a #PangoOTBuffer.
|
|
||||||
*
|
|
||||||
* Since: 1.4
|
|
||||||
**/
|
|
||||||
void
|
|
||||||
pango_ot_ruleset_substitute (PangoOTRuleset *ruleset,
|
|
||||||
PangoOTBuffer *buffer)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
TTO_GSUB gsub = NULL;
|
|
||||||
|
|
||||||
g_return_if_fail (PANGO_OT_IS_RULESET (ruleset));
|
|
||||||
|
|
||||||
for (i = 0; i < ruleset->rules->len; i++)
|
|
||||||
{
|
|
||||||
PangoOTRule *rule = &g_array_index (ruleset->rules, PangoOTRule, i);
|
|
||||||
|
|
||||||
if (rule->table_type != PANGO_OT_TABLE_GSUB)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!gsub)
|
|
||||||
{
|
|
||||||
gsub = pango_ot_info_get_gsub (ruleset->info);
|
|
||||||
|
|
||||||
if (gsub)
|
|
||||||
TT_GSUB_Clear_Features (gsub);
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
TT_GSUB_Add_Feature (gsub, rule->feature_index, rule->property_bit);
|
|
||||||
}
|
|
||||||
|
|
||||||
TT_GSUB_Apply_String (gsub, buffer->buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* pango_ot_ruleset_position:
|
|
||||||
* @ruleset: a #PangoOTRuleset.
|
|
||||||
* @buffer: a #PangoOTBuffer.
|
|
||||||
*
|
|
||||||
* Since: 1.4
|
|
||||||
**/
|
|
||||||
void
|
|
||||||
pango_ot_ruleset_position (PangoOTRuleset *ruleset,
|
|
||||||
PangoOTBuffer *buffer)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
TTO_GPOS gpos = NULL;
|
|
||||||
|
|
||||||
g_return_if_fail (PANGO_OT_IS_RULESET (ruleset));
|
|
||||||
|
|
||||||
for (i = 0; i < ruleset->rules->len; i++)
|
|
||||||
{
|
|
||||||
PangoOTRule *rule = &g_array_index (ruleset->rules, PangoOTRule, i);
|
|
||||||
|
|
||||||
if (rule->table_type != PANGO_OT_TABLE_GPOS)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!gpos)
|
|
||||||
{
|
|
||||||
gpos = pango_ot_info_get_gpos (ruleset->info);
|
|
||||||
|
|
||||||
if (gpos)
|
|
||||||
TT_GPOS_Clear_Features (gpos);
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
TT_GPOS_Add_Feature (gpos, rule->feature_index, rule->property_bit);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TT_GPOS_Apply_String (ruleset->info->face, gpos, 0, buffer->buffer,
|
|
||||||
FALSE /* enable device-dependant values */,
|
|
||||||
buffer->rtl) == FT_Err_Ok)
|
|
||||||
buffer->applied_gpos = TRUE;
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue