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