summaryrefslogtreecommitdiff
path: root/Build/source/libs/graphite2
diff options
context:
space:
mode:
authorPeter Breitenlohner <peb@mppmu.mpg.de>2015-08-05 08:59:06 +0000
committerPeter Breitenlohner <peb@mppmu.mpg.de>2015-08-05 08:59:06 +0000
commita80f9f3d6b0a845c322d040fd3adb13b2ff41db7 (patch)
treeaf860685b7061063716e6a18bd2d5acfa8839ea0 /Build/source/libs/graphite2
parentcf732e3b1fcc0534a2c400e057231efc3c4a2ece (diff)
graphite2 1.3.0
git-svn-id: svn://tug.org/texlive/trunk@38046 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/libs/graphite2')
-rw-r--r--Build/source/libs/graphite2/ChangeLog5
-rw-r--r--Build/source/libs/graphite2/Makefile.am42
-rw-r--r--Build/source/libs/graphite2/Makefile.in111
-rwxr-xr-xBuild/source/libs/graphite2/configure24
-rw-r--r--Build/source/libs/graphite2/graphite2-1.2.4/.hg_archival.txt5
-rw-r--r--Build/source/libs/graphite2/graphite2-1.2.4/Todo.txt3
-rw-r--r--Build/source/libs/graphite2/graphite2-1.2.4/src/Rule.cpp31
-rw-r--r--Build/source/libs/graphite2/graphite2-1.2.4/src/inc/GlyphCache.h92
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0-PATCHES/ChangeLog (renamed from Build/source/libs/graphite2/graphite2-1.2.4-PATCHES/ChangeLog)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0-PATCHES/TL-Changes (renamed from Build/source/libs/graphite2/graphite2-1.2.4-PATCHES/TL-Changes)2
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/.hg_archival.txt5
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/.hgeol (renamed from Build/source/libs/graphite2/graphite2-1.2.4/.hgeol)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/.hgignore (renamed from Build/source/libs/graphite2/graphite2-1.2.4/.hgignore)2
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/.hgtags (renamed from Build/source/libs/graphite2/graphite2-1.2.4/.hgtags)2
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/CMakeLists.txt (renamed from Build/source/libs/graphite2/graphite2-1.2.4/CMakeLists.txt)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/COPYING (renamed from Build/source/libs/graphite2/graphite2-1.2.4/COPYING)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/ChangeLog (renamed from Build/source/libs/graphite2/graphite2-1.2.4/ChangeLog)12
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/Graphite.cmake (renamed from Build/source/libs/graphite2/graphite2-1.2.4/Graphite.cmake)11
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/LICENSE (renamed from Build/source/libs/graphite2/graphite2-1.2.4/LICENSE)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/Todo.txt13
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/graphite2.pc.in (renamed from Build/source/libs/graphite2/graphite2-1.2.4/graphite2.pc.in)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/include/graphite2/Font.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/include/graphite2/Font.h)4
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/include/graphite2/Log.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/include/graphite2/Log.h)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/include/graphite2/Segment.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/include/graphite2/Segment.h)36
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/include/graphite2/Types.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/include/graphite2/Types.h)15
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/Bidi.cpp (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/Bidi.cpp)47
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/CMakeLists.txt (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/CMakeLists.txt)7
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/CachedFace.cpp (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/CachedFace.cpp)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/CmapCache.cpp (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/CmapCache.cpp)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/Code.cpp (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/Code.cpp)128
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/Collider.cpp1080
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/Decompressor.cpp102
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/Face.cpp (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/Face.cpp)98
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/FeatureMap.cpp (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/FeatureMap.cpp)10
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/FileFace.cpp (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/FileFace.cpp)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/Font.cpp (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/Font.cpp)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/GlyphCache.cpp (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/GlyphCache.cpp)167
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/GlyphFace.cpp (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/GlyphFace.cpp)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/Intervals.cpp292
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/Justifier.cpp (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/Justifier.cpp)13
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/NameTable.cpp (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/NameTable.cpp)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/Pass.cpp (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/Pass.cpp)531
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/Position.cpp98
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/SegCache.cpp (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/SegCache.cpp)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/SegCacheEntry.cpp (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/SegCacheEntry.cpp)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/SegCacheStore.cpp (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/SegCacheStore.cpp)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/Segment.cpp (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/Segment.cpp)31
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/Silf.cpp (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/Silf.cpp)36
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/Slot.cpp (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/Slot.cpp)124
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/Sparse.cpp (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/Sparse.cpp)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/TtfUtil.cpp (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/TtfUtil.cpp)70
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/UtfCodec.cpp (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/UtfCodec.cpp)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/call_machine.cpp (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/call_machine.cpp)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/direct_machine.cpp (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/direct_machine.cpp)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/files.mk (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/files.mk)10
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/gr_char_info.cpp (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/gr_char_info.cpp)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/gr_face.cpp (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/gr_face.cpp)2
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/gr_features.cpp (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/gr_features.cpp)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/gr_font.cpp (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/gr_font.cpp)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/gr_logging.cpp (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/gr_logging.cpp)24
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/gr_segment.cpp (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/gr_segment.cpp)4
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/gr_slot.cpp (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/gr_slot.cpp)4
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Bidi.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Bidi.h)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/CachedFace.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/inc/CachedFace.h)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/CharInfo.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/inc/CharInfo.h)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/CmapCache.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/inc/CmapCache.h)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Code.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Code.h)26
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Collider.h220
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Decompressor.h52
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Endian.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Endian.h)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Error.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Error.h)23
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Face.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Face.h)13
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/FeatureMap.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/inc/FeatureMap.h)7
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/FeatureVal.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/inc/FeatureVal.h)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/FileFace.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/inc/FileFace.h)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Font.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Font.h)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/GlyphCache.h227
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/GlyphFace.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/inc/GlyphFace.h)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Intervals.h231
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/List.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/inc/List.h)13
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Machine.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Machine.h)6
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Main.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Main.h)5
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/NameTable.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/inc/NameTable.h)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Pass.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Pass.h)41
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Position.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Position.h)9
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Rule.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Rule.h)2
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/SegCache.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/inc/SegCache.h)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/SegCacheEntry.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/inc/SegCacheEntry.h)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/SegCacheStore.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/inc/SegCacheStore.h)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Segment.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Segment.h)25
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Shrinker.h119
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Silf.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Silf.h)12
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Slot.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Slot.h)7
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Sparse.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Sparse.h)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/TtfTypes.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/inc/TtfTypes.h)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/TtfUtil.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/inc/TtfUtil.h)4
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/UtfCodec.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/inc/UtfCodec.h)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/bits.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/inc/bits.h)64
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/debug.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/inc/debug.h)8
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/json.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/inc/json.h)7
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/locale2lcid.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/inc/locale2lcid.h)0
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/opcode_table.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/inc/opcode_table.h)7
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/inc/opcodes.h (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/inc/opcodes.h)52
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/json.cpp (renamed from Build/source/libs/graphite2/graphite2-1.2.4/src/json.cpp)16
-rw-r--r--Build/source/libs/graphite2/version.ac4
105 files changed, 3957 insertions, 536 deletions
diff --git a/Build/source/libs/graphite2/ChangeLog b/Build/source/libs/graphite2/ChangeLog
index 9e3cd4eaba5..84b7dab846d 100644
--- a/Build/source/libs/graphite2/ChangeLog
+++ b/Build/source/libs/graphite2/ChangeLog
@@ -1,3 +1,8 @@
+2015-08-05 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Import graphite2-1.3.0.
+ * Makefile.am, version.ac: Adapted.
+
2015-07-06 Peter Breitenlohner <peb@mppmu.mpg.de>
* Makefile.am: Better dependencies for 'make check'.
diff --git a/Build/source/libs/graphite2/Makefile.am b/Build/source/libs/graphite2/Makefile.am
index bb95ae3f59d..c4f4d22e582 100644
--- a/Build/source/libs/graphite2/Makefile.am
+++ b/Build/source/libs/graphite2/Makefile.am
@@ -33,15 +33,18 @@ libgraphite2_a_SOURCES = \
@GRAPHITE2_TREE@/src/CachedFace.cpp \
@GRAPHITE2_TREE@/src/CmapCache.cpp \
@GRAPHITE2_TREE@/src/Code.cpp \
+ @GRAPHITE2_TREE@/src/Collider.cpp \
+ @GRAPHITE2_TREE@/src/Decompressor.cpp \
@GRAPHITE2_TREE@/src/Face.cpp \
@GRAPHITE2_TREE@/src/FeatureMap.cpp \
@GRAPHITE2_TREE@/src/Font.cpp \
@GRAPHITE2_TREE@/src/GlyphCache.cpp \
@GRAPHITE2_TREE@/src/GlyphFace.cpp \
+ @GRAPHITE2_TREE@/src/Intervals.cpp \
@GRAPHITE2_TREE@/src/Justifier.cpp \
@GRAPHITE2_TREE@/src/NameTable.cpp \
@GRAPHITE2_TREE@/src/Pass.cpp \
- @GRAPHITE2_TREE@/src/Rule.cpp \
+ @GRAPHITE2_TREE@/src/Position.cpp \
@GRAPHITE2_TREE@/src/Segment.cpp \
@GRAPHITE2_TREE@/src/Silf.cpp \
@GRAPHITE2_TREE@/src/Slot.cpp \
@@ -54,42 +57,7 @@ libgraphite2_a_SOURCES = \
@GRAPHITE2_TREE@/src/gr_font.cpp \
@GRAPHITE2_TREE@/src/gr_logging.cpp \
@GRAPHITE2_TREE@/src/gr_segment.cpp \
- @GRAPHITE2_TREE@/src/gr_slot.cpp \
- @GRAPHITE2_TREE@/src/inc/CachedFace.h \
- @GRAPHITE2_TREE@/src/inc/CharInfo.h \
- @GRAPHITE2_TREE@/src/inc/CmapCache.h \
- @GRAPHITE2_TREE@/src/inc/Code.h \
- @GRAPHITE2_TREE@/src/inc/Endian.h \
- @GRAPHITE2_TREE@/src/inc/Face.h \
- @GRAPHITE2_TREE@/src/inc/FeatureMap.h \
- @GRAPHITE2_TREE@/src/inc/FeatureVal.h \
- @GRAPHITE2_TREE@/src/inc/FileFace.h \
- @GRAPHITE2_TREE@/src/inc/Font.h \
- @GRAPHITE2_TREE@/src/inc/GlyphCache.h \
- @GRAPHITE2_TREE@/src/inc/GlyphFace.h \
- @GRAPHITE2_TREE@/src/inc/List.h \
- @GRAPHITE2_TREE@/src/inc/Machine.h \
- @GRAPHITE2_TREE@/src/inc/Main.h \
- @GRAPHITE2_TREE@/src/inc/NameTable.h \
- @GRAPHITE2_TREE@/src/inc/Pass.h \
- @GRAPHITE2_TREE@/src/inc/Position.h \
- @GRAPHITE2_TREE@/src/inc/Rule.h \
- @GRAPHITE2_TREE@/src/inc/SegCache.h \
- @GRAPHITE2_TREE@/src/inc/SegCacheEntry.h \
- @GRAPHITE2_TREE@/src/inc/SegCacheStore.h \
- @GRAPHITE2_TREE@/src/inc/Segment.h \
- @GRAPHITE2_TREE@/src/inc/Silf.h \
- @GRAPHITE2_TREE@/src/inc/Slot.h \
- @GRAPHITE2_TREE@/src/inc/Sparse.h \
- @GRAPHITE2_TREE@/src/inc/TtfTypes.h \
- @GRAPHITE2_TREE@/src/inc/TtfUtil.h \
- @GRAPHITE2_TREE@/src/inc/UtfCodec.h \
- @GRAPHITE2_TREE@/src/inc/bits.h \
- @GRAPHITE2_TREE@/src/inc/debug.h \
- @GRAPHITE2_TREE@/src/inc/json.h \
- @GRAPHITE2_TREE@/src/inc/locale2lcid.h \
- @GRAPHITE2_TREE@/src/inc/opcode_table.h \
- @GRAPHITE2_TREE@/src/inc/opcodes.h
+ @GRAPHITE2_TREE@/src/gr_slot.cpp
if DIRECT_TYPE
libgraphite2_a_SOURCES += @GRAPHITE2_TREE@/src/direct_machine.cpp
diff --git a/Build/source/libs/graphite2/Makefile.in b/Build/source/libs/graphite2/Makefile.in
index c119e263733..cdaa56406f1 100644
--- a/Build/source/libs/graphite2/Makefile.in
+++ b/Build/source/libs/graphite2/Makefile.in
@@ -127,14 +127,19 @@ libgraphite2_a_LIBADD =
am__libgraphite2_a_SOURCES_DIST = @GRAPHITE2_TREE@/src/Bidi.cpp \
@GRAPHITE2_TREE@/src/CachedFace.cpp \
@GRAPHITE2_TREE@/src/CmapCache.cpp \
- @GRAPHITE2_TREE@/src/Code.cpp @GRAPHITE2_TREE@/src/Face.cpp \
+ @GRAPHITE2_TREE@/src/Code.cpp \
+ @GRAPHITE2_TREE@/src/Collider.cpp \
+ @GRAPHITE2_TREE@/src/Decompressor.cpp \
+ @GRAPHITE2_TREE@/src/Face.cpp \
@GRAPHITE2_TREE@/src/FeatureMap.cpp \
@GRAPHITE2_TREE@/src/Font.cpp \
@GRAPHITE2_TREE@/src/GlyphCache.cpp \
@GRAPHITE2_TREE@/src/GlyphFace.cpp \
+ @GRAPHITE2_TREE@/src/Intervals.cpp \
@GRAPHITE2_TREE@/src/Justifier.cpp \
@GRAPHITE2_TREE@/src/NameTable.cpp \
- @GRAPHITE2_TREE@/src/Pass.cpp @GRAPHITE2_TREE@/src/Rule.cpp \
+ @GRAPHITE2_TREE@/src/Pass.cpp \
+ @GRAPHITE2_TREE@/src/Position.cpp \
@GRAPHITE2_TREE@/src/Segment.cpp @GRAPHITE2_TREE@/src/Silf.cpp \
@GRAPHITE2_TREE@/src/Slot.cpp @GRAPHITE2_TREE@/src/Sparse.cpp \
@GRAPHITE2_TREE@/src/TtfUtil.cpp \
@@ -146,41 +151,6 @@ am__libgraphite2_a_SOURCES_DIST = @GRAPHITE2_TREE@/src/Bidi.cpp \
@GRAPHITE2_TREE@/src/gr_logging.cpp \
@GRAPHITE2_TREE@/src/gr_segment.cpp \
@GRAPHITE2_TREE@/src/gr_slot.cpp \
- @GRAPHITE2_TREE@/src/inc/CachedFace.h \
- @GRAPHITE2_TREE@/src/inc/CharInfo.h \
- @GRAPHITE2_TREE@/src/inc/CmapCache.h \
- @GRAPHITE2_TREE@/src/inc/Code.h \
- @GRAPHITE2_TREE@/src/inc/Endian.h \
- @GRAPHITE2_TREE@/src/inc/Face.h \
- @GRAPHITE2_TREE@/src/inc/FeatureMap.h \
- @GRAPHITE2_TREE@/src/inc/FeatureVal.h \
- @GRAPHITE2_TREE@/src/inc/FileFace.h \
- @GRAPHITE2_TREE@/src/inc/Font.h \
- @GRAPHITE2_TREE@/src/inc/GlyphCache.h \
- @GRAPHITE2_TREE@/src/inc/GlyphFace.h \
- @GRAPHITE2_TREE@/src/inc/List.h \
- @GRAPHITE2_TREE@/src/inc/Machine.h \
- @GRAPHITE2_TREE@/src/inc/Main.h \
- @GRAPHITE2_TREE@/src/inc/NameTable.h \
- @GRAPHITE2_TREE@/src/inc/Pass.h \
- @GRAPHITE2_TREE@/src/inc/Position.h \
- @GRAPHITE2_TREE@/src/inc/Rule.h \
- @GRAPHITE2_TREE@/src/inc/SegCache.h \
- @GRAPHITE2_TREE@/src/inc/SegCacheEntry.h \
- @GRAPHITE2_TREE@/src/inc/SegCacheStore.h \
- @GRAPHITE2_TREE@/src/inc/Segment.h \
- @GRAPHITE2_TREE@/src/inc/Silf.h \
- @GRAPHITE2_TREE@/src/inc/Slot.h \
- @GRAPHITE2_TREE@/src/inc/Sparse.h \
- @GRAPHITE2_TREE@/src/inc/TtfTypes.h \
- @GRAPHITE2_TREE@/src/inc/TtfUtil.h \
- @GRAPHITE2_TREE@/src/inc/UtfCodec.h \
- @GRAPHITE2_TREE@/src/inc/bits.h \
- @GRAPHITE2_TREE@/src/inc/debug.h \
- @GRAPHITE2_TREE@/src/inc/json.h \
- @GRAPHITE2_TREE@/src/inc/locale2lcid.h \
- @GRAPHITE2_TREE@/src/inc/opcode_table.h \
- @GRAPHITE2_TREE@/src/inc/opcodes.h \
@GRAPHITE2_TREE@/src/direct_machine.cpp \
@GRAPHITE2_TREE@/src/call_machine.cpp \
@GRAPHITE2_TREE@/src/SegCache.cpp \
@@ -203,15 +173,18 @@ am_libgraphite2_a_OBJECTS = @GRAPHITE2_TREE@/src/Bidi.$(OBJEXT) \
@GRAPHITE2_TREE@/src/CachedFace.$(OBJEXT) \
@GRAPHITE2_TREE@/src/CmapCache.$(OBJEXT) \
@GRAPHITE2_TREE@/src/Code.$(OBJEXT) \
+ @GRAPHITE2_TREE@/src/Collider.$(OBJEXT) \
+ @GRAPHITE2_TREE@/src/Decompressor.$(OBJEXT) \
@GRAPHITE2_TREE@/src/Face.$(OBJEXT) \
@GRAPHITE2_TREE@/src/FeatureMap.$(OBJEXT) \
@GRAPHITE2_TREE@/src/Font.$(OBJEXT) \
@GRAPHITE2_TREE@/src/GlyphCache.$(OBJEXT) \
@GRAPHITE2_TREE@/src/GlyphFace.$(OBJEXT) \
+ @GRAPHITE2_TREE@/src/Intervals.$(OBJEXT) \
@GRAPHITE2_TREE@/src/Justifier.$(OBJEXT) \
@GRAPHITE2_TREE@/src/NameTable.$(OBJEXT) \
@GRAPHITE2_TREE@/src/Pass.$(OBJEXT) \
- @GRAPHITE2_TREE@/src/Rule.$(OBJEXT) \
+ @GRAPHITE2_TREE@/src/Position.$(OBJEXT) \
@GRAPHITE2_TREE@/src/Segment.$(OBJEXT) \
@GRAPHITE2_TREE@/src/Silf.$(OBJEXT) \
@GRAPHITE2_TREE@/src/Slot.$(OBJEXT) \
@@ -691,14 +664,19 @@ AM_CPPFLAGS = -I$(top_srcdir)/$(GRAPHITE2_SRC) \
libgraphite2_a_SOURCES = @GRAPHITE2_TREE@/src/Bidi.cpp \
@GRAPHITE2_TREE@/src/CachedFace.cpp \
@GRAPHITE2_TREE@/src/CmapCache.cpp \
- @GRAPHITE2_TREE@/src/Code.cpp @GRAPHITE2_TREE@/src/Face.cpp \
+ @GRAPHITE2_TREE@/src/Code.cpp \
+ @GRAPHITE2_TREE@/src/Collider.cpp \
+ @GRAPHITE2_TREE@/src/Decompressor.cpp \
+ @GRAPHITE2_TREE@/src/Face.cpp \
@GRAPHITE2_TREE@/src/FeatureMap.cpp \
@GRAPHITE2_TREE@/src/Font.cpp \
@GRAPHITE2_TREE@/src/GlyphCache.cpp \
@GRAPHITE2_TREE@/src/GlyphFace.cpp \
+ @GRAPHITE2_TREE@/src/Intervals.cpp \
@GRAPHITE2_TREE@/src/Justifier.cpp \
@GRAPHITE2_TREE@/src/NameTable.cpp \
- @GRAPHITE2_TREE@/src/Pass.cpp @GRAPHITE2_TREE@/src/Rule.cpp \
+ @GRAPHITE2_TREE@/src/Pass.cpp \
+ @GRAPHITE2_TREE@/src/Position.cpp \
@GRAPHITE2_TREE@/src/Segment.cpp @GRAPHITE2_TREE@/src/Silf.cpp \
@GRAPHITE2_TREE@/src/Slot.cpp @GRAPHITE2_TREE@/src/Sparse.cpp \
@GRAPHITE2_TREE@/src/TtfUtil.cpp \
@@ -709,42 +687,7 @@ libgraphite2_a_SOURCES = @GRAPHITE2_TREE@/src/Bidi.cpp \
@GRAPHITE2_TREE@/src/gr_font.cpp \
@GRAPHITE2_TREE@/src/gr_logging.cpp \
@GRAPHITE2_TREE@/src/gr_segment.cpp \
- @GRAPHITE2_TREE@/src/gr_slot.cpp \
- @GRAPHITE2_TREE@/src/inc/CachedFace.h \
- @GRAPHITE2_TREE@/src/inc/CharInfo.h \
- @GRAPHITE2_TREE@/src/inc/CmapCache.h \
- @GRAPHITE2_TREE@/src/inc/Code.h \
- @GRAPHITE2_TREE@/src/inc/Endian.h \
- @GRAPHITE2_TREE@/src/inc/Face.h \
- @GRAPHITE2_TREE@/src/inc/FeatureMap.h \
- @GRAPHITE2_TREE@/src/inc/FeatureVal.h \
- @GRAPHITE2_TREE@/src/inc/FileFace.h \
- @GRAPHITE2_TREE@/src/inc/Font.h \
- @GRAPHITE2_TREE@/src/inc/GlyphCache.h \
- @GRAPHITE2_TREE@/src/inc/GlyphFace.h \
- @GRAPHITE2_TREE@/src/inc/List.h \
- @GRAPHITE2_TREE@/src/inc/Machine.h \
- @GRAPHITE2_TREE@/src/inc/Main.h \
- @GRAPHITE2_TREE@/src/inc/NameTable.h \
- @GRAPHITE2_TREE@/src/inc/Pass.h \
- @GRAPHITE2_TREE@/src/inc/Position.h \
- @GRAPHITE2_TREE@/src/inc/Rule.h \
- @GRAPHITE2_TREE@/src/inc/SegCache.h \
- @GRAPHITE2_TREE@/src/inc/SegCacheEntry.h \
- @GRAPHITE2_TREE@/src/inc/SegCacheStore.h \
- @GRAPHITE2_TREE@/src/inc/Segment.h \
- @GRAPHITE2_TREE@/src/inc/Silf.h \
- @GRAPHITE2_TREE@/src/inc/Slot.h \
- @GRAPHITE2_TREE@/src/inc/Sparse.h \
- @GRAPHITE2_TREE@/src/inc/TtfTypes.h \
- @GRAPHITE2_TREE@/src/inc/TtfUtil.h \
- @GRAPHITE2_TREE@/src/inc/UtfCodec.h \
- @GRAPHITE2_TREE@/src/inc/bits.h \
- @GRAPHITE2_TREE@/src/inc/debug.h \
- @GRAPHITE2_TREE@/src/inc/json.h \
- @GRAPHITE2_TREE@/src/inc/locale2lcid.h \
- @GRAPHITE2_TREE@/src/inc/opcode_table.h \
- @GRAPHITE2_TREE@/src/inc/opcodes.h $(am__append_1) \
+ @GRAPHITE2_TREE@/src/gr_slot.cpp $(am__append_1) \
$(am__append_2) $(am__append_3) $(am__append_5) \
$(am__append_7)
@build_TRUE@dist_check_SCRIPTS = graphite2.test
@@ -835,6 +778,12 @@ clean-noinstLIBRARIES:
@GRAPHITE2_TREE@/src/Code.$(OBJEXT): \
@GRAPHITE2_TREE@/src/$(am__dirstamp) \
@GRAPHITE2_TREE@/src/$(DEPDIR)/$(am__dirstamp)
+@GRAPHITE2_TREE@/src/Collider.$(OBJEXT): \
+ @GRAPHITE2_TREE@/src/$(am__dirstamp) \
+ @GRAPHITE2_TREE@/src/$(DEPDIR)/$(am__dirstamp)
+@GRAPHITE2_TREE@/src/Decompressor.$(OBJEXT): \
+ @GRAPHITE2_TREE@/src/$(am__dirstamp) \
+ @GRAPHITE2_TREE@/src/$(DEPDIR)/$(am__dirstamp)
@GRAPHITE2_TREE@/src/Face.$(OBJEXT): \
@GRAPHITE2_TREE@/src/$(am__dirstamp) \
@GRAPHITE2_TREE@/src/$(DEPDIR)/$(am__dirstamp)
@@ -850,6 +799,9 @@ clean-noinstLIBRARIES:
@GRAPHITE2_TREE@/src/GlyphFace.$(OBJEXT): \
@GRAPHITE2_TREE@/src/$(am__dirstamp) \
@GRAPHITE2_TREE@/src/$(DEPDIR)/$(am__dirstamp)
+@GRAPHITE2_TREE@/src/Intervals.$(OBJEXT): \
+ @GRAPHITE2_TREE@/src/$(am__dirstamp) \
+ @GRAPHITE2_TREE@/src/$(DEPDIR)/$(am__dirstamp)
@GRAPHITE2_TREE@/src/Justifier.$(OBJEXT): \
@GRAPHITE2_TREE@/src/$(am__dirstamp) \
@GRAPHITE2_TREE@/src/$(DEPDIR)/$(am__dirstamp)
@@ -859,7 +811,7 @@ clean-noinstLIBRARIES:
@GRAPHITE2_TREE@/src/Pass.$(OBJEXT): \
@GRAPHITE2_TREE@/src/$(am__dirstamp) \
@GRAPHITE2_TREE@/src/$(DEPDIR)/$(am__dirstamp)
-@GRAPHITE2_TREE@/src/Rule.$(OBJEXT): \
+@GRAPHITE2_TREE@/src/Position.$(OBJEXT): \
@GRAPHITE2_TREE@/src/$(am__dirstamp) \
@GRAPHITE2_TREE@/src/$(DEPDIR)/$(am__dirstamp)
@GRAPHITE2_TREE@/src/Segment.$(OBJEXT): \
@@ -948,16 +900,19 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@@GRAPHITE2_TREE@/src/$(DEPDIR)/CachedFace.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@@GRAPHITE2_TREE@/src/$(DEPDIR)/CmapCache.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@@GRAPHITE2_TREE@/src/$(DEPDIR)/Code.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@@GRAPHITE2_TREE@/src/$(DEPDIR)/Collider.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@@GRAPHITE2_TREE@/src/$(DEPDIR)/Decompressor.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@@GRAPHITE2_TREE@/src/$(DEPDIR)/Face.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@@GRAPHITE2_TREE@/src/$(DEPDIR)/FeatureMap.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@@GRAPHITE2_TREE@/src/$(DEPDIR)/FileFace.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@@GRAPHITE2_TREE@/src/$(DEPDIR)/Font.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@@GRAPHITE2_TREE@/src/$(DEPDIR)/GlyphCache.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@@GRAPHITE2_TREE@/src/$(DEPDIR)/GlyphFace.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@@GRAPHITE2_TREE@/src/$(DEPDIR)/Intervals.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@@GRAPHITE2_TREE@/src/$(DEPDIR)/Justifier.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@@GRAPHITE2_TREE@/src/$(DEPDIR)/NameTable.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@@GRAPHITE2_TREE@/src/$(DEPDIR)/Pass.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@@GRAPHITE2_TREE@/src/$(DEPDIR)/Rule.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@@GRAPHITE2_TREE@/src/$(DEPDIR)/Position.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@@GRAPHITE2_TREE@/src/$(DEPDIR)/SegCache.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@@GRAPHITE2_TREE@/src/$(DEPDIR)/SegCacheEntry.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@@GRAPHITE2_TREE@/src/$(DEPDIR)/SegCacheStore.Po@am__quote@
diff --git a/Build/source/libs/graphite2/configure b/Build/source/libs/graphite2/configure
index f2b52ff0e75..0311bf9c748 100755
--- a/Build/source/libs/graphite2/configure
+++ b/Build/source/libs/graphite2/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for graphite2 (TeX Live) 1.2.4.
+# Generated by GNU Autoconf 2.69 for graphite2 (TeX Live) 1.3.0.
#
# Report bugs to <tex-k@tug.org>.
#
@@ -579,12 +579,12 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='graphite2 (TeX Live)'
PACKAGE_TARNAME='graphite2--tex-live-'
-PACKAGE_VERSION='1.2.4'
-PACKAGE_STRING='graphite2 (TeX Live) 1.2.4'
+PACKAGE_VERSION='1.3.0'
+PACKAGE_STRING='graphite2 (TeX Live) 1.3.0'
PACKAGE_BUGREPORT='tex-k@tug.org'
PACKAGE_URL=''
-ac_unique_file="graphite2-1.2.4/graphite2.pc.in"
+ac_unique_file="graphite2-1.3.0/graphite2.pc.in"
ac_subst_vars='am__EXEEXT_FALSE
am__EXEEXT_TRUE
LTLIBOBJS
@@ -1254,7 +1254,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures graphite2 (TeX Live) 1.2.4 to adapt to many kinds of systems.
+\`configure' configures graphite2 (TeX Live) 1.3.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1321,7 +1321,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of graphite2 (TeX Live) 1.2.4:";;
+ short | recursive ) echo "Configuration of graphite2 (TeX Live) 1.3.0:";;
esac
cat <<\_ACEOF
@@ -1419,7 +1419,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-graphite2 (TeX Live) configure 1.2.4
+graphite2 (TeX Live) configure 1.3.0
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1558,7 +1558,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by graphite2 (TeX Live) $as_me 1.2.4, which was
+It was created by graphite2 (TeX Live) $as_me 1.3.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -3481,7 +3481,7 @@ fi
# Define the identity of the package.
PACKAGE='graphite2--tex-live-'
- VERSION='1.2.4'
+ VERSION='1.3.0'
cat >>confdefs.h <<_ACEOF
@@ -5009,7 +5009,7 @@ $as_echo "#define GRAPHITE2_NTRACING 1" >>confdefs.h
fi
-GRAPHITE2_TREE=graphite2-1.2.4
+GRAPHITE2_TREE=graphite2-1.3.0
ac_config_files="$ac_config_files Makefile include/graphite2/Makefile"
@@ -5577,7 +5577,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by graphite2 (TeX Live) $as_me 1.2.4, which was
+This file was extended by graphite2 (TeX Live) $as_me 1.3.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -5643,7 +5643,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-graphite2 (TeX Live) config.status 1.2.4
+graphite2 (TeX Live) config.status 1.3.0
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/.hg_archival.txt b/Build/source/libs/graphite2/graphite2-1.2.4/.hg_archival.txt
deleted file mode 100644
index dc9ddb46d6c..00000000000
--- a/Build/source/libs/graphite2/graphite2-1.2.4/.hg_archival.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-repo: 999e2033695c3bcf2f65d611737ac9008805bd58
-node: 1efd96aeade964b4d00b7b14e6158a74f0f6593e
-branch: default
-latesttag: 1.2.4
-latesttagdistance: 1
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/Todo.txt b/Build/source/libs/graphite2/graphite2-1.2.4/Todo.txt
deleted file mode 100644
index de9d36157e8..00000000000
--- a/Build/source/libs/graphite2/graphite2-1.2.4/Todo.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Expected changes to come:
-
-* None
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/Rule.cpp b/Build/source/libs/graphite2/graphite2-1.2.4/src/Rule.cpp
deleted file mode 100644
index 34c8ae1691f..00000000000
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/Rule.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-/* GRAPHITE2 LICENSING
-
- Copyright 2011, SIL International
- All rights reserved.
-
- This library is free software; you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published
- by the Free Software Foundation; either version 2.1 of License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should also have received a copy of the GNU Lesser General Public
- License along with this library in the file named "LICENSE".
- If not, write to the Free Software Foundation, 51 Franklin Street,
- Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
- internet at http://www.fsf.org/licenses/lgpl.html.
-
-Alternatively, the contents of this file may be used under the terms of the
-Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
-License, as published by the Free Software Foundation, either version 2
-of the License or (at your option) any later version.
-*/
-
-#include "inc/Rule.h"
-#include "inc/Segment.h"
-
-using namespace graphite2;
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/GlyphCache.h b/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/GlyphCache.h
deleted file mode 100644
index ab5b0b7c5fe..00000000000
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/GlyphCache.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/* GRAPHITE2 LICENSING
-
- Copyright 2012, SIL International
- All rights reserved.
-
- This library is free software; you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published
- by the Free Software Foundation; either version 2.1 of License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should also have received a copy of the GNU Lesser General Public
- License along with this library in the file named "LICENSE".
- If not, write to the Free Software Foundation, 51 Franklin Street,
- Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
- internet at http://www.fsf.org/licenses/lgpl.html.
-
-Alternatively, the contents of this file may be used under the terms of the
-Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
-License, as published by the Free Software Foundation, either version 2
-of the License or (at your option) any later version.
-*/
-#pragma once
-
-
-#include "graphite2/Font.h"
-#include "inc/Main.h"
-
-namespace graphite2 {
-
-class Face;
-class FeatureVal;
-class GlyphFace;
-class Segment;
-
-class GlyphCache
-{
- class Loader;
-
- GlyphCache(const GlyphCache&);
- GlyphCache& operator=(const GlyphCache&);
-
-public:
- GlyphCache(const Face & face, const uint32 face_options);
- ~GlyphCache();
-
- unsigned short numGlyphs() const throw();
- unsigned short numAttrs() const throw();
- unsigned short unitsPerEm() const throw();
-
- const GlyphFace *glyph(unsigned short glyphid) const; //result may be changed by subsequent call with a different glyphid
- const GlyphFace *glyphSafe(unsigned short glyphid) const;
-
- CLASS_NEW_DELETE;
-
-private:
- const Loader * _glyph_loader;
- const GlyphFace * * _glyphs;
- unsigned short _num_glyphs,
- _num_attrs,
- _upem;
-};
-
-inline
-unsigned short GlyphCache::numGlyphs() const throw()
-{
- return _num_glyphs;
-}
-
-inline
-unsigned short GlyphCache::numAttrs() const throw()
-{
- return _num_attrs;
-}
-
-inline
-unsigned short GlyphCache::unitsPerEm() const throw()
-{
- return _upem;
-}
-
-inline
-const GlyphFace *GlyphCache::glyphSafe(unsigned short glyphid) const
-{
- return glyphid < _num_glyphs ? glyph(glyphid) : NULL;
-}
-
-} // namespace graphite2
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4-PATCHES/ChangeLog b/Build/source/libs/graphite2/graphite2-1.3.0-PATCHES/ChangeLog
index 8d3061edbaf..8d3061edbaf 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4-PATCHES/ChangeLog
+++ b/Build/source/libs/graphite2/graphite2-1.3.0-PATCHES/ChangeLog
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4-PATCHES/TL-Changes b/Build/source/libs/graphite2/graphite2-1.3.0-PATCHES/TL-Changes
index 1bc60f09413..ed4929234d6 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4-PATCHES/TL-Changes
+++ b/Build/source/libs/graphite2/graphite2-1.3.0-PATCHES/TL-Changes
@@ -1,4 +1,4 @@
-Changes applied to the graphite2-1.2.4/ tree as obtained from:
+Changes applied to the graphite2-1.3.0/ tree as obtained from:
http://sourceforge.net/projects/silgraphite/files/graphite2/
Removed unused dirs:
diff --git a/Build/source/libs/graphite2/graphite2-1.3.0/.hg_archival.txt b/Build/source/libs/graphite2/graphite2-1.3.0/.hg_archival.txt
new file mode 100644
index 00000000000..9f3710093ce
--- /dev/null
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/.hg_archival.txt
@@ -0,0 +1,5 @@
+repo: 999e2033695c3bcf2f65d611737ac9008805bd58
+node: 9766cf4dec9c25358d01a074ec64408f257fff74
+branch: default
+latesttag: coll_1
+latesttagdistance: 223
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/.hgeol b/Build/source/libs/graphite2/graphite2-1.3.0/.hgeol
index 5eb1fc19d0f..5eb1fc19d0f 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/.hgeol
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/.hgeol
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/.hgignore b/Build/source/libs/graphite2/graphite2-1.3.0/.hgignore
index 5934da4b3c8..59c168c2179 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/.hgignore
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/.hgignore
@@ -20,6 +20,8 @@ nmake*
*.swp
*.la
*.kdev4
+*.orig
+*.pyc
.cproject
.project
.pydevproject
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/.hgtags b/Build/source/libs/graphite2/graphite2-1.3.0/.hgtags
index 5a66aa21918..b945112535c 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/.hgtags
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/.hgtags
@@ -29,3 +29,5 @@ fb4b0c347a953f6aa656a4e414f8e42e91c00c2b 1.2.0
7b0a153b4873117ff726ac8c780f7bd994845285 1.2.2
4605b74e26f3a119753b700524c49b98e7e45639 1.2.3
89895200933d3b0ce799b2d230dd6840106750b1 1.2.4
+5f1e36a3b3b8a7c115ec334741fd83f33b59811c collisions.phase1
+4c5cb2d670c991e6fc13f42d2180b6d693c21dad coll_1
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/CMakeLists.txt b/Build/source/libs/graphite2/graphite2-1.3.0/CMakeLists.txt
index b09e95f4456..b09e95f4456 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/CMakeLists.txt
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/CMakeLists.txt
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/COPYING b/Build/source/libs/graphite2/graphite2-1.3.0/COPYING
index d40f2d84587..d40f2d84587 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/COPYING
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/COPYING
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/ChangeLog b/Build/source/libs/graphite2/graphite2-1.3.0/ChangeLog
index f0e88d60a23..1fa0babb034 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/ChangeLog
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/ChangeLog
@@ -1,3 +1,13 @@
+1.3.0
+ . Add collision avoidance
+ . Shift Collider
+ . Kern Collider
+ . Octabox outlines and subboxes
+ . Add compressed Silf and Glat table support
+ . Bug fixes:
+ . Stop loops forming in the child, sibling tree
+ . Handle bidi mirroring correctly if no bidi occurring
+
1.2.4
. Face failure now has error code reporting via debug logging
. can now call gr_start_logging(NULL, fname)
@@ -8,7 +18,7 @@
. Fonts no longer require a glyf/loca table. In such cases the bounding box is always 0.
. Clang ASAN build support added for testing.
. Handle out of memory sanely.
- . Dcoumentation improvements
+ . Documentation improvements
. Bug fixes:
. Enforce fonts having to store glyph attributes by monotonically increasing attribute number
. zeropadding was not getting called on feature tags
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/Graphite.cmake b/Build/source/libs/graphite2/graphite2-1.3.0/Graphite.cmake
index 1fd3a4e6888..c2f4377d026 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/Graphite.cmake
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/Graphite.cmake
@@ -105,3 +105,14 @@ function(feattest TESTNAME FONTFILE)
endif (NOT (GRAPHITE2_NSEGCACHE OR GRAPHITE2_NFILEFACE))
endfunction(feattest)
+function(cmptest TESTNAME FONTFILE TEXTFILE)
+ if (EXISTS ${PROJECT_SOURCE_DIR}/standards/${TESTNAME}${CMAKE_SYSTEM_NAME}.json)
+ set(PLATFORM_TEST_SUFFIX ${CMAKE_SYSTEM_NAME})
+ endif (EXISTS ${PROJECT_SOURCE_DIR}/standards/${TESTNAME}${CMAKE_SYSTEM_NAME}.json)
+ if (NOT (GRAPHITE2_NFILEFACE))
+ add_test(NAME ${TESTNAME} COMMAND python ${PROJECT_SOURCE_DIR}/fnttxtrender -t ${PROJECT_SOURCE_DIR}/texts/${TEXTFILE} -o ${PROJECT_BINARY_DIR}/${TESTNAME}.json -c ${PROJECT_SOURCE_DIR}/standards/${TESTNAME}${PLATFORM_TEST_SUFFIX}.json ${ARGN} ${PROJECT_SOURCE_DIR}/fonts/${FONTFILE})
+ set_tests_properties(${TESTNAME} PROPERTIES TIMEOUT 10)
+ endif (NOT (GRAPHITE2_NFILEFACE))
+endfunction(cmptest)
+
+
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/LICENSE b/Build/source/libs/graphite2/graphite2-1.3.0/LICENSE
index 2d2d780e601..2d2d780e601 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/LICENSE
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/LICENSE
diff --git a/Build/source/libs/graphite2/graphite2-1.3.0/Todo.txt b/Build/source/libs/graphite2/graphite2-1.3.0/Todo.txt
new file mode 100644
index 00000000000..55299b10a1f
--- /dev/null
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/Todo.txt
@@ -0,0 +1,13 @@
+Expected changes to come:
+
+* Collision avoidance
+ * Slot Collider
+ * Kern Collider
+ * Associated glyph for exclusion
+ * bounding octabox and subboxes
+* FSM compression
+* Setting segment feature values in action code, for pass constraint testing
+* Move gralloc/realloc from once per rule to once per pass to speed up font loading.
+
+Questions:
+* Do we support glyphid as a slot attribute?
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/graphite2.pc.in b/Build/source/libs/graphite2/graphite2-1.3.0/graphite2.pc.in
index a4f19b39ce4..a4f19b39ce4 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/graphite2.pc.in
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/graphite2.pc.in
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/include/graphite2/Font.h b/Build/source/libs/graphite2/graphite2-1.3.0/include/graphite2/Font.h
index 72e8461eafb..fcbfc9d682c 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/include/graphite2/Font.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/include/graphite2/Font.h
@@ -29,8 +29,8 @@
#include "graphite2/Types.h"
#define GR2_VERSION_MAJOR 1
-#define GR2_VERSION_MINOR 2
-#define GR2_VERSION_BUGFIX 4
+#define GR2_VERSION_MINOR 3
+#define GR2_VERSION_BUGFIX 0
#ifdef __cplusplus
extern "C"
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/include/graphite2/Log.h b/Build/source/libs/graphite2/graphite2-1.3.0/include/graphite2/Log.h
index d1c6f0fe36f..d1c6f0fe36f 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/include/graphite2/Log.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/include/graphite2/Log.h
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/include/graphite2/Segment.h b/Build/source/libs/graphite2/graphite2-1.3.0/include/graphite2/Segment.h
index c89df5e8811..afcff7492a8 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/include/graphite2/Segment.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/include/graphite2/Segment.h
@@ -120,13 +120,45 @@ enum gr_attrCode {
/// Justification weight for this glyph (not implemented)
gr_slatJWeight,
/// Amount this slot mush shrink or stretch in design units
- gr_slatJWidth,
+ gr_slatJWidth = 29,
/// SubSegment split point
gr_slatSegSplit = gr_slatJStretch + 29,
/// User defined attribute, see subattr for user attr number
gr_slatUserDefn,
/// Bidi level
- gr_slatBidiLevel,
+ gr_slatBidiLevel = 56,
+ /// Collision flags
+ gr_slatColFlags,
+ /// Collision constraint rectangle left (bl.x)
+ gr_slatColLimitblx,
+ /// Collision constraint rectangle lower (bl.y)
+ gr_slatColLimitbly,
+ /// Collision constraint rectangle right (tr.x)
+ gr_slatColLimittrx,
+ /// Collision constraint rectangle upper (tr.y)
+ gr_slatColLimittry,
+ /// Collision shift x
+ gr_slatColShiftx,
+ /// Collision shift y
+ gr_slatColShifty,
+ /// Collision margin
+ gr_slatColMargin,
+ /// Margin cost weight
+ gr_slatColMarginWt,
+ // Additional glyph that excludes movement near this one:
+ gr_slatColExclGlyph,
+ gr_slatColExclOffx,
+ gr_slatColExclOffy,
+ // Collision sequence enforcing attributes:
+ gr_slatSeqClass,
+ gr_slatSeqProxClass,
+ gr_slatSeqOrder,
+ gr_slatSeqAboveXoff,
+ gr_slatSeqAboveWt,
+ gr_slatSeqBelowXlim,
+ gr_slatSeqBelowWt,
+ gr_slatSeqValignHt,
+ gr_slatSeqValignWt,
/// not implemented
gr_slatMax,
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/include/graphite2/Types.h b/Build/source/libs/graphite2/graphite2-1.3.0/include/graphite2/Types.h
index 268bee7a975..e8e45c1ff8f 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/include/graphite2/Types.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/include/graphite2/Types.h
@@ -58,12 +58,15 @@ enum gr_encform {
#endif
#endif
#define GR2_LOCAL
-#else
- #if __GNUC__ >= 4
- #define GR2_API __attribute__ ((visibility("default")))
- #define GR2_LOCAL __attribute__ ((visibility("hidden")))
+#elif __GNUC__ >= 4
+ #if defined GRAPHITE2_STATIC
+ #define GR2_API __attribute__ ((visibility("hidden")))
#else
- #define GR2_API
- #define GR2_LOCAL
+ #define GR2_API __attribute__ ((visibility("default")))
#endif
+ #define GR2_LOCAL __attribute__ ((visibility("hidden")))
+#else
+ #define GR2_API
+ #define GR2_LOCAL
#endif
+
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/Bidi.cpp b/Build/source/libs/graphite2/graphite2-1.3.0/src/Bidi.cpp
index 530f51abc1d..e26db2531c3 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/Bidi.cpp
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/Bidi.cpp
@@ -62,8 +62,8 @@ enum DirCode { // Hungarian: dirc
};
enum DirMask {
- WSflag = (1 << 7), // keep track of WS for eos handling
- WSMask = ~(1 << 7)
+ WSflag = int8(1 << 7), // keep track of WS for eos handling
+ WSMask = int8(~(1 << 7))
};
inline uint8 BaseClass(Slot *s) { return s->getBidiClass() & WSMask; }
@@ -540,7 +540,7 @@ void processParens(Slot *s, Segment *seg, uint8 aMirror, int level, BracketPairS
BracketPair *p;
for ( ; s; s = s->prev()) // walk the sequence
{
- uint16 ogid = seg->glyphAttr(s->gid(), aMirror);
+ uint16 ogid = seg->glyphAttr(s->gid(), aMirror) || s->gid();
int cls = BaseClass(s);
switch(cls)
@@ -571,35 +571,38 @@ void processParens(Slot *s, Segment *seg, uint8 aMirror, int level, BracketPairS
mask |= 2;
}
}
- for (p = stack.start(); p; p =p->next()) // walk the stack
+ if (stack.size())
{
- if (p->close() && p->mask())
+ for (p = stack.start(); p; p =p->next()) // walk the stack
{
- int dir = (level & 1) + 1;
- if (p->mask() & dir)
- { }
- else if (p->mask() & (1 << (~level & 1))) // if inside has strong other embedding
+ if (p->close() && p->mask())
{
- int ldir = p->before();
- if ((p->before() == OPP || p->before() == CPP) && p->prev())
+ int dir = (level & 1) + 1;
+ if (p->mask() & dir)
+ { }
+ else if (p->mask() & (1 << (~level & 1))) // if inside has strong other embedding
{
- for (BracketPair *q = p->prev(); q; q = q->prev())
+ int ldir = p->before();
+ if ((p->before() == OPP || p->before() == CPP) && p->prev())
{
- ldir = q->open()->getBidiClass();
- if (ldir < 3) break;
- ldir = q->before();
- if (ldir < 3) break;
+ for (BracketPair *q = p->prev(); q; q = q->prev())
+ {
+ ldir = q->open()->getBidiClass();
+ if (ldir < 3) break;
+ ldir = q->before();
+ if (ldir < 3) break;
+ }
+ if (ldir > 2) ldir = 0;
}
- if (ldir > 2) ldir = 0;
+ if (ldir > 0 && (ldir - 1) != (level & 1)) // is dir given opp. to level dir (ldir == R or L)
+ dir = (~level & 1) + 1;
}
- if (ldir > 0 && (ldir - 1) != (level & 1)) // is dir given opp. to level dir (ldir == R or L)
- dir = (~level & 1) + 1;
+ p->open()->setBidiClass(dir);
+ p->close()->setBidiClass(dir);
}
- p->open()->setBidiClass(dir);
- p->close()->setBidiClass(dir);
}
+ stack.clear();
}
- stack.clear();
}
int GetDeferredNeutrals(int action, int level)
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/CMakeLists.txt b/Build/source/libs/graphite2/graphite2-1.3.0/src/CMakeLists.txt
index f785070830a..336dd8cc796 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/CMakeLists.txt
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/CMakeLists.txt
@@ -78,15 +78,18 @@ add_library(graphite2 SHARED
CachedFace.cpp
CmapCache.cpp
Code.cpp
+ Collider.cpp
+ Decompressor.cpp
Face.cpp
FeatureMap.cpp
Font.cpp
GlyphFace.cpp
GlyphCache.cpp
+ Intervals.cpp
Justifier.cpp
NameTable.cpp
Pass.cpp
- Rule.cpp
+ Position.cpp
Segment.cpp
Silf.cpp
Slot.cpp
@@ -112,7 +115,7 @@ endif (${CMAKE_BUILD_TYPE} STREQUAL "ClangASN")
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
set_target_properties(graphite2 PROPERTIES
- COMPILE_FLAGS "-Wall -Wextra -Wno-unknown-pragmas -Wendif-labels -Wshadow -Wctor-dtor-privacy -Wnon-virtual-dtor -fno-rtti -fno-exceptions -fvisibility=hidden -fvisibility-inlines-hidden -fno-stack-protector"
+ COMPILE_FLAGS "-Wall -Wextra -Wno-unknown-pragmas -Wendif-labels -Wshadow -Wctor-dtor-privacy -Wnon-virtual-dtor -fno-rtti -fno-exceptions -fvisibility=hidden -fvisibility-inlines-hidden -fno-stack-protector -Wdouble-promotion"
LINK_FLAGS "-nodefaultlibs ${GRAPHITE_LINK_FLAGS}"
LINKER_LANGUAGE C)
if (${CMAKE_CXX_COMPILER} MATCHES ".*mingw.*")
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/CachedFace.cpp b/Build/source/libs/graphite2/graphite2-1.3.0/src/CachedFace.cpp
index fd599bde8aa..fd599bde8aa 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/CachedFace.cpp
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/CachedFace.cpp
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/CmapCache.cpp b/Build/source/libs/graphite2/graphite2-1.3.0/src/CmapCache.cpp
index a184e97095c..a184e97095c 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/CmapCache.cpp
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/CmapCache.cpp
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/Code.cpp b/Build/source/libs/graphite2/graphite2-1.3.0/src/Code.cpp
index 85769867dfd..9caed1333d1 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/Code.cpp
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/Code.cpp
@@ -77,6 +77,7 @@ struct context
} // end namespace
+byte * Machine::Code::local_memory = 0;
class Machine::Code::decoder
{
@@ -94,7 +95,7 @@ public:
};
- decoder(const limits & lims, Code &code) throw();
+ decoder(limits & lims, Code &code, enum passtype pt) throw();
bool load(const byte * bc_begin, const byte * bc_end);
void apply_analysis(instr * const code, instr * code_end);
@@ -107,6 +108,7 @@ private:
bool emit_opcode(opcode opc, const byte * & bc);
bool validate_opcode(const opcode opc, const byte * const bc);
bool valid_upto(const uint16 limit, const uint16 x) const throw();
+ bool test_context() const throw();
void failure(const status_t s) const throw() { _code.failure(s); }
Code & _code;
@@ -114,14 +116,16 @@ private:
uint16 _rule_length;
instr * _instr;
byte * _data;
- const limits & _max;
+ limits & _max;
analysis _analysis;
+ enum passtype _passtype;
+ int _stack_depth;
};
struct Machine::Code::decoder::limits
{
- const byte * const bytecode;
+ const byte * bytecode;
const uint8 pre_context;
const uint16 rule_length,
classes,
@@ -130,19 +134,21 @@ struct Machine::Code::decoder::limits
const byte attrid[gr_slatMax];
};
-inline Machine::Code::decoder::decoder(const limits & lims, Code &code) throw()
+inline Machine::Code::decoder::decoder(limits & lims, Code &code, enum passtype pt) throw()
: _code(code),
_pre_context(code._constraint ? 0 : lims.pre_context),
_rule_length(code._constraint ? 1 : lims.rule_length),
- _instr(code._code), _data(code._data), _max(lims)
+ _instr(code._code), _data(code._data), _max(lims), _passtype(pt),
+ _stack_depth(0)
{ }
Machine::Code::Code(bool is_constraint, const byte * bytecode_begin, const byte * const bytecode_end,
- uint8 pre_context, uint16 rule_length, const Silf & silf, const Face & face)
+ uint8 pre_context, uint16 rule_length, const Silf & silf, const Face & face,
+ enum passtype pt, byte * & _out)
: _code(0), _data(0), _data_size(0), _instr_count(0), _max_ref(0), _status(loaded),
- _constraint(is_constraint), _modify(false), _delete(false), _own(true)
+ _constraint(is_constraint), _modify(false), _delete(false), _own(_out==0)
{
#ifdef GRAPHITE2_TELEMETRY
telemetry::category _code_cat(face.tele.code);
@@ -150,7 +156,7 @@ Machine::Code::Code(bool is_constraint, const byte * bytecode_begin, const byte
assert(bytecode_begin != 0);
if (bytecode_begin == bytecode_end)
{
- ::new (this) Code();
+ // ::new (this) Code();
return;
}
assert(bytecode_end > bytecode_begin);
@@ -158,17 +164,17 @@ Machine::Code::Code(bool is_constraint, const byte * bytecode_begin, const byte
// Allocate code and dat target buffers, these sizes are a worst case
// estimate. Once we know their real sizes the we'll shrink them.
- _code = static_cast<instr *>(malloc((bytecode_end - bytecode_begin)
- * sizeof(instr)));
- _data = static_cast<byte *>(malloc((bytecode_end - bytecode_begin)
- * sizeof(byte)));
+ if (_out) _code = reinterpret_cast<instr *>(_out);
+ else _code = static_cast<instr *>(malloc((bytecode_end - bytecode_begin)
+ * (sizeof(instr)+sizeof(byte))));
+ _data = reinterpret_cast<byte *>(_code + (bytecode_end - bytecode_begin));
if (!_code || !_data) {
failure(alloc_failed);
return;
}
- const decoder::limits lims = {
+ decoder::limits lims = {
bytecode_end,
pre_context,
rule_length,
@@ -184,7 +190,7 @@ Machine::Code::Code(bool is_constraint, const byte * bytecode_begin, const byte
0,0,0,0,0,0,0, silf.numUser()}
};
- decoder dec(lims, *this);
+ decoder dec(lims, *this, pt);
if(!dec.load(bytecode_begin, bytecode_end))
return;
@@ -211,8 +217,13 @@ Machine::Code::Code(bool is_constraint, const byte * bytecode_begin, const byte
// memory.
assert((bytecode_end - bytecode_begin) >= std::ptrdiff_t(_instr_count));
assert((bytecode_end - bytecode_begin) >= std::ptrdiff_t(_data_size));
- _code = static_cast<instr *>(realloc(_code, (_instr_count+1)*sizeof(instr)));
- _data = static_cast<byte *>(realloc(_data, _data_size*sizeof(byte)));
+ memmove(_code + (_instr_count+1), _data, _data_size*sizeof(byte));
+ size_t const total_sz = ((_instr_count+1) + (_data_size + sizeof(instr)-1)/sizeof(instr))*sizeof(instr);
+ if (_out)
+ _out += total_sz;
+ else
+ _code = static_cast<instr *>(realloc(_code, total_sz));
+ _data = reinterpret_cast<byte *>(_code + (_instr_count+1));
if (!_code)
{
@@ -237,6 +248,7 @@ Machine::Code::~Code() throw ()
bool Machine::Code::decoder::load(const byte * bc, const byte * bc_end)
{
+ _max.bytecode = bc_end;
while (bc < bc_end)
{
const opcode opc = fetch_opcode(bc++);
@@ -266,55 +278,82 @@ opcode Machine::Code::decoder::fetch_opcode(const byte * bc)
switch (opc)
{
case NOP :
+ break;
case PUSH_BYTE :
case PUSH_BYTEU :
case PUSH_SHORT :
case PUSH_SHORTU :
case PUSH_LONG :
+ ++_stack_depth;
+ break;
case ADD :
case SUB :
case MUL :
case DIV :
case MIN_ :
case MAX_ :
- case NEG :
- case TRUNC8 :
- case TRUNC16 :
- case COND :
case AND :
case OR :
- case NOT :
case EQUAL :
case NOT_EQ :
case LESS :
case GTR :
case LESS_EQ :
case GTR_EQ :
+ case BITOR :
+ case BITAND :
+ if (--_stack_depth <= 0)
+ failure(underfull_stack);
+ break;
+ case NEG :
+ case TRUNC8 :
+ case TRUNC16 :
+ case NOT :
+ case BITNOT :
+ case BITSET :
+ if (_stack_depth <= 0)
+ failure(underfull_stack);
+ break;
+ case COND :
+ _stack_depth -= 2;
+ if (_stack_depth <= 0)
+ failure(underfull_stack);
break;
case NEXT :
case NEXT_N : // runtime checked
case COPY_NEXT :
+ test_context();
++_pre_context;
break;
case PUT_GLYPH_8BIT_OBS :
valid_upto(_max.classes, bc[0]);
+ test_context();
break;
case PUT_SUBS_8BIT_OBS :
valid_upto(_rule_length, _pre_context + int8(bc[0]));
valid_upto(_max.classes, bc[1]);
valid_upto(_max.classes, bc[2]);
+ test_context();
break;
case PUT_COPY :
valid_upto(_rule_length, _pre_context + int8(bc[0]));
+ test_context();
break;
case INSERT :
- --_pre_context;
+ if (_passtype >= PASS_TYPE_POSITIONING)
+ failure(invalid_opcode);
+ else
+ --_pre_context;
break;
case DELETE :
+ if (_passtype >= PASS_TYPE_POSITIONING)
+ failure(invalid_opcode);
+ test_context();
break;
case ASSOC :
for (uint8 num = bc[0]; num; --num)
valid_upto(_rule_length, _pre_context + int8(bc[num]));
+ test_context();
break;
case CNTXT_ITEM :
valid_upto(_max.rule_length, _max.pre_context + int8(bc[0]));
@@ -325,39 +364,52 @@ opcode Machine::Code::decoder::fetch_opcode(const byte * bc)
case ATTR_ADD :
case ATTR_SUB :
case ATTR_SET_SLOT :
+ if (--_stack_depth < 0)
+ failure(underfull_stack);
valid_upto(gr_slatMax, bc[0]);
+ test_context();
break;
case IATTR_SET_SLOT :
+ if (--_stack_depth < 0)
+ failure(underfull_stack);
if (valid_upto(gr_slatMax, bc[0]))
valid_upto(_max.attrid[bc[0]], bc[1]);
+ test_context();
break;
case PUSH_SLOT_ATTR :
+ ++_stack_depth;
valid_upto(gr_slatMax, bc[0]);
valid_upto(_rule_length, _pre_context + int8(bc[1]));
break;
case PUSH_GLYPH_ATTR_OBS :
+ ++_stack_depth;
valid_upto(_max.glyf_attrs, bc[0]);
valid_upto(_rule_length, _pre_context + int8(bc[1]));
break;
case PUSH_GLYPH_METRIC :
+ ++_stack_depth;
valid_upto(kgmetDescent, bc[0]);
valid_upto(_rule_length, _pre_context + int8(bc[1]));
// level: dp[2] no check necessary
break;
case PUSH_FEAT :
+ ++_stack_depth;
valid_upto(_max.features, bc[0]);
valid_upto(_rule_length, _pre_context + int8(bc[1]));
break;
case PUSH_ATT_TO_GATTR_OBS :
+ ++_stack_depth;
valid_upto(_max.glyf_attrs, bc[0]);
valid_upto(_rule_length, _pre_context + int8(bc[1]));
break;
case PUSH_ATT_TO_GLYPH_METRIC :
+ ++_stack_depth;
valid_upto(kgmetDescent, bc[0]);
valid_upto(_rule_length, _pre_context + int8(bc[1]));
// level: dp[2] no check necessary
break;
case PUSH_ISLOT_ATTR :
+ ++_stack_depth;
if (valid_upto(gr_slatMax, bc[0]))
{
valid_upto(_rule_length, _pre_context + int8(bc[1]));
@@ -365,32 +417,42 @@ opcode Machine::Code::decoder::fetch_opcode(const byte * bc)
}
break;
case PUSH_IGLYPH_ATTR :// not implemented
+ ++_stack_depth;
case POP_RET :
+ if (--_stack_depth < 0)
+ failure(underfull_stack);
case RET_ZERO :
case RET_TRUE :
break;
case IATTR_SET :
case IATTR_ADD :
case IATTR_SUB :
+ if (--_stack_depth < 0)
+ failure(underfull_stack);
if (valid_upto(gr_slatMax, bc[0]))
valid_upto(_max.attrid[bc[0]], bc[1]);
+ test_context();
break;
case PUSH_PROC_STATE : // dummy: dp[0] no check necessary
case PUSH_VERSION :
+ ++_stack_depth;
break;
case PUT_SUBS :
valid_upto(_rule_length, _pre_context + int8(bc[0]));
valid_upto(_max.classes, uint16(bc[1]<< 8) | bc[2]);
valid_upto(_max.classes, uint16(bc[3]<< 8) | bc[4]);
+ test_context();
break;
case PUT_SUBS2 : // not implemented
case PUT_SUBS3 : // not implemented
break;
case PUT_GLYPH :
valid_upto(_max.classes, uint16(bc[0]<< 8) | bc[1]);
+ test_context();
break;
case PUSH_GLYPH_ATTR :
case PUSH_ATT_TO_GLYPH_ATTR :
+ ++_stack_depth;
valid_upto(_max.glyf_attrs, uint16(bc[0]<< 8) | bc[1]);
valid_upto(_rule_length, _pre_context + int8(bc[2]));
break;
@@ -506,16 +568,20 @@ bool Machine::Code::decoder::emit_opcode(opcode opc, const byte * & bc)
byte & instr_skip = _data[-1];
byte & data_skip = *_data++;
++_code._data_size;
+ const byte *curr_end = _max.bytecode;
if (load(bc, bc + instr_skip))
{
bc += instr_skip;
data_skip = instr_skip - (_code._instr_count - ctxt_start);
instr_skip = _code._instr_count - ctxt_start;
+ _max.bytecode = curr_end;
_rule_length = 1;
_pre_context = 0;
}
+ else
+ return false;
}
return bool(_code);
@@ -554,7 +620,7 @@ bool Machine::Code::decoder::validate_opcode(const opcode opc, const byte * cons
}
const opcode_t & op = Machine::getOpcodeTable()[opc];
const size_t param_sz = op.param_sz == VARARGS ? bc[0] + 1 : op.param_sz;
- if (bc + param_sz > _max.bytecode)
+ if (bc - 1 + param_sz > _max.bytecode)
{
failure(arguments_exhausted);
return false;
@@ -570,6 +636,15 @@ bool Machine::Code::decoder::valid_upto(const uint16 limit, const uint16 x) cons
return t;
}
+bool Machine::Code::decoder::test_context() const throw()
+{
+ if (_pre_context >= _rule_length)
+ {
+ failure(out_of_range_data);
+ return false;
+ }
+ return true;
+}
inline
void Machine::Code::failure(const status_t s) throw() {
@@ -594,8 +669,8 @@ void Machine::Code::decoder::analysis::set_changed(const int index) throw() {
void Machine::Code::release_buffers() throw()
{
- free(_code);
- free(_data);
+ if (_own)
+ free(_code);
_code = 0;
_data = 0;
_own = false;
@@ -604,13 +679,12 @@ void Machine::Code::release_buffers() throw()
int32 Machine::Code::run(Machine & m, slotref * & map) const
{
- assert(_own);
+// assert(_own);
assert(*this); // Check we are actually runnable
if (m.slotMap().size() <= size_t(_max_ref + m.slotMap().context()))
{
m._status = Machine::slot_offset_out_bounds;
-// return (m.slotMap().end() - map);
return 1;
}
diff --git a/Build/source/libs/graphite2/graphite2-1.3.0/src/Collider.cpp b/Build/source/libs/graphite2/graphite2-1.3.0/src/Collider.cpp
new file mode 100644
index 00000000000..b17b9b42f0a
--- /dev/null
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/Collider.cpp
@@ -0,0 +1,1080 @@
+/* GRAPHITE2 LICENSING
+
+ Copyright 2010, SIL International
+ All rights reserved.
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should also have received a copy of the GNU Lesser General Public
+ License along with this library in the file named "LICENSE".
+ If not, write to the Free Software Foundation, 51 Franklin Street,
+ Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
+ internet at http://www.fsf.org/licenses/lgpl.html.
+
+Alternatively, the contents of this file may be used under the terms of the
+Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
+License, as published by the Free Software Foundation, either version 2
+of the License or (at your option) any later version.
+*/
+#include <algorithm>
+#include <limits>
+#include <math.h>
+#include <string>
+#include <functional>
+#include "inc/Collider.h"
+#include "inc/Segment.h"
+#include "inc/Slot.h"
+#include "inc/GlyphCache.h"
+#include "inc/Sparse.h"
+
+#define ISQRT2 0.707106781f
+
+// Possible rounding error for subbox boundaries: 0.016 = 1/64 = 1/256 * 4
+// (values in font range from 0..256)
+#define SUBBOX_RND_ERR 0.016
+
+using namespace graphite2;
+
+//// SHIFT-COLLIDER ////
+
+// Initialize the Collider to hold the basic movement limits for the
+// target slot, the one we are focusing on fixing.
+bool ShiftCollider::initSlot(Segment *seg, Slot *aSlot, const Rect &limit, float margin, float marginWeight,
+ const Position &currShift, const Position &currOffset, int dir, GR_MAYBE_UNUSED json * const dbgout)
+{
+ int i;
+ float max, min;
+ float a, shift;
+ const GlyphCache &gc = seg->getFace()->glyphs();
+ unsigned short gid = aSlot->gid();
+ if (!gc.check(gid))
+ return false;
+ const BBox &bb = gc.getBoundingBBox(gid);
+ const SlantBox &sb = gc.getBoundingSlantBox(gid);
+ //float sx = aSlot->origin().x + currShift.x;
+ //float sy = aSlot->origin().y + currShift.y;
+ if (currOffset.x != 0.f || currOffset.y != 0.f)
+ _limit = Rect(limit.bl - currOffset, limit.tr - currOffset);
+ else
+ _limit = limit;
+ // For a ShiftCollider, these indices indicate which vector we are moving by:
+ // each _ranges represents absolute space with respect to the origin of the slot. Thus take into account true origins but subtract the vmin for the slot
+ for (i = 0; i < 4; ++i)
+ {
+ switch (i) {
+ case 0 : // x direction
+ min = _limit.bl.x + currOffset.x;
+ max = _limit.tr.x + currOffset.x;
+ _len[i] = bb.xa - bb.xi;
+ a = currOffset.y + currShift.y;
+ _ranges[i].initialise<XY>(min, max, margin, marginWeight, a);
+ break;
+ case 1 : // y direction
+ min = _limit.bl.y + currOffset.y;
+ max = _limit.tr.y + currOffset.y;
+ _len[i] = bb.ya - bb.yi;
+ a = currOffset.x + currShift.x;
+ _ranges[i].initialise<XY>(min, max, margin, marginWeight, a);
+ break;
+ case 2 : // sum (negatively sloped diagonal boundaries)
+ // pick closest x,y limit boundaries in s direction
+ shift = currOffset.x + currOffset.y + currShift.x + currShift.y;
+ min = -2 * std::min(currShift.x - _limit.bl.x, currShift.y - _limit.bl.y) + shift;
+ max = 2 * std::min(_limit.tr.x - currShift.x, _limit.tr.y - currShift.y) + shift;
+ _len[i] = sb.sa - sb.si;
+ a = currOffset.x - currOffset.y + currShift.x - currShift.y;
+ _ranges[i].initialise<SD>(min, max, margin / ISQRT2, marginWeight, a);
+ break;
+ case 3 : // diff (positively sloped diagonal boundaries)
+ // pick closest x,y limit boundaries in d direction
+ shift = currOffset.x - currOffset.y + currShift.x - currShift.y;
+ min = -2 * std::min(currShift.x - _limit.bl.x, _limit.tr.y - currShift.y) + shift;
+ max = 2 * std::min(_limit.tr.x - currShift.x, currShift.y - _limit.bl.y) + shift;
+ _len[i] = sb.da - sb.di;
+ a = currOffset.x + currOffset.y + currShift.x + currShift.y;
+ _ranges[i].initialise<SD>(min, max, margin / ISQRT2, marginWeight, a);
+ break;
+ }
+ }
+
+ _target = aSlot;
+ if ((dir & 1) == 0)
+ {
+ // For LTR, switch and negate x limits.
+ _limit.bl.x = -1 * limit.tr.x;
+ //_limit.tr.x = -1 * limit.bl.x;
+ }
+ _currOffset = currOffset;
+ _currShift = currShift;
+ _origin = aSlot->origin() - currOffset; // the original anchor position of the glyph
+
+ _margin = margin;
+ _marginWt = marginWeight;
+
+ SlotCollision *c = seg->collisionInfo(aSlot);
+ _seqClass = c->seqClass();
+ _seqProxClass = c->seqProxClass();
+ _seqOrder = c->seqOrder();
+ return true;
+}
+
+template <class O>
+float sdm(float vi, float va, float mx, float my, O op)
+{
+ float res = 2 * mx - vi;
+ if (op(res, vi + 2 * my))
+ {
+ res = va + 2 * my;
+ if (op(res, 2 * mx - va))
+ res = mx + my;
+ }
+ return res;
+}
+
+// Mark an area with a cost that can vary along the x or y axis. The region is expressed in terms of the centre of the target glyph in each axis
+void ShiftCollider::addBox_slope(bool isx, const Rect &box, const BBox &bb, const SlantBox &sb, const Position &org, float weight, float m, bool minright, int axis)
+{
+ float a, c;
+ switch (axis) {
+ case 0 :
+ if (box.bl.y < org.y + bb.ya && box.tr.y > org.y + bb.yi && box.width() > 0)
+ {
+ a = org.y + 0.5f * (bb.yi + bb.ya);
+ c = 0.5f * (bb.xi + bb.xa);
+ if (isx)
+ _ranges[axis].weighted<XY>(box.bl.x - c, box.tr.x - c, weight, a, m,
+ (minright ? box.tr.x : box.bl.x) - c, a, 0, false);
+ else
+ _ranges[axis].weighted<XY>(box.bl.x - c, box.tr.x - c, weight, a, 0, 0, org.y,
+ m * (a * a + sqr((minright ? box.tr.y : box.bl.y) - 0.5f * (bb.yi + bb.ya))), false);
+ }
+ break;
+ case 1 :
+ if (box.bl.x < org.x + bb.xa && box.tr.x > org.x + bb.xi && box.height() > 0)
+ {
+ a = org.x + 0.5f * (bb.xi + bb.xa);
+ c = 0.5f * (bb.yi + bb.ya);
+ if (isx)
+ _ranges[axis].weighted<XY>(box.bl.y - c, box.tr.y - c, weight, a, 0, 0, org.x,
+ m * (a * a + sqr((minright ? box.tr.x : box.bl.x) - 0.5f * (bb.xi + bb.xa))), false);
+ else
+ _ranges[axis].weighted<XY>(box.bl.y - c, box.tr.y - c, weight, a, m,
+ (minright ? box.tr.y : box.bl.y) - c, a, 0, false);
+ }
+ break;
+ case 2 :
+ if (box.bl.x - box.tr.y < org.x - org.y + sb.da && box.tr.x - box.bl.y > org.x - org.y + sb.di)
+ {
+ float d = org.x - org.y + 0.5f * (sb.di + sb.da);
+ c = 0.5f * (sb.si + sb.sa);
+ float smax = std::min(2 * box.tr.x - d, 2 * box.tr.y + d);
+ float smin = std::max(2 * box.bl.x - d, 2 * box.bl.y + d);
+ if (smin > smax) return;
+ float si;
+ a = d;
+ if (isx)
+ si = 2 * (minright ? box.tr.x : box.bl.x) - a;
+ else
+ si = 2 * (minright ? box.tr.y : box.bl.y) + a;
+ _ranges[axis].weighted<SD>(smin - c, smax - c, weight / 2, a, m / 2, si, 0, 0, isx);
+ }
+ break;
+ case 3 :
+ if (box.bl.x + box.bl.y < org.x + org.y + sb.sa && box.tr.x + box.tr.y > org.x + org.y + sb.si)
+ {
+ float s = org.x + org.y + 0.5f * (sb.si + sb.sa);
+ c = 0.5f * (sb.di + sb.da);
+ float dmax = std::min(2 * box.tr.x - s, s - 2 * box.bl.y);
+ float dmin = std::max(2 * box.bl.x - s, s - 2 * box.tr.y);
+ if (dmin > dmax) return;
+ float di;
+ a = s;
+ if (isx)
+ di = 2 * (minright ? box.tr.x : box.bl.x) - a;
+ else
+ di = 2 * (minright ? box.tr.y : box.bl.y) + a;
+ _ranges[axis].weighted<SD>(dmin - c, dmax - c, weight / 2, a, m / 2, di, 0, 0, !isx);
+ }
+ break;
+ default :
+ break;
+ }
+ return;
+}
+
+// Mark an area with an absolute cost, making it completely inaccessible.
+inline void ShiftCollider::removeBox(const Rect &box, const BBox &bb, const SlantBox &sb, const Position &org, int axis)
+{
+ float c;
+ switch (axis) {
+ case 0 :
+ if (box.bl.y < org.y + bb.ya && box.tr.y > org.y + bb.yi && box.width() > 0)
+ {
+ c = 0.5f * (bb.xi + bb.xa);
+ _ranges[axis].exclude(box.bl.x - c, box.tr.x - c);
+ }
+ break;
+ case 1 :
+ if (box.bl.x < org.x + bb.xa && box.tr.x > org.x + bb.xi && box.height() > 0)
+ {
+ c = 0.5f * (bb.yi + bb.ya);
+ _ranges[axis].exclude(box.bl.y - c, box.tr.y - c);
+ }
+ break;
+ case 2 :
+ if (box.bl.x - box.tr.y < org.x - org.y + sb.da && box.tr.x - box.bl.y > org.x - org.y + sb.di
+ && box.width() > 0 && box.height() > 0)
+ {
+ float di = org.x - org.y + sb.di;
+ float da = org.x - org.y + sb.da;
+ float smax = sdm(di, da, box.tr.x, box.tr.y, std::greater<float>());
+ float smin = sdm(da, di, box.bl.x, box.bl.y, std::less<float>());
+ c = 0.5f * (sb.si + sb.sa);
+ _ranges[axis].exclude(smin - c, smax - c);
+ }
+ break;
+ case 3 :
+ if (box.bl.x + box.bl.y < org.x + org.y + sb.sa && box.tr.x + box.tr.y > org.x + org.y + sb.si
+ && box.width() > 0 && box.height() > 0)
+ {
+ float si = org.x + org.y + sb.si;
+ float sa = org.x + org.y + sb.sa;
+ float dmax = sdm(si, sa, box.tr.x, -box.bl.y, std::greater<float>());
+ float dmin = sdm(sa, si, box.bl.x, -box.tr.y, std::less<float>());
+ c = 0.5f * (sb.di + sb.da);
+ _ranges[axis].exclude(dmin - c, dmax - c);
+ }
+ break;
+ default :
+ break;
+ }
+ return;
+}
+
+// Adjust the movement limits for the target to avoid having it collide
+// with the given neighbor slot. Also determine if there is in fact a collision
+// between the target and the given slot.
+bool ShiftCollider::mergeSlot(Segment *seg, Slot *slot, const Position &currShift,
+ bool isAfter, // slot is logically after _target
+ bool sameCluster, bool &hasCol, bool isExclusion,
+ GR_MAYBE_UNUSED json * const dbgout )
+{
+ bool isCol = false;
+ const float tx = _currOffset.x + _currShift.x;
+ const float ty = _currOffset.y + _currShift.y;
+ const float td = tx - ty;
+ const float ts = tx + ty;
+ const float sx = slot->origin().x - _origin.x + currShift.x;
+ const float sy = slot->origin().y - _origin.y + currShift.y;
+ const float sd = sx - sy;
+ const float ss = sx + sy;
+ float vmin, vmax;
+ float omin, omax, otmin, otmax;
+ float cmin, cmax; // target limits
+ float torg;
+ const GlyphCache &gc = seg->getFace()->glyphs();
+ const unsigned short gid = slot->gid();
+ if (!gc.check(gid))
+ return false;
+ const unsigned short tgid = _target->gid();
+ const BBox &bb = gc.getBoundingBBox(gid);
+ const SlantBox &sb = gc.getBoundingSlantBox(gid);
+ const BBox &tbb = gc.getBoundingBBox(tgid);
+ const SlantBox &tsb = gc.getBoundingSlantBox(tgid);
+
+ SlotCollision * cslot = seg->collisionInfo(slot);
+ int orderFlags = 0;
+ bool sameClass = _seqProxClass == 0 && cslot->seqClass() == _seqClass;
+ if (sameCluster && _seqClass
+ && (sameClass || (_seqProxClass != 0 && cslot->seqClass() == _seqProxClass)))
+ // Force the target glyph to be in the specified direction from the slot we're testing.
+ orderFlags = _seqOrder;
+ float seq_above_wt = cslot->seqAboveWt();
+ float seq_below_wt = cslot->seqBelowWt();
+ float seq_valign_wt = cslot->seqValignWt();
+
+ // if isAfter, invert orderFlags for diagonal orders.
+ if (isAfter)
+ {
+ // invert appropriate bits
+ orderFlags ^= (sameClass ? 0x3F : 0x3);
+ // consider 2 bits at a time, non overlapping. If both bits set, clear them
+ orderFlags = orderFlags ^ ((((orderFlags >> 1) & orderFlags) & 0x15) * 3);
+ }
+
+#if !defined GRAPHITE2_NTRACING
+ if (dbgout)
+ dbgout->setenv(0, slot);
+#endif
+
+ // Process main bounding octabox.
+ for (int i = 0; i < 4; ++i)
+ {
+ switch (i) {
+ case 0 : // x direction
+ vmin = std::max(std::max(bb.xi - tbb.xa + sx, sb.di - tsb.da + ty + sd), sb.si - tsb.sa - ty + ss);
+ vmax = std::min(std::min(bb.xa - tbb.xi + sx, sb.da - tsb.di + ty + sd), sb.sa - tsb.si - ty + ss);
+ otmin = tbb.yi + ty;
+ otmax = tbb.ya + ty;
+ omin = bb.yi + sy;
+ omax = bb.ya + sy;
+ torg = _currOffset.x;
+ cmin = _limit.bl.x + torg;
+ cmax = _limit.tr.x - tbb.xi + tbb.xa + torg;
+ break;
+ case 1 : // y direction
+ vmin = std::max(std::max(bb.yi - tbb.ya + sy, tsb.di - sb.da + tx - sd), sb.si - tsb.sa - tx + ss);
+ vmax = std::min(std::min(bb.ya - tbb.yi + sy, tsb.da - sb.di + tx - sd), sb.sa - tsb.si - tx + ss);
+ otmin = tbb.xi + tx;
+ otmax = tbb.xa + tx;
+ omin = bb.xi + sx;
+ omax = bb.xa + sx;
+ torg = _currOffset.y;
+ cmin = _limit.bl.y + torg;
+ cmax = _limit.tr.y - tbb.yi + tbb.ya + torg;
+ break;
+ case 2 : // sum - moving along the positively-sloped vector, so the boundaries are the
+ // negatively-sloped boundaries.
+ vmin = std::max(std::max(sb.si - tsb.sa + ss, 2 * (bb.yi - tbb.ya + sy) + td), 2 * (bb.xi - tbb.xa + sx) - td);
+ vmax = std::min(std::min(sb.sa - tsb.si + ss, 2 * (bb.ya - tbb.yi + sy) + td), 2 * (bb.xa - tbb.xi + sx) - td);
+ otmin = tsb.di + td;
+ otmax = tsb.da + td;
+ omin = sb.di + sd;
+ omax = sb.da + sd;
+ torg = _currOffset.x + _currOffset.y;
+ cmin = _limit.bl.x + _limit.bl.y + torg;
+ cmax = _limit.tr.x + _limit.tr.y - tsb.si + tsb.sa + torg;
+ break;
+ case 3 : // diff - moving along the negatively-sloped vector, so the boundaries are the
+ // positively-sloped boundaries.
+ vmin = std::max(std::max(sb.di - tsb.da + sd, 2 * (bb.xi - tbb.xa + sx) - ts), -2 * (bb.ya - tbb.yi + sy) + ts);
+ vmax = std::min(std::min(sb.da - tsb.di + sd, 2 * (bb.xa - tbb.xi + sx) - ts), -2 * (bb.yi - tbb.ya + sy) + ts);
+ otmin = tsb.si + ts;
+ otmax = tsb.sa + ts;
+ omin = sb.si + ss;
+ omax = sb.sa + ss;
+ torg = _currOffset.x - _currOffset.y;
+ cmin = _limit.bl.x - _limit.tr.y + torg;
+ cmax = _limit.tr.x - _limit.bl.y - tsb.di + tsb.da + torg;
+ break;
+ default :
+ continue;
+ }
+
+#if !defined GRAPHITE2_NTRACING
+ if (dbgout)
+ dbgout->setenv(1, reinterpret_cast<void *>(-1));
+#define DBGTAG(x) if (dbgout) dbgout->setenv(1, reinterpret_cast<void *>(-x));
+#else
+#define DBGTAG(x)
+#endif
+
+ if (orderFlags)
+ {
+ Position org(tx, ty);
+ float xminf = _limit.bl.x + _currOffset.x + tbb.xi;
+ float xpinf = _limit.tr.x + _currOffset.x + tbb.xa;
+ float ypinf = _limit.tr.y + _currOffset.y + tbb.ya;
+ float yminf = _limit.bl.y + _currOffset.y + tbb.yi;
+ switch (orderFlags) {
+ case SlotCollision::SEQ_ORDER_RIGHTUP :
+ {
+ float r1Xedge = cslot->seqAboveXoff() + 0.5f * (bb.xi + bb.xa) + sx;
+ float r3Xedge = cslot->seqBelowXlim() + bb.xa + sx + 0.5f * (tbb.xa - tbb.xi);
+ float r2Yedge = 0.5f * (bb.yi + bb.ya) + sy;
+
+ // DBGTAG(1x) means the regions are up and right
+ // region 1
+ DBGTAG(11)
+ addBox_slope(true, Rect(Position(xminf, r2Yedge), Position(r1Xedge, ypinf)),
+ tbb, tsb, org, 0, seq_above_wt, true, i);
+ // region 2
+ DBGTAG(12)
+ removeBox(Rect(Position(xminf, yminf), Position(r3Xedge, r2Yedge)), tbb, tsb, org, i);
+ // region 3, which end is zero is irrelevant since m weight is 0
+ DBGTAG(13)
+ addBox_slope(true, Rect(Position(r3Xedge, yminf), Position(xpinf, r2Yedge - cslot->seqValignHt())),
+ tbb, tsb, org, seq_below_wt, 0, true, i);
+ // region 4
+ DBGTAG(14)
+ addBox_slope(false, Rect(Position(sx + bb.xi, r2Yedge), Position(xpinf, r2Yedge + cslot->seqValignHt())),
+ tbb, tsb, org, 0, seq_valign_wt, true, i);
+ // region 5
+ DBGTAG(15)
+ addBox_slope(false, Rect(Position(sx + bb.xi, r2Yedge - cslot->seqValignHt()), Position(xpinf, r2Yedge)),
+ tbb, tsb, org, seq_below_wt, seq_valign_wt, false, i);
+ break;
+ }
+ case SlotCollision::SEQ_ORDER_LEFTDOWN :
+ {
+ float r1Xedge = 0.5f * (bb.xi + bb.xa) + cslot->seqAboveXoff() + sx;
+ float r3Xedge = bb.xi - cslot->seqBelowXlim() + sx - 0.5f * (tbb.xa - tbb.xi);
+ float r2Yedge = 0.5f * (bb.yi + bb.ya) + sy;
+ // DBGTAG(2x) means the regions are up and right
+ // region 1
+ DBGTAG(21)
+ addBox_slope(true, Rect(Position(r1Xedge, yminf), Position(xpinf, r2Yedge)),
+ tbb, tsb, org, 0, seq_above_wt, false, i);
+ // region 2
+ DBGTAG(22)
+ removeBox(Rect(Position(r3Xedge, r2Yedge), Position(xpinf, ypinf)), tbb, tsb, org, i);
+ // region 3
+ DBGTAG(23)
+ addBox_slope(true, Rect(Position(xminf, r2Yedge - cslot->seqValignHt()), Position(r3Xedge, ypinf)),
+ tbb, tsb, org, seq_below_wt, 0, false, i);
+ // region 4
+ DBGTAG(24)
+ addBox_slope(false, Rect(Position(xminf, r2Yedge), Position(sx + bb.xa, r2Yedge + cslot->seqValignHt())),
+ tbb, tsb, org, 0, seq_valign_wt, true, i);
+ // region 5
+ DBGTAG(25)
+ addBox_slope(false, Rect(Position(xminf, r2Yedge - cslot->seqValignHt()),
+ Position(sx + bb.xa, r2Yedge)), tbb, tsb, org, seq_below_wt, seq_valign_wt, false, i);
+ break;
+ }
+ case SlotCollision::SEQ_ORDER_NOABOVE : // enforce neighboring glyph being above
+ DBGTAG(31);
+ removeBox(Rect(Position(bb.xi - tbb.xa + sx, sy + bb.ya),
+ Position(bb.xa - tbb.xi + sx, ypinf)), tbb, tsb, org, i);
+ break;
+ case SlotCollision::SEQ_ORDER_NOBELOW : // enforce neighboring glyph being below
+ DBGTAG(32);
+ removeBox(Rect(Position(bb.xi - tbb.xa + sx, yminf),
+ Position(bb.xa - tbb.xi + sx, sy + bb.yi)), tbb, tsb, org, i);
+ break;
+ case SlotCollision::SEQ_ORDER_NOLEFT : // enforce neighboring glyph being to the left
+ DBGTAG(33)
+ removeBox(Rect(Position(xminf, bb.yi - tbb.ya + sy),
+ Position(bb.xi - tbb.xa + sx, bb.ya - tbb.yi + sy)), tbb, tsb, org, i);
+ break;
+ case SlotCollision::SEQ_ORDER_NORIGHT : // enforce neighboring glyph being to the right
+ DBGTAG(34)
+ removeBox(Rect(Position(bb.xa - tbb.xi + sx, bb.yi - tbb.ya + sy),
+ Position(xpinf, bb.ya - tbb.yi + sy)), tbb, tsb, org, i);
+ break;
+ default :
+ break;
+ }
+ }
+
+ if (vmax < cmin - _margin || vmin > cmax + _margin || omax < otmin - _margin || omin > otmax + _margin)
+ continue;
+
+ // Process sub-boxes that are defined for this glyph.
+ // We only need to do this if there was in fact a collision with the main octabox.
+ uint8 numsub = gc.numSubBounds(gid);
+ if (numsub > 0)
+ {
+ bool anyhits = false;
+ for (int j = 0; j < numsub; ++j)
+ {
+ const BBox &sbb = gc.getSubBoundingBBox(gid, j);
+ const SlantBox &ssb = gc.getSubBoundingSlantBox(gid, j);
+ switch (i) {
+ case 0 : // x
+ vmin = std::max(std::max(sbb.xi-tbb.xa+sx, ssb.di-tsb.da+sd+ty), ssb.si-tsb.sa+ss-ty);
+ vmax = std::min(std::min(sbb.xa-tbb.xi+sx, ssb.da-tsb.di+sd+ty), ssb.sa-tsb.si+ss-ty);
+ omin = sbb.yi + sy;
+ omax = sbb.ya + sy;
+ break;
+ case 1 : // y
+ vmin = std::max(std::max(sbb.yi-tbb.ya+sy, tsb.di-ssb.da-sd+tx), ssb.si-tsb.sa+ss-tx);
+ vmax = std::min(std::min(sbb.ya-tbb.yi+sy, tsb.da-ssb.di-sd+tx), ssb.sa-tsb.si+ss-tx);
+ omin = sbb.xi + sx;
+ omax = sbb.xa + sx;
+ break;
+ case 2 : // sum
+ vmin = std::max(std::max(ssb.si-tsb.sa+ss, 2*(sbb.yi-tbb.ya+sy)+td), 2*(sbb.xi-tbb.xa+sx)-td);
+ vmax = std::min(std::min(ssb.sa-tsb.si+ss, 2*(sbb.ya-tbb.yi+sy)+td), 2*(sbb.xa-tbb.xi+sx)-td);
+ omin = ssb.di + sd;
+ omax = ssb.da + sd;
+ break;
+ case 3 : // diff
+ vmin = std::max(std::max(ssb.di-tsb.da+sd, 2*(sbb.xi-tbb.xa+sx)-ts), -2*(sbb.ya-tbb.yi+sy)+ts);
+ vmax = std::min(std::min(ssb.da-tsb.di+sd, 2*(sbb.xa-tbb.xi+sx)-ts), -2*(sbb.yi-tbb.ya+sy)+ts);
+ omin = ssb.si + ss;
+ omax = ssb.sa + ss;
+ break;
+ }
+ if (vmax < cmin - _margin || vmin > cmax + _margin || omax < otmin - _margin || omin > otmax + _margin)
+ continue;
+
+#if !defined GRAPHITE2_NTRACING
+ if (dbgout)
+ dbgout->setenv(1, reinterpret_cast<void *>(j));
+#endif
+ if (omin > otmax)
+ _ranges[i].weightedAxis(i, vmin - _margin, vmax + _margin, 0, 0, 0, 0, 0,
+ sqr(_margin - omin + otmax) * _marginWt, false);
+ else if (omax < otmin)
+ _ranges[i].weightedAxis(i, vmin - _margin, vmax + _margin, 0, 0, 0, 0, 0,
+ sqr(_margin - otmin + omax) * _marginWt, false);
+ else
+ _ranges[i].exclude_with_margins(vmin, vmax, i);
+ anyhits = true;
+ }
+ if (anyhits)
+ isCol = true;
+ }
+ else // no sub-boxes
+ {
+#if !defined GRAPHITE2_NTRACING
+ if (dbgout)
+ dbgout->setenv(1, reinterpret_cast<void *>(-1));
+#endif
+ isCol = true;
+ if (omin > otmax)
+ _ranges[i].weightedAxis(i, vmin - _margin, vmax + _margin, 0, 0, 0, 0, 0,
+ sqr(_margin - omin + otmax) * _marginWt, false);
+ else if (omax < otmin)
+ _ranges[i].weightedAxis(i, vmin - _margin, vmax + _margin, 0, 0, 0, 0, 0,
+ sqr(_margin - otmin + omax) * _marginWt, false);
+ else
+ _ranges[i].exclude_with_margins(vmin, vmax, i);
+
+ }
+ }
+ bool res = true;
+ if (cslot && cslot->exclGlyph() > 0 && gc.check(cslot->exclGlyph()) && !isExclusion)
+ {
+ // Set up the bogus slot representing the exclusion glyph.
+ Slot *exclSlot = seg->newSlot();
+ exclSlot->setGlyph(seg, cslot->exclGlyph());
+ Position exclOrigin(slot->origin() + cslot->exclOffset());
+ exclSlot->origin(exclOrigin);
+ res &= mergeSlot(seg, exclSlot, currShift, isAfter, sameCluster, isCol, true, dbgout );
+ seg->freeSlot(exclSlot);
+ }
+ hasCol |= isCol;
+ return res;
+
+} // end of ShiftCollider::mergeSlot
+
+
+// Figure out where to move the target glyph to, and return the amount to shift by.
+Position ShiftCollider::resolve(GR_MAYBE_UNUSED Segment *seg, bool &isCol, GR_MAYBE_UNUSED json * const dbgout)
+{
+ float tbase;
+ float totalCost = (float)(std::numeric_limits<float>::max() / 2);
+ Position resultPos = Position(0, 0);
+#if !defined GRAPHITE2_NTRACING
+ int bestAxis = -1;
+ if (dbgout)
+ {
+ outputJsonDbgStartSlot(dbgout, seg);
+ *dbgout << "vectors" << json::array;
+ }
+#endif
+ isCol = true;
+ for (int i = 0; i < 4; ++i)
+ {
+ float bestCost = -1;
+ float bestPos;
+ // Calculate the margin depending on whether we are moving diagonally or not:
+ switch (i) {
+ case 0 : // x direction
+ tbase = _currOffset.x;
+ break;
+ case 1 : // y direction
+ tbase = _currOffset.y;
+ break;
+ case 2 : // sum (negatively-sloped diagonals)
+ tbase = _currOffset.x + _currOffset.y;
+ break;
+ case 3 : // diff (positively-sloped diagonals)
+ tbase = _currOffset.x - _currOffset.y;
+ break;
+ }
+ Position testp;
+ bestPos = _ranges[i].closest(0, bestCost) - tbase; // Get the best relative position
+#if !defined GRAPHITE2_NTRACING
+ if (dbgout)
+ outputJsonDbgOneVector(dbgout, seg, i, tbase, bestCost, bestPos) ;
+#endif
+ if (bestCost >= 0.0f)
+ {
+ isCol = false;
+ switch (i) {
+ case 0 : testp = Position(bestPos, _currShift.y); break;
+ case 1 : testp = Position(_currShift.x, bestPos); break;
+ case 2 : testp = Position(0.5f * (_currShift.x - _currShift.y + bestPos), 0.5f * (_currShift.y - _currShift.x + bestPos)); break;
+ case 3 : testp = Position(0.5f * (_currShift.x + _currShift.y + bestPos), 0.5f * (_currShift.x + _currShift.y - bestPos)); break;
+ }
+ if (bestCost < totalCost - 0.01f)
+ {
+ totalCost = bestCost;
+ resultPos = testp;
+#if !defined GRAPHITE2_NTRACING
+ bestAxis = i;
+#endif
+ }
+ }
+ } // end of loop over 4 directions
+
+#if !defined GRAPHITE2_NTRACING
+ if (dbgout)
+ outputJsonDbgEndSlot(dbgout, resultPos, bestAxis, isCol);
+#endif
+
+ return resultPos;
+
+} // end of ShiftCollider::resolve
+
+
+#if !defined GRAPHITE2_NTRACING
+
+void ShiftCollider::outputJsonDbg(json * const dbgout, Segment *seg, int axis)
+{
+ int axisMax = axis;
+ if (axis < 0) // output all axes
+ {
+ *dbgout << "gid" << _target->gid()
+ << "limit" << _limit
+ << "target" << json::object
+ << "origin" << _target->origin()
+ << "margin" << _margin
+ << "bbox" << seg->theGlyphBBoxTemporary(_target->gid())
+ << "slantbox" << seg->getFace()->glyphs().slant(_target->gid())
+ << json::close; // target object
+ *dbgout << "ranges" << json::array;
+ axis = 0;
+ axisMax = 3;
+ }
+ for (int iAxis = axis; iAxis <= axisMax; ++iAxis)
+ {
+ *dbgout << json::flat << json::array << _ranges[iAxis].position();
+ for (Zones::const_iterator s = _ranges[iAxis].begin(), e = _ranges[iAxis].end(); s != e; ++s)
+ *dbgout << json::flat << json::array
+ << Position(s->x, s->xm) << s->sm << s->smx << s->c
+ << json::close;
+ *dbgout << json::close;
+ }
+ if (axis < axisMax) // looped through the _ranges array for all axes
+ *dbgout << json::close; // ranges array
+}
+
+void ShiftCollider::outputJsonDbgStartSlot(json * const dbgout, Segment *seg)
+{
+ *dbgout << json::object // slot - not closed till the end of the caller method
+ << "slot" << objectid(dslot(seg, _target))
+ << "gid" << _target->gid()
+ << "limit" << _limit
+ << "target" << json::object
+ << "origin" << _origin
+ << "currShift" << _currShift
+ << "currOffset" << seg->collisionInfo(_target)->offset()
+ << "bbox" << seg->theGlyphBBoxTemporary(_target->gid())
+ << "slantBox" << seg->getFace()->glyphs().slant(_target->gid())
+ << "fix" << "shift";
+ *dbgout << json::close; // target object
+}
+
+void ShiftCollider::outputJsonDbgEndSlot(GR_MAYBE_UNUSED json * const dbgout,
+ Position resultPos, int bestAxis, bool isCol)
+{
+ *dbgout << json::close // vectors array
+ << "result" << resultPos
+ //<< "scraping" << _scraping[bestAxis]
+ << "bestAxis" << bestAxis
+ << "stillBad" << isCol
+ << json::close; // slot object
+}
+
+void ShiftCollider::outputJsonDbgOneVector(json * const dbgout, Segment *seg, int axis,
+ float tleft, float bestCost, float bestVal)
+{
+ const char * label;
+ switch (axis)
+ {
+ case 0: label = "x"; break;
+ case 1: label = "y"; break;
+ case 2: label = "sum (NE-SW)"; break;
+ case 3: label = "diff (NW-SE)"; break;
+ default: label = "???"; break;
+ }
+
+ *dbgout << json::object // vector
+ << "direction" << label
+ << "targetMin" << tleft;
+
+ outputJsonDbgRemovals(dbgout, axis, seg);
+
+ *dbgout << "ranges";
+ outputJsonDbg(dbgout, seg, axis);
+
+ *dbgout << "bestCost" << bestCost
+ << "bestVal" << bestVal + tleft
+ << json::close; // vectors object
+}
+
+void ShiftCollider::outputJsonDbgRemovals(json * const dbgout, int axis, Segment *seg)
+{
+ *dbgout << "removals" << json::array;
+ _ranges[axis].jsonDbgOut(seg);
+ *dbgout << json::close; // removals array
+}
+
+#endif // !defined GRAPHITE2_NTRACING
+
+
+//// KERN-COLLIDER ////
+
+inline
+static float localmax (float al, float au, float bl, float bu, float x)
+{
+ if (al < bl)
+ { if (au < bu) return au < x ? au : x; }
+ else if (au > bu) return bl < x ? bl : x;
+ return x;
+}
+
+inline
+static float localmin(float al, float au, float bl, float bu, float x)
+{
+ if (bl > al)
+ { if (bu > au) return bl > x ? bl : x; }
+ else if (au > bu) return al > x ? al : x;
+ return x;
+}
+
+// Return the given edge of the glyph at height y, taking any slant box into account.
+static float get_edge(Segment *seg, const Slot *s, const Position &shift, float y, float width, bool isRight)
+{
+ const GlyphCache &gc = seg->getFace()->glyphs();
+ unsigned short gid = s->gid();
+ float sx = s->origin().x + shift.x;
+ float sy = s->origin().y + shift.y;
+ uint8 numsub = gc.numSubBounds(gid);
+ float res = isRight ? (float)-1e38 : (float)1e38;
+
+ if (numsub > 0)
+ {
+ for (int i = 0; i < numsub; ++i)
+ {
+ const BBox &sbb = gc.getSubBoundingBBox(gid, i);
+ const SlantBox &ssb = gc.getSubBoundingSlantBox(gid, i);
+ if (sy + sbb.yi > y + width / 2 || sy + sbb.ya < y - width / 2)
+ continue;
+ if (isRight)
+ {
+ float x = sx + sbb.xa;
+ if (x > res)
+ {
+ float td = sx - sy + ssb.da + y;
+ float ts = sx + sy + ssb.sa - y;
+ x = localmax(td - width / 2, td + width / 2, ts - width / 2, ts + width / 2, x);
+ if (x > res)
+ res = x;
+ }
+ }
+ else
+ {
+ float x = sx + sbb.xi;
+ if (x < res)
+ {
+ float td = sx - sy + ssb.di + y;
+ float ts = sx + sy + ssb.si - y;
+ x = localmin(td - width / 2, td + width / 2, ts - width / 2, ts + width / 2, x);
+ if (x < res)
+ res = x;
+ }
+ }
+ }
+ }
+ else
+ {
+ const BBox &bb = gc.getBoundingBBox(gid);
+ const SlantBox &sb = gc.getBoundingSlantBox(gid);
+ float td = sx - sy + y;
+ float ts = sx + sy - y;
+ if (isRight)
+ res = localmax(td + sb.da - width / 2, td + sb.da + width / 2, ts + sb.sa - width / 2, ts + sb.sa + width / 2, sx + bb.xa);
+ else
+ res = localmin(td + sb.di - width / 2, td + sb.di + width / 2, ts + sb.si - width / 2, ts + sb.si + width / 2, sx + bb.xi);
+ }
+ return res;
+}
+
+
+bool KernCollider::initSlot(Segment *seg, Slot *aSlot, const Rect &limit, float margin,
+ const Position &currShift, const Position &offsetPrev, int dir,
+ float ymin, float ymax, GR_MAYBE_UNUSED json * const dbgout)
+{
+ const GlyphCache &gc = seg->getFace()->glyphs();
+ const Slot *base = aSlot;
+ // const Slot *last = aSlot;
+ const Slot *s;
+ int numSlices;
+ while (base->attachedTo())
+ base = base->attachedTo();
+ if (margin < 10) margin = 10;
+
+ _limit = limit;
+ _offsetPrev = offsetPrev; // kern from a previous pass
+
+ // Calculate the height of the glyph and how many horizontal slices to use.
+ if (_maxy >= 1e37f)
+ {
+ _maxy = ymax;
+ _miny = ymin;
+ _sliceWidth = margin / 1.5f;
+ numSlices = int((_maxy - _miny + 2) / (_sliceWidth / 1.5f) + 1.f); // +2 helps with rounding errors
+ _edges.clear();
+ _edges.insert(_edges.begin(), numSlices, (dir & 1) ? 1e38f : -1e38f);
+ _xbound = (dir & 1) ? (float)1e38f : (float)-1e38f;
+ }
+ else if (_maxy != ymax || _miny != ymin)
+ {
+ if (_miny != ymin)
+ {
+ numSlices = int((ymin - _miny) / _sliceWidth - 1);
+ _miny += numSlices * _sliceWidth;
+ if (numSlices < 0)
+ _edges.insert(_edges.begin(), -numSlices, (dir & 1) ? 1e38f : -1e38f);
+ else if ((unsigned)numSlices < _edges.size()) // this shouldn't fire since we always grow the range
+ {
+ Vector<float>::iterator e = _edges.begin();
+ while (numSlices--)
+ ++e;
+ _edges.erase(_edges.begin(), e);
+ }
+ }
+ if (_maxy != ymax)
+ {
+ numSlices = int((ymax - _miny) / _sliceWidth + 1);
+ _maxy = numSlices * _sliceWidth + _miny;
+ if (numSlices > (int)_edges.size())
+ _edges.insert(_edges.end(), numSlices - _edges.size(), (dir & 1) ? 1e38f : -1e38f);
+ else if (numSlices < (int)_edges.size()) // this shouldn't fire since we always grow the range
+ {
+ while ((int)_edges.size() > numSlices)
+ _edges.pop_back();
+ }
+ }
+ }
+ numSlices = _edges.size();
+
+#if !defined GRAPHITE2_NTRACING
+ // Debugging
+ _seg = seg;
+ _slotNear.clear();
+ _slotNear.insert(_slotNear.begin(), numSlices, NULL);
+ _nearEdges.clear();
+ _nearEdges.insert(_nearEdges.begin(), numSlices, (dir & 1) ? -1e38f : +1e38f);
+#endif
+
+ // Determine the trailing edge of each slice (ie, left edge for a RTL glyph).
+ for (s = base; s; s = s->nextInCluster(s))
+ {
+ SlotCollision *c = seg->collisionInfo(s);
+ if (!gc.check(s->gid()))
+ return false;
+ const BBox &bs = gc.getBoundingBBox(s->gid());
+ float x = s->origin().x + c->shift().x + ((dir & 1) ? bs.xi : bs.xa);
+ // Loop over slices.
+ // Note smin might not be zero if glyph s is not at the bottom of the cluster; similarly for smax.
+ float toffset = c->shift().y - _miny + 1 + s->origin().y;
+ int smin = std::max(0, int((bs.yi + toffset) / _sliceWidth));
+ int smax = std::min(numSlices - 1, int((bs.ya + toffset) / _sliceWidth + 1));
+ for (int i = smin; i <= smax; ++i)
+ {
+ float t;
+ float y = _miny - 1 + (i + .5f) * _sliceWidth; // vertical center of slice
+ if ((dir & 1) && x < _edges[i])
+ {
+ t = get_edge(seg, s, currShift, y, _sliceWidth, false);
+ if (t < _edges[i])
+ {
+ _edges[i] = t;
+ if (t < _xbound)
+ _xbound = t;
+ }
+ }
+ else if (!(dir & 1) && x > _edges[i])
+ {
+ t = get_edge(seg, s, currShift, y, _sliceWidth, true);
+ if (t > _edges[i])
+ {
+ _edges[i] = t;
+ if (t > _xbound)
+ _xbound = t;
+ }
+ }
+ }
+ }
+ _mingap = (float)1e38;
+ _target = aSlot;
+ _margin = margin;
+ _currShift = currShift;
+ return true;
+} // end of KernCollider::initSlot
+
+
+// Determine how much the target slot needs to kern away from the given slot.
+// In other words, merge information from given slot's position with what the target slot knows
+// about how it can kern.
+// Return false if we know there is no collision, true if we think there might be one.
+bool KernCollider::mergeSlot(Segment *seg, Slot *slot, const Position &currShift, float currSpace, int dir, GR_MAYBE_UNUSED json * const dbgout)
+{
+ int rtl = (dir & 1) * 2 - 1;
+ const Rect &bb = seg->theGlyphBBoxTemporary(slot->gid());
+ const float sx = slot->origin().x + currShift.x;
+ float x = sx + (rtl > 0 ? bb.tr.x : bb.bl.x);
+ // this isn't going to reduce _mingap so skip
+ if ((rtl > 0 && x < _xbound - _mingap - currSpace) || (rtl <= 0 && x > _xbound + _mingap + currSpace))
+ return false;
+
+ const float sy = slot->origin().y + currShift.y;
+ int smin = std::max(0, int((bb.bl.y + (1 - _miny + sy)) / _sliceWidth + 1));
+ int smax = std::min((int)_edges.size() - 1, int((bb.tr.y + (1 - _miny + sy)) / _sliceWidth + 1));
+ bool collides = false;
+
+ for (int i = smin; i <= smax; ++i)
+ {
+ float t;
+ float y = (float)(_miny - 1 + (i + .5f) * _sliceWidth); // vertical center of slice
+ if (x * rtl > _edges[i] * rtl - _mingap - currSpace)
+ {
+ // 2 * currSpace to account for the space that is already separating them and the space we want to add
+ float m = get_edge(seg, slot, currShift, y, _sliceWidth, rtl > 0) + 2 * rtl * currSpace;
+ t = rtl * (_edges[i] - m);
+ // Check slices above and below (if any).
+ if (i < (int)_edges.size() - 1) t = std::min(t, rtl * (_edges[i+1] - m));
+ if (i > 0) t = std::min(t, rtl * (_edges[i-1] - m));
+ // _mingap is positive to shrink
+ if (t < _mingap)
+ {
+ _mingap = t;
+ collides = true;
+ }
+#if !defined GRAPHITE2_NTRACING
+ // Debugging - remember the closest neighboring edge for this slice.
+ if (rtl * m > rtl * _nearEdges[i])
+ {
+ _slotNear[i] = slot;
+ _nearEdges[i] = m;
+ }
+#endif
+ }
+ }
+ return collides; // note that true is not a necessarily reliable value
+
+} // end of KernCollider::mergeSlot
+
+
+// Return the amount to kern by.
+// TODO: do we need to make use of marginMin here? Probably not.
+Position KernCollider::resolve(GR_MAYBE_UNUSED Segment *seg, GR_MAYBE_UNUSED Slot *slot,
+ int dir, float margin, GR_MAYBE_UNUSED json * const dbgout)
+{
+ float resultNeeded = (1 - 2 * (dir & 1)) * (_mingap - margin);
+ float result = min(_limit.tr.x - _offsetPrev.x, max(resultNeeded, _limit.bl.x - _offsetPrev.x));
+
+#if !defined GRAPHITE2_NTRACING
+ if (dbgout)
+ {
+ *dbgout << json::object // slot
+ << "slot" << objectid(dslot(seg, _target))
+ << "gid" << _target->gid()
+ << "margin" << _margin
+ << "limit" << _limit
+ << "target" << json::object
+ << "origin" << _target->origin()
+ //<< "currShift" << _currShift
+ << "offsetPrev" << _offsetPrev
+ << "bbox" << seg->theGlyphBBoxTemporary(_target->gid())
+ << "slantBox" << seg->getFace()->glyphs().slant(_target->gid())
+ << "fix" << "kern"
+ << "slices" << _edges.size()
+ << "sliceWidth" << _sliceWidth
+ << json::close; // target object
+
+ *dbgout << "slices" << json::array;
+ for (int is = 0; is < (int)_edges.size(); is++)
+ {
+ *dbgout << json::flat << json::object
+ << "i" << is
+ << "targetEdge" << _edges[is]
+ << "neighbor" << objectid(dslot(seg, _slotNear[is]))
+ << "nearEdge" << _nearEdges[is]
+ << json::close;
+ }
+ *dbgout << json::close; // slices array
+
+ *dbgout
+ << "xbound" << _xbound
+ << "minGap" << _mingap
+ << "needed" << resultNeeded
+ << "result" << result
+ << "stillBad" << (result != resultNeeded)
+ << json::close; // slot object
+ }
+#endif
+
+ return Position(result, 0.);
+
+} // end of KernCollider::resolve
+
+void KernCollider::shift(const Position &mv, int dir)
+{
+ for (Vector<float>::iterator e = _edges.begin(); e != _edges.end(); ++e)
+ *e += mv.x;
+ _xbound += (1 - 2 * (dir & 1)) * mv.x;
+}
+
+//// SLOT-COLLISION ////
+
+// Initialize the collision attributes for the given slot.
+SlotCollision::SlotCollision(Segment *seg, Slot *slot)
+{
+ initFromSlot(seg, slot);
+}
+
+void SlotCollision::initFromSlot(Segment *seg, Slot *slot)
+{
+ // Initialize slot attributes from glyph attributes.
+ // The order here must match the order in the grcompiler code,
+ // GrcSymbolTable::AssignInternalGlyphAttrIDs.
+ uint16 gid = slot->gid();
+ uint16 aCol = seg->silf()->aCollision(); // flags attr ID
+ const GlyphFace * glyphFace = seg->getFace()->glyphs().glyphSafe(gid);
+ if (!glyphFace)
+ return;
+ const sparse &p = glyphFace->attrs();
+ _flags = p[aCol];
+ _limit = Rect(Position(p[aCol+1], p[aCol+2]),
+ Position(p[aCol+3], p[aCol+4]));
+ _margin = p[aCol+5];
+ _marginWt = p[aCol+6];
+
+ _seqClass = p[aCol+7];
+ _seqProxClass = p[aCol+8];
+ _seqOrder = p[aCol+9];
+ _seqAboveXoff = p[aCol+10];
+ _seqAboveWt = p[aCol+11];
+ _seqBelowXlim = p[aCol+12];
+ _seqBelowWt = p[aCol+13];
+ _seqValignHt = p[aCol+14];
+ _seqValignWt = p[aCol+15];
+
+ // These attributes do not have corresponding glyph attribute:
+ _exclGlyph = 0;
+ _exclOffset = Position(0, 0);
+}
+
+float SlotCollision::getKern(int dir) const
+{
+ if ((_flags & SlotCollision::COLL_KERN) != 0)
+ return float(_shift.x * ((dir & 1) ? -1 : 1));
+ else
+ return 0;
+}
+
diff --git a/Build/source/libs/graphite2/graphite2-1.3.0/src/Decompressor.cpp b/Build/source/libs/graphite2/graphite2-1.3.0/src/Decompressor.cpp
new file mode 100644
index 00000000000..919678a640b
--- /dev/null
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/Decompressor.cpp
@@ -0,0 +1,102 @@
+/* Copyright (c) 2012, Siyuan Fu <fusiyuan2010@gmail.com>
+ Copyright (c) 2015, SIL International
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ 3. Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+#include <cassert>
+
+#include "inc/Decompressor.h"
+#include "inc/Shrinker.h"
+
+using namespace shrinker;
+
+namespace {
+
+u8 const LONG_DIST = 0x10;
+u8 const MATCH_LEN = 0x0f;
+
+template <int M>
+inline
+u32 read_literal(u8 const * &s, u8 const * const e, u32 l) {
+ if (unlikely(l == M))
+ {
+ u8 b = 0;
+ do { l += b = *s++; } while(b==0xff && s != e);
+ }
+ return l;
+}
+
+bool read_directive(u8 const * &src, u8 const * const end, u32 & literal_len, u32 & match_len, u32 & match_dist)
+{
+ u8 const flag = *src++;
+
+ literal_len = read_literal<7>(src, end, flag >> 5);
+ match_len = read_literal<15>(src, end, flag & MATCH_LEN);
+
+ match_dist = *src++;
+ if (flag & LONG_DIST)
+ match_dist |= ((*src++) << 8);
+
+ return match_dist != 0xffff;
+}
+
+}
+
+int shrinker::decompress(void const *in, size_t in_size, void *out, size_t out_size)
+{
+ u8 const * src = static_cast<u8 const *>(in),
+ * const src_end = src + in_size;
+
+ u8 * dst = static_cast<u8*>(out),
+ * const dst_end = dst + out_size;
+
+ u32 literal_len = 0,
+ match_len = 0,
+ match_dist = 0;
+
+ while (read_directive(src, src_end, literal_len, match_len, match_dist))
+ {
+ // Copy in literal
+ if (unlikely(dst + literal_len + sizeof(unsigned long) > dst_end)) return -1;
+ dst = memcpy_nooverlap(dst, src, literal_len);
+ src += literal_len;
+
+ // Copy, possibly repeating, match from earlier in the
+ // decoded output.
+ u8 const * const pcpy = dst - match_dist - 1;
+ if (unlikely(pcpy < static_cast<u8*>(out)
+ || dst + match_len + MINMATCH + sizeof(unsigned long) > dst_end)) return -1;
+ dst = memcpy_(dst, pcpy, match_len + MINMATCH);
+ }
+
+ if (unlikely(dst + literal_len > dst_end)) return -1;
+ dst = memcpy_nooverlap_surpass(dst, src, literal_len);
+
+ return dst - (u8*)out;
+}
+
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/Face.cpp b/Build/source/libs/graphite2/graphite2-1.3.0/src/Face.cpp
index e25f7260ac6..25e1b713095 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/Face.cpp
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/Face.cpp
@@ -28,6 +28,7 @@ of the License or (at your option) any later version.
#include "graphite2/Segment.h"
#include "inc/CmapCache.h"
#include "inc/debug.h"
+#include "inc/Decompressor.h"
#include "inc/Endian.h"
#include "inc/Face.h"
#include "inc/FileFace.h"
@@ -40,6 +41,16 @@ of the License or (at your option) any later version.
using namespace graphite2;
+namespace
+{
+enum compression
+{
+ NONE,
+ SHRINKER
+};
+
+}
+
Face::Face(const void* appFaceHandle/*non-NULL*/, const gr_face_ops & ops)
: m_appFaceHandle(appFaceHandle),
m_pFileFace(NULL),
@@ -84,20 +95,22 @@ bool Face::readGlyphs(uint32 faceOptions)
telemetry::category _glyph_cat(tele.glyph);
#endif
error_context(EC_READGLYPHS);
- if (faceOptions & gr_face_cacheCmap)
- m_cmap = new CachedCmap(*this);
- else
- m_cmap = new DirectCmap(*this);
-
m_pGlyphFaceCache = new GlyphCache(*this, faceOptions);
+
if (e.test(!m_pGlyphFaceCache, E_OUTOFMEM)
|| e.test(m_pGlyphFaceCache->numGlyphs() == 0, E_NOGLYPHS)
- || e.test(m_pGlyphFaceCache->unitsPerEm() == 0, E_BADUPEM)
- || e.test(!m_cmap, E_OUTOFMEM) || e.test(!*m_cmap, E_BADCMAP))
+ || e.test(m_pGlyphFaceCache->unitsPerEm() == 0, E_BADUPEM))
{
return error(e);
}
+ if (faceOptions & gr_face_cacheCmap)
+ m_cmap = new CachedCmap(*this);
+ else
+ m_cmap = new DirectCmap(*this);
+ if (e.test(!m_cmap, E_OUTOFMEM) || e.test(!*m_cmap, E_BADCMAP))
+ return error(e);
+
if (faceOptions & gr_face_preloadGlyphs)
nameTable(); // preload the name table along with the glyphs.
@@ -119,10 +132,12 @@ bool Face::readGraphite(const Table & silf)
if (version >= 0x00030000)
be::skip<uint32>(p); // compilerVersion
m_numSilf = be::read<uint16>(p);
+
be::skip<uint16>(p); // reserved
bool havePasses = false;
m_silfs = new Silf[m_numSilf];
+ if (e.test(!m_silfs, E_OUTOFMEM)) return error(e);
for (int i = 0; i < m_numSilf; i++)
{
error_context(EC_ASILF + (i << 8));
@@ -158,9 +173,14 @@ bool Face::runGraphite(Segment *seg, const Silf *aSilf) const
}
#endif
- bool res = aSilf->runGraphite(seg, 0, aSilf->justificationPass(), true);
+ bool res = aSilf->runGraphite(seg, 0, aSilf->positionPass(), true);
if (res)
- res = aSilf->runGraphite(seg, aSilf->positionPass(), aSilf->numPasses(), false);
+ {
+ seg->associateChars(0, seg->charInfoCount());
+ if (aSilf->flags() & 0x20)
+ res &= seg->initCollisions();
+ res &= aSilf->runGraphite(seg, aSilf->positionPass(), aSilf->numPasses(), false);
+ }
#if !defined GRAPHITE2_NTRACING
if (dbgout)
@@ -245,17 +265,24 @@ uint16 Face::languageForLocale(const char * locale) const
return 0;
}
-Face::Table::Table(const Face & face, const Tag n) throw()
-: _f(&face)
+
+
+Face::Table::Table(const Face & face, const Tag n, uint32 version) throw()
+: _f(&face), _compressed(false)
{
size_t sz = 0;
- _p = reinterpret_cast<const byte *>((*_f->m_ops.get_table)(_f->m_appFaceHandle, n, &sz));
+ _p = static_cast<const byte *>((*_f->m_ops.get_table)(_f->m_appFaceHandle, n, &sz));
_sz = uint32(sz);
+
if (!TtfUtil::CheckTable(n, _p, _sz))
{
this->~Table(); // Make sure we release the table buffer even if the table filed it's checks
_p = 0; _sz = 0;
+ return;
}
+
+ if (be::peek<uint32>(_p) >= version)
+ decompress();
}
Face::Table & Face::Table::operator = (const Table & rhs) throw()
@@ -267,3 +294,50 @@ Face::Table & Face::Table::operator = (const Table & rhs) throw()
return *this;
}
+Error Face::Table::decompress()
+{
+ Error e;
+ byte * uncompressed_table = 0;
+ size_t uncompressed_size = 0;
+
+ const byte * p = _p;
+ const uint32 version = be::read<uint32>(p); // Table version number.
+
+ // The scheme is in the top 5 bits of the 1st uint32.
+ const uint32 hdr = be::read<uint32>(p);
+ switch(compression(hdr >> 27))
+ {
+ case NONE: return e;
+ case SHRINKER:
+ {
+ uncompressed_size = hdr & 0x07ffffff;
+ uncompressed_table = gralloc<byte>(uncompressed_size);
+ if (!e.test(!uncompressed_table, E_OUTOFMEM))
+ e.test(shrinker::decompress(p, _sz - 2*sizeof(uint32), uncompressed_table, uncompressed_size) != signed(uncompressed_size), E_SHRINKERFAILED);
+ break;
+ }
+ default:
+ e.error(E_BADSCHEME);
+ };
+
+ // Check the uncompressed version number against the original.
+ if (!e)
+ e.test(be::peek<uint32>(uncompressed_table) != version, E_SHRINKERFAILED);
+
+ // Tell the provider to release the compressed form since were replacing
+ // it anyway.
+ this->~Table();
+
+ if (e)
+ {
+ free(uncompressed_table);
+ uncompressed_table = 0;
+ uncompressed_size = 0;
+ }
+
+ _p = uncompressed_table;
+ _sz = uncompressed_size + sizeof(uint32);
+ _compressed = true;
+
+ return e;
+}
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/FeatureMap.cpp b/Build/source/libs/graphite2/graphite2-1.3.0/src/FeatureMap.cpp
index 7cc3c7299bd..199ff700cf4 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/FeatureMap.cpp
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/FeatureMap.cpp
@@ -165,16 +165,16 @@ bool FeatureMap::readFeats(const Face & face)
label, uiName, flags,
uiSet, num_settings);
}
- m_defaultFeatures = new Features(bits/(sizeof(uint32)*8) + 1, *this);
+ new (&m_defaultFeatures) Features(bits/(sizeof(uint32)*8) + 1, *this);
m_pNamedFeats = new NameAndFeatureRef[m_numFeats];
- if (!m_defaultFeatures || !m_pNamedFeats)
+ if (!m_pNamedFeats)
{
free(defVals);
return false;
}
for (int i = 0; i < m_numFeats; ++i)
{
- m_feats[i].applyValToFeature(defVals[i], *m_defaultFeatures);
+ m_feats[i].applyValToFeature(defVals[i], m_defaultFeatures);
m_pNamedFeats[i] = m_feats+i;
}
@@ -214,7 +214,7 @@ bool SillMap::readSill(const Face & face)
uint16 numSettings = be::read<uint16>(p);
uint16 offset = be::read<uint16>(p);
if (offset + 8U * numSettings > sill.size() && numSettings > 0) return false;
- Features* feats = new Features(*m_FeatureMap.m_defaultFeatures);
+ Features* feats = new Features(m_FeatureMap.m_defaultFeatures);
if (!feats) return false;
const byte *pLSet = sill + offset;
@@ -250,7 +250,7 @@ Features* SillMap::cloneFeatures(uint32 langname/*0 means default*/) const
return new Features(*m_langFeats[i].m_pFeatures);
}
}
- return new Features (*m_FeatureMap.m_defaultFeatures);
+ return new Features (m_FeatureMap.m_defaultFeatures);
}
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/FileFace.cpp b/Build/source/libs/graphite2/graphite2-1.3.0/src/FileFace.cpp
index 3df67354b1b..3df67354b1b 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/FileFace.cpp
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/FileFace.cpp
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/Font.cpp b/Build/source/libs/graphite2/graphite2-1.3.0/src/Font.cpp
index 5cec362bfc6..5cec362bfc6 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/Font.cpp
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/Font.cpp
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/GlyphCache.cpp b/Build/source/libs/graphite2/graphite2-1.3.0/src/GlyphCache.cpp
index aee03055e17..59f418a2d80 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/GlyphCache.cpp
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/GlyphCache.cpp
@@ -31,6 +31,7 @@ of the License or (at your option) any later version.
#include "inc/GlyphCache.h"
#include "inc/GlyphFace.h"
#include "inc/Endian.h"
+#include "inc/bits.h"
using namespace graphite2;
@@ -70,13 +71,14 @@ namespace
protected:
const byte * _e, * _v;
- ptrdiff_t _n;
+ size_t _n;
};
typedef _glat_iterator<uint8> glat_iterator;
typedef _glat_iterator<uint16> glat2_iterator;
}
+const Rect GlyphCache::nullRect = Rect();
class GlyphCache::Loader
{
@@ -87,8 +89,10 @@ public:
unsigned short int units_per_em() const throw();
unsigned short int num_glyphs() const throw();
unsigned short int num_attrs() const throw();
+ bool has_boxes() const throw();
- const GlyphFace * read_glyph(unsigned short gid, GlyphFace &) const throw();
+ const GlyphFace * read_glyph(unsigned short gid, GlyphFace &, int *numsubs) const throw();
+ GlyphBox * read_box(uint16 gid, GlyphBox *curr, const GlyphFace & face) const throw();
CLASS_NEW_DELETE;
private:
@@ -101,6 +105,7 @@ private:
m_pGloc;
bool _long_fmt;
+ bool _has_boxes;
unsigned short _num_glyphs_graphics, //i.e. boundary box and advance
_num_glyphs_attributes,
_num_attrs; // number of glyph attributes per glyph
@@ -111,31 +116,49 @@ private:
GlyphCache::GlyphCache(const Face & face, const uint32 face_options)
: _glyph_loader(new Loader(face, bool(face_options & gr_face_dumbRendering))),
_glyphs(_glyph_loader && *_glyph_loader ? grzeroalloc<const GlyphFace *>(_glyph_loader->num_glyphs()) : 0),
+ _boxes(_glyph_loader && _glyph_loader->has_boxes() ? grzeroalloc<GlyphBox *>(_glyph_loader->num_glyphs()) : 0),
_num_glyphs(_glyphs ? _glyph_loader->num_glyphs() : 0),
_num_attrs(_glyphs ? _glyph_loader->num_attrs() : 0),
_upem(_glyphs ? _glyph_loader->units_per_em() : 0)
{
if ((face_options & gr_face_preloadGlyphs) && _glyph_loader && _glyphs)
{
+ int numsubs = 0;
GlyphFace * const glyphs = new GlyphFace [_num_glyphs];
if (!glyphs)
return;
// The 0 glyph is definately required.
- _glyphs[0] = _glyph_loader->read_glyph(0, glyphs[0]);
+ _glyphs[0] = _glyph_loader->read_glyph(0, glyphs[0], &numsubs);
// glyphs[0] has the same address as the glyphs array just allocated,
// thus assigning the &glyphs[0] to _glyphs[0] means _glyphs[0] points
// to the entire array.
const GlyphFace * loaded = _glyphs[0];
for (uint16 gid = 1; loaded && gid != _num_glyphs; ++gid)
- _glyphs[gid] = loaded = _glyph_loader->read_glyph(gid, glyphs[gid]);
+ _glyphs[gid] = loaded = _glyph_loader->read_glyph(gid, glyphs[gid], &numsubs);
if (!loaded)
{
_glyphs[0] = 0;
delete [] glyphs;
}
+ else if (numsubs > 0)
+ {
+ GlyphBox * boxes = (GlyphBox *)gralloc<char>(_num_glyphs * sizeof(GlyphBox) + (numsubs-1) * 8 * sizeof(float));
+ GlyphBox * currbox = boxes;
+
+ for (uint16 gid = 0; currbox && gid != _num_glyphs; ++gid)
+ {
+ _boxes[gid] = currbox;
+ currbox = _glyph_loader->read_box(gid, currbox, *_glyphs[gid]);
+ }
+ if (!currbox)
+ {
+ free(boxes);
+ _boxes[0] = 0;
+ }
+ }
delete _glyph_loader;
_glyph_loader = 0;
}
@@ -144,6 +167,11 @@ GlyphCache::GlyphCache(const Face & face, const uint32 face_options)
{
free(_glyphs);
_glyphs = 0;
+ if (_boxes)
+ {
+ free(_boxes);
+ _boxes = 0;
+ }
_num_glyphs = _num_attrs = _upem = 0;
}
}
@@ -163,6 +191,18 @@ GlyphCache::~GlyphCache()
delete [] _glyphs[0];
free(_glyphs);
}
+ if (_boxes)
+ {
+ if (_glyph_loader)
+ {
+ GlyphBox * * g = _boxes;
+ for (uint16 n = _num_glyphs; n; --n, ++g)
+ free(*g);
+ }
+ else
+ free(_boxes[0]);
+ free(_boxes);
+ }
delete _glyph_loader;
}
@@ -171,13 +211,23 @@ const GlyphFace *GlyphCache::glyph(unsigned short glyphid) const //result m
const GlyphFace * & p = _glyphs[glyphid];
if (p == 0 && _glyph_loader)
{
+ int numsubs = 0;
GlyphFace * g = new GlyphFace();
- if (g) p = _glyph_loader->read_glyph(glyphid, *g);
+ if (g) p = _glyph_loader->read_glyph(glyphid, *g, &numsubs);
if (!p)
{
delete g;
return *_glyphs;
}
+ if (_boxes)
+ {
+ _boxes[glyphid] = (GlyphBox *)gralloc<char>(sizeof(GlyphBox) + 8 * numsubs * sizeof(float));
+ if (!_glyph_loader->read_box(glyphid, _boxes[glyphid], *_glyphs[glyphid]))
+ {
+ free(_boxes[glyphid]);
+ _boxes[glyphid] = 0;
+ }
+ }
}
return p;
}
@@ -191,6 +241,7 @@ GlyphCache::Loader::Loader(const Face & face, const bool dumb_font)
_glyf(face, Tag::glyf),
_loca(face, Tag::loca),
_long_fmt(false),
+ _has_boxes(false),
_num_glyphs_graphics(0),
_num_glyphs_attributes(0),
_num_attrs(0)
@@ -203,7 +254,7 @@ GlyphCache::Loader::Loader(const Face & face, const bool dumb_font)
_num_glyphs_graphics = TtfUtil::GlyphCount(maxp);
// This will fail if the number of glyphs is wildly out of range.
- if (_glyf && TtfUtil::LocaLookup(_num_glyphs_graphics-1, _loca, _loca.size(), _head) == size_t(-1))
+ if (_glyf && TtfUtil::LocaLookup(_num_glyphs_graphics-1, _loca, _loca.size(), _head) == size_t(-2))
{
_head = Face::Table();
return;
@@ -211,7 +262,7 @@ GlyphCache::Loader::Loader(const Face & face, const bool dumb_font)
if (!dumb_font)
{
- if ((m_pGlat = Face::Table(face, Tag::Glat)) == NULL
+ if ((m_pGlat = Face::Table(face, Tag::Glat, 0x00030000)) == NULL
|| (m_pGloc = Face::Table(face, Tag::Gloc)) == NULL
|| m_pGloc.size() < 6)
{
@@ -219,7 +270,7 @@ GlyphCache::Loader::Loader(const Face & face, const bool dumb_font)
return;
}
const byte * p = m_pGloc;
- const int version = be::read<uint32>(p);
+ int version = be::read<uint32>(p);
const uint16 flags = be::read<uint16>(p);
_num_attrs = be::read<uint16>(p);
// We can accurately calculate the number of attributed glyphs by
@@ -231,13 +282,22 @@ GlyphCache::Loader::Loader(const Face & face, const bool dumb_font)
- sizeof(uint16)*(flags & 0x2 ? _num_attrs : 0))
/ (_long_fmt ? sizeof(uint32) : sizeof(uint16)) - 1;
- if (version != 0x00010000
+ if (version >= 0x00020000
|| _num_attrs == 0 || _num_attrs > 0x3000 // is this hard limit appropriate?
|| _num_glyphs_graphics > _num_glyphs_attributes)
{
_head = Face::Table();
return;
}
+
+ p = m_pGlat;
+ version = be::read<uint32>(p);
+ if (version >= 0x00040000) // reject Glat tables that are too new
+ {
+ _head = Face::Table();
+ return;
+ }
+ _has_boxes = (version == 0x00030000);
}
}
@@ -265,7 +325,13 @@ unsigned short int GlyphCache::Loader::num_attrs() const throw()
return _num_attrs;
}
-const GlyphFace * GlyphCache::Loader::read_glyph(unsigned short glyphid, GlyphFace & glyph) const throw()
+inline
+bool GlyphCache::Loader::has_boxes () const throw()
+{
+ return _has_boxes;
+}
+
+const GlyphFace * GlyphCache::Loader::read_glyph(unsigned short glyphid, GlyphFace & glyph, int *numsubs) const throw()
{
Rect bbox;
Position advance;
@@ -312,30 +378,89 @@ const GlyphFace * GlyphCache::Loader::read_glyph(unsigned short glyphid, GlyphFa
return 0;
const uint32 glat_version = be::peek<uint32>(m_pGlat);
+ if (glat_version == 0x00030000)
+ {
+ const byte * p = m_pGlat + glocs;
+ uint16 bmap = be::read<uint16>(p);
+ int num = bit_set_count((uint32)bmap);
+ if (numsubs) *numsubs += num;
+ glocs += 6 + 8 * num;
+ if (glocs > gloce)
+ return 0;
+ }
if (glat_version < 0x00020000)
{
if (gloce - glocs < 2*sizeof(byte)+sizeof(uint16)
|| gloce - glocs > _num_attrs*(2*sizeof(byte)+sizeof(uint16)))
- {
- return 0;
- }
-
+ return 0;
new (&glyph) GlyphFace(bbox, advance, glat_iterator(m_pGlat + glocs), glat_iterator(m_pGlat + gloce));
}
else
{
- if (gloce - glocs < 3*sizeof(uint16)
+ if (gloce - glocs < 3*sizeof(uint16) // can a glyph have no attributes? why not?
|| gloce - glocs > _num_attrs*3*sizeof(uint16))
- {
- return 0;
- }
-
+ return 0;
new (&glyph) GlyphFace(bbox, advance, glat2_iterator(m_pGlat + glocs), glat2_iterator(m_pGlat + gloce));
}
-
if (!glyph.attrs() || glyph.attrs().capacity() > _num_attrs)
return 0;
}
-
return &glyph;
}
+
+inline float scale_to(uint8 t, float zmin, float zmax)
+{
+ return (zmin + t * (zmax - zmin) / 255);
+}
+
+Rect readbox(Rect &b, uint8 zxmin, uint8 zymin, uint8 zxmax, uint8 zymax)
+{
+ return Rect(Position(scale_to(zxmin, b.bl.x, b.tr.x), scale_to(zymin, b.bl.y, b.tr.y)),
+ Position(scale_to(zxmax, b.bl.x, b.tr.x), scale_to(zymax, b.bl.y, b.tr.y)));
+}
+
+GlyphBox * GlyphCache::Loader::read_box(uint16 gid, GlyphBox *curr, const GlyphFace & glyph) const throw()
+{
+ if (gid >= _num_glyphs_attributes) return 0;
+
+ const byte * gloc = m_pGloc;
+ size_t glocs = 0, gloce = 0;
+
+ be::skip<uint32>(gloc);
+ be::skip<uint16>(gloc,2);
+ if (_long_fmt)
+ {
+ be::skip<uint32>(gloc, gid);
+ glocs = be::read<uint32>(gloc);
+ gloce = be::peek<uint32>(gloc);
+ }
+ else
+ {
+ be::skip<uint16>(gloc, gid);
+ glocs = be::read<uint16>(gloc);
+ gloce = be::peek<uint16>(gloc);
+ }
+
+ if (glocs >= m_pGlat.size() || gloce > m_pGlat.size())
+ return 0;
+
+ const byte * p = m_pGlat + glocs;
+ uint16 bmap = be::read<uint16>(p);
+ int num = bit_set_count((uint32)bmap);
+
+ Rect bbox = glyph.theBBox();
+ Rect diamax(Position(bbox.bl.x + bbox.bl.y, bbox.bl.x - bbox.tr.y),
+ Position(bbox.tr.x + bbox.tr.y, bbox.tr.x - bbox.bl.y));
+ Rect diabound = readbox(diamax, p[0], p[2], p[1], p[3]);
+ ::new (curr) GlyphBox(num, bmap, &diabound);
+ be::skip<uint8>(p, 4);
+
+ for (int i = 0; i < num * 2; ++i)
+ {
+ Rect box = readbox((i & 1) ? diamax : bbox, p[0], p[2], p[1], p[3]);
+ curr->addSubBox(i >> 1, i & 1, &box);
+ be::skip<uint8>(p, 4);
+ }
+ return (GlyphBox *)((char *)(curr) + sizeof(GlyphBox) + 2 * num * sizeof(Rect));
+}
+
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/GlyphFace.cpp b/Build/source/libs/graphite2/graphite2-1.3.0/src/GlyphFace.cpp
index 9fc11b2157e..9fc11b2157e 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/GlyphFace.cpp
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/GlyphFace.cpp
diff --git a/Build/source/libs/graphite2/graphite2-1.3.0/src/Intervals.cpp b/Build/source/libs/graphite2/graphite2-1.3.0/src/Intervals.cpp
new file mode 100644
index 00000000000..3a252c54fed
--- /dev/null
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/Intervals.cpp
@@ -0,0 +1,292 @@
+/* GRAPHITE2 LICENSING
+
+ Copyright 2010, SIL International
+ All rights reserved.
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should also have received a copy of the GNU Lesser General Public
+ License along with this library in the file named "LICENSE".
+ If not, write to the Free Software Foundation, 51 Franklin Street,
+ Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
+ internet at http://www.fsf.org/licenses/lgpl.html.
+
+Alternatively, the contents of this file may be used under the terms of the
+Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
+License, as published by the Free Software Foundation, either version 2
+of the License or (at your option) any later version.
+*/
+#include <algorithm>
+#include <cmath>
+#include <limits>
+
+#include "inc/Intervals.h"
+#include "inc/Segment.h"
+#include "inc/Slot.h"
+#include "inc/debug.h"
+#include "inc/bits.h"
+
+using namespace graphite2;
+
+#include <cmath>
+
+inline
+Zones::Exclusion Zones::Exclusion::split_at(float p) {
+ Exclusion r(*this);
+ r.xm = x = p;
+ return r;
+}
+
+inline
+void Zones::Exclusion::left_trim(float p) {
+ x = p;
+}
+
+inline
+Zones::Exclusion & Zones::Exclusion::operator += (Exclusion const & rhs) {
+ c += rhs.c; sm += rhs.sm; smx += rhs.smx; open = false;
+ return *this;
+}
+
+inline
+uint8 Zones::Exclusion::outcode(float val) const {
+ float p = val;
+ return ((p >= xm) << 1) | (p < x);
+}
+
+void Zones::exclude_with_margins(float xmin, float xmax, int axis) {
+ remove(xmin, xmax);
+ weightedAxis(axis, xmin-_margin_len, xmin, 0, 0, _margin_weight, xmin-_margin_len, 0, 0, false);
+ weightedAxis(axis, xmax, xmax+_margin_len, 0, 0, _margin_weight, xmax+_margin_len, 0, 0, false);
+}
+
+namespace
+{
+
+inline
+bool separated(float a, float b) {
+ return a != b;
+ //return std::fabs(a-b) > std::numeric_limits<float>::epsilon(); // std::epsilon may not work. but 0.5 fails exising 64 bit tests
+ //return std::fabs(a-b) > 0.5f;
+}
+
+}
+
+void Zones::insert(Exclusion e)
+{
+#if !defined GRAPHITE2_NTRACING
+ addDebug(&e);
+#endif
+ e.x = std::max(e.x, _pos);
+ e.xm = std::min(e.xm, _posm);
+ if (e.x >= e.xm) return;
+
+ for (iterator i = _exclusions.begin(), ie = _exclusions.end(); i != ie && e.x < e.xm; ++i)
+ {
+ const uint8 oca = e.outcode(i->x),
+ ocb = e.outcode(i->xm);
+ if ((oca & ocb) != 0) continue;
+
+ switch (oca ^ ocb) // What kind of overlap?
+ {
+ case 0: // e completely covers i
+ // split e at i.x into e1,e2
+ // split e2 at i.mx into e2,e3
+ // drop e1 ,i+e2, e=e3
+ *i += e;
+ e.left_trim(i->xm);
+ break;
+ case 1: // e overlaps on the rhs of i
+ // split i at e->x into i1,i2
+ // split e at i.mx into e1,e2
+ // trim i1, insert i2+e1, e=e2
+ if (!separated(i->xm, e.x)) break;
+ if (separated(i->x,e.x)) { i = _exclusions.insert(i,i->split_at(e.x)); ++i; }
+ *i += e;
+ e.left_trim(i->xm);
+ break;
+ case 2: // e overlaps on the lhs of i
+ // split e at i->x into e1,e2
+ // split i at e.mx into i1,i2
+ // drop e1, insert e2+i1, trim i2
+ if (!separated(e.xm, i->x)) return;
+ if (separated(e.xm, i->xm)) i = _exclusions.insert(i,i->split_at(e.xm));
+ *i += e;
+ return;
+ case 3: // i completely covers e
+ // split i at e.x into i1,i2
+ // split i2 at e.mx into i2,i3
+ // insert i1, insert e+i2
+ if (separated(e.xm, i->xm)) i = _exclusions.insert(i,i->split_at(e.xm));
+ i = _exclusions.insert(i, i->split_at(e.x));
+ *++i += e;
+ return;
+ }
+
+ ie = _exclusions.end();
+ }
+}
+
+
+void Zones::remove(float x, float xm)
+{
+#if !defined GRAPHITE2_NTRACING
+ removeDebug(x, xm);
+#endif
+ x = std::max(x, _pos);
+ xm = std::min(xm, _posm);
+ if (x >= xm) return;
+
+ for (iterator i = _exclusions.begin(), ie = _exclusions.end(); i != ie; ++i)
+ {
+ const uint8 oca = i->outcode(x),
+ ocb = i->outcode(xm);
+ if ((oca & ocb) != 0) continue;
+
+ switch (oca ^ ocb) // What kind of overlap?
+ {
+ case 0: // i completely covers e
+ if (separated(i->x, x)) { i = _exclusions.insert(i,i->split_at(x)); ++i; }
+ // no break
+ case 1: // i overlaps on the rhs of e
+ i->left_trim(xm);
+ return;
+ case 2: // i overlaps on the lhs of e
+ i->xm = x;
+ if (separated(i->x, i->xm)) break;
+ // no break
+ case 3: // e completely covers i
+ i = _exclusions.erase(i);
+ --i;
+ break;
+ }
+
+ ie = _exclusions.end();
+ }
+}
+
+
+Zones::const_iterator Zones::find_exclusion_under(float x) const
+{
+ int l = 0, h = _exclusions.size();
+
+ while (l < h)
+ {
+ int const p = (l+h) >> 1;
+ switch (_exclusions[p].outcode(x))
+ {
+ case 0 : return _exclusions.begin()+p;
+ case 1 : h = p; break;
+ case 2 :
+ case 3 : l = p+1; break;
+ }
+ }
+
+ return _exclusions.begin()+l;
+}
+
+
+float Zones::closest(float origin, float & cost) const
+{
+ float best_c = std::numeric_limits<float>::max(),
+ best_x = 0;
+
+ const const_iterator start = find_exclusion_under(origin);
+
+ // Forward scan looking for lowest cost
+ for (const_iterator i = start, ie = _exclusions.end(); i != ie; ++i)
+ if (i->track_cost(best_c, best_x, origin)) break;
+
+ // Backward scan looking for lowest cost
+ // We start from the exclusion to the immediate left of start since we've
+ // already tested start with the right most scan above.
+ for (const_iterator i = start-1, ie = _exclusions.begin()-1; i != ie; --i)
+ if (i->track_cost(best_c, best_x, origin)) break;
+
+ cost = (best_c == std::numeric_limits<float>::max() ? -1 : best_c);
+ return best_x;
+}
+
+
+// Cost and test position functions
+
+bool Zones::Exclusion::track_cost(float & best_cost, float & best_pos, float origin) const {
+ const float p = test_position(origin),
+ localc = cost(p - origin);
+ if (open && localc > best_cost) return true;
+
+ if (localc < best_cost)
+ {
+ best_cost = localc;
+ best_pos = p;
+ }
+ return false;
+}
+
+inline
+float Zones::Exclusion::cost(float p) const {
+ return (sm * p - 2 * smx) * p + c;
+}
+
+
+float Zones::Exclusion::test_position(float origin) const {
+ if (sm < 0)
+ {
+ // sigh, test both ends and perhaps the middle too!
+ float res = x;
+ float cl = cost(x);
+ if (x < origin && xm > origin)
+ {
+ float co = cost(origin);
+ if (co < cl)
+ {
+ cl = co;
+ res = origin;
+ }
+ }
+ float cr = cost(xm);
+ return cl > cr ? xm : res;
+ }
+ else
+ {
+ float zerox = smx / sm + origin;
+ if (zerox < x) return x;
+ else if (zerox > xm) return xm;
+ else return zerox;
+ }
+}
+
+
+#if !defined GRAPHITE2_NTRACING
+
+void Zones::jsonDbgOut(Segment *seg) const {
+
+ if (_dbg)
+ {
+ for (Zones::idebugs s = dbgs_begin(), e = dbgs_end(); s != e; ++s)
+ {
+ *_dbg << json::flat << json::array
+ << objectid(dslot(seg, (Slot *)(s->_env[0])))
+ << reinterpret_cast<ptrdiff_t>(s->_env[1]);
+ if (s->_isdel)
+ *_dbg << "remove" << Position(s->_excl.x, s->_excl.xm);
+ else
+ *_dbg << "exclude" << json::flat << json::array
+ << s->_excl.x << s->_excl.xm
+ << s->_excl.sm << s->_excl.smx << s->_excl.c
+ << json::close;
+ *_dbg << json::close;
+ }
+ }
+}
+
+#endif
+
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/Justifier.cpp b/Build/source/libs/graphite2/graphite2-1.3.0/src/Justifier.cpp
index 5816ee0890f..9f95033255c 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/Justifier.cpp
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/Justifier.cpp
@@ -60,7 +60,7 @@ void JustifyTotal::accumulate(Slot *s, Segment *seg, int level)
m_tWeight += s->getJustify(seg, level, 3);
}
-float Segment::justify(Slot *pSlot, const Font *font, float width, GR_MAYBE_UNUSED justFlags flags, Slot *pFirst, Slot *pLast)
+float Segment::justify(Slot *pSlot, const Font *font, float width, GR_MAYBE_UNUSED justFlags jflags, Slot *pFirst, Slot *pLast)
{
Slot *s, *end;
float currWidth = 0.0;
@@ -76,11 +76,11 @@ float Segment::justify(Slot *pSlot, const Font *font, float width, GR_MAYBE_UNUS
while (!pLast->isBase()) pLast = pLast->attachedTo();
const float base = pFirst->origin().x / scale;
width = width / scale;
- if ((flags & gr_justEndInline) == 0)
+ if ((jflags & gr_justEndInline) == 0)
{
do {
Rect bbox = theGlyphBBoxTemporary(pLast->glyph());
- if (bbox.bl.x != 0. || bbox.bl.y != 0. || bbox.tr.x != 0. || bbox.tr.y == 0.)
+ if (bbox.bl.x != 0.f || bbox.bl.y != 0.f || bbox.tr.x != 0.f || bbox.tr.y == 0.f)
break;
pLast = pLast->prev();
} while (pLast != pFirst);
@@ -116,8 +116,7 @@ float Segment::justify(Slot *pSlot, const Font *font, float width, GR_MAYBE_UNUS
++numLevels;
}
- JustifyTotal *stats = new JustifyTotal[numLevels];
- if (!stats) return -1.0;
+ Vector<JustifyTotal> stats(numLevels);
for (s = pFirst; s != end; s = s->nextSibling())
{
float w = s->origin().x / scale + s->advance() - base;
@@ -127,7 +126,7 @@ float Segment::justify(Slot *pSlot, const Font *font, float width, GR_MAYBE_UNUS
s->just(0);
}
- for (int i = (width < 0.0) ? -1 : numLevels - 1; i >= 0; --i)
+ for (int i = (width < 0.0f) ? -1 : numLevels - 1; i >= 0; --i)
{
float diff;
float error = 0.;
@@ -197,7 +196,7 @@ float Segment::justify(Slot *pSlot, const Font *font, float width, GR_MAYBE_UNUS
<< "passes" << json::array;
#endif
- if (m_silf->justificationPass() != m_silf->positionPass() && (width >= 0. || (silf()->flags() & 1)))
+ if (m_silf->justificationPass() != m_silf->positionPass() && (width >= 0.f || (silf()->flags() & 1)))
m_silf->runGraphite(this, m_silf->justificationPass(), m_silf->positionPass());
#if !defined GRAPHITE2_NTRACING
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/NameTable.cpp b/Build/source/libs/graphite2/graphite2-1.3.0/src/NameTable.cpp
index f83adb09cd8..f83adb09cd8 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/NameTable.cpp
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/NameTable.cpp
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/Pass.cpp b/Build/source/libs/graphite2/graphite2-1.3.0/src/Pass.cpp
index 140b45bcca0..fde290b14fd 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/Pass.cpp
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/Pass.cpp
@@ -31,10 +31,12 @@ of the License or (at your option) any later version.
#include <cstring>
#include <cstdlib>
#include <cassert>
+#include <cmath>
#include "inc/Segment.h"
#include "inc/Code.h"
#include "inc/Rule.h"
#include "inc/Error.h"
+#include "inc/Collider.h"
using namespace graphite2;
using vm::Machine;
@@ -49,6 +51,8 @@ Pass::Pass()
m_startStates(0),
m_transitions(0),
m_states(0),
+ m_codes(0),
+ m_progs(0),
m_flags(0),
m_iMaxLoop(0),
m_numGlyphs(0),
@@ -70,21 +74,27 @@ Pass::~Pass()
free(m_states);
free(m_ruleMap);
- delete [] m_rules;
+ if (m_rules) delete [] m_rules;
+ if (m_codes) delete [] m_codes;
+ free(m_progs);
}
-bool Pass::readPass(const byte * const pass_start, size_t pass_length, size_t subtable_base, GR_MAYBE_UNUSED Face & face, Error &e)
+bool Pass::readPass(const byte * const pass_start, size_t pass_length, size_t subtable_base,
+ GR_MAYBE_UNUSED Face & face, passtype pt, GR_MAYBE_UNUSED uint32 version, Error &e)
{
- const byte * p = pass_start,
- * const pass_end = p + pass_length;
+ const byte * p = pass_start,
+ * const pass_end = p + pass_length;
size_t numRanges;
if (e.test(pass_length < 40, E_BADPASSLENGTH)) return face.error(e);
// Read in basic values
m_flags = be::read<byte>(p);
+ if (e.test((m_flags & 15) && pt < PASS_TYPE_POSITIONING, E_BADCOLLISIONPASS))
+ return face.error(e);
m_iMaxLoop = be::read<byte>(p);
be::skip<byte>(p,2); // skip maxContext & maxBackup
m_numRules = be::read<uint16>(p);
+ if (e.test(!m_numRules && !(m_flags & 7), E_BADEMPTYPASS)) return face.error(e);
be::skip<uint16>(p); // fsmOffset - not sure why we would want this
const byte * const pcCode = pass_start + be::read<uint32>(p) - subtable_base,
* const rcCode = pass_start + be::read<uint32>(p) - subtable_base,
@@ -101,7 +111,7 @@ bool Pass::readPass(const byte * const pass_start, size_t pass_length, size_t su
if ( e.test(m_numTransition > m_numStates, E_BADNUMTRANS)
|| e.test(m_numSuccess > m_numStates, E_BADNUMSUCCESS)
|| e.test(m_numSuccess + m_numTransition < m_numStates, E_BADNUMSTATES)
- || e.test(numRanges == 0, E_NORANGES))
+ || e.test(m_numRules && numRanges == 0, E_NORANGES))
return face.error(e);
m_successStart = m_numStates - m_numSuccess;
@@ -131,23 +141,26 @@ bool Pass::readPass(const byte * const pass_start, size_t pass_length, size_t su
be::skip<uint16>(p, m_numRules);
const byte * const precontext = p;
be::skip<byte>(p, m_numRules);
- be::skip<byte>(p); // skip reserved byte
- if (e.test(p + sizeof(uint16) > pass_end, E_BADCTXTLENS)) return face.error(e);
+ if (e.test(p + sizeof(uint16) + sizeof(uint8) > pass_end, E_BADCTXTLENS)) return face.error(e);
+ m_colThreshold = be::read<uint8>(p);
+ if (m_colThreshold == 0) m_colThreshold = 10; // A default
const size_t pass_constraint_len = be::read<uint16>(p);
+
const uint16 * const o_constraint = reinterpret_cast<const uint16 *>(p);
be::skip<uint16>(p, m_numRules + 1);
const uint16 * const o_actions = reinterpret_cast<const uint16 *>(p);
be::skip<uint16>(p, m_numRules + 1);
const byte * const states = p;
+ if (e.test(p + 2 * m_numTransition*m_numColumns >= pass_end, E_BADPASSLENGTH)) return face.error(e);
be::skip<int16>(p, m_numTransition*m_numColumns);
- be::skip<byte>(p); // skip reserved byte
- if (e.test(p != pcCode, E_BADPASSCCODEPTR) || e.test(p >= pass_end, E_BADPASSLENGTH)) return face.error(e);
+ be::skip<uint8>(p);
+ if (e.test(p != pcCode, E_BADPASSCCODEPTR)) return face.error(e);
be::skip<byte>(p, pass_constraint_len);
- if (e.test(p != rcCode, E_BADRULECCODEPTR) || e.test(p >= pass_end, E_BADPASSLENGTH)
+ if (e.test(p != rcCode, E_BADRULECCODEPTR)
|| e.test(size_t(rcCode - pcCode) != pass_constraint_len, E_BADCCODELEN)) return face.error(e);
be::skip<byte>(p, be::peek<uint16>(o_constraint + m_numRules));
- if (e.test(p != aCode, E_BADACTIONCODEPTR) || e.test(p >= pass_end, E_BADPASSLENGTH)) return face.error(e);
+ if (e.test(p != aCode, E_BADACTIONCODEPTR)) return face.error(e);
be::skip<byte>(p, be::peek<uint16>(o_actions + m_numRules));
// We should be at the end or within the pass
@@ -158,19 +171,22 @@ bool Pass::readPass(const byte * const pass_start, size_t pass_length, size_t su
{
face.error_context(face.error_context() + 1);
m_cPConstraint = vm::Machine::Code(true, pcCode, pcCode + pass_constraint_len,
- precontext[0], be::peek<uint16>(sort_keys), *m_silf, face);
+ precontext[0], be::peek<uint16>(sort_keys), *m_silf, face, PASS_TYPE_UNKNOWN);
if (e.test(!m_cPConstraint, E_OUTOFMEM)
- || e.test(m_cPConstraint.status(), m_cPConstraint.status() + E_CODEFAILURE))
+ || e.test(!m_cPConstraint, m_cPConstraint.status() + E_CODEFAILURE))
return face.error(e);
face.error_context(face.error_context() - 1);
}
- if (!readRanges(ranges, numRanges, e)) return face.error(e);
- if (!readRules(rule_map, numEntries, precontext, sort_keys,
- o_constraint, rcCode, o_actions, aCode, face, e)) return false;
+ if (m_numRules)
+ {
+ if (!readRanges(ranges, numRanges, e)) return face.error(e);
+ if (!readRules(rule_map, numEntries, precontext, sort_keys,
+ o_constraint, rcCode, o_actions, aCode, face, pt, e)) return false;
+ }
#ifdef GRAPHITE2_TELEMETRY
telemetry::category _states_cat(face.tele.states);
#endif
- return readStates(start_states, states, o_rule_map, face, e);
+ return m_numRules ? readStates(start_states, states, o_rule_map, face, e) : true;
}
@@ -178,12 +194,11 @@ bool Pass::readRules(const byte * rule_map, const size_t num_entries,
const byte *precontext, const uint16 * sort_key,
const uint16 * o_constraint, const byte *rc_data,
const uint16 * o_action, const byte * ac_data,
- Face & face, Error &e)
+ Face & face, passtype pt, Error &e)
{
const byte * const ac_data_end = ac_data + be::peek<uint16>(o_action + m_numRules);
const byte * const rc_data_end = rc_data + be::peek<uint16>(o_constraint + m_numRules);
- if (e.test(!(m_rules = new Rule [m_numRules]), E_OUTOFMEM)) return face.error(e);
precontext += m_numRules;
sort_key += m_numRules;
o_constraint += m_numRules;
@@ -193,6 +208,15 @@ bool Pass::readRules(const byte * rule_map, const size_t num_entries,
const byte * ac_begin = 0, * rc_begin = 0,
* ac_end = ac_data + be::peek<uint16>(o_action),
* rc_end = rc_data + be::peek<uint16>(o_constraint);
+
+ // Allocate pools
+ m_rules = new Rule [m_numRules];
+ m_codes = new Code [m_numRules*2];
+ m_progs = static_cast<byte *>(malloc((ac_end - ac_data + rc_end - rc_data)
+ *(sizeof(vm::instr)+sizeof(byte))));
+ byte * prog_pool_free = m_progs;
+ if (e.test(!(m_rules && m_codes && m_progs), E_OUTOFMEM)) return face.error(e);
+
Rule * r = m_rules + m_numRules - 1;
for (size_t n = m_numRules; n; --n, --r, ac_end = ac_begin, rc_end = rc_begin)
{
@@ -211,8 +235,8 @@ bool Pass::readRules(const byte * rule_map, const size_t num_entries,
if (ac_begin > ac_end || ac_begin > ac_data_end || ac_end > ac_data_end
|| rc_begin > rc_end || rc_begin > rc_data_end || rc_end > rc_data_end)
return false;
- r->action = new vm::Machine::Code(false, ac_begin, ac_end, r->preContext, r->sort, *m_silf, face);
- r->constraint = new vm::Machine::Code(true, rc_begin, rc_end, r->preContext, r->sort, *m_silf, face);
+ r->action = new (m_codes+n*2-2) vm::Machine::Code(false, ac_begin, ac_end, r->preContext, r->sort, *m_silf, face, pt, prog_pool_free);
+ r->constraint = new (m_codes+n*2-1) vm::Machine::Code(true, rc_begin, rc_end, r->preContext, r->sort, *m_silf, face, pt, prog_pool_free);
if (e.test(!r->action || !r->constraint, E_OUTOFMEM)
|| e.test(r->action->status() != Code::loaded, r->action->status() + E_CODEFAILURE)
@@ -221,6 +245,17 @@ bool Pass::readRules(const byte * rule_map, const size_t num_entries,
return face.error(e);
}
+ // Shrink the program pool
+ ptrdiff_t const delta = static_cast<byte *>(realloc(m_progs, prog_pool_free - m_progs)) - m_progs;
+ if (delta)
+ {
+ m_progs += delta;
+ for (Code * c = m_codes, * const ce = c + m_numRules*2; c != ce; ++c)
+ {
+ c->externalProgramMoved(delta);
+ }
+ }
+
// Load the rule entries map
face.error_context((face.error_context() & 0xFFFF00) + EC_APASS);
RuleEntry * re = m_ruleMap = gralloc<RuleEntry>(num_entries);
@@ -325,33 +360,52 @@ bool Pass::readRanges(const byte * ranges, size_t num_ranges, Error &e)
}
-void Pass::runGraphite(Machine & m, FiniteStateMachine & fsm) const
+bool Pass::runGraphite(vm::Machine & m, FiniteStateMachine & fsm) const
{
Slot *s = m.slotMap().segment.first();
- if (!s || !testPassConstraint(m)) return;
- Slot *currHigh = s->next();
+ if (!s || !testPassConstraint(m)) return true;
+ if (m_numRules)
+ {
+ Slot *currHigh = s->next();
#if !defined GRAPHITE2_NTRACING
- if (fsm.dbgout) *fsm.dbgout << "rules" << json::array;
- json::closer rules_array_closer(fsm.dbgout);
+ if (fsm.dbgout) *fsm.dbgout << "rules" << json::array;
+ json::closer rules_array_closer(fsm.dbgout);
#endif
- m.slotMap().highwater(currHigh);
- int lc = m_iMaxLoop;
- do
- {
- findNDoRule(s, m, fsm);
- if (s && (m.slotMap().highpassed() || s == m.slotMap().highwater() || --lc == 0)) {
- if (!lc)
- {
-// if (dbgout) *dbgout << json::item << json::flat << rule_event(-1, s, 1);
- s = m.slotMap().highwater();
+ m.slotMap().highwater(currHigh);
+ int lc = m_iMaxLoop;
+ do
+ {
+ findNDoRule(s, m, fsm);
+ if (s && (s == m.slotMap().highwater() || m.slotMap().highpassed() || --lc == 0)) {
+ if (!lc)
+ s = m.slotMap().highwater();
+ lc = m_iMaxLoop;
+ if (s)
+ m.slotMap().highwater(s->next());
}
- lc = m_iMaxLoop;
- if (s)
- m.slotMap().highwater(s->next());
+ } while (s);
+ }
+
+ if (!(m_flags & 15) || !m.slotMap().segment.hasCollisionInfo())
+ return true;
+
+ if (m_flags & 7)
+ {
+ if (!(m.slotMap().segment.flags() & Segment::SEG_INITCOLLISIONS))
+ {
+ m.slotMap().segment.positionSlots(0, 0, 0, true);
+// m.slotMap().segment.flags(m.slotMap().segment.flags() | Segment::SEG_INITCOLLISIONS);
}
- } while (s);
+ if (!collisionShift(&m.slotMap().segment, m.slotMap().segment.dir(), fsm.dbgout))
+ return false;
+ }
+ if ((m_flags & 24) && !collisionKern(&m.slotMap().segment, m.slotMap().segment.dir(), fsm.dbgout))
+ return false;
+ if ((m_flags & 15) && !collisionFinish(&m.slotMap().segment, fsm.dbgout))
+ return false;
+ return true;
}
bool Pass::runFSM(FiniteStateMachine& fsm, Slot * slot) const
@@ -455,6 +509,7 @@ void Pass::findNDoRule(Slot * & slot, Machine &m, FiniteStateMachine & fsm) cons
}
slot = slot->next();
+ return;
}
#if !defined GRAPHITE2_NTRACING
@@ -464,9 +519,10 @@ void Pass::dumpRuleEventConsidered(const FiniteStateMachine & fsm, const RuleEnt
*fsm.dbgout << "considered" << json::array;
for (const RuleEntry *r = fsm.rules.begin(); r != &re; ++r)
{
- if (r->rule->preContext > fsm.slots.context()) continue;
- *fsm.dbgout << json::flat << json::object
- << "id" << r->rule - m_rules
+ if (r->rule->preContext > fsm.slots.context())
+ continue;
+ *fsm.dbgout << json::flat << json::object
+ << "id" << r->rule - m_rules
<< "failed" << true
<< "input" << json::flat << json::object
<< "start" << objectid(dslot(&fsm.slots.segment, input_slot(fsm.slots, -r->rule->preContext)))
@@ -586,15 +642,23 @@ int Pass::doAction(const Code *codeptr, Slot * & slot_out, vm::Machine & m) cons
void Pass::adjustSlot(int delta, Slot * & slot_out, SlotMap & smap) const
{
- if (delta < 0)
+ if (!slot_out)
{
- if (!slot_out)
+ if (smap.highpassed() || slot_out == smap.highwater())
{
slot_out = smap.segment.last();
++delta;
- if (smap.highpassed() && !smap.highwater())
+ if (!smap.highwater())
smap.highpassed(false);
}
+ else
+ {
+ slot_out = smap.segment.first();
+ --delta;
+ }
+ }
+ if (delta < 0)
+ {
while (++delta <= 0 && slot_out)
{
if (smap.highpassed() && smap.highwater() == slot_out)
@@ -604,11 +668,6 @@ void Pass::adjustSlot(int delta, Slot * & slot_out, SlotMap & smap) const
}
else if (delta > 0)
{
- if (!slot_out)
- {
- slot_out = smap.segment.first();
- --delta;
- }
while (--delta >= 0 && slot_out)
{
slot_out = slot_out->next();
@@ -618,3 +677,373 @@ void Pass::adjustSlot(int delta, Slot * & slot_out, SlotMap & smap) const
}
}
+bool Pass::collisionShift(Segment *seg, int dir, json * const dbgout) const
+{
+ ShiftCollider shiftcoll(dbgout);
+ // bool isfirst = true;
+ const uint8 numLoops = m_flags & 7; // number of loops permitted to fix collisions; does not include kerning
+ bool hasCollisions = false;
+ Slot *start = seg->first(); // turn on collision fixing for the first slot
+ Slot *end = NULL;
+ bool moved = false;
+
+#if !defined GRAPHITE2_NTRACING
+ if (dbgout)
+ *dbgout << "collisions" << json::array
+ << json::flat << json::object << "num-loops" << numLoops << json::close;
+#endif
+
+ while (start)
+ {
+#if !defined GRAPHITE2_NTRACING
+ if (dbgout) *dbgout << json::object << "phase" << "1" << "moves" << json::array;
+#endif
+ hasCollisions = false;
+ end = NULL;
+ // phase 1 : position shiftable glyphs, ignoring kernable glyphs
+ for (Slot *s = start; s; s = s->next())
+ {
+ const SlotCollision * c = seg->collisionInfo(s);
+ if (start && (c->flags() & (SlotCollision::COLL_FIX | SlotCollision::COLL_KERN)) == SlotCollision::COLL_FIX
+ && !resolveCollisions(seg, s, start, shiftcoll, false, dir, moved, hasCollisions, dbgout))
+ return false;
+ if (s != start && c->flags() & SlotCollision::COLL_END)
+ {
+ end = s->next();
+ break;
+ }
+ }
+
+#if !defined GRAPHITE2_NTRACING
+ if (dbgout)
+ *dbgout << json::close << json::close; // phase-1
+#endif
+
+ // phase 2 : loop until happy.
+ for (int i = 0; i < numLoops - 1; ++i)
+ {
+ if (hasCollisions || moved)
+ {
+
+#if !defined GRAPHITE2_NTRACING
+ if (dbgout)
+ *dbgout << json::object << "phase" << "2a" << "loop" << i << "moves" << json::array;
+#endif
+ // phase 2a : if any shiftable glyphs are in collision, iterate backwards,
+ // fixing them and ignoring other non-collided glyphs. Note that this handles ONLY
+ // glyphs that are actually in collision from phases 1 or 2b, and working backwards
+ // has the intended effect of breaking logjams.
+ if (hasCollisions)
+ {
+ hasCollisions = false;
+ #if 0
+ moved = true;
+ for (Slot *s = start; s != end; s = s->next())
+ {
+ SlotCollision * c = seg->collisionInfo(s);
+ c->setShift(Position(0, 0));
+ }
+ #endif
+ Slot *lend = end ? end->prev() : seg->last();
+ Slot *lstart = start->prev();
+ for (Slot *s = lend; s != lstart; s = s->prev())
+ {
+ SlotCollision * c = seg->collisionInfo(s);
+ if (start && (c->flags() & (SlotCollision::COLL_FIX | SlotCollision::COLL_KERN | SlotCollision::COLL_ISCOL))
+ == (SlotCollision::COLL_FIX | SlotCollision::COLL_ISCOL)) // ONLY if this glyph is still colliding
+ {
+ if (!resolveCollisions(seg, s, lend, shiftcoll, true, dir, moved, hasCollisions, dbgout))
+ return false;
+ c->setFlags(c->flags() | SlotCollision::COLL_TEMPLOCK);
+ }
+ }
+ }
+
+#if !defined GRAPHITE2_NTRACING
+ if (dbgout)
+ *dbgout << json::close << json::close // phase 2a
+ << json::object << "phase" << "2b" << "loop" << i << "moves" << json::array;
+#endif
+
+ // phase 2b : redo basic diacritic positioning pass for ALL glyphs. Each successive loop adjusts
+ // glyphs from their current adjusted position, which has the effect of gradually minimizing the
+ // resulting adjustment; ie, the final result will be gradually closer to the original location.
+ // Also it allows more flexibility in the final adjustment, since it is moving along the
+ // possible 8 vectors from successively different starting locations.
+ if (moved)
+ {
+ moved = false;
+ for (Slot *s = start; s != end; s = s->next())
+ {
+ SlotCollision * c = seg->collisionInfo(s);
+ if (start && (c->flags() & (SlotCollision::COLL_FIX | SlotCollision::COLL_TEMPLOCK
+ | SlotCollision::COLL_KERN)) == SlotCollision::COLL_FIX
+ && !resolveCollisions(seg, s, start, shiftcoll, false, dir, moved, hasCollisions, dbgout))
+ return false;
+ else if (c->flags() & SlotCollision::COLL_TEMPLOCK)
+ c->setFlags(c->flags() & ~SlotCollision::COLL_TEMPLOCK);
+ }
+ }
+ // if (!hasCollisions) // no, don't leave yet because phase 2b will continue to improve things
+ // break;
+#if !defined GRAPHITE2_NTRACING
+ if (dbgout)
+ *dbgout << json::close << json::close; // phase 2
+#endif
+ }
+ }
+ if (!end)
+ break;
+ start = NULL;
+ for (Slot *s = end->prev(); s; s = s->next())
+ {
+ if (seg->collisionInfo(s)->flags() & SlotCollision::COLL_START)
+ {
+ start = s;
+ break;
+ }
+ }
+ }
+ return true;
+}
+
+bool Pass::collisionKern(Segment *seg, int dir, json * const dbgout) const
+{
+ KernCollider kerncoll(dbgout);
+ Slot *start = seg->first();
+ float ymin = 1e38f;
+ float ymax = -1e38f;
+ const GlyphCache &gc = seg->getFace()->glyphs();
+
+ // phase 3 : handle kerning of clusters
+#if !defined GRAPHITE2_NTRACING
+ if (dbgout)
+ *dbgout << json::object << "phase" << "3" << "moves" << json::array;
+#endif
+
+ for (Slot *s = seg->first(); s; s = s->next())
+ {
+ if (!gc.check(s->gid()))
+ return false;
+ const SlotCollision * c = seg->collisionInfo(s);
+ const Rect &bbox = seg->theGlyphBBoxTemporary(s->gid());
+ float y = s->origin().y + c->shift().y;
+ ymax = max(y + bbox.tr.y, ymax);
+ ymin = min(y + bbox.bl.y, ymin);
+ if (start && (c->flags() & (SlotCollision::COLL_KERN | SlotCollision::COLL_FIX))
+ == (SlotCollision::COLL_KERN | SlotCollision::COLL_FIX))
+ resolveKern(seg, s, start, kerncoll, dir, ymin, ymax, dbgout);
+ if (c->flags() & SlotCollision::COLL_END)
+ start = NULL;
+ if (c->flags() & SlotCollision::COLL_START)
+ start = s;
+ }
+
+#if !defined GRAPHITE2_NTRACING
+ if (dbgout)
+ *dbgout << json::close << json::close; // phase 3
+#endif
+ return true;
+}
+
+bool Pass::collisionFinish(Segment *seg, GR_MAYBE_UNUSED json * const dbgout) const
+{
+ for (Slot *s = seg->first(); s; s = s->next())
+ {
+ SlotCollision *c = seg->collisionInfo(s);
+ if (c->shift().x != 0 || c->shift().y != 0)
+ {
+ const Position newOffset = c->shift();
+ const Position nullPosition(0, 0);
+ c->setOffset(newOffset + c->offset());
+ c->setShift(nullPosition);
+ }
+ }
+// seg->positionSlots();
+
+#if !defined GRAPHITE2_NTRACING
+ if (dbgout)
+ *dbgout << json::close;
+#endif
+ return true;
+}
+
+// Can slot s be kerned, or is it attached to something that can be kerned?
+static bool inKernCluster(Segment *seg, Slot *s)
+{
+ SlotCollision *c = seg->collisionInfo(s);
+ if (c->flags() & SlotCollision::COLL_KERN /** && c->flags() & SlotCollision::COLL_FIX **/ )
+ return true;
+ while (s->attachedTo())
+ {
+ s = s->attachedTo();
+ c = seg->collisionInfo(s);
+ if (c->flags() & SlotCollision::COLL_KERN /** && c->flags() & SlotCollision::COLL_FIX **/ )
+ return true;
+ }
+ return false;
+}
+
+// Fix collisions for the given slot.
+// Return true if everything was fixed, false if there are still collisions remaining.
+// isRev means be we are processing backwards.
+bool Pass::resolveCollisions(Segment *seg, Slot *slotFix, Slot *start,
+ ShiftCollider &coll, GR_MAYBE_UNUSED bool isRev, int dir, bool &moved, bool &hasCol,
+ json * const dbgout) const
+{
+ Slot * nbor; // neighboring slot
+ SlotCollision *cFix = seg->collisionInfo(slotFix);
+ if (!coll.initSlot(seg, slotFix, cFix->limit(), cFix->margin(), cFix->marginWt(),
+ cFix->shift(), cFix->offset(), dir, dbgout))
+ return false;
+ bool collides = false;
+ // When we're processing forward, ignore kernable glyphs that preceed the target glyph.
+ // When processing backward, don't ignore these until we pass slotFix.
+ bool ignoreForKern = !isRev;
+ bool rtl = dir & 1;
+ Slot *base = slotFix;
+ while (base->attachedTo())
+ base = base->attachedTo();
+ Position zero(0., 0.);
+
+ // Look for collisions with the neighboring glyphs.
+ for (nbor = start; nbor; nbor = isRev ? nbor->prev() : nbor->next())
+ {
+ SlotCollision *cNbor = seg->collisionInfo(nbor);
+ bool sameCluster = nbor->isChildOf(base);
+ if (nbor != slotFix // don't process if this is the slot of interest
+ && !(cNbor->flags() & SlotCollision::COLL_IGNORE) // don't process if ignoring
+ && (nbor == base || sameCluster // process if in the same cluster as slotFix
+ || !inKernCluster(seg, nbor) // or this cluster is not to be kerned
+ || (rtl ^ ignoreForKern)) // or it comes before(ltr) or after(rtl)
+ && (!isRev // if processing forwards then good to merge otherwise only:
+ || !(cNbor->flags() & SlotCollision::COLL_FIX) // merge in immovable stuff
+ || (cNbor->flags() & SlotCollision::COLL_KERN && !sameCluster) // ignore other kernable clusters
+ || (cNbor->flags() & SlotCollision::COLL_ISCOL)) // test against other collided glyphs
+ && !coll.mergeSlot(seg, nbor, cNbor->shift(), !ignoreForKern, sameCluster, collides, false, dbgout))
+ return false;
+ else if (nbor == slotFix)
+ // Switching sides of this glyph - if we were ignoring kernable stuff before, don't anymore.
+ ignoreForKern = !ignoreForKern;
+
+ if (nbor != start && (cNbor->flags() & (isRev ? SlotCollision::COLL_START : SlotCollision::COLL_END)))
+ break;
+ }
+ bool isCol = false;
+ if (collides || cFix->shift().x != 0.f || cFix->shift().y != 0.f)
+ {
+ Position shift = coll.resolve(seg, isCol, dbgout);
+ // isCol has been set to true if a collision remains.
+ if (std::fabs(shift.x) < 1e38f && std::fabs(shift.y) < 1e38f)
+ {
+ if (sqr(shift.x-cFix->shift().x) + sqr(shift.y-cFix->shift().y) >= m_colThreshold * m_colThreshold)
+ moved = true;
+ cFix->setShift(shift);
+ if (slotFix->firstChild())
+ {
+ Rect bbox;
+ Position here = slotFix->origin() + shift;
+ float clusterMin = here.x;
+ slotFix->firstChild()->finalise(seg, NULL, here, bbox, 0, clusterMin, false);
+ }
+ }
+ }
+ else
+ {
+ // This glyph is not colliding with anything.
+#if !defined GRAPHITE2_NTRACING
+ if (dbgout)
+ {
+ *dbgout << json::object
+ << "missed" << objectid(dslot(seg, slotFix));
+ coll.outputJsonDbg(dbgout, seg, -1);
+ *dbgout << json::close;
+ }
+#endif
+ }
+
+ // Set the is-collision flag bit.
+ if (isCol)
+ { cFix->setFlags(cFix->flags() | SlotCollision::COLL_ISCOL | SlotCollision::COLL_KNOWN); }
+ else
+ { cFix->setFlags((cFix->flags() & ~SlotCollision::COLL_ISCOL) | SlotCollision::COLL_KNOWN); }
+ hasCol |= isCol;
+ return true;
+}
+
+float Pass::resolveKern(Segment *seg, Slot *slotFix, GR_MAYBE_UNUSED Slot *start, KernCollider &coll, int dir,
+ float &ymin, float &ymax, json *const dbgout) const
+{
+ Slot *nbor; // neighboring slot
+ float currSpace = 0.;
+ bool collides = false;
+ unsigned int space_count = 0;
+ Slot *base = slotFix;
+ while (base->attachedTo())
+ base = base->attachedTo();
+ SlotCollision *cFix = seg->collisionInfo(base);
+ const GlyphCache &gc = seg->getFace()->glyphs();
+
+ if (base != slotFix)
+ {
+ cFix->setFlags(cFix->flags() | SlotCollision::COLL_KERN | SlotCollision::COLL_FIX);
+ return 0;
+ }
+ bool seenEnd = (cFix->flags() & SlotCollision::COLL_END) != 0;
+ bool isInit = false;
+
+ for (nbor = slotFix->next(); nbor; nbor = nbor->next())
+ {
+ if (nbor->isChildOf(base))
+ continue;
+ if (!gc.check(nbor->gid()))
+ return 0.;
+ const Rect &bb = seg->theGlyphBBoxTemporary(nbor->gid());
+ SlotCollision *cNbor = seg->collisionInfo(nbor);
+ if (bb.bl.y == 0.f && bb.tr.y == 0.f)
+ {
+ if ((m_flags & 24) == 16)
+ break;
+ // Add space for a space glyph.
+ currSpace += nbor->advance();
+ ++space_count;
+ }
+ else
+ {
+ space_count = 0;
+ float y = nbor->origin().y + cNbor->shift().y;
+ ymax = max(y + bb.tr.y, ymax);
+ ymin = min(y + bb.bl.y, ymin);
+ if (nbor != slotFix && !(cNbor->flags() & SlotCollision::COLL_IGNORE))
+ {
+ seenEnd = true;
+ if (!isInit)
+ {
+ if (!coll.initSlot(seg, slotFix, cFix->limit(), cFix->margin(),
+ cFix->shift(), cFix->offset(), dir, ymin, ymax, dbgout))
+ return 0.;
+ isInit = true;
+ }
+ collides |= coll.mergeSlot(seg, nbor, cNbor->shift(), currSpace, dir, dbgout);
+ }
+ }
+ if (cNbor->flags() & SlotCollision::COLL_END)
+ {
+ if (seenEnd && space_count < 2)
+ break;
+ else
+ seenEnd = true;
+ }
+ }
+ if (collides)
+ {
+ Position mv = coll.resolve(seg, slotFix, dir, cFix->margin(), dbgout);
+ coll.shift(mv, dir);
+ Position delta = slotFix->advancePos() + mv - cFix->shift();
+ slotFix->advance(delta);
+ cFix->setShift(mv);
+ return mv.x;
+ }
+ return 0.;
+}
+
diff --git a/Build/source/libs/graphite2/graphite2-1.3.0/src/Position.cpp b/Build/source/libs/graphite2/graphite2-1.3.0/src/Position.cpp
new file mode 100644
index 00000000000..17247987591
--- /dev/null
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/Position.cpp
@@ -0,0 +1,98 @@
+/* GRAPHITE2 LICENSING
+
+ Copyright 2010, SIL International
+ All rights reserved.
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should also have received a copy of the GNU Lesser General Public
+ License along with this library in the file named "LICENSE".
+ If not, write to the Free Software Foundation, 51 Franklin Street,
+ Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
+ internet at http://www.fsf.org/licenses/lgpl.html.
+
+Alternatively, the contents of this file may be used under the terms of the
+Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
+License, as published by the Free Software Foundation, either version 2
+of the License or (at your option) any later version.
+*/
+#include "inc/Position.h"
+#include <cmath>
+
+using namespace graphite2;
+
+bool Rect::hitTest(Rect &other)
+{
+ if (bl.x > other.tr.x) return false;
+ if (tr.x < other.bl.x) return false;
+ if (bl.y > other.tr.y) return false;
+ if (tr.y < other.bl.y) return false;
+ return true;
+}
+
+Position Rect::overlap(Position &offset, Rect &other, Position &othero)
+{
+ float ax = (bl.x + offset.x) - (other.tr.x + othero.x);
+ float ay = (bl.y + offset.y) - (other.tr.y + othero.y);
+ float bx = (other.bl.x + othero.x) - (tr.x + offset.x);
+ float by = (other.bl.y + othero.y) - (tr.y + offset.y);
+ return Position((ax > bx ? ax : bx), (ay > by ? ay : by));
+}
+
+float boundmin(float move, float lim1, float lim2, float &error)
+{
+ // error is always positive for easy comparison
+ if (move < lim1 && move < lim2)
+ { error = 0.; return move; }
+ else if (lim1 < lim2)
+ { error = std::fabs(move - lim1); return lim1; }
+ else
+ { error = std::fabs(move - lim2); return lim2; }
+}
+
+#if 0
+Position Rect::constrainedAvoid(Position &offset, Rect &box, Rect &sdbox, Position &other, Rect &obox, Rect &osdbox)
+{
+ // a = max, i = min, s = sum, d = diff
+ float eax, eay, eix, eiy, eas, eis, ead, eid;
+ float beste = INF;
+ Position res;
+ // calculate the movements in each direction and the error (amount of remaining overlap)
+ // first param is movement, second and third are movement over the constraining box
+ float ax = boundmin(obox.tr.x + other.x - box.bl.x - offset.x + 1, tr.x - offset.x, INF, &eax);
+ float ay = boundmin(obox.tr.y + other.y - box.bl.y - offset.y + 1, tr.y - offset.y, INF, &eay);
+ float ix = boundmin(obox.bl.x + other.x - box.tr.x - offset.x + 1, bl.x - offset.x, INF, &eix);
+ float iy = boundmin(obox.bl.y + other.y - box.tr.y - offset.y + 1, bl.y - offset.y, INF, &eiy);
+ float as = boundmin(ISQRT2 * (osdbox.tr.x + other.x + other.y - sdbox.bl.x - offset.x - offset.y) + 1, tr.x - offset.x, tr.y - offset.y, &eas);
+ float is = boundmin(ISQRT2 * (osdbox.bl.x + other.x + other.y - sdbox.tr.x - offset.x - offset.y) + 1, bl.x - offset.x, bl.y - offset.y, &eis);
+ float ad = boundmin(ISQRT2 * (osdbox.tr.y + other.x - other.y - sdbox.bl.y - offset.x + offset.y) + 1, tr.y - offset.y, tr.x - offset.x, &ead);
+ float id = boundmin(ISQRT2 * (osdbox.bl.y + other.x - other.y - sdbox.tr.y - offset.x + offset.y) + 1, bl.y - offset.y, bl.x - offset.x, &eid);
+
+ if (eax < beste)
+ { res = Position(ax, 0); beste = eax; }
+ if (eay < beste)
+ { res = Position(0, ay); beste = eay; }
+ if (eix < beste)
+ { res = Position(ix, 0); beste = eix; }
+ if (eiy < beste)
+ { res = Position(0, iy); beste = eiy; }
+ if (SQRT2 * (eas) < beste)
+ { res = Position(as, ad); beste = SQRT2 * (eas); }
+ if (SQRT2 * (eis) < beste)
+ { res = Position(is, is); beste = SQRT2 * (eis); }
+ if (SQRT2 * (ead) < beste)
+ { res = Position(ad, ad); beste = SQRT2 * (ead); }
+ if (SQRT2 * (eid) < beste)
+ { res = Position(id, id); beste = SQRT2 * (eid); }
+ return res;
+}
+#endif
+
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/SegCache.cpp b/Build/source/libs/graphite2/graphite2-1.3.0/src/SegCache.cpp
index 446dfbec43f..446dfbec43f 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/SegCache.cpp
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/SegCache.cpp
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/SegCacheEntry.cpp b/Build/source/libs/graphite2/graphite2-1.3.0/src/SegCacheEntry.cpp
index d35912d5aed..d35912d5aed 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/SegCacheEntry.cpp
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/SegCacheEntry.cpp
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/SegCacheStore.cpp b/Build/source/libs/graphite2/graphite2-1.3.0/src/SegCacheStore.cpp
index 236fb707ffa..236fb707ffa 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/SegCacheStore.cpp
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/SegCacheStore.cpp
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/Segment.cpp b/Build/source/libs/graphite2/graphite2-1.3.0/src/Segment.cpp
index 42d7be57c26..f8b2690e8cf 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/Segment.cpp
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/Segment.cpp
@@ -37,6 +37,7 @@ of the License or (at your option) any later version.
#include "inc/Main.h"
#include "inc/CmapCache.h"
#include "inc/Bidi.h"
+#include "inc/Collider.h"
#include "graphite2/Segment.h"
@@ -46,6 +47,7 @@ Segment::Segment(unsigned int numchars, const Face* face, uint32 script, int tex
: m_freeSlots(NULL),
m_freeJustifies(NULL),
m_charinfo(new CharInfo[numchars]),
+ m_collisions(NULL),
m_face(face),
m_silf(face->chooseSilf(script)),
m_first(NULL),
@@ -55,7 +57,8 @@ Segment::Segment(unsigned int numchars, const Face* face, uint32 script, int tex
m_numCharinfo(numchars),
m_passBits(m_silf->aPassBits() ? -1 : 0),
m_defaultOriginal(0),
- m_dir(textDir)
+ m_dir(textDir),
+ m_flags(0)
{
freeSlot(newSlot());
m_bufSize = log_binary(numchars)+1;
@@ -335,7 +338,7 @@ void Segment::linkClusters(Slot *s, Slot * end)
}
}
-Position Segment::positionSlots(const Font *font, Slot * iStart, Slot * iEnd)
+Position Segment::positionSlots(const Font *font, Slot * iStart, Slot * iEnd, bool isFinal)
{
Position currpos(0., 0.);
float clusterMin = 0.;
@@ -349,7 +352,7 @@ Position Segment::positionSlots(const Font *font, Slot * iStart, Slot * iEnd)
for (Slot * s = iEnd, * const end = iStart->prev(); s && s != end; s = s->prev())
{
if (s->isBase())
- currpos = s->finalise(this, font, currpos, bbox, 0, clusterMin = currpos.x);
+ currpos = s->finalise(this, font, currpos, bbox, 0, clusterMin = currpos.x, isFinal);
}
}
else
@@ -357,7 +360,7 @@ Position Segment::positionSlots(const Font *font, Slot * iStart, Slot * iEnd)
for (Slot * s = iStart, * const end = iEnd->next(); s && s != end; s = s->next())
{
if (s->isBase())
- currpos = s->finalise(this, font, currpos, bbox, 0, clusterMin = currpos.x);
+ currpos = s->finalise(this, font, currpos, bbox, 0, clusterMin = currpos.x, isFinal);
}
}
return currpos;
@@ -434,11 +437,6 @@ bool Segment::read_text(const Face *face, const Features* pFeats/*must not be NU
return true;
}
-void Segment::prepare_pos(const Font * /*font*/)
-{
- // copy key changeable metrics into slot (if any);
-}
-
Slot *process_bidi(Slot *start, int level, int prelevel, int &nextLevel, int dirover, int isol, int &cisol, int &isolerr, int &embederr, int init, Segment *seg, uint8 aMirror, BracketPairStack &stack);
void resolveImplicit(Slot *s, Segment *seg, uint8 aMirror);
void resolveWhitespace(int baseLevel, Slot *s);
@@ -462,7 +460,7 @@ void Segment::bidiPass(uint8 aBidi, int paradir, uint8 aMirror)
}
bmask |= (1 << s->getBidiClass());
s->setBidiLevel(baseLevel);
- if (glyphAttr(s->gid(), aMirror) && s->getBidiClass() == 21)
+ if (s->getBidiClass() == 21)
++ssize;
}
@@ -492,3 +490,16 @@ void Segment::bidiPass(uint8 aBidi, int paradir, uint8 aMirror)
}
}
+bool Segment::initCollisions()
+{
+ if (m_collisions) free(m_collisions);
+ Slot *p = m_first;
+ m_collisions = gralloc<SlotCollision>(slotCount());
+ if (!m_collisions) return false;
+ for (unsigned short i = 0; i < slotCount(); ++i)
+ {
+ ::new (m_collisions + p->index()) SlotCollision(this, p);
+ p = p->next();
+ }
+ return true;
+}
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/Silf.cpp b/Build/source/libs/graphite2/graphite2-1.3.0/src/Silf.cpp
index 8b77271d2b4..df7dd1e2ef6 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/Silf.cpp
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/Silf.cpp
@@ -93,6 +93,10 @@ bool Silf::readGraphite(const byte * const silf_start, size_t lSilf, Face& face,
* const silf_end = p + lSilf;
Error e;
+ if (e.test(version >= 0x00060000, E_BADSILFVERSION))
+ {
+ releaseBuffers(); return face.error(e);
+ }
if (version >= 0x00030000)
{
if (e.test(lSilf < 28, E_BADSIZE)) { releaseBuffers(); return face.error(e); }
@@ -140,7 +144,9 @@ bool Silf::readGraphite(const byte * const silf_start, size_t lSilf, Face& face,
m_aLig = be::read<uint16>(p);
m_aUser = be::read<uint8>(p);
m_iMaxComp = be::read<uint8>(p);
- be::skip<byte>(p,5); // direction and 4 reserved bytes
+ be::skip<byte>(p); // direction
+ m_aCollision = be::read<uint8>(p);
+ be::skip<byte>(p,3);
be::skip<uint16>(p, be::read<uint8>(p)); // don't need critical features yet
be::skip<byte>(p); // reserved
if (e.test(p >= silf_end, E_BADCRITFEATURES)) { releaseBuffers(); return face.error(e); }
@@ -155,6 +161,7 @@ bool Silf::readGraphite(const byte * const silf_start, size_t lSilf, Face& face,
|| e.test(m_aBreak >= num_attrs, E_BADABREAK)
|| e.test(m_aBidi >= num_attrs, E_BADABIDI)
|| e.test(m_aMirror>= num_attrs, E_BADAMIRROR)
+ || e.test(m_aCollision && m_aCollision >= num_attrs - 5, E_BADACOLLISION)
|| e.test(m_numPasses > 128, E_BADNUMPASSES) || e.test(passes_start >= silf_end, E_BADPASSESSTART)
|| e.test(m_pPass < m_sPass, E_BADPASSBOUND) || e.test(m_pPass > m_numPasses, E_BADPPASS) || e.test(m_sPass > m_numPasses, E_BADSPASS)
|| e.test(m_jPass < m_pPass, E_BADJPASSBOUND) || e.test(m_jPass > m_numPasses, E_BADJPASS)
@@ -168,11 +175,12 @@ bool Silf::readGraphite(const byte * const silf_start, size_t lSilf, Face& face,
if (e.test(p + sizeof(uint16) >= passes_start, E_BADPASSESSTART)) { releaseBuffers(); return face.error(e); }
m_numPseudo = be::read<uint16>(p);
be::skip<uint16>(p, 3); // searchPseudo, pseudoSelector, pseudoShift
- if (e.test(p + m_numPseudo*(sizeof(uint32) + sizeof(uint16)) >= passes_start, E_BADNUMPSEUDO))
+ m_pseudos = new Pseudo[m_numPseudo];
+ if (e.test(p + m_numPseudo*(sizeof(uint32) + sizeof(uint16)) >= passes_start, E_BADNUMPSEUDO)
+ || e.test(!m_pseudos, E_OUTOFMEM))
{
releaseBuffers(); return face.error(e);
}
- m_pseudos = new Pseudo[m_numPseudo];
for (int i = 0; i < m_numPseudo; i++)
{
m_pseudos[i].uid = be::read<uint32>(p);
@@ -180,9 +188,11 @@ bool Silf::readGraphite(const byte * const silf_start, size_t lSilf, Face& face,
}
const size_t clen = readClassMap(p, passes_start - p, version, e);
- if (e || e.test(p + clen > passes_start, E_BADPASSESSTART)) { releaseBuffers(); return face.error(e); }
-
m_passes = new Pass[m_numPasses];
+ if (e || e.test(p + clen > passes_start, E_BADPASSESSTART)
+ || e.test(!m_passes, E_OUTOFMEM))
+ { releaseBuffers(); return face.error(e); }
+
for (size_t i = 0; i < m_numPasses; ++i)
{
const byte * const pass_start = silf_start + be::read<uint32>(o_passes),
@@ -192,8 +202,15 @@ bool Silf::readGraphite(const byte * const silf_start, size_t lSilf, Face& face,
releaseBuffers(); return face.error(e);
}
+ enum passtype pt = PASS_TYPE_UNKNOWN;
+ if (i >= m_jPass) pt = PASS_TYPE_JUSTIFICATION;
+ else if (i >= m_pPass) pt = PASS_TYPE_POSITIONING;
+ else if (i >= m_sPass) pt = PASS_TYPE_SUBSTITUTE;
+ else pt = PASS_TYPE_LINEBREAK;
+
m_passes[i].init(this);
- if (!m_passes[i].readPass(pass_start, pass_end - pass_start, pass_start - silf_start, face, e))
+ if (!m_passes[i].readPass(pass_start, pass_end - pass_start, pass_start - silf_start, face, pt,
+ version, e))
{
releaseBuffers();
return false;
@@ -373,7 +390,7 @@ bool Silf::runGraphite(Segment *seg, uint8 firstPass, uint8 lastPass, int dobidi
if (!(seg->dir() & 2))
seg->bidiPass(m_aBidi, seg->dir() & 1, m_aMirror);
- else if (m_aMirror)
+ else if (m_aMirror && (seg->dir() & 1))
{
Slot * s;
for (s = seg->first(); s; s = s->next())
@@ -403,8 +420,9 @@ bool Silf::runGraphite(Segment *seg, uint8 firstPass, uint8 lastPass, int dobidi
#endif
// test whether to reorder, prepare for positioning
- if (i >= 32 || (seg->passBits() & (1 << i)) == 0)
- m_passes[i].runGraphite(m, fsm);
+ if ((i >= 32 || (seg->passBits() & (1 << i)) == 0 || (m_passes[i].flags() & 7))
+ && !m_passes[i].runGraphite(m, fsm))
+ return false;
// only subsitution passes can change segment length, cached subsegments are short for their text
if (m.status() != vm::Machine::finished
|| (i < m_pPass && (seg->slotCount() > initSize * MAX_SEG_GROWTH_FACTOR
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/Slot.cpp b/Build/source/libs/graphite2/graphite2-1.3.0/src/Slot.cpp
index d802cd98d24..0c25fa76137 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/Slot.cpp
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/Slot.cpp
@@ -29,6 +29,7 @@ of the License or (at your option) any later version.
#include "inc/Silf.h"
#include "inc/CharInfo.h"
#include "inc/Rule.h"
+#include "inc/Collider.h"
using namespace graphite2;
@@ -85,19 +86,26 @@ void Slot::update(int /*numGrSlots*/, int numCharInfo, Position &relpos)
m_position = m_position + relpos;
}
-Position Slot::finalise(const Segment *seg, const Font *font, Position & base, Rect & bbox, uint8 attrLevel, float & clusterMin)
+Position Slot::finalise(const Segment *seg, const Font *font, Position & base, Rect & bbox, uint8 attrLevel, float & clusterMin, bool isFinal)
{
+ SlotCollision *coll = NULL;
if (attrLevel && m_attLevel > attrLevel) return Position(0, 0);
- float scale = 1.0;
+ float scale = font ? font->scale() : 1.0f;
Position shift(m_shift.x * ((seg->dir() & 1) * -2 + 1) + m_just, m_shift.y);
float tAdvance = m_advance.x + m_just;
+ if (isFinal && (coll = seg->collisionInfo(this)))
+ {
+ const Position &collshift = coll->offset();
+ if (!(coll->flags() & SlotCollision::COLL_KERN) || (seg->dir() & 1))
+ shift = shift + collshift;
+ }
const GlyphFace * glyphFace = seg->getFace()->glyphs().glyphSafe(glyph());
if (font)
{
scale = font->scale();
shift *= scale;
if (font->isHinted() && glyphFace)
- tAdvance = (m_advance.x - glyphFace->theAdvance().x + m_just) * scale + font->advance(m_glyphid);
+ tAdvance = (m_advance.x - glyphFace->theAdvance().x + m_just) * scale + font->advance(glyph());
else
tAdvance *= scale;
}
@@ -107,15 +115,15 @@ Position Slot::finalise(const Segment *seg, const Font *font, Position & base, R
if (!m_parent)
{
res = base + Position(tAdvance, m_advance.y * scale);
- clusterMin = base.x;
+ clusterMin = m_position.x;
}
else
{
float tAdv;
m_position += (m_attach - m_with) * scale;
- tAdv = m_advance.x >= 0.5 ? m_position.x + tAdvance - shift.x : 0.f;
+ tAdv = m_advance.x >= 0.5f ? m_position.x + tAdvance - shift.x : 0.f;
res = Position(tAdv, 0);
- if ((m_advance.x >= 0.5 || m_position.x < 0) && m_position.x < clusterMin) clusterMin = m_position.x;
+ if ((m_advance.x >= 0.5f || m_position.x < 0) && m_position.x < clusterMin) clusterMin = m_position.x;
}
if (glyphFace)
@@ -126,19 +134,19 @@ Position Slot::finalise(const Segment *seg, const Font *font, Position & base, R
if (m_child && m_child != this && m_child->attachedTo() == this)
{
- Position tRes = m_child->finalise(seg, font, m_position, bbox, attrLevel, clusterMin);
- if ((!m_parent || m_advance.x >= 0.5) && tRes.x > res.x) res = tRes;
+ Position tRes = m_child->finalise(seg, font, m_position, bbox, attrLevel, clusterMin, isFinal);
+ if ((!m_parent || m_advance.x >= 0.5f) && tRes.x > res.x) res = tRes;
}
if (m_parent && m_sibling && m_sibling != this && m_sibling->attachedTo() == m_parent)
{
- Position tRes = m_sibling->finalise(seg, font, base, bbox, attrLevel, clusterMin);
+ Position tRes = m_sibling->finalise(seg, font, base, bbox, attrLevel, clusterMin, isFinal);
if (tRes.x > res.x) res = tRes;
}
if (!m_parent && clusterMin < base.x)
{
- Position adj = Position(base.x - clusterMin, 0.);
+ Position adj = Position(m_position.x - clusterMin, 0.);
res += adj;
m_position += adj;
if (m_child) m_child->floodShift(adj);
@@ -151,7 +159,7 @@ int32 Slot::clusterMetric(const Segment *seg, uint8 metric, uint8 attrLevel)
Position base;
Rect bbox = seg->theGlyphBBoxTemporary(glyph());
float clusterMin = 0.;
- Position res = finalise(seg, NULL, base, bbox, attrLevel, clusterMin);
+ Position res = finalise(seg, NULL, base, bbox, attrLevel, clusterMin, false);
switch (metrics(metric))
{
@@ -180,6 +188,8 @@ int32 Slot::clusterMetric(const Segment *seg, uint8 metric, uint8 attrLevel)
}
}
+#define SLOTGETCOLATTR(x) { SlotCollision *c = seg->collisionInfo(this); return c ? int(c-> x) : 0; }
+
int Slot::getAttr(const Segment *seg, attrCode ind, uint8 subindex) const
{
if (!this) return 0;
@@ -211,7 +221,7 @@ int Slot::getAttr(const Segment *seg, attrCode ind, uint8 subindex) const
case gr_slatBreak : return seg->charinfo(m_original)->breakWeight();
case gr_slatCompRef : return 0;
case gr_slatDir : if (m_bidiCls == -1)
- const_cast<Slot *>(this)->setBidiClass(seg->glyphAttr(gid(), seg->silf()->aBidi()));
+ const_cast<Slot *>(this)->setBidiClass(int8(seg->glyphAttr(gid(), seg->silf()->aBidi())));
return m_bidiCls;
case gr_slatInsert : return isInsertBefore();
case gr_slatPosX : return int(m_position.x); // but need to calculate it
@@ -224,10 +234,42 @@ int Slot::getAttr(const Segment *seg, attrCode ind, uint8 subindex) const
case gr_slatUserDefn : return m_userAttr[subindex];
case gr_slatSegSplit : return seg->charinfo(m_original)->flags() & 3;
case gr_slatBidiLevel: return m_bidiLevel;
- default : return 0;
+ case gr_slatColFlags : { SlotCollision *c = seg->collisionInfo(this); return c ? c->flags() : 0; }
+ case gr_slatColLimitblx : SLOTGETCOLATTR(limit().bl.x)
+ case gr_slatColLimitbly : SLOTGETCOLATTR(limit().bl.y)
+ case gr_slatColLimittrx : SLOTGETCOLATTR(limit().tr.x)
+ case gr_slatColLimittry : SLOTGETCOLATTR(limit().tr.y)
+ case gr_slatColShiftx : SLOTGETCOLATTR(offset().x)
+ case gr_slatColShifty : SLOTGETCOLATTR(offset().y)
+ case gr_slatColMargin : SLOTGETCOLATTR(margin())
+ case gr_slatColMarginWt : SLOTGETCOLATTR(marginWt())
+ case gr_slatColExclGlyph : SLOTGETCOLATTR(exclGlyph())
+ case gr_slatColExclOffx : SLOTGETCOLATTR(exclOffset().x)
+ case gr_slatColExclOffy : SLOTGETCOLATTR(exclOffset().y)
+ case gr_slatSeqClass : SLOTGETCOLATTR(seqClass())
+ case gr_slatSeqProxClass : SLOTGETCOLATTR(seqProxClass())
+ case gr_slatSeqOrder : SLOTGETCOLATTR(seqOrder())
+ case gr_slatSeqAboveXoff : SLOTGETCOLATTR(seqAboveXoff())
+ case gr_slatSeqAboveWt : SLOTGETCOLATTR(seqAboveWt())
+ case gr_slatSeqBelowXlim : SLOTGETCOLATTR(seqBelowXlim())
+ case gr_slatSeqBelowWt : SLOTGETCOLATTR(seqBelowWt())
+ case gr_slatSeqValignHt : SLOTGETCOLATTR(seqValignHt())
+ case gr_slatSeqValignWt : SLOTGETCOLATTR(seqValignWt())
+ default : return 0;
}
}
+#define SLOTCOLSETATTR(x) { \
+ SlotCollision *c = seg->collisionInfo(this); \
+ if (c) { c-> x ; c->setFlags(c->flags() & ~SlotCollision::COLL_KNOWN); } \
+ break; }
+#define SLOTCOLSETCOMPLEXATTR(t, y, x) { \
+ SlotCollision *c = seg->collisionInfo(this); \
+ if (c) { \
+ const t &s = c-> y; \
+ c-> x ; c->setFlags(c->flags() & ~SlotCollision::COLL_KNOWN); } \
+ break; }
+
void Slot::setAttr(Segment *seg, attrCode ind, uint8 subindex, int16 value, const SlotMap & map)
{
if (!this) return;
@@ -252,9 +294,9 @@ void Slot::setAttr(Segment *seg, attrCode ind, uint8 subindex, int16 value, cons
if (idx < map.size() && map[idx])
{
Slot *other = map[idx];
- if (other == this) break;
+ if (other == this || other == m_parent) break;
if (m_parent) m_parent->removeChild(this);
- if (other->child(this))
+ if (!other->isChildOf(this) && other->child(this))
{
attachTo(other);
if (((seg->dir() & 1) != 0) ^ (idx > subindex))
@@ -280,7 +322,7 @@ void Slot::setAttr(Segment *seg, attrCode ind, uint8 subindex, int16 value, cons
seg->charinfo(m_original)->breakWeight(value);
break;
case gr_slatCompRef : break; // not sure what to do here
- case gr_slatDir : m_bidiCls = value; break;
+ case gr_slatDir : m_bidiCls = int8(value); break;
case gr_slatInsert :
markInsertBefore(value? true : false);
break;
@@ -293,6 +335,29 @@ void Slot::setAttr(Segment *seg, attrCode ind, uint8 subindex, int16 value, cons
case gr_slatJWidth : just(value); break;
case gr_slatSegSplit : seg->charinfo(m_original)->addflags(value & 3); break;
case gr_slatUserDefn : m_userAttr[subindex] = value; break;
+ case gr_slatColFlags : {
+ SlotCollision *c = seg->collisionInfo(this);
+ if (c)
+ c->setFlags(value);
+ break; }
+ case gr_slatColLimitblx : SLOTCOLSETCOMPLEXATTR(Rect, limit(), setLimit(Rect(Position(value, s.bl.y), s.tr)))
+ case gr_slatColLimitbly : SLOTCOLSETCOMPLEXATTR(Rect, limit(), setLimit(Rect(Position(s.bl.x, value), s.tr)))
+ case gr_slatColLimittrx : SLOTCOLSETCOMPLEXATTR(Rect, limit(), setLimit(Rect(s.bl, Position(value, s.tr.y))))
+ case gr_slatColLimittry : SLOTCOLSETCOMPLEXATTR(Rect, limit(), setLimit(Rect(s.bl, Position(s.tr.x, value))))
+ case gr_slatColMargin : SLOTCOLSETATTR(setMargin(value))
+ case gr_slatColMarginWt : SLOTCOLSETATTR(setMarginWt(value))
+ case gr_slatColExclGlyph : SLOTCOLSETATTR(setExclGlyph(value))
+ case gr_slatColExclOffx : SLOTCOLSETCOMPLEXATTR(Position, exclOffset(), setExclOffset(Position(value, s.y)))
+ case gr_slatColExclOffy : SLOTCOLSETCOMPLEXATTR(Position, exclOffset(), setExclOffset(Position(s.x, value)))
+ case gr_slatSeqClass : SLOTCOLSETATTR(setSeqClass(value))
+ case gr_slatSeqProxClass : SLOTCOLSETATTR(setSeqProxClass(value))
+ case gr_slatSeqOrder : SLOTCOLSETATTR(setSeqOrder(value))
+ case gr_slatSeqAboveXoff : SLOTCOLSETATTR(setSeqAboveXoff(value))
+ case gr_slatSeqAboveWt : SLOTCOLSETATTR(setSeqAboveWt(value))
+ case gr_slatSeqBelowXlim : SLOTCOLSETATTR(setSeqBelowXlim(value))
+ case gr_slatSeqBelowWt : SLOTCOLSETATTR(setSeqBelowWt(value))
+ case gr_slatSeqValignHt : SLOTCOLSETATTR(setSeqValignHt(value))
+ case gr_slatSeqValignWt : SLOTCOLSETATTR(setSeqValignWt(value))
default :
break;
}
@@ -374,6 +439,7 @@ bool Slot::removeSibling(Slot *ap)
else if (ap == m_sibling)
{
m_sibling = m_sibling->nextSibling();
+ ap->sibling(NULL);
return true;
}
else
@@ -425,3 +491,29 @@ void SlotJustify::LoadSlot(const Slot *s, const Segment *seg)
v[3] = seg->glyphAttr(s->gid(), justs->attrWeight());
}
}
+
+Slot * Slot::nextInCluster(const Slot *s) const
+{
+ Slot *base;
+ if (s->firstChild())
+ return s->firstChild();
+ else if (s->nextSibling())
+ return s->nextSibling();
+ while ((base = s->attachedTo()))
+ {
+ if (base->firstChild() == s && base->nextSibling())
+ return base->nextSibling();
+ s = base;
+ }
+ return NULL;
+}
+
+bool Slot::isChildOf(const Slot *base) const
+{
+ if (m_parent == base)
+ return true;
+ else if (!m_parent)
+ return false;
+ else
+ return m_parent->isChildOf(base);
+}
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/Sparse.cpp b/Build/source/libs/graphite2/graphite2-1.3.0/src/Sparse.cpp
index 8730f78644d..8730f78644d 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/Sparse.cpp
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/Sparse.cpp
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/TtfUtil.cpp b/Build/source/libs/graphite2/graphite2-1.3.0/src/TtfUtil.cpp
index fcd2478a266..ad0ec965b75 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/TtfUtil.cpp
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/TtfUtil.cpp
@@ -873,11 +873,11 @@ const void * FindCmapSubtable(const void * pCmap, int nPlatformId, /* =3 */ int
/*----------------------------------------------------------------------------------------------
Check the Microsoft Unicode subtable for expected values
----------------------------------------------------------------------------------------------*/
-bool CheckCmapSubtable4(const void * pCmapSubtable4)
+bool CheckCmapSubtable4(const void * pCmapSubtable4 /*, unsigned int maxgid*/)
{
if (!pCmapSubtable4) return false;
const Sfnt::CmapSubTable * pTable = reinterpret_cast<const Sfnt::CmapSubTable *>(pCmapSubtable4);
- // Bob H says ome freeware TT fonts have version 1 (eg, CALIGULA.TTF)
+ // Bob H say some freeware TT fonts have version 1 (eg, CALIGULA.TTF)
// so don't check subtable version. 21 Mar 2002 spec changes version to language.
if (be::swap(pTable->format) != 4) return false;
const Sfnt::CmapSubTableFormat4 * pTable4 = reinterpret_cast<const Sfnt::CmapSubTableFormat4 *>(pCmapSubtable4);
@@ -889,7 +889,37 @@ bool CheckCmapSubtable4(const void * pCmapSubtable4)
return false;
// check last range is properly terminated
uint16 chEnd = be::peek<uint16>(pTable4->end_code + nRanges - 1);
- return (chEnd == 0xFFFF);
+ if (chEnd != 0xFFFF)
+ return false;
+#if 0
+ int lastend = -1;
+ for (int i = 0; i < nRanges; ++i)
+ {
+ uint16 end = be::peek<uint16>(pTable4->end_code + i);
+ uint16 start = be::peek<uint16>(pTable4->end_code + nRanges + 1 + i);
+ int16 delta = be::peek<int16>(pTable4->end_code + 2*nRanges + 1 + i);
+ uint16 offset = be::peek<uint16>(pTable4->end_code + 3*nRanges + 1 + i);
+ if (lastend >= end || lastend >= start)
+ return false;
+ if (offset)
+ {
+ const uint16 *gstart = pTable4->end_code + 3*nRanges + 1 + i + (offset >> 1);
+ const uint16 *gend = gstart + end - start;
+ if ((char *)gend >= (char *)pCmapSubtable4 + length)
+ return false;
+ while (gstart <= gend)
+ {
+ uint16 g = be::peek<uint16>(gstart++);
+ if (g && ((g + delta) & 0xFFFF) > maxgid)
+ return false;
+ }
+ }
+ else if (((delta + end) & 0xFFFF) > maxgid)
+ return false;
+ lastend = end;
+ }
+#endif
+ return true;;
}
/*----------------------------------------------------------------------------------------------
@@ -1032,7 +1062,7 @@ unsigned int CmapSubtable4NextCodepoint(const void *pCmap31, unsigned int nUnico
/*----------------------------------------------------------------------------------------------
Check the Microsoft UCS-4 subtable for expected values.
----------------------------------------------------------------------------------------------*/
-bool CheckCmapSubtable12(const void *pCmapSubtable12)
+bool CheckCmapSubtable12(const void *pCmapSubtable12 /*, unsigned int maxgid*/)
{
if (!pCmapSubtable12) return false;
const Sfnt::CmapSubTable * pTable = reinterpret_cast<const Sfnt::CmapSubTable *>(pCmapSubtable12);
@@ -1042,9 +1072,19 @@ bool CheckCmapSubtable12(const void *pCmapSubtable12)
uint32 length = be::swap(pTable12->length);
if (length < sizeof(Sfnt::CmapSubTableFormat12))
return false;
-
- return (length == (sizeof(Sfnt::CmapSubTableFormat12) + (be::swap(pTable12->num_groups) - 1)
- * sizeof(uint32) * 3));
+ uint32 num_groups = be::swap(pTable12->num_groups);
+ if (length != (sizeof(Sfnt::CmapSubTableFormat12) + (num_groups - 1) * sizeof(uint32) * 3))
+ return false;
+#if 0
+ for (unsigned int i = 0; i < num_groups; ++i)
+ {
+ if (be::swap(pTable12->group[i].end_char_code) - be::swap(pTable12->group[i].start_char_code) + be::swap(pTable12->group[i].start_glyph_id) > maxgid)
+ return false;
+ if (i > 0 && be::swap(pTable12->group[i].start_char_code) <= be::swap(pTable12->group[i-1].end_char_code))
+ return false;
+ }
+#endif
+ return true;
}
/*----------------------------------------------------------------------------------------------
@@ -1145,6 +1185,7 @@ size_t LocaLookup(gid16 nGlyphId,
const void * pHead) // throw (std::out_of_range)
{
const Sfnt::FontHeader * pTable = reinterpret_cast<const Sfnt::FontHeader *>(pHead);
+ size_t res = -2;
// CheckTable verifies the index_to_loc_format is valid
if (be::swap(pTable->index_to_loc_format) == Sfnt::FontHeader::ShortIndexLocFormat)
@@ -1152,21 +1193,24 @@ size_t LocaLookup(gid16 nGlyphId,
if (nGlyphId < (lLocaSize >> 1) - 1) // allow sentinel value to be accessed
{
const uint16 * pShortTable = reinterpret_cast<const uint16 *>(pLoca);
- return (be::peek<uint16>(pShortTable + nGlyphId) << 1);
+ res = be::peek<uint16>(pShortTable + nGlyphId) << 1;
+ if (res == static_cast<size_t>(be::peek<uint16>(pShortTable + nGlyphId + 1) << 1))
+ return -1;
}
}
-
- if (be::swap(pTable->index_to_loc_format) == Sfnt::FontHeader::LongIndexLocFormat)
+ else if (be::swap(pTable->index_to_loc_format) == Sfnt::FontHeader::LongIndexLocFormat)
{ // loca entries are four bytes
if (nGlyphId < (lLocaSize >> 2) - 1)
{
const uint32 * pLongTable = reinterpret_cast<const uint32 *>(pLoca);
- return be::peek<uint32>(pLongTable + nGlyphId);
+ res = be::peek<uint32>(pLongTable + nGlyphId);
+ if (res == static_cast<size_t>(be::peek<uint32>(pLongTable + nGlyphId + 1)))
+ return -1;
}
}
// only get here if glyph id was bad
- return -1;
+ return res;
//throw std::out_of_range("glyph id out of range for font");
}
@@ -1177,7 +1221,7 @@ size_t LocaLookup(gid16 nGlyphId,
void * GlyfLookup(const void * pGlyf, size_t nGlyfOffset, size_t nTableLen)
{
const uint8 * pByte = reinterpret_cast<const uint8 *>(pGlyf);
- if (nGlyfOffset == size_t(-1) || nGlyfOffset >= nTableLen)
+ if (nGlyfOffset == size_t(-1) || nGlyfOffset == size_t(-2) || nGlyfOffset >= nTableLen)
return NULL;
return const_cast<uint8 *>(pByte + nGlyfOffset);
}
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/UtfCodec.cpp b/Build/source/libs/graphite2/graphite2-1.3.0/src/UtfCodec.cpp
index d1db5fa11f1..d1db5fa11f1 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/UtfCodec.cpp
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/UtfCodec.cpp
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/call_machine.cpp b/Build/source/libs/graphite2/graphite2-1.3.0/src/call_machine.cpp
index cfe57076fab..cfe57076fab 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/call_machine.cpp
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/call_machine.cpp
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/direct_machine.cpp b/Build/source/libs/graphite2/graphite2-1.3.0/src/direct_machine.cpp
index 09709c30336..09709c30336 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/direct_machine.cpp
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/direct_machine.cpp
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/files.mk b/Build/source/libs/graphite2/graphite2-1.3.0/src/files.mk
index a9950a58d70..b1ff7736f2b 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/files.mk
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/files.mk
@@ -51,15 +51,19 @@ $(_NS)_SOURCES = \
$($(_NS)_BASE)/src/CachedFace.cpp \
$($(_NS)_BASE)/src/CmapCache.cpp \
$($(_NS)_BASE)/src/Code.cpp \
+ $($(_NS)_BASE)/src/Collider.cpp \
+ $($(_NS)_BASE)/src/Decompressor.cpp \
$($(_NS)_BASE)/src/Face.cpp \
$($(_NS)_BASE)/src/FeatureMap.cpp \
$($(_NS)_BASE)/src/FileFace.cpp \
$($(_NS)_BASE)/src/Font.cpp \
$($(_NS)_BASE)/src/GlyphCache.cpp \
$($(_NS)_BASE)/src/GlyphFace.cpp \
+ $($(_NS)_BASE)/src/Intervals.cpp \
$($(_NS)_BASE)/src/Justifier.cpp \
$($(_NS)_BASE)/src/NameTable.cpp \
$($(_NS)_BASE)/src/Pass.cpp \
+ $($(_NS)_BASE)/src/Position.cpp \
$($(_NS)_BASE)/src/SegCache.cpp \
$($(_NS)_BASE)/src/SegCacheEntry.cpp \
$($(_NS)_BASE)/src/SegCacheStore.cpp \
@@ -74,10 +78,14 @@ $(_NS)_PRIVATE_HEADERS = \
$($(_NS)_BASE)/src/inc/bits.h \
$($(_NS)_BASE)/src/inc/debug.h \
$($(_NS)_BASE)/src/inc/json.h \
+ $($(_NS)_BASE)/src/inc/locale2lcid.h \
+ $($(_NS)_BASE)/src/inc/Bidi.h \
$($(_NS)_BASE)/src/inc/CachedFace.h \
$($(_NS)_BASE)/src/inc/CharInfo.h \
$($(_NS)_BASE)/src/inc/CmapCache.h \
$($(_NS)_BASE)/src/inc/Code.h \
+ $($(_NS)_BASE)/src/inc/Collider.h \
+ $($(_NS)_BASE)/src/inc/Decompressor.h \
$($(_NS)_BASE)/src/inc/Endian.h \
$($(_NS)_BASE)/src/inc/Error.h \
$($(_NS)_BASE)/src/inc/Face.h \
@@ -87,6 +95,7 @@ $(_NS)_PRIVATE_HEADERS = \
$($(_NS)_BASE)/src/inc/Font.h \
$($(_NS)_BASE)/src/inc/GlyphCache.h \
$($(_NS)_BASE)/src/inc/GlyphFace.h \
+ $($(_NS)_BASE)/src/inc/Intervals.h \
$($(_NS)_BASE)/src/inc/List.h \
$($(_NS)_BASE)/src/inc/locale2lcid.h \
$($(_NS)_BASE)/src/inc/Machine.h \
@@ -101,6 +110,7 @@ $(_NS)_PRIVATE_HEADERS = \
$($(_NS)_BASE)/src/inc/SegCacheEntry.h \
$($(_NS)_BASE)/src/inc/SegCacheStore.h \
$($(_NS)_BASE)/src/inc/Segment.h \
+ $($(_NS)_BASE)/src/inc/Shrinker.h \
$($(_NS)_BASE)/src/inc/Silf.h \
$($(_NS)_BASE)/src/inc/Slot.h \
$($(_NS)_BASE)/src/inc/Sparse.h \
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/gr_char_info.cpp b/Build/source/libs/graphite2/graphite2-1.3.0/src/gr_char_info.cpp
index ebcb68e593f..ebcb68e593f 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/gr_char_info.cpp
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/gr_char_info.cpp
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/gr_face.cpp b/Build/source/libs/graphite2/graphite2-1.3.0/src/gr_face.cpp
index a245da4da47..fe1eb838207 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/gr_face.cpp
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/gr_face.cpp
@@ -46,7 +46,7 @@ namespace
#ifdef GRAPHITE2_TELEMETRY
telemetry::category _misc_cat(face.tele.misc);
#endif
- Face::Table silf(face, Tag::Silf);
+ Face::Table silf(face, Tag::Silf, 0x00050000);
if (silf) options &= ~gr_face_dumbRendering;
else if (!(options & gr_face_dumbRendering))
return false;
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/gr_features.cpp b/Build/source/libs/graphite2/graphite2-1.3.0/src/gr_features.cpp
index 38cebb7b5db..38cebb7b5db 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/gr_features.cpp
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/gr_features.cpp
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/gr_font.cpp b/Build/source/libs/graphite2/graphite2-1.3.0/src/gr_font.cpp
index ed70ab7381e..ed70ab7381e 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/gr_font.cpp
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/gr_font.cpp
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/gr_logging.cpp b/Build/source/libs/graphite2/graphite2-1.3.0/src/gr_logging.cpp
index 7cfe5360886..3e453ba8e2c 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/gr_logging.cpp
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/gr_logging.cpp
@@ -32,6 +32,7 @@ of the License or (at your option) any later version.
#include "inc/Slot.h"
#include "inc/Segment.h"
#include "inc/json.h"
+#include "inc/Collider.h"
#if defined _WIN32
#include "windows.h"
@@ -184,6 +185,7 @@ json & graphite2::operator << (json & j, const dslot & ds) throw()
assert(ds.second);
const Segment & seg = *ds.first;
const Slot & s = *ds.second;
+ const SlotCollision *cslot = seg.collisionInfo(ds.second);
j << json::object
<< "id" << objectid(ds)
@@ -220,6 +222,28 @@ json & graphite2::operator << (json & j, const dslot & ds) throw()
j << objectid(dslot(&seg, c));
j << json::close;
}
+ if (cslot)
+ {
+ // Note: the reason for using Positions to lump together related attributes is to make the
+ // JSON output slightly more compact.
+ j << "collision" << json::flat << json::object
+// << "shift" << cslot->shift() -- not used pass level, only within the collision routine itself
+ << "offset" << cslot->offset()
+ << "limit" << cslot->limit()
+ << "flags" << cslot->flags()
+ << "margin" << Position(cslot->margin(), cslot->marginWt())
+ << "exclude" << cslot->exclGlyph()
+ << "excludeoffset" << cslot->exclOffset();
+ if (cslot->seqOrder() != 0)
+ {
+ j << "seqclass" << Position(cslot->seqClass(), cslot->seqProxClass())
+ << "seqorder" << cslot->seqOrder()
+ << "seqabove" << Position(cslot->seqAboveXoff(), cslot->seqAboveWt())
+ << "seqbelow" << Position(cslot->seqBelowXlim(), cslot->seqBelowWt())
+ << "seqvalign" << Position(cslot->seqValignHt(), cslot->seqValignWt());
+ }
+ j << json::close;
+ }
return j << json::close;
}
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/gr_segment.cpp b/Build/source/libs/graphite2/graphite2-1.3.0/src/gr_segment.cpp
index 71e40bcdddf..aab74e40ff5 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/gr_segment.cpp
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/gr_segment.cpp
@@ -48,10 +48,6 @@ namespace
delete pRes;
return NULL;
}
- // run the line break passes
- // run the substitution passes
- pRes->prepare_pos(font);
- // run the positioning passes
pRes->finalise(font);
return static_cast<gr_segment*>(pRes);
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/gr_slot.cpp b/Build/source/libs/graphite2/graphite2-1.3.0/src/gr_slot.cpp
index c615e40ffe5..0e41f6cb519 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/gr_slot.cpp
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/gr_slot.cpp
@@ -103,11 +103,11 @@ float gr_slot_advance_X(const gr_slot* p/*not NULL*/, const gr_face *face, const
return res;
}
-float gr_slot_advance_Y(const gr_slot *p/*not NULL*/, const gr_face *face, const gr_font *font)
+float gr_slot_advance_Y(const gr_slot *p/*not NULL*/, GR_MAYBE_UNUSED const gr_face *face, const gr_font *font)
{
assert(p);
float res = p->advancePos().y;
- if (font && (face || !face))
+ if (font)
return res * font->scale();
else
return res;
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Bidi.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Bidi.h
index 9593c7e149a..9593c7e149a 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Bidi.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Bidi.h
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/CachedFace.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/CachedFace.h
index 53674754ee2..53674754ee2 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/CachedFace.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/CachedFace.h
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/CharInfo.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/CharInfo.h
index d9e56eeed64..d9e56eeed64 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/CharInfo.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/CharInfo.h
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/CmapCache.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/CmapCache.h
index 7820c958b0e..7820c958b0e 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/CmapCache.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/CmapCache.h
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Code.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Code.h
index 1ce148ab430..c27ff0d9da1 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Code.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Code.h
@@ -41,6 +41,14 @@ namespace graphite2 {
class Silf;
class Face;
+enum passtype {
+ PASS_TYPE_UNKNOWN = 0,
+ PASS_TYPE_LINEBREAK,
+ PASS_TYPE_SUBSTITUTE,
+ PASS_TYPE_POSITIONING,
+ PASS_TYPE_JUSTIFICATION
+};
+
namespace vm {
class Machine::Code
@@ -56,10 +64,12 @@ public:
jump_past_end,
arguments_exhausted,
missing_return,
- nested_context_item
+ nested_context_item,
+ underfull_stack
};
private:
+ static byte * local_memory;
class decoder;
instr * _code;
@@ -79,7 +89,8 @@ private:
public:
Code() throw();
Code(bool is_constraint, const byte * bytecode_begin, const byte * const bytecode_end,
- uint8 pre_context, uint16 rule_length, const Silf &, const Face &);
+ uint8 pre_context, uint16 rule_length, const Silf &, const Face &,
+ enum passtype pt, byte * & _out = local_memory);
Code(const Machine::Code &) throw();
~Code() throw();
@@ -92,12 +103,14 @@ public:
bool immutable() const throw();
bool deletes() const throw();
size_t maxRef() const throw();
+ void externalProgramMoved(ptrdiff_t) throw();
int32 run(Machine &m, slotref * & map) const;
CLASS_NEW_DELETE;
};
+
inline Machine::Code::Code() throw()
: _code(0), _data(0), _data_size(0), _instr_count(0), _max_ref(0),
_status(loaded), _constraint(false), _modify(false),_delete(false),
@@ -171,5 +184,14 @@ inline size_t Machine::Code::maxRef() const throw()
return _max_ref;
}
+inline void Machine::Code::externalProgramMoved(ptrdiff_t dist) throw()
+{
+ if (_code && !_own)
+ {
+ _code += dist / sizeof(instr);
+ _data += dist;
+ }
+}
+
} // namespace vm
} // namespace graphite2
diff --git a/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Collider.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Collider.h
new file mode 100644
index 00000000000..635f9b07324
--- /dev/null
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Collider.h
@@ -0,0 +1,220 @@
+/* GRAPHITE2 LICENSING
+
+ Copyright 2010, SIL International
+ All rights reserved.
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should also have received a copy of the GNU Lesser General Public
+ License along with this library in the file named "LICENSE".
+ If not, write to the Free Software Foundation, 51 Franklin Street,
+ Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
+ internet at http://www.fsf.org/licenses/lgpl.html.
+
+Alternatively, the contents of this file may be used under the terms of the
+Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
+License, as published by the Free Software Foundation, either version 2
+of the License or (at your option) any later version.
+*/
+#pragma once
+
+#include <utility>
+#include "inc/List.h"
+#include "inc/Slot.h"
+#include "inc/Position.h"
+#include "inc/Intervals.h"
+#include "inc/debug.h"
+//#include "inc/Segment.h"
+
+namespace graphite2 {
+
+class json;
+class Slot;
+class Segment;
+
+#define SLOTCOLSETUINTPROP(x, y) uint16 x() const { return _ ##x; } void y (uint16 v) { _ ##x = v; }
+#define SLOTCOLSETINTPROP(x, y) int16 x() const { return _ ##x; } void y (int16 v) { _ ##x = v; }
+#define SLOTCOLSETPOSITIONPROP(x, y) const Position &x() const { return _ ##x; } void y (const Position &v) { _ ##x = v; }
+
+// Slot attributes related to collision-fixing
+class SlotCollision
+{
+public:
+ enum {
+ // COLL_TESTONLY = 0, // default - test other glyphs for collision with this one, but don't move this one
+ COLL_FIX = 1, // fix collisions involving this glyph
+ COLL_IGNORE = 2, // ignore this glyph altogether
+ COLL_START = 4, // start of range of possible collisions
+ COLL_END = 8, // end of range of possible collisions
+ COLL_KERN = 16, // collisions with this glyph are fixed by adding kerning space after it
+ COLL_ISCOL = 32, // this glyph has a collision
+ COLL_KNOWN = 64, // we've figured out what's happening with this glyph
+ COLL_TEMPLOCK = 128, // Lock glyphs that have been given priority positioning
+ ////COLL_JUMPABLE = 128, // moving glyphs may jump this stationary glyph in any direction - DELETE
+ ////COLL_OVERLAP = 256, // use maxoverlap to restrict - DELETE
+ };
+
+ // Behavior for the collision.order attribute. To GDL this is an enum, to us it's a bitfield, with only 1 bit set
+ // Allows for easier inversion.
+ enum {
+ SEQ_ORDER_LEFTDOWN = 1,
+ SEQ_ORDER_RIGHTUP = 2,
+ SEQ_ORDER_NOABOVE = 4,
+ SEQ_ORDER_NOBELOW = 8,
+ SEQ_ORDER_NOLEFT = 16,
+ SEQ_ORDER_NORIGHT = 32
+ };
+
+ SlotCollision(Segment *seg, Slot *slot);
+ void initFromSlot(Segment *seg, Slot *slot);
+
+ const Rect &limit() const { return _limit; }
+ void setLimit(const Rect &r) { _limit = r; }
+ SLOTCOLSETPOSITIONPROP(shift, setShift)
+ SLOTCOLSETPOSITIONPROP(offset, setOffset)
+ SLOTCOLSETPOSITIONPROP(exclOffset, setExclOffset)
+ SLOTCOLSETUINTPROP(margin, setMargin)
+ SLOTCOLSETUINTPROP(marginWt, setMarginWt)
+ SLOTCOLSETUINTPROP(flags, setFlags)
+ SLOTCOLSETUINTPROP(exclGlyph, setExclGlyph)
+ SLOTCOLSETUINTPROP(seqClass, setSeqClass)
+ SLOTCOLSETUINTPROP(seqProxClass, setSeqProxClass)
+ SLOTCOLSETUINTPROP(seqOrder, setSeqOrder)
+ SLOTCOLSETINTPROP(seqAboveXoff, setSeqAboveXoff)
+ SLOTCOLSETUINTPROP(seqAboveWt, setSeqAboveWt)
+ SLOTCOLSETINTPROP(seqBelowXlim, setSeqBelowXlim)
+ SLOTCOLSETUINTPROP(seqBelowWt, setSeqBelowWt)
+ SLOTCOLSETUINTPROP(seqValignHt, setSeqValignHt)
+ SLOTCOLSETUINTPROP(seqValignWt, setSeqValignWt)
+
+ float getKern(int dir) const;
+
+private:
+ Rect _limit;
+ Position _shift; // adjustment within the given pass
+ Position _offset; // total adjustment for collisions
+ Position _exclOffset;
+ uint16 _margin;
+ uint16 _marginWt;
+ uint16 _flags;
+ uint16 _exclGlyph;
+ uint16 _seqClass;
+ uint16 _seqProxClass;
+ uint16 _seqOrder;
+ int16 _seqAboveXoff;
+ uint16 _seqAboveWt;
+ int16 _seqBelowXlim;
+ uint16 _seqBelowWt;
+ uint16 _seqValignHt;
+ uint16 _seqValignWt;
+
+}; // end of class SlotColllision
+
+class BBox;
+class SlantBox;
+
+class ShiftCollider
+{
+public:
+ typedef std::pair<float, float> fpair;
+ typedef Vector<fpair> vfpairs;
+ typedef vfpairs::iterator ivfpairs;
+
+ ShiftCollider(GR_MAYBE_UNUSED json *dbgout)
+ {
+#if !defined GRAPHITE2_NTRACING
+ for (int i = 0; i < 4; ++i)
+ _ranges[i].setdebug(dbgout);
+#endif
+ }
+ ~ShiftCollider() throw() { };
+
+ bool initSlot(Segment *seg, Slot *aSlot, const Rect &constraint,
+ float margin, float marginMin, const Position &currShift,
+ const Position &currOffset, int dir, GR_MAYBE_UNUSED json * const dbgout);
+ bool mergeSlot(Segment *seg, Slot *slot, const Position &currShift, bool isAfter,
+ bool sameCluster, bool &hasCol, bool isExclusion, GR_MAYBE_UNUSED json * const dbgout);
+ Position resolve(Segment *seg, bool &isCol, GR_MAYBE_UNUSED json * const dbgout);
+ void addBox_slope(bool isx, const Rect &box, const BBox &bb, const SlantBox &sb, const Position &org, float weight, float m, bool minright, int mode);
+ void removeBox(const Rect &box, const BBox &bb, const SlantBox &sb, const Position &org, int mode);
+ const Position &origin() const { return _origin; }
+
+#if !defined GRAPHITE2_NTRACING
+ void outputJsonDbg(json * const dbgout, Segment *seg, int axis);
+ void outputJsonDbgStartSlot(json * const dbgout, Segment *seg);
+ void outputJsonDbgEndSlot(json * const dbgout, Position resultPos, int bestAxis, bool isCol);
+ void outputJsonDbgOneVector(json * const dbgout, Segment *seg, int axis, float tleft, float bestCost, float bestVal);
+ void outputJsonDbgRawRanges(json * const dbgout, int axis);
+ void outputJsonDbgRemovals(json * const dbgout, int axis, Segment *seg);
+#endif
+
+ CLASS_NEW_DELETE;
+
+protected:
+ Zones _ranges[4]; // possible movements in 4 directions (horizontally, vertically, diagonally);
+ Slot * _target; // the glyph to fix
+ Rect _limit;
+ Position _currShift;
+ Position _currOffset;
+ Position _origin; // Base for all relative calculations
+ float _margin;
+ float _marginWt;
+ float _len[4];
+ uint16 _seqClass;
+ uint16 _seqProxClass;
+ uint16 _seqOrder;
+
+ //bool _scraping[4];
+
+}; // end of class ShiftCollider
+
+class KernCollider
+{
+public:
+ KernCollider(GR_MAYBE_UNUSED json *dbg) : _miny(-1e38f), _maxy(1e38f) { };
+ ~KernCollider() throw() { };
+ bool initSlot(Segment *seg, Slot *aSlot, const Rect &constraint, float margin,
+ const Position &currShift, const Position &offsetPrev, int dir,
+ float ymin, float ymax, json * const dbgout);
+ bool mergeSlot(Segment *seg, Slot *slot, const Position &currShift, float currSpace, int dir, json * const dbgout);
+ Position resolve(Segment *seg, Slot *slot, int dir, float margin, json * const dbgout);
+ void shift(const Position &mv, int dir);
+
+ CLASS_NEW_DELETE;
+
+private:
+ Slot * _target; // the glyph to fix
+ Rect _limit;
+ float _margin;
+ Position _offsetPrev; // kern from a previous pass
+ Position _currShift; // NOT USED??
+ float _miny; // y-coordinates offset by global slot position
+ float _maxy;
+ Vector<float> _edges; // edges of horizontal slices
+ float _sliceWidth; // width of each slice
+ float _mingap;
+ float _xbound; // max or min edge
+
+#if !defined GRAPHITE2_NTRACING
+ // Debugging
+ Segment * _seg;
+ Vector<float> _nearEdges; // closest potential collision in each slice
+ Vector<Slot*> _slotNear;
+#endif
+}; // end of class KernCollider
+
+
+inline
+float sqr(float x) { return x * x; }
+
+
+}; // end of namespace graphite2
+
diff --git a/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Decompressor.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Decompressor.h
new file mode 100644
index 00000000000..e79410455ee
--- /dev/null
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Decompressor.h
@@ -0,0 +1,52 @@
+/* Copyright (c) 2012, Siyuan Fu <fusiyuan2010@gmail.com>
+ Copyright (c) 2015, SIL International
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ 3. Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+#pragma once
+
+#include <cstddef>
+
+namespace shrinker
+{
+
+int decompress(void const *in, size_t in_size, void *out, size_t out_size);
+/*
+in: inbuf --- compressed data
+out: outbuf --- decompressed data to place in
+size: decompressed(original) data size should be
+
+return value:
+ positive integer means decompress success and it's the sizeof decompressed data,
+ which should be equal to size.
+ or -1 means decompress failed
+*/
+
+} // end of namespace shrinker
+
+
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Endian.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Endian.h
index fc84ec27898..fc84ec27898 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Endian.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Endian.h
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Error.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Error.h
index dd958de6fcd..899b44fd2c9 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Error.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Error.h
@@ -111,16 +111,23 @@ enum errors {
E_BADRULEMAPPING = 50, // The structure of the rule mapping is bad
E_BADRANGE = 51, // Bad column range structure including a glyph in more than one column
E_BADRULENUM = 52, // A reference to a rule is out of range (too high)
+ E_BADACOLLISION = 53, // Bad Silf table collision attribute number (too high)
+ E_BADEMPTYPASS = 54, // Can't have empty passes (no rules) except for collision passes
+ E_BADSILFVERSION = 55, // The Silf table has a bad version (probably too high)
+ E_BADCOLLISIONPASS = 56, // Collision flags set on a non positioning pass
// Code errors
E_CODEFAILURE = 60, // Base code error. The following subcodes must align with Machine::Code::status_t in Code.h
- E_CODEALLOC = 61, // Out of memory
- E_INVALIDOPCODE = 62, // Invalid op code
- E_UNIMPOPCODE = 63, // Unimplemented op code encountered
- E_OUTOFRANGECODE = 64, // Code argument out of range
- E_BADJUMPCODE = 65, // Code jumps past end of op codes
- E_CODEBADARGS = 66, // Code arguments exhausted
- E_CODENORETURN = 67, // Missing return type op code at end of code
- E_CODENESTEDCTXT = 68 // Nested context encountered in code
+ E_CODEALLOC = 61, // Out of memory
+ E_INVALIDOPCODE = 62, // Invalid op code
+ E_UNIMPOPCODE = 63, // Unimplemented op code encountered
+ E_OUTOFRANGECODE = 64, // Code argument out of range
+ E_BADJUMPCODE = 65, // Code jumps past end of op codes
+ E_CODEBADARGS = 66, // Code arguments exhausted
+ E_CODENORETURN = 67, // Missing return type op code at end of code
+ E_CODENESTEDCTXT = 68, // Nested context encountered in code
+// Compression errors
+ E_BADSCHEME = 69,
+ E_SHRINKERFAILED = 70,
};
}
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Face.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Face.h
index e2574492583..3d87494d9f1 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Face.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Face.h
@@ -170,10 +170,13 @@ class Face::Table
const Face * _f;
mutable const byte * _p;
uint32 _sz;
+ bool _compressed;
+
+ Error decompress();
public:
Table() throw();
- Table(const Face & face, const Tag n) throw();
+ Table(const Face & face, const Tag n, uint32 version=0xffffffff) throw();
Table(const Table & rhs) throw();
~Table() throw();
@@ -185,13 +188,13 @@ public:
inline
Face::Table::Table() throw()
-: _f(0), _p(0), _sz(0)
+: _f(0), _p(0), _sz(0), _compressed(false)
{
}
inline
Face::Table::Table(const Table & rhs) throw()
-: _f(rhs._f), _p(rhs._p), _sz(rhs._sz)
+: _f(rhs._f), _p(rhs._p), _sz(rhs._sz), _compressed(rhs._compressed)
{
rhs._p = 0;
}
@@ -199,7 +202,9 @@ Face::Table::Table(const Table & rhs) throw()
inline
Face::Table::~Table() throw()
{
- if (_p && _f->m_ops.release_table)
+ if (_compressed)
+ free(const_cast<byte *>(_p));
+ else if (_p && _f->m_ops.release_table)
(*_f->m_ops.release_table)(_f->m_appFaceHandle, _p);
}
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/FeatureMap.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/FeatureMap.h
index bc8a5db170d..a199a87d71f 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/FeatureMap.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/FeatureMap.h
@@ -117,9 +117,8 @@ class NameAndFeatureRef
class FeatureMap
{
public:
- FeatureMap() : m_numFeats(0), m_feats(NULL), m_pNamedFeats(NULL),
- m_defaultFeatures(NULL) {}
- ~FeatureMap() { delete [] m_feats; delete[] m_pNamedFeats; delete m_defaultFeatures; }
+ FeatureMap() : m_numFeats(0), m_feats(NULL), m_pNamedFeats(NULL) {}
+ ~FeatureMap() { delete [] m_feats; delete[] m_pNamedFeats; }
bool readFeats(const Face & face);
const FeatureRef *findFeatureRef(uint32 name) const;
@@ -135,7 +134,7 @@ friend class SillMap;
FeatureRef *m_feats;
NameAndFeatureRef* m_pNamedFeats; //owned
- FeatureVal* m_defaultFeatures; //owned
+ FeatureVal m_defaultFeatures; //owned
private: //defensive on m_feats, m_pNamedFeats, and m_defaultFeatures
FeatureMap(const FeatureMap&);
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/FeatureVal.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/FeatureVal.h
index 5fbcf082063..5fbcf082063 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/FeatureVal.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/FeatureVal.h
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/FileFace.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/FileFace.h
index 81e501bab25..81e501bab25 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/FileFace.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/FileFace.h
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Font.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Font.h
index bc7084050e5..bc7084050e5 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Font.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Font.h
diff --git a/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/GlyphCache.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/GlyphCache.h
new file mode 100644
index 00000000000..821aae53f2d
--- /dev/null
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/GlyphCache.h
@@ -0,0 +1,227 @@
+/* GRAPHITE2 LICENSING
+
+ Copyright 2012, SIL International
+ All rights reserved.
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should also have received a copy of the GNU Lesser General Public
+ License along with this library in the file named "LICENSE".
+ If not, write to the Free Software Foundation, 51 Franklin Street,
+ Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
+ internet at http://www.fsf.org/licenses/lgpl.html.
+
+Alternatively, the contents of this file may be used under the terms of the
+Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
+License, as published by the Free Software Foundation, either version 2
+of the License or (at your option) any later version.
+*/
+#pragma once
+
+
+#include "graphite2/Font.h"
+#include "inc/Main.h"
+#include "inc/Position.h"
+#include "inc/GlyphFace.h"
+
+namespace graphite2 {
+
+class Face;
+class FeatureVal;
+class Segment;
+
+
+class SlantBox
+{
+public:
+ SlantBox(float psi = 0., float pdi = 0., float psa = 0., float pda = 0.) : si(psi), di(pdi), sa(psa), da(pda) {};
+ float width() const { return sa - si; }
+ float height() const { return da - di; }
+ float si; // min
+ float di; // min
+ float sa; // max
+ float da; // max
+};
+
+static SlantBox nullSlant(0, 0, 0, 0);
+
+class BBox
+{
+public:
+ BBox(float pxi = 0, float pyi = 0., float pxa = 0., float pya = 0.) : xi(pxi), yi(pyi), xa(pxa), ya(pya) {};
+ float width() const { return xa - xi; }
+ float height() const { return ya - yi; }
+ float xi; // min
+ float yi; // min
+ float xa; // max
+ float ya; // max
+};
+
+static BBox nullBBox(0, 0, 0, 0);
+
+class GlyphBox
+{
+ GlyphBox(const GlyphBox &);
+ GlyphBox & operator = (const GlyphBox &);
+
+public:
+ GlyphBox(uint8 numsubs, unsigned short bitmap, Rect *slanted) : _num(numsubs), _bitmap(bitmap), _slant(*slanted) {};
+
+ void addSubBox(int subindex, int boundary, Rect *val) { _subs[subindex * 2 + boundary] = *val; }
+ Rect &subVal(int subindex, int boundary) { return _subs[subindex * 2 + boundary]; }
+ const Rect &slant() const { return _slant; }
+ uint8 num() const { return _num; }
+ const Rect *subs() const { return _subs; }
+
+private:
+ uint8 _num;
+ unsigned short _bitmap;
+ Rect _slant;
+ Rect _subs[1];
+};
+
+class GlyphCache
+{
+ class Loader;
+
+ GlyphCache(const GlyphCache&);
+ GlyphCache& operator=(const GlyphCache&);
+
+ static const Rect nullRect;
+
+public:
+ GlyphCache(const Face & face, const uint32 face_options);
+ ~GlyphCache();
+
+ unsigned short numGlyphs() const throw();
+ unsigned short numAttrs() const throw();
+ unsigned short unitsPerEm() const throw();
+
+ const GlyphFace *glyph(unsigned short glyphid) const; //result may be changed by subsequent call with a different glyphid
+ const GlyphFace *glyphSafe(unsigned short glyphid) const;
+ float getBoundingMetric(unsigned short glyphid, uint8 metric) const;
+ uint8 numSubBounds(unsigned short glyphid) const;
+ float getSubBoundingMetric(unsigned short glyphid, uint8 subindex, uint8 metric) const;
+ const Rect & slant(unsigned short glyphid) const { return _boxes[glyphid] ? _boxes[glyphid]->slant() : nullRect; }
+ const SlantBox & getBoundingSlantBox(unsigned short glyphid) const;
+ const BBox & getBoundingBBox(unsigned short glyphid) const;
+ const SlantBox & getSubBoundingSlantBox(unsigned short glyphid, uint8 subindex) const;
+ const BBox & getSubBoundingBBox(unsigned short glyphid, uint8 subindex) const;
+ bool check(unsigned short glyphid) const;
+
+ CLASS_NEW_DELETE;
+
+private:
+ const Loader * _glyph_loader;
+ const GlyphFace * * _glyphs;
+ GlyphBox * * _boxes;
+ unsigned short _num_glyphs,
+ _num_attrs,
+ _upem;
+};
+
+inline
+unsigned short GlyphCache::numGlyphs() const throw()
+{
+ return _num_glyphs;
+}
+
+inline
+unsigned short GlyphCache::numAttrs() const throw()
+{
+ return _num_attrs;
+}
+
+inline
+unsigned short GlyphCache::unitsPerEm() const throw()
+{
+ return _upem;
+}
+
+inline
+bool GlyphCache::check(unsigned short glyphid) const
+{
+ return glyphid < _num_glyphs;
+}
+
+inline
+const GlyphFace *GlyphCache::glyphSafe(unsigned short glyphid) const
+{
+ return glyphid < _num_glyphs ? glyph(glyphid) : NULL;
+}
+
+inline
+float GlyphCache::getBoundingMetric(unsigned short glyphid, uint8 metric) const
+{
+ if (glyphid >= _num_glyphs) return 0.;
+ switch (metric) {
+ case 0: return (float)(glyph(glyphid)->theBBox().bl.x); // x_min
+ case 1: return (float)(glyph(glyphid)->theBBox().bl.y); // y_min
+ case 2: return (float)(glyph(glyphid)->theBBox().tr.x); // x_max
+ case 3: return (float)(glyph(glyphid)->theBBox().tr.y); // y_max
+ case 4: return (float)(_boxes[glyphid] ? _boxes[glyphid]->slant().bl.x : 0.f); // sum_min
+ case 5: return (float)(_boxes[glyphid] ? _boxes[glyphid]->slant().bl.y : 0.f); // diff_min
+ case 6: return (float)(_boxes[glyphid] ? _boxes[glyphid]->slant().tr.x : 0.f); // sum_max
+ case 7: return (float)(_boxes[glyphid] ? _boxes[glyphid]->slant().tr.y : 0.f); // diff_max
+ default: return 0.;
+ }
+}
+
+inline const SlantBox &GlyphCache::getBoundingSlantBox(unsigned short glyphid) const
+{
+ return _boxes[glyphid] ? *(SlantBox *)(&(_boxes[glyphid]->slant())) : nullSlant;
+}
+
+inline const BBox &GlyphCache::getBoundingBBox(unsigned short glyphid) const
+{
+ return *(BBox *)(&(glyph(glyphid)->theBBox()));
+}
+
+inline
+float GlyphCache::getSubBoundingMetric(unsigned short glyphid, uint8 subindex, uint8 metric) const
+{
+ GlyphBox *b = _boxes[glyphid];
+ if (b == NULL || subindex >= b->num()) return 0;
+
+ switch (metric) {
+ case 0: return b->subVal(subindex, 0).bl.x;
+ case 1: return b->subVal(subindex, 0).bl.y;
+ case 2: return b->subVal(subindex, 0).tr.x;
+ case 3: return b->subVal(subindex, 0).tr.y;
+ case 4: return b->subVal(subindex, 1).bl.x;
+ case 5: return b->subVal(subindex, 1).bl.y;
+ case 6: return b->subVal(subindex, 1).tr.x;
+ case 7: return b->subVal(subindex, 1).tr.y;
+ default: return 0.;
+ }
+}
+
+inline const SlantBox &GlyphCache::getSubBoundingSlantBox(unsigned short glyphid, uint8 subindex) const
+{
+ GlyphBox *b = _boxes[glyphid];
+// if (b == NULL || subindex >= b->num()) return nullSlant;
+ return *(SlantBox *)(b->subs() + 2 * subindex + 1);
+}
+
+inline const BBox &GlyphCache::getSubBoundingBBox(unsigned short glyphid, uint8 subindex) const
+{
+ GlyphBox *b = _boxes[glyphid];
+// if (b == NULL || subindex >= b->num()) return nullBBox;
+ return *(BBox *)(b->subs() + 2 * subindex);
+}
+
+inline
+uint8 GlyphCache::numSubBounds(unsigned short glyphid) const
+{
+ return _boxes[glyphid] ? _boxes[glyphid]->num() : 0;
+}
+
+} // namespace graphite2
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/GlyphFace.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/GlyphFace.h
index 89ed5aea91a..89ed5aea91a 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/GlyphFace.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/GlyphFace.h
diff --git a/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Intervals.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Intervals.h
new file mode 100644
index 00000000000..bc9fab65ab1
--- /dev/null
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Intervals.h
@@ -0,0 +1,231 @@
+/* GRAPHITE2 LICENSING
+
+ Copyright 2010, SIL International
+ All rights reserved.
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should also have received a copy of the GNU Lesser General Public
+ License along with this library in the file named "LICENSE".
+ If not, write to the Free Software Foundation, 51 Franklin Street,
+ Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
+ internet at http://www.fsf.org/licenses/lgpl.html.
+
+Alternatively, the contents of this file may be used under the terms of the
+Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
+License, as published by the Free Software Foundation, either version 2
+of the License or (at your option) any later version.
+*/
+#pragma once
+
+#include <utility>
+
+#include "inc/Main.h"
+#include "inc/List.h"
+#include "inc/json.h"
+#include "inc/Position.h"
+
+// An IntervalSet represents the possible movement of a given glyph in a given direction
+// (horizontally, vertically, or diagonally).
+// A vector is needed to represent disjoint ranges, eg, -300..-150, 20..200, 500..750.
+// Each pair represents the min/max of a sub-range.
+
+namespace graphite2 {
+
+class Segment;
+
+enum zones_t {SD, XY};
+
+class Zones
+{
+ struct Exclusion
+ {
+ template<zones_t O>
+ static Exclusion weighted(float xmin, float xmax, float f, float a0,
+ float m, float xi, float ai, float c, bool nega);
+
+ float x, // x position
+ xm, // xmax position
+ c, // constant + sum(MiXi^2)
+ sm, // sum(Mi)
+ smx; // sum(MiXi)
+ bool open;
+
+ Exclusion(float x, float w, float smi, float smxi, float c);
+ Exclusion & operator += (Exclusion const & rhs);
+ uint8 outcode(float p) const;
+
+ Exclusion split_at(float p);
+ void left_trim(float p);
+
+ bool track_cost(float & cost, float & x, float origin) const;
+
+ private:
+ float test_position(float origin) const;
+ float cost(float x) const;
+ };
+
+ typedef Vector<Exclusion> exclusions;
+
+ typedef exclusions::iterator iterator;
+ typedef Exclusion * pointer;
+ typedef Exclusion & reference;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+
+public:
+ typedef exclusions::const_iterator const_iterator;
+ typedef Exclusion const * const_pointer;
+ typedef Exclusion const & const_reference;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+#if !defined GRAPHITE2_NTRACING
+ struct Debug
+ {
+ Exclusion _excl;
+ bool _isdel;
+ Vector<void *> _env;
+
+ Debug(Exclusion *e, bool isdel, json *dbg) : _excl(*e), _isdel(isdel), _env(dbg->getenvs()) { };
+ };
+
+ typedef Vector<Debug> debugs;
+ typedef debugs::const_iterator idebugs;
+ void addDebug(Exclusion *e);
+ void removeDebug(float pos, float posm);
+ void setdebug(json *dbgout) { _dbg = dbgout; }
+ idebugs dbgs_begin() const { return _dbgs.begin(); }
+ idebugs dbgs_end() const { return _dbgs.end(); }
+ void jsonDbgOut(Segment *seg) const;
+ Position position() const { return Position(_pos, _posm); }
+#endif
+
+ Zones();
+ template<zones_t O>
+ void initialise(float xmin, float xmax, float margin_len, float margin_weight, float ao);
+
+ void exclude(float xmin, float xmax);
+ void exclude_with_margins(float xmin, float xmax, int axis);
+
+ template<zones_t O>
+ void weighted(float xmin, float xmax, float f, float a0, float mi, float xi, float ai, float c, bool nega);
+ void weightedAxis(int axis, float xmin, float xmax, float f, float a0, float mi, float xi, float ai, float c, bool nega);
+
+ float closest( float origin, float &cost) const;
+
+ const_iterator begin() const { return _exclusions.begin(); }
+ const_iterator end() const { return _exclusions.end(); }
+
+private:
+ exclusions _exclusions;
+#if !defined GRAPHITE2_NTRACING
+ json * _dbg;
+ debugs _dbgs;
+#endif
+ float _margin_len,
+ _margin_weight,
+ _pos,
+ _posm;
+
+ void insert(Exclusion e);
+ void remove(float x, float xm);
+ const_iterator find_exclusion_under(float x) const;
+};
+
+
+inline
+Zones::Zones()
+: _margin_len(0), _margin_weight(0), _pos(0), _posm(0)
+{
+ _exclusions.reserve(8);
+}
+
+inline
+Zones::Exclusion::Exclusion(float x_, float xm_, float smi, float smxi, float c_)
+: x(x_), xm(xm_), c(c_), sm(smi), smx(smxi), open(false)
+{ }
+
+template<zones_t O>
+inline
+void Zones::initialise(float xmin, float xmax, float margin_len,
+ float margin_weight, float a0)
+{
+ _margin_len = margin_len;
+ _margin_weight = margin_weight;
+ _pos = xmin;
+ _posm = xmax;
+ _exclusions.clear();
+ _exclusions.push_back(Exclusion::weighted<O>(xmin, xmax, 1, a0, 0, 0, 0, 0, false));
+ _exclusions.front().open = true;
+#if !defined GRAPHITE2_NTRACING
+ _dbgs.clear();
+#endif
+}
+
+inline
+void Zones::exclude(float xmin, float xmax) {
+ remove(xmin, xmax);
+}
+
+template<zones_t O>
+inline
+void Zones::weighted(float xmin, float xmax, float f, float a0,
+ float m, float xi, float ai, float c, bool nega) {
+ insert(Exclusion::weighted<O>(xmin, xmax, f, a0, m, xi, ai, c, nega));
+}
+
+inline
+void Zones::weightedAxis(int axis, float xmin, float xmax, float f, float a0,
+ float m, float xi, float ai, float c, bool nega) {
+ if (axis < 2)
+ weighted<XY>(xmin, xmax, f, a0, m, xi, ai, c, nega);
+ else
+ weighted<SD>(xmin, xmax, f, a0, m, xi, ai, c, nega);
+}
+
+#if !defined GRAPHITE2_NTRACING
+inline
+void Zones::addDebug(Exclusion *e) {
+ if (_dbg)
+ _dbgs.push_back(Debug(e, false, _dbg));
+}
+
+inline
+void Zones::removeDebug(float pos, float posm) {
+ if (_dbg)
+ {
+ Exclusion e(pos, posm, 0, 0, 0);
+ _dbgs.push_back(Debug(&e, true, _dbg));
+ }
+}
+#endif
+
+template<>
+inline
+Zones::Exclusion Zones::Exclusion::weighted<XY>(float xmin, float xmax, float f, float a0,
+ float m, float xi, GR_MAYBE_UNUSED float ai, float c, GR_MAYBE_UNUSED bool nega) {
+ return Exclusion(xmin, xmax,
+ m + f,
+ m * xi,
+ m * xi * xi + f * a0 * a0 + c);
+}
+
+template<>
+inline
+Zones::Exclusion Zones::Exclusion::weighted<SD>(float xmin, float xmax, float f, float a0,
+ float m, float xi, float ai,float c, bool nega) {
+ float xia = nega ? xi - ai : xi + ai;
+ return Exclusion(xmin, xmax,
+ 0.25f * (m + 2.f * f),
+ 0.25f * m * xia,
+ 0.25f * (m * xia * xia + 2.f * f * a0 * a0) + c);
+}
+
+} // end of namespace graphite2
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/List.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/List.h
index f99036912d8..41e51738c3e 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/List.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/List.h
@@ -70,6 +70,7 @@ public:
size_t capacity() const{ return m_end - m_first; }
void reserve(size_t n);
+ void resize(size_t n, const T & v = T());
reference front() { assert(size() > 0); return *begin(); }
const_reference front() const { assert(size() > 0); return *begin(); }
@@ -82,7 +83,7 @@ public:
void assign(size_t n, const T& u) { clear(); insert(begin(), n, u); }
void assign(const_iterator first, const_iterator last) { clear(); insert(begin(), first, last); }
- iterator insert(iterator p, const T & x) { p = _insert_default(p, 1); *p = x; return p; }
+ iterator insert(iterator p, const T & x) { p = _insert_default(p, 1); new (p) T(x); return p; }
void insert(iterator p, size_t n, const T & x);
void insert(iterator p, const_iterator first, const_iterator last);
void pop_back() { assert(size() > 0); --m_last; }
@@ -109,13 +110,21 @@ void Vector<T>::reserve(size_t n)
}
}
+template <typename T>
+inline
+void Vector<T>::resize(size_t n, const T & v) {
+ const ptrdiff_t d = n-size();
+ if (d < 0) erase(end()+d, end());
+ else if (d > 0) insert(end(), d, v);
+}
+
template<typename T>
inline
typename Vector<T>::iterator Vector<T>::_insert_default(iterator p, size_t n)
{
assert(begin() <= p && p <= end());
const ptrdiff_t i = p - begin();
- reserve((size() + n + 7) >> 3 << 3);
+ reserve(((size() + n + 7) >> 3) << 3);
p = begin() + i;
// Move tail if there is one
if (p != end()) memmove(p + n, p, distance(p,end())*sizeof(T));
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Machine.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Machine.h
index 21f8addbb44..4efb70cd946 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Machine.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Machine.h
@@ -110,7 +110,9 @@ enum opcode {
PUSH_PROC_STATE, PUSH_VERSION,
PUT_SUBS, PUT_SUBS2, PUT_SUBS3,
PUT_GLYPH, PUSH_GLYPH_ATTR, PUSH_ATT_TO_GLYPH_ATTR,
- MAX_OPCODE,
+ BITOR, BITAND, BITNOT,
+ BITSET, SET_FEAT,
+ MAX_OPCODE,
// private opcodes for internal use only, comes after all other on disk opcodes
TEMP_COPY = MAX_OPCODE
};
@@ -148,7 +150,7 @@ public:
SlotMap & slotMap() const throw();
status_t status() const throw();
- operator bool () const throw();
+// operator bool () const throw();
private:
void check_final_stack(const stack_t * const sp);
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Main.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Main.h
index 8f7c201b96b..8ff062a71d6 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Main.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Main.h
@@ -125,3 +125,8 @@ inline T max(const T a, const T b)
#else
#define GR_MAYBE_UNUSED
#endif
+
+#ifdef _MSC_VER
+#pragma warning(disable: 4800)
+#pragma warning(once: 4355)
+#endif
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/NameTable.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/NameTable.h
index 0fdbeb4d85f..0fdbeb4d85f 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/NameTable.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/NameTable.h
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Pass.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Pass.h
index 33abbdce503..f0f9a5f1249 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Pass.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Pass.h
@@ -39,6 +39,11 @@ struct RuleEntry;
struct State;
class FiniteStateMachine;
class Error;
+class ShiftCollider;
+class KernCollider;
+class json;
+
+enum passtype;
class Pass
{
@@ -46,10 +51,11 @@ public:
Pass();
~Pass();
- bool readPass(const byte * pPass, size_t pass_length, size_t subtable_base, Face & face, Error &e);
- void runGraphite(vm::Machine & m, FiniteStateMachine & fsm) const;
+ bool readPass(const byte * pPass, size_t pass_length, size_t subtable_base, Face & face,
+ enum passtype pt, uint32 version, Error &e);
+ bool runGraphite(vm::Machine & m, FiniteStateMachine & fsm) const;
void init(Silf *silf) { m_silf = silf; }
- byte spaceContextuals() const { return (m_flags & 0x0E) >> 1; }
+ byte flags() const { return m_flags; }
CLASS_NEW_DELETE
private:
@@ -61,7 +67,7 @@ private:
const byte *precontext, const uint16 * sort_key,
const uint16 * o_constraint, const byte *constraint_data,
const uint16 * o_action, const byte * action_data,
- Face &, Error &e);
+ Face &, enum passtype pt, Error &e);
bool readStates(const byte * starts, const byte * states, const byte * o_rule_map, Face &, Error &e);
bool readRanges(const byte * ranges, size_t num_ranges, Error &e);
uint16 glyphToCol(const uint16 gid) const;
@@ -69,14 +75,24 @@ private:
void dumpRuleEventConsidered(const FiniteStateMachine & fsm, const RuleEntry & re) const;
void dumpRuleEventOutput(const FiniteStateMachine & fsm, const Rule & r, Slot * os) const;
void adjustSlot(int delta, Slot * & slot_out, SlotMap &) const;
- const Silf* m_silf;
- uint16 * m_cols;
- Rule * m_rules; // rules
- RuleEntry * m_ruleMap;
- uint16 * m_startStates; // prectxt length
- uint16 * m_transitions;
- State * m_states;
-
+ bool collisionShift(Segment *seg, int dir, json * const dbgout) const;
+ bool collisionKern(Segment *seg, int dir, json * const dbgout) const;
+ bool collisionFinish(Segment *seg, GR_MAYBE_UNUSED json * const dbgout) const;
+ bool resolveCollisions(Segment *seg, Slot *slot, Slot *start, ShiftCollider &coll, bool isRev,
+ int dir, bool &moved, bool &hasCol, json * const dbgout) const;
+ float resolveKern(Segment *seg, Slot *slot, Slot *start, KernCollider &coll, int dir,
+ float &ymin, float &ymax, json *const dbgout) const;
+
+ const Silf * m_silf;
+ uint16 * m_cols;
+ Rule * m_rules; // rules
+ RuleEntry * m_ruleMap;
+ uint16 * m_startStates; // prectxt length
+ uint16 * m_transitions;
+ State * m_states;
+ vm::Machine::Code * m_codes;
+ byte * m_progs;
+
byte m_flags;
byte m_iMaxLoop;
uint16 m_numGlyphs;
@@ -88,6 +104,7 @@ private:
uint16 m_numColumns;
byte m_minPreCtxt;
byte m_maxPreCtxt;
+ byte m_colThreshold;
vm::Machine::Code m_cPConstraint;
private: //defensive
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Position.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Position.h
index c6f1b755644..97bc1cdf7a8 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Position.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Position.h
@@ -50,7 +50,16 @@ public :
Rect(const Position& botLeft, const Position& topRight): bl(botLeft), tr(topRight) {}
Rect widen(const Rect& other) { return Rect(Position(bl.x > other.bl.x ? other.bl.x : bl.x, bl.y > other.bl.y ? other.bl.y : bl.y), Position(tr.x > other.tr.x ? tr.x : other.tr.x, tr.y > other.tr.y ? tr.y : other.tr.y)); }
Rect operator + (const Position &a) const { return Rect(Position(bl.x + a.x, bl.y + a.y), Position(tr.x + a.x, tr.y + a.y)); }
+ Rect operator - (const Position &a) const { return Rect(Position(bl.x - a.x, bl.y - a.y), Position(tr.x - a.x, tr.y - a.y)); }
Rect operator * (float m) const { return Rect(Position(bl.x, bl.y) * m, Position(tr.x, tr.y) * m); }
+ float width() const { return tr.x - bl.x; }
+ float height() const { return tr.y - bl.y; }
+
+ bool hitTest(Rect &other);
+
+ // returns Position(overlapx, overlapy) where overlap<0 if overlapping else positive)
+ Position overlap(Position &offset, Rect &other, Position &otherOffset);
+ //Position constrainedAvoid(Position &offset, Rect &box, Rect &sdbox, Position &other, Rect &obox, Rect &osdbox);
Position bl;
Position tr;
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Rule.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Rule.h
index 8891ac86334..caec236274b 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Rule.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Rule.h
@@ -53,8 +53,6 @@ private:
inline Rule::~Rule()
{
- delete constraint;
- delete action;
}
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/SegCache.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/SegCache.h
index ad48258d053..ad48258d053 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/SegCache.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/SegCache.h
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/SegCacheEntry.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/SegCacheEntry.h
index 9a7d930677c..9a7d930677c 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/SegCacheEntry.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/SegCacheEntry.h
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/SegCacheStore.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/SegCacheStore.h
index 1e6a6e216e7..1e6a6e216e7 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/SegCacheStore.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/SegCacheStore.h
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Segment.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Segment.h
index ef15e125ef2..b814c5f0f9e 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Segment.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Segment.h
@@ -40,6 +40,7 @@ of the License or (at your option) any later version.
#include "inc/Position.h"
#include "inc/List.h"
#include "inc/Bidi.h"
+#include "inc/Collider.h"
#define MAX_SEG_GROWTH_FACTOR 256
@@ -86,6 +87,11 @@ class Segment
Segment& operator=(const Segment&);
public:
+
+ enum {
+ SEG_INITCOLLISIONS = 1
+ };
+
unsigned int slotCount() const { return m_numGlyphs; } //one slot per glyph
void extendLength(int num) { m_numGlyphs += num; }
Position advance() const { return m_advance; }
@@ -107,6 +113,8 @@ public:
Slot * endSlot, const Slot * srcSlot,
const size_t numGlyphs);
#endif
+ uint8 flags() const { return m_flags; }
+ void flags(uint8 f) { m_flags = f; }
Slot *first() { return m_first; }
void first(Slot *p) { m_first = p; }
Slot *last() { return m_last; }
@@ -116,13 +124,20 @@ public:
void freeSlot(Slot *);
SlotJustify *newJustify();
void freeJustify(SlotJustify *aJustify);
- Position positionSlots(const Font *font, Slot *first=0, Slot *last=0);
+ Position positionSlots(const Font *font=0, Slot *first=0, Slot *last=0, bool isFinal = true);
void associateChars(int offset, int num);
void linkClusters(Slot *first, Slot *last);
uint16 getClassGlyph(uint16 cid, uint16 offset) const { return m_silf->getClassGlyph(cid, offset); }
uint16 findClassIndex(uint16 cid, uint16 gid) const { return m_silf->findClassIndex(cid, gid); }
int addFeatures(const Features& feats) { m_feats.push_back(feats); return m_feats.size() - 1; }
uint32 getFeature(int index, uint8 findex) const { const FeatureRef* pFR=m_face->theSill().theFeatureMap().featureRef(findex); if (!pFR) return 0; else return pFR->getFeatureVal(m_feats[index]); }
+ void setFeature(int index, uint8 findex, uint32 val) {
+ const FeatureRef* pFR=m_face->theSill().theFeatureMap().featureRef(findex);
+ if (pFR)
+ {
+ if (val > pFR->maxVal()) val = pFR->maxVal();
+ pFR->applyValToFeature(val, m_feats[index]);
+ } }
void dir(int8 val) { m_dir = val; }
unsigned int passBits() const { return m_passBits; }
void mergePassBits(const unsigned int val) { m_passBits &= val; }
@@ -141,14 +156,16 @@ public:
bool hasJustification() const { return m_justifies.size() != 0; }
bool isWhitespace(const int cid) const;
+ bool hasCollisionInfo() const { return m_collisions != 0; }
+ SlotCollision *collisionInfo(const Slot *s) const { return m_collisions ? m_collisions + s->index() : NULL; }
CLASS_NEW_DELETE
public: //only used by: GrSegment* makeAndInitialize(const GrFont *font, const GrFace *face, uint32 script, const FeaturesHandle& pFeats/*must not be IsNull*/, encform enc, const void* pStart, size_t nChars, int dir);
bool read_text(const Face *face, const Features* pFeats/*must not be NULL*/, gr_encform enc, const void*pStart, size_t nChars);
- void prepare_pos(const Font *font);
void finalise(const Font *font);
float justify(Slot *pSlot, const Font *font, float width, enum justFlags flags, Slot *pFirst, Slot *pLast);
+ bool initCollisions();
private:
Position m_advance; // whole segment advance
@@ -159,6 +176,7 @@ private:
Slot * m_freeSlots; // linked list of free slots
SlotJustify * m_freeJustifies; // Slot justification blocks free list
CharInfo * m_charinfo; // character info, one per input character
+ SlotCollision * m_collisions; // Array of SlotCollisions for each slot
const Face * m_face; // GrFace
const Silf * m_silf;
Slot * m_first; // first slot in segment
@@ -169,6 +187,7 @@ private:
m_passBits; // if bit set then skip pass
int m_defaultOriginal; // number of whitespace chars in the string
int8 m_dir;
+ uint8 m_flags; // General purpose flags
};
@@ -179,7 +198,7 @@ void Segment::finalise(const Font *font)
if (!m_first) return;
m_advance = positionSlots(font);
- associateChars(0, m_numCharinfo);
+ //associateChars(0, m_numCharinfo);
linkClusters(m_first, m_last);
}
diff --git a/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Shrinker.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Shrinker.h
new file mode 100644
index 00000000000..e4db2f135a6
--- /dev/null
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Shrinker.h
@@ -0,0 +1,119 @@
+/* Copyright (c) 2012, Siyuan Fu <fusiyuan2010@gmail.com>
+ Copyright (c) 2015, SIL International
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ 3. Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#pragma once
+
+#include <cassert>
+#include <cstddef>
+#include <cstring>
+
+#include <iterator>
+
+//the code from LZ4
+#if (GCC_VERSION >= 302) || (__INTEL_COMPILER >= 800) || defined(__clang__)
+# define expect(expr,value) (__builtin_expect ((expr),(value)) )
+#else
+# define expect(expr,value) (expr)
+#endif
+#define likely(expr) expect((expr) != 0, 1)
+#define unlikely(expr) expect((expr) != 0, 0)
+////////////////////
+
+
+namespace
+{
+
+#if defined(_MSC_VER)
+typedef unsigned __int8 u8;
+typedef unsigned __int16 u16;
+typedef unsigned __int32 u32;
+typedef unsigned __int64 u64;
+#else
+#include <stdint.h>
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+#endif
+
+ptrdiff_t const MINMATCH = 4;
+
+template<int S>
+inline
+void unaligned_copy(void * d, void const * s) {
+ ::memcpy(d, s, S);
+}
+
+inline
+u8 * memcpy_nooverlap(u8 * d, u8 const * s, size_t n) {
+ size_t const WS = sizeof(unsigned long);
+ u8 const * e = s + n;
+ do
+ {
+ unaligned_copy<WS>(d, s);
+ d += WS;
+ s += WS;
+ }
+ while (s < e);
+ d-=(s-e);
+
+ return d;
+}
+
+
+inline
+u8 * memcpy_nooverlap_surpass(u8 * d, u8 const * s, size_t n) {
+ size_t const WS = sizeof(unsigned long);
+ size_t wn = n/WS;
+ while (wn--)
+ {
+ unaligned_copy<WS>(d, s);
+ d += WS;
+ s += WS;
+ }
+ n &= WS-1;
+ while (n--) {*d++ = *s++; }
+
+ return d;
+}
+
+
+inline
+u8 * memcpy_(u8 * d, u8 const * s, size_t n) {
+ if (likely(d>s+sizeof(unsigned long)))
+ return memcpy_nooverlap(d,s,n);
+ else while (n--) *d++ = *s++;
+ return d;
+}
+
+} // end of anonymous namespace
+
+
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Silf.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Silf.h
index c7e9b5d6b6a..a31d4bf35f9 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Silf.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Silf.h
@@ -85,6 +85,7 @@ public:
uint8 aMirror() const {return m_aMirror; }
uint8 aPassBits() const { return m_aPassBits; }
uint8 aBidi() const { return m_aBidi; }
+ uint8 aCollision() const { return m_aCollision; }
uint8 substitutionPass() const { return m_sPass; }
uint8 positionPass() const { return m_pPass; }
uint8 justificationPass() const { return m_jPass; }
@@ -114,13 +115,10 @@ private:
uint8 m_sPass, m_pPass, m_jPass, m_bPass,
m_flags;
- uint8 m_aPseudo, m_aBreak, m_aUser, m_aBidi, m_aMirror, m_aPassBits,
- m_iMaxComp;
- uint16 m_aLig,
- m_numPseudo,
- m_nClass,
- m_nLinear,
- m_gEndLine;
+ uint8 m_aPseudo, m_aBreak, m_aUser, m_aBidi, m_aMirror, m_aPassBits,
+ m_iMaxComp, m_aCollision;
+ uint16 m_aLig, m_numPseudo, m_nClass, m_nLinear,
+ m_gEndLine;
gr_faceinfo m_silfinfo;
void releaseBuffers() throw();
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Slot.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Slot.h
index 1847269d733..65ee5af8bc8 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Slot.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Slot.h
@@ -75,6 +75,7 @@ public:
unsigned short gid() const { return m_glyphid; }
Position origin() const { return m_position; }
float advance() const { return m_advance.x; }
+ void advance(Position &val) { m_advance = val; }
Position advancePos() const { return m_advance; }
int before() const { return m_before; }
int after() const { return m_after; }
@@ -98,7 +99,7 @@ public:
void after(int ind) { m_after = ind; }
bool isBase() const { return (!m_parent); }
void update(int numSlots, int numCharInfo, Position &relpos);
- Position finalise(const Segment* seg, const Font* font, Position & base, Rect & bbox, uint8 attrLevel, float & clusterMin);
+ Position finalise(const Segment* seg, const Font* font, Position & base, Rect & bbox, uint8 attrLevel, float & clusterMin, bool isFinal);
bool isDeleted() const { return (m_flags & DELETED) ? true : false; }
void markDeleted(bool state) { if (state) m_flags |= DELETED; else m_flags &= ~DELETED; }
bool isCopied() const { return (m_flags & COPIED) ? true : false; }
@@ -122,8 +123,10 @@ public:
Slot *attachedTo() const { return m_parent; }
Position attachOffset() const { return m_attach - m_with; }
Slot* firstChild() const { return m_child; }
+ void firstChild(Slot *ap) { m_child = ap; }
bool child(Slot *ap);
Slot* nextSibling() const { return m_sibling; }
+ void nextSibling(Slot *ap) { m_sibling = ap; }
bool sibling(Slot *ap);
bool removeChild(Slot *ap);
bool removeSibling(Slot *ap);
@@ -132,6 +135,8 @@ public:
void floodShift(Position adj);
float just() const { return m_just; }
void just(float j) { m_just = j; }
+ Slot *nextInCluster(const Slot *s) const;
+ bool isChildOf(const Slot *base) const;
CLASS_NEW_DELETE
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Sparse.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Sparse.h
index b87ab88f3c8..b87ab88f3c8 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/Sparse.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/Sparse.h
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/TtfTypes.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/TtfTypes.h
index ea20e5775fc..ea20e5775fc 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/TtfTypes.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/TtfTypes.h
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/TtfUtil.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/TtfUtil.h
index b7b7ffee6c8..428dea09f13 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/TtfUtil.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/TtfUtil.h
@@ -137,11 +137,11 @@ public:
////////////////////////////////// cmap lookup tools
const void * FindCmapSubtable(const void * pCmap, int nPlatformId = 3,
int nEncodingId = 1, size_t length = 0);
- bool CheckCmapSubtable4(const void * pCmap31);
+ bool CheckCmapSubtable4(const void * pCmap31 /*, unsigned int maxgid*/);
gid16 CmapSubtable4Lookup(const void * pCmapSubtabel4, unsigned int nUnicodeId, int rangeKey = 0);
unsigned int CmapSubtable4NextCodepoint(const void *pCmap31, unsigned int nUnicodeId,
int * pRangeKey = 0);
- bool CheckCmapSubtable12(const void *pCmap310);
+ bool CheckCmapSubtable12(const void *pCmap310 /*, unsigned int maxgid*/);
gid16 CmapSubtable12Lookup(const void * pCmap310, unsigned int uUnicodeId, int rangeKey = 0);
unsigned int CmapSubtable12NextCodepoint(const void *pCmap310, unsigned int nUnicodeId,
int * pRangeKey = 0);
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/UtfCodec.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/UtfCodec.h
index c60ba41e72e..c60ba41e72e 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/UtfCodec.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/UtfCodec.h
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/bits.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/bits.h
index 908049f7285..615c6cba67f 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/bits.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/bits.h
@@ -29,15 +29,63 @@ of the License or (at your option) any later version.
namespace graphite2
{
+
+#if defined GRAPHITE2_BUILTINS && (defined __GNUC__ || defined __clang__)
+
template<typename T>
inline unsigned int bit_set_count(T v)
{
- v = v - ((v >> 1) & T(~T(0)/3)); // temp
- v = (v & T(~T(0)/15*3)) + ((v >> 2) & T(~T(0)/15*3)); // temp
- v = (v + (v >> 4)) & T(~T(0)/255*15); // temp
- return (T)(v * T(~T(0)/255)) >> (sizeof(T)-1)*8; // count
+ return __builtin_popcount(v);
+}
+
+template<>
+inline unsigned int bit_set_count(int16 v)
+{
+ return __builtin_popcount(static_cast<uint16>(v));
+}
+
+template<>
+inline unsigned int bit_set_count(int8 v)
+{
+ return __builtin_popcount(static_cast<uint8>(v));
}
+template<>
+inline unsigned int bit_set_count(unsigned long v)
+{
+ return __builtin_popcountl(v);
+}
+
+template<>
+inline unsigned int bit_set_count(signed long v)
+{
+ return __builtin_popcountl(v);
+}
+
+template<>
+inline unsigned int bit_set_count(unsigned long long v)
+{
+ return __builtin_popcountll(v);
+}
+
+template<>
+inline unsigned int bit_set_count(signed long long v)
+{
+ return __builtin_popcountll(v);
+}
+#else
+
+template<typename T>
+inline unsigned int bit_set_count(T v)
+{
+ v = v - ((v >> 1) & T(~(0UL)/3)); // temp
+ v = (v & T(~(0UL)/15*3)) + ((v >> 2) & T(~(0UL)/15*3)); // temp
+ v = (v + (v >> 4)) & T(~(0UL)/255*15); // temp
+ return (T)(v * T(~(0UL)/255)) >> (sizeof(T)-1)*8; // count
+}
+
+#endif
+
template<int S>
inline unsigned long _mask_over_val(unsigned long v)
@@ -87,4 +135,12 @@ inline T zero_bytes(const T x, unsigned char n)
return T((has_zero(x^t) >> 7)*n);
}
+#if 0
+inline float float_round(float x, uint32 m)
+{
+ *reinterpret_cast<unsigned int *>(&x) &= m;
+ return *reinterpret_cast<float *>(&x);
+}
+#endif
+
}
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/debug.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/debug.h
index a4438c9269d..97175eb2cc4 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/debug.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/debug.h
@@ -54,6 +54,7 @@ struct objectid
json & operator << (json & j, const Position &) throw();
+json & operator << (json & j, const Rect &) throw();
json & operator << (json & j, const CharInfo &) throw();
json & operator << (json & j, const dslot &) throw();
json & operator << (json & j, const objectid &) throw();
@@ -69,6 +70,13 @@ json & operator << (json & j, const Position & p) throw()
inline
+json & operator << (json & j, const Rect & p) throw()
+{
+ return j << json::flat << json::array << p.bl.x << p.bl.y << p.tr.x << p.tr.y << json::close;
+}
+
+
+inline
json & operator << (json & j, const objectid & sid) throw()
{
return j << sid.name;
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/json.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/json.h
index 1310411270d..90b8573d655 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/json.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/json.h
@@ -29,9 +29,11 @@ of the License or (at your option) any later version.
// Author: Tim Eves
#pragma once
+
#include "inc/Main.h"
#include <cassert>
#include <cstdio>
+#include "inc/List.h"
namespace graphite2 {
@@ -49,6 +51,7 @@ class json
* _context, // current context (top of stack)
* _flatten; // if !0 points to context above which
// pretty printed output should occur.
+ Vector<void *> _env;
void context(const char current) throw();
void indent(const int d=0) throw();
@@ -64,6 +67,10 @@ public:
typedef bool boolean;
static const _null_t null;
+ void setenv(unsigned int index, void *val) { _env.reserve(index + 1); if (index >= _env.size()) _env.insert(_env.end(), _env.size() - index + 1, 0); _env[index] = val; }
+ void *getenv(unsigned int index) const { return _env[index]; }
+ const Vector<void *> &getenvs() const { return _env; }
+
static void flat(json &) throw();
static void close(json &) throw();
static void object(json &) throw();
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/locale2lcid.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/locale2lcid.h
index bc3e3d83047..bc3e3d83047 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/locale2lcid.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/locale2lcid.h
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/opcode_table.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/opcode_table.h
index 06916f6c875..73a99c82043 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/opcode_table.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/opcode_table.h
@@ -43,7 +43,7 @@ of the License or (at your option) any later version.
// level - any byte
static const opcode_t opcode_table[] =
{
- {{do2(nop)}, 0, "NOP"},
+ {{do2(nop)}, 0, "NOP"},
{{do2(push_byte)}, 1, "PUSH_BYTE"}, // number
{{do2(push_byte_u)}, 1, "PUSH_BYTE_U"}, // number
@@ -114,6 +114,11 @@ static const opcode_t opcode_table[] =
{{do_(put_glyph), NILOP}, 2, "PUT_GLYPH"}, // output_class output_class
{{do2(push_glyph_attr)}, 3, "PUSH_GLYPH_ATTR"}, // gattrnum gattrnum slot
{{do2(push_att_to_glyph_attr)}, 3, "PUSH_ATT_TO_GLYPH_ATTR"}, // gattrnum gattrnum slot
+ {{do2(bor)}, 0, "BITOR"},
+ {{do2(band)}, 0, "BITAND"},
+ {{do2(bnot)}, 0, "BITNOT"}, // 0x40
+ {{do2(setbits)}, 4, "BITSET"},
+ {{do2(set_feat)}, 2, "SET_FEAT"},
// private opcodes for internal use only, comes after all other on disk opcodes.
{{do_(temp_copy), NILOP}, 0, "TEMP_COPY"}
};
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/opcodes.h b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/opcodes.h
index 9ad35bfd373..1c36c301b64 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/inc/opcodes.h
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/inc/opcodes.h
@@ -241,20 +241,24 @@ ENDOP
STARTOP(put_copy)
declare_params(1);
const int slot_ref = int8(*param);
- if (is && (slot_ref ||is != *map))
+ if (is)
{
- int16 *tempUserAttrs = is->userAttrs();
slotref ref = slotat(slot_ref);
- if (ref)
+ if (ref && ref != is)
{
- memcpy(tempUserAttrs, ref->userAttrs(), seg.numAttrs() * sizeof(uint16));
+ int16 *tempUserAttrs = is->userAttrs();
+ if (is->attachedTo() || is->firstChild()) DIE
Slot *prev = is->prev();
Slot *next = is->next();
- memcpy(is, slotat(slot_ref), sizeof(Slot));
+ memcpy(tempUserAttrs, ref->userAttrs(), seg.numAttrs() * sizeof(uint16));
+ memcpy(is, ref, sizeof(Slot));
+ is->firstChild(NULL);
+ is->nextSibling(NULL);
is->userAttrs(tempUserAttrs);
is->next(next);
is->prev(prev);
- is->sibling(NULL);
+ if (is->attachedTo())
+ is->attachedTo()->child(is);
}
is->markCopied(false);
is->markDeleted(false);
@@ -316,7 +320,7 @@ STARTOP(insert)
ENDOP
STARTOP(delete_)
- if (!is) DIE
+ if (!is || is->isDeleted()) DIE
is->markDeleted(true);
if (is->prev())
is->prev()->next(is->next());
@@ -644,3 +648,37 @@ STARTOP(temp_copy)
newSlot->markCopied(true);
*map = newSlot;
ENDOP
+
+STARTOP(band)
+ binop(&);
+ENDOP
+
+STARTOP(bor)
+ binop(|);
+ENDOP
+
+STARTOP(bnot)
+ *sp = ~*sp;
+ENDOP
+
+STARTOP(setbits)
+ declare_params(4);
+ const uint16 m = uint16(param[0]) << 8
+ | uint8(param[1]);
+ const uint16 v = uint16(param[2]) << 8
+ | uint8(param[3]);
+ *sp = ((*sp) & ~m) | v;
+ENDOP
+
+STARTOP(set_feat)
+ declare_params(2);
+ const unsigned int feat = uint8(param[0]);
+ const int slot_ref = int8(param[1]);
+ slotref slot = slotat(slot_ref);
+ if (slot)
+ {
+ uint8 fid = seg.charinfo(slot->original())->fid();
+ seg.setFeature(fid, feat, pop());
+ }
+ENDOP
+
diff --git a/Build/source/libs/graphite2/graphite2-1.2.4/src/json.cpp b/Build/source/libs/graphite2/graphite2-1.3.0/src/json.cpp
index 2f45cc005a0..d6e5518a1c3 100644
--- a/Build/source/libs/graphite2/graphite2-1.2.4/src/json.cpp
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/json.cpp
@@ -30,6 +30,7 @@ of the License or (at your option) any later version.
#if !defined GRAPHITE2_NTRACING
#include <cstdio>
+#include <limits>
#include "inc/json.h"
using namespace graphite2;
@@ -116,7 +117,20 @@ json & json::operator << (json::string s) throw()
return *this;
}
-json & json::operator << (json::number f) throw() { context(seq); fprintf(_stream, "%g", f); return *this; }
+json & json::operator << (json::number f) throw()
+{
+ context(seq);
+ if (std::numeric_limits<json::number>::infinity() == f)
+ fputs("Infinity", _stream);
+ else if (-std::numeric_limits<json::number>::infinity() == f)
+ fputs("-Infinity", _stream);
+ else if (std::numeric_limits<json::number>::quiet_NaN() == f ||
+ std::numeric_limits<json::number>::signaling_NaN() == f)
+ fputs("NaN", _stream);
+ else
+ fprintf(_stream, "%g", f);
+ return *this;
+}
json & json::operator << (json::integer d) throw() { context(seq); fprintf(_stream, "%ld", d); return *this; }
json & json::operator << (long unsigned d) throw() { context(seq); fprintf(_stream, "%ld", d); return *this; }
json & json::operator << (json::boolean b) throw() { context(seq); fputs(b ? "true" : "false", _stream); return *this; }
diff --git a/Build/source/libs/graphite2/version.ac b/Build/source/libs/graphite2/version.ac
index 5962e99fc3f..60aa9d82050 100644
--- a/Build/source/libs/graphite2/version.ac
+++ b/Build/source/libs/graphite2/version.ac
@@ -1,5 +1,5 @@
dnl
-dnl Copyright (C) 2012, 2013 Peter Breitenlohner <tex-live@tug.org>
+dnl Copyright (C) 2012-2015 Peter Breitenlohner <tex-live@tug.org>
dnl
dnl This file is free software; the copyright holder
dnl gives unlimited permission to copy and/or distribute it,
@@ -8,4 +8,4 @@ dnl
dnl --------------------------------------------------------
dnl
dnl m4-include this file to define the current graphite2 version
-m4_define([graphite2_version], [1.2.4])
+m4_define([graphite2_version], [1.3.0])