aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/PositionCache.cxx
diff options
context:
space:
mode:
authorNeil <nyamatongwe@gmail.com>2013-07-22 19:36:55 +1000
committerNeil <nyamatongwe@gmail.com>2013-07-22 19:36:55 +1000
commit199d7ee000fcb1ce24d3f4a919dc825e6c0d2f45 (patch)
tree12c648fe19907c70867438641fa36ee550923847 /src/PositionCache.cxx
parent47792a5650ed6c70b05ccf1c33cce015d032bd04 (diff)
downloadscintilla-mirror-199d7ee000fcb1ce24d3f4a919dc825e6c0d2f45.tar.gz
Added the character representation feature.
Diffstat (limited to 'src/PositionCache.cxx')
-rw-r--r--src/PositionCache.cxx88
1 files changed, 78 insertions, 10 deletions
diff --git a/src/PositionCache.cxx b/src/PositionCache.cxx
index 742a226b9..d92d49338 100644
--- a/src/PositionCache.cxx
+++ b/src/PositionCache.cxx
@@ -13,6 +13,9 @@
#include <string>
#include <vector>
#include <map>
+#ifndef SCINTILLA_NO_UNORDERED_MAP
+#include <unordered_map>
+#endif
#include "Platform.h"
@@ -34,6 +37,7 @@
#include "ILexer.h"
#include "CaseFolder.h"
#include "Document.h"
+#include "UniConversion.h"
#include "Selection.h"
#include "PositionCache.h"
@@ -336,6 +340,62 @@ void LineLayoutCache::Dispose(LineLayout *ll) {
}
}
+// Simply pack the (maximum 4) character bytes into an int
+static inline int KeyFromString(const char *charBytes, size_t len) {
+ PLATFORM_ASSERT(len <= 4);
+ int k=0;
+ for (size_t i=0; i<len && charBytes[i]; i++) {
+ k = k * 0x100;
+ k += charBytes[i];
+ }
+ return k;
+}
+
+SpecialRepresentations::SpecialRepresentations() {
+ std::fill(startByteHasReprs, startByteHasReprs+0x100, 0);
+}
+
+void SpecialRepresentations::SetRepresentation(const char *charBytes, const char *value) {
+ MapRepresentation::iterator it = mapReprs.find(KeyFromString(charBytes, UTF8MaxBytes));
+ if (it == mapReprs.end()) {
+ // New entry so increment for first byte
+ startByteHasReprs[static_cast<unsigned char>(charBytes[0])]++;
+ }
+ mapReprs[KeyFromString(charBytes, UTF8MaxBytes)] = value;
+}
+
+void SpecialRepresentations::ClearRepresentation(const char *charBytes) {
+ MapRepresentation::iterator it = mapReprs.find(KeyFromString(charBytes, UTF8MaxBytes));
+ if (it != mapReprs.end()) {
+ mapReprs.erase(it);
+ startByteHasReprs[static_cast<unsigned char>(charBytes[0])]--;
+ }
+}
+
+Representation *SpecialRepresentations::RepresentationFromCharacter(const char *charBytes, size_t len) {
+ PLATFORM_ASSERT(len <= 4);
+ if (!startByteHasReprs[static_cast<unsigned char>(charBytes[0])])
+ return 0;
+ MapRepresentation::iterator it = mapReprs.find(KeyFromString(charBytes, len));
+ if (it != mapReprs.end()) {
+ return &(it->second);
+ }
+ return 0;
+}
+
+bool SpecialRepresentations::Contains(const char *charBytes, size_t len) const {
+ PLATFORM_ASSERT(len <= 4);
+ if (!startByteHasReprs[static_cast<unsigned char>(charBytes[0])])
+ return false;
+ MapRepresentation::const_iterator it = mapReprs.find(KeyFromString(charBytes, len));
+ return it != mapReprs.end();
+}
+
+void SpecialRepresentations::Clear() {
+ mapReprs.clear();
+ std::fill(startByteHasReprs, startByteHasReprs+0x100, 0);
+}
+
void BreakFinder::Insert(int val) {
if (val >= nextBreak) {
for (std::vector<int>::iterator it = selAndEdge.begin(); it != selAndEdge.end(); ++it) {
@@ -352,6 +412,7 @@ void BreakFinder::Insert(int val) {
}
}
+/*
extern bool BadUTF(const char *s, int len, int &trailBytes);
static int NextBadU(const char *s, int p, int len, int &trailBytes) {
@@ -362,9 +423,10 @@ static int NextBadU(const char *s, int p, int len, int &trailBytes) {
}
return -1;
}
+*/
BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_,
- int xStart, bool breakForSelection, Document *pdoc_) :
+ int xStart, bool breakForSelection, Document *pdoc_, SpecialRepresentations *preprs_) :
ll(ll_),
lineStart(lineStart_),
lineEnd(lineEnd_),
@@ -373,7 +435,8 @@ BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posL
saeCurrentPos(0),
saeNext(0),
subBreak(-1),
- pdoc(pdoc_) {
+ pdoc(pdoc_),
+ preprs(preprs_) {
// Search for first visible break
// First find the first visible character
@@ -401,14 +464,19 @@ BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posL
Insert(ll->edgeColumn - 1);
Insert(lineEnd - 1);
- if (pdoc && (SC_CP_UTF8 == pdoc->dbcsCodePage)) {
- int trailBytes=0;
- for (int pos = -1;;) {
- pos = NextBadU(ll->chars, pos, lineEnd, trailBytes);
- if (pos < 0)
- break;
- Insert(pos-1);
- Insert(pos);
+ if (pdoc && preprs) {
+ EncodingFamily encodingFamily = pdoc->CodePageFamily();
+ for (int posRepr=0; posRepr<lineEnd;) {
+ int charWidth = 1;
+ if (encodingFamily == efUnicode)
+ charWidth = UTF8DrawBytes(reinterpret_cast<unsigned char *>(ll->chars) + posRepr, lineEnd - posRepr);
+ else if (encodingFamily == efDBCS)
+ charWidth = pdoc->IsDBCSLeadByte(ll->chars[posRepr]) ? 2 : 1;
+ if (preprs->Contains(ll->chars + posRepr, charWidth)) {
+ Insert(posRepr - 1);
+ Insert(posRepr + charWidth - 1);
+ }
+ posRepr += charWidth;
}
}
saeNext = (!selAndEdge.empty()) ? selAndEdge[0] : -1;