Starting to clean up and document Fl_Text_... to acheive UTF-8 support.

git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@7428 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Matthias Melcher 2010-04-05 12:45:03 +00:00
parent dcdc4439cc
commit f2fa59fd0f
2 changed files with 118 additions and 163 deletions

View File

@ -33,68 +33,147 @@
#ifndef FL_TEXT_BUFFER_H
#define FL_TEXT_BUFFER_H
/*
UTF-8 terminology for this file:
"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)
"character size" is the size of a UTF-8 character in bytes
"character width" is the width of a Unicode character in pixels
"column" was orginally defined as a character offset from the left margin. It was
identical to the byte offset. In UTF-8, we have neither a byte offset nor
truly fixed width fonts. Column could be a pixel value multiplied with
an average character width (which is a bearable approximation).
*/
/* Maximum length in characters of a tab or control character expansion
of a single buffer character */
#define FL_TEXT_MAX_EXP_CHAR_LEN 20
#include "Fl_Export.H"
/** \class Fl_Text_Selection
This is an internal class for Fl_Text_Buffer to manage text selections.
\todo members must be documented
/**
\class Fl_Text_Selection
\brief This is an internal class for Fl_Text_Buffer to manage text selections.
*/
class FL_EXPORT Fl_Text_Selection {
friend class Fl_Text_Buffer;
public:
void set(int start, int end);
void set_rectangular(int start, int end, int rectStart, int rectEnd);
void update(int pos, int nDeleted, int nInserted);
char rectangular() const { return mRectangular; }
int start() const { return mStart; }
int end() const { return mEnd; }
int rect_start() const { return mRectStart; }
int rect_end() const { return mRectEnd; }
/**
Returns a non-zero number if any text has been selected, or 0
if no text is selected.
*/
char selected() const { return mSelected; }
void selected(char b) { mSelected = b; }
int includes(int pos, int lineStartPos, int dispIndex) const;
int position(int* start, int* end) const;
int position(int* start, int* end, int* isRect, int* rectStart, int* rectEnd) const;
public:
/**
\brief Set the selection range.
\param start byte offset to first selected character
\param end byte offset pointing after last selected character
*/
void set(int start, int end);
/**
\brief Set a regtangular selection range.
\param start byte offset to first selected character
\param end byte offset pointing after last selected character
\param rectStart first selected column
\param rectEnd last selected column +1
*/
void set_rectangular(int start, int end, int rectStart, int rectEnd);
/**
\brief Updates a selection afer text was modified.
\param pos byte offset into text buffer at which the change occured
\param nDeleted number of bytes deleted from the buffer
\param nInserted number of bytes inserted into the buffer
*/
void update(int pos, int nDeleted, int nInserted);
/**
\brief Returns true if the selection is rectangular.
*/
char rectangular() const { return mRectangular; }
/**
\brief Return the byte offset to the first selected character.
*/
int start() const { return mStart; }
/**
\brief Return the byte ofsset to the character after the last selected character.
*/
int end() const { return mEnd; }
/**
\brief Return the first column of the rectangular selection.
*/
int rect_start() const { return mRectStart; }
/**
\brief Return the last column of the rectangular selection + 1.
*/
int rect_end() const { return mRectEnd; }
/**
\brief Returns true if any text is selected.
Returns a non-zero number if any text has been selected, or 0
if no text is selected.
*/
char selected() const { return mSelected; }
/**
\brief Modify the 'selected' flag.
*/
void selected(char b) { mSelected = b; }
/**
\brief ??
*/
int includes(int pos, int lineStartPos, int dispIndex) const;
/**
\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
*/
int position(int* start, int* end) const;
/**
\brief Return the positions of this rectangular selection.
\param start return byte offset to first selected character
\param end return byte offset pointing after last selected character
\param isRect return if the selection is rectangular
\param rectStart return first selected column
\param rectEnd return last selected column +1
*/
int position(int* start, int* end, int* isRect, int* rectStart, int* rectEnd) const;
protected:
char mSelected;
char mRectangular;
int mStart;
int mEnd;
int mRectStart;
int mRectEnd;
protected:
char mSelected; ///< this flag is set if any text is selected
char mRectangular; ///< this flag is set if the selection is rectangular
int mStart; ///< byte offset to the first selected character
int mEnd; ///< byte offset to the character after the last selected character
int mRectStart; ///< first selected column (see "column")
int mRectEnd; ///< last selected column +1 (see "column")
};
typedef void (*Fl_Text_Modify_Cb)(int pos, int nInserted, int nDeleted,
int nRestyled, const char* deletedText,
void* cbArg);
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.
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/.
*/
/**
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/.
*/
class FL_EXPORT Fl_Text_Buffer {
public:
Fl_Text_Buffer(int requestedSize = 0, int preferredGapSize = 1024);

View File

@ -223,133 +223,9 @@ void Fl_Text_Display::highlight_data(Fl_Text_Buffer *styleBuffer,
mHighlightCBArg = cbArg;
mStyleBuffer->canUndo(0);
#if 0
// FIXME: this is in nedit code -- is it needed?
/* Call TextDSetFont to combine font information from style table and
primary font, adjust font-related parameters, and then redisplay */
TextDSetFont(textD, textD->fontStruct);
#endif
damage(FL_DAMAGE_EXPOSE);
}
#if 0
// FIXME: this is in nedit code -- is it needed?
/**
Change the (non highlight) font
*/
void TextDSetFont(textDisp *textD, XFontStruct *fontStruct) {
Display *display = XtDisplay(textD->w);
int i, maxAscent = fontStruct->ascent, maxDescent = fontStruct->descent;
int width, height, fontWidth;
Pixel bgPixel, fgPixel, selectFGPixel, selectBGPixel;
Pixel highlightFGPixel, highlightBGPixel;
XGCValues values;
XFontStruct *styleFont;
/* If font size changes, cursor will be redrawn in a new position */
blankCursorProtrusions(textD);
/* If there is a (syntax highlighting) style table in use, find the new
maximum font height for this text display */
for (i=0; i<textD->nStyles; i++) {
styleFont = textD->styleTable[i].font;
if (styleFont != NULL && styleFont->ascent > maxAscent)
maxAscent = styleFont->ascent;
if (styleFont != NULL && styleFont->descent > maxDescent)
maxDescent = styleFont->descent;
}
textD->ascent = maxAscent;
textD->descent = maxDescent;
/* If all of the current fonts are fixed and match in width, compute */
fontWidth = fontStruct->max_bounds.width;
if (fontWidth != fontStruct->min_bounds.width)
fontWidth = -1;
else {
for (i=0; i<textD->nStyles; i++) {
styleFont = textD->styleTable[i].font;
if (styleFont != NULL && (styleFont->max_bounds.width != fontWidth ||
styleFont->max_bounds.width != styleFont->min_bounds.width))
fontWidth = -1;
}
}
textD->fixedFontWidth = fontWidth;
/* Don't let the height dip below one line, or bad things can happen */
if (textD->height < maxAscent + maxDescent)
textD->height = maxAscent + maxDescent;
/* Change the font. In most cases, this means re-allocating the
affected GCs (they are shared with other widgets, and if the primary
font changes, must be re-allocated to change it). Unfortunately,
this requres recovering all of the colors from the existing GCs */
textD->fontStruct = fontStruct;
XGetGCValues(display, textD->gc, GCForeground|GCBackground, &values);
fgPixel = values.foreground;
bgPixel = values.background;
XGetGCValues(display, textD->selectGC, GCForeground|GCBackground, &values);
selectFGPixel = values.foreground;
selectBGPixel = values.background;
XGetGCValues(display, textD->highlightGC,GCForeground|GCBackground,&values);
highlightFGPixel = values.foreground;
highlightBGPixel = values.background;
releaseGC(textD->w, textD->gc);
releaseGC(textD->w, textD->selectGC);
releaseGC(textD->w, textD->highlightGC);
releaseGC(textD->w, textD->selectBGGC);
releaseGC(textD->w, textD->highlightBGGC);
if (textD->lineNumGC != NULL)
releaseGC(textD->w, textD->lineNumGC);
textD->lineNumGC = NULL;
allocateFixedFontGCs(textD, fontStruct, bgPixel, fgPixel, selectFGPixel,
selectBGPixel, highlightFGPixel, highlightBGPixel);
XSetFont(display, textD->styleGC, fontStruct->fid);
/* Do a full resize to force recalculation of font related parameters */
width = textD->width;
height = textD->height;
textD->width = textD->height = 0;
TextDResize(textD, width, height);
/* Redisplay */
TextDRedisplayRect(textD, textD->left, textD->top, textD->width,
textD->height);
/* Clean up line number area in case spacing has changed */
draw_line_numbers(textD, True);
}
int TextDMinFontWidth(textDisp *textD, Boolean considerStyles) {
int fontWidth = textD->fontStruct->max_bounds.width;
int i;
if (considerStyles) {
for (i = 0; i < textD->nStyles; ++i) {
int thisWidth = (textD->styleTable[i].font)->min_bounds.width;
if (thisWidth < fontWidth) {
fontWidth = thisWidth;
}
}
}
return(fontWidth);
}
int TextDMaxFontWidth(textDisp *textD, Boolean considerStyles) {
int fontWidth = textD->fontStruct->max_bounds.width;
int i;
if (considerStyles) {
for (i = 0; i < textD->nStyles; ++i) {
int thisWidth = (textD->styleTable[i].font)->max_bounds.width;
if (thisWidth > fontWidth) {
fontWidth = thisWidth;
}
}
}
return(fontWidth);
}
#endif
int Fl_Text_Display::longest_vline() const {
int longest = 0;
for (int i = 0; i < mNVisibleLines; i++)