Browse Source

Starting to rework Fl_Text_Display from scratch to make wrapping work correctly. Fixed a few issues that made wrapping crash. Using ASCII range only with fixed character sizes should still wrap as expected?!

git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@7794 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
pull/49/head
Matthias Melcher 15 years ago
parent
commit
38dcb5a463
  1. 14
      FL/Fl_Text_Buffer.H
  2. 78
      FL/Fl_Text_Display.H
  3. 11
      src/Fl_Text_Buffer.cxx
  4. 17
      src/Fl_Text_Display.cxx
  5. 2
      test/editor.cxx

14
FL/Fl_Text_Buffer.H

@ -39,7 +39,7 @@ @@ -39,7 +39,7 @@
?? "length" is the number of characters in a string
?? "size" is the number of bytes
?? "index" is the position in a string in number of characters
?? "offset" is the position in a strin in bytes (and must be kept on a charater boundary)
?? "offset" is the position in a string in bytes (and must be kept on a charater boundary)
(there seems to be no standard in Uncode documents, howevere "length" is commonly
referencing the number of bytes. Maybe "bytes" and "glyphs" would be the most
obvious way to describe sizes?)
@ -154,6 +154,11 @@ typedef void (*Fl_Text_Predelete_Cb)(int pos, int nDeleted, void* cbArg); @@ -154,6 +154,11 @@ typedef void (*Fl_Text_Predelete_Cb)(int pos, int nDeleted, void* cbArg);
/**
\brief This class manages unicode displayed in one or more Fl_Text_Display widgets.
All text in Fl_Text_Buffermust be encoded in UTF-8. All indices used in the
function calls must be aligned to the start of a UTF-8 sequence. All indices
and pointers returned will be aligned. All functions that return a single
character will return that in an unsiged int in UCS-4 encoding.
The Fl_Text_Buffer class is used by the Fl_Text_Display
and Fl_Text_Editor to manage complex text data and is based upon the
excellent NEdit text editor engine - see http://www.nedit.org/.
@ -193,7 +198,7 @@ public: @@ -193,7 +198,7 @@ public:
/**
Replaces the entire contents of the text buffer.
Text must be valid utf8.
\param text Text must be valid utf8.
\todo unicode check
*/
void text(const char* text);
@ -228,12 +233,16 @@ public: @@ -228,12 +233,16 @@ public:
/**
Convert a byte offset in buffer into a memory address.
\param pos byte offset into buffer
\return byte offset converted to a memory address
*/
const char *address(int pos) const
{ return (pos < mGapStart) ? mBuf+pos : mBuf+pos+mGapEnd-mGapStart; }
/**
Convert a byte offset in buffer into a memory address.
\param pos byte offset into buffer
\return byte offset converted to a memory address
*/
char *address(int pos)
{ return (pos < mGapStart) ? mBuf+pos : mBuf+pos+mGapEnd-mGapStart; }
@ -748,6 +757,7 @@ protected: @@ -748,6 +757,7 @@ protected:
expensive and the length will be required by any caller who will continue
on to call redisplay). \p pos must be contiguous with the existing text in
the buffer (i.e. not past the end).
\return the number of bytes inserted
\todo unicode check
*/
int insert_(int pos, const char* text);

78
FL/Fl_Text_Display.H

