15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc. All rights reserved. 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met: 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer in the 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * documentation and/or other materials provided with the distribution. 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 245267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/platform/graphics/Image.h" 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/platform/Length.h" 3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/platform/MIMETypeRegistry.h" 3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/platform/SharedBuffer.h" 33f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)#include "core/platform/chromium/TraceEvent.h" 3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/platform/graphics/BitmapImage.h" 35f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)#include "core/platform/graphics/FloatPoint.h" 36f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)#include "core/platform/graphics/FloatRect.h" 37f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)#include "core/platform/graphics/FloatSize.h" 3853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/platform/graphics/GraphicsContext.h" 39e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "core/platform/graphics/GraphicsContextStateSaver.h" 40e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "core/platform/graphics/GraphicsTypes.h" 4153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/platform/graphics/IntRect.h" 42f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)#include "public/platform/Platform.h" 43f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)#include "public/platform/WebData.h" 445267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "wtf/MainThread.h" 455267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "wtf/StdLibExtras.h" 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 47f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)#include <math.h> 48f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore { 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Image::Image(ImageObserver* observer) 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : m_imageObserver(observer) 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Image::~Image() 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Image* Image::nullImage() 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(isMainThread()); 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DEFINE_STATIC_LOCAL(RefPtr<Image>, nullImage, (BitmapImage::create()));; 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return nullImage.get(); 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 67f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)PassRefPtr<Image> Image::loadPlatformResource(const char *name) 68f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles){ 69f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) const WebKit::WebData& resource = WebKit::Platform::current()->loadResource(name); 70f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) if (resource.isEmpty()) 71f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return Image::nullImage(); 72f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) 73f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) RefPtr<Image> image = BitmapImage::create(); 74f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) image->setData(resource, true); 75f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return image.release(); 76f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)} 77f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool Image::supportsType(const String& type) 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 805267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) return MIMETypeRegistry::isSupportedImageResourceMIMEType(type); 815267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)} 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool Image::setData(PassRefPtr<SharedBuffer> data, bool allDataReceived) 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 85926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_encodedImageData = data; 86926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!m_encodedImageData.get()) 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 89926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) int length = m_encodedImageData->size(); 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!length) 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 925267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return dataChanged(allDataReceived); 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 965267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)void Image::fillWithSolidColor(GraphicsContext* ctxt, const FloatRect& dstRect, const Color& color, CompositeOperator op) 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!color.alpha()) 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1005267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CompositeOperator previousOperator = ctxt->compositeOperation(); 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ctxt->setCompositeOperation(!color.hasAlpha() && op == CompositeSourceOver ? CompositeCopy : op); 1035267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) ctxt->fillRect(dstRect, color); 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ctxt->setCompositeOperation(previousOperator); 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)FloatRect Image::adjustForNegativeSize(const FloatRect& rect) 10893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){ 10993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) FloatRect norm = rect; 11093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (norm.width() < 0) { 11193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) norm.setX(norm.x() + norm.width()); 11293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) norm.setWidth(-norm.width()); 11393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) } 11493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (norm.height() < 0) { 11593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) norm.setY(norm.y() + norm.height()); 11693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) norm.setHeight(-norm.height()); 11793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) } 11893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return norm; 11993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)} 12093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 1215267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)void Image::draw(GraphicsContext* ctx, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator op, BlendMode blendMode, RespectImageOrientationEnum) 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1235267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) draw(ctx, dstRect, srcRect, op, blendMode); 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1265267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)void Image::drawTiled(GraphicsContext* ctxt, const FloatRect& destRect, const FloatPoint& srcPoint, const FloatSize& scaledTileSize, CompositeOperator op, BlendMode blendMode) 1275267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles){ 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (mayFillWithSolidColor()) { 1295267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) fillWithSolidColor(ctxt, destRect, solidColor(), op); 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // See <https://webkit.org/b/59043>. 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!isBitmapImage() || notSolidColor()); 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatSize intrinsicTileSize = size(); 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (hasRelativeWidth()) 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) intrinsicTileSize.setWidth(scaledTileSize.width()); 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (hasRelativeHeight()) 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) intrinsicTileSize.setHeight(scaledTileSize.height()); 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatSize scale(scaledTileSize.width() / intrinsicTileSize.width(), 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) scaledTileSize.height() / intrinsicTileSize.height()); 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatRect oneTileRect; 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) oneTileRect.setX(destRect.x() + fmodf(fmodf(-srcPoint.x(), scaledTileSize.width()) - scaledTileSize.width(), scaledTileSize.width())); 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) oneTileRect.setY(destRect.y() + fmodf(fmodf(-srcPoint.y(), scaledTileSize.height()) - scaledTileSize.height(), scaledTileSize.height())); 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) oneTileRect.setSize(scaledTileSize); 1495267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) 1505267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) // Check and see if a single draw of the image can cover the entire area we are supposed to tile. 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (oneTileRect.contains(destRect)) { 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatRect visibleSrcRect; 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) visibleSrcRect.setX((destRect.x() - oneTileRect.x()) / scale.width()); 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) visibleSrcRect.setY((destRect.y() - oneTileRect.y()) / scale.height()); 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) visibleSrcRect.setWidth(destRect.width() / scale.width()); 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) visibleSrcRect.setHeight(destRect.height() / scale.height()); 1575267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) draw(ctxt, destRect, visibleSrcRect, op, blendMode); 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1615267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) FloatRect tileRect(FloatPoint(), intrinsicTileSize); 162521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) drawPattern(ctxt, tileRect, scale, oneTileRect.location(), op, destRect, blendMode); 1635267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) startAnimation(); 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// FIXME: Merge with the other drawTiled eventually, since we need a combination of both for some things. 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Image::drawTiled(GraphicsContext* ctxt, const FloatRect& dstRect, const FloatRect& srcRect, 169e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch const FloatSize& providedTileScaleFactor, TileRule hRule, TileRule vRule, CompositeOperator op) 1705267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles){ 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (mayFillWithSolidColor()) { 1725267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) fillWithSolidColor(ctxt, dstRect, solidColor(), op); 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1755267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) 176e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch // FIXME: We do not support 'space' yet. For now just map it to 'repeat'. 177e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch if (hRule == SpaceTile) 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) hRule = RepeatTile; 179e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch if (vRule == SpaceTile) 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) vRule = RepeatTile; 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 182e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch // FIXME: if this code is used for background-repeat: round (in addition to 183e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch // border-image-repeat), then add logic to deal with the background-size: auto 184e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch // special case. The aspect ratio should be maintained in this case. 185e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch FloatSize tileScaleFactor = providedTileScaleFactor; 186e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch bool useLowInterpolationQuality = false; 187e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch if (hRule == RoundTile) { 188e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch float hRepetitions = std::max(1.0f, roundf(dstRect.width() / (tileScaleFactor.width() * srcRect.width()))); 189e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch tileScaleFactor.setWidth(dstRect.width() / (srcRect.width() * hRepetitions)); 190e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch } 191e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch if (vRule == RoundTile) { 192e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch float vRepetitions = std::max(1.0f, roundf(dstRect.height() / (tileScaleFactor.height() * srcRect.height()))); 193e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch tileScaleFactor.setHeight(dstRect.height() / (srcRect.height() * vRepetitions)); 194e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch } 195e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch if (hRule == RoundTile || vRule == RoundTile) { 196e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch // High interpolation quality rounds the scaled tile to an integer size (see Image::drawPattern). 197e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch // To avoid causing a visual problem, linear interpolation must be used instead. 198e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch // FIXME: Allow using high-quality interpolation in this case, too. 199e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch useLowInterpolationQuality = true; 200e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch } 201e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We want to construct the phase such that the pattern is centered (when stretch is not 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // set for a particular rule). 2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float hPhase = tileScaleFactor.width() * srcRect.x(); 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float vPhase = tileScaleFactor.height() * srcRect.y(); 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float scaledTileWidth = tileScaleFactor.width() * srcRect.width(); 2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float scaledTileHeight = tileScaleFactor.height() * srcRect.height(); 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (hRule == Image::RepeatTile) 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) hPhase -= (dstRect.width() - scaledTileWidth) / 2; 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (vRule == Image::RepeatTile) 2115267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) vPhase -= (dstRect.height() - scaledTileHeight) / 2; 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatPoint patternPhase(dstRect.x() - hPhase, dstRect.y() - vPhase); 2135267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) 214e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch if (useLowInterpolationQuality) { 215e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch InterpolationQuality previousInterpolationQuality = ctxt->imageInterpolationQuality(); 216e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch ctxt->setImageInterpolationQuality(InterpolationLow); 217e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch drawPattern(ctxt, srcRect, tileScaleFactor, patternPhase, op, dstRect); 218e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch ctxt->setImageInterpolationQuality(previousInterpolationQuality); 219e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch } else { 220e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch drawPattern(ctxt, srcRect, tileScaleFactor, patternPhase, op, dstRect); 221e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch } 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) startAnimation(); 2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 226f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)void Image::drawPattern(GraphicsContext* context, const FloatRect& floatSrcRect, const FloatSize& scale, 227f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) const FloatPoint& phase, CompositeOperator compositeOp, const FloatRect& destRect, BlendMode blendMode) 228f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles){ 229f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) TRACE_EVENT0("skia", "Image::drawPattern"); 230f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) if (RefPtr<NativeImageSkia> bitmap = nativeImageForCurrentFrame()) 231f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) bitmap->drawPattern(context, adjustForNegativeSize(floatSrcRect), scale, phase, compositeOp, destRect, blendMode); 232f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)} 233f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Image::computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio) 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) intrinsicRatio = size(); 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) intrinsicWidth = Length(intrinsicRatio.width(), Fixed); 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) intrinsicHeight = Length(intrinsicRatio.height(), Fixed); 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 242