本文整理汇总了C++中RenderInline类的典型用法代码示例。如果您正苦于以下问题:C++ RenderInline类的具体用法?C++ RenderInline怎么用?C++ RenderInline使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了RenderInline类的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: new
RenderInline* RenderInline::cloneInline(RenderFlow* src)
{
RenderInline* o = new (src->renderArena()) RenderInline(src->element());
o->m_isContinuation = true;
o->setStyle(src->style());
return o;
}
示例2: mutableRectBasedTestResult
bool HitTestResult::addNodeToRectBasedTestResult(Node* node, const HitTestRequest& request, const HitTestLocation& locationInContainer, const FloatRect& rect)
{
// If it is not a rect-based hit test, this method has to be no-op.
// Return false, so the hit test stops.
if (!isRectBasedTest())
return false;
// If node is null, return true so the hit test can continue.
if (!node)
return true;
if (!request.allowsShadowContent())
node = node->shadowAncestorNode();
mutableRectBasedTestResult().add(node);
bool regionFilled = rect.contains(locationInContainer.boundingBox());
// FIXME: This code (incorrectly) attempts to correct for culled inline nodes. See https://bugs.webkit.org/show_bug.cgi?id=85849.
if (node->renderer()->isInline() && !regionFilled) {
for (RenderObject* curr = node->renderer()->parent(); curr; curr = curr->parent()) {
if (!curr->isRenderInline())
break;
// We need to make sure the nodes for culled inlines get included.
RenderInline* currInline = toRenderInline(curr);
if (currInline->alwaysCreateLineBoxes())
break;
if (currInline->visibleToHitTesting() && currInline->node())
mutableRectBasedTestResult().add(currInline->node()->shadowAncestorNode());
}
}
return !regionFilled;
}
示例3: mutableRectBasedTestResult
bool HitTestResult::addNodeToRectBasedTestResult(Node* node, const LayoutPoint& pointInContainer, const FloatRect& rect)
{
// If it is not a rect-based hit test, this method has to be no-op.
// Return false, so the hit test stops.
if (!isRectBasedTest())
return false;
// If node is null, return true so the hit test can continue.
if (!node)
return true;
if (m_shadowContentFilterPolicy == DoNotAllowShadowContent)
node = node->shadowAncestorNode();
mutableRectBasedTestResult().add(node);
if (node->renderer()->isInline()) {
for (RenderObject* curr = node->renderer()->parent(); curr; curr = curr->parent()) {
if (!curr->isRenderInline())
break;
// We need to make sure the nodes for culled inlines get included.
RenderInline* currInline = toRenderInline(curr);
if (currInline->alwaysCreateLineBoxes())
break;
if (currInline->visibleToHitTesting() && currInline->node())
mutableRectBasedTestResult().add(currInline->node()->shadowAncestorNode());
}
}
return !rect.contains(rectForPoint(pointInContainer));
}
示例4: flowBoxForRenderer
static inline InlineFlowBox* flowBoxForRenderer(RenderObject* renderer)
{
if (!renderer)
return 0;
if (renderer->isRenderBlock()) {
// If we're given a block element, it has to be a RenderSVGText.
ASSERT(renderer->isSVGText());
RenderBlock* renderBlock = toRenderBlock(renderer);
// RenderSVGText only ever contains a single line box.
InlineFlowBox* flowBox = renderBlock->firstLineBox();
ASSERT(flowBox == renderBlock->lastLineBox());
return flowBox;
}
if (renderer->isRenderInline()) {
// We're given a RenderSVGInline or objects that derive from it (RenderSVGTSpan / RenderSVGTextPath)
RenderInline* renderInline = toRenderInline(renderer);
// RenderSVGInline only ever contains a single line box.
InlineFlowBox* flowBox = renderInline->firstLineBox();
ASSERT(flowBox == renderInline->lastLineBox());
return flowBox;
}
ASSERT_NOT_REACHED();
return 0;
}
示例5: accumulateInFlowPositionOffsets
static LayoutSize accumulateInFlowPositionOffsets(const RenderObject* child)
{
if (!child->isAnonymousBlock() || !child->isRelPositioned())
return LayoutSize();
LayoutSize offset;
RenderObject* p = toRenderBlock(child)->inlineElementContinuation();
while (p && p->isRenderInline()) {
if (p->isRelPositioned()) {
RenderInline* renderInline = toRenderInline(p);
offset += renderInline->offsetForInFlowPosition();
}
p = p->parent();
}
return offset;
}
示例6: ASSERT
void RenderLineBoxList::paint(RenderBoxModelObject* renderer, PaintInfo& paintInfo, const LayoutPoint& paintOffset) const
{
// Only paint during the foreground/selection phases.
if (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection && paintInfo.phase != PaintPhaseOutline
&& paintInfo.phase != PaintPhaseSelfOutline && paintInfo.phase != PaintPhaseChildOutlines && paintInfo.phase != PaintPhaseTextClip
&& paintInfo.phase != PaintPhaseMask)
return;
ASSERT(renderer->isRenderBlock() || (renderer->isRenderInline() && renderer->hasLayer())); // The only way an inline could paint like this is if it has a layer.
// If we have no lines then we have no work to do.
if (!firstLineBox())
return;
if (!anyLineIntersectsRect(renderer, paintInfo.rect, paintOffset))
return;
PaintInfo info(paintInfo);
ListHashSet<RenderInline*> outlineObjects;
info.setOutlineObjects(&outlineObjects);
// 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 = firstLineBox(); curr; curr = curr->nextLineBox()) {
if (lineIntersectsDirtyRect(renderer, curr, info, paintOffset)) {
RootInlineBox& root = curr->root();
curr->paint(info, paintOffset, root.lineTop(), root.lineBottom());
}
}
if (info.phase == PaintPhaseOutline || info.phase == PaintPhaseSelfOutline || info.phase == PaintPhaseChildOutlines) {
ListHashSet<RenderInline*>::iterator end = info.outlineObjects()->end();
for (ListHashSet<RenderInline*>::iterator it = info.outlineObjects()->begin(); it != end; ++it) {
RenderInline* flow = *it;
flow->paintOutline(info, paintOffset);
}
info.outlineObjects()->clear();
}
}
示例7: buildRendererHighlight
static void buildRendererHighlight(RenderObject* renderer, RenderRegion* region, const HighlightConfig& highlightConfig, Highlight* highlight, InspectorOverlay::CoordinateSystem coordinateSystem)
{
Frame* containingFrame = renderer->document().frame();
if (!containingFrame)
return;
highlight->setDataFromConfig(highlightConfig);
FrameView* containingView = containingFrame->view();
FrameView* mainView = containingFrame->page()->mainFrame().view();
// RenderSVGRoot should be highlighted through the isBox() code path, all other SVG elements should just dump their absoluteQuads().
bool isSVGRenderer = renderer->node() && renderer->node()->isSVGElement() && !renderer->isSVGRoot();
if (isSVGRenderer) {
highlight->type = HighlightTypeRects;
renderer->absoluteQuads(highlight->quads);
for (size_t i = 0; i < highlight->quads.size(); ++i)
contentsQuadToCoordinateSystem(mainView, containingView, highlight->quads[i], coordinateSystem);
} else if (renderer->isBox() || renderer->isRenderInline()) {
LayoutRect contentBox;
LayoutRect paddingBox;
LayoutRect borderBox;
LayoutRect marginBox;
if (renderer->isBox()) {
RenderBox* renderBox = toRenderBox(renderer);
LayoutBoxExtent margins(renderBox->marginTop(), renderBox->marginRight(), renderBox->marginBottom(), renderBox->marginLeft());
if (!renderBox->isOutOfFlowPositioned() && region) {
RenderBox::LogicalExtentComputedValues computedValues;
renderBox->computeLogicalWidthInRegion(computedValues, region);
margins.mutableLogicalLeft(renderBox->style().writingMode()) = computedValues.m_margins.m_start;
margins.mutableLogicalRight(renderBox->style().writingMode()) = computedValues.m_margins.m_end;
}
paddingBox = renderBox->clientBoxRectInRegion(region);
contentBox = LayoutRect(paddingBox.x() + renderBox->paddingLeft(), paddingBox.y() + renderBox->paddingTop(),
paddingBox.width() - renderBox->paddingLeft() - renderBox->paddingRight(), paddingBox.height() - renderBox->paddingTop() - renderBox->paddingBottom());
borderBox = LayoutRect(paddingBox.x() - renderBox->borderLeft(), paddingBox.y() - renderBox->borderTop(),
paddingBox.width() + renderBox->borderLeft() + renderBox->borderRight(), paddingBox.height() + renderBox->borderTop() + renderBox->borderBottom());
marginBox = LayoutRect(borderBox.x() - margins.left(), borderBox.y() - margins.top(),
borderBox.width() + margins.left() + margins.right(), borderBox.height() + margins.top() + margins.bottom());
} else {
RenderInline* renderInline = toRenderInline(renderer);
// RenderInline's bounding box includes paddings and borders, excludes margins.
borderBox = renderInline->linesBoundingBox();
paddingBox = LayoutRect(borderBox.x() + renderInline->borderLeft(), borderBox.y() + renderInline->borderTop(),
borderBox.width() - renderInline->borderLeft() - renderInline->borderRight(), borderBox.height() - renderInline->borderTop() - renderInline->borderBottom());
contentBox = LayoutRect(paddingBox.x() + renderInline->paddingLeft(), paddingBox.y() + renderInline->paddingTop(),
paddingBox.width() - renderInline->paddingLeft() - renderInline->paddingRight(), paddingBox.height() - renderInline->paddingTop() - renderInline->paddingBottom());
// Ignore marginTop and marginBottom for inlines.
marginBox = LayoutRect(borderBox.x() - renderInline->marginLeft(), borderBox.y(),
borderBox.width() + renderInline->horizontalMarginExtent(), borderBox.height());
}
FloatQuad absContentQuad;
FloatQuad absPaddingQuad;
FloatQuad absBorderQuad;
FloatQuad absMarginQuad;
if (region) {
RenderFlowThread* flowThread = region->flowThread();
// Figure out the quads in the space of the RenderFlowThread.
absContentQuad = renderer->localToContainerQuad(FloatRect(contentBox), flowThread);
absPaddingQuad = renderer->localToContainerQuad(FloatRect(paddingBox), flowThread);
absBorderQuad = renderer->localToContainerQuad(FloatRect(borderBox), flowThread);
absMarginQuad = renderer->localToContainerQuad(FloatRect(marginBox), flowThread);
// Move the quad relative to the space of the current region.
LayoutRect flippedRegionRect(region->flowThreadPortionRect());
flowThread->flipForWritingMode(flippedRegionRect);
FloatSize delta = region->contentBoxRect().location() - flippedRegionRect.location();
absContentQuad.move(delta);
absPaddingQuad.move(delta);
absBorderQuad.move(delta);
absMarginQuad.move(delta);
// Resolve the absolute quads starting from the current region.
absContentQuad = region->localToAbsoluteQuad(absContentQuad);
absPaddingQuad = region->localToAbsoluteQuad(absPaddingQuad);
absBorderQuad = region->localToAbsoluteQuad(absBorderQuad);
absMarginQuad = region->localToAbsoluteQuad(absMarginQuad);
} else {
absContentQuad = renderer->localToAbsoluteQuad(FloatRect(contentBox));
absPaddingQuad = renderer->localToAbsoluteQuad(FloatRect(paddingBox));
absBorderQuad = renderer->localToAbsoluteQuad(FloatRect(borderBox));
absMarginQuad = renderer->localToAbsoluteQuad(FloatRect(marginBox));
}
contentsQuadToCoordinateSystem(mainView, containingView, absContentQuad, coordinateSystem);
contentsQuadToCoordinateSystem(mainView, containingView, absPaddingQuad, coordinateSystem);
contentsQuadToCoordinateSystem(mainView, containingView, absBorderQuad, coordinateSystem);
contentsQuadToCoordinateSystem(mainView, containingView, absMarginQuad, coordinateSystem);
highlight->type = HighlightTypeNode;
highlight->quads.append(absMarginQuad);
//.........这里部分代码省略.........
示例8: cloneInline
void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock,
RenderBlock* middleBlock,
RenderObject* beforeChild, RenderFlow* oldCont)
{
// Create a clone of this inline.
RenderInline* clone = cloneInline(this);
clone->setContinuation(oldCont);
// Now take all of the children from beforeChild to the end and remove
// them from |this| and place them in the clone.
RenderObject* o = beforeChild;
while (o) {
RenderObject* tmp = o;
o = tmp->nextSibling();
clone->addChildToFlow(removeChildNode(tmp), 0);
tmp->setNeedsLayoutAndPrefWidthsRecalc();
}
// Hook |clone| up as the continuation of the middle block.
middleBlock->setContinuation(clone);
// We have been reparented and are now under the fromBlock. We need
// to walk up our inline parent chain until we hit the containing block.
// Once we hit the containing block we're done.
RenderFlow* curr = static_cast<RenderFlow*>(parent());
RenderFlow* currChild = this;
// FIXME: Because splitting is O(n^2) as tags nest pathologically, we cap the depth at which we're willing to clone.
// There will eventually be a better approach to this problem that will let us nest to a much
// greater depth (see bugzilla bug 13430) but for now we have a limit. This *will* result in
// incorrect rendering, but the alternative is to hang forever.
unsigned splitDepth = 1;
const unsigned cMaxSplitDepth = 200;
while (curr && curr != fromBlock) {
if (splitDepth < cMaxSplitDepth) {
// Create a new clone.
RenderInline* cloneChild = clone;
clone = cloneInline(curr);
// Insert our child clone as the first child.
clone->addChildToFlow(cloneChild, 0);
// Hook the clone up as a continuation of |curr|.
RenderFlow* oldCont = curr->continuation();
curr->setContinuation(clone);
clone->setContinuation(oldCont);
// Someone may have indirectly caused a <q> to split. When this happens, the :after content
// has to move into the inline continuation. Call updateBeforeAfterContent to ensure that the inline's :after
// content gets properly destroyed.
curr->updateBeforeAfterContent(RenderStyle::AFTER);
// Now we need to take all of the children starting from the first child
// *after* currChild and append them all to the clone.
o = currChild->nextSibling();
while (o) {
RenderObject* tmp = o;
o = tmp->nextSibling();
clone->addChildToFlow(curr->removeChildNode(tmp), 0);
tmp->setNeedsLayoutAndPrefWidthsRecalc();
}
}
// Keep walking up the chain.
currChild = curr;
curr = static_cast<RenderFlow*>(curr->parent());
splitDepth++;
}
// Now we are at the block level. We need to put the clone into the toBlock.
toBlock->appendChildNode(clone);
// Now take all the children after currChild and remove them from the fromBlock
// and put them in the toBlock.
o = currChild->nextSibling();
while (o) {
RenderObject* tmp = o;
o = tmp->nextSibling();
toBlock->appendChildNode(fromBlock->removeChildNode(tmp));
}
}
示例9: toRenderInline
void RenderLineBoxList::dirtyLinesFromChangedChild(RenderObject* container, RenderObject* child)
{
if (!container->parent() || (container->isRenderBlock() && (container->selfNeedsLayout() || !container->isRenderBlockFlow())))
return;
RenderInline* inlineContainer = container->isRenderInline() ? toRenderInline(container) : 0;
InlineBox* firstBox = inlineContainer ? inlineContainer->firstLineBoxIncludingCulling() : firstLineBox();
// If we have no first line box, then just bail early.
if (!firstBox) {
// For an empty inline, go ahead and propagate the check up to our parent, unless the parent
// is already dirty.
if (container->isInline() && !container->ancestorLineBoxDirty()) {
container->parent()->dirtyLinesFromChangedChild(container);
container->setAncestorLineBoxDirty(); // Mark the container to avoid dirtying the same lines again across multiple destroy() calls of the same subtree.
}
return;
}
// Try to figure out which line box we belong in. First try to find a previous
// line box by examining our siblings. If we didn't find a line box, then use our
// parent's first line box.
RootInlineBox* box = 0;
RenderObject* curr = 0;
for (curr = child->previousSibling(); curr; curr = curr->previousSibling()) {
if (curr->isFloatingOrOutOfFlowPositioned())
continue;
if (curr->isReplaced()) {
InlineBox* wrapper = toRenderBox(curr)->inlineBoxWrapper();
if (wrapper)
box = &wrapper->root();
} else if (curr->isText()) {
InlineTextBox* textBox = toRenderText(curr)->lastTextBox();
if (textBox)
box = &textBox->root();
} else if (curr->isRenderInline()) {
InlineBox* lastSiblingBox = toRenderInline(curr)->lastLineBoxIncludingCulling();
if (lastSiblingBox)
box = &lastSiblingBox->root();
}
if (box)
break;
}
if (!box) {
if (inlineContainer && !inlineContainer->alwaysCreateLineBoxes()) {
// https://bugs.webkit.org/show_bug.cgi?id=60778
// We may have just removed a <br> with no line box that was our first child. In this case
// we won't find a previous sibling, but firstBox can be pointing to a following sibling.
// This isn't good enough, since we won't locate the root line box that encloses the removed
// <br>. We have to just over-invalidate a bit and go up to our parent.
if (!inlineContainer->ancestorLineBoxDirty()) {
inlineContainer->parent()->dirtyLinesFromChangedChild(inlineContainer);
inlineContainer->setAncestorLineBoxDirty(); // Mark the container to avoid dirtying the same lines again across multiple destroy() calls of the same subtree.
}
return;
}
box = &firstBox->root();
}
// If we found a line box, then dirty it.
if (box) {
RootInlineBox* adjacentBox;
box->markDirty();
// dirty the adjacent lines that might be affected
// NOTE: we dirty the previous line because RootInlineBox objects cache
// the address of the first object on the next line after a BR, which we may be
// invalidating here. For more info, see how RenderBlock::layoutInlineChildren
// calls setLineBreakInfo with the result of findNextLineBreak. findNextLineBreak,
// despite the name, actually returns the first RenderObject after the BR.
// <rdar://problem/3849947> "Typing after pasting line does not appear until after window resize."
adjacentBox = box->prevRootBox();
if (adjacentBox)
adjacentBox->markDirty();
adjacentBox = box->nextRootBox();
// If |child| has been inserted before the first element in the linebox, but after collapsed leading
// space, the search for |child|'s linebox will go past the leading space to the previous linebox and select that
// one as |box|. If we hit that situation here, dirty the |box| actually containing the child too.
bool insertedAfterLeadingSpace = box->lineBreakObj() == child->previousSibling();
if (adjacentBox && (adjacentBox->lineBreakObj() == child || child->isBR() || (curr && curr->isBR())
|| insertedAfterLeadingSpace || isIsolated(container->style()->unicodeBidi()))) {
adjacentBox->markDirty();
}
}
}
示例10: cloneInline
void RenderInline::splitInlines(RenderBlock *fromBlock, RenderBlock *toBlock, RenderBlock *middleBlock, RenderObject *beforeChild,
RenderFlow *oldCont)
{
// Create a clone of this inline.
RenderInline *clone = cloneInline(this);
clone->setContinuation(oldCont);
// Now take all of the children from beforeChild to the end and remove
// then from |this| and place them in the clone.
RenderObject *o = beforeChild;
while(o)
{
RenderObject *tmp = o;
o = tmp->nextSibling();
clone->addChildToFlow(removeChildNode(tmp), 0);
tmp->setNeedsLayoutAndMinMaxRecalc();
}
// Hook |clone| up as the continuation of the middle block.
middleBlock->setContinuation(clone);
// We have been reparented and are now under the fromBlock. We need
// to walk up our inline parent chain until we hit the containing block.
// Once we hit the containing block we're done.
RenderFlow *curr = static_cast< RenderFlow * >(parent());
RenderFlow *currChild = this;
while(curr && curr != fromBlock)
{
// Create a new clone.
RenderInline *cloneChild = clone;
clone = cloneInline(curr);
// Insert our child clone as the first child.
clone->addChildToFlow(cloneChild, 0);
// Hook the clone up as a continuation of |curr|.
RenderFlow *oldCont = curr->continuation();
curr->setContinuation(clone);
clone->setContinuation(oldCont);
// Now we need to take all of the children starting from the first child
// *after* currChild and append them all to the clone.
o = currChild->nextSibling();
while(o)
{
RenderObject *tmp = o;
o = tmp->nextSibling();
clone->appendChildNode(curr->removeChildNode(tmp));
tmp->setNeedsLayoutAndMinMaxRecalc();
}
// Keep walking up the chain.
currChild = curr;
curr = static_cast< RenderFlow * >(curr->parent());
}
// Now we are at the block level. We need to put the clone into the toBlock.
toBlock->appendChildNode(clone);
// Now take all the children after currChild and remove them from the fromBlock
// and put them in the toBlock.
o = currChild->nextSibling();
while(o)
{
RenderObject *tmp = o;
o = tmp->nextSibling();
toBlock->appendChildNode(fromBlock->removeChildNode(tmp));
}
}
示例11: autoPushRoot
void RenderLineBoxList::readyWRATHWidgets(PaintedWidgetsOfWRATHHandle &handle,
RenderBoxModelObject *renderer,
PaintInfoOfWRATH &paintInfo, int tx, int ty)
{
RenderLineBoxList_WRATHWidgets *d;
d=RenderLineBoxList_WRATHWidgets::object(renderer, handle);
ContextOfWRATH::AutoPushNode autoPushRoot(paintInfo.wrath_context, d->m_root_node);
/*
this just.. sucks. WebKit builds a list of
RenderInline objects that it will draw outlines.
It is not clear if and how that list changes,
so we punt and make all them handle non-visible
and only those that are found in the list
are then made visible.
*/
d->m_handles.hideEachObject();
d->m_outlineHandles.hideEachObject();
// Only paint during the foreground/selection phases.
if (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection && paintInfo.phase != PaintPhaseOutline
&& paintInfo.phase != PaintPhaseSelfOutline && paintInfo.phase != PaintPhaseChildOutlines && paintInfo.phase != PaintPhaseTextClip
&& paintInfo.phase != PaintPhaseMask)
return;
ASSERT(renderer->isRenderBlock() || (renderer->isRenderInline() && renderer->hasLayer())); // The only way an inline could paint like this is if it has a layer.
// If we have no lines then we have no work to do.
if (!firstLineBox())
return;
RenderView* v = renderer->view();
bool usePrintRect = !v->printRect().isEmpty();
int outlineSize = renderer->maximalOutlineSize(paintInfo.phase);
if (!anyLineIntersectsRect(renderer, paintInfo.rect, tx, ty, usePrintRect, outlineSize))
return;
PaintInfoOfWRATH info(paintInfo);
ListHashSet<RenderInline*> outlineObjects;
info.outlineObjects = &outlineObjects;
for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
if (usePrintRect) {
RootInlineBox* root = curr->root();
int topForPaginationCheck = curr->logicalTopVisualOverflow(root->lineTop());
int bottomForPaginationCheck = curr->logicalLeftVisualOverflow();
if (!curr->parent()) {
// We're a root box. Use lineTop and lineBottom as well here.
topForPaginationCheck = min(topForPaginationCheck, root->lineTop());
bottomForPaginationCheck = max(bottomForPaginationCheck, root->lineBottom());
}
if (bottomForPaginationCheck - topForPaginationCheck <= v->printRect().height()) {
if (ty + bottomForPaginationCheck > v->printRect().maxY()) {
if (RootInlineBox* nextRootBox = curr->root()->nextRootBox())
bottomForPaginationCheck = min(bottomForPaginationCheck, min(nextRootBox->logicalTopVisualOverflow(), nextRootBox->lineTop()));
}
if (ty + bottomForPaginationCheck > v->printRect().maxY()) {
if (ty + topForPaginationCheck < v->truncatedAt())
v->setBestTruncatedAt(ty + topForPaginationCheck, renderer);
// If we were able to truncate, don't paint.
if (ty + topForPaginationCheck >= v->truncatedAt())
break;
}
}
}
if (lineIntersectsDirtyRect(renderer, curr, info, tx, ty)) {
RootInlineBox* root = curr->root();
PaintedWidgetsOfWRATHHandleT<InlineBox> &currHandle(d->m_handles.getHandle(curr));
currHandle.visible(true);
curr->readyWRATHWidgets(currHandle, info, tx, ty, root->lineTop(), root->lineBottom());
}
}
if (info.phase == PaintPhaseOutline || info.phase == PaintPhaseSelfOutline || info.phase == PaintPhaseChildOutlines) {
ListHashSet<RenderInline*>::iterator end = info.outlineObjects->end();
for (ListHashSet<RenderInline*>::iterator it = info.outlineObjects->begin(); it != end; ++it) {
RenderInline* flow = *it;
PaintedWidgetsOfWRATHHandle &handle(d->m_outlineHandles.getHandle(flow));
handle.visible(true);
flow->readyWRATHWidgetOutline(handle, info.wrath_context, tx, ty);
}
info.outlineObjects->clear();
}
d->m_handles.removeNonVisibleHandles();
d->m_outlineHandles.removeNonVisibleHandles();
}
示例12: ASSERT
void RenderLineBoxList::dirtyLinesFromChangedChild(RenderBoxModelObject& container, RenderObject& child)
{
ASSERT(is<RenderInline>(container) || is<RenderBlockFlow>(container));
if (!container.parent() || (is<RenderBlockFlow>(container) && container.selfNeedsLayout()))
return;
RenderInline* inlineContainer = is<RenderInline>(container) ? &downcast<RenderInline>(container) : nullptr;
InlineBox* firstBox = inlineContainer ? inlineContainer->firstLineBoxIncludingCulling() : firstLineBox();
// If we have no first line box, then just bail early.
if (!firstBox) {
// For an empty inline, propagate the check up to our parent, unless the parent is already dirty.
if (container.isInline() && !container.ancestorLineBoxDirty()) {
container.parent()->dirtyLinesFromChangedChild(container);
container.setAncestorLineBoxDirty(); // Mark the container to avoid dirtying the same lines again across multiple destroy() calls of the same subtree.
}
return;
}
// Try to figure out which line box we belong in. First try to find a previous
// line box by examining our siblings. If we didn't find a line box, then use our
// parent's first line box.
RootInlineBox* box = nullptr;
RenderObject* current;
for (current = child.previousSibling(); current; current = current->previousSibling()) {
if (current->isFloatingOrOutOfFlowPositioned())
continue;
if (current->isReplaced()) {
if (auto wrapper = downcast<RenderBox>(*current).inlineBoxWrapper())
box = &wrapper->root();
} if (is<RenderLineBreak>(*current)) {
if (auto wrapper = downcast<RenderLineBreak>(*current).inlineBoxWrapper())
box = &wrapper->root();
} else if (is<RenderText>(*current)) {
if (InlineTextBox* textBox = downcast<RenderText>(*current).lastTextBox())
box = &textBox->root();
} else if (is<RenderInline>(*current)) {
InlineBox* lastSiblingBox = downcast<RenderInline>(*current).lastLineBoxIncludingCulling();
if (lastSiblingBox)
box = &lastSiblingBox->root();
}
if (box)
break;
}
if (!box) {
if (inlineContainer && !inlineContainer->alwaysCreateLineBoxes()) {
// https://bugs.webkit.org/show_bug.cgi?id=60778
// We may have just removed a <br> with no line box that was our first child. In this case
// we won't find a previous sibling, but firstBox can be pointing to a following sibling.
// This isn't good enough, since we won't locate the root line box that encloses the removed
// <br>. We have to just over-invalidate a bit and go up to our parent.
if (!inlineContainer->ancestorLineBoxDirty()) {
inlineContainer->parent()->dirtyLinesFromChangedChild(*inlineContainer);
inlineContainer->setAncestorLineBoxDirty(); // Mark the container to avoid dirtying the same lines again across multiple destroy() calls of the same subtree.
}
return;
}
box = &firstBox->root();
}
// If we found a line box, then dirty it.
if (box) {
box->markDirty();
// Dirty the adjacent lines that might be affected.
// NOTE: we dirty the previous line because RootInlineBox objects cache
// the address of the first object on the next line after a BR, which we may be
// invalidating here. For more info, see how RenderBlock::layoutInlineChildren
// calls setLineBreakInfo with the result of findNextLineBreak. findNextLineBreak,
// despite the name, actually returns the first RenderObject after the BR.
// <rdar://problem/3849947> "Typing after pasting line does not appear until after window resize."
if (RootInlineBox* prevBox = box->prevRootBox())
prevBox->markDirty();
// FIXME: We shouldn't need to always dirty the next line. This is only strictly
// necessary some of the time, in situations involving BRs.
if (RootInlineBox* nextBox = box->nextRootBox()) {
nextBox->markDirty();
// Dedicated linebox for floats may be added as the last rootbox. If this occurs with BRs inside inlines that propagte their lineboxes to
// the parent flow, we need to invalidate it explicitly.
// FIXME: We should be able to figure out the actual "changed child" even when we are calling through empty inlines recursively.
if (is<RenderInline>(child) && !downcast<RenderInline>(child).firstLineBoxIncludingCulling()) {
auto* lastRootBox = nextBox->blockFlow().lastRootBox();
if (lastRootBox->isTrailingFloatsRootInlineBox() && !lastRootBox->isDirty())
lastRootBox->markDirty();
}
}
}
}
示例13: ASSERT
void RenderLineBoxList::paint(RenderBoxModelObject* renderer, RenderObject::PaintInfo& paintInfo, int tx, int ty) const
{
// Only paint during the foreground/selection phases.(只有画前景和选择才会跑到这里)
if (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection && paintInfo.phase != PaintPhaseOutline
&& paintInfo.phase != PaintPhaseSelfOutline && paintInfo.phase != PaintPhaseChildOutlines && paintInfo.phase != PaintPhaseTextClip
&& paintInfo.phase != PaintPhaseMask)
return;
ASSERT(renderer->isRenderBlock() || (renderer->isRenderInline() && renderer->hasLayer())); // The only way an inline could paint like this is if it has a layer.
// If we have no lines then we have no work to do.
if (!firstLineBox())
return;
// We can check the first box and last box and avoid painting if we don't
// intersect. 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.
int yPos = firstLineBox()->topVisibleOverflow() - renderer->maximalOutlineSize(paintInfo.phase);
int h = renderer->maximalOutlineSize(paintInfo.phase) + lastLineBox()->bottomVisibleOverflow() - yPos; // 要画的inline块(从第一行到最后一行的)整个高度
yPos += ty; // 起始高度
if (yPos >= paintInfo.rect.bottom() || yPos + h <= paintInfo.rect.y())
return;
RenderObject::PaintInfo info(paintInfo);
ListHashSet<RenderInline*> outlineObjects;
info.outlineObjects = &outlineObjects;
// 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.
RenderView* v = renderer->view();
bool usePrintRect = !v->printRect().isEmpty();
for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) { // 开始对每行进行绘制
if (usePrintRect) {
// FIXME: This is a feeble effort to avoid splitting a line across two pages.
// It is utterly inadequate, and this should not be done at paint time at all.
// The whole way objects break across pages needs to be redone.
// Try to avoid splitting a line vertically, but only if it's less than the height
// of the entire page.
if (curr->bottomVisibleOverflow() - curr->topVisibleOverflow() <= v->printRect().height()) {
if (ty + curr->bottomVisibleOverflow() > v->printRect().bottom()) {
if (ty + curr->topVisibleOverflow() < v->truncatedAt())
v->setBestTruncatedAt(ty + curr->root()->topVisibleOverflow(), renderer);
// If we were able to truncate, don't paint.
if (ty + curr->topVisibleOverflow() >= v->truncatedAt())
break;
}
}
}
int top = min(curr->topVisibleOverflow(), curr->root()->selectionTop()) - renderer->maximalOutlineSize(info.phase); // 高点
int bottom = curr->bottomVisibleOverflow() + renderer->maximalOutlineSize(info.phase); // 底点
h = bottom - top; // 高度
yPos = ty + top; // 开始绘制点
v->setMinimumColumnHeight(h);
if (yPos < info.rect.bottom() && yPos + h > info.rect.y())
curr->paint(info, tx, ty); // 开始绘制该行
}
if (info.phase == PaintPhaseOutline || info.phase == PaintPhaseSelfOutline || info.phase == PaintPhaseChildOutlines) {
ListHashSet<RenderInline*>::iterator end = info.outlineObjects->end();
for (ListHashSet<RenderInline*>::iterator it = info.outlineObjects->begin(); it != end; ++it) {
RenderInline* flow = *it;
flow->paintOutline(info.context, tx, ty);
}
info.outlineObjects->clear();
}
}