diff options
author | Sebastian Geerken <devnull@localhost> | 2013-01-02 10:00:02 +0100 |
---|---|---|
committer | Sebastian Geerken <devnull@localhost> | 2013-01-02 10:00:02 +0100 |
commit | ea0cbd334be765eac1d47783c052d15642a407be (patch) | |
tree | 0806204dfcf2b68820ce469f0e498545ab59d702 | |
parent | 9a533c36c2858875a31900fc86a3000a8f1d59bc (diff) |
Fixed valgrind error in Hyphenator.
-rw-r--r-- | dw/hyphenator.cc | 34 | ||||
-rw-r--r-- | lout/unicode.cc | 16 | ||||
-rw-r--r-- | lout/unicode.hh | 4 | ||||
-rw-r--r-- | test/liang.cc | 2 |
4 files changed, 45 insertions, 11 deletions
diff --git a/dw/hyphenator.cc b/dw/hyphenator.cc index af10587c..00240bc0 100644 --- a/dw/hyphenator.cc +++ b/dw/hyphenator.cc @@ -317,16 +317,30 @@ void Hyphenator::hyphenateSingleWord(core::Platform *platform, // No hyphens in the first two chars or the last two. // Characters are not bytes, so UTF-8 characters must be counted. - int len = strlen (wordLc); - const char *bytesStart = nextUtf8Char (nextUtf8Char (wordLc)); - int numBytesStart = bytesStart ? bytesStart - wordLc : len; - for (int i = 0; i < numBytesStart; i++) - points.set (i + 1, 0); - - int numBytes1End = platform->prevGlyph (wordLc, len); - int numBytes2End = platform->prevGlyph (wordLc, numBytes1End); - for (int i = 0; i < len - numBytes2End; i++) - points.set (points.size() - 2 - i, 0); + const char *s = nextUtf8Char (wordLc); + if (s != NULL && (s = nextUtf8Char (s)) != NULL) { + // First two characters. + int bytesStart = s - wordLc; + for (int i = 0; i < bytesStart; i++) + points.set (i + 1, 0); + + // Last two characters: instead of iterating back from the end, + // we simply iterate from the start to the end and count the + // characters. + + int lenBytes = strlen (wordLc); + int lenUtf8 = numUtf8Chars (wordLc); + int bytesEnd = 0; + + s = wordLc; + for (int i = 0; s; s = nextUtf8Char (s), i++) { + if (i == lenUtf8 - 2) + bytesEnd = lenBytes - (s - wordLc); + } + + for (int i = 0; i < bytesEnd; i++) + points.set (points.size() - 2 - i, 0); + } // Examine the points to build the break point list. int n = lout::misc::min ((int)strlen (wordLc), points.size () - 2); diff --git a/lout/unicode.cc b/lout/unicode.cc index 39d3a094..77bd8077 100644 --- a/lout/unicode.cc +++ b/lout/unicode.cc @@ -139,6 +139,22 @@ const char *nextUtf8Char (const char *s, int len) return r; } +int numUtf8Chars (const char *s) +{ + int numUtf8 = 0; + for (const char *r = s; r; r = nextUtf8Char (r)) + numUtf8++; + return numUtf8; +} + +int numUtf8Chars (const char *s, int len) +{ + int numUtf8 = 0; + for (const char *r = s; len > 0 && r; r = nextUtf8Char (r, len)) + numUtf8++; + return numUtf8; +} + } // namespace lout } // namespace unicode diff --git a/lout/unicode.hh b/lout/unicode.hh index cfde25e6..c74fd9b5 100644 --- a/lout/unicode.hh +++ b/lout/unicode.hh @@ -19,6 +19,10 @@ const char *nextUtf8Char (const char *s); const char *nextUtf8Char (const char *s, int len); +int numUtf8Chars (const char *s); + +int numUtf8Chars (const char *s, int len); + } // namespace lout } // namespace unicode diff --git a/test/liang.cc b/test/liang.cc index a1bc2442..ce5036fa 100644 --- a/test/liang.cc +++ b/test/liang.cc @@ -18,7 +18,7 @@ void hyphenateWord (dw::core::Platform *p, const char *word) } putchar ('\n'); if (breakPos) - delete breakPos; + free (breakPos); } int main (int argc, char *argv[]) |