git-svn-id: http://skia.googlecode.com/svn/trunk@536 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
reed@android.com 2010-04-08 18:48:12 +00:00
parent a4e5ed854a
commit 5469607a00
88 changed files with 40830 additions and 0 deletions

20
third_party/harfbuzz/.gitignore vendored Normal file
View File

@ -0,0 +1,20 @@
INSTALL
Makefile.in
aclocal.m4
autom4te.cache
config.guess
config.h.in
config.sub
config.h
configure
depcomp
install-sh
ltmain.sh
missing
Makefile
config.status
config.log
libtool
stamp-h1
compile
build

6
third_party/harfbuzz/AUTHORS vendored Normal file
View File

@ -0,0 +1,6 @@
David Turner
Werner Lemberg
Owen Taylor
Behdad Esfahbod
Lars Knoll
Simon Hausmann

24
third_party/harfbuzz/COPYING vendored Normal file
View File

@ -0,0 +1,24 @@
HarfBuzz was previously licensed under different licenses. This was
changed in January 2008. If you need to relicense your old copies,
consult the announcement of the license change on the internet.
Other than that, each copy of HarfBuzz is licensed under the COPYING
file included with it. The actual license follows:
Permission is hereby granted, without written agreement and without
license or royalty fees, to use, copy, modify, and distribute this
software and its documentation for any purpose, provided that the
above copyright notice and the following two paragraphs appear in
all copies of this software.
IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

0
third_party/harfbuzz/ChangeLog vendored Normal file
View File

2
third_party/harfbuzz/Makefile.am vendored Normal file
View File

@ -0,0 +1,2 @@
SUBDIRS = src tests

0
third_party/harfbuzz/NEWS vendored Normal file
View File

7
third_party/harfbuzz/README vendored Normal file
View File

@ -0,0 +1,7 @@
This is HarfBuzz, an OpenType Layout engine library.
To report bugs or post to discussion mailing list, see:
http://freedesktop.org/wiki/Software/HarfBuzz
For license information, see the file COPYING.

9
third_party/harfbuzz/README.google vendored Normal file
View File

@ -0,0 +1,9 @@
Harfbuzz
http://freedesktop.org/wiki/Software/HarfBuzz
This code was taken from b0d396aa88b3cdf8cea896bfeeba197656e1cdb1
(git://anongit.freedesktop.org/harfbuzz)
The patch in chromium.patch was applied on top of this; I will talk with
upstream about it.

116
third_party/harfbuzz/autogen.sh vendored Executable file
View File

@ -0,0 +1,116 @@
#!/bin/sh
# Run this to generate all the initial makefiles, etc.
set -e
srcdir=`dirname $0`
test -z "$srcdir" && srcdir=.
ORIGDIR=`pwd`
cd $srcdir
PROJECT=harfbuzz
TEST_TYPE=-f
FILE=src/harfbuzz.h
ACLOCAL=${ACLOCAL-aclocal}
LIBTOOLIZE=${LIBTOOLIZE-libtoolize}
AUTOMAKE=${AUTOMAKE-automake}
AUTOHEADER=${AUTOHEADER-autoheader}
AUTOCONF=${AUTOCONF-autoconf}
LIBTOOLIZE_FLAGS="--copy --force"
DIE=0
have_libtool=false
if $LIBTOOLIZE --version < /dev/null > /dev/null 2>&1 ; then
libtool_version=`$LIBTOOLIZE --version | sed 's/^[^0-9]*\([0-9].[0-9.]*\).*/\1/'`
case $libtool_version in
1.4*|1.5*|1.6*|1.7*|2*)
have_libtool=true
;;
esac
fi
if $have_libtool ; then : ; else
echo
echo "You must have libtool 1.4 installed to compile $PROJECT."
echo "Install the appropriate package for your distribution,"
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
DIE=1
fi
($AUTOCONF --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "You must have autoconf installed to compile $PROJECT."
echo "libtool the appropriate package for your distribution,"
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
DIE=1
}
have_automake=false
need_libtoolize=true
if $AUTOMAKE --version < /dev/null > /dev/null 2>&1 ; then
automake_version=`$AUTOMAKE --version | grep 'automake (GNU automake)' | sed 's/^[^0-9]*\(.*\)/\1/'`
case $automake_version in
1.2*|1.3*|1.4)
;;
1.4*)
have_automake=true
need_libtoolize=false
;;
*)
have_automake=true
;;
esac
fi
if $have_automake ; then : ; else
echo
echo "You must have automake 1.4-p1 installed to compile $PROJECT."
echo "Get ftp://ftp.gnu.org/pub/gnu/automake/automake-1.4-p1.tar.gz"
echo "(or a newer version if it is available)"
DIE=1
fi
if test "$DIE" -eq 1; then
exit 1
fi
test $TEST_TYPE $FILE || {
echo "You must run this script in the top-level $PROJECT directory"
exit 1
}
if test -z "$AUTOGEN_SUBDIR_MODE"; then
if test -z "$*"; then
echo "I am going to run ./configure with no arguments - if you wish "
echo "to pass any to it, please specify them on the $0 command line."
fi
fi
echo Running $ACLOCAL $ACLOCAL_FLAGS
$ACLOCAL $ACLOCAL_FLAGS
# optionally run autoheader
if $AUTOHEADER --version < /dev/null > /dev/null 2>&1; then
echo Running $AUTOHEADER
$AUTOHEADER
fi
case $need_libtoolize in
true)
echo Running $LIBTOOLIZE $LIBTOOLIZE_FLAGS
$LIBTOOLIZE $LIBTOOLIZE_FLAGS
;;
esac
echo Running $AUTOMAKE -a $am_opt
$AUTOMAKE -a $am_opt
echo Running $AUTOCONF
$AUTOCONF
cd $ORIGDIR
if test -z "$AUTOGEN_SUBDIR_MODE"; then
echo Running $srcdir/configure "$@"
$srcdir/configure "$@"
echo
echo "Now type 'make' to compile $PROJECT."
fi

37
third_party/harfbuzz/chromium.patch vendored Normal file
View File

@ -0,0 +1,37 @@
diff --git a/contrib/harfbuzz-unicode.c b/contrib/harfbuzz-unicode.c
index 51dd4ea..cb7a85b 100644
--- a/contrib/harfbuzz-unicode.c
+++ b/contrib/harfbuzz-unicode.c
@@ -171,7 +171,10 @@ hb_utf16_script_run_prev(unsigned *num_code_points, HB_ScriptItem *output,
current_script = script;
continue;
} else if (script == HB_Script_Inherited) {
- current_script = script;
+ // Just assume that whatever follows this combining character is within
+ // the same script. This is incorrect if you had language1 + combining
+ // char + language 2, but that is rare and this code is suspicious
+ // anyway.
continue;
} else {
*iter = prev_iter;
diff --git a/src/harfbuzz-shaper.cpp b/src/harfbuzz-shaper.cpp
index f3ec8e1..2b0dfde 100644
--- a/src/harfbuzz-shaper.cpp
+++ b/src/harfbuzz-shaper.cpp
@@ -433,7 +433,7 @@ void HB_HeuristicSetGlyphAttributes(HB_ShaperItem *item)
// ### zeroWidth and justification are missing here!!!!!
- assert(item->num_glyphs <= length);
+ assert(length <= item->num_glyphs);
// qDebug("QScriptEngine::heuristicSetGlyphAttributes, num_glyphs=%d", item->num_glyphs);
HB_GlyphAttributes *attributes = item->attributes;
@@ -451,7 +451,6 @@ void HB_HeuristicSetGlyphAttributes(HB_ShaperItem *item)
}
++glyph_pos;
}
- assert(glyph_pos == item->num_glyphs);
// first char in a run is never (treated as) a mark
int cStart = 0;

60
third_party/harfbuzz/config.h vendored Normal file
View File

@ -0,0 +1,60 @@
/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#define LT_OBJDIR ".libs/"
/* Name of package */
#define PACKAGE "harfbuzz"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT ""
/* Define to the full name of this package. */
#define PACKAGE_NAME ""
/* Define to the full name and version of this package. */
#define PACKAGE_STRING ""
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME ""
/* Define to the version of this package. */
#define PACKAGE_VERSION ""
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Version number of package */
#define VERSION "0.1"

54
third_party/harfbuzz/configure.ac vendored Normal file
View File

@ -0,0 +1,54 @@
AC_INIT(README)
AM_INIT_AUTOMAKE(harfbuzz, 0.1)
AC_PROG_CC
AC_PROG_CXX
AM_PROG_LIBTOOL
PKG_PROG_PKG_CONFIG
AM_CONFIG_HEADER(config.h)
if test "x$ac_compiler_gnu" = xyes; then
CFLAGS="$CFLAGS -Wall -W -pedantic -ansi"
CXXFLAGS="$CXXFLAGS -Wall -W"
fi
AC_PATH_PROG(ft_config,freetype-config,no)
if test "$ft_config" = "no"; then
AC_MSG_ERROR([You must have freetype installed; see http://www.freetype.org/])
fi
FREETYPE_CFLAGS="`$ft_config --cflags`"
FREETYPE_LIBS="`$ft_config --libs`"
AC_SUBST(FREETYPE_LIBS)
AC_SUBST(FREETYPE_CFLAGS)
AC_ARG_ENABLE(qt, AS_HELP_STRING([--disable-qt], [Build Qt support (default: auto)]), [QT=$enableval], [QT=auto])
if test "x$QT" = xauto; then
PKG_CHECK_MODULES(QT, [QtGui >= 4.3], [QT=yes], [QT=no])
fi
if test "x$QT" = xyes; then
PKG_CHECK_MODULES(QT_GUI, [QtGui >= 4.3])
PKG_CHECK_MODULES(QT_QTEST, [QtTest >= 4.3])
_PKG_CONFIG(QT_INCDIR, [variable=includedir], [QtGui >= 4.3])
QT_GUI_CFLAGS="$QT_GUI_CFLAGS -I$pkg_cv_QT_INCDIR/../Qt"
AC_SUBST(QT_GUI_CFLAGS)
AC_SUBST(QT_GUI_LIBS)
AC_SUBST(QT_QTEST_CFLAGS)
AC_SUBST(QT_QTEST_LIBS)
_PKG_CONFIG(QT_MOC, [variable=moc_location], [QtGui >= 4.3])
QT_MOC=$pkg_cv_QT_MOC
AC_SUBST(QT_MOC)
fi
AM_CONDITIONAL(QT, [test "x$QT" = xyes])
AC_OUTPUT([
Makefile
src/Makefile
tests/Makefile
tests/linebreaking/Makefile
tests/shaping/Makefile
])

9
third_party/harfbuzz/contrib/README vendored Normal file
View File

@ -0,0 +1,9 @@
Harfbuzz requires several functions to be defined in order to work with the
platform's Unicode tables etc.
If you are building on top of Qt4 you should look at the code in the tests/
directory for examples of how to hook up Qt4 functions to Harfbuzz.
Otherwise, this directory contains examples of using downloaded Unicode tables
and/or glib to host Harfbuzz. You should read the README file in tables/ for how
to build the header files for some of the Unicode tables.

View File

@ -0,0 +1,149 @@
#include <stdint.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_TRUETYPE_TABLES_H
#if 0
#include <freetype/freetype.h>
#include <freetype/tttables.h>
#endif
#include <harfbuzz-shaper.h>
#include "harfbuzz-unicode.h"
static HB_Bool
hb_freetype_string_to_glyphs(HB_Font font,
const HB_UChar16 *chars, hb_uint32 len,
HB_Glyph *glyphs, hb_uint32 *numGlyphs,
HB_Bool is_rtl) {
FT_Face face = (FT_Face) font->userData;
if (len > *numGlyphs)
return 0;
size_t i = 0, j = 0;
while (i < len) {
const uint32_t cp = utf16_to_code_point(chars, len, &i);
glyphs[j++] = FT_Get_Char_Index(face, cp);
}
*numGlyphs = j;
return 1;
}
static void
hb_freetype_advances_get(HB_Font font, const HB_Glyph *glyphs, hb_uint32 len,
HB_Fixed *advances, int flags) {
FT_Face face = (FT_Face) font->userData;
hb_uint32 i;
for (i = 0; i < len; ++i) {
const FT_Error error = FT_Load_Glyph(face, glyphs[i], FT_LOAD_DEFAULT);
if (error) {
advances[i] = 0;
continue;
}
advances[i] = face->glyph->advance.x;
}
}
static HB_Bool
hb_freetype_can_render(HB_Font font, const HB_UChar16 *chars, hb_uint32 len) {
FT_Face face = (FT_Face)font->userData;
size_t i = 0;
while (i < len) {
const uint32_t cp = utf16_to_code_point(chars, len, &i);
if (FT_Get_Char_Index(face, cp) == 0)
return 0;
}
return 1;
}
static HB_Error
hb_freetype_outline_point_get(HB_Font font, HB_Glyph glyph, int flags,
hb_uint32 point, HB_Fixed *xpos, HB_Fixed *ypos,
hb_uint32 *n_points) {
HB_Error error = HB_Err_Ok;
FT_Face face = (FT_Face) font->userData;
int load_flags = (flags & HB_ShaperFlag_UseDesignMetrics) ? FT_LOAD_NO_HINTING : FT_LOAD_DEFAULT;
if ((error = (HB_Error) FT_Load_Glyph(face, glyph, load_flags)))
return error;
if (face->glyph->format != ft_glyph_format_outline)
return (HB_Error)HB_Err_Invalid_SubTable;
*n_points = face->glyph->outline.n_points;
if (!(*n_points))
return HB_Err_Ok;
if (point > *n_points)
return (HB_Error)HB_Err_Invalid_SubTable;
*xpos = face->glyph->outline.points[point].x;
*ypos = face->glyph->outline.points[point].y;
return HB_Err_Ok;
}
static void
hb_freetype_glyph_metrics_get(HB_Font font, HB_Glyph glyph,
HB_GlyphMetrics *metrics) {
FT_Face face = (FT_Face) font->userData;
const FT_Error error = FT_Load_Glyph(face, glyph, FT_LOAD_DEFAULT);
if (error) {
metrics->x = metrics->y = metrics->width = metrics->height = 0;
metrics->xOffset = metrics->yOffset = 0;
return;
}
const FT_Glyph_Metrics *ftmetrics = &face->glyph->metrics;
metrics->width = ftmetrics->width;
metrics->height = ftmetrics->height;
metrics->x = ftmetrics->horiAdvance;
metrics->y = 0; // unclear what this is
metrics->xOffset = ftmetrics->horiBearingX;
metrics->yOffset = ftmetrics->horiBearingY;
}
static HB_Fixed
hb_freetype_font_metric_get(HB_Font font, HB_FontMetric metric) {
FT_Face face = (FT_Face) font->userData;
switch (metric) {
case HB_FontAscent:
// Note that we aren't scanning the VDMX table which we probably would in
// an ideal world.
return face->ascender;
default:
return 0;
}
}
const HB_FontClass hb_freetype_class = {
hb_freetype_string_to_glyphs,
hb_freetype_advances_get,
hb_freetype_can_render,
hb_freetype_outline_point_get,
hb_freetype_glyph_metrics_get,
hb_freetype_font_metric_get,
};
HB_Error
hb_freetype_table_sfnt_get(void *voidface, const HB_Tag tag, HB_Byte *buffer, HB_UInt *len) {
FT_Face face = (FT_Face) voidface;
FT_ULong ftlen = *len;
if (!FT_IS_SFNT(face))
return HB_Err_Invalid_Argument;
const FT_Error error = FT_Load_Sfnt_Table(face, tag, 0, buffer, &ftlen);
*len = ftlen;
return (HB_Error) error;
}

View File

@ -0,0 +1,9 @@
#ifndef HB_FREETYPE_H_
#define HB_FREETYPE_H_
extern const HB_FontClass hb_freetype_class;
HB_Error hb_freetype_table_sfnt_get(void *voidface, const HB_Tag tag,
HB_Byte *buffer, HB_UInt *len);
#endif // HB_FREETYPE_H_

View File

@ -0,0 +1,169 @@
#include "harfbuzz-external.h"
#include <glib.h>
static int
hb_category_for_char(HB_UChar32 ch) {
switch (g_unichar_type(ch)) {
case G_UNICODE_CONTROL:
return HB_Other_Control;
case G_UNICODE_FORMAT:
return HB_Other_Format;
case G_UNICODE_UNASSIGNED:
return HB_Other_NotAssigned;
case G_UNICODE_PRIVATE_USE:
return HB_Other_PrivateUse;
case G_UNICODE_SURROGATE:
return HB_Other_Surrogate;
case G_UNICODE_LOWERCASE_LETTER:
return HB_Letter_Lowercase;
case G_UNICODE_MODIFIER_LETTER:
return HB_Letter_Modifier;
case G_UNICODE_OTHER_LETTER:
return HB_Letter_Other;
case G_UNICODE_TITLECASE_LETTER:
return HB_Letter_Titlecase;
case G_UNICODE_UPPERCASE_LETTER:
return HB_Letter_Uppercase;
case G_UNICODE_COMBINING_MARK:
return HB_Mark_SpacingCombining;
case G_UNICODE_ENCLOSING_MARK:
return HB_Mark_Enclosing;
case G_UNICODE_NON_SPACING_MARK:
return HB_Mark_NonSpacing;
case G_UNICODE_DECIMAL_NUMBER:
return HB_Number_DecimalDigit;
case G_UNICODE_LETTER_NUMBER:
return HB_Number_Letter;
case G_UNICODE_OTHER_NUMBER:
return HB_Number_Other;
case G_UNICODE_CONNECT_PUNCTUATION:
return HB_Punctuation_Connector;
case G_UNICODE_DASH_PUNCTUATION:
return HB_Punctuation_Dash;
case G_UNICODE_CLOSE_PUNCTUATION:
return HB_Punctuation_Close;
case G_UNICODE_FINAL_PUNCTUATION:
return HB_Punctuation_FinalQuote;
case G_UNICODE_INITIAL_PUNCTUATION:
return HB_Punctuation_InitialQuote;
case G_UNICODE_OTHER_PUNCTUATION:
return HB_Punctuation_Other;
case G_UNICODE_OPEN_PUNCTUATION:
return HB_Punctuation_Open;
case G_UNICODE_CURRENCY_SYMBOL:
return HB_Symbol_Currency;
case G_UNICODE_MODIFIER_SYMBOL:
return HB_Symbol_Modifier;
case G_UNICODE_MATH_SYMBOL:
return HB_Symbol_Math;
case G_UNICODE_OTHER_SYMBOL:
return HB_Symbol_Other;
case G_UNICODE_LINE_SEPARATOR:
return HB_Separator_Line;
case G_UNICODE_PARAGRAPH_SEPARATOR:
return HB_Separator_Paragraph;
case G_UNICODE_SPACE_SEPARATOR:
return HB_Separator_Space;
default:
return HB_Symbol_Other;
}
}
HB_LineBreakClass
HB_GetLineBreakClass(HB_UChar32 ch) {
switch (g_unichar_break_type(ch)) {
case G_UNICODE_BREAK_MANDATORY:
return HB_LineBreak_BK;
case G_UNICODE_BREAK_CARRIAGE_RETURN:
return HB_LineBreak_CR;
case G_UNICODE_BREAK_LINE_FEED:
return HB_LineBreak_LF;
case G_UNICODE_BREAK_COMBINING_MARK:
return HB_LineBreak_CM;
case G_UNICODE_BREAK_SURROGATE:
return HB_LineBreak_SG;
case G_UNICODE_BREAK_ZERO_WIDTH_SPACE:
return HB_LineBreak_ZW;
case G_UNICODE_BREAK_INSEPARABLE:
return HB_LineBreak_IN;
case G_UNICODE_BREAK_NON_BREAKING_GLUE:
return HB_LineBreak_GL;
case G_UNICODE_BREAK_CONTINGENT:
return HB_LineBreak_AL;
case G_UNICODE_BREAK_SPACE:
return HB_LineBreak_SP;
case G_UNICODE_BREAK_AFTER:
return HB_LineBreak_BA;
case G_UNICODE_BREAK_BEFORE:
return HB_LineBreak_BB;
case G_UNICODE_BREAK_BEFORE_AND_AFTER:
return HB_LineBreak_B2;
case G_UNICODE_BREAK_HYPHEN:
return HB_LineBreak_HY;
case G_UNICODE_BREAK_NON_STARTER:
return HB_LineBreak_NS;
case G_UNICODE_BREAK_OPEN_PUNCTUATION:
return HB_LineBreak_OP;
case G_UNICODE_BREAK_CLOSE_PUNCTUATION:
return HB_LineBreak_CL;
case G_UNICODE_BREAK_QUOTATION:
return HB_LineBreak_QU;
case G_UNICODE_BREAK_EXCLAMATION:
return HB_LineBreak_EX;
case G_UNICODE_BREAK_IDEOGRAPHIC:
return HB_LineBreak_ID;
case G_UNICODE_BREAK_NUMERIC:
return HB_LineBreak_NU;
case G_UNICODE_BREAK_INFIX_SEPARATOR:
return HB_LineBreak_IS;
case G_UNICODE_BREAK_SYMBOL:
return HB_LineBreak_SY;
case G_UNICODE_BREAK_ALPHABETIC:
return HB_LineBreak_AL;
case G_UNICODE_BREAK_PREFIX:
return HB_LineBreak_PR;
case G_UNICODE_BREAK_POSTFIX:
return HB_LineBreak_PO;
case G_UNICODE_BREAK_COMPLEX_CONTEXT:
return HB_LineBreak_SA;
case G_UNICODE_BREAK_AMBIGUOUS:
return HB_LineBreak_AL;
case G_UNICODE_BREAK_UNKNOWN:
return HB_LineBreak_AL;
case G_UNICODE_BREAK_NEXT_LINE:
return HB_LineBreak_AL;
case G_UNICODE_BREAK_WORD_JOINER:
return HB_LineBreak_WJ;
case G_UNICODE_BREAK_HANGUL_L_JAMO:
return HB_LineBreak_JL;
case G_UNICODE_BREAK_HANGUL_V_JAMO:
return HB_LineBreak_JV;
case G_UNICODE_BREAK_HANGUL_T_JAMO:
return HB_LineBreak_JT;
case G_UNICODE_BREAK_HANGUL_LV_SYLLABLE:
return HB_LineBreak_H2;
case G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE:
return HB_LineBreak_H3;
default:
return HB_LineBreak_AL;
}
}
int
HB_GetUnicodeCharCombiningClass(HB_UChar32 ch) {
return g_unichar_combining_class(ch);
}
void
HB_GetUnicodeCharProperties(HB_UChar32 ch,
HB_CharCategory *category,
int *combiningClass) {
*category = hb_category_for_char(ch);
*combiningClass = g_unichar_combining_class(ch);
}
HB_CharCategory
HB_GetUnicodeCharCategory(HB_UChar32 ch) {
return hb_category_for_char(ch);
}

View File

@ -0,0 +1,84 @@
#include <stdlib.h>
#include <stdint.h>
#include <harfbuzz-external.h>
#include "tables/category-properties.h"
#include "tables/combining-properties.h"
HB_LineBreakClass
HB_GetLineBreakClass(HB_UChar32 ch) {
abort();
return 0;
}
static int
combining_property_cmp(const void *vkey, const void *vcandidate) {
const uint32_t key = (uint32_t) (intptr_t) vkey;
const struct combining_property *candidate = vcandidate;
if (key < candidate->range_start) {
return -1;
} else if (key > candidate->range_end) {
return 1;
} else {
return 0;
}
}
static int
code_point_to_combining_class(HB_UChar32 cp) {
const void *vprop = bsearch((void *) (intptr_t) cp, combining_properties,
combining_properties_count,
sizeof(struct combining_property),
combining_property_cmp);
if (!vprop)
return 0;
return ((const struct combining_property *) vprop)->klass;
}
int
HB_GetUnicodeCharCombiningClass(HB_UChar32 ch) {
return code_point_to_combining_class(ch);
return 0;
}
static int
category_property_cmp(const void *vkey, const void *vcandidate) {
const uint32_t key = (uint32_t) (intptr_t) vkey;
const struct category_property *candidate = vcandidate;
if (key < candidate->range_start) {
return -1;
} else if (key > candidate->range_end) {
return 1;
} else {
return 0;
}
}
static HB_CharCategory
code_point_to_category(HB_UChar32 cp) {
const void *vprop = bsearch((void *) (intptr_t) cp, category_properties,
category_properties_count,
sizeof(struct category_property),
category_property_cmp);
if (!vprop)
return HB_NoCategory;
return ((const struct category_property *) vprop)->category;
}
void
HB_GetUnicodeCharProperties(HB_UChar32 ch,
HB_CharCategory *category,
int *combiningClass) {
*category = code_point_to_category(ch);
*combiningClass = code_point_to_combining_class(ch);
}
HB_CharCategory
HB_GetUnicodeCharCategory(HB_UChar32 ch) {
return code_point_to_category(ch);
}

View File

@ -0,0 +1,287 @@
#include <stdint.h>
#include <stdlib.h>
#include <harfbuzz-external.h>
#include <harfbuzz-impl.h>
#include <harfbuzz-shaper.h>
#include "harfbuzz-unicode.h"
#include "tables/grapheme-break-properties.h"
#include "tables/mirroring-properties.h"
#include "tables/script-properties.h"
uint32_t
utf16_to_code_point(const uint16_t *chars, size_t len, ssize_t *iter) {
const uint16_t v = chars[(*iter)++];
if (HB_IsHighSurrogate(v)) {
// surrogate pair
if (*iter >= len) {
// the surrogate is incomplete.
return HB_InvalidCodePoint;
}
const uint16_t v2 = chars[(*iter)++];
if (!HB_IsLowSurrogate(v2)) {
// invalidate surrogate pair.
return HB_InvalidCodePoint;
}
return HB_SurrogateToUcs4(v, v2);
}
if (HB_IsLowSurrogate(v)) {
// this isn't a valid code point
return HB_InvalidCodePoint;
}
return v;
}
uint32_t
utf16_to_code_point_prev(const uint16_t *chars, size_t len, ssize_t *iter) {
const uint16_t v = chars[(*iter)--];
if (HB_IsLowSurrogate(v)) {
// surrogate pair
if (*iter < 0) {
// the surrogate is incomplete.
return HB_InvalidCodePoint;
}
const uint16_t v2 = chars[(*iter)--];
if (!HB_IsHighSurrogate(v2)) {
// invalidate surrogate pair.
return HB_InvalidCodePoint;
}
return HB_SurrogateToUcs4(v2, v);
}
if (HB_IsHighSurrogate(v)) {
// this isn't a valid code point
return HB_InvalidCodePoint;
}
return v;
}
static int
script_property_cmp(const void *vkey, const void *vcandidate) {
const uint32_t key = (uint32_t) (intptr_t) vkey;
const struct script_property *candidate = vcandidate;
if (key < candidate->range_start) {
return -1;
} else if (key > candidate->range_end) {
return 1;
} else {
return 0;
}
}
HB_Script
code_point_to_script(uint32_t cp) {
const void *vprop = bsearch((void *) (intptr_t) cp, script_properties,
script_properties_count,
sizeof(struct script_property),
script_property_cmp);
if (!vprop)
return HB_Script_Common;
return ((const struct script_property *) vprop)->script;
}
char
hb_utf16_script_run_next(unsigned *num_code_points, HB_ScriptItem *output,
const uint16_t *chars, size_t len, ssize_t *iter) {
if (*iter == len)
return 0;
output->pos = *iter;
const uint32_t init_cp = utf16_to_code_point(chars, len, iter);
unsigned cps = 1;
if (init_cp == HB_InvalidCodePoint)
return 0;
const HB_Script init_script = code_point_to_script(init_cp);
HB_Script current_script = init_script;
output->script = init_script;
for (;;) {
if (*iter == len)
break;
const ssize_t prev_iter = *iter;
const uint32_t cp = utf16_to_code_point(chars, len, iter);
if (cp == HB_InvalidCodePoint)
return 0;
cps++;
const HB_Script script = code_point_to_script(cp);
if (script != current_script) {
if (current_script == init_script == HB_Script_Inherited) {
// If we started off as inherited, we take whatever we can find.
output->script = script;
current_script = script;
continue;
} else if (script == HB_Script_Inherited) {
continue;
} else {
*iter = prev_iter;
cps--;
break;
}
}
}
if (output->script == HB_Script_Inherited)
output->script = HB_Script_Common;
output->length = *iter - output->pos;
if (num_code_points)
*num_code_points = cps;
return 1;
}
char
hb_utf16_script_run_prev(unsigned *num_code_points, HB_ScriptItem *output,
const uint16_t *chars, size_t len, ssize_t *iter) {
if (*iter == (size_t) -1)
return 0;
const size_t ending_index = *iter;
const uint32_t init_cp = utf16_to_code_point_prev(chars, len, iter);
unsigned cps = 1;
if (init_cp == HB_InvalidCodePoint)
return 0;
const HB_Script init_script = code_point_to_script(init_cp);
HB_Script current_script = init_script;
output->script = init_script;
for (;;) {
if (*iter < 0)
break;
const ssize_t prev_iter = *iter;
const uint32_t cp = utf16_to_code_point_prev(chars, len, iter);
if (cp == HB_InvalidCodePoint)
return 0;
cps++;
const HB_Script script = code_point_to_script(cp);
if (script != current_script) {
if (current_script == init_script == HB_Script_Inherited) {
// If we started off as inherited, we take whatever we can find.
output->script = script;
current_script = script;
continue;
} else if (script == HB_Script_Inherited) {
// Just assume that whatever follows this combining character is within
// the same script. This is incorrect if you had language1 + combining
// char + language 2, but that is rare and this code is suspicious
// anyway.
continue;
} else {
*iter = prev_iter;
cps--;
break;
}
}
}
if (output->script == HB_Script_Inherited)
output->script = HB_Script_Common;
output->pos = *iter + 1;
output->length = ending_index - *iter;
if (num_code_points)
*num_code_points = cps;
return 1;
}
static int
grapheme_break_property_cmp(const void *vkey, const void *vcandidate) {
const uint32_t key = (uint32_t) (intptr_t) vkey;
const struct grapheme_break_property *candidate = vcandidate;
if (key < candidate->range_start) {
return -1;
} else if (key > candidate->range_end) {
return 1;
} else {
return 0;
}
}
HB_GraphemeClass
HB_GetGraphemeClass(HB_UChar32 ch) {
const void *vprop = bsearch((void *) (intptr_t) ch, grapheme_break_properties,
grapheme_break_properties_count,
sizeof(struct grapheme_break_property),
grapheme_break_property_cmp);
if (!vprop)
return HB_Grapheme_Other;
return ((const struct grapheme_break_property *) vprop)->klass;
}
HB_WordClass
HB_GetWordClass(HB_UChar32 ch) {
abort();
return 0;
}
HB_SentenceClass
HB_GetSentenceClass(HB_UChar32 ch) {
abort();
return 0;
}
void
HB_GetGraphemeAndLineBreakClass(HB_UChar32 ch, HB_GraphemeClass *gclass, HB_LineBreakClass *breakclass) {
*gclass = HB_GetGraphemeClass(ch);
*breakclass = HB_GetLineBreakClass(ch);
}
static int
mirroring_property_cmp(const void *vkey, const void *vcandidate) {
const uint32_t key = (uint32_t) (intptr_t) vkey;
const struct mirroring_property *candidate = vcandidate;
if (key < candidate->a) {
return -1;
} else if (key > candidate->a) {
return 1;
} else {
return 0;
}
}
HB_UChar16
HB_GetMirroredChar(HB_UChar16 ch) {
const void *mprop = bsearch((void *) (intptr_t) ch, mirroring_properties,
mirroring_properties_count,
sizeof(struct mirroring_property),
mirroring_property_cmp);
if (!mprop)
return ch;
return ((const struct mirroring_property *) mprop)->b;
}
void *
HB_Library_Resolve(const char *library, const char *symbol) {
abort();
return NULL;
}
void *
HB_TextCodecForMib(int mib) {
abort();
return NULL;
}
char *
HB_TextCodec_ConvertFromUnicode(void *codec, const HB_UChar16 *unicode, hb_uint32 length, hb_uint32 *outputLength) {
abort();
return NULL;
}
void
HB_TextCodec_FreeResult(char *v) {
abort();
}

View File

@ -0,0 +1,54 @@
#ifndef SCRIPT_IDENTIFY_H_
#define SCRIPT_IDENTIFY_H_
#include <stdint.h>
#include <harfbuzz-shaper.h>
static const uint32_t HB_InvalidCodePoint = 0xffffffffu;
// -----------------------------------------------------------------------------
// Return the next Unicode code point from a UTF-16 vector
// chars: a pointer to @len words
// iter: (input/output) an index into @chars. This is updated.
// returns: HB_InvalidCodePoint on error and the code point otherwise.
// -----------------------------------------------------------------------------
uint32_t utf16_to_code_point(const uint16_t *chars, size_t len, ssize_t *iter);
// -----------------------------------------------------------------------------
// Like the above, except that the code points are traversed backwards. Thus,
// on the first call, |iter| should be |len| - 1.
// -----------------------------------------------------------------------------
uint32_t utf16_to_code_point(const uint16_t *chars, size_t len, ssize_t *iter);
// -----------------------------------------------------------------------------
// Return the script of the given code point
// -----------------------------------------------------------------------------
HB_Script code_point_to_script(uint32_t cp);
// -----------------------------------------------------------------------------
// Find the next script run in a UTF-16 string.
//
// A script run is a subvector of codepoints, all of which are in the same
// script. A run will never cut a surrogate pair in half at either end.
//
// num_code_points: (output, maybe NULL) the number of code points in the run
// output: (output) the @pos, @length and @script fields are set on success
// chars: the UTF-16 string
// len: the length of @chars, in words
// iter: (in/out) the current index into the string. This should be 0 for the
// first call and is updated on exit.
//
// returns: non-zero if a script run was found and returned.
// -----------------------------------------------------------------------------
char hb_utf16_script_run_next(unsigned *num_code_points, HB_ScriptItem *output,
const uint16_t *chars, size_t len, ssize_t *iter);
// -----------------------------------------------------------------------------
// This is the same as above, except that the input is traversed backwards.
// Thus, on the first call, |iter| should be |len| - 1.
// -----------------------------------------------------------------------------
char hb_utf16_script_run_prev(unsigned *num_code_points, HB_ScriptItem *output,
const uint16_t *chars, size_t len, ssize_t *iter);
#endif

View File

@ -0,0 +1,588 @@
# BidiMirroring-5.1.0.txt
# Date: 2008-03-28, 10:22:00 PDT [KW]
#
# Bidi_Mirroring_Glyph Property
#
# This file is an informative contributory data file in the
# Unicode Character Database.
#
# Copyright (c) 1991-2008 Unicode, Inc.
# For terms of use, see http://www.unicode.org/terms_of_use.html
#
# This data file lists characters that have the mirrored property
# where there is another Unicode character that typically has a glyph
# that is the mirror image of the original character's glyph.
# The repertoire covered by the file is Unicode 5.1.0.
#
# The file contains a list of lines with mappings from one code point
# to another one for character-based mirroring.
# Note that for "real" mirroring, a rendering engine needs to select
# appropriate alternative glyphs, and that many Unicode characters do not
# have a mirror-image Unicode character.
#
# Each mapping line contains two fields, separated by a semicolon (';').
# Each of the two fields contains a code point represented as a
# variable-length hexadecimal value with 4 to 6 digits.
# A comment indicates where the characters are "BEST FIT" mirroring.
#
# Code points with the "mirrored" property but no appropriate mirrors are
# listed as comments at the end of the file.
#
# For information on bidi mirroring, see UAX #9: Bidirectional Algorithm,
# at http://www.unicode.org/unicode/reports/tr9/
#
# This file was originally created by Markus Scherer.
# Extended for Unicode 3.2, 4.0, 4.1, 5.0, and 5.1 by Ken Whistler.
#
# ############################################################
0028; 0029 # LEFT PARENTHESIS
0029; 0028 # RIGHT PARENTHESIS
003C; 003E # LESS-THAN SIGN
003E; 003C # GREATER-THAN SIGN
005B; 005D # LEFT SQUARE BRACKET
005D; 005B # RIGHT SQUARE BRACKET
007B; 007D # LEFT CURLY BRACKET
007D; 007B # RIGHT CURLY BRACKET
00AB; 00BB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
00BB; 00AB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
0F3A; 0F3B # TIBETAN MARK GUG RTAGS GYON
0F3B; 0F3A # TIBETAN MARK GUG RTAGS GYAS
0F3C; 0F3D # TIBETAN MARK ANG KHANG GYON
0F3D; 0F3C # TIBETAN MARK ANG KHANG GYAS
169B; 169C # OGHAM FEATHER MARK
169C; 169B # OGHAM REVERSED FEATHER MARK
2039; 203A # SINGLE LEFT-POINTING ANGLE QUOTATION MARK
203A; 2039 # SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
2045; 2046 # LEFT SQUARE BRACKET WITH QUILL
2046; 2045 # RIGHT SQUARE BRACKET WITH QUILL
207D; 207E # SUPERSCRIPT LEFT PARENTHESIS
207E; 207D # SUPERSCRIPT RIGHT PARENTHESIS
208D; 208E # SUBSCRIPT LEFT PARENTHESIS
208E; 208D # SUBSCRIPT RIGHT PARENTHESIS
2208; 220B # ELEMENT OF
2209; 220C # NOT AN ELEMENT OF
220A; 220D # SMALL ELEMENT OF
220B; 2208 # CONTAINS AS MEMBER
220C; 2209 # DOES NOT CONTAIN AS MEMBER
220D; 220A # SMALL CONTAINS AS MEMBER
2215; 29F5 # DIVISION SLASH
223C; 223D # TILDE OPERATOR
223D; 223C # REVERSED TILDE
2243; 22CD # ASYMPTOTICALLY EQUAL TO
2252; 2253 # APPROXIMATELY EQUAL TO OR THE IMAGE OF
2253; 2252 # IMAGE OF OR APPROXIMATELY EQUAL TO
2254; 2255 # COLON EQUALS
2255; 2254 # EQUALS COLON
2264; 2265 # LESS-THAN OR EQUAL TO
2265; 2264 # GREATER-THAN OR EQUAL TO
2266; 2267 # LESS-THAN OVER EQUAL TO
2267; 2266 # GREATER-THAN OVER EQUAL TO
2268; 2269 # [BEST FIT] LESS-THAN BUT NOT EQUAL TO
2269; 2268 # [BEST FIT] GREATER-THAN BUT NOT EQUAL TO
226A; 226B # MUCH LESS-THAN
226B; 226A # MUCH GREATER-THAN
226E; 226F # [BEST FIT] NOT LESS-THAN
226F; 226E # [BEST FIT] NOT GREATER-THAN
2270; 2271 # [BEST FIT] NEITHER LESS-THAN NOR EQUAL TO
2271; 2270 # [BEST FIT] NEITHER GREATER-THAN NOR EQUAL TO
2272; 2273 # [BEST FIT] LESS-THAN OR EQUIVALENT TO
2273; 2272 # [BEST FIT] GREATER-THAN OR EQUIVALENT TO
2274; 2275 # [BEST FIT] NEITHER LESS-THAN NOR EQUIVALENT TO
2275; 2274 # [BEST FIT] NEITHER GREATER-THAN NOR EQUIVALENT TO
2276; 2277 # LESS-THAN OR GREATER-THAN
2277; 2276 # GREATER-THAN OR LESS-THAN
2278; 2279 # [BEST FIT] NEITHER LESS-THAN NOR GREATER-THAN
2279; 2278 # [BEST FIT] NEITHER GREATER-THAN NOR LESS-THAN
227A; 227B # PRECEDES
227B; 227A # SUCCEEDS
227C; 227D # PRECEDES OR EQUAL TO
227D; 227C # SUCCEEDS OR EQUAL TO
227E; 227F # [BEST FIT] PRECEDES OR EQUIVALENT TO
227F; 227E # [BEST FIT] SUCCEEDS OR EQUIVALENT TO
2280; 2281 # [BEST FIT] DOES NOT PRECEDE
2281; 2280 # [BEST FIT] DOES NOT SUCCEED
2282; 2283 # SUBSET OF
2283; 2282 # SUPERSET OF
2284; 2285 # [BEST FIT] NOT A SUBSET OF
2285; 2284 # [BEST FIT] NOT A SUPERSET OF
2286; 2287 # SUBSET OF OR EQUAL TO
2287; 2286 # SUPERSET OF OR EQUAL TO
2288; 2289 # [BEST FIT] NEITHER A SUBSET OF NOR EQUAL TO
2289; 2288 # [BEST FIT] NEITHER A SUPERSET OF NOR EQUAL TO
228A; 228B # [BEST FIT] SUBSET OF WITH NOT EQUAL TO
228B; 228A # [BEST FIT] SUPERSET OF WITH NOT EQUAL TO
228F; 2290 # SQUARE IMAGE OF
2290; 228F # SQUARE ORIGINAL OF
2291; 2292 # SQUARE IMAGE OF OR EQUAL TO
2292; 2291 # SQUARE ORIGINAL OF OR EQUAL TO
2298; 29B8 # CIRCLED DIVISION SLASH
22A2; 22A3 # RIGHT TACK
22A3; 22A2 # LEFT TACK
22A6; 2ADE # ASSERTION
22A8; 2AE4 # TRUE
22A9; 2AE3 # FORCES
22AB; 2AE5 # DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE
22B0; 22B1 # PRECEDES UNDER RELATION
22B1; 22B0 # SUCCEEDS UNDER RELATION
22B2; 22B3 # NORMAL SUBGROUP OF
22B3; 22B2 # CONTAINS AS NORMAL SUBGROUP
22B4; 22B5 # NORMAL SUBGROUP OF OR EQUAL TO
22B5; 22B4 # CONTAINS AS NORMAL SUBGROUP OR EQUAL TO
22B6; 22B7 # ORIGINAL OF
22B7; 22B6 # IMAGE OF
22C9; 22CA # LEFT NORMAL FACTOR SEMIDIRECT PRODUCT
22CA; 22C9 # RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT
22CB; 22CC # LEFT SEMIDIRECT PRODUCT
22CC; 22CB # RIGHT SEMIDIRECT PRODUCT
22CD; 2243 # REVERSED TILDE EQUALS
22D0; 22D1 # DOUBLE SUBSET
22D1; 22D0 # DOUBLE SUPERSET
22D6; 22D7 # LESS-THAN WITH DOT
22D7; 22D6 # GREATER-THAN WITH DOT
22D8; 22D9 # VERY MUCH LESS-THAN
22D9; 22D8 # VERY MUCH GREATER-THAN
22DA; 22DB # LESS-THAN EQUAL TO OR GREATER-THAN
22DB; 22DA # GREATER-THAN EQUAL TO OR LESS-THAN
22DC; 22DD # EQUAL TO OR LESS-THAN
22DD; 22DC # EQUAL TO OR GREATER-THAN
22DE; 22DF # EQUAL TO OR PRECEDES
22DF; 22DE # EQUAL TO OR SUCCEEDS
22E0; 22E1 # [BEST FIT] DOES NOT PRECEDE OR EQUAL
22E1; 22E0 # [BEST FIT] DOES NOT SUCCEED OR EQUAL
22E2; 22E3 # [BEST FIT] NOT SQUARE IMAGE OF OR EQUAL TO
22E3; 22E2 # [BEST FIT] NOT SQUARE ORIGINAL OF OR EQUAL TO
22E4; 22E5 # [BEST FIT] SQUARE IMAGE OF OR NOT EQUAL TO
22E5; 22E4 # [BEST FIT] SQUARE ORIGINAL OF OR NOT EQUAL TO
22E6; 22E7 # [BEST FIT] LESS-THAN BUT NOT EQUIVALENT TO
22E7; 22E6 # [BEST FIT] GREATER-THAN BUT NOT EQUIVALENT TO
22E8; 22E9 # [BEST FIT] PRECEDES BUT NOT EQUIVALENT TO
22E9; 22E8 # [BEST FIT] SUCCEEDS BUT NOT EQUIVALENT TO
22EA; 22EB # [BEST FIT] NOT NORMAL SUBGROUP OF
22EB; 22EA # [BEST FIT] DOES NOT CONTAIN AS NORMAL SUBGROUP
22EC; 22ED # [BEST FIT] NOT NORMAL SUBGROUP OF OR EQUAL TO
22ED; 22EC # [BEST FIT] DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL
22F0; 22F1 # UP RIGHT DIAGONAL ELLIPSIS
22F1; 22F0 # DOWN RIGHT DIAGONAL ELLIPSIS
22F2; 22FA # ELEMENT OF WITH LONG HORIZONTAL STROKE
22F3; 22FB # ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE
22F4; 22FC # SMALL ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE
22F6; 22FD # ELEMENT OF WITH OVERBAR
22F7; 22FE # SMALL ELEMENT OF WITH OVERBAR
22FA; 22F2 # CONTAINS WITH LONG HORIZONTAL STROKE
22FB; 22F3 # CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE
22FC; 22F4 # SMALL CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE
22FD; 22F6 # CONTAINS WITH OVERBAR
22FE; 22F7 # SMALL CONTAINS WITH OVERBAR
2308; 2309 # LEFT CEILING
2309; 2308 # RIGHT CEILING
230A; 230B # LEFT FLOOR
230B; 230A # RIGHT FLOOR
2329; 232A # LEFT-POINTING ANGLE BRACKET
232A; 2329 # RIGHT-POINTING ANGLE BRACKET
2768; 2769 # MEDIUM LEFT PARENTHESIS ORNAMENT
2769; 2768 # MEDIUM RIGHT PARENTHESIS ORNAMENT
276A; 276B # MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT
276B; 276A # MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT
276C; 276D # MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT
276D; 276C # MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT
276E; 276F # HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT
276F; 276E # HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT
2770; 2771 # HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT
2771; 2770 # HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT
2772; 2773 # LIGHT LEFT TORTOISE SHELL BRACKET
2773; 2772 # LIGHT RIGHT TORTOISE SHELL BRACKET
2774; 2775 # MEDIUM LEFT CURLY BRACKET ORNAMENT
2775; 2774 # MEDIUM RIGHT CURLY BRACKET ORNAMENT
27C3; 27C4 # OPEN SUBSET
27C4; 27C3 # OPEN SUPERSET
27C5; 27C6 # LEFT S-SHAPED BAG DELIMITER
27C6; 27C5 # RIGHT S-SHAPED BAG DELIMITER
27C8; 27C9 # REVERSE SOLIDUS PRECEDING SUBSET
27C9; 27C8 # SUPERSET PRECEDING SOLIDUS
27D5; 27D6 # LEFT OUTER JOIN
27D6; 27D5 # RIGHT OUTER JOIN
27DD; 27DE # LONG RIGHT TACK
27DE; 27DD # LONG LEFT TACK
27E2; 27E3 # WHITE CONCAVE-SIDED DIAMOND WITH LEFTWARDS TICK
27E3; 27E2 # WHITE CONCAVE-SIDED DIAMOND WITH RIGHTWARDS TICK
27E4; 27E5 # WHITE SQUARE WITH LEFTWARDS TICK
27E5; 27E4 # WHITE SQUARE WITH RIGHTWARDS TICK
27E6; 27E7 # MATHEMATICAL LEFT WHITE SQUARE BRACKET
27E7; 27E6 # MATHEMATICAL RIGHT WHITE SQUARE BRACKET
27E8; 27E9 # MATHEMATICAL LEFT ANGLE BRACKET
27E9; 27E8 # MATHEMATICAL RIGHT ANGLE BRACKET
27EA; 27EB # MATHEMATICAL LEFT DOUBLE ANGLE BRACKET
27EB; 27EA # MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET
27EC; 27ED # MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET
27ED; 27EC # MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET
27EE; 27EF # MATHEMATICAL LEFT FLATTENED PARENTHESIS
27EF; 27EE # MATHEMATICAL RIGHT FLATTENED PARENTHESIS
2983; 2984 # LEFT WHITE CURLY BRACKET
2984; 2983 # RIGHT WHITE CURLY BRACKET
2985; 2986 # LEFT WHITE PARENTHESIS
2986; 2985 # RIGHT WHITE PARENTHESIS
2987; 2988 # Z NOTATION LEFT IMAGE BRACKET
2988; 2987 # Z NOTATION RIGHT IMAGE BRACKET
2989; 298A # Z NOTATION LEFT BINDING BRACKET
298A; 2989 # Z NOTATION RIGHT BINDING BRACKET
298B; 298C # LEFT SQUARE BRACKET WITH UNDERBAR
298C; 298B # RIGHT SQUARE BRACKET WITH UNDERBAR
298D; 2990 # LEFT SQUARE BRACKET WITH TICK IN TOP CORNER
298E; 298F # RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER
298F; 298E # LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER
2990; 298D # RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER
2991; 2992 # LEFT ANGLE BRACKET WITH DOT
2992; 2991 # RIGHT ANGLE BRACKET WITH DOT
2993; 2994 # LEFT ARC LESS-THAN BRACKET
2994; 2993 # RIGHT ARC GREATER-THAN BRACKET
2995; 2996 # DOUBLE LEFT ARC GREATER-THAN BRACKET
2996; 2995 # DOUBLE RIGHT ARC LESS-THAN BRACKET
2997; 2998 # LEFT BLACK TORTOISE SHELL BRACKET
2998; 2997 # RIGHT BLACK TORTOISE SHELL BRACKET
29B8; 2298 # CIRCLED REVERSE SOLIDUS
29C0; 29C1 # CIRCLED LESS-THAN
29C1; 29C0 # CIRCLED GREATER-THAN
29C4; 29C5 # SQUARED RISING DIAGONAL SLASH
29C5; 29C4 # SQUARED FALLING DIAGONAL SLASH
29CF; 29D0 # LEFT TRIANGLE BESIDE VERTICAL BAR
29D0; 29CF # VERTICAL BAR BESIDE RIGHT TRIANGLE
29D1; 29D2 # BOWTIE WITH LEFT HALF BLACK
29D2; 29D1 # BOWTIE WITH RIGHT HALF BLACK
29D4; 29D5 # TIMES WITH LEFT HALF BLACK
29D5; 29D4 # TIMES WITH RIGHT HALF BLACK
29D8; 29D9 # LEFT WIGGLY FENCE
29D9; 29D8 # RIGHT WIGGLY FENCE
29DA; 29DB # LEFT DOUBLE WIGGLY FENCE
29DB; 29DA # RIGHT DOUBLE WIGGLY FENCE
29F5; 2215 # REVERSE SOLIDUS OPERATOR
29F8; 29F9 # BIG SOLIDUS
29F9; 29F8 # BIG REVERSE SOLIDUS
29FC; 29FD # LEFT-POINTING CURVED ANGLE BRACKET
29FD; 29FC # RIGHT-POINTING CURVED ANGLE BRACKET
2A2B; 2A2C # MINUS SIGN WITH FALLING DOTS
2A2C; 2A2B # MINUS SIGN WITH RISING DOTS
2A2D; 2A2E # PLUS SIGN IN LEFT HALF CIRCLE
2A2E; 2A2D # PLUS SIGN IN RIGHT HALF CIRCLE
2A34; 2A35 # MULTIPLICATION SIGN IN LEFT HALF CIRCLE
2A35; 2A34 # MULTIPLICATION SIGN IN RIGHT HALF CIRCLE
2A3C; 2A3D # INTERIOR PRODUCT
2A3D; 2A3C # RIGHTHAND INTERIOR PRODUCT
2A64; 2A65 # Z NOTATION DOMAIN ANTIRESTRICTION
2A65; 2A64 # Z NOTATION RANGE ANTIRESTRICTION
2A79; 2A7A # LESS-THAN WITH CIRCLE INSIDE
2A7A; 2A79 # GREATER-THAN WITH CIRCLE INSIDE
2A7D; 2A7E # LESS-THAN OR SLANTED EQUAL TO
2A7E; 2A7D # GREATER-THAN OR SLANTED EQUAL TO
2A7F; 2A80 # LESS-THAN OR SLANTED EQUAL TO WITH DOT INSIDE
2A80; 2A7F # GREATER-THAN OR SLANTED EQUAL TO WITH DOT INSIDE
2A81; 2A82 # LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE
2A82; 2A81 # GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE
2A83; 2A84 # LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE RIGHT
2A84; 2A83 # GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE LEFT
2A8B; 2A8C # LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN
2A8C; 2A8B # GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN
2A91; 2A92 # LESS-THAN ABOVE GREATER-THAN ABOVE DOUBLE-LINE EQUAL
2A92; 2A91 # GREATER-THAN ABOVE LESS-THAN ABOVE DOUBLE-LINE EQUAL
2A93; 2A94 # LESS-THAN ABOVE SLANTED EQUAL ABOVE GREATER-THAN ABOVE SLANTED EQUAL
2A94; 2A93 # GREATER-THAN ABOVE SLANTED EQUAL ABOVE LESS-THAN ABOVE SLANTED EQUAL
2A95; 2A96 # SLANTED EQUAL TO OR LESS-THAN
2A96; 2A95 # SLANTED EQUAL TO OR GREATER-THAN
2A97; 2A98 # SLANTED EQUAL TO OR LESS-THAN WITH DOT INSIDE
2A98; 2A97 # SLANTED EQUAL TO OR GREATER-THAN WITH DOT INSIDE
2A99; 2A9A # DOUBLE-LINE EQUAL TO OR LESS-THAN
2A9A; 2A99 # DOUBLE-LINE EQUAL TO OR GREATER-THAN
2A9B; 2A9C # DOUBLE-LINE SLANTED EQUAL TO OR LESS-THAN
2A9C; 2A9B # DOUBLE-LINE SLANTED EQUAL TO OR GREATER-THAN
2AA1; 2AA2 # DOUBLE NESTED LESS-THAN
2AA2; 2AA1 # DOUBLE NESTED GREATER-THAN
2AA6; 2AA7 # LESS-THAN CLOSED BY CURVE
2AA7; 2AA6 # GREATER-THAN CLOSED BY CURVE
2AA8; 2AA9 # LESS-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL
2AA9; 2AA8 # GREATER-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL
2AAA; 2AAB # SMALLER THAN
2AAB; 2AAA # LARGER THAN
2AAC; 2AAD # SMALLER THAN OR EQUAL TO
2AAD; 2AAC # LARGER THAN OR EQUAL TO
2AAF; 2AB0 # PRECEDES ABOVE SINGLE-LINE EQUALS SIGN
2AB0; 2AAF # SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN
2AB3; 2AB4 # PRECEDES ABOVE EQUALS SIGN
2AB4; 2AB3 # SUCCEEDS ABOVE EQUALS SIGN
2ABB; 2ABC # DOUBLE PRECEDES
2ABC; 2ABB # DOUBLE SUCCEEDS
2ABD; 2ABE # SUBSET WITH DOT
2ABE; 2ABD # SUPERSET WITH DOT
2ABF; 2AC0 # SUBSET WITH PLUS SIGN BELOW
2AC0; 2ABF # SUPERSET WITH PLUS SIGN BELOW
2AC1; 2AC2 # SUBSET WITH MULTIPLICATION SIGN BELOW
2AC2; 2AC1 # SUPERSET WITH MULTIPLICATION SIGN BELOW
2AC3; 2AC4 # SUBSET OF OR EQUAL TO WITH DOT ABOVE
2AC4; 2AC3 # SUPERSET OF OR EQUAL TO WITH DOT ABOVE
2AC5; 2AC6 # SUBSET OF ABOVE EQUALS SIGN
2AC6; 2AC5 # SUPERSET OF ABOVE EQUALS SIGN
2ACD; 2ACE # SQUARE LEFT OPEN BOX OPERATOR
2ACE; 2ACD # SQUARE RIGHT OPEN BOX OPERATOR
2ACF; 2AD0 # CLOSED SUBSET
2AD0; 2ACF # CLOSED SUPERSET
2AD1; 2AD2 # CLOSED SUBSET OR EQUAL TO
2AD2; 2AD1 # CLOSED SUPERSET OR EQUAL TO
2AD3; 2AD4 # SUBSET ABOVE SUPERSET
2AD4; 2AD3 # SUPERSET ABOVE SUBSET
2AD5; 2AD6 # SUBSET ABOVE SUBSET
2AD6; 2AD5 # SUPERSET ABOVE SUPERSET
2ADE; 22A6 # SHORT LEFT TACK
2AE3; 22A9 # DOUBLE VERTICAL BAR LEFT TURNSTILE
2AE4; 22A8 # VERTICAL BAR DOUBLE LEFT TURNSTILE
2AE5; 22AB # DOUBLE VERTICAL BAR DOUBLE LEFT TURNSTILE
2AEC; 2AED # DOUBLE STROKE NOT SIGN
2AED; 2AEC # REVERSED DOUBLE STROKE NOT SIGN
2AF7; 2AF8 # TRIPLE NESTED LESS-THAN
2AF8; 2AF7 # TRIPLE NESTED GREATER-THAN
2AF9; 2AFA # DOUBLE-LINE SLANTED LESS-THAN OR EQUAL TO
2AFA; 2AF9 # DOUBLE-LINE SLANTED GREATER-THAN OR EQUAL TO
2E02; 2E03 # LEFT SUBSTITUTION BRACKET
2E03; 2E02 # RIGHT SUBSTITUTION BRACKET
2E04; 2E05 # LEFT DOTTED SUBSTITUTION BRACKET
2E05; 2E04 # RIGHT DOTTED SUBSTITUTION BRACKET
2E09; 2E0A # LEFT TRANSPOSITION BRACKET
2E0A; 2E09 # RIGHT TRANSPOSITION BRACKET
2E0C; 2E0D # LEFT RAISED OMISSION BRACKET
2E0D; 2E0C # RIGHT RAISED OMISSION BRACKET
2E1C; 2E1D # LEFT LOW PARAPHRASE BRACKET
2E1D; 2E1C # RIGHT LOW PARAPHRASE BRACKET
2E20; 2E21 # LEFT VERTICAL BAR WITH QUILL
2E21; 2E20 # RIGHT VERTICAL BAR WITH QUILL
2E22; 2E23 # TOP LEFT HALF BRACKET
2E23; 2E22 # TOP RIGHT HALF BRACKET
2E24; 2E25 # BOTTOM LEFT HALF BRACKET
2E25; 2E24 # BOTTOM RIGHT HALF BRACKET
2E26; 2E27 # LEFT SIDEWAYS U BRACKET
2E27; 2E26 # RIGHT SIDEWAYS U BRACKET
2E28; 2E29 # LEFT DOUBLE PARENTHESIS
2E29; 2E28 # RIGHT DOUBLE PARENTHESIS
3008; 3009 # LEFT ANGLE BRACKET
3009; 3008 # RIGHT ANGLE BRACKET
300A; 300B # LEFT DOUBLE ANGLE BRACKET
300B; 300A # RIGHT DOUBLE ANGLE BRACKET
300C; 300D # [BEST FIT] LEFT CORNER BRACKET
300D; 300C # [BEST FIT] RIGHT CORNER BRACKET
300E; 300F # [BEST FIT] LEFT WHITE CORNER BRACKET
300F; 300E # [BEST FIT] RIGHT WHITE CORNER BRACKET
3010; 3011 # LEFT BLACK LENTICULAR BRACKET
3011; 3010 # RIGHT BLACK LENTICULAR BRACKET
3014; 3015 # LEFT TORTOISE SHELL BRACKET
3015; 3014 # RIGHT TORTOISE SHELL BRACKET
3016; 3017 # LEFT WHITE LENTICULAR BRACKET
3017; 3016 # RIGHT WHITE LENTICULAR BRACKET
3018; 3019 # LEFT WHITE TORTOISE SHELL BRACKET
3019; 3018 # RIGHT WHITE TORTOISE SHELL BRACKET
301A; 301B # LEFT WHITE SQUARE BRACKET
301B; 301A # RIGHT WHITE SQUARE BRACKET
FE59; FE5A # SMALL LEFT PARENTHESIS
FE5A; FE59 # SMALL RIGHT PARENTHESIS
FE5B; FE5C # SMALL LEFT CURLY BRACKET
FE5C; FE5B # SMALL RIGHT CURLY BRACKET
FE5D; FE5E # SMALL LEFT TORTOISE SHELL BRACKET
FE5E; FE5D # SMALL RIGHT TORTOISE SHELL BRACKET
FE64; FE65 # SMALL LESS-THAN SIGN
FE65; FE64 # SMALL GREATER-THAN SIGN
FF08; FF09 # FULLWIDTH LEFT PARENTHESIS
FF09; FF08 # FULLWIDTH RIGHT PARENTHESIS
FF1C; FF1E # FULLWIDTH LESS-THAN SIGN
FF1E; FF1C # FULLWIDTH GREATER-THAN SIGN
FF3B; FF3D # FULLWIDTH LEFT SQUARE BRACKET
FF3D; FF3B # FULLWIDTH RIGHT SQUARE BRACKET
FF5B; FF5D # FULLWIDTH LEFT CURLY BRACKET
FF5D; FF5B # FULLWIDTH RIGHT CURLY BRACKET
FF5F; FF60 # FULLWIDTH LEFT WHITE PARENTHESIS
FF60; FF5F # FULLWIDTH RIGHT WHITE PARENTHESIS
FF62; FF63 # [BEST FIT] HALFWIDTH LEFT CORNER BRACKET
FF63; FF62 # [BEST FIT] HALFWIDTH RIGHT CORNER BRACKET
# The following characters have no appropriate mirroring character.
# For these characters it is up to the rendering system
# to provide mirrored glyphs.
# 2140; DOUBLE-STRUCK N-ARY SUMMATION
# 2201; COMPLEMENT
# 2202; PARTIAL DIFFERENTIAL
# 2203; THERE EXISTS
# 2204; THERE DOES NOT EXIST
# 2211; N-ARY SUMMATION
# 2216; SET MINUS
# 221A; SQUARE ROOT
# 221B; CUBE ROOT
# 221C; FOURTH ROOT
# 221D; PROPORTIONAL TO
# 221F; RIGHT ANGLE
# 2220; ANGLE
# 2221; MEASURED ANGLE
# 2222; SPHERICAL ANGLE
# 2224; DOES NOT DIVIDE
# 2226; NOT PARALLEL TO
# 222B; INTEGRAL
# 222C; DOUBLE INTEGRAL
# 222D; TRIPLE INTEGRAL
# 222E; CONTOUR INTEGRAL
# 222F; SURFACE INTEGRAL
# 2230; VOLUME INTEGRAL
# 2231; CLOCKWISE INTEGRAL
# 2232; CLOCKWISE CONTOUR INTEGRAL
# 2233; ANTICLOCKWISE CONTOUR INTEGRAL
# 2239; EXCESS
# 223B; HOMOTHETIC
# 223E; INVERTED LAZY S
# 223F; SINE WAVE
# 2240; WREATH PRODUCT
# 2241; NOT TILDE
# 2242; MINUS TILDE
# 2244; NOT ASYMPTOTICALLY EQUAL TO
# 2245; APPROXIMATELY EQUAL TO
# 2246; APPROXIMATELY BUT NOT ACTUALLY EQUAL TO
# 2247; NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO
# 2248; ALMOST EQUAL TO
# 2249; NOT ALMOST EQUAL TO
# 224A; ALMOST EQUAL OR EQUAL TO
# 224B; TRIPLE TILDE
# 224C; ALL EQUAL TO
# 225F; QUESTIONED EQUAL TO
# 2260; NOT EQUAL TO
# 2262; NOT IDENTICAL TO
# 228C; MULTISET
# 22A7; MODELS
# 22AA; TRIPLE VERTICAL BAR RIGHT TURNSTILE
# 22AC; DOES NOT PROVE
# 22AD; NOT TRUE
# 22AE; DOES NOT FORCE
# 22AF; NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE
# 22B8; MULTIMAP
# 22BE; RIGHT ANGLE WITH ARC
# 22BF; RIGHT TRIANGLE
# 22F5; ELEMENT OF WITH DOT ABOVE
# 22F8; ELEMENT OF WITH UNDERBAR
# 22F9; ELEMENT OF WITH TWO HORIZONTAL STROKES
# 22FF; Z NOTATION BAG MEMBERSHIP
# 2320; TOP HALF INTEGRAL
# 2321; BOTTOM HALF INTEGRAL
# 27CC; LONG DIVISION
# 27C0; THREE DIMENSIONAL ANGLE
# 27D3; LOWER RIGHT CORNER WITH DOT
# 27D4; UPPER LEFT CORNER WITH DOT
# 27DC; LEFT MULTIMAP
# 299B; MEASURED ANGLE OPENING LEFT
# 299C; RIGHT ANGLE VARIANT WITH SQUARE
# 299D; MEASURED RIGHT ANGLE WITH DOT
# 299E; ANGLE WITH S INSIDE
# 299F; ACUTE ANGLE
# 29A0; SPHERICAL ANGLE OPENING LEFT
# 29A1; SPHERICAL ANGLE OPENING UP
# 29A2; TURNED ANGLE
# 29A3; REVERSED ANGLE
# 29A4; ANGLE WITH UNDERBAR
# 29A5; REVERSED ANGLE WITH UNDERBAR
# 29A6; OBLIQUE ANGLE OPENING UP
# 29A7; OBLIQUE ANGLE OPENING DOWN
# 29A8; MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND RIGHT
# 29A9; MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND LEFT
# 29AA; MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND RIGHT
# 29AB; MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND LEFT
# 29AC; MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND UP
# 29AD; MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND UP
# 29AE; MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND DOWN
# 29AF; MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND DOWN
# 29C2; CIRCLE WITH SMALL CIRCLE TO THE RIGHT
# 29C3; CIRCLE WITH TWO HORIZONTAL STROKES TO THE RIGHT
# 29C9; TWO JOINED SQUARES
# 29CE; RIGHT TRIANGLE ABOVE LEFT TRIANGLE
# 29DC; INCOMPLETE INFINITY
# 29E1; INCREASES AS
# 29E3; EQUALS SIGN AND SLANTED PARALLEL
# 29E4; EQUALS SIGN AND SLANTED PARALLEL WITH TILDE ABOVE
# 29E5; IDENTICAL TO AND SLANTED PARALLEL
# 29E8; DOWN-POINTING TRIANGLE WITH LEFT HALF BLACK
# 29E9; DOWN-POINTING TRIANGLE WITH RIGHT HALF BLACK
# 29F4; RULE-DELAYED
# 29F6; SOLIDUS WITH OVERBAR
# 29F7; REVERSE SOLIDUS WITH HORIZONTAL STROKE
# 2A0A; MODULO TWO SUM
# 2A0B; SUMMATION WITH INTEGRAL
# 2A0C; QUADRUPLE INTEGRAL OPERATOR
# 2A0D; FINITE PART INTEGRAL
# 2A0E; INTEGRAL WITH DOUBLE STROKE
# 2A0F; INTEGRAL AVERAGE WITH SLASH
# 2A10; CIRCULATION FUNCTION
# 2A11; ANTICLOCKWISE INTEGRATION
# 2A12; LINE INTEGRATION WITH RECTANGULAR PATH AROUND POLE
# 2A13; LINE INTEGRATION WITH SEMICIRCULAR PATH AROUND POLE
# 2A14; LINE INTEGRATION NOT INCLUDING THE POLE
# 2A15; INTEGRAL AROUND A POINT OPERATOR
# 2A16; QUATERNION INTEGRAL OPERATOR
# 2A17; INTEGRAL WITH LEFTWARDS ARROW WITH HOOK
# 2A18; INTEGRAL WITH TIMES SIGN
# 2A19; INTEGRAL WITH INTERSECTION
# 2A1A; INTEGRAL WITH UNION
# 2A1B; INTEGRAL WITH OVERBAR
# 2A1C; INTEGRAL WITH UNDERBAR
# 2A1E; LARGE LEFT TRIANGLE OPERATOR
# 2A1F; Z NOTATION SCHEMA COMPOSITION
# 2A20; Z NOTATION SCHEMA PIPING
# 2A21; Z NOTATION SCHEMA PROJECTION
# 2A24; PLUS SIGN WITH TILDE ABOVE
# 2A26; PLUS SIGN WITH TILDE BELOW
# 2A29; MINUS SIGN WITH COMMA ABOVE
# 2A3E; Z NOTATION RELATIONAL COMPOSITION
# 2A57; SLOPING LARGE OR
# 2A58; SLOPING LARGE AND
# 2A6A; TILDE OPERATOR WITH DOT ABOVE
# 2A6B; TILDE OPERATOR WITH RISING DOTS
# 2A6C; SIMILAR MINUS SIMILAR
# 2A6D; CONGRUENT WITH DOT ABOVE
# 2A6F; ALMOST EQUAL TO WITH CIRCUMFLEX ACCENT
# 2A70; APPROXIMATELY EQUAL OR EQUAL TO
# 2A73; EQUALS SIGN ABOVE TILDE OPERATOR
# 2A74; DOUBLE COLON EQUAL
# 2A7B; LESS-THAN WITH QUESTION MARK ABOVE
# 2A7C; GREATER-THAN WITH QUESTION MARK ABOVE
# 2A85; LESS-THAN OR APPROXIMATE
# 2A86; GREATER-THAN OR APPROXIMATE
# 2A87; LESS-THAN AND SINGLE-LINE NOT EQUAL TO
# 2A88; GREATER-THAN AND SINGLE-LINE NOT EQUAL TO
# 2A89; LESS-THAN AND NOT APPROXIMATE
# 2A8A; GREATER-THAN AND NOT APPROXIMATE
# 2A8D; LESS-THAN ABOVE SIMILAR OR EQUAL
# 2A8E; GREATER-THAN ABOVE SIMILAR OR EQUAL
# 2A8F; LESS-THAN ABOVE SIMILAR ABOVE GREATER-THAN
# 2A90; GREATER-THAN ABOVE SIMILAR ABOVE LESS-THAN
# 2A9D; SIMILAR OR LESS-THAN
# 2A9E; SIMILAR OR GREATER-THAN
# 2A9F; SIMILAR ABOVE LESS-THAN ABOVE EQUALS SIGN
# 2AA0; SIMILAR ABOVE GREATER-THAN ABOVE EQUALS SIGN
# 2AA3; DOUBLE NESTED LESS-THAN WITH UNDERBAR
# 2AB1; PRECEDES ABOVE SINGLE-LINE NOT EQUAL TO
# 2AB2; SUCCEEDS ABOVE SINGLE-LINE NOT EQUAL TO
# 2AB5; PRECEDES ABOVE NOT EQUAL TO
# 2AB6; SUCCEEDS ABOVE NOT EQUAL TO
# 2AB7; PRECEDES ABOVE ALMOST EQUAL TO
# 2AB8; SUCCEEDS ABOVE ALMOST EQUAL TO
# 2AB9; PRECEDES ABOVE NOT ALMOST EQUAL TO
# 2ABA; SUCCEEDS ABOVE NOT ALMOST EQUAL TO
# 2AC7; SUBSET OF ABOVE TILDE OPERATOR
# 2AC8; SUPERSET OF ABOVE TILDE OPERATOR
# 2AC9; SUBSET OF ABOVE ALMOST EQUAL TO
# 2ACA; SUPERSET OF ABOVE ALMOST EQUAL TO
# 2ACB; SUBSET OF ABOVE NOT EQUAL TO
# 2ACC; SUPERSET OF ABOVE NOT EQUAL TO
# 2ADC; FORKING
# 2AE2; VERTICAL BAR TRIPLE RIGHT TURNSTILE
# 2AE6; LONG DASH FROM LEFT MEMBER OF DOUBLE VERTICAL
# 2AEE; DOES NOT DIVIDE WITH REVERSED NEGATION SLASH
# 2AF3; PARALLEL WITH TILDE OPERATOR
# 2AFB; TRIPLE SOLIDUS BINARY RELATION
# 2AFD; DOUBLE SOLIDUS OPERATOR
# 1D6DB; MATHEMATICAL BOLD PARTIAL DIFFERENTIAL
# 1D715; MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL
# 1D74F; MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL
# 1D789; MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL
# 1D7C3; MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL
# EOF

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,17 @@
This directory contains Python script to parse several of the Unicode tables
that are downloadable from the web and generate C header files from them.
These are the locations of the files which are parsed. You should download these
files and put them in this directory.
http://www.unicode.org/Public/5.1.0/ucd/extracted/DerivedGeneralCategory.txt
http://www.unicode.org/Public/5.1.0/ucd/extracted/DerivedCombiningClass.txt
http://www.unicode.org/Public/UNIDATA/auxiliary/GraphemeBreakProperty.txt
http://www.unicode.org/Public/5.1.0/ucd/Scripts.txt
Then you can run the following python scripts to generate the header files:
python category-parse.py DerivedGeneralCategory.txt category-properties.h
python combining-class-parse.py DerivedCombiningClass.txt combining-properties.h
python grapheme-break-parse.py GraphemeBreakProperty.txt grapheme-break-properties.h
python scripts-parse.py Scripts.txt script-properties.h

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,70 @@
import sys
from unicode_parse_common import *
# http://www.unicode.org/Public/5.1.0/ucd/extracted/DerivedGeneralCategory.txt
category_to_harfbuzz = {
'Mn': 'HB_Mark_NonSpacing',
'Mc': 'HB_Mark_SpacingCombining',
'Me': 'HB_Mark_Enclosing',
'Nd': 'HB_Number_DecimalDigit',
'Nl': 'HB_Number_Letter',
'No': 'HB_Number_Other',
'Zs': 'HB_Separator_Space',
'Zl': 'HB_Separator_Line',
'Zp': 'HB_Separator_Paragraph',
'Cc': 'HB_Other_Control',
'Cf': 'HB_Other_Format',
'Cs': 'HB_Other_Surrogate',
'Co': 'HB_Other_PrivateUse',
'Cn': 'HB_Other_NotAssigned',
'Lu': 'HB_Letter_Uppercase',
'Ll': 'HB_Letter_Lowercase',
'Lt': 'HB_Letter_Titlecase',
'Lm': 'HB_Letter_Modifier',
'Lo': 'HB_Letter_Other',
'Pc': 'HB_Punctuation_Connector',
'Pd': 'HB_Punctuation_Dash',
'Ps': 'HB_Punctuation_Open',
'Pe': 'HB_Punctuation_Close',
'Pi': 'HB_Punctuation_InitialQuote',
'Pf': 'HB_Punctuation_FinalQuote',
'Po': 'HB_Punctuation_Other',
'Sm': 'HB_Symbol_Math',
'Sc': 'HB_Symbol_Currency',
'Sk': 'HB_Symbol_Modifier',
'So': 'HB_Symbol_Other',
}
def main(infile, outfile):
ranges = unicode_file_parse(infile, category_to_harfbuzz)
ranges = sort_and_merge(ranges)
print >>outfile, '// Generated from Unicode script tables\n'
print >>outfile, '#ifndef CATEGORY_PROPERTIES_H_'
print >>outfile, '#define CATEGORY_PROPERTIES_H_\n'
print >>outfile, '#include <stdint.h>'
print >>outfile, '#include "harfbuzz-external.h"\n'
print >>outfile, 'struct category_property {'
print >>outfile, ' uint32_t range_start;'
print >>outfile, ' uint32_t range_end;'
print >>outfile, ' HB_CharCategory category;'
print >>outfile, '};\n'
print >>outfile, 'static const struct category_property category_properties[] = {'
for (start, end, value) in ranges:
print >>outfile, ' {0x%x, 0x%x, %s},' % (start, end, value)
print >>outfile, '};\n'
print >>outfile, 'static const unsigned category_properties_count = %d;\n' % len(ranges)
print >>outfile, '#endif // CATEGORY_PROPERTIES_H_'
if __name__ == '__main__':
if len(sys.argv) != 3:
print 'Usage: %s <input .txt> <output .h>' % sys.argv[0]
else:
main(file(sys.argv[1], 'r'), file(sys.argv[2], 'w+'))

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,34 @@
import sys
from unicode_parse_common import *
# http://www.unicode.org/Public/5.1.0/ucd/extracted/DerivedCombiningClass.txt
class IdentityMap(object):
def __getitem__(_, key):
return key
def main(infile, outfile):
ranges = unicode_file_parse(infile, IdentityMap(), '0')
ranges = sort_and_merge(ranges)
print >>outfile, '// Generated from Unicode tables\n'
print >>outfile, '#ifndef COMBINING_PROPERTIES_H_'
print >>outfile, '#define COMBINING_PROPERTIES_H_\n'
print >>outfile, '#include <stdint.h>'
print >>outfile, 'struct combining_property {'
print >>outfile, ' uint32_t range_start;'
print >>outfile, ' uint32_t range_end;'
print >>outfile, ' uint8_t klass;'
print >>outfile, '};\n'
print >>outfile, 'static const struct combining_property combining_properties[] = {'
for (start, end, value) in ranges:
print >>outfile, ' {0x%x, 0x%x, %s},' % (start, end, value)
print >>outfile, '};\n'
print >>outfile, 'static const unsigned combining_properties_count = %d;\n' % len(ranges)
print >>outfile, '#endif // COMBINING_PROPERTIES_H_'
if __name__ == '__main__':
if len(sys.argv) != 3:
print 'Usage: %s <input .txt> <output .h>' % sys.argv[0]
else:
main(file(sys.argv[1], 'r'), file(sys.argv[2], 'w+'))

View File

@ -0,0 +1,247 @@
// Generated from Unicode tables
#ifndef COMBINING_PROPERTIES_H_
#define COMBINING_PROPERTIES_H_
#include <stdint.h>
struct combining_property {
uint32_t range_start;
uint32_t range_end;
uint8_t klass;
};
static const struct combining_property combining_properties[] = {
{0x300, 0x314, 230},
{0x315, 0x315, 232},
{0x316, 0x319, 220},
{0x31a, 0x31a, 232},
{0x31b, 0x31b, 216},
{0x31c, 0x320, 220},
{0x321, 0x322, 202},
{0x323, 0x326, 220},
{0x327, 0x328, 202},
{0x329, 0x333, 220},
{0x334, 0x338, 1},
{0x339, 0x33c, 220},
{0x33d, 0x344, 230},
{0x345, 0x345, 240},
{0x346, 0x346, 230},
{0x347, 0x349, 220},
{0x34a, 0x34c, 230},
{0x34d, 0x34e, 220},
{0x350, 0x352, 230},
{0x353, 0x356, 220},
{0x357, 0x357, 230},
{0x358, 0x358, 232},
{0x359, 0x35a, 220},
{0x35b, 0x35b, 230},
{0x35c, 0x35c, 233},
{0x35d, 0x35e, 234},
{0x35f, 0x35f, 233},
{0x360, 0x361, 234},
{0x362, 0x362, 233},
{0x363, 0x36f, 230},
{0x483, 0x487, 230},
{0x591, 0x591, 220},
{0x592, 0x595, 230},
{0x596, 0x596, 220},
{0x597, 0x599, 230},
{0x59a, 0x59a, 222},
{0x59b, 0x59b, 220},
{0x59c, 0x5a1, 230},
{0x5a2, 0x5a7, 220},
{0x5a8, 0x5a9, 230},
{0x5aa, 0x5aa, 220},
{0x5ab, 0x5ac, 230},
{0x5ad, 0x5ad, 222},
{0x5ae, 0x5ae, 228},
{0x5af, 0x5af, 230},
{0x5b0, 0x5b0, 10},
{0x5b1, 0x5b1, 11},
{0x5b2, 0x5b2, 12},
{0x5b3, 0x5b3, 13},
{0x5b4, 0x5b4, 14},
{0x5b5, 0x5b5, 15},
{0x5b6, 0x5b6, 16},
{0x5b7, 0x5b7, 17},
{0x5b8, 0x5b8, 18},
{0x5b9, 0x5ba, 19},
{0x5bb, 0x5bb, 20},
{0x5bc, 0x5bc, 21},
{0x5bd, 0x5bd, 22},
{0x5bf, 0x5bf, 23},
{0x5c1, 0x5c1, 24},
{0x5c2, 0x5c2, 25},
{0x5c4, 0x5c4, 230},
{0x5c5, 0x5c5, 220},
{0x5c7, 0x5c7, 18},
{0x610, 0x617, 230},
{0x618, 0x618, 30},
{0x619, 0x619, 31},
{0x61a, 0x61a, 32},
{0x64b, 0x64b, 27},
{0x64c, 0x64c, 28},
{0x64d, 0x64d, 29},
{0x64e, 0x64e, 30},
{0x64f, 0x64f, 31},
{0x650, 0x650, 32},
{0x651, 0x651, 33},
{0x652, 0x652, 34},
{0x653, 0x654, 230},
{0x655, 0x656, 220},
{0x657, 0x65b, 230},
{0x65c, 0x65c, 220},
{0x65d, 0x65e, 230},
{0x670, 0x670, 35},
{0x6d6, 0x6dc, 230},
{0x6df, 0x6e2, 230},
{0x6e3, 0x6e3, 220},
{0x6e4, 0x6e4, 230},
{0x6e7, 0x6e8, 230},
{0x6ea, 0x6ea, 220},
{0x6eb, 0x6ec, 230},
{0x6ed, 0x6ed, 220},
{0x711, 0x711, 36},
{0x730, 0x730, 230},
{0x731, 0x731, 220},
{0x732, 0x733, 230},
{0x734, 0x734, 220},
{0x735, 0x736, 230},
{0x737, 0x739, 220},
{0x73a, 0x73a, 230},
{0x73b, 0x73c, 220},
{0x73d, 0x73d, 230},
{0x73e, 0x73e, 220},
{0x73f, 0x741, 230},
{0x742, 0x742, 220},
{0x743, 0x743, 230},
{0x744, 0x744, 220},
{0x745, 0x745, 230},
{0x746, 0x746, 220},
{0x747, 0x747, 230},
{0x748, 0x748, 220},
{0x749, 0x74a, 230},
{0x7eb, 0x7f1, 230},
{0x7f2, 0x7f2, 220},
{0x7f3, 0x7f3, 230},
{0x93c, 0x93c, 7},
{0x94d, 0x94d, 9},
{0x951, 0x951, 230},
{0x952, 0x952, 220},
{0x953, 0x954, 230},
{0x9bc, 0x9bc, 7},
{0x9cd, 0x9cd, 9},
{0xa3c, 0xa3c, 7},
{0xa4d, 0xa4d, 9},
{0xabc, 0xabc, 7},
{0xacd, 0xacd, 9},
{0xb3c, 0xb3c, 7},
{0xb4d, 0xb4d, 9},
{0xbcd, 0xbcd, 9},
{0xc4d, 0xc4d, 9},
{0xc55, 0xc55, 84},
{0xc56, 0xc56, 91},
{0xcbc, 0xcbc, 7},
{0xccd, 0xccd, 9},
{0xd4d, 0xd4d, 9},
{0xdca, 0xdca, 9},
{0xe38, 0xe39, 103},
{0xe3a, 0xe3a, 9},
{0xe48, 0xe4b, 107},
{0xeb8, 0xeb9, 118},
{0xec8, 0xecb, 122},
{0xf18, 0xf19, 220},
{0xf35, 0xf35, 220},
{0xf37, 0xf37, 220},
{0xf39, 0xf39, 216},
{0xf71, 0xf71, 129},
{0xf72, 0xf72, 130},
{0xf74, 0xf74, 132},
{0xf7a, 0xf7d, 130},
{0xf80, 0xf80, 130},
{0xf82, 0xf83, 230},
{0xf84, 0xf84, 9},
{0xf86, 0xf87, 230},
{0xfc6, 0xfc6, 220},
{0x1037, 0x1037, 7},
{0x1039, 0x103a, 9},
{0x108d, 0x108d, 220},
{0x135f, 0x135f, 230},
{0x1714, 0x1714, 9},
{0x1734, 0x1734, 9},
{0x17d2, 0x17d2, 9},
{0x17dd, 0x17dd, 230},
{0x18a9, 0x18a9, 228},
{0x1939, 0x1939, 222},
{0x193a, 0x193a, 230},
{0x193b, 0x193b, 220},
{0x1a17, 0x1a17, 230},
{0x1a18, 0x1a18, 220},
{0x1b34, 0x1b34, 7},
{0x1b44, 0x1b44, 9},
{0x1b6b, 0x1b6b, 230},
{0x1b6c, 0x1b6c, 220},
{0x1b6d, 0x1b73, 230},
{0x1baa, 0x1baa, 9},
{0x1c37, 0x1c37, 7},
{0x1dc0, 0x1dc1, 230},
{0x1dc2, 0x1dc2, 220},
{0x1dc3, 0x1dc9, 230},
{0x1dca, 0x1dca, 220},
{0x1dcb, 0x1dcc, 230},
{0x1dcd, 0x1dcd, 234},
{0x1dce, 0x1dce, 214},
{0x1dcf, 0x1dcf, 220},
{0x1dd0, 0x1dd0, 202},
{0x1dd1, 0x1de6, 230},
{0x1dfe, 0x1dfe, 230},
{0x1dff, 0x1dff, 220},
{0x20d0, 0x20d1, 230},
{0x20d2, 0x20d3, 1},
{0x20d4, 0x20d7, 230},
{0x20d8, 0x20da, 1},
{0x20db, 0x20dc, 230},
{0x20e1, 0x20e1, 230},
{0x20e5, 0x20e6, 1},
{0x20e7, 0x20e7, 230},
{0x20e8, 0x20e8, 220},
{0x20e9, 0x20e9, 230},
{0x20ea, 0x20eb, 1},
{0x20ec, 0x20ef, 220},
{0x20f0, 0x20f0, 230},
{0x2de0, 0x2dff, 230},
{0x302a, 0x302a, 218},
{0x302b, 0x302b, 228},
{0x302c, 0x302c, 232},
{0x302d, 0x302d, 222},
{0x302e, 0x302f, 224},
{0x3099, 0x309a, 8},
{0xa66f, 0xa66f, 230},
{0xa67c, 0xa67d, 230},
{0xa806, 0xa806, 9},
{0xa8c4, 0xa8c4, 9},
{0xa92b, 0xa92d, 220},
{0xa953, 0xa953, 9},
{0xfb1e, 0xfb1e, 26},
{0xfe20, 0xfe26, 230},
{0x101fd, 0x101fd, 220},
{0x10a0d, 0x10a0d, 220},
{0x10a0f, 0x10a0f, 230},
{0x10a38, 0x10a38, 230},
{0x10a39, 0x10a39, 1},
{0x10a3a, 0x10a3a, 220},
{0x10a3f, 0x10a3f, 9},
{0x1d165, 0x1d166, 216},
{0x1d167, 0x1d169, 1},
{0x1d16d, 0x1d16d, 226},
{0x1d16e, 0x1d172, 216},
{0x1d17b, 0x1d182, 220},
{0x1d185, 0x1d189, 230},
{0x1d18a, 0x1d18b, 220},
{0x1d1aa, 0x1d1ad, 230},
{0x1d242, 0x1d244, 230},
};
static const unsigned combining_properties_count = 229;
#endif // COMBINING_PROPERTIES_H_

View File

@ -0,0 +1,45 @@
import sys
from unicode_parse_common import *
# http://www.unicode.org/Public/UNIDATA/auxiliary/GraphemeBreakProperty.txt
property_to_harfbuzz = {
'CR': 'HB_Grapheme_CR',
'LF': 'HB_Grapheme_LF',
'Control': 'HB_Grapheme_Control',
'Extend': 'HB_Grapheme_Extend',
'Prepend': 'HB_Grapheme_Other',
'SpacingMark': 'HB_Grapheme_Other',
'L': 'HB_Grapheme_L',
'V': 'HB_Grapheme_V',
'T': 'HB_Grapheme_T',
'LV': 'HB_Grapheme_LV',
'LVT': 'HB_Grapheme_LVT',
}
def main(infile, outfile):
ranges = unicode_file_parse(infile, property_to_harfbuzz)
ranges.sort()
print >>outfile, '// Generated from Unicode Grapheme break tables\n'
print >>outfile, '#ifndef GRAPHEME_BREAK_PROPERTY_H_'
print >>outfile, '#define GRAPHEME_BREAK_PROPERTY_H_\n'
print >>outfile, '#include <stdint.h>'
print >>outfile, '#include "harfbuzz-external.h"\n'
print >>outfile, 'struct grapheme_break_property {'
print >>outfile, ' uint32_t range_start;'
print >>outfile, ' uint32_t range_end;'
print >>outfile, ' HB_GraphemeClass klass;'
print >>outfile, '};\n'
print >>outfile, 'static const struct grapheme_break_property grapheme_break_properties[] = {'
for (start, end, value) in ranges:
print >>outfile, ' {0x%x, 0x%x, %s},' % (start, end, value)
print >>outfile, '};\n'
print >>outfile, 'static const unsigned grapheme_break_properties_count = %d;\n' % len(ranges)
print >>outfile, '#endif // GRAPHEME_BREAK_PROPERTY_H_'
if __name__ == '__main__':
if len(sys.argv) != 3:
print 'Usage: %s <input .txt> <output .h>' % sys.argv[0]
else:
main(file(sys.argv[1], 'r'), file(sys.argv[2], 'w+'))

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,50 @@
import sys
# http://www.unicode.org/Public/UNIDATA/auxiliary/BidiMirroring.txt
# This parses a file in the format of the above file and outputs a table
# suitable for bsearch(3). This table maps Unicode code points to their
# 'mirror'. (Mirroring is used when rendering RTL characters, see the Unicode
# standard). By convention, this mapping should be commutative, but this code
# doesn't enforce or check this.
def main(infile, outfile):
pairs = []
for line in infile:
line = line[:-1]
if len(line) == 0 or line[0] == '#':
continue
if '#' in line:
(data, _) = line.split('#', 1)
else:
data = line
if ';' not in data:
continue
(a, b) = data.split(';', 1)
a = int(a, 16)
b = int(b, 16)
pairs.append((a, b))
pairs.sort()
print >>outfile, '// Generated from Unicode Bidi Mirroring tables\n'
print >>outfile, '#ifndef MIRRORING_PROPERTY_H_'
print >>outfile, '#define MIRRORING_PROPERTY_H_\n'
print >>outfile, '#include <stdint.h>'
print >>outfile, 'struct mirroring_property {'
print >>outfile, ' uint32_t a;'
print >>outfile, ' uint32_t b;'
print >>outfile, '};\n'
print >>outfile, 'static const struct mirroring_property mirroring_properties[] = {'
for pair in pairs:
print >>outfile, ' {0x%x, 0x%x},' % pair
print >>outfile, '};\n'
print >>outfile, 'static const unsigned mirroring_properties_count = %d;\n' % len(pairs)
print >>outfile, '#endif // MIRRORING_PROPERTY_H_'
if __name__ == '__main__':
if len(sys.argv) != 3:
print 'Usage: %s <input .txt> <output .h>' % sys.argv[0]
else:
main(file(sys.argv[1], 'r'), file(sys.argv[2], 'w+'))

View File

@ -0,0 +1,379 @@
// Generated from Unicode Bidi Mirroring tables
#ifndef MIRRORING_PROPERTY_H_
#define MIRRORING_PROPERTY_H_
#include <stdint.h>
struct mirroring_property {
uint32_t a;
uint32_t b;
};
static const struct mirroring_property mirroring_properties[] = {
{0x28, 0x29},
{0x29, 0x28},
{0x3c, 0x3e},
{0x3e, 0x3c},
{0x5b, 0x5d},
{0x5d, 0x5b},
{0x7b, 0x7d},
{0x7d, 0x7b},
{0xab, 0xbb},
{0xbb, 0xab},
{0xf3a, 0xf3b},
{0xf3b, 0xf3a},
{0xf3c, 0xf3d},
{0xf3d, 0xf3c},
{0x169b, 0x169c},
{0x169c, 0x169b},
{0x2039, 0x203a},
{0x203a, 0x2039},
{0x2045, 0x2046},
{0x2046, 0x2045},
{0x207d, 0x207e},
{0x207e, 0x207d},
{0x208d, 0x208e},
{0x208e, 0x208d},
{0x2208, 0x220b},
{0x2209, 0x220c},
{0x220a, 0x220d},
{0x220b, 0x2208},
{0x220c, 0x2209},
{0x220d, 0x220a},
{0x2215, 0x29f5},
{0x223c, 0x223d},
{0x223d, 0x223c},
{0x2243, 0x22cd},
{0x2252, 0x2253},
{0x2253, 0x2252},
{0x2254, 0x2255},
{0x2255, 0x2254},
{0x2264, 0x2265},
{0x2265, 0x2264},
{0x2266, 0x2267},
{0x2267, 0x2266},
{0x2268, 0x2269},
{0x2269, 0x2268},
{0x226a, 0x226b},
{0x226b, 0x226a},
{0x226e, 0x226f},
{0x226f, 0x226e},
{0x2270, 0x2271},
{0x2271, 0x2270},
{0x2272, 0x2273},
{0x2273, 0x2272},
{0x2274, 0x2275},
{0x2275, 0x2274},
{0x2276, 0x2277},
{0x2277, 0x2276},
{0x2278, 0x2279},
{0x2279, 0x2278},
{0x227a, 0x227b},
{0x227b, 0x227a},
{0x227c, 0x227d},
{0x227d, 0x227c},
{0x227e, 0x227f},
{0x227f, 0x227e},
{0x2280, 0x2281},
{0x2281, 0x2280},
{0x2282, 0x2283},
{0x2283, 0x2282},
{0x2284, 0x2285},
{0x2285, 0x2284},
{0x2286, 0x2287},
{0x2287, 0x2286},
{0x2288, 0x2289},
{0x2289, 0x2288},
{0x228a, 0x228b},
{0x228b, 0x228a},
{0x228f, 0x2290},
{0x2290, 0x228f},
{0x2291, 0x2292},
{0x2292, 0x2291},
{0x2298, 0x29b8},
{0x22a2, 0x22a3},
{0x22a3, 0x22a2},
{0x22a6, 0x2ade},
{0x22a8, 0x2ae4},
{0x22a9, 0x2ae3},
{0x22ab, 0x2ae5},
{0x22b0, 0x22b1},
{0x22b1, 0x22b0},
{0x22b2, 0x22b3},
{0x22b3, 0x22b2},
{0x22b4, 0x22b5},
{0x22b5, 0x22b4},
{0x22b6, 0x22b7},
{0x22b7, 0x22b6},
{0x22c9, 0x22ca},
{0x22ca, 0x22c9},
{0x22cb, 0x22cc},
{0x22cc, 0x22cb},
{0x22cd, 0x2243},
{0x22d0, 0x22d1},
{0x22d1, 0x22d0},
{0x22d6, 0x22d7},
{0x22d7, 0x22d6},
{0x22d8, 0x22d9},
{0x22d9, 0x22d8},
{0x22da, 0x22db},
{0x22db, 0x22da},
{0x22dc, 0x22dd},
{0x22dd, 0x22dc},
{0x22de, 0x22df},
{0x22df, 0x22de},
{0x22e0, 0x22e1},
{0x22e1, 0x22e0},
{0x22e2, 0x22e3},
{0x22e3, 0x22e2},
{0x22e4, 0x22e5},
{0x22e5, 0x22e4},
{0x22e6, 0x22e7},
{0x22e7, 0x22e6},
{0x22e8, 0x22e9},
{0x22e9, 0x22e8},
{0x22ea, 0x22eb},
{0x22eb, 0x22ea},
{0x22ec, 0x22ed},
{0x22ed, 0x22ec},
{0x22f0, 0x22f1},
{0x22f1, 0x22f0},
{0x22f2, 0x22fa},
{0x22f3, 0x22fb},
{0x22f4, 0x22fc},
{0x22f6, 0x22fd},
{0x22f7, 0x22fe},
{0x22fa, 0x22f2},
{0x22fb, 0x22f3},
{0x22fc, 0x22f4},
{0x22fd, 0x22f6},
{0x22fe, 0x22f7},
{0x2308, 0x2309},
{0x2309, 0x2308},
{0x230a, 0x230b},
{0x230b, 0x230a},
{0x2329, 0x232a},
{0x232a, 0x2329},
{0x2768, 0x2769},
{0x2769, 0x2768},
{0x276a, 0x276b},
{0x276b, 0x276a},
{0x276c, 0x276d},
{0x276d, 0x276c},
{0x276e, 0x276f},
{0x276f, 0x276e},
{0x2770, 0x2771},
{0x2771, 0x2770},
{0x2772, 0x2773},
{0x2773, 0x2772},
{0x2774, 0x2775},
{0x2775, 0x2774},
{0x27c3, 0x27c4},
{0x27c4, 0x27c3},
{0x27c5, 0x27c6},
{0x27c6, 0x27c5},
{0x27c8, 0x27c9},
{0x27c9, 0x27c8},
{0x27d5, 0x27d6},
{0x27d6, 0x27d5},
{0x27dd, 0x27de},
{0x27de, 0x27dd},
{0x27e2, 0x27e3},
{0x27e3, 0x27e2},
{0x27e4, 0x27e5},
{0x27e5, 0x27e4},
{0x27e6, 0x27e7},
{0x27e7, 0x27e6},
{0x27e8, 0x27e9},
{0x27e9, 0x27e8},
{0x27ea, 0x27eb},
{0x27eb, 0x27ea},
{0x27ec, 0x27ed},
{0x27ed, 0x27ec},
{0x27ee, 0x27ef},
{0x27ef, 0x27ee},
{0x2983, 0x2984},
{0x2984, 0x2983},
{0x2985, 0x2986},
{0x2986, 0x2985},
{0x2987, 0x2988},
{0x2988, 0x2987},
{0x2989, 0x298a},
{0x298a, 0x2989},
{0x298b, 0x298c},
{0x298c, 0x298b},
{0x298d, 0x2990},
{0x298e, 0x298f},
{0x298f, 0x298e},
{0x2990, 0x298d},
{0x2991, 0x2992},
{0x2992, 0x2991},
{0x2993, 0x2994},
{0x2994, 0x2993},
{0x2995, 0x2996},
{0x2996, 0x2995},
{0x2997, 0x2998},
{0x2998, 0x2997},
{0x29b8, 0x2298},
{0x29c0, 0x29c1},
{0x29c1, 0x29c0},
{0x29c4, 0x29c5},
{0x29c5, 0x29c4},
{0x29cf, 0x29d0},
{0x29d0, 0x29cf},
{0x29d1, 0x29d2},
{0x29d2, 0x29d1},
{0x29d4, 0x29d5},
{0x29d5, 0x29d4},
{0x29d8, 0x29d9},
{0x29d9, 0x29d8},
{0x29da, 0x29db},
{0x29db, 0x29da},
{0x29f5, 0x2215},
{0x29f8, 0x29f9},
{0x29f9, 0x29f8},
{0x29fc, 0x29fd},
{0x29fd, 0x29fc},
{0x2a2b, 0x2a2c},
{0x2a2c, 0x2a2b},
{0x2a2d, 0x2a2e},
{0x2a2e, 0x2a2d},
{0x2a34, 0x2a35},
{0x2a35, 0x2a34},
{0x2a3c, 0x2a3d},
{0x2a3d, 0x2a3c},
{0x2a64, 0x2a65},
{0x2a65, 0x2a64},
{0x2a79, 0x2a7a},
{0x2a7a, 0x2a79},
{0x2a7d, 0x2a7e},
{0x2a7e, 0x2a7d},
{0x2a7f, 0x2a80},
{0x2a80, 0x2a7f},
{0x2a81, 0x2a82},
{0x2a82, 0x2a81},
{0x2a83, 0x2a84},
{0x2a84, 0x2a83},
{0x2a8b, 0x2a8c},
{0x2a8c, 0x2a8b},
{0x2a91, 0x2a92},
{0x2a92, 0x2a91},
{0x2a93, 0x2a94},
{0x2a94, 0x2a93},
{0x2a95, 0x2a96},
{0x2a96, 0x2a95},
{0x2a97, 0x2a98},
{0x2a98, 0x2a97},
{0x2a99, 0x2a9a},
{0x2a9a, 0x2a99},
{0x2a9b, 0x2a9c},
{0x2a9c, 0x2a9b},
{0x2aa1, 0x2aa2},
{0x2aa2, 0x2aa1},
{0x2aa6, 0x2aa7},
{0x2aa7, 0x2aa6},
{0x2aa8, 0x2aa9},
{0x2aa9, 0x2aa8},
{0x2aaa, 0x2aab},
{0x2aab, 0x2aaa},
{0x2aac, 0x2aad},
{0x2aad, 0x2aac},
{0x2aaf, 0x2ab0},
{0x2ab0, 0x2aaf},
{0x2ab3, 0x2ab4},
{0x2ab4, 0x2ab3},
{0x2abb, 0x2abc},
{0x2abc, 0x2abb},
{0x2abd, 0x2abe},
{0x2abe, 0x2abd},
{0x2abf, 0x2ac0},
{0x2ac0, 0x2abf},
{0x2ac1, 0x2ac2},
{0x2ac2, 0x2ac1},
{0x2ac3, 0x2ac4},
{0x2ac4, 0x2ac3},
{0x2ac5, 0x2ac6},
{0x2ac6, 0x2ac5},
{0x2acd, 0x2ace},
{0x2ace, 0x2acd},
{0x2acf, 0x2ad0},
{0x2ad0, 0x2acf},
{0x2ad1, 0x2ad2},
{0x2ad2, 0x2ad1},
{0x2ad3, 0x2ad4},
{0x2ad4, 0x2ad3},
{0x2ad5, 0x2ad6},
{0x2ad6, 0x2ad5},
{0x2ade, 0x22a6},
{0x2ae3, 0x22a9},
{0x2ae4, 0x22a8},
{0x2ae5, 0x22ab},
{0x2aec, 0x2aed},
{0x2aed, 0x2aec},
{0x2af7, 0x2af8},
{0x2af8, 0x2af7},
{0x2af9, 0x2afa},
{0x2afa, 0x2af9},
{0x2e02, 0x2e03},
{0x2e03, 0x2e02},
{0x2e04, 0x2e05},
{0x2e05, 0x2e04},
{0x2e09, 0x2e0a},
{0x2e0a, 0x2e09},
{0x2e0c, 0x2e0d},
{0x2e0d, 0x2e0c},
{0x2e1c, 0x2e1d},
{0x2e1d, 0x2e1c},
{0x2e20, 0x2e21},
{0x2e21, 0x2e20},
{0x2e22, 0x2e23},
{0x2e23, 0x2e22},
{0x2e24, 0x2e25},
{0x2e25, 0x2e24},
{0x2e26, 0x2e27},
{0x2e27, 0x2e26},
{0x2e28, 0x2e29},
{0x2e29, 0x2e28},
{0x3008, 0x3009},
{0x3009, 0x3008},
{0x300a, 0x300b},
{0x300b, 0x300a},
{0x300c, 0x300d},
{0x300d, 0x300c},
{0x300e, 0x300f},
{0x300f, 0x300e},
{0x3010, 0x3011},
{0x3011, 0x3010},
{0x3014, 0x3015},
{0x3015, 0x3014},
{0x3016, 0x3017},
{0x3017, 0x3016},
{0x3018, 0x3019},
{0x3019, 0x3018},
{0x301a, 0x301b},
{0x301b, 0x301a},
{0xfe59, 0xfe5a},
{0xfe5a, 0xfe59},
{0xfe5b, 0xfe5c},
{0xfe5c, 0xfe5b},
{0xfe5d, 0xfe5e},
{0xfe5e, 0xfe5d},
{0xfe64, 0xfe65},
{0xfe65, 0xfe64},
{0xff08, 0xff09},
{0xff09, 0xff08},
{0xff1c, 0xff1e},
{0xff1e, 0xff1c},
{0xff3b, 0xff3d},
{0xff3d, 0xff3b},
{0xff5b, 0xff5d},
{0xff5d, 0xff5b},
{0xff5f, 0xff60},
{0xff60, 0xff5f},
{0xff62, 0xff63},
{0xff63, 0xff62},
};
static const unsigned mirroring_properties_count = 362;
#endif // MIRRORING_PROPERTY_H_

View File

@ -0,0 +1,297 @@
// Generated from Unicode script tables
#ifndef SCRIPT_PROPERTIES_H_
#define SCRIPT_PROPERTIES_H_
#include <stdint.h>
#include "harfbuzz-shaper.h"
struct script_property {
uint32_t range_start;
uint32_t range_end;
HB_Script script;
};
static const struct script_property script_properties[] = {
{0x300, 0x36f, HB_Script_Inherited},
{0x370, 0x373, HB_Script_Greek},
{0x375, 0x377, HB_Script_Greek},
{0x37a, 0x37d, HB_Script_Greek},
{0x384, 0x384, HB_Script_Greek},
{0x386, 0x386, HB_Script_Greek},
{0x388, 0x38a, HB_Script_Greek},
{0x38c, 0x38c, HB_Script_Greek},
{0x38e, 0x3a1, HB_Script_Greek},
{0x3a3, 0x3e1, HB_Script_Greek},
{0x3f0, 0x3ff, HB_Script_Greek},
{0x400, 0x523, HB_Script_Cyrillic},
{0x531, 0x556, HB_Script_Armenian},
{0x559, 0x55f, HB_Script_Armenian},
{0x561, 0x587, HB_Script_Armenian},
{0x58a, 0x58a, HB_Script_Armenian},
{0x591, 0x5c7, HB_Script_Hebrew},
{0x5d0, 0x5ea, HB_Script_Hebrew},
{0x5f0, 0x5f4, HB_Script_Hebrew},
{0x606, 0x60b, HB_Script_Arabic},
{0x60d, 0x61a, HB_Script_Arabic},
{0x61e, 0x61e, HB_Script_Arabic},
{0x621, 0x63f, HB_Script_Arabic},
{0x641, 0x64a, HB_Script_Arabic},
{0x64b, 0x655, HB_Script_Inherited},
{0x656, 0x65e, HB_Script_Arabic},
{0x66a, 0x66f, HB_Script_Arabic},
{0x670, 0x670, HB_Script_Inherited},
{0x671, 0x6dc, HB_Script_Arabic},
{0x6de, 0x6ff, HB_Script_Arabic},
{0x700, 0x70d, HB_Script_Syriac},
{0x70f, 0x74a, HB_Script_Syriac},
{0x74d, 0x74f, HB_Script_Syriac},
{0x750, 0x77f, HB_Script_Arabic},
{0x780, 0x7b1, HB_Script_Thaana},
{0x901, 0x939, HB_Script_Devanagari},
{0x93c, 0x94d, HB_Script_Devanagari},
{0x950, 0x950, HB_Script_Devanagari},
{0x951, 0x952, HB_Script_Inherited},
{0x953, 0x954, HB_Script_Devanagari},
{0x958, 0x963, HB_Script_Devanagari},
{0x966, 0x96f, HB_Script_Devanagari},
{0x971, 0x972, HB_Script_Devanagari},
{0x97b, 0x97f, HB_Script_Devanagari},
{0x981, 0x983, HB_Script_Bengali},
{0x985, 0x98c, HB_Script_Bengali},
{0x98f, 0x990, HB_Script_Bengali},
{0x993, 0x9a8, HB_Script_Bengali},
{0x9aa, 0x9b0, HB_Script_Bengali},
{0x9b2, 0x9b2, HB_Script_Bengali},
{0x9b6, 0x9b9, HB_Script_Bengali},
{0x9bc, 0x9c4, HB_Script_Bengali},
{0x9c7, 0x9c8, HB_Script_Bengali},
{0x9cb, 0x9ce, HB_Script_Bengali},
{0x9d7, 0x9d7, HB_Script_Bengali},
{0x9dc, 0x9dd, HB_Script_Bengali},
{0x9df, 0x9e3, HB_Script_Bengali},
{0x9e6, 0x9fa, HB_Script_Bengali},
{0xa01, 0xa03, HB_Script_Gurmukhi},
{0xa05, 0xa0a, HB_Script_Gurmukhi},
{0xa0f, 0xa10, HB_Script_Gurmukhi},
{0xa13, 0xa28, HB_Script_Gurmukhi},
{0xa2a, 0xa30, HB_Script_Gurmukhi},
{0xa32, 0xa33, HB_Script_Gurmukhi},
{0xa35, 0xa36, HB_Script_Gurmukhi},
{0xa38, 0xa39, HB_Script_Gurmukhi},
{0xa3c, 0xa3c, HB_Script_Gurmukhi},
{0xa3e, 0xa42, HB_Script_Gurmukhi},
{0xa47, 0xa48, HB_Script_Gurmukhi},
{0xa4b, 0xa4d, HB_Script_Gurmukhi},
{0xa51, 0xa51, HB_Script_Gurmukhi},
{0xa59, 0xa5c, HB_Script_Gurmukhi},
{0xa5e, 0xa5e, HB_Script_Gurmukhi},
{0xa66, 0xa75, HB_Script_Gurmukhi},
{0xa81, 0xa83, HB_Script_Gujarati},
{0xa85, 0xa8d, HB_Script_Gujarati},
{0xa8f, 0xa91, HB_Script_Gujarati},
{0xa93, 0xaa8, HB_Script_Gujarati},
{0xaaa, 0xab0, HB_Script_Gujarati},
{0xab2, 0xab3, HB_Script_Gujarati},
{0xab5, 0xab9, HB_Script_Gujarati},
{0xabc, 0xac5, HB_Script_Gujarati},
{0xac7, 0xac9, HB_Script_Gujarati},
{0xacb, 0xacd, HB_Script_Gujarati},
{0xad0, 0xad0, HB_Script_Gujarati},
{0xae0, 0xae3, HB_Script_Gujarati},
{0xae6, 0xaef, HB_Script_Gujarati},
{0xaf1, 0xaf1, HB_Script_Gujarati},
{0xb01, 0xb03, HB_Script_Oriya},
{0xb05, 0xb0c, HB_Script_Oriya},
{0xb0f, 0xb10, HB_Script_Oriya},
{0xb13, 0xb28, HB_Script_Oriya},
{0xb2a, 0xb30, HB_Script_Oriya},
{0xb32, 0xb33, HB_Script_Oriya},
{0xb35, 0xb39, HB_Script_Oriya},
{0xb3c, 0xb44, HB_Script_Oriya},
{0xb47, 0xb48, HB_Script_Oriya},
{0xb4b, 0xb4d, HB_Script_Oriya},
{0xb56, 0xb57, HB_Script_Oriya},
{0xb5c, 0xb5d, HB_Script_Oriya},
{0xb5f, 0xb63, HB_Script_Oriya},
{0xb66, 0xb71, HB_Script_Oriya},
{0xb82, 0xb83, HB_Script_Tamil},
{0xb85, 0xb8a, HB_Script_Tamil},
{0xb8e, 0xb90, HB_Script_Tamil},
{0xb92, 0xb95, HB_Script_Tamil},
{0xb99, 0xb9a, HB_Script_Tamil},
{0xb9c, 0xb9c, HB_Script_Tamil},
{0xb9e, 0xb9f, HB_Script_Tamil},
{0xba3, 0xba4, HB_Script_Tamil},
{0xba8, 0xbaa, HB_Script_Tamil},
{0xbae, 0xbb9, HB_Script_Tamil},
{0xbbe, 0xbc2, HB_Script_Tamil},
{0xbc6, 0xbc8, HB_Script_Tamil},
{0xbca, 0xbcd, HB_Script_Tamil},
{0xbd0, 0xbd0, HB_Script_Tamil},
{0xbd7, 0xbd7, HB_Script_Tamil},
{0xbe6, 0xbfa, HB_Script_Tamil},
{0xc01, 0xc03, HB_Script_Telugu},
{0xc05, 0xc0c, HB_Script_Telugu},
{0xc0e, 0xc10, HB_Script_Telugu},
{0xc12, 0xc28, HB_Script_Telugu},
{0xc2a, 0xc33, HB_Script_Telugu},
{0xc35, 0xc39, HB_Script_Telugu},
{0xc3d, 0xc44, HB_Script_Telugu},
{0xc46, 0xc48, HB_Script_Telugu},
{0xc4a, 0xc4d, HB_Script_Telugu},
{0xc55, 0xc56, HB_Script_Telugu},
{0xc58, 0xc59, HB_Script_Telugu},
{0xc60, 0xc63, HB_Script_Telugu},
{0xc66, 0xc6f, HB_Script_Telugu},
{0xc78, 0xc7f, HB_Script_Telugu},
{0xc82, 0xc83, HB_Script_Kannada},
{0xc85, 0xc8c, HB_Script_Kannada},
{0xc8e, 0xc90, HB_Script_Kannada},
{0xc92, 0xca8, HB_Script_Kannada},
{0xcaa, 0xcb3, HB_Script_Kannada},
{0xcb5, 0xcb9, HB_Script_Kannada},
{0xcbc, 0xcc4, HB_Script_Kannada},
{0xcc6, 0xcc8, HB_Script_Kannada},
{0xcca, 0xccd, HB_Script_Kannada},
{0xcd5, 0xcd6, HB_Script_Kannada},
{0xcde, 0xcde, HB_Script_Kannada},
{0xce0, 0xce3, HB_Script_Kannada},
{0xce6, 0xcef, HB_Script_Kannada},
{0xd02, 0xd03, HB_Script_Malayalam},
{0xd05, 0xd0c, HB_Script_Malayalam},
{0xd0e, 0xd10, HB_Script_Malayalam},
{0xd12, 0xd28, HB_Script_Malayalam},
{0xd2a, 0xd39, HB_Script_Malayalam},
{0xd3d, 0xd44, HB_Script_Malayalam},
{0xd46, 0xd48, HB_Script_Malayalam},
{0xd4a, 0xd4d, HB_Script_Malayalam},
{0xd57, 0xd57, HB_Script_Malayalam},
{0xd60, 0xd63, HB_Script_Malayalam},
{0xd66, 0xd75, HB_Script_Malayalam},
{0xd79, 0xd7f, HB_Script_Malayalam},
{0xd82, 0xd83, HB_Script_Sinhala},
{0xd85, 0xd96, HB_Script_Sinhala},
{0xd9a, 0xdb1, HB_Script_Sinhala},
{0xdb3, 0xdbb, HB_Script_Sinhala},
{0xdbd, 0xdbd, HB_Script_Sinhala},
{0xdc0, 0xdc6, HB_Script_Sinhala},
{0xdca, 0xdca, HB_Script_Sinhala},
{0xdcf, 0xdd4, HB_Script_Sinhala},
{0xdd6, 0xdd6, HB_Script_Sinhala},
{0xdd8, 0xddf, HB_Script_Sinhala},
{0xdf2, 0xdf4, HB_Script_Sinhala},
{0xe01, 0xe3a, HB_Script_Thai},
{0xe40, 0xe5b, HB_Script_Thai},
{0xe81, 0xe82, HB_Script_Lao},
{0xe84, 0xe84, HB_Script_Lao},
{0xe87, 0xe88, HB_Script_Lao},
{0xe8a, 0xe8a, HB_Script_Lao},
{0xe8d, 0xe8d, HB_Script_Lao},
{0xe94, 0xe97, HB_Script_Lao},
{0xe99, 0xe9f, HB_Script_Lao},
{0xea1, 0xea3, HB_Script_Lao},
{0xea5, 0xea5, HB_Script_Lao},
{0xea7, 0xea7, HB_Script_Lao},
{0xeaa, 0xeab, HB_Script_Lao},
{0xead, 0xeb9, HB_Script_Lao},
{0xebb, 0xebd, HB_Script_Lao},
{0xec0, 0xec4, HB_Script_Lao},
{0xec6, 0xec6, HB_Script_Lao},
{0xec8, 0xecd, HB_Script_Lao},
{0xed0, 0xed9, HB_Script_Lao},
{0xedc, 0xedd, HB_Script_Lao},
{0xf00, 0xf47, HB_Script_Tibetan},
{0xf49, 0xf6c, HB_Script_Tibetan},
{0xf71, 0xf8b, HB_Script_Tibetan},
{0xf90, 0xf97, HB_Script_Tibetan},
{0xf99, 0xfbc, HB_Script_Tibetan},
{0xfbe, 0xfcc, HB_Script_Tibetan},
{0xfce, 0xfd4, HB_Script_Tibetan},
{0x1000, 0x1099, HB_Script_Myanmar},
{0x109e, 0x109f, HB_Script_Myanmar},
{0x10a0, 0x10c5, HB_Script_Georgian},
{0x10d0, 0x10fa, HB_Script_Georgian},
{0x10fc, 0x10fc, HB_Script_Georgian},
{0x1100, 0x1159, HB_Script_Hangul},
{0x115f, 0x11a2, HB_Script_Hangul},
{0x11a8, 0x11f9, HB_Script_Hangul},
{0x1680, 0x169c, HB_Script_Ogham},
{0x16a0, 0x16ea, HB_Script_Runic},
{0x16ee, 0x16f0, HB_Script_Runic},
{0x1780, 0x17dd, HB_Script_Khmer},
{0x17e0, 0x17e9, HB_Script_Khmer},
{0x17f0, 0x17f9, HB_Script_Khmer},
{0x19e0, 0x19ff, HB_Script_Khmer},
{0x1d26, 0x1d2a, HB_Script_Greek},
{0x1d2b, 0x1d2b, HB_Script_Cyrillic},
{0x1d5d, 0x1d61, HB_Script_Greek},
{0x1d66, 0x1d6a, HB_Script_Greek},
{0x1d78, 0x1d78, HB_Script_Cyrillic},
{0x1dbf, 0x1dbf, HB_Script_Greek},
{0x1dc0, 0x1de6, HB_Script_Inherited},
{0x1dfe, 0x1dff, HB_Script_Inherited},
{0x1f00, 0x1f15, HB_Script_Greek},
{0x1f18, 0x1f1d, HB_Script_Greek},
{0x1f20, 0x1f45, HB_Script_Greek},
{0x1f48, 0x1f4d, HB_Script_Greek},
{0x1f50, 0x1f57, HB_Script_Greek},
{0x1f59, 0x1f59, HB_Script_Greek},
{0x1f5b, 0x1f5b, HB_Script_Greek},
{0x1f5d, 0x1f5d, HB_Script_Greek},
{0x1f5f, 0x1f7d, HB_Script_Greek},
{0x1f80, 0x1fb4, HB_Script_Greek},
{0x1fb6, 0x1fc4, HB_Script_Greek},
{0x1fc6, 0x1fd3, HB_Script_Greek},
{0x1fd6, 0x1fdb, HB_Script_Greek},
{0x1fdd, 0x1fef, HB_Script_Greek},
{0x1ff2, 0x1ff4, HB_Script_Greek},
{0x1ff6, 0x1ffe, HB_Script_Greek},
{0x200c, 0x200d, HB_Script_Inherited},
{0x20d0, 0x20f0, HB_Script_Inherited},
{0x2126, 0x2126, HB_Script_Greek},
{0x2d00, 0x2d25, HB_Script_Georgian},
{0x2de0, 0x2dff, HB_Script_Cyrillic},
{0x302a, 0x302f, HB_Script_Inherited},
{0x3099, 0x309a, HB_Script_Inherited},
{0x3131, 0x318e, HB_Script_Hangul},
{0x3200, 0x321e, HB_Script_Hangul},
{0x3260, 0x327e, HB_Script_Hangul},
{0xa640, 0xa65f, HB_Script_Cyrillic},
{0xa662, 0xa673, HB_Script_Cyrillic},
{0xa67c, 0xa697, HB_Script_Cyrillic},
{0xac00, 0xd7a3, HB_Script_Hangul},
{0xfb13, 0xfb17, HB_Script_Armenian},
{0xfb1d, 0xfb36, HB_Script_Hebrew},
{0xfb38, 0xfb3c, HB_Script_Hebrew},
{0xfb3e, 0xfb3e, HB_Script_Hebrew},
{0xfb40, 0xfb41, HB_Script_Hebrew},
{0xfb43, 0xfb44, HB_Script_Hebrew},
{0xfb46, 0xfb4f, HB_Script_Hebrew},
{0xfb50, 0xfbb1, HB_Script_Arabic},
{0xfbd3, 0xfd3d, HB_Script_Arabic},
{0xfd50, 0xfd8f, HB_Script_Arabic},
{0xfd92, 0xfdc7, HB_Script_Arabic},
{0xfdf0, 0xfdfc, HB_Script_Arabic},
{0xfe00, 0xfe0f, HB_Script_Inherited},
{0xfe20, 0xfe26, HB_Script_Inherited},
{0xfe70, 0xfe74, HB_Script_Arabic},
{0xfe76, 0xfefc, HB_Script_Arabic},
{0xffa0, 0xffbe, HB_Script_Hangul},
{0xffc2, 0xffc7, HB_Script_Hangul},
{0xffca, 0xffcf, HB_Script_Hangul},
{0xffd2, 0xffd7, HB_Script_Hangul},
{0xffda, 0xffdc, HB_Script_Hangul},
{0x10140, 0x1018a, HB_Script_Greek},
{0x101fd, 0x101fd, HB_Script_Inherited},
{0x1d167, 0x1d169, HB_Script_Inherited},
{0x1d17b, 0x1d182, HB_Script_Inherited},
{0x1d185, 0x1d18b, HB_Script_Inherited},
{0x1d1aa, 0x1d1ad, HB_Script_Inherited},
{0x1d200, 0x1d245, HB_Script_Greek},
{0xe0100, 0xe01ef, HB_Script_Inherited},
};
static const unsigned script_properties_count = 277;
#endif // SCRIPT_PROPERTIES_H_

View File

@ -0,0 +1,75 @@
import sys
from unicode_parse_common import *
# http://www.unicode.org/Public/5.1.0/ucd/Scripts.txt
script_to_harfbuzz = {
# This is the list of HB_Script_* at the time of writing
'Common': 'HB_Script_Common',
'Greek': 'HB_Script_Greek',
'Cyrillic': 'HB_Script_Cyrillic',
'Armenian': 'HB_Script_Armenian',
'Hebrew': 'HB_Script_Hebrew',
'Arabic': 'HB_Script_Arabic',
'Syriac': 'HB_Script_Syriac',
'Thaana': 'HB_Script_Thaana',
'Devanagari': 'HB_Script_Devanagari',
'Bengali': 'HB_Script_Bengali',
'Gurmukhi': 'HB_Script_Gurmukhi',
'Gujarati': 'HB_Script_Gujarati',
'Oriya': 'HB_Script_Oriya',
'Tamil': 'HB_Script_Tamil',
'Telugu': 'HB_Script_Telugu',
'Kannada': 'HB_Script_Kannada',
'Malayalam': 'HB_Script_Malayalam',
'Sinhala': 'HB_Script_Sinhala',
'Thai': 'HB_Script_Thai',
'Lao': 'HB_Script_Lao',
'Tibetan': 'HB_Script_Tibetan',
'Myanmar': 'HB_Script_Myanmar',
'Georgian': 'HB_Script_Georgian',
'Hangul': 'HB_Script_Hangul',
'Ogham': 'HB_Script_Ogham',
'Runic': 'HB_Script_Runic',
'Khmer': 'HB_Script_Khmer',
'Inherited': 'HB_Script_Inherited',
}
class ScriptDict(object):
def __init__(self, base):
self.base = base
def __getitem__(self, key):
r = self.base.get(key, None)
if r is None:
return 'HB_Script_Common'
return r
def main(infile, outfile):
ranges = unicode_file_parse(infile,
ScriptDict(script_to_harfbuzz),
'HB_Script_Common')
ranges = sort_and_merge(ranges)
print >>outfile, '// Generated from Unicode script tables\n'
print >>outfile, '#ifndef SCRIPT_PROPERTIES_H_'
print >>outfile, '#define SCRIPT_PROPERTIES_H_\n'
print >>outfile, '#include <stdint.h>'
print >>outfile, '#include "harfbuzz-shaper.h"\n'
print >>outfile, 'struct script_property {'
print >>outfile, ' uint32_t range_start;'
print >>outfile, ' uint32_t range_end;'
print >>outfile, ' HB_Script script;'
print >>outfile, '};\n'
print >>outfile, 'static const struct script_property script_properties[] = {'
for (start, end, value) in ranges:
print >>outfile, ' {0x%x, 0x%x, %s},' % (start, end, value)
print >>outfile, '};\n'
print >>outfile, 'static const unsigned script_properties_count = %d;\n' % len(ranges)
print >>outfile, '#endif // SCRIPT_PROPERTIES_H_'
if __name__ == '__main__':
if len(sys.argv) != 3:
print 'Usage: %s <input .txt> <output .h>' % sys.argv[0]
else:
main(file(sys.argv[1], 'r'), file(sys.argv[2], 'w+'))

View File

@ -0,0 +1,70 @@
def lines_get(f):
'''Parse a file like object, removing comments and returning a list of
lines.'''
def cut_comment(line):
first_hash = line.find('#')
if first_hash == -1:
return line
return line[:first_hash]
return [x for x in [cut_comment(x[:-1]) for x in f.readlines()] if len(x)]
def line_split(line):
'''Split a line based on a semicolon separator.'''
def normalise(word):
return word.lstrip().rstrip()
return [normalise(x) for x in line.split(';')]
def codepoints_parse(token):
'''Parse a Unicode style code-point range. Return either a single value or a
tuple of (start, end) for a range of code-points.'''
def fromHex(token):
return int(token, 16)
parts = token.split('..')
if len(parts) == 2:
return (fromHex(parts[0]), fromHex(parts[1]))
elif len(parts) == 1:
return fromHex(parts[0])
else:
raise ValueError(token)
def unicode_file_parse(input, map, default_value = None):
'''Parse a file like object, @input where the first column is a code-point
range and the second column is mapped via the given dict, @map.'''
ranges = []
tokens = [line_split(x) for x in lines_get(input)]
for line in tokens:
if len(line) == 2:
codepoints = codepoints_parse(line[0])
value = map[line[1]]
if value == default_value:
continue
if type(codepoints) == int:
codepoints = (codepoints, codepoints)
ranges.append((codepoints[0], codepoints[1], value))
else:
raise ValueError(line)
return ranges
def sort_and_merge(ranges):
'''Given a list of (start, end, value), merge elements where the ranges are
continuous and the values are the same.'''
output = []
ranges.sort()
current = None
for v in ranges:
if current is None:
current = v
continue
if current[1] + 1 == v[0] and current[2] == v[2]:
current = (current[0], v[1], v[2])
else:
output.append(current)
current = v
if current is not None:
output.append(current)
return output

69
third_party/harfbuzz/harfbuzz.gyp vendored Normal file
View File

@ -0,0 +1,69 @@
# Copyright (c) 2009 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
{
'targets': [
{
'target_name': 'harfbuzz',
'type': '<(library)',
'sources': [
'src/harfbuzz-buffer.c',
'src/harfbuzz-stream.c',
'src/harfbuzz-dump.c',
'src/harfbuzz-gdef.c',
'src/harfbuzz-gpos.c',
'src/harfbuzz-gsub.c',
'src/harfbuzz-impl.c',
'src/harfbuzz-open.c',
'src/harfbuzz-shaper.cpp',
'src/harfbuzz-tibetan.c',
'src/harfbuzz-khmer.c',
'src/harfbuzz-indic.cpp',
'src/harfbuzz-hebrew.c',
'src/harfbuzz-arabic.c',
'src/harfbuzz-hangul.c',
'src/harfbuzz-myanmar.c',
'src/harfbuzz-thai.c',
],
'include_dirs': [
'src',
],
'direct_dependent_settings': {
'include_dirs': [
'src',
],
},
'dependencies': [
'../../build/linux/system.gyp:freetype2',
],
},
{
'target_name': 'harfbuzz_interface',
'type': '<(library)',
'sources': [
'contrib/harfbuzz-freetype.c',
'contrib/harfbuzz-unicode.c',
'contrib/harfbuzz-unicode-tables.c',
],
'include_dirs': [
'src',
'contrib',
],
'direct_dependent_settings': {
'include_dirs': [
'contrib',
],
},
'dependencies': [
'../../build/linux/system.gyp:freetype2',
],
},
],
}
# Local Variables:
# tab-width:2
# indent-tabs-mode:nil
# End:
# vim: set expandtab tabstop=2 shiftwidth=2:

7
third_party/harfbuzz/src/.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
*.o
*.lo
Makefile
*.la
.deps
.libs
*~

68
third_party/harfbuzz/src/Makefile.am vendored Normal file
View File

@ -0,0 +1,68 @@
## Process this file with automake to produce Makefile.in
noinst_LTLIBRARIES = libharfbuzz-1.la
MAINSOURCES = \
harfbuzz-buffer.c \
harfbuzz-stream.c \
harfbuzz-dump.c \
harfbuzz-gdef.c \
harfbuzz-gpos.c \
harfbuzz-gsub.c \
harfbuzz-impl.c \
harfbuzz-open.c \
harfbuzz-shaper.cpp \
harfbuzz-tibetan.c \
harfbuzz-khmer.c \
harfbuzz-indic.cpp \
harfbuzz-hebrew.c \
harfbuzz-arabic.c \
harfbuzz-hangul.c \
harfbuzz-myanmar.c \
harfbuzz-thai.c
EXTRA_SOURCES = harfbuzz.c
PUBLICHEADERS = \
harfbuzz.h \
harfbuzz-buffer.h \
harfbuzz-dump.h \
harfbuzz-gdef.h \
harfbuzz-gpos.h \
harfbuzz-gsub.h \
harfbuzz-open.h \
harfbuzz-global.h \
harfbuzz-external.h \
harfbuzz-shaper.h \
harfbuzz-stream.h
PRIVATEHEADERS = \
harfbuzz-impl.h \
harfbuzz-buffer-private.h \
harfbuzz-stream-private.h \
harfbuzz-gdef-private.h \
harfbuzz-gpos-private.h \
harfbuzz-gsub-private.h \
harfbuzz-open-private.h \
harfbuzz-shaper-private.h
libharfbuzz_1_la_SOURCES = \
$(MAINSOURCES) \
$(PUBLICHEADERS) \
$(PRIVATEHEADERS)
#noinst_PROGRAMS = harfbuzz-dump
#
#harfbuzz_dump_SOURCES = \
# harfbuzz-dump-main.c
#
#harfbuzz_dump_LDADD = \
# libharfbuzz-1.la
EXTRA_DIST = \
README \
COPYING.FTL \
COPYING.GPL \
COPYING \
$(EXTRA_SOURCES)

1145
third_party/harfbuzz/src/harfbuzz-arabic.c vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,107 @@
/*
* Copyright (C) 1998-2004 David Turner and Werner Lemberg
* Copyright (C) 2004,2007 Red Hat, Inc.
*
* This is part of HarfBuzz, an OpenType Layout engine library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Red Hat Author(s): Owen Taylor, Behdad Esfahbod
*/
#ifndef HARFBUZZ_BUFFER_PRIVATE_H
#define HARFBUZZ_BUFFER_PRIVATE_H
#include "harfbuzz-impl.h"
#include "harfbuzz-buffer.h"
HB_BEGIN_HEADER
#define HB_GLYPH_PROPERTIES_UNKNOWN 0xFFFF
HB_INTERNAL void
_hb_buffer_swap( HB_Buffer buffer );
HB_INTERNAL void
_hb_buffer_clear_output( HB_Buffer buffer );
HB_INTERNAL HB_Error
_hb_buffer_clear_positions( HB_Buffer buffer );
HB_INTERNAL HB_Error
_hb_buffer_add_output_glyphs( HB_Buffer buffer,
HB_UShort num_in,
HB_UShort num_out,
HB_UShort *glyph_data,
HB_UShort component,
HB_UShort ligID );
HB_INTERNAL HB_Error
_hb_buffer_add_output_glyph ( HB_Buffer buffer,
HB_UInt glyph_index,
HB_UShort component,
HB_UShort ligID );
HB_INTERNAL HB_Error
_hb_buffer_copy_output_glyph ( HB_Buffer buffer );
HB_INTERNAL HB_Error
_hb_buffer_replace_output_glyph ( HB_Buffer buffer,
HB_UInt glyph_index,
HB_Bool inplace );
HB_INTERNAL HB_UShort
_hb_buffer_allocate_ligid( HB_Buffer buffer );
/* convenience macros */
#define IN_GLYPH( pos ) (buffer->in_string[(pos)].gindex)
#define IN_ITEM( pos ) (&buffer->in_string[(pos)])
#define IN_CURGLYPH() (buffer->in_string[buffer->in_pos].gindex)
#define IN_CURITEM() (&buffer->in_string[buffer->in_pos])
#define IN_PROPERTIES( pos ) (buffer->in_string[(pos)].properties)
#define IN_LIGID( pos ) (buffer->in_string[(pos)].ligID)
#define IN_COMPONENT( pos ) (buffer->in_string[(pos)].component)
#define POSITION( pos ) (&buffer->positions[(pos)])
#define OUT_GLYPH( pos ) (buffer->out_string[(pos)].gindex)
#define OUT_ITEM( pos ) (&buffer->out_string[(pos)])
#define CHECK_Property( gdef, index, flags, property ) \
( ( error = _HB_GDEF_Check_Property( (gdef), (index), (flags), \
(property) ) ) != HB_Err_Ok )
#define ADD_String( buffer, num_in, num_out, glyph_data, component, ligID ) \
( ( error = _hb_buffer_add_output_glyphs( (buffer), \
(num_in), (num_out), \
(glyph_data), (component), (ligID) \
) ) != HB_Err_Ok )
#define ADD_Glyph( buffer, glyph_index, component, ligID ) \
( ( error = _hb_buffer_add_output_glyph( (buffer), \
(glyph_index), (component), (ligID) \
) ) != HB_Err_Ok )
#define REPLACE_Glyph( buffer, glyph_index, nesting_level ) \
( ( error = _hb_buffer_replace_output_glyph( (buffer), (glyph_index), \
(nesting_level) == 1 ) ) != HB_Err_Ok )
#define COPY_Glyph( buffer ) \
( (error = _hb_buffer_copy_output_glyph ( buffer ) ) != HB_Err_Ok )
HB_END_HEADER
#endif /* HARFBUZZ_BUFFER_PRIVATE_H */

View File

@ -0,0 +1,383 @@
/*
* Copyright (C) 1998-2004 David Turner and Werner Lemberg
* Copyright (C) 2004,2007 Red Hat, Inc.
*
* This is part of HarfBuzz, an OpenType Layout engine library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Red Hat Author(s): Owen Taylor, Behdad Esfahbod
*/
#include "harfbuzz-impl.h"
#include "harfbuzz-buffer-private.h"
#include "harfbuzz-gsub-private.h"
#include "harfbuzz-gpos-private.h"
/* Here is how the buffer works internally:
*
* There are two string pointers: in_string and out_string. They
* always have same allocated size, but different length and positions.
*
* As an optimization, both in_string and out_string may point to the
* same piece of memory, which is owned by in_string. This remains the
* case as long as:
*
* - copy_glyph() is called
* - replace_glyph() is called with inplace=TRUE
* - add_output_glyph() and add_output_glyphs() are not called
*
* In that case swap(), and copy_glyph(), and replace_glyph() are all
* mostly no-op.
*
* As soon an add_output_glyph[s]() or replace_glyph() with inplace=FALSE is
* called, out_string is moved over to an alternate buffer (alt_string), and
* its current contents (out_length entries) are copied to the alt buffer.
* This should all remain transparent to the user. swap() then switches
* in_string and alt_string. alt_string is not allocated until its needed,
* but after that it's grown with in_string unconditionally.
*
* The buffer->separate_out boolean keeps status of whether out_string points
* to in_string (FALSE) or alt_string (TRUE).
*/
/* Internal API */
static HB_Error
hb_buffer_ensure( HB_Buffer buffer,
HB_UInt size )
{
HB_UInt new_allocated = buffer->allocated;
if (size > new_allocated)
{
HB_Error error;
while (size > new_allocated)
new_allocated += (new_allocated >> 1) + 8;
if ( buffer->positions )
{
if ( REALLOC_ARRAY( buffer->positions, new_allocated, HB_PositionRec ) )
return error;
}
if ( REALLOC_ARRAY( buffer->in_string, new_allocated, HB_GlyphItemRec ) )
return error;
if ( buffer->separate_out )
{
if ( REALLOC_ARRAY( buffer->alt_string, new_allocated, HB_GlyphItemRec ) )
return error;
buffer->out_string = buffer->alt_string;
}
else
{
buffer->out_string = buffer->in_string;
if ( buffer->alt_string )
{
if ( REALLOC_ARRAY( buffer->alt_string, new_allocated, HB_GlyphItemRec ) )
return error;
}
}
buffer->allocated = new_allocated;
}
return HB_Err_Ok;
}
static HB_Error
hb_buffer_duplicate_out_buffer( HB_Buffer buffer )
{
if ( !buffer->alt_string )
{
HB_Error error;
if ( ALLOC_ARRAY( buffer->alt_string, buffer->allocated, HB_GlyphItemRec ) )
return error;
}
buffer->out_string = buffer->alt_string;
memcpy( buffer->out_string, buffer->in_string, buffer->out_length * sizeof (buffer->out_string[0]) );
buffer->separate_out = TRUE;
return HB_Err_Ok;
}
/* Public API */
HB_Error
hb_buffer_new( HB_Buffer *pbuffer )
{
HB_Buffer buffer;
HB_Error error;
if ( ALLOC( buffer, sizeof( HB_BufferRec ) ) )
return error;
buffer->allocated = 0;
buffer->in_string = NULL;
buffer->alt_string = NULL;
buffer->positions = NULL;
hb_buffer_clear( buffer );
*pbuffer = buffer;
return HB_Err_Ok;
}
void
hb_buffer_free( HB_Buffer buffer )
{
FREE( buffer->in_string );
FREE( buffer->alt_string );
buffer->out_string = NULL;
FREE( buffer->positions );
FREE( buffer );
}
void
hb_buffer_clear( HB_Buffer buffer )
{
buffer->in_length = 0;
buffer->out_length = 0;
buffer->in_pos = 0;
buffer->out_pos = 0;
buffer->out_string = buffer->in_string;
buffer->separate_out = FALSE;
buffer->max_ligID = 0;
}
HB_Error
hb_buffer_add_glyph( HB_Buffer buffer,
HB_UInt glyph_index,
HB_UInt properties,
HB_UInt cluster )
{
HB_Error error;
HB_GlyphItem glyph;
error = hb_buffer_ensure( buffer, buffer->in_length + 1 );
if ( error )
return error;
glyph = &buffer->in_string[buffer->in_length];
glyph->gindex = glyph_index;
glyph->properties = properties;
glyph->cluster = cluster;
glyph->component = 0;
glyph->ligID = 0;
glyph->gproperties = HB_GLYPH_PROPERTIES_UNKNOWN;
buffer->in_length++;
return HB_Err_Ok;
}
/* HarfBuzz-Internal API */
HB_INTERNAL void
_hb_buffer_clear_output( HB_Buffer buffer )
{
buffer->out_length = 0;
buffer->out_pos = 0;
buffer->out_string = buffer->in_string;
buffer->separate_out = FALSE;
}
HB_INTERNAL HB_Error
_hb_buffer_clear_positions( HB_Buffer buffer )
{
if ( !buffer->positions )
{
HB_Error error;
if ( ALLOC_ARRAY( buffer->positions, buffer->allocated, HB_PositionRec ) )
return error;
}
memset (buffer->positions, 0, sizeof (buffer->positions[0]) * buffer->in_length);
return HB_Err_Ok;
}
HB_INTERNAL void
_hb_buffer_swap( HB_Buffer buffer )
{
HB_GlyphItem tmp_string;
int tmp_length;
int tmp_pos;
if ( buffer->separate_out )
{
tmp_string = buffer->in_string;
buffer->in_string = buffer->out_string;
buffer->out_string = tmp_string;
buffer->alt_string = buffer->out_string;
}
tmp_length = buffer->in_length;
buffer->in_length = buffer->out_length;
buffer->out_length = tmp_length;
tmp_pos = buffer->in_pos;
buffer->in_pos = buffer->out_pos;
buffer->out_pos = tmp_pos;
}
/* The following function copies `num_out' elements from `glyph_data'
to `buffer->out_string', advancing the in array pointer in the structure
by `num_in' elements, and the out array pointer by `num_out' elements.
Finally, it sets the `length' field of `out' equal to
`pos' of the `out' structure.
If `component' is 0xFFFF, the component value from buffer->in_pos
will copied `num_out' times, otherwise `component' itself will
be used to fill the `component' fields.
If `ligID' is 0xFFFF, the ligID value from buffer->in_pos
will copied `num_out' times, otherwise `ligID' itself will
be used to fill the `ligID' fields.
The properties for all replacement glyphs are taken
from the glyph at position `buffer->in_pos'.
The cluster value for the glyph at position buffer->in_pos is used
for all replacement glyphs */
HB_INTERNAL HB_Error
_hb_buffer_add_output_glyphs( HB_Buffer buffer,
HB_UShort num_in,
HB_UShort num_out,
HB_UShort *glyph_data,
HB_UShort component,
HB_UShort ligID )
{
HB_Error error;
HB_UShort i;
HB_UInt properties;
HB_UInt cluster;
error = hb_buffer_ensure( buffer, buffer->out_pos + num_out );
if ( error )
return error;
if ( !buffer->separate_out )
{
error = hb_buffer_duplicate_out_buffer( buffer );
if ( error )
return error;
}
properties = buffer->in_string[buffer->in_pos].properties;
cluster = buffer->in_string[buffer->in_pos].cluster;
if ( component == 0xFFFF )
component = buffer->in_string[buffer->in_pos].component;
if ( ligID == 0xFFFF )
ligID = buffer->in_string[buffer->in_pos].ligID;
for ( i = 0; i < num_out; i++ )
{
HB_GlyphItem item = &buffer->out_string[buffer->out_pos + i];
item->gindex = glyph_data[i];
item->properties = properties;
item->cluster = cluster;
item->component = component;
item->ligID = ligID;
item->gproperties = HB_GLYPH_PROPERTIES_UNKNOWN;
}
buffer->in_pos += num_in;
buffer->out_pos += num_out;
buffer->out_length = buffer->out_pos;
return HB_Err_Ok;
}
HB_INTERNAL HB_Error
_hb_buffer_add_output_glyph( HB_Buffer buffer,
HB_UInt glyph_index,
HB_UShort component,
HB_UShort ligID )
{
HB_UShort glyph_data = glyph_index;
return _hb_buffer_add_output_glyphs ( buffer, 1, 1,
&glyph_data, component, ligID );
}
HB_INTERNAL HB_Error
_hb_buffer_copy_output_glyph ( HB_Buffer buffer )
{
HB_Error error;
error = hb_buffer_ensure( buffer, buffer->out_pos + 1 );
if ( error )
return error;
if ( buffer->separate_out )
{
buffer->out_string[buffer->out_pos] = buffer->in_string[buffer->in_pos];
}
buffer->in_pos++;
buffer->out_pos++;
buffer->out_length = buffer->out_pos;
return HB_Err_Ok;
}
HB_INTERNAL HB_Error
_hb_buffer_replace_output_glyph( HB_Buffer buffer,
HB_UInt glyph_index,
HB_Bool inplace )
{
HB_Error error;
if ( inplace )
{
error = _hb_buffer_copy_output_glyph ( buffer );
if ( error )
return error;
buffer->out_string[buffer->out_pos-1].gindex = glyph_index;
}
else
{
return _hb_buffer_add_output_glyph( buffer, glyph_index, 0xFFFF, 0xFFFF );
}
return HB_Err_Ok;
}
HB_INTERNAL HB_UShort
_hb_buffer_allocate_ligid( HB_Buffer buffer )
{
buffer->max_ligID++;
if (HB_UNLIKELY (buffer->max_ligID == 0))
buffer->max_ligID++;
return buffer->max_ligID;
}

View File

@ -0,0 +1,94 @@
/*
* Copyright (C) 1998-2004 David Turner and Werner Lemberg
* Copyright (C) 2004,2007 Red Hat, Inc.
*
* This is part of HarfBuzz, an OpenType Layout engine library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Red Hat Author(s): Owen Taylor, Behdad Esfahbod
*/
#ifndef HARFBUZZ_BUFFER_H
#define HARFBUZZ_BUFFER_H
#include "harfbuzz-global.h"
HB_BEGIN_HEADER
typedef struct HB_GlyphItemRec_ {
HB_UInt gindex;
HB_UInt properties;
HB_UInt cluster;
HB_UShort component;
HB_UShort ligID;
HB_UShort gproperties;
} HB_GlyphItemRec, *HB_GlyphItem;
typedef struct HB_PositionRec_ {
HB_Fixed x_pos;
HB_Fixed y_pos;
HB_Fixed x_advance;
HB_Fixed y_advance;
HB_UShort back; /* number of glyphs to go back
for drawing current glyph */
HB_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. */
HB_Short cursive_chain; /* character to which this connects,
may be positive or negative; used
only internally */
} HB_PositionRec, *HB_Position;
typedef struct HB_BufferRec_{
HB_UInt allocated;
HB_UInt in_length;
HB_UInt out_length;
HB_UInt in_pos;
HB_UInt out_pos;
HB_Bool separate_out;
HB_GlyphItem in_string;
HB_GlyphItem out_string;
HB_GlyphItem alt_string;
HB_Position positions;
HB_UShort max_ligID;
} HB_BufferRec, *HB_Buffer;
HB_Error
hb_buffer_new( HB_Buffer *buffer );
void
hb_buffer_free( HB_Buffer buffer );
void
hb_buffer_clear( HB_Buffer buffer );
HB_Error
hb_buffer_add_glyph( HB_Buffer buffer,
HB_UInt glyph_index,
HB_UInt properties,
HB_UInt cluster );
HB_END_HEADER
#endif /* HARFBUZZ_BUFFER_H */

View File

@ -0,0 +1,97 @@
/*
* Copyright (C) 2000 Red Hat, Inc.
*
* This is part of HarfBuzz, an OpenType Layout engine library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Red Hat Author(s): Owen Taylor
*/
#include <stdio.h>
#include <stdlib.h>
#include "harfbuzz.h"
#include "harfbuzz-dump.h"
#define N_ELEMENTS(arr) (sizeof(arr)/ sizeof((arr)[0]))
static int
croak (const char *situation, HB_Error error)
{
fprintf (stderr, "%s: Error %d\n", situation, error);
exit (1);
}
int
main (int argc, char **argv)
{
HB_Error error;
FT_Library library;
HB_Font font;
HB_GSUB gsub;
HB_GPOS gpos;
if (argc != 2)
{
fprintf (stderr, "Usage: harfbuzz-dump 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, &font)))
croak ("FT_New_Face", error);
printf ("<?xml version=\"1.0\"?>\n");
printf ("<OpenType>\n");
if (!(error = HB_Load_GSUB_Table (font, &gsub, NULL)))
{
HB_Dump_GSUB_Table (gsub, stdout);
if ((error = HB_Done_GSUB_Table (gsub)))
croak ("HB_Done_GSUB_Table", error);
}
else if (error != HB_Err_Not_Covered)
fprintf (stderr, "HB_Load_GSUB_Table: error 0x%x\n", error);
if (!(error = HB_Load_GPOS_Table (font, &gpos, NULL)))
{
HB_Dump_GPOS_Table (gpos, stdout);
if ((error = HB_Done_GPOS_Table (gpos)))
croak ("HB_Done_GPOS_Table", error);
}
else if (error != HB_Err_Not_Covered)
fprintf (stderr, "HB_Load_GPOS_Table: error 0x%x\n", error);
printf ("</OpenType>\n");
if ((error = FT_Done_Face (font)))
croak ("FT_Done_Face", error);
if ((error = FT_Done_FreeType (library)))
croak ("FT_Done_FreeType", error);
return 0;
}

765
third_party/harfbuzz/src/harfbuzz-dump.c vendored Normal file
View File

@ -0,0 +1,765 @@
/*
* Copyright (C) 2000, 2007 Red Hat, Inc.
*
* This is part of HarfBuzz, an OpenType Layout engine library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Red Hat Author(s): Owen Taylor, Behdad Esfahbod
*/
#include "harfbuzz-impl.h"
#include "harfbuzz-dump.h"
#include "harfbuzz-gdef-private.h"
#include "harfbuzz-gsub-private.h"
#include "harfbuzz-gpos-private.h"
#include "harfbuzz-open-private.h"
#include <stdarg.h>
#define DUMP(format) dump (stream, indent, format)
#define DUMP1(format, arg1) dump (stream, indent, format, arg1)
#define DUMP2(format, arg1, arg2) dump (stream, indent, format, arg1, arg2)
#define DUMP3(format, arg1, arg2, arg3) dump (stream, indent, format, arg1, arg2, arg3)
#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 ">%#06x</" #fld ">\n", (strct)->fld)
#define DUMP_FGLYPH(strct,fld) dump (stream, indent, "<" #fld ">%#06x</" #fld ">\n", (strct)->fld)
#define DUMP_USHORT_ARRAY(strct,fld,cnt) Dump_UShort_Array ((strct)->fld, cnt, #fld, stream, indent);
#define DEF_DUMP(type) static void Dump_ ## type (HB_ ## type *type, FILE *stream, int indent, HB_Type hb_type)
#define RECURSE(name, type, val) do { DUMP ("<" #name ">\n"); Dump_ ## type (val, stream, indent + 1, hb_type); DUMP ("</" #name ">\n"); } while (0)
#define RECURSE_NUM(name, i, type, val) do { DUMP1 ("<" #name "> <!-- %d -->\n", i); Dump_ ## type (val, stream, indent + 1, hb_type); DUMP ("</" #name ">\n"); } while (0)
#define DUMP_VALUE_RECORD(val, frmt) do { DUMP ("<ValueRecord>\n"); Dump_ValueRecord (val, stream, indent + 1, hb_type, frmt); DUMP ("</ValueRecord>\n"); } while (0)
static void
do_indent (FILE *stream, int indent)
{
fprintf (stream, "%*s", indent * 3, "");
}
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
Dump_UShort_Array (HB_UShort *array, int count, const char *name, FILE *stream, int indent)
{
int i;
do_indent (stream, indent);
fprintf (stream, "<%s>", name);
for (i = 0; i < count; i++)
fprintf (stream, "%d%s", array[i], i == 0 ? "" : " ");
fprintf (stream, "</%s>\n", name);
}
static void
Print_Tag (HB_UInt tag, FILE *stream)
{
fprintf (stream, "%c%c%c%c",
(unsigned char)(tag >> 24),
(unsigned char)((tag >> 16) & 0xff),
(unsigned char)((tag >> 8) & 0xff),
(unsigned char)(tag & 0xff));
}
DEF_DUMP (LangSys)
{
int i;
HB_UNUSED(hb_type);
DUMP_FUINT (LangSys, LookupOrderOffset);
DUMP_FUINT (LangSys, ReqFeatureIndex);
DUMP_FUINT (LangSys, FeatureCount);
for (i=0; i < LangSys->FeatureCount; i++)
DUMP1("<FeatureIndex>%d</FeatureIndex>\n", LangSys->FeatureIndex[i]);
}
DEF_DUMP (ScriptTable)
{
int i;
RECURSE (DefaultLangSys, LangSys, &ScriptTable->DefaultLangSys);
DUMP_FUINT (ScriptTable, LangSysCount);
for (i=0; i < ScriptTable->LangSysCount; i++)
{
do_indent (stream, indent);
fprintf (stream, "<LangSysTag>");
Print_Tag (ScriptTable->LangSysRecord[i].LangSysTag, stream);
fprintf (stream, "</LangSysTag>\n");
RECURSE_NUM (LangSys, i, LangSys, &ScriptTable->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_NUM (Script, i, ScriptTable, &ScriptList->ScriptRecord[i].Script);
}
}
DEF_DUMP (Feature)
{
int i;
HB_UNUSED(hb_type);
DUMP_FUINT (Feature, FeatureParams);
DUMP_FUINT (Feature, LookupListCount);
for (i=0; i < Feature->LookupListCount; i++)
DUMP1("<LookupIndex>%d</LookupIndex>\n", Feature->LookupListIndex[i]);
}
DEF_DUMP (MarkRecord)
{
HB_UNUSED(hb_type);
DUMP_FUINT (MarkRecord, Class);
DUMP1("<Anchor>%d</Anchor>\n", MarkRecord->MarkAnchor.PosFormat );
}
DEF_DUMP (MarkArray)
{
int i;
DUMP_FUINT (MarkArray, MarkCount);
for (i=0; i < MarkArray->MarkCount; i++)
RECURSE_NUM (MarkRecord, i, MarkRecord, &MarkArray->MarkRecord[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> <!-- %d -->\n", i);
RECURSE_NUM (Feature, i, Feature, &FeatureList->FeatureRecord[i].Feature);
}
}
DEF_DUMP (Coverage)
{
HB_UNUSED(hb_type);
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++)
DUMP2("<Glyph>%#06x</Glyph> <!-- %d -->\n",
Coverage->cf.cf1.GlyphArray[i], i);
}
else
{
int i;
DUMP_FUINT (&Coverage->cf.cf2, RangeCount);
for ( i = 0; i < Coverage->cf.cf2.RangeCount; i++ )
DUMP3("<Glyph>%#06x - %#06x</Glyph> <!-- %d -->\n",
Coverage->cf.cf2.RangeRecord[i].Start,
Coverage->cf.cf2.RangeRecord[i].End, i);
}
}
DEF_DUMP (ClassRangeRecord)
{
HB_UNUSED(hb_type);
DUMP_FGLYPH (ClassRangeRecord, Start);
DUMP_FGLYPH (ClassRangeRecord, End);
DUMP_FUINT (ClassRangeRecord, Class);
}
DEF_DUMP (ClassDefinition)
{
HB_UNUSED(hb_type);
DUMP_FUINT( ClassDefinition, ClassFormat);
DUMP_FUINT( ClassDefinition, loaded);
if (ClassDefinition->ClassFormat == 1)
{
int i;
HB_ClassDefFormat1 *ClassDefFormat1 = &ClassDefinition->cd.cd1;
DUMP("<ClassDefinition>\n");
DUMP_FUINT (ClassDefFormat1, StartGlyph );
DUMP_FUINT (ClassDefFormat1, GlyphCount );
for (i = 0; i < ClassDefFormat1->GlyphCount; i++)
DUMP2(" <Class>%d</Class> <!-- %#06x -->", ClassDefFormat1->ClassValueArray[i],
ClassDefFormat1->StartGlyph+i );
}
else if (ClassDefinition->ClassFormat == 2)
{
int i;
HB_ClassDefFormat2 *ClassDefFormat2 = &ClassDefinition->cd.cd2;
DUMP_FUINT (ClassDefFormat2, ClassRangeCount);
for (i = 0; i < ClassDefFormat2->ClassRangeCount; i++)
RECURSE_NUM (ClassRangeRecord, i, ClassRangeRecord, &ClassDefFormat2->ClassRangeRecord[i]);
}
else
fprintf(stderr, "invalid class def table!!!\n");
}
DEF_DUMP (SubstLookupRecord)
{
HB_UNUSED(hb_type);
DUMP_FUINT (SubstLookupRecord, SequenceIndex);
DUMP_FUINT (SubstLookupRecord, LookupListIndex);
}
DEF_DUMP (ChainSubClassRule)
{
int i;
DUMP_USHORT_ARRAY (ChainSubClassRule, Backtrack, ChainSubClassRule->BacktrackGlyphCount);
DUMP_USHORT_ARRAY (ChainSubClassRule, Input, ChainSubClassRule->InputGlyphCount - 1);
DUMP_USHORT_ARRAY (ChainSubClassRule, Lookahead, ChainSubClassRule->LookaheadGlyphCount);
for (i = 0; i < ChainSubClassRule->SubstCount; i++)
RECURSE_NUM (SubstLookupRecord, i, SubstLookupRecord, &ChainSubClassRule->SubstLookupRecord[i]);
indent--;
}
DEF_DUMP (ChainSubClassSet)
{
int i;
DUMP_FUINT( ChainSubClassSet, ChainSubClassRuleCount );
for (i = 0; i < ChainSubClassSet->ChainSubClassRuleCount; i++)
RECURSE_NUM (ChainSubClassRule, i, ChainSubClassRule, &ChainSubClassSet->ChainSubClassRule[i]);
}
static void
Dump_GSUB_Lookup_Single (HB_SubTable *subtable, FILE *stream, int indent, HB_Type hb_type)
{
HB_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++)
DUMP2("<Substitute>%#06x</Substitute> <!-- %d -->\n", SingleSubst->ssf.ssf2.Substitute[i], i);
}
}
DEF_DUMP (Ligature)
{
int i;
HB_UNUSED(hb_type);
DUMP_FGLYPH (Ligature, LigGlyph);
DUMP_FUINT (Ligature, ComponentCount);
for (i=0; i < Ligature->ComponentCount - 1; i++)
DUMP1("<Component>%#06x</Component>\n", Ligature->Component[i]);
}
DEF_DUMP (LigatureSet)
{
int i;
DUMP_FUINT (LigatureSet, LigatureCount);
for (i=0; i < LigatureSet->LigatureCount; i++)
RECURSE_NUM (Ligature, i, Ligature, &LigatureSet->Ligature[i]);
}
static void
Dump_GSUB_Lookup_Ligature (HB_SubTable *subtable, FILE *stream, int indent, HB_Type hb_type)
{
int i;
HB_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_NUM (LigatureSet, i, LigatureSet, &LigatureSubst->LigatureSet[i]);
}
DEF_DUMP (ContextSubstFormat1)
{
HB_UNUSED(hb_type);
HB_UNUSED(ContextSubstFormat1);
DUMP("<!-- Not implemented!!! -->\n");
}
DEF_DUMP (ContextSubstFormat2)
{
DUMP_FUINT (ContextSubstFormat2, MaxContextLength);
RECURSE (Coverage, Coverage, &ContextSubstFormat2->Coverage);
RECURSE (ClassDefinition, ClassDefinition, &ContextSubstFormat2->ClassDef);
}
DEF_DUMP (ContextSubstFormat3)
{
HB_UNUSED(hb_type);
HB_UNUSED(ContextSubstFormat3);
DUMP("<!-- Not implemented!!! -->\n");
}
static void
Dump_GSUB_Lookup_Context (HB_SubTable *subtable, FILE *stream, int indent, HB_Type hb_type)
{
HB_ContextSubst *ContextSubst = &subtable->st.gsub.context;
DUMP_FUINT (ContextSubst, SubstFormat);
switch( ContextSubst->SubstFormat )
{
case 1:
Dump_ContextSubstFormat1 (&ContextSubst->csf.csf1, stream, indent+2, hb_type);
break;
case 2:
Dump_ContextSubstFormat2 (&ContextSubst->csf.csf2, stream, indent+2, hb_type);
break;
case 3:
Dump_ContextSubstFormat3 (&ContextSubst->csf.csf3, stream, indent+2, hb_type);
break;
default:
fprintf(stderr, "invalid subformat!!!!!\n");
}
}
DEF_DUMP (ChainContextSubstFormat1)
{
HB_UNUSED(hb_type);
HB_UNUSED(ChainContextSubstFormat1);
DUMP("<!-- Not implemented!!! -->\n");
}
DEF_DUMP (ChainContextSubstFormat2)
{
int i;
RECURSE (Coverage, Coverage, &ChainContextSubstFormat2->Coverage);
DUMP_FUINT (ChainContextSubstFormat2, MaxBacktrackLength);
RECURSE (ClassDefinition, ClassDefinition, &ChainContextSubstFormat2->BacktrackClassDef);
DUMP_FUINT (ChainContextSubstFormat2, MaxInputLength);
RECURSE (ClassDefinition, ClassDefinition, &ChainContextSubstFormat2->InputClassDef);
DUMP_FUINT (ChainContextSubstFormat2, MaxLookaheadLength);
RECURSE (ClassDefinition, ClassDefinition, &ChainContextSubstFormat2->LookaheadClassDef);
DUMP_FUINT (ChainContextSubstFormat2, ChainSubClassSetCount);
for (i = 0; i < ChainContextSubstFormat2->ChainSubClassSetCount; i++)
RECURSE (ChainSubClassSet, ChainSubClassSet, &ChainContextSubstFormat2->ChainSubClassSet[i]);
}
DEF_DUMP (ChainContextSubstFormat3)
{
int i;
DUMP_FUINT (ChainContextSubstFormat3, BacktrackGlyphCount);
for (i = 0; i < ChainContextSubstFormat3->BacktrackGlyphCount; i++)
RECURSE (BacktrackCoverage, Coverage, &ChainContextSubstFormat3->BacktrackCoverage[i]);
DUMP_FUINT (ChainContextSubstFormat3, InputGlyphCount);
for (i = 0; i < ChainContextSubstFormat3->InputGlyphCount; i++)
RECURSE (InputCoverage, Coverage, &ChainContextSubstFormat3->InputCoverage[i]);
DUMP_FUINT (ChainContextSubstFormat3, LookaheadGlyphCount);
for (i = 0; i < ChainContextSubstFormat3->LookaheadGlyphCount; i++)
RECURSE (LookaheadCoverage, Coverage, &ChainContextSubstFormat3->LookaheadCoverage[i]);
for (i = 0; i < ChainContextSubstFormat3->SubstCount; i++)
RECURSE_NUM (SubstLookupRecord, i, SubstLookupRecord, &ChainContextSubstFormat3->SubstLookupRecord[i]);
}
static void
Dump_GSUB_Lookup_Chain (HB_SubTable *subtable, FILE *stream, int indent, HB_Type hb_type)
{
HB_ChainContextSubst *chain = &subtable->st.gsub.chain;
DUMP_FUINT (chain, SubstFormat);
switch (chain->SubstFormat)
{
case 1:
Dump_ChainContextSubstFormat1 (&chain->ccsf.ccsf1, stream, indent+2, hb_type);
break;
case 2:
Dump_ChainContextSubstFormat2 (&chain->ccsf.ccsf2, stream, indent+2, hb_type);
break;
case 3:
Dump_ChainContextSubstFormat3 (&chain->ccsf.ccsf3, stream, indent+2, hb_type);
break;
default:
fprintf(stderr, "invalid subformat!!!!!\n");
}
}
static void
Dump_Device (HB_Device *Device, FILE *stream, int indent, HB_Type hb_type)
{
int i;
int bits;
int n_per;
unsigned int mask;
HB_UNUSED(hb_type);
DUMP_FUINT (Device, StartSize);
DUMP_FUINT (Device, EndSize);
DUMP_FUINT (Device, DeltaFormat);
switch (Device->DeltaFormat)
{
case 1:
bits = 2;
break;
case 2:
bits = 4;
break;
case 3:
bits = 8;
break;
default:
bits = 0;
break;
}
DUMP ("<DeltaValue>");
if (!bits)
{
fprintf(stderr, "invalid DeltaFormat!!!!!\n");
}
else
{
n_per = 16 / bits;
mask = (1 << bits) - 1;
mask = mask << (16 - bits);
for (i = Device->StartSize; i <= Device->EndSize ; i++)
{
HB_UShort val = Device->DeltaValue[i / n_per];
HB_Short signed_val = ((val << ((i % n_per) * bits)) & mask);
dump (stream, indent, "%d", signed_val >> (16 - bits));
if (i != Device->EndSize)
DUMP (", ");
}
}
DUMP ("</DeltaValue>\n");
}
static void
Dump_ValueRecord (HB_ValueRecord *ValueRecord, FILE *stream, int indent, HB_Type hb_type, HB_UShort value_format)
{
if (value_format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT)
DUMP_FINT (ValueRecord, XPlacement);
if (value_format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT)
DUMP_FINT (ValueRecord, YPlacement);
if (value_format & HB_GPOS_FORMAT_HAVE_X_ADVANCE)
DUMP_FINT (ValueRecord, XAdvance);
if (value_format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE)
DUMP_FINT (ValueRecord, XAdvance);
if (value_format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT_DEVICE)
RECURSE (Device, Device, &ValueRecord->XPlacementDevice);
if (value_format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT_DEVICE)
RECURSE (Device, Device, &ValueRecord->YPlacementDevice);
if (value_format & HB_GPOS_FORMAT_HAVE_X_ADVANCE_DEVICE)
RECURSE (Device, Device, &ValueRecord->XAdvanceDevice);
if (value_format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE_DEVICE)
RECURSE (Device, Device, &ValueRecord->YAdvanceDevice);
if (value_format & HB_GPOS_FORMAT_HAVE_X_ID_PLACEMENT)
DUMP_FUINT (ValueRecord, XIdPlacement);
if (value_format & HB_GPOS_FORMAT_HAVE_Y_ID_PLACEMENT)
DUMP_FUINT (ValueRecord, YIdPlacement);
if (value_format & HB_GPOS_FORMAT_HAVE_X_ID_ADVANCE)
DUMP_FUINT (ValueRecord, XIdAdvance);
if (value_format & HB_GPOS_FORMAT_HAVE_Y_ID_ADVANCE)
DUMP_FUINT (ValueRecord, XIdAdvance);
}
static void
Dump_GPOS_Lookup_Single (HB_SubTable *subtable, FILE *stream, int indent, HB_Type hb_type)
{
HB_SinglePos *SinglePos = &subtable->st.gpos.single;
DUMP_FUINT (SinglePos, PosFormat);
RECURSE (Coverage, Coverage, &SinglePos->Coverage);
DUMP_FUINT (SinglePos, ValueFormat);
if (SinglePos->PosFormat == 1)
{
DUMP_VALUE_RECORD (&SinglePos->spf.spf1.Value, SinglePos->ValueFormat);
}
else
{
int i;
DUMP_FUINT (&SinglePos->spf.spf2, ValueCount);
for (i = 0; i < SinglePos->spf.spf2.ValueCount; i++)
DUMP_VALUE_RECORD (&SinglePos->spf.spf2.Value[i], SinglePos->ValueFormat);
}
}
static void
Dump_PairValueRecord (HB_PairValueRecord *PairValueRecord, FILE *stream, int indent, HB_Type hb_type, HB_UShort ValueFormat1, HB_UShort ValueFormat2)
{
DUMP_FUINT (PairValueRecord, SecondGlyph);
DUMP_VALUE_RECORD (&PairValueRecord->Value1, ValueFormat1);
DUMP_VALUE_RECORD (&PairValueRecord->Value2, ValueFormat2);
}
static void
Dump_PairSet (HB_PairSet *PairSet, FILE *stream, int indent, HB_Type hb_type, HB_UShort ValueFormat1, HB_UShort ValueFormat2)
{
int i;
DUMP_FUINT (PairSet, PairValueCount);
for (i = 0; i < PairSet->PairValueCount; i++)
{
DUMP ("<PairValueRecord>\n");
Dump_PairValueRecord (&PairSet->PairValueRecord[i], stream, indent + 1, hb_type, ValueFormat1, ValueFormat2);
DUMP ("</PairValueRecord>\n");
}
}
static void
Dump_GPOS_Lookup_Pair (HB_SubTable *subtable, FILE *stream, int indent, HB_Type hb_type)
{
HB_PairPos *PairPos = &subtable->st.gpos.pair;
DUMP_FUINT (PairPos, PosFormat);
RECURSE (Coverage, Coverage, &PairPos->Coverage);
DUMP_FUINT (PairPos, ValueFormat1);
DUMP_FUINT (PairPos, ValueFormat2);
if (PairPos->PosFormat == 1)
{
int i;
DUMP_FUINT (&PairPos->ppf.ppf1, PairSetCount);
for (i = 0; i < PairPos->ppf.ppf1.PairSetCount; i++)
{
DUMP ("<PairSet>\n");
Dump_PairSet (&PairPos->ppf.ppf1.PairSet[i], stream, indent + 1, hb_type, PairPos->ValueFormat1, PairPos->ValueFormat2);
DUMP ("</PairSet>\n");
}
}
else
{
}
}
static void
Dump_GPOS_Lookup_Markbase (HB_SubTable *subtable, FILE *stream, int indent, HB_Type hb_type)
{
int i;
HB_MarkBasePos *markbase = &subtable->st.gpos.markbase;
DUMP_FUINT (markbase, PosFormat);
RECURSE (Coverage, Coverage, &markbase->MarkCoverage);
RECURSE (Coverage, Coverage, &markbase->BaseCoverage);
DUMP_FUINT (markbase, ClassCount);
RECURSE (MarkArray, MarkArray, &markbase->MarkArray);
DUMP ("<BaseArray>\n");
indent++;
DUMP_FUINT (&markbase->BaseArray, BaseCount);
for (i = 0; i < markbase->BaseArray.BaseCount; i++)
{
int j;
HB_BaseRecord *r = &markbase->BaseArray.BaseRecord[i];
DUMP1 ("<BaseRecord> <!-- %d -->\n", i);
for (j = 0; j < markbase->ClassCount; j++)
DUMP1 (" <Anchor>%d</Anchor>\n", r->BaseAnchor->PosFormat);
DUMP ("<BaseRecord>\n");
}
indent--;
DUMP ("</BaseArray>\n");
}
DEF_DUMP (Lookup)
{
int i;
const char *lookup_name;
void (*lookup_func) (HB_SubTable *subtable, FILE *stream, int indent, HB_Type hb_type) = NULL;
if (hb_type == HB_Type_GSUB)
{
switch (Lookup->LookupType)
{
case HB_GSUB_LOOKUP_SINGLE:
lookup_name = "SINGLE";
lookup_func = Dump_GSUB_Lookup_Single;
break;
case HB_GSUB_LOOKUP_MULTIPLE:
lookup_name = "MULTIPLE";
break;
case HB_GSUB_LOOKUP_ALTERNATE:
lookup_name = "ALTERNATE";
break;
case HB_GSUB_LOOKUP_LIGATURE:
lookup_name = "LIGATURE";
lookup_func = Dump_GSUB_Lookup_Ligature;
break;
case HB_GSUB_LOOKUP_CONTEXT:
lookup_name = "CONTEXT";
lookup_func = Dump_GSUB_Lookup_Context;
break;
case HB_GSUB_LOOKUP_CHAIN:
lookup_name = "CHAIN";
lookup_func = Dump_GSUB_Lookup_Chain;
break;
default:
lookup_name = "(unknown)";
lookup_func = NULL;
break;
}
}
else
{
switch (Lookup->LookupType)
{
case HB_GPOS_LOOKUP_SINGLE:
lookup_name = "SINGLE";
lookup_func = Dump_GPOS_Lookup_Single;
break;
case HB_GPOS_LOOKUP_PAIR:
lookup_name = "PAIR";
lookup_func = Dump_GPOS_Lookup_Pair;
break;
case HB_GPOS_LOOKUP_CURSIVE:
lookup_name = "CURSIVE";
break;
case HB_GPOS_LOOKUP_MARKBASE:
lookup_name = "MARKBASE";
lookup_func = Dump_GPOS_Lookup_Markbase;
break;
case HB_GPOS_LOOKUP_MARKLIG:
lookup_name = "MARKLIG";
break;
case HB_GPOS_LOOKUP_MARKMARK:
lookup_name = "MARKMARK";
break;
case HB_GPOS_LOOKUP_CONTEXT:
lookup_name = "CONTEXT";
break;
case HB_GPOS_LOOKUP_CHAIN:
lookup_name = "CHAIN";
break;
default:
lookup_name = "(unknown)";
lookup_func = NULL;
break;
}
}
DUMP2("<LookupType>%s</LookupType> <!-- %d -->\n", lookup_name, Lookup->LookupType);
DUMP1("<LookupFlag>%#06x</LookupFlag>\n", Lookup->LookupFlag);
for (i=0; i < Lookup->SubTableCount; i++)
{
DUMP ("<Subtable>\n");
if (lookup_func)
(*lookup_func) (&Lookup->SubTable[i], stream, indent + 1, hb_type);
DUMP ("</Subtable>\n");
}
}
DEF_DUMP (LookupList)
{
int i;
DUMP_FUINT (LookupList, LookupCount);
for (i=0; i < LookupList->LookupCount; i++)
RECURSE_NUM (Lookup, i, Lookup, &LookupList->Lookup[i]);
}
void
HB_Dump_GSUB_Table (HB_GSUB gsub, FILE *stream)
{
int indent = 1;
HB_Type hb_type = HB_Type_GSUB;
do_indent (stream, indent);
fprintf(stream, "<!-- GSUB -->\n");
RECURSE (ScriptList, ScriptList, &gsub->ScriptList);
RECURSE (FeatureList, FeatureList, &gsub->FeatureList);
RECURSE (LookupList, LookupList, &gsub->LookupList);
}
void
HB_Dump_GPOS_Table (HB_GPOS gpos, FILE *stream)
{
int indent = 1;
HB_Type hb_type = HB_Type_GPOS;
do_indent (stream, indent);
fprintf(stream, "<!-- GPOS -->\n");
RECURSE (ScriptList, ScriptList, &gpos->ScriptList);
RECURSE (FeatureList, FeatureList, &gpos->FeatureList);
RECURSE (LookupList, LookupList, &gpos->LookupList);
}

View File

@ -0,0 +1,41 @@
/*
* Copyright (C) 2000, 2007 Red Hat, Inc.
*
* This is part of HarfBuzz, an OpenType Layout engine library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Red Hat Author(s): Owen Taylor, Behdad Esfahbod
*/
#ifndef HARFBUZZ_DUMP_H
#define HARFBUZZ_DUMP_H
#include <stdio.h>
#include "harfbuzz-gsub.h"
#include "harfbuzz-gpos.h"
HB_BEGIN_HEADER
void HB_Dump_GSUB_Table (HB_GSUB gsub, FILE *stream);
void HB_Dump_GPOS_Table (HB_GPOS gpos, FILE *stream);
HB_END_HEADER
#endif /* HARFBUZZ_DUMP_H */

View File

@ -0,0 +1,157 @@
/*
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
*
* This is part of HarfBuzz, an OpenType Layout engine library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#ifndef HARFBUZZ_EXTERNAL_H
#define HARFBUZZ_EXTERNAL_H
#include "harfbuzz-global.h"
HB_BEGIN_HEADER
/* This header contains some methods that are not part of
Harfbuzz itself, but referenced by it.
They need to be provided by the application/library
*/
/*
see http://www.unicode.org/reports/tr14/tr14-19.html
we don't use the XX, AI and CB properties and map them to AL instead.
as we don't support any EBDIC based OS'es, NL is ignored and mapped to AL as well.
*/
typedef enum {
HB_LineBreak_OP, HB_LineBreak_CL, HB_LineBreak_QU, HB_LineBreak_GL, HB_LineBreak_NS,
HB_LineBreak_EX, HB_LineBreak_SY, HB_LineBreak_IS, HB_LineBreak_PR, HB_LineBreak_PO,
HB_LineBreak_NU, HB_LineBreak_AL, HB_LineBreak_ID, HB_LineBreak_IN, HB_LineBreak_HY,
HB_LineBreak_BA, HB_LineBreak_BB, HB_LineBreak_B2, HB_LineBreak_ZW, HB_LineBreak_CM,
HB_LineBreak_WJ, HB_LineBreak_H2, HB_LineBreak_H3, HB_LineBreak_JL, HB_LineBreak_JV,
HB_LineBreak_JT, HB_LineBreak_SA, HB_LineBreak_SG,
HB_LineBreak_SP, HB_LineBreak_CR, HB_LineBreak_LF, HB_LineBreak_BK
} HB_LineBreakClass;
typedef enum
{
HB_NoCategory,
HB_Mark_NonSpacing, /* Mn */
HB_Mark_SpacingCombining, /* Mc */
HB_Mark_Enclosing, /* Me */
HB_Number_DecimalDigit, /* Nd */
HB_Number_Letter, /* Nl */
HB_Number_Other, /* No */
HB_Separator_Space, /* Zs */
HB_Separator_Line, /* Zl */
HB_Separator_Paragraph, /* Zp */
HB_Other_Control, /* Cc */
HB_Other_Format, /* Cf */
HB_Other_Surrogate, /* Cs */
HB_Other_PrivateUse, /* Co */
HB_Other_NotAssigned, /* Cn */
HB_Letter_Uppercase, /* Lu */
HB_Letter_Lowercase, /* Ll */
HB_Letter_Titlecase, /* Lt */
HB_Letter_Modifier, /* Lm */
HB_Letter_Other, /* Lo */
HB_Punctuation_Connector, /* Pc */
HB_Punctuation_Dash, /* Pd */
HB_Punctuation_Open, /* Ps */
HB_Punctuation_Close, /* Pe */
HB_Punctuation_InitialQuote, /* Pi */
HB_Punctuation_FinalQuote, /* Pf */
HB_Punctuation_Other, /* Po */
HB_Symbol_Math, /* Sm */
HB_Symbol_Currency, /* Sc */
HB_Symbol_Modifier, /* Sk */
HB_Symbol_Other /* So */
} HB_CharCategory;
typedef enum
{
HB_Grapheme_Other,
HB_Grapheme_CR,
HB_Grapheme_LF,
HB_Grapheme_Control,
HB_Grapheme_Extend,
HB_Grapheme_L,
HB_Grapheme_V,
HB_Grapheme_T,
HB_Grapheme_LV,
HB_Grapheme_LVT
} HB_GraphemeClass;
typedef enum
{
HB_Word_Other,
HB_Word_Format,
HB_Word_Katakana,
HB_Word_ALetter,
HB_Word_MidLetter,
HB_Word_MidNum,
HB_Word_Numeric,
HB_Word_ExtendNumLet
} HB_WordClass;
typedef enum
{
HB_Sentence_Other,
HB_Sentence_Sep,
HB_Sentence_Format,
HB_Sentence_Sp,
HB_Sentence_Lower,
HB_Sentence_Upper,
HB_Sentence_OLetter,
HB_Sentence_Numeric,
HB_Sentence_ATerm,
HB_Sentence_STerm,
HB_Sentence_Close
} HB_SentenceClass;
HB_GraphemeClass HB_GetGraphemeClass(HB_UChar32 ch);
HB_WordClass HB_GetWordClass(HB_UChar32 ch);
HB_SentenceClass HB_GetSentenceClass(HB_UChar32 ch);
HB_LineBreakClass HB_GetLineBreakClass(HB_UChar32 ch);
void HB_GetGraphemeAndLineBreakClass(HB_UChar32 ch, HB_GraphemeClass *grapheme, HB_LineBreakClass *lineBreak);
void HB_GetUnicodeCharProperties(HB_UChar32 ch, HB_CharCategory *category, int *combiningClass);
HB_CharCategory HB_GetUnicodeCharCategory(HB_UChar32 ch);
int HB_GetUnicodeCharCombiningClass(HB_UChar32 ch);
HB_UChar16 HB_GetMirroredChar(HB_UChar16 ch);
void *HB_Library_Resolve(const char *library, const char *symbol);
void *HB_TextCodecForMib(int mib);
char *HB_TextCodec_ConvertFromUnicode(void *codec, const HB_UChar16 *unicode, hb_uint32 length, hb_uint32 *outputLength);
void HB_TextCodec_FreeResult(char *);
HB_END_HEADER
#endif

View File

@ -0,0 +1,124 @@
/*
* Copyright (C) 1998-2004 David Turner and Werner Lemberg
* Copyright (C) 2006 Behdad Esfahbod
*
* This is part of HarfBuzz, an OpenType Layout engine library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#ifndef HARFBUZZ_GDEF_PRIVATE_H
#define HARFBUZZ_GDEF_PRIVATE_H
#include "harfbuzz-impl.h"
#include "harfbuzz-stream-private.h"
#include "harfbuzz-buffer-private.h"
#include "harfbuzz-gdef.h"
HB_BEGIN_HEADER
/* Attachment related structures */
struct HB_AttachPoint_
{
HB_UShort PointCount; /* size of the PointIndex array */
HB_UShort* PointIndex; /* array of contour points */
};
/* Ligature Caret related structures */
struct HB_CaretValueFormat1_
{
HB_Short Coordinate; /* x or y value (in design units) */
};
typedef struct HB_CaretValueFormat1_ HB_CaretValueFormat1;
struct HB_CaretValueFormat2_
{
HB_UShort CaretValuePoint; /* contour point index on glyph */
};
typedef struct HB_CaretValueFormat2_ HB_CaretValueFormat2;
struct HB_CaretValueFormat3_
{
HB_Short Coordinate; /* x or y value (in design units) */
HB_Device Device; /* Device table for x or y value */
};
typedef struct HB_CaretValueFormat3_ HB_CaretValueFormat3;
struct HB_CaretValueFormat4_
{
HB_UShort IdCaretValue; /* metric ID */
};
typedef struct HB_CaretValueFormat4_ HB_CaretValueFormat4;
struct HB_CaretValue_
{
HB_UShort CaretValueFormat; /* 1, 2, 3, or 4 */
union
{
HB_CaretValueFormat1 cvf1;
HB_CaretValueFormat2 cvf2;
HB_CaretValueFormat3 cvf3;
HB_CaretValueFormat4 cvf4;
} cvf;
};
typedef struct HB_CaretValue_ HB_CaretValue;
struct HB_LigGlyph_
{
HB_Bool loaded;
HB_UShort CaretCount; /* number of caret values */
HB_CaretValue* CaretValue; /* array of caret values */
};
HB_INTERNAL HB_Error
_HB_GDEF_Add_Glyph_Property( HB_GDEFHeader* gdef,
HB_UShort glyphID,
HB_UShort property );
HB_INTERNAL HB_Error
_HB_GDEF_Check_Property( HB_GDEFHeader* gdef,
HB_GlyphItem item,
HB_UShort flags,
HB_UShort* property );
HB_INTERNAL HB_Error
_HB_GDEF_LoadMarkAttachClassDef_From_LookupFlags( HB_GDEFHeader* gdef,
HB_Stream input,
HB_Lookup* lo,
HB_UShort num_lookups );
HB_END_HEADER
#endif /* HARFBUZZ_GDEF_PRIVATE_H */

1159
third_party/harfbuzz/src/harfbuzz-gdef.c vendored Normal file

File diff suppressed because it is too large Load Diff

135
third_party/harfbuzz/src/harfbuzz-gdef.h vendored Normal file
View File

@ -0,0 +1,135 @@
/*
* Copyright (C) 1998-2004 David Turner and Werner Lemberg
* Copyright (C) 2006 Behdad Esfahbod
*
* This is part of HarfBuzz, an OpenType Layout engine library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#ifndef HARFBUZZ_GDEF_H
#define HARFBUZZ_GDEF_H
#include "harfbuzz-open.h"
#include "harfbuzz-stream.h"
HB_BEGIN_HEADER
/* GDEF glyph properties. Note that HB_GDEF_COMPONENT has no corresponding
* flag in the LookupFlag field. */
#define HB_GDEF_BASE_GLYPH 0x0002
#define HB_GDEF_LIGATURE 0x0004
#define HB_GDEF_MARK 0x0008
#define HB_GDEF_COMPONENT 0x0010
typedef struct HB_AttachPoint_ HB_AttachPoint;
struct HB_AttachList_
{
HB_Bool loaded;
HB_Coverage Coverage; /* Coverage table */
HB_UShort GlyphCount; /* number of glyphs with
attachments */
HB_AttachPoint* AttachPoint; /* array of AttachPoint tables */
};
typedef struct HB_AttachList_ HB_AttachList;
typedef struct HB_LigGlyph_ HB_LigGlyph;
struct HB_LigCaretList_
{
HB_Bool loaded;
HB_Coverage Coverage; /* Coverage table */
HB_UShort LigGlyphCount; /* number of ligature glyphs */
HB_LigGlyph* LigGlyph; /* array of LigGlyph tables */
};
typedef struct HB_LigCaretList_ HB_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 HB_GDEFHeader_
{
HB_UInt offset;
HB_16Dot16 Version;
HB_ClassDefinition GlyphClassDef;
HB_AttachList AttachList;
HB_LigCaretList LigCaretList;
HB_UInt MarkAttachClassDef_offset;
HB_ClassDefinition MarkAttachClassDef; /* new in OT 1.2 */
HB_UShort LastGlyph;
HB_UShort** NewGlyphClasses;
};
typedef struct HB_GDEFHeader_ HB_GDEFHeader;
typedef struct HB_GDEFHeader_* HB_GDEF;
HB_Error HB_New_GDEF_Table( HB_GDEFHeader** retptr );
HB_Error HB_Load_GDEF_Table( HB_Stream stream,
HB_GDEFHeader** gdef );
HB_Error HB_Done_GDEF_Table ( HB_GDEFHeader* gdef );
HB_Error HB_GDEF_Get_Glyph_Property( HB_GDEFHeader* gdef,
HB_UShort glyphID,
HB_UShort* property );
HB_Error HB_GDEF_Build_ClassDefinition( HB_GDEFHeader* gdef,
HB_UShort num_glyphs,
HB_UShort glyph_count,
HB_UShort* glyph_array,
HB_UShort* class_array );
HB_END_HEADER
#endif /* HARFBUZZ_GDEF_H */

View File

@ -0,0 +1,118 @@
/*
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
* Copyright (C) 2007 Red Hat, Inc.
*
* This is part of HarfBuzz, an OpenType Layout engine library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Red Hat Author(s): Behdad Esfahbod
*/
#ifndef HARFBUZZ_GLOBAL_H
#define HARFBUZZ_GLOBAL_H
#include <stdlib.h>
#include <string.h>
#ifdef __cplusplus
#define HB_BEGIN_HEADER extern "C" {
#define HB_END_HEADER }
#else
#define HB_BEGIN_HEADER /* nothing */
#define HB_END_HEADER /* nothing */
#endif
HB_BEGIN_HEADER
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE (!FALSE)
#endif
#define HB_MAKE_TAG( _x1, _x2, _x3, _x4 ) \
( ( (HB_UInt)_x1 << 24 ) | \
( (HB_UInt)_x2 << 16 ) | \
( (HB_UInt)_x3 << 8 ) | \
(HB_UInt)_x4 )
typedef char hb_int8;
typedef unsigned char hb_uint8;
typedef short hb_int16;
typedef unsigned short hb_uint16;
typedef int hb_int32;
typedef unsigned int hb_uint32;
typedef hb_uint8 HB_Bool;
typedef hb_uint8 HB_Byte;
typedef hb_uint16 HB_UShort;
typedef hb_uint32 HB_UInt;
typedef hb_int8 HB_Char;
typedef hb_int16 HB_Short;
typedef hb_int32 HB_Int;
typedef hb_uint16 HB_UChar16;
typedef hb_uint32 HB_UChar32;
typedef hb_uint32 HB_Glyph;
typedef hb_int32 HB_Fixed; /* 26.6 */
#define HB_FIXED_CONSTANT(v) ((v) * 64)
#define HB_FIXED_ROUND(v) (((v)+32) & -64)
typedef hb_int32 HB_16Dot16; /* 16.16 */
typedef void * HB_Pointer;
typedef hb_uint32 HB_Tag;
typedef enum {
/* no error */
HB_Err_Ok = 0x0000,
HB_Err_Not_Covered = 0xFFFF,
/* _hb_err() is called whenever returning the following errors,
* and in a couple places for HB_Err_Not_Covered too. */
/* programmer error */
HB_Err_Invalid_Argument = 0x1A66,
/* font error */
HB_Err_Invalid_SubTable_Format = 0x157F,
HB_Err_Invalid_SubTable = 0x1570,
HB_Err_Read_Error = 0x6EAD,
/* system error */
HB_Err_Out_Of_Memory = 0xDEAD
} HB_Error;
typedef struct {
HB_Fixed x;
HB_Fixed y;
} HB_FixedPoint;
typedef struct HB_Font_ *HB_Font;
typedef struct HB_StreamRec_ *HB_Stream;
typedef struct HB_FaceRec_ *HB_Face;
HB_END_HEADER
#endif

View File

@ -0,0 +1,712 @@
/*
* Copyright (C) 1998-2004 David Turner and Werner Lemberg
* Copyright (C) 2006 Behdad Esfahbod
*
* This is part of HarfBuzz, an OpenType Layout engine library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#ifndef HARFBUZZ_GPOS_PRIVATE_H
#define HARFBUZZ_GPOS_PRIVATE_H
#include "harfbuzz-impl.h"
#include "harfbuzz-stream-private.h"
#include "harfbuzz-gpos.h"
HB_BEGIN_HEADER
/* shared tables */
struct HB_ValueRecord_
{
HB_Short XPlacement; /* horizontal adjustment for
placement */
HB_Short YPlacement; /* vertical adjustment for
placement */
HB_Short XAdvance; /* horizontal adjustment for
advance */
HB_Short YAdvance; /* vertical adjustment for
advance */
HB_Device XPlacementDevice; /* device table for horizontal
placement */
HB_Device YPlacementDevice; /* device table for vertical
placement */
HB_Device XAdvanceDevice; /* device table for horizontal
advance */
HB_Device YAdvanceDevice; /* device table for vertical
advance */
HB_UShort XIdPlacement; /* horizontal placement metric ID */
HB_UShort YIdPlacement; /* vertical placement metric ID */
HB_UShort XIdAdvance; /* horizontal advance metric ID */
HB_UShort YIdAdvance; /* vertical advance metric ID */
};
typedef struct HB_ValueRecord_ HB_ValueRecord;
/* Mask values to scan the value format of the ValueRecord structure.
We always expand compressed ValueRecords of the font. */
#define HB_GPOS_FORMAT_HAVE_X_PLACEMENT 0x0001
#define HB_GPOS_FORMAT_HAVE_Y_PLACEMENT 0x0002
#define HB_GPOS_FORMAT_HAVE_X_ADVANCE 0x0004
#define HB_GPOS_FORMAT_HAVE_Y_ADVANCE 0x0008
#define HB_GPOS_FORMAT_HAVE_X_PLACEMENT_DEVICE 0x0010
#define HB_GPOS_FORMAT_HAVE_Y_PLACEMENT_DEVICE 0x0020
#define HB_GPOS_FORMAT_HAVE_X_ADVANCE_DEVICE 0x0040
#define HB_GPOS_FORMAT_HAVE_Y_ADVANCE_DEVICE 0x0080
#define HB_GPOS_FORMAT_HAVE_X_ID_PLACEMENT 0x0100
#define HB_GPOS_FORMAT_HAVE_Y_ID_PLACEMENT 0x0200
#define HB_GPOS_FORMAT_HAVE_X_ID_ADVANCE 0x0400
#define HB_GPOS_FORMAT_HAVE_Y_ID_ADVANCE 0x0800
struct HB_AnchorFormat1_
{
HB_Short XCoordinate; /* horizontal value */
HB_Short YCoordinate; /* vertical value */
};
typedef struct HB_AnchorFormat1_ HB_AnchorFormat1;
struct HB_AnchorFormat2_
{
HB_Short XCoordinate; /* horizontal value */
HB_Short YCoordinate; /* vertical value */
HB_UShort AnchorPoint; /* index to glyph contour point */
};
typedef struct HB_AnchorFormat2_ HB_AnchorFormat2;
struct HB_AnchorFormat3_
{
HB_Short XCoordinate; /* horizontal value */
HB_Short YCoordinate; /* vertical value */
HB_Device XDeviceTable; /* device table for X coordinate */
HB_Device YDeviceTable; /* device table for Y coordinate */
};
typedef struct HB_AnchorFormat3_ HB_AnchorFormat3;
struct HB_AnchorFormat4_
{
HB_UShort XIdAnchor; /* horizontal metric ID */
HB_UShort YIdAnchor; /* vertical metric ID */
};
typedef struct HB_AnchorFormat4_ HB_AnchorFormat4;
struct HB_Anchor_
{
HB_UShort PosFormat; /* 1, 2, 3, or 4 -- 0 indicates
that there is no Anchor table */
union
{
HB_AnchorFormat1 af1;
HB_AnchorFormat2 af2;
HB_AnchorFormat3 af3;
HB_AnchorFormat4 af4;
} af;
};
typedef struct HB_Anchor_ HB_Anchor;
struct HB_MarkRecord_
{
HB_UShort Class; /* mark class */
HB_Anchor MarkAnchor; /* anchor table */
};
typedef struct HB_MarkRecord_ HB_MarkRecord;
struct HB_MarkArray_
{
HB_UShort MarkCount; /* number of MarkRecord tables */
HB_MarkRecord* MarkRecord; /* array of MarkRecord tables */
};
typedef struct HB_MarkArray_ HB_MarkArray;
/* LookupType 1 */
struct HB_SinglePosFormat1_
{
HB_ValueRecord Value; /* ValueRecord for all covered
glyphs */
};
typedef struct HB_SinglePosFormat1_ HB_SinglePosFormat1;
struct HB_SinglePosFormat2_
{
HB_UShort ValueCount; /* number of ValueRecord tables */
HB_ValueRecord* Value; /* array of ValueRecord tables */
};
typedef struct HB_SinglePosFormat2_ HB_SinglePosFormat2;
struct HB_SinglePos_
{
HB_UShort PosFormat; /* 1 or 2 */
HB_Coverage Coverage; /* Coverage table */
HB_UShort ValueFormat; /* format of ValueRecord table */
union
{
HB_SinglePosFormat1 spf1;
HB_SinglePosFormat2 spf2;
} spf;
};
typedef struct HB_SinglePos_ HB_SinglePos;
/* LookupType 2 */
struct HB_PairValueRecord_
{
HB_UShort SecondGlyph; /* glyph ID for second glyph */
HB_ValueRecord Value1; /* pos. data for first glyph */
HB_ValueRecord Value2; /* pos. data for second glyph */
};
typedef struct HB_PairValueRecord_ HB_PairValueRecord;
struct HB_PairSet_
{
HB_UShort PairValueCount;
/* number of PairValueRecord tables */
HB_PairValueRecord* PairValueRecord;
/* array of PairValueRecord tables */
};
typedef struct HB_PairSet_ HB_PairSet;
struct HB_PairPosFormat1_
{
HB_UShort PairSetCount; /* number of PairSet tables */
HB_PairSet* PairSet; /* array of PairSet tables */
};
typedef struct HB_PairPosFormat1_ HB_PairPosFormat1;
struct HB_Class2Record_
{
HB_ValueRecord Value1; /* pos. data for first glyph */
HB_ValueRecord Value2; /* pos. data for second glyph */
};
typedef struct HB_Class2Record_ HB_Class2Record;
struct HB_Class1Record_
{
HB_Class2Record* Class2Record; /* array of Class2Record tables */
};
typedef struct HB_Class1Record_ HB_Class1Record;
struct HB_PairPosFormat2_
{
HB_ClassDefinition ClassDef1; /* class def. for first glyph */
HB_ClassDefinition ClassDef2; /* class def. for second glyph */
HB_UShort Class1Count; /* number of classes in ClassDef1
table */
HB_UShort Class2Count; /* number of classes in ClassDef2
table */
HB_Class1Record* Class1Record; /* array of Class1Record tables */
};
typedef struct HB_PairPosFormat2_ HB_PairPosFormat2;
struct HB_PairPos_
{
HB_UShort PosFormat; /* 1 or 2 */
HB_Coverage Coverage; /* Coverage table */
HB_UShort ValueFormat1; /* format of ValueRecord table
for first glyph */
HB_UShort ValueFormat2; /* format of ValueRecord table
for second glyph */
union
{
HB_PairPosFormat1 ppf1;
HB_PairPosFormat2 ppf2;
} ppf;
};
typedef struct HB_PairPos_ HB_PairPos;
/* LookupType 3 */
struct HB_EntryExitRecord_
{
HB_Anchor EntryAnchor; /* entry Anchor table */
HB_Anchor ExitAnchor; /* exit Anchor table */
};
typedef struct HB_EntryExitRecord_ HB_EntryExitRecord;
struct HB_CursivePos_
{
HB_UShort PosFormat; /* always 1 */
HB_Coverage Coverage; /* Coverage table */
HB_UShort EntryExitCount;
/* number of EntryExitRecord tables */
HB_EntryExitRecord* EntryExitRecord;
/* array of EntryExitRecord tables */
};
typedef struct HB_CursivePos_ HB_CursivePos;
/* LookupType 4 */
struct HB_BaseRecord_
{
HB_Anchor* BaseAnchor; /* array of base glyph anchor
tables */
};
typedef struct HB_BaseRecord_ HB_BaseRecord;
struct HB_BaseArray_
{
HB_UShort BaseCount; /* number of BaseRecord tables */
HB_BaseRecord* BaseRecord; /* array of BaseRecord tables */
};
typedef struct HB_BaseArray_ HB_BaseArray;
struct HB_MarkBasePos_
{
HB_UShort PosFormat; /* always 1 */
HB_Coverage MarkCoverage; /* mark glyph coverage table */
HB_Coverage BaseCoverage; /* base glyph coverage table */
HB_UShort ClassCount; /* number of mark classes */
HB_MarkArray MarkArray; /* mark array table */
HB_BaseArray BaseArray; /* base array table */
};
typedef struct HB_MarkBasePos_ HB_MarkBasePos;
/* LookupType 5 */
struct HB_ComponentRecord_
{
HB_Anchor* LigatureAnchor; /* array of ligature glyph anchor
tables */
};
typedef struct HB_ComponentRecord_ HB_ComponentRecord;
struct HB_LigatureAttach_
{
HB_UShort ComponentCount;
/* number of ComponentRecord tables */
HB_ComponentRecord* ComponentRecord;
/* array of ComponentRecord tables */
};
typedef struct HB_LigatureAttach_ HB_LigatureAttach;
struct HB_LigatureArray_
{
HB_UShort LigatureCount; /* number of LigatureAttach tables */
HB_LigatureAttach* LigatureAttach;
/* array of LigatureAttach tables */
};
typedef struct HB_LigatureArray_ HB_LigatureArray;
struct HB_MarkLigPos_
{
HB_UShort PosFormat; /* always 1 */
HB_Coverage MarkCoverage; /* mark glyph coverage table */
HB_Coverage LigatureCoverage;
/* ligature glyph coverage table */
HB_UShort ClassCount; /* number of mark classes */
HB_MarkArray MarkArray; /* mark array table */
HB_LigatureArray LigatureArray; /* ligature array table */
};
typedef struct HB_MarkLigPos_ HB_MarkLigPos;
/* LookupType 6 */
struct HB_Mark2Record_
{
HB_Anchor* Mark2Anchor; /* array of mark glyph anchor
tables */
};
typedef struct HB_Mark2Record_ HB_Mark2Record;
struct HB_Mark2Array_
{
HB_UShort Mark2Count; /* number of Mark2Record tables */
HB_Mark2Record* Mark2Record; /* array of Mark2Record tables */
};
typedef struct HB_Mark2Array_ HB_Mark2Array;
struct HB_MarkMarkPos_
{
HB_UShort PosFormat; /* always 1 */
HB_Coverage Mark1Coverage; /* first mark glyph coverage table */
HB_Coverage Mark2Coverage; /* second mark glyph coverave table */
HB_UShort ClassCount; /* number of combining mark classes */
HB_MarkArray Mark1Array; /* MarkArray table for first mark */
HB_Mark2Array Mark2Array; /* MarkArray table for second mark */
};
typedef struct HB_MarkMarkPos_ HB_MarkMarkPos;
/* needed by both lookup type 7 and 8 */
struct HB_PosLookupRecord_
{
HB_UShort SequenceIndex; /* index into current
glyph sequence */
HB_UShort LookupListIndex; /* Lookup to apply to that pos. */
};
typedef struct HB_PosLookupRecord_ HB_PosLookupRecord;
/* LookupType 7 */
struct HB_PosRule_
{
HB_UShort GlyphCount; /* total number of input glyphs */
HB_UShort PosCount; /* number of PosLookupRecord tables */
HB_UShort* Input; /* array of input glyph IDs */
HB_PosLookupRecord* PosLookupRecord;
/* array of PosLookupRecord tables */
};
typedef struct HB_PosRule_ HB_PosRule;
struct HB_PosRuleSet_
{
HB_UShort PosRuleCount; /* number of PosRule tables */
HB_PosRule* PosRule; /* array of PosRule tables */
};
typedef struct HB_PosRuleSet_ HB_PosRuleSet;
struct HB_ContextPosFormat1_
{
HB_Coverage Coverage; /* Coverage table */
HB_UShort PosRuleSetCount; /* number of PosRuleSet tables */
HB_PosRuleSet* PosRuleSet; /* array of PosRuleSet tables */
};
typedef struct HB_ContextPosFormat1_ HB_ContextPosFormat1;
struct HB_PosClassRule_
{
HB_UShort GlyphCount; /* total number of context classes */
HB_UShort PosCount; /* number of PosLookupRecord tables */
HB_UShort* Class; /* array of classes */
HB_PosLookupRecord* PosLookupRecord;
/* array of PosLookupRecord tables */
};
typedef struct HB_PosClassRule_ HB_PosClassRule;
struct HB_PosClassSet_
{
HB_UShort PosClassRuleCount;
/* number of PosClassRule tables */
HB_PosClassRule* PosClassRule; /* array of PosClassRule tables */
};
typedef struct HB_PosClassSet_ HB_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 HB_ContextPosFormat2_
{
HB_UShort MaxContextLength;
/* maximal context length */
HB_Coverage Coverage; /* Coverage table */
HB_ClassDefinition ClassDef; /* ClassDef table */
HB_UShort PosClassSetCount;
/* number of PosClassSet tables */
HB_PosClassSet* PosClassSet; /* array of PosClassSet tables */
};
typedef struct HB_ContextPosFormat2_ HB_ContextPosFormat2;
struct HB_ContextPosFormat3_
{
HB_UShort GlyphCount; /* number of input glyphs */
HB_UShort PosCount; /* number of PosLookupRecord tables */
HB_Coverage* Coverage; /* array of Coverage tables */
HB_PosLookupRecord* PosLookupRecord;
/* array of PosLookupRecord tables */
};
typedef struct HB_ContextPosFormat3_ HB_ContextPosFormat3;
struct HB_ContextPos_
{
HB_UShort PosFormat; /* 1, 2, or 3 */
union
{
HB_ContextPosFormat1 cpf1;
HB_ContextPosFormat2 cpf2;
HB_ContextPosFormat3 cpf3;
} cpf;
};
typedef struct HB_ContextPos_ HB_ContextPos;
/* LookupType 8 */
struct HB_ChainPosRule_
{
HB_UShort BacktrackGlyphCount;
/* total number of backtrack glyphs */
HB_UShort* Backtrack; /* array of backtrack glyph IDs */
HB_UShort InputGlyphCount;
/* total number of input glyphs */
HB_UShort* Input; /* array of input glyph IDs */
HB_UShort LookaheadGlyphCount;
/* total number of lookahead glyphs */
HB_UShort* Lookahead; /* array of lookahead glyph IDs */
HB_UShort PosCount; /* number of PosLookupRecords */
HB_PosLookupRecord* PosLookupRecord;
/* array of PosLookupRecords */
};
typedef struct HB_ChainPosRule_ HB_ChainPosRule;
struct HB_ChainPosRuleSet_
{
HB_UShort ChainPosRuleCount;
/* number of ChainPosRule tables */
HB_ChainPosRule* ChainPosRule; /* array of ChainPosRule tables */
};
typedef struct HB_ChainPosRuleSet_ HB_ChainPosRuleSet;
struct HB_ChainContextPosFormat1_
{
HB_Coverage Coverage; /* Coverage table */
HB_UShort ChainPosRuleSetCount;
/* number of ChainPosRuleSet tables */
HB_ChainPosRuleSet* ChainPosRuleSet;
/* array of ChainPosRuleSet tables */
};
typedef struct HB_ChainContextPosFormat1_ HB_ChainContextPosFormat1;
struct HB_ChainPosClassRule_
{
HB_UShort BacktrackGlyphCount;
/* total number of backtrack
classes */
HB_UShort* Backtrack; /* array of backtrack classes */
HB_UShort InputGlyphCount;
/* total number of context classes */
HB_UShort* Input; /* array of context classes */
HB_UShort LookaheadGlyphCount;
/* total number of lookahead
classes */
HB_UShort* Lookahead; /* array of lookahead classes */
HB_UShort PosCount; /* number of PosLookupRecords */
HB_PosLookupRecord* PosLookupRecord;
/* array of substitution lookups */
};
typedef struct HB_ChainPosClassRule_ HB_ChainPosClassRule;
struct HB_ChainPosClassSet_
{
HB_UShort ChainPosClassRuleCount;
/* number of ChainPosClassRule
tables */
HB_ChainPosClassRule* ChainPosClassRule;
/* array of ChainPosClassRule
tables */
};
typedef struct HB_ChainPosClassSet_ HB_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 HB_ChainContextPosFormat2_
{
HB_Coverage Coverage; /* Coverage table */
HB_UShort MaxBacktrackLength;
/* maximal backtrack length */
HB_ClassDefinition BacktrackClassDef;
/* BacktrackClassDef table */
HB_UShort MaxInputLength;
/* maximal input length */
HB_ClassDefinition InputClassDef;
/* InputClassDef table */
HB_UShort MaxLookaheadLength;
/* maximal lookahead length */
HB_ClassDefinition LookaheadClassDef;
/* LookaheadClassDef table */
HB_UShort ChainPosClassSetCount;
/* number of ChainPosClassSet
tables */
HB_ChainPosClassSet* ChainPosClassSet;
/* array of ChainPosClassSet
tables */
};
typedef struct HB_ChainContextPosFormat2_ HB_ChainContextPosFormat2;
struct HB_ChainContextPosFormat3_
{
HB_UShort BacktrackGlyphCount;
/* number of backtrack glyphs */
HB_Coverage* BacktrackCoverage;
/* array of backtrack Coverage
tables */
HB_UShort InputGlyphCount;
/* number of input glyphs */
HB_Coverage* InputCoverage;
/* array of input coverage
tables */
HB_UShort LookaheadGlyphCount;
/* number of lookahead glyphs */
HB_Coverage* LookaheadCoverage;
/* array of lookahead coverage
tables */
HB_UShort PosCount; /* number of PosLookupRecords */
HB_PosLookupRecord* PosLookupRecord;
/* array of substitution lookups */
};
typedef struct HB_ChainContextPosFormat3_ HB_ChainContextPosFormat3;
struct HB_ChainContextPos_
{
HB_UShort PosFormat; /* 1, 2, or 3 */
union
{
HB_ChainContextPosFormat1 ccpf1;
HB_ChainContextPosFormat2 ccpf2;
HB_ChainContextPosFormat3 ccpf3;
} ccpf;
};
typedef struct HB_ChainContextPos_ HB_ChainContextPos;
#if 0
/* LookupType 10 */
struct HB_ExtensionPos_
{
HB_UShort PosFormat; /* always 1 */
HB_UShort LookuptType; /* lookup-type of referenced subtable */
HB_GPOS_SubTable *subtable; /* referenced subtable */
};
typedef struct HB_ExtensionPos_ HB_ExtensionPos;
#endif
union HB_GPOS_SubTable_
{
HB_SinglePos single;
HB_PairPos pair;
HB_CursivePos cursive;
HB_MarkBasePos markbase;
HB_MarkLigPos marklig;
HB_MarkMarkPos markmark;
HB_ContextPos context;
HB_ChainContextPos chain;
};
typedef union HB_GPOS_SubTable_ HB_GPOS_SubTable;
HB_INTERNAL HB_Error
_HB_GPOS_Load_SubTable( HB_GPOS_SubTable* st,
HB_Stream stream,
HB_UShort lookup_type );
HB_INTERNAL void
_HB_GPOS_Free_SubTable( HB_GPOS_SubTable* st,
HB_UShort lookup_type );
HB_END_HEADER
#endif /* HARFBUZZ_GPOS_PRIVATE_H */

6055
third_party/harfbuzz/src/harfbuzz-gpos.c vendored Normal file

File diff suppressed because it is too large Load Diff

149
third_party/harfbuzz/src/harfbuzz-gpos.h vendored Normal file
View File

@ -0,0 +1,149 @@
/*
* Copyright (C) 1998-2004 David Turner and Werner Lemberg
* Copyright (C) 2006 Behdad Esfahbod
*
* This is part of HarfBuzz, an OpenType Layout engine library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#ifndef HARFBUZZ_GPOS_H
#define HARFBUZZ_GPOS_H
#include "harfbuzz-gdef.h"
#include "harfbuzz-buffer.h"
HB_BEGIN_HEADER
/* Lookup types for glyph positioning */
#define HB_GPOS_LOOKUP_SINGLE 1
#define HB_GPOS_LOOKUP_PAIR 2
#define HB_GPOS_LOOKUP_CURSIVE 3
#define HB_GPOS_LOOKUP_MARKBASE 4
#define HB_GPOS_LOOKUP_MARKLIG 5
#define HB_GPOS_LOOKUP_MARKMARK 6
#define HB_GPOS_LOOKUP_CONTEXT 7
#define HB_GPOS_LOOKUP_CHAIN 8
#define HB_GPOS_LOOKUP_EXTENSION 9
/* 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 HB_GPOS_Register_MM_Function().
`metric_value' must be returned as a scaled value (but shouldn't
be rounded). */
typedef HB_Error (*HB_MMFunction)(HB_Font font,
HB_UShort metric_id,
HB_Fixed* metric_value,
void* data );
struct HB_GPOSHeader_
{
HB_16Dot16 Version;
HB_ScriptList ScriptList;
HB_FeatureList FeatureList;
HB_LookupList LookupList;
HB_GDEFHeader* gdef;
/* this is OpenType 1.2 -- Multiple Master fonts need this
callback function to get various metric values from the
PostScript interpreter. */
HB_MMFunction mmfunc;
void* data;
};
typedef struct HB_GPOSHeader_ HB_GPOSHeader;
typedef HB_GPOSHeader* HB_GPOS;
HB_Error HB_Load_GPOS_Table( HB_Stream stream,
HB_GPOSHeader** gpos,
HB_GDEFHeader* gdef,
HB_Stream gdefStream );
HB_Error HB_Done_GPOS_Table( HB_GPOSHeader* gpos );
HB_Error HB_GPOS_Select_Script( HB_GPOSHeader* gpos,
HB_UInt script_tag,
HB_UShort* script_index );
HB_Error HB_GPOS_Select_Language( HB_GPOSHeader* gpos,
HB_UInt language_tag,
HB_UShort script_index,
HB_UShort* language_index,
HB_UShort* req_feature_index );
HB_Error HB_GPOS_Select_Feature( HB_GPOSHeader* gpos,
HB_UInt feature_tag,
HB_UShort script_index,
HB_UShort language_index,
HB_UShort* feature_index );
HB_Error HB_GPOS_Query_Scripts( HB_GPOSHeader* gpos,
HB_UInt** script_tag_list );
HB_Error HB_GPOS_Query_Languages( HB_GPOSHeader* gpos,
HB_UShort script_index,
HB_UInt** language_tag_list );
HB_Error HB_GPOS_Query_Features( HB_GPOSHeader* gpos,
HB_UShort script_index,
HB_UShort language_index,
HB_UInt** feature_tag_list );
HB_Error HB_GPOS_Add_Feature( HB_GPOSHeader* gpos,
HB_UShort feature_index,
HB_UInt property );
HB_Error HB_GPOS_Clear_Features( HB_GPOSHeader* gpos );
HB_Error HB_GPOS_Register_MM_Function( HB_GPOSHeader* gpos,
HB_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. */
HB_Error HB_GPOS_Apply_String( HB_Font font,
HB_GPOSHeader* gpos,
HB_UShort load_flags,
HB_Buffer buffer,
HB_Bool dvi,
HB_Bool r2l );
HB_END_HEADER
#endif /* HARFBUZZ_GPOS_H */

View File

@ -0,0 +1,476 @@
/*
* Copyright (C) 1998-2004 David Turner and Werner Lemberg
* Copyright (C) 2006 Behdad Esfahbod
*
* This is part of HarfBuzz, an OpenType Layout engine library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#ifndef HARFBUZZ_GSUB_PRIVATE_H
#define HARFBUZZ_GSUB_PRIVATE_H
#include "harfbuzz-impl.h"
#include "harfbuzz-stream-private.h"
#include "harfbuzz-gsub.h"
HB_BEGIN_HEADER
typedef union HB_GSUB_SubTable_ HB_GSUB_SubTable;
/* LookupType 1 */
struct HB_SingleSubstFormat1_
{
HB_Short DeltaGlyphID; /* constant added to get
substitution glyph index */
};
typedef struct HB_SingleSubstFormat1_ HB_SingleSubstFormat1;
struct HB_SingleSubstFormat2_
{
HB_UShort GlyphCount; /* number of glyph IDs in
Substitute array */
HB_UShort* Substitute; /* array of substitute glyph IDs */
};
typedef struct HB_SingleSubstFormat2_ HB_SingleSubstFormat2;
struct HB_SingleSubst_
{
HB_UShort SubstFormat; /* 1 or 2 */
HB_Coverage Coverage; /* Coverage table */
union
{
HB_SingleSubstFormat1 ssf1;
HB_SingleSubstFormat2 ssf2;
} ssf;
};
typedef struct HB_SingleSubst_ HB_SingleSubst;
/* LookupType 2 */
struct HB_Sequence_
{
HB_UShort GlyphCount; /* number of glyph IDs in the
Substitute array */
HB_UShort* Substitute; /* string of glyph IDs to
substitute */
};
typedef struct HB_Sequence_ HB_Sequence;
struct HB_MultipleSubst_
{
HB_UShort SubstFormat; /* always 1 */
HB_Coverage Coverage; /* Coverage table */
HB_UShort SequenceCount; /* number of Sequence tables */
HB_Sequence* Sequence; /* array of Sequence tables */
};
typedef struct HB_MultipleSubst_ HB_MultipleSubst;
/* LookupType 3 */
struct HB_AlternateSet_
{
HB_UShort GlyphCount; /* number of glyph IDs in the
Alternate array */
HB_UShort* Alternate; /* array of alternate glyph IDs */
};
typedef struct HB_AlternateSet_ HB_AlternateSet;
struct HB_AlternateSubst_
{
HB_UShort SubstFormat; /* always 1 */
HB_Coverage Coverage; /* Coverage table */
HB_UShort AlternateSetCount;
/* number of AlternateSet tables */
HB_AlternateSet* AlternateSet; /* array of AlternateSet tables */
};
typedef struct HB_AlternateSubst_ HB_AlternateSubst;
/* LookupType 4 */
struct HB_Ligature_
{
HB_UShort LigGlyph; /* glyphID of ligature
to substitute */
HB_UShort ComponentCount; /* number of components in ligature */
HB_UShort* Component; /* array of component glyph IDs */
};
typedef struct HB_Ligature_ HB_Ligature;
struct HB_LigatureSet_
{
HB_UShort LigatureCount; /* number of Ligature tables */
HB_Ligature* Ligature; /* array of Ligature tables */
};
typedef struct HB_LigatureSet_ HB_LigatureSet;
struct HB_LigatureSubst_
{
HB_UShort SubstFormat; /* always 1 */
HB_Coverage Coverage; /* Coverage table */
HB_UShort LigatureSetCount; /* number of LigatureSet tables */
HB_LigatureSet* LigatureSet; /* array of LigatureSet tables */
};
typedef struct HB_LigatureSubst_ HB_LigatureSubst;
/* needed by both lookup type 5 and 6 */
struct HB_SubstLookupRecord_
{
HB_UShort SequenceIndex; /* index into current
glyph sequence */
HB_UShort LookupListIndex; /* Lookup to apply to that pos. */
};
typedef struct HB_SubstLookupRecord_ HB_SubstLookupRecord;
/* LookupType 5 */
struct HB_SubRule_
{
HB_UShort GlyphCount; /* total number of input glyphs */
HB_UShort SubstCount; /* number of SubstLookupRecord
tables */
HB_UShort* Input; /* array of input glyph IDs */
HB_SubstLookupRecord* SubstLookupRecord;
/* array of SubstLookupRecord
tables */
};
typedef struct HB_SubRule_ HB_SubRule;
struct HB_SubRuleSet_
{
HB_UShort SubRuleCount; /* number of SubRule tables */
HB_SubRule* SubRule; /* array of SubRule tables */
};
typedef struct HB_SubRuleSet_ HB_SubRuleSet;
struct HB_ContextSubstFormat1_
{
HB_Coverage Coverage; /* Coverage table */
HB_UShort SubRuleSetCount; /* number of SubRuleSet tables */
HB_SubRuleSet* SubRuleSet; /* array of SubRuleSet tables */
};
typedef struct HB_ContextSubstFormat1_ HB_ContextSubstFormat1;
struct HB_SubClassRule_
{
HB_UShort GlyphCount; /* total number of context classes */
HB_UShort SubstCount; /* number of SubstLookupRecord
tables */
HB_UShort* Class; /* array of classes */
HB_SubstLookupRecord* SubstLookupRecord;
/* array of SubstLookupRecord
tables */
};
typedef struct HB_SubClassRule_ HB_SubClassRule;
struct HB_SubClassSet_
{
HB_UShort SubClassRuleCount;
/* number of SubClassRule tables */
HB_SubClassRule* SubClassRule; /* array of SubClassRule tables */
};
typedef struct HB_SubClassSet_ HB_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 HB_ContextSubstFormat2_
{
HB_UShort MaxContextLength;
/* maximal context length */
HB_Coverage Coverage; /* Coverage table */
HB_ClassDefinition ClassDef; /* ClassDef table */
HB_UShort SubClassSetCount;
/* number of SubClassSet tables */
HB_SubClassSet* SubClassSet; /* array of SubClassSet tables */
};
typedef struct HB_ContextSubstFormat2_ HB_ContextSubstFormat2;
struct HB_ContextSubstFormat3_
{
HB_UShort GlyphCount; /* number of input glyphs */
HB_UShort SubstCount; /* number of SubstLookupRecords */
HB_Coverage* Coverage; /* array of Coverage tables */
HB_SubstLookupRecord* SubstLookupRecord;
/* array of substitution lookups */
};
typedef struct HB_ContextSubstFormat3_ HB_ContextSubstFormat3;
struct HB_ContextSubst_
{
HB_UShort SubstFormat; /* 1, 2, or 3 */
union
{
HB_ContextSubstFormat1 csf1;
HB_ContextSubstFormat2 csf2;
HB_ContextSubstFormat3 csf3;
} csf;
};
typedef struct HB_ContextSubst_ HB_ContextSubst;
/* LookupType 6 */
struct HB_ChainSubRule_
{
HB_UShort BacktrackGlyphCount;
/* total number of backtrack glyphs */
HB_UShort* Backtrack; /* array of backtrack glyph IDs */
HB_UShort InputGlyphCount;
/* total number of input glyphs */
HB_UShort* Input; /* array of input glyph IDs */
HB_UShort LookaheadGlyphCount;
/* total number of lookahead glyphs */
HB_UShort* Lookahead; /* array of lookahead glyph IDs */
HB_UShort SubstCount; /* number of SubstLookupRecords */
HB_SubstLookupRecord* SubstLookupRecord;
/* array of SubstLookupRecords */
};
typedef struct HB_ChainSubRule_ HB_ChainSubRule;
struct HB_ChainSubRuleSet_
{
HB_UShort ChainSubRuleCount;
/* number of ChainSubRule tables */
HB_ChainSubRule* ChainSubRule; /* array of ChainSubRule tables */
};
typedef struct HB_ChainSubRuleSet_ HB_ChainSubRuleSet;
struct HB_ChainContextSubstFormat1_
{
HB_Coverage Coverage; /* Coverage table */
HB_UShort ChainSubRuleSetCount;
/* number of ChainSubRuleSet tables */
HB_ChainSubRuleSet* ChainSubRuleSet;
/* array of ChainSubRuleSet tables */
};
typedef struct HB_ChainContextSubstFormat1_ HB_ChainContextSubstFormat1;
struct HB_ChainSubClassRule_
{
HB_UShort BacktrackGlyphCount;
/* total number of backtrack
classes */
HB_UShort* Backtrack; /* array of backtrack classes */
HB_UShort InputGlyphCount;
/* total number of context classes */
HB_UShort* Input; /* array of context classes */
HB_UShort LookaheadGlyphCount;
/* total number of lookahead
classes */
HB_UShort* Lookahead; /* array of lookahead classes */
HB_UShort SubstCount; /* number of SubstLookupRecords */
HB_SubstLookupRecord* SubstLookupRecord;
/* array of substitution lookups */
};
typedef struct HB_ChainSubClassRule_ HB_ChainSubClassRule;
struct HB_ChainSubClassSet_
{
HB_UShort ChainSubClassRuleCount;
/* number of ChainSubClassRule
tables */
HB_ChainSubClassRule* ChainSubClassRule;
/* array of ChainSubClassRule
tables */
};
typedef struct HB_ChainSubClassSet_ HB_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 HB_ChainContextSubstFormat2_
{
HB_Coverage Coverage; /* Coverage table */
HB_UShort MaxBacktrackLength;
/* maximal backtrack length */
HB_ClassDefinition BacktrackClassDef;
/* BacktrackClassDef table */
HB_UShort MaxInputLength;
/* maximal input length */
HB_ClassDefinition InputClassDef;
/* InputClassDef table */
HB_UShort MaxLookaheadLength;
/* maximal lookahead length */
HB_ClassDefinition LookaheadClassDef;
/* LookaheadClassDef table */
HB_UShort ChainSubClassSetCount;
/* number of ChainSubClassSet
tables */
HB_ChainSubClassSet* ChainSubClassSet;
/* array of ChainSubClassSet
tables */
};
typedef struct HB_ChainContextSubstFormat2_ HB_ChainContextSubstFormat2;
struct HB_ChainContextSubstFormat3_
{
HB_UShort BacktrackGlyphCount;
/* number of backtrack glyphs */
HB_Coverage* BacktrackCoverage;
/* array of backtrack Coverage
tables */
HB_UShort InputGlyphCount;
/* number of input glyphs */
HB_Coverage* InputCoverage;
/* array of input coverage
tables */
HB_UShort LookaheadGlyphCount;
/* number of lookahead glyphs */
HB_Coverage* LookaheadCoverage;
/* array of lookahead coverage
tables */
HB_UShort SubstCount; /* number of SubstLookupRecords */
HB_SubstLookupRecord* SubstLookupRecord;
/* array of substitution lookups */
};
typedef struct HB_ChainContextSubstFormat3_ HB_ChainContextSubstFormat3;
struct HB_ChainContextSubst_
{
HB_UShort SubstFormat; /* 1, 2, or 3 */
union
{
HB_ChainContextSubstFormat1 ccsf1;
HB_ChainContextSubstFormat2 ccsf2;
HB_ChainContextSubstFormat3 ccsf3;
} ccsf;
};
typedef struct HB_ChainContextSubst_ HB_ChainContextSubst;
#if 0
/* LookupType 7 */
struct HB_ExtensionSubst_
{
HB_UShort SubstFormat; /* always 1 */
HB_UShort LookuptType; /* lookup-type of referenced subtable */
HB_GSUB_SubTable *subtable; /* referenced subtable */
};
typedef struct HB_ExtensionSubst_ HB_ExtensionSubst;
#endif
/* LookupType 8 */
struct HB_ReverseChainContextSubst_
{
HB_UShort SubstFormat; /* always 1 */
HB_Coverage Coverage; /* coverage table for input glyphs */
HB_UShort BacktrackGlyphCount; /* number of backtrack glyphs */
HB_Coverage* BacktrackCoverage; /* array of backtrack Coverage
tables */
HB_UShort LookaheadGlyphCount; /* number of lookahead glyphs */
HB_Coverage* LookaheadCoverage; /* array of lookahead Coverage
tables */
HB_UShort GlyphCount; /* number of Glyph IDs */
HB_UShort* Substitute; /* array of substitute Glyph ID */
};
typedef struct HB_ReverseChainContextSubst_ HB_ReverseChainContextSubst;
union HB_GSUB_SubTable_
{
HB_SingleSubst single;
HB_MultipleSubst multiple;
HB_AlternateSubst alternate;
HB_LigatureSubst ligature;
HB_ContextSubst context;
HB_ChainContextSubst chain;
HB_ReverseChainContextSubst reverse;
};
HB_INTERNAL HB_Error
_HB_GSUB_Load_SubTable( HB_GSUB_SubTable* st,
HB_Stream stream,
HB_UShort lookup_type );
HB_INTERNAL void
_HB_GSUB_Free_SubTable( HB_GSUB_SubTable* st,
HB_UShort lookup_type );
HB_END_HEADER
#endif /* HARFBUZZ_GSUB_PRIVATE_H */

4329
third_party/harfbuzz/src/harfbuzz-gsub.c vendored Normal file

File diff suppressed because it is too large Load Diff

141
third_party/harfbuzz/src/harfbuzz-gsub.h vendored Normal file
View File

@ -0,0 +1,141 @@
/*
* Copyright (C) 1998-2004 David Turner and Werner Lemberg
* Copyright (C) 2006 Behdad Esfahbod
*
* This is part of HarfBuzz, an OpenType Layout engine library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#ifndef HARFBUZZ_GSUB_H
#define HARFBUZZ_GSUB_H
#include "harfbuzz-gdef.h"
#include "harfbuzz-buffer.h"
HB_BEGIN_HEADER
/* Lookup types for glyph substitution */
#define HB_GSUB_LOOKUP_SINGLE 1
#define HB_GSUB_LOOKUP_MULTIPLE 2
#define HB_GSUB_LOOKUP_ALTERNATE 3
#define HB_GSUB_LOOKUP_LIGATURE 4
#define HB_GSUB_LOOKUP_CONTEXT 5
#define HB_GSUB_LOOKUP_CHAIN 6
#define HB_GSUB_LOOKUP_EXTENSION 7
#define HB_GSUB_LOOKUP_REVERSE_CHAIN 8
/* 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
HB_GSUB_Register_Alternate_Function(). The function must return an
index into the `alternates' array. */
typedef HB_UShort (*HB_AltFunction)(HB_UInt pos,
HB_UShort glyphID,
HB_UShort num_alternates,
HB_UShort* alternates,
void* data );
struct HB_GSUBHeader_
{
HB_UInt offset;
HB_16Dot16 Version;
HB_ScriptList ScriptList;
HB_FeatureList FeatureList;
HB_LookupList LookupList;
HB_GDEFHeader* gdef;
/* the next two fields are used for an alternate substitution callback
function to select the proper alternate glyph. */
HB_AltFunction altfunc;
void* data;
};
typedef struct HB_GSUBHeader_ HB_GSUBHeader;
typedef HB_GSUBHeader* HB_GSUB;
HB_Error HB_Load_GSUB_Table( HB_Stream stream,
HB_GSUBHeader** gsub,
HB_GDEFHeader* gdef,
HB_Stream gdefStream );
HB_Error HB_Done_GSUB_Table( HB_GSUBHeader* gsub );
HB_Error HB_GSUB_Select_Script( HB_GSUBHeader* gsub,
HB_UInt script_tag,
HB_UShort* script_index );
HB_Error HB_GSUB_Select_Language( HB_GSUBHeader* gsub,
HB_UInt language_tag,
HB_UShort script_index,
HB_UShort* language_index,
HB_UShort* req_feature_index );
HB_Error HB_GSUB_Select_Feature( HB_GSUBHeader* gsub,
HB_UInt feature_tag,
HB_UShort script_index,
HB_UShort language_index,
HB_UShort* feature_index );
HB_Error HB_GSUB_Query_Scripts( HB_GSUBHeader* gsub,
HB_UInt** script_tag_list );
HB_Error HB_GSUB_Query_Languages( HB_GSUBHeader* gsub,
HB_UShort script_index,
HB_UInt** language_tag_list );
HB_Error HB_GSUB_Query_Features( HB_GSUBHeader* gsub,
HB_UShort script_index,
HB_UShort language_index,
HB_UInt** feature_tag_list );
HB_Error HB_GSUB_Add_Feature( HB_GSUBHeader* gsub,
HB_UShort feature_index,
HB_UInt property );
HB_Error HB_GSUB_Clear_Features( HB_GSUBHeader* gsub );
HB_Error HB_GSUB_Register_Alternate_Function( HB_GSUBHeader* gsub,
HB_AltFunction altfunc,
void* data );
HB_Error HB_GSUB_Apply_String( HB_GSUBHeader* gsub,
HB_Buffer buffer );
HB_END_HEADER
#endif /* HARFBUZZ_GSUB_H */

View File

@ -0,0 +1,268 @@
/*
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
*
* This is part of HarfBuzz, an OpenType Layout engine library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#include "harfbuzz-shaper.h"
#include "harfbuzz-shaper-private.h"
#include <assert.h>
/*
// Hangul is a syllable based script. Unicode reserves a large range
// for precomposed hangul, where syllables are already precomposed to
// their final glyph shape. In addition, a so called jamo range is
// defined, that can be used to express old Hangul. Modern hangul
// syllables can also be expressed as jamo, and should be composed
// into syllables. The operation is rather simple and mathematical.
// Every hangul jamo is classified as being either a Leading consonant
// (L), and intermediat Vowel (V) or a trailing consonant (T). Modern
// hangul syllables (the ones in the precomposed area can be of type
// LV or LVT.
//
// Syllable breaks do _not_ occur between:
//
// L L, V or precomposed
// V, LV V, T
// LVT, T T
//
// A standard syllable is of the form L+V+T*. The above rules allow
// nonstandard syllables L*V*T*. To transform them into standard
// syllables fill characters L_f and V_f can be inserted.
*/
enum {
Hangul_SBase = 0xac00,
Hangul_LBase = 0x1100,
Hangul_VBase = 0x1161,
Hangul_TBase = 0x11a7,
Hangul_SCount = 11172,
Hangul_LCount = 19,
Hangul_VCount = 21,
Hangul_TCount = 28,
Hangul_NCount = 21*28
};
#define hangul_isPrecomposed(uc) \
(uc >= Hangul_SBase && uc < Hangul_SBase + Hangul_SCount)
#define hangul_isLV(uc) \
((uc - Hangul_SBase) % Hangul_TCount == 0)
typedef enum {
L,
V,
T,
LV,
LVT,
X
} HangulType;
static HangulType hangul_type(unsigned short uc) {
if (uc > Hangul_SBase && uc < Hangul_SBase + Hangul_SCount)
return hangul_isLV(uc) ? LV : LVT;
if (uc < Hangul_LBase || uc > 0x11ff)
return X;
if (uc < Hangul_VBase)
return L;
if (uc < Hangul_TBase)
return V;
return T;
}
static int hangul_nextSyllableBoundary(const HB_UChar16 *s, int start, int end)
{
const HB_UChar16 *uc = s + start;
HangulType state = hangul_type(*uc);
int pos = 1;
while (pos < end - start) {
HangulType newState = hangul_type(uc[pos]);
switch(newState) {
case X:
goto finish;
case L:
case V:
case T:
if (state > newState)
goto finish;
state = newState;
break;
case LV:
if (state > L)
goto finish;
state = V;
break;
case LVT:
if (state > L)
goto finish;
state = T;
}
++pos;
}
finish:
return start+pos;
}
#ifndef NO_OPENTYPE
static const HB_OpenTypeFeature hangul_features [] = {
{ HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty },
{ HB_MAKE_TAG('l', 'j', 'm', 'o'), CcmpProperty },
{ HB_MAKE_TAG('j', 'j', 'm', 'o'), CcmpProperty },
{ HB_MAKE_TAG('t', 'j', 'm', 'o'), CcmpProperty },
{ 0, 0 }
};
#endif
static HB_Bool hangul_shape_syllable(HB_ShaperItem *item, HB_Bool openType)
{
const HB_UChar16 *ch = item->string + item->item.pos;
int len = item->item.length;
#ifndef NO_OPENTYPE
const int availableGlyphs = item->num_glyphs;
#endif
int i;
HB_UChar16 composed = 0;
/* see if we can compose the syllable into a modern hangul */
if (item->item.length == 2) {
int LIndex = ch[0] - Hangul_LBase;
int VIndex = ch[1] - Hangul_VBase;
if (LIndex >= 0 && LIndex < Hangul_LCount &&
VIndex >= 0 && VIndex < Hangul_VCount)
composed = (LIndex * Hangul_VCount + VIndex) * Hangul_TCount + Hangul_SBase;
} else if (item->item.length == 3) {
int LIndex = ch[0] - Hangul_LBase;
int VIndex = ch[1] - Hangul_VBase;
int TIndex = ch[2] - Hangul_TBase;
if (LIndex >= 0 && LIndex < Hangul_LCount &&
VIndex >= 0 && VIndex < Hangul_VCount &&
TIndex >= 0 && TIndex < Hangul_TCount)
composed = (LIndex * Hangul_VCount + VIndex) * Hangul_TCount + TIndex + Hangul_SBase;
}
/* if we have a modern hangul use the composed form */
if (composed) {
ch = &composed;
len = 1;
}
if (!item->font->klass->convertStringToGlyphIndices(item->font,
ch, len,
item->glyphs, &item->num_glyphs,
item->item.bidiLevel % 2))
return FALSE;
for (i = 0; i < len; i++) {
item->attributes[i].mark = FALSE;
item->attributes[i].clusterStart = FALSE;
item->attributes[i].justification = 0;
item->attributes[i].zeroWidth = FALSE;
/*IDEBUG(" %d: %4x", i, ch[i].unicode()); */
}
#ifndef NO_OPENTYPE
if (!composed && openType) {
HB_Bool positioned;
HB_STACKARRAY(unsigned short, logClusters, len);
for (i = 0; i < len; ++i)
logClusters[i] = i;
item->log_clusters = logClusters;
HB_OpenTypeShape(item, /*properties*/0);
positioned = HB_OpenTypePosition(item, availableGlyphs, /*doLogClusters*/FALSE);
HB_FREE_STACKARRAY(logClusters);
if (!positioned)
return FALSE;
} else {
HB_HeuristicPosition(item);
}
#endif
item->attributes[0].clusterStart = TRUE;
return TRUE;
}
HB_Bool HB_HangulShape(HB_ShaperItem *item)
{
const HB_UChar16 *uc = item->string + item->item.pos;
HB_Bool allPrecomposed = TRUE;
int i;
assert(item->item.script == HB_Script_Hangul);
for (i = 0; i < (int)item->item.length; ++i) {
if (!hangul_isPrecomposed(uc[i])) {
allPrecomposed = FALSE;
break;
}
}
if (!allPrecomposed) {
HB_Bool openType = FALSE;
unsigned short *logClusters = item->log_clusters;
HB_ShaperItem syllable;
int first_glyph = 0;
int sstart = item->item.pos;
int end = sstart + item->item.length;
#ifndef NO_OPENTYPE
openType = HB_SelectScript(item, hangul_features);
#endif
syllable = *item;
while (sstart < end) {
int send = hangul_nextSyllableBoundary(item->string, sstart, end);
syllable.item.pos = sstart;
syllable.item.length = send-sstart;
syllable.glyphs = item->glyphs + first_glyph;
syllable.attributes = item->attributes + first_glyph;
syllable.offsets = item->offsets + first_glyph;
syllable.advances = item->advances + first_glyph;
syllable.num_glyphs = item->num_glyphs - first_glyph;
if (!hangul_shape_syllable(&syllable, openType)) {
item->num_glyphs += syllable.num_glyphs;
return FALSE;
}
/* fix logcluster array */
for (i = sstart; i < send; ++i)
logClusters[i-item->item.pos] = first_glyph;
sstart = send;
first_glyph += syllable.num_glyphs;
}
item->num_glyphs = first_glyph;
return TRUE;
}
return HB_BasicShape(item);
}

View File

@ -0,0 +1,189 @@
/*
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
*
* This is part of HarfBuzz, an OpenType Layout engine library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#include "harfbuzz-shaper.h"
#include "harfbuzz-shaper-private.h"
#include <assert.h>
/*
// Uniscribe also defines dlig for Hebrew, but we leave this out for now, as it's mostly
// ligatures one does not want in modern Hebrew (as lam-alef ligatures).
*/
#ifndef NO_OPENTYPE
static const HB_OpenTypeFeature hebrew_features[] = {
{ HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty },
{0, 0}
};
#endif
/* Hebrew shaping. In the non opentype case we try to use the
presentation forms specified for Hebrew. Especially for the
ligatures with Dagesh this gives much better results than we could
achieve manually.
*/
HB_Bool HB_HebrewShape(HB_ShaperItem *shaper_item)
{
enum {
Dagesh = 0x5bc,
ShinDot = 0x5c1,
SinDot = 0x5c2,
Patah = 0x5b7,
Qamats = 0x5b8,
Holam = 0x5b9,
Rafe = 0x5bf
};
assert(shaper_item->item.script == HB_Script_Hebrew);
HB_HeuristicSetGlyphAttributes(shaper_item);
#ifndef NO_OPENTYPE
if (HB_SelectScript(shaper_item, hebrew_features)) {
const int availableGlyphs = shaper_item->num_glyphs;
if (!HB_ConvertStringToGlyphIndices(shaper_item))
return FALSE;
HB_OpenTypeShape(shaper_item, /*properties*/0);
return HB_OpenTypePosition(shaper_item, availableGlyphs, /*doLogClusters*/TRUE);
}
#endif
{
const HB_UChar16 *uc = shaper_item->string + shaper_item->item.pos;
unsigned short *logClusters = shaper_item->log_clusters;
HB_GlyphAttributes *attributes = shaper_item->attributes;
HB_Bool haveGlyphs;
int slen = 1;
int cluster_start = 0;
hb_uint32 i;
HB_STACKARRAY(HB_UChar16, shapedChars, 2 * shaper_item->item.length);
*shapedChars = *uc;
logClusters[0] = 0;
for (i = 1; i < shaper_item->item.length; ++i) {
hb_uint16 base = shapedChars[cluster_start];
hb_uint16 shaped = 0;
HB_Bool invalid = FALSE;
if (uc[i] == Dagesh) {
if (base >= 0x5d0
&& base <= 0x5ea
&& base != 0x5d7
&& base != 0x5dd
&& base != 0x5df
&& base != 0x5e2
&& base != 0x5e5) {
shaped = base - 0x5d0 + 0xfb30;
} else if (base == 0xfb2a || base == 0xfb2b /* Shin with Shin or Sin dot */) {
shaped = base + 2;
} else {
invalid = TRUE;
}
} else if (uc[i] == ShinDot) {
if (base == 0x05e9)
shaped = 0xfb2a;
else if (base == 0xfb49)
shaped = 0xfb2c;
else
invalid = TRUE;
} else if (uc[i] == SinDot) {
if (base == 0x05e9)
shaped = 0xfb2b;
else if (base == 0xfb49)
shaped = 0xfb2d;
else
invalid = TRUE;
} else if (uc[i] == Patah) {
if (base == 0x5d0)
shaped = 0xfb2e;
} else if (uc[i] == Qamats) {
if (base == 0x5d0)
shaped = 0xfb2f;
} else if (uc[i] == Holam) {
if (base == 0x5d5)
shaped = 0xfb4b;
} else if (uc[i] == Rafe) {
if (base == 0x5d1)
shaped = 0xfb4c;
else if (base == 0x5db)
shaped = 0xfb4d;
else if (base == 0x5e4)
shaped = 0xfb4e;
}
if (invalid) {
shapedChars[slen] = 0x25cc;
attributes[slen].clusterStart = TRUE;
attributes[slen].mark = FALSE;
attributes[slen].combiningClass = 0;
cluster_start = slen;
++slen;
}
if (shaped) {
if (shaper_item->font->klass->canRender(shaper_item->font, (HB_UChar16 *)&shaped, 1)) {
shapedChars[cluster_start] = shaped;
} else
shaped = 0;
}
if (!shaped) {
HB_CharCategory category;
int cmb;
shapedChars[slen] = uc[i];
HB_GetUnicodeCharProperties(uc[i], &category, &cmb);
if (category != HB_Mark_NonSpacing) {
attributes[slen].clusterStart = TRUE;
attributes[slen].mark = FALSE;
attributes[slen].combiningClass = 0;
attributes[slen].dontPrint = HB_IsControlChar(uc[i]);
cluster_start = slen;
} else {
attributes[slen].clusterStart = FALSE;
attributes[slen].mark = TRUE;
attributes[slen].combiningClass = cmb;
}
++slen;
}
logClusters[i] = cluster_start;
}
haveGlyphs = shaper_item->font->klass
->convertStringToGlyphIndices(shaper_item->font,
shapedChars, slen,
shaper_item->glyphs, &shaper_item->num_glyphs,
shaper_item->item.bidiLevel % 2);
HB_FREE_STACKARRAY(shapedChars);
if (!haveGlyphs)
return FALSE;
HB_HeuristicPosition(shaper_item);
}
return TRUE;
}

View File

@ -0,0 +1,84 @@
/*
* Copyright (C) 1998-2004 David Turner and Werner Lemberg
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
* Copyright (C) 2007 Red Hat, Inc.
*
* This is part of HarfBuzz, an OpenType Layout engine library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Red Hat Author(s): Behdad Esfahbod
*/
#include "harfbuzz-impl.h"
HB_INTERNAL HB_Pointer
_hb_alloc(size_t size,
HB_Error *perror )
{
HB_Error error = (HB_Error)0;
HB_Pointer block = NULL;
if ( size > 0 )
{
block = calloc( 1, size );
if ( !block )
error = ERR(HB_Err_Out_Of_Memory);
}
*perror = error;
return block;
}
HB_INTERNAL HB_Pointer
_hb_realloc(HB_Pointer block,
size_t new_size,
HB_Error *perror )
{
HB_Pointer block2 = NULL;
HB_Error error = (HB_Error)0;
block2 = realloc( block, new_size );
if ( block2 == NULL && new_size != 0 )
error = ERR(HB_Err_Out_Of_Memory);
if ( !error )
block = block2;
*perror = error;
return block;
}
HB_INTERNAL void
_hb_free( HB_Pointer block )
{
if ( block )
free( block );
}
/* helper func to set a breakpoint on */
HB_INTERNAL HB_Error
_hb_err (HB_Error code)
{
return code;
}

131
third_party/harfbuzz/src/harfbuzz-impl.h vendored Normal file
View File

@ -0,0 +1,131 @@
/*
* Copyright (C) 1998-2004 David Turner and Werner Lemberg
* Copyright (C) 2006 Behdad Esfahbod
*
* This is part of HarfBuzz, an OpenType Layout engine library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#ifndef HARFBUZZ_IMPL_H
#define HARFBUZZ_IMPL_H
#include "harfbuzz-global.h"
#include <stdlib.h>
HB_BEGIN_HEADER
#ifndef HB_INTERNAL
# define HB_INTERNAL
#endif
#ifndef NULL
# define NULL ((void *)0)
#endif
#ifndef FALSE
# define FALSE 0
#endif
#ifndef TRUE
# define TRUE 1
#endif
#ifndef TTAG_GDEF
# define TTAG_GDEF HB_MAKE_TAG( 'G', 'D', 'E', 'F' )
#endif
#ifndef TTAG_GPOS
# define TTAG_GPOS HB_MAKE_TAG( 'G', 'P', 'O', 'S' )
#endif
#ifndef TTAG_GSUB
# define TTAG_GSUB HB_MAKE_TAG( 'G', 'S', 'U', 'B' )
#endif
#ifndef HB_UNUSED
# define HB_UNUSED(arg) ((arg) = (arg))
#endif
#define HB_LIKELY(cond) (cond)
#define HB_UNLIKELY(cond) (cond)
#define ARRAY_LEN(Array) ((int)(sizeof (Array) / sizeof (Array)[0]))
#define HB_IsHighSurrogate(ucs) \
(((ucs) & 0xfc00) == 0xd800)
#define HB_IsLowSurrogate(ucs) \
(((ucs) & 0xfc00) == 0xdc00)
#define HB_SurrogateToUcs4(high, low) \
(((HB_UChar32)(high))<<10) + (low) - 0x35fdc00;
#define ALLOC(_ptr,_size) \
( (_ptr) = _hb_alloc( _size, &error ), error != 0 )
#define REALLOC(_ptr,_newsz) \
( (_ptr) = _hb_realloc( (_ptr), (_newsz), &error ), error != 0 )
#define FREE(_ptr) \
do { \
if ( (_ptr) ) \
{ \
_hb_free( _ptr ); \
_ptr = NULL; \
} \
} while (0)
#define ALLOC_ARRAY(_ptr,_count,_type) \
ALLOC(_ptr,(_count)*sizeof(_type))
#define REALLOC_ARRAY(_ptr,_newcnt,_type) \
REALLOC(_ptr,(_newcnt)*sizeof(_type))
#define MEM_Copy(dest,source,count) memcpy( (char*)(dest), (const char*)(source), (size_t)(count) )
#define ERR(err) _hb_err (err)
HB_INTERNAL HB_Pointer
_hb_alloc( size_t size,
HB_Error *perror_ );
HB_INTERNAL HB_Pointer
_hb_realloc( HB_Pointer block,
size_t new_size,
HB_Error *perror_ );
HB_INTERNAL void
_hb_free( HB_Pointer block );
/* helper func to set a breakpoint on */
HB_INTERNAL HB_Error
_hb_err (HB_Error code);
HB_END_HEADER
#endif /* HARFBUZZ_IMPL_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,667 @@
/*
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
*
* This is part of HarfBuzz, an OpenType Layout engine library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#include "harfbuzz-shaper.h"
#include "harfbuzz-shaper-private.h"
#include <assert.h>
#include <stdio.h>
/*
// Vocabulary
// Base -> A consonant or an independent vowel in its full (not subscript) form. It is the
// center of the syllable, it can be surrounded by coeng (subscript) consonants, vowels,
// split vowels, signs... but there is only one base in a syllable, it has to be coded as
// the first character of the syllable.
// split vowel --> vowel that has two parts placed separately (e.g. Before and after the consonant).
// Khmer language has five of them. Khmer split vowels either have one part before the
// base and one after the base or they have a part before the base and a part above the base.
// The first part of all Khmer split vowels is the same character, identical to
// the glyph of Khmer dependent vowel SRA EI
// coeng --> modifier used in Khmer to construct coeng (subscript) consonants
// Differently than indian languages, the coeng modifies the consonant that follows it,
// not the one preceding it Each consonant has two forms, the base form and the subscript form
// the base form is the normal one (using the consonants code-point), the subscript form is
// displayed when the combination coeng + consonant is encountered.
// Consonant of type 1 -> A consonant which has subscript for that only occupies space under a base consonant
// Consonant of type 2.-> Its subscript form occupies space under and before the base (only one, RO)
// Consonant of Type 3 -> Its subscript form occupies space under and after the base (KHO, CHHO, THHO, BA, YO, SA)
// Consonant shifter -> Khmer has to series of consonants. The same dependent vowel has different sounds
// if it is attached to a consonant of the first series or a consonant of the second series
// Most consonants have an equivalent in the other series, but some of theme exist only in
// one series (for example SA). If we want to use the consonant SA with a vowel sound that
// can only be done with a vowel sound that corresponds to a vowel accompanying a consonant
// of the other series, then we need to use a consonant shifter: TRIISAP or MUSIKATOAN
// x17C9 y x17CA. TRIISAP changes a first series consonant to second series sound and
// MUSIKATOAN a second series consonant to have a first series vowel sound.
// Consonant shifter are both normally supercript marks, but, when they are followed by a
// superscript, they change shape and take the form of subscript dependent vowel SRA U.
// If they are in the same syllable as a coeng consonant, Unicode 3.0 says that they
// should be typed before the coeng. Unicode 4.0 breaks the standard and says that it should
// be placed after the coeng consonant.
// Dependent vowel -> In khmer dependent vowels can be placed above, below, before or after the base
// Each vowel has its own position. Only one vowel per syllable is allowed.
// Signs -> Khmer has above signs and post signs. Only one above sign and/or one post sign are
// Allowed in a syllable.
//
//
// order is important here! This order must be the same that is found in each horizontal
// line in the statetable for Khmer (see khmerStateTable) .
*/
enum KhmerCharClassValues {
CC_RESERVED = 0,
CC_CONSONANT = 1, /* Consonant of type 1 or independent vowel */
CC_CONSONANT2 = 2, /* Consonant of type 2 */
CC_CONSONANT3 = 3, /* Consonant of type 3 */
CC_ZERO_WIDTH_NJ_MARK = 4, /* Zero Width non joiner character (0x200C) */
CC_CONSONANT_SHIFTER = 5,
CC_ROBAT = 6, /* Khmer special diacritic accent -treated differently in state table */
CC_COENG = 7, /* Subscript consonant combining character */
CC_DEPENDENT_VOWEL = 8,
CC_SIGN_ABOVE = 9,
CC_SIGN_AFTER = 10,
CC_ZERO_WIDTH_J_MARK = 11, /* Zero width joiner character */
CC_COUNT = 12 /* This is the number of character classes */
};
enum KhmerCharClassFlags {
CF_CLASS_MASK = 0x0000FFFF,
CF_CONSONANT = 0x01000000, /* flag to speed up comparing */
CF_SPLIT_VOWEL = 0x02000000, /* flag for a split vowel -> the first part is added in front of the syllable */
CF_DOTTED_CIRCLE = 0x04000000, /* add a dotted circle if a character with this flag is the first in a syllable */
CF_COENG = 0x08000000, /* flag to speed up comparing */
CF_SHIFTER = 0x10000000, /* flag to speed up comparing */
CF_ABOVE_VOWEL = 0x20000000, /* flag to speed up comparing */
/* position flags */
CF_POS_BEFORE = 0x00080000,
CF_POS_BELOW = 0x00040000,
CF_POS_ABOVE = 0x00020000,
CF_POS_AFTER = 0x00010000,
CF_POS_MASK = 0x000f0000
};
/* Characters that get referred to by name */
enum KhmerChar {
C_SIGN_ZWNJ = 0x200C,
C_SIGN_ZWJ = 0x200D,
C_RO = 0x179A,
C_VOWEL_AA = 0x17B6,
C_SIGN_NIKAHIT = 0x17C6,
C_VOWEL_E = 0x17C1,
C_COENG = 0x17D2
};
/*
// simple classes, they are used in the statetable (in this file) to control the length of a syllable
// they are also used to know where a character should be placed (location in reference to the base character)
// and also to know if a character, when independently displayed, should be displayed with a dotted-circle to
// indicate error in syllable construction
*/
enum {
_xx = CC_RESERVED,
_sa = CC_SIGN_ABOVE | CF_DOTTED_CIRCLE | CF_POS_ABOVE,
_sp = CC_SIGN_AFTER | CF_DOTTED_CIRCLE| CF_POS_AFTER,
_c1 = CC_CONSONANT | CF_CONSONANT,
_c2 = CC_CONSONANT2 | CF_CONSONANT,
_c3 = CC_CONSONANT3 | CF_CONSONANT,
_rb = CC_ROBAT | CF_POS_ABOVE | CF_DOTTED_CIRCLE,
_cs = CC_CONSONANT_SHIFTER | CF_DOTTED_CIRCLE | CF_SHIFTER,
_dl = CC_DEPENDENT_VOWEL | CF_POS_BEFORE | CF_DOTTED_CIRCLE,
_db = CC_DEPENDENT_VOWEL | CF_POS_BELOW | CF_DOTTED_CIRCLE,
_da = CC_DEPENDENT_VOWEL | CF_POS_ABOVE | CF_DOTTED_CIRCLE | CF_ABOVE_VOWEL,
_dr = CC_DEPENDENT_VOWEL | CF_POS_AFTER | CF_DOTTED_CIRCLE,
_co = CC_COENG | CF_COENG | CF_DOTTED_CIRCLE,
/* split vowel */
_va = _da | CF_SPLIT_VOWEL,
_vr = _dr | CF_SPLIT_VOWEL
};
/*
// Character class: a character class value
// ORed with character class flags.
*/
typedef unsigned long KhmerCharClass;
/*
// Character class tables
// _xx character does not combine into syllable, such as numbers, puntuation marks, non-Khmer signs...
// _sa Sign placed above the base
// _sp Sign placed after the base
// _c1 Consonant of type 1 or independent vowel (independent vowels behave as type 1 consonants)
// _c2 Consonant of type 2 (only RO)
// _c3 Consonant of type 3
// _rb Khmer sign robat u17CC. combining mark for subscript consonants
// _cd Consonant-shifter
// _dl Dependent vowel placed before the base (left of the base)
// _db Dependent vowel placed below the base
// _da Dependent vowel placed above the base
// _dr Dependent vowel placed behind the base (right of the base)
// _co Khmer combining mark COENG u17D2, combines with the consonant or independent vowel following
// it to create a subscript consonant or independent vowel
// _va Khmer split vowel in which the first part is before the base and the second one above the base
// _vr Khmer split vowel in which the first part is before the base and the second one behind (right of) the base
*/
static const KhmerCharClass khmerCharClasses[] = {
_c1, _c1, _c1, _c3, _c1, _c1, _c1, _c1, _c3, _c1, _c1, _c1, _c1, _c3, _c1, _c1, /* 1780 - 178F */
_c1, _c1, _c1, _c1, _c3, _c1, _c1, _c1, _c1, _c3, _c2, _c1, _c1, _c1, _c3, _c3, /* 1790 - 179F */
_c1, _c3, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, /* 17A0 - 17AF */
_c1, _c1, _c1, _c1, _dr, _dr, _dr, _da, _da, _da, _da, _db, _db, _db, _va, _vr, /* 17B0 - 17BF */
_vr, _dl, _dl, _dl, _vr, _vr, _sa, _sp, _sp, _cs, _cs, _sa, _rb, _sa, _sa, _sa, /* 17C0 - 17CF */
_sa, _sa, _co, _sa, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _sa, _xx, _xx /* 17D0 - 17DF */
};
/* this enum must reflect the range of khmerCharClasses */
enum KhmerCharClassesRange {
KhmerFirstChar = 0x1780,
KhmerLastChar = 0x17df
};
/*
// Below we define how a character in the input string is either in the khmerCharClasses table
// (in which case we get its type back), a ZWJ or ZWNJ (two characters that may appear
// within the syllable, but are not in the table) we also get their type back, or an unknown object
// in which case we get _xx (CC_RESERVED) back
*/
static KhmerCharClass getKhmerCharClass(HB_UChar16 uc)
{
if (uc == C_SIGN_ZWJ) {
return CC_ZERO_WIDTH_J_MARK;
}
if (uc == C_SIGN_ZWNJ) {
return CC_ZERO_WIDTH_NJ_MARK;
}
if (uc < KhmerFirstChar || uc > KhmerLastChar) {
return CC_RESERVED;
}
return khmerCharClasses[uc - KhmerFirstChar];
}
/*
// The stateTable is used to calculate the end (the length) of a well
// formed Khmer Syllable.
//
// Each horizontal line is ordered exactly the same way as the values in KhmerClassTable
// CharClassValues. This coincidence of values allows the follow up of the table.
//
// Each line corresponds to a state, which does not necessarily need to be a type
// of component... for example, state 2 is a base, with is always a first character
// in the syllable, but the state could be produced a consonant of any type when
// it is the first character that is analysed (in ground state).
//
// Differentiating 3 types of consonants is necessary in order to
// forbid the use of certain combinations, such as having a second
// coeng after a coeng RO,
// The inexistent possibility of having a type 3 after another type 3 is permitted,
// eliminating it would very much complicate the table, and it does not create typing
// problems, as the case above.
//
// The table is quite complex, in order to limit the number of coeng consonants
// to 2 (by means of the table).
//
// There a peculiarity, as far as Unicode is concerned:
// - The consonant-shifter is considered in two possible different
// locations, the one considered in Unicode 3.0 and the one considered in
// Unicode 4.0. (there is a backwards compatibility problem in this standard).
//
//
// xx independent character, such as a number, punctuation sign or non-khmer char
//
// c1 Khmer consonant of type 1 or an independent vowel
// that is, a letter in which the subscript for is only under the
// base, not taking any space to the right or to the left
//
// c2 Khmer consonant of type 2, the coeng form takes space under
// and to the left of the base (only RO is of this type)
//
// c3 Khmer consonant of type 3. Its subscript form takes space under
// and to the right of the base.
//
// cs Khmer consonant shifter
//
// rb Khmer robat
//
// co coeng character (u17D2)
//
// dv dependent vowel (including split vowels, they are treated in the same way).
// even if dv is not defined above, the component that is really tested for is
// KhmerClassTable::CC_DEPENDENT_VOWEL, which is common to all dependent vowels
//
// zwj Zero Width joiner
//
// zwnj Zero width non joiner
//
// sa above sign
//
// sp post sign
//
// there are lines with equal content but for an easier understanding
// (and maybe change in the future) we did not join them
*/
static const signed char khmerStateTable[][CC_COUNT] =
{
/* xx c1 c2 c3 zwnj cs rb co dv sa sp zwj */
{ 1, 2, 2, 2, 1, 1, 1, 6, 1, 1, 1, 2}, /* 0 - ground state */
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 1 - exit state (or sign to the right of the syllable) */
{-1, -1, -1, -1, 3, 4, 5, 6, 16, 17, 1, -1}, /* 2 - Base consonant */
{-1, -1, -1, -1, -1, 4, -1, -1, 16, -1, -1, -1}, /* 3 - First ZWNJ before a register shifter It can only be followed by a shifter or a vowel */
{-1, -1, -1, -1, 15, -1, -1, 6, 16, 17, 1, 14}, /* 4 - First register shifter */
{-1, -1, -1, -1, -1, -1, -1, -1, 20, -1, 1, -1}, /* 5 - Robat */
{-1, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1}, /* 6 - First Coeng */
{-1, -1, -1, -1, 12, 13, -1, 10, 16, 17, 1, 14}, /* 7 - First consonant of type 1 after coeng */
{-1, -1, -1, -1, 12, 13, -1, -1, 16, 17, 1, 14}, /* 8 - First consonant of type 2 after coeng */
{-1, -1, -1, -1, 12, 13, -1, 10, 16, 17, 1, 14}, /* 9 - First consonant or type 3 after ceong */
{-1, 11, 11, 11, -1, -1, -1, -1, -1, -1, -1, -1}, /* 10 - Second Coeng (no register shifter before) */
{-1, -1, -1, -1, 15, -1, -1, -1, 16, 17, 1, 14}, /* 11 - Second coeng consonant (or ind. vowel) no register shifter before */
{-1, -1, -1, -1, -1, 13, -1, -1, 16, -1, -1, -1}, /* 12 - Second ZWNJ before a register shifter */
{-1, -1, -1, -1, 15, -1, -1, -1, 16, 17, 1, 14}, /* 13 - Second register shifter */
{-1, -1, -1, -1, -1, -1, -1, -1, 16, -1, -1, -1}, /* 14 - ZWJ before vowel */
{-1, -1, -1, -1, -1, -1, -1, -1, 16, -1, -1, -1}, /* 15 - ZWNJ before vowel */
{-1, -1, -1, -1, -1, -1, -1, -1, -1, 17, 1, 18}, /* 16 - dependent vowel */
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 18}, /* 17 - sign above */
{-1, -1, -1, -1, -1, -1, -1, 19, -1, -1, -1, -1}, /* 18 - ZWJ after vowel */
{-1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 19 - Third coeng */
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1}, /* 20 - dependent vowel after a Robat */
};
/* #define KHMER_DEBUG */
#ifdef KHMER_DEBUG
#define KHDEBUG qDebug
#else
#define KHDEBUG if(0) printf
#endif
/*
// Given an input string of characters and a location in which to start looking
// calculate, using the state table, which one is the last character of the syllable
// that starts in the starting position.
*/
static int khmer_nextSyllableBoundary(const HB_UChar16 *s, int start, int end, HB_Bool *invalid)
{
const HB_UChar16 *uc = s + start;
int state = 0;
int pos = start;
*invalid = FALSE;
while (pos < end) {
KhmerCharClass charClass = getKhmerCharClass(*uc);
if (pos == start) {
*invalid = (charClass > 0) && ! (charClass & CF_CONSONANT);
}
state = khmerStateTable[state][charClass & CF_CLASS_MASK];
KHDEBUG("state[%d]=%d class=%8lx (uc=%4x)", pos - start, state,
charClass, *uc );
if (state < 0) {
break;
}
++uc;
++pos;
}
return pos;
}
#ifndef NO_OPENTYPE
static const HB_OpenTypeFeature khmer_features[] = {
{ HB_MAKE_TAG( 'p', 'r', 'e', 'f' ), PreFormProperty },
{ HB_MAKE_TAG( 'b', 'l', 'w', 'f' ), BelowFormProperty },
{ HB_MAKE_TAG( 'a', 'b', 'v', 'f' ), AboveFormProperty },
{ HB_MAKE_TAG( 'p', 's', 't', 'f' ), PostFormProperty },
{ HB_MAKE_TAG( 'p', 'r', 'e', 's' ), PreSubstProperty },
{ HB_MAKE_TAG( 'b', 'l', 'w', 's' ), BelowSubstProperty },
{ HB_MAKE_TAG( 'a', 'b', 'v', 's' ), AboveSubstProperty },
{ HB_MAKE_TAG( 'p', 's', 't', 's' ), PostSubstProperty },
{ HB_MAKE_TAG( 'c', 'l', 'i', 'g' ), CligProperty },
{ 0, 0 }
};
#endif
static HB_Bool khmer_shape_syllable(HB_Bool openType, HB_ShaperItem *item)
{
/* KHDEBUG("syllable from %d len %d, str='%s'", item->from, item->length,
item->string->mid(item->from, item->length).toUtf8().data()); */
int len = 0;
int syllableEnd = item->item.pos + item->item.length;
unsigned short reordered[16];
unsigned char properties[16];
enum {
AboveForm = 0x01,
PreForm = 0x02,
PostForm = 0x04,
BelowForm = 0x08
};
#ifndef NO_OPENTYPE
const int availableGlyphs = item->num_glyphs;
#endif
int coengRo;
int i;
/* according to the specs this is the max length one can get
### the real value should be smaller */
assert(item->item.length < 13);
memset(properties, 0, 16*sizeof(unsigned char));
#ifdef KHMER_DEBUG
qDebug("original:");
for (int i = from; i < syllableEnd; i++) {
qDebug(" %d: %4x", i, string[i]);
}
#endif
/*
// write a pre vowel or the pre part of a split vowel first
// and look out for coeng + ro. RO is the only vowel of type 2, and
// therefore the only one that requires saving space before the base.
*/
coengRo = -1; /* There is no Coeng Ro, if found this value will change */
for (i = item->item.pos; i < syllableEnd; i += 1) {
KhmerCharClass charClass = getKhmerCharClass(item->string[i]);
/* if a split vowel, write the pre part. In Khmer the pre part
is the same for all split vowels, same glyph as pre vowel C_VOWEL_E */
if (charClass & CF_SPLIT_VOWEL) {
reordered[len] = C_VOWEL_E;
properties[len] = PreForm;
++len;
break; /* there can be only one vowel */
}
/* if a vowel with pos before write it out */
if (charClass & CF_POS_BEFORE) {
reordered[len] = item->string[i];
properties[len] = PreForm;
++len;
break; /* there can be only one vowel */
}
/* look for coeng + ro and remember position
works because coeng + ro is always in front of a vowel (if there is a vowel)
and because CC_CONSONANT2 is enough to identify it, as it is the only consonant
with this flag */
if ( (charClass & CF_COENG) && (i + 1 < syllableEnd) &&
( (getKhmerCharClass(item->string[i+1]) & CF_CLASS_MASK) == CC_CONSONANT2) ) {
coengRo = i;
}
}
/* write coeng + ro if found */
if (coengRo > -1) {
reordered[len] = C_COENG;
properties[len] = PreForm;
++len;
reordered[len] = C_RO;
properties[len] = PreForm;
++len;
}
/*
shall we add a dotted circle?
If in the position in which the base should be (first char in the string) there is
a character that has the Dotted circle flag (a character that cannot be a base)
then write a dotted circle */
if (getKhmerCharClass(item->string[item->item.pos]) & CF_DOTTED_CIRCLE) {
reordered[len] = C_DOTTED_CIRCLE;
++len;
}
/* copy what is left to the output, skipping before vowels and
coeng Ro if they are present */
for (i = item->item.pos; i < syllableEnd; i += 1) {
HB_UChar16 uc = item->string[i];
KhmerCharClass charClass = getKhmerCharClass(uc);
/* skip a before vowel, it was already processed */
if (charClass & CF_POS_BEFORE) {
continue;
}
/* skip coeng + ro, it was already processed */
if (i == coengRo) {
i += 1;
continue;
}
switch (charClass & CF_POS_MASK)
{
case CF_POS_ABOVE :
reordered[len] = uc;
properties[len] = AboveForm;
++len;
break;
case CF_POS_AFTER :
reordered[len] = uc;
properties[len] = PostForm;
++len;
break;
case CF_POS_BELOW :
reordered[len] = uc;
properties[len] = BelowForm;
++len;
break;
default:
/* assign the correct flags to a coeng consonant
Consonants of type 3 are taged as Post forms and those type 1 as below forms */
if ( (charClass & CF_COENG) && i + 1 < syllableEnd ) {
unsigned char property = (getKhmerCharClass(item->string[i+1]) & CF_CLASS_MASK) == CC_CONSONANT3 ?
PostForm : BelowForm;
reordered[len] = uc;
properties[len] = property;
++len;
i += 1;
reordered[len] = item->string[i];
properties[len] = property;
++len;
break;
}
/* if a shifter is followed by an above vowel change the shifter to below form,
an above vowel can have two possible positions i + 1 or i + 3
(position i+1 corresponds to unicode 3, position i+3 to Unicode 4)
and there is an extra rule for C_VOWEL_AA + C_SIGN_NIKAHIT also for two
different positions, right after the shifter or after a vowel (Unicode 4) */
if ( (charClass & CF_SHIFTER) && (i + 1 < syllableEnd) ) {
if (getKhmerCharClass(item->string[i+1]) & CF_ABOVE_VOWEL ) {
reordered[len] = uc;
properties[len] = BelowForm;
++len;
break;
}
if (i + 2 < syllableEnd &&
(item->string[i+1] == C_VOWEL_AA) &&
(item->string[i+2] == C_SIGN_NIKAHIT) )
{
reordered[len] = uc;
properties[len] = BelowForm;
++len;
break;
}
if (i + 3 < syllableEnd && (getKhmerCharClass(item->string[i+3]) & CF_ABOVE_VOWEL) ) {
reordered[len] = uc;
properties[len] = BelowForm;
++len;
break;
}
if (i + 4 < syllableEnd &&
(item->string[i+3] == C_VOWEL_AA) &&
(item->string[i+4] == C_SIGN_NIKAHIT) )
{
reordered[len] = uc;
properties[len] = BelowForm;
++len;
break;
}
}
/* default - any other characters */
reordered[len] = uc;
++len;
break;
} /* switch */
} /* for */
if (!item->font->klass->convertStringToGlyphIndices(item->font,
reordered, len,
item->glyphs, &item->num_glyphs,
item->item.bidiLevel % 2))
return FALSE;
KHDEBUG("after shaping: len=%d", len);
for (i = 0; i < len; i++) {
item->attributes[i].mark = FALSE;
item->attributes[i].clusterStart = FALSE;
item->attributes[i].justification = 0;
item->attributes[i].zeroWidth = FALSE;
KHDEBUG(" %d: %4x property=%x", i, reordered[i], properties[i]);
}
/* now we have the syllable in the right order, and can start running it through open type. */
#ifndef NO_OPENTYPE
if (openType) {
hb_uint32 where[16];
for (i = 0; i < len; ++i) {
where[i] = ~(PreSubstProperty
| BelowSubstProperty
| AboveSubstProperty
| PostSubstProperty
| CligProperty
| PositioningProperties);
if (properties[i] == PreForm)
where[i] &= ~PreFormProperty;
else if (properties[i] == BelowForm)
where[i] &= ~BelowFormProperty;
else if (properties[i] == AboveForm)
where[i] &= ~AboveFormProperty;
else if (properties[i] == PostForm)
where[i] &= ~PostFormProperty;
}
HB_OpenTypeShape(item, where);
if (!HB_OpenTypePosition(item, availableGlyphs, /*doLogClusters*/FALSE))
return FALSE;
} else
#endif
{
KHDEBUG("Not using openType");
HB_HeuristicPosition(item);
}
item->attributes[0].clusterStart = TRUE;
return TRUE;
}
HB_Bool HB_KhmerShape(HB_ShaperItem *item)
{
HB_Bool openType = FALSE;
unsigned short *logClusters = item->log_clusters;
int i;
HB_ShaperItem syllable = *item;
int first_glyph = 0;
int sstart = item->item.pos;
int end = sstart + item->item.length;
assert(item->item.script == HB_Script_Khmer);
#ifndef NO_OPENTYPE
openType = HB_SelectScript(item, khmer_features);
#endif
KHDEBUG("khmer_shape: from %d length %d", item->item.pos, item->item.length);
while (sstart < end) {
HB_Bool invalid;
int send = khmer_nextSyllableBoundary(item->string, sstart, end, &invalid);
KHDEBUG("syllable from %d, length %d, invalid=%s", sstart, send-sstart,
invalid ? "TRUE" : "FALSE");
syllable.item.pos = sstart;
syllable.item.length = send-sstart;
syllable.glyphs = item->glyphs + first_glyph;
syllable.attributes = item->attributes + first_glyph;
syllable.offsets = item->offsets + first_glyph;
syllable.advances = item->advances + first_glyph;
syllable.num_glyphs = item->num_glyphs - first_glyph;
if (!khmer_shape_syllable(openType, &syllable)) {
KHDEBUG("syllable shaping failed, syllable requests %d glyphs", syllable.num_glyphs);
item->num_glyphs += syllable.num_glyphs;
return FALSE;
}
/* fix logcluster array */
KHDEBUG("syllable:");
for (i = first_glyph; i < first_glyph + (int)syllable.num_glyphs; ++i)
KHDEBUG(" %d -> glyph %x", i, item->glyphs[i]);
KHDEBUG(" logclusters:");
for (i = sstart; i < send; ++i) {
KHDEBUG(" %d -> glyph %d", i, first_glyph);
logClusters[i-item->item.pos] = first_glyph;
}
sstart = send;
first_glyph += syllable.num_glyphs;
}
item->num_glyphs = first_glyph;
return TRUE;
}
void HB_KhmerAttributes(HB_Script script, const HB_UChar16 *text, hb_uint32 from, hb_uint32 len, HB_CharAttributes *attributes)
{
int end = from + len;
const HB_UChar16 *uc = text + from;
hb_uint32 i = 0;
HB_UNUSED(script);
attributes += from;
while ( i < len ) {
HB_Bool invalid;
hb_uint32 boundary = khmer_nextSyllableBoundary( text, from+i, end, &invalid ) - from;
attributes[i].charStop = TRUE;
if ( boundary > len-1 ) boundary = len;
i++;
while ( i < boundary ) {
attributes[i].charStop = FALSE;
++uc;
++i;
}
assert( i == boundary );
}
}

View File

@ -0,0 +1,542 @@
/*
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
*
* This is part of HarfBuzz, an OpenType Layout engine library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#include "harfbuzz-shaper.h"
#include "harfbuzz-shaper-private.h"
#include <assert.h>
#include <stdio.h>
enum MymrCharClassValues
{
Mymr_CC_RESERVED = 0,
Mymr_CC_CONSONANT = 1, /* Consonant of type 1, that has subscript form */
Mymr_CC_CONSONANT2 = 2, /* Consonant of type 2, that has no subscript form */
Mymr_CC_NGA = 3, /* Consonant NGA */
Mymr_CC_YA = 4, /* Consonant YA */
Mymr_CC_RA = 5, /* Consonant RA */
Mymr_CC_WA = 6, /* Consonant WA */
Mymr_CC_HA = 7, /* Consonant HA */
Mymr_CC_IND_VOWEL = 8, /* Independent vowel */
Mymr_CC_ZERO_WIDTH_NJ_MARK = 9, /* Zero Width non joiner character (0x200C) */
Mymr_CC_VIRAMA = 10, /* Subscript consonant combining character */
Mymr_CC_PRE_VOWEL = 11, /* Dependent vowel, prebase (Vowel e) */
Mymr_CC_BELOW_VOWEL = 12, /* Dependent vowel, prebase (Vowel u, uu) */
Mymr_CC_ABOVE_VOWEL = 13, /* Dependent vowel, prebase (Vowel i, ii, ai) */
Mymr_CC_POST_VOWEL = 14, /* Dependent vowel, prebase (Vowel aa) */
Mymr_CC_SIGN_ABOVE = 15,
Mymr_CC_SIGN_BELOW = 16,
Mymr_CC_SIGN_AFTER = 17,
Mymr_CC_ZERO_WIDTH_J_MARK = 18, /* Zero width joiner character */
Mymr_CC_COUNT = 19 /* This is the number of character classes */
};
enum MymrCharClassFlags
{
Mymr_CF_CLASS_MASK = 0x0000FFFF,
Mymr_CF_CONSONANT = 0x01000000, /* flag to speed up comparing */
Mymr_CF_MEDIAL = 0x02000000, /* flag to speed up comparing */
Mymr_CF_IND_VOWEL = 0x04000000, /* flag to speed up comparing */
Mymr_CF_DEP_VOWEL = 0x08000000, /* flag to speed up comparing */
Mymr_CF_DOTTED_CIRCLE = 0x10000000, /* add a dotted circle if a character with this flag is the first in a syllable */
Mymr_CF_VIRAMA = 0x20000000, /* flag to speed up comparing */
/* position flags */
Mymr_CF_POS_BEFORE = 0x00080000,
Mymr_CF_POS_BELOW = 0x00040000,
Mymr_CF_POS_ABOVE = 0x00020000,
Mymr_CF_POS_AFTER = 0x00010000,
Mymr_CF_POS_MASK = 0x000f0000,
Mymr_CF_AFTER_KINZI = 0x00100000
};
/* Characters that get refrered to by name */
enum MymrChar
{
Mymr_C_SIGN_ZWNJ = 0x200C,
Mymr_C_SIGN_ZWJ = 0x200D,
Mymr_C_DOTTED_CIRCLE = 0x25CC,
Mymr_C_RA = 0x101B,
Mymr_C_YA = 0x101A,
Mymr_C_NGA = 0x1004,
Mymr_C_VOWEL_E = 0x1031,
Mymr_C_VIRAMA = 0x1039
};
enum
{
Mymr_xx = Mymr_CC_RESERVED,
Mymr_c1 = Mymr_CC_CONSONANT | Mymr_CF_CONSONANT | Mymr_CF_POS_BELOW,
Mymr_c2 = Mymr_CC_CONSONANT2 | Mymr_CF_CONSONANT,
Mymr_ng = Mymr_CC_NGA | Mymr_CF_CONSONANT | Mymr_CF_POS_ABOVE,
Mymr_ya = Mymr_CC_YA | Mymr_CF_CONSONANT | Mymr_CF_MEDIAL | Mymr_CF_POS_AFTER | Mymr_CF_AFTER_KINZI,
Mymr_ra = Mymr_CC_RA | Mymr_CF_CONSONANT | Mymr_CF_MEDIAL | Mymr_CF_POS_BEFORE,
Mymr_wa = Mymr_CC_WA | Mymr_CF_CONSONANT | Mymr_CF_MEDIAL | Mymr_CF_POS_BELOW,
Mymr_ha = Mymr_CC_HA | Mymr_CF_CONSONANT | Mymr_CF_MEDIAL | Mymr_CF_POS_BELOW,
Mymr_id = Mymr_CC_IND_VOWEL | Mymr_CF_IND_VOWEL,
Mymr_vi = Mymr_CC_VIRAMA | Mymr_CF_VIRAMA | Mymr_CF_POS_ABOVE | Mymr_CF_DOTTED_CIRCLE,
Mymr_dl = Mymr_CC_PRE_VOWEL | Mymr_CF_DEP_VOWEL | Mymr_CF_POS_BEFORE | Mymr_CF_DOTTED_CIRCLE | Mymr_CF_AFTER_KINZI,
Mymr_db = Mymr_CC_BELOW_VOWEL | Mymr_CF_DEP_VOWEL | Mymr_CF_POS_BELOW | Mymr_CF_DOTTED_CIRCLE | Mymr_CF_AFTER_KINZI,
Mymr_da = Mymr_CC_ABOVE_VOWEL | Mymr_CF_DEP_VOWEL | Mymr_CF_POS_ABOVE | Mymr_CF_DOTTED_CIRCLE | Mymr_CF_AFTER_KINZI,
Mymr_dr = Mymr_CC_POST_VOWEL | Mymr_CF_DEP_VOWEL | Mymr_CF_POS_AFTER | Mymr_CF_DOTTED_CIRCLE | Mymr_CF_AFTER_KINZI,
Mymr_sa = Mymr_CC_SIGN_ABOVE | Mymr_CF_DOTTED_CIRCLE | Mymr_CF_POS_ABOVE | Mymr_CF_AFTER_KINZI,
Mymr_sb = Mymr_CC_SIGN_BELOW | Mymr_CF_DOTTED_CIRCLE | Mymr_CF_POS_BELOW | Mymr_CF_AFTER_KINZI,
Mymr_sp = Mymr_CC_SIGN_AFTER | Mymr_CF_DOTTED_CIRCLE | Mymr_CF_AFTER_KINZI
};
typedef int MymrCharClass;
static const MymrCharClass mymrCharClasses[] =
{
Mymr_c1, Mymr_c1, Mymr_c1, Mymr_c1, Mymr_ng, Mymr_c1, Mymr_c1, Mymr_c1,
Mymr_c1, Mymr_c1, Mymr_c2, Mymr_c1, Mymr_c1, Mymr_c1, Mymr_c1, Mymr_c1, /* 1000 - 100F */
Mymr_c1, Mymr_c1, Mymr_c1, Mymr_c1, Mymr_c1, Mymr_c1, Mymr_c1, Mymr_c1,
Mymr_c1, Mymr_c1, Mymr_ya, Mymr_ra, Mymr_c1, Mymr_wa, Mymr_c1, Mymr_ha, /* 1010 - 101F */
Mymr_c2, Mymr_c2, Mymr_xx, Mymr_id, Mymr_id, Mymr_id, Mymr_id, Mymr_id,
Mymr_xx, Mymr_id, Mymr_id, Mymr_xx, Mymr_dr, Mymr_da, Mymr_da, Mymr_db, /* 1020 - 102F */
Mymr_db, Mymr_dl, Mymr_da, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_sa, Mymr_sb,
Mymr_sp, Mymr_vi, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, /* 1030 - 103F */
Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx,
Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, /* 1040 - 104F */
Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx,
Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, /* 1050 - 105F */
};
static MymrCharClass
getMyanmarCharClass (HB_UChar16 ch)
{
if (ch == Mymr_C_SIGN_ZWJ)
return Mymr_CC_ZERO_WIDTH_J_MARK;
if (ch == Mymr_C_SIGN_ZWNJ)
return Mymr_CC_ZERO_WIDTH_NJ_MARK;
if (ch < 0x1000 || ch > 0x105f)
return Mymr_CC_RESERVED;
return mymrCharClasses[ch - 0x1000];
}
static const signed char mymrStateTable[][Mymr_CC_COUNT] =
{
/* xx c1, c2 ng ya ra wa ha id zwnj vi dl db da dr sa sb sp zwj */
{ 1, 4, 4, 2, 4, 4, 4, 4, 24, 1, 27, 17, 18, 19, 20, 21, 1, 1, 4}, /* 0 - ground state */
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 1 - exit state (or sp to the right of the syllable) */
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, 17, 18, 19, 20, 21, -1, -1, 4}, /* 2 - NGA */
{-1, 4, 4, 4, 4, 4, 4, 4, -1, 23, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 3 - Virama after NGA */
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5, 17, 18, 19, 20, 21, 1, 1, -1}, /* 4 - Base consonant */
{-2, 6, -2, -2, 7, 8, 9, 10, -2, 23, -2, -2, -2, -2, -2, -2, -2, -2, -2}, /* 5 - First virama */
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 25, 17, 18, 19, 20, 21, -1, -1, -1}, /* 6 - c1 after virama */
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12, 17, 18, 19, 20, 21, -1, -1, -1}, /* 7 - ya after virama */
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12, 17, 18, 19, 20, 21, -1, -1, -1}, /* 8 - ra after virama */
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12, 17, 18, 19, 20, 21, -1, -1, -1}, /* 9 - wa after virama */
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 17, 18, 19, 20, 21, -1, -1, -1}, /* 10 - ha after virama */
{-1, -1, -1, -1, 7, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 11 - Virama after NGA+zwj */
{-2, -2, -2, -2, -2, -2, 13, 14, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2}, /* 12 - Second virama */
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15, 17, 18, 19, 20, 21, -1, -1, -1}, /* 13 - wa after virama */
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 17, 18, 19, 20, 21, -1, -1, -1}, /* 14 - ha after virama */
{-2, -2, -2, -2, -2, -2, -2, 16, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2}, /* 15 - Third virama */
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 17, 18, 19, 20, 21, -1, -1, -1}, /* 16 - ha after virama */
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20, 21, 1, 1, -1}, /* 17 - dl, Dependent vowel e */
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 19, -1, 21, 1, 1, -1}, /* 18 - db, Dependent vowel u,uu */
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1}, /* 19 - da, Dependent vowel i,ii,ai */
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 22, -1, -1, -1, -1, -1, 1, 1, -1}, /* 20 - dr, Dependent vowel aa */
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1}, /* 21 - sa, Sign anusvara */
{-1, -1, -1, -1, -1, -1, -1, -1, -1, 23, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 22 - atha */
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1}, /* 23 - zwnj for atha */
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1}, /* 24 - Independent vowel */
{-2, -2, -2, -2, 26, 26, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2}, /* 25 - Virama after subscript consonant */
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12, 17, 18, 19, 20, 21, -1, 1, -1}, /* 26 - ra/ya after subscript consonant + virama */
{-1, 6, -1, -1, 7, 8, 9, 10, -1, 23, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 27 - Virama after ground state */
/* exit state -2 is for invalid order of medials and combination of invalids
with virama where virama should treat as start of next syllable
*/
};
/*#define MYANMAR_DEBUG */
#ifdef MYANMAR_DEBUG
#define MMDEBUG qDebug
#else
#define MMDEBUG if(0) printf
#endif
/*
// Given an input string of characters and a location in which to start looking
// calculate, using the state table, which one is the last character of the syllable
// that starts in the starting position.
*/
static int myanmar_nextSyllableBoundary(const HB_UChar16 *s, int start, int end, HB_Bool *invalid)
{
const HB_UChar16 *uc = s + start;
int state = 0;
int pos = start;
*invalid = FALSE;
while (pos < end) {
MymrCharClass charClass = getMyanmarCharClass(*uc);
state = mymrStateTable[state][charClass & Mymr_CF_CLASS_MASK];
if (pos == start)
*invalid = (HB_Bool)(charClass & Mymr_CF_DOTTED_CIRCLE);
MMDEBUG("state[%d]=%d class=%8x (uc=%4x)", pos - start, state, charClass, *uc);
if (state < 0) {
if (state < -1)
--pos;
break;
}
++uc;
++pos;
}
return pos;
}
#ifndef NO_OPENTYPE
/* ###### might have to change order of above and below forms and substitutions,
but according to Unicode below comes before above */
static const HB_OpenTypeFeature myanmar_features[] = {
{ HB_MAKE_TAG('p', 'r', 'e', 'f'), PreFormProperty },
{ HB_MAKE_TAG('b', 'l', 'w', 'f'), BelowFormProperty },
{ HB_MAKE_TAG('a', 'b', 'v', 'f'), AboveFormProperty },
{ HB_MAKE_TAG('p', 's', 't', 'f'), PostFormProperty },
{ HB_MAKE_TAG('p', 'r', 'e', 's'), PreSubstProperty },
{ HB_MAKE_TAG('b', 'l', 'w', 's'), BelowSubstProperty },
{ HB_MAKE_TAG('a', 'b', 'v', 's'), AboveSubstProperty },
{ HB_MAKE_TAG('p', 's', 't', 's'), PostSubstProperty },
{ HB_MAKE_TAG('r', 'l', 'i', 'g'), CligProperty }, /* Myanmar1 uses this instead of the other features */
{ 0, 0 }
};
#endif
/*
// Visual order before shaping should be:
//
// [Vowel Mark E]
// [Virama + Medial Ra]
// [Base]
// [Virama + Consonant]
// [Nga + Virama] (Kinzi) ### should probably come before post forms (medial ya)
// [Vowels]
// [Marks]
//
// This means that we can keep the logical order apart from having to
// move the pre vowel, medial ra and kinzi
*/
static HB_Bool myanmar_shape_syllable(HB_Bool openType, HB_ShaperItem *item, HB_Bool invalid)
{
/*
// MMDEBUG("\nsyllable from %d len %d, str='%s'", item->item.pos, item->item.length,
// item->string->mid(item->from, item->length).toUtf8().data());
*/
#ifndef NO_OPENTYPE
const int availableGlyphs = item->num_glyphs;
#endif
const HB_UChar16 *uc = item->string + item->item.pos;
int vowel_e = -1;
int kinzi = -1;
int medial_ra = -1;
int base = -1;
int i;
int len = 0;
unsigned short reordered[32];
unsigned char properties[32];
enum {
AboveForm = 0x01,
PreForm = 0x02,
PostForm = 0x04,
BelowForm = 0x08
};
HB_Bool lastWasVirama = FALSE;
int basePos = -1;
memset(properties, 0, 32*sizeof(unsigned char));
/* according to the table the max length of a syllable should be around 14 chars */
assert(item->item.length < 32);
#ifdef MYANMAR_DEBUG
printf("original:");
for (i = 0; i < (int)item->item.length; i++) {
printf(" %d: %4x", i, uc[i]);
}
#endif
for (i = 0; i < (int)item->item.length; ++i) {
HB_UChar16 chr = uc[i];
if (chr == Mymr_C_VOWEL_E) {
vowel_e = i;
continue;
}
if (i == 0
&& chr == Mymr_C_NGA
&& i + 2 < (int)item->item.length
&& uc[i+1] == Mymr_C_VIRAMA) {
int mc = getMyanmarCharClass(uc[i+2]);
/*MMDEBUG("maybe kinzi: mc=%x", mc);*/
if ((mc & Mymr_CF_CONSONANT) == Mymr_CF_CONSONANT) {
kinzi = i;
continue;
}
}
if (base >= 0
&& chr == Mymr_C_VIRAMA
&& i + 1 < (int)item->item.length
&& uc[i+1] == Mymr_C_RA) {
medial_ra = i;
continue;
}
if (base < 0)
base = i;
}
MMDEBUG("\n base=%d, vowel_e=%d, kinzi=%d, medial_ra=%d", base, vowel_e, kinzi, medial_ra);
/* write vowel_e if found */
if (vowel_e >= 0) {
reordered[0] = Mymr_C_VOWEL_E;
len = 1;
}
/* write medial_ra */
if (medial_ra >= 0) {
reordered[len] = Mymr_C_VIRAMA;
reordered[len+1] = Mymr_C_RA;
properties[len] = PreForm;
properties[len+1] = PreForm;
len += 2;
}
/* shall we add a dotted circle?
If in the position in which the base should be (first char in the string) there is
a character that has the Dotted circle flag (a character that cannot be a base)
then write a dotted circle */
if (invalid) {
reordered[len] = C_DOTTED_CIRCLE;
++len;
}
/* copy the rest of the syllable to the output, inserting the kinzi
at the correct place */
for (i = 0; i < (int)item->item.length; ++i) {
hb_uint16 chr = uc[i];
MymrCharClass cc;
if (i == vowel_e)
continue;
if (i == medial_ra || i == kinzi) {
++i;
continue;
}
cc = getMyanmarCharClass(uc[i]);
if (kinzi >= 0 && i > base && (cc & Mymr_CF_AFTER_KINZI)) {
reordered[len] = Mymr_C_NGA;
reordered[len+1] = Mymr_C_VIRAMA;
properties[len-1] = AboveForm;
properties[len] = AboveForm;
len += 2;
kinzi = -1;
}
if (lastWasVirama) {
int prop = 0;
switch(cc & Mymr_CF_POS_MASK) {
case Mymr_CF_POS_BEFORE:
prop = PreForm;
break;
case Mymr_CF_POS_BELOW:
prop = BelowForm;
break;
case Mymr_CF_POS_ABOVE:
prop = AboveForm;
break;
case Mymr_CF_POS_AFTER:
prop = PostForm;
break;
default:
break;
}
properties[len-1] = prop;
properties[len] = prop;
if(basePos >= 0 && basePos == len-2)
properties[len-2] = prop;
}
lastWasVirama = (chr == Mymr_C_VIRAMA);
if(i == base)
basePos = len;
if ((chr != Mymr_C_SIGN_ZWNJ && chr != Mymr_C_SIGN_ZWJ) || !len) {
reordered[len] = chr;
++len;
}
}
if (kinzi >= 0) {
reordered[len] = Mymr_C_NGA;
reordered[len+1] = Mymr_C_VIRAMA;
properties[len] = AboveForm;
properties[len+1] = AboveForm;
len += 2;
}
if (!item->font->klass->convertStringToGlyphIndices(item->font,
reordered, len,
item->glyphs, &item->num_glyphs,
item->item.bidiLevel % 2))
return FALSE;
MMDEBUG("after shaping: len=%d", len);
for (i = 0; i < len; i++) {
item->attributes[i].mark = FALSE;
item->attributes[i].clusterStart = FALSE;
item->attributes[i].justification = 0;
item->attributes[i].zeroWidth = FALSE;
MMDEBUG(" %d: %4x property=%x", i, reordered[i], properties[i]);
}
/* now we have the syllable in the right order, and can start running it through open type. */
#ifndef NO_OPENTYPE
if (openType) {
unsigned short logClusters[32];
hb_uint32 where[32];
for (i = 0; i < len; ++i)
logClusters[i] = i;
for (i = 0; i < len; ++i) {
where[i] = ~(PreSubstProperty
| BelowSubstProperty
| AboveSubstProperty
| PostSubstProperty
| CligProperty
| PositioningProperties);
if (properties[i] & PreForm)
where[i] &= ~PreFormProperty;
if (properties[i] & BelowForm)
where[i] &= ~BelowFormProperty;
if (properties[i] & AboveForm)
where[i] &= ~AboveFormProperty;
if (properties[i] & PostForm)
where[i] &= ~PostFormProperty;
}
HB_OpenTypeShape(item, where);
if (!HB_OpenTypePosition(item, availableGlyphs, /*doLogClusters*/FALSE))
return FALSE;
} else
#endif
{
MMDEBUG("Not using openType");
HB_HeuristicPosition(item);
}
item->attributes[0].clusterStart = TRUE;
return TRUE;
}
HB_Bool HB_MyanmarShape(HB_ShaperItem *item)
{
HB_Bool openType = FALSE;
unsigned short *logClusters = item->log_clusters;
HB_ShaperItem syllable = *item;
int first_glyph = 0;
int sstart = item->item.pos;
int end = sstart + item->item.length;
int i = 0;
assert(item->item.script == HB_Script_Myanmar);
#ifndef NO_OPENTYPE
openType = HB_SelectScript(item, myanmar_features);
#endif
MMDEBUG("myanmar_shape: from %d length %d", item->item.pos, item->item.length);
while (sstart < end) {
HB_Bool invalid;
int send = myanmar_nextSyllableBoundary(item->string, sstart, end, &invalid);
MMDEBUG("syllable from %d, length %d, invalid=%s", sstart, send-sstart,
invalid ? "TRUE" : "FALSE");
syllable.item.pos = sstart;
syllable.item.length = send-sstart;
syllable.glyphs = item->glyphs + first_glyph;
syllable.attributes = item->attributes + first_glyph;
syllable.advances = item->advances + first_glyph;
syllable.offsets = item->offsets + first_glyph;
syllable.num_glyphs = item->num_glyphs - first_glyph;
if (!myanmar_shape_syllable(openType, &syllable, invalid)) {
MMDEBUG("syllable shaping failed, syllable requests %d glyphs", syllable.num_glyphs);
item->num_glyphs += syllable.num_glyphs;
return FALSE;
}
/* fix logcluster array */
MMDEBUG("syllable:");
for (i = first_glyph; i < first_glyph + (int)syllable.num_glyphs; ++i)
MMDEBUG(" %d -> glyph %x", i, item->glyphs[i]);
MMDEBUG(" logclusters:");
for (i = sstart; i < send; ++i) {
MMDEBUG(" %d -> glyph %d", i, first_glyph);
logClusters[i-item->item.pos] = first_glyph;
}
sstart = send;
first_glyph += syllable.num_glyphs;
}
item->num_glyphs = first_glyph;
return TRUE;
}
void HB_MyanmarAttributes(HB_Script script, const HB_UChar16 *text, hb_uint32 from, hb_uint32 len, HB_CharAttributes *attributes)
{
int end = from + len;
const HB_UChar16 *uc = text + from;
hb_uint32 i = 0;
HB_UNUSED(script);
attributes += from;
while (i < len) {
HB_Bool invalid;
hb_uint32 boundary = myanmar_nextSyllableBoundary(text, from+i, end, &invalid) - from;
attributes[i].charStop = TRUE;
if (i)
attributes[i-1].lineBreakType = HB_Break;
if (boundary > len-1)
boundary = len;
i++;
while (i < boundary) {
attributes[i].charStop = FALSE;
++uc;
++i;
}
assert(i == boundary);
}
}

View File

@ -0,0 +1,102 @@
/*
* Copyright (C) 1998-2004 David Turner and Werner Lemberg
* Copyright (C) 2006 Behdad Esfahbod
*
* This is part of HarfBuzz, an OpenType Layout engine library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#ifndef HARFBUZZ_OPEN_PRIVATE_H
#define HARFBUZZ_OPEN_PRIVATE_H
#include "harfbuzz-impl.h"
#include "harfbuzz-open.h"
#include "harfbuzz-gsub-private.h"
#include "harfbuzz-gpos-private.h"
HB_BEGIN_HEADER
struct HB_SubTable_
{
union
{
HB_GSUB_SubTable gsub;
HB_GPOS_SubTable gpos;
} st;
};
HB_INTERNAL HB_Error
_HB_OPEN_Load_ScriptList( HB_ScriptList* sl,
HB_Stream input );
HB_INTERNAL HB_Error
_HB_OPEN_Load_FeatureList( HB_FeatureList* fl,
HB_Stream input );
HB_INTERNAL HB_Error
_HB_OPEN_Load_LookupList( HB_LookupList* ll,
HB_Stream input,
HB_Type type );
HB_INTERNAL HB_Error
_HB_OPEN_Load_Coverage( HB_Coverage* c,
HB_Stream input );
HB_INTERNAL HB_Error
_HB_OPEN_Load_ClassDefinition( HB_ClassDefinition* cd,
HB_UShort limit,
HB_Stream input );
HB_INTERNAL HB_Error
_HB_OPEN_Load_EmptyOrClassDefinition( HB_ClassDefinition* cd,
HB_UShort limit,
HB_UInt class_offset,
HB_UInt base_offset,
HB_Stream input );
HB_INTERNAL HB_Error
_HB_OPEN_Load_Device( HB_Device* d,
HB_Stream input );
HB_INTERNAL void _HB_OPEN_Free_ScriptList( HB_ScriptList* sl );
HB_INTERNAL void _HB_OPEN_Free_FeatureList( HB_FeatureList* fl );
HB_INTERNAL void _HB_OPEN_Free_LookupList( HB_LookupList* ll,
HB_Type type );
HB_INTERNAL void _HB_OPEN_Free_Coverage( HB_Coverage* c );
HB_INTERNAL void _HB_OPEN_Free_ClassDefinition( HB_ClassDefinition* cd );
HB_INTERNAL void _HB_OPEN_Free_Device( HB_Device* d );
HB_INTERNAL HB_Error
_HB_OPEN_Coverage_Index( HB_Coverage* c,
HB_UShort glyphID,
HB_UShort* index );
HB_INTERNAL HB_Error
_HB_OPEN_Get_Class( HB_ClassDefinition* cd,
HB_UShort glyphID,
HB_UShort* klass,
HB_UShort* index );
HB_INTERNAL HB_Error
_HB_OPEN_Get_Device( HB_Device* d,
HB_UShort size,
HB_Short* value );
HB_END_HEADER
#endif /* HARFBUZZ_OPEN_PRIVATE_H */

1416
third_party/harfbuzz/src/harfbuzz-open.c vendored Normal file

File diff suppressed because it is too large Load Diff

282
third_party/harfbuzz/src/harfbuzz-open.h vendored Normal file
View File

@ -0,0 +1,282 @@
/*
* Copyright (C) 1998-2004 David Turner and Werner Lemberg
* Copyright (C) 2006 Behdad Esfahbod
*
* This is part of HarfBuzz, an OpenType Layout engine library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#ifndef HARFBUZZ_OPEN_H
#define HARFBUZZ_OPEN_H
#include "harfbuzz-global.h"
HB_BEGIN_HEADER
/* Use this if a feature applies to all glyphs */
#define HB_ALL_GLYPHS 0xFFFF
#define HB_DEFAULT_LANGUAGE 0xFFFF
#define HB_MAX_NESTING_LEVEL 100
/* Script list related structures */
struct HB_LangSys_
{
HB_UShort LookupOrderOffset; /* always 0 for TT Open 1.0 */
HB_UShort ReqFeatureIndex; /* required FeatureIndex */
HB_UShort FeatureCount; /* number of Feature indices */
HB_UShort* FeatureIndex; /* array of Feature indices */
};
typedef struct HB_LangSys_ HB_LangSys;
struct HB_LangSysRecord_
{
HB_UInt LangSysTag; /* LangSysTag identifier */
HB_LangSys LangSys; /* LangSys table */
};
typedef struct HB_LangSysRecord_ HB_LangSysRecord;
struct HB_ScriptTable_
{
HB_LangSys DefaultLangSys; /* DefaultLangSys table */
HB_UShort LangSysCount; /* number of LangSysRecords */
HB_LangSysRecord* LangSysRecord; /* array of LangSysRecords */
};
typedef struct HB_ScriptTable_ HB_ScriptTable;
struct HB_ScriptRecord_
{
HB_UInt ScriptTag; /* ScriptTag identifier */
HB_ScriptTable Script; /* Script table */
};
typedef struct HB_ScriptRecord_ HB_ScriptRecord;
struct HB_ScriptList_
{
HB_UShort ScriptCount; /* number of ScriptRecords */
HB_ScriptRecord* ScriptRecord; /* array of ScriptRecords */
};
typedef struct HB_ScriptList_ HB_ScriptList;
/* Feature list related structures */
struct HB_Feature_
{
HB_UShort FeatureParams; /* always 0 for TT Open 1.0 */
HB_UShort LookupListCount; /* number of LookupList indices */
HB_UShort* LookupListIndex; /* array of LookupList indices */
};
typedef struct HB_Feature_ HB_Feature;
struct HB_FeatureRecord_
{
HB_UInt FeatureTag; /* FeatureTag identifier */
HB_Feature Feature; /* Feature table */
};
typedef struct HB_FeatureRecord_ HB_FeatureRecord;
struct HB_FeatureList_
{
HB_UShort FeatureCount; /* number of FeatureRecords */
HB_FeatureRecord* FeatureRecord; /* array of FeatureRecords */
HB_UShort* ApplyOrder; /* order to apply features */
HB_UShort ApplyCount; /* number of elements in ApplyOrder */
};
typedef struct HB_FeatureList_ HB_FeatureList;
/* Lookup list related structures */
typedef struct HB_SubTable_ HB_SubTable;
struct HB_Lookup_
{
HB_UShort LookupType; /* Lookup type */
HB_UShort LookupFlag; /* Lookup qualifiers */
HB_UShort SubTableCount; /* number of SubTables */
HB_SubTable* SubTable; /* array of SubTables */
};
typedef struct HB_Lookup_ HB_Lookup;
/* The `Properties' field is not defined in the OpenType specification but
is needed for processing lookups. If properties[n] is > 0, the
functions HB_GSUB_Apply_String() resp. HB_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 HB_LookupList_
{
HB_UShort LookupCount; /* number of Lookups */
HB_Lookup* Lookup; /* array of Lookup records */
HB_UInt* Properties; /* array of flags */
};
typedef struct HB_LookupList_ HB_LookupList;
/* Possible LookupFlag bit masks. `HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS' comes from the
OpenType 1.2 specification; HB_LOOKUP_FLAG_RIGHT_TO_LEFT has been (re)introduced in
OpenType 1.3 -- if set, the last glyph in a cursive attachment
sequence has to be positioned on the baseline -- regardless of the
writing direction. */
#define HB_LOOKUP_FLAG_RIGHT_TO_LEFT 0x0001
#define HB_LOOKUP_FLAG_IGNORE_BASE_GLYPHS 0x0002
#define HB_LOOKUP_FLAG_IGNORE_LIGATURES 0x0004
#define HB_LOOKUP_FLAG_IGNORE_MARKS 0x0008
#define HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS 0xFF00
struct HB_CoverageFormat1_
{
HB_UShort GlyphCount; /* number of glyphs in GlyphArray */
HB_UShort* GlyphArray; /* array of glyph IDs */
};
typedef struct HB_CoverageFormat1_ HB_CoverageFormat1;
struct HB_RangeRecord_
{
HB_UShort Start; /* first glyph ID in the range */
HB_UShort End; /* last glyph ID in the range */
HB_UShort StartCoverageIndex; /* coverage index of first
glyph ID in the range */
};
typedef struct HB_RangeRecord_ HB_RangeRecord;
struct HB_CoverageFormat2_
{
HB_UShort RangeCount; /* number of RangeRecords */
HB_RangeRecord* RangeRecord; /* array of RangeRecords */
};
typedef struct HB_CoverageFormat2_ HB_CoverageFormat2;
struct HB_Coverage_
{
HB_UShort CoverageFormat; /* 1 or 2 */
union
{
HB_CoverageFormat1 cf1;
HB_CoverageFormat2 cf2;
} cf;
};
typedef struct HB_Coverage_ HB_Coverage;
struct HB_ClassDefFormat1_
{
HB_UShort StartGlyph; /* first glyph ID of the
ClassValueArray */
HB_UShort GlyphCount; /* size of the ClassValueArray */
HB_UShort* ClassValueArray; /* array of class values */
};
typedef struct HB_ClassDefFormat1_ HB_ClassDefFormat1;
struct HB_ClassRangeRecord_
{
HB_UShort Start; /* first glyph ID in the range */
HB_UShort End; /* last glyph ID in the range */
HB_UShort Class; /* applied to all glyphs in range */
};
typedef struct HB_ClassRangeRecord_ HB_ClassRangeRecord;
struct HB_ClassDefFormat2_
{
HB_UShort ClassRangeCount;
/* number of ClassRangeRecords */
HB_ClassRangeRecord* ClassRangeRecord;
/* array of ClassRangeRecords */
};
typedef struct HB_ClassDefFormat2_ HB_ClassDefFormat2;
struct HB_ClassDefinition_
{
HB_Bool loaded;
HB_UShort ClassFormat; /* 1 or 2 */
union
{
HB_ClassDefFormat1 cd1;
HB_ClassDefFormat2 cd2;
} cd;
};
typedef struct HB_ClassDefinition_ HB_ClassDefinition;
struct HB_Device_
{
HB_UShort StartSize; /* smallest size to correct */
HB_UShort EndSize; /* largest size to correct */
HB_UShort DeltaFormat; /* DeltaValue array data format:
1, 2, or 3 */
HB_UShort* DeltaValue; /* array of compressed data */
};
typedef struct HB_Device_ HB_Device;
enum HB_Type_
{
HB_Type_GSUB,
HB_Type_GPOS
};
typedef enum HB_Type_ HB_Type;
HB_END_HEADER
#endif /* HARFBUZZ_OPEN_H */

View File

@ -0,0 +1,199 @@
/*
* Copyright (C) 2006 Red Hat, Inc.
*
* This is part of HarfBuzz, an OpenType Layout engine library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Red Hat Author(s): Owen Taylor
*/
#include <stdint.h>
/* Base Types */
typedef hb_uint16 HB_CodePoint; /* UTF-16 codepoint (not character ) */
typedef char HB_Boolean;
typedef hb_uint32 HB_Fixed; /* 26.6 */
typedef hb_uint32 HB_Glyph;
typedef hb_uint32 HB_Unichar;
/* Metrics reported by the font backend for use of the shaper */
typedef struct _HB_GlyphMetrics HB_GlyphMetrics;
struct _HB_GlyphMetrics
{
HB_Fixed advance;
/* Do we need ink/logical extents for the glyph here? */
};
/*
* HB_Font: Abstract font interface.
* First pass of this might just have FT_Face *getFace();
*/
typedef struct _HB_Font HB_Font;
typedef struct _HB_FontClass HB_FontClass;
struct HB_FontClass {
HB_Glyph (*charToGlyph)(HB_Font *font, HB_Unichar chr);
void (*getMetrics)(HB_Font *font, HB_Glyph glyph, HB_GlyphMetrics *metrics);
HB_Boolean (*getSFontTable)(HB_Font *font, void **cookie, char **start, int *len);
HB_Boolean (*freeSFontTable)(void **cookie);
};
struct _HB_Font {
HB_FontClass *clazz;
};
/*
* Language tags, of the form en-us; represented as interned, canonicalized
* strings. hb_language_from_string("en_US"), hb_language_from_string("en-us")
* both return the same (pointer-comparable) HB_Language).
*/
typedef struct HB_Language_ *HB_Language;
HB_Language hb_language_from_string(const char *str);
const char *hb_language_to_string(HB_Language language);
/* Special treatment for the edges of runs.
*/
typedef enum {
HB_RUN_EDGE_LINE_VISUAL_EDGE = 1 << 0,
HB_RUN_EDGE_LINE_LOGICAL_EDGE = 1 << 1,
HB_RUN_EDGE_LINE_ADD_HYPHEN = 1 << 2 /* ???? */
} HB_RunEdge;
/* Defines optional informaiton in HB_ShapeInput; this allows extension
* of HB_ShapeInput while keeping binary compatibility
*/
typedef enum {
HB_SHAPE_START_TYPE = 1 << 0,
HB_SHAPE_END_TYPE = 1 << 1
} HB_ShapeFlags;
/* Attributes types are described by "interned strings"; this is a little
* annoying if you want to write a switch statement, but keeps things
* simple.
*/
typedef struct _HB_AttributeType *HB_AttributeType;
HB_AttributeType hb_attribute_type_from_string(const char *str);
const char *hb_attribute_type_to_string(HB_AttributeType attribute_type);
struct HB_Attribute {
HB_AttributeType type;
int start;
int end;
};
/**
* You could handle this like HB_Language, but an enum seems a little nicer;
* another approach would be to use OpenType script tags.
*/
typedef enum {
HB_SCRIPT_LATIN
/* ... */
} HB_ShapeScript;
/* This is just the subset of direction information needed by the shaper */
typedef enum {
HB_DIRECTION_LTR,
HB_DIRECTION_RTL,
HB_DIRECTION_TTB
} HB_Direction;
typedef struct _HB_ShapeInput HB_ShapeInput;
struct _HB_ShapeInput {
/* Defines what fields the caller has initialized - fields not in
* the enum are mandatory.
*/
HB_ShapeFlags flags;
HB_CodePoint *text;
int length; /* total length of text to shape */
int shape_offset; /* start of section to shape */
int shape_length; /* number of code points to shape */
HB_Direction direction;
HB_ShapeScript script;
HB_Language language;
HB_AttributeType *attributes;
int n_attributes;
HB_RunEdge start_type;
HB_RunEdge end_type;
};
struct HB_GlyphItem {
HB_Glyph glyph;
HB_Fixed x_offset;
HB_Fixed y_offset;
HB_Fixed advance;
/* Add kashida information, etc, here */
};
typedef enum {
HB_RESULT_SUCCESS,
HB_RESULT_NO_MEMORY,
HB_SHAPE_RESULT_FAILED
} HB_Result;
/*
* Buffer for output
*/
typedef struct _HB_GlyphBuffer HB_GlyphBuffer;
struct _HB_GlyphBuffer {
int glyph_item_size;
int total_glyphs;
int *log_clusters; /* Uniscribe style */
int cluster_space;
int glyph_space;
void *glyph_buffer;
};
/* Making this self-allocating simplifies writing shapers and
* also keeps things easier for caller. item_size passed in
* must be at least sizeof(HB_GlyphItem) but can be bigger,
* to accomodate application structures that extend HB_GlyphItem.
* The allocated items will be zero-initialized.
*
* (Hack: Harfbuzz could choose to use even a *bigger* item size
* and stick internal information before the public item structure.
* This hack could possibly be used to unify this with HB_Buffer)
*/
HB_GlyphBuffer *hb_glyph_buffer_new (size_t item_size);
void hb_glyph_buffer_clear (HB_GlyphBuffer *buf);
HB_Result hb_glyph_buffer_extend_glyphs (HB_GlyphBuffer *buf, int n_items);
HB_Result hb_glyph_buffer_extend_clusters (HB_GlyphBuffer *buf, int n_clusters);
void hb_glyph_buffer_free (HB_GlyphBuffer *buf);
/* Accessor for a particular glyph */
#define HB_GLYPH_BUFFER_ITEM(buffer, index)
/*
* Main shaping function
*/
HB_Result hb_shape(HB_ShapeInput *input, HB_GlyphBuffer *output);

View File

@ -0,0 +1,36 @@
/*
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
*
* This is part of HarfBuzz, an OpenType Layout engine library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#include "harfbuzz-shaper.cpp"
#include "harfbuzz-indic.cpp"
extern "C" {
#include "harfbuzz-tibetan.c"
#include "harfbuzz-khmer.c"
#include "harfbuzz-hebrew.c"
#include "harfbuzz-arabic.c"
#include "harfbuzz-hangul.c"
#include "harfbuzz-myanmar.c"
#include "harfbuzz-thai.c"
}

View File

@ -0,0 +1,167 @@
/*
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
*
* This is part of HarfBuzz, an OpenType Layout engine library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#ifndef HARFBUZZ_SHAPER_PRIVATE_H
#define HARFBUZZ_SHAPER_PRIVATE_H
HB_BEGIN_HEADER
enum {
C_DOTTED_CIRCLE = 0x25CC
};
typedef enum
{
HB_Combining_BelowLeftAttached = 200,
HB_Combining_BelowAttached = 202,
HB_Combining_BelowRightAttached = 204,
HB_Combining_LeftAttached = 208,
HB_Combining_RightAttached = 210,
HB_Combining_AboveLeftAttached = 212,
HB_Combining_AboveAttached = 214,
HB_Combining_AboveRightAttached = 216,
HB_Combining_BelowLeft = 218,
HB_Combining_Below = 220,
HB_Combining_BelowRight = 222,
HB_Combining_Left = 224,
HB_Combining_Right = 226,
HB_Combining_AboveLeft = 228,
HB_Combining_Above = 230,
HB_Combining_AboveRight = 232,
HB_Combining_DoubleBelow = 233,
HB_Combining_DoubleAbove = 234,
HB_Combining_IotaSubscript = 240
} HB_CombiningClass;
typedef enum {
CcmpProperty = 0x1,
InitProperty = 0x2,
IsolProperty = 0x4,
FinaProperty = 0x8,
MediProperty = 0x10,
RligProperty = 0x20,
CaltProperty = 0x40,
LigaProperty = 0x80,
DligProperty = 0x100,
CswhProperty = 0x200,
MsetProperty = 0x400,
/* used by indic and myanmar shaper */
NuktaProperty = 0x4,
AkhantProperty = 0x8,
RephProperty = 0x10,
PreFormProperty = 0x20,
BelowFormProperty = 0x40,
AboveFormProperty = 0x80,
HalfFormProperty = 0x100,
PostFormProperty = 0x200,
VattuProperty = 0x400,
PreSubstProperty = 0x800,
BelowSubstProperty = 0x1000,
AboveSubstProperty = 0x2000,
PostSubstProperty = 0x4000,
HalantProperty = 0x8000,
CligProperty = 0x10000
} HB_OpenTypeProperty;
/* return true if ok. */
typedef HB_Bool (*HB_ShapeFunction)(HB_ShaperItem *shaper_item);
typedef void (*HB_AttributeFunction)(HB_Script script, const HB_UChar16 *string, hb_uint32 from, hb_uint32 len, HB_CharAttributes *attributes);
typedef struct {
HB_ShapeFunction shape;
HB_AttributeFunction charAttributes;
} HB_ScriptEngine;
extern const HB_ScriptEngine hb_scriptEngines[];
extern HB_Bool HB_BasicShape(HB_ShaperItem *shaper_item);
extern HB_Bool HB_TibetanShape(HB_ShaperItem *shaper_item);
extern HB_Bool HB_HebrewShape(HB_ShaperItem *shaper_item);
extern HB_Bool HB_ArabicShape(HB_ShaperItem *shaper_item);
extern HB_Bool HB_HangulShape(HB_ShaperItem *shaper_item);
extern HB_Bool HB_MyanmarShape(HB_ShaperItem *shaper_item);
extern HB_Bool HB_KhmerShape(HB_ShaperItem *shaper_item);
extern HB_Bool HB_IndicShape(HB_ShaperItem *shaper_item);
extern void HB_TibetanAttributes(HB_Script script, const HB_UChar16 *string, hb_uint32 from, hb_uint32 len, HB_CharAttributes *attributes);
extern void HB_MyanmarAttributes(HB_Script script, const HB_UChar16 *string, hb_uint32 from, hb_uint32 len, HB_CharAttributes *attributes);
extern void HB_KhmerAttributes(HB_Script script, const HB_UChar16 *string, hb_uint32 from, hb_uint32 len, HB_CharAttributes *attributes);
extern void HB_IndicAttributes(HB_Script script, const HB_UChar16 *string, hb_uint32 from, hb_uint32 len, HB_CharAttributes *attributes);
extern void HB_ThaiAttributes(HB_Script script, const HB_UChar16 *string, hb_uint32 from, hb_uint32 len, HB_CharAttributes *attributes);
typedef struct {
hb_uint32 tag;
hb_uint32 property;
} HB_OpenTypeFeature;
#define PositioningProperties 0x80000000
HB_Bool HB_SelectScript(HB_ShaperItem *item, const HB_OpenTypeFeature *features);
HB_Bool HB_OpenTypeShape(HB_ShaperItem *item, const hb_uint32 *properties);
HB_Bool HB_OpenTypePosition(HB_ShaperItem *item, int availableGlyphs, HB_Bool doLogClusters);
void HB_HeuristicPosition(HB_ShaperItem *item);
void HB_HeuristicSetGlyphAttributes(HB_ShaperItem *item);
#define HB_IsControlChar(uc) \
((uc >= 0x200b && uc <= 0x200f /* ZW Space, ZWNJ, ZWJ, LRM and RLM */) \
|| (uc >= 0x2028 && uc <= 0x202f /* LS, PS, LRE, RLE, PDF, LRO, RLO, NNBSP */) \
|| (uc >= 0x206a && uc <= 0x206f /* ISS, ASS, IAFS, AFS, NADS, NODS */))
HB_Bool HB_ConvertStringToGlyphIndices(HB_ShaperItem *shaper_item);
#define HB_GetGlyphAdvances(shaper_item) \
shaper_item->font->klass->getGlyphAdvances(shaper_item->font, \
shaper_item->glyphs, shaper_item->num_glyphs, \
shaper_item->advances, \
shaper_item->face->current_flags);
#define HB_DECLARE_STACKARRAY(Type, Name) \
Type stack##Name[512]; \
Type *Name = stack##Name;
#define HB_INIT_STACKARRAY(Type, Name, Length) \
if ((Length) >= 512) \
Name = (Type *)malloc((Length) * sizeof(Type));
#define HB_STACKARRAY(Type, Name, Length) \
HB_DECLARE_STACKARRAY(Type, Name) \
HB_INIT_STACKARRAY(Type, Name, Length)
#define HB_FREE_STACKARRAY(Name) \
if (stack##Name != Name) \
free(Name);
HB_END_HEADER
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,278 @@
/*
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
*
* This is part of HarfBuzz, an OpenType Layout engine library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#ifndef HARFBUZZ_SHAPER_H
#define HARFBUZZ_SHAPER_H
#include "harfbuzz-global.h"
#include "harfbuzz-gdef.h"
#include "harfbuzz-gpos.h"
#include "harfbuzz-gsub.h"
#include "harfbuzz-external.h"
#include "harfbuzz-stream-private.h"
HB_BEGIN_HEADER
typedef enum {
HB_Script_Common,
HB_Script_Greek,
HB_Script_Cyrillic,
HB_Script_Armenian,
HB_Script_Hebrew,
HB_Script_Arabic,
HB_Script_Syriac,
HB_Script_Thaana,
HB_Script_Devanagari,
HB_Script_Bengali,
HB_Script_Gurmukhi,
HB_Script_Gujarati,
HB_Script_Oriya,
HB_Script_Tamil,
HB_Script_Telugu,
HB_Script_Kannada,
HB_Script_Malayalam,
HB_Script_Sinhala,
HB_Script_Thai,
HB_Script_Lao,
HB_Script_Tibetan,
HB_Script_Myanmar,
HB_Script_Georgian,
HB_Script_Hangul,
HB_Script_Ogham,
HB_Script_Runic,
HB_Script_Khmer,
HB_Script_Nko,
HB_Script_Inherited,
HB_ScriptCount = HB_Script_Inherited
/*
HB_Script_Latin = Common,
HB_Script_Ethiopic = Common,
HB_Script_Cherokee = Common,
HB_Script_CanadianAboriginal = Common,
HB_Script_Mongolian = Common,
HB_Script_Hiragana = Common,
HB_Script_Katakana = Common,
HB_Script_Bopomofo = Common,
HB_Script_Han = Common,
HB_Script_Yi = Common,
HB_Script_OldItalic = Common,
HB_Script_Gothic = Common,
HB_Script_Deseret = Common,
HB_Script_Tagalog = Common,
HB_Script_Hanunoo = Common,
HB_Script_Buhid = Common,
HB_Script_Tagbanwa = Common,
HB_Script_Limbu = Common,
HB_Script_TaiLe = Common,
HB_Script_LinearB = Common,
HB_Script_Ugaritic = Common,
HB_Script_Shavian = Common,
HB_Script_Osmanya = Common,
HB_Script_Cypriot = Common,
HB_Script_Braille = Common,
HB_Script_Buginese = Common,
HB_Script_Coptic = Common,
HB_Script_NewTaiLue = Common,
HB_Script_Glagolitic = Common,
HB_Script_Tifinagh = Common,
HB_Script_SylotiNagri = Common,
HB_Script_OldPersian = Common,
HB_Script_Kharoshthi = Common,
HB_Script_Balinese = Common,
HB_Script_Cuneiform = Common,
HB_Script_Phoenician = Common,
HB_Script_PhagsPa = Common,
*/
} HB_Script;
typedef struct
{
hb_uint32 pos;
hb_uint32 length;
HB_Script script;
hb_uint8 bidiLevel;
} HB_ScriptItem;
typedef enum {
HB_NoBreak,
HB_SoftHyphen,
HB_Break,
HB_ForcedBreak
} HB_LineBreakType;
typedef struct {
/*HB_LineBreakType*/ unsigned lineBreakType :2;
/*HB_Bool*/ unsigned whiteSpace :1; /* A unicode whitespace character, except NBSP, ZWNBSP */
/*HB_Bool*/ unsigned charStop :1; /* Valid cursor position (for left/right arrow) */
/*HB_Bool*/ unsigned wordBoundary :1;
/*HB_Bool*/ unsigned sentenceBoundary :1;
unsigned unused :2;
} HB_CharAttributes;
void HB_GetCharAttributes(const HB_UChar16 *string, hb_uint32 stringLength,
const HB_ScriptItem *items, hb_uint32 numItems,
HB_CharAttributes *attributes);
/* requires HB_GetCharAttributes to be called before */
void HB_GetWordBoundaries(const HB_UChar16 *string, hb_uint32 stringLength,
const HB_ScriptItem *items, hb_uint32 numItems,
HB_CharAttributes *attributes);
/* requires HB_GetCharAttributes to be called before */
void HB_GetSentenceBoundaries(const HB_UChar16 *string, hb_uint32 stringLength,
const HB_ScriptItem *items, hb_uint32 numItems,
HB_CharAttributes *attributes);
typedef enum {
HB_LeftToRight = 0,
HB_RightToLeft = 1
} HB_StringToGlyphsFlags;
typedef enum {
HB_ShaperFlag_Default = 0,
HB_ShaperFlag_NoKerning = 1,
HB_ShaperFlag_UseDesignMetrics = 1 << 1,
/* Arabic vowels in some fonts (Times New Roman, at least) have
non-zero advances, when they should be zero. Setting this shaper
flag causes us to zero out the advances for mark glyphs. */
HB_ShaperFlag_ForceMarksToZeroWidth = 1 << 2
} HB_ShaperFlag;
/*
highest value means highest priority for justification. Justification is done by first inserting kashidas
starting with the highest priority positions, then stretching spaces, afterwards extending inter char
spacing, and last spacing between arabic words.
NoJustification is for example set for arabic where no Kashida can be inserted or for diacritics.
*/
typedef enum {
HB_NoJustification= 0, /* Justification can't be applied after this glyph */
HB_Arabic_Space = 1, /* This glyph represents a space inside arabic text */
HB_Character = 2, /* Inter-character justification point follows this glyph */
HB_Space = 4, /* This glyph represents a blank outside an Arabic run */
HB_Arabic_Normal = 7, /* Normal Middle-Of-Word glyph that connects to the right (begin) */
HB_Arabic_Waw = 8, /* Next character is final form of Waw/Ain/Qaf/Fa */
HB_Arabic_BaRa = 9, /* Next two chars are Ba + Ra/Ya/AlefMaksura */
HB_Arabic_Alef = 10, /* Next character is final form of Alef/Tah/Lam/Kaf/Gaf */
HB_Arabic_HaaDal = 11, /* Next character is final form of Haa/Dal/Taa Marbutah */
HB_Arabic_Seen = 12, /* Initial or Medial form Of Seen/Sad */
HB_Arabic_Kashida = 13 /* Kashida(U+640) in middle of word */
} HB_JustificationClass;
/* This structure is binary compatible with Uniscribe's SCRIPT_VISATTR. Would be nice to keep
* it like that. If this is a problem please tell Trolltech :)
*/
typedef struct {
unsigned justification :4; /* Justification class */
unsigned clusterStart :1; /* First glyph of representation of cluster */
unsigned mark :1; /* needs to be positioned around base char */
unsigned zeroWidth :1; /* ZWJ, ZWNJ etc, with no width */
unsigned dontPrint :1;
unsigned combiningClass :8;
} HB_GlyphAttributes;
typedef struct HB_FaceRec_ {
HB_Bool isSymbolFont;
HB_GDEF gdef;
HB_GSUB gsub;
HB_GPOS gpos;
HB_Bool supported_scripts[HB_ScriptCount];
HB_Buffer buffer;
HB_Script current_script;
int current_flags; /* HB_ShaperFlags */
HB_Bool has_opentype_kerning;
HB_Bool glyphs_substituted;
HB_GlyphAttributes *tmpAttributes;
unsigned int *tmpLogClusters;
int length;
int orig_nglyphs;
} HB_FaceRec;
typedef HB_Error (*HB_GetFontTableFunc)(void *font, HB_Tag tag, HB_Byte *buffer, HB_UInt *length);
HB_Face HB_NewFace(void *font, HB_GetFontTableFunc tableFunc);
void HB_FreeFace(HB_Face face);
typedef struct {
HB_Fixed x, y;
HB_Fixed width, height;
HB_Fixed xOffset, yOffset;
} HB_GlyphMetrics;
typedef enum {
HB_FontAscent
} HB_FontMetric;
typedef struct {
HB_Bool (*convertStringToGlyphIndices)(HB_Font font, const HB_UChar16 *string, hb_uint32 length, HB_Glyph *glyphs, hb_uint32 *numGlyphs, HB_Bool rightToLeft);
void (*getGlyphAdvances)(HB_Font font, const HB_Glyph *glyphs, hb_uint32 numGlyphs, HB_Fixed *advances, int flags /*HB_ShaperFlag*/);
HB_Bool (*canRender)(HB_Font font, const HB_UChar16 *string, hb_uint32 length);
/* implementation needs to make sure to load a scaled glyph, so /no/ FT_LOAD_NO_SCALE */
HB_Error (*getPointInOutline)(HB_Font font, HB_Glyph glyph, int flags /*HB_ShaperFlag*/, hb_uint32 point, HB_Fixed *xpos, HB_Fixed *ypos, hb_uint32 *nPoints);
void (*getGlyphMetrics)(HB_Font font, HB_Glyph glyph, HB_GlyphMetrics *metrics);
HB_Fixed (*getFontMetric)(HB_Font font, HB_FontMetric metric);
} HB_FontClass;
typedef struct HB_Font_ {
const HB_FontClass *klass;
/* Metrics */
HB_UShort x_ppem, y_ppem;
HB_16Dot16 x_scale, y_scale;
void *userData;
} HB_FontRec;
typedef struct HB_ShaperItem_ HB_ShaperItem;
struct HB_ShaperItem_ {
const HB_UChar16 *string; /* input: the Unicode UTF16 text to be shaped */
hb_uint32 stringLength; /* input: the length of the input in 16-bit words */
HB_ScriptItem item; /* input: the current run to be shaped: a run of text all in the same script that is a substring of <string> */
HB_Font font; /* input: the font: scale, units and function pointers supplying glyph indices and metrics */
HB_Face face; /* input: the shaper state; current script, access to the OpenType tables , etc. */
int shaperFlags; /* input (unused) should be set to 0; intended to support flags defined in HB_ShaperFlag */
HB_Bool glyphIndicesPresent; /* input: true if the <glyphs> array contains glyph indices ready to be shaped */
hb_uint32 initialGlyphCount; /* input: if glyphIndicesPresent is true, the number of glyph indices in the <glyphs> array */
hb_uint32 num_glyphs; /* input: capacity of output arrays <glyphs>, <attributes>, <advances>, <offsets>, and <log_clusters>; */
/* output: required capacity (may be larger than actual capacity) */
HB_Glyph *glyphs; /* output: <num_glyphs> indices of shaped glyphs */
HB_GlyphAttributes *attributes; /* output: <num_glyphs> glyph attributes */
HB_Fixed *advances; /* output: <num_glyphs> advances */
HB_FixedPoint *offsets; /* output: <num_glyphs> offsets */
unsigned short *log_clusters; /* output: for each output glyph, the index in the input of the start of its logical cluster */
/* internal */
HB_Bool kerning_applied; /* output: true if kerning was applied by the shaper */
};
HB_Bool HB_ShapeItem(HB_ShaperItem *item);
HB_END_HEADER
#endif

View File

@ -0,0 +1,81 @@
/*
* Copyright (C) 1998-2004 David Turner and Werner Lemberg
* Copyright (C) 2006 Behdad Esfahbod
*
* This is part of HarfBuzz, an OpenType Layout engine library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#ifndef HARFBUZZ_STREAM_PRIVATE_H
#define HARFBUZZ_STREAM_PRIVATE_H
#include "harfbuzz-impl.h"
#include "harfbuzz-stream.h"
HB_BEGIN_HEADER
HB_INTERNAL void
_hb_close_stream( HB_Stream stream );
HB_INTERNAL HB_Int
_hb_stream_pos( HB_Stream stream );
HB_INTERNAL HB_Error
_hb_stream_seek( HB_Stream stream,
HB_UInt pos );
HB_INTERNAL HB_Error
_hb_stream_frame_enter( HB_Stream stream,
HB_UInt size );
HB_INTERNAL void
_hb_stream_frame_exit( HB_Stream stream );
/* convenience macros */
#define SET_ERR(c) ( (error = (c)) != 0 )
#define GOTO_Table(tag) (0)
#define FILE_Pos() _hb_stream_pos( stream )
#define FILE_Seek(pos) SET_ERR( _hb_stream_seek( stream, pos ) )
#define ACCESS_Frame(size) SET_ERR( _hb_stream_frame_enter( stream, size ) )
#define FORGET_Frame() _hb_stream_frame_exit( stream )
#define GET_Byte() (*stream->cursor++)
#define GET_Short() (stream->cursor += 2, (HB_Short)( \
(*(((HB_Byte*)stream->cursor)-2) << 8) | \
*(((HB_Byte*)stream->cursor)-1) \
))
#define GET_Long() (stream->cursor += 4, (HB_Int)( \
(*(((HB_Byte*)stream->cursor)-4) << 24) | \
(*(((HB_Byte*)stream->cursor)-3) << 16) | \
(*(((HB_Byte*)stream->cursor)-2) << 8) | \
*(((HB_Byte*)stream->cursor)-1) \
))
#define GET_Char() ((HB_Char)GET_Byte())
#define GET_UShort() ((HB_UShort)GET_Short())
#define GET_ULong() ((HB_UInt)GET_Long())
#define GET_Tag4() GET_ULong()
HB_END_HEADER
#endif /* HARFBUZZ_STREAM_PRIVATE_H */

View File

@ -0,0 +1,114 @@
/*
* Copyright (C) 2005 David Turner
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
* Copyright (C) 2007 Red Hat, Inc.
*
* This is part of HarfBuzz, an OpenType Layout engine library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Red Hat Author(s): Behdad Esfahbod
*/
#include "harfbuzz-impl.h"
#include "harfbuzz-stream-private.h"
#include <stdlib.h>
#if 0
#include <stdio.h>
#define LOG(x) _hb_log x
static void
_hb_log( const char* format, ... )
{
va_list ap;
va_start( ap, format );
vfprintf( stderr, format, ap );
va_end( ap );
}
#else
#define LOG(x) do {} while (0)
#endif
HB_INTERNAL void
_hb_close_stream( HB_Stream stream )
{
if (!stream)
return;
free(stream->base);
free(stream);
}
HB_INTERNAL HB_Int
_hb_stream_pos( HB_Stream stream )
{
LOG(( "_hb_stream_pos() -> %ld\n", stream->pos ));
return stream->pos;
}
HB_INTERNAL HB_Error
_hb_stream_seek( HB_Stream stream,
HB_UInt pos )
{
HB_Error error = (HB_Error)0;
stream->pos = pos;
if (pos > stream->size)
error = ERR(HB_Err_Read_Error);
LOG(( "_hb_stream_seek(%ld) -> 0x%04X\n", pos, error ));
return error;
}
HB_INTERNAL HB_Error
_hb_stream_frame_enter( HB_Stream stream,
HB_UInt count )
{
HB_Error error = HB_Err_Ok;
/* check new position, watch for overflow */
if (HB_UNLIKELY (stream->pos + count > stream->size ||
stream->pos + count < stream->pos))
{
error = ERR(HB_Err_Read_Error);
goto Exit;
}
/* set cursor */
stream->cursor = stream->base + stream->pos;
stream->pos += count;
Exit:
LOG(( "_hb_stream_frame_enter(%ld) -> 0x%04X\n", count, error ));
return error;
}
HB_INTERNAL void
_hb_stream_frame_exit( HB_Stream stream )
{
stream->cursor = NULL;
LOG(( "_hb_stream_frame_exit()\n" ));
}

View File

@ -0,0 +1,45 @@
/*
* Copyright (C) 2005 David Turner
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
*
* This is part of HarfBuzz, an OpenType Layout engine library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#ifndef HARFBUZZ_STREAM_H
#define HARFBUZZ_STREAM_H
#include "harfbuzz-global.h"
HB_BEGIN_HEADER
typedef struct HB_StreamRec_
{
HB_Byte* base;
HB_UInt size;
HB_UInt pos;
HB_Byte* cursor;
} HB_StreamRec;
HB_END_HEADER
#endif

View File

@ -0,0 +1,87 @@
/*
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
*
* This is part of HarfBuzz, an OpenType Layout engine library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#include "harfbuzz-shaper.h"
#include "harfbuzz-shaper-private.h"
#include "harfbuzz-external.h"
#include <assert.h>
static void thaiWordBreaks(const HB_UChar16 *string, hb_uint32 len, HB_CharAttributes *attributes)
{
typedef int (*th_brk_def)(const char*, int[], int);
static void *thaiCodec = 0;
static th_brk_def th_brk = 0;
char *cstr = 0;
int brp[128];
int *break_positions = brp;
hb_uint32 numbreaks;
hb_uint32 i;
if (!thaiCodec)
thaiCodec = HB_TextCodecForMib(2259);
/* load libthai dynamically */
if (!th_brk && thaiCodec) {
th_brk = (th_brk_def)HB_Library_Resolve("thai", "th_brk");
if (!th_brk)
thaiCodec = 0;
}
if (!th_brk)
return;
cstr = HB_TextCodec_ConvertFromUnicode(thaiCodec, string, len, 0);
if (!cstr)
return;
break_positions = brp;
numbreaks = th_brk(cstr, break_positions, 128);
if (numbreaks > 128) {
break_positions = (int *)malloc(numbreaks * sizeof(int));
numbreaks = th_brk(cstr, break_positions, numbreaks);
}
for (i = 0; i < len; ++i)
attributes[i].lineBreakType = HB_NoBreak;
for (i = 0; i < numbreaks; ++i) {
if (break_positions[i] > 0)
attributes[break_positions[i]-1].lineBreakType = HB_Break;
}
if (break_positions != brp)
free(break_positions);
HB_TextCodec_FreeResult(cstr);
}
void HB_ThaiAttributes(HB_Script script, const HB_UChar16 *text, hb_uint32 from, hb_uint32 len, HB_CharAttributes *attributes)
{
assert(script == HB_Script_Thai);
attributes += from;
thaiWordBreaks(text + from, len, attributes);
}

View File

@ -0,0 +1,274 @@
/*
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
*
* This is part of HarfBuzz, an OpenType Layout engine library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#include "harfbuzz-shaper.h"
#include "harfbuzz-shaper-private.h"
#include <assert.h>
/*
tibetan syllables are of the form:
head position consonant
first sub-joined consonant
....intermediate sub-joined consonants (if any)
last sub-joined consonant
sub-joined vowel (a-chung U+0F71)
standard or compound vowel sign (or 'virama' for devanagari transliteration)
*/
typedef enum {
TibetanOther,
TibetanHeadConsonant,
TibetanSubjoinedConsonant,
TibetanSubjoinedVowel,
TibetanVowel
} TibetanForm;
/* this table starts at U+0f40 */
static const unsigned char tibetanForm[0x80] = {
TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant,
TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant,
TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant,
TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant,
TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant,
TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant,
TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant,
TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant,
TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant,
TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant,
TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant,
TibetanOther, TibetanOther, TibetanOther, TibetanOther,
TibetanOther, TibetanVowel, TibetanVowel, TibetanVowel,
TibetanVowel, TibetanVowel, TibetanVowel, TibetanVowel,
TibetanVowel, TibetanVowel, TibetanVowel, TibetanVowel,
TibetanVowel, TibetanVowel, TibetanVowel, TibetanVowel,
TibetanVowel, TibetanVowel, TibetanVowel, TibetanVowel,
TibetanVowel, TibetanVowel, TibetanVowel, TibetanVowel,
TibetanOther, TibetanOther, TibetanOther, TibetanOther,
TibetanOther, TibetanOther, TibetanOther, TibetanOther,
TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,
TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,
TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,
TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,
TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,
TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,
TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,
TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,
TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,
TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,
TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,
TibetanSubjoinedConsonant, TibetanOther, TibetanOther, TibetanOther
};
#define tibetan_form(c) \
(TibetanForm)tibetanForm[c - 0x0f40]
static const HB_OpenTypeFeature tibetan_features[] = {
{ HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty },
{ HB_MAKE_TAG('a', 'b', 'v', 's'), AboveSubstProperty },
{ HB_MAKE_TAG('b', 'l', 'w', 's'), BelowSubstProperty },
{ HB_MAKE_TAG('c', 'a', 'l', 't'), CaltProperty },
{0, 0}
};
static HB_Bool tibetan_shape_syllable(HB_Bool openType, HB_ShaperItem *item, HB_Bool invalid)
{
hb_uint32 i;
const HB_UChar16 *str = item->string + item->item.pos;
int len = item->item.length;
#ifndef NO_OPENTYPE
const int availableGlyphs = item->num_glyphs;
#endif
HB_Bool haveGlyphs;
HB_STACKARRAY(HB_UChar16, reordered, len + 4);
if (item->num_glyphs < item->item.length + 4) {
item->num_glyphs = item->item.length + 4;
return FALSE;
}
if (invalid) {
*reordered = 0x25cc;
memcpy(reordered+1, str, len*sizeof(HB_UChar16));
len++;
str = reordered;
}
haveGlyphs = item->font->klass->convertStringToGlyphIndices(item->font,
str, len,
item->glyphs, &item->num_glyphs,
item->item.bidiLevel % 2);
HB_FREE_STACKARRAY(reordered);
if (!haveGlyphs)
return FALSE;
for (i = 0; i < item->item.length; i++) {
item->attributes[i].mark = FALSE;
item->attributes[i].clusterStart = FALSE;
item->attributes[i].justification = 0;
item->attributes[i].zeroWidth = FALSE;
/* IDEBUG(" %d: %4x", i, str[i]); */
}
/* now we have the syllable in the right order, and can start running it through open type. */
#ifndef NO_OPENTYPE
if (openType) {
HB_OpenTypeShape(item, /*properties*/0);
if (!HB_OpenTypePosition(item, availableGlyphs, /*doLogClusters*/FALSE))
return FALSE;
} else {
HB_HeuristicPosition(item);
}
#endif
item->attributes[0].clusterStart = TRUE;
return TRUE;
}
static int tibetan_nextSyllableBoundary(const HB_UChar16 *s, int start, int end, HB_Bool *invalid)
{
const HB_UChar16 *uc = s + start;
int pos = 0;
TibetanForm state = tibetan_form(*uc);
/* qDebug("state[%d]=%d (uc=%4x)", pos, state, uc[pos]);*/
pos++;
if (state != TibetanHeadConsonant) {
if (state != TibetanOther)
*invalid = TRUE;
goto finish;
}
while (pos < end - start) {
TibetanForm newState = tibetan_form(uc[pos]);
switch(newState) {
case TibetanSubjoinedConsonant:
case TibetanSubjoinedVowel:
if (state != TibetanHeadConsonant &&
state != TibetanSubjoinedConsonant)
goto finish;
state = newState;
break;
case TibetanVowel:
if (state != TibetanHeadConsonant &&
state != TibetanSubjoinedConsonant &&
state != TibetanSubjoinedVowel)
goto finish;
break;
case TibetanOther:
case TibetanHeadConsonant:
goto finish;
}
pos++;
}
finish:
*invalid = FALSE;
return start+pos;
}
HB_Bool HB_TibetanShape(HB_ShaperItem *item)
{
HB_Bool openType = FALSE;
unsigned short *logClusters = item->log_clusters;
HB_ShaperItem syllable = *item;
int first_glyph = 0;
int sstart = item->item.pos;
int end = sstart + item->item.length;
assert(item->item.script == HB_Script_Tibetan);
#ifndef QT_NO_OPENTYPE
openType = HB_SelectScript(item, tibetan_features);
#endif
while (sstart < end) {
HB_Bool invalid;
int i;
int send = tibetan_nextSyllableBoundary(item->string, sstart, end, &invalid);
/* IDEBUG("syllable from %d, length %d, invalid=%s", sstart, send-sstart,
invalid ? "TRUE" : "FALSE"); */
syllable.item.pos = sstart;
syllable.item.length = send-sstart;
syllable.glyphs = item->glyphs + first_glyph;
syllable.attributes = item->attributes + first_glyph;
syllable.offsets = item->offsets + first_glyph;
syllable.advances = item->advances + first_glyph;
syllable.num_glyphs = item->num_glyphs - first_glyph;
if (!tibetan_shape_syllable(openType, &syllable, invalid)) {
item->num_glyphs += syllable.num_glyphs;
return FALSE;
}
/* fix logcluster array */
for (i = sstart; i < send; ++i)
logClusters[i-item->item.pos] = first_glyph;
sstart = send;
first_glyph += syllable.num_glyphs;
}
item->num_glyphs = first_glyph;
return TRUE;
}
void HB_TibetanAttributes(HB_Script script, const HB_UChar16 *text, hb_uint32 from, hb_uint32 len, HB_CharAttributes *attributes)
{
int end = from + len;
const HB_UChar16 *uc = text + from;
hb_uint32 i = 0;
HB_UNUSED(script);
attributes += from;
while (i < len) {
HB_Bool invalid;
hb_uint32 boundary = tibetan_nextSyllableBoundary(text, from+i, end, &invalid) - from;
attributes[i].charStop = TRUE;
if (boundary > len-1) boundary = len;
i++;
while (i < boundary) {
attributes[i].charStop = FALSE;
++uc;
++i;
}
assert(i == boundary);
}
}

32
third_party/harfbuzz/src/harfbuzz.c vendored Normal file
View File

@ -0,0 +1,32 @@
/*
* Copyright (C) 2006 Behdad Esfahbod
*
* This is part of HarfBuzz, an OpenType Layout engine library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#define HB_INTERNAL static
#include "harfbuzz-buffer.c"
#include "harfbuzz-gdef.c"
#include "harfbuzz-gsub.c"
#include "harfbuzz-gpos.c"
#include "harfbuzz-impl.c"
#include "harfbuzz-open.c"
#include "harfbuzz-stream.c"

38
third_party/harfbuzz/src/harfbuzz.h vendored Normal file
View File

@ -0,0 +1,38 @@
/*
* Copyright (C) 1998-2004 David Turner and Werner Lemberg
* Copyright (C) 2006 Behdad Esfahbod
*
* This is part of HarfBuzz, an OpenType Layout engine library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#ifndef HARFBUZZ_H
#define HARFBUZZ_H
#include "harfbuzz-external.h"
#include "harfbuzz-global.h"
#include "harfbuzz-buffer.h"
#include "harfbuzz-gdef.h"
#include "harfbuzz-gsub.h"
#include "harfbuzz-gpos.h"
#include "harfbuzz-open.h"
#include "harfbuzz-shaper.h"
#endif /* HARFBUZZ_OPEN_H */

View File

@ -0,0 +1,7 @@
SUBDIRS =
if QT
SUBDIRS += linebreaking shaping
endif

View File

@ -0,0 +1,4 @@
.deps
linebreaking
*.moc
*.o

View File

@ -0,0 +1,12 @@
check_PROGRAMS = linebreaking
linebreaking_SOURCES = main.cpp harfbuzz-qt.cpp
linebreaking_LDADD = $(QT_GUI_LIBS) $(QT_QTEST_LIBS) ../../src/libharfbuzz-1.la
main.o: main.moc
main.moc: $(srcdir)/main.cpp
$(QT_MOC) -o main.moc $(srcdir)/main.cpp
INCLUDES = -I$(top_srcdir)/src $(FREETYPE_CFLAGS) $(QT_GUI_CFLAGS) $(QT_QTEST_CFLAGS)

View File

@ -0,0 +1,108 @@
/*
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
*
* This is part of HarfBuzz, an OpenType Layout engine library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#include <harfbuzz-external.h>
#include <Qt/private/qunicodetables_p.h>
#include <QLibrary>
#include <QTextCodec>
extern "C" {
HB_LineBreakClass HB_GetLineBreakClass(HB_UChar32 ch)
{
#if QT_VERSION >= 0x040300
return (HB_LineBreakClass)QUnicodeTables::lineBreakClass(ch);
#else
#error "This test currently requires Qt >= 4.3"
#endif
}
void HB_GetUnicodeCharProperties(HB_UChar32 ch, HB_CharCategory *category, int *combiningClass)
{
*category = (HB_CharCategory)QChar::category(ch);
*combiningClass = QChar::combiningClass(ch);
}
HB_CharCategory HB_GetUnicodeCharCategory(HB_UChar32 ch)
{
return (HB_CharCategory)QChar::category(ch);
}
int HB_GetUnicodeCharCombiningClass(HB_UChar32 ch)
{
return QChar::combiningClass(ch);
}
HB_UChar16 HB_GetMirroredChar(HB_UChar16 ch)
{
return QChar::mirroredChar(ch);
}
HB_WordClass HB_GetWordClass(HB_UChar32 ch)
{
const QUnicodeTables::Properties *prop = QUnicodeTables::properties(ch);
return (HB_WordClass) prop->wordBreak;
}
HB_SentenceClass HB_GetSentenceClass(HB_UChar32 ch)
{
const QUnicodeTables::Properties *prop = QUnicodeTables::properties(ch);
return (HB_SentenceClass) prop->sentenceBreak;
}
void HB_GetGraphemeAndLineBreakClass(HB_UChar32 ch, HB_GraphemeClass *grapheme, HB_LineBreakClass *lineBreak)
{
const QUnicodeTables::Properties *prop = QUnicodeTables::properties(ch);
*grapheme = (HB_GraphemeClass) prop->graphemeBreak;
*lineBreak = (HB_LineBreakClass) prop->line_break_class;
}
void *HB_Library_Resolve(const char *library, const char *symbol)
{
return QLibrary::resolve(library, symbol);
}
void *HB_TextCodecForMib(int mib)
{
return QTextCodec::codecForMib(mib);
}
char *HB_TextCodec_ConvertFromUnicode(void *codec, const HB_UChar16 *unicode, hb_uint32 length, hb_uint32 *outputLength)
{
QByteArray data = reinterpret_cast<QTextCodec *>(codec)->fromUnicode((const QChar *)unicode, length);
// ### suboptimal
char *output = (char *)malloc(data.length() + 1);
memcpy(output, data.constData(), data.length() + 1);
if (outputLength)
*outputLength = data.length();
return output;
}
void HB_TextCodec_FreeResult(char *string)
{
free(string);
}
}

View File

@ -0,0 +1,230 @@
/*
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
*
* This is part of HarfBuzz, an OpenType Layout engine library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
/*
!!!!!! Warning !!!!!
Please don't save this file in emacs. It contains utf8 text sequences emacs will
silently convert to a series of question marks.
*/
#include <QtTest/QtTest>
#include <QtCore/qdebug.h>
#include <harfbuzz-shaper.h>
static QVector<HB_CharAttributes> getCharAttributes(const QString &str, HB_Script script = HB_Script_Common)
{
QVector<HB_CharAttributes> attrs(str.length());
HB_ScriptItem item;
item.pos = 0;
item.length = str.length();
item.script = script;
HB_GetCharAttributes(str.utf16(), str.length(),
&item, 1,
attrs.data());
return attrs;
}
class tst_CharAttributes : public QObject
{
Q_OBJECT
public:
tst_CharAttributes();
virtual ~tst_CharAttributes();
public slots:
void init();
void cleanup();
private slots:
void lineBreaking();
void charWordStopOnLineSeparator();
void charStopForSurrogatePairs();
void thaiWordBreak();
};
tst_CharAttributes::tst_CharAttributes()
{
}
tst_CharAttributes::~tst_CharAttributes()
{
}
void tst_CharAttributes::init()
{
}
void tst_CharAttributes::cleanup()
{
}
void tst_CharAttributes::lineBreaking()
{
struct Breaks {
const char *utf8;
uchar breaks[32];
};
Breaks brks[] = {
{ "11", { false, 0xff } },
{ "aa", { false, 0xff } },
{ "++", { false, 0xff } },
{ "--", { false, 0xff } },
{ "((", { false, 0xff } },
{ "))", { false, 0xff } },
{ "..", { false, 0xff } },
{ "\"\"", { false, 0xff } },
{ "$$", { false, 0xff } },
{ "!!", { false, 0xff } },
{ "??", { false, 0xff } },
{ ",,", { false, 0xff } },
{ ")()", { true, false, 0xff } },
{ "?!?", { false, false, 0xff } },
{ ".,.", { false, false, 0xff } },
{ "+-+", { false, false, 0xff } },
{ "+=+", { false, false, 0xff } },
{ "+(+", { false, false, 0xff } },
{ "+)+", { false, false, 0xff } },
{ "a b", { false, true, 0xff } },
{ "a(b", { false, false, 0xff } },
{ "a)b", { false, false, 0xff } },
{ "a-b", { false, true, 0xff } },
{ "a.b", { false, false, 0xff } },
{ "a+b", { false, false, 0xff } },
{ "a?b", { false, false, 0xff } },
{ "a!b", { false, false, 0xff } },
{ "a$b", { false, false, 0xff } },
{ "a,b", { false, false, 0xff } },
{ "a/b", { false, false, 0xff } },
{ "1/2", { false, false, 0xff } },
{ "./.", { false, false, 0xff } },
{ ",/,", { false, false, 0xff } },
{ "!/!", { false, false, 0xff } },
{ "\\/\\", { false, false, 0xff } },
{ "1 2", { false, true, 0xff } },
{ "1(2", { false, false, 0xff } },
{ "1)2", { false, false, 0xff } },
{ "1-2", { false, false, 0xff } },
{ "1.2", { false, false, 0xff } },
{ "1+2", { false, false, 0xff } },
{ "1?2", { false, true, 0xff } },
{ "1!2", { false, true, 0xff } },
{ "1$2", { false, false, 0xff } },
{ "1,2", { false, false, 0xff } },
{ "1/2", { false, false, 0xff } },
{ "\330\260\331\216\331\204\331\220\331\203\331\216", { false, false, false, false, false, 0xff } },
{ "\330\247\331\204\331\205 \330\247\331\204\331\205", { false, false, false, true, false, false, 0xff } },
{ "1#2", { false, false, 0xff } },
{ "!#!", { false, false, 0xff } },
{ 0, {} }
};
Breaks *b = brks;
while (b->utf8) {
QString str = QString::fromUtf8(b->utf8);
QVector<HB_CharAttributes> attrs = getCharAttributes(str);
int i;
for (i = 0; i < (int)str.length() - 1; ++i) {
QVERIFY(b->breaks[i] != 0xff);
if ( (attrs[i].lineBreakType != HB_NoBreak) != (bool)b->breaks[i] ) {
qDebug("test case \"%s\" failed at char %d; break type: %d", b->utf8, i, attrs[i].lineBreakType);
QCOMPARE( (attrs[i].lineBreakType != HB_NoBreak), (bool)b->breaks[i] );
}
}
QVERIFY(attrs[i].lineBreakType == HB_ForcedBreak);
QCOMPARE(b->breaks[i], (uchar)0xff);
++b;
}
}
void tst_CharAttributes::charWordStopOnLineSeparator()
{
const QChar lineSeparator(QChar::LineSeparator);
QString txt;
txt.append(lineSeparator);
txt.append(lineSeparator);
QVector<HB_CharAttributes> attrs = getCharAttributes(txt);
QVERIFY(attrs[1].charStop);
}
void tst_CharAttributes::charStopForSurrogatePairs()
{
QString txt;
txt.append("a");
txt.append(0xd87e);
txt.append(0xdc25);
txt.append("b");
QVector<HB_CharAttributes> attrs = getCharAttributes(txt);
QVERIFY(attrs[0].charStop);
QVERIFY(attrs[1].charStop);
QVERIFY(!attrs[2].charStop);
QVERIFY(attrs[3].charStop);
}
void tst_CharAttributes::thaiWordBreak()
{
// สวัสดีครับ นี่เป็นการงทดสอบตัวเอ
QTextCodec *codec = QTextCodec::codecForMib(2259);
QString txt = codec->toUnicode(QByteArray("\xca\xc7\xd1\xca\xb4\xd5\xa4\xc3\xd1\xba\x20\xb9\xd5\xe8\xe0\xbb\xe7\xb9\xa1\xd2\xc3\xb7\xb4\xca\xcd\xba\xb5\xd1\xc7\xe0\xcd\xa7"));
QCOMPARE(txt.length(), 32);
QVector<HB_CharAttributes> attrs = getCharAttributes(txt, HB_Script_Thai);
QVERIFY(attrs[0].lineBreakType == HB_NoBreak);
QVERIFY(attrs[1].lineBreakType == HB_NoBreak);
QVERIFY(attrs[2].lineBreakType == HB_NoBreak);
QVERIFY(attrs[3].lineBreakType == HB_NoBreak);
QVERIFY(attrs[4].lineBreakType == HB_NoBreak);
QVERIFY(attrs[5].lineBreakType == HB_Break);
QVERIFY(attrs[6].lineBreakType == HB_NoBreak);
QVERIFY(attrs[7].lineBreakType == HB_NoBreak);
QVERIFY(attrs[8].lineBreakType == HB_NoBreak);
QVERIFY(attrs[9].lineBreakType == HB_NoBreak);
QVERIFY(attrs[10].lineBreakType == HB_Break);
QVERIFY(attrs[11].lineBreakType == HB_NoBreak);
QVERIFY(attrs[12].lineBreakType == HB_NoBreak);
QVERIFY(attrs[13].lineBreakType == HB_Break);
QVERIFY(attrs[14].lineBreakType == HB_NoBreak);
QVERIFY(attrs[15].lineBreakType == HB_NoBreak);
QVERIFY(attrs[16].lineBreakType == HB_NoBreak);
QVERIFY(attrs[17].lineBreakType == HB_Break);
QVERIFY(attrs[18].lineBreakType == HB_NoBreak);
QVERIFY(attrs[19].lineBreakType == HB_NoBreak);
QVERIFY(attrs[20].lineBreakType == HB_Break);
QVERIFY(attrs[21].lineBreakType == HB_NoBreak);
QVERIFY(attrs[22].lineBreakType == HB_NoBreak);
QVERIFY(attrs[23].lineBreakType == HB_NoBreak);
QVERIFY(attrs[24].lineBreakType == HB_NoBreak);
QVERIFY(attrs[25].lineBreakType == HB_Break);
QVERIFY(attrs[26].lineBreakType == HB_NoBreak);
for (int i = 27; i < 32; ++i)
QVERIFY(attrs[i].lineBreakType == HB_NoBreak);
}
QTEST_MAIN(tst_CharAttributes)
#include "main.moc"

View File

@ -0,0 +1,2 @@
harfbuzz-test-fonts-0.1.tar.bz2
fonts

View File

@ -0,0 +1,14 @@
check_PROGRAMS = shaping
shaping_SOURCES = main.cpp ../linebreaking/harfbuzz-qt.cpp
shaping_LDADD = $(QT_GUI_LIBS) $(QT_QTEST_LIBS) ../../src/libharfbuzz-1.la
main.o: main.moc
main.moc: $(srcdir)/main.cpp
$(QT_MOC) -o main.moc $(srcdir)/main.cpp
INCLUDES = -I$(top_srcdir)/src $(FREETYPE_CFLAGS) $(QT_GUI_CFLAGS) $(QT_QTEST_CFLAGS)
AM_CPPFLAGS = -DQT_GUI_LIB -DSRCDIR=\"$(srcdir)\"

View File

@ -0,0 +1,9 @@
These shaper tests need some specific TrueType fonts. You can get a package of
them from
http://people.freedesktop.org/~hausmann/harfbuzz-test-fonts-0.1.tar.bz2
In addition you may need two fonts (Mangal and Tunga) from Microsoft Windows
for some of the test cases. These fonts are not freely redistributable.
The test program looks for them in a fonts/ subdirectory.

File diff suppressed because it is too large Load Diff