@ -40,11 +40,12 @@ @@ -40,11 +40,12 @@
#include "Fl_Text_Buffer.H"
/**
This is the FLTK text display widget. It allows the user to
view multiple lines of text and supports highlighting and
scrolling. The buffer that is displayed in the widget is managed
by the Fl_Text_Buffer
class.
\brief Rich text display widget.
This is the FLTK text display widget. It allows the user to view multiple lines
of text and supports highlighting and scrolling. The buffer that is displayed
in the widget is managed by the Fl_Text_Buffer class. A single Text Buffer
can be displayed by multiple Text Displays.
*/
class FL_EXPORT Fl_Text_Display: public Fl_Group
{
@ -54,8 +55,11 @@ class FL_EXPORT Fl_Text_Display: public Fl_Group @@ -54,8 +55,11 @@ class FL_EXPORT Fl_Text_Display: public Fl_Group
text display cursor shapes enumeration
*/
enum {
NORMAL_CURSOR, CARET_CURSOR, DIM_CURSOR,
BLOCK_CURSOR, HEAVY_CURSOR
NORMAL_CURSOR, /**< I-beam */
CARET_CURSOR, /**< caret under the text */
DIM_CURSOR, /**< dim I-beam */
BLOCK_CURSOR, /**< unfille box under the current character */
HEAVY_CURSOR /**< thick I-beam */
};
/**
@ -64,7 +68,8 @@ class FL_EXPORT Fl_Text_Display: public Fl_Group @@ -64,7 +68,8 @@ class FL_EXPORT Fl_Text_Display: public Fl_Group
characters.
*/
enum {
CURSOR_POS, CHARACTER_POS
CURSOR_POS,
CHARACTER_POS
};
/**
@ -73,22 +78,15 @@ class FL_EXPORT Fl_Text_Display: public Fl_Group @@ -73,22 +78,15 @@ class FL_EXPORT Fl_Text_Display: public Fl_Group
word and triple clicking selects by line.
*/
enum {
DRAG_CHAR = 0, DRAG_WORD = 1, DRAG_LINE = 2
DRAG_CHAR = 0,
DRAG_WORD = 1,
DRAG_LINE = 2
};
friend void fl_text_drag_me(int pos, Fl_Text_Display* d);
typedef void (*Unfinished_Style_Cb)(int, void *);
/**
style attributes - currently not implemented!
*/
enum {
ATTR_NONE = 0,
ATTR_UNDERLINE = 1,
ATTR_HIDDEN = 2
};
/**
This structure associates the color,font,size of a string to draw
with an attribute mask matching attr
@ -96,7 +94,7 @@ class FL_EXPORT Fl_Text_Display: public Fl_Group @@ -96,7 +94,7 @@ class FL_EXPORT Fl_Text_Display: public Fl_Group
struct Style_Table_Entry {
Fl_Color color;
Fl_Font font;
int size;
Fl_Fontsize size;
unsigned attr;
};
@ -104,17 +102,20 @@ class FL_EXPORT Fl_Text_Display: public Fl_Group @@ -104,17 +102,20 @@ class FL_EXPORT Fl_Text_Display: public Fl_Group
~Fl_Text_Display();
virtual int handle(int e);
void buffer(Fl_Text_Buffer* buf);
/**
Sets or gets the current text buffer associated with the text widget.
Sets the current text buffer associated with the text widget.
Multiple text widgets can be associated with the same text buffer.
\param buf new text buffer
*/
void buffer(Fl_Text_Buffer& buf) { buffer(&buf); }
/**
Gets the current text buffer associated with the text widget.
Multiple text widgets can be associated with the same text buffer.
\return current text buffer
*/
Fl_Text_Buffer* buffer() const { return mBuffer; }
@ -126,11 +127,13 @@ class FL_EXPORT Fl_Text_Display: public Fl_Group @@ -126,11 +127,13 @@ class FL_EXPORT Fl_Text_Display: public Fl_Group
/**
Gets the position of the text insertion cursor for text display
\return insert position index into text buffer
*/
int insert_position() const { return mCursorPos; }
int in_selection(int x, int y) const;
void show_insert_position();
int move_right();
int move_left();
int move_up();
@ -142,6 +145,7 @@ class FL_EXPORT Fl_Text_Display: public Fl_Group @@ -142,6 +145,7 @@ class FL_EXPORT Fl_Text_Display: public Fl_Group
int rewind_lines(int startPos, int nLines);
void next_word(void);
void previous_word(void);
void show_cursor(int b = 1);
/**
@ -152,42 +156,52 @@ class FL_EXPORT Fl_Text_Display: public Fl_Group @@ -152,42 +156,52 @@ class FL_EXPORT Fl_Text_Display: public Fl_Group
void cursor_style(int style);
/**
Sets or gets the text cursor color.
Gets the text cursor color.
\return cursor color
*/
Fl_Color cursor_color() const {return mCursor_color;}
/**
Sets or gets the text cursor color.
Sets the text cursor color.
\param n new cursor color
*/
void cursor_color(Fl_Color n) {mCursor_color = n;}
/**
Sets or gets the width/height of the scrollbars.
Gets the width/height of the scrollbars.
/return width of scrollbars
*/
int scrollbar_width() const { return scrollbar_width_; }
/**
Sets or gets the width/height of the scrollbars.
Sets the width/height of the scrollbars.
\param W width of scrollbars
*/
void scrollbar_width(int W) { scrollbar_width_ = W; }
/**
Gets the scrollbar alignment type
\return scrollbar alignment
*/
Fl_Align scrollbar_align() const { return scrollbar_align_; }
/**
Sets the scrollbar alignment type
\param a new scrollbar alignment
*/
void scrollbar_align(Fl_Align a) { scrollbar_align_ = a; }
/**
Moves the insert position to the beginning of the current word.
\param pos start calculation at this index
\return beginning of the wors
*/
int word_start(int pos) const { return buffer()->word_start(pos); }
/**
Moves the insert position to the end of the current word.
\param pos start calculation at this index
\return index of first character after the end of the word
*/
int word_end(int pos) const { return buffer()->word_end(pos); }
@ -203,42 +217,50 @@ class FL_EXPORT Fl_Text_Display: public Fl_Group @@ -203,42 +217,50 @@ class FL_EXPORT Fl_Text_Display: public Fl_Group
/**
\todo FIXME : get set methods pointing on shortcut_
have no effects as shortcut_ is unused in this class and derived!
\return the current shortcut key
*/
int shortcut() const {return shortcut_;}
/**
\todo FIXME : get set methods pointing on shortcut_
have no effects as shortcut_ is unused in this class and derived!
\param s the new shortcut key
*/
void shortcut(int s) {shortcut_ = s;}
/**
Gets the default font used when drawing text in the widget.
\return current text font face unless overriden by a style
*/
Fl_Font textfont() const {return textfont_;}
/**
Sets the default font used when drawing text in the widget.
\param s default text font face
*/
void textfont(Fl_Font s) {textfont_ = s;}
/**
Gets the default size of text in the widget.
\return current text height unless overriden by a style
*/
Fl_Fontsize textsize() const {return textsize_;}
/**
Sets the default size of text in the widget.
\param s new text size
*/
void textsize(Fl_Fontsize s) {textsize_ = s;}
/**
Gets the default color of text in the widget.
\return text color unless overriden by a style
*/
Fl_Color textcolor() const {return textcolor_;}
/**
Sets the default color of text in the widget.
\param n new text color
*/
void textcolor(Fl_Color n) {textcolor_ = n;}
@ -266,7 +288,13 @@ class FL_EXPORT Fl_Text_Display: public Fl_Group @@ -266,7 +288,13 @@ class FL_EXPORT Fl_Text_Display: public Fl_Group
int leftCharIndex, int rightCharIndex);
int find_x(const char *s, int len, int style, int x) const;
enum { DRAW_LINE, FIND_INDEX, GET_WIDTH };
enum {
DRAW_LINE,
FIND_INDEX,
GET_WIDTH
};
int handle_vline(int mode,
int lineStart, int lineLen, int leftChar, int rightChar,
int topClip, int bottomClip,

11
src/Fl_Text_Buffer.cxx

@ -270,6 +270,10 @@ char Fl_Text_Buffer::byte_at(int pos) const { @@ -270,6 +270,10 @@ char Fl_Text_Buffer::byte_at(int pos) const {
*/
void Fl_Text_Buffer::insert(int pos, const char *text)
{
/* check if there is actually any text */
if (!text || !*text)
return;
/* if pos is not contiguous to existing text, make it */
if (pos > mLength)
pos = mLength;
@ -1010,7 +1014,7 @@ int Fl_Text_Buffer::search_forward(int startPos, const char *searchString, @@ -1010,7 +1014,7 @@ int Fl_Text_Buffer::search_forward(int startPos, const char *searchString,
return 1;
}
// FIXME: character is ucs-4
} while ((matchCase ? char_at(bp++) == *sp++ :
} while ((matchCase ? char_at(bp++) == (unsigned int)*sp++ :
toupper(char_at(bp++)) == toupper(*sp++))
&& bp < length());
startPos++;
@ -1040,7 +1044,7 @@ int Fl_Text_Buffer::search_backward(int startPos, const char *searchString, @@ -1040,7 +1044,7 @@ int Fl_Text_Buffer::search_backward(int startPos, const char *searchString,
return 1;
}
// FIXME: character is ucs-4
} while ((matchCase ? char_at(bp--) == *sp-- :
} while ((matchCase ? char_at(bp--) == (unsigned int)*sp-- :
toupper(char_at(bp--)) == toupper(*sp--))
&& bp >= 0);
startPos--;
@ -1128,6 +1132,9 @@ int Fl_Text_Buffer::findchars_backward(int startPos, const char *searchChars, @@ -1128,6 +1132,9 @@ int Fl_Text_Buffer::findchars_backward(int startPos, const char *searchChars,
*/
int Fl_Text_Buffer::insert_(int pos, const char *text)
{
if (!text || !*text)
return 0;
int insertedLength = strlen(text);
/* Prepare the buffer to receive the new text. If the new text fits in

17
src/Fl_Text_Display.cxx

@ -25,6 +25,8 @@ @@ -25,6 +25,8 @@
// http://www.fltk.org/str.php
//
// TODO: check all functions for UTF-8/UCS-4 compatibility!
#include <stdio.h>
#include <stdlib.h>
#include <FL/fl_utf8.h>
@ -169,8 +171,10 @@ Fl_Text_Display::~Fl_Text_Display() { @@ -169,8 +171,10 @@ Fl_Text_Display::~Fl_Text_Display() {
if (mLineStarts) delete[] mLineStarts;
}
/**
Attach a text buffer to display, replacing the current buffer (if any)
\param buf attach this text buffer
*/
void Fl_Text_Display::buffer( Fl_Text_Buffer *buf ) {
/* If the text display is already displaying a buffer, clear it off
@ -725,15 +729,13 @@ int Fl_Text_Display::position_to_linecol( int pos, int* lineNum, int* column ) c @@ -725,15 +729,13 @@ int Fl_Text_Display::position_to_linecol( int pos, int* lineNum, int* column ) c
pos < mFirstChar || pos > mLastChar)
return 0;
*lineNum = mAbsTopLineNum + buffer()->count_lines(mFirstChar, pos);
*column
= buffer()->count_displayed_characters(buffer()->line_start(pos), pos);
*column = buffer()->count_displayed_characters(buffer()->line_start(pos), pos);
return 1;
}
retVal = position_to_line( pos, lineNum );
if ( retVal ) {
*column = mBuffer->count_displayed_characters(
mLineStarts[ *lineNum ], pos );
*column = mBuffer->count_displayed_characters( mLineStarts[ *lineNum ], pos );
*lineNum += mTopLineNum;
}
return retVal;
@ -1431,6 +1433,10 @@ int Fl_Text_Display::handle_vline( @@ -1431,6 +1433,10 @@ int Fl_Text_Display::handle_vline(
startX += w;
startIndex = i;
}
if (len==-1) {
// FIXME: what happened? Is there an illegal charater, or an illegal index?
len = 1;
}
i += len;
}
int w = string_width( lineStr+startIndex, i-startIndex, style );
@ -2234,8 +2240,7 @@ int Fl_Text_Display::measure_vline( int visLineNum ) const { @@ -2234,8 +2240,7 @@ int Fl_Text_Display::measure_vline( int visLineNum ) const {
Return true if there are lines visible with no corresponding buffer text
*/
int Fl_Text_Display::empty_vlines() const {
return mNVisibleLines > 0 &&
mLineStarts[ mNVisibleLines - 1 ] == -1;
return (mNVisibleLines > 0) && (mLineStarts[ mNVisibleLines - 1 ] == -1);
}
/**

2
test/editor.cxx

@ -785,6 +785,7 @@ Fl_Window* new_view() { @@ -785,6 +785,7 @@ Fl_Window* new_view() {
Fl_Menu_Bar* m = new Fl_Menu_Bar(0, 0, 660, 30);
m->copy(menuitems, w);
w->editor = new Fl_Text_Editor(0, 30, 660, 370);
w->editor->wrap_mode(1, 32);
w->editor->textfont(FL_COURIER);
w->editor->textsize(TS);
w->editor->buffer(textbuf);
@ -812,6 +813,7 @@ int main(int argc, char **argv) { @@ -812,6 +813,7 @@ int main(int argc, char **argv) {
" if ( fnfc.show() ) return;\n"
" save_file(fnfc.filename());\n"
"}\n\n"
" 2 4 6 8 0 2 4 6 8 0 2 4 6 8 0 2 4 6 8 0\n\n"
"// Falsches Üben von Xylophonmusik quält jeden größeren Zwerg\n"
"// (= Wrongful practicing of xylophone music tortures every larger dwarf)\n"
"\n"

Loading…
Cancel
Save