1 //
2 // "$Id: Fl_Text_Buffer_mod.H 8148 2010-12-31 22:38:03Z matt $"
3 //
4 // Header file for Fl_Text_Buffer_mod class.
5 //
6 // Copyright 2001-2010 by Bill Spitzak and others.
7 // Original code Copyright Mark Edel.  Permission to distribute under
8 // the LGPL for the FLTK library granted by Mark Edel.
9 //
10 // This library is free software; you can redistribute it and/or
11 // modify it under the terms of the GNU Library General Public
12 // License as published by the Free Software Foundation; either
13 // version 2 of the License, or (at your option) any later version.
14 //
15 // This library is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 // Library General Public License for more details.
19 //
20 // You should have received a copy of the GNU Library General Public
21 // License along with this library; if not, write to the
22 //
23 //  Free Software Foundation, Inc.
24 //  51 Franklin Street, Fifth Floor
25 //  Boston, MA  02110-1301 USA.
26 //
27 // Please report all bugs and problems on the following page:
28 //
29 //     http://www.fltk.org/str.php
30 //
31 
32 /* \file
33  Fl_Text_Buffer_mod, Fl_Text_Selection_mod widget . */
34 
35 #ifndef Fl_Text_Buffer_mod_H
36 #define Fl_Text_Buffer_mod_H
37 
38 
39 #undef ASSERT_UTF8
40 
41 #ifdef ASSERT_UTF8
42 # include <assert.h>
43 # define IS_UTF8_ALIGNED(a) if (a && *a) assert(fl_utf8len(*(a))>0);
44 # define IS_UTF8_ALIGNED2(a, b) if (b>=0 && b<a->length()) assert(fl_utf8len(a->byte_at(b))>0);
45 #else
46 # define IS_UTF8_ALIGNED(a)
47 # define IS_UTF8_ALIGNED2(a, b)
48 #endif
49 
50 
51 /*
52  "character size" is the size of a UTF-8 character in bytes
53  "character width" is the width of a Unicode character in pixels
54  "column" was orginally defined as a character offset from the left margin.
55  It was identical to the byte offset. In UTF-8, we have neither a byte offset
56  nor truly fixed width fonts (*). Column could be a pixel value multiplied with
57  an average character width (which is a bearable approximation).
58 
59  * in Unicode, there are no fixed width fonts! Even if the ASCII characters may
60    happen to be all the same width in pixels, chinese charcaters surely are not.
61    There are plenty of exceptions, like ligatures, that make special handling of
62    "fixed" character widths a nightmare. I decided to remove all references to
63    fixed fonts and see "columns" as a multiple of the average width of a
64    character in the main font.
65      - Matthias
66  */
67 
68 
69 /* Maximum length in characters of a tab or control character expansion
70  of a single buffer character */
71 #define FL_TEXT_MAX_EXP_CHAR_LEN 20
72 
73 #include <FL/Fl_Export.H>
74 
75 
76 /**
77  \class Fl_Text_Selection_mod
78  \brief This is an internal class for Fl_Text_Buffer_mod to manage text selections.
79  This class works correctly with utf-8 strings assuming that the parameters
80  for all calls are on character boundaries.
81  */
82 class FL_EXPORT Fl_Text_Selection_mod {
83   friend class Fl_Text_Buffer_mod;
84 
85 public:
86 
87   /**
88    \brief Set the selection range.
89    \param start byte offset to first selected character
90    \param end byte offset pointing after last selected character
91    */
92   void set(int start, int end);
93 
94   /**
95    \brief Updates a selection afer text was modified.
96    Updates an individual selection for changes in the corresponding text
97    \param pos byte offset into text buffer at which the change occured
98    \param nDeleted number of bytes deleted from the buffer
99    \param nInserted number of bytes inserted into the buffer
100    */
101   void update(int pos, int nDeleted, int nInserted);
102 
103   /**
104    \brief Return the byte offset to the first selected character.
105    \return byte offset
106    */
start()107   int start() const { return mStart; }
108 
109   /**
110    \brief Return the byte ofsset to the character after the last selected character.
111    \return byte offset
112    */
end()113   int end() const { return mEnd; }
114 
115   /**
116    \brief Returns true if any text is selected.
117    \return a non-zero number if any text has been selected, or 0
118    if no text is selected.
119    */
selected()120   bool selected() const { return mSelected; }
121 
122   /**
123    \brief Modify the 'selected' flag.
124    \param b new flag
125    */
selected(bool b)126   void selected(bool b) { mSelected = b; }
127 
128   /**
129    Return true if position \p pos with indentation \p dispIndex is in
130    the Fl_Text_Selection_mod.
131    */
132   int includes(int pos) const;
133 
134   /**
135    \brief Return the positions of this selection.
136    \param start retrun byte offset to first selected character
137    \param end retrun byte offset pointing after last selected character
138    \return true if selected
139    */
140   int position(int* start, int* end) const;
141 
142 protected:
143 
144   int mStart;         ///< byte offset to the first selected character
145   int mEnd;           ///< byte offset to the character after the last selected character
146   bool mSelected;     ///< this flag is set if any text is selected
147 };
148 
149 
150 typedef void (*Fl_Text_Modify_Cb)(int pos, int nInserted, int nDeleted,
151                                   int nRestyled, const char* deletedText,
152                                   void* cbArg);
153 
154 
155 typedef void (*Fl_Text_Predelete_Cb)(int pos, int nDeleted, void* cbArg);
156 
157 
158 /**
159  \brief This class manages unicode displayed in one or more Fl_Text_Display_mod widgets.
160 
161  All text in Fl_Text_Buffer_modmust be encoded in UTF-8. All indices used in the
162  function calls must be aligned to the start of a UTF-8 sequence. All indices
163  and pointers returned will be aligned. All functions that return a single
164  character will return that in an unsiged int in UCS-4 encoding.
165 
166  The Fl_Text_Buffer_mod class is used by the Fl_Text_Display_mod
167  and Fl_Text_Editor_mod to manage complex text data and is based upon the
168  excellent NEdit text editor engine - see http://www.nedit.org/.
169  */
170 class FL_EXPORT Fl_Text_Buffer_mod {
171 public:
172 
173   /**
174    Create an empty text buffer of a pre-determined size.
175    \param requestedSize use this to avoid unnecessary re-allocation
176     if you know exactly how much the buffer will need to hold
177    \param preferredGapSize Initial size for the buffer gap (empty space
178     in the buffer where text might be inserted
179     if the user is typing sequential chars)
180    */
181   Fl_Text_Buffer_mod(int requestedSize = 0, int preferredGapSize = 1024);
182 
183   /**
184    Frees a text buffer
185    */
186   ~Fl_Text_Buffer_mod();
187 
188   /**
189    \brief Returns the number of bytes in the buffer.
190    \return size of text in bytes
191    */
length()192   int length() const { return mLength; }
193 
194   /**
195    \brief Get a copy of the entire contents of the text buffer.
196    Memory is allocated to contain the returned string, which the caller
197    must free.
198    \return newly allocated text buffer - must be free'd, text is utf8
199    */
200   char* text() const;
201 
202   /**
203    Replaces the entire contents of the text buffer.
204    \param text Text must be valid utf8.
205    */
206   void text(const char* text);
207 
208   /**
209    \brief Get a copy of a part of the text buffer.
210    Return a copy of the text between \p start and \p end character positions
211    from text buffer \p buf. Positions start at 0, and the range does not
212    include the character pointed to by \p end.
213    When you are done with the text, free it using the free() function.
214    \param start byte offset to first character
215    \param end byte offset after last character in range
216    \return newly allocated text buffer - must be free'd, text is utf8
217    */
218   char* text_range(int start, int end) const;
219 
220   /**
221    Returns the UCS-4 character at the specified position pos in the buffer.
222    Positions start at 0
223    \param pos byte offset into buffer, pos must be at a character boundary
224    \return Unicode UCS-4 encoded character
225    */
226   unsigned int char_at(int pos) const;
227 
228   /**
229    Returns the UTF-8 character at the specified position pos in the buffer.
230    Positions start at 0
231    param pos byte offset into buffer, pos must be at a character boundary
232    return Unicode UTF-8 encoded character
233    return length of Unicode encoded character in len
234    */
235   unsigned int get_char_at(int pos, int &len) const;
236 
237   /**
238    Returns the raw byte at the specified position pos in the buffer.
239    Positions start at 0
240    \param pos byte offset into buffer
241    \return unencoded raw byte
242    */
243   char byte_at(int pos) const;
244 
245   /**
246    Convert a byte offset in buffer into a memory address.
247    \param pos byte offset into buffer
248    \return byte offset converted to a memory address
249    */
address(int pos)250   const char *address(int pos) const
251   { return (pos < mGapStart) ? mBuf+pos : mBuf+pos+mGapEnd-mGapStart; }
252 
253   /**
254    Convert a byte offset in buffer into a memory address.
255    \param pos byte offset into buffer
256    \return byte offset converted to a memory address
257    */
address(int pos)258   char *address(int pos)
259   { return (pos < mGapStart) ? mBuf+pos : mBuf+pos+mGapEnd-mGapStart; }
260 
261   /**
262    Inserts null-terminated string \p text at position \p pos.
263    \param pos insertion position as byte offset (must be utf-8 character aligned)
264    \param text utf-8 encoded and nul terminated text
265    */
266   void insert(int pos, const char* text);
267 
268   /**
269    Appends the text string to the end of the buffer.
270    \param t utf-8 encoded and nul terminated text
271    */
append(const char * t)272   void append(const char* t) { insert(length(), t); }
273 
274   /**
275    Deletes a range of characters in the buffer.
276    \param start byte offset to first character to be removed
277    \param end byte offset to charcatre after last character to be removed
278    */
279   void remove(int start, int end);
280 
281   /**
282    Deletes the characters between \p start and \p end, and inserts the null-terminated string \p text in their place in the buffer.
283    \param start byte offset to first character to be removed and new insert position
284    \param end byte offset to charcatre after last character to be removed
285    \param text utf-8 encoded and nul terminated text
286    */
287   void replace(int start, int end, const char *text);
288 
289   /**
290    Copies text from one buffer to this one.
291    \param fromBuf source text buffer may be the same as this
292    \param fromStart byte offset into buffer
293    \param fromEnd byte offset into buffer
294    \param toPos destination byte offset into buffer
295    */
296   void copy(Fl_Text_Buffer_mod* fromBuf, int fromStart, int fromEnd, int toPos);
297 
298   /**
299    Undo text modification according to the undo variables or insert text
300    from the undo buffer
301    */
302   int undo(int *cp=0);
303 
304   /**
305    Lets the undo system know if we can undo changes
306    */
307   void canUndo(char flag=1);
308 
309   /**
310    Inserts a file at the specified position. Returns 0 on success,
311    non-zero on error (strerror() contains reason).  1 indicates open
312    for read failed (no data loaded). 2 indicates error occurred
313    while reading data (data was partially loaded).
314    File can be UTF-8 or CP1252-encoded.
315    If the input file is not UTF-8-encoded, the Fl_Text_Buffer_mod widget will contain
316    UTF-8-transcoded data. By default, the message Fl_Text_Buffer_mod::file_encoding_warning_message
317    will warn the user about this.
318    \see input_file_was_transcoded and transcoding_warning_action.
319    */
320   int insertfile(const char *file, int pos, int buflen = 128*1024);
321 
322   /**
323    Appends the named file to the end of the buffer. See also insertfile().
324    */
325   int appendfile(const char *file, int buflen = 128*1024)
326   { return insertfile(file, length(), buflen); }
327 
328   /**
329    Loads a text file into the buffer. See also insertfile().
330    */
331   int loadfile(const char *file, int buflen = 128*1024)
332   { select(0, length()); remove_selection(); return appendfile(file, buflen); }
333 
334   /**
335    Writes the specified portions of the file to a file. Returns 0 on success, non-zero
336    on error (strerror() contains reason).  1 indicates open for write failed
337    (no data saved). 2 indicates error occurred while writing data
338    (data was partially saved).
339    */
340   int outputfile(const char *file, int start, int end, int buflen = 128*1024);
341 
342   /**
343    Saves a text file from the current buffer
344    */
345   int savefile(const char *file, int buflen = 128*1024)
346   { return outputfile(file, 0, length(), buflen); }
347 
348   /**
349    Gets the tab width.
350    */
tab_distance()351   int tab_distance() const { return mTabDist; }
352 
353   /**
354    Set the hardware tab distance (width) used by all displays for this buffer,
355    and used in computing offsets for rectangular selection operations.
356    */
357   void tab_distance(int tabDist);
358 
359   /**
360    Selects a range of characters in the buffer.
361    */
362   void select(int start, int end);
363 
364   /**
365    Returns a non 0 value if text has been selected, 0 otherwise
366    */
selected()367   int selected() const { return mPrimary.selected(); }
368 
369   /**
370    Cancels any previous selection on the primary text selection object
371    */
372   void unselect();
373 
374   /**
375    Gets the selection position
376    */
377   int selection_position(int* start, int* end);
378 
379   /**
380    Returns the currently selected text. When you are done with
381    the text, free it using the free() function.
382    */
383   char* selection_text();
384 
385   /**
386    Removes the text in the primary selection.
387    */
388   void remove_selection();
389 
390   /**
391    Replaces the text in the primary selection.
392    */
393   void replace_selection(const char* text);
394 
395   /**
396    Selects a range of characters in the secondary selection.
397    */
398   void secondary_select(int start, int end);
399 
400   /**
401    Returns a non 0 value if text has been selected in the secondary
402    text selection, 0 otherwise
403    */
secondary_selected()404   int secondary_selected() { return mSecondary.selected(); }
405 
406   /**
407    Clears any selection in the secondary text selection object.
408    */
409   void secondary_unselect();
410 
411   /**
412    Returns the current selection in the secondary text selection object.
413    */
414   int secondary_selection_position(int* start, int* end);
415 
416   /**
417    Returns the text in the secondary selection. When you are
418    done with the text, free it using the free() function.
419    */
420   char* secondary_selection_text();
421 
422   /**
423    Removes the text from the buffer corresponding to the secondary text selection object.
424    */
425   void remove_secondary_selection();
426 
427   /**
428    Replaces the text from the buffer corresponding to the secondary
429    text selection object with the new string \p text.
430    */
431   void replace_secondary_selection(const char* text);
432 
433   /**
434    Highlights the specified text within the buffer.
435    */
436   void highlight(int start, int end);
437 
438   /**
439    Returns the highlighted text. When you are done with the
440    text, free it using the free() function.
441    */
highlight()442   int highlight() { return mHighlight.selected(); }
443 
444   /**
445    Unhighlights text in the buffer.
446    */
447   void unhighlight();
448 
449   /**
450    Highlights the specified text between \p start and \p end within the buffer.
451    */
452   int highlight_position(int* start, int* end);
453 
454   /**
455    Returns the highlighted text. When you are done with the
456    text, free it using the free() function.
457    */
458   char* highlight_text();
459 
460   /**
461    Adds a callback function that is called whenever the text buffer is
462    modified. The callback function is declared as follows:
463 
464    \code
465    typedef void (*Fl_Text_Modify_Cb)(int pos, int nInserted, int nDeleted,
466       int nRestyled, const char* deletedText,
467       void* cbArg);
468    \endcode
469    */
470   void add_modify_callback(Fl_Text_Modify_Cb bufModifiedCB, void* cbArg);
471 
472   /**
473    Removes a modify callback.
474    */
475   void remove_modify_callback(Fl_Text_Modify_Cb bufModifiedCB, void* cbArg);
476 
477   /**
478    Calls all modify callbacks that have been registered using
479    the add_modify_callback()
480    method.
481    */
call_modify_callbacks()482   void call_modify_callbacks() { call_modify_callbacks(0, 0, 0, 0, 0); }
483 
484   /**
485    Adds a callback routine to be called before text is deleted from the buffer.
486    */
487   void add_predelete_callback(Fl_Text_Predelete_Cb bufPredelCB, void* cbArg);
488 
489   /**
490    Removes a callback routine \p bufPreDeleteCB associated with argument \p cbArg
491    to be called before text is deleted from the buffer.
492    */
493   void remove_predelete_callback(Fl_Text_Predelete_Cb predelCB, void* cbArg);
494 
495   /**
496    Calls the stored pre-delete callback procedure(s) for this buffer to update
497    the changed area(s) on the screen and any other listeners.
498    */
call_predelete_callbacks()499   void call_predelete_callbacks() { call_predelete_callbacks(0, 0); }
500 
501   /**
502    Returns the text from the entire line containing the specified
503    character position. When you are done with the text, free it
504    using the free() function.
505    \param pos byte index into buffer
506    \return copy of utf8 text, must be free'd
507    */
508   char* line_text(int pos) const;
509 
510   /**
511    Returns the position of the start of the line containing position \p pos.
512    \param pos byte index into buffer
513    \return byte offset to line start
514    */
515   int line_start(int pos) const;
516 
517   /**
518    Finds and returns the position of the end of the line containing position \p pos
519    (which is either a pointer to the newline character ending the line,
520    or a pointer to one character beyond the end of the buffer)
521    \param pos byte index into buffer
522    \return byte offset to line end
523    */
524   int line_end(int pos) const;
525 
526   /**
527    Returns the position corresponding to the start of the word
528    \param pos byte index into buffer
529    \return byte offset to word start
530    */
531   int word_start(int pos) const;
532 
533   /**
534    Returns the position corresponding to the end of the word.
535    \param pos byte index into buffer
536    \return byte offset to word end
537    */
538   int word_end(int pos) const;
539 
540   /**
541    Count the number of displayed characters between buffer position
542    \p lineStartPos and \p targetPos. (displayed characters are the characters
543    shown on the screen to represent characters in the buffer, where tabs and
544    control characters are expanded)
545    */
546   int count_displayed_characters(int lineStartPos, int targetPos) const;
547 
548   /**
549    Count forward from buffer position \p startPos in displayed characters
550    (displayed characters are the characters shown on the screen to represent
551    characters in the buffer, where tabs and control characters are expanded)
552    \param lineStartPos byte offset into buffer
553    \param nChars number of bytes that are sent to the display
554    \return byte offset in input after all output bytes are sent
555    */
556   int skip_displayed_characters(int lineStartPos, int nChars);
557 
558   /**
559    Counts the number of newlines between \p startPos and \p endPos in buffer.
560    The character at position \p endPos is not counted.
561    */
562   int count_lines(int startPos, int endPos) const;
563 
564   /**
565    Finds the first character of the line \p nLines forward from \p startPos
566    in the buffer and returns its position
567    */
568   int skip_lines(int startPos, int nLines);
569 
570   /**
571    Finds and returns the position of the first character of the line \p nLines backwards
572    from \p startPos (not counting the character pointed to by \p startpos if
573    that is a newline) in the buffer.  \p nLines == 0 means find the beginning of the line
574    */
575   int rewind_lines(int startPos, int nLines);
576 
577   /**
578    Finds the next occurrence of the specified character.
579    Search forwards in buffer for character \p searchChar, starting
580    with the character \p startPos, and returning the result in \p foundPos
581    returns 1 if found, 0 if not.  (The difference between this and
582    BufSearchForward is that it's optimized for single characters.  The
583    overall performance of the text widget is dependent on its ability to
584    count lines quickly, hence searching for a single character: newline)
585    \param startPos byte offset to start position
586    \param searchChar UCS-4 character that we want to find
587    \param foundPos byte offset where the character was found
588    \return 1 if found, 0 if not
589    */
590   int findchar_forward(int startPos, unsigned searchChar, int* foundPos) const;
591 
592   /**
593    Search backwards in buffer \p buf for character \p searchChar, starting
594    with the character BEFORE \p startPos, returning the result in \p foundPos
595    returns 1 if found, 0 if not.  (The difference between this and
596    BufSearchBackward is that it's optimized for single characters.  The
597    overall performance of the text widget is dependent on its ability to
598    count lines quickly, hence searching for a single character: newline)
599    \param startPos byte offset to start position
600    \param searchChar UCS-4 character that we want to find
601    \param foundPos byte offset where the character was found
602    \return 1 if found, 0 if not
603    */
604   int findchar_backward(int startPos, unsigned int searchChar, int* foundPos) const;
605 
606   /**
607    Finds the next nth occurrence of the specified character.
608    Search forwards in buffer for character \p searchChar, starting
609    with the character \p startPos, and returning the result in \p foundPos
610    returns 1 if found, 0 if not.  (The difference between this and
611    BufSearchForward is that it's optimized for single characters.  The
612    overall performance of the text widget is dependent on its ability to
613    count lines quickly, hence searching for a single character: newline)
614    \param startPos byte offset to start position
615    \param searchChar UCS-4 character that we want to find
616    \param foundPos byte offset where the character was found
617    \return 1 if found, 0 if not
618    */
619   int findchars_forward(int startPos, const char* searchString, int* foundPos, int n = 1) const;
620 
621   int search_forward(int startPos, const char* searchString, int* foundPos,
622                      int matchCase = 0) const;
623 
624   /**
625    Search backwards in buffer for string <i>searchCharssearchString</i>, starting with the
626    character BEFORE \p startPos, returning the result in \p foundPos
627    returns 1 if found, 0 if not.
628    \param startPos byte offset to start position
629    \param searchString utf8 string that we want to find
630    \param foundPos byte offset where the string was found
631    \param matchCase if set, match character case
632    \return 1 if found, 0 if not
633    */
634   int search_backward(int startPos, const char* searchString, int* foundPos,
635                       int matchCase = 0) const;
636 
637   int findchars_backward(int startPos, const char* searchChars, int* foundPos);
638 
639   /**
640    Returns the primary selection.
641    */
primary_selection()642   const Fl_Text_Selection_mod* primary_selection() const { return &mPrimary; }
643 
644   /**
645    Returns the primary selection.
646    */
primary_selection()647   Fl_Text_Selection_mod* primary_selection() { return &mPrimary; }
648 
649   /**
650    Returns the secondary selection.
651    */
secondary_selection()652   const Fl_Text_Selection_mod* secondary_selection() const { return &mSecondary; }
653 
654   /**
655    Returns the current highlight selection.
656    */
highlight_selection()657   const Fl_Text_Selection_mod* highlight_selection() const { return &mHighlight; }
658 
659   /**
660    Returns the index of the previous character.
661    \param ix index to the current char
662    */
663   int prev_char(int ix) const;
664   int prev_char_clipped(int ix) const;
665 
666   /**
667    Returns the index of the next character.
668    \param ix index to the current char
669    */
670   int next_char(int ix) const;
671   int next_char_clipped(int ix) const;
672 
673   /**
674    Align an index into the buffer to the current or previous utf8 boundary.
675    */
676   int utf8_align(int) const;
677 
678   /**
679    \brief true iff the loaded file has been transcoded to UTF-8
680    */
681   int input_file_was_transcoded;
682 
683   /** This message may be displayed using the fl_alert() function when a file
684    which was not UTF-8 encoded is input.
685    */
686   static const char* file_encoding_warning_message;
687 
688   /**
689    \brief Pointer to a function called after reading a non UTF-8 encoded file.
690 
691    This function is called after reading a file if the file content
692    was transcoded to UTF-8. Its default implementation calls fl_alert()
693    with the text of \ref file_encoding_warning_message. No warning message is
694    displayed if this pointer is set to NULL. Use \ref input_file_was_transcoded
695    to be informed if file input required transcoding to UTF-8.
696    */
697   void (*transcoding_warning_action)(Fl_Text_Buffer_mod*);
698 
699 protected:
700 
701   /**
702    Calls the stored modify callback procedure(s) for this buffer to update the
703    changed area(s) on the screen and any other listeners.
704    */
705   void call_modify_callbacks(int pos, int nDeleted, int nInserted,
706                              int nRestyled, const char* deletedText) const;
707 
708   /**
709    Calls the stored pre-delete callback procedure(s) for this buffer to update
710    the changed area(s) on the screen and any other listeners.
711    */
712   void call_predelete_callbacks(int pos, int nDeleted) const;
713 
714   /**
715    Internal (non-redisplaying) version of BufInsert. Returns the length of
716    text inserted (this is just strlen(\p text), however this calculation can be
717    expensive and the length will be required by any caller who will continue
718    on to call redisplay). \p pos must be contiguous with the existing text in
719    the buffer (i.e. not past the end).
720    \return the number of bytes inserted
721    */
722   int insert_(int pos, const char* text);
723 
724   /**
725    Internal (non-redisplaying) version of BufRemove.  Removes the contents
726    of the buffer between start and end (and moves the gap to the site of
727    the delete).
728    */
729   void remove_(int start, int end);
730 
731   /**
732    Calls the stored redisplay procedure(s) for this buffer to update the
733    screen for a change in a selection.
734    */
735   void redisplay_selection(Fl_Text_Selection_mod* oldSelection,
736                            Fl_Text_Selection_mod* newSelection) const;
737 
738   /**
739    Move the gap to start at a new position.
740    */
741   void move_gap(int pos);
742 
743   /**
744    Reallocates the text storage in the buffer to have a gap starting at \p newGapStart
745    and a gap size of \p newGapLen, preserving the buffer's current contents.
746    */
747   void reallocate_with_gap(int newGapStart, int newGapLen);
748 
749   char* selection_text_(Fl_Text_Selection_mod* sel) const;
750 
751   /**
752    Removes the text from the buffer corresponding to \p sel.
753    */
754   void remove_selection_(Fl_Text_Selection_mod* sel);
755 
756   /**
757    Replaces the \p text in selection \p sel.
758    */
759   void replace_selection_(Fl_Text_Selection_mod* sel, const char* text);
760 
761   /**
762    Updates all of the selections in the buffer for changes in the buffer's text
763    */
764   void update_selections(int pos, int nDeleted, int nInserted);
765 
766   Fl_Text_Selection_mod mPrimary;     /**< highlighted areas */
767   Fl_Text_Selection_mod mSecondary;   /**< highlighted areas */
768   Fl_Text_Selection_mod mHighlight;   /**< highlighted areas */
769   int mLength;                    /**< length of the text in the buffer (the length
770                                    of the buffer itself must be calculated:
771                                    gapEnd - gapStart + length) */
772   char* mBuf;                     /**< allocated memory where the text is stored */
773   int mGapStart;                  /**< points to the first character of the gap */
774   int mGapEnd;                    /**< points to the first char after the gap */
775   // The hardware tab distance used by all displays for this buffer,
776   // and used in computing offsets for rectangular selection operations.
777   int mTabDist;                   /**< equiv. number of characters in a tab */
778   int mNModifyProcs;              /**< number of modify-redisplay procs attached */
779   Fl_Text_Modify_Cb *mModifyProcs;/**< procedures to call when buffer is
780                                    modified to redisplay contents */
781   void** mCbArgs;                 /**< caller arguments for modifyProcs above */
782   int mNPredeleteProcs;           /**< number of pre-delete procs attached */
783   Fl_Text_Predelete_Cb *mPredeleteProcs; /**< procedure to call before text is deleted
784                                    from the buffer; at most one is supported. */
785   void **mPredeleteCbArgs;        /**< caller argument for pre-delete proc above */
786   int mCursorPosHint;             /**< hint for reasonable cursor position after
787                                    a buffer modification operation */
788   char mCanUndo;                  /**< if this buffer is used for attributes, it must
789                                    not do any undo calls */
790   int mPreferredGapSize;          /**< the default allocation for the text gap is 1024
791                                    bytes and should only be increased if frequent
792                                    and large changes in buffer size are expected */
793 };
794 
795 #endif
796 
797 //
798 // End of "$Id: Fl_Text_Buffer_mod.H 8148 2010-12-31 22:38:03Z matt $".
799 //
800