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.
This commit is contained in:
Owen Taylor 2000-12-20 04:41:36 +00:00 committed by Owen Taylor
commit 80a1582913
19 changed files with 17151 additions and 0 deletions

8
src/.cvsignore Normal file
View File

@ -0,0 +1,8 @@
Makefile.in
Makefile
makefile.mingw
ottest
*.lo
*.la
.deps
.libs

158
src/FT-license.txt Normal file
View File

@ -0,0 +1,158 @@
The FreeType Project LICENSE
----------------------------
Copyright 1996-1999 by
David Turner, Robert Wilhelm, and Werner Lemberg
Introduction
============
The FreeType Project is distributed in several archive packages;
some of them may contain, in addition to the FreeType font engine,
various tools and contributions which rely on, or relate to, the
FreeType Project.
This license applies to all files found in such packages, and
which do not fall under their own explicit license. The license
affects thus the FreeType font engine, the test programs,
documentation and makefiles, at the very least.
This license was inspired by the BSD, Artistic, and IJG
(Independent JPEG Group) licenses, which all encourage inclusion
and use of free software in commercial and freeware products
alike. As a consequence, its main points are that:
o We don't promise that this software works. However, we are be
interested in any kind of bug reports. (`as is' distribution)
o You can use this software for whatever you want, in parts or
full form, without having to pay us. (`royalty-free' usage)
o You may not pretend that you wrote this software. If you use
it, or only parts of it, in a program, you must acknowledge
somewhere in your documentation that you've used the FreeType
code. (`credits')
We specifically permit and encourage the inclusion of this
software, with or without modifications, in commercial products,
provided that all warranty or liability claims are assumed by the
product vendor.
Legal Terms
===========
0. Definitions
--------------
Throughout this license, the terms `package', `FreeType Project',
and `FreeType archive' refer to the set of files originally
distributed by the authors (David Turner, Robert Wilhelm, and
Werner Lemberg) as the `FreeType project', be they named as alpha,
beta or final release.
`You' refers to the licensee, or person using the project, where
`using' is a generic term including compiling the project's source
code as well as linking it to form a `program' or `executable'.
This program is referred to as `a program using the FreeType
engine'.
This license applies to all files distributed in the original
FreeType archive, including all source code, binaries and
documentation, unless otherwise stated in the file in its
original, unmodified form as distributed in the original archive.
If you are unsure whether or not a particular file is covered by
this license, you must contact us to verify this.
The FreeType project is copyright (C) 1996-1999 by David Turner,
Robert Wilhelm, and Werner Lemberg. All rights reserved except as
specified below.
1. No Warranty
--------------
THE FREETYPE ARCHIVE IS PROVIDED `AS IS' WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. IN NO EVENT WILL ANY OF THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY DAMAGES CAUSED BY THE USE OR THE INABILITY TO
USE, OF THE FREETYPE PROJECT.
As you have not signed this license, you are not required to
accept it. However, as the FreeType project is copyrighted
material, only this license, or another one contracted with the
authors, grants you the right to use, distribute, and modify it.
Therefore, by using, distributing, or modifying the FreeType
project, you indicate that you understand and accept all the terms
of this license.
2. Redistribution
-----------------
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
o Redistribution of source code must retain this license file
(`licence.txt') unaltered; any additions, deletions or changes
to the original files must be clearly indicated in
accompanying documentation. The copyright notices of the
unaltered, original files must be preserved in all copies of
source files.
o Redistribution in binary form must provide a disclaimer that
states that the software is based in part of the work of the
FreeType Team, in the distribution documentation. We also
encourage you to put an URL to the FreeType web page in your
documentation, though this isn't mandatory.
These conditions apply to any software derived from or based on
the FreeType code, not just the unmodified files. If you use our
work, you must acknowledge us. However, no fee need be paid to
us.
3. Advertising
--------------
The names of FreeType's authors and contributors may not be used
to endorse or promote products derived from this software without
specific prior written permission.
We suggest, but do not require, that you use one or more of the
following phrases to refer to this software in your documentation
or advertising materials: `FreeType Project', `FreeType Engine',
`FreeType library', or `FreeType Distribution'.
4. Contacts
-----------
There are two mailing lists related to FreeType:
o freetype@freetype.org
Discusses general use and applications of FreeType, as well as
future and wanted additions to the library and distribution.
If you are looking for support, start in this list if you
haven't found anything to help you in the documentation.
o devel@freetype.org
Discusses bugs, as well as engine internals, design issues,
specific licenses, porting, etc.
o http://www.freetype.org
Holds the current FreeType web page, which will allow you to
download our latest development version and read online
documentation.
You can also contact us individually at:
David Turner <david.turner@freetype.org>
Robert Wilhelm <robert.wilhelm@freetype.org>
Werner Lemberg <werner.lemberg@freetype.org>
--- end of license.txt ---

39
src/Makefile.am Normal file
View File

@ -0,0 +1,39 @@
## Process this file with automake to produce Makefile.in
INCLUDES = \
-DSYSCONFDIR=\"$(sysconfdir)\" \
-DLIBDIR=\"$(libdir)\" \
$(FREETYPE_CFLAGS) \
$(X_CFLAGS) \
-I$(top_srcdir)
LDADDS = @STRIP_BEGIN@ \
@x_ldflags@ \
@x_libs@ \
@GLIB_LIBS@ \
-lm \
@STRIP_END@
noinst_LTLIBRARIES = libpango-ot.la
libpango_ot_la_SOURCES = \
ftxopen.c \
ftxgdef.c \
ftxgpos.c \
pango-ot-info.c \
pango-ot-ruleset.c \
ftxgsub.c
noinst_PROGRAMS = ottest
ottest_SOURCES = \
ottest.c \
disasm.c \
disasm.h
ottest_LDADD = \
libpango-ot.la \
$(FREETYPE_LIBS)
EXTRA_DIST = \
README

36
src/README Normal file
View File

@ -0,0 +1,36 @@
This directory includes code for using OpenType Layout tables from
OpenType fonts with FreeType and
The table reading code in:
ftxopen.[ch]
ftxopenf.h
ftxgdef.[ch]
ftxgpos.[ch]
ftxgdef.[ch]
Is derived from the OpenType code in FreeType-1.x, ported to FreeType2.
(This code has been abandoned for FreeType2, but until something better
comes along, should serve our purposes.)
This code should be left following the FreeType indentation style and
coding conventions.
In addition to porting to FreeType-2, it has been modified to
add support for PangoGlyphString's log_clusters, and in various
other ways. Bug reports on these files should be sent to
gtk-i18n-list@gtk.org, NOT to the freetype maintainers.
The license for these files is in the file freetype-license.txt.
Most of the additional files in this directory implement a high-level
interface to this that follows Pango conventions and integrates with
Pango.
disasm.[ch] is a partial dumper for OpenType layout tables useful
in figuring out what is going on. Please extend to cover additional
parts of the tables as you encounter fonts using them.
Owen Taylor
17 December 2000

317
src/disasm.c Normal file
View File

@ -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);
}

26
src/disasm.h Normal file
View File

@ -0,0 +1,26 @@
/* Pango
* disasm.h: 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 <stdio.h>
#include "ftxopen.h"
void TT_Dump_GSUB_Table (TTO_GSUB gsub, FILE *stream);
void TT_Dump_GPOS_Table (TTO_GPOS gpos, FILE *stream);

1155
src/ftxgdef.c Normal file

File diff suppressed because it is too large Load Diff

220
src/ftxgdef.h Normal file
View File

@ -0,0 +1,220 @@
/*******************************************************************
*
* ftxgdef.h
*
* TrueType Open GDEF table support
*
* Copyright 1996-2000 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used
* modified and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
******************************************************************/
#ifndef FTXOPEN_H
#error "Don't include this file! Use ftxopen.h instead."
#endif
#ifndef FTXGDEF_H
#define FTXGDEF_H
#ifdef __cplusplus
extern "C" {
#endif
#define TTO_Err_Invalid_GDEF_SubTable_Format 0x1030
#define TTO_Err_Invalid_GDEF_SubTable 0x1031
/* GDEF glyph classes */
#define UNCLASSIFIED_GLYPH 0
#define SIMPLE_GLYPH 1
#define LIGATURE_GLYPH 2
#define MARK_GLYPH 3
#define COMPONENT_GLYPH 4
/* GDEF glyph properties, corresponding to class values 1-4. Note that
TTO_COMPONENT has no corresponding flag in the LookupFlag field. */
#define TTO_BASE_GLYPH 0x0002
#define TTO_LIGATURE 0x0004
#define TTO_MARK 0x0008
#define TTO_COMPONENT 0x0010
/* Attachment related structures */
struct TTO_AttachPoint_
{
FT_UShort PointCount; /* size of the PointIndex array */
FT_UShort* PointIndex; /* array of contour points */
};
typedef struct TTO_AttachPoint_ TTO_AttachPoint;
struct TTO_AttachList_
{
FT_Bool loaded;
TTO_Coverage Coverage; /* Coverage table */
FT_UShort GlyphCount; /* number of glyphs with
attachments */
TTO_AttachPoint* AttachPoint; /* array of AttachPoint tables */
};
typedef struct TTO_AttachList_ TTO_AttachList;
/* Ligature Caret related structures */
struct TTO_CaretValueFormat1_
{
FT_Short Coordinate; /* x or y value (in design units) */
};
typedef struct TTO_CaretValueFormat1_ TTO_CaretValueFormat1;
struct TTO_CaretValueFormat2_
{
FT_UShort CaretValuePoint; /* contour point index on glyph */
};
typedef struct TTO_CaretValueFormat2_ TTO_CaretValueFormat2;
struct TTO_CaretValueFormat3_
{
FT_Short Coordinate; /* x or y value (in design units) */
TTO_Device Device; /* Device table for x or y value */
};
typedef struct TTO_CaretValueFormat3_ TTO_CaretValueFormat3;
struct TTO_CaretValueFormat4_
{
FT_UShort IdCaretValue; /* metric ID */
};
typedef struct TTO_CaretValueFormat4_ TTO_CaretValueFormat4;
struct TTO_CaretValue_
{
FT_UShort CaretValueFormat; /* 1, 2, 3, or 4 */
union
{
TTO_CaretValueFormat1 cvf1;
TTO_CaretValueFormat2 cvf2;
TTO_CaretValueFormat3 cvf3;
TTO_CaretValueFormat4 cvf4;
} cvf;
};
typedef struct TTO_CaretValue_ TTO_CaretValue;
struct TTO_LigGlyph_
{
FT_Bool loaded;
FT_UShort CaretCount; /* number of caret values */
TTO_CaretValue* CaretValue; /* array of caret values */
};
typedef struct TTO_LigGlyph_ TTO_LigGlyph;
struct TTO_LigCaretList_
{
FT_Bool loaded;
TTO_Coverage Coverage; /* Coverage table */
FT_UShort LigGlyphCount; /* number of ligature glyphs */
TTO_LigGlyph* LigGlyph; /* array of LigGlyph tables */
};
typedef struct TTO_LigCaretList_ TTO_LigCaretList;
/* The `NewGlyphClasses' field is not defined in the TTO specification.
We use it for fonts with a constructed `GlyphClassDef' structure
(i.e., which don't have a GDEF table) to collect glyph classes
assigned during the lookup process. The number of arrays in this
pointer array is GlyphClassDef->cd.cd2.ClassRangeCount+1; the nth
array then contains the glyph class values of the glyphs not covered
by the ClassRangeRecords structures with index n-1 and n. We store
glyph class values for four glyphs in a single array element.
`LastGlyph' is identical to the number of glyphs minus one in the
font; we need it only if `NewGlyphClasses' is not NULL (to have an
upper bound for the last array).
Note that we first store the file offset to the `MarkAttachClassDef'
field (which has been introduced in OpenType 1.2) -- since the
`Version' field value hasn't been increased to indicate that we have
one more field for some obscure reason, we must parse the GSUB table
to find out whether class values refer to this table. Only then we
can finally load the MarkAttachClassDef structure if necessary. */
struct TTO_GDEFHeader_
{
FT_Memory memory;
FT_ULong offset;
FT_Fixed Version;
TTO_ClassDefinition GlyphClassDef;
TTO_AttachList AttachList;
TTO_LigCaretList LigCaretList;
FT_ULong MarkAttachClassDef_offset;
TTO_ClassDefinition MarkAttachClassDef; /* new in OT 1.2 */
FT_UShort LastGlyph;
FT_UShort** NewGlyphClasses;
};
typedef struct TTO_GDEFHeader_ TTO_GDEFHeader;
typedef struct TTO_GDEFHeader_* TTO_GDEF;
/* finally, the GDEF API */
/* EXPORT_DEF
FT_Error TT_Init_GDEF_Extension( TT_Engine engine ); */
EXPORT_DEF
FT_Error TT_Load_GDEF_Table( FT_Face face,
TTO_GDEFHeader** gdef );
EXPORT_DEF
FT_Error TT_Done_GDEF_Table ( TTO_GDEFHeader* gdef );
EXPORT_DEF
FT_Error TT_GDEF_Get_Glyph_Property( TTO_GDEFHeader* gdef,
FT_UShort glyphID,
FT_UShort* property );
EXPORT_DEF
FT_Error TT_GDEF_Build_ClassDefinition( TTO_GDEFHeader* gdef,
FT_UShort num_glyphs,
FT_UShort glyph_count,
FT_UShort* glyph_array,
FT_UShort* class_array );
#ifdef __cplusplus
}
#endif
#endif /* FTXGDEF_H */
/* END */

6222
src/ftxgpos.c Normal file

File diff suppressed because it is too large Load Diff

858
src/ftxgpos.h Normal file
View File

@ -0,0 +1,858 @@
/*******************************************************************
*
* ftxgpos.h
*
* TrueType Open GPOS table support
*
* Copyright 1996-2000 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used
* modified and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
******************************************************************/
#ifndef FTXOPEN_H
#error "Don't include this file! Use ftxopen.h instead."
#endif
#ifndef FTXGPOS_H
#define FTXGPOS_H
#ifdef __cplusplus
extern "C" {
#endif
#define TTO_Err_Invalid_GPOS_SubTable_Format 0x1020
#define TTO_Err_Invalid_GPOS_SubTable 0x1021
/* Lookup types for glyph positioning */
#define GPOS_LOOKUP_SINGLE 1
#define GPOS_LOOKUP_PAIR 2
#define GPOS_LOOKUP_CURSIVE 3
#define GPOS_LOOKUP_MARKBASE 4
#define GPOS_LOOKUP_MARKLIG 5
#define GPOS_LOOKUP_MARKMARK 6
#define GPOS_LOOKUP_CONTEXT 7
#define GPOS_LOOKUP_CHAIN 8
/* A pointer to a function which loads a glyph. Its parameters are
the same as in a call to TT_Load_Glyph() -- if no glyph loading
function will be registered with TTO_GPOS_Register_Glyph_Function(),
TT_Load_Glyph() will be called indeed. The purpose of this function
pointer is to provide a hook for caching glyph outlines and sbits
(using the instance's generic pointer to hold the data).
If for some reason no outline data is available (e.g. for an
embedded bitmap glyph), _glyph->outline.n_points should be set to
zero. _glyph can be computed with
_glyph = HANDLE_Glyph( glyph ) */
typedef FT_Error (*TTO_GlyphFunction)(FT_Face face,
FT_UInt glyphIndex,
FT_Int loadFlags );
/* A pointer to a function which accesses the PostScript interpreter.
Multiple Master fonts need this interface to convert a metric ID
(as stored in an OpenType font version 1.2 or higher) `metric_id'
into a metric value (returned in `metric_value').
`data' points to the user-defined structure specified during a
call to TT_GPOS_Register_MM_Function().
`metric_value' must be returned as a scaled value (but shouldn't
be rounded). */
typedef FT_Error (*TTO_MMFunction)(FT_Face face,
FT_UShort metric_id,
FT_Pos* metric_value,
void* data );
struct TTO_GPOSHeader_
{
FT_Memory memory;
FT_Fixed Version;
TTO_ScriptList ScriptList;
TTO_FeatureList FeatureList;
TTO_LookupList LookupList;
TTO_GDEFHeader* gdef;
/* the next field is used for a callback function to get the
glyph outline. */
TTO_GlyphFunction gfunc;
/* this is OpenType 1.2 -- Multiple Master fonts need this
callback function to get various metric values from the
PostScript interpreter. */
TTO_MMFunction mmfunc;
void* data;
};
typedef struct TTO_GPOSHeader_ TTO_GPOSHeader;
typedef struct TTO_GPOSHeader_* TTO_GPOS;
/* shared tables */
struct TTO_ValueRecord_
{
FT_Short XPlacement; /* horizontal adjustment for
placement */
FT_Short YPlacement; /* vertical adjustment for
placement */
FT_Short XAdvance; /* horizontal adjustment for
advance */
FT_Short YAdvance; /* vertical adjustment for
advance */
TTO_Device XPlacementDevice; /* device table for horizontal
placement */
TTO_Device YPlacementDevice; /* device table for vertical
placement */
TTO_Device XAdvanceDevice; /* device table for horizontal
advance */
TTO_Device YAdvanceDevice; /* device table for vertical
advance */
FT_UShort XIdPlacement; /* horizontal placement metric ID */
FT_UShort YIdPlacement; /* vertical placement metric ID */
FT_UShort XIdAdvance; /* horizontal advance metric ID */
FT_UShort YIdAdvance; /* vertical advance metric ID */
};
typedef struct TTO_ValueRecord_ TTO_ValueRecord;
/* Mask values to scan the value format of the ValueRecord structure.
We always expand compressed ValueRecords of the font. */
#define HAVE_X_PLACEMENT 0x0001
#define HAVE_Y_PLACEMENT 0x0002
#define HAVE_X_ADVANCE 0x0004
#define HAVE_Y_ADVANCE 0x0008
#define HAVE_X_PLACEMENT_DEVICE 0x0010
#define HAVE_Y_PLACEMENT_DEVICE 0x0020
#define HAVE_X_ADVANCE_DEVICE 0x0040
#define HAVE_Y_ADVANCE_DEVICE 0x0080
#define HAVE_X_ID_PLACEMENT 0x0100
#define HAVE_Y_ID_PLACEMENT 0x0200
#define HAVE_X_ID_ADVANCE 0x0400
#define HAVE_Y_ID_ADVANCE 0x0800
struct TTO_AnchorFormat1_
{
FT_Short XCoordinate; /* horizontal value */
FT_Short YCoordinate; /* vertical value */
};
typedef struct TTO_AnchorFormat1_ TTO_AnchorFormat1;
struct TTO_AnchorFormat2_
{
FT_Short XCoordinate; /* horizontal value */
FT_Short YCoordinate; /* vertical value */
FT_UShort AnchorPoint; /* index to glyph contour point */
};
typedef struct TTO_AnchorFormat2_ TTO_AnchorFormat2;
struct TTO_AnchorFormat3_
{
FT_Short XCoordinate; /* horizontal value */
FT_Short YCoordinate; /* vertical value */
TTO_Device XDeviceTable; /* device table for X coordinate */
TTO_Device YDeviceTable; /* device table for Y coordinate */
};
typedef struct TTO_AnchorFormat3_ TTO_AnchorFormat3;
struct TTO_AnchorFormat4_
{
FT_UShort XIdAnchor; /* horizontal metric ID */
FT_UShort YIdAnchor; /* vertical metric ID */
};
typedef struct TTO_AnchorFormat4_ TTO_AnchorFormat4;
struct TTO_Anchor_
{
FT_UShort PosFormat; /* 1, 2, 3, or 4 -- 0 indicates
that there is no Anchor table */
union
{
TTO_AnchorFormat1 af1;
TTO_AnchorFormat2 af2;
TTO_AnchorFormat3 af3;
TTO_AnchorFormat4 af4;
} af;
};
typedef struct TTO_Anchor_ TTO_Anchor;
struct TTO_MarkRecord_
{
FT_UShort Class; /* mark class */
TTO_Anchor MarkAnchor; /* anchor table */
};
typedef struct TTO_MarkRecord_ TTO_MarkRecord;
struct TTO_MarkArray_
{
FT_UShort MarkCount; /* number of MarkRecord tables */
TTO_MarkRecord* MarkRecord; /* array of MarkRecord tables */
};
typedef struct TTO_MarkArray_ TTO_MarkArray;
/* LookupType 1 */
struct TTO_SinglePosFormat1_
{
TTO_ValueRecord Value; /* ValueRecord for all covered
glyphs */
};
typedef struct TTO_SinglePosFormat1_ TTO_SinglePosFormat1;
struct TTO_SinglePosFormat2_
{
FT_UShort ValueCount; /* number of ValueRecord tables */
TTO_ValueRecord* Value; /* array of ValueRecord tables */
};
typedef struct TTO_SinglePosFormat2_ TTO_SinglePosFormat2;
struct TTO_SinglePos_
{
FT_UShort PosFormat; /* 1 or 2 */
TTO_Coverage Coverage; /* Coverage table */
FT_UShort ValueFormat; /* format of ValueRecord table */
union
{
TTO_SinglePosFormat1 spf1;
TTO_SinglePosFormat2 spf2;
} spf;
};
typedef struct TTO_SinglePos_ TTO_SinglePos;
/* LookupType 2 */
struct TTO_PairValueRecord_
{
FT_UShort SecondGlyph; /* glyph ID for second glyph */
TTO_ValueRecord Value1; /* pos. data for first glyph */
TTO_ValueRecord Value2; /* pos. data for second glyph */
};
typedef struct TTO_PairValueRecord_ TTO_PairValueRecord;
struct TTO_PairSet_
{
FT_UShort PairValueCount;
/* number of PairValueRecord tables */
TTO_PairValueRecord* PairValueRecord;
/* array of PairValueRecord tables */
};
typedef struct TTO_PairSet_ TTO_PairSet;
struct TTO_PairPosFormat1_
{
FT_UShort PairSetCount; /* number of PairSet tables */
TTO_PairSet* PairSet; /* array of PairSet tables */
};
typedef struct TTO_PairPosFormat1_ TTO_PairPosFormat1;
struct TTO_Class2Record_
{
TTO_ValueRecord Value1; /* pos. data for first glyph */
TTO_ValueRecord Value2; /* pos. data for second glyph */
};
typedef struct TTO_Class2Record_ TTO_Class2Record;
struct TTO_Class1Record_
{
TTO_Class2Record* Class2Record; /* array of Class2Record tables */
};
typedef struct TTO_Class1Record_ TTO_Class1Record;
struct TTO_PairPosFormat2_
{
TTO_ClassDefinition ClassDef1; /* class def. for first glyph */
TTO_ClassDefinition ClassDef2; /* class def. for second glyph */
FT_UShort Class1Count; /* number of classes in ClassDef1
table */
FT_UShort Class2Count; /* number of classes in ClassDef2
table */
TTO_Class1Record* Class1Record; /* array of Class1Record tables */
};
typedef struct TTO_PairPosFormat2_ TTO_PairPosFormat2;
struct TTO_PairPos_
{
FT_UShort PosFormat; /* 1 or 2 */
TTO_Coverage Coverage; /* Coverage table */
FT_UShort ValueFormat1; /* format of ValueRecord table
for first glyph */
FT_UShort ValueFormat2; /* format of ValueRecord table
for second glyph */
union
{
TTO_PairPosFormat1 ppf1;
TTO_PairPosFormat2 ppf2;
} ppf;
};
typedef struct TTO_PairPos_ TTO_PairPos;
/* LookupType 3 */
struct TTO_EntryExitRecord_
{
TTO_Anchor EntryAnchor; /* entry Anchor table */
TTO_Anchor ExitAnchor; /* exit Anchor table */
};
typedef struct TTO_EntryExitRecord_ TTO_EntryExitRecord;
struct TTO_CursivePos_
{
FT_UShort PosFormat; /* always 1 */
TTO_Coverage Coverage; /* Coverage table */
FT_UShort EntryExitCount;
/* number of EntryExitRecord tables */
TTO_EntryExitRecord* EntryExitRecord;
/* array of EntryExitRecord tables */
};
typedef struct TTO_CursivePos_ TTO_CursivePos;
/* LookupType 4 */
struct TTO_BaseRecord_
{
TTO_Anchor* BaseAnchor; /* array of base glyph anchor
tables */
};
typedef struct TTO_BaseRecord_ TTO_BaseRecord;
struct TTO_BaseArray_
{
FT_UShort BaseCount; /* number of BaseRecord tables */
TTO_BaseRecord* BaseRecord; /* array of BaseRecord tables */
};
typedef struct TTO_BaseArray_ TTO_BaseArray;
struct TTO_MarkBasePos_
{
FT_UShort PosFormat; /* always 1 */
TTO_Coverage MarkCoverage; /* mark glyph coverage table */
TTO_Coverage BaseCoverage; /* base glyph coverage table */
FT_UShort ClassCount; /* number of mark classes */
TTO_MarkArray MarkArray; /* mark array table */
TTO_BaseArray BaseArray; /* base array table */
};
typedef struct TTO_MarkBasePos_ TTO_MarkBasePos;
/* LookupType 5 */
struct TTO_ComponentRecord_
{
TTO_Anchor* LigatureAnchor; /* array of ligature glyph anchor
tables */
};
typedef struct TTO_ComponentRecord_ TTO_ComponentRecord;
struct TTO_LigatureAttach_
{
FT_UShort ComponentCount;
/* number of ComponentRecord tables */
TTO_ComponentRecord* ComponentRecord;
/* array of ComponentRecord tables */
};
typedef struct TTO_LigatureAttach_ TTO_LigatureAttach;
struct TTO_LigatureArray_
{
FT_UShort LigatureCount; /* number of LigatureAttach tables */
TTO_LigatureAttach* LigatureAttach;
/* array of LigatureAttach tables */
};
typedef struct TTO_LigatureArray_ TTO_LigatureArray;
struct TTO_MarkLigPos_
{
FT_UShort PosFormat; /* always 1 */
TTO_Coverage MarkCoverage; /* mark glyph coverage table */
TTO_Coverage LigatureCoverage;
/* ligature glyph coverage table */
FT_UShort ClassCount; /* number of mark classes */
TTO_MarkArray MarkArray; /* mark array table */
TTO_LigatureArray LigatureArray; /* ligature array table */
};
typedef struct TTO_MarkLigPos_ TTO_MarkLigPos;
/* LookupType 6 */
struct TTO_Mark2Record_
{
TTO_Anchor* Mark2Anchor; /* array of mark glyph anchor
tables */
};
typedef struct TTO_Mark2Record_ TTO_Mark2Record;
struct TTO_Mark2Array_
{
FT_UShort Mark2Count; /* number of Mark2Record tables */
TTO_Mark2Record* Mark2Record; /* array of Mark2Record tables */
};
typedef struct TTO_Mark2Array_ TTO_Mark2Array;
struct TTO_MarkMarkPos_
{
FT_UShort PosFormat; /* always 1 */
TTO_Coverage Mark1Coverage; /* first mark glyph coverage table */
TTO_Coverage Mark2Coverage; /* second mark glyph coverave table */
FT_UShort ClassCount; /* number of combining mark classes */
TTO_MarkArray Mark1Array; /* MarkArray table for first mark */
TTO_Mark2Array Mark2Array; /* MarkArray table for second mark */
};
typedef struct TTO_MarkMarkPos_ TTO_MarkMarkPos;
/* needed by both lookup type 7 and 8 */
struct TTO_PosLookupRecord_
{
FT_UShort SequenceIndex; /* index into current
glyph sequence */
FT_UShort LookupListIndex; /* Lookup to apply to that pos. */
};
typedef struct TTO_PosLookupRecord_ TTO_PosLookupRecord;
/* LookupType 7 */
struct TTO_PosRule_
{
FT_UShort GlyphCount; /* total number of input glyphs */
FT_UShort PosCount; /* number of PosLookupRecord tables */
FT_UShort* Input; /* array of input glyph IDs */
TTO_PosLookupRecord* PosLookupRecord;
/* array of PosLookupRecord tables */
};
typedef struct TTO_PosRule_ TTO_PosRule;
struct TTO_PosRuleSet_
{
FT_UShort PosRuleCount; /* number of PosRule tables */
TTO_PosRule* PosRule; /* array of PosRule tables */
};
typedef struct TTO_PosRuleSet_ TTO_PosRuleSet;
struct TTO_ContextPosFormat1_
{
TTO_Coverage Coverage; /* Coverage table */
FT_UShort PosRuleSetCount; /* number of PosRuleSet tables */
TTO_PosRuleSet* PosRuleSet; /* array of PosRuleSet tables */
};
typedef struct TTO_ContextPosFormat1_ TTO_ContextPosFormat1;
struct TTO_PosClassRule_
{
FT_UShort GlyphCount; /* total number of context classes */
FT_UShort PosCount; /* number of PosLookupRecord tables */
FT_UShort* Class; /* array of classes */
TTO_PosLookupRecord* PosLookupRecord;
/* array of PosLookupRecord tables */
};
typedef struct TTO_PosClassRule_ TTO_PosClassRule;
struct TTO_PosClassSet_
{
FT_UShort PosClassRuleCount;
/* number of PosClassRule tables */
TTO_PosClassRule* PosClassRule; /* array of PosClassRule tables */
};
typedef struct TTO_PosClassSet_ TTO_PosClassSet;
/* The `MaxContextLength' field is not defined in the TTO specification
but simplifies the implementation of this format. It holds the
maximal context length used in the context rules. */
struct TTO_ContextPosFormat2_
{
FT_UShort MaxContextLength;
/* maximal context length */
TTO_Coverage Coverage; /* Coverage table */
TTO_ClassDefinition ClassDef; /* ClassDef table */
FT_UShort PosClassSetCount;
/* number of PosClassSet tables */
TTO_PosClassSet* PosClassSet; /* array of PosClassSet tables */
};
typedef struct TTO_ContextPosFormat2_ TTO_ContextPosFormat2;
struct TTO_ContextPosFormat3_
{
FT_UShort GlyphCount; /* number of input glyphs */
FT_UShort PosCount; /* number of PosLookupRecord tables */
TTO_Coverage* Coverage; /* array of Coverage tables */
TTO_PosLookupRecord* PosLookupRecord;
/* array of PosLookupRecord tables */
};
typedef struct TTO_ContextPosFormat3_ TTO_ContextPosFormat3;
struct TTO_ContextPos_
{
FT_UShort PosFormat; /* 1, 2, or 3 */
union
{
TTO_ContextPosFormat1 cpf1;
TTO_ContextPosFormat2 cpf2;
TTO_ContextPosFormat3 cpf3;
} cpf;
};
typedef struct TTO_ContextPos_ TTO_ContextPos;
/* LookupType 8 */
struct TTO_ChainPosRule_
{
FT_UShort BacktrackGlyphCount;
/* total number of backtrack glyphs */
FT_UShort* Backtrack; /* array of backtrack glyph IDs */
FT_UShort InputGlyphCount;
/* total number of input glyphs */
FT_UShort* Input; /* array of input glyph IDs */
FT_UShort LookaheadGlyphCount;
/* total number of lookahead glyphs */
FT_UShort* Lookahead; /* array of lookahead glyph IDs */
FT_UShort PosCount; /* number of PosLookupRecords */
TTO_PosLookupRecord* PosLookupRecord;
/* array of PosLookupRecords */
};
typedef struct TTO_ChainPosRule_ TTO_ChainPosRule;
struct TTO_ChainPosRuleSet_
{
FT_UShort ChainPosRuleCount;
/* number of ChainPosRule tables */
TTO_ChainPosRule* ChainPosRule; /* array of ChainPosRule tables */
};
typedef struct TTO_ChainPosRuleSet_ TTO_ChainPosRuleSet;
struct TTO_ChainContextPosFormat1_
{
TTO_Coverage Coverage; /* Coverage table */
FT_UShort ChainPosRuleSetCount;
/* number of ChainPosRuleSet tables */
TTO_ChainPosRuleSet* ChainPosRuleSet;
/* array of ChainPosRuleSet tables */
};
typedef struct TTO_ChainContextPosFormat1_ TTO_ChainContextPosFormat1;
struct TTO_ChainPosClassRule_
{
FT_UShort BacktrackGlyphCount;
/* total number of backtrack
classes */
FT_UShort* Backtrack; /* array of backtrack classes */
FT_UShort InputGlyphCount;
/* total number of context classes */
FT_UShort* Input; /* array of context classes */
FT_UShort LookaheadGlyphCount;
/* total number of lookahead
classes */
FT_UShort* Lookahead; /* array of lookahead classes */
FT_UShort PosCount; /* number of PosLookupRecords */
TTO_PosLookupRecord* PosLookupRecord;
/* array of substitution lookups */
};
typedef struct TTO_ChainPosClassRule_ TTO_ChainPosClassRule;
struct TTO_ChainPosClassSet_
{
FT_UShort ChainPosClassRuleCount;
/* number of ChainPosClassRule
tables */
TTO_ChainPosClassRule* ChainPosClassRule;
/* array of ChainPosClassRule
tables */
};
typedef struct TTO_ChainPosClassSet_ TTO_ChainPosClassSet;
/* The `MaxXXXLength' fields are not defined in the TTO specification
but simplifies the implementation of this format. It holds the
maximal context length used in the specific context rules. */
struct TTO_ChainContextPosFormat2_
{
TTO_Coverage Coverage; /* Coverage table */
FT_UShort MaxBacktrackLength;
/* maximal backtrack length */
TTO_ClassDefinition BacktrackClassDef;
/* BacktrackClassDef table */
FT_UShort MaxInputLength;
/* maximal input length */
TTO_ClassDefinition InputClassDef;
/* InputClassDef table */
FT_UShort MaxLookaheadLength;
/* maximal lookahead length */
TTO_ClassDefinition LookaheadClassDef;
/* LookaheadClassDef table */
FT_UShort ChainPosClassSetCount;
/* number of ChainPosClassSet
tables */
TTO_ChainPosClassSet* ChainPosClassSet;
/* array of ChainPosClassSet
tables */
};
typedef struct TTO_ChainContextPosFormat2_ TTO_ChainContextPosFormat2;
struct TTO_ChainContextPosFormat3_
{
FT_UShort BacktrackGlyphCount;
/* number of backtrack glyphs */
TTO_Coverage* BacktrackCoverage;
/* array of backtrack Coverage
tables */
FT_UShort InputGlyphCount;
/* number of input glyphs */
TTO_Coverage* InputCoverage;
/* array of input coverage
tables */
FT_UShort LookaheadGlyphCount;
/* number of lookahead glyphs */
TTO_Coverage* LookaheadCoverage;
/* array of lookahead coverage
tables */
FT_UShort PosCount; /* number of PosLookupRecords */
TTO_PosLookupRecord* PosLookupRecord;
/* array of substitution lookups */
};
typedef struct TTO_ChainContextPosFormat3_ TTO_ChainContextPosFormat3;
struct TTO_ChainContextPos_
{
FT_UShort PosFormat; /* 1, 2, or 3 */
union
{
TTO_ChainContextPosFormat1 ccpf1;
TTO_ChainContextPosFormat2 ccpf2;
TTO_ChainContextPosFormat3 ccpf3;
} ccpf;
};
typedef struct TTO_ChainContextPos_ TTO_ChainContextPos;
union TTO_GPOS_SubTable_
{
TTO_SinglePos single;
TTO_PairPos pair;
TTO_CursivePos cursive;
TTO_MarkBasePos markbase;
TTO_MarkLigPos marklig;
TTO_MarkMarkPos markmark;
TTO_ContextPos context;
TTO_ChainContextPos chain;
};
typedef union TTO_GPOS_SubTable_ TTO_GPOS_SubTable;
/* This `string object' is much simpler compared to TTO_GSUB_String.
A call to TTO_GPOS_Apply_String() will allocate it. */
struct TTO_GPOS_Data_
{
FT_Pos x_pos;
FT_Pos y_pos;
FT_Pos x_advance;
FT_Pos y_advance;
FT_UShort back; /* number of glyphs to go back
for drawing current glyph */
FT_Bool new_advance; /* if set, the advance width values are
absolute, i.e., they won't be
added to the original glyph's value
but rather replace them. */
};
typedef struct TTO_GPOS_Data_ TTO_GPOS_Data;
/* finally, the GPOS API */
/* EXPORT_DEF
FT_Export ( FT_Error ) TT_Init_GPOS_Extension( TT_Engine engine ); */
EXPORT_DEF
FT_Error TT_Load_GPOS_Table( FT_Face face,
TTO_GPOSHeader** gpos,
TTO_GDEFHeader* gdef );
EXPORT_DEF
FT_Error TT_Done_GPOS_Table( TTO_GPOSHeader* gpos );
EXPORT_DEF
FT_Error TT_GPOS_Select_Script( TTO_GPOSHeader* gpos,
FT_ULong script_tag,
FT_UShort* script_index );
EXPORT_DEF
FT_Error TT_GPOS_Select_Language( TTO_GPOSHeader* gpos,
FT_ULong language_tag,
FT_UShort script_index,
FT_UShort* language_index,
FT_UShort* req_feature_index );
EXPORT_DEF
FT_Error TT_GPOS_Select_Feature( TTO_GPOSHeader* gpos,
FT_ULong feature_tag,
FT_UShort script_index,
FT_UShort language_index,
FT_UShort* feature_index );
EXPORT_DEF
FT_Error TT_GPOS_Query_Scripts( TTO_GPOSHeader* gpos,
FT_ULong** script_tag_list );
EXPORT_DEF
FT_Error TT_GPOS_Query_Languages( TTO_GPOSHeader* gpos,
FT_UShort script_index,
FT_ULong** language_tag_list );
EXPORT_DEF
FT_Error TT_GPOS_Query_Features( TTO_GPOSHeader* gpos,
FT_UShort script_index,
FT_UShort language_index,
FT_ULong** feature_tag_list );
EXPORT_DEF
FT_Error TT_GPOS_Add_Feature( TTO_GPOSHeader* gpos,
FT_UShort feature_index,
FT_UShort property );
EXPORT_DEF
FT_Error TT_GPOS_Clear_Features( TTO_GPOSHeader* gpos );
EXPORT_DEF
FT_Error TT_GPOS_Register_Glyph_Function( TTO_GPOSHeader* gpos,
TTO_GlyphFunction gfunc );
EXPORT_DEF
FT_Error TT_GPOS_Register_MM_Function( TTO_GPOSHeader* gpos,
TTO_MMFunction mmfunc,
void* data );
/* If `dvi' is TRUE, glyph contour points for anchor points and device
tables are ignored -- you will get device independent values. */
EXPORT_DEF
FT_Error TT_GPOS_Apply_String( FT_Face face,
TTO_GPOSHeader* gpos,
FT_UShort load_flags,
TTO_GSUB_String* in,
TTO_GPOS_Data** out,
FT_Bool dvi,
FT_Bool r2l );
#ifdef __cplusplus
}
#endif
#endif /* FTXGPOS_H */
/* END */

4531
src/ftxgsub.c Normal file

File diff suppressed because it is too large Load Diff

612
src/ftxgsub.h Normal file
View File

@ -0,0 +1,612 @@
/*******************************************************************
*
* ftxgsub.h
*
* TrueType Open GSUB table support
*
* Copyright 1996-2000 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used
* modified and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
******************************************************************/
#ifndef FTXOPEN_H
#error "Don't include this file! Use ftxopen.h instead."
#endif
#ifndef FTXGSUB_H
#define FTXGSUB_H
#ifdef __cplusplus
extern "C" {
#endif
#define TTO_Err_Invalid_GSUB_SubTable_Format 0x1010
#define TTO_Err_Invalid_GSUB_SubTable 0x1011
/* Lookup types for glyph substitution */
#define GSUB_LOOKUP_SINGLE 1
#define GSUB_LOOKUP_MULTIPLE 2
#define GSUB_LOOKUP_ALTERNATE 3
#define GSUB_LOOKUP_LIGATURE 4
#define GSUB_LOOKUP_CONTEXT 5
#define GSUB_LOOKUP_CHAIN 6
/* Use this if a feature applies to all glyphs */
#define ALL_GLYPHS 0xFFFF
/* A pointer to a function which selects the alternate glyph. `pos' is
the position of the glyph with index `glyphID', `num_alternates'
gives the number of alternates in the `alternates' array. `data'
points to the user-defined structure specified during a call to
TT_GSUB_Register_Alternate_Function(). The function must return an
index into the `alternates' array. */
typedef FT_UShort (*TTO_AltFunction)(FT_ULong pos,
FT_UShort glyphID,
FT_UShort num_alternates,
FT_UShort* alternates,
void* data );
struct TTO_GSUBHeader_
{
FT_Memory memory;
FT_ULong offset;
FT_Fixed Version;
TTO_ScriptList ScriptList;
TTO_FeatureList FeatureList;
TTO_LookupList LookupList;
TTO_GDEFHeader* gdef;
/* the next two fields are used for an alternate substitution callback
function to select the proper alternate glyph. */
TTO_AltFunction altfunc;
void* data;
};
typedef struct TTO_GSUBHeader_ TTO_GSUBHeader;
typedef struct TTO_GSUBHeader_* TTO_GSUB;
/* LookupType 1 */
struct TTO_SingleSubstFormat1_
{
FT_Short DeltaGlyphID; /* constant added to get
substitution glyph index */
};
typedef struct TTO_SingleSubstFormat1_ TTO_SingleSubstFormat1;
struct TTO_SingleSubstFormat2_
{
FT_UShort GlyphCount; /* number of glyph IDs in
Substitute array */
FT_UShort* Substitute; /* array of substitute glyph IDs */
};
typedef struct TTO_SingleSubstFormat2_ TTO_SingleSubstFormat2;
struct TTO_SingleSubst_
{
FT_UShort SubstFormat; /* 1 or 2 */
TTO_Coverage Coverage; /* Coverage table */
union
{
TTO_SingleSubstFormat1 ssf1;
TTO_SingleSubstFormat2 ssf2;
} ssf;
};
typedef struct TTO_SingleSubst_ TTO_SingleSubst;
/* LookupType 2 */
struct TTO_Sequence_
{
FT_UShort GlyphCount; /* number of glyph IDs in the
Substitute array */
FT_UShort* Substitute; /* string of glyph IDs to
substitute */
};
typedef struct TTO_Sequence_ TTO_Sequence;
struct TTO_MultipleSubst_
{
FT_UShort SubstFormat; /* always 1 */
TTO_Coverage Coverage; /* Coverage table */
FT_UShort SequenceCount; /* number of Sequence tables */
TTO_Sequence* Sequence; /* array of Sequence tables */
};
typedef struct TTO_MultipleSubst_ TTO_MultipleSubst;
/* LookupType 3 */
struct TTO_AlternateSet_
{
FT_UShort GlyphCount; /* number of glyph IDs in the
Alternate array */
FT_UShort* Alternate; /* array of alternate glyph IDs */
};
typedef struct TTO_AlternateSet_ TTO_AlternateSet;
struct TTO_AlternateSubst_
{
FT_UShort SubstFormat; /* always 1 */
TTO_Coverage Coverage; /* Coverage table */
FT_UShort AlternateSetCount;
/* number of AlternateSet tables */
TTO_AlternateSet* AlternateSet; /* array of AlternateSet tables */
};
typedef struct TTO_AlternateSubst_ TTO_AlternateSubst;
/* LookupType 4 */
struct TTO_Ligature_
{
FT_UShort LigGlyph; /* glyphID of ligature
to substitute */
FT_UShort ComponentCount; /* number of components in ligature */
FT_UShort* Component; /* array of component glyph IDs */
};
typedef struct TTO_Ligature_ TTO_Ligature;
struct TTO_LigatureSet_
{
FT_UShort LigatureCount; /* number of Ligature tables */
TTO_Ligature* Ligature; /* array of Ligature tables */
};
typedef struct TTO_LigatureSet_ TTO_LigatureSet;
struct TTO_LigatureSubst_
{
FT_UShort SubstFormat; /* always 1 */
TTO_Coverage Coverage; /* Coverage table */
FT_UShort LigatureSetCount; /* number of LigatureSet tables */
TTO_LigatureSet* LigatureSet; /* array of LigatureSet tables */
};
typedef struct TTO_LigatureSubst_ TTO_LigatureSubst;
/* needed by both lookup type 5 and 6 */
struct TTO_SubstLookupRecord_
{
FT_UShort SequenceIndex; /* index into current
glyph sequence */
FT_UShort LookupListIndex; /* Lookup to apply to that pos. */
};
typedef struct TTO_SubstLookupRecord_ TTO_SubstLookupRecord;
/* LookupType 5 */
struct TTO_SubRule_
{
FT_UShort GlyphCount; /* total number of input glyphs */
FT_UShort SubstCount; /* number of SubstLookupRecord
tables */
FT_UShort* Input; /* array of input glyph IDs */
TTO_SubstLookupRecord* SubstLookupRecord;
/* array of SubstLookupRecord
tables */
};
typedef struct TTO_SubRule_ TTO_SubRule;
struct TTO_SubRuleSet_
{
FT_UShort SubRuleCount; /* number of SubRule tables */
TTO_SubRule* SubRule; /* array of SubRule tables */
};
typedef struct TTO_SubRuleSet_ TTO_SubRuleSet;
struct TTO_ContextSubstFormat1_
{
TTO_Coverage Coverage; /* Coverage table */
FT_UShort SubRuleSetCount; /* number of SubRuleSet tables */
TTO_SubRuleSet* SubRuleSet; /* array of SubRuleSet tables */
};
typedef struct TTO_ContextSubstFormat1_ TTO_ContextSubstFormat1;
struct TTO_SubClassRule_
{
FT_UShort GlyphCount; /* total number of context classes */
FT_UShort SubstCount; /* number of SubstLookupRecord
tables */
FT_UShort* Class; /* array of classes */
TTO_SubstLookupRecord* SubstLookupRecord;
/* array of SubstLookupRecord
tables */
};
typedef struct TTO_SubClassRule_ TTO_SubClassRule;
struct TTO_SubClassSet_
{
FT_UShort SubClassRuleCount;
/* number of SubClassRule tables */
TTO_SubClassRule* SubClassRule; /* array of SubClassRule tables */
};
typedef struct TTO_SubClassSet_ TTO_SubClassSet;
/* The `MaxContextLength' field is not defined in the TTO specification
but simplifies the implementation of this format. It holds the
maximal context length used in the context rules. */
struct TTO_ContextSubstFormat2_
{
FT_UShort MaxContextLength;
/* maximal context length */
TTO_Coverage Coverage; /* Coverage table */
TTO_ClassDefinition ClassDef; /* ClassDef table */
FT_UShort SubClassSetCount;
/* number of SubClassSet tables */
TTO_SubClassSet* SubClassSet; /* array of SubClassSet tables */
};
typedef struct TTO_ContextSubstFormat2_ TTO_ContextSubstFormat2;
struct TTO_ContextSubstFormat3_
{
FT_UShort GlyphCount; /* number of input glyphs */
FT_UShort SubstCount; /* number of SubstLookupRecords */
TTO_Coverage* Coverage; /* array of Coverage tables */
TTO_SubstLookupRecord* SubstLookupRecord;
/* array of substitution lookups */
};
typedef struct TTO_ContextSubstFormat3_ TTO_ContextSubstFormat3;
struct TTO_ContextSubst_
{
FT_UShort SubstFormat; /* 1, 2, or 3 */
union
{
TTO_ContextSubstFormat1 csf1;
TTO_ContextSubstFormat2 csf2;
TTO_ContextSubstFormat3 csf3;
} csf;
};
typedef struct TTO_ContextSubst_ TTO_ContextSubst;
/* LookupType 6 */
struct TTO_ChainSubRule_
{
FT_UShort BacktrackGlyphCount;
/* total number of backtrack glyphs */
FT_UShort* Backtrack; /* array of backtrack glyph IDs */
FT_UShort InputGlyphCount;
/* total number of input glyphs */
FT_UShort* Input; /* array of input glyph IDs */
FT_UShort LookaheadGlyphCount;
/* total number of lookahead glyphs */
FT_UShort* Lookahead; /* array of lookahead glyph IDs */
FT_UShort SubstCount; /* number of SubstLookupRecords */
TTO_SubstLookupRecord* SubstLookupRecord;
/* array of SubstLookupRecords */
};
typedef struct TTO_ChainSubRule_ TTO_ChainSubRule;
struct TTO_ChainSubRuleSet_
{
FT_UShort ChainSubRuleCount;
/* number of ChainSubRule tables */
TTO_ChainSubRule* ChainSubRule; /* array of ChainSubRule tables */
};
typedef struct TTO_ChainSubRuleSet_ TTO_ChainSubRuleSet;
struct TTO_ChainContextSubstFormat1_
{
TTO_Coverage Coverage; /* Coverage table */
FT_UShort ChainSubRuleSetCount;
/* number of ChainSubRuleSet tables */
TTO_ChainSubRuleSet* ChainSubRuleSet;
/* array of ChainSubRuleSet tables */
};
typedef struct TTO_ChainContextSubstFormat1_ TTO_ChainContextSubstFormat1;
struct TTO_ChainSubClassRule_
{
FT_UShort BacktrackGlyphCount;
/* total number of backtrack
classes */
FT_UShort* Backtrack; /* array of backtrack classes */
FT_UShort InputGlyphCount;
/* total number of context classes */
FT_UShort* Input; /* array of context classes */
FT_UShort LookaheadGlyphCount;
/* total number of lookahead
classes */
FT_UShort* Lookahead; /* array of lookahead classes */
FT_UShort SubstCount; /* number of SubstLookupRecords */
TTO_SubstLookupRecord* SubstLookupRecord;
/* array of substitution lookups */
};
typedef struct TTO_ChainSubClassRule_ TTO_ChainSubClassRule;
struct TTO_ChainSubClassSet_
{
FT_UShort ChainSubClassRuleCount;
/* number of ChainSubClassRule
tables */
TTO_ChainSubClassRule* ChainSubClassRule;
/* array of ChainSubClassRule
tables */
};
typedef struct TTO_ChainSubClassSet_ TTO_ChainSubClassSet;
/* The `MaxXXXLength' fields are not defined in the TTO specification
but simplifies the implementation of this format. It holds the
maximal context length used in the specific context rules. */
struct TTO_ChainContextSubstFormat2_
{
TTO_Coverage Coverage; /* Coverage table */
FT_UShort MaxBacktrackLength;
/* maximal backtrack length */
TTO_ClassDefinition BacktrackClassDef;
/* BacktrackClassDef table */
FT_UShort MaxInputLength;
/* maximal input length */
TTO_ClassDefinition InputClassDef;
/* InputClassDef table */
FT_UShort MaxLookaheadLength;
/* maximal lookahead length */
TTO_ClassDefinition LookaheadClassDef;
/* LookaheadClassDef table */
FT_UShort ChainSubClassSetCount;
/* number of ChainSubClassSet
tables */
TTO_ChainSubClassSet* ChainSubClassSet;
/* array of ChainSubClassSet
tables */
};
typedef struct TTO_ChainContextSubstFormat2_ TTO_ChainContextSubstFormat2;
struct TTO_ChainContextSubstFormat3_
{
FT_UShort BacktrackGlyphCount;
/* number of backtrack glyphs */
TTO_Coverage* BacktrackCoverage;
/* array of backtrack Coverage
tables */
FT_UShort InputGlyphCount;
/* number of input glyphs */
TTO_Coverage* InputCoverage;
/* array of input coverage
tables */
FT_UShort LookaheadGlyphCount;
/* number of lookahead glyphs */
TTO_Coverage* LookaheadCoverage;
/* array of lookahead coverage
tables */
FT_UShort SubstCount; /* number of SubstLookupRecords */
TTO_SubstLookupRecord* SubstLookupRecord;
/* array of substitution lookups */
};
typedef struct TTO_ChainContextSubstFormat3_ TTO_ChainContextSubstFormat3;
struct TTO_ChainContextSubst_
{
FT_UShort SubstFormat; /* 1, 2, or 3 */
union
{
TTO_ChainContextSubstFormat1 ccsf1;
TTO_ChainContextSubstFormat2 ccsf2;
TTO_ChainContextSubstFormat3 ccsf3;
} ccsf;
};
typedef struct TTO_ChainContextSubst_ TTO_ChainContextSubst;
union TTO_GSUB_SubTable_
{
TTO_SingleSubst single;
TTO_MultipleSubst multiple;
TTO_AlternateSubst alternate;
TTO_LigatureSubst ligature;
TTO_ContextSubst context;
TTO_ChainContextSubst chain;
};
typedef union TTO_GSUB_SubTable_ TTO_GSUB_SubTable;
/* A simple string object. It can both `send' and `receive' data.
In case of sending, `length' and `pos' will be used. In case of
receiving, `pos' points to the first free slot, and `allocated'
specifies the amount of allocated memory (and the `length' field
will be ignored). The routine TT_Add_String() will increase the
amount of memory if necessary. After end of receive, `length'
should be set to the value of `pos', and `pos' will be set to zero.
`properties' (which is treated as a bit field) gives the glyph's
properties: If a certain bit is set for a glyph, the feature which
has the same bit set in its property value is applied.
`components' is an internal array which tracks components of
ligatures. We need this for MarkToLigature Attachment Positioning
Subtables (in GPOS) together with `ligIDs' (which is used to mark
ligatures and the skipped glyphs during a ligature lookup).
`max_ligID' is increased after a successful ligature lookup.
NEVER modify any elements of the structure! You should rather copy
its contents if necessary.
TT_Add_String() will also handle allocation; you should use
free() in case you want to destroy the arrays in the object. */
struct TTO_GSUB_String_
{
FT_Memory memory;
FT_ULong length;
FT_ULong pos;
FT_ULong allocated;
FT_UShort* string;
FT_UShort* properties;
FT_UShort* components;
FT_UShort max_ligID;
FT_UShort* ligIDs;
FT_Int* logClusters;
};
typedef struct TTO_GSUB_String_ TTO_GSUB_String;
/* finally, the GSUB API */
/* EXPORT_DEF
TT_Error TT_Init_GSUB_Extension( TT_Engine engine ); */
EXPORT_DEF
FT_Error TT_Load_GSUB_Table( FT_Face face,
TTO_GSUBHeader** gsub,
TTO_GDEFHeader* gdef );
EXPORT_DEF
FT_Error TT_Done_GSUB_Table( TTO_GSUBHeader* gsub );
EXPORT_DEF
FT_Error TT_GSUB_Select_Script( TTO_GSUBHeader* gsub,
FT_ULong script_tag,
FT_UShort* script_index );
EXPORT_DEF
FT_Error TT_GSUB_Select_Language( TTO_GSUBHeader* gsub,
FT_ULong language_tag,
FT_UShort script_index,
FT_UShort* language_index,
FT_UShort* req_feature_index );
EXPORT_DEF
FT_Error TT_GSUB_Select_Feature( TTO_GSUBHeader* gsub,
FT_ULong feature_tag,
FT_UShort script_index,
FT_UShort language_index,
FT_UShort* feature_index );
EXPORT_DEF
FT_Error TT_GSUB_Query_Scripts( TTO_GSUBHeader* gsub,
FT_ULong** script_tag_list );
EXPORT_DEF
FT_Error TT_GSUB_Query_Languages( TTO_GSUBHeader* gsub,
FT_UShort script_index,
FT_ULong** language_tag_list );
EXPORT_DEF
FT_Error TT_GSUB_Query_Features( TTO_GSUBHeader* gsub,
FT_UShort script_index,
FT_UShort language_index,
FT_ULong** feature_tag_list );
EXPORT_DEF
FT_Error TT_GSUB_Add_Feature( TTO_GSUBHeader* gsub,
FT_UShort feature_index,
FT_UShort property );
EXPORT_DEF
FT_Error TT_GSUB_Clear_Features( TTO_GSUBHeader* gsub );
EXPORT_DEF
FT_Error TT_GSUB_Register_Alternate_Function( TTO_GSUBHeader* gsub,
TTO_AltFunction altfunc,
void* data );
EXPORT_DEF
FT_Error TT_GSUB_String_New( FT_Memory memory,
TTO_GSUB_String **result );
EXPORT_DEF
FT_Error TT_GSUB_String_Set_Length( TTO_GSUB_String *str,
FT_ULong new_length);
EXPORT_DEF
FT_Error TT_GSUB_String_Done( TTO_GSUB_String *str );
EXPORT_DEF
FT_Error TT_GSUB_Apply_String( TTO_GSUBHeader* gsub,
TTO_GSUB_String* in,
TTO_GSUB_String* out );
EXPORT_DEF
FT_Error TT_GSUB_Add_String( TTO_GSUB_String* in,
FT_UShort num_in,
TTO_GSUB_String* out,
FT_UShort num_out,
FT_UShort* glyph_data,
FT_UShort component,
FT_UShort ligID );
#ifdef __cplusplus
}
#endif
#endif /* FTXGSUB_H */
/* END */

1467
src/ftxopen.c Normal file

File diff suppressed because it is too large Load Diff

308
src/ftxopen.h Normal file
View File

@ -0,0 +1,308 @@
/*******************************************************************
*
* ftxopen.h
*
* TrueType Open support.
*
* Copyright 1996-2000 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used
* modified and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
* This file should be included by the application. Nevertheless,
* the table specific APIs (and structures) are located in files like
* ftxgsub.h or ftxgpos.h; these header files are read by ftxopen.h .
*
******************************************************************/
#ifndef FTXOPEN_H
#define FTXOPEN_H
#include <freetype/freetype.h>
#ifdef __cplusplus
extern "C" {
#endif
#define EXPORT_DEF
#define EXPORT_FUNC
#define TTO_MAX_NESTING_LEVEL 100
#define TTO_Err_Invalid_SubTable_Format 0x1000
#define TTO_Err_Invalid_SubTable 0x1001
#define TTO_Err_Not_Covered 0x1002
#define TTO_Err_Too_Many_Nested_Contexts 0x1003
#define TTO_Err_No_MM_Interpreter 0x1004
/* Script list related structures */
struct TTO_LangSys_
{
FT_UShort LookupOrderOffset; /* always 0 for TT Open 1.0 */
FT_UShort ReqFeatureIndex; /* required FeatureIndex */
FT_UShort FeatureCount; /* number of Feature indices */
FT_UShort* FeatureIndex; /* array of Feature indices */
};
typedef struct TTO_LangSys_ TTO_LangSys;
struct TTO_LangSysRecord_
{
FT_ULong LangSysTag; /* LangSysTag identifier */
TTO_LangSys LangSys; /* LangSys table */
};
typedef struct TTO_LangSysRecord_ TTO_LangSysRecord;
struct TTO_Script_
{
TTO_LangSys DefaultLangSys; /* DefaultLangSys table */
FT_UShort LangSysCount; /* number of LangSysRecords */
TTO_LangSysRecord* LangSysRecord; /* array of LangSysRecords */
};
typedef struct TTO_Script_ TTO_Script;
struct TTO_ScriptRecord_
{
FT_ULong ScriptTag; /* ScriptTag identifier */
TTO_Script Script; /* Script table */
};
typedef struct TTO_ScriptRecord_ TTO_ScriptRecord;
struct TTO_ScriptList_
{
FT_UShort ScriptCount; /* number of ScriptRecords */
TTO_ScriptRecord* ScriptRecord; /* array of ScriptRecords */
};
typedef struct TTO_ScriptList_ TTO_ScriptList;
/* Feature list related structures */
struct TTO_Feature_
{
FT_UShort FeatureParams; /* always 0 for TT Open 1.0 */
FT_UShort LookupListCount; /* number of LookupList indices */
FT_UShort* LookupListIndex; /* array of LookupList indices */
};
typedef struct TTO_Feature_ TTO_Feature;
struct TTO_FeatureRecord_
{
FT_ULong FeatureTag; /* FeatureTag identifier */
TTO_Feature Feature; /* Feature table */
};
typedef struct TTO_FeatureRecord_ TTO_FeatureRecord;
struct TTO_FeatureList_
{
FT_UShort FeatureCount; /* number of FeatureRecords */
TTO_FeatureRecord* FeatureRecord; /* array of FeatureRecords */
};
typedef struct TTO_FeatureList_ TTO_FeatureList;
/* Lookup list related structures */
struct TTO_SubTable_; /* defined below after inclusion
of ftxgsub.h and ftxgpos.h */
typedef struct TTO_SubTable_ TTO_SubTable;
struct TTO_Lookup_
{
FT_UShort LookupType; /* Lookup type */
FT_UShort LookupFlag; /* Lookup qualifiers */
FT_UShort SubTableCount; /* number of SubTables */
TTO_SubTable* SubTable; /* array of SubTables */
};
typedef struct TTO_Lookup_ TTO_Lookup;
/* The `Properties' field is not defined in the TTO specification but
is needed for processing lookups. If properties[n] is > 0, the
functions TT_GSUB_Apply_String() resp. TT_GPOS_Apply_String() will
process Lookup[n] for glyphs which have the specific bit not set in
the `properties' field of the input string object. */
struct TTO_LookupList_
{
FT_UShort LookupCount; /* number of Lookups */
TTO_Lookup* Lookup; /* array of Lookup records */
FT_UShort* Properties; /* array of flags */
};
typedef struct TTO_LookupList_ TTO_LookupList;
/* Possible LookupFlag bit masks. `IGNORE_SPECIAL_MARKS' comes from the
OpenType 1.2 specification. */
#define IGNORE_BASE_GLYPHS 0x0002
#define IGNORE_LIGATURES 0x0004
#define IGNORE_MARKS 0x0008
#define IGNORE_SPECIAL_MARKS 0xFF00
struct TTO_CoverageFormat1_
{
FT_UShort GlyphCount; /* number of glyphs in GlyphArray */
FT_UShort* GlyphArray; /* array of glyph IDs */
};
typedef struct TTO_CoverageFormat1_ TTO_CoverageFormat1;
struct TTO_RangeRecord_
{
FT_UShort Start; /* first glyph ID in the range */
FT_UShort End; /* last glyph ID in the range */
FT_UShort StartCoverageIndex; /* coverage index of first
glyph ID in the range */
};
typedef struct TTO_RangeRecord_ TTO_RangeRecord;
struct TTO_CoverageFormat2_
{
FT_UShort RangeCount; /* number of RangeRecords */
TTO_RangeRecord* RangeRecord; /* array of RangeRecords */
};
typedef struct TTO_CoverageFormat2_ TTO_CoverageFormat2;
struct TTO_Coverage_
{
FT_UShort CoverageFormat; /* 1 or 2 */
union
{
TTO_CoverageFormat1 cf1;
TTO_CoverageFormat2 cf2;
} cf;
};
typedef struct TTO_Coverage_ TTO_Coverage;
struct TTO_ClassDefFormat1_
{
FT_UShort StartGlyph; /* first glyph ID of the
ClassValueArray */
FT_UShort GlyphCount; /* size of the ClassValueArray */
FT_UShort* ClassValueArray; /* array of class values */
};
typedef struct TTO_ClassDefFormat1_ TTO_ClassDefFormat1;
struct TTO_ClassRangeRecord_
{
FT_UShort Start; /* first glyph ID in the range */
FT_UShort End; /* last glyph ID in the range */
FT_UShort Class; /* applied to all glyphs in range */
};
typedef struct TTO_ClassRangeRecord_ TTO_ClassRangeRecord;
struct TTO_ClassDefFormat2_
{
FT_UShort ClassRangeCount;
/* number of ClassRangeRecords */
TTO_ClassRangeRecord* ClassRangeRecord;
/* array of ClassRangeRecords */
};
typedef struct TTO_ClassDefFormat2_ TTO_ClassDefFormat2;
/* The `Defined' field is not defined in the TTO specification but
apparently needed for processing fonts like trado.ttf: This font
refers to a class which contains not a single element. We map such
classes to class 0. */
struct TTO_ClassDefinition_
{
FT_Bool loaded;
FT_Bool* Defined; /* array of Booleans.
If Defined[n] is FALSE,
class n contains no glyphs. */
FT_UShort ClassFormat; /* 1 or 2 */
union
{
TTO_ClassDefFormat1 cd1;
TTO_ClassDefFormat2 cd2;
} cd;
};
typedef struct TTO_ClassDefinition_ TTO_ClassDefinition;
struct TTO_Device_
{
FT_UShort StartSize; /* smallest size to correct */
FT_UShort EndSize; /* largest size to correct */
FT_UShort DeltaFormat; /* DeltaValue array data format:
1, 2, or 3 */
FT_UShort* DeltaValue; /* array of compressed data */
};
typedef struct TTO_Device_ TTO_Device;
#include "ftxgdef.h"
#include "ftxgsub.h"
#include "ftxgpos.h"
struct TTO_SubTable_
{
union
{
TTO_GSUB_SubTable gsub;
TTO_GPOS_SubTable gpos;
} st;
};
enum TTO_Type_
{
GSUB,
GPOS
};
typedef enum TTO_Type_ TTO_Type;
#ifdef __cplusplus
}
#endif
#endif /* FTXOPEN_H */
/* END */

161
src/ftxopenf.h Normal file
View File

@ -0,0 +1,161 @@
/*******************************************************************
*
* ftxopenf.h
*
* internal TrueType Open functions
*
* Copyright 1996-2000 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used
* modified and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
******************************************************************/
#ifndef FTXOPENF_H
#define FTXOPENF_H
#include "ftxopen.h"
#ifdef __cplusplus
extern "C" {
#endif
/* functions from ftxopen.c */
FT_Error Load_ScriptList( TTO_ScriptList* sl,
FT_Stream stream );
FT_Error Load_FeatureList( TTO_FeatureList* fl,
FT_Stream input );
FT_Error Load_LookupList( TTO_LookupList* ll,
FT_Stream input,
TTO_Type type );
FT_Error Load_Coverage( TTO_Coverage* c,
FT_Stream input );
FT_Error Load_ClassDefinition( TTO_ClassDefinition* cd,
FT_UShort limit,
FT_Stream input );
FT_Error Load_Device( TTO_Device* d,
FT_Stream input );
void Free_ScriptList( TTO_ScriptList* sl,
FT_Memory memory );
void Free_FeatureList( TTO_FeatureList* fl,
FT_Memory memory );
void Free_LookupList( TTO_LookupList* ll,
TTO_Type type,
FT_Memory memory );
void Free_Coverage( TTO_Coverage* c,
FT_Memory memory );
void Free_ClassDefinition( TTO_ClassDefinition* cd,
FT_Memory memory );
void Free_Device( TTO_Device* d,
FT_Memory memory );
/* functions from ftxgsub.c */
FT_Error Load_SingleSubst( TTO_SingleSubst* ss,
FT_Stream input );
FT_Error Load_MultipleSubst( TTO_MultipleSubst* ms,
FT_Stream input );
FT_Error Load_AlternateSubst( TTO_AlternateSubst* as,
FT_Stream input );
FT_Error Load_LigatureSubst( TTO_LigatureSubst* ls,
FT_Stream input );
FT_Error Load_ContextSubst( TTO_ContextSubst* cs,
FT_Stream input );
FT_Error Load_ChainContextSubst( TTO_ChainContextSubst* ccs,
FT_Stream input );
void Free_SingleSubst( TTO_SingleSubst* ss,
FT_Memory memory );
void Free_MultipleSubst( TTO_MultipleSubst* ms,
FT_Memory memory );
void Free_AlternateSubst( TTO_AlternateSubst* as,
FT_Memory memory );
void Free_LigatureSubst( TTO_LigatureSubst* ls,
FT_Memory memory );
void Free_ContextSubst( TTO_ContextSubst* cs,
FT_Memory memory );
void Free_ChainContextSubst( TTO_ChainContextSubst* ccs,
FT_Memory memory );
/* functions from ftxgpos.c */
FT_Error Load_SinglePos( TTO_SinglePos* sp,
FT_Stream input );
FT_Error Load_PairPos( TTO_PairPos* pp,
FT_Stream input );
FT_Error Load_CursivePos( TTO_CursivePos* cp,
FT_Stream input );
FT_Error Load_MarkBasePos( TTO_MarkBasePos* mbp,
FT_Stream input );
FT_Error Load_MarkLigPos( TTO_MarkLigPos* mlp,
FT_Stream input );
FT_Error Load_MarkMarkPos( TTO_MarkMarkPos* mmp,
FT_Stream input );
FT_Error Load_ContextPos( TTO_ContextPos* cp,
FT_Stream input );
FT_Error Load_ChainContextPos( TTO_ChainContextPos* ccp,
FT_Stream input );
void Free_SinglePos( TTO_SinglePos* sp,
FT_Memory memory );
void Free_PairPos( TTO_PairPos* pp,
FT_Memory memory );
void Free_CursivePos( TTO_CursivePos* cp,
FT_Memory memory );
void Free_MarkBasePos( TTO_MarkBasePos* mbp,
FT_Memory memory );
void Free_MarkLigPos( TTO_MarkLigPos* mlp,
FT_Memory memory );
void Free_MarkMarkPos( TTO_MarkMarkPos* mmp,
FT_Memory memory );
void Free_ContextPos( TTO_ContextPos* cp,
FT_Memory memory );
void Free_ChainContextPos( TTO_ChainContextPos* ccp,
FT_Memory memory );
/* query functions */
FT_Error Coverage_Index( TTO_Coverage* c,
FT_UShort glyphID,
FT_UShort* index );
FT_Error Get_Class( TTO_ClassDefinition* cd,
FT_UShort glyphID,
FT_UShort* class,
FT_UShort* index );
FT_Error Get_Device( TTO_Device* d,
FT_UShort size,
FT_Short* value );
/* functions from ftxgdef.c */
FT_Error Add_Glyph_Property( TTO_GDEFHeader* gdef,
FT_UShort glyphID,
FT_UShort property );
FT_Error Check_Property( TTO_GDEFHeader* gdef,
FT_UShort index,
FT_UShort flags,
FT_UShort* property );
#define CHECK_Property( gdef, index, flags, property ) \
( ( error = Check_Property( (gdef), (index), (flags), \
(property) ) ) != TT_Err_Ok )
#ifdef __cplusplus
}
#endif
#endif /* FTXOPENF_H */
/* END */

265
src/ottest.c Normal file
View File

@ -0,0 +1,265 @@
/* Pango
* otttest.c: Test program 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 <stdio.h>
#include <stdlib.h>
#include "ftxopen.h"
#include <freetype/internal/ftmemory.h>
#include "disasm.h"
#define N_ELEMENTS(arr) (sizeof(arr)/ sizeof((arr)[0]))
int
croak (const char *situation, FT_Error error)
{
fprintf (stderr, "%s: Error %d\n", situation, error);
exit (1);
}
enum {
I = 1 << 0,
M = 1 << 1,
F = 1 << 2,
L = 1 << 3
};
void
print_tag (FT_ULong tag)
{
fprintf (stderr, "%c%c%c%c",
(unsigned char)(tag >> 24),
(unsigned char)((tag & 0xff0000) >> 16),
(unsigned char)((tag & 0xff00) >> 8),
(unsigned char)(tag & 0xff));
}
void
maybe_add_feature (TTO_GSUB gsub,
FT_UShort script_index,
FT_ULong tag,
FT_UShort property)
{
FT_Error error;
FT_UShort feature_index;
/* 0xffff == default language system */
error = TT_GSUB_Select_Feature (gsub, tag, script_index, 0xffff, &feature_index);
if (error)
{
if (error == TTO_Err_Not_Covered)
{
print_tag (tag);
fprintf (stderr, " not covered, ignored\n");
return;
}
croak ("TT_GSUB_Select_Feature", error);
}
if ((error = TT_GSUB_Add_Feature (gsub, feature_index, property)))
croak ("TT_GSUB_Add_Feature", error);
}
void
select_cmap (FT_Face face)
{
FT_UShort i;
FT_CharMap cmap = NULL;
for (i = 0; i < face->num_charmaps; i++)
{
if (face->charmaps[i]->platform_id == 3 && face->charmaps[i]->encoding_id == 1)
{
cmap = face->charmaps[i];
break;
}
}
/* we try only pid/eid (0,0) if no (3,1) map is found -- many Windows
fonts have only rudimentary (0,0) support. */
if (!cmap)
for (i = 0; i < face->num_charmaps; i++)
{
if (face->charmaps[i]->platform_id == 3 && face->charmaps[i]->encoding_id == 1)
{
cmap = face->charmaps[i];
break;
}
}
if (cmap)
FT_Set_Charmap (face, cmap);
else
{
fprintf (stderr, "Sorry, but this font doesn't contain"
" any Unicode mapping table.\n");
exit (1);
}
}
void
add_features (TTO_GSUB gsub)
{
FT_Error error;
FT_ULong tag = FT_MAKE_TAG ('a', 'r', 'a', 'b');
FT_UShort script_index;
error = TT_GSUB_Select_Script (gsub, tag, &script_index);
if (error)
{
if (error == TTO_Err_Not_Covered)
{
fprintf (stderr, "Arabic not covered, no features used\n");
return;
}
croak ("TT_GSUB_Select_Script", error);
}
maybe_add_feature (gsub, script_index, FT_MAKE_TAG ('i', 'n', 'i', 't'), I);
maybe_add_feature (gsub, script_index, FT_MAKE_TAG ('m', 'e', 'd', 'i'), M);
maybe_add_feature (gsub, script_index, FT_MAKE_TAG ('f', 'i', 'n', 'a'), F);
maybe_add_feature (gsub, script_index, FT_MAKE_TAG ('l', 'i', 'g', 'a'), L);
}
void
dump_string (TTO_GSUB_String *str)
{
int i;
fprintf (stderr, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
for (i = 0; i < str->length; i++)
{
fprintf (stderr, "%2d: %#06x %#06x %4d %4d\n",
i,
str->string[i],
str->properties[i],
str->components[i],
str->ligIDs[i]);
}
fprintf (stderr, "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
}
FT_UShort arabic_str[] = { 0x645, 0x643, 0x64a, 0x644, 0x639, 0x20, 0x645, 0x627, 0x644, 0x633, 0x644, 0x627 };
FT_UShort arabic_props[] = { I|L, M|L, M|L, M|L, M|L, F|L, I|L, M|L, M|L, M|L, M|L, F|L };
void
try_string (FT_Library library,
FT_Face face,
TTO_GSUB gsub)
{
FT_Error error;
TTO_GSUB_String *in_str;
TTO_GSUB_String *out_str;
int i;
if ((error = TT_GSUB_String_New (face->memory, &in_str)))
croak ("TT_GSUB_String_New", error);
if ((error = TT_GSUB_String_New (face->memory, &out_str)))
croak ("TT_GSUB_String_New", error);
if ((error = TT_GSUB_String_Set_Length (in_str, N_ELEMENTS (arabic_str))))
croak ("TT_GSUB_String_Set_Length", error);
for (i=0; i < N_ELEMENTS (arabic_str); i++)
{
in_str->string[i] = FT_Get_Char_Index (face, arabic_str[i]);
in_str->properties[i] = arabic_props[i];
in_str->components[i] = i;
in_str->ligIDs[i] = i;
}
if ((error = TT_GSUB_Apply_String (gsub, in_str, out_str)))
croak ("TT_GSUB_Apply_String", error);
dump_string (in_str);
dump_string (out_str);
if ((error = TT_GSUB_String_Done (in_str)))
croak ("TT_GSUB_String_New", error);
if ((error = TT_GSUB_String_Done (out_str)))
croak ("TT_GSUB_String_New", error);
}
int
main (int argc, char **argv)
{
FT_Error error;
FT_Library library;
FT_Face face;
TTO_GSUB gsub;
TTO_GPOS gpos;
if (argc != 2)
{
fprintf (stderr, "Usage: ottest MYFONT.TTF\n");
exit(1);
}
if ((error = FT_Init_FreeType (&library)))
croak ("FT_Init_FreeType", error);
if ((error = FT_New_Face (library, argv[1], 0, &face)))
croak ("FT_New_Face", error);
if (!(error = TT_Load_GSUB_Table (face, &gsub, NULL)))
{
TT_Dump_GSUB_Table (gsub, stdout);
if ((error = TT_Done_GSUB_Table (gsub)))
croak ("FT_Done_GSUB_Table", error);
}
else
fprintf (stderr, "TT_Load_GSUB_Table %d\n", error);
if (!(error = TT_Load_GPOS_Table (face, &gpos, NULL)))
{
TT_Dump_GPOS_Table (gpos, stdout);
if ((error = TT_Done_GPOS_Table (gpos)))
croak ("FT_Done_GPOS_Table", error);
}
else
fprintf (stderr, "TT_Load_GPOS_Table %d\n", error);
#if 0
select_cmap (face);
add_features (gsub);
try_string (library, face, gsub);
#endif
if ((error = FT_Done_Face (face)))
croak ("FT_Done_Face", error);
if ((error = FT_Done_FreeType (library)))
croak ("FT_Done_FreeType", error);
return 0;
}

438
src/pango-ot-info.c Normal file
View File

@ -0,0 +1,438 @@
/* 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 "pango-ot-private.h"
#include <freetype/internal/tterrors.h>
#include <freetype/internal/ftobjs.h>
#include <freetype/ftmodule.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 */
};
object_type = g_type_register_static (G_TYPE_OBJECT,
"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;
}
}
PangoOTInfo *
pango_ot_info_new (FT_Face face)
{
PangoOTInfo *info;
info = g_object_new (PANGO_TYPE_OT_INFO, NULL);
info->face = face;
return info;
}
/* There must be be a better way to do this
*/
static gboolean
is_truetype (FT_Face face)
{
return strcmp (FT_MODULE_CLASS (face->driver)->module_name, "truetype") == 0;
}
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);
}
}
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;
}
}
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}

