本文整理汇总了C++中PaintInfo类的典型用法代码示例。如果您正苦于以下问题:C++ PaintInfo类的具体用法?C++ PaintInfo怎么用?C++ PaintInfo使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了PaintInfo类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: paintObject
void TableSectionPainter::paintObject(const PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
LayoutRect localPaintInvalidationRect = LayoutRect(paintInfo.cullRect().m_rect);
localPaintInvalidationRect.moveBy(-paintOffset);
LayoutRect tableAlignedRect = m_layoutTableSection.logicalRectForWritingModeAndDirection(localPaintInvalidationRect);
CellSpan dirtiedRows = m_layoutTableSection.dirtiedRows(tableAlignedRect);
CellSpan dirtiedColumns = m_layoutTableSection.dirtiedColumns(tableAlignedRect);
if (dirtiedColumns.start() >= dirtiedColumns.end())
return;
const HashSet<LayoutTableCell*>& overflowingCells = m_layoutTableSection.overflowingCells();
if (!m_layoutTableSection.hasMultipleCellLevels() && !overflowingCells.size()) {
// Draw the dirty cells in the order that they appear.
for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) {
const LayoutTableRow* row = m_layoutTableSection.rowLayoutObjectAt(r);
if (row && !row->hasSelfPaintingLayer())
TableRowPainter(*row).paintOutlineForRowIfNeeded(paintInfo, paintOffset);
for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) {
const LayoutTableSection::CellStruct& current = m_layoutTableSection.cellAt(r, c);
const 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++) {
const LayoutTableRow* row = m_layoutTableSection.rowLayoutObjectAt(r);
if (row && !row->hasSelfPaintingLayer())
TableRowPainter(*row).paintOutlineForRowIfNeeded(paintInfo, paintOffset);
for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) {
const 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);
for (unsigned i = 0; i < cells.size(); ++i)
paintCell(*cells[i], paintInfo, paintOffset);
}
}
示例2: frame
void RenderSVGRoot::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
// An empty viewport disables rendering.
if (borderBoxRect().isEmpty())
return;
// Don't paint, if the context explicitly disabled it.
if (paintInfo.context().paintingDisabled())
return;
// SVG outlines are painted during PaintPhaseForeground.
if (paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline)
return;
// An empty viewBox also disables rendering.
// (http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute)
if (svgSVGElement().hasEmptyViewBox())
return;
Page* page = frame().page();
// Don't paint if we don't have kids, except if we have filters we should paint those.
if (!firstChild()) {
auto* resources = SVGResourcesCache::cachedResourcesForRenderer(*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
if (shouldApplyViewportClip())
childPaintInfo.context().clip(snappedIntRect(overflowClipRect(paintOffset, currentRenderNamedFlowFragment())));
// 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) {
childPaintInfo.updateSubtreePaintRootForChildren(this);
for (auto& child : childrenOfType<RenderElement>(*this))
child.paint(childPaintInfo, location());
}
}
childPaintInfo.context().restore();
}
示例3: paint
void ReplacedPainter::paint(const PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
if (!m_layoutReplaced.shouldPaint(paintInfo, paintOffset))
return;
LayoutPoint adjustedPaintOffset = paintOffset + m_layoutReplaced.location();
LayoutRect borderRect(adjustedPaintOffset, m_layoutReplaced.size());
if (m_layoutReplaced.hasBoxDecorationBackground() && (paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection))
m_layoutReplaced.paintBoxDecorationBackground(paintInfo, adjustedPaintOffset);
if (paintInfo.phase == PaintPhaseMask) {
m_layoutReplaced.paintMask(paintInfo, adjustedPaintOffset);
return;
}
if (paintInfo.phase == PaintPhaseClippingMask && (!m_layoutReplaced.hasLayer() || !m_layoutReplaced.layer()->hasCompositedClippingMask()))
return;
if (paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) {
if (m_layoutReplaced.styleRef().outlineWidth())
ObjectPainter(m_layoutReplaced).paintOutline(paintInfo, adjustedPaintOffset);
return;
}
if (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection && !m_layoutReplaced.canHaveChildren() && paintInfo.phase != PaintPhaseClippingMask)
return;
if (!paintInfo.shouldPaintWithinRoot(&m_layoutReplaced))
return;
if (paintInfo.phase == PaintPhaseSelection)
if (m_layoutReplaced.selectionState() == SelectionNone)
return;
{
Optional<RoundedInnerRectClipper> clipper;
bool completelyClippedOut = false;
if (m_layoutReplaced.style()->hasBorderRadius()) {
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.
FloatRoundedRect roundedInnerRect = m_layoutReplaced.style()->getRoundedInnerBorderFor(borderRect,
LayoutRectOutsets(
-(m_layoutReplaced.paddingTop() + m_layoutReplaced.borderTop()),
-(m_layoutReplaced.paddingRight() + m_layoutReplaced.borderRight()),
-(m_layoutReplaced.paddingBottom() + m_layoutReplaced.borderBottom()),
-(m_layoutReplaced.paddingLeft() + m_layoutReplaced.borderLeft())),
true, true);
clipper.emplace(m_layoutReplaced, paintInfo, borderRect, roundedInnerRect, ApplyToDisplayList);
}
}
if (!completelyClippedOut) {
if (paintInfo.phase == PaintPhaseClippingMask) {
BoxPainter(m_layoutReplaced).paintClippingMask(paintInfo, adjustedPaintOffset);
} else {
m_layoutReplaced.paintReplaced(paintInfo, adjustedPaintOffset);
}
}
}
// The selection tint never gets clipped by border-radius rounding, since we want it to run right up to the edges of
// surrounding content.
bool drawSelectionTint = paintInfo.phase == PaintPhaseForeground && m_layoutReplaced.selectionState() != SelectionNone && !paintInfo.isPrinting();
if (drawSelectionTint && !LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(*paintInfo.context, m_layoutReplaced, DisplayItem::SelectionTint, adjustedPaintOffset)) {
LayoutRect selectionPaintingRect = m_layoutReplaced.localSelectionRect();
selectionPaintingRect.moveBy(adjustedPaintOffset);
IntRect selectionPaintingIntRect = pixelSnappedIntRect(selectionPaintingRect);
LayoutObjectDrawingRecorder drawingRecorder(*paintInfo.context, m_layoutReplaced, DisplayItem::SelectionTint, selectionPaintingIntRect, adjustedPaintOffset);
paintInfo.context->fillRect(selectionPaintingIntRect, m_layoutReplaced.selectionBackgroundColor());
}
}
示例4: paintBoxDecorationBackground
void ViewPainter::paintBoxDecorationBackground(const PaintInfo& paintInfo) {
if (paintInfo.skipRootBackground())
return;
// This function overrides background painting for the LayoutView.
// View background painting is special in the following ways:
// 1. The view paints background for the root element, the background
// positioning respects the positioning and transformation of the root
// element.
// 2. CSS background-clip is ignored, the background layers always expand to
// cover the whole canvas. None of the stacking context effects (except
// transformation) on the root element affects the background.
// 3. The main frame is also responsible for painting the user-agent-defined
// base background color. Conceptually it should be painted by the embedder
// but painting it here allows culling and pre-blending optimization when
// possible.
GraphicsContext& context = paintInfo.context;
if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(
context, m_layoutView, DisplayItem::kDocumentBackground))
return;
// The background fill rect is the size of the LayoutView's main
// GraphicsLayer.
IntRect backgroundRect =
pixelSnappedIntRect(m_layoutView.layer()->boundingBoxForCompositing());
const Document& document = m_layoutView.document();
const FrameView& frameView = *m_layoutView.frameView();
bool isMainFrame = document.isInMainFrame();
bool paintsBaseBackground = isMainFrame && !frameView.isTransparent();
bool shouldClearCanvas =
paintsBaseBackground &&
(document.settings() &&
document.settings()->shouldClearDocumentBackground());
Color baseBackgroundColor =
paintsBaseBackground ? frameView.baseBackgroundColor() : Color();
Color rootBackgroundColor =
m_layoutView.style()->visitedDependentColor(CSSPropertyBackgroundColor);
const LayoutObject* rootObject =
document.documentElement() ? document.documentElement()->layoutObject()
: nullptr;
LayoutObjectDrawingRecorder recorder(
context, m_layoutView, DisplayItem::kDocumentBackground, backgroundRect);
// Special handling for print economy mode.
bool forceBackgroundToWhite =
BoxPainter::shouldForceWhiteBackgroundForPrintEconomy(
m_layoutView.styleRef(), document);
if (forceBackgroundToWhite) {
// If for any reason the view background is not transparent, paint white
// instead, otherwise keep transparent as is.
if (paintsBaseBackground || rootBackgroundColor.alpha() ||
m_layoutView.style()->backgroundLayers().image())
context.fillRect(backgroundRect, Color::white, SkBlendMode::kSrc);
return;
}
// Compute the enclosing rect of the view, in root element space.
//
// For background colors we can simply paint the document rect in the default
// space. However for background image, the root element transform applies.
// The strategy is to apply root element transform on the context and issue
// draw commands in the local space, therefore we need to apply inverse
// transform on the document rect to get to the root element space.
bool backgroundRenderable = true;
TransformationMatrix transform;
IntRect paintRect = backgroundRect;
if (!rootObject || !rootObject->isBox()) {
backgroundRenderable = false;
} else if (rootObject->hasLayer()) {
const PaintLayer& rootLayer = *toLayoutBoxModelObject(rootObject)->layer();
LayoutPoint offset;
rootLayer.convertToLayerCoords(nullptr, offset);
transform.translate(offset.x(), offset.y());
transform.multiply(
rootLayer.renderableTransform(paintInfo.getGlobalPaintFlags()));
if (!transform.isInvertible()) {
backgroundRenderable = false;
} else {
bool isClamped;
paintRect = transform.inverse()
.projectQuad(FloatQuad(backgroundRect), &isClamped)
.enclosingBoundingBox();
backgroundRenderable = !isClamped;
}
}
if (!backgroundRenderable) {
if (baseBackgroundColor.alpha()) {
context.fillRect(
backgroundRect, baseBackgroundColor,
shouldClearCanvas ? SkBlendMode::kSrc : SkBlendMode::kSrcOver);
} else if (shouldClearCanvas) {
context.fillRect(backgroundRect, Color(), SkBlendMode::kClear);
}
return;
}
//.........这里部分代码省略.........
示例5: DCHECK
void BlockPainter::paintContents(const PaintInfo& paintInfo,
const LayoutPoint& paintOffset) {
DCHECK(!m_layoutBlock.childrenInline());
PaintInfo paintInfoForDescendants = paintInfo.forDescendants();
m_layoutBlock.paintChildren(paintInfoForDescendants, paintOffset);
}
示例6: 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());
}
}
示例7: 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 (hasBoxDecorations() && 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) && style().outlineWidth())
paintOutline(paintInfo, paintRect);
if (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection && !canHaveChildren())
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(), style().colorSpace());
}
}
示例8: ruleThickness
void RenderMathMLMenclose::paint(PaintInfo& info, const LayoutPoint& paintOffset)
{
RenderMathMLRow::paint(info, paintOffset);
if (info.context().paintingDisabled() || info.phase != PaintPhaseForeground || style().visibility() != VISIBLE)
return;
LayoutUnit thickness = ruleThickness();
// Make a copy of the PaintInfo because applyTransform will modify its rect.
PaintInfo paintInfo(info);
GraphicsContextStateSaver stateSaver(paintInfo.context());
paintInfo.context().setStrokeThickness(thickness);
paintInfo.context().setStrokeStyle(SolidStroke);
paintInfo.context().setStrokeColor(style().visitedDependentColor(CSSPropertyColor));
paintInfo.context().setFillColor(Color::transparent);
paintInfo.applyTransform(AffineTransform().translate(paintOffset + location()));
// In the MathML in HTML5 implementation note, the "left" notation is described as follows:
// - center of the left vertical bar is at 3\xi_8 padding + \xi_8 border/2 = 7\xi_8/2
// - top space is Overbar Vertical Gap + Overbar Rule Thickness = 3\xi_8 + \xi_8 = 4\xi_8
// - bottom space is Underbar Vertical Gap + Underbar Rule Thickness = 3\xi_8 + \xi_8 = 4\xi_8
if (hasNotation(MathMLMencloseElement::Left)) {
LayoutUnit x = m_contentRect.x() - 7 * thickness / 2;
LayoutUnit yStart = m_contentRect.y() - 4 * thickness;
LayoutUnit yEnd = m_contentRect.maxY() + 4 * thickness;
drawLine(info, x, yStart, x, yEnd);
}
// In the MathML in HTML5 implementation note, the "right" notation is described as follows:
// - center of the right vertical bar is at 3\xi_8 padding + \xi_8 border/2 = 7\xi_8/2
// - top space is Overbar Vertical Gap + Overbar Rule Thickness = 3\xi_8 + \xi_8 = 4\xi_8
// - bottom space is Underbar Vertical Gap + Underbar Rule Thickness = 3\xi_8 + \xi_8 = 4\xi_8
if (hasNotation(MathMLMencloseElement::Right)) {
LayoutUnit x = m_contentRect.maxX() + 7 * thickness / 2;
LayoutUnit yStart = m_contentRect.y() - 4 * thickness;
LayoutUnit yEnd = m_contentRect.maxY() + 4 * thickness;
drawLine(info, x, yStart, x, yEnd);
}
// In the MathML in HTML5 implementation note, the "vertical" notation is horizontally centered.
if (hasNotation(MathMLMencloseElement::VerticalStrike)) {
LayoutUnit x = m_contentRect.x() + (m_contentRect.width() - thickness) / 2;
LayoutUnit yStart = m_contentRect.y();
LayoutUnit yEnd = m_contentRect.maxY();
drawLine(info, x, yStart, x, yEnd);
}
// In the MathML in HTML5 implementation note, the "top" notation is described as follows:
// - middle of the top horizontal bar is at Vertical Gap + Rule Thickness / 2 = 7\xi_8/2
// - left and right spaces have size 4\xi_8
if (hasNotation(MathMLMencloseElement::Top)) {
LayoutUnit y = m_contentRect.y() - 7 * thickness / 2;
LayoutUnit xStart = m_contentRect.x() - 4 * thickness;
LayoutUnit xEnd = m_contentRect.maxX() + 4 * thickness;
drawLine(info, xStart, y, xEnd, y);
}
// In the MathML in HTML5 implementation note, the "bottom" notation is described as follows:
// - middle of the bottom horizontal bar is at Vertical Gap + Rule Thickness / 2 = 7\xi_8/2
// - left and right spaces have size 4\xi_8
if (hasNotation(MathMLMencloseElement::Bottom)) {
LayoutUnit y = m_contentRect.maxY() + 7 * thickness / 2;
LayoutUnit xStart = m_contentRect.x() - 4 * thickness;
LayoutUnit xEnd = m_contentRect.maxX() + 4 * thickness;
drawLine(info, xStart, y, xEnd, y);
}
// In the MathML in HTML5 implementation note, the "vertical" notation is vertically centered.
if (hasNotation(MathMLMencloseElement::HorizontalStrike)) {
LayoutUnit y = m_contentRect.y() + (m_contentRect.height() - thickness) / 2;
LayoutUnit xStart = m_contentRect.x();
LayoutUnit xEnd = m_contentRect.maxX();
drawLine(info, xStart, y, xEnd, y);
}
// In the MathML in HTML5 implementation note, the "updiagonalstrike" goes from the bottom left corner
// to the top right corner.
if (hasNotation(MathMLMencloseElement::UpDiagonalStrike))
drawLine(info, m_contentRect.x(), m_contentRect.maxY(), m_contentRect.maxX(), m_contentRect.y());
// In the MathML in HTML5 implementation note, the "downdiagonalstrike" goes from the top left corner
// to the bottom right corner.
if (hasNotation(MathMLMencloseElement::DownDiagonalStrike))
drawLine(info, m_contentRect.x(), m_contentRect.y(), m_contentRect.maxX(), m_contentRect.maxY());
// In the MathML in HTML5 implementation note, the "roundedbox" has radii size 3\xi_8 and is obtained
// by inflating the content box by 3\xi_8 + \xi_8/2 = 7\xi_8/2
if (hasNotation(MathMLMencloseElement::RoundedBox)) {
LayoutSize radiiSize(3 * thickness, 3 * thickness);
RoundedRect::Radii radii(radiiSize, radiiSize, radiiSize, radiiSize);
RoundedRect roundedRect(m_contentRect, radii);
roundedRect.inflate(7 * thickness / 2);
Path path;
path.addRoundedRect(roundedRect);
paintInfo.context().strokePath(path);
}
// For longdiv, we use our own rules for now:
//.........这里部分代码省略.........
示例9: paint
void RenderMathMLBlock::paint(PaintInfo& info, const LayoutPoint& paintOffset)
{
RenderBlock::paint(info, paintOffset);
if (info.context().paintingDisabled() || info.phase != PaintPhaseForeground)
return;
IntPoint adjustedPaintOffset = roundedIntPoint(paintOffset + location());
GraphicsContextStateSaver stateSaver(info.context());
info.context().setStrokeThickness(1.0f);
info.context().setStrokeStyle(SolidStroke);
info.context().setStrokeColor(Color(0, 0, 255));
info.context().drawLine(adjustedPaintOffset, IntPoint(adjustedPaintOffset.x() + pixelSnappedOffsetWidth(), adjustedPaintOffset.y()));
info.context().drawLine(IntPoint(adjustedPaintOffset.x() + pixelSnappedOffsetWidth(), adjustedPaintOffset.y()), IntPoint(adjustedPaintOffset.x() + pixelSnappedOffsetWidth(), adjustedPaintOffset.y() + pixelSnappedOffsetHeight()));
info.context().drawLine(IntPoint(adjustedPaintOffset.x(), adjustedPaintOffset.y() + pixelSnappedOffsetHeight()), IntPoint(adjustedPaintOffset.x() + pixelSnappedOffsetWidth(), adjustedPaintOffset.y() + pixelSnappedOffsetHeight()));
info.context().drawLine(adjustedPaintOffset, IntPoint(adjustedPaintOffset.x(), adjustedPaintOffset.y() + pixelSnappedOffsetHeight()));
int topStart = paddingTop();
info.context().setStrokeColor(Color(0, 255, 0));
info.context().drawLine(IntPoint(adjustedPaintOffset.x(), adjustedPaintOffset.y() + topStart), IntPoint(adjustedPaintOffset.x() + pixelSnappedOffsetWidth(), adjustedPaintOffset.y() + topStart));
int baseline = roundToInt(baselinePosition(AlphabeticBaseline, true, HorizontalLine));
info.context().setStrokeColor(Color(255, 0, 0));
info.context().drawLine(IntPoint(adjustedPaintOffset.x(), adjustedPaintOffset.y() + baseline), IntPoint(adjustedPaintOffset.x() + pixelSnappedOffsetWidth(), adjustedPaintOffset.y() + baseline));
}
示例10: paintEllipsisBox
void RootInlineBoxPainter::paintEllipsisBox(const PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit lineTop, LayoutUnit lineBottom) const
{
if (m_rootInlineBox.hasEllipsisBox() && paintInfo.shouldPaintWithinRoot(&m_rootInlineBox.layoutObject()) && m_rootInlineBox.lineLayoutItem().style()->visibility() == VISIBLE
&& paintInfo.phase == PaintPhaseForeground)
m_rootInlineBox.ellipsisBox()->paint(paintInfo, paintOffset, lineTop, lineBottom);
}
示例11: paintCollapsedBorders
void TableCellPainter::paintCollapsedBorders(const PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
ASSERT(paintInfo.phase == PaintPhaseCollapsedTableBorders);
if (!paintInfo.shouldPaintWithinRoot(&m_layoutTableCell) || m_layoutTableCell.style()->visibility() != VISIBLE)
return;
LayoutRect paintRect = paintBounds(paintOffset, AddOffsetFromParent);
LayoutRect drawingCullRect(paintRect);
drawingCullRect.expandEdges(m_layoutTableCell.table()->outerBorderTop(), m_layoutTableCell.table()->outerBorderRight(),
m_layoutTableCell.table()->outerBorderBottom(), m_layoutTableCell.table()->outerBorderLeft());
if (drawingCullRect.y() >= paintInfo.rect.maxY())
return;
if (drawingCullRect.maxY() <= paintInfo.rect.y())
return;
const CollapsedBorderValue* tableCurrentBorderValue = m_layoutTableCell.table()->currentBorderValue();
if (!tableCurrentBorderValue)
return;
const ComputedStyle& styleForCellFlow = m_layoutTableCell.styleForCellFlow();
const CollapsedBorderValue& leftBorderValue = cachedCollapsedLeftBorder(styleForCellFlow);
const CollapsedBorderValue& rightBorderValue = cachedCollapsedRightBorder(styleForCellFlow);
const CollapsedBorderValue& topBorderValue = cachedCollapsedTopBorder(styleForCellFlow);
const CollapsedBorderValue& bottomBorderValue = cachedCollapsedBottomBorder(styleForCellFlow);
bool shouldPaintTop = topBorderValue.shouldPaint(*tableCurrentBorderValue);
bool shouldPaintBottom = bottomBorderValue.shouldPaint(*tableCurrentBorderValue);
bool shouldPaintLeft = leftBorderValue.shouldPaint(*tableCurrentBorderValue);
bool shouldPaintRight = rightBorderValue.shouldPaint(*tableCurrentBorderValue);
if (!shouldPaintTop && !shouldPaintBottom && !shouldPaintLeft && !shouldPaintRight)
return;
GraphicsContext* graphicsContext = paintInfo.context;
LayoutObjectDrawingRecorder recorder(*graphicsContext, m_layoutTableCell, paintInfo.phase, drawingCullRect);
if (recorder.canUseCachedDrawing())
return;
bool antialias = BoxPainter::shouldAntialiasLines(graphicsContext);
// Adjust our x/y/width/height so that we paint the collapsed borders at the correct location.
int topWidth = topBorderValue.width();
int bottomWidth = bottomBorderValue.width();
int leftWidth = leftBorderValue.width();
int rightWidth = rightBorderValue.width();
IntRect borderRect = pixelSnappedIntRect(paintRect.x() - leftWidth / 2,
paintRect.y() - topWidth / 2,
paintRect.width() + leftWidth / 2 + (rightWidth + 1) / 2,
paintRect.height() + topWidth / 2 + (bottomWidth + 1) / 2);
Color cellColor = m_layoutTableCell.resolveColor(CSSPropertyColor);
// We never paint diagonals at the joins. We simply let the border with the highest
// precedence paint on top of borders with lower precedence.
if (shouldPaintTop) {
ObjectPainter::drawLineForBoxSide(graphicsContext, borderRect.x(), borderRect.y(), borderRect.maxX(), borderRect.y() + topWidth, BSTop,
topBorderValue.color().resolve(cellColor), collapsedBorderStyle(topBorderValue.style()), 0, 0, antialias);
}
if (shouldPaintBottom) {
ObjectPainter::drawLineForBoxSide(graphicsContext, borderRect.x(), borderRect.maxY() - bottomWidth, borderRect.maxX(), borderRect.maxY(), BSBottom,
bottomBorderValue.color().resolve(cellColor), collapsedBorderStyle(bottomBorderValue.style()), 0, 0, antialias);
}
if (shouldPaintLeft) {
ObjectPainter::drawLineForBoxSide(graphicsContext, borderRect.x(), borderRect.y(), borderRect.x() + leftWidth, borderRect.maxY(), BSLeft,
leftBorderValue.color().resolve(cellColor), collapsedBorderStyle(leftBorderValue.style()), 0, 0, antialias);
}
if (shouldPaintRight) {
ObjectPainter::drawLineForBoxSide(graphicsContext, borderRect.maxX() - rightWidth, borderRect.y(), borderRect.maxX(), borderRect.maxY(), BSRight,
rightBorderValue.color().resolve(cellColor), collapsedBorderStyle(rightBorderValue.style()), 0, 0, antialias);
}
}
示例12: paintMask
void InlineFlowBoxPainter::paintMask(const PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
if (!paintInfo.shouldPaintWithinRoot(&m_inlineFlowBox.layoutObject()) || m_inlineFlowBox.layoutObject().style()->visibility() != VISIBLE || paintInfo.phase != PaintPhaseMask)
return;
LayoutRect frameRect = roundedFrameRectClampedToLineTopAndBottomIfNeeded();
// Move x/y to our coordinates.
LayoutRect localRect(frameRect);
m_inlineFlowBox.flipForWritingMode(localRect);
LayoutPoint adjustedPaintOffset = paintOffset + localRect.location();
const NinePieceImage& maskNinePieceImage = m_inlineFlowBox.layoutObject().style()->maskBoxImage();
StyleImage* maskBoxImage = m_inlineFlowBox.layoutObject().style()->maskBoxImage().image();
// Figure out if we need to push a transparency layer to render our mask.
bool pushTransparencyLayer = false;
bool compositedMask = m_inlineFlowBox.layoutObject().hasLayer() && m_inlineFlowBox.boxModelObject()->layer()->hasCompositedMask();
bool flattenCompositingLayers = m_inlineFlowBox.layoutObject().view()->frameView() && m_inlineFlowBox.layoutObject().view()->frameView()->paintBehavior() & PaintBehaviorFlattenCompositingLayers;
SkXfermode::Mode compositeOp = SkXfermode::kSrcOver_Mode;
if (!compositedMask || flattenCompositingLayers) {
if ((maskBoxImage && m_inlineFlowBox.layoutObject().style()->maskLayers().hasImage()) || m_inlineFlowBox.layoutObject().style()->maskLayers().next()) {
pushTransparencyLayer = true;
paintInfo.context->beginLayer(1.0f, SkXfermode::kDstIn_Mode);
} else {
// TODO(fmalita): passing a dst-in xfer mode down to paintFillLayers/paintNinePieceImage
// seems dangerous: it is only correct if applied atomically (single draw call). While
// the heuristic above presumably ensures that is the case, this approach seems super
// fragile. We should investigate dropping this optimization in favour of the more
// robust layer branch above.
compositeOp = SkXfermode::kDstIn_Mode;
}
}
LayoutRect paintRect = LayoutRect(adjustedPaintOffset, frameRect.size());
paintFillLayers(paintInfo, Color::transparent, m_inlineFlowBox.layoutObject().style()->maskLayers(), paintRect, compositeOp);
bool hasBoxImage = maskBoxImage && maskBoxImage->canRender(m_inlineFlowBox.layoutObject(), m_inlineFlowBox.layoutObject().style()->effectiveZoom());
if (!hasBoxImage || !maskBoxImage->isLoaded()) {
if (pushTransparencyLayer)
paintInfo.context->endLayer();
return; // Don't paint anything while we wait for the image to load.
}
// The simple case is where we are the only box for this object. In those
// cases only a single call to draw is required.
if (!m_inlineFlowBox.prevLineBox() && !m_inlineFlowBox.nextLineBox()) {
BoxPainter::paintNinePieceImage(*m_inlineFlowBox.boxModelObject(), paintInfo.context, paintRect, m_inlineFlowBox.layoutObject().styleRef(), maskNinePieceImage, compositeOp);
} else {
// We have a mask image that spans multiple lines.
// FIXME: What the heck do we do with RTL here? The math we're using is obviously not right,
// but it isn't even clear how this should work at all.
LayoutRect imageStripPaintRect = paintRectForImageStrip(adjustedPaintOffset, frameRect.size(), LTR);
LayoutRect clipRect = clipRectForNinePieceImageStrip(&m_inlineFlowBox, maskNinePieceImage, paintRect);
GraphicsContextStateSaver stateSaver(*paintInfo.context);
paintInfo.context->clip(clipRect);
BoxPainter::paintNinePieceImage(*m_inlineFlowBox.boxModelObject(), paintInfo.context, imageStripPaintRect, m_inlineFlowBox.layoutObject().styleRef(), maskNinePieceImage, compositeOp);
}
if (pushTransparencyLayer)
paintInfo.context->endLayer();
}
示例13: overflowRect
void InlineFlowBoxPainter::paint(const PaintInfo& paintInfo, const LayoutPoint& paintOffset, const LayoutUnit lineTop, const LayoutUnit lineBottom)
{
LayoutRect overflowRect(m_inlineFlowBox.visualOverflowRect(lineTop, lineBottom));
m_inlineFlowBox.flipForWritingMode(overflowRect);
overflowRect.moveBy(paintOffset);
if (!paintInfo.rect.intersects(pixelSnappedIntRect(overflowRect)))
return;
if (paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) {
// Add ourselves to the paint info struct's list of inlines that need to paint their
// outlines.
if (m_inlineFlowBox.layoutObject().style()->visibility() == VISIBLE && m_inlineFlowBox.layoutObject().style()->hasOutline() && !m_inlineFlowBox.isRootInlineBox()) {
LayoutInline& inlineFlow = toLayoutInline(m_inlineFlowBox.layoutObject());
LayoutBlock* cb = 0;
bool containingBlockPaintsContinuationOutline = inlineFlow.continuation() || inlineFlow.isInlineElementContinuation();
if (containingBlockPaintsContinuationOutline) {
// FIXME: See https://bugs.webkit.org/show_bug.cgi?id=54690. We currently don't reconnect inline continuations
// after a child removal. As a result, those merged inlines do not get seperated and hence not get enclosed by
// anonymous blocks. In this case, it is better to bail out and paint it ourself.
LayoutBlock* enclosingAnonymousBlock = m_inlineFlowBox.layoutObject().containingBlock();
if (!enclosingAnonymousBlock->isAnonymousBlock()) {
containingBlockPaintsContinuationOutline = false;
} else {
cb = enclosingAnonymousBlock->containingBlock();
for (LayoutBoxModelObject* box = m_inlineFlowBox.boxModelObject(); box != cb; box = box->parent()->enclosingBoxModelObject()) {
if (box->hasSelfPaintingLayer()) {
containingBlockPaintsContinuationOutline = false;
break;
}
}
}
}
if (containingBlockPaintsContinuationOutline) {
// Add ourselves to the containing block of the entire continuation so that it can
// paint us atomically.
cb->addContinuationWithOutline(toLayoutInline(m_inlineFlowBox.layoutObject().node()->layoutObject()));
} else if (!inlineFlow.isInlineElementContinuation()) {
paintInfo.outlineObjects()->add(&inlineFlow);
}
}
} else if (paintInfo.phase == PaintPhaseMask) {
DrawingRecorder recorder(*paintInfo.context, m_inlineFlowBox, DisplayItem::paintPhaseToDrawingType(paintInfo.phase), pixelSnappedIntRect(overflowRect));
if (!recorder.canUseCachedDrawing())
paintMask(paintInfo, paintOffset);
return;
} else if (paintInfo.phase == PaintPhaseForeground) {
// Paint our background, border and box-shadow.
paintBoxDecorationBackground(paintInfo, paintOffset);
}
// Paint our children.
if (paintInfo.phase != PaintPhaseSelfOutline) {
PaintInfo childInfo(paintInfo);
childInfo.phase = paintInfo.phase == PaintPhaseChildOutlines ? PaintPhaseOutline : paintInfo.phase;
if (childInfo.paintingRoot && childInfo.paintingRoot->isDescendantOf(&m_inlineFlowBox.layoutObject()))
childInfo.paintingRoot = 0;
else
childInfo.updatePaintingRootForChildren(&m_inlineFlowBox.layoutObject());
for (InlineBox* curr = m_inlineFlowBox.firstChild(); curr; curr = curr->nextOnLine()) {
if (curr->layoutObject().isText() || !curr->boxModelObject()->hasSelfPaintingLayer())
curr->paint(childInfo, paintOffset, lineTop, lineBottom);
}
}
}
示例14: paint
void SVGInlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint&, LayoutUnit, LayoutUnit)
{
ASSERT(paintInfo.shouldPaintWithinRoot(renderer()));
ASSERT(paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection);
ASSERT(truncation() == cNoTruncation);
if (renderer()->style()->visibility() != VISIBLE)
return;
// Note: We're explicitely not supporting composition & custom underlines and custom highlighters - unlike InlineTextBox.
// If we ever need that for SVG, it's very easy to refactor and reuse the code.
RenderObject* parentRenderer = parent()->renderer();
ASSERT(parentRenderer);
bool paintSelectedTextOnly = paintInfo.phase == PaintPhaseSelection;
bool hasSelection = !parentRenderer->document()->printing() && selectionState() != RenderObject::SelectionNone;
if (!hasSelection && paintSelectedTextOnly)
return;
RenderSVGInlineText* textRenderer = toRenderSVGInlineText(this->textRenderer());
ASSERT(textRenderer);
if (!textShouldBePainted(textRenderer))
return;
RenderStyle* style = parentRenderer->style();
ASSERT(style);
const SVGRenderStyle* svgStyle = style->svgStyle();
ASSERT(svgStyle);
bool hasFill = svgStyle->hasFill();
bool hasStroke = svgStyle->hasStroke();
RenderStyle* selectionStyle = style;
if (hasSelection) {
selectionStyle = parentRenderer->getCachedPseudoStyle(SELECTION);
if (selectionStyle) {
const SVGRenderStyle* svgSelectionStyle = selectionStyle->svgStyle();
ASSERT(svgSelectionStyle);
if (!hasFill)
hasFill = svgSelectionStyle->hasFill();
if (!hasStroke)
hasStroke = svgSelectionStyle->hasStroke();
} else
selectionStyle = style;
}
AffineTransform fragmentTransform;
unsigned textFragmentsSize = m_textFragments.size();
for (unsigned i = 0; i < textFragmentsSize; ++i) {
SVGTextFragment& fragment = m_textFragments.at(i);
ASSERT(!m_paintingResource);
GraphicsContextStateSaver stateSaver(*paintInfo.context);
fragment.buildFragmentTransform(fragmentTransform);
if (!fragmentTransform.isIdentity())
paintInfo.context->concatCTM(fragmentTransform);
// Spec: All text decorations except line-through should be drawn before the text is filled and stroked; thus, the text is rendered on top of these decorations.
int decorations = style->textDecorationsInEffect();
if (decorations & UNDERLINE)
paintDecoration(paintInfo.context, UNDERLINE, fragment);
if (decorations & OVERLINE)
paintDecoration(paintInfo.context, OVERLINE, fragment);
// Fill text
if (hasFill) {
m_paintingResourceMode = ApplyToFillMode | ApplyToTextMode;
paintText(paintInfo.context, style, selectionStyle, fragment, hasSelection, paintSelectedTextOnly);
}
// Stroke text
if (hasStroke) {
m_paintingResourceMode = ApplyToStrokeMode | ApplyToTextMode;
paintText(paintInfo.context, style, selectionStyle, fragment, hasSelection, paintSelectedTextOnly);
}
// Spec: Line-through should be drawn after the text is filled and stroked; thus, the line-through is rendered on top of the text.
if (decorations & LINE_THROUGH)
paintDecoration(paintInfo.context, LINE_THROUGH, fragment);
m_paintingResourceMode = ApplyToDefaultMode;
}
ASSERT(!m_paintingResource);
}
示例15: locationIncludingFlipping
void EllipsisBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit lineTop, LayoutUnit lineBottom)
{
GraphicsContext* context = paintInfo.context;
RenderStyle* style = m_renderer->style(isFirstLineStyle());
const Font& font = style->font();
FloatPoint boxOrigin = locationIncludingFlipping();
LayoutPoint adjustedPaintOffset = paintOffset;
if (!isHorizontal())
adjustedPaintOffset.move(0, -virtualLogicalHeight());
boxOrigin.move(adjustedPaintOffset.x(), adjustedPaintOffset.y());
FloatRect boxRect(boxOrigin, LayoutSize(logicalWidth(), virtualLogicalHeight()));
GraphicsContextStateSaver stateSaver(*context);
if (!isHorizontal())
context->concatCTM(InlineTextBox::rotation(boxRect, InlineTextBox::Clockwise));
FloatPoint textOrigin = FloatPoint(boxOrigin.x(), boxOrigin.y() + font.fontMetrics().ascent());
Color styleTextColor = m_renderer->resolveColor(style, CSSPropertyWebkitTextFillColor);
if (styleTextColor != context->fillColor())
context->setFillColor(styleTextColor);
if (selectionState() != RenderObject::SelectionNone) {
paintSelection(context, boxOrigin, style, font);
// Select the correct color for painting the text.
Color foreground = paintInfo.forceBlackText() ? Color::black : renderer()->selectionForegroundColor();
if (foreground.isValid() && foreground != styleTextColor)
context->setFillColor(foreground);
}
// Text shadows are disabled when printing. http://crbug.com/258321
const ShadowList* shadowList = context->printing() ? 0 : style->textShadow();
bool hasShadow = shadowList;
if (hasShadow) {
DrawLooper drawLooper;
for (size_t i = shadowList->shadows().size(); i--; ) {
const ShadowData& shadow = shadowList->shadows()[i];
int shadowX = isHorizontal() ? shadow.x() : shadow.y();
int shadowY = isHorizontal() ? shadow.y() : -shadow.x();
FloatSize offset(shadowX, shadowY);
drawLooper.addShadow(offset, shadow.blur(), m_renderer->resolveColor(shadow.color()),
DrawLooper::ShadowRespectsTransforms, DrawLooper::ShadowIgnoresAlpha);
}
drawLooper.addUnmodifiedContent();
context->setDrawLooper(drawLooper);
}
// FIXME: Why is this always LTR? Fix by passing correct text run flags below.
TextRun textRun = RenderBlockFlow::constructTextRun(renderer(), font, m_str, style, TextRun::AllowTrailingExpansion);
TextRunPaintInfo textRunPaintInfo(textRun);
textRunPaintInfo.bounds = boxRect;
context->drawText(font, textRunPaintInfo, textOrigin);
// Restore the regular fill color.
if (styleTextColor != context->fillColor())
context->setFillColor(styleTextColor);
if (hasShadow)
context->clearDrawLooper();
paintMarkupBox(paintInfo, paintOffset, lineTop, lineBottom, style);
}