aboutsummaryrefslogtreecommitdiffhomepage
path: root/gtk/PlatGTK.cxx
diff options
context:
space:
mode:
authornyamatongwe <unknown>2004-01-31 22:41:38 +0000
committernyamatongwe <unknown>2004-01-31 22:41:38 +0000
commitdec18f76e9b24bdbaa8fb9dd8064326bb9888514 (patch)
tree711c2a4cdb74eec9de53d1c473387b6caf803182 /gtk/PlatGTK.cxx
parent903ab4d8d81800c98da460730f38f51eb866daab (diff)
downloadscintilla-mirror-dec18f76e9b24bdbaa8fb9dd8064326bb9888514.tar.gz
Chooses between input method or standard keyboard reading based
on whether character set is Asian or not. Encapsulated access to iconv in Converter class.
Diffstat (limited to 'gtk/PlatGTK.cxx')
-rw-r--r--gtk/PlatGTK.cxx73
1 files changed, 27 insertions, 46 deletions
diff --git a/gtk/PlatGTK.cxx b/gtk/PlatGTK.cxx
index a24c9f1f6..52977a6f7 100644
--- a/gtk/PlatGTK.cxx
+++ b/gtk/PlatGTK.cxx
@@ -1,6 +1,6 @@
// Scintilla source code edit control
// PlatGTK.cxx - implementation of platform facilities on GTK+/Linux
-// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 1998-2004 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <string.h>
@@ -37,16 +37,7 @@
#if GTK_MAJOR_VERSION >= 2
#define USE_PANGO 1
-#include <iconv.h>
-const iconv_t iconvhBad = (iconv_t)(-1);
-// Since various versions of iconv can not agree on whether the src argument
-// is char ** or const char ** provide a templatised adaptor.
-template<typename T>
-size_t iconv_adaptor(size_t(*f_iconv)(iconv_t, T, size_t *, char **, size_t *),
- iconv_t cd, char** src, size_t *srcleft,
- char **dst, size_t *dstleft) {
- return f_iconv(cd, (T)src, srcleft, dst, dstleft);
-}
+#include "Converter.h"
#endif
#ifdef _MSC_VER
@@ -677,9 +668,9 @@ class SurfaceImpl : public Surface {
#ifdef USE_PANGO
PangoContext *pcontext;
PangoLayout *layout;
- iconv_t iconvh;
+ Converter conv;
int characterSet;
- void SetIconv(int characterSet_);
+ void SetConverter(int characterSet_);
#endif
public:
SurfaceImpl();
@@ -773,16 +764,10 @@ const char *CharacterSetID(int characterSet) {
#ifdef USE_PANGO
-void SurfaceImpl::SetIconv(int characterSet_) {
+void SurfaceImpl::SetConverter(int characterSet_) {
if (characterSet != characterSet_) {
- if (iconvh != iconvhBad)
- iconv_close(iconvh);
- iconvh = iconvhBad;
characterSet = characterSet_;
- const char *source = CharacterSetID(characterSet);
- if (*source) {
- iconvh = iconv_open("UTF-8", source);
- }
+ conv.Open("UTF-8", CharacterSetID(characterSet));
}
}
#endif
@@ -790,7 +775,7 @@ void SurfaceImpl::SetIconv(int characterSet_) {
SurfaceImpl::SurfaceImpl() : et(singleByte), drawable(0), gc(0), ppixmap(0),
x(0), y(0), inited(false), createdGC(false)
#ifdef USE_PANGO
-, pcontext(0), layout(0), iconvh(iconvhBad), characterSet(-1)
+, pcontext(0), layout(0), characterSet(-1)
#endif
{
}
@@ -817,9 +802,7 @@ void SurfaceImpl::Release() {
if (pcontext)
g_object_unref(pcontext);
pcontext = 0;
- if (iconvh != iconvhBad)
- iconv_close(iconvh);
- iconvh = iconvhBad;
+ conv.Close();
characterSet = -1;
#endif
x = 0;
@@ -1039,14 +1022,14 @@ static size_t UTF8Len(char ch) {
}
#ifdef USE_PANGO
-static char *UTF8FromIconv(iconv_t iconvh, const char *s, int len) {
- if (iconvh != ((iconv_t)(-1))) {
+static char *UTF8FromIconv(const Converter &conv, const char *s, int len) {
+ if (conv) {
char *utfForm = new char[len*3+1];
char *pin = const_cast<char *>(s);
size_t inLeft = len;
char *pout = utfForm;
size_t outLeft = len*3+1;
- size_t conversions = iconv_adaptor(iconv, iconvh, &pin, &inLeft, &pout, &outLeft);
+ size_t conversions = conv.Convert(&pin, &inLeft, &pout, &outLeft);
if (conversions != ((size_t)(-1))) {
*pout = '\0';
return utfForm;
@@ -1056,14 +1039,16 @@ static char *UTF8FromIconv(iconv_t iconvh, const char *s, int len) {
return 0;
}
-static size_t MultiByteLenFromIconv(iconv_t iconvh, const char *s, size_t len) {
+// Work out how many bytes are in a character by trying to convert using iconv,
+// returning the first length that succeeds.
+static size_t MultiByteLenFromIconv(const Converter &conv, const char *s, size_t len) {
for (size_t lenMB=1; (lenMB<4) && (lenMB <= len); lenMB++) {
char wcForm[2];
char *pin = const_cast<char *>(s);
size_t inLeft = lenMB;
char *pout = wcForm;
size_t outLeft = 2;
- size_t conversions = iconv_adaptor(iconv, iconvh, &pin, &inLeft, &pout, &outLeft);
+ size_t conversions = conv.Convert(&pin, &inLeft, &pout, &outLeft);
if (conversions != ((size_t)(-1))) {
return lenMB;
}
@@ -1154,8 +1139,8 @@ void SurfaceImpl::DrawTextBase(PRectangle rc, Font &font_, int ybase, const char
pango_layout_set_text(layout, s, len);
} else {
if (!utfForm) {
- SetIconv(PFont(font_)->characterSet);
- utfForm = UTF8FromIconv(iconvh, s, len);
+ SetConverter(PFont(font_)->characterSet);
+ utfForm = UTF8FromIconv(conv, s, len);
}
if (!utfForm) { // iconv failed so try DBCS if DBCS mode
if (et == dbcs) {
@@ -1279,14 +1264,13 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positi
} else {
int positionsCalculated = 0;
if (et == dbcs) {
- SetIconv(PFont(font_)->characterSet);
- char *utfForm = UTF8FromIconv(iconvh, s, len);
+ SetConverter(PFont(font_)->characterSet);
+ char *utfForm = UTF8FromIconv(conv, s, len);
if (utfForm) {
// Convert to UTF-8 so can ask Pango for widths, then
// Loop through UTF-8 and DBCS forms, taking account of different
// character byte lengths.
- iconv_t iconvhMeasure =
- iconv_open("UCS-2", CharacterSetID(characterSet));
+ Converter convMeasure("UCS-2", CharacterSetID(characterSet));
pango_layout_set_text(layout, utfForm, strlen(utfForm));
int i = 0;
int utfIndex = 0;
@@ -1296,7 +1280,7 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positi
int position = PANGO_PIXELS(pos.x);
int utfIndexNext = pango_layout_iter_get_index (iter);
while (utfIndex < utfIndexNext) {
- size_t lenChar = MultiByteLenFromIconv(iconvhMeasure, s+i, len-i);
+ size_t lenChar = MultiByteLenFromIconv(convMeasure, s+i, len-i);
//size_t lenChar = mblen(s+i, MB_CUR_MAX);
while (lenChar--) {
positions[i++] = position;
@@ -1307,14 +1291,13 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positi
}
pango_layout_iter_free (iter);
delete []utfForm;
- iconv_close(iconvhMeasure);
}
}
if (positionsCalculated < 1 ) {
// Either Latin1 or DBCS conversion failed so treat as Latin1.
bool useGFree = false;
- SetIconv(PFont(font_)->characterSet);
- char *utfForm = UTF8FromIconv(iconvh, s, len);
+ SetConverter(PFont(font_)->characterSet);
+ char *utfForm = UTF8FromIconv(conv, s, len);
if (!utfForm) {
utfForm = UTF8FromLatin1(s, len);
}
@@ -1406,8 +1389,8 @@ int SurfaceImpl::WidthText(Font &font_, const char *s, int len) {
utfForm = UTF8FromDBCS(s, len);
}
if (!utfForm) { // DBCS failed so treat as iconv
- SetIconv(PFont(font_)->characterSet);
- utfForm = UTF8FromIconv(iconvh, s, len);
+ SetConverter(PFont(font_)->characterSet);
+ utfForm = UTF8FromIconv(conv, s, len);
}
if (!utfForm) { // g_locale_to_utf8 failed so treat as Latin1
utfForm = UTF8FromLatin1(s, len);
@@ -2407,10 +2390,8 @@ int Platform::DBCSCharLength(int codePage, const char *s) {
// Experimental and disabled code - change 999932 to 932 above to
// enable locale avoiding but expensive character length determination.
// Avoid locale with explicit use of iconv
- iconv_t iconvhMeasure =
- iconv_open("UCS-2", CharacterSetID(SC_CHARSET_SHIFTJIS));
- size_t lenChar = MultiByteLenFromIconv(iconvhMeasure, s, strlen(s));
- iconv_close(iconvhMeasure);
+ Converter convMeasure("UCS-2", CharacterSetID(SC_CHARSET_SHIFTJIS));
+ size_t lenChar = MultiByteLenFromIconv(convMeasure, s, strlen(s));
return lenChar;
} else {
int bytes = mblen(s, MB_CUR_MAX);