summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkira Kakuto <kakuto@fuk.kindai.ac.jp>2016-03-15 09:13:20 +0000
committerAkira Kakuto <kakuto@fuk.kindai.ac.jp>2016-03-15 09:13:20 +0000
commit9b92252d80eba01cd25cc9610ad64908af57ba08 (patch)
tree6b30c240226b3187d7fbf2f098cfc64b8a3fbd7a
parenta47ea6ff25589ac48846a0df205a7a037fe5c5bd (diff)
graphite2 1.3.7
git-svn-id: svn://tug.org/texlive/trunk@40028 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r--Build/source/libs/README2
-rw-r--r--Build/source/libs/graphite2/ChangeLog5
-rwxr-xr-xBuild/source/libs/graphite2/configure20
-rw-r--r--Build/source/libs/graphite2/graphite2-PATCHES/ChangeLog5
-rw-r--r--Build/source/libs/graphite2/graphite2-PATCHES/TL-Changes2
-rw-r--r--Build/source/libs/graphite2/graphite2-src/ChangeLog4
-rw-r--r--Build/source/libs/graphite2/graphite2-src/include/graphite2/Font.h2
-rw-r--r--Build/source/libs/graphite2/graphite2-src/src/CachedFace.cpp4
-rw-r--r--Build/source/libs/graphite2/graphite2-src/src/Code.cpp205
-rw-r--r--Build/source/libs/graphite2/graphite2-src/src/Collider.cpp2
-rw-r--r--Build/source/libs/graphite2/graphite2-src/src/Face.cpp10
-rw-r--r--Build/source/libs/graphite2/graphite2-src/src/GlyphCache.cpp21
-rw-r--r--Build/source/libs/graphite2/graphite2-src/src/GlyphFace.cpp22
-rw-r--r--Build/source/libs/graphite2/graphite2-src/src/NameTable.cpp27
-rw-r--r--Build/source/libs/graphite2/graphite2-src/src/Pass.cpp26
-rw-r--r--Build/source/libs/graphite2/graphite2-src/src/Segment.cpp8
-rw-r--r--Build/source/libs/graphite2/graphite2-src/src/Silf.cpp6
-rw-r--r--Build/source/libs/graphite2/graphite2-src/src/Slot.cpp93
-rw-r--r--Build/source/libs/graphite2/graphite2-src/src/TtfUtil.cpp12
-rw-r--r--Build/source/libs/graphite2/graphite2-src/src/inc/Code.h8
-rw-r--r--Build/source/libs/graphite2/graphite2-src/src/inc/Face.h2
-rw-r--r--Build/source/libs/graphite2/graphite2-src/src/inc/GlyphFace.h2
-rw-r--r--Build/source/libs/graphite2/graphite2-src/src/inc/Rule.h9
-rw-r--r--Build/source/libs/graphite2/graphite2-src/src/inc/Segment.h4
-rw-r--r--Build/source/libs/graphite2/graphite2-src/src/inc/Slot.h5
-rw-r--r--Build/source/libs/graphite2/graphite2-src/src/inc/UtfCodec.h43
-rw-r--r--Build/source/libs/graphite2/graphite2-src/src/inc/opcode_table.h2
-rw-r--r--Build/source/libs/graphite2/graphite2-src/src/inc/opcodes.h7
-rw-r--r--Build/source/libs/graphite2/version.ac2
29 files changed, 326 insertions, 234 deletions
diff --git a/Build/source/libs/README b/Build/source/libs/README
index 0d7d658df0b..b5d9d76457e 100644
--- a/Build/source/libs/README
+++ b/Build/source/libs/README
@@ -21,7 +21,7 @@ gd 2.1.1 - checked 14jan15
gmp 6.1.0 - checked 28dec15
http://ftp.gnu.org/gnu/gmp/
-graphite2 1.3.6 - checked 01mar16
+graphite2 1.3.7 - checked 15mar16
http://sourceforge.net/projects/silgraphite/files/graphite2/
harfbuzz 1.2.3 - checked 25feb16
diff --git a/Build/source/libs/graphite2/ChangeLog b/Build/source/libs/graphite2/ChangeLog
index b6790892f5b..114bc27e066 100644
--- a/Build/source/libs/graphite2/ChangeLog
+++ b/Build/source/libs/graphite2/ChangeLog
@@ -1,3 +1,8 @@
+2016-03-15 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ Import graphite2-1.3.7.
+ * version.ac: Adjusted.
+
2016-03-01 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
Import graphite2-1.3.6.
diff --git a/Build/source/libs/graphite2/configure b/Build/source/libs/graphite2/configure
index 4a2c29c0268..5f54b52840a 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.3.6.
+# Generated by GNU Autoconf 2.69 for graphite2 (TeX Live) 1.3.7.
#
# Report bugs to <tex-k@tug.org>.
#
@@ -579,8 +579,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='graphite2 (TeX Live)'
PACKAGE_TARNAME='graphite2--tex-live-'
-PACKAGE_VERSION='1.3.6'
-PACKAGE_STRING='graphite2 (TeX Live) 1.3.6'
+PACKAGE_VERSION='1.3.7'
+PACKAGE_STRING='graphite2 (TeX Live) 1.3.7'
PACKAGE_BUGREPORT='tex-k@tug.org'
PACKAGE_URL=''
@@ -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.3.6 to adapt to many kinds of systems.
+\`configure' configures graphite2 (TeX Live) 1.3.7 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.3.6:";;
+ short | recursive ) echo "Configuration of graphite2 (TeX Live) 1.3.7:";;
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.3.6
+graphite2 (TeX Live) configure 1.3.7
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.3.6, which was
+It was created by graphite2 (TeX Live) $as_me 1.3.7, 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.3.6'
+ VERSION='1.3.7'
cat >>confdefs.h <<_ACEOF
@@ -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.3.6, which was
+This file was extended by graphite2 (TeX Live) $as_me 1.3.7, 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.3.6
+graphite2 (TeX Live) config.status 1.3.7
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/Build/source/libs/graphite2/graphite2-PATCHES/ChangeLog b/Build/source/libs/graphite2/graphite2-PATCHES/ChangeLog
index baa126ff8e2..8c9a25cb237 100644
--- a/Build/source/libs/graphite2/graphite2-PATCHES/ChangeLog
+++ b/Build/source/libs/graphite2/graphite2-PATCHES/ChangeLog
@@ -1,3 +1,8 @@
+2016-03-15 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ Imported graphite2-1.3.7 source tree from:
+ http://sourceforge.net/projects/silgraphite/files/graphite2/
+
2016-03-01 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
Imported graphite2-1.3.6 source tree from:
diff --git a/Build/source/libs/graphite2/graphite2-PATCHES/TL-Changes b/Build/source/libs/graphite2/graphite2-PATCHES/TL-Changes
index 08fa835e4f2..d67afb870d8 100644
--- a/Build/source/libs/graphite2/graphite2-PATCHES/TL-Changes
+++ b/Build/source/libs/graphite2/graphite2-PATCHES/TL-Changes
@@ -1,4 +1,4 @@
-Changes applied to the graphite2-1.3.6/ tree as obtained from:
+Changes applied to the graphite2-1.3.7/ tree as obtained from:
http://sourceforge.net/projects/silgraphite/files/graphite2/
Removed unused dirs:
diff --git a/Build/source/libs/graphite2/graphite2-src/ChangeLog b/Build/source/libs/graphite2/graphite2-src/ChangeLog
index 522b8101175..e2157225a71 100644
--- a/Build/source/libs/graphite2/graphite2-src/ChangeLog
+++ b/Build/source/libs/graphite2/graphite2-src/ChangeLog
@@ -1,3 +1,7 @@
+1.3.7
+ . Bug fixes
+ . Start to deprecate SegCache. This will be going away in a later release.
+
1.3.6
. Bug fixes
diff --git a/Build/source/libs/graphite2/graphite2-src/include/graphite2/Font.h b/Build/source/libs/graphite2/graphite2-src/include/graphite2/Font.h
index 30b89994e74..866294da9f1 100644
--- a/Build/source/libs/graphite2/graphite2-src/include/graphite2/Font.h
+++ b/Build/source/libs/graphite2/graphite2-src/include/graphite2/Font.h
@@ -30,7 +30,7 @@
#define GR2_VERSION_MAJOR 1
#define GR2_VERSION_MINOR 3
-#define GR2_VERSION_BUGFIX 6
+#define GR2_VERSION_BUGFIX 7
#ifdef __cplusplus
extern "C"
diff --git a/Build/source/libs/graphite2/graphite2-src/src/CachedFace.cpp b/Build/source/libs/graphite2/graphite2-src/src/CachedFace.cpp
index fd599bde8aa..71cd5ca452c 100644
--- a/Build/source/libs/graphite2/graphite2-src/src/CachedFace.cpp
+++ b/Build/source/libs/graphite2/graphite2-src/src/CachedFace.cpp
@@ -69,10 +69,10 @@ bool CachedFace::runGraphite(Segment *seg, const Silf *pSilf) const
Slot * subSegEndSlot = subSegStartSlot;
uint16 cmapGlyphs[eMaxSpliceSize];
int subSegStart = 0;
- for (unsigned int i = 0; i < seg->charInfoCount(); ++i)
+ for (unsigned int i = 0; i < seg->charInfoCount() && subSegEndSlot; ++i)
{
const unsigned int length = i - subSegStart + 1;
- if (length < eMaxSpliceSize)
+ if (length < eMaxSpliceSize && subSegEndSlot->gid() < m_cacheStore->maxCmapGid())
cmapGlyphs[length-1] = subSegEndSlot->gid();
else return false;
const bool spaceOnly = m_cacheStore->isSpaceGlyph(subSegEndSlot->gid());
diff --git a/Build/source/libs/graphite2/graphite2-src/src/Code.cpp b/Build/source/libs/graphite2/graphite2-src/src/Code.cpp
index aa7959708da..247a0529cfa 100644
--- a/Build/source/libs/graphite2/graphite2-src/src/Code.cpp
+++ b/Build/source/libs/graphite2/graphite2-src/src/Code.cpp
@@ -66,11 +66,10 @@ inline bool is_return(const instr i) {
struct context
{
- context(uint8 ref=0) : codeRef(ref) {flags.changed=false; flags.referenced=false; flags.inserted=false;}
+ context(uint8 ref=0) : codeRef(ref) {flags.changed=false; flags.referenced=false;}
struct {
uint8 changed:1,
- referenced:1,
- inserted:1;
+ referenced:1;
} flags;
uint8 codeRef;
};
@@ -82,46 +81,40 @@ class Machine::Code::decoder
{
public:
struct limits;
- struct analysis
- {
- static const int NUMCONTEXTS = 256;
- uint8 slotref;
- context contexts[NUMCONTEXTS];
- byte max_ref;
-
- analysis() : slotref(0), max_ref(0) {};
- void set_ref(int index, bool incinsert=false) throw();
- void set_noref(int index) throw();
- void set_changed(int index) throw();
-
- };
+ static const int NUMCONTEXTS = 256;
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);
- byte max_ref() { return _analysis.max_ref; }
- int pre_context() const { return _pre_context; }
+ byte max_ref() { return _max_ref; }
+ int out_index() const { return _out_index; }
private:
+ void set_ref(int index) throw();
+ void set_noref(int index) throw();
+ void set_changed(int index) throw();
opcode fetch_opcode(const byte * bc);
void analyse_opcode(const opcode, const int8 * const dp) throw();
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();
+ bool test_ref(int8 index) const throw();
void failure(const status_t s) const throw() { _code.failure(s); }
Code & _code;
- int _pre_context;
- uint16 _rule_length;
+ int _out_index;
+ uint16 _out_length;
instr * _instr;
byte * _data;
limits & _max;
- analysis _analysis;
enum passtype _passtype;
int _stack_depth;
bool _in_ctxt_item;
+ int16 _slotref;
+ context _contexts[NUMCONTEXTS];
+ byte _max_ref;
};
@@ -138,11 +131,13 @@ struct Machine::Code::decoder::limits
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),
+ _out_index(code._constraint ? 0 : lims.pre_context),
+ _out_length(code._constraint ? 1 : lims.rule_length),
_instr(code._code), _data(code._data), _max(lims), _passtype(pt),
_stack_depth(0),
- _in_ctxt_item(false)
+ _in_ctxt_item(false),
+ _slotref(0),
+ _max_ref(0)
{ }
@@ -168,7 +163,7 @@ Machine::Code::Code(bool is_constraint, const byte * bytecode_begin, const byte
// Allocate code and data target buffers, these sizes are a worst case
// estimate. Once we know their real sizes the we'll shrink them.
if (_out) _code = reinterpret_cast<instr *>(*_out);
- else _code = static_cast<instr *>(malloc(estimateCodeDataOut(bytecode_end-bytecode_begin)));
+ else _code = static_cast<instr *>(malloc(estimateCodeDataOut(bytecode_end-bytecode_begin, 1, is_constraint ? 0 : rule_length)));
_data = reinterpret_cast<byte *>(_code + (bytecode_end - bytecode_begin));
if (!_code || !_data) {
@@ -324,37 +319,47 @@ opcode Machine::Code::decoder::fetch_opcode(const byte * bc)
case NEXT :
case NEXT_N : // runtime checked
case COPY_NEXT :
- test_context();
- ++_pre_context;
+ ++_out_index;
+ if (_out_index < -1 || _out_index > _out_length || _slotref > _max.rule_length)
+ failure(out_of_range_data);
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]));
+ test_ref(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_ref(int8(bc[0]));
test_context();
break;
case INSERT :
if (_passtype >= PASS_TYPE_POSITIONING)
failure(invalid_opcode);
- else
- --_pre_context;
+ ++_out_length;
+ if (_out_index < 0) ++_out_index;
+ if (_out_index < -1 || _out_index >= _out_length)
+ failure(out_of_range_data);
break;
case DELETE :
if (_passtype >= PASS_TYPE_POSITIONING)
failure(invalid_opcode);
- test_context();
+ if (_out_index < _max.pre_context)
+ failure(out_of_range_data);
+ --_out_index;
+ --_out_length;
+ if (_out_index < -1 || _out_index > _out_length)
+ failure(out_of_range_data);
break;
case ASSOC :
+ if (bc[0] == 0)
+ failure(out_of_range_data);
for (uint8 num = bc[0]; num; --num)
- valid_upto(_rule_length, _pre_context + int8(bc[num]));
+ test_ref(int8(bc[num]));
test_context();
break;
case CNTXT_ITEM :
@@ -383,42 +388,33 @@ opcode Machine::Code::decoder::fetch_opcode(const byte * bc)
case PUSH_SLOT_ATTR :
++_stack_depth;
valid_upto(gr_slatMax, bc[0]);
- valid_upto(_rule_length, _pre_context + int8(bc[1]));
+ test_ref(int8(bc[1]));
if (attrCode(bc[0]) == gr_slatUserDefn) // use IATTR for user attributes
failure(out_of_range_data);
break;
case PUSH_GLYPH_ATTR_OBS :
+ case PUSH_ATT_TO_GATTR_OBS :
++_stack_depth;
valid_upto(_max.glyf_attrs, bc[0]);
- valid_upto(_rule_length, _pre_context + int8(bc[1]));
+ test_ref(int8(bc[1]));
break;
+ case PUSH_ATT_TO_GLYPH_METRIC :
case PUSH_GLYPH_METRIC :
++_stack_depth;
valid_upto(kgmetDescent, bc[0]);
- valid_upto(_rule_length, _pre_context + int8(bc[1]));
+ test_ref(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
+ test_ref(int8(bc[1]));
break;
case PUSH_ISLOT_ATTR :
++_stack_depth;
if (valid_upto(gr_slatMax, bc[0]))
{
- valid_upto(_rule_length, _pre_context + int8(bc[1]));
+ test_ref(int8(bc[1]));
valid_upto(_max.attrid[bc[0]], bc[2]);
}
break;
@@ -447,7 +443,7 @@ opcode Machine::Code::decoder::fetch_opcode(const byte * bc)
++_stack_depth;
break;
case PUT_SUBS :
- valid_upto(_rule_length, _pre_context + int8(bc[0]));
+ test_ref(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();
@@ -463,7 +459,11 @@ opcode Machine::Code::decoder::fetch_opcode(const byte * bc)
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]));
+ test_ref(int8(bc[2]));
+ break;
+ case SET_FEAT :
+ valid_upto(_max.features, bc[0]);
+ test_ref(int8(bc[1]));
break;
default:
failure(invalid_opcode);
@@ -476,79 +476,64 @@ opcode Machine::Code::decoder::fetch_opcode(const byte * bc)
void Machine::Code::decoder::analyse_opcode(const opcode opc, const int8 * arg) throw()
{
- if (_code._constraint) return;
-
switch (opc)
{
case DELETE :
_code._delete = true;
break;
+ case ASSOC :
+ set_changed(0);
+// for (uint8 num = arg[0]; num; --num)
+// _analysis.set_noref(num);
+ break;
case PUT_GLYPH_8BIT_OBS :
case PUT_GLYPH :
_code._modify = true;
- _analysis.set_changed(0);
+ set_changed(0);
break;
case ATTR_SET :
case ATTR_ADD :
+ case ATTR_SUB :
case ATTR_SET_SLOT :
case IATTR_SET_SLOT :
case IATTR_SET :
case IATTR_ADD :
case IATTR_SUB :
- _analysis.set_noref(0);
+ set_noref(0);
break;
case NEXT :
case COPY_NEXT :
- if (!_analysis.contexts[_analysis.slotref].flags.inserted)
- ++_analysis.slotref;
- _analysis.contexts[_analysis.slotref] = context(_code._instr_count+1);
+ ++_slotref;
+ _contexts[_slotref] = context(_code._instr_count+1);
// if (_analysis.slotref > _analysis.max_ref) _analysis.max_ref = _analysis.slotref;
break;
case INSERT :
- _analysis.contexts[_analysis.slotref].flags.inserted = true;
+ if (_slotref >= 0) --_slotref;
_code._modify = true;
break;
case PUT_SUBS_8BIT_OBS : // slotref on 1st parameter
case PUT_SUBS :
_code._modify = true;
- _analysis.set_changed(0);
+ set_changed(0);
GR_FALLTHROUGH;
// no break
case PUT_COPY :
- {
- if (arg[0] != 0) { _analysis.set_changed(0); _code._modify = true; }
- if (arg[0] <= 0 && -arg[0] <= _analysis.slotref - _analysis.contexts[_analysis.slotref].flags.inserted)
- _analysis.set_ref(arg[0], true);
- else if (arg[0] > 0)
- _analysis.set_ref(arg[0], true);
+ if (arg[0] != 0) { set_changed(0); _code._modify = true; }
+ set_ref(arg[0]);
break;
- }
- case PUSH_ATT_TO_GATTR_OBS : // slotref on 2nd parameter
- if (_code._constraint) return;
- GR_FALLTHROUGH;
- // no break
case PUSH_GLYPH_ATTR_OBS :
case PUSH_SLOT_ATTR :
case PUSH_GLYPH_METRIC :
+ case PUSH_ATT_TO_GATTR_OBS :
case PUSH_ATT_TO_GLYPH_METRIC :
case PUSH_ISLOT_ATTR :
case PUSH_FEAT :
- if (arg[1] <= 0 && -arg[1] <= _analysis.slotref - _analysis.contexts[_analysis.slotref].flags.inserted)
- _analysis.set_ref(arg[1], true);
- else if (arg[1] > 0)
- _analysis.set_ref(arg[1], true);
+ case SET_FEAT :
+ set_ref(arg[1]);
break;
case PUSH_ATT_TO_GLYPH_ATTR :
- if (_code._constraint) return;
- GR_FALLTHROUGH;
- // no break
case PUSH_GLYPH_ATTR :
- if (arg[2] <= 0 && -arg[2] <= _analysis.slotref - _analysis.contexts[_analysis.slotref].flags.inserted)
- _analysis.set_ref(arg[2], true);
- else if (arg[2] > 0)
- _analysis.set_ref(arg[2], true);
- break;
- case ASSOC : // slotrefs in varargs
+ set_ref(arg[2]);
break;
default:
break;
@@ -584,10 +569,10 @@ bool Machine::Code::decoder::emit_opcode(opcode opc, const byte * & bc)
// instruction and data portions.
if (opc == CNTXT_ITEM)
{
- assert(_pre_context == 0);
+ assert(_out_index == 0);
_in_ctxt_item = true;
- _pre_context = _max.pre_context + int8(_data[-2]);
- _rule_length = _max.rule_length;
+ _out_index = _max.pre_context + int8(_data[-2]);
+ _out_length = _max.rule_length;
const size_t ctxt_start = _code._instr_count;
byte & instr_skip = _data[-1];
@@ -602,13 +587,13 @@ bool Machine::Code::decoder::emit_opcode(opcode opc, const byte * & bc)
instr_skip = _code._instr_count - ctxt_start;
_max.bytecode = curr_end;
- _rule_length = 1;
- _pre_context = 0;
+ _out_length = 1;
+ _out_index = 0;
_in_ctxt_item = false;
}
else
{
- _pre_context = 0;
+ _out_index = 0;
return false;
}
}
@@ -624,7 +609,7 @@ void Machine::Code::decoder::apply_analysis(instr * const code, instr * code_end
if (_code._constraint) return;
const instr temp_copy = Machine::getOpcodeTable()[TEMP_COPY].impl[0];
- for (const context * c = _analysis.contexts, * const ce = c + _analysis.slotref; c != ce; ++c)
+ for (const context * c = _contexts, * const ce = c + _slotref; c < ce; ++c)
{
if (!c->flags.referenced || !c->flags.changed) continue;
@@ -649,6 +634,11 @@ bool Machine::Code::decoder::validate_opcode(const opcode opc, const byte * cons
return false;
}
const opcode_t & op = Machine::getOpcodeTable()[opc];
+ if (op.impl[_code._constraint] == 0)
+ {
+ failure(unimplemented_opcode_used);
+ return false;
+ }
if (op.param_sz == VARARGS && bc >= _max.bytecode)
{
failure(arguments_exhausted);
@@ -671,9 +661,15 @@ bool Machine::Code::decoder::valid_upto(const uint16 limit, const uint16 x) cons
return t;
}
+inline
+bool Machine::Code::decoder::test_ref(int8 index) const throw()
+{
+ return valid_upto(_max.rule_length, _slotref + _max.pre_context + index);
+}
+
bool Machine::Code::decoder::test_context() const throw()
{
- if (_pre_context >= _rule_length || _analysis.slotref >= analysis::NUMCONTEXTS - 1)
+ if (_out_index >= _out_length || _out_index < 0 || _slotref >= NUMCONTEXTS - 1)
{
failure(out_of_range_data);
return false;
@@ -689,28 +685,25 @@ void Machine::Code::failure(const status_t s) throw() {
inline
-void Machine::Code::decoder::analysis::set_ref(int index, bool incinsert) throw() {
- if (incinsert && contexts[slotref].flags.inserted) --index;
- if (index + slotref < 0 || index + slotref >= NUMCONTEXTS) return;
- contexts[index + slotref].flags.referenced = true;
- if ((index > 0 || !contexts[index + slotref].flags.inserted) && index + slotref > max_ref) max_ref = index + slotref;
+void Machine::Code::decoder::set_ref(int index) throw() {
+ if (index + _slotref < 0 || index + _slotref >= NUMCONTEXTS) return;
+ _contexts[index + _slotref].flags.referenced = true;
+ if (index + _slotref > _max_ref) _max_ref = index + _slotref;
}
inline
-void Machine::Code::decoder::analysis::set_noref(int index) throw() {
- if (contexts[slotref].flags.inserted) --index;
- if (index + slotref < 0 || index + slotref >= NUMCONTEXTS) return;
- if ((index > 0 || !contexts[index + slotref].flags.inserted) && index + slotref > max_ref) max_ref = index + slotref;
+void Machine::Code::decoder::set_noref(int index) throw() {
+ if (index + _slotref < 0 || index + _slotref >= NUMCONTEXTS) return;
+ if (index + _slotref > _max_ref) _max_ref = index + _slotref;
}
inline
-void Machine::Code::decoder::analysis::set_changed(int index) throw() {
- if (contexts[slotref].flags.inserted) --index;
- if (index + slotref < 0 || index + slotref >= NUMCONTEXTS) return;
- contexts[index + slotref].flags.changed = true;
- if ((index > 0 || !contexts[index + slotref].flags.inserted) && index + slotref > max_ref) max_ref = index + slotref;
+void Machine::Code::decoder::set_changed(int index) throw() {
+ if (index + _slotref < 0 || index + _slotref >= NUMCONTEXTS) return;
+ _contexts[index + _slotref].flags.changed= true;
+ if (index + _slotref > _max_ref) _max_ref = index + _slotref;
}
diff --git a/Build/source/libs/graphite2/graphite2-src/src/Collider.cpp b/Build/source/libs/graphite2/graphite2-src/src/Collider.cpp
index 87f067d3f7c..591b01ebe90 100644
--- a/Build/source/libs/graphite2/graphite2-src/src/Collider.cpp
+++ b/Build/source/libs/graphite2/graphite2-src/src/Collider.cpp
@@ -26,7 +26,7 @@ of the License or (at your option) any later version.
*/
#include <algorithm>
#include <limits>
-#include <math.h>
+#include <cmath>
#include <string>
#include <functional>
#include "inc/Collider.h"
diff --git a/Build/source/libs/graphite2/graphite2-src/src/Face.cpp b/Build/source/libs/graphite2/graphite2-src/src/Face.cpp
index e9b1b1c177c..1ab7a60f490 100644
--- a/Build/source/libs/graphite2/graphite2-src/src/Face.cpp
+++ b/Build/source/libs/graphite2/graphite2-src/src/Face.cpp
@@ -183,7 +183,8 @@ bool Face::runGraphite(Segment *seg, const Silf *aSilf) const
seg->associateChars(0, seg->charInfoCount());
if (aSilf->flags() & 0x20)
res &= seg->initCollisions();
- res &= aSilf->runGraphite(seg, aSilf->positionPass(), aSilf->numPasses(), false);
+ if (res)
+ res &= aSilf->runGraphite(seg, aSilf->positionPass(), aSilf->numPasses(), false);
}
#if !defined GRAPHITE2_NTRACING
@@ -231,7 +232,7 @@ uint16 Face::findPseudo(uint32 uid) const
return (m_numSilf) ? m_silfs[0].findPseudo(uid) : 0;
}
-uint16 Face::getGlyphMetric(uint16 gid, uint8 metric) const
+int32 Face::getGlyphMetric(uint16 gid, uint8 metric) const
{
switch (metrics(metric))
{
@@ -282,7 +283,7 @@ Face::Table::Table(const Face & face, const Tag n, uint32 version) throw()
if (!TtfUtil::CheckTable(n, _p, _sz))
{
- this->~Table(); // Make sure we release the table buffer even if the table filed it's checks
+ releaseBuffers(); // Make sure we release the table buffer even if the table failed it's checks
return;
}
@@ -329,7 +330,8 @@ Error Face::Table::decompress()
{
uncompressed_size = hdr & 0x07ffffff;
uncompressed_table = gralloc<byte>(uncompressed_size);
- if (!e.test(!uncompressed_table, E_OUTOFMEM))
+ if (!e.test(!uncompressed_table || uncompressed_size < 4, E_OUTOFMEM))
+ memset(uncompressed_table, 0, 4); // make sure version number is initialised
// coverity[forward_null : FALSE] - uncompressed_table has been checked so can't be null
// coverity[checked_return : FALSE] - we test e later
e.test(lz4::decompress(p, _sz - 2*sizeof(uint32), uncompressed_table, uncompressed_size) != signed(uncompressed_size), E_SHRINKERFAILED);
diff --git a/Build/source/libs/graphite2/graphite2-src/src/GlyphCache.cpp b/Build/source/libs/graphite2/graphite2-src/src/GlyphCache.cpp
index 8792f9700b3..ae9035d1d4b 100644
--- a/Build/source/libs/graphite2/graphite2-src/src/GlyphCache.cpp
+++ b/Build/source/libs/graphite2/graphite2-src/src/GlyphCache.cpp
@@ -116,8 +116,10 @@ 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),
+ _glyphs(_glyph_loader && *_glyph_loader && _glyph_loader->num_glyphs()
+ ? grzeroalloc<const GlyphFace *>(_glyph_loader->num_glyphs()) : 0),
+ _boxes(_glyph_loader && _glyph_loader->has_boxes() && _glyph_loader->num_glyphs()
+ ? 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)
@@ -144,7 +146,7 @@ GlyphCache::GlyphCache(const Face & face, const uint32 face_options)
_glyphs[0] = 0;
delete [] glyphs;
}
- else if (numsubs > 0)
+ else if (numsubs > 0 && _boxes)
{
GlyphBox * boxes = (GlyphBox *)gralloc<char>(_num_glyphs * sizeof(GlyphBox) + numsubs * 8 * sizeof(float));
GlyphBox * currbox = boxes;
@@ -285,7 +287,8 @@ GlyphCache::Loader::Loader(const Face & face, const bool dumb_font)
if (version >= 0x00020000 || tmpnumgattrs < 0 || tmpnumgattrs > 65535
|| _num_attrs == 0 || _num_attrs > 0x3000 // is this hard limit appropriate?
- || _num_glyphs_graphics > tmpnumgattrs)
+ || _num_glyphs_graphics > tmpnumgattrs
+ || m_pGlat.size() < 4)
{
_head = Face::Table();
return;
@@ -294,7 +297,7 @@ GlyphCache::Loader::Loader(const Face & face, const bool dumb_font)
_num_glyphs_attributes = static_cast<unsigned short>(tmpnumgattrs);
p = m_pGlat;
version = be::read<uint32>(p);
- if (version >= 0x00040000) // reject Glat tables that are too new
+ if (version >= 0x00040000 || (version >= 0x00030000 && m_pGlat.size() < 8)) // reject Glat tables that are too new
{
_head = Face::Table();
return;
@@ -386,11 +389,11 @@ const GlyphFace * GlyphCache::Loader::read_glyph(unsigned short glyphid, GlyphFa
gloce = be::peek<uint16>(gloc);
}
- if (glocs >= m_pGlat.size() || gloce > m_pGlat.size())
+ if (glocs + 1 >= m_pGlat.size() || gloce > m_pGlat.size())
return 0;
const uint32 glat_version = be::peek<uint32>(m_pGlat);
- if (glat_version == 0x00030000)
+ if (glat_version >= 0x00030000)
{
const byte * p = m_pGlat + glocs;
uint16 bmap = be::read<uint16>(p);
@@ -454,7 +457,7 @@ GlyphBox * GlyphCache::Loader::read_box(uint16 gid, GlyphBox *curr, const GlyphF
gloce = be::peek<uint16>(gloc);
}
- if (glocs >= m_pGlat.size() || gloce > m_pGlat.size())
+ if (gloce > m_pGlat.size() || glocs + 6 >= gloce)
return 0;
const byte * p = m_pGlat + glocs;
@@ -467,6 +470,8 @@ GlyphBox * GlyphCache::Loader::read_box(uint16 gid, GlyphBox *curr, const GlyphF
Rect diabound = readbox(diamax, p[0], p[2], p[1], p[3]);
::new (curr) GlyphBox(num, bmap, &diabound);
be::skip<uint8>(p, 4);
+ if (glocs + 6 + num * 8 >= gloce)
+ return 0;
for (int i = 0; i < num * 2; ++i)
{
diff --git a/Build/source/libs/graphite2/graphite2-src/src/GlyphFace.cpp b/Build/source/libs/graphite2/graphite2-src/src/GlyphFace.cpp
index 9fc11b2157e..ce17e42bd47 100644
--- a/Build/source/libs/graphite2/graphite2-src/src/GlyphFace.cpp
+++ b/Build/source/libs/graphite2/graphite2-src/src/GlyphFace.cpp
@@ -29,20 +29,20 @@ of the License or (at your option) any later version.
using namespace graphite2;
-uint16 GlyphFace::getMetric(uint8 metric) const
+int32 GlyphFace::getMetric(uint8 metric) const
{
switch (metrics(metric))
{
- case kgmetLsb : return static_cast<uint16>(m_bbox.bl.x);
- case kgmetRsb : return static_cast<uint16>(m_advance.x - m_bbox.tr.x);
- case kgmetBbTop : return static_cast<uint16>(m_bbox.tr.y);
- case kgmetBbBottom : return static_cast<uint16>(m_bbox.bl.y);
- case kgmetBbLeft : return static_cast<uint16>(m_bbox.bl.x);
- case kgmetBbRight : return static_cast<uint16>(m_bbox.tr.x);
- case kgmetBbHeight : return static_cast<uint16>(m_bbox.tr.y - m_bbox.bl.y);
- case kgmetBbWidth : return static_cast<uint16>(m_bbox.tr.x - m_bbox.bl.x);
- case kgmetAdvWidth : return static_cast<uint16>(m_advance.x);
- case kgmetAdvHeight : return static_cast<uint16>(m_advance.y);
+ case kgmetLsb : return m_bbox.bl.x;
+ case kgmetRsb : return m_advance.x - m_bbox.tr.x;
+ case kgmetBbTop : return m_bbox.tr.y;
+ case kgmetBbBottom : return m_bbox.bl.y;
+ case kgmetBbLeft : return m_bbox.bl.x;
+ case kgmetBbRight : return m_bbox.tr.x;
+ case kgmetBbHeight : return m_bbox.tr.y - m_bbox.bl.y;
+ case kgmetBbWidth : return m_bbox.tr.x - m_bbox.bl.x;
+ case kgmetAdvWidth : return m_advance.x;
+ case kgmetAdvHeight : return m_advance.y;
default : return 0;
}
}
diff --git a/Build/source/libs/graphite2/graphite2-src/src/NameTable.cpp b/Build/source/libs/graphite2/graphite2-src/src/NameTable.cpp
index f83adb09cd8..2baa1bbdc52 100644
--- a/Build/source/libs/graphite2/graphite2-src/src/NameTable.cpp
+++ b/Build/source/libs/graphite2/graphite2-src/src/NameTable.cpp
@@ -47,15 +47,16 @@ NameTable::NameTable(const void* data, size_t length, uint16 platformId, uint16
sizeof(TtfUtil::Sfnt::NameRecord) * ( be::swap<uint16>(m_table->count) - 1)))
{
uint16 offset = be::swap<uint16>(m_table->string_offset);
- m_nameData = reinterpret_cast<const uint8*>(pdata) + offset;
- setPlatformEncoding(platformId, encodingID);
- m_nameDataLength = length - offset;
- }
- else
- {
- free(const_cast<TtfUtil::Sfnt::FontNames*>(m_table));
- m_table = NULL;
+ if (offset < length)
+ {
+ m_nameData = reinterpret_cast<const uint8*>(pdata) + offset;
+ setPlatformEncoding(platformId, encodingID);
+ m_nameDataLength = length - offset;
+ return;
+ }
}
+ free(const_cast<TtfUtil::Sfnt::FontNames*>(m_table));
+ m_table = NULL;
}
uint16 NameTable::setPlatformEncoding(uint16 platformId, uint16 encodingID)
@@ -144,7 +145,7 @@ void* NameTable::getName(uint16& languageId, uint16 nameId, gr_encform enc, uint
return NULL;
}
utf16Length >>= 1; // in utf16 units
- utf16::codeunit_t * utf16Name = gralloc<utf16::codeunit_t>(utf16Length);
+ utf16::codeunit_t * utf16Name = gralloc<utf16::codeunit_t>(utf16Length + 1);
if (!utf16Name)
{
languageId = 0;
@@ -156,6 +157,14 @@ void* NameTable::getName(uint16& languageId, uint16 nameId, gr_encform enc, uint
{
utf16Name[i] = be::read<uint16>(pName);
}
+ utf16Name[utf16Length] = 0;
+ if (!utf16::validate(utf16Name, utf16Name + utf16Length))
+ {
+ free(utf16Name);
+ languageId = 0;
+ length = 0;
+ return NULL;
+ }
switch (enc)
{
case gr_utf8:
diff --git a/Build/source/libs/graphite2/graphite2-src/src/Pass.cpp b/Build/source/libs/graphite2/graphite2-src/src/Pass.cpp
index fcf0384a60c..6f6b91331f5 100644
--- a/Build/source/libs/graphite2/graphite2-src/src/Pass.cpp
+++ b/Build/source/libs/graphite2/graphite2-src/src/Pass.cpp
@@ -101,7 +101,7 @@ bool Pass::readPass(const byte * const pass_start, size_t pass_length, size_t su
// Read in basic values
const byte flags = be::read<byte>(p);
if (e.test((flags & 0x1f) &&
- (pt < PASS_TYPE_POSITIONING || !m_silf->aCollision() || !face.glyphs().hasBoxes()),
+ (pt < PASS_TYPE_POSITIONING || !m_silf->aCollision() || !face.glyphs().hasBoxes() || !(m_silf->flags() & 0x20)),
E_BADCOLLISIONPASS))
return face.error(e);
m_numCollRuns = flags & 0x7;
@@ -231,7 +231,11 @@ bool Pass::readRules(const byte * rule_map, const size_t num_entries,
// Allocate pools
m_rules = new Rule [m_numRules];
m_codes = new Code [m_numRules*2];
- const size_t prog_pool_sz = vm::Machine::Code::estimateCodeDataOut(ac_end - ac_data + rc_end - rc_data);
+ int totalSlots = 0;
+ const uint16 *tsort = sort_key;
+ for (int i = 0; i < m_numRules; ++i)
+ totalSlots += be::peek<uint16>(--tsort);
+ const size_t prog_pool_sz = vm::Machine::Code::estimateCodeDataOut(ac_end - ac_data + rc_end - rc_data, 2 * m_numRules, totalSlots);
m_progs = gralloc<byte>(prog_pool_sz);
byte * prog_pool_free = m_progs,
* prog_pool_end = m_progs + prog_pool_sz;
@@ -254,7 +258,7 @@ 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
- || vm::Machine::Code::estimateCodeDataOut(ac_end - ac_begin + rc_end - rc_begin) > size_t(prog_pool_end - prog_pool_free))
+ || vm::Machine::Code::estimateCodeDataOut(ac_end - ac_begin + rc_end - rc_begin, 2, r->sort) > size_t(prog_pool_end - prog_pool_free))
return false;
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);
@@ -356,7 +360,8 @@ bool Pass::readStates(const byte * starts, const byte *states, const byte * o_ru
s->rules = begin;
s->rules_end = (end - begin <= FiniteStateMachine::MAX_RULES)? end :
begin + FiniteStateMachine::MAX_RULES;
- qsort(begin, end - begin, sizeof(RuleEntry), &cmpRuleEntry);
+ if (begin) // keep UBSan happy can't call qsort with null begin
+ qsort(begin, end - begin, sizeof(RuleEntry), &cmpRuleEntry);
}
return true;
@@ -454,9 +459,9 @@ bool Pass::runFSM(FiniteStateMachine& fsm, Slot * slot) const
do
{
fsm.slots.pushSlot(slot);
- if (--free_slots == 0
- || slot->gid() >= m_numGlyphs
+ if (slot->gid() >= m_numGlyphs
|| m_cols[slot->gid()] == 0xffffU
+ || --free_slots == 0
|| state >= m_numTransition)
return free_slots != 0;
@@ -632,10 +637,13 @@ bool Pass::testConstraint(const Rule & r, Machine & m) const
const uint16 curr_context = m.slotMap().context();
if (unsigned(r.sort - r.preContext) > m.slotMap().size() - curr_context
|| curr_context - r.preContext < 0) return false;
- if (!*r.constraint) return true;
- assert(r.constraint->constraint());
vm::slotref * map = m.slotMap().begin() + curr_context - r.preContext;
+ if (map[r.sort - 1] == 0)
+ return false;
+
+ if (!*r.constraint) return true;
+ assert(r.constraint->constraint());
for (int n = r.sort; n && map; --n, ++map)
{
if (!*map) continue;
@@ -652,7 +660,7 @@ void SlotMap::collectGarbage(Slot * &aSlot)
{
for(Slot **s = begin(), *const *const se = end() - 1; s != se; ++s) {
Slot *& slot = *s;
- if(slot->isDeleted() || slot->isCopied())
+ if(slot && (slot->isDeleted() || slot->isCopied()))
{
if (slot == aSlot)
aSlot = slot->prev() ? slot->prev() : slot->next();
diff --git a/Build/source/libs/graphite2/graphite2-src/src/Segment.cpp b/Build/source/libs/graphite2/graphite2-src/src/Segment.cpp
index ecc35f50aa0..966f75784dd 100644
--- a/Build/source/libs/graphite2/graphite2-src/src/Segment.cpp
+++ b/Build/source/libs/graphite2/graphite2-src/src/Segment.cpp
@@ -424,6 +424,9 @@ Position Segment::positionSlots(const Font *font, Slot * iStart, Slot * iEnd, bo
if (!iStart) iStart = m_first;
if (!iEnd) iEnd = m_last;
+ if (!iStart || !iEnd) // only true for empty segments
+ return currpos;
+
if (isRtl)
{
for (Slot * s = iEnd, * const end = iStart->prev(); s && s != end; s = s->prev())
@@ -531,6 +534,9 @@ bool Segment::initCollisions()
if (!m_collisions) return false;
for (Slot *p = m_first; p; p = p->next())
- ::new (collisionInfo(p)) SlotCollision(this, p);
+ if (p->index() < slotCount())
+ ::new (collisionInfo(p)) SlotCollision(this, p);
+ else
+ return false;
return true;
}
diff --git a/Build/source/libs/graphite2/graphite2-src/src/Silf.cpp b/Build/source/libs/graphite2/graphite2-src/src/Silf.cpp
index adfad4029a0..02876881e6f 100644
--- a/Build/source/libs/graphite2/graphite2-src/src/Silf.cpp
+++ b/Build/source/libs/graphite2/graphite2-src/src/Silf.cpp
@@ -355,10 +355,10 @@ uint16 Silf::getClassGlyph(uint16 cid, unsigned int index) const
bool Silf::runGraphite(Segment *seg, uint8 firstPass, uint8 lastPass, int dobidi) const
{
assert(seg != 0);
- SlotMap map(*seg, m_dir);
+ unsigned int maxSize = seg->slotCount() * MAX_SEG_GROWTH_FACTOR;
+ SlotMap map(*seg, m_dir, maxSize);
FiniteStateMachine fsm(map, seg->getFace()->logger());
vm::Machine m(map);
- unsigned int initSize = seg->slotCount();
uint8 lbidi = m_bPass;
#if !defined GRAPHITE2_NTRACING
json * const dbgout = seg->getFace()->logger();
@@ -424,7 +424,7 @@ bool Silf::runGraphite(Segment *seg, uint8 firstPass, uint8 lastPass, int dobidi
return false;
// only subsitution passes can change segment length, cached subsegments are short for their text
if (m.status() != vm::Machine::finished
- || (seg->slotCount() && seg->slotCount() * MAX_SEG_GROWTH_FACTOR < initSize))
+ || (seg->slotCount() && seg->slotCount() > maxSize))
return false;
}
return true;
diff --git a/Build/source/libs/graphite2/graphite2-src/src/Slot.cpp b/Build/source/libs/graphite2/graphite2-src/src/Slot.cpp
index 3330c8131fb..4227327c4b3 100644
--- a/Build/source/libs/graphite2/graphite2-src/src/Slot.cpp
+++ b/Build/source/libs/graphite2/graphite2-src/src/Slot.cpp
@@ -85,10 +85,10 @@ 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, bool rtl, bool isFinal)
+Position Slot::finalise(const Segment *seg, const Font *font, Position & base, Rect & bbox, uint8 attrLevel, float & clusterMin, bool rtl, bool isFinal, int depth)
{
SlotCollision *coll = NULL;
- if (attrLevel && m_attLevel > attrLevel) return Position(0, 0);
+ if (depth > 100 || (attrLevel && m_attLevel > attrLevel)) return Position(0, 0);
float scale = font ? font->scale() : 1.0f;
Position shift(m_shift.x * (rtl * -2 + 1) + m_just, m_shift.y);
float tAdvance = m_advance.x + m_just;
@@ -133,13 +133,13 @@ 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, rtl, isFinal);
+ Position tRes = m_child->finalise(seg, font, m_position, bbox, attrLevel, clusterMin, rtl, isFinal, depth + 1);
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, rtl, isFinal);
+ Position tRes = m_sibling->finalise(seg, font, base, bbox, attrLevel, clusterMin, rtl, isFinal, depth + 1);
if (tRes.x > res.x) res = tRes;
}
@@ -165,25 +165,25 @@ int32 Slot::clusterMetric(const Segment *seg, uint8 metric, uint8 attrLevel, boo
switch (metrics(metric))
{
case kgmetLsb :
- return static_cast<uint32>(bbox.bl.x);
+ return bbox.bl.x;
case kgmetRsb :
- return static_cast<uint32>(res.x - bbox.tr.x);
+ return res.x - bbox.tr.x;
case kgmetBbTop :
- return static_cast<uint32>(bbox.tr.y);
+ return bbox.tr.y;
case kgmetBbBottom :
- return static_cast<uint32>(bbox.bl.y);
+ return bbox.bl.y;
case kgmetBbLeft :
- return static_cast<uint32>(bbox.bl.x);
+ return bbox.bl.x;
case kgmetBbRight :
- return static_cast<uint32>(bbox.tr.x);
+ return bbox.tr.x;
case kgmetBbWidth :
- return static_cast<uint32>(bbox.tr.x - bbox.bl.x);
+ return bbox.tr.x - bbox.bl.x;
case kgmetBbHeight :
- return static_cast<uint32>(bbox.tr.y - bbox.bl.y);
+ return bbox.tr.y - bbox.bl.y;
case kgmetAdvWidth :
- return static_cast<uint32>(res.x);
+ return res.x;
case kgmetAdvHeight :
- return static_cast<uint32>(res.y);
+ return res.y;
default :
return 0;
}
@@ -295,9 +295,22 @@ 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 || other == m_parent) break;
- if (m_parent) m_parent->removeChild(this);
- if (!other->isChildOf(this) && other->child(this))
+ if (other == this || other == m_parent || other->isCopied()) break;
+ if (m_parent) { m_parent->removeChild(this); attachTo(NULL); }
+ Slot *pOther = other;
+ int count = 0;
+ bool foundOther = false;
+ while (pOther)
+ {
+ ++count;
+ if (pOther == this) foundOther = true;
+ pOther = pOther->attachedTo();
+ }
+ for (pOther = m_child; pOther; pOther = pOther->m_child)
+ ++count;
+ for (pOther = m_sibling; pOther; pOther = pOther->m_sibling)
+ ++count;
+ if (count < 100 && !foundOther && other->child(this))
{
attachTo(other);
if ((map.dir() != 0) ^ (idx > subindex))
@@ -421,31 +434,24 @@ bool Slot::sibling(Slot *ap)
bool Slot::removeChild(Slot *ap)
{
- if (this == ap || !m_child) return false;
+ if (this == ap || !m_child || !ap) return false;
else if (ap == m_child)
{
Slot *nSibling = m_child->nextSibling();
- m_child->removeSibling(nSibling);
+ m_child->nextSibling(NULL);
m_child = nSibling;
return true;
}
- else
- return m_child->removeSibling(ap);
- return true;
-}
-
-bool Slot::removeSibling(Slot *ap)
-{
- if (this == ap || !m_sibling) return false;
- else if (ap == m_sibling)
+ for (Slot *p = m_child; p; p = p->m_sibling)
{
- m_sibling = m_sibling->nextSibling();
- if (m_sibling) ap->removeSibling(m_sibling);
- return true;
+ if (p->m_sibling && p->m_sibling == ap)
+ {
+ p->m_sibling = p->m_sibling->m_sibling;
+ ap->nextSibling(NULL);
+ return true;
+ }
}
- else
- return m_sibling->removeSibling(ap);
- return true;
+ return false;
}
void Slot::setGlyph(Segment *seg, uint16 glyphid, const GlyphFace * theGlyph)
@@ -480,11 +486,13 @@ void Slot::setGlyph(Segment *seg, uint16 glyphid, const GlyphFace * theGlyph)
}
}
-void Slot::floodShift(Position adj)
+void Slot::floodShift(Position adj, int depth)
{
+ if (depth > 100)
+ return;
m_position += adj;
- if (m_child) m_child->floodShift(adj);
- if (m_sibling) m_sibling->floodShift(adj);
+ if (m_child) m_child->floodShift(adj, depth + 1);
+ if (m_sibling) m_sibling->floodShift(adj, depth + 1);
}
void SlotJustify::LoadSlot(const Slot *s, const Segment *seg)
@@ -519,10 +527,9 @@ Slot * Slot::nextInCluster(const Slot *s) const
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);
+ for (Slot *p = m_parent; p; p = p->m_parent)
+ if (p == base)
+ return true;
+ return false;
}
+
diff --git a/Build/source/libs/graphite2/graphite2-src/src/TtfUtil.cpp b/Build/source/libs/graphite2/graphite2-src/src/TtfUtil.cpp
index 85a4e6a0a81..75e8da11c45 100644
--- a/Build/source/libs/graphite2/graphite2-src/src/TtfUtil.cpp
+++ b/Build/source/libs/graphite2/graphite2-src/src/TtfUtil.cpp
@@ -896,15 +896,17 @@ bool CheckCmapSubtable4(const void * pCmapSubtable4, const void * pCmapEnd /*, u
const Sfnt::CmapSubTable * pTable = reinterpret_cast<const Sfnt::CmapSubTable *>(pCmapSubtable4);
// 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;
+ if (table_len < sizeof(*pTable) || be::swap(pTable->format) != 4) return false;
const Sfnt::CmapSubTableFormat4 * pTable4 = reinterpret_cast<const Sfnt::CmapSubTableFormat4 *>(pCmapSubtable4);
+ if (table_len < sizeof(*pTable4))
+ return false;
uint16 length = be::swap(pTable4->length);
if (length > table_len)
return false;
if (length < sizeof(Sfnt::CmapSubTableFormat4))
return false;
uint16 nRanges = be::swap(pTable4->seg_count_x2) >> 1;
- if (length < sizeof(Sfnt::CmapSubTableFormat4) + 4 * nRanges * sizeof(uint16))
+ if (!nRanges || length < sizeof(Sfnt::CmapSubTableFormat4) + 4 * nRanges * sizeof(uint16))
return false;
// check last range is properly terminated
uint16 chEnd = be::peek<uint16>(pTable4->end_code + nRanges - 1);
@@ -1004,7 +1006,7 @@ gid16 CmapSubtable4Lookup(const void * pCmapSubtabel4, unsigned int nUnicodeId,
// Look up value in glyphIdArray
const ptrdiff_t offset = (nUnicodeId - chStart) + (idRangeOffset >> 1) +
(pMid - reinterpret_cast<const uint16 *>(pTable));
- if (offset * 2 >= be::swap<uint16>(pTable->length))
+ if (offset * 2 + 1 >= be::swap<uint16>(pTable->length))
return 0;
gid16 nGlyphId = be::peek<uint16>(reinterpret_cast<const uint16 *>(pTable)+offset);
// If this value is 0, return 0. Else add the idDelta
@@ -1086,9 +1088,11 @@ bool CheckCmapSubtable12(const void *pCmapSubtable12, const void *pCmapEnd /*, u
size_t table_len = (const byte *)pCmapEnd - (const byte *)pCmapSubtable12;
if (!pCmapSubtable12) return false;
const Sfnt::CmapSubTable * pTable = reinterpret_cast<const Sfnt::CmapSubTable *>(pCmapSubtable12);
- if (be::swap(pTable->format) != 12)
+ if (table_len < sizeof(*pTable) || be::swap(pTable->format) != 12)
return false;
const Sfnt::CmapSubTableFormat12 * pTable12 = reinterpret_cast<const Sfnt::CmapSubTableFormat12 *>(pCmapSubtable12);
+ if (table_len < sizeof(*pTable12))
+ return false;
uint32 length = be::swap(pTable12->length);
if (length > table_len)
return false;
diff --git a/Build/source/libs/graphite2/graphite2-src/src/inc/Code.h b/Build/source/libs/graphite2/graphite2-src/src/inc/Code.h
index 5451a34809b..3985ae416e9 100644
--- a/Build/source/libs/graphite2/graphite2-src/src/inc/Code.h
+++ b/Build/source/libs/graphite2/graphite2-src/src/inc/Code.h
@@ -86,7 +86,7 @@ private:
void failure(const status_t) throw();
public:
- static size_t estimateCodeDataOut(size_t num_bytecodes);
+ static size_t estimateCodeDataOut(size_t num_bytecodes, int nRules, int nSlots);
Code() throw();
Code(bool is_constraint, const byte * bytecode_begin, const byte * const bytecode_end,
@@ -112,9 +112,11 @@ public:
};
inline
-size_t Machine::Code::estimateCodeDataOut(size_t n_bc)
+size_t Machine::Code::estimateCodeDataOut(size_t n_bc, int nRules, int nSlots)
{
- return (n_bc + 1) * (sizeof(instr)+sizeof(byte));
+ // max is: all codes are instructions + 1 for each rule + max tempcopies
+ // allocate space for separate maximal code and data then merge them later
+ return (n_bc + nRules + nSlots) * sizeof(instr) + n_bc * sizeof(byte);
}
diff --git a/Build/source/libs/graphite2/graphite2-src/src/inc/Face.h b/Build/source/libs/graphite2/graphite2-src/src/inc/Face.h
index 7682dfaca3e..43ea4319681 100644
--- a/Build/source/libs/graphite2/graphite2-src/src/inc/Face.h
+++ b/Build/source/libs/graphite2/graphite2-src/src/inc/Face.h
@@ -87,7 +87,7 @@ public:
const FeatureRef * feature(uint16 index) const;
// Glyph related
- uint16 getGlyphMetric(uint16 gid, uint8 metric) const;
+ int32 getGlyphMetric(uint16 gid, uint8 metric) const;
uint16 findPseudo(uint32 uid) const;
// Errors
diff --git a/Build/source/libs/graphite2/graphite2-src/src/inc/GlyphFace.h b/Build/source/libs/graphite2/graphite2-src/src/inc/GlyphFace.h
index 89ed5aea91a..41685a55f4f 100644
--- a/Build/source/libs/graphite2/graphite2-src/src/inc/GlyphFace.h
+++ b/Build/source/libs/graphite2/graphite2-src/src/inc/GlyphFace.h
@@ -51,7 +51,7 @@ public:
const Position & theAdvance() const;
const Rect & theBBox() const { return m_bbox; }
const sparse & attrs() const { return m_attrs; }
- uint16 getMetric(uint8 metric) const;
+ int32 getMetric(uint8 metric) const;
CLASS_NEW_DELETE;
private:
diff --git a/Build/source/libs/graphite2/graphite2-src/src/inc/Rule.h b/Build/source/libs/graphite2/graphite2-src/src/inc/Rule.h
index 36c8d89a63d..5ac21a17598 100644
--- a/Build/source/libs/graphite2/graphite2-src/src/inc/Rule.h
+++ b/Build/source/libs/graphite2/graphite2-src/src/inc/Rule.h
@@ -102,7 +102,7 @@ class SlotMap
{
public:
enum {MAX_SLOTS=64};
- SlotMap(Segment & seg, uint8 direction);
+ SlotMap(Segment & seg, uint8 direction, int maxSize);
Slot * * begin();
Slot * * end();
@@ -121,6 +121,7 @@ public:
void highpassed(bool v) { m_highpassed = v; }
uint8 dir() const { return m_dir; }
+ int decMax() { return --m_maxSize; }
Segment & segment;
private:
@@ -128,6 +129,7 @@ private:
unsigned short m_size;
unsigned short m_precontext;
Slot * m_highwater;
+ int m_maxSize;
uint8 m_dir;
bool m_highpassed;
};
@@ -242,8 +244,9 @@ void FiniteStateMachine::Rules::accumulate_rules(const State &state)
}
inline
-SlotMap::SlotMap(Segment & seg, uint8 direction)
-: segment(seg), m_size(0), m_precontext(0), m_highwater(0), m_dir(direction), m_highpassed(false)
+SlotMap::SlotMap(Segment & seg, uint8 direction, int maxSize)
+: segment(seg), m_size(0), m_precontext(0), m_highwater(0),
+ m_maxSize(maxSize), m_dir(direction), m_highpassed(false)
{
m_slot_map[0] = 0;
}
diff --git a/Build/source/libs/graphite2/graphite2-src/src/inc/Segment.h b/Build/source/libs/graphite2/graphite2-src/src/inc/Segment.h
index 7d72f98eda4..bcba1f2a87b 100644
--- a/Build/source/libs/graphite2/graphite2-src/src/inc/Segment.h
+++ b/Build/source/libs/graphite2/graphite2-src/src/inc/Segment.h
@@ -40,7 +40,7 @@ of the License or (at your option) any later version.
#include "inc/List.h"
#include "inc/Collider.h"
-#define MAX_SEG_GROWTH_FACTOR 256
+#define MAX_SEG_GROWTH_FACTOR 64
namespace graphite2 {
@@ -159,7 +159,7 @@ public:
void reverseSlots();
bool isWhitespace(const int cid) const;
- bool hasCollisionInfo() const { return (m_flags & SEG_HASCOLLISIONS); }
+ bool hasCollisionInfo() const { return (m_flags & SEG_HASCOLLISIONS) && m_collisions; }
SlotCollision *collisionInfo(const Slot *s) const { return m_collisions ? m_collisions + s->index() : 0; }
CLASS_NEW_DELETE
diff --git a/Build/source/libs/graphite2/graphite2-src/src/inc/Slot.h b/Build/source/libs/graphite2/graphite2-src/src/inc/Slot.h
index a6e05491c6d..daa11244737 100644
--- a/Build/source/libs/graphite2/graphite2-src/src/inc/Slot.h
+++ b/Build/source/libs/graphite2/graphite2-src/src/inc/Slot.h
@@ -97,7 +97,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, bool rtl, bool isFinal);
+ Position finalise(const Segment* seg, const Font* font, Position & base, Rect & bbox, uint8 attrLevel, float & clusterMin, bool rtl, bool isFinal, int depth = 0);
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; }
@@ -128,10 +128,9 @@ public:
void nextSibling(Slot *ap) { m_sibling = ap; }
bool sibling(Slot *ap);
bool removeChild(Slot *ap);
- bool removeSibling(Slot *ap);
int32 clusterMetric(const Segment* seg, uint8 metric, uint8 attrLevel, bool rtl);
void positionShift(Position a) { m_position += a; }
- void floodShift(Position adj);
+ void floodShift(Position adj, int depth = 0);
float just() const { return m_just; }
void just(float j) { m_just = j; }
Slot *nextInCluster(const Slot *s) const;
diff --git a/Build/source/libs/graphite2/graphite2-src/src/inc/UtfCodec.h b/Build/source/libs/graphite2/graphite2-src/src/inc/UtfCodec.h
index 66384ae182a..3417bac7b15 100644
--- a/Build/source/libs/graphite2/graphite2-src/src/inc/UtfCodec.h
+++ b/Build/source/libs/graphite2/graphite2-src/src/inc/UtfCodec.h
@@ -40,6 +40,7 @@ struct _utf_codec
static void put(codeunit_t * cp, const uchar_t , int8 & len) throw();
static uchar_t get(const codeunit_t * cp, int8 & len) throw();
+ static bool validate(const codeunit_t * s, const codeunit_t * e) throw();
};
@@ -63,6 +64,12 @@ public:
if (cp[0] < limit) { l = 1; return cp[0]; }
else { l = -1; return 0xFFFD; }
}
+
+ inline
+ static bool validate(codeunit_t * s, codeunit_t * e) throw()
+ {
+ return e > s;
+ }
};
@@ -93,12 +100,21 @@ public:
const uint32 uh = cp[0];
l = 1;
- if (0xD800 > uh || uh > 0xDFFF) { return uh; }
+ if (uh < 0xD800|| uh > 0xDFFF) { return uh; }
const uint32 ul = cp[1];
- if (uh > 0xDBFF || 0xDC00 > ul || ul > 0xDFFF) { l = -1; return 0xFFFD; }
+ if (uh > 0xDBFF || ul < 0xDC00 || ul > 0xDFFF) { l = -1; return 0xFFFD; }
++l;
return (uh<<10) + ul + surrogate_offset;
}
+
+ inline
+ static bool validate(codeunit_t * s, codeunit_t * e) throw()
+ {
+ const ptrdiff_t n = e-s;
+ if (n <= 0) return n == 0;
+ const uint32 u = *(s+(n-1)); // Get the last codepoint
+ return (u < 0xD800 || u > 0xDBFF);
+ }
};
@@ -148,6 +164,24 @@ public:
}
return u;
}
+
+ inline
+ static bool validate(codeunit_t * s, codeunit_t * e) throw()
+ {
+ const ptrdiff_t n = e-s;
+ if (n <= 0) return n == 0;
+ s += (n-1);
+ if (*s < 0x80) return true;
+ if (*s >= 0xC0) return false;
+ if (n == 1) return true;
+ if (*--s < 0x80) return true;
+ if (*s >= 0xe0) return false;
+ if (n == 2 || *s >= 0xC0) return true;
+ if (*--s < 0x80) return true;
+ if (*s >= 0xF0) return false;
+ return true;
+ }
+
};
@@ -200,6 +234,11 @@ struct utf
typedef _utf_iterator<C> iterator;
typedef _utf_iterator<const C> const_iterator;
+
+ inline
+ static bool validate(codeunit_t * s, codeunit_t * e) throw() {
+ return _utf_codec<sizeof(C)*8>::validate(s,e);
+ }
};
diff --git a/Build/source/libs/graphite2/graphite2-src/src/inc/opcode_table.h b/Build/source/libs/graphite2/graphite2-src/src/inc/opcode_table.h
index 73a99c82043..50ae1d4d077 100644
--- a/Build/source/libs/graphite2/graphite2-src/src/inc/opcode_table.h
+++ b/Build/source/libs/graphite2/graphite2-src/src/inc/opcode_table.h
@@ -118,7 +118,7 @@ static const opcode_t opcode_table[] =
{{do2(band)}, 0, "BITAND"},
{{do2(bnot)}, 0, "BITNOT"}, // 0x40
{{do2(setbits)}, 4, "BITSET"},
- {{do2(set_feat)}, 2, "SET_FEAT"},
+ {{do_(set_feat), NILOP}, 2, "SET_FEAT"}, // featidx slot
// 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-src/src/inc/opcodes.h b/Build/source/libs/graphite2/graphite2-src/src/inc/opcodes.h
index 76da50bf409..23f595fde1f 100644
--- a/Build/source/libs/graphite2/graphite2-src/src/inc/opcodes.h
+++ b/Build/source/libs/graphite2/graphite2-src/src/inc/opcodes.h
@@ -242,7 +242,7 @@ ENDOP
STARTOP(put_copy)
declare_params(1);
const int slot_ref = int8(*param);
- if (is)
+ if (is && !is->isDeleted())
{
slotref ref = slotat(slot_ref);
if (ref && ref != is)
@@ -267,6 +267,7 @@ STARTOP(put_copy)
ENDOP
STARTOP(insert)
+ if (smap.decMax() <= 0) DIE;
Slot *newSlot = seg.newSlot();
if (!newSlot) DIE;
Slot *iss = is;
@@ -555,7 +556,7 @@ STARTOP(iattr_add)
const int val = int(pop());
if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
{
- seg.positionSlots(0, *smap.begin(), *(smap.end()-1), dir);
+ seg.positionSlots(0, *smap.begin(), *(smap.end()-1), seg.currdir());
flags |= POSITIONED;
}
int res = is->getAttr(&seg, slat, idx);
@@ -569,7 +570,7 @@ STARTOP(iattr_sub)
const int val = int(pop());
if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
{
- seg.positionSlots(0, *smap.begin(), *(smap.end()-1), dir);
+ seg.positionSlots(0, *smap.begin(), *(smap.end()-1), seg.currdir());
flags |= POSITIONED;
}
int res = is->getAttr(&seg, slat, idx);
diff --git a/Build/source/libs/graphite2/version.ac b/Build/source/libs/graphite2/version.ac
index 10ef86c5e7e..fbf987009bb 100644
--- a/Build/source/libs/graphite2/version.ac
+++ b/Build/source/libs/graphite2/version.ac
@@ -8,4 +8,4 @@ dnl
dnl --------------------------------------------------------
dnl
dnl m4-include this file to define the current graphite2 version
-m4_define([graphite2_version], [1.3.6])
+m4_define([graphite2_version], [1.3.7])