summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManolo Gouy <Manolo>2014-03-28 10:15:43 +0000
committerManolo Gouy <Manolo>2014-03-28 10:15:43 +0000
commit623012ad7288011c4fdb040446b2e2a1a927f354 (patch)
treeed947f59ab6373fa8818e75ea3383291c8521191
parent7accbfd440e4bd8bf28b9b2b910cec2bff0511a6 (diff)
Removes a constraint that the fancy string drawing function fl_draw() is limited to 1024 chars/line
that blocked a user of the Fl_Browser widget (see "fl_draw MAXBUF limit" in fltk.coredev). Also, removed a useless computation in string expansion that checked for valid UTF-8 sequences: the point is that a valid UTF-8 sequence for a non-ascii char contains no ascii char, thus no tab, space, control, & or @ we want to process differently. Also, invalid UTF-8 sequences are copied unchanged by this procedure. Therefore, checking for tab, space, control, & or @, and copying the byte otherwise, is enough. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@10123 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
-rw-r--r--src/fl_draw.cxx93
1 files changed, 58 insertions, 35 deletions
diff --git a/src/fl_draw.cxx b/src/fl_draw.cxx
index 10082f5e9..361881bfd 100644
--- a/src/fl_draw.cxx
+++ b/src/fl_draw.cxx
@@ -32,17 +32,16 @@
#include <ctype.h>
#include <math.h>
-#define MAXBUF 1024
char fl_draw_shortcut; // set by fl_labeltypes.cxx
static char* underline_at;
-/**
+/* This function is no longer called
utf8 multibyte char seq. detection an pass-thru routine.
\retval false if no utf8 seq detected, no change made. true if utf8 and d copied with s seq.
- note that for n bytes copied dest incremented of n, but s of n-1 for compatible loop use see below.
-*/
+ note that for n bytes copied d incremented of n, but s of n-1 for compatible loop use see below.
+*
#define C_IN(c,a,b) ((c)>=(a) && (c)<=(b))
#define C_UTF8(c) C_IN(c,0x80,0xBF)
@@ -88,27 +87,26 @@ static bool handle_utf8_seq(const char * &s,char * &d) {
// fprintf(stderr, "Not UTF8 char \n");
return false;
}
- return true; // we did handled and copied the utf8 multibyte char seq.
-}
-
-/**
- Copy \p from to \p buf, replacing unprintable characters with ^X and \\nnn.
-
- Stop at a newline or if MAXBUF characters written to buffer.
- Also word-wrap if width exceeds maxw.
- Returns a pointer to the start of the next line of characters.
- Sets n to the number of characters put into the buffer.
- Sets width to the width of the string in the current font.
-*/
-const char*
-fl_expand_text(const char* from, char* buf, int maxbuf, double maxw, int& n,
- double &width, int wrap, int draw_symbols) {
- char* o = buf;
+ return true; // we handled and copied the utf8 multibyte char seq.
+}*/
+
+/* If called with maxbuf==0, use an internally allocated buffer and enlarge it as needed.
+ Otherwise, use buf as buffer but don't go beyond its length of maxbuf.
+ */
+static const char* expand_text_(const char* from, char*& buf, int maxbuf, double maxw, int& n,
+ double &width, int wrap, int draw_symbols) {
char* e = buf+(maxbuf-4);
underline_at = 0;
+ double w = 0;
+ static int l_local_buff = 500;
+ static char *local_buf = (char*)malloc(l_local_buff); // initial buffer allocation
+ if (maxbuf == 0) {
+ buf = local_buf;
+ e = buf + l_local_buff - 4;
+ }
+ char* o = buf;
char* word_end = o;
const char* word_start = from;
- double w = 0;
const char* p = from;
for (;; p++) {
@@ -132,7 +130,15 @@ fl_expand_text(const char* from, char* buf, int maxbuf, double maxw, int& n,
word_start = p+1;
}
- if (o > e) break; // don't overflow buffer
+ if (o > e) {
+ if (maxbuf) break; // don't overflow buffer
+ l_local_buff += (o - e) + 200; // enlarge buffer
+ buf = (char*)realloc(local_buf, l_local_buff);
+ e = buf + l_local_buff - 4; // update pointers to buffer content
+ o = buf + (o - local_buf);
+ word_end = buf + (word_end - local_buf);
+ local_buf = buf;
+ }
if (c == '\t') {
for (c = fl_utf_nb_char((uchar*)buf, (int) (o-buf) )%8; c<8 && o<e; c++)
@@ -143,14 +149,17 @@ fl_expand_text(const char* from, char* buf, int maxbuf, double maxw, int& n,
} else if (c < ' ' || c == 127) { // ^X
*o++ = '^';
*o++ = c ^ 0x40;
- } else if (handle_utf8_seq(p, o)) { // figure out if we have an utf8 valid sequence before we determine the nbsp test validity:
+/* This is in fact not useful: the point is that a valid UTF-8 sequence for a non-ascii char contains no ascii char,
+ thus no tab, space, control, & or @ we want to process differently.
+ Also, invalid UTF-8 sequences are copied unchanged by this procedure.
+ Therefore, checking for tab, space, control, & or @, and copying the byte otherwise, is enough.
+ } else if (handle_utf8_seq(p, o)) { // figure out if we have an utf8 valid sequence before we determine the nbsp test validity:
#ifdef __APPLE__
} else if (c == 0xCA) { // non-breaking space in MacRoman
#else
} else if (c == 0xA0) { // non-breaking space in ISO 8859
#endif
- *o++ = ' ';
-
+ *o++ = ' ';*/
} else if (c == '@' && draw_symbols) { // Symbol???
if (p[1] && p[1] != '@') break;
*o++ = c;
@@ -167,6 +176,21 @@ fl_expand_text(const char* from, char* buf, int maxbuf, double maxw, int& n,
}
/**
+ Copy \p from to \p buf, replacing control characters with ^X.
+
+ Stop at a newline or if \p maxbuf characters written to buffer.
+ Also word-wrap if width exceeds maxw.
+ Returns a pointer to the start of the next line of characters.
+ Sets n to the number of characters put into the buffer.
+ Sets width to the width of the string in the current font.
+ */
+const char*
+fl_expand_text(const char* from, char* buf, int maxbuf, double maxw, int& n,
+ double &width, int wrap, int draw_symbols) {
+ return expand_text_(from, buf, maxbuf, maxw, n, width, wrap, draw_symbols);
+}
+
+/**
The same as fl_draw(const char*,int,int,int,int,Fl_Align,Fl_Image*,int) with
the addition of the \p callthis parameter, which is a pointer to a text drawing
function such as fl_draw(const char*, int, int, int) to do the real work
@@ -178,9 +202,9 @@ void fl_draw(
void (*callthis)(const char*,int,int,int),
Fl_Image* img, int draw_symbols)
{
+ char *linebuf = NULL;
const char* p;
const char* e;
- char buf[MAXBUF];
int buflen;
char symbol[2][255], *symptr;
int symwidth[2], symoffset, symtotal, imgtotal;
@@ -223,7 +247,7 @@ void fl_draw(
if (str) {
for (p = str, lines=0; p;) {
- e = fl_expand_text(p, buf, MAXBUF, w - symtotal - imgtotal, buflen, width,
+ e = expand_text_(p, linebuf, 0, w - symtotal - imgtotal, buflen, width,
align&FL_ALIGN_WRAP, draw_symbols);
if (strw<width) strw = (int)width;
lines++;
@@ -290,7 +314,7 @@ void fl_draw(
if (str) {
int desc = fl_descent();
for (p=str; ; ypos += height) {
- if (lines>1) e = fl_expand_text(p, buf, MAXBUF, w - symtotal - imgtotal, buflen,
+ if (lines>1) e = expand_text_(p, linebuf, 0, w - symtotal - imgtotal, buflen,
width, align&FL_ALIGN_WRAP, draw_symbols);
else e = "";
@@ -300,10 +324,10 @@ void fl_draw(
else if (align & FL_ALIGN_RIGHT) xpos = x + w - (int)(width + .5) - symwidth[1] - imgw[1];
else xpos = x + (w - (int)(width + .5) - symtotal - imgw[0] - imgw[1]) / 2 + symwidth[0] + imgw[0];
- callthis(buf,buflen,xpos,ypos-desc);
+ callthis(linebuf,buflen,xpos,ypos-desc);
- if (underline_at && underline_at >= buf && underline_at < (buf + buflen))
- callthis("_",1,xpos+int(fl_width(buf,(int) (underline_at-buf))),ypos-desc);
+ if (underline_at && underline_at >= linebuf && underline_at < (linebuf + buflen))
+ callthis("_",1,xpos+int(fl_width(linebuf,(int) (underline_at-linebuf))),ypos-desc);
if (!*e || (*e == '@' && e[1] != '@')) break;
p = e;
@@ -361,7 +385,6 @@ void fl_draw(
below the text as specified by the \p align value.
The \p draw_symbols argument specifies whether or not to look for symbol
names starting with the '\@' character'
- The text length is limited to 1024 characters per line.
*/
void fl_draw(
const char* str,
@@ -406,9 +429,9 @@ void fl_draw(
void fl_measure(const char* str, int& w, int& h, int draw_symbols) {
if (!str || !*str) {w = 0; h = 0; return;}
h = fl_height();
+ char *linebuf = NULL;
const char* p;
const char* e;
- char buf[MAXBUF];
int buflen;
int lines;
double width=0;
@@ -436,8 +459,8 @@ void fl_measure(const char* str, int& w, int& h, int draw_symbols) {
symtotal = symwidth[0] + symwidth[1];
for (p = str, lines=0; p;) {
-// e = expand(p, buf, w - symtotal, buflen, width, w != 0, draw_symbols);
- e = fl_expand_text(p, buf, MAXBUF, w - symtotal, buflen, width,
+// e = expand(p, linebuf, w - symtotal, buflen, width, w != 0, draw_symbols);
+ e = expand_text_(p, linebuf, 0, w - symtotal, buflen, width,
w != 0, draw_symbols);
if ((int)ceil(width) > W) W = (int)ceil(width);
lines++;