static void deflateIfOverlapped(IntRect& a, IntRect& b) { if (!a.intersects(b) || a.contains(b) || b.contains(a)) return; static const int fudgeFactor = -2; // Avoid negative width or height values. if ((a.width() + 2 * fudgeFactor > 0) && (a.height() + 2 * fudgeFactor > 0)) a.inflate(fudgeFactor); if ((b.width() + 2 * fudgeFactor > 0) && (b.height() + 2 * fudgeFactor > 0)) b.inflate(fudgeFactor); }
void FindController::drawRect(PageOverlay* pageOverlay, GraphicsContext& graphicsContext, const IntRect& dirtyRect) { float fractionFadedIn = pageOverlay->fractionFadedIn(); Vector<IntRect> rects = rectsForTextMatches(); // Draw the background. graphicsContext.fillRect(dirtyRect, overlayBackgroundColor(fractionFadedIn), ColorSpaceSRGB); { GraphicsContextStateSaver stateSaver(graphicsContext); graphicsContext.setShadow(FloatSize(shadowOffsetX, shadowOffsetY), shadowBlurRadius, holeShadowColor(fractionFadedIn), ColorSpaceSRGB); graphicsContext.setFillColor(holeFillColor(fractionFadedIn), ColorSpaceSRGB); // Draw white frames around the holes. for (size_t i = 0; i < rects.size(); ++i) { IntRect whiteFrameRect = rects[i]; whiteFrameRect.inflate(1); graphicsContext.fillRect(whiteFrameRect); } } graphicsContext.setFillColor(Color::transparent, ColorSpaceSRGB); // Clear out the holes. for (size_t i = 0; i < rects.size(); ++i) graphicsContext.fillRect(rects[i]); }
void FindController::drawRect(PageOverlay*, GraphicsContext& graphicsContext, const IntRect& dirtyRect) { Vector<IntRect> rects = rectsForTextMatches(); // Draw the background. graphicsContext.fillRect(dirtyRect, overlayBackgroundColor(), ColorSpaceSRGB); graphicsContext.save(); graphicsContext.setShadow(FloatSize(shadowOffsetX, shadowOffsetY), shadowBlurRadius, Color::black, ColorSpaceSRGB); graphicsContext.setFillColor(Color::white, ColorSpaceSRGB); // Draw white frames around the holes. for (size_t i = 0; i < rects.size(); ++i) { IntRect whiteFrameRect = rects[i]; whiteFrameRect.inflate(1); graphicsContext.fillRect(whiteFrameRect); } graphicsContext.restore(); graphicsContext.setFillColor(Color::transparent, ColorSpaceSRGB); // Clear out the holes. for (size_t i = 0; i < rects.size(); ++i) graphicsContext.fillRect(rects[i]); }
void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int offset, const Color& color) { if (paintingDisabled()) return; if (rects.isEmpty()) return; // FIXME: We just unite all focus ring rects into one for now. // We should outline the edge of the full region. offset += (width - 1) / 2; IntRect finalFocusRect; for (unsigned i = 0; i < rects.size(); i++) { IntRect focusRect = rects[i]; focusRect.inflate(offset); finalFocusRect.unite(focusRect); } StrokeStyle oldStyle = m_data->strokeStyle(); Color oldStrokeColor = m_data->strokeColor(); m_data->setStrokeStyle(DashedStroke); m_data->setStrokeColor(color); strokeRect(FloatRect(finalFocusRect), 1.f); m_data->setStrokeStyle(oldStyle); m_data->setStrokeColor(oldStrokeColor); }
void RenderReplaced::adjustOverflowForBoxShadowAndReflect() { IntRect overflow; for (ShadowData* boxShadow = style()->boxShadow(); boxShadow; boxShadow = boxShadow->next) { if (boxShadow->style == Inset) continue; IntRect shadow = borderBoxRect(); shadow.move(boxShadow->x, boxShadow->y); shadow.inflate(boxShadow->blur + boxShadow->spread); overflow.unite(shadow); } // Now that we have an overflow rect including shadow, let's make sure that // the reflection (which can also include the shadow) is also included. if (hasReflection()) { if (overflow.isEmpty()) overflow = borderBoxRect(); overflow.unite(reflectedRect(overflow)); } if (!overflow.isEmpty()) { if (!gOverflowRectMap) gOverflowRectMap = new OverflowRectMap(); overflow.unite(borderBoxRect()); gOverflowRectMap->set(this, overflow); setReplacedHasOverflow(true); } else if (replacedHasOverflow()) { gOverflowRectMap->remove(this); setReplacedHasOverflow(false); } }
IntRect WebPopupMenuProxyWin::clientRect() const { IntRect clientRect = m_windowRect; clientRect.inflate(-popupWindowBorderWidth); clientRect.setLocation(IntPoint(0, 0)); return clientRect; }
static void fillSmoothEdgedRect(GraphicsContext* context, const IntRect& rect, const Color& color) { Color halfColor(color.red(), color.green(), color.blue(), color.alpha() / 2); IntRect topRect = rect; topRect.inflateX(-1); topRect.setHeight(1); context->fillRect(topRect, halfColor, ColorSpaceDeviceRGB); IntRect leftRect = rect; leftRect.inflateY(-1); leftRect.setWidth(1); context->fillRect(leftRect, halfColor, ColorSpaceDeviceRGB); IntRect centerRect = rect; centerRect.inflate(-1); context->fillRect(centerRect, color, ColorSpaceDeviceRGB); IntRect rightRect = rect; rightRect.inflateY(-1); rightRect.setX(centerRect.maxX()); rightRect.setWidth(1); context->fillRect(rightRect, halfColor, ColorSpaceDeviceRGB); IntRect bottomRect = rect; bottomRect.inflateX(-1); bottomRect.setY(centerRect.maxY()); bottomRect.setHeight(1); context->fillRect(bottomRect, halfColor, ColorSpaceDeviceRGB); }
void GraphicsContext::drawFocusRing(const Color& color) { if (paintingDisabled()) return; int radius = (focusRingWidth() - 1) / 2; int offset = radius + focusRingOffset(); const Vector<IntRect>& rects = focusRingRects(); unsigned rectCount = rects.size(); IntRect finalFocusRect; for (unsigned i = 0; i < rectCount; i++) { IntRect focusRect = rects[i]; focusRect.inflate(offset); finalFocusRect.unite(focusRect); } cairo_t* cr = m_data->cr; cairo_save(cr); // FIXME: These rects should be rounded cairo_rectangle(cr, finalFocusRect.x(), finalFocusRect.y(), finalFocusRect.width(), finalFocusRect.height()); // Force the alpha to 50%. This matches what the Mac does with outline rings. Color ringColor(color.red(), color.green(), color.blue(), 127); setColor(cr, ringColor); cairo_stroke(cr); cairo_restore(cr); }
IntRect RenderReplaced::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) { if (style()->visibility() != VISIBLE && !enclosingLayer()->hasVisibleContent()) return IntRect(); // The selectionRect can project outside of the overflowRect, so take their union // for repainting to avoid selection painting glitches. IntRect r = unionRect(localSelectionRect(false), visualOverflowRect()); RenderView* v = view(); if (v) { // FIXME: layoutDelta needs to be applied in parts before/after transforms and // repaint containers. https://bugs.webkit.org/show_bug.cgi?id=23308 r.move(v->layoutDelta()); } if (style()) { if (style()->hasAppearance()) // The theme may wish to inflate the rect used when repainting. theme()->adjustRepaintRect(this, r); if (v) r.inflate(style()->outlineSize()); } computeRectForRepaint(repaintContainer, r); return r; }
bool RenderThemeGtk::paintMediaSliderTrack(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) { GraphicsContext* context = paintInfo.context; context->fillRect(FloatRect(r), m_panelColor, ColorSpaceDeviceRGB); context->fillRect(FloatRect(IntRect(r.x(), r.y() + (r.height() - m_mediaSliderHeight) / 2, r.width(), m_mediaSliderHeight)), m_sliderColor, ColorSpaceDeviceRGB); RenderStyle* style = o->style(); HTMLMediaElement* mediaElement = toParentMediaElement(o); if (!mediaElement) return false; // Draw the buffered ranges. This code is highly inspired from // Chrome for the gradient code. float mediaDuration = mediaElement->duration(); RefPtr<TimeRanges> timeRanges = mediaElement->buffered(); IntRect trackRect = r; int totalWidth = trackRect.width(); trackRect.inflate(-style->borderLeftWidth()); context->save(); context->setStrokeStyle(NoStroke); for (unsigned index = 0; index < timeRanges->length(); ++index) { ExceptionCode ignoredException; float start = timeRanges->start(index, ignoredException); float end = timeRanges->end(index, ignoredException); int width = ((end - start) * totalWidth) / mediaDuration; IntRect rangeRect; if (!index) { rangeRect = trackRect; rangeRect.setWidth(width); } else { rangeRect.setLocation(IntPoint(trackRect.x() + start / mediaDuration* totalWidth, trackRect.y())); rangeRect.setSize(IntSize(width, trackRect.height())); } // Don't bother drawing empty range. if (rangeRect.isEmpty()) continue; IntPoint sliderTopLeft = rangeRect.location(); IntPoint sliderTopRight = sliderTopLeft; sliderTopRight.move(0, rangeRect.height()); RefPtr<Gradient> gradient = Gradient::create(sliderTopLeft, sliderTopRight); Color startColor = m_panelColor; gradient->addColorStop(0.0, startColor); gradient->addColorStop(1.0, Color(startColor.red() / 2, startColor.green() / 2, startColor.blue() / 2, startColor.alpha())); context->setFillGradient(gradient); context->fillRect(rangeRect); } context->restore(); return false; }
void TouchEventHandler::drawTapHighlight() { Element* elementUnderFatFinger = m_lastFatFingersResult.nodeAsElementIfApplicable(); if (!elementUnderFatFinger) return; Element* element = elementForTapHighlight(elementUnderFatFinger); if (!element) return; // Get the element bounding rect in transformed coordinates so we can extract // the focus ring relative position each rect. RenderObject* renderer = element->renderer(); ASSERT(renderer); Frame* elementFrame = element->document()->frame(); ASSERT(elementFrame); FrameView* elementFrameView = elementFrame->view(); if (!elementFrameView) return; // Tell the client if the element is either in a scrollable container or in a fixed positioned container. // On the client side, this info is being used to hide the tap highlight window on scroll. RenderLayer* layer = m_webPage->enclosingFixedPositionedAncestorOrSelfIfFixedPositioned(renderer->enclosingLayer()); bool shouldHideTapHighlightRightAfterScrolling = !layer->renderer()->isRenderView(); shouldHideTapHighlightRightAfterScrolling |= !!m_webPage->m_inRegionScroller->d->node(); IntPoint framePos(m_webPage->frameOffset(elementFrame)); // FIXME: We can get more precise on the <map> case by calculating the rect with HTMLAreaElement::computeRect(). IntRect absoluteRect(renderer->absoluteClippedOverflowRect()); absoluteRect.move(framePos.x(), framePos.y()); IntRect clippingRect; if (elementFrame == m_webPage->mainFrame()) clippingRect = IntRect(IntPoint(0, 0), elementFrameView->contentsSize()); else clippingRect = m_webPage->mainFrame()->view()->windowToContents(m_webPage->getRecursiveVisibleWindowRect(elementFrameView, true /*noClipToMainFrame*/)); clippingRect = intersection(absoluteRect, clippingRect); Vector<FloatQuad> focusRingQuads; renderer->absoluteFocusRingQuads(focusRingQuads); Platform::IntRectRegion region; for (size_t i = 0; i < focusRingQuads.size(); ++i) { IntRect rect = focusRingQuads[i].enclosingBoundingBox(); rect.move(framePos.x(), framePos.y()); IntRect clippedRect = intersection(clippingRect, rect); clippedRect.inflate(2); region = unionRegions(region, Platform::IntRect(clippedRect)); } Color highlightColor = element->renderStyle()->tapHighlightColor(); m_webPage->m_tapHighlight->draw(region, highlightColor.red(), highlightColor.green(), highlightColor.blue(), highlightColor.alpha(), shouldHideTapHighlightRightAfterScrolling); }
static bool paintMediaSlider(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect) { HTMLMediaElement* mediaElement = toParentMediaElement(object); if (!mediaElement) return false; RenderStyle* style = object->style(); GraphicsContext* context = paintInfo.context; // Draw the border of the time bar. // FIXME: this should be a rounded rect but need to fix GraphicsContextSkia first. // https://bugs.webkit.org/show_bug.cgi?id=30143 context->save(); context->setShouldAntialias(true); context->setStrokeStyle(SolidStroke); context->setStrokeColor(style->visitedDependentColor(CSSPropertyBorderLeftColor), ColorSpaceDeviceRGB); context->setStrokeThickness(style->borderLeftWidth()); context->setFillColor(style->visitedDependentColor(CSSPropertyBackgroundColor), ColorSpaceDeviceRGB); context->drawRect(rect); context->restore(); // Draw the buffered ranges. // FIXME: Draw multiple ranges if there are multiple buffered ranges. IntRect bufferedRect = rect; bufferedRect.inflate(-style->borderLeftWidth()); double bufferedWidth = 0.0; if (mediaElement->percentLoaded() > 0.0) { // Account for the width of the slider thumb. Image* mediaSliderThumb = getMediaSliderThumb(); double thumbWidth = mediaSliderThumb->width() / 2.0 + 1.0; double rectWidth = bufferedRect.width() - thumbWidth; if (rectWidth < 0.0) rectWidth = 0.0; bufferedWidth = rectWidth * mediaElement->percentLoaded() + thumbWidth; } bufferedRect.setWidth(bufferedWidth); // Don't bother drawing an empty area. if (!bufferedRect.isEmpty()) { IntPoint sliderTopLeft = bufferedRect.location(); IntPoint sliderTopRight = sliderTopLeft; sliderTopRight.move(0, bufferedRect.height()); RefPtr<Gradient> gradient = Gradient::create(sliderTopLeft, sliderTopRight); Color startColor = object->style()->visitedDependentColor(CSSPropertyColor); gradient->addColorStop(0.0, startColor); gradient->addColorStop(1.0, Color(startColor.red() / 2, startColor.green() / 2, startColor.blue() / 2, startColor.alpha())); context->save(); context->setStrokeStyle(NoStroke); context->setFillGradient(gradient); context->fillRect(bufferedRect); context->restore(); } return true; }
void scrollIntoView(Element* element) { // NOTE: Element's scrollIntoView method could had been used here, but // it is preferable to inflate |element|'s bounding rect a bit before // scrolling it for accurate reason. // Element's scrollIntoView method does not provide this flexibility. static const int fudgeFactor = 2; IntRect bounds = element->getRect(); bounds.inflate(fudgeFactor); element->renderer()->enclosingLayer()->scrollRectToVisible(bounds); }
void GLWebViewState::addDirtyArea(const IntRect& rect) { if (rect.isEmpty()) return; IntRect inflatedRect = rect; inflatedRect.inflate(8); if (m_frameworkLayersInval.isEmpty()) m_frameworkLayersInval = inflatedRect; else m_frameworkLayersInval.unite(inflatedRect); }
static void adjustRectForFocus(GtkWidget* widget, IntRect& rect, bool ignoreInteriorFocusProperty = false) { gint focusWidth, focusPad; gboolean interiorFocus = 0; gtk_widget_style_get(widget, "interior-focus", &interiorFocus, "focus-line-width", &focusWidth, "focus-padding", &focusPad, NULL); if (!ignoreInteriorFocusProperty && interiorFocus) return; rect.inflate(focusWidth + focusPad); }
void ScrollbarThemeOpus::paintThumb(GraphicsContext* context, ScrollbarThemeClient* scrollbar, const IntRect& rect) { if (!clientOpacityMap->contains(scrollbar)) return; int opacity = clientOpacityMap->get(scrollbar); if (!opacity) return; IntRect thumbRect = rect; thumbRect.inflate(-1); int scrollThickness = thumbRect.width() < thumbRect.height() ? thumbRect.width() : thumbRect.height(); IntSize curveSize(scrollThickness / 2, scrollThickness / 2); Color fillColor(makeRGBA(128, 128, 128, opacity)); context->fillRoundedRect(thumbRect, curveSize, curveSize, curveSize, curveSize, fillColor, ColorSpaceDeviceRGB); }
// It's called a "focus ring" but it's not a ring, it's a (possibly rounded) rect around // something that is highlighted, like a text input. void GraphicsContext::drawFocusRing(const Color& color) { if (paintingDisabled()) return; const int radius = (focusRingWidth() - 1) / 2; const int offset = radius + focusRingOffset(); const Vector<IntRect>& rects = focusRingRects(); unsigned rectCount = rects.size(); IntRect finalFocusRect; for (unsigned i = 0; i < rectCount; i++) { IntRect focusRect = rects[i]; focusRect.setLocation(focusRect.location() + origin()); focusRect.inflate(offset); finalFocusRect.unite(focusRect); } bool useDefaultFocusRingDraw = true; EA::WebKit::ViewNotification* pVN = EA::WebKit::GetViewNotification(); EA::WebKit::FocusRingDrawInfo focusInfo; EA::Raster::ISurface* pSurface = m_data->surface; EA::WebKit::View* pView = NULL; if(pSurface) pView = static_cast<EA::WebKit::View*> (pSurface->GetUserData()); // Need to verify that this cast is always safe... focusInfo.mpView = pView; EA::WebKit::GetEARasterInstance()->IntRectToEARect(finalFocusRect, focusInfo.mFocusRect); focusInfo.mFocusRect.h -= 1; focusInfo.mFocusRect.w -= 1; focusInfo.mSuggestedColor.setRGB(color.rgb()); focusInfo.mpSurface = m_data->surface; if(pVN) { useDefaultFocusRingDraw = !pVN->DrawFocusRing(focusInfo); } //default focus rect draw method if(useDefaultFocusRingDraw) { // Force the alpha to 50%. This matches what the Mac does with outline rings. const EA::Raster::Color ringColor(color.red(), color.green(), color.blue(), 127); EA::WebKit::GetEARasterInstance()->RectangleColor(focusInfo.mpSurface, focusInfo.mFocusRect, ringColor); } }
void RenderImage::areaElementFocusChanged(HTMLAreaElement* areaElement) { ASSERT(areaElement->imageElement() == node()); Path path = areaElement->computePath(this); if (path.isEmpty()) return; RenderStyle* areaElementStyle = areaElement->computedStyle(); unsigned short outlineWidth = areaElementStyle->outlineWidth(); IntRect repaintRect = enclosingIntRect(path.boundingRect()); repaintRect.moveBy(-absoluteContentBox().location()); repaintRect.inflate(outlineWidth); repaintRectangle(repaintRect); }
IntRect LayerWebKitThread::mapFromTransformed(const IntRect& contentsRect, double scale) { IntRect untransformedContentsRect = contentsRect; if (scale != 1.0) { TransformationMatrix matrix; matrix.scale(1.0 / scale); untransformedContentsRect = matrix.mapRect(contentsRect); // We extract from the contentsRect but draw a slightly larger region than // we were told to, in order to avoid pixels being rendered only partially. const int atLeastOneDevicePixel = static_cast<int>(ceilf(1.0 / scale)); untransformedContentsRect.inflate(atLeastOneDevicePixel); } return untransformedContentsRect; }
bool RenderThemeGtk::paintMediaSliderTrack(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) { GraphicsContext* context = paintInfo.context; context->fillRect(FloatRect(r), m_panelColor, DeviceColorSpace); context->fillRect(FloatRect(IntRect(r.x(), r.y() + (r.height() - m_mediaSliderHeight) / 2, r.width(), m_mediaSliderHeight)), m_sliderColor, DeviceColorSpace); RenderStyle* style = o->style(); HTMLMediaElement* mediaElement = toParentMediaElement(o); if (!mediaElement) return false; // Draw the buffered ranges. This code is highly inspired from // Chrome. // FIXME: Draw multiple ranges if there are multiple buffered // ranges. The current implementation of the player is always // buffering a single range anyway. IntRect bufferedRect = r; bufferedRect.inflate(-style->borderLeftWidth()); bufferedRect.setWidth((bufferedRect.width() * mediaElement->percentLoaded())); // Don't bother drawing an empty area. if (bufferedRect.isEmpty()) return false; IntPoint sliderTopLeft = bufferedRect.location(); IntPoint sliderTopRight = sliderTopLeft; sliderTopRight.move(0, bufferedRect.height()); RefPtr<Gradient> gradient = Gradient::create(sliderTopLeft, sliderTopRight); Color startColor = m_panelColor; gradient->addColorStop(0.0, startColor); gradient->addColorStop(1.0, Color(startColor.red() / 2, startColor.green() / 2, startColor.blue() / 2, startColor.alpha())); context->save(); context->setStrokeStyle(NoStroke); context->setFillGradient(gradient); context->fillRect(bufferedRect); context->restore(); return false; }
virtual void paint(GraphicsContext* ctx, const IntRect& rect) { // Most of this code is copied from PluginView::paintMissingPluginIcon // with slight modification. static RefPtr<Image> image; if (!image) { image = Image::loadPlatformResource("togglePlugin"); } IntRect imageRect(x(), y(), image->width(), image->height()); int xOffset = (width() - imageRect.width()) >> 1; int yOffset = (height() - imageRect.height()) >> 1; imageRect.move(xOffset, yOffset); if (!rect.intersects(imageRect)) return; // FIXME: We need to clip similarly to paintMissingPluginIcon but it is // way screwed up right now. It has something to do with how we tell // webkit the scroll position and it causes the placeholder to get // clipped very badly. http://b/issue?id=2533303 ctx->save(); ctx->clip(frameRect()); ctx->setFillColor(Color::white, DeviceColorSpace); ctx->fillRect(frameRect()); if (frameRect().contains(imageRect)) { // Leave a 2 pixel padding. const int pixelWidth = 2; IntRect innerRect = frameRect(); innerRect.inflate(-pixelWidth); // Draw a 2 pixel light gray border. ctx->setStrokeColor(Color::lightGray, DeviceColorSpace); ctx->strokeRect(innerRect, pixelWidth); } // Draw the image in the center ctx->drawImage(image.get(), DeviceColorSpace, imageRect.location()); ctx->restore(); }
DrawingRecorder::DrawingRecorder(GraphicsContext& context, const DisplayItemClientWrapper& displayItemClient, DisplayItem::Type displayItemType, const FloatRect& cullRect) : m_context(context) , m_displayItemClient(displayItemClient) , m_displayItemType(displayItemType) #if ENABLE(ASSERT) , m_displayItemPosition(m_context.displayItemList()->newDisplayItems().size()) , m_underInvalidationCheckingMode(DrawingDisplayItem::CheckPicture) #endif { ASSERT(context.displayItemList()); if (context.displayItemList()->displayItemConstructionIsDisabled()) return; // Must check DrawingRecorder::useCachedDrawingIfPossible before creating the DrawingRecorder. ASSERT((RuntimeEnabledFeatures::slimmingPaintOffsetCachingEnabled() && context.displayItemList()->paintOffsetWasInvalidated(displayItemClient.displayItemClient())) || RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled() || !useCachedDrawingIfPossible(m_context, m_displayItemClient, m_displayItemType)); ASSERT(DisplayItem::isDrawingType(displayItemType)); #if ENABLE(ASSERT) context.setInDrawingRecorder(true); #endif context.beginRecording(cullRect); #if ENABLE(ASSERT) if (RuntimeEnabledFeatures::slimmingPaintStrictCullRectClippingEnabled()) { // Skia depends on the cull rect containing all of the display item commands. When strict // cull rect clipping is enabled, make this explicit. This allows us to identify potential // incorrect cull rects that might otherwise be masked due to Skia internal optimizations. context.save(); IntRect verificationClip = enclosingIntRect(cullRect); // Expand the verification clip by one pixel to account for Skia's SkCanvas::getClipBounds() // expansion, used in testing cull rects. // TODO(schenney) This is not the best place to do this. Ideally, we would expand by one pixel // in device (pixel) space, but to do that we would need to add the verification mode to Skia. verificationClip.inflate(1); context.clipRect(verificationClip, NotAntiAliased, SkRegion::kIntersect_Op); } #endif }
void RenderReplaced::adjustOverflowForBoxShadow() { IntRect overflow; for (ShadowData* boxShadow = style()->boxShadow(); boxShadow; boxShadow = boxShadow->next) { IntRect shadow = borderBox(); shadow.move(boxShadow->x, boxShadow->y); shadow.inflate(boxShadow->blur); overflow.unite(shadow); } if (!overflow.isEmpty()) { if (!gOverflowRectMap) gOverflowRectMap = new OverflowRectMap(); overflow.unite(borderBox()); gOverflowRectMap->set(this, overflow); m_hasOverflow = true; } else if (m_hasOverflow) { gOverflowRectMap->remove(this); m_hasOverflow = false; } }
void FindController::drawRect(PageOverlay* pageOverlay, GraphicsContext& graphicsContext, const IntRect& dirtyRect) { float fractionFadedIn = pageOverlay->fractionFadedIn(); Vector<IntRect> rects = rectsForTextMatches(); // Draw the background. graphicsContext.fillRect(dirtyRect, overlayBackgroundColor(fractionFadedIn), ColorSpaceSRGB); { GraphicsContextStateSaver stateSaver(graphicsContext); graphicsContext.setShadow(FloatSize(shadowOffsetX, shadowOffsetY), shadowBlurRadius, holeShadowColor(fractionFadedIn), ColorSpaceSRGB); graphicsContext.setFillColor(holeFillColor(fractionFadedIn), ColorSpaceSRGB); // Draw white frames around the holes. for (size_t i = 0; i < rects.size(); ++i) { IntRect whiteFrameRect = rects[i]; whiteFrameRect.inflate(1); graphicsContext.fillRect(whiteFrameRect); } } graphicsContext.setFillColor(Color::transparent, ColorSpaceSRGB); // Clear out the holes. for (size_t i = 0; i < rects.size(); ++i) graphicsContext.fillRect(rects[i]); if (!m_isShowingFindIndicator) return; if (Frame* selectedFrame = frameWithSelection(m_webPage->corePage())) { IntRect findIndicatorRect = selectedFrame->view()->contentsToWindow(enclosingIntRect(selectedFrame->selection()->bounds())); if (findIndicatorRect != m_findIndicatorRect) hideFindIndicator(); } }
void FindController::drawRect(PageOverlay*, GraphicsContext& graphicsContext, const IntRect& dirtyRect) { Color overlayBackgroundColor(0.1f, 0.1f, 0.1f, 0.25f); Vector<IntRect> rects = rectsForTextMatches(); // Draw the background. graphicsContext.fillRect(dirtyRect, overlayBackgroundColor, ColorSpaceSRGB); { GraphicsContextStateSaver stateSaver(graphicsContext); #if ENABLE(LEGACY_FIND_INDICATOR_STYLE) graphicsContext.setShadow(FloatSize(shadowOffsetX, shadowOffsetY), shadowBlurRadius, Color::black, ColorSpaceSRGB); #endif graphicsContext.setFillColor(Color::white, ColorSpaceSRGB); // Draw white frames around the holes. for (auto& rect : rects) { IntRect whiteFrameRect = rect; whiteFrameRect.inflate(1); graphicsContext.fillRect(whiteFrameRect); } } // Clear out the holes. for (auto& rect : rects) graphicsContext.clearRect(rect); if (!m_isShowingFindIndicator) return; if (Frame* selectedFrame = frameWithSelection(m_webPage->corePage())) { IntRect findIndicatorRect = selectedFrame->view()->contentsToWindow(enclosingIntRect(selectedFrame->selection().selectionBounds())); if (findIndicatorRect != m_findIndicatorRect) hideFindIndicator(); } }
IntRect RenderReplaced::absoluteClippedOverflowRect() { if (style()->visibility() != VISIBLE && !enclosingLayer()->hasVisibleContent()) return IntRect(); // The selectionRect can project outside of the overflowRect, so use // that for repainting to avoid selection painting glitches IntRect r = localSelectionRect(false); RenderView* v = view(); if (v) r.move(v->layoutDelta()); if (style()) { if (style()->hasAppearance()) // The theme may wish to inflate the rect used when repainting. theme()->adjustRepaintRect(this, r); if (v) r.inflate(style()->outlineSize()); } computeAbsoluteRepaintRect(r); return r; }
void LayerWebKitThread::paintContents(BlackBerry::Platform::Graphics::Buffer* buffer, const IntRect& contentsRect, double scale) { if (!drawsContent() && !contents()) return; if (!buffer) return; IntRect untransformedContentsRect = contentsRect; FloatRect clipRect = contentsRect; if (scale != 1.0) { TransformationMatrix matrix; matrix.scale(1.0 / scale); untransformedContentsRect = matrix.mapRect(contentsRect); clipRect = matrix.mapRect(clipRect); // We extract from the contentsRect but draw a slightly larger region than // we were told to, in order to avoid pixels being rendered only partially. const int atLeastOneDevicePixel = static_cast<int>(ceilf(1.0 / scale)); untransformedContentsRect.inflate(atLeastOneDevicePixel); } PlatformGraphicsContext* platformContext = lockBufferDrawable(buffer); GraphicsContext graphicsContext(platformContext); if (contents()) { // Images needs to be centered and will be scaled to fit the bounds on the compositing thread if (!contents()->size().isEmpty()) graphicsContext.drawImage(contents(), ColorSpaceDeviceRGB, IntPoint(0, 0)); } else { graphicsContext.translate(-contentsRect.x(), -contentsRect.y()); graphicsContext.scale(FloatSize(scale, scale)); graphicsContext.clip(clipRect); m_owner->paintGraphicsLayerContents(graphicsContext, untransformedContentsRect); } releaseBufferDrawable(buffer); }
SkBitmap LayerWebKitThread::paintContents(const IntRect& contentsRect, double scale, bool* isSolidColor, Color* color) { // Don't try to allocate image data bigger than this. This should be big // enough to accomodate a huge iScroll use case. // FIXME: This is a hack to work around a crash bug on maps.bing.com where // a (visually empty) layer becomes too big. static const int maximumBitmapSizeInBytes = 40 * 1024 * 1024; static const int bytesPerPixel = 4; if (isSolidColor) *isSolidColor = false; if (contentsRect.width() * contentsRect.height() * bytesPerPixel > maximumBitmapSizeInBytes) return SkBitmap(); SkBitmap bitmap; // Keep the canvas alive until we're done extracting its pixels OwnPtr<InstrumentedPlatformCanvas> canvas; if (drawsContent()) { // Layer contents must be drawn into a canvas. IntRect untransformedContentsRect = contentsRect; canvas = adoptPtr(new InstrumentedPlatformCanvas(contentsRect.width(), contentsRect.height())); PlatformContextSkia skiaContext(canvas.get()); GraphicsContext graphicsContext(&skiaContext); graphicsContext.translate(-contentsRect.x(), -contentsRect.y()); if (scale != 1.0) { TransformationMatrix matrix; matrix.scale(1.0 / scale); untransformedContentsRect = matrix.mapRect(contentsRect); // We extract from the contentsRect but draw a slightly larger region than // we were told to, in order to avoid pixels being rendered only partially. const int atLeastOneDevicePixel = static_cast<int>(ceilf(1.0 / scale)); untransformedContentsRect.inflate(atLeastOneDevicePixel); graphicsContext.scale(FloatSize(scale, scale)); } // RenderLayerBacking doesn't always clip, so we need to do this by ourselves. graphicsContext.clip(untransformedContentsRect); m_owner->paintGraphicsLayerContents(graphicsContext, untransformedContentsRect); bitmap = canvas->getDevice()->accessBitmap(false); if (isSolidColor) { *isSolidColor = canvas->isSolidColor(); if (color) *color = canvas->solidColor(); } } ASSERT(!bitmap.isNull()); // FIXME: do we need to support more image configurations? ASSERT(bitmap.config() == SkBitmap::kARGB_8888_Config); if (bitmap.config() != SkBitmap::kARGB_8888_Config) return SkBitmap(); return bitmap; }
void TileGrid::prepareGL(GLWebViewState* state, float scale, const IntRect& prepareArea, const IntRect& fullContentArea, TilePainter* painter, int regionFlags, bool isLowResPrefetch, bool updateWithBlit) { // first, how many tiles do we need m_area = computeTilesArea(prepareArea, scale); if (m_area.isEmpty()) return; ALOGV("prepare TileGrid %p with scale %.2f, prepareArea " " %d, %d - %d x %d, corresponding to %d, %d x - %d x %d tiles", this, scale, prepareArea.x(), prepareArea.y(), prepareArea.width(), prepareArea.height(), m_area.x(), m_area.y(), m_area.width(), m_area.height()); bool goingDown = m_prevTileY < m_area.y(); m_prevTileY = m_area.y(); TilesManager* tilesManager = TilesManager::instance(); if (scale != m_scale) tilesManager->removeOperationsForFilter(new ScaleFilter(painter, m_scale)); m_scale = scale; // apply dirty region to affected tiles if (!m_dirtyRegion.isEmpty()) { for (unsigned int i = 0; i < m_tiles.size(); i++) m_tiles[i]->markAsDirty(m_dirtyRegion); // log inval region for the base surface if (m_isBaseSurface && tilesManager->getProfiler()->enabled()) { SkRegion::Iterator iterator(m_dirtyRegion); while (!iterator.done()) { SkIRect r = iterator.rect(); tilesManager->getProfiler()->nextInval(r, scale); iterator.next(); } } m_dirtyRegion.setEmpty(); } if (regionFlags & StandardRegion) { for (int i = 0; i < m_area.width(); i++) { if (goingDown) { for (int j = 0; j < m_area.height(); j++) prepareTile(m_area.x() + i, m_area.y() + j, painter, state, isLowResPrefetch, false, updateWithBlit); } else { for (int j = m_area.height() - 1; j >= 0; j--) prepareTile(m_area.x() + i, m_area.y() + j, painter, state, isLowResPrefetch, false, updateWithBlit); } } } if (regionFlags & ExpandedRegion) { IntRect fullArea = computeTilesArea(fullContentArea, scale); IntRect expandedArea = m_area; // on systems reporting highEndGfx=true and useMinimalMemory not set, use expanded bounds if (tilesManager->highEndGfx() && !tilesManager->useMinimalMemory()) expandedArea.inflate(EXPANDED_BOUNDS_INFLATE); if (isLowResPrefetch) expandedArea.inflateY(EXPANDED_PREFETCH_BOUNDS_Y_INFLATE); // clip painting area to content expandedArea.intersect(fullArea); for (int i = expandedArea.x(); i < expandedArea.maxX(); i++) for (int j = expandedArea.y(); j < expandedArea.maxY(); j++) if (!m_area.contains(i, j)) prepareTile(i, j, painter, state, isLowResPrefetch, true, updateWithBlit); } }