diff options
author | Steve Block <steveblock@google.com> | 2011-05-06 11:45:16 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2011-05-12 13:44:10 +0100 |
commit | cad810f21b803229eb11403f9209855525a25d57 (patch) | |
tree | 29a6fd0279be608e0fe9ffe9841f722f0f4e4269 /WebCore/platform/graphics/skia | |
parent | 121b0cf4517156d0ac5111caf9830c51b69bae8f (diff) | |
download | external_webkit-cad810f21b803229eb11403f9209855525a25d57.zip external_webkit-cad810f21b803229eb11403f9209855525a25d57.tar.gz external_webkit-cad810f21b803229eb11403f9209855525a25d57.tar.bz2 |
Merge WebKit at r75315: Initial merge by git.
Change-Id: I570314b346ce101c935ed22a626b48c2af266b84
Diffstat (limited to 'WebCore/platform/graphics/skia')
26 files changed, 0 insertions, 5859 deletions
diff --git a/WebCore/platform/graphics/skia/BitmapImageSingleFrameSkia.h b/WebCore/platform/graphics/skia/BitmapImageSingleFrameSkia.h deleted file mode 100644 index 553f203..0000000 --- a/WebCore/platform/graphics/skia/BitmapImageSingleFrameSkia.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2006,2007,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: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT - * OWNER 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. - */ - -#ifndef BitmapImageSingleFrameSkia_h -#define BitmapImageSingleFrameSkia_h - -#include "Image.h" -#include "NativeImageSkia.h" - -namespace WebCore { - -// This image class can be used in places which need an Image, but have -// raw pixel data rather than undecoded image data. -// The Image is simpler than a BitmapImage, as it does not have image -// observers, animation, multiple frames, or non-decoded data. -// Therefore trimming the decoded data (destroyDecodedData()) has no effect. -// -// The difficulty with putting this in BitmapImage::create(NativeImagePtr) -// is that NativeImagePtr = NativeImageSkia, yet callers have SkBitmap. -class BitmapImageSingleFrameSkia : public Image { -public: - // Creates a new Image from the given SkBitmap. If "copyPixels" is true, a - // deep copy is done. Otherwise, a shallow copy is done (pixel data is - // ref'ed). - static PassRefPtr<BitmapImageSingleFrameSkia> create(const SkBitmap&, bool copyPixels); - - virtual bool isBitmapImage() const { return true; } - - virtual IntSize size() const - { - return IntSize(m_nativeImage.width(), m_nativeImage.height()); - } - - // Do nothing, as we only have the one representation of data (decoded). - virtual void destroyDecodedData(bool destroyAll = true) { } - - virtual unsigned decodedSize() const - { - return m_nativeImage.decodedSize(); - } - - // We only have a single frame. - virtual NativeImagePtr nativeImageForCurrentFrame() - { - return &m_nativeImage; - } - -protected: - virtual void draw(GraphicsContext*, const FloatRect& dstRect, const FloatRect& srcRect, ColorSpace styleColorSpace, CompositeOperator); - -private: - NativeImageSkia m_nativeImage; - - // Creates a new Image from the given SkBitmap, using a shallow copy. - explicit BitmapImageSingleFrameSkia(const SkBitmap&); -}; - -} // namespace WebCore - -#endif // BitmapImageSingleFrameSkia_h diff --git a/WebCore/platform/graphics/skia/FloatPointSkia.cpp b/WebCore/platform/graphics/skia/FloatPointSkia.cpp deleted file mode 100644 index 054a772..0000000 --- a/WebCore/platform/graphics/skia/FloatPointSkia.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT - * OWNER 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/WebCore/platform/graphics/skia/FloatRectSkia.cpp b/WebCore/platform/graphics/skia/FloatRectSkia.cpp deleted file mode 100644 index a10371f..0000000 --- a/WebCore/platform/graphics/skia/FloatRectSkia.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT - * OWNER 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/WebCore/platform/graphics/skia/FontCustomPlatformData.cpp b/WebCore/platform/graphics/skia/FontCustomPlatformData.cpp deleted file mode 100644 index 161fee9..0000000 --- a/WebCore/platform/graphics/skia/FontCustomPlatformData.cpp +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright (C) 2007 Apple Computer, Inc. - * Copyright (c) 2007, 2008, 2009, Google Inc. All rights reserved. - * Copyright (C) 2010 Company 100, Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT - * OWNER 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 "FontCustomPlatformData.h" - -#if OS(WINDOWS) -#include "Base64.h" -#include "ChromiumBridge.h" -#include "OpenTypeUtilities.h" -#elif OS(LINUX) || OS(FREEBSD) || PLATFORM(BREWMP) -#include "SkStream.h" -#endif - -#include "FontPlatformData.h" -#include "NotImplemented.h" -#include "OpenTypeSanitizer.h" -#include "SharedBuffer.h" - -#if OS(WINDOWS) -#include <objbase.h> -#elif OS(LINUX) || OS(FREEBSD) || PLATFORM(BREWMP) -#include <cstring> -#endif - -namespace WebCore { - -FontCustomPlatformData::~FontCustomPlatformData() -{ -#if OS(WINDOWS) - if (m_fontReference) - RemoveFontMemResourceEx(m_fontReference); -#elif OS(LINUX) || OS(FREEBSD) || PLATFORM(BREWMP) - if (m_fontReference) - m_fontReference->unref(); -#endif -} - -FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation orientation, FontRenderingMode mode) -{ -#if OS(WINDOWS) - ASSERT(m_fontReference); - - LOGFONT logFont; - // m_name comes from createUniqueFontName, which, in turn, gets - // it from base64-encoded uuid (128-bit). So, m_name - // can never be longer than LF_FACESIZE (32). - if (m_name.length() + 1 >= LF_FACESIZE) { - ASSERT_NOT_REACHED(); - return FontPlatformData(); - } - memcpy(logFont.lfFaceName, m_name.charactersWithNullTermination(), - sizeof(logFont.lfFaceName[0]) * (1 + m_name.length())); - - // FIXME: almost identical to FillLogFont in FontCacheWin.cpp. - // Need to refactor. - logFont.lfHeight = -size; - logFont.lfWidth = 0; - logFont.lfEscapement = 0; - logFont.lfOrientation = 0; - logFont.lfUnderline = false; - logFont.lfStrikeOut = false; - logFont.lfCharSet = DEFAULT_CHARSET; - logFont.lfOutPrecision = OUT_TT_ONLY_PRECIS; - logFont.lfQuality = ChromiumBridge::layoutTestMode() ? - NONANTIALIASED_QUALITY : - DEFAULT_QUALITY; // Honor user's desktop settings. - logFont.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; - logFont.lfItalic = italic; - logFont.lfWeight = bold ? 700 : 400; - - HFONT hfont = CreateFontIndirect(&logFont); - return FontPlatformData(hfont, size); -#elif OS(LINUX) || OS(FREEBSD) || PLATFORM(BREWMP) - ASSERT(m_fontReference); - return FontPlatformData(m_fontReference, "", size, bold && !m_fontReference->isBold(), italic && !m_fontReference->isItalic(), orientation); -#else - notImplemented(); - return FontPlatformData(); -#endif -} - -#if OS(WINDOWS) -// Creates a unique and unpredictable font name, in order to avoid collisions and to -// not allow access from CSS. -static String createUniqueFontName() -{ - Vector<char> fontUuid(sizeof(GUID)); - CoCreateGuid(reinterpret_cast<GUID*>(fontUuid.data())); - - Vector<char> fontNameVector; - base64Encode(fontUuid, fontNameVector); - ASSERT(fontNameVector.size() < LF_FACESIZE); - return String(fontNameVector.data(), fontNameVector.size()); -} -#endif - -#if OS(LINUX) || OS(FREEBSD) || PLATFORM(BREWMP) -class RemoteFontStream : public SkStream { -public: - explicit RemoteFontStream(PassRefPtr<SharedBuffer> buffer) - : m_buffer(buffer) - , m_offset(0) - { - } - - virtual ~RemoteFontStream() - { - } - - virtual bool rewind() - { - m_offset = 0; - return true; - } - - virtual size_t read(void* buffer, size_t size) - { - if (!buffer && !size) { - // This is request for the length of the stream. - return m_buffer->size(); - } - if (!buffer) { - // This is a request to skip bytes. This operation is not supported. - return 0; - } - // This is a request to read bytes. - if (!m_buffer->data() || !m_buffer->size()) - return 0; - size_t left = m_buffer->size() - m_offset; - size_t toRead = (left > size) ? size : left; - std::memcpy(buffer, m_buffer->data() + m_offset, toRead); - m_offset += toRead; - return toRead; - } - -private: - RefPtr<SharedBuffer> m_buffer; - size_t m_offset; -}; -#endif - -FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer) -{ - ASSERT_ARG(buffer, buffer); - -#if ENABLE(OPENTYPE_SANITIZER) - OpenTypeSanitizer sanitizer(buffer); - RefPtr<SharedBuffer> transcodeBuffer = sanitizer.sanitize(); - if (!transcodeBuffer) - return 0; // validation failed. - buffer = transcodeBuffer.get(); -#endif - -#if OS(WINDOWS) - // Introduce the font to GDI. AddFontMemResourceEx should be used with care, because it will pollute the process's - // font namespace (Windows has no API for creating an HFONT from data without exposing the font to the - // entire process first). - String fontName = createUniqueFontName(); - HANDLE fontReference = renameAndActivateFont(buffer, fontName); - if (!fontReference) - return 0; - return new FontCustomPlatformData(fontReference, fontName); -#elif OS(LINUX) || OS(FREEBSD) || PLATFORM(BREWMP) - RemoteFontStream* stream = new RemoteFontStream(buffer); - SkTypeface* typeface = SkTypeface::CreateFromStream(stream); - if (!typeface) - return 0; - return new FontCustomPlatformData(typeface); -#else - notImplemented(); - return 0; -#endif -} - -bool FontCustomPlatformData::supportsFormat(const String& format) -{ - return equalIgnoringCase(format, "truetype") || equalIgnoringCase(format, "opentype") -#if ENABLE(OPENTYPE_SANITIZER) - || equalIgnoringCase(format, "woff") -#endif - ; -} - -} diff --git a/WebCore/platform/graphics/skia/FontCustomPlatformData.h b/WebCore/platform/graphics/skia/FontCustomPlatformData.h deleted file mode 100644 index e51b6b6..0000000 --- a/WebCore/platform/graphics/skia/FontCustomPlatformData.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2007 Apple Computer, Inc. - * Copyright (c) 2007, 2008, 2009, 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: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT - * OWNER 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. - */ - -#ifndef FontCustomPlatformData_h -#define FontCustomPlatformData_h - -#include "FontOrientation.h" -#include "FontRenderingMode.h" -#include <wtf/Forward.h> -#include <wtf/Noncopyable.h> - -#if OS(WINDOWS) -#include "PlatformString.h" -#include <windows.h> -#elif OS(LINUX) || OS(FREEBSD) || PLATFORM(BREWMP) -#include "SkTypeface.h" -#endif - -namespace WebCore { - -class FontPlatformData; -class SharedBuffer; - -struct FontCustomPlatformData : Noncopyable { -#if OS(WINDOWS) - FontCustomPlatformData(HANDLE fontReference, const String& name) - : m_fontReference(fontReference) - , m_name(name) - {} -#elif OS(LINUX) || OS(FREEBSD) || PLATFORM(BREWMP) - explicit FontCustomPlatformData(SkTypeface* typeface) - : m_fontReference(typeface) - {} -#endif - - ~FontCustomPlatformData(); - - FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, - FontRenderingMode = NormalRenderingMode); - - static bool supportsFormat(const String&); - -#if OS(WINDOWS) - HANDLE m_fontReference; - String m_name; -#elif OS(LINUX) || OS(FREEBSD) || PLATFORM(BREWMP) - SkTypeface* m_fontReference; -#endif -}; - -FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer*); -} - -#endif // FontCustomPlatformData_h diff --git a/WebCore/platform/graphics/skia/GlyphPageTreeNodeSkia.cpp b/WebCore/platform/graphics/skia/GlyphPageTreeNodeSkia.cpp deleted file mode 100644 index 66e6839..0000000 --- a/WebCore/platform/graphics/skia/GlyphPageTreeNodeSkia.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2008, 2009 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: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT - * OWNER 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 "GlyphPageTreeNode.h" - -#include "Font.h" -#include "HarfbuzzSkia.h" -#include "SimpleFontData.h" - -#include "SkTemplates.h" -#include "SkPaint.h" -#include "SkUtils.h" - -namespace WebCore { - -static int substituteWithVerticalGlyphs(const SimpleFontData* fontData, uint16_t* glyphs, unsigned bufferLength) -{ - HB_FaceRec_* hbFace = fontData->platformData().harfbuzzFace(); - if (!hbFace->gsub) { - // if there is no GSUB table, treat it as not covered - return 0Xffff; - } - - HB_Buffer buffer; - hb_buffer_new(&buffer); - for (unsigned i = 0; i < bufferLength; ++i) - hb_buffer_add_glyph(buffer, glyphs[i], 0, i); - - HB_UShort scriptIndex; - HB_UShort featureIndex; - - HB_GSUB_Select_Script(hbFace->gsub, HB_MAKE_TAG('D', 'F', 'L', 'T'), &scriptIndex); - HB_GSUB_Select_Feature(hbFace->gsub, HB_MAKE_TAG('v', 'e', 'r', 't'), scriptIndex, 0xffff, &featureIndex); - HB_GSUB_Add_Feature(hbFace->gsub, featureIndex, 1); - HB_GSUB_Select_Feature(hbFace->gsub, HB_MAKE_TAG('v', 'r', 't', '2'), scriptIndex, 0xffff, &featureIndex); - HB_GSUB_Add_Feature(hbFace->gsub, featureIndex, 1); - - int error = HB_GSUB_Apply_String(hbFace->gsub, buffer); - if (!error) { - for (unsigned i = 0; i < bufferLength; ++i) - glyphs[i] = static_cast<Glyph>(buffer->out_string[i].gindex); - } - return error; -} - -bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned bufferLength, const SimpleFontData* fontData) -{ - if (SkUTF16_IsHighSurrogate(buffer[bufferLength-1])) { - SkDebugf("%s last char is high-surrogate", __FUNCTION__); - return false; - } - - SkPaint paint; - fontData->platformData().setupPaint(&paint); - paint.setTextEncoding(SkPaint::kUTF16_TextEncoding); - - SkAutoSTMalloc <GlyphPage::size, uint16_t> glyphStorage(length); - uint16_t* glyphs = glyphStorage.get(); - // textToGlyphs takes a byte count, not a glyph count so we multiply by two. - unsigned count = paint.textToGlyphs(buffer, bufferLength * 2, glyphs); - if (count != length) { - SkDebugf("%s count != length\n", __FUNCTION__); - return false; - } - - if ((fontData->orientation() == Vertical) && (!fontData->isBrokenIdeographFont())) { - bool lookVariants = false; - for (unsigned i = 0; i < bufferLength; ++i) { - if (!Font::isCJKIdeograph(buffer[i])) { - lookVariants = true; - continue; - } - } - if (lookVariants) - substituteWithVerticalGlyphs(fontData, glyphs, bufferLength); - } - - unsigned allGlyphs = 0; // track if any of the glyphIDs are non-zero - for (unsigned i = 0; i < length; i++) { - setGlyphDataForIndex(offset + i, glyphs[i], glyphs[i] ? fontData : NULL); - allGlyphs |= glyphs[i]; - } - - return allGlyphs != 0; -} - -} // namespace WebCore diff --git a/WebCore/platform/graphics/skia/GradientSkia.cpp b/WebCore/platform/graphics/skia/GradientSkia.cpp deleted file mode 100644 index a636d10..0000000 --- a/WebCore/platform/graphics/skia/GradientSkia.cpp +++ /dev/null @@ -1,196 +0,0 @@ -/* - * 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: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT - * OWNER 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 "SkGradientShader.h" -#include "SkiaUtils.h" - -namespace WebCore { - -void Gradient::platformDestroy() -{ - if (m_gradient) - SkSafeUnref(m_gradient); - 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 totalStopsNeeded(const Gradient::ColorStop* stopData, size_t count) -{ - // N.B.: The tests in this function should kept in sync with the ones in - // fillStops(), or badness happens. - const Gradient::ColorStop* stop = stopData; - size_t countUsed = count; - if (count < 1 || stop->stop > 0.0) - countUsed++; - stop += count - 1; - if (count < 1 || stop->stop < 1.0) - countUsed++; - return countUsed; -} - -// 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 fillStops(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]; - } -} - -static inline bool compareStops(const Gradient::ColorStop& a, const Gradient::ColorStop& b) -{ - return a.stop < b.stop; -} - -SkShader* Gradient::platformGradient() -{ - if (m_gradient) - return m_gradient; - - // FIXME: This and compareStops() are also in Gradient.cpp and - // CSSGradientValue.cpp; probably should refactor in WebKit. - if (!m_stopsSorted) { - if (m_stops.size()) - std::stable_sort(m_stops.begin(), m_stops.end(), compareStops); - m_stopsSorted = true; - } - size_t countUsed = totalStopsNeeded(m_stops.data(), m_stops.size()); - ASSERT(countUsed >= 2); - ASSERT(countUsed >= m_stops.size()); - - // FIXME: Why is all this manual pointer math needed?! - SkAutoMalloc storage(countUsed * (sizeof(SkColor) + sizeof(SkScalar))); - SkColor* colors = (SkColor*)storage.get(); - SkScalar* pos = (SkScalar*)(colors + countUsed); - - fillStops(m_stops.data(), m_stops.size(), pos, colors); - - SkShader::TileMode tile = SkShader::kClamp_TileMode; - switch (m_spreadMethod) { - case SpreadMethodReflect: - tile = SkShader::kMirror_TileMode; - break; - case SpreadMethodRepeat: - tile = SkShader::kRepeat_TileMode; - break; - case SpreadMethodPad: - tile = SkShader::kClamp_TileMode; - break; - } - - if (m_radial) { - // Since the two-point radial gradient is slower than the plain radial, - // only use it if we have to. - if (m_p0 == m_p1 && m_r0 <= 0.0f) { - // The radius we give to Skia must be positive (and non-zero). If - // we're given a zero radius, just ask for a very small radius so - // Skia will still return an object. - SkScalar radius = m_r1 > 0 ? WebCoreFloatToSkScalar(m_r1) : SK_ScalarMin; - m_gradient = SkGradientShader::CreateRadial(m_p1, radius, colors, pos, static_cast<int>(countUsed), tile); - } else { - // The radii we give to Skia must be positive. If we're given a - // negative radius, ask for zero instead. - SkScalar radius0 = m_r0 >= 0.0f ? WebCoreFloatToSkScalar(m_r0) : 0; - SkScalar radius1 = m_r1 >= 0.0f ? WebCoreFloatToSkScalar(m_r1) : 0; - m_gradient = SkGradientShader::CreateTwoPointRadial(m_p0, radius0, m_p1, radius1, colors, pos, static_cast<int>(countUsed), tile); - } - } else { - SkPoint pts[2] = { m_p0, m_p1 }; - m_gradient = SkGradientShader::CreateLinear(pts, colors, pos, - static_cast<int>(countUsed), tile); - } - - ASSERT(m_gradient); - - SkMatrix matrix = m_gradientSpaceTransformation; - m_gradient->setLocalMatrix(matrix); - - return m_gradient; -} - -void Gradient::fill(GraphicsContext* context, const FloatRect& rect) -{ - context->setFillGradient(this); - context->fillRect(rect); -} - -void Gradient::setPlatformGradientSpaceTransform(const AffineTransform& matrix) -{ - if (m_gradient) - m_gradient->setLocalMatrix(m_gradientSpaceTransformation); -} - -} // namespace WebCore diff --git a/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp b/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp deleted file mode 100644 index 8b7ac86..0000000 --- a/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * Copyright (C) 2010 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" - -#if ENABLE(3D_CANVAS) - -#include "GraphicsContext3D.h" - -#include "Image.h" -#include "ImageSource.h" -#include "NativeImageSkia.h" -#include <wtf/OwnPtr.h> -#include <wtf/PassOwnPtr.h> - -#include <algorithm> - -namespace WebCore { - -bool GraphicsContext3D::getImageData(Image* image, - unsigned int format, - unsigned int type, - bool premultiplyAlpha, - bool ignoreGammaAndColorProfile, - Vector<uint8_t>& outputVector) -{ - if (!image) - return false; - OwnPtr<NativeImageSkia> pixels; - NativeImageSkia* skiaImage = 0; - AlphaOp neededAlphaOp = AlphaDoNothing; - if (image->data()) { - ImageSource decoder(ImageSource::AlphaNotPremultiplied, - ignoreGammaAndColorProfile ? ImageSource::GammaAndColorProfileIgnored : ImageSource::GammaAndColorProfileApplied); - decoder.setData(image->data(), true); - if (!decoder.frameCount() || !decoder.frameIsCompleteAtIndex(0)) - return false; - bool hasAlpha = decoder.frameHasAlphaAtIndex(0); - pixels = adoptPtr(decoder.createFrameAtIndex(0)); - if (!pixels.get() || !pixels->isDataComplete() || !pixels->width() || !pixels->height()) - return false; - SkBitmap::Config skiaConfig = pixels->config(); - if (skiaConfig != SkBitmap::kARGB_8888_Config) - return false; - skiaImage = pixels.get(); - if (hasAlpha && premultiplyAlpha) - neededAlphaOp = AlphaDoPremultiply; - } else { - // This is a special case for texImage2D with HTMLCanvasElement input. - skiaImage = image->nativeImageForCurrentFrame(); - if (!premultiplyAlpha) - neededAlphaOp = AlphaDoUnmultiply; - } - if (!skiaImage) - return false; - SkBitmap& skiaImageRef = *skiaImage; - SkAutoLockPixels lock(skiaImageRef); - ASSERT(skiaImage->rowBytes() == skiaImage->width() * 4); - outputVector.resize(skiaImage->rowBytes() * skiaImage->height()); - return packPixels(reinterpret_cast<const uint8_t*>(skiaImage->getPixels()), - SourceFormatBGRA8, skiaImage->width(), skiaImage->height(), 0, - format, type, neededAlphaOp, outputVector.data()); -} - -} // namespace WebCore - -#endif // ENABLE(3D_CANVAS) diff --git a/WebCore/platform/graphics/skia/GraphicsContextPlatformPrivate.h b/WebCore/platform/graphics/skia/GraphicsContextPlatformPrivate.h deleted file mode 100644 index 5e12ad6..0000000 --- a/WebCore/platform/graphics/skia/GraphicsContextPlatformPrivate.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT - * OWNER 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. - */ - -#ifndef GraphicsContextPlatformPrivate_h -#define GraphicsContextPlatformPrivate_h - -#include <wtf/Noncopyable.h> - -class PlatformContextSkia; - -namespace WebCore { - -// This class just holds onto a PlatformContextSkia for GraphicsContext. -class GraphicsContextPlatformPrivate : public Noncopyable { -public: - GraphicsContextPlatformPrivate(PlatformContextSkia* platformContext) - : m_context(platformContext) { } - - PlatformContextSkia* context() { return m_context; } - -private: - // Non-owning pointer to the PlatformContext. - PlatformContextSkia* m_context; -}; - -} // namespace WebCore - -#endif // GraphicsContextPlatformPrivate_h diff --git a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp deleted file mode 100644 index 1b217ee..0000000 --- a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp +++ /dev/null @@ -1,1262 +0,0 @@ -/* - * Copyright (c) 2006, 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: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT - * OWNER 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 "GraphicsContext.h" - -#include "AffineTransform.h" -#include "Color.h" -#include "FloatRect.h" -#include "GLES2Canvas.h" -#include "Gradient.h" -#include "GraphicsContextPlatformPrivate.h" -#include "ImageBuffer.h" -#include "IntRect.h" -#include "NativeImageSkia.h" -#include "NotImplemented.h" -#include "PlatformContextSkia.h" - -#include "SkBitmap.h" -#include "SkBlurDrawLooper.h" -#include "SkCornerPathEffect.h" -#include "SkShader.h" -#include "SkiaUtils.h" -#include "skia/ext/platform_canvas.h" - -#include <math.h> -#include <wtf/Assertions.h> -#include <wtf/MathExtras.h> -#include <wtf/UnusedParam.h> - -using namespace std; - -namespace WebCore { - -namespace { - -inline int fastMod(int value, int max) -{ - int sign = SkExtractSign(value); - - value = SkApplySign(value, sign); - if (value >= max) - value %= max; - return SkApplySign(value, sign); -} - -inline float square(float n) -{ - return n * n; -} - -} // namespace - -// "Seatbelt" functions ------------------------------------------------------ -// -// These functions check certain graphics primitives for being "safe". -// Skia has historically crashed when sent crazy data. These functions do -// additional checking to prevent crashes. -// -// Ideally, all of these would be fixed in the graphics layer and we would not -// have to do any checking. You can uncomment the ENSURE_VALUE_SAFETY_FOR_SKIA -// flag to check the graphics layer. - -// Disabling these checks (20/01/2010), since we think we've fixed all the Skia -// bugs. Leaving the code in for now, so we can revert easily if necessary. -// #define ENSURE_VALUE_SAFETY_FOR_SKIA - -#ifdef ENSURE_VALUE_SAFETY_FOR_SKIA -static bool isCoordinateSkiaSafe(float coord) -{ - // First check for valid floats. -#if defined(_MSC_VER) - if (!_finite(coord)) -#else - if (!finite(coord)) -#endif - return false; - - // Skia uses 16.16 fixed point and 26.6 fixed point in various places. If - // the transformed point exceeds 15 bits, we just declare that it's - // unreasonable to catch both of these cases. - static const int maxPointMagnitude = 32767; - if (coord > maxPointMagnitude || coord < -maxPointMagnitude) - return false; - - return true; -} -#endif - -static bool isPointSkiaSafe(const SkMatrix& transform, const SkPoint& pt) -{ -#ifdef ENSURE_VALUE_SAFETY_FOR_SKIA - // Now check for points that will overflow. We check the *transformed* - // points since this is what will be rasterized. - SkPoint xPt; - transform.mapPoints(&xPt, &pt, 1); - return isCoordinateSkiaSafe(xPt.fX) && isCoordinateSkiaSafe(xPt.fY); -#else - return true; -#endif -} - -static bool isRectSkiaSafe(const SkMatrix& transform, const SkRect& rc) -{ -#ifdef ENSURE_VALUE_SAFETY_FOR_SKIA - SkPoint topleft = {rc.fLeft, rc.fTop}; - SkPoint bottomright = {rc.fRight, rc.fBottom}; - return isPointSkiaSafe(transform, topleft) && isPointSkiaSafe(transform, bottomright); -#else - return true; -#endif -} - -bool isPathSkiaSafe(const SkMatrix& transform, const SkPath& path) -{ -#ifdef ENSURE_VALUE_SAFETY_FOR_SKIA - SkPoint current_points[4]; - SkPath::Iter iter(path, false); - for (SkPath::Verb verb = iter.next(current_points); - verb != SkPath::kDone_Verb; - verb = iter.next(current_points)) { - switch (verb) { - case SkPath::kMove_Verb: - // This move will be duplicated in the next verb, so we can ignore. - break; - case SkPath::kLine_Verb: - // iter.next returns 2 points. - if (!isPointSkiaSafe(transform, current_points[0]) - || !isPointSkiaSafe(transform, current_points[1])) - return false; - break; - case SkPath::kQuad_Verb: - // iter.next returns 3 points. - if (!isPointSkiaSafe(transform, current_points[0]) - || !isPointSkiaSafe(transform, current_points[1]) - || !isPointSkiaSafe(transform, current_points[2])) - return false; - break; - case SkPath::kCubic_Verb: - // iter.next returns 4 points. - if (!isPointSkiaSafe(transform, current_points[0]) - || !isPointSkiaSafe(transform, current_points[1]) - || !isPointSkiaSafe(transform, current_points[2]) - || !isPointSkiaSafe(transform, current_points[3])) - return false; - break; - case SkPath::kClose_Verb: - case SkPath::kDone_Verb: - default: - break; - } - } - return true; -#else - return true; -#endif -} - -// Local helper functions ------------------------------------------------------ - -void addCornerArc(SkPath* path, const SkRect& rect, const IntSize& size, int startAngle) -{ - SkIRect ir; - int rx = SkMin32(SkScalarRound(rect.width()), size.width()); - int ry = SkMin32(SkScalarRound(rect.height()), size.height()); - - ir.set(-rx, -ry, rx, ry); - switch (startAngle) { - case 0: - ir.offset(rect.fRight - ir.fRight, rect.fBottom - ir.fBottom); - break; - case 90: - ir.offset(rect.fLeft - ir.fLeft, rect.fBottom - ir.fBottom); - break; - case 180: - ir.offset(rect.fLeft - ir.fLeft, rect.fTop - ir.fTop); - break; - case 270: - ir.offset(rect.fRight - ir.fRight, rect.fTop - ir.fTop); - break; - default: - ASSERT(0); - } - - SkRect r; - r.set(ir); - path->arcTo(r, SkIntToScalar(startAngle), SkIntToScalar(90), false); -} - -// ----------------------------------------------------------------------------- - -// This may be called with a NULL pointer to create a graphics context that has -// no painting. -void GraphicsContext::platformInit(PlatformGraphicsContext* gc) -{ - m_data = new GraphicsContextPlatformPrivate(gc); - setPaintingDisabled(!gc || !platformContext()->canvas()); -} - -void GraphicsContext::platformDestroy() -{ - delete m_data; -} - -PlatformGraphicsContext* GraphicsContext::platformContext() const -{ - ASSERT(!paintingDisabled()); - return m_data->context(); -} - -// State saving ---------------------------------------------------------------- - -void GraphicsContext::savePlatformState() -{ - if (paintingDisabled()) - return; - - if (platformContext()->useGPU()) - platformContext()->gpuCanvas()->save(); - - // Save our private State. - platformContext()->save(); -} - -void GraphicsContext::restorePlatformState() -{ - if (paintingDisabled()) - return; - - if (platformContext()->useGPU()) - platformContext()->gpuCanvas()->restore(); - - // Restore our private State. - platformContext()->restore(); -} - -void GraphicsContext::beginTransparencyLayer(float opacity) -{ - if (paintingDisabled()) - return; - - // We need the "alpha" layer flag here because the base layer is opaque - // (the surface of the page) but layers on top may have transparent parts. - // Without explicitly setting the alpha flag, the layer will inherit the - // opaque setting of the base and some things won't work properly. - platformContext()->canvas()->saveLayerAlpha( - 0, - static_cast<unsigned char>(opacity * 255), - static_cast<SkCanvas::SaveFlags>(SkCanvas::kHasAlphaLayer_SaveFlag | - SkCanvas::kFullColorLayer_SaveFlag)); -} - -void GraphicsContext::endTransparencyLayer() -{ - if (paintingDisabled()) - return; - platformContext()->canvas()->restore(); -} - -// Graphics primitives --------------------------------------------------------- - -void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness) -{ - if (paintingDisabled()) - return; - - SkRect r(rect); - if (!isRectSkiaSafe(getCTM(), r)) - return; - - platformContext()->prepareForSoftwareDraw(); - 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()) { - // Adding one to the thickness doesn't make the border too thick as - // it's painted over afterwards. But without this adjustment the - // border appears a little anemic after anti-aliasing. - r.inset(SkIntToScalar(thickness + 1), SkIntToScalar(thickness + 1)); - path.addOval(r, SkPath::kCCW_Direction); - } - platformContext()->clipPathAntiAliased(path); -} - -void GraphicsContext::addPath(const Path& path) -{ - if (paintingDisabled()) - return; - platformContext()->addPath(*path.platformPath()); -} - -void GraphicsContext::beginPath() -{ - if (paintingDisabled()) - return; - platformContext()->beginPath(); -} - -void GraphicsContext::clearPlatformShadow() -{ - if (paintingDisabled()) - return; - platformContext()->setDrawLooper(0); -} - -void GraphicsContext::clearRect(const FloatRect& rect) -{ - if (paintingDisabled()) - return; - - if (platformContext()->useGPU() && !platformContext()->canvasClipApplied()) { - platformContext()->prepareForHardwareDraw(); - platformContext()->gpuCanvas()->clearRect(rect); - return; - } - - // Force a readback here (if we're using the GPU), since clearRect() is - // incompatible with mixed-mode rendering. - platformContext()->syncSoftwareCanvas(); - - SkRect r = rect; - if (!isRectSkiaSafe(getCTM(), r)) - ClipRectToCanvas(*platformContext()->canvas(), r, &r); - - SkPaint paint; - platformContext()->setupPaintForFilling(&paint); - paint.setXfermodeMode(SkXfermode::kClear_Mode); - platformContext()->canvas()->drawRect(r, paint); -} - -void GraphicsContext::clip(const FloatRect& rect) -{ - if (paintingDisabled()) - return; - - SkRect r(rect); - if (!isRectSkiaSafe(getCTM(), r)) - return; - - platformContext()->prepareForSoftwareDraw(); - platformContext()->canvas()->clipRect(r); -} - -void GraphicsContext::clip(const Path& path) -{ - if (paintingDisabled()) - return; - - const SkPath& p = *path.platformPath(); - if (!isPathSkiaSafe(getCTM(), p)) - return; - - platformContext()->prepareForSoftwareDraw(); - platformContext()->clipPathAntiAliased(p); -} - -void GraphicsContext::canvasClip(const Path& path) -{ - if (paintingDisabled()) - return; - - const SkPath& p = *path.platformPath(); - if (!isPathSkiaSafe(getCTM(), p)) - return; - - platformContext()->canvasClipPath(p); -} - -void GraphicsContext::clipOut(const IntRect& rect) -{ - if (paintingDisabled()) - return; - - SkRect r(rect); - if (!isRectSkiaSafe(getCTM(), r)) - return; - - platformContext()->canvas()->clipRect(r, SkRegion::kDifference_Op); -} - -void GraphicsContext::clipOut(const Path& p) -{ - if (paintingDisabled()) - return; - - const SkPath& path = *p.platformPath(); - if (!isPathSkiaSafe(getCTM(), path)) - return; - - platformContext()->canvas()->clipPath(path, SkRegion::kDifference_Op); -} - -void GraphicsContext::clipPath(const Path& pathToClip, WindRule clipRule) -{ - if (paintingDisabled()) - return; - - // FIXME: Be smarter about this. - beginPath(); - addPath(pathToClip); - - SkPath path = platformContext()->currentPathInLocalCoordinates(); - if (!isPathSkiaSafe(getCTM(), path)) - return; - - path.setFillType(clipRule == RULE_EVENODD ? SkPath::kEvenOdd_FillType : SkPath::kWinding_FillType); - platformContext()->clipPathAntiAliased(path); -} - -void GraphicsContext::concatCTM(const AffineTransform& affine) -{ - if (paintingDisabled()) - return; - - if (platformContext()->useGPU()) - platformContext()->gpuCanvas()->concatCTM(affine); - - platformContext()->canvas()->concat(affine); -} - -void GraphicsContext::drawConvexPolygon(size_t numPoints, - const FloatPoint* points, - bool shouldAntialias) -{ - if (paintingDisabled()) - return; - - if (numPoints <= 1) - return; - - platformContext()->prepareForSoftwareDraw(); - - SkPath path; - - path.incReserve(numPoints); - path.moveTo(WebCoreFloatToSkScalar(points[0].x()), - WebCoreFloatToSkScalar(points[0].y())); - for (size_t i = 1; i < numPoints; i++) { - path.lineTo(WebCoreFloatToSkScalar(points[i].x()), - WebCoreFloatToSkScalar(points[i].y())); - } - - if (!isPathSkiaSafe(getCTM(), path)) - return; - - SkPaint paint; - platformContext()->setupPaintForFilling(&paint); - platformContext()->canvas()->drawPath(path, paint); - - if (strokeStyle() != NoStroke) { - paint.reset(); - platformContext()->setupPaintForStroking(&paint, 0, 0); - platformContext()->canvas()->drawPath(path, paint); - } -} - -void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint* points, bool antialiased) -{ - if (paintingDisabled()) - return; - - if (numPoints <= 1) - return; - - // FIXME: IMPLEMENT!! -} - -// This method is only used to draw the little circles used in lists. -void GraphicsContext::drawEllipse(const IntRect& elipseRect) -{ - if (paintingDisabled()) - return; - - SkRect rect = elipseRect; - if (!isRectSkiaSafe(getCTM(), rect)) - return; - - platformContext()->prepareForSoftwareDraw(); - SkPaint paint; - platformContext()->setupPaintForFilling(&paint); - platformContext()->canvas()->drawOval(rect, paint); - - if (strokeStyle() != NoStroke) { - paint.reset(); - platformContext()->setupPaintForStroking(&paint, &rect, 0); - platformContext()->canvas()->drawOval(rect, paint); - } -} - -void GraphicsContext::drawFocusRing(const Path& path, int width, int offset, const Color& color) -{ - // FIXME: implement -} - -void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int /* width */, int /* offset */, const Color& color) -{ - if (paintingDisabled()) - return; - - unsigned rectCount = rects.size(); - if (!rectCount) - return; - - platformContext()->prepareForSoftwareDraw(); - SkRegion focusRingRegion; - const SkScalar focusRingOutset = WebCoreFloatToSkScalar(0.5); - for (unsigned i = 0; i < rectCount; i++) { - SkIRect r = rects[i]; - r.inset(-focusRingOutset, -focusRingOutset); - focusRingRegion.op(r, SkRegion::kUnion_Op); - } - - SkPath path; - SkPaint paint; - paint.setAntiAlias(true); - paint.setStyle(SkPaint::kStroke_Style); - - paint.setColor(color.rgb()); - paint.setStrokeWidth(focusRingOutset * 2); - paint.setPathEffect(new SkCornerPathEffect(focusRingOutset * 2))->unref(); - focusRingRegion.getBoundaryPath(&path); - platformContext()->canvas()->drawPath(path, paint); -} - -// This is only used to draw borders. -void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2) -{ - if (paintingDisabled()) - return; - - StrokeStyle penStyle = strokeStyle(); - if (penStyle == NoStroke) - return; - - SkPaint paint; - if (!isPointSkiaSafe(getCTM(), point1) || !isPointSkiaSafe(getCTM(), point2)) - return; - - platformContext()->prepareForSoftwareDraw(); - - FloatPoint p1 = point1; - FloatPoint p2 = point2; - bool isVerticalLine = (p1.x() == p2.x()); - int width = roundf(strokeThickness()); - - // 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. - FloatSize disp = p2 - p1; - int length = SkScalarRound(disp.width() + disp.height()); - platformContext()->setupPaintForStroking(&paint, 0, length); - - if (strokeStyle() == DottedStroke || strokeStyle() == DashedStroke) { - // Do a rect fill of our endpoints. This ensures we always have the - // appearance of being a border. We then draw the actual dotted/dashed line. - - SkRect r1, r2; - r1.set(p1.x(), p1.y(), p1.x() + width, p1.y() + width); - r2.set(p2.x(), p2.y(), p2.x() + width, p2.y() + width); - - if (isVerticalLine) { - r1.offset(-width / 2, 0); - r2.offset(-width / 2, -width); - } else { - r1.offset(0, -width / 2); - r2.offset(-width, -width / 2); - } - SkPaint fillPaint; - fillPaint.setColor(paint.getColor()); - platformContext()->canvas()->drawRect(r1, fillPaint); - platformContext()->canvas()->drawRect(r2, fillPaint); - } - - adjustLineToPixelBoundaries(p1, p2, width, penStyle); - SkPoint pts[2] = { (SkPoint)p1, (SkPoint)p2 }; - - platformContext()->canvas()->drawPoints(SkCanvas::kLines_PointMode, 2, pts, paint); -} - -void GraphicsContext::drawLineForTextChecking(const IntPoint& pt, int width, TextCheckingLineStyle style) -{ - if (paintingDisabled()) - return; - - platformContext()->prepareForSoftwareDraw(); - - // Create the pattern we'll use to draw the underline. - static SkBitmap* misspellBitmap = 0; - if (!misspellBitmap) { - // We use a 2-pixel-high misspelling indicator because that seems to be - // what WebKit is designed for, and how much room there is in a typical - // page for it. - const int rowPixels = 32; // Must be multiple of 4 for pattern below. - const int colPixels = 2; - misspellBitmap = new SkBitmap; - misspellBitmap->setConfig(SkBitmap::kARGB_8888_Config, - rowPixels, colPixels); - misspellBitmap->allocPixels(); - - misspellBitmap->eraseARGB(0, 0, 0, 0); - const uint32_t lineColor = 0xFFFF0000; // Opaque red. - const uint32_t antiColor = 0x60600000; // Semitransparent red. - - // Pattern: X o o X o o X - // o X o o X o - uint32_t* row1 = misspellBitmap->getAddr32(0, 0); - uint32_t* row2 = misspellBitmap->getAddr32(0, 1); - for (int x = 0; x < rowPixels; x++) { - switch (x % 4) { - case 0: - row1[x] = lineColor; - break; - case 1: - row1[x] = antiColor; - row2[x] = antiColor; - break; - case 2: - row2[x] = lineColor; - break; - case 3: - row1[x] = antiColor; - row2[x] = antiColor; - break; - } - } - } - - // Offset it vertically by 1 so that there's some space under the text. - SkScalar originX = SkIntToScalar(pt.x()); - SkScalar originY = SkIntToScalar(pt.y()) + 1; - - // Make a shader for the bitmap with an origin of the box we'll draw. This - // shader is refcounted and will have an initial refcount of 1. - SkShader* shader = SkShader::CreateBitmapShader( - *misspellBitmap, SkShader::kRepeat_TileMode, - SkShader::kRepeat_TileMode); - SkMatrix matrix; - matrix.reset(); - matrix.postTranslate(originX, originY); - shader->setLocalMatrix(matrix); - - // Assign the shader to the paint & release our reference. The paint will - // now own the shader and the shader will be destroyed when the paint goes - // out of scope. - SkPaint paint; - paint.setShader(shader); - shader->unref(); - - SkRect rect; - rect.set(originX, - originY, - originX + SkIntToScalar(width), - originY + SkIntToScalar(misspellBitmap->height())); - platformContext()->canvas()->drawRect(rect, paint); -} - -void GraphicsContext::drawLineForText(const IntPoint& pt, - int width, - bool printing) -{ - if (paintingDisabled()) - return; - - if (width <= 0) - return; - - platformContext()->prepareForSoftwareDraw(); - - int thickness = SkMax32(static_cast<int>(strokeThickness()), 1); - SkRect r; - r.fLeft = SkIntToScalar(pt.x()); - r.fTop = SkIntToScalar(pt.y()); - r.fRight = r.fLeft + SkIntToScalar(width); - r.fBottom = r.fTop + SkIntToScalar(thickness); - - SkPaint paint; - platformContext()->setupPaintForFilling(&paint); - // Text lines are drawn using the stroke color. - paint.setColor(platformContext()->effectiveStrokeColor()); - platformContext()->canvas()->drawRect(r, paint); -} - -// Draws a filled rectangle with a stroked border. -void GraphicsContext::drawRect(const IntRect& rect) -{ - if (paintingDisabled()) - return; - - platformContext()->prepareForSoftwareDraw(); - - SkRect r = rect; - if (!isRectSkiaSafe(getCTM(), r)) { - // See the fillRect below. - ClipRectToCanvas(*platformContext()->canvas(), r, &r); - } - - platformContext()->drawRect(r); -} - -void GraphicsContext::fillPath(const Path& pathToFill) -{ - if (paintingDisabled()) - return; - - // FIXME: Be smarter about this. - beginPath(); - addPath(pathToFill); - - SkPath path = platformContext()->currentPathInLocalCoordinates(); - if (!isPathSkiaSafe(getCTM(), path)) - return; - - platformContext()->prepareForSoftwareDraw(); - - const GraphicsContextState& state = m_state; - path.setFillType(state.fillRule == RULE_EVENODD ? - SkPath::kEvenOdd_FillType : SkPath::kWinding_FillType); - - SkPaint paint; - platformContext()->setupPaintForFilling(&paint); - - platformContext()->canvas()->drawPath(path, paint); -} - -void GraphicsContext::fillRect(const FloatRect& rect) -{ - if (paintingDisabled()) - return; - - SkRect r = rect; - if (!isRectSkiaSafe(getCTM(), r)) { - // See the other version of fillRect below. - ClipRectToCanvas(*platformContext()->canvas(), r, &r); - } - - if (platformContext()->useGPU() && platformContext()->canAccelerate()) { - platformContext()->prepareForHardwareDraw(); - platformContext()->gpuCanvas()->fillRect(rect); - return; - } - - platformContext()->save(); - - platformContext()->prepareForSoftwareDraw(); - - SkPaint paint; - platformContext()->setupPaintForFilling(&paint); - platformContext()->canvas()->drawRect(r, paint); - - platformContext()->restore(); -} - -void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorSpace colorSpace) -{ - if (paintingDisabled()) - return; - - if (platformContext()->useGPU() && platformContext()->canAccelerate()) { - platformContext()->prepareForHardwareDraw(); - platformContext()->gpuCanvas()->fillRect(rect, color, colorSpace); - return; - } - - platformContext()->prepareForSoftwareDraw(); - - SkRect r = rect; - if (!isRectSkiaSafe(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 - // should be fixable in Skia (since the output bitmap isn't that - // large), but until that is fixed, we try to handle it ourselves. - // - // We manually clip the rectangle to the current clip rect. This - // will prevent overflow. The rectangle will be transformed to the - // canvas' coordinate space before it is converted to fixed point - // so we are guaranteed not to overflow after doing this. - ClipRectToCanvas(*platformContext()->canvas(), r, &r); - } - - SkPaint paint; - platformContext()->setupPaintCommon(&paint); - paint.setColor(color.rgb()); - platformContext()->canvas()->drawRect(r, paint); -} - -void GraphicsContext::fillRoundedRect(const IntRect& rect, - const IntSize& topLeft, - const IntSize& topRight, - const IntSize& bottomLeft, - const IntSize& bottomRight, - const Color& color, - ColorSpace colorSpace) -{ - if (paintingDisabled()) - return; - - platformContext()->prepareForSoftwareDraw(); - - SkRect r = rect; - if (!isRectSkiaSafe(getCTM(), r)) - // See fillRect(). - ClipRectToCanvas(*platformContext()->canvas(), r, &r); - - if (topLeft.width() + topRight.width() > rect.width() - || bottomLeft.width() + bottomRight.width() > rect.width() - || topLeft.height() + bottomLeft.height() > rect.height() - || topRight.height() + bottomRight.height() > rect.height()) { - // Not all the radii fit, return a rect. This matches the behavior of - // Path::createRoundedRectangle. Without this we attempt to draw a round - // shadow for a square box. - fillRect(rect, color, colorSpace); - return; - } - - SkPath path; - addCornerArc(&path, r, topRight, 270); - addCornerArc(&path, r, bottomRight, 0); - addCornerArc(&path, r, bottomLeft, 90); - addCornerArc(&path, r, topLeft, 180); - - SkPaint paint; - platformContext()->setupPaintForFilling(&paint); - platformContext()->canvas()->drawPath(path, paint); -} - -AffineTransform GraphicsContext::getCTM() const -{ - const SkMatrix& m = platformContext()->canvas()->getTotalMatrix(); - return AffineTransform(SkScalarToDouble(m.getScaleX()), - SkScalarToDouble(m.getSkewY()), - SkScalarToDouble(m.getSkewX()), - SkScalarToDouble(m.getScaleY()), - SkScalarToDouble(m.getTranslateX()), - SkScalarToDouble(m.getTranslateY())); -} - -FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect) -{ - // This logic is copied from GraphicsContextCG, eseidel 5/05/08 - - // It is not enough just to round to pixels in device space. The rotation - // part of the affine transform matrix to device space can mess with this - // conversion if we have a rotating image like the hands of the world clock - // widget. We just need the scale, so we get the affine transform matrix and - // extract the scale. - - const SkMatrix& deviceMatrix = platformContext()->canvas()->getTotalMatrix(); - if (deviceMatrix.isIdentity()) - return rect; - - float deviceScaleX = sqrtf(square(deviceMatrix.getScaleX()) - + square(deviceMatrix.getSkewY())); - float deviceScaleY = sqrtf(square(deviceMatrix.getSkewX()) - + square(deviceMatrix.getScaleY())); - - FloatPoint deviceOrigin(rect.x() * deviceScaleX, rect.y() * deviceScaleY); - FloatPoint deviceLowerRight((rect.x() + rect.width()) * deviceScaleX, - (rect.y() + rect.height()) * deviceScaleY); - - deviceOrigin.setX(roundf(deviceOrigin.x())); - deviceOrigin.setY(roundf(deviceOrigin.y())); - deviceLowerRight.setX(roundf(deviceLowerRight.x())); - deviceLowerRight.setY(roundf(deviceLowerRight.y())); - - // Don't let the height or width round to 0 unless either was originally 0 - if (deviceOrigin.y() == deviceLowerRight.y() && rect.height()) - deviceLowerRight.move(0, 1); - if (deviceOrigin.x() == deviceLowerRight.x() && rect.width()) - deviceLowerRight.move(1, 0); - - FloatPoint roundedOrigin(deviceOrigin.x() / deviceScaleX, - deviceOrigin.y() / deviceScaleY); - FloatPoint roundedLowerRight(deviceLowerRight.x() / deviceScaleX, - deviceLowerRight.y() / deviceScaleY); - return FloatRect(roundedOrigin, roundedLowerRight - roundedOrigin); -} - -void GraphicsContext::scale(const FloatSize& size) -{ - if (paintingDisabled()) - return; - - if (platformContext()->useGPU()) - platformContext()->gpuCanvas()->scale(size); - - platformContext()->canvas()->scale(WebCoreFloatToSkScalar(size.width()), - WebCoreFloatToSkScalar(size.height())); -} - -void GraphicsContext::setAlpha(float alpha) -{ - if (paintingDisabled()) - return; - - if (platformContext()->useGPU()) - platformContext()->gpuCanvas()->setAlpha(alpha); - - platformContext()->setAlpha(alpha); -} - -void GraphicsContext::setPlatformCompositeOperation(CompositeOperator op) -{ - if (paintingDisabled()) - return; - - if (platformContext()->useGPU()) - platformContext()->gpuCanvas()->setCompositeOperation(op); - - platformContext()->setXfermodeMode(WebCoreCompositeToSkiaComposite(op)); -} - -InterpolationQuality GraphicsContext::imageInterpolationQuality() const -{ - return platformContext()->interpolationQuality(); -} - -void GraphicsContext::setImageInterpolationQuality(InterpolationQuality q) -{ - platformContext()->setInterpolationQuality(q); -} - -void GraphicsContext::setLineCap(LineCap cap) -{ - if (paintingDisabled()) - return; - switch (cap) { - case ButtCap: - platformContext()->setLineCap(SkPaint::kButt_Cap); - break; - case RoundCap: - platformContext()->setLineCap(SkPaint::kRound_Cap); - break; - case SquareCap: - platformContext()->setLineCap(SkPaint::kSquare_Cap); - break; - default: - ASSERT(0); - break; - } -} - -void GraphicsContext::setLineDash(const DashArray& dashes, float dashOffset) -{ - if (paintingDisabled()) - return; - - // FIXME: This is lifted directly off SkiaSupport, lines 49-74 - // so it is not guaranteed to work correctly. - size_t dashLength = dashes.size(); - if (!dashLength) { - // If no dash is set, revert to solid stroke - // FIXME: do we need to set NoStroke in some cases? - platformContext()->setStrokeStyle(SolidStroke); - platformContext()->setDashPathEffect(0); - return; - } - - size_t count = !(dashLength % 2) ? dashLength : dashLength * 2; - SkScalar* intervals = new SkScalar[count]; - - for (unsigned int i = 0; i < count; i++) - intervals[i] = dashes[i % dashLength]; - - platformContext()->setDashPathEffect(new SkDashPathEffect(intervals, count, dashOffset)); - - delete[] intervals; -} - -void GraphicsContext::setLineJoin(LineJoin join) -{ - if (paintingDisabled()) - return; - switch (join) { - case MiterJoin: - platformContext()->setLineJoin(SkPaint::kMiter_Join); - break; - case RoundJoin: - platformContext()->setLineJoin(SkPaint::kRound_Join); - break; - case BevelJoin: - platformContext()->setLineJoin(SkPaint::kBevel_Join); - break; - default: - ASSERT(0); - break; - } -} - -void GraphicsContext::setMiterLimit(float limit) -{ - if (paintingDisabled()) - return; - platformContext()->setMiterLimit(limit); -} - -void GraphicsContext::setPlatformFillColor(const Color& color, ColorSpace colorSpace) -{ - if (paintingDisabled()) - return; - - if (platformContext()->useGPU()) - platformContext()->gpuCanvas()->setFillColor(color, colorSpace); - - platformContext()->setFillColor(color.rgb()); -} - -void GraphicsContext::setPlatformFillGradient(Gradient* gradient) -{ - if (paintingDisabled()) - return; - - platformContext()->setFillShader(gradient->platformGradient()); -} - -void GraphicsContext::setPlatformFillPattern(Pattern* pattern) -{ - if (paintingDisabled()) - return; - - platformContext()->setFillShader(pattern->platformPattern(getCTM())); -} - -void GraphicsContext::setPlatformShadow(const FloatSize& size, - float blurFloat, - const Color& color, - ColorSpace colorSpace) -{ - if (paintingDisabled()) - return; - - // Detect when there's no effective shadow and clear the looper. - if (!size.width() && !size.height() && !blurFloat) { - platformContext()->setDrawLooper(0); - return; - } - - double width = size.width(); - double height = size.height(); - double blur = blurFloat; - - SkBlurDrawLooper::BlurFlags blurFlags = SkBlurDrawLooper::kNone_BlurFlag; - - if (m_state.shadowsIgnoreTransforms) { - // Currently only the GraphicsContext associated with the - // CanvasRenderingContext for HTMLCanvasElement have shadows ignore - // Transforms. So with this flag set, we know this state is associated - // with a CanvasRenderingContext. - blurFlags = SkBlurDrawLooper::kIgnoreTransform_BlurFlag; - - // CG uses natural orientation for Y axis, but the HTML5 canvas spec - // does not. - // So we now flip the height since it was flipped in - // CanvasRenderingContext in order to work with CG. - height = -height; - } - - SkColor c; - if (color.isValid()) - c = color.rgb(); - else - c = SkColorSetARGB(0xFF/3, 0, 0, 0); // "std" apple shadow color. - - // TODO(tc): Should we have a max value for the blur? CG clamps at 1000.0 - // for perf reasons. - SkDrawLooper* dl = new SkBlurDrawLooper(blur / 2, width, height, c, blurFlags); - platformContext()->setDrawLooper(dl); - dl->unref(); -} - -void GraphicsContext::setPlatformStrokeColor(const Color& strokecolor, ColorSpace colorSpace) -{ - if (paintingDisabled()) - return; - - platformContext()->setStrokeColor(strokecolor.rgb()); -} - -void GraphicsContext::setPlatformStrokeStyle(const StrokeStyle& stroke) -{ - if (paintingDisabled()) - return; - - platformContext()->setStrokeStyle(stroke); -} - -void GraphicsContext::setPlatformStrokeThickness(float thickness) -{ - if (paintingDisabled()) - return; - - platformContext()->setStrokeThickness(thickness); -} - -void GraphicsContext::setPlatformStrokeGradient(Gradient* gradient) -{ - if (paintingDisabled()) - return; - - platformContext()->setStrokeShader(gradient->platformGradient()); -} - -void GraphicsContext::setPlatformStrokePattern(Pattern* pattern) -{ - if (paintingDisabled()) - return; - - platformContext()->setStrokeShader(pattern->platformPattern(getCTM())); -} - -void GraphicsContext::setPlatformTextDrawingMode(TextDrawingModeFlags mode) -{ - if (paintingDisabled()) - return; - - platformContext()->setTextDrawingMode(mode); -} - -void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect) -{ -} - -void GraphicsContext::setPlatformShouldAntialias(bool enable) -{ - if (paintingDisabled()) - return; - - platformContext()->setUseAntialiasing(enable); -} - -void GraphicsContext::strokeArc(const IntRect& r, int startAngle, int angleSpan) -{ - if (paintingDisabled()) - return; - - platformContext()->prepareForSoftwareDraw(); - - SkPaint paint; - SkRect oval = r; - if (strokeStyle() == NoStroke) { - // Stroke using the fill color. - // TODO(brettw) is this really correct? It seems unreasonable. - platformContext()->setupPaintForFilling(&paint); - paint.setStyle(SkPaint::kStroke_Style); - paint.setStrokeWidth(WebCoreFloatToSkScalar(strokeThickness())); - } else - platformContext()->setupPaintForStroking(&paint, 0, 0); - - // We do this before converting to scalar, so we don't overflow SkFixed. - startAngle = fastMod(startAngle, 360); - angleSpan = fastMod(angleSpan, 360); - - SkPath path; - path.addArc(oval, SkIntToScalar(-startAngle), SkIntToScalar(-angleSpan)); - if (!isPathSkiaSafe(getCTM(), path)) - return; - platformContext()->canvas()->drawPath(path, paint); -} - -void GraphicsContext::strokePath(const Path& pathToStroke) -{ - if (paintingDisabled()) - return; - - // FIXME: Be smarter about this. - beginPath(); - addPath(pathToStroke); - - SkPath path = platformContext()->currentPathInLocalCoordinates(); - if (!isPathSkiaSafe(getCTM(), path)) - return; - - platformContext()->prepareForSoftwareDraw(); - - SkPaint paint; - platformContext()->setupPaintForStroking(&paint, 0, 0); - platformContext()->canvas()->drawPath(path, paint); -} - -void GraphicsContext::strokeRect(const FloatRect& rect, float lineWidth) -{ - if (paintingDisabled()) - return; - - if (!isRectSkiaSafe(getCTM(), rect)) - return; - - platformContext()->prepareForSoftwareDraw(); - - SkPaint paint; - platformContext()->setupPaintForStroking(&paint, 0, 0); - paint.setStrokeWidth(WebCoreFloatToSkScalar(lineWidth)); - platformContext()->canvas()->drawRect(rect, paint); -} - -void GraphicsContext::rotate(float angleInRadians) -{ - if (paintingDisabled()) - return; - - if (platformContext()->useGPU()) - platformContext()->gpuCanvas()->rotate(angleInRadians); - - platformContext()->canvas()->rotate(WebCoreFloatToSkScalar( - angleInRadians * (180.0f / 3.14159265f))); -} - -void GraphicsContext::translate(float w, float h) -{ - if (paintingDisabled()) - return; - - if (platformContext()->useGPU()) - platformContext()->gpuCanvas()->translate(w, h); - - platformContext()->canvas()->translate(WebCoreFloatToSkScalar(w), - WebCoreFloatToSkScalar(h)); -} - -void GraphicsContext::syncSoftwareCanvas() -{ - platformContext()->syncSoftwareCanvas(); -} - -void GraphicsContext::setSharedGraphicsContext3D(SharedGraphicsContext3D* context, DrawingBuffer* framebuffer, const IntSize& size) -{ - platformContext()->setSharedGraphicsContext3D(context, framebuffer, size); -} - -void GraphicsContext::markDirtyRect(const IntRect& rect) -{ - platformContext()->markDirtyRect(rect); -} - -} // namespace WebCore diff --git a/WebCore/platform/graphics/skia/ImageBufferSkia.cpp b/WebCore/platform/graphics/skia/ImageBufferSkia.cpp deleted file mode 100644 index 468ccda..0000000 --- a/WebCore/platform/graphics/skia/ImageBufferSkia.cpp +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Copyright (c) 2008, Google Inc. All rights reserved. - * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> - * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT - * OWNER 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 "ImageBuffer.h" - -#include "Base64.h" -#include "BitmapImage.h" -#include "BitmapImageSingleFrameSkia.h" -#include "DrawingBuffer.h" -#include "GLES2Canvas.h" -#include "GraphicsContext.h" -#include "ImageData.h" -#include "JPEGImageEncoder.h" -#include "MIMETypeRegistry.h" -#include "PNGImageEncoder.h" -#include "PlatformContextSkia.h" -#include "SkColorPriv.h" -#include "SkiaUtils.h" - -#include <wtf/text/StringConcatenate.h> - -using namespace std; - -namespace WebCore { - -// We pass a technically-uninitialized canvas to the platform context here since -// the canvas initialization completes in ImageBuffer::ImageBuffer. But -// PlatformContext doesn't actually need to use the object, and this makes all -// the ownership easier to manage. -ImageBufferData::ImageBufferData(const IntSize& size) - : m_platformContext(0) // Canvas is set in ImageBuffer constructor. -{ -} - -ImageBuffer::ImageBuffer(const IntSize& size, ColorSpace, RenderingMode, bool& success) - : m_data(size) - , m_size(size) -{ - if (!m_data.m_canvas.initialize(size.width(), size.height(), false)) { - success = false; - return; - } - - m_data.m_platformContext.setCanvas(&m_data.m_canvas); - m_context.set(new GraphicsContext(&m_data.m_platformContext)); - m_context->platformContext()->setDrawingToImageBuffer(true); - - // Make the background transparent. It would be nice if this wasn't - // required, but the canvas is currently filled with the magic transparency - // color. Can we have another way to manage this? - m_data.m_canvas.drawARGB(0, 0, 0, 0, SkXfermode::kClear_Mode); - success = true; -} - -ImageBuffer::~ImageBuffer() -{ -} - -GraphicsContext* ImageBuffer::context() const -{ - return m_context.get(); -} - -bool ImageBuffer::drawsUsingCopy() const -{ - return false; -} - -PassRefPtr<Image> ImageBuffer::copyImage() const -{ - m_context->platformContext()->syncSoftwareCanvas(); - return BitmapImageSingleFrameSkia::create(*m_data.m_platformContext.bitmap(), true); -} - -void ImageBuffer::clip(GraphicsContext* context, const FloatRect& rect) const -{ - context->platformContext()->beginLayerClippedToImage(rect, this); -} - -void ImageBuffer::draw(GraphicsContext* context, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect, - CompositeOperator op, bool useLowQualityScale) -{ - if (m_data.m_platformContext.useGPU() && context->platformContext()->useGPU()) { - if (context->platformContext()->canAccelerate()) { - DrawingBuffer* sourceDrawingBuffer = m_data.m_platformContext.gpuCanvas()->drawingBuffer(); - unsigned sourceTexture = static_cast<unsigned>(sourceDrawingBuffer->platformColorBuffer()); - FloatRect destRectFlipped(destRect); - destRectFlipped.setY(destRect.y() + destRect.height()); - destRectFlipped.setHeight(-destRect.height()); - context->platformContext()->prepareForHardwareDraw(); - context->platformContext()->gpuCanvas()->drawTexturedRect(sourceTexture, m_size, srcRect, destRectFlipped, styleColorSpace, op); - return; - } - m_data.m_platformContext.syncSoftwareCanvas(); - } - - RefPtr<Image> image = BitmapImageSingleFrameSkia::create(*m_data.m_platformContext.bitmap(), context == m_context); - context->drawImage(image.get(), styleColorSpace, destRect, srcRect, op, useLowQualityScale); -} - -void ImageBuffer::drawPattern(GraphicsContext* context, const FloatRect& srcRect, const AffineTransform& patternTransform, - const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect) -{ - RefPtr<Image> image = BitmapImageSingleFrameSkia::create(*m_data.m_platformContext.bitmap(), context == m_context); - image->drawPattern(context, srcRect, patternTransform, phase, styleColorSpace, op, destRect); -} - -void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookUpTable) -{ - const SkBitmap& bitmap = *context()->platformContext()->bitmap(); - if (bitmap.isNull()) - return; - - ASSERT(bitmap.config() == SkBitmap::kARGB_8888_Config); - SkAutoLockPixels bitmapLock(bitmap); - for (int y = 0; y < m_size.height(); ++y) { - uint32_t* srcRow = bitmap.getAddr32(0, y); - for (int x = 0; x < m_size.width(); ++x) { - SkColor color = SkPMColorToColor(srcRow[x]); - srcRow[x] = SkPreMultiplyARGB(SkColorGetA(color), - lookUpTable[SkColorGetR(color)], - lookUpTable[SkColorGetG(color)], - lookUpTable[SkColorGetB(color)]); - } - } -} - -template <Multiply multiplied> -PassRefPtr<ImageData> getImageData(const IntRect& rect, const SkBitmap& bitmap, - const IntSize& size) -{ - RefPtr<ImageData> result = ImageData::create(rect.width(), rect.height()); - - if (bitmap.config() == SkBitmap::kNo_Config) { - // This is an empty SkBitmap that could not be configured. - ASSERT(!size.width() || !size.height()); - return result; - } - - unsigned char* data = result->data()->data()->data(); - - if (rect.x() < 0 || rect.y() < 0 || - (rect.x() + rect.width()) > size.width() || - (rect.y() + rect.height()) > size.height()) - memset(data, 0, result->data()->length()); - - int originX = rect.x(); - int destX = 0; - if (originX < 0) { - destX = -originX; - originX = 0; - } - int endX = rect.x() + rect.width(); - if (endX > size.width()) - endX = size.width(); - int numColumns = endX - originX; - - if (numColumns <= 0) - return result; - - int originY = rect.y(); - int destY = 0; - if (originY < 0) { - destY = -originY; - originY = 0; - } - int endY = rect.y() + rect.height(); - if (endY > size.height()) - endY = size.height(); - int numRows = endY - originY; - - if (numRows <= 0) - return result; - - ASSERT(bitmap.config() == SkBitmap::kARGB_8888_Config); - SkAutoLockPixels bitmapLock(bitmap); - - unsigned destBytesPerRow = 4 * rect.width(); - unsigned char* destRow = data + destY * destBytesPerRow + destX * 4; - - for (int y = 0; y < numRows; ++y) { - uint32_t* srcRow = bitmap.getAddr32(originX, originY + y); - for (int x = 0; x < numColumns; ++x) { - unsigned char* destPixel = &destRow[x * 4]; - if (multiplied == Unmultiplied) { - SkColor color = srcRow[x]; - unsigned a = SkColorGetA(color); - destPixel[0] = a ? SkColorGetR(color) * 255 / a : 0; - destPixel[1] = a ? SkColorGetG(color) * 255 / a : 0; - destPixel[2] = a ? SkColorGetB(color) * 255 / a : 0; - destPixel[3] = a; - } else { - // Input and output are both pre-multiplied, we just need to re-arrange the - // bytes from the bitmap format to RGBA. - destPixel[0] = SkGetPackedR32(srcRow[x]); - destPixel[1] = SkGetPackedG32(srcRow[x]); - destPixel[2] = SkGetPackedB32(srcRow[x]); - destPixel[3] = SkGetPackedA32(srcRow[x]); - } - } - destRow += destBytesPerRow; - } - - return result; -} - -PassRefPtr<ImageData> ImageBuffer::getUnmultipliedImageData(const IntRect& rect) const -{ - context()->platformContext()->syncSoftwareCanvas(); - return getImageData<Unmultiplied>(rect, *context()->platformContext()->bitmap(), m_size); -} - -PassRefPtr<ImageData> ImageBuffer::getPremultipliedImageData(const IntRect& rect) const -{ - context()->platformContext()->syncSoftwareCanvas(); - return getImageData<Premultiplied>(rect, *context()->platformContext()->bitmap(), m_size); -} - -template <Multiply multiplied> -void putImageData(ImageData*& source, const IntRect& sourceRect, const IntPoint& destPoint, - const SkBitmap& bitmap, const IntSize& size) -{ - ASSERT(sourceRect.width() > 0); - ASSERT(sourceRect.height() > 0); - - int originX = sourceRect.x(); - int destX = destPoint.x() + sourceRect.x(); - ASSERT(destX >= 0); - ASSERT(destX < size.width()); - ASSERT(originX >= 0); - ASSERT(originX < sourceRect.right()); - - int endX = destPoint.x() + sourceRect.right(); - ASSERT(endX <= size.width()); - - int numColumns = endX - destX; - - int originY = sourceRect.y(); - int destY = destPoint.y() + sourceRect.y(); - ASSERT(destY >= 0); - ASSERT(destY < size.height()); - ASSERT(originY >= 0); - ASSERT(originY < sourceRect.bottom()); - - int endY = destPoint.y() + sourceRect.bottom(); - ASSERT(endY <= size.height()); - int numRows = endY - destY; - - ASSERT(bitmap.config() == SkBitmap::kARGB_8888_Config); - SkAutoLockPixels bitmapLock(bitmap); - - unsigned srcBytesPerRow = 4 * source->width(); - - const unsigned char* srcRow = source->data()->data()->data() + originY * srcBytesPerRow + originX * 4; - - for (int y = 0; y < numRows; ++y) { - uint32_t* destRow = bitmap.getAddr32(destX, destY + y); - for (int x = 0; x < numColumns; ++x) { - const unsigned char* srcPixel = &srcRow[x * 4]; - if (multiplied == Unmultiplied) { - unsigned char alpha = srcPixel[3]; - unsigned char r = SkMulDiv255Ceiling(srcPixel[0], alpha); - unsigned char g = SkMulDiv255Ceiling(srcPixel[1], alpha); - unsigned char b = SkMulDiv255Ceiling(srcPixel[2], alpha); - destRow[x] = SkPackARGB32(alpha, r, g, b); - } else - destRow[x] = SkPackARGB32(srcPixel[3], srcPixel[0], - srcPixel[1], srcPixel[2]); - } - srcRow += srcBytesPerRow; - } -} - -void ImageBuffer::putUnmultipliedImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint) -{ - context()->platformContext()->prepareForSoftwareDraw(); - putImageData<Unmultiplied>(source, sourceRect, destPoint, *context()->platformContext()->bitmap(), m_size); -} - -void ImageBuffer::putPremultipliedImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint) -{ - putImageData<Premultiplied>(source, sourceRect, destPoint, *context()->platformContext()->bitmap(), m_size); -} - -String ImageBuffer::toDataURL(const String& mimeType, const double* quality) const -{ - ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType)); - - Vector<unsigned char> encodedImage; - if (mimeType == "image/jpeg") { - int compressionQuality = JPEGImageEncoder::DefaultCompressionQuality; - if (quality && *quality >= 0.0 && *quality <= 1.0) - compressionQuality = static_cast<int>(*quality * 100 + 0.5); - if (!JPEGImageEncoder::encode(*context()->platformContext()->bitmap(), compressionQuality, &encodedImage)) - return "data:,"; - } else { - if (!PNGImageEncoder::encode(*context()->platformContext()->bitmap(), &encodedImage)) - return "data:,"; - ASSERT(mimeType == "image/png"); - } - - Vector<char> base64Data; - base64Encode(*reinterpret_cast<Vector<char>*>(&encodedImage), base64Data); - - return makeString("data:", mimeType, ";base64,", base64Data); -} - -} // namespace WebCore diff --git a/WebCore/platform/graphics/skia/ImageSkia.cpp b/WebCore/platform/graphics/skia/ImageSkia.cpp deleted file mode 100644 index c7fa6f4..0000000 --- a/WebCore/platform/graphics/skia/ImageSkia.cpp +++ /dev/null @@ -1,540 +0,0 @@ -/* - * 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: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT - * OWNER 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 "AffineTransform.h" -#include "BitmapImage.h" -#include "BitmapImageSingleFrameSkia.h" -#include "FloatConversion.h" -#include "FloatRect.h" -#include "GLES2Canvas.h" -#include "GraphicsContext.h" -#include "Logging.h" -#include "NativeImageSkia.h" -#include "PlatformContextSkia.h" -#include "PlatformString.h" -#include "SkPixelRef.h" -#include "SkRect.h" -#include "SkShader.h" -#include "SkiaUtils.h" -#include "Texture.h" - -#include "skia/ext/image_operations.h" -#include "skia/ext/platform_canvas.h" - -namespace WebCore { - -// Used by computeResamplingMode to tell how bitmaps should be resampled. -enum ResamplingMode { - // Nearest neighbor resampling. Used when we detect that the page is - // trying to make a pattern by stretching a small bitmap very large. - RESAMPLE_NONE, - - // Default skia resampling. Used for large growing of images where high - // quality resampling doesn't get us very much except a slowdown. - RESAMPLE_LINEAR, - - // High quality resampling. - RESAMPLE_AWESOME, -}; - -static ResamplingMode computeResamplingMode(PlatformContextSkia* platformContext, const NativeImageSkia& bitmap, int srcWidth, int srcHeight, float destWidth, float destHeight) -{ - if (platformContext->hasImageResamplingHint()) { - IntSize srcSize; - FloatSize dstSize; - platformContext->getImageResamplingHint(&srcSize, &dstSize); - srcWidth = srcSize.width(); - srcHeight = srcSize.height(); - destWidth = dstSize.width(); - destHeight = dstSize.height(); - } - - int destIWidth = static_cast<int>(destWidth); - int destIHeight = static_cast<int>(destHeight); - - // The percent change below which we will not resample. This usually means - // an off-by-one error on the web page, and just doing nearest neighbor - // sampling is usually good enough. - const float kFractionalChangeThreshold = 0.025f; - - // Images smaller than this in either direction are considered "small" and - // are not resampled ever (see below). - const int kSmallImageSizeThreshold = 8; - - // The amount an image can be stretched in a single direction before we - // say that it is being stretched so much that it must be a line or - // background that doesn't need resampling. - const float kLargeStretch = 3.0f; - - // Figure out if we should resample this image. We try to prune out some - // common cases where resampling won't give us anything, since it is much - // slower than drawing stretched. - if (srcWidth == destIWidth && srcHeight == destIHeight) { - // We don't need to resample if the source and destination are the same. - return RESAMPLE_NONE; - } - - if (srcWidth <= kSmallImageSizeThreshold - || srcHeight <= kSmallImageSizeThreshold - || destWidth <= kSmallImageSizeThreshold - || destHeight <= kSmallImageSizeThreshold) { - // Never resample small images. These are often used for borders and - // rules (think 1x1 images used to make lines). - return RESAMPLE_NONE; - } - - if (srcHeight * kLargeStretch <= destHeight || srcWidth * kLargeStretch <= destWidth) { - // Large image detected. - - // Don't resample if it is being stretched a lot in only one direction. - // This is trying to catch cases where somebody has created a border - // (which might be large) and then is stretching it to fill some part - // of the page. - if (srcWidth == destWidth || srcHeight == destHeight) - return RESAMPLE_NONE; - - // The image is growing a lot and in more than one direction. Resampling - // is slow and doesn't give us very much when growing a lot. - return RESAMPLE_LINEAR; - } - - if ((fabs(destWidth - srcWidth) / srcWidth < kFractionalChangeThreshold) - && (fabs(destHeight - srcHeight) / srcHeight < kFractionalChangeThreshold)) { - // It is disappointingly common on the web for image sizes to be off by - // one or two pixels. We don't bother resampling if the size difference - // is a small fraction of the original size. - return RESAMPLE_NONE; - } - - // When the image is not yet done loading, use linear. We don't cache the - // partially resampled images, and as they come in incrementally, it causes - // us to have to resample the whole thing every time. - if (!bitmap.isDataComplete()) - return RESAMPLE_LINEAR; - - // Everything else gets resampled. - // If the platform context permits high quality interpolation, use it. - // High quality interpolation only enabled for scaling and translation. - if (platformContext->interpolationQuality() == InterpolationHigh - && !(platformContext->canvas()->getTotalMatrix().getType() & (SkMatrix::kAffine_Mask | SkMatrix::kPerspective_Mask))) - return RESAMPLE_AWESOME; - - return RESAMPLE_LINEAR; -} - -// Draws the given bitmap to the given canvas. The subset of the source bitmap -// identified by src_rect is drawn to the given destination rect. The bitmap -// will be resampled to resample_width * resample_height (this is the size of -// the whole image, not the subset). See shouldResampleBitmap for more. -// -// This does a lot of computation to resample only the portion of the bitmap -// that will only be drawn. This is critical for performance since when we are -// scrolling, for example, we are only drawing a small strip of the image. -// Resampling the whole image every time is very slow, so this speeds up things -// dramatically. -static void drawResampledBitmap(SkCanvas& canvas, SkPaint& paint, const NativeImageSkia& bitmap, const SkIRect& srcIRect, const SkRect& destRect) -{ - // First get the subset we need. This is efficient and does not copy pixels. - SkBitmap subset; - bitmap.extractSubset(&subset, srcIRect); - SkRect srcRect; - srcRect.set(srcIRect); - - // Whether we're doing a subset or using the full source image. - bool srcIsFull = srcIRect.fLeft == 0 && srcIRect.fTop == 0 - && srcIRect.width() == bitmap.width() - && srcIRect.height() == bitmap.height(); - - // We will always draw in integer sizes, so round the destination rect. - SkIRect destRectRounded; - destRect.round(&destRectRounded); - SkIRect resizedImageRect = // Represents the size of the resized image. - { 0, 0, destRectRounded.width(), destRectRounded.height() }; - - // Apply forward transform to destRect to estimate required size of - // re-sampled bitmap, and use only in calls required to resize, or that - // check for the required size. - SkRect destRectTransformed; - canvas.getTotalMatrix().mapRect(&destRectTransformed, destRect); - SkIRect destRectTransformedRounded; - destRectTransformed.round(&destRectTransformedRounded); - - if (srcIsFull && bitmap.hasResizedBitmap(destRectTransformedRounded.width(), destRectTransformedRounded.height())) { - // Yay, this bitmap frame already has a resized version. - SkBitmap resampled = bitmap.resizedBitmap(destRectTransformedRounded.width(), destRectTransformedRounded.height()); - canvas.drawBitmapRect(resampled, 0, destRect, &paint); - return; - } - - // Compute the visible portion of our rect. - // We also need to compute the transformed portion of the - // visible portion for use below. - SkRect destBitmapSubsetSk; - ClipRectToCanvas(canvas, destRect, &destBitmapSubsetSk); - SkRect destBitmapSubsetTransformed; - canvas.getTotalMatrix().mapRect(&destBitmapSubsetTransformed, destBitmapSubsetSk); - destBitmapSubsetSk.offset(-destRect.fLeft, -destRect.fTop); - SkIRect destBitmapSubsetTransformedRounded; - destBitmapSubsetTransformed.round(&destBitmapSubsetTransformedRounded); - destBitmapSubsetTransformedRounded.offset(-destRectTransformedRounded.fLeft, -destRectTransformedRounded.fTop); - - // The matrix inverting, etc. could have introduced rounding error which - // causes the bounds to be outside of the resized bitmap. We round outward - // so we always lean toward it being larger rather than smaller than we - // need, and then clamp to the bitmap bounds so we don't get any invalid - // data. - SkIRect destBitmapSubsetSkI; - destBitmapSubsetSk.roundOut(&destBitmapSubsetSkI); - if (!destBitmapSubsetSkI.intersect(resizedImageRect)) - return; // Resized image does not intersect. - - if (srcIsFull && bitmap.shouldCacheResampling( - resizedImageRect.width(), - resizedImageRect.height(), - destBitmapSubsetSkI.width(), - destBitmapSubsetSkI.height())) { - // We're supposed to resize the entire image and cache it, even though - // we don't need all of it. - SkBitmap resampled = bitmap.resizedBitmap(destRectTransformedRounded.width(), - destRectTransformedRounded.height()); - canvas.drawBitmapRect(resampled, 0, destRect, &paint); - } else { - // We should only resize the exposed part of the bitmap to do the - // minimal possible work. - - // Resample the needed part of the image. - // Transforms above plus rounding may cause destBitmapSubsetTransformedRounded - // to go outside the image, so need to clip to avoid problems. - if (destBitmapSubsetTransformedRounded.intersect(0, 0, - destRectTransformedRounded.width(), destRectTransformedRounded.height())) { - - SkBitmap resampled = skia::ImageOperations::Resize(subset, - skia::ImageOperations::RESIZE_LANCZOS3, - destRectTransformedRounded.width(), destRectTransformedRounded.height(), - destBitmapSubsetTransformedRounded); - - // Compute where the new bitmap should be drawn. Since our new bitmap - // may be smaller than the original, we have to shift it over by the - // same amount that we cut off the top and left. - destBitmapSubsetSkI.offset(destRect.fLeft, destRect.fTop); - SkRect offsetDestRect; - offsetDestRect.set(destBitmapSubsetSkI); - - canvas.drawBitmapRect(resampled, 0, offsetDestRect, &paint); - } - } -} - -static void paintSkBitmap(PlatformContextSkia* platformContext, const NativeImageSkia& bitmap, const SkIRect& srcRect, const SkRect& destRect, const SkXfermode::Mode& compOp) -{ - SkPaint paint; - paint.setXfermodeMode(compOp); - paint.setFilterBitmap(true); - paint.setAlpha(platformContext->getNormalizedAlpha()); - - skia::PlatformCanvas* canvas = platformContext->canvas(); - - ResamplingMode resampling = platformContext->isPrinting() ? RESAMPLE_NONE : - computeResamplingMode(platformContext, bitmap, srcRect.width(), srcRect.height(), - SkScalarToFloat(destRect.width()), - SkScalarToFloat(destRect.height())); - if (resampling == RESAMPLE_AWESOME) { - drawResampledBitmap(*canvas, paint, bitmap, srcRect, destRect); - } else { - // No resampling necessary, we can just draw the bitmap. We want to - // filter it if we decided to do linear interpolation above, or if there - // is something interesting going on with the matrix (like a rotation). - // Note: for serialization, we will want to subset the bitmap first so - // we don't send extra pixels. - canvas->drawBitmapRect(bitmap, &srcRect, destRect, &paint); - } -} - -// Transforms the given dimensions with the given matrix. Used to see how big -// images will be once transformed. -static void TransformDimensions(const SkMatrix& matrix, float srcWidth, float srcHeight, float* destWidth, float* destHeight) { - // Transform 3 points to see how long each side of the bitmap will be. - SkPoint src_points[3]; // (0, 0), (width, 0), (0, height). - src_points[0].set(0, 0); - src_points[1].set(SkFloatToScalar(srcWidth), 0); - src_points[2].set(0, SkFloatToScalar(srcHeight)); - - // Now measure the length of the two transformed vectors relative to the - // transformed origin to see how big the bitmap will be. Note: for skews, - // this isn't the best thing, but we don't have skews. - SkPoint dest_points[3]; - matrix.mapPoints(dest_points, src_points, 3); - *destWidth = SkScalarToFloat((dest_points[1] - dest_points[0]).length()); - *destHeight = SkScalarToFloat((dest_points[2] - dest_points[0]).length()); -} - -// A helper method for translating negative width and height values. -static FloatRect normalizeRect(const FloatRect& rect) -{ - FloatRect norm = rect; - if (norm.width() < 0) { - norm.setX(norm.x() + norm.width()); - norm.setWidth(-norm.width()); - } - if (norm.height() < 0) { - norm.setY(norm.y() + norm.height()); - norm.setHeight(-norm.height()); - } - return norm; -} - -bool FrameData::clear(bool clearMetadata) -{ - if (clearMetadata) - m_haveMetadata = false; - - if (m_frame) { - // ImageSource::createFrameAtIndex() allocated |m_frame| and passed - // ownership to BitmapImage; we must delete it here. - delete m_frame; - m_frame = 0; - return true; - } - return false; -} - -void Image::drawPattern(GraphicsContext* context, - const FloatRect& floatSrcRect, - const AffineTransform& patternTransform, - const FloatPoint& phase, - ColorSpace styleColorSpace, - CompositeOperator compositeOp, - const FloatRect& destRect) -{ - FloatRect normSrcRect = normalizeRect(floatSrcRect); - if (destRect.isEmpty() || normSrcRect.isEmpty()) - return; // nothing to draw - - NativeImageSkia* bitmap = nativeImageForCurrentFrame(); - if (!bitmap) - return; - - // 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. - SkBitmap srcSubset; - SkIRect srcRect = enclosingIntRect(normSrcRect); - bitmap->extractSubset(&srcSubset, srcRect); - - SkBitmap resampled; - SkShader* shader; - - // Figure out what size the bitmap will be in the destination. The - // destination rect is the bounds of the pattern, we need to use the - // matrix to see how bit it will be. - float destBitmapWidth, destBitmapHeight; - TransformDimensions(patternTransform, srcRect.width(), srcRect.height(), - &destBitmapWidth, &destBitmapHeight); - - // Compute the resampling mode. - ResamplingMode resampling; - if (context->platformContext()->isPrinting()) - resampling = RESAMPLE_LINEAR; - else { - resampling = computeResamplingMode(context->platformContext(), *bitmap, - srcRect.width(), srcRect.height(), - destBitmapWidth, destBitmapHeight); - } - - // Load the transform WebKit requested. - SkMatrix matrix(patternTransform); - - if (resampling == RESAMPLE_AWESOME) { - // Do nice resampling. - SkBitmap resampled; - int width = static_cast<int>(destBitmapWidth); - int height = static_cast<int>(destBitmapHeight); - if (!srcRect.fLeft && !srcRect.fTop - && srcRect.fRight == bitmap->width() && srcRect.fBottom == bitmap->height() - && (bitmap->hasResizedBitmap(width, height) - || bitmap->shouldCacheResampling(width, height, width, height))) { - // resizedBitmap() caches resized image. - resampled = bitmap->resizedBitmap(width, height); - } else { - resampled = skia::ImageOperations::Resize(srcSubset, - skia::ImageOperations::RESIZE_LANCZOS3, width, height); - } - shader = SkShader::CreateBitmapShader(resampled, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode); - - // Since we just resized the bitmap, we need to undo the scale set in - // the image transform. - matrix.setScaleX(SkIntToScalar(1)); - matrix.setScaleY(SkIntToScalar(1)); - } else { - // No need to do nice resampling. - shader = SkShader::CreateBitmapShader(srcSubset, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode); - } - - // We also need to translate it such that the origin of the pattern is the - // origin of the destination rect, which is what WebKit expects. Skia uses - // the coordinate system origin as the base for the patter. If WebKit wants - // a shifted image, it will shift it from there using the patternTransform. - float adjustedX = phase.x() + normSrcRect.x() * - narrowPrecisionToFloat(patternTransform.a()); - float adjustedY = phase.y() + normSrcRect.y() * - narrowPrecisionToFloat(patternTransform.d()); - matrix.postTranslate(SkFloatToScalar(adjustedX), - SkFloatToScalar(adjustedY)); - shader->setLocalMatrix(matrix); - - SkPaint paint; - paint.setShader(shader)->unref(); - paint.setXfermodeMode(WebCoreCompositeToSkiaComposite(compositeOp)); - paint.setFilterBitmap(resampling == RESAMPLE_LINEAR); - - context->platformContext()->paintSkPaint(destRect, paint); -} - -static void drawBitmapGLES2(GraphicsContext* ctxt, NativeImageSkia* bitmap, const FloatRect& srcRect, const FloatRect& dstRect, ColorSpace styleColorSpace, CompositeOperator compositeOp) -{ - ctxt->platformContext()->prepareForHardwareDraw(); - GLES2Canvas* gpuCanvas = ctxt->platformContext()->gpuCanvas(); - Texture* texture = gpuCanvas->getTexture(bitmap); - if (!texture) { - ASSERT(bitmap->config() == SkBitmap::kARGB_8888_Config); - ASSERT(bitmap->rowBytes() == bitmap->width() * 4); - texture = gpuCanvas->createTexture(bitmap, Texture::BGRA8, bitmap->width(), bitmap->height()); - SkAutoLockPixels lock(*bitmap); - ASSERT(bitmap->getPixels()); - texture->load(bitmap->getPixels()); - } - gpuCanvas->drawTexturedRect(texture, srcRect, dstRect, styleColorSpace, compositeOp); -} - -// ================================================ -// BitmapImage Class -// ================================================ - -// FIXME: These should go to BitmapImageSkia.cpp - -void BitmapImage::initPlatformData() -{ - // This is not used. On Mac, the "platform" data is a cache of some OS - // specific versions of the image that are created is some cases. These - // aren't normally used, it is equivalent to getHBITMAP on Windows, and - // the platform data is the cache. -} - -void BitmapImage::invalidatePlatformData() -{ - // See initPlatformData above. -} - -void BitmapImage::checkForSolidColor() -{ - m_checkedForSolidColor = true; -} - -void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dstRect, - const FloatRect& srcRect, ColorSpace colorSpace, CompositeOperator compositeOp) -{ - if (!m_source.initialized()) - return; - - // Spin the animation to the correct frame before we try to draw it, so we - // don't draw an old frame and then immediately need to draw a newer one, - // causing flicker and wasting CPU. - startAnimation(); - - NativeImageSkia* bm = nativeImageForCurrentFrame(); - if (!bm) - return; // It's too early and we don't have an image yet. - - FloatRect normDstRect = normalizeRect(dstRect); - FloatRect normSrcRect = normalizeRect(srcRect); - - if (normSrcRect.isEmpty() || normDstRect.isEmpty()) - return; // Nothing to draw. - - if (ctxt->platformContext()->useGPU() && ctxt->platformContext()->canAccelerate()) { - drawBitmapGLES2(ctxt, bm, normSrcRect, normDstRect, colorSpace, compositeOp); - return; - } - - ctxt->platformContext()->prepareForSoftwareDraw(); - - paintSkBitmap(ctxt->platformContext(), - *bm, - enclosingIntRect(normSrcRect), - normDstRect, - WebCoreCompositeToSkiaComposite(compositeOp)); -} - -// FIXME: These should go into BitmapImageSingleFrameSkia.cpp - -void BitmapImageSingleFrameSkia::draw(GraphicsContext* ctxt, - const FloatRect& dstRect, - const FloatRect& srcRect, - ColorSpace styleColorSpace, - CompositeOperator compositeOp) -{ - FloatRect normDstRect = normalizeRect(dstRect); - FloatRect normSrcRect = normalizeRect(srcRect); - - if (normSrcRect.isEmpty() || normDstRect.isEmpty()) - return; // Nothing to draw. - - if (ctxt->platformContext()->useGPU() && ctxt->platformContext()->canAccelerate()) { - drawBitmapGLES2(ctxt, &m_nativeImage, srcRect, dstRect, styleColorSpace, compositeOp); - return; - } - - ctxt->platformContext()->prepareForSoftwareDraw(); - - paintSkBitmap(ctxt->platformContext(), - m_nativeImage, - enclosingIntRect(normSrcRect), - normDstRect, - WebCoreCompositeToSkiaComposite(compositeOp)); -} - -BitmapImageSingleFrameSkia::BitmapImageSingleFrameSkia(const SkBitmap& bitmap) - : m_nativeImage(bitmap) -{ -} - -PassRefPtr<BitmapImageSingleFrameSkia> BitmapImageSingleFrameSkia::create(const SkBitmap& bitmap, bool copyPixels) -{ - if (copyPixels) { - SkBitmap temp; - bitmap.copyTo(&temp, bitmap.config()); - return adoptRef(new BitmapImageSingleFrameSkia(temp)); - } - return adoptRef(new BitmapImageSingleFrameSkia(bitmap)); -} - -} // namespace WebCore diff --git a/WebCore/platform/graphics/skia/IntPointSkia.cpp b/WebCore/platform/graphics/skia/IntPointSkia.cpp deleted file mode 100644 index fd9a6fd..0000000 --- a/WebCore/platform/graphics/skia/IntPointSkia.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT - * OWNER 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/WebCore/platform/graphics/skia/IntRectSkia.cpp b/WebCore/platform/graphics/skia/IntRectSkia.cpp deleted file mode 100644 index ea138ee..0000000 --- a/WebCore/platform/graphics/skia/IntRectSkia.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT - * OWNER 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()) -{ -} - -} // namespace WebCore diff --git a/WebCore/platform/graphics/skia/NativeImageSkia.cpp b/WebCore/platform/graphics/skia/NativeImageSkia.cpp deleted file mode 100644 index 94f9b75..0000000 --- a/WebCore/platform/graphics/skia/NativeImageSkia.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/* - * 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: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT - * OWNER 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" - -#if !PLATFORM(ANDROID) -#include "skia/ext/image_operations.h" -#endif - -#include "NativeImageSkia.h" -#include "SharedGraphicsContext3D.h" -#include "SkiaUtils.h" - -namespace WebCore { - -NativeImageSkia::NativeImageSkia() - : m_isDataComplete(false), - m_lastRequestSize(0, 0), - m_resizeRequests(0) -{ -} - -NativeImageSkia::NativeImageSkia(const SkBitmap& other) - : SkBitmap(other), - m_isDataComplete(false), - m_lastRequestSize(0, 0), - m_resizeRequests(0) -{ -} - - -NativeImageSkia::~NativeImageSkia() -{ -#if PLATFORM(ANDROID) - // SharedGraphicsContext3D::removeTexturesFor() takes a NativeImagePtr. On - // Chromium, this is NativeImageSkia, which inherits from SkBitmap. On - // Android, NativeImagePtr is a SkBitmapRef, which is a wrapper around - // SkBitmap. Failing to call removeTexturesFor() probably causes a leak. - // TODO: Fix this. See http://b/3047425 -#else - SharedGraphicsContext3D::removeTexturesFor(this); -#endif -} - -int NativeImageSkia::decodedSize() const -{ - return getSize() + m_resizedImage.getSize(); -} - -bool NativeImageSkia::hasResizedBitmap(int w, int h) const -{ - if (m_lastRequestSize.width() == w && m_lastRequestSize.height() == h) - m_resizeRequests++; - else { - m_lastRequestSize = IntSize(w, h); - m_resizeRequests = 0; - } - - return m_resizedImage.width() == w && m_resizedImage.height() == h; -} - -// FIXME: don't cache when image is in-progress. - -SkBitmap NativeImageSkia::resizedBitmap(int w, int h) const -{ -#if !PLATFORM(ANDROID) - if (m_resizedImage.width() != w || m_resizedImage.height() != h) - m_resizedImage = skia::ImageOperations::Resize(*this, skia::ImageOperations::RESIZE_LANCZOS3, w, h); -#endif - - return m_resizedImage; -} - -bool NativeImageSkia::shouldCacheResampling(int destWidth, - int destHeight, - int destSubsetWidth, - int destSubsetHeight) const -{ - // We can not cache incomplete frames. This might be a good optimization in - // the future, were we know how much of the frame has been decoded, so when - // we incrementally draw more of the image, we only have to resample the - // parts that are changed. - if (!m_isDataComplete) - return false; - - // If the destination bitmap is small, we'll always allow caching, since - // there is not very much penalty for computing it and it may come in handy. - static const int kSmallBitmapSize = 4096; - if (destWidth * destHeight <= kSmallBitmapSize) - return true; - - // If "too many" requests have been made for this bitmap, we assume that - // many more will be made as well, and we'll go ahead and cache it. - static const int kManyRequestThreshold = 4; - if (m_lastRequestSize.width() == destWidth && - m_lastRequestSize.height() == destHeight) { - if (m_resizeRequests >= kManyRequestThreshold) - return true; - } else { - // When a different size is being requested, count this as a query - // (hasResizedBitmap) and reset the counter. - m_lastRequestSize = IntSize(destWidth, destHeight); - m_resizeRequests = 0; - } - - // Otherwise, use the heuristic that if more than 1/4 of the image is - // requested, it's worth caching. - int destSize = destWidth * destHeight; - int destSubsetSize = destSubsetWidth * destSubsetHeight; - return destSize / 4 < destSubsetSize; -} - -} // namespace WebCore diff --git a/WebCore/platform/graphics/skia/NativeImageSkia.h b/WebCore/platform/graphics/skia/NativeImageSkia.h deleted file mode 100644 index 00b0a68..0000000 --- a/WebCore/platform/graphics/skia/NativeImageSkia.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * 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: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT - * OWNER 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. - */ - -#ifndef NativeImageSkia_h -#define NativeImageSkia_h - -#include "SkBitmap.h" -#include "IntSize.h" - -namespace WebCore { - -// This object is used as the "native image" in our port. When WebKit uses -// "NativeImagePtr", it is a pointer to this type. It is an SkBitmap, but also -// stores a cached resized image. -class NativeImageSkia : public SkBitmap { -public: - NativeImageSkia(); - ~NativeImageSkia(); - - // This constructor does a shallow copy of the passed-in SkBitmap (ie., it - // references the same pixel data and bumps the refcount). Use only when - // you want sharing semantics. - explicit NativeImageSkia(const SkBitmap&); - - // Returns the number of bytes of image data. This includes the cached - // resized version if there is one. - int decodedSize() const; - - // Sets the data complete flag. This is called by the image decoder when - // all data is complete, and used by us to know whether we can cache - // resized images. - void setDataComplete() { m_isDataComplete = true; } - - // Returns true if the entire image has been decoded. - bool isDataComplete() const { return m_isDataComplete; } - - // We can keep a resized version of the bitmap cached on this object. - // This function will return true if there is a cached version of the - // given image subset with the given dimensions. - bool hasResizedBitmap(int width, int height) const; - - // This will return an existing resized image, or generate a new one of - // the specified size and store it in the cache. Subsetted images can not - // be cached unless the subset is the entire bitmap. - SkBitmap resizedBitmap(int width, int height) const; - - // Returns true if the given resize operation should either resize the whole - // image and cache it, or resize just the part it needs and throw the result - // away. - // - // On the one hand, if only a small subset is desired, then we will waste a - // lot of time resampling the entire thing, so we only want to do exactly - // what's required. On the other hand, resampling the entire bitmap is - // better if we're going to be using it more than once (like a bitmap - // scrolling on and off the screen. Since we only cache when doing the - // entire thing, it's best to just do it up front. - bool shouldCacheResampling(int destWidth, - int destHeight, - int destSubsetWidth, - int destSubsetHeight) const; - -private: - // Set to true when the data is complete. Before the entire image has - // loaded, we do not want to cache a resize. - bool m_isDataComplete; - - // The cached bitmap. This will be empty() if there is no cached image. - mutable SkBitmap m_resizedImage; - - // References how many times that the image size has been requested for - // the last size. - // - // Every time we get a request, if it matches the m_lastRequestSize, we'll - // increment the counter, and if not, we'll reset the counter and save the - // size. - // - // This allows us to see if many requests have been made for the same - // resized image, we know that we should probably cache it, even if all of - // those requests individually are small and would not otherwise be cached. - mutable IntSize m_lastRequestSize; - mutable int m_resizeRequests; -}; - -} -#endif // NativeImageSkia_h - diff --git a/WebCore/platform/graphics/skia/PathSkia.cpp b/WebCore/platform/graphics/skia/PathSkia.cpp deleted file mode 100644 index 89323c4..0000000 --- a/WebCore/platform/graphics/skia/PathSkia.cpp +++ /dev/null @@ -1,274 +0,0 @@ -// 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: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT -// OWNER 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 "Path.h" - -#include "AffineTransform.h" -#include "FloatRect.h" -#include "ImageBuffer.h" -#include "StrokeStyleApplier.h" - -#include "SkPath.h" -#include "SkRegion.h" -#include "SkiaUtils.h" - -#include <wtf/MathExtras.h> - -namespace WebCore { - -Path::Path() -{ - m_path = new SkPath; -} - -Path::Path(const Path& other) -{ - m_path = new SkPath(*other.m_path); -} - -Path::~Path() -{ - delete m_path; -} - -Path& Path::operator=(const Path& other) -{ - *m_path = *other.m_path; - return *this; -} - -bool Path::isEmpty() const -{ - return m_path->isEmpty(); -} - -bool Path::hasCurrentPoint() const -{ - return m_path->getPoints(NULL, 0) != 0; -} - -FloatPoint Path::currentPoint() const -{ - // FIXME: return current point of subpath. - float quietNaN = std::numeric_limits<float>::quiet_NaN(); - return FloatPoint(quietNaN, quietNaN); -} - -bool Path::contains(const FloatPoint& point, WindRule rule) const -{ - return SkPathContainsPoint(m_path, point, - rule == RULE_NONZERO ? SkPath::kWinding_FillType : SkPath::kEvenOdd_FillType); -} - -void Path::translate(const FloatSize& size) -{ - m_path->offset(WebCoreFloatToSkScalar(size.width()), WebCoreFloatToSkScalar(size.height())); -} - -FloatRect Path::boundingRect() const -{ - return m_path->getBounds(); -} - -void Path::moveTo(const FloatPoint& point) -{ - m_path->moveTo(point); -} - -void Path::addLineTo(const FloatPoint& point) -{ - m_path->lineTo(point); -} - -void Path::addQuadCurveTo(const FloatPoint& cp, const FloatPoint& ep) -{ - m_path->quadTo(cp, ep); -} - -void Path::addBezierCurveTo(const FloatPoint& p1, const FloatPoint& p2, const FloatPoint& ep) -{ - m_path->cubicTo(p1, p2, ep); -} - -void Path::addArcTo(const FloatPoint& p1, const FloatPoint& p2, float radius) -{ - m_path->arcTo(p1, p2, WebCoreFloatToSkScalar(radius)); -} - -void Path::closeSubpath() -{ - m_path->close(); -} - -void Path::addArc(const FloatPoint& p, float r, float sa, float ea, bool anticlockwise) { - SkScalar cx = WebCoreFloatToSkScalar(p.x()); - SkScalar cy = WebCoreFloatToSkScalar(p.y()); - SkScalar radius = WebCoreFloatToSkScalar(r); - SkScalar s360 = SkIntToScalar(360); - - SkRect oval; - oval.set(cx - radius, cy - radius, cx + radius, cy + radius); - - float sweep = ea - sa; - SkScalar startDegrees = WebCoreFloatToSkScalar(sa * 180 / piFloat); - SkScalar sweepDegrees = WebCoreFloatToSkScalar(sweep * 180 / piFloat); - // Check for a circle. - if (sweepDegrees >= s360 || sweepDegrees <= -s360) { - // Move to the start position (0 sweep means we add a single point). - m_path->arcTo(oval, startDegrees, 0, false); - // Draw the circle. - m_path->addOval(oval); - // Force a moveTo the end position. - m_path->arcTo(oval, startDegrees + sweepDegrees, 0, true); - } else { - // Counterclockwise arcs should be drawn with negative sweeps, while - // clockwise arcs should be drawn with positive sweeps. Check to see - // if the situation is reversed and correct it by adding or subtracting - // a full circle - if (anticlockwise && sweepDegrees > 0) { - sweepDegrees -= s360; - } else if (!anticlockwise && sweepDegrees < 0) { - sweepDegrees += s360; - } - - m_path->arcTo(oval, startDegrees, sweepDegrees, false); - } -} - -void Path::addRect(const FloatRect& rect) -{ - m_path->addRect(rect); -} - -void Path::addEllipse(const FloatRect& rect) -{ - m_path->addOval(rect); -} - -void Path::clear() -{ - m_path->reset(); -} - -static FloatPoint* convertPathPoints(FloatPoint dst[], const SkPoint src[], int count) -{ - for (int i = 0; i < count; i++) { - dst[i].setX(SkScalarToFloat(src[i].fX)); - dst[i].setY(SkScalarToFloat(src[i].fY)); - } - return dst; -} - -void Path::apply(void* info, PathApplierFunction function) const -{ - SkPath::Iter iter(*m_path, false); - SkPoint pts[4]; - PathElement pathElement; - FloatPoint pathPoints[3]; - - for (;;) { - switch (iter.next(pts)) { - case SkPath::kMove_Verb: - pathElement.type = PathElementMoveToPoint; - pathElement.points = convertPathPoints(pathPoints, &pts[0], 1); - break; - case SkPath::kLine_Verb: - pathElement.type = PathElementAddLineToPoint; - pathElement.points = convertPathPoints(pathPoints, &pts[1], 1); - break; - case SkPath::kQuad_Verb: - pathElement.type = PathElementAddQuadCurveToPoint; - pathElement.points = convertPathPoints(pathPoints, &pts[1], 2); - break; - case SkPath::kCubic_Verb: - pathElement.type = PathElementAddCurveToPoint; - pathElement.points = convertPathPoints(pathPoints, &pts[1], 3); - break; - case SkPath::kClose_Verb: - pathElement.type = PathElementCloseSubpath; - pathElement.points = convertPathPoints(pathPoints, 0, 0); - break; - case SkPath::kDone_Verb: - return; - } - function(info, &pathElement); - } -} - -void Path::transform(const AffineTransform& xform) -{ - m_path->transform(xform); -} - -// Computes the bounding box for the stroke and style currently selected into -// the given bounding box. This also takes into account the stroke width. -static FloatRect boundingBoxForCurrentStroke(const GraphicsContext* context) -{ - SkPaint paint; - context->platformContext()->setupPaintForStroking(&paint, 0, 0); - SkPath boundingPath; - paint.getFillPath(context->platformContext()->currentPathInLocalCoordinates(), &boundingPath); - return boundingPath.getBounds(); -} - -FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier) -{ - GraphicsContext* scratch = scratchContext(); - scratch->save(); - scratch->beginPath(); - scratch->addPath(*this); - - if (applier) - applier->strokeStyle(scratch); - - FloatRect r = boundingBoxForCurrentStroke(scratch); - scratch->restore(); - return r; -} - -bool Path::strokeContains(StrokeStyleApplier* applier, const FloatPoint& point) const -{ - ASSERT(applier); - GraphicsContext* scratch = scratchContext(); - scratch->save(); - - applier->strokeStyle(scratch); - - SkPaint paint; - scratch->platformContext()->setupPaintForStroking(&paint, 0, 0); - SkPath strokePath; - paint.getFillPath(*platformPath(), &strokePath); - bool contains = SkPathContainsPoint(&strokePath, point, - SkPath::kWinding_FillType); - - scratch->restore(); - return contains; -} -} // namespace WebCore diff --git a/WebCore/platform/graphics/skia/PatternSkia.cpp b/WebCore/platform/graphics/skia/PatternSkia.cpp deleted file mode 100644 index 72fac77..0000000 --- a/WebCore/platform/graphics/skia/PatternSkia.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/* - * 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 "SkCanvas.h" -#include "SkColor.h" -#include "SkColorShader.h" -#include "SkShader.h" - -namespace WebCore { - -void Pattern::platformDestroy() -{ - SkSafeUnref(m_pattern); - m_pattern = 0; -} - -PlatformPatternPtr Pattern::platformPattern(const AffineTransform& patternTransform) -{ - if (m_pattern) - return m_pattern; - - // Note: patternTransform is ignored since it seems to be applied elsewhere - // (when the pattern is used?). Applying it to the pattern (i.e. - // shader->setLocalMatrix) results in a double transformation. This can be - // seen, for instance, as an extra offset in: - // LayoutTests/fast/canvas/patternfill-repeat.html - // and expanded scale and skew in: - // LayoutTests/svg/W3C-SVG-1.1/pservers-grad-06-b.svg - - SkBitmap* bm = m_tileImage->nativeImageForCurrentFrame(); - // If we don't have a bitmap, return a transparent shader. - if (!bm) - m_pattern = new SkColorShader(SkColorSetARGB(0, 0, 0, 0)); - - else if (m_repeatX && m_repeatY) - m_pattern = SkShader::CreateBitmapShader(*bm, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode); - - else { - - // Skia does not have a "draw the tile only once" option. Clamp_TileMode - // repeats the last line of the image after drawing one tile. To avoid - // filling the space with arbitrary pixels, this workaround forces the - // image to have a line of transparent pixels on the "repeated" edge(s), - // thus causing extra space to be transparent filled. - SkShader::TileMode tileModeX = m_repeatX ? SkShader::kRepeat_TileMode : SkShader::kClamp_TileMode; - SkShader::TileMode tileModeY = m_repeatY ? SkShader::kRepeat_TileMode : SkShader::kClamp_TileMode; - int expandW = m_repeatX ? 0 : 1; - int expandH = m_repeatY ? 0 : 1; - - // Create a transparent bitmap 1 pixel wider and/or taller than the - // original, then copy the orignal into it. - // FIXME: Is there a better way to pad (not scale) an image in skia? - SkBitmap bm2; - bm2.setConfig(bm->config(), bm->width() + expandW, bm->height() + expandH); - bm2.allocPixels(); - bm2.eraseARGB(0x00, 0x00, 0x00, 0x00); - SkCanvas canvas(bm2); - canvas.drawBitmap(*bm, 0, 0); - m_pattern = SkShader::CreateBitmapShader(bm2, tileModeX, tileModeY); - } - m_pattern->setLocalMatrix(m_patternSpaceTransformation); - return m_pattern; -} - -void Pattern::setPlatformPatternSpaceTransform() -{ - if (m_pattern) - m_pattern->setLocalMatrix(m_patternSpaceTransformation); -} - -} // namespace WebCore diff --git a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp deleted file mode 100644 index d3c0e00..0000000 --- a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp +++ /dev/null @@ -1,890 +0,0 @@ -/* - * 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: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT - * OWNER 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 "PlatformContextSkia.h" - -#include "AffineTransform.h" -#include "DrawingBuffer.h" -#include "Extensions3D.h" -#include "GraphicsContext.h" -#include "GraphicsContext3D.h" -#include "ImageBuffer.h" -#include "NativeImageSkia.h" -#include "SkiaUtils.h" -#include "Texture.h" -#include "TilingData.h" - -#include "skia/ext/image_operations.h" -#include "skia/ext/platform_canvas.h" - -#include "SkBitmap.h" -#include "SkColorPriv.h" -#include "SkDashPathEffect.h" -#include "SkShader.h" - -#include <wtf/MathExtras.h> -#include <wtf/OwnArrayPtr.h> -#include <wtf/Vector.h> - -#if ENABLE(ACCELERATED_2D_CANVAS) -#include "GLES2Canvas.h" -#include "SharedGraphicsContext3D.h" -#endif - -namespace WebCore { - -extern bool isPathSkiaSafe(const SkMatrix& transform, const SkPath& path); - -// State ----------------------------------------------------------------------- - -// Encapsulates the additional painting state information we store for each -// pushed graphics state. -struct PlatformContextSkia::State { - State(); - State(const State&); - ~State(); - - // Common shader state. - float m_alpha; - SkXfermode::Mode m_xferMode; - bool m_useAntialiasing; - SkDrawLooper* m_looper; - - // Fill. - SkColor m_fillColor; - SkShader* m_fillShader; - - // Stroke. - StrokeStyle m_strokeStyle; - SkColor m_strokeColor; - SkShader* m_strokeShader; - float m_strokeThickness; - int m_dashRatio; // Ratio of the length of a dash to its width. - float m_miterLimit; - SkPaint::Cap m_lineCap; - SkPaint::Join m_lineJoin; - SkDashPathEffect* m_dash; - - // Text. (See TextModeFill & friends in GraphicsContext.h.) - TextDrawingModeFlags m_textDrawingMode; - - // Helper function for applying the state's alpha value to the given input - // color to produce a new output color. - SkColor applyAlpha(SkColor) const; - - // If non-empty, the current State is clipped to this image. - SkBitmap m_imageBufferClip; - // If m_imageBufferClip is non-empty, this is the region the image is clipped to. - FloatRect m_clip; - - // This is a list of clipping paths which are currently active, in the - // order in which they were pushed. - WTF::Vector<SkPath> m_antiAliasClipPaths; - InterpolationQuality m_interpolationQuality; - - // If we currently have a canvas (non-antialiased path) clip applied. - bool m_canvasClipApplied; - - PlatformContextSkia::State cloneInheritedProperties(); -private: - // Not supported. - void operator=(const State&); -}; - -// Note: Keep theses default values in sync with GraphicsContextState. -PlatformContextSkia::State::State() - : m_alpha(1) - , m_xferMode(SkXfermode::kSrcOver_Mode) - , m_useAntialiasing(true) - , m_looper(0) - , m_fillColor(0xFF000000) - , m_fillShader(0) - , m_strokeStyle(SolidStroke) - , m_strokeColor(Color::black) - , m_strokeShader(0) - , m_strokeThickness(0) - , m_dashRatio(3) - , m_miterLimit(4) - , m_lineCap(SkPaint::kDefault_Cap) - , m_lineJoin(SkPaint::kDefault_Join) - , m_dash(0) - , m_textDrawingMode(TextModeFill) - , m_interpolationQuality(InterpolationHigh) - , m_canvasClipApplied(false) -{ -} - -PlatformContextSkia::State::State(const State& other) - : m_alpha(other.m_alpha) - , m_xferMode(other.m_xferMode) - , m_useAntialiasing(other.m_useAntialiasing) - , m_looper(other.m_looper) - , m_fillColor(other.m_fillColor) - , m_fillShader(other.m_fillShader) - , m_strokeStyle(other.m_strokeStyle) - , m_strokeColor(other.m_strokeColor) - , m_strokeShader(other.m_strokeShader) - , m_strokeThickness(other.m_strokeThickness) - , m_dashRatio(other.m_dashRatio) - , m_miterLimit(other.m_miterLimit) - , m_lineCap(other.m_lineCap) - , m_lineJoin(other.m_lineJoin) - , m_dash(other.m_dash) - , m_textDrawingMode(other.m_textDrawingMode) - , m_imageBufferClip(other.m_imageBufferClip) - , m_clip(other.m_clip) - , m_antiAliasClipPaths(other.m_antiAliasClipPaths) - , m_interpolationQuality(other.m_interpolationQuality) - , m_canvasClipApplied(other.m_canvasClipApplied) -{ - // Up the ref count of these. SkSafeRef does nothing if its argument is 0. - SkSafeRef(m_looper); - SkSafeRef(m_dash); - SkSafeRef(m_fillShader); - SkSafeRef(m_strokeShader); -} - -PlatformContextSkia::State::~State() -{ - SkSafeUnref(m_looper); - SkSafeUnref(m_dash); - SkSafeUnref(m_fillShader); - SkSafeUnref(m_strokeShader); -} - -// Returns a new State with all of this object's inherited properties copied. -PlatformContextSkia::State PlatformContextSkia::State::cloneInheritedProperties() -{ - PlatformContextSkia::State state(*this); - - // Everything is inherited except for the clip paths. - state.m_antiAliasClipPaths.clear(); - - return state; -} - -SkColor PlatformContextSkia::State::applyAlpha(SkColor c) const -{ - int s = roundf(m_alpha * 256); - if (s >= 256) - return c; - if (s < 0) - return 0; - - int a = SkAlphaMul(SkColorGetA(c), s); - return (c & 0x00FFFFFF) | (a << 24); -} - -// PlatformContextSkia --------------------------------------------------------- - -// Danger: canvas can be NULL. -PlatformContextSkia::PlatformContextSkia(skia::PlatformCanvas* canvas) - : m_canvas(canvas) - , m_drawingToImageBuffer(false) - , m_useGPU(false) -#if ENABLE(ACCELERATED_2D_CANVAS) - , m_gpuCanvas(0) -#endif - , m_backingStoreState(None) -{ - m_stateStack.append(State()); - m_state = &m_stateStack.last(); -} - -PlatformContextSkia::~PlatformContextSkia() -{ -#if ENABLE(ACCELERATED_2D_CANVAS) - if (m_gpuCanvas) - m_gpuCanvas->drawingBuffer()->setWillPublishCallback(0); -#endif -} - -void PlatformContextSkia::setCanvas(skia::PlatformCanvas* canvas) -{ - m_canvas = canvas; -} - -void PlatformContextSkia::setDrawingToImageBuffer(bool value) -{ - m_drawingToImageBuffer = value; -} - -bool PlatformContextSkia::isDrawingToImageBuffer() const -{ - return m_drawingToImageBuffer; -} - -void PlatformContextSkia::save() -{ - ASSERT(!hasImageResamplingHint()); - - m_stateStack.append(m_state->cloneInheritedProperties()); - m_state = &m_stateStack.last(); - - // The clip image only needs to be applied once. Reset the image so that we - // don't attempt to clip multiple times. - m_state->m_imageBufferClip.reset(); - - // Save our native canvas. - canvas()->save(); -} - -void PlatformContextSkia::beginLayerClippedToImage(const FloatRect& rect, - const ImageBuffer* imageBuffer) -{ - // Skia doesn't support clipping to an image, so we create a layer. The next - // time restore is invoked the layer and |imageBuffer| are combined to - // create the resulting image. - m_state->m_clip = rect; - SkRect bounds = { SkFloatToScalar(rect.x()), SkFloatToScalar(rect.y()), - SkFloatToScalar(rect.right()), SkFloatToScalar(rect.bottom()) }; - - canvas()->clipRect(bounds); - canvas()->saveLayerAlpha(&bounds, 255, - static_cast<SkCanvas::SaveFlags>(SkCanvas::kHasAlphaLayer_SaveFlag | SkCanvas::kFullColorLayer_SaveFlag)); - // Copy off the image as |imageBuffer| may be deleted before restore is invoked. - const SkBitmap* bitmap = imageBuffer->context()->platformContext()->bitmap(); - if (!bitmap->pixelRef()) { - // The bitmap owns it's pixels. This happens when we've allocated the - // pixels in some way and assigned them directly to the bitmap (as - // happens when we allocate a DIB). In this case the assignment operator - // does not copy the pixels, rather the copied bitmap ends up - // referencing the same pixels. As the pixels may not live as long as we - // need it to, we copy the image. - bitmap->copyTo(&m_state->m_imageBufferClip, SkBitmap::kARGB_8888_Config); - } else { - // If there is a pixel ref, we can safely use the assignment operator. - m_state->m_imageBufferClip = *bitmap; - } -} - -void PlatformContextSkia::clipPathAntiAliased(const SkPath& clipPath) -{ - // If we are currently tracking any anti-alias clip paths, then we already - // have a layer in place and don't need to add another. - bool haveLayerOutstanding = m_state->m_antiAliasClipPaths.size(); - - // See comments in applyAntiAliasedClipPaths about how this works. - m_state->m_antiAliasClipPaths.append(clipPath); - - if (!haveLayerOutstanding) { - SkRect bounds = clipPath.getBounds(); - canvas()->saveLayerAlpha(&bounds, 255, static_cast<SkCanvas::SaveFlags>(SkCanvas::kHasAlphaLayer_SaveFlag | SkCanvas::kFullColorLayer_SaveFlag | SkCanvas::kClipToLayer_SaveFlag)); - // Guards state modification during clipped operations. - // The state is popped in applyAntiAliasedClipPaths(). - canvas()->save(); - } -} - -void PlatformContextSkia::restore() -{ - if (!m_state->m_imageBufferClip.empty()) { - applyClipFromImage(m_state->m_clip, m_state->m_imageBufferClip); - canvas()->restore(); - } - - if (!m_state->m_antiAliasClipPaths.isEmpty()) - applyAntiAliasedClipPaths(m_state->m_antiAliasClipPaths); - - m_stateStack.removeLast(); - m_state = &m_stateStack.last(); - - // Restore our native canvas. - canvas()->restore(); -} - -void PlatformContextSkia::drawRect(SkRect rect) -{ - SkPaint paint; - int fillcolorNotTransparent = m_state->m_fillColor & 0xFF000000; - if (fillcolorNotTransparent) { - setupPaintForFilling(&paint); - canvas()->drawRect(rect, paint); - } - - if (m_state->m_strokeStyle != NoStroke - && (m_state->m_strokeColor & 0xFF000000)) { - // We do a fill of four rects to simulate the stroke of a border. - SkColor oldFillColor = m_state->m_fillColor; - - // setFillColor() will set the shader to NULL, so save a ref to it now. - SkShader* oldFillShader = m_state->m_fillShader; - SkSafeRef(oldFillShader); - setFillColor(m_state->m_strokeColor); - paint.reset(); - setupPaintForFilling(&paint); - SkRect topBorder = { rect.fLeft, rect.fTop, rect.fRight, rect.fTop + 1 }; - canvas()->drawRect(topBorder, paint); - SkRect bottomBorder = { rect.fLeft, rect.fBottom - 1, rect.fRight, rect.fBottom }; - canvas()->drawRect(bottomBorder, paint); - SkRect leftBorder = { rect.fLeft, rect.fTop + 1, rect.fLeft + 1, rect.fBottom - 1 }; - canvas()->drawRect(leftBorder, paint); - SkRect rightBorder = { rect.fRight - 1, rect.fTop + 1, rect.fRight, rect.fBottom - 1 }; - canvas()->drawRect(rightBorder, paint); - setFillColor(oldFillColor); - setFillShader(oldFillShader); - SkSafeUnref(oldFillShader); - } -} - -void PlatformContextSkia::setupPaintCommon(SkPaint* paint) const -{ -#if defined(SK_DEBUG) - { - SkPaint defaultPaint; - SkASSERT(*paint == defaultPaint); - } -#endif - - paint->setAntiAlias(m_state->m_useAntialiasing); - paint->setXfermodeMode(m_state->m_xferMode); - paint->setLooper(m_state->m_looper); -} - -void PlatformContextSkia::setupPaintForFilling(SkPaint* paint) const -{ - setupPaintCommon(paint); - paint->setColor(m_state->applyAlpha(m_state->m_fillColor)); - paint->setShader(m_state->m_fillShader); -} - -float PlatformContextSkia::setupPaintForStroking(SkPaint* paint, SkRect* rect, int length) const -{ - setupPaintCommon(paint); - float width = m_state->m_strokeThickness; - - paint->setColor(m_state->applyAlpha(m_state->m_strokeColor)); - paint->setShader(m_state->m_strokeShader); - paint->setStyle(SkPaint::kStroke_Style); - paint->setStrokeWidth(SkFloatToScalar(width)); - paint->setStrokeCap(m_state->m_lineCap); - paint->setStrokeJoin(m_state->m_lineJoin); - paint->setStrokeMiter(SkFloatToScalar(m_state->m_miterLimit)); - - if (m_state->m_dash) - paint->setPathEffect(m_state->m_dash); - else { - switch (m_state->m_strokeStyle) { - case NoStroke: - case SolidStroke: - break; - case DashedStroke: - width = m_state->m_dashRatio * width; - // Fall through. - case DottedStroke: - // Truncate the width, since we don't want fuzzy dots or dashes. - int dashLength = static_cast<int>(width); - // Subtract off the endcaps, since they're rendered separately. - int distance = length - 2 * static_cast<int>(m_state->m_strokeThickness); - int phase = 1; - if (dashLength > 1) { - // Determine how many dashes or dots we should have. - int numDashes = distance / dashLength; - int remainder = distance % dashLength; - // Adjust the phase to center the dashes within the line. - if (numDashes % 2 == 0) { - // Even: shift right half a dash, minus half the remainder - phase = (dashLength - remainder) / 2; - } else { - // Odd: shift right a full dash, minus half the remainder - phase = dashLength - remainder / 2; - } - } - SkScalar dashLengthSk = SkIntToScalar(dashLength); - SkScalar intervals[2] = { dashLengthSk, dashLengthSk }; - paint->setPathEffect(new SkDashPathEffect(intervals, 2, SkIntToScalar(phase)))->unref(); - } - } - - return width; -} - -void PlatformContextSkia::setDrawLooper(SkDrawLooper* dl) -{ - SkRefCnt_SafeAssign(m_state->m_looper, dl); -} - -void PlatformContextSkia::setMiterLimit(float ml) -{ - m_state->m_miterLimit = ml; -} - -void PlatformContextSkia::setAlpha(float alpha) -{ - m_state->m_alpha = alpha; -} - -void PlatformContextSkia::setLineCap(SkPaint::Cap lc) -{ - m_state->m_lineCap = lc; -} - -void PlatformContextSkia::setLineJoin(SkPaint::Join lj) -{ - m_state->m_lineJoin = lj; -} - -void PlatformContextSkia::setXfermodeMode(SkXfermode::Mode pdm) -{ - m_state->m_xferMode = pdm; -} - -void PlatformContextSkia::setFillColor(SkColor color) -{ - m_state->m_fillColor = color; - setFillShader(0); -} - -SkDrawLooper* PlatformContextSkia::getDrawLooper() const -{ - return m_state->m_looper; -} - -StrokeStyle PlatformContextSkia::getStrokeStyle() const -{ - return m_state->m_strokeStyle; -} - -void PlatformContextSkia::setStrokeStyle(StrokeStyle strokeStyle) -{ - m_state->m_strokeStyle = strokeStyle; -} - -void PlatformContextSkia::setStrokeColor(SkColor strokeColor) -{ - m_state->m_strokeColor = strokeColor; - setStrokeShader(0); -} - -float PlatformContextSkia::getStrokeThickness() const -{ - return m_state->m_strokeThickness; -} - -void PlatformContextSkia::setStrokeThickness(float thickness) -{ - m_state->m_strokeThickness = thickness; -} - -void PlatformContextSkia::setStrokeShader(SkShader* strokeShader) -{ - if (strokeShader) - m_state->m_strokeColor = Color::black; - - if (strokeShader != m_state->m_strokeShader) { - SkSafeUnref(m_state->m_strokeShader); - m_state->m_strokeShader = strokeShader; - SkSafeRef(m_state->m_strokeShader); - } -} - -TextDrawingModeFlags PlatformContextSkia::getTextDrawingMode() const -{ - return m_state->m_textDrawingMode; -} - -float PlatformContextSkia::getAlpha() const -{ - return m_state->m_alpha; -} - -int PlatformContextSkia::getNormalizedAlpha() const -{ - int alpha = roundf(m_state->m_alpha * 256); - if (alpha > 255) - alpha = 255; - else if (alpha < 0) - alpha = 0; - return alpha; -} - -void PlatformContextSkia::setTextDrawingMode(TextDrawingModeFlags mode) -{ - // TextModeClip is never used, so we assert that it isn't set: - // https://bugs.webkit.org/show_bug.cgi?id=21898 - ASSERT(!(mode & TextModeClip)); - m_state->m_textDrawingMode = mode; -} - -void PlatformContextSkia::setUseAntialiasing(bool enable) -{ - m_state->m_useAntialiasing = enable; -} - -SkColor PlatformContextSkia::effectiveFillColor() const -{ - return m_state->applyAlpha(m_state->m_fillColor); -} - -SkColor PlatformContextSkia::effectiveStrokeColor() const -{ - return m_state->applyAlpha(m_state->m_strokeColor); -} - -void PlatformContextSkia::beginPath() -{ - m_path.reset(); -} - -void PlatformContextSkia::addPath(const SkPath& path) -{ - m_path.addPath(path, m_canvas->getTotalMatrix()); -} - -SkPath PlatformContextSkia::currentPathInLocalCoordinates() const -{ - SkPath localPath = m_path; - const SkMatrix& matrix = m_canvas->getTotalMatrix(); - SkMatrix inverseMatrix; - if (!matrix.invert(&inverseMatrix)) - return SkPath(); - localPath.transform(inverseMatrix); - return localPath; -} - -void PlatformContextSkia::canvasClipPath(const SkPath& path) -{ - m_state->m_canvasClipApplied = true; - m_canvas->clipPath(path); -} - -void PlatformContextSkia::setFillRule(SkPath::FillType fr) -{ - m_path.setFillType(fr); -} - -void PlatformContextSkia::setFillShader(SkShader* fillShader) -{ - if (fillShader) - m_state->m_fillColor = Color::black; - - if (fillShader != m_state->m_fillShader) { - SkSafeUnref(m_state->m_fillShader); - m_state->m_fillShader = fillShader; - SkSafeRef(m_state->m_fillShader); - } -} - -InterpolationQuality PlatformContextSkia::interpolationQuality() const -{ - return m_state->m_interpolationQuality; -} - -void PlatformContextSkia::setInterpolationQuality(InterpolationQuality interpolationQuality) -{ - m_state->m_interpolationQuality = interpolationQuality; -} - -void PlatformContextSkia::setDashPathEffect(SkDashPathEffect* dash) -{ - if (dash != m_state->m_dash) { - SkSafeUnref(m_state->m_dash); - m_state->m_dash = dash; - } -} - -void PlatformContextSkia::paintSkPaint(const SkRect& rect, - const SkPaint& paint) -{ - m_canvas->drawRect(rect, paint); -} - -const SkBitmap* PlatformContextSkia::bitmap() const -{ - return &m_canvas->getDevice()->accessBitmap(false); -} - -bool PlatformContextSkia::isPrinting() -{ - return m_canvas->getTopPlatformDevice().IsVectorial(); -} - -void PlatformContextSkia::getImageResamplingHint(IntSize* srcSize, FloatSize* dstSize) const -{ - *srcSize = m_imageResamplingHintSrcSize; - *dstSize = m_imageResamplingHintDstSize; -} - -void PlatformContextSkia::setImageResamplingHint(const IntSize& srcSize, const FloatSize& dstSize) -{ - m_imageResamplingHintSrcSize = srcSize; - m_imageResamplingHintDstSize = dstSize; -} - -void PlatformContextSkia::clearImageResamplingHint() -{ - m_imageResamplingHintSrcSize = IntSize(); - m_imageResamplingHintDstSize = FloatSize(); -} - -bool PlatformContextSkia::hasImageResamplingHint() const -{ - return !m_imageResamplingHintSrcSize.isEmpty() && !m_imageResamplingHintDstSize.isEmpty(); -} - -void PlatformContextSkia::applyClipFromImage(const FloatRect& rect, const SkBitmap& imageBuffer) -{ - // NOTE: this assumes the image mask contains opaque black for the portions that are to be shown, as such we - // only look at the alpha when compositing. I'm not 100% sure this is what WebKit expects for image clipping. - SkPaint paint; - paint.setXfermodeMode(SkXfermode::kDstIn_Mode); - m_canvas->drawBitmap(imageBuffer, SkFloatToScalar(rect.x()), SkFloatToScalar(rect.y()), &paint); -} - -void PlatformContextSkia::applyAntiAliasedClipPaths(WTF::Vector<SkPath>& paths) -{ - // Anti-aliased clipping: - // - // Skia's clipping is 1-bit only. Consider what would happen if it were 8-bit: - // We have a square canvas, filled with white and we declare a circular - // clipping path. Then we fill twice with a black rectangle. The fractional - // pixels would first get the correct color (white * alpha + black * (1 - - // alpha)), but the second fill would apply the alpha to the already - // modified color and the result would be too dark. - // - // This, anti-aliased clipping needs to be performed after the drawing has - // been done. In order to do this, we create a new layer of the canvas in - // clipPathAntiAliased and store the clipping path. All drawing is done to - // the layer's bitmap while it's in effect. When WebKit calls restore() to - // undo the clipping, this function is called. - // - // Here, we walk the list of clipping paths backwards and, for each, we - // clear outside of the clipping path. We only need a single extra layer - // for any number of clipping paths. - // - // When we call restore on the SkCanvas, the layer's bitmap is composed - // into the layer below and we end up with correct, anti-aliased clipping. - - m_canvas->restore(); - - SkPaint paint; - paint.setXfermodeMode(SkXfermode::kClear_Mode); - paint.setAntiAlias(true); - paint.setStyle(SkPaint::kFill_Style); - - for (size_t i = paths.size() - 1; i < paths.size(); --i) { - paths[i].setFillType(SkPath::kInverseWinding_FillType); - m_canvas->drawPath(paths[i], paint); - } - - m_canvas->restore(); -} - -bool PlatformContextSkia::canAccelerate() const -{ - return !m_state->m_fillShader // Can't accelerate with a fill gradient or pattern. - && !m_state->m_looper // Can't accelerate with a shadow. - && !m_state->m_canvasClipApplied; // Can't accelerate with a clip to path applied. -} - -bool PlatformContextSkia::canvasClipApplied() const -{ - return m_state->m_canvasClipApplied; -} - -class WillPublishCallbackImpl : public DrawingBuffer::WillPublishCallback { -public: - static PassOwnPtr<WillPublishCallback> create(PlatformContextSkia* pcs) - { - return adoptPtr(new WillPublishCallbackImpl(pcs)); - } - - virtual void willPublish() - { - m_pcs->prepareForHardwareDraw(); - } - -private: - explicit WillPublishCallbackImpl(PlatformContextSkia* pcs) - : m_pcs(pcs) - { - } - - PlatformContextSkia* m_pcs; -}; - -void PlatformContextSkia::setSharedGraphicsContext3D(SharedGraphicsContext3D* context, DrawingBuffer* drawingBuffer, const WebCore::IntSize& size) -{ -#if ENABLE(ACCELERATED_2D_CANVAS) - if (context && drawingBuffer) { - m_useGPU = true; - m_gpuCanvas = new GLES2Canvas(context, drawingBuffer, size); - m_uploadTexture.clear(); - drawingBuffer->setWillPublishCallback(WillPublishCallbackImpl::create(this)); - } else { - syncSoftwareCanvas(); - m_uploadTexture.clear(); - m_gpuCanvas.clear(); - m_useGPU = false; - } -#endif -} - -void PlatformContextSkia::prepareForSoftwareDraw() const -{ - if (!m_useGPU) - return; - - if (m_backingStoreState == Hardware) { - // Depending on the blend mode we need to do one of a few things: - - // * For associative blend modes, we can draw into an initially empty - // canvas and then composite the results on top of the hardware drawn - // results before the next hardware draw or swapBuffers(). - - // * For non-associative blend modes we have to do a readback and then - // software draw. When we re-upload in this mode we have to blow - // away whatever is in the hardware backing store (do a copy instead - // of a compositing operation). - - if (m_state->m_xferMode == SkXfermode::kSrcOver_Mode) { - // Note that we have rendering results in both the hardware and software backing stores. - m_backingStoreState = Mixed; - } else { - readbackHardwareToSoftware(); - // When we switch back to hardware copy the results, don't composite. - m_backingStoreState = Software; - } - } else if (m_backingStoreState == Mixed) { - if (m_state->m_xferMode != SkXfermode::kSrcOver_Mode) { - // Have to composite our currently software drawn data... - uploadSoftwareToHardware(CompositeSourceOver); - // then do a readback so we can hardware draw stuff. - readbackHardwareToSoftware(); - m_backingStoreState = Software; - } - } else if (m_backingStoreState == None) { - m_backingStoreState = Software; - } -} - -void PlatformContextSkia::prepareForHardwareDraw() const -{ - if (!m_useGPU) - return; - - if (m_backingStoreState == Software) { - // Last drawn in software; upload everything we've drawn. - uploadSoftwareToHardware(CompositeCopy); - } else if (m_backingStoreState == Mixed) { - // Stuff in software/hardware, composite the software stuff on top of - // the hardware stuff. - uploadSoftwareToHardware(CompositeSourceOver); - } - m_backingStoreState = Hardware; -} - -void PlatformContextSkia::syncSoftwareCanvas() const -{ - if (!m_useGPU) - return; - - if (m_backingStoreState == Hardware) - readbackHardwareToSoftware(); - else if (m_backingStoreState == Mixed) { - // Have to composite our currently software drawn data.. - uploadSoftwareToHardware(CompositeSourceOver); - // then do a readback. - readbackHardwareToSoftware(); - m_backingStoreState = Software; - } - m_backingStoreState = Software; -} - -void PlatformContextSkia::markDirtyRect(const IntRect& rect) -{ - if (!m_useGPU) - return; - - switch (m_backingStoreState) { - case Software: - case Mixed: - m_softwareDirtyRect.unite(rect); - return; - case Hardware: - return; - default: - ASSERT_NOT_REACHED(); - } -} - -void PlatformContextSkia::uploadSoftwareToHardware(CompositeOperator op) const -{ -#if ENABLE(ACCELERATED_2D_CANVAS) - const SkBitmap& bitmap = m_canvas->getDevice()->accessBitmap(false); - SkAutoLockPixels lock(bitmap); - SharedGraphicsContext3D* context = m_gpuCanvas->context(); - if (!m_uploadTexture || m_uploadTexture->tiles().totalSizeX() < bitmap.width() || m_uploadTexture->tiles().totalSizeY() < bitmap.height()) - m_uploadTexture = context->createTexture(Texture::BGRA8, bitmap.width(), bitmap.height()); - - m_uploadTexture->updateSubRect(bitmap.getPixels(), m_softwareDirtyRect); - AffineTransform identity; - gpuCanvas()->drawTexturedRect(m_uploadTexture.get(), m_softwareDirtyRect, m_softwareDirtyRect, identity, 1.0, ColorSpaceDeviceRGB, op); - // Clear out the region of the software canvas we just uploaded. - m_canvas->save(); - m_canvas->resetMatrix(); - SkRect bounds = m_softwareDirtyRect; - m_canvas->clipRect(bounds, SkRegion::kReplace_Op); - m_canvas->drawARGB(0, 0, 0, 0, SkXfermode::kClear_Mode); - m_canvas->restore(); - m_softwareDirtyRect.setWidth(0); // Clear dirty rect. -#endif -} - -void PlatformContextSkia::readbackHardwareToSoftware() const -{ -#if ENABLE(ACCELERATED_2D_CANVAS) - const SkBitmap& bitmap = m_canvas->getDevice()->accessBitmap(true); - SkAutoLockPixels lock(bitmap); - int width = bitmap.width(), height = bitmap.height(); - OwnArrayPtr<uint32_t> buf(new uint32_t[width]); - SharedGraphicsContext3D* context = m_gpuCanvas->context(); - m_gpuCanvas->bindFramebuffer(); - // Flips the image vertically. - for (int y = 0; y < height; ++y) { - uint32_t* pixels = bitmap.getAddr32(0, y); - if (context->supportsBGRA()) - context->readPixels(0, height - 1 - y, width, 1, Extensions3D::BGRA_EXT, GraphicsContext3D::UNSIGNED_BYTE, pixels); - else { - context->readPixels(0, height - 1 - y, width, 1, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels); - for (int i = 0; i < width; ++i) { - uint32_t pixel = pixels[i]; - // Swizzles from RGBA -> BGRA. - pixels[i] = (pixel & 0xFF00FF00) | ((pixel & 0x00FF0000) >> 16) | ((pixel & 0x000000FF) << 16); - } - } - } - m_softwareDirtyRect.unite(IntRect(0, 0, width, height)); // Mark everything as dirty. -#endif -} - -} // namespace WebCore diff --git a/WebCore/platform/graphics/skia/PlatformContextSkia.h b/WebCore/platform/graphics/skia/PlatformContextSkia.h deleted file mode 100644 index 11b311a..0000000 --- a/WebCore/platform/graphics/skia/PlatformContextSkia.h +++ /dev/null @@ -1,240 +0,0 @@ -/* - * 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: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT - * OWNER 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. - */ - -#ifndef PlatformContextSkia_h -#define PlatformContextSkia_h - -#include "GraphicsContext.h" -#include "Noncopyable.h" - -#include "SkDashPathEffect.h" -#include "SkDrawLooper.h" -#include "SkPaint.h" -#include "SkPath.h" -#include "skia/ext/platform_canvas.h" - -#include <wtf/Vector.h> - -namespace WebCore { - -enum CompositeOperator; -class DrawingBuffer; -class GLES2Canvas; -class GraphicsContext3D; -class Texture; - -// This class holds the platform-specific state for GraphicsContext. We put -// most of our Skia wrappers on this class. In theory, a lot of this stuff could -// be moved to GraphicsContext directly, except that some code external to this -// would like to poke at our graphics layer as well (like the Image and Font -// stuff, which needs some amount of our wrappers and state around SkCanvas). -// -// So in general, this class uses just Skia types except when there's no easy -// conversion. GraphicsContext is responsible for converting the WebKit types to -// Skia types and setting up the eventual call to the Skia functions. -// -// This class then keeps track of all the current Skia state. WebKit expects -// that the graphics state that is pushed and popped by save() and restore() -// includes things like colors and pen styles. Skia does this differently, where -// push and pop only includes transforms and bitmaps, and the application is -// responsible for managing the painting state which is store in separate -// SkPaint objects. This class provides the adaptor that allows the painting -// state to be pushed and popped along with the bitmap. -class PlatformContextSkia : public Noncopyable { -public: - // For printing, there shouldn't be any canvas. canvas can be NULL. If you - // supply a NULL canvas, you can also call setCanvas later. - PlatformContextSkia(skia::PlatformCanvas*); - ~PlatformContextSkia(); - - // Sets the canvas associated with this context. Use when supplying NULL - // to the constructor. - void setCanvas(skia::PlatformCanvas*); - - // If false we're rendering to a GraphicsContext for a web page, if false - // we're not (as is the case when rendering to a canvas object). - // If this is true the contents have not been marked up with the magic - // color and all text drawing needs to go to a layer so that the alpha is - // correctly updated. - void setDrawingToImageBuffer(bool); - bool isDrawingToImageBuffer() const; - - void save(); - void restore(); - - // Begins a layer that is clipped to the image |imageBuffer| at the location - // |rect|. This layer is implicitly restored when the next restore is - // invoked. - // NOTE: |imageBuffer| may be deleted before the |restore| is invoked. - void beginLayerClippedToImage(const FloatRect&, const ImageBuffer*); - void clipPathAntiAliased(const SkPath&); - - // Sets up the common flags on a paint for antialiasing, effects, etc. - // This is implicitly called by setupPaintFill and setupPaintStroke, but - // you may wish to call it directly sometimes if you don't want that other - // behavior. - void setupPaintCommon(SkPaint*) const; - - // Sets up the paint for the current fill style. - void setupPaintForFilling(SkPaint*) const; - - // Sets up the paint for stroking. Returns an int representing the width of - // the pen, or 1 if the pen's width is 0 if a non-zero length is provided, - // the number of dashes/dots on a dashed/dotted line will be adjusted to - // start and end that length with a dash/dot. - float setupPaintForStroking(SkPaint*, SkRect*, int length) const; - - // State setting functions. - void setDrawLooper(SkDrawLooper*); // Note: takes an additional ref. - void setMiterLimit(float); - void setAlpha(float); - void setLineCap(SkPaint::Cap); - void setLineJoin(SkPaint::Join); - void setFillRule(SkPath::FillType); - void setXfermodeMode(SkXfermode::Mode); - void setFillColor(SkColor); - void setFillShader(SkShader*); - void setStrokeStyle(StrokeStyle); - void setStrokeColor(SkColor); - void setStrokeThickness(float thickness); - void setStrokeShader(SkShader*); - void setTextDrawingMode(TextDrawingModeFlags mode); - void setUseAntialiasing(bool enable); - void setDashPathEffect(SkDashPathEffect*); - - SkDrawLooper* getDrawLooper() const; - StrokeStyle getStrokeStyle() const; - float getStrokeThickness() const; - TextDrawingModeFlags getTextDrawingMode() const; - float getAlpha() const; - int getNormalizedAlpha() const; - - void beginPath(); - void addPath(const SkPath&); - SkPath currentPathInLocalCoordinates() const; - - void canvasClipPath(const SkPath&); - - // Returns the fill color. The returned color has it's alpha adjusted - // by the current alpha. - SkColor effectiveFillColor() const; - - // Returns the stroke color. The returned color has it's alpha adjusted - // by the current alpha. - SkColor effectiveStrokeColor() const; - - skia::PlatformCanvas* canvas() { return m_canvas; } - - InterpolationQuality interpolationQuality() const; - void setInterpolationQuality(InterpolationQuality interpolationQuality); - - // FIXME: This should be pushed down to GraphicsContext. - void drawRect(SkRect rect); - - // FIXME: I'm still unsure how I will serialize this call. - void paintSkPaint(const SkRect&, const SkPaint&); - - const SkBitmap* bitmap() const; - - // Returns the canvas used for painting, NOT guaranteed to be non-NULL. - // - // Warning: This function is deprecated so the users are reminded that they - // should use this layer of indirection instead of using the canvas - // directly. This is to help with the eventual serialization. - skia::PlatformCanvas* canvas() const; - - // Returns if the context is a printing context instead of a display - // context. Bitmap shouldn't be resampled when printing to keep the best - // possible quality. - bool isPrinting(); - - void getImageResamplingHint(IntSize* srcSize, FloatSize* dstSize) const; - void setImageResamplingHint(const IntSize& srcSize, const FloatSize& dstSize); - void clearImageResamplingHint(); - bool hasImageResamplingHint() const; - - bool canAccelerate() const; - bool canvasClipApplied() const; - bool useGPU() { return m_useGPU; } - void setSharedGraphicsContext3D(SharedGraphicsContext3D*, DrawingBuffer*, const IntSize&); -#if ENABLE(ACCELERATED_2D_CANVAS) - GLES2Canvas* gpuCanvas() const { return m_gpuCanvas.get(); } -#else - GLES2Canvas* gpuCanvas() const { return 0; } -#endif - // Call these before making a call that manipulates the underlying - // skia::PlatformCanvas or WebCore::GLES2Canvas - void prepareForSoftwareDraw() const; - void prepareForHardwareDraw() const; - // Call to force the skia::PlatformCanvas to contain all rendering results. - void syncSoftwareCanvas() const; - void markDirtyRect(const IntRect& rect); - -private: - // Used when restoring and the state has an image clip. Only shows the pixels in - // m_canvas that are also in imageBuffer. - void applyClipFromImage(const FloatRect&, const SkBitmap&); - void applyAntiAliasedClipPaths(WTF::Vector<SkPath>& paths); - - void uploadSoftwareToHardware(CompositeOperator) const; - void readbackHardwareToSoftware() const; - - // Defines drawing style. - struct State; - - // NULL indicates painting is disabled. Never delete this object. - skia::PlatformCanvas* m_canvas; - - // States stack. Enables local drawing state change with save()/restore() - // calls. - WTF::Vector<State> m_stateStack; - // Pointer to the current drawing state. This is a cached value of - // mStateStack.back(). - State* m_state; - - // Current path in global coordinates. - SkPath m_path; - - // Stores image sizes for a hint to compute image resampling modes. - // Values are used in ImageSkia.cpp - IntSize m_imageResamplingHintSrcSize; - FloatSize m_imageResamplingHintDstSize; - bool m_drawingToImageBuffer; - bool m_useGPU; -#if ENABLE(ACCELERATED_2D_CANVAS) - OwnPtr<GLES2Canvas> m_gpuCanvas; - mutable RefPtr<Texture> m_uploadTexture; -#endif - mutable enum { None, Software, Mixed, Hardware } m_backingStoreState; - mutable IntRect m_softwareDirtyRect; -}; - -} -#endif // PlatformContextSkia_h diff --git a/WebCore/platform/graphics/skia/PlatformGraphics.h b/WebCore/platform/graphics/skia/PlatformGraphics.h deleted file mode 100644 index 4ae8835..0000000 --- a/WebCore/platform/graphics/skia/PlatformGraphics.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT - * OWNER 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. - */ - -#ifndef PlatformGraphics_h -#define PlatformGraphics_h - -typedef class SkShader* PlatformGradient; -typedef class SkShader* PlatformPattern; - -#endif // PlatformGraphics_h diff --git a/WebCore/platform/graphics/skia/SkiaFontWin.cpp b/WebCore/platform/graphics/skia/SkiaFontWin.cpp deleted file mode 100644 index 5046c50..0000000 --- a/WebCore/platform/graphics/skia/SkiaFontWin.cpp +++ /dev/null @@ -1,358 +0,0 @@ -/* - * 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: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT - * OWNER 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 "SkiaFontWin.h" - -#include "AffineTransform.h" -#include "PlatformContextSkia.h" -#include "Gradient.h" -#include "Pattern.h" -#include "SkCanvas.h" -#include "SkPaint.h" -#include "SkShader.h" - -#include <wtf/ListHashSet.h> -#include <wtf/Vector.h> - -namespace WebCore { - -struct CachedOutlineKey { - CachedOutlineKey() : font(0), glyph(0), path(0) {} - CachedOutlineKey(HFONT f, WORD g) : font(f), glyph(g), path(0) {} - - HFONT font; - WORD glyph; - - // The lifetime of this pointer is managed externally to this class. Be sure - // to call DeleteOutline to remove items. - SkPath* path; -}; - -const bool operator==(const CachedOutlineKey& a, const CachedOutlineKey& b) -{ - return a.font == b.font && a.glyph == b.glyph; -} - -struct CachedOutlineKeyHash { - static unsigned hash(const CachedOutlineKey& key) - { - unsigned keyBytes; - memcpy(&keyBytes, &key.font, sizeof(unsigned)); - return keyBytes + key.glyph; - } - - static unsigned equal(const CachedOutlineKey& a, const CachedOutlineKey& b) - { - return a.font == b.font && a.glyph == b.glyph; - } - - static const bool safeToCompareToEmptyOrDeleted = true; -}; - -// The global number of glyph outlines we'll cache. -static const int outlineCacheSize = 256; - -typedef ListHashSet<CachedOutlineKey, outlineCacheSize+1, CachedOutlineKeyHash> OutlineCache; - -// FIXME: Convert from static constructor to accessor function. WebCore tries to -// avoid global constructors to save on start-up time. -static OutlineCache outlineCache; - -static SkScalar FIXEDToSkScalar(FIXED fixed) -{ - SkFixed skFixed; - memcpy(&skFixed, &fixed, sizeof(SkFixed)); - return SkFixedToScalar(skFixed); -} - -// Removes the given key from the cached outlines, also deleting the path. -static void deleteOutline(OutlineCache::iterator deleteMe) -{ - delete deleteMe->path; - outlineCache.remove(deleteMe); -} - -static void addPolyCurveToPath(const TTPOLYCURVE* polyCurve, SkPath* path) -{ - switch (polyCurve->wType) { - case TT_PRIM_LINE: - for (WORD i = 0; i < polyCurve->cpfx; i++) { - path->lineTo(FIXEDToSkScalar(polyCurve->apfx[i].x), -FIXEDToSkScalar(polyCurve->apfx[i].y)); - } - break; - - case TT_PRIM_QSPLINE: - // FIXME: doesn't this duplicate points if we do the loop > once? - for (WORD i = 0; i < polyCurve->cpfx - 1; i++) { - SkScalar bx = FIXEDToSkScalar(polyCurve->apfx[i].x); - SkScalar by = FIXEDToSkScalar(polyCurve->apfx[i].y); - - SkScalar cx = FIXEDToSkScalar(polyCurve->apfx[i + 1].x); - SkScalar cy = FIXEDToSkScalar(polyCurve->apfx[i + 1].y); - if (i < polyCurve->cpfx - 2) { - // We're not the last point, compute C. - cx = SkScalarAve(bx, cx); - cy = SkScalarAve(by, cy); - } - - // Need to flip the y coordinates since the font's coordinate system is - // flipped from ours vertically. - path->quadTo(bx, -by, cx, -cy); - } - break; - - case TT_PRIM_CSPLINE: - // FIXME - break; - } -} - -// The size of the glyph path buffer. -static const int glyphPathBufferSize = 4096; - -// Fills the given SkPath with the outline for the given glyph index. The font -// currently selected into the given DC is used. Returns true on success. -static bool getPathForGlyph(HDC dc, WORD glyph, SkPath* path) -{ - char buffer[glyphPathBufferSize]; - GLYPHMETRICS gm; - MAT2 mat = {{0, 1}, {0, 0}, {0, 0}, {0, 1}}; // Each one is (fract,value). - - DWORD totalSize = GetGlyphOutlineW(dc, glyph, GGO_GLYPH_INDEX | GGO_NATIVE, - &gm, glyphPathBufferSize, buffer, &mat); - if (totalSize == GDI_ERROR) - return false; - - const char* curGlyph = buffer; - const char* endGlyph = &buffer[totalSize]; - while (curGlyph < endGlyph) { - const TTPOLYGONHEADER* polyHeader = - reinterpret_cast<const TTPOLYGONHEADER*>(curGlyph); - path->moveTo(FIXEDToSkScalar(polyHeader->pfxStart.x), - -FIXEDToSkScalar(polyHeader->pfxStart.y)); - - const char* curPoly = curGlyph + sizeof(TTPOLYGONHEADER); - const char* endPoly = curGlyph + polyHeader->cb; - while (curPoly < endPoly) { - const TTPOLYCURVE* polyCurve = - reinterpret_cast<const TTPOLYCURVE*>(curPoly); - addPolyCurveToPath(polyCurve, path); - curPoly += sizeof(WORD) * 2 + sizeof(POINTFX) * polyCurve->cpfx; - } - path->close(); - curGlyph += polyHeader->cb; - } - - return true; -} - -// Returns a SkPath corresponding to the give glyph in the given font. The font -// should be selected into the given DC. The returned path is owned by the -// hashtable. Returns 0 on error. -const SkPath* SkiaWinOutlineCache::lookupOrCreatePathForGlyph(HDC hdc, HFONT font, WORD glyph) -{ - CachedOutlineKey key(font, glyph); - OutlineCache::iterator found = outlineCache.find(key); - if (found != outlineCache.end()) { - // Keep in MRU order by removing & reinserting the value. - key = *found; - outlineCache.remove(found); - outlineCache.add(key); - return key.path; - } - - key.path = new SkPath; - if (!getPathForGlyph(hdc, glyph, key.path)) - return 0; - - if (outlineCache.size() > outlineCacheSize) - // The cache is too big, find the oldest value (first in the list). - deleteOutline(outlineCache.begin()); - - outlineCache.add(key); - return key.path; -} - - -void SkiaWinOutlineCache::removePathsForFont(HFONT hfont) -{ - // ListHashSet isn't the greatest structure for deleting stuff out of, but - // removing entries will be relatively rare (we don't remove fonts much, nor - // do we draw out own glyphs using these routines much either). - // - // We keep a list of all glyphs we're removing which we do in a separate - // pass. - Vector<CachedOutlineKey> outlinesToDelete; - for (OutlineCache::iterator i = outlineCache.begin(); - i != outlineCache.end(); ++i) - outlinesToDelete.append(*i); - - for (Vector<CachedOutlineKey>::iterator i = outlinesToDelete.begin(); - i != outlinesToDelete.end(); ++i) - deleteOutline(outlineCache.find(*i)); -} - -bool windowsCanHandleDrawTextShadow(GraphicsContext *context) -{ - FloatSize shadowOffset; - float shadowBlur; - Color shadowColor; - ColorSpace shadowColorSpace; - - bool hasShadow = context->getShadow(shadowOffset, shadowBlur, shadowColor, shadowColorSpace); - return (hasShadow && (shadowBlur == 0) && (shadowColor.alpha() == 255) && (context->fillColor().alpha() == 255)); -} - -bool windowsCanHandleTextDrawing(GraphicsContext* context) -{ - // Check for non-translation transforms. Sometimes zooms will look better in - // Skia, and sometimes better in Windows. The main problem is that zooming - // in using Skia will show you the hinted outlines for the smaller size, - // which look weird. All else being equal, it's better to use Windows' text - // drawing, so we don't check for zooms. - const AffineTransform& matrix = context->getCTM(); - if (matrix.b() != 0 || matrix.c() != 0) // Check for skew. - return false; - - // Check for stroke effects. - if (context->platformContext()->getTextDrawingMode() != TextModeFill) - return false; - - // Check for gradients. - if (context->fillGradient() || context->strokeGradient()) - return false; - - // Check for patterns. - if (context->fillPattern() || context->strokePattern()) - return false; - - // Check for shadow effects. - if (context->platformContext()->getDrawLooper() && (!windowsCanHandleDrawTextShadow(context))) - return false; - - return true; -} - -// Draws the given text string using skia. Note that gradient or -// pattern may be NULL, in which case a solid colour is used. -static bool skiaDrawText(HFONT hfont, - HDC dc, - SkCanvas* canvas, - const SkPoint& point, - SkPaint* paint, - const WORD* glyphs, - const int* advances, - const GOFFSET* offsets, - int numGlyphs) -{ - float x = point.fX, y = point.fY; - - for (int i = 0; i < numGlyphs; i++) { - const SkPath* path = SkiaWinOutlineCache::lookupOrCreatePathForGlyph(dc, hfont, glyphs[i]); - if (!path) - return false; - - float offsetX = 0.0f, offsetY = 0.0f; - if (offsets && (offsets[i].du != 0 || offsets[i].dv != 0)) { - offsetX = offsets[i].du; - offsetY = offsets[i].dv; - } - - SkPath newPath; - newPath.addPath(*path, x + offsetX, y + offsetY); - canvas->drawPath(newPath, *paint); - - x += advances[i]; - } - - return true; -} - -bool paintSkiaText(GraphicsContext* context, - HFONT hfont, - int numGlyphs, - const WORD* glyphs, - const int* advances, - const GOFFSET* offsets, - const SkPoint* origin) -{ - HDC dc = GetDC(0); - HGDIOBJ oldFont = SelectObject(dc, hfont); - - PlatformContextSkia* platformContext = context->platformContext(); - TextDrawingModeFlags textMode = platformContext->getTextDrawingMode(); - - // Filling (if necessary). This is the common case. - SkPaint paint; - platformContext->setupPaintForFilling(&paint); - paint.setFlags(SkPaint::kAntiAlias_Flag); - bool didFill = false; - - if ((textMode & TextModeFill) && SkColorGetA(paint.getColor())) { - if (!skiaDrawText(hfont, dc, platformContext->canvas(), *origin, &paint, - &glyphs[0], &advances[0], &offsets[0], numGlyphs)) - return false; - didFill = true; - } - - // Stroking on top (if necessary). - if ((textMode & TextModeStroke) - && platformContext->getStrokeStyle() != NoStroke - && platformContext->getStrokeThickness() > 0) { - - paint.reset(); - platformContext->setupPaintForStroking(&paint, 0, 0); - paint.setFlags(SkPaint::kAntiAlias_Flag); - if (didFill) { - // If there is a shadow and we filled above, there will already be - // a shadow. We don't want to draw it again or it will be too dark - // and it will go on top of the fill. - // - // Note that this isn't strictly correct, since the stroke could be - // very thick and the shadow wouldn't account for this. The "right" - // thing would be to draw to a new layer and then draw that layer - // with a shadow. But this is a lot of extra work for something - // that isn't normally an issue. - SkSafeUnref(paint.setLooper(0)); - } - - if (!skiaDrawText(hfont, dc, platformContext->canvas(), *origin, &paint, - &glyphs[0], &advances[0], &offsets[0], numGlyphs)) - return false; - } - - SelectObject(dc, oldFont); - ReleaseDC(0, dc); - - return true; -} - -} // namespace WebCore diff --git a/WebCore/platform/graphics/skia/SkiaFontWin.h b/WebCore/platform/graphics/skia/SkiaFontWin.h deleted file mode 100644 index 40bee62..0000000 --- a/WebCore/platform/graphics/skia/SkiaFontWin.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * 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: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT - * OWNER 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. - */ - -#ifndef SkiaFontWin_h -#define SkiaFontWin_h - -#include <windows.h> -#include <usp10.h> - -class SkPath; -class SkPoint; - -namespace WebCore { - -class GraphicsContext; -class PlatformContextSkia; - -// FIXME: Rename file to SkiaWinOutlineCache -class SkiaWinOutlineCache { -public: - static const SkPath* lookupOrCreatePathForGlyph(HDC, HFONT, WORD); - // Removes any cached glyphs from the outline cache corresponding to the - // given font handle. - static void removePathsForFont(HFONT); - -private: - SkiaWinOutlineCache(); -}; - -// The functions below are used for more complex font drawing (effects such as -// stroking and more complex transforms) than Windows supports directly. Since -// Windows drawing is faster you should use windowsCanHandleTextDrawing first to -// check if using Skia is required at all. -// Note that the text will look different (no ClearType) so this should only be -// used when necessary. -// -// When you call a Skia* text drawing function, various glyph outlines will be -// cached. As a result, you should call SkiaWinOutlineCache::removePathsForFont -// when the font is destroyed so that the cache does not outlive the font (since -// the HFONTs are recycled). -// -// Remember that Skia's text drawing origin is the baseline, like WebKit, not -// the top, like Windows. - -// Returns true if the fillColor and shadowColor are opaque and the text-shadow -// is not blurred. -bool windowsCanHandleDrawTextShadow(GraphicsContext*); - -// Returns true if advanced font rendering is recommended. -bool windowsCanHandleTextDrawing(GraphicsContext*); - -// Note that the offsets parameter is optional. If not NULL it represents a -// per glyph offset (such as returned by ScriptPlace Windows API function). -// -// Returns true of the text was drawn successfully. False indicates an error -// from Windows. -bool paintSkiaText(GraphicsContext* graphicsContext, - HFONT hfont, - int numGlyphs, - const WORD* glyphs, - const int* advances, - const GOFFSET* offsets, - const SkPoint* origin); - -} // namespace WebCore - -#endif // SkiaFontWin_h diff --git a/WebCore/platform/graphics/skia/SkiaUtils.cpp b/WebCore/platform/graphics/skia/SkiaUtils.cpp deleted file mode 100644 index da83793..0000000 --- a/WebCore/platform/graphics/skia/SkiaUtils.cpp +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright (c) 2006,2007,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: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT - * OWNER 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 "SkiaUtils.h" - -#include "ImageBuffer.h" -#include "SharedBuffer.h" -#include "SkCanvas.h" -#include "SkColorPriv.h" -#include "SkMatrix.h" -#include "SkRegion.h" -#include "SkUnPreMultiply.h" - -namespace WebCore { - -#if PLATFORM(ANDROID) -static const struct CompositOpToSkiaMode { - uint8_t mCompositOp; - uint8_t mMode; -} gMapCompositOpsToSkiaModes[] = { - { CompositeClear, SkXfermode::kClear_Mode }, - { CompositeCopy, SkXfermode::kSrc_Mode }, - { CompositeSourceOver, SkXfermode::kSrcOver_Mode }, - { CompositeSourceIn, SkXfermode::kSrcIn_Mode }, - { CompositeSourceOut, SkXfermode::kSrcOut_Mode }, - { CompositeSourceAtop, SkXfermode::kSrcATop_Mode }, - { CompositeDestinationOver, SkXfermode::kDstOver_Mode }, - { CompositeDestinationIn, SkXfermode::kDstIn_Mode }, - { CompositeDestinationOut, SkXfermode::kDstOut_Mode }, - { CompositeDestinationAtop, SkXfermode::kDstATop_Mode }, - { CompositeXOR, SkXfermode::kXor_Mode }, - // need more details on the composite modes to be sure these are right - { CompositePlusDarker, SkXfermode::kDarken_Mode }, - { CompositeHighlight, SkXfermode::kSrcOver_Mode }, // TODO - { CompositePlusLighter, SkXfermode::kPlus_Mode } -}; - -SkXfermode::Mode WebCoreCompositeToSkiaCOmposite(CompositeOperator op) -{ - const CompositOpToSkiaMode* table = gMapCompositOpsToSkiaModes; - - for (unsigned i = 0; i < SK_ARRAY_COUNT(gMapCompositOpsToSkiaModes); i++) { - if (table[i].mCompositOp == op) - return (SkXfermode::Mode)table[i].mMode; - } - - SkDEBUGF(("GraphicsContext::setCompositeOperation uknown CompositeOperator %d\n", op)); - return SkXfermode::kSrcOver_Mode; // fall-back -} - -#endif - -static const struct CompositOpToXfermodeMode { - uint8_t mCompositOp; - uint8_t m_xfermodeMode; -} gMapCompositOpsToXfermodeModes[] = { - { CompositeClear, SkXfermode::kClear_Mode }, - { CompositeCopy, SkXfermode::kSrc_Mode }, - { CompositeSourceOver, SkXfermode::kSrcOver_Mode }, - { CompositeSourceIn, SkXfermode::kSrcIn_Mode }, - { CompositeSourceOut, SkXfermode::kSrcOut_Mode }, - { CompositeSourceAtop, SkXfermode::kSrcATop_Mode }, - { CompositeDestinationOver, SkXfermode::kDstOver_Mode }, - { CompositeDestinationIn, SkXfermode::kDstIn_Mode }, - { CompositeDestinationOut, SkXfermode::kDstOut_Mode }, - { CompositeDestinationAtop, SkXfermode::kDstATop_Mode }, - { CompositeXOR, SkXfermode::kXor_Mode }, - { CompositePlusDarker, SkXfermode::kDarken_Mode }, - { CompositeHighlight, SkXfermode::kSrcOver_Mode }, // TODO - { CompositePlusLighter, SkXfermode::kPlus_Mode } -}; - -SkXfermode::Mode WebCoreCompositeToSkiaComposite(CompositeOperator op) -{ - const CompositOpToXfermodeMode* table = gMapCompositOpsToXfermodeModes; - - for (unsigned i = 0; i < SK_ARRAY_COUNT(gMapCompositOpsToXfermodeModes); i++) { - if (table[i].mCompositOp == op) - return (SkXfermode::Mode)table[i].m_xfermodeMode; - } - - SkDEBUGF(("GraphicsContext::setPlatformCompositeOperation unknown CompositeOperator %d\n", op)); - return SkXfermode::kSrcOver_Mode; // fall-back -} - -#if PLATFORM(ANDROID) -Color SkPMColorToWebCoreColor(SkPMColor pm) -{ - SkColor c = SkUnPreMultiply::PMColorToColor(pm); - // need the cast to find the right constructor - return WebCore::Color((int)SkColorGetR(c), (int)SkColorGetG(c), - (int)SkColorGetB(c), (int)SkColorGetA(c)); -} -#else -static U8CPU InvScaleByte(U8CPU component, uint32_t scale) -{ - SkASSERT(component == (uint8_t)component); - return (component * scale + 0x8000) >> 16; -} - -SkColor SkPMColorToColor(SkPMColor pm) -{ - if (!pm) - return 0; - unsigned a = SkGetPackedA32(pm); - if (!a) { - // A zero alpha value when there are non-zero R, G, or B channels is an - // invalid premultiplied color (since all channels should have been - // multiplied by 0 if a=0). - SkASSERT(false); - // In production, return 0 to protect against division by zero. - return 0; - } - - uint32_t scale = (255 << 16) / a; - - return SkColorSetARGB(a, - InvScaleByte(SkGetPackedR32(pm), scale), - InvScaleByte(SkGetPackedG32(pm), scale), - InvScaleByte(SkGetPackedB32(pm), scale)); -} - -Color SkPMColorToWebCoreColor(SkPMColor pm) -{ - return SkPMColorToColor(pm); -} -#endif - -void IntersectRectAndRegion(const SkRegion& region, const SkRect& srcRect, SkRect* destRect) { - // The cliperator requires an int rect, so we round out. - SkIRect srcRectRounded; - srcRect.roundOut(&srcRectRounded); - - // The Cliperator will iterate over a bunch of rects where our transformed - // rect and the clipping region (which may be non-square) overlap. - SkRegion::Cliperator cliperator(region, srcRectRounded); - if (cliperator.done()) { - destRect->setEmpty(); - return; - } - - // Get the union of all visible rects in the clip that overlap our bitmap. - SkIRect currentVisibleRect = cliperator.rect(); - cliperator.next(); - while (!cliperator.done()) { - currentVisibleRect.join(cliperator.rect()); - cliperator.next(); - } - - destRect->set(currentVisibleRect); -} - -void ClipRectToCanvas(const SkCanvas& canvas, const SkRect& srcRect, SkRect* destRect) { - // Translate into the canvas' coordinate space. This is where the clipping - // region applies. - SkRect transformedSrc; - canvas.getTotalMatrix().mapRect(&transformedSrc, srcRect); - - // Do the intersection. - SkRect transformedDest; - IntersectRectAndRegion(canvas.getTotalClip(), transformedSrc, &transformedDest); - - // Now transform it back into world space. - SkMatrix inverseTransform; - canvas.getTotalMatrix().invert(&inverseTransform); - inverseTransform.mapRect(destRect, transformedDest); -} - -bool SkPathContainsPoint(SkPath* originalPath, const FloatPoint& point, SkPath::FillType ft) -{ - SkRegion rgn; - SkRegion clip; - - SkPath::FillType originalFillType = originalPath->getFillType(); - - const SkPath* path = originalPath; - SkPath scaledPath; - int scale = 1; - - SkRect bounds = originalPath->getBounds(); - - // We can immediately return false if the point is outside the bounding - // rect. We don't use bounds.contains() here, since it would exclude - // points on the right and bottom edges of the bounding rect, and we want - // to include them. - SkScalar fX = SkFloatToScalar(point.x()); - SkScalar fY = SkFloatToScalar(point.y()); - if (fX < bounds.fLeft || fX > bounds.fRight || fY < bounds.fTop || fY > bounds.fBottom) - return false; - - originalPath->setFillType(ft); - - // Skia has trouble with coordinates close to the max signed 16-bit values - // If we have those, we need to scale. - // - // TODO: remove this code once Skia is patched to work properly with large - // values - const SkScalar kMaxCoordinate = SkIntToScalar(1<<15); - SkScalar biggestCoord = std::max(std::max(std::max(bounds.fRight, bounds.fBottom), -bounds.fLeft), -bounds.fTop); - - if (biggestCoord > kMaxCoordinate) { - scale = SkScalarCeil(SkScalarDiv(biggestCoord, kMaxCoordinate)); - - SkMatrix m; - m.setScale(SkScalarInvert(SkIntToScalar(scale)), SkScalarInvert(SkIntToScalar(scale))); - originalPath->transform(m, &scaledPath); - path = &scaledPath; - } - - int x = static_cast<int>(floorf(point.x() / scale)); - int y = static_cast<int>(floorf(point.y() / scale)); - clip.setRect(x - 1, y - 1, x + 1, y + 1); - - bool contains = rgn.setPath(*path, clip); - - originalPath->setFillType(originalFillType); - return contains; -} - -GraphicsContext* scratchContext() -{ - static ImageBuffer* scratch = ImageBuffer::create(IntSize(1, 1)).leakPtr(); - // We don't bother checking for failure creating the ImageBuffer, since our - // ImageBuffer initializer won't fail. - return scratch->context(); -} - -} // namespace WebCore diff --git a/WebCore/platform/graphics/skia/SkiaUtils.h b/WebCore/platform/graphics/skia/SkiaUtils.h deleted file mode 100644 index 681dcd5..0000000 --- a/WebCore/platform/graphics/skia/SkiaUtils.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2006,2007,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: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT - * OWNER 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. - */ - -// All of the functions in this file should move to new homes and this file should be deleted. - -#ifndef SkiaUtils_h -#define SkiaUtils_h - -#include <wtf/MathExtras.h> -#include "GraphicsContext.h" -#include "SkPath.h" -#include "SkXfermode.h" - -class SkCanvas; -class SkRegion; - -namespace WebCore { - -SkXfermode::Mode WebCoreCompositeToSkiaComposite(CompositeOperator); - -// move this guy into SkColor.h -SkColor SkPMColorToColor(SkPMColor); - -// This should be an operator on Color -Color SkPMColorToWebCoreColor(SkPMColor); - -// Skia has problems when passed infinite, etc floats, filter them to 0. -inline SkScalar WebCoreFloatToSkScalar(float f) -{ - return SkFloatToScalar(isfinite(f) ? f : 0); -} - -inline SkScalar WebCoreDoubleToSkScalar(double d) -{ - return SkDoubleToScalar(isfinite(d) ? d : 0); -} - -// Computes the smallest rectangle that, which when drawn to the given canvas, -// will cover the same area as the source rectangle. It will clip to the canvas' -// clip, doing the necessary coordinate transforms. -// -// srcRect and destRect can be the same. -void ClipRectToCanvas(const SkCanvas&, const SkRect& srcRect, SkRect* destRect); - -// Determine if a given WebKit point is contained in a path -bool SkPathContainsPoint(SkPath*, const FloatPoint&, SkPath::FillType); - -// Returns a statically allocated 1x1 GraphicsContext intended for temporary -// operations. Please save() the state and restore() it when you're done with -// the context. -GraphicsContext* scratchContext(); - -} // namespace WebCore - -#endif // SkiaUtils_h diff --git a/WebCore/platform/graphics/skia/TransformationMatrixSkia.cpp b/WebCore/platform/graphics/skia/TransformationMatrixSkia.cpp deleted file mode 100644 index dc610d7..0000000 --- a/WebCore/platform/graphics/skia/TransformationMatrixSkia.cpp +++ /dev/null @@ -1,78 +0,0 @@ -// 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: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * 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. -// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT -// OWNER 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 "AffineTransform.h" -#include "TransformationMatrix.h" - -#include "SkiaUtils.h" - -namespace WebCore { - -TransformationMatrix::operator SkMatrix() const -{ - SkMatrix result; - - result.setScaleX(WebCoreDoubleToSkScalar(a())); - result.setSkewX(WebCoreDoubleToSkScalar(c())); - result.setTranslateX(WebCoreDoubleToSkScalar(e())); - - result.setScaleY(WebCoreDoubleToSkScalar(d())); - result.setSkewY(WebCoreDoubleToSkScalar(b())); - result.setTranslateY(WebCoreDoubleToSkScalar(f())); - - // FIXME: Set perspective properly. - result.setPerspX(0); - result.setPerspY(0); - result.set(SkMatrix::kMPersp2, SK_Scalar1); - - return result; -} - -AffineTransform::operator SkMatrix() const -{ - SkMatrix result; - - result.setScaleX(WebCoreDoubleToSkScalar(a())); - result.setSkewX(WebCoreDoubleToSkScalar(c())); - result.setTranslateX(WebCoreDoubleToSkScalar(e())); - - result.setScaleY(WebCoreDoubleToSkScalar(d())); - result.setSkewY(WebCoreDoubleToSkScalar(b())); - result.setTranslateY(WebCoreDoubleToSkScalar(f())); - - // FIXME: Set perspective properly. - result.setPerspX(0); - result.setPerspY(0); - result.set(SkMatrix::kMPersp2, SK_Scalar1); - - return result; -} - -} // namespace WebCore |