Changeset 128416 in webkit
- Timestamp:
- Sep 13, 2012 12:51:00 AM (12 years ago)
- Location:
- trunk
- Files:
-
- 28 added
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r128414 r128416 1 2012-09-13 Raul Hudea <rhudea@adobe.com> 2 3 [CSSRegions][CSSOM] Implement Element.getRegionFlowRanges 4 https://bugs.webkit.org/show_bug.cgi?id=78493 5 6 Reviewed by David Hyatt. 7 8 Add tests for getRegionFlowRanges call. 9 10 * fast/regions/get-region-flow-ranges-absolute-pos-expected.txt: Added. 11 * fast/regions/get-region-flow-ranges-absolute-pos.html: Added. 12 * fast/regions/get-region-flow-ranges-content-nodes-expected.txt: Added. 13 * fast/regions/get-region-flow-ranges-content-nodes.html: Added. 14 * fast/regions/get-region-flow-ranges-display-none-expected.txt: Added. 15 * fast/regions/get-region-flow-ranges-display-none.html: Added. 16 * fast/regions/get-region-flow-ranges-empty-regions-expected.txt: Added. 17 * fast/regions/get-region-flow-ranges-empty-regions.html: Added. 18 * fast/regions/get-region-flow-ranges-expected.txt: Added. 19 * fast/regions/get-region-flow-ranges-fixed-pos-expected.txt: Added. 20 * fast/regions/get-region-flow-ranges-fixed-pos.html: Added. 21 * fast/regions/get-region-flow-ranges-horiz-bt-expected.txt: Added. 22 * fast/regions/get-region-flow-ranges-horiz-bt.html: Added. 23 * fast/regions/get-region-flow-ranges-inline-only-expected.txt: Added. 24 * fast/regions/get-region-flow-ranges-inline-only.html: Added. 25 * fast/regions/get-region-flow-ranges-text-expected.txt: Added. 26 * fast/regions/get-region-flow-ranges-text-vert-lr-expected.txt: Added. 27 * fast/regions/get-region-flow-ranges-text-vert-lr.html: Added. 28 * fast/regions/get-region-flow-ranges-text.html: Added. 29 * fast/regions/get-region-flow-ranges-vert-lr-expected.txt: Added. 30 * fast/regions/get-region-flow-ranges-vert-lr.html: Added. 31 * fast/regions/get-region-flow-ranges-vert-rl-expected.txt: Added. 32 * fast/regions/get-region-flow-ranges-vert-rl.html: Added. 33 * fast/regions/get-region-flow-ranges-writing-modes-rl-rb-lr-expected.txt: Added. 34 * fast/regions/get-region-flow-ranges-writing-modes-rl-rb-lr.html: Added. 35 * fast/regions/get-region-flow-ranges-writing-modes-tb-rl-lr-expected.txt: Added. 36 * fast/regions/get-region-flow-ranges-writing-modes-tb-rl-lr.html: Added. 37 * fast/regions/get-region-flow-ranges.html: Added. 38 * fast/regions/resources/helper.js: 39 (getName): 40 (getRangeAt): 41 (compareArrays): 42 1 43 2012-09-13 Zan Dobersek <zandobersek@gmail.com> 2 44 -
trunk/LayoutTests/fast/regions/resources/helper.js
r108103 r128416 161 161 expression ? logPassMessage("") : logFailMessage(failMessage); 162 162 } 163 164 // used by getRegionFlowRanges tests 165 function getName(node) { 166 if (!node) return "undefined"; 167 if (node.nodeType == 3) // Text node 168 return "#text"; 169 // all the others should have an id 170 return node.id; 171 } 172 173 function getRangeAt(arrRange, index) { 174 if (index < arrRange.length) 175 return [getName(arrRange[index].startContainer), arrRange[index].startOffset, getName(arrRange[index].endContainer), arrRange[index].endOffset]; 176 return null; 177 } 178 179 function compareArrays(current, expected) { 180 try { 181 if (current == null) { 182 testFailed("Null object. Expected [" + expected.toString() + "] was null"); 183 return; 184 } 185 if (current.length !== expected.length) { 186 testFailed("Array length differs. Expected [" + expected.toString() + "] was [" + current.toString() + "]"); 187 return; 188 } 189 for (var i = 0; i < current.length; i++) 190 if (current[i] !== expected[i]) { 191 testFailed("Expected [" + expected.toString() + "]. Was [" + current.toString() + "]"); 192 return; 193 } 194 } catch (ex) { 195 testFailed(current + " threw exception " + ex); 196 } 197 testPassed("Array [" + expected.toString() + "] is equal to [" + current.toString() + "]"); 198 } -
trunk/Source/WebCore/ChangeLog
r128411 r128416 1 2012-09-13 Raul Hudea <rhudea@adobe.com> 2 3 [CSSRegions][CSSOM] Implement Element.getRegionFlowRanges 4 https://bugs.webkit.org/show_bug.cgi?id=78493 5 6 Reviewed by David Hyatt. 7 8 Implement the getRegionFlowRanges function from the CSS Regions spec. It is implemented by iterating over 9 the content nodes and figuring out which nodes have boundingBox intersecting the region box and figuring out 10 the start and end positions. 11 12 Tests: fast/regions/get-region-flow-ranges-absolute-pos.html 13 fast/regions/get-region-flow-ranges-content-nodes.html 14 fast/regions/get-region-flow-ranges-display-none.html 15 fast/regions/get-region-flow-ranges-empty-regions.html 16 fast/regions/get-region-flow-ranges-fixed-pos.html 17 fast/regions/get-region-flow-ranges-horiz-bt.html 18 fast/regions/get-region-flow-ranges-inline-only.html 19 fast/regions/get-region-flow-ranges-text-vert-lr.html 20 fast/regions/get-region-flow-ranges-text.html 21 fast/regions/get-region-flow-ranges-vert-lr.html 22 fast/regions/get-region-flow-ranges-vert-rl.html 23 fast/regions/get-region-flow-ranges-writing-modes-rl-rb-lr.html 24 fast/regions/get-region-flow-ranges-writing-modes-tb-rl-lr.html 25 fast/regions/get-region-flow-ranges.html 26 27 * dom/Element.cpp: 28 (WebCore::Element::webkitGetRegionFlowRanges): 29 (WebCore): 30 * dom/Element.h: 31 * dom/Element.idl: added the webkitGetRegionFlowRanges method 32 * rendering/RenderBlock.cpp: 33 (WebCore::RenderBlock::computeStartPositionDeltaForChildAvoidingFloats): Use the logicalTopOfFlowThreadContentRect instead of offsetFromLogicalTopOfFirstPage (renamed) 34 (WebCore::RenderBlock::hasNextPage): Use the logicalTopOfFlowThreadContentRect instead of offsetFromLogicalTopOfFirstPage (renamed) 35 (WebCore::RenderBlock::offsetFromLogicalTopOfFirstPage): Added a slower path which works without LayoutState 36 (WebCore::RenderBlock::clampToStartAndEndRegions): Use the logicalTopOfFlowThreadContentRect instead of offsetFromLogicalTopOfFirstPage (renamed) 37 * rendering/RenderBox.cpp: 38 (WebCore::RenderBox::shrinkLogicalWidthToAvoidFloats): Use the logicalTopOfFlowThreadContentRect instead of offsetFromLogicalTopOfFirstPage (renamed) 39 (WebCore::RenderBox::containingBlockAvailableLineWidthInRegion): Use the logicalTopOfFlowThreadContentRect instead of offsetFromLogicalTopOfFirstPage (renamed) 40 (WebCore::computeInlineStaticDistance): Use the logicalTopOfFlowThreadContentRect instead of offsetFromLogicalTopOfFirstPage (renamed) 41 * rendering/RenderNamedFlowThread.cpp: 42 (WebCore::isContainedInNodes): 43 (WebCore): 44 (WebCore::boxIntersectsRegion): 45 (WebCore::RenderNamedFlowThread::getRanges): returns a vector of Ranges that contains Node that are part of a region 46 * rendering/RenderNamedFlowThread.h: 47 (RenderNamedFlowThread): 48 * rendering/RenderRegion.cpp: 49 (WebCore::RenderRegion::logicalTopOfFlowThreadContentRect): Returns the logical top of a rectangle inside the flow thread content 50 (WebCore): 51 (WebCore::RenderRegion::logicalBottomOfFlowThreadContentRect): Returns the logical bottom of a rectangle inside the flow thread content 52 (WebCore::RenderRegion::getRanges): proxy the getRanges call to its named flow thread 53 * rendering/RenderRegion.h: 54 (RenderRegion): 55 (WebCore::RenderRegion::logicalTopForFlowThreadContent): Renamed from offsetFromLogicalTopOfFirstPage 56 (WebCore::RenderRegion::logicalBottomForFlowThreadContent): Returns the logical bottom of the FlowThreadContent rect 57 1 58 2012-09-13 Adam Barth <abarth@webkit.org> 2 59 -
trunk/Source/WebCore/dom/Element.cpp
r128363 r128416 2063 2063 } 2064 2064 2065 #if ENABLE(CSS_REGIONS) 2066 2067 Vector<RefPtr<Range> > Element::webkitGetRegionFlowRanges() const 2068 { 2069 document()->updateLayoutIgnorePendingStylesheets(); 2070 2071 Vector<RefPtr<Range> > rangeObjects; 2072 if (document()->cssRegionsEnabled() && renderer() && renderer()->isRenderRegion()) { 2073 RenderRegion* region = toRenderRegion(renderer()); 2074 if (region->isValid()) 2075 region->getRanges(rangeObjects); 2076 } 2077 2078 return rangeObjects; 2079 } 2080 2081 #endif 2082 2065 2083 #ifndef NDEBUG 2066 2084 bool Element::fastAttributeLookupAllowed(const QualifiedName& name) const -
trunk/Source/WebCore/dom/Element.h
r127811 r128416 428 428 RenderRegion* renderRegion() const; 429 429 const AtomicString& webkitRegionOverset() const; 430 #if ENABLE(CSS_REGIONS) 431 Vector<RefPtr<Range> > webkitGetRegionFlowRanges() const; 432 #endif 430 433 431 434 bool hasID() const; -
trunk/Source/WebCore/dom/Element.idl
r126245 r128416 145 145 // CSS Regions API 146 146 readonly attribute DOMString webkitRegionOverset; 147 [Conditional=CSS_REGIONS] sequence<Range> webkitGetRegionFlowRanges(); 147 148 148 149 #if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C -
trunk/Source/WebCore/rendering/RenderBlock.cpp
r128201 r128416 2233 2233 LayoutUnit blockOffset = logicalTopForChild(child); 2234 2234 if (region) 2235 blockOffset = max(blockOffset, blockOffset + (region-> offsetFromLogicalTopOfFirstPage() - offsetFromLogicalTopOfFirstPage));2235 blockOffset = max(blockOffset, blockOffset + (region->logicalTopForFlowThreadContent() - offsetFromLogicalTopOfFirstPage)); 2236 2236 2237 2237 LayoutUnit startOff = startOffsetForLine(blockOffset, false, region, offsetFromLogicalTopOfFirstPage, logicalHeightForChild(child)); … … 6897 6897 if (region->isLastRegion()) 6898 6898 return region->isRenderRegionSet() || region->style()->regionOverflow() == BreakRegionOverflow 6899 || (pageBoundaryRule == IncludePageBoundary && pageOffset == region-> offsetFromLogicalTopOfFirstPage());6899 || (pageBoundaryRule == IncludePageBoundary && pageOffset == region->logicalTopForFlowThreadContent()); 6900 6900 return true; 6901 6901 } … … 7188 7188 LayoutUnit RenderBlock::offsetFromLogicalTopOfFirstPage() const 7189 7189 { 7190 // FIXME: This function needs to work without layout state. It's fine to use the layout state as a cache7191 // for speed, but we need a slow implementation that will walk up the containing block chain and figure7192 // out our offset from the top of the page.7193 7190 LayoutState* layoutState = view()->layoutState(); 7194 if (!layoutState || !layoutState->isPaginated()) 7195 return 0; 7196 7197 // FIXME: Sanity check that the renderer in the layout state is ours, since otherwise the computation will be off. 7198 // Right now this assert gets hit inside computeLogicalHeight for percentage margins, since they're computed using 7199 // widths which can vary in each region. Until we patch that, we can't have this assert. 7200 // ASSERT(layoutState->m_renderer == this); 7201 7202 LayoutSize offsetDelta = layoutState->m_layoutOffset - layoutState->m_pageOffset; 7203 return isHorizontalWritingMode() ? offsetDelta.height() : offsetDelta.width(); 7191 if (layoutState && !layoutState->isPaginated()) 7192 return ZERO_LAYOUT_UNIT; 7193 if (layoutState) { 7194 // FIXME: Sanity check that the renderer in the layout state is ours, since otherwise the computation will be off. 7195 // Right now this assert gets hit inside computeLogicalHeight for percentage margins, since they're computed using 7196 // widths which can vary in each region. Until we patch that, we can't have this assert. 7197 // ASSERT(layoutState->m_renderer == this); 7198 7199 LayoutSize offsetDelta = layoutState->m_layoutOffset - layoutState->m_pageOffset; 7200 return isHorizontalWritingMode() ? offsetDelta.height() : offsetDelta.width(); 7201 } 7202 // FIXME: Right now, this assert is hit outside layout, from logicalLeftSelectionOffset in selectionGapRectsForRepaint (called from FrameSelection::selectAll). 7203 // ASSERT(inRenderFlowThread()); 7204 7205 // FIXME: This is a slower path that doesn't use layout state and relies on getting your logical top inside the enclosing flow thread. It doesn't 7206 // work with columns or pages currently, but it should once they have been switched over to using flow threads. 7207 if (!inRenderFlowThread()) 7208 return ZERO_LAYOUT_UNIT; 7209 7210 const RenderBlock* currentBlock = this; 7211 LayoutRect blockRect(0, 0, width(), height()); 7212 7213 while (currentBlock && !currentBlock->isRenderFlowThread()) { 7214 RenderBlock* containerBlock = currentBlock->containingBlock(); 7215 ASSERT(containerBlock); 7216 if (!containerBlock) 7217 return ZERO_LAYOUT_UNIT; 7218 LayoutPoint currentBlockLocation = currentBlock->location(); 7219 7220 if (containerBlock->style()->writingMode() != currentBlock->style()->writingMode()) { 7221 // We have to put the block rect in container coordinates 7222 // and we have to take into account both the container and current block flipping modes 7223 if (containerBlock->style()->isFlippedBlocksWritingMode()) { 7224 if (containerBlock->isHorizontalWritingMode()) 7225 blockRect.setY(currentBlock->height() - blockRect.maxY()); 7226 else 7227 blockRect.setX(currentBlock->width() - blockRect.maxX()); 7228 } 7229 currentBlock->flipForWritingMode(blockRect); 7230 } 7231 blockRect.moveBy(currentBlockLocation); 7232 currentBlock = containerBlock; 7233 }; 7234 return currentBlock->isHorizontalWritingMode() ? blockRect.y() : blockRect.x(); 7204 7235 } 7205 7236 … … 7249 7280 enclosingRenderFlowThread()->getRegionRangeForBox(this, startRegion, endRegion); 7250 7281 7251 if (startRegion && region-> offsetFromLogicalTopOfFirstPage() < startRegion->offsetFromLogicalTopOfFirstPage())7282 if (startRegion && region->logicalTopForFlowThreadContent() < startRegion->logicalTopForFlowThreadContent()) 7252 7283 return startRegion; 7253 if (endRegion && region-> offsetFromLogicalTopOfFirstPage() > endRegion->offsetFromLogicalTopOfFirstPage())7284 if (endRegion && region->logicalTopForFlowThreadContent() > endRegion->logicalTopForFlowThreadContent()) 7254 7285 return endRegion; 7255 7286 -
trunk/Source/WebCore/rendering/RenderBox.cpp
r128375 r128416 1158 1158 LayoutUnit adjustedPageOffsetForContainingBlock = offsetFromLogicalTopOfFirstPage - logicalTop(); 1159 1159 if (region) { 1160 LayoutUnit offsetFromLogicalTopOfRegion = region ? region-> offsetFromLogicalTopOfFirstPage() - offsetFromLogicalTopOfFirstPage : ZERO_LAYOUT_UNIT;1160 LayoutUnit offsetFromLogicalTopOfRegion = region ? region->logicalTopForFlowThreadContent() - offsetFromLogicalTopOfFirstPage : ZERO_LAYOUT_UNIT; 1161 1161 logicalTopPosition = max(logicalTopPosition, logicalTopPosition + offsetFromLogicalTopOfRegion); 1162 1162 containingBlockRegion = cb->clampToStartAndEndRegions(region); … … 1220 1220 LayoutUnit adjustedPageOffsetForContainingBlock = offsetFromLogicalTopOfFirstPage - logicalTop(); 1221 1221 if (region) { 1222 LayoutUnit offsetFromLogicalTopOfRegion = region ? region-> offsetFromLogicalTopOfFirstPage() - offsetFromLogicalTopOfFirstPage : ZERO_LAYOUT_UNIT;1222 LayoutUnit offsetFromLogicalTopOfRegion = region ? region->logicalTopForFlowThreadContent() - offsetFromLogicalTopOfFirstPage : ZERO_LAYOUT_UNIT; 1223 1223 logicalTopPosition = max(logicalTopPosition, logicalTopPosition + offsetFromLogicalTopOfRegion); 1224 1224 containingBlockRegion = cb->clampToStartAndEndRegions(region); … … 2504 2504 const RenderBlock* cb = toRenderBlock(curr); 2505 2505 region = cb->clampToStartAndEndRegions(region); 2506 RenderBoxRegionInfo* boxInfo = cb->renderBoxRegionInfo(region, region-> offsetFromLogicalTopOfFirstPage());2506 RenderBoxRegionInfo* boxInfo = cb->renderBoxRegionInfo(region, region->logicalTopForFlowThreadContent()); 2507 2507 if (boxInfo) 2508 2508 staticPosition += boxInfo->logicalLeft(); … … 2523 2523 const RenderBlock* cb = toRenderBlock(curr); 2524 2524 region = cb->clampToStartAndEndRegions(region); 2525 RenderBoxRegionInfo* boxInfo = cb->renderBoxRegionInfo(region, region-> offsetFromLogicalTopOfFirstPage());2525 RenderBoxRegionInfo* boxInfo = cb->renderBoxRegionInfo(region, region->logicalTopForFlowThreadContent()); 2526 2526 if (boxInfo) { 2527 2527 if (curr != containerBlock) -
trunk/Source/WebCore/rendering/RenderNamedFlowThread.cpp
r128293 r128416 28 28 29 29 #include "FlowThreadController.h" 30 #include "InlineTextBox.h" 30 31 #include "InspectorInstrumentation.h" 32 #include "Position.h" 33 #include "RenderInline.h" 31 34 #include "RenderRegion.h" 35 #include "RenderText.h" 32 36 #include "RenderView.h" 37 #include "Text.h" 33 38 #include "WebKitNamedFlow.h" 34 39 … … 396 401 } 397 402 398 } 403 static bool isContainedInNodes(Vector<Node*> others, Node* node) 404 { 405 for (size_t i = 0; i < others.size(); i++) { 406 Node* other = others.at(i); 407 if (other->contains(node)) 408 return true; 409 } 410 return false; 411 } 412 413 static bool boxIntersectsRegion(LayoutUnit logicalTopForBox, LayoutUnit logicalBottomForBox, LayoutUnit logicalTopForRegion, LayoutUnit logicalBottomForRegion) 414 { 415 bool regionIsEmpty = logicalBottomForRegion != MAX_LAYOUT_UNIT && logicalTopForRegion != MIN_LAYOUT_UNIT 416 && (logicalBottomForRegion - logicalTopForRegion) <= 0; 417 return (logicalBottomForBox - logicalTopForBox) > 0 418 && !regionIsEmpty 419 && logicalTopForBox < logicalBottomForRegion && logicalTopForRegion < logicalBottomForBox; 420 } 421 422 void RenderNamedFlowThread::getRanges(Vector<RefPtr<Range> >& rangeObjects, const RenderRegion* region) const 423 { 424 LayoutUnit logicalTopForRegion; 425 LayoutUnit logicalBottomForRegion; 426 427 // extend the first region top to contain everything up to its logical height 428 if (region->isFirstRegion()) 429 logicalTopForRegion = MIN_LAYOUT_UNIT; 430 else 431 logicalTopForRegion = region->logicalTopForFlowThreadContent(); 432 433 // extend the last region to contain everything above its y() 434 if (region->isLastRegion()) 435 logicalBottomForRegion = MAX_LAYOUT_UNIT; 436 else 437 logicalBottomForRegion = region->logicalBottomForFlowThreadContent(); 438 439 Vector<Node*> nodes; 440 // eliminate the contentNodes that are descendants of other contentNodes 441 for (NamedFlowContentNodes::const_iterator it = contentNodes().begin(); it != contentNodes().end(); ++it) { 442 Node* node = *it; 443 if (!isContainedInNodes(nodes, node)) 444 nodes.append(node); 445 } 446 447 for (size_t i = 0; i < nodes.size(); i++) { 448 Node* contentNode = nodes.at(i); 449 if (!contentNode->renderer()) 450 continue; 451 452 ExceptionCode ignoredException; 453 RefPtr<Range> range = Range::create(contentNode->document()); 454 bool foundStartPosition = false; 455 bool startsAboveRegion = true; 456 bool endsBelowRegion = true; 457 bool skipOverOutsideNodes = false; 458 Node* lastEndNode = 0; 459 460 for (Node* node = contentNode; node; node = node->traverseNextNode(contentNode)) { 461 RenderObject* renderer = node->renderer(); 462 if (!renderer) 463 continue; 464 465 LayoutRect boundingBox; 466 if (renderer->isRenderInline()) 467 boundingBox = toRenderInline(renderer)->linesBoundingBox(); 468 else if (renderer->isText()) 469 boundingBox = toRenderText(renderer)->linesBoundingBox(); 470 else { 471 boundingBox = toRenderBox(renderer)->frameRect(); 472 if (toRenderBox(renderer)->isRelPositioned()) 473 boundingBox.move(toRenderBox(renderer)->relativePositionLogicalOffset()); 474 } 475 476 LayoutUnit offsetTop = renderer->containingBlock()->offsetFromLogicalTopOfFirstPage(); 477 const LayoutPoint logicalOffsetFromTop(isHorizontalWritingMode() ? ZERO_LAYOUT_UNIT : offsetTop, 478 isHorizontalWritingMode() ? offsetTop : ZERO_LAYOUT_UNIT); 479 480 boundingBox.moveBy(logicalOffsetFromTop); 481 482 LayoutUnit logicalTopForRenderer = region->logicalTopOfFlowThreadContentRect(boundingBox); 483 LayoutUnit logicalBottomForRenderer = region->logicalBottomOfFlowThreadContentRect(boundingBox); 484 485 // if the bounding box of the current element doesn't intersect the region box 486 // close the current range only if the start element began inside the region, 487 // otherwise just move the start position after this node and keep skipping them until we found a proper start position. 488 if (!boxIntersectsRegion(logicalTopForRenderer, logicalBottomForRenderer, logicalTopForRegion, logicalBottomForRegion)) { 489 if (foundStartPosition) { 490 if (!startsAboveRegion) { 491 if (range->intersectsNode(node, ignoredException)) 492 range->setEndBefore(node, ignoredException); 493 rangeObjects.append(range->cloneRange(ignoredException)); 494 range = Range::create(contentNode->document()); 495 startsAboveRegion = true; 496 } else 497 skipOverOutsideNodes = true; 498 } 499 if (skipOverOutsideNodes) 500 range->setStartAfter(node, ignoredException); 501 foundStartPosition = false; 502 continue; 503 } 504 505 // start position 506 if (logicalTopForRenderer < logicalTopForRegion && startsAboveRegion) { 507 if (renderer->isText()) { // Text crosses region top 508 // for Text elements, just find the last textbox that is contained inside the region and use its start() offset as start position 509 RenderText* textRenderer = toRenderText(renderer); 510 for (InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) { 511 if (offsetTop + box->logicalBottom() < logicalTopForRegion) 512 continue; 513 range->setStart(Position(toText(node), box->start())); 514 startsAboveRegion = false; 515 break; 516 } 517 } else { // node crosses region top 518 // for all elements, except Text, just set the start position to be before their children 519 startsAboveRegion = true; 520 range->setStart(Position(node, Position::PositionIsBeforeChildren)); 521 } 522 } else { // node starts inside region 523 // for elements that start inside the region, set the start position to be before them. If we found one, we will just skip the others until 524 // the range is closed. 525 if (startsAboveRegion) { 526 startsAboveRegion = false; 527 range->setStartBefore(node, ignoredException); 528 } 529 } 530 skipOverOutsideNodes = false; 531 foundStartPosition = true; 532 533 // end position 534 if (logicalBottomForRegion < logicalBottomForRenderer && (endsBelowRegion || (!endsBelowRegion && !node->isDescendantOf(lastEndNode)))) { 535 // for Text elements, just find just find the last textbox that is contained inside the region and use its start()+len() offset as end position 536 if (renderer->isText()) { // Text crosses region bottom 537 RenderText* textRenderer = toRenderText(renderer); 538 InlineTextBox* lastBox = 0; 539 for (InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) { 540 if ((offsetTop + box->logicalTop()) < logicalBottomForRegion) { 541 lastBox = box; 542 continue; 543 } 544 ASSERT(lastBox); 545 if (lastBox) 546 range->setEnd(Position(toText(node), lastBox->start() + lastBox->len())); 547 break; 548 } 549 endsBelowRegion = false; 550 lastEndNode = node; 551 } else { // node crosses region bottom 552 // for all elements, except Text, just set the start position to be after their children 553 range->setEnd(Position(node, Position::PositionIsAfterChildren)); 554 endsBelowRegion = true; 555 lastEndNode = node; 556 } 557 } else { // node ends inside region 558 // for elements that ends inside the region, set the end position to be after them 559 // allow this end position to be changed only by other elements that are not descendants of the current end node 560 if (endsBelowRegion || (!endsBelowRegion && !node->isDescendantOf(lastEndNode))) { 561 range->setEndAfter(node, ignoredException); 562 endsBelowRegion = false; 563 lastEndNode = node; 564 } 565 } 566 } 567 if (foundStartPosition || skipOverOutsideNodes) 568 rangeObjects.append(range); 569 } 570 } 571 572 } -
trunk/Source/WebCore/rendering/RenderNamedFlowThread.h
r127472 r128416 71 71 bool hasContentNode(Node* contentNode) const { ASSERT(contentNode); return m_contentNodes.contains(contentNode); } 72 72 bool isMarkedForDestruction() const; 73 void getRanges(Vector<RefPtr<Range> >&, const RenderRegion*) const; 73 74 74 75 protected: -
trunk/Source/WebCore/rendering/RenderRegion.cpp
r128155 r128416 36 36 #include "IntRect.h" 37 37 #include "PaintInfo.h" 38 #include "Range.h" 38 39 #include "RenderBoxRegionInfo.h" 39 40 #include "RenderNamedFlowThread.h" … … 329 330 } 330 331 331 LayoutUnit RenderRegion::offsetFromLogicalTopOfFirstPage() const 332 { 333 if (!m_isValid || !m_flowThread) 334 return 0; 335 if (m_flowThread->isHorizontalWritingMode()) 336 return flowThreadPortionRect().y(); 337 return flowThreadPortionRect().x(); 332 LayoutUnit RenderRegion::logicalTopOfFlowThreadContentRect(const LayoutRect& rect) const 333 { 334 if (!m_isValid || !flowThread()) 335 return ZERO_LAYOUT_UNIT; 336 return flowThread()->isHorizontalWritingMode() ? rect.y() : rect.x(); 337 } 338 339 LayoutUnit RenderRegion::logicalBottomOfFlowThreadContentRect(const LayoutRect& rect) const 340 { 341 if (!m_isValid || !flowThread()) 342 return ZERO_LAYOUT_UNIT; 343 return flowThread()->isHorizontalWritingMode() ? rect.maxY() : rect.maxX(); 338 344 } 339 345 … … 537 543 } 538 544 545 void RenderRegion::getRanges(Vector<RefPtr<Range> >& rangeObjects) const 546 { 547 RenderNamedFlowThread* namedFlow = view()->flowThreadController()->ensureRenderFlowThreadWithName(style()->regionThread()); 548 namedFlow->getRanges(rangeObjects, this); 549 } 550 539 551 } // namespace WebCore -
trunk/Source/WebCore/rendering/RenderRegion.h
r128155 r128416 79 79 void deleteAllRenderBoxRegionInfo(); 80 80 81 LayoutUnit offsetFromLogicalTopOfFirstPage() const;82 83 81 bool isFirstRegion() const; 84 82 bool isLastRegion() const; … … 105 103 virtual LayoutUnit maxPreferredLogicalWidth() const OVERRIDE; 106 104 105 LayoutUnit logicalTopOfFlowThreadContentRect(const LayoutRect&) const; 106 LayoutUnit logicalBottomOfFlowThreadContentRect(const LayoutRect&) const; 107 LayoutUnit logicalTopForFlowThreadContent() const { return logicalTopOfFlowThreadContentRect(flowThreadPortionRect()); }; 108 LayoutUnit logicalBottomForFlowThreadContent() const { return logicalBottomOfFlowThreadContentRect(flowThreadPortionRect()); }; 109 110 void getRanges(Vector<RefPtr<Range> >&) const; 111 107 112 // This method represents the logical height of the entire flow thread portion used by the region or set. 108 113 // For RenderRegions it matches logicalPaginationHeight(), but for sets it is the height of all the pages
Note: See TracChangeset
for help on using the changeset viewer.