diff options
-rw-r--r-- | gtk/ScintillaGTK.cxx | 153 | ||||
-rw-r--r-- | include/Scintilla.h | 3 | ||||
-rw-r--r-- | include/Scintilla.iface | 13 | ||||
-rw-r--r-- | src/Editor.cxx | 6 | ||||
-rw-r--r-- | src/Editor.h | 1 | ||||
-rw-r--r-- | src/PropSet.cxx | 2 |
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; } |