aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Geerken <devnull@localhost>2013-01-13 11:11:32 +0100
committerSebastian Geerken <devnull@localhost>2013-01-13 11:11:32 +0100
commit1924a60362ef44b7661ee52118aea5f6f5bad1cc (patch)
tree8ea1e980503dfd3b2b43b933668bc7f5d82ec003
parentc970e613628ca47f47aa3336390a237a83c67d29 (diff)
Now, all floats covering a line are considered for calculating the borders.
-rw-r--r--dw/outofflowmgr.cc63
-rw-r--r--dw/outofflowmgr.hh11
-rw-r--r--dw/textblock.cc25
-rw-r--r--dw/textblock.hh7
-rw-r--r--dw/textblock_linebreaking.cc8
5 files changed, 74 insertions, 40 deletions
diff --git a/dw/outofflowmgr.cc b/dw/outofflowmgr.cc
index 6d7349d9..161c3746 100644
--- a/dw/outofflowmgr.cc
+++ b/dw/outofflowmgr.cc
@@ -345,44 +345,53 @@ namespace dw {
containingBlock->borderChanged (min (oldY, vloat->y));
}
-int OutOfFlowMgr::getLeftBorder (int y)
+/**
+ * Get the left border for the vertical position of *y*, for a height
+ * of *h", based on floats.
+ *
+ * The border includes marging/border/padding of the containging
+ * block, but is 0 if there is no float, so a caller should also
+ * consider other borders.
+ */
+int OutOfFlowMgr::getLeftBorder (int y, int h)
{
- //return 40 * sin ((double)y / 30);
-
- for(int i = 0; i < leftFloats->size(); i++) {
- Float *vloat = leftFloats->get(i);
- ensureFloatSize (vloat);
-
- if(vloat->y != -1 && y >= vloat->y &&
- y < vloat->y + vloat->size.ascent + vloat->size.descent) {
- //printf (" LEFT: %d ==> %d (%d + %d)\n", y,
- // vloat->size.width, vloat->size.ascent, vloat->size.descent);
- return vloat->size.width + vloat->borderWidth;
- }
- }
+ return getBorder (leftFloats, y, h);
+}
- //printf (" LEFT: %d ==> %d (no float)\n", y, 0);
- return 0;
+/**
+ * Get the right border for the vertical position of *y*, for a height
+ * of *h", based on floats.
+ *
+ * See also getLeftBorder(int, int);
+ */
+int OutOfFlowMgr::getRightBorder (int y, int h)
+{
+ return getBorder (rightFloats, y, h);
}
-int OutOfFlowMgr::getRightBorder (int y)
+int OutOfFlowMgr::getBorder (Vector<Float> *list, int y, int h)
{
- //return 40 * cos ((double)y / 30);
+ int border = 0;
- for(int i = 0; i < rightFloats->size(); i++) {
- Float *vloat = rightFloats->get(i);
+ // To be a bit more efficient, one could use linear search to find
+ // the first affected float.
+ for(int i = 0; i < list->size(); i++) {
+ Float *vloat = list->get(i);
ensureFloatSize (vloat);
-
- if(vloat->y != -1 && y >= vloat->y &&
+
+ if(vloat->y != -1 && y + h >= vloat->y &&
y < vloat->y + vloat->size.ascent + vloat->size.descent) {
- //printf (" RIGHT: %d ==> %d (%d + %d)\n", y,
- // vloat->size.width, vloat->size.ascent, vloat->size.descent);
- return vloat->size.width + vloat->borderWidth;
+ // It is not sufficient to find the first float, since a line
+ // (with height h) may cover the region of multiple float, of
+ // which the widest has to be choosen.
+ border = max (border, vloat->size.width + vloat->borderWidth);
}
+ // To be a bit more efficient, the loop could be stopped when
+ // (i) at least one float has been found, and (ii) the next float is
+ // below y + h.
}
- //printf (" RIGHT: %d ==> %d (no float)\n", y, 0);
- return 0;
+ return border;
}
void OutOfFlowMgr::ensureFloatSize (Float *vloat)
diff --git a/dw/outofflowmgr.hh b/dw/outofflowmgr.hh
index af10d2e0..13fc0877 100644
--- a/dw/outofflowmgr.hh
+++ b/dw/outofflowmgr.hh
@@ -47,6 +47,7 @@ private:
core::View *view, core::Rectangle *area);
core::Widget *getWidgetAtPoint (lout::container::typed::Vector<Float> *list,
int x, int y, int level);
+ int getBorder (lout::container::typed::Vector<Float> *list, int y, int h);
inline static bool isRefFloat (int ref)
{ return ref != -1 && (ref & 1) == 1; }
@@ -87,15 +88,9 @@ public:
void getSize (int cbWidth, int cbHeight, int *oofWidth, int *oofHeight);
- /**
- * Get the left border for the vertical position of y, based on
- * floats. The border includes marging/border/padding of the
- * containging block, but is 0 if there is no float, so a caller
- * should also consider other borders.
- */
- int getLeftBorder (int y);
+ int getLeftBorder (int y, int h);
- int getRightBorder (int y);
+ int getRightBorder (int y, int h);
inline static bool isRefOutOfFlow (int ref)
{ return ref != -1 && (ref & 1) != 0; }
diff --git a/dw/textblock.cc b/dw/textblock.cc
index 7af85668..79f801a9 100644
--- a/dw/textblock.cc
+++ b/dw/textblock.cc
@@ -2397,6 +2397,31 @@ int Textblock::topOfPossiblyMissingLine (int lineNo)
}
}
+int Textblock::heightOfPossiblyMissingLine (int lineNo)
+{
+ if (lineNo < lines->size()) {
+ // An existing line.
+ Line *line = lines->getRef (lineNo);
+ return line->boxAscent + line->boxDescent;
+ } else if (lineNo == lines->size()) {
+ // The line to be constructed: some words exist, but not the
+ // line. Accumulate the word heights. TODO Could be faster by
+ // accumulating them when words are added.
+
+ // Furthermore, this is in some cases incomplete: see
+ // doc/dw-out-of-flow.doc.
+
+ int h = 1;
+ int firstWord = lines->size() > 0 ? lines->getLastRef()->lastWord + 1 : 0;
+ for (int i = firstWord; i < words->size(); i++) {
+ Word *word = words->getRef (i);
+ h = misc::max (h, word->size.ascent + word->size.descent);
+ }
+ return h;
+ } else
+ return 1;
+}
+
core::Widget *Textblock::asWidget ()
{
return this;
diff --git a/dw/textblock.hh b/dw/textblock.hh
index 22f68fe3..aefe63ef 100644
--- a/dw/textblock.hh
+++ b/dw/textblock.hh
@@ -523,7 +523,8 @@ protected:
if (containingBlock->outOfFlowMgr && mustBorderBeRegarded (lineNo))
resultFromOOFM =
containingBlock->outOfFlowMgr->getLeftBorder
- (topOfPossiblyMissingLine (lineNo) + diffYToContainingBlock)
+ (topOfPossiblyMissingLine (lineNo) + diffYToContainingBlock,
+ heightOfPossiblyMissingLine (lineNo))
- diffXToContainingBlock;
else
resultFromOOFM = 0;
@@ -548,7 +549,8 @@ protected:
if (containingBlock->outOfFlowMgr && mustBorderBeRegarded (lineNo))
resultFromOOFM =
containingBlock->outOfFlowMgr->getRightBorder
- (topOfPossiblyMissingLine (lineNo) + diffYToContainingBlock)
+ (topOfPossiblyMissingLine (lineNo) + diffYToContainingBlock,
+ heightOfPossiblyMissingLine (lineNo))
- restWidthToContainingBlock;
else
resultFromOOFM = 0;
@@ -608,6 +610,7 @@ protected:
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);
diff --git a/dw/textblock_linebreaking.cc b/dw/textblock_linebreaking.cc
index 143cc135..f6851530 100644
--- a/dw/textblock_linebreaking.cc
+++ b/dw/textblock_linebreaking.cc
@@ -376,7 +376,8 @@ Textblock::Line *Textblock::addLine (int firstWord, int lastWord,
if (containingBlock->outOfFlowMgr && mustBorderBeRegarded (line))
resultFromOOFM =
containingBlock->outOfFlowMgr->getLeftBorder
- (line->top + getStyle()->boxOffsetY() + diffYToContainingBlock)
+ (line->top + getStyle()->boxOffsetY() + diffYToContainingBlock,
+ line->boxAscent + line->boxDescent)
- diffXToContainingBlock;
else
resultFromOOFM = 0;
@@ -504,11 +505,12 @@ void Textblock::wordWrap (int wordIndex, bool wrapAll)
int y =
topOfPossiblyMissingLine (lines->size ()) + diffYToContainingBlock;
+ int h = heightOfPossiblyMissingLine (lines->size ());
int l =
- containingBlock->outOfFlowMgr->getLeftBorder (y)
+ containingBlock->outOfFlowMgr->getLeftBorder (y, h)
- diffXToContainingBlock;
int r =
- containingBlock->outOfFlowMgr->getRightBorder (y)
+ containingBlock->outOfFlowMgr->getRightBorder (y, h)
- restWidthToContainingBlock;
thereWillBeMoreSpace = l > 0 || r > 0;