diff options
Diffstat (limited to 'dw/textblock.hh')
-rw-r--r-- | dw/textblock.hh | 138 |
1 files changed, 121 insertions, 17 deletions
diff --git a/dw/textblock.hh b/dw/textblock.hh index 12950ec3..3a927464 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 @@ -18,10 +19,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> * @@ -141,7 +143,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: /** @@ -207,6 +209,9 @@ private: void print (); }; + Textblock *containingBlock; + OutOfFlowMgr *outOfFlowMgr; + protected: enum { /** @@ -367,7 +372,8 @@ protected: /* These values are set by set_... */ int availWidth, availAscent, availDescent; - int wrapRef; /* [0 based] */ + int wrapRef; /* 0-based. Important: This is the line number, not + the value stored in parentRef. */ lout::misc::SimpleVector <Line> *lines; int nonTemporaryLines; @@ -420,25 +426,115 @@ 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. Extremely (perhaps too) simple + * implementation. */ - inline int lineXOffsetContents (Line *line) + inline bool mustBorderBeRegardedForWord (int firstWord) { - return innerPadding + line->leftOffset + - (line == lines->getFirstRef() ? line1OffsetEff : 0); + assert (firstWord < words->size ()); + Word *word = words->getRef (firstWord); + return !(word->content.type == core::Content::WIDGET_IN_FLOW && + word->content.widget->instanceOf (Textblock::CLASS_ID)); + } + + inline bool mustBorderBeRegarded (Line *line) + { + return mustBorderBeRegardedForWord (line->firstWord); + } + + inline bool mustBorderBeRegarded (int lineNo) + { + int firstWord; + if (lineNo == 0) + firstWord = 0; + else + firstWord = lines->getRef(lineNo - 1)->lastWord + 1; + + return mustBorderBeRegardedForWord (firstWord); } + void borderChanged (int yCanvas, bool extremesChanges); + /** - * \brief Like lineXOffset, but relative to the allocation (i.e. - * including border etc.). + * \brief Returns the x offset (the indentation plus any offset + * needed for centering or right justification) for the line, + * relative to the allocation (i.e. including border etc.). */ inline int lineXOffsetWidget (Line *line) { - return lineXOffsetContents (line) + getStyle()->boxOffsetX (); + int resultFromOOFM; + if (containingBlock->outOfFlowMgr && mustBorderBeRegarded (line)) + resultFromOOFM = + containingBlock->getAllocation()->x - allocation.x + + containingBlock->outOfFlowMgr->getLeftBorder + (allocation.y + line->top + getStyle()->boxOffsetY() + - containingBlock->getAllocation()->y); + else + resultFromOOFM = 0; + + return innerPadding + line->leftOffset + + (line == lines->getFirstRef() ? line1OffsetEff : 0) + + lout::misc::max (getStyle()->boxOffsetX(), resultFromOOFM); + } + + inline int lineLeftBorder (int lineNo) + { + // Note that the line must not exist yet (but unless it is not + // the first line, the previous line, lineNo - 1, must). But + // lineHeight should be known to the caller. + int top; + if (lineNo == 0) + top = 0; + else { + Line *prevLine = lines->getRef (lineNo - 1); + top = prevLine->top + prevLine->boxAscent + prevLine->boxDescent + + prevLine->breakSpace; + } + + int resultFromOOFM; + if (containingBlock->outOfFlowMgr && mustBorderBeRegarded (lineNo)) + resultFromOOFM = + containingBlock->getAllocation()->x - allocation.x + + containingBlock->outOfFlowMgr->getLeftBorder + (allocation.y + top + getStyle()->boxOffsetY() + - containingBlock->getAllocation()->y); + 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) + { + // Similar to lineLeftBorder(). + int top; + if (lineNo == 0) + top = 0; + else { + Line *prevLine = lines->getRef (lineNo - 1); + top = prevLine->top + prevLine->boxAscent + prevLine->boxDescent + + prevLine->breakSpace; + } + + int resultFromOOFM; + if (containingBlock->outOfFlowMgr && mustBorderBeRegarded (lineNo)) + resultFromOOFM = + (containingBlock->getAllocation()->x + + containingBlock->getAllocation()->width) - + (allocation.x + allocation.width) + + containingBlock->outOfFlowMgr->getRightBorder + (allocation.y + top + getStyle()->boxOffsetY() + - containingBlock->getAllocation()->y); + else + resultFromOOFM = 0; + + return lout::misc::max (getStyle()->boxRestWidth(), resultFromOOFM); } inline int lineYOffsetWidgetAllocation (Line *line, @@ -499,6 +595,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); @@ -518,6 +616,7 @@ protected: core::style::Style *style, int numBreaks, int *breakPos, core::Requisition *wordSize); + static bool isContainingBlock (Widget *widget); public: static int CLASS_ID; @@ -563,6 +662,11 @@ 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::style::Style *getCBStyle (); + core::Allocation *getCBAllocation (); }; } // namespace dw |