void GradientGeneratedImage::drawPattern(GraphicsContext* destContext, const FloatRect& srcRect, const FloatSize& scale, const FloatPoint& phase, CompositeOperator compositeOp, const FloatRect& destRect, WebBlendMode blendMode, const IntSize& repeatSpacing) { float stepX = srcRect.width() + repeatSpacing.width(); float stepY = srcRect.height() + repeatSpacing.height(); int firstColumn = static_cast<int>(floorf((((destRect.x() - phase.x()) / scale.width()) - srcRect.x()) / srcRect.width())); int firstRow = static_cast<int>(floorf((((destRect.y() - phase.y()) / scale.height()) - srcRect.y()) / srcRect.height())); for (int i = firstColumn; ; ++i) { float dstX = (srcRect.x() + i * stepX) * scale.width() + phase.x(); // assert that first column encroaches left edge of dstRect. ASSERT(i > firstColumn || dstX <= destRect.x()); ASSERT(i == firstColumn || dstX > destRect.x()); if (dstX >= destRect.maxX()) break; float dstMaxX = dstX + srcRect.width() * scale.width(); if (dstX < destRect.x()) dstX = destRect.x(); if (dstMaxX > destRect.maxX()) dstMaxX = destRect.maxX(); if (dstX >= dstMaxX) continue; FloatRect visibleSrcRect; FloatRect tileDstRect; tileDstRect.setX(dstX); tileDstRect.setWidth(dstMaxX - dstX); visibleSrcRect.setX((tileDstRect.x() - phase.x()) / scale.width() - i * stepX); visibleSrcRect.setWidth(tileDstRect.width() / scale.width()); for (int j = firstRow; ; j++) { float dstY = (srcRect.y() + j * stepY) * scale.height() + phase.y(); // assert that first row encroaches top edge of dstRect. ASSERT(j > firstRow || dstY <= destRect.y()); ASSERT(j == firstRow || dstY > destRect.y()); if (dstY >= destRect.maxY()) break; float dstMaxY = dstY + srcRect.height() * scale.height(); if (dstY < destRect.y()) dstY = destRect.y(); if (dstMaxY > destRect.maxY()) dstMaxY = destRect.maxY(); if (dstY >= dstMaxY) continue; tileDstRect.setY(dstY); tileDstRect.setHeight(dstMaxY - dstY); visibleSrcRect.setY((tileDstRect.y() - phase.y()) / scale.height() - j * stepY); visibleSrcRect.setHeight(tileDstRect.height() / scale.height()); draw(destContext, tileDstRect, visibleSrcRect, compositeOp, blendMode); } } }
void RenderSVGResourceMasker::drawMaskForRenderer(RenderElement& renderer, const BackgroundImageGeometry& geometry, GraphicsContext* context, CompositeOperator compositeOp) { if (context->paintingDisabled()) return; if (!applySVGMask(renderer, context, false)) return; MaskerData* maskerData = maskerDataForRenderer(renderer); ASSERT(maskerData); FloatRect oneTileRect; FloatSize actualTileSize(geometry.tileSize().width() + geometry.spaceSize().width(), geometry.tileSize().height() + geometry.spaceSize().height()); oneTileRect.setX(geometry.destRect().x() + fmodf(fmodf(-geometry.phase().width(), actualTileSize.width()) - actualTileSize.width(), actualTileSize.width())); oneTileRect.setY(geometry.destRect().y() + fmodf(fmodf(-geometry.phase().height(), actualTileSize.height()) - actualTileSize.height(), actualTileSize.height())); oneTileRect.setSize(geometry.tileSize()); FloatSize intrinsicTileSize = maskerData->maskImage->logicalSize(); FloatSize scale(geometry.tileSize().width() / intrinsicTileSize.width(), geometry.tileSize().height() / intrinsicTileSize.height()); FloatRect visibleSrcRect; visibleSrcRect.setX((geometry.destRect().x() - oneTileRect.x()) / scale.width()); visibleSrcRect.setY((geometry.destRect().y() - oneTileRect.y()) / scale.height()); visibleSrcRect.setWidth(geometry.destRect().width() / scale.width()); visibleSrcRect.setHeight(geometry.destRect().height() / scale.height()); context->drawImageBuffer(maskerData->maskImage.get(), ColorSpaceDeviceRGB, geometry.destRect(), visibleSrcRect, compositeOp); }
Vector<FloatQuad> RenderTextLineBoxes::absoluteQuadsForRange(const RenderText& renderer, unsigned start, unsigned end, bool useSelectionHeight, bool* wasFixed) const { Vector<FloatQuad> quads; for (auto box = m_first; box; box = box->nextTextBox()) { // Note: box->end() returns the index of the last character, not the index past it if (start <= box->start() && box->end() < end) { FloatRect boundaries = box->calculateBoundaries(); if (useSelectionHeight) { LayoutRect selectionRect = box->localSelectionRect(start, end); if (box->isHorizontal()) { boundaries.setHeight(selectionRect.height()); boundaries.setY(selectionRect.y()); } else { boundaries.setWidth(selectionRect.width()); boundaries.setX(selectionRect.x()); } } quads.append(renderer.localToAbsoluteQuad(boundaries, 0, wasFixed)); continue; } FloatRect rect = localQuadForTextBox(*box, start, end, useSelectionHeight); if (!rect.isZero()) quads.append(renderer.localToAbsoluteQuad(rect, 0, wasFixed)); } return quads; }
Vector<IntRect> RenderTextLineBoxes::absoluteRectsForRange(const RenderText& renderer, unsigned start, unsigned end, bool useSelectionHeight, bool* wasFixed) const { Vector<IntRect> rects; for (auto box = m_first; box; box = box->nextTextBox()) { // Note: box->end() returns the index of the last character, not the index past it if (start <= box->start() && box->end() < end) { FloatRect boundaries = box->calculateBoundaries(); if (useSelectionHeight) { LayoutRect selectionRect = box->localSelectionRect(start, end); if (box->isHorizontal()) { boundaries.setHeight(selectionRect.height()); boundaries.setY(selectionRect.y()); } else { boundaries.setWidth(selectionRect.width()); boundaries.setX(selectionRect.x()); } } rects.append(renderer.localToAbsoluteQuad(boundaries, 0, wasFixed).enclosingBoundingBox()); continue; } // FIXME: This code is wrong. It's converting local to absolute twice. http://webkit.org/b/65722 FloatRect rect = localQuadForTextBox(*box, start, end, useSelectionHeight); if (!rect.isZero()) rects.append(renderer.localToAbsoluteQuad(rect, 0, wasFixed).enclosingBoundingBox()); } return rects; }
FloatRect FilterEffect::getSourceRect(const FloatRect& destRect, const FloatRect& destClipRect) { FloatRect sourceRect = mapRect(destRect, false); FloatRect sourceClipRect = mapRect(destClipRect, false); FloatRect boundaries = filter()->mapLocalRectToAbsoluteRect(effectBoundaries()); if (hasX()) sourceClipRect.setX(boundaries.x()); if (hasY()) sourceClipRect.setY(boundaries.y()); if (hasWidth()) sourceClipRect.setWidth(boundaries.width()); if (hasHeight()) sourceClipRect.setHeight(boundaries.height()); FloatRect result; if (m_inputEffects.size() > 0) { result = m_inputEffects.at(0)->getSourceRect(sourceRect, sourceClipRect); for (unsigned i = 1; i < m_inputEffects.size(); ++i) result.unite(m_inputEffects.at(i)->getSourceRect(sourceRect, sourceClipRect)); } else { result = sourceRect; result.intersect(sourceClipRect); } return result; }
void Image::drawTiled(GraphicsContext* ctxt, const FloatRect& destRect, const FloatPoint& srcPoint, const FloatSize& scaledTileSize, SkXfermode::Mode op, const IntSize& repeatSpacing) { FloatSize intrinsicTileSize = size(); if (hasRelativeWidth()) intrinsicTileSize.setWidth(scaledTileSize.width()); if (hasRelativeHeight()) intrinsicTileSize.setHeight(scaledTileSize.height()); FloatSize scale(scaledTileSize.width() / intrinsicTileSize.width(), scaledTileSize.height() / intrinsicTileSize.height()); FloatSize actualTileSize(scaledTileSize.width() + repeatSpacing.width(), scaledTileSize.height() + repeatSpacing.height()); FloatRect oneTileRect; oneTileRect.setX(destRect.x() + fmodf(fmodf(-srcPoint.x(), actualTileSize.width()) - actualTileSize.width(), actualTileSize.width())); oneTileRect.setY(destRect.y() + fmodf(fmodf(-srcPoint.y(), actualTileSize.height()) - actualTileSize.height(), actualTileSize.height())); oneTileRect.setSize(scaledTileSize); // Check and see if a single draw of the image can cover the entire area we are supposed to tile. if (oneTileRect.contains(destRect)) { FloatRect visibleSrcRect; visibleSrcRect.setX((destRect.x() - oneTileRect.x()) / scale.width()); visibleSrcRect.setY((destRect.y() - oneTileRect.y()) / scale.height()); visibleSrcRect.setWidth(destRect.width() / scale.width()); visibleSrcRect.setHeight(destRect.height() / scale.height()); ctxt->drawImage(this, destRect, visibleSrcRect, op, DoNotRespectImageOrientation); return; } FloatRect tileRect(FloatPoint(), intrinsicTileSize); drawPattern(ctxt, tileRect, scale, oneTileRect.location(), op, destRect, repeatSpacing); startAnimation(); }
SkImageFilter::CropRect FilterEffect::getCropRect(const FloatSize& cropOffset) const { FloatRect rect = filter()->filterRegion(); uint32_t flags = 0; FloatRect boundaries = effectBoundaries(); boundaries.move(cropOffset); if (hasX()) { rect.setX(boundaries.x()); flags |= SkImageFilter::CropRect::kHasLeft_CropEdge; flags |= SkImageFilter::CropRect::kHasRight_CropEdge; } if (hasY()) { rect.setY(boundaries.y()); flags |= SkImageFilter::CropRect::kHasTop_CropEdge; flags |= SkImageFilter::CropRect::kHasBottom_CropEdge; } if (hasWidth()) { rect.setWidth(boundaries.width()); flags |= SkImageFilter::CropRect::kHasRight_CropEdge; } if (hasHeight()) { rect.setHeight(boundaries.height()); flags |= SkImageFilter::CropRect::kHasBottom_CropEdge; } rect.scale(filter()->absoluteTransform().a(), filter()->absoluteTransform().d()); return SkImageFilter::CropRect(rect, flags); }
void PlatformCALayerWinInternal::setNeedsDisplayInRect(const FloatRect& dirtyRect) { if (!owner()) return; ASSERT(owner()->layerType() != PlatformCALayer::LayerTypeTiledBackingLayer); if (owner()->owner()) { if (owner()->owner()->platformCALayerShowRepaintCounter(owner())) { FloatRect layerBounds = owner()->bounds(); FloatRect repaintCounterRect = layerBounds; // We assume a maximum of 4 digits and a font size of 18. repaintCounterRect.setWidth(80); repaintCounterRect.setHeight(22); if (owner()->owner()->platformCALayerContentsOrientation() == WebCore::GraphicsLayer::CompositingCoordinatesTopDown) repaintCounterRect.setY(layerBounds.height() - (layerBounds.y() + repaintCounterRect.height())); internalSetNeedsDisplay(&repaintCounterRect); } if (owner()->owner()->platformCALayerContentsOrientation() == WebCore::GraphicsLayer::CompositingCoordinatesTopDown) { FloatRect flippedDirtyRect = dirtyRect; flippedDirtyRect.setY(owner()->bounds().height() - (flippedDirtyRect.y() + flippedDirtyRect.height())); internalSetNeedsDisplay(&flippedDirtyRect); return; } } internalSetNeedsDisplay(&dirtyRect); owner()->setNeedsCommit(); }
SkImageFilter::CropRect FilterEffect::getCropRect(const FloatSize& cropOffset) const { FloatRect rect; uint32_t flags = 0; if (!hasConnectedInput() && !filter()->filterRegion().isEmpty()) { rect = filter()->filterRegion(); flags = SkImageFilter::CropRect::kHasAll_CropEdge; } FloatRect boundaries = effectBoundaries(); boundaries.move(cropOffset); if (hasX()) { rect.setX(boundaries.x()); flags |= SkImageFilter::CropRect::kHasLeft_CropEdge; } if (hasY()) { rect.setY(boundaries.y()); flags |= SkImageFilter::CropRect::kHasTop_CropEdge; } if (hasWidth()) { rect.setWidth(boundaries.width()); flags |= SkImageFilter::CropRect::kHasWidth_CropEdge; } if (hasHeight()) { rect.setHeight(boundaries.height()); flags |= SkImageFilter::CropRect::kHasHeight_CropEdge; } rect.scale(filter()->scale()); return SkImageFilter::CropRect(rect, flags); }
void SVGFilter::calculateEffectSubRegion(FilterEffect* effect) { FloatRect subRegionBBox = effect->effectBoundaries(); FloatRect useBBox = effect->unionOfChildEffectSubregions(); FloatRect newSubRegion = subRegionBBox; if (m_effectBBoxMode) { newSubRegion = useBBox; if (effect->hasX()) newSubRegion.setX(m_itemBox.x() + subRegionBBox.x() * m_itemBox.width()); if (effect->hasY()) newSubRegion.setY(m_itemBox.y() + subRegionBBox.y() * m_itemBox.height()); if (effect->hasWidth()) newSubRegion.setWidth(subRegionBBox.width() * m_itemBox.width()); if (effect->hasHeight()) newSubRegion.setHeight(subRegionBBox.height() * m_itemBox.height()); } else { if (!effect->hasX()) newSubRegion.setX(useBBox.x()); if (!effect->hasY()) newSubRegion.setY(useBBox.y()); if (!effect->hasWidth()) newSubRegion.setWidth(useBBox.width()); if (!effect->hasHeight()) newSubRegion.setHeight(useBBox.height()); } // clip every filter effect to the filter region newSubRegion.intersect(m_filterRect); effect->setSubRegion(newSubRegion); newSubRegion.scale(filterResolution().width(), filterResolution().height()); effect->setScaledSubRegion(newSubRegion); m_maxImageSize = m_maxImageSize.expandedTo(newSubRegion.size()); }
static void heightAttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info) { INC_STATS("DOM.SVGRect.height._set"); V8SVGPODTypeWrapper<FloatRect>* wrapper = V8SVGPODTypeWrapper<FloatRect>::toNative(info.Holder()); FloatRect impInstance = *wrapper; FloatRect* imp = &impInstance; float v = static_cast<float>(value->NumberValue()); imp->setHeight(v); wrapper->commitChange(*imp, V8Proxy::svgContext(wrapper)); return; }
void ShadowList::adjustRectForShadow(FloatRect& rect) const { float shadowLeft = 0; float shadowRight = 0; float shadowTop = 0; float shadowBottom = 0; calculateShadowExtent(this, shadowLeft, shadowRight, shadowTop, shadowBottom); rect.move(shadowLeft, shadowTop); rect.setWidth(rect.width() - shadowLeft + shadowRight); rect.setHeight(rect.height() - shadowTop + shadowBottom); }
static void clampToContentsRectIfRectIsInfinite(FloatRect& rect, const IntRect& contentsRect) { if (rect.width() >= LayoutUnit::nearlyMax() || rect.width() <= LayoutUnit::nearlyMin()) { rect.setX(contentsRect.x()); rect.setWidth(contentsRect.width()); } if (rect.height() >= LayoutUnit::nearlyMax() || rect.height() <= LayoutUnit::nearlyMin()) { rect.setY(contentsRect.y()); rect.setHeight(contentsRect.height()); } }
FloatRect SVGImageBufferTools::clampedAbsoluteTargetRect(const FloatRect& absoluteTargetRect) { FloatRect clampedAbsoluteTargetRect = absoluteTargetRect; if (clampedAbsoluteTargetRect.width() > kMaxImageBufferSize) clampedAbsoluteTargetRect.setWidth(kMaxImageBufferSize); if (clampedAbsoluteTargetRect.height() > kMaxImageBufferSize) clampedAbsoluteTargetRect.setHeight(kMaxImageBufferSize); return clampedAbsoluteTargetRect; }
void ShadowData::adjustRectForShadow(FloatRect& rect, int additionalOutlineSize) const { int shadowLeft = 0; int shadowRight = 0; int shadowTop = 0; int shadowBottom = 0; calculateShadowExtent(this, additionalOutlineSize, shadowLeft, shadowRight, shadowTop, shadowBottom); rect.move(shadowLeft, shadowTop); rect.setWidth(rect.width() - shadowLeft + shadowRight); rect.setHeight(rect.height() - shadowTop + shadowBottom); }
FloatRect Image::adjustForNegativeSize(const FloatRect& rect) { FloatRect norm = rect; if (norm.width() < 0) { norm.setX(norm.x() + norm.width()); norm.setWidth(-norm.width()); } if (norm.height() < 0) { norm.setY(norm.y() + norm.height()); norm.setHeight(-norm.height()); } return norm; }
// A helper method for translating negative width and height values. FloatRect normalizeRect(const FloatRect& rect) { FloatRect norm = rect; if (norm.width() < 0) { norm.setX(norm.x() + norm.width()); norm.setWidth(-norm.width()); } if (norm.height() < 0) { norm.setY(norm.y() + norm.height()); norm.setHeight(-norm.height()); } return norm; }
void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator compositeOp) { CGImageRef image = frameAtIndex(m_currentFrame); if (!image) // If it's too early we won't have an image yet. return; if (mayFillWithSolidColor()) { fillWithSolidColor(ctxt, destRect, solidColor(), compositeOp); return; } CGContextRef context = ctxt->platformContext(); ctxt->save(); // If the source rect is a subportion of the image, then we compute an inflated destination rect that will hold the entire image // and then set a clip to the portion that we want to display. CGSize selfSize = size(); FloatRect adjustedDestRect = destRect; if (srcRect.width() != selfSize.width || srcRect.height() != selfSize.height) { // A subportion of the image is drawing. Adjust the destination rect to // account for this. float xScale = srcRect.width() / destRect.width(); float yScale = srcRect.height() / destRect.height(); adjustedDestRect.setLocation(FloatPoint(destRect.x() - srcRect.x() / xScale, destRect.y() - srcRect.y() / yScale)); adjustedDestRect.setSize(FloatSize(size().width() / xScale, size().height() / yScale)); CGContextClipToRect(context, destRect); } // If the image is only partially loaded, then shrink the destination rect that we're drawing into accordingly. float currHeight = CGImageGetHeight(image); if (currHeight < selfSize.height) adjustedDestRect.setHeight(adjustedDestRect.height() * currHeight / selfSize.height); // Flip the coords. ctxt->setCompositeOperation(compositeOp); CGContextTranslateCTM(context, adjustedDestRect.x(), adjustedDestRect.bottom()); CGContextScaleCTM(context, 1, -1); adjustedDestRect.setLocation(FloatPoint()); // Draw the image. CGContextDrawImage(context, adjustedDestRect, image); ctxt->restore(); startAnimation(); if (imageObserver()) imageObserver()->didDraw(this); }
static FloatRect getRect(FilterEffect* effect) { FloatRect result = effect->filter()->filterRegion(); FloatRect boundaries = effect->effectBoundaries(); if (effect->hasX()) result.setX(boundaries.x()); if (effect->hasY()) result.setY(boundaries.y()); if (effect->hasWidth()) result.setWidth(boundaries.width()); if (effect->hasHeight()) result.setHeight(boundaries.height()); return result; }
// 3/13/09 CSidhall - Added to get easy access to the current clip rectangle in screen space FloatRect GraphicsContext::getClip() const { FloatRect rect; // Note: seems m_data might be decrepated eventually if((m_data) && (m_data->surface)) { rect.setX( (float) m_data->surface->GetClipRect().x); rect.setY((float) m_data->surface->GetClipRect().y); rect.setWidth(m_data->surface->GetClipRect().width()); rect.setHeight(m_data->surface->GetClipRect().height()); } return rect; }
FloatRect FloatRect::normalized() const { FloatRect normalizedRect = *this; if (width() < 0) { normalizedRect.setX(x() + width()); normalizedRect.setWidth(-width()); } if (height() < 0) { normalizedRect.setY(y() + height()); normalizedRect.setHeight(-height()); } return normalizedRect; }
FloatRect Image::computeSubsetForTile(const FloatRect& tile, const FloatRect& dest, const FloatSize& imageSize) { DCHECK(tile.contains(dest)); const FloatSize scale(tile.width() / imageSize.width(), tile.height() / imageSize.height()); FloatRect subset = dest; subset.setX((dest.x() - tile.x()) / scale.width()); subset.setY((dest.y() - tile.y()) / scale.height()); subset.setWidth(dest.width() / scale.width()); subset.setHeight(dest.height() / scale.height()); return subset; }
FloatRect FilterEffect::determineFilterPrimitiveSubregion(DetermineSubregionFlags flags) { Filter* filter = this->filter(); ASSERT(filter); // FETile, FETurbulence, FEFlood don't have input effects, take the filter region as unite rect. FloatRect subregion; if (unsigned numberOfInputEffects = inputEffects().size()) { subregion = inputEffect(0)->determineFilterPrimitiveSubregion(flags); for (unsigned i = 1; i < numberOfInputEffects; ++i) subregion.unite(inputEffect(i)->determineFilterPrimitiveSubregion(flags)); } else { subregion = filter->filterRegion(); } // After calling determineFilterPrimitiveSubregion on the target effect, reset the subregion again for <feTile>. if (filterEffectType() == FilterEffectTypeTile) subregion = filter->filterRegion(); if (flags & MapRectForward) { // mapRect works on absolute rectangles. subregion = filter->mapAbsoluteRectToLocalRect(mapRect( filter->mapLocalRectToAbsoluteRect(subregion))); } FloatRect boundaries = effectBoundaries(); if (hasX()) subregion.setX(boundaries.x()); if (hasY()) subregion.setY(boundaries.y()); if (hasWidth()) subregion.setWidth(boundaries.width()); if (hasHeight()) subregion.setHeight(boundaries.height()); setFilterPrimitiveSubregion(subregion); FloatRect absoluteSubregion = filter->mapLocalRectToAbsoluteRect(subregion); // Clip every filter effect to the filter region. if (flags & ClipToFilterRegion) { absoluteSubregion.intersect(filter->absoluteFilterRegion()); } setMaxEffectRect(absoluteSubregion); return subregion; }
PassOwnPtr<ImageBuffer> RenderSVGResourcePattern::createTileImage(RenderObject* object, const PatternAttributes& attributes, const FloatRect& tileBoundaries, const FloatRect& absoluteTileBoundaries, const AffineTransform& tileImageTransform) const { ASSERT(object); // Clamp tile image size against SVG viewport size, as last resort, to avoid allocating huge image buffers. FloatRect contentBoxRect = SVGRenderSupport::findTreeRootObject(object)->contentBoxRect(); FloatRect clampedAbsoluteTileBoundaries = absoluteTileBoundaries; if (clampedAbsoluteTileBoundaries.width() > contentBoxRect.width()) clampedAbsoluteTileBoundaries.setWidth(contentBoxRect.width()); if (clampedAbsoluteTileBoundaries.height() > contentBoxRect.height()) clampedAbsoluteTileBoundaries.setHeight(contentBoxRect.height()); OwnPtr<ImageBuffer> tileImage; if (!SVGImageBufferTools::createImageBuffer(absoluteTileBoundaries, clampedAbsoluteTileBoundaries, tileImage, ColorSpaceDeviceRGB)) return PassOwnPtr<ImageBuffer>(); GraphicsContext* tileImageContext = tileImage->context(); ASSERT(tileImageContext); // The image buffer represents the final rendered size, so the content has to be scaled (to avoid pixelation). tileImageContext->scale(FloatSize(absoluteTileBoundaries.width() / tileBoundaries.width(), absoluteTileBoundaries.height() / tileBoundaries.height())); // Apply tile image transformations. if (!tileImageTransform.isIdentity()) tileImageContext->concatCTM(tileImageTransform); AffineTransform contentTransformation; if (attributes.boundingBoxModeContent()) contentTransformation = tileImageTransform; // Draw the content into the ImageBuffer. for (Node* node = attributes.patternContentElement()->firstChild(); node; node = node->nextSibling()) { if (!node->isSVGElement() || !static_cast<SVGElement*>(node)->isStyled() || !node->renderer()) continue; SVGImageBufferTools::renderSubtreeToImageBuffer(tileImage.get(), node->renderer(), contentTransformation); } return tileImage.release(); }
void ImageBuffer::draw(GraphicsContext* context, ColorSpace styleColorSpace, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator op, bool useLowQualityScale) { if (m_data.m_tiledImage && context != m_context.get()) { FloatRect src = srcRect; if (src.width() == -1) src.setWidth(m_data.m_tiledImage->size().width()); if (src.height() == -1) src.setHeight(m_data.m_tiledImage->size().height()); ASSERT(context->platformContext()->activePainter()); context->platformContext()->activePainter()->drawImage(m_data.m_tiledImage.get(), dstRect, src); return; } RefPtr<Image> imageCopy = copyImage(); context->drawImage(imageCopy.get(), styleColorSpace, dstRect, srcRect, op, useLowQualityScale); }
FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& frect) { FloatRect result; wxCoord x = (wxCoord)frect.x(); wxCoord y = (wxCoord)frect.y(); x = m_data->context->LogicalToDeviceX(x); y = m_data->context->LogicalToDeviceY(y); result.setX((float)x); result.setY((float)y); x = (wxCoord)frect.width(); y = (wxCoord)frect.height(); x = m_data->context->LogicalToDeviceXRel(x); y = m_data->context->LogicalToDeviceYRel(y); result.setWidth((float)x); result.setHeight((float)y); return result; }
Vector<FloatQuad> RenderTextLineBoxes::absoluteQuads(const RenderText& renderer, bool* wasFixed, ClippingOption option) const { Vector<FloatQuad> quads; for (auto box = m_first; box; box = box->nextTextBox()) { FloatRect boundaries = box->calculateBoundaries(); // Shorten the width of this text box if it ends in an ellipsis. // FIXME: ellipsisRectForBox should switch to return FloatRect soon with the subpixellayout branch. IntRect ellipsisRect = (option == ClipToEllipsis) ? ellipsisRectForBox(*box, 0, renderer.textLength()) : IntRect(); if (!ellipsisRect.isEmpty()) { if (renderer.style().isHorizontalWritingMode()) boundaries.setWidth(ellipsisRect.maxX() - boundaries.x()); else boundaries.setHeight(ellipsisRect.maxY() - boundaries.y()); } quads.append(renderer.localToAbsoluteQuad(boundaries, 0, wasFixed)); } return quads; }
void Image::drawTiled(GraphicsContext* ctxt, const FloatRect& destRect, const FloatPoint& srcPoint, const FloatSize& scaledTileSize, ColorSpace styleColorSpace, CompositeOperator op) { if (mayFillWithSolidColor()) { fillWithSolidColor(ctxt, destRect, solidColor(), styleColorSpace, op); return; } // See <https://webkit.org/b/59043>. #if !PLATFORM(WX) ASSERT(!isBitmapImage() || notSolidColor()); #endif FloatSize intrinsicTileSize = size(); if (hasRelativeWidth()) intrinsicTileSize.setWidth(scaledTileSize.width()); if (hasRelativeHeight()) intrinsicTileSize.setHeight(scaledTileSize.height()); FloatSize scale(scaledTileSize.width() / intrinsicTileSize.width(), scaledTileSize.height() / intrinsicTileSize.height()); FloatRect oneTileRect; oneTileRect.setX(destRect.x() + fmodf(fmodf(-srcPoint.x(), scaledTileSize.width()) - scaledTileSize.width(), scaledTileSize.width())); oneTileRect.setY(destRect.y() + fmodf(fmodf(-srcPoint.y(), scaledTileSize.height()) - scaledTileSize.height(), scaledTileSize.height())); oneTileRect.setSize(scaledTileSize); // Check and see if a single draw of the image can cover the entire area we are supposed to tile. if (oneTileRect.contains(destRect)) { FloatRect visibleSrcRect; visibleSrcRect.setX((destRect.x() - oneTileRect.x()) / scale.width()); visibleSrcRect.setY((destRect.y() - oneTileRect.y()) / scale.height()); visibleSrcRect.setWidth(destRect.width() / scale.width()); visibleSrcRect.setHeight(destRect.height() / scale.height()); draw(ctxt, destRect, visibleSrcRect, styleColorSpace, op); return; } AffineTransform patternTransform = AffineTransform().scaleNonUniform(scale.width(), scale.height()); FloatRect tileRect(FloatPoint(), intrinsicTileSize); drawPattern(ctxt, tileRect, patternTransform, oneTileRect.location(), styleColorSpace, op, destRect); startAnimation(); }
void TileCoverageMap::update() { FloatRect containerBounds = m_controller.bounds(); FloatRect visibleRect = m_controller.visibleRect(); visibleRect.contract(4, 4); // Layer is positioned 2px from top and left edges. visibleRect.setHeight(visibleRect.height() - m_controller.topContentInset()); float widthScale = 1; float scale = 1; if (!containerBounds.isEmpty()) { widthScale = std::min<float>(visibleRect.width() / containerBounds.width(), 0.1); scale = std::min(widthScale, visibleRect.height() / containerBounds.height()); } float indicatorScale = scale * m_controller.tileGrid().scale(); FloatRect mapBounds = containerBounds; mapBounds.scale(indicatorScale, indicatorScale); m_layer.get().setPosition(m_position + FloatPoint(2, 2)); m_layer.get().setBounds(mapBounds); m_layer.get().setNeedsDisplay(); visibleRect.scale(indicatorScale, indicatorScale); visibleRect.expand(2, 2); m_visibleRectIndicatorLayer->setPosition(visibleRect.location()); m_visibleRectIndicatorLayer->setBounds(FloatRect(FloatPoint(), visibleRect.size())); Color visibleRectIndicatorColor; switch (m_controller.indicatorMode()) { case SynchronousScrollingBecauseOfStyleIndication: visibleRectIndicatorColor = Color(255, 0, 0); break; case SynchronousScrollingBecauseOfEventHandlersIndication: visibleRectIndicatorColor = Color(255, 255, 0); break; case AsyncScrollingIndication: visibleRectIndicatorColor = Color(0, 200, 0); break; } m_visibleRectIndicatorLayer.get().setBorderColor(visibleRectIndicatorColor); }
FloatRect RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(FilterEffect* effect) { SVGFilter* filter = static_cast<SVGFilter*>(effect->filter()); ASSERT(filter); // FETile, FETurbulence, FEFlood don't have input effects, take the filter region as unite rect. FloatRect subregion; if (unsigned numberOfInputEffects = effect->inputEffects().size()) { subregion = determineFilterPrimitiveSubregion(effect->inputEffect(0)); for (unsigned i = 1; i < numberOfInputEffects; ++i) subregion.unite(determineFilterPrimitiveSubregion(effect->inputEffect(i))); } else subregion = filter->filterRegionInUserSpace(); // After calling determineFilterPrimitiveSubregion on the target effect, reset the subregion again for <feTile>. if (effect->filterEffectType() == FilterEffectTypeTile) subregion = filter->filterRegionInUserSpace(); FloatRect effectBoundaries = effect->effectBoundaries(); if (effect->hasX()) subregion.setX(effectBoundaries.x()); if (effect->hasY()) subregion.setY(effectBoundaries.y()); if (effect->hasWidth()) subregion.setWidth(effectBoundaries.width()); if (effect->hasHeight()) subregion.setHeight(effectBoundaries.height()); effect->setFilterPrimitiveSubregion(subregion); FloatRect absoluteSubregion = filter->absoluteTransform().mapRect(subregion); FloatSize filterResolution = filter->filterResolution(); absoluteSubregion.scale(filterResolution.width(), filterResolution.height()); // Clip every filter effect to the filter region. FloatRect absoluteScaledFilterRegion = filter->filterRegion(); absoluteScaledFilterRegion.scale(filterResolution.width(), filterResolution.height()); absoluteSubregion.intersect(absoluteScaledFilterRegion); effect->setMaxEffectRect(absoluteSubregion); return subregion; }