diff options
author | tc@google.com <tc@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-01 22:31:35 +0000 |
---|---|---|
committer | tc@google.com <tc@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-01 22:31:35 +0000 |
commit | de56f378336660dcc848763c80267a5e063ae47d (patch) | |
tree | 7f551b88923b35bc4022ce6ab3a3f602fb60d91c /webkit/port/platform/graphics | |
parent | dc4f63c80cb90efe594131030aad6776e5945fcc (diff) | |
download | chromium_src-de56f378336660dcc848763c80267a5e063ae47d.zip chromium_src-de56f378336660dcc848763c80267a5e063ae47d.tar.gz chromium_src-de56f378336660dcc848763c80267a5e063ae47d.tar.bz2 |
Merge the chrome_webkit_merge_branch back on to trunk. This brings us
up to webkit@36102.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@2778 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/port/platform/graphics')
31 files changed, 938 insertions, 690 deletions
diff --git a/webkit/port/platform/graphics/AffineTransformSkia.cpp b/webkit/port/platform/graphics/AffineTransformSkia.cpp index ed4942a..30d87d3 100644 --- a/webkit/port/platform/graphics/AffineTransformSkia.cpp +++ b/webkit/port/platform/graphics/AffineTransformSkia.cpp @@ -78,26 +78,18 @@ void AffineTransform::map(double x, double y, double *x2, double *y2) const *y2 = SkScalarToDouble(dst.fY); } -IntRect AffineTransform::mapRect(const IntRect &rect) const +IntRect AffineTransform::mapRect(const IntRect& src) const { - SkRect src, dst; - SkIRect ir; - - WebCoreRectToSkiaRect(rect, &src); + SkRect dst; m_transform.mapRect(&dst, src); - dst.round(&ir); - - return IntRect(ir.fLeft, ir.fTop, ir.width(), ir.height()); + return enclosingIntRect(dst); } -FloatRect AffineTransform::mapRect(const FloatRect &rect) const +FloatRect AffineTransform::mapRect(const FloatRect& src) const { - SkRect src, dst; - - WebCoreRectToSkiaRect(rect, &src); + SkRect dst; m_transform.mapRect(&dst, src); - - return FloatRect(dst.fLeft, dst.fTop, dst.width(), dst.height()); + return dst; } bool AffineTransform::isIdentity() const @@ -152,18 +144,18 @@ AffineTransform::operator SkMatrix() const return m_transform; } -bool AffineTransform::operator==(const AffineTransform &m2) const +bool AffineTransform::operator==(const AffineTransform& m2) const { return m_transform == m2.m_transform; } -AffineTransform &AffineTransform::operator*= (const AffineTransform &m2) +AffineTransform &AffineTransform::operator*=(const AffineTransform& m2) { m_transform.setConcat(m2.m_transform, m_transform); return *this; } -AffineTransform AffineTransform::operator* (const AffineTransform &m2) +AffineTransform AffineTransform::operator*(const AffineTransform& m2) { AffineTransform cat; @@ -171,46 +163,58 @@ AffineTransform AffineTransform::operator* (const AffineTransform &m2) return cat; } -double AffineTransform::a() const { +double AffineTransform::a() const +{ return SkScalarToDouble(m_transform.getScaleX()); } -void AffineTransform::setA(double a) { +void AffineTransform::setA(double a) +{ m_transform.setScaleX(WebCoreDoubleToSkScalar(a)); } -double AffineTransform::b() const { +double AffineTransform::b() const +{ return SkScalarToDouble(m_transform.getSkewY()); } -void AffineTransform::setB(double b) { +void AffineTransform::setB(double b) +{ m_transform.setSkewY(WebCoreDoubleToSkScalar(b)); } -double AffineTransform::c() const { +double AffineTransform::c() const +{ return SkScalarToDouble(m_transform.getSkewX()); } -void AffineTransform::setC(double c) { +void AffineTransform::setC(double c) +{ m_transform.setSkewX(WebCoreDoubleToSkScalar(c)); } -double AffineTransform::d() const { +double AffineTransform::d() const +{ return SkScalarToDouble(m_transform.getScaleY()); } -void AffineTransform::setD(double d) { +void AffineTransform::setD(double d) +{ m_transform.setScaleY(WebCoreDoubleToSkScalar(d)); } -double AffineTransform::e() const { +double AffineTransform::e() const +{ return SkScalarToDouble(m_transform.getTranslateX()); } -void AffineTransform::setE(double e) { +void AffineTransform::setE(double e) +{ m_transform.setTranslateX(WebCoreDoubleToSkScalar(e)); } -double AffineTransform::f() const { +double AffineTransform::f() const +{ return SkScalarToDouble(m_transform.getTranslateY()); } -void AffineTransform::setF(double f) { +void AffineTransform::setF(double f) +{ m_transform.setTranslateY(WebCoreDoubleToSkScalar(f)); } -} +} // namespace WebCore diff --git a/webkit/port/platform/graphics/ColorSkia.cpp b/webkit/port/platform/graphics/ColorSkia.cpp new file mode 100644 index 0000000..23c5eb0 --- /dev/null +++ b/webkit/port/platform/graphics/ColorSkia.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2008 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "Color.h" + +#include "SkColor.h" + +#include <wtf/Assertions.h> + +namespace WebCore { + +COMPILE_ASSERT(SK_ColorBLACK == Color::black, SkColorAndColorAreLaidOutTheSame); + +} // namespace WebCore diff --git a/webkit/port/platform/graphics/FloatPointSkia.cpp b/webkit/port/platform/graphics/FloatPointSkia.cpp new file mode 100644 index 0000000..01c94ef --- /dev/null +++ b/webkit/port/platform/graphics/FloatPointSkia.cpp @@ -0,0 +1,47 @@ +/*
+ * Copyright (C) 2008 Google, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "FloatPoint.h"
+
+#include "SkPoint.h"
+#include "SkiaUtils.h"
+
+namespace WebCore {
+
+FloatPoint::FloatPoint(const SkPoint& p)
+ : m_x(p.fX)
+ , m_y(p.fY)
+{
+}
+
+FloatPoint::operator SkPoint() const
+{
+ SkPoint p = { WebCoreFloatToSkScalar(m_x), WebCoreFloatToSkScalar(m_y) };
+ return p;
+}
+
+} // namespace WebCore
+
diff --git a/webkit/port/platform/graphics/FloatRectSkia.cpp b/webkit/port/platform/graphics/FloatRectSkia.cpp new file mode 100644 index 0000000..4676983 --- /dev/null +++ b/webkit/port/platform/graphics/FloatRectSkia.cpp @@ -0,0 +1,46 @@ +/*
+ * Copyright (C) 2008 Google, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "FloatRect.h"
+
+#include "SkRect.h"
+
+namespace WebCore {
+
+FloatRect::FloatRect(const SkRect& r)
+ : m_location(r.fLeft, r.fTop)
+ , m_size(r.width(), r.height())
+{
+}
+
+FloatRect::operator SkRect() const
+{
+ SkRect rect = { x(), y(), right(), bottom() };
+ return rect;
+}
+
+} // namespace WebCore
+
diff --git a/webkit/port/platform/graphics/FontCacheWin.cpp b/webkit/port/platform/graphics/FontCacheWin.cpp index 29fe120..e4b2c65 100644 --- a/webkit/port/platform/graphics/FontCacheWin.cpp +++ b/webkit/port/platform/graphics/FontCacheWin.cpp @@ -29,6 +29,7 @@ #include "config.h" #include "FontCache.h" #include "Font.h" +#include "HashSet.h" #include "SimpleFontData.h" #include "StringHash.h" #include <algorithm> @@ -555,6 +556,22 @@ FontPlatformData* FontCache::getLastResortFallbackFont( return getCachedFontPlatformData(description, fontStr); } +static LONG toGDIFontWeight(FontWeight fontWeight) +{ + static LONG gdiFontWeights[] = { + FW_THIN, // FontWeight100 + FW_EXTRALIGHT, // FontWeight200 + FW_LIGHT, // FontWeight300 + FW_NORMAL, // FontWeight400 + FW_MEDIUM, // FontWeight500 + FW_SEMIBOLD, // FontWeight600 + FW_BOLD, // FontWeight700 + FW_EXTRABOLD, // FontWeight800 + FW_HEAVY // FontWeight900 + }; + return gdiFontWeights[fontWeight]; +} + // TODO(jungshik): This may not be the best place to put this function. See // TODO in pending/FontCache.h. AtomicString FontCache::getGenericFontForScript(UScriptCode script, const FontDescription& description) @@ -584,16 +601,7 @@ static void FillLogFont(const FontDescription& fontDescription, LOGFONT* winfont : DEFAULT_QUALITY; // Honor user's desktop settings. winfont->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; winfont->lfItalic = fontDescription.italic(); - - // FIXME: Support weights for real. Do our own enumeration of the available weights. - // We can't rely on Windows here, since we need to follow the CSS2 algorithm for how to fill in - // gaps in the weight list. - // fontExists() used to hardcod Lucida Grande. According to FIXME comment, - // that's because it uses different weights than typical Win32 fonts - // (500/600 instead of 400/700). However, createFontPlatformData - // didn't. Special-casing Lucida Grande in a refactored function - // led to massive webkit test failure. - winfont->lfWeight = fontDescription.bold() ? 700 : 400; + winfont->lfWeight = toGDIFontWeight(fontDescription.weight()); } bool FontCache::fontExists(const FontDescription& fontDescription, const AtomicString& family) @@ -618,6 +626,55 @@ bool FontCache::fontExists(const FontDescription& fontDescription, const AtomicS return LookupAltName(family, altName) && equalIgnoringCase(altName, winName); } +struct TraitsInFamilyProcData { + TraitsInFamilyProcData(const AtomicString& familyName) + : m_familyName(familyName) + { + } + + const AtomicString& m_familyName; + HashSet<unsigned> m_traitsMasks; +}; + +static int CALLBACK traitsInFamilyEnumProc(CONST LOGFONT* logFont, CONST TEXTMETRIC* metrics, DWORD fontType, LPARAM lParam) +{ + TraitsInFamilyProcData* procData = reinterpret_cast<TraitsInFamilyProcData*>(lParam); + + unsigned traitsMask = 0; + traitsMask |= logFont->lfItalic ? FontStyleItalicMask : FontStyleNormalMask; + traitsMask |= FontVariantNormalMask; + LONG weight = logFont->lfWeight; + traitsMask |= weight == FW_THIN ? FontWeight100Mask : + weight == FW_EXTRALIGHT ? FontWeight200Mask : + weight == FW_LIGHT ? FontWeight300Mask : + weight == FW_NORMAL ? FontWeight400Mask : + weight == FW_MEDIUM ? FontWeight500Mask : + weight == FW_SEMIBOLD ? FontWeight600Mask : + weight == FW_BOLD ? FontWeight700Mask : + weight == FW_EXTRABOLD ? FontWeight800Mask : + FontWeight900Mask; + procData->m_traitsMasks.add(traitsMask); + return 1; +} + +void FontCache::getTraitsInFamily(const AtomicString& familyName, Vector<unsigned>& traitsMasks) +{ + HDC hdc = GetDC(0); + + LOGFONT logFont; + logFont.lfCharSet = DEFAULT_CHARSET; + unsigned familyLength = min(familyName.length(), static_cast<unsigned>(LF_FACESIZE - 1)); + memcpy(logFont.lfFaceName, familyName.characters(), familyLength * sizeof(UChar)); + logFont.lfFaceName[familyLength] = 0; + logFont.lfPitchAndFamily = 0; + + TraitsInFamilyProcData procData(familyName); + EnumFontFamiliesEx(hdc, &logFont, traitsInFamilyEnumProc, reinterpret_cast<LPARAM>(&procData), 0); + copyToVector(procData.m_traitsMasks, traitsMasks); + + ReleaseDC(0, hdc); +} + FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family) { LOGFONT winfont = {0}; @@ -631,8 +688,8 @@ FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontD if (!hfont) return 0; - // TODO(pamg): Do we need to use predefined fonts "guaranteed" to exist - // when we're running in layout-test mode? + // TODO(pamg): Do we need to use predefined fonts "guaranteed" to exist + // when we're running in layout-test mode? if (!equalIgnoringCase(family, winName)) { // For CJK fonts with both English and native names, // GetTextFace returns a native name under the font's "locale" diff --git a/webkit/port/platform/graphics/FontPlatformData.h b/webkit/port/platform/graphics/FontPlatformData.h index ff0d863..25938dc 100644 --- a/webkit/port/platform/graphics/FontPlatformData.h +++ b/webkit/port/platform/graphics/FontPlatformData.h @@ -25,6 +25,7 @@ #define FontPlatformData_H #include "StringImpl.h" +#include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> typedef struct HFONT__ *HFONT; @@ -36,21 +37,13 @@ class FontDescription; class FontPlatformData { public: - class Deleted {}; - // Used for deleted values in the font cache's hash tables. The hash table // will create us with this structure, and it will compare other values // to this "Deleted" one. It expects the Deleted one to be differentiable // from the NULL one (created with the empty constructor), so we can't just // set everything to NULL. - // - // NOTE: On WebKit trunk now, this is changed to the new value - // WTF::HashTableDeletedValue (declared in RefPtr.h). When we merge to a - // version with that, we should use it and remove our "Deleted" version. - // We would just assign the magic WTF::HashTableDeletedValue to our - // m_font RefPtr. - FontPlatformData(Deleted) - : m_font(RefCountedHFONT::createDeleted()) + FontPlatformData(WTF::HashTableDeletedValueType) + : m_font(hashTableDeletedFontValue()) , m_size(-1) , m_isMLangFont(false) {} @@ -65,6 +58,8 @@ public: bool isMLangFont); FontPlatformData(float size, bool bold, bool oblique); + bool isHashTableDeletedValue() const { return m_font == hashTableDeletedFontValue(); } + ~FontPlatformData(); HFONT hfont() const { return m_font ? m_font->hfont() : 0; } @@ -87,8 +82,10 @@ private: // don't really want to re-create the HFONT. class RefCountedHFONT : public RefCounted<RefCountedHFONT> { public: - static PassRefPtr<RefCountedHFONT> create(HFONT hfont) { return adoptRef(new RefCountedHFONT(hfont)); } - static PassRefPtr<RefCountedHFONT> createDeleted() { return adoptRef(new RefCountedHFONT(reinterpret_cast<HFONT>(-1))); } + static PassRefPtr<RefCountedHFONT> create(HFONT hfont) + { + return adoptRef(new RefCountedHFONT(hfont)); + } ~RefCountedHFONT(); @@ -102,14 +99,15 @@ private: // The create() function assumes there is already a refcount of one // so it can do adoptRef. RefCountedHFONT(HFONT hfont) - : RefCounted<RefCountedHFONT>(1) - , m_hfont(hfont) + : m_hfont(hfont) { } HFONT m_hfont; }; + static RefCountedHFONT* hashTableDeletedFontValue(); + RefPtr<RefCountedHFONT> m_font; float m_size; // Point size of the font in pixels. diff --git a/webkit/port/platform/graphics/FontPlatformDataWin.cpp b/webkit/port/platform/graphics/FontPlatformDataWin.cpp index 53ade3e..2aad126 100644 --- a/webkit/port/platform/graphics/FontPlatformDataWin.cpp +++ b/webkit/port/platform/graphics/FontPlatformDataWin.cpp @@ -55,4 +55,11 @@ FontPlatformData::RefCountedHFONT::~RefCountedHFONT() DeleteObject(m_hfont); } +FontPlatformData::RefCountedHFONT* FontPlatformData::hashTableDeletedFontValue() +{ + static RefPtr<RefCountedHFONT> deletedValue = + RefCountedHFONT::create(reinterpret_cast<HFONT>(-1)); + return deletedValue.get(); +} + } diff --git a/webkit/port/platform/graphics/FontWin.cpp b/webkit/port/platform/graphics/FontWin.cpp index 0287d3f..9bd5a7a 100644 --- a/webkit/port/platform/graphics/FontWin.cpp +++ b/webkit/port/platform/graphics/FontWin.cpp @@ -47,8 +47,6 @@ void Font::drawGlyphs(GraphicsContext* graphicsContext, const FloatPoint& point) const { PlatformGraphicsContext* context = graphicsContext->platformContext(); - SkPoint origin; - WebCorePointToSkiaPoint(point, &origin); // Max buffer length passed to the underlying windows API. const int kMaxBufferLength = 1024; @@ -84,7 +82,7 @@ void Font::drawGlyphs(GraphicsContext* graphicsContext, // the 'point' represents the baseline, so we need to move it up to the // top of the bounding square by subtracting the ascent - SkPoint origin2 = origin; + SkPoint origin2 = point; origin2.fY -= font->ascent(); origin2.fX += chunk_x; @@ -135,10 +133,7 @@ void Font::drawComplexText(GraphicsContext* context, int to) const { UniscribeStateTextRun state(run, *this); - PlatformContextSkia* skia = PlatformContextToPlatformContextSkia(context->platformContext()); - SkPoint p; - WebCorePointToSkiaPoint(point, &p); - skia->paintComplexText(state, p, from, to, ascent()); + context->platformContext()->paintComplexText(state, point, from, to, ascent()); } float Font::floatWidthForComplexText(const TextRun& run) const @@ -161,4 +156,4 @@ int Font::offsetForPositionForComplexText(const TextRun& run, int x, bool includ return char_index; } -} +} // namespace WebCore diff --git a/webkit/port/platform/graphics/GradientSkia.cpp b/webkit/port/platform/graphics/GradientSkia.cpp new file mode 100644 index 0000000..b287bde --- /dev/null +++ b/webkit/port/platform/graphics/GradientSkia.cpp @@ -0,0 +1,142 @@ +/*
+ * Copyright (C) 2008 Google, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Gradient.h"
+
+#include "CSSParser.h"
+#include "GraphicsContext.h"
+#include "NotImplemented.h"
+
+#include "SkGradientShader.h"
+#include "SkiaUtils.h"
+
+namespace WebCore {
+
+void Gradient::platformDestroy()
+{
+ if (m_gradient)
+ m_gradient->safeUnref();
+ m_gradient = 0;
+}
+
+static inline U8CPU F2B(float x)
+{
+ return static_cast<int>(x * 255);
+}
+
+static SkColor makeSkColor(float a, float r, float g, float b)
+{
+ return SkColorSetARGB(F2B(a), F2B(r), F2B(g), F2B(b));
+}
+
+// Determine the total number of stops needed, including pseudo-stops at the
+// ends as necessary.
+static size_t total_stops_needed(const Gradient::ColorStop* stopData, size_t count)
+{
+ const Gradient::ColorStop* stop = stopData;
+ size_t count_used = count;
+ if (count < 1 || stop->stop > 0.0)
+ count_used++;
+ stop += count - 1;
+ if (count < 2 || stop->stop < 1.0)
+ count_used++;
+ return count_used;
+}
+
+// Collect sorted stop position and color information into the pos and colors
+// buffers, ensuring stops at both 0.0 and 1.0. The buffers must be large
+// enough to hold information for all stops, including the new endpoints if
+// stops at 0.0 and 1.0 aren't already included.
+static void fill_stops(const Gradient::ColorStop* stopData,
+ size_t count, SkScalar* pos, SkColor* colors)
+{
+ const Gradient::ColorStop* stop = stopData;
+ size_t start = 0;
+ if (count < 1) {
+ // A gradient with no stops must be transparent black.
+ pos[0] = WebCoreFloatToSkScalar(0.0);
+ colors[0] = makeSkColor(0.0, 0.0, 0.0, 0.0);
+ start = 1;
+ } else if (stop->stop > 0.0) {
+ // Copy the first stop to 0.0. The first stop position may have a slight
+ // rounding error, but we don't care in this float comparison, since
+ // 0.0 comes through cleanly and people aren't likely to want a gradient
+ // with a stop at (0 + epsilon).
+ pos[0] = WebCoreFloatToSkScalar(0.0);
+ colors[0] = makeSkColor(stop->alpha, stop->red, stop->green, stop->blue);
+ start = 1;
+ }
+
+ for (size_t i = start; i < start + count; i++) {
+ pos[i] = WebCoreFloatToSkScalar(stop->stop);
+ colors[i] = makeSkColor(stop->alpha, stop->red, stop->green, stop->blue);
+ ++stop;
+ }
+
+ // Copy the last stop to 1.0 if needed. See comment above about this float
+ // comparison.
+ if (count < 1 || (--stop)->stop < 1.0) {
+ pos[start + count] = WebCoreFloatToSkScalar(1.0);
+ colors[start + count] = colors[start + count - 1];
+ }
+}
+
+SkShader* Gradient::platformGradient()
+{
+ if (m_gradient)
+ return m_gradient;
+
+ size_t count_used = total_stops_needed(m_stops.data(), m_stops.size());
+ ASSERT(count_used >= 2);
+ ASSERT(count_used >= m_stops.size());
+
+ // FIXME: Why is all this manual pointer math needed?!
+ SkAutoMalloc storage(count_used * (sizeof(SkColor) + sizeof(SkScalar)));
+ SkColor* colors = (SkColor*)storage.get();
+ SkScalar* pos = (SkScalar*)(colors + count_used);
+
+ fill_stops(m_stops.data(), m_stops.size(), pos, colors);
+
+ if (m_radial) {
+ m_gradient = SkGradientShader::CreateRadial(m_p1,
+ WebCoreFloatToSkScalar(m_r1), colors, pos,
+ static_cast<int>(count_used), SkShader::kClamp_TileMode);
+ } else {
+ SkPoint pts[2] = { m_p0, m_p1 };
+ m_gradient = SkGradientShader::CreateLinear(pts, colors, pos,
+ static_cast<int>(count_used), SkShader::kClamp_TileMode);
+ }
+
+ return m_gradient;
+}
+
+void Gradient::fill(GraphicsContext* context, const FloatRect& rect)
+{
+ // Until this is filled, we don't support CSSGradients
+ notImplemented();
+}
+
+} // namespace WebCore
diff --git a/webkit/port/platform/graphics/GraphicsContextPrivate.cpp b/webkit/port/platform/graphics/GraphicsContextPlatformPrivate.cpp index d06ee33..7f28d19 100644 --- a/webkit/port/platform/graphics/GraphicsContextPrivate.cpp +++ b/webkit/port/platform/graphics/GraphicsContextPlatformPrivate.cpp @@ -19,9 +19,8 @@ #include "config.h" -#include "GraphicsContextPrivate.h" - #include "GraphicsContext.h" +#include "GraphicsContextPlatformPrivate.h" #include "PlatformContextSkia.h" namespace WebCore { diff --git a/webkit/port/platform/graphics/GraphicsContextPrivate.h b/webkit/port/platform/graphics/GraphicsContextPlatformPrivate.h index 70e3d60..77f5e89 100644 --- a/webkit/port/platform/graphics/GraphicsContextPrivate.h +++ b/webkit/port/platform/graphics/GraphicsContextPlatformPrivate.h @@ -30,9 +30,7 @@ public: GraphicsContextPlatformPrivate(PlatformContextSkia* pgc); ~GraphicsContextPlatformPrivate(); - PlatformContextSkia* platformContext() { - return m_context; - } + PlatformContextSkia* platformContext() { return m_context; } void setShouldDelete(bool should_delete) { m_should_delete = should_delete; diff --git a/webkit/port/platform/graphics/GraphicsContextSkia.cpp b/webkit/port/platform/graphics/GraphicsContextSkia.cpp index 90eb7ea..d282555 100644 --- a/webkit/port/platform/graphics/GraphicsContextSkia.cpp +++ b/webkit/port/platform/graphics/GraphicsContextSkia.cpp @@ -18,20 +18,22 @@ #include "config.h" #include "GraphicsContext.h" +#include "GraphicsContextPlatformPrivate.h" #include "GraphicsContextPrivate.h" #include "wtf/MathExtras.h" #include "Assertions.h" #include "AffineTransform.h" +#include "FloatRect.h" +#include "Gradient.h" +#include "IntRect.h" #include "NativeImageSkia.h" +#include "NotImplemented.h" #include "SkBlurDrawLooper.h" #include "SkCornerPathEffect.h" #include "SkiaUtils.h" -#ifdef ANDROID_CANVAS_IMPL -# include "SkBitmap.h" -# include "SkGradientShader.h" -#endif +#include "SkBitmap.h" #include "base/gfx/platform_canvas_win.h" @@ -165,70 +167,6 @@ void add_corner_arc(SkPath* path, const SkRect& rect, const IntSize& size, int s path->arcTo(r, SkIntToScalar(startAngle), SkIntToScalar(90), false); } -U8CPU F2B(float x) -{ - return (int)(x * 255); -} - -SkColor make_color(float a, float r, float g, float b) -{ - return SkColorSetARGB(F2B(a), F2B(r), F2B(g), F2B(b)); -} - -// Determine the total number of stops needed, including pseudo-stops at the -// ends as necessary. -size_t total_stops_needed(const WebCore::CanvasGradient::ColorStop* stopData, - size_t count) -{ - const WebCore::CanvasGradient::ColorStop* stop = stopData; - size_t count_used = count; - if (count < 1 || stop->stop > 0.0) - count_used++; - stop += count - 1; - if (count < 2 || stop->stop < 1.0) - count_used++; - return count_used; -} - -// Collect sorted stop position and color information into the pos and colors -// buffers, ensuring stops at both 0.0 and 1.0. The buffers must be large -// enough to hold information for all stops, including the new endpoints if -// stops at 0.0 and 1.0 aren't already included. -void fill_stops(const WebCore::CanvasGradient::ColorStop* stopData, - size_t count, SkScalar* pos, SkColor* colors) -{ - const WebCore::CanvasGradient::ColorStop* stop = stopData; - size_t start = 0; - if (count < 1) { - // A gradient with no stops must be transparent black. - pos[0] = WebCoreFloatToSkScalar(0.0); - colors[0] = make_color(0.0, 0.0, 0.0, 0.0); - start = 1; - } else if (stop->stop > 0.0) { - // Copy the first stop to 0.0. The first stop position may have a slight - // rounding error, but we don't care in this float comparison, since - // 0.0 comes through cleanly and people aren't likely to want a gradient - // with a stop at (0 + epsilon). - pos[0] = WebCoreFloatToSkScalar(0.0); - colors[0] = make_color(stop->alpha, stop->red, stop->green, stop->blue); - start = 1; - } - - for (size_t i = start; i < start + count; i++) - { - pos[i] = WebCoreFloatToSkScalar(stop->stop); - colors[i] = make_color(stop->alpha, stop->red, stop->green, stop->blue); - ++stop; - } - - // Copy the last stop to 1.0 if needed. See comment above about this float - // comparison. - if (count < 1 || (--stop)->stop < 1.0) { - pos[start + count] = WebCoreFloatToSkScalar(1.0); - colors[start + count] = colors[start + count - 1]; - } -} - COMPILE_ASSERT(GraphicsContextPlatformPrivate::NoStroke == NoStroke, AssertNoStroke); COMPILE_ASSERT(GraphicsContextPlatformPrivate::SolidStroke == SolidStroke, AssertSolidStroke); COMPILE_ASSERT(GraphicsContextPlatformPrivate::DottedStroke == DottedStroke, AssertDottedStroke); @@ -248,7 +186,7 @@ GraphicsContextPlatformPrivate::StrokeStyle StrokeStyle2StrokeStyle(StrokeStyle // no painting. GraphicsContext::GraphicsContext(PlatformGraphicsContext *gc) : m_common(createGraphicsContextPrivate()) - , m_data(new GraphicsContextPlatformPrivate(PlatformContextToPlatformContextSkia(gc))) + , m_data(new GraphicsContextPlatformPrivate(gc)) { setPaintingDisabled(!m_data->canvas()); } @@ -277,9 +215,8 @@ void GraphicsContext::drawRect(const IntRect& rect) if (paintingDisabled()) return; - SkRect r; - WebCoreRectToSkiaRect(rect, &r); - if (!IsRectReasonable(m_data->canvas()->getTotalMatrix(), r)) { + SkRect r = rect; + if (!IsRectReasonable(getCTM(), r)) { // See the fillRect below. ClipRectToCanvas(*m_data->canvas(), r, &r); } @@ -298,21 +235,17 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2) return; SkPaint paint; - SkPoint pts[2]; - - WebCorePointToSkiaPoint(point1, &pts[0]); - WebCorePointToSkiaPoint(point2, &pts[1]); - if (!IsPointReasonable(m_data->canvas()->getTotalMatrix(), pts[0]) || - !IsPointReasonable(m_data->canvas()->getTotalMatrix(), pts[1])) + SkPoint pts[2] = { (SkPoint)point1, (SkPoint)point2 }; + if (!IsPointReasonable(getCTM(), pts[0]) || + !IsPointReasonable(getCTM(), pts[1])) return; //we know these are vertical or horizontal lines, so the length will just be the sum of the //displacement component vectors give or take 1 - probably worth the speed up of no square //root, which also won't be exact - SkPoint disp = pts[1]-pts[0]; - int length = SkScalarRound(disp.fX+disp.fY); - //int length = SkScalarRound(disp.length()); - int width = m_data->setup_paint_stroke(&paint, NULL, length); + SkPoint disp = pts[1] - pts[0]; + int length = SkScalarRound(disp.fX + disp.fY); + int width = m_data->setup_paint_stroke(&paint, 0, length); // "borrowed" this comment and idea from GraphicsContextCG.cpp // For odd widths, we add in 0.5 to the appropriate x/y so that the float arithmetic @@ -324,12 +257,10 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2) if (width & 1) //odd { - if (isVerticalLine) - { + if (isVerticalLine) { pts[0].fX = pts[0].fX + SK_ScalarHalf; pts[1].fX = pts[0].fX; - } - else //Horizontal line + } else //Horizontal line { pts[0].fY = pts[0].fY + SK_ScalarHalf; pts[1].fY = pts[0].fY; @@ -439,26 +370,24 @@ void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint& pt, } // This method is only used to draw the little circles used in lists. -void GraphicsContext::drawEllipse(const IntRect& rect) +void GraphicsContext::drawEllipse(const IntRect& elipseRect) { if (paintingDisabled()) return; - SkPaint paint; - SkRect oval; - - WebCoreRectToSkiaRect(rect, &oval); - if (!IsRectReasonable(m_data->canvas()->getTotalMatrix(), oval)) + SkRect rect = elipseRect; + if (!IsRectReasonable(getCTM(), rect)) return; + SkPaint paint; if (fillColor().rgb() & 0xFF000000) { m_data->setup_paint_fill(&paint); - m_data->canvas()->drawOval(oval, paint); + m_data->canvas()->drawOval(rect, paint); } if (strokeStyle() != NoStroke) { paint.reset(); - m_data->setup_paint_stroke(&paint, &oval, 0); - m_data->canvas()->drawOval(oval, paint); + m_data->setup_paint_stroke(&paint, &rect, 0); + m_data->canvas()->drawOval(rect, paint); } } @@ -478,27 +407,23 @@ void GraphicsContext::strokeArc(const IntRect& r, int startAngle, int angleSpan) if (paintingDisabled()) return; - SkPath path; SkPaint paint; - SkRect oval; - - WebCoreRectToSkiaRect(r, &oval); + SkRect oval = r; if (strokeStyle() == NoStroke) { m_data->setup_paint_fill(&paint); // we want the fill color paint.setStyle(SkPaint::kStroke_Style); paint.setStrokeWidth(WebCoreFloatToSkScalar(strokeThickness())); - } - else { + } else m_data->setup_paint_stroke(&paint, NULL, 0); - } // we do this before converting to scalar, so we don't overflow SkFixed startAngle = fast_mod(startAngle, 360); angleSpan = fast_mod(angleSpan, 360); + SkPath path; path.addArc(oval, SkIntToScalar(-startAngle), SkIntToScalar(-angleSpan)); - if (!IsPathReasonable(m_data->canvas()->getTotalMatrix(), path)) + if (!IsPathReasonable(getCTM(), path)) return; m_data->canvas()->drawPath(path, paint); } @@ -511,7 +436,6 @@ void GraphicsContext::drawConvexPolygon(size_t numPoints, const FloatPoint* poin if (numPoints <= 1) return; - SkPaint paint; SkPath path; path.incReserve(numPoints); @@ -519,9 +443,10 @@ void GraphicsContext::drawConvexPolygon(size_t numPoints, const FloatPoint* poin for (size_t i = 1; i < numPoints; i++) path.lineTo(WebCoreFloatToSkScalar(points[i].x()), WebCoreFloatToSkScalar(points[i].y())); - if (!IsPathReasonable(m_data->canvas()->getTotalMatrix(), path)) + if (!IsPathReasonable(getCTM(), path)) return; + SkPaint paint; if (fillColor().rgb() & 0xFF000000) { m_data->setup_paint_fill(&paint); m_data->canvas()->drawPath(path, paint); @@ -534,171 +459,115 @@ void GraphicsContext::drawConvexPolygon(size_t numPoints, const FloatPoint* poin } } -#ifdef ANDROID_CANVAS_IMPL - -static void check_set_shader(SkPaint* paint, SkShader* s0, SkShader* s1) -{ - if (s0) { - paint->setShader(s0); - } - else if (s1) { - paint->setShader(s1); - } -} - - -void GraphicsContext::fillPath(const Path& webCorePath, PlatformGradient* grad, PlatformPattern* pat) -{ - fillPath(PathToSkPath(webCorePath), grad, pat); -} - -void GraphicsContext::fillPath(PlatformPath* path, PlatformGradient* grad, PlatformPattern* pat) +void GraphicsContext::fillPath() { if (paintingDisabled()) return; - if (!IsPathReasonable(m_data->canvas()->getTotalMatrix(), *path)) + const SkPath& path = *m_data->currentPath(); + if (!IsPathReasonable(getCTM(), path)) return; - SkPaint paint; + const GraphicsContextState& state = m_common->state; + ColorSpace colorSpace = state.fillColorSpace; - m_data->setup_paint_fill(&paint); - check_set_shader(&paint, grad, pat); + if (colorSpace == SolidColorSpace && !fillColor().alpha()) + return; - m_data->canvas()->drawPath(*path, paint); -} + SkPaint paint; + m_data->setup_paint_fill(&paint); + if (colorSpace == PatternColorSpace) { + SkShader* pat = state.fillPattern->createPlatformPattern(getCTM()); + paint.setShader(pat); + pat->unref(); + } else if (colorSpace == GradientColorSpace) + paint.setShader(state.fillGradient->platformGradient()); -void GraphicsContext::strokePath(const Path& webCorePath, PlatformGradient* grad, PlatformPattern* pat) -{ - strokePath(PathToSkPath(webCorePath), grad, pat); + m_data->canvas()->drawPath(path, paint); } -void GraphicsContext::strokePath(PlatformPath* path, PlatformGradient* grad, PlatformPattern* pat) +void GraphicsContext::strokePath() { if (paintingDisabled()) return; - if (!IsPathReasonable(m_data->canvas()->getTotalMatrix(), *path)) + const SkPath& path = *m_data->currentPath(); + if (!IsPathReasonable(getCTM(), path)) return; - SkPaint paint; + const GraphicsContextState& state = m_common->state; + ColorSpace colorSpace = state.strokeColorSpace; + + if (colorSpace == SolidColorSpace && !strokeColor().alpha()) + return; + SkPaint paint; m_data->setup_paint_stroke(&paint, NULL, 0); - check_set_shader(&paint, grad, pat); - m_data->canvas()->drawPath(*path, paint); + if (colorSpace == PatternColorSpace) { + SkShader* pat = state.strokePattern->createPlatformPattern(getCTM()); + paint.setShader(pat); + pat->unref(); + } else if (colorSpace == GradientColorSpace) + paint.setShader(state.strokeGradient->platformGradient()); + + m_data->canvas()->drawPath(path, paint); } -void GraphicsContext::fillRect(const FloatRect& rect, PlatformGradient* grad, PlatformPattern* pat) +void GraphicsContext::fillRect(const FloatRect& rect) { if (paintingDisabled()) return; - SkPaint paint; - m_data->setup_paint_fill(&paint); - check_set_shader(&paint, grad, pat); - - SkRect r; - WebCoreRectToSkiaRect(rect, &r); - if (!IsRectReasonable(m_data->canvas()->getTotalMatrix(), r)) { + SkRect r = rect; + if (!IsRectReasonable(getCTM(), r)) { // See the other version of fillRect below. ClipRectToCanvas(*m_data->canvas(), r, &r); } - m_data->canvas()->drawRect(r, paint); -} + const GraphicsContextState& state = m_common->state; + ColorSpace colorSpace = state.fillColorSpace; -void GraphicsContext::strokeRect(const FloatRect& rect, float lineWidth, PlatformGradient* grad, PlatformPattern* pat) -{ - if (paintingDisabled()) + if (colorSpace == SolidColorSpace && !fillColor().alpha()) return; SkPaint paint; - m_data->setup_paint_stroke(&paint, NULL, 0); - paint.setStrokeWidth(WebCoreFloatToSkScalar(lineWidth)); - check_set_shader(&paint, grad, pat); + m_data->setup_paint_fill(&paint); - SkRect r; - WebCoreRectToSkiaRect(rect, &r); - if (!IsRectReasonable(m_data->canvas()->getTotalMatrix(), r)) - return; + if (colorSpace == PatternColorSpace) { + SkShader* pat = state.fillPattern->createPlatformPattern(getCTM()); + paint.setShader(pat); + pat->unref(); + } else if (colorSpace == GradientColorSpace) + paint.setShader(state.fillGradient->platformGradient()); m_data->canvas()->drawRect(r, paint); } -PlatformGradient* GraphicsContext::newPlatformLinearGradient(const FloatPoint& p0, - const FloatPoint& p1, - const WebCore::CanvasGradient::ColorStop* stopData, size_t count) +void GraphicsContext::strokeRect(const FloatRect& rect, float lineWidth) { - SkPoint pts[2]; - WebCorePointToSkiaPoint(p0, &pts[0]); - WebCorePointToSkiaPoint(p1, &pts[1]); - - size_t count_used = total_stops_needed(stopData, count); - ASSERT(count_used >= 2); - ASSERT(count_used >= count); - - SkAutoMalloc storage(count_used * (sizeof(SkColor) + sizeof(SkScalar))); - SkColor* colors = (SkColor*)storage.get(); - SkScalar* pos = (SkScalar*)(colors + count_used); - - fill_stops(stopData, count, pos, colors); - return SkGradientShader::CreateLinear(pts, colors, pos, - static_cast<int>(count_used), - SkShader::kClamp_TileMode); -} - -PlatformGradient* GraphicsContext::newPlatformRadialGradient(const FloatPoint& p0, float r0, - const FloatPoint& p1, float r1, - const WebCore::CanvasGradient::ColorStop* stopData, size_t count) -{ - SkPoint center; - WebCorePointToSkiaPoint(p1, ¢er); - SkMatrix identity; - identity.reset(); - if (!IsPointReasonable(identity, center)) { - center.fX = 0; - center.fY = 0; - } - - size_t count_used = total_stops_needed(stopData, count); - ASSERT(count_used >= 2); - ASSERT(count_used >= count); - - SkAutoMalloc storage(count_used * (sizeof(SkColor) + sizeof(SkScalar))); - SkColor* colors = (SkColor*)storage.get(); - SkScalar* pos = (SkScalar*)(colors + count_used); - - fill_stops(stopData, count, pos, colors); - return SkGradientShader::CreateRadial(center, WebCoreFloatToSkScalar(r1), - colors, pos, - static_cast<int>(count_used), - SkShader::kClamp_TileMode); -} + if (paintingDisabled()) + return; + if (!IsRectReasonable(getCTM(), rect)) + return; -void GraphicsContext::freePlatformGradient(PlatformGradient* shader) -{ - shader->safeUnref(); -} + const GraphicsContextState& state = m_common->state; + ColorSpace colorSpace = state.strokeColorSpace; -PlatformPattern* GraphicsContext::newPlatformPattern(Image* image, - Image::TileRule hRule, - Image::TileRule vRule) -{ - if (NULL == image) - return NULL; + if (colorSpace == SolidColorSpace && !strokeColor().alpha()) + return; - NativeImageSkia* bm = image->getBitmap(); - if (NULL == bm) - return NULL; + SkPaint paint; + m_data->setup_paint_stroke(&paint, NULL, 0); + paint.setStrokeWidth(WebCoreFloatToSkScalar(lineWidth)); - return SkShader::CreateBitmapShader(*bm, - WebCoreTileToSkiaTile(hRule), - WebCoreTileToSkiaTile(vRule)); -} + if (colorSpace == PatternColorSpace) { + SkShader* pat = state.strokePattern->createPlatformPattern(getCTM()); + paint.setShader(pat); + pat->unref(); + } else if (colorSpace == GradientColorSpace) + paint.setShader(state.strokeGradient->platformGradient()); -void GraphicsContext::freePlatformPattern(PlatformPattern* shader) -{ - shader->safeUnref(); + m_data->canvas()->drawRect(rect, paint); } GraphicsContext* GraphicsContext::createOffscreenContext(int width, int height) @@ -725,21 +594,20 @@ void GraphicsContext::drawOffscreenContext(GraphicsContext* ctx, const FloatRect if (paintingDisabled() || ctx->paintingDisabled()) return; - const SkBitmap& bm = ctx->m_data->canvas()->getDevice()->accessBitmap(false); - SkIRect src; - SkRect dst; - SkPaint paint; + SkIRect src; if (srcRect) { - WebCoreRectToSkiaRect(*srcRect, &src); - // FIXME(brettw) FIX THIS YOU RETARD! + src = enclosingIntRect(*srcRect); + if (!IsRectReasonable(getCTM(), *srcRect)) + return; } - - WebCoreRectToSkiaRect(dstRect, &dst); - if (!IsRectReasonable(m_data->canvas()->getTotalMatrix(), dst)) + SkRect dst = dstRect; + if (!IsRectReasonable(getCTM(), dst)) return; + SkPaint paint; paint.setFilterBitmap(true); + const SkBitmap& bm = ctx->m_data->canvas()->getDevice()->accessBitmap(false); m_data->canvas()->drawBitmapRect(bm, srcRect ? &src : NULL, dst, @@ -749,38 +617,33 @@ void GraphicsContext::drawOffscreenContext(GraphicsContext* ctx, const FloatRect FloatRect GraphicsContext::getClipLocalBounds() const { SkRect r; - if (!m_data->canvas()->getClipBounds(&r)) r.setEmpty(); - return FloatRect(SkScalarToFloat(r.fLeft), SkScalarToFloat(r.fTop), - SkScalarToFloat(r.width()), SkScalarToFloat(r.height())); + return r; } -FloatRect GraphicsContext::getPathBoundingBox(const Path& path) const +FloatRect GraphicsContext::getBoundingBoxForCurrentPath(bool includeStroke) const { - SkRect r; - SkPaint paint; - m_data->setup_paint_stroke(&paint, NULL, 0); - SkPath boundingPath; - paint.getFillPath(*path.platformPath(), &boundingPath); + if (includeStroke) { + SkPaint paint; + m_data->setup_paint_stroke(&paint, NULL, 0); + paint.getFillPath(*m_data->currentPath(), &boundingPath); + } else + boundingPath = *m_data->currentPath(); + + SkRect r; boundingPath.computeBounds(&r, SkPath::kExact_BoundsType); - return FloatRect( - SkScalarToFloat(r.fLeft), - SkScalarToFloat(r.fTop), - SkScalarToFloat(r.width()), - SkScalarToFloat(r.height())); + return r; } bool GraphicsContext::strokeContains(const Path& path, const FloatPoint& point) const { - SkRegion rgn, clip; SkPaint paint; - m_data->setup_paint_stroke(&paint, NULL, 0); SkPath strokePath; @@ -789,33 +652,14 @@ bool GraphicsContext::strokeContains(const Path& path, const FloatPoint& point) return SkPathContainsPoint(&strokePath, point, SkPath::kWinding_FillType); } - -#endif // ANDROID_CANVAS_IMPL - -#if 0 -static int getBlendedColorComponent(int c, int a) -{ - // We use white. - float alpha = (float)(a) / 255; - int whiteBlend = 255 - a; - c -= whiteBlend; - return (int)(c/alpha); -} -#endif - -void GraphicsContext::fillRect(const IntRect& rect, const Color& color) +void GraphicsContext::fillRect(const FloatRect& rect, const Color& color) { if (paintingDisabled()) return; if (color.rgb() & 0xFF000000) { - SkPaint paint; - SkRect r; - - WebCoreRectToSkiaRect(rect, &r); - - static const float kMaxCoord = 32767; - if (!IsRectReasonable(m_data->canvas()->getTotalMatrix(), r)) { + SkRect r = rect; + if (!IsRectReasonable(getCTM(), r)) { // Special case when the rectangle overflows fixed point. This is a // workaround to fix bug 1212844. When the input rectangle is very // large, it can overflow Skia's internal fixed point rect. This @@ -829,27 +673,7 @@ void GraphicsContext::fillRect(const IntRect& rect, const Color& color) ClipRectToCanvas(*m_data->canvas(), r, &r); } - m_data->setup_paint_common(&paint); - paint.setColor(color.rgb()); - m_data->canvas()->drawRect(r, paint); - } -} - -void GraphicsContext::fillRect(const FloatRect& rect, const Color& color) -{ - if (paintingDisabled()) - return; - - if (color.rgb() & 0xFF000000) { SkPaint paint; - SkRect r; - - WebCoreRectToSkiaRect(rect, &r); - if (!IsRectReasonable(m_data->canvas()->getTotalMatrix(), r)) { - // See other fillRect() above. - ClipRectToCanvas(*m_data->canvas(), r, &r); - } - m_data->setup_paint_common(&paint); paint.setColor(color.rgb()); m_data->canvas()->drawRect(r, paint); @@ -862,34 +686,31 @@ void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLef if (paintingDisabled()) return; - SkRect r; - WebCoreRectToSkiaRect(rect, &r); - if (!IsRectReasonable(m_data->canvas()->getTotalMatrix(), r)) { + SkRect r = rect; + if (!IsRectReasonable(getCTM(), r)) { // See fillRect(). ClipRectToCanvas(*m_data->canvas(), r, &r); } - SkPaint paint; SkPath path; - add_corner_arc(&path, r, topRight, 270); add_corner_arc(&path, r, bottomRight, 0); add_corner_arc(&path, r, bottomLeft, 90); add_corner_arc(&path, r, topLeft, 180); + SkPaint paint; m_data->setup_paint_fill(&paint); m_data->canvas()->drawPath(path, paint); return fillRect(rect, color); } -void GraphicsContext::clip(const IntRect& rect) +void GraphicsContext::clip(const FloatRect& rect) { if (paintingDisabled()) return; - SkRect r; - WebCoreRectToSkiaRect(rect, &r); - if (!IsRectReasonable(m_data->canvas()->getTotalMatrix(), r)) + SkRect r(rect); + if (!IsRectReasonable(getCTM(), r)) return; m_data->canvas()->clipRect(r); @@ -900,8 +721,8 @@ void GraphicsContext::clip(const Path& path) if (paintingDisabled()) return; - const SkPath& p = *PathToSkPath(path); - if (!IsPathReasonable(m_data->canvas()->getTotalMatrix(), p)) + const SkPath& p = *path.platformPath(); + if (!IsPathReasonable(getCTM(), p)) return; m_data->canvas()->clipPath(p); @@ -911,16 +732,15 @@ void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness { if (paintingDisabled()) return; - SkPath path; - SkRect r; - WebCoreRectToSkiaRect(rect, &r); - if (!IsRectReasonable(m_data->canvas()->getTotalMatrix(), r)) + + SkRect r(rect); + if (!IsRectReasonable(getCTM(), r)) return; + SkPath path; path.addOval(r, SkPath::kCW_Direction); // only perform the inset if we won't invert r - if (2*thickness < rect.width() && 2*thickness < rect.height()) - { + if (2*thickness < rect.width() && 2*thickness < rect.height()) { r.inset(SkIntToScalar(thickness) ,SkIntToScalar(thickness)); path.addOval(r, SkPath::kCCW_Direction); } @@ -932,9 +752,9 @@ void GraphicsContext::clipOut(const IntRect& rect) { if (paintingDisabled()) return; - SkRect r; - WebCoreRectToSkiaRect(rect, &r); - if (!IsRectReasonable(m_data->canvas()->getTotalMatrix(), r)) + + SkRect r(rect); + if (!IsRectReasonable(getCTM(), r)) return; m_data->canvas()->clipRect(r, SkRegion::kDifference_Op); @@ -944,13 +764,12 @@ void GraphicsContext::clipOutEllipseInRect(const IntRect& rect) { if (paintingDisabled()) return; - SkRect oval; - SkPath path; - WebCoreRectToSkiaRect(rect, &oval); - if (!IsRectReasonable(m_data->canvas()->getTotalMatrix(), oval)) + SkRect oval(rect); + if (!IsRectReasonable(getCTM(), oval)) return; + SkPath path; path.addOval(oval, SkPath::kCCW_Direction); m_data->canvas()->clipPath(path, SkRegion::kDifference_Op); } @@ -960,18 +779,12 @@ void GraphicsContext::clipOut(const Path& p) if (paintingDisabled()) return; - const SkPath& path = *PathToSkPath(p); - if (!IsPathReasonable(m_data->canvas()->getTotalMatrix(), path)) + const SkPath& path = *p.platformPath(); + if (!IsPathReasonable(getCTM(), path)) return; - m_data->canvas()->clipPath(path, SkRegion::kDifference_Op); -} -#if SVG_SUPPORT -KRenderingDeviceContext* GraphicsContext::createRenderingDeviceContext() -{ - return new KRenderingDeviceContextQuartz(platformContext()); + m_data->canvas()->clipPath(path, SkRegion::kDifference_Op); } -#endif void GraphicsContext::beginTransparencyLayer(float opacity) { @@ -1001,13 +814,17 @@ void GraphicsContext::endTransparencyLayer() m_data->canvas()->restore(); } -void GraphicsContext::setShadow(const IntSize& size, int blur, const Color& color) +void GraphicsContext::setPlatformStrokeStyle(const StrokeStyle& stroke) +{ + m_data->setStrokeStyle(StrokeStyle2StrokeStyle(stroke)); +} + +void GraphicsContext::setPlatformShadow(const IntSize& size, int blur, const Color& color) { if (paintingDisabled()) return; - if (blur > 0) - { + if (blur > 0) { SkColor c; if (color.isValid()) @@ -1020,16 +837,12 @@ void GraphicsContext::setShadow(const IntSize& size, int blur, const Color& colo SkIntToScalar(size.height()), c); m_data->setDrawLooper(dl)->unref(); - } - else + } else m_data->setDrawLooper(NULL); } -void GraphicsContext::clearShadow() +void GraphicsContext::clearPlatformShadow() { - if (paintingDisabled()) - return; - m_data->setDrawLooper(NULL); } @@ -1044,10 +857,8 @@ void GraphicsContext::drawFocusRing(const Color& color) SkRegion exterior_region; const SkScalar exterior_offset = WebCoreFloatToSkScalar(0.5); - for (unsigned i = 0; i < rectCount; i++) - { - SkIRect r; - WebCoreRectToSkiaRect(rects[i], &r); + for (unsigned i = 0; i < rectCount; i++) { + SkIRect r = rects[i]; r.inset(-exterior_offset, -exterior_offset); exterior_region.op(r, SkRegion::kUnion_Op); } @@ -1090,31 +901,13 @@ void GraphicsContext::clearRect(const FloatRect& rect) if (paintingDisabled()) return; - SkPaint paint; - SkRect r; - WebCoreRectToSkiaRect(rect, &r); - if (!IsRectReasonable(m_data->canvas()->getTotalMatrix(), r)) + SkRect r = rect; + if (!IsRectReasonable(getCTM(), r)) ClipRectToCanvas(*m_data->canvas(), r, &r); - m_data->setup_paint_fill(&paint); - paint.setPorterDuffXfermode(SkPorterDuff::kClear_Mode); - m_data->canvas()->drawRect(r, paint); -} - -void GraphicsContext::strokeRect(const FloatRect& rect, float lineWidth) -{ - if (paintingDisabled()) - return; - SkPaint paint; - SkRect r; - - WebCoreRectToSkiaRect(rect, &r); - if (!IsRectReasonable(m_data->canvas()->getTotalMatrix(), r)) - return; - m_data->setup_paint_fill(&paint); - paint.setStrokeWidth(WebCoreFloatToSkScalar(lineWidth)); + paint.setPorterDuffXfermode(SkPorterDuff::kClear_Mode); m_data->canvas()->drawRect(r, paint); } @@ -1154,21 +947,6 @@ void GraphicsContext::setLineJoin(LineJoin join) } } -void GraphicsContext::setFillRule(WindRule rule) -{ - switch (rule) { - case RULE_NONZERO: - m_data->setFillRule(SkPath::kWinding_FillType); - break; - case RULE_EVENODD: - m_data->setFillRule(SkPath::kEvenOdd_FillType); - break; - default: - SkDEBUGF(("GraphicsContext::setFillRule: unknown WindRule %d\n", rule)); - break; - } -} - void GraphicsContext::scale(const FloatSize& size) { if (paintingDisabled()) @@ -1200,15 +978,16 @@ AffineTransform GraphicsContext::getCTM() const return m_data->canvas()->getTotalMatrix(); } - -HDC GraphicsContext::getWindowsContext(bool supportAlphaBlend, const IntRect*) { +HDC GraphicsContext::getWindowsContext(const IntRect&, bool supportAlphaBlend, bool mayCreateBitmap) +{ if (paintingDisabled()) - return NULL; + return 0; // No need to ever call endPlatformPaint() since it is a noop. return m_data->canvas()->beginPlatformPaint(); } -void GraphicsContext::releaseWindowsContext(HDC hdc, bool supportAlphaBlend, const IntRect*) { +void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect&, bool supportAlphaBlend, bool mayCreateBitmap) +{ // noop, the DC will be lazily freed by the bitmap when no longer needed } @@ -1267,10 +1046,14 @@ void GraphicsContext::setPlatformFillColor(const Color& color) m_data->setFillColor(color.rgb()); } +/* +TODO(brettw): WebKit's implementation of this function moved into the cross- +platform file GraphicsContext.cpp. We need to figure out how to hook this up +properly once everything links. void GraphicsContext::setPlatformStrokeStyle(const StrokeStyle & strokestyle) { m_data->setStrokeStyle(StrokeStyle2StrokeStyle(strokestyle)); -} +}*/ void GraphicsContext::setPlatformStrokeColor(const Color& strokecolor) { @@ -1284,7 +1067,7 @@ void GraphicsContext::setPlatformStrokeThickness(float thickness) void GraphicsContext::addPath(const Path& path) { - m_data->addPath(*PathToSkPath(path)); + m_data->addPath(*path.platformPath()); } void GraphicsContext::beginPath() @@ -1305,9 +1088,36 @@ void GraphicsContext::setShouldDelete(bool should_delete) m_data->setShouldDelete(should_delete); } -PlatformPath* GraphicsContext::currentPath() +// TODO(eseidel): This is needed for image masking and complex text fills +void GraphicsContext::clipToImageBuffer(const FloatRect& rect, const ImageBuffer* imageBuffer) +{ + if (paintingDisabled()) + return; + + notImplemented(); +} + +void GraphicsContext::setImageInterpolationQuality(InterpolationQuality) +{ + notImplemented(); +} + +// Skia platform gradients and patterns are handled at draw time +// Upstream is considering removing these methods anyway +void GraphicsContext::setPlatformStrokePattern(Pattern* pattern) +{ +} + +void GraphicsContext::setPlatformFillPattern(Pattern* pattern) +{ +} + +void GraphicsContext::setPlatformStrokeGradient(Gradient*) +{ +} + +void GraphicsContext::setPlatformFillGradient(Gradient*) { - return m_data->currentPath(); } } diff --git a/webkit/port/platform/graphics/IconWin.cpp b/webkit/port/platform/graphics/IconWin.cpp index b348f45..6c17a53 100644 --- a/webkit/port/platform/graphics/IconWin.cpp +++ b/webkit/port/platform/graphics/IconWin.cpp @@ -31,11 +31,6 @@ namespace WebCore { -Icon::Icon() - : m_hIcon(0) -{ -} - Icon::Icon(HICON icon) : m_hIcon(icon) { @@ -56,9 +51,7 @@ PassRefPtr<Icon> Icon::newIconForFile(const String& filename) if (!SHGetFileInfo(tmpFilename.charactersWithNullTermination(), 0, &sfi, sizeof(sfi), SHGFI_ICON | SHGFI_SHELLICONSIZE | SHGFI_SMALLICON)) return 0; - Icon* icon = new Icon(); - icon->m_hIcon = sfi.hIcon; - return icon; + return adoptRef(new Icon(sfi.hIcon)); } void Icon::paint(GraphicsContext* context, const IntRect& r) @@ -66,9 +59,7 @@ void Icon::paint(GraphicsContext* context, const IntRect& r) if (context->paintingDisabled()) return; - SkIRect rect; - WebCoreRectToSkiaRect(r, &rect); - PlatformContextToPlatformContextSkia(context->platformContext())->paintIcon(m_hIcon, rect); + context->platformContext()->paintIcon(m_hIcon, r); } -} +} // namespace WebCore diff --git a/webkit/port/platform/graphics/ImageBufferSkia.cpp b/webkit/port/platform/graphics/ImageBufferSkia.cpp index dcad45a..e1d9c90 100644 --- a/webkit/port/platform/graphics/ImageBufferSkia.cpp +++ b/webkit/port/platform/graphics/ImageBufferSkia.cpp @@ -30,13 +30,12 @@ #include "config.h" #include "ImageBuffer.h" +#include "BitmapImage.h" #include "GraphicsContext.h" -#include "PlatformContextSkia.h" -#include <cairo.h> - -#include "SkBitmap.h" - +#include "ImageData.h" #include "NotImplemented.h" +#include "PlatformContextSkia.h" +#include "SkiaUtils.h" using namespace std; @@ -44,26 +43,50 @@ namespace WebCore { auto_ptr<ImageBuffer> ImageBuffer::create(const IntSize& size, bool) { - return auto_ptr<ImageBuffer>(new ImageBuffer(size)); + return auto_ptr<ImageBuffer>(new ImageBuffer(size)); +} + +GraphicsContext* ImageBuffer::context() const +{ + return m_context.get(); } -const SkBitmap* ImageBuffer::image() const +Image* ImageBuffer::image() const { - return m_context.get()->platformContext()->bitmap(); + if (!m_image) { + // It's assumed that if image() is called, the actual rendering to + // the GraphicsContext must be done. + ASSERT(context()); + const SkBitmap* bitmap = context()->platformContext()->bitmap(); + m_image = BitmapImage::create(); + // TODO(tc): This is inefficient because we serialize then re-interpret + // the image. If this matters for performance, we should add another + // BitmapImage::create method that takes a SkBitmap (similar to what + // CoreGraphics does). + m_image->setData(SerializeSkBitmap(*bitmap), true); + } + return m_image.get(); } -cairo_surface_t* ImageBuffer::surface() const +PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect&) const { notImplemented(); - return NULL; + return 0; } -GraphicsContext* ImageBuffer::context() const +void ImageBuffer::putImageData(ImageData*, const IntRect&, const IntPoint&) { - return m_context.get(); + notImplemented(); +} + +String ImageBuffer::toDataURL(const String&) const +{ + notImplemented(); + return String(); } ImageBuffer::ImageBuffer(const IntSize& size) : + m_data(0), m_size(size), m_context(GraphicsContext::createOffscreenContext(size.width(), size.height())) { diff --git a/webkit/port/platform/graphics/ImageSkia.cpp b/webkit/port/platform/graphics/ImageSkia.cpp index 359f6c0..1989eba8 100644 --- a/webkit/port/platform/graphics/ImageSkia.cpp +++ b/webkit/port/platform/graphics/ImageSkia.cpp @@ -77,42 +77,6 @@ void TransformDimensions(const SkMatrix& matrix, *dest_height = SkScalarToFloat((dest_points[2] - dest_points[0]).length()); } -// Constructs a BMP V4 bitmap from an SkBitmap. -PassRefPtr<SharedBuffer> SerializeBitmap(const SkBitmap& bitmap) -{ - int width = bitmap.width(); - int height = bitmap.height(); - - // Create a BMP v4 header that we can serialize. - BITMAPV4HEADER v4Header; - gfx::CreateBitmapV4Header(width, height, &v4Header); - v4Header.bV4SizeImage = width * sizeof(uint32_t) * height; - - // Serialize the bitmap. - BITMAPFILEHEADER fileHeader; - fileHeader.bfType = 0x4d42; // "BM" header - fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + v4Header.bV4Size; - fileHeader.bfSize = fileHeader.bfOffBits + v4Header.bV4SizeImage; - fileHeader.bfReserved1 = fileHeader.bfReserved2 = 0; - - // Write BITMAPFILEHEADER - RefPtr<SharedBuffer> buffer(new SharedBuffer( - reinterpret_cast<const char*>(&fileHeader), - sizeof(BITMAPFILEHEADER))); - - // Write BITMAPINFOHEADER - buffer->append(reinterpret_cast<const char*>(&v4Header), - sizeof(BITMAPV4HEADER)); - - // Write the image body. - SkAutoLockPixels bitmap_lock(bitmap); - buffer->append(reinterpret_cast<const char*>(bitmap.getAddr32(0, 0)), - v4Header.bV4SizeImage); - - return buffer; -} - - // Creates an Image for the text area resize corner. We do this by drawing the // theme native control into a memory buffer then converting the memory buffer // into a BMP byte stream, then feeding it into the Image object. We have to @@ -120,9 +84,9 @@ PassRefPtr<SharedBuffer> SerializeBitmap(const SkBitmap& bitmap) // us to directly manipulate the image data. We don't bother caching this // image because the caller holds onto a static copy (see // WebCore/rendering/RenderLayer.cpp). -void GetTextAreaResizeCorner(Image* image) +static PassRefPtr<Image> GetTextAreaResizeCorner() { - ASSERT(image); + RefPtr<Image> image = BitmapImage::create(); // Get the size of the resizer. const int width = PlatformScrollbar::verticalScrollbarWidth(); @@ -139,12 +103,8 @@ void GetTextAreaResizeCorner(Image* image) gfx::NativeTheme::instance()->PaintStatusGripper(hdc, SP_GRIPPER, 0, 0, &widgetRect); device.postProcessGDI(0, 0, width, height); - image->setData(SerializeBitmap(device.accessBitmap(false)), true); -} - -// Convert from what WebKit thinks the type is, to what it is for our port -inline NativeImageSkia* ToSkiaFrame(NativeImagePtr native) { - return reinterpret_cast<NativeImageSkia*>(native); + image->setData(SerializeSkBitmap(device.accessBitmap(false)), true); + return image.release(); } } // namespace @@ -157,91 +117,83 @@ void FrameData::clear() m_hasAlpha = true; } +static inline PassRefPtr<Image> loadImageWithResourceId(int resourceId) +{ + RefPtr<Image> image = BitmapImage::create(); + // Load the desired resource. + std::string data(webkit_glue::GetDataResource(resourceId)); + RefPtr<SharedBuffer> buffer(SharedBuffer::create(data.data(), data.length())); + image->setData(buffer, true); + return image.release(); +} + // static -Image* Image::loadPlatformResource(const char *name) +PassRefPtr<Image> Image::loadPlatformResource(const char *name) { - Image* image = new BitmapImage; - - // Figure out which resource ID the caller wanted. - int resource_id; - if (!strcmp(name, "missingImage")) { - resource_id = IDR_BROKENIMAGE; - } else if (!strcmp(name, "tickmarkDash")) { - resource_id = IDR_TICKMARK_DASH; - } else if (!strcmp(name, "textAreaResizeCorner")) { - GetTextAreaResizeCorner(image); - return image; - } else if (!strcmp(name, "deleteButton") || - !strcmp(name, "deleteButtonPressed")) { + if (!strcmp(name, "missingImage")) + return loadImageWithResourceId(IDR_BROKENIMAGE); + if (!strcmp(name, "tickmarkDash")) + return loadImageWithResourceId(IDR_TICKMARK_DASH); + if (!strcmp(name, "textAreaResizeCorner")) + return GetTextAreaResizeCorner(); + if (!strcmp(name, "deleteButton") || !strcmp(name, "deleteButtonPressed")) { LOG(NotYetImplemented, "Image resource %s does not yet exist\n", name); - return image; - } else { - LOG(NotYetImplemented, "Unknown image resource %s requested\n", name); - return image; + return Image::nullImage(); } - // Load the desired resource. - std::string data(webkit_glue::GetDataResource(resource_id)); - RefPtr<SharedBuffer> buffer(new SharedBuffer(data.data(), data.length())); - image->setData(buffer, true); - return image; + LOG(NotYetImplemented, "Unknown image resource %s requested\n", name); + return Image::nullImage(); } -static bool subsetBitmap(SkBitmap* dst, const SkBitmap& src, const FloatRect& r) +static bool subsetBitmap(SkBitmap* dst, const SkBitmap& src, const FloatRect& clip) { - SkIRect bounds, clip; - bounds.set(0, 0, src.width(), src.height()); - WebCoreRectToSkiaRect(r, &clip); - + FloatRect floatBounds(0, 0, src.width(), src.height()); + if (!floatBounds.intersects(clip)) + return false; + SkAutoLockPixels src_lock(src); - if (bounds.intersect(clip)) - { - void* addr; - switch (src.getConfig()) { - case SkBitmap::kIndex8_Config: - case SkBitmap::kA8_Config: - addr = (void*)src.getAddr8(bounds.fLeft, bounds.fTop); - break; - case SkBitmap::kRGB_565_Config: - addr = (void*)src.getAddr16(bounds.fLeft, bounds.fTop); - break; - case SkBitmap::kARGB_8888_Config: - addr = (void*)src.getAddr32(bounds.fLeft, bounds.fTop); - break; - default: - SkDEBUGF(("subset_bitmap: can't subset this bitmap config %d\n", src.getConfig())); - return false; - } - dst->setConfig(src.getConfig(), bounds.width(), bounds.height(), src.rowBytes()); - dst->setPixels(addr); + IntRect bounds(floatBounds); + void* addr; + switch (src.getConfig()) { + case SkBitmap::kIndex8_Config: + case SkBitmap::kA8_Config: + addr = (void*)src.getAddr8(bounds.x(), bounds.y()); + break; + case SkBitmap::kRGB_565_Config: + addr = (void*)src.getAddr16(bounds.x(), bounds.y()); + break; + case SkBitmap::kARGB_8888_Config: + addr = (void*)src.getAddr32(bounds.x(), bounds.y()); + break; + default: + SkDEBUGF(("subset_bitmap: can't subset this bitmap config %d\n", src.getConfig())); + return false; } + dst->setConfig(src.getConfig(), bounds.width(), bounds.height(), src.rowBytes()); + dst->setPixels(addr); return false; } void Image::drawPattern(GraphicsContext* context, - const FloatRect& srcRect, + const FloatRect& floatSrcRect, const AffineTransform& patternTransform, const FloatPoint& phase, CompositeOperator compositeOp, const FloatRect& destRect) { - if (destRect.isEmpty() || srcRect.isEmpty()) + if (destRect.isEmpty() || floatSrcRect.isEmpty()) return; // nothing to draw - NativeImageSkia* bitmap = ToSkiaFrame(nativeImageForCurrentFrame()); + NativeImageSkia* bitmap = nativeImageForCurrentFrame(); if (!bitmap) return; - PlatformContextSkia* skia = PlatformContextToPlatformContextSkia( - context->platformContext()); - // This is a very inexpensive operation. It will generate a new bitmap but // it will internally reference the old bitmap's pixels, adjusting the row // stride so the extra pixels appear as padding to the subsetted bitmap. - SkIRect srcSkIRect; - WebCoreRectToSkiaRect(srcRect, &srcSkIRect); SkBitmap src_subset; - bitmap->extractSubset(&src_subset, srcSkIRect); + SkIRect srcRect = enclosingIntRect(floatSrcRect); + bitmap->extractSubset(&src_subset, srcRect); SkBitmap resampled; SkShader* shader; @@ -255,9 +207,9 @@ void Image::drawPattern(GraphicsContext* context, // Compute the resampling mode. PlatformContextSkia::ResamplingMode resampling; - if (context->platformContext()->IsPrinting()) { + if (context->platformContext()->IsPrinting()) resampling = PlatformContextSkia::RESAMPLE_LINEAR; - } else { + else { resampling = PlatformContextSkia::computeResamplingMode( *bitmap, srcRect.width(), srcRect.height(), @@ -299,9 +251,7 @@ void Image::drawPattern(GraphicsContext* context, paint.setPorterDuffXfermode(WebCoreCompositeToSkiaComposite(compositeOp)); paint.setFilterBitmap(resampling == PlatformContextSkia::RESAMPLE_LINEAR); - SkRect dstR; - WebCoreRectToSkiaRect(destRect, &dstR); - skia->paintSkPaint(dstR, paint); + context->platformContext()->paintSkPaint(destRect, paint); } // ================================================ @@ -327,7 +277,7 @@ void BitmapImage::checkForSolidColor() bool BitmapImage::getHBITMAP(HBITMAP bmp) { - NativeImageSkia* bm = getBitmap(); + NativeImageSkia* bm = nativeImageForCurrentFrame(); if (!bm) return false; @@ -347,11 +297,6 @@ bool BitmapImage::getHBITMAPOfSize(HBITMAP bmp, LPSIZE size) return false; } -NativeImageSkia* BitmapImage::getBitmap() -{ - return ToSkiaFrame(nativeImageForCurrentFrame()); -} - void BitmapImage::drawFrameMatchingSourceSize(GraphicsContext*, const FloatRect& dstRect, const IntSize& srcSize, @@ -366,23 +311,17 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dstRect, if (!m_source.initialized()) return; - const NativeImageSkia* bm = getBitmap(); + const NativeImageSkia* bm = nativeImageForCurrentFrame(); if (!bm) return; // It's too early and we don't have an image yet. - SkIRect source_rect; - WebCoreRectToSkiaRect(srcRect, &source_rect); - SkRect dest_rect; - WebCoreRectToSkiaRect(dstRect, &dest_rect); - if (source_rect.isEmpty() || dest_rect.isEmpty()) + if (srcRect.isEmpty() || dstRect.isEmpty()) return; // Nothing to draw. - PlatformContextSkia* skia = PlatformContextToPlatformContextSkia( - ctxt->platformContext()); - skia->paintSkBitmap(*bm, source_rect, dest_rect, - WebCoreCompositeToSkiaComposite(compositeOp)); + ctxt->platformContext()->paintSkBitmap(*bm, enclosingIntRect(srcRect), + enclosingIntRect(dstRect), WebCoreCompositeToSkiaComposite(compositeOp)); startAnimation(); } -} +} // namespace WebCore diff --git a/webkit/port/platform/graphics/ImageSourceSkia.cpp b/webkit/port/platform/graphics/ImageSourceSkia.cpp index 48db176..fda00ab 100644 --- a/webkit/port/platform/graphics/ImageSourceSkia.cpp +++ b/webkit/port/platform/graphics/ImageSourceSkia.cpp @@ -139,6 +139,12 @@ IntSize ImageSource::size() const return m_decoder->size(); } +IntSize ImageSource::frameSizeAtIndex(size_t) const +{ + // TODO(brettw) do we need anything here? + return size(); +} + int ImageSource::repetitionCount() { if (!m_decoder) diff --git a/webkit/port/platform/graphics/IntPointSkia.cpp b/webkit/port/platform/graphics/IntPointSkia.cpp new file mode 100644 index 0000000..21e110e --- /dev/null +++ b/webkit/port/platform/graphics/IntPointSkia.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2008 Google, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "IntPoint.h" +#include "SkPoint.h" + +namespace WebCore { + +IntPoint::IntPoint(const SkIPoint& p) + : m_x(p.fX) + , m_y(p.fY) +{ +} + +IntPoint::operator SkIPoint() const +{ + SkIPoint p = { m_x, m_y }; + return p; +} + +IntPoint::operator SkPoint() const +{ + SkPoint p = { SkIntToScalar(m_x), SkIntToScalar(m_y) }; + return p; +} + +} // namespace WebCore diff --git a/webkit/port/platform/graphics/IntPointWin.cpp b/webkit/port/platform/graphics/IntPointWin.cpp index a6ce0bb..91ffe02 100644 --- a/webkit/port/platform/graphics/IntPointWin.cpp +++ b/webkit/port/platform/graphics/IntPointWin.cpp @@ -53,4 +53,4 @@ IntPoint::operator POINTS() const return p; } -} +} // namespace WebCore diff --git a/webkit/port/platform/graphics/IntRectSkia.cpp b/webkit/port/platform/graphics/IntRectSkia.cpp new file mode 100644 index 0000000..e3186e2 --- /dev/null +++ b/webkit/port/platform/graphics/IntRectSkia.cpp @@ -0,0 +1,54 @@ +/*
+ * Copyright (C) 2008 Google, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "IntRect.h"
+
+#include "SkRect.h"
+
+namespace WebCore {
+
+IntRect::operator SkIRect() const
+{
+ SkIRect rect = { x(), y(), right(), bottom() };
+ return rect;
+}
+
+IntRect::operator SkRect() const
+{
+ SkRect rect;
+ rect.set(SkIntToScalar(x()), SkIntToScalar(y()),
+ SkIntToScalar(right()), SkIntToScalar(bottom()));
+ return rect;
+}
+
+IntRect::IntRect(const SkIRect& r)
+ : m_location(r.fLeft, r.fTop)
+ , m_size(r.width(), r.height())
+{
+}
+
+}
+
diff --git a/webkit/port/platform/graphics/IntRectWin.cpp b/webkit/port/platform/graphics/IntRectWin.cpp index 6228be8..a156039 100644 --- a/webkit/port/platform/graphics/IntRectWin.cpp +++ b/webkit/port/platform/graphics/IntRectWin.cpp @@ -30,7 +30,8 @@ namespace WebCore { IntRect::IntRect(const RECT& r) - : m_location(IntPoint(r.left, r.top)), m_size(IntSize(r.right-r.left, r.bottom-r.top)) + : m_location(IntPoint(r.left, r.top)) + , m_size(IntSize(r.right-r.left, r.bottom-r.top)) { } @@ -40,4 +41,4 @@ IntRect::operator RECT() const return rect; } -} +} // namespace WebCore diff --git a/webkit/port/platform/graphics/IntSizeWin.cpp b/webkit/port/platform/graphics/IntSizeWin.cpp index 8a27cdb..b8156e5 100644 --- a/webkit/port/platform/graphics/IntSizeWin.cpp +++ b/webkit/port/platform/graphics/IntSizeWin.cpp @@ -41,4 +41,4 @@ IntSize::operator SIZE() const return s; } -} +} // namespace WebCore diff --git a/webkit/port/platform/graphics/PathSkia.cpp b/webkit/port/platform/graphics/PathSkia.cpp index b88d11d..d8b5b75 100644 --- a/webkit/port/platform/graphics/PathSkia.cpp +++ b/webkit/port/platform/graphics/PathSkia.cpp @@ -47,7 +47,6 @@ Path::Path() Path::Path(const Path& other) { m_path = new SkPath(*other.m_path); - m_rule = other.m_rule; } Path::~Path() @@ -159,16 +158,12 @@ void Path::addArc(const FloatPoint& p, float r, float sa, float ea, void Path::addRect(const FloatRect& rect) { - SkRect r; - WebCoreRectToSkiaRect(rect, &r); - m_path->addRect(r); + m_path->addRect(rect); } void Path::addEllipse(const FloatRect& rect) { - SkRect r; - WebCoreRectToSkiaRect(rect, &r); - m_path->addOval(r); + m_path->addOval(rect); } void Path::clear() @@ -243,23 +238,23 @@ String Path::debugString() const verb = iter.next(pts); switch (verb) { case SkPath::kMove_Verb: - result += String::format("M%.2f,%.2f", pts[0].fX, pts[0].fY); + result += String::format("M%.2f,%.2f ", pts[0].fX, pts[0].fY); numPoints -= 1; break; case SkPath::kLine_Verb: if (!iter.isCloseLine()) { - result += String::format("L%.2f,%.2f", pts[1].fX, pts[1].fY); + result += String::format("L%.2f,%.2f ", pts[1].fX, pts[1].fY); numPoints -= 1; } break; case SkPath::kQuad_Verb: - result += String::format("Q%.2f,%.2f,%.2f,%.2f", + result += String::format("Q%.2f,%.2f,%.2f,%.2f ", pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY); numPoints -= 2; break; case SkPath::kCubic_Verb: - result += String::format("C%.2f,%.2f,%.2f,%.2f,%.2f,%.2f", + result += String::format("C%.2f,%.2f,%.2f,%.2f,%.2f,%.2f ", pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY, pts[3].fX, pts[3].fY); @@ -278,10 +273,10 @@ String Path::debugString() const if (numPoints) { ASSERT(numPoints==1); m_path->getLastPt(pts); - result += String::format("M%.2f,%.2f", pts[0].fX, pts[0].fY); + result += String::format("M%.2f,%.2f ", pts[0].fX, pts[0].fY); } - return result; + return result.stripWhiteSpace(); } -} +} // namespace WebCore diff --git a/webkit/port/platform/graphics/PatternSkia.cpp b/webkit/port/platform/graphics/PatternSkia.cpp new file mode 100644 index 0000000..d80d3ec --- /dev/null +++ b/webkit/port/platform/graphics/PatternSkia.cpp @@ -0,0 +1,57 @@ +/*
+ * Copyright (C) 2008 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Pattern.h"
+
+#include "AffineTransform.h"
+#include "Image.h"
+#include "NativeImageSkia.h"
+
+#include "SkShader.h"
+
+namespace WebCore {
+
+static inline SkShader::TileMode shaderRule(bool shouldRepeat)
+{
+ // 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;
+}
+
+PlatformPatternPtr Pattern::createPlatformPattern(const AffineTransform& patternTransform) const
+{
+ SkBitmap* bm = m_tileImage->nativeImageForCurrentFrame();
+ SkShader* shader = SkShader::CreateBitmapShader(*bm,
+ shaderRule(m_repeatX),
+ shaderRule(m_repeatY));
+ shader->setLocalMatrix(patternTransform);
+ return shader;
+}
+
+} // namespace WebCore
diff --git a/webkit/port/platform/graphics/PlatformGraphics.h b/webkit/port/platform/graphics/PlatformGraphics.h index b3d83dc..6669dae 100644 --- a/webkit/port/platform/graphics/PlatformGraphics.h +++ b/webkit/port/platform/graphics/PlatformGraphics.h @@ -5,8 +5,8 @@ #ifndef PlatformGraphics_d #define PlatformGraphics_d -typedef class SkShader PlatformGradient; -typedef class SkShader PlatformPattern; +typedef class SkShader* PlatformGradient; +typedef class SkShader* PlatformPattern; #endif diff --git a/webkit/port/platform/graphics/SkGraphicsContext.cpp b/webkit/port/platform/graphics/SkGraphicsContext.cpp index 3a1b3c7..d89dbd0 100644 --- a/webkit/port/platform/graphics/SkGraphicsContext.cpp +++ b/webkit/port/platform/graphics/SkGraphicsContext.cpp @@ -27,6 +27,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#include "config.h" #include "SkGraphicsContext.h" #include <vssym32.h> @@ -35,7 +36,7 @@ #include "base/gfx/native_theme.h" #include "base/gfx/platform_canvas_win.h" #include "base/gfx/skia_utils.h" -#include "GraphicsContextPrivate.h" +#include "GraphicsContextPlatformPrivate.h" #include "NativeImageSkia.h" #include "SkBitmap.h" diff --git a/webkit/port/platform/graphics/SkiaUtils.cpp b/webkit/port/platform/graphics/SkiaUtils.cpp index 27779c7..aa8aef0 100644 --- a/webkit/port/platform/graphics/SkiaUtils.cpp +++ b/webkit/port/platform/graphics/SkiaUtils.cpp @@ -31,15 +31,13 @@ #include "SkiaUtils.h" +#include "SharedBuffer.h" #include "SkCanvas.h" #include "SkColorPriv.h" #include "SkMatrix.h" #include "SkRegion.h" -void WebCorePointToSkiaPoint(const WebCore::IntPoint& src, SkPoint* dst) -{ - dst->set(SkIntToScalar(src.x()), SkIntToScalar(src.y())); -} +#include "base/gfx/bitmap_header.h" void WebCorePointToSkiaPoint(const WebCore::FloatPoint& src, SkPoint* dst) { @@ -112,15 +110,6 @@ SkPorterDuff::Mode WebCoreCompositeToSkiaComposite(WebCore::CompositeOperator op return SkPorterDuff::kSrcOver_Mode; // fall-back } -SkShader::TileMode WebCoreTileToSkiaTile(WebCore::Image::TileRule rule) -{ - // StretchTile, RoundTile, RepeatTile - // hack!!!! what does stretch and round mean??? - - return SkShader::kRepeat_TileMode; -} - - static U8CPU InvScaleByte(U8CPU component, uint32_t scale) { SkASSERT(component == (uint8_t)component); @@ -144,9 +133,7 @@ static SkColor SkPMColorToColor(SkPMColor pm) WebCore::Color SkPMColorToWebCoreColor(SkPMColor pm) { - SkColor c = SkPMColorToColor(pm); - - return WebCore::Color(SkColorGetR(c), SkColorGetG(c), SkColorGetB(c), SkColorGetA(c)); + return SkPMColorToColor(pm); } void IntersectRectAndRegion(const SkRegion& region, const SkRect& src_rect, @@ -239,3 +226,37 @@ bool SkPathContainsPoint(SkPath* orig_path, WebCore::FloatPoint point, SkPath::F orig_path->setFillType(orig_ft); // restore return contains; } + +PassRefPtr<WebCore::SharedBuffer> SerializeSkBitmap(const SkBitmap& bitmap) +{ + int width = bitmap.width(); + int height = bitmap.height(); + + // Create a BMP v4 header that we can serialize. + BITMAPV4HEADER v4Header; + gfx::CreateBitmapV4Header(width, height, &v4Header); + v4Header.bV4SizeImage = width * sizeof(uint32_t) * height; + + // Serialize the bitmap. + BITMAPFILEHEADER fileHeader; + fileHeader.bfType = 0x4d42; // "BM" header + fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + v4Header.bV4Size; + fileHeader.bfSize = fileHeader.bfOffBits + v4Header.bV4SizeImage; + fileHeader.bfReserved1 = fileHeader.bfReserved2 = 0; + + // Write BITMAPFILEHEADER + RefPtr<WebCore::SharedBuffer> buffer(WebCore::SharedBuffer::create( + reinterpret_cast<const char*>(&fileHeader), + sizeof(BITMAPFILEHEADER))); + + // Write BITMAPINFOHEADER + buffer->append(reinterpret_cast<const char*>(&v4Header), + sizeof(BITMAPV4HEADER)); + + // Write the image body. + SkAutoLockPixels bitmap_lock(bitmap); + buffer->append(reinterpret_cast<const char*>(bitmap.getAddr32(0, 0)), + v4Header.bV4SizeImage); + + return buffer; +} diff --git a/webkit/port/platform/graphics/SkiaUtils.h b/webkit/port/platform/graphics/SkiaUtils.h index 28d43be..617b8c8 100644 --- a/webkit/port/platform/graphics/SkiaUtils.h +++ b/webkit/port/platform/graphics/SkiaUtils.h @@ -7,46 +7,23 @@ #ifndef SkiaUtils_h #define SkiaUtils_h +#include <wtf/PassRefPtr.h> #include "base/float_util.h" #include "GraphicsContext.h" #include "SkPath.h" #include "SkShader.h" #include "PlatformContextSkia.h" +class WebCore::SharedBuffer; class SkRegion; -// Converts the given WebCore point to a Skia point. -void WebCorePointToSkiaPoint(const WebCore::IntPoint& src, SkPoint* dst); -void WebCorePointToSkiaPoint(const WebCore::FloatPoint& src, SkPoint* dst); - -// Converts from various types of WebCore rectangles to the corresponding -// Skia rectangle types. -void WebCoreRectToSkiaRect(const WebCore::IntRect& src, SkRect* dst); -void WebCoreRectToSkiaRect(const WebCore::FloatRect& src, SkRect* dst); -void WebCoreRectToSkiaRect(const WebCore::IntRect& src, SkIRect* dst); -void WebCoreRectToSkiaRect(const WebCore::FloatRect& src, SkIRect* dst); - -// Converts a WebCore |Path| to an SkPath. -inline SkPath* PathToSkPath(const WebCore::Path& path) { - return reinterpret_cast<SkPath*>(path.platformPath()); -} - // Converts a WebCore composit operation (WebCore::Composite*) to the // corresponding Skia type. SkPorterDuff::Mode WebCoreCompositeToSkiaComposite(WebCore::CompositeOperator); -// Converts a WebCore tiling rule to the corresponding Skia tiling mode. -SkShader::TileMode WebCoreTileToSkiaTile(WebCore::Image::TileRule); - // Converts Android colors to WebKit ones. WebCore::Color SkPMColorToWebCoreColor(SkPMColor pm); -// A platform graphics context is actually a PlatformContextSkia. -inline PlatformContextSkia* PlatformContextToPlatformContextSkia( - PlatformGraphicsContext* context) { - return reinterpret_cast<PlatformContextSkia*>(context); -} - // Skia has problems when passed infinite, etc floats, filter them to 0. inline SkScalar WebCoreFloatToSkScalar(const float& f) { return SkFloatToScalar(base::IsFinite(f) ? f : 0); @@ -74,5 +51,7 @@ void ClipRectToCanvas(const SkCanvas& canvas, const SkRect& src_rect, // Determine if a given WebKit point is contained in a path bool SkPathContainsPoint(SkPath* orig_path, WebCore::FloatPoint point, SkPath::FillType ft); -#endif // SkiaUtils_h +// Constructs a BMP V4 bitmap from an SkBitmap. +PassRefPtr<WebCore::SharedBuffer> SerializeSkBitmap(const SkBitmap&); +#endif // SkiaUtils_h diff --git a/webkit/port/platform/graphics/svg/SVGPaintServerGradientSkia.cpp b/webkit/port/platform/graphics/svg/SVGPaintServerGradientSkia.cpp index 84c445b..76b2370 100644 --- a/webkit/port/platform/graphics/svg/SVGPaintServerGradientSkia.cpp +++ b/webkit/port/platform/graphics/svg/SVGPaintServerGradientSkia.cpp @@ -35,6 +35,7 @@ #include "SVGPaintServerRadialGradient.h" #include "GraphicsContext.h" +#include "Path.h" #include "RenderObject.h" #include "RenderPath.h" #include "RenderStyle.h" @@ -156,17 +157,15 @@ bool SVGPaintServerGradient::setup(GraphicsContext*& context, SkMatrix matrix; // Calculate a matrix to transform a gradient to fit the bounding box - if(boundingBoxMode()) { + if (boundingBoxMode()) { matrix.reset(); - SkRect rc; - context->currentPath()->computeBounds(&rc, SkPath::kExact_BoundsType); + SkRect rc = context->getBoundingBoxForCurrentPath(true); matrix.preTranslate(rc.fLeft, rc.fTop); matrix.preScale(rc.width(), rc.height()); matrix.preConcat(gradientTransform()); - } else { + } else matrix = gradientTransform(); - } if (this->type() == LinearGradientPaintServer) { const SVGPaintServerLinearGradient* linear = diff --git a/webkit/port/platform/graphics/svg/SVGPaintServerPatternSkia.cpp b/webkit/port/platform/graphics/svg/SVGPaintServerPatternSkia.cpp index f9b97a6..8400633 100644 --- a/webkit/port/platform/graphics/svg/SVGPaintServerPatternSkia.cpp +++ b/webkit/port/platform/graphics/svg/SVGPaintServerPatternSkia.cpp @@ -33,6 +33,7 @@ #include "GraphicsContext.h" #include "ImageBuffer.h" #include "RenderObject.h" +#include "Pattern.h" #include "SVGPatternElement.h" #include "SVGPaintServerPattern.h" #include "SkiaSupport.h" @@ -59,20 +60,19 @@ bool SVGPaintServerPattern::setup(GraphicsContext*& context, const RenderObject* if (!tile()) return false; - SkShader* shader = SkShader::CreateBitmapShader(*tile()->image(), SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode); + AffineTransform transform = patternTransform(); + transform.translate(patternBoundaries().x(), patternBoundaries().y()); - SkMatrix matrix = patternTransform(); - matrix.preTranslate(patternBoundaries().x(), patternBoundaries().y()); - - shader->setLocalMatrix(matrix); - context->platformContext()->setPattern(shader); + RefPtr<Pattern> pattern(Pattern::create(tile()->image(), true, true)); if ((type & ApplyToFillTargetType) && style->svgStyle()->hasFill()) { + context->setFillPattern(pattern); if (isPaintingText) context->setTextDrawingMode(cTextFill); } if ((type & ApplyToStrokeTargetType) && style->svgStyle()->hasStroke()) { + context->setStrokePattern(pattern); applyStrokeStyleToContext(context, style, object); if (isPaintingText) context->setTextDrawingMode(cTextStroke); diff --git a/webkit/port/platform/graphics/svg/SVGPaintServerSkia.cpp b/webkit/port/platform/graphics/svg/SVGPaintServerSkia.cpp index 7684396..4acd0f9 100644 --- a/webkit/port/platform/graphics/svg/SVGPaintServerSkia.cpp +++ b/webkit/port/platform/graphics/svg/SVGPaintServerSkia.cpp @@ -36,9 +36,6 @@ #include "RenderPath.h" #include "SkiaUtils.h" -#include "SkDashPathEffect.h" - -#include "NotImplemented.h" namespace WebCore { @@ -53,22 +50,17 @@ void SVGPaintServer::draw(GraphicsContext*& context, const RenderObject* object, void SVGPaintServer::teardown(GraphicsContext*& context, const RenderObject*, SVGPaintTargetType, bool isPaintingText) const { - context->beginPath(); - context->platformContext()->setGradient(NULL); - context->platformContext()->setPattern(NULL); } void SVGPaintServer::renderPath(GraphicsContext*& context, const RenderObject* object, SVGPaintTargetType type) const { RenderStyle* renderStyle = object ? object->style() : NULL; - SkPath* path = context->currentPath(); - if ((type & ApplyToFillTargetType) && (!renderStyle || renderStyle->svgStyle()->hasFill())) - context->fillPath(path, NULL, NULL); + context->fillPath(); if ((type & ApplyToStrokeTargetType) && (!renderStyle || renderStyle->svgStyle()->hasStroke())) - context->strokePath(path, NULL, NULL); + context->strokePath(); } } // namespace WebCore diff --git a/webkit/port/platform/graphics/svg/SkiaSupport.cpp b/webkit/port/platform/graphics/svg/SkiaSupport.cpp index fbc752b..2df8841 100644 --- a/webkit/port/platform/graphics/svg/SkiaSupport.cpp +++ b/webkit/port/platform/graphics/svg/SkiaSupport.cpp @@ -55,12 +55,11 @@ void applyStrokeStyleToContext(GraphicsContext* context, const RenderStyle* styl context->setLineCap(svgStyle->capStyle()); context->setLineJoin(svgStyle->joinStyle()); - if(svgStyle->joinStyle() == MiterJoin) { + if (svgStyle->joinStyle() == MiterJoin) context->setMiterLimit(svgStyle->strokeMiterLimit()); - } - const DashArray& dashes = WebCore::dashArrayFromRenderingStyle(style); - double dashOffset = SVGRenderStyle::cssPrimitiveToLength(object, style->svgStyle()->strokeDashOffset(), 0.0); + const DashArray& dashes = dashArrayFromRenderingStyle(style); + float dashOffset = SVGRenderStyle::cssPrimitiveToLength(object, style->svgStyle()->strokeDashOffset(), 0.0); unsigned int dashLength = !dashes.isEmpty() ? dashes.size() : 0; if(dashLength) { @@ -79,9 +78,8 @@ void applyStrokeStyleToContext(GraphicsContext* context, const RenderStyle* styl GraphicsContext* scratchContext() { static GraphicsContext* scratch = NULL; - if (!scratch) { + if (!scratch) scratch = GraphicsContext::createOffscreenContext(1, 1); - } return scratch; } @@ -90,8 +88,10 @@ FloatRect strokeBoundingBox(const Path& path, RenderStyle* style, const RenderOb GraphicsContext* scratch = scratchContext(); scratch->save(); + scratch->beginPath(); + scratch->addPath(path); applyStrokeStyleToContext(scratch, style, object); - FloatRect bbox = scratch->getPathBoundingBox(path); + FloatRect bbox = scratch->getBoundingBoxForCurrentPath(true); scratch->restore(); return bbox; |