aboutsummaryrefslogtreecommitdiff
path: root/dw/textblock.hh
diff options
context:
space:
mode:
Diffstat (limited to 'dw/textblock.hh')
-rw-r--r--dw/textblock.hh138
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