summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FL/Fl_Text_Buffer.H4
-rw-r--r--src/Fl_Text_Buffer.cxx126
-rw-r--r--src/Fl_Text_Display.cxx2
3 files changed, 108 insertions, 24 deletions
diff --git a/FL/Fl_Text_Buffer.H b/FL/Fl_Text_Buffer.H
index 909775f84..7a8fedb41 100644
--- a/FL/Fl_Text_Buffer.H
+++ b/FL/Fl_Text_Buffer.H
@@ -75,7 +75,6 @@ public:
\brief Set the selection range.
\param start byte offset to first selected character
\param end byte offset pointing after last selected character
- \todo unicode check
*/
void set(int start, int end);
@@ -85,7 +84,6 @@ public:
\param end byte offset pointing after last selected character
\param rectStart first selected column
\param rectEnd last selected column +1
- \todo unicode check
*/
void set_rectangular(int start, int end, int rectStart, int rectEnd);
@@ -154,7 +152,6 @@ public:
\brief Return the positions of this selection.
\param start retrun byte offset to first selected character
\param end retrun byte offset pointing after last selected character
- \todo unicode check
*/
int position(int* start, int* end) const;
@@ -165,7 +162,6 @@ public:
\param isRect return if the selection is rectangular
\param rectStart return first selected column
\param rectEnd return last selected column +1
- \todo unicode check
*/
int position(int* start, int* end, int* isRect, int* rectStart, int* rectEnd) const;
diff --git a/src/Fl_Text_Buffer.cxx b/src/Fl_Text_Buffer.cxx
index 490729337..aa957e867 100644
--- a/src/Fl_Text_Buffer.cxx
+++ b/src/Fl_Text_Buffer.cxx
@@ -33,29 +33,92 @@
#include <FL/Fl.H>
#include <FL/Fl_Text_Buffer.H>
+/*
+ This file is based on a port of NEdit to FLTK many years ago. NEdit at that
+ point was already stretched beyond the task it was designed for which explains
+ why the source code is sometimes pretty convoluted. It still is a nice widget
+ for FLTK.
+
+ With the introduction of Unicode and UTF-8, Fl_Text_... has to go into a whole
+ new generation of code. Originally designed for monspaced fonts only, many
+ features make les sense in the multibyte and multiwdth world of UTF-8.
+
+ Columns are a good example. There is simply no such thing.
+
+ Rectangular selections pose a real problem.
+
+ Using multiple spaces to emulate tab stops will no longer work.
+
+ And constantly recalculating character widths is just much too expensive.
+
+ But nevertheless, we will get ths widget rolling again ;-)
+
+ */
+
+/*
+ \todo unicode check
+ */
static void insertColInLine(const char *line, char *insLine, int column,
int insWidth, int tabDist, int useTabs,
char *outStr, int *outLen,
int *endOffset);
+
+/*
+ \todo unicode check
+ */
static void deleteRectFromLine(const char *line, int rectStart,
int rectEnd, int tabDist, int useTabs,
char *outStr,
int *outLen, int *endOffset);
+
+/*
+ \todo unicode check
+ */
static void overlayRectInLine(const char *line, char *insLine,
int rectStart, int rectEnd, int tabDist,
int useTabs, char *outStr,
int *outLen, int *endOffset);
+
+/*
+ \todo unicode check
+ */
static void addPadding(char *string, int startIndent, int toIndent,
int tabDist, int useTabs, int *charsAdded);
+
+/*
+ \todo unicode check
+ */
static char *copyLine(const char *text, int *lineLen);
+
+/*
+ unicode tested
+ */
static int countLines(const char *string);
+
+/*
+ \todo unicode check
+ */
static int textWidth(const char *text, int tabDist);
+
+/*
+ \todo unicode check
+ */
static char *realignTabs(const char *text, int origIndent, int newIndent,
int tabDist, int useTabs, int *newLength);
+
+/*
+ \todo unicode check
+ */
static char *expandTabs(const char *text, int startIndent, int tabDist, int *newLen);
+
+/*
+ \todo unicode check
+ */
static char *unexpandTabs(char *text, int startIndent, int tabDist, int *newLen);
+
#ifndef min
+
static int max(int i1, int i2)
{
return i1 >= i2 ? i1 : i2;
@@ -65,6 +128,7 @@ static int min(int i1, int i2)
{
return i1 <= i2 ? i1 : i2;
}
+
#endif
static const char *ControlCodeTable[32] = {
@@ -901,11 +965,12 @@ int Fl_Text_Buffer::expand_character(char c, int indent, char *outStr, int tabDi
} else if (c == 127) {
sprintf(outStr, "<del>");
return 5;
- } else if (c == 0) {
- sprintf(outStr, "<nul>");
- return 5;
} else if ((c & 0x80) && !(c & 0x40)) {
- return 0;
+#ifdef DEBUG
+ fprintf(stderr, "%s:%d - Error in UTF-8 encoding!\n", __FILE__, __LINE__);
+#endif
+ *outStr = c;
+ return 1;
} else if (c & 0x80) {
*outStr = c;
return fl_utf8len(c);
@@ -919,17 +984,18 @@ int Fl_Text_Buffer::expand_character(char c, int indent, char *outStr, int tabDi
int Fl_Text_Buffer::character_width(char c, int indent, int tabDist)
{
/* Note, this code must parallel that in Fl_Text_Buffer::ExpandCharacter */
- if (c == '\t')
+ if (c == '\t') {
return tabDist - (indent % tabDist);
- else if (((unsigned char) c) <= 31)
+ } else if (((unsigned char) c) <= 31) {
return strlen(ControlCodeTable[(unsigned char) c]) + 2;
- else if (c == 127)
- return 5;
- else if (c == 0)
+ } else if (c == 127) {
return 5;
- else if ((c & 0x80) && !(c & 0x40))
- return 0;
- else if (c & 0x80) {
+ } else if ((c & 0x80) && !(c & 0x40)) {
+#ifdef DEBUG
+ fprintf(stderr, "%s:%d - Error in UTF-8 encoding!\n", __FILE__, __LINE__);
+#endif
+ return 1;
+ } else if (c & 0x80) {
return fl_utf8len(c);
}
return 1;
@@ -1655,6 +1721,9 @@ static void overlayRectInLine(const char *line, char *insLine,
*outLen = (outPtr - outStr) + strlen(linePtr);
}
+
+// simple setter
+// Unicode safe
void Fl_Text_Selection::set(int startpos, int endpos)
{
mSelected = startpos != endpos;
@@ -1663,6 +1732,9 @@ void Fl_Text_Selection::set(int startpos, int endpos)
mEnd = max(startpos, endpos);
}
+
+// simple setter
+// Unicode safe
void Fl_Text_Selection::set_rectangular(int startpos, int endpos,
int rectStart, int rectEnd)
{
@@ -1674,6 +1746,9 @@ void Fl_Text_Selection::set_rectangular(int startpos, int endpos,
mRectEnd = rectEnd;
}
+
+// simple getter
+// Unicode safe
int Fl_Text_Selection::position(int *startpos, int *endpos) const {
if (!mSelected)
return 0;
@@ -1681,7 +1756,12 @@ int Fl_Text_Selection::position(int *startpos, int *endpos) const {
*endpos = mEnd;
return 1;
-} int Fl_Text_Selection::position(int *startpos, int *endpos,
+}
+
+
+// simple getter
+// Unicode safe
+int Fl_Text_Selection::position(int *startpos, int *endpos,
int *isRect, int *rectStart,
int *rectEnd) const {
if (!mSelected)
@@ -1697,13 +1777,18 @@ int Fl_Text_Selection::position(int *startpos, int *endpos) const {
return 1;
}
+
int Fl_Text_Selection::includes(int pos, int lineStartPos, int dispIndex) const {
- return selected() &&
- ((!rectangular() && pos >= start() && pos < end()) ||
- (rectangular() && pos >= start() && lineStartPos <= end() &&
- dispIndex >= rect_start() && dispIndex < rect_end())
- );
-} char *Fl_Text_Buffer::selection_text_(Fl_Text_Selection * sel) const {
+ return (selected()
+ && ( (!rectangular() && pos >= start() && pos < end())
+ || (rectangular() && pos >= start() && lineStartPos <= end()
+ && dispIndex >= rect_start() && dispIndex < rect_end()
+ )
+ )
+ );
+}
+
+char *Fl_Text_Buffer::selection_text_(Fl_Text_Selection * sel) const {
int start, end, isRect, rectStart, rectEnd;
/* If there's no selection, return an allocated empty string */
@@ -2007,7 +2092,8 @@ static char *copyLine(const char *text, int *lineLen)
}
/*
- Counts the number of newlines in a null-terminated text string;
+ Counts the number of newlines in a null-terminated text string.
+ Unicode tested.
*/
static int countLines(const char *string)
{
diff --git a/src/Fl_Text_Display.cxx b/src/Fl_Text_Display.cxx
index eb0598cdb..31ea985b8 100644
--- a/src/Fl_Text_Display.cxx
+++ b/src/Fl_Text_Display.cxx
@@ -1543,6 +1543,7 @@ void Fl_Text_Display::draw_vline(int visLineNum, int leftClip, int rightClip,
int l = 1;
if (*outPtr & 0x80) {
l = fl_utf8len(*outPtr);
+ if (l<=0) l = 1;
}
charWidth = string_width( &expandedChar[ i ], l, charStyle );
} else
@@ -1590,6 +1591,7 @@ void Fl_Text_Display::draw_vline(int visLineNum, int leftClip, int rightClip,
int l = 1;
if (*outPtr & 0x80) {
l = fl_utf8len(*outPtr);
+ if (l<=0) l = 1;
}
charWidth = string_width( &expandedChar[ i ], l, charStyle );
} else