aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorclaireho <chinglanho@gmail.com>2010-11-11 10:57:27 -0800
committerclaireho <chinglanho@gmail.com>2010-11-11 12:05:43 -0800
commit57e6107a9d66a9a97b146def0ef38c010f954be6 (patch)
tree86ab62c1cf63753518628c5c96decaccb87ade16
parentbc5032157caeb9e460d05f147c010fe9df851f4c (diff)
downloadharfbuzz-57e6107a9d66a9a97b146def0ef38c010f954be6.tar.gz
Upgrade to latest Harfbuzz library and add CleanSpec.mk.
The Harfbuzz version includes: 1. More bug fixings. 2. Memory reduction - 50 % less. 3. Shapping for Greek. Note: The following files include the bug fixings from Chrome: a. contrib/harfbuzz-unicode.c b. src/harfbuzz-shaper.cpp Change-Id: I9f5fc16b01c85fb54bbd66c6f9f5526e68e7d01a
-rw-r--r--Android.mk3
-rw-r--r--CleanSpec.mk50
-rwxr-xr-xcontrib/harfbuzz-unicode.c19
-rwxr-xr-xsrc/Makefile.am3
-rwxr-xr-xsrc/harfbuzz-arabic.c1
-rwxr-xr-xsrc/harfbuzz-buffer.h16
-rwxr-xr-xsrc/harfbuzz-dump.c10
-rwxr-xr-xsrc/harfbuzz-external.h6
-rwxr-xr-xsrc/harfbuzz-gdef-private.h25
-rwxr-xr-xsrc/harfbuzz-gdef.c6
-rwxr-xr-xsrc/harfbuzz-gdef.h21
-rwxr-xr-xsrc/harfbuzz-global.h4
-rwxr-xr-xsrc/harfbuzz-gpos-private.h67
-rwxr-xr-xsrc/harfbuzz-gpos.c190
-rwxr-xr-xsrc/harfbuzz-gpos.h6
-rw-r--r--src/harfbuzz-greek.c447
-rwxr-xr-xsrc/harfbuzz-gsub-private.h151
-rwxr-xr-xsrc/harfbuzz-gsub.h23
-rwxr-xr-xsrc/harfbuzz-hangul.c2
-rwxr-xr-xsrc/harfbuzz-hebrew.c8
-rwxr-xr-xsrc/harfbuzz-indic.cpp23
-rwxr-xr-xsrc/harfbuzz-myanmar.c4
-rwxr-xr-xsrc/harfbuzz-open-private.h2
-rwxr-xr-xsrc/harfbuzz-open.c31
-rwxr-xr-xsrc/harfbuzz-open.h48
-rwxr-xr-xsrc/harfbuzz-shaper-all.cpp1
-rwxr-xr-xsrc/harfbuzz-shaper-private.h56
-rwxr-xr-xsrc/harfbuzz-shaper.cpp40
-rwxr-xr-xsrc/harfbuzz-shaper.h50
-rwxr-xr-xsrc/harfbuzz-stream.h10
-rwxr-xr-xsrc/harfbuzz-thai.c66
31 files changed, 1020 insertions, 369 deletions
diff --git a/Android.mk b/Android.mk
index 2fbfc7a..fab7288 100644
--- a/Android.mk
+++ b/Android.mk
@@ -47,7 +47,8 @@ LOCAL_SRC_FILES:= \
src/harfbuzz-arabic.c \
src/harfbuzz-hangul.c \
src/harfbuzz-myanmar.c \
- src/harfbuzz-thai.c
+ src/harfbuzz-thai.c \
+ src/harfbuzz-greek.c
LOCAL_SHARED_LIBRARIES := \
libcutils \
diff --git a/CleanSpec.mk b/CleanSpec.mk
new file mode 100644
index 0000000..c6c9849
--- /dev/null
+++ b/CleanSpec.mk
@@ -0,0 +1,50 @@
+# Copyright (C) 2007 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# If you don't need to do a full clean build but would like to touch
+# a file or delete some intermediate files, add a clean step to the end
+# of the list. These steps will only be run once, if they haven't been
+# run before.
+#
+# E.g.:
+# $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
+# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
+#
+# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
+# files that are missing or have been moved.
+#
+# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
+# Use $(OUT_DIR) to refer to the "out" directory.
+#
+# If you need to re-do something that's already mentioned, just copy
+# the command and add it to the bottom of the list. E.g., if a change
+# that you made last week required touching a file and a change you
+# made today requires touching the same file, just copy the old
+# touch step and add it to the end of the list.
+#
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
+
+# For example:
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
+#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
+#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libharfbuzz_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libharfbuzz_intermediates)
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
diff --git a/contrib/harfbuzz-unicode.c b/contrib/harfbuzz-unicode.c
index 7bf8967..2953a85 100755
--- a/contrib/harfbuzz-unicode.c
+++ b/contrib/harfbuzz-unicode.c
@@ -268,24 +268,7 @@ HB_GetMirroredChar(HB_UChar16 ch) {
}
void *
-HB_Library_Resolve(const char *library, const char *symbol) {
+HB_Library_Resolve(const char *library, int version, 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();
-}
diff --git a/src/Makefile.am b/src/Makefile.am
index 2b0fb1d..51d0652 100755
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -12,7 +12,8 @@ MAINSOURCES = \
harfbuzz-impl.c \
harfbuzz-open.c \
harfbuzz-shaper.cpp \
- harfbuzz-tibetan.c \
+ harfbuzz-greek.c \
+ harfbuzz-tibetan.c \
harfbuzz-khmer.c \
harfbuzz-indic.cpp \
harfbuzz-hebrew.c \
diff --git a/src/harfbuzz-arabic.c b/src/harfbuzz-arabic.c
index ce2ca6c..3837087 100755
--- a/src/harfbuzz-arabic.c
+++ b/src/harfbuzz-arabic.c
@@ -1107,7 +1107,6 @@ HB_Bool HB_ArabicShape(HB_ShaperItem *item)
assert(item->item.script == HB_Script_Arabic || item->item.script == HB_Script_Syriac
|| item->item.script == HB_Script_Nko);
- item->shaperFlags |= HB_ShaperFlag_ForceMarksToZeroWidth;
#ifndef NO_OPENTYPE
if (HB_SelectScript(item, item->item.script == HB_Script_Arabic ? arabic_features : syriac_features)) {
diff --git a/src/harfbuzz-buffer.h b/src/harfbuzz-buffer.h
index b134407..0d7c2c2 100755
--- a/src/harfbuzz-buffer.h
+++ b/src/harfbuzz-buffer.h
@@ -32,6 +32,10 @@
HB_BEGIN_HEADER
+#ifdef HB_USE_PACKED_STRUCTS
+#pragma pack(push, 1)
+#endif
+
typedef struct HB_GlyphItemRec_ {
HB_UInt gindex;
HB_UInt properties;
@@ -48,13 +52,13 @@ typedef struct HB_PositionRec_ {
HB_Fixed y_advance;
HB_UShort back; /* number of glyphs to go back
for drawing current glyph */
+ HB_Short cursive_chain; /* character to which this connects,
+ may be positive or negative; used
+ only internally */
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;
@@ -66,12 +70,12 @@ typedef struct HB_BufferRec_{
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_Bool separate_out;
} HB_BufferRec, *HB_Buffer;
HB_Error
@@ -89,6 +93,10 @@ hb_buffer_add_glyph( HB_Buffer buffer,
HB_UInt properties,
HB_UInt cluster );
+#ifdef HB_USE_PACKED_STRUCTS
+#pragma pack(pop)
+#endif
+
HB_END_HEADER
#endif /* HARFBUZZ_BUFFER_H */
diff --git a/src/harfbuzz-dump.c b/src/harfbuzz-dump.c
index 8c81da1..54d42e9 100755
--- a/src/harfbuzz-dump.c
+++ b/src/harfbuzz-dump.c
@@ -519,13 +519,14 @@ Dump_ValueRecord (HB_ValueRecord *ValueRecord, FILE *stream, int indent, HB_Type
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);
+ RECURSE (Device, Device, &*ValueRecord->DeviceTables[VR_X_PLACEMENT_DEVICE]);
if (value_format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT_DEVICE)
- RECURSE (Device, Device, &ValueRecord->YPlacementDevice);
+ RECURSE (Device, Device, &*ValueRecord->DeviceTables[VR_Y_PLACEMENT_DEVICE]);
if (value_format & HB_GPOS_FORMAT_HAVE_X_ADVANCE_DEVICE)
- RECURSE (Device, Device, &ValueRecord->XAdvanceDevice);
+ RECURSE (Device, Device, &*ValueRecord->DeviceTables[VR_X_ADVANCE_DEVICE]);
if (value_format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE_DEVICE)
- RECURSE (Device, Device, &ValueRecord->YAdvanceDevice);
+ RECURSE (Device, Device, &*ValueRecord->DeviceTables[VR_Y_ADVANCE_DEVICE]);
+#ifdef HB_SUPPORT_MULTIPLE_MASTER
if (value_format & HB_GPOS_FORMAT_HAVE_X_ID_PLACEMENT)
DUMP_FUINT (ValueRecord, XIdPlacement);
if (value_format & HB_GPOS_FORMAT_HAVE_Y_ID_PLACEMENT)
@@ -534,6 +535,7 @@ Dump_ValueRecord (HB_ValueRecord *ValueRecord, FILE *stream, int indent, HB_Type
DUMP_FUINT (ValueRecord, XIdAdvance);
if (value_format & HB_GPOS_FORMAT_HAVE_Y_ID_ADVANCE)
DUMP_FUINT (ValueRecord, XIdAdvance);
+#endif
}
static void
diff --git a/src/harfbuzz-external.h b/src/harfbuzz-external.h
index 760749b..7644f0d 100755
--- a/src/harfbuzz-external.h
+++ b/src/harfbuzz-external.h
@@ -146,11 +146,7 @@ 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 *);
+void *HB_Library_Resolve(const char *library, int version, const char *symbol);
HB_END_HEADER
diff --git a/src/harfbuzz-gdef-private.h b/src/harfbuzz-gdef-private.h
index da06b6f..2a6d958 100755
--- a/src/harfbuzz-gdef-private.h
+++ b/src/harfbuzz-gdef-private.h
@@ -34,12 +34,16 @@
HB_BEGIN_HEADER
+#ifdef HB_USE_PACKED_STRUCTS
+#pragma pack(push, 1)
+#endif
+
/* Attachment related structures */
struct HB_AttachPoint_
{
- HB_UShort PointCount; /* size of the PointIndex array */
HB_UShort* PointIndex; /* array of contour points */
+ HB_UShort PointCount; /* size of the PointIndex array */
};
/* Ligature Caret related structures */
@@ -62,32 +66,36 @@ typedef struct HB_CaretValueFormat2_ HB_CaretValueFormat2;
struct HB_CaretValueFormat3_
{
+ HB_Device* Device; /* Device table for x or y value */
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;
+#ifdef HB_SUPPORT_MULTIPLE_MASTER
struct HB_CaretValueFormat4_
{
HB_UShort IdCaretValue; /* metric ID */
};
typedef struct HB_CaretValueFormat4_ HB_CaretValueFormat4;
+#endif
struct HB_CaretValue_
{
- HB_UShort CaretValueFormat; /* 1, 2, 3, or 4 */
-
union
{
HB_CaretValueFormat1 cvf1;
HB_CaretValueFormat2 cvf2;
HB_CaretValueFormat3 cvf3;
+#ifdef HB_SUPPORT_MULTIPLE_MASTER
HB_CaretValueFormat4 cvf4;
+#endif
} cvf;
+
+ HB_Byte CaretValueFormat; /* 1, 2, 3, or 4 */
};
typedef struct HB_CaretValue_ HB_CaretValue;
@@ -95,10 +103,9 @@ 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_UShort CaretCount; /* number of caret values */
+ HB_Bool loaded;
};
@@ -119,6 +126,10 @@ _HB_GDEF_LoadMarkAttachClassDef_From_LookupFlags( HB_GDEFHeader* gdef,
HB_Lookup* lo,
HB_UShort num_lookups );
+#ifdef HB_USE_PACKED_STRUCTS
+#pragma pack(pop)
+#endif
+
HB_END_HEADER
#endif /* HARFBUZZ_GDEF_PRIVATE_H */
diff --git a/src/harfbuzz-gdef.c b/src/harfbuzz-gdef.c
index ff3a1f4..966b167 100755
--- a/src/harfbuzz-gdef.c
+++ b/src/harfbuzz-gdef.c
@@ -442,7 +442,11 @@ static HB_Error Load_CaretValue( HB_CaretValue* cv,
if ( ACCESS_Frame( 2L ) )
return error;
+#ifdef HB_SUPPORT_MULTIPLE_MASTER
cv->cvf.cvf4.IdCaretValue = GET_UShort();
+#else
+ (void) GET_UShort();
+#endif
FORGET_Frame();
break;
@@ -458,7 +462,7 @@ static HB_Error Load_CaretValue( HB_CaretValue* cv,
static void Free_CaretValue( HB_CaretValue* cv)
{
if ( cv->CaretValueFormat == 3 )
- _HB_OPEN_Free_Device( &cv->cvf.cvf3.Device );
+ _HB_OPEN_Free_Device( cv->cvf.cvf3.Device );
}
diff --git a/src/harfbuzz-gdef.h b/src/harfbuzz-gdef.h
index b6dcadc..f9a03dd 100755
--- a/src/harfbuzz-gdef.h
+++ b/src/harfbuzz-gdef.h
@@ -31,6 +31,10 @@
HB_BEGIN_HEADER
+#ifdef HB_USE_PACKED_STRUCTS
+#pragma pack(push, 1)
+#endif
+
/* GDEF glyph properties. Note that HB_GDEF_COMPONENT has no corresponding
* flag in the LookupFlag field. */
#define HB_GDEF_BASE_GLYPH 0x0002
@@ -44,12 +48,11 @@ typedef struct HB_AttachPoint_ HB_AttachPoint;
struct HB_AttachList_
{
- HB_Bool loaded;
-
+ HB_AttachPoint* AttachPoint; /* array of AttachPoint tables */
HB_Coverage Coverage; /* Coverage table */
HB_UShort GlyphCount; /* number of glyphs with
attachments */
- HB_AttachPoint* AttachPoint; /* array of AttachPoint tables */
+ HB_Bool loaded;
};
typedef struct HB_AttachList_ HB_AttachList;
@@ -58,11 +61,10 @@ typedef struct HB_LigGlyph_ HB_LigGlyph;
struct HB_LigCaretList_
{
- HB_Bool loaded;
-
+ HB_LigGlyph* LigGlyph; /* array of LigGlyph tables */
HB_Coverage Coverage; /* Coverage table */
HB_UShort LigGlyphCount; /* number of ligature glyphs */
- HB_LigGlyph* LigGlyph; /* array of LigGlyph tables */
+ HB_Bool loaded;
};
typedef struct HB_LigCaretList_ HB_LigCaretList;
@@ -91,18 +93,18 @@ typedef struct HB_LigCaretList_ HB_LigCaretList;
struct HB_GDEFHeader_
{
+ HB_UShort** NewGlyphClasses;
HB_UInt offset;
+ HB_UInt MarkAttachClassDef_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;
@@ -129,6 +131,9 @@ HB_Error HB_GDEF_Build_ClassDefinition( HB_GDEFHeader* gdef,
HB_UShort* glyph_array,
HB_UShort* class_array );
+#ifdef HB_USE_PACKED_STRUCTS
+#pragma pack(pop)
+#endif
HB_END_HEADER
diff --git a/src/harfbuzz-global.h b/src/harfbuzz-global.h
index d4e6b46..bccd6a2 100755
--- a/src/harfbuzz-global.h
+++ b/src/harfbuzz-global.h
@@ -39,6 +39,10 @@
#define HB_END_HEADER /* nothing */
#endif
+#if defined(__GNUC__) || defined(_MSC_VER)
+#define HB_USE_PACKED_STRUCTS
+#endif
+
HB_BEGIN_HEADER
#ifndef FALSE
diff --git a/src/harfbuzz-gpos-private.h b/src/harfbuzz-gpos-private.h
index 4110700..39f3159 100755
--- a/src/harfbuzz-gpos-private.h
+++ b/src/harfbuzz-gpos-private.h
@@ -32,9 +32,17 @@
HB_BEGIN_HEADER
+#ifdef HB_USE_PACKED_STRUCTS
+#pragma pack(push, 1)
+#endif
/* shared tables */
+#define VR_X_PLACEMENT_DEVICE 0
+#define VR_Y_PLACEMENT_DEVICE 1
+#define VR_X_ADVANCE_DEVICE 2
+#define VR_Y_ADVANCE_DEVICE 3
+
struct HB_ValueRecord_
{
HB_Short XPlacement; /* horizontal adjustment for
@@ -45,18 +53,16 @@ struct HB_ValueRecord_
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_Device** DeviceTables; /* device tables for placement
+ and advance */
+
+#ifdef HB_SUPPORT_MULTIPLE_MASTER
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 */
+#endif
};
typedef struct HB_ValueRecord_ HB_ValueRecord;
@@ -65,6 +71,8 @@ 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_DEVICE_TABLES 0x00F0
+
#define HB_GPOS_FORMAT_HAVE_X_PLACEMENT 0x0001
#define HB_GPOS_FORMAT_HAVE_Y_PLACEMENT 0x0002
#define HB_GPOS_FORMAT_HAVE_X_ADVANCE 0x0004
@@ -97,18 +105,20 @@ struct HB_AnchorFormat2_
typedef struct HB_AnchorFormat2_ HB_AnchorFormat2;
+#define AF3_X_DEVICE_TABLE 0
+#define AF3_Y_DEVICE_TABLE 1
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 */
+ HB_Device** DeviceTables; /* device tables for coordinates */
};
typedef struct HB_AnchorFormat3_ HB_AnchorFormat3;
+#ifdef HB_SUPPORT_MULTIPLE_MASTER
struct HB_AnchorFormat4_
{
HB_UShort XIdAnchor; /* horizontal metric ID */
@@ -116,11 +126,12 @@ struct HB_AnchorFormat4_
};
typedef struct HB_AnchorFormat4_ HB_AnchorFormat4;
+#endif
struct HB_Anchor_
{
- HB_UShort PosFormat; /* 1, 2, 3, or 4 -- 0 indicates
+ HB_Byte PosFormat; /* 1, 2, 3, or 4 -- 0 indicates
that there is no Anchor table */
union
@@ -128,7 +139,9 @@ struct HB_Anchor_
HB_AnchorFormat1 af1;
HB_AnchorFormat2 af2;
HB_AnchorFormat3 af3;
+#ifdef HB_SUPPORT_MULTIPLE_MASTER
HB_AnchorFormat4 af4;
+#endif
} af;
};
@@ -175,7 +188,7 @@ typedef struct HB_SinglePosFormat2_ HB_SinglePosFormat2;
struct HB_SinglePos_
{
- HB_UShort PosFormat; /* 1 or 2 */
+ HB_Byte PosFormat; /* 1 or 2 */
HB_Coverage Coverage; /* Coverage table */
HB_UShort ValueFormat; /* format of ValueRecord table */
@@ -255,7 +268,7 @@ typedef struct HB_PairPosFormat2_ HB_PairPosFormat2;
struct HB_PairPos_
{
- HB_UShort PosFormat; /* 1 or 2 */
+ HB_Byte PosFormat; /* 1 or 2 */
HB_Coverage Coverage; /* Coverage table */
HB_UShort ValueFormat1; /* format of ValueRecord table
for first glyph */
@@ -507,7 +520,7 @@ typedef struct HB_ContextPosFormat3_ HB_ContextPosFormat3;
struct HB_ContextPos_
{
- HB_UShort PosFormat; /* 1, 2, or 3 */
+ HB_Byte PosFormat; /* 1, 2, or 3 */
union
{
@@ -524,18 +537,18 @@ typedef struct HB_ContextPos_ HB_ContextPos;
struct HB_ChainPosRule_
{
+ HB_UShort* Backtrack; /* array of backtrack glyph IDs */
+ HB_UShort* Input; /* array of input glyph IDs */
+ HB_UShort* Lookahead; /* array of lookahead glyph IDs */
+ HB_PosLookupRecord* PosLookupRecord;
+ /* array of PosLookupRecords */
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;
@@ -565,20 +578,20 @@ typedef struct HB_ChainContextPosFormat1_ HB_ChainContextPosFormat1;
struct HB_ChainPosClassRule_
{
+ HB_UShort* Backtrack; /* array of backtrack classes */
+ HB_UShort* Input; /* array of context classes */
+ HB_UShort* Lookahead; /* array of lookahead classes */
+ HB_PosLookupRecord* PosLookupRecord;
+ /* array of substitution lookups */
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;
@@ -656,7 +669,7 @@ typedef struct HB_ChainContextPosFormat3_ HB_ChainContextPosFormat3;
struct HB_ChainContextPos_
{
- HB_UShort PosFormat; /* 1, 2, or 3 */
+ HB_Byte PosFormat; /* 1, 2, or 3 */
union
{
@@ -707,6 +720,10 @@ HB_INTERNAL void
_HB_GPOS_Free_SubTable( HB_GPOS_SubTable* st,
HB_UShort lookup_type );
+#ifdef HB_USE_PACKED_STRUCTS
+#pragma pack(pop)
+#endif
+
HB_END_HEADER
#endif /* HARFBUZZ_GPOS_PRIVATE_H */
diff --git a/src/harfbuzz-gpos.c b/src/harfbuzz-gpos.c
index 356dc01..a216005 100755
--- a/src/harfbuzz-gpos.c
+++ b/src/harfbuzz-gpos.c
@@ -57,6 +57,7 @@ static HB_Error GPOS_Do_Glyph_Lookup( GPOS_Instance* gpi,
+#ifdef HB_SUPPORT_MULTIPLE_MASTER
/* the client application must replace this with something more
meaningful if multiple master fonts are to be supported. */
@@ -71,6 +72,7 @@ static HB_Error default_mmfunc( HB_Font font,
HB_UNUSED(data);
return ERR(HB_Err_Not_Covered); /* ERR() call intended */
}
+#endif
@@ -97,7 +99,9 @@ HB_Error HB_Load_GPOS_Table( HB_Stream stream,
if ( ALLOC ( gpos, sizeof( *gpos ) ) )
return error;
+#ifdef HB_SUPPORT_MULTIPLE_MASTER
gpos->mmfunc = default_mmfunc;
+#endif
/* skip version */
@@ -252,10 +256,24 @@ static HB_Error Load_ValueRecord( HB_ValueRecord* vr,
else
vr->YAdvance = 0;
+ if ( format & HB_GPOS_FORMAT_HAVE_DEVICE_TABLES )
+ {
+ if ( ALLOC_ARRAY( vr->DeviceTables, 4, HB_Device ) )
+ return error;
+ vr->DeviceTables[VR_X_ADVANCE_DEVICE] = 0;
+ vr->DeviceTables[VR_Y_ADVANCE_DEVICE] = 0;
+ vr->DeviceTables[VR_X_PLACEMENT_DEVICE] = 0;
+ vr->DeviceTables[VR_Y_PLACEMENT_DEVICE] = 0;
+ }
+ else
+ {
+ vr->DeviceTables = 0;
+ }
+
if ( format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT_DEVICE )
{
if ( ACCESS_Frame( 2L ) )
- return error;
+ goto Fail4;
new_offset = GET_UShort();
@@ -267,20 +285,11 @@ static HB_Error Load_ValueRecord( HB_ValueRecord* vr,
cur_offset = FILE_Pos();
if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Device( &vr->XPlacementDevice,
+ ( error = _HB_OPEN_Load_Device( &vr->DeviceTables[VR_X_PLACEMENT_DEVICE],
stream ) ) != HB_Err_Ok )
- return error;
+ goto Fail4;
(void)FILE_Seek( cur_offset );
}
- else
- goto empty1;
- }
- else
- {
- empty1:
- vr->XPlacementDevice.StartSize = 0;
- vr->XPlacementDevice.EndSize = 0;
- vr->XPlacementDevice.DeltaValue = NULL;
}
if ( format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT_DEVICE )
@@ -298,20 +307,11 @@ static HB_Error Load_ValueRecord( HB_ValueRecord* vr,
cur_offset = FILE_Pos();
if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Device( &vr->YPlacementDevice,
+ ( error = _HB_OPEN_Load_Device( &vr->DeviceTables[VR_Y_PLACEMENT_DEVICE],
stream ) ) != HB_Err_Ok )
goto Fail3;
(void)FILE_Seek( cur_offset );
}
- else
- goto empty2;
- }
- else
- {
- empty2:
- vr->YPlacementDevice.StartSize = 0;
- vr->YPlacementDevice.EndSize = 0;
- vr->YPlacementDevice.DeltaValue = NULL;
}
if ( format & HB_GPOS_FORMAT_HAVE_X_ADVANCE_DEVICE )
@@ -329,20 +329,11 @@ static HB_Error Load_ValueRecord( HB_ValueRecord* vr,
cur_offset = FILE_Pos();
if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Device( &vr->XAdvanceDevice,
+ ( error = _HB_OPEN_Load_Device( &vr->DeviceTables[VR_X_ADVANCE_DEVICE],
stream ) ) != HB_Err_Ok )
goto Fail2;
(void)FILE_Seek( cur_offset );
}
- else
- goto empty3;
- }
- else
- {
- empty3:
- vr->XAdvanceDevice.StartSize = 0;
- vr->XAdvanceDevice.EndSize = 0;
- vr->XAdvanceDevice.DeltaValue = NULL;
}
if ( format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE_DEVICE )
@@ -360,20 +351,11 @@ static HB_Error Load_ValueRecord( HB_ValueRecord* vr,
cur_offset = FILE_Pos();
if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Device( &vr->YAdvanceDevice,
+ ( error = _HB_OPEN_Load_Device( &vr->DeviceTables[VR_Y_ADVANCE_DEVICE],
stream ) ) != HB_Err_Ok )
goto Fail1;
(void)FILE_Seek( cur_offset );
}
- else
- goto empty4;
- }
- else
- {
- empty4:
- vr->YAdvanceDevice.StartSize = 0;
- vr->YAdvanceDevice.EndSize = 0;
- vr->YAdvanceDevice.DeltaValue = NULL;
}
if ( format & HB_GPOS_FORMAT_HAVE_X_ID_PLACEMENT )
@@ -381,59 +363,89 @@ static HB_Error Load_ValueRecord( HB_ValueRecord* vr,
if ( ACCESS_Frame( 2L ) )
goto Fail1;
+#ifdef HB_SUPPORT_MULTIPLE_MASTER
vr->XIdPlacement = GET_UShort();
+#else
+ (void) GET_UShort();
+#endif
FORGET_Frame();
}
+#ifdef HB_SUPPORT_MULTIPLE_MASTER
else
vr->XIdPlacement = 0;
+#endif
if ( format & HB_GPOS_FORMAT_HAVE_Y_ID_PLACEMENT )
{
if ( ACCESS_Frame( 2L ) )
goto Fail1;
+#ifdef HB_SUPPORT_MULTIPLE_MASTER
vr->YIdPlacement = GET_UShort();
+#else
+ (void) GET_UShort();
+#endif
FORGET_Frame();
}
+#ifdef HB_SUPPORT_MULTIPLE_MASTER
else
vr->YIdPlacement = 0;
+#endif
if ( format & HB_GPOS_FORMAT_HAVE_X_ID_ADVANCE )
{
if ( ACCESS_Frame( 2L ) )
goto Fail1;
+#ifdef HB_SUPPORT_MULTIPLE_MASTER
vr->XIdAdvance = GET_UShort();
+#else
+ (void) GET_UShort();
+#endif
FORGET_Frame();
}
+#ifdef HB_SUPPORT_MULTIPLE_MASTER
else
vr->XIdAdvance = 0;
+#endif
if ( format & HB_GPOS_FORMAT_HAVE_Y_ID_ADVANCE )
{
if ( ACCESS_Frame( 2L ) )
goto Fail1;
+#ifdef HB_SUPPORT_MULTIPLE_MASTER
vr->YIdAdvance = GET_UShort();
+#else
+ (void) GET_UShort();
+#endif
FORGET_Frame();
}
+#ifdef HB_SUPPORT_MULTIPLE_MASTER
else
vr->YIdAdvance = 0;
+#endif
return HB_Err_Ok;
Fail1:
- _HB_OPEN_Free_Device( &vr->YAdvanceDevice );
+ if ( vr->DeviceTables )
+ _HB_OPEN_Free_Device( vr->DeviceTables[VR_Y_ADVANCE_DEVICE] );
Fail2:
- _HB_OPEN_Free_Device( &vr->XAdvanceDevice );
+ if ( vr->DeviceTables )
+ _HB_OPEN_Free_Device( vr->DeviceTables[VR_X_ADVANCE_DEVICE] );
Fail3:
- _HB_OPEN_Free_Device( &vr->YPlacementDevice );
+ if ( vr->DeviceTables )
+ _HB_OPEN_Free_Device( vr->DeviceTables[VR_Y_PLACEMENT_DEVICE] );
+
+Fail4:
+ FREE( vr->DeviceTables );
return error;
}
@@ -442,13 +454,14 @@ static void Free_ValueRecord( HB_ValueRecord* vr,
HB_UShort format )
{
if ( format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE_DEVICE )
- _HB_OPEN_Free_Device( &vr->YAdvanceDevice );
+ _HB_OPEN_Free_Device( vr->DeviceTables[VR_Y_ADVANCE_DEVICE] );
if ( format & HB_GPOS_FORMAT_HAVE_X_ADVANCE_DEVICE )
- _HB_OPEN_Free_Device( &vr->XAdvanceDevice );
+ _HB_OPEN_Free_Device( vr->DeviceTables[VR_X_ADVANCE_DEVICE] );
if ( format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT_DEVICE )
- _HB_OPEN_Free_Device( &vr->YPlacementDevice );
+ _HB_OPEN_Free_Device( vr->DeviceTables[VR_Y_PLACEMENT_DEVICE] );
if ( format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT_DEVICE )
- _HB_OPEN_Free_Device( &vr->XPlacementDevice );
+ _HB_OPEN_Free_Device( vr->DeviceTables[VR_X_PLACEMENT_DEVICE] );
+ FREE( vr->DeviceTables );
}
@@ -457,10 +470,12 @@ static HB_Error Get_ValueRecord( GPOS_Instance* gpi,
HB_UShort format,
HB_Position gd )
{
- HB_Fixed value;
HB_Short pixel_value;
HB_Error error = HB_Err_Ok;
+#ifdef HB_SUPPORT_MULTIPLE_MASTER
HB_GPOSHeader* gpos = gpi->gpos;
+ HB_Fixed value;
+#endif
HB_UShort x_ppem, y_ppem;
HB_16Dot16 x_scale, y_scale;
@@ -491,26 +506,27 @@ static HB_Error Get_ValueRecord( GPOS_Instance* gpi,
if ( format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT_DEVICE )
{
- _HB_OPEN_Get_Device( &vr->XPlacementDevice, x_ppem, &pixel_value );
+ _HB_OPEN_Get_Device( vr->DeviceTables[VR_X_PLACEMENT_DEVICE], x_ppem, &pixel_value );
gd->x_pos += pixel_value << 6;
}
if ( format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT_DEVICE )
{
- _HB_OPEN_Get_Device( &vr->YPlacementDevice, y_ppem, &pixel_value );
+ _HB_OPEN_Get_Device( vr->DeviceTables[VR_Y_PLACEMENT_DEVICE], y_ppem, &pixel_value );
gd->y_pos += pixel_value << 6;
}
if ( format & HB_GPOS_FORMAT_HAVE_X_ADVANCE_DEVICE )
{
- _HB_OPEN_Get_Device( &vr->XAdvanceDevice, x_ppem, &pixel_value );
+ _HB_OPEN_Get_Device( vr->DeviceTables[VR_X_ADVANCE_DEVICE], x_ppem, &pixel_value );
gd->x_advance += pixel_value << 6;
}
if ( format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE_DEVICE )
{
- _HB_OPEN_Get_Device( &vr->YAdvanceDevice, y_ppem, &pixel_value );
+ _HB_OPEN_Get_Device( vr->DeviceTables[VR_Y_ADVANCE_DEVICE], y_ppem, &pixel_value );
gd->y_advance += pixel_value << 6;
}
}
+#ifdef HB_SUPPORT_MULTIPLE_MASTER
/* values returned from mmfunc() are already in fractional pixels */
if ( format & HB_GPOS_FORMAT_HAVE_X_ID_PLACEMENT )
@@ -545,6 +561,7 @@ static HB_Error Get_ValueRecord( GPOS_Instance* gpi,
return error;
gd->y_advance += value;
}
+#endif
return error;
}
@@ -608,21 +625,21 @@ static HB_Error Load_Anchor( HB_Anchor* an,
if ( new_offset )
{
+ if ( ALLOC_ARRAY( an->af.af3.DeviceTables, 2, HB_Device ) )
+ return error;
+
+ an->af.af3.DeviceTables[AF3_X_DEVICE_TABLE] = 0;
+ an->af.af3.DeviceTables[AF3_Y_DEVICE_TABLE] = 0;
+
new_offset += base_offset;
cur_offset = FILE_Pos();
if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Device( &an->af.af3.XDeviceTable,
+ ( error = _HB_OPEN_Load_Device( &an->af.af3.DeviceTables[AF3_X_DEVICE_TABLE],
stream ) ) != HB_Err_Ok )
- return error;
+ goto Fail2;
(void)FILE_Seek( cur_offset );
}
- else
- {
- an->af.af3.XDeviceTable.StartSize = 0;
- an->af.af3.XDeviceTable.EndSize = 0;
- an->af.af3.XDeviceTable.DeltaValue = NULL;
- }
if ( ACCESS_Frame( 2L ) )
goto Fail;
@@ -633,29 +650,37 @@ static HB_Error Load_Anchor( HB_Anchor* an,
if ( new_offset )
{
+ if ( !an->af.af3.DeviceTables )
+ {
+ if ( ALLOC_ARRAY( an->af.af3.DeviceTables, 2, HB_Device ) )
+ return error;
+
+ an->af.af3.DeviceTables[AF3_X_DEVICE_TABLE] = 0;
+ an->af.af3.DeviceTables[AF3_Y_DEVICE_TABLE] = 0;
+ }
+
new_offset += base_offset;
cur_offset = FILE_Pos();
if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Device( &an->af.af3.YDeviceTable,
+ ( error = _HB_OPEN_Load_Device( &an->af.af3.DeviceTables[AF3_Y_DEVICE_TABLE],
stream ) ) != HB_Err_Ok )
goto Fail;
(void)FILE_Seek( cur_offset );
}
- else
- {
- an->af.af3.YDeviceTable.StartSize = 0;
- an->af.af3.YDeviceTable.EndSize = 0;
- an->af.af3.YDeviceTable.DeltaValue = NULL;
- }
break;
case 4:
if ( ACCESS_Frame( 4L ) )
return error;
+#ifdef HB_SUPPORT_MULTIPLE_MASTER
an->af.af4.XIdAnchor = GET_UShort();
an->af.af4.YIdAnchor = GET_UShort();
+#else
+ (void) GET_UShort();
+ (void) GET_UShort();
+#endif
FORGET_Frame();
break;
@@ -667,17 +692,22 @@ static HB_Error Load_Anchor( HB_Anchor* an,
return HB_Err_Ok;
Fail:
- _HB_OPEN_Free_Device( &an->af.af3.XDeviceTable );
+ if ( an->af.af3.DeviceTables )
+ _HB_OPEN_Free_Device( an->af.af3.DeviceTables[AF3_X_DEVICE_TABLE] );
+
+Fail2:
+ FREE( an->af.af3.DeviceTables );
return error;
}
static void Free_Anchor( HB_Anchor* an)
{
- if ( an->PosFormat == 3 )
+ if ( an->PosFormat == 3 && an->af.af3.DeviceTables )
{
- _HB_OPEN_Free_Device( &an->af.af3.YDeviceTable );
- _HB_OPEN_Free_Device( &an->af.af3.XDeviceTable );
+ _HB_OPEN_Free_Device( an->af.af3.DeviceTables[AF3_X_DEVICE_TABLE] );
+ _HB_OPEN_Free_Device( an->af.af3.DeviceTables[AF3_Y_DEVICE_TABLE] );
+ FREE( an->af.af3.DeviceTables );
}
}
@@ -690,7 +720,9 @@ static HB_Error Get_Anchor( GPOS_Instance* gpi,
{
HB_Error error = HB_Err_Ok;
+#ifdef HB_SUPPORT_MULTIPLE_MASTER
HB_GPOSHeader* gpos = gpi->gpos;
+#endif
HB_UShort ap;
HB_Short pixel_value;
@@ -743,9 +775,9 @@ static HB_Error Get_Anchor( GPOS_Instance* gpi,
case 3:
if ( !gpi->dvi )
{
- _HB_OPEN_Get_Device( &an->af.af3.XDeviceTable, x_ppem, &pixel_value );
+ _HB_OPEN_Get_Device( an->af.af3.DeviceTables[AF3_X_DEVICE_TABLE], x_ppem, &pixel_value );
*x_value = pixel_value << 6;
- _HB_OPEN_Get_Device( &an->af.af3.YDeviceTable, y_ppem, &pixel_value );
+ _HB_OPEN_Get_Device( an->af.af3.DeviceTables[AF3_Y_DEVICE_TABLE], y_ppem, &pixel_value );
*y_value = pixel_value << 6;
}
else
@@ -756,6 +788,7 @@ static HB_Error Get_Anchor( GPOS_Instance* gpi,
break;
case 4:
+#ifdef HB_SUPPORT_MULTIPLE_MASTER
error = (gpos->mmfunc)( gpi->font, an->af.af4.XIdAnchor,
x_value, gpos->data );
if ( error )
@@ -766,6 +799,9 @@ static HB_Error Get_Anchor( GPOS_Instance* gpi,
if ( error )
return error;
break;
+#else
+ return ERR(HB_Err_Not_Covered);
+#endif
}
return error;
@@ -5966,8 +6002,7 @@ HB_Error HB_GPOS_Clear_Features( HB_GPOSHeader* gpos )
return HB_Err_Ok;
}
-
-
+#ifdef HB_SUPPORT_MULTIPLE_MASTER
HB_Error HB_GPOS_Register_MM_Function( HB_GPOSHeader* gpos,
HB_MMFunction mmfunc,
void* data )
@@ -5980,6 +6015,7 @@ HB_Error HB_GPOS_Register_MM_Function( HB_GPOSHeader* gpos,
return HB_Err_Ok;
}
+#endif
/* If `dvi' is TRUE, glyph contour points for anchor points and device
tables are ignored -- you will get device independent values. */
diff --git a/src/harfbuzz-gpos.h b/src/harfbuzz-gpos.h
index 2840dae..92bff84 100755
--- a/src/harfbuzz-gpos.h
+++ b/src/harfbuzz-gpos.h
@@ -44,6 +44,7 @@ HB_BEGIN_HEADER
#define HB_GPOS_LOOKUP_CHAIN 8
#define HB_GPOS_LOOKUP_EXTENSION 9
+#ifdef HB_SUPPORT_MULTIPLE_MASTER
/* 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'
@@ -59,6 +60,7 @@ typedef HB_Error (*HB_MMFunction)(HB_Font font,
HB_UShort metric_id,
HB_Fixed* metric_value,
void* data );
+#endif
struct HB_GPOSHeader_
@@ -71,12 +73,14 @@ struct HB_GPOSHeader_
HB_GDEFHeader* gdef;
+#ifdef HB_SUPPORT_MULTIPLE_MASTER
/* 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;
+#endif
};
typedef struct HB_GPOSHeader_ HB_GPOSHeader;
@@ -129,9 +133,11 @@ HB_Error HB_GPOS_Add_Feature( HB_GPOSHeader* gpos,
HB_Error HB_GPOS_Clear_Features( HB_GPOSHeader* gpos );
+#ifdef HB_SUPPORT_MULTIPLE_MASTER
HB_Error HB_GPOS_Register_MM_Function( HB_GPOSHeader* gpos,
HB_MMFunction mmfunc,
void* data );
+#endif
/* If `dvi' is TRUE, glyph contour points for anchor points and device
tables are ignored -- you will get device independent values. */
diff --git a/src/harfbuzz-greek.c b/src/harfbuzz-greek.c
new file mode 100644
index 0000000..2e9b858
--- /dev/null
+++ b/src/harfbuzz-greek.c
@@ -0,0 +1,447 @@
+/*
+ * Copyright (C) 2010 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>
+
+#ifndef NO_OPENTYPE
+static const HB_OpenTypeFeature greek_features[] = {
+ { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty },
+ { HB_MAKE_TAG('l', 'i', 'g', 'a'), CcmpProperty },
+ { HB_MAKE_TAG('c', 'l', 'i', 'g'), CcmpProperty },
+ {0, 0}
+};
+#endif
+
+/*
+ Greek decompositions
+*/
+
+
+typedef struct _hb_greek_decomposition {
+ HB_UChar16 composed;
+ HB_UChar16 base;
+} hb_greek_decomposition;
+
+static const hb_greek_decomposition decompose_0x300[] = {
+ { 0x1FBA, 0x0391 },
+ { 0x1FC8, 0x0395 },
+ { 0x1FCA, 0x0397 },
+ { 0x1FDA, 0x0399 },
+ { 0x1FF8, 0x039F },
+ { 0x1FEA, 0x03A5 },
+ { 0x1FFA, 0x03A9 },
+ { 0x1F70, 0x03B1 },
+ { 0x1F72, 0x03B5 },
+ { 0x1F74, 0x03B7 },
+ { 0x1F76, 0x03B9 },
+ { 0x1F78, 0x03BF },
+ { 0x1F7A, 0x03C5 },
+ { 0x1F7C, 0x03C9 },
+ { 0x1FD2, 0x03CA },
+ { 0x1FE2, 0x03CB },
+ { 0x1F02, 0x1F00 },
+ { 0, 0 }
+};
+
+static HB_UChar16 compose_0x300(HB_UChar16 base)
+{
+ if ((base ^ 0x1f00) < 0x100) {
+ if (base <= 0x1f69 && !(base & 0x6))
+ return base + 2;
+ if (base == 0x1fbf)
+ return 0x1fcd;
+ if (base == 0x1ffe)
+ return 0x1fdd;
+ return 0;
+ }
+ {
+ const hb_greek_decomposition *d = decompose_0x300;
+ while (d->base && d->base != base)
+ ++d;
+ return d->composed;
+ }
+}
+
+static const hb_greek_decomposition decompose_0x301[] = {
+ { 0x0386, 0x0391 },
+ { 0x0388, 0x0395 },
+ { 0x0389, 0x0397 },
+ { 0x038A, 0x0399 },
+ { 0x038C, 0x039F },
+ { 0x038E, 0x03A5 },
+ { 0x038F, 0x03A9 },
+ { 0x03AC, 0x03B1 },
+ { 0x03AD, 0x03B5 },
+ { 0x03AE, 0x03B7 },
+ { 0x03AF, 0x03B9 },
+ { 0x03CC, 0x03BF },
+ { 0x03CD, 0x03C5 },
+ { 0x03CE, 0x03C9 },
+ { 0x0390, 0x03CA },
+ { 0x03B0, 0x03CB },
+ { 0x03D3, 0x03D2 },
+ { 0, 0 }
+};
+
+
+static HB_UChar16 compose_0x301(HB_UChar16 base)
+{
+ if ((base ^ 0x1f00) < 0x100) {
+ if (base <= 0x1f69 && !(base & 0x6))
+ return base + 4;
+ if (base == 0x1fbf)
+ return 0x1fce;
+ if (base == 0x1ffe)
+ return 0x1fde;
+ }
+ {
+ const hb_greek_decomposition *d = decompose_0x301;
+ while (d->base && d->base != base)
+ ++d;
+ return d->composed;
+ }
+}
+
+static const hb_greek_decomposition decompose_0x304[] = {
+ { 0x1FB9, 0x0391 },
+ { 0x1FD9, 0x0399 },
+ { 0x1FE9, 0x03A5 },
+ { 0x1FB1, 0x03B1 },
+ { 0x1FD1, 0x03B9 },
+ { 0x1FE1, 0x03C5 },
+ { 0, 0 }
+};
+
+static HB_UChar16 compose_0x304(HB_UChar16 base)
+{
+ const hb_greek_decomposition *d = decompose_0x304;
+ while (d->base && d->base != base)
+ ++d;
+ return d->composed;
+}
+
+static const hb_greek_decomposition decompose_0x306[] = {
+ { 0x1FB8, 0x0391 },
+ { 0x1FD8, 0x0399 },
+ { 0x1FE8, 0x03A5 },
+ { 0x1FB0, 0x03B1 },
+ { 0x1FD0, 0x03B9 },
+ { 0x1FE0, 0x03C5 },
+ { 0, 0 }
+};
+
+static HB_UChar16 compose_0x306(HB_UChar16 base)
+{
+ const hb_greek_decomposition *d = decompose_0x306;
+ while (d->base && d->base != base)
+ ++d;
+ return d->composed;
+}
+
+static const hb_greek_decomposition decompose_0x308[] = {
+ { 0x03AA, 0x0399 },
+ { 0x03AB, 0x03A5 },
+ { 0x03CA, 0x03B9 },
+ { 0x03CB, 0x03C5 },
+ { 0x03D4, 0x03D2 },
+ { 0, 0 }
+};
+
+static HB_UChar16 compose_0x308(HB_UChar16 base)
+{
+ const hb_greek_decomposition *d = decompose_0x308;
+ while (d->base && d->base != base)
+ ++d;
+ return d->composed;
+}
+
+
+static const hb_greek_decomposition decompose_0x313[] = {
+ { 0x1F08, 0x0391 },
+ { 0x1F18, 0x0395 },
+ { 0x1F28, 0x0397 },
+ { 0x1F38, 0x0399 },
+ { 0x1F48, 0x039F },
+ { 0x1F68, 0x03A9 },
+ { 0x1F00, 0x03B1 },
+ { 0x1F10, 0x03B5 },
+ { 0x1F20, 0x03B7 },
+ { 0x1F30, 0x03B9 },
+ { 0x1F40, 0x03BF },
+ { 0x1FE4, 0x03C1 },
+ { 0x1F50, 0x03C5 },
+ { 0x1F60, 0x03C9 },
+ { 0, 0 }
+};
+
+static HB_UChar16 compose_0x313(HB_UChar16 base)
+{
+ const hb_greek_decomposition *d = decompose_0x313;
+ while (d->base && d->base != base)
+ ++d;
+ return d->composed;
+}
+
+static const hb_greek_decomposition decompose_0x314[] = {
+ { 0x1F09, 0x0391 },
+ { 0x1F19, 0x0395 },
+ { 0x1F29, 0x0397 },
+ { 0x1F39, 0x0399 },
+ { 0x1F49, 0x039F },
+ { 0x1FEC, 0x03A1 },
+ { 0x1F59, 0x03A5 },
+ { 0x1F69, 0x03A9 },
+ { 0x1F01, 0x03B1 },
+ { 0x1F11, 0x03B5 },
+ { 0x1F21, 0x03B7 },
+ { 0x1F31, 0x03B9 },
+ { 0x1F41, 0x03BF },
+ { 0x1FE5, 0x03C1 },
+ { 0x1F51, 0x03C5 },
+ { 0x1F61, 0x03C9 },
+ { 0, 0 }
+};
+
+static HB_UChar16 compose_0x314(HB_UChar16 base)
+{
+ const hb_greek_decomposition *d = decompose_0x314;
+ while (d->base && d->base != base)
+ ++d;
+ return d->composed;
+}
+
+static const hb_greek_decomposition decompose_0x342[] = {
+ { 0x1FB6, 0x03B1 },
+ { 0x1FC6, 0x03B7 },
+ { 0x1FD6, 0x03B9 },
+ { 0x1FE6, 0x03C5 },
+ { 0x1FF6, 0x03C9 },
+ { 0x1FD7, 0x03CA },
+ { 0x1FE7, 0x03CB },
+ { 0x1F06, 0x1F00 },
+ { 0x1F07, 0x1F01 },
+ { 0x1F0E, 0x1F08 },
+ { 0x1F0F, 0x1F09 },
+ { 0x1F26, 0x1F20 },
+ { 0x1F27, 0x1F21 },
+ { 0x1F2E, 0x1F28 },
+ { 0x1F2F, 0x1F29 },
+ { 0x1F36, 0x1F30 },
+ { 0x1F37, 0x1F31 },
+ { 0x1F3E, 0x1F38 },
+ { 0x1F3F, 0x1F39 },
+ { 0x1F56, 0x1F50 },
+ { 0x1F57, 0x1F51 },
+ { 0x1F5F, 0x1F59 },
+ { 0x1F66, 0x1F60 },
+ { 0x1F67, 0x1F61 },
+ { 0x1F6E, 0x1F68 },
+ { 0x1F6F, 0x1F69 },
+ { 0x1FCF, 0x1FBF },
+ { 0x1FDF, 0x1FFE },
+ { 0, 0 }
+};
+
+static HB_UChar16 compose_0x342(HB_UChar16 base)
+{
+ const hb_greek_decomposition *d = decompose_0x342;
+ while (d->base && d->base != base)
+ ++d;
+ return d->composed;
+}
+
+static const hb_greek_decomposition decompose_0x345[] = {
+ { 0x1FBC, 0x0391 },
+ { 0x1FCC, 0x0397 },
+ { 0x1FFC, 0x03A9 },
+ { 0x1FB4, 0x03AC },
+ { 0x1FC4, 0x03AE },
+ { 0x1FB3, 0x03B1 },
+ { 0x1FC3, 0x03B7 },
+ { 0x1FF3, 0x03C9 },
+ { 0x1FF4, 0x03CE },
+ { 0x1F80, 0x1F00 },
+ { 0x1F81, 0x1F01 },
+ { 0x1F82, 0x1F02 },
+ { 0x1F83, 0x1F03 },
+ { 0x1F84, 0x1F04 },
+ { 0x1F85, 0x1F05 },
+ { 0x1F86, 0x1F06 },
+ { 0x1F87, 0x1F07 },
+ { 0x1F88, 0x1F08 },
+ { 0x1F89, 0x1F09 },
+ { 0x1F8A, 0x1F0A },
+ { 0x1F8B, 0x1F0B },
+ { 0x1F8C, 0x1F0C },
+ { 0x1F8D, 0x1F0D },
+ { 0x1F8E, 0x1F0E },
+ { 0x1F8F, 0x1F0F },
+ { 0x1F90, 0x1F20 },
+ { 0x1F91, 0x1F21 },
+ { 0x1F92, 0x1F22 },
+ { 0x1F93, 0x1F23 },
+ { 0x1F94, 0x1F24 },
+ { 0x1F95, 0x1F25 },
+ { 0x1F96, 0x1F26 },
+ { 0x1F97, 0x1F27 },
+ { 0x1F98, 0x1F28 },
+ { 0x1F99, 0x1F29 },
+ { 0x1F9A, 0x1F2A },
+ { 0x1F9B, 0x1F2B },
+ { 0x1F9C, 0x1F2C },
+ { 0x1F9D, 0x1F2D },
+ { 0x1F9E, 0x1F2E },
+ { 0x1F9F, 0x1F2F },
+ { 0x1FA0, 0x1F60 },
+ { 0x1FA1, 0x1F61 },
+ { 0x1FA2, 0x1F62 },
+ { 0x1FA3, 0x1F63 },
+ { 0x1FA4, 0x1F64 },
+ { 0x1FA5, 0x1F65 },
+ { 0x1FA6, 0x1F66 },
+ { 0x1FA7, 0x1F67 },
+ { 0x1FA8, 0x1F68 },
+ { 0x1FA9, 0x1F69 },
+ { 0x1FAA, 0x1F6A },
+ { 0x1FAB, 0x1F6B },
+ { 0x1FAC, 0x1F6C },
+ { 0x1FAD, 0x1F6D },
+ { 0x1FAE, 0x1F6E },
+ { 0x1FAF, 0x1F6F },
+ { 0x1FB2, 0x1F70 },
+ { 0x1FC2, 0x1F74 },
+ { 0x1FF2, 0x1F7C },
+ { 0x1FB7, 0x1FB6 },
+ { 0x1FC7, 0x1FC6 },
+ { 0x1FF7, 0x1FF6 },
+ { 0, 0 }
+};
+
+static HB_UChar16 compose_0x345(HB_UChar16 base)
+{
+ const hb_greek_decomposition *d = decompose_0x345;
+ while (d->base && d->base != base)
+ ++d;
+ return d->composed;
+}
+
+/*
+ Greek shaping. Heuristic positioning can't render polytonic greek correctly. We're a lot
+ better off mapping greek chars with diacritics to the characters in the extended greek
+ region in Unicode if possible.
+*/
+HB_Bool HB_GreekShape(HB_ShaperItem *shaper_item)
+{
+ const int availableGlyphs = shaper_item->num_glyphs;
+ 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);
+
+ assert(shaper_item->item.script == HB_Script_Greek);
+
+ *shapedChars = *uc;
+ logClusters[0] = 0;
+
+ for (i = 1; i < shaper_item->item.length; ++i) {
+ hb_uint16 base = shapedChars[slen-1];
+ hb_uint16 shaped = 0;
+ if (uc[i] == 0x300)
+ shaped = compose_0x300(base);
+ else if (uc[i] == 0x301)
+ shaped = compose_0x301(base);
+ else if (uc[i] == 0x304)
+ shaped = compose_0x304(base);
+ else if (uc[i] == 0x306)
+ shaped = compose_0x306(base);
+ else if (uc[i] == 0x308)
+ shaped = compose_0x308(base);
+ else if (uc[i] == 0x313)
+ shaped = compose_0x313(base);
+ else if (uc[i] == 0x314)
+ shaped = compose_0x314(base);
+ else if (uc[i] == 0x342)
+ shaped = compose_0x342(base);
+ else if (uc[i] == 0x345)
+ shaped = compose_0x345(base);
+
+ if (shaped) {
+ if (shaper_item->font->klass->canRender(shaper_item->font, (HB_UChar16 *)&shaped, 1)) {
+ shapedChars[slen-1] = 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;
+
+#ifndef NO_OPENTYPE
+ if (HB_SelectScript(shaper_item, greek_features)) {
+ HB_OpenTypeShape(shaper_item, /*properties*/0);
+ return HB_OpenTypePosition(shaper_item, availableGlyphs, /*doLogClusters*/TRUE);
+ }
+#endif
+ HB_HeuristicPosition(shaper_item);
+
+ return TRUE;
+}
+
diff --git a/src/harfbuzz-gsub-private.h b/src/harfbuzz-gsub-private.h
index dd5ffdf..7eb329e 100755
--- a/src/harfbuzz-gsub-private.h
+++ b/src/harfbuzz-gsub-private.h
@@ -32,6 +32,9 @@
HB_BEGIN_HEADER
+#ifdef HB_USE_PACKED_STRUCTS
+#pragma pack(push, 1)
+#endif
typedef union HB_GSUB_SubTable_ HB_GSUB_SubTable;
@@ -48,9 +51,9 @@ typedef struct HB_SingleSubstFormat1_ HB_SingleSubstFormat1;
struct HB_SingleSubstFormat2_
{
+ HB_UShort* Substitute; /* array of substitute glyph IDs */
HB_UShort GlyphCount; /* number of glyph IDs in
Substitute array */
- HB_UShort* Substitute; /* array of substitute glyph IDs */
};
typedef struct HB_SingleSubstFormat2_ HB_SingleSubstFormat2;
@@ -58,14 +61,14 @@ 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;
+
+ HB_Coverage Coverage; /* Coverage table */
+ HB_Byte SubstFormat; /* 1 or 2 */
};
typedef struct HB_SingleSubst_ HB_SingleSubst;
@@ -75,10 +78,10 @@ typedef struct HB_SingleSubst_ HB_SingleSubst;
struct HB_Sequence_
{
- HB_UShort GlyphCount; /* number of glyph IDs in the
- Substitute array */
HB_UShort* Substitute; /* string of glyph IDs to
substitute */
+ HB_UShort GlyphCount; /* number of glyph IDs in the
+ Substitute array */
};
typedef struct HB_Sequence_ HB_Sequence;
@@ -86,10 +89,10 @@ typedef struct HB_Sequence_ HB_Sequence;
struct HB_MultipleSubst_
{
- HB_UShort SubstFormat; /* always 1 */
+ HB_Sequence* Sequence; /* array of Sequence tables */
HB_Coverage Coverage; /* Coverage table */
+ HB_UShort SubstFormat; /* always 1 */
HB_UShort SequenceCount; /* number of Sequence tables */
- HB_Sequence* Sequence; /* array of Sequence tables */
};
typedef struct HB_MultipleSubst_ HB_MultipleSubst;
@@ -99,9 +102,9 @@ typedef struct HB_MultipleSubst_ HB_MultipleSubst;
struct HB_AlternateSet_
{
+ HB_UShort* Alternate; /* array of alternate glyph IDs */
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;
@@ -109,11 +112,11 @@ typedef struct HB_AlternateSet_ HB_AlternateSet;
struct HB_AlternateSubst_
{
- HB_UShort SubstFormat; /* always 1 */
+ HB_AlternateSet* AlternateSet; /* array of AlternateSet tables */
HB_Coverage Coverage; /* Coverage table */
+ HB_UShort SubstFormat; /* always 1 */
HB_UShort AlternateSetCount;
/* number of AlternateSet tables */
- HB_AlternateSet* AlternateSet; /* array of AlternateSet tables */
};
typedef struct HB_AlternateSubst_ HB_AlternateSubst;
@@ -123,10 +126,10 @@ typedef struct HB_AlternateSubst_ HB_AlternateSubst;
struct HB_Ligature_
{
+ HB_UShort* Component; /* array of component glyph IDs */
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;
@@ -134,8 +137,8 @@ typedef struct HB_Ligature_ HB_Ligature;
struct HB_LigatureSet_
{
- HB_UShort LigatureCount; /* number of Ligature tables */
HB_Ligature* Ligature; /* array of Ligature tables */
+ HB_UShort LigatureCount; /* number of Ligature tables */
};
typedef struct HB_LigatureSet_ HB_LigatureSet;
@@ -143,10 +146,10 @@ typedef struct HB_LigatureSet_ HB_LigatureSet;
struct HB_LigatureSubst_
{
- HB_UShort SubstFormat; /* always 1 */
+ HB_LigatureSet* LigatureSet; /* array of LigatureSet tables */
HB_Coverage Coverage; /* Coverage table */
+ HB_UShort SubstFormat; /* always 1 */
HB_UShort LigatureSetCount; /* number of LigatureSet tables */
- HB_LigatureSet* LigatureSet; /* array of LigatureSet tables */
};
typedef struct HB_LigatureSubst_ HB_LigatureSubst;
@@ -168,13 +171,13 @@ typedef struct HB_SubstLookupRecord_ HB_SubstLookupRecord;
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 */
+ HB_UShort GlyphCount; /* total number of input glyphs */
+ HB_UShort SubstCount; /* number of SubstLookupRecord
+ tables */
};
typedef struct HB_SubRule_ HB_SubRule;
@@ -182,8 +185,8 @@ typedef struct HB_SubRule_ HB_SubRule;
struct HB_SubRuleSet_
{
- HB_UShort SubRuleCount; /* number of SubRule tables */
HB_SubRule* SubRule; /* array of SubRule tables */
+ HB_UShort SubRuleCount; /* number of SubRule tables */
};
typedef struct HB_SubRuleSet_ HB_SubRuleSet;
@@ -191,9 +194,9 @@ typedef struct HB_SubRuleSet_ HB_SubRuleSet;
struct HB_ContextSubstFormat1_
{
+ HB_SubRuleSet* SubRuleSet; /* array of SubRuleSet tables */
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;
@@ -201,13 +204,13 @@ 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 */
+ HB_UShort GlyphCount; /* total number of context classes */
+ HB_UShort SubstCount; /* number of SubstLookupRecord
+ tables */
};
typedef struct HB_SubClassRule_ HB_SubClassRule;
@@ -215,9 +218,9 @@ typedef struct HB_SubClassRule_ HB_SubClassRule;
struct HB_SubClassSet_
{
+ HB_SubClassRule* SubClassRule; /* array of SubClassRule tables */
HB_UShort SubClassRuleCount;
/* number of SubClassRule tables */
- HB_SubClassRule* SubClassRule; /* array of SubClassRule tables */
};
typedef struct HB_SubClassSet_ HB_SubClassSet;
@@ -229,13 +232,13 @@ typedef struct HB_SubClassSet_ HB_SubClassSet;
struct HB_ContextSubstFormat2_
{
- HB_UShort MaxContextLength;
- /* maximal context length */
+ HB_SubClassSet* SubClassSet; /* array of SubClassSet tables */
HB_Coverage Coverage; /* Coverage table */
HB_ClassDefinition ClassDef; /* ClassDef table */
HB_UShort SubClassSetCount;
/* number of SubClassSet tables */
- HB_SubClassSet* SubClassSet; /* array of SubClassSet tables */
+ HB_UShort MaxContextLength;
+ /* maximal context length */
};
typedef struct HB_ContextSubstFormat2_ HB_ContextSubstFormat2;
@@ -243,11 +246,11 @@ 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 */
+ HB_UShort GlyphCount; /* number of input glyphs */
+ HB_UShort SubstCount; /* number of SubstLookupRecords */
};
typedef struct HB_ContextSubstFormat3_ HB_ContextSubstFormat3;
@@ -255,14 +258,14 @@ 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;
+
+ HB_Byte SubstFormat; /* 1, 2, or 3 */
};
typedef struct HB_ContextSubst_ HB_ContextSubst;
@@ -272,18 +275,18 @@ typedef struct HB_ContextSubst_ HB_ContextSubst;
struct HB_ChainSubRule_
{
+ HB_UShort* Backtrack; /* array of backtrack glyph IDs */
+ HB_UShort* Input; /* array of input glyph IDs */
+ HB_UShort* Lookahead; /* array of lookahead glyph IDs */
+ HB_SubstLookupRecord* SubstLookupRecord;
+ /* array of SubstLookupRecords */
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;
@@ -291,9 +294,9 @@ typedef struct HB_ChainSubRule_ HB_ChainSubRule;
struct HB_ChainSubRuleSet_
{
+ HB_ChainSubRule* ChainSubRule; /* array of ChainSubRule tables */
HB_UShort ChainSubRuleCount;
/* number of ChainSubRule tables */
- HB_ChainSubRule* ChainSubRule; /* array of ChainSubRule tables */
};
typedef struct HB_ChainSubRuleSet_ HB_ChainSubRuleSet;
@@ -301,11 +304,11 @@ typedef struct HB_ChainSubRuleSet_ HB_ChainSubRuleSet;
struct HB_ChainContextSubstFormat1_
{
+ HB_ChainSubRuleSet* ChainSubRuleSet;
+ /* array of ChainSubRuleSet tables */
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;
@@ -313,20 +316,20 @@ typedef struct HB_ChainContextSubstFormat1_ HB_ChainContextSubstFormat1;
struct HB_ChainSubClassRule_
{
+ HB_UShort* Backtrack; /* array of backtrack classes */
+ HB_UShort* Input; /* array of context classes */
+ HB_UShort* Lookahead; /* array of lookahead classes */
+ HB_SubstLookupRecord* SubstLookupRecord;
+ /* array of substitution lookups */
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;
@@ -334,12 +337,12 @@ typedef struct HB_ChainSubClassRule_ HB_ChainSubClassRule;
struct HB_ChainSubClassSet_
{
- HB_UShort ChainSubClassRuleCount;
- /* number of ChainSubClassRule
- tables */
HB_ChainSubClassRule* ChainSubClassRule;
/* array of ChainSubClassRule
tables */
+ HB_UShort ChainSubClassRuleCount;
+ /* number of ChainSubClassRule
+ tables */
};
typedef struct HB_ChainSubClassSet_ HB_ChainSubClassSet;
@@ -351,27 +354,27 @@ typedef struct HB_ChainSubClassSet_ HB_ChainSubClassSet;
struct HB_ChainContextSubstFormat2_
{
+ HB_ChainSubClassSet* ChainSubClassSet;
+ /* array of ChainSubClassSet
+ tables */
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 */
+ HB_UShort MaxBacktrackLength;
+ /* maximal backtrack length */
+ HB_UShort MaxLookaheadLength;
+ /* maximal lookahead length */
+ HB_UShort MaxInputLength;
+ /* maximal input length */
};
typedef struct HB_ChainContextSubstFormat2_ HB_ChainContextSubstFormat2;
@@ -379,24 +382,24 @@ 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 */
+ HB_UShort BacktrackGlyphCount;
+ /* number of backtrack glyphs */
+ HB_UShort InputGlyphCount;
+ /* number of input glyphs */
+ HB_UShort LookaheadGlyphCount;
+ /* number of lookahead glyphs */
+ HB_UShort SubstCount; /* number of SubstLookupRecords */
};
typedef struct HB_ChainContextSubstFormat3_ HB_ChainContextSubstFormat3;
@@ -404,14 +407,14 @@ 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;
+
+ HB_Byte SubstFormat; /* 1, 2, or 3 */
};
typedef struct HB_ChainContextSubst_ HB_ChainContextSubst;
@@ -421,9 +424,9 @@ typedef struct HB_ChainContextSubst_ HB_ChainContextSubst;
/* LookupType 7 */
struct HB_ExtensionSubst_
{
+ HB_GSUB_SubTable *subtable; /* referenced subtable */
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;
@@ -433,16 +436,16 @@ typedef struct HB_ExtensionSubst_ HB_ExtensionSubst;
/* 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* LookaheadCoverage; /* array of lookahead Coverage
+ tables */
+ HB_UShort* Substitute; /* array of substitute Glyph ID */
HB_Coverage* BacktrackCoverage; /* array of backtrack Coverage
tables */
+ HB_Coverage Coverage; /* coverage table for input glyphs */
+ HB_UShort SubstFormat; /* always 1 */
+ HB_UShort BacktrackGlyphCount; /* number of backtrack glyphs */
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;
@@ -471,6 +474,10 @@ HB_INTERNAL void
_HB_GSUB_Free_SubTable( HB_GSUB_SubTable* st,
HB_UShort lookup_type );
+#ifdef HB_USE_PACKED_STRUCTS
+#pragma pack(pop)
+#endif
+
HB_END_HEADER
#endif /* HARFBUZZ_GSUB_PRIVATE_H */
diff --git a/src/harfbuzz-gsub.h b/src/harfbuzz-gsub.h
index 1ca3f0c..b00df44 100755
--- a/src/harfbuzz-gsub.h
+++ b/src/harfbuzz-gsub.h
@@ -32,6 +32,10 @@
HB_BEGIN_HEADER
+#ifdef HB_USE_PACKED_STRUCTS
+#pragma pack(push, 1)
+#endif
+
/* Lookup types for glyph substitution */
#define HB_GSUB_LOOKUP_SINGLE 1
@@ -60,6 +64,14 @@ typedef HB_UShort (*HB_AltFunction)(HB_UInt pos,
struct HB_GSUBHeader_
{
+ HB_GDEFHeader* gdef;
+
+ /* the next two fields are used for an alternate substitution callback
+ function to select the proper alternate glyph. */
+
+ void* data;
+ HB_AltFunction altfunc;
+
HB_UInt offset;
HB_16Dot16 Version;
@@ -67,14 +79,6 @@ struct HB_GSUBHeader_
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;
@@ -135,6 +139,9 @@ HB_Error HB_GSUB_Register_Alternate_Function( HB_GSUBHeader* gsub,
HB_Error HB_GSUB_Apply_String( HB_GSUBHeader* gsub,
HB_Buffer buffer );
+#ifdef HB_USE_PACKED_STRUCTS
+#pragma pack(pop)
+#endif
HB_END_HEADER
diff --git a/src/harfbuzz-hangul.c b/src/harfbuzz-hangul.c
index a819dac..6f89ed6 100755
--- a/src/harfbuzz-hangul.c
+++ b/src/harfbuzz-hangul.c
@@ -130,7 +130,7 @@ static int hangul_nextSyllableBoundary(const HB_UChar16 *s, int start, int end)
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('v', 'j', 'm', 'o'), CcmpProperty },
{ HB_MAKE_TAG('t', 'j', 'm', 'o'), CcmpProperty },
{ 0, 0 }
};
diff --git a/src/harfbuzz-hebrew.c b/src/harfbuzz-hebrew.c
index d2664de..67029be 100755
--- a/src/harfbuzz-hebrew.c
+++ b/src/harfbuzz-hebrew.c
@@ -56,8 +56,6 @@ HB_Bool HB_HebrewShape(HB_ShaperItem *shaper_item)
assert(shaper_item->item.script == HB_Script_Hebrew);
- HB_HeuristicSetGlyphAttributes(shaper_item);
-
#ifndef NO_OPENTYPE
if (HB_SelectScript(shaper_item, hebrew_features)) {
@@ -65,7 +63,7 @@ HB_Bool HB_HebrewShape(HB_ShaperItem *shaper_item)
if (!HB_ConvertStringToGlyphIndices(shaper_item))
return FALSE;
-
+ HB_HeuristicSetGlyphAttributes(shaper_item);
HB_OpenTypeShape(shaper_item, /*properties*/0);
return HB_OpenTypePosition(shaper_item, availableGlyphs, /*doLogClusters*/TRUE);
}
@@ -86,7 +84,7 @@ HB_Bool HB_HebrewShape(HB_ShaperItem *shaper_item)
logClusters[0] = 0;
for (i = 1; i < shaper_item->item.length; ++i) {
- hb_uint16 base = shapedChars[cluster_start];
+ hb_uint16 base = shapedChars[slen-1];
hb_uint16 shaped = 0;
HB_Bool invalid = FALSE;
if (uc[i] == Dagesh) {
@@ -145,7 +143,7 @@ HB_Bool HB_HebrewShape(HB_ShaperItem *shaper_item)
}
if (shaped) {
if (shaper_item->font->klass->canRender(shaper_item->font, (HB_UChar16 *)&shaped, 1)) {
- shapedChars[cluster_start] = shaped;
+ shapedChars[slen-1] = shaped;
} else
shaped = 0;
}
diff --git a/src/harfbuzz-indic.cpp b/src/harfbuzz-indic.cpp
index 3c9df93..4d8418b 100755
--- a/src/harfbuzz-indic.cpp
+++ b/src/harfbuzz-indic.cpp
@@ -1107,6 +1107,7 @@ static inline void splitMatra(unsigned short *reordered, int matra, int &len)
#ifndef NO_OPENTYPE
static const HB_OpenTypeFeature indic_features[] = {
+ { HB_MAKE_TAG('l', 'o', 'c', 'a'), LocaProperty },
{ HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty },
{ HB_MAKE_TAG('i', 'n', 'i', 't'), InitProperty },
{ HB_MAKE_TAG('n', 'u', 'k', 't'), NuktaProperty },
@@ -1115,12 +1116,14 @@ static const HB_OpenTypeFeature indic_features[] = {
{ HB_MAKE_TAG('b', 'l', 'w', 'f'), BelowFormProperty },
{ HB_MAKE_TAG('h', 'a', 'l', 'f'), HalfFormProperty },
{ HB_MAKE_TAG('p', 's', 't', 'f'), PostFormProperty },
+ { HB_MAKE_TAG('c', 'j', 'c', 't'), ConjunctFormProperty },
{ HB_MAKE_TAG('v', 'a', 't', 'u'), VattuProperty },
{ 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('h', 'a', 'l', 'n'), HalantProperty },
+ { HB_MAKE_TAG('c', 'a', 'l', 't'), IndicCaltProperty },
{ 0, 0 }
};
#endif
@@ -1148,6 +1151,8 @@ static QString propertiesToString(int properties)
{
QString res;
properties = ~properties;
+ if (properties & LocaProperty)
+ res += "Loca ";
if (properties & CcmpProperty)
res += "Ccmp ";
if (properties & InitProperty)
@@ -1168,6 +1173,8 @@ static QString propertiesToString(int properties)
res += "HalfForm ";
if (properties & PostFormProperty)
res += "PostForm ";
+ if (properties & ConjunctFormProperty)
+ res += "PostForm ";
if (properties & VattuProperty)
res += "Vattu ";
if (properties & PreSubstProperty)
@@ -1182,6 +1189,8 @@ static QString propertiesToString(int properties)
res += "Halant ";
if (properties & CligProperty)
res += "Clig ";
+ if (properties & IndicCaltProperty)
+ res += "Calt ";
return res;
}
#endif
@@ -1296,10 +1305,15 @@ static bool indic_shape_syllable(HB_Bool openType, HB_ShaperItem *item, bool inv
}
int skipped = 0;
Position pos = Post;
- for (i = len-1; i > base; i--) {
+ for (i = len-1; i >= base; i--) {
if (position[i] != Consonant && (position[i] != Control || script == HB_Script_Kannada))
continue;
+ if (i < len-1 && position[i] == Control && position[i+1] == Consonant) {
+ base = i+1;
+ break;
+ }
+
Position charPosition = indic_position(uc[i]);
if (pos == Post && charPosition == Post) {
pos = Post;
@@ -1545,16 +1559,20 @@ static bool indic_shape_syllable(HB_Bool openType, HB_ShaperItem *item, bool inv
// features we should always apply
for (i = 0; i < len; ++i)
- properties[i] = ~(CcmpProperty
+ properties[i] = ~(LocaProperty
+ | CcmpProperty
| NuktaProperty
| VattuProperty
+ | ConjunctFormProperty
| PreSubstProperty
| BelowSubstProperty
| AboveSubstProperty
| PostSubstProperty
| HalantProperty
+ | IndicCaltProperty
| PositioningProperties);
+ // Loca always applies
// Ccmp always applies
// Init
if (item->item.pos == 0
@@ -1611,6 +1629,7 @@ static bool indic_shape_syllable(HB_Bool openType, HB_ShaperItem *item, bool inv
// abvs always applies
// psts always applies
// halant always applies
+ // calt always applies
#ifdef INDIC_DEBUG
// {
diff --git a/src/harfbuzz-myanmar.c b/src/harfbuzz-myanmar.c
index 7cd82bb..4b68e64 100755
--- a/src/harfbuzz-myanmar.c
+++ b/src/harfbuzz-myanmar.c
@@ -424,12 +424,8 @@ static HB_Bool myanmar_shape_syllable(HB_Bool openType, HB_ShaperItem *item, HB_
#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
diff --git a/src/harfbuzz-open-private.h b/src/harfbuzz-open-private.h
index 73dd383..f1ca278 100755
--- a/src/harfbuzz-open-private.h
+++ b/src/harfbuzz-open-private.h
@@ -69,7 +69,7 @@ _HB_OPEN_Load_EmptyOrClassDefinition( HB_ClassDefinition* cd,
HB_UInt base_offset,
HB_Stream input );
HB_INTERNAL HB_Error
-_HB_OPEN_Load_Device( HB_Device* d,
+_HB_OPEN_Load_Device( HB_Device** d,
HB_Stream input );
HB_INTERNAL void _HB_OPEN_Free_ScriptList( HB_ScriptList* sl );
diff --git a/src/harfbuzz-open.c b/src/harfbuzz-open.c
index 0fe1e4d..f12f5b7 100755
--- a/src/harfbuzz-open.c
+++ b/src/harfbuzz-open.c
@@ -1282,9 +1282,10 @@ _HB_OPEN_Get_Class( HB_ClassDefinition* cd,
HB_INTERNAL HB_Error
-_HB_OPEN_Load_Device( HB_Device* d,
+_HB_OPEN_Load_Device( HB_Device** device,
HB_Stream stream )
{
+ HB_Device* d;
HB_Error error;
HB_UShort n, count;
@@ -1295,6 +1296,14 @@ _HB_OPEN_Load_Device( HB_Device* d,
if ( ACCESS_Frame( 6L ) )
return error;
+ if ( ALLOC( *device, sizeof(HB_Device)) )
+ {
+ *device = 0;
+ return error;
+ }
+
+ d = *device;
+
d->StartSize = GET_UShort();
d->EndSize = GET_UShort();
d->DeltaFormat = GET_UShort();
@@ -1318,11 +1327,17 @@ _HB_OPEN_Load_Device( HB_Device* d,
( 4 - d->DeltaFormat ) ) + 1;
if ( ALLOC_ARRAY( d->DeltaValue, count, HB_UShort ) )
+ {
+ FREE( *device );
+ *device = 0;
return error;
+ }
if ( ACCESS_Frame( count * 2L ) )
{
FREE( d->DeltaValue );
+ FREE( *device );
+ *device = 0;
return error;
}
@@ -1340,7 +1355,11 @@ _HB_OPEN_Load_Device( HB_Device* d,
HB_INTERNAL void
_HB_OPEN_Free_Device( HB_Device* d )
{
- FREE( d->DeltaValue );
+ if ( d )
+ {
+ FREE( d->DeltaValue );
+ FREE( d );
+ }
}
@@ -1384,13 +1403,11 @@ _HB_OPEN_Get_Device( HB_Device* d,
HB_UShort size,
HB_Short* value )
{
- HB_UShort byte, bits, mask, f, s;
-
-
- f = d->DeltaFormat;
+ HB_UShort byte, bits, mask, s;
- if ( d->DeltaValue && size >= d->StartSize && size <= d->EndSize )
+ if ( d && d->DeltaValue && size >= d->StartSize && size <= d->EndSize )
{
+ HB_UShort f = d->DeltaFormat;
s = size - d->StartSize;
byte = d->DeltaValue[s >> ( 4 - f )];
bits = byte >> ( 16 - ( ( s % ( 1 << ( 4 - f ) ) + 1 ) << f ) );
diff --git a/src/harfbuzz-open.h b/src/harfbuzz-open.h
index bdc6358..4ba6cf5 100755
--- a/src/harfbuzz-open.h
+++ b/src/harfbuzz-open.h
@@ -30,6 +30,10 @@
HB_BEGIN_HEADER
+#ifdef HB_USE_PACKED_STRUCTS
+#pragma pack(push, 1)
+#endif
+
/* Use this if a feature applies to all glyphs */
#define HB_ALL_GLYPHS 0xFFFF
@@ -42,10 +46,10 @@ HB_BEGIN_HEADER
struct HB_LangSys_
{
+ HB_UShort* FeatureIndex; /* array of Feature indices */
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;
@@ -53,8 +57,8 @@ typedef struct HB_LangSys_ HB_LangSys;
struct HB_LangSysRecord_
{
- HB_UInt LangSysTag; /* LangSysTag identifier */
HB_LangSys LangSys; /* LangSys table */
+ HB_UInt LangSysTag; /* LangSysTag identifier */
};
typedef struct HB_LangSysRecord_ HB_LangSysRecord;
@@ -62,9 +66,9 @@ typedef struct HB_LangSysRecord_ HB_LangSysRecord;
struct HB_ScriptTable_
{
+ HB_LangSysRecord* LangSysRecord; /* array of LangSysRecords */
HB_LangSys DefaultLangSys; /* DefaultLangSys table */
HB_UShort LangSysCount; /* number of LangSysRecords */
- HB_LangSysRecord* LangSysRecord; /* array of LangSysRecords */
};
typedef struct HB_ScriptTable_ HB_ScriptTable;
@@ -81,8 +85,8 @@ typedef struct HB_ScriptRecord_ HB_ScriptRecord;
struct HB_ScriptList_
{
- HB_UShort ScriptCount; /* number of ScriptRecords */
HB_ScriptRecord* ScriptRecord; /* array of ScriptRecords */
+ HB_UShort ScriptCount; /* number of ScriptRecords */
};
typedef struct HB_ScriptList_ HB_ScriptList;
@@ -92,9 +96,9 @@ typedef struct HB_ScriptList_ HB_ScriptList;
struct HB_Feature_
{
+ HB_UShort* LookupListIndex; /* array of LookupList indices */
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;
@@ -111,9 +115,9 @@ 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_FeatureRecord* FeatureRecord; /* array of FeatureRecords */
+ HB_UShort FeatureCount; /* number of FeatureRecords */
HB_UShort ApplyCount; /* number of elements in ApplyOrder */
};
@@ -127,10 +131,10 @@ typedef struct HB_SubTable_ HB_SubTable;
struct HB_Lookup_
{
+ HB_SubTable* SubTable; /* array of SubTables */
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;
@@ -144,9 +148,9 @@ typedef struct HB_Lookup_ HB_Lookup;
struct HB_LookupList_
{
- HB_UShort LookupCount; /* number of Lookups */
HB_Lookup* Lookup; /* array of Lookup records */
HB_UInt* Properties; /* array of flags */
+ HB_UShort LookupCount; /* number of Lookups */
};
typedef struct HB_LookupList_ HB_LookupList;
@@ -167,8 +171,8 @@ typedef struct HB_LookupList_ HB_LookupList;
struct HB_CoverageFormat1_
{
- HB_UShort GlyphCount; /* number of glyphs in GlyphArray */
HB_UShort* GlyphArray; /* array of glyph IDs */
+ HB_UShort GlyphCount; /* number of glyphs in GlyphArray */
};
typedef struct HB_CoverageFormat1_ HB_CoverageFormat1;
@@ -187,8 +191,8 @@ typedef struct HB_RangeRecord_ HB_RangeRecord;
struct HB_CoverageFormat2_
{
- HB_UShort RangeCount; /* number of RangeRecords */
HB_RangeRecord* RangeRecord; /* array of RangeRecords */
+ HB_UShort RangeCount; /* number of RangeRecords */
};
typedef struct HB_CoverageFormat2_ HB_CoverageFormat2;
@@ -196,7 +200,7 @@ typedef struct HB_CoverageFormat2_ HB_CoverageFormat2;
struct HB_Coverage_
{
- HB_UShort CoverageFormat; /* 1 or 2 */
+ HB_Byte CoverageFormat; /* 1 or 2 */
union
{
@@ -210,10 +214,10 @@ typedef struct HB_Coverage_ HB_Coverage;
struct HB_ClassDefFormat1_
{
+ HB_UShort* ClassValueArray; /* array of class values */
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;
@@ -231,10 +235,10 @@ typedef struct HB_ClassRangeRecord_ HB_ClassRangeRecord;
struct HB_ClassDefFormat2_
{
- HB_UShort ClassRangeCount;
- /* number of ClassRangeRecords */
HB_ClassRangeRecord* ClassRangeRecord;
/* array of ClassRangeRecords */
+ HB_UShort ClassRangeCount;
+ /* number of ClassRangeRecords */
};
typedef struct HB_ClassDefFormat2_ HB_ClassDefFormat2;
@@ -242,15 +246,14 @@ 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;
+
+ HB_Byte ClassFormat; /* 1 or 2 */
+ HB_Bool loaded;
};
typedef struct HB_ClassDefinition_ HB_ClassDefinition;
@@ -258,11 +261,11 @@ typedef struct HB_ClassDefinition_ HB_ClassDefinition;
struct HB_Device_
{
+ HB_UShort* DeltaValue; /* array of compressed data */
HB_UShort StartSize; /* smallest size to correct */
HB_UShort EndSize; /* largest size to correct */
- HB_UShort DeltaFormat; /* DeltaValue array data format:
+ HB_Byte DeltaFormat; /* DeltaValue array data format:
1, 2, or 3 */
- HB_UShort* DeltaValue; /* array of compressed data */
};
typedef struct HB_Device_ HB_Device;
@@ -276,6 +279,9 @@ enum HB_Type_
typedef enum HB_Type_ HB_Type;
+#ifdef HB_USE_PACKED_STRUCTS
+#pragma pack(pop)
+#endif
HB_END_HEADER
diff --git a/src/harfbuzz-shaper-all.cpp b/src/harfbuzz-shaper-all.cpp
index d2f902f..2dae501 100755
--- a/src/harfbuzz-shaper-all.cpp
+++ b/src/harfbuzz-shaper-all.cpp
@@ -25,6 +25,7 @@
#include "harfbuzz-shaper.cpp"
#include "harfbuzz-indic.cpp"
extern "C" {
+#include "harfbuzz-greek.c"
#include "harfbuzz-tibetan.c"
#include "harfbuzz-khmer.c"
#include "harfbuzz-hebrew.c"
diff --git a/src/harfbuzz-shaper-private.h b/src/harfbuzz-shaper-private.h
index 80bccf8..e1360c7 100755
--- a/src/harfbuzz-shaper-private.h
+++ b/src/harfbuzz-shaper-private.h
@@ -57,34 +57,37 @@ typedef enum
} 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,
+ LocaProperty = 0x1,
+ CcmpProperty = 0x2,
+ InitProperty = 0x4,
+ IsolProperty = 0x8,
+ FinaProperty = 0x10,
+ MediProperty = 0x20,
+ RligProperty = 0x40,
+ CaltProperty = 0x80,
+ LigaProperty = 0x100,
+ DligProperty = 0x200,
+ CswhProperty = 0x400,
+ MsetProperty = 0x800,
/* 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
+ NuktaProperty = 0x8,
+ AkhantProperty = 0x10,
+ RephProperty = 0x20,
+ PreFormProperty = 0x40,
+ BelowFormProperty = 0x80,
+ AboveFormProperty = 0x100,
+ HalfFormProperty = 0x200,
+ PostFormProperty = 0x400,
+ ConjunctFormProperty = 0x800,
+ VattuProperty = 0x1000,
+ PreSubstProperty = 0x2000,
+ BelowSubstProperty = 0x4000,
+ AboveSubstProperty = 0x8000,
+ PostSubstProperty = 0x10000,
+ HalantProperty = 0x20000,
+ CligProperty = 0x40000,
+ IndicCaltProperty = 0x80000
} HB_OpenTypeProperty;
@@ -100,6 +103,7 @@ typedef struct {
extern const HB_ScriptEngine hb_scriptEngines[];
extern HB_Bool HB_BasicShape(HB_ShaperItem *shaper_item);
+extern HB_Bool HB_GreekShape(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);
diff --git a/src/harfbuzz-shaper.cpp b/src/harfbuzz-shaper.cpp
index 808f8be..9b91c19 100755
--- a/src/harfbuzz-shaper.cpp
+++ b/src/harfbuzz-shaper.cpp
@@ -183,18 +183,15 @@ static void calcLineBreaks(const HB_UChar16 *uc, hb_uint32 len, HB_CharAttribute
if (ncls >= HB_LineBreak_CR)
goto next;
- // two complex chars (thai or lao), thai_attributes might override, but here we do a best guess
- if (cls == HB_LineBreak_SA && ncls == HB_LineBreak_SA) {
- lineBreakType = HB_Break;
- goto next;
- }
-
{
int tcls = ncls;
+ // for south east asian chars that require a complex (dictionary analysis), the unicode
+ // standard recommends to treat them as AL. thai_attributes and other attribute methods that
+ // do dictionary analysis can override
if (tcls >= HB_LineBreak_SA)
- tcls = HB_LineBreak_ID;
+ tcls = HB_LineBreak_AL;
if (cls >= HB_LineBreak_SA)
- cls = HB_LineBreak_ID;
+ cls = HB_LineBreak_AL;
int brk = breakTable[cls][tcls];
switch (brk) {
@@ -598,7 +595,7 @@ const HB_ScriptEngine HB_ScriptEngines[] = {
// Common
{ HB_BasicShape, 0},
// Greek
- { HB_BasicShape, 0},
+ { HB_GreekShape, 0},
// Cyrillic
{ HB_BasicShape, 0},
// Armenian
@@ -986,11 +983,12 @@ HB_Face HB_NewFace(void *font, HB_GetFontTableFunc tableFunc)
face->glyphs_substituted = false;
face->buffer = 0;
- HB_Error error;
+ HB_Error error = HB_Err_Ok;
HB_Stream stream;
HB_Stream gdefStream;
gdefStream = getTableStream(font, tableFunc, TTAG_GDEF);
+ error = HB_Err_Not_Covered;
if (!gdefStream || (error = HB_Load_GDEF_Table(gdefStream, &face->gdef))) {
//DEBUG("error loading gdef table: %d", error);
face->gdef = 0;
@@ -998,6 +996,7 @@ HB_Face HB_NewFace(void *font, HB_GetFontTableFunc tableFunc)
//DEBUG() << "trying to load gsub table";
stream = getTableStream(font, tableFunc, TTAG_GSUB);
+ error = HB_Err_Not_Covered;
if (!stream || (error = HB_Load_GSUB_Table(stream, &face->gsub, face->gdef, gdefStream))) {
face->gsub = 0;
if (error != HB_Err_Not_Covered) {
@@ -1009,6 +1008,7 @@ HB_Face HB_NewFace(void *font, HB_GetFontTableFunc tableFunc)
_hb_close_stream(stream);
stream = getTableStream(font, tableFunc, TTAG_GPOS);
+ error = HB_Err_Not_Covered;
if (!stream || (error = HB_Load_GPOS_Table(stream, &face->gpos, face->gdef, gdefStream))) {
face->gpos = 0;
DEBUG("error loading gpos table: %d", error);
@@ -1201,24 +1201,6 @@ HB_Bool HB_OpenTypeShape(HB_ShaperItem *item, const hb_uint32 *properties)
return true;
}
-/* See comments near the definition of HB_ShaperFlag_ForceMarksToZeroWidth for a description
- of why this function exists. */
-void HB_FixupZeroWidth(HB_ShaperItem *item)
-{
- HB_UShort property;
-
- if (!item->face->gdef)
- return;
-
- for (unsigned int i = 0; i < item->num_glyphs; ++i) {
- /* If the glyph is a mark, force its advance to zero. */
- if (HB_GDEF_Get_Glyph_Property (item->face->gdef, item->glyphs[i], &property) == HB_Err_Ok &&
- property == HB_GDEF_MARK) {
- item->advances[i] = 0;
- }
- }
-}
-
HB_Bool HB_OpenTypePosition(HB_ShaperItem *item, int availableGlyphs, HB_Bool doLogClusters)
{
HB_Face face = item->face;
@@ -1233,8 +1215,6 @@ HB_Bool HB_OpenTypePosition(HB_ShaperItem *item, int availableGlyphs, HB_Bool do
if (!face->glyphs_substituted && !glyphs_positioned) {
HB_GetGlyphAdvances(item);
- if (item->face->current_flags & HB_ShaperFlag_ForceMarksToZeroWidth)
- HB_FixupZeroWidth(item);
return true; // nothing to do for us
}
diff --git a/src/harfbuzz-shaper.h b/src/harfbuzz-shaper.h
index 33fc85a..ab5c07a 100755
--- a/src/harfbuzz-shaper.h
+++ b/src/harfbuzz-shaper.h
@@ -34,6 +34,22 @@
HB_BEGIN_HEADER
+#ifdef HB_USE_PACKED_STRUCTS
+#pragma pack(push, 1)
+#endif
+
+/*
+ using anything else than signed or unsigned for bitfields in C is non standard,
+ but accepted by almost all compilers. And it gives a significant reduction in
+ memory consumption as HB_CharAttributes and HB_GlyphAttributes will not have
+ a 4 byte alignment
+*/
+#ifdef __xlC__
+typedef unsigned hb_bitfield;
+#else
+typedef hb_uint8 hb_bitfield;
+#endif
+
typedef enum {
HB_Script_Common,
HB_Script_Greek,
@@ -123,12 +139,12 @@ typedef enum {
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_LineBreakType*/ hb_bitfield lineBreakType :2;
+ /*HB_Bool*/ hb_bitfield whiteSpace :1; /* A unicode whitespace character, except NBSP, ZWNBSP */
+ /*HB_Bool*/ hb_bitfield charStop :1; /* Valid cursor position (for left/right arrow) */
+ /*HB_Bool*/ hb_bitfield wordBoundary :1;
+ /*HB_Bool*/ hb_bitfield sentenceBoundary :1;
+ hb_bitfield unused :2;
} HB_CharAttributes;
void HB_GetCharAttributes(const HB_UChar16 *string, hb_uint32 stringLength,
@@ -154,11 +170,7 @@ typedef enum {
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_UseDesignMetrics = 2
} HB_ShaperFlag;
/*
@@ -185,12 +197,12 @@ typedef enum {
* 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_bitfield justification :4; /* Justification class */
+ hb_bitfield clusterStart :1; /* First glyph of representation of cluster */
+ hb_bitfield mark :1; /* needs to be positioned around base char */
+ hb_bitfield zeroWidth :1; /* ZWJ, ZWNJ etc, with no width */
+ hb_bitfield dontPrint :1;
+ hb_bitfield combiningClass :8;
} HB_GlyphAttributes;
typedef struct HB_FaceRec_ {
@@ -246,6 +258,10 @@ typedef struct HB_Font_ {
void *userData;
} HB_FontRec;
+#ifdef HB_USE_PACKED_STRUCTS
+#pragma pack(pop)
+#endif
+
typedef struct HB_ShaperItem_ HB_ShaperItem;
struct HB_ShaperItem_ {
diff --git a/src/harfbuzz-stream.h b/src/harfbuzz-stream.h
index 9991936..a155cc2 100755
--- a/src/harfbuzz-stream.h
+++ b/src/harfbuzz-stream.h
@@ -30,15 +30,21 @@
HB_BEGIN_HEADER
+#ifdef HB_USE_PACKED_STRUCTS
+#pragma pack(push, 1)
+#endif
+
typedef struct HB_StreamRec_
{
HB_Byte* base;
+ HB_Byte* cursor;
HB_UInt size;
HB_UInt pos;
-
- HB_Byte* cursor;
} HB_StreamRec;
+#ifdef HB_USE_PACKED_STRUCTS
+#pragma pack(pop)
+#endif
HB_END_HEADER
diff --git a/src/harfbuzz-thai.c b/src/harfbuzz-thai.c
index 1d1aa2f..e153ba9 100755
--- a/src/harfbuzz-thai.c
+++ b/src/harfbuzz-thai.c
@@ -27,57 +27,81 @@
#include "harfbuzz-external.h"
#include <assert.h>
+#include <stdio.h>
+
+typedef int (*th_brk_def)(const char*, int[], int);
+static th_brk_def th_brk = 0;
+static int libthai_resolved = 0;
+
+static void resolve_libthai()
+{
+ if (!th_brk)
+ th_brk = (th_brk_def)HB_Library_Resolve("thai", 0, "th_brk");
+ libthai_resolved = 1;
+}
+
+static void to_tis620(const HB_UChar16 *string, hb_uint32 len, const char *cstr)
+{
+ hb_uint32 i;
+ unsigned char *result = (unsigned char *)cstr;
+
+ for (i = 0; i < len; ++i) {
+ if (string[i] <= 0xa0)
+ result[i] = (unsigned char)string[i];
+ if (string[i] >= 0xe01 && string[i] <= 0xe5b)
+ result[i] = (unsigned char)(string[i] - 0xe00 + 0xa0);
+ else
+ result[i] = '?';
+ }
+
+ result[len] = 0;
+}
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;
+ char s[128];
+ char *cstr = s;
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 (!libthai_resolved)
+ resolve_libthai();
if (!th_brk)
return;
- cstr = HB_TextCodec_ConvertFromUnicode(thaiCodec, string, len, 0);
- if (!cstr)
- return;
+ if (len >= 128)
+ cstr = (char *)malloc(len*sizeof(char) + 1);
+
+ to_tis620(string, len, cstr);
- 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)
+ for (i = 0; i < len; ++i) {
attributes[i].lineBreakType = HB_NoBreak;
+ attributes[i].wordBoundary = FALSE;
+ }
for (i = 0; i < numbreaks; ++i) {
- if (break_positions[i] > 0)
+ if (break_positions[i] > 0) {
attributes[break_positions[i]-1].lineBreakType = HB_Break;
+ attributes[i].wordBoundary = TRUE;
+ }
}
if (break_positions != brp)
free(break_positions);
- HB_TextCodec_FreeResult(cstr);
+ if (len >= 128)
+ free(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);