bool RenderThemeGtk::paintMediaSliderTrack(RenderObject* o, const 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 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((start * totalWidth) / mediaDuration, 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; }
static bool isDeletableElement(const Node* node) { if (!node || !node->isHTMLElement() || !node->inDocument() || !node->rendererIsEditable()) return false; // In general we want to only draw the UI around object of a certain area, but we still keep the min width/height to // make sure we don't end up with very thin or very short elements getting the UI. const int minimumArea = 2500; const int minimumWidth = 48; const int minimumHeight = 16; const unsigned minimumVisibleBorders = 1; RenderObject* renderer = node->renderer(); if (!renderer || !renderer->isBox()) return false; // Disallow the body element since it isn't practical to delete, and the deletion UI would be clipped. if (node->hasTagName(bodyTag)) return false; // Disallow elements with any overflow clip, since the deletion UI would be clipped as well. <rdar://problem/6840161> if (renderer->hasOverflowClip()) return false; // Disallow Mail blockquotes since the deletion UI would get in the way of editing for these. if (isMailBlockquote(node)) return false; RenderBox* box = toRenderBox(renderer); IntRect borderBoundingBox = box->borderBoundingBox(); if (borderBoundingBox.width() < minimumWidth || borderBoundingBox.height() < minimumHeight) return false; if ((borderBoundingBox.width() * borderBoundingBox.height()) < minimumArea) return false; if (renderer->isTable()) return true; if (node->hasTagName(ulTag) || node->hasTagName(olTag) || node->hasTagName(iframeTag)) return true; if (renderer->isPositioned()) return true; if (renderer->isRenderBlock() && !renderer->isTableCell()) { RenderStyle* style = renderer->style(); if (!style) return false; // Allow blocks that have background images if (style->hasBackgroundImage()) { for (const FillLayer* background = style->backgroundLayers(); background; background = background->next()) { if (background->image() && background->image()->canRender(1)) return true; } } // Allow blocks with a minimum number of non-transparent borders unsigned visibleBorders = style->borderTop().isVisible() + style->borderBottom().isVisible() + style->borderLeft().isVisible() + style->borderRight().isVisible(); if (visibleBorders >= minimumVisibleBorders) return true; // Allow blocks that have a different background from it's parent ContainerNode* parentNode = node->parentNode(); if (!parentNode) return false; RenderObject* parentRenderer = parentNode->renderer(); if (!parentRenderer) return false; RenderStyle* parentStyle = parentRenderer->style(); if (!parentStyle) return false; if (renderer->hasBackground() && (!parentRenderer->hasBackground() || style->visitedDependentColor(CSSPropertyBackgroundColor) != parentStyle->visitedDependentColor(CSSPropertyBackgroundColor))) return true; } return false; }
static IntPoint innerBottomRight(const IntRect& rect) { // Actually, the rect does not contain rect.maxX(). Refer to IntRect::contain. return IntPoint(rect.maxX() - 1, rect.maxY() - 1); }
IntRect PageClientImpl::rootViewToScreen(const IntRect& rect) { return IntRect(convertWidgetPointToScreenPoint(m_viewWidget, rect.location()), rect.size()); }
FloatRect::FloatRect(const IntRect& r) : m_location(r.location()), m_size(r.size()) {}
// FIXME: This doesn't behave correctly for floating or positioned images, but WebCore doesn't handle those well // during selection creation yet anyway. // FIXME: We can't tell whether or not we contain the start or end of the selected Range using only the offsets // of the start and end, we need to know the whole Position. void RenderImage::collectSelectionRects(Vector<SelectionRect>& rects, unsigned, unsigned) { RenderBlock* containingBlock = this->containingBlock(); IntRect imageRect; // FIXME: It doesn't make sense to package line bounds into SelectionRects. We should find // the right and left extent of the selection once for the entire selected Range, perhaps // using the Range's common ancestor. IntRect lineExtentRect; bool isFirstOnLine = false; bool isLastOnLine = false; InlineBox* inlineBox = inlineBoxWrapper(); if (!inlineBox) { // This is a block image. imageRect = IntRect(0, 0, width(), height()); isFirstOnLine = true; isLastOnLine = true; lineExtentRect = imageRect; if (containingBlock->isHorizontalWritingMode()) { lineExtentRect.setX(containingBlock->x()); lineExtentRect.setWidth(containingBlock->width()); } else { lineExtentRect.setY(containingBlock->y()); lineExtentRect.setHeight(containingBlock->height()); } } else { LayoutUnit selectionTop = !containingBlock->style().isFlippedBlocksWritingMode() ? inlineBox->root().selectionTop() - logicalTop() : logicalBottom() - inlineBox->root().selectionBottom(); imageRect = IntRect(0, selectionTop, logicalWidth(), inlineBox->root().selectionHeight()); isFirstOnLine = !inlineBox->previousOnLineExists(); isLastOnLine = !inlineBox->nextOnLineExists(); LogicalSelectionOffsetCaches cache(*containingBlock); LayoutUnit leftOffset = containingBlock->logicalLeftSelectionOffset(*containingBlock, inlineBox->logicalTop(), cache); LayoutUnit rightOffset = containingBlock->logicalRightSelectionOffset(*containingBlock, inlineBox->logicalTop(), cache); lineExtentRect = IntRect(leftOffset - logicalLeft(), imageRect.y(), rightOffset - leftOffset, imageRect.height()); if (!inlineBox->isHorizontal()) { imageRect = imageRect.transposedRect(); lineExtentRect = lineExtentRect.transposedRect(); } } bool isFixed = false; IntRect absoluteBounds = localToAbsoluteQuad(FloatRect(imageRect), UseTransforms, &isFixed).enclosingBoundingBox(); IntRect lineExtentBounds = localToAbsoluteQuad(FloatRect(lineExtentRect)).enclosingBoundingBox(); if (!containingBlock->isHorizontalWritingMode()) lineExtentBounds = lineExtentBounds.transposedRect(); // FIXME: We should consider either making SelectionRect a struct or better organize its optional fields into // an auxiliary struct to simplify its initialization. rects.append(SelectionRect(absoluteBounds, containingBlock->style().direction(), lineExtentBounds.x(), lineExtentBounds.maxX(), lineExtentBounds.maxY(), 0, false /* line break */, isFirstOnLine, isLastOnLine, false /* contains start */, false /* contains end */, containingBlock->style().isHorizontalWritingMode(), isFixed, false /* ruby text */, view().pageNumberForBlockProgressionOffset(absoluteBounds.x()))); }
bool Surface::blitFromContents(Tile* tile) { if (!singleLayer() || !tile || !getFirstLayer() || !getFirstLayer()->content()) return false; if (tile->frontTexture() != tile->lastDrawnTexture()) { // the below works around an issue where glTexSubImage2d can't update a // texture that hasn't drawn yet by drawing it off screen. // glFlush() and glFinish() work also, but are likely more wasteful. SkRect rect = SkRect::MakeXYWH(-100, -100, 0, 0); FloatRect fillPortion(0, 0, 0, 0); tile->frontTexture()->drawGL(false, rect, 1.0f, 0, false, true, fillPortion); } LayerContent* content = getFirstLayer()->content(); // Extract the dirty rect from the region. Note that this is *NOT* constrained // to this tile IntRect dirtyRect = tile->dirtyArea().getBounds(); IntRect tileRect = IntRect(tile->x() * TilesManager::tileWidth(), tile->y() * TilesManager::tileHeight(), TilesManager::tileWidth(), TilesManager::tileHeight()); FloatRect tileRectInDoc = tileRect; tileRectInDoc.scale(1 / tile->scale()); dirtyRect.intersect(enclosingIntRect(tileRectInDoc)); PrerenderedInval* prerenderedInval = content->prerenderForRect(dirtyRect); if (!prerenderedInval || prerenderedInval->bitmap.isNull()) return false; SkBitmap sourceBitmap = prerenderedInval->bitmap; // Calculate the screen rect that is dirty, then intersect it with the // tile's screen rect so that we end up with the pixels we need to blit FloatRect screenDirty = dirtyRect; screenDirty.scale(tile->scale()); IntRect enclosingScreenDirty = enclosingIntRect(screenDirty); enclosingScreenDirty.intersect(tileRect); if (enclosingScreenDirty.isEmpty()) return false; // Make sure the screen area we want to blit is contained by the // prerendered screen area if (!prerenderedInval->screenArea.contains(enclosingScreenDirty)) { ALOGD("prerendered->screenArea " INT_RECT_FORMAT " doesn't contain " "enclosingScreenDirty " INT_RECT_FORMAT, INT_RECT_ARGS(prerenderedInval->screenArea), INT_RECT_ARGS(enclosingScreenDirty)); return false; } IntPoint origin = prerenderedInval->screenArea.location(); SkBitmap subset; subset.setConfig(sourceBitmap.config(), enclosingScreenDirty.width(), enclosingScreenDirty.height()); subset.allocPixels(); int topOffset = enclosingScreenDirty.y() - prerenderedInval->screenArea.y(); int leftOffset = enclosingScreenDirty.x() - prerenderedInval->screenArea.x(); if (!GLUtils::deepCopyBitmapSubset(sourceBitmap, subset, leftOffset, topOffset)) return false; // Now upload SkIRect textureInval = SkIRect::MakeXYWH(enclosingScreenDirty.x() - tileRect.x(), enclosingScreenDirty.y() - tileRect.y(), enclosingScreenDirty.width(), enclosingScreenDirty.height()); GLUtils::updateTextureWithBitmap(tile->frontTexture()->m_ownTextureId, subset, textureInval); tile->onBlitUpdate(); return true; }
bool RenderThemeWin::paintSearchFieldCancelButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) { IntRect bounds = r; ASSERT(o->parent()); if (!o->parent() || !o->parent()->isBox()) return false; RenderBox* parentRenderBox = toRenderBox(o->parent()); IntRect parentBox = parentRenderBox->absoluteContentBox(); // Make sure the scaled button stays square and will fit in its parent's box bounds.setHeight(min(parentBox.width(), min(parentBox.height(), bounds.height()))); bounds.setWidth(bounds.height()); // Center the button vertically. Round up though, so if it has to be one pixel off-center, it will // be one pixel closer to the bottom of the field. This tends to look better with the text. bounds.setY(parentBox.y() + (parentBox.height() - bounds.height() + 1) / 2); static Image* cancelImage = Image::loadPlatformResource("searchCancel").releaseRef(); static Image* cancelPressedImage = Image::loadPlatformResource("searchCancelPressed").releaseRef(); paintInfo.context->drawImage(isPressed(o) ? cancelPressedImage : cancelImage, o->style()->colorSpace(), bounds); return false; }
// addFocusRingRects is called from paintOutline and needs to be in the same coordinates as the paintOuline call void RenderSVGContainer::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint&, const RenderLayerModelObject*) { IntRect paintRectInParent = enclosingIntRect(localToParentTransform().mapRect(repaintRectInLocalCoordinates())); if (!paintRectInParent.isEmpty()) rects.append(paintRectInParent); }
bool ScrollbarThemeComposite::paint(ScrollbarThemeClient* scrollbar, GraphicsContext* graphicsContext, const IntRect& damageRect) { // Create the ScrollbarControlPartMask based on the damageRect ScrollbarControlPartMask scrollMask = NoPart; IntRect backButtonStartPaintRect; IntRect backButtonEndPaintRect; IntRect forwardButtonStartPaintRect; IntRect forwardButtonEndPaintRect; if (hasButtons(scrollbar)) { backButtonStartPaintRect = backButtonRect(scrollbar, BackButtonStartPart, true); if (damageRect.intersects(backButtonStartPaintRect)) scrollMask |= BackButtonStartPart; backButtonEndPaintRect = backButtonRect(scrollbar, BackButtonEndPart, true); if (damageRect.intersects(backButtonEndPaintRect)) scrollMask |= BackButtonEndPart; forwardButtonStartPaintRect = forwardButtonRect(scrollbar, ForwardButtonStartPart, true); if (damageRect.intersects(forwardButtonStartPaintRect)) scrollMask |= ForwardButtonStartPart; forwardButtonEndPaintRect = forwardButtonRect(scrollbar, ForwardButtonEndPart, true); if (damageRect.intersects(forwardButtonEndPaintRect)) scrollMask |= ForwardButtonEndPart; } IntRect startTrackRect; IntRect thumbRect; IntRect endTrackRect; IntRect trackPaintRect = trackRect(scrollbar, true); if (damageRect.intersects(trackPaintRect)) scrollMask |= TrackBGPart; bool thumbPresent = hasThumb(scrollbar); if (thumbPresent) { IntRect track = trackRect(scrollbar); splitTrack(scrollbar, track, startTrackRect, thumbRect, endTrackRect); if (damageRect.intersects(thumbRect)) scrollMask |= ThumbPart; if (damageRect.intersects(startTrackRect)) scrollMask |= BackTrackPart; if (damageRect.intersects(endTrackRect)) scrollMask |= ForwardTrackPart; } // Paint the scrollbar background (only used by custom CSS scrollbars). paintScrollbarBackground(graphicsContext, scrollbar); // Paint the back and forward buttons. if (scrollMask & BackButtonStartPart) paintButton(graphicsContext, scrollbar, backButtonStartPaintRect, BackButtonStartPart); if (scrollMask & BackButtonEndPart) paintButton(graphicsContext, scrollbar, backButtonEndPaintRect, BackButtonEndPart); if (scrollMask & ForwardButtonStartPart) paintButton(graphicsContext, scrollbar, forwardButtonStartPaintRect, ForwardButtonStartPart); if (scrollMask & ForwardButtonEndPart) paintButton(graphicsContext, scrollbar, forwardButtonEndPaintRect, ForwardButtonEndPart); if (scrollMask & TrackBGPart) paintTrackBackground(graphicsContext, scrollbar, trackPaintRect); if ((scrollMask & ForwardTrackPart) || (scrollMask & BackTrackPart)) { // Paint the track pieces above and below the thumb. if (scrollMask & BackTrackPart) paintTrackPiece(graphicsContext, scrollbar, startTrackRect, BackTrackPart); if (scrollMask & ForwardTrackPart) paintTrackPiece(graphicsContext, scrollbar, endTrackRect, ForwardTrackPart); paintTickmarks(graphicsContext, scrollbar, trackPaintRect); } // Paint the thumb. if (scrollMask & ThumbPart) paintThumb(graphicsContext, scrollbar, thumbRect); return true; }
PassRefPtr<Uint8ClampedArray> getImageData(const IntRect& rect, SkCanvas* canvas, const IntSize& size) { float area = 4.0f * rect.width() * rect.height(); if (area > static_cast<float>(std::numeric_limits<int>::max())) return 0; RefPtr<Uint8ClampedArray> result = Uint8ClampedArray::createUninitialized(rect.width() * rect.height() * 4); unsigned char* data = result->data(); if (rect.x() < 0 || rect.y() < 0 || rect.maxX() > size.width() || rect.maxY() > size.height()) result->zeroFill(); unsigned destBytesPerRow = 4 * rect.width(); SkBitmap destBitmap; destBitmap.setConfig(SkBitmap::kARGB_8888_Config, rect.width(), rect.height(), destBytesPerRow); destBitmap.setPixels(data); SkCanvas::Config8888 config8888; if (multiplied == Premultiplied) config8888 = SkCanvas::kRGBA_Premul_Config8888; else config8888 = SkCanvas::kRGBA_Unpremul_Config8888; canvas->readPixels(&destBitmap, rect.x(), rect.y(), config8888); return result.release(); }
int ScrollbarThemeComposite::trackLength(ScrollbarThemeClient* scrollbar) { IntRect constrainedTrackRect = constrainTrackRectToTrackPieces(scrollbar, trackRect(scrollbar)); return (scrollbar->orientation() == HorizontalScrollbar) ? constrainedTrackRect.width() : constrainedTrackRect.height(); }
int ScrollbarThemeComposite::trackPosition(ScrollbarThemeClient* scrollbar) { IntRect constrainedTrackRect = constrainTrackRectToTrackPieces(scrollbar, trackRect(scrollbar)); return (scrollbar->orientation() == HorizontalScrollbar) ? constrainedTrackRect.x() - scrollbar->x() : constrainedTrackRect.y() - scrollbar->y(); }
void ScrollbarThemeComposite::splitTrack(ScrollbarThemeClient* scrollbar, const IntRect& unconstrainedTrackRect, IntRect& beforeThumbRect, IntRect& thumbRect, IntRect& afterThumbRect) { // This function won't even get called unless we're big enough to have some combination of these three rects where at least // one of them is non-empty. IntRect trackRect = constrainTrackRectToTrackPieces(scrollbar, unconstrainedTrackRect); int thickness = scrollbar->orientation() == HorizontalScrollbar ? scrollbar->height() : scrollbar->width(); int thumbPos = thumbPosition(scrollbar); if (scrollbar->orientation() == HorizontalScrollbar) { thumbRect = IntRect(trackRect.x() + thumbPos, trackRect.y() + (trackRect.height() - thickness) / 2, thumbLength(scrollbar), thickness); beforeThumbRect = IntRect(trackRect.x(), trackRect.y(), thumbPos + thumbRect.width() / 2, trackRect.height()); afterThumbRect = IntRect(trackRect.x() + beforeThumbRect.width(), trackRect.y(), trackRect.maxX() - beforeThumbRect.maxX(), trackRect.height()); } else { thumbRect = IntRect(trackRect.x() + (trackRect.width() - thickness) / 2, trackRect.y() + thumbPos, thickness, thumbLength(scrollbar)); beforeThumbRect = IntRect(trackRect.x(), trackRect.y(), trackRect.width(), thumbPos + thumbRect.height() / 2); afterThumbRect = IntRect(trackRect.x(), trackRect.y() + beforeThumbRect.height(), trackRect.width(), trackRect.maxY() - beforeThumbRect.maxY()); } }
void ScrollView::paint(GraphicsContext* context, const IntRect& rect) { if (platformWidget()) { Widget::paint(context, rect); return; } if (context->paintingDisabled() && !context->updatingControlTints()) return; IntRect documentDirtyRect = rect; documentDirtyRect.intersect(frameRect()); context->save(); context->translate(x(), y()); documentDirtyRect.move(-x(), -y()); context->translate(-scrollX(), -scrollY()); documentDirtyRect.move(scrollX(), scrollY()); context->clip(visibleContentRect()); paintContents(context, documentDirtyRect); context->restore(); // Now paint the scrollbars. if (!m_scrollbarsSuppressed && (m_horizontalScrollbar || m_verticalScrollbar)) { context->save(); IntRect scrollViewDirtyRect = rect; scrollViewDirtyRect.intersect(frameRect()); context->translate(x(), y()); scrollViewDirtyRect.move(-x(), -y()); if (m_horizontalScrollbar) m_horizontalScrollbar->paint(context, scrollViewDirtyRect); if (m_verticalScrollbar) m_verticalScrollbar->paint(context, scrollViewDirtyRect); IntRect hCorner; if (m_horizontalScrollbar && width() - m_horizontalScrollbar->width() > 0) { hCorner = IntRect(m_horizontalScrollbar->width(), height() - m_horizontalScrollbar->height(), width() - m_horizontalScrollbar->width(), m_horizontalScrollbar->height()); if (hCorner.intersects(scrollViewDirtyRect)) ScrollbarTheme::nativeTheme()->paintScrollCorner(this, context, hCorner); } if (m_verticalScrollbar && height() - m_verticalScrollbar->height() > 0) { IntRect vCorner(width() - m_verticalScrollbar->width(), m_verticalScrollbar->height(), m_verticalScrollbar->width(), height() - m_verticalScrollbar->height()); if (vCorner != hCorner && vCorner.intersects(scrollViewDirtyRect)) ScrollbarTheme::nativeTheme()->paintScrollCorner(this, context, vCorner); } context->restore(); } // Paint the panScroll Icon if (m_drawPanScrollIcon) { DEFINE_STATIC_LOCAL(RefPtr<Image>, panScrollIcon, (Image::loadPlatformResource("panIcon"))); context->drawImage(panScrollIcon.get(), m_panScrollIconPoint); } }
void GraphicsContext::addRoundedRectClip(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight) { if (paintingDisabled()) return; // Need sufficient width and height to contain these curves. Sanity check our top/bottom // values and our width/height values to make sure the curves can all fit. int requiredWidth = qMax(topLeft.width() + topRight.width(), bottomLeft.width() + bottomRight.width()); if (requiredWidth > rect.width()) return; int requiredHeight = qMax(topLeft.height() + bottomLeft.height(), topRight.height() + bottomRight.height()); if (requiredHeight > rect.height()) return; // Clip to our rect. clip(rect); // OK, the curves can fit. QPainterPath path; // Add the four ellipses to the path. Technically this really isn't good enough, since we could end up // not clipping the other 3/4 of the ellipse we don't care about. We're relying on the fact that for // normal use cases these ellipses won't overlap one another (or when they do the curvature of one will // be subsumed by the other). path.addEllipse(QRectF(rect.x(), rect.y(), topLeft.width() * 2, topLeft.height() * 2)); path.addEllipse(QRectF(rect.right() - topRight.width() * 2, rect.y(), topRight.width() * 2, topRight.height() * 2)); path.addEllipse(QRectF(rect.x(), rect.bottom() - bottomLeft.height() * 2, bottomLeft.width() * 2, bottomLeft.height() * 2)); path.addEllipse(QRectF(rect.right() - bottomRight.width() * 2, rect.bottom() - bottomRight.height() * 2, bottomRight.width() * 2, bottomRight.height() * 2)); int topLeftRightHeightMax = qMax(topLeft.height(), topRight.height()); int bottomLeftRightHeightMax = qMax(bottomLeft.height(), bottomRight.height()); int topBottomLeftWidthMax = qMax(topLeft.width(), bottomLeft.width()); int topBottomRightWidthMax = qMax(topRight.width(), bottomRight.width()); // Now add five rects (one for each edge rect in between the rounded corners and one for the interior). path.addRect(QRectF(rect.x() + topLeft.width(), rect.y(), rect.width() - topLeft.width() - topRight.width(), topLeftRightHeightMax)); path.addRect(QRectF(rect.x() + bottomLeft.width(), rect.bottom() - bottomLeftRightHeightMax, rect.width() - bottomLeft.width() - bottomRight.width(), bottomLeftRightHeightMax)); path.addRect(QRectF(rect.x(), rect.y() + topLeft.height(), topBottomLeftWidthMax, rect.height() - topLeft.height() - bottomLeft.height())); path.addRect(QRectF(rect.right() - topBottomRightWidthMax, rect.y() + topRight.height(), topBottomRightWidthMax, rect.height() - topRight.height() - bottomRight.height())); path.addRect(QRectF(rect.x() + topBottomLeftWidthMax, rect.y() + topLeftRightHeightMax, rect.width() - topBottomLeftWidthMax - topBottomRightWidthMax, rect.height() - topLeftRightHeightMax - bottomLeftRightHeightMax)); path.setFillRule(Qt::WindingFill); m_data->p().setClipPath(path, Qt::IntersectClip); }
void Renderer::setViewport(const IntRect& rect) { return setViewport(rect.left, rect.bottom, rect.width(), rect.height()); }
void RenderSVGModelObject::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumulatedOffset) const { IntRect rect = enclosingIntRect(strokeBoundingBox()); rect.moveBy(roundedIntPoint(accumulatedOffset)); rects.append(rect); }
IntPoint AccessibilityObject::clickPoint() const { IntRect rect = elementRect(); return IntPoint(rect.x() + rect.width() / 2, rect.y() + rect.height() / 2); }
PassRefPtr<ImageData> getImageData(const IntRect& rect, const SkBitmap& bitmap, const IntSize& size) { RefPtr<ImageData> result = ImageData::create(rect.width(), rect.height()); if (bitmap.config() == SkBitmap::kNo_Config) { // This is an empty SkBitmap that could not be configured. ASSERT(!size.width() || !size.height()); return result; } unsigned char* data = result->data()->data()->data(); if (rect.x() < 0 || rect.y() < 0 || (rect.x() + rect.width()) > size.width() || (rect.y() + rect.height()) > size.height()) memset(data, 0, result->data()->length()); int originX = rect.x(); int destX = 0; if (originX < 0) { destX = -originX; originX = 0; } int endX = rect.x() + rect.width(); if (endX > size.width()) endX = size.width(); int numColumns = endX - originX; int originY = rect.y(); int destY = 0; if (originY < 0) { destY = -originY; originY = 0; } int endY = rect.y() + rect.height(); if (endY > size.height()) endY = size.height(); int numRows = endY - originY; ASSERT(bitmap.config() == SkBitmap::kARGB_8888_Config); SkAutoLockPixels bitmapLock(bitmap); unsigned destBytesPerRow = 4 * rect.width(); unsigned char* destRow = data + destY * destBytesPerRow + destX * 4; for (int y = 0; y < numRows; ++y) { uint32_t* srcRow = bitmap.getAddr32(originX, originY + y); for (int x = 0; x < numColumns; ++x) { unsigned char* destPixel = &destRow[x * 4]; if (multiplied == Unmultiplied) { SkColor color = srcRow[x]; unsigned a = SkColorGetA(color); destPixel[0] = a ? SkColorGetR(color) * 255 / a : 0; destPixel[1] = a ? SkColorGetG(color) * 255 / a : 0; destPixel[2] = a ? SkColorGetB(color) * 255 / a : 0; destPixel[3] = a; } else { // Input and output are both pre-multiplied, we just need to re-arrange the // bytes from the bitmap format to RGBA. destPixel[0] = SkGetPackedR32(srcRow[x]); destPixel[1] = SkGetPackedG32(srcRow[x]); destPixel[2] = SkGetPackedB32(srcRow[x]); destPixel[3] = SkGetPackedA32(srcRow[x]); } } destRow += destBytesPerRow; } return result; }
IntSize RenderTheme::meterSizeForBounds(const RenderMeter*, const IntRect& bounds) const { return bounds.size(); }
void WKViewFindZoomableAreaForRect(WKViewRef viewRef, WKRect wkRect) { IntRect rect = toIntRect(wkRect); toImpl(viewRef)->findZoomableAreaForPoint(rect.center(), rect.size()); }
void BitmapTextureImageBuffer::updateContents(Image* image, const IntRect& targetRect, const IntPoint& offset) { m_image->context()->drawImage(image, ColorSpaceDeviceRGB, targetRect, IntRect(offset, targetRect.size()), CompositeCopy); }
static gboolean webkit_web_view_popup_menu_handler(GtkWidget* widget) { static const int contextMenuMargin = 1; // The context menu event was generated from the keyboard, so show the context menu by the current selection. Page* page = core(webView_s); FrameView* view = page->mainFrame()->view(); Position start = page->mainFrame()->selection()->selection().start(); Position end = page->mainFrame()->selection()->selection().end(); int rightAligned = FALSE; IntPoint location; if (!start.node() || !end.node()) location = IntPoint(rightAligned ? view->contentsWidth() - contextMenuMargin : contextMenuMargin, contextMenuMargin); else { RenderObject* renderer = start.node()->renderer(); if (!renderer) return FALSE; // Calculate the rect of the first line of the selection (cribbed from -[WebCoreFrameBridge firstRectForDOMRange:]). int extraWidthToEndOfLine = 0; InlineBox* startInlineBox; int startCaretOffset; start.getInlineBoxAndOffset(DOWNSTREAM, startInlineBox, startCaretOffset); IntRect startCaretRect = renderer->localCaretRect(startInlineBox, startCaretOffset, &extraWidthToEndOfLine); InlineBox* endInlineBox; int endCaretOffset; end.getInlineBoxAndOffset(UPSTREAM, endInlineBox, endCaretOffset); IntRect endCaretRect = renderer->localCaretRect(endInlineBox, endCaretOffset); IntRect firstRect; if (startCaretRect.y() == endCaretRect.y()) firstRect = IntRect(MIN(startCaretRect.x(), endCaretRect.x()), startCaretRect.y(), abs(endCaretRect.x() - startCaretRect.x()), MAX(startCaretRect.height(), endCaretRect.height())); else firstRect = IntRect(startCaretRect.x(), startCaretRect.y(), startCaretRect.width() + extraWidthToEndOfLine, startCaretRect.height()); location = IntPoint(rightAligned ? firstRect.right() : firstRect.x(), firstRect.bottom()); } int x, y; gdk_window_get_origin(GTK_WIDGET(view->root()->hostWindow()->platformPageClient())->window, &x, &y); // FIXME: The IntSize(0, -1) is a hack to get the hit-testing to result in the selected element. // Ideally we'd have the position of a context menu event be separate from its target node. location = view->contentsToWindow(location) + IntSize(0, -1); IntPoint global = location + IntSize(x, y); PlatformMouseEvent event(location, global, NoButton, MouseEventPressed, 0, false, false, false, false, gtk_get_current_event_time()); return false;//webkit_web_view_forward_context_menu_event(WEBKIT_WEB_VIEW(widget), event); }
void WebCoordinatedSurface::copyToTexture(PassRefPtr<WebCore::BitmapTexture> passTexture, const IntRect& target, const IntPoint& sourceOffset) { RefPtr<BitmapTexture> texture(passTexture); #if USE(GRAPHICS_SURFACE) if (isBackedByGraphicsSurface()) { RefPtr<BitmapTextureGL> textureGL = toBitmapTextureGL(texture.get()); if (textureGL) { uint32_t textureID = textureGL->id(); uint32_t textureTarget = textureGL->textureTarget(); m_graphicsSurface->copyToGLTexture(textureTarget, textureID, target, sourceOffset); return; } RefPtr<Image> image = m_graphicsSurface->createReadOnlyImage(IntRect(sourceOffset, target.size())); texture->updateContents(image.get(), target, IntPoint::zero(), BitmapTexture::UpdateCanModifyOriginalImageData); return; } #endif ASSERT(m_bitmap); RefPtr<Image> image = m_bitmap->createImage(); texture->updateContents(image.get(), target, sourceOffset, BitmapTexture::UpdateCanModifyOriginalImageData); }
IntRect ScrollView::windowToContents(const IntRect& windowRect) const { IntRect viewRect = convertFromContainingWindow(windowRect); viewRect.move(scrollOffset()); return viewRect; }
void TiledBackingStore::createTiles() { // Guard here as as these can change before the timer fires. if (isBackingStoreUpdatesSuspended()) return; // Update our backing store geometry. const IntRect previousRect = m_rect; m_rect = mapFromContents(m_client->tiledBackingStoreContentsRect()); m_trajectoryVector = m_pendingTrajectoryVector; m_visibleRect = visibleRect(); if (m_rect.isEmpty()) { setCoverRect(IntRect()); setKeepRect(IntRect()); return; } /* We must compute cover and keep rects using the visibleRect, instead of the rect intersecting the visibleRect with m_rect, * because TBS can be used as a backing store of GraphicsLayer and the visible rect usually does not intersect with m_rect. * In the below case, the intersecting rect is an empty. * * +---------------+ * | | * | m_rect | * | +-------|-----------------------+ * | | HERE | cover or keep | * +---------------+ rect | * | +---------+ | * | | visible | | * | | rect | | * | +---------+ | * | | * | | * +-------------------------------+ * * We must create or keep the tiles in the HERE region. */ IntRect coverRect; IntRect keepRect; computeCoverAndKeepRect(m_visibleRect, coverRect, keepRect); setCoverRect(coverRect); setKeepRect(keepRect); if (coverRect.isEmpty()) return; // Resize tiles at the edge in case the contents size has changed, but only do so // after having dropped tiles outside the keep rect. bool didResizeTiles = false; if (previousRect != m_rect) didResizeTiles = resizeEdgeTiles(); // Search for the tile position closest to the viewport center that does not yet contain a tile. // Which position is considered the closest depends on the tileDistance function. double shortestDistance = std::numeric_limits<double>::infinity(); Vector<Tile::Coordinate> tilesToCreate; unsigned requiredTileCount = 0; // Cover areas (in tiles) with minimum distance from the visible rect. If the visible rect is // not covered already it will be covered first in one go, due to the distance being 0 for tiles // inside the visible rect. Tile::Coordinate topLeft = tileCoordinateForPoint(coverRect.location()); Tile::Coordinate bottomRight = tileCoordinateForPoint(innerBottomRight(coverRect)); for (int yCoordinate = topLeft.y(); yCoordinate <= bottomRight.y(); ++yCoordinate) { for (int xCoordinate = topLeft.x(); xCoordinate <= bottomRight.x(); ++xCoordinate) { Tile::Coordinate currentCoordinate(xCoordinate, yCoordinate); if (tileAt(currentCoordinate)) continue; ++requiredTileCount; double distance = tileDistance(m_visibleRect, currentCoordinate); if (distance > shortestDistance) continue; if (distance < shortestDistance) { tilesToCreate.clear(); shortestDistance = distance; } tilesToCreate.append(currentCoordinate); } } // Now construct the tile(s) within the shortest distance. unsigned tilesToCreateCount = tilesToCreate.size(); for (unsigned n = 0; n < tilesToCreateCount; ++n) { Tile::Coordinate coordinate = tilesToCreate[n]; setTile(coordinate, m_backend->createTile(this, coordinate)); } requiredTileCount -= tilesToCreateCount; // Paint the content of the newly created tiles or resized tiles. if (tilesToCreateCount || didResizeTiles) updateTileBuffers(); // Re-call createTiles on a timer to cover the visible area with the newest shortest distance. m_pendingTileCreation = requiredTileCount; if (m_pendingTileCreation) { if (!m_commitTileUpdatesOnIdleEventLoop) { m_client->tiledBackingStoreHasPendingTileCreation(); return; } static const double tileCreationDelay = 0.01; startBackingStoreUpdateTimer(tileCreationDelay); } }
IntRect ScrollView::contentsToWindow(const IntRect& contentsRect) const { IntRect viewRect = contentsRect; viewRect.move(-scrollOffset()); return convertToContainingWindow(viewRect); }
void TiledBackingStore::adjustForContentsRect(IntRect& rect) const { IntRect bounds = m_rect; IntSize candidateSize = rect.size(); rect.intersect(bounds); if (rect.size() == candidateSize) return; /* * In the following case, there is no intersection of the contents rect and the cover rect. * Thus the latter should not be inflated. * * +---------------+ * | m_rect | * +---------------+ * * +-------------------------------+ * | cover rect | * | +---------+ | * | | visible | | * | | rect | | * | +---------+ | * +-------------------------------+ */ if (rect.isEmpty()) return; // Try to create a cover rect of the same size as the candidate, but within content bounds. int pixelsCovered = candidateSize.width() * candidateSize.height(); if (rect.width() < candidateSize.width()) rect.inflateY(((pixelsCovered / rect.width()) - rect.height()) / 2); if (rect.height() < candidateSize.height()) rect.inflateX(((pixelsCovered / rect.height()) - rect.width()) / 2); rect.intersect(bounds); }
void RenderTheme::paintSliderTicks(const RenderObject& o, const PaintInfo& paintInfo, const IntRect& rect) { Node* node = o.node(); if (!node) return; HTMLInputElement* input = node->toInputElement(); if (!input) return; HTMLDataListElement* dataList = downcast<HTMLDataListElement>(input->list()); if (!dataList) return; double min = input->minimum(); double max = input->maximum(); ControlPart part = o.style().appearance(); // We don't support ticks on alternate sliders like MediaVolumeSliders. if (part != SliderHorizontalPart && part != SliderVerticalPart) return; bool isHorizontal = part == SliderHorizontalPart; IntSize thumbSize; const RenderObject* thumbRenderer = input->sliderThumbElement()->renderer(); if (thumbRenderer) { const RenderStyle& thumbStyle = thumbRenderer->style(); int thumbWidth = thumbStyle.width().intValue(); int thumbHeight = thumbStyle.height().intValue(); thumbSize.setWidth(isHorizontal ? thumbWidth : thumbHeight); thumbSize.setHeight(isHorizontal ? thumbHeight : thumbWidth); } IntSize tickSize = sliderTickSize(); float zoomFactor = o.style().effectiveZoom(); FloatRect tickRect; int tickRegionSideMargin = 0; int tickRegionWidth = 0; IntRect trackBounds; RenderObject* trackRenderer = input->sliderTrackElement()->renderer(); // We can ignoring transforms because transform is handled by the graphics context. if (trackRenderer) trackBounds = trackRenderer->absoluteBoundingBoxRectIgnoringTransforms(); IntRect sliderBounds = o.absoluteBoundingBoxRectIgnoringTransforms(); // Make position relative to the transformed ancestor element. trackBounds.setX(trackBounds.x() - sliderBounds.x() + rect.x()); trackBounds.setY(trackBounds.y() - sliderBounds.y() + rect.y()); if (isHorizontal) { tickRect.setWidth(floor(tickSize.width() * zoomFactor)); tickRect.setHeight(floor(tickSize.height() * zoomFactor)); tickRect.setY(floor(rect.y() + rect.height() / 2.0 + sliderTickOffsetFromTrackCenter() * zoomFactor)); tickRegionSideMargin = trackBounds.x() + (thumbSize.width() - tickSize.width() * zoomFactor) / 2.0; tickRegionWidth = trackBounds.width() - thumbSize.width(); } else { tickRect.setWidth(floor(tickSize.height() * zoomFactor)); tickRect.setHeight(floor(tickSize.width() * zoomFactor)); tickRect.setX(floor(rect.x() + rect.width() / 2.0 + sliderTickOffsetFromTrackCenter() * zoomFactor)); tickRegionSideMargin = trackBounds.y() + (thumbSize.width() - tickSize.width() * zoomFactor) / 2.0; tickRegionWidth = trackBounds.height() - thumbSize.width(); } RefPtr<HTMLCollection> options = dataList->options(); GraphicsContextStateSaver stateSaver(*paintInfo.context); paintInfo.context->setFillColor(o.style().visitedDependentColor(CSSPropertyColor), ColorSpaceDeviceRGB); for (unsigned i = 0; Node* node = options->item(i); i++) { ASSERT(is<HTMLOptionElement>(node)); HTMLOptionElement& optionElement = downcast<HTMLOptionElement>(*node); String value = optionElement.value(); if (!input->isValidValue(value)) continue; double parsedValue = parseToDoubleForNumberType(input->sanitizeValue(value)); double tickFraction = (parsedValue - min) / (max - min); double tickRatio = isHorizontal && o.style().isLeftToRightDirection() ? tickFraction : 1.0 - tickFraction; double tickPosition = round(tickRegionSideMargin + tickRegionWidth * tickRatio); if (isHorizontal) tickRect.setX(tickPosition); else tickRect.setY(tickPosition); paintInfo.context->fillRect(tickRect); } }