summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/graphics
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/platform/graphics')
-rw-r--r--Source/WebCore/platform/graphics/ANGLEWebKitBridge.cpp8
-rw-r--r--Source/WebCore/platform/graphics/ContextShadow.h2
-rw-r--r--Source/WebCore/platform/graphics/Extensions3D.h5
-rw-r--r--Source/WebCore/platform/graphics/FloatQuad.h6
-rw-r--r--Source/WebCore/platform/graphics/FloatRect.cpp20
-rw-r--r--Source/WebCore/platform/graphics/FloatRect.h10
-rw-r--r--Source/WebCore/platform/graphics/Font.cpp74
-rw-r--r--Source/WebCore/platform/graphics/Font.h25
-rw-r--r--Source/WebCore/platform/graphics/FontCache.cpp11
-rw-r--r--Source/WebCore/platform/graphics/FontDescription.h9
-rw-r--r--Source/WebCore/platform/graphics/FontFastPath.cpp13
-rw-r--r--Source/WebCore/platform/graphics/FontMetrics.h122
-rw-r--r--Source/WebCore/platform/graphics/FontWidthVariant.h35
-rw-r--r--Source/WebCore/platform/graphics/GlyphBuffer.h17
-rw-r--r--Source/WebCore/platform/graphics/GlyphPageTreeNode.cpp2
-rw-r--r--Source/WebCore/platform/graphics/GraphicsContext.cpp52
-rw-r--r--Source/WebCore/platform/graphics/GraphicsContext.h23
-rw-r--r--Source/WebCore/platform/graphics/GraphicsContext3D.cpp4
-rw-r--r--Source/WebCore/platform/graphics/GraphicsContext3D.h16
-rw-r--r--Source/WebCore/platform/graphics/Icon.h7
-rw-r--r--Source/WebCore/platform/graphics/IntRect.cpp16
-rw-r--r--Source/WebCore/platform/graphics/IntRect.h26
-rw-r--r--Source/WebCore/platform/graphics/IntRectHash.h59
-rw-r--r--Source/WebCore/platform/graphics/IntSizeHash.h16
-rw-r--r--Source/WebCore/platform/graphics/MediaPlayer.cpp20
-rw-r--r--Source/WebCore/platform/graphics/MediaPlayer.h5
-rw-r--r--Source/WebCore/platform/graphics/MediaPlayerPrivate.h4
-rw-r--r--Source/WebCore/platform/graphics/ShadowBlur.cpp733
-rw-r--r--Source/WebCore/platform/graphics/ShadowBlur.h105
-rw-r--r--Source/WebCore/platform/graphics/SimpleFontData.cpp38
-rw-r--r--Source/WebCore/platform/graphics/SimpleFontData.h16
-rw-r--r--Source/WebCore/platform/graphics/StringTruncator.cpp2
-rw-r--r--Source/WebCore/platform/graphics/TextRun.h23
-rw-r--r--Source/WebCore/platform/graphics/TiledBackingStore.cpp20
-rw-r--r--Source/WebCore/platform/graphics/WidthIterator.cpp74
-rw-r--r--Source/WebCore/platform/graphics/WidthIterator.h7
-rw-r--r--Source/WebCore/platform/graphics/android/FontAndroid.cpp7
-rw-r--r--Source/WebCore/platform/graphics/android/FontCustomPlatformData.cpp2
-rw-r--r--Source/WebCore/platform/graphics/android/FontCustomPlatformData.h3
-rw-r--r--Source/WebCore/platform/graphics/android/FontDataAndroid.cpp26
-rw-r--r--Source/WebCore/platform/graphics/android/GLWebViewState.cpp2
-rw-r--r--Source/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp60
-rw-r--r--Source/WebCore/platform/graphics/android/ImageBufferAndroid.cpp6
-rw-r--r--Source/WebCore/platform/graphics/android/LayerAndroid.cpp4
-rw-r--r--Source/WebCore/platform/graphics/android/PathAndroid.cpp31
-rw-r--r--Source/WebCore/platform/graphics/android/PlatformGraphicsContext.h2
-rw-r--r--Source/WebCore/platform/graphics/android/ShaderProgram.cpp40
-rw-r--r--Source/WebCore/platform/graphics/android/TiledPage.cpp6
-rw-r--r--Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp4
-rw-r--r--Source/WebCore/platform/graphics/ca/PlatformCAAnimation.h8
-rw-r--r--Source/WebCore/platform/graphics/ca/mac/PlatformCAAnimationMac.mm55
-rw-r--r--Source/WebCore/platform/graphics/ca/win/CACFLayerTreeHost.cpp401
-rw-r--r--Source/WebCore/platform/graphics/ca/win/CACFLayerTreeHost.h58
-rw-r--r--Source/WebCore/platform/graphics/ca/win/CACFLayerTreeHostClient.h43
-rw-r--r--Source/WebCore/platform/graphics/ca/win/LegacyCACFLayerTreeHost.cpp401
-rw-r--r--Source/WebCore/platform/graphics/ca/win/LegacyCACFLayerTreeHost.h82
-rw-r--r--Source/WebCore/platform/graphics/ca/win/PlatformCAAnimationWin.cpp51
-rw-r--r--Source/WebCore/platform/graphics/ca/win/WKCACFViewLayerTreeHost.cpp160
-rw-r--r--Source/WebCore/platform/graphics/ca/win/WKCACFViewLayerTreeHost.h65
-rw-r--r--Source/WebCore/platform/graphics/cairo/CairoUtilities.cpp4
-rw-r--r--Source/WebCore/platform/graphics/cairo/FontCustomPlatformData.h3
-rw-r--r--Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp12
-rw-r--r--Source/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp41
-rw-r--r--Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp123
-rw-r--r--Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp14
-rw-r--r--Source/WebCore/platform/graphics/cg/ImageCG.cpp4
-rw-r--r--Source/WebCore/platform/graphics/chromium/ComplexTextControllerLinux.cpp38
-rw-r--r--Source/WebCore/platform/graphics/chromium/ComplexTextControllerLinux.h4
-rw-r--r--Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp17
-rw-r--r--Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h3
-rw-r--r--Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp15
-rw-r--r--Source/WebCore/platform/graphics/chromium/Extensions3DChromium.h4
-rw-r--r--Source/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp37
-rw-r--r--Source/WebCore/platform/graphics/chromium/FontChromiumWin.cpp29
-rw-r--r--Source/WebCore/platform/graphics/chromium/FontLinux.cpp19
-rw-r--r--Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp16
-rw-r--r--Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.h5
-rw-r--r--Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp24
-rw-r--r--Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp21
-rw-r--r--Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h3
-rw-r--r--Source/WebCore/platform/graphics/chromium/HarfbuzzSkia.cpp4
-rw-r--r--Source/WebCore/platform/graphics/chromium/IconChromium.cpp (renamed from Source/WebCore/platform/graphics/chromium/IconChromiumLinux.cpp)20
-rw-r--r--Source/WebCore/platform/graphics/chromium/IconChromiumMac.cpp50
-rw-r--r--Source/WebCore/platform/graphics/chromium/IconChromiumWin.cpp65
-rw-r--r--Source/WebCore/platform/graphics/chromium/LayerChromium.cpp9
-rw-r--r--Source/WebCore/platform/graphics/chromium/LayerChromium.h13
-rw-r--r--Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp83
-rw-r--r--Source/WebCore/platform/graphics/chromium/LayerTexture.cpp1
-rw-r--r--Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp37
-rw-r--r--Source/WebCore/platform/graphics/chromium/PlatformIcon.h6
-rw-r--r--Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp126
-rw-r--r--Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h19
-rw-r--r--Source/WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp24
-rw-r--r--Source/WebCore/platform/graphics/chromium/SimpleFontDataLinux.cpp34
-rw-r--r--Source/WebCore/platform/graphics/chromium/TransparencyWin.cpp6
-rw-r--r--Source/WebCore/platform/graphics/chromium/UniscribeHelperTextRun.cpp10
-rw-r--r--Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp18
-rw-r--r--Source/WebCore/platform/graphics/chromium/VideoLayerChromium.h2
-rw-r--r--Source/WebCore/platform/graphics/cocoa/FontPlatformData.h16
-rw-r--r--Source/WebCore/platform/graphics/cocoa/FontPlatformDataCocoa.mm52
-rw-r--r--Source/WebCore/platform/graphics/efl/FontEfl.cpp5
-rw-r--r--Source/WebCore/platform/graphics/filters/DistantLightSource.cpp80
-rw-r--r--Source/WebCore/platform/graphics/filters/DistantLightSource.h2
-rw-r--r--Source/WebCore/platform/graphics/filters/FEDiffuseLighting.cpp25
-rw-r--r--Source/WebCore/platform/graphics/filters/FEDiffuseLighting.h10
-rw-r--r--Source/WebCore/platform/graphics/filters/FilterEffect.cpp16
-rw-r--r--Source/WebCore/platform/graphics/filters/FilterEffect.h1
-rw-r--r--Source/WebCore/platform/graphics/filters/LightSource.cpp149
-rw-r--r--Source/WebCore/platform/graphics/filters/LightSource.h11
-rw-r--r--Source/WebCore/platform/graphics/filters/PointLightSource.cpp91
-rw-r--r--Source/WebCore/platform/graphics/filters/PointLightSource.h3
-rw-r--r--Source/WebCore/platform/graphics/filters/SpotLightSource.cpp198
-rw-r--r--Source/WebCore/platform/graphics/filters/SpotLightSource.h8
-rw-r--r--Source/WebCore/platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp2
-rw-r--r--Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp21
-rw-r--r--Source/WebCore/platform/graphics/gpu/DrawingBuffer.cpp16
-rw-r--r--Source/WebCore/platform/graphics/gpu/LoopBlinnPathCache.cpp86
-rw-r--r--Source/WebCore/platform/graphics/gpu/LoopBlinnPathCache.h123
-rw-r--r--Source/WebCore/platform/graphics/gpu/LoopBlinnPathProcessor.cpp1228
-rw-r--r--Source/WebCore/platform/graphics/gpu/LoopBlinnPathProcessor.h126
-rw-r--r--Source/WebCore/platform/graphics/gpu/LoopBlinnShader.cpp59
-rw-r--r--Source/WebCore/platform/graphics/gpu/LoopBlinnShader.h58
-rw-r--r--Source/WebCore/platform/graphics/gpu/LoopBlinnSolidFillShader.cpp62
-rw-r--r--Source/WebCore/platform/graphics/gpu/LoopBlinnSolidFillShader.h52
-rw-r--r--Source/WebCore/platform/graphics/gpu/Shader.cpp169
-rw-r--r--Source/WebCore/platform/graphics/gpu/Shader.h27
-rw-r--r--Source/WebCore/platform/graphics/gpu/SolidFillShader.cpp20
-rw-r--r--Source/WebCore/platform/graphics/gpu/TexShader.cpp25
-rw-r--r--Source/WebCore/platform/graphics/gpu/Texture.cpp2
-rw-r--r--Source/WebCore/platform/graphics/gpu/TilingData.cpp8
-rw-r--r--Source/WebCore/platform/graphics/gpu/mac/DrawingBufferMac.mm2
-rw-r--r--Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp17
-rw-r--r--Source/WebCore/platform/graphics/gtk/FontGtk.cpp5
-rw-r--r--Source/WebCore/platform/graphics/haiku/FontCustomPlatformData.cpp2
-rw-r--r--Source/WebCore/platform/graphics/haiku/FontCustomPlatformData.h3
-rw-r--r--Source/WebCore/platform/graphics/haiku/FontHaiku.cpp5
-rw-r--r--Source/WebCore/platform/graphics/haiku/SimpleFontDataHaiku.cpp10
-rw-r--r--Source/WebCore/platform/graphics/mac/ComplexTextController.cpp82
-rw-r--r--Source/WebCore/platform/graphics/mac/ComplexTextController.h15
-rw-r--r--Source/WebCore/platform/graphics/mac/ComplexTextControllerATSUI.cpp3
-rw-r--r--Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.cpp6
-rw-r--r--Source/WebCore/platform/graphics/mac/FontCacheMac.mm2
-rw-r--r--Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp4
-rw-r--r--Source/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp4
-rw-r--r--Source/WebCore/platform/graphics/mac/FontCustomPlatformData.h3
-rw-r--r--Source/WebCore/platform/graphics/mac/FontMac.mm9
-rw-r--r--Source/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp4
-rw-r--r--Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm8
-rw-r--r--Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm2
-rw-r--r--Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm63
-rw-r--r--Source/WebCore/platform/graphics/mac/WebGLLayer.mm4
-rw-r--r--Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp8
-rw-r--r--Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp28
-rw-r--r--Source/WebCore/platform/graphics/opengl/TextureMapperGL.cpp4
-rw-r--r--Source/WebCore/platform/graphics/pango/FontCustomPlatformDataPango.cpp2
-rw-r--r--Source/WebCore/platform/graphics/pango/SimpleFontDataPango.cpp22
-rw-r--r--Source/WebCore/platform/graphics/qt/ContextShadowQt.cpp5
-rw-r--r--Source/WebCore/platform/graphics/qt/Extensions3DQt.cpp4
-rw-r--r--Source/WebCore/platform/graphics/qt/FontCustomPlatformData.h3
-rw-r--r--Source/WebCore/platform/graphics/qt/FontCustomPlatformDataQt.cpp2
-rw-r--r--Source/WebCore/platform/graphics/qt/FontQt.cpp37
-rw-r--r--Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp30
-rw-r--r--Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp30
-rw-r--r--Source/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp16
-rw-r--r--Source/WebCore/platform/graphics/qt/GraphicsLayerQt.h4
-rw-r--r--Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp14
-rw-r--r--Source/WebCore/platform/graphics/qt/ImageDecoderQt.cpp2
-rw-r--r--Source/WebCore/platform/graphics/qt/ImageQt.cpp23
-rw-r--r--Source/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp2
-rw-r--r--Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp19
-rw-r--r--Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h2
-rw-r--r--Source/WebCore/platform/graphics/qt/PathQt.cpp21
-rw-r--r--Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp22
-rw-r--r--Source/WebCore/platform/graphics/qt/TransparencyLayer.h3
-rw-r--r--Source/WebCore/platform/graphics/skia/FloatRectSkia.cpp2
-rw-r--r--Source/WebCore/platform/graphics/skia/FontCustomPlatformData.cpp13
-rw-r--r--Source/WebCore/platform/graphics/skia/FontCustomPlatformData.h3
-rw-r--r--Source/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp4
-rw-r--r--Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp32
-rw-r--r--Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp121
-rw-r--r--Source/WebCore/platform/graphics/skia/IntRectSkia.cpp4
-rw-r--r--Source/WebCore/platform/graphics/skia/PathSkia.cpp20
-rw-r--r--Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp79
-rw-r--r--Source/WebCore/platform/graphics/skia/PlatformContextSkia.h8
-rw-r--r--Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h4
-rw-r--r--Source/WebCore/platform/graphics/texmap/TextureMapperNode.cpp12
-rw-r--r--Source/WebCore/platform/graphics/transforms/AffineTransform.cpp14
-rw-r--r--Source/WebCore/platform/graphics/transforms/AffineTransform.h6
-rw-r--r--Source/WebCore/platform/graphics/transforms/Matrix3DTransformOperation.h2
-rw-r--r--Source/WebCore/platform/graphics/transforms/MatrixTransformOperation.h2
-rw-r--r--Source/WebCore/platform/graphics/transforms/PerspectiveTransformOperation.cpp25
-rw-r--r--Source/WebCore/platform/graphics/transforms/PerspectiveTransformOperation.h14
-rw-r--r--Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp48
-rw-r--r--Source/WebCore/platform/graphics/transforms/TransformationMatrix.h18
-rw-r--r--Source/WebCore/platform/graphics/win/FontCGWin.cpp10
-rw-r--r--Source/WebCore/platform/graphics/win/FontCustomPlatformData.cpp13
-rw-r--r--Source/WebCore/platform/graphics/win/FontCustomPlatformData.h3
-rw-r--r--Source/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.cpp2
-rw-r--r--Source/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.h2
-rw-r--r--Source/WebCore/platform/graphics/win/FontWin.cpp9
-rw-r--r--Source/WebCore/platform/graphics/win/GraphicsContextWin.cpp2
-rw-r--r--Source/WebCore/platform/graphics/win/IconWin.cpp11
-rw-r--r--Source/WebCore/platform/graphics/win/IntRectWin.cpp2
-rw-r--r--Source/WebCore/platform/graphics/win/MediaPlayerPrivateFullscreenWindow.cpp21
-rw-r--r--Source/WebCore/platform/graphics/win/MediaPlayerPrivateFullscreenWindow.h13
-rw-r--r--Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp2
-rw-r--r--Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp2
-rw-r--r--Source/WebCore/platform/graphics/win/QTMovie.cpp108
-rw-r--r--Source/WebCore/platform/graphics/win/QTMovieGWorld.cpp8
-rw-r--r--Source/WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp41
-rw-r--r--Source/WebCore/platform/graphics/win/SimpleFontDataCairoWin.cpp21
-rw-r--r--Source/WebCore/platform/graphics/win/SimpleFontDataWin.cpp32
-rw-r--r--Source/WebCore/platform/graphics/win/UniscribeController.cpp6
-rw-r--r--Source/WebCore/platform/graphics/win/WKCAImageQueue.cpp4
-rw-r--r--Source/WebCore/platform/graphics/wince/FontCustomPlatformData.cpp12
-rw-r--r--Source/WebCore/platform/graphics/wince/FontCustomPlatformData.h3
-rw-r--r--Source/WebCore/platform/graphics/wince/FontWinCE.cpp8
-rw-r--r--Source/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp41
-rw-r--r--Source/WebCore/platform/graphics/wince/PlatformPathWinCE.cpp10
-rw-r--r--Source/WebCore/platform/graphics/wince/SharedBitmap.cpp10
-rw-r--r--Source/WebCore/platform/graphics/wince/SimpleFontDataWinCE.cpp17
-rw-r--r--Source/WebCore/platform/graphics/wx/FontCustomPlatformData.cpp2
-rw-r--r--Source/WebCore/platform/graphics/wx/FontCustomPlatformData.h4
-rw-r--r--Source/WebCore/platform/graphics/wx/FontPlatformData.h4
-rw-r--r--Source/WebCore/platform/graphics/wx/FontPlatformDataWx.cpp2
-rw-r--r--Source/WebCore/platform/graphics/wx/FontWx.cpp10
-rw-r--r--Source/WebCore/platform/graphics/wx/GraphicsContextWx.cpp4
-rw-r--r--Source/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp12
228 files changed, 6325 insertions, 1969 deletions
diff --git a/Source/WebCore/platform/graphics/ANGLEWebKitBridge.cpp b/Source/WebCore/platform/graphics/ANGLEWebKitBridge.cpp
index f416b47..9e64904 100644
--- a/Source/WebCore/platform/graphics/ANGLEWebKitBridge.cpp
+++ b/Source/WebCore/platform/graphics/ANGLEWebKitBridge.cpp
@@ -25,7 +25,7 @@
#include "config.h"
-#if ENABLE(3D_CANVAS)
+#if ENABLE(WEBGL)
#include "ANGLEWebKitBridge.h"
#include <wtf/OwnArrayPtr.h>
@@ -93,7 +93,7 @@ bool ANGLEWebKitBridge::validateShaderSource(const char* shaderSource, ANGLEShad
int logSize = 0;
ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &logSize);
if (logSize > 1) {
- OwnArrayPtr<char> logBuffer(new char[logSize]);
+ OwnArrayPtr<char> logBuffer = adoptArrayPtr(new char[logSize]);
if (logBuffer) {
ShGetInfoLog(compiler, logBuffer.get());
shaderValidationLog = logBuffer.get();
@@ -105,7 +105,7 @@ bool ANGLEWebKitBridge::validateShaderSource(const char* shaderSource, ANGLEShad
int translationLength = 0;
ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &translationLength);
if (translationLength > 1) {
- OwnArrayPtr<char> translationBuffer(new char[translationLength]);
+ OwnArrayPtr<char> translationBuffer = adoptArrayPtr(new char[translationLength]);
if (!translationBuffer)
return false;
ShGetObjectCode(compiler, translationBuffer.get());
@@ -117,4 +117,4 @@ bool ANGLEWebKitBridge::validateShaderSource(const char* shaderSource, ANGLEShad
}
-#endif // ENABLE(3D_CANVAS)
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/platform/graphics/ContextShadow.h b/Source/WebCore/platform/graphics/ContextShadow.h
index a1fba5c..c0571f0 100644
--- a/Source/WebCore/platform/graphics/ContextShadow.h
+++ b/Source/WebCore/platform/graphics/ContextShadow.h
@@ -68,6 +68,8 @@ typedef void* PlatformContext;
// This class should be copyable since GraphicsContextQt keeps a stack of
// the shadow state for savePlatformState and restorePlatformState.
+// This class is Deprecated. Platforms should migrate to ShadowBlur.
+
class ContextShadow {
public:
enum {
diff --git a/Source/WebCore/platform/graphics/Extensions3D.h b/Source/WebCore/platform/graphics/Extensions3D.h
index 1a2b7a1..6d6efe5 100644
--- a/Source/WebCore/platform/graphics/Extensions3D.h
+++ b/Source/WebCore/platform/graphics/Extensions3D.h
@@ -52,6 +52,7 @@ public:
// GL_ANGLE_framebuffer_blit / GL_ANGLE_framebuffer_multisample
// GL_OES_texture_float
// GL_OES_standard_derivatives
+ // GL_OES_rgb8_rgba8
// Takes full name of extension; for example,
// "GL_EXT_texture_format_BGRA8888".
@@ -87,6 +88,10 @@ public:
// GL_OES_standard_derivatives names
FRAGMENT_SHADER_DERIVATIVE_HINT_OES = 0x8B8B,
+
+ // GL_OES_rgb8_rgba8 names
+ RGB8_OES = 0x8051,
+ RGBA8_OES = 0x8058,
};
// GL_ARB_robustness
diff --git a/Source/WebCore/platform/graphics/FloatQuad.h b/Source/WebCore/platform/graphics/FloatQuad.h
index 6cd86f6..e913723 100644
--- a/Source/WebCore/platform/graphics/FloatQuad.h
+++ b/Source/WebCore/platform/graphics/FloatQuad.h
@@ -54,9 +54,9 @@ public:
FloatQuad(const FloatRect& inRect)
: m_p1(inRect.location())
- , m_p2(inRect.right(), inRect.y())
- , m_p3(inRect.right(), inRect.bottom())
- , m_p4(inRect.x(), inRect.bottom())
+ , m_p2(inRect.maxX(), inRect.y())
+ , m_p3(inRect.maxX(), inRect.maxY())
+ , m_p4(inRect.x(), inRect.maxY())
{
}
diff --git a/Source/WebCore/platform/graphics/FloatRect.cpp b/Source/WebCore/platform/graphics/FloatRect.cpp
index 0d8a24e..36f3d3a 100644
--- a/Source/WebCore/platform/graphics/FloatRect.cpp
+++ b/Source/WebCore/platform/graphics/FloatRect.cpp
@@ -51,22 +51,22 @@ bool FloatRect::intersects(const FloatRect& other) const
{
// Checking emptiness handles negative widths as well as zero.
return !isEmpty() && !other.isEmpty()
- && x() < other.right() && other.x() < right()
- && y() < other.bottom() && other.y() < bottom();
+ && x() < other.maxX() && other.x() < maxX()
+ && y() < other.maxY() && other.y() < maxY();
}
bool FloatRect::contains(const FloatRect& other) const
{
- return x() <= other.x() && right() >= other.right()
- && y() <= other.y() && bottom() >= other.bottom();
+ return x() <= other.x() && maxX() >= other.maxX()
+ && y() <= other.y() && maxY() >= other.maxY();
}
void FloatRect::intersect(const FloatRect& other)
{
float l = max(x(), other.x());
float t = max(y(), other.y());
- float r = min(right(), other.right());
- float b = min(bottom(), other.bottom());
+ float r = min(maxX(), other.maxX());
+ float b = min(maxY(), other.maxY());
// Return a clean empty rectangle for non-intersecting cases.
if (l >= r || t >= b) {
@@ -91,8 +91,8 @@ void FloatRect::unite(const FloatRect& other)
float l = min(x(), other.x());
float t = min(y(), other.y());
- float r = max(right(), other.right());
- float b = max(bottom(), other.bottom());
+ float r = max(maxX(), other.maxX());
+ float b = max(maxY(), other.maxY());
setLocationAndSizeFromEdges(l, t, r, b);
}
@@ -180,8 +180,8 @@ IntRect enclosingIntRect(const FloatRect& rect)
{
float left = floorf(rect.x());
float top = floorf(rect.y());
- float width = ceilf(rect.right()) - left;
- float height = ceilf(rect.bottom()) - top;
+ float width = ceilf(rect.maxX()) - left;
+ float height = ceilf(rect.maxY()) - top;
return IntRect(safeFloatToInt(left), safeFloatToInt(top),
safeFloatToInt(width), safeFloatToInt(height));
}
diff --git a/Source/WebCore/platform/graphics/FloatRect.h b/Source/WebCore/platform/graphics/FloatRect.h
index 10ad838..733f7cc 100644
--- a/Source/WebCore/platform/graphics/FloatRect.h
+++ b/Source/WebCore/platform/graphics/FloatRect.h
@@ -90,6 +90,8 @@ public:
float x() const { return m_location.x(); }
float y() const { return m_location.y(); }
+ float maxX() const { return x() + width(); }
+ float maxY() const { return y() + height(); }
float width() const { return m_size.width(); }
float height() const { return m_size.height(); }
@@ -100,11 +102,6 @@ public:
bool isEmpty() const { return m_size.isEmpty(); }
- float left() const { return x(); }
- float right() const { return x() + width(); }
- float top() const { return y(); }
- float bottom() const { return y() + height(); }
-
FloatPoint center() const { return FloatPoint(x() + width() / 2, y() + height() / 2); }
void move(const FloatSize& delta) { m_location += delta; }
@@ -119,10 +116,9 @@ public:
// Note, this doesn't match what IntRect::contains(IntPoint&) does; the int version
// is really checking for containment of 1x1 rect, but that doesn't make sense with floats.
bool contains(float px, float py) const
- { return px >= x() && px <= right() && py >= y() && py <= bottom(); }
+ { return px >= x() && px <= maxX() && py >= y() && py <= maxY(); }
bool contains(const FloatPoint& point) const { return contains(point.x(), point.y()); }
-
void inflateX(float dx) {
m_location.setX(m_location.x() - dx);
m_size.setWidth(m_size.width() + dx + dx);
diff --git a/Source/WebCore/platform/graphics/Font.cpp b/Source/WebCore/platform/graphics/Font.cpp
index 394de35..6bdddfc 100644
--- a/Source/WebCore/platform/graphics/Font.cpp
+++ b/Source/WebCore/platform/graphics/Font.cpp
@@ -2,7 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2000 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2003, 2006, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2006, 2010, 2011 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -247,21 +247,15 @@ bool Font::isSVGFont() const
}
#endif
-String Font::normalizeSpaces(const String& string)
+String Font::normalizeSpaces(const UChar* characters, unsigned length)
{
- const UChar* characters = string.characters();
- unsigned length = string.length();
- Vector<UChar, 256> buffer(length);
- bool didReplacement = false;
-
- for (unsigned i = 0; i < length; ++i) {
- UChar originalCharacter = characters[i];
- buffer[i] = normalizeSpaces(originalCharacter);
- if (buffer[i] != originalCharacter)
- didReplacement = true;
- }
+ UChar* buffer;
+ String normalized = String::createUninitialized(length, buffer);
+
+ for (unsigned i = 0; i < length; ++i)
+ buffer[i] = normalizeSpaces(characters[i]);
- return didReplacement ? String(buffer.data(), length) : string;
+ return normalized;
}
static bool shouldUseFontSmoothing = true;
@@ -293,7 +287,7 @@ Font::CodePath Font::codePath(const TextRun& run) const
return s_codePath;
#if PLATFORM(QT)
- if (run.padding() || run.rtl() || isSmallCaps() || wordSpacing() || letterSpacing())
+ if (run.expansion() || run.rtl() || isSmallCaps() || wordSpacing() || letterSpacing())
return Complex;
#endif
@@ -458,6 +452,56 @@ bool Font::isCJKIdeographOrSymbol(UChar32 c)
return isCJKIdeograph(c);
}
+unsigned Font::expansionOpportunityCount(const UChar* characters, size_t length, TextDirection direction, bool& isAfterExpansion)
+{
+ static bool expandAroundIdeographs = canExpandAroundIdeographsInComplexText();
+ unsigned count = 0;
+ if (direction == LTR) {
+ for (size_t i = 0; i < length; ++i) {
+ UChar32 character = characters[i];
+ if (treatAsSpace(character)) {
+ count++;
+ isAfterExpansion = true;
+ continue;
+ }
+ if (U16_IS_LEAD(character) && i + 1 < length && U16_IS_TRAIL(characters[i + 1])) {
+ character = U16_GET_SUPPLEMENTARY(character, characters[i + 1]);
+ i++;
+ }
+ if (expandAroundIdeographs && isCJKIdeographOrSymbol(character)) {
+ if (!isAfterExpansion)
+ count++;
+ count++;
+ isAfterExpansion = true;
+ continue;
+ }
+ isAfterExpansion = false;
+ }
+ } else {
+ for (size_t i = length; i > 0; --i) {
+ UChar32 character = characters[i - 1];
+ if (treatAsSpace(character)) {
+ count++;
+ isAfterExpansion = true;
+ continue;
+ }
+ if (U16_IS_TRAIL(character) && i > 1 && U16_IS_LEAD(characters[i - 2])) {
+ character = U16_GET_SUPPLEMENTARY(characters[i - 2], character);
+ i--;
+ }
+ if (expandAroundIdeographs && isCJKIdeographOrSymbol(character)) {
+ if (!isAfterExpansion)
+ count++;
+ count++;
+ isAfterExpansion = true;
+ continue;
+ }
+ isAfterExpansion = false;
+ }
+ }
+ return count;
+}
+
bool Font::canReceiveTextEmphasis(UChar32 c)
{
CharCategory category = Unicode::category(c);
diff --git a/Source/WebCore/platform/graphics/Font.h b/Source/WebCore/platform/graphics/Font.h
index 2957c0a..258240b 100644
--- a/Source/WebCore/platform/graphics/Font.h
+++ b/Source/WebCore/platform/graphics/Font.h
@@ -2,7 +2,7 @@
* Copyright (C) 2000 Lars Knoll (knoll@kde.org)
* (C) 2000 Antti Koivisto (koivisto@kde.org)
* (C) 2000 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2003, 2006, 2007, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2006, 2007, 2010, 2011 Apple Inc. All rights reserved.
* Copyright (C) 2008 Holger Hans Peter Freyther
*
* This library is free software; you can redistribute it and/or
@@ -25,14 +25,15 @@
#ifndef Font_h
#define Font_h
-#include "CharacterNames.h"
#include "FontDescription.h"
#include "FontFallbackList.h"
#include "SimpleFontData.h"
+#include "TextDirection.h"
#include "TypesettingFeatures.h"
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
#include <wtf/MathExtras.h>
+#include <wtf/unicode/CharacterNames.h>
#if PLATFORM(QT)
#include <QFont>
@@ -43,7 +44,7 @@ namespace WebCore {
class FloatPoint;
class FloatRect;
class FontData;
-class FontFallbackList;
+class FontMetrics;
class FontPlatformData;
class FontSelector;
class GlyphBuffer;
@@ -54,8 +55,6 @@ class TextRun;
struct GlyphData;
-const unsigned defaultUnitsPerEm = 1000;
-
struct GlyphOverflow {
GlyphOverflow()
: left(0)
@@ -124,17 +123,12 @@ public:
bool italic() const { return m_fontDescription.italic(); }
FontWeight weight() const { return m_fontDescription.weight(); }
+ FontWidthVariant widthVariant() const { return m_fontDescription.widthVariant(); }
bool isPlatformFont() const { return m_isPlatformFont; }
// Metrics that we query the FontFallbackList for.
- int ascent(FontBaseline baselineType = AlphabeticBaseline) const { return primaryFont()->ascent(baselineType); }
- int descent(FontBaseline baselineType = AlphabeticBaseline) const { return primaryFont()->descent(baselineType); }
- int height() const { return ascent() + descent(); }
- int lineSpacing() const { return primaryFont()->lineSpacing(); }
- int lineGap() const { return primaryFont()->lineGap(); }
- float xHeight() const { return primaryFont()->xHeight(); }
- unsigned unitsPerEm() const { return primaryFont()->unitsPerEm(); }
+ const FontMetrics& fontMetrics() const { return primaryFont()->fontMetrics(); }
int spaceWidth() const { return (int)ceilf(primaryFont()->adjustedSpaceWidth() + m_letterSpacing); }
float tabWidth(const SimpleFontData& fontData) const { return 8 * ceilf(fontData.adjustedSpaceWidth() + letterSpacing()); }
int emphasisMarkAscent(const AtomicString&) const;
@@ -150,7 +144,9 @@ public:
static bool isCJKIdeograph(UChar32);
static bool isCJKIdeographOrSymbol(UChar32);
-
+
+ static unsigned expansionOpportunityCount(const UChar*, size_t length, TextDirection, bool& isAfterExpansion);
+
#if PLATFORM(QT)
QFont font() const;
#endif
@@ -185,6 +181,7 @@ private:
bool getEmphasisMarkGlyphData(const AtomicString&, GlyphData&) const;
static bool canReturnFallbackFontsForComplexText();
+ static bool canExpandAroundIdeographsInComplexText();
CodePath codePath(const TextRun&) const;
@@ -226,7 +223,7 @@ public:
return character;
}
- static String normalizeSpaces(const String&);
+ static String normalizeSpaces(const UChar*, unsigned length);
#if ENABLE(SVG_FONTS)
bool isSVGFont() const;
diff --git a/Source/WebCore/platform/graphics/FontCache.cpp b/Source/WebCore/platform/graphics/FontCache.cpp
index cfca980..ca82ebd 100644
--- a/Source/WebCore/platform/graphics/FontCache.cpp
+++ b/Source/WebCore/platform/graphics/FontCache.cpp
@@ -57,7 +57,7 @@ struct FontPlatformDataCacheKey {
WTF_MAKE_FAST_ALLOCATED;
public:
FontPlatformDataCacheKey(const AtomicString& family = AtomicString(), unsigned size = 0, unsigned weight = 0, bool italic = false,
- bool isPrinterFont = false, FontRenderingMode renderingMode = NormalRenderingMode, FontOrientation orientation = Horizontal)
+ bool isPrinterFont = false, FontRenderingMode renderingMode = NormalRenderingMode, FontOrientation orientation = Horizontal, FontWidthVariant widthVariant = RegularWidth)
: m_size(size)
, m_weight(weight)
, m_family(family)
@@ -65,6 +65,7 @@ public:
, m_printerFont(isPrinterFont)
, m_renderingMode(renderingMode)
, m_orientation(orientation)
+ , m_widthVariant(widthVariant)
{
}
@@ -75,7 +76,7 @@ public:
{
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_orientation == other.m_orientation;
+ m_renderingMode == other.m_renderingMode && m_orientation == other.m_orientation && m_widthVariant == other.m_widthVariant;
}
unsigned m_size;
@@ -85,6 +86,7 @@ public:
bool m_printerFont;
FontRenderingMode m_renderingMode;
FontOrientation m_orientation;
+ FontWidthVariant m_widthVariant;
private:
static unsigned hashTableDeletedSize() { return 0xFFFFFFFFU; }
@@ -92,10 +94,11 @@ private:
inline unsigned computeHash(const FontPlatformDataCacheKey& fontKey)
{
- unsigned hashCodes[4] = {
+ unsigned hashCodes[5] = {
CaseFoldingHash::hash(fontKey.m_family),
fontKey.m_size,
fontKey.m_weight,
+ fontKey.m_widthVariant,
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 WTF::StringHasher::createBlobHash<sizeof(hashCodes)>(hashCodes);
@@ -195,7 +198,7 @@ FontPlatformData* FontCache::getCachedFontPlatformData(const FontDescription& fo
}
FontPlatformDataCacheKey key(familyName, fontDescription.computedPixelSize(), fontDescription.weight(), fontDescription.italic(),
- fontDescription.usePrinterFont(), fontDescription.renderingMode(), fontDescription.orientation());
+ fontDescription.usePrinterFont(), fontDescription.renderingMode(), fontDescription.orientation(), fontDescription.widthVariant());
FontPlatformData* result = 0;
bool foundResult;
FontPlatformDataCache::iterator it = gFontPlatformDataCache->find(key);
diff --git a/Source/WebCore/platform/graphics/FontDescription.h b/Source/WebCore/platform/graphics/FontDescription.h
index 12900bf..283d297 100644
--- a/Source/WebCore/platform/graphics/FontDescription.h
+++ b/Source/WebCore/platform/graphics/FontDescription.h
@@ -30,6 +30,7 @@
#include "FontRenderingMode.h"
#include "FontSmoothingMode.h"
#include "FontTraitsMask.h"
+#include "FontWidthVariant.h"
#include "TextRenderingMode.h"
namespace WebCore {
@@ -57,6 +58,7 @@ public:
: m_specifiedSize(0)
, m_computedSize(0)
, m_orientation(Horizontal)
+ , m_widthVariant(RegularWidth)
, m_italic(false)
, m_smallCaps(false)
, m_isAbsoluteSize(false)
@@ -97,6 +99,7 @@ public:
FontTraitsMask traitsMask() const;
bool isSpecifiedFont() const { return m_isSpecifiedFont; }
FontOrientation orientation() const { return m_orientation; }
+ FontWidthVariant widthVariant() const { return m_widthVariant; }
void setFamily(const FontFamily& family) { m_familyList = family; }
void setComputedSize(float s) { m_computedSize = s; }
@@ -117,6 +120,7 @@ public:
void setTextRenderingMode(TextRenderingMode rendering) { m_textRendering = rendering; }
void setIsSpecifiedFont(bool isSpecifiedFont) { m_isSpecifiedFont = isSpecifiedFont; }
void setOrientation(FontOrientation orientation) { m_orientation = orientation; }
+ void setWidthVariant(FontWidthVariant widthVariant) { m_widthVariant = widthVariant; }
private:
FontFamily m_familyList; // The list of font families to be used.
@@ -126,6 +130,8 @@ private:
float m_computedSize; // Computed size adjusted for the minimum font size and the zoom factor.
FontOrientation m_orientation;
+
+ FontWidthVariant m_widthVariant;
bool m_italic : 1;
bool m_smallCaps : 1;
@@ -162,7 +168,8 @@ inline bool FontDescription::operator==(const FontDescription& other) const
&& m_fontSmoothing == other.m_fontSmoothing
&& m_textRendering == other.m_textRendering
&& m_isSpecifiedFont == other.m_isSpecifiedFont
- && m_orientation == other.m_orientation;
+ && m_orientation == other.m_orientation
+ && m_widthVariant == other.m_widthVariant;
}
}
diff --git a/Source/WebCore/platform/graphics/FontFastPath.cpp b/Source/WebCore/platform/graphics/FontFastPath.cpp
index f927c13..034ac22 100644
--- a/Source/WebCore/platform/graphics/FontFastPath.cpp
+++ b/Source/WebCore/platform/graphics/FontFastPath.cpp
@@ -23,7 +23,6 @@
#include "config.h"
#include "Font.h"
-#include "CharacterNames.h"
#include "FloatRect.h"
#include "FontCache.h"
#include "FontFallbackList.h"
@@ -32,8 +31,8 @@
#include "SimpleFontData.h"
#include "TextRun.h"
#include "WidthIterator.h"
-
#include <wtf/MathExtras.h>
+#include <wtf/unicode/CharacterNames.h>
#include <wtf/unicode/Unicode.h>
using namespace WTF;
@@ -252,7 +251,7 @@ int Font::emphasisMarkAscent(const AtomicString& mark) const
if (!markFontData)
return 0;
- return markFontData->ascent();
+ return markFontData->fontMetrics().ascent();
}
int Font::emphasisMarkDescent(const AtomicString& mark) const
@@ -266,7 +265,7 @@ int Font::emphasisMarkDescent(const AtomicString& mark) const
if (!markFontData)
return 0;
- return markFontData->descent();
+ return markFontData->fontMetrics().descent();
}
int Font::emphasisMarkHeight(const AtomicString& mark) const
@@ -280,7 +279,7 @@ int Font::emphasisMarkHeight(const AtomicString& mark) const
if (!markFontData)
return 0;
- return markFontData->height();
+ return markFontData->fontMetrics().height();
}
float Font::getGlyphsAndAdvancesForSimpleText(const TextRun& run, int from, int to, GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot forTextEmphasis) const
@@ -414,8 +413,8 @@ float Font::floatWidthForSimpleText(const TextRun& run, GlyphBuffer* glyphBuffer
it.advance(run.length(), glyphBuffer);
if (glyphOverflow) {
- glyphOverflow->top = max<int>(glyphOverflow->top, ceilf(-it.minGlyphBoundingBoxY()) - ascent());
- glyphOverflow->bottom = max<int>(glyphOverflow->bottom, ceilf(it.maxGlyphBoundingBoxY()) - descent());
+ glyphOverflow->top = max<int>(glyphOverflow->top, ceilf(-it.minGlyphBoundingBoxY()) - fontMetrics().ascent());
+ glyphOverflow->bottom = max<int>(glyphOverflow->bottom, ceilf(it.maxGlyphBoundingBoxY()) - fontMetrics().descent());
glyphOverflow->left = ceilf(it.firstGlyphOverflow());
glyphOverflow->right = ceilf(it.lastGlyphOverflow());
}
diff --git a/Source/WebCore/platform/graphics/FontMetrics.h b/Source/WebCore/platform/graphics/FontMetrics.h
new file mode 100644
index 0000000..89c5545
--- /dev/null
+++ b/Source/WebCore/platform/graphics/FontMetrics.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved.
+ *
+ * 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 FontMetrics_h
+#define FontMetrics_h
+
+#include <wtf/MathExtras.h>
+
+namespace WebCore {
+
+const unsigned gDefaultUnitsPerEm = 1000;
+
+class FontMetrics {
+public:
+ FontMetrics()
+ : m_unitsPerEm(gDefaultUnitsPerEm)
+ , m_ascent(0)
+ , m_descent(0)
+ , m_lineGap(0)
+ , m_lineSpacing(0)
+ , m_xHeight(0)
+ {
+ }
+
+ unsigned unitsPerEm() const { return m_unitsPerEm; }
+ void setUnitsPerEm(unsigned unitsPerEm) { m_unitsPerEm = unitsPerEm; }
+
+ float floatAscent(FontBaseline baselineType = AlphabeticBaseline) const
+ {
+ if (baselineType == AlphabeticBaseline)
+ return m_ascent;
+ return floatHeight() / 2;
+ }
+
+ void setAscent(float ascent) { m_ascent = ascent; }
+
+ float floatDescent(FontBaseline baselineType = AlphabeticBaseline) const
+ {
+ if (baselineType == AlphabeticBaseline)
+ return m_descent;
+ return floatHeight() / 2;
+ }
+
+ void setDescent(float descent) { m_descent = descent; }
+
+ float floatHeight(FontBaseline baselineType = AlphabeticBaseline) const
+ {
+ return floatAscent(baselineType) + floatDescent(baselineType);
+ }
+
+ float floatLineGap() const { return m_lineGap; }
+ void setLineGap(float lineGap) { m_lineGap = lineGap; }
+
+ float floatLineSpacing() const { return m_lineSpacing; }
+ void setLineSpacing(float lineSpacing) { m_lineSpacing = lineSpacing; }
+
+ float xHeight() const { return m_xHeight; }
+ void setXHeight(float xHeight) { m_xHeight = xHeight; }
+
+ // Integer variants of certain metrics, used for HTML rendering.
+ int ascent(FontBaseline baselineType = AlphabeticBaseline) const
+ {
+ if (baselineType == AlphabeticBaseline)
+ return lroundf(m_ascent);
+ return height() - height() / 2;
+ }
+
+ int descent(FontBaseline baselineType = AlphabeticBaseline) const
+ {
+ if (baselineType == AlphabeticBaseline)
+ return lroundf(m_descent);
+ return height() / 2;
+ }
+
+ int height(FontBaseline baselineType = AlphabeticBaseline) const
+ {
+ return ascent(baselineType) + descent(baselineType);
+ }
+
+ int lineGap() const { return lroundf(m_lineGap); }
+ int lineSpacing() const { return lroundf(m_lineSpacing); }
+
+private:
+ friend class SimpleFontData;
+
+ void reset()
+ {
+ m_unitsPerEm = gDefaultUnitsPerEm;
+ m_ascent = 0;
+ m_descent = 0;
+ m_lineGap = 0;
+ m_lineSpacing = 0;
+ m_xHeight = 0;
+ }
+
+ unsigned m_unitsPerEm;
+ float m_ascent;
+ float m_descent;
+ float m_lineGap;
+ float m_lineSpacing;
+ float m_xHeight;
+};
+
+} // namespace WebCore
+
+#endif // FontMetrics_h
diff --git a/Source/WebCore/platform/graphics/FontWidthVariant.h b/Source/WebCore/platform/graphics/FontWidthVariant.h
new file mode 100644
index 0000000..bbc98ee
--- /dev/null
+++ b/Source/WebCore/platform/graphics/FontWidthVariant.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2011 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 FontWidthVariant_h
+#define FontWidthVariant_h
+
+namespace WebCore {
+
+enum FontWidthVariant { RegularWidth, HalfWidth, ThirdWidth, QuarterWidth };
+
+} // namespace WebCore
+
+#endif // FontWidthVariant_h
diff --git a/Source/WebCore/platform/graphics/GlyphBuffer.h b/Source/WebCore/platform/graphics/GlyphBuffer.h
index 6f1fe7b..7aac1e3 100644
--- a/Source/WebCore/platform/graphics/GlyphBuffer.h
+++ b/Source/WebCore/platform/graphics/GlyphBuffer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2009, 2011 Apple Inc. All rights reserved.
* Copyright (C) 2007-2008 Torch Mobile Inc.
*
* Redistribution and use in source and binary forms, with or without
@@ -187,7 +187,20 @@ public:
m_advances.append(advance);
}
#endif
-
+
+ void expandLastAdvance(float width)
+ {
+ ASSERT(!isEmpty());
+ GlyphBufferAdvance& lastAdvance = m_advances.last();
+#if PLATFORM(CG) || (PLATFORM(WX) && OS(DARWIN))
+ lastAdvance.width += width;
+#elif OS(WINCE)
+ lastAdvance += width;
+#else
+ lastAdvance += FloatSize(width, 0);
+#endif
+ }
+
private:
Vector<const SimpleFontData*, 2048> m_fontData;
Vector<GlyphBufferGlyph, 2048> m_glyphs;
diff --git a/Source/WebCore/platform/graphics/GlyphPageTreeNode.cpp b/Source/WebCore/platform/graphics/GlyphPageTreeNode.cpp
index 3df14b9..e7ed193 100644
--- a/Source/WebCore/platform/graphics/GlyphPageTreeNode.cpp
+++ b/Source/WebCore/platform/graphics/GlyphPageTreeNode.cpp
@@ -29,12 +29,12 @@
#include "config.h"
#include "GlyphPageTreeNode.h"
-#include "CharacterNames.h"
#include "PlatformString.h"
#include "SegmentedFontData.h"
#include "SimpleFontData.h"
#include <stdio.h>
#include <wtf/text/CString.h>
+#include <wtf/unicode/CharacterNames.h>
#include <wtf/unicode/Unicode.h>
namespace WebCore {
diff --git a/Source/WebCore/platform/graphics/GraphicsContext.cpp b/Source/WebCore/platform/graphics/GraphicsContext.cpp
index 9f94ac9..a0a7ea9 100644
--- a/Source/WebCore/platform/graphics/GraphicsContext.cpp
+++ b/Source/WebCore/platform/graphics/GraphicsContext.cpp
@@ -142,6 +142,18 @@ void GraphicsContext::setShadow(const FloatSize& offset, float blur, const Color
setPlatformShadow(offset, blur, color, colorSpace);
}
+void GraphicsContext::setLegacyShadow(const FloatSize& offset, float blur, const Color& color, ColorSpace colorSpace)
+{
+ m_state.shadowOffset = offset;
+ m_state.shadowBlur = blur;
+ m_state.shadowColor = color;
+ m_state.shadowColorSpace = colorSpace;
+#if PLATFORM(CG)
+ m_state.shadowsUseLegacyRadius = true;
+#endif
+ setPlatformShadow(offset, blur, color, colorSpace);
+}
+
void GraphicsContext::clearShadow()
{
m_state.shadowOffset = FloatSize();
@@ -532,10 +544,10 @@ void GraphicsContext::drawImageBuffer(ImageBuffer* image, ColorSpace styleColorS
InterpolationQuality previousInterpolationQuality = imageInterpolationQuality();
// FIXME: Should be InterpolationLow
setImageInterpolationQuality(InterpolationNone);
- image->draw(this, styleColorSpace, dest, src, op, useLowQualityScale);
+ image->draw(this, styleColorSpace, FloatRect(dest.location(), FloatSize(tw, th)), FloatRect(src.location(), FloatSize(tsw, tsh)), op, useLowQualityScale);
setImageInterpolationQuality(previousInterpolationQuality);
} else
- image->draw(this, styleColorSpace, dest, src, op, useLowQualityScale);
+ image->draw(this, styleColorSpace, FloatRect(dest.location(), FloatSize(tw, th)), FloatRect(src.location(), FloatSize(tsw, tsh)), op, useLowQualityScale);
}
void GraphicsContext::addRoundedRectClip(const RoundedIntRect& rect)
@@ -565,6 +577,14 @@ void GraphicsContext::clipToImageBuffer(ImageBuffer* buffer, const FloatRect& re
buffer->clip(this, rect);
}
+#if !PLATFORM(CG)
+IntRect GraphicsContext::clipBounds() const
+{
+ ASSERT_NOT_REACHED();
+ return IntRect();
+}
+#endif
+
TextDrawingModeFlags GraphicsContext::textDrawingMode() const
{
return m_state.textDrawingMode;
@@ -590,6 +610,34 @@ void GraphicsContext::fillRoundedRect(const RoundedIntRect& rect, const Color& c
fillRoundedRect(rect.rect(), rect.radii().topLeft(), rect.radii().topRight(), rect.radii().bottomLeft(), rect.radii().bottomRight(), color, colorSpace);
}
+#if !PLATFORM(CG)
+void GraphicsContext::fillRectWithRoundedHole(const IntRect& rect, const RoundedIntRect& roundedHoleRect, const Color& color, ColorSpace colorSpace)
+{
+ if (paintingDisabled())
+ return;
+
+ Path path;
+ path.addRect(rect);
+
+ if (!roundedHoleRect.radii().isZero())
+ path.addRoundedRect(roundedHoleRect.rect(), roundedHoleRect.radii().topLeft(), roundedHoleRect.radii().topRight(), roundedHoleRect.radii().bottomLeft(), roundedHoleRect.radii().bottomRight());
+ else
+ path.addRect(roundedHoleRect.rect());
+
+ WindRule oldFillRule = fillRule();
+ Color oldFillColor = fillColor();
+ ColorSpace oldFillColorSpace = fillColorSpace();
+
+ setFillRule(RULE_EVENODD);
+ setFillColor(color, colorSpace);
+
+ fillPath(path);
+
+ setFillRule(oldFillRule);
+ setFillColor(oldFillColor, oldFillColorSpace);
+}
+#endif
+
void GraphicsContext::setCompositeOperation(CompositeOperator compositeOperation)
{
m_state.compositeOperator = compositeOperation;
diff --git a/Source/WebCore/platform/graphics/GraphicsContext.h b/Source/WebCore/platform/graphics/GraphicsContext.h
index 77321e2..21a9067 100644
--- a/Source/WebCore/platform/graphics/GraphicsContext.h
+++ b/Source/WebCore/platform/graphics/GraphicsContext.h
@@ -176,6 +176,11 @@ namespace WebCore {
, shouldSmoothFonts(true)
, paintingDisabled(false)
, shadowsIgnoreTransforms(false)
+#if PLATFORM(CG)
+ // Core Graphics incorrectly renders shadows with radius > 8px (<rdar://problem/8103442>),
+ // but we need to preserve this buggy behavior for canvas and -webkit-box-shadow.
+ , shadowsUseLegacyRadius(false)
+#endif
{
}
@@ -212,6 +217,9 @@ namespace WebCore {
bool shouldSmoothFonts : 1;
bool paintingDisabled : 1;
bool shadowsIgnoreTransforms : 1;
+#if PLATFORM(CG)
+ bool shadowsUseLegacyRadius : 1;
+#endif
};
class GraphicsContext {
@@ -320,6 +328,7 @@ namespace WebCore {
void fillRect(const FloatRect&, Generator&);
void fillRoundedRect(const IntRect&, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color&, ColorSpace);
void fillRoundedRect(const RoundedIntRect&, const Color&, ColorSpace);
+ void fillRectWithRoundedHole(const IntRect&, const RoundedIntRect& roundedHoleRect, const Color&, ColorSpace);
void clearRect(const FloatRect&);
@@ -355,6 +364,8 @@ namespace WebCore {
void clipPath(const Path&, WindRule);
void clipConvexPolygon(size_t numPoints, const FloatPoint*, bool antialias = true);
void clipToImageBuffer(ImageBuffer*, const FloatRect&);
+
+ IntRect clipBounds() const;
TextDrawingModeFlags textDrawingMode() const;
void setTextDrawingMode(TextDrawingModeFlags);
@@ -385,6 +396,10 @@ namespace WebCore {
bool hasShadow() const;
void setShadow(const FloatSize&, float blur, const Color&, ColorSpace);
+ // Legacy shadow blur radius is used for canvas, and -webkit-box-shadow.
+ // It has different treatment of radii > 8px.
+ void setLegacyShadow(const FloatSize&, float blur, const Color&, ColorSpace);
+
bool getShadow(FloatSize&, float&, Color&, ColorSpace&) const;
void clearShadow();
@@ -404,16 +419,11 @@ namespace WebCore {
void setCompositeOperation(CompositeOperator);
CompositeOperator compositeOperation() const;
-#if PLATFORM(SKIA)
- void beginPath();
- void addPath(const Path&);
-#endif
-
void clip(const Path&);
// This clip function is used only by <canvas> code. It allows
// implementations to handle clipping on the canvas differently since
- // the disipline is different.
+ // the discipline is different.
void canvasClip(const Path&);
void clipOut(const Path&);
@@ -500,7 +510,6 @@ namespace WebCore {
bool inTransparencyLayer() const;
void pushTransparencyLayerInternal(const QRect &rect, qreal opacity, QPixmap& alphaMask);
void takeOwnershipOfPlatformContext();
- static QPainter::CompositionMode toQtCompositionMode(CompositeOperator op);
#endif
#if PLATFORM(QT) || PLATFORM(CAIRO)
diff --git a/Source/WebCore/platform/graphics/GraphicsContext3D.cpp b/Source/WebCore/platform/graphics/GraphicsContext3D.cpp
index f7c5a66..324fed8 100644
--- a/Source/WebCore/platform/graphics/GraphicsContext3D.cpp
+++ b/Source/WebCore/platform/graphics/GraphicsContext3D.cpp
@@ -26,7 +26,7 @@
#include "config.h"
-#if ENABLE(3D_CANVAS)
+#if ENABLE(WEBGL)
#include "GraphicsContext3D.h"
@@ -1437,4 +1437,4 @@ bool GraphicsContext3D::packPixels(const uint8_t* sourceData,
} // namespace WebCore
-#endif // ENABLE(3D_CANVAS)
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/platform/graphics/GraphicsContext3D.h b/Source/WebCore/platform/graphics/GraphicsContext3D.h
index 24827e5..d6c1cec 100644
--- a/Source/WebCore/platform/graphics/GraphicsContext3D.h
+++ b/Source/WebCore/platform/graphics/GraphicsContext3D.h
@@ -47,7 +47,9 @@
typedef unsigned int GC3Denum;
typedef unsigned char GC3Dboolean;
typedef unsigned int GC3Dbitfield;
+typedef signed char GC3Dbyte;
typedef unsigned char GC3Dubyte;
+typedef short GC3Dshort;
typedef unsigned short GC3Dushort;
typedef int GC3Dint;
typedef int GC3Dsizei;
@@ -117,7 +119,7 @@ class GraphicsContext3DInternal;
class GraphicsContext3D : public RefCounted<GraphicsContext3D> {
public:
- enum WebGLEnumType {
+ enum {
DEPTH_BUFFER_BIT = 0x00000100,
STENCIL_BUFFER_BIT = 0x00000400,
COLOR_BUFFER_BIT = 0x00004000,
@@ -452,6 +454,14 @@ public:
RenderDirectlyToHostWindow
};
+ class ContextLostCallback {
+ public:
+ virtual void onContextLost() = 0;
+ virtual ~ContextLostCallback() {}
+ };
+
+ void setContextLostCallback(PassOwnPtr<ContextLostCallback>);
+
static PassRefPtr<GraphicsContext3D> create(Attributes, HostWindow*, RenderStyle = RenderOffscreen);
~GraphicsContext3D();
@@ -487,10 +497,6 @@ public:
void prepareTexture();
#endif
- // Helper to return the size in bytes of OpenGL data types
- // like GL_FLOAT, GL_INT, etc.
- unsigned int sizeInBytes(GC3Denum type);
-
// Helper to texImage2D with pixel==0 case: pixels are initialized to 0.
// Return true if no GL error is synthesized.
// By default, alignment is 4, the OpenGL default setting.
diff --git a/Source/WebCore/platform/graphics/Icon.h b/Source/WebCore/platform/graphics/Icon.h
index c83685f..2797133 100644
--- a/Source/WebCore/platform/graphics/Icon.h
+++ b/Source/WebCore/platform/graphics/Icon.h
@@ -42,6 +42,7 @@ typedef struct _GdkPixbuf GdkPixbuf;
#elif PLATFORM(EFL)
typedef struct _Evas_Object Evas_Object;
#elif PLATFORM(CHROMIUM)
+#include "Image.h"
#include "PlatformIcon.h"
#endif
@@ -60,6 +61,8 @@ public:
#if PLATFORM(WIN)
static PassRefPtr<Icon> create(HICON hIcon) { return adoptRef(new Icon(hIcon)); }
+#elif PLATFORM(CHROMIUM)
+ static PassRefPtr<Icon> create(PassRefPtr<PlatformIcon> icon) { return adoptRef(new Icon(icon)); }
#endif
private:
@@ -79,8 +82,8 @@ private:
Icon();
Evas_Object* m_icon;
#elif PLATFORM(CHROMIUM)
- Icon(const PlatformIcon&);
- PlatformIcon m_icon;
+ Icon(PassRefPtr<PlatformIcon>);
+ RefPtr<PlatformIcon> m_icon;
#endif
};
diff --git a/Source/WebCore/platform/graphics/IntRect.cpp b/Source/WebCore/platform/graphics/IntRect.cpp
index 188b5f9..7591c41 100644
--- a/Source/WebCore/platform/graphics/IntRect.cpp
+++ b/Source/WebCore/platform/graphics/IntRect.cpp
@@ -44,22 +44,22 @@ bool IntRect::intersects(const IntRect& other) const
{
// Checking emptiness handles negative widths as well as zero.
return !isEmpty() && !other.isEmpty()
- && x() < other.right() && other.x() < right()
- && y() < other.bottom() && other.y() < bottom();
+ && x() < other.maxX() && other.x() < maxX()
+ && y() < other.maxY() && other.y() < maxY();
}
bool IntRect::contains(const IntRect& other) const
{
- return x() <= other.x() && right() >= other.right()
- && y() <= other.y() && bottom() >= other.bottom();
+ return x() <= other.x() && maxX() >= other.maxX()
+ && y() <= other.y() && maxY() >= other.maxY();
}
void IntRect::intersect(const IntRect& other)
{
int l = max(x(), other.x());
int t = max(y(), other.y());
- int r = min(right(), other.right());
- int b = min(bottom(), other.bottom());
+ int r = min(maxX(), other.maxX());
+ int b = min(maxY(), other.maxY());
// Return a clean empty rectangle for non-intersecting cases.
if (l >= r || t >= b) {
@@ -87,8 +87,8 @@ void IntRect::unite(const IntRect& other)
int l = min(x(), other.x());
int t = min(y(), other.y());
- int r = max(right(), other.right());
- int b = max(bottom(), other.bottom());
+ int r = max(maxX(), other.maxX());
+ int b = max(maxY(), other.maxY());
m_location.setX(l);
m_location.setY(t);
diff --git a/Source/WebCore/platform/graphics/IntRect.h b/Source/WebCore/platform/graphics/IntRect.h
index 638db75..3a2433d 100644
--- a/Source/WebCore/platform/graphics/IntRect.h
+++ b/Source/WebCore/platform/graphics/IntRect.h
@@ -91,6 +91,8 @@ public:
int x() const { return m_location.x(); }
int y() const { return m_location.y(); }
+ int maxX() const { return x() + width(); }
+ int maxY() const { return y() + height(); }
int width() const { return m_size.width(); }
int height() const { return m_size.height(); }
@@ -99,18 +101,8 @@ public:
void setWidth(int width) { m_size.setWidth(width); }
void setHeight(int height) { m_size.setHeight(height); }
- // Be careful with these functions. The point is considered to be to the right and below. These are not
- // substitutes for right() and bottom().
- IntPoint topLeft() const { return m_location; }
- IntPoint topRight() const { return IntPoint(right() - 1, y()); }
- IntPoint bottomLeft() const { return IntPoint(x(), bottom() - 1); }
- IntPoint bottomRight() const { return IntPoint(right() - 1, bottom() - 1); }
-
bool isEmpty() const { return m_size.isEmpty(); }
- int right() const { return x() + width(); }
- int bottom() const { return y() + height(); }
-
// NOTE: The result is rounded to integer values, and thus may be not the exact
// center point.
IntPoint center() const { return IntPoint(x() + width() / 2, y() + height() / 2); }
@@ -118,26 +110,26 @@ public:
void move(const IntSize& s) { m_location += s; }
void move(int dx, int dy) { m_location.move(dx, dy); }
- void shiftLeftEdgeTo(int edge)
+ void shiftXEdgeTo(int edge)
{
int delta = edge - x();
setX(edge);
setWidth(std::max(0, width() - delta));
}
- void shiftRightEdgeTo(int edge)
+ void shiftMaxXEdgeTo(int edge)
{
- int delta = edge - right();
+ int delta = edge - maxX();
setWidth(std::max(0, width() + delta));
}
- void shiftTopEdgeTo(int edge)
+ void shiftYEdgeTo(int edge)
{
int delta = edge - y();
setY(edge);
setHeight(std::max(0, height() - delta));
}
- void shiftBottomEdgeTo(int edge)
+ void shiftMaxYEdgeTo(int edge)
{
- int delta = edge - bottom();
+ int delta = edge - maxY();
setHeight(std::max(0, height() + delta));
}
@@ -147,7 +139,7 @@ public:
// This checks to see if the rect contains x,y in the traditional sense.
// Equivalent to checking if the rect contains a 1x1 rect below and to the right of (px,py).
bool contains(int px, int py) const
- { return px >= x() && px < right() && py >= y() && py < bottom(); }
+ { return px >= x() && px < maxX() && py >= y() && py < maxY(); }
bool contains(const IntPoint& point) const { return contains(point.x(), point.y()); }
void intersect(const IntRect&);
diff --git a/Source/WebCore/platform/graphics/IntRectHash.h b/Source/WebCore/platform/graphics/IntRectHash.h
new file mode 100644
index 0000000..7138f33
--- /dev/null
+++ b/Source/WebCore/platform/graphics/IntRectHash.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2011 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 INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef IntRectHash_h
+#define IntRectHash_h
+
+#include "IntPointHash.h"
+#include "IntRect.h"
+#include "IntSizeHash.h"
+#include <wtf/HashMap.h>
+#include <wtf/HashSet.h>
+
+namespace WTF {
+
+template<> struct IntHash<WebCore::IntRect> {
+ static unsigned hash(const WebCore::IntRect& key)
+ {
+ return intHash(static_cast<uint64_t>(DefaultHash<WebCore::IntPoint>::Hash::hash(key.location())) << 32 | DefaultHash<WebCore::IntSize>::Hash::hash(key.size()));
+ }
+ static bool equal(const WebCore::IntRect& a, const WebCore::IntRect& b)
+ {
+ return DefaultHash<WebCore::IntPoint>::Hash::equal(a.location(), b.location()) && DefaultHash<WebCore::IntSize>::Hash::equal(a.size(), b.size());
+ }
+ static const bool safeToCompareToEmptyOrDeleted = true;
+};
+template<> struct DefaultHash<WebCore::IntRect> { typedef IntHash<WebCore::IntRect> Hash; };
+
+template<> struct HashTraits<WebCore::IntRect> : GenericHashTraits<WebCore::IntRect> {
+ static const bool emptyValueIsZero = true;
+ static const bool needsDestruction = false;
+ static void constructDeletedValue(WebCore::IntRect& slot) { new (&slot) WebCore::IntRect(-1, -1, -1, -1); }
+ static bool isDeletedValue(const WebCore::IntRect& value) { return value.x() == -1 && value.y() == -1 && value.width() == -1 && value.height() == -1; }
+};
+
+}
+
+#endif
diff --git a/Source/WebCore/platform/graphics/IntSizeHash.h b/Source/WebCore/platform/graphics/IntSizeHash.h
index ad6eac3..0cca000 100644
--- a/Source/WebCore/platform/graphics/IntSizeHash.h
+++ b/Source/WebCore/platform/graphics/IntSizeHash.h
@@ -24,22 +24,20 @@
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
-using WebCore::IntSize;
-
namespace WTF {
- template<> struct IntHash<IntSize> {
- static unsigned hash(const IntSize& key) { return intHash((static_cast<uint64_t>(key.width()) << 32 | key.height())); }
- static bool equal(const IntSize& a, const IntSize& b) { return a == b; }
+ template<> struct IntHash<WebCore::IntSize> {
+ static unsigned hash(const WebCore::IntSize& key) { return intHash((static_cast<uint64_t>(key.width()) << 32 | key.height())); }
+ static bool equal(const WebCore::IntSize& a, const WebCore::IntSize& b) { return a == b; }
static const bool safeToCompareToEmptyOrDeleted = true;
};
- template<> struct DefaultHash<IntSize> { typedef IntHash<IntSize> Hash; };
+ template<> struct DefaultHash<WebCore::IntSize> { typedef IntHash<WebCore::IntSize> Hash; };
- template<> struct HashTraits<IntSize> : GenericHashTraits<IntSize> {
+ template<> struct HashTraits<WebCore::IntSize> : GenericHashTraits<WebCore::IntSize> {
static const bool emptyValueIsZero = true;
static const bool needsDestruction = false;
- static void constructDeletedValue(IntSize& slot) { new (&slot) IntSize(-1, -1); }
- static bool isDeletedValue(const IntSize& value) { return value.width() == -1 && value.height() == -1; }
+ static void constructDeletedValue(WebCore::IntSize& slot) { new (&slot) WebCore::IntSize(-1, -1); }
+ static bool isDeletedValue(const WebCore::IntSize& value) { return value.width() == -1 && value.height() == -1; }
};
} // namespace WTF
diff --git a/Source/WebCore/platform/graphics/MediaPlayer.cpp b/Source/WebCore/platform/graphics/MediaPlayer.cpp
index 60f55a5..8eed0d2 100644
--- a/Source/WebCore/platform/graphics/MediaPlayer.cpp
+++ b/Source/WebCore/platform/graphics/MediaPlayer.cpp
@@ -698,6 +698,26 @@ double MediaPlayer::maximumDurationToCacheMediaTime() const
return m_private->maximumDurationToCacheMediaTime();
}
+unsigned long MediaPlayer::decodedFrames() const
+{
+ return m_private->decodedFrames();
+}
+
+unsigned long MediaPlayer::droppedFrames() const
+{
+ return m_private->droppedFrames();
+}
+
+unsigned long MediaPlayer::audioBytesDecoded() const
+{
+ return m_private->audioBytesDecoded();
+}
+
+unsigned long MediaPlayer::videoBytesDecoded() const
+{
+ return m_private->videoBytesDecoded();
+}
+
void MediaPlayer::reloadTimerFired(Timer<MediaPlayer>*)
{
m_private->cancelLoad();
diff --git a/Source/WebCore/platform/graphics/MediaPlayer.h b/Source/WebCore/platform/graphics/MediaPlayer.h
index ef0b3eb..1112148 100644
--- a/Source/WebCore/platform/graphics/MediaPlayer.h
+++ b/Source/WebCore/platform/graphics/MediaPlayer.h
@@ -287,6 +287,11 @@ public:
double maximumDurationToCacheMediaTime() const;
+ unsigned long decodedFrames() const;
+ unsigned long droppedFrames() const;
+ unsigned long audioBytesDecoded() const;
+ unsigned long videoBytesDecoded() const;
+
private:
MediaPlayer(MediaPlayerClient*);
void loadWithNextMediaEngine(MediaPlayerFactory*);
diff --git a/Source/WebCore/platform/graphics/MediaPlayerPrivate.h b/Source/WebCore/platform/graphics/MediaPlayerPrivate.h
index 6abe258..04b2612 100644
--- a/Source/WebCore/platform/graphics/MediaPlayerPrivate.h
+++ b/Source/WebCore/platform/graphics/MediaPlayerPrivate.h
@@ -136,6 +136,10 @@ public:
// it is OK to calculate movie time before refreshing the cached time.
virtual double maximumDurationToCacheMediaTime() const { return 0; }
+ virtual unsigned long decodedFrames() const { return 0; }
+ virtual unsigned long droppedFrames() const { return 0; }
+ virtual unsigned long audioBytesDecoded() const { return 0; }
+ virtual unsigned long videoBytesDecoded() const { return 0; }
};
}
diff --git a/Source/WebCore/platform/graphics/ShadowBlur.cpp b/Source/WebCore/platform/graphics/ShadowBlur.cpp
new file mode 100644
index 0000000..f61ecff
--- /dev/null
+++ b/Source/WebCore/platform/graphics/ShadowBlur.cpp
@@ -0,0 +1,733 @@
+/*
+ * Copyright (C) 2011 Apple Inc.
+ * Copyright (C) 2010 Sencha, Inc.
+ * Copyright (C) 2010 Igalia S.L.
+ * 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 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 "ShadowBlur.h"
+
+#include "AffineTransform.h"
+#include "FloatQuad.h"
+#include "GraphicsContext.h"
+#include "ImageBuffer.h"
+#include "Timer.h"
+#include <wtf/MathExtras.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/UnusedParam.h>
+
+using namespace std;
+
+namespace WebCore {
+
+static inline int roundUpToMultipleOf32(int d)
+{
+ return (1 + (d >> 5)) << 5;
+}
+
+// ShadowBlur needs a scratch image as the buffer for the blur filter.
+// Instead of creating and destroying the buffer for every operation,
+// we create a buffer which will be automatically purged via a timer.
+class ScratchBuffer {
+public:
+ ScratchBuffer()
+ : m_purgeTimer(this, &ScratchBuffer::timerFired)
+#if !ASSERT_DISABLED
+ , m_bufferInUse(false)
+#endif
+ {
+ }
+
+ ImageBuffer* getScratchBuffer(const IntSize& size)
+ {
+ ASSERT(!m_bufferInUse);
+#if !ASSERT_DISABLED
+ m_bufferInUse = true;
+#endif
+ // We do not need to recreate the buffer if the current buffer is large enough.
+ if (m_imageBuffer && m_imageBuffer->width() >= size.width() && m_imageBuffer->height() >= size.height())
+ return m_imageBuffer.get();
+
+ // Round to the nearest 32 pixels so we do not grow the buffer for similar sized requests.
+ IntSize roundedSize(roundUpToMultipleOf32(size.width()), roundUpToMultipleOf32(size.height()));
+
+ m_imageBuffer = ImageBuffer::create(roundedSize);
+ return m_imageBuffer.get();
+ }
+
+ void scheduleScratchBufferPurge()
+ {
+#if !ASSERT_DISABLED
+ m_bufferInUse = false;
+#endif
+ if (m_purgeTimer.isActive())
+ m_purgeTimer.stop();
+
+ const double scratchBufferPurgeInterval = 2;
+ m_purgeTimer.startOneShot(scratchBufferPurgeInterval);
+ }
+
+ static ScratchBuffer& shared();
+
+private:
+ void timerFired(Timer<ScratchBuffer>*)
+ {
+ clearScratchBuffer();
+ }
+
+ void clearScratchBuffer()
+ {
+ m_imageBuffer = 0;
+ }
+
+ OwnPtr<ImageBuffer> m_imageBuffer;
+ Timer<ScratchBuffer> m_purgeTimer;
+#if !ASSERT_DISABLED
+ bool m_bufferInUse;
+#endif
+};
+
+ScratchBuffer& ScratchBuffer::shared()
+{
+ DEFINE_STATIC_LOCAL(ScratchBuffer, scratchBuffer, ());
+ return scratchBuffer;
+}
+
+static const int templateSideLength = 1;
+
+ShadowBlur::ShadowBlur(float radius, const FloatSize& offset, const Color& color, ColorSpace colorSpace)
+ : m_color(color)
+ , m_colorSpace(colorSpace)
+ , m_blurRadius(radius)
+ , m_offset(offset)
+ , m_layerImage(0)
+ , m_shadowsIgnoreTransforms(false)
+{
+ // Limit blur radius to 128 to avoid lots of very expensive blurring.
+ m_blurRadius = min<float>(m_blurRadius, 128);
+
+ // The type of shadow is decided by the blur radius, shadow offset, and shadow color.
+ if (!m_color.isValid() || !color.alpha()) {
+ // Can't paint the shadow with invalid or invisible color.
+ m_type = NoShadow;
+ } else if (m_blurRadius > 0) {
+ // Shadow is always blurred, even the offset is zero.
+ m_type = BlurShadow;
+ } else if (!m_offset.width() && !m_offset.height()) {
+ // Without blur and zero offset means the shadow is fully hidden.
+ m_type = NoShadow;
+ } else
+ m_type = SolidShadow;
+}
+
+// Instead of integer division, we use 17.15 for fixed-point division.
+static const int blurSumShift = 15;
+static const float gaussianKernelFactor = 3 / 4.f * sqrtf(2 * piFloat);
+
+void ShadowBlur::blurLayerImage(unsigned char* imageData, const IntSize& size, int rowStride)
+{
+ const int channels[4] =
+#if CPU(BIG_ENDIAN)
+ { 0, 3, 2, 0 };
+#elif CPU(MIDDLE_ENDIAN)
+ { 1, 2, 3, 1 };
+#else
+ { 3, 0, 1, 3 };
+#endif
+
+ int diameter;
+ if (m_shadowsIgnoreTransforms)
+ diameter = max(2, static_cast<int>(floorf((2 / 3.f) * m_blurRadius))); // Canvas shadow. FIXME: we should adjust the blur radius higher up.
+ else {
+ // http://dev.w3.org/csswg/css3-background/#box-shadow
+ // Approximate a Gaussian blur with a standard deviation equal to half the blur radius,
+ // which http://www.w3.org/TR/SVG/filters.html#feGaussianBlurElement tell us how to do.
+ // However, shadows rendered according to that spec will extend a little further than m_blurRadius,
+ // so we apply a fudge factor to bring the radius down slightly.
+ float stdDev = m_blurRadius / 2;
+ const float fudgeFactor = 0.88f;
+ diameter = max(2, static_cast<int>(floorf(stdDev * gaussianKernelFactor * fudgeFactor + 0.5f)));
+ }
+
+ enum {
+ leftLobe = 0,
+ rightLobe = 1
+ };
+
+ int lobes[3][2]; // indexed by pass, and left/right lobe
+
+ if (diameter & 1) {
+ // if d is odd, use three box-blurs of size 'd', centered on the output pixel.
+ int lobeSize = (diameter - 1) / 2;
+ lobes[0][leftLobe] = lobeSize;
+ lobes[0][rightLobe] = lobeSize;
+ lobes[1][leftLobe] = lobeSize;
+ lobes[1][rightLobe] = lobeSize;
+ lobes[2][leftLobe] = lobeSize;
+ lobes[2][rightLobe] = lobeSize;
+ } else {
+ // if d is even, two box-blurs of size 'd' (the first one centered on the pixel boundary
+ // between the output pixel and the one to the left, the second one centered on the pixel
+ // boundary between the output pixel and the one to the right) and one box blur of size 'd+1' centered on the output pixel
+ int lobeSize = diameter / 2;
+ lobes[0][leftLobe] = lobeSize;
+ lobes[0][rightLobe] = lobeSize - 1;
+ lobes[1][leftLobe] = lobeSize - 1;
+ lobes[1][rightLobe] = lobeSize;
+ lobes[2][leftLobe] = lobeSize;
+ lobes[2][rightLobe] = lobeSize;
+ }
+
+ // First pass is horizontal.
+ int stride = 4;
+ int delta = rowStride;
+ int final = size.height();
+ int dim = size.width();
+
+ // Two stages: horizontal and vertical
+ for (int pass = 0; pass < 2; ++pass) {
+ unsigned char* pixels = imageData;
+
+ for (int j = 0; j < final; ++j, pixels += delta) {
+ // For each step, we blur the alpha in a channel and store the result
+ // in another channel for the subsequent step.
+ // We use sliding window algorithm to accumulate the alpha values.
+ // This is much more efficient than computing the sum of each pixels
+ // covered by the box kernel size for each x.
+ for (int step = 0; step < 3; ++step) {
+ int side1 = lobes[step][leftLobe];
+ int side2 = lobes[step][rightLobe];
+ int pixelCount = side1 + 1 + side2;
+ int invCount = ((1 << blurSumShift) + pixelCount - 1) / pixelCount;
+ int ofs = 1 + side2;
+ int alpha1 = pixels[channels[step]];
+ int alpha2 = pixels[(dim - 1) * stride + channels[step]];
+
+ unsigned char* ptr = pixels + channels[step + 1];
+ unsigned char* prev = pixels + stride + channels[step];
+ unsigned char* next = pixels + ofs * stride + channels[step];
+
+ int i;
+ int sum = side1 * alpha1 + alpha1;
+ int limit = (dim < side2 + 1) ? dim : side2 + 1;
+
+ for (i = 1; i < limit; ++i, prev += stride)
+ sum += *prev;
+
+ if (limit <= side2)
+ sum += (side2 - limit + 1) * alpha2;
+
+ limit = (side1 < dim) ? side1 : dim;
+ for (i = 0; i < limit; ptr += stride, next += stride, ++i, ++ofs) {
+ *ptr = (sum * invCount) >> blurSumShift;
+ sum += ((ofs < dim) ? *next : alpha2) - alpha1;
+ }
+
+ prev = pixels + channels[step];
+ for (; ofs < dim; ptr += stride, prev += stride, next += stride, ++i, ++ofs) {
+ *ptr = (sum * invCount) >> blurSumShift;
+ sum += (*next) - (*prev);
+ }
+
+ for (; i < dim; ptr += stride, prev += stride, ++i) {
+ *ptr = (sum * invCount) >> blurSumShift;
+ sum += alpha2 - (*prev);
+ }
+ }
+ }
+
+ // Last pass is vertical.
+ stride = rowStride;
+ delta = 4;
+ final = size.width();
+ dim = size.height();
+ }
+}
+
+void ShadowBlur::adjustBlurRadius(GraphicsContext* context)
+{
+ if (!m_shadowsIgnoreTransforms)
+ return;
+
+ const AffineTransform transform = context->getCTM();
+
+ // Adjust blur if we're scaling, since the radius must not be affected by transformations.
+ // FIXME: use AffineTransform::isIdentityOrTranslationOrFlipped()?
+ if (transform.isIdentity())
+ return;
+
+ // Calculate transformed unit vectors.
+ const FloatQuad unitQuad(FloatPoint(0, 0), FloatPoint(1, 0),
+ FloatPoint(0, 1), FloatPoint(1, 1));
+ const FloatQuad transformedUnitQuad = transform.mapQuad(unitQuad);
+
+ // Calculate X axis scale factor.
+ const FloatSize xUnitChange = transformedUnitQuad.p2() - transformedUnitQuad.p1();
+ const float xAxisScale = sqrtf(xUnitChange.width() * xUnitChange.width()
+ + xUnitChange.height() * xUnitChange.height());
+
+ // Calculate Y axis scale factor.
+ const FloatSize yUnitChange = transformedUnitQuad.p3() - transformedUnitQuad.p1();
+ const float yAxisScale = sqrtf(yUnitChange.width() * yUnitChange.width()
+ + yUnitChange.height() * yUnitChange.height());
+
+ // blurLayerImage() does not support per-axis blurring, so calculate a balanced scaling.
+ // FIXME: does AffineTransform.xScale()/yScale() help?
+ const float scale = sqrtf(xAxisScale * yAxisScale);
+ m_blurRadius = roundf(m_blurRadius / scale);
+}
+
+IntRect ShadowBlur::calculateLayerBoundingRect(GraphicsContext* context, const FloatRect& shadowedRect, const IntRect& clipRect)
+{
+ const float roundedRadius = ceilf(m_blurRadius);
+
+ // Calculate the destination of the blurred and/or transformed layer.
+ FloatRect layerRect;
+ float inflation = 0;
+
+ const AffineTransform transform = context->getCTM();
+ if (m_shadowsIgnoreTransforms && !transform.isIdentity()) {
+ FloatQuad transformedPolygon = transform.mapQuad(FloatQuad(shadowedRect));
+ transformedPolygon.move(m_offset);
+ layerRect = transform.inverse().mapQuad(transformedPolygon).boundingBox();
+ } else {
+ layerRect = shadowedRect;
+ layerRect.move(m_offset);
+ }
+
+ // We expand the area by the blur radius to give extra space for the blur transition.
+ if (m_type == BlurShadow) {
+ layerRect.inflate(roundedRadius);
+ inflation = roundedRadius;
+ }
+
+ FloatRect unclippedLayerRect = layerRect;
+
+ if (!clipRect.contains(enclosingIntRect(layerRect))) {
+ // If we are totally outside the clip region, we aren't painting at all.
+ if (intersection(layerRect, clipRect).isEmpty())
+ return IntRect();
+
+ IntRect inflatedClip = clipRect;
+ // Pixels at the edges can be affected by pixels outside the buffer,
+ // so intersect with the clip inflated by the blur.
+ if (m_type == BlurShadow)
+ inflatedClip.inflate(roundedRadius);
+
+ layerRect.intersect(inflatedClip);
+ }
+
+ const float frameSize = inflation * 2;
+ m_sourceRect = FloatRect(0, 0, shadowedRect.width() + frameSize, shadowedRect.height() + frameSize);
+ m_layerOrigin = FloatPoint(layerRect.x(), layerRect.y());
+ m_layerSize = layerRect.size();
+
+ const FloatPoint unclippedLayerOrigin = FloatPoint(unclippedLayerRect.x(), unclippedLayerRect.y());
+ const FloatSize clippedOut = unclippedLayerOrigin - m_layerOrigin;
+
+ // Set the origin as the top left corner of the scratch image, or, in case there's a clipped
+ // out region, set the origin accordingly to the full bounding rect's top-left corner.
+ float translationX = -shadowedRect.x() + inflation - fabsf(clippedOut.width());
+ float translationY = -shadowedRect.y() + inflation - fabsf(clippedOut.height());
+ m_layerContextTranslation = FloatSize(translationX, translationY);
+
+ return enclosingIntRect(layerRect);
+}
+
+GraphicsContext* ShadowBlur::beginShadowLayer(GraphicsContext* graphicsContext, const IntRect& layerRect)
+{
+ adjustBlurRadius(graphicsContext);
+
+ // Don't paint if we are totally outside the clip region.
+ if (layerRect.isEmpty())
+ return 0;
+
+ m_layerImage = ScratchBuffer::shared().getScratchBuffer(layerRect.size());
+ GraphicsContext* layerContext = m_layerImage->context();
+
+ layerContext->save(); // Balanced by restore() in endShadowLayer().
+
+ // Always clear the surface first. FIXME: we could avoid the clear on first allocation.
+ // Add a pixel to avoid later edge aliasing when rotated.
+ layerContext->clearRect(FloatRect(0, 0, m_layerSize.width() + 1, m_layerSize.height() + 1));
+ layerContext->translate(m_layerContextTranslation);
+
+ return layerContext;
+}
+
+void ShadowBlur::endShadowLayer(GraphicsContext* graphicsContext)
+{
+ if (!m_layerImage)
+ return;
+
+ m_layerImage->context()->restore();
+
+ if (m_type == BlurShadow) {
+ IntRect blurRect = enclosingIntRect(FloatRect(FloatPoint(), m_layerSize));
+ RefPtr<ByteArray> layerData = m_layerImage->getUnmultipliedImageData(blurRect);
+ blurLayerImage(layerData->data(), blurRect.size(), blurRect.width() * 4);
+ m_layerImage->putUnmultipliedImageData(layerData.get(), blurRect.size(), blurRect, IntPoint());
+ }
+
+ graphicsContext->save();
+
+ IntSize bufferSize = m_layerImage->size();
+ if (bufferSize != m_layerSize) {
+ // The rect passed to clipToImageBuffer() has to be the size of the entire buffer,
+ // but we may not have cleared it all, so clip to the filled part first.
+ graphicsContext->clip(FloatRect(m_layerOrigin, m_layerSize));
+ }
+ graphicsContext->clipToImageBuffer(m_layerImage, FloatRect(m_layerOrigin, bufferSize));
+ graphicsContext->setFillColor(m_color, m_colorSpace);
+
+ graphicsContext->clearShadow();
+ graphicsContext->fillRect(FloatRect(m_layerOrigin, m_sourceRect.size()));
+
+ graphicsContext->restore();
+
+ m_layerImage = 0;
+
+ // Schedule a purge of the scratch buffer. We do not need to destroy the surface.
+ ScratchBuffer::shared().scheduleScratchBufferPurge();
+}
+
+static void computeSliceSizesFromRadii(int twiceRadius, const RoundedIntRect::Radii& radii, int& leftSlice, int& rightSlice, int& topSlice, int& bottomSlice)
+{
+ leftSlice = twiceRadius + max(radii.topLeft().width(), radii.bottomLeft().width());
+ rightSlice = twiceRadius + max(radii.topRight().width(), radii.bottomRight().width());
+
+ topSlice = twiceRadius + max(radii.topLeft().height(), radii.topRight().height());
+ bottomSlice = twiceRadius + max(radii.bottomLeft().height(), radii.bottomRight().height());
+}
+
+IntSize ShadowBlur::templateSize(const RoundedIntRect::Radii& radii) const
+{
+ const int templateSideLength = 1;
+
+ int leftSlice;
+ int rightSlice;
+ int topSlice;
+ int bottomSlice;
+ computeSliceSizesFromRadii(2 * ceilf(m_blurRadius), radii, leftSlice, rightSlice, topSlice, bottomSlice);
+
+ return IntSize(templateSideLength + leftSlice + rightSlice,
+ templateSideLength + topSlice + bottomSlice);
+}
+
+void ShadowBlur::drawRectShadow(GraphicsContext* graphicsContext, const FloatRect& shadowedRect, const RoundedIntRect::Radii& radii)
+{
+ IntRect layerRect = calculateLayerBoundingRect(graphicsContext, shadowedRect, graphicsContext->clipBounds());
+ if (layerRect.isEmpty())
+ return;
+
+ // drawRectShadowWithTiling does not work with rotations.
+ // https://bugs.webkit.org/show_bug.cgi?id=45042
+ if (!graphicsContext->getCTM().isIdentityOrTranslationOrFlipped() || m_type != BlurShadow) {
+ drawRectShadowWithoutTiling(graphicsContext, shadowedRect, radii, layerRect);
+ return;
+ }
+
+ IntSize templateSize = this->templateSize(radii);
+
+ if (templateSize.width() > shadowedRect.width() || templateSize.height() > shadowedRect.height()
+ || (templateSize.width() * templateSize.height() > m_sourceRect.width() * m_sourceRect.height())) {
+ drawRectShadowWithoutTiling(graphicsContext, shadowedRect, radii, layerRect);
+ return;
+ }
+
+ drawRectShadowWithTiling(graphicsContext, shadowedRect, radii, templateSize);
+}
+
+void ShadowBlur::drawInsetShadow(GraphicsContext* graphicsContext, const FloatRect& rect, const FloatRect& holeRect, const RoundedIntRect::Radii& holeRadii)
+{
+ IntRect layerRect = calculateLayerBoundingRect(graphicsContext, rect, graphicsContext->clipBounds());
+ if (layerRect.isEmpty())
+ return;
+
+ // drawInsetShadowWithTiling does not work with rotations.
+ // https://bugs.webkit.org/show_bug.cgi?id=45042
+ if (!graphicsContext->getCTM().isIdentityOrTranslationOrFlipped() || m_type != BlurShadow) {
+ drawInsetShadowWithoutTiling(graphicsContext, rect, holeRect, holeRadii, layerRect);
+ return;
+ }
+
+ IntSize templateSize = this->templateSize(holeRadii);
+
+ if (templateSize.width() > holeRect.width() || templateSize.height() > holeRect.height()
+ || (templateSize.width() * templateSize.height() > holeRect.width() * holeRect.height())) {
+ drawInsetShadowWithoutTiling(graphicsContext, rect, holeRect, holeRadii, layerRect);
+ return;
+ }
+
+ drawInsetShadowWithTiling(graphicsContext, rect, holeRect, holeRadii, templateSize);
+}
+
+void ShadowBlur::drawRectShadowWithoutTiling(GraphicsContext* graphicsContext, const FloatRect& shadowedRect, const RoundedIntRect::Radii& radii, const IntRect& layerRect)
+{
+ GraphicsContext* shadowContext = beginShadowLayer(graphicsContext, layerRect);
+ if (!shadowContext)
+ return;
+
+ Path path;
+ path.addRoundedRect(shadowedRect, radii.topLeft(), radii.topRight(), radii.bottomLeft(), radii.bottomRight());
+
+ shadowContext->setFillColor(Color::black, ColorSpaceDeviceRGB);
+ shadowContext->fillPath(path);
+
+ endShadowLayer(graphicsContext);
+}
+
+void ShadowBlur::drawInsetShadowWithoutTiling(GraphicsContext* graphicsContext, const FloatRect& rect, const FloatRect& holeRect, const RoundedIntRect::Radii& holeRadii, const IntRect& layerRect)
+{
+ GraphicsContext* shadowContext = beginShadowLayer(graphicsContext, layerRect);
+ if (!shadowContext)
+ return;
+
+ Path path;
+ path.addRect(rect);
+ path.addRoundedRect(holeRect, holeRadii.topLeft(), holeRadii.topRight(), holeRadii.bottomLeft(), holeRadii.bottomRight());
+
+ shadowContext->setFillRule(RULE_EVENODD);
+ shadowContext->setFillColor(Color::black, ColorSpaceDeviceRGB);
+ shadowContext->fillPath(path);
+
+ endShadowLayer(graphicsContext);
+}
+
+/*
+ These functions use tiling to improve the performance of the shadow
+ drawing of rounded rectangles. The code basically does the following
+ steps:
+
+ 1. Calculate the size of the shadow template, a rectangle that
+ contains all the necessary tiles to draw the complete shadow.
+
+ 2. If that size is smaller than the real rectangle render the new
+ template rectangle and its shadow in a new surface, in other case
+ render the shadow of the real rectangle in the destination
+ surface.
+
+ 3. Calculate the sizes and positions of the tiles and their
+ destinations and use drawPattern to render the final shadow. The
+ code divides the rendering in 8 tiles:
+
+ 1 | 2 | 3
+ -----------
+ 4 | | 5
+ -----------
+ 6 | 7 | 8
+
+ The corners are directly copied from the template rectangle to the
+ real one and the side tiles are 1 pixel width, we use them as
+ tiles to cover the destination side. The corner tiles are bigger
+ than just the side of the rounded corner, we need to increase it
+ because the modifications caused by the corner over the blur
+ effect. We fill the central or outer part with solid color to complete
+ the shadow.
+ */
+
+void ShadowBlur::drawInsetShadowWithTiling(GraphicsContext* graphicsContext, const FloatRect& rect, const FloatRect& holeRect, const RoundedIntRect::Radii& radii, const IntSize& templateSize)
+{
+ graphicsContext->save();
+ graphicsContext->clearShadow();
+
+ const float roundedRadius = ceilf(m_blurRadius);
+ const float twiceRadius = roundedRadius * 2;
+
+ m_layerImage = ScratchBuffer::shared().getScratchBuffer(templateSize);
+
+ // Draw the rectangle with hole.
+ FloatRect templateBounds(0, 0, templateSize.width(), templateSize.height());
+ FloatRect templateHole = FloatRect(roundedRadius, roundedRadius, templateSize.width() - twiceRadius, templateSize.height() - twiceRadius);
+ Path path;
+ path.addRect(templateBounds);
+ path.addRoundedRect(templateHole, radii.topLeft(), radii.topRight(), radii.bottomLeft(), radii.bottomRight());
+
+ // Draw shadow into a new ImageBuffer.
+ GraphicsContext* shadowContext = m_layerImage->context();
+ shadowContext->save();
+ shadowContext->clearRect(templateBounds);
+ shadowContext->setFillRule(RULE_EVENODD);
+ shadowContext->setFillColor(Color::black, ColorSpaceDeviceRGB);
+ shadowContext->fillPath(path);
+ blurAndColorShadowBuffer(templateSize);
+ shadowContext->restore();
+
+ FloatRect boundingRect = rect;
+ boundingRect.move(m_offset);
+
+ FloatRect destHoleRect = holeRect;
+ destHoleRect.move(m_offset);
+ FloatRect destHoleBounds = destHoleRect;
+ destHoleBounds.inflate(roundedRadius);
+
+ // Fill the external part of the shadow (which may be visible because of offset).
+ Path exteriorPath;
+ exteriorPath.addRect(boundingRect);
+ exteriorPath.addRect(destHoleBounds);
+
+ graphicsContext->save();
+ graphicsContext->setFillRule(RULE_EVENODD);
+ graphicsContext->setFillColor(m_color, m_colorSpace);
+ graphicsContext->fillPath(exteriorPath);
+ graphicsContext->restore();
+
+ drawLayerPieces(graphicsContext, destHoleBounds, radii, roundedRadius, templateSize, InnerShadow);
+
+ graphicsContext->restore();
+
+ m_layerImage = 0;
+ // Schedule a purge of the scratch buffer.
+ ScratchBuffer::shared().scheduleScratchBufferPurge();
+}
+
+void ShadowBlur::drawRectShadowWithTiling(GraphicsContext* graphicsContext, const FloatRect& shadowedRect, const RoundedIntRect::Radii& radii, const IntSize& templateSize)
+{
+ graphicsContext->save();
+ graphicsContext->clearShadow();
+
+ const float roundedRadius = ceilf(m_blurRadius);
+ const float twiceRadius = roundedRadius * 2;
+
+ m_layerImage = ScratchBuffer::shared().getScratchBuffer(templateSize);
+
+ // Draw the rectangle.
+ FloatRect templateShadow = FloatRect(roundedRadius, roundedRadius, templateSize.width() - twiceRadius, templateSize.height() - twiceRadius);
+ Path path;
+ path.addRoundedRect(templateShadow, radii.topLeft(), radii.topRight(), radii.bottomLeft(), radii.bottomRight());
+
+ // Draw shadow into the ImageBuffer.
+ GraphicsContext* shadowContext = m_layerImage->context();
+ shadowContext->save();
+ shadowContext->clearRect(FloatRect(0, 0, templateSize.width(), templateSize.height()));
+ shadowContext->setFillColor(Color::black, ColorSpaceDeviceRGB);
+ shadowContext->fillPath(path);
+ blurAndColorShadowBuffer(templateSize);
+ shadowContext->restore();
+
+ FloatRect shadowBounds = shadowedRect;
+ shadowBounds.move(m_offset.width(), m_offset.height());
+ shadowBounds.inflate(roundedRadius);
+
+ drawLayerPieces(graphicsContext, shadowBounds, radii, roundedRadius, templateSize, OuterShadow);
+
+ graphicsContext->restore();
+
+ m_layerImage = 0;
+ // Schedule a purge of the scratch buffer.
+ ScratchBuffer::shared().scheduleScratchBufferPurge();
+}
+
+void ShadowBlur::drawLayerPieces(GraphicsContext* graphicsContext, const FloatRect& shadowBounds, const RoundedIntRect::Radii& radii, float roundedRadius, const IntSize& templateSize, ShadowDirection direction)
+{
+ const float twiceRadius = roundedRadius * 2;
+
+ int leftSlice;
+ int rightSlice;
+ int topSlice;
+ int bottomSlice;
+ computeSliceSizesFromRadii(twiceRadius, radii, leftSlice, rightSlice, topSlice, bottomSlice);
+
+ int centerWidth = shadowBounds.width() - leftSlice - rightSlice;
+ int centerHeight = shadowBounds.height() - topSlice - bottomSlice;
+
+ if (direction == OuterShadow) {
+ FloatRect shadowInterior(shadowBounds.x() + leftSlice, shadowBounds.y() + topSlice, centerWidth, centerHeight);
+ if (!shadowInterior.isEmpty()) {
+ graphicsContext->save();
+
+ graphicsContext->setFillColor(m_color, m_colorSpace);
+ graphicsContext->fillRect(shadowInterior);
+
+ graphicsContext->restore();
+ }
+ }
+
+ // Note that drawing the ImageBuffer is faster than creating a Image and drawing that,
+ // because ImageBuffer::draw() knows that it doesn't have to copy the image bits.
+
+ // Top side.
+ FloatRect tileRect = FloatRect(leftSlice, 0, templateSideLength, topSlice);
+ FloatRect destRect = FloatRect(shadowBounds.x() + leftSlice, shadowBounds.y(), centerWidth, topSlice);
+ graphicsContext->drawImageBuffer(m_layerImage, ColorSpaceDeviceRGB, destRect, tileRect);
+
+ // Draw the bottom side.
+ tileRect.setY(templateSize.height() - bottomSlice);
+ tileRect.setHeight(bottomSlice);
+ destRect.setY(shadowBounds.maxY() - bottomSlice);
+ destRect.setHeight(bottomSlice);
+ graphicsContext->drawImageBuffer(m_layerImage, ColorSpaceDeviceRGB, destRect, tileRect);
+
+ // Left side.
+ tileRect = FloatRect(0, topSlice, leftSlice, templateSideLength);
+ destRect = FloatRect(shadowBounds.x(), shadowBounds.y() + topSlice, leftSlice, centerHeight);
+ graphicsContext->drawImageBuffer(m_layerImage, ColorSpaceDeviceRGB, destRect, tileRect);
+
+ // Right side.
+ tileRect.setX(templateSize.width() - rightSlice);
+ tileRect.setWidth(rightSlice);
+ destRect.setX(shadowBounds.maxX() - rightSlice);
+ destRect.setWidth(rightSlice);
+ graphicsContext->drawImageBuffer(m_layerImage, ColorSpaceDeviceRGB, destRect, tileRect);
+
+ // Top left corner.
+ tileRect = FloatRect(0, 0, leftSlice, topSlice);
+ destRect = FloatRect(shadowBounds.x(), shadowBounds.y(), leftSlice, topSlice);
+ graphicsContext->drawImageBuffer(m_layerImage, ColorSpaceDeviceRGB, destRect, tileRect);
+
+ // Top right corner.
+ tileRect = FloatRect(templateSize.width() - rightSlice, 0, rightSlice, topSlice);
+ destRect = FloatRect(shadowBounds.maxX() - rightSlice, shadowBounds.y(), rightSlice, topSlice);
+ graphicsContext->drawImageBuffer(m_layerImage, ColorSpaceDeviceRGB, destRect, tileRect);
+
+ // Bottom right corner.
+ tileRect = FloatRect(templateSize.width() - rightSlice, templateSize.height() - bottomSlice, rightSlice, bottomSlice);
+ destRect = FloatRect(shadowBounds.maxX() - rightSlice, shadowBounds.maxY() - bottomSlice, rightSlice, bottomSlice);
+ graphicsContext->drawImageBuffer(m_layerImage, ColorSpaceDeviceRGB, destRect, tileRect);
+
+ // Bottom left corner.
+ tileRect = FloatRect(0, templateSize.height() - bottomSlice, leftSlice, bottomSlice);
+ destRect = FloatRect(shadowBounds.x(), shadowBounds.maxY() - bottomSlice, leftSlice, bottomSlice);
+ graphicsContext->drawImageBuffer(m_layerImage, ColorSpaceDeviceRGB, destRect, tileRect);
+}
+
+
+void ShadowBlur::blurAndColorShadowBuffer(const IntSize& templateSize)
+{
+ {
+ IntRect blurRect(IntPoint(), templateSize);
+ RefPtr<ByteArray> layerData = m_layerImage->getUnmultipliedImageData(blurRect);
+ blurLayerImage(layerData->data(), blurRect.size(), blurRect.width() * 4);
+ m_layerImage->putUnmultipliedImageData(layerData.get(), blurRect.size(), blurRect, IntPoint());
+ }
+
+ // Mask the image with the shadow color.
+ GraphicsContext* shadowContext = m_layerImage->context();
+ shadowContext->setCompositeOperation(CompositeSourceIn);
+ shadowContext->setFillColor(m_color, m_colorSpace);
+ shadowContext->fillRect(FloatRect(0, 0, templateSize.width(), templateSize.height()));
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/ShadowBlur.h b/Source/WebCore/platform/graphics/ShadowBlur.h
new file mode 100644
index 0000000..e52d6dc
--- /dev/null
+++ b/Source/WebCore/platform/graphics/ShadowBlur.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2011 Apple Inc.
+ * Copyright (C) 2010 Sencha, Inc.
+ * Copyright (C) 2010 Igalia S.L.
+ * 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 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 ShadowBlur_h
+#define ShadowBlur_h
+
+#include "Color.h"
+#include "ColorSpace.h"
+#include "FloatRect.h"
+#include "RoundedIntRect.h"
+#include <wtf/Noncopyable.h>
+
+namespace WebCore {
+
+class AffineTransform;
+class GraphicsContext;
+class ImageBuffer;
+
+class ShadowBlur {
+ WTF_MAKE_NONCOPYABLE(ShadowBlur);
+public:
+ ShadowBlur(float radius, const FloatSize& offset, const Color&, ColorSpace);
+
+ void setShadowsIgnoreTransforms(bool ignoreTransforms) { m_shadowsIgnoreTransforms = ignoreTransforms; }
+ bool shadowsIgnoreTransforms() const { return m_shadowsIgnoreTransforms; }
+
+ void drawRectShadow(GraphicsContext*, const FloatRect&, const RoundedIntRect::Radii&);
+ void drawInsetShadow(GraphicsContext*, const FloatRect&, const FloatRect& holeRect, const RoundedIntRect::Radii& holeRadii);
+
+private:
+ GraphicsContext* beginShadowLayer(GraphicsContext*, const IntRect& layerRect);
+ void endShadowLayer(GraphicsContext*);
+
+ void adjustBlurRadius(GraphicsContext*);
+ void blurLayerImage(unsigned char*, const IntSize&, int stride);
+
+ enum ShadowDirection {
+ OuterShadow,
+ InnerShadow
+ };
+
+ IntRect calculateLayerBoundingRect(GraphicsContext*, const FloatRect& layerArea, const IntRect& clipRect);
+ IntSize templateSize(const RoundedIntRect::Radii&) const;
+
+ void drawRectShadowWithoutTiling(GraphicsContext*, const FloatRect&, const RoundedIntRect::Radii&, const IntRect& layerRect);
+ void drawRectShadowWithTiling(GraphicsContext*, const FloatRect&, const RoundedIntRect::Radii&, const IntSize& shadowTemplateSize);
+
+ void drawInsetShadowWithoutTiling(GraphicsContext*, const FloatRect&, const FloatRect& holeRect, const RoundedIntRect::Radii&, const IntRect& layerRect);
+ void drawInsetShadowWithTiling(GraphicsContext*, const FloatRect&, const FloatRect& holeRect, const RoundedIntRect::Radii&, const IntSize& shadowTemplateSize);
+
+ void drawLayerPieces(GraphicsContext*, const FloatRect& shadowBounds, const RoundedIntRect::Radii&, float roundedRadius, const IntSize& templateSize, ShadowDirection);
+
+ void blurAndColorShadowBuffer(const IntSize& templateSize);
+
+ enum ShadowType {
+ NoShadow,
+ SolidShadow,
+ BlurShadow
+ };
+
+ ShadowType m_type;
+
+ Color m_color;
+ ColorSpace m_colorSpace;
+ float m_blurRadius;
+ FloatSize m_offset;
+
+ ImageBuffer* m_layerImage; // Buffer to where the temporary shadow will be drawn to.
+
+ FloatRect m_sourceRect; // Sub-rect of m_layerImage that contains the shadow pixels.
+ FloatPoint m_layerOrigin; // Top-left corner of the (possibly clipped) bounding rect to draw the shadow to.
+ FloatSize m_layerSize; // Size of m_layerImage pixels that need blurring.
+ FloatSize m_layerContextTranslation; // Translation to apply to m_layerContext for the shadow to be correctly clipped.
+
+ bool m_shadowsIgnoreTransforms;
+};
+
+} // namespace WebCore
+
+#endif // ShadowBlur_h
diff --git a/Source/WebCore/platform/graphics/SimpleFontData.cpp b/Source/WebCore/platform/graphics/SimpleFontData.cpp
index e773880..2693609 100644
--- a/Source/WebCore/platform/graphics/SimpleFontData.cpp
+++ b/Source/WebCore/platform/graphics/SimpleFontData.cpp
@@ -50,7 +50,6 @@ namespace WebCore {
SimpleFontData::SimpleFontData(const FontPlatformData& platformData, bool isCustomFont, bool isLoading)
: m_maxCharWidth(-1)
, m_avgCharWidth(-1)
- , m_unitsPerEm(defaultUnitsPerEm)
, m_orientation(platformData.orientation())
, m_platformData(platformData)
, m_treatAsFixedPitch(false)
@@ -74,31 +73,36 @@ SimpleFontData::SimpleFontData(PassOwnPtr<SVGFontData> svgFontData, int size, bo
, m_isBrokenIdeographFont(false)
{
SVGFontFaceElement* svgFontFaceElement = m_svgFontData->svgFontFaceElement();
- m_unitsPerEm = svgFontFaceElement->unitsPerEm();
-
- double scale = size;
- if (m_unitsPerEm)
- scale /= m_unitsPerEm;
-
- m_ascent = static_cast<int>(svgFontFaceElement->ascent() * scale);
- m_descent = static_cast<int>(svgFontFaceElement->descent() * scale);
- m_xHeight = static_cast<int>(svgFontFaceElement->xHeight() * scale);
- m_lineGap = 0.1f * size;
- m_lineSpacing = m_ascent + m_descent + m_lineGap;
+ unsigned unitsPerEm = svgFontFaceElement->unitsPerEm();
+
+ float scale = size;
+ if (unitsPerEm)
+ scale /= unitsPerEm;
+
+ float xHeight = svgFontFaceElement->xHeight() * scale;
+ float ascent = svgFontFaceElement->ascent() * scale;
+ float descent = svgFontFaceElement->descent() * scale;
+ float lineGap = 0.1f * size;
+ m_fontMetrics.setUnitsPerEm(unitsPerEm);
+ m_fontMetrics.setAscent(ascent);
+ m_fontMetrics.setDescent(descent);
+ m_fontMetrics.setLineGap(lineGap);
+ m_fontMetrics.setLineSpacing(roundf(ascent) + roundf(descent) + roundf(lineGap));
+ m_fontMetrics.setXHeight(xHeight);
SVGFontElement* associatedFontElement = svgFontFaceElement->associatedFontElement();
Vector<SVGGlyphIdentifier> spaceGlyphs;
associatedFontElement->getGlyphIdentifiersForString(String(" ", 1), spaceGlyphs);
- m_spaceWidth = spaceGlyphs.isEmpty() ? m_xHeight : static_cast<float>(spaceGlyphs.first().horizontalAdvanceX * scale);
+ m_spaceWidth = spaceGlyphs.isEmpty() ? xHeight : spaceGlyphs.first().horizontalAdvanceX * scale;
Vector<SVGGlyphIdentifier> numeralZeroGlyphs;
associatedFontElement->getGlyphIdentifiersForString(String("0", 1), numeralZeroGlyphs);
- m_avgCharWidth = numeralZeroGlyphs.isEmpty() ? m_spaceWidth : static_cast<float>(numeralZeroGlyphs.first().horizontalAdvanceX * scale);
+ m_avgCharWidth = numeralZeroGlyphs.isEmpty() ? m_spaceWidth : numeralZeroGlyphs.first().horizontalAdvanceX * scale;
Vector<SVGGlyphIdentifier> letterWGlyphs;
associatedFontElement->getGlyphIdentifiersForString(String("W", 1), letterWGlyphs);
- m_maxCharWidth = letterWGlyphs.isEmpty() ? m_ascent : static_cast<float>(letterWGlyphs.first().horizontalAdvanceX * scale);
+ m_maxCharWidth = letterWGlyphs.isEmpty() ? ascent : letterWGlyphs.first().horizontalAdvanceX * scale;
// FIXME: is there a way we can get the space glyph from the SVGGlyphIdentifier above?
m_spaceGlyph = 0;
@@ -126,10 +130,10 @@ void SimpleFontData::initCharWidths()
// If we can't retrieve the width of a '0', fall back to the x height.
if (m_avgCharWidth <= 0.f)
- m_avgCharWidth = m_xHeight;
+ m_avgCharWidth = m_fontMetrics.xHeight();
if (m_maxCharWidth <= 0.f)
- m_maxCharWidth = max<float>(m_avgCharWidth, m_ascent);
+ m_maxCharWidth = max(m_avgCharWidth, m_fontMetrics.floatAscent());
}
void SimpleFontData::platformGlyphInit()
diff --git a/Source/WebCore/platform/graphics/SimpleFontData.h b/Source/WebCore/platform/graphics/SimpleFontData.h
index 90713af..07c2bd1 100644
--- a/Source/WebCore/platform/graphics/SimpleFontData.h
+++ b/Source/WebCore/platform/graphics/SimpleFontData.h
@@ -26,6 +26,7 @@
#include "FontBaseline.h"
#include "FontData.h"
+#include "FontMetrics.h"
#include "FontPlatformData.h"
#include "FloatRect.h"
#include "GlyphMetricsMap.h"
@@ -101,15 +102,9 @@ public:
// FIXME: Use the actual metrics for fonts with vertical tables instead of just hard-coding. If the font is horizontally oriented or
// a broken ideographic font, then just hard-code to split ascent/descent down the middle. Otherwise we should actually use the metrics
// from the font itself.
- int ascent(FontBaseline baselineType = AlphabeticBaseline) const { return baselineType == AlphabeticBaseline ? m_ascent : height() - height() / 2; }
- int descent(FontBaseline baselineType = AlphabeticBaseline) const { return baselineType == AlphabeticBaseline ? m_descent : height() / 2; }
- int height() const { return m_ascent + m_descent; }
- int lineSpacing() const { return m_lineSpacing; }
- int lineGap() const { return m_lineGap; }
+ const FontMetrics& fontMetrics() const { return m_fontMetrics; }
float maxCharWidth() const { return m_maxCharWidth; }
float avgCharWidth() const { return m_avgCharWidth; }
- float xHeight() const { return m_xHeight; }
- unsigned unitsPerEm() const { return m_unitsPerEm; }
FloatRect boundsForGlyph(Glyph) const;
float widthForGlyph(Glyph glyph) const;
@@ -211,14 +206,9 @@ private:
float widthForGDIGlyph(Glyph glyph) const;
#endif
- int m_ascent;
- int m_descent;
- int m_lineSpacing;
- int m_lineGap;
+ FontMetrics m_fontMetrics;
float m_maxCharWidth;
float m_avgCharWidth;
- float m_xHeight;
- unsigned m_unitsPerEm;
FontOrientation m_orientation; // This is our supported orientation according to the tables in the font. FontPlatformData will just always have the desired orientation.
// This value represents what we actually support.
diff --git a/Source/WebCore/platform/graphics/StringTruncator.cpp b/Source/WebCore/platform/graphics/StringTruncator.cpp
index 65325f0..8468188 100644
--- a/Source/WebCore/platform/graphics/StringTruncator.cpp
+++ b/Source/WebCore/platform/graphics/StringTruncator.cpp
@@ -29,12 +29,12 @@
#include "config.h"
#include "StringTruncator.h"
-#include "CharacterNames.h"
#include "Font.h"
#include "TextBreakIterator.h"
#include "TextRun.h"
#include <wtf/Assertions.h>
#include <wtf/Vector.h>
+#include <wtf/unicode/CharacterNames.h>
namespace WebCore {
diff --git a/Source/WebCore/platform/graphics/TextRun.h b/Source/WebCore/platform/graphics/TextRun.h
index dce5535..ef434bd 100644
--- a/Source/WebCore/platform/graphics/TextRun.h
+++ b/Source/WebCore/platform/graphics/TextRun.h
@@ -2,7 +2,7 @@
* Copyright (C) 2000 Lars Knoll (knoll@kde.org)
* (C) 2000 Antti Koivisto (koivisto@kde.org)
* (C) 2000 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2003, 2006, 2007 Apple Computer, Inc.
+ * Copyright (C) 2003, 2006, 2007, 2011 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -33,12 +33,18 @@ class RenderSVGResource;
class TextRun {
public:
- TextRun(const UChar* c, int len, bool allowTabs = false, int xpos = 0, int padding = 0, bool rtl = false, bool directionalOverride = false,
+ enum TrailingExpansionBehavior {
+ AllowTrailingExpansion,
+ ForbidTrailingExpansion
+ };
+
+ TextRun(const UChar* c, int len, bool allowTabs = false, int xpos = 0, int expansion = 0, TrailingExpansionBehavior trailingExpansionBehavior = AllowTrailingExpansion, bool rtl = false, bool directionalOverride = false,
bool applyRunRounding = true, bool applyWordRounding = true)
: m_characters(c)
, m_len(len)
, m_xpos(xpos)
- , m_padding(padding)
+ , m_expansion(expansion)
+ , m_trailingExpansionBehavior(trailingExpansionBehavior)
#if ENABLE(SVG)
, m_horizontalGlyphStretch(1)
#endif
@@ -55,12 +61,13 @@ public:
{
}
- TextRun(const String& s, bool allowTabs = false, int xpos = 0, int padding = 0, bool rtl = false, bool directionalOverride = false,
+ TextRun(const String& s, bool allowTabs = false, int xpos = 0, int expansion = 0, TrailingExpansionBehavior trailingExpansionBehavior = AllowTrailingExpansion, bool rtl = false, bool directionalOverride = false,
bool applyRunRounding = true, bool applyWordRounding = true)
: m_characters(s.characters())
, m_len(s.length())
, m_xpos(xpos)
- , m_padding(padding)
+ , m_expansion(expansion)
+ , m_trailingExpansionBehavior(trailingExpansionBehavior)
#if ENABLE(SVG)
, m_horizontalGlyphStretch(1)
#endif
@@ -92,7 +99,8 @@ public:
bool allowTabs() const { return m_allowTabs; }
int xPos() const { return m_xpos; }
- int padding() const { return m_padding; }
+ int expansion() const { return m_expansion; }
+ bool allowsTrailingExpansion() const { return m_trailingExpansionBehavior == AllowTrailingExpansion; }
bool rtl() const { return m_rtl; }
bool ltr() const { return !m_rtl; }
bool directionalOverride() const { return m_directionalOverride; }
@@ -121,7 +129,8 @@ private:
// start of the containing block. In the case of right alignment or center alignment, left start of
// the text line is not the same as left start of the containing block.
int m_xpos;
- int m_padding;
+ int m_expansion;
+ TrailingExpansionBehavior m_trailingExpansionBehavior;
#if ENABLE(SVG)
float m_horizontalGlyphStretch;
#endif
diff --git a/Source/WebCore/platform/graphics/TiledBackingStore.cpp b/Source/WebCore/platform/graphics/TiledBackingStore.cpp
index 1d6f237..f6921ef 100644
--- a/Source/WebCore/platform/graphics/TiledBackingStore.cpp
+++ b/Source/WebCore/platform/graphics/TiledBackingStore.cpp
@@ -73,8 +73,8 @@ void TiledBackingStore::invalidate(const IntRect& contentsDirtyRect)
{
IntRect dirtyRect(mapFromContents(contentsDirtyRect));
- Tile::Coordinate topLeft = tileCoordinateForPoint(dirtyRect.topLeft());
- Tile::Coordinate bottomRight = tileCoordinateForPoint(dirtyRect.bottomRight());
+ Tile::Coordinate topLeft = tileCoordinateForPoint(dirtyRect.location());
+ Tile::Coordinate bottomRight = tileCoordinateForPoint(IntPoint(dirtyRect.maxX(), dirtyRect.maxY()));
for (unsigned yCoordinate = topLeft.y(); yCoordinate <= bottomRight.y(); ++yCoordinate) {
for (unsigned xCoordinate = topLeft.x(); xCoordinate <= bottomRight.x(); ++xCoordinate) {
@@ -93,6 +93,8 @@ void TiledBackingStore::updateTileBuffers()
if (m_contentsFrozen)
return;
+ m_client->tiledBackingStorePaintBegin();
+
Vector<IntRect> paintedArea;
Vector<RefPtr<Tile> > dirtyTiles;
TileMap::iterator end = m_tiles.end();
@@ -104,10 +106,10 @@ void TiledBackingStore::updateTileBuffers()
paintedArea.append(mapToContents(it->second->rect()));
}
- if (dirtyTiles.isEmpty())
+ if (dirtyTiles.isEmpty()) {
+ m_client->tiledBackingStorePaintEnd(paintedArea);
return;
-
- m_client->tiledBackingStorePaintBegin();
+ }
// FIXME: In single threaded case, tile back buffers could be updated asynchronously
// one by one and then swapped to front in one go. This would minimize the time spent
@@ -132,8 +134,8 @@ void TiledBackingStore::paint(GraphicsContext* context, const IntRect& rect)
IntRect dirtyRect = mapFromContents(rect);
- Tile::Coordinate topLeft = tileCoordinateForPoint(dirtyRect.topLeft());
- Tile::Coordinate bottomRight = tileCoordinateForPoint(dirtyRect.bottomRight());
+ Tile::Coordinate topLeft = tileCoordinateForPoint(dirtyRect.location());
+ Tile::Coordinate bottomRight = tileCoordinateForPoint(IntPoint(dirtyRect.maxX(), dirtyRect.maxY()));
for (unsigned yCoordinate = topLeft.y(); yCoordinate <= bottomRight.y(); ++yCoordinate) {
for (unsigned xCoordinate = topLeft.x(); xCoordinate <= bottomRight.x(); ++xCoordinate) {
@@ -227,8 +229,8 @@ void TiledBackingStore::createTiles()
double shortestDistance = std::numeric_limits<double>::infinity();
Vector<Tile::Coordinate> tilesToCreate;
unsigned requiredTileCount = 0;
- Tile::Coordinate topLeft = tileCoordinateForPoint(coverRect.topLeft());
- Tile::Coordinate bottomRight = tileCoordinateForPoint(coverRect.bottomRight());
+ Tile::Coordinate topLeft = tileCoordinateForPoint(coverRect.location());
+ Tile::Coordinate bottomRight = tileCoordinateForPoint(IntPoint(coverRect.maxX(), coverRect.maxY()));
for (unsigned yCoordinate = topLeft.y(); yCoordinate <= bottomRight.y(); ++yCoordinate) {
for (unsigned xCoordinate = topLeft.x(); xCoordinate <= bottomRight.x(); ++xCoordinate) {
Tile::Coordinate currentCoordinate(xCoordinate, yCoordinate);
diff --git a/Source/WebCore/platform/graphics/WidthIterator.cpp b/Source/WebCore/platform/graphics/WidthIterator.cpp
index 412c86e..a1a88da 100644
--- a/Source/WebCore/platform/graphics/WidthIterator.cpp
+++ b/Source/WebCore/platform/graphics/WidthIterator.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003, 2006, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2006, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
* Copyright (C) 2008 Holger Hans Peter Freyther
*
* This library is free software; you can redistribute it and/or
@@ -47,6 +47,7 @@ WidthIterator::WidthIterator(const Font* font, const TextRun& run, HashSet<const
, m_end(run.length())
, m_currentCharacter(0)
, m_runWidthSoFar(0)
+ , m_isAfterExpansion(true)
, m_finalRoundingWidth(0)
, m_fallbackFonts(fallbackFonts)
, m_accountForGlyphBounds(accountForGlyphBounds)
@@ -58,20 +59,19 @@ WidthIterator::WidthIterator(const Font* font, const TextRun& run, HashSet<const
{
// If the padding is non-zero, count the number of spaces in the run
// and divide that by the padding for per space addition.
- m_padding = m_run.padding();
- if (!m_padding)
- m_padPerSpace = 0;
+ m_expansion = m_run.expansion();
+ if (!m_expansion)
+ m_expansionPerOpportunity = 0;
else {
- int numSpaces = 0;
- for (int i = 0; i < run.length(); i++) {
- if (Font::treatAsSpace(m_run[i]))
- numSpaces++;
- }
+ bool isAfterExpansion = true;
+ unsigned expansionOpportunityCount = Font::expansionOpportunityCount(m_run.characters(), m_end, m_run.ltr() ? LTR : RTL, isAfterExpansion);
+ if (isAfterExpansion && !m_run.allowsTrailingExpansion())
+ expansionOpportunityCount--;
- if (!numSpaces)
- m_padPerSpace = 0;
+ if (!expansionOpportunityCount)
+ m_expansionPerOpportunity = 0;
else
- m_padPerSpace = m_padding / numSpaces;
+ m_expansionPerOpportunity = m_expansion / expansionOpportunityCount;
}
}
@@ -84,7 +84,7 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer)
const UChar* cp = m_run.data(currentCharacter);
bool rtl = m_run.rtl();
- bool hasExtraSpacing = (m_font->letterSpacing() || m_font->wordSpacing() || m_padding) && !m_run.spacingDisabled();
+ bool hasExtraSpacing = (m_font->letterSpacing() || m_font->wordSpacing() || m_expansion) && !m_run.spacingDisabled();
float widthSinceLastRounding = m_runWidthSoFar;
m_runWidthSoFar = floorf(m_runWidthSoFar);
@@ -173,26 +173,34 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer)
if (width && m_font->letterSpacing())
width += m_font->letterSpacing();
- if (Font::treatAsSpace(c)) {
- // Account for padding. WebCore uses space padding to justify text.
- // We distribute the specified padding over the available spaces in the run.
- if (m_padding) {
- // Use left over padding if not evenly divisible by number of spaces.
- if (m_padding < m_padPerSpace) {
- width += m_padding;
- m_padding = 0;
- } else {
- float previousPadding = m_padding;
- m_padding -= m_padPerSpace;
- width += roundf(previousPadding) - roundf(m_padding);
+ static bool expandAroundIdeographs = Font::canExpandAroundIdeographsInComplexText();
+ bool treatAsSpace = Font::treatAsSpace(c);
+ if (treatAsSpace || (expandAroundIdeographs && Font::isCJKIdeographOrSymbol(c))) {
+ // Distribute the run's total expansion evenly over all expansion opportunities in the run.
+ if (m_expansion && (m_run.allowsTrailingExpansion() || (m_run.ltr() && currentCharacter + clusterLength < static_cast<size_t>(m_run.length()))
+ || (m_run.rtl() && currentCharacter))) {
+ float previousExpansion = m_expansion;
+ if (!treatAsSpace && !m_isAfterExpansion) {
+ // Take the expansion opportunity before this ideograph.
+ m_expansion -= m_expansionPerOpportunity;
+ int expansion = roundf(previousExpansion) - roundf(m_expansion);
+ m_runWidthSoFar += expansion;
+ if (glyphBuffer)
+ glyphBuffer->expandLastAdvance(expansion);
+ previousExpansion = m_expansion;
}
- }
+ m_expansion -= m_expansionPerOpportunity;
+ width += roundf(previousExpansion) - roundf(m_expansion);
+ m_isAfterExpansion = true;
+ } else
+ m_isAfterExpansion = false;
// Account for word spacing.
// We apply additional space between "words" by adding width to the space character.
- if (currentCharacter != 0 && !Font::treatAsSpace(cp[-1]) && m_font->wordSpacing())
+ if (treatAsSpace && currentCharacter && !Font::treatAsSpace(cp[-1]) && m_font->wordSpacing())
width += m_font->wordSpacing();
- }
+ } else
+ m_isAfterExpansion = false;
}
if (m_accountForGlyphBounds) {
@@ -247,9 +255,9 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer)
lastRoundingWidth = width - oldWidth;
if (m_accountForGlyphBounds) {
- m_maxGlyphBoundingBoxY = max(m_maxGlyphBoundingBoxY, bounds.bottom());
+ m_maxGlyphBoundingBoxY = max(m_maxGlyphBoundingBoxY, bounds.maxY());
m_minGlyphBoundingBoxY = min(m_minGlyphBoundingBoxY, bounds.y());
- m_lastGlyphOverflow = max<float>(0, bounds.right() - width);
+ m_lastGlyphOverflow = max<float>(0, bounds.maxX() - width);
}
}
@@ -260,13 +268,13 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer)
bool WidthIterator::advanceOneCharacter(float& width, GlyphBuffer* glyphBuffer)
{
- glyphBuffer->clear();
+ int oldSize = glyphBuffer->size();
advance(m_currentCharacter + 1, glyphBuffer);
float w = 0;
- for (int i = 0; i < glyphBuffer->size(); ++i)
+ for (int i = oldSize; i < glyphBuffer->size(); ++i)
w += glyphBuffer->advanceAt(i);
width = w;
- return !glyphBuffer->isEmpty();
+ return glyphBuffer->size() > oldSize;
}
UChar32 WidthIterator::normalizeVoicingMarks(int currentCharacter)
diff --git a/Source/WebCore/platform/graphics/WidthIterator.h b/Source/WebCore/platform/graphics/WidthIterator.h
index 8b3c067..2b4f051 100644
--- a/Source/WebCore/platform/graphics/WidthIterator.h
+++ b/Source/WebCore/platform/graphics/WidthIterator.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003, 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2006, 2008, 2011 Apple Inc. All rights reserved.
* Copyright (C) 2008 Holger Hans Peter Freyther
*
* This library is free software; you can redistribute it and/or
@@ -50,8 +50,9 @@ struct WidthIterator {
unsigned m_currentCharacter;
float m_runWidthSoFar;
- float m_padding;
- float m_padPerSpace;
+ float m_expansion;
+ float m_expansionPerOpportunity;
+ bool m_isAfterExpansion;
float m_finalRoundingWidth;
private:
diff --git a/Source/WebCore/platform/graphics/android/FontAndroid.cpp b/Source/WebCore/platform/graphics/android/FontAndroid.cpp
index 7fcad73..af2edc7 100644
--- a/Source/WebCore/platform/graphics/android/FontAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/FontAndroid.cpp
@@ -161,6 +161,11 @@ bool Font::canReturnFallbackFontsForComplexText()
return false;
}
+bool Font::canExpandAroundIdeographsInComplexText()
+{
+ return false;
+}
+
void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
const GlyphBuffer& glyphBuffer, int from, int numGlyphs,
const FloatPoint& point) const
@@ -918,7 +923,7 @@ void Font::drawComplexText(GraphicsContext* gc, TextRun const& run,
bool haveMultipleLayers = isCanvasMultiLayered(canvas);
TextRunWalker walker(run, point.x(), this);
walker.setWordAndLetterSpacing(wordSpacing(), letterSpacing());
- walker.setPadding(run.padding());
+ walker.setPadding(run.expansion());
while (walker.nextScriptRun()) {
if (fill) {
diff --git a/Source/WebCore/platform/graphics/android/FontCustomPlatformData.cpp b/Source/WebCore/platform/graphics/android/FontCustomPlatformData.cpp
index 4795d9e..7190f32 100644
--- a/Source/WebCore/platform/graphics/android/FontCustomPlatformData.cpp
+++ b/Source/WebCore/platform/graphics/android/FontCustomPlatformData.cpp
@@ -46,7 +46,7 @@ FontCustomPlatformData::~FontCustomPlatformData()
}
FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic,
- FontOrientation, FontRenderingMode)
+ FontOrientation, FontWidthVariant, FontRenderingMode)
{
// turn bold/italic into fakeBold/fakeItalic
if (m_typeface != NULL) {
diff --git a/Source/WebCore/platform/graphics/android/FontCustomPlatformData.h b/Source/WebCore/platform/graphics/android/FontCustomPlatformData.h
index b03afa9..f74abc5 100644
--- a/Source/WebCore/platform/graphics/android/FontCustomPlatformData.h
+++ b/Source/WebCore/platform/graphics/android/FontCustomPlatformData.h
@@ -28,6 +28,7 @@
#include "FontOrientation.h"
#include "FontRenderingMode.h"
+#include "FontWidthVariant.h"
#include <wtf/Forward.h>
#include <wtf/Noncopyable.h>
@@ -46,7 +47,7 @@ public:
SkTypeface* typeface() const { return m_typeface; }
- FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation, FontRenderingMode);
+ FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation, FontWidthVariant, FontRenderingMode);
static bool supportsFormat(const String&);
private:
diff --git a/Source/WebCore/platform/graphics/android/FontDataAndroid.cpp b/Source/WebCore/platform/graphics/android/FontDataAndroid.cpp
index 545dcf7..1f19b6d 100644
--- a/Source/WebCore/platform/graphics/android/FontDataAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/FontDataAndroid.cpp
@@ -43,22 +43,20 @@ namespace WebCore {
void SimpleFontData::platformInit()
{
SkPaint paint;
- SkPaint::FontMetrics metrics;
+ SkPaint::FontMetrics skiaFontMetrics;
m_platformData.setupPaint(&paint);
- (void)paint.getFontMetrics(&metrics);
-
- // use ceil instead of round to favor descent, given a lot of accidental
- // clipping of descenders (e.g. 14pt 'g') in textedit fields
- int d = SkScalarCeil(metrics.fDescent);
- int s = SkScalarRound(metrics.fDescent - metrics.fAscent);
- int a = s - d;
-
- m_ascent = a;
- m_descent = d;
- m_xHeight = SkScalarToFloat(-metrics.fAscent) * 0.56f; // hack I stole from the window's port
- m_lineSpacing = a + d;
- m_lineGap = SkScalarRound(metrics.fLeading);
+ paint.getFontMetrics(&skiaFontMetrics);
+
+ float d = SkScalarToFloat(skiaFontMetrics.fDescent);
+ float s = SkScalarToFloat(skiaFontMetrics.fDescent - skiaFontMetrics.fAscent);
+ float a = s - d;
+
+ m_fontMetrics.setAscent(a);
+ m_fontMetrics.setDescent(d);
+ m_fontMetrics.setXHeight(SkScalarToFloat(-skiaFontMetrics.fAscent) * 0.56f); // hack I stole from the window's port
+ m_fontMetrics.setLineSpacing(a + d);
+ m_fontMetrics.setLineGap(SkScalarToFloat(skiaFontMetrics.fLeading));
}
void SimpleFontData::platformCharWidthInit()
diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
index f46d335..966670d 100644
--- a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
+++ b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
@@ -229,7 +229,7 @@ void GLWebViewState::inval(const IntRect& rect)
rect.x(), rect.y(), rect.right(), rect.bottom());
}
} else {
- m_invalidateRegion.op(rect.x(), rect.y(), rect.right(), rect.bottom(), SkRegion::kUnion_Op);
+ m_invalidateRegion.op(rect.x(), rect.y(), rect.maxX(), rect.maxY(), SkRegion::kUnion_Op);
}
}
diff --git a/Source/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp b/Source/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp
index 888be5b..012c1a8 100644
--- a/Source/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp
@@ -115,7 +115,6 @@ struct ShadowRec {
class GraphicsContextPlatformPrivate {
public:
struct State {
- SkPath* path;
SkPathEffect* pathEffect;
float miterLimit;
float alpha;
@@ -133,8 +132,7 @@ public:
WTF::Vector<SkPath> antiAliasClipPaths;
State()
- : path(0) // Lazily allocated
- , pathEffect(0)
+ : pathEffect(0)
, miterLimit(4)
, alpha(1)
, strokeThickness(0) // Same as default in GraphicsContextPrivate.h
@@ -162,13 +160,11 @@ public:
, strokeColor(other.strokeColor)
, useAA(other.useAA)
{
- path = deepCopyPtr<SkPath>(other.path);
SkSafeRef(pathEffect);
}
~State()
{
- delete path;
SkSafeUnref(pathEffect);
}
@@ -273,26 +269,6 @@ public:
m_state->strokeThickness = f;
}
- void beginPath()
- {
- if (m_state->path)
- m_state->path->reset();
- }
-
- void addPath(const SkPath& other)
- {
- if (!m_state->path)
- m_state->path = new SkPath(other);
- else
- m_state->path->addPath(other);
- }
-
- // May return null
- SkPath* getPath() const
- {
- return m_state->path;
- }
-
void setupPaintCommon(SkPaint* paint) const
{
paint->setAntiAlias(m_state->useAA);
@@ -538,11 +514,6 @@ bool GraphicsContext::willStroke() const
return m_data->getState()->strokeColor;
}
-const SkPath* GraphicsContext::getCurrPath() const
-{
- return m_data->getState()->path;
-}
-
// Draws a filled rectangle with a stroked border.
void GraphicsContext::drawRect(const IntRect& rect)
{
@@ -909,12 +880,7 @@ void GraphicsContext::clipPath(const Path& pathToClip, WindRule clipRule)
if (paintingDisabled())
return;
- // FIXME: Be smarter about this.
- beginPath();
- addPath(pathToClip);
-
- const SkPath* oldPath = m_data->getPath();
- SkPath path(*oldPath);
+ SkPath path = *pathToClip.platformPath();
path.setFillType(clipRule == RULE_EVENODD ? SkPath::kEvenOdd_FillType : SkPath::kWinding_FillType);
GC2CANVAS(this)->clipPath(path);
}
@@ -1231,23 +1197,9 @@ AffineTransform GraphicsContext::getCTM() const
///////////////////////////////////////////////////////////////////////////////
-void GraphicsContext::beginPath()
-{
- m_data->beginPath();
-}
-
-void GraphicsContext::addPath(const Path& p)
-{
- m_data->addPath(*p.platformPath());
-}
-
void GraphicsContext::fillPath(const Path& pathToFill)
{
- // FIXME: Be smarter about this.
- beginPath();
- addPath(pathToFill);
-
- SkPath* path = m_data->getPath();
+ SkPath* path = pathToFill.platformPath();
if (paintingDisabled() || !path)
return;
@@ -1272,11 +1224,7 @@ void GraphicsContext::fillPath(const Path& pathToFill)
void GraphicsContext::strokePath(const Path& pathToStroke)
{
- // FIXME: Be smarter about this.
- beginPath();
- addPath(pathToStroke);
-
- const SkPath* path = m_data->getPath();
+ const SkPath* path = pathToStroke.platformPath();
if (paintingDisabled() || !path)
return;
diff --git a/Source/WebCore/platform/graphics/android/ImageBufferAndroid.cpp b/Source/WebCore/platform/graphics/android/ImageBufferAndroid.cpp
index 0a36051..5807f87 100644
--- a/Source/WebCore/platform/graphics/android/ImageBufferAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/ImageBufferAndroid.cpp
@@ -120,7 +120,7 @@ PassRefPtr<ByteArray> ImageBuffer::getUnmultipliedImageData(const IntRect& rect)
RefPtr<ByteArray> result = ByteArray::create(rect.width() * rect.height() * 4);
unsigned char* data = result->data();
- if (rect.x() < 0 || rect.y() < 0 || rect.right() > m_size.width() || rect.bottom() > m_size.height())
+ if (rect.x() < 0 || rect.y() < 0 || rect.maxX() > m_size.width() || rect.maxY() > m_size.height())
memset(data, 0, result->length());
int originx = rect.x();
@@ -189,7 +189,7 @@ void ImageBuffer::putUnmultipliedImageData(ByteArray* source, const IntSize& sou
ASSERT(originx >= 0);
ASSERT(originx <= sourceRect.right());
- int endx = destPoint.x() + sourceRect.right();
+ int endx = destPoint.x() + sourceRect.maxX();
ASSERT(endx <= m_size.width());
int numColumns = endx - destx;
@@ -201,7 +201,7 @@ void ImageBuffer::putUnmultipliedImageData(ByteArray* source, const IntSize& sou
ASSERT(originy >= 0);
ASSERT(originy <= sourceRect.bottom());
- int endy = destPoint.y() + sourceRect.bottom();
+ int endy = destPoint.y() + sourceRect.maxY();
ASSERT(endy <= m_size.height());
int numRows = endy - desty;
diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp
index c0fbf61..34c02e9 100644
--- a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp
@@ -600,7 +600,7 @@ void LayerAndroid::updateGLPositions(const TransformationMatrix& parentMatrix,
localMatrix.translate3d(originX + position.x(),
originY + position.y(),
anchorPointZ());
- localMatrix.multLeft(m_transform);
+ localMatrix.multiply(m_transform);
localMatrix.translate3d(-originX,
-originY,
-anchorPointZ());
@@ -648,7 +648,7 @@ void LayerAndroid::updateGLPositions(const TransformationMatrix& parentMatrix,
if (!m_childrenTransform.isIdentity()) {
localMatrix.translate(getSize().width() * 0.5f, getSize().height() * 0.5f);
- localMatrix.multLeft(m_childrenTransform);
+ localMatrix.multiply(m_childrenTransform);
localMatrix.translate(-getSize().width() * 0.5f, -getSize().height() * 0.5f);
}
for (int i = 0; i < count; i++)
diff --git a/Source/WebCore/platform/graphics/android/PathAndroid.cpp b/Source/WebCore/platform/graphics/android/PathAndroid.cpp
index e0d7171..ad345bb 100644
--- a/Source/WebCore/platform/graphics/android/PathAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/PathAndroid.cpp
@@ -285,35 +285,20 @@ void Path::transform(const AffineTransform& xform)
///////////////////////////////////////////////////////////////////////////////
-// Computes the bounding box for the stroke and style currently selected into
-// the given bounding box. This also takes into account the stroke width.
-static FloatRect boundingBoxForCurrentStroke(GraphicsContext* context)
-{
- const SkPath* path = context->getCurrPath();
- if (NULL == path) {
- return FloatRect();
- }
-
- SkPaint paint;
- context->setupStrokePaint(&paint);
- SkPath fillPath;
- paint.getFillPath(*path, &fillPath);
- const SkRect& r = fillPath.getBounds();
- return FloatRect(SkScalarToFloat(r.fLeft), SkScalarToFloat(r.fTop),
- SkScalarToFloat(r.width()), SkScalarToFloat(r.height()));
-}
-
FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier)
{
GraphicsContext* scratch = scratchContext();
scratch->save();
- scratch->beginPath();
- scratch->addPath(*this);
-
+
if (applier)
applier->strokeStyle(scratch);
-
- FloatRect r = boundingBoxForCurrentStroke(scratch);
+
+ SkPaint paint;
+ scratch->setupStrokePaint(&paint);
+ SkPath boundingPath;
+ paint.getFillPath(*platformPath(), &boundingPath);
+
+ FloatRect r = boundingPath.getBounds();
scratch->restore();
return r;
}
diff --git a/Source/WebCore/platform/graphics/android/PlatformGraphicsContext.h b/Source/WebCore/platform/graphics/android/PlatformGraphicsContext.h
index 0ce86d2..98fcc49 100644
--- a/Source/WebCore/platform/graphics/android/PlatformGraphicsContext.h
+++ b/Source/WebCore/platform/graphics/android/PlatformGraphicsContext.h
@@ -118,7 +118,7 @@ public:
state == WebCore::RenderSkinAndroid::kFocused)
return;
m_state = state;
- SkCanvas* canvas = m_picture->beginRecording(m_rect.right(), m_rect.bottom());
+ SkCanvas* canvas = m_picture->beginRecording(m_rect.maxX(), m_rect.maxY());
buttonSkin->draw(canvas, m_rect, state);
m_picture->endRecording();
}
diff --git a/Source/WebCore/platform/graphics/android/ShaderProgram.cpp b/Source/WebCore/platform/graphics/android/ShaderProgram.cpp
index 0117bc0..f2b2dc8 100644
--- a/Source/WebCore/platform/graphics/android/ShaderProgram.cpp
+++ b/Source/WebCore/platform/graphics/android/ShaderProgram.cpp
@@ -224,9 +224,7 @@ void ShaderProgram::setProjectionMatrix(SkRect& geometry)
TransformationMatrix scale;
scale.scale3d(geometry.width(), geometry.height(), 1.0);
- TransformationMatrix total = m_projectionMatrix;
- total.multLeft(translate);
- total.multLeft(scale);
+ TransformationMatrix total = m_projectionMatrix * translate * scale;
GLfloat projectionMatrix[16];
GLUtils::toGLMatrix(projectionMatrix, total);
@@ -264,14 +262,10 @@ void ShaderProgram::setViewRect(const IntRect& viewRect)
TransformationMatrix scale;
scale.scale3d(m_viewRect.width() * 0.5f, m_viewRect.height() * 0.5f, 1);
- m_documentToScreenMatrix = m_projectionMatrix;
- m_documentToScreenMatrix.multiply(translate);
- m_documentToScreenMatrix.multiply(scale);
+ m_documentToScreenMatrix = scale * translate * m_projectionMatrix;
- m_documentToInvScreenMatrix = m_projectionMatrix;
translate.scale3d(1, -1, 1);
- m_documentToInvScreenMatrix.multiply(translate);
- m_documentToInvScreenMatrix.multiply(scale);
+ m_documentToInvScreenMatrix = scale * translate * m_projectionMatrix;
}
// This function transform a clip rect extracted from the current layer
@@ -279,8 +273,7 @@ void ShaderProgram::setViewRect(const IntRect& viewRect)
FloatRect ShaderProgram::rectInScreenCoord(const TransformationMatrix& drawMatrix, const IntSize& size)
{
FloatRect srect(0, 0, size.width(), size.height());
- TransformationMatrix renderMatrix = drawMatrix;
- renderMatrix.multiply(m_documentToScreenMatrix);
+ TransformationMatrix renderMatrix = m_documentToScreenMatrix * drawMatrix;
return renderMatrix.mapRect(srect);
}
@@ -288,8 +281,7 @@ FloatRect ShaderProgram::rectInScreenCoord(const TransformationMatrix& drawMatri
FloatRect ShaderProgram::rectInInvScreenCoord(const TransformationMatrix& drawMatrix, const IntSize& size)
{
FloatRect srect(0, 0, size.width(), size.height());
- TransformationMatrix renderMatrix = drawMatrix;
- renderMatrix.multiply(m_documentToInvScreenMatrix);
+ TransformationMatrix renderMatrix = m_documentToInvScreenMatrix * drawMatrix;
return renderMatrix.mapRect(srect);
}
@@ -372,9 +364,9 @@ IntRect ShaderProgram::clippedRectWithViewport(const IntRect& rect, int margin)
float ShaderProgram::zValue(const TransformationMatrix& drawMatrix, float w, float h)
{
- TransformationMatrix renderMatrix = drawMatrix;
- renderMatrix.scale3d(w, h, 1);
- renderMatrix.multiply(m_projectionMatrix);
+ TransformationMatrix modifiedDrawMatrix = drawMatrix;
+ modifiedDrawMatrix.scale3d(w, h, 1);
+ TransformationMatrix renderMatrix = m_projectionMatrix * modifiedDrawMatrix;
FloatPoint3D point(0.5, 0.5, 0.0);
FloatPoint3D result = renderMatrix.mapPoint(point);
return result.z();
@@ -385,11 +377,11 @@ void ShaderProgram::drawLayerQuad(const TransformationMatrix& drawMatrix,
bool forceBlending)
{
- TransformationMatrix renderMatrix = drawMatrix;
+ TransformationMatrix modifiedDrawMatrix = drawMatrix;
// move the drawing depending on where the texture is on the layer
- renderMatrix.translate(geometry.fLeft, geometry.fTop);
- renderMatrix.scale3d(geometry.width(), geometry.height(), 1);
- renderMatrix.multiply(m_projectionMatrix);
+ modifiedDrawMatrix.translate(geometry.fLeft, geometry.fTop);
+ modifiedDrawMatrix.scale3d(geometry.width(), geometry.height(), 1);
+ TransformationMatrix renderMatrix = m_projectionMatrix * modifiedDrawMatrix;
GLfloat projectionMatrix[16];
GLUtils::toGLMatrix(projectionMatrix, renderMatrix);
@@ -414,10 +406,10 @@ void ShaderProgram::drawVideoLayerQuad(const TransformationMatrix& drawMatrix,
// switch to our custom yuv video rendering program
glUseProgram(m_videoProgram);
- TransformationMatrix renderMatrix = drawMatrix;
- renderMatrix.translate(geometry.fLeft, geometry.fTop);
- renderMatrix.scale3d(geometry.width(), geometry.height(), 1);
- renderMatrix.multiply(m_projectionMatrix);
+ TransformationMatrix modifiedDrawMatrix = drawMatrix;
+ modifiedDrawMatrix.translate(geometry.fLeft, geometry.fTop);
+ modifiedDrawMatrix.scale3d(geometry.width(), geometry.height(), 1);
+ TransformationMatrix renderMatrix = m_projectionMatrix * modifiedDrawMatrix;
GLfloat projectionMatrix[16];
GLUtils::toGLMatrix(projectionMatrix, renderMatrix);
diff --git a/Source/WebCore/platform/graphics/android/TiledPage.cpp b/Source/WebCore/platform/graphics/android/TiledPage.cpp
index 5212871..0e1e947 100644
--- a/Source/WebCore/platform/graphics/android/TiledPage.cpp
+++ b/Source/WebCore/platform/graphics/android/TiledPage.cpp
@@ -122,14 +122,14 @@ void TiledPage::invalidateRect(const IntRect& inval, const unsigned int pictureC
const int firstDirtyTileX = static_cast<int>(floorf(inval.x() * invTileContentWidth));
const int firstDirtyTileY = static_cast<int>(floorf(inval.y() * invTileContentHeight));
- const int lastDirtyTileX = static_cast<int>(ceilf(inval.right() * invTileContentWidth));
- const int lastDirtyTileY = static_cast<int>(ceilf(inval.bottom() * invTileContentHeight));
+ const int lastDirtyTileX = static_cast<int>(ceilf(inval.maxX() * invTileContentWidth));
+ const int lastDirtyTileY = static_cast<int>(ceilf(inval.maxY() * invTileContentHeight));
XLOG("Marking X %d-%d and Y %d-%d dirty", firstDirtyTileX, lastDirtyTileX, firstDirtyTileY, lastDirtyTileY);
// We defer marking the tile as dirty until the next time we need to prepare
// to draw.
m_invalRegion.op(firstDirtyTileX, firstDirtyTileY, lastDirtyTileX, lastDirtyTileY, SkRegion::kUnion_Op);
- m_invalTilesRegion.op(inval.x(), inval.y(), inval.right(), inval.bottom(), SkRegion::kUnion_Op);
+ m_invalTilesRegion.op(inval.x(), inval.y(), inval.maxX(), inval.maxY(), SkRegion::kUnion_Op);
m_latestPictureInval = pictureCount;
}
diff --git a/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp b/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp
index 01e25e9..2b4a39e 100644
--- a/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp
+++ b/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp
@@ -1507,7 +1507,7 @@ void GraphicsLayerCA::pauseCAAnimationOnLayer(AnimatedPropertyID property, const
return;
// Animations on the layer are immutable, so we have to clone and modify.
- RefPtr<PlatformCAAnimation> newAnim = PlatformCAAnimation::create(curAnim.get());
+ RefPtr<PlatformCAAnimation> newAnim = curAnim->copy();
newAnim->setSpeed(0);
newAnim->setTimeOffset(timeOffset);
@@ -1646,7 +1646,7 @@ void GraphicsLayerCA::setupAnimation(PlatformCAAnimation* propertyAnim, const An
float repeatCount = anim->iterationCount();
if (repeatCount == Animation::IterationCountInfinite)
- repeatCount = FLT_MAX;
+ repeatCount = numeric_limits<float>::max();
else if (anim->direction() == Animation::AnimationDirectionAlternate)
repeatCount /= 2;
diff --git a/Source/WebCore/platform/graphics/ca/PlatformCAAnimation.h b/Source/WebCore/platform/graphics/ca/PlatformCAAnimation.h
index 4bfce63..a8528fd 100644
--- a/Source/WebCore/platform/graphics/ca/PlatformCAAnimation.h
+++ b/Source/WebCore/platform/graphics/ca/PlatformCAAnimation.h
@@ -63,13 +63,14 @@ public:
enum ValueFunctionType { NoValueFunction, RotateX, RotateY, RotateZ, ScaleX, ScaleY, ScaleZ, Scale, TranslateX, TranslateY, TranslateZ, Translate };
static PassRefPtr<PlatformCAAnimation> create(AnimationType, const String& keyPath);
- static PassRefPtr<PlatformCAAnimation> create(PlatformAnimationRef animation);
- static PassRefPtr<PlatformCAAnimation> create(const PlatformCAAnimation* animation);
+ static PassRefPtr<PlatformCAAnimation> create(PlatformAnimationRef);
~PlatformCAAnimation();
static bool supportsValueFunction();
+ PassRefPtr<PlatformCAAnimation> copy() const;
+
PlatformAnimationRef platformAnimation() const;
AnimationType animationType() const { return m_type; }
@@ -136,8 +137,7 @@ public:
protected:
PlatformCAAnimation(AnimationType, const String& keyPath);
- PlatformCAAnimation(PlatformAnimationRef animation);
- PlatformCAAnimation(const PlatformCAAnimation* animation);
+ PlatformCAAnimation(PlatformAnimationRef);
private:
AnimationType m_type;
diff --git a/Source/WebCore/platform/graphics/ca/mac/PlatformCAAnimationMac.mm b/Source/WebCore/platform/graphics/ca/mac/PlatformCAAnimationMac.mm
index 2a00857..506bd40 100644
--- a/Source/WebCore/platform/graphics/ca/mac/PlatformCAAnimationMac.mm
+++ b/Source/WebCore/platform/graphics/ca/mac/PlatformCAAnimationMac.mm
@@ -159,11 +159,6 @@ PassRefPtr<PlatformCAAnimation> PlatformCAAnimation::create(PlatformAnimationRef
return adoptRef(new PlatformCAAnimation(animation));
}
-PassRefPtr<PlatformCAAnimation> PlatformCAAnimation::create(const PlatformCAAnimation* animation)
-{
- return adoptRef(new PlatformCAAnimation(animation));
-}
-
PlatformCAAnimation::PlatformCAAnimation(AnimationType type, const String& keyPath)
: m_type(type)
{
@@ -187,38 +182,36 @@ PlatformCAAnimation::PlatformCAAnimation(PlatformAnimationRef animation)
m_animation = static_cast<CAPropertyAnimation*>(animation);
}
-PlatformCAAnimation::PlatformCAAnimation(const PlatformCAAnimation* animation)
+PassRefPtr<PlatformCAAnimation> PlatformCAAnimation::copy() const
{
- PlatformCAAnimation* newAnimation = new PlatformCAAnimation(animation->animationType(), animation->keyPath());
-
- newAnimation->setBeginTime(animation->beginTime());
- newAnimation->setDuration(animation->duration());
- newAnimation->setSpeed(animation->speed());
- newAnimation->setTimeOffset(animation->timeOffset());
- newAnimation->setRepeatCount(animation->repeatCount());
- newAnimation->setAutoreverses(animation->autoreverses());
- newAnimation->setFillMode(animation->fillMode());
- newAnimation->setRemovedOnCompletion(animation->isRemovedOnCompletion());
- newAnimation->setAdditive(animation->isAdditive());
- newAnimation->copyTimingFunctionFrom(animation);
-
-#if HAVE_MODERN_QUARTZCORE
- newAnimation->setValueFunction(animation->valueFunction());
-#endif
-
- setNonZeroBeginTimeFlag(newAnimation, hasNonZeroBeginTimeFlag(animation));
+ RefPtr<PlatformCAAnimation> animation = create(animationType(), keyPath());
+
+ animation->setBeginTime(beginTime());
+ animation->setDuration(duration());
+ animation->setSpeed(speed());
+ animation->setTimeOffset(timeOffset());
+ animation->setRepeatCount(repeatCount());
+ animation->setAutoreverses(autoreverses());
+ animation->setFillMode(fillMode());
+ animation->setRemovedOnCompletion(isRemovedOnCompletion());
+ animation->setAdditive(isAdditive());
+ animation->copyTimingFunctionFrom(this);
+ animation->setValueFunction(valueFunction());
+
+ setNonZeroBeginTimeFlag(animation.get(), hasNonZeroBeginTimeFlag(this));
// Copy the specific Basic or Keyframe values
- if (animation->animationType() == Keyframe) {
- newAnimation->copyValuesFrom(animation);
- newAnimation->copyKeyTimesFrom(animation);
- newAnimation->copyTimingFunctionsFrom(animation);
+ if (animationType() == Keyframe) {
+ animation->copyValuesFrom(this);
+ animation->copyKeyTimesFrom(this);
+ animation->copyTimingFunctionsFrom(this);
} else {
- newAnimation->copyFromValueFrom(animation);
- newAnimation->copyToValueFrom(animation);
+ animation->copyFromValueFrom(this);
+ animation->copyToValueFrom(this);
}
+
+ return animation;
}
-
PlatformCAAnimation::~PlatformCAAnimation()
{
}
diff --git a/Source/WebCore/platform/graphics/ca/win/CACFLayerTreeHost.cpp b/Source/WebCore/platform/graphics/ca/win/CACFLayerTreeHost.cpp
index 1d27608..9dc30ea 100644
--- a/Source/WebCore/platform/graphics/ca/win/CACFLayerTreeHost.cpp
+++ b/Source/WebCore/platform/graphics/ca/win/CACFLayerTreeHost.cpp
@@ -28,49 +28,22 @@
#if USE(ACCELERATED_COMPOSITING)
+#include "CACFLayerTreeHostClient.h"
#include "LayerChangesFlusher.h"
+#include "LegacyCACFLayerTreeHost.h"
#include "PlatformCALayer.h"
+#include "WKCACFViewLayerTreeHost.h"
#include "WebCoreInstanceHandle.h"
-#include <WebKitSystemInterface/WebKitSystemInterface.h>
#include <limits.h>
#include <wtf/CurrentTime.h>
-#include <wtf/HashMap.h>
#include <wtf/OwnArrayPtr.h>
-#include <wtf/OwnPtr.h>
-#include <wtf/PassOwnPtr.h>
-#include <wtf/StdLibExtras.h>
-#ifndef NDEBUG
-#define D3D_DEBUG_INFO
-#endif
-
-#include <d3d9.h>
-#include <d3dx9.h>
-
-using namespace std;
-
-#pragma comment(lib, "d3d9")
-#pragma comment(lib, "d3dx9")
#ifdef DEBUG_ALL
#pragma comment(lib, "QuartzCore_debug")
#else
#pragma comment(lib, "QuartzCore")
#endif
-static IDirect3D9* s_d3d = 0;
-static IDirect3D9* d3d()
-{
- if (s_d3d)
- return s_d3d;
-
- if (!LoadLibrary(TEXT("d3d9.dll")))
- return 0;
-
- s_d3d = Direct3DCreate9(D3D_SDK_VERSION);
-
- return s_d3d;
-}
-
inline static CGRect winRectToCGRect(RECT rc)
{
return CGRectMake(rc.left, rc.top, (rc.right - rc.left), (rc.bottom - rc.top));
@@ -83,40 +56,6 @@ inline static CGRect winRectToCGRect(RECT rc, RECT relativeToRect)
namespace WebCore {
-static D3DPRESENT_PARAMETERS initialPresentationParameters()
-{
- D3DPRESENT_PARAMETERS parameters = {0};
- parameters.Windowed = TRUE;
- parameters.SwapEffect = D3DSWAPEFFECT_COPY;
- parameters.BackBufferCount = 1;
- parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
- parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
-
- return parameters;
-}
-
-// FIXME: <rdar://6507851> Share this code with CoreAnimation.
-static bool hardwareCapabilitiesIndicateCoreAnimationSupport(const D3DCAPS9& caps)
-{
- // CoreAnimation needs two or more texture units.
- if (caps.MaxTextureBlendStages < 2)
- return false;
-
- // CoreAnimation needs non-power-of-two textures.
- if ((caps.TextureCaps & D3DPTEXTURECAPS_POW2) && !(caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL))
- return false;
-
- // CoreAnimation needs vertex shader 2.0 or greater.
- if (D3DSHADER_VERSION_MAJOR(caps.VertexShaderVersion) < 2)
- return false;
-
- // CoreAnimation needs pixel shader 2.0 or greater.
- if (D3DSHADER_VERSION_MAJOR(caps.PixelShaderVersion) < 2)
- return false;
-
- return true;
-}
-
bool CACFLayerTreeHost::acceleratedCompositingAvailable()
{
static bool available;
@@ -158,7 +97,7 @@ bool CACFLayerTreeHost::acceleratedCompositingAvailable()
wcex.hInstance = WebCore::instanceHandle();
wcex.lpszClassName = L"CoreAnimationTesterWindowClass";
::RegisterClassEx(&wcex);
- HWND testWindow = ::CreateWindow(L"CoreAnimationTesterWindowClass", L"CoreAnimationTesterWindow", WS_POPUP, -500, -500, 0, 0, 0, 0, 0, 0);
+ HWND testWindow = ::CreateWindow(L"CoreAnimationTesterWindowClass", L"CoreAnimationTesterWindow", WS_POPUP, -500, -500, 20, 20, 0, 0, 0, 0);
if (!testWindow) {
available = false;
@@ -168,6 +107,7 @@ bool CACFLayerTreeHost::acceleratedCompositingAvailable()
RefPtr<CACFLayerTreeHost> host = CACFLayerTreeHost::create();
host->setWindow(testWindow);
available = host->createRenderer();
+ host->setWindow(0);
::DestroyWindow(testWindow);
return available;
@@ -177,22 +117,29 @@ PassRefPtr<CACFLayerTreeHost> CACFLayerTreeHost::create()
{
if (!acceleratedCompositingAvailable())
return 0;
- return adoptRef(new CACFLayerTreeHost());
+ RefPtr<CACFLayerTreeHost> host = WKCACFViewLayerTreeHost::create();
+ if (!host)
+ host = LegacyCACFLayerTreeHost::create();
+ host->initialize();
+ return host.release();
}
CACFLayerTreeHost::CACFLayerTreeHost()
: m_client(0)
- , m_mightBeAbleToCreateDeviceLater(true)
, m_rootLayer(PlatformCALayer::create(PlatformCALayer::LayerTypeRootLayer, 0))
- , m_context(wkCACFContextCreate())
, m_window(0)
- , m_renderTimer(this, &CACFLayerTreeHost::renderTimerFired)
- , m_mustResetLostDeviceBeforeRendering(false)
, m_shouldFlushPendingGraphicsLayerChanges(false)
, m_isFlushingLayerChanges(false)
+#if !ASSERT_DISABLED
+ , m_state(WindowNotSet)
+#endif
+{
+}
+
+void CACFLayerTreeHost::initialize()
{
// Point the CACFContext to this
- wkCACFContextSetUserData(m_context, this);
+ initializeContext(this, m_rootLayer.get());
// Under the root layer, we have a clipping layer to clip the content,
// that contains a scroll layer that we use for scrolling the content.
@@ -212,20 +159,11 @@ CACFLayerTreeHost::CACFLayerTreeHost()
m_rootLayer->setBackgroundColor(debugColor);
CGColorRelease(debugColor);
#endif
-
- if (m_context)
- wkCACFContextSetLayer(m_context, m_rootLayer->platformLayer());
-
-#ifndef NDEBUG
- char* printTreeFlag = getenv("CA_PRINT_TREE");
- m_printTree = printTreeFlag && atoi(printTreeFlag);
-#endif
}
CACFLayerTreeHost::~CACFLayerTreeHost()
{
- setWindow(0);
- wkCACFContextDestroy(m_context);
+ ASSERT_WITH_MESSAGE(m_state != WindowSet, "Must call setWindow(0) before destroying CACFLayerTreeHost");
}
void CACFLayerTreeHost::setWindow(HWND window)
@@ -233,13 +171,28 @@ void CACFLayerTreeHost::setWindow(HWND window)
if (window == m_window)
return;
+#if !ASSERT_DISABLED
+ switch (m_state) {
+ case WindowNotSet:
+ ASSERT_ARG(window, window);
+ ASSERT(!m_window);
+ m_state = WindowSet;
+ break;
+ case WindowSet:
+ ASSERT_ARG(window, !window);
+ ASSERT(m_window);
+ m_state = WindowCleared;
+ break;
+ case WindowCleared:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+#endif
+
if (m_window)
destroyRenderer();
m_window = window;
-
- if (m_window)
- createRenderer();
}
PlatformCALayer* CACFLayerTreeHost::rootLayer() const
@@ -275,109 +228,11 @@ void CACFLayerTreeHost::layerTreeDidChange()
LayerChangesFlusher::shared().flushPendingLayerChangesSoon(this);
}
-bool CACFLayerTreeHost::createRenderer()
-{
- if (m_d3dDevice || !m_mightBeAbleToCreateDeviceLater)
- return m_d3dDevice;
-
- m_mightBeAbleToCreateDeviceLater = false;
- D3DPRESENT_PARAMETERS parameters = initialPresentationParameters();
-
- if (!d3d() || !::IsWindow(m_window))
- return false;
-
- // D3D doesn't like to make back buffers for 0 size windows. We skirt this problem if we make the
- // passed backbuffer width and height non-zero. The window will necessarily get set to a non-zero
- // size eventually, and then the backbuffer size will get reset.
- RECT rect;
- GetClientRect(m_window, &rect);
-
- if (rect.left-rect.right == 0 || rect.bottom-rect.top == 0) {
- parameters.BackBufferWidth = 1;
- parameters.BackBufferHeight = 1;
- }
-
- D3DCAPS9 d3dCaps;
- if (FAILED(d3d()->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &d3dCaps)))
- return false;
-
- DWORD behaviorFlags = D3DCREATE_FPU_PRESERVE;
- if ((d3dCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) && d3dCaps.VertexProcessingCaps)
- behaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
- else
- behaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
-
- COMPtr<IDirect3DDevice9> device;
- if (FAILED(d3d()->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_window, behaviorFlags, &parameters, &device))) {
- // In certain situations (e.g., shortly after waking from sleep), Direct3DCreate9() will
- // return an IDirect3D9 for which IDirect3D9::CreateDevice will always fail. In case we
- // have one of these bad IDirect3D9s, get rid of it so we'll fetch a new one the next time
- // we want to call CreateDevice.
- s_d3d->Release();
- s_d3d = 0;
-
- // Even if we don't have a bad IDirect3D9, in certain situations (e.g., shortly after
- // waking from sleep), CreateDevice will fail, but will later succeed if called again.
- m_mightBeAbleToCreateDeviceLater = true;
-
- return false;
- }
-
- // Now that we've created the IDirect3DDevice9 based on the capabilities we
- // got from the IDirect3D9 global object, we requery the device for its
- // actual capabilities. The capabilities returned by the device can
- // sometimes be more complete, for example when using software vertex
- // processing.
- D3DCAPS9 deviceCaps;
- if (FAILED(device->GetDeviceCaps(&deviceCaps)))
- return false;
-
- if (!hardwareCapabilitiesIndicateCoreAnimationSupport(deviceCaps))
- return false;
-
- m_d3dDevice = device;
-
- initD3DGeometry();
-
- wkCACFContextSetD3DDevice(m_context, m_d3dDevice.get());
-
- if (IsWindow(m_window))
- m_rootLayer->setBounds(bounds());
-
- return true;
-}
-
void CACFLayerTreeHost::destroyRenderer()
{
- LayerChangesFlusher::shared().cancelPendingFlush(this);
-
- wkCACFContextSetLayer(m_context, 0);
-
- wkCACFContextSetD3DDevice(m_context, 0);
- m_d3dDevice = 0;
- if (s_d3d)
- s_d3d->Release();
-
- s_d3d = 0;
m_rootLayer = 0;
m_rootChildLayer = 0;
-
- m_mightBeAbleToCreateDeviceLater = true;
-}
-
-void CACFLayerTreeHost::resize()
-{
- if (!m_d3dDevice)
- return;
-
- // Resetting the device might fail here. But that's OK, because if it does it we will attempt to
- // reset the device the next time we try to render.
- resetDevice(ChangedWindowSize);
-
- if (m_rootLayer) {
- m_rootLayer->setBounds(bounds());
- wkCACFContextFlush(m_context);
- }
+ LayerChangesFlusher::shared().cancelPendingFlush(this);
}
static void getDirtyRects(HWND window, Vector<CGRect>& outRects)
@@ -398,7 +253,7 @@ static void getDirtyRects(HWND window, Vector<CGRect>& outRects)
}
DWORD dataSize = GetRegionData(region.get(), 0, 0);
- OwnArrayPtr<unsigned char> regionDataBuffer(new unsigned char[dataSize]);
+ OwnArrayPtr<unsigned char> regionDataBuffer = adoptArrayPtr(new unsigned char[dataSize]);
RGNDATA* regionData = reinterpret_cast<RGNDATA*>(regionDataBuffer.get());
if (!GetRegionData(region.get(), dataSize, regionData))
return;
@@ -410,120 +265,13 @@ static void getDirtyRects(HWND window, Vector<CGRect>& outRects)
outRects[i] = winRectToCGRect(*rect, clientRect);
}
-void CACFLayerTreeHost::renderTimerFired(Timer<CACFLayerTreeHost>*)
-{
- paint();
-}
-
void CACFLayerTreeHost::paint()
{
- createRenderer();
- if (!m_d3dDevice) {
- if (m_mightBeAbleToCreateDeviceLater)
- renderSoon();
- return;
- }
-
Vector<CGRect> dirtyRects;
getDirtyRects(m_window, dirtyRects);
render(dirtyRects);
}
-void CACFLayerTreeHost::render(const Vector<CGRect>& windowDirtyRects)
-{
- ASSERT(m_d3dDevice);
-
- if (m_mustResetLostDeviceBeforeRendering && !resetDevice(LostDevice)) {
- // We can't reset the device right now. Try again soon.
- renderSoon();
- return;
- }
-
- // All pending animations will have been started with the flush. Fire the animationStarted calls
- double currentTime = WTF::currentTime();
- double currentMediaTime = CACurrentMediaTime();
- double t = currentTime + wkCACFContextGetLastCommitTime(m_context) - currentMediaTime;
- ASSERT(t <= currentTime);
-
- HashSet<RefPtr<PlatformCALayer> >::iterator end = m_pendingAnimatedLayers.end();
- for (HashSet<RefPtr<PlatformCALayer> >::iterator it = m_pendingAnimatedLayers.begin(); it != end; ++it) {
- PlatformCALayerClient* owner = (*it)->owner();
- owner->platformCALayerAnimationStarted(t);
- }
-
- m_pendingAnimatedLayers.clear();
-
- CGRect bounds = this->bounds();
-
- // Give the renderer some space to use. This needs to be valid until the
- // wkCACFContextFinishUpdate() call below.
- char space[4096];
- if (!wkCACFContextBeginUpdate(m_context, space, sizeof(space), currentMediaTime, bounds, windowDirtyRects.data(), windowDirtyRects.size()))
- return;
-
- HRESULT err = S_OK;
- CFTimeInterval timeToNextRender = numeric_limits<CFTimeInterval>::infinity();
-
- do {
- // FIXME: don't need to clear dirty region if layer tree is opaque.
-
- WKCACFUpdateRectEnumerator* e = wkCACFContextCopyUpdateRectEnumerator(m_context);
- if (!e)
- break;
-
- Vector<D3DRECT, 64> rects;
- for (const CGRect* r = wkCACFUpdateRectEnumeratorNextRect(e); r; r = wkCACFUpdateRectEnumeratorNextRect(e)) {
- D3DRECT rect;
- rect.x1 = r->origin.x;
- rect.x2 = rect.x1 + r->size.width;
- rect.y1 = bounds.origin.y + bounds.size.height - (r->origin.y + r->size.height);
- rect.y2 = rect.y1 + r->size.height;
-
- rects.append(rect);
- }
- wkCACFUpdateRectEnumeratorRelease(e);
-
- timeToNextRender = wkCACFContextGetNextUpdateTime(m_context);
-
- if (rects.isEmpty())
- break;
-
- m_d3dDevice->Clear(rects.size(), rects.data(), D3DCLEAR_TARGET, 0, 1.0f, 0);
-
- m_d3dDevice->BeginScene();
- wkCACFContextRenderUpdate(m_context);
- m_d3dDevice->EndScene();
-
- err = m_d3dDevice->Present(0, 0, 0, 0);
-
- if (err == D3DERR_DEVICELOST) {
- wkCACFContextAddUpdateRect(m_context, bounds);
- if (!resetDevice(LostDevice)) {
- // We can't reset the device right now. Try again soon.
- renderSoon();
- return;
- }
- }
- } while (err == D3DERR_DEVICELOST);
-
- wkCACFContextFinishUpdate(m_context);
-
-#ifndef NDEBUG
- if (m_printTree)
- m_rootLayer->printTree();
-#endif
-
- // If timeToNextRender is not infinity, it means animations are running, so queue up to render again
- if (timeToNextRender != numeric_limits<CFTimeInterval>::infinity())
- renderSoon();
-}
-
-void CACFLayerTreeHost::renderSoon()
-{
- if (!m_renderTimer.isActive())
- m_renderTimer.startOneShot(0);
-}
-
void CACFLayerTreeHost::flushPendingGraphicsLayerChangesSoon()
{
m_shouldFlushPendingGraphicsLayerChanges = true;
@@ -545,75 +293,36 @@ void CACFLayerTreeHost::flushPendingLayerChangesNow()
}
// Flush changes stored up in PlatformCALayers to the context so they will be rendered.
- wkCACFContextFlush(m_context);
-
- renderSoon();
+ flushContext();
m_isFlushingLayerChanges = false;
}
-CGRect CACFLayerTreeHost::bounds() const
+void CACFLayerTreeHost::contextDidChange()
{
- RECT clientRect;
- GetClientRect(m_window, &clientRect);
-
- return winRectToCGRect(clientRect);
+ // All pending animations will have been started with the flush. Fire the animationStarted calls.
+ notifyAnimationsStarted();
}
-void CACFLayerTreeHost::initD3DGeometry()
+void CACFLayerTreeHost::notifyAnimationsStarted()
{
- ASSERT(m_d3dDevice);
-
- CGRect bounds = this->bounds();
-
- float x0 = bounds.origin.x;
- float y0 = bounds.origin.y;
- float x1 = x0 + bounds.size.width;
- float y1 = y0 + bounds.size.height;
+ double currentTime = WTF::currentTime();
+ double time = currentTime + lastCommitTime() - CACurrentMediaTime();
+ ASSERT(time <= currentTime);
- D3DXMATRIXA16 projection;
- D3DXMatrixOrthoOffCenterRH(&projection, x0, x1, y0, y1, -1.0f, 1.0f);
+ HashSet<RefPtr<PlatformCALayer> >::iterator end = m_pendingAnimatedLayers.end();
+ for (HashSet<RefPtr<PlatformCALayer> >::iterator it = m_pendingAnimatedLayers.begin(); it != end; ++it)
+ (*it)->animationStarted(time);
- m_d3dDevice->SetTransform(D3DTS_PROJECTION, &projection);
+ m_pendingAnimatedLayers.clear();
}
-bool CACFLayerTreeHost::resetDevice(ResetReason reason)
+CGRect CACFLayerTreeHost::bounds() const
{
- ASSERT(m_d3dDevice);
- ASSERT(m_context);
-
- HRESULT hr = m_d3dDevice->TestCooperativeLevel();
-
- if (hr == D3DERR_DEVICELOST || hr == D3DERR_DRIVERINTERNALERROR) {
- // The device cannot be reset at this time. Try again soon.
- m_mustResetLostDeviceBeforeRendering = true;
- return false;
- }
-
- m_mustResetLostDeviceBeforeRendering = false;
-
- if (reason == LostDevice && hr == D3D_OK) {
- // The device wasn't lost after all.
- return true;
- }
-
- // We can reset the device.
-
- // We have to release the context's D3D resrouces whenever we reset the IDirect3DDevice9 in order to
- // destroy any D3DPOOL_DEFAULT resources that Core Animation has allocated (e.g., textures used
- // for mask layers). See <http://msdn.microsoft.com/en-us/library/bb174425(v=VS.85).aspx>.
- wkCACFContextReleaseD3DResources(m_context);
-
- D3DPRESENT_PARAMETERS parameters = initialPresentationParameters();
- hr = m_d3dDevice->Reset(&parameters);
-
- // TestCooperativeLevel told us the device may be reset now, so we should
- // not be told here that the device is lost.
- ASSERT(hr != D3DERR_DEVICELOST);
-
- initD3DGeometry();
+ RECT clientRect;
+ GetClientRect(m_window, &clientRect);
- return true;
+ return winRectToCGRect(clientRect);
}
}
diff --git a/Source/WebCore/platform/graphics/ca/win/CACFLayerTreeHost.h b/Source/WebCore/platform/graphics/ca/win/CACFLayerTreeHost.h
index fc61f39..6d91a73 100644
--- a/Source/WebCore/platform/graphics/ca/win/CACFLayerTreeHost.h
+++ b/Source/WebCore/platform/graphics/ca/win/CACFLayerTreeHost.h
@@ -47,75 +47,59 @@ typedef struct CGImage* CGImageRef;
namespace WebCore {
+class CACFLayerTreeHostClient;
class PlatformCALayer;
-class CACFLayerTreeHostClient {
-public:
- virtual ~CACFLayerTreeHostClient() { }
- virtual void flushPendingGraphicsLayerChanges() { }
-};
-
-// FIXME: Currently there is a CACFLayerTreeHost for each WebView and each
-// has its own CARenderOGLContext and Direct3DDevice9, which is inefficient.
-// (https://bugs.webkit.org/show_bug.cgi?id=31855)
class CACFLayerTreeHost : public RefCounted<CACFLayerTreeHost> {
friend PlatformCALayer;
public:
static PassRefPtr<CACFLayerTreeHost> create();
- ~CACFLayerTreeHost();
+ virtual ~CACFLayerTreeHost();
static bool acceleratedCompositingAvailable();
void setClient(CACFLayerTreeHostClient* client) { m_client = client; }
void setRootChildLayer(PlatformCALayer*);
- void layerTreeDidChange();
void setWindow(HWND);
- void paint();
- void resize();
+ virtual void paint();
+ virtual void resize() = 0;
void flushPendingGraphicsLayerChangesSoon();
void flushPendingLayerChangesNow();
protected:
- PlatformCALayer* rootLayer() const;
- void addPendingAnimatedLayer(PassRefPtr<PlatformCALayer>);
-
-private:
CACFLayerTreeHost();
- bool createRenderer();
- void destroyRenderer();
- void renderSoon();
- void renderTimerFired(Timer<CACFLayerTreeHost>*);
-
CGRect bounds() const;
+ PlatformCALayer* rootLayer() const;
+ HWND window() const { return m_window; }
+ void notifyAnimationsStarted();
- void initD3DGeometry();
+ virtual bool createRenderer() = 0;
+ virtual void destroyRenderer();
+ virtual void contextDidChange();
- // Call this when the device window has changed size or when IDirect3DDevice9::Present returns
- // D3DERR_DEVICELOST. Returns true if the device was recovered, false if rendering must be
- // aborted and reattempted soon.
- enum ResetReason { ChangedWindowSize, LostDevice };
- bool resetDevice(ResetReason);
+private:
+ void initialize();
+ void addPendingAnimatedLayer(PassRefPtr<PlatformCALayer>);
+ void layerTreeDidChange();
- void render(const Vector<CGRect>& dirtyRects = Vector<CGRect>());
+ virtual void flushContext() = 0;
+ virtual CFTimeInterval lastCommitTime() const = 0;
+ virtual void render(const Vector<CGRect>& dirtyRects = Vector<CGRect>()) = 0;
+ virtual void initializeContext(void* userData, PlatformCALayer*) = 0;
CACFLayerTreeHostClient* m_client;
- bool m_mightBeAbleToCreateDeviceLater;
- COMPtr<IDirect3DDevice9> m_d3dDevice;
RefPtr<PlatformCALayer> m_rootLayer;
RefPtr<PlatformCALayer> m_rootChildLayer;
- WKCACFContext* m_context;
+ HashSet<RefPtr<PlatformCALayer> > m_pendingAnimatedLayers;
HWND m_window;
- Timer<CACFLayerTreeHost> m_renderTimer;
- bool m_mustResetLostDeviceBeforeRendering;
bool m_shouldFlushPendingGraphicsLayerChanges;
bool m_isFlushingLayerChanges;
- HashSet<RefPtr<PlatformCALayer> > m_pendingAnimatedLayers;
-#ifndef NDEBUG
- bool m_printTree;
+#if !ASSERT_DISABLED
+ enum { WindowNotSet, WindowSet, WindowCleared } m_state;
#endif
};
diff --git a/Source/WebCore/platform/graphics/ca/win/CACFLayerTreeHostClient.h b/Source/WebCore/platform/graphics/ca/win/CACFLayerTreeHostClient.h
new file mode 100644
index 0000000..845f934
--- /dev/null
+++ b/Source/WebCore/platform/graphics/ca/win/CACFLayerTreeHostClient.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2011 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 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 CACFLayerTreeHostClient_h
+#define CACFLayerTreeHostClient_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+namespace WebCore {
+
+class CACFLayerTreeHostClient {
+public:
+ virtual ~CACFLayerTreeHostClient() { }
+ virtual void flushPendingGraphicsLayerChanges() { }
+};
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
+#endif // CACFLayerTreeHostClient_h
diff --git a/Source/WebCore/platform/graphics/ca/win/LegacyCACFLayerTreeHost.cpp b/Source/WebCore/platform/graphics/ca/win/LegacyCACFLayerTreeHost.cpp
new file mode 100644
index 0000000..772244b
--- /dev/null
+++ b/Source/WebCore/platform/graphics/ca/win/LegacyCACFLayerTreeHost.cpp
@@ -0,0 +1,401 @@
+/*
+ * Copyright (C) 2011 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 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 "LegacyCACFLayerTreeHost.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "PlatformCALayer.h"
+#include <WebKitSystemInterface/WebKitSystemInterface.h>
+
+#ifndef NDEBUG
+#define D3D_DEBUG_INFO
+#endif
+
+#include <d3d9.h>
+#include <d3dx9.h>
+
+#pragma comment(lib, "d3d9")
+#pragma comment(lib, "d3dx9")
+
+using namespace std;
+
+namespace WebCore {
+
+static IDirect3D9* s_d3d = 0;
+static IDirect3D9* d3d()
+{
+ if (s_d3d)
+ return s_d3d;
+
+ if (!LoadLibrary(TEXT("d3d9.dll")))
+ return 0;
+
+ s_d3d = Direct3DCreate9(D3D_SDK_VERSION);
+
+ return s_d3d;
+}
+
+static D3DPRESENT_PARAMETERS initialPresentationParameters()
+{
+ D3DPRESENT_PARAMETERS parameters = {0};
+ parameters.Windowed = TRUE;
+ parameters.SwapEffect = D3DSWAPEFFECT_COPY;
+ parameters.BackBufferCount = 1;
+ parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
+ parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
+
+ return parameters;
+}
+
+// FIXME: <rdar://6507851> Share this code with CoreAnimation.
+static bool hardwareCapabilitiesIndicateCoreAnimationSupport(const D3DCAPS9& caps)
+{
+ // CoreAnimation needs two or more texture units.
+ if (caps.MaxTextureBlendStages < 2)
+ return false;
+
+ // CoreAnimation needs non-power-of-two textures.
+ if ((caps.TextureCaps & D3DPTEXTURECAPS_POW2) && !(caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL))
+ return false;
+
+ // CoreAnimation needs vertex shader 2.0 or greater.
+ if (D3DSHADER_VERSION_MAJOR(caps.VertexShaderVersion) < 2)
+ return false;
+
+ // CoreAnimation needs pixel shader 2.0 or greater.
+ if (D3DSHADER_VERSION_MAJOR(caps.PixelShaderVersion) < 2)
+ return false;
+
+ return true;
+}
+
+PassRefPtr<LegacyCACFLayerTreeHost> LegacyCACFLayerTreeHost::create()
+{
+ return adoptRef(new LegacyCACFLayerTreeHost);
+}
+
+LegacyCACFLayerTreeHost::LegacyCACFLayerTreeHost()
+ : m_renderTimer(this, &LegacyCACFLayerTreeHost::renderTimerFired)
+ , m_context(wkCACFContextCreate())
+ , m_mightBeAbleToCreateDeviceLater(true)
+ , m_mustResetLostDeviceBeforeRendering(false)
+{
+#ifndef NDEBUG
+ char* printTreeFlag = getenv("CA_PRINT_TREE");
+ m_printTree = printTreeFlag && atoi(printTreeFlag);
+#endif
+}
+
+LegacyCACFLayerTreeHost::~LegacyCACFLayerTreeHost()
+{
+ wkCACFContextDestroy(m_context);
+}
+
+void LegacyCACFLayerTreeHost::initializeContext(void* userData, PlatformCALayer* layer)
+{
+ wkCACFContextSetUserData(m_context, userData);
+ wkCACFContextSetLayer(m_context, layer->platformLayer());
+}
+
+bool LegacyCACFLayerTreeHost::createRenderer()
+{
+ if (m_d3dDevice || !m_mightBeAbleToCreateDeviceLater)
+ return m_d3dDevice;
+
+ m_mightBeAbleToCreateDeviceLater = false;
+ D3DPRESENT_PARAMETERS parameters = initialPresentationParameters();
+
+ if (!d3d() || !::IsWindow(window()))
+ return false;
+
+ // D3D doesn't like to make back buffers for 0 size windows. We skirt this problem if we make the
+ // passed backbuffer width and height non-zero. The window will necessarily get set to a non-zero
+ // size eventually, and then the backbuffer size will get reset.
+ RECT rect;
+ GetClientRect(window(), &rect);
+
+ if (rect.left-rect.right == 0 || rect.bottom-rect.top == 0) {
+ parameters.BackBufferWidth = 1;
+ parameters.BackBufferHeight = 1;
+ }
+
+ D3DCAPS9 d3dCaps;
+ if (FAILED(d3d()->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &d3dCaps)))
+ return false;
+
+ DWORD behaviorFlags = D3DCREATE_FPU_PRESERVE;
+ if ((d3dCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) && d3dCaps.VertexProcessingCaps)
+ behaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
+ else
+ behaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
+
+ COMPtr<IDirect3DDevice9> device;
+ if (FAILED(d3d()->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window(), behaviorFlags, &parameters, &device))) {
+ // In certain situations (e.g., shortly after waking from sleep), Direct3DCreate9() will
+ // return an IDirect3D9 for which IDirect3D9::CreateDevice will always fail. In case we
+ // have one of these bad IDirect3D9s, get rid of it so we'll fetch a new one the next time
+ // we want to call CreateDevice.
+ s_d3d->Release();
+ s_d3d = 0;
+
+ // Even if we don't have a bad IDirect3D9, in certain situations (e.g., shortly after
+ // waking from sleep), CreateDevice will fail, but will later succeed if called again.
+ m_mightBeAbleToCreateDeviceLater = true;
+
+ return false;
+ }
+
+ // Now that we've created the IDirect3DDevice9 based on the capabilities we
+ // got from the IDirect3D9 global object, we requery the device for its
+ // actual capabilities. The capabilities returned by the device can
+ // sometimes be more complete, for example when using software vertex
+ // processing.
+ D3DCAPS9 deviceCaps;
+ if (FAILED(device->GetDeviceCaps(&deviceCaps)))
+ return false;
+
+ if (!hardwareCapabilitiesIndicateCoreAnimationSupport(deviceCaps))
+ return false;
+
+ m_d3dDevice = device;
+
+ initD3DGeometry();
+
+ wkCACFContextSetD3DDevice(m_context, m_d3dDevice.get());
+
+ if (IsWindow(window())) {
+ rootLayer()->setBounds(bounds());
+ flushContext();
+ }
+
+ return true;
+}
+
+void LegacyCACFLayerTreeHost::destroyRenderer()
+{
+ wkCACFContextSetLayer(m_context, 0);
+
+ wkCACFContextSetD3DDevice(m_context, 0);
+ m_d3dDevice = 0;
+ if (s_d3d)
+ s_d3d->Release();
+
+ s_d3d = 0;
+ m_mightBeAbleToCreateDeviceLater = true;
+
+ CACFLayerTreeHost::destroyRenderer();
+}
+
+void LegacyCACFLayerTreeHost::resize()
+{
+ if (!m_d3dDevice)
+ return;
+
+ // Resetting the device might fail here. But that's OK, because if it does it we will attempt to
+ // reset the device the next time we try to render.
+ resetDevice(ChangedWindowSize);
+
+ if (rootLayer()) {
+ rootLayer()->setBounds(bounds());
+ flushContext();
+ }
+}
+
+void LegacyCACFLayerTreeHost::renderTimerFired(Timer<LegacyCACFLayerTreeHost>*)
+{
+ paint();
+}
+
+void LegacyCACFLayerTreeHost::paint()
+{
+ createRenderer();
+ if (!m_d3dDevice) {
+ if (m_mightBeAbleToCreateDeviceLater)
+ renderSoon();
+ return;
+ }
+
+ CACFLayerTreeHost::paint();
+}
+
+void LegacyCACFLayerTreeHost::render(const Vector<CGRect>& windowDirtyRects)
+{
+ ASSERT(m_d3dDevice);
+
+ if (m_mustResetLostDeviceBeforeRendering && !resetDevice(LostDevice)) {
+ // We can't reset the device right now. Try again soon.
+ renderSoon();
+ return;
+ }
+
+ CGRect bounds = this->bounds();
+
+ // Give the renderer some space to use. This needs to be valid until the
+ // wkCACFContextFinishUpdate() call below.
+ char space[4096];
+ if (!wkCACFContextBeginUpdate(m_context, space, sizeof(space), CACurrentMediaTime(), bounds, windowDirtyRects.data(), windowDirtyRects.size()))
+ return;
+
+ HRESULT err = S_OK;
+ CFTimeInterval timeToNextRender = numeric_limits<CFTimeInterval>::infinity();
+
+ do {
+ // FIXME: don't need to clear dirty region if layer tree is opaque.
+
+ WKCACFUpdateRectEnumerator* e = wkCACFContextCopyUpdateRectEnumerator(m_context);
+ if (!e)
+ break;
+
+ Vector<D3DRECT, 64> rects;
+ for (const CGRect* r = wkCACFUpdateRectEnumeratorNextRect(e); r; r = wkCACFUpdateRectEnumeratorNextRect(e)) {
+ D3DRECT rect;
+ rect.x1 = r->origin.x;
+ rect.x2 = rect.x1 + r->size.width;
+ rect.y1 = bounds.origin.y + bounds.size.height - (r->origin.y + r->size.height);
+ rect.y2 = rect.y1 + r->size.height;
+
+ rects.append(rect);
+ }
+ wkCACFUpdateRectEnumeratorRelease(e);
+
+ timeToNextRender = wkCACFContextGetNextUpdateTime(m_context);
+
+ if (rects.isEmpty())
+ break;
+
+ m_d3dDevice->Clear(rects.size(), rects.data(), D3DCLEAR_TARGET, 0, 1.0f, 0);
+
+ m_d3dDevice->BeginScene();
+ wkCACFContextRenderUpdate(m_context);
+ m_d3dDevice->EndScene();
+
+ err = m_d3dDevice->Present(0, 0, 0, 0);
+
+ if (err == D3DERR_DEVICELOST) {
+ wkCACFContextAddUpdateRect(m_context, bounds);
+ if (!resetDevice(LostDevice)) {
+ // We can't reset the device right now. Try again soon.
+ renderSoon();
+ return;
+ }
+ }
+ } while (err == D3DERR_DEVICELOST);
+
+ wkCACFContextFinishUpdate(m_context);
+
+#ifndef NDEBUG
+ if (m_printTree)
+ rootLayer()->printTree();
+#endif
+
+ // If timeToNextRender is not infinity, it means animations are running, so queue up to render again
+ if (timeToNextRender != numeric_limits<CFTimeInterval>::infinity())
+ renderSoon();
+}
+
+void LegacyCACFLayerTreeHost::renderSoon()
+{
+ if (!m_renderTimer.isActive())
+ m_renderTimer.startOneShot(0);
+}
+
+void LegacyCACFLayerTreeHost::flushContext()
+{
+ wkCACFContextFlush(m_context);
+ contextDidChange();
+}
+
+void LegacyCACFLayerTreeHost::contextDidChange()
+{
+ renderSoon();
+ CACFLayerTreeHost::contextDidChange();
+}
+
+CFTimeInterval LegacyCACFLayerTreeHost::lastCommitTime() const
+{
+ return wkCACFContextGetLastCommitTime(m_context);
+}
+
+void LegacyCACFLayerTreeHost::initD3DGeometry()
+{
+ ASSERT(m_d3dDevice);
+
+ CGRect bounds = this->bounds();
+
+ float x0 = bounds.origin.x;
+ float y0 = bounds.origin.y;
+ float x1 = x0 + bounds.size.width;
+ float y1 = y0 + bounds.size.height;
+
+ D3DXMATRIXA16 projection;
+ D3DXMatrixOrthoOffCenterRH(&projection, x0, x1, y0, y1, -1.0f, 1.0f);
+
+ m_d3dDevice->SetTransform(D3DTS_PROJECTION, &projection);
+}
+
+bool LegacyCACFLayerTreeHost::resetDevice(ResetReason reason)
+{
+ ASSERT(m_d3dDevice);
+ ASSERT(m_context);
+
+ HRESULT hr = m_d3dDevice->TestCooperativeLevel();
+
+ if (hr == D3DERR_DEVICELOST || hr == D3DERR_DRIVERINTERNALERROR) {
+ // The device cannot be reset at this time. Try again soon.
+ m_mustResetLostDeviceBeforeRendering = true;
+ return false;
+ }
+
+ m_mustResetLostDeviceBeforeRendering = false;
+
+ if (reason == LostDevice && hr == D3D_OK) {
+ // The device wasn't lost after all.
+ return true;
+ }
+
+ // We can reset the device.
+
+ // We have to release the context's D3D resrouces whenever we reset the IDirect3DDevice9 in order to
+ // destroy any D3DPOOL_DEFAULT resources that Core Animation has allocated (e.g., textures used
+ // for mask layers). See <http://msdn.microsoft.com/en-us/library/bb174425(v=VS.85).aspx>.
+ wkCACFContextReleaseD3DResources(m_context);
+
+ D3DPRESENT_PARAMETERS parameters = initialPresentationParameters();
+ hr = m_d3dDevice->Reset(&parameters);
+
+ // TestCooperativeLevel told us the device may be reset now, so we should
+ // not be told here that the device is lost.
+ ASSERT(hr != D3DERR_DEVICELOST);
+
+ initD3DGeometry();
+
+ return true;
+}
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/ca/win/LegacyCACFLayerTreeHost.h b/Source/WebCore/platform/graphics/ca/win/LegacyCACFLayerTreeHost.h
new file mode 100644
index 0000000..bfa530b
--- /dev/null
+++ b/Source/WebCore/platform/graphics/ca/win/LegacyCACFLayerTreeHost.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2011 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 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 LegacyCACFLayerTreeHost_h
+#define LegacyCACFLayerTreeHost_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "CACFLayerTreeHost.h"
+
+namespace WebCore {
+
+// FIXME: Currently there is a LegacyCACFLayerTreeHost for each WebView and each
+// has its own WKCACFContext and Direct3DDevice9, which is inefficient.
+// (https://bugs.webkit.org/show_bug.cgi?id=31855)
+class LegacyCACFLayerTreeHost : public CACFLayerTreeHost {
+public:
+ static PassRefPtr<LegacyCACFLayerTreeHost> create();
+ virtual ~LegacyCACFLayerTreeHost();
+
+private:
+ LegacyCACFLayerTreeHost();
+
+ void initD3DGeometry();
+
+ // Call this when the device window has changed size or when IDirect3DDevice9::Present returns
+ // D3DERR_DEVICELOST. Returns true if the device was recovered, false if rendering must be
+ // aborted and reattempted soon.
+ enum ResetReason { ChangedWindowSize, LostDevice };
+ bool resetDevice(ResetReason);
+
+ void renderSoon();
+ void renderTimerFired(Timer<LegacyCACFLayerTreeHost>*);
+
+ virtual void initializeContext(void* userData, PlatformCALayer*);
+ virtual void resize();
+ virtual bool createRenderer();
+ virtual void destroyRenderer();
+ virtual CFTimeInterval lastCommitTime() const;
+ virtual void flushContext();
+ virtual void contextDidChange();
+ virtual void paint();
+ virtual void render(const Vector<CGRect>& dirtyRects = Vector<CGRect>());
+
+ Timer<LegacyCACFLayerTreeHost> m_renderTimer;
+ COMPtr<IDirect3DDevice9> m_d3dDevice;
+ WKCACFContext* m_context;
+ bool m_mightBeAbleToCreateDeviceLater;
+ bool m_mustResetLostDeviceBeforeRendering;
+
+#ifndef NDEBUG
+ bool m_printTree;
+#endif
+};
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
+#endif // LegacyCACFLayerTreeHost_h
diff --git a/Source/WebCore/platform/graphics/ca/win/PlatformCAAnimationWin.cpp b/Source/WebCore/platform/graphics/ca/win/PlatformCAAnimationWin.cpp
index 228bb01..6e3011b 100644
--- a/Source/WebCore/platform/graphics/ca/win/PlatformCAAnimationWin.cpp
+++ b/Source/WebCore/platform/graphics/ca/win/PlatformCAAnimationWin.cpp
@@ -145,11 +145,6 @@ PassRefPtr<PlatformCAAnimation> PlatformCAAnimation::create(PlatformAnimationRef
return adoptRef(new PlatformCAAnimation(animation));
}
-PassRefPtr<PlatformCAAnimation> PlatformCAAnimation::create(const PlatformCAAnimation* animation)
-{
- return adoptRef(new PlatformCAAnimation(animation));
-}
-
PlatformCAAnimation::PlatformCAAnimation(AnimationType type, const String& keyPath)
: m_type(type)
{
@@ -176,33 +171,33 @@ PlatformCAAnimation::PlatformCAAnimation(PlatformAnimationRef animation)
m_animation = animation;
}
-PlatformCAAnimation::PlatformCAAnimation(const PlatformCAAnimation* animation)
+PassRefPtr<PlatformCAAnimation> PlatformCAAnimation::copy() const
{
- m_animation.adoptCF(CACFAnimationCreate((animation->animationType() == Basic) ? kCACFBasicAnimation : kCACFKeyframeAnimation));
- RetainPtr<CFStringRef> keyPath(AdoptCF, animation->keyPath().createCFString());
- CACFAnimationSetKeyPath(m_animation.get(), keyPath.get());
-
- setBeginTime(animation->beginTime());
- setDuration(animation->duration());
- setSpeed(animation->speed());
- setTimeOffset(animation->timeOffset());
- setRepeatCount(animation->repeatCount());
- setAutoreverses(animation->autoreverses());
- setFillMode(animation->fillMode());
- setRemovedOnCompletion(animation->isRemovedOnCompletion());
- setAdditive(animation->isAdditive());
- copyTimingFunctionFrom(animation);
- setValueFunction(animation->valueFunction());
-
+ RefPtr<PlatformCAAnimation> animation = create(animationType(), keyPath());
+
+ animation->setBeginTime(beginTime());
+ animation->setDuration(duration());
+ animation->setSpeed(speed());
+ animation->setTimeOffset(timeOffset());
+ animation->setRepeatCount(repeatCount());
+ animation->setAutoreverses(autoreverses());
+ animation->setFillMode(fillMode());
+ animation->setRemovedOnCompletion(isRemovedOnCompletion());
+ animation->setAdditive(isAdditive());
+ animation->copyTimingFunctionFrom(this);
+ animation->setValueFunction(valueFunction());
+
// Copy the specific Basic or Keyframe values
- if (animation->animationType() == Keyframe) {
- copyValuesFrom(animation);
- copyKeyTimesFrom(animation);
- copyTimingFunctionsFrom(animation);
+ if (animationType() == Keyframe) {
+ animation->copyValuesFrom(this);
+ animation->copyKeyTimesFrom(this);
+ animation->copyTimingFunctionsFrom(this);
} else {
- copyFromValueFrom(animation);
- copyToValueFrom(animation);
+ animation->copyFromValueFrom(this);
+ animation->copyToValueFrom(this);
}
+
+ return animation;
}
PlatformCAAnimation::~PlatformCAAnimation()
diff --git a/Source/WebCore/platform/graphics/ca/win/WKCACFViewLayerTreeHost.cpp b/Source/WebCore/platform/graphics/ca/win/WKCACFViewLayerTreeHost.cpp
new file mode 100644
index 0000000..e672c2d
--- /dev/null
+++ b/Source/WebCore/platform/graphics/ca/win/WKCACFViewLayerTreeHost.cpp
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2011 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 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 "WKCACFViewLayerTreeHost.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "PlatformCALayer.h"
+#include "SoftLinking.h"
+#include <wtf/CurrentTime.h>
+
+typedef struct _CACFLayer* CACFLayerRef;
+
+namespace WebCore {
+
+#ifdef DEBUG_ALL
+SOFT_LINK_DEBUG_LIBRARY(WebKitQuartzCoreAdditions)
+#else
+SOFT_LINK_LIBRARY(WebKitQuartzCoreAdditions)
+#endif
+
+SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewCreate, WKCACFViewRef, __cdecl, (), ())
+SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewSetLayer, void, __cdecl, (WKCACFViewRef view, CACFLayerRef layer), (view, layer))
+SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewUpdate, void, __cdecl, (WKCACFViewRef view, HWND window, const CGRect* bounds), (view, window, bounds))
+SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewCanDraw, bool, __cdecl, (WKCACFViewRef view), (view))
+SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewDraw, void, __cdecl, (WKCACFViewRef view), (view))
+SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewFlushContext, void, __cdecl, (WKCACFViewRef view), (view))
+SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewInvalidateRects, void, __cdecl, (WKCACFViewRef view, const CGRect rects[], size_t count), (view, rects, count))
+typedef void (*WKCACFViewContextDidChangeCallback)(WKCACFViewRef view, void* info);
+SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewSetContextDidChangeCallback, void, __cdecl, (WKCACFViewRef view, WKCACFViewContextDidChangeCallback callback, void* info), (view, callback, info))
+SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewGetLastCommitTime, CFTimeInterval, __cdecl, (WKCACFViewRef view), (view))
+SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewSetContextUserData, void, __cdecl, (WKCACFViewRef view, void* userData), (view, userData))
+
+PassRefPtr<WKCACFViewLayerTreeHost> WKCACFViewLayerTreeHost::create()
+{
+ if (!WebKitQuartzCoreAdditionsLibrary())
+ return 0;
+
+ return adoptRef(new WKCACFViewLayerTreeHost);
+}
+
+WKCACFViewLayerTreeHost::WKCACFViewLayerTreeHost()
+ : m_view(AdoptCF, WKCACFViewCreate())
+ , m_viewNeedsUpdate(true)
+{
+}
+
+void WKCACFViewLayerTreeHost::updateViewIfNeeded()
+{
+ if (!m_viewNeedsUpdate)
+ return;
+ m_viewNeedsUpdate = false;
+
+ CGRect layerBounds = rootLayer()->bounds();
+
+ CGRect bounds = this->bounds();
+ WKCACFViewUpdate(m_view.get(), window(), &bounds);
+
+ if (CGRectEqualToRect(layerBounds, rootLayer()->bounds()))
+ return;
+
+ // Flush the context so the layer's rendered bounds will match our bounds.
+ flushContext();
+}
+
+void WKCACFViewLayerTreeHost::contextDidChangeCallback(WKCACFViewRef view, void* info)
+{
+ ASSERT_ARG(view, view);
+ ASSERT_ARG(info, info);
+
+ WKCACFViewLayerTreeHost* host = static_cast<WKCACFViewLayerTreeHost*>(info);
+ ASSERT_ARG(view, view == host->m_view);
+ host->contextDidChange();
+}
+
+void WKCACFViewLayerTreeHost::contextDidChange()
+{
+ // Tell the WKCACFView to start rendering now that we have some contents to render.
+ updateViewIfNeeded();
+
+ CACFLayerTreeHost::contextDidChange();
+}
+
+void WKCACFViewLayerTreeHost::initializeContext(void* userData, PlatformCALayer* layer)
+{
+ WKCACFViewSetContextUserData(m_view.get(), userData);
+ WKCACFViewSetLayer(m_view.get(), layer->platformLayer());
+ WKCACFViewSetContextDidChangeCallback(m_view.get(), contextDidChangeCallback, this);
+}
+
+void WKCACFViewLayerTreeHost::resize()
+{
+ m_viewNeedsUpdate = true;
+}
+
+bool WKCACFViewLayerTreeHost::createRenderer()
+{
+ updateViewIfNeeded();
+ return WKCACFViewCanDraw(m_view.get());
+}
+
+void WKCACFViewLayerTreeHost::destroyRenderer()
+{
+ m_viewNeedsUpdate = true;
+ WKCACFViewUpdate(m_view.get(), 0, 0);
+ WKCACFViewSetContextUserData(m_view.get(), 0);
+ WKCACFViewSetLayer(m_view.get(), 0);
+ WKCACFViewSetContextDidChangeCallback(m_view.get(), 0, 0);
+
+ CACFLayerTreeHost::destroyRenderer();
+}
+
+CFTimeInterval WKCACFViewLayerTreeHost::lastCommitTime() const
+{
+ return WKCACFViewGetLastCommitTime(m_view.get());
+}
+
+void WKCACFViewLayerTreeHost::flushContext()
+{
+ WKCACFViewFlushContext(m_view.get());
+}
+
+void WKCACFViewLayerTreeHost::paint()
+{
+ updateViewIfNeeded();
+ CACFLayerTreeHost::paint();
+}
+
+void WKCACFViewLayerTreeHost::render(const Vector<CGRect>& dirtyRects)
+{
+ WKCACFViewInvalidateRects(m_view.get(), dirtyRects.data(), dirtyRects.size());
+ WKCACFViewDraw(m_view.get());
+}
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/ca/win/WKCACFViewLayerTreeHost.h b/Source/WebCore/platform/graphics/ca/win/WKCACFViewLayerTreeHost.h
new file mode 100644
index 0000000..af09f76
--- /dev/null
+++ b/Source/WebCore/platform/graphics/ca/win/WKCACFViewLayerTreeHost.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2011 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 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 WKCACFViewLayerTreeHost_h
+#define WKCACFViewLayerTreeHost_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "CACFLayerTreeHost.h"
+
+typedef struct _WKCACFView* WKCACFViewRef;
+
+namespace WebCore {
+
+class WKCACFViewLayerTreeHost : public CACFLayerTreeHost {
+public:
+ static PassRefPtr<WKCACFViewLayerTreeHost> create();
+
+private:
+ WKCACFViewLayerTreeHost();
+
+ void updateViewIfNeeded();
+ static void contextDidChangeCallback(WKCACFViewRef, void* info);
+
+ virtual void initializeContext(void* userData, PlatformCALayer*);
+ virtual void resize();
+ virtual bool createRenderer();
+ virtual void destroyRenderer();
+ virtual void flushContext();
+ virtual void contextDidChange();
+ virtual void paint();
+ virtual void render(const Vector<CGRect>& dirtyRects = Vector<CGRect>());
+ virtual CFTimeInterval lastCommitTime() const;
+
+ RetainPtr<WKCACFViewRef> m_view;
+ bool m_viewNeedsUpdate;
+};
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
+#endif // WKCACFViewLayerTreeHost_h
diff --git a/Source/WebCore/platform/graphics/cairo/CairoUtilities.cpp b/Source/WebCore/platform/graphics/cairo/CairoUtilities.cpp
index 013a4af..ee159a1 100644
--- a/Source/WebCore/platform/graphics/cairo/CairoUtilities.cpp
+++ b/Source/WebCore/platform/graphics/cairo/CairoUtilities.cpp
@@ -106,7 +106,11 @@ cairo_operator_t toCairoOperator(CompositeOperator op)
case CompositeXOR:
return CAIRO_OPERATOR_XOR;
case CompositePlusDarker:
+#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 10, 0)
+ return CAIRO_OPERATOR_DARKEN;
+#else
return CAIRO_OPERATOR_SATURATE;
+#endif
case CompositeHighlight:
// There is no Cairo equivalent for CompositeHighlight.
return CAIRO_OPERATOR_OVER;
diff --git a/Source/WebCore/platform/graphics/cairo/FontCustomPlatformData.h b/Source/WebCore/platform/graphics/cairo/FontCustomPlatformData.h
index 50ea00f..5807102 100644
--- a/Source/WebCore/platform/graphics/cairo/FontCustomPlatformData.h
+++ b/Source/WebCore/platform/graphics/cairo/FontCustomPlatformData.h
@@ -24,6 +24,7 @@
#include "FontOrientation.h"
#include "FontRenderingMode.h"
+#include "FontWidthVariant.h"
#include <wtf/Forward.h>
#include <wtf/Noncopyable.h>
@@ -40,7 +41,7 @@ struct FontCustomPlatformData {
public:
FontCustomPlatformData(FT_Face, SharedBuffer*);
~FontCustomPlatformData();
- FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, FontRenderingMode = NormalRenderingMode);
+ FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, FontWidthVariant = RegularWidth, FontRenderingMode = NormalRenderingMode);
static bool supportsFormat(const String&);
private:
diff --git a/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp b/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
index 51b5ee6..f7d6040 100644
--- a/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
+++ b/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
@@ -173,7 +173,7 @@ PassRefPtr<ByteArray> getImageData(const IntRect& rect, const ImageBufferData& d
destx = -originx;
originx = 0;
}
- int endx = rect.right();
+ int endx = rect.maxX();
if (endx > size.width())
endx = size.width();
int numColumns = endx - originx;
@@ -184,7 +184,7 @@ PassRefPtr<ByteArray> getImageData(const IntRect& rect, const ImageBufferData& d
desty = -originy;
originy = 0;
}
- int endy = rect.bottom();
+ int endy = rect.maxY();
if (endy > size.height())
endy = size.height();
int numRows = endy - originy;
@@ -239,9 +239,9 @@ void putImageData(ByteArray*& source, const IntSize& sourceSize, const IntRect&
ASSERT(destx >= 0);
ASSERT(destx < size.width());
ASSERT(originx >= 0);
- ASSERT(originx <= sourceRect.right());
+ ASSERT(originx <= sourceRect.maxX());
- int endx = destPoint.x() + sourceRect.right();
+ int endx = destPoint.x() + sourceRect.maxX();
ASSERT(endx <= size.width());
int numColumns = endx - destx;
@@ -251,9 +251,9 @@ void putImageData(ByteArray*& source, const IntSize& sourceSize, const IntRect&
ASSERT(desty >= 0);
ASSERT(desty < size.height());
ASSERT(originy >= 0);
- ASSERT(originy <= sourceRect.bottom());
+ ASSERT(originy <= sourceRect.maxY());
- int endy = destPoint.y() + sourceRect.bottom();
+ int endy = destPoint.y() + sourceRect.maxY();
ASSERT(endy <= size.height());
int numRows = endy - desty;
diff --git a/Source/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp b/Source/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp
index c19bd72..187d296 100644
--- a/Source/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp
+++ b/Source/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp
@@ -26,7 +26,7 @@
#include "config.h"
-#if ENABLE(3D_CANVAS)
+#if ENABLE(WEBGL)
#include "GraphicsContext3D.h"
#include "GraphicsContextCG.h"
@@ -105,7 +105,7 @@ bool GraphicsContext3D::getImageData(Image* image,
decoder.setData(image->data(), true);
if (!decoder.frameCount())
return false;
- decodedImage = decoder.createFrameAtIndex(0);
+ decodedImage.adoptCF(decoder.createFrameAtIndex(0));
cgImage = decodedImage.get();
} else
cgImage = image->nativeImageForCurrentFrame();
@@ -116,6 +116,34 @@ bool GraphicsContext3D::getImageData(Image* image,
size_t height = CGImageGetHeight(cgImage);
if (!width || !height)
return false;
+
+ // See whether the image is using an indexed color space, and if
+ // so, re-render it into an RGB color space. The image re-packing
+ // code requires color data, not color table indices, for the
+ // image data.
+ CGColorSpaceRef colorSpace = CGImageGetColorSpace(cgImage);
+ CGColorSpaceModel model = CGColorSpaceGetModel(colorSpace);
+ if (model == kCGColorSpaceModelIndexed) {
+ RetainPtr<CGContextRef> bitmapContext;
+ // FIXME: we should probably manually convert the image by indexing into
+ // the color table, which would allow us to avoid premultiplying the
+ // alpha channel. Creation of a bitmap context with an alpha channel
+ // doesn't seem to work unless it's premultiplied.
+ bitmapContext.adoptCF(CGBitmapContextCreate(0, width, height, 8, width * 4,
+ deviceRGBColorSpaceRef(),
+ kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host));
+ if (!bitmapContext)
+ return false;
+
+ CGContextSetBlendMode(bitmapContext.get(), kCGBlendModeCopy);
+ CGContextSetInterpolationQuality(bitmapContext.get(), kCGInterpolationNone);
+ CGContextDrawImage(bitmapContext.get(), CGRectMake(0, 0, width, height), cgImage);
+
+ // Now discard the original CG image and replace it with a copy from the bitmap context.
+ decodedImage.adoptCF(CGBitmapContextCreateImage(bitmapContext.get()));
+ cgImage = decodedImage.get();
+ }
+
size_t bitsPerComponent = CGImageGetBitsPerComponent(cgImage);
size_t bitsPerPixel = CGImageGetBitsPerPixel(cgImage);
if (bitsPerComponent != 8 && bitsPerComponent != 16)
@@ -168,10 +196,11 @@ bool GraphicsContext3D::getImageData(Image* image,
AlphaFormat alphaFormat = AlphaFormatNone;
switch (CGImageGetAlphaInfo(cgImage)) {
case kCGImageAlphaPremultipliedFirst:
- // This path is only accessible for MacOS earlier than 10.6.4.
// This is a special case for texImage2D with HTMLCanvasElement input,
- // in which case image->data() should be null.
- ASSERT(!image->data());
+ // in which case image->data() should be null, or indexed color models,
+ // where we need premultiplied alpha to create the bitmap context
+ // successfully.
+ ASSERT(!image->data() || model == kCGColorSpaceModelIndexed);
if (!premultiplyAlpha)
neededAlphaOp = AlphaDoUnmultiply;
alphaFormat = AlphaFormatFirst;
@@ -254,4 +283,4 @@ void GraphicsContext3D::paintToCanvas(const unsigned char* imagePixels, int imag
} // namespace WebCore
-#endif // ENABLE(3D_CANVAS)
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp b/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
index bcfc37b..3591479 100644
--- a/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
+++ b/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
@@ -35,6 +35,7 @@
#include "KURL.h"
#include "Path.h"
#include "Pattern.h"
+#include "ShadowBlur.h"
#include <CoreGraphics/CoreGraphics.h>
#include <wtf/MathExtras.h>
@@ -165,9 +166,9 @@ void GraphicsContext::drawRect(const IntRect& rect)
setCGFillColor(context, strokeColor(), strokeColorSpace());
CGRect rects[4] = {
FloatRect(rect.x(), rect.y(), rect.width(), 1),
- FloatRect(rect.x(), rect.bottom() - 1, rect.width(), 1),
+ FloatRect(rect.x(), rect.maxY() - 1, rect.width(), 1),
FloatRect(rect.x(), rect.y() + 1, 1, rect.height() - 2),
- FloatRect(rect.right() - 1, rect.y() + 1, 1, rect.height() - 2)
+ FloatRect(rect.maxX() - 1, rect.y() + 1, 1, rect.height() - 2)
};
CGContextFillRects(context, rects, 4);
if (oldFillColor != strokeColor())
@@ -563,7 +564,7 @@ void GraphicsContext::fillPath(const Path& path)
CGContextClip(layerContext);
m_state.fillGradient->paint(layerContext);
- CGContextDrawLayerAtPoint(context, CGPointMake(rect.left(), rect.top()), layer);
+ CGContextDrawLayerAtPoint(context, CGPointMake(rect.x(), rect.y()), layer);
CGLayerRelease(layer);
} else {
CGContextBeginPath(context);
@@ -616,6 +617,16 @@ void GraphicsContext::strokePath(const Path& path)
CGContextStrokePath(context);
}
+static float radiusToLegacyRadius(float radius)
+{
+ return radius > 8 ? 8 + 4 * sqrt((radius - 8) / 2) : radius;
+}
+
+static bool hasBlurredShadow(const GraphicsContextState& state)
+{
+ return state.shadowColor.isValid() && state.shadowColor.alpha() && state.shadowBlur;
+}
+
void GraphicsContext::fillRect(const FloatRect& rect)
{
if (paintingDisabled())
@@ -626,11 +637,16 @@ void GraphicsContext::fillRect(const FloatRect& rect)
if (m_state.fillGradient) {
CGContextSaveGState(context);
if (hasShadow()) {
- CGContextConcatCTM(context, m_state.fillGradient->gradientSpaceTransform());
CGLayerRef layer = CGLayerCreateWithContext(context, CGSizeMake(rect.width(), rect.height()), 0);
CGContextRef layerContext = CGLayerGetContext(layer);
+
+ CGContextTranslateCTM(layerContext, -rect.x(), -rect.y());
+ CGContextAddRect(layerContext, rect);
+ CGContextClip(layerContext);
+
+ CGContextConcatCTM(layerContext, m_state.fillGradient->gradientSpaceTransform());
m_state.fillGradient->paint(layerContext);
- CGContextDrawLayerAtPoint(context, CGPointMake(rect.left(), rect.top()), layer);
+ CGContextDrawLayerAtPoint(context, CGPointMake(rect.x(), rect.y()), layer);
CGLayerRelease(layer);
} else {
CGContextClipToRect(context, rect);
@@ -643,7 +659,22 @@ void GraphicsContext::fillRect(const FloatRect& rect)
if (m_state.fillPattern)
applyFillPattern();
+
+ bool drawOwnShadow = hasBlurredShadow(m_state) && !m_state.shadowsIgnoreTransforms; // Don't use ShadowBlur for canvas yet.
+ if (drawOwnShadow) {
+ float shadowBlur = m_state.shadowsUseLegacyRadius ? radiusToLegacyRadius(m_state.shadowBlur) : m_state.shadowBlur;
+ // Turn off CG shadows.
+ CGContextSaveGState(context);
+ CGContextSetShadowWithColor(platformContext(), CGSizeZero, 0, 0);
+
+ ShadowBlur contextShadow(shadowBlur, m_state.shadowOffset, m_state.shadowColor, m_state.shadowColorSpace);
+ contextShadow.drawRectShadow(this, rect, RoundedIntRect::Radii());
+ }
+
CGContextFillRect(context, rect);
+
+ if (drawOwnShadow)
+ CGContextRestoreGState(context);
}
void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorSpace colorSpace)
@@ -658,7 +689,21 @@ void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorS
if (oldFillColor != color || oldColorSpace != colorSpace)
setCGFillColor(context, color, colorSpace);
+ bool drawOwnShadow = hasBlurredShadow(m_state) && !m_state.shadowsIgnoreTransforms; // Don't use ShadowBlur for canvas yet.
+ if (drawOwnShadow) {
+ float shadowBlur = m_state.shadowsUseLegacyRadius ? radiusToLegacyRadius(m_state.shadowBlur) : m_state.shadowBlur;
+ // Turn off CG shadows.
+ CGContextSaveGState(context);
+ CGContextSetShadowWithColor(platformContext(), CGSizeZero, 0, 0);
+
+ ShadowBlur contextShadow(shadowBlur, m_state.shadowOffset, m_state.shadowColor, m_state.shadowColorSpace);
+ contextShadow.drawRectShadow(this, rect, RoundedIntRect::Radii());
+ }
+
CGContextFillRect(context, rect);
+
+ if (drawOwnShadow)
+ CGContextRestoreGState(context);
if (oldFillColor != color || oldColorSpace != colorSpace)
setCGFillColor(context, oldFillColor, oldColorSpace);
@@ -678,12 +723,72 @@ void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLef
Path path;
path.addRoundedRect(rect, topLeft, topRight, bottomLeft, bottomRight);
+
+ bool drawOwnShadow = hasBlurredShadow(m_state) && !m_state.shadowsIgnoreTransforms; // Don't use ShadowBlur for canvas yet.
+ if (drawOwnShadow) {
+ float shadowBlur = m_state.shadowsUseLegacyRadius ? radiusToLegacyRadius(m_state.shadowBlur) : m_state.shadowBlur;
+
+ // Turn off CG shadows.
+ CGContextSaveGState(context);
+ CGContextSetShadowWithColor(platformContext(), CGSizeZero, 0, 0);
+
+ ShadowBlur contextShadow(shadowBlur, m_state.shadowOffset, m_state.shadowColor, m_state.shadowColorSpace);
+ contextShadow.drawRectShadow(this, rect, RoundedIntRect::Radii(topLeft, topRight, bottomLeft, bottomRight));
+ }
+
fillPath(path);
+ if (drawOwnShadow)
+ CGContextRestoreGState(context);
+
if (oldFillColor != color || oldColorSpace != colorSpace)
setCGFillColor(context, oldFillColor, oldColorSpace);
}
+void GraphicsContext::fillRectWithRoundedHole(const IntRect& rect, const RoundedIntRect& roundedHoleRect, const Color& color, ColorSpace colorSpace)
+{
+ if (paintingDisabled())
+ return;
+
+ CGContextRef context = platformContext();
+
+ Path path;
+ path.addRect(rect);
+
+ if (!roundedHoleRect.radii().isZero())
+ path.addRoundedRect(roundedHoleRect.rect(), roundedHoleRect.radii().topLeft(), roundedHoleRect.radii().topRight(), roundedHoleRect.radii().bottomLeft(), roundedHoleRect.radii().bottomRight());
+ else
+ path.addRect(roundedHoleRect.rect());
+
+ WindRule oldFillRule = fillRule();
+ Color oldFillColor = fillColor();
+ ColorSpace oldFillColorSpace = fillColorSpace();
+
+ setFillRule(RULE_EVENODD);
+ setFillColor(color, colorSpace);
+
+ // fillRectWithRoundedHole() assumes that the edges of rect are clipped out, so we only care about shadows cast around inside the hole.
+ bool drawOwnShadow = hasBlurredShadow(m_state) && !m_state.shadowsIgnoreTransforms;
+ if (drawOwnShadow) {
+ float shadowBlur = m_state.shadowsUseLegacyRadius ? radiusToLegacyRadius(m_state.shadowBlur) : m_state.shadowBlur;
+
+ // Turn off CG shadows.
+ CGContextSaveGState(context);
+ CGContextSetShadowWithColor(platformContext(), CGSizeZero, 0, 0);
+
+ ShadowBlur contextShadow(shadowBlur, m_state.shadowOffset, m_state.shadowColor, m_state.shadowColorSpace);
+ contextShadow.drawInsetShadow(this, rect, roundedHoleRect.rect(), roundedHoleRect.radii());
+ }
+
+ fillPath(path);
+
+ if (drawOwnShadow)
+ CGContextRestoreGState(context);
+
+ setFillRule(oldFillRule);
+ setFillColor(oldFillColor, oldFillColorSpace);
+}
+
void GraphicsContext::clip(const FloatRect& rect)
{
if (paintingDisabled())
@@ -722,6 +827,11 @@ void GraphicsContext::clipPath(const Path& path, WindRule clipRule)
CGContextClip(context);
}
+IntRect GraphicsContext::clipBounds() const
+{
+ return enclosingIntRect(CGContextGetClipBoundingBox(platformContext()));
+}
+
void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness)
{
if (paintingDisabled())
@@ -766,6 +876,9 @@ void GraphicsContext::setPlatformShadow(const FloatSize& offset, float blur, con
{
if (paintingDisabled())
return;
+
+ // FIXME: we could avoid the shadow setup cost when we know we'll render the shadow ourselves.
+
CGFloat xOffset = offset.width();
CGFloat yOffset = offset.height();
CGFloat blurRadius = blur;
diff --git a/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp b/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp
index 295f632..ab5907e 100644
--- a/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp
+++ b/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp
@@ -267,7 +267,7 @@ PassRefPtr<ByteArray> getImageData(const IntRect& rect, const ImageBufferData& i
RefPtr<ByteArray> result = ByteArray::create(rect.width() * rect.height() * 4);
unsigned char* data = result->data();
- if (rect.x() < 0 || rect.y() < 0 || rect.right() > size.width() || rect.bottom() > size.height())
+ if (rect.x() < 0 || rect.y() < 0 || rect.maxX() > size.width() || rect.maxY() > size.height())
memset(data, 0, result->length());
int originx = rect.x();
@@ -276,7 +276,7 @@ PassRefPtr<ByteArray> getImageData(const IntRect& rect, const ImageBufferData& i
destx = -originx;
originx = 0;
}
- int endx = rect.right();
+ int endx = rect.maxX();
if (endx > size.width())
endx = size.width();
int numColumns = endx - originx;
@@ -287,7 +287,7 @@ PassRefPtr<ByteArray> getImageData(const IntRect& rect, const ImageBufferData& i
desty = -originy;
originy = 0;
}
- int endy = rect.bottom();
+ int endy = rect.maxY();
if (endy > size.height())
endy = size.height();
int numRows = endy - originy;
@@ -377,9 +377,9 @@ void putImageData(ByteArray*& source, const IntSize& sourceSize, const IntRect&
ASSERT(destx >= 0);
ASSERT(destx < size.width());
ASSERT(originx >= 0);
- ASSERT(originx <= sourceRect.right());
+ ASSERT(originx <= sourceRect.maxX());
- int endx = destPoint.x() + sourceRect.right();
+ int endx = destPoint.x() + sourceRect.maxX();
ASSERT(endx <= size.width());
int numColumns = endx - destx;
@@ -389,9 +389,9 @@ void putImageData(ByteArray*& source, const IntSize& sourceSize, const IntRect&
ASSERT(desty >= 0);
ASSERT(desty < size.height());
ASSERT(originy >= 0);
- ASSERT(originy <= sourceRect.bottom());
+ ASSERT(originy <= sourceRect.maxY());
- int endy = destPoint.y() + sourceRect.bottom();
+ int endy = destPoint.y() + sourceRect.maxY();
ASSERT(endy <= size.height());
int numRows = endy - desty;
diff --git a/Source/WebCore/platform/graphics/cg/ImageCG.cpp b/Source/WebCore/platform/graphics/cg/ImageCG.cpp
index dfee96a..08f65bd 100644
--- a/Source/WebCore/platform/graphics/cg/ImageCG.cpp
+++ b/Source/WebCore/platform/graphics/cg/ImageCG.cpp
@@ -204,7 +204,7 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& destRect, const F
adjustedDestRect.setHeight(subimageRect.height() / yScale);
image.adoptCF(CGImageCreateWithImageInRect(image.get(), subimageRect));
- if (currHeight < srcRect.bottom()) {
+ if (currHeight < srcRect.maxY()) {
ASSERT(CGImageGetHeight(image.get()) == currHeight - CGRectIntegral(srcRect).origin.y);
adjustedDestRect.setHeight(CGImageGetHeight(image.get()) / yScale);
}
@@ -224,7 +224,7 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& destRect, const F
// Flip the coords.
CGContextScaleCTM(context, 1, -1);
- adjustedDestRect.setY(-adjustedDestRect.bottom());
+ adjustedDestRect.setY(-adjustedDestRect.maxY());
// Adjust the color space.
image = imageWithColorSpace(image.get(), styleColorSpace);
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;
diff --git a/Source/WebCore/platform/graphics/cocoa/FontPlatformData.h b/Source/WebCore/platform/graphics/cocoa/FontPlatformData.h
index 8cf08fb..ca38029 100644
--- a/Source/WebCore/platform/graphics/cocoa/FontPlatformData.h
+++ b/Source/WebCore/platform/graphics/cocoa/FontPlatformData.h
@@ -25,6 +25,7 @@
#define FontPlatformData_h
#include "FontOrientation.h"
+#include "FontWidthVariant.h"
#include <wtf/text/StringImpl.h>
#ifdef __OBJC__
@@ -59,11 +60,12 @@ inline CTFontRef toCTFontRef(NSFont *nsFont) { return reinterpret_cast<CTFontRef
class FontPlatformData {
public:
- FontPlatformData(float size, bool syntheticBold, bool syntheticOblique, FontOrientation orientation = Horizontal)
+ FontPlatformData(float size, bool syntheticBold, bool syntheticOblique, FontOrientation orientation = Horizontal, FontWidthVariant widthVariant = RegularWidth)
: m_syntheticBold(syntheticBold)
, m_syntheticOblique(syntheticOblique)
, m_orientation(orientation)
, m_size(size)
+ , m_widthVariant(widthVariant)
, m_font(0)
#ifdef BUILDING_ON_TIGER
, m_cgFont(0)
@@ -72,13 +74,14 @@ class FontPlatformData {
{
}
- FontPlatformData(NSFont *nsFont, float size, bool syntheticBold = false, bool syntheticOblique = false, FontOrientation = Horizontal);
+ FontPlatformData(NSFont*, float size, bool syntheticBold = false, bool syntheticOblique = false, FontOrientation = Horizontal, FontWidthVariant = RegularWidth);
- FontPlatformData(CGFontRef cgFont, float size, bool syntheticBold, bool syntheticOblique, FontOrientation orientation)
+ FontPlatformData(CGFontRef cgFont, float size, bool syntheticBold, bool syntheticOblique, FontOrientation orientation, FontWidthVariant widthVariant)
: m_syntheticBold(syntheticBold)
, m_syntheticOblique(syntheticOblique)
, m_orientation(orientation)
, m_size(size)
+ , m_widthVariant(widthVariant)
, m_font(0)
, m_cgFont(cgFont)
, m_isColorBitmapFont(false)
@@ -96,17 +99,20 @@ class FontPlatformData {
bool syntheticBold() const { return m_syntheticBold; }
bool syntheticOblique() const { return m_syntheticOblique; }
FontOrientation orientation() const { return m_orientation; }
+ FontWidthVariant widthVariant() const { return m_widthVariant; }
bool m_syntheticBold;
bool m_syntheticOblique;
FontOrientation m_orientation;
float m_size;
+
+ FontWidthVariant m_widthVariant;
unsigned hash() const
{
ASSERT(m_font != 0 || m_cgFont == 0);
- uintptr_t hashCodes[2] = { (uintptr_t)m_font, m_orientation << 2 | m_syntheticBold << 1 | m_syntheticOblique };
+ uintptr_t hashCodes[3] = { (uintptr_t)m_font, m_widthVariant, m_orientation << 2 | m_syntheticBold << 1 | m_syntheticOblique };
return WTF::StringHasher::createBlobHash<sizeof(hashCodes)>(hashCodes);
}
@@ -115,7 +121,7 @@ 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_orientation == other.m_orientation;
+ m_cgFont == other.m_cgFont && m_size == other.m_size && m_orientation == other.m_orientation && m_widthVariant == other.m_widthVariant;
}
NSFont *font() const { return m_font; }
diff --git a/Source/WebCore/platform/graphics/cocoa/FontPlatformDataCocoa.mm b/Source/WebCore/platform/graphics/cocoa/FontPlatformDataCocoa.mm
index 8dacbe3..b40f698 100644
--- a/Source/WebCore/platform/graphics/cocoa/FontPlatformDataCocoa.mm
+++ b/Source/WebCore/platform/graphics/cocoa/FontPlatformDataCocoa.mm
@@ -30,6 +30,9 @@
namespace WebCore {
+// These CoreText Text Spacing feature selectors are not defined in CoreText.
+enum TextSpacingCTFeatureSelector { TextSpacingProportional, TextSpacingFullWidth, TextSpacingHalfWidth, TextSpacingThirdWidth, TextSpacingQuarterWidth };
+
#if PLATFORM(MAC)
void FontPlatformData::loadFont(NSFont* nsFont, float, NSFont*& outNSFont, CGFontRef& cgFont)
{
@@ -42,10 +45,11 @@ void FontPlatformData::loadFont(NSFont* nsFont, float, NSFont*& outNSFont, CGFon
}
#endif // PLATFORM(MAC)
-FontPlatformData::FontPlatformData(NSFont *nsFont, float size, bool syntheticBold, bool syntheticOblique, FontOrientation orientation)
+FontPlatformData::FontPlatformData(NSFont *nsFont, float size, bool syntheticBold, bool syntheticOblique, FontOrientation orientation, FontWidthVariant widthVariant)
: m_syntheticBold(syntheticBold)
, m_syntheticOblique(syntheticOblique)
, m_size(size)
+ , m_widthVariant(widthVariant)
, m_font(nsFont)
#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
// FIXME: Chromium: The following code isn't correct for the Chromium port since the sandbox might
@@ -79,6 +83,7 @@ FontPlatformData::FontPlatformData(const FontPlatformData& f)
m_syntheticBold = f.m_syntheticBold;
m_syntheticOblique = f.m_syntheticOblique;
m_size = f.m_size;
+ m_widthVariant = f.m_widthVariant;
m_cgFont = f.m_cgFont;
m_isColorBitmapFont = f.m_isColorBitmapFont;
m_orientation = f.m_orientation;
@@ -99,6 +104,7 @@ const FontPlatformData& FontPlatformData::operator=(const FontPlatformData& f)
m_syntheticBold = f.m_syntheticBold;
m_syntheticOblique = f.m_syntheticOblique;
m_size = f.m_size;
+ m_widthVariant = f.m_widthVariant;
m_cgFont = f.m_cgFont;
if (m_font == f.m_font)
return *this;
@@ -165,12 +171,48 @@ bool FontPlatformData::allowsLigatures() const
return ![[m_font coveredCharacterSet] characterIsMember:'a'];
}
+inline int mapFontWidthVariantToCTFeatureSelector(FontWidthVariant variant)
+{
+ switch(variant) {
+ case RegularWidth:
+ return TextSpacingProportional;
+
+ case HalfWidth:
+ return TextSpacingHalfWidth;
+
+ case ThirdWidth:
+ return TextSpacingThirdWidth;
+
+ case QuarterWidth:
+ return TextSpacingQuarterWidth;
+ }
+
+ ASSERT_NOT_REACHED();
+ return TextSpacingProportional;
+}
+
CTFontRef FontPlatformData::ctFont() const
{
- if (m_font)
- return toCTFontRef(m_font);
- if (!m_CTFont)
- m_CTFont.adoptCF(CTFontCreateWithGraphicsFont(m_cgFont.get(), m_size, 0, 0));
+ if (m_widthVariant == RegularWidth) {
+ if (m_font)
+ return toCTFontRef(m_font);
+ if (!m_CTFont)
+ m_CTFont.adoptCF(CTFontCreateWithGraphicsFont(m_cgFont.get(), m_size, 0, 0));
+ return m_CTFont.get();
+ }
+
+ if (!m_CTFont) {
+ int featureTypeValue = kTextSpacingType;
+ int featureSelectorValue = mapFontWidthVariantToCTFeatureSelector(m_widthVariant);
+ RetainPtr<CTFontRef> sourceFont(AdoptCF, CTFontCreateWithGraphicsFont(m_cgFont.get(), m_size, 0, 0));
+ RetainPtr<CTFontDescriptorRef> sourceDescriptor(AdoptCF, CTFontCopyFontDescriptor(sourceFont.get()));
+ RetainPtr<CFNumberRef> featureType(AdoptCF, CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &featureTypeValue));
+ RetainPtr<CFNumberRef> featureSelector(AdoptCF, CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &featureSelectorValue));
+ RetainPtr<CTFontDescriptorRef> newDescriptor(AdoptCF, CTFontDescriptorCreateCopyWithFeature(sourceDescriptor.get(), featureType.get(), featureSelector.get()));
+ RetainPtr<CTFontRef> newFont(AdoptCF, CTFontCreateWithFontDescriptor(newDescriptor.get(), m_size, 0));
+
+ m_CTFont = newFont.get() ? newFont : sourceFont;
+ }
return m_CTFont.get();
}
diff --git a/Source/WebCore/platform/graphics/efl/FontEfl.cpp b/Source/WebCore/platform/graphics/efl/FontEfl.cpp
index d3ca183..83cc7ff 100644
--- a/Source/WebCore/platform/graphics/efl/FontEfl.cpp
+++ b/Source/WebCore/platform/graphics/efl/FontEfl.cpp
@@ -50,6 +50,11 @@ bool Font::canReturnFallbackFontsForComplexText()
return false;
}
+bool Font::canExpandAroundIdeographsInComplexText()
+{
+ return false;
+}
+
float Font::floatWidthForComplexText(const TextRun&, HashSet<const SimpleFontData*>*, GlyphOverflow*) const
{
notImplemented();
diff --git a/Source/WebCore/platform/graphics/filters/DistantLightSource.cpp b/Source/WebCore/platform/graphics/filters/DistantLightSource.cpp
new file mode 100644
index 0000000..4c3b49b
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/DistantLightSource.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2010 Zoltan Herczeg <zherczeg@webkit.org>
+ * Copyright (C) 2011 University of Szeged
+ * Copyright (C) 2011 Renata Hodovan <reni@webkit.org>
+ *
+ * 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 UNIVERSITY OF SZEGED ``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 UNIVERSITY OF SZEGED OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "DistantLightSource.h"
+
+#include "RenderTreeAsText.h"
+
+namespace WebCore {
+
+void DistantLightSource::initPaintingData(PaintingData& paintingData)
+{
+ float azimuth = deg2rad(m_azimuth);
+ float elevation = deg2rad(m_elevation);
+ paintingData.lightVector.setX(cosf(azimuth) * cosf(elevation));
+ paintingData.lightVector.setY(sinf(azimuth) * cosf(elevation));
+ paintingData.lightVector.setZ(sinf(elevation));
+ paintingData.lightVectorLength = 1;
+}
+
+void DistantLightSource::updatePaintingData(PaintingData&, int, int, float)
+{
+}
+
+bool DistantLightSource::setAzimuth(float azimuth)
+{
+ if (m_azimuth == azimuth)
+ return false;
+ m_azimuth = azimuth;
+ return true;
+}
+
+bool DistantLightSource::setElevation(float elevation)
+{
+ if (m_elevation == elevation)
+ return false;
+ m_elevation = elevation;
+ return true;
+}
+
+TextStream& DistantLightSource::externalRepresentation(TextStream& ts) const
+{
+ ts << "[type=DISTANT-LIGHT] ";
+ ts << "[azimuth=\"" << azimuth() << "\"]";
+ ts << "[elevation=\"" << elevation() << "\"]";
+ return ts;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/Source/WebCore/platform/graphics/filters/DistantLightSource.h b/Source/WebCore/platform/graphics/filters/DistantLightSource.h
index d5d474f..1e19c62 100644
--- a/Source/WebCore/platform/graphics/filters/DistantLightSource.h
+++ b/Source/WebCore/platform/graphics/filters/DistantLightSource.h
@@ -36,7 +36,9 @@ public:
}
float azimuth() const { return m_azimuth; }
+ bool setAzimuth(float);
float elevation() const { return m_elevation; }
+ bool setElevation(float);
virtual void initPaintingData(PaintingData&);
virtual void updatePaintingData(PaintingData&, int x, int y, float z);
diff --git a/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.cpp b/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.cpp
index a8a825a..5f9d049 100644
--- a/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.cpp
+++ b/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.cpp
@@ -52,9 +52,12 @@ Color FEDiffuseLighting::lightingColor() const
return m_lightingColor;
}
-void FEDiffuseLighting::setLightingColor(const Color& lightingColor)
+bool FEDiffuseLighting::setLightingColor(const Color& lightingColor)
{
+ if (m_lightingColor == lightingColor)
+ return false;
m_lightingColor = lightingColor;
+ return true;
}
float FEDiffuseLighting::surfaceScale() const
@@ -62,9 +65,12 @@ float FEDiffuseLighting::surfaceScale() const
return m_surfaceScale;
}
-void FEDiffuseLighting::setSurfaceScale(float surfaceScale)
+bool FEDiffuseLighting::setSurfaceScale(float surfaceScale)
{
+ if (m_surfaceScale == surfaceScale)
+ return false;
m_surfaceScale = surfaceScale;
+ return true;
}
float FEDiffuseLighting::diffuseConstant() const
@@ -72,9 +78,12 @@ float FEDiffuseLighting::diffuseConstant() const
return m_diffuseConstant;
}
-void FEDiffuseLighting::setDiffuseConstant(float diffuseConstant)
+bool FEDiffuseLighting::setDiffuseConstant(float diffuseConstant)
{
+ if (m_diffuseConstant == diffuseConstant)
+ return false;
m_diffuseConstant = diffuseConstant;
+ return true;
}
float FEDiffuseLighting::kernelUnitLengthX() const
@@ -82,9 +91,12 @@ float FEDiffuseLighting::kernelUnitLengthX() const
return m_kernelUnitLengthX;
}
-void FEDiffuseLighting::setKernelUnitLengthX(float kernelUnitLengthX)
+bool FEDiffuseLighting::setKernelUnitLengthX(float kernelUnitLengthX)
{
+ if (m_kernelUnitLengthX == kernelUnitLengthX)
+ return false;
m_kernelUnitLengthX = kernelUnitLengthX;
+ return true;
}
float FEDiffuseLighting::kernelUnitLengthY() const
@@ -92,9 +104,12 @@ float FEDiffuseLighting::kernelUnitLengthY() const
return m_kernelUnitLengthY;
}
-void FEDiffuseLighting::setKernelUnitLengthY(float kernelUnitLengthY)
+bool FEDiffuseLighting::setKernelUnitLengthY(float kernelUnitLengthY)
{
+ if (m_kernelUnitLengthY == kernelUnitLengthY)
+ return false;
m_kernelUnitLengthY = kernelUnitLengthY;
+ return true;
}
const LightSource* FEDiffuseLighting::lightSource() const
diff --git a/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.h b/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.h
index b58b47a..5f20651 100644
--- a/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.h
+++ b/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.h
@@ -36,19 +36,19 @@ public:
virtual ~FEDiffuseLighting();
Color lightingColor() const;
- void setLightingColor(const Color&);
+ bool setLightingColor(const Color&);
float surfaceScale() const;
- void setSurfaceScale(float);
+ bool setSurfaceScale(float);
float diffuseConstant() const;
- void setDiffuseConstant(float);
+ bool setDiffuseConstant(float);
float kernelUnitLengthX() const;
- void setKernelUnitLengthX(float);
+ bool setKernelUnitLengthX(float);
float kernelUnitLengthY() const;
- void setKernelUnitLengthY(float);
+ bool setKernelUnitLengthY(float);
const LightSource* lightSource() const;
void setLightSource(PassRefPtr<LightSource>);
diff --git a/Source/WebCore/platform/graphics/filters/FilterEffect.cpp b/Source/WebCore/platform/graphics/filters/FilterEffect.cpp
index 85154b5..f07d00c 100644
--- a/Source/WebCore/platform/graphics/filters/FilterEffect.cpp
+++ b/Source/WebCore/platform/graphics/filters/FilterEffect.cpp
@@ -77,6 +77,16 @@ FilterEffect* FilterEffect::inputEffect(unsigned number) const
return m_inputEffects.at(number).get();
}
+void FilterEffect::clearResult()
+{
+ if (m_imageBufferResult)
+ m_imageBufferResult.clear();
+ if (m_unmultipliedImageResult)
+ m_unmultipliedImageResult.clear();
+ if (m_premultipliedImageResult)
+ m_premultipliedImageResult.clear();
+}
+
ImageBuffer* FilterEffect::asImageBuffer()
{
if (!hasResult())
@@ -109,7 +119,7 @@ PassRefPtr<ByteArray> FilterEffect::asPremultipliedImage(const IntRect& rect)
inline void FilterEffect::copyImageBytes(ByteArray* source, ByteArray* destination, const IntRect& rect)
{
// Copy the necessary lines.
- if (rect.x() < 0 || rect.y() < 0 || rect.bottom() > m_absolutePaintRect.width() || rect.bottom() > m_absolutePaintRect.height())
+ if (rect.x() < 0 || rect.y() < 0 || rect.maxY() > m_absolutePaintRect.width() || rect.maxY() > m_absolutePaintRect.height())
memset(destination->data(), 0, destination->length());
int xOrigin = rect.x();
@@ -118,7 +128,7 @@ inline void FilterEffect::copyImageBytes(ByteArray* source, ByteArray* destinati
xDest = -xOrigin;
xOrigin = 0;
}
- int xEnd = rect.right();
+ int xEnd = rect.maxX();
if (xEnd > m_absolutePaintRect.width())
xEnd = m_absolutePaintRect.width();
@@ -128,7 +138,7 @@ inline void FilterEffect::copyImageBytes(ByteArray* source, ByteArray* destinati
yDest = -yOrigin;
yOrigin = 0;
}
- int yEnd = rect.bottom();
+ int yEnd = rect.maxY();
if (yEnd > m_absolutePaintRect.height())
yEnd = m_absolutePaintRect.height();
diff --git a/Source/WebCore/platform/graphics/filters/FilterEffect.h b/Source/WebCore/platform/graphics/filters/FilterEffect.h
index 062dd1b..2de8ac5 100644
--- a/Source/WebCore/platform/graphics/filters/FilterEffect.h
+++ b/Source/WebCore/platform/graphics/filters/FilterEffect.h
@@ -53,6 +53,7 @@ public:
virtual ~FilterEffect();
bool hasResult() const { return m_imageBufferResult || m_unmultipliedImageResult || m_premultipliedImageResult; }
+ void clearResult();
ImageBuffer* asImageBuffer();
PassRefPtr<ByteArray> asUnmultipliedImage(const IntRect&);
PassRefPtr<ByteArray> asPremultipliedImage(const IntRect&);
diff --git a/Source/WebCore/platform/graphics/filters/LightSource.cpp b/Source/WebCore/platform/graphics/filters/LightSource.cpp
index de0691e..cf262e8 100644
--- a/Source/WebCore/platform/graphics/filters/LightSource.cpp
+++ b/Source/WebCore/platform/graphics/filters/LightSource.cpp
@@ -3,6 +3,7 @@
* Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
* Copyright (C) 2005 Eric Seidel <eric@webkit.org>
* Copyright (C) 2010 Zoltan Herczeg <zherczeg@webkit.org>
+ * Copyright (C) 2011 Renata Hodovan <reni@webkit.org>, University of Szeged.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -33,136 +34,80 @@
namespace WebCore {
-void PointLightSource::initPaintingData(PaintingData&)
+bool LightSource::setAzimuth(float azimuth)
{
+ if (m_type == LS_DISTANT)
+ return static_cast<DistantLightSource*>(this)->setAzimuth(azimuth);
+ return false;
}
-void PointLightSource::updatePaintingData(PaintingData& paintingData, int x, int y, float z)
+bool LightSource::setElevation(float elevation)
{
- paintingData.lightVector.setX(m_position.x() - x);
- paintingData.lightVector.setY(m_position.y() - y);
- paintingData.lightVector.setZ(m_position.z() - z);
- paintingData.lightVectorLength = paintingData.lightVector.length();
+ if (m_type == LS_DISTANT)
+ return static_cast<DistantLightSource*>(this)->setElevation(elevation);
+ return false;
}
-// spot-light edge darkening depends on an absolute treshold
-// according to the SVG 1.1 SE light regression tests
-static const float antiAliasTreshold = 0.016f;
-
-void SpotLightSource::initPaintingData(PaintingData& paintingData)
+bool LightSource::setX(float x)
{
- paintingData.privateColorVector = paintingData.colorVector;
- paintingData.directionVector.setX(m_direction.x() - m_position.x());
- paintingData.directionVector.setY(m_direction.y() - m_position.y());
- paintingData.directionVector.setZ(m_direction.z() - m_position.z());
- paintingData.directionVector.normalize();
-
- if (!m_limitingConeAngle) {
- paintingData.coneCutOffLimit = 0.0f;
- paintingData.coneFullLight = -antiAliasTreshold;
- } else {
- float limitingConeAngle = m_limitingConeAngle;
- if (limitingConeAngle < 0.0f)
- limitingConeAngle = -limitingConeAngle;
- if (limitingConeAngle > 90.0f)
- limitingConeAngle = 90.0f;
- paintingData.coneCutOffLimit = cosf(deg2rad(180.0f - limitingConeAngle));
- paintingData.coneFullLight = paintingData.coneCutOffLimit - antiAliasTreshold;
- }
-
- // Optimization for common specularExponent values
- if (!m_specularExponent)
- paintingData.specularExponent = 0;
- else if (m_specularExponent == 1.0f)
- paintingData.specularExponent = 1;
- else // It is neither 0.0f nor 1.0f
- paintingData.specularExponent = 2;
+ if (m_type == LS_SPOT)
+ return static_cast<SpotLightSource*>(this)->setX(x);
+ if (m_type == LS_POINT)
+ return static_cast<PointLightSource*>(this)->setX(x);
+ return false;
}
-void SpotLightSource::updatePaintingData(PaintingData& paintingData, int x, int y, float z)
+bool LightSource::setY(float y)
{
- paintingData.lightVector.setX(m_position.x() - x);
- paintingData.lightVector.setY(m_position.y() - y);
- paintingData.lightVector.setZ(m_position.z() - z);
- paintingData.lightVectorLength = paintingData.lightVector.length();
-
- float cosineOfAngle = (paintingData.lightVector * paintingData.directionVector) / paintingData.lightVectorLength;
- if (cosineOfAngle > paintingData.coneCutOffLimit) {
- // No light is produced, scanlines are not updated
- paintingData.colorVector.setX(0.0f);
- paintingData.colorVector.setY(0.0f);
- paintingData.colorVector.setZ(0.0f);
- return;
- }
-
- // Set the color of the pixel
- float lightStrength;
- switch (paintingData.specularExponent) {
- case 0:
- lightStrength = 1.0f; // -cosineOfAngle ^ 0 == 1
- break;
- case 1:
- lightStrength = -cosineOfAngle; // -cosineOfAngle ^ 1 == -cosineOfAngle
- break;
- default:
- lightStrength = powf(-cosineOfAngle, m_specularExponent);
- break;
- }
-
- if (cosineOfAngle > paintingData.coneFullLight)
- lightStrength *= (paintingData.coneCutOffLimit - cosineOfAngle) / (paintingData.coneCutOffLimit - paintingData.coneFullLight);
-
- if (lightStrength > 1.0f)
- lightStrength = 1.0f;
-
- paintingData.colorVector.setX(paintingData.privateColorVector.x() * lightStrength);
- paintingData.colorVector.setY(paintingData.privateColorVector.y() * lightStrength);
- paintingData.colorVector.setZ(paintingData.privateColorVector.z() * lightStrength);
+ if (m_type == LS_SPOT)
+ return static_cast<SpotLightSource*>(this)->setY(y);
+ if (m_type == LS_POINT)
+ return static_cast<PointLightSource*>(this)->setY(y);
+ return false;
}
-void DistantLightSource::initPaintingData(PaintingData& paintingData)
+bool LightSource::setZ(float z)
{
- float azimuth = deg2rad(m_azimuth);
- float elevation = deg2rad(m_elevation);
- paintingData.lightVector.setX(cosf(azimuth) * cosf(elevation));
- paintingData.lightVector.setY(sinf(azimuth) * cosf(elevation));
- paintingData.lightVector.setZ(sinf(elevation));
- paintingData.lightVectorLength = 1;
+ if (m_type == LS_SPOT)
+ return static_cast<SpotLightSource*>(this)->setZ(z);
+ if (m_type == LS_POINT)
+ return static_cast<PointLightSource*>(this)->setZ(z);
+ return false;
}
-void DistantLightSource::updatePaintingData(PaintingData&, int, int, float)
+bool LightSource::setPointsAtX(float pointsAtX)
{
+ if (m_type == LS_SPOT)
+ return static_cast<SpotLightSource*>(this)->setPointsAtX(pointsAtX);
+ return false;
}
-static TextStream& operator<<(TextStream& ts, const FloatPoint3D& p)
+bool LightSource::setPointsAtY(float pointsAtY)
{
- ts << "x=" << p.x() << " y=" << p.y() << " z=" << p.z();
- return ts;
+ if (m_type == LS_SPOT)
+ return static_cast<SpotLightSource*>(this)->setPointsAtY(pointsAtY);
+ return false;
}
-TextStream& PointLightSource::externalRepresentation(TextStream& ts) const
+bool LightSource::setPointsAtZ(float pointsAtZ)
{
- ts << "[type=POINT-LIGHT] ";
- ts << "[position=\"" << position() << "\"]";
- return ts;
+ if (m_type == LS_SPOT)
+ return static_cast<SpotLightSource*>(this)->setPointsAtZ(pointsAtZ);
+ return false;
}
-TextStream& SpotLightSource::externalRepresentation(TextStream& ts) const
+bool LightSource::setSpecularExponent(float specularExponent)
{
- ts << "[type=SPOT-LIGHT] ";
- ts << "[position=\"" << position() << "\"]";
- ts << "[direction=\"" << direction() << "\"]";
- ts << "[specularExponent=\"" << specularExponent() << "\"]";
- ts << "[limitingConeAngle=\"" << limitingConeAngle() << "\"]";
- return ts;
+ if (m_type == LS_SPOT)
+ return static_cast<SpotLightSource*>(this)->setSpecularExponent(specularExponent);
+ return false;
}
-TextStream& DistantLightSource::externalRepresentation(TextStream& ts) const
+bool LightSource::setLimitingConeAngle(float limitingConeAngle)
{
- ts << "[type=DISTANT-LIGHT] ";
- ts << "[azimuth=\"" << azimuth() << "\"]";
- ts << "[elevation=\"" << elevation() << "\"]";
- return ts;
+ if (m_type == LS_SPOT)
+ return static_cast<SpotLightSource*>(this)->setLimitingConeAngle(limitingConeAngle);
+ return false;
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/filters/LightSource.h b/Source/WebCore/platform/graphics/filters/LightSource.h
index 013e910..24c319a 100644
--- a/Source/WebCore/platform/graphics/filters/LightSource.h
+++ b/Source/WebCore/platform/graphics/filters/LightSource.h
@@ -74,6 +74,17 @@ public:
// specified "surfaceScale" constant, which type is <number> in the SVG standard
virtual void updatePaintingData(PaintingData&, int x, int y, float z) = 0;
+ bool setAzimuth(float);
+ bool setElevation(float);
+ bool setX(float);
+ bool setY(float);
+ bool setZ(float);
+ bool setPointsAtX(float);
+ bool setPointsAtY(float);
+ bool setPointsAtZ(float);
+ bool setSpecularExponent(float);
+ bool setLimitingConeAngle(float);
+
private:
LightType m_type;
};
diff --git a/Source/WebCore/platform/graphics/filters/PointLightSource.cpp b/Source/WebCore/platform/graphics/filters/PointLightSource.cpp
new file mode 100644
index 0000000..207ed8e
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/PointLightSource.cpp
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2010 Zoltan Herczeg <zherczeg@webkit.org>
+ * Copyright (C) 2011 University of Szeged
+ * Copyright (C) 2011 Renata Hodovan <reni@webkit.org>
+ *
+ * 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 UNIVERSITY OF SZEGED ``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 UNIVERSITY OF SZEGED OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "PointLightSource.h"
+
+#include "TextStream.h"
+
+namespace WebCore {
+
+void PointLightSource::initPaintingData(PaintingData&)
+{
+}
+
+void PointLightSource::updatePaintingData(PaintingData& paintingData, int x, int y, float z)
+{
+ paintingData.lightVector.setX(m_position.x() - x);
+ paintingData.lightVector.setY(m_position.y() - y);
+ paintingData.lightVector.setZ(m_position.z() - z);
+ paintingData.lightVectorLength = paintingData.lightVector.length();
+}
+
+bool PointLightSource::setX(float x)
+{
+ if (m_position.x() == x)
+ return false;
+ m_position.setX(x);
+ return true;
+}
+
+bool PointLightSource::setY(float y)
+{
+ if (m_position.y() == y)
+ return false;
+ m_position.setY(y);
+ return true;
+}
+
+bool PointLightSource::setZ(float z)
+{
+ if (m_position.z() == z)
+ return false;
+ m_position.setZ(z);
+ return true;
+}
+
+static TextStream& operator<<(TextStream& ts, const FloatPoint3D& p)
+{
+ ts << "x=" << p.x() << " y=" << p.y() << " z=" << p.z();
+ return ts;
+}
+
+TextStream& PointLightSource::externalRepresentation(TextStream& ts) const
+{
+ ts << "[type=POINT-LIGHT] ";
+ ts << "[position=\"" << position() << "\"]";
+ return ts;
+}
+
+}; // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/Source/WebCore/platform/graphics/filters/PointLightSource.h b/Source/WebCore/platform/graphics/filters/PointLightSource.h
index 163c829..a93bf2c 100644
--- a/Source/WebCore/platform/graphics/filters/PointLightSource.h
+++ b/Source/WebCore/platform/graphics/filters/PointLightSource.h
@@ -36,6 +36,9 @@ public:
}
const FloatPoint3D& position() const { return m_position; }
+ bool setX(float);
+ bool setY(float);
+ bool setZ(float);
virtual void initPaintingData(PaintingData&);
virtual void updatePaintingData(PaintingData&, int x, int y, float z);
diff --git a/Source/WebCore/platform/graphics/filters/SpotLightSource.cpp b/Source/WebCore/platform/graphics/filters/SpotLightSource.cpp
new file mode 100644
index 0000000..648fcae
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/SpotLightSource.cpp
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com>
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2010 Zoltan Herczeg <zherczeg@webkit.org>
+ * Copyright (C) 2011 University of Szeged
+ * Copyright (C) 2011 Renata Hodovan <reni@webkit.org>
+ *
+ * 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 UNIVERSITY OF SZEGED ``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 UNIVERSITY OF SZEGED OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "SpotLightSource.h"
+
+#include "TextStream.h"
+
+namespace WebCore {
+
+// spot-light edge darkening depends on an absolute treshold
+// according to the SVG 1.1 SE light regression tests
+static const float antiAliasTreshold = 0.016f;
+
+void SpotLightSource::initPaintingData(PaintingData& paintingData)
+{
+ paintingData.privateColorVector = paintingData.colorVector;
+ paintingData.directionVector.setX(m_direction.x() - m_position.x());
+ paintingData.directionVector.setY(m_direction.y() - m_position.y());
+ paintingData.directionVector.setZ(m_direction.z() - m_position.z());
+ paintingData.directionVector.normalize();
+
+ if (!m_limitingConeAngle) {
+ paintingData.coneCutOffLimit = 0.0f;
+ paintingData.coneFullLight = -antiAliasTreshold;
+ } else {
+ float limitingConeAngle = m_limitingConeAngle;
+ if (limitingConeAngle < 0.0f)
+ limitingConeAngle = -limitingConeAngle;
+ if (limitingConeAngle > 90.0f)
+ limitingConeAngle = 90.0f;
+ paintingData.coneCutOffLimit = cosf(deg2rad(180.0f - limitingConeAngle));
+ paintingData.coneFullLight = paintingData.coneCutOffLimit - antiAliasTreshold;
+ }
+
+ // Optimization for common specularExponent values
+ if (!m_specularExponent)
+ paintingData.specularExponent = 0;
+ else if (m_specularExponent == 1.0f)
+ paintingData.specularExponent = 1;
+ else // It is neither 0.0f nor 1.0f
+ paintingData.specularExponent = 2;
+}
+
+void SpotLightSource::updatePaintingData(PaintingData& paintingData, int x, int y, float z)
+{
+ paintingData.lightVector.setX(m_position.x() - x);
+ paintingData.lightVector.setY(m_position.y() - y);
+ paintingData.lightVector.setZ(m_position.z() - z);
+ paintingData.lightVectorLength = paintingData.lightVector.length();
+
+ float cosineOfAngle = (paintingData.lightVector * paintingData.directionVector) / paintingData.lightVectorLength;
+ if (cosineOfAngle > paintingData.coneCutOffLimit) {
+ // No light is produced, scanlines are not updated
+ paintingData.colorVector.setX(0.0f);
+ paintingData.colorVector.setY(0.0f);
+ paintingData.colorVector.setZ(0.0f);
+ return;
+ }
+
+ // Set the color of the pixel
+ float lightStrength;
+ switch (paintingData.specularExponent) {
+ case 0:
+ lightStrength = 1.0f; // -cosineOfAngle ^ 0 == 1
+ break;
+ case 1:
+ lightStrength = -cosineOfAngle; // -cosineOfAngle ^ 1 == -cosineOfAngle
+ break;
+ default:
+ lightStrength = powf(-cosineOfAngle, m_specularExponent);
+ break;
+ }
+
+ if (cosineOfAngle > paintingData.coneFullLight)
+ lightStrength *= (paintingData.coneCutOffLimit - cosineOfAngle) / (paintingData.coneCutOffLimit - paintingData.coneFullLight);
+
+ if (lightStrength > 1.0f)
+ lightStrength = 1.0f;
+
+ paintingData.colorVector.setX(paintingData.privateColorVector.x() * lightStrength);
+ paintingData.colorVector.setY(paintingData.privateColorVector.y() * lightStrength);
+ paintingData.colorVector.setZ(paintingData.privateColorVector.z() * lightStrength);
+}
+
+bool SpotLightSource::setX(float x)
+{
+ if (m_position.x() == x)
+ return false;
+ m_position.setX(x);
+ return true;
+}
+
+bool SpotLightSource::setY(float y)
+{
+ if (m_position.y() == y)
+ return false;
+ m_position.setY(y);
+ return true;
+}
+
+bool SpotLightSource::setZ(float z)
+{
+ if (m_position.z() == z)
+ return false;
+ m_position.setZ(z);
+ return true;
+}
+
+bool SpotLightSource::setPointsAtX(float pointsAtX)
+{
+ if (m_direction.x() == pointsAtX)
+ return false;
+ m_direction.setX(pointsAtX);
+ return true;
+}
+
+bool SpotLightSource::setPointsAtY(float pointsAtY)
+{
+ if (m_direction.y() == pointsAtY)
+ return false;
+ m_direction.setY(pointsAtY);
+ return true;
+}
+
+bool SpotLightSource::setPointsAtZ(float pointsAtZ)
+{
+ if (m_direction.z() == pointsAtZ)
+ return false;
+ m_direction.setZ(pointsAtZ);
+ return true;
+}
+
+bool SpotLightSource::setSpecularExponent(float specularExponent)
+{
+ if (m_specularExponent == specularExponent)
+ return false;
+ m_specularExponent = specularExponent;
+ return true;
+}
+
+bool SpotLightSource::setLimitingConeAngle(float limitingConeAngle)
+{
+ if (m_limitingConeAngle == limitingConeAngle)
+ return false;
+ m_limitingConeAngle = limitingConeAngle;
+ return true;
+}
+
+static TextStream& operator<<(TextStream& ts, const FloatPoint3D& p)
+{
+ ts << "x=" << p.x() << " y=" << p.y() << " z=" << p.z();
+ return ts;
+}
+
+TextStream& SpotLightSource::externalRepresentation(TextStream& ts) const
+{
+ ts << "[type=SPOT-LIGHT] ";
+ ts << "[position=\"" << position() << "\"]";
+ ts << "[direction=\"" << direction() << "\"]";
+ ts << "[specularExponent=\"" << specularExponent() << "\"]";
+ ts << "[limitingConeAngle=\"" << limitingConeAngle() << "\"]";
+ return ts;
+}
+
+}; // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/Source/WebCore/platform/graphics/filters/SpotLightSource.h b/Source/WebCore/platform/graphics/filters/SpotLightSource.h
index cd6a614..b4f1b61 100644
--- a/Source/WebCore/platform/graphics/filters/SpotLightSource.h
+++ b/Source/WebCore/platform/graphics/filters/SpotLightSource.h
@@ -37,10 +37,18 @@ public:
}
const FloatPoint3D& position() const { return m_position; }
+ bool setX(float);
+ bool setY(float);
+ bool setZ(float);
const FloatPoint3D& direction() const { return m_direction; }
+ bool setPointsAtX(float);
+ bool setPointsAtY(float);
+ bool setPointsAtZ(float);
float specularExponent() const { return m_specularExponent; }
+ bool setSpecularExponent(float);
float limitingConeAngle() const { return m_limitingConeAngle; }
+ bool setLimitingConeAngle(float);
virtual void initPaintingData(PaintingData&);
virtual void updatePaintingData(PaintingData&, int x, int y, float z);
diff --git a/Source/WebCore/platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp b/Source/WebCore/platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp
index c547224..841c8a3 100644
--- a/Source/WebCore/platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp
+++ b/Source/WebCore/platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp
@@ -59,7 +59,7 @@ FontCustomPlatformData::~FontCustomPlatformData()
cairo_font_face_destroy(m_fontFace);
}
-FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, FontRenderingMode)
+FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, FontWidthVariant, FontRenderingMode)
{
return FontPlatformData(m_fontFace, size, bold, italic);
}
diff --git a/Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp b/Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp
index 97fd81a..6290eeb 100644
--- a/Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp
+++ b/Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp
@@ -50,21 +50,28 @@ void SimpleFontData::platformInit()
cairo_font_extents_t font_extents;
cairo_text_extents_t text_extents;
cairo_scaled_font_extents(m_platformData.scaledFont(), &font_extents);
- m_ascent = static_cast<int>(lroundf(font_extents.ascent));
- m_descent = static_cast<int>(lroundf(font_extents.descent));
- m_lineSpacing = static_cast<int>(lroundf(font_extents.height));
+
+ m_fontMetrics.setAscent(font_extents.ascent);
+ m_fontMetrics.setDescent(font_extents.descent);
+
// There seems to be some rounding error in cairo (or in how we
// use cairo) with some fonts, like DejaVu Sans Mono, which makes
// cairo report a height smaller than ascent + descent, which is
// wrong and confuses WebCore's layout system. Workaround this
// while we figure out what's going on.
- if (m_lineSpacing < m_ascent + m_descent)
- m_lineSpacing = m_ascent + m_descent;
+ float lineSpacing = font_extents.height;
+ if (lineSpacing < font_extents.ascent + font_extents.descent)
+ lineSpacing = font_extents.ascent + font_extents.descent;
+
+ m_fontMetrics.setLineSpacing(lroundf(lineSpacing));
+ m_fontMetrics.setLineGap(lineSpacing - font_extents.ascent - font_extents.descent);
+
cairo_scaled_font_text_extents(m_platformData.scaledFont(), "x", &text_extents);
- m_xHeight = text_extents.height;
+ m_fontMetrics.setXHeight(text_extents.height);
+
cairo_scaled_font_text_extents(m_platformData.scaledFont(), " ", &text_extents);
m_spaceWidth = static_cast<float>(text_extents.x_advance);
- m_lineGap = m_lineSpacing - m_ascent - m_descent;
+
m_syntheticBoldOffset = m_platformData.syntheticBold() ? 1.0f : 0.f;
}
diff --git a/Source/WebCore/platform/graphics/gpu/DrawingBuffer.cpp b/Source/WebCore/platform/graphics/gpu/DrawingBuffer.cpp
index dae83a2..2a83fcf 100644
--- a/Source/WebCore/platform/graphics/gpu/DrawingBuffer.cpp
+++ b/Source/WebCore/platform/graphics/gpu/DrawingBuffer.cpp
@@ -30,7 +30,7 @@
#include "config.h"
-#if ENABLE(ACCELERATED_2D_CANVAS) || ENABLE(3D_CANVAS)
+#if ENABLE(ACCELERATED_2D_CANVAS) || ENABLE(WEBGL)
#include "DrawingBuffer.h"
@@ -41,10 +41,11 @@ namespace WebCore {
PassRefPtr<DrawingBuffer> DrawingBuffer::create(GraphicsContext3D* context, const IntSize& size)
{
Extensions3D* extensions = context->getExtensions();
- bool multisampleSupported = extensions->supports("GL_ANGLE_framebuffer_blit") && extensions->supports("GL_ANGLE_framebuffer_multisample");
+ bool multisampleSupported = extensions->supports("GL_ANGLE_framebuffer_blit") && extensions->supports("GL_ANGLE_framebuffer_multisample") && extensions->supports("GL_OES_rgb8_rgba8");
if (multisampleSupported) {
extensions->ensureEnabled("GL_ANGLE_framebuffer_blit");
extensions->ensureEnabled("GL_ANGLE_framebuffer_multisample");
+ extensions->ensureEnabled("GL_OES_rgb8_rgba8");
}
bool packedDepthStencilSupported = extensions->supports("GL_OES_packed_depth_stencil");
if (packedDepthStencilSupported)
@@ -145,8 +146,6 @@ void DrawingBuffer::resizeDepthStencil(int sampleCount)
void DrawingBuffer::reset(const IntSize& newSize)
{
- if (m_size == newSize)
- return;
m_size = newSize;
if (!m_context)
@@ -155,13 +154,15 @@ void DrawingBuffer::reset(const IntSize& newSize)
m_context->makeContextCurrent();
const GraphicsContext3D::Attributes& attributes = m_context->getContextAttributes();
- unsigned long internalColorFormat, colorFormat;
+ unsigned long internalColorFormat, colorFormat, internalRenderbufferFormat;
if (attributes.alpha) {
internalColorFormat = GraphicsContext3D::RGBA;
colorFormat = GraphicsContext3D::RGBA;
+ internalRenderbufferFormat = Extensions3D::RGBA8_OES;
} else {
internalColorFormat = GraphicsContext3D::RGB;
colorFormat = GraphicsContext3D::RGB;
+ internalRenderbufferFormat = Extensions3D::RGB8_OES;
}
@@ -175,7 +176,7 @@ void DrawingBuffer::reset(const IntSize& newSize)
m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO);
m_context->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, m_multisampleColorBuffer);
- m_context->getExtensions()->renderbufferStorageMultisample(GraphicsContext3D::RENDERBUFFER, sampleCount, internalColorFormat, m_size.width(), m_size.height());
+ m_context->getExtensions()->renderbufferStorageMultisample(GraphicsContext3D::RENDERBUFFER, sampleCount, internalRenderbufferFormat, m_size.width(), m_size.height());
m_context->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::RENDERBUFFER, m_multisampleColorBuffer);
resizeDepthStencil(sampleCount);
if (m_context->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) != GraphicsContext3D::FRAMEBUFFER_COMPLETE) {
@@ -192,7 +193,8 @@ void DrawingBuffer::reset(const IntSize& newSize)
m_context->texImage2DResourceSafe(GraphicsContext3D::TEXTURE_2D, 0, internalColorFormat, m_size.width(), m_size.height(), 0, colorFormat, GraphicsContext3D::UNSIGNED_BYTE);
m_context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, m_colorBuffer, 0);
m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, 0);
- resizeDepthStencil(0);
+ if (!multisample())
+ resizeDepthStencil(0);
if (m_context->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) != GraphicsContext3D::FRAMEBUFFER_COMPLETE) {
// Cleanup
clear();
diff --git a/Source/WebCore/platform/graphics/gpu/LoopBlinnPathCache.cpp b/Source/WebCore/platform/graphics/gpu/LoopBlinnPathCache.cpp
new file mode 100644
index 0000000..35f15e5
--- /dev/null
+++ b/Source/WebCore/platform/graphics/gpu/LoopBlinnPathCache.cpp
@@ -0,0 +1,86 @@
+/*
+ * 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:
+ *
+ * 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 AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "LoopBlinnPathCache.h"
+
+namespace WebCore {
+
+LoopBlinnPathCache::LoopBlinnPathCache()
+{
+}
+
+LoopBlinnPathCache::~LoopBlinnPathCache()
+{
+}
+
+void LoopBlinnPathCache::addVertex(float x, float y,
+ float k, float l, float m)
+{
+ m_vertices.append(x);
+ m_vertices.append(y);
+ m_texcoords.append(k);
+ m_texcoords.append(l);
+ m_texcoords.append(m);
+}
+
+void LoopBlinnPathCache::clear()
+{
+ m_vertices.clear();
+ m_texcoords.clear();
+ m_interiorVertices.clear();
+#ifdef LOOP_BLINN_PATH_CACHE_DEBUG_INTERIOR_EDGES
+ m_interiorEdgeVertices.clear();
+#endif // LOOP_BLINN_PATH_CACHE_DEBUG_INTERIOR_EDGES
+}
+
+void LoopBlinnPathCache::addInteriorVertex(float x, float y)
+{
+ m_interiorVertices.append(x);
+ m_interiorVertices.append(y);
+}
+
+#ifdef LOOP_BLINN_PATH_CACHE_DEBUG_INTERIOR_EDGES
+unsigned LoopBlinnPathCache::numberOfInteriorEdgeVertices() const
+{
+ return m_interiorEdgeVertices.size() / 2;
+}
+
+const float* LoopBlinnPathCache::interiorEdgeVertices() const
+{
+ if (!numberOfInteriorEdgeVertices())
+ return 0;
+ return m_interiorEdgeVertices.data();
+}
+
+void LoopBlinnPathCache::addInteriorEdgeVertex(float x, float y)
+{
+ m_interiorEdgeVertices.append(x);
+ m_interiorEdgeVertices.append(y);
+}
+#endif // LOOP_BLINN_PATH_CACHE_DEBUG_INTERIOR_EDGES
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/gpu/LoopBlinnPathCache.h b/Source/WebCore/platform/graphics/gpu/LoopBlinnPathCache.h
new file mode 100644
index 0000000..d21d246
--- /dev/null
+++ b/Source/WebCore/platform/graphics/gpu/LoopBlinnPathCache.h
@@ -0,0 +1,123 @@
+/*
+ * 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:
+ *
+ * 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 AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LoopBlinnPathCache_h
+#define LoopBlinnPathCache_h
+
+#include <wtf/Noncopyable.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+// A cache of the processed triangle mesh for a given path. Because these
+// might be expensive to allocate (using malloc/free internally), it is
+// recommended to try to reuse them when possible.
+
+// Uncomment the following to obtain debugging information for the edges
+// facing the interior region of the mesh.
+// #define LOOP_BLINN_PATH_CACHE_DEBUG_INTERIOR_EDGES
+
+class LoopBlinnPathCache {
+ WTF_MAKE_NONCOPYABLE(LoopBlinnPathCache);
+public:
+ LoopBlinnPathCache();
+ ~LoopBlinnPathCache();
+
+ unsigned numberOfVertices() const { return m_vertices.size() / 2; }
+
+ // Get the base pointer to the vertex information. There are two
+ // coordinates per vertex. This pointer is valid until the cache is
+ // cleared or another vertex is added. Returns 0 if there are no
+ // vertices in the mesh.
+ const float* vertices() const
+ {
+ if (!numberOfVertices())
+ return 0;
+ return m_vertices.data();
+ }
+
+ // Get the base pointer to the texture coordinate information. There
+ // are three coordinates per vertex. This pointer is valid until the
+ // cache is cleared or another vertex is added. Returns 0 if
+ // there are no vertices in the mesh.
+ const float* texcoords() const
+ {
+ if (!numberOfVertices())
+ return 0;
+ return m_texcoords.data();
+ }
+
+ // Adds a vertex's information to the cache. The first two arguments
+ // are the x and y coordinates of the vertex on the plane; the last
+ // three arguments are the cubic texture coordinates associated with
+ // this vertex.
+ void addVertex(float x, float y,
+ float /*k*/, float /*l*/, float /*m*/);
+
+ unsigned numberOfInteriorVertices() const { return m_interiorVertices.size() / 2; }
+
+ // Base pointer to the interior vertices; two coordinates per
+ // vertex, which can be drawn as GL_TRIANGLES. Returns 0 if there
+ // are no interior vertices in the mesh.
+ const float* interiorVertices() const
+ {
+ if (!numberOfInteriorVertices())
+ return 0;
+ return m_interiorVertices.data();
+ }
+
+ void addInteriorVertex(float x, float y);
+
+ // Clears all of the stored vertex information in this cache.
+ void clear();
+
+#ifdef LOOP_BLINN_PATH_CACHE_DEBUG_INTERIOR_EDGES
+ // The number of interior edge vertices
+ unsigned numberOfInteriorEdgeVertices() const;
+ // Base pointer to the interior vertices; two coordinates per
+ // vertex, which can be drawn as GL_LINES. Returns 0 if there are
+ // no interior edge vertices in the mesh.
+ const float* interiorEdgeVertices() const;
+ void addInteriorEdgeVertex(float x, float y);
+#endif // LOOP_BLINN_PATH_CACHE_DEBUG_INTERIOR_EDGES
+
+private:
+ // The two-dimensional vertices of the triangle mesh.
+ Vector<float> m_vertices;
+
+ // The three-dimensional cubic texture coordinates.
+ Vector<float> m_texcoords;
+
+ Vector<float> m_interiorVertices;
+
+#ifdef LOOP_BLINN_PATH_CACHE_DEBUG_INTERIOR_EDGES
+ // The following is only for debugging
+ Vector<float> m_interiorEdgeVertices;
+#endif // LOOP_BLINN_PATH_CACHE_DEBUG_INTERIOR_EDGES
+};
+
+} // namespace WebCore
+
+#endif // LoopBlinnPathCache_h
diff --git a/Source/WebCore/platform/graphics/gpu/LoopBlinnPathProcessor.cpp b/Source/WebCore/platform/graphics/gpu/LoopBlinnPathProcessor.cpp
new file mode 100644
index 0000000..e84ddbf
--- /dev/null
+++ b/Source/WebCore/platform/graphics/gpu/LoopBlinnPathProcessor.cpp
@@ -0,0 +1,1228 @@
+/*
+ * 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:
+ *
+ * 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 AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "LoopBlinnPathProcessor.h"
+
+#include "FloatPoint.h"
+#include "FloatRect.h"
+#include "LoopBlinnClassifier.h"
+#include "LoopBlinnConstants.h"
+#include "LoopBlinnLocalTriangulator.h"
+#include "LoopBlinnMathUtils.h"
+#include "LoopBlinnPathCache.h"
+#include "LoopBlinnTextureCoords.h"
+#include "PODArena.h"
+#include "PODIntervalTree.h"
+#include "Path.h"
+#include "internal_glu.h"
+#include <algorithm>
+#include <wtf/Assertions.h>
+#include <wtf/FastMalloc.h>
+
+#if PLATFORM(SKIA)
+#include "SkGeometry.h"
+#include "SkPath.h"
+#include "SkScalar.h"
+#else
+// Must port to your platform.
+#endif
+
+namespace WebCore {
+
+using LoopBlinnMathUtils::XRay;
+using LoopBlinnMathUtils::chopCubicAt;
+using LoopBlinnMathUtils::numXRayCrossingsForCubic;
+using LoopBlinnMathUtils::trianglesOverlap;
+using LoopBlinnMathUtils::xRayCrossesLine;
+using LoopBlinnPathProcessorImplementation::Contour;
+using LoopBlinnPathProcessorImplementation::Segment;
+
+namespace {
+
+#ifndef NDEBUG
+String valueToString(const FloatRect& arg)
+{
+ StringBuilder builder;
+ builder.append("[FloatRect x=");
+ builder.append(String::number(arg.x()));
+ builder.append(" y=");
+ builder.append(String::number(arg.y()));
+ builder.append(" maxX=");
+ builder.append(String::number(arg.maxX()));
+ builder.append(" maxY=");
+ builder.append(String::number(arg.maxY()));
+ builder.append("]");
+ return builder.toString();
+}
+#endif
+
+struct SweepData;
+
+} // anonymous namespace
+
+namespace LoopBlinnPathProcessorImplementation {
+class Segment;
+}
+
+#ifndef NDEBUG
+// Routines needed to print the types of IntervalNodes we instantiate
+// in this file.
+template <>
+struct ValueToString<float> {
+ static String string(const float& value)
+ {
+ return String::number(value);
+ }
+};
+
+template <>
+struct ValueToString<SweepData*> {
+ static String string(SweepData* const& value)
+ {
+ return String::format("0x%p", value);
+ }
+};
+
+template <>
+struct ValueToString<LoopBlinnPathProcessorImplementation::Segment*> {
+ static String string(LoopBlinnPathProcessorImplementation::Segment* const& value)
+ {
+ return String::format("0x%p", value);
+ }
+};
+#endif
+
+namespace LoopBlinnPathProcessorImplementation {
+
+//----------------------------------------------------------------------
+// Segment
+//
+
+// Describes a segment of the path: either a cubic or a line segment.
+// These are stored in a doubly linked list to speed up curve
+// subdivision, which occurs due to either rendering artifacts in the
+// loop case or due to overlapping triangles.
+class Segment {
+ WTF_MAKE_NONCOPYABLE(Segment);
+public:
+ enum Kind {
+ Cubic,
+ Line
+ };
+
+ // No-argument constructor allows construction by the PODArena class.
+ Segment()
+ : m_arena(0)
+ , m_kind(Cubic)
+ , m_prev(0)
+ , m_next(0)
+ , m_contour(0)
+ , m_triangulator(0)
+ , m_markedForSubdivision(false)
+ {
+ }
+
+ // Initializer for cubic curve segments.
+ void setup(PODArena* arena,
+ Contour* contour,
+ FloatPoint cp0,
+ FloatPoint cp1,
+ FloatPoint cp2,
+ FloatPoint cp3)
+ {
+ m_arena = arena;
+ m_contour = contour;
+ m_kind = Cubic;
+ m_points[0] = cp0;
+ m_points[1] = cp1;
+ m_points[2] = cp2;
+ m_points[3] = cp3;
+ computeBoundingBox();
+ }
+
+ // Initializer for line segments.
+ void setup(PODArena* arena,
+ Contour* contour,
+ FloatPoint p0,
+ FloatPoint p1)
+ {
+ m_arena = arena;
+ m_contour = contour;
+ m_kind = Line;
+ m_points[0] = p0;
+ m_points[1] = p1;
+ computeBoundingBox();
+ }
+
+ Kind kind() const { return m_kind; }
+
+ // Returns the i'th control point, 0 <= i < 4.
+ const FloatPoint& getPoint(int i)
+ {
+ ASSERT(i >= 0 && i < 4);
+ return m_points[i];
+ }
+
+ Segment* next() const { return m_next; }
+ Segment* prev() const { return m_prev; }
+
+ void setNext(Segment* next) { m_next = next; }
+ void setPrev(Segment* prev) { m_prev = prev; }
+
+ // The contour this segment belongs to.
+ Contour* contour() const { return m_contour; }
+
+ // Subdivides the current segment at the given parameter value (0 <=
+ // t <= 1) and replaces it with the two newly created Segments in
+ // the linked list, if possible. Returns a pointer to the leftmost
+ // Segment.
+ Segment* subdivide(float param)
+ {
+ FloatPoint dst[7];
+ chopCubicAt(m_points, dst, param);
+ Segment* left = m_arena->allocateObject<Segment>();
+ Segment* right = m_arena->allocateObject<Segment>();
+ left->setup(m_arena, m_contour, dst[0], dst[1], dst[2], dst[3]);
+ right->setup(m_arena, m_contour, dst[3], dst[4], dst[5], dst[6]);
+ left->setNext(right);
+ right->setPrev(left);
+ // Try to set up a link between "this->prev()" and "left".
+ if (prev()) {
+ left->setPrev(prev());
+ prev()->setNext(left);
+ }
+ // Try to set up a link between "this->next()" and "right".
+ Segment* n = next();
+ if (n) {
+ right->setNext(n);
+ n->setPrev(right);
+ }
+ // Set up a link between "this" and "left"; this is only to
+ // provide a certain amount of continuity during forward iteration.
+ setNext(left);
+ return left;
+ }
+
+ // Subdivides the current segment at the halfway point and replaces
+ // it with the two newly created Segments in the linked list, if
+ // possible. Returns a pointer to the leftmost Segment.
+ Segment* subdivide() { return subdivide(0.5f); }
+
+ const FloatRect& boundingBox() const { return m_boundingBox; }
+
+ // Computes the number of times a query line starting at the given
+ // point and extending to x=+infinity crosses this segment. Outgoing
+ // "ambiguous" argument indicates whether the query intersected an
+ // endpoint or tangent point of the segment, indicating that another
+ // query point is preferred.
+ int numCrossingsForXRay(const XRay& xRay, bool& ambiguous) const
+ {
+ if (m_kind == Cubic)
+ // Should consider caching the monotonic cubics.
+ return numXRayCrossingsForCubic(xRay, m_points, ambiguous);
+
+ return xRayCrossesLine(xRay, m_points, ambiguous) ? 1 : 0;
+ }
+
+ // Performs a local triangulation of the control points in this
+ // segment. This operation only makes sense for cubic type segments.
+ // texCoords may be null when the klm coordinates have not been
+ // computed yet.
+ void triangulate(LoopBlinnLocalTriangulator::InsideEdgeComputation computeInsideEdges,
+ const LoopBlinnTextureCoords::Result* texCoords);
+
+ // Returns the number of control point triangles associated with
+ // this segment.
+ int numberOfTriangles() const
+ {
+ if (!m_triangulator)
+ return 0;
+ return m_triangulator->numberOfTriangles();
+ }
+
+ // Fetches the given control point triangle for this segment.
+ LoopBlinnLocalTriangulator::Triangle* getTriangle(int index)
+ {
+ ASSERT(m_triangulator);
+ return m_triangulator->getTriangle(index);
+ }
+
+ // Number of vertices along the inside edge of this segment. This
+ // can be called either for line or cubic type segments.
+ int numberOfInteriorVertices() const
+ {
+ if (m_kind == Cubic) {
+ if (m_triangulator)
+ return m_triangulator->numberOfInteriorVertices();
+
+ return 0;
+ }
+
+ return 2;
+ }
+
+ // Returns the given interior vertex, 0 <= index < numberOfInteriorVertices().
+ FloatPoint getInteriorVertex(int index) const
+ {
+ ASSERT(index >= 0 && index < numberOfInteriorVertices());
+ if (m_kind == Cubic) {
+ FloatPoint res;
+ if (m_triangulator) {
+ LoopBlinnLocalTriangulator::Vertex* vertex = m_triangulator->getInteriorVertex(index);
+ if (vertex)
+ res.set(vertex->xyCoordinates().x(), vertex->xyCoordinates().y());
+ }
+ return res;
+ }
+
+ return m_points[index];
+ }
+
+ // State to assist with curve subdivision.
+ bool markedForSubdivision() const { return m_markedForSubdivision; }
+ void setMarkedForSubdivision(bool markedForSubdivision) { m_markedForSubdivision = markedForSubdivision; }
+
+#ifndef NDEBUG
+ // Suppport for printing Segments.
+ String toString() const
+ {
+ StringBuilder builder;
+ builder.append("[Segment kind=");
+ builder.append(kind() == Line ? "line" : "cubic");
+ builder.append(" boundingBox=");
+ builder.append(valueToString(boundingBox()));
+ builder.append(" contour=0x");
+ builder.append(String::format("%p", contour()));
+ builder.append(" markedForSubdivision=");
+ builder.append(markedForSubdivision() ? "true" : "false");
+ builder.append("]");
+ return builder.toString();
+ }
+#endif
+
+ private:
+ // Computes the bounding box of this Segment.
+ void computeBoundingBox()
+ {
+ switch (m_kind) {
+ case Cubic:
+ m_boundingBox.fitToPoints(m_points[0], m_points[1], m_points[2], m_points[3]);
+ break;
+
+ case Line:
+ m_boundingBox.fitToPoints(m_points[0], m_points[1]);
+ break;
+ }
+ }
+
+ PODArena* m_arena;
+ Kind m_kind;
+ FloatPoint m_points[4];
+ Segment* m_prev;
+ Segment* m_next;
+ Contour* m_contour;
+ FloatRect m_boundingBox;
+ LoopBlinnLocalTriangulator* m_triangulator;
+ bool m_markedForSubdivision;
+};
+
+//----------------------------------------------------------------------
+// Contour
+//
+
+// Describes a closed contour of the path.
+class Contour {
+ WTF_MAKE_NONCOPYABLE(Contour);
+public:
+ Contour()
+ {
+ m_first = &m_sentinel;
+ m_first->setNext(m_first);
+ m_first->setPrev(m_first);
+ m_isOrientedCounterClockwise = true;
+ m_boundingBoxDirty = false;
+ m_fillSide = LoopBlinnConstants::RightSide;
+ }
+
+ void add(Segment* segment)
+ {
+ if (m_first == &m_sentinel) {
+ // First element is the sentinel. Replace it with the incoming
+ // segment.
+ segment->setNext(m_first);
+ segment->setPrev(m_first);
+ m_first->setNext(segment);
+ m_first->setPrev(segment);
+ m_first = segment;
+ } else {
+ // m_first->prev() is the sentinel.
+ ASSERT(m_first->prev() == &m_sentinel);
+ Segment* last = m_sentinel.prev();
+ last->setNext(segment);
+ segment->setPrev(last);
+ segment->setNext(&m_sentinel);
+ m_sentinel.setPrev(segment);
+ }
+ m_boundingBoxDirty = true;
+ }
+
+ // Subdivides the given segment at the given parametric value.
+ // Returns a pointer to the first of the two portions of the
+ // subdivided segment.
+ Segment* subdivide(Segment* segment, float param)
+ {
+ Segment* left = segment->subdivide(param);
+ if (m_first == segment)
+ m_first = left;
+ return left;
+ }
+
+ // Subdivides the given segment at the halfway point. Returns a
+ // pointer to the first of the two portions of the subdivided
+ // segment.
+ Segment* subdivide(Segment* segment)
+ {
+ Segment* left = segment->subdivide();
+ if (m_first == segment)
+ m_first = left;
+ return left;
+ }
+
+ // Returns the first segment in the contour for iteration.
+ Segment* begin() const { return m_first; }
+
+ // Returns the last segment in the contour for iteration. Callers
+ // should not iterate over this segment. In other words:
+ // for (Segment* cur = contour->begin();
+ // cur != contour->end();
+ // cur = cur->next()) {
+ // // .. process cur ...
+ // }
+ Segment* end()
+ {
+ ASSERT(m_first->prev() == &m_sentinel);
+ return &m_sentinel;
+ }
+
+ bool isOrientedCounterClockwise() const { return m_isOrientedCounterClockwise; }
+ void setIsOrientedCounterClockwise(bool isOrientedCounterClockwise) { m_isOrientedCounterClockwise = isOrientedCounterClockwise; }
+
+ const FloatRect& boundingBox()
+ {
+ if (m_boundingBoxDirty) {
+ bool first = true;
+ for (Segment* cur = begin(); cur != end(); cur = cur->next()) {
+ if (first)
+ m_boundingBox = cur->boundingBox();
+ else
+ m_boundingBox.unite(cur->boundingBox());
+ first = false;
+ }
+
+ m_boundingBoxDirty = false;
+ }
+ return m_boundingBox;
+ }
+
+ // Returns which side of this contour is filled.
+ LoopBlinnConstants::FillSide fillSide() const
+ {
+ return m_fillSide;
+ }
+
+ void setFillSide(LoopBlinnConstants::FillSide fillSide)
+ {
+ m_fillSide = fillSide;
+ }
+
+private:
+ // The start of the segment chain. The segments are kept in a
+ // circular doubly linked list for rapid access to the beginning and
+ // end.
+ Segment* m_first;
+
+ // The sentinel element at the end of the chain, needed for
+ // reasonable iteration semantics.
+ Segment m_sentinel;
+
+ bool m_isOrientedCounterClockwise;
+
+ FloatRect m_boundingBox;
+ bool m_boundingBoxDirty;
+
+ // Which side of this contour should be filled.
+ LoopBlinnConstants::FillSide m_fillSide;
+};
+
+//----------------------------------------------------------------------
+// Segment
+//
+
+// Definition of Segment::triangulate(), which must come after
+// declaration of Contour.
+void Segment::triangulate(LoopBlinnLocalTriangulator::InsideEdgeComputation computeInsideEdges,
+ const LoopBlinnTextureCoords::Result* texCoords)
+{
+ ASSERT(m_kind == Cubic);
+ if (!m_triangulator)
+ m_triangulator = m_arena->allocateObject<LoopBlinnLocalTriangulator>();
+ m_triangulator->reset();
+ for (int i = 0; i < 4; i++) {
+ LoopBlinnLocalTriangulator::Vertex* vertex = m_triangulator->getVertex(i);
+ if (texCoords) {
+ vertex->set(getPoint(i).x(),
+ getPoint(i).y(),
+ texCoords->klmCoordinates[i].x(),
+ texCoords->klmCoordinates[i].y(),
+ texCoords->klmCoordinates[i].z());
+ } else {
+ vertex->set(getPoint(i).x(),
+ getPoint(i).y(),
+ // No texture coordinates yet
+ 0, 0, 0);
+ }
+ }
+ m_triangulator->triangulate(computeInsideEdges, contour()->fillSide());
+}
+
+} // namespace LoopBlinnPathProcessorImplementation
+
+//----------------------------------------------------------------------
+// LoopBlinnPathProcessor
+//
+
+LoopBlinnPathProcessor::LoopBlinnPathProcessor()
+ : m_arena(PODArena::create())
+#ifndef NDEBUG
+ , m_verboseLogging(false)
+#endif
+{
+}
+
+LoopBlinnPathProcessor::LoopBlinnPathProcessor(PassRefPtr<PODArena> arena)
+ : m_arena(arena)
+#ifndef NDEBUG
+ , m_verboseLogging(false)
+#endif
+{
+}
+
+LoopBlinnPathProcessor::~LoopBlinnPathProcessor()
+{
+}
+
+void LoopBlinnPathProcessor::process(const Path& path, LoopBlinnPathCache& cache)
+{
+ buildContours(path);
+
+ // Run plane-sweep algorithm to determine overlaps of control point
+ // curves and subdivide curves appropriately.
+ subdivideCurves();
+
+ // Determine orientations of countours. Based on orientation and the
+ // number of curve crossings at a random point on the contour,
+ // determine whether to fill the left or right side of the contour.
+ determineSidesToFill();
+
+ // Classify curves, compute texture coordinates and subdivide as
+ // necessary to eliminate rendering artifacts. Do the final
+ // triangulation of the curve segments, determining the path along
+ // the interior of the shape.
+ for (Vector<Contour*>::iterator iter = m_contours.begin(); iter != m_contours.end(); ++iter) {
+ Contour* cur = *iter;
+ for (Segment* seg = cur->begin(); seg != cur->end(); seg = seg->next()) {
+ if (seg->kind() == Segment::Cubic) {
+ LoopBlinnClassifier::Result classification = LoopBlinnClassifier::classify(seg->getPoint(0),
+ seg->getPoint(1),
+ seg->getPoint(2),
+ seg->getPoint(3));
+#ifndef NDEBUG
+ if (m_verboseLogging)
+ LOG_ERROR("Classification: %d", (int) classification.curveType);
+#endif
+ LoopBlinnTextureCoords::Result texCoords =
+ LoopBlinnTextureCoords::compute(classification, cur->fillSide());
+ if (texCoords.hasRenderingArtifact) {
+ // FIXME: there is a problem where the algorithm
+ // sometimes fails to converge when splitting at the
+ // subdivision parameter value. For the time being,
+ // split halfway.
+ cur->subdivide(seg);
+ // Next iteration will handle the newly subdivided curves
+ } else {
+ if (!texCoords.isLineOrPoint) {
+ seg->triangulate(LoopBlinnLocalTriangulator::ComputeInsideEdges, &texCoords);
+ for (int i = 0; i < seg->numberOfTriangles(); i++) {
+ LoopBlinnLocalTriangulator::Triangle* triangle = seg->getTriangle(i);
+ for (int j = 0; j < 3; j++) {
+ LoopBlinnLocalTriangulator::Vertex* vert = triangle->getVertex(j);
+ cache.addVertex(vert->xyCoordinates().x(),
+ vert->xyCoordinates().y(),
+ vert->klmCoordinates().x(),
+ vert->klmCoordinates().y(),
+ vert->klmCoordinates().z());
+ }
+ }
+#ifdef LOOP_BLINN_PATH_CACHE_DEBUG_INTERIOR_EDGES
+ // Show the end user the interior edges as well
+ for (int i = 1; i < seg->numberOfInteriorVertices(); i++) {
+ FloatPoint vert = seg->getInteriorVertex(i);
+ // Duplicate previous vertex to be able to draw GL_LINES
+ FloatPoint prev = seg->getInteriorVertex(i - 1);
+ cache.addInteriorEdgeVertex(prev.x(), prev.y());
+ cache.addInteriorEdgeVertex(vert.x(), vert.y());
+ }
+#endif // LOOP_BLINN_PATH_CACHE_DEBUG_INTERIOR_EDGES
+ }
+ }
+ }
+ }
+ }
+
+ // Run the interior paths through a tessellation algorithm
+ // supporting multiple contours.
+ tessellateInterior(cache);
+}
+
+void LoopBlinnPathProcessor::buildContours(const Path& path)
+{
+ // Clear out the contours
+ m_contours.clear();
+#if PLATFORM(SKIA)
+ SkPath::Iter iter(*path.platformPath(), false);
+ SkPoint points[4];
+ SkPath::Verb verb;
+ Contour* contour = 0;
+ SkPoint curPoint = { 0 };
+ SkPoint moveToPoint = { 0 };
+ do {
+ verb = iter.next(points);
+ if (verb != SkPath::kMove_Verb) {
+ if (!contour) {
+ contour = m_arena->allocateObject<Contour>();
+ m_contours.append(contour);
+ }
+ }
+ switch (verb) {
+ case SkPath::kMove_Verb: {
+ contour = m_arena->allocateObject<Contour>();
+ m_contours.append(contour);
+ curPoint = points[0];
+ moveToPoint = points[0];
+#ifndef NDEBUG
+ if (m_verboseLogging)
+ LOG_ERROR("MoveTo (%f, %f)", points[0].fX, points[0].fY);
+#endif
+ break;
+ }
+ case SkPath::kLine_Verb: {
+ Segment* segment = m_arena->allocateObject<Segment>();
+ if (iter.isCloseLine()) {
+ segment->setup(m_arena.get(), contour, curPoint, points[1]);
+#ifndef NDEBUG
+ if (m_verboseLogging)
+ LOG_ERROR("CloseLineTo (%f, %f), (%f, %f)", curPoint.fX, curPoint.fY, points[1].fX, points[1].fY);
+#endif
+ contour->add(segment);
+ contour = 0;
+ } else {
+ segment->setup(m_arena.get(), contour, points[0], points[1]);
+#ifndef NDEBUG
+ if (m_verboseLogging)
+ LOG_ERROR("LineTo (%f, %f), (%f, %f)", points[0].fX, points[0].fY, points[1].fX, points[1].fY);
+#endif
+ contour->add(segment);
+ curPoint = points[1];
+ }
+ break;
+ }
+ case SkPath::kQuad_Verb: {
+ // Need to degree elevate the quadratic into a cubic
+ SkPoint cubic[4];
+ SkConvertQuadToCubic(points, cubic);
+ Segment* segment = m_arena->allocateObject<Segment>();
+ segment->setup(m_arena.get(), contour,
+ cubic[0], cubic[1], cubic[2], cubic[3]);
+#ifndef NDEBUG
+ if (m_verboseLogging)
+ LOG_ERROR("Quad->CubicTo (%f, %f), (%f, %f), (%f, %f), (%f, %f)", cubic[0].fX, cubic[0].fY, cubic[1].fX, cubic[1].fY, cubic[2].fX, cubic[2].fY, cubic[3].fX, cubic[3].fY);
+#endif
+ contour->add(segment);
+ curPoint = cubic[3];
+ break;
+ }
+ case SkPath::kCubic_Verb: {
+ Segment* segment = m_arena->allocateObject<Segment>();
+ segment->setup(m_arena.get(), contour, points[0], points[1], points[2], points[3]);
+#ifndef NDEBUG
+ if (m_verboseLogging)
+ LOG_ERROR("CubicTo (%f, %f), (%f, %f), (%f, %f), (%f, %f)", points[0].fX, points[0].fY, points[1].fX, points[1].fY, points[2].fX, points[2].fY, points[3].fX, points[3].fY);
+#endif
+ contour->add(segment);
+ curPoint = points[3];
+ break;
+ }
+ case SkPath::kClose_Verb: {
+ Segment* segment = m_arena->allocateObject<Segment>();
+ segment->setup(m_arena.get(), contour, curPoint, moveToPoint);
+#ifndef NDEBUG
+ if (m_verboseLogging)
+ LOG_ERROR("Close (%f, %f) -> (%f, %f)", curPoint.fX, curPoint.fY, moveToPoint.fX, moveToPoint.fY);
+#endif
+ contour->add(segment);
+ contour = 0;
+ }
+ case SkPath::kDone_Verb:
+ break;
+ }
+ } while (verb != SkPath::kDone_Verb);
+#else // !PLATFORM(SKIA)
+ // Must port to your platform.
+ ASSERT_NOT_REACHED();
+#endif
+}
+
+#ifndef NDEBUG
+Vector<Segment*> LoopBlinnPathProcessor::allSegmentsOverlappingY(Contour* queryContour, float x, float y)
+{
+ Vector<Segment*> res;
+ for (Vector<Contour*>::iterator iter = m_contours.begin(); iter != m_contours.end(); ++iter) {
+ Contour* cur = *iter;
+ for (Segment* seg = cur->begin(); seg != cur->end(); seg = seg->next()) {
+ const FloatRect& boundingBox = seg->boundingBox();
+ if (boundingBox.y() <= y && y <= boundingBox.maxY())
+ res.append(seg);
+ }
+ }
+ return res;
+}
+#endif
+
+// Uncomment this to debug the orientation computation.
+// #define GPU_PATH_PROCESSOR_DEBUG_ORIENTATION
+
+void LoopBlinnPathProcessor::determineSidesToFill()
+{
+ // Loop and Blinn's algorithm can only easily emulate the even/odd
+ // fill rule, and only for non-intersecting curves. We can determine
+ // which side of each curve segment to fill based on its
+ // clockwise/counterclockwise orientation and how many other
+ // contours surround it.
+
+ // To optimize the query of all curve segments intersecting a
+ // horizontal line going to x=+infinity, we build up an interval
+ // tree whose keys are the y extents of the segments.
+ PODIntervalTree<float, Segment*> tree(m_arena);
+ typedef PODIntervalTree<float, Segment*>::IntervalType IntervalType;
+
+ for (Vector<Contour*>::iterator iter = m_contours.begin(); iter != m_contours.end(); ++iter) {
+ Contour* cur = *iter;
+ determineOrientation(cur);
+ for (Segment* seg = cur->begin(); seg != cur->end(); seg = seg->next()) {
+ const FloatRect& boundingBox = seg->boundingBox();
+ tree.add(tree.createInterval(boundingBox.y(), boundingBox.maxY(), seg));
+ }
+ }
+
+ // Now iterate through the contours and pick a random segment (in
+ // this case we use the first) and a random point on that segment.
+ // Find all segments from other contours which intersect this one
+ // and count the number of crossings a horizontal line to
+ // x=+infinity makes with those contours. This combined with the
+ // orientation of the curve tells us which side to fill -- again,
+ // assuming an even/odd fill rule, which is all we can easily
+ // handle.
+ for (Vector<Contour*>::iterator iter = m_contours.begin(); iter != m_contours.end(); ++iter) {
+ Contour* cur = *iter;
+
+ bool ambiguous = true;
+ int numCrossings = 0;
+
+ // For each contour, attempt to find a point on the contour which,
+ // when we cast an XRay, does not intersect the other contours at
+ // an ambiguous point (the junction between two curves or at a
+ // tangent point). Ambiguous points make the determination of
+ // whether this contour is contained within another fragile. Note
+ // that this loop is only an approximation to the selection of a
+ // good casting point. We could as well evaluate a segment to
+ // determine a point upon it.
+ for (Segment* seg = cur->begin();
+ ambiguous && seg != cur->end();
+ seg = seg->next()) {
+ numCrossings = 0;
+ // We use a zero-sized vertical interval for the query.
+ Vector<IntervalType> overlaps = tree.allOverlaps(tree.createInterval(seg->getPoint(0).y(),
+ seg->getPoint(0).y(),
+ 0));
+#if defined(GPU_PATH_PROCESSOR_DEBUG_ORIENTATION) && !defined(NDEBUG)
+ Vector<Segment*> slowOverlaps = allSegmentsOverlappingY(cur, seg->getPoint(0).x(), seg->getPoint(0).y());
+ if (overlaps.size() != slowOverlaps.size()) {
+ LOG_ERROR("For query point (%f, %f) on contour 0x%p:", seg->getPoint(0).x(), seg->getPoint(0).y(), cur);
+ LOG_ERROR(" overlaps:");
+ for (size_t i = 0; i < overlaps.size(); i++)
+ LOG_ERROR(" %d: %s", i+1, overlaps[i].data()->toString().ascii().data());
+ LOG_ERROR(" slowOverlaps:");
+ for (size_t i = 0; i < slowOverlaps.size(); i++)
+ LOG_ERROR(" %d: %s", (i+1) slowOverlaps[i]->toString());
+ LOG_ERROR("Interval tree:");
+ tree.dump();
+ }
+ ASSERT(overlaps.size() == slowOverlaps.size());
+#endif // defined(GPU_PATH_PROCESSOR_DEBUG_ORIENTATION) && !defined(NDEBUG)
+ for (Vector<IntervalType>::iterator iter = overlaps.begin(); iter != overlaps.end(); ++iter) {
+ const IntervalType& interval = *iter;
+ Segment* querySegment = interval.data();
+ // Ignore segments coming from the same contour.
+ if (querySegment->contour() != cur) {
+ // Only perform queries that can affect the computation.
+ const FloatRect& boundingBox = querySegment->contour()->boundingBox();
+ if (seg->getPoint(0).x() >= boundingBox.x()
+ && seg->getPoint(0).x() <= boundingBox.maxX()) {
+ numCrossings += querySegment->numCrossingsForXRay(seg->getPoint(0),
+ ambiguous);
+ if (ambiguous) {
+#ifndef NDEBUG
+ if (m_verboseLogging) {
+ LOG_ERROR("Ambiguous intersection query at point (%f, %f)", seg->getPoint(0).x(), seg->getPoint(0).y());
+ LOG_ERROR("Query segment: %s", querySegment->toString().ascii().data());
+ }
+#endif
+ break; // Abort iteration over overlaps.
+ }
+ }
+ }
+ }
+ } // for (Segment* seg = cur->begin(); ...
+
+ cur->setFillSide((cur->isOrientedCounterClockwise() ^ (numCrossings & 1)) ? LoopBlinnConstants::LeftSide : LoopBlinnConstants::RightSide);
+ }
+}
+
+void LoopBlinnPathProcessor::determineOrientation(Contour* contour)
+{
+ // Determine signed area of the polygon represented by the points
+ // along the segments. Consider this an approximation to the true
+ // orientation of the polygon; it probably won't handle
+ // self-intersecting curves correctly.
+ //
+ // There is also a pretty basic assumption here that the contour is
+ // closed.
+ float signedArea = 0;
+ for (Segment* seg = contour->begin();
+ seg != contour->end();
+ seg = seg->next()) {
+ int limit = (seg->kind() == Segment::Cubic) ? 4 : 2;
+ for (int i = 1; i < limit; i++) {
+ const FloatPoint& prevPoint = seg->getPoint(i - 1);
+ const FloatPoint& point = seg->getPoint(i);
+ float curArea = prevPoint.x() * point.y() - prevPoint.y() * point.x();
+#ifndef NDEBUG
+ if (m_verboseLogging)
+ LOG_ERROR("Adding to signed area (%f, %f) -> (%f, %f) = %f", prevPoint.x(), prevPoint.y(), point.x(), point.y(), curArea);
+#endif
+ signedArea += curArea;
+ }
+ }
+
+ if (signedArea > 0)
+ contour->setIsOrientedCounterClockwise(true);
+ else
+ contour->setIsOrientedCounterClockwise(false);
+}
+
+namespace {
+
+//----------------------------------------------------------------------
+// Classes and typedefs needed for curve subdivision. These can't be scoped
+// within the subdivideCurves() method itself, because templates then fail
+// to instantiate.
+
+// The user data which is placed in the PODIntervalTree.
+struct SweepData {
+ SweepData()
+ : triangle(0)
+ , segment(0)
+ {
+ }
+
+ // The triangle this interval is associated with
+ LoopBlinnLocalTriangulator::Triangle* triangle;
+ // The segment the triangle is associated with
+ Segment* segment;
+};
+
+typedef PODIntervalTree<float, SweepData*> SweepTree;
+typedef SweepTree::IntervalType SweepInterval;
+
+// The entry / exit events which occur at the minimum and maximum x
+// coordinates of the control point triangles' bounding boxes.
+//
+// Note that this class requires its copy constructor and assignment
+// operator since it needs to be stored in a Vector.
+class SweepEvent {
+public:
+ SweepEvent()
+ : m_x(0)
+ , m_entry(false)
+ , m_interval(0, 0, 0)
+ {
+ }
+
+ // Initializes the SweepEvent.
+ void setup(float x, bool entry, SweepInterval interval)
+ {
+ m_x = x;
+ m_entry = entry;
+ m_interval = interval;
+ }
+
+ float x() const { return m_x; }
+ bool entry() const { return m_entry; }
+ const SweepInterval& interval() const { return m_interval; }
+
+ bool operator<(const SweepEvent& other) const
+ {
+ return m_x < other.m_x;
+ }
+
+private:
+ float m_x;
+ bool m_entry;
+ SweepInterval m_interval;
+};
+
+bool trianglesOverlap(LoopBlinnLocalTriangulator::Triangle* t0,
+ LoopBlinnLocalTriangulator::Triangle* t1)
+{
+ return trianglesOverlap(t0->getVertex(0)->xyCoordinates(),
+ t0->getVertex(1)->xyCoordinates(),
+ t0->getVertex(2)->xyCoordinates(),
+ t1->getVertex(0)->xyCoordinates(),
+ t1->getVertex(1)->xyCoordinates(),
+ t1->getVertex(2)->xyCoordinates());
+}
+
+} // anonymous namespace
+
+void LoopBlinnPathProcessor::subdivideCurves()
+{
+ // We need to determine all overlaps of all control point triangles
+ // (from different segments, not the same segment) and, if any
+ // exist, subdivide the associated curves.
+ //
+ // The plane-sweep algorithm determines all overlaps of a set of
+ // rectangles in the 2D plane. Our problem maps very well to this
+ // algorithm and significantly reduces the complexity compared to a
+ // naive implementation.
+ //
+ // Each bounding box of a control point triangle is converted into
+ // an "entry" event at its smallest X coordinate and an "exit" event
+ // at its largest X coordinate. Each event has an associated
+ // one-dimensional interval representing the Y span of the bounding
+ // box. We sort these events by increasing X coordinate. We then
+ // iterate through them. For each entry event we add the interval to
+ // a side interval tree, and query this tree for overlapping
+ // intervals. Any overlapping interval corresponds to an overlapping
+ // bounding box. For each exit event we remove the associated
+ // interval from the interval tree.
+
+ Vector<Segment*> curSegments;
+ Vector<Segment*> nextSegments;
+
+ // Start things off by considering all of the segments
+ for (Vector<Contour*>::iterator iter = m_contours.begin(); iter != m_contours.end(); ++iter) {
+ Contour* cur = *iter;
+ for (Segment* seg = cur->begin(); seg != cur->end(); seg = seg->next()) {
+ if (seg->kind() == Segment::Cubic) {
+ seg->triangulate(LoopBlinnLocalTriangulator::DontComputeInsideEdges, 0);
+ curSegments.append(seg);
+ }
+ }
+ }
+
+ // Subdivide curves at most this many times
+ const int MaxIterations = 5;
+ Vector<SweepInterval> overlaps;
+
+ for (int currentIteration = 0; currentIteration < MaxIterations; ++currentIteration) {
+ if (!curSegments.size())
+ // Done
+ break;
+
+ Vector<SweepEvent> events;
+ SweepTree tree(m_arena);
+ for (Vector<Segment*>::iterator iter = curSegments.begin(); iter != curSegments.end(); ++iter) {
+ Segment* seg = *iter;
+ ASSERT(seg->kind() == Segment::Cubic);
+ for (int i = 0; i < seg->numberOfTriangles(); i++) {
+ LoopBlinnLocalTriangulator::Triangle* triangle = seg->getTriangle(i);
+ FloatRect boundingBox;
+ boundingBox.fitToPoints(triangle->getVertex(0)->xyCoordinates(),
+ triangle->getVertex(1)->xyCoordinates(),
+ triangle->getVertex(2)->xyCoordinates());
+ // Ignore zero-width triangles to avoid issues with
+ // coincident entry and exit events for the same triangle
+ if (boundingBox.maxX() > boundingBox.x()) {
+ SweepData* data = m_arena->allocateObject<SweepData>();
+ data->triangle = triangle;
+ data->segment = seg;
+ SweepInterval interval = tree.createInterval(boundingBox.y(), boundingBox.maxY(), data);
+ // Add entry and exit events
+ SweepEvent event;
+ event.setup(boundingBox.x(), true, interval);
+ events.append(event);
+ event.setup(boundingBox.maxX(), false, interval);
+ events.append(event);
+ }
+ }
+ }
+
+ // Sort events by increasing X coordinate
+ std::sort(events.begin(), events.end());
+#ifndef NDEBUG
+ for (size_t ii = 1; ii < events.size(); ++ii)
+ ASSERT(events[ii - 1].x() <= events[ii].x());
+#endif
+
+ // Now iterate through the events
+ for (Vector<SweepEvent>::iterator iter = events.begin(); iter != events.end(); ++iter) {
+ SweepEvent event = *iter;
+ if (event.entry()) {
+ // See whether the associated segment has been subdivided yet
+ if (!event.interval().data()->segment->markedForSubdivision()) {
+ // Query the tree
+ overlaps.clear();
+ tree.allOverlaps(event.interval(), overlaps);
+ // Now see exactly which triangles overlap this one
+ for (Vector<SweepInterval>::iterator iter = overlaps.begin(); iter != overlaps.end(); ++iter) {
+ SweepInterval overlap = *iter;
+ // Only pay attention to overlaps from a different Segment
+ if (event.interval().data()->segment != overlap.data()->segment) {
+ // See whether the triangles actually overlap
+ if (trianglesOverlap(event.interval().data()->triangle,
+ overlap.data()->triangle)) {
+ // Actually subdivide the segments.
+ // Each one might already have been subdivided.
+ Segment* seg = event.interval().data()->segment;
+ conditionallySubdivide(seg, nextSegments);
+ seg = overlap.data()->segment;
+ conditionallySubdivide(seg, nextSegments);
+ }
+ }
+ }
+ }
+ // Add this interval into the tree
+ tree.add(event.interval());
+ } else {
+ // Remove this interval from the tree
+ tree.remove(event.interval());
+ }
+ }
+
+ curSegments.swap(nextSegments);
+ nextSegments.clear();
+ }
+}
+
+void LoopBlinnPathProcessor::conditionallySubdivide(Segment* seg, Vector<Segment*>& nextSegments)
+{
+ if (!seg->markedForSubdivision()) {
+ seg->setMarkedForSubdivision(true);
+ Segment* next = seg->contour()->subdivide(seg);
+ // Triangulate the newly subdivided segments.
+ next->triangulate(LoopBlinnLocalTriangulator::DontComputeInsideEdges, 0);
+ next->next()->triangulate(LoopBlinnLocalTriangulator::DontComputeInsideEdges, 0);
+ // Add them for the next iteration.
+ nextSegments.append(next);
+ nextSegments.append(next->next());
+ }
+}
+
+#ifndef NDEBUG
+void LoopBlinnPathProcessor::subdivideCurvesSlow()
+{
+ // Alternate, significantly slower algorithm for curve subdivision
+ // for use in debugging.
+ Vector<Segment*> curSegments;
+ Vector<Segment*> nextSegments;
+
+ // Start things off by considering all of the segments
+ for (Vector<Contour*>::iterator iter = m_contours.begin(); iter != m_contours.end(); ++iter) {
+ Contour* cur = *iter;
+ for (Segment* seg = cur->begin(); seg != cur->end(); seg = seg->next()) {
+ if (seg->kind() == Segment::Cubic) {
+ seg->triangulate(LoopBlinnLocalTriangulator::DontComputeInsideEdges, 0);
+ curSegments.append(seg);
+ }
+ }
+ }
+
+ // Subdivide curves at most this many times
+ const int MaxIterations = 5;
+
+ for (int currentIteration = 0; currentIteration < MaxIterations; ++currentIteration) {
+ if (!curSegments.size())
+ // Done
+ break;
+
+ for (Vector<Segment*>::iterator iter = curSegments.begin(); iter != curSegments.end(); ++iter) {
+ Segment* seg = *iter;
+ ASSERT(seg->kind() == Segment::Cubic);
+ for (Vector<Segment*>::iterator iter2 = curSegments.begin();
+ iter2 != curSegments.end();
+ iter2++) {
+ Segment* seg2 = *iter2;
+ ASSERT(seg2->kind() == Segment::Cubic);
+ if (seg != seg2) {
+ for (int i = 0; i < seg->numberOfTriangles(); i++) {
+ LoopBlinnLocalTriangulator::Triangle* triangle = seg->getTriangle(i);
+ for (int j = 0; j < seg2->numberOfTriangles(); j++) {
+ LoopBlinnLocalTriangulator::Triangle* triangle2 = seg2->getTriangle(j);
+ if (trianglesOverlap(triangle, triangle2)) {
+ conditionallySubdivide(seg, nextSegments);
+ conditionallySubdivide(seg2, nextSegments);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ curSegments.swap(nextSegments);
+ nextSegments.clear();
+ }
+}
+#endif
+
+namespace {
+
+//----------------------------------------------------------------------
+// Structures and callbacks for tessellation of the interior region of
+// the contours.
+
+// The user data for the GLU tessellator.
+struct TessellationState {
+ TessellationState(LoopBlinnPathCache& inputCache)
+ : cache(inputCache) { }
+
+ LoopBlinnPathCache& cache;
+ Vector<void*> allocatedPointers;
+};
+
+static void vertexCallback(void* vertexData, void* data)
+{
+ TessellationState* state = static_cast<TessellationState*>(data);
+ GLdouble* location = static_cast<GLdouble*>(vertexData);
+ state->cache.addInteriorVertex(static_cast<float>(location[0]),
+ static_cast<float>(location[1]));
+}
+
+static void combineCallback(GLdouble coords[3], void* vertexData[4],
+ GLfloat weight[4], void** outData,
+ void* polygonData)
+{
+ TessellationState* state = static_cast<TessellationState*>(polygonData);
+ GLdouble* outVertex = static_cast<GLdouble*>(fastMalloc(3 * sizeof(GLdouble)));
+ state->allocatedPointers.append(outVertex);
+ outVertex[0] = coords[0];
+ outVertex[1] = coords[1];
+ outVertex[2] = coords[2];
+ *outData = outVertex;
+}
+
+static void edgeFlagCallback(GLboolean)
+{
+ // No-op just to prevent triangle strips and fans from being passed to us.
+ // See the OpenGL Programming Guide, Chapter 11, "Tessellators and Quadrics".
+}
+
+} // anonymous namespace
+
+void LoopBlinnPathProcessor::tessellateInterior(LoopBlinnPathCache& cache)
+{
+ // Because the GLU tessellator requires its input in
+ // double-precision format, we need to make a separate copy of the
+ // data.
+ Vector<GLdouble> vertexData;
+ Vector<size_t> contourEndings;
+ // For avoiding adding coincident vertices.
+ float curX = 0, curY = 0;
+ for (Vector<Contour*>::iterator iter = m_contours.begin(); iter != m_contours.end(); ++iter) {
+ Contour* cur = *iter;
+ bool first = true;
+ for (Segment* seg = cur->begin(); seg != cur->end(); seg = seg->next()) {
+ int numberOfInteriorVertices = seg->numberOfInteriorVertices();
+ for (int i = 0; i < numberOfInteriorVertices - 1; i++) {
+ FloatPoint point = seg->getInteriorVertex(i);
+ if (first) {
+ first = false;
+ vertexData.append(point.x());
+ vertexData.append(point.y());
+ vertexData.append(0);
+ curX = point.x();
+ curY = point.y();
+ } else if (point.x() != curX || point.y() != curY) {
+ vertexData.append(point.x());
+ vertexData.append(point.y());
+ vertexData.append(0);
+ curX = point.x();
+ curY = point.y();
+ }
+ }
+ }
+ contourEndings.append(vertexData.size());
+ }
+ // Now that we have all of the vertex data in a stable location in
+ // memory, call the tessellator.
+ GLUtesselator* tess = internal_gluNewTess();
+ TessellationState state(cache);
+ internal_gluTessCallback(tess, GLU_TESS_VERTEX_DATA,
+ reinterpret_cast<GLvoid (*)()>(vertexCallback));
+ internal_gluTessCallback(tess, GLU_TESS_COMBINE_DATA,
+ reinterpret_cast<GLvoid (*)()>(combineCallback));
+ internal_gluTessCallback(tess, GLU_TESS_EDGE_FLAG,
+ reinterpret_cast<GLvoid (*)()>(edgeFlagCallback));
+ internal_gluTessBeginPolygon(tess, &state);
+ internal_gluTessBeginContour(tess);
+ GLdouble* base = vertexData.data();
+ int contourIndex = 0;
+ for (size_t i = 0; i < vertexData.size(); i += 3) {
+ if (i == contourEndings[contourIndex]) {
+ internal_gluTessEndContour(tess);
+ internal_gluTessBeginContour(tess);
+ ++contourIndex;
+ }
+ internal_gluTessVertex(tess, &base[i], &base[i]);
+ }
+ internal_gluTessEndContour(tess);
+ internal_gluTessEndPolygon(tess);
+ for (size_t i = 0; i < state.allocatedPointers.size(); i++)
+ fastFree(state.allocatedPointers[i]);
+ internal_gluDeleteTess(tess);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/gpu/LoopBlinnPathProcessor.h b/Source/WebCore/platform/graphics/gpu/LoopBlinnPathProcessor.h
new file mode 100644
index 0000000..ad89bc1
--- /dev/null
+++ b/Source/WebCore/platform/graphics/gpu/LoopBlinnPathProcessor.h
@@ -0,0 +1,126 @@
+/*
+ * 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:
+ *
+ * 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 AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// The main entry point for Loop and Blinn's GPU accelerated curve
+// rendering algorithm.
+
+#ifndef LoopBlinnPathProcessor_h
+#define LoopBlinnPathProcessor_h
+
+#include <wtf/Noncopyable.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+// We use a namespace for classes which are simply implementation
+// details of the algorithm but which we need to reference from the
+// class definition.
+namespace LoopBlinnPathProcessorImplementation {
+
+class Contour;
+class Segment;
+
+} // namespace LoopBlinnPathProcessorImplementation
+
+class Path;
+class LoopBlinnPathCache;
+class PODArena;
+
+// The LoopBlinnPathProcessor turns a Path (assumed to contain one or
+// more closed regions) into a set of exterior and interior triangles,
+// stored in the LoopBlinnPathCache. The exterior triangles have
+// associated 3D texture coordinates which are used to evaluate the
+// curve's inside/outside function on a per-pixel basis. The interior
+// triangles are filled with 100% opacity.
+//
+// Note that the fill style and management of multiple layers are
+// separate concerns, handled at a higher level with shaders and
+// polygon offsets.
+class LoopBlinnPathProcessor {
+public:
+ LoopBlinnPathProcessor();
+ explicit LoopBlinnPathProcessor(PassRefPtr<PODArena>);
+ ~LoopBlinnPathProcessor();
+
+ // Transforms the given path into a triangle mesh for rendering
+ // using Loop and Blinn's shader, placing the result into the given
+ // LoopBlinnPathCache.
+ void process(const Path&, LoopBlinnPathCache&);
+
+#ifndef NDEBUG
+ // Enables or disables verbose logging in debug mode.
+ void setVerboseLogging(bool onOrOff);
+#endif
+
+private:
+ // Builds a list of contours for the given path.
+ void buildContours(const Path&);
+
+ // Determines whether the left or right side of each contour should
+ // be filled.
+ void determineSidesToFill();
+
+ // Determines whether the given (closed) contour is oriented
+ // clockwise or counterclockwise.
+ void determineOrientation(LoopBlinnPathProcessorImplementation::Contour*);
+
+ // Subdivides the curves so that there are no overlaps of the
+ // triangles associated with the curves' control points.
+ void subdivideCurves();
+
+ // Helper function used during curve subdivision.
+ void conditionallySubdivide(LoopBlinnPathProcessorImplementation::Segment*,
+ Vector<LoopBlinnPathProcessorImplementation::Segment*>& nextSegments);
+
+ // Tessellates the interior regions of the contours.
+ void tessellateInterior(LoopBlinnPathCache&);
+
+#ifndef NDEBUG
+ // For debugging the orientation computation. Returns all of the
+ // segments overlapping the given Y coordinate.
+ Vector<LoopBlinnPathProcessorImplementation::Segment*> allSegmentsOverlappingY(LoopBlinnPathProcessorImplementation::Contour*, float x, float y);
+
+ // For debugging the curve subdivision algorithm. Subdivides the
+ // curves using an alternate, slow (O(n^3)) algorithm.
+ void subdivideCurvesSlow();
+#endif
+
+ // PODArena from which to allocate temporary objects.
+ RefPtr<PODArena> m_arena;
+
+ // The contours described by the path.
+ Vector<LoopBlinnPathProcessorImplementation::Contour*> m_contours;
+
+#ifndef NDEBUG
+ // Whether or not to perform verbose logging in debug mode.
+ bool m_verboseLogging;
+#endif
+};
+
+} // namespace WebCore
+
+#endif // LoopBlinnPathProcessor_h
diff --git a/Source/WebCore/platform/graphics/gpu/LoopBlinnShader.cpp b/Source/WebCore/platform/graphics/gpu/LoopBlinnShader.cpp
new file mode 100644
index 0000000..364e6c8
--- /dev/null
+++ b/Source/WebCore/platform/graphics/gpu/LoopBlinnShader.cpp
@@ -0,0 +1,59 @@
+/*
+ * 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:
+ *
+ * 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 AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "LoopBlinnShader.h"
+
+#include "GraphicsContext3D.h"
+
+namespace WebCore {
+
+LoopBlinnShader::LoopBlinnShader(GraphicsContext3D* context, unsigned program)
+ : Shader(context, program)
+{
+ m_worldViewProjectionLocation = context->getUniformLocation(program, "worldViewProjection");
+ m_positionLocation = context->getAttribLocation(program, "position");
+ m_klmLocation = context->getAttribLocation(program, "klm");
+}
+
+void LoopBlinnShader::use(unsigned vertexOffset, unsigned klmOffset, const AffineTransform& transform)
+{
+ m_context->useProgram(m_program);
+
+ float matrix[16];
+ affineTo4x4(transform, matrix);
+ m_context->uniformMatrix4fv(m_worldViewProjectionLocation, false /*transpose*/, matrix, 1 /*count*/);
+
+ m_context->vertexAttribPointer(m_positionLocation, 2, GraphicsContext3D::FLOAT, false, 0, vertexOffset);
+ m_context->enableVertexAttribArray(m_positionLocation);
+
+ if (m_klmLocation != -1) {
+ m_context->vertexAttribPointer(m_klmLocation, 3, GraphicsContext3D::FLOAT, false, 0, klmOffset);
+ m_context->enableVertexAttribArray(m_klmLocation);
+ }
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/gpu/LoopBlinnShader.h b/Source/WebCore/platform/graphics/gpu/LoopBlinnShader.h
new file mode 100644
index 0000000..2d24dc3
--- /dev/null
+++ b/Source/WebCore/platform/graphics/gpu/LoopBlinnShader.h
@@ -0,0 +1,58 @@
+/*
+ * 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:
+ *
+ * 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 AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LoopBlinnShader_h
+#define LoopBlinnShader_h
+
+#include "Shader.h"
+
+namespace WebCore {
+
+class GraphicsContext3D;
+
+class LoopBlinnShader : public Shader {
+public:
+ enum Region {
+ Interior,
+ Exterior
+ };
+
+protected:
+ LoopBlinnShader(GraphicsContext3D*, unsigned program);
+
+ // This assumes the vertices and klm coordinates are stored in the
+ // same, currently bound, buffer object, contiguously and at the
+ // specified offsets.
+ void use(unsigned vertexOffset, unsigned klmOffset, const AffineTransform&);
+
+private:
+ int m_worldViewProjectionLocation;
+ int m_positionLocation;
+ int m_klmLocation;
+};
+
+} // namespace WebCore
+
+#endif // LoopBlinnShader_h
diff --git a/Source/WebCore/platform/graphics/gpu/LoopBlinnSolidFillShader.cpp b/Source/WebCore/platform/graphics/gpu/LoopBlinnSolidFillShader.cpp
new file mode 100644
index 0000000..43a97ef
--- /dev/null
+++ b/Source/WebCore/platform/graphics/gpu/LoopBlinnSolidFillShader.cpp
@@ -0,0 +1,62 @@
+/*
+ * 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:
+ *
+ * 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 AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "LoopBlinnSolidFillShader.h"
+
+#include "GraphicsContext3D.h"
+
+namespace WebCore {
+
+PassOwnPtr<LoopBlinnSolidFillShader> LoopBlinnSolidFillShader::create(GraphicsContext3D* context,
+ LoopBlinnShader::Region region,
+ Shader::AntialiasType antialiasType)
+{
+ VertexType type = (region == Interior) ? LoopBlinnInterior : LoopBlinnExterior;
+ unsigned program = loadProgram(context,
+ generateVertex(type, SolidFill),
+ generateFragment(type, SolidFill, antialiasType));
+ if (!program)
+ return 0;
+ return new LoopBlinnSolidFillShader(context, program);
+}
+
+LoopBlinnSolidFillShader::LoopBlinnSolidFillShader(GraphicsContext3D* context, unsigned program)
+ : LoopBlinnShader(context, program)
+{
+ m_colorLocation = context->getUniformLocation(program, "color");
+}
+
+void LoopBlinnSolidFillShader::use(unsigned vertexOffset, unsigned klmOffset, const AffineTransform& transform, const Color& color)
+{
+ LoopBlinnShader::use(vertexOffset, klmOffset, transform);
+
+ float rgba[4];
+ color.getRGBA(rgba[0], rgba[1], rgba[2], rgba[3]);
+ m_context->uniform4f(m_colorLocation, rgba[0] * rgba[3], rgba[1] * rgba[3], rgba[2] * rgba[3], rgba[3]);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/gpu/LoopBlinnSolidFillShader.h b/Source/WebCore/platform/graphics/gpu/LoopBlinnSolidFillShader.h
new file mode 100644
index 0000000..36312a2
--- /dev/null
+++ b/Source/WebCore/platform/graphics/gpu/LoopBlinnSolidFillShader.h
@@ -0,0 +1,52 @@
+/*
+ * 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:
+ *
+ * 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 AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LoopBlinnSolidFillShader_h
+#define LoopBlinnSolidFillShader_h
+
+#include "LoopBlinnShader.h"
+
+namespace WebCore {
+
+class GraphicsContext3D;
+
+class LoopBlinnSolidFillShader : public LoopBlinnShader {
+public:
+ static PassOwnPtr<LoopBlinnSolidFillShader> create(GraphicsContext3D*, Region, AntialiasType);
+
+ // This assumes the vertices and klm coordinates are stored in the
+ // same, currently bound, buffer object, contiguously and at the
+ // specified offsets.
+ void use(unsigned vertexOffset, unsigned klmOffset, const AffineTransform&, const Color&);
+
+private:
+ LoopBlinnSolidFillShader(GraphicsContext3D*, unsigned program);
+
+ int m_colorLocation;
+};
+
+} // namespace WebCore
+
+#endif // LoopBlinnSolidFillShader_h
diff --git a/Source/WebCore/platform/graphics/gpu/Shader.cpp b/Source/WebCore/platform/graphics/gpu/Shader.cpp
index 6978322..1b9bfd5 100644
--- a/Source/WebCore/platform/graphics/gpu/Shader.cpp
+++ b/Source/WebCore/platform/graphics/gpu/Shader.cpp
@@ -38,6 +38,7 @@
#include "GraphicsContext3D.h"
#include <wtf/text/CString.h>
+#include <wtf/text/StringBuilder.h>
namespace WebCore {
@@ -56,14 +57,34 @@ void Shader::affineTo3x3(const AffineTransform& transform, float mat[9])
}
// static
-unsigned Shader::loadShader(GraphicsContext3D* context, unsigned type, const char* shaderSource)
+void Shader::affineTo4x4(const AffineTransform& transform, float mat[16])
+{
+ mat[0] = transform.a();
+ mat[1] = transform.b();
+ mat[2] = 0.0f;
+ mat[3] = 0.0f;
+ mat[4] = transform.c();
+ mat[5] = transform.d();
+ mat[6] = 0.0f;
+ mat[7] = 0.0f;
+ mat[8] = 0.0f;
+ mat[9] = 0.0f;
+ mat[10] = 1.0f;
+ mat[11] = 0.0f;
+ mat[12] = transform.e();
+ mat[13] = transform.f();
+ mat[14] = 0.0f;
+ mat[15] = 1.0f;
+}
+
+// static
+unsigned Shader::loadShader(GraphicsContext3D* context, unsigned type, const String& shaderSource)
{
unsigned shader = context->createShader(type);
if (!shader)
return 0;
- String shaderSourceStr(shaderSource);
- context->shaderSource(shader, shaderSourceStr);
+ context->shaderSource(shader, shaderSource);
context->compileShader(shader);
int compileStatus = 0;
context->getShaderiv(shader, GraphicsContext3D::COMPILE_STATUS, &compileStatus);
@@ -77,7 +98,7 @@ unsigned Shader::loadShader(GraphicsContext3D* context, unsigned type, const cha
}
// static
-unsigned Shader::loadProgram(GraphicsContext3D* context, const char* vertexShaderSource, const char* fragmentShaderSource)
+unsigned Shader::loadProgram(GraphicsContext3D* context, const String& vertexShaderSource, const String& fragmentShaderSource)
{
unsigned vertexShader = loadShader(context, GraphicsContext3D::VERTEX_SHADER, vertexShaderSource);
if (!vertexShader)
@@ -111,6 +132,146 @@ Shader::~Shader()
m_context->deleteProgram(m_program);
}
+// static
+String Shader::generateVertex(Shader::VertexType vertexType, Shader::FillType fillType)
+{
+ StringBuilder builder;
+ switch (vertexType) {
+ case TwoDimensional:
+ builder.append(
+ "uniform mat3 matrix;\n"
+ "attribute vec3 position;\n");
+ break;
+ case LoopBlinnInterior:
+ builder.append(
+ "uniform mat4 worldViewProjection;\n"
+ "attribute vec2 position;\n");
+ break;
+ case LoopBlinnExterior:
+ builder.append(
+ "uniform mat4 worldViewProjection;\n"
+ "attribute vec2 position;\n"
+ "attribute vec3 klm;\n"
+ "varying vec3 v_klm;\n");
+ break;
+ }
+
+ if (fillType == TextureFill) {
+ builder.append(
+ "uniform mat3 texMatrix;\n"
+ "varying vec3 texCoord;\n");
+ }
+
+ builder.append(
+ "void main() {\n");
+
+ if (vertexType == TwoDimensional) {
+ builder.append(
+ "gl_Position = vec4(matrix * position, 1.0);\n");
+ } else {
+ builder.append(
+ "gl_Position = worldViewProjection * vec4(position, 0.0, 1.0);\n");
+ if (vertexType == LoopBlinnExterior) {
+ builder.append(
+ "v_klm = klm;\n");
+ }
+ }
+
+ if (fillType == TextureFill) {
+ builder.append(
+ "texCoord = texMatrix * position;\n");
+ }
+
+ builder.append(
+ "}\n");
+
+ return builder.toString();
}
+// static
+String Shader::generateFragment(Shader::VertexType vertexType, Shader::FillType fillType, Shader::AntialiasType antialiasType)
+{
+ StringBuilder builder;
+ builder.append(
+ "#ifdef GL_ES\n"
+ "precision mediump float;\n"
+ "#endif\n");
+
+ if (vertexType == LoopBlinnExterior) {
+ if (antialiasType == Antialiased) {
+ builder.append(
+ "#extension GL_OES_standard_derivatives : enable\n");
+ }
+ builder.append(
+ "varying vec3 v_klm;\n");
+ }
+
+ switch (fillType) {
+ case SolidFill:
+ builder.append(
+ "uniform vec4 color;\n");
+ break;
+ case TextureFill:
+ builder.append(
+ "uniform sampler2D sampler;\n"
+ "uniform float globalAlpha;\n"
+ "varying vec3 texCoord;\n");
+ break;
+ }
+
+ builder.append(
+ "void main() {\n");
+
+ if (vertexType != LoopBlinnExterior) {
+ builder.append(
+ "float alpha = 1.0;\n");
+ } else {
+ if (antialiasType == Antialiased) {
+ builder.append(
+ " // Gradients\n"
+ " vec3 px = dFdx(v_klm);\n"
+ " vec3 py = dFdy(v_klm);\n"
+ "\n"
+ " // Chain rule\n"
+ " float k2 = v_klm.x * v_klm.x;\n"
+ " float c = k2 * v_klm.x - v_klm.y * v_klm.z;\n"
+ " float k23 = 3.0 * k2;\n"
+ " float cx = k23 * px.x - v_klm.z * px.y - v_klm.y * px.z;\n"
+ " float cy = k23 * py.x - v_klm.z * py.y - v_klm.y * py.z;\n"
+ "\n"
+ " // Signed distance\n"
+ " float sd = c / sqrt(cx * cx + cy * cy);\n"
+ "\n"
+ " // Linear alpha\n"
+ " // FIXME: figure out why this needs to be\n"
+ " // negated compared to the HLSL version, and also why\n"
+ " // we need an adjustment by +1.0 for it to look good.\n"
+ " // float alpha = clamp(0.5 - sd, 0.0, 1.0);\n"
+ " float alpha = clamp(sd + 0.5, 0.0, 1.0);\n");
+ } else {
+ builder.append(
+ " float t = v_klm.x * v_klm.x * v_klm.x - v_klm.y * v_klm.z;\n"
+ " float alpha = clamp(sign(t), 0.0, 1.0);\n");
+ }
+ }
+
+ switch (fillType) {
+ case SolidFill:
+ builder.append(
+ "gl_FragColor = color * alpha;\n");
+ break;
+ case TextureFill:
+ builder.append(
+ "gl_FragColor = texture2D(sampler, texCoord.xy) * alpha * globalAlpha;\n");
+ break;
+ }
+
+ builder.append(
+ "}\n");
+
+ return builder.toString();
+}
+
+} // namespace WebCore
+
#endif
diff --git a/Source/WebCore/platform/graphics/gpu/Shader.h b/Source/WebCore/platform/graphics/gpu/Shader.h
index 4f62ca9..35d1a3b 100644
--- a/Source/WebCore/platform/graphics/gpu/Shader.h
+++ b/Source/WebCore/platform/graphics/gpu/Shader.h
@@ -33,6 +33,7 @@
#include <wtf/Noncopyable.h>
#include <wtf/PassOwnPtr.h>
+#include <wtf/text/WTFString.h>
namespace WebCore {
@@ -42,13 +43,35 @@ class Color;
class Shader {
WTF_MAKE_NONCOPYABLE(Shader);
+public:
+ enum VertexType {
+ TwoDimensional,
+ LoopBlinnInterior,
+ LoopBlinnExterior
+ };
+
+ enum FillType {
+ SolidFill,
+ TextureFill
+ };
+
+ // Currently only applies to the Loop-Blinn vertex type.
+ enum AntialiasType {
+ NotAntialiased,
+ Antialiased
+ };
+
protected:
Shader(GraphicsContext3D*, unsigned program);
~Shader();
+ static String generateVertex(VertexType, FillType);
+ static String generateFragment(VertexType, FillType, AntialiasType);
+
static void affineTo3x3(const AffineTransform&, float mat[9]);
- static unsigned loadShader(GraphicsContext3D*, unsigned type, const char* shaderSource);
- static unsigned loadProgram(GraphicsContext3D*, const char* vertexShaderSource, const char* fragmentShaderSource);
+ static void affineTo4x4(const AffineTransform&, float mat[16]);
+ static unsigned loadShader(GraphicsContext3D*, unsigned type, const String& shaderSource);
+ static unsigned loadProgram(GraphicsContext3D*, const String& vertexShaderSource, const String& fragmentShaderSource);
GraphicsContext3D* m_context;
unsigned m_program;
diff --git a/Source/WebCore/platform/graphics/gpu/SolidFillShader.cpp b/Source/WebCore/platform/graphics/gpu/SolidFillShader.cpp
index 86079be..78381f0 100644
--- a/Source/WebCore/platform/graphics/gpu/SolidFillShader.cpp
+++ b/Source/WebCore/platform/graphics/gpu/SolidFillShader.cpp
@@ -49,23 +49,9 @@ SolidFillShader::SolidFillShader(GraphicsContext3D* context, unsigned program)
PassOwnPtr<SolidFillShader> SolidFillShader::create(GraphicsContext3D* context)
{
- static const char* vertexShaderSource =
- "uniform mat3 matrix;\n"
- "uniform vec4 color;\n"
- "attribute vec3 position;\n"
- "void main() {\n"
- " gl_Position = vec4(matrix * position, 1.0);\n"
- "}\n";
- static const char* fragmentShaderSource =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
- "uniform mat3 matrix;\n"
- "uniform vec4 color;\n"
- "void main() {\n"
- " gl_FragColor = color;\n"
- "}\n";
- unsigned program = loadProgram(context, vertexShaderSource, fragmentShaderSource);
+ unsigned program = loadProgram(context,
+ generateVertex(Shader::TwoDimensional, Shader::SolidFill),
+ generateFragment(Shader::TwoDimensional, Shader::SolidFill, Shader::NotAntialiased));
if (!program)
return 0;
return new SolidFillShader(context, program);
diff --git a/Source/WebCore/platform/graphics/gpu/TexShader.cpp b/Source/WebCore/platform/graphics/gpu/TexShader.cpp
index d7ffa17..9eb5c16 100644
--- a/Source/WebCore/platform/graphics/gpu/TexShader.cpp
+++ b/Source/WebCore/platform/graphics/gpu/TexShader.cpp
@@ -43,33 +43,16 @@ TexShader::TexShader(GraphicsContext3D* context, unsigned program)
{
m_matrixLocation = context->getUniformLocation(program, "matrix");
m_texMatrixLocation = context->getUniformLocation(program, "texMatrix");
- m_alphaLocation = context->getUniformLocation(program, "alpha");
+ m_alphaLocation = context->getUniformLocation(program, "globalAlpha");
m_positionLocation = context->getAttribLocation(program, "position");
m_samplerLocation = context->getUniformLocation(program, "sampler");
}
PassOwnPtr<TexShader> TexShader::create(GraphicsContext3D* context)
{
- static const char* vertexShaderSource =
- "uniform mat3 matrix;\n"
- "uniform mat3 texMatrix;\n"
- "attribute vec3 position;\n"
- "varying vec3 texCoord;\n"
- "void main() {\n"
- " texCoord = texMatrix * position;\n"
- " gl_Position = vec4(matrix * position, 1.0);\n"
- "}\n";
- static const char* fragmentShaderSource =
- "#ifdef GL_ES\n"
- "precision mediump float;\n"
- "#endif\n"
- "uniform sampler2D sampler;\n"
- "uniform float alpha;\n"
- "varying vec3 texCoord;\n"
- "void main() {\n"
- " gl_FragColor = texture2D(sampler, texCoord.xy)* vec4(alpha);\n"
- "}\n";
- unsigned program = loadProgram(context, vertexShaderSource, fragmentShaderSource);
+ unsigned program = loadProgram(context,
+ generateVertex(Shader::TwoDimensional, Shader::TextureFill),
+ generateFragment(Shader::TwoDimensional, Shader::TextureFill, Shader::NotAntialiased));
if (!program)
return 0;
return new TexShader(context, program);
diff --git a/Source/WebCore/platform/graphics/gpu/Texture.cpp b/Source/WebCore/platform/graphics/gpu/Texture.cpp
index e1f8114..b1ba827 100644
--- a/Source/WebCore/platform/graphics/gpu/Texture.cpp
+++ b/Source/WebCore/platform/graphics/gpu/Texture.cpp
@@ -166,7 +166,7 @@ void Texture::updateSubRect(void* pixels, const IntRect& updateRect)
int tempBuffSize = // Temporary buffer size is the smaller of the max texture size or the updateRectSanitized
min(m_tiles.maxTextureSize(), m_tiles.borderTexels() + updateRectSanitized.width()) *
min(m_tiles.maxTextureSize(), m_tiles.borderTexels() + updateRectSanitized.height());
- OwnArrayPtr<uint32_t> tempBuff(new uint32_t[tempBuffSize]);
+ OwnArrayPtr<uint32_t> tempBuff = adoptArrayPtr(new uint32_t[tempBuffSize]);
for (int tile = 0; tile < m_tiles.numTiles(); tile++) {
// Intersect with tile
diff --git a/Source/WebCore/platform/graphics/gpu/TilingData.cpp b/Source/WebCore/platform/graphics/gpu/TilingData.cpp
index a98add7..e7c4e4c 100644
--- a/Source/WebCore/platform/graphics/gpu/TilingData.cpp
+++ b/Source/WebCore/platform/graphics/gpu/TilingData.cpp
@@ -89,9 +89,9 @@ IntRect TilingData::tileBoundsWithBorder(int tile) const
if (m_borderTexels) {
int x1 = bounds.x();
- int x2 = bounds.right();
+ int x2 = bounds.maxX();
int y1 = bounds.y();
- int y2 = bounds.bottom();
+ int y2 = bounds.maxY();
if (tileXIndex(tile) > 0)
x1--;
@@ -182,8 +182,8 @@ IntRect TilingData::overlappedTileIndices(const WebCore::IntRect &srcRect) const
{
int x = tileXIndexFromSrcCoord(srcRect.x());
int y = tileYIndexFromSrcCoord(srcRect.y());
- int r = tileXIndexFromSrcCoord(srcRect.right());
- int b = tileYIndexFromSrcCoord(srcRect.bottom());
+ int r = tileXIndexFromSrcCoord(srcRect.maxX());
+ int b = tileYIndexFromSrcCoord(srcRect.maxY());
return IntRect(x, y, r - x, b - y);
}
diff --git a/Source/WebCore/platform/graphics/gpu/mac/DrawingBufferMac.mm b/Source/WebCore/platform/graphics/gpu/mac/DrawingBufferMac.mm
index e6dfdb8..13c0968 100644
--- a/Source/WebCore/platform/graphics/gpu/mac/DrawingBufferMac.mm
+++ b/Source/WebCore/platform/graphics/gpu/mac/DrawingBufferMac.mm
@@ -25,7 +25,7 @@
#include "config.h"
-#if ENABLE(ACCELERATED_2D_CANVAS) || ENABLE(3D_CANVAS)
+#if ENABLE(ACCELERATED_2D_CANVAS) || ENABLE(WEBGL)
#include "DrawingBuffer.h"
diff --git a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
index c113c69..69bdeab 100644
--- a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
+++ b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
@@ -1384,11 +1384,15 @@ static HashSet<String> mimeTypeCache()
// These formats are supported by GStreamer, but not
// correctly advertised.
- if (g_str_equal(name, "video/x-h264")
- || g_str_equal(name, "audio/x-m4a")) {
+ if (g_str_equal(name, "video/x-h264")) {
cache.add(String("video/mp4"));
+ cached = true;
+ }
+
+ if (g_str_equal(name, "audio/x-m4a")) {
cache.add(String("audio/aac"));
cache.add(String("audio/mp4"));
+ cache.add(String("audio/x-m4a"));
cached = true;
}
@@ -1466,6 +1470,15 @@ static HashSet<String> mimeTypeCache()
for (int index = 0; extensions[index]; index++) {
if (g_str_equal(extensions[index], "m4v"))
cache.add(String("video/x-m4v"));
+
+ // Workaround for
+ // https://bugzilla.gnome.org/show_bug.cgi?id=640709.
+ // typefindfunctions <= 0.10.32 doesn't
+ // register the H264 typefinder correctly so
+ // as a workaround we check the registered
+ // file extensions for it.
+ if (g_str_equal(extensions[index], "h264"))
+ cache.add(String("video/mp4"));
}
}
}
diff --git a/Source/WebCore/platform/graphics/gtk/FontGtk.cpp b/Source/WebCore/platform/graphics/gtk/FontGtk.cpp
index 4d6f509..216fb56 100644
--- a/Source/WebCore/platform/graphics/gtk/FontGtk.cpp
+++ b/Source/WebCore/platform/graphics/gtk/FontGtk.cpp
@@ -215,6 +215,11 @@ bool Font::canReturnFallbackFontsForComplexText()
return false;
}
+bool Font::canExpandAroundIdeographsInComplexText()
+{
+ return false;
+}
+
static void drawGlyphsShadow(GraphicsContext* graphicsContext, cairo_t* context, const FloatPoint& point, PangoLayoutLine* layoutLine, PangoRegionType renderRegion)
{
ContextShadow* shadow = graphicsContext->contextShadow();
diff --git a/Source/WebCore/platform/graphics/haiku/FontCustomPlatformData.cpp b/Source/WebCore/platform/graphics/haiku/FontCustomPlatformData.cpp
index ce7ec46..017b1e4 100644
--- a/Source/WebCore/platform/graphics/haiku/FontCustomPlatformData.cpp
+++ b/Source/WebCore/platform/graphics/haiku/FontCustomPlatformData.cpp
@@ -31,7 +31,7 @@ FontCustomPlatformData::~FontCustomPlatformData()
{
}
-FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, FontRenderingMode)
+FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, FontWidthVariant, FontRenderingMode)
{
return FontPlatformData(size, bold, italic);
}
diff --git a/Source/WebCore/platform/graphics/haiku/FontCustomPlatformData.h b/Source/WebCore/platform/graphics/haiku/FontCustomPlatformData.h
index 86f99b2..7ffe89a 100644
--- a/Source/WebCore/platform/graphics/haiku/FontCustomPlatformData.h
+++ b/Source/WebCore/platform/graphics/haiku/FontCustomPlatformData.h
@@ -23,6 +23,7 @@
#include "FontOrientation.h"
#include "FontRenderingMode.h"
+#include "FontWidthVariant.h"
#include <wtf/Forward.h>
namespace WebCore {
@@ -38,7 +39,7 @@ namespace WebCore {
static bool supportsFormat(const String&);
- FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, FontRenderingMode = NormalRenderingMode);
+ FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, FontWidthVariant = RegularWidth, FontRenderingMode = NormalRenderingMode);
};
FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer*);
diff --git a/Source/WebCore/platform/graphics/haiku/FontHaiku.cpp b/Source/WebCore/platform/graphics/haiku/FontHaiku.cpp
index 819fecb..5a1a1d0 100644
--- a/Source/WebCore/platform/graphics/haiku/FontHaiku.cpp
+++ b/Source/WebCore/platform/graphics/haiku/FontHaiku.cpp
@@ -65,6 +65,11 @@ bool Font::canReturnFallbackFontsForComplexText()
return false;
}
+bool Font::canExpandAroundIdeographsInComplexText()
+{
+ return false;
+}
+
void Font::drawGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* font,
const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point) const
{
diff --git a/Source/WebCore/platform/graphics/haiku/SimpleFontDataHaiku.cpp b/Source/WebCore/platform/graphics/haiku/SimpleFontDataHaiku.cpp
index b1e7082..4ded761 100644
--- a/Source/WebCore/platform/graphics/haiku/SimpleFontDataHaiku.cpp
+++ b/Source/WebCore/platform/graphics/haiku/SimpleFontDataHaiku.cpp
@@ -48,11 +48,11 @@ void SimpleFontData::platformInit()
font_height height;
font->GetHeight(&height);
- m_ascent = static_cast<int>(height.ascent);
- m_descent = static_cast<int>(height.descent);
- m_lineSpacing = m_ascent + m_descent;
- m_xHeight = height.ascent * 0.56f; // Hack taken from the win port.
- m_lineGap = height.leading;
+ m_fontMetrics.setAscent(height.ascent);
+ m_fontMetrics.setDescent(height.descent);
+ m_fontMetrics.setXHeight(height.ascent * 0.56f); // Hack taken from the win port.
+ m_fontMetrics.setLineGap(height.leading);
+ m_fontMetrics.setLineSpacing(lroundf(height.ascent) + lroundf(height.descent) + lroundf(height.leading));
}
void SimpleFontData::platformCharWidthInit()
diff --git a/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp b/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp
index 86f6bec..1fe3d28 100644
--- a/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp
+++ b/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -25,14 +25,13 @@
#include "config.h"
#include "ComplexTextController.h"
-#include <ApplicationServices/ApplicationServices.h>
-#include "CharacterNames.h"
#include "FloatSize.h"
#include "Font.h"
#include "TextBreakIterator.h"
#include "TextRun.h"
-
+#include <ApplicationServices/ApplicationServices.h>
#include <wtf/StdLibExtras.h>
+#include <wtf/unicode/CharacterNames.h>
#if defined(BUILDING_ON_LEOPARD)
// Undefined when compiling agains the 10.5 SDK.
@@ -71,7 +70,8 @@ ComplexTextController::ComplexTextController(const Font* font, const TextRun& ru
, m_glyphInCurrentRun(0)
, m_characterInCurrentGlyph(0)
, m_finalRoundingWidth(0)
- , m_padding(run.padding())
+ , m_expansion(run.expansion())
+ , m_afterExpansion(true)
, m_fallbackFonts(fallbackFonts)
, m_minGlyphBoundingBoxX(numeric_limits<float>::max())
, m_maxGlyphBoundingBoxX(numeric_limits<float>::min())
@@ -79,19 +79,18 @@ ComplexTextController::ComplexTextController(const Font* font, const TextRun& ru
, m_maxGlyphBoundingBoxY(numeric_limits<float>::min())
, m_lastRoundingGlyph(0)
{
- if (!m_padding)
- m_padPerSpace = 0;
+ if (!m_expansion)
+ m_expansionPerOpportunity = 0;
else {
- int numSpaces = 0;
- for (int s = 0; s < m_run.length(); s++) {
- if (Font::treatAsSpace(m_run[s]))
- numSpaces++;
- }
+ bool isAfterExpansion = true;
+ unsigned expansionOpportunityCount = Font::expansionOpportunityCount(m_run.characters(), m_end, m_run.ltr() ? LTR : RTL, isAfterExpansion);
+ if (isAfterExpansion && !m_run.allowsTrailingExpansion())
+ expansionOpportunityCount--;
- if (!numSpaces)
- m_padPerSpace = 0;
+ if (!expansionOpportunityCount)
+ m_expansionPerOpportunity = 0;
else
- m_padPerSpace = m_padding / numSpaces;
+ m_expansionPerOpportunity = m_expansion / expansionOpportunityCount;
}
collectComplexTextRuns();
@@ -118,9 +117,9 @@ int ComplexTextController::offsetForPosition(float h, bool includePartialGlyphs)
CFIndex hitGlyphStart = complexTextRun.indexAt(j);
CFIndex hitGlyphEnd;
if (m_run.ltr())
- hitGlyphEnd = max<CFIndex>(hitGlyphStart, j + 1 < complexTextRun.glyphCount() ? complexTextRun.indexAt(j + 1) : static_cast<CFIndex>(complexTextRun.stringLength()));
+ hitGlyphEnd = max<CFIndex>(hitGlyphStart, j + 1 < complexTextRun.glyphCount() ? complexTextRun.indexAt(j + 1) : static_cast<CFIndex>(complexTextRun.indexEnd()));
else
- hitGlyphEnd = max<CFIndex>(hitGlyphStart, j > 0 ? complexTextRun.indexAt(j - 1) : static_cast<CFIndex>(complexTextRun.stringLength()));
+ hitGlyphEnd = max<CFIndex>(hitGlyphStart, j > 0 ? complexTextRun.indexAt(j - 1) : static_cast<CFIndex>(complexTextRun.indexEnd()));
// FIXME: Instead of dividing the glyph's advance equally between the characters, this
// could use the glyph's "ligature carets". However, there is no Core Text API to get the
@@ -311,6 +310,7 @@ ComplexTextController::ComplexTextRun::ComplexTextRun(const SimpleFontData* font
, m_characters(characters)
, m_stringLocation(stringLocation)
, m_stringLength(stringLength)
+ , m_indexEnd(stringLength)
, m_isMonotonic(true)
{
#if USE(CORE_TEXT) && USE(ATSUI)
@@ -335,7 +335,7 @@ void ComplexTextController::ComplexTextRun::setIsNonMonotonic()
m_glyphEndOffsets.grow(m_glyphCount);
for (size_t i = 0; i < m_glyphCount; ++i) {
- CFIndex nextMappedIndex = m_stringLength;
+ CFIndex nextMappedIndex = m_indexEnd;
for (size_t j = indexAt(i) + 1; j < m_stringLength; ++j) {
if (mappedIndices[j]) {
nextMappedIndex = j;
@@ -370,9 +370,9 @@ void ComplexTextController::advance(unsigned offset, GlyphBuffer* glyphBuffer)
unsigned glyphEndOffset;
if (complexTextRun.isMonotonic()) {
if (ltr)
- glyphEndOffset = max<unsigned>(glyphStartOffset, g + 1 < glyphCount ? static_cast<unsigned>(complexTextRun.indexAt(g + 1)) : complexTextRun.stringLength());
+ glyphEndOffset = max<unsigned>(glyphStartOffset, static_cast<unsigned>(g + 1 < glyphCount ? complexTextRun.indexAt(g + 1) : complexTextRun.indexEnd()));
else
- glyphEndOffset = max<unsigned>(glyphStartOffset, g > 0 ? static_cast<unsigned>(complexTextRun.indexAt(g - 1)) : complexTextRun.stringLength());
+ glyphEndOffset = max<unsigned>(glyphStartOffset, static_cast<unsigned>(g > 0 ? complexTextRun.indexAt(g - 1) : complexTextRun.indexEnd()));
} else
glyphEndOffset = complexTextRun.endOffsetAt(g);
@@ -386,7 +386,7 @@ void ComplexTextController::advance(unsigned offset, GlyphBuffer* glyphBuffer)
unsigned oldCharacterInCurrentGlyph = m_characterInCurrentGlyph;
m_characterInCurrentGlyph = min(m_currentCharacter - complexTextRun.stringLocation(), glyphEndOffset) - glyphStartOffset;
- // FIXME: Instead of dividing the glyph's advance equially between the characters, this
+ // FIXME: Instead of dividing the glyph's advance equally between the characters, this
// could use the glyph's "ligature carets". However, there is no Core Text API to get the
// ligature carets.
if (glyphStartOffset == glyphEndOffset) {
@@ -421,6 +421,7 @@ void ComplexTextController::adjustGlyphsAndAdvances()
{
CGFloat widthSinceLastRounding = 0;
size_t runCount = m_complexTextRuns.size();
+ bool hasExtraSpacing = (m_font.letterSpacing() || m_font.wordSpacing() || m_expansion) && !m_run.spacingDisabled();
for (size_t r = 0; r < runCount; ++r) {
ComplexTextRun& complexTextRun = *m_complexTextRuns[r];
unsigned glyphCount = complexTextRun.glyphCount();
@@ -433,7 +434,6 @@ void ComplexTextController::adjustGlyphsAndAdvances()
const UChar* cp = complexTextRun.characters();
CGFloat roundedSpaceWidth = roundCGFloat(fontData->spaceWidth());
bool roundsAdvances = !m_font.isPrinterFont() && fontData->platformData().roundsGlyphAdvances();
- bool hasExtraSpacing = (m_font.letterSpacing() || m_font.wordSpacing() || m_padding) && !m_run.spacingDisabled();
CGPoint glyphOrigin = CGPointZero;
CFIndex lastCharacterIndex = m_run.ltr() ? numeric_limits<CFIndex>::min() : numeric_limits<CFIndex>::max();
bool isMonotonic = true;
@@ -489,25 +489,29 @@ void ComplexTextController::adjustGlyphsAndAdvances()
advance.width += m_font.letterSpacing();
// Handle justification and word-spacing.
- if (treatAsSpace) {
- // Account for padding. WebCore uses space padding to justify text.
- // We distribute the specified padding over the available spaces in the run.
- if (m_padding) {
- // Use leftover padding if not evenly divisible by number of spaces.
- if (m_padding < m_padPerSpace) {
- advance.width += m_padding;
- m_padding = 0;
- } else {
- float previousPadding = m_padding;
- m_padding -= m_padPerSpace;
- advance.width += roundf(previousPadding) - roundf(m_padding);
+ if (treatAsSpace || Font::isCJKIdeographOrSymbol(ch)) {
+ // Distribute the run's total expansion evenly over all expansion opportunities in the run.
+ if (m_expansion && (!lastGlyph || m_run.allowsTrailingExpansion())) {
+ float previousExpansion = m_expansion;
+ if (!treatAsSpace && !m_afterExpansion) {
+ // Take the expansion opportunity before this ideograph.
+ m_expansion -= m_expansionPerOpportunity;
+ int expansion = roundf(previousExpansion) - roundf(m_expansion);
+ m_totalWidth += expansion;
+ m_adjustedAdvances.last().width += expansion;
+ previousExpansion = m_expansion;
}
- }
+ m_expansion -= m_expansionPerOpportunity;
+ advance.width += roundf(previousExpansion) - roundf(m_expansion);
+ m_afterExpansion = true;
+ } else
+ m_afterExpansion = false;
// Account for word-spacing.
- if (characterIndex > 0 && !Font::treatAsSpace(*m_run.data(characterIndex - 1)) && m_font.wordSpacing())
+ if (treatAsSpace && characterIndex > 0 && !Font::treatAsSpace(*m_run.data(characterIndex - 1)) && m_font.wordSpacing())
advance.width += m_font.wordSpacing();
- }
+ } else
+ m_afterExpansion = false;
}
// Deal with the float/integer impedance mismatch between CG and WebCore. "Words" (characters
@@ -549,9 +553,9 @@ void ComplexTextController::adjustGlyphsAndAdvances()
FloatRect glyphBounds = fontData->boundsForGlyph(glyph);
glyphBounds.move(glyphOrigin.x, glyphOrigin.y);
m_minGlyphBoundingBoxX = min(m_minGlyphBoundingBoxX, glyphBounds.x());
- m_maxGlyphBoundingBoxX = max(m_maxGlyphBoundingBoxX, glyphBounds.right());
+ m_maxGlyphBoundingBoxX = max(m_maxGlyphBoundingBoxX, glyphBounds.maxX());
m_minGlyphBoundingBoxY = min(m_minGlyphBoundingBoxY, glyphBounds.y());
- m_maxGlyphBoundingBoxY = max(m_maxGlyphBoundingBoxY, glyphBounds.bottom());
+ m_maxGlyphBoundingBoxY = max(m_maxGlyphBoundingBoxY, glyphBounds.maxY());
glyphOrigin.x += advance.width;
glyphOrigin.y += advance.height;
diff --git a/Source/WebCore/platform/graphics/mac/ComplexTextController.h b/Source/WebCore/platform/graphics/mac/ComplexTextController.h
index 9cf80a6..63f93a2 100644
--- a/Source/WebCore/platform/graphics/mac/ComplexTextController.h
+++ b/Source/WebCore/platform/graphics/mac/ComplexTextController.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2009, 2011 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -72,9 +72,9 @@ private:
class ComplexTextRun : public RefCounted<ComplexTextRun> {
public:
#if USE(CORE_TEXT)
- static PassRefPtr<ComplexTextRun> create(CTRunRef ctRun, const SimpleFontData* fontData, const UChar* characters, unsigned stringLocation, size_t stringLength)
+ static PassRefPtr<ComplexTextRun> create(CTRunRef ctRun, const SimpleFontData* fontData, const UChar* characters, unsigned stringLocation, size_t stringLength, CFRange runRange)
{
- return adoptRef(new ComplexTextRun(ctRun, fontData, characters, stringLocation, stringLength));
+ return adoptRef(new ComplexTextRun(ctRun, fontData, characters, stringLocation, stringLength, runRange));
}
#endif
#if USE(ATSUI)
@@ -94,6 +94,7 @@ private:
unsigned stringLocation() const { return m_stringLocation; }
size_t stringLength() const { return m_stringLength; }
ALWAYS_INLINE CFIndex indexAt(size_t i) const;
+ CFIndex indexEnd() const { return m_indexEnd; }
CFIndex endOffsetAt(size_t i) const { ASSERT(!m_isMonotonic); return m_glyphEndOffsets[i]; }
const CGGlyph* glyphs() const { return m_glyphs; }
const CGSize* advances() const { return m_advances; }
@@ -102,7 +103,7 @@ private:
private:
#if USE(CORE_TEXT)
- ComplexTextRun(CTRunRef, const SimpleFontData*, const UChar* characters, unsigned stringLocation, size_t stringLength);
+ ComplexTextRun(CTRunRef, const SimpleFontData*, const UChar* characters, unsigned stringLocation, size_t stringLength, CFRange runRange);
void createTextRunFromFontDataCoreText(bool ltr);
#endif
#if USE(ATSUI)
@@ -133,6 +134,7 @@ private:
#if USE(ATSUI)
Vector<CFIndex, 64> m_atsuiIndices;
#endif
+ CFIndex m_indexEnd;
Vector<CFIndex, 64> m_glyphEndOffsets;
Vector<CGGlyph, 64> m_glyphsVector;
const CGGlyph* m_glyphs;
@@ -175,8 +177,9 @@ private:
unsigned m_glyphInCurrentRun;
unsigned m_characterInCurrentGlyph;
float m_finalRoundingWidth;
- float m_padding;
- float m_padPerSpace;
+ float m_expansion;
+ float m_expansionPerOpportunity;
+ bool m_afterExpansion;
HashSet<const SimpleFontData*>* m_fallbackFonts;
diff --git a/Source/WebCore/platform/graphics/mac/ComplexTextControllerATSUI.cpp b/Source/WebCore/platform/graphics/mac/ComplexTextControllerATSUI.cpp
index 9c2ab6b..b367fdf 100644
--- a/Source/WebCore/platform/graphics/mac/ComplexTextControllerATSUI.cpp
+++ b/Source/WebCore/platform/graphics/mac/ComplexTextControllerATSUI.cpp
@@ -25,10 +25,10 @@
#if USE(ATSUI)
-#include "CharacterNames.h"
#include "Font.h"
#include "ShapeArabic.h"
#include "TextRun.h"
+#include <wtf/unicode/CharacterNames.h>
#ifdef __LP64__
// ATSUTextInserted() is SPI in 64-bit.
@@ -146,6 +146,7 @@ ComplexTextController::ComplexTextRun::ComplexTextRun(ATSUTextLayout atsuTextLay
, m_characters(characters)
, m_stringLocation(stringLocation)
, m_stringLength(stringLength)
+ , m_indexEnd(stringLength)
, m_directionalOverride(directionalOverride)
, m_isMonotonic(true)
{
diff --git a/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.cpp b/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.cpp
index 07fb153..239113f 100644
--- a/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.cpp
+++ b/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.cpp
@@ -42,12 +42,13 @@ extern const CFStringRef kCTTypesetterOptionForcedEmbeddingLevel;
namespace WebCore {
-ComplexTextController::ComplexTextRun::ComplexTextRun(CTRunRef ctRun, const SimpleFontData* fontData, const UChar* characters, unsigned stringLocation, size_t stringLength)
+ComplexTextController::ComplexTextRun::ComplexTextRun(CTRunRef ctRun, const SimpleFontData* fontData, const UChar* characters, unsigned stringLocation, size_t stringLength, CFRange runRange)
: m_coreTextRun(ctRun)
, m_fontData(fontData)
, m_characters(characters)
, m_stringLocation(stringLocation)
, m_stringLength(stringLength)
+ , m_indexEnd(runRange.location + runRange.length)
, m_isMonotonic(true)
{
m_glyphCount = CTRunGetGlyphCount(m_coreTextRun.get());
@@ -165,7 +166,8 @@ void ComplexTextController::collectComplexTextRunsForCharactersCoreText(const UC
for (CFIndex r = 0; r < runCount; r++) {
CTRunRef ctRun = static_cast<CTRunRef>(CFArrayGetValueAtIndex(runArray, r));
ASSERT(CFGetTypeID(ctRun) == CTRunGetTypeID());
- m_complexTextRuns.append(ComplexTextRun::create(ctRun, fontData, cp, stringLocation, length));
+ CFRange runRange = CTRunGetStringRange(ctRun);
+ m_complexTextRuns.append(ComplexTextRun::create(ctRun, fontData, cp, stringLocation, length, runRange));
}
}
diff --git a/Source/WebCore/platform/graphics/mac/FontCacheMac.mm b/Source/WebCore/platform/graphics/mac/FontCacheMac.mm
index 068bd8e..c254906 100644
--- a/Source/WebCore/platform/graphics/mac/FontCacheMac.mm
+++ b/Source/WebCore/platform/graphics/mac/FontCacheMac.mm
@@ -211,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, size, syntheticBold, syntheticOblique, fontDescription.orientation());
+ return new FontPlatformData(platformFont, size, syntheticBold, syntheticOblique, fontDescription.orientation(), fontDescription.widthVariant());
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp b/Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp
index 02bac9c..865051d 100644
--- a/Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp
+++ b/Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp
@@ -111,8 +111,8 @@ float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFon
{
ComplexTextController controller(this, run, true, fallbackFonts);
if (glyphOverflow) {
- glyphOverflow->top = max<int>(glyphOverflow->top, ceilf(-controller.minGlyphBoundingBoxY()) - ascent());
- glyphOverflow->bottom = max<int>(glyphOverflow->bottom, ceilf(controller.maxGlyphBoundingBoxY()) - descent());
+ glyphOverflow->top = max<int>(glyphOverflow->top, ceilf(-controller.minGlyphBoundingBoxY()) - fontMetrics().ascent());
+ glyphOverflow->bottom = max<int>(glyphOverflow->bottom, ceilf(controller.maxGlyphBoundingBoxY()) - fontMetrics().descent());
glyphOverflow->left = max<int>(0, ceilf(-controller.minGlyphBoundingBoxX()));
glyphOverflow->right = max<int>(0, ceilf(controller.maxGlyphBoundingBoxX() - controller.totalWidth()));
}
diff --git a/Source/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp b/Source/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp
index d04d0e4..f2bc33d 100644
--- a/Source/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp
+++ b/Source/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp
@@ -38,9 +38,9 @@ FontCustomPlatformData::~FontCustomPlatformData()
CGFontRelease(m_cgFont);
}
-FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation orientation, FontRenderingMode)
+FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation orientation, FontWidthVariant widthVariant, FontRenderingMode)
{
- return FontPlatformData(m_cgFont, size, bold, italic, orientation);
+ return FontPlatformData(m_cgFont, size, bold, italic, orientation, widthVariant);
}
FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
diff --git a/Source/WebCore/platform/graphics/mac/FontCustomPlatformData.h b/Source/WebCore/platform/graphics/mac/FontCustomPlatformData.h
index 7043d7e..c7ae1ca 100644
--- a/Source/WebCore/platform/graphics/mac/FontCustomPlatformData.h
+++ b/Source/WebCore/platform/graphics/mac/FontCustomPlatformData.h
@@ -23,6 +23,7 @@
#include "FontOrientation.h"
#include "FontRenderingMode.h"
+#include "FontWidthVariant.h"
#include <CoreFoundation/CFBase.h>
#include <wtf/Forward.h>
#include <wtf/Noncopyable.h>
@@ -47,7 +48,7 @@ public:
~FontCustomPlatformData();
- FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, FontRenderingMode = NormalRenderingMode);
+ FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, FontWidthVariant = RegularWidth, FontRenderingMode = NormalRenderingMode);
static bool supportsFormat(const String&);
diff --git a/Source/WebCore/platform/graphics/mac/FontMac.mm b/Source/WebCore/platform/graphics/mac/FontMac.mm
index 8519667..acd7562 100644
--- a/Source/WebCore/platform/graphics/mac/FontMac.mm
+++ b/Source/WebCore/platform/graphics/mac/FontMac.mm
@@ -47,6 +47,11 @@ bool Font::canReturnFallbackFontsForComplexText()
return true;
}
+bool Font::canExpandAroundIdeographsInComplexText()
+{
+ return true;
+}
+
static void showGlyphsWithAdvances(const SimpleFontData* font, CGContextRef context, const CGGlyph* glyphs, const CGSize* advances, size_t count)
{
const FontPlatformData& platformData = font->platformData();
@@ -60,8 +65,8 @@ static void showGlyphsWithAdvances(const SimpleFontData* font, CGContextRef cont
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();
+ runMatrix.tx = savedMatrix.tx + font->fontMetrics().ascent();
+ runMatrix.ty = savedMatrix.ty + font->fontMetrics().descent();
CGContextSetTextMatrix(context, runMatrix);
}
diff --git a/Source/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp b/Source/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp
index 5388c24..8b04ffa 100644
--- a/Source/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp
+++ b/Source/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp
@@ -39,8 +39,8 @@ namespace WebCore {
#ifndef BUILDING_ON_TIGER
static bool shouldUseCoreText(UChar* buffer, unsigned bufferLength, const SimpleFontData* fontData)
{
- if (fontData->orientation() == Vertical && !fontData->isBrokenIdeographFont()) {
- // Ideographs don't have a vertical variant.
+ if (fontData->platformData().widthVariant() != RegularWidth || (fontData->orientation() == Vertical && !fontData->isBrokenIdeographFont())) {
+ // Ideographs don't have a vertical variant or width variants.
for (unsigned i = 0; i < bufferLength; ++i) {
if (!Font::isCJKIdeograph(buffer[i]))
return true;
diff --git a/Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm b/Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm
index 21eb59d..aaa250b 100644
--- a/Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm
+++ b/Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm
@@ -25,7 +25,7 @@
#include "config.h"
-#if ENABLE(3D_CANVAS)
+#if ENABLE(WEBGL)
#include "GraphicsContext3D.h"
@@ -245,6 +245,10 @@ bool GraphicsContext3D::isGLES2Compliant() const
return false;
}
+void GraphicsContext3D::setContextLostCallback(PassOwnPtr<ContextLostCallback>)
+{
+}
+
}
-#endif // ENABLE(3D_CANVAS)
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm b/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
index 2361f6a..8b1fb92 100644
--- a/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
+++ b/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
@@ -616,7 +616,7 @@ QTTime MediaPlayerPrivateQTKit::createQTTime(float time) const
if (!metaDataAvailable())
return QTMakeTime(0, 600);
long timeScale = [[m_qtMovie.get() attributeForKey:QTMovieTimeScaleAttribute] longValue];
- return QTMakeTime(time * timeScale, timeScale);
+ return QTMakeTime(lroundf(time * timeScale), timeScale);
}
void MediaPlayerPrivateQTKit::resumeLoad()
diff --git a/Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm b/Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
index 92585c6..3094498 100644
--- a/Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
+++ b/Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
@@ -218,19 +218,20 @@ void SimpleFontData::platformInit()
int iAscent;
int iDescent;
int iLineGap;
+ unsigned unitsPerEm;
#ifdef BUILDING_ON_TIGER
- wkGetFontMetrics(m_platformData.cgFont(), &iAscent, &iDescent, &iLineGap, &m_unitsPerEm);
+ wkGetFontMetrics(m_platformData.cgFont(), &iAscent, &iDescent, &iLineGap, &unitsPerEm);
#else
iAscent = CGFontGetAscent(m_platformData.cgFont());
iDescent = CGFontGetDescent(m_platformData.cgFont());
iLineGap = CGFontGetLeading(m_platformData.cgFont());
- m_unitsPerEm = CGFontGetUnitsPerEm(m_platformData.cgFont());
+ unitsPerEm = CGFontGetUnitsPerEm(m_platformData.cgFont());
#endif
float pointSize = m_platformData.m_size;
- float fAscent = scaleEmToUnits(iAscent, m_unitsPerEm) * pointSize;
- float fDescent = -scaleEmToUnits(iDescent, m_unitsPerEm) * pointSize;
- float fLineGap = scaleEmToUnits(iLineGap, m_unitsPerEm) * pointSize;
+ float ascent = scaleEmToUnits(iAscent, unitsPerEm) * pointSize;
+ float descent = -scaleEmToUnits(iDescent, unitsPerEm) * pointSize;
+ float lineGap = scaleEmToUnits(iLineGap, unitsPerEm) * pointSize;
// We need to adjust Times, Helvetica, and Courier to closely match the
// vertical metrics of their Microsoft counterparts that are the de facto
@@ -239,25 +240,23 @@ void SimpleFontData::platformInit()
// and add it to the ascent.
NSString *familyName = [m_platformData.font() familyName];
if ([familyName isEqualToString:@"Times"] || [familyName isEqualToString:@"Helvetica"] || [familyName isEqualToString:@"Courier"])
- fAscent += floorf(((fAscent + fDescent) * 0.15f) + 0.5f);
+ ascent += floorf(((ascent + descent) * 0.15f) + 0.5f);
else if ([familyName isEqualToString:@"Geeza Pro"]) {
// Geeza Pro has glyphs that draw slightly above the ascent or far below the descent. Adjust
// those vertical metrics to better match reality, so that diacritics at the bottom of one line
// do not overlap diacritics at the top of the next line.
- fAscent *= 1.08f;
- fDescent *= 2.f;
+ ascent *= 1.08f;
+ descent *= 2.f;
}
- m_ascent = lroundf(fAscent);
- m_descent = lroundf(fDescent);
- m_lineGap = lroundf(fLineGap);
- m_lineSpacing = m_ascent + m_descent + m_lineGap;
-
+ // Compute and store line spacing, before the line metrics hacks are applied.
+ m_fontMetrics.setLineSpacing(lroundf(ascent) + lroundf(descent) + lroundf(lineGap));
+
// Hack Hiragino line metrics to allow room for marked text underlines.
// <rdar://problem/5386183>
- if (m_descent < 3 && m_lineGap >= 3 && [familyName hasPrefix:@"Hiragino"]) {
- m_lineGap -= 3 - m_descent;
- m_descent = 3;
+ if (descent < 3 && lineGap >= 3 && [familyName hasPrefix:@"Hiragino"]) {
+ lineGap -= 3 - descent;
+ descent = 3;
}
if (m_orientation == Vertical) {
@@ -278,6 +277,8 @@ void SimpleFontData::platformInit()
m_orientation = Horizontal;
}
+ float xHeight;
+
// Measure the actual character "x", because AppKit synthesizes X height rather than getting it from the font.
// Unfortunately, NSFont will round this for us so we don't quite get the right value.
GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page();
@@ -288,21 +289,27 @@ void SimpleFontData::platformInit()
// and web pages that foolishly use this metric for width will be laid out
// poorly if we return an accurate height. Classic case is Times 13 point,
// which has an "x" that is 7x6 pixels.
- m_xHeight = static_cast<float>(max(CGRectGetMaxX(xBox), -CGRectGetMinY(xBox)));
+ xHeight = static_cast<float>(max(CGRectGetMaxX(xBox), -CGRectGetMinY(xBox)));
} else {
#ifndef BUILDING_ON_TIGER
- m_xHeight = static_cast<float>(CGFontGetXHeight(m_platformData.cgFont())) / m_unitsPerEm;
+ xHeight = static_cast<float>(CGFontGetXHeight(m_platformData.cgFont())) / unitsPerEm;
#else
- m_xHeight = m_platformData.font() ? [m_platformData.font() xHeight] : 0;
+ 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 following code makes a guess for 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;
+ if (!static_cast<int>(xHeight) && ascent)
+ xHeight = 2 * ascent / 3;
}
+
+ m_fontMetrics.setUnitsPerEm(unitsPerEm);
+ m_fontMetrics.setAscent(ascent);
+ m_fontMetrics.setDescent(descent);
+ m_fontMetrics.setLineGap(lineGap);
+ m_fontMetrics.setXHeight(xHeight);
}
-
+
static CFDataRef copyFontTableForTag(FontPlatformData& platformData, FourCharCode tableName)
{
#ifdef BUILDING_ON_TIGER
@@ -337,7 +344,7 @@ void SimpleFontData::platformCharWidthInit()
if (os2Table && CFDataGetLength(os2Table.get()) >= 4) {
const UInt8* os2 = CFDataGetBytePtr(os2Table.get());
SInt16 os2AvgCharWidth = os2[2] * 256 + os2[3];
- m_avgCharWidth = scaleEmToUnits(os2AvgCharWidth, m_unitsPerEm) * m_platformData.m_size;
+ m_avgCharWidth = scaleEmToUnits(os2AvgCharWidth, m_fontMetrics.unitsPerEm()) * m_platformData.m_size;
}
RetainPtr<CFDataRef> headTable(AdoptCF, copyFontTableForTag(m_platformData, 'head'));
@@ -348,7 +355,7 @@ void SimpleFontData::platformCharWidthInit()
SInt16 xMin = static_cast<SInt16>(uxMin);
SInt16 xMax = static_cast<SInt16>(uxMax);
float diff = static_cast<float>(xMax - xMin);
- m_maxCharWidth = scaleEmToUnits(diff, m_unitsPerEm) * m_platformData.m_size;
+ m_maxCharWidth = scaleEmToUnits(diff, m_fontMetrics.unitsPerEm()) * m_platformData.m_size;
}
// Fallback to a cross-platform estimate, which will populate these values if they are non-positive.
@@ -387,7 +394,7 @@ SimpleFontData* SimpleFontData::scaledFontData(const FontDescription& fontDescri
BEGIN_BLOCK_OBJC_EXCEPTIONS;
float size = m_platformData.size() * scaleFactor;
- FontPlatformData scaledFontData([[NSFontManager sharedFontManager] convertFont:m_platformData.font() toSize:size], size);
+ FontPlatformData scaledFontData([[NSFontManager sharedFontManager] convertFont:m_platformData.font() toSize:size], size, false, false, m_platformData.orientation());
// AppKit resets the type information (screen/printer) when you convert a font to a different size.
// We have to fix up the font that we're handed back.
@@ -470,13 +477,13 @@ FloatRect SimpleFontData::platformBoundsForGlyph(Glyph glyph) const
#ifndef BUILDING_ON_TIGER
boundingBox = CTFontGetBoundingRectsForGlyphs(m_platformData.ctFont(),
orientation() == Vertical ? kCTFontVerticalOrientation : kCTFontHorizontalOrientation, &glyph, 0, 1);
- boundingBox.setY(-boundingBox.bottom());
+ boundingBox.setY(-boundingBox.maxY());
#else
// FIXME: Custom fonts don't have NSFonts, so this function doesn't compute correct bounds for these on Tiger.
if (!m_platformData.font())
return boundingBox;
boundingBox = [m_platformData.font() boundingRectForGlyph:glyph];
- boundingBox.setY(-boundingBox.bottom());
+ boundingBox.setY(-boundingBox.maxY());
#endif
if (m_syntheticBoldOffset)
boundingBox.setWidth(boundingBox.width() + m_syntheticBoldOffset);
diff --git a/Source/WebCore/platform/graphics/mac/WebGLLayer.mm b/Source/WebCore/platform/graphics/mac/WebGLLayer.mm
index c24181b..d1007b9 100644
--- a/Source/WebCore/platform/graphics/mac/WebGLLayer.mm
+++ b/Source/WebCore/platform/graphics/mac/WebGLLayer.mm
@@ -26,7 +26,7 @@
#include "config.h"
#if USE(ACCELERATED_COMPOSITING)
-#if ENABLE(3D_CANVAS)
+#if ENABLE(WEBGL)
#import "WebGLLayer.h"
@@ -163,5 +163,5 @@ static void freeData(void *, const void *data, size_t /* size */)
@end
-#endif // ENABLE(3D_CANVAS)
+#endif // ENABLE(WEBGL)
#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp
index 3eb5196..df45147 100644
--- a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp
+++ b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp
@@ -25,7 +25,7 @@
#include "config.h"
-#if ENABLE(3D_CANVAS)
+#if ENABLE(WEBGL)
#include "Extensions3DOpenGL.h"
@@ -79,6 +79,10 @@ bool Extensions3DOpenGL::supports(const String& name)
if (name == "GL_ANGLE_framebuffer_multisample")
return m_availableExtensions.contains("GL_EXT_framebuffer_multisample");
+ // Desktop GL always supports GL_OES_rgb8_rgba8.
+ if (name == "GL_OES_rgb8_rgba8")
+ return true;
+
// If GL_ARB_texture_float is available then we report GL_OES_texture_float and
// GL_OES_texture_half_float as available.
if (name == "GL_OES_texture_float" || name == "GL_OES_texture_half_float")
@@ -125,4 +129,4 @@ void Extensions3DOpenGL::renderbufferStorageMultisample(unsigned long target, un
} // namespace WebCore
-#endif // ENABLE(3D_CANVAS)
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp b/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp
index 7c103f3..c224e20 100644
--- a/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp
+++ b/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp
@@ -25,7 +25,7 @@
#include "config.h"
-#if ENABLE(3D_CANVAS)
+#if ENABLE(WEBGL)
#include "GraphicsContext3D.h"
@@ -83,7 +83,7 @@ void GraphicsContext3D::paintRenderingResultsToCanvas(CanvasRenderingContext* co
int rowBytes = m_currentWidth * 4;
int totalBytes = rowBytes * m_currentHeight;
- OwnArrayPtr<unsigned char> pixels(new unsigned char[totalBytes]);
+ OwnArrayPtr<unsigned char> pixels = adoptArrayPtr(new unsigned char[totalBytes]);
if (!pixels)
return;
@@ -1437,28 +1437,6 @@ void GraphicsContext3D::deleteTexture(Platform3DObject texture)
glDeleteTextures(1, &texture);
}
-uint32_t GraphicsContext3D::sizeInBytes(GC3Denum type)
-{
- switch (type) {
- case GL_BYTE:
- return sizeof(GLbyte);
- case GL_UNSIGNED_BYTE:
- return sizeof(GLubyte);
- case GL_SHORT:
- return sizeof(GLshort);
- case GL_UNSIGNED_SHORT:
- return sizeof(GLushort);
- case GL_INT:
- return sizeof(GLint);
- case GL_UNSIGNED_INT:
- return sizeof(GLuint);
- case GL_FLOAT:
- return sizeof(GLfloat);
- default:
- return 0;
- }
-}
-
void GraphicsContext3D::synthesizeGLError(GC3Denum error)
{
m_syntheticErrors.add(error);
@@ -1473,4 +1451,4 @@ Extensions3D* GraphicsContext3D::getExtensions()
}
-#endif // ENABLE(3D_CANVAS)
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/platform/graphics/opengl/TextureMapperGL.cpp b/Source/WebCore/platform/graphics/opengl/TextureMapperGL.cpp
index 03f9b7c..2e2082d 100644
--- a/Source/WebCore/platform/graphics/opengl/TextureMapperGL.cpp
+++ b/Source/WebCore/platform/graphics/opengl/TextureMapperGL.cpp
@@ -390,7 +390,7 @@ void TextureMapperGL::drawTexture(const BitmapTexture& texture, const IntRect& t
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(data().projectionMatrix).multLeft(modelViewMatrix).multLeft(TransformationMatrix(
+ TransformationMatrix matrix = TransformationMatrix(data().projectionMatrix).multiply(modelViewMatrix).multiply(TransformationMatrix(
targetRect.width(), 0, 0, 0,
0, targetRect.height(), 0, 0,
0, 0, 1, 0,
@@ -606,7 +606,7 @@ void TextureMapperGL::paintToTarget(const BitmapTexture& aSurface, const IntSize
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 matrix = createProjectionMatrix(surfaceSize, true).multiply(transform).multiply(
TransformationMatrix(
surface.m_actualSize.width(), 0, 0, 0,
0, surface.m_actualSize.height(), 0, 0,
diff --git a/Source/WebCore/platform/graphics/pango/FontCustomPlatformDataPango.cpp b/Source/WebCore/platform/graphics/pango/FontCustomPlatformDataPango.cpp
index a158689..f9d36d3 100644
--- a/Source/WebCore/platform/graphics/pango/FontCustomPlatformDataPango.cpp
+++ b/Source/WebCore/platform/graphics/pango/FontCustomPlatformDataPango.cpp
@@ -30,7 +30,7 @@ FontCustomPlatformData::~FontCustomPlatformData()
{
}
-FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, FontRenderingMode)
+FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, FontWidthVariant, FontRenderingMode)
{
return FontPlatformData(m_fontFace, size, bold, italic);
}
diff --git a/Source/WebCore/platform/graphics/pango/SimpleFontDataPango.cpp b/Source/WebCore/platform/graphics/pango/SimpleFontDataPango.cpp
index d0bf836..3fe15b3 100644
--- a/Source/WebCore/platform/graphics/pango/SimpleFontDataPango.cpp
+++ b/Source/WebCore/platform/graphics/pango/SimpleFontDataPango.cpp
@@ -49,21 +49,27 @@ void SimpleFontData::platformInit()
cairo_font_extents_t font_extents;
cairo_text_extents_t text_extents;
cairo_scaled_font_extents(m_platformData.m_scaledFont, &font_extents);
- m_ascent = static_cast<int>(lroundf(font_extents.ascent));
- m_descent = static_cast<int>(lroundf(font_extents.descent));
- m_lineSpacing = static_cast<int>(lroundf(font_extents.height));
+
+ m_fontMetrics.setAscent(font_extents.ascent);
+ m_fontMetrics.setDescent(font_extents.descent);
+
// There seems to be some rounding error in cairo (or in how we
// use cairo) with some fonts, like DejaVu Sans Mono, which makes
// cairo report a height smaller than ascent + descent, which is
// wrong and confuses WebCore's layout system. Workaround this
// while we figure out what's going on.
- if (m_lineSpacing < m_ascent + m_descent)
- m_lineSpacing = m_ascent + m_descent;
+ float lineSpacing = font_extents.height;
+ if (lineSpacing < font_extents.ascent + font_extents.descent)
+ lineSpacing = font_extents.ascent + font_extents.descent;
+ m_fontMetrics.setLineSpacing(lroundf(lineSpacing));
+ m_fontMetrics.setLineGap(lineSpacing - font_extents.ascent - font_extents.descent);
+
cairo_scaled_font_text_extents(m_platformData.m_scaledFont, "x", &text_extents);
- m_xHeight = text_extents.height;
+ m_fontMetrics.setXHeight(text_extents.height);
+
cairo_scaled_font_text_extents(m_platformData.m_scaledFont, " ", &text_extents);
- m_spaceWidth = static_cast<float>(text_extents.x_advance);
- m_lineGap = m_lineSpacing - m_ascent - m_descent;
+ m_spaceWidth = static_cast<float>(text_extents.x_advance);
+
m_syntheticBoldOffset = m_platformData.syntheticBold() ? 1.0f : 0.f;
}
diff --git a/Source/WebCore/platform/graphics/qt/ContextShadowQt.cpp b/Source/WebCore/platform/graphics/qt/ContextShadowQt.cpp
index 37d6b44..9eb31a7 100644
--- a/Source/WebCore/platform/graphics/qt/ContextShadowQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/ContextShadowQt.cpp
@@ -57,7 +57,7 @@ private:
ShadowBuffer::ShadowBuffer(QObject* parent)
: QObject(parent)
- , timerId(0)
+ , timerId(-1)
{
}
@@ -89,7 +89,8 @@ QImage* ShadowBuffer::scratchImage(const QSize& size)
void ShadowBuffer::schedulePurge()
{
static const double BufferPurgeDelay = 2; // seconds
- killTimer(timerId);
+ if (timerId >= 0)
+ killTimer(timerId);
timerId = startTimer(BufferPurgeDelay * 1000);
}
diff --git a/Source/WebCore/platform/graphics/qt/Extensions3DQt.cpp b/Source/WebCore/platform/graphics/qt/Extensions3DQt.cpp
index cd28f0e..5238d46 100644
--- a/Source/WebCore/platform/graphics/qt/Extensions3DQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/Extensions3DQt.cpp
@@ -25,7 +25,7 @@
#include "config.h"
-#if ENABLE(3D_CANVAS)
+#if ENABLE(WEBGL)
#include "Extensions3DQt.h"
@@ -58,4 +58,4 @@ int Extensions3DQt::getGraphicsResetStatusARB()
} // namespace WebCore
-#endif // ENABLE(3D_CANVAS)
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/platform/graphics/qt/FontCustomPlatformData.h b/Source/WebCore/platform/graphics/qt/FontCustomPlatformData.h
index 54fa679..e8441d2 100644
--- a/Source/WebCore/platform/graphics/qt/FontCustomPlatformData.h
+++ b/Source/WebCore/platform/graphics/qt/FontCustomPlatformData.h
@@ -24,6 +24,7 @@
#include "FontOrientation.h"
#include "FontRenderingMode.h"
+#include "FontWidthVariant.h"
#include <wtf/FastAllocBase.h>
#include <wtf/Forward.h>
#include <wtf/Noncopyable.h>
@@ -42,7 +43,7 @@ public:
// for use with QFontDatabase::addApplicationFont/removeApplicationFont
int m_handle;
- FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, FontRenderingMode = NormalRenderingMode);
+ FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, FontWidthVariant = RegularWidth, FontRenderingMode = NormalRenderingMode);
static bool supportsFormat(const String&);
};
diff --git a/Source/WebCore/platform/graphics/qt/FontCustomPlatformDataQt.cpp b/Source/WebCore/platform/graphics/qt/FontCustomPlatformDataQt.cpp
index e2f009b..ec8747d 100644
--- a/Source/WebCore/platform/graphics/qt/FontCustomPlatformDataQt.cpp
+++ b/Source/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, FontOrientation, FontRenderingMode)
+FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, FontWidthVariant, FontRenderingMode)
{
QFont font;
font.setFamily(QFontDatabase::applicationFontFamilies(m_handle)[0]);
diff --git a/Source/WebCore/platform/graphics/qt/FontQt.cpp b/Source/WebCore/platform/graphics/qt/FontQt.cpp
index 778a13f..646cd0e 100644
--- a/Source/WebCore/platform/graphics/qt/FontQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/FontQt.cpp
@@ -61,14 +61,14 @@ static const QString fromRawDataWithoutRef(const String& string, int start = 0,
static QTextLine setupLayout(QTextLayout* layout, const TextRun& style)
{
int flags = style.rtl() ? Qt::TextForceRightToLeft : Qt::TextForceLeftToRight;
- if (style.padding())
+ if (style.expansion())
flags |= Qt::TextJustificationForced;
layout->setFlags(flags);
layout->beginLayout();
QTextLine line = layout->createLine();
line.setLineWidth(INT_MAX/256);
- if (style.padding())
- line.setLineWidth(line.naturalTextWidth() + style.padding());
+ if (style.expansion())
+ line.setLineWidth(line.naturalTextWidth() + style.expansion());
layout->endLayout();
return line;
}
@@ -107,7 +107,7 @@ static void drawTextCommon(GraphicsContext* ctx, const TextRun& run, const Float
textStrokePen = QPen(QColor(ctx->strokeColor()), ctx->strokeThickness());
}
- String sanitized = Font::normalizeSpaces(String(run.characters(), run.length()));
+ String sanitized = Font::normalizeSpaces(run.characters(), run.length());
QString string = fromRawDataWithoutRef(sanitized);
QPointF pt(point.x(), point.y());
@@ -196,7 +196,7 @@ static void drawTextCommon(GraphicsContext* ctx, const TextRun& run, const Float
p->save();
p->setPen(ctxShadow->m_color);
p->translate(ctxShadow->offset());
- p->drawText(pt, string, flags, run.padding());
+ p->drawText(pt, string, flags, run.expansion());
p->restore();
} else {
QFontMetrics fm(font);
@@ -210,7 +210,7 @@ static void drawTextCommon(GraphicsContext* ctx, const TextRun& run, const Float
// Since it will be blurred anyway, we don't care about render hints.
shadowPainter->setFont(p->font());
shadowPainter->setPen(ctxShadow->m_color);
- shadowPainter->drawText(pt, string, flags, run.padding());
+ shadowPainter->drawText(pt, string, flags, run.expansion());
ctxShadow->endShadowLayer(ctx);
}
}
@@ -243,7 +243,7 @@ static void drawTextCommon(GraphicsContext* ctx, const TextRun& run, const Float
if (ctx->textDrawingMode() & TextModeFill) {
QPen previousPen = p->pen();
p->setPen(textFillPen);
- p->drawText(pt, string, flags, run.padding());
+ p->drawText(pt, string, flags, run.expansion());
p->setPen(previousPen);
}
}
@@ -299,7 +299,7 @@ float Font::floatWidthForSimpleText(const TextRun& run, GlyphBuffer* glyphBuffer
if (!run.length())
return 0;
- String sanitized = Font::normalizeSpaces(String(run.characters(), run.length()));
+ String sanitized = Font::normalizeSpaces(run.characters(), run.length());
QString string = fromRawDataWithoutRef(sanitized);
int w = QFontMetrics(font()).width(string, -1, Qt::TextBypassShaping);
@@ -308,7 +308,7 @@ float Font::floatWidthForSimpleText(const TextRun& run, GlyphBuffer* glyphBuffer
if (treatAsSpace(run[0]))
w -= m_wordSpacing;
- return w + run.padding();
+ return w + run.expansion();
#else
Q_ASSERT(false);
return 0;
@@ -324,9 +324,9 @@ float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFon
return 0;
if (run.length() == 1 && treatAsSpace(run[0]))
- return QFontMetrics(font()).width(space) + run.padding();
+ return QFontMetrics(font()).width(space) + run.expansion();
- String sanitized = Font::normalizeSpaces(String(run.characters(), run.length()));
+ String sanitized = Font::normalizeSpaces(run.characters(), run.length());
QString string = fromRawDataWithoutRef(sanitized);
int w = QFontMetrics(font()).width(string);
@@ -334,13 +334,13 @@ float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFon
if (treatAsSpace(run[0]))
w -= m_wordSpacing;
- return w + run.padding();
+ return w + run.expansion();
}
int Font::offsetForPositionForSimpleText(const TextRun& run, float position, bool includePartialGlyphs) const
{
#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)
- String sanitized = Font::normalizeSpaces(String(run.characters(), run.length()));
+ String sanitized = Font::normalizeSpaces(run.characters(), run.length());
QString string = fromRawDataWithoutRef(sanitized);
QFontMetrics fm(font());
@@ -367,7 +367,7 @@ int Font::offsetForPositionForSimpleText(const TextRun& run, float position, boo
int Font::offsetForPositionForComplexText(const TextRun& run, float position, bool) const
{
- String sanitized = Font::normalizeSpaces(String(run.characters(), run.length()));
+ String sanitized = Font::normalizeSpaces(run.characters(), run.length());
QString string = fromRawDataWithoutRef(sanitized);
QTextLayout layout(string, font());
@@ -378,7 +378,7 @@ int Font::offsetForPositionForComplexText(const TextRun& run, float position, bo
FloatRect Font::selectionRectForSimpleText(const TextRun& run, const FloatPoint& pt, int h, int from, int to) const
{
#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)
- String sanitized = Font::normalizeSpaces(String(run.characters(), run.length()));
+ String sanitized = Font::normalizeSpaces(run.characters(), run.length());
QString wholeText = fromRawDataWithoutRef(sanitized);
QString selectedText = fromRawDataWithoutRef(sanitized, from, qMin(to - from, wholeText.length() - from));
@@ -394,7 +394,7 @@ FloatRect Font::selectionRectForSimpleText(const TextRun& run, const FloatPoint&
FloatRect Font::selectionRectForComplexText(const TextRun& run, const FloatPoint& pt, int h, int from, int to) const
{
- String sanitized = Font::normalizeSpaces(String(run.characters(), run.length()));
+ String sanitized = Font::normalizeSpaces(run.characters(), run.length());
QString string = fromRawDataWithoutRef(sanitized);
QTextLayout layout(string, font());
@@ -413,6 +413,11 @@ bool Font::canReturnFallbackFontsForComplexText()
return false;
}
+bool Font::canExpandAroundIdeographsInComplexText()
+{
+ return false;
+}
+
bool Font::primaryFontHasGlyphForCharacter(UChar32) const
{
notImplemented();
diff --git a/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp b/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
index 295212c..8b87f5f 100644
--- a/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
@@ -34,7 +34,7 @@
#include <wtf/UnusedParam.h>
#include <wtf/text/CString.h>
-#if ENABLE(3D_CANVAS)
+#if ENABLE(WEBGL)
namespace WebCore {
@@ -1611,28 +1611,6 @@ void GraphicsContext3D::deleteTexture(Platform3DObject texture)
glDeleteTextures(1, &texture);
}
-unsigned int GraphicsContext3D::sizeInBytes(GC3Denum type)
-{
- switch (type) {
- case GraphicsContext3D::BYTE:
- return sizeof(GLbyte);
- case GraphicsContext3D::UNSIGNED_BYTE:
- return sizeof(GLubyte);
- case GraphicsContext3D::SHORT:
- return sizeof(GLshort);
- case GraphicsContext3D::UNSIGNED_SHORT:
- return sizeof(GLushort);
- case GraphicsContext3D::INT:
- return sizeof(GLint);
- case GraphicsContext3D::UNSIGNED_INT:
- return sizeof(GLuint);
- case GraphicsContext3D::FLOAT:
- return sizeof(GLfloat);
- default:
- return 0;
- }
-}
-
void GraphicsContext3D::synthesizeGLError(GC3Denum error)
{
m_internal->m_syntheticErrors.add(error);
@@ -1669,6 +1647,10 @@ bool GraphicsContext3D::getImageData(Image* image,
format, type, neededAlphaOp, outputVector.data());
}
+void GraphicsContext3D::setContextLostCallback(PassOwnPtr<ContextLostCallback>)
+{
+}
+
}
-#endif // ENABLE(3D_CANVAS)
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
index 4dabe09..bf2826c 100644
--- a/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
@@ -62,14 +62,11 @@
#include <QPolygonF>
#include <QStack>
#include <QVector>
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
+#include <wtf/MathExtras.h>
namespace WebCore {
-QPainter::CompositionMode GraphicsContext::toQtCompositionMode(CompositeOperator op)
+static inline QPainter::CompositionMode toQtCompositionMode(CompositeOperator op)
{
switch (op) {
case CompositeClear:
@@ -231,8 +228,15 @@ GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate(QPainter* p, cons
if (!painter)
return;
+#if OS(SYMBIAN)
+ if (painter->paintEngine()->type() == QPaintEngine::OpenVG)
+ antiAliasingForRectsAndLines = true;
+ else
+ antiAliasingForRectsAndLines = painter->testRenderHint(QPainter::Antialiasing);
+#else
// Use the default the QPainter was constructed with.
antiAliasingForRectsAndLines = painter->testRenderHint(QPainter::Antialiasing);
+#endif
// Used for default image interpolation quality.
initialSmoothPixmapTransformHint = painter->testRenderHint(QPainter::SmoothPixmapTransform);
@@ -784,7 +788,7 @@ void GraphicsContext::clipPath(const Path& path, WindRule clipRule)
p->setClipPath(platformPath, Qt::IntersectClip);
}
-void drawFocusRingForPath(QPainter* p, const QPainterPath& path, int width, const Color& color, bool antiAliasing)
+void drawFocusRingForPath(QPainter* p, const QPainterPath& path, const Color& color, bool antiAliasing)
{
const bool antiAlias = p->testRenderHint(QPainter::Antialiasing);
p->setRenderHint(QPainter::Antialiasing, antiAliasing);
@@ -794,9 +798,8 @@ void drawFocusRingForPath(QPainter* p, const QPainterPath& path, int width, cons
QPen nPen = p->pen();
nPen.setColor(color);
- nPen.setWidth(width);
p->setBrush(Qt::NoBrush);
- nPen.setStyle(Qt::SolidLine);
+ nPen.setStyle(Qt::DotLine);
p->strokePath(path, nPen);
p->setBrush(oldBrush);
@@ -805,14 +808,14 @@ void drawFocusRingForPath(QPainter* p, const QPainterPath& path, int width, cons
p->setRenderHint(QPainter::Antialiasing, antiAlias);
}
-void GraphicsContext::drawFocusRing(const Path& path, int width, int offset, const Color& color)
+void GraphicsContext::drawFocusRing(const Path& path, int /* width */, int offset, const Color& color)
{
// FIXME: Use 'offset' for something? http://webkit.org/b/49909
if (paintingDisabled() || !color.isValid())
return;
- drawFocusRingForPath(m_data->p(), path.platformPath(), width, color, m_data->antiAliasingForRectsAndLines);
+ drawFocusRingForPath(m_data->p(), path.platformPath(), color, m_data->antiAliasingForRectsAndLines);
}
/**
@@ -840,8 +843,7 @@ void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int
tmpPath.addRoundedRect(rect, radius, radius);
path = path.united(tmpPath);
}
-
- drawFocusRingForPath(m_data->p(), path, width, color, m_data->antiAliasingForRectsAndLines);
+ drawFocusRingForPath(m_data->p(), path, color, m_data->antiAliasingForRectsAndLines);
}
void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool)
@@ -896,7 +898,7 @@ FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& frect)
qreal deviceScaleY = sqrtf(deviceTransform.m21() * deviceTransform.m21() + deviceTransform.m22() * deviceTransform.m22());
QPoint deviceOrigin(frect.x() * deviceScaleX, frect.y() * deviceScaleY);
- QPoint deviceLowerRight(frect.right() * deviceScaleX, frect.bottom() * deviceScaleY);
+ QPoint deviceLowerRight(frect.maxX() * deviceScaleX, frect.maxY() * deviceScaleY);
// Don't let the height or width round to 0 unless either was originally 0
if (deviceOrigin.y() == deviceLowerRight.y() && frect.height())
@@ -1135,7 +1137,7 @@ void GraphicsContext::rotate(float radians)
if (paintingDisabled())
return;
- m_data->p()->rotate(180 / M_PI*radians);
+ m_data->p()->rotate(rad2deg(qreal(radians)));
}
void GraphicsContext::scale(const FloatSize& s)
diff --git a/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp b/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp
index 75fb427..0d7aa45 100644
--- a/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp
@@ -305,7 +305,7 @@ public:
}
} m_state;
-#if ENABLE(3D_CANVAS)
+#if ENABLE(WEBGL)
const GraphicsContext3D* m_gc3D;
#endif
@@ -335,7 +335,7 @@ GraphicsLayerQtImpl::GraphicsLayerQtImpl(GraphicsLayerQt* newLayer)
#if ENABLE(TILED_BACKING_STORE)
, m_tiledBackingStore(0)
#endif
-#if ENABLE(3D_CANVAS)
+#if ENABLE(WEBGL)
, m_gc3D(0)
#endif
{
@@ -529,12 +529,12 @@ void GraphicsLayerQtImpl::updateTransform()
// have to maintain that ourselves for 3D.
localTransform
.translate3d(originX + m_state.pos.x(), originY + m_state.pos.y(), m_state.anchorPoint.z())
- .multLeft(m_baseTransform)
+ .multiply(m_baseTransform)
.translate3d(-originX, -originY, -m_state.anchorPoint.z());
// This is the actual 3D transform of this item, with the ancestors' transform baked in.
m_transformRelativeToRootLayer = TransformationMatrix(parent ? parent->m_transformRelativeToRootLayer : TransformationMatrix())
- .multLeft(localTransform);
+ .multiply(localTransform);
// Now we have enough information to determine if the layer is facing backwards.
if (!m_state.backfaceVisibility && m_transformRelativeToRootLayer.inverse().m33() < 0) {
@@ -562,7 +562,7 @@ void GraphicsLayerQtImpl::updateTransform()
if (!m_state.childrenTransform.isIdentity()) {
m_transformRelativeToRootLayer
.translate(m_size.width() / 2, m_size.height() /2)
- .multLeft(m_state.childrenTransform)
+ .multiply(m_state.childrenTransform)
.translate(-m_size.width() / 2, -m_size.height() /2);
}
@@ -647,7 +647,7 @@ void GraphicsLayerQtImpl::paint(QPainter* painter, const QStyleOptionGraphicsIte
case MediaContentType:
// we don't need to paint anything: we have a QGraphicsItem from the media element
break;
-#if ENABLE(3D_CANVAS)
+#if ENABLE(WEBGL)
case Canvas3DContentType:
m_gc3D->paint(painter, option->rect);
break;
@@ -791,7 +791,7 @@ void GraphicsLayerQtImpl::flushChanges(bool recursive, bool forceUpdateTransform
setFlag(ItemHasNoContents, !m_layer->drawsContent());
break;
-#if ENABLE(3D_CANVAS)
+#if ENABLE(WEBGL)
case Canvas3DContentType:
if (m_pendingContent.contentType != m_currentContent.contentType)
update();
@@ -1250,7 +1250,7 @@ void GraphicsLayerQt::setContentsBackgroundColor(const Color& color)
GraphicsLayer::setContentsBackgroundColor(color);
}
-#if ENABLE(3D_CANVAS)
+#if ENABLE(WEBGL)
void GraphicsLayerQt::setContentsToGraphicsContext3D(const GraphicsContext3D* ctx)
{
if (ctx == m_impl->m_gc3D)
diff --git a/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.h b/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.h
index 8027143..569bd8d 100644
--- a/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.h
+++ b/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.h
@@ -20,7 +20,7 @@
#ifndef GraphicsLayerQt_h
#define GraphicsLayerQt_h
-#if ENABLE(3D_CANVAS)
+#if ENABLE(WEBGL)
#include "GraphicsContext3D.h"
#endif
#include "GraphicsLayer.h"
@@ -79,7 +79,7 @@ public:
virtual void setContentsNeedsDisplay();
virtual void setContentsToMedia(PlatformLayer*);
virtual void setContentsBackgroundColor(const Color&);
-#if ENABLE(3D_CANVAS)
+#if ENABLE(WEBGL)
virtual void setContentsToGraphicsContext3D(const GraphicsContext3D*);
virtual void setGraphicsContext3DNeedsDisplay();
#endif
diff --git a/Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp b/Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp
index d1567ec..62f5c3e 100644
--- a/Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp
@@ -188,7 +188,7 @@ PassRefPtr<ByteArray> getImageData(const IntRect& rect, const ImageBufferData& i
RefPtr<ByteArray> result = ByteArray::create(rect.width() * rect.height() * 4);
unsigned char* data = result->data();
- if (rect.x() < 0 || rect.y() < 0 || rect.right() > size.width() || rect.bottom() > size.height())
+ if (rect.x() < 0 || rect.y() < 0 || rect.maxX() > size.width() || rect.maxY() > size.height())
memset(data, 0, result->length());
int originx = rect.x();
@@ -197,7 +197,7 @@ PassRefPtr<ByteArray> getImageData(const IntRect& rect, const ImageBufferData& i
destx = -originx;
originx = 0;
}
- int endx = rect.right();
+ int endx = rect.maxX();
if (endx > size.width())
endx = size.width();
int numColumns = endx - originx;
@@ -208,7 +208,7 @@ PassRefPtr<ByteArray> getImageData(const IntRect& rect, const ImageBufferData& i
desty = -originy;
originy = 0;
}
- int endy = rect.bottom();
+ int endy = rect.maxY();
if (endy > size.height())
endy = size.height();
int numRows = endy - originy;
@@ -302,9 +302,9 @@ void putImageData(ByteArray*& source, const IntSize& sourceSize, const IntRect&
ASSERT(destx >= 0);
ASSERT(destx < size.width());
ASSERT(originx >= 0);
- ASSERT(originx <= sourceRect.right());
+ ASSERT(originx <= sourceRect.maxX());
- int endx = destPoint.x() + sourceRect.right();
+ int endx = destPoint.x() + sourceRect.maxX();
ASSERT(endx <= size.width());
int numColumns = endx - destx;
@@ -314,9 +314,9 @@ void putImageData(ByteArray*& source, const IntSize& sourceSize, const IntRect&
ASSERT(desty >= 0);
ASSERT(desty < size.height());
ASSERT(originy >= 0);
- ASSERT(originy <= sourceRect.bottom());
+ ASSERT(originy <= sourceRect.maxY());
- int endy = destPoint.y() + sourceRect.bottom();
+ int endy = destPoint.y() + sourceRect.maxY();
ASSERT(endy <= size.height());
int numRows = endy - desty;
diff --git a/Source/WebCore/platform/graphics/qt/ImageDecoderQt.cpp b/Source/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
index 71352e4..3540994 100644
--- a/Source/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
@@ -213,7 +213,7 @@ bool ImageDecoderQt::internalHandleCurrentImage(size_t frameIndex)
// now into the ImageFrame - even if the image is not
ImageFrame* const buffer = &m_frameBufferCache[frameIndex];
- buffer->setRect(m_reader->currentImageRect());
+ buffer->setOriginalFrameRect(m_reader->currentImageRect());
buffer->setStatus(ImageFrame::FrameComplete);
buffer->setDuration(m_reader->nextImageDelay());
buffer->setPixmap(pixmap);
diff --git a/Source/WebCore/platform/graphics/qt/ImageQt.cpp b/Source/WebCore/platform/graphics/qt/ImageQt.cpp
index 58f82ef..0c8ce9e 100644
--- a/Source/WebCore/platform/graphics/qt/ImageQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/ImageQt.cpp
@@ -120,11 +120,9 @@ void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const
CompositeOperator previousOperator = ctxt->compositeOperation();
- ctxt->setCompositeOperation(op);
- QPainter* p = ctxt->platformContext();
- if (!pixmap.hasAlpha() && p->compositionMode() == QPainter::CompositionMode_SourceOver)
- p->setCompositionMode(QPainter::CompositionMode_Source);
+ ctxt->setCompositeOperation(!pixmap.hasAlpha() && op == CompositeSourceOver ? CompositeCopy : op);
+ QPainter* p = ctxt->platformContext();
QTransform transform(patternTransform);
// If this would draw more than one scaled tile, we scale the pixmap first and then use the result to draw.
@@ -223,15 +221,8 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst,
return;
}
- QPainter* painter(ctxt->platformContext());
-
- QPainter::CompositionMode compositionMode = GraphicsContext::toQtCompositionMode(op);
-
- if (!image->hasAlpha() && painter->compositionMode() == QPainter::CompositionMode_SourceOver)
- compositionMode = QPainter::CompositionMode_Source;
-
- QPainter::CompositionMode lastCompositionMode = painter->compositionMode();
- painter->setCompositionMode(compositionMode);
+ CompositeOperator previousOperator = ctxt->compositeOperation();
+ ctxt->setCompositeOperation(!image->hasAlpha() && op == CompositeSourceOver ? CompositeCopy : op);
ContextShadow* shadow = ctxt->contextShadow();
if (shadow->m_type != ContextShadow::NoShadow) {
@@ -243,11 +234,9 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst,
}
}
- // Test using example site at
- // http://www.meyerweb.com/eric/css/edge/complexspiral/demo.html
- painter->drawPixmap(normalizedDst, *image, normalizedSrc);
+ ctxt->platformContext()->drawPixmap(normalizedDst, *image, normalizedSrc);
- painter->setCompositionMode(lastCompositionMode);
+ ctxt->setCompositeOperation(previousOperator);
if (imageObserver())
imageObserver()->didDraw(this);
diff --git a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp
index b881036..fab4db1 100644
--- a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp
+++ b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp
@@ -102,7 +102,7 @@ MediaPlayerPrivatePhonon::MediaPlayerPrivatePhonon(MediaPlayer* player)
// Make sure we get updates for each frame
m_videoWidget->installEventFilter(this);
- foreach (QWidget* widget, qFindChildren<QWidget*>(m_videoWidget))
+ foreach (QWidget* widget, m_videoWidget->findChildren<QWidget*>())
widget->installEventFilter(this);
connect(m_mediaObject, SIGNAL(stateChanged(Phonon::State,Phonon::State)),
diff --git a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp
index 0a4c0f6..caf9c2d 100644
--- a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp
@@ -215,7 +215,7 @@ void MediaPlayerPrivateQt::commitLoad(const String& url)
// Don't set the header if there are no cookies.
// This prevents a warning from being emitted.
if (!cookies.isEmpty())
- request.setHeader(QNetworkRequest::CookieHeader, qVariantFromValue(cookies));
+ request.setHeader(QNetworkRequest::CookieHeader, QVariant::fromValue(cookies));
// Set the refferer, but not when requesting insecure content from a secure page
QUrl documentUrl = QUrl(QString(document->documentURI()));
@@ -543,7 +543,7 @@ void MediaPlayerPrivateQt::updateStates()
m_readyState = MediaPlayer::HaveCurrentData;
} else if (currentStatus == QMediaPlayer::BufferedMedia
|| currentStatus == QMediaPlayer::EndOfMedia) {
- m_networkState = MediaPlayer::Idle;
+ m_networkState = MediaPlayer::Loaded;
m_readyState = MediaPlayer::HaveEnoughData;
} else if (currentStatus == QMediaPlayer::InvalidMedia) {
m_networkState = MediaPlayer::NetworkError;
@@ -618,6 +618,21 @@ void MediaPlayerPrivateQt::paint(GraphicsContext* context, const IntRect& rect)
m_videoScene->render(painter, QRectF(QRect(rect)), m_videoItem->sceneBoundingRect());
}
+void MediaPlayerPrivateQt::paintCurrentFrameInContext(GraphicsContext* context, const IntRect& rect)
+{
+ if (context->paintingDisabled())
+ return;
+
+ if (!m_isVisible)
+ return;
+
+ // Grab the painter and widget
+ QPainter* painter = context->platformContext();
+
+ // Render the video, using the item as it might not be in the scene
+ m_videoItem->paint(painter, 0, 0);
+}
+
void MediaPlayerPrivateQt::repaint()
{
m_webCorePlayer->repaint();
diff --git a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h
index 2621432..e4133db 100644
--- a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h
+++ b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h
@@ -89,6 +89,8 @@ public:
void setSize(const IntSize&);
void paint(GraphicsContext*, const IntRect&);
+ // reimplemented for canvas drawImage(HTMLVideoElement)
+ void paintCurrentFrameInContext(GraphicsContext*, const IntRect&);
bool supportsFullscreen() const { return true; }
diff --git a/Source/WebCore/platform/graphics/qt/PathQt.cpp b/Source/WebCore/platform/graphics/qt/PathQt.cpp
index 571b405..ad482f7 100644
--- a/Source/WebCore/platform/graphics/qt/PathQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/PathQt.cpp
@@ -39,15 +39,9 @@
#include <QPainterPath>
#include <QTransform>
#include <QString>
+#include <wtf/MathExtras.h>
#include <wtf/OwnPtr.h>
-#define _USE_MATH_DEFINES
-#include <math.h>
-
-#ifndef M_PI
-# define M_PI 3.14159265358979323846
-#endif
-
namespace WebCore {
Path::Path()
@@ -263,7 +257,6 @@ void Path::closeSubpath()
m_path.closeSubpath();
}
-#define DEGREES(t) ((t) * 180.0 / M_PI)
void Path::addArc(const FloatPoint& p, float r, float sar, float ear, bool anticlockwise)
{
qreal xc = p.x();
@@ -280,8 +273,8 @@ void Path::addArc(const FloatPoint& p, float r, float sar, float ear, bool antic
anticlockwise = !anticlockwise;
//end hack
- float sa = DEGREES(sar);
- float ea = DEGREES(ear);
+ float sa = rad2deg(sar);
+ float ea = rad2deg(ear);
double span = 0;
@@ -438,6 +431,14 @@ float Path::normalAngleAtLength(float length, bool& ok)
qreal percent = m_path.percentAtLength(length);
qreal angle = m_path.angleAtPercent(percent);
+ // Normalize angle value.
+ // QPainterPath returns angle values with the origo being at the top left corner.
+ // In case of moveTo(0, 0) and addLineTo(0, 10) the angle is 270,
+ // while the caller expects it to be 90.
+ // Normalize the value by mirroring it to the x-axis.
+ // For more info look at pathLengthApplierFunction().
+ if (angle > 0)
+ angle = 360 - angle;
return angle;
}
diff --git a/Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp b/Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp
index 47ddf02..9e43558 100644
--- a/Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp
@@ -24,7 +24,7 @@
#include "config.h"
#include "SimpleFontData.h"
-#include <QFontMetrics>
+#include <QFontMetricsF>
namespace WebCore {
@@ -41,25 +41,19 @@ bool SimpleFontData::containsCharacters(const UChar*, int) const
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;
}
- QFontMetrics fm(m_platformData.font());
-
- m_ascent = fm.ascent();
- m_descent = fm.descent();
- m_lineSpacing = fm.lineSpacing();
- m_xHeight = fm.xHeight();
+ QFontMetricsF fm(m_platformData.font());
+ m_fontMetrics.setAscent(fm.ascent());
+ m_fontMetrics.setDescent(fm.descent());
+ m_fontMetrics.setXHeight(fm.xHeight());
+ m_fontMetrics.setLineGap(fm.leading());
+ m_fontMetrics.setLineSpacing(fm.lineSpacing());
m_spaceWidth = fm.width(QLatin1Char(' '));
- m_lineGap = fm.leading();
}
void SimpleFontData::platformGlyphInit()
diff --git a/Source/WebCore/platform/graphics/qt/TransparencyLayer.h b/Source/WebCore/platform/graphics/qt/TransparencyLayer.h
index ff9ef20..f13deb0 100644
--- a/Source/WebCore/platform/graphics/qt/TransparencyLayer.h
+++ b/Source/WebCore/platform/graphics/qt/TransparencyLayer.h
@@ -59,9 +59,8 @@ public:
painter.setPen(p->pen());
painter.setBrush(p->brush());
painter.setTransform(p->transform(), true);
- painter.setOpacity(p->opacity());
painter.setFont(p->font());
- painter.setCompositionMode(p->compositionMode());
+ painter.setOpacity(1);
}
TransparencyLayer()
diff --git a/Source/WebCore/platform/graphics/skia/FloatRectSkia.cpp b/Source/WebCore/platform/graphics/skia/FloatRectSkia.cpp
index a10371f..23045ba 100644
--- a/Source/WebCore/platform/graphics/skia/FloatRectSkia.cpp
+++ b/Source/WebCore/platform/graphics/skia/FloatRectSkia.cpp
@@ -43,7 +43,7 @@ FloatRect::FloatRect(const SkRect& r)
FloatRect::operator SkRect() const
{
- SkRect rect = { x(), y(), right(), bottom() };
+ SkRect rect = { x(), y(), maxX(), maxY() };
return rect;
}
diff --git a/Source/WebCore/platform/graphics/skia/FontCustomPlatformData.cpp b/Source/WebCore/platform/graphics/skia/FontCustomPlatformData.cpp
index 0b31dfa..0e68c21 100644
--- a/Source/WebCore/platform/graphics/skia/FontCustomPlatformData.cpp
+++ b/Source/WebCore/platform/graphics/skia/FontCustomPlatformData.cpp
@@ -65,7 +65,7 @@ FontCustomPlatformData::~FontCustomPlatformData()
#endif
}
-FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation orientation, FontRenderingMode mode)
+FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation orientation, FontWidthVariant, FontRenderingMode mode)
{
#if OS(WINDOWS)
ASSERT(m_fontReference);
@@ -114,13 +114,12 @@ FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, b
// not allow access from CSS.
static String createUniqueFontName()
{
- Vector<char> fontUuid(sizeof(GUID));
- CoCreateGuid(reinterpret_cast<GUID*>(fontUuid.data()));
+ GUID fontUuid;
+ CoCreateGuid(&fontUuid);
- Vector<char> fontNameVector;
- base64Encode(fontUuid, fontNameVector);
- ASSERT(fontNameVector.size() < LF_FACESIZE);
- return String(fontNameVector.data(), fontNameVector.size());
+ String fontName = base64Encode(reinterpret_cast<char*>(&fontUuid), sizeof(fontUuid));
+ ASSERT(fontName.length() < LF_FACESIZE);
+ return fontName;
}
#endif
diff --git a/Source/WebCore/platform/graphics/skia/FontCustomPlatformData.h b/Source/WebCore/platform/graphics/skia/FontCustomPlatformData.h
index 4228b40..2dee3ab 100644
--- a/Source/WebCore/platform/graphics/skia/FontCustomPlatformData.h
+++ b/Source/WebCore/platform/graphics/skia/FontCustomPlatformData.h
@@ -34,6 +34,7 @@
#include "FontOrientation.h"
#include "FontRenderingMode.h"
+#include "FontWidthVariant.h"
#include <wtf/Forward.h>
#include <wtf/Noncopyable.h>
@@ -65,7 +66,7 @@ public:
~FontCustomPlatformData();
- FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal,
+ FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, FontWidthVariant = RegularWidth,
FontRenderingMode = NormalRenderingMode);
static bool supportsFormat(const String&);
diff --git a/Source/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp b/Source/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp
index c4b753b..5950c35 100644
--- a/Source/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp
+++ b/Source/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp
@@ -26,7 +26,7 @@
#include "config.h"
-#if ENABLE(3D_CANVAS)
+#if ENABLE(WEBGL)
#include "GraphicsContext3D.h"
@@ -87,4 +87,4 @@ bool GraphicsContext3D::getImageData(Image* image,
} // namespace WebCore
-#endif // ENABLE(3D_CANVAS)
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp b/Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
index 1a7112b..9f2ed32 100644
--- a/Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
+++ b/Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
@@ -309,20 +309,6 @@ void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness
platformContext()->clipPathAntiAliased(path);
}
-void GraphicsContext::addPath(const Path& path)
-{
- if (paintingDisabled())
- return;
- platformContext()->addPath(*path.platformPath());
-}
-
-void GraphicsContext::beginPath()
-{
- if (paintingDisabled())
- return;
- platformContext()->beginPath();
-}
-
void GraphicsContext::clearPlatformShadow()
{
if (paintingDisabled())
@@ -431,11 +417,7 @@ void GraphicsContext::clipPath(const Path& pathToClip, WindRule clipRule)
if (platformContext()->useGPU())
platformContext()->gpuCanvas()->clipPath(pathToClip);
- // FIXME: Be smarter about this.
- beginPath();
- addPath(pathToClip);
-
- SkPath path = platformContext()->currentPathInLocalCoordinates();
+ SkPath path = *pathToClip.platformPath();
if (!isPathSkiaSafe(getCTM(), path))
return;
@@ -738,17 +720,13 @@ void GraphicsContext::fillPath(const Path& pathToFill)
if (paintingDisabled())
return;
- // FIXME: Be smarter about this.
- beginPath();
- addPath(pathToFill);
-
if (platformContext()->useGPU() && platformContext()->canAccelerate()) {
platformContext()->prepareForHardwareDraw();
platformContext()->gpuCanvas()->fillPath(pathToFill);
return;
}
- SkPath path = platformContext()->currentPathInLocalCoordinates();
+ SkPath path = *pathToFill.platformPath();
if (!isPathSkiaSafe(getCTM(), path))
return;
@@ -1204,11 +1182,7 @@ void GraphicsContext::strokePath(const Path& pathToStroke)
if (paintingDisabled())
return;
- // FIXME: Be smarter about this.
- beginPath();
- addPath(pathToStroke);
-
- SkPath path = platformContext()->currentPathInLocalCoordinates();
+ SkPath path = *pathToStroke.platformPath();
if (!isPathSkiaSafe(getCTM(), path))
return;
diff --git a/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp b/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
index 2c489ef..2721523 100644
--- a/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
+++ b/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
@@ -2,11 +2,11 @@
* Copyright (c) 2008, Google Inc. All rights reserved.
* Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
* Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
- *
+ *
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
@@ -16,7 +16,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
@@ -162,12 +162,14 @@ void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookUpTable)
}
template <Multiply multiplied>
-PassRefPtr<ByteArray> getImageData(const IntRect& rect, const SkBitmap& bitmap,
+PassRefPtr<ByteArray> getImageData(const IntRect& rect, SkDevice& srcDevice,
const IntSize& size)
{
RefPtr<ByteArray> result = ByteArray::create(rect.width() * rect.height() * 4);
- if (bitmap.config() == SkBitmap::kNo_Config) {
+ SkBitmap::Config srcConfig = srcDevice.accessBitmap(false).config();
+
+ if (srcConfig == SkBitmap::kNo_Config) {
// This is an empty SkBitmap that could not be configured.
ASSERT(!size.width() || !size.height());
return result.release();
@@ -177,8 +179,8 @@ PassRefPtr<ByteArray> getImageData(const IntRect& rect, const SkBitmap& bitmap,
if (rect.x() < 0
|| rect.y() < 0
- || rect.right() > size.width()
- || rect.bottom() > size.height())
+ || rect.maxX() > size.width()
+ || rect.maxY() > size.height())
memset(data, 0, result->length());
int originX = rect.x();
@@ -187,12 +189,12 @@ PassRefPtr<ByteArray> getImageData(const IntRect& rect, const SkBitmap& bitmap,
destX = -originX;
originX = 0;
}
- int endX = rect.right();
+ int endX = rect.maxX();
if (endX > size.width())
endX = size.width();
int numColumns = endX - originX;
- if (numColumns <= 0)
+ if (numColumns <= 0)
return result.release();
int originY = rect.y();
@@ -201,38 +203,42 @@ PassRefPtr<ByteArray> getImageData(const IntRect& rect, const SkBitmap& bitmap,
destY = -originY;
originY = 0;
}
- int endY = rect.bottom();
+ int endY = rect.maxY();
if (endY > size.height())
endY = size.height();
int numRows = endY - originY;
- if (numRows <= 0)
+ if (numRows <= 0)
return result.release();
- ASSERT(bitmap.config() == SkBitmap::kARGB_8888_Config);
- SkAutoLockPixels bitmapLock(bitmap);
+ ASSERT(srcConfig == SkBitmap::kARGB_8888_Config);
unsigned destBytesPerRow = 4 * rect.width();
+
+ SkBitmap srcBitmap;
+ srcDevice.readPixels(SkIRect::MakeXYWH(originX, originY, numColumns, numRows), &srcBitmap);
+
unsigned char* destRow = data + destY * destBytesPerRow + destX * 4;
+ // Do conversion of byte order and alpha divide (if necessary)
for (int y = 0; y < numRows; ++y) {
- uint32_t* srcRow = bitmap.getAddr32(originX, originY + y);
+ SkPMColor* srcBitmapRow = srcBitmap.getAddr32(0, y);
for (int x = 0; x < numColumns; ++x) {
+ SkPMColor srcPMColor = srcBitmapRow[x];
unsigned char* destPixel = &destRow[x * 4];
if (multiplied == Unmultiplied) {
- SkColor color = srcRow[x];
- unsigned a = SkColorGetA(color);
- destPixel[0] = a ? SkColorGetR(color) * 255 / a : 0;
- destPixel[1] = a ? SkColorGetG(color) * 255 / a : 0;
- destPixel[2] = a ? SkColorGetB(color) * 255 / a : 0;
+ unsigned char a = SkGetPackedA32(srcPMColor);
+ destPixel[0] = a ? SkGetPackedR32(srcPMColor) * 255 / a : 0;
+ destPixel[1] = a ? SkGetPackedG32(srcPMColor) * 255 / a : 0;
+ destPixel[2] = a ? SkGetPackedB32(srcPMColor) * 255 / a : 0;
destPixel[3] = a;
} else {
// Input and output are both pre-multiplied, we just need to re-arrange the
// bytes from the bitmap format to RGBA.
- destPixel[0] = SkGetPackedR32(srcRow[x]);
- destPixel[1] = SkGetPackedG32(srcRow[x]);
- destPixel[2] = SkGetPackedB32(srcRow[x]);
- destPixel[3] = SkGetPackedA32(srcRow[x]);
+ destPixel[0] = SkGetPackedR32(srcPMColor);
+ destPixel[1] = SkGetPackedG32(srcPMColor);
+ destPixel[2] = SkGetPackedB32(srcPMColor);
+ destPixel[3] = SkGetPackedA32(srcPMColor);
}
}
destRow += destBytesPerRow;
@@ -244,18 +250,18 @@ PassRefPtr<ByteArray> getImageData(const IntRect& rect, const SkBitmap& bitmap,
PassRefPtr<ByteArray> ImageBuffer::getUnmultipliedImageData(const IntRect& rect) const
{
context()->platformContext()->syncSoftwareCanvas();
- return getImageData<Unmultiplied>(rect, *context()->platformContext()->bitmap(), m_size);
+ return getImageData<Unmultiplied>(rect, *context()->platformContext()->canvas()->getDevice(), m_size);
}
PassRefPtr<ByteArray> ImageBuffer::getPremultipliedImageData(const IntRect& rect) const
{
context()->platformContext()->syncSoftwareCanvas();
- return getImageData<Premultiplied>(rect, *context()->platformContext()->bitmap(), m_size);
+ return getImageData<Premultiplied>(rect, *context()->platformContext()->canvas()->getDevice(), m_size);
}
template <Multiply multiplied>
-void putImageData(ByteArray*& source, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint,
- const SkBitmap& bitmap, const IntSize& size)
+void putImageData(ByteArray*& source, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint,
+ SkDevice* dstDevice, const IntSize& size)
{
ASSERT(sourceRect.width() > 0);
ASSERT(sourceRect.height() > 0);
@@ -265,9 +271,9 @@ void putImageData(ByteArray*& source, const IntSize& sourceSize, const IntRect&
ASSERT(destX >= 0);
ASSERT(destX < size.width());
ASSERT(originX >= 0);
- ASSERT(originX < sourceRect.right());
+ ASSERT(originX < sourceRect.maxX());
- int endX = destPoint.x() + sourceRect.right();
+ int endX = destPoint.x() + sourceRect.maxX();
ASSERT(endX <= size.width());
int numColumns = endX - destX;
@@ -277,21 +283,33 @@ void putImageData(ByteArray*& source, const IntSize& sourceSize, const IntRect&
ASSERT(destY >= 0);
ASSERT(destY < size.height());
ASSERT(originY >= 0);
- ASSERT(originY < sourceRect.bottom());
+ ASSERT(originY < sourceRect.maxY());
- int endY = destPoint.y() + sourceRect.bottom();
+ int endY = destPoint.y() + sourceRect.maxY();
ASSERT(endY <= size.height());
int numRows = endY - destY;
- ASSERT(bitmap.config() == SkBitmap::kARGB_8888_Config);
- SkAutoLockPixels bitmapLock(bitmap);
-
unsigned srcBytesPerRow = 4 * sourceSize.width();
- const unsigned char* srcRow = source->data() + originY * srcBytesPerRow + originX * 4;
+ SkBitmap deviceBitmap = dstDevice->accessBitmap(true);
+ SkAutoLockPixels deviceAutoLock(deviceBitmap);
+ // If the device's bitmap doesn't have pixels we will make a temp and call writePixels on the device.
+ bool temporaryBitmap = !deviceBitmap.getPixels();
+ SkBitmap destBitmap;
+
+ if (temporaryBitmap) {
+ destBitmap.setConfig(SkBitmap::kARGB_8888_Config, numColumns, numRows, srcBytesPerRow);
+ if (!destBitmap.allocPixels())
+ CRASH();
+ } else
+ deviceBitmap.extractSubset(&destBitmap, SkIRect::MakeXYWH(destX, destY, numColumns, numRows));
+
+ // Whether we made a temporary or not destBitmap is always configured to be written at 0,0
+ SkAutoLockPixels destAutoLock(destBitmap);
+ const unsigned char* srcRow = source->data() + originY * srcBytesPerRow + originX * 4;
for (int y = 0; y < numRows; ++y) {
- uint32_t* destRow = bitmap.getAddr32(destX, destY + y);
+ SkPMColor* destRow = destBitmap.getAddr32(0, y);
for (int x = 0; x < numColumns; ++x) {
const unsigned char* srcPixel = &srcRow[x * 4];
if (multiplied == Unmultiplied) {
@@ -301,22 +319,26 @@ void putImageData(ByteArray*& source, const IntSize& sourceSize, const IntRect&
unsigned char b = SkMulDiv255Ceiling(srcPixel[2], alpha);
destRow[x] = SkPackARGB32(alpha, r, g, b);
} else
- destRow[x] = SkPackARGB32(srcPixel[3], srcPixel[0],
- srcPixel[1], srcPixel[2]);
+ destRow[x] = SkPackARGB32(srcPixel[3], srcPixel[0], srcPixel[1], srcPixel[2]);
}
srcRow += srcBytesPerRow;
}
+
+ // If we used a temporary then write it to the device
+ if (temporaryBitmap)
+ dstDevice->writePixels(destBitmap, destX, destY);
}
void ImageBuffer::putUnmultipliedImageData(ByteArray* source, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint)
{
- context()->platformContext()->prepareForSoftwareDraw();
- putImageData<Unmultiplied>(source, sourceSize, sourceRect, destPoint, *context()->platformContext()->bitmap(), m_size);
+ context()->platformContext()->syncSoftwareCanvas();
+ putImageData<Unmultiplied>(source, sourceSize, sourceRect, destPoint, context()->platformContext()->canvas()->getDevice(), m_size);
}
void ImageBuffer::putPremultipliedImageData(ByteArray* source, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint)
{
- putImageData<Premultiplied>(source, sourceSize, sourceRect, destPoint, *context()->platformContext()->bitmap(), m_size);
+ context()->platformContext()->syncSoftwareCanvas();
+ putImageData<Premultiplied>(source, sourceSize, sourceRect, destPoint, context()->platformContext()->canvas()->getDevice(), m_size);
}
String ImageBuffer::toDataURL(const String& mimeType, const double* quality) const
@@ -324,14 +346,27 @@ String ImageBuffer::toDataURL(const String& mimeType, const double* quality) con
ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType));
Vector<unsigned char> encodedImage;
+ SkDevice* device = context()->platformContext()->canvas()->getDevice();
+ SkBitmap bitmap = device->accessBitmap(false);
+
+ // if we can't see the pixels directly, call readPixels() to get a copy.
+ // this could happen if the device is backed by a GPU.
+ bitmap.lockPixels(); // balanced by our destructor, or explicitly if getPixels() fails
+ if (!bitmap.getPixels()) {
+ bitmap.unlockPixels();
+ SkIRect bounds = SkIRect::MakeWH(device->width(), device->height());
+ if (!device->readPixels(bounds, &bitmap))
+ return "data:,";
+ }
+
if (mimeType == "image/jpeg") {
int compressionQuality = JPEGImageEncoder::DefaultCompressionQuality;
if (quality && *quality >= 0.0 && *quality <= 1.0)
compressionQuality = static_cast<int>(*quality * 100 + 0.5);
- if (!JPEGImageEncoder::encode(*context()->platformContext()->bitmap(), compressionQuality, &encodedImage))
+ if (!JPEGImageEncoder::encode(bitmap, compressionQuality, &encodedImage))
return "data:,";
} else {
- if (!PNGImageEncoder::encode(*context()->platformContext()->bitmap(), &encodedImage))
+ if (!PNGImageEncoder::encode(bitmap, &encodedImage))
return "data:,";
ASSERT(mimeType == "image/png");
}
diff --git a/Source/WebCore/platform/graphics/skia/IntRectSkia.cpp b/Source/WebCore/platform/graphics/skia/IntRectSkia.cpp
index ea138ee..0024086 100644
--- a/Source/WebCore/platform/graphics/skia/IntRectSkia.cpp
+++ b/Source/WebCore/platform/graphics/skia/IntRectSkia.cpp
@@ -37,14 +37,14 @@ namespace WebCore {
IntRect::operator SkIRect() const
{
- SkIRect rect = { x(), y(), right(), bottom() };
+ SkIRect rect = { x(), y(), maxX(), maxY() };
return rect;
}
IntRect::operator SkRect() const
{
SkRect rect;
- rect.set(SkIntToScalar(x()), SkIntToScalar(y()), SkIntToScalar(right()), SkIntToScalar(bottom()));
+ rect.set(SkIntToScalar(x()), SkIntToScalar(y()), SkIntToScalar(maxX()), SkIntToScalar(maxY()));
return rect;
}
diff --git a/Source/WebCore/platform/graphics/skia/PathSkia.cpp b/Source/WebCore/platform/graphics/skia/PathSkia.cpp
index 89323c4..6318c21 100644
--- a/Source/WebCore/platform/graphics/skia/PathSkia.cpp
+++ b/Source/WebCore/platform/graphics/skia/PathSkia.cpp
@@ -227,28 +227,20 @@ void Path::transform(const AffineTransform& xform)
m_path->transform(xform);
}
-// Computes the bounding box for the stroke and style currently selected into
-// the given bounding box. This also takes into account the stroke width.
-static FloatRect boundingBoxForCurrentStroke(const GraphicsContext* context)
-{
- SkPaint paint;
- context->platformContext()->setupPaintForStroking(&paint, 0, 0);
- SkPath boundingPath;
- paint.getFillPath(context->platformContext()->currentPathInLocalCoordinates(), &boundingPath);
- return boundingPath.getBounds();
-}
-
FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier)
{
GraphicsContext* scratch = scratchContext();
scratch->save();
- scratch->beginPath();
- scratch->addPath(*this);
if (applier)
applier->strokeStyle(scratch);
- FloatRect r = boundingBoxForCurrentStroke(scratch);
+ SkPaint paint;
+ scratch->platformContext()->setupPaintForStroking(&paint, 0, 0);
+ SkPath boundingPath;
+ paint.getFillPath(*platformPath(), &boundingPath);
+
+ FloatRect r = boundingPath.getBounds();
scratch->restore();
return r;
}
diff --git a/Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp b/Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
index d852e9b..5e08b3c 100644
--- a/Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
+++ b/Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
@@ -51,6 +51,12 @@
#include "SkDashPathEffect.h"
#include "SkShader.h"
+#if ENABLE(SKIA_GPU)
+#include "GrContext.h"
+#include "SkGpuDevice.h"
+#include "SkGpuDeviceFactory.h"
+#endif
+
#include <wtf/MathExtras.h>
#include <wtf/OwnArrayPtr.h>
#include <wtf/Vector.h>
@@ -62,6 +68,18 @@
namespace WebCore {
+#if ENABLE(SKIA_GPU)
+GrContext* GetGlobalGrContext()
+{
+ static GrContext* gGR;
+ if (!gGR) {
+ gGR = GrContext::CreateGLShaderContext();
+ gGR->setTextureCacheLimits(512, 50 * 1024 * 1024);
+ }
+ return gGR;
+}
+#endif
+
extern bool isPathSkiaSafe(const SkMatrix& transform, const SkPath& path);
// State -----------------------------------------------------------------------
@@ -266,7 +284,7 @@ void PlatformContextSkia::beginLayerClippedToImage(const FloatRect& rect,
// create the resulting image.
m_state->m_clip = rect;
SkRect bounds = { SkFloatToScalar(rect.x()), SkFloatToScalar(rect.y()),
- SkFloatToScalar(rect.right()), SkFloatToScalar(rect.bottom()) };
+ SkFloatToScalar(rect.maxX()), SkFloatToScalar(rect.maxY()) };
canvas()->clipRect(bounds);
canvas()->saveLayerAlpha(&bounds, 255,
@@ -550,38 +568,12 @@ SkColor PlatformContextSkia::effectiveStrokeColor() const
return m_state->applyAlpha(m_state->m_strokeColor);
}
-void PlatformContextSkia::beginPath()
-{
- m_path.reset();
-}
-
-void PlatformContextSkia::addPath(const SkPath& path)
-{
- m_path.addPath(path, m_canvas->getTotalMatrix());
-}
-
-SkPath PlatformContextSkia::currentPathInLocalCoordinates() const
-{
- SkPath localPath = m_path;
- const SkMatrix& matrix = m_canvas->getTotalMatrix();
- SkMatrix inverseMatrix;
- if (!matrix.invert(&inverseMatrix))
- return SkPath();
- localPath.transform(inverseMatrix);
- return localPath;
-}
-
void PlatformContextSkia::canvasClipPath(const SkPath& path)
{
m_state->m_canvasClipApplied = true;
m_canvas->clipPath(path);
}
-void PlatformContextSkia::setFillRule(SkPath::FillType fr)
-{
- m_path.setFillType(fr);
-}
-
void PlatformContextSkia::setFillShader(SkShader* fillShader)
{
if (fillShader)
@@ -625,7 +617,11 @@ const SkBitmap* PlatformContextSkia::bitmap() const
bool PlatformContextSkia::isPrinting()
{
+#if ENABLE(SKIA_GPU)
+ return true;
+#else
return m_canvas->getTopPlatformDevice().IsVectorial();
+#endif
}
void PlatformContextSkia::getImageResamplingHint(IntSize* srcSize, FloatSize* dstSize) const
@@ -739,6 +735,19 @@ void PlatformContextSkia::setSharedGraphicsContext3D(SharedGraphicsContext3D* co
m_gpuCanvas = new GLES2Canvas(context, drawingBuffer, size);
m_uploadTexture.clear();
drawingBuffer->setWillPublishCallback(WillPublishCallbackImpl::create(this));
+
+#if ENABLE(SKIA_GPU)
+ m_useGPU = false;
+ context->makeContextCurrent();
+ m_gpuCanvas->bindFramebuffer();
+
+ GrContext* gr = GetGlobalGrContext();
+ gr->resetContext();
+ SkDeviceFactory* factory = new SkGpuDeviceFactory(gr, SkGpuDevice::Current3DApiRenderTarget());
+ SkDevice* device = factory->newDevice(m_canvas, SkBitmap::kARGB_8888_Config, drawingBuffer->size().width(), drawingBuffer->size().height(), false, false);
+ m_canvas->setDevice(device)->unref();
+ m_canvas->setDeviceFactory(factory);
+#endif
} else {
syncSoftwareCanvas();
m_uploadTexture.clear();
@@ -750,8 +759,13 @@ void PlatformContextSkia::setSharedGraphicsContext3D(SharedGraphicsContext3D* co
void PlatformContextSkia::prepareForSoftwareDraw() const
{
- if (!m_useGPU)
+ if (!m_useGPU) {
+#if ENABLE(SKIA_GPU)
+ if (m_gpuCanvas)
+ m_gpuCanvas->context()->makeContextCurrent();
+#endif
return;
+ }
if (m_backingStoreState == Hardware) {
// Depending on the blend mode we need to do one of a few things:
@@ -804,8 +818,13 @@ void PlatformContextSkia::prepareForHardwareDraw() const
void PlatformContextSkia::syncSoftwareCanvas() const
{
- if (!m_useGPU)
+ if (!m_useGPU) {
+#if ENABLE(SKIA_GPU)
+ if (m_gpuCanvas)
+ m_gpuCanvas->bindFramebuffer();
+#endif
return;
+ }
if (m_backingStoreState == Hardware)
readbackHardwareToSoftware();
@@ -865,7 +884,7 @@ void PlatformContextSkia::readbackHardwareToSoftware() const
const SkBitmap& bitmap = m_canvas->getDevice()->accessBitmap(true);
SkAutoLockPixels lock(bitmap);
int width = bitmap.width(), height = bitmap.height();
- OwnArrayPtr<uint32_t> buf(new uint32_t[width]);
+ OwnArrayPtr<uint32_t> buf = adoptArrayPtr(new uint32_t[width]);
SharedGraphicsContext3D* context = m_gpuCanvas->context();
m_gpuCanvas->bindFramebuffer();
// Flips the image vertically.
diff --git a/Source/WebCore/platform/graphics/skia/PlatformContextSkia.h b/Source/WebCore/platform/graphics/skia/PlatformContextSkia.h
index 0304486..d7dd6a9 100644
--- a/Source/WebCore/platform/graphics/skia/PlatformContextSkia.h
+++ b/Source/WebCore/platform/graphics/skia/PlatformContextSkia.h
@@ -118,7 +118,6 @@ public:
void setAlpha(float);
void setLineCap(SkPaint::Cap);
void setLineJoin(SkPaint::Join);
- void setFillRule(SkPath::FillType);
void setXfermodeMode(SkXfermode::Mode);
void setFillColor(SkColor);
void setFillShader(SkShader*);
@@ -137,10 +136,6 @@ public:
float getAlpha() const;
int getNormalizedAlpha() const;
- void beginPath();
- void addPath(const SkPath&);
- SkPath currentPathInLocalCoordinates() const;
-
void canvasClipPath(const SkPath&);
// Returns the fill color. The returned color has it's alpha adjusted
@@ -220,9 +215,6 @@ private:
// mStateStack.back().
State* m_state;
- // Current path in global coordinates.
- SkPath m_path;
-
// Stores image sizes for a hint to compute image resampling modes.
// Values are used in ImageSkia.cpp
IntSize m_imageResamplingHintSrcSize;
diff --git a/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h b/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h
index 85fa3ee..47a27c6 100644
--- a/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h
+++ b/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h
@@ -26,7 +26,7 @@
#include "Image.h"
#include "TextureMapperNode.h"
-#if ENABLE(3D_CANVAS)
+#if ENABLE(WEBGL)
#include "GraphicsContext3D.h"
#endif
@@ -73,7 +73,7 @@ public:
virtual void setContentsToImage(Image*);
virtual void setContentsToMedia(PlatformLayer*);
virtual void setContentsBackgroundColor(const Color&);
-#if ENABLE(3D_CANVAS)
+#if ENABLE(WEBGL)
virtual void setContentsToGraphicsContext3D(const GraphicsContext3D*);
virtual void setGraphicsContext3DNeedsDisplay();
#endif
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperNode.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapperNode.cpp
index 09051f9..bf53e61 100644
--- a/Source/WebCore/platform/graphics/texmap/TextureMapperNode.cpp
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapperNode.cpp
@@ -318,7 +318,7 @@ void TextureMapperNode::computeLocalTransform()
m_transforms.local =
TransformationMatrix()
.translate3d(originX + m_state.pos.x(), originY + m_state.pos.y(), m_state.anchorPoint.z())
- .multLeft(m_state.transform)
+ .multiply(m_state.transform)
.translate3d(-originX, -originY, -m_state.anchorPoint.z());
m_transforms.localDirty = false;
}
@@ -352,7 +352,7 @@ void TextureMapperNode::computeReplicaTransform()
m_nearestSurfaceSize = nearestSurfaceSize();
if (m_layerType != TransparencyLayer) {
- m_transforms.replica = TransformationMatrix(m_transforms.target).multLeft(m_state.replicaLayer->m_transforms.local);
+ m_transforms.replica = TransformationMatrix(m_transforms.target).multiply(m_state.replicaLayer->m_transforms.local);
return;
}
@@ -361,7 +361,7 @@ void TextureMapperNode::computeReplicaTransform()
m_transforms.replica =
TransformationMatrix()
.translate(originX, originY)
- .multLeft(m_state.replicaLayer->m_transforms.local)
+ .multiply(m_state.replicaLayer->m_transforms.local)
.translate(-originX, -originY);
}
@@ -377,7 +377,7 @@ void TextureMapperNode::computeTransformations()
TextureMapperNode* parent = m_parent;
computeLocalTransform();
- m_transforms.target = TransformationMatrix(parent ? parent->m_transforms.forDescendants : TransformationMatrix()).multLeft(m_transforms.local);
+ m_transforms.target = TransformationMatrix(parent ? parent->m_transforms.forDescendants : TransformationMatrix()).multiply(m_transforms.local);
m_transforms.forDescendants = (m_layerType == ClipLayer ? TransformationMatrix() : m_transforms.target);
if (m_effectTarget)
@@ -408,10 +408,10 @@ void TextureMapperNode::computeTransformations()
if (m_transforms.perspectiveDirty)
m_transforms.perspective = TransformationMatrix()
.translate(centerPoint.x(), centerPoint.y())
- .multLeft(m_state.childrenTransform)
+ .multiply(m_state.childrenTransform)
.translate(-centerPoint.x(), -centerPoint.y());
m_transforms.perspectiveDirty = false;
- m_transforms.forDescendants.multLeft(m_transforms.perspective);
+ m_transforms.forDescendants.multiply(m_transforms.perspective);
}
void TextureMapperNode::uploadTextureFromContent(TextureMapper* textureMapper, const IntRect& visibleRect, GraphicsLayer* layer)
diff --git a/Source/WebCore/platform/graphics/transforms/AffineTransform.cpp b/Source/WebCore/platform/graphics/transforms/AffineTransform.cpp
index 3f88140..a1ffa30 100644
--- a/Source/WebCore/platform/graphics/transforms/AffineTransform.cpp
+++ b/Source/WebCore/platform/graphics/transforms/AffineTransform.cpp
@@ -222,14 +222,6 @@ AffineTransform& AffineTransform::translate(double tx, double ty)
return *this;
}
-// *this = translation * *this
-AffineTransform& AffineTransform::translateRight(double tx, double ty)
-{
- m_transform[4] += tx;
- m_transform[5] += ty;
- return *this;
-}
-
AffineTransform& AffineTransform::scaleNonUniform(double sx, double sy)
{
return scale(sx, sy);
@@ -324,9 +316,9 @@ FloatRect AffineTransform::mapRect(const FloatRect& rect) const
FloatQuad result;
result.setP1(mapPoint(rect.location()));
- result.setP2(mapPoint(FloatPoint(rect.right(), rect.y())));
- result.setP3(mapPoint(FloatPoint(rect.right(), rect.bottom())));
- result.setP4(mapPoint(FloatPoint(rect.x(), rect.bottom())));
+ result.setP2(mapPoint(FloatPoint(rect.maxX(), rect.y())));
+ result.setP3(mapPoint(FloatPoint(rect.maxX(), rect.maxY())));
+ result.setP4(mapPoint(FloatPoint(rect.x(), rect.maxY())));
return result.boundingBox();
}
diff --git a/Source/WebCore/platform/graphics/transforms/AffineTransform.h b/Source/WebCore/platform/graphics/transforms/AffineTransform.h
index 50d0655..3e3995f 100644
--- a/Source/WebCore/platform/graphics/transforms/AffineTransform.h
+++ b/Source/WebCore/platform/graphics/transforms/AffineTransform.h
@@ -103,7 +103,6 @@ public:
AffineTransform& rotate(double d);
AffineTransform& rotateFromVector(double x, double y);
AffineTransform& translate(double tx, double ty);
- AffineTransform& translateRight(double tx, double ty);
AffineTransform& shear(double sx, double sy);
AffineTransform& flipX();
AffineTransform& flipY();
@@ -172,6 +171,11 @@ public:
operator wxGraphicsMatrix() const;
#endif
+ static AffineTransform translation(double x, double y)
+ {
+ return AffineTransform(1, 0, 0, 1, x, y);
+ }
+
private:
void setMatrix(const Transform m)
{
diff --git a/Source/WebCore/platform/graphics/transforms/Matrix3DTransformOperation.h b/Source/WebCore/platform/graphics/transforms/Matrix3DTransformOperation.h
index 0a0aaf0..dd5dae2 100644
--- a/Source/WebCore/platform/graphics/transforms/Matrix3DTransformOperation.h
+++ b/Source/WebCore/platform/graphics/transforms/Matrix3DTransformOperation.h
@@ -55,7 +55,7 @@ private:
virtual bool apply(TransformationMatrix& transform, const IntSize&) const
{
- transform.multLeft(TransformationMatrix(m_matrix));
+ transform.multiply(TransformationMatrix(m_matrix));
return false;
}
diff --git a/Source/WebCore/platform/graphics/transforms/MatrixTransformOperation.h b/Source/WebCore/platform/graphics/transforms/MatrixTransformOperation.h
index fd9b27e..6f4e725 100644
--- a/Source/WebCore/platform/graphics/transforms/MatrixTransformOperation.h
+++ b/Source/WebCore/platform/graphics/transforms/MatrixTransformOperation.h
@@ -62,7 +62,7 @@ private:
virtual bool apply(TransformationMatrix& transform, const IntSize&) const
{
TransformationMatrix matrix(m_a, m_b, m_c, m_d, m_e, m_f);
- transform.multLeft(TransformationMatrix(matrix));
+ transform.multiply(matrix);
return false;
}
diff --git a/Source/WebCore/platform/graphics/transforms/PerspectiveTransformOperation.cpp b/Source/WebCore/platform/graphics/transforms/PerspectiveTransformOperation.cpp
index 9fd03a1..18bfe37 100644
--- a/Source/WebCore/platform/graphics/transforms/PerspectiveTransformOperation.cpp
+++ b/Source/WebCore/platform/graphics/transforms/PerspectiveTransformOperation.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#include "PerspectiveTransformOperation.h"
-#include <algorithm>
+#include <wtf/MathExtras.h>
using namespace std;
@@ -37,22 +37,29 @@ PassRefPtr<TransformOperation> PerspectiveTransformOperation::blend(const Transf
if (from && !from->isSameType(*this))
return this;
- if (blendToIdentity)
- return PerspectiveTransformOperation::create(m_p + (1. - m_p) * progress);
+ if (blendToIdentity) {
+ double p = m_p.calcFloatValue(1);
+ p = p + (1. - p) * progress; // FIXME: this seems wrong. https://bugs.webkit.org/show_bug.cgi?id=52700
+ return PerspectiveTransformOperation::create(Length(clampToPositiveInteger(p), Fixed));
+ }
const PerspectiveTransformOperation* fromOp = static_cast<const PerspectiveTransformOperation*>(from);
- double fromP = fromOp ? fromOp->m_p : 0;
- double toP = m_p;
+ Length fromP = fromOp ? fromOp->m_p : Length(m_p.type());
+ Length toP = m_p;
TransformationMatrix fromT;
TransformationMatrix toT;
- fromT.applyPerspective(fromP);
- toT.applyPerspective(toP);
+ fromT.applyPerspective(fromP.calcFloatValue(1));
+ toT.applyPerspective(toP.calcFloatValue(1));
toT.blend(fromT, progress);
TransformationMatrix::DecomposedType decomp;
toT.decompose(decomp);
-
- return PerspectiveTransformOperation::create(decomp.perspectiveZ ? -1.0 / decomp.perspectiveZ : 0.0);
+
+ if (decomp.perspectiveZ) {
+ double val = -1.0 / decomp.perspectiveZ;
+ return PerspectiveTransformOperation::create(Length(clampToPositiveInteger(val), Fixed));
+ }
+ return PerspectiveTransformOperation::create(Length(0, Fixed));
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/transforms/PerspectiveTransformOperation.h b/Source/WebCore/platform/graphics/transforms/PerspectiveTransformOperation.h
index 834cc83..886d3dc 100644
--- a/Source/WebCore/platform/graphics/transforms/PerspectiveTransformOperation.h
+++ b/Source/WebCore/platform/graphics/transforms/PerspectiveTransformOperation.h
@@ -26,21 +26,22 @@
#ifndef PerspectiveTransformOperation_h
#define PerspectiveTransformOperation_h
+#include "Length.h"
#include "TransformOperation.h"
namespace WebCore {
class PerspectiveTransformOperation : public TransformOperation {
public:
- static PassRefPtr<PerspectiveTransformOperation> create(double p)
+ static PassRefPtr<PerspectiveTransformOperation> create(const Length& p)
{
return adoptRef(new PerspectiveTransformOperation(p));
}
- double perspective() const { return m_p; }
+ Length perspective() const { return m_p; }
private:
- virtual bool isIdentity() const { return m_p == 0; }
+ virtual bool isIdentity() const { return m_p.calcFloatValue(1) == 0; }
virtual OperationType getOperationType() const { return PERSPECTIVE; }
virtual bool isSameType(const TransformOperation& o) const { return o.getOperationType() == PERSPECTIVE; }
@@ -54,18 +55,19 @@ private:
virtual bool apply(TransformationMatrix& transform, const IntSize&) const
{
- transform.applyPerspective(m_p);
+ transform.applyPerspective(m_p.calcFloatValue(1));
return false;
}
virtual PassRefPtr<TransformOperation> blend(const TransformOperation* from, double progress, bool blendToIdentity = false);
- PerspectiveTransformOperation(double p)
+ PerspectiveTransformOperation(const Length& p)
: m_p(p)
{
+ ASSERT(p.isFixed());
}
- double m_p;
+ Length m_p;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp b/Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp
index 357a140..c7283a5 100644
--- a/Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp
+++ b/Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp
@@ -55,21 +55,17 @@ namespace WebCore {
// webmasters - are to be held responsible. Basically, don't be a jerk, and remember that anything free comes
// with no guarantee.
-// A Note About row-major vs. column major matrixes
+// A clarification about the storage of matrix elements
//
-// The clients of this class (CSSMatrix and SVGMatrix) assume a column-major ordering.
-// That means that when the matrix is initialized with 16 values, the first 4 values
-// go in the 4 rows of the first column, etc. And in the dereferencing calls, the first
-// digit is the column (e.g., m23() is column 2 row 3). Because C++ uses row-major arrays
-// the internal matrix is stored in row-major order, so m[2][0] means row 2, column 0. This
-// has no bearing on how the matrix is viewed on the outside, since all access is done
-// with function calls. But it does help make the code more clear if you know that.
+// This class uses a 2 dimensional array internally to store the elements of the matrix. The first index into
+// the array refers to the column that the element lies in; the second index refers to the row.
//
-// FIXME: Multiply calls are named for what they do in the internal, row-major world.
-// multLeft is actually a multRight in a column-major world, and multiply is a multLeft
-// in a column-major world. For now I've left it that way to avoid too many confusing
-// changes to the code. In particular AffineTransform uses these same terms for the
-// opposite operations. So we have to be VERY careful when we change them.
+// In other words, this is the layout of the matrix:
+//
+// | m_matrix[0][0] m_matrix[1][0] m_matrix[2][0] m_matrix[3][0] |
+// | m_matrix[0][1] m_matrix[1][1] m_matrix[2][1] m_matrix[3][1] |
+// | m_matrix[0][2] m_matrix[1][2] m_matrix[2][2] m_matrix[3][2] |
+// | m_matrix[0][3] m_matrix[1][3] m_matrix[2][3] m_matrix[3][3] |
typedef double Vector4[4];
typedef double Vector3[3];
@@ -634,7 +630,7 @@ TransformationMatrix& TransformationMatrix::scaleNonUniform(double sx, double sy
mat.m_matrix[0][0] = sx;
mat.m_matrix[1][1] = sy;
- multLeft(mat);
+ multiply(mat);
return *this;
}
@@ -645,7 +641,7 @@ TransformationMatrix& TransformationMatrix::scale3d(double sx, double sy, double
mat.m_matrix[1][1] = sy;
mat.m_matrix[2][2] = sz;
- multLeft(mat);
+ multiply(mat);
return *this;
}
@@ -732,7 +728,7 @@ TransformationMatrix& TransformationMatrix::rotate3d(double x, double y, double
mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0f;
mat.m_matrix[3][3] = 1.0f;
}
- multLeft(mat);
+ multiply(mat);
return *this;
}
@@ -783,7 +779,7 @@ TransformationMatrix& TransformationMatrix::rotate3d(double rx, double ry, doubl
mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0f;
mat.m_matrix[3][3] = 1.0f;
- rmat.multLeft(mat);
+ rmat.multiply(mat);
rx /= 2.0f;
sinA = sin(rx);
@@ -803,9 +799,9 @@ TransformationMatrix& TransformationMatrix::rotate3d(double rx, double ry, doubl
mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0f;
mat.m_matrix[3][3] = 1.0f;
- rmat.multLeft(mat);
+ rmat.multiply(mat);
- multLeft(rmat);
+ multiply(rmat);
return *this;
}
@@ -869,7 +865,7 @@ TransformationMatrix& TransformationMatrix::skew(double sx, double sy)
mat.m_matrix[0][1] = tan(sy); // note that the y shear goes in the first row
mat.m_matrix[1][0] = tan(sx); // and the x shear in the second row
- multLeft(mat);
+ multiply(mat);
return *this;
}
@@ -879,7 +875,7 @@ TransformationMatrix& TransformationMatrix::applyPerspective(double p)
if (p != 0)
mat.m_matrix[2][3] = -1/p;
- multLeft(mat);
+ multiply(mat);
return *this;
}
@@ -896,7 +892,7 @@ TransformationMatrix TransformationMatrix::rectToRect(const FloatRect& from, con
//
// *this = mat * *this
//
-TransformationMatrix& TransformationMatrix::multLeft(const TransformationMatrix& mat)
+TransformationMatrix& TransformationMatrix::multiply(const TransformationMatrix& mat)
{
Matrix4 tmp;
@@ -1105,25 +1101,25 @@ void TransformationMatrix::recompose(const DecomposedType& decomp)
2 * (xz - yw), 2 * (yz + xw), 1 - 2 * (xx + yy), 0,
0, 0, 0, 1);
- multLeft(rotationMatrix);
+ multiply(rotationMatrix);
// now apply skew
if (decomp.skewYZ) {
TransformationMatrix tmp;
tmp.setM32((float) decomp.skewYZ);
- multLeft(tmp);
+ multiply(tmp);
}
if (decomp.skewXZ) {
TransformationMatrix tmp;
tmp.setM31((float) decomp.skewXZ);
- multLeft(tmp);
+ multiply(tmp);
}
if (decomp.skewXY) {
TransformationMatrix tmp;
tmp.setM21((float) decomp.skewXY);
- multLeft(tmp);
+ multiply(tmp);
}
// finally, apply scale
diff --git a/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h b/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h
index c883675..fa27c0e 100644
--- a/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h
+++ b/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h
@@ -208,11 +208,8 @@ public:
void setF(double f) { m_matrix[3][1] = f; }
// this = this * mat
- TransformationMatrix& multiply(const TransformationMatrix& t) { return *this *= t; }
+ TransformationMatrix& multiply(const TransformationMatrix&);
- // this = mat * this
- TransformationMatrix& multLeft(const TransformationMatrix& mat);
-
TransformationMatrix& scale(double);
TransformationMatrix& scaleNonUniform(double sx, double sy);
TransformationMatrix& scale3d(double sx, double sy, double sz);
@@ -296,19 +293,18 @@ public:
}
bool operator!=(const TransformationMatrix& other) const { return !(*this == other); }
-
- // *this = *this * t (i.e., a multRight)
+
+ // *this = *this * t
TransformationMatrix& operator*=(const TransformationMatrix& t)
{
- *this = *this * t;
- return *this;
+ return multiply(t);
}
- // result = *this * t (i.e., a multRight)
+ // result = *this * t
TransformationMatrix operator*(const TransformationMatrix& t) const
{
- TransformationMatrix result = t;
- result.multLeft(*this);
+ TransformationMatrix result = *this;
+ result.multiply(t);
return result;
}
diff --git a/Source/WebCore/platform/graphics/win/FontCGWin.cpp b/Source/WebCore/platform/graphics/win/FontCGWin.cpp
index 8012722..fe26c43 100644
--- a/Source/WebCore/platform/graphics/win/FontCGWin.cpp
+++ b/Source/WebCore/platform/graphics/win/FontCGWin.cpp
@@ -167,8 +167,12 @@ static void drawGDIGlyphs(GraphicsContext* graphicsContext, const SimpleFontData
drawIntoBitmap = true;
// We put slop into this rect, since glyphs can overflow the ascent/descent bounds and the left/right edges.
// FIXME: Can get glyphs' optical bounds (even from CG) to get this right.
- int lineGap = font->lineGap();
- textRect = IntRect(point.x() - (font->ascent() + font->descent()) / 2, point.y() - font->ascent() - lineGap, totalWidth + font->ascent() + font->descent(), font->lineSpacing());
+ const FontMetrics& fontMetrics = font->fontMetrics();
+ int lineGap = fontMetrics.lineGap();
+ textRect = IntRect(point.x() - (fontMetrics.ascent() + fontMetrics.descent()) / 2,
+ point.y() - fontMetrics.ascent() - lineGap,
+ totalWidth + fontMetrics.ascent() + fontMetrics.descent(),
+ fontMetrics.lineSpacing());
bitmap.set(graphicsContext->createWindowsBitmap(textRect.size()));
memset(bitmap->buffer(), 255, bitmap->bufferLength());
hdc = bitmap->hdc();
@@ -288,7 +292,7 @@ static void drawGDIGlyphs(GraphicsContext* graphicsContext, const SimpleFontData
buffer[i + 2] = fillColor.red();
buffer[i + 3] = alpha;
}
- graphicsContext->drawWindowsBitmap(bitmap.get(), textRect.topLeft());
+ graphicsContext->drawWindowsBitmap(bitmap.get(), textRect.location());
} else
graphicsContext->releaseWindowsContext(hdc, textRect, true, false);
}
diff --git a/Source/WebCore/platform/graphics/win/FontCustomPlatformData.cpp b/Source/WebCore/platform/graphics/win/FontCustomPlatformData.cpp
index 9cae99b..4aee6cd 100644
--- a/Source/WebCore/platform/graphics/win/FontCustomPlatformData.cpp
+++ b/Source/WebCore/platform/graphics/win/FontCustomPlatformData.cpp
@@ -59,7 +59,7 @@ FontCustomPlatformData::~FontCustomPlatformData()
}
}
-FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, FontRenderingMode renderingMode)
+FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, FontWidthVariant, FontRenderingMode renderingMode)
{
ASSERT(m_fontReference);
ASSERT(T2embedLibrary());
@@ -154,13 +154,12 @@ static unsigned long WINAPIV readEmbedProc(void* stream, void* buffer, unsigned
// not allow access from CSS.
static String createUniqueFontName()
{
- Vector<char> fontUuid(sizeof(GUID));
- CoCreateGuid(reinterpret_cast<GUID*>(fontUuid.data()));
+ GUID fontUuid;
+ CoCreateGuid(&fontUuid);
- Vector<char> fontNameVector;
- base64Encode(fontUuid, fontNameVector);
- ASSERT(fontNameVector.size() < LF_FACESIZE);
- return String(fontNameVector.data(), fontNameVector.size());
+ String fontName = base64Encode(reinterpret_cast<char*>(&fontUuid), sizeof(fontUuid));
+ ASSERT(fontName.length() < LF_FACESIZE);
+ return fontName;
}
FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
diff --git a/Source/WebCore/platform/graphics/win/FontCustomPlatformData.h b/Source/WebCore/platform/graphics/win/FontCustomPlatformData.h
index de33c63..abdb356 100644
--- a/Source/WebCore/platform/graphics/win/FontCustomPlatformData.h
+++ b/Source/WebCore/platform/graphics/win/FontCustomPlatformData.h
@@ -23,6 +23,7 @@
#include "FontOrientation.h"
#include "FontRenderingMode.h"
+#include "FontWidthVariant.h"
#include "PlatformString.h"
#include <wtf/Forward.h>
#include <wtf/Noncopyable.h>
@@ -45,7 +46,7 @@ public:
~FontCustomPlatformData();
- FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, FontRenderingMode = NormalRenderingMode);
+ FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, FontWidthVariant = RegularWidth, FontRenderingMode = NormalRenderingMode);
static bool supportsFormat(const String&);
diff --git a/Source/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.cpp b/Source/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.cpp
index c3decbf..fd30a6d 100644
--- a/Source/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.cpp
+++ b/Source/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, FontOrientation)
+FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, FontWidthVariant)
{
return FontPlatformData(m_fontFace, size, bold, italic);
}
diff --git a/Source/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.h b/Source/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.h
index 9c67037..ea3ae38 100644
--- a/Source/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.h
+++ b/Source/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.h
@@ -42,7 +42,7 @@ public:
}
~FontCustomPlatformData();
- FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal);
+ FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, FontWidthVariant = RegularWidth);
static bool supportsFormat(const String&);
diff --git a/Source/WebCore/platform/graphics/win/FontWin.cpp b/Source/WebCore/platform/graphics/win/FontWin.cpp
index 2ed9eb3..47c44bc 100644
--- a/Source/WebCore/platform/graphics/win/FontWin.cpp
+++ b/Source/WebCore/platform/graphics/win/FontWin.cpp
@@ -45,6 +45,11 @@ bool Font::canReturnFallbackFontsForComplexText()
return true;
}
+bool Font::canExpandAroundIdeographsInComplexText()
+{
+ return false;
+}
+
FloatRect Font::selectionRectForComplexText(const TextRun& run, const FloatPoint& point, int h,
int from, int to) const
{
@@ -122,8 +127,8 @@ float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFon
UniscribeController controller(this, run, fallbackFonts);
controller.advance(run.length());
if (glyphOverflow) {
- glyphOverflow->top = max<int>(glyphOverflow->top, ceilf(-controller.minGlyphBoundingBoxY()) - ascent());
- glyphOverflow->bottom = max<int>(glyphOverflow->bottom, ceilf(controller.maxGlyphBoundingBoxY()) - descent());
+ glyphOverflow->top = max<int>(glyphOverflow->top, ceilf(-controller.minGlyphBoundingBoxY()) - fontMetrics().ascent());
+ glyphOverflow->bottom = max<int>(glyphOverflow->bottom, ceilf(controller.maxGlyphBoundingBoxY()) - fontMetrics().descent());
glyphOverflow->left = max<int>(0, ceilf(-controller.minGlyphBoundingBoxX()));
glyphOverflow->right = max<int>(0, ceilf(controller.maxGlyphBoundingBoxX() - controller.runWidthSoFar()));
}
diff --git a/Source/WebCore/platform/graphics/win/GraphicsContextWin.cpp b/Source/WebCore/platform/graphics/win/GraphicsContextWin.cpp
index f1953e4..bb22024 100644
--- a/Source/WebCore/platform/graphics/win/GraphicsContextWin.cpp
+++ b/Source/WebCore/platform/graphics/win/GraphicsContextWin.cpp
@@ -154,7 +154,7 @@ void GraphicsContextPlatformPrivate::clip(const FloatRect& clipRect)
{
if (!m_hdc)
return;
- IntersectClipRect(m_hdc, clipRect.x(), clipRect.y(), clipRect.right(), clipRect.bottom());
+ IntersectClipRect(m_hdc, clipRect.x(), clipRect.y(), clipRect.maxX(), clipRect.maxY());
}
void GraphicsContextPlatformPrivate::clip(const Path&)
diff --git a/Source/WebCore/platform/graphics/win/IconWin.cpp b/Source/WebCore/platform/graphics/win/IconWin.cpp
index 4d4d219..7e03362 100644
--- a/Source/WebCore/platform/graphics/win/IconWin.cpp
+++ b/Source/WebCore/platform/graphics/win/IconWin.cpp
@@ -25,7 +25,6 @@
#include "GraphicsContext.h"
#include "LocalWindowsContext.h"
#include "PlatformString.h"
-#include <tchar.h>
#include <windows.h>
#if OS(WINCE)
@@ -68,16 +67,16 @@ PassRefPtr<Icon> Icon::createIconForFiles(const Vector<String>& filenames)
#if OS(WINCE)
return 0;
#else
- TCHAR buffer[MAX_PATH];
- UINT length = ::GetSystemDirectory(buffer, WTF_ARRAY_LENGTH(buffer));
+ WCHAR buffer[MAX_PATH];
+ UINT length = ::GetSystemDirectoryW(buffer, WTF_ARRAY_LENGTH(buffer));
if (!length)
return 0;
-
- if (_tcscat_s(buffer, TEXT("\\shell32.dll")))
+
+ if (wcscat_s(buffer, L"\\shell32.dll"))
return 0;
HICON hIcon;
- if (!::ExtractIconEx(buffer, shell32MultipleFileIconIndex, 0, &hIcon, 1))
+ if (!::ExtractIconExW(buffer, shell32MultipleFileIconIndex, 0, &hIcon, 1))
return 0;
return adoptRef(new Icon(hIcon));
#endif
diff --git a/Source/WebCore/platform/graphics/win/IntRectWin.cpp b/Source/WebCore/platform/graphics/win/IntRectWin.cpp
index fe25a7f..6af6735 100644
--- a/Source/WebCore/platform/graphics/win/IntRectWin.cpp
+++ b/Source/WebCore/platform/graphics/win/IntRectWin.cpp
@@ -38,7 +38,7 @@ IntRect::IntRect(const RECT& r)
IntRect::operator RECT() const
{
- RECT rect = { x(), y(), right(), bottom() };
+ RECT rect = { x(), y(), maxX(), maxY() };
return rect;
}
diff --git a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateFullscreenWindow.cpp b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateFullscreenWindow.cpp
index 01db7f2..dd3cd32 100644
--- a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateFullscreenWindow.cpp
+++ b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateFullscreenWindow.cpp
@@ -34,6 +34,11 @@
#include <CoreGraphics/CGColor.h>
#endif
+#if USE(ACCELERATED_COMPOSITING)
+#include "CACFLayerTreeHost.h"
+#include "PlatformCALayer.h"
+#endif
+
namespace WebCore {
MediaPlayerPrivateFullscreenWindow::MediaPlayerPrivateFullscreenWindow(MediaPlayerPrivateFullscreenClient* client)
@@ -47,8 +52,11 @@ MediaPlayerPrivateFullscreenWindow::MediaPlayerPrivateFullscreenWindow(MediaPlay
MediaPlayerPrivateFullscreenWindow::~MediaPlayerPrivateFullscreenWindow()
{
- if (m_hwnd)
- close();
+ if (!m_hwnd)
+ return;
+
+ ::DestroyWindow(m_hwnd);
+ ASSERT(!m_hwnd);
}
void MediaPlayerPrivateFullscreenWindow::createWindow(HWND parentHwnd)
@@ -65,8 +73,7 @@ void MediaPlayerPrivateFullscreenWindow::createWindow(HWND parentHwnd)
windowAtom = ::RegisterClassEx(&wcex);
}
- if (m_hwnd)
- close();
+ ASSERT(!m_hwnd);
MONITORINFO mi = {0};
mi.cbSize = sizeof(MONITORINFO);
@@ -87,12 +94,6 @@ void MediaPlayerPrivateFullscreenWindow::createWindow(HWND parentHwnd)
::SetFocus(m_hwnd);
}
-void MediaPlayerPrivateFullscreenWindow::close()
-{
- ::DestroyWindow(m_hwnd);
- ASSERT(!m_hwnd);
-}
-
#if USE(ACCELERATED_COMPOSITING)
void MediaPlayerPrivateFullscreenWindow::setRootChildLayer(PassRefPtr<PlatformCALayer> rootChild)
{
diff --git a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateFullscreenWindow.h b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateFullscreenWindow.h
index c1ae762..e07bbac 100644
--- a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateFullscreenWindow.h
+++ b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateFullscreenWindow.h
@@ -26,9 +26,10 @@
#ifndef MediaPlayerPrivateFullscreenWindow_h
#define MediaPlayerPrivateFullscreenWindow_h
+#include <wtf/RefPtr.h>
+
#if USE(ACCELERATED_COMPOSITING)
-#include "CACFLayerTreeHost.h"
-#include "PlatformCALayer.h"
+#include "CACFLayerTreeHostClient.h"
#endif
typedef unsigned WPARAM;
@@ -40,6 +41,11 @@ typedef unsigned int UINT;
namespace WebCore {
+#if USE(ACCELERATED_COMPOSITING)
+class CACFLayerTreeHost;
+class PlatformCALayer;
+#endif
+
class MediaPlayerPrivateFullscreenClient {
public:
virtual LRESULT fullscreenClientWndProc(HWND, UINT message, WPARAM, LPARAM) = 0;
@@ -53,13 +59,10 @@ public:
~MediaPlayerPrivateFullscreenWindow();
void createWindow(HWND ownerWindow);
- void close();
HWND hwnd() const { return m_hwnd; }
#if USE(ACCELERATED_COMPOSITING)
- CACFLayerTreeHost* layerView() const { return m_layerTreeHost.get(); }
-
PlatformCALayer* rootChildLayer() const { return m_rootChild.get(); }
void setRootChildLayer(PassRefPtr<PlatformCALayer>);
#endif
diff --git a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp
index 0b91455..d47de2b 100644
--- a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp
+++ b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp
@@ -1059,7 +1059,7 @@ float MediaPlayerPrivateQuickTimeVisualContext::mediaTimeForTimeValue(float time
if (m_readyState < MediaPlayer::HaveMetadata || !(timeScale = m_movie->timeScale()))
return timeValue;
- long mediaTimeValue = static_cast<long>(timeValue * timeScale);
+ long mediaTimeValue = lroundf(timeValue * timeScale);
return static_cast<float>(mediaTimeValue) / timeScale;
}
diff --git a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp
index 431d624..07b7621 100644
--- a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp
+++ b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp
@@ -622,7 +622,7 @@ void MediaPlayerPrivate::paint(GraphicsContext* p, const IntRect& r)
m_qtGWorld->paint(hdc, r.x(), r.y());
if (usingTempBitmap)
- p->drawWindowsBitmap(bitmap.get(), r.topLeft());
+ p->drawWindowsBitmap(bitmap.get(), r.location());
else
p->releaseWindowsContext(hdc, r);
diff --git a/Source/WebCore/platform/graphics/win/QTMovie.cpp b/Source/WebCore/platform/graphics/win/QTMovie.cpp
index dfa1d36..4cd8161 100644
--- a/Source/WebCore/platform/graphics/win/QTMovie.cpp
+++ b/Source/WebCore/platform/graphics/win/QTMovie.cpp
@@ -33,7 +33,9 @@
#include <Movies.h>
#include <QTML.h>
#include <QuickTimeComponents.h>
+#include <WebKitSystemInterface/WebKitSystemInterface.h>
#include <wtf/Assertions.h>
+#include <wtf/MathExtras.h>
#include <wtf/Noncopyable.h>
#include <wtf/Vector.h>
@@ -46,7 +48,6 @@ static const long subTitleTrackType = 'sbtl';
static const long mpeg4ObjectDescriptionTrackType = 'odsm';
static const long mpeg4SceneDescriptionTrackType = 'sdsm';
static const long closedCaptionDisplayPropertyID = 'disp';
-static LPCTSTR fullscreenQTMoviePointerProp = TEXT("fullscreenQTMoviePointer");
// Resizing GWorlds is slow, give them a minimum size so size of small
// videos can be animated smoothly
@@ -60,7 +61,7 @@ union UppParam {
void* ptr;
};
-static Vector<CFStringRef>* gSupportedTypes = 0;
+static CFMutableArrayRef gSupportedTypes = 0;
static SInt32 quickTimeVersion = 0;
class QTMoviePrivate : public QTMovieTaskClient {
@@ -374,10 +375,10 @@ void QTMovie::setCurrentTime(float time) const
m_private->m_seeking = true;
TimeScale scale = GetMovieTimeScale(m_private->m_movie);
if (m_private->m_movieController) {
- QTRestartAtTimeRecord restart = { time * scale , 0 };
+ QTRestartAtTimeRecord restart = { lroundf(time * scale) , 0 };
MCDoAction(m_private->m_movieController, mcActionRestartAtTime, (void *)&restart);
} else
- SetMovieTimeValue(m_private->m_movie, TimeValue(time * scale));
+ SetMovieTimeValue(m_private->m_movie, TimeValue(lroundf(time * scale)));
QTMovieTask::sharedTask()->updateTaskTimer();
}
@@ -747,112 +748,59 @@ long QTMovie::timeScale() const
return GetMovieTimeScale(m_private->m_movie);
}
+static void getMIMETypeCallBack(const char* type);
+
static void initializeSupportedTypes()
{
if (gSupportedTypes)
return;
- gSupportedTypes = new Vector<CFStringRef>;
+ gSupportedTypes = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
if (quickTimeVersion < minimumQuickTimeVersion) {
LOG_ERROR("QuickTime version %x detected, at least %x required. Returning empty list of supported media MIME types.", quickTimeVersion, minimumQuickTimeVersion);
return;
}
// QuickTime doesn't have an importer for video/quicktime. Add it manually.
- gSupportedTypes->append(CFSTR("video/quicktime"));
-
- for (int index = 0; index < 2; index++) {
- ComponentDescription findCD;
-
- // look at all movie importers that can import in place and are installed.
- findCD.componentType = MovieImportType;
- findCD.componentSubType = 0;
- findCD.componentManufacturer = 0;
- findCD.componentFlagsMask = cmpIsMissing | movieImportSubTypeIsFileExtension | canMovieImportInPlace | dontAutoFileMovieImport;
-
- // look at those registered by HFS file types the first time through, by file extension the second time
- findCD.componentFlags = canMovieImportInPlace | (index ? movieImportSubTypeIsFileExtension : 0);
-
- long componentCount = CountComponents(&findCD);
- if (!componentCount)
- continue;
+ CFArrayAppendValue(gSupportedTypes, CFSTR("video/quicktime"));
+
+ wkGetQuickTimeMIMETypeList(getMIMETypeCallBack);
+}
- Component comp = 0;
- while (comp = FindNextComponent(comp, &findCD)) {
- // Does this component have a MIME type container?
- ComponentDescription infoCD;
- OSErr err = GetComponentInfo(comp, &infoCD, nil /*name*/, nil /*info*/, nil /*icon*/);
- if (err)
- continue;
- if (!(infoCD.componentFlags & hasMovieImportMIMEList))
- continue;
- QTAtomContainer mimeList = 0;
- err = MovieImportGetMIMETypeList((ComponentInstance)comp, &mimeList);
- if (err || !mimeList)
- continue;
+static void getMIMETypeCallBack(const char* type)
+{
+ ASSERT(type);
+ CFStringRef cfType = CFStringCreateWithCString(kCFAllocatorDefault, type, kCFStringEncodingMacRoman);
+ if (!cfType)
+ return;
- // Grab every type from the container.
- QTLockContainer(mimeList);
- int typeCount = QTCountChildrenOfType(mimeList, kParentAtomIsContainer, kMimeInfoMimeTypeTag);
- for (int typeIndex = 1; typeIndex <= typeCount; typeIndex++) {
- QTAtom mimeTag = QTFindChildByIndex(mimeList, 0, kMimeInfoMimeTypeTag, typeIndex, 0);
- if (!mimeTag)
- continue;
- char* atomData;
- long typeLength;
- if (noErr != QTGetAtomDataPtr(mimeList, mimeTag, &typeLength, &atomData))
- continue;
-
- char typeBuffer[256];
- if (typeLength >= sizeof(typeBuffer))
- continue;
- memcpy(typeBuffer, atomData, typeLength);
- typeBuffer[typeLength] = 0;
-
- // Only add "audio/..." and "video/..." types.
- if (strncmp(typeBuffer, "audio/", 6) && strncmp(typeBuffer, "video/", 6))
- continue;
-
- CFStringRef cfMimeType = CFStringCreateWithCString(0, typeBuffer, kCFStringEncodingUTF8);
- if (!cfMimeType)
- continue;
-
- // Only add each type once.
- bool alreadyAdded = false;
- for (int addedIndex = 0; addedIndex < gSupportedTypes->size(); addedIndex++) {
- CFStringRef type = gSupportedTypes->at(addedIndex);
- if (kCFCompareEqualTo == CFStringCompare(cfMimeType, type, kCFCompareCaseInsensitive)) {
- alreadyAdded = true;
- break;
- }
- }
- if (!alreadyAdded)
- gSupportedTypes->append(cfMimeType);
- else
- CFRelease(cfMimeType);
- }
- DisposeHandle(mimeList);
- }
+ // Filter out all non-audio or -video MIME Types, and only add each type once:
+ if (CFStringHasPrefix(cfType, CFSTR("audio/")) || CFStringHasPrefix(cfType, CFSTR("video/"))) {
+ CFRange range = CFRangeMake(0, CFArrayGetCount(gSupportedTypes));
+ if (!CFArrayContainsValue(gSupportedTypes, range, cfType))
+ CFArrayAppendValue(gSupportedTypes, cfType);
}
+
+ CFRelease(cfType);
}
unsigned QTMovie::countSupportedTypes()
{
initializeSupportedTypes();
- return static_cast<unsigned>(gSupportedTypes->size());
+ return static_cast<unsigned>(CFArrayGetCount(gSupportedTypes));
}
void QTMovie::getSupportedType(unsigned index, const UChar*& str, unsigned& len)
{
initializeSupportedTypes();
- ASSERT(index < gSupportedTypes->size());
+ ASSERT(index < CFArrayGetCount(gSupportedTypes));
// Allocate sufficient buffer to hold any MIME type
static UniChar* staticBuffer = 0;
if (!staticBuffer)
staticBuffer = new UniChar[32];
- CFStringRef cfstr = gSupportedTypes->at(index);
+ CFStringRef cfstr = (CFStringRef)CFArrayGetValueAtIndex(gSupportedTypes, index);
len = CFStringGetLength(cfstr);
CFRange range = { 0, len };
CFStringGetCharacters(cfstr, range, staticBuffer);
diff --git a/Source/WebCore/platform/graphics/win/QTMovieGWorld.cpp b/Source/WebCore/platform/graphics/win/QTMovieGWorld.cpp
index e13f732..4be1bbb 100644
--- a/Source/WebCore/platform/graphics/win/QTMovieGWorld.cpp
+++ b/Source/WebCore/platform/graphics/win/QTMovieGWorld.cpp
@@ -40,7 +40,7 @@ using namespace std;
static const long minimumQuickTimeVersion = 0x07300000; // 7.3
-static LPCTSTR fullscreenQTMovieGWorldPointerProp = TEXT("fullscreenQTMovieGWorldPointer");
+static LPCWSTR fullscreenQTMovieGWorldPointerProp = L"fullscreenQTMovieGWorldPointer";
// Resizing GWorlds is slow, give them a minimum size so size of small
// videos can be animated smoothly
@@ -378,10 +378,10 @@ bool QTMovieGWorld::isDisabled() const
LRESULT QTMovieGWorld::fullscreenWndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lParam)
{
- QTMovieGWorld* movie = static_cast<QTMovieGWorld*>(GetProp(wnd, fullscreenQTMovieGWorldPointerProp));
+ QTMovieGWorld* movie = static_cast<QTMovieGWorld*>(GetPropW(wnd, fullscreenQTMovieGWorldPointerProp));
if (message == WM_DESTROY)
- RemoveProp(wnd, fullscreenQTMovieGWorldPointerProp);
+ RemovePropW(wnd, fullscreenQTMovieGWorldPointerProp);
if (!movie)
return DefWindowProc(wnd, message, wParam, lParam);
@@ -423,7 +423,7 @@ HWND QTMovieGWorld::enterFullscreen(QTMovieGWorldFullscreenClient* client)
// Set the 'this' pointer on the HWND
HWND wnd = static_cast<HWND>(GetPortNativeWindow(m_private->m_fullscreenWindow));
- SetProp(wnd, fullscreenQTMovieGWorldPointerProp, static_cast<HANDLE>(this));
+ SetPropW(wnd, fullscreenQTMovieGWorldPointerProp, static_cast<HANDLE>(this));
return wnd;
}
diff --git a/Source/WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp b/Source/WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp
index 20d42ff..30a931e 100644
--- a/Source/WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp
+++ b/Source/WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp
@@ -29,20 +29,19 @@
#include "config.h"
#include "SimpleFontData.h"
-#include <winsock2.h>
#include "Font.h"
#include "FontCache.h"
#include "FloatRect.h"
#include "FontDescription.h"
#include "PlatformString.h"
-#include <wtf/MathExtras.h>
-#include <wtf/RetainPtr.h>
-#include <unicode/uchar.h>
-#include <unicode/unorm.h>
#include <ApplicationServices/ApplicationServices.h>
#include <WebKitSystemInterface/WebKitSystemInterface.h>
#include <mlang.h>
-#include <tchar.h>
+#include <unicode/uchar.h>
+#include <unicode/unorm.h>
+#include <winsock2.h>
+#include <wtf/MathExtras.h>
+#include <wtf/RetainPtr.h>
namespace WebCore {
@@ -64,19 +63,19 @@ void SimpleFontData::platformInit()
int iAscent = CGFontGetAscent(font);
int iDescent = CGFontGetDescent(font);
int iLineGap = CGFontGetLeading(font);
- m_unitsPerEm = CGFontGetUnitsPerEm(font);
+ unsigned unitsPerEm = CGFontGetUnitsPerEm(font);
float pointSize = m_platformData.size();
- float fAscent = scaleEmToUnits(iAscent, m_unitsPerEm) * pointSize;
- float fDescent = -scaleEmToUnits(iDescent, m_unitsPerEm) * pointSize;
- float fLineGap = scaleEmToUnits(iLineGap, m_unitsPerEm) * pointSize;
+ float fAscent = scaleEmToUnits(iAscent, unitsPerEm) * pointSize;
+ float fDescent = -scaleEmToUnits(iDescent, unitsPerEm) * pointSize;
+ float fLineGap = scaleEmToUnits(iLineGap, unitsPerEm) * pointSize;
if (!isCustomFont()) {
HDC dc = GetDC(0);
HGDIOBJ oldFont = SelectObject(dc, m_platformData.hfont());
int faceLength = GetTextFace(dc, 0, 0);
- Vector<TCHAR> faceName(faceLength);
+ Vector<WCHAR> faceName(faceLength);
GetTextFace(dc, faceLength, faceName.data());
- m_isSystemFont = !_tcscmp(faceName.data(), _T("Lucida Grande"));
+ m_isSystemFont = !wcscmp(faceName.data(), L"Lucida Grande");
SelectObject(dc, oldFont);
ReleaseDC(0, dc);
@@ -88,15 +87,15 @@ void SimpleFontData::platformInit()
// web standard. The AppKit adjustment of 20% is too big and is
// incorrectly added to line spacing, so we use a 15% adjustment instead
// and add it to the ascent.
- if (!_tcscmp(faceName.data(), _T("Times")) || !_tcscmp(faceName.data(), _T("Helvetica")) || !_tcscmp(faceName.data(), _T("Courier")))
+ if (!wcscmp(faceName.data(), L"Times") || !wcscmp(faceName.data(), L"Helvetica") || !wcscmp(faceName.data(), L"Courier"))
fAscent += floorf(((fAscent + fDescent) * 0.15f) + 0.5f);
}
}
- m_ascent = lroundf(fAscent);
- m_descent = lroundf(fDescent);
- m_lineGap = lroundf(fLineGap);
- m_lineSpacing = m_ascent + m_descent + m_lineGap;
+ m_fontMetrics.setAscent(fAscent);
+ m_fontMetrics.setDescent(fDescent);
+ m_fontMetrics.setLineGap(fLineGap);
+ m_fontMetrics.setLineSpacing(lroundf(fAscent) + lroundf(fDescent) + lroundf(fLineGap));
// Measure the actual character "x", because AppKit synthesizes X height rather than getting it from the font.
// Unfortunately, NSFont will round this for us so we don't quite get the right value.
@@ -109,11 +108,13 @@ void SimpleFontData::platformInit()
// and web pages that foolishly use this metric for width will be laid out
// poorly if we return an accurate height. Classic case is Times 13 point,
// which has an "x" that is 7x6 pixels.
- m_xHeight = scaleEmToUnits(max(CGRectGetMaxX(xBox), CGRectGetMaxY(xBox)), m_unitsPerEm) * pointSize;
+ m_fontMetrics.setXHeight(scaleEmToUnits(max(CGRectGetMaxX(xBox), CGRectGetMaxY(xBox)), unitsPerEm) * pointSize);
} else {
int iXHeight = CGFontGetXHeight(font);
- m_xHeight = scaleEmToUnits(iXHeight, m_unitsPerEm) * pointSize;
+ m_fontMetrics.setXHeight(scaleEmToUnits(iXHeight, unitsPerEm) * pointSize);
}
+
+ m_fontMetrics.setUnitsPerEm(unitsPerEm);
}
void SimpleFontData::platformCharWidthInit()
@@ -133,7 +134,7 @@ FloatRect SimpleFontData::platformBoundsForGlyph(Glyph glyph) const
CGRect box;
CGFontGetGlyphBBoxes(m_platformData.cgFont(), &glyph, 1, &box);
float pointSize = m_platformData.size();
- CGFloat scale = pointSize / unitsPerEm();
+ CGFloat scale = pointSize / fontMetrics().unitsPerEm();
FloatRect boundingBox = CGRectApplyAffineTransform(box, CGAffineTransformMakeScale(scale, -scale));
if (m_syntheticBoldOffset)
boundingBox.setWidth(boundingBox.width() + m_syntheticBoldOffset);
diff --git a/Source/WebCore/platform/graphics/win/SimpleFontDataCairoWin.cpp b/Source/WebCore/platform/graphics/win/SimpleFontDataCairoWin.cpp
index 62ea060..277a13f 100644
--- a/Source/WebCore/platform/graphics/win/SimpleFontDataCairoWin.cpp
+++ b/Source/WebCore/platform/graphics/win/SimpleFontDataCairoWin.cpp
@@ -37,7 +37,6 @@
#include <cairo.h>
#include <cairo-win32.h>
#include <mlang.h>
-#include <tchar.h>
#include <wtf/MathExtras.h>
namespace WebCore {
@@ -63,13 +62,16 @@ void SimpleFontData::platformInit()
TEXTMETRIC textMetrics;
GetTextMetrics(hdc, &textMetrics);
- m_ascent = lroundf(textMetrics.tmAscent * metricsMultiplier);
- m_descent = lroundf(textMetrics.tmDescent * metricsMultiplier);
- m_xHeight = m_ascent * 0.56f; // Best guess for xHeight for non-Truetype fonts.
- m_lineGap = lroundf(textMetrics.tmExternalLeading * metricsMultiplier);
- m_lineSpacing = m_ascent + m_descent + m_lineGap;
- m_avgCharWidth = lroundf(textMetrics.tmAveCharWidth * metricsMultiplier);
- m_maxCharWidth = lroundf(textMetrics.tmMaxCharWidth * metricsMultiplier);
+ float ascent = textMetrics.tmAscent * metricsMultiplier;
+ float descent = textMetrics.tmDescent * metricsMultiplier;
+ float xHeight = ascent * 0.56f; // Best guess for xHeight for non-Truetype fonts.
+ float lineGap = textMetrics.tmExternalLeading * metricsMultiplier;
+ m_fontMetrics.setAscent(ascent);
+ m_fontMetrics.setDescent(descent);
+ m_fontMetrics.setLineGap(lineGap);
+ m_fontMetrics.setLineSpacing(lroundf(ascent) + lroundf(descent) + lroundf(lineGap));
+ m_avgCharWidth = textMetrics.tmAveCharWidth * metricsMultiplier;
+ m_maxCharWidth = textMetrics.tmMaxCharWidth * metricsMultiplier;
OUTLINETEXTMETRIC metrics;
if (GetOutlineTextMetrics(hdc, sizeof(metrics), &metrics) > 0) {
@@ -78,9 +80,10 @@ void SimpleFontData::platformInit()
MAT2 mat = { 1, 0, 0, 1 };
DWORD len = GetGlyphOutline(hdc, 'x', GGO_METRICS, &gm, 0, 0, &mat);
if (len != GDI_ERROR && gm.gmptGlyphOrigin.y > 0)
- m_xHeight = gm.gmptGlyphOrigin.y * metricsMultiplier;
+ xHeight = gm.gmptGlyphOrigin.y * metricsMultiplier;
}
+ m_fontMetrics.setXHeight(xHeight);
cairo_win32_scaled_font_done_font(scaledFont);
m_isSystemFont = false;
diff --git a/Source/WebCore/platform/graphics/win/SimpleFontDataWin.cpp b/Source/WebCore/platform/graphics/win/SimpleFontDataWin.cpp
index 60afe6a..323ff73 100644
--- a/Source/WebCore/platform/graphics/win/SimpleFontDataWin.cpp
+++ b/Source/WebCore/platform/graphics/win/SimpleFontDataWin.cpp
@@ -29,16 +29,15 @@
#include "config.h"
#include "SimpleFontData.h"
-#include <winsock2.h>
#include "Font.h"
#include "FontCache.h"
#include "FloatRect.h"
#include "FontDescription.h"
-#include <wtf/MathExtras.h>
+#include <mlang.h>
#include <unicode/uchar.h>
#include <unicode/unorm.h>
-#include <mlang.h>
-#include <tchar.h>
+#include <winsock2.h>
+#include <wtf/MathExtras.h>
#if PLATFORM(CG)
#include <ApplicationServices/ApplicationServices.h>
@@ -66,14 +65,9 @@ bool SimpleFontData::shouldApplyMacAscentHack()
void SimpleFontData::initGDIFont()
{
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,21 +76,25 @@ void SimpleFontData::initGDIFont()
OUTLINETEXTMETRIC metrics;
GetOutlineTextMetrics(hdc, sizeof(metrics), &metrics);
TEXTMETRIC& textMetrics = metrics.otmTextMetrics;
- m_ascent = textMetrics.tmAscent;
- m_descent = textMetrics.tmDescent;
- m_lineGap = textMetrics.tmExternalLeading;
- m_lineSpacing = m_ascent + m_descent + m_lineGap;
+ float ascent = textMetrics.tmAscent;
+ float descent = textMetrics.tmDescent;
+ float lineGap = textMetrics.tmExternalLeading;
+ m_fontMetrics.setAscent(ascent);
+ m_fontMetrics.setDescent(descent);
+ m_fontMetrics.setLineGap(lineGap);
+ m_fontMetrics.setLineSpacing(lroundf(ascent) + lroundf(descent) + lroundf(lineGap));
m_avgCharWidth = textMetrics.tmAveCharWidth;
m_maxCharWidth = textMetrics.tmMaxCharWidth;
- m_xHeight = m_ascent * 0.56f; // Best guess for xHeight if no x glyph is present.
+ float xHeight = ascent * 0.56f; // Best guess for xHeight if no x glyph is present.
GLYPHMETRICS gm;
MAT2 mat = { 1, 0, 0, 1 };
DWORD len = GetGlyphOutline(hdc, 'x', GGO_METRICS, &gm, 0, 0, &mat);
if (len != GDI_ERROR && gm.gmptGlyphOrigin.y > 0)
- m_xHeight = gm.gmptGlyphOrigin.y;
+ xHeight = gm.gmptGlyphOrigin.y;
- m_unitsPerEm = metrics.otmEMSquare;
+ m_fontMetrics.setXHeight(xHeight);
+ m_fontMetrics.setUnitsPerEm(metrics.otmEMSquare);
SelectObject(hdc, oldFont);
ReleaseDC(0, hdc);
diff --git a/Source/WebCore/platform/graphics/win/UniscribeController.cpp b/Source/WebCore/platform/graphics/win/UniscribeController.cpp
index dac6c3e..ebbed51 100644
--- a/Source/WebCore/platform/graphics/win/UniscribeController.cpp
+++ b/Source/WebCore/platform/graphics/win/UniscribeController.cpp
@@ -49,7 +49,7 @@ UniscribeController::UniscribeController(const Font* font, const TextRun& run, H
, m_end(run.length())
, m_currentCharacter(0)
, m_runWidthSoFar(0)
- , m_padding(run.padding())
+ , m_padding(run.expansion())
, m_computingOffsetPosition(false)
, m_includePartialGlyphs(false)
, m_offsetX(0)
@@ -394,9 +394,9 @@ bool UniscribeController::shapeAndPlaceItem(const UChar* cp, unsigned i, const S
FloatRect glyphBounds = fontData->boundsForGlyph(glyph);
glyphBounds.move(m_glyphOrigin.x(), m_glyphOrigin.y());
m_minGlyphBoundingBoxX = min(m_minGlyphBoundingBoxX, glyphBounds.x());
- m_maxGlyphBoundingBoxX = max(m_maxGlyphBoundingBoxX, glyphBounds.right());
+ m_maxGlyphBoundingBoxX = max(m_maxGlyphBoundingBoxX, glyphBounds.maxX());
m_minGlyphBoundingBoxY = min(m_minGlyphBoundingBoxY, glyphBounds.y());
- m_maxGlyphBoundingBoxY = max(m_maxGlyphBoundingBoxY, glyphBounds.bottom());
+ m_maxGlyphBoundingBoxY = max(m_maxGlyphBoundingBoxY, glyphBounds.maxY());
m_glyphOrigin.move(advance + offsetX, -offsetY);
// Mutate the glyph array to contain our altered advances.
diff --git a/Source/WebCore/platform/graphics/win/WKCAImageQueue.cpp b/Source/WebCore/platform/graphics/win/WKCAImageQueue.cpp
index c2a178b..c8f2116 100644
--- a/Source/WebCore/platform/graphics/win/WKCAImageQueue.cpp
+++ b/Source/WebCore/platform/graphics/win/WKCAImageQueue.cpp
@@ -24,11 +24,11 @@
*/
#include "config.h"
+#include "WKCAImageQueue.h"
#if USE(ACCELERATED_COMPOSITING)
-#include "WKCAImageQueue.h"
-
+#include <CoreFoundation/CoreFoundation.h>
#include <WebKitSystemInterface/WebKitSystemInterface.h>
#include <wtf/RetainPtr.h>
diff --git a/Source/WebCore/platform/graphics/wince/FontCustomPlatformData.cpp b/Source/WebCore/platform/graphics/wince/FontCustomPlatformData.cpp
index f61ae8e..fb97fe1 100644
--- a/Source/WebCore/platform/graphics/wince/FontCustomPlatformData.cpp
+++ b/Source/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, FontOrientation, FontRenderingMode renderingMode)
+FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, FontWidthVariant, FontRenderingMode renderingMode)
{
FontDescription fontDesc;
fontDesc.setComputedSize(size);
@@ -59,16 +59,14 @@ FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, b
// not allow access from CSS.
static String createUniqueFontName()
{
- Vector<char> fontUuid(sizeof(GUID));
+ GUID fontUuid;
- unsigned int* ptr = reinterpret_cast<unsigned int*>(fontUuid.data());
+ unsigned int* ptr = reinterpret_cast<unsigned int*>(&fontUuid);
for (int i = 0; i < sizeof(GUID) / sizeof(int) ; ++i)
*(ptr + i) = static_cast<unsigned int>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0));
- Vector<char> fontNameVector;
- base64Encode(fontUuid, fontNameVector);
- ASSERT(fontNameVector.size() < LF_FACESIZE);
- String fontName(fontNameVector.data(), fontNameVector.size());
+ String fontName = base64Encode(reinterpret_cast<char*>(&fontUuid), sizeof(fontUuid));
+ ASSERT(fontName.length() < LF_FACESIZE);
return fontName.replace('/', '_');
}
diff --git a/Source/WebCore/platform/graphics/wince/FontCustomPlatformData.h b/Source/WebCore/platform/graphics/wince/FontCustomPlatformData.h
index 0508246..fe7ee94 100644
--- a/Source/WebCore/platform/graphics/wince/FontCustomPlatformData.h
+++ b/Source/WebCore/platform/graphics/wince/FontCustomPlatformData.h
@@ -23,6 +23,7 @@
#include "FontDescription.h"
#include "FontRenderingMode.h"
+#include "FontWidthVariant.h"
#include "PlatformString.h"
#include <wtf/Noncopyable.h>
@@ -47,7 +48,7 @@ namespace WebCore {
~FontCustomPlatformData();
- FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation fontOrientation = Horizontal, FontRenderingMode = NormalRenderingMode);
+ FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, FontWidthVariant = RegularWidth, FontRenderingMode = NormalRenderingMode);
static bool supportsFormat(const String&);
diff --git a/Source/WebCore/platform/graphics/wince/FontWinCE.cpp b/Source/WebCore/platform/graphics/wince/FontWinCE.cpp
index 5a4c8da..c3e6ce4 100644
--- a/Source/WebCore/platform/graphics/wince/FontWinCE.cpp
+++ b/Source/WebCore/platform/graphics/wince/FontWinCE.cpp
@@ -86,6 +86,7 @@ public:
TextRunComponent::TextRunComponent(const UChar *start, int length, const TextRun& parentTextRun, const Font &font, int o)
: m_textRun(start, length, parentTextRun.allowTabs(), 0, 0
+ , parentTextRun.allowsTrailingExpansion() ? TextRun::AllowTrailingExpansion : TextRun::ForbidTrailingExpansion
, parentTextRun.rtl()
, parentTextRun.directionalOverride()
, parentTextRun.applyRunRounding()
@@ -112,7 +113,7 @@ static int generateComponents(TextRunComponents* components, const Font &font, c
{
int letterSpacing = font.letterSpacing();
int wordSpacing = font.wordSpacing();
- int padding = run.padding();
+ int padding = run.expansion();
int numSpaces = 0;
if (padding) {
for (int i = 0; i < run.length(); i++)
@@ -340,4 +341,9 @@ bool Font::canReturnFallbackFontsForComplexText()
return false;
}
+bool Font::canExpandAroundIdeographsInComplexText()
+{
+ return false;
+}
+
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp b/Source/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp
index 9b672d2..7b1c27b 100644
--- a/Source/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp
+++ b/Source/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp
@@ -23,7 +23,6 @@
#include "GraphicsContext.h"
#include "AffineTransform.h"
-#include "CharacterNames.h"
#include "Font.h"
#include "GDIExtras.h"
#include "GlyphBuffer.h"
@@ -33,9 +32,9 @@
#include "PlatformPathWinCE.h"
#include "SharedBitmap.h"
#include "SimpleFontData.h"
-#include <wtf/OwnPtr.h>
-
#include <windows.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/unicode/CharacterNames.h>
namespace WebCore {
@@ -62,7 +61,7 @@ static inline int stableRound(double d)
// Unlike enclosingIntRect(), this function does strict rounding.
static inline IntRect roundRect(const FloatRect& r)
{
- return IntRect(stableRound(r.x()), stableRound(r.y()), stableRound(r.right()) - stableRound(r.x()), stableRound(r.bottom()) - stableRound(r.y()));
+ return IntRect(stableRound(r.x()), stableRound(r.y()), stableRound(r.maxX()) - stableRound(r.x()), stableRound(r.maxY()) - stableRound(r.y()));
}
// Rotation transformation
@@ -129,8 +128,8 @@ template<class Transform, class Rect, class Value> static inline Rect mapRect(co
{
Value x[4], y[4];
Value l, t, r, b;
- r = rect.right() - 1;
- b = rect.bottom() - 1;
+ r = rect.maxX() - 1;
+ b = rect.maxY() - 1;
transform.map(rect.x(), rect.y(), x, y);
transform.map(rect.x(), b, x + 1, y + 1);
transform.map(r, b, x + 2, y + 2);
@@ -503,10 +502,10 @@ TransparentLayerDC::TransparentLayerDC(GraphicsContextPlatformPrivate* data, Int
m_rotation.m_postShiftX -= m_origRect.x();
m_rotation.m_postShiftY -= m_origRect.y();
- FloatPoint topLeft = m_data->m_transform.mapPoint(FloatPoint(rectBeforeTransform->topLeft()));
- FloatPoint topRight(rectBeforeTransform->right() - 1, rectBeforeTransform->y());
+ FloatPoint topLeft = m_data->m_transform.mapPoint(FloatPoint(rectBeforeTransform->location()));
+ FloatPoint topRight(rectBeforeTransform->maxX() - 1, rectBeforeTransform->y());
topRight = m_data->m_transform.mapPoint(topRight);
- FloatPoint bottomLeft(rectBeforeTransform->x(), rectBeforeTransform->bottom() - 1);
+ FloatPoint bottomLeft(rectBeforeTransform->x(), rectBeforeTransform->maxY() - 1);
bottomLeft = m_data->m_transform.mapPoint(bottomLeft);
FloatSize sideTop = topRight - topLeft;
FloatSize sideLeft = bottomLeft - topLeft;
@@ -656,7 +655,7 @@ void GraphicsContext::drawRect(const IntRect& rect)
if (trRect.height() <= 0)
trRect.setHeight(1);
- Rectangle(dc, trRect.x(), trRect.y(), trRect.right(), trRect.bottom());
+ Rectangle(dc, trRect.x(), trRect.y(), trRect.maxX(), trRect.maxY());
}
SelectObject(dc, oldPen);
@@ -726,7 +725,7 @@ void GraphicsContext::drawEllipse(const IntRect& rect)
oldPen = SelectObject(dc, GetStockObject(NULL_PEN));
if (brush || pen)
- Ellipse(dc, trRect.x(), trRect.y(), trRect.right(), trRect.bottom());
+ Ellipse(dc, trRect.x(), trRect.y(), trRect.maxX(), trRect.maxY());
SelectObject(dc, oldPen);
SelectObject(dc, oldBrush);
@@ -839,7 +838,7 @@ void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSp
}
HGDIOBJ oldBrush = SelectObject(dc, GetStockObject(NULL_BRUSH));
- Ellipse(dc, trRect.x(), trRect.y(), trRect.right(), trRect.bottom());
+ Ellipse(dc, trRect.x(), trRect.y(), trRect.maxX(), trRect.maxY());
SelectObject(dc, oldBrush);
if (newClip)
@@ -960,9 +959,9 @@ void GraphicsContext::clip(const FloatRect& rect)
OwnPtr<HRGN> clipRgn(CreateRectRgn(0, 0, 0, 0));
if (GetClipRgn(m_data->m_dc, clipRgn.get()) > 0)
- IntersectClipRect(m_data->m_dc, trRect.x(), trRect.y(), trRect.right(), trRect.bottom());
+ IntersectClipRect(m_data->m_dc, trRect.x(), trRect.y(), trRect.maxX(), trRect.maxY());
else {
- clipRgn.set(CreateRectRgn(trRect.x(), trRect.y(), trRect.right(), trRect.bottom()));
+ clipRgn.set(CreateRectRgn(trRect.x(), trRect.y(), trRect.maxX(), trRect.maxY()));
SelectClipRgn(m_data->m_dc, clipRgn.get());
}
}
@@ -977,7 +976,7 @@ void GraphicsContext::clipOut(const IntRect& rect)
IntRect trRect = m_data->mapRect(rect);
- ExcludeClipRect(m_data->m_dc, trRect.x(), trRect.y(), trRect.right(), trRect.bottom());
+ ExcludeClipRect(m_data->m_dc, trRect.x(), trRect.y(), trRect.maxX(), trRect.maxY());
}
void GraphicsContext::drawFocusRing(const Path& path, int width, int offset, const Color& color)
@@ -1093,8 +1092,8 @@ void GraphicsContext::strokeRect(const FloatRect& rect, float width)
OwnPtr<HPEN> pen = createPen(strokeColor(), strokeThickness(), strokeStyle());
HGDIOBJ oldPen = SelectObject(dc, pen.get());
- int right = trRect.right() - 1;
- int bottom = trRect.bottom() - 1;
+ int right = trRect.maxX() - 1;
+ int bottom = trRect.maxY() - 1;
const POINT intPoints[5] =
{
{ trRect.x(), trRect.y() },
@@ -1536,8 +1535,8 @@ void GraphicsContext::drawText(const Font& font, const TextRun& run, const IntPo
float oldOpacity = m_data->m_opacity;
m_data->m_opacity *= fillColor().alpha() / 255.0;
- FloatRect textRect = font.selectionRectForText(run, point, font.height(), from, to);
- textRect.setY(textRect.y() - font.ascent());
+ FloatRect textRect = font.selectionRectForText(run, point, font.fontMetrics().height(), from, to);
+ textRect.setY(textRect.y() - font.fontMetrics().ascent());
IntRect trRect = enclosingIntRect(m_data->mapRect(textRect));
RECT bmpRect;
AlphaPaintType alphaPaintType = mustSupportAlpha ? AlphaPaintOther : AlphaPaintNone;
@@ -1546,7 +1545,7 @@ void GraphicsContext::drawText(const Font& font, const TextRun& run, const IntPo
GraphicsContext gc(0);
gc.setBitmap(bmp);
gc.scale(FloatSize(m_data->m_transform.a(), m_data->m_transform.d()));
- font.drawText(&gc, run, IntPoint(0, font.ascent()), from, to);
+ font.drawText(&gc, run, IntPoint(0, font.fontMetrics().ascent()), from, to);
}
unsigned key1;
HDC memDC = bmp->getDC(&key1);
@@ -1591,7 +1590,7 @@ void GraphicsContext::drawText(const SimpleFontData* fontData, const GlyphBuffer
? fontData->platformData().getScaledFontHandle(height, scaleX == scaleY ? 0 : width)
: 0;
- FloatPoint startPoint(point.x(), point.y() - fontData->ascent());
+ FloatPoint startPoint(point.x(), point.y() - fontData->fontMetrics().ascent());
FloatPoint trPoint = m_data->mapPoint(startPoint);
int y = stableRound(trPoint.y());
diff --git a/Source/WebCore/platform/graphics/wince/PlatformPathWinCE.cpp b/Source/WebCore/platform/graphics/wince/PlatformPathWinCE.cpp
index 8534f89..8efe661 100644
--- a/Source/WebCore/platform/graphics/wince/PlatformPathWinCE.cpp
+++ b/Source/WebCore/platform/graphics/wince/PlatformPathWinCE.cpp
@@ -119,7 +119,7 @@ static inline void bezier(int segments, Vector<PathPoint>& pts, const PathPoint*
static bool containsPoint(const FloatRect& r, const FloatPoint& p)
{
- return p.x() >= r.x() && p.y() >= r.y() && p.x() < r.right() && p.y() < r.bottom();
+ return p.x() >= r.x() && p.y() >= r.y() && p.x() < r.maxX() && p.y() < r.maxY();
}
static void normalizeAngle(float& angle)
@@ -146,7 +146,7 @@ static void inflateRectToContainPoint(FloatRect& r, float x, float y)
return;
}
if (x < r.x()) {
- r.setWidth(r.right() - x);
+ r.setWidth(r.maxX() - x);
r.setX(x);
} else {
float w = x - r.x() + 1;
@@ -154,7 +154,7 @@ static void inflateRectToContainPoint(FloatRect& r, float x, float y)
r.setWidth(w);
}
if (y < r.y()) {
- r.setHeight(r.bottom() - y);
+ r.setHeight(r.maxY() - y);
r.setY(y);
} else {
float h = y - r.y() + 1;
@@ -740,8 +740,8 @@ void PlatformPath::addRect(const FloatRect& r)
{
moveTo(r.location());
- float right = r.right() - 1;
- float bottom = r.bottom() - 1;
+ float right = r.maxX() - 1;
+ float bottom = r.maxY() - 1;
addLineTo(FloatPoint(right, r.y()));
addLineTo(FloatPoint(right, bottom));
addLineTo(FloatPoint(r.x(), bottom));
diff --git a/Source/WebCore/platform/graphics/wince/SharedBitmap.cpp b/Source/WebCore/platform/graphics/wince/SharedBitmap.cpp
index 168a5e2..2bf0028 100644
--- a/Source/WebCore/platform/graphics/wince/SharedBitmap.cpp
+++ b/Source/WebCore/platform/graphics/wince/SharedBitmap.cpp
@@ -135,7 +135,7 @@ bool SharedBitmap::to16bit()
int width = newBmpInfo.width();
int paddedWidth = newBmpInfo.paddedWidth();
int bufferSize = paddedWidth * newBmpInfo.height();
- OwnArrayPtr<unsigned> newPixelData(new unsigned[bufferSize / 2]);
+ OwnArrayPtr<unsigned> newPixelData = adoptArrayPtr(new unsigned[bufferSize / 2]);
void* newPixels = newPixelData.get();
if (!newPixels)
@@ -481,8 +481,8 @@ void SharedBitmap::drawPattern(HDC hdc, const AffineTransform& transform, const
RECT dstRectWin = {
stableRound(trRect.x()),
stableRound(trRect.y()),
- stableRound(trRect.right()),
- stableRound(trRect.bottom()),
+ stableRound(trRect.maxX()),
+ stableRound(trRect.maxY()),
};
if (dstRectWin.right <= dstRectWin.left || dstRectWin.bottom <= dstRectWin.top)
return;
@@ -497,8 +497,8 @@ void SharedBitmap::drawPattern(HDC hdc, const AffineTransform& transform, const
RECT srcRectWin = {
0,
0,
- stableRound(visibleDstRect.right()) - stableRound(visibleDstRect.x()),
- stableRound(visibleDstRect.bottom()) - stableRound(visibleDstRect.y())
+ stableRound(visibleDstRect.maxX()) - stableRound(visibleDstRect.x()),
+ stableRound(visibleDstRect.maxY()) - stableRound(visibleDstRect.y())
};
if (srcRectWin.right <= 0 || srcRectWin.bottom <= 0)
return;
diff --git a/Source/WebCore/platform/graphics/wince/SimpleFontDataWinCE.cpp b/Source/WebCore/platform/graphics/wince/SimpleFontDataWinCE.cpp
index 27a021e..8abafbd 100644
--- a/Source/WebCore/platform/graphics/wince/SimpleFontDataWinCE.cpp
+++ b/Source/WebCore/platform/graphics/wince/SimpleFontDataWinCE.cpp
@@ -27,7 +27,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-
#include "config.h"
#include "SimpleFontData.h"
@@ -35,9 +34,8 @@
#include "Font.h"
#include "FontCache.h"
#include "FontDescription.h"
-#include <wtf/MathExtras.h>
#include <mlang.h>
-#include <tchar.h>
+#include <wtf/MathExtras.h>
namespace WebCore {
@@ -51,11 +49,14 @@ void SimpleFontData::platformInit()
const TEXTMETRIC& tm = m_platformData.metrics();
m_isSystemFont = m_platformData.isSystemFont();
- m_ascent = (tm.tmAscent * m_platformData.size() + 36) / 72;
- m_descent = (tm.tmDescent * m_platformData.size() + 36) / 72;
- m_lineGap = (tm.tmExternalLeading * m_platformData.size() + 36) / 72;
- m_lineSpacing = m_ascent + m_descent + m_lineGap;
- m_xHeight = m_ascent * 0.56f;
+ float ascent = (tm.tmAscent * m_platformData.size() + 36) / 72.0f;
+ float descent = (tm.tmDescent * m_platformData.size() + 36) / 72.0f;
+ float lineGap = (tm.tmExternalLeading * m_platformData.size() + 36) / 72.0f;
+ m_fontMetrics.setAscent(ascent);
+ m_fontMetrics.setDescent(descent);
+ m_fontMetrics.setLineGap(lineGap);
+ m_fontMetrics.setLineSpacing(lroundf(ascent) + lroundf(descent) + lroundf(lineGap));
+ m_fontMetrics.setXHeight(ascent * 0.56f);
}
void SimpleFontData::platformDestroy()
diff --git a/Source/WebCore/platform/graphics/wx/FontCustomPlatformData.cpp b/Source/WebCore/platform/graphics/wx/FontCustomPlatformData.cpp
index 6133372..055f0fc 100644
--- a/Source/WebCore/platform/graphics/wx/FontCustomPlatformData.cpp
+++ b/Source/WebCore/platform/graphics/wx/FontCustomPlatformData.cpp
@@ -31,7 +31,7 @@ FontCustomPlatformData::~FontCustomPlatformData()
{
}
-FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, FontRenderingMode)
+FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, FontWidthVariant, FontRenderingMode)
{
return FontPlatformData(size, bold, italic);
}
diff --git a/Source/WebCore/platform/graphics/wx/FontCustomPlatformData.h b/Source/WebCore/platform/graphics/wx/FontCustomPlatformData.h
index 86f99b2..c975296 100644
--- a/Source/WebCore/platform/graphics/wx/FontCustomPlatformData.h
+++ b/Source/WebCore/platform/graphics/wx/FontCustomPlatformData.h
@@ -23,7 +23,9 @@
#include "FontOrientation.h"
#include "FontRenderingMode.h"
+#include "FontWidthVariant.h"
#include <wtf/Forward.h>
+#include <wtf/Noncopyable.h>
namespace WebCore {
@@ -38,7 +40,7 @@ namespace WebCore {
static bool supportsFormat(const String&);
- FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, FontRenderingMode = NormalRenderingMode);
+ FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, FontWidthVariant = RegularWidth, FontRenderingMode = NormalRenderingMode);
};
FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer*);
diff --git a/Source/WebCore/platform/graphics/wx/FontPlatformData.h b/Source/WebCore/platform/graphics/wx/FontPlatformData.h
index 9ae8b54..3ef0179 100644
--- a/Source/WebCore/platform/graphics/wx/FontPlatformData.h
+++ b/Source/WebCore/platform/graphics/wx/FontPlatformData.h
@@ -30,6 +30,7 @@
#define FontPlatformData_h
#include "FontDescription.h"
+#include "FontWidthVariant.h"
#include "FontOrientation.h"
#include "StringImpl.h"
#include <wtf/Forward.h>
@@ -150,6 +151,9 @@ public:
FontOrientation orientation() const { return Horizontal; } // FIXME: Implement.
+ // We don't support this yet, so just return the default value for now.
+ FontWidthVariant widthVariant() const { return RegularWidth; }
+
#if OS(WINDOWS)
bool useGDI() const;
HFONT hfont() const;
diff --git a/Source/WebCore/platform/graphics/wx/FontPlatformDataWx.cpp b/Source/WebCore/platform/graphics/wx/FontPlatformDataWx.cpp
index 66c69ee..c125b7c 100644
--- a/Source/WebCore/platform/graphics/wx/FontPlatformDataWx.cpp
+++ b/Source/WebCore/platform/graphics/wx/FontPlatformDataWx.cpp
@@ -126,7 +126,7 @@ unsigned FontPlatformData::computeHash() const
thisFont->GetStyle(),
thisFont->GetWeight(),
thisFont->GetUnderlined(),
- StringImpl::computeHash(thisFont->GetFaceName().utf8_str())
+ WTF::StringHasher::createHash(thisFont->GetFaceName().utf8_str().data())
};
return WTF::StringHasher::createBlobHash<sizeof(hashCodes)>(hashCodes);
diff --git a/Source/WebCore/platform/graphics/wx/FontWx.cpp b/Source/WebCore/platform/graphics/wx/FontWx.cpp
index c01e249..c48f3c7 100644
--- a/Source/WebCore/platform/graphics/wx/FontWx.cpp
+++ b/Source/WebCore/platform/graphics/wx/FontWx.cpp
@@ -32,6 +32,7 @@
#include "IntRect.h"
#include "NotImplemented.h"
#include "SimpleFontData.h"
+#include "TextRun.h"
#if OS(WINDOWS)
#include "UniscribeController.h"
@@ -57,6 +58,15 @@ bool Font::canReturnFallbackFontsForComplexText()
#endif
}
+bool Font::canExpandAroundIdeographsInComplexText()
+{
+#if OS(DARWIN)
+ return true;
+#else
+ return false;
+#endif
+}
+
void Font::drawGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* font, const GlyphBuffer& glyphBuffer,
int from, int numGlyphs, const FloatPoint& point) const
{
diff --git a/Source/WebCore/platform/graphics/wx/GraphicsContextWx.cpp b/Source/WebCore/platform/graphics/wx/GraphicsContextWx.cpp
index f1c09c5..991be79 100644
--- a/Source/WebCore/platform/graphics/wx/GraphicsContextWx.cpp
+++ b/Source/WebCore/platform/graphics/wx/GraphicsContextWx.cpp
@@ -515,7 +515,7 @@ void GraphicsContext::fillPath(const Path& path)
#if USE(WXGC)
wxGraphicsContext* gc = m_data->context->GetGraphicsContext();
if (gc)
- gc->FillPath(path.platformPath());
+ gc->FillPath(*path.platformPath());
#endif
}
@@ -524,7 +524,7 @@ void GraphicsContext::strokePath(const Path& path)
#if USE(WXGC)
wxGraphicsContext* gc = m_data->context->GetGraphicsContext();
if (gc)
- gc->StrokePath(path.platformPath());
+ gc->StrokePath(*path.platformPath());
#endif
}
diff --git a/Source/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp b/Source/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp
index 0e24bfc..4f24e4c 100644
--- a/Source/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp
+++ b/Source/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp
@@ -53,12 +53,12 @@ void SimpleFontData::platformInit()
wxFont *font = m_platformData.font();
if (font && font->IsOk()) {
wxFontProperties props = wxFontProperties(font);
- m_ascent = props.GetAscent();
- m_descent = props.GetDescent();
- m_lineSpacing = props.GetLineSpacing();
- m_xHeight = props.GetXHeight();
- m_unitsPerEm = 1; // FIXME!
- m_lineGap = props.GetLineGap();
+ m_fontMetrics.setAscent(props.GetAscent());
+ m_fontMetrics.setDescent(props.GetDescent());
+ m_fontMetrics.setXHeight(props.GetXHeight());
+ m_fontMetrics.setUnitsPerEm(1); // FIXME!
+ m_fontMetrics.setLineGap(props.GetLineGap());
+ m_fontMetrics.setLineSpacing(props.GetLineSpacing());
}
m_syntheticBoldOffset = 0.0f;