diff options
Diffstat (limited to 'dw/textblock.hh')
-rw-r--r-- | dw/textblock.hh | 118 |
1 files changed, 96 insertions, 22 deletions
diff --git a/dw/textblock.hh b/dw/textblock.hh index d5b64e42..e5423c98 100644 --- a/dw/textblock.hh +++ b/dw/textblock.hh @@ -4,6 +4,7 @@ #include <limits.h> #include "core.hh" +#include "outofflowmgr.hh" #include "../lout/misc.hh" // These were used when improved line breaking and hyphenation were @@ -11,6 +12,8 @@ #define PRINTF(fmt, ...) #define PUTCHAR(ch) +//#define DEBUG + namespace dw { /** @@ -18,10 +21,11 @@ namespace dw { * of paragraphs. * * <div style="border: 2px solid #ffff00; margin-top: 0.5em; - * margin-bottom: 0.5em; padding: 0.5em 1em; - * background-color: #ffffe0"><b>Info:</b> The recent changes (line - * breaking and hyphenation) have not yet been incorporated into this - * documentation. See \ref dw-line-breaking.</div> + * margin-bottom: 0.5em; padding: 0.5em 1em; background-color: + * #ffffe0"><b>Info:</b> The recent changes (line breaking and + * hyphenation on one hand, floats on the other hand) have not yet + * been incorporated into this documentation. See \ref + * dw-line-breaking and \ref dw-out-of-flow.</div> * * <h3>Signals</h3> * @@ -146,7 +150,7 @@ namespace dw { * necessary, or otherwise the line from which a rewrap is necessary. * */ -class Textblock: public core::Widget +class Textblock: public core::Widget, public OutOfFlowMgr::ContainingBlock { private: /** @@ -236,6 +240,9 @@ private: static const char *hyphenDrawChar; + Textblock *containingBlock; + OutOfFlowMgr *outOfFlowMgr; + protected: struct Paragraph { @@ -275,7 +282,7 @@ protected: /* "top" is always relative to the top of the first line, i.e. * page->lines[0].top is always 0. */ int top, boxAscent, boxDescent, contentAscent, contentDescent, - breakSpace, leftOffset; + breakSpace, leftOffset, offsetCompleteWidget; /* This is similar to descent, but includes the bottom margins of the * widgets within this line. */ @@ -359,13 +366,14 @@ protected: class TextblockIterator: public core::Iterator { private: + bool oofm; int index; public: TextblockIterator (Textblock *textblock, core::Content::Type mask, bool atEnd); TextblockIterator (Textblock *textblock, core::Content::Type mask, - int index); + bool oofm, int index); lout::object::Object *clone(); int compareTo(lout::misc::Comparable *other); @@ -375,6 +383,7 @@ protected: void highlight (int start, int end, core::HighlightLayer layer); void unhighlight (int direction, core::HighlightLayer layer); void getAllocation (int start, int end, core::Allocation *allocation); + void print (); }; friend class TextblockIterator; @@ -424,7 +433,10 @@ protected: /* These values are set by set_... */ int availWidth, availAscent, availDescent; - int wrapRefLines, wrapRefParagraphs; /* [0 based] */ + int wrapRefLines, wrapRefParagraphs; /* 0-based. Important: Both + are the line numbers, not + the value stored in + parentRef. */ lout::misc::SimpleVector <Line> *lines; lout::misc::SimpleVector <Paragraph> *paragraphs; @@ -480,25 +492,68 @@ protected: core::Requisition *size); /** - * \brief Returns the x offset (the indentation plus any offset needed for - * centering or right justification) for the line. - * - * The offset returned is relative to the page *content* (i.e. without - * border etc.). + * Of nested text blocks, only the most inner one must regard the + * borders of floats. */ - inline int lineXOffsetContents (Line *line) + inline bool mustBorderBeRegarded (Line *line) { - return innerPadding + line->leftOffset + - (line == lines->getFirstRef() ? line1OffsetEff : 0); + return getTextblockForLine (line) == NULL; } - /** - * \brief Like lineXOffset, but relative to the allocation (i.e. - * including border etc.). - */ - inline int lineXOffsetWidget (Line *line) + inline bool mustBorderBeRegarded (int lineNo) + { + return getTextblockForLine (lineNo) == NULL; + } + + void borderChanged (int yWidget, bool extremesChanges); + + int diffXToContainingBlock, restWidthToContainingBlock, + diffYToContainingBlock; + + inline int lineLeftBorder (int lineNo) + { + assert (diffXToContainingBlock != -1); + assert (diffYToContainingBlock != -1); + + // Note that the line must not exist yet (but unless it is not + // the first line, the previous line, lineNo - 1, must). + int resultFromOOFM; + if (containingBlock->outOfFlowMgr && mustBorderBeRegarded (lineNo)) + resultFromOOFM = + containingBlock->outOfFlowMgr->getLeftBorder + (topOfPossiblyMissingLine (lineNo) + diffYToContainingBlock, + heightOfPossiblyMissingLine (lineNo)) + - diffXToContainingBlock; + else + resultFromOOFM = 0; + + // TODO: line->leftOffset is not regarded, which is correct, depending + // on where this method is called. Document; perhaps rename this method. + // (Update: was renamed.) + return innerPadding + + (lineNo == 0 ? line1OffsetEff : 0) + + lout::misc::max (getStyle()->boxOffsetX(), resultFromOOFM); + } + + inline int lineRightBorder (int lineNo) { - return lineXOffsetContents (line) + getStyle()->boxOffsetX (); + assert (restWidthToContainingBlock != -1); + assert (diffYToContainingBlock != -1); + + // Similar to lineLeftBorder(). + + int resultFromOOFM; + // TODO sizeRequest? + if (containingBlock->outOfFlowMgr && mustBorderBeRegarded (lineNo)) + resultFromOOFM = + containingBlock->outOfFlowMgr->getRightBorder + (topOfPossiblyMissingLine (lineNo) + diffYToContainingBlock, + heightOfPossiblyMissingLine (lineNo)) + - restWidthToContainingBlock; + else + resultFromOOFM = 0; + + return lout::misc::max (getStyle()->boxRestWidth(), resultFromOOFM); } inline int lineYOffsetWidgetAllocation (Line *line, @@ -549,6 +604,12 @@ protected: (Word::DIV_CHAR_AT_EOL | Word::PERM_DIV_CHAR)) ? 1 : 0; } + Textblock *getTextblockForLine (Line *line); + Textblock *getTextblockForLine (int lineNo); + Textblock *getTextblockForLine (int firstWord, int lastWord); + int topOfPossiblyMissingLine (int lineNo); + int heightOfPossiblyMissingLine (int lineNo); + bool sendSelectionEvent (core::SelectionState::EventType eventType, core::MousePositionEvent *event); @@ -556,6 +617,12 @@ protected: int *maxOfMinWidth, int *sumOfMaxWidth); void processWord (int wordIndex); virtual void wordWrap (int wordIndex, bool wrapAll); + void wrapWidgetOofRef (int wordIndex); + int searchMinBap (int firstWord, int lastWordm, int penaltyIndex, + bool correctAtEnd); + int considerHyphenation (int breakPos); + bool isHyphenationCandidate (Word *word); + void handleWordExtremes (int wordIndex); void correctLastWordExtremes (); @@ -575,6 +642,8 @@ protected: void markSizeChange (int ref); void markExtremesChange (int ref); + void notifySetAsTopLevel(); + void notifySetParent(); void setWidth (int width); void setAscent (int ascent); void setDescent (int descent); @@ -594,6 +663,7 @@ protected: core::style::Style *style, int numBreaks, int *breakPos, core::Requisition *wordSize); + static bool isContainingBlock (Widget *widget); public: static int CLASS_ID; @@ -639,6 +709,10 @@ public: void changeLinkColor (int link, int newColor); void changeWordStyle (int from, int to, core::style::Style *style, bool includeFirstSpace, bool includeLastSpace); + + // From OutOfFlowMgr::ContainingBlock: + void borderChanged (int y); + core::Widget *asWidget (); }; } // namespace dw |