This is an automated email from the git hooks/post-receive script.

rene pushed a commit to branch master
in repository graphite2.

commit 73ffa74d28363cbac4ab454160f78c6d1a3867b2
Author: Rene Engelhard <[email protected]>
Date:   Thu Apr 21 14:48:48 2016 +0200

    Imported Upstream version 1.2.1
---
 .hg_archival.txt                          |  5 +--
 CMakeLists.txt                            |  2 +-
 ChangeLog                                 |  7 +++
 Graphite.cmake                            | 11 +++--
 debian-src/build                          |  4 +-
 debian-src/changelog                      |  6 +++
 doc/building.txt                          | 55 ++++++++++++++++++-----
 doc/calling.txt                           | 62 +++++++++++++------------
 doc/testing.txt                           |  6 +--
 gr2fonttest/gr2FontTest.cpp               | 75 ++++++++++++++++++++++---------
 include/graphite2/Font.h                  |  4 +-
 include/graphite2/Segment.h               | 38 ++++++++++++----
 src/CMakeLists.txt                        |  4 +-
 src/Face.cpp                              |  4 +-
 src/FeatureMap.cpp                        | 16 +++----
 src/FileFace.cpp                          | 11 +----
 src/Font.cpp                              |  3 +-
 src/GlyphCache.cpp                        | 25 ++++-------
 src/Pass.cpp                              | 17 ++++---
 src/Segment.cpp                           | 16 +++----
 src/Silf.cpp                              |  2 +-
 src/Slot.cpp                              | 34 +++++++++++++-
 src/Sparse.cpp                            |  7 +--
 src/TtfUtil.cpp                           |  2 -
 src/inc/FeatureMap.h                      |  3 --
 src/inc/GlyphCache.h                      | 13 +++---
 src/inc/Machine.h                         |  2 +-
 src/inc/Main.h                            | 12 +++++
 src/inc/Pass.h                            |  1 -
 src/inc/Segment.h                         | 10 ++---
 src/inc/Silf.h                            | 12 ++---
 src/inc/Slot.h                            |  4 +-
 src/inc/Sparse.h                          | 14 +++++-
 src/inc/bits.h                            | 11 +++--
 src/inc/opcode_table.h                    |  6 +--
 src/inc/opcodes.h                         | 14 +++---
 tests/CMakeLists.txt                      |  4 +-
 tests/comparerenderer/CompareRenderer.cpp |  6 +--
 tests/comparerenderer/Gr2Renderer.h       |  6 +--
 tests/comparerenderer/RendererOptions.h   |  6 +--
 tests/examples/cluster.c                  |  4 +-
 tests/examples/linebreak.c                | 38 +++++++++-------
 tests/fuzz-tests/CMakeLists.txt           |  2 +
 tests/sparsetest/sparsetest.cpp           |  6 +--
 tests/standards/charis1.log               |  1 +
 tests/standards/charis2.log               |  1 +
 tests/standards/charis3.log               |  1 +
 tests/standards/charis4.log               |  1 +
 tests/standards/charis5.log               |  1 +
 tests/standards/charis6.log               |  1 +
 tests/standards/general1.log              |  1 +
 tests/standards/grtest1.log               |  1 +
 tests/standards/magyar1.log               |  1 +
 tests/standards/magyar2.log               |  1 +
 tests/standards/magyar3.log               |  1 +
 tests/standards/padauk1.log               |  1 +
 tests/standards/padauk10.log              |  1 +
 tests/standards/padauk11.log              |  1 +
 tests/standards/padauk2.log               |  1 +
 tests/standards/padauk3.log               |  1 +
 tests/standards/padauk3Windows.log        |  1 +
 tests/standards/padauk4.log               |  1 +
 tests/standards/padauk5.log               |  1 +
 tests/standards/padauk6.log               |  1 +
 tests/standards/padauk7.log               |  1 +
 tests/standards/padauk8.log               |  1 +
 tests/standards/padauk9.log               |  1 +
 tests/standards/scher1.log                |  1 +
 tests/standards/scher2.log                |  1 +
 tests/standards/scher3.log                |  1 +
 tests/utftest/utftest.cpp                 | 69 +++++++++++++++++++++++-----
 71 files changed, 457 insertions(+), 228 deletions(-)

diff --git a/.hg_archival.txt b/.hg_archival.txt
index 0e511bd..039e20a 100644
--- a/.hg_archival.txt
+++ b/.hg_archival.txt
@@ -1,5 +1,4 @@
 repo: 999e2033695c3bcf2f65d611737ac9008805bd58
-node: 8d2a85a546653a795d39cab287a1965a785cfbf8
+node: 9ca2c8c1469f6107cd366e4be2035ce0dfa09b65
 branch: default
-latesttag: 1.2.0
-latesttagdistance: 1
+tag: 1.2.1
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 043a9f4..c142371 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -63,7 +63,7 @@ if (NOT (GRAPHITE2_NSEGCACHE OR GRAPHITE2_NFILEFACE))
     add_subdirectory(gr2fonttest)
 endif (NOT (GRAPHITE2_NSEGCACHE OR GRAPHITE2_NFILEFACE))
 
-set(version 2.1.0)
+set(version 3.0.1)
 set(libdir ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX})
 set(includedir ${CMAKE_INSTALL_PREFIX}/include)
 
diff --git a/ChangeLog b/ChangeLog
index 03629e9..f6cd4b3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+1.2.1
+    . Bug fixes:
+        . Allow glyph reattachment
+        . Allow signed glyph attributes
+        . Various build problems with MacOS, old gcc versions, etc.
+        . Various overrun read errors fixed
+
 1.2.0
     . API Changes:
         . Added Windows friendly gr_start_logging and gr_stop_logging, now per 
face
diff --git a/Graphite.cmake b/Graphite.cmake
index b6fe7cf..54f765a 100644
--- a/Graphite.cmake
+++ b/Graphite.cmake
@@ -32,11 +32,12 @@ FUNCTION(CREATE_LIBTOOL_FILE _target _install_DIR)
   GET_TARGET_PROPERTY_WITH_DEFAULT(_target_age ${_target} LT_VERSION_AGE 0)
   GET_TARGET_PROPERTY_WITH_DEFAULT(_target_revision ${_target} 
LT_VERSION_REVISION 0)
   GET_TARGET_PROPERTY_WITH_DEFAULT(_target_installed ${_target} LT_INSTALLED 
yes)
-  GET_TARGET_PROPERTY_WITH_DEFAULT(_target_shouldnotlink ${_target} 
LT_SHOULDNOTLINK yes)
+  GET_TARGET_PROPERTY_WITH_DEFAULT(_target_shouldnotlink ${_target} 
LT_SHOULDNOTLINK no)
   GET_TARGET_PROPERTY_WITH_DEFAULT(_target_dlopen ${_target} LT_DLOPEN "")
   GET_TARGET_PROPERTY_WITH_DEFAULT(_target_dlpreopen ${_target} LT_DLPREOPEN 
"")
   GET_FILENAME_COMPONENT(_lanamewe ${_target_location} NAME_WE)
   GET_FILENAME_COMPONENT(_soname ${_target_location} NAME)
+  GET_FILENAME_COMPONENT(_soext ${_target_location} EXT)
   SET(_laname ${PROJECT_BINARY_DIR}/${_lanamewe}.la)
   FILE(WRITE ${_laname} "# ${_lanamewe}.la - a libtool library file\n")
   FILE(APPEND ${_laname} "# Generated by CMake ${CMAKE_VERSION} (like GNU 
libtool)\n")
@@ -44,14 +45,18 @@ FUNCTION(CREATE_LIBTOOL_FILE _target _install_DIR)
   FILE(APPEND ${_laname} "# The name that we can dlopen(3).\n")
   FILE(APPEND ${_laname} "dlname='${_soname}'\n\n")
   FILE(APPEND ${_laname} "# Names of this library.\n")
