void FindPageOverlay::drawRect(GraphicsContext& graphicsContext, const IntRect& dirtyRect) { Vector<IntRect> rects = rectsForTextMatches(); ASSERT(!rects.isEmpty()); FrameView* frameView = webPage()->corePage()->mainFrame()->view(); int width = frameView->width(); if (frameView->verticalScrollbar()) width -= frameView->verticalScrollbar()->width(); int height = frameView->height(); if (frameView->horizontalScrollbar()) height -= frameView->horizontalScrollbar()->height(); IntRect paintRect = intersection(dirtyRect, IntRect(0, 0, width, height)); if (paintRect.isEmpty()) return; graphicsContext.beginTransparencyLayer(1); graphicsContext.setCompositeOperation(CompositeCopy); // Draw the background. graphicsContext.fillRect(paintRect, overlayBackgroundColor(), sRGBColorSpace); // FIXME: Draw the holes. graphicsContext.endTransparencyLayer(); }
void RenderEmbeddedObject::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOffset) { if (!showsUnavailablePluginIndicator()) return; if (paintInfo.phase == PaintPhaseSelection) return; GraphicsContext* context = paintInfo.context; if (context->paintingDisabled()) return; FloatRect contentRect; FloatRect indicatorRect; FloatRect replacementTextRect; FloatRect arrowRect; FontCascade font; TextRun run(""); float textWidth; if (!getReplacementTextGeometry(paintOffset, contentRect, indicatorRect, replacementTextRect, arrowRect, font, run, textWidth)) return; Path background; background.addRoundedRect(indicatorRect, FloatSize(replacementTextRoundedRectRadius, replacementTextRoundedRectRadius)); GraphicsContextStateSaver stateSaver(*context); context->clip(contentRect); context->setFillColor(m_unavailablePluginIndicatorIsPressed ? replacementTextRoundedRectPressedColor() : replacementTextRoundedRectColor(), style().colorSpace()); context->fillPath(background); Path strokePath; FloatRect strokeRect(indicatorRect); strokeRect.inflate(1); strokePath.addRoundedRect(strokeRect, FloatSize(replacementTextRoundedRectRadius + 1, replacementTextRoundedRectRadius + 1)); context->setStrokeColor(unavailablePluginBorderColor(), style().colorSpace()); context->setStrokeThickness(2); context->strokePath(strokePath); const FontMetrics& fontMetrics = font.fontMetrics(); float labelX = roundf(replacementTextRect.location().x() + replacementTextRoundedRectLeftTextMargin); float labelY = roundf(replacementTextRect.location().y() + (replacementTextRect.size().height() - fontMetrics.height()) / 2 + fontMetrics.ascent() + replacementTextRoundedRectTopTextMargin); context->setFillColor(replacementTextColor(), style().colorSpace()); context->drawBidiText(font, run, FloatPoint(labelX, labelY)); if (shouldUnavailablePluginMessageBeButton(document(), m_pluginUnavailabilityReason)) { arrowRect.inflate(-replacementArrowCirclePadding); context->beginTransparencyLayer(1.0); context->setFillColor(replacementTextColor(), style().colorSpace()); context->fillEllipse(arrowRect); context->setCompositeOperation(CompositeClear); drawReplacementArrow(context, arrowRect); context->endTransparencyLayer(); } }
void InlinePainter::paintOutline(const PaintInfo& paintInfo, const LayoutPoint& paintOffset) { RenderStyle* styleToUse = m_renderInline.style(); if (!styleToUse->hasOutline()) return; LayoutRect bounds; if (RuntimeEnabledFeatures::slimmingPaintEnabled()) { // FIXME: Use tighter bounds. RenderBlock* cb = m_renderInline.containingBlock(); bounds = cb->visualOverflowRect(); bounds.moveBy(paintOffset); } RenderDrawingRecorder recorder(paintInfo.context, m_renderInline, paintInfo.phase, bounds); if (recorder.canUseCachedDrawing()) return; if (styleToUse->outlineStyleIsAuto()) { if (RenderTheme::theme().shouldDrawDefaultFocusRing(&m_renderInline)) { // Only paint the focus ring by hand if the theme isn't able to draw the focus ring. ObjectPainter(m_renderInline).paintFocusRing(paintInfo, paintOffset, styleToUse); } return; } if (styleToUse->outlineStyle() == BNONE) return; Vector<LayoutRect> rects; rects.append(LayoutRect()); for (InlineFlowBox* curr = m_renderInline.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_renderInline.resolveColor(styleToUse, CSSPropertyOutlineColor); bool useTransparencyLayer = outlineColor.hasAlpha(); GraphicsContext* graphicsContext = paintInfo.context; if (useTransparencyLayer) { graphicsContext->beginTransparencyLayer(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(); }
void PageOverlay::drawRect(GraphicsContext& graphicsContext, const IntRect& dirtyRect) { // If the dirty rect is outside the bounds, ignore it. IntRect paintRect = intersection(dirtyRect, bounds()); if (paintRect.isEmpty()) return; GraphicsContextStateSaver stateSaver(graphicsContext); graphicsContext.beginTransparencyLayer(1); graphicsContext.setCompositeOperation(CompositeCopy); m_client->drawRect(this, graphicsContext, paintRect); graphicsContext.endTransparencyLayer(); }
void CrossfadeGeneratedImage::drawCrossfade(GraphicsContext& context) { // Draw nothing if either of the images hasn't loaded yet. if (m_fromImage == Image::nullImage() || m_toImage == Image::nullImage()) return; GraphicsContextStateSaver stateSaver(context); context.clip(FloatRect(FloatPoint(), m_crossfadeSize)); context.beginTransparencyLayer(1); drawCrossfadeSubimage(context, m_fromImage, CompositeSourceOver, 1 - m_percentage, m_crossfadeSize); drawCrossfadeSubimage(context, m_toImage, CompositePlusLighter, m_percentage, m_crossfadeSize); context.endTransparencyLayer(); }
void SVGImage::draw(GraphicsContext& context, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator compositeOp, BlendMode blendMode, ImageOrientationDescription) { if (!m_page) return; FrameView* view = frameView(); ASSERT(view); GraphicsContextStateSaver stateSaver(context); context.setCompositeOperation(compositeOp, blendMode); context.clip(enclosingIntRect(dstRect)); float alpha = context.alpha(); bool compositingRequiresTransparencyLayer = compositeOp != CompositeSourceOver || blendMode != BlendModeNormal || alpha < 1; if (compositingRequiresTransparencyLayer) { context.beginTransparencyLayer(alpha); context.setCompositeOperation(CompositeSourceOver, BlendModeNormal); } FloatSize scale(dstRect.width() / srcRect.width(), dstRect.height() / srcRect.height()); // We can only draw the entire frame, clipped to the rect we want. So compute where the top left // of the image would be if we were drawing without clipping, and translate accordingly. FloatSize topLeftOffset(srcRect.location().x() * scale.width(), srcRect.location().y() * scale.height()); FloatPoint destOffset = dstRect.location() - topLeftOffset; context.translate(destOffset.x(), destOffset.y()); context.scale(scale); view->resize(containerSize()); if (!m_url.isEmpty()) view->scrollToFragment(m_url); if (view->needsLayout()) view->layout(); view->paint(context, intersection(context.clipBounds(), enclosingIntRect(srcRect))); if (compositingRequiresTransparencyLayer) context.endTransparencyLayer(); stateSaver.restore(); if (imageObserver()) imageObserver()->didDraw(this); }
static void drawCrossfadeSubimage(GraphicsContext& context, Image* image, CompositeOperator operation, float opacity, const FloatSize& targetSize) { FloatSize imageSize = image->size(); // SVGImage resets the opacity when painting, so we have to use transparency layers to accurately paint one at a given opacity. bool useTransparencyLayer = image->isSVGImage(); GraphicsContextStateSaver stateSaver(context); context.setCompositeOperation(operation); if (useTransparencyLayer) context.beginTransparencyLayer(opacity); else context.setAlpha(opacity); if (targetSize != imageSize) context.scale(FloatSize(targetSize.width() / imageSize.width(), targetSize.height() / imageSize.height())); context.drawImage(image, ColorSpaceDeviceRGB, IntPoint()); if (useTransparencyLayer) context.endTransparencyLayer(); }
void BeginTransparencyLayer::apply(GraphicsContext& context) const { context.beginTransparencyLayer(m_opacity); }