bool RenderSVGForeignObject::nodeAtFloatPoint(const HitTestRequest& request, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction) { FloatPoint localPoint = localTransform().inverse().mapPoint(pointInParent); // Early exit if local point is not contained in clipped viewport area if (SVGRenderSupport::isOverflowHidden(this) && !m_viewport.contains(localPoint)) return false; return RenderBlock::nodeAtPoint(request, result, roundedLayoutPoint(localPoint), LayoutPoint(), hitTestAction); }
bool RenderSVGText::nodeAtFloatPoint(const HitTestRequest& request, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction) { PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_TEXT_HITTESTING, request, style()->pointerEvents()); bool isVisible = (style()->visibility() == VISIBLE); if (isVisible || !hitRules.requireVisible) { if ((hitRules.canHitStroke && (style()->svgStyle()->hasStroke() || !hitRules.requireStroke)) || (hitRules.canHitFill && (style()->svgStyle()->hasFill() || !hitRules.requireFill))) { FloatPoint localPoint = localToParentTransform().inverse().mapPoint(pointInParent); if (!SVGRenderSupport::pointInClippingArea(this, localPoint)) return false; HitTestLocation hitTestLocation(LayoutPoint(flooredIntPoint(localPoint))); return RenderBlock::nodeAtPoint(request, result, hitTestLocation, LayoutPoint(), hitTestAction); } } return false; }
void RenderScrollbarPart::layout() { setLocation(LayoutPoint()); // We don't worry about positioning ourselves. We're just determining our minimum width/height. if (m_scrollbar->orientation() == HorizontalScrollbar) layoutHorizontalPart(); else layoutVerticalPart(); setNeedsLayout(false); }
void RenderRegion::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOffset) { // Delegate painting of content in region to RenderFlowThread. if (!m_flowThread || !isValid()) return; setRegionBoxesRegionStyle(); m_flowThread->paintIntoRegion(paintInfo, this, LayoutPoint(paintOffset.x() + borderLeft() + paddingLeft(), paintOffset.y() + borderTop() + paddingTop())); restoreRegionBoxesOriginalStyle(); }
static LayoutPoint cornerPointOfRect(LayoutRect rect, Corner whichCorner) { switch (whichCorner) { case Corner::TopLeft: return rect.minXMinYCorner(); case Corner::TopRight: return rect.maxXMinYCorner(); } ASSERT_NOT_REACHED(); return LayoutPoint(); }
void RenderSVGRoot::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOffset) { // An empty viewport disables rendering. if (pixelSnappedBorderBoxRect().isEmpty()) return; // Don't paint, if the context explicitely disabled it. if (paintInfo.context->paintingDisabled()) return; Page* page = 0; if (Frame* frame = this->frame()) page = frame->page(); // Don't paint if we don't have kids, except if we have filters we should paint those. if (!firstChild()) { SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(this); if (!resources || !resources->filter()) { if (page && paintInfo.phase == PaintPhaseForeground) page->addRelevantUnpaintedObject(this, visualOverflowRect()); return; } } if (page && paintInfo.phase == PaintPhaseForeground) page->addRelevantRepaintedObject(this, visualOverflowRect()); // Make a copy of the PaintInfo because applyTransform will modify the damage rect. PaintInfo childPaintInfo(paintInfo); childPaintInfo.context->save(); // Apply initial viewport clip - not affected by overflow handling childPaintInfo.context->clip(pixelSnappedIntRect(overflowClipRect(paintOffset, paintInfo.renderRegion))); // Convert from container offsets (html renderers) to a relative transform (svg renderers). // Transform from our paint container's coordinate system to our local coords. IntPoint adjustedPaintOffset = roundedIntPoint(paintOffset); childPaintInfo.applyTransform(AffineTransform::translation(adjustedPaintOffset.x(), adjustedPaintOffset.y()) * localToBorderBoxTransform()); // SVGRenderingContext must be destroyed before we restore the childPaintInfo.context, because a filter may have // changed the context and it is only reverted when the SVGRenderingContext destructor finishes applying the filter. { SVGRenderingContext renderingContext; bool continueRendering = true; if (childPaintInfo.phase == PaintPhaseForeground) { renderingContext.prepareToRenderSVGContent(this, childPaintInfo); continueRendering = renderingContext.isRenderingPrepared(); } if (continueRendering) RenderBox::paint(childPaintInfo, LayoutPoint()); } childPaintInfo.context->restore(); }
void PaintPropertyTreeBuilder::walk(FrameView& frameView, const PaintPropertyTreeBuilderContext& context) { PaintPropertyTreeBuilderContext localContext(context); // TODO(pdr): Creating paint properties for FrameView here will not be // needed once settings()->rootLayerScrolls() is enabled. // TODO(pdr): Make this conditional on the rootLayerScrolls setting. TransformationMatrix frameTranslate; frameTranslate.translate(frameView.x(), frameView.y()); // The frame owner applies paint offset already. // This assumption may change in the future. ASSERT(context.paintOffset == LayoutPoint()); RefPtr<TransformPaintPropertyNode> newTransformNodeForPreTranslation = TransformPaintPropertyNode::create(frameTranslate, FloatPoint3D(), context.currentTransform); localContext.transformForFixedPositioned = newTransformNodeForPreTranslation.get(); localContext.paintOffsetForFixedPositioned = LayoutPoint(); FloatRoundedRect contentClip(IntRect(IntPoint(), frameView.visibleContentSize())); RefPtr<ClipPaintPropertyNode> newClipNodeForContentClip = ClipPaintPropertyNode::create(newTransformNodeForPreTranslation.get(), contentClip, localContext.currentClip); localContext.currentClip = localContext.clipForOutOfFlowPositioned = localContext.clipForFixedPositioned = newClipNodeForContentClip.get(); DoubleSize scrollOffset = frameView.scrollOffsetDouble(); TransformationMatrix frameScroll; frameScroll.translate(-scrollOffset.width(), -scrollOffset.height()); RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = TransformPaintPropertyNode::create(frameScroll, FloatPoint3D(), newTransformNodeForPreTranslation); localContext.currentTransform = localContext.transformForOutOfFlowPositioned = newTransformNodeForScrollTranslation.get(); localContext.paintOffset = localContext.paintOffsetForOutOfFlowPositioned = LayoutPoint(); frameView.setPreTranslation(newTransformNodeForPreTranslation.release()); frameView.setScrollTranslation(newTransformNodeForScrollTranslation.release()); frameView.setContentClip(newClipNodeForContentClip.release()); if (LayoutView* layoutView = frameView.layoutView()) walk(*layoutView, localContext); for (Frame* child = frameView.frame().tree().firstChild(); child; child = child->tree().nextSibling()) { if (!child->isLocalFrame()) continue; if (FrameView* childView = toLocalFrame(child)->view()) walk(*childView, localContext); } }
static LayoutRect getShapeImageReplacedRect(const RenderBox& renderBox, const StyleImage& styleImage) { if (renderBox.isRenderImage()) { const RenderImage& renderImage = *toRenderImage(&renderBox); return renderImage.replacedContentRect(renderBox.intrinsicSize()); } ASSERT(styleImage.cachedImage()); ASSERT(styleImage.cachedImage()->hasImage()); return LayoutRect(LayoutPoint(), styleImage.cachedImage()->image()->size()); }
void SVGTextPainter::paint(const PaintInfo& paintInfo) { if (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection) return; PaintInfo blockInfo(paintInfo); TransformRecorder transformRecorder(*blockInfo.context, m_renderSVGText.displayItemClient(), m_renderSVGText.localToParentTransform()); // When transitioning from SVG to block painters we need to keep the PaintInfo rect up-to-date // because it can be used for clipping. m_renderSVGText.updatePaintInfoRect(blockInfo.rect); BlockPainter(m_renderSVGText).paint(blockInfo, LayoutPoint()); // Paint the outlines, if any if (paintInfo.phase == PaintPhaseForeground) { blockInfo.phase = PaintPhaseSelfOutline; BlockPainter(m_renderSVGText).paint(blockInfo, LayoutPoint()); } }
void RenderSVGText::paint(PaintInfo& paintInfo, const LayoutPoint&) { if (paintInfo.context->paintingDisabled()) return; if (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection) return; PaintInfo blockInfo(paintInfo); GraphicsContextStateSaver stateSaver(*blockInfo.context); blockInfo.applyTransform(localToParentTransform()); RenderBlock::paint(blockInfo, LayoutPoint()); // Paint the outlines, if any if (paintInfo.phase == PaintPhaseForeground) { blockInfo.phase = PaintPhaseSelfOutline; RenderBlock::paint(blockInfo, LayoutPoint()); } }
void PaintPropertyTreeBuilder::updatePaintOffsetTranslation( const LayoutObject& object, PaintPropertyTreeBuilderContext& context) { if (object.isBoxModelObject() && context.current.paintOffset != LayoutPoint()) { // TODO(trchen): Eliminate PaintLayer dependency. PaintLayer* layer = toLayoutBoxModelObject(object).layer(); if (layer && layer->paintsWithTransform(GlobalPaintNormalPhase)) { // We should use the same subpixel paint offset values for snapping // regardless of whether a transform is present. If there is a transform // we round the paint offset but keep around the residual fractional // component for the transformed content to paint with. In spv1 this was // called "subpixel accumulation". For more information, see // PaintLayer::subpixelAccumulation() and // PaintLayerPainter::paintFragmentByApplyingTransform. IntPoint roundedPaintOffset = roundedIntPoint(context.current.paintOffset); LayoutPoint fractionalPaintOffset = LayoutPoint(context.current.paintOffset - roundedPaintOffset); context.current.transform = object.getMutableForPainting() .ensurePaintProperties() .updatePaintOffsetTranslation( context.current.transform, TransformationMatrix().translate(roundedPaintOffset.x(), roundedPaintOffset.y()), FloatPoint3D(), context.current.shouldFlattenInheritedTransform, context.current.renderingContextID); context.current.paintOffset = fractionalPaintOffset; return; } } if (object.isLayoutView()) return; if (auto* properties = object.getMutableForPainting().paintProperties()) properties->clearPaintOffsetTranslation(); }
void RenderSVGRoot::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOffset) { // An empty viewport disables rendering. if (pixelSnappedBorderBoxRect().isEmpty()) return; // Don't paint, if the context explicitly disabled it. if (paintInfo.context->paintingDisabled()) return; // An empty viewBox also disables rendering. // (http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute) SVGSVGElement* svg = toSVGSVGElement(node()); ASSERT(svg); if (svg->hasEmptyViewBox()) return; // Don't paint if we don't have kids, except if we have filters we should paint those. if (!firstChild()) { SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(this); if (!resources || !resources->filter()) return; } // Make a copy of the PaintInfo because applyTransform will modify the damage rect. PaintInfo childPaintInfo(paintInfo); childPaintInfo.context->save(); // Apply initial viewport clip if (shouldApplyViewportClip()) childPaintInfo.context->clip(pixelSnappedIntRect(overflowClipRect(paintOffset))); // Convert from container offsets (html renderers) to a relative transform (svg renderers). // Transform from our paint container's coordinate system to our local coords. IntPoint adjustedPaintOffset = roundedIntPoint(paintOffset); childPaintInfo.applyTransform(AffineTransform::translation(adjustedPaintOffset.x(), adjustedPaintOffset.y()) * localToBorderBoxTransform()); // SVGRenderingContext must be destroyed before we restore the childPaintInfo.context, because a filter may have // changed the context and it is only reverted when the SVGRenderingContext destructor finishes applying the filter. { SVGRenderingContext renderingContext; bool continueRendering = true; if (childPaintInfo.phase == PaintPhaseForeground) { renderingContext.prepareToRenderSVGContent(this, childPaintInfo); continueRendering = renderingContext.isRenderingPrepared(); } if (continueRendering) RenderBox::paint(childPaintInfo, LayoutPoint()); } childPaintInfo.context->restore(); }
void RenderFlowThread::paintIntoRegion(PaintInfo& paintInfo, RenderRegion* region, const LayoutPoint& paintOffset) { GraphicsContext* context = paintInfo.context; if (!context) return; // Adjust the clipping rect for the region. // paintOffset contains the offset where the painting should occur // adjusted with the region padding and border. LayoutRect regionRect(region->regionRect()); LayoutRect regionOverflowRect(region->regionOverflowRect()); LayoutRect regionClippingRect(paintOffset + (regionOverflowRect.location() - regionRect.location()), regionOverflowRect.size()); PaintInfo info(paintInfo); info.rect.intersect(pixelSnappedIntRect(regionClippingRect)); if (!info.rect.isEmpty()) { context->save(); context->clip(regionClippingRect); // RenderFlowThread should start painting its content in a position that is offset // from the region rect's current position. The amount of offset is equal to the location of // region in flow coordinates. LayoutPoint renderFlowThreadOffset; if (style()->isFlippedBlocksWritingMode()) { LayoutRect flippedRegionRect(regionRect); flipForWritingMode(flippedRegionRect); renderFlowThreadOffset = LayoutPoint(paintOffset - flippedRegionRect.location()); } else renderFlowThreadOffset = LayoutPoint(paintOffset - regionRect.location()); context->translate(renderFlowThreadOffset.x(), renderFlowThreadOffset.y()); info.rect.moveBy(-roundedIntPoint(renderFlowThreadOffset)); layer()->paint(context, info.rect, 0, 0, region, RenderLayer::PaintLayerTemporaryClipRects); context->restore(); } }
LayoutPoint MultiColumnFragmentainerGroup::visualPointToFlowThreadPoint(const LayoutPoint& visualPoint) const { unsigned columnIndex = columnIndexAtVisualPoint(visualPoint); LayoutRect columnRect = columnRectAt(columnIndex); LayoutPoint localPoint(visualPoint); localPoint.moveBy(-columnRect.location()); // Before converting to a flow thread position, if the block direction coordinate is outside the // column, snap to the bounds of the column, and reset the inline direction coordinate to the // start position in the column. The effect of this is that if the block position is before the // column rectangle, we'll get to the beginning of this column, while if the block position is // after the column rectangle, we'll get to the beginning of the next column. if (!m_columnSet.isHorizontalWritingMode()) { LayoutUnit columnStart = m_columnSet.style()->isLeftToRightDirection() ? LayoutUnit() : columnRect.height(); if (localPoint.x() < 0) localPoint = LayoutPoint(LayoutUnit(), columnStart); else if (localPoint.x() > logicalHeight()) localPoint = LayoutPoint(logicalHeight(), columnStart); return LayoutPoint(localPoint.x() + logicalTopInFlowThreadAt(columnIndex), localPoint.y()); } LayoutUnit columnStart = m_columnSet.style()->isLeftToRightDirection() ? LayoutUnit() : columnRect.width(); if (localPoint.y() < 0) localPoint = LayoutPoint(columnStart, LayoutUnit()); else if (localPoint.y() > logicalHeight()) localPoint = LayoutPoint(columnStart, logicalHeight()); return LayoutPoint(localPoint.x(), localPoint.y() + logicalTopInFlowThreadAt(columnIndex)); }
void Element::paint(Canvas* canvas) { if (!renderer() || !renderer()->isBox()) return; RenderBox* box = toRenderBox(renderer()); GraphicsContext context(canvas->skCanvas()); // Very simplified painting to allow painting an arbitrary (layer-less) subtree. Vector<RenderBox*> layers; PaintInfo paintInfo(&context, box->absoluteBoundingBoxRect(), box); box->paint(paintInfo, LayoutPoint(), layers); // Note we're ignoring any layers encountered. }
void RenderView::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset) { // If we ever require layout but receive a paint anyway, something has gone horribly wrong. ASSERT(!needsLayout()); // RenderViews should never be called to paint with an offset not on device pixels. ASSERT(LayoutPoint(IntPoint(paintOffset.x(), paintOffset.y())) == paintOffset); // This avoids painting garbage between columns if there is a column gap. if (m_frameView && m_frameView->pagination().mode != Pagination::Unpaginated) paintInfo.context->fillRect(paintInfo.rect, m_frameView->baseBackgroundColor(), ColorSpaceDeviceRGB); paintObject(paintInfo, paintOffset); }
bool RenderSVGForeignObject::nodeAtFloatPoint(const HitTestRequest& request, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction) { // Embedded content is drawn in the foreground phase. if (hitTestAction != HitTestForeground) return false; AffineTransform localTransform = this->localTransform(); if (!localTransform.isInvertible()) return false; FloatPoint localPoint = localTransform.inverse().mapPoint(pointInParent); // Early exit if local point is not contained in clipped viewport area if (SVGRenderSupport::isOverflowHidden(this) && !m_viewport.contains(localPoint)) return false; // FOs establish a stacking context, so we need to hit-test all layers. HitTestLocation hitTestLocation(roundedLayoutPoint(localPoint)); return RenderBlock::nodeAtPoint(request, result, hitTestLocation, LayoutPoint(), HitTestForeground) || RenderBlock::nodeAtPoint(request, result, hitTestLocation, LayoutPoint(), HitTestFloat) || RenderBlock::nodeAtPoint(request, result, hitTestLocation, LayoutPoint(), HitTestChildBlockBackgrounds); }
static PassRefPtr<TransformPaintPropertyNode> createPaintOffsetTranslationIfNeeded(const LayoutObject& object, PaintPropertyTreeBuilderContext& context) { bool shouldCreatePaintOffsetTranslationNode = false; if (object.isSVGRoot()) { // SVG doesn't use paint offset internally so emit a paint offset at the html->svg boundary. shouldCreatePaintOffsetTranslationNode = true; } else if (object.isBoxModelObject()) { // TODO(trchen): Eliminate PaintLayer dependency. PaintLayer* layer = toLayoutBoxModelObject(object).layer(); shouldCreatePaintOffsetTranslationNode = layer && layer->paintsWithTransform(GlobalPaintNormalPhase); } if (context.paintOffset == LayoutPoint() || !shouldCreatePaintOffsetTranslationNode) return nullptr; RefPtr<TransformPaintPropertyNode> newTransformNodeForPaintOffsetTranslation = TransformPaintPropertyNode::create( TransformationMatrix().translate(context.paintOffset.x(), context.paintOffset.y()), FloatPoint3D(), context.currentTransform); context.currentTransform = newTransformNodeForPaintOffsetTranslation.get(); context.paintOffset = LayoutPoint(); return newTransformNodeForPaintOffsetTranslation.release(); }
void RenderView::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, Vector<RenderBox*>& layers) { // If we ever require layout but receive a paint anyway, something has gone horribly wrong. ASSERT(!needsLayout()); // RenderViews should never be called to paint with an offset not on device pixels. ASSERT(LayoutPoint(IntPoint(paintOffset.x(), paintOffset.y())) == paintOffset); // This avoids painting garbage between columns if there is a column gap. if (m_frameView && style()->isOverflowPaged()) paintInfo.context->fillRect(paintInfo.rect, m_frameView->baseBackgroundColor()); paintObject(paintInfo, paintOffset, layers); }
bool RenderSVGText::nodeAtFloatPoint(const HitTestRequest& request, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction) { PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_TEXT_HITTESTING, request, style()->pointerEvents()); bool isVisible = (style()->visibility() == VISIBLE); if (isVisible || !hitRules.requireVisible) { if ((hitRules.canHitBoundingBox && !objectBoundingBox().isEmpty()) || (hitRules.canHitStroke && (style()->svgStyle().hasStroke() || !hitRules.requireStroke)) || (hitRules.canHitFill && (style()->svgStyle().hasFill() || !hitRules.requireFill))) { FloatPoint localPoint; if (!SVGRenderSupport::transformToUserSpaceAndCheckClipping(this, localToParentTransform(), pointInParent, localPoint)) return false; if (hitRules.canHitBoundingBox && !objectBoundingBox().contains(localPoint)) return false; HitTestLocation hitTestLocation(LayoutPoint(flooredIntPoint(localPoint))); return RenderBlock::nodeAtPoint(request, result, hitTestLocation, LayoutPoint(), hitTestAction); } } return false; }
LayoutRect RenderReplaced::localSelectionRect(bool checkWhetherSelected) const { if (checkWhetherSelected && !isSelected()) return LayoutRect(); if (!inlineBoxWrapper()) // We're a block-level replaced element. Just return our own dimensions. return LayoutRect(LayoutPoint(), size()); RootInlineBox& root = inlineBoxWrapper()->root(); LayoutUnit newLogicalTop = root.selectionTop() - inlineBoxWrapper()->logicalTop(); return LayoutRect(0, newLogicalTop, width(), root.selectionHeight()); }
LayoutRect LayoutListMarker::localSelectionRect() const { InlineBox* box = inlineBoxWrapper(); if (!box) return LayoutRect(LayoutPoint(), size()); RootInlineBox& root = inlineBoxWrapper()->root(); const ComputedStyle* blockStyle = root.block().style(); LayoutUnit newLogicalTop = blockStyle->isFlippedBlocksWritingMode() ? inlineBoxWrapper()->logicalBottom() - root.selectionBottom() : root.selectionTop() - inlineBoxWrapper()->logicalTop(); return blockStyle->isHorizontalWritingMode() ? LayoutRect(0, newLogicalTop, size().width(), root.selectionHeight()) : LayoutRect(newLogicalTop, 0, root.selectionHeight(), size().height()); }
const Shape& ShapeOutsideInfo::computedShape() const { if (Shape* shape = m_shape.get()) return *shape; AutoReset<bool> isInComputingShape(&m_isComputingShape, true); const ComputedStyle& style = *m_layoutBox.style(); ASSERT(m_layoutBox.containingBlock()); const ComputedStyle& containingBlockStyle = *m_layoutBox.containingBlock()->style(); WritingMode writingMode = containingBlockStyle.getWritingMode(); // Make sure contentWidth is not negative. This can happen when containing // block has a vertical scrollbar and its content is smaller than the // scrollbar width. LayoutUnit maximumValue = m_layoutBox.containingBlock() ? std::max(LayoutUnit(), m_layoutBox.containingBlock()->contentWidth()) : LayoutUnit(); float margin = floatValueForLength(m_layoutBox.style()->shapeMargin(), maximumValue.toFloat()); float shapeImageThreshold = style.shapeImageThreshold(); ASSERT(style.shapeOutside()); const ShapeValue& shapeValue = *style.shapeOutside(); switch (shapeValue.type()) { case ShapeValue::Shape: ASSERT(shapeValue.shape()); m_shape = Shape::createShape( shapeValue.shape(), m_referenceBoxLogicalSize, writingMode, margin); break; case ShapeValue::Image: ASSERT(shapeValue.isImageValid()); m_shape = createShapeForImage(shapeValue.image(), shapeImageThreshold, writingMode, margin); break; case ShapeValue::Box: { const FloatRoundedRect& shapeRect = style.getRoundedBorderFor( LayoutRect(LayoutPoint(), m_referenceBoxLogicalSize), m_layoutBox.view()); m_shape = Shape::createLayoutBoxShape(shapeRect, writingMode, margin); break; } } ASSERT(m_shape); return *m_shape; }
void ViewPainter::paint(const PaintInfo& paintInfo, const LayoutPoint& paintOffset) { // If we ever require layout but receive a paint anyway, something has gone horribly wrong. ASSERT(!m_layoutView.needsLayout()); // LayoutViews should never be called to paint with an offset not on device pixels. ASSERT(LayoutPoint(IntPoint(paintOffset.x(), paintOffset.y())) == paintOffset); const FrameView* frameView = m_layoutView.frameView(); if (frameView->shouldThrottleRendering()) return; m_layoutView.paintObject(paintInfo, paintOffset); BlockPainter(m_layoutView).paintOverflowControlsIfNeeded(paintInfo, paintOffset); }
std::unique_ptr<Shape> ShapeOutsideInfo::createShapeForImage(StyleImage* styleImage, float shapeImageThreshold, WritingMode writingMode, float margin) const { LayoutSize imageSize = m_renderer.calculateImageIntrinsicDimensions(styleImage, m_referenceBoxLogicalSize, RenderImage::ScaleByEffectiveZoom); styleImage->setContainerSizeForRenderer(&m_renderer, imageSize, m_renderer.style().effectiveZoom()); const LayoutRect& marginRect = getShapeImageMarginRect(m_renderer, m_referenceBoxLogicalSize); const LayoutRect& imageRect = is<RenderImage>(m_renderer) ? downcast<RenderImage>(m_renderer).replacedContentRect(m_renderer.intrinsicSize()) : LayoutRect(LayoutPoint(), imageSize); ASSERT(!styleImage->isPendingImage()); RefPtr<Image> image = styleImage->image(const_cast<RenderBox*>(&m_renderer), imageSize); return Shape::createRasterShape(image.get(), shapeImageThreshold, imageRect, marginRect, writingMode, margin); }
LayoutRect RenderReplaced::localSelectionRect(bool checkWhetherSelected) const { if (checkWhetherSelected && !isSelected()) return LayoutRect(); if (!m_inlineBoxWrapper) // We're a block-level replaced element. Just return our own dimensions. return LayoutRect(LayoutPoint(), size()); const RootInlineBox& rootBox = m_inlineBoxWrapper->root(); LayoutUnit newLogicalTop = rootBox.blockFlow().style().isFlippedBlocksWritingMode() ? m_inlineBoxWrapper->logicalBottom() - rootBox.selectionBottom() : rootBox.selectionTop() - m_inlineBoxWrapper->logicalTop(); if (rootBox.blockFlow().style().isHorizontalWritingMode()) return LayoutRect(0, newLogicalTop, width(), rootBox.selectionHeight()); return LayoutRect(newLogicalTop, 0, rootBox.selectionHeight(), height()); }
bool EllipsisBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit lineTop, LayoutUnit lineBottom, HitTestAction hitTestAction) { LayoutPoint adjustedLocation = accumulatedOffset + LayoutPoint(topLeft()); // Hit test the markup box. if (InlineBox* markupBox = this->markupBox()) { const RenderStyle& lineStyle = this->lineStyle(); LayoutUnit mtx = adjustedLocation.x() + m_logicalWidth - markupBox->x(); LayoutUnit mty = adjustedLocation.y() + lineStyle.fontMetrics().ascent() - (markupBox->y() + markupBox->lineStyle().fontMetrics().ascent()); if (markupBox->nodeAtPoint(request, result, locationInContainer, LayoutPoint(mtx, mty), lineTop, lineBottom, hitTestAction)) { blockFlow().updateHitTestResult(result, locationInContainer.point() - LayoutSize(mtx, mty)); return true; } } LayoutRect boundsRect(adjustedLocation, LayoutSize(m_logicalWidth, m_height)); if (visibleToHitTesting() && boundsRect.intersects(HitTestLocation::rectForPoint(locationInContainer.point(), 0, 0, 0, 0))) { blockFlow().updateHitTestResult(result, locationInContainer.point() - toLayoutSize(adjustedLocation)); if (!result.addNodeToRectBasedTestResult(blockFlow().element(), request, locationInContainer, boundsRect)) return true; } return false; }
PositionWithAffinity RenderSVGText::positionForPoint(const LayoutPoint& pointInContents) { RootInlineBox* rootBox = firstRootBox(); if (!rootBox) return createPositionWithAffinity(0, DOWNSTREAM); ASSERT(!rootBox->nextRootBox()); ASSERT(childrenInline()); InlineBox* closestBox = toSVGRootInlineBox(rootBox)->closestLeafChildForPosition(pointInContents); if (!closestBox) return createPositionWithAffinity(0, DOWNSTREAM); return closestBox->renderer().positionForPoint(LayoutPoint(pointInContents.x(), closestBox->y())); }
void ViewPainter::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset) { // If we ever require layout but receive a paint anyway, something has gone horribly wrong. ASSERT(!m_renderView.needsLayout()); // RenderViews should never be called to paint with an offset not on device pixels. ASSERT(LayoutPoint(IntPoint(paintOffset.x(), paintOffset.y())) == paintOffset); ANNOTATE_GRAPHICS_CONTEXT(paintInfo, &m_renderView); // This avoids painting garbage between columns if there is a column gap. if (m_renderView.frameView() && m_renderView.style()->isOverflowPaged()) paintInfo.context->fillRect(paintInfo.rect, m_renderView.frameView()->baseBackgroundColor()); m_renderView.paintObject(paintInfo, paintOffset); }
// Hit Testing bool RenderRegion::hitTestFlowThreadContents(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction action) { if (!isValid() || action != HitTestForeground) return false; LayoutRect boundsRect = borderBoxRectInRegion(locationInContainer.region()); boundsRect.moveBy(accumulatedOffset); if (visibleToHitTesting() && locationInContainer.intersects(boundsRect)) { if (m_flowThread->hitTestFlowThreadPortionInRegion(this, flowThreadPortionRect(), flowThreadPortionOverflowRect(), request, result, locationInContainer, LayoutPoint(accumulatedOffset.x() + borderLeft() + paddingLeft(), accumulatedOffset.y() + borderTop() + paddingTop()))) return true; } return false; }