本文整理汇总了C++中LayoutRect::moveBy方法的典型用法代码示例。如果您正苦于以下问题:C++ LayoutRect::moveBy方法的具体用法?C++ LayoutRect::moveBy怎么用?C++ LayoutRect::moveBy使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类LayoutRect
的用法示例。
在下文中一共展示了LayoutRect::moveBy方法的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: calculateRects
void RenderLayerClipper::calculateRects(const ClipRectsContext& context, const LayoutRect& paintDirtyRect, LayoutRect& layerBounds,
ClipRect& backgroundRect, ClipRect& foregroundRect, ClipRect& outlineRect, const LayoutPoint* offsetFromRoot) const
{
bool isClippingRoot = m_renderer.layer() == context.rootLayer;
if (!isClippingRoot && m_renderer.layer()->parent()) {
backgroundRect = backgroundClipRect(context);
backgroundRect.move(roundedIntSize(context.subPixelAccumulation));
backgroundRect.intersect(paintDirtyRect);
} else {
backgroundRect = paintDirtyRect;
}
foregroundRect = backgroundRect;
outlineRect = backgroundRect;
LayoutPoint offset;
if (offsetFromRoot)
offset = *offsetFromRoot;
else
m_renderer.layer()->convertToLayerCoords(context.rootLayer, offset);
layerBounds = LayoutRect(offset, LayoutSize(m_renderer.layer()->size()));
// Update the clip rects that will be passed to child layers.
if (m_renderer.hasOverflowClip()) {
// This layer establishes a clip of some kind.
if (!isClippingRoot || context.respectOverflowClip == RespectOverflowClip) {
foregroundRect.intersect(toRenderBox(m_renderer).overflowClipRect(offset, context.scrollbarRelevancy));
if (m_renderer.style()->hasBorderRadius())
foregroundRect.setHasRadius(true);
}
// If we establish an overflow clip at all, then go ahead and make sure our background
// rect is intersected with our layer's bounds including our visual overflow,
// since any visual overflow like box-shadow or border-outset is not clipped by overflow:auto/hidden.
if (toRenderBox(m_renderer).hasVisualOverflow()) {
// FIXME: Perhaps we should be propagating the borderbox as the clip rect for children, even though
// we may need to inflate our clip specifically for shadows or outsets.
// FIXME: Does not do the right thing with CSS regions yet, since we don't yet factor in the
// individual region boxes as overflow.
LayoutRect layerBoundsWithVisualOverflow = toRenderBox(m_renderer).visualOverflowRect();
toRenderBox(m_renderer).flipForWritingMode(layerBoundsWithVisualOverflow); // Layers are in physical coordinates, so the overflow has to be flipped.
layerBoundsWithVisualOverflow.moveBy(offset);
if (!isClippingRoot || context.respectOverflowClip == RespectOverflowClip)
backgroundRect.intersect(layerBoundsWithVisualOverflow);
} else {
LayoutRect bounds = toRenderBox(m_renderer).borderBoxRect();
bounds.moveBy(offset);
if (!isClippingRoot || context.respectOverflowClip == RespectOverflowClip)
backgroundRect.intersect(bounds);
}
}
// CSS clip (different than clipping due to overflow) can clip to any box, even if it falls outside of the border box.
if (m_renderer.hasClip()) {
// Clip applies to *us* as well, so go ahead and update the damageRect.
LayoutRect newPosClip = toRenderBox(m_renderer).clipRect(offset);
backgroundRect.intersect(newPosClip);
foregroundRect.intersect(newPosClip);
outlineRect.intersect(newPosClip);
}
}
示例2: paint
void RenderReplaced::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
ANNOTATE_GRAPHICS_CONTEXT(paintInfo, this);
if (!shouldPaint(paintInfo, paintOffset))
return;
LayoutPoint adjustedPaintOffset = paintOffset + location();
if (hasBoxDecorationBackground() && (paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection))
paintBoxDecorationBackground(paintInfo, adjustedPaintOffset);
if (paintInfo.phase == PaintPhaseMask) {
paintMask(paintInfo, adjustedPaintOffset);
return;
}
if (paintInfo.phase == PaintPhaseClippingMask && (!hasLayer() || !layer()->hasCompositedClippingMask()))
return;
LayoutRect paintRect = LayoutRect(adjustedPaintOffset, size());
if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && style()->outlineWidth())
paintOutline(paintInfo, paintRect);
if (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection && !canHaveChildren() && paintInfo.phase != PaintPhaseClippingMask)
return;
if (!paintInfo.shouldPaintWithinRoot(this))
return;
bool drawSelectionTint = selectionState() != SelectionNone && !document().printing();
if (paintInfo.phase == PaintPhaseSelection) {
if (selectionState() == SelectionNone)
return;
drawSelectionTint = false;
}
bool completelyClippedOut = false;
if (style()->hasBorderRadius()) {
LayoutRect borderRect = LayoutRect(adjustedPaintOffset, size());
if (borderRect.isEmpty())
completelyClippedOut = true;
else {
// Push a clip if we have a border radius, since we want to round the foreground content that gets painted.
paintInfo.context->save();
RoundedRect roundedInnerRect = style()->getRoundedInnerBorderFor(paintRect,
paddingTop() + borderTop(), paddingBottom() + borderBottom(), paddingLeft() + borderLeft(), paddingRight() + borderRight(), true, true);
clipRoundedInnerRect(paintInfo.context, paintRect, roundedInnerRect);
}
}
if (!completelyClippedOut) {
if (paintInfo.phase == PaintPhaseClippingMask) {
paintClippingMask(paintInfo, adjustedPaintOffset);
} else {
paintReplaced(paintInfo, adjustedPaintOffset);
}
if (style()->hasBorderRadius())
paintInfo.context->restore();
}
// The selection tint never gets clipped by border-radius rounding, since we want it to run right up to the edges of
// surrounding content.
if (drawSelectionTint) {
LayoutRect selectionPaintingRect = localSelectionRect();
selectionPaintingRect.moveBy(adjustedPaintOffset);
paintInfo.context->fillRect(pixelSnappedIntRect(selectionPaintingRect), selectionBackgroundColor());
}
}
示例3: getRanges
void RenderNamedFlowThread::getRanges(Vector<RefPtr<Range> >& rangeObjects, const RenderRegion* region) const
{
LayoutUnit logicalTopForRegion;
LayoutUnit logicalBottomForRegion;
// extend the first region top to contain everything up to its logical height
if (region->isFirstRegion())
logicalTopForRegion = LayoutUnit::min();
else
logicalTopForRegion = region->logicalTopForFlowThreadContent();
// extend the last region to contain everything above its y()
if (region->isLastRegion())
logicalBottomForRegion = LayoutUnit::max();
else
logicalBottomForRegion = region->logicalBottomForFlowThreadContent();
Vector<Element*> elements;
// eliminate the contentElements that are descendants of other contentElements
for (auto it = contentElements().begin(), end = contentElements().end(); it != end; ++it) {
Element* element = *it;
if (!isContainedInElements(elements, element))
elements.append(element);
}
for (size_t i = 0; i < elements.size(); i++) {
Element* contentElement = elements.at(i);
if (!contentElement->renderer())
continue;
RefPtr<Range> range = Range::create(&contentElement->document());
bool foundStartPosition = false;
bool startsAboveRegion = true;
bool endsBelowRegion = true;
bool skipOverOutsideNodes = false;
Node* lastEndNode = 0;
for (Node* node = contentElement; node; node = nextNodeInsideContentElement(node, contentElement)) {
RenderObject* renderer = node->renderer();
if (!renderer)
continue;
LayoutRect boundingBox;
if (renderer->isRenderInline())
boundingBox = toRenderInline(renderer)->linesBoundingBox();
else if (renderer->isText())
boundingBox = toRenderText(renderer)->linesBoundingBox();
else {
boundingBox = toRenderBox(renderer)->frameRect();
if (toRenderBox(renderer)->isRelPositioned())
boundingBox.move(toRenderBox(renderer)->relativePositionLogicalOffset());
}
LayoutUnit offsetTop = renderer->containingBlock()->offsetFromLogicalTopOfFirstPage();
const LayoutPoint logicalOffsetFromTop(isHorizontalWritingMode() ? LayoutUnit() : offsetTop,
isHorizontalWritingMode() ? offsetTop : LayoutUnit());
boundingBox.moveBy(logicalOffsetFromTop);
LayoutUnit logicalTopForRenderer = region->logicalTopOfFlowThreadContentRect(boundingBox);
LayoutUnit logicalBottomForRenderer = region->logicalBottomOfFlowThreadContentRect(boundingBox);
// if the bounding box of the current element doesn't intersect the region box
// close the current range only if the start element began inside the region,
// otherwise just move the start position after this node and keep skipping them until we found a proper start position.
if (!boxIntersectsRegion(logicalTopForRenderer, logicalBottomForRenderer, logicalTopForRegion, logicalBottomForRegion)) {
if (foundStartPosition) {
if (!startsAboveRegion) {
if (range->intersectsNode(node, IGNORE_EXCEPTION))
range->setEndBefore(node, IGNORE_EXCEPTION);
rangeObjects.append(range->cloneRange(IGNORE_EXCEPTION));
range = Range::create(&contentElement->document());
startsAboveRegion = true;
} else
skipOverOutsideNodes = true;
}
if (skipOverOutsideNodes)
range->setStartAfter(node, IGNORE_EXCEPTION);
foundStartPosition = false;
continue;
}
// start position
if (logicalTopForRenderer < logicalTopForRegion && startsAboveRegion) {
if (renderer->isText()) { // Text crosses region top
// for Text elements, just find the last textbox that is contained inside the region and use its start() offset as start position
RenderText* textRenderer = toRenderText(renderer);
for (InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
if (offsetTop + box->logicalBottom() < logicalTopForRegion)
continue;
range->setStart(Position(toText(node), box->start()));
startsAboveRegion = false;
break;
}
} else { // node crosses region top
// for all elements, except Text, just set the start position to be before their children
startsAboveRegion = true;
range->setStart(Position(node, Position::PositionIsBeforeChildren));
}
} else { // node starts inside region
//.........这里部分代码省略.........
示例4: paintOutline
void InlinePainter::paintOutline(const PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
const ComputedStyle& styleToUse = m_layoutInline.styleRef();
if (!styleToUse.hasOutline())
return;
if (styleToUse.outlineStyleIsAuto()) {
if (LayoutTheme::theme().shouldDrawDefaultFocusRing(&m_layoutInline)) {
Vector<LayoutRect> focusRingRects;
m_layoutInline.addFocusRingRects(focusRingRects, paintOffset);
LayoutRect focusRingBoundingRect;
for (const auto& rect : focusRingRects)
focusRingBoundingRect.unite(rect);
LayoutObjectDrawingRecorder recorder(*paintInfo.context, m_layoutInline, paintInfo.phase, focusRingBoundingRect);
if (recorder.canUseCachedDrawing())
return;
// Only paint the focus ring by hand if the theme isn't able to draw the focus ring.
ObjectPainter(m_layoutInline).paintFocusRing(paintInfo, styleToUse, focusRingRects);
}
return;
}
if (styleToUse.outlineStyle() == BNONE)
return;
Vector<LayoutRect> rects;
rects.append(LayoutRect());
for (InlineFlowBox* curr = m_layoutInline.firstLineBox(); curr; curr = curr->nextLineBox()) {
RootInlineBox& root = curr->root();
LayoutUnit top = std::max<LayoutUnit>(root.lineTop(), curr->logicalTop());
LayoutUnit bottom = std::min<LayoutUnit>(root.lineBottom(), curr->logicalBottom());
rects.append(LayoutRect(curr->x(), top, curr->logicalWidth(), bottom - top));
}
rects.append(LayoutRect());
Color outlineColor = m_layoutInline.resolveColor(styleToUse, CSSPropertyOutlineColor);
bool useTransparencyLayer = outlineColor.hasAlpha();
int outlineWidth = styleToUse.outlineWidth();
LayoutRect bounds;
for (const auto& rect : rects) {
LayoutRect rectCopy(rect);
rectCopy.expand(LayoutSize(outlineWidth, outlineWidth));
bounds.unite(rectCopy);
}
bounds.moveBy(paintOffset);
LayoutObjectDrawingRecorder recorder(*paintInfo.context, m_layoutInline, paintInfo.phase, bounds);
if (recorder.canUseCachedDrawing())
return;
GraphicsContext* graphicsContext = paintInfo.context;
if (useTransparencyLayer) {
graphicsContext->beginLayer(static_cast<float>(outlineColor.alpha()) / 255);
outlineColor = Color(outlineColor.red(), outlineColor.green(), outlineColor.blue());
}
for (unsigned i = 1; i < rects.size() - 1; i++)
paintOutlineForLine(graphicsContext, paintOffset, rects.at(i - 1), rects.at(i), rects.at(i + 1), outlineColor);
if (useTransparencyLayer)
graphicsContext->endLayer();
}
示例5: paintObject
void BlockPainter::paintObject(const PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
if (RuntimeEnabledFeatures::slimmingPaintOffsetCachingEnabled() && m_layoutBlock.childrenInline() && !paintInfo.context.paintController().skippingCache()) {
if (m_layoutBlock.paintOffsetChanged(paintOffset)) {
LineBoxListPainter(m_layoutBlock.lineBoxes()).invalidateLineBoxPaintOffsets(paintInfo);
paintInfo.context.paintController().invalidatePaintOffset(m_layoutBlock);
}
// Set previousPaintOffset here in case that m_layoutBlock paints nothing and no
// LayoutObjectDrawingRecorder updates its previousPaintOffset.
// TODO(wangxianzhu): Integrate paint offset checking into new paint invalidation.
m_layoutBlock.mutableForPainting().setPreviousPaintOffset(paintOffset);
}
const PaintPhase paintPhase = paintInfo.phase;
if ((paintPhase == PaintPhaseSelfBlockBackground || paintPhase == PaintPhaseBlockBackground)
&& m_layoutBlock.style()->visibility() == VISIBLE
&& m_layoutBlock.hasBoxDecorationBackground())
m_layoutBlock.paintBoxDecorationBackground(paintInfo, paintOffset);
if (paintPhase == PaintPhaseMask && m_layoutBlock.style()->visibility() == VISIBLE) {
m_layoutBlock.paintMask(paintInfo, paintOffset);
return;
}
if (paintPhase == PaintPhaseClippingMask && m_layoutBlock.style()->visibility() == VISIBLE) {
BoxPainter(m_layoutBlock).paintClippingMask(paintInfo, paintOffset);
return;
}
// FIXME: When Skia supports annotation rect covering (https://code.google.com/p/skia/issues/detail?id=3872),
// this rect may be covered by foreground and descendant drawings. Then we may need a dedicated paint phase.
if (paintPhase == PaintPhaseForeground && paintInfo.isPrinting())
ObjectPainter(m_layoutBlock).addPDFURLRectIfNeeded(paintInfo, paintOffset);
{
Optional<ScrollRecorder> scrollRecorder;
Optional<PaintInfo> scrolledPaintInfo;
if (m_layoutBlock.hasOverflowClip()) {
IntSize scrollOffset = m_layoutBlock.scrolledContentOffset();
if (m_layoutBlock.layer()->scrollsOverflow() || !scrollOffset.isZero()) {
scrollRecorder.emplace(paintInfo.context, m_layoutBlock, paintPhase, scrollOffset);
scrolledPaintInfo.emplace(paintInfo);
AffineTransform transform;
transform.translate(-scrollOffset.width(), -scrollOffset.height());
scrolledPaintInfo->updateCullRect(transform);
}
}
// We're done. We don't bother painting any children.
if (paintPhase == PaintPhaseSelfBlockBackground || paintInfo.paintRootBackgroundOnly())
return;
const PaintInfo& contentsPaintInfo = scrolledPaintInfo ? *scrolledPaintInfo : paintInfo;
if (paintPhase != PaintPhaseSelfOutline)
paintContents(contentsPaintInfo, paintOffset);
if (paintPhase == PaintPhaseForeground && !paintInfo.isPrinting())
m_layoutBlock.paintSelection(contentsPaintInfo, paintOffset); // Fill in gaps in selection on lines and between blocks.
if (paintPhase == PaintPhaseFloat || paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip)
m_layoutBlock.paintFloats(contentsPaintInfo, paintOffset);
}
if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && m_layoutBlock.style()->hasOutline() && m_layoutBlock.style()->visibility() == VISIBLE)
ObjectPainter(m_layoutBlock).paintOutline(paintInfo, paintOffset);
// If the caret's node's layout object's containing block is this block, and the paint action is PaintPhaseForeground,
// then paint the caret.
if (paintPhase == PaintPhaseForeground && m_layoutBlock.hasCaret() && !LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(paintInfo.context, m_layoutBlock, DisplayItem::Caret, paintOffset)) {
LayoutRect bounds = m_layoutBlock.visualOverflowRect();
bounds.moveBy(paintOffset);
LayoutObjectDrawingRecorder recorder(paintInfo.context, m_layoutBlock, DisplayItem::Caret, bounds, paintOffset);
paintCarets(paintInfo, paintOffset);
}
}
示例6: paintReplaced
void RenderImage::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
LayoutUnit cWidth = contentWidth();
LayoutUnit cHeight = contentHeight();
LayoutUnit leftBorder = borderLeft();
LayoutUnit topBorder = borderTop();
LayoutUnit leftPad = paddingLeft();
LayoutUnit topPad = paddingTop();
GraphicsContext& context = paintInfo.context();
float deviceScaleFactor = document().deviceScaleFactor();
Page* page = frame().page();
if (!imageResource().hasImage() || imageResource().errorOccurred()) {
if (paintInfo.phase == PaintPhaseSelection)
return;
if (page && paintInfo.phase == PaintPhaseForeground)
page->addRelevantUnpaintedObject(this, visualOverflowRect());
if (cWidth > 2 && cHeight > 2) {
LayoutUnit borderWidth = LayoutUnit(1 / deviceScaleFactor);
// Draw an outline rect where the image should be.
context.setStrokeStyle(SolidStroke);
context.setStrokeColor(Color::lightGray, style().colorSpace());
context.setFillColor(Color::transparent, style().colorSpace());
context.drawRect(snapRectToDevicePixels(LayoutRect(paintOffset.x() + leftBorder + leftPad, paintOffset.y() + topBorder + topPad, cWidth, cHeight), deviceScaleFactor), borderWidth);
bool errorPictureDrawn = false;
LayoutSize imageOffset;
// When calculating the usable dimensions, exclude the pixels of
// the ouline rect so the error image/alt text doesn't draw on it.
LayoutUnit usableWidth = cWidth - 2 * borderWidth;
LayoutUnit usableHeight = cHeight - 2 * borderWidth;
RefPtr<Image> image = imageResource().image();
if (imageResource().errorOccurred() && !image->isNull() && usableWidth >= image->width() && usableHeight >= image->height()) {
// Call brokenImage() explicitly to ensure we get the broken image icon at the appropriate resolution.
std::pair<Image*, float> brokenImageAndImageScaleFactor = imageResource().cachedImage()->brokenImage(document().deviceScaleFactor());
image = brokenImageAndImageScaleFactor.first;
FloatSize imageSize = image->size();
imageSize.scale(1 / brokenImageAndImageScaleFactor.second);
// Center the error image, accounting for border and padding.
LayoutUnit centerX = (usableWidth - imageSize.width()) / 2;
if (centerX < 0)
centerX = 0;
LayoutUnit centerY = (usableHeight - imageSize.height()) / 2;
if (centerY < 0)
centerY = 0;
imageOffset = LayoutSize(leftBorder + leftPad + centerX + borderWidth, topBorder + topPad + centerY + borderWidth);
ImageOrientationDescription orientationDescription(shouldRespectImageOrientation());
#if ENABLE(CSS_IMAGE_ORIENTATION)
orientationDescription.setImageOrientationEnum(style().imageOrientation());
#endif
context.drawImage(*image, style().colorSpace(), snapRectToDevicePixels(LayoutRect(paintOffset + imageOffset, imageSize), deviceScaleFactor), orientationDescription);
errorPictureDrawn = true;
}
if (!m_altText.isEmpty()) {
String text = document().displayStringModifiedByEncoding(m_altText);
context.setFillColor(style().visitedDependentColor(CSSPropertyColor), style().colorSpace());
const FontCascade& font = style().fontCascade();
const FontMetrics& fontMetrics = font.fontMetrics();
LayoutUnit ascent = fontMetrics.ascent();
LayoutPoint altTextOffset = paintOffset;
altTextOffset.move(leftBorder + leftPad + (paddingWidth / 2) - borderWidth, topBorder + topPad + ascent + (paddingHeight / 2) - borderWidth);
// Only draw the alt text if it'll fit within the content box,
// and only if it fits above the error image.
TextRun textRun = RenderBlock::constructTextRun(this, font, text, style());
LayoutUnit textWidth = font.width(textRun);
if (errorPictureDrawn) {
if (usableWidth >= textWidth && fontMetrics.height() <= imageOffset.height())
context.drawText(font, textRun, altTextOffset);
} else if (usableWidth >= textWidth && usableHeight >= fontMetrics.height())
context.drawText(font, textRun, altTextOffset);
}
}
} else if (imageResource().hasImage() && cWidth > 0 && cHeight > 0) {
RefPtr<Image> img = imageResource().image(cWidth, cHeight);
if (!img || img->isNull()) {
if (page && paintInfo.phase == PaintPhaseForeground)
page->addRelevantUnpaintedObject(this, visualOverflowRect());
return;
}
LayoutRect contentBoxRect = this->contentBoxRect();
contentBoxRect.moveBy(paintOffset);
LayoutRect replacedContentRect = this->replacedContentRect(intrinsicSize());
replacedContentRect.moveBy(paintOffset);
bool clip = !contentBoxRect.contains(replacedContentRect);
GraphicsContextStateSaver stateSaver(context, clip);
if (clip)
context.clip(contentBoxRect);
paintIntoRect(context, snapRectToDevicePixels(replacedContentRect, deviceScaleFactor));
//.........这里部分代码省略.........
示例7: calculateRects
void PaintLayerClipper::calculateRects(
const ClipRectsContext& context,
const LayoutRect& paintDirtyRect,
LayoutRect& layerBounds,
ClipRect& backgroundRect,
ClipRect& foregroundRect,
const LayoutPoint* offsetFromRoot) const {
if (m_geometryMapper) {
calculateRectsWithGeometryMapper(context, paintDirtyRect, layerBounds,
backgroundRect, foregroundRect,
offsetFromRoot);
return;
}
bool isClippingRoot = &m_layer == context.rootLayer;
LayoutBoxModelObject& layoutObject = *m_layer.layoutObject();
if (!isClippingRoot && m_layer.parent()) {
backgroundRect = backgroundClipRect(context);
backgroundRect.move(context.subPixelAccumulation);
backgroundRect.intersect(paintDirtyRect);
} else {
backgroundRect = paintDirtyRect;
}
foregroundRect = backgroundRect;
LayoutPoint offset;
if (offsetFromRoot)
offset = *offsetFromRoot;
else
m_layer.convertToLayerCoords(context.rootLayer, offset);
layerBounds = LayoutRect(offset, LayoutSize(m_layer.size()));
// Update the clip rects that will be passed to child layers.
if (shouldClipOverflow(context)) {
foregroundRect.intersect(
toLayoutBox(layoutObject)
.overflowClipRect(offset, context.overlayScrollbarClipBehavior));
if (layoutObject.styleRef().hasBorderRadius())
foregroundRect.setHasRadius(true);
// FIXME: Does not do the right thing with columns yet, since we don't yet
// factor in the individual column boxes as overflow.
// The LayoutView is special since its overflow clipping rect may be larger
// than its box rect (crbug.com/492871).
LayoutRect layerBoundsWithVisualOverflow =
layoutObject.isLayoutView()
? toLayoutView(layoutObject).viewRect()
: toLayoutBox(layoutObject).visualOverflowRect();
// PaintLayer are in physical coordinates, so the overflow has to be
// flipped.
toLayoutBox(layoutObject).flipForWritingMode(layerBoundsWithVisualOverflow);
layerBoundsWithVisualOverflow.moveBy(offset);
backgroundRect.intersect(layerBoundsWithVisualOverflow);
}
// CSS clip (different than clipping due to overflow) can clip to any box,
// even if it falls outside of the border box.
if (layoutObject.hasClip()) {
// Clip applies to *us* as well, so go ahead and update the damageRect.
LayoutRect newPosClip = toLayoutBox(layoutObject).clipRect(offset);
backgroundRect.intersect(newPosClip);
backgroundRect.setIsClippedByClipCss();
foregroundRect.intersect(newPosClip);
foregroundRect.setIsClippedByClipCss();
}
}
示例8: paintObject
void TableSectionPainter::paintObject(const PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
LayoutRect localPaintInvalidationRect = LayoutRect(paintInfo.rect);
localPaintInvalidationRect.moveBy(-paintOffset);
LayoutRect tableAlignedRect = m_layoutTableSection.logicalRectForWritingModeAndDirection(localPaintInvalidationRect);
CellSpan dirtiedRows = m_layoutTableSection.dirtiedRows(tableAlignedRect);
CellSpan dirtiedColumns = m_layoutTableSection.dirtiedColumns(tableAlignedRect);
HashSet<LayoutTableCell*> overflowingCells = m_layoutTableSection.overflowingCells();
if (dirtiedColumns.start() < dirtiedColumns.end()) {
if (!m_layoutTableSection.hasMultipleCellLevels() && !overflowingCells.size()) {
if (paintInfo.phase == PaintPhaseCollapsedTableBorders) {
// Collapsed borders are painted from the bottom right to the top left so that precedence
// due to cell position is respected.
for (unsigned r = dirtiedRows.end(); r > dirtiedRows.start(); r--) {
unsigned row = r - 1;
for (unsigned c = dirtiedColumns.end(); c > dirtiedColumns.start(); c--) {
unsigned col = c - 1;
LayoutTableSection::CellStruct& current = m_layoutTableSection.cellAt(row, col);
LayoutTableCell* cell = current.primaryCell();
if (!cell || (row > dirtiedRows.start() && m_layoutTableSection.primaryCellAt(row - 1, col) == cell) || (col > dirtiedColumns.start() && m_layoutTableSection.primaryCellAt(row, col - 1) == cell))
continue;
LayoutPoint cellPoint = m_layoutTableSection.flipForWritingModeForChild(cell, paintOffset);
TableCellPainter(*cell).paintCollapsedBorders(paintInfo, cellPoint);
}
}
} else {
// Draw the dirty cells in the order that they appear.
for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) {
LayoutTableRow* row = m_layoutTableSection.rowRendererAt(r);
if (row && !row->hasSelfPaintingLayer())
TableRowPainter(*row).paintOutlineForRowIfNeeded(paintInfo, paintOffset);
for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) {
LayoutTableSection::CellStruct& current = m_layoutTableSection.cellAt(r, c);
LayoutTableCell* cell = current.primaryCell();
if (!cell || (r > dirtiedRows.start() && m_layoutTableSection.primaryCellAt(r - 1, c) == cell) || (c > dirtiedColumns.start() && m_layoutTableSection.primaryCellAt(r, c - 1) == cell))
continue;
paintCell(cell, paintInfo, paintOffset);
}
}
}
} else {
// The overflowing cells should be scarce to avoid adding a lot of cells to the HashSet.
#if ENABLE(ASSERT)
unsigned totalRows = m_layoutTableSection.numRows();
unsigned totalCols = m_layoutTableSection.table()->columns().size();
ASSERT(overflowingCells.size() < totalRows * totalCols * gMaxAllowedOverflowingCellRatioForFastPaintPath);
#endif
// To make sure we properly paint invalidate the section, we paint invalidated all the overflowing cells that we collected.
Vector<LayoutTableCell*> cells;
copyToVector(overflowingCells, cells);
HashSet<LayoutTableCell*> spanningCells;
for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) {
LayoutTableRow* row = m_layoutTableSection.rowRendererAt(r);
if (row && !row->hasSelfPaintingLayer())
TableRowPainter(*row).paintOutlineForRowIfNeeded(paintInfo, paintOffset);
for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) {
LayoutTableSection::CellStruct& current = m_layoutTableSection.cellAt(r, c);
if (!current.hasCells())
continue;
for (unsigned i = 0; i < current.cells.size(); ++i) {
if (overflowingCells.contains(current.cells[i]))
continue;
if (current.cells[i]->rowSpan() > 1 || current.cells[i]->colSpan() > 1) {
if (!spanningCells.add(current.cells[i]).isNewEntry)
continue;
}
cells.append(current.cells[i]);
}
}
}
// Sort the dirty cells by paint order.
if (!overflowingCells.size())
std::stable_sort(cells.begin(), cells.end(), compareCellPositions);
else
std::sort(cells.begin(), cells.end(), compareCellPositionsWithOverflowingCells);
if (paintInfo.phase == PaintPhaseCollapsedTableBorders) {
for (unsigned i = cells.size(); i > 0; --i) {
LayoutPoint cellPoint = m_layoutTableSection.flipForWritingModeForChild(cells[i - 1], paintOffset);
TableCellPainter(*cells[i - 1]).paintCollapsedBorders(paintInfo, cellPoint);
}
} else {
for (unsigned i = 0; i < cells.size(); ++i)
paintCell(cells[i], paintInfo, paintOffset);
}
}
}
}
示例9: paint
void PartPainter::paint(const PaintInfo& paintInfo,
const LayoutPoint& paintOffset) {
LayoutPoint adjustedPaintOffset = paintOffset + m_layoutPart.location();
if (!ReplacedPainter(m_layoutPart)
.shouldPaint(paintInfo, adjustedPaintOffset))
return;
LayoutRect borderRect(adjustedPaintOffset, m_layoutPart.size());
if (m_layoutPart.hasBoxDecorationBackground() &&
(paintInfo.phase == PaintPhaseForeground ||
paintInfo.phase == PaintPhaseSelection))
BoxPainter(m_layoutPart)
.paintBoxDecorationBackground(paintInfo, adjustedPaintOffset);
if (paintInfo.phase == PaintPhaseMask) {
BoxPainter(m_layoutPart).paintMask(paintInfo, adjustedPaintOffset);
return;
}
if (shouldPaintSelfOutline(paintInfo.phase))
ObjectPainter(m_layoutPart).paintOutline(paintInfo, adjustedPaintOffset);
if (paintInfo.phase != PaintPhaseForeground)
return;
if (m_layoutPart.widget()) {
// TODO(schenney) crbug.com/93805 Speculative release assert to verify that
// the crashes we see in widget painting are due to a destroyed LayoutPart
// object.
CHECK(m_layoutPart.node());
Optional<RoundedInnerRectClipper> clipper;
if (m_layoutPart.style()->hasBorderRadius()) {
if (borderRect.isEmpty())
return;
FloatRoundedRect roundedInnerRect =
m_layoutPart.style()->getRoundedInnerBorderFor(
borderRect,
LayoutRectOutsets(
-(m_layoutPart.paddingTop() + m_layoutPart.borderTop()),
-(m_layoutPart.paddingRight() + m_layoutPart.borderRight()),
-(m_layoutPart.paddingBottom() + m_layoutPart.borderBottom()),
-(m_layoutPart.paddingLeft() + m_layoutPart.borderLeft())),
true, true);
clipper.emplace(m_layoutPart, paintInfo, borderRect, roundedInnerRect,
ApplyToDisplayList);
}
m_layoutPart.paintContents(paintInfo, paintOffset);
}
// Paint a partially transparent wash over selected widgets.
if (isSelected() && !paintInfo.isPrinting() &&
!LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(
paintInfo.context, m_layoutPart, paintInfo.phase)) {
LayoutRect rect = m_layoutPart.localSelectionRect();
rect.moveBy(adjustedPaintOffset);
IntRect selectionRect = pixelSnappedIntRect(rect);
LayoutObjectDrawingRecorder drawingRecorder(paintInfo.context, m_layoutPart,
paintInfo.phase, selectionRect);
paintInfo.context.fillRect(selectionRect,
m_layoutPart.selectionBackgroundColor());
}
if (m_layoutPart.canResize())
ScrollableAreaPainter(*m_layoutPart.layer()->getScrollableArea())
.paintResizer(paintInfo.context, roundedIntPoint(adjustedPaintOffset),
paintInfo.cullRect());
}
示例10: calculate
void BackgroundImageGeometry::calculate(
const LayoutBoxModelObject& obj,
const LayoutBoxModelObject* paintContainer,
const GlobalPaintFlags globalPaintFlags,
const FillLayer& fillLayer,
const LayoutRect& paintRect) {
LayoutUnit left;
LayoutUnit top;
LayoutSize positioningAreaSize;
bool isLayoutView = obj.isLayoutView();
const LayoutBox* rootBox = nullptr;
if (isLayoutView) {
// It is only possible reach here when root element has a box.
Element* documentElement = obj.document().documentElement();
DCHECK(documentElement);
DCHECK(documentElement->layoutObject());
DCHECK(documentElement->layoutObject()->isBox());
rootBox = toLayoutBox(documentElement->layoutObject());
}
const LayoutBoxModelObject& positioningBox =
isLayoutView ? static_cast<const LayoutBoxModelObject&>(*rootBox) : obj;
// Determine the background positioning area and set destRect to the
// background painting area. destRect will be adjusted later if the
// background is non-repeating.
// FIXME: transforms spec says that fixed backgrounds behave like scroll
// inside transforms.
bool fixedAttachment = fillLayer.attachment() == FixedBackgroundAttachment;
if (RuntimeEnabledFeatures::fastMobileScrollingEnabled()) {
// As a side effect of an optimization to blit on scroll, we do not honor
// the CSS property "background-attachment: fixed" because it may result in
// rendering artifacts. Note, these artifacts only appear if we are blitting
// on scroll of a page that has fixed background images.
fixedAttachment = false;
}
if (!fixedAttachment) {
setDestRect(paintRect);
LayoutUnit right;
LayoutUnit bottom;
// Scroll and Local.
if (fillLayer.origin() != BorderFillBox) {
left = LayoutUnit(positioningBox.borderLeft());
right = LayoutUnit(positioningBox.borderRight());
top = LayoutUnit(positioningBox.borderTop());
bottom = LayoutUnit(positioningBox.borderBottom());
if (fillLayer.origin() == ContentFillBox) {
left += positioningBox.paddingLeft();
right += positioningBox.paddingRight();
top += positioningBox.paddingTop();
bottom += positioningBox.paddingBottom();
}
}
if (isLayoutView) {
// The background of the box generated by the root element covers the
// entire canvas and will be painted by the view object, but the we should
// still use the root element box for positioning.
positioningAreaSize =
rootBox->size() - LayoutSize(left + right, top + bottom),
rootBox->location();
// The input paint rect is specified in root element local coordinate
// (i.e. a transform is applied on the context for painting), and is
// expanded to cover the whole canvas. Since left/top is relative to the
// paint rect, we need to offset them back.
left -= paintRect.x();
top -= paintRect.y();
} else {
positioningAreaSize =
paintRect.size() - LayoutSize(left + right, top + bottom);
}
} else {
setHasNonLocalGeometry();
LayoutRect viewportRect = obj.viewRect();
if (fixedBackgroundPaintsInLocalCoordinates(obj, globalPaintFlags)) {
viewportRect.setLocation(LayoutPoint());
} else {
if (FrameView* frameView = obj.view()->frameView())
viewportRect.setLocation(IntPoint(frameView->scrollOffsetInt()));
// Compensate the translations created by ScrollRecorders.
// TODO(trchen): Fix this for SP phase 2. crbug.com/529963.
viewportRect.moveBy(
accumulatedScrollOffsetForFixedBackground(obj, paintContainer));
}
if (paintContainer)
viewportRect.moveBy(
LayoutPoint(-paintContainer->localToAbsolute(FloatPoint())));
setDestRect(viewportRect);
positioningAreaSize = destRect().size();
}
LayoutSize fillTileSize(
calculateFillTileSize(positioningBox, fillLayer, positioningAreaSize));
// It's necessary to apply the heuristic here prior to any further
// calculations to avoid incorrectly using sub-pixel values that won't be
//.........这里部分代码省略.........
示例11: paint
void RenderReplaced::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
if (!shouldPaint(paintInfo, paintOffset))
return;
#ifndef NDEBUG
SetLayoutNeededForbiddenScope scope(this);
#endif
LayoutPoint adjustedPaintOffset = paintOffset + location();
if (hasVisibleBoxDecorations() && paintInfo.phase == PaintPhaseForeground)
paintBoxDecorations(paintInfo, adjustedPaintOffset);
if (paintInfo.phase == PaintPhaseMask) {
paintMask(paintInfo, adjustedPaintOffset);
return;
}
LayoutRect paintRect = LayoutRect(adjustedPaintOffset, size());
if (paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) {
if (style().outlineWidth())
paintOutline(paintInfo, paintRect);
return;
}
if (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection)
return;
if (!paintInfo.shouldPaintWithinRoot(*this))
return;
bool drawSelectionTint = shouldDrawSelectionTint();
if (paintInfo.phase == PaintPhaseSelection) {
if (selectionState() == SelectionNone)
return;
drawSelectionTint = false;
}
bool completelyClippedOut = false;
if (style().hasBorderRadius()) {
LayoutRect borderRect = LayoutRect(adjustedPaintOffset, size());
if (borderRect.isEmpty())
completelyClippedOut = true;
else {
// Push a clip if we have a border radius, since we want to round the foreground content that gets painted.
paintInfo.context().save();
FloatRoundedRect roundedInnerRect = FloatRoundedRect(style().getRoundedInnerBorderFor(paintRect,
paddingTop() + borderTop(), paddingBottom() + borderBottom(), paddingLeft() + borderLeft(), paddingRight() + borderRight(), true, true));
clipRoundedInnerRect(paintInfo.context(), paintRect, roundedInnerRect);
}
}
if (!completelyClippedOut) {
paintReplaced(paintInfo, adjustedPaintOffset);
if (style().hasBorderRadius())
paintInfo.context().restore();
}
// The selection tint never gets clipped by border-radius rounding, since we want it to run right up to the edges of
// surrounding content.
if (drawSelectionTint) {
LayoutRect selectionPaintingRect = localSelectionRect();
selectionPaintingRect.moveBy(adjustedPaintOffset);
paintInfo.context().fillRect(snappedIntRect(selectionPaintingRect), selectionBackgroundColor());
}
}
示例12: controlClipRect
LayoutRect LayoutTextControlSingleLine::controlClipRect(const LayoutPoint& additionalOffset) const
{
LayoutRect clipRect = paddingBoxRect();
clipRect.moveBy(additionalOffset);
return clipRect;
}
示例13: paint
void ListMarkerPainter::paint(const PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
if (paintInfo.phase != PaintPhaseForeground)
return;
if (m_layoutListMarker.style()->visibility() != VISIBLE)
return;
if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(paintInfo.context, m_layoutListMarker, paintInfo.phase, paintOffset))
return;
LayoutPoint boxOrigin(paintOffset + m_layoutListMarker.location());
LayoutRect overflowRect(m_layoutListMarker.visualOverflowRect());
overflowRect.moveBy(boxOrigin);
IntRect pixelSnappedOverflowRect = pixelSnappedIntRect(overflowRect);
if (!paintInfo.cullRect().intersectsCullRect(overflowRect))
return;
LayoutObjectDrawingRecorder recorder(paintInfo.context, m_layoutListMarker, paintInfo.phase, pixelSnappedOverflowRect, paintOffset);
LayoutRect box(boxOrigin, m_layoutListMarker.size());
IntRect marker = m_layoutListMarker.getRelativeMarkerRect();
marker.moveBy(roundedIntPoint(boxOrigin));
GraphicsContext& context = paintInfo.context;
if (m_layoutListMarker.isImage()) {
context.drawImage(m_layoutListMarker.image()->image(
&m_layoutListMarker, marker.size(), m_layoutListMarker.styleRef().effectiveZoom()).get(), marker);
if (m_layoutListMarker.getSelectionState() != SelectionNone) {
LayoutRect selRect = m_layoutListMarker.localSelectionRect();
selRect.moveBy(boxOrigin);
context.fillRect(pixelSnappedIntRect(selRect), m_layoutListMarker.listItem()->selectionBackgroundColor());
}
return;
}
LayoutListMarker::ListStyleCategory styleCategory = m_layoutListMarker.listStyleCategory();
if (styleCategory == LayoutListMarker::ListStyleCategory::None)
return;
const Color color(m_layoutListMarker.resolveColor(CSSPropertyColor));
// Apply the color to the list marker text.
context.setFillColor(color);
const EListStyleType listStyle = m_layoutListMarker.style()->listStyleType();
if (styleCategory == LayoutListMarker::ListStyleCategory::Symbol) {
paintSymbol(context, color, marker, listStyle);
return;
}
if (m_layoutListMarker.text().isEmpty())
return;
const Font& font = m_layoutListMarker.style()->font();
TextRun textRun = constructTextRun(font, m_layoutListMarker.text(), m_layoutListMarker.styleRef());
GraphicsContextStateSaver stateSaver(context, false);
if (!m_layoutListMarker.style()->isHorizontalWritingMode()) {
marker.moveBy(roundedIntPoint(-boxOrigin));
marker = marker.transposedRect();
marker.moveBy(IntPoint(roundToInt(box.x()), roundToInt(box.y() - m_layoutListMarker.logicalHeight())));
stateSaver.save();
context.translate(marker.x(), marker.maxY());
context.rotate(static_cast<float>(deg2rad(90.)));
context.translate(-marker.x(), -marker.maxY());
}
TextRunPaintInfo textRunPaintInfo(textRun);
textRunPaintInfo.bounds = marker;
IntPoint textOrigin = IntPoint(marker.x(), marker.y() + m_layoutListMarker.style()->fontMetrics().ascent());
// Text is not arbitrary. We can judge whether it's RTL from the first character,
// and we only need to handle the direction RightToLeft for now.
bool textNeedsReversing = WTF::Unicode::direction(m_layoutListMarker.text()[0]) == WTF::Unicode::RightToLeft;
StringBuilder reversedText;
if (textNeedsReversing) {
unsigned length = m_layoutListMarker.text().length();
reversedText.reserveCapacity(length);
for (int i = length - 1; i >= 0; --i)
reversedText.append(m_layoutListMarker.text()[i]);
ASSERT(reversedText.length() == length);
textRun.setText(reversedText.toString());
}
const UChar suffix = ListMarkerText::suffix(listStyle, m_layoutListMarker.listItem()->value());
UChar suffixStr[2] = { suffix, static_cast<UChar>(' ') };
TextRun suffixRun = constructTextRun(font, suffixStr, 2, m_layoutListMarker.styleRef(), m_layoutListMarker.style()->direction());
TextRunPaintInfo suffixRunInfo(suffixRun);
suffixRunInfo.bounds = marker;
if (m_layoutListMarker.style()->isLeftToRightDirection()) {
context.drawText(font, textRunPaintInfo, textOrigin);
context.drawText(font, suffixRunInfo, textOrigin + IntSize(font.width(textRun), 0));
} else {
context.drawText(font, suffixRunInfo, textOrigin);
context.drawText(font, textRunPaintInfo, textOrigin + IntSize(font.width(suffixRun), 0));
}
//.........这里部分代码省略.........