void LineBoxListPainter::paint(const LayoutBoxModelObject& layoutObject, const PaintInfo& paintInfo, const LayoutPoint& paintOffset) const { ASSERT(!shouldPaintSelfOutline(paintInfo.phase) && !shouldPaintDescendantOutlines(paintInfo.phase)); // Only paint during the foreground/selection phases. if (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection && paintInfo.phase != PaintPhaseTextClip && paintInfo.phase != PaintPhaseMask) return; ASSERT(layoutObject.isLayoutBlock() || (layoutObject.isLayoutInline() && layoutObject.hasLayer())); // The only way an inline could paint like this is if it has a layer. if (paintInfo.phase == PaintPhaseForeground && paintInfo.isPrinting()) addPDFURLRectsForInlineChildrenRecursively(layoutObject, paintInfo, paintOffset); // If we have no lines then we have no work to do. if (!m_lineBoxList.firstLineBox()) return; if (!m_lineBoxList.anyLineIntersectsRect(LineLayoutBoxModel(const_cast<LayoutBoxModelObject*>(&layoutObject)), paintInfo.cullRect(), paintOffset)) return; PaintInfo info(paintInfo); // See if our root lines intersect with the dirty rect. If so, then we paint // them. Note that boxes can easily overlap, so we can't make any assumptions // based off positions of our first line box or our last line box. for (InlineFlowBox* curr = m_lineBoxList.firstLineBox(); curr; curr = curr->nextLineBox()) { if (m_lineBoxList.lineIntersectsDirtyRect(LineLayoutBoxModel(const_cast<LayoutBoxModelObject*>(&layoutObject)), curr, info.cullRect(), paintOffset)) { RootInlineBox& root = curr->root(); curr->paint(info, paintOffset, root.lineTop(), root.lineBottom()); } } }
FloatRect RenderSVGText::relativeBBox(bool includeStroke) const { FloatRect repaintRect; for (InlineRunBox* runBox = firstLineBox(); runBox; runBox = runBox->nextLineBox()) { ASSERT(runBox->isInlineFlowBox()); InlineFlowBox* flowBox = static_cast<InlineFlowBox*>(runBox); for (InlineBox* box = flowBox->firstChild(); box; box = box->nextOnLine()) repaintRect.unite(FloatRect(box->xPos(), box->yPos(), box->width(), box->height())); } // SVG needs to include the strokeWidth(), not the textStrokeWidth(). if (includeStroke && style()->svgStyle()->hasStroke()) { float strokeWidth = SVGRenderStyle::cssPrimitiveToLength(this, style()->svgStyle()->strokeWidth(), 0.0f); #if ENABLE(SVG_FONTS) const Font& font = style()->font(); if (font.primaryFont()->isSVGFont()) { float scale = font.unitsPerEm() > 0 ? font.size() / font.unitsPerEm() : 0.0f; if (scale != 0.0f) strokeWidth /= scale; } #endif repaintRect.inflate(strokeWidth); } repaintRect.move(xPos(), yPos()); return repaintRect; }
bool LineBoxList::hitTest(LayoutBoxModelObject* renderer, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction) const { if (hitTestAction != HitTestForeground) return false; ASSERT(renderer->isLayoutBlock() || (renderer->isLayoutInline() && renderer->hasLayer())); // The only way an inline could hit test like this is if it has a layer. // If we have no lines then we have no work to do. if (!firstLineBox()) return false; LayoutPoint point = locationInContainer.point(); LayoutRect rect(firstLineBox()->isHorizontal() ? IntRect(point.x(), point.y() - locationInContainer.topPadding(), 1, locationInContainer.topPadding() + locationInContainer.bottomPadding() + 1) : IntRect(point.x() - locationInContainer.leftPadding(), point.y(), locationInContainer.rightPadding() + locationInContainer.leftPadding() + 1, 1)); if (!anyLineIntersectsRect(renderer, rect, accumulatedOffset)) return false; // See if our root lines contain the point. If so, then we hit test // them further. Note that boxes can easily overlap, so we can't make any assumptions // based off positions of our first line box or our last line box. for (InlineFlowBox* curr = lastLineBox(); curr; curr = curr->prevLineBox()) { RootInlineBox& root = curr->root(); if (rangeIntersectsRect(renderer, curr->logicalTopVisualOverflow(root.lineTop()), curr->logicalBottomVisualOverflow(root.lineBottom()), rect, accumulatedOffset)) { bool inside = curr->nodeAtPoint(result, locationInContainer, accumulatedOffset, root.lineTop(), root.lineBottom()); if (inside) { renderer->updateHitTestResult(result, locationInContainer.point() - toLayoutSize(accumulatedOffset)); return true; } } } return false; }
bool RenderLineBoxList::hitTest(RenderBoxModelObject* renderer, const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction) const { if (hitTestAction != HitTestForeground) return false; ASSERT(renderer->isRenderBlock() || (renderer->isRenderInline() && renderer->hasLayer())); // The only way an inline could hit test like this is if it has a layer. // If we have no lines then we have no work to do. if (!firstLineBox()) return false; // We can check the first box and last box and avoid hit testing if we don't // contain the point. This is a quick short-circuit that we can take to avoid walking any lines. // FIXME: This check is flawed in the following extremely obscure way: // if some line in the middle has a huge overflow, it might actually extend below the last line. if ((y >= ty + lastLineBox()->root()->bottomVisibleOverflow()) || (y < ty + firstLineBox()->root()->topVisibleOverflow())) return false; // See if our root lines contain the point. If so, then we hit test // them further. Note that boxes can easily overlap, so we can't make any assumptions // based off positions of our first line box or our last line box. for (InlineFlowBox* curr = lastLineBox(); curr; curr = curr->prevLineBox()) { if (y >= ty + curr->root()->topVisibleOverflow() && y < ty + curr->root()->bottomVisibleOverflow()) { bool inside = curr->nodeAtPoint(request, result, x, y, tx, ty); if (inside) { renderer->updateHitTestResult(result, IntPoint(x - tx, y - ty)); return true; } } } return false; }
bool RenderFlow::hitTestLines(NodeInfo& i, int x, int y, int tx, int ty, HitTestAction hitTestAction) { (void) hitTestAction; /* if (hitTestAction != HitTestForeground) // ### port hitTest return false; */ if (!firstLineBox()) return false; // We can check the first box and last box and avoid hit testing if we don't // contain the point. This is a quick short-circuit that we can take to avoid walking any lines. // FIXME: This check is flawed in two extremely obscure ways. // (1) If some line in the middle has a huge overflow, it might actually extend below the last line. // (2) The overflow from an inline block on a line is not reported to the line. if ((y >= ty + lastLineBox()->root()->bottomOverflow()) || (y < ty + firstLineBox()->root()->topOverflow())) return false; // See if our root lines contain the point. If so, then we hit test // them further. Note that boxes can easily overlap, so we can't make any assumptions // based off positions of our first line box or our last line box. for (InlineFlowBox* curr = lastLineBox(); curr; curr = curr->prevFlowBox()) { if (y >= ty + curr->root()->topOverflow() && y < ty + curr->root()->bottomOverflow()) { bool inside = curr->nodeAtPoint(i, x, y, tx, ty); if (inside) { setInnerNode(i); return true; } } } return false; }
void LineBoxListPainter::paint(LayoutBoxModelObject* layoutObject, const PaintInfo& paintInfo, const LayoutPoint& paintOffset) const { ASSERT(paintInfo.phase != PaintPhaseOutline && paintInfo.phase != PaintPhaseSelfOutline && paintInfo.phase != PaintPhaseChildOutlines); // Only paint during the foreground/selection phases. if (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection && paintInfo.phase != PaintPhaseTextClip && paintInfo.phase != PaintPhaseMask) return; ASSERT(layoutObject->isLayoutBlock() || (layoutObject->isLayoutInline() && layoutObject->hasLayer())); // The only way an inline could paint like this is if it has a layer. // FIXME: When Skia supports annotation rect covering (https://code.google.com/p/skia/issues/detail?id=3872), // these rects may be covered line box drawings. Then we may need a dedicated paint phase. if (paintInfo.phase == PaintPhaseForeground && paintInfo.isPrinting()) addPDFURLRectsForInlineChildrenRecursively(layoutObject, paintInfo, paintOffset); // If we have no lines then we have no work to do. if (!m_lineBoxList.firstLineBox()) return; if (!m_lineBoxList.anyLineIntersectsRect(LineLayoutBoxModel(layoutObject), LayoutRect(paintInfo.rect), paintOffset)) return; PaintInfo info(paintInfo); // See if our root lines intersect with the dirty rect. If so, then we paint // them. Note that boxes can easily overlap, so we can't make any assumptions // based off positions of our first line box or our last line box. for (InlineFlowBox* curr = m_lineBoxList.firstLineBox(); curr; curr = curr->nextLineBox()) { if (m_lineBoxList.lineIntersectsDirtyRect(LineLayoutBoxModel(layoutObject), curr, info, paintOffset)) { RootInlineBox& root = curr->root(); curr->paint(info, paintOffset, root.lineTop(), root.lineBottom()); } } }
/** * Traverses the horizontal inline boxes and appends the point coordinates to * the given array. * @param box inline box * @param pointArray array collecting coordinates * @param bottom \c true, collect bottom coordinates, \c false, collect top * coordinates. * @param limit lower limit that an y-coordinate must at least reach. Note * that limit designates the highest y-coordinate for \c bottom, and * the lowest for !\c bottom. */ static void collectHorizontalBoxCoordinates(InlineBox *box, QValueVector< QPoint > &pointArray, bool bottom, int offset, int limit = -500000) { // kdDebug(6000) << "collectHorizontalBoxCoordinates: " << endl; offset = bottom ? offset : -offset; int y = box->yPos() + bottom * box->height() + offset; if(limit != -500000 && (bottom ? y < limit : y > limit)) y = limit; int x = box->xPos() + bottom * box->width() + offset; QPoint newPnt(x, y); // Add intersection point if point-array not empty. if(!pointArray.isEmpty()) { QPoint lastPnt = pointArray.back(); QPoint insPnt(newPnt.x(), lastPnt.y()); if(offset && ((bottom && lastPnt.y() > y) || (!bottom && lastPnt.y() < y))) { insPnt.rx() = lastPnt.x(); insPnt.ry() = y; } // kdDebug(6040) << "left: " << lastPnt << " == " << insPnt << ": " << (insPnt == lastPnt) << endl; appendPoint(pointArray, insPnt); } // Insert starting point of box appendPoint(pointArray, newPnt); newPnt.rx() += (bottom ? -box->width() : box->width()) - 2 * offset; if(box->isInlineFlowBox()) { InlineFlowBox *flowBox = static_cast< InlineFlowBox * >(box); for(InlineBox *b = bottom ? flowBox->lastChild() : flowBox->firstChild(); b; b = bottom ? b->prevOnLine() : b->nextOnLine()) { // Don't let boxes smaller than this flow box' height influence // the vertical position of the outline if they have a different // x-coordinate int l2; if(b->xPos() != box->xPos() && b->xPos() + b->width() != box->xPos() + box->width()) l2 = y; else l2 = limit; collectHorizontalBoxCoordinates(b, pointArray, bottom, kAbs(offset), l2); } // Add intersection point if flow box contained any children if(flowBox->firstChild()) { QPoint lastPnt = pointArray.back(); QPoint insPnt(lastPnt.x(), newPnt.y()); // kdDebug(6040) << "right: " << lastPnt << " == " << insPnt << ": " << (insPnt == lastPnt) << endl; appendPoint(pointArray, insPnt); } } // Insert ending point of box appendPoint(pointArray, newPnt); // kdDebug(6000) << "collectHorizontalBoxCoordinates: " << "ende" << endl; }
void InlineFlowBox::determineSpacingForFlowBoxes(bool lastLine, RenderObject* endObject) { // All boxes start off open. They will not apply any margins/border/padding on // any side. bool includeLeftEdge = false; bool includeRightEdge = false; RenderFlow* flow = static_cast<RenderFlow*>(object()); if (!flow->firstChild()) includeLeftEdge = includeRightEdge = true; // Empty inlines never split across lines. else if (parent()) { // The root inline box never has borders/margins/padding. bool ltr = flow->style()->direction() == LTR; // Check to see if all initial lines are unconstructed. If so, then // we know the inline began on this line. if (!flow->firstLineBox()->isConstructed()) { if (ltr && flow->firstLineBox() == this) includeLeftEdge = true; else if (!ltr && flow->lastLineBox() == this) includeRightEdge = true; } // In order to determine if the inline ends on this line, we check three things: // (1) If we are the last line and we don't have a continuation(), then we can // close up. // (2) If the last line box for the flow has an object following it on the line (ltr, // reverse for rtl), then the inline has closed. // (3) The line may end on the inline. If we are the last child (climbing up // the end object's chain), then we just closed as well. if (!flow->lastLineBox()->isConstructed()) { if (ltr) { if (!nextLineBox() && ((lastLine && !object()->continuation()) || nextOnLineExists() || onEndChain(endObject))) includeRightEdge = true; } else { if ((!prevLineBox() || !prevLineBox()->isConstructed()) && ((lastLine && !object()->continuation()) || prevOnLineExists() || onEndChain(endObject))) includeLeftEdge = true; } } } setEdges(includeLeftEdge, includeRightEdge); // Recur into our children. for (InlineBox* currChild = firstChild(); currChild; currChild = currChild->nextOnLine()) { if (currChild->isInlineFlowBox()) { InlineFlowBox* currFlow = static_cast<InlineFlowBox*>(currChild); currFlow->determineSpacingForFlowBoxes(lastLine, endObject); } } }
void RenderSVGInline::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const { auto* textAncestor = RenderSVGText::locateRenderSVGTextAncestor(*this); if (!textAncestor) return; FloatRect textBoundingBox = textAncestor->strokeBoundingBox(); for (InlineFlowBox* box = firstLineBox(); box; box = box->nextLineBox()) quads.append(localToAbsoluteQuad(FloatRect(textBoundingBox.x() + box->x(), textBoundingBox.y() + box->y(), box->logicalWidth(), box->logicalHeight()), UseTransforms, wasFixed)); }
void RenderSVGInline::absoluteQuads(Vector<FloatQuad>& quads) { const RenderObject* object = SVGRenderSupport::findTextRootObject(this); if (!object) return; FloatRect textBoundingBox = object->strokeBoundingBox(); for (InlineFlowBox* box = firstLineBox(); box; box = box->nextLineBox()) quads.append(localToAbsoluteQuad(FloatRect(textBoundingBox.x() + box->x(), textBoundingBox.y() + box->y(), box->width(), box->height()))); }
void RenderSVGInline::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) { RenderObject* object = RenderSVGText::locateRenderSVGTextAncestor(this); if (!object) return; FloatRect textBoundingBox = object->strokeBoundingBox(); for (InlineFlowBox* box = firstLineBox(); box; box = box->nextLineBox()) quads.append(localToAbsoluteQuad(FloatRect(textBoundingBox.x() + box->x(), textBoundingBox.y() + box->y(), box->logicalWidth(), box->logicalHeight()), false, wasFixed)); }
void RenderLineBoxList::deleteLineBoxTree(RenderArena* arena) { InlineFlowBox* line = m_firstLineBox; InlineFlowBox* nextLine; while (line) { nextLine = line->nextLineBox(); line->deleteLine(arena); line = nextLine; } m_firstLineBox = m_lastLineBox = 0; }
void LineBoxList::deleteLineBoxTree() { InlineFlowBox* line = m_firstLineBox; InlineFlowBox* nextLine; while (line) { nextLine = line->nextLineBox(); line->deleteLine(); line = nextLine; } m_firstLineBox = m_lastLineBox = 0; }
void RenderLineBoxList::deleteLineBoxes() { if (m_firstLineBox) { InlineFlowBox* next; for (InlineFlowBox* curr = m_firstLineBox; curr; curr = next) { next = curr->nextLineBox(); delete curr; } m_firstLineBox = nullptr; m_lastLineBox = nullptr; } }
void RenderLineBoxList::deleteLineBoxes(RenderArena* arena) { if (m_firstLineBox) { InlineFlowBox* next; for (InlineFlowBox* curr = m_firstLineBox; curr; curr = next) { next = curr->nextLineBox(); curr->destroy(arena); } m_firstLineBox = 0; m_lastLineBox = 0; } }
FloatRect RenderSVGText::objectBoundingBox() const { FloatRect boundingBox; for (InlineFlowBox* flow = firstLineBox(); flow; flow = flow->nextLineBox()) { for (InlineBox* box = flow->firstChild(); box; box = box->nextOnLine()) boundingBox.unite(FloatRect(box->x(), box->y(), box->width(), box->height())); } boundingBox.move(x(), y()); return boundingBox; }
void LineBoxList::deleteLineBoxes() { if (m_firstLineBox) { InlineFlowBox* next; for (InlineFlowBox* curr = m_firstLineBox; curr; curr = next) { next = curr->nextLineBox(); curr->destroy(); } m_firstLineBox = 0; m_lastLineBox = 0; } }
void RenderTextTrackCue::repositionGenericCue() { ASSERT(firstChild()); InlineFlowBox* firstLineBox = toRenderInline(firstChild())->firstLineBox(); if (static_cast<TextTrackCueGeneric*>(m_cue)->useDefaultPosition() && firstLineBox) { LayoutUnit parentWidth = containingBlock()->logicalWidth(); LayoutUnit width = firstLineBox->width(); LayoutUnit right = (parentWidth / 2) - (width / 2); setX(right); } repositionCueSnapToLinesNotSet(); }
InlineBox* RenderSVGText::createInlineBox(bool makePlaceHolderBox, bool isRootLineBox, bool isOnlyRun) { ASSERT(!isInlineFlow()); InlineFlowBox* flowBox = new (renderArena()) SVGRootInlineBox(this); if (!m_firstLineBox) m_firstLineBox = m_lastLineBox = flowBox; else { m_lastLineBox->setNextLineBox(flowBox); flowBox->setPreviousLineBox(m_lastLineBox); m_lastLineBox = flowBox; } return flowBox; }
void LineBoxList::extractLineBox(InlineFlowBox* box) { checkConsistency(); m_lastLineBox = box->prevLineBox(); if (box == m_firstLineBox) m_firstLineBox = 0; if (box->prevLineBox()) box->prevLineBox()->setNextLineBox(0); box->setPreviousLineBox(0); for (InlineFlowBox* curr = box; curr; curr = curr->nextLineBox()) curr->setExtracted(); checkConsistency(); }
void RenderFlow::attachLineBox(InlineFlowBox* box) { if (m_lastLineBox) { m_lastLineBox->setNextLineBox(box); box->setPreviousLineBox(m_lastLineBox); } else m_firstLineBox = box; InlineFlowBox* last = box; for (InlineFlowBox* curr = box; curr; curr = curr->nextFlowBox()) { curr->setExtracted(false); last = curr; } m_lastLineBox = last; }
FloatRect RenderSVGText::objectBoundingBox() const { FloatRect boundingBox; for (InlineRunBox* runBox = firstLineBox(); runBox; runBox = runBox->nextLineBox()) { ASSERT(runBox->isInlineFlowBox()); InlineFlowBox* flowBox = static_cast<InlineFlowBox*>(runBox); for (InlineBox* box = flowBox->firstChild(); box; box = box->nextOnLine()) boundingBox.unite(FloatRect(box->x(), box->y(), box->width(), box->height())); } boundingBox.move(x(), y()); return boundingBox; }
int InlineFlowBox::placeBoxesHorizontally(int x) { // Set our x position. setXPos(x); int startX = x; x += borderLeft() + paddingLeft(); for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) { if (curr->object()->isText()) { InlineTextBox* text = static_cast<InlineTextBox*>(curr); text->setXPos(x); x += curr->width(); } else { if (curr->object()->isPositioned()) { if (curr->object()->parent()->style()->direction() == LTR) curr->setXPos(x); else { // Our offset that we cache needs to be from the edge of the right border box and // not the left border box. We have to subtract |x| from the width of the block // (which can be obtained by walking up to the root line box). InlineBox* root = this; while (!root->isRootInlineBox()) root = root->parent(); curr->setXPos(root->object()->width()-x); } continue; // The positioned object has no effect on the width. } if (curr->object()->isInlineFlow()) { InlineFlowBox* flow = static_cast<InlineFlowBox*>(curr); x += flow->marginLeft(); x = flow->placeBoxesHorizontally(x); x += flow->marginRight(); } else { x += curr->object()->marginLeft(); curr->setXPos(x); x += curr->width() + curr->object()->marginRight(); } } } x += borderRight() + paddingRight(); setWidth(x-startX); return x; }
void RenderListItem::positionListMarker() { if (m_marker && m_marker->parent()->isBox() && !m_marker->isInside() && m_marker->inlineBoxWrapper()) { int markerOldX = m_marker->x(); int yOffset = 0; int xOffset = 0; for (RenderBox* o = m_marker->parentBox(); o != this; o = o->parentBox()) { yOffset += o->y(); xOffset += o->x(); } bool adjustOverflow = false; int markerXPos; RootInlineBox* root = m_marker->inlineBoxWrapper()->root(); // FIXME: Inline flows in the line box hierarchy that have self-painting layers should act as cutoff points // and really shouldn't keep propagating overflow up. This won't really break anything other than repainting // not being as tight as it could be though. if (style()->isLeftToRightDirection()) { int leftLineOffset = logicalLeftOffsetForLine(yOffset, logicalLeftOffsetForLine(yOffset, false), false); markerXPos = leftLineOffset - xOffset - paddingLeft() - borderLeft() + m_marker->marginLeft(); m_marker->inlineBoxWrapper()->adjustPosition(markerXPos - markerOldX, 0); for (InlineFlowBox* box = m_marker->inlineBoxWrapper()->parent(); box; box = box->parent()) { if (markerXPos < box->leftLayoutOverflow()) { box->setInlineDirectionOverflowPositions(markerXPos, box->rightLayoutOverflow(), box->leftVisualOverflow(), box->rightVisualOverflow()); if (box == root) adjustOverflow = true; } } } else { int rightLineOffset = logicalRightOffsetForLine(yOffset, logicalRightOffsetForLine(yOffset, false), false); markerXPos = rightLineOffset - xOffset + paddingRight() + borderRight() + m_marker->marginLeft(); m_marker->inlineBoxWrapper()->adjustPosition(markerXPos - markerOldX, 0); for (InlineFlowBox* box = m_marker->inlineBoxWrapper()->parent(); box; box = box->parent()) { if (markerXPos + m_marker->width() > box->rightLayoutOverflow()) { box->setInlineDirectionOverflowPositions(box->leftLayoutOverflow(), markerXPos + m_marker->width(), box->leftVisualOverflow(), box->rightVisualOverflow()); if (box == root) adjustOverflow = true; } } } if (adjustOverflow) { IntRect markerRect(markerXPos + xOffset, yOffset, m_marker->width(), m_marker->height()); RenderBox* o = m_marker; do { o = o->parentBox(); if (o->isRenderBlock()) { toRenderBlock(o)->addAbsoluteLayoutOverflow(markerRect); toRenderBlock(o)->addLayoutOverflow(markerRect); } markerRect.move(-o->x(), -o->y()); } while (o != this && !o->hasSelfPaintingLayer()); } } }
void RenderLineBoxList::appendLineBox(std::unique_ptr<InlineFlowBox> box) { checkConsistency(); InlineFlowBox* boxPtr = box.release(); if (!m_firstLineBox) { m_firstLineBox = boxPtr; m_lastLineBox = boxPtr; } else { m_lastLineBox->setNextLineBox(boxPtr); boxPtr->setPreviousLineBox(m_lastLineBox); m_lastLineBox = boxPtr; } checkConsistency(); }
void RenderSVGText::absoluteQuads(Vector<FloatQuad>& quads) { RenderSVGRoot* root = findSVGRootObject(parent()); if (!root) return; // Don't use objectBoundingBox here, as it's unites the selection rects. Makes it hard // to spot errors, if there are any using WebInspector. Individually feed them into 'rects'. for (InlineFlowBox* flow = firstLineBox(); flow; flow = flow->nextLineBox()) { for (InlineBox* box = flow->firstChild(); box; box = box->nextOnLine()) { FloatRect boxRect(box->x(), box->y(), box->width(), box->height()); // FIXME: crawling up the parent chain to map each quad is very inefficient // we should compute the absoluteTransform outside this loop first. quads.append(localToAbsoluteQuad(boxRect)); } } }
void RenderTextTrackCue::repositionGenericCue() { TextTrackCueGeneric* cue = static_cast<TextTrackCueGeneric*>(m_cue); if (!cue->useDefaultPosition()) return; ASSERT(firstChild()); InlineFlowBox* firstLineBox = toRenderInline(firstChild())->firstLineBox(); if (!firstLineBox) return; LayoutUnit parentWidth = containingBlock()->logicalWidth(); LayoutUnit width = firstLineBox->width(); LayoutUnit right = (parentWidth / 2) - (width / 2); setX(right); }
void RenderLineBoxList::attachLineBox(InlineFlowBox* box) { checkConsistency(); if (m_lastLineBox) { m_lastLineBox->setNextLineBox(box); box->setPreviousLineBox(m_lastLineBox); } else m_firstLineBox = box; InlineFlowBox* last = box; for (InlineFlowBox* curr = box; curr; curr = curr->nextLineBox()) { curr->setExtracted(false); last = curr; } m_lastLineBox = last; checkConsistency(); }
FloatRect RenderSVGText::relativeBBox(bool includeStroke) const { FloatRect repaintRect; for (InlineRunBox* runBox = firstLineBox(); runBox; runBox = runBox->nextLineBox()) { ASSERT(runBox->isInlineFlowBox()); InlineFlowBox* flowBox = static_cast<InlineFlowBox*>(runBox); for (InlineBox* box = flowBox->firstChild(); box; box = box->nextOnLine()) repaintRect.unite(FloatRect(box->xPos(), box->yPos(), box->width(), box->height())); } // SVG needs to include the strokeWidth(), not the textStrokeWidth(). if (includeStroke && style()->svgStyle()->hasStroke()) repaintRect.inflate(narrowPrecisionToFloat(KSVGPainterFactory::cssPrimitiveToLength(this, style()->svgStyle()->strokeWidth(), 0.0))); repaintRect.move(xPos(), yPos()); return repaintRect; }
void RenderSVGText::absoluteRects(Vector<IntRect>& rects, int, int) { RenderSVGRoot* root = findSVGRootObject(parent()); if (!root) return; // Don't use objectBoundingBox here, as it's unites the selection rects. Makes it hard // to spot errors, if there are any using WebInspector. Individually feed them into 'rects'. for (InlineRunBox* runBox = firstLineBox(); runBox; runBox = runBox->nextLineBox()) { ASSERT(runBox->isInlineFlowBox()); InlineFlowBox* flowBox = static_cast<InlineFlowBox*>(runBox); for (InlineBox* box = flowBox->firstChild(); box; box = box->nextOnLine()) { FloatRect boxRect(box->x(), box->y(), box->width(), box->height()); // FIXME: crawling up the parent chain to map each rect is very inefficient // we should compute the absoluteTransform outside this loop first. rects.append(enclosingIntRect(localToAbsoluteQuad(boxRect).boundingBox())); } } }