Since Xft may only be available statically without shlib deps, check for
Tue Dec 19 22:47:16 2000 Owen Taylor <otaylor@redhat.com>
* configure.in pango-config.in pangoxft.pc.in
modules/basic/Makefile.am: Since Xft may only be available
statically without shlib deps, check for FreeType libs explicitly
and include them when linking, otherwise things won't work. Also,
define FREETYPE_CFLAGS from freetype-config --cflags.
* modules/basic/basic-xft.c pango/pangoxft-font{,map}.c: Fool
Xft into not converting glyph indices by loading the
face unencoded then calling FT_Set_Charmap ourselves.
* pango/Makefile.am pango/pango-ot.h pango/opentype/* :Add start
of opentype handling - most of the actually meat of the code here
is the OpenType layout code from FreeType 1 ported to freetype2
and adapted slighlty for our purposes. Also, includes a
incomplete OpenType-table-dumping code useful for figuring
out what is going on.
* pango/pangoxft.h pango/pangoxft-font.h: Add calls for
getting FT_Face and PangoOTInfo from PangoXftFont.
* modules/arabic/{Makefile.am,arabic-ot.[ch],arabic-xft.c}:
Initial support for rendering Arabic with OpenType fonts.
diff --git a/src/disasm.c b/src/disasm.c
new file mode 100644
index 0000000..2e064ec
--- /dev/null
+++ b/src/disasm.c
@@ -0,0 +1,317 @@
+/* Pango
+ * disasm.c: Dump OpenType layout tables
+ *
+ * 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 <stdarg.h>
+
+#include "disasm.h"
+
+#define DUMP(args...) dump (stream, indent, args)
+#define DUMP_FINT(strct,fld) dump (stream, indent, "<" #fld ">%d</" #fld ">\n", (strct)->fld)
+#define DUMP_FUINT(strct,fld) dump (stream, indent, "<" #fld ">%u</" #fld ">\n", (strct)->fld)
+#define DUMP_FGLYPH(strct,fld) dump (stream, indent, "<" #fld ">%#4x</" #fld ">\n", (strct)->fld)
+
+#define DEF_DUMP(type) static void Dump_ ## type (TTO_ ## type *type, FILE *stream, int indent, FT_Bool is_gsub)
+#define RECURSE(name, type, val) do { DUMP ("<" #name ">\n"); Dump_ ## type (val, stream, indent + 1, is_gsub); DUMP ("</" #name ">\n"); } while (0)
+
+static void
+do_indent (FILE *stream, int indent)
+{
+ int i;
+
+ for (i = 0; i < indent * 3; i++)
+ fputc (' ', stream);
+}
+
+static void
+dump (FILE *stream, int indent, const char *format, ...)
+{
+ va_list list;
+
+ do_indent (stream, indent);
+
+ va_start (list, format);
+ vfprintf (stream, format, list);
+ va_end (list);
+}
+
+static void
+Print_Tag (FT_ULong tag, FILE *stream)
+{
+ fprintf (stream, "%c%c%c%c",
+ (unsigned char)(tag >> 24),
+ (unsigned char)((tag & 0xff0000) >> 16),
+ (unsigned char)((tag & 0xff00) >> 8),
+ (unsigned char)(tag & 0xff));
+}
+
+DEF_DUMP (LangSys)
+{
+ int i;
+
+ DUMP_FUINT (LangSys, LookupOrderOffset);
+ DUMP_FUINT (LangSys, ReqFeatureIndex);
+ DUMP_FUINT (LangSys, FeatureCount);
+
+ for (i=0; i < LangSys->FeatureCount; i++)
+ DUMP("<FeatureIndex>%d</FeatureIndex>\n", LangSys->FeatureIndex[i]);
+}
+
+DEF_DUMP (Script)
+{
+ int i;
+
+ RECURSE (DefaultLangSys, LangSys, &Script->DefaultLangSys);
+
+ DUMP_FUINT (Script, LangSysCount);
+
+ for (i=0; i < Script->LangSysCount; i++)
+ {
+ do_indent (stream, indent);
+ fprintf (stream, "<LangSysTag>");
+ Print_Tag (Script->LangSysRecord[i].LangSysTag, stream);
+ fprintf (stream, "</LangSysTag>\n");
+ RECURSE (LangSys, LangSys, &Script->LangSysRecord[i].LangSys);
+ }
+}
+
+DEF_DUMP (ScriptList)
+{
+ int i;
+
+ DUMP_FUINT (ScriptList, ScriptCount);
+
+ for (i=0; i < ScriptList->ScriptCount; i++)
+ {
+ do_indent (stream, indent);
+ fprintf (stream, "<ScriptTag>");
+ Print_Tag (ScriptList->ScriptRecord[i].ScriptTag, stream);
+ fprintf (stream, "</ScriptTag>\n");
+ RECURSE (Script, Script, &ScriptList->ScriptRecord[i].Script);
+ }
+}
+
+DEF_DUMP (Feature)
+{
+ int i;
+
+ DUMP_FUINT (Feature, FeatureParams);
+ DUMP_FUINT (Feature, LookupListCount);
+
+ for (i=0; i < Feature->LookupListCount; i++)
+ DUMP("<LookupIndex>%d</LookupIndex>\n", Feature->LookupListIndex[i]);
+}
+
+DEF_DUMP (FeatureList)
+{
+ int i;
+
+ DUMP_FUINT (FeatureList, FeatureCount);
+
+ for (i=0; i < FeatureList->FeatureCount; i++)
+ {
+ do_indent (stream, indent);
+ fprintf (stream, "<FeatureTag>");
+ Print_Tag (FeatureList->FeatureRecord[i].FeatureTag, stream);
+ fprintf (stream, "</FeatureTag>\n");
+ RECURSE (Feature, Feature, &FeatureList->FeatureRecord[i].Feature);
+ }
+}
+
+DEF_DUMP (Coverage)
+{
+ DUMP_FUINT (Coverage, CoverageFormat);
+
+ if (Coverage->CoverageFormat == 1)
+ {
+ int i;
+ DUMP_FUINT (&Coverage->cf.cf1, GlyphCount);
+
+ for (i = 0; i < Coverage->cf.cf1.GlyphCount; i++)
+ DUMP("<Glyph>%#4x</Glyph> <!-- %d -->\n", Coverage->cf.cf1.GlyphArray[i], i);
+ }
+ else
+ {
+ }
+}
+
+static void
+Dump_GSUB_Lookup_Single (TTO_SubTable *subtable, FILE *stream, int indent, FT_Bool is_gsub)
+{
+ TTO_SingleSubst *SingleSubst = &subtable->st.gsub.single;
+
+ DUMP_FUINT (SingleSubst, SubstFormat);
+ RECURSE (Coverage, Coverage, &SingleSubst->Coverage);
+
+ if (SingleSubst->SubstFormat == 1)
+ {
+ DUMP_FINT (&SingleSubst->ssf.ssf1, DeltaGlyphID);
+ }
+ else
+ {
+ int i;
+
+ DUMP_FINT (&SingleSubst->ssf.ssf2, GlyphCount);
+ for (i=0; i < SingleSubst->ssf.ssf2.GlyphCount; i++)
+ DUMP("<Substitute>%#4x</Substitute> <!-- %d -->\n", SingleSubst->ssf.ssf2.Substitute[i], i);
+ }
+}
+
+DEF_DUMP (Ligature)
+{
+ int i;
+
+ DUMP_FGLYPH (Ligature, LigGlyph);
+ DUMP_FUINT (Ligature, ComponentCount);
+
+ for (i=0; i < Ligature->ComponentCount - 1; i++)
+ DUMP("<Component>%#4x</Component>\n", Ligature->Component[i]);
+}
+
+DEF_DUMP (LigatureSet)
+{
+ int i;
+
+ DUMP_FUINT (LigatureSet, LigatureCount);
+
+ for (i=0; i < LigatureSet->LigatureCount; i++)
+ RECURSE (Ligature, Ligature, &LigatureSet->Ligature[i]);
+}
+
+static void
+Dump_GSUB_Lookup_Ligature (TTO_SubTable *subtable, FILE *stream, int indent, FT_Bool is_gsub)
+{
+ int i;
+ TTO_LigatureSubst *LigatureSubst = &subtable->st.gsub.ligature;
+
+ DUMP_FUINT (LigatureSubst, SubstFormat);
+ RECURSE (Coverage, Coverage, &LigatureSubst->Coverage);
+
+ DUMP_FUINT (LigatureSubst, LigatureSetCount);
+
+ for (i=0; i < LigatureSubst->LigatureSetCount; i++)
+ RECURSE (LigatureSet, LigatureSet, &LigatureSubst->LigatureSet[i]);
+}
+
+DEF_DUMP (Lookup)
+{
+ int i;
+ const char *lookup_name = NULL;
+ void (*lookup_func) (TTO_SubTable *subtable, FILE *stream, int indent, FT_Bool is_gsub) = NULL;
+
+ if (is_gsub)
+ {
+ switch (Lookup->LookupType)
+ {
+ case GSUB_LOOKUP_SINGLE:
+ lookup_name = "SINGLE";
+ lookup_func = Dump_GSUB_Lookup_Single;
+ break;
+ case GSUB_LOOKUP_MULTIPLE:
+ lookup_name = "MULTIPLE";
+ break;
+ case GSUB_LOOKUP_ALTERNATE:
+ lookup_name = "ALTERNATE";
+ break;
+ case GSUB_LOOKUP_LIGATURE:
+ lookup_name = "LIGATURE";
+ lookup_func = Dump_GSUB_Lookup_Ligature;
+ break;
+ case GSUB_LOOKUP_CONTEXT:
+ lookup_name = "CONTEXT";
+ break;
+ case GSUB_LOOKUP_CHAIN:
+ lookup_name = "CHAIN";
+ break;
+ }
+ }
+ else
+ {
+ switch (Lookup->LookupType)
+ {
+ case GPOS_LOOKUP_SINGLE:
+ lookup_name = "SINGLE";
+ break;
+ case GPOS_LOOKUP_PAIR:
+ lookup_name = "PAIR";
+ break;
+ case GPOS_LOOKUP_CURSIVE:
+ lookup_name = "CURSIVE";
+ break;
+ case GPOS_LOOKUP_MARKBASE:
+ lookup_name = "MARKBASE";
+ break;
+ case GPOS_LOOKUP_MARKLIG:
+ lookup_name = "MARKLIG";
+ break;
+ case GPOS_LOOKUP_MARKMARK:
+ lookup_name = "MARKMARK";
+ break;
+ case GPOS_LOOKUP_CONTEXT:
+ lookup_name = "CONTEXT";
+ break;
+ case GPOS_LOOKUP_CHAIN:
+ lookup_name = "CHAIN";
+ break;
+ }
+ }
+
+ DUMP("<LookupType>%s</LookupType>\n", lookup_name);
+
+ for (i=0; i < Lookup->SubTableCount; i++)
+ {
+ DUMP ("<Subtable>\n");
+ if (lookup_func)
+ (*lookup_func) (&Lookup->SubTable[i], stream, indent + 1, is_gsub);
+ DUMP ("</Subtable>\n");
+ }
+}
+
+DEF_DUMP (LookupList)
+{
+ int i;
+
+ DUMP_FUINT (LookupList, LookupCount);
+
+ for (i=0; i < LookupList->LookupCount; i++)
+ RECURSE (Lookup, Lookup, &LookupList->Lookup[i]);
+}
+
+void
+TT_Dump_GSUB_Table (TTO_GSUB gsub, FILE *stream)
+{
+ int indent = 0;
+ FT_Bool is_gsub = 1;
+
+ RECURSE (ScriptList, ScriptList, &gsub->ScriptList);
+ RECURSE (FeatureList, FeatureList, &gsub->FeatureList);
+ RECURSE (LookupList, LookupList, &gsub->LookupList);
+}
+
+void
+TT_Dump_GPOS_Table (TTO_GPOS gpos, FILE *stream)
+{
+ int indent = 0;
+ FT_Bool is_gsub = 0;
+
+ RECURSE (ScriptList, ScriptList, &gpos->ScriptList);
+ RECURSE (FeatureList, FeatureList, &gpos->FeatureList);
+ RECURSE (LookupList, LookupList, &gpos->LookupList);
+}