mirror of https://github.com/fltk/fltk
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:
parent
dcdc4439cc
commit
f2fa59fd0f
|
@ -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);
|
||||
|
|
|
@ -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++)
|
||||
|
|
Loading…
Reference in New Issue