Home | History | Annotate | Download | only in skia
      1 /*
      2  * Copyright (c) 2008, Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #ifndef NativeImageSkia_h
     32 #define NativeImageSkia_h
     33 
     34 #include "SkBitmap.h"
     35 #include "SkRect.h"
     36 #include "SkSize.h"
     37 #include "SkXfermode.h"
     38 #include "platform/PlatformExport.h"
     39 #include "platform/geometry/IntSize.h"
     40 #include "platform/graphics/GraphicsTypes.h"
     41 #include "wtf/Forward.h"
     42 #include "wtf/PassRefPtr.h"
     43 #include "wtf/RefCounted.h"
     44 
     45 class SkMatrix;
     46 class SkPaint;
     47 
     48 namespace WebCore {
     49 
     50 class FloatPoint;
     51 class FloatRect;
     52 class FloatSize;
     53 class GraphicsContext;
     54 
     55 // This object is used as the "native image" in our port. When WebKit uses
     56 // PassNativeImagePtr / NativeImagePtr, it is a smart pointer to this type.
     57 // It has an SkBitmap, and also stores a cached resized image.
     58 class PLATFORM_EXPORT NativeImageSkia : public RefCounted<NativeImageSkia> {
     59 public:
     60     static PassRefPtr<NativeImageSkia> create()
     61     {
     62         return adoptRef(new NativeImageSkia());
     63     }
     64 
     65     // This factory method does a shallow copy of the passed-in SkBitmap
     66     // (ie., it references the same pixel data and bumps the refcount). Use
     67     // only when you want sharing semantics.
     68     static PassRefPtr<NativeImageSkia> create(const SkBitmap& bitmap)
     69     {
     70         return adoptRef(new NativeImageSkia(bitmap));
     71     }
     72 
     73     // This method does a shallow copy of the internal SkBitmap (ie., it
     74     // references the same pixel data and bumps the refcount). Use only when
     75     // you want sharing semantics.
     76     PassRefPtr<NativeImageSkia> clone() const
     77     {
     78         return adoptRef(new NativeImageSkia(m_image, m_resizedImage, m_cachedImageInfo, m_resizeRequests));
     79     }
     80 
     81     ~NativeImageSkia();
     82 
     83     // Returns the number of bytes of image data. This includes the cached
     84     // resized version if there is one.
     85     int decodedSize() const;
     86 
     87     // Returns true if the entire image has been decoded.
     88     bool isDataComplete() const { return m_image.isImmutable(); }
     89 
     90     // Get reference to the internal SkBitmap representing this image.
     91     const SkBitmap& bitmap() const { return m_image; }
     92 
     93     // We can keep a resized version of the bitmap cached on this object.
     94     // This function will return true if there is a cached version of the given
     95     // scale and subset.
     96     bool hasResizedBitmap(const SkISize& scaledImageSize, const SkIRect& scaledImageSubset) const;
     97 
     98     // This will return an existing resized image subset, or generate a new one
     99     // of the specified size and subset and possibly cache it.
    100     //
    101     // scaledImageSize
    102     // Dimensions of the scaled full image.
    103     //
    104     // scaledImageSubset
    105     // Rectangle of the subset in the scaled image.
    106     SkBitmap resizedBitmap(const SkISize& scaledImageSize, const SkIRect& scaledImageSubset) const;
    107 
    108     void draw(GraphicsContext*, const SkRect& srcRect, const SkRect& destRect, PassRefPtr<SkXfermode>) const;
    109     void drawPattern(
    110         GraphicsContext*,
    111         const FloatRect& srcRect,
    112         const FloatSize& scale,
    113         const FloatPoint& phase,
    114         CompositeOperator,
    115         const FloatRect& destRect,
    116         blink::WebBlendMode,
    117         const IntSize& repeatSpacing) const;
    118 
    119 private:
    120     NativeImageSkia();
    121 
    122     NativeImageSkia(const SkBitmap&);
    123 
    124     // ImageResourceInfo is used to uniquely identify cached or requested image
    125     // resizes.
    126     // Image resize is identified by the scaled image size and scaled image subset.
    127     struct ImageResourceInfo {
    128         SkISize scaledImageSize;
    129         SkIRect scaledImageSubset;
    130 
    131         ImageResourceInfo();
    132 
    133         bool isEqual(const SkISize& otherScaledImageSize, const SkIRect& otherScaledImageSubset) const;
    134         void set(const SkISize& otherScaledImageSize, const SkIRect& otherScaledImageSubset);
    135         SkIRect rectInSubset(const SkIRect& otherScaledImageRect);
    136     };
    137 
    138     NativeImageSkia(const SkBitmap& image, const SkBitmap& resizedImage, const ImageResourceInfo&, int resizeRequests);
    139 
    140     // Returns true if the given resize operation should either resize the whole
    141     // image and cache it, or resize just the part it needs and throw the result
    142     // away.
    143     //
    144     // Calling this function may increment a request count that can change the
    145     // result of subsequent calls.
    146     //
    147     // On the one hand, if only a small subset is desired, then we will waste a
    148     // lot of time resampling the entire thing, so we only want to do exactly
    149     // what's required. On the other hand, resampling the entire bitmap is
    150     // better if we're going to be using it more than once (like a bitmap
    151     // scrolling on and off the screen. Since we only cache when doing the
    152     // entire thing, it's best to just do it up front.
    153     bool shouldCacheResampling(const SkISize& scaledImageSize, const SkIRect& scaledImageSubset) const;
    154 
    155     InterpolationQuality computeInterpolationQuality(const SkMatrix&, float srcWidth, float srcHeight, float destWidth, float destHeight) const;
    156     SkBitmap extractScaledImageFragment(const SkRect& srcRect, float scaleX, float scaleY, SkRect* scaledSrcRect) const;
    157     void drawResampledBitmap(GraphicsContext*, SkPaint&, const SkRect& srcRect, const SkRect& destRect) const;
    158 
    159     // The original image.
    160     SkBitmap m_image;
    161 
    162     // The cached bitmap fragment. This is a subset of the scaled version of
    163     // |m_image|. empty() returns true if there is no cached image.
    164     mutable SkBitmap m_resizedImage;
    165 
    166     // References how many times that the image size has been requested for
    167     // the last size.
    168     //
    169     // Every time we get a call to shouldCacheResampling, if it matches the
    170     // m_cachedImageInfo, we'll increment the counter, and if not, we'll reset
    171     // the counter and save the dimensions.
    172     //
    173     // This allows us to see if many requests have been made for the same
    174     // resized image, we know that we should probably cache it, even if all of
    175     // those requests individually are small and would not otherwise be cached.
    176     //
    177     // We also track scaling information and destination subset for the scaled
    178     // image. See comments for ImageResourceInfo.
    179     mutable ImageResourceInfo m_cachedImageInfo;
    180     mutable int m_resizeRequests;
    181 };
    182 
    183 }
    184 #endif  // NativeImageSkia_h
    185