98
src/pango-ot-private.h Normal file
View File

@ -0,0 +1,98 @@
/* 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 <freetype/freetype.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;
};
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__ */

232
src/pango-ot-ruleset.c Normal file
View File

@ -0,0 +1,232 @@
/* 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 <freetype/internal/ftmemory.h>
#include <pango/pango-ot.h>
#include "pango-ot-private.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,
};
object_type = g_type_register_static (G_TYPE_OBJECT,
"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 (G_OBJECT (ruleset->info));
}
PangoOTRuleset *
pango_ot_ruleset_new (PangoOTInfo *info)
{
PangoOTRuleset *ruleset;
ruleset = g_object_new (PANGO_TYPE_OT_RULESET, NULL);
ruleset->info = g_object_ref (G_OBJECT (info));
return 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);
}
void
pango_ot_ruleset_shape (PangoOTRuleset *ruleset,
PangoGlyphString *glyphs,
gulong *properties)
{
int i;
int last_cluster;
TTO_GSUB gsub = NULL;
TTO_GPOS gpos = NULL;
TTO_GSUB_String *in_string = NULL;
TTO_GSUB_String *out_string = NULL;
TTO_GSUB_String *result_string = NULL;
TTO_GPOS_Data *pos_data;
gboolean need_gsub = FALSE;
gboolean need_gpos = FALSE;
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)
need_gsub = TRUE;
else
need_gpos = TRUE;
}
if (need_gsub)
{
gsub = pango_ot_info_get_gsub (ruleset->info);
if (gsub)
TT_GSUB_Clear_Features (gsub);
}
if (need_gpos)
{
gpos = pango_ot_info_get_gpos (ruleset->info);
if (gpos)
TT_GPOS_Clear_Features (gpos);
}
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)
{
if (gsub)
TT_GSUB_Add_Feature (gsub, rule->feature_index, rule->property_bit);
}
else
{
if (gpos)
TT_GPOS_Add_Feature (gpos, rule->feature_index, rule->property_bit);
}
}
if (!gsub && !gpos)
return;
g_assert (TT_GSUB_String_New (ruleset->info->face->memory,
&in_string) == FT_Err_Ok);
g_assert (TT_GSUB_String_Set_Length (in_string, glyphs->num_glyphs) == FT_Err_Ok);
for (i = 0; i < glyphs->num_glyphs; i++)
{
in_string->string[i] = glyphs->glyphs[i].glyph;
in_string->properties[i] = properties[i];
in_string->logClusters[i] = glyphs->log_clusters[i];
}
in_string->max_ligID = i;
if (gsub)
{
g_assert (TT_GSUB_String_New (ruleset->info->face->memory,
&out_string) == FT_Err_Ok);
result_string = out_string;
TT_GSUB_Apply_String (gsub, in_string, out_string);
}
else
result_string = in_string;
pango_glyph_string_set_size (glyphs, result_string->length);
last_cluster = -1;
for (i = 0; i < result_string->length; i++)
{
glyphs->glyphs[i].glyph = result_string->string[i];
glyphs->glyphs[i].glyph = result_string->string[i];
glyphs->log_clusters[i] = result_string->logClusters[i];
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];
}
if (in_string)
TT_GSUB_String_Done (in_string);
if (out_string)
TT_GSUB_String_Done (out_string);
}