aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gtk/ScintillaGTK.cxx153
-rw-r--r--include/Scintilla.h3
-rw-r--r--include/Scintilla.iface13
-rw-r--r--src/Editor.cxx6
-rw-r--r--src/Editor.h1
-rw-r--r--src/PropSet.cxx2
6 files changed, 143 insertions, 35 deletions
diff --git a/gtk/ScintillaGTK.cxx b/gtk/ScintillaGTK.cxx
index 6968a9ca9..f9ddaf5ba 100644
--- a/gtk/ScintillaGTK.cxx
+++ b/gtk/ScintillaGTK.cxx
@@ -143,6 +143,8 @@ private:
virtual void Finalise();
virtual void DisplayCursor(Window::Cursor c);
virtual void StartDrag();
+ int TargetAsUTF8(char *text);
+ int EncodedFromUTF8(char *utf8, char *encoded);
public: // Public for scintilla_send_message
virtual sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
private:
@@ -747,6 +749,116 @@ void ScintillaGTK::StartDrag() {
reinterpret_cast<GdkEvent *>(&evbtn));
}
+#ifdef USE_CONVERTER
+static char *ConvertText(int *lenResult, char *s, size_t len, const char *charSetDest, const char *charSetSource) {
+ *lenResult = 0;
+ char *destForm = 0;
+ Converter conv(charSetDest, charSetSource);
+ if (conv) {
+ destForm = new char[len*3+1];
+ char *pin = s;
+ size_t inLeft = len;
+ char *pout = destForm;
+ size_t outLeft = len*3+1;
+ size_t conversions = conv.Convert(&pin, &inLeft, &pout, &outLeft);
+ if (conversions == ((size_t)(-1))) {
+fprintf(stderr, "iconv %s->%s failed for %s\n", charSetSource, charSetDest, static_cast<char *>(s));
+ delete []destForm;
+ destForm = 0;
+ } else {
+//fprintf(stderr, "iconv OK %s %d\n", destForm, pout - destForm);
+ *pout = '\0';
+ *lenResult = pout - destForm;
+ }
+ } else {
+fprintf(stderr, "Can not iconv %s %s\n", charSetDest, charSetSource);
+ }
+ if (!destForm) {
+ destForm = new char[1];
+ destForm[0] = '\0';
+ *lenResult = 0;
+ }
+ return destForm;
+}
+#endif
+
+// Returns the target converted to UTF8.
+// Return the length in bytes.
+int ScintillaGTK::TargetAsUTF8(char *text) {
+ int targetLength = targetEnd - targetStart;
+ if (IsUnicodeMode()) {
+ if (text) {
+ pdoc->GetCharRange(text, targetStart, targetLength);
+ }
+ } else {
+ // Need to convert
+#ifdef USE_CONVERTER
+ const char *charSetBuffer = CharacterSetID();
+ if (*charSetBuffer) {
+//~ fprintf(stderr, "AsUTF8 %s %d %0d-%0d\n", charSetBuffer, targetLength, targetStart, targetEnd);
+ char *s = new char[targetLength];
+ if (s) {
+ pdoc->GetCharRange(s, targetStart, targetLength);
+//~ fprintf(stderr, " \"%s\"\n", s);
+ if (text) {
+ char *tmputf = ConvertText(&targetLength, s, targetLength, "UTF-8", charSetBuffer);
+ memcpy(text, tmputf, targetLength);
+ delete []tmputf;
+//~ fprintf(stderr, " \"%s\"\n", text);
+ }
+ delete []s;
+ }
+ } else {
+ if (text) {
+ pdoc->GetCharRange(text, targetStart, targetLength);
+ }
+ }
+#else
+ // Fail
+ return 0;
+#endif
+ }
+//~ fprintf(stderr, "Length = %d bytes\n", targetLength);
+ return targetLength;
+}
+
+// Translates a nul terminated UTF8 string into the document encoding.
+// Return the length of the result in bytes.
+int ScintillaGTK::EncodedFromUTF8(char *utf8, char *encoded) {
+ int inputLength = lengthForEncode ? lengthForEncode : strlen(utf8);
+ if (IsUnicodeMode()) {
+ if (encoded) {
+ memcpy(encoded, utf8, inputLength);
+ }
+ return inputLength;
+ } else {
+ // Need to convert
+#ifdef USE_CONVERTER
+ const char *charSetBuffer = CharacterSetID();
+ if (*charSetBuffer) {
+//~ fprintf(stderr, "Encode %s %d\n", charSetBuffer, inputLength);
+ int outLength = 0;
+ char *tmpEncoded = ConvertText(&outLength, utf8, inputLength, charSetBuffer, "UTF-8");
+ if (tmpEncoded) {
+//~ fprintf(stderr, " \"%s\"\n", tmpEncoded);
+ if (encoded) {
+ memcpy(encoded, tmpEncoded, outLength);
+ }
+ delete []tmpEncoded;
+ }
+ return outLength;
+ } else {
+ if (encoded) {
+ memcpy(encoded, utf8, inputLength);
+ }
+ return inputLength;
+ }
+#endif
+ }
+ // Fail
+ return 0;
+}
+
sptr_t ScintillaGTK::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
switch (iMessage) {
@@ -762,9 +874,15 @@ sptr_t ScintillaGTK::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam
#ifdef SCI_LEXER
case SCI_LOADLEXERLIBRARY:
- LexerManager::GetInstance()->Load(reinterpret_cast<const char*>( wParam ));
+ LexerManager::GetInstance()->Load(reinterpret_cast<const char*>(wParam));
break;
#endif
+ case SCI_TARGETASUTF8:
+ return TargetAsUTF8(reinterpret_cast<char*>(lParam));
+
+ case SCI_ENCODEDFROMUTF8:
+ return EncodedFromUTF8(reinterpret_cast<char*>(wParam),
+ reinterpret_cast<char*>(lParam));
default:
return ScintillaBase::WndProc(iMessage, wParam, lParam);
@@ -1264,39 +1382,6 @@ void ScintillaGTK::ClaimSelection() {
}
}
-#ifdef USE_CONVERTER
-static char *ConvertText(int *lenResult, char *s, size_t len, const char *charSetDest, const char *charSetSource) {
- *lenResult = 0;
- char *destForm = 0;
- Converter conv(charSetDest, charSetSource);
- if (conv) {
- destForm = new char[len*3+1];
- char *pin = s;
- size_t inLeft = len;
- char *pout = destForm;
- size_t outLeft = len*3+1;
- size_t conversions = conv.Convert(&pin, &inLeft, &pout, &outLeft);
- if (conversions == ((size_t)(-1))) {
-fprintf(stderr, "iconv %s->%s failed for %s\n", charSetSource, charSetDest, static_cast<char *>(s));
- delete []destForm;
- destForm = 0;
- } else {
-//fprintf(stderr, "iconv OK %s %d\n", destForm, pout - destForm);
- *pout = '\0';
- *lenResult = pout - destForm;
- }
- } else {
-//fprintf(stderr, "Can not iconv %s %s\n", charSetDest, charSetSource);
- }
- if (!destForm) {
- destForm = new char[1];
- destForm[0] = '\0';
- *lenResult = 0;
- }
- return destForm;
-}
-#endif
-
// Convert line endings for a piece of text to a particular mode.
// Stop at len or when a NUL is found.
char *ConvertLineEnds(int *pLenOut, const char *s, size_t len, int eolMode) {
diff --git a/include/Scintilla.h b/include/Scintilla.h
index 1a4e48872..78f3e093e 100644
--- a/include/Scintilla.h
+++ b/include/Scintilla.h
@@ -583,6 +583,9 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_SETCHARSDEFAULT 2444
#define SCI_AUTOCGETCURRENT 2445
#define SCI_ALLOCATE 2446
+#define SCI_TARGETASUTF8 2447
+#define SCI_SETLENGTHFORENCODE 2448
+#define SCI_ENCODEDFROMUTF8 2449
#define SCI_STARTRECORD 3001
#define SCI_STOPRECORD 3002
#define SCI_SETLEXER 4001
diff --git a/include/Scintilla.iface b/include/Scintilla.iface
index a430db791..3997c3c64 100644
--- a/include/Scintilla.iface
+++ b/include/Scintilla.iface
@@ -1582,6 +1582,19 @@ fun int AutoCGetCurrent=2445(,)
# Enlarge the document to a particular size of text bytes.
fun void Allocate=2446(int bytes,)
+# Returns the target converted to UTF8.
+# Return the length in bytes.
+fun int TargetAsUTF8=2447(, stringresult s)
+
+# Set the length of the utf8 argument for calling EncodedFromUTF8.
+# Set to 0 and the string will be measured to the first nul.
+fun void SetLengthForEncode=2448(int bytes,)
+
+# Translates a UTF8 string into the document encoding.
+# Return the length of the result in bytes.
+# On error return 0.
+fun int EncodedFromUTF8=2449(string utf8, stringresult encoded)
+
# Start notifying the container of all key presses and commands.
fun void StartRecord=3001(,)
diff --git a/src/Editor.cxx b/src/Editor.cxx
index 1ab36610b..23b612229 100644
--- a/src/Editor.cxx
+++ b/src/Editor.cxx
@@ -360,6 +360,8 @@ Editor::Editor() {
topLine = 0;
posTopLine = 0;
+
+ lengthForEncode = 0;
needUpdateUI = true;
braces[0] = invalidPosition;
@@ -6948,6 +6950,10 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
SetSelection(currentPos, anchor); // Ensure selection inside document
return 0;
+ case SCI_SETLENGTHFORENCODE:
+ lengthForEncode = wParam;
+ return 0;
+
case SCI_SELECTIONISRECTANGLE:
return selType == selRectangle ? 1 : 0;
diff --git a/src/Editor.h b/src/Editor.h
index b9bda04ab..d5116f0de 100644
--- a/src/Editor.h
+++ b/src/Editor.h
@@ -257,6 +257,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
int searchFlags;
int topLine;
int posTopLine;
+ int lengthForEncode;
bool needUpdateUI;
Position braces[2];
diff --git a/src/PropSet.cxx b/src/PropSet.cxx
index 00e9986f7..bf345145f 100644
--- a/src/PropSet.cxx
+++ b/src/PropSet.cxx
@@ -124,7 +124,7 @@ SString &SString::assign(const char *sOther, lenpos_t sSize_) {
s = StringAllocate(sOther, sSize_);
if (s) {
sSize = sSize_; // Allow buffer bigger than real string, thus providing space to grow
- sLen = strlen(s);
+ sLen = sSize_;
} else {
sSize = sLen = 0;
}