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

Side by Side Diff: WebCore/platform/graphics/skia/PatternSkia.cpp

Issue 42100: Apply tranformation to pattern locally to fix some layout tests.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/deps/third_party/WebKit/
Patch Set: '' Created 11 years, 9 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2008 Google Inc. All rights reserved. 2 * Copyright (C) 2008 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 22 matching lines...) Expand all
33 #include "NativeImageSkia.h" 33 #include "NativeImageSkia.h"
34 #include "TransformationMatrix.h" 34 #include "TransformationMatrix.h"
35 35
36 #include "SkShader.h" 36 #include "SkShader.h"
37 #include "SkCanvas.h" 37 #include "SkCanvas.h"
38 38
39 namespace WebCore { 39 namespace WebCore {
40 40
41 PlatformPatternPtr Pattern::createPlatformPattern(const TransformationMatrix& pa tternTransform) const 41 PlatformPatternPtr Pattern::createPlatformPattern(const TransformationMatrix& pa tternTransform) const
42 { 42 {
43 // Note: patternTransform is ignored since it seems to be applied elsewhere 43 // Note: |patternTransform| is ignored since it is a global transformation
44 // (when the pattern is used?). Applying it to the pattern (i.e. 44 // applied by the GraphicsContext. Pattern-specific transformation is stored
45 // shader->setLocalMatrix) results in a double transformation. This can be 45 // in |m_patternSpaceTransformation|.
46 // seen, for instance, as an extra offset in:
47 // LayoutTests/fast/canvas/patternfill-repeat.html
48 // and expanded scale and skew in:
49 // LayoutTests/svg/W3C-SVG-1.1/pservers-grad-06-b.svg
50 46
51 SkBitmap* bm = m_tileImage->nativeImageForCurrentFrame(); 47 SkBitmap* bm = m_tileImage->nativeImageForCurrentFrame();
52 if (m_repeatX && m_repeatY) 48 SkShader* shader = NULL;
53 return SkShader::CreateBitmapShader(*bm, SkShader::kRepeat_TileMode, SkS hader::kRepeat_TileMode);
54 49
55 // Skia does not have a "draw the tile only once" option. Clamp_TileMode 50 if (m_repeatX && m_repeatY) {
56 // repeats the last line of the image after drawing one tile. To avoid 51 shader = SkShader::CreateBitmapShader(*bm, SkShader::kRepeat_TileMode, S kShader::kRepeat_TileMode);
57 // filling the space with arbitrary pixels, this workaround forces the 52 } else {
58 // image to have a line of transparent pixels on the "repeated" edge(s), 53 // Skia does not have a "draw the tile only once" option. Clamp_TileMode
59 // thus causing extra space to be transparent filled. 54 // repeats the last line of the image after drawing one tile. To avoid
60 SkShader::TileMode tileModeX = m_repeatX ? SkShader::kRepeat_TileMode : SkSh ader::kClamp_TileMode; 55 // filling the space with arbitrary pixels, this workaround forces the
61 SkShader::TileMode tileModeY = m_repeatY ? SkShader::kRepeat_TileMode : SkSh ader::kClamp_TileMode; 56 // image to have a line of transparent pixels on the "repeated" edge(s),
62 int expandW = m_repeatX ? 0 : 1; 57 // thus causing extra space to be transparent filled.
63 int expandH = m_repeatY ? 0 : 1; 58 SkShader::TileMode tileModeX = m_repeatX ? SkShader::kRepeat_TileMode : SkShader::kClamp_TileMode;
59 SkShader::TileMode tileModeY = m_repeatY ? SkShader::kRepeat_TileMode : SkShader::kClamp_TileMode;
60 int expandW = m_repeatX ? 0 : 1;
61 int expandH = m_repeatY ? 0 : 1;
64 62
65 // Create a transparent bitmap 1 pixel wider and/or taller than the 63 // Create a transparent bitmap 1 pixel wider and/or taller than the
66 // original, then copy the orignal into it. 64 // original, then copy the orignal into it.
67 // FIXME: Is there a better way to pad (not scale) an image in skia? 65 // FIXME: Is there a better way to pad (not scale) an image in skia?
68 SkBitmap bm2; 66 SkBitmap bm2;
69 bm2.setConfig(bm->config(), bm->width() + expandW, bm->height() + expandH); 67 bm2.setConfig(bm->config(), bm->width() + expandW, bm->height() + expand H);
70 bm2.allocPixels(); 68 bm2.allocPixels();
71 bm2.eraseARGB(0x00, 0x00, 0x00, 0x00); 69 bm2.eraseARGB(0x00, 0x00, 0x00, 0x00);
72 SkCanvas canvas(bm2); 70 SkCanvas canvas(bm2);
73 canvas.drawBitmap(*bm, 0, 0); 71 canvas.drawBitmap(*bm, 0, 0);
74 return SkShader::CreateBitmapShader(bm2, tileModeX, tileModeY); 72 shader = SkShader::CreateBitmapShader(bm2, tileModeX, tileModeY);
73 }
74
75 // The local transform is saved in m_patternSpaceTransformation, and we need
76 // to apply it to the pattern. But Skia seems to have a problem with
77 // positive translations in tile mode, so adjust the translation to an
78 // equivalent negative value if we are in tile mode.
79 // For example:
80 // transform.e() == 56 (X translation)
81 // bm->width() == 20 (Pattern width)
82 // To make it look the same, we can have a X translation of -6, -26, etc.
83 // An equivalent negative translation would be 56 less some multiple of 20,
84 // e.g. -6, -26, -46. We can obtain the first such number that satisfies
85 // this property by doing 56 - 3 * 20 = -6. The value of such multiple is
86 // obtained by ceil(56 / 20) = 3.
87 double translateX = 0.0;
88 double translateY = 0.0;
89 TransformationMatrix transform = m_patternSpaceTransformation;
90 if (m_repeatX && bm->width() && transform.e() > 0.0) {
91 translateX = -bm->width() * ceil(transform.e() / bm->width());
92 }
93 if (m_repeatY && bm->height() && transform.f() > 0.0) {
94 translateY = -bm->height() * ceil(transform.f() / bm->height());
95 }
96 // Note that transform.translate(x, y) is to apply translation to the
97 // current matrix, not setting the translation.
98 shader->setLocalMatrix(transform.translate(translateX, translateY));
99 return shader;
75 } 100 }
76 101
77 } // namespace WebCore 102 } // namespace WebCore
OLDNEW
« 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