Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2262)

Unified Diff: WebCore/platform/graphics/skia/PatternSkia.cpp

Issue 17365: Workaround a skia limitation when drawing repeated patterns (Closed) Base URL: svn://chrome-svn/chrome/trunk/deps/third_party/WebKit/
Patch Set: '' Created 11 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: WebCore/platform/graphics/skia/PatternSkia.cpp
===================================================================
--- WebCore/platform/graphics/skia/PatternSkia.cpp (revision 8041)
+++ WebCore/platform/graphics/skia/PatternSkia.cpp (working copy)
@@ -34,22 +34,44 @@
#include "TransformationMatrix.h"
#include "SkShader.h"
+#include "SkCanvas.h"
namespace WebCore {
-static inline SkShader::TileMode shaderRule(bool shouldRepeat)
+PlatformPatternPtr Pattern::createPlatformPattern(const TransformationMatrix& patternTransform) const
{
- // FIXME: Skia does not have a "draw the tile only once" option
- // Clamp draws the last line of the image after stopping repeating
- return shouldRepeat ? SkShader::kRepeat_TileMode : SkShader::kClamp_TileMode;
-}
+ // Note: patternTransform is ignored since it seems to be applied elsewhere
+ // (when the pattern is used?). Applying it to the pattern (i.e.
+ // shader->setLocalMatrix) results in a double transformation. This can be
+ // seen, for instance, as an extra offset in:
+ // LayoutTests/fast/canvas/patternfill-repeat.html
+ // and expanded scale and skew in:
+ // LayoutTests/svg/W3C-SVG-1.1/pservers-grad-06-b.svg
-PlatformPatternPtr Pattern::createPlatformPattern(const TransformationMatrix& patternTransform) const
-{
SkBitmap* bm = m_tileImage->nativeImageForCurrentFrame();
- SkShader* shader = SkShader::CreateBitmapShader(*bm, shaderRule(m_repeatX), shaderRule(m_repeatY));
- shader->setLocalMatrix(patternTransform);
- return shader;
+ if (m_repeatX && m_repeatY)
+ return SkShader::CreateBitmapShader(*bm, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode);
+
+ // 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?
+ SkBitmap bm2;
+ bm2.setConfig(bm->config(), bm->width() + expandW, bm->height() + expandH);
+ bm2.allocPixels();
+ bm2.eraseARGB(0x00, 0x00, 0x00, 0x00);
+ SkCanvas canvas(bm2);
+ canvas.drawBitmap(*bm, 0, 0);
+ return SkShader::CreateBitmapShader(bm2, tileModeX, tileModeY);
}
} // namespace WebCore
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698