[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[graphite2] 31/69: Imported Upstream version 1.2.1



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 <rene@debian.org>
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 <martin_hosken@sil.org>  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 to: