diff options
author | Sebastian Geerken <devnull@localhost> | 2013-01-13 11:11:32 +0100 |
---|---|---|
committer | Sebastian Geerken <devnull@localhost> | 2013-01-13 11:11:32 +0100 |
commit | 1924a60362ef44b7661ee52118aea5f6f5bad1cc (patch) | |
tree | 8ea1e980503dfd3b2b43b933668bc7f5d82ec003 | |
parent | c970e613628ca47f47aa3336390a237a83c67d29 (diff) |
Now, all floats covering a line are considered for calculating the borders.
-rw-r--r-- | dw/outofflowmgr.cc | 63 | ||||
-rw-r--r-- | dw/outofflowmgr.hh | 11 | ||||
-rw-r--r-- | dw/textblock.cc | 25 | ||||
-rw-r--r-- | dw/textblock.hh | 7 | ||||
-rw-r--r-- | dw/textblock_linebreaking.cc | 8 |
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; |