diff options
author | John Reck <jreck@google.com> | 2010-11-04 12:00:17 -0700 |
---|---|---|
committer | John Reck <jreck@google.com> | 2010-11-09 11:35:04 -0800 |
commit | e14391e94c850b8bd03680c23b38978db68687a8 (patch) | |
tree | 3fed87e6620fecaf3edc7259ae58a11662bedcb2 /WebCore/platform/graphics | |
parent | 1bd705833a68f07850cf7e204b26f8d328d16951 (diff) | |
download | external_webkit-e14391e94c850b8bd03680c23b38978db68687a8.zip external_webkit-e14391e94c850b8bd03680c23b38978db68687a8.tar.gz external_webkit-e14391e94c850b8bd03680c23b38978db68687a8.tar.bz2 |
Merge Webkit at r70949: Initial merge by git.
Change-Id: I77b8645c083b5d0da8dba73ed01d4014aab9848e
Diffstat (limited to 'WebCore/platform/graphics')
85 files changed, 1614 insertions, 562 deletions
diff --git a/WebCore/platform/graphics/FontCache.cpp b/WebCore/platform/graphics/FontCache.cpp index ff865c2..149ea79 100644 --- a/WebCore/platform/graphics/FontCache.cpp +++ b/WebCore/platform/graphics/FontCache.cpp @@ -55,13 +55,14 @@ FontCache::FontCache() struct FontPlatformDataCacheKey : FastAllocBase { FontPlatformDataCacheKey(const AtomicString& family = AtomicString(), unsigned size = 0, unsigned weight = 0, bool italic = false, - bool isPrinterFont = false, FontRenderingMode renderingMode = NormalRenderingMode) + bool isPrinterFont = false, FontRenderingMode renderingMode = NormalRenderingMode, FontOrientation orientation = Horizontal) : m_size(size) , m_weight(weight) , m_family(family) , m_italic(italic) , m_printerFont(isPrinterFont) , m_renderingMode(renderingMode) + , m_orientation(orientation) { } @@ -72,7 +73,7 @@ struct FontPlatformDataCacheKey : FastAllocBase { { return equalIgnoringCase(m_family, other.m_family) && m_size == other.m_size && m_weight == other.m_weight && m_italic == other.m_italic && m_printerFont == other.m_printerFont && - m_renderingMode == other.m_renderingMode; + m_renderingMode == other.m_renderingMode && m_orientation == other.m_orientation; } unsigned m_size; @@ -81,6 +82,7 @@ struct FontPlatformDataCacheKey : FastAllocBase { bool m_italic; bool m_printerFont; FontRenderingMode m_renderingMode; + FontOrientation m_orientation; private: static unsigned hashTableDeletedSize() { return 0xFFFFFFFFU; } @@ -92,9 +94,9 @@ inline unsigned computeHash(const FontPlatformDataCacheKey& fontKey) CaseFoldingHash::hash(fontKey.m_family), fontKey.m_size, fontKey.m_weight, - static_cast<unsigned>(fontKey.m_italic) << 2 | static_cast<unsigned>(fontKey.m_printerFont) << 1 | static_cast<unsigned>(fontKey.m_renderingMode) + static_cast<unsigned>(fontKey.m_orientation) << 3 | static_cast<unsigned>(fontKey.m_italic) << 2 | static_cast<unsigned>(fontKey.m_printerFont) << 1 | static_cast<unsigned>(fontKey.m_renderingMode) }; - return StringImpl::computeHash(reinterpret_cast<UChar*>(hashCodes), sizeof(hashCodes) / sizeof(UChar)); + return WTF::StringHasher::createBlobHash<sizeof(hashCodes)>(hashCodes); } struct FontPlatformDataCacheKeyHash { @@ -191,7 +193,7 @@ FontPlatformData* FontCache::getCachedFontPlatformData(const FontDescription& fo } FontPlatformDataCacheKey key(familyName, fontDescription.computedPixelSize(), fontDescription.weight(), fontDescription.italic(), - fontDescription.usePrinterFont(), fontDescription.renderingMode()); + fontDescription.usePrinterFont(), fontDescription.renderingMode(), fontDescription.orientation()); FontPlatformData* result = 0; bool foundResult; FontPlatformDataCache::iterator it = gFontPlatformDataCache->find(key); diff --git a/WebCore/platform/graphics/FontDescription.h b/WebCore/platform/graphics/FontDescription.h index 48fcaad..12900bf 100644 --- a/WebCore/platform/graphics/FontDescription.h +++ b/WebCore/platform/graphics/FontDescription.h @@ -26,6 +26,7 @@ #define FontDescription_h #include "FontFamily.h" +#include "FontOrientation.h" #include "FontRenderingMode.h" #include "FontSmoothingMode.h" #include "FontTraitsMask.h" @@ -55,6 +56,7 @@ public: FontDescription() : m_specifiedSize(0) , m_computedSize(0) + , m_orientation(Horizontal) , m_italic(false) , m_smallCaps(false) , m_isAbsoluteSize(false) @@ -94,6 +96,7 @@ public: FontTraitsMask traitsMask() const; bool isSpecifiedFont() const { return m_isSpecifiedFont; } + FontOrientation orientation() const { return m_orientation; } void setFamily(const FontFamily& family) { m_familyList = family; } void setComputedSize(float s) { m_computedSize = s; } @@ -113,6 +116,7 @@ public: void setFontSmoothing(FontSmoothingMode smoothing) { m_fontSmoothing = smoothing; } void setTextRenderingMode(TextRenderingMode rendering) { m_textRendering = rendering; } void setIsSpecifiedFont(bool isSpecifiedFont) { m_isSpecifiedFont = isSpecifiedFont; } + void setOrientation(FontOrientation orientation) { m_orientation = orientation; } private: FontFamily m_familyList; // The list of font families to be used. @@ -121,6 +125,8 @@ private: // rounding, minimum font sizes, and zooming. float m_computedSize; // Computed size adjusted for the minimum font size and the zoom factor. + FontOrientation m_orientation; + bool m_italic : 1; bool m_smallCaps : 1; bool m_isAbsoluteSize : 1; // Whether or not CSS specified an explicit size @@ -155,7 +161,8 @@ inline bool FontDescription::operator==(const FontDescription& other) const && m_keywordSize == other.m_keywordSize && m_fontSmoothing == other.m_fontSmoothing && m_textRendering == other.m_textRendering - && m_isSpecifiedFont == other.m_isSpecifiedFont; + && m_isSpecifiedFont == other.m_isSpecifiedFont + && m_orientation == other.m_orientation; } } diff --git a/WebCore/platform/graphics/FontOrientation.h b/WebCore/platform/graphics/FontOrientation.h new file mode 100644 index 0000000..12cf5c1 --- /dev/null +++ b/WebCore/platform/graphics/FontOrientation.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2010 Apple 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. + */ + +#ifndef FontOrientation_h +#define FontOrientation_h + +namespace WebCore { + +enum FontOrientation { Horizontal, Vertical }; + +} // namespace WebCore + +#endif // FontOrientation_h diff --git a/WebCore/platform/graphics/Gradient.cpp b/WebCore/platform/graphics/Gradient.cpp index f9427fb..6cb0ef1 100644 --- a/WebCore/platform/graphics/Gradient.cpp +++ b/WebCore/platform/graphics/Gradient.cpp @@ -196,6 +196,16 @@ int Gradient::findStop(float value) const return m_lastStop; } +bool Gradient::hasAlpha() const +{ + for (size_t i = 0; i < m_stops.size(); i++) { + if (m_stops[i].alpha < 1) + return true; + } + + return false; +} + void Gradient::setSpreadMethod(GradientSpreadMethod spreadMethod) { // FIXME: Should it become necessary, allow calls to this method after m_gradient has been set. diff --git a/WebCore/platform/graphics/Gradient.h b/WebCore/platform/graphics/Gradient.h index 0a69fa2..153e1e9 100644 --- a/WebCore/platform/graphics/Gradient.h +++ b/WebCore/platform/graphics/Gradient.h @@ -92,6 +92,7 @@ namespace WebCore { void addColorStop(float, const Color&); void getColor(float value, float* r, float* g, float* b, float* a) const; + bool hasAlpha() const; bool isRadial() const { return m_radial; } bool isZeroSize() const { return m_p0.x() == m_p1.x() && m_p0.y() == m_p1.y() && (!m_radial || m_r0 == m_r1); } diff --git a/WebCore/platform/graphics/GraphicsContext3D.cpp b/WebCore/platform/graphics/GraphicsContext3D.cpp index d2e9057..b8c66d5 100644 --- a/WebCore/platform/graphics/GraphicsContext3D.cpp +++ b/WebCore/platform/graphics/GraphicsContext3D.cpp @@ -945,6 +945,8 @@ static void doPacking(const void* sourceData, doUnpackingAndPacking<uint16_t, DestType, unpackA16BigToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); break; } + default: + ASSERT(false); } } diff --git a/WebCore/platform/graphics/GraphicsContext3D.h b/WebCore/platform/graphics/GraphicsContext3D.h index d74c97c..20b4e2d 100644 --- a/WebCore/platform/graphics/GraphicsContext3D.h +++ b/WebCore/platform/graphics/GraphicsContext3D.h @@ -540,7 +540,7 @@ public: // uploading. This enum must be public because it is accessed // by non-member functions. enum SourceDataFormat { - kSourceFormatRGBA8, + kSourceFormatRGBA8 = 0, kSourceFormatRGBA16Little, kSourceFormatRGBA16Big, kSourceFormatRGB8, @@ -566,7 +566,8 @@ public: kSourceFormatAR16Big, kSourceFormatA8, kSourceFormatA16Little, - kSourceFormatA16Big + kSourceFormatA16Big, + kSourceFormatNumFormats }; //---------------------------------------------------------------------- diff --git a/WebCore/platform/graphics/GraphicsLayer.h b/WebCore/platform/graphics/GraphicsLayer.h index ad4d056..991ca32 100644 --- a/WebCore/platform/graphics/GraphicsLayer.h +++ b/WebCore/platform/graphics/GraphicsLayer.h @@ -40,6 +40,10 @@ #include <wtf/OwnPtr.h> #include <wtf/PassOwnPtr.h> +#if USE(TEXTURE_MAPPER) +#include "texmap/TextureMapperPlatformLayer.h" +#endif + #if PLATFORM(MAC) #ifdef __OBJC__ @class WebLayer; @@ -57,11 +61,21 @@ typedef WKCACFLayer PlatformLayer; typedef void* NativeLayer; } #elif PLATFORM(QT) +#if USE(TEXTURE_MAPPER) +namespace WebCore { +class TextureMapperPlatformLayer; +typedef TextureMapperPlatformLayer PlatformLayer; +typedef TextureMapperPlatformLayer* NativeLayer; +}; +#else QT_BEGIN_NAMESPACE -class QGraphicsItem; +class QGraphicsObject; QT_END_NAMESPACE -typedef QGraphicsItem PlatformLayer; -typedef QGraphicsItem* NativeLayer; +namespace WebCore { +typedef QGraphicsObject PlatformLayer; +typedef QGraphicsObject* NativeLayer; +} +#endif #elif PLATFORM(CHROMIUM) namespace WebCore { class LayerChromium; diff --git a/WebCore/platform/graphics/ImageSource.h b/WebCore/platform/graphics/ImageSource.h index 189f0f5..4d50253 100644 --- a/WebCore/platform/graphics/ImageSource.h +++ b/WebCore/platform/graphics/ImageSource.h @@ -69,7 +69,12 @@ class IntSize; class SharedBuffer; #if PLATFORM(CG) +#if USE(WEBKIT_IMAGE_DECODERS) +class ImageDecoder; +typedef ImageDecoder* NativeImageSourcePtr; +#else typedef CGImageSourceRef NativeImageSourcePtr; +#endif typedef CGImageRef NativeImagePtr; #elif PLATFORM(OPENVG) class ImageDecoder; diff --git a/WebCore/platform/graphics/SimpleFontData.h b/WebCore/platform/graphics/SimpleFontData.h index 535554f..7bd58ad 100644 --- a/WebCore/platform/graphics/SimpleFontData.h +++ b/WebCore/platform/graphics/SimpleFontData.h @@ -37,7 +37,7 @@ typedef struct OpaqueATSUStyle* ATSUStyle; #endif -#if USE(CORE_TEXT) +#if PLATFORM(MAC) || USE(CORE_TEXT) #include <wtf/RetainPtr.h> #endif @@ -130,7 +130,7 @@ public: NSFont* getNSFont() const { return m_platformData.nsFont(); } #endif -#if USE(CORE_TEXT) +#if PLATFORM(MAC) || USE(CORE_TEXT) CFDictionaryRef getCFStringAttributes(TypesettingFeatures) const; #endif @@ -234,7 +234,7 @@ public: private: #endif -#if USE(CORE_TEXT) +#if PLATFORM(MAC) || USE(CORE_TEXT) mutable HashMap<unsigned, RetainPtr<CFDictionaryRef> > m_CFStringAttributes; #endif diff --git a/WebCore/platform/graphics/TiledBackingStoreClient.h b/WebCore/platform/graphics/TiledBackingStoreClient.h index c5845b9..6087ec3 100644 --- a/WebCore/platform/graphics/TiledBackingStoreClient.h +++ b/WebCore/platform/graphics/TiledBackingStoreClient.h @@ -30,6 +30,7 @@ public: virtual void tiledBackingStorePaintEnd(const Vector<IntRect>& paintedArea) = 0; virtual IntRect tiledBackingStoreContentsRect() = 0; virtual IntRect tiledBackingStoreVisibleRect() = 0; + virtual Color tiledBackingStoreBackgroundColor() const = 0; }; #else diff --git a/WebCore/platform/graphics/WOFFFileFormat.cpp b/WebCore/platform/graphics/WOFFFileFormat.cpp index 25b3b00..5391f30 100644 --- a/WebCore/platform/graphics/WOFFFileFormat.cpp +++ b/WebCore/platform/graphics/WOFFFileFormat.cpp @@ -25,16 +25,16 @@ #include "config.h" #include "WOFFFileFormat.h" +#include <zlib.h> #if !ENABLE(OPENTYPE_SANITIZER) #include "SharedBuffer.h" -#if !PLATFORM(WIN) #if OS(UNIX) #include <netinet/in.h> #endif -#include <zlib.h> + #if PLATFORM(BREWMP) #include <AEEStdLib.h> #define htonl(x) HTONL(x) @@ -42,17 +42,8 @@ #define ntohl(x) NTOHL(x) #define ntohs(x) NTOHS(x) #endif -#else -#include "SoftLinking.h" - -typedef unsigned char Bytef; -typedef unsigned long uLong; -typedef unsigned long uLongf; -#define Z_OK 0 - -SOFT_LINK_LIBRARY(zlib1); -SOFT_LINK(zlib1, uncompress, int, __cdecl, (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen), (dest, destLen, source, sourceLen)); +#if PLATFORM(WIN) #if CPU(BIG_ENDIAN) #define ntohs(x) ((uint16_t)(x)) #define htons(x) ((uint16_t)(x)) @@ -70,7 +61,6 @@ SOFT_LINK(zlib1, uncompress, int, __cdecl, (Bytef *dest, uLongf *destLen, const (((uint32_t)(x) & 0x0000ff00) << 8) | (((uint32_t)(x) & 0x000000ff) << 24))) #define htonl(x) ntohl(x) #endif - #endif // PLATFORM(WIN) namespace WebCore { @@ -123,10 +113,6 @@ bool isWOFF(SharedBuffer* buffer) bool convertWOFFToSfnt(SharedBuffer* woff, Vector<char>& sfnt) { -#if PLATFORM(WINDOWS) - if (!zlib1Library()) - return false; -#endif ASSERT_ARG(sfnt, sfnt.isEmpty()); size_t offset = 0; diff --git a/WebCore/platform/graphics/cairo/FontCacheFreeType.cpp b/WebCore/platform/graphics/cairo/FontCacheFreeType.cpp index 5dca010..cd9ee46 100644 --- a/WebCore/platform/graphics/cairo/FontCacheFreeType.cpp +++ b/WebCore/platform/graphics/cairo/FontCacheFreeType.cpp @@ -41,33 +41,63 @@ void FontCache::platformInit() ASSERT_NOT_REACHED(); } -const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length) +FcPattern* createFontConfigPatternForCharacters(const UChar* characters, int length) { - FcResult fresult; - FontPlatformData* prim = const_cast<FontPlatformData*>(&font.primaryFont()->platformData()); + FcPattern* pattern = FcPatternCreate(); + + FcCharSet* fontConfigCharSet = FcCharSetCreate(); + for (int i = 0; i < length; ++i) { + if (U16_IS_SURROGATE(characters[i]) && U16_IS_SURROGATE_LEAD(characters[i]) + && i != length - 1 && U16_IS_TRAIL(characters[i + 1])) { + FcCharSetAddChar(fontConfigCharSet, U16_GET_SUPPLEMENTARY(characters[i], characters[i+1])); + i++; + } else + FcCharSetAddChar(fontConfigCharSet, characters[i]); + } + FcPatternAddCharSet(pattern, FC_CHARSET, fontConfigCharSet); + FcCharSetDestroy(fontConfigCharSet); - // FIXME: This should not happen, apparently. We are null-checking - // for now just to avoid crashing. - if (!prim || !prim->m_pattern) + FcPatternAddBool(pattern, FC_SCALABLE, FcTrue); + FcConfigSubstitute(0, pattern, FcMatchPattern); + FcDefaultSubstitute(pattern); + return pattern; +} + +FcPattern* findBestFontGivenFallbacks(const FontPlatformData& fontData, FcPattern* pattern) +{ + if (!fontData.m_pattern) return 0; - if (!prim->m_fallbacks) - prim->m_fallbacks = FcFontSort(0, prim->m_pattern.get(), FcTrue, 0, &fresult); + if (!fontData.m_fallbacks) { + FcResult fontConfigResult; + fontData.m_fallbacks = FcFontSort(0, fontData.m_pattern.get(), FcTrue, 0, &fontConfigResult); + } - FcFontSet* fs = prim->m_fallbacks; + if (!fontData.m_fallbacks) + return 0; - for (int i = 0; i < fs->nfont; i++) { - PlatformRefPtr<FcPattern> fin = adoptPlatformRef(FcFontRenderPrepare(0, prim->m_pattern.get(), fs->fonts[i])); - cairo_font_face_t* fontFace = cairo_ft_font_face_create_for_pattern(fin.get()); - FontPlatformData alternateFont(fontFace, font.fontDescription().computedPixelSize(), false, false); - cairo_font_face_destroy(fontFace); - alternateFont.m_pattern = fin; - SimpleFontData* sfd = getCachedFontData(&alternateFont); - if (sfd->containsCharacters(characters, length)) - return sfd; + FcFontSet* sets[] = { fontData.m_fallbacks }; + FcResult fontConfigResult; + return FcFontSetMatch(0, sets, 1, pattern, &fontConfigResult); +} + +const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length) +{ + PlatformRefPtr<FcPattern> pattern = adoptPlatformRef(createFontConfigPatternForCharacters(characters, length)); + const FontPlatformData& fontData = font.primaryFont()->platformData(); + + PlatformRefPtr<FcPattern> fallbackPattern = adoptPlatformRef(findBestFontGivenFallbacks(fontData, pattern.get())); + if (fallbackPattern) { + FontPlatformData alternateFontData(fallbackPattern.get(), font.fontDescription()); + return getCachedFontData(&alternateFontData); } - return 0; + FcResult fontConfigResult; + PlatformRefPtr<FcPattern> resultPattern = adoptPlatformRef(FcFontMatch(0, pattern.get(), &fontConfigResult)); + if (!resultPattern) + return 0; + FontPlatformData alternateFontData(resultPattern.get(), font.fontDescription()); + return getCachedFontData(&alternateFontData); } SimpleFontData* FontCache::getSimilarFontPlatformData(const Font& font) diff --git a/WebCore/platform/graphics/cairo/FontCustomPlatformData.cpp b/WebCore/platform/graphics/cairo/FontCustomPlatformData.cpp index 0d195cb..800907a 100644 --- a/WebCore/platform/graphics/cairo/FontCustomPlatformData.cpp +++ b/WebCore/platform/graphics/cairo/FontCustomPlatformData.cpp @@ -58,7 +58,7 @@ FontCustomPlatformData::~FontCustomPlatformData() cairo_font_face_destroy(m_fontFace); } -FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontRenderingMode) +FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, FontRenderingMode) { return FontPlatformData(m_fontFace, size, bold, italic); } diff --git a/WebCore/platform/graphics/cairo/FontCustomPlatformData.h b/WebCore/platform/graphics/cairo/FontCustomPlatformData.h index c48d110..dac31f8 100644 --- a/WebCore/platform/graphics/cairo/FontCustomPlatformData.h +++ b/WebCore/platform/graphics/cairo/FontCustomPlatformData.h @@ -22,6 +22,7 @@ #ifndef FontCustomPlatformData_h #define FontCustomPlatformData_h +#include "FontOrientation.h" #include "FontRenderingMode.h" #include <wtf/Forward.h> #include <wtf/Noncopyable.h> @@ -38,7 +39,7 @@ struct FontCustomPlatformData : Noncopyable { public: FontCustomPlatformData(FT_Face, SharedBuffer*); ~FontCustomPlatformData(); - FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontRenderingMode = NormalRenderingMode); + FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, FontRenderingMode = NormalRenderingMode); static bool supportsFormat(const String&); private: diff --git a/WebCore/platform/graphics/cairo/FontPlatformDataFreeType.h b/WebCore/platform/graphics/cairo/FontPlatformDataFreeType.h index 7d3ff99..d47d556 100644 --- a/WebCore/platform/graphics/cairo/FontPlatformDataFreeType.h +++ b/WebCore/platform/graphics/cairo/FontPlatformDataFreeType.h @@ -86,7 +86,7 @@ public: #endif PlatformRefPtr<FcPattern> m_pattern; - FcFontSet* m_fallbacks; + mutable FcFontSet* m_fallbacks; // Initialized lazily. float m_size; bool m_syntheticBold; bool m_syntheticOblique; diff --git a/WebCore/platform/graphics/cairo/PathCairo.cpp b/WebCore/platform/graphics/cairo/PathCairo.cpp index d5045be..03f1d10 100644 --- a/WebCore/platform/graphics/cairo/PathCairo.cpp +++ b/WebCore/platform/graphics/cairo/PathCairo.cpp @@ -274,6 +274,8 @@ FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier) bool Path::contains(const FloatPoint& point, WindRule rule) const { + if (!isfinite(point.x()) || !isfinite(point.y())) + return false; cairo_t* cr = platformPath()->context(); cairo_fill_rule_t cur = cairo_get_fill_rule(cr); cairo_set_fill_rule(cr, rule == RULE_EVENODD ? CAIRO_FILL_RULE_EVEN_ODD : CAIRO_FILL_RULE_WINDING); diff --git a/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp b/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp index fe4fc7f..a1cc805 100644 --- a/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp +++ b/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp @@ -41,6 +41,56 @@ namespace WebCore { +enum SourceDataFormatBase { + SourceFormatBaseR = 0, + SourceFormatBaseA, + SourceFormatBaseRA, + SourceFormatBaseAR, + SourceFormatBaseRGB, + SourceFormatBaseRGBA, + SourceFormatBaseARGB, + SourceFormatBaseNumFormats +}; + +enum AlphaFormat { + AlphaFormatNone = 0, + AlphaFormatFirst, + AlphaFormatLast, + AlphaFormatNumFormats +}; + +// This returns kSourceFormatNumFormats if the combination of input parameters is unsupported. +static GraphicsContext3D::SourceDataFormat getSourceDataFormat(unsigned int componentsPerPixel, AlphaFormat alphaFormat, bool is16BitFormat, bool bigEndian) +{ + const static SourceDataFormatBase formatTableBase[4][AlphaFormatNumFormats] = { // componentsPerPixel x AlphaFormat + // AlphaFormatNone AlphaFormatFirst AlphaFormatLast + { SourceFormatBaseR, SourceFormatBaseA, SourceFormatBaseA }, // 1 componentsPerPixel + { SourceFormatBaseNumFormats, SourceFormatBaseAR, SourceFormatBaseRA }, // 2 componentsPerPixel + { SourceFormatBaseRGB, SourceFormatBaseNumFormats, SourceFormatBaseNumFormats }, // 3 componentsPerPixel + { SourceFormatBaseNumFormats, SourceFormatBaseARGB, SourceFormatBaseRGBA } // 4 componentsPerPixel + }; + const static GraphicsContext3D::SourceDataFormat formatTable[SourceFormatBaseNumFormats][3] = { // SourceDataFormatBase x bitsPerComponentAndEndian + // 8bits 16bits, little endian 16bits, big endian + { GraphicsContext3D::kSourceFormatR8, GraphicsContext3D::kSourceFormatR16Little, GraphicsContext3D::kSourceFormatR16Big }, + { GraphicsContext3D::kSourceFormatA8, GraphicsContext3D::kSourceFormatA16Little, GraphicsContext3D::kSourceFormatA16Big }, + { GraphicsContext3D::kSourceFormatRA8, GraphicsContext3D::kSourceFormatRA16Little, GraphicsContext3D::kSourceFormatRA16Big }, + { GraphicsContext3D::kSourceFormatAR8, GraphicsContext3D::kSourceFormatAR16Little, GraphicsContext3D::kSourceFormatAR16Big }, + { GraphicsContext3D::kSourceFormatRGB8, GraphicsContext3D::kSourceFormatRGB16Little, GraphicsContext3D::kSourceFormatRGB16Big }, + { GraphicsContext3D::kSourceFormatRGBA8, GraphicsContext3D::kSourceFormatRGBA16Little, GraphicsContext3D::kSourceFormatRGBA16Big }, + { GraphicsContext3D::kSourceFormatARGB8, GraphicsContext3D::kSourceFormatARGB16Little, GraphicsContext3D::kSourceFormatARGB16Big } + }; + + ASSERT(componentsPerPixel <= 4 && componentsPerPixel > 0); + SourceDataFormatBase formatBase = formatTableBase[componentsPerPixel - 1][alphaFormat]; + if (formatBase == SourceFormatBaseNumFormats) + return GraphicsContext3D::kSourceFormatNumFormats; + if (!is16BitFormat) + return formatTable[formatBase][0]; + if (!bigEndian) + return formatTable[formatBase][1]; + return formatTable[formatBase][2]; +} + bool GraphicsContext3D::getImageData(Image* image, unsigned int format, unsigned int type, @@ -62,6 +112,7 @@ bool GraphicsContext3D::getImageData(Image* image, cgImage = image->nativeImageForCurrentFrame(); if (!cgImage) return false; + size_t width = CGImageGetWidth(cgImage); size_t height = CGImageGetHeight(cgImage); if (!width || !height) @@ -73,6 +124,7 @@ bool GraphicsContext3D::getImageData(Image* image, if (bitsPerPixel % bitsPerComponent) return false; size_t componentsPerPixel = bitsPerPixel / bitsPerComponent; + bool srcByteOrder16Big = false; if (bitsPerComponent == 16) { CGBitmapInfo bitInfo = CGImageGetBitmapInfo(cgImage); @@ -93,8 +145,9 @@ bool GraphicsContext3D::getImageData(Image* image, return false; } } - SourceDataFormat srcDataFormat = kSourceFormatRGBA8; + AlphaOp neededAlphaOp = kAlphaDoNothing; + AlphaFormat alphaFormat = AlphaFormatNone; switch (CGImageGetAlphaInfo(cgImage)) { case kCGImageAlphaPremultipliedFirst: // This path is only accessible for MacOS earlier than 10.6.4. @@ -103,68 +156,17 @@ bool GraphicsContext3D::getImageData(Image* image, ASSERT(!image->data()); if (!premultiplyAlpha) neededAlphaOp = kAlphaDoUnmultiply; - switch (componentsPerPixel) { - case 2: - if (bitsPerComponent == 8) - srcDataFormat = kSourceFormatAR8; - else - srcDataFormat = srcByteOrder16Big ? kSourceFormatAR16Big : kSourceFormatAR16Little; - break; - case 4: - if (bitsPerComponent == 8) - srcDataFormat = kSourceFormatARGB8; - else - srcDataFormat = srcByteOrder16Big ? kSourceFormatARGB16Big : kSourceFormatARGB16Little; - break; - default: - return false; - } + alphaFormat = AlphaFormatFirst; break; case kCGImageAlphaFirst: // This path is only accessible for MacOS earlier than 10.6.4. if (premultiplyAlpha) neededAlphaOp = kAlphaDoPremultiply; - switch (componentsPerPixel) { - case 1: - if (bitsPerComponent == 8) - srcDataFormat = kSourceFormatA8; - else - srcDataFormat = srcByteOrder16Big ? kSourceFormatA16Big : kSourceFormatA16Little; - break; - case 2: - if (bitsPerComponent == 8) - srcDataFormat = kSourceFormatAR8; - else - srcDataFormat = srcByteOrder16Big ? kSourceFormatAR16Big : kSourceFormatAR16Little; - break; - case 4: - if (bitsPerComponent == 8) - srcDataFormat = kSourceFormatARGB8; - else - srcDataFormat = srcByteOrder16Big ? kSourceFormatARGB16Big : kSourceFormatARGB16Little; - break; - default: - return false; - } + alphaFormat = AlphaFormatFirst; break; case kCGImageAlphaNoneSkipFirst: // This path is only accessible for MacOS earlier than 10.6.4. - switch (componentsPerPixel) { - case 2: - if (bitsPerComponent == 8) - srcDataFormat = kSourceFormatAR8; - else - srcDataFormat = srcByteOrder16Big ? kSourceFormatAR16Big : kSourceFormatAR16Little; - break; - case 4: - if (bitsPerComponent == 8) - srcDataFormat = kSourceFormatARGB8; - else - srcDataFormat = srcByteOrder16Big ? kSourceFormatARGB16Big : kSourceFormatARGB16Little; - break; - default: - return false; - } + alphaFormat = AlphaFormatFirst; break; case kCGImageAlphaPremultipliedLast: // This is a special case for texImage2D with HTMLCanvasElement input, @@ -172,88 +174,26 @@ bool GraphicsContext3D::getImageData(Image* image, ASSERT(!image->data()); if (!premultiplyAlpha) neededAlphaOp = kAlphaDoUnmultiply; - switch (componentsPerPixel) { - case 2: - if (bitsPerComponent == 8) - srcDataFormat = kSourceFormatRA8; - else - srcDataFormat = srcByteOrder16Big ? kSourceFormatRA16Big : kSourceFormatRA16Little; - break; - case 4: - if (bitsPerComponent == 8) - srcDataFormat = kSourceFormatRGBA8; - else - srcDataFormat = srcByteOrder16Big ? kSourceFormatRGBA16Big : kSourceFormatRGBA16Little; - break; - default: - return false; - } + alphaFormat = AlphaFormatLast; break; case kCGImageAlphaLast: if (premultiplyAlpha) neededAlphaOp = kAlphaDoPremultiply; - switch (componentsPerPixel) { - case 1: - if (bitsPerComponent == 8) - srcDataFormat = kSourceFormatA8; - else - srcDataFormat = srcByteOrder16Big ? kSourceFormatA16Big : kSourceFormatA16Little; - break; - case 2: - if (bitsPerComponent == 8) - srcDataFormat = kSourceFormatRA8; - else - srcDataFormat = srcByteOrder16Big ? kSourceFormatRA16Big : kSourceFormatRA16Little; - break; - case 4: - if (bitsPerComponent == 8) - srcDataFormat = kSourceFormatRGBA8; - else - srcDataFormat = srcByteOrder16Big ? kSourceFormatRGBA16Big : kSourceFormatRGBA16Little; - break; - default: - return false; - } + alphaFormat = AlphaFormatLast; break; case kCGImageAlphaNoneSkipLast: - switch (componentsPerPixel) { - case 2: - if (bitsPerComponent == 8) - srcDataFormat = kSourceFormatRA8; - else - srcDataFormat = srcByteOrder16Big ? kSourceFormatRA16Big : kSourceFormatRA16Little; - break; - case 4: - if (bitsPerComponent == 8) - srcDataFormat = kSourceFormatRGBA8; - else - srcDataFormat = srcByteOrder16Big ? kSourceFormatRGBA16Big : kSourceFormatRGBA16Little; - break; - default: - return false; - } + alphaFormat = AlphaFormatLast; break; case kCGImageAlphaNone: - switch (componentsPerPixel) { - case 1: - if (bitsPerComponent == 8) - srcDataFormat = kSourceFormatR8; - else - srcDataFormat = srcByteOrder16Big ? kSourceFormatR16Big : kSourceFormatR16Little; - break; - case 3: - if (bitsPerComponent == 8) - srcDataFormat = kSourceFormatRGB8; - else - srcDataFormat = srcByteOrder16Big ? kSourceFormatRGB16Big : kSourceFormatRGB16Little; - break; - default: - return false; - } + alphaFormat = AlphaFormatNone; break; default: return false; } + SourceDataFormat srcDataFormat = getSourceDataFormat(componentsPerPixel, alphaFormat, bitsPerComponent == 16, srcByteOrder16Big); + if (srcDataFormat == kSourceFormatNumFormats) + return false; + RetainPtr<CFDataRef> pixelData; pixelData.adoptCF(CGDataProviderCopyData(CGImageGetDataProvider(cgImage))); if (!pixelData) diff --git a/WebCore/platform/graphics/chromium/FontLinux.cpp b/WebCore/platform/graphics/chromium/FontLinux.cpp index f38273c..e73747f 100644 --- a/WebCore/platform/graphics/chromium/FontLinux.cpp +++ b/WebCore/platform/graphics/chromium/FontLinux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2008, Google Inc. All rights reserved. + * Copyright (c) 2007, 2008, 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 @@ -220,8 +220,6 @@ public: const FontPlatformData* fontPlatformDataForScriptRun() { return reinterpret_cast<FontPlatformData*>(m_item.font->userData); } private: - const TextRun& getTextRun(const TextRun&); - const TextRun& getNormalizedTextRun(const TextRun&); void setupFontForScriptRun(); HB_FontRec* allocHarfbuzzFont(); void deleteGlyphArrays(); @@ -229,7 +227,9 @@ private: void resetGlyphArrays(); void shapeGlyphs(); void setGlyphXPositions(bool); - void mirrorCharacters(UChar*, const UChar*, int) const; + + static void normalizeSpacesAndMirrorChars(const UChar* source, bool rtl, UChar* destination, int length); + static const TextRun& getNormalizedTextRun(const TextRun& originalRun, OwnPtr<TextRun>& normalizedRun, OwnArrayPtr<UChar>& normalizedBuffer); // This matches the logic in RenderBlock::findNextLineBreak static bool isCodepointSpace(HB_UChar16 c) { return c == ' ' || c == '\t'; } @@ -264,11 +264,13 @@ TextRunWalker::TextRunWalker(const TextRun& run, unsigned startingX, const Font* : m_font(font) , m_startingX(startingX) , m_offsetX(m_startingX) - , m_run(getTextRun(run)) + , m_run(getNormalizedTextRun(run, m_normalizedRun, m_normalizedBuffer)) , m_iterateBackwards(m_run.rtl()) , m_wordSpacingAdjustment(0) , m_padding(0) + , m_padPerWordBreak(0) , m_padError(0) + , m_letterSpacing(0) { // Do not use |run| inside this constructor. Use |m_run| instead. @@ -286,17 +288,8 @@ TextRunWalker::TextRunWalker(const TextRun& run, unsigned startingX, const Font* m_item.item.bidiLevel = m_run.rtl(); - int length = m_run.length(); - m_item.stringLength = length; - - if (!m_item.item.bidiLevel) - m_item.string = m_run.characters(); - else { - // Assume mirrored character is in the same Unicode multilingual plane as the original one. - UChar* string = new UChar[length]; - mirrorCharacters(string, m_run.characters(), length); - m_item.string = string; - } + m_item.string = m_run.characters(); + m_item.stringLength = m_run.length(); reset(); } @@ -306,8 +299,6 @@ TextRunWalker::~TextRunWalker() fastFree(m_item.font); deleteGlyphArrays(); delete[] m_item.log_clusters; - if (m_item.item.bidiLevel) - delete[] m_item.string; } bool TextRunWalker::isWordBreak(unsigned index, bool isRTL) @@ -408,51 +399,6 @@ float TextRunWalker::widthOfFullRun() return widthSum; } -const TextRun& TextRunWalker::getTextRun(const TextRun& originalRun) -{ - // Normalize the text run in two ways: - // 1) Convert the |originalRun| to NFC normalized form if combining diacritical marks - // (U+0300..) are used in the run. This conversion is necessary since most OpenType - // fonts (e.g., Arial) don't have substitution rules for the diacritical marks in - // their GSUB tables. - // - // Note that we don't use the icu::Normalizer::isNormalized(UNORM_NFC) API here since - // the API returns FALSE (= not normalized) for complex runs that don't require NFC - // normalization (e.g., Arabic text). Unless the run contains the diacritical marks, - // Harfbuzz will do the same thing for us using the GSUB table. - // 2) Convert spacing characters into plain spaces, as some fonts will provide glyphs - // for characters like '\n' otherwise. - for (int i = 0; i < originalRun.length(); ++i) { - UChar ch = originalRun[i]; - UBlockCode block = ::ublock_getCode(ch); - if (block == UBLOCK_COMBINING_DIACRITICAL_MARKS || (Font::treatAsSpace(ch) && ch != ' ')) - return getNormalizedTextRun(originalRun); - } - return originalRun; -} - -const TextRun& TextRunWalker::getNormalizedTextRun(const TextRun& originalRun) -{ - icu::UnicodeString normalizedString; - UErrorCode error = U_ZERO_ERROR; - icu::Normalizer::normalize(icu::UnicodeString(originalRun.characters(), originalRun.length()), UNORM_NFC, 0 /* no options */, normalizedString, error); - if (U_FAILURE(error)) - return originalRun; - - m_normalizedBuffer.set(new UChar[normalizedString.length() + 1]); - normalizedString.extract(m_normalizedBuffer.get(), normalizedString.length() + 1, error); - ASSERT(U_SUCCESS(error)); - - for (int i = 0; i < normalizedString.length(); ++i) { - if (Font::treatAsSpace(m_normalizedBuffer[i])) - m_normalizedBuffer[i] = ' '; - } - - m_normalizedRun.set(new TextRun(originalRun)); - m_normalizedRun->setText(m_normalizedBuffer.get(), normalizedString.length()); - return *m_normalizedRun; -} - void TextRunWalker::setupFontForScriptRun() { const FontData* fontData = m_font->glyphDataForCharacter(m_item.string[m_item.item.pos], false, false).fontData; @@ -595,7 +541,7 @@ void TextRunWalker::setGlyphXPositions(bool isRTL) m_offsetX += m_pixelWidth; } -void TextRunWalker::mirrorCharacters(UChar* destination, const UChar* source, int length) const +void TextRunWalker::normalizeSpacesAndMirrorChars(const UChar* source, bool rtl, UChar* destination, int length) { int position = 0; bool error = false; @@ -604,13 +550,68 @@ void TextRunWalker::mirrorCharacters(UChar* destination, const UChar* source, in UChar32 character; int nextPosition = position; U16_NEXT(source, nextPosition, length, character); - character = u_charMirror(character); + if (Font::treatAsSpace(character)) + character = ' '; + else if (rtl) + character = u_charMirror(character); U16_APPEND(destination, position, length, character, error); ASSERT(!error); position = nextPosition; } } +const TextRun& TextRunWalker::getNormalizedTextRun(const TextRun& originalRun, OwnPtr<TextRun>& normalizedRun, OwnArrayPtr<UChar>& normalizedBuffer) +{ + // Normalize the text run in three ways: + // 1) Convert the |originalRun| to NFC normalized form if combining diacritical marks + // (U+0300..) are used in the run. This conversion is necessary since most OpenType + // fonts (e.g., Arial) don't have substitution rules for the diacritical marks in + // their GSUB tables. + // + // Note that we don't use the icu::Normalizer::isNormalized(UNORM_NFC) API here since + // the API returns FALSE (= not normalized) for complex runs that don't require NFC + // normalization (e.g., Arabic text). Unless the run contains the diacritical marks, + // Harfbuzz will do the same thing for us using the GSUB table. + // 2) Convert spacing characters into plain spaces, as some fonts will provide glyphs + // for characters like '\n' otherwise. + // 3) Convert mirrored characters such as parenthesis for rtl text. + + // Convert to NFC form if the text has diacritical marks. + icu::UnicodeString normalizedString; + UErrorCode error = U_ZERO_ERROR; + + for (int16_t i = 0; i < originalRun.length(); ++i) { + UChar ch = originalRun[i]; + if (::ublock_getCode(ch) == UBLOCK_COMBINING_DIACRITICAL_MARKS) { + icu::Normalizer::normalize(icu::UnicodeString(originalRun.characters(), + originalRun.length()), UNORM_NFC, 0 /* no options */, + normalizedString, error); + if (U_FAILURE(error)) + return originalRun; + break; + } + } + + // Normalize space and mirror parenthesis for rtl text. + int normalizedBufferLength; + const UChar* sourceText; + if (normalizedString.isEmpty()) { + normalizedBufferLength = originalRun.length(); + sourceText = originalRun.characters(); + } else { + normalizedBufferLength = normalizedString.length(); + sourceText = normalizedString.getBuffer(); + } + + normalizedBuffer.set(new UChar[normalizedBufferLength + 1]); + + normalizeSpacesAndMirrorChars(sourceText, originalRun.rtl(), normalizedBuffer.get(), normalizedBufferLength); + + normalizedRun.set(new TextRun(originalRun)); + normalizedRun->setText(normalizedBuffer.get(), normalizedBufferLength); + return *normalizedRun; +} + static void setupForTextPainting(SkPaint* paint, SkColor color) { paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding); diff --git a/WebCore/platform/graphics/chromium/FontPlatformDataChromiumWin.h b/WebCore/platform/graphics/chromium/FontPlatformDataChromiumWin.h index beac0bf..c59cb56 100644 --- a/WebCore/platform/graphics/chromium/FontPlatformDataChromiumWin.h +++ b/WebCore/platform/graphics/chromium/FontPlatformDataChromiumWin.h @@ -102,7 +102,7 @@ private: HFONT hfont() const { return m_hfont; } unsigned hash() const { - return StringImpl::computeHash(reinterpret_cast<const UChar*>(&m_hfont), sizeof(HFONT) / sizeof(UChar)); + return WTF::StringHasher::createBlobHash<sizeof(HFONT)>(&m_hfont); } bool operator==(const RefCountedHFONT& other) const diff --git a/WebCore/platform/graphics/chromium/LayerChromium.cpp b/WebCore/platform/graphics/chromium/LayerChromium.cpp index 79f18f0..f668bbf 100644 --- a/WebCore/platform/graphics/chromium/LayerChromium.cpp +++ b/WebCore/platform/graphics/chromium/LayerChromium.cpp @@ -176,8 +176,10 @@ void LayerChromium::setLayerRenderer(LayerRendererChromium* renderer) { // If we're changing layer renderers then we need to free up any resources // allocated by the old renderer. - if (layerRenderer() && layerRenderer() != renderer) + if (layerRenderer() && layerRenderer() != renderer) { cleanupResources(); + setNeedsDisplay(); + } m_layerRenderer = renderer; } diff --git a/WebCore/platform/graphics/chromium/LayerRendererChromium.h b/WebCore/platform/graphics/chromium/LayerRendererChromium.h index 6a06105..b2a32ee 100644 --- a/WebCore/platform/graphics/chromium/LayerRendererChromium.h +++ b/WebCore/platform/graphics/chromium/LayerRendererChromium.h @@ -82,6 +82,7 @@ public: void setRootLayer(PassRefPtr<LayerChromium> layer) { m_rootLayer = layer; } LayerChromium* rootLayer() { return m_rootLayer.get(); } + void transferRootLayer(LayerRendererChromium* other) { other->m_rootLayer = m_rootLayer.release(); } bool hardwareCompositing() const { return m_hardwareCompositing; } diff --git a/WebCore/platform/graphics/cocoa/FontPlatformData.h b/WebCore/platform/graphics/cocoa/FontPlatformData.h index 034e23b..17ae4b5 100644 --- a/WebCore/platform/graphics/cocoa/FontPlatformData.h +++ b/WebCore/platform/graphics/cocoa/FontPlatformData.h @@ -24,6 +24,7 @@ #ifndef FontPlatformData_h #define FontPlatformData_h +#include "FontOrientation.h" #include <wtf/text/StringImpl.h> #ifdef __OBJC__ @@ -58,9 +59,10 @@ inline CTFontRef toCTFontRef(NSFont *nsFont) { return reinterpret_cast<CTFontRef class FontPlatformData { public: - FontPlatformData(float size, bool syntheticBold, bool syntheticOblique) + FontPlatformData(float size, bool syntheticBold, bool syntheticOblique, FontOrientation orientation = Horizontal) : m_syntheticBold(syntheticBold) , m_syntheticOblique(syntheticOblique) + , m_orientation(orientation) , m_atsuFontID(0) , m_size(size) , m_font(0) @@ -71,11 +73,12 @@ class FontPlatformData { { } - FontPlatformData(NSFont *nsFont, bool syntheticBold = false, bool syntheticOblique = false); + FontPlatformData(NSFont *nsFont, bool syntheticBold = false, bool syntheticOblique = false, FontOrientation = Horizontal); - FontPlatformData(CGFontRef cgFont, ATSUFontID fontID, float size, bool syntheticBold, bool syntheticOblique) + FontPlatformData(CGFontRef cgFont, ATSUFontID fontID, float size, bool syntheticBold, bool syntheticOblique, FontOrientation orientation) : m_syntheticBold(syntheticBold) , m_syntheticOblique(syntheticOblique) + , m_orientation(orientation) , m_atsuFontID(fontID) , m_size(size) , m_font(0) @@ -94,9 +97,11 @@ class FontPlatformData { float size() const { return m_size; } bool syntheticBold() const { return m_syntheticBold; } bool syntheticOblique() const { return m_syntheticOblique; } + FontOrientation orientation() const { return m_orientation; } bool m_syntheticBold; bool m_syntheticOblique; + FontOrientation m_orientation; ATSUFontID m_atsuFontID; float m_size; @@ -104,8 +109,8 @@ class FontPlatformData { unsigned hash() const { ASSERT(m_font != 0 || m_cgFont == 0); - uintptr_t hashCodes[2] = { (uintptr_t)m_font, m_syntheticBold << 1 | m_syntheticOblique }; - return StringImpl::computeHash(reinterpret_cast<UChar*>(hashCodes), sizeof(hashCodes) / sizeof(UChar)); + uintptr_t hashCodes[2] = { (uintptr_t)m_font, m_orientation << 2 | m_syntheticBold << 1 | m_syntheticOblique }; + return WTF::StringHasher::createBlobHash<sizeof(hashCodes)>(hashCodes); } const FontPlatformData& operator=(const FontPlatformData& f); @@ -113,15 +118,13 @@ class FontPlatformData { bool operator==(const FontPlatformData& other) const { return m_font == other.m_font && m_syntheticBold == other.m_syntheticBold && m_syntheticOblique == other.m_syntheticOblique && - m_cgFont == other.m_cgFont && m_size == other.m_size && m_atsuFontID == other.m_atsuFontID; + m_cgFont == other.m_cgFont && m_size == other.m_size && m_atsuFontID == other.m_atsuFontID && m_orientation == other.m_orientation; } NSFont *font() const { return m_font; } void setFont(NSFont *font); -#if USE(CORE_TEXT) CTFontRef ctFont() const; -#endif bool roundsGlyphAdvances() const; bool allowsLigatures() const; @@ -157,9 +160,7 @@ private: CGFontRef m_cgFont; // It is not necessary to refcount this, since either an NSFont owns it or some CachedFont has it referenced. #endif -#if USE(CORE_TEXT) mutable RetainPtr<CTFontRef> m_CTFont; -#endif bool m_isColorBitmapFont; diff --git a/WebCore/platform/graphics/cocoa/FontPlatformDataCocoa.mm b/WebCore/platform/graphics/cocoa/FontPlatformDataCocoa.mm index bd49dcc..dbfec5f 100644 --- a/WebCore/platform/graphics/cocoa/FontPlatformDataCocoa.mm +++ b/WebCore/platform/graphics/cocoa/FontPlatformDataCocoa.mm @@ -44,7 +44,7 @@ void FontPlatformData::loadFont(NSFont* nsFont, float, NSFont*& outNSFont, CGFon } #endif // PLATFORM(MAC) -FontPlatformData::FontPlatformData(NSFont *nsFont, bool syntheticBold, bool syntheticOblique) +FontPlatformData::FontPlatformData(NSFont *nsFont, bool syntheticBold, bool syntheticOblique, FontOrientation orientation) : m_syntheticBold(syntheticBold) , m_syntheticOblique(syntheticOblique) , m_font(nsFont) @@ -63,6 +63,26 @@ FontPlatformData::FontPlatformData(NSFont *nsFont, bool syntheticBold, bool synt CGFontRef cgFont = 0; loadFont(nsFont, m_size, m_font, cgFont, m_atsuFontID); + if (orientation == Vertical) { + // Ignore vertical orientation when the font doesn't support vertical metrics. + // The check doesn't look neat but this is what AppKit does for vertical writing... + RetainPtr<CFArrayRef> tableTags(AdoptCF, CTFontCopyAvailableTables(ctFont(), kCTFontTableOptionExcludeSynthetic)); + CFIndex numTables = CFArrayGetCount(tableTags.get()); + bool found = false; + for (CFIndex index = 0; index < numTables; ++index) { + CTFontTableTag tag = (CTFontTableTag)(uintptr_t)CFArrayGetValueAtIndex(tableTags.get(), index); + if (tag == kCTFontTableVhea || tag == kCTFontTableVORG) { + found = true; + break; + } + } + + if (found == false) + orientation = Horizontal; + } + + m_orientation = orientation; + if (m_font) CFRetain(m_font); @@ -83,9 +103,8 @@ FontPlatformData::FontPlatformData(const FontPlatformData& f) m_cgFont = f.m_cgFont; m_atsuFontID = f.m_atsuFontID; m_isColorBitmapFont = f.m_isColorBitmapFont; -#if USE(CORE_TEXT) + m_orientation = f.m_orientation; m_CTFont = f.m_CTFont; -#endif #if PLATFORM(CHROMIUM) && OS(DARWIN) m_inMemoryFont = f.m_inMemoryFont; #endif @@ -112,9 +131,8 @@ const FontPlatformData& FontPlatformData::operator=(const FontPlatformData& f) CFRelease(m_font); m_font = f.m_font; m_isColorBitmapFont = f.m_isColorBitmapFont; -#if USE(CORE_TEXT) + m_orientation = f.m_orientation; m_CTFont = f.m_CTFont; -#endif #if PLATFORM(CHROMIUM) && OS(DARWIN) m_inMemoryFont = f.m_inMemoryFont; #endif @@ -157,9 +175,7 @@ void FontPlatformData::setFont(NSFont *font) #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) m_isColorBitmapFont = CTFontGetSymbolicTraits(toCTFontRef(m_font)) & kCTFontColorGlyphsTrait; #endif -#if USE(CORE_TEXT) m_CTFont = 0; -#endif } bool FontPlatformData::roundsGlyphAdvances() const @@ -169,10 +185,9 @@ bool FontPlatformData::roundsGlyphAdvances() const bool FontPlatformData::allowsLigatures() const { - return ![[m_font coveredCharacterSet] characterIsMember:'a']; + return m_orientation == Horizontal && ![[m_font coveredCharacterSet] characterIsMember:'a']; } -#if USE(CORE_TEXT) CTFontRef FontPlatformData::ctFont() const { if (m_font) @@ -181,13 +196,13 @@ CTFontRef FontPlatformData::ctFont() const m_CTFont.adoptCF(CTFontCreateWithGraphicsFont(m_cgFont.get(), m_size, 0, 0)); return m_CTFont.get(); } -#endif // USE(CORE_TEXT) #ifndef NDEBUG String FontPlatformData::description() const { RetainPtr<CFStringRef> cgFontDescription(AdoptCF, CFCopyDescription(cgFont())); - return String(cgFontDescription.get()) + " " + String::number(m_size) + (m_syntheticBold ? " synthetic bold" : "") + (m_syntheticOblique ? " synthetic oblique" : ""); + return String(cgFontDescription.get()) + " " + String::number(m_size) + + (m_syntheticBold ? " synthetic bold" : "") + (m_syntheticOblique ? " synthetic oblique" : "") + (m_orientation ? " vertical orientation" : ""); } #endif diff --git a/WebCore/platform/graphics/filters/FEBlend.cpp b/WebCore/platform/graphics/filters/FEBlend.cpp index 1a40027..03b95c3 100644 --- a/WebCore/platform/graphics/filters/FEBlend.cpp +++ b/WebCore/platform/graphics/filters/FEBlend.cpp @@ -95,26 +95,30 @@ void FEBlend::apply(Filter* filter) if (!in->resultImage() || !in2->resultImage()) return; - if (m_mode == FEBLEND_MODE_UNKNOWN) + if (m_mode <= FEBLEND_MODE_UNKNOWN || m_mode > FEBLEND_MODE_LIGHTEN) return; if (!effectContext(filter)) return; IntRect effectADrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect()); - RefPtr<CanvasPixelArray> srcPixelArrayA(in->resultImage()->getPremultipliedImageData(effectADrawingRect)->data()); + RefPtr<ImageData> srcImageDataA = in->resultImage()->getPremultipliedImageData(effectADrawingRect); + ByteArray* srcPixelArrayA = srcImageDataA->data()->data(); IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->absolutePaintRect()); - RefPtr<CanvasPixelArray> srcPixelArrayB(in2->resultImage()->getPremultipliedImageData(effectBDrawingRect)->data()); + RefPtr<ImageData> srcImageDataB = in2->resultImage()->getPremultipliedImageData(effectBDrawingRect); + ByteArray* srcPixelArrayB = srcImageDataB->data()->data(); IntRect imageRect(IntPoint(), resultImage()->size()); RefPtr<ImageData> imageData = ImageData::create(imageRect.width(), imageRect.height()); + ByteArray* dstPixelArray = imageData->data()->data(); // Keep synchronized with BlendModeType static const BlendType callEffect[] = {unknown, normal, multiply, screen, darken, lighten}; - ASSERT(srcPixelArrayA->length() == srcPixelArrayB->length()); - for (unsigned pixelOffset = 0; pixelOffset < srcPixelArrayA->length(); pixelOffset += 4) { + unsigned pixelArrayLength = srcPixelArrayA->length(); + ASSERT(pixelArrayLength == srcPixelArrayB->length()); + for (unsigned pixelOffset = 0; pixelOffset < pixelArrayLength; pixelOffset += 4) { unsigned char alphaA = srcPixelArrayA->get(pixelOffset + 3); unsigned char alphaB = srcPixelArrayB->get(pixelOffset + 3); for (unsigned channel = 0; channel < 3; ++channel) { @@ -122,10 +126,10 @@ void FEBlend::apply(Filter* filter) unsigned char colorB = srcPixelArrayB->get(pixelOffset + channel); unsigned char result = (*callEffect[m_mode])(colorA, colorB, alphaA, alphaB); - imageData->data()->set(pixelOffset + channel, result); + dstPixelArray->set(pixelOffset + channel, result); } unsigned char alphaR = 255 - ((255 - alphaA) * (255 - alphaB)) / 255; - imageData->data()->set(pixelOffset + 3, alphaR); + dstPixelArray->set(pixelOffset + 3, alphaR); } resultImage()->putPremultipliedImageData(imageData.get(), imageRect, IntPoint()); diff --git a/WebCore/platform/graphics/filters/FEColorMatrix.cpp b/WebCore/platform/graphics/filters/FEColorMatrix.cpp index b41d5ad..acf7d4a 100644 --- a/WebCore/platform/graphics/filters/FEColorMatrix.cpp +++ b/WebCore/platform/graphics/filters/FEColorMatrix.cpp @@ -25,11 +25,10 @@ #if ENABLE(FILTERS) #include "FEColorMatrix.h" -#include "CanvasPixelArray.h" #include "Filter.h" #include "GraphicsContext.h" #include "ImageData.h" -#include <math.h> + #include <wtf/MathExtras.h> namespace WebCore { @@ -112,25 +111,21 @@ inline void huerotate(double& red, double& green, double& blue, const float& hue inline void luminance(double& red, double& green, double& blue, double& alpha) { alpha = 0.2125 * red + 0.7154 * green + 0.0721 * blue; - red = 0.; - green = 0.; - blue = 0.; + red = 0; + green = 0; + blue = 0; } template<ColorMatrixType filterType> -void effectType(const PassRefPtr<CanvasPixelArray>& srcPixelArray, PassRefPtr<ImageData>& imageData, const Vector<float>& values) +void effectType(ByteArray* pixelArray, const Vector<float>& values) { - for (unsigned pixelOffset = 0; pixelOffset < srcPixelArray->length(); pixelOffset++) { - unsigned pixelByteOffset = pixelOffset * 4; - - unsigned char r = 0, g = 0, b = 0, a = 0; - srcPixelArray->get(pixelByteOffset, r); - srcPixelArray->get(pixelByteOffset + 1, g); - srcPixelArray->get(pixelByteOffset + 2, b); - srcPixelArray->get(pixelByteOffset + 3, a); + unsigned pixelArrayLength = pixelArray->length(); + for (unsigned pixelByteOffset = 0; pixelByteOffset < pixelArrayLength; pixelByteOffset += 4) { + double red = pixelArray->get(pixelByteOffset); + double green = pixelArray->get(pixelByteOffset + 1); + double blue = pixelArray->get(pixelByteOffset + 2); + double alpha = pixelArray->get(pixelByteOffset + 3); - double red = r, green = g, blue = b, alpha = a; - switch (filterType) { case FECOLORMATRIX_TYPE_MATRIX: matrix(red, green, blue, alpha, values); @@ -146,10 +141,10 @@ void effectType(const PassRefPtr<CanvasPixelArray>& srcPixelArray, PassRefPtr<Im break; } - imageData->data()->set(pixelByteOffset, red); - imageData->data()->set(pixelByteOffset + 1, green); - imageData->data()->set(pixelByteOffset + 2, blue); - imageData->data()->set(pixelByteOffset + 3, alpha); + pixelArray->set(pixelByteOffset, red); + pixelArray->set(pixelByteOffset + 1, green); + pixelArray->set(pixelByteOffset + 2, blue); + pixelArray->set(pixelByteOffset + 3, alpha); } } @@ -167,23 +162,23 @@ void FEColorMatrix::apply(Filter* filter) filterContext->drawImageBuffer(in->resultImage(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect())); IntRect imageRect(IntPoint(), resultImage()->size()); - PassRefPtr<ImageData> imageData(resultImage()->getUnmultipliedImageData(imageRect)); - PassRefPtr<CanvasPixelArray> srcPixelArray(imageData->data()); + RefPtr<ImageData> imageData = resultImage()->getUnmultipliedImageData(imageRect); + ByteArray* pixelArray = imageData->data()->data(); switch (m_type) { case FECOLORMATRIX_TYPE_UNKNOWN: break; case FECOLORMATRIX_TYPE_MATRIX: - effectType<FECOLORMATRIX_TYPE_MATRIX>(srcPixelArray, imageData, m_values); + effectType<FECOLORMATRIX_TYPE_MATRIX>(pixelArray, m_values); break; case FECOLORMATRIX_TYPE_SATURATE: - effectType<FECOLORMATRIX_TYPE_SATURATE>(srcPixelArray, imageData, m_values); + effectType<FECOLORMATRIX_TYPE_SATURATE>(pixelArray, m_values); break; case FECOLORMATRIX_TYPE_HUEROTATE: - effectType<FECOLORMATRIX_TYPE_HUEROTATE>(srcPixelArray, imageData, m_values); + effectType<FECOLORMATRIX_TYPE_HUEROTATE>(pixelArray, m_values); break; case FECOLORMATRIX_TYPE_LUMINANCETOALPHA: - effectType<FECOLORMATRIX_TYPE_LUMINANCETOALPHA>(srcPixelArray, imageData, m_values); + effectType<FECOLORMATRIX_TYPE_LUMINANCETOALPHA>(pixelArray, m_values); setIsAlphaImage(true); break; } diff --git a/WebCore/platform/graphics/filters/FEComponentTransfer.cpp b/WebCore/platform/graphics/filters/FEComponentTransfer.cpp index 08d0b1f..5cffac7 100644 --- a/WebCore/platform/graphics/filters/FEComponentTransfer.cpp +++ b/WebCore/platform/graphics/filters/FEComponentTransfer.cpp @@ -26,11 +26,11 @@ #if ENABLE(FILTERS) #include "FEComponentTransfer.h" -#include "CanvasPixelArray.h" #include "Filter.h" #include "GraphicsContext.h" #include "ImageData.h" -#include <math.h> + +#include <wtf/MathExtras.h> namespace WebCore { @@ -168,13 +168,14 @@ void FEComponentTransfer::apply(Filter* filter) (*callEffect[transferFunction[channel].type])(tables[channel], transferFunction[channel]); IntRect drawingRect = requestedRegionOfInputImageData(in->absolutePaintRect()); - RefPtr<ImageData> imageData(in->resultImage()->getUnmultipliedImageData(drawingRect)); - CanvasPixelArray* srcPixelArray(imageData->data()); + RefPtr<ImageData> imageData = in->resultImage()->getUnmultipliedImageData(drawingRect); + ByteArray* pixelArray = imageData->data()->data(); - for (unsigned pixelOffset = 0; pixelOffset < srcPixelArray->length(); pixelOffset += 4) { + unsigned pixelArrayLength = pixelArray->length(); + for (unsigned pixelOffset = 0; pixelOffset < pixelArrayLength; pixelOffset += 4) { for (unsigned channel = 0; channel < 4; ++channel) { - unsigned char c = srcPixelArray->get(pixelOffset + channel); - imageData->data()->set(pixelOffset + channel, tables[channel][c]); + unsigned char c = pixelArray->get(pixelOffset + channel); + pixelArray->set(pixelOffset + channel, tables[channel][c]); } } diff --git a/WebCore/platform/graphics/filters/FEComposite.cpp b/WebCore/platform/graphics/filters/FEComposite.cpp index 2326966..aad71e3 100644 --- a/WebCore/platform/graphics/filters/FEComposite.cpp +++ b/WebCore/platform/graphics/filters/FEComposite.cpp @@ -26,7 +26,6 @@ #if ENABLE(FILTERS) #include "FEComposite.h" -#include "CanvasPixelArray.h" #include "Filter.h" #include "GraphicsContext.h" #include "ImageData.h" @@ -98,12 +97,13 @@ void FEComposite::setK4(float k4) m_k4 = k4; } -inline void arithmetic(const RefPtr<CanvasPixelArray>& srcPixelArrayA, CanvasPixelArray*& srcPixelArrayB, +inline void arithmetic(const ByteArray* srcPixelArrayA, ByteArray* srcPixelArrayB, float k1, float k2, float k3, float k4) { float scaledK1 = k1 / 255.f; float scaledK4 = k4 * 255.f; - for (unsigned pixelOffset = 0; pixelOffset < srcPixelArrayA->length(); pixelOffset += 4) { + unsigned pixelArrayLength = srcPixelArrayA->length(); + for (unsigned pixelOffset = 0; pixelOffset < pixelArrayLength; pixelOffset += 4) { for (unsigned channel = 0; channel < 4; ++channel) { unsigned char i1 = srcPixelArrayA->get(pixelOffset + channel); unsigned char i2 = srcPixelArrayB->get(pixelOffset + channel); @@ -174,11 +174,12 @@ void FEComposite::apply(Filter* filter) break; case FECOMPOSITE_OPERATOR_ARITHMETIC: { IntRect effectADrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect()); - RefPtr<CanvasPixelArray> srcPixelArrayA(in->resultImage()->getPremultipliedImageData(effectADrawingRect)->data()); + RefPtr<ImageData> srcImageData = in->resultImage()->getPremultipliedImageData(effectADrawingRect); + ByteArray* srcPixelArrayA = srcImageData->data()->data(); IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->absolutePaintRect()); - RefPtr<ImageData> imageData(in2->resultImage()->getPremultipliedImageData(effectBDrawingRect)); - CanvasPixelArray* srcPixelArrayB(imageData->data()); + RefPtr<ImageData> imageData = in2->resultImage()->getPremultipliedImageData(effectBDrawingRect); + ByteArray* srcPixelArrayB = imageData->data()->data(); arithmetic(srcPixelArrayA, srcPixelArrayB, m_k1, m_k2, m_k3, m_k4); resultImage()->putPremultipliedImageData(imageData.get(), IntRect(IntPoint(), resultImage()->size()), IntPoint()); diff --git a/WebCore/platform/graphics/filters/FEDisplacementMap.cpp b/WebCore/platform/graphics/filters/FEDisplacementMap.cpp index 0c53241..4c62ca7 100644 --- a/WebCore/platform/graphics/filters/FEDisplacementMap.cpp +++ b/WebCore/platform/graphics/filters/FEDisplacementMap.cpp @@ -26,7 +26,6 @@ #if ENABLE(FILTERS) #include "FEDisplacementMap.h" -#include "CanvasPixelArray.h" #include "Filter.h" #include "GraphicsContext.h" #include "ImageData.h" @@ -93,13 +92,16 @@ void FEDisplacementMap::apply(Filter* filter) return; IntRect effectADrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect()); - RefPtr<CanvasPixelArray> srcPixelArrayA(in->resultImage()->getPremultipliedImageData(effectADrawingRect)->data()); + RefPtr<ImageData> srcImageDataA = in->resultImage()->getPremultipliedImageData(effectADrawingRect); + ByteArray* srcPixelArrayA = srcImageDataA->data()->data() ; IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->absolutePaintRect()); - RefPtr<CanvasPixelArray> srcPixelArrayB(in2->resultImage()->getUnmultipliedImageData(effectBDrawingRect)->data()); + RefPtr<ImageData> srcImageDataB = in2->resultImage()->getUnmultipliedImageData(effectBDrawingRect); + ByteArray* srcPixelArrayB = srcImageDataB->data()->data(); IntRect imageRect(IntPoint(), resultImage()->size()); RefPtr<ImageData> imageData = ImageData::create(imageRect.width(), imageRect.height()); + ByteArray* dstPixelArray = imageData->data()->data(); ASSERT(srcPixelArrayA->length() == srcPixelArrayB->length()); @@ -116,10 +118,10 @@ void FEDisplacementMap::apply(Filter* filter) int srcY = y + static_cast<int>(scaleY * srcPixelArrayB->get(dstIndex + m_yChannelSelector - 1) + scaleAdjustmentY); for (unsigned channel = 0; channel < 4; ++channel) { if (srcX < 0 || srcX >= imageRect.width() || srcY < 0 || srcY >= imageRect.height()) - imageData->data()->set(dstIndex + channel, static_cast<unsigned char>(0)); + dstPixelArray->set(dstIndex + channel, static_cast<unsigned char>(0)); else { unsigned char pixelValue = srcPixelArrayA->get(srcY * stride + srcX * 4 + channel); - imageData->data()->set(dstIndex + channel, pixelValue); + dstPixelArray->set(dstIndex + channel, pixelValue); } } diff --git a/WebCore/platform/graphics/filters/FEGaussianBlur.cpp b/WebCore/platform/graphics/filters/FEGaussianBlur.cpp index 1f36ba7..bb70537 100644 --- a/WebCore/platform/graphics/filters/FEGaussianBlur.cpp +++ b/WebCore/platform/graphics/filters/FEGaussianBlur.cpp @@ -27,10 +27,10 @@ #if ENABLE(FILTERS) #include "FEGaussianBlur.h" -#include "CanvasPixelArray.h" #include "Filter.h" #include "GraphicsContext.h" #include "ImageData.h" + #include <wtf/MathExtras.h> using std::max; @@ -72,7 +72,7 @@ void FEGaussianBlur::setStdDeviationY(float y) m_stdY = y; } -static void boxBlur(CanvasPixelArray*& srcPixelArray, CanvasPixelArray*& dstPixelArray, +inline void boxBlur(ByteArray* srcPixelArray, ByteArray* dstPixelArray, unsigned dx, int dxLeft, int dxRight, int stride, int strideLine, int effectWidth, int effectHeight, bool alphaImage) { for (int y = 0; y < effectHeight; ++y) { @@ -175,7 +175,7 @@ void FEGaussianBlur::apply(Filter* filter) setIsAlphaImage(in->isAlphaImage()); IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect()); - RefPtr<ImageData> srcImageData(in->resultImage()->getPremultipliedImageData(effectDrawingRect)); + RefPtr<ImageData> srcImageData = in->resultImage()->getPremultipliedImageData(effectDrawingRect); IntRect imageRect(IntPoint(), resultImage()->size()); if (!m_stdX && !m_stdY) { @@ -187,9 +187,9 @@ void FEGaussianBlur::apply(Filter* filter) unsigned kernelSizeY = 0; calculateKernelSize(filter, kernelSizeX, kernelSizeY, m_stdX, m_stdY); - CanvasPixelArray* srcPixelArray(srcImageData->data()); + ByteArray* srcPixelArray = srcImageData->data()->data(); RefPtr<ImageData> tmpImageData = ImageData::create(imageRect.width(), imageRect.height()); - CanvasPixelArray* tmpPixelArray(tmpImageData->data()); + ByteArray* tmpPixelArray = tmpImageData->data()->data(); int stride = 4 * imageRect.width(); int dxLeft = 0; @@ -201,7 +201,7 @@ void FEGaussianBlur::apply(Filter* filter) kernelPosition(i, kernelSizeX, dxLeft, dxRight); boxBlur(srcPixelArray, tmpPixelArray, kernelSizeX, dxLeft, dxRight, 4, stride, imageRect.width(), imageRect.height(), isAlphaImage()); } else { - CanvasPixelArray* auxPixelArray = tmpPixelArray; + ByteArray* auxPixelArray = tmpPixelArray; tmpPixelArray = srcPixelArray; srcPixelArray = auxPixelArray; } @@ -210,7 +210,7 @@ void FEGaussianBlur::apply(Filter* filter) kernelPosition(i, kernelSizeY, dyLeft, dyRight); boxBlur(tmpPixelArray, srcPixelArray, kernelSizeY, dyLeft, dyRight, stride, 4, imageRect.height(), imageRect.width(), isAlphaImage()); } else { - CanvasPixelArray* auxPixelArray = tmpPixelArray; + ByteArray* auxPixelArray = tmpPixelArray; tmpPixelArray = srcPixelArray; srcPixelArray = auxPixelArray; } diff --git a/WebCore/platform/graphics/filters/FEMorphology.cpp b/WebCore/platform/graphics/filters/FEMorphology.cpp index ac26441..0b67f9a 100644 --- a/WebCore/platform/graphics/filters/FEMorphology.cpp +++ b/WebCore/platform/graphics/filters/FEMorphology.cpp @@ -26,7 +26,6 @@ #if ENABLE(FILTERS) #include "FEMorphology.h" -#include "CanvasPixelArray.h" #include "Filter.h" #include "ImageData.h" @@ -108,8 +107,10 @@ void FEMorphology::apply(Filter* filter) IntRect imageRect(IntPoint(), resultImage()->size()); IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect()); - RefPtr<CanvasPixelArray> srcPixelArray(in->resultImage()->getPremultipliedImageData(effectDrawingRect)->data()); + RefPtr<ImageData> srcImageData = in->resultImage()->getPremultipliedImageData(effectDrawingRect); + ByteArray* srcPixelArray = srcImageData->data()->data(); RefPtr<ImageData> imageData = ImageData::create(imageRect.width(), imageRect.height()); + ByteArray* dstPixelArray = imageData->data()->data(); int effectWidth = effectDrawingRect.width() * 4; @@ -155,7 +156,7 @@ void FEMorphology::apply(Filter* filter) (m_type == FEMORPHOLOGY_OPERATOR_DILATE && extrema[kernelIndex] >= entireExtrema)) entireExtrema = extrema[kernelIndex]; } - imageData->data()->set(y * effectWidth + 4 * x + channel, entireExtrema); + dstPixelArray->set(y * effectWidth + 4 * x + channel, entireExtrema); } } } diff --git a/WebCore/platform/graphics/filters/FETile.cpp b/WebCore/platform/graphics/filters/FETile.cpp index a695d3b..57160ed 100644 --- a/WebCore/platform/graphics/filters/FETile.cpp +++ b/WebCore/platform/graphics/filters/FETile.cpp @@ -41,14 +41,6 @@ PassRefPtr<FETile> FETile::create() return adoptRef(new FETile); } -FloatRect FETile::determineFilterPrimitiveSubregion(Filter* filter) -{ - inputEffect(0)->determineFilterPrimitiveSubregion(filter); - - filter->determineFilterPrimitiveSubregion(this, filter->filterRegionInUserSpace()); - return filterPrimitiveSubregion(); -} - void FETile::apply(Filter* filter) { // FIXME: See bug 47315. This is a hack to work around a compile failure, but is incorrect behavior otherwise. diff --git a/WebCore/platform/graphics/filters/FETile.h b/WebCore/platform/graphics/filters/FETile.h index 8562c90..5f21433 100644 --- a/WebCore/platform/graphics/filters/FETile.h +++ b/WebCore/platform/graphics/filters/FETile.h @@ -37,10 +37,10 @@ public: virtual void determineAbsolutePaintRect(Filter*) { setAbsolutePaintRect(maxEffectRect()); } + virtual FilterEffectType filterEffectType() const { return FilterEffectTypeTile; } + virtual TextStream& externalRepresentation(TextStream&, int indention) const; - virtual FloatRect determineFilterPrimitiveSubregion(Filter*); - private: FETile(); }; diff --git a/WebCore/platform/graphics/filters/FETurbulence.cpp b/WebCore/platform/graphics/filters/FETurbulence.cpp index b1494a5..9ad27cf 100644 --- a/WebCore/platform/graphics/filters/FETurbulence.cpp +++ b/WebCore/platform/graphics/filters/FETurbulence.cpp @@ -26,7 +26,6 @@ #if ENABLE(FILTERS) #include "FETurbulence.h" -#include "CanvasPixelArray.h" #include "Filter.h" #include "ImageData.h" @@ -329,6 +328,7 @@ void FETurbulence::apply(Filter* filter) return; RefPtr<ImageData> imageData = ImageData::create(imageRect.width(), imageRect.height()); + ByteArray* pixelArray = imageData->data()->data(); PaintingData paintingData(m_seed, roundedIntSize(filterPrimitiveSubregion().size())); initPaint(paintingData); @@ -342,7 +342,7 @@ void FETurbulence::apply(Filter* filter) for (int x = 0; x < imageRect.width(); ++x) { point.setX(point.x() + 1); for (paintingData.channel = 0; paintingData.channel < 4; ++paintingData.channel, ++indexOfPixelChannel) - imageData->data()->set(indexOfPixelChannel, calculateTurbulenceValueForPoint(paintingData, filter->mapAbsolutePointToLocalPoint(point))); + pixelArray->set(indexOfPixelChannel, calculateTurbulenceValueForPoint(paintingData, filter->mapAbsolutePointToLocalPoint(point))); } } resultImage()->putUnmultipliedImageData(imageData.get(), imageRect, IntPoint()); diff --git a/WebCore/platform/graphics/filters/Filter.h b/WebCore/platform/graphics/filters/Filter.h index 121e389..33cf724 100644 --- a/WebCore/platform/graphics/filters/Filter.h +++ b/WebCore/platform/graphics/filters/Filter.h @@ -52,12 +52,8 @@ namespace WebCore { virtual FloatPoint mapAbsolutePointToLocalPoint(const FloatPoint&) const { return FloatPoint(); } - // SVG specific - virtual void determineFilterPrimitiveSubregion(FilterEffect*, const FloatRect&) { } - virtual FloatRect filterRegionInUserSpace() const { return FloatRect(); } - virtual FloatSize maxImageSize() const = 0; virtual bool effectBoundingBoxMode() const = 0; private: diff --git a/WebCore/platform/graphics/filters/FilterEffect.cpp b/WebCore/platform/graphics/filters/FilterEffect.cpp index 121b921..ad351a5 100644 --- a/WebCore/platform/graphics/filters/FilterEffect.cpp +++ b/WebCore/platform/graphics/filters/FilterEffect.cpp @@ -39,23 +39,6 @@ FilterEffect::~FilterEffect() { } -FloatRect FilterEffect::determineFilterPrimitiveSubregion(Filter* filter) -{ - FloatRect uniteRect; - unsigned size = m_inputEffects.size(); - - // FETurbulence, FEImage and FEFlood don't have input effects, take the filter region as unite rect. - if (!size) - uniteRect = filter->filterRegionInUserSpace(); - else { - for (unsigned i = 0; i < size; ++i) - uniteRect.unite(m_inputEffects.at(i)->determineFilterPrimitiveSubregion(filter)); - } - - filter->determineFilterPrimitiveSubregion(this, uniteRect); - return m_filterPrimitiveSubregion; -} - void FilterEffect::determineAbsolutePaintRect(Filter*) { m_absolutePaintRect = IntRect(); diff --git a/WebCore/platform/graphics/filters/FilterEffect.h b/WebCore/platform/graphics/filters/FilterEffect.h index a614b59..25db57b 100644 --- a/WebCore/platform/graphics/filters/FilterEffect.h +++ b/WebCore/platform/graphics/filters/FilterEffect.h @@ -99,9 +99,6 @@ public: bool hasHeight() const { return m_hasHeight; } void setHasHeight(bool value) { m_hasHeight = value; } - // FIXME: FETile still needs special handling. - virtual FloatRect determineFilterPrimitiveSubregion(Filter*); - FloatRect filterPrimitiveSubregion() const { return m_filterPrimitiveSubregion; } void setFilterPrimitiveSubregion(const FloatRect& filterPrimitiveSubregion) { m_filterPrimitiveSubregion = filterPrimitiveSubregion; } diff --git a/WebCore/platform/graphics/gtk/FontCustomPlatformDataPango.cpp b/WebCore/platform/graphics/gtk/FontCustomPlatformDataPango.cpp index d5f3173..a158689 100644 --- a/WebCore/platform/graphics/gtk/FontCustomPlatformDataPango.cpp +++ b/WebCore/platform/graphics/gtk/FontCustomPlatformDataPango.cpp @@ -30,7 +30,7 @@ FontCustomPlatformData::~FontCustomPlatformData() { } -FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontRenderingMode) +FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, FontRenderingMode) { return FontPlatformData(m_fontFace, size, bold, italic); } diff --git a/WebCore/platform/graphics/gtk/FontPlatformDataPango.h b/WebCore/platform/graphics/gtk/FontPlatformDataPango.h index 7b1e51f..c42af7f 100644 --- a/WebCore/platform/graphics/gtk/FontPlatformDataPango.h +++ b/WebCore/platform/graphics/gtk/FontPlatformDataPango.h @@ -71,7 +71,7 @@ public: unsigned hash() const { uintptr_t hashCodes[1] = { reinterpret_cast<uintptr_t>(m_scaledFont) }; - return StringImpl::computeHash(reinterpret_cast<UChar*>(hashCodes), sizeof(hashCodes) / sizeof(UChar)); + return WTF::StringHasher::createBlobHash<sizeof(hashCodes)>(hashCodes); } bool operator==(const FontPlatformData&) const; diff --git a/WebCore/platform/graphics/haiku/FontCustomPlatformData.cpp b/WebCore/platform/graphics/haiku/FontCustomPlatformData.cpp index 4b39fdd..ce7ec46 100644 --- a/WebCore/platform/graphics/haiku/FontCustomPlatformData.cpp +++ b/WebCore/platform/graphics/haiku/FontCustomPlatformData.cpp @@ -31,7 +31,7 @@ FontCustomPlatformData::~FontCustomPlatformData() { } -FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontRenderingMode) +FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, FontRenderingMode) { return FontPlatformData(size, bold, italic); } diff --git a/WebCore/platform/graphics/haiku/FontCustomPlatformData.h b/WebCore/platform/graphics/haiku/FontCustomPlatformData.h index a7dfe37..cc348e3 100644 --- a/WebCore/platform/graphics/haiku/FontCustomPlatformData.h +++ b/WebCore/platform/graphics/haiku/FontCustomPlatformData.h @@ -21,6 +21,7 @@ #ifndef FontCustomPlatformData_h #define FontCustomPlatformData_h +#include "FontOrientation.h" #include "FontRenderingMode.h" #include <wtf/Forward.h> #include <wtf/Noncopyable.h> @@ -37,7 +38,7 @@ namespace WebCore { static bool supportsFormat(const String&); - FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontRenderingMode = NormalRenderingMode); + FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, FontRenderingMode = NormalRenderingMode); }; FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer*); diff --git a/WebCore/platform/graphics/mac/FontCacheMac.mm b/WebCore/platform/graphics/mac/FontCacheMac.mm index 0747dd7..313db1c 100644 --- a/WebCore/platform/graphics/mac/FontCacheMac.mm +++ b/WebCore/platform/graphics/mac/FontCacheMac.mm @@ -142,7 +142,8 @@ const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, cons FontPlatformData alternateFont(substituteFont, !font.isPlatformFont() && isAppKitFontWeightBold(weight) && !isAppKitFontWeightBold(substituteFontWeight), - !font.isPlatformFont() && (traits & NSFontItalicTrait) && !(substituteFontTraits & NSFontItalicTrait)); + !font.isPlatformFont() && (traits & NSFontItalicTrait) && !(substituteFontTraits & NSFontItalicTrait), + platformData.m_orientation); return getCachedFontData(&alternateFont); } @@ -210,7 +211,7 @@ FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontD bool syntheticBold = isAppKitFontWeightBold(weight) && !isAppKitFontWeightBold(actualWeight); bool syntheticOblique = (traits & NSFontItalicTrait) && !(actualTraits & NSFontItalicTrait); - return new FontPlatformData(platformFont, syntheticBold, syntheticOblique); + return new FontPlatformData(platformFont, syntheticBold, syntheticOblique, fontDescription.orientation()); } } // namespace WebCore diff --git a/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp b/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp index a600d73..cead71b 100644 --- a/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp +++ b/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp @@ -38,9 +38,9 @@ FontCustomPlatformData::~FontCustomPlatformData() CGFontRelease(m_cgFont); } -FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontRenderingMode) +FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation orientation, FontRenderingMode) { - return FontPlatformData(m_cgFont, (ATSUFontID)m_atsFont, size, bold, italic); + return FontPlatformData(m_cgFont, (ATSUFontID)m_atsFont, size, bold, italic, orientation); } FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer) diff --git a/WebCore/platform/graphics/mac/FontCustomPlatformData.h b/WebCore/platform/graphics/mac/FontCustomPlatformData.h index 90440d5..7702457 100644 --- a/WebCore/platform/graphics/mac/FontCustomPlatformData.h +++ b/WebCore/platform/graphics/mac/FontCustomPlatformData.h @@ -21,6 +21,7 @@ #ifndef FontCustomPlatformData_h #define FontCustomPlatformData_h +#include "FontOrientation.h" #include "FontRenderingMode.h" #include <CoreFoundation/CFBase.h> #include <wtf/Forward.h> @@ -41,7 +42,7 @@ struct FontCustomPlatformData : Noncopyable { {} ~FontCustomPlatformData(); - FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontRenderingMode = NormalRenderingMode); + FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, FontRenderingMode = NormalRenderingMode); static bool supportsFormat(const String&); diff --git a/WebCore/platform/graphics/mac/FontMac.mm b/WebCore/platform/graphics/mac/FontMac.mm index 33a930b..d760f5a 100644 --- a/WebCore/platform/graphics/mac/FontMac.mm +++ b/WebCore/platform/graphics/mac/FontMac.mm @@ -47,10 +47,29 @@ bool Font::canReturnFallbackFontsForComplexText() return true; } -static void showGlyphsWithAdvances(const FontPlatformData& font, CGContextRef context, const CGGlyph* glyphs, const CGSize* advances, size_t count) +static void showGlyphsWithAdvances(const SimpleFontData* font, CGContextRef context, const CGGlyph* glyphs, const CGSize* advances, size_t count) { - if (!font.isColorBitmapFont()) + const FontPlatformData& platformData = font->platformData(); + if (!platformData.isColorBitmapFont()) { + CGAffineTransform savedMatrix; + bool isVertical = platformData.orientation() == Vertical; + + if (isVertical) { + CGAffineTransform rotateLeftTransform = CGAffineTransformMake(0, -1, 1, 0, 0, 0); + + savedMatrix = CGContextGetTextMatrix(context); + CGAffineTransform runMatrix = CGAffineTransformConcat(savedMatrix, rotateLeftTransform); + // Move start point to put glyphs into original region. + runMatrix.tx = savedMatrix.tx + font->ascent(); + runMatrix.ty = savedMatrix.ty + font->descent(); + CGContextSetTextMatrix(context, runMatrix); + } + CGContextShowGlyphsWithAdvances(context, glyphs, advances, count); + + if (isVertical) + CGContextSetTextMatrix(context, savedMatrix); + } #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) else { if (!count) @@ -64,7 +83,7 @@ static void showGlyphsWithAdvances(const FontPlatformData& font, CGContextRef co positions[i].x = positions[i - 1].x + advance.width; positions[i].y = positions[i - 1].y + advance.height; } - CTFontDrawGlyphs(font.ctFont(), glyphs, positions.data(), count, context); + CTFontDrawGlyphs(platformData.ctFont(), glyphs, positions.data(), count, context); } #endif } @@ -149,19 +168,19 @@ void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, cons Color shadowFillColor(shadowColor.red(), shadowColor.green(), shadowColor.blue(), shadowColor.alpha() * fillColor.alpha() / 255); context->setFillColor(shadowFillColor, fillColorSpace); CGContextSetTextPosition(cgContext, point.x() + shadowOffset.width(), point.y() + shadowOffset.height()); - showGlyphsWithAdvances(platformData, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs); + showGlyphsWithAdvances(font, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs); if (font->syntheticBoldOffset()) { CGContextSetTextPosition(cgContext, point.x() + shadowOffset.width() + font->syntheticBoldOffset(), point.y() + shadowOffset.height()); - showGlyphsWithAdvances(platformData, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs); + showGlyphsWithAdvances(font, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs); } context->setFillColor(fillColor, fillColorSpace); } CGContextSetTextPosition(cgContext, point.x(), point.y()); - showGlyphsWithAdvances(platformData, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs); + showGlyphsWithAdvances(font, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs); if (font->syntheticBoldOffset()) { CGContextSetTextPosition(cgContext, point.x() + font->syntheticBoldOffset(), point.y()); - showGlyphsWithAdvances(platformData, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs); + showGlyphsWithAdvances(font, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs); } if (hasSimpleShadow) diff --git a/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp b/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp index 143e665..48ad1c0 100644 --- a/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp +++ b/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp @@ -40,15 +40,70 @@ bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned b bool haveGlyphs = false; #ifndef BUILDING_ON_TIGER - Vector<CGGlyph, 512> glyphs(bufferLength); - wkGetGlyphsForCharacters(fontData->platformData().cgFont(), buffer, glyphs.data(), bufferLength); + if (fontData->platformData().orientation() == Horizontal) { + Vector<CGGlyph, 512> glyphs(bufferLength); + wkGetGlyphsForCharacters(fontData->platformData().cgFont(), buffer, glyphs.data(), bufferLength); + for (unsigned i = 0; i < length; ++i) { + if (!glyphs[i]) + setGlyphDataForIndex(offset + i, 0, 0); + else { + setGlyphDataForIndex(offset + i, glyphs[i], fontData); + haveGlyphs = true; + } + } + } else { + // We ask CoreText for possible vertical variant glyphs + RetainPtr<CFStringRef> string(AdoptCF, CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault, buffer, bufferLength, kCFAllocatorNull)); + RetainPtr<CFAttributedStringRef> attributedString(AdoptCF, CFAttributedStringCreate(kCFAllocatorDefault, string.get(), fontData->getCFStringAttributes(0))); + RetainPtr<CTLineRef> line(AdoptCF, CTLineCreateWithAttributedString(attributedString.get())); - for (unsigned i = 0; i < length; ++i) { - if (!glyphs[i]) - setGlyphDataForIndex(offset + i, 0, 0); - else { - setGlyphDataForIndex(offset + i, glyphs[i], fontData); - haveGlyphs = true; + CFArrayRef runArray = CTLineGetGlyphRuns(line.get()); + CFIndex runCount = CFArrayGetCount(runArray); + + // Initialize glyph entries + for (unsigned index = 0; index < length; ++index) + setGlyphDataForIndex(offset + index, 0, 0); + + Vector<CGGlyph, 512> glyphVector; + Vector<CFIndex, 512> indexVector; + bool done = false; + for (CFIndex r = 0; r < runCount && !done ; ++r) { + // CTLine could map characters over multiple fonts using its own font fallback list. + // We need to pick runs that use the exact font we need, i.e., fontData->platformData().ctFont(). + CTRunRef ctRun = static_cast<CTRunRef>(CFArrayGetValueAtIndex(runArray, r)); + ASSERT(CFGetTypeID(ctRun) == CTRunGetTypeID()); + + CFDictionaryRef attributes = CTRunGetAttributes(ctRun); + CTFontRef runFont = static_cast<CTFontRef>(CFDictionaryGetValue(attributes, kCTFontAttributeName)); + RetainPtr<CGFontRef> runCGFont(AdoptCF, CTFontCopyGraphicsFont(runFont, 0)); + // Use CGFont here as CFEqual for CTFont counts all attributes for font. + if (CFEqual(fontData->platformData().cgFont(), runCGFont.get())) { + // This run uses the font we want. Extract glyphs. + CFIndex glyphCount = CTRunGetGlyphCount(ctRun); + const CGGlyph* glyphs = CTRunGetGlyphsPtr(ctRun); + if (!glyphs) { + glyphVector.resize(glyphCount); + CTRunGetGlyphs(ctRun, CFRangeMake(0, 0), glyphVector.data()); + glyphs = glyphVector.data(); + } + const CFIndex* stringIndices = CTRunGetStringIndicesPtr(ctRun); + if (!stringIndices) { + indexVector.resize(glyphCount); + CTRunGetStringIndices(ctRun, CFRangeMake(0, 0), indexVector.data()); + stringIndices = indexVector.data(); + } + + for (CFIndex i = 0; i < glyphCount; ++i) { + if (stringIndices[i] >= static_cast<CFIndex>(length)) { + done = true; + break; + } + if (glyphs[i]) { + setGlyphDataForIndex(offset + stringIndices[i], glyphs[i], fontData); + haveGlyphs = true; + } + } + } } } #else diff --git a/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm b/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm index e079b44..78d004a 100644 --- a/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm +++ b/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm @@ -210,6 +210,8 @@ GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs, HostWi m_compiler.setResources(ANGLEResources); ::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); + ::glEnable(GL_POINT_SPRITE); + ::glClearColor(0, 0, 0, 0); } diff --git a/WebCore/platform/graphics/mac/SimpleFontDataCoreText.cpp b/WebCore/platform/graphics/mac/SimpleFontDataCoreText.cpp index 4fb525f..01d75ee 100644 --- a/WebCore/platform/graphics/mac/SimpleFontDataCoreText.cpp +++ b/WebCore/platform/graphics/mac/SimpleFontDataCoreText.cpp @@ -30,8 +30,6 @@ #import "config.h" #import "SimpleFontData.h" -#if USE(CORE_TEXT) - #import "Font.h" #import "FontCache.h" #import "FontDescription.h" @@ -60,16 +58,16 @@ CFDictionaryRef SimpleFontData::getCFStringAttributes(TypesettingFeatures typese if (!(typesettingFeatures & Kerning)) { static const float kerningAdjustmentValue = 0; static CFNumberRef kerningAdjustment = CFNumberCreate(kCFAllocatorDefault, kCFNumberFloatType, &kerningAdjustmentValue); - static const void* keysWithKerningDisabled[] = { kCTFontAttributeName, kCTKernAttributeName, kCTLigatureAttributeName }; + static const void* keysWithKerningDisabled[] = { kCTFontAttributeName, kCTKernAttributeName, kCTLigatureAttributeName, kCTVerticalFormsAttributeName }; const void* valuesWithKerningDisabled[] = { platformData().ctFont(), kerningAdjustment, allowLigatures - ? ligaturesAllowed : ligaturesNotAllowed }; + ? ligaturesAllowed : ligaturesNotAllowed, platformData().orientation() == Vertical ? kCFBooleanTrue : kCFBooleanFalse }; attributesDictionary.adoptCF(CFDictionaryCreate(0, keysWithKerningDisabled, valuesWithKerningDisabled, sizeof(keysWithKerningDisabled) / sizeof(*keysWithKerningDisabled), &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); } else { // By omitting the kCTKernAttributeName attribute, we get Core Text's standard kerning. - static const void* keysWithKerningEnabled[] = { kCTFontAttributeName, kCTLigatureAttributeName }; - const void* valuesWithKerningEnabled[] = { platformData().ctFont(), allowLigatures ? ligaturesAllowed : ligaturesNotAllowed }; + static const void* keysWithKerningEnabled[] = { kCTFontAttributeName, kCTLigatureAttributeName, kCTVerticalFormsAttributeName }; + const void* valuesWithKerningEnabled[] = { platformData().ctFont(), allowLigatures ? ligaturesAllowed : ligaturesNotAllowed, platformData().orientation() == Vertical ? kCFBooleanTrue : kCFBooleanFalse }; attributesDictionary.adoptCF(CFDictionaryCreate(0, keysWithKerningEnabled, valuesWithKerningEnabled, sizeof(keysWithKerningEnabled) / sizeof(*keysWithKerningEnabled), &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); @@ -79,5 +77,3 @@ CFDictionaryRef SimpleFontData::getCFStringAttributes(TypesettingFeatures typese } } // namespace WebCore - -#endif diff --git a/WebCore/platform/graphics/mac/SimpleFontDataMac.mm b/WebCore/platform/graphics/mac/SimpleFontDataMac.mm index 94fcc5e..fd57630 100644 --- a/WebCore/platform/graphics/mac/SimpleFontDataMac.mm +++ b/WebCore/platform/graphics/mac/SimpleFontDataMac.mm @@ -277,6 +277,11 @@ void SimpleFontData::platformInit() #else m_xHeight = m_platformData.font() ? [m_platformData.font() xHeight] : 0; #endif + // CGFontGetXHeight() returns a wrong value for "Apple Symbols" font (a float close to 0, but not strictly 0). + // The following code makes a guess for m_xHeight in that case. + // The int cast is a workaround for the "almost" zero value returned by CGFontGetXHeight(). + if (!static_cast<int>(m_xHeight) && fAscent) + m_xHeight = 2 * fAscent / 3; } } @@ -417,11 +422,9 @@ FloatRect SimpleFontData::platformBoundsForGlyph(Glyph glyph) const { FloatRect boundingBox; #ifndef BUILDING_ON_TIGER - CGRect box; - CGFontGetGlyphBBoxes(platformData().cgFont(), &glyph, 1, &box); - float pointSize = platformData().m_size; - CGFloat scale = pointSize / unitsPerEm(); - boundingBox = CGRectApplyAffineTransform(box, CGAffineTransformMakeScale(scale, -scale)); + boundingBox = CTFontGetBoundingRectsForGlyphs(m_platformData.ctFont(), + m_platformData.orientation() == Vertical ? kCTFontVerticalOrientation : kCTFontHorizontalOrientation, &glyph, 0, 1); + boundingBox.setY(-boundingBox.bottom()); #else // FIXME: Custom fonts don't have NSFonts, so this function doesn't compute correct bounds for these on Tiger. if (!m_platformData.font()) @@ -437,14 +440,18 @@ FloatRect SimpleFontData::platformBoundsForGlyph(Glyph glyph) const float SimpleFontData::platformWidthForGlyph(Glyph glyph) const { - NSFont* font = platformData().font(); - float pointSize = platformData().m_size; - CGAffineTransform m = CGAffineTransformMakeScale(pointSize, pointSize); CGSize advance; - if (!wkGetGlyphTransformedAdvances(platformData().cgFont(), font, &m, &glyph, &advance)) { - LOG_ERROR("Unable to cache glyph widths for %@ %f", [font displayName], pointSize); - advance.width = 0; - } + if (m_platformData.orientation() == Horizontal) { + NSFont* font = platformData().font(); + float pointSize = platformData().m_size; + CGAffineTransform m = CGAffineTransformMakeScale(pointSize, pointSize); + if (!wkGetGlyphTransformedAdvances(platformData().cgFont(), font, &m, &glyph, &advance)) { + LOG_ERROR("Unable to cache glyph widths for %@ %f", [font displayName], pointSize); + advance.width = 0; + } + } else + CTFontGetAdvancesForGlyphs(m_platformData.ctFont(), kCTFontVerticalOrientation, &glyph, &advance, 1); + return advance.width + m_syntheticBoldOffset; } diff --git a/WebCore/platform/graphics/opengl/TextureMapperGL.cpp b/WebCore/platform/graphics/opengl/TextureMapperGL.cpp new file mode 100644 index 0000000..6527ce4 --- /dev/null +++ b/WebCore/platform/graphics/opengl/TextureMapperGL.cpp @@ -0,0 +1,591 @@ +/* + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "TextureMapperGL.h" + +#include "GraphicsContext.h" +#include "HashMap.h" +#include "Image.h" +#include "PassRefPtr.h" +#include "RefCounted.h" +#include "Timer.h" + +#if defined(TEXMAP_OPENGL_ES_2) +#include <GLES2/gl2.h> +#elif OS(MAC_OS_X) +#include <gl.h> +#else +#include <GL/gl.h> +#endif + +#ifndef TEXMAP_OPENGL_ES2 +extern "C" { + void glUniform1f(GLint, GLfloat); + void glUniform1i(GLint, GLint); + void glVertexAttribPointer(GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid*); + void glUniform4f(GLint, GLfloat, GLfloat, GLfloat, GLfloat); + void glShaderSource(GLuint, GLsizei, const char**, const GLint*); + GLuint glCreateShader(GLenum); + void glShaderSource(GLuint, GLsizei, const char**, const GLint*); + void glCompileShader(GLuint); + void glDeleteShader(GLuint); + void glUniformMatrix4fv(GLint, GLsizei, GLboolean, const GLfloat*); + GLuint glCreateProgram(); + void glAttachShader(GLuint, GLuint); + void glLinkProgram(GLuint); + void glUseProgram(GLuint); + void glDisableVertexAttribArray(GLuint); + void glEnableVertexAttribArray(GLuint); + void glBindFramebuffer(GLenum target, GLuint framebuffer); + void glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers); + void glGenFramebuffers(GLsizei n, GLuint* framebuffers); + void glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); + void glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params); + void glBindBuffer(GLenum, GLuint); + void glDeleteBuffers(GLsizei, const GLuint*); + void glGenBuffers(GLsizei, GLuint*); + void glBufferData(GLenum, GLsizeiptr, const GLvoid*, GLenum); + void glBufferSubData(GLenum, GLsizeiptr, GLsizeiptr, const GLvoid*); + void glGetProgramInfoLog(GLuint program, GLsizei, GLsizei*, GLchar*); + +#if !OS(MAC_OS_X) + GLint glGetUniformLocation(GLuint, const GLchar*); + GLint glBindAttribLocation(GLuint, GLuint, const GLchar*); +#endif +} +#endif + +namespace WebCore { + +inline static void debugGLCommand(const char* command, int line) +{ + const GLenum err = glGetError(); + if (!err) + return; + WTFReportError(__FILE__, line, WTF_PRETTY_FUNCTION, "[TextureMapper GL] Command failed: %s (%x)\n", command, err); +} + +#define DEBUG_GL_COMMANDS + +#ifdef DEBUG_GL_COMMANDS +#define GL_CMD(x) {x, debugGLCommand(#x, __LINE__); } +#else +#define GL_CMD(x) x +#endif + +class BitmapTextureGL : public BitmapTexture { +public: + virtual void destroy(); + virtual IntSize size() const; + virtual bool isValid() const; + virtual void reset(const IntSize&, bool opaque); + virtual PlatformGraphicsContext* beginPaint(const IntRect& dirtyRect); + virtual void endPaint(); + virtual void setContentsToImage(Image*); + +private: + GLuint m_id; + NativeImagePtr m_image; + FloatSize m_relativeSize; + bool m_opaque; + IntSize m_textureSize; + RefPtr<RGBA32PremultimpliedBuffer> m_buffer; + IntRect m_dirtyRect; + GLuint m_fbo; + IntSize m_actualSize; + bool m_surfaceNeedsReset; + BitmapTextureGL() + : m_id(0) + , m_image(0) + , m_opaque(false) + , m_fbo(0) + , m_surfaceNeedsReset(true) + { + } + + friend class TextureMapperGL; +}; + +static struct TexmapShaderInfo { + enum ShaderProgramIndex { + SimpleProgram, + OpacityAndMaskProgram, + TargetProgram, + NumPrograms + }; + + enum ShaderVariableIndex { + InMatrixVariable, + InSourceMatrixVariable, + InMaskMatrixVariable, + InVertexVariable, + + OpacityVariable, + SourceTextureVariable, + MaskTextureVariable, + NumVariables + }; + + struct ProgramInfo { + GLuint id; + GLint vars[NumVariables]; + }; + + GLint getUniformLocation(ShaderProgramIndex prog, ShaderVariableIndex var, const char* name) + { + return programs[prog].vars[var] = glGetUniformLocation(programs[prog].id, name); + } + + void createShaderProgram(const char* vertexShaderSource, const char* fragmentShaderSource, ShaderProgramIndex index) + { + GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); + GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + GL_CMD(glShaderSource(vertexShader, 1, &vertexShaderSource, 0)) + GL_CMD(glShaderSource(fragmentShader, 1, &fragmentShaderSource, 0)) + GLuint programID = glCreateProgram(); + GL_CMD(glCompileShader(vertexShader)) + GL_CMD(glCompileShader(fragmentShader)) + GL_CMD(glAttachShader(programID, vertexShader)) + GL_CMD(glAttachShader(programID, fragmentShader)) + GL_CMD(glBindAttribLocation(programID, 0, "InVertex")) + GL_CMD(glLinkProgram(programID)) + programs[index].id = programID; + } + + ProgramInfo programs[NumPrograms]; + +} gShaderInfo; + +#define TEXMAP_GET_SHADER_VAR_LOCATION(prog, var) \ + if (gShaderInfo.getUniformLocation(TexmapShaderInfo::prog##Program, TexmapShaderInfo::var##Variable, #var) < 0) \ + LOG_ERROR("Couldn't find variable "#var" in program "#prog"\n"); +#define TEXMAP_BUILD_SHADER(program) gShaderInfo.createShaderProgram(vertexShaderSource##program, fragmentShaderSource##program, TexmapShaderInfo::program##Program); + +TextureMapperGL::TextureMapperGL(GraphicsContext* context) + : TextureMapper(context) + , m_currentProgram(TexmapShaderInfo::TargetProgram) +{ + static bool shadersCompiled = false; + if (shadersCompiled) + return; + shadersCompiled = true; +#ifndef TEXMAP_OPENGL_ES2 +#define OES2_PRECISION_DEFINITIONS \ + "#define lowp\n#define highp\n" +#else +#define OES2_PRECISION_DEFINITIONS +#endif + + const char* fragmentShaderSourceOpacityAndMask = + OES2_PRECISION_DEFINITIONS +" uniform sampler2D SourceTexture, MaskTexture; \n" +" uniform lowp float Opacity; \n" +" varying highp vec2 OutTexCoordSource, OutTexCoordMask; \n" +" void main(void) \n" +" { \n" +" lowp vec4 color = texture2D(SourceTexture, OutTexCoordSource); \n" +" lowp vec4 maskColor = texture2D(MaskTexture, OutTexCoordMask); \n" +" lowp float o = Opacity * maskColor.a; \n" +" gl_FragColor = vec4(color.rgb * o, color.a * o); \n" +" } \n"; + + const char* vertexShaderSourceOpacityAndMask = + OES2_PRECISION_DEFINITIONS +" uniform mat4 InMatrix, InSourceMatrix, InMaskMatrix; \n" +" attribute vec4 InVertex; \n" +" varying highp vec2 OutTexCoordSource, OutTexCoordMask; \n" +" void main(void) \n" +" { \n" +" OutTexCoordSource = vec2(InSourceMatrix * InVertex); \n" +" OutTexCoordMask = vec2(InMaskMatrix * InVertex); \n" +" gl_Position = InMatrix * InVertex; \n" +" } \n"; + + const char* fragmentShaderSourceSimple = + OES2_PRECISION_DEFINITIONS +" uniform sampler2D SourceTexture; \n" +" uniform lowp float Opacity; \n" +" varying highp vec2 OutTexCoordSource; \n" +" void main(void) \n" +" { \n" +" lowp vec4 color = texture2D(SourceTexture, OutTexCoordSource); \n" +" gl_FragColor = vec4(color.rgb * Opacity, color.a * Opacity); \n" +" } \n"; + + const char* vertexShaderSourceSimple = + OES2_PRECISION_DEFINITIONS +" uniform mat4 InMatrix, InSourceMatrix; \n" +" attribute vec4 InVertex; \n" +" varying highp vec2 OutTexCoordSource; \n" +" void main(void) \n" +" { \n" +" OutTexCoordSource = vec2(InSourceMatrix * InVertex); \n" +" gl_Position = InMatrix * InVertex; \n" +" } \n"; + + const char* fragmentShaderSourceTarget = + OES2_PRECISION_DEFINITIONS +" uniform sampler2D SourceTexture; \n" +" uniform lowp float Opacity; \n" +" varying highp vec2 OutTexCoordSource; \n" +" void main(void) \n" +" { \n" +" lowp vec4 color = texture2D(SourceTexture, OutTexCoordSource); \n" +" gl_FragColor = vec4(color.bgr * Opacity, color.a * Opacity); \n" +" } \n"; + + const char* vertexShaderSourceTarget = vertexShaderSourceSimple; + + TEXMAP_BUILD_SHADER(Simple) + TEXMAP_BUILD_SHADER(OpacityAndMask) + TEXMAP_BUILD_SHADER(Target) + + TEXMAP_GET_SHADER_VAR_LOCATION(OpacityAndMask, InMatrix) + TEXMAP_GET_SHADER_VAR_LOCATION(OpacityAndMask, InSourceMatrix) + TEXMAP_GET_SHADER_VAR_LOCATION(OpacityAndMask, InMaskMatrix) + TEXMAP_GET_SHADER_VAR_LOCATION(OpacityAndMask, SourceTexture) + TEXMAP_GET_SHADER_VAR_LOCATION(OpacityAndMask, MaskTexture) + TEXMAP_GET_SHADER_VAR_LOCATION(OpacityAndMask, Opacity) + + TEXMAP_GET_SHADER_VAR_LOCATION(Simple, InSourceMatrix) + TEXMAP_GET_SHADER_VAR_LOCATION(Simple, InMatrix) + TEXMAP_GET_SHADER_VAR_LOCATION(Simple, SourceTexture) + TEXMAP_GET_SHADER_VAR_LOCATION(Simple, Opacity) + + TEXMAP_GET_SHADER_VAR_LOCATION(Target, InSourceMatrix) + TEXMAP_GET_SHADER_VAR_LOCATION(Target, InMatrix) + TEXMAP_GET_SHADER_VAR_LOCATION(Target, SourceTexture) + TEXMAP_GET_SHADER_VAR_LOCATION(Target, Opacity) +} + +void TextureMapperGL::drawTexture(const BitmapTexture& texture, const IntRect& targetRect, const TransformationMatrix& modelViewMatrix, float opacity, const BitmapTexture* maskTexture) +{ + if (!texture.isValid()) + return; + + const BitmapTextureGL& textureGL = static_cast<const BitmapTextureGL&>(texture); + + TexmapShaderInfo::ShaderProgramIndex program; + if (maskTexture) + program = TexmapShaderInfo::OpacityAndMaskProgram; + else + program = TexmapShaderInfo::SimpleProgram; + + const TexmapShaderInfo::ProgramInfo& programInfo = gShaderInfo.programs[program]; + if (m_currentProgram != program) { + GL_CMD(glUseProgram(programInfo.id)) + GL_CMD(glDisableVertexAttribArray(gShaderInfo.programs[m_currentProgram].vars[TexmapShaderInfo::InVertexVariable])) + m_currentProgram = program; + GL_CMD(glEnableVertexAttribArray(programInfo.vars[TexmapShaderInfo::InVertexVariable])) + } + + GL_CMD(glDisable(GL_DEPTH_TEST)) + GL_CMD(glDisable(GL_STENCIL_TEST)) + + GL_CMD(glActiveTexture(GL_TEXTURE0)) + GL_CMD(glBindTexture(GL_TEXTURE_2D, textureGL.m_id)) + GL_CMD(glBindBuffer(GL_ARRAY_BUFFER, 0)) + const GLfloat unitRect[] = {0, 0, 1, 0, 1, 1, 0, 1}; + GL_CMD(glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, unitRect)) + + TransformationMatrix matrix = TransformationMatrix(m_projectionMatrix).multLeft(modelViewMatrix).multLeft(TransformationMatrix( + targetRect.width(), 0, 0, 0, + 0, targetRect.height(), 0, 0, + 0, 0, 1, 0, + targetRect.x(), targetRect.y(), 0, 1)); + + const GLfloat m4[] = { + matrix.m11(), matrix.m12(), matrix.m13(), matrix.m14(), + matrix.m21(), matrix.m22(), matrix.m23(), matrix.m24(), + matrix.m31(), matrix.m32(), matrix.m33(), matrix.m34(), + matrix.m41(), matrix.m42(), matrix.m43(), matrix.m44() + }; + const GLfloat m4src[] = {textureGL.m_relativeSize.width(), 0, 0, 0, + 0, textureGL.m_relativeSize.height(), 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1}; + GL_CMD(glUniformMatrix4fv(programInfo.vars[TexmapShaderInfo::InMatrixVariable], 1, GL_FALSE, m4)) + GL_CMD(glUniformMatrix4fv(programInfo.vars[TexmapShaderInfo::InSourceMatrixVariable], 1, GL_FALSE, m4src)) + GL_CMD(glUniform1i(programInfo.vars[TexmapShaderInfo::SourceTextureVariable], 0)) + GL_CMD(glUniform1f(programInfo.vars[TexmapShaderInfo::OpacityVariable], opacity)) + + if (maskTexture && maskTexture->isValid()) { + const BitmapTextureGL* maskTextureGL = static_cast<const BitmapTextureGL*>(maskTexture); + GL_CMD(glActiveTexture(GL_TEXTURE1)) + GL_CMD(glBindTexture(GL_TEXTURE_2D, maskTextureGL->m_id)) + const GLfloat m4mask[] = {maskTextureGL->m_relativeSize.width(), 0, 0, 0, + 0, maskTextureGL->m_relativeSize.height(), 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1}; + glUniformMatrix4fv(programInfo.vars[TexmapShaderInfo::InMaskMatrixVariable], 1, GL_FALSE, m4mask); + GL_CMD(glUniform1i(programInfo.vars[TexmapShaderInfo::MaskTextureVariable], 1)) + GL_CMD(glActiveTexture(GL_TEXTURE0)) + } + + + if (textureGL.m_opaque && opacity > 0.99 && !maskTexture) + GL_CMD(glDisable(GL_BLEND)) + else { + GL_CMD(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)) + GL_CMD(glEnable(GL_BLEND)) + } + + GL_CMD(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)) +} + + +const char* TextureMapperGL::type() const +{ + return "OpenGL"; +} + +void BitmapTextureGL::reset(const IntSize& newSize, bool opaque) +{ + BitmapTexture::reset(newSize, opaque); + m_image = 0; + IntSize newTextureSize = nextPowerOfTwo(newSize); + bool justCreated = false; + if (!m_id) { + GL_CMD(glGenTextures(1, &m_id)) + justCreated = true; + } + + if (justCreated || newTextureSize.width() > m_textureSize.width() || newTextureSize.height() > m_textureSize.height()) { + m_textureSize = newTextureSize; + GL_CMD(glBindTexture(GL_TEXTURE_2D, m_id)) + GL_CMD(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)) + GL_CMD(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)) + GL_CMD(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)) + GL_CMD(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)) + GL_CMD(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_textureSize.width(), m_textureSize.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0)) + } + m_actualSize = newSize; + m_relativeSize = FloatSize(float(newSize.width()) / m_textureSize.width(), float(newSize.height()) / m_textureSize.height()); + m_opaque = opaque; + m_surfaceNeedsReset = true; +} + +PlatformGraphicsContext* BitmapTextureGL::beginPaint(const IntRect& dirtyRect) +{ + m_buffer = RGBA32PremultimpliedBuffer::create(); + m_dirtyRect = dirtyRect; + return m_buffer->beginPaint(dirtyRect, m_opaque); +} + +void BitmapTextureGL::endPaint() +{ + if (!m_buffer) + return; + m_buffer->endPaint(); + GL_CMD(glBindTexture(GL_TEXTURE_2D, m_id)) + GL_CMD(glTexSubImage2D(GL_TEXTURE_2D, 0, m_dirtyRect.x(), m_dirtyRect.y(), m_dirtyRect.width(), m_dirtyRect.height(), GL_RGBA, GL_UNSIGNED_BYTE, m_buffer->data())) + m_buffer.clear(); +} + +struct TexmapGLShaderTextures { + struct Entry { + GLuint texture; + int refCount; + }; + HashMap<NativeImagePtr, Entry> imageToTexture; + GLuint findOrCreate(NativeImagePtr image, bool& found) + { + HashMap<NativeImagePtr, Entry>::iterator it = imageToTexture.find(image); + found = false; + if (it != imageToTexture.end()) { + it->second.refCount++; + found = true; + return it->second.texture; + } + Entry entry; + GL_CMD(glGenTextures(1, &entry.texture)); + entry.refCount = 1; + imageToTexture.add(image, entry); + return entry.texture; + } + + bool deref(NativeImagePtr image) + { + HashMap<NativeImagePtr, Entry>::iterator it = imageToTexture.find(image); + if (it != imageToTexture.end()) { + if (it->second.refCount < 2) { + imageToTexture.remove(it); + return false; + } + } + return true; + } +}; + +static TexmapGLShaderTextures gTextureRepository; + +void BitmapTextureGL::setContentsToImage(Image* image) +{ + NativeImagePtr nativeImage = image ? image->nativeImageForCurrentFrame() : 0; + if (!image || !nativeImage) { + if (m_image) + destroy(); + return; + } + + if (nativeImage == m_image) + return; + bool found = false; + GLuint newTextureID = gTextureRepository.findOrCreate(nativeImage, found); + if (newTextureID != m_id) { + destroy(); + m_id = newTextureID; + reset(image->size(), false); + m_image = nativeImage; + if (!found) { + GraphicsContext context(beginPaint(IntRect(0, 0, m_textureSize.width(), m_textureSize.height()))); + context.drawImage(image, ColorSpaceDeviceRGB, IntPoint(0, 0), CompositeCopy); + endPaint(); + } + } +} + +void BitmapTextureGL::destroy() +{ + if (m_id && (!m_image || !gTextureRepository.deref(m_image))) + GL_CMD(glDeleteTextures(1, &m_id)) + if (m_fbo) + GL_CMD(glDeleteFramebuffers(1, &m_fbo)) + + m_fbo = 0; + m_id = 0; + m_textureSize = IntSize(); + m_relativeSize = FloatSize(1, 1); +} + +bool BitmapTextureGL::isValid() const +{ + return m_id; +} + +IntSize BitmapTextureGL::size() const +{ + return m_textureSize; +} + +static inline TransformationMatrix createProjectionMatrix(const IntSize& size, bool flip) +{ + return TransformationMatrix(2.0 / float(size.width()), 0, 0, 0, + 0, (flip ? -2.0 : 2.0) / float(size.height()), 0, 0, + 0, 0, -0.000001, 0, + -1, flip ? 1 : -1, 0, 1); +} + +void TextureMapperGL::cleanup() +{ +} + +void TextureMapperGL::bindSurface(BitmapTexture *surfacePointer) +{ + BitmapTextureGL* surface = static_cast<BitmapTextureGL*>(surfacePointer); + + if (!surface) + return; + TransformationMatrix matrix = createProjectionMatrix(surface->size(), false); + matrix.translate(-surface->offset().x(), -surface->offset().y()); + + if (surface->m_surfaceNeedsReset || !surface->m_fbo) { + if (!surface->m_fbo) + GL_CMD(glGenFramebuffers(1, &surface->m_fbo)) + GL_CMD(glBindFramebuffer(GL_FRAMEBUFFER, surface->m_fbo)) + GL_CMD(glBindTexture(GL_TEXTURE_2D, 0)) + GL_CMD(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, surface->m_id, 0)) + GL_CMD(glClearColor(0, 0, 0, 0)) + GL_CMD(glClear(GL_COLOR_BUFFER_BIT)) + surface->m_surfaceNeedsReset = false; + } else { + GL_CMD(glBindFramebuffer(GL_FRAMEBUFFER, surface->m_fbo)) + } + + GL_CMD(glViewport(0, 0, surface->size().width(), surface->size().height())) + m_projectionMatrix = matrix; +} + +void TextureMapperGL::setClip(const IntRect& rect) +{ + GL_CMD(glScissor(rect.x(), rect.y(), rect.width(), rect.height())) + GL_CMD(glEnable(GL_SCISSOR_TEST)) +} + + +void TextureMapperGL::paintToTarget(const BitmapTexture& aSurface, const IntSize& surfaceSize, const TransformationMatrix& transform, float opacity, const IntRect& visibleRect) +{ + const BitmapTextureGL& surface = static_cast<const BitmapTextureGL&>(aSurface); + + // Create the model-view-projection matrix to display on screen. + TransformationMatrix matrix = createProjectionMatrix(surfaceSize, true).multLeft(transform).multLeft( + TransformationMatrix( + surface.m_actualSize.width(), 0, 0, 0, + 0, surface.m_actualSize.height(), 0, 0, + 0, 0, 1, 0, + surface.offset().x(), surface.offset().y(), 0, 1 + ) + ); + + const GLfloat m4[] = { + matrix.m11(), matrix.m12(), matrix.m13(), matrix.m14(), + matrix.m21(), matrix.m22(), matrix.m23(), matrix.m24(), + matrix.m31(), matrix.m32(), matrix.m33(), matrix.m34(), + matrix.m41(), matrix.m42(), matrix.m43(), matrix.m44() + }; + + const GLfloat m4src[] = {surface.m_relativeSize.width(), 0, 0, 0, + 0, surface.m_relativeSize.height(), 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1}; + + // We already blended the alpha in; the result is premultiplied. + GL_CMD(glUseProgram(gShaderInfo.programs[TexmapShaderInfo::TargetProgram].id)) + GL_CMD(glBindFramebuffer(GL_FRAMEBUFFER, 0)) + GL_CMD(glViewport(0, 0, surfaceSize.width(), surfaceSize.height())) + GL_CMD(glDisable(GL_STENCIL_TEST)) + const TexmapShaderInfo::ProgramInfo& programInfo = gShaderInfo.programs[TexmapShaderInfo::TargetProgram]; + GL_CMD(glUniform1f(programInfo.vars[TexmapShaderInfo::OpacityVariable], opacity)) + GL_CMD(glActiveTexture(GL_TEXTURE0)) + GL_CMD(glBindTexture(GL_TEXTURE_2D, surface.m_id)) + GL_CMD(glUniform1i(programInfo.vars[TexmapShaderInfo::SourceTextureVariable], 0)) + GL_CMD(glEnableVertexAttribArray(programInfo.vars[TexmapShaderInfo::InVertexVariable])) + GL_CMD(glUniformMatrix4fv(programInfo.vars[TexmapShaderInfo::InMatrixVariable], 1, GL_FALSE, m4)) + GL_CMD(glUniformMatrix4fv(programInfo.vars[TexmapShaderInfo::InSourceMatrixVariable], 1, GL_FALSE, m4src)) + GL_CMD(glBindBuffer(GL_ARRAY_BUFFER, 0)) + const GLfloat unitRect[] = {0, 0, 1, 0, 1, 1, 0, 1}; + GL_CMD(glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, unitRect)) + GL_CMD(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)) + GL_CMD(glEnable(GL_BLEND)) + setClip(visibleRect); + + GL_CMD(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)) + GL_CMD(glDisableVertexAttribArray(programInfo.vars[TexmapShaderInfo::InVertexVariable])) + GL_CMD(glUseProgram(0)) + GL_CMD(glBindBuffer(GL_ARRAY_BUFFER, 0)) + m_currentProgram = TexmapShaderInfo::TargetProgram; +} + +PassRefPtr<BitmapTexture> TextureMapperGL::createTexture() +{ + return adoptRef(new BitmapTextureGL()); +} + +}; diff --git a/WebCore/platform/graphics/opengl/TextureMapperGL.h b/WebCore/platform/graphics/opengl/TextureMapperGL.h new file mode 100644 index 0000000..7a12c72 --- /dev/null +++ b/WebCore/platform/graphics/opengl/TextureMapperGL.h @@ -0,0 +1,83 @@ +/* + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + */ + +#ifndef TextureMapperGL_h +#define TextureMapperGL_h + +#if USE(ACCELERATED_COMPOSITING) + +#include "FloatQuad.h" +#include "IntSize.h" +#include "TransformationMatrix.h" +#include "texmap/TextureMapper.h" + +namespace WebCore { + +// An OpenGL-ES2 implementation of TextureMapper. +class TextureMapperGL : public TextureMapper { +public: + TextureMapperGL(GraphicsContext* gc); + virtual ~TextureMapperGL() {} + + // reimps from TextureMapper + virtual void drawTexture(const BitmapTexture& texture, const IntRect&, const TransformationMatrix& transform, float opacity, const BitmapTexture* maskTexture); + virtual void bindSurface(BitmapTexture* surface); + virtual void setClip(const IntRect&); + virtual void paintToTarget(const BitmapTexture&, const IntSize&, const TransformationMatrix&, float opacity, const IntRect& visibleRect); + virtual bool allowSurfaceForRoot() const { return true; } + virtual PassRefPtr<BitmapTexture> createTexture(); + virtual const char* type() const; + virtual void cleanup(); + +private: + TransformationMatrix m_projectionMatrix; + int m_currentProgram; +}; + +// An offscreen buffer to be rendered by software. +class RGBA32PremultimpliedBuffer : public RefCounted<RGBA32PremultimpliedBuffer> { +public: + virtual ~RGBA32PremultimpliedBuffer() {} + virtual PlatformGraphicsContext* beginPaint(const IntRect& dirtyRect, bool opaque) = 0; + virtual void endPaint() = 0; + virtual const void* data() const = 0; + static PassRefPtr<RGBA32PremultimpliedBuffer> create(); +}; + +static inline int nextPowerOfTwo(int num) +{ + for (int i = 0x10000000; i > 0; i >>= 1) { + if (num == i) + return num; + if (num & i) + return (i << 1); + } + return 1; +} + +static inline IntSize nextPowerOfTwo(const IntSize& size) +{ + return IntSize(nextPowerOfTwo(size.width()), nextPowerOfTwo(size.height())); +} + +}; + +#endif + +#endif diff --git a/WebCore/platform/graphics/qt/FontCustomPlatformData.h b/WebCore/platform/graphics/qt/FontCustomPlatformData.h index 019a6bc..6c41d47 100644 --- a/WebCore/platform/graphics/qt/FontCustomPlatformData.h +++ b/WebCore/platform/graphics/qt/FontCustomPlatformData.h @@ -22,6 +22,7 @@ #ifndef FontCustomPlatformData_h #define FontCustomPlatformData_h +#include "FontOrientation.h" #include "FontRenderingMode.h" #include <wtf/Forward.h> #include <wtf/Noncopyable.h> @@ -37,7 +38,7 @@ struct FontCustomPlatformData : Noncopyable { // for use with QFontDatabase::addApplicationFont/removeApplicationFont int m_handle; - FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontRenderingMode = NormalRenderingMode); + FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, FontRenderingMode = NormalRenderingMode); static bool supportsFormat(const String&); }; diff --git a/WebCore/platform/graphics/qt/FontCustomPlatformDataQt.cpp b/WebCore/platform/graphics/qt/FontCustomPlatformDataQt.cpp index dbf0b16..e2f009b 100644 --- a/WebCore/platform/graphics/qt/FontCustomPlatformDataQt.cpp +++ b/WebCore/platform/graphics/qt/FontCustomPlatformDataQt.cpp @@ -34,7 +34,7 @@ FontCustomPlatformData::~FontCustomPlatformData() QFontDatabase::removeApplicationFont(m_handle); } -FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontRenderingMode) +FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, FontRenderingMode) { QFont font; font.setFamily(QFontDatabase::applicationFontFamilies(m_handle)[0]); diff --git a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp index 8b34f51..50971b5 100644 --- a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp +++ b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp @@ -171,7 +171,7 @@ static inline Qt::FillRule toQtFillRule(WindRule rule) class GraphicsContextPlatformPrivate : public Noncopyable { public: - GraphicsContextPlatformPrivate(QPainter* painter); + GraphicsContextPlatformPrivate(QPainter*, const QColor& initialSolidColor); ~GraphicsContextPlatformPrivate(); inline QPainter* p() const @@ -225,42 +225,42 @@ private: }; -GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate(QPainter* p) +GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate(QPainter* p, const QColor& initialSolidColor) + : antiAliasingForRectsAndLines(false) + , layerCount(0) + , solidColor(initialSolidColor) + , imageInterpolationQuality(InterpolationDefault) + , painter(p) { - painter = p; - layerCount = 0; - - solidColor = QBrush(Qt::black); + if (!painter) + return; - imageInterpolationQuality = InterpolationDefault; + // Use the default the QPainter was constructed with. + antiAliasingForRectsAndLines = painter->testRenderHint(QPainter::Antialiasing); - if (painter) { - // use the default the QPainter was constructed with - antiAliasingForRectsAndLines = painter->testRenderHint(QPainter::Antialiasing); - // FIXME: Maybe only enable in SVG mode? - painter->setRenderHint(QPainter::Antialiasing, true); - painter->setRenderHint(QPainter::SmoothPixmapTransform, true); - } else - antiAliasingForRectsAndLines = false; + painter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform, true); } GraphicsContextPlatformPrivate::~GraphicsContextPlatformPrivate() { } -GraphicsContext::GraphicsContext(PlatformGraphicsContext* context) +GraphicsContext::GraphicsContext(PlatformGraphicsContext* painter) : m_common(createGraphicsContextPrivate()) - , m_data(new GraphicsContextPlatformPrivate(context)) + , m_data(new GraphicsContextPlatformPrivate(painter, fillColor())) { - setPaintingDisabled(!context); - if (context) { - // Make sure the context starts in sync with our state. - setPlatformFillColor(fillColor(), ColorSpaceDeviceRGB); - setPlatformStrokeColor(strokeColor(), ColorSpaceDeviceRGB); + setPaintingDisabled(!painter); - // Make sure we start with the correct join mode. - setLineJoin(MiterJoin); - } + if (!painter) + return; + + // solidColor is initialized with the fillColor(). + painter->setBrush(m_data->solidColor); + + QPen pen(painter->pen()); + pen.setColor(strokeColor()); + pen.setJoinStyle(toQtLineJoin(MiterJoin)); + painter->setPen(pen); } GraphicsContext::~GraphicsContext() diff --git a/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp b/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp index e0941f5..aa7ed2f 100644 --- a/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp +++ b/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp @@ -200,6 +200,7 @@ public: TransformationMatrix m_transformRelativeToRootLayer; bool m_transformAnimationRunning; bool m_opacityAnimationRunning; + bool m_blockNotifySyncRequired; #ifndef QT_NO_GRAPHICSEFFECT QWeakPointer<MaskEffectQt> m_maskEffect; #endif @@ -300,6 +301,7 @@ GraphicsLayerQtImpl::GraphicsLayerQtImpl(GraphicsLayerQt* newLayer) , m_layer(newLayer) , m_transformAnimationRunning(false) , m_opacityAnimationRunning(false) + , m_blockNotifySyncRequired(false) , m_changeMask(NoChanges) #if ENABLE(3D_CANVAS) , m_gc3D(0) @@ -593,6 +595,8 @@ void GraphicsLayerQtImpl::paint(QPainter* painter, const QStyleOptionGraphicsIte void GraphicsLayerQtImpl::notifySyncRequired() { + m_blockNotifySyncRequired = false; + if (m_layer->client()) m_layer->client()->notifySyncRequired(m_layer); } @@ -600,8 +604,14 @@ void GraphicsLayerQtImpl::notifySyncRequired() void GraphicsLayerQtImpl::notifyChange(ChangeMask changeMask) { m_changeMask |= changeMask; + + if (m_blockNotifySyncRequired) + return; + static QMetaMethod syncMethod = staticMetaObject.method(staticMetaObject.indexOfMethod("notifySyncRequired()")); syncMethod.invoke(this, Qt::QueuedConnection); + + m_blockNotifySyncRequired = true; } void GraphicsLayerQtImpl::flushChanges(bool recursive, bool forceUpdateTransform) diff --git a/WebCore/platform/graphics/qt/ImageBufferQt.cpp b/WebCore/platform/graphics/qt/ImageBufferQt.cpp index 0cdc894..de23297 100644 --- a/WebCore/platform/graphics/qt/ImageBufferQt.cpp +++ b/WebCore/platform/graphics/qt/ImageBufferQt.cpp @@ -157,14 +157,17 @@ void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookUpTable) QImage image = m_data.m_pixmap.toImage().convertToFormat(QImage::Format_ARGB32); ASSERT(!image.isNull()); + uchar* bits = image.bits(); + const int bytesPerLine = image.bytesPerLine(); + for (int y = 0; y < m_size.height(); ++y) { - for (int x = 0; x < m_size.width(); x++) { - QRgb value = image.pixel(x, y); - value = qRgba(lookUpTable[qRed(value)], - lookUpTable[qGreen(value)], - lookUpTable[qBlue(value)], - qAlpha(value)); - image.setPixel(x, y, value); + quint32* scanLine = reinterpret_cast_ptr<quint32*>(bits + y * bytesPerLine); + for (int x = 0; x < m_size.width(); ++x) { + QRgb& pixel = scanLine[x]; + pixel = qRgba(lookUpTable[qRed(pixel)], + lookUpTable[qGreen(pixel)], + lookUpTable[qBlue(pixel)], + qAlpha(pixel)); } } diff --git a/WebCore/platform/graphics/qt/TileQt.cpp b/WebCore/platform/graphics/qt/TileQt.cpp index 9628448..096ce14 100644 --- a/WebCore/platform/graphics/qt/TileQt.cpp +++ b/WebCore/platform/graphics/qt/TileQt.cpp @@ -97,9 +97,10 @@ void Tile::updateBackBuffer() return; if (!m_backBuffer) { - if (!m_buffer) + if (!m_buffer) { m_backBuffer = new QPixmap(m_backingStore->m_tileSize.width(), m_backingStore->m_tileSize.height()); - else { + m_backBuffer->fill(m_backingStore->m_client->tiledBackingStoreBackgroundColor()); + } else { // Currently all buffers are updated synchronously at the same time so there is no real need // to have separate back and front buffers. Just use the existing buffer. m_backBuffer = m_buffer; diff --git a/WebCore/platform/graphics/skia/FontCustomPlatformData.cpp b/WebCore/platform/graphics/skia/FontCustomPlatformData.cpp index 8301871..2ea568b 100644 --- a/WebCore/platform/graphics/skia/FontCustomPlatformData.cpp +++ b/WebCore/platform/graphics/skia/FontCustomPlatformData.cpp @@ -1,6 +1,7 @@ /* * 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 @@ -36,7 +37,7 @@ #include "Base64.h" #include "ChromiumBridge.h" #include "OpenTypeUtilities.h" -#elif OS(LINUX) || OS(FREEBSD) +#elif OS(LINUX) || OS(FREEBSD) || PLATFORM(BREWMP) #include "SkStream.h" #endif @@ -47,7 +48,7 @@ #if OS(WINDOWS) #include <objbase.h> -#elif OS(LINUX) || OS(FREEBSD) +#elif OS(LINUX) || OS(FREEBSD) || PLATFORM(BREWMP) #include <cstring> #endif @@ -58,13 +59,13 @@ FontCustomPlatformData::~FontCustomPlatformData() #if OS(WINDOWS) if (m_fontReference) RemoveFontMemResourceEx(m_fontReference); -#elif OS(LINUX) || OS(FREEBSD) +#elif OS(LINUX) || OS(FREEBSD) || PLATFORM(BREWMP) if (m_fontReference) m_fontReference->unref(); #endif } -FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontRenderingMode mode) +FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, FontRenderingMode mode) { #if OS(WINDOWS) ASSERT(m_fontReference); @@ -99,7 +100,7 @@ FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, b HFONT hfont = CreateFontIndirect(&logFont); return FontPlatformData(hfont, size); -#elif OS(LINUX) || OS(FREEBSD) +#elif OS(LINUX) || OS(FREEBSD) || PLATFORM(BREWMP) ASSERT(m_fontReference); return FontPlatformData(m_fontReference, "", size, bold && !m_fontReference->isBold(), italic && !m_fontReference->isItalic()); #else @@ -123,7 +124,7 @@ static String createUniqueFontName() } #endif -#if OS(LINUX) || OS(FREEBSD) +#if OS(LINUX) || OS(FREEBSD) || PLATFORM(BREWMP) class RemoteFontStream : public SkStream { public: explicit RemoteFontStream(PassRefPtr<SharedBuffer> buffer) @@ -189,7 +190,7 @@ FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer) if (!fontReference) return 0; return new FontCustomPlatformData(fontReference, fontName); -#elif OS(LINUX) || OS(FREEBSD) +#elif OS(LINUX) || OS(FREEBSD) || PLATFORM(BREWMP) RemoteFontStream* stream = new RemoteFontStream(buffer); SkTypeface* typeface = SkTypeface::CreateFromStream(stream); if (!typeface) diff --git a/WebCore/platform/graphics/skia/FontCustomPlatformData.h b/WebCore/platform/graphics/skia/FontCustomPlatformData.h index 94d7ec3..e51b6b6 100644 --- a/WebCore/platform/graphics/skia/FontCustomPlatformData.h +++ b/WebCore/platform/graphics/skia/FontCustomPlatformData.h @@ -32,6 +32,7 @@ #ifndef FontCustomPlatformData_h #define FontCustomPlatformData_h +#include "FontOrientation.h" #include "FontRenderingMode.h" #include <wtf/Forward.h> #include <wtf/Noncopyable.h> @@ -39,7 +40,7 @@ #if OS(WINDOWS) #include "PlatformString.h" #include <windows.h> -#elif OS(LINUX) || OS(FREEBSD) +#elif OS(LINUX) || OS(FREEBSD) || PLATFORM(BREWMP) #include "SkTypeface.h" #endif @@ -54,7 +55,7 @@ struct FontCustomPlatformData : Noncopyable { : m_fontReference(fontReference) , m_name(name) {} -#elif OS(LINUX) || OS(FREEBSD) +#elif OS(LINUX) || OS(FREEBSD) || PLATFORM(BREWMP) explicit FontCustomPlatformData(SkTypeface* typeface) : m_fontReference(typeface) {} @@ -62,7 +63,7 @@ struct FontCustomPlatformData : Noncopyable { ~FontCustomPlatformData(); - FontPlatformData fontPlatformData(int size, bool bold, bool italic, + FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, FontRenderingMode = NormalRenderingMode); static bool supportsFormat(const String&); @@ -70,7 +71,7 @@ struct FontCustomPlatformData : Noncopyable { #if OS(WINDOWS) HANDLE m_fontReference; String m_name; -#elif OS(LINUX) || OS(FREEBSD) +#elif OS(LINUX) || OS(FREEBSD) || PLATFORM(BREWMP) SkTypeface* m_fontReference; #endif }; diff --git a/WebCore/platform/graphics/chromium/GlyphPageTreeNodeLinux.cpp b/WebCore/platform/graphics/skia/GlyphPageTreeNodeSkia.cpp index 6024d43..6024d43 100644 --- a/WebCore/platform/graphics/chromium/GlyphPageTreeNodeLinux.cpp +++ b/WebCore/platform/graphics/skia/GlyphPageTreeNodeSkia.cpp diff --git a/WebCore/platform/graphics/skia/ImageSkia.cpp b/WebCore/platform/graphics/skia/ImageSkia.cpp index 23e7be6..ae2653a 100644 --- a/WebCore/platform/graphics/skia/ImageSkia.cpp +++ b/WebCore/platform/graphics/skia/ImageSkia.cpp @@ -236,12 +236,7 @@ static void paintSkBitmap(PlatformContextSkia* platformContext, const NativeImag SkPaint paint; paint.setXfermodeMode(compOp); paint.setFilterBitmap(true); - int alpha = roundf(platformContext->getAlpha() * 256); - if (alpha > 255) - alpha = 255; - else if (alpha < 0) - alpha = 0; - paint.setAlpha(alpha); + paint.setAlpha(platformContext->getNormalizedAlpha()); skia::PlatformCanvas* canvas = platformContext->canvas(); diff --git a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp index 3f9e4c1..6204597 100644 --- a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp +++ b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp @@ -510,6 +510,16 @@ 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(int mode) { // cTextClip is never used, so we assert that it isn't set: diff --git a/WebCore/platform/graphics/skia/PlatformContextSkia.h b/WebCore/platform/graphics/skia/PlatformContextSkia.h index 84e5d78..110085d 100644 --- a/WebCore/platform/graphics/skia/PlatformContextSkia.h +++ b/WebCore/platform/graphics/skia/PlatformContextSkia.h @@ -134,6 +134,7 @@ public: float getStrokeThickness() const; int getTextDrawingMode() const; float getAlpha() const; + int getNormalizedAlpha() const; void beginPath(); void addPath(const SkPath&); diff --git a/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp b/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp index cf90cb1..057bcfc 100644 --- a/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp +++ b/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp @@ -683,7 +683,6 @@ void TextureMapperNode::uploadTextureFromContent(TextureMapper* textureMapper, c || (!m_currentContent.needsDisplay && m_currentContent.needsDisplayRect.isEmpty() && !needsReset)) return; - WTF::StopWatch stopWatch; IntRect dirtyRect = IntRect(0, 0, m_size.width(), m_size.height()); if (!needsReset && !m_currentContent.needsDisplay) dirtyRect.intersect(m_currentContent.needsDisplayRect); @@ -701,15 +700,6 @@ void TextureMapperNode::uploadTextureFromContent(TextureMapper* textureMapper, c m_layer->paintGraphicsLayerContents(context, dirtyRect); } m_texture->endPaint(); - { -#if 0 - LOG("[TextureMapper] Re-render(%d) layer(%p) %d::%d::%d (%dx%d) [%dms]\n", ++renderCount, this, - needsReset, m_currentContent.needsDisplay, !m_currentContent.needsDisplayRect.isEmpty(), - dirtyRect.width(), dirtyRect.height(), int(stopWatch.elapsed() * 1000)); - static int renderCount = 0; - m_texture->save(String().format("/tmp/layer_%d.png", renderCount)); -#endif - } m_currentContent.needsDisplay = false; } @@ -739,8 +729,6 @@ void TextureMapperNode::paintSelf(const TexmapPaintOptions& options) void TextureMapperNode::paintRecursive(TexmapPaintOptions options) { - WTF::StopWatch stopWatch; - bool isDirty = m_state.dirty; m_state.dirty = false; diff --git a/WebCore/platform/graphics/win/FontCustomPlatformData.cpp b/WebCore/platform/graphics/win/FontCustomPlatformData.cpp index 6e59ad7..9cae99b 100644 --- a/WebCore/platform/graphics/win/FontCustomPlatformData.cpp +++ b/WebCore/platform/graphics/win/FontCustomPlatformData.cpp @@ -59,7 +59,7 @@ FontCustomPlatformData::~FontCustomPlatformData() } } -FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontRenderingMode renderingMode) +FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, FontRenderingMode renderingMode) { ASSERT(m_fontReference); ASSERT(T2embedLibrary()); diff --git a/WebCore/platform/graphics/win/FontCustomPlatformData.h b/WebCore/platform/graphics/win/FontCustomPlatformData.h index d19a8a5..1bdf270 100644 --- a/WebCore/platform/graphics/win/FontCustomPlatformData.h +++ b/WebCore/platform/graphics/win/FontCustomPlatformData.h @@ -21,6 +21,7 @@ #ifndef FontCustomPlatformData_h #define FontCustomPlatformData_h +#include "FontOrientation.h" #include "FontRenderingMode.h" #include "PlatformString.h" #include <wtf/Forward.h> @@ -42,7 +43,7 @@ struct FontCustomPlatformData : Noncopyable { ~FontCustomPlatformData(); - FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontRenderingMode = NormalRenderingMode); + FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, FontRenderingMode = NormalRenderingMode); static bool supportsFormat(const String&); diff --git a/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.cpp b/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.cpp index 02c5b99..c3decbf 100644 --- a/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.cpp +++ b/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.cpp @@ -32,7 +32,7 @@ FontCustomPlatformData::~FontCustomPlatformData() cairo_font_face_destroy(m_fontFace); } -FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic) +FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation) { return FontPlatformData(m_fontFace, size, bold, italic); } diff --git a/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.h b/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.h index 525957f..3ab52b8 100644 --- a/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.h +++ b/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.h @@ -22,6 +22,7 @@ #ifndef FontCustomPlatformDataCairo_h #define FontCustomPlatformDataCairo_h +#include "FontDescription.h" #include <wtf/Forward.h> #include <wtf/Noncopyable.h> @@ -39,7 +40,7 @@ struct FontCustomPlatformData : Noncopyable { } ~FontCustomPlatformData(); - FontPlatformData fontPlatformData(int size, bool bold, bool italic); + FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal); static bool supportsFormat(const String&); diff --git a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp index 1b4f1d9..5544229 100644 --- a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp +++ b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp @@ -36,6 +36,7 @@ #include "KURL.h" #include "MediaPlayerPrivateTaskTimer.h" #include "QTCFDictionary.h" +#include "QTDecompressionSession.h" #include "QTMovie.h" #include "QTMovieTask.h" #include "QTMovieVisualContext.h" @@ -728,12 +729,24 @@ void MediaPlayerPrivateQuickTimeVisualContext::paint(GraphicsContext* p, const I if (currentMode == MediaRenderingSoftwareRenderer && !m_visualContext) return; -#if USE(ACCELERATED_COMPOSITING) - if (m_qtVideoLayer) - return; -#endif QTPixelBuffer buffer = m_visualContext->imageForTime(0); if (buffer.pixelBufferRef()) { +#if USE(ACCELERATED_COMPOSITING) + if (m_qtVideoLayer) { + // We are probably being asked to render the video into a canvas, but + // there's a good chance the QTPixelBuffer is not ARGB and thus can't be + // drawn using CG. If so, fire up an ICMDecompressionSession and convert + // the current frame into something which can be rendered by CG. + if (!buffer.pixelFormatIs32ARGB() && !buffer.pixelFormatIs32BGRA()) { + // The decompression session will only decompress a specific pixelFormat + // at a specific width and height; if these differ, the session must be + // recreated with the new parameters. + if (!m_decompressionSession || !m_decompressionSession->canDecompress(buffer)) + m_decompressionSession = QTDecompressionSession::create(buffer.pixelFormatType(), buffer.width(), buffer.height()); + buffer = m_decompressionSession->decompress(buffer); + } + } +#endif CGImageRef image = CreateCGImageFromPixelBuffer(buffer); CGContextRef context = p->platformContext(); @@ -1089,7 +1102,7 @@ void MediaPlayerPrivateQuickTimeVisualContext::setUpVideoRendering() m_player->mediaPlayerClient()->mediaPlayerRenderingModeChanged(m_player); #endif - QTMovieVisualContext::Type contextType = requiredDllsAvailable() && preferredMode == MediaRenderingMovieLayer ? QTMovieVisualContext::ConfigureForCAImageQueue : QTMovieVisualContext::ConfigureForCGImage; + QTPixelBuffer::Type contextType = requiredDllsAvailable() && preferredMode == MediaRenderingMovieLayer ? QTPixelBuffer::ConfigureForCAImageQueue : QTPixelBuffer::ConfigureForCGImage; m_visualContext = QTMovieVisualContext::create(m_visualContextClient.get(), contextType); m_visualContext->setMovie(m_movie.get()); } diff --git a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h index 4c62558..109fd0b 100644 --- a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h +++ b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h @@ -42,6 +42,7 @@ typedef struct CGImage *CGImageRef; class QTMovie; class QTMovieVisualContext; +class QTDecompressionSession; namespace WebCore { @@ -178,6 +179,7 @@ private: RefPtr<WKCACFLayer> m_qtVideoLayer; OwnPtr<GraphicsLayer> m_transformLayer; OwnPtr<WKCAImageQueue> m_imageQueue; + OwnPtr<QTDecompressionSession> m_decompressionSession; CGAffineTransform m_movieTransform; #endif RefPtr<QTMovieVisualContext> m_visualContext; diff --git a/WebCore/platform/graphics/win/QTDecompressionSession.cpp b/WebCore/platform/graphics/win/QTDecompressionSession.cpp new file mode 100644 index 0000000..eeb3ca7 --- /dev/null +++ b/WebCore/platform/graphics/win/QTDecompressionSession.cpp @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2010 Apple, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "config.h" + +#include "QTDecompressionSession.h" + +#include <ImageCompression.h> +#include <algorithm> + +class QTDecompressionSessionClient { +public: + static void trackingCallback(void *decompressionTrackingRefCon, OSStatus, + ICMDecompressionTrackingFlags decompressionTrackingFlags, CVPixelBufferRef pixelBuffer, + TimeValue64, TimeValue64, ICMValidTimeFlags, void *, void *) + { + QTDecompressionSession* session = static_cast<QTDecompressionSession*>(decompressionTrackingRefCon); + ASSERT(session); + + if (decompressionTrackingFlags & kICMDecompressionTracking_FrameDecoded) + session->m_latestFrame = QTPixelBuffer(pixelBuffer); + } +}; + +PassOwnPtr<QTDecompressionSession> QTDecompressionSession::create(unsigned long pixelFormat, size_t width, size_t height) +{ + return adoptPtr(new QTDecompressionSession(pixelFormat, width, height)); +} + +QTDecompressionSession::QTDecompressionSession(unsigned long pixelFormat, size_t width, size_t height) + : m_session(0) + , m_pixelFormat(pixelFormat) + , m_width(width) + , m_height(height) +{ + initializeSession(); +} + +QTDecompressionSession::~QTDecompressionSession() +{ + if (m_session) + ICMDecompressionSessionRelease(m_session); +} + +void QTDecompressionSession::initializeSession() +{ + if (m_session) + return; + + ICMPixelFormatInfo pixelFormatInfo = {sizeof(ICMPixelFormatInfo), 0}; + if (ICMGetPixelFormatInfo(m_pixelFormat, &pixelFormatInfo) != noErr) { + // The ICM does not know anything about the pixelFormat contained in + // the pixel buffer, so it won't be able to convert it to RGBA. + return; + } + + // The depth and cType fields of the ImageDescriptionHandle are filled + // out according to the instructions in Technical Q&A QA1183: + // http://developer.apple.com/library/mac/#qa/qa2001/qa1183.html + bool isIndexed = pixelFormatInfo.formatFlags & kICMPixelFormatIsIndexed; + bool isQD = pixelFormatInfo.formatFlags & kICMPixelFormatIsSupportedByQD; + bool isMonochrome = pixelFormatInfo.formatFlags & kICMPixelFormatIsMonochrome; + bool hasAlpha = pixelFormatInfo.formatFlags & kICMPixelFormatHasAlphaChannel; + + unsigned int depth = 24; // The default depth is 24. + if (hasAlpha) + depth = 32; // Any pixel format with alpha gets a depth of 32. + else if (isMonochrome) { + // Grayscale pixel formats get depths 33 through 40, depending + // on their bits per pixel. Yes, this means that 16-bit grayscale + // and 8-bit grayscale have the same pixel depth. + depth = 32 + std::min<unsigned int>(8, pixelFormatInfo.bitsPerPixel[0]); + } else if (isIndexed) { + // Indexed pixel formats get a depth of 1 through 8, depending on + // the their bits per pixel. + depth = pixelFormatInfo.bitsPerPixel[0]; + } + + // If QuickDraw supports the given pixel format, the cType should be kRawCodecType. + // Otherwise, use the pixel format code for the cType. We are assuming the pixel + // buffer is uncompressed. + unsigned long cType = isQD ? kRawCodecType : m_pixelFormat; + + ImageDescriptionHandle description = (ImageDescriptionHandle)NewHandleClear(sizeof(ImageDescription)); + (**description).idSize = sizeof(ImageDescription); + (**description).cType = cType; + (**description).version = 2; + (**description).spatialQuality = codecLosslessQuality; + (**description).width = m_width; + (**description).height = m_height; + (**description).hRes = 72 << 16; // 72 DPI as a fixed-point number + (**description).vRes = 72 << 16; // 72 DPI as a fixed-point number + (**description).frameCount = 1; + (**description).depth = depth; + (**description).clutID = -1; + + // Create the mandatory ICMDecompressionSessionOptions, but leave + // all the default values. + ICMDecompressionSessionOptionsRef options = 0; + ICMDecompressionSessionOptionsCreate(kCFAllocatorDefault, &options); + + CFDictionaryRef pixelBufferAttributes = QTPixelBuffer::createPixelBufferAttributesDictionary(QTPixelBuffer::ConfigureForCGImage); + + ICMDecompressionTrackingCallbackRecord callback = { + QTDecompressionSessionClient::trackingCallback, + this, + }; + + ICMDecompressionSessionCreate(kCFAllocatorDefault, + description, + options, + pixelBufferAttributes, + &callback, + &m_session); + + if (pixelBufferAttributes) + CFRelease(pixelBufferAttributes); + + ICMDecompressionSessionOptionsRelease(options); + DisposeHandle((Handle)description); +} + +bool QTDecompressionSession::canDecompress(QTPixelBuffer inBuffer) +{ + return m_session + && inBuffer.pixelFormatType() == m_pixelFormat + && inBuffer.width() == m_width + && inBuffer.height() == m_height; +} + +QTPixelBuffer QTDecompressionSession::decompress(QTPixelBuffer inBuffer) +{ + if (!canDecompress(inBuffer)) + return QTPixelBuffer(); + + inBuffer.lockBaseAddress(); + ICMDecompressionSessionDecodeFrame(m_session, + static_cast<UInt8*>(inBuffer.baseAddress()), + inBuffer.dataSize(), + 0, // frameOptions + 0, // frameTime + 0); // sourceFrameRefCon + + // Because we passed in 0 for frameTime, the above function + // is synchronous, and the client callback will have been + // called before the function returns, and m_latestFrame + // will contain the newly decompressed frame. + return m_latestFrame; +} diff --git a/WebCore/platform/graphics/win/QTDecompressionSession.h b/WebCore/platform/graphics/win/QTDecompressionSession.h new file mode 100644 index 0000000..67b6635 --- /dev/null +++ b/WebCore/platform/graphics/win/QTDecompressionSession.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2010 Apple, 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. + */ + +#ifndef QTDecompressionSession_h +#define QTDecompressionSession_h + +#ifdef QTMOVIEWIN_EXPORTS +#define QTMOVIEWIN_API __declspec(dllexport) +#else +#define QTMOVIEWIN_API __declspec(dllimport) +#endif + +#include "QTPixelBuffer.h" + +#include <WTF/PassOwnPtr.h> + +class QTDecompressionSessionClient; +typedef struct OpaqueICMDecompressionSession* ICMDecompressionSessionRef; + +class QTMOVIEWIN_API QTDecompressionSession { +public: + static PassOwnPtr<QTDecompressionSession> create(unsigned long pixelFormat, size_t width, size_t height); + ~QTDecompressionSession(); + + bool canDecompress(QTPixelBuffer); + + // The resulting QTPixelBuffer will be a CG compatable ARGB pixel buffer. + QTPixelBuffer decompress(QTPixelBuffer); + +private: + friend class QTDecompressionSessionClient; + QTDecompressionSession(unsigned long pixelFormat, size_t width, size_t height); + void initializeSession(); + + unsigned long m_pixelFormat; + size_t m_width; + size_t m_height; + QTPixelBuffer m_latestFrame; + ICMDecompressionSessionRef m_session; +}; + +#endif diff --git a/WebCore/platform/graphics/win/QTMovieVisualContext.cpp b/WebCore/platform/graphics/win/QTMovieVisualContext.cpp index 0232d3b..0fcc7e2 100644 --- a/WebCore/platform/graphics/win/QTMovieVisualContext.cpp +++ b/WebCore/platform/graphics/win/QTMovieVisualContext.cpp @@ -39,7 +39,7 @@ struct QTCVTimeStamp { class QTMovieVisualContextPriv { public: - QTMovieVisualContextPriv(QTMovieVisualContext* parent, QTMovieVisualContextClient* client, QTMovieVisualContext::Type contextType); + QTMovieVisualContextPriv(QTMovieVisualContext* parent, QTMovieVisualContextClient* client, QTPixelBuffer::Type contextType); ~QTMovieVisualContextPriv(); bool isImageAvailableForTime(const QTCVTimeStamp*) const; @@ -61,61 +61,28 @@ private: }; -static OSStatus SetNumberValue(CFMutableDictionaryRef inDict, CFStringRef inKey, SInt32 inValue) +static CFDictionaryRef createPixelBufferOptionsDictionary(QTPixelBuffer::Type contextType) { - CFNumberRef number; - - number = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &inValue); - if (!number) - return coreFoundationUnknownErr; - - CFDictionarySetValue(inDict, inKey, number); - CFRelease(number); - - return noErr; -} - -static CFDictionaryRef createPixelBufferOptionsDictionary(QTMovieVisualContext::Type contextType) -{ - static const CFStringRef kDirect3DCompatibilityKey = CFSTR("Direct3DCompatibility"); - - CFMutableDictionaryRef pixelBufferOptions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - - CFMutableDictionaryRef pixelBufferAttributes = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - if (contextType == QTMovieVisualContext::ConfigureForCAImageQueue) { - // Ask for D3D compatible pixel buffers so no further work is needed. - CFDictionarySetValue(pixelBufferAttributes, kDirect3DCompatibilityKey, kCFBooleanTrue); - } else { - // Use the k32BGRAPixelFormat, as QuartzCore will be able to use the pixels directly, - // without needing an additional copy or rendering pass. - SetNumberValue(pixelBufferAttributes, kCVPixelBufferPixelFormatTypeKey, k32BGRAPixelFormat); - - // Set kCVPixelBufferBytesPerRowAlignmentKey to 16 to ensure that each row of pixels - // starts at a 16 byte aligned address for most efficient data reading. - SetNumberValue(pixelBufferAttributes, kCVPixelBufferBytesPerRowAlignmentKey, 16); - CFDictionarySetValue(pixelBufferAttributes, kCVPixelBufferCGImageCompatibilityKey, kCFBooleanTrue); - } - - CFDictionarySetValue(pixelBufferOptions, kQTVisualContextPixelBufferAttributesKey, pixelBufferAttributes); - - CFRelease(pixelBufferAttributes); - + const void* key = kQTVisualContextPixelBufferAttributesKey; + const void* value = QTPixelBuffer::createPixelBufferAttributesDictionary(contextType); + CFDictionaryRef pixelBufferOptions = CFDictionaryCreate(kCFAllocatorDefault, &key, &value, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFRelease(value); return pixelBufferOptions; } -static CFDictionaryRef pixelBufferCreationOptions(QTMovieVisualContext::Type contextType) +static CFDictionaryRef pixelBufferCreationOptions(QTPixelBuffer::Type contextType) { - if (contextType == QTMovieVisualContext::ConfigureForCAImageQueue) { + if (contextType == QTPixelBuffer::ConfigureForCAImageQueue) { static CFDictionaryRef imageQueueOptions = createPixelBufferOptionsDictionary(contextType); return imageQueueOptions; } - ASSERT(contextType == QTMovieVisualContext::ConfigureForCGImage); + ASSERT(contextType == QTPixelBuffer::ConfigureForCGImage); static CFDictionaryRef cgImageOptions = createPixelBufferOptionsDictionary(contextType); return cgImageOptions; } -QTMovieVisualContextPriv::QTMovieVisualContextPriv(QTMovieVisualContext* parent, QTMovieVisualContextClient* client, QTMovieVisualContext::Type contextType) +QTMovieVisualContextPriv::QTMovieVisualContextPriv(QTMovieVisualContext* parent, QTMovieVisualContextClient* client, QTPixelBuffer::Type contextType) : m_parent(parent) , m_client(client) , m_visualContext(0) @@ -206,12 +173,12 @@ void QTMovieVisualContextPriv::imageAvailableCallback(QTVisualContextRef visualC vc->m_client->imageAvailableForTime(reinterpret_cast<const QTCVTimeStamp*>(timeStamp)); } -PassRefPtr<QTMovieVisualContext> QTMovieVisualContext::create(QTMovieVisualContextClient* client, Type contextType) +PassRefPtr<QTMovieVisualContext> QTMovieVisualContext::create(QTMovieVisualContextClient* client, QTPixelBuffer::Type contextType) { return adoptRef(new QTMovieVisualContext(client, contextType)); } -QTMovieVisualContext::QTMovieVisualContext(QTMovieVisualContextClient* client, Type contextType) +QTMovieVisualContext::QTMovieVisualContext(QTMovieVisualContextClient* client, QTPixelBuffer::Type contextType) : m_private(new QTMovieVisualContextPriv(this, client, contextType)) { } diff --git a/WebCore/platform/graphics/win/QTMovieVisualContext.h b/WebCore/platform/graphics/win/QTMovieVisualContext.h index 057031e..8410208 100644 --- a/WebCore/platform/graphics/win/QTMovieVisualContext.h +++ b/WebCore/platform/graphics/win/QTMovieVisualContext.h @@ -54,9 +54,7 @@ public: class QTMOVIEWIN_API QTMovieVisualContext : public RefCounted<QTMovieVisualContext> { public: - enum Type { ConfigureForCGImage, ConfigureForCAImageQueue }; - - static PassRefPtr<QTMovieVisualContext> create(QTMovieVisualContextClient*, Type); + static PassRefPtr<QTMovieVisualContext> create(QTMovieVisualContextClient*, QTPixelBuffer::Type); ~QTMovieVisualContext(); bool isImageAvailableForTime(const QTCVTimeStamp*) const; @@ -71,7 +69,7 @@ public: static double currentHostTime(); protected: - QTMovieVisualContext(QTMovieVisualContextClient*, Type); + QTMovieVisualContext(QTMovieVisualContextClient*, QTPixelBuffer::Type); void setupVisualContext(); friend class QTMovieVisualContextPriv; diff --git a/WebCore/platform/graphics/win/QTPixelBuffer.cpp b/WebCore/platform/graphics/win/QTPixelBuffer.cpp index 657b68e..44a1b0e 100644 --- a/WebCore/platform/graphics/win/QTPixelBuffer.cpp +++ b/WebCore/platform/graphics/win/QTPixelBuffer.cpp @@ -26,6 +26,7 @@ #include "QTPixelBuffer.h" +#include <CFNumber.h> #include <CFString.h> #include <CGColorSpace.h> #include <CGImage.h> @@ -33,6 +34,41 @@ #include <QuickDraw.h> #include <memory.h> +static OSStatus SetNumberValue(CFMutableDictionaryRef inDict, CFStringRef inKey, SInt32 inValue) +{ + CFNumberRef number; + + number = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &inValue); + if (!number) + return coreFoundationUnknownErr; + + CFDictionarySetValue(inDict, inKey, number); + CFRelease(number); + + return noErr; +} + +CFDictionaryRef QTPixelBuffer::createPixelBufferAttributesDictionary(QTPixelBuffer::Type contextType) +{ + static const CFStringRef kDirect3DCompatibilityKey = CFSTR("Direct3DCompatibility"); + + CFMutableDictionaryRef pixelBufferAttributes = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + if (contextType == QTPixelBuffer::ConfigureForCAImageQueue) { + // Ask for D3D compatible pixel buffers so no further work is needed. + CFDictionarySetValue(pixelBufferAttributes, kDirect3DCompatibilityKey, kCFBooleanTrue); + } else { + // Use the k32BGRAPixelFormat, as QuartzCore will be able to use the pixels directly, + // without needing an additional copy or rendering pass. + SetNumberValue(pixelBufferAttributes, kCVPixelBufferPixelFormatTypeKey, k32BGRAPixelFormat); + + // Set kCVPixelBufferBytesPerRowAlignmentKey to 16 to ensure that each row of pixels + // starts at a 16 byte aligned address for most efficient data reading. + SetNumberValue(pixelBufferAttributes, kCVPixelBufferBytesPerRowAlignmentKey, 16); + CFDictionarySetValue(pixelBufferAttributes, kCVPixelBufferCGImageCompatibilityKey, kCFBooleanTrue); + } + return pixelBufferAttributes; +} + QTPixelBuffer::QTPixelBuffer() : m_pixelBuffer(0) { diff --git a/WebCore/platform/graphics/win/QTPixelBuffer.h b/WebCore/platform/graphics/win/QTPixelBuffer.h index 22f8ba4..13630da 100644 --- a/WebCore/platform/graphics/win/QTPixelBuffer.h +++ b/WebCore/platform/graphics/win/QTPixelBuffer.h @@ -44,6 +44,9 @@ typedef const struct __CFDictionary * CFDictionaryRef; // safe to call within WebKit. class QTMOVIEWIN_API QTPixelBuffer { public: + enum Type { ConfigureForCGImage, ConfigureForCAImageQueue }; + static CFDictionaryRef createPixelBufferAttributesDictionary(Type); + QTPixelBuffer(); QTPixelBuffer(const QTPixelBuffer&); QTPixelBuffer(CVPixelBufferRef); diff --git a/WebCore/platform/graphics/wince/FontCustomPlatformData.cpp b/WebCore/platform/graphics/wince/FontCustomPlatformData.cpp index 3605c72..f61ae8e 100644 --- a/WebCore/platform/graphics/wince/FontCustomPlatformData.cpp +++ b/WebCore/platform/graphics/wince/FontCustomPlatformData.cpp @@ -45,7 +45,7 @@ FontCustomPlatformData::~FontCustomPlatformData() g_customFontCache->unregisterFont(m_name); } -FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontRenderingMode renderingMode) +FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, FontRenderingMode renderingMode) { FontDescription fontDesc; fontDesc.setComputedSize(size); diff --git a/WebCore/platform/graphics/wince/FontCustomPlatformData.h b/WebCore/platform/graphics/wince/FontCustomPlatformData.h index 5ce0ea6..abdc0f2 100644 --- a/WebCore/platform/graphics/wince/FontCustomPlatformData.h +++ b/WebCore/platform/graphics/wince/FontCustomPlatformData.h @@ -21,6 +21,7 @@ #ifndef FontCustomPlatformData_h #define FontCustomPlatformData_h +#include "FontDescription.h" #include "FontRenderingMode.h" #include "PlatformString.h" #include <wtf/Noncopyable.h> @@ -44,7 +45,7 @@ namespace WebCore { ~FontCustomPlatformData(); - FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontRenderingMode = NormalRenderingMode); + FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation fontOrientation = Horizontal, FontRenderingMode = NormalRenderingMode); static bool supportsFormat(const String&); diff --git a/WebCore/platform/graphics/wince/FontPlatformData.cpp b/WebCore/platform/graphics/wince/FontPlatformData.cpp index d84a7cc..d9d8a72 100644 --- a/WebCore/platform/graphics/wince/FontPlatformData.cpp +++ b/WebCore/platform/graphics/wince/FontPlatformData.cpp @@ -148,7 +148,7 @@ struct FixedSizeFontDataKeyHash { font.m_weight, // static_cast<unsigned>(font.m_italic); }; - return StringImpl::computeHash(reinterpret_cast<UChar*>(hashCodes), sizeof(hashCodes) / sizeof(UChar)); + return WTF::StringHasher::createBlobHash<sizeof(hashCodes)>(hashCodes); } static bool equal(const FixedSizeFontDataKey& a, const FixedSizeFontDataKey& b) diff --git a/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp b/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp index a0c10fc..a11b8d8 100644 --- a/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp +++ b/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp @@ -283,7 +283,7 @@ public: return 0; } - RefPtr<SharedBitmap> bmp = SharedBitmap::createInstance(alphaPaint == AlphaPaintNone, origRect.width(), origRect.height(), false); + RefPtr<SharedBitmap> bmp = SharedBitmap::create(origRect.size(), alphaPaint == AlphaPaintNone ? BitmapInfo::BitCount16 : BitmapInfo::BitCount32, false); SetRect(&bmpRect, 0, 0, origRect.width(), origRect.height()); if (bmp) { switch (alphaPaint) { @@ -523,7 +523,7 @@ TransparentLayerDC::TransparentLayerDC(GraphicsContextPlatformPrivate* data, Int origRect.inflateX(stableRound((width - origRect.width()) * 0.5)); origRect.inflateY(stableRound((height - origRect.height()) * 0.5)); - m_bitmap = SharedBitmap::createInstance(m_rotatedBitmap->is16bit(), m_origRect.width(), m_origRect.height(), true); + m_bitmap = SharedBitmap::create(m_origRect.size(), m_rotatedBitmap->is16bit() ? BitmapInfo::BitCount16 : BitmapInfo::BitCount32, true); if (m_bitmap) rotateBitmap(m_bitmap.get(), m_rotatedBitmap.get(), -m_rotation); else @@ -608,15 +608,13 @@ void GraphicsContext::setBitmap(PassRefPtr<SharedBitmap> bmp) HDC GraphicsContext::getWindowsContext(const IntRect& dstRect, bool supportAlphaBlend, bool mayCreateBitmap) { - notImplemented(); - ASSERT_NOT_REACHED(); - return 0; + // FIXME: Add support for AlphaBlend. + ASSERT(!supportAlphaBlend); + return m_data->m_dc; } void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect& dstRect, bool supportAlphaBlend, bool mayCreateBitmap) { - notImplemented(); - ASSERT_NOT_REACHED(); } void GraphicsContext::savePlatformState() @@ -1779,7 +1777,7 @@ void GraphicsContext::drawFrameControl(const IntRect& rect, unsigned type, unsig RECT rectWin = trRect; if ((rectWin.right - rectWin.left) < boxWidthBest) { - RefPtr<SharedBitmap> bmp = SharedBitmap::createInstance(true, boxWidthBest, boxHeightBest, true); + RefPtr<SharedBitmap> bmp = SharedBitmap::create(IntSize(boxWidthBest, boxHeightBest), BitmapInfo::BitCount16, true); SharedBitmap::DCHolder memDC(bmp.get()); if (memDC.get()) { RECT tempRect = {0, 0, boxWidthBest, boxHeightBest}; diff --git a/WebCore/platform/graphics/wince/ImageBufferWinCE.cpp b/WebCore/platform/graphics/wince/ImageBufferWinCE.cpp index 15720f3..ec8517b 100644 --- a/WebCore/platform/graphics/wince/ImageBufferWinCE.cpp +++ b/WebCore/platform/graphics/wince/ImageBufferWinCE.cpp @@ -64,7 +64,7 @@ void BufferedImage::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect } ImageBufferData::ImageBufferData(const IntSize& size) -: m_bitmap(SharedBitmap::createInstance(false, size.width(), size.height(), false)) + : m_bitmap(SharedBitmap::create(size, BitmapInfo::BitCount32, false)) { // http://www.w3.org/TR/2009/WD-html5-20090212/the-canvas-element.html#canvaspixelarray // "When the canvas is initialized it must be set to fully transparent black." @@ -72,7 +72,7 @@ ImageBufferData::ImageBufferData(const IntSize& size) m_bitmap->setHasAlpha(true); } -ImageBuffer::ImageBuffer(const IntSize& size, ImageColorSpace colorSpace, bool& success) +ImageBuffer::ImageBuffer(const IntSize& size, ColorSpace colorSpace, bool& success) : m_data(size) , m_size(size) { diff --git a/WebCore/platform/graphics/wince/ImageWinCE.cpp b/WebCore/platform/graphics/wince/ImageWinCE.cpp index 53b9b68..ec7403e 100644 --- a/WebCore/platform/graphics/wince/ImageWinCE.cpp +++ b/WebCore/platform/graphics/wince/ImageWinCE.cpp @@ -43,11 +43,7 @@ namespace WebCore { NativeImagePtr RGBA32Buffer::asNewNativeImage() const { - NativeImagePtr image = SharedBitmap::createInstance(false, width(), height(), false); - - memcpy(image->bytes(), m_bytes.data(), m_bytes.size() * sizeof(PixelData)); - - return image; + return SharedBitmap::create(m_bytes, m_size, hasAlpha()); } bool FrameData::clear(bool clearMetaData) diff --git a/WebCore/platform/graphics/wx/FontCustomPlatformData.cpp b/WebCore/platform/graphics/wx/FontCustomPlatformData.cpp index 4cebe43..6133372 100644 --- a/WebCore/platform/graphics/wx/FontCustomPlatformData.cpp +++ b/WebCore/platform/graphics/wx/FontCustomPlatformData.cpp @@ -31,7 +31,7 @@ FontCustomPlatformData::~FontCustomPlatformData() { } -FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontRenderingMode) +FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, FontRenderingMode) { return FontPlatformData(size, bold, italic); } diff --git a/WebCore/platform/graphics/wx/FontCustomPlatformData.h b/WebCore/platform/graphics/wx/FontCustomPlatformData.h index a7dfe37..cc348e3 100644 --- a/WebCore/platform/graphics/wx/FontCustomPlatformData.h +++ b/WebCore/platform/graphics/wx/FontCustomPlatformData.h @@ -21,6 +21,7 @@ #ifndef FontCustomPlatformData_h #define FontCustomPlatformData_h +#include "FontOrientation.h" #include "FontRenderingMode.h" #include <wtf/Forward.h> #include <wtf/Noncopyable.h> @@ -37,7 +38,7 @@ namespace WebCore { static bool supportsFormat(const String&); - FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontRenderingMode = NormalRenderingMode); + FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, FontRenderingMode = NormalRenderingMode); }; FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer*); diff --git a/WebCore/platform/graphics/wx/FontPlatformDataWx.cpp b/WebCore/platform/graphics/wx/FontPlatformDataWx.cpp index b77a03b..66c69ee 100644 --- a/WebCore/platform/graphics/wx/FontPlatformDataWx.cpp +++ b/WebCore/platform/graphics/wx/FontPlatformDataWx.cpp @@ -111,20 +111,25 @@ FontPlatformData::FontPlatformData(const FontDescription& desc, const AtomicStri m_size = desc.computedPixelSize(); m_fontState = VALID; m_size = desc.computedPixelSize(); - } -unsigned FontPlatformData::computeHash() const { - wxFont* thisFont = m_font->font(); - ASSERT(thisFont && thisFont->IsOk()); - - // make a hash that is unique for this font, but not globally unique - that is, - // a font whose properties are equal should generate the same hash - uintptr_t hashCodes[6] = { thisFont->GetPointSize(), thisFont->GetFamily(), thisFont->GetStyle(), - thisFont->GetWeight(), thisFont->GetUnderlined(), - StringImpl::computeHash(thisFont->GetFaceName().utf8_str()) }; - - return StringImpl::computeHash(reinterpret_cast<UChar*>(hashCodes), sizeof(hashCodes) / sizeof(UChar)); +unsigned FontPlatformData::computeHash() const +{ + wxFont* thisFont = m_font->font(); + ASSERT(thisFont && thisFont->IsOk()); + + // make a hash that is unique for this font, but not globally unique - that is, + // a font whose properties are equal should generate the same hash + uintptr_t hashCodes[6] = { + thisFont->GetPointSize(), + thisFont->GetFamily(), + thisFont->GetStyle(), + thisFont->GetWeight(), + thisFont->GetUnderlined(), + StringImpl::computeHash(thisFont->GetFaceName().utf8_str()) + }; + + return WTF::StringHasher::createBlobHash<sizeof(hashCodes)>(hashCodes); } FontPlatformData::~FontPlatformData() |