-  FILE(APPEND ${_laname} 
"library_names='${_soname}.${_target_current}.${_target_age}.${_target_revision}
 ${_soname}.${_target_current} ${_soname}'\n\n")
+  if (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
+    FILE(APPEND ${_laname} 
"library_names='${_lanamwe}.${_target_current}.${_target_revision}.${_target_age}.${_soext}
 ${_lanamewe}.${_target_current}.${_soext} ${_soname}'\n\n")
+  else (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
+    FILE(APPEND ${_laname} 
"library_names='${_soname}.${_target_current}.${_target_revision}.${_target_age}
 ${_soname}.${_target_current} ${_soname}'\n\n")
+  endif (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
   FILE(APPEND ${_laname} "# The name of the static archive.\n")
   FILE(APPEND ${_laname} "old_library='${_target_static_lib}'\n\n")
   FILE(APPEND ${_laname} "# Libraries that this one depends upon.\n")
   FILE(APPEND ${_laname} "dependency_libs='${_target_dependency_libs}'\n\n")
   FILE(APPEND ${_laname} "# Names of additional weak libraries provided by 
this library\n")
   FILE(APPEND ${_laname} "weak_library_names=\n\n")
-  FILE(APPEND ${_laname} "# Version information for ${_laname}.\n")
+  FILE(APPEND ${_laname} "# Version information for ${_lanamewe}.\n")
   FILE(APPEND ${_laname} "current=${_target_current}\n")
   FILE(APPEND ${_laname} "age=${_target_age}\n")
   FILE(APPEND ${_laname} "revision=${_target_revision}\n\n")
diff --git a/debian-src/build b/debian-src/build
index 6aae061..8352947 100755
--- a/debian-src/build
+++ b/debian-src/build
@@ -1,7 +1,7 @@
 #!/bin/bash
 HERE=`pwd`
 if [ ! -n "${TARGETS}" ]; then
-    TARGETS="lucid natty oneiric precise"
+    TARGETS="lucid oneiric precise quantal"
 fi
 #PUBLISH='SIL'
 PUBLISH='LINGNET'
@@ -26,6 +26,8 @@ if [ "${BUILD_ARCHS:0:6}" = "source" ]; then
 else
     echo ">> non-source build"
     rm ${BUILDINGDIR}/*build*
+    rm ${BUILDINGDIR}/*lucid*
+    rm ${BUILDINGDIR}/*precise*
 fi
 
 source /home/bob/pbuilder/build.common
diff --git a/debian-src/changelog b/debian-src/changelog
index ff2f85e..d40e8d6 100644
--- a/debian-src/changelog
+++ b/debian-src/changelog
@@ -1,3 +1,9 @@
+graphite2 (1.2.1-1~palaso1) precise; urgency=low
+
+  * New upstream release with bug fixes
+
+ -- Martin Hosken <[email protected]>  Tue, 26 Feb 2013 14:21:18 +0100
+
 graphite2 (1.2.0-1~palaso1) precise; urgency=low
 
   * New upstream release with library API bump from 2.0.0 to 3.0.1 (v3 API 
with age of 1) 
diff --git a/doc/building.txt b/doc/building.txt
index b48a479..11ac84e 100644
--- a/doc/building.txt
+++ b/doc/building.txt
@@ -1,6 +1,8 @@
 == Building Graphite 2 ==
 
-Graphite 2 is made available as a source tarball from: 
http://projects.palaso.org/graphitedev/files and also from 
http://sf.net/projects/silgraphite/files/graphite2
+Graphite 2 is made available as a source tarball from these urls: 
+    http://projects.palaso.org/graphitedev/files 
+ or http://sf.net/projects/silgraphite/files/graphite2
 
 Graphite 2 uses cmake for its build system. The basic build procedure is to 
 create a directory in which to build the library and produce the products. 
@@ -100,26 +102,55 @@ the -Doption=value command line option.
 For example: -DGRAPHITE2_COMPARE_RENDERER=ON
 
 CMAKE_BUILD_TYPE:STRING::
-    This specifies which type of build to do. It is a string and may take the 
values: Release, RelWithDeb, Debug.
+    This specifies which type of build to do. It is a string and may take the 
+    values: Release, RelWithDeb, Debug.
     The default is Release. This must be specified on Windows.
 
 GRAPHITE2_COMPARE_RENDERER:BOOL::
-    This is a boolean value that specifies whether to build the 
comparerenderer program that may link to silGraphite
-    or harfbuzz, if libraries of those packages are installed. The default 
value is OFF.
+    This is a boolean value that specifies whether to build the 
comparerenderer 
+    program that may link to silGraphite or harfbuzz, if libraries of those 
+    packages are installed. The default value is OFF.
 
 GRAPHITE2_NFILEFACE:BOOL::
-    This boolean value turns off FileFace support to save code space. By 
default it is OFF.
+    This boolean value turns off FileFace support to save code space. 
+    By default it is OFF.
 
 GRAPHITE2_NSEGCACHE:BOOL::
-    This boolean value turns off Segment caching support to save code space. 
By default it is OFF.
+    This boolean value turns off Segment caching support to save code space. 
+    By default it is OFF.
 
 GRAPHITE2_NTRACING:BOOL::
-    This boolean value turns off tracing support to save code space. Tracing 
support allows debug output of segment
-    creation. By default it is OFF.
+    This boolean value turns off tracing support to save code space. Tracing 
+    support allows debug output of segment creation. By default it is OFF.
 
 GRAPHITE2_VM_TYPE:STRING::
-    This string value can be auto, direct or call. It specifies which type of 
virtual machine processor to use. The
-    default value of auto tells the system to work out the best approach for 
this architecture. A value of direct
-    tells the system to use the direct machine which is faster. The value of 
call tells the system to use the slower
-    but more cross compiler portable call based machine.
+    This string value can be auto, direct or call. It specifies which type of 
+    virtual machine processor to use. The default value of auto tells the 
+    system to work out the best approach for this architecture. A value of 
+    direct tells the system to use the direct machine which is faster. 
+    The value of call tells the system to use the slower but more cross 
+    compiler portable call based machine.
+
+=== Limitations ===
+
+There are some hard build dependencies:
+
+python::
+    To run the make test and make fuzztest, the build system requires 
+    python v2.6 or later. Currently python 3 is not supported, however porting
+    using 2to3 is straightforward. 
+
+Other configuration related dependencies:
+
+silgraphite::
+    Required to build the comparerender test and benchmarking tool and in turn
+    to allow extra tests to be run which check graphite2's rendering against 
+    silgraphite.
+
+freetype::
+    Also required by comparerender
+
+harfbuzz, harfbuzng, icule::
+    If found comparerenderer will be built with support for these but they are 
+    not required to build or run any tests
 
diff --git a/doc/calling.txt b/doc/calling.txt
index 77522ec..b54eb06 100644
--- a/doc/calling.txt
+++ b/doc/calling.txt
@@ -228,26 +228,33 @@ include::../tests/examples/linebreak.c[]
 <2> Create an area to store line starts. There won't be more line starts than 
characters
     in the text. The first line starts at the start of the segment.
 
-<3> Scan through the slots, if we are past the end of the line then find 
somewhere to chop.
+<3> A simplistic approach would scan forwards using 
gr_slot_next_sibling_attachment, thus
+    walking the bases. The bases are guaranteed to be ordered graphically, and 
so we can
+    chop when we pass the line end. But in some cases, particularly Arabic, 
fonts are
+    implemented with one base per word and all the other base characters are 
attached in
+    a chain from that. So we need to walk the segment by slot, even 
considering attached
+    slots. This is not a problem since attached slots are not going to have a 
wildly
+    different position to their base and if one leaks over the end of the 
line, the
+    breakweight considerations will get us back to a good base.
 
-<4> Scan backwards for a valid linebreak location.
+<4> Scan through the slots, if we are past the end of the line then find 
somewhere to chop.
 
-<5> We use 15 (syllable break) as an appropriate break value. A negative value 
means the
-    break constraint is before the slot, so we test that. Likewise for after 
we test for
-    a positive value.
+<5> We use 15 (word break) as an appropriate break value.
 
-<6> Break the line here.
+<6> Scan backwards for a valid linebreak location.
 
-<7> Update the line width for the new line based on the start of the new line.
+<7> Break the line here.
 
-<8> Justify each line to be width wide. And tell it to skip final whitespace 
(as if that whitespace were outside the width).
+<8> Update the line width for the new line based on the start of the new line.
 
-<9> Each line is a complete linked list that we can iterate over. We can no 
longer iterate
-    over the whole segment. We have to do it line by line now.
+<9> Justify each line to be width wide. And tell it to skip final whitespace 
(as if that whitespace were outside the width).
+
+<10> Each line is a complete linked list that we can iterate over. We can no 
longer iterate
+     over the whole segment. We have to do it line by line now.
 
 === Bidi ===
 
-Bidirectional processing is complex not so much because of any algorithms
+Bidirectional processing is complex; not so much because of any algorithms
 involved, but because of the tendency for applications to address bidi text
 processing differently. Some try to do everything themselves, inverting the 
text
 order, etc. While others do nothing, expecting the shaper to resolve all the
@@ -259,24 +266,21 @@ various bits to control bidi processing within the 
Graphite engine.
 
 [width="100%",cols="^2,^3,<15",options="header"]
 |=======================================================
-|gr_nobidi  |gr_nomirror  |Description
-
-|0          |0            |
-Runs the bidi algorithm and does all mirroring
-
-|0          |1            |
-Runs the bidi algorithm and mirrors those chars that don't have char
-replacements. It also un/remirrors anything that ends up in the opposite 
direction
-to the stated text direction on input.
-
-|1          |0            |
-Doesn't run the bidi algorithm but does do mirroring of all characters if
-direction is rtl.
-
-|1          |1            |
-Doesn't run the bidi algorithm and only mirrors those glyphs for which there is
-no corresponding mirroring character.
-
+| gr_nobidi | gr_nomirror | Description
+
+| 0         | 0           | Runs the bidi algorithm and does all mirroring
+
+| 0         | 1           | Runs the bidi algorithm and mirrors those chars 
+                            that don't have char replacements. It also 
+                            un/remirrors anything that ends up in the opposite 
+                            direction to the stated text direction on input.
+                            
+| 1         | 0           | Doesn't run the bidi algorithm but does do 
+                            mirroring of all characters if direction is rtl.
+                            
+| 1         | 1           | Doesn't run the bidi algorithm and only mirrors 
+                            those glyphs for which there is no corresponding 
+                            mirroring character.
 |=======================================================
 
 
diff --git a/doc/testing.txt b/doc/testing.txt
index 0a7858d..2f3defe 100644
--- a/doc/testing.txt
+++ b/doc/testing.txt
@@ -9,7 +9,7 @@ fuzz tests uses valgrind to check for rogue memory accesses and 
runs several
 thousand tests on each of the 4 major test fonts and takes considerably longer 
 to run.
 We also have a growing suite of fuzz test regressions culled from logs 
-generated by the above fuzz test systen, which can be run with a make command. 
+generated by the above fuzz test system, which can be run with a make command. 
 These are intended to be run before bug fix release and other point releases.
 
 === Running the tests ===
@@ -58,8 +58,8 @@ TrueType and Graphite specific tables with a random value, 
but excludes
 OpenType and AAT related tables. It also imposes a runtime limit of 10 seconds 
 (most test should compete in a fraction of a second) and a memory limit 200MiB,
 again a normal run should only use a tiny fraction of that.
-If the `comparerenderer` test segfaults, exceeds those limits or returns a 
error 
-value it is logged to a file named on the following pattern: 
+If the `comparerenderer` test segfaults, exceeds those limits or returns an 
+error value it is logged to a file named on the following pattern: 
 `fuzzfont-<font name>-<text name>.log`, which is written to the script's 
 current directory.
 
diff --git a/gr2fonttest/gr2FontTest.cpp b/gr2fonttest/gr2FontTest.cpp
index 2956f84..8190fbe 100644
--- a/gr2fonttest/gr2FontTest.cpp
+++ b/gr2fonttest/gr2FontTest.cpp
@@ -92,7 +92,7 @@ public:
     bool ws;
     bool rtl;
     bool useLineFill;
-    bool useCodes;
+    int useCodes;
     int justification;
     bool enableCache;
     float width;
@@ -102,6 +102,8 @@ public:
     size_t offset;
     FILE * log;
     char * trace;
+    int codesize;
+    gr_face_options opts;
     
 private :  //defensive since log should not be copied
     Parameters(const Parameters&);
@@ -133,16 +135,18 @@ void Parameters::clear()
     rtl = false;
     ws = false;
     useLineFill = false;
-    useCodes = false;
+    useCodes = 0;
     justification = 0;
     enableCache = false;
     width = 100.0f;
     pText32 = NULL;
     textArgIndex = 0;
     charLength = 0;
+    codesize = 4;
     offset = 0;
     log = stdout;
     trace = NULL;
+    opts = gr_face_preloadAll;
 }
 
 
@@ -162,18 +166,16 @@ namespace gr2 = graphite2;
 template <typename utf>
 size_t convertUtf(const void * src, unsigned int * & dest)
 {
-    dest = static_cast<unsigned int 
*>(malloc(sizeof(*dest)*strlen(reinterpret_cast<const char *>(src))+1));
+    dest = static_cast<unsigned int *>(malloc(sizeof(unsigned 
int)*(strlen(reinterpret_cast<const char *>(src))+1)));
     if (!dest)
        return 0;
 
     typename utf::const_iterator ui = src;
-    size_t n_chars = 0;
     unsigned int * out = dest;
        while ((*out = *ui) != 0 && !ui.error())
        {
                ++ui;
                ++out;
-               ++n_chars;
        }
 
        if (ui.error())
@@ -183,7 +185,7 @@ size_t convertUtf(const void * src, unsigned int * & dest)
                return size_t(-1);
        }
 
-       return n_chars;
+       return (out-dest);
 }
 
 
@@ -193,6 +195,7 @@ bool Parameters::loadFromArgs(int argc, char *argv[])
     pText32 = NULL;
     features = NULL;
     log = stdout;
+    codesize = 4;
     bool argError = false;
     char* pText = NULL;
     typedef enum 
@@ -208,7 +211,7 @@ bool Parameters::loadFromArgs(int argc, char *argv[])
         FEAT,
         LOG,
         TRACE,
-        TRACE_MASK
+        SIZE
     } TestOptions;
     TestOptions option = NONE;
     char * pIntEnd = NULL;
@@ -290,6 +293,11 @@ bool Parameters::loadFromArgs(int argc, char *argv[])
             trace = argv[a];
             option = NONE;
             break;
+        case SIZE :
+            pIntEnd = NULL;
+            codesize = strtol(argv[a],&pIntEnd, 10);
+            option = NONE;
+            break;
         default:
             option = NONE;
             if (argv[a][0] == '-')
@@ -336,10 +344,14 @@ bool Parameters::loadFromArgs(int argc, char *argv[])
                 {
                     option = FEAT;
                 }
+                else if (strcmp(argv[a], "-bytes") == 0)
+                {
+                    option = SIZE;
+                }
                 else if (strcmp(argv[a], "-codes") == 0)
                 {
                     option = NONE;
-                    useCodes = true;
+                    useCodes = 4;
                     // must be less than argc
                     //pText32 = new unsigned int[argc];
                     pText32 = (unsigned int *)malloc(sizeof(unsigned int) * 
argc);
@@ -362,9 +374,10 @@ bool Parameters::loadFromArgs(int argc, char *argv[])
                 {
                     option = TRACE;
                 }
-                else if (strcmp(argv[a], "-mask") == 0)
+                else if (strcmp(argv[a], "-demand") == 0)
                 {
-                    option = TRACE_MASK;
+                    option = NONE;
+                    opts = gr_face_default;
                 }
                 else
                 {
@@ -587,9 +600,9 @@ int Parameters::testFileFont() const
     {
         gr_face *face = NULL;
         if (enableCache)
-            face = gr_make_file_face_with_seg_cache(fileName, 1000, 
gr_face_preloadGlyphs | gr_face_dumbRendering);
+            face = gr_make_file_face_with_seg_cache(fileName, 1000, opts | 
gr_face_dumbRendering);
         else
-            face = gr_make_file_face(fileName, gr_face_preloadGlyphs);
+            face = gr_make_file_face(fileName, opts);
 
         // use the -trace option to specify a file
        if (trace)      gr_start_logging(face, trace);
@@ -653,17 +666,37 @@ int Parameters::testFileFont() const
        {
         gr_segment* pSeg = NULL;
         if (features)
-        {
             featureList = parseFeatures(face);
-            pSeg = gr_make_seg(sizedFont,
-                face, 0, featureList, textSrc.utfEncodingForm(),
-                textSrc.get_utf_buffer_begin(), textSrc.getLength(), rtl ? 1 : 
0);
+        if (codesize == 2)
+        {
+            unsigned short *pText16 = (unsigned short 
*)malloc(textSrc.getLength() * 2 * sizeof(unsigned short));
+            gr2::utf16::iterator ui = pText16;
+            unsigned int *p = pText32;
+            for (int i = 0; i < textSrc.getLength(); ++i)
+            {
+                *ui = *p++;
+                ui++;
+            }
+            *ui = 0;
+            pSeg = gr_make_seg(sizedFont, face, 0, features ? featureList : 
NULL, (gr_encform)codesize, pText16, textSrc.getLength(), rtl ? 1 : 0);
         }
-        else
+        else if (codesize == 1)
         {
-            pSeg = gr_make_seg(sizedFont, face, 0, NULL, 
textSrc.utfEncodingForm(),
-                textSrc.get_utf_buffer_begin(), textSrc.getLength(), rtl ? 1 : 
0);
+            unsigned char *pText8 = (unsigned char 
*)malloc(textSrc.getLength() * 4);
+            gr2::utf8::iterator ui = pText8;
+            unsigned int *p = pText32;
+            for (int i = 0; i < textSrc.getLength(); ++i)
+            {
+                *ui = *p++;
+                ui++;
+            }
+            *ui = 0;
+            pSeg = gr_make_seg(sizedFont, face, 0, features ? featureList : 
NULL, (gr_encform)codesize, pText8, textSrc.getLength(), rtl ? 1 : 0);
         }
+        else
+            pSeg = gr_make_seg(sizedFont, face, 0, features ? featureList : 
NULL, textSrc.utfEncodingForm(),
+                textSrc.get_utf_buffer_begin(), textSrc.getLength(), rtl ? 1 : 
0);
+
         if (pSeg)
         {
             int i = 0;
@@ -680,6 +713,7 @@ int Parameters::testFileFont() const
             for (const gr_slot* slot = gr_seg_first_slot(pSeg); slot; slot = 
gr_slot_next_in_segment(slot), ++i)
             { map[i] = (size_t)slot; }
             map[i] = 0;
+            fprintf(log, "Segment length: %d\n", gr_seg_n_slots(pSeg));
             fprintf(log, "pos  gid   attach\t     x\t     y\tins bw\t  
chars\t\tUnicode\t");
             fprintf(log, "\n");
             i = 0;
@@ -777,8 +811,9 @@ int main(int argc, char *argv[])
         fprintf(stderr,"-feat f=g\tSet feature f to value g. Separate multiple 
features with ,\n");
         fprintf(stderr,"-log out.log\tSet log file to use rather than 
stdout\n");
         fprintf(stderr,"-trace trace.xml\tDefine a file for the XML trace 
log\n");
-        fprintf(stderr,"-mask mask\tDefine the mask to use for trace 
logging\n");
+        fprintf(stderr,"-demand\tDemand load glyphs and cmap cache\n");
         fprintf(stderr,"-cache\tEnable Segment Cache\n");
+        fprintf(stderr,"-bytes\tword size for character transfer [1,2,4] 
defaults to 4\n");
         return 1;
     }
     return parameters.testFileFont();
diff --git a/include/graphite2/Font.h b/include/graphite2/Font.h
index 39e4dcf..7fc3e6e 100644
--- a/include/graphite2/Font.h
+++ b/include/graphite2/Font.h
@@ -30,7 +30,7 @@
 
 #define GR2_VERSION_MAJOR   1
 #define GR2_VERSION_MINOR   2
-#define GR2_VERSION_BUGFIX  0
+#define GR2_VERSION_BUGFIX  1
 
 #ifdef __cplusplus
 extern "C"
@@ -63,7 +63,7 @@ enum gr_face_options {
     /** Cache the lookup from code point to glyph ID at construction time */
     gr_face_cacheCmap = 4,
     /** Preload everything */
-    gr_face_preloadAll = 6
+    gr_face_preloadAll = gr_face_preloadGlyphs | gr_face_cacheCmap
 };
 
 /** Holds information about a particular Graphite silf table that has been 
loaded */
diff --git a/include/graphite2/Segment.h b/include/graphite2/Segment.h
index 051c8ed..580f837 100644
--- a/include/graphite2/Segment.h
+++ b/include/graphite2/Segment.h
@@ -155,13 +155,22 @@ GR2_API unsigned int gr_cinfo_unicode_char(const 
gr_char_info* p/*not NULL*/);
 /** Returns breakweight for a charinfo.
   * 
   * @return Breakweight is a number between -50 and 50 indicating the cost of a
-  * break before or after this character.
+  * break before or after this character. If the value < 0, the absolute value
+  * is this character's contribution to the overall breakweight before it. If 
the value
+  * > 0, then the value is this character's contribution to the overall 
breakweight after it.
+  * The overall breakweight between two characters is the maximum of the 
breakweight
+  * contributions from the characters either side of it. If a character makes 
no
+  * contribution to the breakweight on one side of it, the contribution is 
considered
+  * to be 0.
   * @param p Pointer to charinfo to return information on.
   */
 GR2_API int gr_cinfo_break_weight(const gr_char_info* p/*not NULL*/);
 
 /** Returns the slot index that after this character is after in the slot 
stream
   *
+  * In effect each character is associated with a set of slots and this returns
+  * the index of the last slot in the segment this character is associated 
with.
+  *
   * @return after slot index between 0 and gr_seg_n_slots()
   * @param p Pointer to charinfo to return information on.
   */
@@ -169,6 +178,9 @@ GR2_API int gr_cinfo_after(const gr_char_info* p/*not 
NULL*/);
 
 /** Returns the slot index that before this character is before in the slot 
stream
   *
+  * In effect each character is associated with a set of slots and this returns
+  * the index of the first slot in the segment this character is associated 
with.
+  *
   * @return before slot index between 0 and gr_seg_n_slots()
   * @param p Pointer to charinfo to return information on.
   */
@@ -340,34 +352,42 @@ GR2_API float gr_slot_origin_Y(const gr_slot* p);
   *
   * @param p    Slot to give results for
   * @param face gr_face of the glyphs. May be NULL if unhinted advances used
-  * @param font gr_font to scale for pixel results. If NULL returns design 
units advance. If not NULL then returns pixel advance based on hinted or scaled 
glyph advances in the font. face must be passed for hinted advances to be used.
+  * @param font gr_font to scale for pixel results. If NULL returns design
+  *             units advance. If not NULL then returns pixel advance based
+  *             on hinted or scaled glyph advances in the font. face must be
+  *             passed for hinted advances to be used.
   */
 GR2_API float gr_slot_advance_X(const gr_slot* p, const gr_face* face, const 
gr_font *font);
 
 /** Returns the vertical advance for the glyph in the slot adjusted for kerning
   *
-  * Returns design units unless font is not NULL in which case the pixel value 
is returned scaled for the given font
+  * Returns design units unless font is not NULL in which case the pixel value
+  * is returned scaled for the given font
   */
 GR2_API float gr_slot_advance_Y(const gr_slot* p, const gr_face* face, const 
gr_font *font);
 
 /** Returns the gr_char_info index before us
   *
   * Returns the index of the gr_char_info that a cursor before this slot, 
would put
-  * an underlying cursor before.
+  * an underlying cursor before. This may also be interpretted as each slot 
holding
+  * a set of char_infos that it is associated with and this function returning 
the
+  * index of the char_info with lowest index, from this set.
   */
 GR2_API int gr_slot_before(const gr_slot* p/*not NULL*/);
 
 /** Returns the gr_char_info index after us
   *
   * Returns the index of the gr_char_info that a cursor after this slot would 
put an
-  * underlying cursor after.
+  * underlying cursor after. This may also be interpretted as each slot 
holding a set
+  * of char_infos that it is associated with and this function returning the 
index of
+  * the char_info with the highest index, from this set.
   */
 GR2_API int gr_slot_after(const gr_slot* p/*not NULL*/);
 
 /** Returns the index of this slot in the segment
   *
-  * Returns the index given to this slot during final positioning. This 
corresponds to the value returned br gr_cinfo_before()
-  * and gr_cinfo_after()
+  * Returns the index given to this slot during final positioning. This 
corresponds
+  * to the value returned br gr_cinfo_before() and gr_cinfo_after()
   */
 GR2_API unsigned int gr_slot_index(const gr_slot* p/*not NULL*/);
 
@@ -383,8 +403,8 @@ GR2_API int gr_slot_can_insert_before(const gr_slot* p);
 
 /** Returns the original gr_char_info index this slot refers to.
   *
-  * Each Slot has a gr_char_info that it originates from. This is that 
gr_char_info. The index is passed to gr_seg_cinfo(). This
-  * information is useful for testing.
+  * Each Slot has a gr_char_info that it originates from. This is that 
gr_char_info.
+  * The index is passed to gr_seg_cinfo(). This information is useful for 
testing.
   */
 GR2_API int gr_slot_original(const gr_slot* p/*not NULL*/);
 
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 1b48546..ef0f8a7 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -103,7 +103,7 @@ set_target_properties(graphite2 PROPERTIES  PUBLIC_HEADER 
"${GRAPHITE_HEADERS}"
 
 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 -fdiagnostics-show-option 
-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"
         LINK_FLAGS      "-nodefaultlibs" 
         LINKER_LANGUAGE C)
     if (${CMAKE_CXX_COMPILER} MATCHES  ".*mingw.*")
@@ -119,7 +119,7 @@ endif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
 
 if  (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
     set_target_properties(graphite2 PROPERTIES 
-        COMPILE_FLAGS   "-Wall -Wextra -Wno-unknown-pragmas -Wendif-labels 
-Wshadow -Wno-ctor-dtor-privacy -Wno-non-virtual-dtor -fdiagnostics-show-option 
-fno-rtti -fno-exceptions -fvisibility=hidden -fvisibility-inlines-hidden 
-fno-stack-protector"
+        COMPILE_FLAGS   "-Wall -Wextra -Wno-unknown-pragmas -Wendif-labels 
-Wshadow -Wno-ctor-dtor-privacy -Wno-non-virtual-dtor -fno-rtti -fno-exceptions 
-fvisibility=hidden -fvisibility-inlines-hidden -fno-stack-protector"
         LINK_FLAGS      "-nodefaultlibs" 
         LINKER_LANGUAGE C)
     target_link_libraries(graphite2 c)
diff --git a/src/Face.cpp b/src/Face.cpp
index 4566025..3428aea 100644
--- a/src/Face.cpp
+++ b/src/Face.cpp
@@ -53,7 +53,7 @@ Face::Face(const void* appFaceHandle/*non-NULL*/, const 
gr_face_ops & ops)
   m_descent(0)
 {
     memset(&m_ops, 0, sizeof m_ops);
-    memcpy(&m_ops, &ops, std::min(sizeof m_ops, ops.size));
+    memcpy(&m_ops, &ops, min(sizeof m_ops, ops.size));
 }
 
 
@@ -91,7 +91,7 @@ bool Face::readGlyphs(uint32 faceOptions)
        return false;
 
     if (faceOptions & gr_face_preloadGlyphs)
-        nameTable();        // preload the name table along with the glyphs, 
heh.
+        nameTable();        // preload the name table along with the glyphs.
 
     return true;
 }
diff --git a/src/FeatureMap.cpp b/src/FeatureMap.cpp
index c625950..aa638d5 100644
--- a/src/FeatureMap.cpp
+++ b/src/FeatureMap.cpp
@@ -185,23 +185,23 @@ bool SillMap::readFace(const Face & face)
 bool SillMap::readSill(const Face & face)
 {
        const Face::Table sill(face, TtfUtil::Tag::Sill);
-    const byte *pSill = sill;
+    const byte *p = sill;
 
-    if (!pSill) return true;
+    if (!p) return true;
     if (sill.size() < 12) return false;
-    if (be::read<uint32>(pSill) != 0x00010000UL) return false;
-    m_numLanguages = be::read<uint16>(pSill);
+    if (be::read<uint32>(p) != 0x00010000UL) return false;
+    m_numLanguages = be::read<uint16>(p);
     m_langFeats = new LangFeaturePair[m_numLanguages];
     if (!m_langFeats || !m_FeatureMap.m_numFeats) { m_numLanguages = 0; return 
true; }        //defensive
 
-    pSill += 6;     // skip the fast search
+    p += 6;     // skip the fast search
     if (sill.size() < m_numLanguages * 8U + 12) return false;
 
     for (int i = 0; i < m_numLanguages; i++)
     {
-        uint32 langid = be::read<uint32>(pSill);
-        uint16 numSettings = be::read<uint16>(pSill);
-        uint16 offset = be::read<uint16>(pSill);
+        uint32 langid = be::read<uint32>(p);
+        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);
         const byte *pLSet = sill + offset;
diff --git a/src/FileFace.cpp b/src/FileFace.cpp
index 1e37763..dc2f017 100644
--- a/src/FileFace.cpp
+++ b/src/FileFace.cpp
@@ -25,20 +25,13 @@ License, as published by the Free Software Foundation, 
either version 2
 of the License or (at your option) any later version.
 */
 #include <cstring>
-//#include "graphite2/Segment.h"
-//#include "inc/CmapCache.h"
-//#include "inc/Endian.h"
 #include "inc/FileFace.h"
-//#include "inc/GlyphFace.h"
-//#include "inc/SegCacheStore.h"
-//#include "inc/Segment.h"
-//#include "inc/NameTable.h"
 
 
-using namespace graphite2;
-
 #ifndef GRAPHITE2_NFILEFACE
 
+using namespace graphite2;
+
 FileFace::FileFace(const char *filename)
 : _file(fopen(filename, "rb")),
   _file_len(0),
diff --git a/src/Font.cpp b/src/Font.cpp
index b090bb0..8860d3b 100644
--- a/src/Font.cpp
+++ b/src/Font.cpp
@@ -24,7 +24,6 @@ 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 "inc/Face.h"
 #include "inc/Font.h"
 #include "inc/GlyphCache.h"
@@ -39,7 +38,7 @@ Font::Font(float ppm, const Face & f, const void * 
appFontHandle, const gr_font_
 {
     memset(&m_ops, 0, sizeof m_ops);
     if (m_hinted)
-        memcpy(&m_ops, ops, std::min(sizeof m_ops, ops->size));
+        memcpy(&m_ops, ops, min(sizeof m_ops, ops->size));
     else
         m_ops.glyph_advance_x = &Face::default_glyph_advance;
 
diff --git a/src/GlyphCache.cpp b/src/GlyphCache.cpp
index 7f30447..457397b 100644
--- a/src/GlyphCache.cpp
+++ b/src/GlyphCache.cpp
@@ -24,8 +24,6 @@ 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 "graphite2/Font.h"
 
 #include "inc/Main.h"
@@ -175,17 +173,15 @@ const GlyphFace *GlyphCache::glyph(unsigned short 
glyphid) const      //result m
     {
         GlyphFace * g = new GlyphFace();
         if (g)  p = _glyph_loader->read_glyph(glyphid, *g);
+        if (!p)
+        {
+            delete g;
+            return *_glyphs;
+        }
     }
     return p;
 }
 
-uint16 GlyphCache::glyphAttr(uint16 gid, uint16 gattr) const
-{
-       const GlyphFace * p = glyphSafe(gid);
-
-       return p && gattr < _num_attrs ? p->attrs()[gattr] : 0;
-}
-
 
 
 GlyphCache::Loader::Loader(const Face & face, const bool dumb_font)
@@ -236,7 +232,7 @@ GlyphCache::Loader::Loader(const Face & face, const bool 
dumb_font)
                                        / (_long_fmt ? sizeof(uint32) : 
sizeof(uint16)) - 1;
 
         if (version != 0x00010000
-            || _num_attrs == 0 || _num_attrs > 0x1000  // is this hard limit 
appropriate?
+            || _num_attrs == 0 || _num_attrs > 0x3000  // is this hard limit 
appropriate?
             || _num_glyphs_graphics > _num_glyphs_attributes)
         {
             _head = Face::Table();
@@ -260,7 +256,7 @@ unsigned short int GlyphCache::Loader::units_per_em() const 
throw()
 inline
 unsigned short int GlyphCache::Loader::num_glyphs() const throw()
 {
-    return std::max(_num_glyphs_graphics, _num_glyphs_attributes);
+    return max(_num_glyphs_graphics, _num_glyphs_attributes);
 }
 
 inline
@@ -308,7 +304,7 @@ 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 >= m_pGlat.size() || gloce > m_pGlat.size())
             return 0;
 
         const uint32 glat_version = be::peek<uint32>(m_pGlat);
@@ -333,11 +329,8 @@ const GlyphFace * GlyphCache::Loader::read_glyph(unsigned 
short glyphid, GlyphFa
             new (&glyph) GlyphFace(bbox, advance, glat2_iterator(m_pGlat + 
glocs), glat2_iterator(m_pGlat + gloce));
         }
 
-        if (glyph.attrs().size() > _num_attrs)
-        {
-            glyph.~GlyphFace();
+        if (glyph.attrs().capacity() > _num_attrs)
             return 0;
-        }
     }
 
     return &glyph;
diff --git a/src/Pass.cpp b/src/Pass.cpp
index 51fabc8..a44648a 100644
--- a/src/Pass.cpp
+++ b/src/Pass.cpp
@@ -275,16 +275,19 @@ bool Pass::readRanges(const byte * ranges, size_t 
num_ranges)
     memset(m_cols, 0xFF, m_numGlyphs * sizeof(uint16));
     for (size_t n = num_ranges; n; --n)
     {
-        const uint16 first = be::read<uint16>(ranges),
-                     last  = be::read<uint16>(ranges),
-                     col   = be::read<uint16>(ranges);
-        uint16 *p;
+        uint16     * ci     = m_cols + be::read<uint16>(ranges),
+                   * ci_end = m_cols + be::read<uint16>(ranges) + 1,
+                     col    = be::read<uint16>(ranges);
 
-        if (first > last || last >= m_numGlyphs || col >= m_sColumns)
+        if (ci >= ci_end || ci_end > m_cols+m_numGlyphs || col >= m_sColumns)
             return false;
 
-        for (p = m_cols + first; p <= m_cols + last; )
-            *p++ = col;
+        // A glyph must only belong to one column at a time
+        while (ci != ci_end && *ci == 0xffff)
+            *ci++ = col;
+
+        if (ci != ci_end)
+            return false;
     }
     return true;
 }
diff --git a/src/Segment.cpp b/src/Segment.cpp
index 8b54198..6893c31 100644
--- a/src/Segment.cpp
+++ b/src/Segment.cpp
@@ -139,14 +139,7 @@ void Segment::appendSlot(int id, int cid, int gid, int 
iFeats, size_t coffset)
     m_charinfo[id].feats(iFeats);
     m_charinfo[id].base(coffset);
     const GlyphFace * theGlyph = m_face->glyphs().glyphSafe(gid);
-    if (theGlyph)
-    {
-        m_charinfo[id].breakWeight(theGlyph->attrs()[m_silf->aBreak()]);
-    }
-    else
-    {
-        m_charinfo[id].breakWeight(0);
-    }
+    m_charinfo[id].breakWeight(theGlyph ? theGlyph->attrs()[m_silf->aBreak()] 
: 0);
     
     aSlot->child(NULL);
     aSlot->setGlyph(this, gid, theGlyph);
@@ -192,6 +185,13 @@ void Segment::freeSlot(Slot *aSlot)
 {
     if (m_last == aSlot) m_last = aSlot->prev();
     if (m_first == aSlot) m_first = aSlot->next();
+    if (aSlot->attachedTo())
+        aSlot->attachedTo()->removeChild(aSlot);
+    while (aSlot->firstChild())
+    {
+        aSlot->firstChild()->attachTo(NULL);
+        aSlot->removeChild(aSlot->firstChild());
+    }
     // reset the slot incase it is reused
     ::new (aSlot) Slot;
     memset(aSlot->userAttrs(), 0, m_silf->numUser() * sizeof(int16));
diff --git a/src/Silf.cpp b/src/Silf.cpp
index 96d78e7..53c1384 100644
--- a/src/Silf.cpp
+++ b/src/Silf.cpp
@@ -133,8 +133,8 @@ bool Silf::readGraphite(const byte * const silf_start, 
size_t lSilf, const Face&
     be::skip<byte>(p);                                                 // 
reserved
     if (p >= silf_end)   { releaseBuffers(); return false; }
     be::skip<uint32>(p, be::read<uint8>(p));   // don't use scriptTag array.
+    if (p + sizeof(uint16) + sizeof(uint32) >= silf_end)  { releaseBuffers(); 
return false; }
     m_gEndLine  = be::read<uint16>(p);          // lbGID
-    if (p >= silf_end)   { releaseBuffers(); return false; }
     const byte * o_passes = p,
                * const passes_start = silf_start + be::read<uint32>(p);
 
diff --git a/src/Slot.cpp b/src/Slot.cpp
index f78fee7..d7e0778 100644
--- a/src/Slot.cpp
+++ b/src/Slot.cpp
@@ -144,7 +144,7 @@ Position Slot::finalise(const Segment *seg, const Font 
*font, Position & base, R
     return res;
 }
 
-uint32 Slot::clusterMetric(const Segment *seg, uint8 metric, uint8 attrLevel)
+int32 Slot::clusterMetric(const Segment *seg, uint8 metric, uint8 attrLevel)
 {
     Position base;
     Rect bbox = seg->theGlyphBBoxTemporary(gid());
@@ -247,7 +247,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 && other->child(this))
+            if (other == this) break;
+            if (m_parent) m_parent->removeChild(this);
+            if (other->child(this))
             {
                 attachTo(other);
                 if (((seg->dir() & 1) != 0) ^ (idx > subindex))
@@ -345,6 +347,34 @@ bool Slot::sibling(Slot *ap)
     return true;
 }
 
+bool Slot::removeChild(Slot *ap)
+{
+    if (this == ap || !m_child) return false;
+    else if (ap == m_child)
+    {
+        Slot *nSibling = m_child->nextSibling();
+        m_child->sibling(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)
+    {
+        m_sibling = m_sibling->nextSibling();
+        return true;
+    }
+    else
+        return m_sibling->removeSibling(ap);
+    return true;
+}
+
 void Slot::setGlyph(Segment *seg, uint16 glyphid, const GlyphFace * theGlyph)
 {
     m_glyphid = glyphid;
diff --git a/src/Sparse.cpp b/src/Sparse.cpp
index 64675a2..a3eb52a 100644
--- a/src/Sparse.cpp
+++ b/src/Sparse.cpp
@@ -39,15 +39,16 @@ sparse::~sparse() throw()
 
 sparse::mapped_type sparse::operator [] (const key_type k) const throw()
 {
-       const chunk &           c = m_array.map[k/SIZEOF_CHUNK];
+    mapped_type         g = key_type(k/SIZEOF_CHUNK - m_nchunks) >> (sizeof 
k*8 - 1);
+       const chunk &           c = m_array.map[g*k/SIZEOF_CHUNK];
        const mask_t            m = c.mask >> (SIZEOF_CHUNK - 1 - 
(k%SIZEOF_CHUNK));
-       const mapped_type   g = m & 1;
+       g *= m & 1;
 
        return g*m_array.values[g*(c.offset + bit_set_count(m >> 1))];
 }
 
 
-size_t sparse::size() const throw()
+size_t sparse::capacity() const throw()
 {
        size_t n = m_nchunks,
                   s = 0;
diff --git a/src/TtfUtil.cpp b/src/TtfUtil.cpp
index dbd1d5b..9ede99e 100644
--- a/src/TtfUtil.cpp
+++ b/src/TtfUtil.cpp
@@ -709,10 +709,8 @@ int PostLookup(const void * pPost, size_t lPostSize, const 
void * pMaxp,
                                if 
(be::swap(pTable2->glyph_name_index[nGlyphId]) == iPostName)
                                        return nGlyphId;
                        }
-                       return -1; // no glyph with this standard name
                }
 
-               else
                { // did not match a standard name, search font specific names
                        size_t nStrSizeGoal = strlen(pPostName);
                        const char * pFirstGlyphName = reinterpret_cast<const 
char *>(
diff --git a/src/inc/FeatureMap.h b/src/inc/FeatureMap.h
index ffc58c9..dc5175c 100644
--- a/src/inc/FeatureMap.h
+++ b/src/inc/FeatureMap.h
@@ -25,9 +25,6 @@ License, as published by the Free Software Foundation, either 
version 2
 of the License or (at your option) any later version.
 */
 #pragma once
-// #include <cstring>
-// #include "graphite2/Types.h"
-//#include "graphite2/Font.h"
 #include "inc/Main.h"
 #include "inc/FeatureVal.h"
 
diff --git a/src/inc/GlyphCache.h b/src/inc/GlyphCache.h
index 4f000dc..7445715 100644
--- a/src/inc/GlyphCache.h
+++ b/src/inc/GlyphCache.h
@@ -48,13 +48,12 @@ public:
     GlyphCache(const Face & face, const uint32 face_options);
     ~GlyphCache();
 
-    size_t numGlyphs() const throw();
-    size_t numAttrs() const throw();
-    size_t unitsPerEm() const throw();
+    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;
-    uint16 glyphAttr(uint16 gid, uint16 gattr) const;
 
     CLASS_NEW_DELETE;
     
@@ -67,19 +66,19 @@ private:
 };
 
 inline
-size_t GlyphCache::numGlyphs() const throw()
+unsigned short GlyphCache::numGlyphs() const throw()
 {
     return _num_glyphs;
 }
 
 inline
-size_t GlyphCache::numAttrs() const throw()
+unsigned short GlyphCache::numAttrs() const throw()
 {
     return _num_attrs;
 }
 
 inline
-size_t GlyphCache::unitsPerEm() const throw()
+unsigned short  GlyphCache::unitsPerEm() const throw()
 {
     return _upem;
 }
diff --git a/src/inc/Machine.h b/src/inc/Machine.h
index 655d606..f6af443 100644
--- a/src/inc/Machine.h
+++ b/src/inc/Machine.h
@@ -36,7 +36,7 @@ of the License or (at your option) any later version.
 #include "inc/Main.h"
 
 #if defined(__GNUC__)
-#if defined(__clang__)
+#if defined(__clang__) || (__GNUC__ * 100 + __GNUC_MINOR__ * 10) < 430
 #define     HOT
 #if defined(__x86_64)
 #define     REGPARM(n)      __attribute__((regparm(n)))
diff --git a/src/inc/Main.h b/src/inc/Main.h
index 6ddaf37..674af80 100644
--- a/src/inc/Main.h
+++ b/src/inc/Main.h
@@ -56,6 +56,18 @@ template <typename T> T * grzeroalloc(size_t n)
     return reinterpret_cast<T*>(calloc(n, sizeof(T)));
 }
 
+template <typename T>
+inline T min(const T a, const T b)
+{
+    return a < b ? a : b;
+}
+
+template <typename T>
+inline T max(const T a, const T b)
+{
+    return a > b ? a : b;
+}
+
 } // namespace graphite2
 
 #define CLASS_NEW_DELETE \
diff --git a/src/inc/Pass.h b/src/inc/Pass.h
index 64d0716..6554d93 100644
--- a/src/inc/Pass.h
+++ b/src/inc/Pass.h
@@ -56,7 +56,6 @@ private:
     int        doAction(const vm::Machine::Code* codeptr, Slot * & slot_out, 
vm::Machine &) const;
     bool       testPassConstraint(vm::Machine & m) const;
     bool       testConstraint(const Rule & r, vm::Machine &) const;
-    bool       readFSM(const byte* p, const byte*const pass_start, const 
size_t max_offset);
     bool       readRules(const byte * rule_map, const size_t num_entries,
                      const byte *precontext, const uint16 * sort_key,
                      const uint16 * o_constraint, const byte *constraint_data, 
diff --git a/src/inc/Segment.h b/src/inc/Segment.h
index a2ff6d0..a36fb73 100644
--- a/src/inc/Segment.h
+++ b/src/inc/Segment.h
@@ -123,8 +123,8 @@ public:
     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 dir(int8 val) { m_dir = val; }
-    uint16 glyphAttr(uint16 gid, uint16 gattr) const { return 
m_face->glyphs().glyphAttr(gid, gattr); }
-    uint16 getGlyphMetric(Slot *iSlot, uint8 metric, uint8 attrLevel) const;
+    int16 glyphAttr(uint16 gid, uint16 gattr) const { const GlyphFace * p = 
m_face->glyphs().glyphSafe(gid); return p ? p->attrs()[gattr] : 0; }
+    int32 getGlyphMetric(Slot *iSlot, uint8 metric, uint8 attrLevel) const;
     float glyphAdvance(uint16 gid) const { return 
m_face->glyphs().glyph(gid)->theAdvance().x; }
     const Rect &theGlyphBBoxTemporary(uint16 gid) const { return 
m_face->glyphs().glyph(gid)->theBBox(); }   //warning value may become invalid 
when another glyph is accessed
     Slot *findRoot(Slot *is) const { return is->attachedTo() ? 
findRoot(is->attachedTo()) : is; }
@@ -150,8 +150,8 @@ public:       //only used by: GrSegment* 
makeAndInitialize(const GrFont *font, c
 private:
     Rect            m_bbox;             // ink box of the segment
     Position        m_advance;          // whole segment advance
-    SlotRope        m_slots;            // std::vector of slot buffers
-    AttributeRope   m_userAttrs;        // std::vector of userAttrs buffers
+    SlotRope        m_slots;            // Vector of slot buffers
+    AttributeRope   m_userAttrs;        // Vector of userAttrs buffers
     JustifyRope     m_justifies;        // Slot justification info buffers
     FeatureList     m_feats;            // feature settings referenced by 
charinfos in this segment
     Slot          * m_freeSlots;        // linked list of free slots
@@ -181,7 +181,7 @@ void Segment::finalise(const Font *font)
 }
 
 inline
-uint16 Segment::getGlyphMetric(Slot *iSlot, uint8 metric, uint8 attrLevel) 
const {
+int32 Segment::getGlyphMetric(Slot *iSlot, uint8 metric, uint8 attrLevel) 
const {
     if (attrLevel > 0)
     {
         Slot *is = findRoot(iSlot);
diff --git a/src/inc/Silf.h b/src/inc/Silf.h
index 7245907..652f084 100644
--- a/src/inc/Silf.h
+++ b/src/inc/Silf.h
@@ -78,7 +78,7 @@ public:
     uint16 findClassIndex(uint16 cid, uint16 gid) const;
     uint16 getClassGlyph(uint16 cid, unsigned int index) const;
     uint16 findPseudo(uint32 uid) const;
-    size_t numUser() const { return m_aUser; }
+    uint8 numUser() const { return m_aUser; }
     uint8 aPseudo() const { return m_aPseudo; }
     uint8 aBreak() const { return m_aBreak; }
     uint8 aMirror() const {return m_aMirror; }
@@ -86,11 +86,11 @@ public:
     uint8 positionPass() const { return m_pPass; }
     uint8 justificationPass() const { return m_jPass; }
     uint8 bidiPass() const { return m_bPass; }
-    size_t numPasses() const { return m_numPasses; }
-    size_t maxCompPerLig() const { return m_iMaxComp; }
-    size_t numClasses() const { return m_nClass; }
-    uint8 flags() const { return m_flags; }
-    size_t numJustLevels() const { return m_numJusts; }
+    uint8 numPasses() const { return m_numPasses; }
+    uint8 maxCompPerLig() const { return m_iMaxComp; }
+    uint16 numClasses() const { return m_nClass; }
+    byte  flags() const { return m_flags; }
+    uint8 numJustLevels() const { return m_numJusts; }
     Justinfo *justAttrs() const { return m_justs; }
     uint16 endLineGlyphid() const { return m_gEndLine; }
     const gr_faceinfo *silfInfo() const { return &m_silfinfo; }
diff --git a/src/inc/Slot.h b/src/inc/Slot.h
index 285d7f1..3f0c473 100644
--- a/src/inc/Slot.h
+++ b/src/inc/Slot.h
@@ -125,7 +125,9 @@ public:
     bool child(Slot *ap);
     Slot* nextSibling() const { return m_sibling; }
     bool sibling(Slot *ap);
-    uint32 clusterMetric(const Segment* seg, uint8 metric, uint8 attrLevel);
+    bool removeChild(Slot *ap);
+    bool removeSibling(Slot *ap);
+    int32 clusterMetric(const Segment* seg, uint8 metric, uint8 attrLevel);
     void positionShift(Position a) { m_position += a; }
     void floodShift(Position adj);
     float just() const { return m_just; }
diff --git a/src/inc/Sparse.h b/src/inc/Sparse.h
index 2eca5b6..bbe6bcf 100644
--- a/src/inc/Sparse.h
+++ b/src/inc/Sparse.h
@@ -33,7 +33,11 @@ of the License or (at your option) any later version.
 namespace graphite2 {
 
 
-
+// A read-only packed fast sparse array of uint16 with uint16 keys.
+// Like most container classes this has capacity and size properties and these
+// refer to the number of stored entries and the number of addressable entries
+// as normal. However due the sparse nature the capacity is always <= than the
+// size.
 class sparse
 {
 public:
@@ -64,6 +68,7 @@ public:
        operator bool () const throw();
        mapped_type     operator [] (const key_type k) const throw();
 
+       size_t capacity() const throw();
        size_t size()     const throw();
 
        size_t _sizeof() const throw();
@@ -137,11 +142,16 @@ sparse::operator bool () const throw()
        return m_array.map != 0;
 }
 
+inline
+size_t sparse::size() const throw()
+{
+    return m_nchunks*SIZEOF_CHUNK;
+}
 
 inline
 size_t sparse::_sizeof() const throw()
 {
-       return sizeof(sparse) + size()*sizeof(mapped_type) + 
m_nchunks*sizeof(chunk);
+       return sizeof(sparse) + capacity()*sizeof(mapped_type) + 
m_nchunks*sizeof(chunk);
 }
 
 } // namespace graphite2
diff --git a/src/inc/bits.h b/src/inc/bits.h
index aec2a00..56b2d10 100644
--- a/src/inc/bits.h
+++ b/src/inc/bits.h
@@ -26,6 +26,9 @@ of the License or (at your option) any later version.
 */
 #pragma once
 
+namespace graphite2
+{
+
 template<typename T>
 inline unsigned int bit_set_count(T v)
 {
@@ -72,16 +75,16 @@ inline unsigned int log_binary(T v)
 }
 
 template<typename T>
-inline T haszero(const T x)
+inline T has_zero(const T x)
 {
        return (x - T(~T(0)/255)) & ~x & T(~T(0)/255*128);
 }
 
 template<typename T>
-inline T zerobytes(const T x, unsigned char n)
+inline T zero_bytes(const T x, unsigned char n)
 {
        const T t = T(~T(0)/255*n);
-       return T((haszero(x^t) >> 7)*n);
+       return T((has_zero(x^t) >> 7)*n);
 }
 
-
+}
diff --git a/src/inc/opcode_table.h b/src/inc/opcode_table.h
index efab472..06916f6 100644
--- a/src/inc/opcode_table.h
+++ b/src/inc/opcode_table.h
@@ -55,8 +55,8 @@ static const opcode_t opcode_table[] =
     {{do2(sub)},                                    0, "SUB"},
     {{do2(mul)},                                    0, "MUL"},
     {{do2(div_)},                                   0, "DIV"},
-    {{do2(min)},                                    0, "MIN"},
-    {{do2(max)},                                    0, "MAX"},
+    {{do2(min_)},                                   0, "MIN"},
+    {{do2(max_)},                                   0, "MAX"},
     {{do2(neg)},                                    0, "NEG"},
     {{do2(trunc8)},                                 0, "TRUNC8"},
     {{do2(trunc16)},                                0, "TRUNC16"},
@@ -114,7 +114,7 @@ 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
-    // private internal private opcodes for internal use only, comes after all 
other on disk opcodes.
+    // private opcodes for internal use only, comes after all other on disk 
opcodes.
     {{do_(temp_copy), NILOP},                       0, "TEMP_COPY"}
 };
 
diff --git a/src/inc/opcodes.h b/src/inc/opcodes.h
index 6127c8f..835e893 100644
--- a/src/inc/opcodes.h
+++ b/src/inc/opcodes.h
@@ -132,12 +132,12 @@ STARTOP(div_)
     binop(/);
 ENDOP
 
-STARTOP(min)
+STARTOP(min_)
     const int32 a = pop(), b = *sp;
     if (a < b) *sp = a;
 ENDOP
 
-STARTOP(max)
+STARTOP(max_)
     const int32 a = pop(), b = *sp;
     if (a > b) *sp = a;
 ENDOP
@@ -443,7 +443,7 @@ STARTOP(push_glyph_attr_obs)
     const int           slot_ref   = int8(param[1]);
     slotref slot = slotat(slot_ref);
     if (slot)
-        push(seg.glyphAttr(slot->gid(), glyph_attr));
+        push(int32(seg.glyphAttr(slot->gid(), glyph_attr)));
 ENDOP
 
 STARTOP(push_glyph_metric)
@@ -477,7 +477,7 @@ STARTOP(push_att_to_gattr_obs)
     {
         slotref att = slot->attachedTo();
         if (att) slot = att;
-        push(seg.glyphAttr(slot->gid(), glyph_attr));
+        push(int32(seg.glyphAttr(slot->gid(), glyph_attr)));
     }
 ENDOP
 
@@ -491,7 +491,7 @@ STARTOP(push_att_to_glyph_metric)
     {
         slotref att = slot->attachedTo();
         if (att) slot = att;
-        push(seg.getGlyphMetric(slot, glyph_attr, attr_level));
+        push(int32(seg.getGlyphMetric(slot, glyph_attr, attr_level)));
     }
 ENDOP
 
@@ -616,7 +616,7 @@ STARTOP(push_glyph_attr)
     const int           slot_ref    = int8(param[2]);
     slotref slot = slotat(slot_ref);
     if (slot)
-        push(seg.glyphAttr(slot->gid(), glyph_attr));
+        push(int32(seg.glyphAttr(slot->gid(), glyph_attr)));
 ENDOP
 
 STARTOP(push_att_to_glyph_attr)
@@ -629,7 +629,7 @@ STARTOP(push_att_to_glyph_attr)
     {
         slotref att = slot->attachedTo();
         if (att) slot = att;
-        push(seg.glyphAttr(slot->gid(), glyph_attr));
+        push(int32(seg.glyphAttr(slot->gid(), glyph_attr)));
     }
 ENDOP
 
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index be54129..e7510e1 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -39,12 +39,12 @@ if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
                             COMPILE_DEFINITIONS 
"GRAPHITE2_STATIC;GRAPHITE2_NTRACING;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;UNICODE")
 else (${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
     set_target_properties(graphite2-base PROPERTIES 
-        COMPILE_FLAGS       "-Wall -Wextra -fdiagnostics-show-option -fno-rtti 
-fno-exceptions -fno-stack-protector"
+        COMPILE_FLAGS       "-Wall -Wextra -fno-rtti -fno-exceptions 
-fno-stack-protector"
         COMPILE_DEFINITIONS "GRAPHITE2_STATIC"
         LINK_FLAGS          "-nodefaultlibs" 
         LINKER_LANGUAGE     C)
     set_target_properties(graphite2-segcache PROPERTIES 
-        COMPILE_FLAGS       "-Wall -Wextra -fdiagnostics-show-option -fno-rtti 
-fno-exceptions -fno-stack-protector"
+        COMPILE_FLAGS       "-Wall -Wextra -fno-rtti -fno-exceptions 
-fno-stack-protector"
         COMPILE_DEFINITIONS "GRAPHITE2_STATIC;GRAPHITE2_NTRACING"
         LINK_FLAGS          "-nodefaultlibs" 
         LINKER_LANGUAGE     C)
diff --git a/tests/comparerenderer/CompareRenderer.cpp 
b/tests/comparerenderer/CompareRenderer.cpp
index 79db0bf..8b46678 100644
--- a/tests/comparerenderer/CompareRenderer.cpp
+++ b/tests/comparerenderer/CompareRenderer.cpp
@@ -341,7 +341,7 @@ int main(int argc, char ** argv)
     int direction = (rendererOptions[OptRtl].exists())? 1 : 0;
     int segCacheSize = rendererOptions[OptSegCache].getInt(argv);
     const std::string traceLogPath = rendererOptions[OptTrace].exists() ? 
rendererOptions[OptTrace].get(argv) : std::string();
-       Gr2Face face(fontFile, segCacheSize, traceLogPath);
+       Gr2Face face(fontFile, segCacheSize, traceLogPath, 
rendererOptions[OptDemand].get(argv));
 
 
     if (rendererOptions[OptFeatures].exists())
@@ -369,7 +369,7 @@ int main(int argc, char ** argv)
         {
             std::string altTraceLogPath = traceLogPath;
             altTraceLogPath.insert(traceLogPath.find_last_of('.'), ".alt");
-               Gr2Face altFace(altFontFile, segCacheSize, altTraceLogPath);
+               Gr2Face altFace(altFontFile, segCacheSize, altTraceLogPath, 
rendererOptions[OptDemand].get(argv));
 
             renderers[0] = new Gr2Renderer(face, fontSize, direction, 
featureSettings);
             renderers[1] = new Gr2Renderer(altFace, fontSize, direction, 
altFeatureSettings);
@@ -422,7 +422,7 @@ int main(int argc, char ** argv)
         if (rendererOptions[OptGraphite2s].exists())
         {
                Gr2Face uncached(fontFile, 0,
-                               
std::string(traceLogPath).insert(traceLogPath.find_last_of('.'), ".uncached"));
+                               
std::string(traceLogPath).insert(traceLogPath.find_last_of('.'), ".uncached"), 
rendererOptions[OptDemand].get(argv));
             renderers[2] = new Gr2Renderer(uncached, fontSize, direction, 
featureSettings);
         }
 
diff --git a/tests/comparerenderer/Gr2Renderer.h 
b/tests/comparerenderer/Gr2Renderer.h
index cd3f6e0..1655354 100644
--- a/tests/comparerenderer/Gr2Renderer.h
+++ b/tests/comparerenderer/Gr2Renderer.h
@@ -35,10 +35,10 @@ class Gr2Face : private std::auto_ptr<gr_face>
        bool m_cached;
 
 public:
-       Gr2Face(const char * fontFile, int cache, const std::string & logPath)
+       Gr2Face(const char * fontFile, int cache, const std::string & logPath, 
const bool demand_load)
     :  std::auto_ptr<gr_face>(cache == 0
-          ? gr_make_file_face(fontFile, gr_face_preloadGlyphs)
-          : gr_make_file_face_with_seg_cache(fontFile, cache, 
gr_face_cacheCmap | gr_face_preloadGlyphs)),
+          ? gr_make_file_face(fontFile, !demand_load ? gr_face_preloadGlyphs : 
gr_face_default)
+          : gr_make_file_face_with_seg_cache(fontFile, cache, (!demand_load ? 
gr_face_preloadGlyphs : gr_face_default) | gr_face_cacheCmap)),
        m_cached(cache > 0)
        {
         if (!get()) return;
diff --git a/tests/comparerenderer/RendererOptions.h 
b/tests/comparerenderer/RendererOptions.h
index adef99c..84e029f 100644
--- a/tests/comparerenderer/RendererOptions.h
+++ b/tests/comparerenderer/RendererOptions.h
@@ -80,7 +80,7 @@ typedef enum {
     OptIgnoreGlyphIdDifferences,
     OptSegCache,
     OptTrace,
-    OptLogMask,
+    OptDemand,
     OptFeatures,
     OptAltFeatures,
     OptQuiet
@@ -107,8 +107,8 @@ static Option rendererOptions[] = {
     Option("-a", "--alt-font", "Alternative font file", Option::OPTION_STRING),
     Option("", "--ignore-gid", "Ignore Glyph IDs in comparison (use with -c -a 
alt.ttf)", Option::OPTION_BOOL),
     Option("", "--seg-cache", "Enable Segment Cache of given size", 
Option::OPTION_INT),
-    Option("", "--trace", "XML trace log file", Option::OPTION_STRING),
-    Option("", "--log-mask", "XML trace log mask (only used with --trace)", 
Option::OPTION_INT),
+    Option("", "--trace", "JSON trace log file", Option::OPTION_STRING),
+    Option("", "--demand", "Load glyphs on demand", Option::OPTION_BOOL),
     Option("", "--features", "Feature list", Option::OPTION_STRING),
     Option("", "--alt-features", "Feature list for alternative font (if 
different)", Option::OPTION_STRING),
     Option("-q", "--quiet", "Supress all output, including error messages", 
Option::OPTION_BOOL)
diff --git a/tests/examples/cluster.c b/tests/examples/cluster.c
index 3859e6f..06bf6d6 100644
--- a/tests/examples/cluster.c
+++ b/tests/examples/cluster.c
@@ -40,8 +40,8 @@ int main(int argc, char **argv)
     memset(clusters, 0, numCodePoints * sizeof(cluster_t));
     for (is = gr_seg_first_slot(seg), ic = 0; is; is = 
gr_slot_next_in_segment(is), ic++)
     {
-        unsigned int before = gr_slot_before(is);
-        unsigned int after = gr_slot_after(is);
+        unsigned int before = gr_cinfo_base(gr_seg_cinfo(seg, 
gr_slot_before(is)));
+        unsigned int after = gr_cinfo_base(gr_seg_cinfo(seg, 
gr_slot_after(is)));
         while (clusters[ci].base_char > before && ci)                          
     /*<2>*/
         {
             clusters[ci-1].num_chars += clusters[ci].num_chars;
diff --git a/tests/examples/linebreak.c b/tests/examples/linebreak.c
index 8a8ff28..20cb01a 100644
--- a/tests/examples/linebreak.c
+++ b/tests/examples/linebreak.c
@@ -3,6 +3,19 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+/* calculate the breakweight between two slots */
+int breakweight_before(const gr_slot *s, const gr_segment *seg)
+{
+    int bbefore = gr_cinfo_break_weight(gr_seg_cinfo(seg, 
gr_slot_after(gr_slot_prev_in_segment(s))));
+    int bafter = gr_cinfo_break_weight(gr_seg_cinfo(seg, gr_slot_before(s)));
+
+    if (!gr_slot_can_insert_before(s))
+        return 50;
+    if (bbefore < 0) bbefore = 0;
+    if (bafter > 0) bafter = 0;
+    return (bbefore > bafter) ? bbefore : bafter;
+}
+
 /* usage: ./linebreak fontfile.ttf width string */
 int main(int argc, char **argv)
 {
@@ -32,33 +45,28 @@ int main(int argc, char **argv)
 
     lineslots = (const gr_slot **)malloc(numCodePoints * sizeof(gr_slot *));
     lineslots[numlines++] = gr_seg_first_slot(seg);                            
 /*<2>*/
-    for (s = lineslots[0]; s; s = gr_slot_next_in_segment(s))
+    for (s = lineslots[0]; s; s = gr_slot_next_in_segment(s))                  
 /*<3>*/
     {
         sprev = NULL;
-        if (gr_slot_origin_X(s) > lineend)                                     
 /*<3>*/
+        if (gr_slot_origin_X(s) > lineend)                                     
 /*<4>*/
         {
-            for (sprev = gr_slot_prev_in_segment(s); sprev;                    
 /*<4>*/
-                                    s = sprev, sprev = 
gr_slot_prev_in_segment(sprev))
+            while (s)
             {
-                int bw = gr_cinfo_break_weight(gr_seg_cinfo(seg, 
gr_slot_before(s)));
-                if (bw < -15)                                                  
 /*<5>*/
-                    continue;
-                bw  = gr_cinfo_break_weight(gr_seg_cinfo(seg, 
gr_slot_after(sprev)));
-                if (bw > 15)
-                    continue;
-                break;
+                if (breakweight_before(s, seg) >= gr_breakWord)                
 /*<5>*/
+                    break;
+                s = gr_slot_prev_in_segment(s);                                
 /*<6>*/
             }
             lineslots[numlines++] = s;
-            gr_slot_linebreak_before((gr_slot *)s);                            
 /*<6>*/
-            lineend = gr_slot_origin_X(s) + width;                             
 /*<7>*/
+            gr_slot_linebreak_before((gr_slot *)s);                            
 /*<7>*/
+            lineend = gr_slot_origin_X(s) + width;                             
 /*<8>*/
         }
     }
 
     printf("%d:", width);
     for (i = 0; i < numlines; i++)
     {                                                                          
 
-        gr_seg_justify(seg, (gr_slot *)lineslots[i], font, width, 0, NULL, 
NULL); /*<8>*/
-        for (s = lineslots[i]; s; s = gr_slot_next_in_segment(s))              
 /*<9>*/
+        gr_seg_justify(seg, (gr_slot *)lineslots[i], font, width, 0, NULL, 
NULL); /*<9>*/
+        for (s = lineslots[i]; s; s = gr_slot_next_in_segment(s))              
 /*<10>*/
             printf("%d(%.2f,%.2f@%d) ", gr_slot_gid(s), gr_slot_origin_X(s), 
gr_slot_origin_Y(s), gr_slot_attr(s, seg, gr_slatJWidth, 0));
         printf("\n");
     }
diff --git a/tests/fuzz-tests/CMakeLists.txt b/tests/fuzz-tests/CMakeLists.txt
index dd2271c..b3a6fac 100644
--- a/tests/fuzz-tests/CMakeLists.txt
+++ b/tests/fuzz-tests/CMakeLists.txt
@@ -21,5 +21,7 @@ foreach (tfile IN LISTS tfiles)
     endif(NOT lastfontname EQUAL fname)
     add_custom_command(TARGET fuzztest PRE_BUILD COMMAND 
${PROJECT_SOURCE_DIR}/../fuzztest ARGS -l 
fuzzregress-${fname}-${textname}-${tname}.log -f 
${PROJECT_SOURCE_DIR}/../fonts/${fname}.ttf -t 10 -q --memory=200 
--include=required,graphite --exclude==fontdir,opentype,volt,advtypo,post 
--valgrind --input=${PROJECT_SOURCE_DIR}/${fname}/${textname}/${tname} -- 
../comparerenderer/comparerenderer -q -s 12 -n -f {} -t 
${PROJECT_SOURCE_DIR}/texts/${textname}.txt)
     add_custom_command(TARGET fuzztest POST_BUILD COMMAND perl ARGS -e 
'print"$$ARGV[0] Failed\\n" if(-s $$ARGV[0])' 
fuzzregress-${fname}-${textname}-${tname}.log)
+    add_custom_command(TARGET fuzztest PRE_BUILD COMMAND 
${PROJECT_SOURCE_DIR}/../fuzztest ARGS -l 
fuzzregress-demand-${fname}-${textname}-${tname}.log -f 
${PROJECT_SOURCE_DIR}/../fonts/${fname}.ttf -t 10 -q --memory=200 
--include=required,graphite --exclude==fontdir,opentype,volt,advtypo,post 
--valgrind --input=${PROJECT_SOURCE_DIR}/${fname}/${textname}/${tname} -- 
../comparerenderer/comparerenderer --demand -q -s 12 -n -f {} -t 
${PROJECT_SOURCE_DIR}/texts/${textname}.txt)
+    add_custom_command(TARGET fuzztest POST_BUILD COMMAND perl ARGS -e 
'print"$$ARGV[0] Failed\\n" if(-s $$ARGV[0])' 
fuzzregress-demand-${fname}-${textname}-${tname}-demand.log)
 endforeach(tfile)
 
diff --git a/tests/sparsetest/sparsetest.cpp b/tests/sparsetest/sparsetest.cpp
index b59375e..89f8848 100644
--- a/tests/sparsetest/sparsetest.cpp
+++ b/tests/sparsetest/sparsetest.cpp
@@ -64,7 +64,7 @@ int main(int argc , char *argv[])
     sparse sp(data, data_end);
 
     // Check all values are stored
-    if (sp.size() != sizeof(data)/sizeof(sparse::value_type))
+    if (sp.capacity() != sizeof(data)/sizeof(sparse::value_type))
         return 1;
 
     // Check the values we put in are coming out again
@@ -99,8 +99,8 @@ int main(int argc , char *argv[])
               << "\tsize:           " << (data_end[-1].first+1)*sizeof(uint16) 
<< std::endl
 
               << "sparse uint16 array:" << std::endl
-              << "\tcapacity:       " << sp.size() << std::endl
-              << "\tresidency:      " << sp.size() << std::endl
+              << "\tcapacity:       " << sp.capacity() << std::endl
+              << "\tresidency:      " << sp.capacity() << std::endl
               << "\tfill ratio:     " << 100.0f << "%" << std::endl
               << "\tsize:           " << sp._sizeof() << std::endl;
 
diff --git a/tests/standards/charis1.log b/tests/standards/charis1.log
index cf92d6f..050eafa 100644
--- a/tests/standards/charis1.log
+++ b/tests/standards/charis1.log
@@ -1,5 +1,6 @@
 Text codes
   69    2e6     2e8     2e5    
+Segment length: 4
 pos  gid   attach           x       y  ins bw    chars         Unicode 
 00    76  -1@0,0          0.0     0.0   1  30    0   0      69      69
 01  2862  -1@0,0          3.6     0.0   1  30    1   1     2e6     2e6
diff --git a/tests/standards/charis2.log b/tests/standards/charis2.log
index ffab9f3..971f1dd 100644
--- a/tests/standards/charis2.log
+++ b/tests/standards/charis2.log
@@ -1,5 +1,6 @@
 Text codes
 1d510    41    1d513   
+Segment length: 3
 pos  gid   attach           x       y  ins bw    chars         Unicode 
 00  1572  -1@0,0          0.0     0.0   1  30    0   0   1d510   1d510
 01    36  -1@0,0         11.7     0.0   1  30    1   1      41      41
diff --git a/tests/standards/charis3.log b/tests/standards/charis3.log
index 4c0be9c..ba2da39 100644
--- a/tests/standards/charis3.log
+++ b/tests/standards/charis3.log
@@ -1,5 +1,6 @@
 Text codes
   54     69    1ec3      75    
+Segment length: 4
 pos  gid   attach           x       y  ins bw    chars         Unicode 
 00    55  -1@0,0          0.0     0.0   1  30    0   0      54      54
 01    76  -1@0,0          7.2     0.0   1  30    1   1      69      69
diff --git a/tests/standards/charis4.log b/tests/standards/charis4.log
index 67528fb..3198b7e 100644
--- a/tests/standards/charis4.log
+++ b/tests/standards/charis4.log
@@ -1,5 +1,6 @@
 Text codes
   6b    361      70    
+Segment length: 3
 pos  gid   attach           x       y  ins bw    chars         Unicode 
 00    78  -1@0,0          0.0     0.0   1  30    0   0      6b      6b
 01  2650  -1@0,0          6.4     0.9   1  30    1   1     361     361
diff --git a/tests/standards/charis5.log b/tests/standards/charis5.log
index 81c8a26..9df44e4 100644
--- a/tests/standards/charis5.log
+++ b/tests/standards/charis5.log
@@ -1,5 +1,6 @@
 Text codes
   20     6c     325      65    
+Segment length: 4
 pos  gid   attach           x       y  ins bw    chars         Unicode 
 00     3  -1@0,0          0.0     0.0   1  15    0   0      20      20
 01    79  -1@0,0          3.5     0.0   1  30    1   1      6c      6c
diff --git a/tests/standards/charis6.log b/tests/standards/charis6.log
index 2d0f224..bb438a1 100644
--- a/tests/standards/charis6.log
+++ b/tests/standards/charis6.log
@@ -1,5 +1,6 @@
 Text codes
   48     65      6c      6c      6f      20      4d      75      6d    
+Segment length: 9
 pos  gid   attach           x       y  ins bw    chars         Unicode 
 00    43  -1@0,0          0.0     0.0   1  30    0   0      48      48
 01    72  -1@0,0          9.2     0.0   1  30    1   1      65      65
diff --git a/tests/standards/general1.log b/tests/standards/general1.log
index 026c767..59ca151 100644
--- a/tests/standards/general1.log
+++ b/tests/standards/general1.log
@@ -1,5 +1,6 @@
 Text codes
  e01     62    
+Segment length: 2
 pos  gid   attach           x       y  ins bw    chars         Unicode 
 00    66  -1@0,0          0.0     0.0   1  30    0   0     e01     e01
 01    68  -1@0,0          4.3     0.0   1  30    1   1      62      62
diff --git a/tests/standards/grtest1.log b/tests/standards/grtest1.log
index 8e6a0f5..f9f12c8 100644
--- a/tests/standards/grtest1.log
+++ b/tests/standards/grtest1.log
@@ -1,5 +1,6 @@
 Text codes
   62     61      61      61      61      61      61      62      61    
+Segment length: 9
 pos  gid   attach           x       y  ins bw    chars         Unicode 
 00    36  -1@0,0          0.0     0.0   1  30    0   0      62      62
 01    37  -1@0,0          8.1     0.0   1  30    1   1      61      61
diff --git a/tests/standards/magyar1.log b/tests/standards/magyar1.log
index 087b316..1f9bd1a 100644
--- a/tests/standards/magyar1.log
+++ b/tests/standards/magyar1.log
@@ -1,6 +1,7 @@
 Text codes
   31     35    
 210=36
+Segment length: 9
 pos  gid   attach           x       y  ins bw    chars         Unicode 
 00  1630  -1@0,0          0.0     0.0   1  30    0   0      31      31
 01    87  -1@0,0          0.0     0.0   1  30    1   1      35      35
diff --git a/tests/standards/magyar2.log b/tests/standards/magyar2.log
index 26208b6..1862808 100644
--- a/tests/standards/magyar2.log
+++ b/tests/standards/magyar2.log
@@ -1,6 +1,7 @@
 Text codes
   31     30    
 210=200
+Segment length: 5
 pos  gid   attach           x       y  ins bw    chars         Unicode 
 00  1630  -1@0,0          0.0     0.0   1  30    0   0      31      31
 01    71  -1@0,0          0.0     0.0   1  30    1   1      30      30
diff --git a/tests/standards/magyar3.log b/tests/standards/magyar3.log
index e8a12e9..9e84858 100644
--- a/tests/standards/magyar3.log
+++ b/tests/standards/magyar3.log
@@ -2,6 +2,7 @@ Text codes
   66     69      66      74      79      2d      66      69      76      65
 
 209=3
+Segment length: 10
 pos  gid   attach           x       y  ins bw    chars         Unicode 
 00    41  -1@0,0          0.0     0.0   1  30    0   0      66      66
 01    76  -1@0,0          5.7     0.0   1  30    1   1      69      69
diff --git a/tests/standards/padauk1.log b/tests/standards/padauk1.log
index 817ccd9..1e5326f 100644
--- a/tests/standards/padauk1.log
+++ b/tests/standards/padauk1.log
@@ -1,5 +1,6 @@
 Text codes
 1015   102f    100f    1039    100f    1031    1038    
+Segment length: 6
 pos  gid   attach           x       y  ins bw    chars         Unicode 
 00   164  -1@0,0          0.0     0.0   1 -15    0   0    1015    1015
 01   213   0@292,-53      4.4     0.0   0 -30    1   1    102f    102f
diff --git a/tests/standards/padauk10.log b/tests/standards/padauk10.log
index 93fc00d..6234ea6 100644
--- a/tests/standards/padauk10.log
+++ b/tests/standards/padauk10.log
@@ -2,6 +2,7 @@ Text codes
 1004   103d    1000    103a    
 kdot=1
 wtri=1
+Segment length: 4
 pos  gid   attach           x       y  ins bw    chars         Unicode 
 00   403  -1@0,0          0.0     0.0   1 -15    0   0    1004    1004
 01   445   0@292,-53      6.0     0.0   0 -50    1   1    103d    103d
diff --git a/tests/standards/padauk11.log b/tests/standards/padauk11.log
index b8f1fd5..cb3cf4f 100644
--- a/tests/standards/padauk11.log
+++ b/tests/standards/padauk11.log
@@ -1,5 +1,6 @@
 Text codes
 100b   1039    100c    1031    102c    
+Segment length: 3
 pos  gid   attach           x       y  ins bw    chars         Unicode 
 00   216  -1@0,0          0.0     0.0   1 -30    3   3    1031    1031
 01   137  -1@0,0          6.8     0.0   1 -30    0   2    100b    100c
diff --git a/tests/standards/padauk2.log b/tests/standards/padauk2.log
index 32ddcc8..30aff81 100644
--- a/tests/standards/padauk2.log
+++ b/tests/standards/padauk2.log
@@ -1,5 +1,6 @@
 Text codes
 1000   103c    102d    102f    
+Segment length: 3
 pos  gid   attach           x       y  ins bw    chars         Unicode 
 00   243  -1@0,0          0.0     0.0   1 -15    1   3    103c    102f
 01    99   0@172,0        2.0     0.0   1 -15    0   0    1000    1000
diff --git a/tests/standards/padauk3.log b/tests/standards/padauk3.log
index 73b9fc7..ad9fdf2 100644
--- a/tests/standards/padauk3.log
+++ b/tests/standards/padauk3.log
@@ -1,6 +1,7 @@
 Text codes
 101e   1004    103a    1039    1001    103b    102d    102f    1004    103a
 1038   
+Segment length: 8
 pos  gid   attach           x       y  ins bw    chars         Unicode 
 00   187  -1@0,0          0.0     0.0   1 -15    0   0    101e    101e
 01   103  -1@0,0         11.6     0.0   1 -50    4   4    1001    1001
diff --git a/tests/standards/padauk3Windows.log 
b/tests/standards/padauk3Windows.log
index d2fe420..e528d0b 100644
--- a/tests/standards/padauk3Windows.log
+++ b/tests/standards/padauk3Windows.log
@@ -1,6 +1,7 @@
 Text codes
 101e   1004    103a    1039    1001    103b    102d    102f    1004    103a
 1038   
+Segment length: 8
 pos  gid   attach           x       y  ins bw    chars         Unicode 
 00   187  -1@0,0          0.0     0.0   1 -15    0   0    101e    101e
 01   103  -1@0,0         11.6     0.0   1 -50    4   4    1001    1001
diff --git a/tests/standards/padauk4.log b/tests/standards/padauk4.log
index d6b1d17..7bc737f 100644
--- a/tests/standards/padauk4.log
+++ b/tests/standards/padauk4.log
@@ -1,5 +1,6 @@
 Text codes
 1005   1000    1039    1000    1030    
+Segment length: 4
 pos  gid   attach           x       y  ins bw    chars         Unicode 
 00   119  -1@0,0          0.0     0.0   1 -15    0   0    1005    1005
 01    99  -1@0,0          6.8     0.0   1 -30    1   1    1000    1000
diff --git a/tests/standards/padauk5.log b/tests/standards/padauk5.log
index 81a0be6..ea64622 100644
--- a/tests/standards/padauk5.log
+++ b/tests/standards/padauk5.log
@@ -1,5 +1,6 @@
 Text codes
 1000   103c    1031    102c    1004    1037    103a    
+Segment length: 7
 pos  gid   attach           x       y  ins bw    chars         Unicode 
 00   216  -1@0,0          0.0     0.0   1 -30    2   2    1031    1031
 01   235  -1@0,0          6.8     0.0   1 -15    1   1    103c    103c
diff --git a/tests/standards/padauk6.log b/tests/standards/padauk6.log
index 79b0c14..cd7589a 100644
--- a/tests/standards/padauk6.log
+++ b/tests/standards/padauk6.log
@@ -1,5 +1,6 @@
 Text codes
 1000   102d    1005    1039    1006    102c    
+Segment length: 5
 pos  gid   attach           x       y  ins bw    chars         Unicode 
 00    99  -1@0,0          0.0     0.0   1 -15    0   0    1000    1000
 01   209   0@714,495     11.1     0.0   0 -50    1   1    102d    102d
diff --git a/tests/standards/padauk7.log b/tests/standards/padauk7.log
index 6ed61fe..198c979 100644
--- a/tests/standards/padauk7.log
+++ b/tests/standards/padauk7.log
@@ -1,5 +1,6 @@
 Text codes
 1017   1014    103c    103d    102f    
+Segment length: 4
 pos  gid   attach           x       y  ins bw    chars         Unicode 
 00   168  -1@0,0          0.0     0.0   1 -15    0   0    1017    1017
 01   236  -1@0,0          6.9     0.0   1 -50    2   3    103c    103d
diff --git a/tests/standards/padauk8.log b/tests/standards/padauk8.log
index d40b8e3..b017fc3 100644
--- a/tests/standards/padauk8.log
+++ b/tests/standards/padauk8.log
@@ -1,5 +1,6 @@
 Text codes
 1004   103a    1039    1005    
+Segment length: 2
 pos  gid   attach           x       y  ins bw    chars         Unicode 
 00   119  -1@0,0          0.0     0.0   1 -50    3   3    1005    1005
 01   111   0@288,495      4.5     0.0   0 -50    0   2    1004    1039
diff --git a/tests/standards/padauk9.log b/tests/standards/padauk9.log
index 28baf5f..986c183 100644
--- a/tests/standards/padauk9.log
+++ b/tests/standards/padauk9.log
@@ -1,5 +1,6 @@
 Text codes
 1004   103a    1039    
+Segment length: 2
 pos  gid   attach           x       y  ins bw    chars         Unicode 
 00   368  -1@0,0          0.0     0.0   1 -30    0   2    1004    1039
 01   111   0@318,493      4.8    -0.0   0 -30    0   2    1004    1039
diff --git a/tests/standards/scher1.log b/tests/standards/scher1.log
index c6ddf2f..c3278bb 100644
--- a/tests/standards/scher1.log
+++ b/tests/standards/scher1.log
@@ -1,5 +1,6 @@
 Text codes
  628    628     64e     644     64e     654     627     64e    
+Segment length: 8
 pos  gid   attach           x       y  ins bw    chars         Unicode 
 00   836  -1@0,0          8.6     0.0   1  30    0   0     628     628
 01   694  -1@0,0          6.4     0.0   1  30    1   1     628     628
diff --git a/tests/standards/scher2.log b/tests/standards/scher2.log
index c2a4173..d9c0704 100644
--- a/tests/standards/scher2.log
+++ b/tests/standards/scher2.log
@@ -1,5 +1,6 @@
 Text codes
  627    644     625     639     644     627     646    
+Segment length: 8
 pos  gid   attach           x       y  ins bw    chars         Unicode 
 00   257  -1@0,0         20.5     0.0   1  30    0   0     627     627
 01  1206  -1@0,0         18.4     0.0   1  30    1   1     644     644
diff --git a/tests/standards/scher3.log b/tests/standards/scher3.log
index 3d99bcd..c54a5d0 100644
--- a/tests/standards/scher3.log
+++ b/tests/standards/scher3.log
@@ -1,5 +1,6 @@
 Text codes
  627     31      32      2d      34      35     627    
+Segment length: 7
 pos  gid   attach           x       y  ins bw    chars         Unicode 
 00   257  -1@0,0         22.8     0.0   1  30    0   0     627     627
 01    22  -1@0,0         18.3     0.0   1  30    2   2      32      32
diff --git a/tests/utftest/utftest.cpp b/tests/utftest/utftest.cpp
index 5c16aca..21cb188 100644
--- a/tests/utftest/utftest.cpp
+++ b/tests/utftest/utftest.cpp
@@ -1,13 +1,13 @@
 #include <graphite2/Segment.h>
 #include <stdio.h>
 
-struct test
+struct test8
 {
     int len,
        error;
     unsigned char str[12];
 };
-struct test tests[] = {
+struct test8 tests8[] = {
     { 4, -1, {0x7F, 0xDF, 0xBF, 0xEF, 0xBF, 0xBF, 0xF4, 0x8F, 0xBF, 0xBF, 0,   
 0} },   // U+7F, U+7FF, U+FFFF, U+10FFF
     { 2,  3, {0x7F, 0xDF, 0xBF, 0xF0, 0x8F, 0xBF, 0xBF, 0xF4, 0x8F, 0xBF, 
0xBF, 0} },   // U+7F, U+7FF, long(U+FFFF), U+10FFF
     { 1,  1, {0x7F, 0xE0, 0x9F, 0xBF, 0xEF, 0xBF, 0xBF, 0xF4, 0x8F, 0xBF, 
0xBF, 0} },   // U+7F, long(U+7FF), U+FFFF, U+10FFF
@@ -20,36 +20,81 @@ struct test tests[] = {
     { 2,  2, {0x65, 0x75, 0xF3, 0x84, 0xA5, 0xF5, 0x75, 0,    0,    0,    0,   
 0} },   // U+65 U+75 bad(3) bad(1) U+75
 };
 
-const int numtests = sizeof(tests)/sizeof(test);
+const int numtests8 = sizeof(tests8)/sizeof(test8);
+
+struct test16
+{
+    int len,
+        error;
+    unsigned short str[6];
+};
+
+struct test16 tests16[] = {
+    {4, -1, {0x007F, 0x07FF, 0xFFFF, 0xDBFF, 0xDFFF, 0x0000} },
+    {4, -1, {0x0001, 0x0080, 0x0800, 0xD800, 0xDC00, 0x0000} },
+    {3,  6, {0x007F, 0x07FF, 0xFFFF, 0xDCFF, 0xDFFF, 0x0000} },
+    {3,  6, {0x0001, 0x0080, 0x0800, 0xD800, 0xD800, 0x0000} },
+    {2,  6, {0x0045, 0xD900, 0xDD00, 0xD900, 0xFFFF, 0x0000} },
+};
+
+const int numtests16 = sizeof(tests16)/sizeof(test16);
 
 int main(int argc, char * argv[]) {
     int i;
     const void * error;
 
-    for (i = 0; i < numtests; ++i)
+    for (i = 0; i < numtests8; ++i)
+    {
+        int res = gr_count_unicode_characters(gr_utf8, tests8[i].str, 
tests8[i].str + sizeof(tests8[i].str), &error);
+        if (tests8[i].error >= 0)
+        {
+               if (!error)
+               {
+                               fprintf(stderr, "%s: test 8:%d failed: expected 
error condition did not occur\n", argv[0], i + 1);
+                               return (i+1);
+               }
+               else if (ptrdiff_t(error) - ptrdiff_t(tests8[i].str) != 
tests8[i].error)
+            {
+                       fprintf(stderr, "%s: test 8:%d failed: error at 
codepoint %d expected at codepoint %d\n", argv[0], i + 1, int(ptrdiff_t(error) 
- ptrdiff_t(tests8[i].str)), tests8[i].error);
+                return (i+1);
+            }
+        }
+        else if (error)
+               {
+                       fprintf(stderr, "%s: test 8:%d failed: unexpected error 
occured at codepoint %d\n", argv[0], i + 1, int(ptrdiff_t(error) - 
ptrdiff_t(tests8[i].str)));
+                       return (i+1);
+               }
+        if (res != tests8[i].len)
+        {
+            fprintf(stderr, "%s: test 8:%d failed: character count failure %d 
!= %d\n", argv[0], i + 1, res, tests8[i].len);
+            return (i+1);
+        }
+    }
+
+    for (i = 0; i < numtests16; ++i)
     {
-        int res = gr_count_unicode_characters(gr_utf8, tests[i].str, 
tests[i].str + sizeof(tests[i].str), &error);
-        if (tests[i].error >= 0)
+        int res = gr_count_unicode_characters(gr_utf16, tests16[i].str, 
tests16[i].str + sizeof(tests16[i].str), &error);
+        if (tests16[i].error >= 0)
         {
                if (!error)
                {
-                               fprintf(stderr, "%s: test %d failed: expected 
error condition did not occur\n", argv[0], i + 1);
+                               fprintf(stderr, "%s: test 16:%d failed: 
expected error condition did not occur\n", argv[0], i + 1);
                                return (i+1);
                }
-               else if (ptrdiff_t(error) - ptrdiff_t(tests[i].str) != 
tests[i].error)
+               else if (ptrdiff_t(error) - ptrdiff_t(tests16[i].str) != 
tests16[i].error)
             {
-                       fprintf(stderr, "%s: test %d failed: error at codepoint 
%d expected at codepoint %d\n", argv[0], i + 1, int(ptrdiff_t(error) - 
ptrdiff_t(tests[i].str)), tests[i].len);
+                       fprintf(stderr, "%s: test 16:%d failed: error at 
codepoint %d expected at codepoint %d\n", argv[0], i + 1, int(ptrdiff_t(error) 
- ptrdiff_t(tests16[i].str)), tests16[i].error);
                 return (i+1);
             }
         }
         else if (error)
                {
-                       fprintf(stderr, "%s: test %d failed: unexpected error 
occured at codepoint %d\n", argv[0], i + 1, int(ptrdiff_t(error) - 
ptrdiff_t(tests[i].str)));
+                       fprintf(stderr, "%s: test 16:%d failed: unexpected 
error occured at codepoint %d\n", argv[0], i + 1, int(ptrdiff_t(error) - 
ptrdiff_t(tests16[i].str)));
                        return (i+1);
                }
-        if (res != tests[i].len)
+        if (res != tests16[i].len)
         {
-            fprintf(stderr, "%s: test %d failed: character count failure %d != 
%d\n", argv[0], i + 1, res, tests[i].len);
+            fprintf(stderr, "%s: test 16:%d failed: character count failure %d 
!= %d\n", argv[0], i + 1, res, tests16[i].len);
             return (i+1);
         }
     }

-- 
Alioth's /usr/local/bin/git-commit-notice on 
/srv/git.debian.org/git/pkg-openoffice/graphite2.git

Reply via email to