Dillo v3.1.1-14-g8f67d6e0
Loading...
Searching...
No Matches
textblock.hh
Go to the documentation of this file.
1#ifndef __DW_TEXTBLOCK_HH__
2#define __DW_TEXTBLOCK_HH__
3
4#include <limits.h>
5
6#include "regardingborder.hh"
7#include "../lout/misc.hh"
8
9// These were used when improved line breaking and hyphenation were implemented.
10// Should be, bit by bit, replaced by RTFL (see ../lout/debug.hh).
11#define PRINTF(fmt, ...)
12#define PUTCHAR(ch)
13
14#ifdef DBG_RTFL
15# define DEBUG
16#endif
17
18namespace dw {
19
206{
207private:
217 enum {
219 PENALTY_PROHIBIT_BREAK = INT_MAX
220 };
221
223 {
224 private:
227 int ratio; // ratio is only defined when badness is defined
229
230 // For debugging: define DEBUG for more informations in print().
231#ifdef DEBUG
232 int totalWidth, idealWidth, totalStretchability, totalShrinkability;
233#endif
234
235 // "Infinity levels" are used to represent very large numbers,
236 // including "quasi-infinite" numbers. A couple of infinity
237 // level and number can be mathematically represented as
238 //
239 // number * N ^ (infinity level)
240 //
241 // where N is a number which is large enough. Practically,
242 // infinity levels are used to circumvent limited ranges for
243 // integer numbers.
244
245 // Here, all infinity levels have got special meanings.
246 enum {
247 INF_VALUE = 0, /* simple values */
248 INF_LARGE, /* large values, like QUITE_LOOSE */
249 INF_NOT_STRETCHABLE, /* reserved for NOT_STRECTHABLE */
250 INF_TOO_TIGHT, /* used for lines, which are too tight */
251 INF_PENALTIES, /* used for penalties */
253
254 // That INF_PENALTIES is the last value means that an
255 // infinite penalty (breaking is prohibited) makes a break
256 // not possible at all, so that pre-formatted text
257 // etc. works.
258 };
259
260 void setSinglePenalty (int index, int penalty);
261 int badnessValue (int infLevel);
262 int penaltyValue (int index, int infLevel);
263
264 public:
265 void calcBadness (int totalWidth, int idealWidth,
266 int totalStretchability, int totalShrinkability);
268 void setPenalties (int penalty1, int penalty2);
269
270 // Rather for debugging:
271 inline int getPenalty (int i) { return penalty[i]; }
272
273 bool lineLoose ();
274 bool lineTight ();
275 bool lineTooTight ();
276 bool lineMustBeBroken (int penaltyIndex);
277 bool lineCanBeBroken (int penaltyIndex);
278 int compareTo (int penaltyIndex, BadnessAndPenalty *other);
279
281 };
282
285 enum { NUM_DIV_CHARS = 4 };
286
287 typedef struct
288 {
289 const char *s;
290 bool charRemoved, canBeHyphenated, unbreakableForMinWidth;
291 int penaltyIndexLeft, penaltyIndexRight;
292 } DivChar;
293
295
296 static const char *hyphenDrawChar;
297
298protected:
299
305 {
306 protected:
310
311 public:
314
315 void setData (int xWordWidget, int lineNo);
316
317 bool readyToDraw ();
318 void getBgArea (int *x, int *y, int *width, int *height);
319 void getRefArea (int *xRef, int *yRef, int *widthRef, int *heightRef);
321 void draw (int x, int y, int width, int height);
322 };
323
325 {
326 public:
329
330 void getBgArea (int *x, int *y, int *width, int *height);
332 };
333
335 {
336 int firstWord; /* first word's index in word vector */
337 int lastWord; /* last word's index in word vector */
338
339 /*
340 * General remark: all values include the last hyphen width, but
341 * not the last space; these values are, however corrected, when
342 * another word is added.
343 *
344 * Also, as opposed to lines, paragraphs are created with the
345 * first, not the last word, so these values change when new
346 * words are added.
347 */
348
349 int parMin; /* The sum of all word minima (plus spaces,
350 hyphen width etc.) since the last possible
351 break within this paragraph. */
354 int parMax; /* The sum of all word maxima in this
355 paragraph (plus spaces, hyphen width
356 etc.). */
358
359 int maxParMin; /* Maximum of all paragraph minima (value of
360 "parMin"), including this paragraph. */
363 int maxParMax; /* Maximum of all paragraph maxima (value of
364 "parMax""), including this paragraph. */
366 };
367
368 struct Line
369 {
370 int firstWord; /* first word's index in word vector */
371 int lastWord; /* last word's index in word vector */
372
373
374 int top; /* "top" is always relative to the top of the
375 first line, i.e. page->lines[0].top is
376 always 0. */
377 int marginAscent; /* Maximum of all total ascents (including
378 margin: hence the name) of the words in this
379 line. */
380 int marginDescent; /* Maximum of all total decents (including
381 margin: hence the name) of the words in this
382 line. */
383 int borderAscent; /* Maximum of all ascents minus margin (but
384 including padding and border: hence the name)
385 of the words in this line. */
386 int borderDescent; /* Maximum of all descents minus margin (but
387 including padding and border: hence the name)
388 of the words in this line. */
389 int contentAscent; /* ??? (depricated?) */
390 int contentDescent; /* ??? (depricated?) */
391 int breakSpace; /* Space between this line and the next one. */
392 int textOffset; /* Horizontal position of the first word of the
393 line, in widget coordinates. */
394
401 inline int totalHeight (int marginNextLine)
402 { return borderAscent + borderDescent
403 // Collapsing of the margins of adjacent lines is done here:
404 + lout::misc::max (marginDescent - borderDescent, marginNextLine,
405 breakSpace); }
406
407 /* Maximum of all line widths, including this line. Does not
408 * include the last space, but the last hyphen width. Please
409 * notice a change: until recently (before hyphenation and
410 * changed line breaking), the values were accumulated up to the
411 * last line, not this line.*/
413
414 /* The word index of the last OOF reference (most importantly:
415 * float) whic is positioned before this line, or -1, if there
416 * is no OOF reference positioned before.
417 *
418 * **Important:** These references may still be part of this or
419 * even a following line, when positioned before (this is the
420 * reason this attribute exists); see \ref dw-out-of-flow. */
422
425 };
426
427 struct Word
428 {
429 enum {
443 /* When calculating the minimal width (as part of extremes),
444 * do not consider this word as breakable. This flag is
445 * ignored when the line is actually broken. */
447 /* If a word represents a "real" text word, or (after
448 * hyphenation) the first part of a "real" text word, this
449 * flag is set. Plays a role for text transformation. */
450 WORD_START = 1 << 5,
451 /* If a word represents a "real" text word, or (after
452 * hyphenation) the last part of a "real" text word, this
453 * flag is set. Analogue to WORD_START. */
454 WORD_END = 1 << 6,
455 /* This word is put at the top of the line, and at the
456 * left. This is necessary if the size of a child widget
457 * depends on the position, which, on the other hand, cannot
458 * be determined before the whole line is broken. */
459 TOPLEFT_OF_LINE = 1 << 7
460 };
461
462 /* TODO: perhaps add a xLeft? */
464 /* Space after the word, only if it's not a break: */
465 short origSpace; /* from font, set by addSpace */
466 short effSpace; /* effective space, set by wordWrap,
467 * used for drawing etc. */
468 short hyphenWidth; /* Additional width, when a word is part
469 * (except the last part) of a hyphenationed
470 * word. Has to be added to the width, when
471 * this is the last word of the line, and
472 * "hyphenWidth > 0" is also used to decide
473 * whether to draw a hyphen. */
474 short flags;
476
477 // accumulated values, relative to the beginning of the line
478 int totalWidth; /* The sum of all word widths; plus all
479 spaces, excluding the one of this
480 word; plus the hyphen width of this
481 word (but of course, no hyphen
482 widths of previous words. In other
483 words: the value compared to the
484 ideal width of the line, if the line
485 would be broken after this word. */
487 int totalSpaceStretchability; // includes all *before* current word
488 int totalSpaceShrinkability; // includes all *before* current word
489 BadnessAndPenalty badnessAndPenalty; /* when line is broken after this
490 * word */
491
493 core::style::Style *spaceStyle; /* initially the same as of the word,
494 later set by a_Dw_page_add_space */
495
496 // These two are used rarely, so there is perhaps a way to store
497 // them which is consuming less memory.
500 };
501
502 struct Anchor
503 {
504 char *name;
506 };
507
509 {
510 protected:
511 int numContentsInFlow ();
513
514 public:
516 bool atEnd);
517
519 (Textblock *textblock, core::Content::Type mask, int wordIndex);
520
522
523 void highlight (int start, int end, core::HighlightLayer layer);
524 void unhighlight (int direction, core::HighlightLayer layer);
525 void getAllocation (int start, int end, core::Allocation *allocation);
526 };
527
528 friend class TextblockIterator;
529
530 /* These fields provide some ad-hoc-functionality, used by sub-classes. */
531 bool hasListitemValue; /* If true, the first word of the page is treated
532 specially (search in source). */
533 int leftInnerPadding; /* This is an additional padding on the left side
534 (used by ListItem). */
535 int line1Offset; /* This is an additional offset of the first line.
536 May be negative (shift to left) or positive
537 (shift to right). */
538 int line1OffsetEff; /* The "effective" value of line1_offset, may
539 differ from line1_offset when
540 ignoreLine1OffsetSometimes is set to true. */
541
542 /* The following is really hackish: It is used for DwTableCell (see
543 * comment in dw_table_cell.c), to avoid too wide table columns. If
544 * set to true, it has following effects:
545 *
546 * (i) line1_offset is ignored in calculating the minimal width
547 * (which is used by DwTable!), and
548 * (ii) line1_offset is ignored (line1_offset_eff is set to 0),
549 * when line1_offset plus the width of the first word is
550 * greater than the the line break witdh.
551 *
552 * \todo Eliminate all these ad-hoc features by a new, simpler and
553 * more elegant design. ;-)
554 */
556
558
565 static int penalties[PENALTY_NUM][2];
566
571
572 bool limitTextWidth; /* from preferences */
574
577
579
580 /* Stores the value of getAvailWidth(). */
582
583 int wrapRefLines, wrapRefParagraphs; /* 0-based. Important: Both
584 are the line numbers, not
585 the value stored in
586 parentRef. */
588
589 // These four values are calculated by containingBlock->outOfFlowMgr
590 // (when defined; otherwise, they are false, or 0, respectively), for
591 // the newly constructed line, only when needed: when a new line is
592 // added, or if something in the line currently constucted has
593 // changed, e. g. a float has been added.
594
596 int newLineLeftBorder, newLineRightBorder; /* As returned by
597 outOfFlowMgr->get...Border,
598 or 0, if outOfFlowMgr
599 is NULL */
601
602 // Ascent and descent of the newly constructed line, i. e. maximum
603 // of all words ascent/descent since the end of the last line. Not
604 // neccessary the ascent and descent of the newly added line, since
605 // not all words are added to it.
607
608 lout::misc::SimpleVector <Line> *lines;
609 lout::misc::SimpleVector <Paragraph> *paragraphs;
611 lout::misc::NotSoSimpleVector <Word> *words;
612 lout::misc::SimpleVector <Anchor> *anchors;
613
614 struct { int index, nChar; }
616
617 int hoverLink; /* The link under the mouse pointer */
618
621
622 void queueDrawRange (int index1, int index2);
623 int calcVerticalBorder (int widgetPadding, int widgetBorder,
624 int widgetMargin, int lineBorderTotal,
625 int lineMarginTotal);
627 void justifyLine (Line *line, int diff);
628 Line *addLine (int firstWord, int lastWord, int newLastOofPos,
629 bool temporary, int minHeight);
630 void rewrap ();
631 void fillParagraphs ();
632 void initNewLine ();
633 void calcBorders (int lastOofRef, int height);
634 void showMissingLines ();
635 void removeTemporaryLines ();
636
639 int x, int yBase, int width);
641 core::style::Color::Shading shading, int x, int y,
642 const char *text, int start, int len, bool isStart,
643 bool isEnd);
644 void drawWord (Line *line, int wordIndex1, int wordIndex2, core::View *view,
645 core::Rectangle *area, int xWidget, int yWidgetBase);
646 void drawWord0 (int wordIndex1, int wordIndex2,
647 const char *text, int totalWidth, bool drawHyphen,
649 core::Rectangle *area, int xWidget, int yWidgetBase);
650 void drawSpace (int wordIndex, core::View *view, core::Rectangle *area,
651 int xWidget, int yWidgetBase);
652 void drawLine (Line *line, core::View *view, core::Rectangle *area,
653 core::DrawingContext *context);
654
655 int findLineIndex (int y);
657 int findLineIndexWhenAllocated (int y);
658 int findLineIndex (int y, int ascent);
659 int findLineOfWord (int wordIndex);
660 int findParagraphOfWord (int wordIndex);
661 Word *findWord (int x, int y, bool *inSpace);
662
663 Word *addWord (int width, int ascent, int descent, short flags,
665 void breakAdded ();
666 void initWord (int wordNo);
667 void cleanupWord (int wordNo);
668 void removeWordImgRenderer (int wordNo);
669 void setWordImgRenderer (int wordNo);
670 void removeSpaceImgRenderer (int wordNo);
671 void setSpaceImgRenderer (int wordNo);
672 void fillWord (int wordNo, int width, int ascent, int descent,
674 void fillSpace (int wordNo, core::style::Style *style);
676 int breakPenalty1, int breakPenalty2, bool forceBreak);
678 { return isBreakAllowed (word->style); }
680 int textWidth (const char *text, int start, int len,
681 core::style::Style *style, bool isStart, bool isEnd);
682 void calcTextSize (const char *text, size_t len, core::style::Style *style,
683 core::Requisition *size, bool isStart, bool isEnd);
684 bool calcSizeOfWidgetInFlow (int wordIndex, Widget *widget,
685 core::Requisition *size);
686 bool findSizeRequestReference (Widget *reference, int *xRef = NULL,
687 int *yRef = NULL);
688 bool findSizeRequestReference (int oofmIndex, int *xRef = NULL,
689 int *yRef = NULL)
690 { return findSizeRequestReference (oofContainer[oofmIndex], xRef, yRef); }
691
696 inline bool mustBorderBeRegarded (Line *line)
697 {
698 return getWidgetRegardingBorderForLine (line) == NULL;
699 }
700
701 inline bool mustBorderBeRegarded (int lineNo)
702 {
703 return getWidgetRegardingBorderForLine (lineNo) == NULL;
704 }
705
706 // The following methods return the y offset of a line,
707 // - given as pointer or by index;
708 // - either within the canvas, or within this widget;
709 // - with allocation passed explicitely, or using the widget allocation
710 // (important: this is set *after* sizeRequestImpl is returning.
711
713 {
714 return line->top + (allocation->ascent - lines->getRef(0)->borderAscent);
715 }
716
717 inline int lineYOffsetWidget (Line *line)
718 {
719 return lineYOffsetWidget (line, &allocation);
720 }
721
723 {
724 return allocation->y + lineYOffsetWidget (line, allocation);
725 }
726
727 inline int lineYOffsetCanvas (Line *line)
728 {
729 return lineYOffsetCanvas (line, &allocation);
730 }
731
732 inline int lineYOffsetWidget (int lineIndex)
733 {
734 return lineYOffsetWidget (lines->getRef (lineIndex));
735 }
736
737 inline int lineYOffsetWidget (int lineIndex, core::Allocation *allocation)
738 {
739 return lineYOffsetWidget (lines->getRef (lineIndex), allocation);
740 }
741
742 inline int lineYOffsetCanvas (int lineIndex)
743 {
744 return lineYOffsetCanvas (lines->getRef (lineIndex));
745 }
746
748 {
749 if (lines->size() == 0)
750 return 0;
751 else {
752 Line *line = lines->getLastRef();
753 if (line->firstWord <= line->lastWord)
754 return
755 (words->getRef(line->lastWord)->flags &
757 else
758 // empty line
759 return 0;
760 }
761 }
762
766 int lastWord);
767 int yOffsetOfLineToBeCreated (int *lastMargin = NULL);
768 int yOffsetOfLineCreated (Line *line);
769
772
773 void processWord (int wordIndex);
774
775 virtual int wordWrap (int wordIndex, bool wrapAll);
776
777 int wrapWordInFlow (int wordIndex, bool wrapAll);
778 int wrapWordOofRef (int wordIndex, bool wrapAll);
779 void balanceBreakPosAndHeight (int wordIndex, int firstIndex,
780 int *searchUntil, bool tempNewLine,
781 int penaltyIndex, bool borderIsCalculated,
782 bool *thereWillBeMoreSpace, bool wrapAll,
783 int *diffWords, int *wordIndexEnd,
784 int *lastFloatPos, bool regardBorder,
785 int *height, int *breakPos);
786 int searchBreakPos (int wordIndex, int firstIndex, int *searchUntil,
787 bool tempNewLine, int penaltyIndex,
788 bool thereWillBeMoreSpace, bool wrapAll,
789 int *diffWords, int *wordIndexEnd,
790 int *addIndex1 = NULL);
791 int searchMinBap (int firstWord, int lastWordm, int penaltyIndex,
792 bool thereWillBeMoreSpace, bool correctAtEnd);
793 int considerHyphenation (int firstIndex, int breakPos);
794 bool isHyphenationCandidate (Word *word);
795 int calcLinePartHeight (int firstWord, int lastWord);
796
797 void handleWordExtremes (int wordIndex);
799
800 static int getSpaceShrinkability(struct Word *word);
801 static int getSpaceStretchability(struct Word *word);
802 int getLineShrinkability(int lastWordIndex);
803 int getLineStretchability(int lastWordIndex);
804 int hyphenateWord (int wordIndex, int *addIndex1 = NULL);
805 void moveWordIndices (int wordIndex, int num, int *addIndex1 = NULL);
806 void accumulateWordForLine (int lineIndex, int wordIndex);
807 void accumulateWordData (int wordIndex);
808 int calcLineBreakWidth (int lineIndex);
809 void initLine1Offset (int wordIndex);
810 void alignLine (int lineIndex);
811 void calcTextOffset (int lineIndex, int totalWidth);
812
813 void drawLevel (core::View *view, core::Rectangle *area, int level,
814 core::DrawingContext *context);
815
816 Widget *getWidgetAtPointLevel (int x, int y, int level,
818
820 Widget **references, int *x, int *y);
823
825
828
829 void notifySetAsTopLevel ();
830 void notifySetParent ();
831
833
834 void calcExtraSpaceImpl (int numPos, Widget **references, int *x, int *y);
835
836 int getAvailWidthOfChild (core::Widget *child, bool forceValue);
837 int getAvailHeightOfChild (core::Widget *child, bool forceValue);
838
841 bool usesAvailWidth ();
842 void resizeDrawImpl ();
843
844 void markSizeChange (int ref);
845 void markExtremesChange (int ref);
846
847 bool isBlockLevel ();
848
854
855 void removeChild (Widget *child);
856
857 void addText0 (const char *text, size_t len, short flags,
859 void calcTextSizes (const char *text, size_t textLen,
861 int numBreaks, int *breakPos,
862 core::Requisition *wordSize);
863
864 int getGeneratorRest (int oofmIndex);
865
866public:
867 static int CLASS_ID;
868
869 static void setPenaltyHyphen (int penaltyHyphen);
870 static void setPenaltyHyphen2 (int penaltyHyphen2);
871 static void setPenaltyEmDashLeft (int penaltyLeftEmDash);
872 static void setPenaltyEmDashRight (int penaltyRightEmDash);
873 static void setPenaltyEmDashRight2 (int penaltyRightEmDash2);
875
879
880 Textblock (bool limitTextWidth, bool treatAsInline = false);
881 ~Textblock ();
882
883 core::Iterator *iterator (core::Content::Type mask, bool atEnd);
884
885 void flush ();
886
887 void addText (const char *text, size_t len, core::style::Style *style);
888 inline void addText (const char *text, core::style::Style *style)
889 { addText (text, strlen(text), style); }
891 bool addAnchor (const char *name, core::style::Style *style);
893 void addBreakOption (core::style::Style *style, bool forceBreak);
894 void addParbreak (int space, core::style::Style *style);
896
898 void changeLinkColor (int link, int newColor);
899 void changeWordStyle (int from, int to, core::style::Style *style,
900 bool includeFirstSpace, bool includeLastSpace);
901
902 void updateReference (int ref);
903 void widgetRefSizeChanged (int externalIndex);
905 int getGeneratorX (int oofmIndex);
906 int getGeneratorY (int oofmIndex);
907 int getGeneratorWidth ();
909 bool usesMaxGeneratorWidth ();
910 bool isPossibleOOFContainer (int oofmIndex);
911 bool isPossibleOOFContainerParent (int oofmIndex);
912};
913
914#define DBG_SET_WORD_PENALTY(n, i, is) \
915 D_STMT_START { \
916 if (words->getRef(n)->badnessAndPenalty.getPenalty (i) == INT_MIN) \
917 DBG_OBJ_ARRATTRSET_SYM ("words", n, "penalty." is, "-inf"); \
918 else if (words->getRef(n)->badnessAndPenalty.getPenalty (i) == INT_MAX) \
919 DBG_OBJ_ARRATTRSET_SYM ("words", n, "penalty." is, "inf"); \
920 else \
921 DBG_OBJ_ARRATTRSET_NUM ("words", n, "penalty." is, \
922 words->getRef(n)->badnessAndPenalty \
923 .getPenalty (i)); \
924 } D_STMT_END
925
926#ifdef DBG_RTFL
927#define DBG_OBJ_ARRATTRSET_WREF(var, ind, attr, wref) \
928 RTFL_OBJ_PRINT ("set", "p:s.d.s:p (p, d)", this, var, ind, attr, wref, \
929 wref->widget, wref->parentRef)
930#else
931#define DBG_OBJ_ARRATTRSET_WREF(var, ind, attr, wref) STMT_NOP
932#endif
933
934#define DBG_SET_WORD(n) \
935 D_STMT_START { \
936 switch (words->getRef(n)->content.type) { \
937 case ::dw::core::Content::TEXT: \
938 DBG_OBJ_ARRATTRSET_SYM ("words", n, "type", "TEXT"); \
939 DBG_OBJ_ARRATTRSET_STR ("words", n, \
940 "text/widget/widgetReference/breakSpace", \
941 words->getRef(n)->content.text); \
942 break; \
943 case ::dw::core::Content::WIDGET_IN_FLOW: \
944 DBG_OBJ_ARRATTRSET_SYM ("words", n, "type", "WIDGET_IN_FLOW"); \
945 DBG_OBJ_ARRATTRSET_PTR ("words", n, \
946 "text/widget/widgetReference/breakSpace", \
947 words->getRef(n)->content.widget); \
948 break; \
949 case ::dw::core::Content::WIDGET_OOF_REF: \
950 DBG_OBJ_ARRATTRSET_SYM ("words", n, "type", "WIDGET_OOF_REF"); \
951 DBG_OBJ_ARRATTRSET_WREF ("words", n, \
952 "text/widget/widgetReference/breakSpace", \
953 words->getRef(n)->content.widgetReference); \
954 break; \
955 case ::dw::core::Content::BREAK: \
956 DBG_OBJ_ARRATTRSET_SYM ("words", n, "type", "BREAK"); \
957 DBG_OBJ_ARRATTRSET_NUM ("words", n, \
958 "text/widget/widgetReference/breakSpace", \
959 words->getRef(n)->content.breakSpace); \
960 break; \
961 default: \
962 DBG_OBJ_ARRATTRSET_SYM ("words", n, "type", "???"); \
963 DBG_OBJ_ARRATTRSET_SYM ("words", n, \
964 "text/widget/widgetReference/breakSpace", \
965 "???"); \
966 } \
967 DBG_SET_WORD_PENALTY (n, 0, "0"); \
968 DBG_SET_WORD_PENALTY (n, 1, "1"); \
969 } D_STMT_END
970
971#define DBG_SET_WORD_SIZE(n) \
972 D_STMT_START { \
973 DBG_OBJ_ARRATTRSET_NUM ("words", n, "size.width", \
974 words->getRef(n)->size.width); \
975 DBG_OBJ_ARRATTRSET_NUM ("words", n, "size.ascent", \
976 words->getRef(n)->size.ascent); \
977 DBG_OBJ_ARRATTRSET_NUM ("words", n, "size.descent", \
978 words->getRef(n)->size.descent); \
979 } D_STMT_END
980
981#define DBG_MSG_WORD(aspect, prio, prefix, n, suffix) \
982 D_STMT_START { \
983 if ((n) < 0 || (n) >= words->size ()) \
984 DBG_OBJ_MSG (aspect, prio, prefix "undefined (wrong index)" suffix); \
985 else { \
986 switch (words->getRef(n)->content.type) { \
987 case ::dw::core::Content::TEXT: \
988 DBG_OBJ_MSGF (aspect, prio, prefix "TEXT / \"%s\"" suffix, \
989 words->getRef(n)->content.text); \
990 break; \
991 case ::dw::core::Content::WIDGET_IN_FLOW: \
992 DBG_OBJ_MSGF (aspect, prio, prefix "WIDGET_IN_FLOW / %p" suffix, \
993 words->getRef(n)->content.widget); \
994 break; \
995 case ::dw::core::Content::WIDGET_OOF_REF: \
996 DBG_OBJ_MSGF (aspect, prio, \
997 prefix "WIDGET_OOF_REF / %p (%p, %d)" suffix,\
998 words->getRef(n)->content.widgetReference, \
999 words->getRef(n)->content.widgetReference->widget, \
1000 words->getRef(n)->content.widgetReference \
1001 ->parentRef); \
1002 break; \
1003 case ::dw::core::Content::BREAK: \
1004 DBG_OBJ_MSGF (aspect, prio, prefix "BREAK / %d" suffix, \
1005 words->getRef(n)->content.breakSpace); \
1006 break; \
1007 default: \
1008 DBG_OBJ_MSG (aspect, prio, prefix "??? / ???" suffix); \
1009 } \
1010 } \
1011 } D_STMT_END
1012
1013} // namespace dw
1014
1015#endif // __DW_TEXTBLOCK_HH__
Base class (rather a tag interface) for those widgets regarding borders defined by floats,...
int penaltyValue(int index, int infLevel)
enum dw::Textblock::BadnessAndPenalty::@31 badnessState
int compareTo(int penaltyIndex, BadnessAndPenalty *other)
void intoStringBuffer(lout::misc::StringBuffer *sb)
void calcBadness(int totalWidth, int idealWidth, int totalStretchability, int totalShrinkability)
void setPenalties(int penalty1, int penalty2)
Sets the penalty, multiplied by 100.
void setSinglePenalty(int index, int penalty)
SpaceImgRenderer(Textblock *textblock, int wordNo)
Definition textblock.hh:327
void getBgArea(int *x, int *y, int *width, int *height)
Return the area covered by the background image.
Definition textblock.cc:110
core::style::Style * getStyle()
Return the style this background image is part of.
Definition textblock.cc:118
void unhighlight(int direction, core::HighlightLayer layer)
Shrink highlighted region to no longer contain the current content.
lout::object::Object * clone()
Return an exact copy of the object.
static TextblockIterator * createWordIndexIterator(Textblock *textblock, core::Content::Type mask, int wordIndex)
void highlight(int start, int end, core::HighlightLayer layer)
Extend highlighted region to contain part of the current content.
void getContentInFlow(int index, core::Content *content)
Implementation used for words.
Definition textblock.hh:305
bool readyToDraw()
If this method returns false, nothing is done at all.
Definition textblock.cc:70
void draw(int x, int y, int width, int height)
Draw (or queue for drawing) an area, which is given in canvas coordinates.
Definition textblock.cc:103
void setData(int xWordWidget, int lineNo)
Definition textblock.cc:63
void getBgArea(int *x, int *y, int *width, int *height)
Return the area covered by the background image.
Definition textblock.cc:80
void getRefArea(int *xRef, int *yRef, int *widthRef, int *heightRef)
Return the "reference area".
Definition textblock.cc:91
core::style::Style * getStyle()
Return the style this background image is part of.
Definition textblock.cc:98
A Widget for rendering text blocks, i.e.
Definition textblock.hh:206
void drawLine(Line *line, core::View *view, core::Rectangle *area, core::DrawingContext *context)
int findParagraphOfWord(int wordIndex)
Find the paragraph of word wordIndex.
void drawWord0(int wordIndex1, int wordIndex2, const char *text, int totalWidth, bool drawHyphen, core::style::Style *style, core::View *view, core::Rectangle *area, int xWidget, int yWidgetBase)
TODO Comment.
void calcTextSizes(const char *text, size_t textLen, core::style::Style *style, int numBreaks, int *breakPos, core::Requisition *wordSize)
void initLine1Offset(int wordIndex)
int searchBreakPos(int wordIndex, int firstIndex, int *searchUntil, bool tempNewLine, int penaltyIndex, bool thereWillBeMoreSpace, bool wrapAll, int *diffWords, int *wordIndexEnd, int *addIndex1=NULL)
void breakAdded()
Called directly after a (line or paragraph) break has been added.
void getExtremesSimpl(core::Extremes *extremes)
Simple variant, to be implemented by widgets with extremes not depending on positions.
Definition textblock.cc:467
void changeWordStyle(int from, int to, core::style::Style *style, bool includeFirstSpace, bool includeLastSpace)
int newLineLeftFloatHeight
Definition textblock.hh:600
void accumulateWordData(int wordIndex)
void addWidget(core::Widget *widget, core::style::Style *style)
Add a widget (word type) to the page.
void getWordExtremes(Word *word, core::Extremes *extremes)
Get the extremes of a word within a textblock.
Definition textblock.cc:457
void addSpace(core::style::Style *style)
?
lout::misc::NotSoSimpleVector< Word > * words
Definition textblock.hh:611
int wrapWordOofRef(int wordIndex, bool wrapAll)
void handleWordExtremes(int wordIndex)
Counter part to wordWrap(), but for extremes, not size calculation.
core::SizeParams sizeRequestParams
Definition textblock.hh:578
int yOffsetOfLineCreated(Line *line)
Includes margin, border, and padding.
int lineYOffsetWidget(int lineIndex)
Definition textblock.hh:732
void correctLastWordExtremes()
Called when something changed for the last word (space, hyphens etc.).
virtual int wordWrap(int wordIndex, bool wrapAll)
void addText(const char *text, core::style::Style *style)
Definition textblock.hh:888
int getLineStretchability(int lastWordIndex)
void setWordImgRenderer(int wordNo)
void enterNotifyImpl(core::EventCrossing *event)
void changeLinkColor(int link, int newColor)
bool isHyphenationCandidate(Word *word)
void widgetRefSizeChanged(int externalIndex)
Called by an implementation of dw::oof::OutOfFlowMgr (actually only OOFPosRelMgr) for the generator o...
int numSizeReferences
Definition textblock.hh:619
Widget * getExtremesReference(int index)
See Sizes of Dillo Widgets (or Size requisitions depending on positions).
Definition textblock.cc:533
struct dw::Textblock::@30 hlStart[core::HIGHLIGHT_NUM_LAYERS]
void handOverBreak(core::style::Style *style)
This function "hands" the last break of a page "over" to a parent page.
void processWord(int wordIndex)
Line * addLine(int firstWord, int lastWord, int newLastOofPos, bool temporary, int minHeight)
static bool mustAddBreaks(core::style::Style *style)
Definition textblock.hh:876
int considerHyphenation(int firstIndex, int breakPos)
Suggest a word to hyphenate, when breaking at breakPos is planned.
void markSizeChange(int ref)
See Sizes of Dillo Widgets.
Definition textblock.cc:877
bool calcSizeOfWidgetInFlow(int wordIndex, Widget *widget, core::Requisition *size)
Calculate the size of a widget, and return whether it has to be positioned at the top of the line.
void oofSizeChanged(bool extremesChanged)
Called by an implementation of dw::oof::OutOfFlowMgr when the size of the container has changed,...
int numGetExtremesReferences()
See Sizes of Dillo Widgets (or Size requisitions depending on positions).
Definition textblock.cc:528
int getGeneratorX(int oofmIndex)
Return position relative to container, not regarding margin/border/padding, Called by OOFFloatsMgr to...
bool newLineHasFloatRight
Definition textblock.hh:595
void fillParagraphs()
Counter part to rewrap(), but for extremes, not size calculation.
static void setStretchabilityFactor(int stretchabilityFactor)
Definition textblock.cc:201
void calcBorders(int lastOofRef, int height)
void rewrap()
Rewrap the page from the line from which this is necessary.
void drawSpace(int wordIndex, core::View *view, core::Rectangle *area, int xWidget, int yWidgetBase)
void sizeAllocateImpl(core::Allocation *allocation)
See Sizes of Dillo Widgets.
Definition textblock.cc:569
static const char * hyphenDrawChar
The character which is used to draw a hyphen at the end of a line, either caused by automatic hyphena...
Definition textblock.hh:296
bool findSizeRequestReference(int oofmIndex, int *xRef=NULL, int *yRef=NULL)
Definition textblock.hh:688
core::Iterator * iterator(core::Content::Type mask, bool atEnd)
Return an iterator for this widget.
void calcExtraSpaceImpl(int numPos, Widget **references, int *x, int *y)
Definition textblock.cc:734
int findLineIndexWhenNotAllocated(int y)
int lineYOffsetWidget(Line *line, core::Allocation *allocation)
Definition textblock.hh:712
void cleanupWord(int wordNo)
void calcTextOffset(int lineIndex, int totalWidth)
Word * findWord(int x, int y, bool *inSpace)
Find the index of the word, or -1.
void balanceBreakPosAndHeight(int wordIndex, int firstIndex, int *searchUntil, bool tempNewLine, int penaltyIndex, bool borderIsCalculated, bool *thereWillBeMoreSpace, bool wrapAll, int *diffWords, int *wordIndexEnd, int *lastFloatPos, bool regardBorder, int *height, int *breakPos)
static void setPenaltyHyphen(int penaltyHyphen)
Definition textblock.cc:175
int newLineRightBorder
Definition textblock.hh:596
bool mustBorderBeRegarded(int lineNo)
Definition textblock.hh:701
void calcTextSize(const char *text, size_t len, core::style::Style *style, core::Requisition *size, bool isStart, bool isEnd)
Calculate the size of a text word.
void notifySetParent()
This method is called after a widget has been added to a parent.
Definition textblock.cc:546
RegardingBorder * getWidgetRegardingBorderForLine(Line *line)
void setBreakOption(Word *word, core::style::Style *style, int breakPenalty1, int breakPenalty2, bool forceBreak)
Set a break option, if allowed by the style.
void accumulateWordForLine(int lineIndex, int wordIndex)
void drawWord(Line *line, int wordIndex1, int wordIndex2, core::View *view, core::Rectangle *area, int xWidget, int yWidgetBase)
Draw a word of text.
int lineYOffsetCanvas(int lineIndex)
Definition textblock.hh:742
int newLineLeftBorder
Definition textblock.hh:596
bool isBreakAllowedInWord(Word *word)
Definition textblock.hh:677
int numSizeRequestReferences()
See Sizes of Dillo Widgets (or Size requisitions depending on positions).
Definition textblock.cc:422
static void setPenaltyEmDashLeft(int penaltyLeftEmDash)
Definition textblock.cc:185
int searchMinBap(int firstWord, int lastWordm, int penaltyIndex, bool thereWillBeMoreSpace, bool correctAtEnd)
int lineYOffsetWidget(int lineIndex, core::Allocation *allocation)
Definition textblock.hh:737
int getAvailHeightOfChild(core::Widget *child, bool forceValue)
Definition textblock.cc:809
int nonTemporaryLines
Definition textblock.hh:610
int getLineShrinkability(int lastWordIndex)
bool limitTextWidth
Definition textblock.hh:572
int lineYOffsetWidget(Line *line)
Definition textblock.hh:717
lout::misc::SimpleVector< Anchor > * anchors
Definition textblock.hh:612
int lineYOffsetCanvas(Line *line)
Definition textblock.hh:727
static int getSpaceStretchability(struct Word *word)
bool affectsSizeChangeContainerChild(Widget *child)
Definition textblock.cc:834
int yOffsetOfLineToBeCreated(int *lastMargin=NULL)
Includes margin, border, and padding.
void setSpaceImgRenderer(int wordNo)
static int stretchabilityFactor
...
Definition textblock.hh:570
static void setPenaltyHyphen2(int penaltyHyphen2)
Definition textblock.cc:180
bool addAnchor(const char *name, core::style::Style *style)
Add an anchor to the page.
static void setPenaltyEmDashRight2(int penaltyRightEmDash2)
Definition textblock.cc:196
void addText(const char *text, size_t len, core::style::Style *style)
Add a word to the page structure.
int getGeneratorY(int oofmIndex)
Return position relative to container, not regarding margin/border/padding, Called by OOFFloatsMgr to...
bool mustBorderBeRegarded(Line *line)
Of nested text blocks, only the most inner one must regard the borders of floats.
Definition textblock.hh:696
struct dw::Textblock::@30 hlEnd[core::HIGHLIGHT_NUM_LAYERS]
bool findSizeRequestReference(Widget *reference, int *xRef=NULL, int *yRef=NULL)
bool isBlockLevel()
Definition textblock.cc:938
void drawText(core::View *view, core::style::Style *style, core::style::Color::Shading shading, int x, int y, const char *text, int start, int len, bool isStart, bool isEnd)
void addBreakOption(core::style::Style *style, bool forceBreak)
Add a break option (see setBreakOption() for details).
void moveWordIndices(int wordIndex, int num, int *addIndex1=NULL)
int calcVerticalBorder(int widgetPadding, int widgetBorder, int widgetMargin, int lineBorderTotal, int lineMarginTotal)
Definition textblock.cc:432
int getMaxGeneratorWidth()
int getGeneratorRest(int oofmIndex)
static int penalties[PENALTY_NUM][2]
The penalties for hyphens and other, multiplied by 100.
Definition textblock.hh:565
int hyphenateWord(int wordIndex, int *addIndex1=NULL)
void leaveNotifyImpl(core::EventCrossing *event)
int calcLineBreakWidth(int lineIndex)
void resizeDrawImpl()
Called after sizeAllocateImpl() to redraw necessary areas.
Definition textblock.cc:857
bool isBreakAllowed(core::style::Style *style)
static void setPenaltyEmDashRight(int penaltyRightEmDash)
Definition textblock.cc:191
bool newLineHasFloatLeft
Definition textblock.hh:595
bool usesAvailWidth()
Must be implemengted by a method returning true, when getAvailWidth() is called.
Definition textblock.cc:852
void addText0(const char *text, size_t len, short flags, core::style::Style *style, core::Requisition *size)
Add a word (without hyphens) to the page structure.
Widget * getWidgetAtPointLevel(int x, int y, int level, core::GettingWidgetAtPointContext *context)
int getGeneratorWidth()
Return width including margin/border/padding Called by OOFFloatsMgr to position floats.
void decorateText(core::View *view, core::style::Style *style, core::style::Color::Shading shading, int x, int yBase, int width)
int findLineOfWord(int wordIndex)
Find the line of word wordIndex.
int wrapWordInFlow(int wordIndex, bool wrapAll)
void removeChild(Widget *child)
bool mustQueueResize
Definition textblock.hh:557
int textWidth(const char *text, int start, int len, core::style::Style *style, bool isStart, bool isEnd)
void notifySetAsTopLevel()
This method is called after a widget has been set as the top of a widget tree.
Definition textblock.cc:538
int newLineRightFloatHeight
Definition textblock.hh:600
void addParbreak(int space, core::style::Style *style)
Cause a paragraph break.
void fillSpace(int wordNo, core::style::Style *style)
int calcLinePartHeight(int firstWord, int lastWord)
Widget * sizeReferences[NUM_OOFM]
Definition textblock.hh:620
bool buttonPressImpl(core::EventButton *event)
Definition textblock.cc:943
static int CLASS_ID
Definition textblock.hh:867
void queueDrawRange(int index1, int index2)
Widget * sizeRequestReference(int index)
See Sizes of Dillo Widgets (or Size requisitions depending on positions).
Definition textblock.cc:427
bool isPossibleOOFContainer(int oofmIndex)
void containerSizeChangedForChildren()
Definition textblock.cc:819
void updateReference(int ref)
Update content in flow, down from ref.
bool usesMaxGeneratorWidth()
void alignLine(int lineIndex)
Align the line.
void fillWord(int wordNo, int width, int ascent, int descent, short flags, core::style::Style *style)
int calcPenaltyIndexForNewLine()
Definition textblock.hh:747
bool motionNotifyImpl(core::EventMotion *event)
Definition textblock.cc:958
bool sendSelectionEvent(core::SelectionState::EventType eventType, core::MousePositionEvent *event)
Send event to selection.
void addLinebreak(core::style::Style *style)
int findLineIndexWhenAllocated(int y)
void removeSpaceImgRenderer(int wordNo)
void initWord(int wordNo)
Basic initialization, which is neccessary before fillWord.
bool hasListitemValue
Definition textblock.hh:531
void sizeRequestImpl(core::Requisition *requisition, int numPos, Widget **references, int *x, int *y)
The ascent of a textblock is the ascent of the first line, plus padding/border/margin.
Definition textblock.cc:308
int wrapRefParagraphs
Definition textblock.hh:583
bool buttonReleaseImpl(core::EventButton *event)
Definition textblock.cc:948
Word * addWord(int width, int ascent, int descent, short flags, core::style::Style *style)
Add a new word (text, widget etc.) to a page.
int getAvailWidthOfChild(core::Widget *child, bool forceValue)
Computes the content width available of a child widget.
Definition textblock.cc:755
void removeWordImgRenderer(int wordNo)
static DivChar divChars[NUM_DIV_CHARS]
Definition textblock.hh:294
void markExtremesChange(int ref)
See Sizes of Dillo Widgets.
Definition textblock.cc:911
lout::misc::SimpleVector< Paragraph > * paragraphs
Definition textblock.hh:609
void justifyLine(Line *line, int diff)
static int getSpaceShrinkability(struct Word *word)
void drawLevel(core::View *view, core::Rectangle *area, int level, core::DrawingContext *context)
bool ignoreLine1OffsetSometimes
Definition textblock.hh:555
int lineYOffsetCanvas(Line *line, core::Allocation *allocation)
Definition textblock.hh:722
lout::misc::SimpleVector< Line > * lines
Definition textblock.hh:608
bool isPossibleOOFContainerParent(int oofmIndex)
int findLineIndex(int y)
Find the first line index that includes y, which is given in widget coordinates.
Set at the top when drawing.
Definition types.hh:295
Represents a button press or release event.
Definition events.hh:58
Represents a enter or leave notify event.
Definition events.hh:75
Represents a mouse motion event.
Definition events.hh:68
Set at the top when getting the widget at the point.
Definition types.hh:313
Iterators are used to iterate through the contents of a widget.
Definition iterator.hh:20
Content::Type mask
Definition iterator.hh:30
Base class for all mouse events related to a specific position.
Definition events.hh:49
dw::core::Shape implemtation for simple rectangles.
Definition types.hh:70
Hold arguments passed to dw::core::Widget::sizeRequest and dw::core::Widget::getExtremes,...
Definition tools.hh:19
An interface to encapsulate platform dependent drawing.
Definition view.hh:17
The base class of all dillo widgets.
Definition widget.hh:24
Allocation * getAllocation()
Definition widget.hh:450
Extremes extremes
Analogue to dw::core::Widget::requisition.
Definition widget.hh:146
Allocation allocation
The current allocation: size and position, always relative to the canvas.
Definition widget.hh:183
Requisition requisition
Size_request() stores the result of the last call of size_request_impl().
Definition widget.hh:140
bool extremesChanged()
Definition widget.hh:440
style::Style * style
Definition widget.hh:130
Suitable for widgets and parts of widgets.
Definition style.hh:855
static bool testStyleRelativelyPositioned(core::style::Style *style)
OOFAwareWidget * oofContainer[NUM_OOFM]
static bool testStyleOutOfFlow(core::style::Style *style)
A class for fast concatenation of a large number of strings.
Definition misc.hh:566
This is the base class for many other classes, which defines very common virtual methods.
Definition object.hh:25
HighlightLayer
Definition types.hh:43
@ HIGHLIGHT_NUM_LAYERS
Definition types.hh:46
Dw is in this namespace, or sub namespaces of this one.
T max(T a, T b)
Definition misc.hh:20
enum dw::Textblock::Line::@33 alignment
int lastOofRefPositionedBeforeThisLine
Definition textblock.hh:421
int totalHeight(int marginNextLine)
Returns the difference between two vertical lines positions: height of this line plus space below thi...
Definition textblock.hh:401
SpaceImgRenderer * spaceImgRenderer
Definition textblock.hh:499
core::style::Style * style
Definition textblock.hh:492
WordImgRenderer * wordImgRenderer
Definition textblock.hh:498
core::Requisition size
Definition textblock.hh:463
BadnessAndPenalty badnessAndPenalty
Definition textblock.hh:489
core::style::Style * spaceStyle
Definition textblock.hh:493
core::Content content
Definition textblock.hh:475
@ DIV_CHAR_AT_EOL
Must be drawn with a hyphen, when at the end of the line.
Definition textblock.hh:434
@ CAN_BE_HYPHENATED
Can be hyphenated automatically.
Definition textblock.hh:432
@ PERM_DIV_CHAR
Is or ends with a "division character", which is part of the word.
Definition textblock.hh:437
@ DRAW_AS_ONE_TEXT
This word must be drawn, together with the following word(s), by only one call of View::drawText(),...
Definition textblock.hh:442
Represents the allocation, i.e.
Definition types.hh:164