diff options
Diffstat (limited to 'src/PositionCache.cxx')
-rw-r--r-- | src/PositionCache.cxx | 62 |
1 files changed, 24 insertions, 38 deletions
diff --git a/src/PositionCache.cxx b/src/PositionCache.cxx index 52c4326c0..e59c12630 100644 --- a/src/PositionCache.cxx +++ b/src/PositionCache.cxx @@ -391,18 +391,19 @@ static int NextBadU(const char *s, int p, int len, int &trailBytes) { return -1; } -BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_, bool utf8_, int xStart, bool breakForSelection) : +BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_, + int xStart, bool breakForSelection, Document *pdoc_) : ll(ll_), lineStart(lineStart_), lineEnd(lineEnd_), posLineStart(posLineStart_), - utf8(utf8_), nextBreak(lineStart_), saeSize(0), saeLen(0), saeCurrentPos(0), saeNext(0), - subBreak(-1) { + subBreak(-1), + pdoc(pdoc_) { saeSize = 8; selAndEdge = new int[saeSize]; for (unsigned int j=0; j < saeSize; j++) { @@ -435,7 +436,7 @@ BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posL Insert(ll->edgeColumn - 1); Insert(lineEnd - 1); - if (utf8) { + if (pdoc && (SC_CP_UTF8 == pdoc->dbcsCodePage)) { int trailBytes=0; for (int pos = -1;;) { pos = NextBadU(ll->chars, pos, lineEnd, trailBytes); @@ -456,10 +457,6 @@ int BreakFinder::First() const { return nextBreak; } -static bool IsTrailByte(int ch) { - return (ch >= 0x80) && (ch < (0x80 + 0x40)); -} - int BreakFinder::Next() { if (subBreak == -1) { int prev = nextBreak; @@ -490,34 +487,7 @@ int BreakFinder::Next() { subBreak = -1; return nextBreak; } else { - int lastGoodBreak = -1; - int lastOKBreak = -1; - int lastUTF8Break = -1; - int j; - for (j = subBreak + 1; j <= nextBreak; j++) { - if (IsSpaceOrTab(ll->chars[j - 1]) && !IsSpaceOrTab(ll->chars[j])) { - lastGoodBreak = j; - } - if (static_cast<unsigned char>(ll->chars[j]) < 'A') { - lastOKBreak = j; - } - if (utf8 && !IsTrailByte(static_cast<unsigned char>(ll->chars[j]))) { - lastUTF8Break = j; - } - if (((j - subBreak) >= lengthEachSubdivision) && - ((lastGoodBreak >= 0) || (lastOKBreak >= 0) || (lastUTF8Break >= 0))) { - break; - } - } - if (lastGoodBreak >= 0) { - subBreak = lastGoodBreak; - } else if (lastOKBreak >= 0) { - subBreak = lastOKBreak; - } else if (lastUTF8Break >= 0) { - subBreak = lastUTF8Break; - } else { - subBreak = nextBreak; - } + subBreak += pdoc->SafeSegment(ll->chars + subBreak, nextBreak-subBreak, lengthEachSubdivision); if (subBreak >= nextBreak) { subBreak = -1; return nextBreak; @@ -624,7 +594,8 @@ void PositionCache::SetSize(size_t size_) { } void PositionCache::MeasureWidths(Surface *surface, ViewStyle &vstyle, unsigned int styleNumber, - const char *s, unsigned int len, int *positions) { + const char *s, unsigned int len, int *positions, Document *pdoc) { + allClear = false; int probe = -1; if ((size > 0) && (len < 30)) { @@ -646,7 +617,22 @@ void PositionCache::MeasureWidths(Surface *surface, ViewStyle &vstyle, unsigned probe = probe2; } } - surface->MeasureWidths(vstyle.styles[styleNumber].font, s, len, positions); + if (len > BreakFinder::lengthStartSubdivision) { + // Break up into segments + unsigned int startSegment = 0; + int xStartSegment = 0; + while (startSegment < len) { + unsigned int lenSegment = pdoc->SafeSegment(s + startSegment, len - startSegment, BreakFinder::lengthEachSubdivision); + surface->MeasureWidths(vstyle.styles[styleNumber].font, s + startSegment, lenSegment, positions + startSegment); + for (unsigned int inSeg = 0; inSeg < lenSegment; inSeg++) { + positions[startSegment + inSeg] += xStartSegment; + } + xStartSegment = positions[startSegment + lenSegment - 1]; + startSegment += lenSegment; + } + } else { + surface->MeasureWidths(vstyle.styles[styleNumber].font, s, len, positions); + } if (probe >= 0) { clock++; if (clock > 60000) { |