diff options
author | Owen Taylor <otaylor@redhat.com> | 2003-07-25 16:11:17 +0000 |
---|---|---|
committer | Owen Taylor <otaylor@src.gnome.org> | 2003-07-25 16:11:17 +0000 |
commit | 18d5d28f70b60d27a6486f5dd6b787fe5ab06737 (patch) | |
tree | 2ff085ea65e7cec3728dcc3dcab8ac0ef1ef06c4 /modules | |
parent | 33cae257cb9e70035bc62d296166e1c1308a5e43 (diff) | |
download | pango-18d5d28f70b60d27a6486f5dd6b787fe5ab06737.tar.gz |
Port pre-base-mantra fixup code from ICU, as needed for Tamil and
Fri Jul 25 12:07:21 2003 Owen Taylor <otaylor@redhat.com>
* modules/indic/mprefixups.[ch] modules/indic/indic-ot.[ch]
modules/indic/indic-fc.c: Port pre-base-mantra
fixup code from ICU, as needed for Tamil and Malayalam.
(Based on patch from Sivaraj Doddannan, #111166)
Diffstat (limited to 'modules')
-rw-r--r-- | modules/indic/Makefile.am | 8 | ||||
-rw-r--r-- | modules/indic/indic-fc.c | 17 | ||||
-rw-r--r-- | modules/indic/indic-ot.c | 37 | ||||
-rw-r--r-- | modules/indic/indic-ot.h | 3 | ||||
-rw-r--r-- | modules/indic/mprefixups.c | 125 | ||||
-rw-r--r-- | modules/indic/mprefixups.h | 50 |
6 files changed, 227 insertions, 13 deletions
diff --git a/modules/indic/Makefile.am b/modules/indic/Makefile.am index 6ed2bad0..2501d6f4 100644 --- a/modules/indic/Makefile.am +++ b/modules/indic/Makefile.am @@ -98,7 +98,9 @@ xft_sources = \ indic-fc.c \ indic-ot-class-tables.c \ indic-ot.c \ - indic-ot.h + indic-ot.h \ + mprefixups.c \ + mprefixups.h pango_indic_xft_la_LDFLAGS = -export-dynamic -avoid-version -module pango_indic_xft_la_LIBADD = $(pangoxftlibs) @@ -121,7 +123,9 @@ ft2_sources = \ indic-fc.c \ indic-ot-class-tables.c \ indic-ot.c \ - indic-ot.h + indic-ot.h \ + mprefixups.c \ + mprefixups.h pango_indic_ft2_la_LDFLAGS = -export-dynamic -avoid-version -module $(no_undefined) pango_indic_ft2_la_LIBADD = $(pangoft2libs) diff --git a/modules/indic/indic-fc.c b/modules/indic/indic-fc.c index 3f905e5e..44832304 100644 --- a/modules/indic/indic-fc.c +++ b/modules/indic/indic-fc.c @@ -313,6 +313,7 @@ indic_engine_shape (PangoFont *font, PangoEngineShapeIndic *indic_shape_engine = NULL; PangoIndicInfo *indic_info = NULL; PangoFcFont *fc_font; + MPreFixups *mprefixups; g_return_if_fail (font != NULL); g_return_if_fail (text != NULL); @@ -332,14 +333,15 @@ indic_engine_shape (PangoFont *font, indic_info = indic_shape_engine->indicInfo; wc_in = expand_text (text, length, &utf8_offsets, &n_chars); - n_glyphs = indic_ot_reorder (wc_in, utf8_offsets, n_chars, indic_info->classTable, NULL, NULL, NULL); - + + n_glyphs = indic_ot_reorder (wc_in, utf8_offsets, n_chars, indic_info->classTable, NULL, NULL, NULL, NULL); + wc_out = g_new (gunichar, n_glyphs); indices = g_new (glong, n_glyphs); tags = g_new (gulong, n_glyphs); - n_glyphs = indic_ot_reorder (wc_in, utf8_offsets, n_chars, indic_info->classTable, wc_out, indices, tags); - + n_glyphs = indic_ot_reorder (wc_in, utf8_offsets, n_chars, indic_info->classTable, wc_out, indices, tags, &mprefixups); + pango_glyph_string_set_size (glyphs, n_glyphs); set_glyphs(font, face, wc_out, n_glyphs, glyphs); @@ -350,6 +352,13 @@ indic_engine_shape (PangoFont *font, pango_ot_ruleset_shape (gsub_ruleset, glyphs, tags); } + /* Fix pre-modifiers for some scripts before base consonant */ + if (mprefixups) + { + indic_mprefixups_apply (mprefixups, glyphs); + indic_mprefixups_free (mprefixups); + } + /* apply default positioning */ for (i = 0; i < glyphs->num_glyphs; i += 1) { diff --git a/modules/indic/indic-ot.c b/modules/indic/indic-ot.c index 99fdff4d..ca05ae30 100644 --- a/modules/indic/indic-ot.c +++ b/modules/indic/indic-ot.c @@ -7,7 +7,7 @@ */ #include "indic-ot.h" - +#include "mprefixups.h" /* * FIXME: should the IndicOutput stuff be moved * to a spereate .h and .c file just to keep the @@ -29,13 +29,16 @@ struct _Output gunichar fMabove; gunichar fMpost; gunichar fLengthMark; - glong fMatraIndex; + glong fMatraIndex; gulong fMatraTags; + glong fMPreOutIndex; + + MPreFixups *fMPreFixups; }; typedef struct _Output Output; -static void initOutput(Output *output, const glong *originalOffsets, gunichar *outChars, glong *charIndices, gulong *charTags) +static void initOutput(Output *output, const glong *originalOffsets, gunichar *outChars, glong *charIndices, gulong *charTags, MPreFixups *mpreFixups) { output->fOriginalOffsets = originalOffsets; @@ -47,6 +50,9 @@ static void initOutput(Output *output, const glong *originalOffsets, gunichar *o output->fMatraTags = 0; output->fMpre = output->fMbelow = output->fMabove = output->fMpost = output->fLengthMark = 0; + + output->fMPreOutIndex = -1; + output->fMPreFixups = mpreFixups; } static void saveMatra(Output *output, gunichar matra, IndicOTCharClass matraClass) @@ -70,6 +76,7 @@ static void noteMatra(Output *output, const IndicOTClassTable *classTable, gunic IndicOTCharClass matraClass = indic_ot_get_char_class(classTable, matra); output->fMpre = output->fMbelow = output->fMabove = output->fMpost = output->fLengthMark = 0; + output->fMPreOutIndex = -1; output->fMatraIndex = matraIndex; output->fMatraTags = matraTags; @@ -90,6 +97,12 @@ static void noteMatra(Output *output, const IndicOTClassTable *classTable, gunic } } +static void noteBaseConsonant(Output *output) +{ + if (output->fMPreFixups && output->fMPreOutIndex >= 0) { + indic_mprefixups_add(output->fMPreFixups, output->fOutIndex, output->fMPreOutIndex); + } +} static void writeChar(Output *output, gunichar ch, guint32 charIndex, gulong charTags) { if (output->fOutChars != NULL) { @@ -104,6 +117,7 @@ static void writeChar(Output *output, gunichar ch, guint32 charIndex, gulong cha static void writeMpre(Output *output) { if (output->fMpre != 0) { + output->fMPreOutIndex = output->fOutIndex; writeChar(output, output->fMpre, output->fMatraIndex, output->fMatraTags); } } @@ -144,12 +158,17 @@ static glong getOutputIndex(Output *output) #define false 0 #define true 1 -glong indic_ot_reorder(const gunichar *chars, const glong *utf8_offsets, glong char_count, const IndicOTClassTable *class_table, gunichar *out_chars, glong *char_indices, gulong *char_tags) +glong indic_ot_reorder(const gunichar *chars, const glong *utf8_offsets, glong char_count, const IndicOTClassTable *class_table, gunichar *out_chars, glong *char_indices, gulong *char_tags, MPreFixups **outMPreFixups) { + MPreFixups *mpreFixups = NULL; Output output; glong i, prev = 0; - initOutput(&output, utf8_offsets, out_chars, char_indices, char_tags); + if (outMPreFixups && (class_table->scriptFlags & SF_MPRE_FIXUP)) { + mpreFixups = indic_mprefixups_new (char_count); + } + + initOutput(&output, utf8_offsets, out_chars, char_indices, char_tags, mpreFixups); while (prev < char_count) { glong syllable = indic_ot_find_syllable(class_table, chars, prev, char_count); @@ -306,6 +325,9 @@ glong indic_ot_reorder(const gunichar *chars, const glong *utf8_offsets, glong c } } + /* note the base consonant for post-GSUB fixups */ + noteBaseConsonant(&output); + /* write base consonant */ for (i = baseConsonant; i < bcSpan; i += 1) { writeChar(&output, chars[i], /*i*/ prev, nukt_p); @@ -401,6 +423,9 @@ glong indic_ot_reorder(const gunichar *chars, const glong *utf8_offsets, glong c prev = syllable; } + if (mpreFixups) { + *outMPreFixups = mpreFixups; + } + return getOutputIndex(&output); } - diff --git a/modules/indic/indic-ot.h b/modules/indic/indic-ot.h index 2e831f9a..caf229d4 100644 --- a/modules/indic/indic-ot.h +++ b/modules/indic/indic-ot.h @@ -12,6 +12,7 @@ #include <freetype/freetype.h> #include <pango/pango-glyph.h> #include <pango/pango-types.h> +#include "mprefixups.h" G_BEGIN_DECLS @@ -241,7 +242,7 @@ gboolean indic_ot_has_below_base_form(const IndicOTClassTable *class_table, guni glong indic_ot_find_syllable(const IndicOTClassTable *class_table, const gunichar *chars, glong prev, glong char_count); -glong indic_ot_reorder(const gunichar *chars, const glong *utf8_offsets, glong char_count, const IndicOTClassTable *class_table, gunichar *out_chars, glong *char_indices, gulong *char_tags); +glong indic_ot_reorder(const gunichar *chars, const glong *utf8_offsets, glong char_count, const IndicOTClassTable *class_table, gunichar *out_chars, glong *char_indices, gulong *char_tags, MPreFixups **outMPreFixups); #endif /* PANGO_ENABLE_ENGINE */ diff --git a/modules/indic/mprefixups.c b/modules/indic/mprefixups.c new file mode 100644 index 00000000..29b126d0 --- /dev/null +++ b/modules/indic/mprefixups.c @@ -0,0 +1,125 @@ +/* + * mprefixups.h: Handle left matra placement + * + * Author: Sivaraj Doddannan + * Ported from IBM's ICU engine. Original copyright: + * (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved + * + * 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 <pango/pango-types.h> +#include "mprefixups.h" +#include <stdio.h> + +struct _FixupData +{ + glong fBaseIndex; + glong fMPreIndex; +}; + +MPreFixups *indic_mprefixups_new(glong char_count) +{ + MPreFixups *mprefixups = g_new (MPreFixups, 1); + mprefixups->fFixupCount = 0; + mprefixups->fFixupData = g_new (FixupData, char_count); + + return mprefixups; +} + +void indic_mprefixups_free (MPreFixups *mprefixups) +{ + g_free (mprefixups->fFixupData); + g_free (mprefixups); +} + +void indic_mprefixups_add (MPreFixups *mprefixups, glong baseIndex, glong mpreIndex) +{ + /* NOTE: don't add the fixup data if the mpre is right + * before the base consonant glyph. + */ + if (baseIndex - mpreIndex > 1) { + mprefixups->fFixupData[mprefixups->fFixupCount].fBaseIndex = baseIndex; + mprefixups->fFixupData[mprefixups->fFixupCount].fMPreIndex = mpreIndex; + + mprefixups->fFixupCount += 1; + } +} + +void indic_mprefixups_apply(MPreFixups *mprefixups, PangoGlyphString *glyphs) +{ + glong fixup; + + for (fixup = 0; fixup < mprefixups->fFixupCount; fixup += 1) { + glong baseIndex = mprefixups->fFixupData[fixup].fBaseIndex; + glong mpreIndex = mprefixups->fFixupData[fixup].fMPreIndex; + glong mpreLimit, mpreCount, moveCount, mpreDest; + glong i; + PangoGlyph *mpreSave; + int *clusterSave; + + /* determine post GSUB location of baseIndex and mpreIndex */ + gboolean no_base = TRUE; + for (i = 0; i<glyphs->num_glyphs; i++) { + if (glyphs->log_clusters[i] == baseIndex) { + baseIndex = i + 1; + no_base = FALSE; + } + if (glyphs->log_clusters[i] == mpreIndex) + mpreIndex = i; + } + if (no_base) + break; + + mpreLimit = mpreIndex + 1; + + while (glyphs->glyphs[baseIndex].glyph == 0xFFFF || glyphs->glyphs[baseIndex].glyph == 0xFFFE) { + baseIndex -= 1; + } + + while (glyphs->glyphs[mpreIndex].glyph == 0xFFFF || glyphs->glyphs[mpreIndex].glyph == 0xFFFE) { + mpreLimit += 1; + } + + if (mpreLimit == baseIndex) { + continue; + } + + mpreCount = mpreLimit - mpreIndex; + moveCount = baseIndex - mpreLimit; + mpreDest = baseIndex - mpreCount - 1; + + mpreSave = g_new (PangoGlyph, mpreCount); + clusterSave = g_new (int, mpreCount); + + for (i = 0; i < mpreCount; i += 1) { + mpreSave[i] = glyphs->glyphs[mpreIndex + i].glyph; + clusterSave[i] = glyphs->log_clusters[mpreIndex + i]; + } + + for (i = 0; i < moveCount; i += 1) { + glyphs->glyphs[mpreIndex + i].glyph = glyphs->glyphs[mpreLimit + i].glyph; + glyphs->log_clusters[mpreIndex + i] = glyphs->log_clusters[mpreLimit + i]; + } + + for (i = 0; i < mpreCount; i += 1) { + glyphs->glyphs[mpreDest + i].glyph = mpreSave[i]; + glyphs->log_clusters[mpreDest + i] = clusterSave[i]; + } + + g_free(mpreSave); + } +} diff --git a/modules/indic/mprefixups.h b/modules/indic/mprefixups.h new file mode 100644 index 00000000..4bab8cac --- /dev/null +++ b/modules/indic/mprefixups.h @@ -0,0 +1,50 @@ +/* + * mprefixups.c: Handle left matra placement + * + * Author: Sivaraj Doddannan + * Ported from IBM's ICU engine. Original copyright: + * (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved + * + * 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 __MPREFIXUPS_H +#define __MPREFIXUPS_H + +#include <pango/pango-types.h> +#include <pango/pango-glyph.h> + +G_BEGIN_DECLS + +typedef struct _FixupData FixupData; + +struct _MPreFixups { + glong fFixupCount; + FixupData *fFixupData; +}; + +typedef struct _MPreFixups MPreFixups; + +MPreFixups *indic_mprefixups_new(glong char_count); +void indic_mprefixups_free(MPreFixups *mprefixups); +void indic_mprefixups_add(MPreFixups *mprefixups, glong baseIndex, glong mpreIndex); +void indic_mprefixups_apply(MPreFixups *mprefixups, PangoGlyphString *glyphs); + + +G_END_DECLS + +#endif + |