diff options
author | Steve Block <steveblock@google.com> | 2011-05-18 13:36:51 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2011-05-24 15:38:28 +0100 |
commit | 2fc2651226baac27029e38c9d6ef883fa32084db (patch) | |
tree | e396d4bf89dcce6ed02071be66212495b1df1dec /Source/WebCore/platform/graphics/chromium | |
parent | b3725cedeb43722b3b175aaeff70552e562d2c94 (diff) | |
download | external_webkit-2fc2651226baac27029e38c9d6ef883fa32084db.zip external_webkit-2fc2651226baac27029e38c9d6ef883fa32084db.tar.gz external_webkit-2fc2651226baac27029e38c9d6ef883fa32084db.tar.bz2 |
Merge WebKit at r78450: Initial merge by git.
Change-Id: I6d3e5f1f868ec266a0aafdef66182ddc3f265dc1
Diffstat (limited to 'Source/WebCore/platform/graphics/chromium')
32 files changed, 498 insertions, 264 deletions
diff --git a/Source/WebCore/platform/graphics/chromium/ComplexTextControllerLinux.cpp b/Source/WebCore/platform/graphics/chromium/ComplexTextControllerLinux.cpp index 92861fc..4598602 100644 --- a/Source/WebCore/platform/graphics/chromium/ComplexTextControllerLinux.cpp +++ b/Source/WebCore/platform/graphics/chromium/ComplexTextControllerLinux.cpp @@ -146,7 +146,10 @@ void ComplexTextController::reset(unsigned offset) // TextRun has been reached. bool ComplexTextController::nextScriptRun() { - if (!hb_utf16_script_run_next(&m_numCodePoints, &m_item.item, m_run.characters(), m_run.length(), &m_indexOfNextScriptRun)) + // Ensure we're not pointing at the small caps buffer. + m_item.string = m_run.characters(); + + if (!hb_utf16_script_run_next(0, &m_item.item, m_run.characters(), m_run.length(), &m_indexOfNextScriptRun)) return false; // It is actually wrong to consider script runs at all in this code. @@ -184,11 +187,33 @@ float ComplexTextController::widthOfFullRun() void ComplexTextController::setupFontForScriptRun() { - const FontData* fontData = m_font->glyphDataForCharacter(m_item.string[m_item.item.pos], false).fontData; + FontDataVariant fontDataVariant = AutoVariant; + // Determine if this script run needs to be converted to small caps. + // nextScriptRun() will always send us a run of the same case, because a + // case change while in small-caps mode always results in different + // FontData, so we only need to check the first character's case. + if (m_font->isSmallCaps() && u_islower(m_item.string[m_item.item.pos])) { + m_smallCapsString = String(m_run.data(m_item.item.pos), m_item.item.length); + m_smallCapsString.makeUpper(); + m_item.string = m_smallCapsString.characters(); + m_item.item.pos = 0; + fontDataVariant = SmallCapsVariant; + } + const FontData* fontData = m_font->glyphDataForCharacter(m_item.string[m_item.item.pos], false, fontDataVariant).fontData; const FontPlatformData& platformData = fontData->fontDataForCharacter(' ')->platformData(); m_item.face = platformData.harfbuzzFace(); void* opaquePlatformData = const_cast<FontPlatformData*>(&platformData); m_item.font->userData = opaquePlatformData; + + int size = platformData.size(); + m_item.font->x_ppem = size; + m_item.font->y_ppem = size; + // x_ and y_scale are the conversion factors from font design space (fEmSize) to 1/64th of device pixels in 16.16 format. + const int devicePixelFraction = 64; + const int multiplyFor16Dot16 = 1 << 16; + int scale = devicePixelFraction * size * multiplyFor16Dot16 / platformData.emSizeInFontUnits(); + m_item.font->x_scale = scale; + m_item.font->y_scale = scale; } HB_FontRec* ComplexTextController::allocHarfbuzzFont() @@ -197,13 +222,6 @@ HB_FontRec* ComplexTextController::allocHarfbuzzFont() memset(font, 0, sizeof(HB_FontRec)); font->klass = &harfbuzzSkiaClass; font->userData = 0; - // The values which harfbuzzSkiaClass returns are already scaled to - // pixel units, so we just set all these to one to disable further - // scaling. - font->x_ppem = 1; - font->y_ppem = 1; - font->x_scale = 1; - font->y_scale = 1; return font; } @@ -369,7 +387,7 @@ const TextRun& ComplexTextController::getNormalizedTextRun(const TextRun& origin sourceText = normalizedString.getBuffer(); } - normalizedBuffer.set(new UChar[normalizedBufferLength + 1]); + normalizedBuffer = adoptArrayPtr(new UChar[normalizedBufferLength + 1]); normalizeSpacesAndMirrorChars(sourceText, originalRun.rtl(), normalizedBuffer.get(), normalizedBufferLength); diff --git a/Source/WebCore/platform/graphics/chromium/ComplexTextControllerLinux.h b/Source/WebCore/platform/graphics/chromium/ComplexTextControllerLinux.h index a2aea60..6a93878 100644 --- a/Source/WebCore/platform/graphics/chromium/ComplexTextControllerLinux.h +++ b/Source/WebCore/platform/graphics/chromium/ComplexTextControllerLinux.h @@ -111,7 +111,7 @@ public: const unsigned short* logClusters() const { return m_item.log_clusters; } // return the number of code points in the current script run - const unsigned numCodePoints() const { return m_numCodePoints; } + const unsigned numCodePoints() const { return m_item.item.length; } // Return the current pixel position of the controller. const unsigned offsetX() const { return m_offsetX; } @@ -141,7 +141,6 @@ private: ssize_t m_indexOfNextScriptRun; // Indexes the script run in |m_run|. unsigned m_offsetX; // Offset in pixels to the start of the next script run. unsigned m_pixelWidth; // Width (in px) of the current script run. - unsigned m_numCodePoints; // Code points in current script run. unsigned m_glyphsArrayCapacity; // Current size of all the Harfbuzz arrays. OwnPtr<TextRun> m_normalizedRun; @@ -155,6 +154,7 @@ private: // each word break we accumulate error. This is the // number of pixels that we are behind so far. int m_letterSpacing; // pixels to be added after each glyph. + String m_smallCapsString; // substring of m_run converted to small caps. }; } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp index d00faf8..a38f6bd 100644 --- a/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp @@ -343,7 +343,7 @@ void ContentLayerChromium::draw() ASSERT(sv && sv->initialized()); GraphicsContext3D* context = layerRendererContext(); GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0)); - m_contentsTexture->bindTexture(); + bindContentsTexture(); layerRenderer()->useShader(sv->contentShaderProgram()); GLC(context, context->uniform1i(sv->shaderSamplerLocation(), 0)); @@ -361,8 +361,21 @@ void ContentLayerChromium::draw() drawOpacity(), sv->shaderMatrixLocation(), sv->shaderAlphaLocation()); } - m_contentsTexture->unreserve(); + unreserveContentsTexture(); +} + +void ContentLayerChromium::unreserveContentsTexture() +{ + if (m_contentsTexture) + m_contentsTexture->unreserve(); } +void ContentLayerChromium::bindContentsTexture() +{ + if (m_contentsTexture) + m_contentsTexture->bindTexture(); +} + + } #endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h b/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h index dc1630b..3363518 100644 --- a/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h +++ b/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h @@ -50,6 +50,9 @@ public: virtual ~ContentLayerChromium(); virtual void updateContentsIfDirty(); + virtual void unreserveContentsTexture(); + virtual void bindContentsTexture(); + virtual void draw(); virtual bool drawsContent() { return m_owner && m_owner->drawsContent(); } diff --git a/Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp b/Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp index 2d4ca41..d956841 100644 --- a/Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp @@ -36,12 +36,20 @@ #include "GraphicsContext3D.h" #include "SharedGraphicsContext3D.h" +#if ENABLE(SKIA_GPU) +#include "GrContext.h" +#endif + #if USE(ACCELERATED_COMPOSITING) #include "Canvas2DLayerChromium.h" #endif namespace WebCore { +#if ENABLE(SKIA_GPU) +extern GrContext* GetGlobalGrContext(); +#endif + struct DrawingBufferInternal { unsigned offscreenColorTexture; #if USE(ACCELERATED_COMPOSITING) @@ -72,7 +80,7 @@ DrawingBuffer::DrawingBuffer(GraphicsContext3D* context, bool multisampleExtensionSupported, bool packedDepthStencilExtensionSupported) : m_context(context) - , m_size(-1, -1) + , m_size(size) , m_multisampleExtensionSupported(multisampleExtensionSupported) , m_packedDepthStencilExtensionSupported(packedDepthStencilExtensionSupported) , m_fbo(0) @@ -119,6 +127,8 @@ void DrawingBuffer::publishToPlatformLayer() if (m_callback) m_callback->willPublish(); + if (multisample()) + commit(); unsigned parentTexture = m_internal->platformLayer->textureId(); // FIXME: We do the copy in the canvas' (child) context so that it executes in the correct order relative to // other commands in the child context. This ensures that the parent texture always contains a complete @@ -126,6 +136,9 @@ void DrawingBuffer::publishToPlatformLayer() // happens before the compositor draws. This means we might draw stale frames sometimes. Ideally this // would insert a fence into the child command stream that the compositor could wait for. m_context->makeContextCurrent(); +#if ENABLE(SKIA_GPU) + GetGlobalGrContext()->flush(false); +#endif static_cast<Extensions3DChromium*>(m_context->getExtensions())->copyTextureToParentTextureCHROMIUM(m_colorBuffer, parentTexture); m_context->flush(); } diff --git a/Source/WebCore/platform/graphics/chromium/Extensions3DChromium.h b/Source/WebCore/platform/graphics/chromium/Extensions3DChromium.h index d120424..92fb7b3 100644 --- a/Source/WebCore/platform/graphics/chromium/Extensions3DChromium.h +++ b/Source/WebCore/platform/graphics/chromium/Extensions3DChromium.h @@ -44,8 +44,8 @@ public: virtual bool supports(const String&); virtual void ensureEnabled(const String&); virtual int getGraphicsResetStatusARB(); - virtual void blitFramebuffer(long srcX0, long srcY0, long srcX1, long srcY1, long dstX0, long dstY0, long dstX1, long dstY1, unsigned long mask, unsigned long filter) { } - virtual void renderbufferStorageMultisample(unsigned long target, unsigned long samples, unsigned long internalformat, unsigned long width, unsigned long height) { } + virtual void blitFramebuffer(long srcX0, long srcY0, long srcX1, long srcY1, long dstX0, long dstY0, long dstX1, long dstY1, unsigned long mask, unsigned long filter); + virtual void renderbufferStorageMultisample(unsigned long target, unsigned long samples, unsigned long internalformat, unsigned long width, unsigned long height); enum { // GL_CHROMIUM_map_sub (enums inherited from GL_ARB_vertex_buffer_object) diff --git a/Source/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp b/Source/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp index f4c0dee..33ebc59 100644 --- a/Source/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp +++ b/Source/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp @@ -399,6 +399,28 @@ static int CALLBACK traitsInFamilyEnumProc(CONST LOGFONT* logFont, CONST TEXTMET return 1; } +struct GetLastResortFallbackFontProcData { + GetLastResortFallbackFontProcData(FontCache* fontCache, const FontDescription* fontDescription, wchar_t* fontName) + : m_fontCache(fontCache) + , m_fontDescription(fontDescription) + , m_fontName(fontName) + , m_fontData(0) + { + } + + FontCache* m_fontCache; + const FontDescription* m_fontDescription; + wchar_t* m_fontName; + SimpleFontData* m_fontData; +}; + +static int CALLBACK getLastResortFallbackFontProc(const LOGFONT* logFont, const TEXTMETRIC* metrics, DWORD fontType, LPARAM lParam) +{ + GetLastResortFallbackFontProcData* procData = reinterpret_cast<GetLastResortFallbackFontProcData*>(lParam); + procData->m_fontData = fontDataFromDescriptionAndLogFont(procData->m_fontCache, *procData->m_fontDescription, *logFont, procData->m_fontName); + return !procData->m_fontData; +} + void FontCache::platformInit() { // Not needed on Windows. @@ -548,6 +570,21 @@ SimpleFontData* FontCache::getLastResortFallbackFont(const FontDescription& desc return simpleFont; } + // Fall back to all the fonts installed in this PC. When a font has a + // localized name according to the system locale as well as an English name, + // both GetTextFace() and EnumFontFamilies() return the localized name. So, + // FontCache::createFontPlatformData() does not filter out the fonts + // returned by this EnumFontFamilies() call. + HDC dc = GetDC(0); + if (dc) { + GetLastResortFallbackFontProcData procData(this, &description, fallbackFontName); + EnumFontFamilies(dc, 0, getLastResortFallbackFontProc, reinterpret_cast<LPARAM>(&procData)); + ReleaseDC(0, dc); + + if (procData.m_fontData) + return procData.m_fontData; + } + ASSERT_NOT_REACHED(); return 0; } diff --git a/Source/WebCore/platform/graphics/chromium/FontChromiumWin.cpp b/Source/WebCore/platform/graphics/chromium/FontChromiumWin.cpp index 5da4d5a..e57a84c 100644 --- a/Source/WebCore/platform/graphics/chromium/FontChromiumWin.cpp +++ b/Source/WebCore/platform/graphics/chromium/FontChromiumWin.cpp @@ -246,10 +246,11 @@ IntRect TransparencyAwareGlyphPainter::estimateTextBounds() for (int i = 0; i < m_numGlyphs; i++) totalWidth += lroundf(m_glyphBuffer.advanceAt(m_from + i)); - return IntRect(m_point.x() - (m_font->ascent() + m_font->descent()) / 2, - m_point.y() - m_font->ascent() - m_font->lineGap(), - totalWidth + m_font->ascent() + m_font->descent(), - m_font->lineSpacing()); + const FontMetrics& fontMetrics = m_font->fontMetrics(); + return IntRect(m_point.x() - (fontMetrics.ascent() + fontMetrics.descent()) / 2, + m_point.y() - fontMetrics.ascent() - fontMetrics.lineGap(), + totalWidth + fontMetrics.ascent() + fontMetrics.descent(), + fontMetrics.lineSpacing()); } bool TransparencyAwareGlyphPainter::drawGlyphs(int numGlyphs, @@ -270,7 +271,7 @@ bool TransparencyAwareGlyphPainter::drawGlyphs(int numGlyphs, // Windows' origin is the top-left of the bounding box, so we have // to subtract off the font ascent to get it. int x = lroundf(m_point.x() + startAdvance); - int y = lroundf(m_point.y() - m_font->ascent()); + int y = lroundf(m_point.y() - m_font->fontMetrics().ascent()); // If there is a non-blur shadow and both the fill color and shadow color // are opaque, handle without skia. @@ -354,10 +355,11 @@ IntRect TransparencyAwareUniscribePainter::estimateTextBounds() // This algorithm for estimating how much extra space we need (the text may // go outside the selection rect) is based roughly on // TransparencyAwareGlyphPainter::estimateTextBounds above. - return IntRect(left - (m_font->ascent() + m_font->descent()) / 2, - m_point.y() - m_font->ascent() - m_font->lineGap(), - (right - left) + m_font->ascent() + m_font->descent(), - m_font->lineSpacing()); + const FontMetrics& fontMetrics = m_font->fontMetrics(); + return IntRect(left - (fontMetrics.ascent() + fontMetrics.descent()) / 2, + m_point.y() - fontMetrics.ascent() - fontMetrics.lineGap(), + (right - left) + fontMetrics.ascent() + fontMetrics.descent(), + fontMetrics.lineSpacing()); } } // namespace @@ -367,6 +369,11 @@ bool Font::canReturnFallbackFontsForComplexText() return false; } +bool Font::canExpandAroundIdeographsInComplexText() +{ + return false; +} + void Font::drawGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* font, const GlyphBuffer& glyphBuffer, @@ -496,14 +503,14 @@ void Font::drawComplexText(GraphicsContext* graphicsContext, COLORREF savedTextColor = GetTextColor(hdc); SetTextColor(hdc, textColor); state.draw(graphicsContext, hdc, static_cast<int>(point.x()) + shadowOffset.width(), - static_cast<int>(point.y() - ascent()) + shadowOffset.height(), from, to); + static_cast<int>(point.y() - fontMetrics().ascent()) + shadowOffset.height(), from, to); SetTextColor(hdc, savedTextColor); } // Uniscribe counts the coordinates from the upper left, while WebKit uses // the baseline, so we have to subtract off the ascent. state.draw(graphicsContext, hdc, static_cast<int>(point.x()), - static_cast<int>(point.y() - ascent()), from, to); + static_cast<int>(point.y() - fontMetrics().ascent()), from, to); context->canvas()->endPlatformPaint(); } diff --git a/Source/WebCore/platform/graphics/chromium/FontLinux.cpp b/Source/WebCore/platform/graphics/chromium/FontLinux.cpp index 822bbbb..823dbc9 100644 --- a/Source/WebCore/platform/graphics/chromium/FontLinux.cpp +++ b/Source/WebCore/platform/graphics/chromium/FontLinux.cpp @@ -55,6 +55,11 @@ bool Font::canReturnFallbackFontsForComplexText() return false; } +bool Font::canExpandAroundIdeographsInComplexText() +{ + return false; +} + static bool isCanvasMultiLayered(SkCanvas* canvas) { SkCanvas::LayerIter layerIterator(canvas, false); @@ -204,7 +209,7 @@ void Font::drawComplexText(GraphicsContext* gc, const TextRun& run, ComplexTextController controller(run, point.x(), this); controller.setWordSpacingAdjustment(wordSpacing()); controller.setLetterSpacingAdjustment(letterSpacing()); - controller.setPadding(run.padding()); + controller.setPadding(run.expansion()); if (run.rtl()) { // FIXME: this causes us to shape the text twice -- once to compute the width and then again @@ -213,7 +218,7 @@ void Font::drawComplexText(GraphicsContext* gc, const TextRun& run, controller.reset(point.x() + controller.widthOfFullRun()); // We need to set the padding again because ComplexTextController layout consumed the value. // Fixing the above problem would help here too. - controller.setPadding(run.padding()); + controller.setPadding(run.expansion()); } while (controller.nextScriptRun()) { @@ -241,7 +246,7 @@ float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFon ComplexTextController controller(run, 0, this); controller.setWordSpacingAdjustment(wordSpacing()); controller.setLetterSpacingAdjustment(letterSpacing()); - controller.setPadding(run.padding()); + controller.setPadding(run.expansion()); return controller.widthOfFullRun(); } @@ -275,11 +280,11 @@ int Font::offsetForPositionForComplexText(const TextRun& run, float xFloat, ComplexTextController controller(run, 0, this); controller.setWordSpacingAdjustment(wordSpacing()); controller.setLetterSpacingAdjustment(letterSpacing()); - controller.setPadding(run.padding()); + controller.setPadding(run.expansion()); if (run.rtl()) { // See FIXME in drawComplexText. controller.reset(controller.widthOfFullRun()); - controller.setPadding(run.padding()); + controller.setPadding(run.expansion()); } unsigned basePosition = 0; @@ -326,11 +331,11 @@ FloatRect Font::selectionRectForComplexText(const TextRun& run, ComplexTextController controller(run, 0, this); controller.setWordSpacingAdjustment(wordSpacing()); controller.setLetterSpacingAdjustment(letterSpacing()); - controller.setPadding(run.padding()); + controller.setPadding(run.expansion()); if (run.rtl()) { // See FIXME in drawComplexText. controller.reset(controller.widthOfFullRun()); - controller.setPadding(run.padding()); + controller.setPadding(run.expansion()); } // Iterate through the script runs in logical order, searching for the run covering the positions of interest. diff --git a/Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp b/Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp index a1ea012..6f9009f 100644 --- a/Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp +++ b/Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp @@ -36,6 +36,7 @@ #include "PlatformBridge.h" #include "PlatformString.h" +#include "SkAdvancedTypefaceMetrics.h" #include "SkPaint.h" #include "SkTypeface.h" @@ -71,6 +72,7 @@ FontPlatformData::FontPlatformData(const FontPlatformData& src) : m_typeface(src.m_typeface) , m_family(src.m_family) , m_textSize(src.m_textSize) + , m_emSizeInFontUnits(src.m_emSizeInFontUnits) , m_fakeBold(src.m_fakeBold) , m_fakeItalic(src.m_fakeItalic) , m_orientation(src.m_orientation) @@ -84,6 +86,7 @@ FontPlatformData::FontPlatformData(SkTypeface* tf, const char* family, float tex : m_typeface(tf) , m_family(family) , m_textSize(textSize) + , m_emSizeInFontUnits(0) , m_fakeBold(fakeBold) , m_fakeItalic(fakeItalic) , m_orientation(orientation) @@ -96,6 +99,7 @@ FontPlatformData::FontPlatformData(const FontPlatformData& src, float textSize) : m_typeface(src.m_typeface) , m_family(src.m_family) , m_textSize(textSize) + , m_emSizeInFontUnits(src.m_emSizeInFontUnits) , m_fakeBold(src.m_fakeBold) , m_fakeItalic(src.m_fakeItalic) , m_harfbuzzFace(src.m_harfbuzzFace) @@ -109,6 +113,17 @@ FontPlatformData::~FontPlatformData() SkSafeUnref(m_typeface); } +int FontPlatformData::emSizeInFontUnits() const +{ + if (m_emSizeInFontUnits) + return m_emSizeInFontUnits; + + SkAdvancedTypefaceMetrics* metrics = m_typeface->getAdvancedTypefaceMetrics(false); + m_emSizeInFontUnits = metrics->fEmSize; + metrics->unref(); + return m_emSizeInFontUnits; +} + FontPlatformData& FontPlatformData::operator=(const FontPlatformData& src) { SkRefCnt_SafeAssign(m_typeface, src.m_typeface); @@ -120,6 +135,7 @@ FontPlatformData& FontPlatformData::operator=(const FontPlatformData& src) m_harfbuzzFace = src.m_harfbuzzFace; m_orientation = src.m_orientation; m_style = src.m_style; + m_emSizeInFontUnits = src.m_emSizeInFontUnits; return *this; } diff --git a/Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.h b/Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.h index 43771d7..d9ebb61 100644 --- a/Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.h +++ b/Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.h @@ -63,6 +63,7 @@ public: FontPlatformData(WTF::HashTableDeletedValueType) : m_typeface(hashTableDeletedFontValue()) , m_textSize(0) + , m_emSizeInFontUnits(0) , m_fakeBold(false) , m_fakeItalic(false) { } @@ -70,6 +71,7 @@ public: FontPlatformData() : m_typeface(0) , m_textSize(0) + , m_emSizeInFontUnits(0) , m_fakeBold(false) , m_fakeItalic(false) , m_orientation(Horizontal) @@ -78,6 +80,7 @@ public: FontPlatformData(float textSize, bool fakeBold, bool fakeItalic) : m_typeface(0) , m_textSize(textSize) + , m_emSizeInFontUnits(0) , m_fakeBold(fakeBold) , m_fakeItalic(fakeItalic) , m_orientation(Horizontal) @@ -107,6 +110,7 @@ public: unsigned hash() const; float size() const { return m_textSize; } + int emSizeInFontUnits() const; FontOrientation orientation() const { return m_orientation; } @@ -153,6 +157,7 @@ private: SkTypeface* m_typeface; CString m_family; float m_textSize; + mutable int m_emSizeInFontUnits; bool m_fakeBold; bool m_fakeItalic; FontOrientation m_orientation; diff --git a/Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp b/Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp index 4393f97..953ee2f 100644 --- a/Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp +++ b/Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp @@ -83,6 +83,22 @@ struct GLES2Canvas::State { AffineTransform m_ctm; WTF::Vector<Path> m_clippingPaths; bool m_clippingEnabled; + + // Helper function for applying the state's alpha value to the given input + // color to produce a new output color. The logic is the same as + // PlatformContextSkia::State::applyAlpha(), but the type is different. + Color applyAlpha(const Color& c) + { + int s = roundf(m_alpha * 256); + if (s >= 256) + return c; + if (s < 0) + return Color(); + + int a = (c.alpha() * s) >> 8; + return Color(c.red(), c.green(), c.blue(), a); + } + }; static inline FloatPoint operator*(const FloatPoint& f, float scale) @@ -192,7 +208,7 @@ void GLES2Canvas::fillPath(const Path& path) { m_context->applyCompositeOperator(m_state->m_compositeOp); applyClipping(m_state->m_clippingEnabled); - fillPath(path, m_state->m_fillColor); + fillPath(path, m_state->applyAlpha(m_state->m_fillColor)); } void GLES2Canvas::fillRect(const FloatRect& rect, const Color& color, ColorSpace colorSpace) @@ -214,7 +230,7 @@ void GLES2Canvas::fillRect(const FloatRect& rect, const Color& color, ColorSpace void GLES2Canvas::fillRect(const FloatRect& rect) { - fillRect(rect, m_state->m_fillColor, ColorSpaceDeviceRGB); + fillRect(rect, m_state->applyAlpha(m_state->m_fillColor), ColorSpaceDeviceRGB); } void GLES2Canvas::setFillColor(const Color& color, ColorSpace colorSpace) @@ -322,8 +338,8 @@ void GLES2Canvas::drawTexturedRect(Texture* texture, const FloatRect& srcRect, c m_context->useQuadVertices(); m_context->setActiveTexture(GraphicsContext3D::TEXTURE0); - for (int y = tileIdxRect.y(); y <= tileIdxRect.bottom(); y++) { - for (int x = tileIdxRect.x(); x <= tileIdxRect.right(); x++) + for (int y = tileIdxRect.y(); y <= tileIdxRect.maxY(); y++) { + for (int x = tileIdxRect.x(); x <= tileIdxRect.maxX(); x++) drawTexturedRectTile(texture, tiles.tileIndex(x, y), srcRect, dstRect, transform, alpha); } } diff --git a/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp index 5e8d148..488230c 100644 --- a/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp @@ -263,6 +263,17 @@ void GraphicsLayerChromium::setContentsOpaque(bool opaque) updateContentsOpaque(); } +void GraphicsLayerChromium::setMaskLayer(GraphicsLayer* maskLayer) +{ + if (maskLayer == m_maskLayer) + return; + + GraphicsLayer::setMaskLayer(maskLayer); + + LayerChromium* maskLayerChromium = m_maskLayer ? m_maskLayer->platformLayer() : 0; + m_layer->setMaskLayer(maskLayerChromium); +} + void GraphicsLayerChromium::setBackfaceVisibility(bool visible) { if (m_backfaceVisibility == visible) @@ -283,6 +294,15 @@ void GraphicsLayerChromium::setOpacity(float opacity) primaryLayer()->setOpacity(opacity); } +void GraphicsLayerChromium::setReplicatedByLayer(GraphicsLayer* layer) +{ + GraphicsLayerChromium* layerChromium = static_cast<GraphicsLayerChromium*>(layer); + GraphicsLayer::setReplicatedByLayer(layer); + LayerChromium* replicaLayer = layerChromium ? layerChromium->primaryLayer() : 0; + primaryLayer()->setReplicaLayer(replicaLayer); +} + + void GraphicsLayerChromium::setContentsNeedsDisplay() { if (m_contentsLayer) @@ -494,6 +514,7 @@ void GraphicsLayerChromium::updateAnchorPoint() { primaryLayer()->setAnchorPoint(FloatPoint(m_anchorPoint.x(), m_anchorPoint.y())); primaryLayer()->setAnchorPointZ(m_anchorPoint.z()); + updateLayerPosition(); } diff --git a/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h b/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h index 130c25c..92c61fe 100644 --- a/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h +++ b/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h @@ -67,6 +67,7 @@ public: virtual void setPreserves3D(bool); virtual void setMasksToBounds(bool); virtual void setDrawsContent(bool); + virtual void setMaskLayer(GraphicsLayer*); virtual void setBackgroundColor(const Color&); virtual void clearBackgroundColor(); @@ -74,6 +75,8 @@ public: virtual void setContentsOpaque(bool); virtual void setBackfaceVisibility(bool); + virtual void setReplicatedByLayer(GraphicsLayer*); + virtual void setOpacity(float); virtual void setNeedsDisplay(); diff --git a/Source/WebCore/platform/graphics/chromium/HarfbuzzSkia.cpp b/Source/WebCore/platform/graphics/chromium/HarfbuzzSkia.cpp index 056d8eb..26ca64e 100644 --- a/Source/WebCore/platform/graphics/chromium/HarfbuzzSkia.cpp +++ b/Source/WebCore/platform/graphics/chromium/HarfbuzzSkia.cpp @@ -94,7 +94,7 @@ static void glyphsToAdvances(HB_Font hbFont, const HB_Glyph* glyphs, hb_uint32 n font->setupPaint(&paint); paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); - OwnArrayPtr<uint16_t> glyphs16(new uint16_t[numGlyphs]); + OwnArrayPtr<uint16_t> glyphs16 = adoptArrayPtr(new uint16_t[numGlyphs]); if (!glyphs16.get()) return; for (unsigned i = 0; i < numGlyphs; ++i) @@ -120,7 +120,7 @@ static HB_Bool canRender(HB_Font hbFont, const HB_UChar16* characters, hb_uint32 font->setupPaint(&paint); paint.setTextEncoding(SkPaint::kUTF16_TextEncoding); - OwnArrayPtr<uint16_t> glyphs16(new uint16_t[length]); + OwnArrayPtr<uint16_t> glyphs16 = adoptArrayPtr(new uint16_t[length]); if (!glyphs16.get()) return 0; int numGlyphs = paint.textToGlyphs(characters, length * sizeof(uint16_t), glyphs16.get()); diff --git a/Source/WebCore/platform/graphics/chromium/IconChromiumLinux.cpp b/Source/WebCore/platform/graphics/chromium/IconChromium.cpp index 16f55e2..398cc3b 100644 --- a/Source/WebCore/platform/graphics/chromium/IconChromiumLinux.cpp +++ b/Source/WebCore/platform/graphics/chromium/IconChromium.cpp @@ -1,10 +1,10 @@ /* - * Copyright (c) 2008, 2009 Google Inc. All rights reserved. - * + * Copyright (c) 2011, Google Inc. All rights reserved. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: - * + * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above @@ -14,7 +14,7 @@ * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -32,12 +32,11 @@ #include "Icon.h" #include "GraphicsContext.h" -#include "NotImplemented.h" #include "PlatformString.h" namespace WebCore { -Icon::Icon(const PlatformIcon& icon) +Icon::Icon(PassRefPtr<PlatformIcon> icon) : m_icon(icon) { } @@ -46,9 +45,14 @@ Icon::~Icon() { } -void Icon::paint(GraphicsContext*, const IntRect&) +void Icon::paint(GraphicsContext* context, const IntRect& rect) { - notImplemented(); + if (context->paintingDisabled()) + return; + + // An Icon doesn't know the color space of the file upload control. + // So use ColorSpaceDeviceRGB. + context->drawImage(m_icon.get(), ColorSpaceDeviceRGB, rect); } } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/chromium/IconChromiumMac.cpp b/Source/WebCore/platform/graphics/chromium/IconChromiumMac.cpp deleted file mode 100644 index a24afb2..0000000 --- a/Source/WebCore/platform/graphics/chromium/IconChromiumMac.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2008, Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "Icon.h" - -#include "PassRefPtr.h" - -// FIXME: These are temporary stubs, we need real implementations which -// may come in the form of IconChromium.cpp. The Windows Chromium -// implementation is currently in IconWin.cpp. - -namespace WebCore { - -Icon::~Icon() -{ -} - -void Icon::paint(GraphicsContext*, const IntRect&) -{ -} - -} diff --git a/Source/WebCore/platform/graphics/chromium/IconChromiumWin.cpp b/Source/WebCore/platform/graphics/chromium/IconChromiumWin.cpp deleted file mode 100644 index e958d4a..0000000 --- a/Source/WebCore/platform/graphics/chromium/IconChromiumWin.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2008, 2009, Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "Icon.h" - -#include <windows.h> -#include <shellapi.h> - -#include "GraphicsContext.h" -#include "PlatformContextSkia.h" -#include "PlatformString.h" -#include "SkiaUtils.h" - -namespace WebCore { - -Icon::Icon(const PlatformIcon& icon) - : m_icon(icon) -{ -} - -Icon::~Icon() -{ - if (m_icon) - DestroyIcon(m_icon); -} - -void Icon::paint(GraphicsContext* context, const IntRect& rect) -{ - if (context->paintingDisabled()) - return; - - HDC hdc = context->platformContext()->canvas()->beginPlatformPaint(); - DrawIconEx(hdc, rect.x(), rect.y(), m_icon, rect.width(), rect.height(), 0, 0, DI_NORMAL); - context->platformContext()->canvas()->endPlatformPaint(); -} - -} // namespace WebCore diff --git a/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp index b7ab098..8d01d9b 100644 --- a/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp @@ -143,6 +143,7 @@ PassRefPtr<LayerChromium> LayerChromium::create(GraphicsLayerChromium* owner) LayerChromium::LayerChromium(GraphicsLayerChromium* owner) : m_owner(owner) , m_contentsDirty(false) + , m_maskLayer(0) , m_targetRenderSurface(0) , m_superlayer(0) , m_anchorPoint(0.5, 0.5) @@ -162,6 +163,7 @@ LayerChromium::LayerChromium(GraphicsLayerChromium* owner) , m_drawDepth(0) , m_layerRenderer(0) , m_renderSurface(0) + , m_replicaLayer(0) { } @@ -433,9 +435,7 @@ void LayerChromium::drawTexturedQuad(GraphicsContext3D* context, const Transform renderMatrix.scale3d(width, height, 1); // Apply the projection matrix before sending the transform over to the shader. - renderMatrix.multiply(projectionMatrix); - - toGLMatrix(&glMatrix[0], renderMatrix); + toGLMatrix(&glMatrix[0], projectionMatrix * renderMatrix); GLC(context, context->uniformMatrix4fv(matrixLocation, false, &glMatrix[0], 1)); @@ -457,8 +457,7 @@ void LayerChromium::drawDebugBorder() layerRenderer()->useShader(sv->borderShaderProgram()); TransformationMatrix renderMatrix = drawTransform(); renderMatrix.scale3d(bounds().width(), bounds().height(), 1); - renderMatrix.multiply(layerRenderer()->projectionMatrix()); - toGLMatrix(&glMatrix[0], renderMatrix); + toGLMatrix(&glMatrix[0], layerRenderer()->projectionMatrix() * renderMatrix); GraphicsContext3D* context = layerRendererContext(); GLC(context, context->uniformMatrix4fv(sv->borderShaderMatrixLocation(), false, &glMatrix[0], 1)); diff --git a/Source/WebCore/platform/graphics/chromium/LayerChromium.h b/Source/WebCore/platform/graphics/chromium/LayerChromium.h index a0a690f..5c7e2b1 100644 --- a/Source/WebCore/platform/graphics/chromium/LayerChromium.h +++ b/Source/WebCore/platform/graphics/chromium/LayerChromium.h @@ -112,6 +112,9 @@ public: void setName(const String& name) { m_name = name; } String name() const { return m_name; } + void setMaskLayer(LayerChromium* maskLayer) { m_maskLayer = maskLayer; } + LayerChromium* maskLayer() const { return m_maskLayer.get(); } + void setNeedsDisplay(const FloatRect& dirtyRect); void setNeedsDisplay(); const FloatRect& dirtyRect() const { return m_dirtyRect; } @@ -152,12 +155,17 @@ public: void setOwner(GraphicsLayerChromium* owner) { m_owner = owner; } + void setReplicaLayer(LayerChromium* layer) { m_replicaLayer = layer; } + LayerChromium* replicaLayer() { return m_replicaLayer; } + // Returns the rect containtaining this layer in the current view's coordinate system. const IntRect getDrawRect() const; // These methods typically need to be overwritten by derived classes. virtual bool drawsContent() { return false; } virtual void updateContentsIfDirty() { } + virtual void unreserveContentsTexture() { } + virtual void bindContentsTexture() { } virtual void draw() { } void drawDebugBorder(); @@ -222,6 +230,8 @@ protected: FloatRect m_dirtyRect; bool m_contentsDirty; + RefPtr<LayerChromium> m_maskLayer; + // Render surface this layer draws into. This is a surface that can belong // either to this layer (if m_targetRenderSurface == m_renderSurface) or // to an ancestor of this layer. The target render surface determines the @@ -298,6 +308,9 @@ private: // Hierarchical bounding rect containing the layer and its descendants. IntRect m_drawableContentRect; + // Replica layer used for reflections. + LayerChromium* m_replicaLayer; + String m_name; }; diff --git a/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp b/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp index 90eac74..f5548c9 100644 --- a/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp @@ -143,20 +143,19 @@ void LayerRendererChromium::useShader(unsigned programId) IntRect LayerRendererChromium::verticalScrollbarRect(const IntRect& visibleRect, const IntRect& contentRect) { - IntRect verticalScrollbar(IntPoint(contentRect.right(), contentRect.y()), IntSize(visibleRect.width() - contentRect.width(), visibleRect.height())); + IntRect verticalScrollbar(IntPoint(contentRect.maxX(), contentRect.y()), IntSize(visibleRect.width() - contentRect.width(), visibleRect.height())); return verticalScrollbar; } IntRect LayerRendererChromium::horizontalScrollbarRect(const IntRect& visibleRect, const IntRect& contentRect) { - IntRect horizontalScrollbar(IntPoint(contentRect.x(), contentRect.bottom()), IntSize(visibleRect.width(), visibleRect.height() - contentRect.height())); + IntRect horizontalScrollbar(IntPoint(contentRect.x(), contentRect.maxY()), IntSize(visibleRect.width(), visibleRect.height() - contentRect.height())); return horizontalScrollbar; } void LayerRendererChromium::invalidateRootLayerRect(const IntRect& dirtyRect, const IntRect& visibleRect, const IntRect& contentRect) { - if (contentRect.intersects(dirtyRect)) - m_rootLayerTiler->invalidateRect(dirtyRect); + m_rootLayerTiler->invalidateRect(dirtyRect); if (m_horizontalScrollbarTiler) { IntRect scrollbar = horizontalScrollbarRect(visibleRect, contentRect); if (dirtyRect.intersects(scrollbar)) { @@ -266,6 +265,11 @@ void LayerRendererChromium::drawLayers(const IntRect& visibleRect, const IntRect // Re-enable color writes to layers, which may be partially transparent. m_context->colorMask(true, true, true, true); + // Recheck that we still have a root layer. This may become null if + // compositing gets turned off during a paint operation. + if (!m_rootLayer) + return; + // Set the root visible/content rects --- used by subsequent drawLayers calls. m_rootVisibleRect = visibleRect; m_rootContentRect = contentRect; @@ -346,8 +350,8 @@ void LayerRendererChromium::setRootLayer(PassRefPtr<LayerChromium> layer) void LayerRendererChromium::getFramebufferPixels(void *pixels, const IntRect& rect) { - ASSERT(rect.right() <= rootLayerTextureSize().width() - && rect.bottom() <= rootLayerTextureSize().height()); + ASSERT(rect.maxX() <= rootLayerTextureSize().width() + && rect.maxY() <= rootLayerTextureSize().height()); if (!pixels) return; @@ -388,7 +392,7 @@ bool LayerRendererChromium::isLayerVisible(LayerChromium* layer, const Transform // bounds into clip space. TransformationMatrix renderMatrix = matrix; renderMatrix.scale3d(layer->bounds().width(), layer->bounds().height(), 1); - renderMatrix.multiply(m_projectionMatrix); + renderMatrix = m_projectionMatrix * renderMatrix; FloatRect layerRect(-0.5, -0.5, 1, 1); FloatRect mappedRect = renderMatrix.mapRect(layerRect); @@ -434,12 +438,12 @@ void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const Tr // LT = Tr[l] layerLocalTransform.translate3d(position.x(), position.y(), layer->anchorPointZ()); // LT = Tr[l] * M[l] - layerLocalTransform.multLeft(layer->transform()); + layerLocalTransform.multiply(layer->transform()); // LT = Tr[l] * M[l] * Tr[c] layerLocalTransform.translate3d(centerOffsetX, centerOffsetY, -layer->anchorPointZ()); TransformationMatrix combinedTransform = parentMatrix; - combinedTransform = combinedTransform.multLeft(layerLocalTransform); + combinedTransform = combinedTransform.multiply(layerLocalTransform); FloatRect layerRect(-0.5 * layer->bounds().width(), -0.5 * layer->bounds().height(), layer->bounds().width(), layer->bounds().height()); IntRect transformedLayerRect; @@ -448,12 +452,17 @@ void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const Tr // these conditions hold: // 1. The layer clips its descendants and its transform is not a simple translation. // 2. If the layer has opacity != 1 and does not have a preserves-3d transform style. + // 3. The layer uses a mask + // 4. The layer has a replica (used for reflections) // If a layer preserves-3d then we don't create a RenderSurface for it to avoid flattening // out its children. The opacity value of the children layers is multiplied by the opacity // of their parent. bool useSurfaceForClipping = layer->masksToBounds() && !isScaleOrTranslation(combinedTransform); bool useSurfaceForOpacity = layer->opacity() != 1 && !layer->preserves3D(); - if ((useSurfaceForClipping || useSurfaceForOpacity) && layer->descendantsDrawContent()) { + bool useSurfaceForMasking = layer->maskLayer(); + bool useSurfaceForReflection = layer->replicaLayer(); + if (((useSurfaceForClipping || useSurfaceForOpacity) && layer->descendantsDrawContent()) + || useSurfaceForMasking || useSurfaceForReflection) { RenderSurfaceChromium* renderSurface = layer->m_renderSurface.get(); if (!renderSurface) renderSurface = layer->createRenderSurface(); @@ -487,6 +496,18 @@ void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const Tr renderSurface->m_layerList.clear(); + if (layer->maskLayer()) { + renderSurface->m_maskLayer = layer->maskLayer(); + layer->maskLayer()->setLayerRenderer(this); + layer->maskLayer()->m_targetRenderSurface = renderSurface; + } else + renderSurface->m_maskLayer = 0; + + if (layer->replicaLayer() && layer->replicaLayer()->maskLayer()) { + layer->replicaLayer()->maskLayer()->setLayerRenderer(this); + layer->replicaLayer()->maskLayer()->m_targetRenderSurface = renderSurface; + } + renderSurfaceLayerList.append(layer); } else { // DT = M[p] * LT @@ -540,7 +561,7 @@ void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const Tr } // Apply the sublayer transform at the center of the layer. - sublayerMatrix.multLeft(layer->sublayerTransform()); + sublayerMatrix.multiply(layer->sublayerTransform()); // The origin of the sublayers is the top left corner of the layer, not the // center. The matrix passed down to the sublayers is therefore: @@ -558,16 +579,13 @@ void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const Tr if (sublayer->m_renderSurface) { RenderSurfaceChromium* sublayerRenderSurface = sublayer->m_renderSurface.get(); - const IntRect& contentRect = sublayerRenderSurface->contentRect(); - FloatRect sublayerRect(-0.5 * contentRect.width(), -0.5 * contentRect.height(), - contentRect.width(), contentRect.height()); - layer->m_drawableContentRect.unite(enclosingIntRect(sublayerRenderSurface->m_drawTransform.mapRect(sublayerRect))); + layer->m_drawableContentRect.unite(enclosingIntRect(sublayerRenderSurface->drawableContentRect())); descendants.append(sublayer); } else layer->m_drawableContentRect.unite(sublayer->m_drawableContentRect); } - if (layer->masksToBounds()) + if (layer->masksToBounds() || useSurfaceForMasking) layer->m_drawableContentRect.intersect(transformedLayerRect); if (layer->m_renderSurface && layer != m_rootLayer) { @@ -577,9 +595,13 @@ void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const Tr // Restrict the RenderSurface size to the portion that's visible. FloatSize centerOffsetDueToClipping; - renderSurface->m_contentRect.intersect(layer->m_scissorRect); - FloatPoint clippedSurfaceCenter = renderSurface->contentRectCenter(); - centerOffsetDueToClipping = clippedSurfaceCenter - surfaceCenter; + // Don't clip if the layer is reflected as the reflection shouldn't be + // clipped. + if (!layer->replicaLayer()) { + renderSurface->m_contentRect.intersect(layer->m_scissorRect); + FloatPoint clippedSurfaceCenter = renderSurface->contentRectCenter(); + centerOffsetDueToClipping = clippedSurfaceCenter - surfaceCenter; + } // The RenderSurface backing texture cannot exceed the maximum supported // texture size. @@ -596,6 +618,15 @@ void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const Tr // Adjust the origin of the transform to be the center of the render surface. renderSurface->m_drawTransform = renderSurface->m_originTransform; renderSurface->m_drawTransform.translate3d(surfaceCenter.x() + centerOffsetDueToClipping.width(), surfaceCenter.y() + centerOffsetDueToClipping.height(), 0); + + // Compute the transformation matrix used to draw the replica of the render + // surface. + if (layer->replicaLayer()) { + renderSurface->m_replicaDrawTransform = renderSurface->m_originTransform; + renderSurface->m_replicaDrawTransform.translate3d(layer->replicaLayer()->position().x(), layer->replicaLayer()->position().y(), 0); + renderSurface->m_replicaDrawTransform.multiply(layer->replicaLayer()->transform()); + renderSurface->m_replicaDrawTransform.translate3d(surfaceCenter.x() - anchorPoint.x() * bounds.width(), surfaceCenter.y() - anchorPoint.y() * bounds.height(), 0); + } } // Compute the depth value of the center of the layer which will be used when @@ -682,10 +713,10 @@ void LayerRendererChromium::drawLayer(LayerChromium* layer, RenderSurfaceChromiu if (!isLayerVisible) return; - // FIXME: Need to take into account the transform of the containing - // RenderSurface here, otherwise single-sided layers that draw on - // transformed surfaces won't always be culled properly. - if (!layer->doubleSided() && layer->m_drawTransform.m33() < 0) + // FIXME: Need to take into account the commulative render surface transforms all the way from + // the default render surface in order to determine visibility. + TransformationMatrix combinedDrawMatrix = (layer->m_renderSurface ? layer->m_renderSurface->drawTransform().multiply(layer->m_drawTransform) : layer->m_drawTransform); + if (!layer->doubleSided() && combinedDrawMatrix.m33() < 0) return; if (layer->drawsContent()) { @@ -711,7 +742,7 @@ void LayerRendererChromium::setScissorToRect(const IntRect& scissorRect) // But, if rendering to offscreen texture, we reverse our sense of 'upside down'. int scissorY; if (m_currentRenderSurface == m_defaultRenderSurface && !m_compositeOffscreen) - scissorY = m_currentRenderSurface->m_contentRect.height() - (scissorRect.bottom() - m_currentRenderSurface->m_contentRect.y()); + scissorY = m_currentRenderSurface->m_contentRect.height() - (scissorRect.maxY() - m_currentRenderSurface->m_contentRect.y()); else scissorY = scissorRect.y() - m_currentRenderSurface->m_contentRect.y(); GLC(m_context.get(), m_context->scissor(scissorX, scissorY, scissorRect.width(), scissorRect.height())); @@ -737,9 +768,9 @@ bool LayerRendererChromium::checkTextureSize(const IntSize& textureSize) void LayerRendererChromium::setDrawViewportRect(const IntRect& drawRect, bool flipY) { if (flipY) - m_projectionMatrix = orthoMatrix(drawRect.x(), drawRect.right(), drawRect.bottom(), drawRect.y()); + m_projectionMatrix = orthoMatrix(drawRect.x(), drawRect.maxX(), drawRect.maxY(), drawRect.y()); else - m_projectionMatrix = orthoMatrix(drawRect.x(), drawRect.right(), drawRect.y(), drawRect.bottom()); + m_projectionMatrix = orthoMatrix(drawRect.x(), drawRect.maxX(), drawRect.y(), drawRect.maxY()); GLC(m_context.get(), m_context->viewport(0, 0, drawRect.width(), drawRect.height())); } diff --git a/Source/WebCore/platform/graphics/chromium/LayerTexture.cpp b/Source/WebCore/platform/graphics/chromium/LayerTexture.cpp index 32bfa0b..23cb4b3 100644 --- a/Source/WebCore/platform/graphics/chromium/LayerTexture.cpp +++ b/Source/WebCore/platform/graphics/chromium/LayerTexture.cpp @@ -79,6 +79,7 @@ void LayerTexture::unreserve() void LayerTexture::bindTexture() { + ASSERT(m_textureManager->hasTexture(m_token)); m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureId); } diff --git a/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp b/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp index 6b65e66..e28c084 100644 --- a/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp @@ -145,8 +145,8 @@ void LayerTilerChromium::contentRectToTileIndices(const IntRect& contentRect, in left = layerRect.x() / m_tileSize.width(); top = layerRect.y() / m_tileSize.height(); - right = (layerRect.right() - 1) / m_tileSize.width(); - bottom = (layerRect.bottom() - 1) / m_tileSize.height(); + right = (layerRect.maxX() - 1) / m_tileSize.width(); + bottom = (layerRect.maxY() - 1) / m_tileSize.height(); } IntRect LayerTilerChromium::contentRectToLayerRect(const IntRect& contentRect) const @@ -272,7 +272,11 @@ void LayerTilerChromium::update(TilePaintInterface& painter, const IntRect& cont // Get the contents of the updated rect. const SkBitmap& bitmap = canvas->getDevice()->accessBitmap(false); ASSERT(bitmap.width() == paintRect.width() && bitmap.height() == paintRect.height()); + if (bitmap.width() != paintRect.width() || bitmap.height() != paintRect.height()) + CRASH(); uint8_t* paintPixels = static_cast<uint8_t*>(bitmap.getPixels()); + if (!paintPixels) + CRASH(); #elif PLATFORM(CG) Vector<uint8_t> canvasPixels; int rowBytes = 4 * paintRect.width(); @@ -299,9 +303,15 @@ void LayerTilerChromium::update(TilePaintInterface& painter, const IntRect& cont #error "Need to implement for your platform." #endif + // Painting could cause compositing to get turned off, which may cause the tiler to become invalidated mid-update. + if (!m_tiles.size()) + return; + for (int j = top; j <= bottom; ++j) { for (int i = left; i <= right; ++i) { Tile* tile = m_tiles[tileIndex(i, j)].get(); + if (!tile) + CRASH(); if (!tile->dirty()) continue; @@ -320,13 +330,21 @@ void LayerTilerChromium::update(TilePaintInterface& painter, const IntRect& cont // Calculate tile-space rectangle to upload into. IntRect destRect(IntPoint(sourceRect.x() - anchor.x(), sourceRect.y() - anchor.y()), sourceRect.size()); - ASSERT(destRect.x() >= 0); - ASSERT(destRect.y() >= 0); + if (destRect.x() < 0) + CRASH(); + if (destRect.y() < 0) + CRASH(); // Offset from paint rectangle to this tile's dirty rectangle. IntPoint paintOffset(sourceRect.x() - paintRect.x(), sourceRect.y() - paintRect.y()); - ASSERT(paintOffset.x() >= 0); - ASSERT(paintOffset.y() >= 0); + if (paintOffset.x() < 0) + CRASH(); + if (paintOffset.y() < 0) + CRASH(); + if (paintOffset.x() + destRect.width() > paintRect.width()) + CRASH(); + if (paintOffset.y() + destRect.height() > paintRect.height()) + CRASH(); uint8_t* pixelSource; if (paintRect.width() == sourceRect.width() && !paintOffset.x()) @@ -357,7 +375,7 @@ void LayerTilerChromium::setLayerPosition(const IntPoint& layerPosition) void LayerTilerChromium::draw(const IntRect& contentRect) { - if (m_skipsDraw) + if (m_skipsDraw || !m_tiles.size()) return; // We reuse the shader program used by ContentLayerChromium. @@ -394,6 +412,9 @@ void LayerTilerChromium::resizeLayer(const IntSize& size) int width = (size.width() + m_tileSize.width() - 1) / m_tileSize.width(); int height = (size.height() + m_tileSize.height() - 1) / m_tileSize.height(); + if (height && (width > INT_MAX / height)) + CRASH(); + Vector<OwnPtr<Tile> > newTiles; newTiles.resize(width * height); for (int j = 0; j < m_layerTileSize.height(); ++j) @@ -409,7 +430,7 @@ void LayerTilerChromium::growLayerToContain(const IntRect& contentRect) { // Grow the tile array to contain this content rect. IntRect layerRect = contentRectToLayerRect(contentRect); - IntSize layerSize = IntSize(layerRect.right(), layerRect.bottom()); + IntSize layerSize = IntSize(layerRect.maxX(), layerRect.maxY()); IntSize newSize = layerSize.expandedTo(m_layerSize); resizeLayer(newSize); diff --git a/Source/WebCore/platform/graphics/chromium/PlatformIcon.h b/Source/WebCore/platform/graphics/chromium/PlatformIcon.h index 51613b8..b485917 100644 --- a/Source/WebCore/platform/graphics/chromium/PlatformIcon.h +++ b/Source/WebCore/platform/graphics/chromium/PlatformIcon.h @@ -31,11 +31,11 @@ #ifndef PlatformIcon_h #define PlatformIcon_h -typedef struct HICON__* HICON; - namespace WebCore { -typedef HICON PlatformIcon; +class Image; + +typedef Image PlatformIcon; } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp index 696828f..b3ce9d7 100644 --- a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp @@ -38,15 +38,17 @@ namespace WebCore { RenderSurfaceChromium::SharedValues::SharedValues(GraphicsContext3D* context) : m_context(context) , m_shaderProgram(0) + , m_maskShaderProgram(0) , m_shaderSamplerLocation(-1) , m_shaderMatrixLocation(-1) , m_shaderAlphaLocation(-1) + , m_maskShaderSamplerLocation(-1) + , m_maskShaderMaskSamplerLocation(-1) + , m_maskShaderMatrixLocation(-1) + , m_maskShaderAlphaLocation(-1) , m_initialized(false) { - // The following program composites layers whose contents are the results of a previous - // render operation and therefore doesn't perform any color swizzling. It is used - // in scrolling and for compositing offscreen textures. - char renderSurfaceVertexShaderString[] = + char vertexShaderString[] = "attribute vec4 a_position; \n" "attribute vec2 a_texCoord; \n" "uniform mat4 matrix; \n" @@ -56,7 +58,7 @@ RenderSurfaceChromium::SharedValues::SharedValues(GraphicsContext3D* context) " gl_Position = matrix * a_position; \n" " v_texCoord = a_texCoord; \n" "} \n"; - char renderSurfaceFragmentShaderString[] = + char fragmentShaderString[] = "precision mediump float; \n" "varying vec2 v_texCoord; \n" "uniform sampler2D s_texture; \n" @@ -66,9 +68,22 @@ RenderSurfaceChromium::SharedValues::SharedValues(GraphicsContext3D* context) " vec4 texColor = texture2D(s_texture, v_texCoord); \n" " gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha; \n" "} \n"; + char fragmentShaderWithMaskString[] = + "precision mediump float; \n" + "varying vec2 v_texCoord; \n" + "uniform sampler2D s_texture; \n" + "uniform sampler2D s_mask; \n" + "uniform float alpha; \n" + "void main() \n" + "{ \n" + " vec4 texColor = texture2D(s_texture, v_texCoord); \n" + " vec4 maskColor = texture2D(s_mask, v_texCoord); \n" + " gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha * maskColor.w; \n" + "} \n"; - m_shaderProgram = LayerChromium::createShaderProgram(m_context, renderSurfaceVertexShaderString, renderSurfaceFragmentShaderString); - if (!m_shaderProgram) { + m_shaderProgram = LayerChromium::createShaderProgram(m_context, vertexShaderString, fragmentShaderString); + m_maskShaderProgram = LayerChromium::createShaderProgram(m_context, vertexShaderString, fragmentShaderWithMaskString); + if (!m_shaderProgram || !m_maskShaderProgram) { LOG_ERROR("RenderSurfaceChromium: Failed to create shader program"); return; } @@ -76,10 +91,24 @@ RenderSurfaceChromium::SharedValues::SharedValues(GraphicsContext3D* context) GLC(m_context, m_shaderSamplerLocation = m_context->getUniformLocation(m_shaderProgram, "s_texture")); GLC(m_context, m_shaderMatrixLocation = m_context->getUniformLocation(m_shaderProgram, "matrix")); GLC(m_context, m_shaderAlphaLocation = m_context->getUniformLocation(m_shaderProgram, "alpha")); - if (m_shaderSamplerLocation == -1 || m_shaderMatrixLocation == -1 || m_shaderAlphaLocation == -1) { - LOG_ERROR("Failed to initialize texture layer shader."); + + GLC(m_context, m_maskShaderSamplerLocation = m_context->getUniformLocation(m_maskShaderProgram, "s_texture")); + GLC(m_context, m_maskShaderMaskSamplerLocation = m_context->getUniformLocation(m_maskShaderProgram, "s_mask")); + GLC(m_context, m_maskShaderMatrixLocation = m_context->getUniformLocation(m_maskShaderProgram, "matrix")); + GLC(m_context, m_maskShaderAlphaLocation = m_context->getUniformLocation(m_maskShaderProgram, "alpha")); + + if (m_shaderSamplerLocation == -1 || m_shaderMatrixLocation == -1 || m_shaderAlphaLocation == -1 + || m_maskShaderSamplerLocation == -1 || m_maskShaderMaskSamplerLocation == -1 || m_maskShaderMatrixLocation == -1 || m_maskShaderAlphaLocation == -1) { + LOG_ERROR("Failed to initialize render surface shaders."); return; } + + GLC(m_context, m_context->useProgram(m_shaderProgram)); + GLC(m_context, m_context->uniform1i(m_shaderSamplerLocation, 0)); + GLC(m_context, m_context->useProgram(m_maskShaderProgram)); + GLC(m_context, m_context->uniform1i(m_maskShaderSamplerLocation, 0)); + GLC(m_context, m_context->uniform1i(m_maskShaderMaskSamplerLocation, 1)); + GLC(m_context, m_context->useProgram(0)); m_initialized = true; } @@ -87,10 +116,13 @@ RenderSurfaceChromium::SharedValues::~SharedValues() { if (m_shaderProgram) GLC(m_context, m_context->deleteProgram(m_shaderProgram)); + if (m_maskShaderProgram) + GLC(m_context, m_context->deleteProgram(m_maskShaderProgram)); } RenderSurfaceChromium::RenderSurfaceChromium(LayerChromium* owningLayer) : m_owningLayer(owningLayer) + , m_maskLayer(0) , m_skipsDraw(false) { } @@ -116,6 +148,17 @@ LayerRendererChromium* RenderSurfaceChromium::layerRenderer() return m_owningLayer->layerRenderer(); } +FloatRect RenderSurfaceChromium::drawableContentRect() const +{ + FloatRect localContentRect(-0.5 * m_contentRect.width(), -0.5 * m_contentRect.height(), + m_contentRect.width(), m_contentRect.height()); + FloatRect drawableContentRect = m_drawTransform.mapRect(localContentRect); + if (m_owningLayer->replicaLayer()) + drawableContentRect.unite(m_replicaDrawTransform.mapRect(localContentRect)); + + return drawableContentRect; +} + bool RenderSurfaceChromium::prepareContentsTexture() { IntSize requiredSize(m_contentRect.size()); @@ -136,24 +179,69 @@ bool RenderSurfaceChromium::prepareContentsTexture() return true; } -void RenderSurfaceChromium::draw() +void RenderSurfaceChromium::drawSurface(LayerChromium* maskLayer, const TransformationMatrix& drawTransform) { - if (m_skipsDraw || !m_contentsTexture) - return; - - m_contentsTexture->bindTexture(); + GraphicsContext3D* context3D = layerRenderer()->context(); + int shaderMatrixLocation = -1; + int shaderAlphaLocation = -1; const RenderSurfaceChromium::SharedValues* sv = layerRenderer()->renderSurfaceSharedValues(); ASSERT(sv && sv->initialized()); + bool useMask = false; + if (maskLayer && maskLayer->drawsContent()) { + maskLayer->updateContentsIfDirty(); + if (!maskLayer->bounds().isEmpty()) { + context3D->makeContextCurrent(); + layerRenderer()->useShader(sv->maskShaderProgram()); + GLC(context3D, context3D->activeTexture(GraphicsContext3D::TEXTURE0)); + m_contentsTexture->bindTexture(); + GLC(context3D, context3D->activeTexture(GraphicsContext3D::TEXTURE1)); + maskLayer->bindContentsTexture(); + GLC(context3D, context3D->activeTexture(GraphicsContext3D::TEXTURE0)); + shaderMatrixLocation = sv->maskShaderMatrixLocation(); + shaderAlphaLocation = sv->maskShaderAlphaLocation(); + useMask = true; + } + } + + if (!useMask) { + layerRenderer()->useShader(sv->shaderProgram()); + m_contentsTexture->bindTexture(); + shaderMatrixLocation = sv->shaderMatrixLocation(); + shaderAlphaLocation = sv->shaderAlphaLocation(); + } + + LayerChromium::drawTexturedQuad(layerRenderer()->context(), layerRenderer()->projectionMatrix(), drawTransform, + m_contentRect.width(), m_contentRect.height(), m_drawOpacity, + shaderMatrixLocation, shaderAlphaLocation); + + m_contentsTexture->unreserve(); + + if (maskLayer) + maskLayer->unreserveContentsTexture(); +} + +void RenderSurfaceChromium::draw() +{ + if (m_skipsDraw || !m_contentsTexture) + return; + // FIXME: By using the same RenderSurface for both the content and its reflection, + // it's currently not possible to apply a separate mask to the reflection layer + // or correctly handle opacity in reflections (opacity must be applied after drawing + // both the layer and its reflection). The solution is to introduce yet another RenderSurface + // to draw the layer and its reflection in. For now we only apply a separate reflection + // mask if the contents don't have a mask of their own. + LayerChromium* replicaMaskLayer = m_maskLayer; + if (!m_maskLayer && m_owningLayer->replicaLayer()) + replicaMaskLayer = m_owningLayer->replicaLayer()->maskLayer(); - layerRenderer()->useShader(sv->shaderProgram()); layerRenderer()->setScissorToRect(m_scissorRect); - LayerChromium::drawTexturedQuad(layerRenderer()->context(), layerRenderer()->projectionMatrix(), m_drawTransform, - m_contentRect.width(), m_contentRect.height(), m_drawOpacity, - sv->shaderMatrixLocation(), sv->shaderAlphaLocation()); + // Reflection draws before the layer. + if (m_owningLayer->replicaLayer()) + drawSurface(replicaMaskLayer, m_replicaDrawTransform); - m_contentsTexture->unreserve(); + drawSurface(m_maskLayer, m_drawTransform); } } diff --git a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h index 689a6eb..b1f6a5c 100644 --- a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h +++ b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h @@ -55,6 +55,11 @@ public: FloatPoint contentRectCenter() const { return FloatRect(m_contentRect).center(); } IntRect contentRect() const { return m_contentRect; } + // Returns the rect that encloses the RenderSurface including any reflection. + FloatRect drawableContentRect() const; + + TransformationMatrix drawTransform() const { return m_drawTransform; } + // Stores values that are shared between instances of this class that are // associated with the same LayerRendererChromium (and hence the same GL // context). @@ -64,30 +69,44 @@ public: ~SharedValues(); unsigned shaderProgram() const { return m_shaderProgram; } + unsigned maskShaderProgram() const { return m_maskShaderProgram; } int shaderSamplerLocation() const { return m_shaderSamplerLocation; } int shaderMatrixLocation() const { return m_shaderMatrixLocation; } int shaderAlphaLocation() const { return m_shaderAlphaLocation; } + int maskShaderSamplerLocation() const { return m_maskShaderSamplerLocation; } + int maskShaderMaskSamplerLocation() const { return m_maskShaderMaskSamplerLocation; } + int maskShaderMatrixLocation() const { return m_maskShaderMatrixLocation; } + int maskShaderAlphaLocation() const { return m_maskShaderAlphaLocation; } bool initialized() const { return m_initialized; } private: GraphicsContext3D* m_context; unsigned m_shaderProgram; + unsigned m_maskShaderProgram; int m_shaderSamplerLocation; int m_shaderMatrixLocation; int m_shaderAlphaLocation; + int m_maskShaderSamplerLocation; + int m_maskShaderMaskSamplerLocation; + int m_maskShaderMatrixLocation; + int m_maskShaderAlphaLocation; bool m_initialized; }; private: LayerRendererChromium* layerRenderer(); + void drawSurface(LayerChromium* maskLayer, const TransformationMatrix& drawTransform); LayerChromium* m_owningLayer; + LayerChromium* m_maskLayer; + IntRect m_contentRect; bool m_skipsDraw; OwnPtr<LayerTexture> m_contentsTexture; float m_drawOpacity; TransformationMatrix m_drawTransform; + TransformationMatrix m_replicaDrawTransform; TransformationMatrix m_originTransform; IntRect m_scissorRect; Vector<LayerChromium*> m_layerList; diff --git a/Source/WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp b/Source/WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp index c23c586..1450c5a 100644 --- a/Source/WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp +++ b/Source/WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp @@ -54,14 +54,9 @@ static inline float scaleEmToUnits(float x, int unitsPerEm) void SimpleFontData::platformInit() { if (!m_platformData.size()) { - m_ascent = 0; - m_descent = 0; - m_lineGap = 0; - m_lineSpacing = 0; + m_fontMetrics.reset(); m_avgCharWidth = 0; m_maxCharWidth = 0; - m_xHeight = 0; - m_unitsPerEm = 0; return; } @@ -82,10 +77,11 @@ void SimpleFontData::platformInit() m_avgCharWidth = textMetric.tmAveCharWidth; m_maxCharWidth = textMetric.tmMaxCharWidth; - m_ascent = textMetric.tmAscent; - m_descent = textMetric.tmDescent; - m_lineGap = textMetric.tmExternalLeading; - m_xHeight = m_ascent * 0.56f; // Best guess for xHeight for non-Truetype fonts. + // FIXME: Access ascent/descent/lineGap with floating point precision. + float ascent = textMetric.tmAscent; + float descent = textMetric.tmDescent; + float lineGap = textMetric.tmExternalLeading; + float xHeight = ascent * 0.56f; // Best guess for xHeight for non-Truetype fonts. OUTLINETEXTMETRIC outlineTextMetric; if (GetOutlineTextMetrics(dc, sizeof(outlineTextMetric), &outlineTextMetric) > 0) { @@ -94,10 +90,14 @@ void SimpleFontData::platformInit() MAT2 identityMatrix = {{0, 1}, {0, 0}, {0, 0}, {0, 1}}; DWORD len = GetGlyphOutlineW(dc, 'x', GGO_METRICS, &glyphMetrics, 0, 0, &identityMatrix); if (len != GDI_ERROR && glyphMetrics.gmBlackBoxY > 0) - m_xHeight = static_cast<float>(glyphMetrics.gmBlackBoxY); + xHeight = static_cast<float>(glyphMetrics.gmBlackBoxY); } - m_lineSpacing = m_ascent + m_descent + m_lineGap; + m_fontMetrics.setAscent(ascent); + m_fontMetrics.setDescent(descent); + m_fontMetrics.setLineGap(lineGap); + m_fontMetrics.setXHeight(xHeight); + m_fontMetrics.setLineSpacing(ascent + descent + lineGap); SelectObject(dc, oldFont); ReleaseDC(0, dc); diff --git a/Source/WebCore/platform/graphics/chromium/SimpleFontDataLinux.cpp b/Source/WebCore/platform/graphics/chromium/SimpleFontDataLinux.cpp index 355d837..9423d1e 100644 --- a/Source/WebCore/platform/graphics/chromium/SimpleFontDataLinux.cpp +++ b/Source/WebCore/platform/graphics/chromium/SimpleFontDataLinux.cpp @@ -55,14 +55,9 @@ static const size_t maxVDMXTableSize = 1024 * 1024; // 1 MB void SimpleFontData::platformInit() { if (!m_platformData.size()) { - m_ascent = 0; - m_descent = 0; - m_lineGap = 0; - m_lineSpacing = 0; + m_fontMetrics.reset(); m_avgCharWidth = 0; m_maxCharWidth = 0; - m_xHeight = 0; - m_unitsPerEm = 0; return; } @@ -88,26 +83,35 @@ void SimpleFontData::platformInit() fastFree(vdmxTable); } + float ascent; + float descent; + // Beware those who step here: This code is designed to match Win32 font // metrics *exactly*. if (isVDMXValid) { - m_ascent = vdmxAscent; - m_descent = -vdmxDescent; + ascent = vdmxAscent; + descent = -vdmxDescent; } else { SkScalar height = -metrics.fAscent + metrics.fDescent + metrics.fLeading; - m_ascent = SkScalarRound(-metrics.fAscent); - m_descent = SkScalarRound(height) - m_ascent; + ascent = SkScalarRound(-metrics.fAscent); + descent = SkScalarRound(height) - ascent; } + m_fontMetrics.setAscent(ascent); + m_fontMetrics.setDescent(descent); + + float xHeight; if (metrics.fXHeight) - m_xHeight = metrics.fXHeight; + xHeight = metrics.fXHeight; else { // hack taken from the Windows port - m_xHeight = static_cast<float>(m_ascent) * 0.56; + xHeight = ascent * 0.56f; } - m_lineGap = SkScalarRound(metrics.fLeading); - m_lineSpacing = m_ascent + m_descent + m_lineGap; + float lineGap = SkScalarToFloat(metrics.fLeading); + m_fontMetrics.setLineGap(lineGap); + m_fontMetrics.setXHeight(xHeight); + m_fontMetrics.setLineSpacing(lroundf(ascent) + lroundf(descent) + lroundf(lineGap)); if (m_orientation == Vertical) { static const uint32_t vheaTag = SkSetFourByteTag('v', 'h', 'e', 'a'); @@ -128,7 +132,7 @@ void SimpleFontData::platformInit() if (metrics.fAvgCharWidth) m_avgCharWidth = SkScalarRound(metrics.fAvgCharWidth); else { - m_avgCharWidth = m_xHeight; + m_avgCharWidth = xHeight; GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page(); diff --git a/Source/WebCore/platform/graphics/chromium/TransparencyWin.cpp b/Source/WebCore/platform/graphics/chromium/TransparencyWin.cpp index ba66eae..193271d 100644 --- a/Source/WebCore/platform/graphics/chromium/TransparencyWin.cpp +++ b/Source/WebCore/platform/graphics/chromium/TransparencyWin.cpp @@ -446,9 +446,9 @@ void TransparencyWin::compositeOpaqueComposite() identity.reset(); destCanvas->setMatrix(identity); - destRect.set(m_transformedSourceRect.x(), m_transformedSourceRect.y(), m_transformedSourceRect.right(), m_transformedSourceRect.bottom()); + destRect.set(m_transformedSourceRect.x(), m_transformedSourceRect.y(), m_transformedSourceRect.maxX(), m_transformedSourceRect.maxY()); } else - destRect.set(m_sourceRect.x(), m_sourceRect.y(), m_sourceRect.right(), m_sourceRect.bottom()); + destRect.set(m_sourceRect.x(), m_sourceRect.y(), m_sourceRect.maxX(), m_sourceRect.maxY()); SkPaint paint; paint.setFilterBitmap(true); @@ -487,7 +487,7 @@ void TransparencyWin::compositeTextComposite() SkMatrix identity; identity.reset(); destCanvas->setMatrix(identity); - SkRect destRect = { m_transformedSourceRect.x(), m_transformedSourceRect.y(), m_transformedSourceRect.right(), m_transformedSourceRect.bottom() }; + SkRect destRect = { m_transformedSourceRect.x(), m_transformedSourceRect.y(), m_transformedSourceRect.maxX(), m_transformedSourceRect.maxY() }; // Note that we need to specify the source layer subset, since the bitmap // may have been cached and it could be larger than what we're using. diff --git a/Source/WebCore/platform/graphics/chromium/UniscribeHelperTextRun.cpp b/Source/WebCore/platform/graphics/chromium/UniscribeHelperTextRun.cpp index aa18b4a..c060b43 100644 --- a/Source/WebCore/platform/graphics/chromium/UniscribeHelperTextRun.cpp +++ b/Source/WebCore/platform/graphics/chromium/UniscribeHelperTextRun.cpp @@ -51,14 +51,14 @@ UniscribeHelperTextRun::UniscribeHelperTextRun(const TextRun& run, setLetterSpacing(font.letterSpacing()); setSpaceWidth(font.spaceWidth()); setWordSpacing(font.wordSpacing()); - setAscent(font.primaryFont()->ascent()); + setAscent(font.fontMetrics().ascent()); init(); - // Padding is the amount to add to make justification happen. This + // Expansion is the amount to add to make justification happen. This // should be done after Init() so all the runs are already measured. - if (run.padding() > 0) - justify(run.padding()); + if (run.expansion() > 0) + justify(run.expansion()); } UniscribeHelperTextRun::UniscribeHelperTextRun( @@ -121,7 +121,7 @@ bool UniscribeHelperTextRun::nextWinFontData( m_hfonts.append(simpleFontData->platformData().hfont()); m_scriptCaches.append(simpleFontData->platformData().scriptCache()); m_fontProperties.append(simpleFontData->platformData().scriptFontProperties()); - m_ascents.append(simpleFontData->ascent()); + m_ascents.append(simpleFontData->fontMetrics().ascent()); } *hfont = m_hfonts[m_fontIndex - 1]; diff --git a/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp index 776b83f..41cd180 100644 --- a/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp @@ -60,6 +60,7 @@ VideoLayerChromium::SharedValues::SharedValues(GraphicsContext3D* context) , m_rgbaShaderMatrixLocation(0) , m_rgbaWidthScaleFactorLocation(0) , m_ccMatrixLocation(0) + , m_signAdjLocation(0) , m_yTextureLocation(0) , m_uTextureLocation(0) , m_vTextureLocation(0) @@ -96,14 +97,15 @@ VideoLayerChromium::SharedValues::SharedValues(GraphicsContext3D* context) "uniform sampler2D u_texture; \n" "uniform sampler2D v_texture; \n" "uniform float alpha; \n" + "uniform float adj; \n" "uniform mat3 cc_matrix; \n" "void main() \n" "{ \n" " float y = texture2D(y_texture, v_texCoord).x; \n" - " float u = texture2D(u_texture, v_texCoord).r - .5; \n" - " float v = texture2D(v_texture, v_texCoord).r - .5; \n" + " float u = texture2D(u_texture, v_texCoord).x - adj; \n" + " float v = texture2D(v_texture, v_texCoord).x - adj; \n" " vec3 rgb = cc_matrix * vec3(y, u, v); \n" - " gl_FragColor = vec4(rgb.x, rgb.y, rgb.z, 1.0) * alpha; \n" + " gl_FragColor = vec4(rgb, float(1)) * alpha; \n" "} \n"; char rgbaFragmentShaderString[] = @@ -113,7 +115,7 @@ VideoLayerChromium::SharedValues::SharedValues(GraphicsContext3D* context) "uniform float alpha; \n" "void main() \n" "{ \n" - " vec4 texColor = texture2D(rgba_texture, vec2(v_texCoord.x, 1.0 - v_texCoord.y)); \n" + " vec4 texColor = texture2D(rgba_texture, vec2(v_texCoord.x, float(1) - v_texCoord.y)); \n" " gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha; \n" "} \n"; @@ -135,6 +137,7 @@ VideoLayerChromium::SharedValues::SharedValues(GraphicsContext3D* context) m_uTextureLocation = m_context->getUniformLocation(m_yuvShaderProgram, "u_texture"); m_vTextureLocation = m_context->getUniformLocation(m_yuvShaderProgram, "v_texture"); m_ccMatrixLocation = m_context->getUniformLocation(m_yuvShaderProgram, "cc_matrix"); + m_signAdjLocation = m_context->getUniformLocation(m_yuvShaderProgram, "adj"); m_yuvAlphaLocation = m_context->getUniformLocation(m_yuvShaderProgram, "alpha"); ASSERT(m_yuvShaderMatrixLocation != -1); @@ -143,6 +146,7 @@ VideoLayerChromium::SharedValues::SharedValues(GraphicsContext3D* context) ASSERT(m_uTextureLocation != -1); ASSERT(m_vTextureLocation != -1); ASSERT(m_ccMatrixLocation != -1); + ASSERT(m_signAdjLocation != -1); ASSERT(m_yuvAlphaLocation != -1); m_rgbaShaderMatrixLocation = m_context->getUniformLocation(m_rgbaShaderProgram, "matrix"); @@ -375,6 +379,12 @@ void VideoLayerChromium::drawYUV(const SharedValues* sv) GLC(context, context->uniform1i(sv->uTextureLocation(), 2)); GLC(context, context->uniform1i(sv->vTextureLocation(), 3)); + // This value of 0.5 maps to 128. It is used in the YUV to RGB conversion + // formula to turn unsigned u and v values to signed u and v values. + // This is loaded as a uniform because certain drivers have problems + // reading literal float values. + GLC(context, context->uniform1f(sv->signAdjLocation(), 0.5)); + GLC(context, context->uniformMatrix3fv(sv->ccMatrixLocation(), 0, const_cast<float*>(yuv2RGB), 1)); drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(), diff --git a/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.h b/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.h index 0992ab7..ac3bca9 100644 --- a/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.h +++ b/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.h @@ -70,6 +70,7 @@ public: int rgbaAlphaLocation() const { return m_rgbaAlphaLocation; } int rgbaTextureLocation() const { return m_rgbaTextureLocation; } int ccMatrixLocation() const { return m_ccMatrixLocation; } + int signAdjLocation() const { return m_signAdjLocation; } bool initialized() const { return m_initialized; } private: GraphicsContext3D* m_context; @@ -80,6 +81,7 @@ public: int m_rgbaShaderMatrixLocation; int m_rgbaWidthScaleFactorLocation; int m_ccMatrixLocation; + int m_signAdjLocation; int m_yTextureLocation; int m_uTextureLocation; int m_vTextureLocation; |