Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / platform / graphics / Pattern.cpp
index 9529307..518d83a 100644 (file)
 #include "config.h"
 #include "platform/graphics/Pattern.h"
 
+#include "platform/graphics/BitmapPattern.h"
+#include "platform/graphics/DisplayList.h"
+#include "platform/graphics/DisplayListPattern.h"
+#include "platform/graphics/StaticBitmapPattern.h"
+#include "third_party/skia/include/core/SkImage.h"
+#include "third_party/skia/include/core/SkShader.h"
 #include <v8.h>
-#include "SkCanvas.h"
-#include "SkColorShader.h"
-#include "platform/graphics/skia/SkiaUtils.h"
 
+namespace blink {
 
-namespace WebCore {
+PassRefPtr<Pattern> Pattern::createBitmapPattern(PassRefPtr<Image> tileImage, RepeatMode repeatMode)
+{
+    if (tileImage->skImage())
+        return StaticBitmapPattern::create(tileImage, repeatMode);
+
+    return BitmapPattern::create(tileImage, repeatMode);
+}
 
-Pattern::Pattern(PassRefPtr<Image> image, bool repeatX, bool repeatY)
-    : m_repeatX(repeatX)
-    , m_repeatY(repeatY)
+PassRefPtr<Pattern> Pattern::createDisplayListPattern(PassRefPtr<DisplayList> displayList,
+    RepeatMode repeatMode)
+{
+    return DisplayListPattern::create(displayList, repeatMode);
+}
+
+Pattern::Pattern(RepeatMode repeatMode, int64_t externalMemoryAllocated)
+    : m_repeatMode(repeatMode)
     , m_externalMemoryAllocated(0)
 {
-    if (image) {
-        m_tileImage = image->nativeImageForCurrentFrame();
-    }
+    adjustExternalMemoryAllocated(externalMemoryAllocated);
 }
 
 Pattern::~Pattern()
 {
-    if (m_externalMemoryAllocated)
-        v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_externalMemoryAllocated);
+    adjustExternalMemoryAllocated(-m_externalMemoryAllocated);
 }
 
 SkShader* Pattern::shader()
 {
-    if (m_pattern)
-        return m_pattern.get();
-
-    // If we don't have a bitmap, return a transparent shader.
-    if (!m_tileImage)
-        m_pattern = adoptRef(new SkColorShader(SK_ColorTRANSPARENT));
-    else if (m_repeatX && m_repeatY)
-        m_pattern = adoptRef(SkShader::CreateBitmapShader(m_tileImage->bitmap(), SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode));
-    else {
-        // Skia does not have a "draw the tile only once" option. Clamp_TileMode
-        // repeats the last line of the image after drawing one tile. To avoid
-        // filling the space with arbitrary pixels, this workaround forces the
-        // image to have a line of transparent pixels on the "repeated" edge(s),
-        // thus causing extra space to be transparent filled.
-        SkShader::TileMode tileModeX = m_repeatX ? SkShader::kRepeat_TileMode : SkShader::kClamp_TileMode;
-        SkShader::TileMode tileModeY = m_repeatY ? SkShader::kRepeat_TileMode : SkShader::kClamp_TileMode;
-        int expandW = m_repeatX ? 0 : 1;
-        int expandH = m_repeatY ? 0 : 1;
-
-        // Create a transparent bitmap 1 pixel wider and/or taller than the
-        // original, then copy the orignal into it.
-        // FIXME: Is there a better way to pad (not scale) an image in skia?
-        SkImageInfo info = m_tileImage->bitmap().info();
-        info.fWidth += expandW;
-        info.fHeight += expandH;
-        // we explicitly require non-opaquness, since we are going to add a transparent strip.
-        info.fAlphaType = kPremul_SkAlphaType;
-
-        SkBitmap bm2;
-        bm2.allocPixels(info);
-        bm2.eraseARGB(0x00, 0x00, 0x00, 0x00);
-        SkCanvas canvas(bm2);
-        canvas.drawBitmap(m_tileImage->bitmap(), 0, 0);
-        bm2.setImmutable();
-        m_pattern = adoptRef(SkShader::CreateBitmapShader(bm2, tileModeX, tileModeY));
-
-        // Clamp to int, since that's what the adjust function takes.
-        m_externalMemoryAllocated = static_cast<int>(std::min(static_cast<size_t>(INT_MAX), bm2.getSafeSize()));
-        v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(m_externalMemoryAllocated);
+    if (!m_pattern) {
+        m_pattern = createShader();
     }
-    m_pattern->setLocalMatrix(affineTransformToSkMatrix(m_patternSpaceTransformation));
+
     return m_pattern.get();
 }
 
 void Pattern::setPatternSpaceTransform(const AffineTransform& patternSpaceTransformation)
 {
+    if (patternSpaceTransformation == m_patternSpaceTransformation)
+        return;
+
     m_patternSpaceTransformation = patternSpaceTransformation;
-    if (m_pattern)
-        m_pattern->setLocalMatrix(affineTransformToSkMatrix(m_patternSpaceTransformation));
+    m_pattern.clear();
 }
 
+void Pattern::adjustExternalMemoryAllocated(int64_t delta)
+{
+    delta = std::max(-m_externalMemoryAllocated, delta);
+
+    v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(delta);
+
+    m_externalMemoryAllocated += delta;
 }
+
+} // namespace blink