summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/platform')
-rw-r--r--Source/WebCore/platform/AsyncFileSystem.h1
-rw-r--r--Source/WebCore/platform/ContentType.cpp14
-rw-r--r--Source/WebCore/platform/DefaultLocalizationStrategy.cpp376
-rw-r--r--Source/WebCore/platform/DragData.h3
-rw-r--r--Source/WebCore/platform/FileSystem.h18
-rw-r--r--Source/WebCore/platform/FloatConversion.h4
-rw-r--r--Source/WebCore/platform/KURL.h6
-rw-r--r--Source/WebCore/platform/KURLGoogle.cpp5
-rw-r--r--Source/WebCore/platform/KURLGooglePrivate.h1
-rw-r--r--Source/WebCore/platform/KURLHash.h6
-rw-r--r--Source/WebCore/platform/LocalizedStrings.h4
-rw-r--r--Source/WebCore/platform/MIMETypeRegistry.cpp8
-rw-r--r--Source/WebCore/platform/RuntimeApplicationChecks.cpp99
-rw-r--r--Source/WebCore/platform/RuntimeApplicationChecks.h (renamed from Source/WebCore/platform/mac/RuntimeApplicationChecks.h)3
-rw-r--r--Source/WebCore/platform/ScrollTypes.h6
-rw-r--r--Source/WebCore/platform/ScrollView.cpp68
-rw-r--r--Source/WebCore/platform/ScrollView.h17
-rw-r--r--Source/WebCore/platform/ScrollableArea.cpp33
-rw-r--r--Source/WebCore/platform/ScrollableArea.h30
-rw-r--r--Source/WebCore/platform/Scrollbar.cpp3
-rw-r--r--Source/WebCore/platform/Scrollbar.h2
-rw-r--r--Source/WebCore/platform/ScrollbarThemeComposite.cpp2
-rw-r--r--Source/WebCore/platform/SecureTextInput.cpp52
-rw-r--r--Source/WebCore/platform/SecureTextInput.h2
-rw-r--r--Source/WebCore/platform/TreeShared.h11
-rw-r--r--Source/WebCore/platform/audio/FFTFrame.cpp4
-rw-r--r--Source/WebCore/platform/audio/FFTFrameStub.cpp4
-rw-r--r--Source/WebCore/platform/audio/HRTFDatabaseLoader.cpp8
-rw-r--r--Source/WebCore/platform/audio/HRTFDatabaseLoader.h7
-rw-r--r--Source/WebCore/platform/audio/SincResampler.h2
-rw-r--r--Source/WebCore/platform/audio/fftw/FFTFrameFFTW.cpp4
-rw-r--r--Source/WebCore/platform/audio/mkl/FFTFrameMKL.cpp10
-rw-r--r--Source/WebCore/platform/chromium/ClipboardMimeTypes.cpp1
-rw-r--r--Source/WebCore/platform/chromium/ClipboardMimeTypes.h1
-rw-r--r--Source/WebCore/platform/chromium/DataTransferItemChromium.cpp31
-rw-r--r--Source/WebCore/platform/chromium/DataTransferItemChromium.h1
-rw-r--r--Source/WebCore/platform/chromium/PlatformBridge.h1
-rw-r--r--Source/WebCore/platform/chromium/PopupMenuChromium.cpp6
-rw-r--r--Source/WebCore/platform/efl/RenderThemeEfl.cpp41
-rw-r--r--Source/WebCore/platform/efl/RenderThemeEfl.h6
-rw-r--r--Source/WebCore/platform/graphics/ANGLEWebKitBridge.h8
-rw-r--r--Source/WebCore/platform/graphics/BitmapImage.cpp1
-rw-r--r--Source/WebCore/platform/graphics/BitmapImage.h20
-rw-r--r--Source/WebCore/platform/graphics/Color.h6
-rw-r--r--Source/WebCore/platform/graphics/ContextShadow.h8
-rw-r--r--Source/WebCore/platform/graphics/DashArray.h4
-rw-r--r--Source/WebCore/platform/graphics/Extensions3D.h5
-rw-r--r--Source/WebCore/platform/graphics/FloatPoint.cpp40
-rw-r--r--Source/WebCore/platform/graphics/FloatPoint.h9
-rw-r--r--Source/WebCore/platform/graphics/FloatRect.cpp21
-rw-r--r--Source/WebCore/platform/graphics/FloatRect.h9
-rw-r--r--Source/WebCore/platform/graphics/FloatSize.h9
-rw-r--r--Source/WebCore/platform/graphics/Font.h3
-rw-r--r--Source/WebCore/platform/graphics/FontCache.cpp17
-rw-r--r--Source/WebCore/platform/graphics/FontMetrics.h5
-rw-r--r--Source/WebCore/platform/graphics/FontPlatformData.h42
-rw-r--r--Source/WebCore/platform/graphics/FontSelector.h11
-rw-r--r--Source/WebCore/platform/graphics/GlyphBuffer.h20
-rw-r--r--Source/WebCore/platform/graphics/GlyphPageTreeNode.cpp3
-rw-r--r--Source/WebCore/platform/graphics/Gradient.cpp4
-rw-r--r--Source/WebCore/platform/graphics/Gradient.h6
-rw-r--r--Source/WebCore/platform/graphics/GraphicsContext.cpp32
-rw-r--r--Source/WebCore/platform/graphics/GraphicsContext.h45
-rw-r--r--Source/WebCore/platform/graphics/GraphicsContext3D.h37
-rw-r--r--Source/WebCore/platform/graphics/Image.cpp2
-rw-r--r--Source/WebCore/platform/graphics/Image.h5
-rw-r--r--Source/WebCore/platform/graphics/ImageBuffer.cpp4
-rw-r--r--Source/WebCore/platform/graphics/ImageBuffer.h11
-rw-r--r--Source/WebCore/platform/graphics/ImageBufferData.h40
-rw-r--r--Source/WebCore/platform/graphics/ImageSource.h8
-rw-r--r--Source/WebCore/platform/graphics/IntPoint.h4
-rw-r--r--Source/WebCore/platform/graphics/IntRect.cpp21
-rw-r--r--Source/WebCore/platform/graphics/IntRect.h12
-rw-r--r--Source/WebCore/platform/graphics/IntSize.h4
-rw-r--r--Source/WebCore/platform/graphics/MediaPlayer.cpp13
-rw-r--r--Source/WebCore/platform/graphics/MediaPlayer.h5
-rw-r--r--Source/WebCore/platform/graphics/Path.cpp5
-rw-r--r--Source/WebCore/platform/graphics/Path.h6
-rw-r--r--Source/WebCore/platform/graphics/Pattern.h4
-rw-r--r--Source/WebCore/platform/graphics/RoundedIntRect.cpp26
-rw-r--r--Source/WebCore/platform/graphics/RoundedIntRect.h13
-rw-r--r--Source/WebCore/platform/graphics/ShadowBlur.cpp265
-rw-r--r--Source/WebCore/platform/graphics/ShadowBlur.h4
-rw-r--r--Source/WebCore/platform/graphics/SimpleFontData.h6
-rw-r--r--Source/WebCore/platform/graphics/WOFFFileFormat.cpp4
-rw-r--r--Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp58
-rw-r--r--Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h26
-rw-r--r--Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundationObjC.h5
-rw-r--r--Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundationObjC.mm58
-rw-r--r--Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp14
-rw-r--r--Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h5
-rw-r--r--Source/WebCore/platform/graphics/ca/TransformationMatrixCA.cpp4
-rw-r--r--Source/WebCore/platform/graphics/ca/win/AbstractCACFLayerTreeHost.h52
-rw-r--r--Source/WebCore/platform/graphics/ca/win/CACFLayerTreeHost.h20
-rw-r--r--Source/WebCore/platform/graphics/ca/win/LayerChangesFlusher.cpp14
-rw-r--r--Source/WebCore/platform/graphics/ca/win/LayerChangesFlusher.h8
-rw-r--r--Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.cpp16
-rw-r--r--Source/WebCore/platform/graphics/ca/win/WKCACFViewLayerTreeHost.cpp17
-rw-r--r--Source/WebCore/platform/graphics/cairo/CairoPath.h50
-rw-r--r--Source/WebCore/platform/graphics/cairo/CairoUtilities.cpp2
-rw-r--r--Source/WebCore/platform/graphics/cairo/ContextShadowCairo.cpp17
-rw-r--r--Source/WebCore/platform/graphics/cairo/DrawErrorUnderline.h2
-rw-r--r--Source/WebCore/platform/graphics/cairo/GraphicsContext3DCairo.cpp120
-rw-r--r--Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp53
-rw-r--r--Source/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h24
-rw-r--r--Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp11
-rw-r--r--Source/WebCore/platform/graphics/cairo/ImageBufferDataCairo.h (renamed from Source/WebCore/platform/graphics/cairo/ImageBufferData.h)7
-rw-r--r--Source/WebCore/platform/graphics/cairo/ImageCairo.cpp4
-rw-r--r--Source/WebCore/platform/graphics/cairo/OpenGLShims.cpp191
-rw-r--r--Source/WebCore/platform/graphics/cairo/OpenGLShims.h315
-rw-r--r--Source/WebCore/platform/graphics/cairo/PathCairo.cpp2
-rw-r--r--Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp47
-rw-r--r--Source/WebCore/platform/graphics/cairo/PlatformContextCairo.h25
-rw-r--r--Source/WebCore/platform/graphics/cairo/PlatformPathCairo.cpp39
-rw-r--r--Source/WebCore/platform/graphics/cairo/PlatformPathCairo.h43
-rw-r--r--Source/WebCore/platform/graphics/cairo/RefPtrCairo.cpp2
-rw-r--r--Source/WebCore/platform/graphics/cg/ColorCG.cpp4
-rw-r--r--Source/WebCore/platform/graphics/cg/FloatPointCG.cpp4
-rw-r--r--Source/WebCore/platform/graphics/cg/FloatRectCG.cpp4
-rw-r--r--Source/WebCore/platform/graphics/cg/FloatSizeCG.cpp4
-rw-r--r--Source/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp14
-rw-r--r--Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp32
-rw-r--r--Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp199
-rw-r--r--Source/WebCore/platform/graphics/cg/ImageBufferDataCG.cpp387
-rw-r--r--Source/WebCore/platform/graphics/cg/ImageBufferDataCG.h (renamed from Source/WebCore/platform/graphics/cg/ImageBufferData.h)16
-rw-r--r--Source/WebCore/platform/graphics/cg/ImageCG.cpp24
-rw-r--r--Source/WebCore/platform/graphics/cg/ImageSourceCG.cpp4
-rw-r--r--Source/WebCore/platform/graphics/cg/IntPointCG.cpp4
-rw-r--r--Source/WebCore/platform/graphics/cg/IntRectCG.cpp4
-rw-r--r--Source/WebCore/platform/graphics/cg/IntSizeCG.cpp4
-rw-r--r--Source/WebCore/platform/graphics/cg/PDFDocumentImage.cpp4
-rw-r--r--Source/WebCore/platform/graphics/cg/PDFDocumentImage.h4
-rw-r--r--Source/WebCore/platform/graphics/cg/PathCG.cpp4
-rw-r--r--Source/WebCore/platform/graphics/cg/TransformationMatrixCG.cpp4
-rw-r--r--Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp23
-rw-r--r--Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h2
-rw-r--r--Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp317
-rw-r--r--Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h38
-rw-r--r--Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp25
-rw-r--r--Source/WebCore/platform/graphics/chromium/Extensions3DChromium.h7
-rw-r--r--Source/WebCore/platform/graphics/chromium/FontChromiumWin.cpp60
-rw-r--r--Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp2
-rw-r--r--Source/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp19
-rw-r--r--Source/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.h2
-rw-r--r--Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp154
-rw-r--r--Source/WebCore/platform/graphics/chromium/GLES2Canvas.h5
-rw-r--r--Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp2
-rw-r--r--Source/WebCore/platform/graphics/chromium/ImageBufferDataSkia.h (renamed from Source/WebCore/platform/graphics/chromium/ImageBufferData.h)9
-rw-r--r--Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp62
-rw-r--r--Source/WebCore/platform/graphics/chromium/ImageLayerChromium.h11
-rw-r--r--Source/WebCore/platform/graphics/chromium/LayerChromium.cpp3
-rw-r--r--Source/WebCore/platform/graphics/chromium/LayerChromium.h10
-rw-r--r--Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp287
-rw-r--r--Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h47
-rw-r--r--Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp84
-rw-r--r--Source/WebCore/platform/graphics/chromium/LayerTilerChromium.h24
-rw-r--r--Source/WebCore/platform/graphics/chromium/PlatformCanvas.cpp18
-rw-r--r--Source/WebCore/platform/graphics/chromium/PlatformCanvas.h14
-rw-r--r--Source/WebCore/platform/graphics/chromium/PlatformImage.cpp6
-rw-r--r--Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp2
-rw-r--r--Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h4
-rw-r--r--Source/WebCore/platform/graphics/chromium/TransparencyWin.cpp8
-rw-r--r--Source/WebCore/platform/graphics/chromium/UniscribeHelper.cpp114
-rw-r--r--Source/WebCore/platform/graphics/chromium/UniscribeHelper.h14
-rw-r--r--Source/WebCore/platform/graphics/chromium/UniscribeHelperTextRun.cpp5
-rw-r--r--Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp2
-rw-r--r--Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp30
-rw-r--r--Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h5
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.cpp3
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.h3
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCCompletionEvent.h62
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp142
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.h13
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp7
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h4
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCMainThread.cpp46
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCMainThread.h53
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCMainThreadTask.h220
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.cpp3
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.h3
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCThread.cpp79
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCThread.h75
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCThreadTask.h279
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.cpp3
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.h3
-rw-r--r--Source/WebCore/platform/graphics/filters/FEFlood.cpp10
-rw-r--r--Source/WebCore/platform/graphics/filters/FEFlood.h4
-rw-r--r--Source/WebCore/platform/graphics/filters/FELighting.cpp123
-rw-r--r--Source/WebCore/platform/graphics/filters/FELighting.h5
-rw-r--r--Source/WebCore/platform/graphics/filters/FESpecularLighting.cpp5
-rw-r--r--Source/WebCore/platform/graphics/filters/FESpecularLighting.h2
-rw-r--r--Source/WebCore/platform/graphics/filters/arm/FELightingNEON.cpp464
-rw-r--r--Source/WebCore/platform/graphics/filters/arm/FELightingNEON.h96
-rw-r--r--Source/WebCore/platform/graphics/gpu/BicubicShader.cpp9
-rw-r--r--Source/WebCore/platform/graphics/gpu/ConvolutionShader.cpp9
-rw-r--r--Source/WebCore/platform/graphics/gpu/DrawingBuffer.cpp188
-rw-r--r--Source/WebCore/platform/graphics/gpu/DrawingBuffer.h7
-rw-r--r--Source/WebCore/platform/graphics/gpu/LoopBlinnMathUtils.cpp102
-rw-r--r--Source/WebCore/platform/graphics/gpu/LoopBlinnMathUtils.h3
-rw-r--r--Source/WebCore/platform/graphics/gpu/Shader.cpp6
-rw-r--r--Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp8
-rw-r--r--Source/WebCore/platform/graphics/gpu/SolidFillShader.cpp2
-rw-r--r--Source/WebCore/platform/graphics/gpu/TexShader.cpp2
-rw-r--r--Source/WebCore/platform/graphics/gpu/TilingData.cpp3
-rw-r--r--Source/WebCore/platform/graphics/gstreamer/ImageGStreamer.h4
-rw-r--r--Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp493
-rw-r--r--Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h51
-rw-r--r--Source/WebCore/platform/graphics/gstreamer/PlatformVideoWindowPrivate.h20
-rw-r--r--Source/WebCore/platform/graphics/gstreamer/PlatformVideoWindowQt.cpp59
-rw-r--r--Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp2
-rw-r--r--Source/WebCore/platform/graphics/gtk/DrawingBufferGtk.cpp93
-rw-r--r--Source/WebCore/platform/graphics/gtk/FontGtk.cpp103
-rw-r--r--Source/WebCore/platform/graphics/gtk/GraphicsContext3DGtk.cpp158
-rw-r--r--Source/WebCore/platform/graphics/gtk/GraphicsContext3DInternal.cpp254
-rw-r--r--Source/WebCore/platform/graphics/gtk/GraphicsContext3DInternal.h58
-rw-r--r--Source/WebCore/platform/graphics/haiku/ImageBufferDataHaiku.h (renamed from Source/WebCore/platform/graphics/haiku/ImageBufferData.h)6
-rw-r--r--Source/WebCore/platform/graphics/mac/ComplexTextController.h7
-rw-r--r--Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.cpp19
-rw-r--r--Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm2
-rw-r--r--Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm2
-rw-r--r--Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp21
-rw-r--r--Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h1
-rw-r--r--Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp10
-rw-r--r--Source/WebCore/platform/graphics/opengl/TextureMapperGL.cpp4
-rw-r--r--Source/WebCore/platform/graphics/opentype/OpenTypeUtilities.cpp2
-rw-r--r--Source/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp2
-rw-r--r--Source/WebCore/platform/graphics/pango/FontPlatformData.h1
-rw-r--r--Source/WebCore/platform/graphics/qt/Extensions3DQt.cpp5
-rw-r--r--Source/WebCore/platform/graphics/qt/Extensions3DQt.h1
-rw-r--r--Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp10
-rw-r--r--Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp2
-rw-r--r--Source/WebCore/platform/graphics/qt/ImageBufferDataQt.h (renamed from Source/WebCore/platform/graphics/qt/ImageBufferData.h)12
-rw-r--r--Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp12
-rw-r--r--Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp28
-rw-r--r--Source/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp17
-rw-r--r--Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp41
-rw-r--r--Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp14
-rw-r--r--Source/WebCore/platform/graphics/skia/ImageSkia.cpp17
-rw-r--r--Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp25
-rw-r--r--Source/WebCore/platform/graphics/skia/PlatformContextSkia.h29
-rw-r--r--Source/WebCore/platform/graphics/skia/SkiaFontWin.cpp117
-rw-r--r--Source/WebCore/platform/graphics/skia/SkiaFontWin.h4
-rw-r--r--Source/WebCore/platform/graphics/transforms/AffineTransform.h8
-rw-r--r--Source/WebCore/platform/graphics/transforms/TransformationMatrix.h12
-rw-r--r--Source/WebCore/platform/graphics/win/DIBPixelData.cpp87
-rw-r--r--Source/WebCore/platform/graphics/win/DIBPixelData.h72
-rw-r--r--Source/WebCore/platform/graphics/win/FontCacheWin.cpp10
-rw-r--r--Source/WebCore/platform/graphics/win/FontPlatformDataWin.cpp4
-rw-r--r--Source/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp28
-rw-r--r--Source/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp71
-rw-r--r--Source/WebCore/platform/graphics/win/GraphicsContextWin.cpp17
-rw-r--r--Source/WebCore/platform/graphics/win/MediaPlayerPrivateFullscreenWindow.cpp2
-rw-r--r--Source/WebCore/platform/graphics/win/SimpleFontDataWin.cpp2
-rw-r--r--Source/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp2
-rw-r--r--Source/WebCore/platform/graphics/wince/ImageBufferDataWince.h (renamed from Source/WebCore/platform/graphics/wince/ImageBufferData.h)5
-rw-r--r--Source/WebCore/platform/graphics/wx/FontPlatformDataWx.cpp4
-rw-r--r--Source/WebCore/platform/graphics/wx/GraphicsContextWx.cpp2
-rw-r--r--Source/WebCore/platform/graphics/wx/ImageBufferDataWx.h (renamed from Source/WebCore/platform/graphics/wx/ImageBufferData.h)8
-rw-r--r--Source/WebCore/platform/gtk/GtkVersioning.c10
-rw-r--r--Source/WebCore/platform/gtk/GtkVersioning.h4
-rw-r--r--Source/WebCore/platform/gtk/LocalizedStringsGtk.cpp5
-rw-r--r--Source/WebCore/platform/gtk/PlatformKeyboardEventGtk.cpp (renamed from Source/WebCore/platform/gtk/KeyEventGtk.cpp)0
-rw-r--r--Source/WebCore/platform/gtk/PlatformMouseEventGtk.cpp (renamed from Source/WebCore/platform/gtk/MouseEventGtk.cpp)0
-rw-r--r--Source/WebCore/platform/gtk/PlatformWheelEventGtk.cpp (renamed from Source/WebCore/platform/gtk/WheelEventGtk.cpp)0
-rw-r--r--Source/WebCore/platform/gtk/RenderThemeGtk.h1
-rw-r--r--Source/WebCore/platform/gtk/RenderThemeGtk3.cpp41
-rw-r--r--Source/WebCore/platform/gtk/ScrollbarThemeGtk3.cpp15
-rw-r--r--Source/WebCore/platform/image-decoders/ImageDecoder.cpp2
-rw-r--r--Source/WebCore/platform/image-decoders/ImageDecoder.h2
-rw-r--r--Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.cpp57
-rw-r--r--Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.h7
-rw-r--r--Source/WebCore/platform/leveldb/LevelDBComparator.h48
-rw-r--r--Source/WebCore/platform/leveldb/LevelDBDatabase.cpp159
-rw-r--r--Source/WebCore/platform/leveldb/LevelDBDatabase.h66
-rw-r--r--Source/WebCore/platform/leveldb/LevelDBIterator.cpp (renamed from Source/WebCore/platform/mac/RuntimeApplicationChecks.mm)74
-rw-r--r--Source/WebCore/platform/leveldb/LevelDBIterator.h65
-rw-r--r--Source/WebCore/platform/leveldb/LevelDBSlice.h67
-rw-r--r--Source/WebCore/platform/mac/ClipboardMac.mm2
-rw-r--r--Source/WebCore/platform/mac/DragDataMac.mm4
-rw-r--r--Source/WebCore/platform/mac/HTMLConverter.h11
-rw-r--r--Source/WebCore/platform/mac/HTMLConverter.mm168
-rw-r--r--Source/WebCore/platform/mac/PasteboardMac.mm18
-rw-r--r--Source/WebCore/platform/mac/ScrollAnimatorMac.h2
-rw-r--r--Source/WebCore/platform/mac/ScrollAnimatorMac.mm90
-rw-r--r--Source/WebCore/platform/mac/WebCoreSystemInterface.h16
-rw-r--r--Source/WebCore/platform/mac/WebCoreSystemInterface.mm6
-rw-r--r--Source/WebCore/platform/mac/WebNSAttributedStringExtras.h30
-rw-r--r--Source/WebCore/platform/mac/WebNSAttributedStringExtras.mm59
-rw-r--r--Source/WebCore/platform/mac/WheelEventMac.mm22
-rw-r--r--Source/WebCore/platform/network/BlobResourceHandle.cpp2
-rw-r--r--Source/WebCore/platform/network/MIMESniffing.cpp495
-rw-r--r--Source/WebCore/platform/network/MIMESniffing.h41
-rw-r--r--Source/WebCore/platform/network/NetworkingContext.h1
-rw-r--r--Source/WebCore/platform/network/ProtectionSpaceHash.h7
-rw-r--r--Source/WebCore/platform/network/ResourceHandleClient.h2
-rw-r--r--Source/WebCore/platform/network/ResourceHandleInternal.h2
-rw-r--r--Source/WebCore/platform/network/ResourceLoadInfo.h6
-rw-r--r--Source/WebCore/platform/network/ResourceLoadPriority.h16
-rw-r--r--Source/WebCore/platform/network/ResourceRequestBase.h9
-rw-r--r--Source/WebCore/platform/network/ResourceResponseBase.cpp124
-rw-r--r--Source/WebCore/platform/network/ResourceResponseBase.h15
-rw-r--r--Source/WebCore/platform/network/android/ResourceHandleAndroid.cpp2
-rw-r--r--Source/WebCore/platform/network/cf/ResourceHandleCFNet.cpp4
-rw-r--r--Source/WebCore/platform/network/cf/ResourceRequest.h5
-rw-r--r--Source/WebCore/platform/network/cf/ResourceRequestCFNet.cpp36
-rw-r--r--Source/WebCore/platform/network/cf/ResourceRequestCFNet.h23
-rw-r--r--Source/WebCore/platform/network/cf/ResourceResponse.h16
-rw-r--r--Source/WebCore/platform/network/cf/ResourceResponseCFNet.cpp89
-rw-r--r--Source/WebCore/platform/network/curl/ResourceHandleCurl.cpp2
-rw-r--r--Source/WebCore/platform/network/mac/ResourceHandleMac.mm4
-rw-r--r--Source/WebCore/platform/network/mac/ResourceRequestMac.mm10
-rw-r--r--Source/WebCore/platform/network/mac/ResourceResponseMac.mm70
-rw-r--r--Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp291
-rw-r--r--Source/WebCore/platform/network/qt/QNetworkReplyHandler.h75
-rw-r--r--Source/WebCore/platform/network/qt/QtMIMETypeSniffer.cpp63
-rw-r--r--Source/WebCore/platform/network/qt/QtMIMETypeSniffer.h50
-rw-r--r--Source/WebCore/platform/network/qt/ResourceHandleQt.cpp86
-rw-r--r--Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp7
-rw-r--r--Source/WebCore/platform/network/win/ResourceHandleWin.cpp2
-rw-r--r--Source/WebCore/platform/qt/ClipboardQt.cpp1
-rw-r--r--Source/WebCore/platform/qt/QtMobileWebStyle.cpp118
-rw-r--r--Source/WebCore/platform/qt/QtMobileWebStyle.h5
-rw-r--r--Source/WebCore/platform/qt/RenderThemeQt.cpp84
-rw-r--r--Source/WebCore/platform/qt/RenderThemeQt.h2
-rw-r--r--Source/WebCore/platform/qt/ScrollbarThemeQt.cpp7
-rw-r--r--Source/WebCore/platform/text/BidiResolver.h238
-rw-r--r--Source/WebCore/platform/text/BidiRunList.h209
-rw-r--r--Source/WebCore/platform/text/LocalizedNumberICU.cpp1
-rw-r--r--Source/WebCore/platform/text/StringWithDirection.h79
-rw-r--r--Source/WebCore/platform/text/TextCheckerClient.h15
-rw-r--r--Source/WebCore/platform/text/TextChecking.h12
-rw-r--r--Source/WebCore/platform/text/UnicodeBidi.h40
-rw-r--r--Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp2
-rw-r--r--Source/WebCore/platform/win/ClipboardWin.cpp2
-rw-r--r--Source/WebCore/platform/win/DragImageCairoWin.cpp51
-rw-r--r--Source/WebCore/platform/win/FileSystemWin.cpp9
-rw-r--r--Source/WebCore/platform/win/LocalizedStringsWin.cpp54
-rw-r--r--Source/WebCore/platform/win/LoggingWin.cpp3
-rw-r--r--Source/WebCore/platform/win/PopupMenuWin.h4
-rw-r--r--Source/WebCore/platform/win/WindowsTouch.h112
-rw-r--r--Source/WebCore/platform/wx/FileSystemWx.cpp29
-rw-r--r--Source/WebCore/platform/wx/WidgetWx.cpp8
342 files changed, 9745 insertions, 3146 deletions
diff --git a/Source/WebCore/platform/AsyncFileSystem.h b/Source/WebCore/platform/AsyncFileSystem.h
index f5207ce..3570de4 100644
--- a/Source/WebCore/platform/AsyncFileSystem.h
+++ b/Source/WebCore/platform/AsyncFileSystem.h
@@ -53,6 +53,7 @@ public:
enum Type {
Temporary,
Persistent,
+ External,
};
virtual void stop() { }
diff --git a/Source/WebCore/platform/ContentType.cpp b/Source/WebCore/platform/ContentType.cpp
index c094d54..b02bc7c 100644
--- a/Source/WebCore/platform/ContentType.cpp
+++ b/Source/WebCore/platform/ContentType.cpp
@@ -45,11 +45,17 @@ String ContentType::parameter(const String& parameterName) const
if (semi != notFound) {
size_t start = strippedType.find(parameterName, semi + 1, false);
if (start != notFound) {
- start = strippedType.find('=', start + 6);
+ start = strippedType.find('=', start + parameterName.length());
if (start != notFound) {
- size_t end = strippedType.find(';', start + 6);
- if (end == notFound)
- end = strippedType.length();
+ size_t quote = strippedType.find('\"', start + 1);
+ size_t end = strippedType.find('\"', start + 2);
+ if (quote != notFound && end != notFound)
+ start = quote;
+ else {
+ end = strippedType.find(';', start + 1);
+ if (end == notFound)
+ end = strippedType.length();
+ }
parameterValue = strippedType.substring(start + 1, end - (start + 1)).stripWhiteSpace();
}
}
diff --git a/Source/WebCore/platform/DefaultLocalizationStrategy.cpp b/Source/WebCore/platform/DefaultLocalizationStrategy.cpp
index 1a50c3c..0a7dd42 100644
--- a/Source/WebCore/platform/DefaultLocalizationStrategy.cpp
+++ b/Source/WebCore/platform/DefaultLocalizationStrategy.cpp
@@ -74,44 +74,44 @@ DefaultLocalizationStrategy::DefaultLocalizationStrategy()
String DefaultLocalizationStrategy::inputElementAltText()
{
- return UI_STRING_KEY("Submit", "Submit (input element)", "alt text for <input> elements with no alt, title, or value");
+ return WEB_UI_STRING_KEY("Submit", "Submit (input element)", "alt text for <input> elements with no alt, title, or value");
}
String DefaultLocalizationStrategy::resetButtonDefaultLabel()
{
- return UI_STRING("Reset", "default label for Reset buttons in forms on web pages");
+ return WEB_UI_STRING("Reset", "default label for Reset buttons in forms on web pages");
}
String DefaultLocalizationStrategy::searchableIndexIntroduction()
{
- return UI_STRING("This is a searchable index. Enter search keywords: ",
+ return WEB_UI_STRING("This is a searchable index. Enter search keywords: ",
"text that appears at the start of nearly-obsolete web pages in the form of a 'searchable index'");
}
String DefaultLocalizationStrategy::submitButtonDefaultLabel()
{
- return UI_STRING("Submit", "default label for Submit buttons in forms on web pages");
+ return WEB_UI_STRING("Submit", "default label for Submit buttons in forms on web pages");
}
String DefaultLocalizationStrategy::fileButtonChooseFileLabel()
{
- return UI_STRING("Choose File", "title for file button used in HTML forms");
+ return WEB_UI_STRING("Choose File", "title for file button used in HTML forms");
}
String DefaultLocalizationStrategy::fileButtonNoFileSelectedLabel()
{
- return UI_STRING("no file selected", "text to display in file button used in HTML forms when no file is selected");
+ return WEB_UI_STRING("no file selected", "text to display in file button used in HTML forms when no file is selected");
}
String DefaultLocalizationStrategy::defaultDetailsSummaryText()
{
- return UI_STRING("Details", "text to display in <details> tag when it has no <summary> child");
+ return WEB_UI_STRING("Details", "text to display in <details> tag when it has no <summary> child");
}
#if PLATFORM(MAC)
String DefaultLocalizationStrategy::copyImageUnknownFileLabel()
{
- return UI_STRING("unknown", "Unknown filename");
+ return WEB_UI_STRING("unknown", "Unknown filename");
}
#endif
@@ -119,129 +119,129 @@ String DefaultLocalizationStrategy::copyImageUnknownFileLabel()
String DefaultLocalizationStrategy::contextMenuItemTagOpenLinkInNewWindow()
{
- return UI_STRING("Open Link in New Window", "Open in New Window context menu item");
+ return WEB_UI_STRING("Open Link in New Window", "Open in New Window context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagDownloadLinkToDisk()
{
- return UI_STRING("Download Linked File", "Download Linked File context menu item");
+ return WEB_UI_STRING("Download Linked File", "Download Linked File context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagCopyLinkToClipboard()
{
- return UI_STRING("Copy Link", "Copy Link context menu item");
+ return WEB_UI_STRING("Copy Link", "Copy Link context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagOpenImageInNewWindow()
{
- return UI_STRING("Open Image in New Window", "Open Image in New Window context menu item");
+ return WEB_UI_STRING("Open Image in New Window", "Open Image in New Window context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagDownloadImageToDisk()
{
- return UI_STRING("Download Image", "Download Image context menu item");
+ return WEB_UI_STRING("Download Image", "Download Image context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagCopyImageToClipboard()
{
- return UI_STRING("Copy Image", "Copy Image context menu item");
+ return WEB_UI_STRING("Copy Image", "Copy Image context menu item");
}
#if PLATFORM(QT)
String DefaultLocalizationStrategy::contextMenuItemTagCopyImageUrlToClipboard()
{
- return UI_STRING("Copy Image Address", "Copy Image Address menu item");
+ return WEB_UI_STRING("Copy Image Address", "Copy Image Address menu item");
}
#endif
String DefaultLocalizationStrategy::contextMenuItemTagOpenVideoInNewWindow()
{
- return UI_STRING("Open Video in New Window", "Open Video in New Window context menu item");
+ return WEB_UI_STRING("Open Video in New Window", "Open Video in New Window context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagOpenAudioInNewWindow()
{
- return UI_STRING("Open Audio in New Window", "Open Audio in New Window context menu item");
+ return WEB_UI_STRING("Open Audio in New Window", "Open Audio in New Window context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagCopyVideoLinkToClipboard()
{
- return UI_STRING("Copy Video Address", "Copy Video Address Location context menu item");
+ return WEB_UI_STRING("Copy Video Address", "Copy Video Address Location context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagCopyAudioLinkToClipboard()
{
- return UI_STRING("Copy Audio Address", "Copy Audio Address Location context menu item");
+ return WEB_UI_STRING("Copy Audio Address", "Copy Audio Address Location context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagToggleMediaControls()
{
- return UI_STRING("Controls", "Media Controls context menu item");
+ return WEB_UI_STRING("Controls", "Media Controls context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagToggleMediaLoop()
{
- return UI_STRING("Loop", "Media Loop context menu item");
+ return WEB_UI_STRING("Loop", "Media Loop context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagEnterVideoFullscreen()
{
- return UI_STRING("Enter Fullscreen", "Video Enter Fullscreen context menu item");
+ return WEB_UI_STRING("Enter Fullscreen", "Video Enter Fullscreen context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagMediaPlay()
{
- return UI_STRING("Play", "Media Play context menu item");
+ return WEB_UI_STRING("Play", "Media Play context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagMediaPause()
{
- return UI_STRING("Pause", "Media Pause context menu item");
+ return WEB_UI_STRING("Pause", "Media Pause context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagMediaMute()
{
- return UI_STRING("Mute", "Media Mute context menu item");
+ return WEB_UI_STRING("Mute", "Media Mute context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagOpenFrameInNewWindow()
{
- return UI_STRING("Open Frame in New Window", "Open Frame in New Window context menu item");
+ return WEB_UI_STRING("Open Frame in New Window", "Open Frame in New Window context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagCopy()
{
- return UI_STRING("Copy", "Copy context menu item");
+ return WEB_UI_STRING("Copy", "Copy context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagGoBack()
{
- return UI_STRING("Back", "Back context menu item");
+ return WEB_UI_STRING("Back", "Back context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagGoForward()
{
- return UI_STRING("Forward", "Forward context menu item");
+ return WEB_UI_STRING("Forward", "Forward context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagStop()
{
- return UI_STRING("Stop", "Stop context menu item");
+ return WEB_UI_STRING("Stop", "Stop context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagReload()
{
- return UI_STRING("Reload", "Reload context menu item");
+ return WEB_UI_STRING("Reload", "Reload context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagCut()
{
- return UI_STRING("Cut", "Cut context menu item");
+ return WEB_UI_STRING("Cut", "Cut context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagPaste()
{
- return UI_STRING("Paste", "Paste context menu item");
+ return WEB_UI_STRING("Paste", "Paste context menu item");
}
#if PLATFORM(GTK)
@@ -278,218 +278,223 @@ String DefaultLocalizationStrategy::contextMenuItemTagSelectAll()
String DefaultLocalizationStrategy::contextMenuItemTagNoGuessesFound()
{
- return UI_STRING("No Guesses Found", "No Guesses Found context menu item");
+ return WEB_UI_STRING("No Guesses Found", "No Guesses Found context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagIgnoreSpelling()
{
- return UI_STRING("Ignore Spelling", "Ignore Spelling context menu item");
+ return WEB_UI_STRING("Ignore Spelling", "Ignore Spelling context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagLearnSpelling()
{
- return UI_STRING("Learn Spelling", "Learn Spelling context menu item");
+ return WEB_UI_STRING("Learn Spelling", "Learn Spelling context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagSearchWeb()
{
- return UI_STRING("Search in Google", "Search in Google context menu item");
+ return WEB_UI_STRING("Search in Google", "Search in Google context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagLookUpInDictionary(const String& selectedString)
{
#if defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD) || defined(BUILDING_ON_SNOW_LEOPARD)
UNUSED_PARAM(selectedString);
- return UI_STRING("Look Up in Dictionary", "Look Up in Dictionary context menu item");
+ return WEB_UI_STRING("Look Up in Dictionary", "Look Up in Dictionary context menu item");
#else
- return UI_STRING("Look Up “<selection>”", "Look Up context menu item with selected word").replace("<selection>", selectedString);
+#if USE(CF)
+ RetainPtr<CFStringRef> selectedCFString(AdoptCF, selectedString.createCFString());
+ return formatLocalizedString(WEB_UI_STRING("Look Up “%@”", "Look Up context menu item with selected word"), selectedCFString.get());
+#else
+ return WEB_UI_STRING("Look Up “<selection>”", "Look Up context menu item with selected word").replace("<selection>", selectedString);
+#endif
#endif
}
String DefaultLocalizationStrategy::contextMenuItemTagOpenLink()
{
- return UI_STRING("Open Link", "Open Link context menu item");
+ return WEB_UI_STRING("Open Link", "Open Link context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagIgnoreGrammar()
{
- return UI_STRING("Ignore Grammar", "Ignore Grammar context menu item");
+ return WEB_UI_STRING("Ignore Grammar", "Ignore Grammar context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagSpellingMenu()
{
- return UI_STRING("Spelling and Grammar", "Spelling and Grammar context sub-menu item");
+ return WEB_UI_STRING("Spelling and Grammar", "Spelling and Grammar context sub-menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagShowSpellingPanel(bool show)
{
if (show)
- return UI_STRING("Show Spelling and Grammar", "menu item title");
- return UI_STRING("Hide Spelling and Grammar", "menu item title");
+ return WEB_UI_STRING("Show Spelling and Grammar", "menu item title");
+ return WEB_UI_STRING("Hide Spelling and Grammar", "menu item title");
}
String DefaultLocalizationStrategy::contextMenuItemTagCheckSpelling()
{
- return UI_STRING("Check Document Now", "Check spelling context menu item");
+ return WEB_UI_STRING("Check Document Now", "Check spelling context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagCheckSpellingWhileTyping()
{
- return UI_STRING("Check Spelling While Typing", "Check spelling while typing context menu item");
+ return WEB_UI_STRING("Check Spelling While Typing", "Check spelling while typing context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagCheckGrammarWithSpelling()
{
- return UI_STRING("Check Grammar With Spelling", "Check grammar with spelling context menu item");
+ return WEB_UI_STRING("Check Grammar With Spelling", "Check grammar with spelling context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagFontMenu()
{
- return UI_STRING("Font", "Font context sub-menu item");
+ return WEB_UI_STRING("Font", "Font context sub-menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagBold()
{
- return UI_STRING("Bold", "Bold context menu item");
+ return WEB_UI_STRING("Bold", "Bold context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagItalic()
{
- return UI_STRING("Italic", "Italic context menu item");
+ return WEB_UI_STRING("Italic", "Italic context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagUnderline()
{
- return UI_STRING("Underline", "Underline context menu item");
+ return WEB_UI_STRING("Underline", "Underline context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagOutline()
{
- return UI_STRING("Outline", "Outline context menu item");
+ return WEB_UI_STRING("Outline", "Outline context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagWritingDirectionMenu()
{
- return UI_STRING("Paragraph Direction", "Paragraph direction context sub-menu item");
+ return WEB_UI_STRING("Paragraph Direction", "Paragraph direction context sub-menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagTextDirectionMenu()
{
- return UI_STRING("Selection Direction", "Selection direction context sub-menu item");
+ return WEB_UI_STRING("Selection Direction", "Selection direction context sub-menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagDefaultDirection()
{
- return UI_STRING("Default", "Default writing direction context menu item");
+ return WEB_UI_STRING("Default", "Default writing direction context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagLeftToRight()
{
- return UI_STRING("Left to Right", "Left to Right context menu item");
+ return WEB_UI_STRING("Left to Right", "Left to Right context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagRightToLeft()
{
- return UI_STRING("Right to Left", "Right to Left context menu item");
+ return WEB_UI_STRING("Right to Left", "Right to Left context menu item");
}
#if PLATFORM(MAC)
String DefaultLocalizationStrategy::contextMenuItemTagSearchInSpotlight()
{
- return UI_STRING("Search in Spotlight", "Search in Spotlight context menu item");
+ return WEB_UI_STRING("Search in Spotlight", "Search in Spotlight context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagShowFonts()
{
- return UI_STRING("Show Fonts", "Show fonts context menu item");
+ return WEB_UI_STRING("Show Fonts", "Show fonts context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagStyles()
{
- return UI_STRING("Styles...", "Styles context menu item");
+ return WEB_UI_STRING("Styles...", "Styles context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagShowColors()
{
- return UI_STRING("Show Colors", "Show colors context menu item");
+ return WEB_UI_STRING("Show Colors", "Show colors context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagSpeechMenu()
{
- return UI_STRING("Speech", "Speech context sub-menu item");
+ return WEB_UI_STRING("Speech", "Speech context sub-menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagStartSpeaking()
{
- return UI_STRING("Start Speaking", "Start speaking context menu item");
+ return WEB_UI_STRING("Start Speaking", "Start speaking context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagStopSpeaking()
{
- return UI_STRING("Stop Speaking", "Stop speaking context menu item");
+ return WEB_UI_STRING("Stop Speaking", "Stop speaking context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagCorrectSpellingAutomatically()
{
- return UI_STRING("Correct Spelling Automatically", "Correct Spelling Automatically context menu item");
+ return WEB_UI_STRING("Correct Spelling Automatically", "Correct Spelling Automatically context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagSubstitutionsMenu()
{
- return UI_STRING("Substitutions", "Substitutions context sub-menu item");
+ return WEB_UI_STRING("Substitutions", "Substitutions context sub-menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagShowSubstitutions(bool show)
{
if (show)
- return UI_STRING("Show Substitutions", "menu item title");
- return UI_STRING("Hide Substitutions", "menu item title");
+ return WEB_UI_STRING("Show Substitutions", "menu item title");
+ return WEB_UI_STRING("Hide Substitutions", "menu item title");
}
String DefaultLocalizationStrategy::contextMenuItemTagSmartCopyPaste()
{
- return UI_STRING("Smart Copy/Paste", "Smart Copy/Paste context menu item");
+ return WEB_UI_STRING("Smart Copy/Paste", "Smart Copy/Paste context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagSmartQuotes()
{
- return UI_STRING("Smart Quotes", "Smart Quotes context menu item");
+ return WEB_UI_STRING("Smart Quotes", "Smart Quotes context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagSmartDashes()
{
- return UI_STRING("Smart Dashes", "Smart Dashes context menu item");
+ return WEB_UI_STRING("Smart Dashes", "Smart Dashes context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagSmartLinks()
{
- return UI_STRING("Smart Links", "Smart Links context menu item");
+ return WEB_UI_STRING("Smart Links", "Smart Links context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagTextReplacement()
{
- return UI_STRING("Text Replacement", "Text Replacement context menu item");
+ return WEB_UI_STRING("Text Replacement", "Text Replacement context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagTransformationsMenu()
{
- return UI_STRING("Transformations", "Transformations context sub-menu item");
+ return WEB_UI_STRING("Transformations", "Transformations context sub-menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagMakeUpperCase()
{
- return UI_STRING("Make Upper Case", "Make Upper Case context menu item");
+ return WEB_UI_STRING("Make Upper Case", "Make Upper Case context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagMakeLowerCase()
{
- return UI_STRING("Make Lower Case", "Make Lower Case context menu item");
+ return WEB_UI_STRING("Make Lower Case", "Make Lower Case context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagCapitalize()
{
- return UI_STRING("Capitalize", "Capitalize context menu item");
+ return WEB_UI_STRING("Capitalize", "Capitalize context menu item");
}
String DefaultLocalizationStrategy::contextMenuItemTagChangeBack(const String& replacedString)
@@ -502,133 +507,133 @@ String DefaultLocalizationStrategy::contextMenuItemTagChangeBack(const String& r
String DefaultLocalizationStrategy::contextMenuItemTagInspectElement()
{
- return UI_STRING("Inspect Element", "Inspect Element context menu item");
+ return WEB_UI_STRING("Inspect Element", "Inspect Element context menu item");
}
#endif // ENABLE(CONTEXT_MENUS)
String DefaultLocalizationStrategy::searchMenuNoRecentSearchesText()
{
- return UI_STRING("No recent searches", "Label for only item in menu that appears when clicking on the search field image, when no searches have been performed");
+ return WEB_UI_STRING("No recent searches", "Label for only item in menu that appears when clicking on the search field image, when no searches have been performed");
}
String DefaultLocalizationStrategy::searchMenuRecentSearchesText()
{
- return UI_STRING("Recent Searches", "label for first item in the menu that appears when clicking on the search field image, used as embedded menu title");
+ return WEB_UI_STRING("Recent Searches", "label for first item in the menu that appears when clicking on the search field image, used as embedded menu title");
}
String DefaultLocalizationStrategy::searchMenuClearRecentSearchesText()
{
- return UI_STRING("Clear Recent Searches", "menu item in Recent Searches menu that empties menu's contents");
+ return WEB_UI_STRING("Clear Recent Searches", "menu item in Recent Searches menu that empties menu's contents");
}
String DefaultLocalizationStrategy::AXWebAreaText()
{
- return UI_STRING("HTML content", "accessibility role description for web area");
+ return WEB_UI_STRING("HTML content", "accessibility role description for web area");
}
String DefaultLocalizationStrategy::AXLinkText()
{
- return UI_STRING("link", "accessibility role description for link");
+ return WEB_UI_STRING("link", "accessibility role description for link");
}
String DefaultLocalizationStrategy::AXListMarkerText()
{
- return UI_STRING("list marker", "accessibility role description for list marker");
+ return WEB_UI_STRING("list marker", "accessibility role description for list marker");
}
String DefaultLocalizationStrategy::AXImageMapText()
{
- return UI_STRING("image map", "accessibility role description for image map");
+ return WEB_UI_STRING("image map", "accessibility role description for image map");
}
String DefaultLocalizationStrategy::AXHeadingText()
{
- return UI_STRING("heading", "accessibility role description for headings");
+ return WEB_UI_STRING("heading", "accessibility role description for headings");
}
String DefaultLocalizationStrategy::AXDefinitionListTermText()
{
- return UI_STRING("term", "term word of a definition");
+ return WEB_UI_STRING("term", "term word of a definition");
}
String DefaultLocalizationStrategy::AXDefinitionListDefinitionText()
{
- return UI_STRING("definition", "definition phrase");
+ return WEB_UI_STRING("definition", "definition phrase");
}
#if PLATFORM(MAC)
String DefaultLocalizationStrategy::AXARIAContentGroupText(const String& ariaType)
{
if (ariaType == "ARIAApplicationAlert")
- return UI_STRING("alert", "An ARIA accessibility group that acts as an alert.");
+ return WEB_UI_STRING("alert", "An ARIA accessibility group that acts as an alert.");
if (ariaType == "ARIAApplicationAlertDialog")
- return UI_STRING("alert dialog", "An ARIA accessibility group that acts as an alert dialog.");
+ return WEB_UI_STRING("alert dialog", "An ARIA accessibility group that acts as an alert dialog.");
if (ariaType == "ARIAApplicationDialog")
- return UI_STRING("dialog", "An ARIA accessibility group that acts as an dialog.");
+ return WEB_UI_STRING("dialog", "An ARIA accessibility group that acts as an dialog.");
if (ariaType == "ARIAApplicationLog")
- return UI_STRING("log", "An ARIA accessibility group that acts as a console log.");
+ return WEB_UI_STRING("log", "An ARIA accessibility group that acts as a console log.");
if (ariaType == "ARIAApplicationMarquee")
- return UI_STRING("marquee", "An ARIA accessibility group that acts as a marquee.");
+ return WEB_UI_STRING("marquee", "An ARIA accessibility group that acts as a marquee.");
if (ariaType == "ARIAApplicationStatus")
- return UI_STRING("application status", "An ARIA accessibility group that acts as a status update.");
+ return WEB_UI_STRING("application status", "An ARIA accessibility group that acts as a status update.");
if (ariaType == "ARIAApplicationTimer")
- return UI_STRING("timer", "An ARIA accessibility group that acts as an updating timer.");
+ return WEB_UI_STRING("timer", "An ARIA accessibility group that acts as an updating timer.");
if (ariaType == "ARIADocument")
- return UI_STRING("document", "An ARIA accessibility group that acts as a document.");
+ return WEB_UI_STRING("document", "An ARIA accessibility group that acts as a document.");
if (ariaType == "ARIADocumentArticle")
- return UI_STRING("article", "An ARIA accessibility group that acts as an article.");
+ return WEB_UI_STRING("article", "An ARIA accessibility group that acts as an article.");
if (ariaType == "ARIADocumentNote")
- return UI_STRING("note", "An ARIA accessibility group that acts as a note in a document.");
+ return WEB_UI_STRING("note", "An ARIA accessibility group that acts as a note in a document.");
if (ariaType == "ARIADocumentRegion")
- return UI_STRING("region", "An ARIA accessibility group that acts as a distinct region in a document.");
+ return WEB_UI_STRING("region", "An ARIA accessibility group that acts as a distinct region in a document.");
if (ariaType == "ARIALandmarkApplication")
- return UI_STRING("application", "An ARIA accessibility group that acts as an application.");
+ return WEB_UI_STRING("application", "An ARIA accessibility group that acts as an application.");
if (ariaType == "ARIALandmarkBanner")
- return UI_STRING("banner", "An ARIA accessibility group that acts as a banner.");
+ return WEB_UI_STRING("banner", "An ARIA accessibility group that acts as a banner.");
if (ariaType == "ARIALandmarkComplementary")
- return UI_STRING("complementary", "An ARIA accessibility group that acts as a region of complementary information.");
+ return WEB_UI_STRING("complementary", "An ARIA accessibility group that acts as a region of complementary information.");
if (ariaType == "ARIALandmarkContentInfo")
- return UI_STRING("content", "An ARIA accessibility group that contains content.");
+ return WEB_UI_STRING("content", "An ARIA accessibility group that contains content.");
if (ariaType == "ARIALandmarkMain")
- return UI_STRING("main", "An ARIA accessibility group that is the main portion of the website.");
+ return WEB_UI_STRING("main", "An ARIA accessibility group that is the main portion of the website.");
if (ariaType == "ARIALandmarkNavigation")
- return UI_STRING("navigation", "An ARIA accessibility group that contains the main navigation elements of a website.");
+ return WEB_UI_STRING("navigation", "An ARIA accessibility group that contains the main navigation elements of a website.");
if (ariaType == "ARIALandmarkSearch")
- return UI_STRING("search", "An ARIA accessibility group that contains a search feature of a website.");
+ return WEB_UI_STRING("search", "An ARIA accessibility group that contains a search feature of a website.");
if (ariaType == "ARIAUserInterfaceTooltip")
- return UI_STRING("tooltip", "An ARIA accessibility group that acts as a tooltip.");
+ return WEB_UI_STRING("tooltip", "An ARIA accessibility group that acts as a tooltip.");
if (ariaType == "ARIATabPanel")
- return UI_STRING("tab panel", "An ARIA accessibility group that contains the content of a tab.");
+ return WEB_UI_STRING("tab panel", "An ARIA accessibility group that contains the content of a tab.");
if (ariaType == "ARIADocumentMath")
- return UI_STRING("math", "An ARIA accessibility group that contains mathematical symbols.");
+ return WEB_UI_STRING("math", "An ARIA accessibility group that contains mathematical symbols.");
return String();
}
#endif
String DefaultLocalizationStrategy::AXButtonActionVerb()
{
- return UI_STRING("press", "Verb stating the action that will occur when a button is pressed, as used by accessibility");
+ return WEB_UI_STRING("press", "Verb stating the action that will occur when a button is pressed, as used by accessibility");
}
String DefaultLocalizationStrategy::AXRadioButtonActionVerb()
{
- return UI_STRING("select", "Verb stating the action that will occur when a radio button is clicked, as used by accessibility");
+ return WEB_UI_STRING("select", "Verb stating the action that will occur when a radio button is clicked, as used by accessibility");
}
String DefaultLocalizationStrategy::AXTextFieldActionVerb()
{
- return UI_STRING("activate", "Verb stating the action that will occur when a text field is selected, as used by accessibility");
+ return WEB_UI_STRING("activate", "Verb stating the action that will occur when a text field is selected, as used by accessibility");
}
String DefaultLocalizationStrategy::AXCheckedCheckBoxActionVerb()
{
- return UI_STRING("uncheck", "Verb stating the action that will occur when a checked checkbox is clicked, as used by accessibility");
+ return WEB_UI_STRING("uncheck", "Verb stating the action that will occur when a checked checkbox is clicked, as used by accessibility");
}
String DefaultLocalizationStrategy::AXUncheckedCheckBoxActionVerb()
{
- return UI_STRING("check", "Verb stating the action that will occur when an unchecked checkbox is clicked, as used by accessibility");
+ return WEB_UI_STRING("check", "Verb stating the action that will occur when an unchecked checkbox is clicked, as used by accessibility");
}
String DefaultLocalizationStrategy::AXMenuListActionVerb()
@@ -645,27 +650,27 @@ String DefaultLocalizationStrategy::AXMenuListPopupActionVerb()
String DefaultLocalizationStrategy::AXLinkActionVerb()
{
- return UI_STRING("jump", "Verb stating the action that will occur when a link is clicked, as used by accessibility");
+ return WEB_UI_STRING("jump", "Verb stating the action that will occur when a link is clicked, as used by accessibility");
}
String DefaultLocalizationStrategy::missingPluginText()
{
- return UI_STRING("Missing Plug-in", "Label text to be used when a plugin is missing");
+ return WEB_UI_STRING("Missing Plug-in", "Label text to be used when a plugin is missing");
}
String DefaultLocalizationStrategy::crashedPluginText()
{
- return UI_STRING("Plug-in Failure", "Label text to be used if plugin host process has crashed");
+ return WEB_UI_STRING("Plug-in Failure", "Label text to be used if plugin host process has crashed");
}
String DefaultLocalizationStrategy::multipleFileUploadText(unsigned numberOfFiles)
{
- return formatLocalizedString(UI_STRING("%d files", "Label to describe the number of files selected in a file upload control that allows multiple files"), numberOfFiles);
+ return formatLocalizedString(WEB_UI_STRING("%d files", "Label to describe the number of files selected in a file upload control that allows multiple files"), numberOfFiles);
}
String DefaultLocalizationStrategy::unknownFileSizeText()
{
- return UI_STRING("Unknown", "Unknown filesize FTP directory listing item");
+ return WEB_UI_STRING("Unknown", "Unknown filesize FTP directory listing item");
}
#if PLATFORM(WIN)
@@ -688,80 +693,101 @@ String DefaultLocalizationStrategy::allFilesText()
String DefaultLocalizationStrategy::keygenMenuItem512()
{
- return UI_STRING("512 (Low Grade)", "Menu item title for KEYGEN pop-up menu");
+ return WEB_UI_STRING("512 (Low Grade)", "Menu item title for KEYGEN pop-up menu");
}
String DefaultLocalizationStrategy::keygenMenuItem1024()
{
- return UI_STRING("1024 (Medium Grade)", "Menu item title for KEYGEN pop-up menu");
+ return WEB_UI_STRING("1024 (Medium Grade)", "Menu item title for KEYGEN pop-up menu");
}
String DefaultLocalizationStrategy::keygenMenuItem2048()
{
- return UI_STRING("2048 (High Grade)", "Menu item title for KEYGEN pop-up menu");
+ return WEB_UI_STRING("2048 (High Grade)", "Menu item title for KEYGEN pop-up menu");
}
String DefaultLocalizationStrategy::keygenKeychainItemName(const String& host)
{
- return UI_STRING("Key from <hostname>", "Name of keychain key generated by the KEYGEN tag").replace("<hostname>", host);
+ RetainPtr<CFStringRef> hostCFString(AdoptCF, host.createCFString());
+ return formatLocalizedString(WEB_UI_STRING("Key from %@", "Name of keychain key generated by the KEYGEN tag"), hostCFString.get());
}
#endif
String DefaultLocalizationStrategy::imageTitle(const String& filename, const IntSize& size)
{
- // FIXME: This should format the numbers correctly. In Mac WebKit, we used +[NSNumberFormatter localizedStringFromNumber:numberStyle:].
- return formatLocalizedString(UI_STRING("<filename> %d×%d pixels", "window title suffix for a standalone image (uses multiplication symbol, not x)"), size.width(), size.height()).replace("<filename>", filename);
+#if USE(CF)
+#if !defined(BUILDING_ON_LEOPARD)
+ RetainPtr<CFStringRef> filenameCFString(AdoptCF, filename.createCFString());
+ RetainPtr<CFLocaleRef> locale(AdoptCF, CFLocaleCopyCurrent());
+ RetainPtr<CFNumberFormatterRef> formatter(AdoptCF, CFNumberFormatterCreate(0, locale.get(), kCFNumberFormatterDecimalStyle));
+
+ int widthInt = size.width();
+ RetainPtr<CFNumberRef> width(AdoptCF, CFNumberCreate(0, kCFNumberIntType, &widthInt));
+ RetainPtr<CFStringRef> widthString(AdoptCF, CFNumberFormatterCreateStringWithNumber(0, formatter.get(), width.get()));
+
+ int heightInt = size.height();
+ RetainPtr<CFNumberRef> height(AdoptCF, CFNumberCreate(0, kCFNumberIntType, &heightInt));
+ RetainPtr<CFStringRef> heightString(AdoptCF, CFNumberFormatterCreateStringWithNumber(0, formatter.get(), height.get()));
+
+ return formatLocalizedString(WEB_UI_STRING("%@ %@×%@ pixels", "window title for a standalone image (uses multiplication symbol, not x)"), filenameCFString.get(), widthString.get(), heightString.get());
+#else
+ RetainPtr<CFStringRef> filenameCFString(AdoptCF, filename.createCFString());
+ return formatLocalizedString(WEB_UI_STRING("%@ %d×%d pixels", "window title for a standalone image (uses multiplication symbol, not x)"), filenameCFString.get(), size.width(), size.height());
+#endif
+#else
+ return formatLocalizedString(WEB_UI_STRING("<filename> %d×%d pixels", "window title for a standalone image (uses multiplication symbol, not x)"), size.width(), size.height()).replace("<filename>", filename);
+#endif
}
String DefaultLocalizationStrategy::mediaElementLoadingStateText()
{
- return UI_STRING("Loading...", "Media controller status message when the media is loading");
+ return WEB_UI_STRING("Loading...", "Media controller status message when the media is loading");
}
String DefaultLocalizationStrategy::mediaElementLiveBroadcastStateText()
{
- return UI_STRING("Live Broadcast", "Media controller status message when watching a live broadcast");
+ return WEB_UI_STRING("Live Broadcast", "Media controller status message when watching a live broadcast");
}
String DefaultLocalizationStrategy::localizedMediaControlElementString(const String& name)
{
if (name == "AudioElement")
- return UI_STRING("audio element controller", "accessibility role description for audio element controller");
+ return WEB_UI_STRING("audio element controller", "accessibility role description for audio element controller");
if (name == "VideoElement")
- return UI_STRING("video element controller", "accessibility role description for video element controller");
+ return WEB_UI_STRING("video element controller", "accessibility role description for video element controller");
if (name == "MuteButton")
- return UI_STRING("mute", "accessibility role description for mute button");
+ return WEB_UI_STRING("mute", "accessibility role description for mute button");
if (name == "UnMuteButton")
- return UI_STRING("unmute", "accessibility role description for turn mute off button");
+ return WEB_UI_STRING("unmute", "accessibility role description for turn mute off button");
if (name == "PlayButton")
- return UI_STRING("play", "accessibility role description for play button");
+ return WEB_UI_STRING("play", "accessibility role description for play button");
if (name == "PauseButton")
- return UI_STRING("pause", "accessibility role description for pause button");
+ return WEB_UI_STRING("pause", "accessibility role description for pause button");
if (name == "Slider")
- return UI_STRING("movie time", "accessibility role description for timeline slider");
+ return WEB_UI_STRING("movie time", "accessibility role description for timeline slider");
if (name == "SliderThumb")
- return UI_STRING("timeline slider thumb", "accessibility role description for timeline thumb");
+ return WEB_UI_STRING("timeline slider thumb", "accessibility role description for timeline thumb");
if (name == "RewindButton")
- return UI_STRING("back 30 seconds", "accessibility role description for seek back 30 seconds button");
+ return WEB_UI_STRING("back 30 seconds", "accessibility role description for seek back 30 seconds button");
if (name == "ReturnToRealtimeButton")
- return UI_STRING("return to realtime", "accessibility role description for return to real time button");
+ return WEB_UI_STRING("return to realtime", "accessibility role description for return to real time button");
if (name == "CurrentTimeDisplay")
- return UI_STRING("elapsed time", "accessibility role description for elapsed time display");
+ return WEB_UI_STRING("elapsed time", "accessibility role description for elapsed time display");
if (name == "TimeRemainingDisplay")
- return UI_STRING("remaining time", "accessibility role description for time remaining display");
+ return WEB_UI_STRING("remaining time", "accessibility role description for time remaining display");
if (name == "StatusDisplay")
- return UI_STRING("status", "accessibility role description for movie status");
+ return WEB_UI_STRING("status", "accessibility role description for movie status");
if (name == "FullscreenButton")
- return UI_STRING("fullscreen", "accessibility role description for enter fullscreen button");
+ return WEB_UI_STRING("fullscreen", "accessibility role description for enter fullscreen button");
if (name == "SeekForwardButton")
- return UI_STRING("fast forward", "accessibility role description for fast forward button");
+ return WEB_UI_STRING("fast forward", "accessibility role description for fast forward button");
if (name == "SeekBackButton")
- return UI_STRING("fast reverse", "accessibility role description for fast reverse button");
+ return WEB_UI_STRING("fast reverse", "accessibility role description for fast reverse button");
if (name == "ShowClosedCaptionsButton")
- return UI_STRING("show closed captions", "accessibility role description for show closed captions button");
+ return WEB_UI_STRING("show closed captions", "accessibility role description for show closed captions button");
if (name == "HideClosedCaptionsButton")
- return UI_STRING("hide closed captions", "accessibility role description for hide closed captions button");
+ return WEB_UI_STRING("hide closed captions", "accessibility role description for hide closed captions button");
// FIXME: the ControlsPanel container should never be visible in the accessibility hierarchy.
if (name == "ControlsPanel")
@@ -774,41 +800,41 @@ String DefaultLocalizationStrategy::localizedMediaControlElementString(const Str
String DefaultLocalizationStrategy::localizedMediaControlElementHelpText(const String& name)
{
if (name == "AudioElement")
- return UI_STRING("audio element playback controls and status display", "accessibility role description for audio element controller");
+ return WEB_UI_STRING("audio element playback controls and status display", "accessibility role description for audio element controller");
if (name == "VideoElement")
- return UI_STRING("video element playback controls and status display", "accessibility role description for video element controller");
+ return WEB_UI_STRING("video element playback controls and status display", "accessibility role description for video element controller");
if (name == "MuteButton")
- return UI_STRING("mute audio tracks", "accessibility help text for mute button");
+ return WEB_UI_STRING("mute audio tracks", "accessibility help text for mute button");
if (name == "UnMuteButton")
- return UI_STRING("unmute audio tracks", "accessibility help text for un mute button");
+ return WEB_UI_STRING("unmute audio tracks", "accessibility help text for un mute button");
if (name == "PlayButton")
- return UI_STRING("begin playback", "accessibility help text for play button");
+ return WEB_UI_STRING("begin playback", "accessibility help text for play button");
if (name == "PauseButton")
- return UI_STRING("pause playback", "accessibility help text for pause button");
+ return WEB_UI_STRING("pause playback", "accessibility help text for pause button");
if (name == "Slider")
- return UI_STRING("movie time scrubber", "accessibility help text for timeline slider");
+ return WEB_UI_STRING("movie time scrubber", "accessibility help text for timeline slider");
if (name == "SliderThumb")
- return UI_STRING("movie time scrubber thumb", "accessibility help text for timeline slider thumb");
+ return WEB_UI_STRING("movie time scrubber thumb", "accessibility help text for timeline slider thumb");
if (name == "RewindButton")
- return UI_STRING("seek movie back 30 seconds", "accessibility help text for jump back 30 seconds button");
+ return WEB_UI_STRING("seek movie back 30 seconds", "accessibility help text for jump back 30 seconds button");
if (name == "ReturnToRealtimeButton")
- return UI_STRING("return streaming movie to real time", "accessibility help text for return streaming movie to real time button");
+ return WEB_UI_STRING("return streaming movie to real time", "accessibility help text for return streaming movie to real time button");
if (name == "CurrentTimeDisplay")
- return UI_STRING("current movie time in seconds", "accessibility help text for elapsed time display");
+ return WEB_UI_STRING("current movie time in seconds", "accessibility help text for elapsed time display");
if (name == "TimeRemainingDisplay")
- return UI_STRING("number of seconds of movie remaining", "accessibility help text for remaining time display");
+ return WEB_UI_STRING("number of seconds of movie remaining", "accessibility help text for remaining time display");
if (name == "StatusDisplay")
- return UI_STRING("current movie status", "accessibility help text for movie status display");
+ return WEB_UI_STRING("current movie status", "accessibility help text for movie status display");
if (name == "SeekBackButton")
- return UI_STRING("seek quickly back", "accessibility help text for fast rewind button");
+ return WEB_UI_STRING("seek quickly back", "accessibility help text for fast rewind button");
if (name == "SeekForwardButton")
- return UI_STRING("seek quickly forward", "accessibility help text for fast forward button");
+ return WEB_UI_STRING("seek quickly forward", "accessibility help text for fast forward button");
if (name == "FullscreenButton")
- return UI_STRING("Play movie in fullscreen mode", "accessibility help text for enter fullscreen button");
+ return WEB_UI_STRING("Play movie in fullscreen mode", "accessibility help text for enter fullscreen button");
if (name == "ShowClosedCaptionsButton")
- return UI_STRING("start displaying closed captions", "accessibility help text for show closed captions button");
+ return WEB_UI_STRING("start displaying closed captions", "accessibility help text for show closed captions button");
if (name == "HideClosedCaptionsButton")
- return UI_STRING("stop displaying closed captions", "accessibility help text for hide closed captions button");
+ return WEB_UI_STRING("stop displaying closed captions", "accessibility help text for hide closed captions button");
ASSERT_NOT_REACHED();
return String();
@@ -817,7 +843,7 @@ String DefaultLocalizationStrategy::localizedMediaControlElementHelpText(const S
String DefaultLocalizationStrategy::localizedMediaTimeDescription(float time)
{
if (!isfinite(time))
- return UI_STRING("indefinite time", "accessibility help text for an indefinite media controller time value");
+ return WEB_UI_STRING("indefinite time", "accessibility help text for an indefinite media controller time value");
int seconds = static_cast<int>(fabsf(time));
int days = seconds / (60 * 60 * 24);
@@ -826,47 +852,47 @@ String DefaultLocalizationStrategy::localizedMediaTimeDescription(float time)
seconds %= 60;
if (days)
- return formatLocalizedString(UI_STRING("%1$d days %2$d hours %3$d minutes %4$d seconds", "accessibility help text for media controller time value >= 1 day"), days, hours, minutes, seconds);
+ return formatLocalizedString(WEB_UI_STRING("%1$d days %2$d hours %3$d minutes %4$d seconds", "accessibility help text for media controller time value >= 1 day"), days, hours, minutes, seconds);
if (hours)
- return formatLocalizedString(UI_STRING("%1$d hours %2$d minutes %3$d seconds", "accessibility help text for media controller time value >= 60 minutes"), hours, minutes, seconds);
+ return formatLocalizedString(WEB_UI_STRING("%1$d hours %2$d minutes %3$d seconds", "accessibility help text for media controller time value >= 60 minutes"), hours, minutes, seconds);
if (minutes)
- return formatLocalizedString(UI_STRING("%1$d minutes %2$d seconds", "accessibility help text for media controller time value >= 60 seconds"), minutes, seconds);
- return formatLocalizedString(UI_STRING("%1$d seconds", "accessibility help text for media controller time value < 60 seconds"), seconds);
+ return formatLocalizedString(WEB_UI_STRING("%1$d minutes %2$d seconds", "accessibility help text for media controller time value >= 60 seconds"), minutes, seconds);
+ return formatLocalizedString(WEB_UI_STRING("%1$d seconds", "accessibility help text for media controller time value < 60 seconds"), seconds);
}
String DefaultLocalizationStrategy::validationMessageValueMissingText()
{
- return UI_STRING("value missing", "Validation message for required form control elements that have no value");
+ return WEB_UI_STRING("value missing", "Validation message for required form control elements that have no value");
}
String DefaultLocalizationStrategy::validationMessageTypeMismatchText()
{
- return UI_STRING("type mismatch", "Validation message for input form controls with a value not matching type");
+ return WEB_UI_STRING("type mismatch", "Validation message for input form controls with a value not matching type");
}
String DefaultLocalizationStrategy::validationMessagePatternMismatchText()
{
- return UI_STRING("pattern mismatch", "Validation message for input form controls requiring a constrained value according to pattern");
+ return WEB_UI_STRING("pattern mismatch", "Validation message for input form controls requiring a constrained value according to pattern");
}
String DefaultLocalizationStrategy::validationMessageTooLongText()
{
- return UI_STRING("too long", "Validation message for form control elements with a value longer than maximum allowed length");
+ return WEB_UI_STRING("too long", "Validation message for form control elements with a value longer than maximum allowed length");
}
String DefaultLocalizationStrategy::validationMessageRangeUnderflowText()
{
- return UI_STRING("range underflow", "Validation message for input form controls with value lower than allowed minimum");
+ return WEB_UI_STRING("range underflow", "Validation message for input form controls with value lower than allowed minimum");
}
String DefaultLocalizationStrategy::validationMessageRangeOverflowText()
{
- return UI_STRING("range overflow", "Validation message for input form controls with value higher than allowed maximum");
+ return WEB_UI_STRING("range overflow", "Validation message for input form controls with value higher than allowed maximum");
}
String DefaultLocalizationStrategy::validationMessageStepMismatchText()
{
- return UI_STRING("step mismatch", "Validation message for input form controls with value not respecting the step attribute");
+ return WEB_UI_STRING("step mismatch", "Validation message for input form controls with value not respecting the step attribute");
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/DragData.h b/Source/WebCore/platform/DragData.h
index b89748e..5b29610 100644
--- a/Source/WebCore/platform/DragData.h
+++ b/Source/WebCore/platform/DragData.h
@@ -119,6 +119,9 @@ public:
bool canSmartReplace() const;
bool containsColor() const;
bool containsFiles() const;
+#if PLATFORM(MAC)
+ NSPasteboard *pasteboard() { return m_pasteboard.get(); }
+#endif
private:
IntPoint m_clientPosition;
IntPoint m_globalPosition;
diff --git a/Source/WebCore/platform/FileSystem.h b/Source/WebCore/platform/FileSystem.h
index 49a78e8..418a645 100644
--- a/Source/WebCore/platform/FileSystem.h
+++ b/Source/WebCore/platform/FileSystem.h
@@ -47,6 +47,11 @@
#endif
#endif
+#if PLATFORM(WX)
+#include <wx/defs.h>
+#include <wx/file.h>
+#endif
+
#if USE(CF) || (PLATFORM(QT) && defined(Q_WS_MAC))
typedef struct __CFBundle* CFBundleRef;
typedef const struct __CFData* CFDataRef;
@@ -72,7 +77,9 @@ typedef struct _GModule GModule;
namespace WebCore {
// PlatformModule
-#if OS(WINDOWS)
+#if PLATFORM(GTK)
+typedef GModule* PlatformModule;
+#elif OS(WINDOWS)
typedef HMODULE PlatformModule;
#elif PLATFORM(QT)
#if defined(Q_WS_MAC)
@@ -82,8 +89,6 @@ typedef QLibrary* PlatformModule;
#else
typedef void* PlatformModule;
#endif
-#elif PLATFORM(GTK)
-typedef GModule* PlatformModule;
#elif USE(CF)
typedef CFBundleRef PlatformModule;
#else
@@ -117,6 +122,9 @@ typedef unsigned PlatformModuleVersion;
#if PLATFORM(QT)
typedef QFile* PlatformFileHandle;
const PlatformFileHandle invalidPlatformFileHandle = 0;
+#elif PLATFORM(GTK)
+typedef GFileIOStream* PlatformFileHandle;
+const PlatformFileHandle invalidPlatformFileHandle = 0;
#elif OS(WINDOWS)
typedef HANDLE PlatformFileHandle;
// FIXME: -1 is INVALID_HANDLE_VALUE, defined in <winbase.h>. Chromium tries to
@@ -125,8 +133,8 @@ const PlatformFileHandle invalidPlatformFileHandle = reinterpret_cast<HANDLE>(-1
#elif PLATFORM(BREWMP)
typedef IFile* PlatformFileHandle;
const PlatformFileHandle invalidPlatformFileHandle = 0;
-#elif PLATFORM(GTK)
-typedef GFileIOStream* PlatformFileHandle;
+#elif PLATFORM(WX)
+typedef wxFile* PlatformFileHandle;
const PlatformFileHandle invalidPlatformFileHandle = 0;
#else
typedef int PlatformFileHandle;
diff --git a/Source/WebCore/platform/FloatConversion.h b/Source/WebCore/platform/FloatConversion.h
index 655ab44..fb76833 100644
--- a/Source/WebCore/platform/FloatConversion.h
+++ b/Source/WebCore/platform/FloatConversion.h
@@ -29,7 +29,7 @@
#ifndef FloatConversion_h
#define FloatConversion_h
-#if PLATFORM(CG)
+#if USE(CG)
#include <CoreGraphics/CGBase.h>
#endif
@@ -44,7 +44,7 @@ namespace WebCore {
return static_cast<float>(number);
}
-#if PLATFORM(CG)
+#if USE(CG)
template<typename T>
CGFloat narrowPrecisionToCGFloat(T);
diff --git a/Source/WebCore/platform/KURL.h b/Source/WebCore/platform/KURL.h
index 5764494..db2dd42 100644
--- a/Source/WebCore/platform/KURL.h
+++ b/Source/WebCore/platform/KURL.h
@@ -76,6 +76,12 @@ public:
KURL(ParsedURLStringTag, const char*);
KURL(ParsedURLStringTag, const String&);
KURL(ParsedURLStringTag, const URLString&);
+#if USE(GOOGLEURL)
+ KURL(WTF::HashTableDeletedValueType) : m_url(WTF::HashTableDeletedValue) { }
+#else
+ KURL(WTF::HashTableDeletedValueType) : m_string(WTF::HashTableDeletedValue) { }
+#endif
+ bool isHashTableDeletedValue() const { return string().isHashTableDeletedValue(); }
// Resolves the relative URL with the given base URL. If provided, the
// TextEncoding is used to encode non-ASCII characers. The base URL can be
diff --git a/Source/WebCore/platform/KURLGoogle.cpp b/Source/WebCore/platform/KURLGoogle.cpp
index 88120a8..0d11b99 100644
--- a/Source/WebCore/platform/KURLGoogle.cpp
+++ b/Source/WebCore/platform/KURLGoogle.cpp
@@ -169,6 +169,11 @@ KURLGooglePrivate::KURLGooglePrivate(const url_parse::Parsed& parsed, bool isVal
{
}
+KURLGooglePrivate::KURLGooglePrivate(WTF::HashTableDeletedValueType)
+ : m_string(WTF::HashTableDeletedValue)
+{
+}
+
// Setters for the data. Using the ASCII version when you know the
// data is ASCII will be slightly more efficient. The UTF-8 version
// will always be correct if the caller is unsure.
diff --git a/Source/WebCore/platform/KURLGooglePrivate.h b/Source/WebCore/platform/KURLGooglePrivate.h
index c74a6b4..12427a3 100644
--- a/Source/WebCore/platform/KURLGooglePrivate.h
+++ b/Source/WebCore/platform/KURLGooglePrivate.h
@@ -48,6 +48,7 @@ namespace WebCore {
public:
KURLGooglePrivate();
KURLGooglePrivate(const url_parse::Parsed&, bool isValid);
+ KURLGooglePrivate(WTF::HashTableDeletedValueType);
// Initializes the object. This will call through the backend initializer
// below.
diff --git a/Source/WebCore/platform/KURLHash.h b/Source/WebCore/platform/KURLHash.h
index 44a4624..a236508 100644
--- a/Source/WebCore/platform/KURLHash.h
+++ b/Source/WebCore/platform/KURLHash.h
@@ -50,11 +50,7 @@ namespace WebCore {
namespace WTF {
- template<> struct HashTraits<WebCore::KURL> : GenericHashTraits<WebCore::KURL> {
- static const bool emptyValueIsZero = true;
- static void constructDeletedValue(WebCore::KURL& slot) { new (&slot) WebCore::KURL(WebCore::ParsedURLString, WTF::String(HashTableDeletedValue)); }
- static bool isDeletedValue(const WebCore::KURL& slot) { return slot.string().isHashTableDeletedValue(); }
- };
+ template<> struct HashTraits<WebCore::KURL> : SimpleClassHashTraits<WebCore::KURL> { };
} // namespace WTF
diff --git a/Source/WebCore/platform/LocalizedStrings.h b/Source/WebCore/platform/LocalizedStrings.h
index 3885439..777fcec 100644
--- a/Source/WebCore/platform/LocalizedStrings.h
+++ b/Source/WebCore/platform/LocalizedStrings.h
@@ -195,8 +195,8 @@ namespace WebCore {
String validationMessageStepMismatchText(const String& base, const String& step);
-#define UI_STRING(string, description) WebCore::localizedString(string)
-#define UI_STRING_KEY(string, key, description) WebCore::localizedString(key)
+#define WEB_UI_STRING(string, description) WebCore::localizedString(string)
+#define WEB_UI_STRING_KEY(string, key, description) WebCore::localizedString(key)
String localizedString(const char* key);
diff --git a/Source/WebCore/platform/MIMETypeRegistry.cpp b/Source/WebCore/platform/MIMETypeRegistry.cpp
index d0ad985..c334683 100644
--- a/Source/WebCore/platform/MIMETypeRegistry.cpp
+++ b/Source/WebCore/platform/MIMETypeRegistry.cpp
@@ -33,7 +33,7 @@
#include <wtf/StdLibExtras.h>
#include <wtf/text/StringHash.h>
-#if PLATFORM(CG)
+#if USE(CG)
#include "ImageSourceCG.h"
#include <ApplicationServices/ApplicationServices.h>
#include <wtf/RetainPtr.h>
@@ -61,7 +61,7 @@ typedef HashMap<String, Vector<String>*, CaseFoldingHash> MediaMIMETypeMap;
static void initializeSupportedImageMIMETypes()
{
-#if PLATFORM(CG)
+#if USE(CG)
RetainPtr<CFArrayRef> supportedTypes(AdoptCF, CGImageSourceCopyTypeIdentifiers());
CFIndex count = CFArrayGetCount(supportedTypes.get());
for (CFIndex i = 0; i < count; i++) {
@@ -157,7 +157,7 @@ static void initializeSupportedImageMIMETypesForEncoding()
{
supportedImageMIMETypesForEncoding = new HashSet<String>;
-#if PLATFORM(CG)
+#if USE(CG)
#if PLATFORM(MAC)
RetainPtr<CFArrayRef> supportedTypes(AdoptCF, CGImageDestinationCopyTypeIdentifiers());
CFIndex count = CFArrayGetCount(supportedTypes.get());
@@ -187,7 +187,7 @@ static void initializeSupportedImageMIMETypesForEncoding()
supportedImageMIMETypesForEncoding->add("image/tiff");
supportedImageMIMETypesForEncoding->add("image/bmp");
supportedImageMIMETypesForEncoding->add("image/ico");
-#elif PLATFORM(CAIRO)
+#elif USE(CAIRO)
supportedImageMIMETypesForEncoding->add("image/png");
#endif
}
diff --git a/Source/WebCore/platform/RuntimeApplicationChecks.cpp b/Source/WebCore/platform/RuntimeApplicationChecks.cpp
new file mode 100644
index 0000000..bdb44c0
--- /dev/null
+++ b/Source/WebCore/platform/RuntimeApplicationChecks.cpp
@@ -0,0 +1,99 @@
+/*
+ * 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.
+ */
+
+#include "config.h"
+#include "RuntimeApplicationChecks.h"
+
+#if USE(CF)
+#include <CoreFoundation/CoreFoundation.h>
+#include <wtf/RetainPtr.h>
+#endif
+
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+static bool mainBundleIsEqualTo(const String& bundleIdentifierString)
+{
+#if USE(CF)
+ CFBundleRef mainBundle = CFBundleGetMainBundle();
+ if (!mainBundle)
+ return false;
+
+ CFStringRef bundleIdentifier = CFBundleGetIdentifier(mainBundle);
+ if (!bundleIdentifier)
+ return false;
+
+ RetainPtr<CFStringRef> bundleIdentifierToCompare(AdoptCF, bundleIdentifierString.createCFString());
+ return CFStringCompare(bundleIdentifier, bundleIdentifierToCompare.get(), 0) == kCFCompareEqualTo;
+#else
+ return false;
+#endif
+}
+
+bool applicationIsSafari()
+{
+ // FIXME: For the WebProcess case, ensure that this is Safari's WebProcess.
+ static bool isSafari = mainBundleIsEqualTo("com.apple.Safari") || mainBundleIsEqualTo("com.apple.WebProcess");
+ return isSafari;
+}
+
+bool applicationIsAppleMail()
+{
+ static bool isAppleMail = mainBundleIsEqualTo("com.apple.mail");
+ return isAppleMail;
+}
+
+bool applicationIsMicrosoftMessenger()
+{
+ static bool isMicrosoftMessenger = mainBundleIsEqualTo("com.microsoft.Messenger");
+ return isMicrosoftMessenger;
+}
+
+bool applicationIsAdobeInstaller()
+{
+ static bool isAdobeInstaller = mainBundleIsEqualTo("com.adobe.Installers.Setup");
+ return isAdobeInstaller;
+}
+
+bool applicationIsAOLInstantMessenger()
+{
+ static bool isAOLInstantMessenger = mainBundleIsEqualTo("com.aol.aim.desktop");
+ return isAOLInstantMessenger;
+}
+
+bool applicationIsMicrosoftMyDay()
+{
+ static bool isMicrosoftMyDay = mainBundleIsEqualTo("com.microsoft.myday");
+ return isMicrosoftMyDay;
+}
+
+bool applicationIsMicrosoftOutlook()
+{
+ static bool isMicrosoftOutlook = mainBundleIsEqualTo("com.microsoft.Outlook");
+ return isMicrosoftOutlook;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/mac/RuntimeApplicationChecks.h b/Source/WebCore/platform/RuntimeApplicationChecks.h
index f938048..c2f4ba1 100644
--- a/Source/WebCore/platform/mac/RuntimeApplicationChecks.h
+++ b/Source/WebCore/platform/RuntimeApplicationChecks.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 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
@@ -34,6 +34,7 @@ bool applicationIsMicrosoftMessenger();
bool applicationIsAdobeInstaller();
bool applicationIsAOLInstantMessenger();
bool applicationIsMicrosoftMyDay();
+bool applicationIsMicrosoftOutlook();
} // namespace WebCore
diff --git a/Source/WebCore/platform/ScrollTypes.h b/Source/WebCore/platform/ScrollTypes.h
index 1f8e095..62b4645 100644
--- a/Source/WebCore/platform/ScrollTypes.h
+++ b/Source/WebCore/platform/ScrollTypes.h
@@ -108,6 +108,12 @@ namespace WebCore {
ScrollByPixel
};
+ enum ScrollElasticity {
+ ScrollElasticityAutomatic,
+ ScrollElasticityNone,
+ ScrollElasticityAllowed
+ };
+
enum ScrollbarOrientation { HorizontalScrollbar, VerticalScrollbar };
enum ScrollbarMode { ScrollbarAuto, ScrollbarAlwaysOff, ScrollbarAlwaysOn };
diff --git a/Source/WebCore/platform/ScrollView.cpp b/Source/WebCore/platform/ScrollView.cpp
index 58615fb..e79f049 100644
--- a/Source/WebCore/platform/ScrollView.cpp
+++ b/Source/WebCore/platform/ScrollView.cpp
@@ -28,6 +28,7 @@
#include "AXObjectCache.h"
#include "GraphicsContext.h"
+#include "GraphicsLayer.h"
#include "HostWindow.h"
#include "PlatformMouseEvent.h"
#include "PlatformWheelEvent.h"
@@ -56,6 +57,7 @@ ScrollView::ScrollView()
, m_paintsEntireContents(false)
, m_clipsRepaints(true)
, m_delegatesScrolling(false)
+ , m_containsScrollableAreaWithOverlayScrollbars(false)
{
platformInit();
}
@@ -873,8 +875,45 @@ void ScrollView::frameRectsChanged()
HashSet<RefPtr<Widget> >::const_iterator end = m_children.end();
for (HashSet<RefPtr<Widget> >::const_iterator current = m_children.begin(); current != end; ++current)
(*current)->frameRectsChanged();
+ positionScrollbarLayers();
}
+#if USE(ACCELERATED_COMPOSITING)
+static void positionScrollbarLayer(GraphicsLayer* graphicsLayer, Scrollbar* scrollbar)
+{
+ if (!graphicsLayer || !scrollbar)
+ return;
+ graphicsLayer->setDrawsContent(true);
+ IntRect scrollbarRect = scrollbar->frameRect();
+ graphicsLayer->setPosition(scrollbarRect.location());
+ if (scrollbarRect.size() != graphicsLayer->size())
+ graphicsLayer->setNeedsDisplay();
+ graphicsLayer->setSize(scrollbarRect.size());
+}
+
+static void positionScrollCornerLayer(GraphicsLayer* graphicsLayer, const IntRect& cornerRect)
+{
+ if (!graphicsLayer)
+ return;
+ graphicsLayer->setDrawsContent(!cornerRect.isEmpty());
+ graphicsLayer->setPosition(cornerRect.location());
+ if (cornerRect.size() != graphicsLayer->size())
+ graphicsLayer->setNeedsDisplay();
+ graphicsLayer->setSize(cornerRect.size());
+}
+#endif
+
+
+void ScrollView::positionScrollbarLayers()
+{
+#if USE(ACCELERATED_COMPOSITING)
+ positionScrollbarLayer(layerForHorizontalScrollbar(), horizontalScrollbar());
+ positionScrollbarLayer(layerForVerticalScrollbar(), verticalScrollbar());
+ positionScrollCornerLayer(layerForScrollCorner(), scrollCornerRect());
+#endif
+}
+
+
void ScrollView::repaintContentRectangle(const IntRect& rect, bool now)
{
IntRect paintRect = rect;
@@ -919,6 +958,11 @@ IntRect ScrollView::scrollCornerRect() const
return cornerRect;
}
+bool ScrollView::isScrollCornerVisible() const
+{
+ return !scrollCornerRect().isEmpty();
+}
+
void ScrollView::updateScrollCorner()
{
}
@@ -928,13 +972,30 @@ void ScrollView::paintScrollCorner(GraphicsContext* context, const IntRect& corn
ScrollbarTheme::nativeTheme()->paintScrollCorner(this, context, cornerRect);
}
+void ScrollView::invalidateScrollCornerRect(const IntRect& rect)
+{
+ invalidateRect(rect);
+}
+
void ScrollView::paintScrollbars(GraphicsContext* context, const IntRect& rect)
{
- if (m_horizontalScrollbar)
+ if (m_horizontalScrollbar
+#if USE(ACCELERATED_COMPOSITING)
+ && !layerForHorizontalScrollbar()
+#endif
+ )
m_horizontalScrollbar->paint(context, rect);
- if (m_verticalScrollbar)
+ if (m_verticalScrollbar
+#if USE(ACCELERATED_COMPOSITING)
+ && !layerForVerticalScrollbar()
+#endif
+ )
m_verticalScrollbar->paint(context, rect);
+#if USE(ACCELERATED_COMPOSITING)
+ if (layerForScrollCorner())
+ return;
+#endif
paintScrollCorner(context, scrollCornerRect());
}
@@ -955,6 +1016,9 @@ void ScrollView::paint(GraphicsContext* context, const IntRect& rect)
return;
notifyPageThatContentAreaWillPaint();
+
+ // If we encounter any overlay scrollbars as we paint, this will be set to true.
+ m_containsScrollableAreaWithOverlayScrollbars = false;
IntRect documentDirtyRect = rect;
documentDirtyRect.intersect(frameRect());
diff --git a/Source/WebCore/platform/ScrollView.h b/Source/WebCore/platform/ScrollView.h
index bff77d5..558aee2 100644
--- a/Source/WebCore/platform/ScrollView.h
+++ b/Source/WebCore/platform/ScrollView.h
@@ -63,6 +63,7 @@ public:
virtual void setScrollOffset(const IntPoint&);
virtual void didCompleteRubberBand(const IntSize&) const;
virtual void notifyPageThatContentAreaWillPaint() const;
+ virtual bool isScrollCornerVisible() const;
// NOTE: This should only be called by the overriden setScrollOffset from ScrollableArea.
virtual void scrollTo(const IntSize& newOffset);
@@ -85,6 +86,8 @@ public:
virtual Scrollbar* verticalScrollbar() const { return m_verticalScrollbar.get(); }
bool isScrollViewScrollbar(const Widget* child) const { return horizontalScrollbar() == child || verticalScrollbar() == child; }
+ void positionScrollbarLayers();
+
// Functions for setting and retrieving the scrolling mode in each axis (horizontal/vertical). The mode has values of
// AlwaysOff, AlwaysOn, and Auto. AlwaysOff means never show a scrollbar, AlwaysOn means always show a scrollbar.
// Auto means show a scrollbar only when one is needed.
@@ -183,6 +186,9 @@ public:
IntSize overhangAmount() const;
+ void cacheCurrentScrollPosition() { m_cachedScrollPosition = scrollPosition(); }
+ IntPoint cachedScrollPosition() const { return m_cachedScrollPosition; }
+
// Functions for scrolling the view.
void setScrollPosition(const IntPoint&);
void scrollBy(const IntSize& s) { return setScrollPosition(scrollPosition() + s); }
@@ -278,12 +284,17 @@ public:
virtual bool isPointInScrollbarCorner(const IntPoint&);
virtual bool scrollbarCornerPresent() const;
+ virtual IntRect scrollCornerRect() const;
+ virtual void paintScrollCorner(GraphicsContext*, const IntRect& cornerRect);
virtual IntRect convertFromScrollbarToContainingView(const Scrollbar*, const IntRect&) const;
virtual IntRect convertFromContainingViewToScrollbar(const Scrollbar*, const IntRect&) const;
virtual IntPoint convertFromScrollbarToContainingView(const Scrollbar*, const IntPoint&) const;
virtual IntPoint convertFromContainingViewToScrollbar(const Scrollbar*, const IntPoint&) const;
+ bool containsScrollableAreaWithOverlayScrollbars() const { return m_containsScrollableAreaWithOverlayScrollbars; }
+ void setContainsScrollableAreaWithOverlayScrollbars(bool contains) { m_containsScrollableAreaWithOverlayScrollbars = contains; }
+
protected:
ScrollView();
@@ -303,9 +314,8 @@ protected:
void setHasHorizontalScrollbar(bool);
void setHasVerticalScrollbar(bool);
- IntRect scrollCornerRect() const;
virtual void updateScrollCorner();
- virtual void paintScrollCorner(GraphicsContext*, const IntRect& cornerRect);
+ virtual void invalidateScrollCornerRect(const IntRect&);
// Scroll the content by blitting the pixels.
virtual bool scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect);
@@ -338,6 +348,7 @@ private:
IntRect m_actualVisibleContentRect;
IntSize m_scrollOffset; // FIXME: Would rather store this as a position, but we will wait to make this change until more code is shared.
+ IntPoint m_cachedScrollPosition;
IntSize m_fixedLayoutSize;
IntSize m_contentsSize;
@@ -355,6 +366,8 @@ private:
bool m_clipsRepaints;
bool m_delegatesScrolling;
+ bool m_containsScrollableAreaWithOverlayScrollbars;
+
IntSize m_boundsSize;
void init();
diff --git a/Source/WebCore/platform/ScrollableArea.cpp b/Source/WebCore/platform/ScrollableArea.cpp
index 34cec9e..2b49427 100644
--- a/Source/WebCore/platform/ScrollableArea.cpp
+++ b/Source/WebCore/platform/ScrollableArea.cpp
@@ -32,6 +32,8 @@
#include "config.h"
#include "ScrollableArea.h"
+#include "GraphicsContext.h"
+#include "GraphicsLayer.h"
#include "FloatPoint.h"
#include "PlatformWheelEvent.h"
#include "ScrollAnimator.h"
@@ -44,6 +46,8 @@ ScrollableArea::ScrollableArea()
: m_scrollAnimator(ScrollAnimator::create(this))
, m_constrainsScrollingToContentEdge(true)
, m_inLiveResize(false)
+ , m_verticalScrollElasticity(ScrollElasticityNone)
+ , m_horizontalScrollElasticity(ScrollElasticityNone)
{
}
@@ -194,4 +198,33 @@ bool ScrollableArea::hasOverlayScrollbars() const
|| (horizontalScrollbar() && horizontalScrollbar()->isOverlayScrollbar());
}
+void ScrollableArea::invalidateScrollbar(Scrollbar* scrollbar, const IntRect& rect)
+{
+#if USE(ACCELERATED_COMPOSITING)
+ if (scrollbar == horizontalScrollbar()) {
+ if (GraphicsLayer* graphicsLayer = layerForHorizontalScrollbar()) {
+ graphicsLayer->setNeedsDisplay();
+ return;
+ }
+ } else if (scrollbar == verticalScrollbar()) {
+ if (GraphicsLayer* graphicsLayer = layerForVerticalScrollbar()) {
+ graphicsLayer->setNeedsDisplay();
+ return;
+ }
+ }
+#endif
+ invalidateScrollbarRect(scrollbar, rect);
+}
+
+void ScrollableArea::invalidateScrollCorner()
+{
+#if USE(ACCELERATED_COMPOSITING)
+ if (GraphicsLayer* graphicsLayer = layerForScrollCorner()) {
+ graphicsLayer->setNeedsDisplay();
+ return;
+ }
+#endif
+ invalidateScrollCornerRect(scrollCornerRect());
+}
+
} // namespace WebCore
diff --git a/Source/WebCore/platform/ScrollableArea.h b/Source/WebCore/platform/ScrollableArea.h
index d08de00..cc63595 100644
--- a/Source/WebCore/platform/ScrollableArea.h
+++ b/Source/WebCore/platform/ScrollableArea.h
@@ -33,9 +33,13 @@
namespace WebCore {
class FloatPoint;
+class GraphicsContext;
class PlatformGestureEvent;
class PlatformWheelEvent;
class ScrollAnimator;
+#if USE(ACCELERATED_COMPOSITING)
+class GraphicsLayer;
+#endif
class ScrollableArea {
public:
@@ -57,6 +61,12 @@ public:
bool constrainsScrollingToContentEdge() const { return m_constrainsScrollingToContentEdge; }
void setConstrainsScrollingToContentEdge(bool constrainsScrollingToContentEdge) { m_constrainsScrollingToContentEdge = constrainsScrollingToContentEdge; }
+ void setVerticalScrollElasticity(ScrollElasticity scrollElasticity) { m_verticalScrollElasticity = scrollElasticity; }
+ ScrollElasticity verticalScrollElasticity() const { return m_verticalScrollElasticity; }
+
+ void setHorizontalScrollElasticity(ScrollElasticity scrollElasticity) { m_horizontalScrollElasticity = scrollElasticity; }
+ ScrollElasticity horizontalScrollElasticity() const { return m_horizontalScrollElasticity; }
+
bool inLiveResize() const { return m_inLiveResize; }
void willStartLiveResize();
void willEndLiveResize();
@@ -71,11 +81,13 @@ public:
ScrollAnimator* scrollAnimator() const { return m_scrollAnimator.get(); }
const IntPoint& scrollOrigin() const { return m_scrollOrigin; }
+ virtual bool isActive() const = 0;
virtual int scrollSize(ScrollbarOrientation) const = 0;
virtual int scrollPosition(Scrollbar*) const = 0;
- virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&) = 0;
- virtual bool isActive() const = 0;
- virtual bool scrollbarCornerPresent() const = 0;
+ void invalidateScrollbar(Scrollbar*, const IntRect&);
+ virtual bool isScrollCornerVisible() const = 0;
+ virtual IntRect scrollCornerRect() const = 0;
+ void invalidateScrollCorner();
virtual void getTickmarks(Vector<IntRect>&) const { }
// This function should be overriden by subclasses to perform the actual
@@ -130,7 +142,19 @@ private:
bool m_inLiveResize;
+ ScrollElasticity m_verticalScrollElasticity;
+ ScrollElasticity m_horizontalScrollElasticity;
+
protected:
+ virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&) = 0;
+ virtual void invalidateScrollCornerRect(const IntRect&) = 0;
+
+#if USE(ACCELERATED_COMPOSITING)
+ virtual GraphicsLayer* layerForHorizontalScrollbar() const { return 0; }
+ virtual GraphicsLayer* layerForVerticalScrollbar() const { return 0; }
+ virtual GraphicsLayer* layerForScrollCorner() const { return 0; }
+#endif
+
// There are 8 possible combinations of writing mode and direction. Scroll origin will be non-zero in the x or y axis
// if there is any reversed direction or writing-mode. The combinations are:
// writing-mode / direction scrollOrigin.x() set scrollOrigin.y() set
diff --git a/Source/WebCore/platform/Scrollbar.cpp b/Source/WebCore/platform/Scrollbar.cpp
index ba00ab0..e59b763 100644
--- a/Source/WebCore/platform/Scrollbar.cpp
+++ b/Source/WebCore/platform/Scrollbar.cpp
@@ -456,8 +456,9 @@ void Scrollbar::invalidateRect(const IntRect& rect)
{
if (suppressInvalidation())
return;
+
if (m_scrollableArea)
- m_scrollableArea->invalidateScrollbarRect(this, rect);
+ m_scrollableArea->invalidateScrollbar(this, rect);
}
IntRect Scrollbar::convertToContainingView(const IntRect& localRect) const
diff --git a/Source/WebCore/platform/Scrollbar.h b/Source/WebCore/platform/Scrollbar.h
index 267eada..161f51e 100644
--- a/Source/WebCore/platform/Scrollbar.h
+++ b/Source/WebCore/platform/Scrollbar.h
@@ -146,7 +146,7 @@ protected:
ScrollbarOrientation m_orientation;
ScrollbarControlSize m_controlSize;
ScrollbarTheme* m_theme;
-
+
int m_visibleSize;
int m_totalSize;
float m_currentPos;
diff --git a/Source/WebCore/platform/ScrollbarThemeComposite.cpp b/Source/WebCore/platform/ScrollbarThemeComposite.cpp
index 26f1494..d9f2662 100644
--- a/Source/WebCore/platform/ScrollbarThemeComposite.cpp
+++ b/Source/WebCore/platform/ScrollbarThemeComposite.cpp
@@ -95,7 +95,7 @@ bool ScrollbarThemeComposite::paint(Scrollbar* scrollbar, GraphicsContext* graph
scrollMask |= BackTrackPart;
if (damageRect.intersects(endTrackRect))
scrollMask |= ForwardTrackPart;
- }
+ }
#if PLATFORM(WIN)
// FIXME: This API makes the assumption that the custom scrollbar's metrics will match
diff --git a/Source/WebCore/platform/SecureTextInput.cpp b/Source/WebCore/platform/SecureTextInput.cpp
index bebb37e..06e1c86 100644
--- a/Source/WebCore/platform/SecureTextInput.cpp
+++ b/Source/WebCore/platform/SecureTextInput.cpp
@@ -10,49 +10,34 @@
* 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.
+ * 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.
*/
#include "config.h"
+
+// FIXME: This should be moved to WebKit, because browser process needs to track secure input state anyway to manipulate input contexts.
+#if PLATFORM(CHROMIUM) && OS(DARWIN)
#include "SecureTextInput.h"
-#if USE(CARBON_SECURE_INPUT_MODE)
#import <Carbon/Carbon.h>
-#endif
namespace WebCore {
-#if USE(CARBON_SECURE_INPUT_MODE)
-
-#ifdef BUILDING_ON_TIGER
-const short enableRomanKeyboardsOnly = -23;
-#endif
-
void enableSecureTextInput()
{
if (IsSecureEventInputEnabled())
return;
EnableSecureEventInput();
-#ifdef BUILDING_ON_TIGER
- KeyScript(enableRomanKeyboardsOnly);
-#else
- // WebKit substitutes nil for input context when in password field, which corresponds to null TSMDocument. So, there is
- // no need to call TSMGetActiveDocument(), which may return an incorrect result when selection hasn't been yet updated
- // after focusing a node.
- CFArrayRef inputSources = TISCreateASCIICapableInputSourceList();
- TSMSetDocumentProperty(0, kTSMDocumentEnabledInputSourcesPropertyTag, sizeof(CFArrayRef), &inputSources);
- CFRelease(inputSources);
-#endif
}
void disableSecureTextInput()
@@ -60,13 +45,8 @@ void disableSecureTextInput()
if (!IsSecureEventInputEnabled())
return;
DisableSecureEventInput();
-#ifdef BUILDING_ON_TIGER
- KeyScript(smKeyEnableKybds);
-#else
- TSMRemoveDocumentProperty(0, kTSMDocumentEnabledInputSourcesPropertyTag);
-#endif
}
-#endif // USE(CARBON_SECURE_INPUT_MODE)
-
} // namespace WebCore
+
+#endif // PLATFORM(CHROMIUM) && OS(DARWIN)
diff --git a/Source/WebCore/platform/SecureTextInput.h b/Source/WebCore/platform/SecureTextInput.h
index c55981e..f1fc083 100644
--- a/Source/WebCore/platform/SecureTextInput.h
+++ b/Source/WebCore/platform/SecureTextInput.h
@@ -40,7 +40,7 @@ namespace WebCore {
void enableSecureTextInput();
void disableSecureTextInput();
-#if !USE(CARBON_SECURE_INPUT_MODE)
+#if !(PLATFORM(CHROMIUM) && OS(DARWIN))
inline void enableSecureTextInput() { }
inline void disableSecureTextInput() { }
#endif
diff --git a/Source/WebCore/platform/TreeShared.h b/Source/WebCore/platform/TreeShared.h
index 9e27c5e..2888ebf 100644
--- a/Source/WebCore/platform/TreeShared.h
+++ b/Source/WebCore/platform/TreeShared.h
@@ -109,11 +109,7 @@ public:
bool m_inRemovedLastRefFunction;
#endif
-private:
-#ifndef NDEBUG
- friend void adopted<>(TreeShared<T>*);
-#endif
-
+protected:
virtual void removedLastRef()
{
#ifndef NDEBUG
@@ -122,6 +118,11 @@ private:
delete this;
}
+private:
+#ifndef NDEBUG
+ friend void adopted<>(TreeShared<T>*);
+#endif
+
int m_refCount;
T* m_parent;
#ifndef NDEBUG
diff --git a/Source/WebCore/platform/audio/FFTFrame.cpp b/Source/WebCore/platform/audio/FFTFrame.cpp
index d9979d9..fbb5dfe 100644
--- a/Source/WebCore/platform/audio/FFTFrame.cpp
+++ b/Source/WebCore/platform/audio/FFTFrame.cpp
@@ -32,6 +32,10 @@
#include "FFTFrame.h"
+#ifndef NDEBUG
+#include <stdio.h>
+#endif
+
#include <wtf/Complex.h>
#include <wtf/MathExtras.h>
#include <wtf/OwnPtr.h>
diff --git a/Source/WebCore/platform/audio/FFTFrameStub.cpp b/Source/WebCore/platform/audio/FFTFrameStub.cpp
index c76c0e2..5494cd0 100644
--- a/Source/WebCore/platform/audio/FFTFrameStub.cpp
+++ b/Source/WebCore/platform/audio/FFTFrameStub.cpp
@@ -79,6 +79,10 @@ void FFTFrame::doInverseFFT(float* data)
ASSERT_NOT_REACHED();
}
+void FFTFrame::initialize()
+{
+}
+
void FFTFrame::cleanup()
{
ASSERT_NOT_REACHED();
diff --git a/Source/WebCore/platform/audio/HRTFDatabaseLoader.cpp b/Source/WebCore/platform/audio/HRTFDatabaseLoader.cpp
index 4368d22..4fcce31 100644
--- a/Source/WebCore/platform/audio/HRTFDatabaseLoader.cpp
+++ b/Source/WebCore/platform/audio/HRTFDatabaseLoader.cpp
@@ -120,6 +120,14 @@ bool HRTFDatabaseLoader::isLoaded() const
return m_hrtfDatabase.get();
}
+
+void HRTFDatabaseLoader::waitForLoaderThreadCompletion()
+{
+ ASSERT(!isMainThread());
+ ASSERT(m_databaseLoaderThread);
+ waitForThreadCompletion(m_databaseLoaderThread, 0);
+}
+
HRTFDatabase* HRTFDatabaseLoader::defaultHRTFDatabase()
{
if (!s_loader)
diff --git a/Source/WebCore/platform/audio/HRTFDatabaseLoader.h b/Source/WebCore/platform/audio/HRTFDatabaseLoader.h
index 72002c5..6dc02a6 100644
--- a/Source/WebCore/platform/audio/HRTFDatabaseLoader.h
+++ b/Source/WebCore/platform/audio/HRTFDatabaseLoader.h
@@ -46,11 +46,18 @@ public:
// Must be called from the main thread.
static PassRefPtr<HRTFDatabaseLoader> createAndLoadAsynchronouslyIfNecessary(double sampleRate);
+ // Returns the singleton HRTFDatabaseLoader.
+ static HRTFDatabaseLoader* loader() { return s_loader; }
+
// Both constructor and destructor must be called from the main thread.
~HRTFDatabaseLoader();
// Returns true once the default database has been completely loaded.
bool isLoaded() const;
+
+ // May not be called on the main thread.
+ // This is so a different background thread may synchronize with the loader thread.
+ void waitForLoaderThreadCompletion();
HRTFDatabase* database() { return m_hrtfDatabase.get(); }
diff --git a/Source/WebCore/platform/audio/SincResampler.h b/Source/WebCore/platform/audio/SincResampler.h
index 92adb95..62339b3 100644
--- a/Source/WebCore/platform/audio/SincResampler.h
+++ b/Source/WebCore/platform/audio/SincResampler.h
@@ -40,7 +40,7 @@ public:
// scaleFactor == sourceSampleRate / destinationSampleRate
// kernelSize can be adjusted for quality (higher is better)
// numberOfKernelOffsets is used for interpolation and is the number of sub-sample kernel shifts.
- SincResampler(double scaleFactor, unsigned kernelSize = 64, unsigned numberOfKernelOffsets = 32);
+ SincResampler(double scaleFactor, unsigned kernelSize = 32, unsigned numberOfKernelOffsets = 32);
// Processes numberOfSourceFrames from source to produce numberOfSourceFrames / scaleFactor frames in destination.
void process(float* source, float* destination, unsigned numberOfSourceFrames);
diff --git a/Source/WebCore/platform/audio/fftw/FFTFrameFFTW.cpp b/Source/WebCore/platform/audio/fftw/FFTFrameFFTW.cpp
index 878ed9f..1a344a6 100644
--- a/Source/WebCore/platform/audio/fftw/FFTFrameFFTW.cpp
+++ b/Source/WebCore/platform/audio/fftw/FFTFrameFFTW.cpp
@@ -29,6 +29,8 @@
#if ENABLE(WEB_AUDIO)
+#if !OS(DARWIN) && USE(WEBAUDIO_FFTW)
+
#include "FFTFrame.h"
#include <wtf/MathExtras.h>
@@ -298,4 +300,6 @@ fftwf_plan FFTFrame::fftwPlanForSize(unsigned fftSize, Direction direction,
} // namespace WebCore
+#endif // !OS(DARWIN) && USE(WEBAUDIO_FFTW)
+
#endif // ENABLE(WEB_AUDIO)
diff --git a/Source/WebCore/platform/audio/mkl/FFTFrameMKL.cpp b/Source/WebCore/platform/audio/mkl/FFTFrameMKL.cpp
index 3ac6b36..6bf2c1e 100644
--- a/Source/WebCore/platform/audio/mkl/FFTFrameMKL.cpp
+++ b/Source/WebCore/platform/audio/mkl/FFTFrameMKL.cpp
@@ -30,6 +30,8 @@
#if ENABLE(WEB_AUDIO)
+#if !OS(DARWIN) && USE(WEBAUDIO_MKL)
+
#include "FFTFrame.h"
#include "mkl_vml.h"
@@ -172,7 +174,7 @@ void FFTFrame::doFFT(float* data)
{
// Compute Forward transform.
MKL_LONG status = DftiComputeForward(m_handle, data, m_complexData.data());
- ASSERT(DftiErrorClass(status, DFTI_NO_ERROR));
+ ASSERT_UNUSED(status, DftiErrorClass(status, DFTI_NO_ERROR));
// De-interleave to separate real and complex arrays. FIXME:
// figure out if it's possible to get MKL to use split-complex
@@ -197,7 +199,7 @@ void FFTFrame::doInverseFFT(float* data)
// Compute backward transform.
MKL_LONG status = DftiComputeBackward(m_handle, interleavedData, data);
- ASSERT(DftiErrorClass(status, DFTI_NO_ERROR));
+ ASSERT_UNUSED(status, DftiErrorClass(status, DFTI_NO_ERROR));
}
void FFTFrame::initialize()
@@ -212,7 +214,7 @@ void FFTFrame::cleanup()
for (int i = 0; i < kMaxFFTPow2Size; ++i) {
if (descriptorHandles[i]) {
MKL_LONG status = DftiFreeDescriptor(&descriptorHandles[i]);
- ASSERT(DftiErrorClass(status, DFTI_NO_ERROR));
+ ASSERT_UNUSED(status, DftiErrorClass(status, DFTI_NO_ERROR));
}
}
@@ -261,4 +263,6 @@ DFTI_DESCRIPTOR_HANDLE FFTFrame::descriptorHandleForSize(unsigned fftSize)
} // namespace WebCore
+#endif // !OS(DARWIN) && USE(WEBAUDIO_MKL)
+
#endif // ENABLE(WEB_AUDIO)
diff --git a/Source/WebCore/platform/chromium/ClipboardMimeTypes.cpp b/Source/WebCore/platform/chromium/ClipboardMimeTypes.cpp
index 27e68ff..94ce27d 100644
--- a/Source/WebCore/platform/chromium/ClipboardMimeTypes.cpp
+++ b/Source/WebCore/platform/chromium/ClipboardMimeTypes.cpp
@@ -41,5 +41,6 @@ const char mimeTypeURL[] = "url";
const char mimeTypeTextURIList[] = "text/uri-list";
const char mimeTypeDownloadURL[] = "downloadurl";
const char mimeTypeFiles[] = "Files";
+const char mimeTypeImagePng[] = "image/png";
} // namespace WebCore
diff --git a/Source/WebCore/platform/chromium/ClipboardMimeTypes.h b/Source/WebCore/platform/chromium/ClipboardMimeTypes.h
index 31e2d3e..3e4ab50 100644
--- a/Source/WebCore/platform/chromium/ClipboardMimeTypes.h
+++ b/Source/WebCore/platform/chromium/ClipboardMimeTypes.h
@@ -41,6 +41,7 @@ extern const char mimeTypeURL[];
extern const char mimeTypeTextURIList[];
extern const char mimeTypeDownloadURL[];
extern const char mimeTypeFiles[];
+extern const char mimeTypeImagePng[];
} // namespace WebCore
diff --git a/Source/WebCore/platform/chromium/DataTransferItemChromium.cpp b/Source/WebCore/platform/chromium/DataTransferItemChromium.cpp
index 7857336..24b498e 100644
--- a/Source/WebCore/platform/chromium/DataTransferItemChromium.cpp
+++ b/Source/WebCore/platform/chromium/DataTransferItemChromium.cpp
@@ -33,9 +33,11 @@
#if ENABLE(DATA_TRANSFER_ITEMS)
+#include "Blob.h"
#include "Clipboard.h"
#include "ClipboardMimeTypes.h"
#include "PlatformBridge.h"
+#include "SharedBuffer.h"
#include "StringCallback.h"
namespace WebCore {
@@ -88,6 +90,8 @@ void DataTransferItemChromium::getAsString(PassRefPtr<StringCallback> callback)
callback->scheduleCallback(m_context, m_data);
return;
}
+
+ ASSERT(m_source == PasteboardSource);
// This is ugly but there's no real alternative.
if (m_type == mimeTypeTextPlain) {
callback->scheduleCallback(m_context, PlatformBridge::clipboardReadPlainText(PasteboardPrivate::StandardBuffer));
@@ -103,6 +107,33 @@ void DataTransferItemChromium::getAsString(PassRefPtr<StringCallback> callback)
ASSERT_NOT_REACHED();
}
+PassRefPtr<Blob> DataTransferItemChromium::getAsFile()
+{
+ if (m_source == InternalSource)
+ return 0;
+
+ ASSERT(m_source == PasteboardSource);
+ if (m_type == mimeTypeImagePng) {
+ // FIXME: This is pretty inefficient. We copy the data from the browser
+ // to the renderer. We then place it in a blob in WebKit, which
+ // registers it and copies it *back* to the browser. When a consumer
+ // wants to read the data, we then copy the data back into the renderer.
+ // https://bugs.webkit.org/show_bug.cgi?id=58107 has been filed to track
+ // improvements to this code (in particular, add a registerClipboardBlob
+ // method to the blob registry; that way the data is only copied over
+ // into the renderer when it's actually read, not when the blob is
+ // initially constructed).
+ RefPtr<SharedBuffer> data = PlatformBridge::clipboardReadImage(PasteboardPrivate::StandardBuffer);
+ RefPtr<RawData> rawData = RawData::create();
+ rawData->mutableData()->append(data->data(), data->size());
+ OwnPtr<BlobData> blobData = BlobData::create();
+ blobData->appendData(rawData, 0, -1);
+ blobData->setContentType(mimeTypeImagePng);
+ return Blob::create(blobData.release(), data->size());
+ }
+ return 0;
+}
+
} // namespace WebCore
#endif // ENABLE(DATA_TRANSFER_ITEMS)
diff --git a/Source/WebCore/platform/chromium/DataTransferItemChromium.h b/Source/WebCore/platform/chromium/DataTransferItemChromium.h
index 77f74f2..66be96e 100644
--- a/Source/WebCore/platform/chromium/DataTransferItemChromium.h
+++ b/Source/WebCore/platform/chromium/DataTransferItemChromium.h
@@ -51,6 +51,7 @@ public:
virtual String type() const;
virtual void getAsString(PassRefPtr<StringCallback>);
+ virtual PassRefPtr<Blob> getAsFile();
private:
enum DataSource {
diff --git a/Source/WebCore/platform/chromium/PlatformBridge.h b/Source/WebCore/platform/chromium/PlatformBridge.h
index 1c3ccbd..3a04617 100644
--- a/Source/WebCore/platform/chromium/PlatformBridge.h
+++ b/Source/WebCore/platform/chromium/PlatformBridge.h
@@ -98,6 +98,7 @@ public:
static String clipboardReadPlainText(PasteboardPrivate::ClipboardBuffer);
static void clipboardReadHTML(PasteboardPrivate::ClipboardBuffer, String*, KURL*);
+ static PassRefPtr<SharedBuffer> clipboardReadImage(PasteboardPrivate::ClipboardBuffer);
// Only the clipboardRead functions take a buffer argument because
// Chromium currently uses a different technique to write to alternate
diff --git a/Source/WebCore/platform/chromium/PopupMenuChromium.cpp b/Source/WebCore/platform/chromium/PopupMenuChromium.cpp
index e83ebe4..af97ecf 100644
--- a/Source/WebCore/platform/chromium/PopupMenuChromium.cpp
+++ b/Source/WebCore/platform/chromium/PopupMenuChromium.cpp
@@ -571,10 +571,10 @@ void PopupContainer::refresh(const IntRect& targetControlRect)
location.move(0, targetControlRect.height());
listBox()->updateFromElement();
- // Store the original height to check if we need to request the location.
- int originalHeight = height();
+ // Store the original size to check if we need to request the location.
+ IntSize originalSize = size();
IntRect widgetRect = layoutAndCalculateWidgetRect(targetControlRect.height(), location);
- if (originalHeight != widgetRect.height())
+ if (originalSize != widgetRect.size())
setFrameRect(widgetRect);
invalidate();
diff --git a/Source/WebCore/platform/efl/RenderThemeEfl.cpp b/Source/WebCore/platform/efl/RenderThemeEfl.cpp
index 439e377..3ce50e3 100644
--- a/Source/WebCore/platform/efl/RenderThemeEfl.cpp
+++ b/Source/WebCore/platform/efl/RenderThemeEfl.cpp
@@ -34,6 +34,7 @@
#include "NotImplemented.h"
#include "PaintInfo.h"
#include "Page.h"
+#include "PlatformContextCairo.h"
#include "RenderBox.h"
#include "RenderObject.h"
#include "RenderProgress.h"
@@ -605,6 +606,8 @@ const char* RenderThemeEfl::edjeGroupFromFormType(FormType type) const
#if ENABLE(VIDEO)
W("mediacontrol/playpause_button"),
W("mediacontrol/mute_button"),
+ W("mediacontrol/seekforward_button"),
+ W("mediacontrol/seekbackward_button"),
#endif
#undef W
0
@@ -1075,7 +1078,11 @@ bool RenderThemeEfl::emitMediaButtonSignal(FormType formType, MediaControlElemen
edje_object_signal_emit(entry->o, "mute", "");
else if (mediaElementType == MediaUnMuteButton)
edje_object_signal_emit(entry->o, "sound", "");
- else
+ else if (mediaElementType == MediaSeekForwardButton)
+ edje_object_signal_emit(entry->o, "seekforward", "");
+ else if (mediaElementType == MediaSeekBackButton)
+ edje_object_signal_emit(entry->o, "seekbackward", "");
+ else
return false;
return true;
@@ -1106,35 +1113,49 @@ bool RenderThemeEfl::paintMediaMuteButton(RenderObject* object, const PaintInfo&
HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(mediaNode);
- if (!emitMediaButtonSignal(MediaMuteUnMuteButton, mediaElement->muted() ? MediaMuteButton : MediaUnMuteButton, rect))
+ if (!emitMediaButtonSignal(MuteUnMuteButton, mediaElement->muted() ? MediaMuteButton : MediaUnMuteButton, rect))
return false;
- return paintThemePart(object, MediaMuteUnMuteButton, info, rect);
+ return paintThemePart(object, MuteUnMuteButton, info, rect);
}
bool RenderThemeEfl::paintMediaPlayButton(RenderObject* object, const PaintInfo& info, const IntRect& rect)
{
Node* node = object->node();
- if (!node)
+ if (!node || !node->isMediaControlElement())
return false;
MediaControlPlayButtonElement* button = static_cast<MediaControlPlayButtonElement*>(node);
- if (!emitMediaButtonSignal(MediaPlayPauseButton, button->displayType(), rect))
+ if (!emitMediaButtonSignal(PlayPauseButton, button->displayType(), rect))
return false;
- return paintThemePart(object, MediaPlayPauseButton, info, rect);
+ return paintThemePart(object, PlayPauseButton, info, rect);
}
bool RenderThemeEfl::paintMediaSeekBackButton(RenderObject* object, const PaintInfo& info, const IntRect& rect)
{
- notImplemented();
- return false;
+ Node* node = object->node();
+ if (!node || !node->isMediaControlElement())
+ return 0;
+
+ MediaControlSeekButtonElement* button = static_cast<MediaControlSeekButtonElement*>(node);
+ if (!emitMediaButtonSignal(SeekBackwardButton, button->displayType(), rect))
+ return false;
+
+ return paintThemePart(object, SeekBackwardButton, info, rect);
}
bool RenderThemeEfl::paintMediaSeekForwardButton(RenderObject* object, const PaintInfo& info, const IntRect& rect)
{
- notImplemented();
- return false;
+ Node* node = object->node();
+ if (!node || !node->isMediaControlElement())
+ return 0;
+
+ MediaControlSeekButtonElement* button = static_cast<MediaControlSeekButtonElement*>(node);
+ if (!emitMediaButtonSignal(SeekForwardButton, button->displayType(), rect))
+ return false;
+
+ return paintThemePart(object, SeekForwardButton, info, rect);
}
bool RenderThemeEfl::paintMediaSliderTrack(RenderObject* object, const PaintInfo& info, const IntRect& rect)
diff --git a/Source/WebCore/platform/efl/RenderThemeEfl.h b/Source/WebCore/platform/efl/RenderThemeEfl.h
index fe8e2d2..054f91d 100644
--- a/Source/WebCore/platform/efl/RenderThemeEfl.h
+++ b/Source/WebCore/platform/efl/RenderThemeEfl.h
@@ -59,8 +59,10 @@ enum FormType { // KEEP IN SYNC WITH edjeGroupFromFormType()
SliderVertical,
SliderHorizontal,
#if ENABLE(VIDEO)
- MediaPlayPauseButton,
- MediaMuteUnMuteButton,
+ PlayPauseButton,
+ MuteUnMuteButton,
+ SeekForwardButton,
+ SeekBackwardButton,
#endif
FormTypeLast
};
diff --git a/Source/WebCore/platform/graphics/ANGLEWebKitBridge.h b/Source/WebCore/platform/graphics/ANGLEWebKitBridge.h
index 7bddbf4..a9d2238 100644
--- a/Source/WebCore/platform/graphics/ANGLEWebKitBridge.h
+++ b/Source/WebCore/platform/graphics/ANGLEWebKitBridge.h
@@ -26,11 +26,15 @@
#ifndef ANGLEWebKitBridge_h
#define ANGLEWebKitBridge_h
-#include "ANGLE/ShaderLang.h"
#include "PlatformString.h"
-
#include <wtf/text/CString.h>
+#if !PLATFORM(GTK)
+#include "ANGLE/ShaderLang.h"
+#else
+#include "ShaderLang.h"
+#endif
+
namespace WebCore {
enum ANGLEShaderType {
diff --git a/Source/WebCore/platform/graphics/BitmapImage.cpp b/Source/WebCore/platform/graphics/BitmapImage.cpp
index 6027f34..7cdb43d 100644
--- a/Source/WebCore/platform/graphics/BitmapImage.cpp
+++ b/Source/WebCore/platform/graphics/BitmapImage.cpp
@@ -103,6 +103,7 @@ void BitmapImage::destroyDecodedDataIfNecessary(bool destroyAll)
void BitmapImage::destroyMetadataAndNotify(int framesCleared)
{
m_isSolidColor = false;
+ m_checkedForSolidColor = false;
invalidatePlatformData();
int deltaBytes = framesCleared * -frameBytes(m_size);
diff --git a/Source/WebCore/platform/graphics/BitmapImage.h b/Source/WebCore/platform/graphics/BitmapImage.h
index c8cf0ab..8d9cd94 100644
--- a/Source/WebCore/platform/graphics/BitmapImage.h
+++ b/Source/WebCore/platform/graphics/BitmapImage.h
@@ -53,11 +53,11 @@ namespace WebCore {
struct FrameData;
}
-// This complicated-looking declaration tells the FrameData Vector that it should copy without
-// invoking our constructor or destructor. This allows us to have a vector even for a struct
-// that's not copyable.
namespace WTF {
- template<> struct VectorTraits<WebCore::FrameData> : public SimpleClassVectorTraits {};
+ // FIXME: This declaration gives FrameData a default constructor that zeroes
+ // all its data members, even though FrameData's default constructor defined
+ // below does not zero all its data members. One of these must be wrong!
+ template<> struct VectorTraits<WebCore::FrameData> : public SimpleClassVectorTraits { };
}
namespace WebCore {
@@ -139,8 +139,9 @@ public:
virtual CFDataRef getTIFFRepresentation();
#endif
-#if PLATFORM(CG)
+#if USE(CG)
virtual CGImageRef getCGImageRef();
+ virtual CGImageRef getFirstCGImageRefOfSize(const IntSize&);
#endif
#if PLATFORM(WIN) || (PLATFORM(QT) && OS(WINDOWS))
@@ -160,6 +161,14 @@ public:
#endif
virtual NativeImagePtr nativeImageForCurrentFrame() { return frameAtIndex(currentFrame()); }
+ bool frameHasAlphaAtIndex(size_t);
+
+#if !ASSERT_DISABLED
+ bool notSolidColor()
+ {
+ return size().width() != 1 || size().height() != 1 || frameCount() > 1;
+ }
+#endif
protected:
enum RepetitionCountStatus {
@@ -190,7 +199,6 @@ protected:
NativeImagePtr frameAtIndex(size_t);
bool frameIsCompleteAtIndex(size_t);
float frameDurationAtIndex(size_t);
- bool frameHasAlphaAtIndex(size_t);
// Decodes and caches a frame. Never accessed except internally.
void cacheFrame(size_t index);
diff --git a/Source/WebCore/platform/graphics/Color.h b/Source/WebCore/platform/graphics/Color.h
index 05d9554..02ec005 100644
--- a/Source/WebCore/platform/graphics/Color.h
+++ b/Source/WebCore/platform/graphics/Color.h
@@ -30,7 +30,7 @@
#include <wtf/Forward.h>
#include <wtf/unicode/Unicode.h>
-#if PLATFORM(CG)
+#if USE(CG)
#include "ColorSpace.h"
typedef struct CGColor* CGColorRef;
#endif
@@ -143,7 +143,7 @@ public:
operator wxColour() const;
#endif
-#if PLATFORM(CG)
+#if USE(CG)
Color(CGColorRef);
#endif
@@ -191,7 +191,7 @@ inline bool operator!=(const Color& a, const Color& b)
Color colorFromPremultipliedARGB(unsigned);
unsigned premultipliedARGBFromColor(const Color&);
-#if PLATFORM(CG)
+#if USE(CG)
CGColorRef cachedCGColor(const Color&, ColorSpace);
#endif
diff --git a/Source/WebCore/platform/graphics/ContextShadow.h b/Source/WebCore/platform/graphics/ContextShadow.h
index 850d489..87acee0 100644
--- a/Source/WebCore/platform/graphics/ContextShadow.h
+++ b/Source/WebCore/platform/graphics/ContextShadow.h
@@ -34,7 +34,7 @@
#include "IntRect.h"
#include <wtf/RefCounted.h>
-#if PLATFORM(CAIRO)
+#if USE(CAIRO)
typedef struct _cairo cairo_t;
typedef struct _cairo_surface cairo_surface_t;
#elif PLATFORM(QT)
@@ -49,7 +49,7 @@ namespace WebCore {
class AffineTransform;
class GraphicsContext;
-#if PLATFORM(CAIRO)
+#if USE(CAIRO)
typedef cairo_surface_t* PlatformImage;
typedef cairo_t* PlatformContext;
#elif PLATFORM(QT)
@@ -116,7 +116,7 @@ public:
void setShadowsIgnoreTransforms(bool enable) { m_shadowsIgnoreTransforms = enable; }
bool shadowsIgnoreTransforms() const { return m_shadowsIgnoreTransforms; }
-#if PLATFORM(CAIRO)
+#if USE(CAIRO)
void drawRectShadow(GraphicsContext* context, const IntRect& rect, const IntSize& topLeftRadius = IntSize(), const IntSize& topRightRadius = IntSize(), const IntSize& bottomLeftRadius = IntSize(), const IntSize& bottomRightRadius = IntSize());
#endif
#if PLATFORM(QT)
@@ -135,7 +135,7 @@ private:
void blurLayerImage(unsigned char*, const IntSize& imageSize, int stride);
IntRect calculateLayerBoundingRect(GraphicsContext*, const FloatRect& layerArea, const IntRect& clipRect);
-#if PLATFORM(CAIRO)
+#if USE(CAIRO)
void drawRectShadowWithoutTiling(GraphicsContext*, const IntRect& shadowRect, const IntSize& topLeftRadius, const IntSize& topRightRadius, const IntSize& bottomLeftRadius, const IntSize& bottomRightRadius, float alpha);
#endif
};
diff --git a/Source/WebCore/platform/graphics/DashArray.h b/Source/WebCore/platform/graphics/DashArray.h
index 46b84a4..0516584 100644
--- a/Source/WebCore/platform/graphics/DashArray.h
+++ b/Source/WebCore/platform/graphics/DashArray.h
@@ -28,9 +28,9 @@
#include <wtf/Vector.h>
-#if PLATFORM(CG)
+#if USE(CG)
typedef Vector<CGFloat> DashArray;
-#elif PLATFORM(CAIRO)
+#elif USE(CAIRO)
typedef Vector<double> DashArray;
#else
typedef Vector<float> DashArray;
diff --git a/Source/WebCore/platform/graphics/Extensions3D.h b/Source/WebCore/platform/graphics/Extensions3D.h
index 5d5a5b7..fee1133 100644
--- a/Source/WebCore/platform/graphics/Extensions3D.h
+++ b/Source/WebCore/platform/graphics/Extensions3D.h
@@ -66,6 +66,11 @@ public:
// extension names for which supports returns true.
virtual void ensureEnabled(const String&) = 0;
+ // Takes full name of extension: for example, "GL_EXT_texture_format_BGRA8888".
+ // Checks to see whether the given extension is actually enabled (see ensureEnabled).
+ // Has no other side-effects.
+ virtual bool isEnabled(const String&) = 0;
+
enum ExtensionsEnumType {
// GL_EXT_texture_format_BGRA8888 enums
BGRA_EXT = 0x80E1,
diff --git a/Source/WebCore/platform/graphics/FloatPoint.cpp b/Source/WebCore/platform/graphics/FloatPoint.cpp
index 226ae71..abe9b86 100644
--- a/Source/WebCore/platform/graphics/FloatPoint.cpp
+++ b/Source/WebCore/platform/graphics/FloatPoint.cpp
@@ -31,6 +31,7 @@
#include "TransformationMatrix.h"
#include "FloatConversion.h"
#include "IntPoint.h"
+#include <limits>
#include <math.h>
namespace WebCore {
@@ -73,4 +74,43 @@ FloatPoint FloatPoint::narrowPrecision(double x, double y)
return FloatPoint(narrowPrecisionToFloat(x), narrowPrecisionToFloat(y));
}
+float findSlope(const FloatPoint& p1, const FloatPoint& p2, float& c)
+{
+ if (p2.x() == p1.x())
+ return std::numeric_limits<float>::infinity();
+
+ // y = mx + c
+ float slope = (p2.y() - p1.y()) / (p2.x() - p1.x());
+ c = p1.y() - slope * p1.x();
+ return slope;
+}
+
+bool findIntersection(const FloatPoint& p1, const FloatPoint& p2, const FloatPoint& d1, const FloatPoint& d2, FloatPoint& intersection)
+{
+ float pOffset = 0;
+ float pSlope = findSlope(p1, p2, pOffset);
+
+ float dOffset = 0;
+ float dSlope = findSlope(d1, d2, dOffset);
+
+ if (dSlope == pSlope)
+ return false;
+
+ if (pSlope == std::numeric_limits<float>::infinity()) {
+ intersection.setX(p1.x());
+ intersection.setY(dSlope * intersection.x() + dOffset);
+ return true;
+ }
+ if (dSlope == std::numeric_limits<float>::infinity()) {
+ intersection.setX(d1.x());
+ intersection.setY(pSlope * intersection.x() + pOffset);
+ return true;
+ }
+
+ // Find x at intersection, where ys overlap; x = (c' - c) / (m - m')
+ intersection.setX((dOffset - pOffset) / (pSlope - dSlope));
+ intersection.setY(pSlope * intersection.x() + pOffset);
+ return true;
+}
+
}
diff --git a/Source/WebCore/platform/graphics/FloatPoint.h b/Source/WebCore/platform/graphics/FloatPoint.h
index c4b2943..fd73c69 100644
--- a/Source/WebCore/platform/graphics/FloatPoint.h
+++ b/Source/WebCore/platform/graphics/FloatPoint.h
@@ -31,7 +31,7 @@
#include "IntPoint.h"
#include <wtf/MathExtras.h>
-#if PLATFORM(CG)
+#if USE(CG) || USE(SKIA_ON_MAC_CHROME)
typedef struct CGPoint CGPoint;
#endif
@@ -109,7 +109,7 @@ public:
return m_x * m_x + m_y * m_y;
}
-#if PLATFORM(CG)
+#if USE(CG) || USE(SKIA_ON_MAC_CHROME)
FloatPoint(const CGPoint&);
operator CGPoint() const;
#endif
@@ -202,6 +202,11 @@ inline IntPoint roundedIntPoint(const FloatPoint& p)
return IntPoint(static_cast<int>(roundf(p.x())), static_cast<int>(roundf(p.y())));
}
+float findSlope(const FloatPoint& p1, const FloatPoint& p2, float& c);
+
+// Find point where lines through the two pairs of points intersect. Returns false if the lines don't intersect.
+bool findIntersection(const FloatPoint& p1, const FloatPoint& p2, const FloatPoint& d1, const FloatPoint& d2, FloatPoint& intersection);
+
}
#endif
diff --git a/Source/WebCore/platform/graphics/FloatRect.cpp b/Source/WebCore/platform/graphics/FloatRect.cpp
index 36f3d3a..165ef76 100644
--- a/Source/WebCore/platform/graphics/FloatRect.cpp
+++ b/Source/WebCore/platform/graphics/FloatRect.cpp
@@ -30,8 +30,8 @@
#include "FloatConversion.h"
#include "IntRect.h"
#include <algorithm>
-#include <limits>
#include <math.h>
+#include <wtf/MathExtras.h>
using std::max;
using std::min;
@@ -97,6 +97,24 @@ void FloatRect::unite(const FloatRect& other)
setLocationAndSizeFromEdges(l, t, r, b);
}
+void FloatRect::uniteIfNonZero(const FloatRect& other)
+{
+ // Handle empty special cases first.
+ if (!other.width() && !other.height())
+ return;
+ if (!width() && !height()) {
+ *this = other;
+ return;
+ }
+
+ float left = min(x(), other.x());
+ float top = min(y(), other.y());
+ float right = max(maxX(), other.maxX());
+ float bottom = max(maxY(), other.maxY());
+
+ setLocationAndSizeFromEdges(left, top, right, bottom);
+}
+
void FloatRect::scale(float sx, float sy)
{
m_location.setX(x() * sx);
@@ -182,6 +200,7 @@ IntRect enclosingIntRect(const FloatRect& rect)
float top = floorf(rect.y());
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 bd23476..493c068 100644
--- a/Source/WebCore/platform/graphics/FloatRect.h
+++ b/Source/WebCore/platform/graphics/FloatRect.h
@@ -29,7 +29,7 @@
#include "FloatPoint.h"
-#if PLATFORM(CG)
+#if USE(CG) || USE(SKIA_ON_MAC_CHROME)
typedef struct CGRect CGRect;
#endif
@@ -59,7 +59,7 @@ class BRect;
struct SkRect;
#endif
-#if PLATFORM(CAIRO)
+#if USE(CAIRO)
typedef struct _cairo_rectangle cairo_rectangle_t;
#endif
@@ -112,6 +112,7 @@ public:
void intersect(const FloatRect&);
void unite(const FloatRect&);
+ void uniteIfNonZero(const FloatRect&);
// 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.
@@ -136,7 +137,7 @@ public:
void fitToPoints(const FloatPoint& p0, const FloatPoint& p1, const FloatPoint& p2);
void fitToPoints(const FloatPoint& p0, const FloatPoint& p1, const FloatPoint& p2, const FloatPoint& p3);
-#if PLATFORM(CG)
+#if USE(CG) || USE(SKIA_ON_MAC_CHROME)
FloatRect(const CGRect&);
operator CGRect() const;
#endif
@@ -172,7 +173,7 @@ public:
operator VGRect() const;
#endif
-#if PLATFORM(CAIRO)
+#if USE(CAIRO)
FloatRect(const cairo_rectangle_t&);
operator cairo_rectangle_t() const;
#endif
diff --git a/Source/WebCore/platform/graphics/FloatSize.h b/Source/WebCore/platform/graphics/FloatSize.h
index 160fc9a..1485c71 100644
--- a/Source/WebCore/platform/graphics/FloatSize.h
+++ b/Source/WebCore/platform/graphics/FloatSize.h
@@ -31,7 +31,7 @@
#include "IntSize.h"
#include <wtf/MathExtras.h>
-#if PLATFORM(CG) || (PLATFORM(WX) && OS(DARWIN))
+#if USE(CG) || (PLATFORM(WX) && OS(DARWIN)) || USE(SKIA_ON_MAC_CHROME)
typedef struct CGSize CGSize;
#endif
@@ -89,7 +89,7 @@ public:
return m_width * m_width + m_height * m_height;
}
-#if PLATFORM(CG) || (PLATFORM(WX) && OS(DARWIN))
+#if USE(CG) || (PLATFORM(WX) && OS(DARWIN)) || USE(SKIA_ON_MAC_CHROME)
explicit FloatSize(const CGSize&); // don't do this implicitly since it's lossy
operator CGSize() const;
#endif
@@ -148,6 +148,11 @@ inline IntSize roundedIntSize(const FloatSize& p)
return IntSize(static_cast<int>(roundf(p.width())), static_cast<int>(roundf(p.height())));
}
+inline IntSize expandedIntSize(const FloatSize& p)
+{
+ return IntSize(clampToInteger(ceilf(p.width())), clampToInteger(ceilf(p.height())));
+}
+
} // namespace WebCore
#endif // FloatSize_h
diff --git a/Source/WebCore/platform/graphics/Font.h b/Source/WebCore/platform/graphics/Font.h
index 554f8a0..beafdc7 100644
--- a/Source/WebCore/platform/graphics/Font.h
+++ b/Source/WebCore/platform/graphics/Font.h
@@ -203,7 +203,8 @@ public:
FontSelector* fontSelector() const;
static bool treatAsSpace(UChar c) { return c == ' ' || c == '\t' || c == '\n' || c == noBreakSpace; }
- static bool treatAsZeroWidthSpace(UChar c) { return c < 0x20 || (c >= 0x7F && c < 0xA0) || c == softHyphen || (c >= 0x200c && c <= 0x200f) || (c >= 0x202a && c <= 0x202e) || c == objectReplacementCharacter; }
+ static bool treatAsZeroWidthSpace(UChar c) { return treatAsZeroWidthSpaceInComplexScript(c) || c == 0x200c || c == 0x200d; }
+ static bool treatAsZeroWidthSpaceInComplexScript(UChar c) { return c < 0x20 || (c >= 0x7F && c < 0xA0) || c == softHyphen || (c >= 0x200e && c <= 0x200f) || (c >= 0x202a && c <= 0x202e) || c == zeroWidthNoBreakSpace || c == objectReplacementCharacter; }
static bool canReceiveTextEmphasis(UChar32 c);
static inline UChar normalizeSpaces(UChar character)
diff --git a/Source/WebCore/platform/graphics/FontCache.cpp b/Source/WebCore/platform/graphics/FontCache.cpp
index 8c5edfe..d64878b 100644
--- a/Source/WebCore/platform/graphics/FontCache.cpp
+++ b/Source/WebCore/platform/graphics/FontCache.cpp
@@ -121,22 +121,7 @@ struct FontPlatformDataCacheKeyHash {
static const bool safeToCompareToEmptyOrDeleted = true;
};
-struct FontPlatformDataCacheKeyTraits : WTF::GenericHashTraits<FontPlatformDataCacheKey> {
- static const bool emptyValueIsZero = true;
- static const FontPlatformDataCacheKey& emptyValue()
- {
- DEFINE_STATIC_LOCAL(FontPlatformDataCacheKey, key, (nullAtom));
- return key;
- }
- static void constructDeletedValue(FontPlatformDataCacheKey& slot)
- {
- new (&slot) FontPlatformDataCacheKey(HashTableDeletedValue);
- }
- static bool isDeletedValue(const FontPlatformDataCacheKey& value)
- {
- return value.isHashTableDeletedValue();
- }
-};
+struct FontPlatformDataCacheKeyTraits : WTF::SimpleClassHashTraits<FontPlatformDataCacheKey> { };
typedef HashMap<FontPlatformDataCacheKey, FontPlatformData*, FontPlatformDataCacheKeyHash, FontPlatformDataCacheKeyTraits> FontPlatformDataCache;
diff --git a/Source/WebCore/platform/graphics/FontMetrics.h b/Source/WebCore/platform/graphics/FontMetrics.h
index 89c5545..367f004 100644
--- a/Source/WebCore/platform/graphics/FontMetrics.h
+++ b/Source/WebCore/platform/graphics/FontMetrics.h
@@ -96,6 +96,11 @@ public:
int lineGap() const { return lroundf(m_lineGap); }
int lineSpacing() const { return lroundf(m_lineSpacing); }
+ bool hasIdenticalAscentDescentAndLineGap(const FontMetrics& other) const
+ {
+ return ascent() == other.ascent() && descent() == other.descent() && lineGap() == other.lineGap();
+ }
+
private:
friend class SimpleFontData;
diff --git a/Source/WebCore/platform/graphics/FontPlatformData.h b/Source/WebCore/platform/graphics/FontPlatformData.h
index 5981c16..a32215d 100644
--- a/Source/WebCore/platform/graphics/FontPlatformData.h
+++ b/Source/WebCore/platform/graphics/FontPlatformData.h
@@ -51,7 +51,7 @@
#include "RefCountedGDIHandle.h"
#endif
-#if PLATFORM(CAIRO)
+#if USE(CAIRO)
#include "HashFunctions.h"
#include <cairo.h>
#endif
@@ -86,7 +86,7 @@ typedef const struct __CTFont* CTFontRef;
typedef struct HFONT__* HFONT;
#endif
-#if PLATFORM(CG)
+#if USE(CG) || USE(SKIA_ON_MAC_CHROME)
typedef struct CGFont* CGFontRef;
#if OS(DARWIN)
#ifndef BUILDING_ON_TIGER
@@ -119,9 +119,9 @@ public:
#elif OS(DARWIN)
, m_font(hashTableDeletedFontValue())
#endif
-#if PLATFORM(CG) && (defined(BUILDING_ON_TIGER) || PLATFORM(WIN))
+#if USE(CG) && (defined(BUILDING_ON_TIGER) || PLATFORM(WIN))
, m_cgFont(0)
-#elif PLATFORM(CAIRO)
+#elif USE(CAIRO)
, m_scaledFont(hashTableDeletedFontValue())
#endif
, m_isColorBitmapFont(false)
@@ -141,9 +141,9 @@ public:
#if OS(DARWIN)
, m_font(0)
#endif
-#if PLATFORM(CG) && (defined(BUILDING_ON_TIGER) || PLATFORM(WIN))
+#if USE(CG) && (defined(BUILDING_ON_TIGER) || PLATFORM(WIN))
, m_cgFont(0)
-#elif PLATFORM(CAIRO)
+#elif USE(CAIRO)
, m_scaledFont(0)
#endif
, m_isColorBitmapFont(false)
@@ -166,9 +166,9 @@ public:
#if OS(DARWIN)
, m_font(0)
#endif
-#if PLATFORM(CG) && (defined(BUILDING_ON_TIGER) || PLATFORM(WIN))
+#if USE(CG) && (defined(BUILDING_ON_TIGER) || PLATFORM(WIN))
, m_cgFont(0)
-#elif PLATFORM(CAIRO)
+#elif USE(CAIRO)
, m_scaledFont(0)
#endif
, m_isColorBitmapFont(false)
@@ -181,6 +181,7 @@ public:
#if OS(DARWIN)
FontPlatformData(NSFont*, float size, bool syntheticBold = false, bool syntheticOblique = false, FontOrientation = Horizontal,
TextOrientation = TextOrientationVerticalRight, FontWidthVariant = RegularWidth);
+#if USE(CG) || USE(SKIA_ON_MAC_CHROME)
FontPlatformData(CGFontRef cgFont, float size, bool syntheticBold, bool syntheticOblique, FontOrientation orientation,
TextOrientation textOrientation, FontWidthVariant widthVariant)
: m_syntheticBold(syntheticBold)
@@ -195,13 +196,14 @@ public:
{
}
#endif
+#endif
#if PLATFORM(WIN)
FontPlatformData(HFONT, float size, bool syntheticBold, bool syntheticOblique, bool useGDI);
-#if PLATFORM(CG)
+#if USE(CG)
FontPlatformData(HFONT, CGFontRef, float size, bool syntheticBold, bool syntheticOblique, bool useGDI);
#endif
#endif
-#if PLATFORM(CAIRO)
+#if USE(CAIRO)
FontPlatformData(cairo_font_face_t*, float size, bool bold, bool italic);
#endif
@@ -215,7 +217,7 @@ public:
void setFont(NSFont*);
#endif
-#if PLATFORM(CG)
+#if USE(CG) || USE(SKIA_ON_MAC_CHROME)
#if OS(DARWIN)
#ifndef BUILDING_ON_TIGER
CGFontRef cgFont() const { return m_cgFont.get(); }
@@ -243,19 +245,21 @@ public:
void setOrientation(FontOrientation orientation) { m_orientation = orientation; }
-#if PLATFORM(CAIRO)
+#if USE(CAIRO)
cairo_scaled_font_t* scaledFont() const { return m_scaledFont; }
#endif
unsigned hash() const
{
-#if PLATFORM(WIN) && !PLATFORM(CAIRO)
+#if PLATFORM(WIN) && !USE(CAIRO)
return m_font ? m_font->hash() : 0;
#elif OS(DARWIN)
+#if USE(CG) || USE(SKIA_ON_MAC_CHROME)
ASSERT(m_font || !m_cgFont);
+#endif
uintptr_t hashCodes[3] = { (uintptr_t)m_font, m_widthVariant, m_textOrientation << 3 | m_orientation << 2 | m_syntheticBold << 1 | m_syntheticOblique };
return StringHasher::hashMemory<sizeof(hashCodes)>(hashCodes);
-#elif PLATFORM(CAIRO)
+#elif USE(CAIRO)
return PtrHash<cairo_scaled_font_t*>::hash(m_scaledFont);
#endif
}
@@ -276,11 +280,11 @@ public:
bool isHashTableDeletedValue() const
{
-#if PLATFORM(WIN) && !PLATFORM(CAIRO)
+#if PLATFORM(WIN) && !USE(CAIRO)
return m_font.isHashTableDeletedValue();
#elif OS(DARWIN)
return m_font == hashTableDeletedFontValue();
-#elif PLATFORM(CAIRO)
+#elif USE(CAIRO)
return m_scaledFont == hashTableDeletedFontValue();
#endif
}
@@ -307,7 +311,7 @@ private:
void platformDataInit(HFONT, float size, HDC, WCHAR* faceName);
#endif
-#if PLATFORM(CAIRO)
+#if USE(CAIRO)
static cairo_scaled_font_t* hashTableDeletedFontValue() { return reinterpret_cast<cairo_scaled_font_t*>(-1); }
#endif
@@ -326,7 +330,7 @@ private:
RefPtr<RefCountedGDIHandle<HFONT> > m_font;
#endif
-#if PLATFORM(CG)
+#if USE(CG) || USE(SKIA_ON_MAC_CHROME)
#if PLATFORM(WIN)
RetainPtr<CGFontRef> m_cgFont;
#else
@@ -339,7 +343,7 @@ private:
#endif
#endif
-#if PLATFORM(CAIRO)
+#if USE(CAIRO)
cairo_scaled_font_t* m_scaledFont;
#endif
diff --git a/Source/WebCore/platform/graphics/FontSelector.h b/Source/WebCore/platform/graphics/FontSelector.h
index 156bf10..e18161b 100644
--- a/Source/WebCore/platform/graphics/FontSelector.h
+++ b/Source/WebCore/platform/graphics/FontSelector.h
@@ -33,6 +33,7 @@ namespace WebCore {
class FontData;
class FontDescription;
+class FontSelectorClient;
class FontSelector : public RefCounted<FontSelector> {
public:
@@ -40,6 +41,16 @@ public:
virtual FontData* getFontData(const FontDescription&, const AtomicString& familyName) = 0;
virtual void fontCacheInvalidated() { }
+
+ virtual void registerForInvalidationCallbacks(FontSelectorClient*) = 0;
+ virtual void unregisterForInvalidationCallbacks(FontSelectorClient*) = 0;
+};
+
+class FontSelectorClient {
+public:
+ virtual ~FontSelectorClient() { }
+
+ virtual void fontsNeedUpdate(FontSelector*) = 0;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/GlyphBuffer.h b/Source/WebCore/platform/graphics/GlyphBuffer.h
index 7aac1e3..f5216a9 100644
--- a/Source/WebCore/platform/graphics/GlyphBuffer.h
+++ b/Source/WebCore/platform/graphics/GlyphBuffer.h
@@ -34,11 +34,11 @@
#include <wtf/UnusedParam.h>
#include <wtf/Vector.h>
-#if PLATFORM(CG) || (PLATFORM(WX) && OS(DARWIN))
+#if USE(CG) || (PLATFORM(WX) && OS(DARWIN)) || USE(SKIA_ON_MAC_CHROME)
#include <ApplicationServices/ApplicationServices.h>
#endif
-#if PLATFORM(CAIRO) || (PLATFORM(WX) && defined(__WXGTK__))
+#if USE(CAIRO) || (PLATFORM(WX) && defined(__WXGTK__))
#include <cairo.h>
#endif
@@ -47,7 +47,7 @@ namespace WebCore {
typedef unsigned short Glyph;
class SimpleFontData;
-#if PLATFORM(CAIRO)
+#if USE(CAIRO)
// FIXME: Why does Cairo use such a huge struct instead of just an offset into an array?
typedef cairo_glyph_t GlyphBufferGlyph;
#elif OS(WINCE)
@@ -58,7 +58,7 @@ typedef Glyph GlyphBufferGlyph;
// CG uses CGSize instead of FloatSize so that the result of advances()
// can be passed directly to CGContextShowGlyphsWithAdvances in FontMac.mm
-#if PLATFORM(CG) || (PLATFORM(WX) && OS(DARWIN))
+#if USE(CG) || (PLATFORM(WX) && OS(DARWIN)) || USE(SKIA_ON_MAC_CHROME)
typedef CGSize GlyphBufferAdvance;
#elif OS(WINCE)
// There is no cross-platform code that uses the height of GlyphBufferAdvance,
@@ -113,7 +113,7 @@ public:
Glyph glyphAt(int index) const
{
-#if PLATFORM(CAIRO)
+#if USE(CAIRO)
return m_glyphs[index].index;
#else
return m_glyphs[index];
@@ -122,7 +122,7 @@ public:
float advanceAt(int index) const
{
-#if PLATFORM(CG) || (PLATFORM(WX) && OS(DARWIN))
+#if USE(CG) || (PLATFORM(WX) && OS(DARWIN)) || USE(SKIA_ON_MAC_CHROME)
return m_advances[index].width;
#elif OS(WINCE)
return m_advances[index];
@@ -145,7 +145,7 @@ public:
{
m_fontData.append(font);
-#if PLATFORM(CAIRO)
+#if USE(CAIRO)
cairo_glyph_t cairoGlyph;
cairoGlyph.index = glyph;
m_glyphs.append(cairoGlyph);
@@ -153,7 +153,7 @@ public:
m_glyphs.append(glyph);
#endif
-#if PLATFORM(CG) || (PLATFORM(WX) && OS(DARWIN))
+#if USE(CG) || (PLATFORM(WX) && OS(DARWIN)) || USE(SKIA_ON_MAC_CHROME)
CGSize advance = { width, 0 };
m_advances.append(advance);
#elif OS(WINCE)
@@ -176,7 +176,7 @@ public:
void add(Glyph glyph, const SimpleFontData* font, GlyphBufferAdvance advance)
{
m_fontData.append(font);
-#if PLATFORM(CAIRO)
+#if USE(CAIRO)
cairo_glyph_t cairoGlyph;
cairoGlyph.index = glyph;
m_glyphs.append(cairoGlyph);
@@ -192,7 +192,7 @@ public:
{
ASSERT(!isEmpty());
GlyphBufferAdvance& lastAdvance = m_advances.last();
-#if PLATFORM(CG) || (PLATFORM(WX) && OS(DARWIN))
+#if USE(CG) || (PLATFORM(WX) && OS(DARWIN)) || USE(SKIA_ON_MAC_CHROME)
lastAdvance.width += width;
#elif OS(WINCE)
lastAdvance += width;
diff --git a/Source/WebCore/platform/graphics/GlyphPageTreeNode.cpp b/Source/WebCore/platform/graphics/GlyphPageTreeNode.cpp
index e7ed193..951cf56 100644
--- a/Source/WebCore/platform/graphics/GlyphPageTreeNode.cpp
+++ b/Source/WebCore/platform/graphics/GlyphPageTreeNode.cpp
@@ -191,6 +191,9 @@ void GlyphPageTreeNode::initializePage(const FontData* fontData, unsigned pageNu
} else if (start == (objectReplacementCharacter & ~(GlyphPage::size - 1))) {
// Object replacement character must not render at all.
buffer[objectReplacementCharacter - start] = zeroWidthSpace;
+ } else if (start == (zeroWidthNoBreakSpace & ~(GlyphPage::size - 1))) {
+ // ZWNBS/BOM must not render at all.
+ buffer[zeroWidthNoBreakSpace - start] = zeroWidthSpace;
}
} else {
bufferLength = GlyphPage::size * 2;
diff --git a/Source/WebCore/platform/graphics/Gradient.cpp b/Source/WebCore/platform/graphics/Gradient.cpp
index 783e552..4edb4bd 100644
--- a/Source/WebCore/platform/graphics/Gradient.cpp
+++ b/Source/WebCore/platform/graphics/Gradient.cpp
@@ -221,7 +221,11 @@ void Gradient::setGradientSpaceTransform(const AffineTransform& gradientSpaceTra
setPlatformGradientSpaceTransform(gradientSpaceTransformation);
}
+<<<<<<< HEAD
#if !(USE(SKIA) && !PLATFORM(ANDROID)) && !PLATFORM(CAIRO)
+=======
+#if !USE(SKIA) && !USE(CAIRO)
+>>>>>>> WebKit.org at r84325
void Gradient::setPlatformGradientSpaceTransform(const AffineTransform&)
{
}
diff --git a/Source/WebCore/platform/graphics/Gradient.h b/Source/WebCore/platform/graphics/Gradient.h
index acc6125..7595896 100644
--- a/Source/WebCore/platform/graphics/Gradient.h
+++ b/Source/WebCore/platform/graphics/Gradient.h
@@ -35,7 +35,7 @@
#include <wtf/PassRefPtr.h>
#include <wtf/Vector.h>
-#if PLATFORM(CG)
+#if USE(CG)
typedef struct CGContext* CGContextRef;
@@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE
class QGradient;
QT_END_NAMESPACE
typedef QGradient* PlatformGradient;
-#elif PLATFORM(CAIRO)
+#elif USE(CAIRO)
typedef struct _cairo_pattern cairo_pattern_t;
typedef cairo_pattern_t* PlatformGradient;
#elif USE(SKIA)
@@ -146,7 +146,7 @@ namespace WebCore {
void setPlatformGradientSpaceTransform(const AffineTransform& gradientSpaceTransformation);
-#if PLATFORM(CG)
+#if USE(CG)
void paint(CGContextRef);
void paint(GraphicsContext*);
#endif
diff --git a/Source/WebCore/platform/graphics/GraphicsContext.cpp b/Source/WebCore/platform/graphics/GraphicsContext.cpp
index fa3280e..ddaf938 100644
--- a/Source/WebCore/platform/graphics/GraphicsContext.cpp
+++ b/Source/WebCore/platform/graphics/GraphicsContext.cpp
@@ -148,7 +148,7 @@ void GraphicsContext::setLegacyShadow(const FloatSize& offset, float blur, const
m_state.shadowBlur = blur;
m_state.shadowColor = color;
m_state.shadowColorSpace = colorSpace;
-#if PLATFORM(CG)
+#if USE(CG)
m_state.shadowsUseLegacyRadius = true;
#endif
setPlatformShadow(offset, blur, color, colorSpace);
@@ -397,7 +397,11 @@ void GraphicsContext::drawBidiText(const Font& font, const TextRun& run, const F
if (paintingDisabled())
return;
+ // FIXME: This ownership should be reversed. We should pass BidiRunList
+ // to BidiResolver in createBidiRunsForLine.
BidiResolver<TextRunIterator, BidiCharacterRun> bidiResolver;
+ BidiRunList<BidiCharacterRun>& bidiRuns = bidiResolver.runs();
+
WTF::Unicode::Direction paragraphDirection = run.ltr() ? WTF::Unicode::LeftToRight : WTF::Unicode::RightToLeft;
bidiResolver.setStatus(BidiStatus(paragraphDirection, paragraphDirection, paragraphDirection, BidiContext::create(run.ltr() ? 0 : 1, paragraphDirection, run.directionalOverride())));
@@ -405,11 +409,11 @@ void GraphicsContext::drawBidiText(const Font& font, const TextRun& run, const F
bidiResolver.setPosition(TextRunIterator(&run, 0));
bidiResolver.createBidiRunsForLine(TextRunIterator(&run, run.length()));
- if (!bidiResolver.runCount())
+ if (!bidiRuns.runCount())
return;
FloatPoint currPoint = point;
- BidiCharacterRun* bidiRun = bidiResolver.firstRun();
+ BidiCharacterRun* bidiRun = bidiRuns.firstRun();
while (bidiRun) {
TextRun subrun = run;
@@ -425,7 +429,7 @@ void GraphicsContext::drawBidiText(const Font& font, const TextRun& run, const F
currPoint.move(font.width(subrun), 0);
}
- bidiResolver.deleteRuns();
+ bidiRuns.deleteRuns();
}
void GraphicsContext::drawHighlightForText(const Font& font, const TextRun& run, const FloatPoint& point, int h, const Color& backgroundColor, ColorSpace colorSpace, int from, int to)
@@ -563,7 +567,7 @@ void GraphicsContext::addRoundedRectClip(const RoundedIntRect& rect)
return;
Path path;
- path.addRoundedRect(rect.rect(), rect.radii().topLeft(), rect.radii().topRight(), rect.radii().bottomLeft(), rect.radii().bottomRight());
+ path.addRoundedRect(rect);
clip(path);
}
@@ -573,7 +577,7 @@ void GraphicsContext::clipOutRoundedRect(const RoundedIntRect& rect)
return;
Path path;
- path.addRoundedRect(rect.rect(), rect.radii().topLeft(), rect.radii().topRight(), rect.radii().bottomLeft(), rect.radii().bottomRight());
+ path.addRoundedRect(rect);
clipOut(path);
}
@@ -584,7 +588,7 @@ void GraphicsContext::clipToImageBuffer(ImageBuffer* buffer, const FloatRect& re
buffer->clip(this, rect);
}
-#if !PLATFORM(CG)
+#if !USE(CG)
IntRect GraphicsContext::clipBounds() const
{
ASSERT_NOT_REACHED();
@@ -617,7 +621,7 @@ 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)
+#if !USE(CG)
void GraphicsContext::fillRectWithRoundedHole(const IntRect& rect, const RoundedIntRect& roundedHoleRect, const Color& color, ColorSpace colorSpace)
{
if (paintingDisabled())
@@ -627,7 +631,7 @@ void GraphicsContext::fillRectWithRoundedHole(const IntRect& rect, const Rounded
path.addRect(rect);
if (!roundedHoleRect.radii().isZero())
- path.addRoundedRect(roundedHoleRect.rect(), roundedHoleRect.radii().topLeft(), roundedHoleRect.radii().topRight(), roundedHoleRect.radii().bottomLeft(), roundedHoleRect.radii().bottomRight());
+ path.addRoundedRect(roundedHoleRect);
else
path.addRect(roundedHoleRect.rect());
@@ -674,7 +678,11 @@ void GraphicsContext::setPlatformStrokePattern(Pattern*)
}
#endif
+<<<<<<< HEAD
#if !PLATFORM(CG) && !(USE(SKIA) && !PLATFORM(ANDROID))
+=======
+#if !USE(CG) && !USE(SKIA)
+>>>>>>> WebKit.org at r84325
// Implement this if you want to go ahead and push the drawing mode into your native context
// immediately.
void GraphicsContext::setPlatformTextDrawingMode(TextDrawingModeFlags mode)
@@ -682,13 +690,17 @@ void GraphicsContext::setPlatformTextDrawingMode(TextDrawingModeFlags mode)
}
#endif
+<<<<<<< HEAD
#if !PLATFORM(QT) && !PLATFORM(CAIRO) && !(USE(SKIA) && !PLATFORM(ANDROID)) && !PLATFORM(HAIKU) && !PLATFORM(OPENVG)
+=======
+#if !PLATFORM(QT) && !USE(CAIRO) && !USE(SKIA) && !PLATFORM(HAIKU) && !PLATFORM(OPENVG)
+>>>>>>> WebKit.org at r84325
void GraphicsContext::setPlatformStrokeStyle(StrokeStyle)
{
}
#endif
-#if !PLATFORM(CG)
+#if !USE(CG)
void GraphicsContext::setPlatformShouldSmoothFonts(bool)
{
}
diff --git a/Source/WebCore/platform/graphics/GraphicsContext.h b/Source/WebCore/platform/graphics/GraphicsContext.h
index c555a5f..2b41c2e 100644
--- a/Source/WebCore/platform/graphics/GraphicsContext.h
+++ b/Source/WebCore/platform/graphics/GraphicsContext.h
@@ -37,9 +37,9 @@
#include <wtf/Noncopyable.h>
#include <wtf/PassOwnPtr.h>
-#if PLATFORM(CG)
+#if USE(CG)
typedef struct CGContext PlatformGraphicsContext;
-#elif PLATFORM(CAIRO)
+#elif USE(CAIRO)
namespace WebCore {
class ContextShadow;
class PlatformContextCairo;
@@ -99,8 +99,9 @@ typedef void PlatformGraphicsContext;
#endif
#if PLATFORM(WIN)
+#include "DIBPixelData.h"
typedef struct HDC__* HDC;
-#if !PLATFORM(CG)
+#if !USE(CG)
// UInt8 is defined in CoreFoundation/CFBase.h
typedef unsigned char UInt8;
#endif
@@ -161,7 +162,7 @@ namespace WebCore {
GraphicsContextState()
: strokeThickness(0)
, shadowBlur(0)
-#if PLATFORM(CAIRO)
+#if USE(CAIRO)
, globalAlpha(1)
#endif
, textDrawingMode(TextModeFill)
@@ -177,7 +178,7 @@ namespace WebCore {
, shouldSmoothFonts(true)
, paintingDisabled(false)
, shadowsIgnoreTransforms(false)
-#if PLATFORM(CG)
+#if USE(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)
@@ -196,7 +197,7 @@ namespace WebCore {
float strokeThickness;
float shadowBlur;
-#if PLATFORM(CAIRO)
+#if USE(CAIRO)
float globalAlpha;
#endif
TextDrawingModeFlags textDrawingMode;
@@ -218,7 +219,7 @@ namespace WebCore {
bool shouldSmoothFonts : 1;
bool paintingDisabled : 1;
bool shadowsIgnoreTransforms : 1;
-#if PLATFORM(CG)
+#if USE(CG)
bool shadowsUseLegacyRadius : 1;
#endif
};
@@ -270,7 +271,7 @@ namespace WebCore {
const GraphicsContextState& state() const;
-#if PLATFORM(CG)
+#if USE(CG)
void applyStrokePattern();
void applyFillPattern();
void drawPath(const Path&);
@@ -383,7 +384,11 @@ namespace WebCore {
void drawBidiText(const Font&, const TextRun&, const FloatPoint&);
void drawHighlightForText(const Font&, const TextRun&, const FloatPoint&, int h, const Color& backgroundColor, ColorSpace, int from = 0, int to = -1);
- FloatRect roundToDevicePixels(const FloatRect&);
+ enum RoundingMode {
+ RoundAllSides,
+ RoundOriginAndDimensions
+ };
+ FloatRect roundToDevicePixels(const FloatRect&, RoundingMode = RoundAllSides);
void drawLineForText(const FloatPoint&, float width, bool printing);
enum TextCheckingLineStyle {
@@ -420,7 +425,7 @@ namespace WebCore {
void setMiterLimit(float);
void setAlpha(float);
-#if PLATFORM(CAIRO)
+#if USE(CAIRO)
float getAlpha();
#endif
@@ -486,18 +491,17 @@ namespace WebCore {
~WindowsBitmap();
HDC hdc() const { return m_hdc; }
- UInt8* buffer() const { return m_bitmapBuffer; }
- unsigned bufferLength() const { return m_bitmapBufferLength; }
- IntSize size() const { return m_size; }
- unsigned bytesPerRow() const { return m_bytesPerRow; }
+ UInt8* buffer() const { return m_pixelData.buffer(); }
+ unsigned bufferLength() const { return m_pixelData.bufferLength(); }
+ const IntSize& size() const { return m_pixelData.size(); }
+ unsigned bytesPerRow() const { return m_pixelData.bytesPerRow(); }
+ unsigned short bitsPerPixel() const { return m_pixelData.bitsPerPixel(); }
+ const DIBPixelData& windowsDIB() const { return m_pixelData; }
private:
HDC m_hdc;
HBITMAP m_bitmap;
- UInt8* m_bitmapBuffer;
- unsigned m_bitmapBufferLength;
- IntSize m_size;
- unsigned m_bytesPerRow;
+ DIBPixelData m_pixelData;
};
WindowsBitmap* createWindowsBitmap(IntSize);
@@ -521,13 +525,12 @@ namespace WebCore {
void takeOwnershipOfPlatformContext();
#endif
-#if PLATFORM(QT) || PLATFORM(CAIRO)
+#if PLATFORM(QT) || USE(CAIRO)
ContextShadow* contextShadow();
#endif
-#if PLATFORM(CAIRO)
+#if USE(CAIRO)
GraphicsContext(cairo_t*);
- void pushImageMask(cairo_surface_t*, const FloatRect&);
#endif
#if PLATFORM(GTK)
diff --git a/Source/WebCore/platform/graphics/GraphicsContext3D.h b/Source/WebCore/platform/graphics/GraphicsContext3D.h
index 351b445..80226cf 100644
--- a/Source/WebCore/platform/graphics/GraphicsContext3D.h
+++ b/Source/WebCore/platform/graphics/GraphicsContext3D.h
@@ -43,8 +43,11 @@
#undef VERSION
#endif
-#if PLATFORM(MAC)
+#if PLATFORM(MAC) || PLATFORM(GTK)
#include "ANGLEWebKitBridge.h"
+#endif
+
+#if PLATFORM(MAC)
#include <OpenGL/OpenGL.h>
#include <wtf/RetainPtr.h>
#ifdef __OBJC__
@@ -73,7 +76,7 @@ typedef void* PlatformGraphicsContext3D;
const PlatformGraphicsContext3D NullPlatformGraphicsContext3D = 0;
const Platform3DObject NullPlatform3DObject = 0;
-#if PLATFORM(CG)
+#if USE(CG)
#include <CoreGraphics/CGContext.h>
#endif
@@ -81,12 +84,15 @@ namespace WebCore {
class CanvasRenderingContext;
class DrawingBuffer;
class Extensions3D;
-#if PLATFORM(MAC)
+#if PLATFORM(MAC) || PLATFORM(GTK)
class Extensions3DOpenGL;
#endif
class HostWindow;
class Image;
class ImageData;
+#if USE(CAIRO)
+class PlatformContextCairo;
+#endif
struct ActiveInfo {
String name;
@@ -95,7 +101,7 @@ struct ActiveInfo {
};
// FIXME: ideally this would be used on all platforms.
-#if PLATFORM(CHROMIUM) || PLATFORM(QT)
+#if PLATFORM(CHROMIUM) || PLATFORM(QT) || PLATFORM(GTK)
class GraphicsContext3DInternal;
#endif
@@ -465,6 +471,9 @@ public:
#if USE(ACCELERATED_COMPOSITING)
PlatformLayer* platformLayer() const;
#endif
+#elif PLATFORM(GTK)
+ PlatformGraphicsContext3D platformGraphicsContext3D();
+ Platform3DObject platformTexture() const { return m_texture; }
#else
PlatformGraphicsContext3D platformGraphicsContext3D() const { return NullPlatformGraphicsContext3D; }
Platform3DObject platformTexture() const { return NullPlatform3DObject; }
@@ -476,7 +485,7 @@ public:
PassRefPtr<DrawingBuffer> createDrawingBuffer(const IntSize& = IntSize());
-#if PLATFORM(MAC) || PLATFORM(CHROMIUM)
+#if PLATFORM(MAC) || PLATFORM(CHROMIUM) || PLATFORM(GTK)
// With multisampling on, blit from multisampleFBO to regular FBO.
void prepareTexture();
#endif
@@ -753,9 +762,12 @@ public:
void reshape(int width, int height);
-#if PLATFORM(CG)
+#if USE(CG)
void paintToCanvas(const unsigned char* imagePixels, int imageWidth, int imageHeight,
int canvasWidth, int canvasHeight, CGContextRef context);
+#elif PLATFORM(GTK)
+ void paintToCanvas(const unsigned char* imagePixels, int imageWidth, int imageHeight,
+ int canvasWidth, int canvasHeight, PlatformContextCairo* context);
#endif
void markContextChanged();
@@ -769,6 +781,8 @@ public:
bool paintsIntoCanvasBuffer() const { return true; }
#elif PLATFORM(CHROMIUM)
bool paintsIntoCanvasBuffer() const;
+#elif PLATFORM(GTK)
+ bool paintsIntoCanvasBuffer() const { return true; }
#else
bool paintsIntoCanvasBuffer() const { return false; }
#endif
@@ -859,7 +873,7 @@ public:
AlphaOp alphaOp,
void* destinationData);
-#if PLATFORM(MAC)
+#if PLATFORM(MAC) || PLATFORM(GTK)
// Take into account the user's requested context creation attributes,
// in particular stencil and antialias, and determine which could or
// could not be honored based on the capabilities of the OpenGL
@@ -874,6 +888,11 @@ public:
int m_currentWidth, m_currentHeight;
#if PLATFORM(MAC)
+ CGLContextObj m_contextObj;
+ RetainPtr<WebGLLayer> m_webGLLayer;
+#endif
+
+#if PLATFORM(MAC) || PLATFORM(GTK)
typedef struct {
String source;
String log;
@@ -889,8 +908,6 @@ public:
Attributes m_attrs;
Vector<Vector<float> > m_vertexArray;
- CGLContextObj m_contextObj;
- RetainPtr<WebGLLayer> m_webGLLayer;
GC3Duint m_texture, m_compositorTexture;
GC3Duint m_fbo;
GC3Duint m_depthStencilBuffer;
@@ -912,7 +929,7 @@ public:
#endif
// FIXME: ideally this would be used on all platforms.
-#if PLATFORM(CHROMIUM) || PLATFORM(QT)
+#if PLATFORM(CHROMIUM) || PLATFORM(QT) || PLATFORM(GTK)
friend class GraphicsContext3DInternal;
OwnPtr<GraphicsContext3DInternal> m_internal;
#endif
diff --git a/Source/WebCore/platform/graphics/Image.cpp b/Source/WebCore/platform/graphics/Image.cpp
index 3096680..11da0ab 100644
--- a/Source/WebCore/platform/graphics/Image.cpp
+++ b/Source/WebCore/platform/graphics/Image.cpp
@@ -36,7 +36,7 @@
#include <math.h>
#include <wtf/StdLibExtras.h>
-#if PLATFORM(CG)
+#if USE(CG)
#include <CoreFoundation/CoreFoundation.h>
#endif
diff --git a/Source/WebCore/platform/graphics/Image.h b/Source/WebCore/platform/graphics/Image.h
index 3c5e7fd..834a0d3 100644
--- a/Source/WebCore/platform/graphics/Image.h
+++ b/Source/WebCore/platform/graphics/Image.h
@@ -45,7 +45,7 @@ class NSImage;
#endif
#endif
-#if PLATFORM(CG)
+#if USE(CG)
struct CGContext;
#endif
@@ -136,8 +136,9 @@ public:
virtual CFDataRef getTIFFRepresentation() { return 0; }
#endif
-#if PLATFORM(CG)
+#if USE(CG)
virtual CGImageRef getCGImageRef() { return 0; }
+ virtual CGImageRef getFirstCGImageRefOfSize(const IntSize&) { return 0; }
#endif
#if PLATFORM(WIN)
diff --git a/Source/WebCore/platform/graphics/ImageBuffer.cpp b/Source/WebCore/platform/graphics/ImageBuffer.cpp
index 4a76be4..23b925a 100644
--- a/Source/WebCore/platform/graphics/ImageBuffer.cpp
+++ b/Source/WebCore/platform/graphics/ImageBuffer.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#include "ImageBuffer.h"
-#if !PLATFORM(CG)
+#if !USE(CG)
#include <math.h>
@@ -69,4 +69,4 @@ void ImageBuffer::transformColorSpace(ColorSpace srcColorSpace, ColorSpace dstCo
}
-#endif // PLATFORM(CG)
+#endif // USE(CG)
diff --git a/Source/WebCore/platform/graphics/ImageBuffer.h b/Source/WebCore/platform/graphics/ImageBuffer.h
index 860f574..c184bbe 100644
--- a/Source/WebCore/platform/graphics/ImageBuffer.h
+++ b/Source/WebCore/platform/graphics/ImageBuffer.h
@@ -41,10 +41,6 @@
#include <wtf/PassRefPtr.h>
#include <wtf/Vector.h>
-#if (PLATFORM(MAC) && PLATFORM(CA) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD))
-#define WTF_USE_IOSURFACE_CANVAS_BACKING_STORE 1
-#endif
-
namespace WebCore {
class GraphicsContext;
@@ -86,6 +82,7 @@ namespace WebCore {
GraphicsContext* context() const;
+ bool isAccelerated() const { return m_accelerateRendering; }
bool drawsUsingCopy() const; // If the image buffer has to render using a copied image, it will return true.
PassRefPtr<Image> copyImage() const; // Return a new image that is a copy of the buffer.
@@ -96,7 +93,7 @@ namespace WebCore {
void putPremultipliedImageData(ByteArray*, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint);
String toDataURL(const String& mimeType, const double* quality = 0) const;
-#if !PLATFORM(CG)
+#if !USE(CG)
AffineTransform baseTransform() const { return AffineTransform(); }
void transformColorSpace(ColorSpace srcColorSpace, ColorSpace dstColorSpace);
void platformTransformColorSpace(const Vector<int>&);
@@ -122,7 +119,7 @@ namespace WebCore {
bool m_accelerateRendering;
OwnPtr<GraphicsContext> m_context;
-#if !PLATFORM(CG)
+#if !USE(CG)
Vector<int> m_linearRgbLUT;
Vector<int> m_deviceRgbLUT;
#endif
@@ -132,7 +129,7 @@ namespace WebCore {
ImageBuffer(const IntSize&, ColorSpace colorSpace, RenderingMode renderingMode, bool& success);
};
-#if PLATFORM(CG) || USE(SKIA)
+#if USE(CG) || USE(SKIA)
String ImageDataToDataURL(const ImageData& input, const String& mimeType, const double* quality);
#endif
diff --git a/Source/WebCore/platform/graphics/ImageBufferData.h b/Source/WebCore/platform/graphics/ImageBufferData.h
new file mode 100644
index 0000000..670a10f
--- /dev/null
+++ b/Source/WebCore/platform/graphics/ImageBufferData.h
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+#if USE(CG)
+#include "ImageBufferDataCG.h"
+#elif USE(CAIRO)
+#include "ImageBufferDataCairo.h"
+#elif PLATFORM(QT)
+#include "ImageBufferDataQt.h"
+#elif USE(SKIA)
+#include "ImageBufferDataSkia.h"
+#elif PLATFORM(HAIKU)
+#include "ImageBufferDataHaiku.h"
+#elif OS(WINCE)
+#include "ImageBufferDataWince.h"
+#elif PLATFORM(WX)
+#include "ImageBufferDataWx.h"
+#endif
diff --git a/Source/WebCore/platform/graphics/ImageSource.h b/Source/WebCore/platform/graphics/ImageSource.h
index 5ece15b..8dcc9a2 100644
--- a/Source/WebCore/platform/graphics/ImageSource.h
+++ b/Source/WebCore/platform/graphics/ImageSource.h
@@ -34,7 +34,7 @@
#if PLATFORM(WX)
class wxBitmap;
class wxGraphicsBitmap;
-#elif PLATFORM(CG)
+#elif USE(CG)
typedef struct CGImageSource* CGImageSourceRef;
typedef struct CGImage* CGImageRef;
typedef const struct __CFData* CFDataRef;
@@ -43,7 +43,7 @@ typedef const struct __CFData* CFDataRef;
QT_BEGIN_NAMESPACE
class QPixmap;
QT_END_NAMESPACE
-#elif PLATFORM(CAIRO)
+#elif USE(CAIRO)
struct _cairo_surface;
typedef struct _cairo_surface cairo_surface_t;
#elif USE(SKIA)
@@ -68,7 +68,7 @@ class IntPoint;
class IntSize;
class SharedBuffer;
-#if PLATFORM(CG)
+#if USE(CG)
#if USE(WEBKIT_IMAGE_DECODERS)
class ImageDecoder;
typedef ImageDecoder* NativeImageSourcePtr;
@@ -107,7 +107,7 @@ typedef wxGraphicsBitmap* NativeImagePtr;
#else
typedef wxBitmap* NativeImagePtr;
#endif
-#elif PLATFORM(CAIRO)
+#elif USE(CAIRO)
typedef cairo_surface_t* NativeImagePtr;
#elif USE(SKIA)
typedef WebCore::NativeImageSkia* NativeImagePtr;
diff --git a/Source/WebCore/platform/graphics/IntPoint.h b/Source/WebCore/platform/graphics/IntPoint.h
index d27906b..46d49eb 100644
--- a/Source/WebCore/platform/graphics/IntPoint.h
+++ b/Source/WebCore/platform/graphics/IntPoint.h
@@ -32,7 +32,7 @@
#include <QDataStream>
#endif
-#if PLATFORM(CG)
+#if USE(CG) || USE(SKIA_ON_MAC_CHROME)
typedef struct CGPoint CGPoint;
#endif
@@ -114,7 +114,7 @@ public:
return IntPoint(m_y, m_x);
}
-#if PLATFORM(CG)
+#if USE(CG) || USE(SKIA_ON_MAC_CHROME)
explicit IntPoint(const CGPoint&); // don't do this implicitly since it's lossy
operator CGPoint() const;
#endif
diff --git a/Source/WebCore/platform/graphics/IntRect.cpp b/Source/WebCore/platform/graphics/IntRect.cpp
index 7591c41..9507406 100644
--- a/Source/WebCore/platform/graphics/IntRect.cpp
+++ b/Source/WebCore/platform/graphics/IntRect.cpp
@@ -96,6 +96,27 @@ void IntRect::unite(const IntRect& other)
m_size.setHeight(b - t);
}
+void IntRect::uniteIfNonZero(const IntRect& other)
+{
+ // Handle empty special cases first.
+ if (!other.width() && !other.height())
+ return;
+ if (!width() && !height()) {
+ *this = other;
+ return;
+ }
+
+ int left = min(x(), other.x());
+ int top = min(y(), other.y());
+ int right = max(maxX(), other.maxX());
+ int bottom = max(maxY(), other.maxY());
+
+ m_location.setX(left);
+ m_location.setY(top);
+ m_size.setWidth(right - left);
+ m_size.setHeight(bottom - top);
+}
+
void IntRect::scale(float s)
{
m_location.setX((int)(x() * s));
diff --git a/Source/WebCore/platform/graphics/IntRect.h b/Source/WebCore/platform/graphics/IntRect.h
index c413e7a..d2b348b 100644
--- a/Source/WebCore/platform/graphics/IntRect.h
+++ b/Source/WebCore/platform/graphics/IntRect.h
@@ -29,7 +29,7 @@
#include "IntPoint.h"
#include <wtf/Vector.h>
-#if PLATFORM(CG)
+#if USE(CG) || USE(SKIA_ON_MAC_CHROME)
typedef struct CGRect CGRect;
#endif
@@ -133,6 +133,11 @@ public:
setHeight(std::max(0, height() + delta));
}
+ IntPoint minXMinYCorner() const { return m_location; } // typically topLeft
+ IntPoint maxXMinYCorner() const { return IntPoint(m_location.x() + m_size.width(), m_location.y()); } // typically topRight
+ IntPoint minXMaxYCorner() const { return IntPoint(m_location.x(), m_location.y() + m_size.height()); } // typically bottomLeft
+ IntPoint maxXMaxYCorner() const { return IntPoint(m_location.x() + m_size.width(), m_location.y() + m_size.height()); } // typically bottomRight
+
bool intersects(const IntRect&) const;
bool contains(const IntRect&) const;
@@ -144,6 +149,7 @@ public:
void intersect(const IntRect&);
void unite(const IntRect&);
+ void uniteIfNonZero(const IntRect&);
void inflateX(int dx)
{
@@ -182,7 +188,7 @@ public:
operator Eina_Rectangle() const;
#endif
-#if PLATFORM(CG)
+#if USE(CG) || USE(SKIA_ON_MAC_CHROME)
operator CGRect() const;
#endif
@@ -228,7 +234,7 @@ inline bool operator!=(const IntRect& a, const IntRect& b)
return a.location() != b.location() || a.size() != b.size();
}
-#if PLATFORM(CG)
+#if USE(CG) || USE(SKIA_ON_MAC_CHROME)
IntRect enclosingIntRect(const CGRect&);
#endif
diff --git a/Source/WebCore/platform/graphics/IntSize.h b/Source/WebCore/platform/graphics/IntSize.h
index 9db2224..8cfabf5 100644
--- a/Source/WebCore/platform/graphics/IntSize.h
+++ b/Source/WebCore/platform/graphics/IntSize.h
@@ -26,7 +26,7 @@
#ifndef IntSize_h
#define IntSize_h
-#if PLATFORM(CG)
+#if USE(CG) || USE(SKIA_ON_MAC_CHROME)
typedef struct CGSize CGSize;
#endif
@@ -109,7 +109,7 @@ public:
return IntSize(m_height, m_width);
}
-#if PLATFORM(CG)
+#if USE(CG) || USE(SKIA_ON_MAC_CHROME)
explicit IntSize(const CGSize&); // don't do this implicitly since it's lossy
operator CGSize() const;
#endif
diff --git a/Source/WebCore/platform/graphics/MediaPlayer.cpp b/Source/WebCore/platform/graphics/MediaPlayer.cpp
index 03004b6..a7e4b90 100644
--- a/Source/WebCore/platform/graphics/MediaPlayer.cpp
+++ b/Source/WebCore/platform/graphics/MediaPlayer.cpp
@@ -792,11 +792,12 @@ void MediaPlayer::networkStateChanged()
// If more than one media engine is installed and this one failed before finding metadata,
// let the next engine try.
if (m_private->networkState() >= FormatError
- && m_private->readyState() < HaveMetadata
- && installedMediaEngines().size() > 1
- && bestMediaEngineForTypeAndCodecs(m_contentMIMEType, m_contentTypeCodecs, m_currentMediaEngine)) {
+ && m_private->readyState() < HaveMetadata
+ && installedMediaEngines().size() > 1) {
+ if ( m_contentMIMEType.isEmpty() || bestMediaEngineForTypeAndCodecs(m_contentMIMEType, m_contentTypeCodecs, m_currentMediaEngine)) {
m_reloadTimer.startOneShot(0);
return;
+ }
}
if (m_mediaPlayerClient)
m_mediaPlayerClient->mediaPlayerNetworkStateChanged(this);
@@ -858,6 +859,12 @@ void MediaPlayer::playbackStateChanged()
m_mediaPlayerClient->mediaPlayerPlaybackStateChanged(this);
}
+void MediaPlayer::firstVideoFrameAvailable()
+{
+ if (m_mediaPlayerClient)
+ m_mediaPlayerClient->mediaPlayerFirstVideoFrameAvailable(this);
+}
+
}
#endif
diff --git a/Source/WebCore/platform/graphics/MediaPlayer.h b/Source/WebCore/platform/graphics/MediaPlayer.h
index ff304ea..41cb6d2 100644
--- a/Source/WebCore/platform/graphics/MediaPlayer.h
+++ b/Source/WebCore/platform/graphics/MediaPlayer.h
@@ -143,6 +143,10 @@ public:
virtual void mediaPlayerEngineUpdated(MediaPlayer*) { }
+ // The first frame of video is available to render. A media engine need only make this callback if the
+ // first frame is not available immediately when prepareForRendering is called.
+ virtual void mediaPlayerFirstVideoFrameAvailable(MediaPlayer*) { }
+
#if USE(ACCELERATED_COMPOSITING)
// whether the rendering system can accelerate the display of this MediaPlayer.
virtual bool mediaPlayerRenderingCanBeAccelerated(MediaPlayer*) { return false; }
@@ -262,6 +266,7 @@ public:
void rateChanged();
void playbackStateChanged();
void durationChanged();
+ void firstVideoFrameAvailable();
void repaint();
diff --git a/Source/WebCore/platform/graphics/Path.cpp b/Source/WebCore/platform/graphics/Path.cpp
index f7aedbe..da09c76 100644
--- a/Source/WebCore/platform/graphics/Path.cpp
+++ b/Source/WebCore/platform/graphics/Path.cpp
@@ -188,4 +188,9 @@ void Path::addRoundedRect(const FloatRect& rect, const FloatSize& topLeftRadius,
closeSubpath();
}
+void Path::addRoundedRect(const RoundedIntRect& r)
+{
+ addRoundedRect(r.rect(), r.radii().topLeft(), r.radii().topRight(), r.radii().bottomLeft(), r.radii().bottomRight());
+}
+
}
diff --git a/Source/WebCore/platform/graphics/Path.h b/Source/WebCore/platform/graphics/Path.h
index c2ca576..9c07247 100644
--- a/Source/WebCore/platform/graphics/Path.h
+++ b/Source/WebCore/platform/graphics/Path.h
@@ -28,10 +28,11 @@
#ifndef Path_h
#define Path_h
+#include "RoundedIntRect.h"
#include <wtf/FastAllocBase.h>
#include <wtf/Forward.h>
-#if PLATFORM(CG)
+#if USE(CG)
typedef struct CGPath PlatformPath;
#elif PLATFORM(OPENVG)
namespace WebCore {
@@ -44,7 +45,7 @@ typedef QPainterPath PlatformPath;
#elif PLATFORM(WX) && USE(WXGC)
class wxGraphicsPath;
typedef wxGraphicsPath PlatformPath;
-#elif PLATFORM(CAIRO)
+#elif USE(CAIRO)
namespace WebCore {
class CairoPath;
}
@@ -137,6 +138,7 @@ namespace WebCore {
void addEllipse(const FloatRect&);
void addRoundedRect(const FloatRect&, const FloatSize& roundingRadii);
void addRoundedRect(const FloatRect&, const FloatSize& topLeftRadius, const FloatSize& topRightRadius, const FloatSize& bottomLeftRadius, const FloatSize& bottomRightRadius);
+ void addRoundedRect(const RoundedIntRect&);
void translate(const FloatSize&);
diff --git a/Source/WebCore/platform/graphics/Pattern.h b/Source/WebCore/platform/graphics/Pattern.h
index c88f2fb..1d0b0f8 100644
--- a/Source/WebCore/platform/graphics/Pattern.h
+++ b/Source/WebCore/platform/graphics/Pattern.h
@@ -35,10 +35,10 @@
#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
-#if PLATFORM(CG)
+#if USE(CG)
typedef struct CGPattern* CGPatternRef;
typedef CGPatternRef PlatformPatternPtr;
-#elif PLATFORM(CAIRO)
+#elif USE(CAIRO)
#include <cairo.h>
typedef cairo_pattern_t* PlatformPatternPtr;
#elif USE(SKIA)
diff --git a/Source/WebCore/platform/graphics/RoundedIntRect.cpp b/Source/WebCore/platform/graphics/RoundedIntRect.cpp
index 4e80c9a..e919c4f 100644
--- a/Source/WebCore/platform/graphics/RoundedIntRect.cpp
+++ b/Source/WebCore/platform/graphics/RoundedIntRect.cpp
@@ -30,6 +30,8 @@
#include "IntRect.h"
#include <algorithm>
+using namespace std;
+
namespace WebCore {
bool RoundedIntRect::Radii::isZero() const
@@ -60,17 +62,17 @@ void RoundedIntRect::Radii::scale(float factor)
void RoundedIntRect::Radii::expand(int topWidth, int bottomWidth, int leftWidth, int rightWidth)
{
- m_topLeft.setWidth(std::max(0, m_topLeft.width() + leftWidth));
- m_topLeft.setHeight(std::max(0, m_topLeft.height() + topWidth));
+ m_topLeft.setWidth(max(0, m_topLeft.width() + leftWidth));
+ m_topLeft.setHeight(max(0, m_topLeft.height() + topWidth));
- m_topRight.setWidth(std::max(0, m_topRight.width() + rightWidth));
- m_topRight.setHeight(std::max(0, m_topRight.height() + topWidth));
+ m_topRight.setWidth(max(0, m_topRight.width() + rightWidth));
+ m_topRight.setHeight(max(0, m_topRight.height() + topWidth));
- m_bottomLeft.setWidth(std::max(0, m_bottomLeft.width() + leftWidth));
- m_bottomLeft.setHeight(std::max(0, m_bottomLeft.height() + bottomWidth));
+ m_bottomLeft.setWidth(max(0, m_bottomLeft.width() + leftWidth));
+ m_bottomLeft.setHeight(max(0, m_bottomLeft.height() + bottomWidth));
- m_bottomRight.setWidth(std::max(0, m_bottomRight.width() + rightWidth));
- m_bottomRight.setHeight(std::max(0, m_bottomRight.height() + bottomWidth));
+ m_bottomRight.setWidth(max(0, m_bottomRight.width() + rightWidth));
+ m_bottomRight.setHeight(max(0, m_bottomRight.height() + bottomWidth));
}
void RoundedIntRect::Radii::includeLogicalEdges(const RoundedIntRect::Radii& edges, bool isHorizontal, bool includeLogicalLeftEdge, bool includeLogicalRightEdge)
@@ -138,4 +140,12 @@ void RoundedIntRect::excludeLogicalEdges(bool isHorizontal, bool excludeLogicalL
m_radii.excludeLogicalEdges(isHorizontal, excludeLogicalLeftEdge, excludeLogicalRightEdge);
}
+bool RoundedIntRect::isRenderable() const
+{
+ return m_radii.topLeft().width() + m_radii.topRight().width() <= m_rect.width()
+ && m_radii.bottomLeft().width() + m_radii.bottomRight().width() <= m_rect.width()
+ && m_radii.topLeft().height() + m_radii.topRight().height() <= m_rect.height()
+ && m_radii.bottomLeft().height() + m_radii.bottomRight().height() <= m_rect.height();
+}
+
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/RoundedIntRect.h b/Source/WebCore/platform/graphics/RoundedIntRect.h
index c3c972f..74ee892 100644
--- a/Source/WebCore/platform/graphics/RoundedIntRect.h
+++ b/Source/WebCore/platform/graphics/RoundedIntRect.h
@@ -93,11 +93,24 @@ public:
void includeLogicalEdges(const Radii& edges, bool isHorizontal, bool includeLogicalLeftEdge, bool includeLogicalRightEdge);
void excludeLogicalEdges(bool isHorizontal, bool excludeLogicalLeftEdge, bool excludeLogicalRightEdge);
+ bool isRenderable() const;
+
private:
IntRect m_rect;
Radii m_radii;
};
+inline bool operator==(const RoundedIntRect::Radii& a, const RoundedIntRect::Radii& b)
+{
+ return a.topLeft() == b.topLeft() && a.topRight() == b.topRight() && a.bottomLeft() == b.bottomLeft() && a.bottomRight() == b.bottomRight();
+}
+
+inline bool operator==(const RoundedIntRect& a, const RoundedIntRect& b)
+{
+ return a.rect() == b.rect() && a.radii() == b.radii();
+}
+
+
} // namespace WebCore
#endif // RoundedIntRect_h
diff --git a/Source/WebCore/platform/graphics/ShadowBlur.cpp b/Source/WebCore/platform/graphics/ShadowBlur.cpp
index 0df51a4..2f25221 100644
--- a/Source/WebCore/platform/graphics/ShadowBlur.cpp
+++ b/Source/WebCore/platform/graphics/ShadowBlur.cpp
@@ -54,6 +54,8 @@ class ScratchBuffer {
public:
ScratchBuffer()
: m_purgeTimer(this, &ScratchBuffer::timerFired)
+ , m_lastRadius(0)
+ , m_lastWasInset(false)
#if !ASSERT_DISABLED
, m_bufferInUse(false)
#endif
@@ -77,6 +79,41 @@ public:
return m_imageBuffer.get();
}
+ void setLastShadowValues(float radius, const Color& color, ColorSpace colorSpace, const FloatRect& shadowRect, const RoundedIntRect::Radii& radii)
+ {
+ m_lastWasInset = false;
+ m_lastRadius = radius;
+ m_lastColor = color;
+ m_lastColorSpace = colorSpace;
+ m_lastShadowRect = shadowRect;
+ m_lastRadii = radii;
+ }
+
+ void setLastInsetShadowValues(float radius, const Color& color, ColorSpace colorSpace, const FloatRect& bounds, const FloatRect& shadowRect, const RoundedIntRect::Radii& radii)
+ {
+ m_lastWasInset = true;
+ m_lastInsetBounds = bounds;
+ m_lastRadius = radius;
+ m_lastColor = color;
+ m_lastColorSpace = colorSpace;
+ m_lastShadowRect = shadowRect;
+ m_lastRadii = radii;
+ }
+
+ bool matchesLastShadow(float radius, const Color& color, ColorSpace colorSpace, const FloatRect& shadowRect, const RoundedIntRect::Radii& radii) const
+ {
+ if (m_lastWasInset)
+ return false;
+ return m_lastRadius == radius && m_lastColor == color && m_lastColorSpace == colorSpace && shadowRect == m_lastShadowRect && radii == m_lastRadii;
+ }
+
+ bool matchesLastInsetShadow(float radius, const Color& color, ColorSpace colorSpace, const FloatRect& bounds, const FloatRect& shadowRect, const RoundedIntRect::Radii& radii) const
+ {
+ if (!m_lastWasInset)
+ return false;
+ return m_lastRadius == radius && m_lastColor == color && m_lastColorSpace == colorSpace && m_lastInsetBounds == bounds && shadowRect == m_lastShadowRect && radii == m_lastRadii;
+ }
+
void scheduleScratchBufferPurge()
{
#if !ASSERT_DISABLED
@@ -100,10 +137,20 @@ private:
void clearScratchBuffer()
{
m_imageBuffer = 0;
+ m_lastRadius = 0;
}
OwnPtr<ImageBuffer> m_imageBuffer;
Timer<ScratchBuffer> m_purgeTimer;
+
+ FloatRect m_lastInsetBounds;
+ FloatRect m_lastShadowRect;
+ RoundedIntRect::Radii m_lastRadii;
+ Color m_lastColor;
+ ColorSpace m_lastColorSpace;
+ float m_lastRadius;
+ bool m_lastWasInset;
+
#if !ASSERT_DISABLED
bool m_bufferInUse;
#endif
@@ -147,14 +194,7 @@ static const int blurSumShift = 15;
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
+ const int channels[4] = { 3, 0, 1, 3 };
int diameter;
if (m_shadowsIgnoreTransforms)
@@ -356,40 +396,10 @@ IntRect ShadowBlur::calculateLayerBoundingRect(GraphicsContext* context, const F
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)
+void ShadowBlur::drawShadowBuffer(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();
@@ -406,11 +416,6 @@ void ShadowBlur::endShadowLayer(GraphicsContext* graphicsContext)
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)
@@ -442,6 +447,8 @@ void ShadowBlur::drawRectShadow(GraphicsContext* graphicsContext, const FloatRec
if (layerRect.isEmpty())
return;
+ adjustBlurRadius(graphicsContext);
+
// drawRectShadowWithTiling does not work with rotations.
// https://bugs.webkit.org/show_bug.cgi?id=45042
if (!graphicsContext->getCTM().isIdentityOrTranslationOrFlipped() || m_type != BlurShadow) {
@@ -466,6 +473,8 @@ void ShadowBlur::drawInsetShadow(GraphicsContext* graphicsContext, const FloatRe
if (layerRect.isEmpty())
return;
+ adjustBlurRadius(graphicsContext);
+
// drawInsetShadowWithTiling does not work with rotations.
// https://bugs.webkit.org/show_bug.cgi?id=45042
if (!graphicsContext->getCTM().isIdentityOrTranslationOrFlipped() || m_type != BlurShadow) {
@@ -486,34 +495,81 @@ void ShadowBlur::drawInsetShadow(GraphicsContext* graphicsContext, const FloatRe
void ShadowBlur::drawRectShadowWithoutTiling(GraphicsContext* graphicsContext, const FloatRect& shadowedRect, const RoundedIntRect::Radii& radii, const IntRect& layerRect)
{
- GraphicsContext* shadowContext = beginShadowLayer(graphicsContext, layerRect);
- if (!shadowContext)
+ m_layerImage = ScratchBuffer::shared().getScratchBuffer(layerRect.size());
+ if (!m_layerImage)
return;
- Path path;
- path.addRoundedRect(shadowedRect, radii.topLeft(), radii.topRight(), radii.bottomLeft(), radii.bottomRight());
+ FloatRect bufferRelativeShadowedRect = shadowedRect;
+ bufferRelativeShadowedRect.move(m_layerContextTranslation);
+ if (!ScratchBuffer::shared().matchesLastShadow(m_blurRadius, Color::black, ColorSpaceDeviceRGB, bufferRelativeShadowedRect, radii)) {
+ GraphicsContext* shadowContext = m_layerImage->context();
+ shadowContext->save();
+
+ // Add a pixel to avoid later edge aliasing when rotated.
+ shadowContext->clearRect(FloatRect(0, 0, m_layerSize.width() + 1, m_layerSize.height() + 1));
+ shadowContext->translate(m_layerContextTranslation);
+ shadowContext->setFillColor(Color::black, ColorSpaceDeviceRGB);
+ if (radii.isZero())
+ shadowContext->fillRect(shadowedRect);
+ else {
+ Path path;
+ path.addRoundedRect(shadowedRect, radii.topLeft(), radii.topRight(), radii.bottomLeft(), radii.bottomRight());
+ shadowContext->fillPath(path);
+ }
+
+ blurShadowBuffer(expandedIntSize(m_layerSize));
- shadowContext->setFillColor(Color::black, ColorSpaceDeviceRGB);
- shadowContext->fillPath(path);
+ shadowContext->restore();
+
+ ScratchBuffer::shared().setLastShadowValues(m_blurRadius, Color::black, ColorSpaceDeviceRGB, bufferRelativeShadowedRect, radii);
+ }
- endShadowLayer(graphicsContext);
+ drawShadowBuffer(graphicsContext);
+ m_layerImage = 0;
+ ScratchBuffer::shared().scheduleScratchBufferPurge();
}
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)
+ m_layerImage = ScratchBuffer::shared().getScratchBuffer(layerRect.size());
+ if (!m_layerImage)
return;
- Path path;
- path.addRect(rect);
- path.addRoundedRect(holeRect, holeRadii.topLeft(), holeRadii.topRight(), holeRadii.bottomLeft(), holeRadii.bottomRight());
+ FloatRect bufferRelativeRect = rect;
+ bufferRelativeRect.move(m_layerContextTranslation);
+
+ FloatRect bufferRelativeHoleRect = holeRect;
+ bufferRelativeHoleRect.move(m_layerContextTranslation);
- shadowContext->setFillRule(RULE_EVENODD);
- shadowContext->setFillColor(Color::black, ColorSpaceDeviceRGB);
- shadowContext->fillPath(path);
+ if (!ScratchBuffer::shared().matchesLastInsetShadow(m_blurRadius, Color::black, ColorSpaceDeviceRGB, bufferRelativeRect, bufferRelativeHoleRect, holeRadii)) {
+ GraphicsContext* shadowContext = m_layerImage->context();
+ shadowContext->save();
- endShadowLayer(graphicsContext);
+ // Add a pixel to avoid later edge aliasing when rotated.
+ shadowContext->clearRect(FloatRect(0, 0, m_layerSize.width() + 1, m_layerSize.height() + 1));
+ shadowContext->translate(m_layerContextTranslation);
+
+ Path path;
+ path.addRect(rect);
+ if (holeRadii.isZero())
+ path.addRect(holeRect);
+ else
+ path.addRoundedRect(holeRect, holeRadii.topLeft(), holeRadii.topRight(), holeRadii.bottomLeft(), holeRadii.bottomRight());
+
+ shadowContext->setFillRule(RULE_EVENODD);
+ shadowContext->setFillColor(Color::black, ColorSpaceDeviceRGB);
+ shadowContext->fillPath(path);
+
+ blurShadowBuffer(expandedIntSize(m_layerSize));
+
+ shadowContext->restore();
+
+ ScratchBuffer::shared().setLastInsetShadowValues(m_blurRadius, Color::black, ColorSpaceDeviceRGB, bufferRelativeRect, bufferRelativeHoleRect, holeRadii);
+ }
+
+ drawShadowBuffer(graphicsContext);
+ m_layerImage = 0;
+ ScratchBuffer::shared().scheduleScratchBufferPurge();
}
/*
@@ -557,23 +613,35 @@ void ShadowBlur::drawInsetShadowWithTiling(GraphicsContext* graphicsContext, con
const float twiceRadius = roundedRadius * 2;
m_layerImage = ScratchBuffer::shared().getScratchBuffer(templateSize);
+ if (!m_layerImage)
+ return;
// 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();
+ if (!ScratchBuffer::shared().matchesLastInsetShadow(m_blurRadius, m_color, m_colorSpace, templateBounds, templateHole, radii)) {
+ // 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);
+
+ Path path;
+ path.addRect(templateBounds);
+ if (radii.isZero())
+ path.addRect(templateHole);
+ else
+ path.addRoundedRect(templateHole, radii.topLeft(), radii.topRight(), radii.bottomLeft(), radii.bottomRight());
+
+ shadowContext->fillPath(path);
+
+ blurAndColorShadowBuffer(templateSize);
+ shadowContext->restore();
+
+ ScratchBuffer::shared().setLastInsetShadowValues(m_blurRadius, m_color, m_colorSpace, templateBounds, templateHole, radii);
+ }
FloatRect boundingRect = rect;
boundingRect.move(m_offset);
@@ -599,7 +667,6 @@ void ShadowBlur::drawInsetShadowWithTiling(GraphicsContext* graphicsContext, con
graphicsContext->restore();
m_layerImage = 0;
- // Schedule a purge of the scratch buffer.
ScratchBuffer::shared().scheduleScratchBufferPurge();
}
@@ -612,20 +679,31 @@ void ShadowBlur::drawRectShadowWithTiling(GraphicsContext* graphicsContext, cons
const float twiceRadius = roundedRadius * 2;
m_layerImage = ScratchBuffer::shared().getScratchBuffer(templateSize);
+ if (!m_layerImage)
+ return;
- // 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();
+ if (!ScratchBuffer::shared().matchesLastShadow(m_blurRadius, m_color, m_colorSpace, templateShadow, radii)) {
+ // 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);
+
+ if (radii.isZero())
+ shadowContext->fillRect(templateShadow);
+ else {
+ Path path;
+ path.addRoundedRect(templateShadow, radii.topLeft(), radii.topRight(), radii.bottomLeft(), radii.bottomRight());
+ shadowContext->fillPath(path);
+ }
+
+ blurAndColorShadowBuffer(templateSize);
+ shadowContext->restore();
+
+ ScratchBuffer::shared().setLastShadowValues(m_blurRadius, m_color, m_colorSpace, templateShadow, radii);
+ }
FloatRect shadowBounds = shadowedRect;
shadowBounds.move(m_offset.width(), m_offset.height());
@@ -636,7 +714,6 @@ void ShadowBlur::drawRectShadowWithTiling(GraphicsContext* graphicsContext, cons
graphicsContext->restore();
m_layerImage = 0;
- // Schedule a purge of the scratch buffer.
ScratchBuffer::shared().scheduleScratchBufferPurge();
}
@@ -714,14 +791,20 @@ void ShadowBlur::drawLayerPieces(GraphicsContext* graphicsContext, const FloatRe
}
+void ShadowBlur::blurShadowBuffer(const IntSize& templateSize)
+{
+ if (m_type != BlurShadow)
+ return;
+
+ 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());
+}
+
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());
- }
+ blurShadowBuffer(templateSize);
// Mask the image with the shadow color.
GraphicsContext* shadowContext = m_layerImage->context();
diff --git a/Source/WebCore/platform/graphics/ShadowBlur.h b/Source/WebCore/platform/graphics/ShadowBlur.h
index e52d6dc..4ba8e23 100644
--- a/Source/WebCore/platform/graphics/ShadowBlur.h
+++ b/Source/WebCore/platform/graphics/ShadowBlur.h
@@ -53,8 +53,7 @@ public:
void drawInsetShadow(GraphicsContext*, const FloatRect&, const FloatRect& holeRect, const RoundedIntRect::Radii& holeRadii);
private:
- GraphicsContext* beginShadowLayer(GraphicsContext*, const IntRect& layerRect);
- void endShadowLayer(GraphicsContext*);
+ void drawShadowBuffer(GraphicsContext*);
void adjustBlurRadius(GraphicsContext*);
void blurLayerImage(unsigned char*, const IntSize&, int stride);
@@ -75,6 +74,7 @@ private:
void drawLayerPieces(GraphicsContext*, const FloatRect& shadowBounds, const RoundedIntRect::Radii&, float roundedRadius, const IntSize& templateSize, ShadowDirection);
+ void blurShadowBuffer(const IntSize& templateSize);
void blurAndColorShadowBuffer(const IntSize& templateSize);
enum ShadowType {
diff --git a/Source/WebCore/platform/graphics/SimpleFontData.h b/Source/WebCore/platform/graphics/SimpleFontData.h
index dfb4be3..67e864a 100644
--- a/Source/WebCore/platform/graphics/SimpleFontData.h
+++ b/Source/WebCore/platform/graphics/SimpleFontData.h
@@ -48,7 +48,7 @@ typedef struct OpaqueATSUStyle* ATSUStyle;
#include <usp10.h>
#endif
-#if PLATFORM(CAIRO)
+#if USE(CAIRO)
#include <cairo.h>
#endif
@@ -115,7 +115,7 @@ public:
float spaceWidth() const { return m_spaceWidth; }
-#if PLATFORM(CG) || PLATFORM(CAIRO) || PLATFORM(WX)
+#if USE(CG) || USE(CAIRO) || PLATFORM(WX) || USE(SKIA_ON_MAC_CHROME)
float syntheticBoldOffset() const { return m_syntheticBoldOffset; }
#endif
@@ -252,7 +252,7 @@ private:
mutable OwnPtr<DerivedFontData> m_derivedFontData;
-#if PLATFORM(CG) || PLATFORM(CAIRO) || PLATFORM(WX)
+#if USE(CG) || USE(CAIRO) || PLATFORM(WX) || USE(SKIA_ON_MAC_CHROME)
float m_syntheticBoldOffset;
#endif
diff --git a/Source/WebCore/platform/graphics/WOFFFileFormat.cpp b/Source/WebCore/platform/graphics/WOFFFileFormat.cpp
index 80a6dcb..d54f3df 100644
--- a/Source/WebCore/platform/graphics/WOFFFileFormat.cpp
+++ b/Source/WebCore/platform/graphics/WOFFFileFormat.cpp
@@ -43,7 +43,7 @@
#define ntohs(x) std_ntohs(x)
#endif
-#if PLATFORM(WIN)
+#if OS(WINDOWS)
#if CPU(BIG_ENDIAN)
#define ntohs(x) ((uint16_t)(x))
#define htons(x) ((uint16_t)(x))
@@ -61,7 +61,7 @@
(((uint32_t)(x) & 0x0000ff00) << 8) | (((uint32_t)(x) & 0x000000ff) << 24)))
#define htonl(x) ntohl(x)
#endif
-#endif // PLATFORM(WIN)
+#endif // OS(WINDOWS)
namespace WebCore {
diff --git a/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp b/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp
index eb96532..681003f 100644
--- a/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp
+++ b/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp
@@ -74,6 +74,8 @@ MediaPlayerPrivateAVFoundation::MediaPlayerPrivateAVFoundation(MediaPlayer* play
, m_cachedHasVideo(false)
, m_cachedHasCaptions(false)
, m_ignoreLoadStateChanges(false)
+ , m_haveReportedFirstVideoFrame(false)
+ , m_playWhenFramesAvailable(false)
{
LOG(Media, "MediaPlayerPrivateAVFoundation::MediaPlayerPrivateAVFoundation(%p)", this);
}
@@ -248,6 +250,25 @@ void MediaPlayerPrivateAVFoundation::prepareToPlay()
checkPlayability();
}
+void MediaPlayerPrivateAVFoundation::play()
+{
+ LOG(Media, "MediaPlayerPrivateAVFoundation::play(%p)", this);
+
+ // If the file has video, don't request playback until the first frame of video is ready to display
+ // or the audio may start playing before we can render video.
+ if (!m_cachedHasVideo || hasAvailableVideoFrame())
+ platformPlay();
+ else
+ m_playWhenFramesAvailable = true;
+}
+
+void MediaPlayerPrivateAVFoundation::pause()
+{
+ LOG(Media, "MediaPlayerPrivateAVFoundation::pause(%p)", this);
+ m_playWhenFramesAvailable = false;
+ platformPause();
+}
+
void MediaPlayerPrivateAVFoundation::paint(GraphicsContext*, const IntRect&)
{
// This is the base class, only need to remember that a frame has been drawn.
@@ -285,6 +306,8 @@ void MediaPlayerPrivateAVFoundation::setRate(float rate)
{
LOG(Media, "MediaPlayerPrivateAVFoundation::setRate(%p) - seting to %f", this, rate);
m_requestedRate = rate;
+
+ updateRate();
}
bool MediaPlayerPrivateAVFoundation::paused() const
@@ -464,12 +487,22 @@ void MediaPlayerPrivateAVFoundation::updateStates()
if (isReadyForVideoSetup() && currentRenderingMode() != preferredRenderingMode())
setUpVideoRendering();
+ if (!m_haveReportedFirstVideoFrame && m_cachedHasVideo && hasAvailableVideoFrame()) {
+ m_haveReportedFirstVideoFrame = true;
+ m_player->firstVideoFrameAvailable();
+ }
+
if (m_networkState != oldNetworkState)
m_player->networkStateChanged();
if (m_readyState != oldReadyState)
m_player->readyStateChanged();
+ if (m_playWhenFramesAvailable && hasAvailableVideoFrame()) {
+ m_playWhenFramesAvailable = false;
+ platformPlay();
+ }
+
LOG(Media, "MediaPlayerPrivateAVFoundation::updateStates(%p) - exiting with networkState = %i, readyState = %i",
this, static_cast<int>(m_networkState), static_cast<int>(m_readyState));
}
@@ -566,6 +599,14 @@ void MediaPlayerPrivateAVFoundation::timeChanged(double time)
}
}
+void MediaPlayerPrivateAVFoundation::seekCompleted(bool finished)
+{
+ LOG(Media, "MediaPlayerPrivateAVFoundation::seekCompleted(%p) - finished = %d", this, finished);
+
+ if (finished)
+ m_seekTo = invalidTime;
+}
+
void MediaPlayerPrivateAVFoundation::didEnd()
{
// Hang onto the current time and use it as duration from now on since we are definitely at
@@ -629,12 +670,22 @@ void MediaPlayerPrivateAVFoundation::clearMainThreadPendingFlag()
void MediaPlayerPrivateAVFoundation::scheduleMainThreadNotification(Notification::Type type, double time)
{
- LOG(Media, "MediaPlayerPrivateAVFoundation::scheduleMainThreadNotification(%p) - notification %d", this, static_cast<int>(type));
+ scheduleMainThreadNotification(Notification(type, time));
+}
+
+void MediaPlayerPrivateAVFoundation::scheduleMainThreadNotification(Notification::Type type, bool finished)
+{
+ scheduleMainThreadNotification(Notification(type, finished));
+}
+
+void MediaPlayerPrivateAVFoundation::scheduleMainThreadNotification(Notification notification)
+{
+ LOG(Media, "MediaPlayerPrivateAVFoundation::scheduleMainThreadNotification(%p) - notification %d", this, static_cast<int>(notification.type()));
m_queueMutex.lock();
// It is important to always process the properties in the order that we are notified,
// so always go through the queue because notifications happen on different threads.
- m_queuedNotifications.append(Notification(type, time));
+ m_queuedNotifications.append(notification);
bool delayDispatch = m_delayCallbacks || !isMainThread();
if (delayDispatch && !m_mainThreadCallPending) {
@@ -714,6 +765,9 @@ void MediaPlayerPrivateAVFoundation::dispatchNotification()
case Notification::PlayerTimeChanged:
timeChanged(notification.time());
break;
+ case Notification::SeekCompleted:
+ seekCompleted(notification.finished());
+ break;
case Notification::AssetMetadataLoaded:
metadataLoaded();
break;
diff --git a/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h b/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h
index a768ab4..becba61 100644
--- a/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h
+++ b/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h
@@ -48,6 +48,7 @@ public:
virtual void loadedTimeRangesChanged();
virtual void seekableTimeRangesChanged();
virtual void timeChanged(double);
+ virtual void seekCompleted(bool);
virtual void didEnd();
class Notification {
@@ -66,31 +67,45 @@ public:
AssetMetadataLoaded,
AssetPlayabilityKnown,
PlayerRateChanged,
- PlayerTimeChanged
+ PlayerTimeChanged,
+ SeekCompleted,
};
Notification()
: m_type(None)
, m_time(0)
+ , m_finished(false)
{
}
Notification(Type type, double time)
: m_type(type)
, m_time(time)
+ , m_finished(false)
+ {
+ }
+
+ Notification(Type type, bool finished)
+ : m_type(type)
+ , m_time(0)
+ , m_finished(finished)
{
}
Type type() { return m_type; }
bool isValid() { return m_type != None; }
double time() { return m_time; }
+ bool finished() { return m_finished; }
private:
Type m_type;
double m_time;
+ bool m_finished;
};
+ void scheduleMainThreadNotification(Notification);
void scheduleMainThreadNotification(Notification::Type, double time = 0);
+ void scheduleMainThreadNotification(Notification::Type, bool completed);
void dispatchNotification();
void clearMainThreadPendingFlag();
@@ -105,8 +120,8 @@ protected:
virtual void prepareToPlay();
virtual PlatformMedia platformMedia() const = 0;
- virtual void play() = 0;
- virtual void pause() = 0;
+ virtual void play();
+ virtual void pause();
virtual IntSize naturalSize() const;
virtual bool hasVideo() const { return m_cachedHasVideo; }
@@ -169,7 +184,10 @@ protected:
};
virtual AVAssetStatus assetStatus() const = 0;
+ virtual void platformPlay() = 0;
+ virtual void platformPause() = 0;
virtual void checkPlayability() = 0;
+ virtual void updateRate() = 0;
virtual float rate() const = 0;
virtual void seekToTime(float time) = 0;
virtual unsigned totalBytes() const = 0;
@@ -254,6 +272,8 @@ private:
bool m_cachedHasVideo;
bool m_cachedHasCaptions;
bool m_ignoreLoadStateChanges;
+ bool m_haveReportedFirstVideoFrame;
+ bool m_playWhenFramesAvailable;
};
}
diff --git a/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundationObjC.h b/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundationObjC.h
index cc00c15..7f214b8 100644
--- a/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundationObjC.h
+++ b/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundationObjC.h
@@ -73,8 +73,8 @@ private:
virtual PlatformMedia platformMedia() const;
- virtual void play();
- virtual void pause();
+ virtual void platformPlay();
+ virtual void platformPause();
virtual float currentTime() const;
virtual void setVolume(float);
virtual void setClosedCaptionsVisible(bool);
@@ -93,6 +93,7 @@ private:
virtual MediaPlayerPrivateAVFoundation::AVAssetStatus assetStatus() const;
virtual void checkPlayability();
+ virtual void updateRate();
virtual float rate() const;
virtual void seekToTime(float time);
virtual unsigned totalBytes() const;
diff --git a/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundationObjC.mm b/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundationObjC.mm
index 55eb433..c4efb9f 100644
--- a/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundationObjC.mm
+++ b/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundationObjC.mm
@@ -100,6 +100,7 @@ enum MediaPlayerAVFoundationObservationContext {
-(void)playableKnown;
-(void)metadataLoaded;
-(void)timeChanged:(double)time;
+-(void)seekCompleted:(BOOL)finished;
-(void)didEnd:(NSNotification *)notification;
-(void)observeValueForKeyPath:keyPath ofObject:(id)object change:(NSDictionary *)change context:(MediaPlayerAVFoundationObservationContext)context;
@end
@@ -200,7 +201,7 @@ void MediaPlayerPrivateAVFoundationObjC::destroyContextVideoRenderer()
if (!m_imageGenerator)
return;
- LOG(Media, "MediaPlayerPrivateAVFoundationObjC::destroyContextVideoRenderer(%p) - destroying", this, m_imageGenerator.get());
+ LOG(Media, "MediaPlayerPrivateAVFoundationObjC::destroyContextVideoRenderer(%p) - destroying %p", this, m_imageGenerator.get());
m_imageGenerator = 0;
}
@@ -213,7 +214,7 @@ void MediaPlayerPrivateAVFoundationObjC::createVideoLayer()
if (!m_videoLayer) {
m_videoLayer.adoptNS([[AVPlayerLayer alloc] init]);
[m_videoLayer.get() setPlayer:m_avPlayer.get()];
- LOG(Media, "MediaPlayerPrivateAVFoundationObjC::createVideoLayer(%p) - returning", this, m_videoLayer.get());
+ LOG(Media, "MediaPlayerPrivateAVFoundationObjC::createVideoLayer(%p) - returning %p", this, m_videoLayer.get());
}
}
@@ -327,9 +328,9 @@ MediaPlayerPrivateAVFoundation::ItemStatus MediaPlayerPrivateAVFoundationObjC::p
return MediaPlayerPrivateAVFoundation::MediaPlayerAVPlayerItemStatusFailed;
if ([m_avPlayerItem.get() isPlaybackLikelyToKeepUp])
return MediaPlayerPrivateAVFoundation::MediaPlayerAVPlayerItemStatusPlaybackLikelyToKeepUp;
- if ([m_avPlayerItem.get() isPlaybackBufferFull])
+ if (buffered()->contain(duration()))
return MediaPlayerPrivateAVFoundation::MediaPlayerAVPlayerItemStatusPlaybackBufferFull;
- if ([m_avPlayerItem.get() isPlaybackBufferEmpty])
+ if (buffered()->contain(currentTime()))
return MediaPlayerPrivateAVFoundation::MediaPlayerAVPlayerItemStatusPlaybackBufferEmpty;
return MediaPlayerPrivateAVFoundation::MediaPlayerAVPlayerItemStatusReadyToPlay;
@@ -350,9 +351,9 @@ PlatformLayer* MediaPlayerPrivateAVFoundationObjC::platformLayer() const
return m_videoLayer.get();
}
-void MediaPlayerPrivateAVFoundationObjC::play()
+void MediaPlayerPrivateAVFoundationObjC::platformPlay()
{
- LOG(Media, "MediaPlayerPrivateAVFoundationObjC::play(%p)", this);
+ LOG(Media, "MediaPlayerPrivateAVFoundationObjC::platformPlay(%p)", this);
if (!metaDataAvailable())
return;
@@ -361,9 +362,9 @@ void MediaPlayerPrivateAVFoundationObjC::play()
setDelayCallbacks(false);
}
-void MediaPlayerPrivateAVFoundationObjC::pause()
+void MediaPlayerPrivateAVFoundationObjC::platformPause()
{
- LOG(Media, "MediaPlayerPrivateAVFoundationObjC::pause(%p)", this);
+ LOG(Media, "MediaPlayerPrivateAVFoundationObjC::platformPause(%p)", this);
if (!metaDataAvailable())
return;
@@ -408,14 +409,10 @@ void MediaPlayerPrivateAVFoundationObjC::seekToTime(float time)
// setCurrentTime generates several event callbacks, update afterwards.
setDelayCallbacks(true);
- float now = currentTime();
- if (time != now)
- [m_avPlayerItem.get() seekToTime:CMTimeMakeWithSeconds(time, 600) toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero];
- else {
- // Force a call to the "time changed" notifier manually because a seek to the current time is a noop
- // so the seek will never seem to complete.
- [m_objcObserver.get() timeChanged:now];
- }
+ WebCoreAVFMovieObserver *observer = m_objcObserver.get();
+ [m_avPlayerItem.get() seekToTime:CMTimeMakeWithSeconds(time, 600) toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero completionHandler:^(BOOL finished) {
+ [observer seekCompleted:finished];
+ }];
setDelayCallbacks(false);
}
@@ -437,6 +434,13 @@ void MediaPlayerPrivateAVFoundationObjC::setClosedCaptionsVisible(bool closedCap
[m_avPlayer.get() setClosedCaptionDisplayEnabled:closedCaptionsVisible];
}
+void MediaPlayerPrivateAVFoundationObjC::updateRate()
+{
+ setDelayCallbacks(true);
+ [m_avPlayer.get() setRate:requestedRate()];
+ setDelayCallbacks(false);
+}
+
float MediaPlayerPrivateAVFoundationObjC::rate() const
{
if (!metaDataAvailable())
@@ -621,12 +625,16 @@ void MediaPlayerPrivateAVFoundationObjC::getSupportedTypes(HashSet<String>& supp
MediaPlayer::SupportsType MediaPlayerPrivateAVFoundationObjC::supportsType(const String& type, const String& codecs)
{
- // Only return "IsSupported" if there is no codecs parameter for now as there is no way to ask if it supports an
- // extended MIME type until rdar://6220037 is fixed.
- if (mimeTypeCache().contains(type))
- return codecs.isEmpty() ? MediaPlayer::MayBeSupported : MediaPlayer::IsSupported;
+ if (!mimeTypeCache().contains(type))
+ return MediaPlayer::IsNotSupported;
+
+ // The spec says:
+ // "Implementors are encouraged to return "maybe" unless the type can be confidently established as being supported or not."
+ if (codecs.isEmpty())
+ return MediaPlayer::MayBeSupported;
- return MediaPlayer::IsNotSupported;
+ NSString *typeString = [NSString stringWithFormat:@"%@; codecs=\"%@\"", (NSString *)type, (NSString *)codecs];
+ return [AVURLAsset isPlayableExtendedMIMEType:typeString] ? MediaPlayer::IsSupported : MediaPlayer::MayBeSupported;;
}
bool MediaPlayerPrivateAVFoundationObjC::isAvailable()
@@ -758,6 +766,14 @@ NSArray* itemKVOProperties()
m_callback->scheduleMainThreadNotification(MediaPlayerPrivateAVFoundation::Notification::PlayerTimeChanged, time);
}
+- (void)seekCompleted:(BOOL)finished
+{
+ if (!m_callback)
+ return;
+
+ m_callback->scheduleMainThreadNotification(MediaPlayerPrivateAVFoundation::Notification::SeekCompleted, static_cast<bool>(finished));
+}
+
- (void)didEnd:(NSNotification *)unusedNotification
{
UNUSED_PARAM(unusedNotification);
diff --git a/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp b/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp
index 427c7bf..8fb4c9f 100644
--- a/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp
+++ b/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp
@@ -255,6 +255,7 @@ GraphicsLayerCA::GraphicsLayerCA(GraphicsLayerClient* client)
, m_contentsLayerHasBackgroundColor(false)
, m_uncommittedChanges(NoChange)
, m_contentsScale(1)
+ , m_allowTiledLayer(true)
{
m_layer = PlatformCALayer::create(PlatformCALayer::LayerTypeWebLayer, this);
@@ -492,6 +493,17 @@ void GraphicsLayerCA::setAcceleratesDrawing(bool acceleratesDrawing)
noteLayerPropertyChanged(AcceleratesDrawingChanged);
}
+void GraphicsLayerCA::setAllowTiledLayer(bool allowTiledLayer)
+{
+ if (allowTiledLayer == m_allowTiledLayer)
+ return;
+
+ m_allowTiledLayer = allowTiledLayer;
+
+ // Handling this as a SizeChanged will cause use to switch in or out of tiled layer as needed
+ noteLayerPropertyChanged(SizeChanged);
+}
+
void GraphicsLayerCA::setBackgroundColor(const Color& color)
{
if (m_backgroundColorSet && m_backgroundColor == color)
@@ -2005,7 +2017,7 @@ FloatSize GraphicsLayerCA::constrainedSize() const
bool GraphicsLayerCA::requiresTiledLayer(const FloatSize& size) const
{
- if (!m_drawsContent)
+ if (!m_drawsContent || !m_allowTiledLayer)
return false;
// FIXME: catch zero-size height or width here (or earlier)?
diff --git a/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h b/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h
index 2c39c0a..3f2d3e4 100644
--- a/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h
+++ b/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h
@@ -122,6 +122,9 @@ public:
virtual void syncCompositingState();
virtual void syncCompositingStateForThisLayerOnly();
+ bool allowTiledLayer() const { return m_allowTiledLayer; }
+ virtual void setAllowTiledLayer(bool b);
+
protected:
virtual void setOpacityInternal(float);
@@ -399,6 +402,8 @@ private:
float clampedContentsScaleForScale(float) const;
float m_contentsScale;
+
+ bool m_allowTiledLayer;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/ca/TransformationMatrixCA.cpp b/Source/WebCore/platform/graphics/ca/TransformationMatrixCA.cpp
index 0ef5fd0..e5ff5ba 100644
--- a/Source/WebCore/platform/graphics/ca/TransformationMatrixCA.cpp
+++ b/Source/WebCore/platform/graphics/ca/TransformationMatrixCA.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#include "TransformationMatrix.h"
-#if PLATFORM(CA)
+#if USE(CA)
#include "FloatConversion.h"
#include <QuartzCore/CATransform3D.h>
@@ -66,4 +66,4 @@ TransformationMatrix::operator CATransform3D() const
}
-#endif // PLATFORM(CA)
+#endif // USE(CA)
diff --git a/Source/WebCore/platform/graphics/ca/win/AbstractCACFLayerTreeHost.h b/Source/WebCore/platform/graphics/ca/win/AbstractCACFLayerTreeHost.h
new file mode 100644
index 0000000..13c6746
--- /dev/null
+++ b/Source/WebCore/platform/graphics/ca/win/AbstractCACFLayerTreeHost.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 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
+ * 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 AbstractCACFLayerTreeHost_h
+#define AbstractCACFLayerTreeHost_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include <wtf/Forward.h>
+
+namespace WebCore {
+
+class PlatformCALayer;
+
+class AbstractCACFLayerTreeHost {
+public:
+ virtual PlatformCALayer* rootLayer() const = 0;
+ virtual void addPendingAnimatedLayer(PassRefPtr<PlatformCALayer>) = 0;
+ virtual void layerTreeDidChange() = 0;
+ virtual void flushPendingLayerChangesNow() = 0;
+
+protected:
+ virtual ~AbstractCACFLayerTreeHost() { }
+};
+
+}
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
+#endif // AbstractCACFLayerTreeHost_h
diff --git a/Source/WebCore/platform/graphics/ca/win/CACFLayerTreeHost.h b/Source/WebCore/platform/graphics/ca/win/CACFLayerTreeHost.h
index 6d91a73..507af0f 100644
--- a/Source/WebCore/platform/graphics/ca/win/CACFLayerTreeHost.h
+++ b/Source/WebCore/platform/graphics/ca/win/CACFLayerTreeHost.h
@@ -28,6 +28,7 @@
#if USE(ACCELERATED_COMPOSITING)
+#include "AbstractCACFLayerTreeHost.h"
#include "COMPtr.h"
#include "Timer.h"
@@ -50,9 +51,7 @@ namespace WebCore {
class CACFLayerTreeHostClient;
class PlatformCALayer;
-class CACFLayerTreeHost : public RefCounted<CACFLayerTreeHost> {
- friend PlatformCALayer;
-
+class CACFLayerTreeHost : public RefCounted<CACFLayerTreeHost>, private AbstractCACFLayerTreeHost {
public:
static PassRefPtr<CACFLayerTreeHost> create();
virtual ~CACFLayerTreeHost();
@@ -66,24 +65,31 @@ public:
virtual void paint();
virtual void resize() = 0;
void flushPendingGraphicsLayerChangesSoon();
- void flushPendingLayerChangesNow();
+
+ // AbstractCACFLayerTreeHost
+ virtual void flushPendingLayerChangesNow();
protected:
CACFLayerTreeHost();
CGRect bounds() const;
- PlatformCALayer* rootLayer() const;
HWND window() const { return m_window; }
void notifyAnimationsStarted();
+ // AbstractCACFLayerTreeHost
+ virtual PlatformCALayer* rootLayer() const;
+
virtual bool createRenderer() = 0;
virtual void destroyRenderer();
virtual void contextDidChange();
private:
void initialize();
- void addPendingAnimatedLayer(PassRefPtr<PlatformCALayer>);
- void layerTreeDidChange();
+
+ // AbstractCACFLayerTreeHost
+ virtual void addPendingAnimatedLayer(PassRefPtr<PlatformCALayer>);
+ virtual void layerTreeDidChange();
+
virtual void flushContext() = 0;
virtual CFTimeInterval lastCommitTime() const = 0;
diff --git a/Source/WebCore/platform/graphics/ca/win/LayerChangesFlusher.cpp b/Source/WebCore/platform/graphics/ca/win/LayerChangesFlusher.cpp
index 3fd857b..ec2a9ff 100644
--- a/Source/WebCore/platform/graphics/ca/win/LayerChangesFlusher.cpp
+++ b/Source/WebCore/platform/graphics/ca/win/LayerChangesFlusher.cpp
@@ -28,8 +28,7 @@
#if USE(ACCELERATED_COMPOSITING)
-#include "CACFLayerTreeHost.h"
-#include "WebCoreInstanceHandle.h"
+#include "AbstractCACFLayerTreeHost.h"
#include <wtf/StdLibExtras.h>
#include <wtf/Vector.h>
@@ -47,7 +46,7 @@ LayerChangesFlusher::LayerChangesFlusher()
{
}
-void LayerChangesFlusher::flushPendingLayerChangesSoon(CACFLayerTreeHost* host)
+void LayerChangesFlusher::flushPendingLayerChangesSoon(AbstractCACFLayerTreeHost* host)
{
if (!m_hostsWithChangesToFlush.add(host).second || m_hook)
return;
@@ -55,7 +54,7 @@ void LayerChangesFlusher::flushPendingLayerChangesSoon(CACFLayerTreeHost* host)
setHook();
}
-void LayerChangesFlusher::cancelPendingFlush(CACFLayerTreeHost* host)
+void LayerChangesFlusher::cancelPendingFlush(AbstractCACFLayerTreeHost* host)
{
m_hostsWithChangesToFlush.remove(host);
@@ -80,9 +79,8 @@ LRESULT LayerChangesFlusher::hookFired(int code, WPARAM wParam, LPARAM lParam)
ASSERT(m_hook);
// Calling out to the hosts can cause m_hostsWithChangesToFlush to be modified, so we copy it
- // into a Vector first. We have to hold a reference to them because otherwise they could be
- // destroyed while we're calling out to them.
- Vector<RefPtr<CACFLayerTreeHost> > hosts;
+ // into a Vector first.
+ Vector<AbstractCACFLayerTreeHost*> hosts;
copyToVector(m_hostsWithChangesToFlush, hosts);
m_hostsWithChangesToFlush.clear();
@@ -108,7 +106,7 @@ void LayerChangesFlusher::setHook()
DWORD threadID = ::GetCurrentThreadId();
- m_hook = ::SetWindowsHookExW(WH_GETMESSAGE, hookCallback, instanceHandle(), threadID);
+ m_hook = ::SetWindowsHookExW(WH_GETMESSAGE, hookCallback, 0, threadID);
ASSERT_WITH_MESSAGE(m_hook, "::SetWindowsHookExW failed with error %lu", ::GetLastError());
// Post a message to the message queue to prevent ::GetMessage from blocking, which will ensure
diff --git a/Source/WebCore/platform/graphics/ca/win/LayerChangesFlusher.h b/Source/WebCore/platform/graphics/ca/win/LayerChangesFlusher.h
index 6a98a99..1e7ab31 100644
--- a/Source/WebCore/platform/graphics/ca/win/LayerChangesFlusher.h
+++ b/Source/WebCore/platform/graphics/ca/win/LayerChangesFlusher.h
@@ -34,15 +34,15 @@
namespace WebCore {
-class CACFLayerTreeHost;
+class AbstractCACFLayerTreeHost;
class LayerChangesFlusher {
WTF_MAKE_NONCOPYABLE(LayerChangesFlusher);
public:
static LayerChangesFlusher& shared();
- void flushPendingLayerChangesSoon(CACFLayerTreeHost*);
- void cancelPendingFlush(CACFLayerTreeHost*);
+ void flushPendingLayerChangesSoon(AbstractCACFLayerTreeHost*);
+ void cancelPendingFlush(AbstractCACFLayerTreeHost*);
private:
LayerChangesFlusher();
@@ -53,7 +53,7 @@ private:
void setHook();
void removeHook();
- HashSet<CACFLayerTreeHost*> m_hostsWithChangesToFlush;
+ HashSet<AbstractCACFLayerTreeHost*> m_hostsWithChangesToFlush;
HHOOK m_hook;
bool m_isCallingHosts;
};
diff --git a/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.cpp b/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.cpp
index b5a26f4..5d20928 100644
--- a/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.cpp
+++ b/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.cpp
@@ -29,7 +29,7 @@
#include "PlatformCALayer.h"
-#include "CACFLayerTreeHost.h"
+#include "AbstractCACFLayerTreeHost.h"
#include "Font.h"
#include "GraphicsContext.h"
#include "PlatformCALayerWinInternal.h"
@@ -65,14 +65,14 @@ static CFStringRef toCACFFilterType(PlatformCALayer::FilterType type)
}
}
-static CACFLayerTreeHost* layerTreeHostForLayer(const PlatformCALayer* layer)
+static AbstractCACFLayerTreeHost* layerTreeHostForLayer(const PlatformCALayer* layer)
{
- // We need the CACFLayerTreeHost associated with this layer, which is stored in the UserData of the CACFContext
+ // We need the AbstractCACFLayerTreeHost associated with this layer, which is stored in the UserData of the CACFContext
void* userData = wkCACFLayerGetContextUserData(layer->platformLayer());
if (!userData)
return 0;
- return static_cast<CACFLayerTreeHost*>(userData);
+ return static_cast<AbstractCACFLayerTreeHost*>(userData);
}
static PlatformCALayerWinInternal* intern(const PlatformCALayer* layer)
@@ -156,7 +156,7 @@ PlatformLayer* PlatformCALayer::platformLayer() const
PlatformCALayer* PlatformCALayer::rootLayer() const
{
- CACFLayerTreeHost* host = layerTreeHostForLayer(this);
+ AbstractCACFLayerTreeHost* host = layerTreeHostForLayer(this);
return host ? host->rootLayer() : 0;
}
@@ -167,7 +167,7 @@ void PlatformCALayer::setNeedsDisplay(const FloatRect* dirtyRect)
void PlatformCALayer::setNeedsCommit()
{
- CACFLayerTreeHost* host = layerTreeHostForLayer(this);
+ AbstractCACFLayerTreeHost* host = layerTreeHostForLayer(this);
if (host)
host->layerTreeDidChange();
}
@@ -270,7 +270,7 @@ void PlatformCALayer::addAnimationForKey(const String& key, PlatformCAAnimation*
setNeedsCommit();
// Tell the host about it so we can fire the start animation event
- CACFLayerTreeHost* host = layerTreeHostForLayer(this);
+ AbstractCACFLayerTreeHost* host = layerTreeHostForLayer(this);
if (host)
host->addPendingAnimatedLayer(this);
}
@@ -283,7 +283,7 @@ void PlatformCALayer::removeAnimationForKey(const String& key)
RetainPtr<CFStringRef> s(AdoptCF, key.createCFString());
CACFLayerRemoveAnimation(m_layer.get(), s.get());
- // We don't "remove" a layer from CACFLayerTreeHost when it loses an animation.
+ // We don't "remove" a layer from AbstractCACFLayerTreeHost when it loses an animation.
// There may be other active animations on the layer and if an animation
// callback is fired on a layer without any animations no harm is done.
diff --git a/Source/WebCore/platform/graphics/ca/win/WKCACFViewLayerTreeHost.cpp b/Source/WebCore/platform/graphics/ca/win/WKCACFViewLayerTreeHost.cpp
index e672c2d..c4c3374 100644
--- a/Source/WebCore/platform/graphics/ca/win/WKCACFViewLayerTreeHost.cpp
+++ b/Source/WebCore/platform/graphics/ca/win/WKCACFViewLayerTreeHost.cpp
@@ -31,6 +31,7 @@
#include "PlatformCALayer.h"
#include "SoftLinking.h"
#include <wtf/CurrentTime.h>
+#include <wtf/Threading.h>
typedef struct _CACFLayer* CACFLayerRef;
@@ -42,7 +43,13 @@ SOFT_LINK_DEBUG_LIBRARY(WebKitQuartzCoreAdditions)
SOFT_LINK_LIBRARY(WebKitQuartzCoreAdditions)
#endif
-SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewCreate, WKCACFViewRef, __cdecl, (), ())
+enum WKCACFViewDrawingDestination {
+ kWKCACFViewDrawingDestinationWindow = 0,
+ kWKCACFViewDrawingDestinationImage,
+};
+typedef enum WKCACFViewDrawingDestination WKCACFViewDrawingDestination;
+
+SOFT_LINK(WebKitQuartzCoreAdditions, WKCACFViewCreate, WKCACFViewRef, __cdecl, (WKCACFViewDrawingDestination destination), (destination))
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))
@@ -63,7 +70,7 @@ PassRefPtr<WKCACFViewLayerTreeHost> WKCACFViewLayerTreeHost::create()
}
WKCACFViewLayerTreeHost::WKCACFViewLayerTreeHost()
- : m_view(AdoptCF, WKCACFViewCreate())
+ : m_view(AdoptCF, WKCACFViewCreate(kWKCACFViewDrawingDestinationWindow))
, m_viewNeedsUpdate(true)
{
}
@@ -98,6 +105,12 @@ void WKCACFViewLayerTreeHost::contextDidChangeCallback(WKCACFViewRef view, void*
void WKCACFViewLayerTreeHost::contextDidChange()
{
+ // This should only be called on a background thread when no changes have actually
+ // been committed to the context, eg. when a video frame has been added to an image
+ // queue, so return without triggering animations etc.
+ if (!isMainThread())
+ return;
+
// Tell the WKCACFView to start rendering now that we have some contents to render.
updateViewIfNeeded();
diff --git a/Source/WebCore/platform/graphics/cairo/CairoPath.h b/Source/WebCore/platform/graphics/cairo/CairoPath.h
deleted file mode 100644
index da7affb..0000000
--- a/Source/WebCore/platform/graphics/cairo/CairoPath.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- Copyright (C) 2007 Alp Toker <alp.toker@collabora.co.uk>
- Copyright (C) 2010 Igalia S.L.
-
- 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
- aint 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 CairoPath_h
-#define CairoPath_h
-
-#include <cairo.h>
-
-namespace WebCore {
-
-// This is necessary since cairo_path_fixed_t isn't exposed in Cairo's public API.
-class CairoPath {
-public:
- CairoPath()
- {
- static cairo_surface_t* pathSurface = cairo_image_surface_create(CAIRO_FORMAT_A8, 1, 1);
- m_cr = cairo_create(pathSurface);
- }
-
- ~CairoPath()
- {
- cairo_destroy(m_cr);
- }
-
- cairo_t* context() { return m_cr; }
-
-private:
- cairo_t* m_cr;
-};
-
-} // namespace WebCore
-
-#endif // CairoPath_h
diff --git a/Source/WebCore/platform/graphics/cairo/CairoUtilities.cpp b/Source/WebCore/platform/graphics/cairo/CairoUtilities.cpp
index ee159a1..758bce9 100644
--- a/Source/WebCore/platform/graphics/cairo/CairoUtilities.cpp
+++ b/Source/WebCore/platform/graphics/cairo/CairoUtilities.cpp
@@ -27,13 +27,13 @@
#include "CairoUtilities.h"
#include "AffineTransform.h"
-#include "CairoPath.h"
#include "Color.h"
#include "FloatPoint.h"
#include "FloatRect.h"
#include "IntRect.h"
#include "OwnPtrCairo.h"
#include "Path.h"
+#include "PlatformPathCairo.h"
#include "RefPtrCairo.h"
#include <wtf/Vector.h>
diff --git a/Source/WebCore/platform/graphics/cairo/ContextShadowCairo.cpp b/Source/WebCore/platform/graphics/cairo/ContextShadowCairo.cpp
index 0f90ce4..d968ee9 100644
--- a/Source/WebCore/platform/graphics/cairo/ContextShadowCairo.cpp
+++ b/Source/WebCore/platform/graphics/cairo/ContextShadowCairo.cpp
@@ -42,11 +42,10 @@ using WTF::max;
namespace WebCore {
-static cairo_surface_t* scratchBuffer = 0;
+static RefPtr<cairo_surface_t> gScratchBuffer;
static void purgeScratchBuffer()
{
- cairo_surface_destroy(scratchBuffer);
- scratchBuffer = 0;
+ gScratchBuffer.clear();
}
// ContextShadow needs a scratch image as the buffer for the blur filter.
@@ -68,20 +67,20 @@ static cairo_surface_t* getScratchBuffer(const IntSize& size)
{
int width = size.width();
int height = size.height();
- int scratchWidth = scratchBuffer ? cairo_image_surface_get_width(scratchBuffer) : 0;
- int scratchHeight = scratchBuffer ? cairo_image_surface_get_height(scratchBuffer) : 0;
+ int scratchWidth = gScratchBuffer.get() ? cairo_image_surface_get_width(gScratchBuffer.get()) : 0;
+ int scratchHeight = gScratchBuffer.get() ? cairo_image_surface_get_height(gScratchBuffer.get()) : 0;
// We do not need to recreate the buffer if the current buffer is large enough.
- if (scratchBuffer && scratchWidth >= width && scratchHeight >= height)
- return scratchBuffer;
+ if (gScratchBuffer.get() && scratchWidth >= width && scratchHeight >= height)
+ return gScratchBuffer.get();
purgeScratchBuffer();
// Round to the nearest 32 pixels so we do not grow the buffer for similar sized requests.
width = (1 + (width >> 5)) << 5;
height = (1 + (height >> 5)) << 5;
- scratchBuffer = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
- return scratchBuffer;
+ gScratchBuffer = adoptRef(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height));
+ return gScratchBuffer.get();
}
PlatformContext ContextShadow::beginShadowLayer(GraphicsContext* context, const FloatRect& layerArea)
diff --git a/Source/WebCore/platform/graphics/cairo/DrawErrorUnderline.h b/Source/WebCore/platform/graphics/cairo/DrawErrorUnderline.h
index b90bb8c..3a49d5c 100644
--- a/Source/WebCore/platform/graphics/cairo/DrawErrorUnderline.h
+++ b/Source/WebCore/platform/graphics/cairo/DrawErrorUnderline.h
@@ -21,7 +21,7 @@
*
*/
-#if PLATFORM(CAIRO)
+#if USE(CAIRO)
#ifndef DrawErrorUnderline_h
#define DrawErrorUnderline_h
diff --git a/Source/WebCore/platform/graphics/cairo/GraphicsContext3DCairo.cpp b/Source/WebCore/platform/graphics/cairo/GraphicsContext3DCairo.cpp
new file mode 100644
index 0000000..c90d8ab
--- /dev/null
+++ b/Source/WebCore/platform/graphics/cairo/GraphicsContext3DCairo.cpp
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ * Copyright (C) 2011 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "GraphicsContext3D.h"
+#include "PlatformContextCairo.h"
+
+#if ENABLE(WEBGL)
+
+#include "Image.h"
+#include "RefPtrCairo.h"
+#include <cairo.h>
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+bool GraphicsContext3D::getImageData(Image* image, unsigned int format, unsigned int type, bool premultiplyAlpha, bool ignoreGammaAndColorProfile, Vector<uint8_t>& outputVector)
+{
+ if (!image)
+ return false;
+ // We need this to stay in scope because the native image is just a shallow copy of the data.
+ ImageSource decoder(premultiplyAlpha ? ImageSource::AlphaPremultiplied : ImageSource::AlphaNotPremultiplied,
+ ignoreGammaAndColorProfile ? ImageSource::GammaAndColorProfileIgnored : ImageSource::GammaAndColorProfileApplied);
+ AlphaOp alphaOp = AlphaDoNothing;
+ RefPtr<cairo_surface_t> imageSurface;
+ if (image->data()) {
+ decoder.setData(image->data(), true);
+ if (!decoder.frameCount() || !decoder.frameIsCompleteAtIndex(0))
+ return false;
+ imageSurface = decoder.createFrameAtIndex(0);
+ } else {
+ imageSurface = image->nativeImageForCurrentFrame();
+ if (!premultiplyAlpha)
+ alphaOp = AlphaDoUnmultiply;
+ }
+
+ if (!imageSurface)
+ return false;
+
+ int width = cairo_image_surface_get_width(imageSurface.get());
+ int height = cairo_image_surface_get_height(imageSurface.get());
+ if (!width || !height)
+ return false;
+
+ if (cairo_image_surface_get_format(imageSurface.get()) != CAIRO_FORMAT_ARGB32)
+ return false;
+
+ unsigned int srcUnpackAlignment = 1;
+ size_t bytesPerRow = cairo_image_surface_get_stride(imageSurface.get());
+ size_t bitsPerPixel = 32;
+ unsigned int padding = bytesPerRow - bitsPerPixel / 8 * width;
+ if (padding) {
+ srcUnpackAlignment = padding + 1;
+ while (bytesPerRow % srcUnpackAlignment)
+ ++srcUnpackAlignment;
+ }
+
+ outputVector.resize(width * height * 4);
+ return packPixels(cairo_image_surface_get_data(imageSurface.get()), SourceFormatBGRA8,
+ width, height, srcUnpackAlignment, format, type, alphaOp, outputVector.data());
+}
+
+void GraphicsContext3D::paintToCanvas(const unsigned char* imagePixels, int imageWidth, int imageHeight, int canvasWidth, int canvasHeight, PlatformContextCairo* context)
+{
+ if (!imagePixels || imageWidth <= 0 || imageHeight <= 0 || canvasWidth <= 0 || canvasHeight <= 0 || !context)
+ return;
+
+ cairo_t *cr = context->cr();
+ context->save();
+
+ cairo_rectangle(cr, 0, 0, canvasWidth, canvasHeight);
+ cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
+ cairo_paint(cr);
+
+ RefPtr<cairo_surface_t> imageSurface = adoptRef(cairo_image_surface_create_for_data(
+ const_cast<unsigned char*>(imagePixels), CAIRO_FORMAT_ARGB32, imageWidth, imageHeight, imageWidth * 4));
+
+ // OpenGL keeps the pixels stored bottom up, so we need to flip the image here.
+ cairo_translate(cr, 0, imageHeight);
+ cairo_scale(cr, 1, -1);
+
+ cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
+ cairo_set_source_surface(cr, imageSurface.get(), 0, 0);
+ cairo_rectangle(cr, 0, 0, canvasWidth, -canvasHeight);
+
+ cairo_fill(cr);
+ context->restore();
+}
+
+void GraphicsContext3D::setContextLostCallback(PassOwnPtr<ContextLostCallback>)
+{
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp b/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
index 0fc94df..4cd0844 100644
--- a/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
+++ b/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
@@ -32,10 +32,9 @@
#include "config.h"
#include "GraphicsContext.h"
-#if PLATFORM(CAIRO)
+#if USE(CAIRO)
#include "AffineTransform.h"
-#include "CairoPath.h"
#include "CairoUtilities.h"
#include "ContextShadow.h"
#include "FloatConversion.h"
@@ -48,6 +47,7 @@
#include "Path.h"
#include "Pattern.h"
#include "PlatformContextCairo.h"
+#include "PlatformPathCairo.h"
#include "RefPtrCairo.h"
#include "SimpleFontData.h"
#include <cairo.h>
@@ -201,8 +201,9 @@ static void strokeCurrentCairoPath(GraphicsContext* context, cairo_t* cairoCont
}
GraphicsContext::GraphicsContext(cairo_t* cr)
+ : m_updatingControlTints(false)
{
- m_data = new GraphicsContextPlatformPrivate(new PlatformContextCairo(cr));
+ m_data = new GraphicsContextPlatformPrivateToplevel(new PlatformContextCairo(cr));
}
void GraphicsContext::platformInit(PlatformContextCairo* platformContext)
@@ -234,24 +235,13 @@ PlatformContextCairo* GraphicsContext::platformContext() const
void GraphicsContext::savePlatformState()
{
- cairo_save(platformContext()->cr());
+ platformContext()->save();
m_data->save();
m_data->shadowStack.append(m_data->shadow);
- m_data->maskImageStack.append(ImageMaskInformation());
}
void GraphicsContext::restorePlatformState()
{
- cairo_t* cr = platformContext()->cr();
-
- const ImageMaskInformation& maskInformation = m_data->maskImageStack.last();
- if (maskInformation.isValid()) {
- const FloatRect& maskRect = maskInformation.maskRect();
- cairo_pop_group_to_source(cr);
- cairo_mask_surface(cr, maskInformation.maskSurface(), maskRect.x(), maskRect.y());
- }
- m_data->maskImageStack.removeLast();
-
if (m_data->shadowStack.isEmpty())
m_data->shadow = ContextShadow();
else {
@@ -259,7 +249,7 @@ void GraphicsContext::restorePlatformState()
m_data->shadowStack.removeLast();
}
- cairo_restore(cr);
+ platformContext()->restore();
m_data->restore();
}
@@ -765,7 +755,7 @@ void GraphicsContext::drawLineForTextChecking(const FloatPoint& origin, float wi
cairo_restore(cr);
}
-FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& frect)
+FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& frect, RoundingMode)
{
FloatRect result;
double x = frect.x();
@@ -1190,33 +1180,6 @@ InterpolationQuality GraphicsContext::imageInterpolationQuality() const
return InterpolationDefault;
}
-void GraphicsContext::pushImageMask(cairo_surface_t* surface, const FloatRect& rect)
-{
- // We must call savePlatformState at least once before we can use image masking,
- // since we actually apply the mask in restorePlatformState.
- ASSERT(!m_data->maskImageStack.isEmpty());
- m_data->maskImageStack.last().update(surface, rect);
-
- // Cairo doesn't support the notion of an image clip, so we push a group here
- // and then paint it to the surface with an image mask (which is an immediate
- // operation) during restorePlatformState.
-
- // We want to allow the clipped elements to composite with the surface as it
- // is now, but they are isolated in another group. To make this work, we're
- // going to blit the current surface contents onto the new group once we push it.
- cairo_t* cr = platformContext()->cr();
- cairo_surface_t* currentTarget = cairo_get_target(cr);
- cairo_surface_flush(currentTarget);
-
- // Pushing a new group ensures that only things painted after this point are clipped.
- cairo_push_group(cr);
- cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
-
- cairo_set_source_surface(cr, currentTarget, 0, 0);
- cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());
- cairo_fill(cr);
-}
-
} // namespace WebCore
-#endif // PLATFORM(CAIRO)
+#endif // USE(CAIRO)
diff --git a/Source/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h b/Source/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h
index 2bc290b..8fd056d 100644
--- a/Source/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h
+++ b/Source/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h
@@ -47,25 +47,6 @@ typedef struct _GdkExposeEvent GdkExposeEvent;
namespace WebCore {
-// In Cairo image masking is immediate, so to emulate image clipping we must save masking
-// details as part of the context state and apply it during platform restore.
-class ImageMaskInformation {
-public:
- void update(cairo_surface_t* maskSurface, const FloatRect& maskRect)
- {
- m_maskSurface = maskSurface;
- m_maskRect = maskRect;
- }
-
- bool isValid() const { return m_maskSurface; }
- cairo_surface_t* maskSurface() const { return m_maskSurface.get(); }
- const FloatRect& maskRect() const { return m_maskRect; }
-
-private:
- RefPtr<cairo_surface_t> m_maskSurface;
- FloatRect m_maskRect;
-};
-
class GraphicsContextPlatformPrivate {
public:
GraphicsContextPlatformPrivate(PlatformContextCairo* newPlatformContext)
@@ -81,7 +62,7 @@ public:
{
}
- ~GraphicsContextPlatformPrivate()
+ virtual ~GraphicsContextPlatformPrivate()
{
}
@@ -121,7 +102,6 @@ public:
Vector<float> layers;
ContextShadow shadow;
Vector<ContextShadow> shadowStack;
- Vector<ImageMaskInformation> maskImageStack;
#if PLATFORM(GTK)
GdkEventExpose* expose;
@@ -142,7 +122,7 @@ public:
{
}
- ~GraphicsContextPlatformPrivateToplevel()
+ virtual ~GraphicsContextPlatformPrivateToplevel()
{
delete platformContext;
}
diff --git a/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp b/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
index 1d5d492..8aa6531 100644
--- a/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
+++ b/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
@@ -55,11 +55,10 @@ static inline cairo_surface_t* copySurface(cairo_surface_t* surface)
int height = cairo_image_surface_get_height(surface);
cairo_surface_t* newsurface = cairo_image_surface_create(format, width, height);
- cairo_t* cr = cairo_create(newsurface);
- cairo_set_source_surface(cr, surface, 0, 0);
- cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
- cairo_paint(cr);
- cairo_destroy(cr);
+ RefPtr<cairo_t> cr = adoptRef(cairo_create(newsurface));
+ cairo_set_source_surface(cr.get(), surface, 0, 0);
+ cairo_set_operator(cr.get(), CAIRO_OPERATOR_SOURCE);
+ cairo_paint(cr.get());
return newsurface;
}
@@ -117,7 +116,7 @@ PassRefPtr<Image> ImageBuffer::copyImage() const
void ImageBuffer::clip(GraphicsContext* context, const FloatRect& maskRect) const
{
- context->pushImageMask(m_data.m_surface, maskRect);
+ context->platformContext()->pushImageMask(m_data.m_surface, maskRect);
}
void ImageBuffer::draw(GraphicsContext* context, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect,
diff --git a/Source/WebCore/platform/graphics/cairo/ImageBufferData.h b/Source/WebCore/platform/graphics/cairo/ImageBufferDataCairo.h
index 42867d1..5ca7262 100644
--- a/Source/WebCore/platform/graphics/cairo/ImageBufferData.h
+++ b/Source/WebCore/platform/graphics/cairo/ImageBufferDataCairo.h
@@ -23,9 +23,6 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ImageBufferData_h
-#define ImageBufferData_h
-
#include "PlatformContextCairo.h"
typedef struct _cairo_surface cairo_surface_t;
@@ -42,6 +39,4 @@ public:
PlatformContextCairo m_platformContext;
};
-} // namespace WebCore
-
-#endif // ImageBufferData_h
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/cairo/ImageCairo.cpp b/Source/WebCore/platform/graphics/cairo/ImageCairo.cpp
index d3a52ce..ce7d8b2 100644
--- a/Source/WebCore/platform/graphics/cairo/ImageCairo.cpp
+++ b/Source/WebCore/platform/graphics/cairo/ImageCairo.cpp
@@ -28,7 +28,7 @@
#include "config.h"
#include "BitmapImage.h"
-#if PLATFORM(CAIRO)
+#if USE(CAIRO)
#include "AffineTransform.h"
#include "CairoUtilities.h"
@@ -205,4 +205,4 @@ void BitmapImage::checkForSolidColor()
}
-#endif // PLATFORM(CAIRO)
+#endif // USE(CAIRO)
diff --git a/Source/WebCore/platform/graphics/cairo/OpenGLShims.cpp b/Source/WebCore/platform/graphics/cairo/OpenGLShims.cpp
new file mode 100644
index 0000000..92d79f9
--- /dev/null
+++ b/Source/WebCore/platform/graphics/cairo/OpenGLShims.cpp
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2011 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#if ENABLE(WEBGL)
+
+#define DISABLE_SHIMS
+#include "OpenGLShims.h"
+
+#include <dlfcn.h>
+#include <wtf/text/CString.h>
+#include <wtf/text/WTFString.h>
+
+#define ASSIGN_FUNCTION_TABLE_ENTRY(FunctionName, success) \
+ openGLFunctionTable()->FunctionName = reinterpret_cast<FunctionName##Type>(lookupOpenGLFunctionAddress(#FunctionName, success))
+
+namespace WebCore {
+
+typedef void* (*glGetProcAddressType) (const char* procName);
+static void* getProcAddress(const char* procName)
+{
+ static bool initialized = false;
+ static glGetProcAddressType getProcAddressFunction = 0;
+
+ if (!initialized) {
+ getProcAddressFunction = reinterpret_cast<glGetProcAddressType>(dlsym(RTLD_DEFAULT, "glXGetProcAddress"));
+ if (!getProcAddressFunction)
+ getProcAddressFunction = reinterpret_cast<glGetProcAddressType>(dlsym(RTLD_DEFAULT, "glXGetProcAddressARB"));
+ }
+
+ if (!getProcAddressFunction)
+ return dlsym(RTLD_DEFAULT, procName);
+ return getProcAddressFunction(procName);
+}
+
+static void* lookupOpenGLFunctionAddress(const char* functionName, bool& success)
+{
+ if (!success)
+ return 0;
+
+ void* target = getProcAddress(functionName);
+ if (target)
+ return target;
+
+ String fullFunctionName(functionName);
+ fullFunctionName.append("ARB");
+ target = getProcAddress(fullFunctionName.utf8().data());
+ if (target)
+ return target;
+
+ fullFunctionName = functionName;
+ fullFunctionName.append("EXT");
+ target = getProcAddress(fullFunctionName.utf8().data());
+
+ // A null address is still a failure case.
+ if (!target)
+ success = false;
+
+ return target;
+}
+
+OpenGLFunctionTable* openGLFunctionTable()
+{
+ static OpenGLFunctionTable table;
+ return &table;
+}
+
+bool initializeOpenGLShims()
+{
+ static bool success = true;
+ static bool initialized = false;
+ if (initialized)
+ return success;
+
+ initialized = true;
+ ASSIGN_FUNCTION_TABLE_ENTRY(glActiveTexture, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glAttachShader, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glBindAttribLocation, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glBindBuffer, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glBindFramebuffer, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glBindRenderbuffer, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glBlendColor, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glBlendEquation, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glBlendEquationSeparate, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glBlendFuncSeparate, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glBlitFramebuffer, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glBufferData, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glBufferSubData, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glCheckFramebufferStatus, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glCompileShader, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glCreateProgram, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glCreateShader, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glDeleteBuffers, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glDeleteFramebuffers, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glDeleteProgram, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glDeleteRenderbuffers, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glDeleteShader, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glDetachShader, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glDisableVertexAttribArray, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glEnableVertexAttribArray, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glFramebufferRenderbuffer, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glFramebufferTexture2D, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glGenBuffers, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glGenerateMipmap, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glGenFramebuffers, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glGenRenderbuffers, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glGetActiveAttrib, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glGetActiveUniform, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glGetAttachedShaders, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glGetAttribLocation, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glGetBufferParameteriv, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glGetFramebufferAttachmentParameteriv, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glGetProgramInfoLog, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glGetProgramiv, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glGetRenderbufferParameteriv, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glGetShaderInfoLog, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glGetShaderiv, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glGetShaderSource, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glGetUniformfv, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glGetUniformiv, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glGetUniformLocation, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glGetVertexAttribfv, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glGetVertexAttribiv, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glGetVertexAttribPointerv, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glIsBuffer, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glIsFramebuffer, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glIsProgram, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glIsRenderbuffer, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glIsShader, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glLinkProgram, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glRenderbufferStorage, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glRenderbufferStorageMultisample, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glSampleCoverage, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glShaderSource, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glStencilFuncSeparate, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glStencilMaskSeparate, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glStencilOpSeparate, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glUniform1f, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glUniform1fv, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glUniform1i, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glUniform1iv, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glUniform2f, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glUniform2fv, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glUniform2i, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glUniform2iv, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glUniform3f, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glUniform3fv, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glUniform3i, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glUniform3iv, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glUniform4f, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glUniform4fv, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glUniform4i, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glUniform4iv, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glUniformMatrix2fv, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glUniformMatrix3fv, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glUniformMatrix4fv, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glUseProgram, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glValidateProgram, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glVertexAttrib1f, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glVertexAttrib1fv, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glVertexAttrib2f, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glVertexAttrib2fv, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glVertexAttrib3f, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glVertexAttrib3fv, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glVertexAttrib4f, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glVertexAttrib4fv, success);
+ ASSIGN_FUNCTION_TABLE_ENTRY(glVertexAttribPointer, success);
+
+ if (!success)
+ LOG_ERROR("Could not initialize OpenGL shims");
+ return success;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/platform/graphics/cairo/OpenGLShims.h b/Source/WebCore/platform/graphics/cairo/OpenGLShims.h
new file mode 100644
index 0000000..a431b03
--- /dev/null
+++ b/Source/WebCore/platform/graphics/cairo/OpenGLShims.h
@@ -0,0 +1,315 @@
+/*
+ * Copyright (C) 2010 Tieto Corporation.
+ * Copyright (C) 2011 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <GL/gl.h>
+
+typedef struct _OpenGLFunctionTable OpenGLFunctionTable;
+
+namespace WebCore {
+bool initializeOpenGLShims();
+OpenGLFunctionTable* openGLFunctionTable();
+}
+
+typedef void (*glActiveTextureType) (GLenum);
+typedef void (*glAttachShaderType) (GLuint, GLuint);
+typedef void (*glBindAttribLocationType) (GLuint, GLuint, const char*);
+typedef void (*glBindBufferType) (GLenum, GLuint);
+typedef void (*glBindFramebufferType) (GLenum, GLuint);
+typedef void (*glBindRenderbufferType) (GLenum, GLuint);
+typedef void (*glBlendColorType) (GLclampf, GLclampf, GLclampf, GLclampf);
+typedef void (*glBlendEquationType) (GLenum);
+typedef void (*glBlendEquationSeparateType)(GLenum, GLenum);
+typedef void (*glBlendFuncSeparateType)(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+typedef void (*glBlitFramebufferType) (GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum);
+typedef void (*glBufferDataType) (GLenum, GLsizeiptr, const GLvoid*, GLenum);
+typedef void (*glBufferSubDataType) (GLenum, GLintptr, GLsizeiptr, const GLvoid*);
+typedef GLenum (*glCheckFramebufferStatusType) (GLenum);
+typedef void (*glCompileShaderType) (GLuint);
+typedef GLuint (*glCreateProgramType) ();
+typedef GLuint (*glCreateShaderType) (GLenum);
+typedef void (*glDeleteBuffersType) (GLsizei, const GLuint*);
+typedef void (*glDeleteFramebuffersType) (GLsizei n, const GLuint*);
+typedef void (*glDeleteProgramType) (GLuint);
+typedef void (*glDeleteRenderbuffersType) (GLsizei n, const GLuint*);
+typedef void (*glDeleteShaderType) (GLuint);
+typedef void (*glDetachShaderType) (GLuint, GLuint);
+typedef void (*glDisableVertexAttribArrayType) (GLuint);
+typedef void (*glEnableVertexAttribArrayType) (GLuint);
+typedef void (*glFramebufferRenderbufferType) (GLenum, GLenum, GLenum, GLuint);
+typedef void (*glFramebufferTexture2DType) (GLenum, GLenum, GLenum, GLuint, GLint);
+typedef void (*glGenBuffersType) (GLsizei, GLuint*);
+typedef void (*glGenerateMipmapType) (GLenum target);
+typedef void (*glGenFramebuffersType) (GLsizei, GLuint*);
+typedef void (*glGenRenderbuffersType) (GLsizei, GLuint*);
+typedef void (*glGetActiveAttribType) (GLuint, GLuint, GLsizei, GLsizei*, GLint*, GLenum*, GLchar*);
+typedef void (*glGetActiveUniformType) (GLuint, GLuint, GLsizei, GLsizei*, GLint*, GLenum*, GLchar*);
+typedef void (*glGetAttachedShadersType) (GLuint, GLsizei, GLsizei*, GLuint*);
+typedef GLint (*glGetAttribLocationType) (GLuint, const char*);
+typedef void (*glGetBufferParameterivType) (GLenum, GLenum, GLint*);
+typedef void (*glGetFramebufferAttachmentParameterivType) (GLenum, GLenum, GLenum, GLint* params);
+typedef void (*glGetProgramInfoLogType) (GLuint, GLsizei, GLsizei*, char*);
+typedef void (*glGetProgramivType) (GLuint, GLenum, GLint*);
+typedef void (*glGetRenderbufferParameterivType) (GLenum, GLenum, GLint*);
+typedef void (*glGetShaderInfoLogType) (GLuint, GLsizei, GLsizei*, char*);
+typedef void (*glGetShaderivType) (GLuint, GLenum, GLint*);
+typedef void (*glGetShaderSourceType) (GLuint, GLsizei, GLsizei*, char*);
+typedef GLint (*glGetUniformLocationType) (GLuint, const char*);
+typedef void (*glGetUniformfvType) (GLuint, GLint, GLfloat*);
+typedef void (*glGetUniformivType) (GLuint, GLint, GLint*);
+typedef void (*glGetVertexAttribfvType) (GLuint, GLenum, GLfloat*);
+typedef void (*glGetVertexAttribivType) (GLuint, GLenum, GLint*);
+typedef void (*glGetVertexAttribPointervType) (GLuint, GLenum, GLvoid**);
+typedef GLboolean (*glIsBufferType) (GLuint);
+typedef GLboolean (*glIsFramebufferType) (GLuint);
+typedef GLboolean (*glIsProgramType) (GLuint);
+typedef GLboolean (*glIsRenderbufferType) (GLuint);
+typedef GLboolean (*glIsShaderType) (GLuint);
+typedef void (*glLinkProgramType) (GLuint);
+typedef void (*glRenderbufferStorageType) (GLenum, GLenum, GLsizei, GLsizei);
+typedef void (*glRenderbufferStorageMultisampleType) (GLenum, GLsizei, GLenum, GLsizei, GLsizei);
+typedef void (*glSampleCoverageType) (GLclampf, GLboolean);
+typedef void (*glShaderSourceType) (GLuint, GLsizei, const char**, const GLint*);
+typedef void (*glStencilFuncSeparateType) (GLenum, GLenum, GLint, GLuint);
+typedef void (*glStencilMaskSeparateType) (GLenum, GLuint);
+typedef void (*glStencilOpSeparateType) (GLenum, GLenum, GLenum, GLenum);
+typedef void (*glUniform1fType) (GLint, GLfloat);
+typedef void (*glUniform1fvType) (GLint, GLsizei, const GLfloat*);
+typedef void (*glUniform1iType) (GLint, GLint);
+typedef void (*glUniform1ivType) (GLint, GLsizei, const GLint*);
+typedef void (*glUniform2fType) (GLint, GLfloat, GLfloat);
+typedef void (*glUniform2fvType) (GLint, GLsizei, const GLfloat*);
+typedef void (*glUniform2iType) (GLint, GLint, GLint);
+typedef void (*glUniform2ivType) (GLint, GLsizei, const GLint*);
+typedef void (*glUniform3fType) (GLint, GLfloat, GLfloat, GLfloat);
+typedef void (*glUniform3fvType) (GLint, GLsizei, const GLfloat*);
+typedef void (*glUniform3iType) (GLint, GLint, GLint, GLint);
+typedef void (*glUniform3ivType) (GLint, GLsizei, const GLint*);
+typedef void (*glUniform4fType) (GLint, GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (*glUniform4fvType) (GLint, GLsizei, const GLfloat*);
+typedef void (*glUniform4iType) (GLint, GLint, GLint, GLint, GLint);
+typedef void (*glUniform4ivType) (GLint, GLsizei, const GLint*);
+typedef void (*glUniformMatrix2fvType) (GLint, GLsizei, GLboolean, const GLfloat*);
+typedef void (*glUniformMatrix3fvType) (GLint, GLsizei, GLboolean, const GLfloat*);
+typedef void (*glUniformMatrix4fvType) (GLint, GLsizei, GLboolean, const GLfloat*);
+typedef void (*glUseProgramType) (GLuint);
+typedef void (*glValidateProgramType) (GLuint);
+typedef void (*glVertexAttrib1fType) (GLuint, const GLfloat);
+typedef void (*glVertexAttrib1fvType) (GLuint, const GLfloat*);
+typedef void (*glVertexAttrib2fType) (GLuint, const GLfloat, const GLfloat);
+typedef void (*glVertexAttrib2fvType) (GLuint, const GLfloat*);
+typedef void (*glVertexAttrib3fType) (GLuint, const GLfloat, const GLfloat, const GLfloat);
+typedef void (*glVertexAttrib3fvType) (GLuint, const GLfloat*);
+typedef void (*glVertexAttrib4fType) (GLuint, const GLfloat, const GLfloat, const GLfloat, const GLfloat);
+typedef void (*glVertexAttrib4fvType) (GLuint, const GLfloat*);
+typedef void (*glVertexAttribPointerType) (GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid*);
+
+#define FUNCTION_TABLE_ENTRY(FunctionName) FunctionName##Type FunctionName
+
+typedef struct _OpenGLFunctionTable {
+ FUNCTION_TABLE_ENTRY(glActiveTexture);
+ FUNCTION_TABLE_ENTRY(glAttachShader);
+ FUNCTION_TABLE_ENTRY(glBindAttribLocation);
+ FUNCTION_TABLE_ENTRY(glBindBuffer);
+ FUNCTION_TABLE_ENTRY(glBindFramebuffer);
+ FUNCTION_TABLE_ENTRY(glBindRenderbuffer);
+ FUNCTION_TABLE_ENTRY(glBlendColor);
+ FUNCTION_TABLE_ENTRY(glBlendEquation);
+ FUNCTION_TABLE_ENTRY(glBlendEquationSeparate);
+ FUNCTION_TABLE_ENTRY(glBlendFuncSeparate);
+ FUNCTION_TABLE_ENTRY(glBlitFramebuffer);
+ FUNCTION_TABLE_ENTRY(glBufferData);
+ FUNCTION_TABLE_ENTRY(glBufferSubData);
+ FUNCTION_TABLE_ENTRY(glCheckFramebufferStatus);
+ FUNCTION_TABLE_ENTRY(glCompileShader);
+ FUNCTION_TABLE_ENTRY(glCreateProgram);
+ FUNCTION_TABLE_ENTRY(glCreateShader);
+ FUNCTION_TABLE_ENTRY(glDeleteBuffers);
+ FUNCTION_TABLE_ENTRY(glDeleteFramebuffers);
+ FUNCTION_TABLE_ENTRY(glDeleteProgram);
+ FUNCTION_TABLE_ENTRY(glDeleteRenderbuffers);
+ FUNCTION_TABLE_ENTRY(glDeleteShader);
+ FUNCTION_TABLE_ENTRY(glDetachShader);
+ FUNCTION_TABLE_ENTRY(glDisableVertexAttribArray);
+ FUNCTION_TABLE_ENTRY(glEnableVertexAttribArray);
+ FUNCTION_TABLE_ENTRY(glFramebufferRenderbuffer);
+ FUNCTION_TABLE_ENTRY(glFramebufferTexture2D);
+ FUNCTION_TABLE_ENTRY(glGenBuffers);
+ FUNCTION_TABLE_ENTRY(glGenerateMipmap);
+ FUNCTION_TABLE_ENTRY(glGenFramebuffers);
+ FUNCTION_TABLE_ENTRY(glGenRenderbuffers);
+ FUNCTION_TABLE_ENTRY(glGetActiveAttrib);
+ FUNCTION_TABLE_ENTRY(glGetActiveUniform);
+ FUNCTION_TABLE_ENTRY(glGetAttachedShaders);
+ FUNCTION_TABLE_ENTRY(glGetAttribLocation);
+ FUNCTION_TABLE_ENTRY(glGetBufferParameteriv);
+ FUNCTION_TABLE_ENTRY(glGetFramebufferAttachmentParameteriv);
+ FUNCTION_TABLE_ENTRY(glGetProgramInfoLog);
+ FUNCTION_TABLE_ENTRY(glGetProgramiv);
+ FUNCTION_TABLE_ENTRY(glGetRenderbufferParameteriv);
+ FUNCTION_TABLE_ENTRY(glGetShaderInfoLog);
+ FUNCTION_TABLE_ENTRY(glGetShaderiv);
+ FUNCTION_TABLE_ENTRY(glGetShaderSource);
+ FUNCTION_TABLE_ENTRY(glGetUniformfv);
+ FUNCTION_TABLE_ENTRY(glGetUniformiv);
+ FUNCTION_TABLE_ENTRY(glGetUniformLocation);
+ FUNCTION_TABLE_ENTRY(glGetVertexAttribfv);
+ FUNCTION_TABLE_ENTRY(glGetVertexAttribiv);
+ FUNCTION_TABLE_ENTRY(glGetVertexAttribPointerv);
+ FUNCTION_TABLE_ENTRY(glIsBuffer);
+ FUNCTION_TABLE_ENTRY(glIsFramebuffer);
+ FUNCTION_TABLE_ENTRY(glIsProgram);
+ FUNCTION_TABLE_ENTRY(glIsRenderbuffer);
+ FUNCTION_TABLE_ENTRY(glIsShader);
+ FUNCTION_TABLE_ENTRY(glLinkProgram);
+ FUNCTION_TABLE_ENTRY(glRenderbufferStorage);
+ FUNCTION_TABLE_ENTRY(glRenderbufferStorageMultisample);
+ FUNCTION_TABLE_ENTRY(glSampleCoverage);
+ FUNCTION_TABLE_ENTRY(glShaderSource);
+ FUNCTION_TABLE_ENTRY(glStencilFuncSeparate);
+ FUNCTION_TABLE_ENTRY(glStencilMaskSeparate);
+ FUNCTION_TABLE_ENTRY(glStencilOpSeparate);
+ FUNCTION_TABLE_ENTRY(glUniform1f);
+ FUNCTION_TABLE_ENTRY(glUniform1fv);
+ FUNCTION_TABLE_ENTRY(glUniform1i);
+ FUNCTION_TABLE_ENTRY(glUniform1iv);
+ FUNCTION_TABLE_ENTRY(glUniform2f);
+ FUNCTION_TABLE_ENTRY(glUniform2fv);
+ FUNCTION_TABLE_ENTRY(glUniform2i);
+ FUNCTION_TABLE_ENTRY(glUniform2iv);
+ FUNCTION_TABLE_ENTRY(glUniform3f);
+ FUNCTION_TABLE_ENTRY(glUniform3fv);
+ FUNCTION_TABLE_ENTRY(glUniform3i);
+ FUNCTION_TABLE_ENTRY(glUniform3iv);
+ FUNCTION_TABLE_ENTRY(glUniform4f);
+ FUNCTION_TABLE_ENTRY(glUniform4fv);
+ FUNCTION_TABLE_ENTRY(glUniform4i);
+ FUNCTION_TABLE_ENTRY(glUniform4iv);
+ FUNCTION_TABLE_ENTRY(glUniformMatrix2fv);
+ FUNCTION_TABLE_ENTRY(glUniformMatrix3fv);
+ FUNCTION_TABLE_ENTRY(glUniformMatrix4fv);
+ FUNCTION_TABLE_ENTRY(glUseProgram);
+ FUNCTION_TABLE_ENTRY(glValidateProgram);
+ FUNCTION_TABLE_ENTRY(glVertexAttrib1f);
+ FUNCTION_TABLE_ENTRY(glVertexAttrib1fv);
+ FUNCTION_TABLE_ENTRY(glVertexAttrib2f);
+ FUNCTION_TABLE_ENTRY(glVertexAttrib2fv);
+ FUNCTION_TABLE_ENTRY(glVertexAttrib3f);
+ FUNCTION_TABLE_ENTRY(glVertexAttrib3fv);
+ FUNCTION_TABLE_ENTRY(glVertexAttrib4f);
+ FUNCTION_TABLE_ENTRY(glVertexAttrib4fv);
+ FUNCTION_TABLE_ENTRY(glVertexAttribPointer);
+} OpenGLFunctionTable;
+
+// We disable the shims for OpenGLShims.cpp, so that we can set them.
+#ifndef DISABLE_SHIMS
+#define LOOKUP_GL_FUNCTION(Function) WebCore::openGLFunctionTable()->Function
+#define glActiveTexture LOOKUP_GL_FUNCTION(glActiveTexture)
+#define glAttachShader LOOKUP_GL_FUNCTION(glAttachShader)
+#define glBindAttribLocation LOOKUP_GL_FUNCTION(glBindAttribLocation)
+#define glBindBuffer LOOKUP_GL_FUNCTION(glBindBuffer)
+#define glBindFramebufferEXT LOOKUP_GL_FUNCTION(glBindFramebuffer)
+#define glBindRenderbufferEXT LOOKUP_GL_FUNCTION(glBindRenderbuffer)
+#define glBlendColor LOOKUP_GL_FUNCTION(glBlendColor)
+#define glBlendEquation LOOKUP_GL_FUNCTION(glBlendEquation)
+#define glBlendEquationSeparate LOOKUP_GL_FUNCTION(glBlendEquationSeparate)
+#define glBlendFuncSeparate LOOKUP_GL_FUNCTION(glBlendFuncSeparate)
+#define glBlitFramebufferEXT LOOKUP_GL_FUNCTION(glBlitFramebuffer)
+#define glBufferData LOOKUP_GL_FUNCTION(glBufferData)
+#define glBufferSubData LOOKUP_GL_FUNCTION(glBufferSubData)
+#define glCheckFramebufferStatusEXT LOOKUP_GL_FUNCTION(glCheckFramebufferStatus)
+#define glCompileShader LOOKUP_GL_FUNCTION(glCompileShader)
+#define glCreateProgram LOOKUP_GL_FUNCTION(glCreateProgram)
+#define glCreateShader LOOKUP_GL_FUNCTION(glCreateShader)
+#define glDeleteBuffers LOOKUP_GL_FUNCTION(glDeleteBuffers)
+#define glDeleteFramebuffersEXT LOOKUP_GL_FUNCTION(glDeleteFramebuffers)
+#define glDeleteProgram LOOKUP_GL_FUNCTION(glDeleteProgram)
+#define glDeleteRenderbuffersEXT LOOKUP_GL_FUNCTION(glDeleteRenderbuffers)
+#define glDeleteShader LOOKUP_GL_FUNCTION(glDeleteShader)
+#define glDetachShader LOOKUP_GL_FUNCTION(glDetachShader)
+#define glDisableVertexAttribArray LOOKUP_GL_FUNCTION(glDisableVertexAttribArray)
+#define glEnableVertexAttribArray LOOKUP_GL_FUNCTION(glEnableVertexAttribArray)
+#define glFramebufferRenderbufferEXT LOOKUP_GL_FUNCTION(glFramebufferRenderbuffer)
+#define glFramebufferTexture2DEXT LOOKUP_GL_FUNCTION(glFramebufferTexture2D)
+#define glGenBuffers LOOKUP_GL_FUNCTION(glGenBuffers)
+#define glGenerateMipmapEXT LOOKUP_GL_FUNCTION(glGenerateMipmap)
+#define glGenFramebuffersEXT LOOKUP_GL_FUNCTION(glGenFramebuffers)
+#define glGenRenderbuffersEXT LOOKUP_GL_FUNCTION(glGenRenderbuffers)
+#define glGetActiveAttrib LOOKUP_GL_FUNCTION(glGetActiveAttrib)
+#define glGetActiveUniform LOOKUP_GL_FUNCTION(glGetActiveUniform)
+#define glGetAttachedShaders LOOKUP_GL_FUNCTION(glGetAttachedShaders)
+#define glGetAttribLocation LOOKUP_GL_FUNCTION(glGetAttribLocation)
+#define glGetBufferParameteriv LOOKUP_GL_FUNCTION(glGetBufferParameteriv)
+#define glGetBufferParameterivEXT LOOKUP_GL_FUNCTION(glGetBufferParameteriv)
+#define glGetFramebufferAttachmentParameterivEXT LOOKUP_GL_FUNCTION(glGetFramebufferAttachmentParameteriv)
+#define glGetProgramInfoLog LOOKUP_GL_FUNCTION(glGetProgramInfoLog)
+#define glGetProgramiv LOOKUP_GL_FUNCTION(glGetProgramiv)
+#define glGetRenderbufferParameterivEXT LOOKUP_GL_FUNCTION(glGetRenderbufferParameteriv)
+#define glGetShaderInfoLog LOOKUP_GL_FUNCTION(glGetShaderInfoLog)
+#define glGetShaderiv LOOKUP_GL_FUNCTION(glGetShaderiv)
+#define glGetShaderSource LOOKUP_GL_FUNCTION(glGetShaderSource)
+#define glGetUniformfv LOOKUP_GL_FUNCTION(glGetUniformfv)
+#define glGetUniformiv LOOKUP_GL_FUNCTION(glGetUniformiv)
+#define glGetUniformLocation LOOKUP_GL_FUNCTION(glGetUniformLocation)
+#define glGetVertexAttribfv LOOKUP_GL_FUNCTION(glGetVertexAttribfv)
+#define glGetVertexAttribiv LOOKUP_GL_FUNCTION(glGetVertexAttribiv)
+#define glGetVertexAttribPointerv LOOKUP_GL_FUNCTION(glGetVertexAttribPointerv)
+#define glIsBuffer LOOKUP_GL_FUNCTION(glIsBuffer)
+#define glIsFramebufferEXT LOOKUP_GL_FUNCTION(glIsFramebuffer)
+#define glIsProgram LOOKUP_GL_FUNCTION(glIsProgram)
+#define glIsRenderbufferEXT LOOKUP_GL_FUNCTION(glIsRenderbuffer)
+#define glIsShader LOOKUP_GL_FUNCTION(glIsShader)
+#define glLinkProgram LOOKUP_GL_FUNCTION(glLinkProgram)
+#define glRenderbufferStorageEXT LOOKUP_GL_FUNCTION(glRenderbufferStorage)
+#define glRenderbufferStorageMultisampleEXT LOOKUP_GL_FUNCTION(glRenderbufferStorageMultisample)
+#define glSampleCoverage LOOKUP_GL_FUNCTION(glSampleCoverage)
+#define glShaderSource LOOKUP_GL_FUNCTION(glShaderSource)
+#define glStencilFuncSeparate LOOKUP_GL_FUNCTION(glStencilFuncSeparate)
+#define glStencilMaskSeparate LOOKUP_GL_FUNCTION(glStencilMaskSeparate)
+#define glStencilOpSeparate LOOKUP_GL_FUNCTION(glStencilOpSeparate)
+#define glUniform1f LOOKUP_GL_FUNCTION(glUniform1f)
+#define glUniform1fv LOOKUP_GL_FUNCTION(glUniform1fv)
+#define glUniform1i LOOKUP_GL_FUNCTION(glUniform1i)
+#define glUniform1iv LOOKUP_GL_FUNCTION(glUniform1iv)
+#define glUniform2f LOOKUP_GL_FUNCTION(glUniform2f)
+#define glUniform2fv LOOKUP_GL_FUNCTION(glUniform2fv)
+#define glUniform2i LOOKUP_GL_FUNCTION(glUniform2i)
+#define glUniform2iv LOOKUP_GL_FUNCTION(glUniform2iv)
+#define glUniform3f LOOKUP_GL_FUNCTION(glUniform3f)
+#define glUniform3fv LOOKUP_GL_FUNCTION(glUniform3fv)
+#define glUniform3i LOOKUP_GL_FUNCTION(glUniform3i)
+#define glUniform3iv LOOKUP_GL_FUNCTION(glUniform3iv)
+#define glUniform4f LOOKUP_GL_FUNCTION(glUniform4f)
+#define glUniform4fv LOOKUP_GL_FUNCTION(glUniform4fv)
+#define glUniform4i LOOKUP_GL_FUNCTION(glUniform4i)
+#define glUniform4iv LOOKUP_GL_FUNCTION(glUniform4iv)
+#define glUniformMatrix2fv LOOKUP_GL_FUNCTION(glUniformMatrix2fv)
+#define glUniformMatrix3fv LOOKUP_GL_FUNCTION(glUniformMatrix3fv)
+#define glUniformMatrix4fv LOOKUP_GL_FUNCTION(glUniformMatrix4fv)
+#define glUseProgram LOOKUP_GL_FUNCTION(glUseProgram)
+#define glValidateProgram LOOKUP_GL_FUNCTION(glValidateProgram)
+#define glVertexAttrib1f LOOKUP_GL_FUNCTION(glVertexAttrib1f)
+#define glVertexAttrib1fv LOOKUP_GL_FUNCTION(glVertexAttrib1fv)
+#define glVertexAttrib2f LOOKUP_GL_FUNCTION(glVertexAttrib2f)
+#define glVertexAttrib2fv LOOKUP_GL_FUNCTION(glVertexAttrib2fv)
+#define glVertexAttrib3f LOOKUP_GL_FUNCTION(glVertexAttrib3f)
+#define glVertexAttrib3fv LOOKUP_GL_FUNCTION(glVertexAttrib3fv)
+#define glVertexAttrib4f LOOKUP_GL_FUNCTION(glVertexAttrib4f)
+#define glVertexAttrib4fv LOOKUP_GL_FUNCTION(glVertexAttrib4fv)
+#define glVertexAttribPointer LOOKUP_GL_FUNCTION(glVertexAttribPointer)
+#endif
diff --git a/Source/WebCore/platform/graphics/cairo/PathCairo.cpp b/Source/WebCore/platform/graphics/cairo/PathCairo.cpp
index 533df10..d62c33f 100644
--- a/Source/WebCore/platform/graphics/cairo/PathCairo.cpp
+++ b/Source/WebCore/platform/graphics/cairo/PathCairo.cpp
@@ -27,10 +27,10 @@
#include "Path.h"
#include "AffineTransform.h"
-#include "CairoPath.h"
#include "FloatRect.h"
#include "GraphicsContext.h"
#include "OwnPtrCairo.h"
+#include "PlatformPathCairo.h"
#include "PlatformString.h"
#include "StrokeStyleApplier.h"
#include <cairo.h>
diff --git a/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp b/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp
index ba75162..061ee06 100644
--- a/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp
+++ b/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp
@@ -35,4 +35,51 @@ PlatformContextCairo::PlatformContextCairo(cairo_t* cr)
{
}
+void PlatformContextCairo::restore()
+{
+ const ImageMaskInformation& maskInformation = m_maskImageStack.last();
+ if (maskInformation.isValid()) {
+ const FloatRect& maskRect = maskInformation.maskRect();
+ cairo_pop_group_to_source(m_cr.get());
+ cairo_mask_surface(m_cr.get(), maskInformation.maskSurface(), maskRect.x(), maskRect.y());
+ }
+ m_maskImageStack.removeLast();
+
+ cairo_restore(m_cr.get());
+}
+
+void PlatformContextCairo::save()
+{
+ m_maskImageStack.append(ImageMaskInformation());
+
+ cairo_save(m_cr.get());
+}
+
+void PlatformContextCairo::pushImageMask(cairo_surface_t* surface, const FloatRect& rect)
+{
+ // We must call savePlatformState at least once before we can use image masking,
+ // since we actually apply the mask in restorePlatformState.
+ ASSERT(!m_maskImageStack.isEmpty());
+ m_maskImageStack.last().update(surface, rect);
+
+ // Cairo doesn't support the notion of an image clip, so we push a group here
+ // and then paint it to the surface with an image mask (which is an immediate
+ // operation) during restorePlatformState.
+
+ // We want to allow the clipped elements to composite with the surface as it
+ // is now, but they are isolated in another group. To make this work, we're
+ // going to blit the current surface contents onto the new group once we push it.
+ cairo_surface_t* currentTarget = cairo_get_target(m_cr.get());
+ cairo_surface_flush(currentTarget);
+
+ // Pushing a new group ensures that only things painted after this point are clipped.
+ cairo_push_group(m_cr.get());
+ cairo_set_operator(m_cr.get(), CAIRO_OPERATOR_SOURCE);
+
+ cairo_set_source_surface(m_cr.get(), currentTarget, 0, 0);
+ cairo_rectangle(m_cr.get(), rect.x(), rect.y(), rect.width(), rect.height());
+ cairo_fill(m_cr.get());
+}
+
+
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.h b/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.h
index c6cceda..937417a 100644
--- a/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.h
+++ b/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.h
@@ -31,6 +31,25 @@
namespace WebCore {
+// In Cairo image masking is immediate, so to emulate image clipping we must save masking
+// details as part of the context state and apply them during platform restore.
+class ImageMaskInformation {
+public:
+ void update(cairo_surface_t* maskSurface, const FloatRect& maskRect)
+ {
+ m_maskSurface = maskSurface;
+ m_maskRect = maskRect;
+ }
+
+ bool isValid() const { return m_maskSurface; }
+ cairo_surface_t* maskSurface() const { return m_maskSurface.get(); }
+ const FloatRect& maskRect() const { return m_maskRect; }
+
+private:
+ RefPtr<cairo_surface_t> m_maskSurface;
+ FloatRect m_maskRect;
+};
+
// Much like PlatformContextSkia in the Skia port, this class holds information that
// would normally be private to GraphicsContext, except that we want to allow access
// to it in Font and Image code. This allows us to separate the concerns of Cairo-specific
@@ -40,11 +59,17 @@ class PlatformContextCairo {
WTF_MAKE_NONCOPYABLE(PlatformContextCairo);
public:
PlatformContextCairo(cairo_t*);
+
cairo_t* cr() { return m_cr.get(); }
void setCr(cairo_t* cr) { m_cr = cr; }
+ void save();
+ void restore();
+ void pushImageMask(cairo_surface_t*, const FloatRect&);
+
private:
RefPtr<cairo_t> m_cr;
+ Vector<ImageMaskInformation> m_maskImageStack;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/cairo/PlatformPathCairo.cpp b/Source/WebCore/platform/graphics/cairo/PlatformPathCairo.cpp
new file mode 100644
index 0000000..3a7d512
--- /dev/null
+++ b/Source/WebCore/platform/graphics/cairo/PlatformPathCairo.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "PlatformPathCairo.h"
+
+#include <cairo.h>
+
+namespace WebCore {
+
+static cairo_surface_t* getPathSurface()
+{
+ return cairo_image_surface_create(CAIRO_FORMAT_A8, 1, 1);
+}
+
+static cairo_surface_t* gPathSurface = getPathSurface();
+
+CairoPath::CairoPath()
+ : m_cr(adoptRef(cairo_create(gPathSurface)))
+{
+}
+
+}
diff --git a/Source/WebCore/platform/graphics/cairo/PlatformPathCairo.h b/Source/WebCore/platform/graphics/cairo/PlatformPathCairo.h
new file mode 100644
index 0000000..938b942
--- /dev/null
+++ b/Source/WebCore/platform/graphics/cairo/PlatformPathCairo.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2007 Alp Toker <alp.toker@collabora.co.uk>
+ * Copyright (C) 2010 Igalia S.L.
+ *
+ * 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 PlatformPathCairo_h
+#define PlatformPathCairo_h
+
+#include "RefPtrCairo.h"
+
+namespace WebCore {
+
+// This is necessary since cairo_path_fixed_t isn't exposed in Cairo's public API.
+class CairoPath {
+public:
+ CairoPath();
+
+ ~CairoPath() {}
+
+ cairo_t* context() { return m_cr.get(); }
+
+private:
+ RefPtr<cairo_t> m_cr;
+};
+
+} // namespace WebCore
+
+#endif // PlatformPathCairo_h
diff --git a/Source/WebCore/platform/graphics/cairo/RefPtrCairo.cpp b/Source/WebCore/platform/graphics/cairo/RefPtrCairo.cpp
index 1792002..90bc3b1 100644
--- a/Source/WebCore/platform/graphics/cairo/RefPtrCairo.cpp
+++ b/Source/WebCore/platform/graphics/cairo/RefPtrCairo.cpp
@@ -61,7 +61,7 @@ template<> void refIfNotNull(cairo_font_face_t* ptr)
template<> void derefIfNotNull(cairo_font_face_t* ptr)
{
if (LIKELY(ptr != 0))
- cairo_font_face_reference(ptr);
+ cairo_font_face_destroy(ptr);
}
template<> void refIfNotNull(cairo_scaled_font_t* ptr)
diff --git a/Source/WebCore/platform/graphics/cg/ColorCG.cpp b/Source/WebCore/platform/graphics/cg/ColorCG.cpp
index c9b05da..55a3017 100644
--- a/Source/WebCore/platform/graphics/cg/ColorCG.cpp
+++ b/Source/WebCore/platform/graphics/cg/ColorCG.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#include "Color.h"
-#if PLATFORM(CG)
+#if USE(CG)
#include "GraphicsContextCG.h"
#include <wtf/Assertions.h>
@@ -146,4 +146,4 @@ CGColorRef cachedCGColor(const Color& color, ColorSpace colorSpace)
}
-#endif // PLATFORM(CG)
+#endif // USE(CG)
diff --git a/Source/WebCore/platform/graphics/cg/FloatPointCG.cpp b/Source/WebCore/platform/graphics/cg/FloatPointCG.cpp
index f9c3353..5e7aab3 100644
--- a/Source/WebCore/platform/graphics/cg/FloatPointCG.cpp
+++ b/Source/WebCore/platform/graphics/cg/FloatPointCG.cpp
@@ -27,7 +27,7 @@
#include "config.h"
#include "FloatPoint.h"
-#if PLATFORM(CG)
+#if USE(CG) || USE(SKIA_ON_MAC_CHROME)
#include <ApplicationServices/ApplicationServices.h>
@@ -44,4 +44,4 @@ FloatPoint::operator CGPoint() const
}
-#endif // PLATFORM(CG)
+#endif // USE(CG)
diff --git a/Source/WebCore/platform/graphics/cg/FloatRectCG.cpp b/Source/WebCore/platform/graphics/cg/FloatRectCG.cpp
index a1ce367..131b7ac 100644
--- a/Source/WebCore/platform/graphics/cg/FloatRectCG.cpp
+++ b/Source/WebCore/platform/graphics/cg/FloatRectCG.cpp
@@ -27,7 +27,7 @@
#include "config.h"
#include "FloatRect.h"
-#if PLATFORM(CG)
+#if USE(CG) || USE(SKIA_ON_MAC_CHROME)
#include <ApplicationServices/ApplicationServices.h>
@@ -44,4 +44,4 @@ FloatRect::operator CGRect() const
}
-#endif // PLATFORM(CG)
+#endif // USE(CG)
diff --git a/Source/WebCore/platform/graphics/cg/FloatSizeCG.cpp b/Source/WebCore/platform/graphics/cg/FloatSizeCG.cpp
index 383af21..a035c7a 100644
--- a/Source/WebCore/platform/graphics/cg/FloatSizeCG.cpp
+++ b/Source/WebCore/platform/graphics/cg/FloatSizeCG.cpp
@@ -27,7 +27,7 @@
#include "config.h"
#include "FloatSize.h"
-#if PLATFORM(CG)
+#if USE(CG) || USE(SKIA_ON_MAC_CHROME)
#include <ApplicationServices/ApplicationServices.h>
@@ -44,4 +44,4 @@ FloatSize::operator CGSize() const
}
-#endif // PLATFORM(CG)
+#endif // USE(CG)
diff --git a/Source/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp b/Source/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp
index 187d296..57abe71 100644
--- a/Source/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp
+++ b/Source/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp
@@ -29,8 +29,9 @@
#if ENABLE(WEBGL)
#include "GraphicsContext3D.h"
-#include "GraphicsContextCG.h"
+#include "BitmapImage.h"
+#include "GraphicsContextCG.h"
#include "Image.h"
#include <CoreGraphics/CGBitmapContext.h>
@@ -99,7 +100,8 @@ bool GraphicsContext3D::getImageData(Image* image,
return false;
CGImageRef cgImage;
RetainPtr<CGImageRef> decodedImage;
- if (image->data()) {
+ bool hasAlpha = image->isBitmapImage() ? static_cast<BitmapImage*>(image)->frameHasAlphaAtIndex(0) : true;
+ if ((ignoreGammaAndColorProfile || (hasAlpha && !premultiplyAlpha)) && image->data()) {
ImageSource decoder(ImageSource::AlphaNotPremultiplied,
ignoreGammaAndColorProfile ? ImageSource::GammaAndColorProfileIgnored : ImageSource::GammaAndColorProfileApplied);
decoder.setData(image->data(), true);
@@ -196,11 +198,6 @@ bool GraphicsContext3D::getImageData(Image* image,
AlphaFormat alphaFormat = AlphaFormatNone;
switch (CGImageGetAlphaInfo(cgImage)) {
case kCGImageAlphaPremultipliedFirst:
- // This is a special case for texImage2D with HTMLCanvasElement input,
- // 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;
@@ -216,9 +213,6 @@ bool GraphicsContext3D::getImageData(Image* image,
alphaFormat = AlphaFormatFirst;
break;
case kCGImageAlphaPremultipliedLast:
- // This is a special case for texImage2D with HTMLCanvasElement input,
- // in which case image->data() should be null.
- ASSERT(!image->data());
if (!premultiplyAlpha)
neededAlphaOp = AlphaDoUnmultiply;
alphaFormat = AlphaFormatLast;
diff --git a/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp b/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
index 7799137..c7626b9 100644
--- a/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
+++ b/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
@@ -756,9 +756,6 @@ void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLef
if (oldFillColor != color || oldColorSpace != colorSpace)
setCGFillColor(context, color, colorSpace);
- Path path;
- path.addRoundedRect(rect, topLeft, topRight, bottomLeft, bottomRight);
-
bool drawOwnShadow = !isAcceleratedContext() && 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;
@@ -771,7 +768,15 @@ void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLef
contextShadow.drawRectShadow(this, rect, RoundedIntRect::Radii(topLeft, topRight, bottomLeft, bottomRight));
}
- fillPath(path);
+ bool equalWidths = (topLeft.width() == topRight.width() && topRight.width() == bottomLeft.width() && bottomLeft.width() == bottomRight.width());
+ bool equalHeights = (topLeft.height() == bottomLeft.height() && bottomLeft.height() == topRight.height() && topRight.height() == bottomRight.height());
+ if (equalWidths && equalHeights && topLeft.width() * 2 == rect.width() && topLeft.height() * 2 == rect.height())
+ CGContextFillEllipseInRect(context, rect);
+ else {
+ Path path;
+ path.addRoundedRect(rect, topLeft, topRight, bottomLeft, bottomRight);
+ fillPath(path);
+ }
if (drawOwnShadow)
CGContextRestoreGState(context);
@@ -791,7 +796,7 @@ void GraphicsContext::fillRectWithRoundedHole(const IntRect& rect, const Rounded
path.addRect(rect);
if (!roundedHoleRect.radii().isZero())
- path.addRoundedRect(roundedHoleRect.rect(), roundedHoleRect.radii().topLeft(), roundedHoleRect.radii().topRight(), roundedHoleRect.radii().bottomLeft(), roundedHoleRect.radii().bottomRight());
+ path.addRoundedRect(roundedHoleRect);
else
path.addRect(roundedHoleRect.rect());
@@ -1167,8 +1172,11 @@ AffineTransform GraphicsContext::getCTM() const
return AffineTransform(t.a, t.b, t.c, t.d, t.tx, t.ty);
}
-FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect)
+FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect, RoundingMode roundingMode)
{
+#if PLATFORM(CHROMIUM)
+ return rect;
+#else
// It is not enough just to round to pixels in device space. The rotation part of the
// affine transform matrix to device space can mess with this conversion if we have a
// rotating image like the hands of the world clock widget. We just need the scale, so
@@ -1192,8 +1200,13 @@ FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect)
deviceOrigin.x = roundf(deviceOrigin.x);
deviceOrigin.y = roundf(deviceOrigin.y);
- deviceLowerRight.x = roundf(deviceLowerRight.x);
- deviceLowerRight.y = roundf(deviceLowerRight.y);
+ if (roundingMode == RoundAllSides) {
+ deviceLowerRight.x = roundf(deviceLowerRight.x);
+ deviceLowerRight.y = roundf(deviceLowerRight.y);
+ } else {
+ deviceLowerRight.x = deviceOrigin.x + roundf(rect.width() * deviceScaleX);
+ deviceLowerRight.y = deviceOrigin.y + roundf(rect.height() * deviceScaleY);
+ }
// Don't let the height or width round to 0 unless either was originally 0
if (deviceOrigin.y == deviceLowerRight.y && rect.height())
@@ -1204,6 +1217,7 @@ FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect)
FloatPoint roundedOrigin = FloatPoint(deviceOrigin.x / deviceScaleX, deviceOrigin.y / deviceScaleY);
FloatPoint roundedLowerRight = FloatPoint(deviceLowerRight.x / deviceScaleX, deviceLowerRight.y / deviceScaleY);
return FloatRect(roundedOrigin, roundedLowerRight - roundedOrigin);
+#endif
}
void GraphicsContext::drawLineForText(const FloatPoint& point, float width, bool printing)
@@ -1232,7 +1246,7 @@ void GraphicsContext::drawLineForText(const FloatPoint& point, float width, bool
// We try to round all parameters to integer boundaries in device space. If rounding pixels in device space
// makes our thickness more than double, then there must be a shrinking-scale factor and rounding to pixels
// in device space will make the underlines too thick.
- CGRect lineRect = roundToDevicePixels(FloatRect(x, y, lineLength, adjustedThickness));
+ CGRect lineRect = roundToDevicePixels(FloatRect(x, y, lineLength, adjustedThickness), RoundOriginAndDimensions);
if (lineRect.size.height < thickness * 2.0) {
x = lineRect.origin.x;
y = lineRect.origin.y;
diff --git a/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp b/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp
index 3c8f959..95ce8c1 100644
--- a/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp
+++ b/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp
@@ -42,10 +42,6 @@
#include <wtf/Threading.h>
#include <math.h>
-#if USE(IOSURFACE_CANVAS_BACKING_STORE)
-#include <IOSurface/IOSurface.h>
-#endif
-
#if PLATFORM(MAC) || PLATFORM(CHROMIUM)
#include "WebCoreSystemInterface.h"
#endif
@@ -56,6 +52,7 @@ namespace WebCore {
#if USE(IOSURFACE_CANVAS_BACKING_STORE)
static const int maxIOSurfaceDimension = 4096;
+static const int minIOSurfaceArea = 50 * 100;
static RetainPtr<IOSurfaceRef> createIOSurface(const IntSize& size)
{
@@ -100,14 +97,6 @@ static void releaseImageData(void*, const void* data, size_t)
fastFree(const_cast<void*>(data));
}
-ImageBufferData::ImageBufferData(const IntSize&)
- : m_data(0)
-#if USE(IOSURFACE_CANVAS_BACKING_STORE)
- , m_surface(0)
-#endif
-{
-}
-
ImageBuffer::ImageBuffer(const IntSize& size, ColorSpace imageColorSpace, RenderingMode renderingMode, bool& success)
: m_data(size)
, m_size(size)
@@ -117,7 +106,7 @@ ImageBuffer::ImageBuffer(const IntSize& size, ColorSpace imageColorSpace, Render
if (size.width() < 0 || size.height() < 0)
return;
#if USE(IOSURFACE_CANVAS_BACKING_STORE)
- if (size.width() >= maxIOSurfaceDimension || size.height() >= maxIOSurfaceDimension)
+ if (size.width() >= maxIOSurfaceDimension || size.height() >= maxIOSurfaceDimension || size.width() * size.height() < minIOSurfaceArea)
m_accelerateRendering = false;
#else
ASSERT(renderingMode == Unaccelerated);
@@ -262,208 +251,32 @@ void ImageBuffer::clip(GraphicsContext* contextToClip, const FloatRect& rect) co
CGContextTranslateCTM(platformContextToClip, -rect.x(), -rect.y() - rect.height());
}
-template <Multiply multiplied>
-PassRefPtr<ByteArray> getImageData(const IntRect& rect, const ImageBufferData& imageData, const IntSize& size, bool accelerateRendering)
-{
- RefPtr<ByteArray> result = ByteArray::create(rect.width() * rect.height() * 4);
- unsigned char* data = result->data();
-
- if (rect.x() < 0 || rect.y() < 0 || rect.maxX() > size.width() || rect.maxY() > size.height())
- memset(data, 0, result->length());
-
- int originx = rect.x();
- int destx = 0;
- if (originx < 0) {
- destx = -originx;
- originx = 0;
- }
- int endx = rect.maxX();
- if (endx > size.width())
- endx = size.width();
- int numColumns = endx - originx;
-
- int originy = rect.y();
- int desty = 0;
- if (originy < 0) {
- desty = -originy;
- originy = 0;
- }
- int endy = rect.maxY();
- if (endy > size.height())
- endy = size.height();
- int numRows = endy - originy;
-
- unsigned destBytesPerRow = 4 * rect.width();
- unsigned char* destRows = data + desty * destBytesPerRow + destx * 4;
-
- unsigned srcBytesPerRow;
- unsigned char* srcRows;
-
- if (!accelerateRendering) {
- srcBytesPerRow = 4 * size.width();
- srcRows = reinterpret_cast<unsigned char*>(imageData.m_data) + originy * srcBytesPerRow + originx * 4;
-
- for (int y = 0; y < numRows; ++y) {
- for (int x = 0; x < numColumns; x++) {
- int basex = x * 4;
- unsigned char alpha = srcRows[basex + 3];
- if (multiplied == Unmultiplied && alpha) {
- destRows[basex] = (srcRows[basex] * 255) / alpha;
- destRows[basex + 1] = (srcRows[basex + 1] * 255) / alpha;
- destRows[basex + 2] = (srcRows[basex + 2] * 255) / alpha;
- destRows[basex + 3] = alpha;
- } else
- reinterpret_cast<uint32_t*>(destRows + basex)[0] = reinterpret_cast<uint32_t*>(srcRows + basex)[0];
- }
- srcRows += srcBytesPerRow;
- destRows += destBytesPerRow;
- }
- } else {
-#if USE(IOSURFACE_CANVAS_BACKING_STORE)
- IOSurfaceRef surface = imageData.m_surface.get();
- IOSurfaceLock(surface, kIOSurfaceLockReadOnly, 0);
- srcBytesPerRow = IOSurfaceGetBytesPerRow(surface);
- srcRows = (unsigned char*)(IOSurfaceGetBaseAddress(surface)) + originy * srcBytesPerRow + originx * 4;
-
- for (int y = 0; y < numRows; ++y) {
- for (int x = 0; x < numColumns; x++) {
- int basex = x * 4;
- unsigned char alpha = srcRows[basex + 3];
- if (multiplied == Unmultiplied && alpha) {
- destRows[basex] = (srcRows[basex + 2] * 255) / alpha;
- destRows[basex + 1] = (srcRows[basex + 1] * 255) / alpha;
- destRows[basex + 2] = (srcRows[basex] * 255) / alpha;
- destRows[basex + 3] = alpha;
- } else {
- destRows[basex] = srcRows[basex + 2];
- destRows[basex + 1] = srcRows[basex + 1];
- destRows[basex + 2] = srcRows[basex];
- destRows[basex + 3] = alpha;
- }
- }
- srcRows += srcBytesPerRow;
- destRows += destBytesPerRow;
- }
- IOSurfaceUnlock(surface, kIOSurfaceLockReadOnly, 0);
-#else
- ASSERT_NOT_REACHED();
-#endif
- }
-
- return result.release();
-}
-
PassRefPtr<ByteArray> ImageBuffer::getUnmultipliedImageData(const IntRect& rect) const
{
if (m_accelerateRendering)
CGContextFlush(context()->platformContext());
- return getImageData<Unmultiplied>(rect, m_data, m_size, m_accelerateRendering);
+ return m_data.getData(rect, m_size, m_accelerateRendering, true);
}
PassRefPtr<ByteArray> ImageBuffer::getPremultipliedImageData(const IntRect& rect) const
{
if (m_accelerateRendering)
CGContextFlush(context()->platformContext());
- return getImageData<Premultiplied>(rect, m_data, m_size, m_accelerateRendering);
-}
-
-template <Multiply multiplied>
-void putImageData(ByteArray*& source, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint, ImageBufferData& imageData, const IntSize& size, bool accelerateRendering)
-{
- ASSERT(sourceRect.width() > 0);
- ASSERT(sourceRect.height() > 0);
-
- int originx = sourceRect.x();
- int destx = destPoint.x() + sourceRect.x();
- ASSERT(destx >= 0);
- ASSERT(destx < size.width());
- ASSERT(originx >= 0);
- ASSERT(originx <= sourceRect.maxX());
-
- int endx = destPoint.x() + sourceRect.maxX();
- ASSERT(endx <= size.width());
-
- int numColumns = endx - destx;
-
- int originy = sourceRect.y();
- int desty = destPoint.y() + sourceRect.y();
- ASSERT(desty >= 0);
- ASSERT(desty < size.height());
- ASSERT(originy >= 0);
- ASSERT(originy <= sourceRect.maxY());
-
- int endy = destPoint.y() + sourceRect.maxY();
- ASSERT(endy <= size.height());
- int numRows = endy - desty;
-
- unsigned srcBytesPerRow = 4 * sourceSize.width();
- unsigned char* srcRows = source->data() + originy * srcBytesPerRow + originx * 4;
- unsigned destBytesPerRow;
- unsigned char* destRows;
-
- if (!accelerateRendering) {
- destBytesPerRow = 4 * size.width();
- destRows = reinterpret_cast<unsigned char*>(imageData.m_data) + desty * destBytesPerRow + destx * 4;
- for (int y = 0; y < numRows; ++y) {
- for (int x = 0; x < numColumns; x++) {
- int basex = x * 4;
- unsigned char alpha = srcRows[basex + 3];
- if (multiplied == Unmultiplied && alpha != 255) {
- destRows[basex] = (srcRows[basex] * alpha + 254) / 255;
- destRows[basex + 1] = (srcRows[basex + 1] * alpha + 254) / 255;
- destRows[basex + 2] = (srcRows[basex + 2] * alpha + 254) / 255;
- destRows[basex + 3] = alpha;
- } else
- reinterpret_cast<uint32_t*>(destRows + basex)[0] = reinterpret_cast<uint32_t*>(srcRows + basex)[0];
- }
- destRows += destBytesPerRow;
- srcRows += srcBytesPerRow;
- }
- } else {
-#if USE(IOSURFACE_CANVAS_BACKING_STORE)
- IOSurfaceRef surface = imageData.m_surface.get();
- IOSurfaceLock(surface, 0, 0);
- destBytesPerRow = IOSurfaceGetBytesPerRow(surface);
- destRows = (unsigned char*)(IOSurfaceGetBaseAddress(surface)) + desty * destBytesPerRow + destx * 4;
-
- for (int y = 0; y < numRows; ++y) {
- for (int x = 0; x < numColumns; x++) {
- int basex = x * 4;
- unsigned char alpha = srcRows[basex + 3];
- if (multiplied == Unmultiplied && alpha != 255) {
- destRows[basex] = (srcRows[basex + 2] * alpha + 254) / 255;
- destRows[basex + 1] = (srcRows[basex + 1] * alpha + 254) / 255;
- destRows[basex + 2] = (srcRows[basex] * alpha + 254) / 255;
- destRows[basex + 3] = alpha;
- } else {
- destRows[basex] = srcRows[basex + 2];
- destRows[basex + 1] = srcRows[basex + 1];
- destRows[basex + 2] = srcRows[basex];
- destRows[basex + 3] = alpha;
- }
- }
- destRows += destBytesPerRow;
- srcRows += srcBytesPerRow;
- }
- IOSurfaceUnlock(surface, 0, 0);
-#else
- ASSERT_NOT_REACHED();
-#endif
- }
+ return m_data.getData(rect, m_size, m_accelerateRendering, false);
}
void ImageBuffer::putUnmultipliedImageData(ByteArray* source, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint)
{
if (m_accelerateRendering)
CGContextFlush(context()->platformContext());
- putImageData<Unmultiplied>(source, sourceSize, sourceRect, destPoint, m_data, m_size, m_accelerateRendering);
+ m_data.putData(source, sourceSize, sourceRect, destPoint, m_size, m_accelerateRendering, true);
}
void ImageBuffer::putPremultipliedImageData(ByteArray* source, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint)
{
if (m_accelerateRendering)
CGContextFlush(context()->platformContext());
- putImageData<Premultiplied>(source, sourceSize, sourceRect, destPoint, m_data, m_size, m_accelerateRendering);
+ m_data.putData(source, sourceSize, sourceRect, destPoint, m_size, m_accelerateRendering, false);
}
static inline CFStringRef jpegUTI()
diff --git a/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.cpp b/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.cpp
new file mode 100644
index 0000000..f067b66
--- /dev/null
+++ b/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.cpp
@@ -0,0 +1,387 @@
+/*
+ * 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.
+ */
+
+#include "config.h"
+#include "ImageBufferData.h"
+
+#include <wtf/Assertions.h>
+
+#if USE(ACCELERATE)
+#include <Accelerate/Accelerate.h>
+#endif
+
+#if USE(IOSURFACE_CANVAS_BACKING_STORE)
+#include <IOSurface/IOSurface.h>
+#include <dispatch/dispatch.h>
+#endif
+
+#if USE(ACCELERATE)
+struct ScanlineData {
+ vImagePixelCount scanlineWidth;
+ unsigned char* srcData;
+ size_t srcRowBytes;
+ unsigned char* destData;
+ size_t destRowBytes;
+};
+#endif
+
+namespace WebCore {
+
+ImageBufferData::ImageBufferData(const IntSize&)
+: m_data(0)
+#if USE(IOSURFACE_CANVAS_BACKING_STORE)
+, m_surface(0)
+#endif
+{
+}
+
+#if USE(ACCELERATE)
+// The vImage unpremultiply routine had a rounding bug before 10.6.7 <rdar://problem/8631548>
+static bool haveVImageRoundingErrorFix()
+{
+ SInt32 version;
+ static bool result = (Gestalt(gestaltSystemVersion, &version) == noErr && version > 0x1066);
+ return result;
+}
+
+#if USE(IOSURFACE_CANVAS_BACKING_STORE)
+static void convertScanline(void* data, size_t tileNumber, bool premultiply)
+{
+ ScanlineData* scanlineData = static_cast<ScanlineData*>(data);
+
+ vImage_Buffer src;
+ src.data = scanlineData->srcData + tileNumber * scanlineData->srcRowBytes;
+ src.height = 1;
+ src.width = scanlineData->scanlineWidth;
+ src.rowBytes = scanlineData->srcRowBytes;
+
+ vImage_Buffer dest;
+ dest.data = scanlineData->destData + tileNumber * scanlineData->destRowBytes;
+ dest.height = 1;
+ dest.width = scanlineData->scanlineWidth;
+ dest.rowBytes = scanlineData->destRowBytes;
+
+ if (premultiply) {
+ if (kvImageNoError != vImagePremultiplyData_RGBA8888(&src, &dest, kvImageDoNotTile))
+ return;
+ } else {
+ if (kvImageNoError != vImageUnpremultiplyData_RGBA8888(&src, &dest, kvImageDoNotTile))
+ return;
+ }
+
+ // Swap channels 1 and 3, to convert BGRA<->RGBA. IOSurfaces is BGRA, ImageData expects RGBA.
+ const uint8_t map[4] = { 2, 1, 0, 3 };
+ vImagePermuteChannels_ARGB8888(&dest, &dest, map, kvImageDoNotTile);
+}
+
+static void unpremultitplyScanline(void* data, size_t tileNumber)
+{
+ convertScanline(data, tileNumber, false);
+}
+
+static void premultitplyScanline(void* data, size_t tileNumber)
+{
+ convertScanline(data, tileNumber, true);
+}
+#endif // USE(IOSURFACE_CANVAS_BACKING_STORE)
+#endif // USE(ACCELERATE)
+
+PassRefPtr<ByteArray> ImageBufferData::getData(const IntRect& rect, const IntSize& size, bool accelerateRendering, bool unmultiplied) const
+{
+ RefPtr<ByteArray> result = ByteArray::create(rect.width() * rect.height() * 4);
+ unsigned char* data = result->data();
+
+ if (rect.x() < 0 || rect.y() < 0 || rect.maxX() > size.width() || rect.maxY() > size.height())
+ memset(data, 0, result->length());
+
+ int originx = rect.x();
+ int destx = 0;
+ if (originx < 0) {
+ destx = -originx;
+ originx = 0;
+ }
+ int endx = rect.maxX();
+ if (endx > size.width())
+ endx = size.width();
+ int width = endx - originx;
+
+ int originy = rect.y();
+ int desty = 0;
+ if (originy < 0) {
+ desty = -originy;
+ originy = 0;
+ }
+ int endy = rect.maxY();
+ if (endy > size.height())
+ endy = size.height();
+ int height = endy - originy;
+
+ if (width <= 0 || height <= 0)
+ return result.release();
+
+ unsigned destBytesPerRow = 4 * rect.width();
+ unsigned char* destRows = data + desty * destBytesPerRow + destx * 4;
+
+ unsigned srcBytesPerRow;
+ unsigned char* srcRows;
+
+ if (!accelerateRendering) {
+ srcBytesPerRow = 4 * size.width();
+ srcRows = reinterpret_cast<unsigned char*>(m_data) + originy * srcBytesPerRow + originx * 4;
+
+#if USE(ACCELERATE)
+ if (unmultiplied && haveVImageRoundingErrorFix()) {
+ vImage_Buffer src;
+ src.height = height;
+ src.width = width;
+ src.rowBytes = srcBytesPerRow;
+ src.data = srcRows;
+
+ vImage_Buffer dst;
+ dst.height = height;
+ dst.width = width;
+ dst.rowBytes = destBytesPerRow;
+ dst.data = destRows;
+
+ vImageUnpremultiplyData_RGBA8888(&src, &dst, kvImageNoFlags);
+ return result.release();
+ }
+#endif
+ for (int y = 0; y < height; ++y) {
+ for (int x = 0; x < width; x++) {
+ int basex = x * 4;
+ unsigned char alpha = srcRows[basex + 3];
+ if (unmultiplied && alpha) {
+ destRows[basex] = (srcRows[basex] * 255) / alpha;
+ destRows[basex + 1] = (srcRows[basex + 1] * 255) / alpha;
+ destRows[basex + 2] = (srcRows[basex + 2] * 255) / alpha;
+ destRows[basex + 3] = alpha;
+ } else
+ reinterpret_cast<uint32_t*>(destRows + basex)[0] = reinterpret_cast<uint32_t*>(srcRows + basex)[0];
+ }
+ srcRows += srcBytesPerRow;
+ destRows += destBytesPerRow;
+ }
+ } else {
+#if USE(IOSURFACE_CANVAS_BACKING_STORE)
+ IOSurfaceRef surface = m_surface.get();
+ IOSurfaceLock(surface, kIOSurfaceLockReadOnly, 0);
+ srcBytesPerRow = IOSurfaceGetBytesPerRow(surface);
+ srcRows = (unsigned char*)(IOSurfaceGetBaseAddress(surface)) + originy * srcBytesPerRow + originx * 4;
+
+#if USE(ACCELERATE)
+ if (unmultiplied) {
+ ScanlineData scanlineData;
+ scanlineData.scanlineWidth = width;
+ scanlineData.srcData = srcRows;
+ scanlineData.srcRowBytes = srcBytesPerRow;
+ scanlineData.destData = destRows;
+ scanlineData.destRowBytes = destBytesPerRow;
+
+ dispatch_apply_f(height, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), &scanlineData, unpremultitplyScanline);
+ } else {
+ vImage_Buffer src;
+ src.height = height;
+ src.width = width;
+ src.rowBytes = srcBytesPerRow;
+ src.data = srcRows;
+
+ vImage_Buffer dest;
+ dest.height = height;
+ dest.width = width;
+ dest.rowBytes = destBytesPerRow;
+ dest.data = destRows;
+
+ // Swap pixel channels from BGRA to RGBA.
+ const uint8_t map[4] = { 2, 1, 0, 3 };
+ vImagePermuteChannels_ARGB8888(&src, &dest, map, kvImageNoFlags);
+ }
+#else
+ for (int y = 0; y < height; ++y) {
+ for (int x = 0; x < width; x++) {
+ int basex = x * 4;
+ unsigned char alpha = srcRows[basex + 3];
+ if (unmultiplied && alpha) {
+ destRows[basex] = (srcRows[basex + 2] * 255) / alpha;
+ destRows[basex + 1] = (srcRows[basex + 1] * 255) / alpha;
+ destRows[basex + 2] = (srcRows[basex] * 255) / alpha;
+ destRows[basex + 3] = alpha;
+ } else {
+ destRows[basex] = srcRows[basex + 2];
+ destRows[basex + 1] = srcRows[basex + 1];
+ destRows[basex + 2] = srcRows[basex];
+ destRows[basex + 3] = alpha;
+ }
+ }
+ srcRows += srcBytesPerRow;
+ destRows += destBytesPerRow;
+ }
+#endif // USE(ACCELERATE)
+ IOSurfaceUnlock(surface, kIOSurfaceLockReadOnly, 0);
+#else
+ ASSERT_NOT_REACHED();
+#endif // USE(IOSURFACE_CANVAS_BACKING_STORE)
+ }
+
+ return result.release();
+}
+
+void ImageBufferData::putData(ByteArray*& source, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint, const IntSize& size, bool accelerateRendering, bool unmultiplied)
+{
+ ASSERT(sourceRect.width() > 0);
+ ASSERT(sourceRect.height() > 0);
+
+ int originx = sourceRect.x();
+ int destx = destPoint.x() + sourceRect.x();
+ ASSERT(destx >= 0);
+ ASSERT(destx < size.width());
+ ASSERT(originx >= 0);
+ ASSERT(originx <= sourceRect.maxX());
+
+ int endx = destPoint.x() + sourceRect.maxX();
+ ASSERT(endx <= size.width());
+
+ int width = endx - destx;
+
+ int originy = sourceRect.y();
+ int desty = destPoint.y() + sourceRect.y();
+ ASSERT(desty >= 0);
+ ASSERT(desty < size.height());
+ ASSERT(originy >= 0);
+ ASSERT(originy <= sourceRect.maxY());
+
+ int endy = destPoint.y() + sourceRect.maxY();
+ ASSERT(endy <= size.height());
+ int height = endy - desty;
+
+ if (width <= 0 || height <= 0)
+ return;
+
+ unsigned srcBytesPerRow = 4 * sourceSize.width();
+ unsigned char* srcRows = source->data() + originy * srcBytesPerRow + originx * 4;
+ unsigned destBytesPerRow;
+ unsigned char* destRows;
+
+ if (!accelerateRendering) {
+ destBytesPerRow = 4 * size.width();
+ destRows = reinterpret_cast<unsigned char*>(m_data) + desty * destBytesPerRow + destx * 4;
+
+#if USE(ACCELERATE)
+ if (haveVImageRoundingErrorFix() && unmultiplied) {
+ vImage_Buffer src;
+ src.height = height;
+ src.width = width;
+ src.rowBytes = srcBytesPerRow;
+ src.data = srcRows;
+
+ vImage_Buffer dst;
+ dst.height = height;
+ dst.width = width;
+ dst.rowBytes = destBytesPerRow;
+ dst.data = destRows;
+
+ vImagePremultiplyData_RGBA8888(&src, &dst, kvImageNoFlags);
+ return;
+ }
+#endif
+ for (int y = 0; y < height; ++y) {
+ for (int x = 0; x < width; x++) {
+ int basex = x * 4;
+ unsigned char alpha = srcRows[basex + 3];
+ if (unmultiplied && alpha != 255) {
+ destRows[basex] = (srcRows[basex] * alpha + 254) / 255;
+ destRows[basex + 1] = (srcRows[basex + 1] * alpha + 254) / 255;
+ destRows[basex + 2] = (srcRows[basex + 2] * alpha + 254) / 255;
+ destRows[basex + 3] = alpha;
+ } else
+ reinterpret_cast<uint32_t*>(destRows + basex)[0] = reinterpret_cast<uint32_t*>(srcRows + basex)[0];
+ }
+ destRows += destBytesPerRow;
+ srcRows += srcBytesPerRow;
+ }
+ } else {
+#if USE(IOSURFACE_CANVAS_BACKING_STORE)
+ IOSurfaceRef surface = m_surface.get();
+ IOSurfaceLock(surface, 0, 0);
+ destBytesPerRow = IOSurfaceGetBytesPerRow(surface);
+ destRows = (unsigned char*)(IOSurfaceGetBaseAddress(surface)) + desty * destBytesPerRow + destx * 4;
+
+#if USE(ACCELERATE)
+ if (unmultiplied) {
+ ScanlineData scanlineData;
+ scanlineData.scanlineWidth = width;
+ scanlineData.srcData = srcRows;
+ scanlineData.srcRowBytes = srcBytesPerRow;
+ scanlineData.destData = destRows;
+ scanlineData.destRowBytes = destBytesPerRow;
+
+ dispatch_apply_f(height, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), &scanlineData, premultitplyScanline);
+ } else {
+ vImage_Buffer src;
+ src.height = height;
+ src.width = width;
+ src.rowBytes = srcBytesPerRow;
+ src.data = srcRows;
+
+ vImage_Buffer dest;
+ dest.height = height;
+ dest.width = width;
+ dest.rowBytes = destBytesPerRow;
+ dest.data = destRows;
+
+ // Swap pixel channels from RGBA to BGRA.
+ const uint8_t map[4] = { 2, 1, 0, 3 };
+ vImagePermuteChannels_ARGB8888(&src, &dest, map, kvImageNoFlags);
+ }
+#else
+ for (int y = 0; y < height; ++y) {
+ for (int x = 0; x < width; x++) {
+ int basex = x * 4;
+ unsigned char alpha = srcRows[basex + 3];
+ if (unmultiplied && alpha != 255) {
+ destRows[basex] = (srcRows[basex + 2] * alpha + 254) / 255;
+ destRows[basex + 1] = (srcRows[basex + 1] * alpha + 254) / 255;
+ destRows[basex + 2] = (srcRows[basex] * alpha + 254) / 255;
+ destRows[basex + 3] = alpha;
+ } else {
+ destRows[basex] = srcRows[basex + 2];
+ destRows[basex + 1] = srcRows[basex + 1];
+ destRows[basex + 2] = srcRows[basex];
+ destRows[basex + 3] = alpha;
+ }
+ }
+ destRows += destBytesPerRow;
+ srcRows += srcBytesPerRow;
+ }
+#endif // USE(ACCELERATE)
+
+ IOSurfaceUnlock(surface, 0, 0);
+#else
+ ASSERT_NOT_REACHED();
+#endif // USE(IOSURFACE_CANVAS_BACKING_STORE)
+ }
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/cg/ImageBufferData.h b/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.h
index 1f706ec..54169e6 100644
--- a/Source/WebCore/platform/graphics/cg/ImageBufferData.h
+++ b/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.h
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
* Copyright (C) 2008 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -23,13 +24,15 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ImageBufferData_h
-#define ImageBufferData_h
-
#include "Image.h"
+#include <wtf/ByteArray.h>
#include <wtf/RefPtr.h>
#include <wtf/RetainPtr.h>
+#if (PLATFORM(MAC) && USE(CA) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD))
+#define WTF_USE_IOSURFACE_CANVAS_BACKING_STORE 1
+#endif
+
typedef struct __IOSurface *IOSurfaceRef;
typedef struct CGColorSpace *CGColorSpaceRef;
typedef struct CGDataProvider *CGDataProviderRef;
@@ -50,8 +53,9 @@ public:
unsigned m_bytesPerRow;
CGColorSpaceRef m_colorSpace;
RetainPtr<IOSurfaceRef> m_surface;
-};
-} // namespace WebCore
+ PassRefPtr<ByteArray> getData(const IntRect& rect, const IntSize& size, bool accelerateRendering, bool unmultiplied) const;
+ void putData(ByteArray*& source, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint, const IntSize& size, bool accelerateRendering, bool unmultiplied);
+};
-#endif // ImageBufferData_h
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/cg/ImageCG.cpp b/Source/WebCore/platform/graphics/cg/ImageCG.cpp
index 08f65bd..635a804 100644
--- a/Source/WebCore/platform/graphics/cg/ImageCG.cpp
+++ b/Source/WebCore/platform/graphics/cg/ImageCG.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#include "BitmapImage.h"
-#if PLATFORM(CG)
+#if USE(CG)
#include "AffineTransform.h"
#include "FloatConversion.h"
@@ -154,6 +154,19 @@ CGImageRef BitmapImage::getCGImageRef()
return frameAtIndex(0);
}
+CGImageRef BitmapImage::getFirstCGImageRefOfSize(const IntSize& size)
+{
+ size_t count = frameCount();
+ for (size_t i = 0; i < count; ++i) {
+ CGImageRef cgImage = frameAtIndex(i);
+ if (IntSize(CGImageGetWidth(cgImage), CGImageGetHeight(cgImage)) == size)
+ return cgImage;
+ }
+
+ // Fallback to the default CGImageRef if we can't find the right size
+ return getCGImageRef();
+}
+
void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& destRect, const FloatRect& srcRect, ColorSpace styleColorSpace, CompositeOperator compositeOp)
{
startAnimation();
@@ -186,7 +199,7 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& destRect, const F
// containing only the portion we want to display. We need to do this because high-quality
// interpolation smoothes sharp edges, causing pixels from outside the source rect to bleed
// into the destination rect. See <rdar://problem/6112909>.
- shouldUseSubimage = (interpolationQuality == kCGInterpolationHigh || interpolationQuality == kCGInterpolationDefault) && (srcRect.size() != destRect.size() || !ctxt->getCTM().isIdentityOrTranslationOrFlipped());
+ shouldUseSubimage = (interpolationQuality != kCGInterpolationNone) && (srcRect.size() != destRect.size() || !ctxt->getCTM().isIdentityOrTranslationOrFlipped());
float xScale = srcRect.width() / destRect.width();
float yScale = srcRect.height() / destRect.height();
if (shouldUseSubimage) {
@@ -255,6 +268,11 @@ void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const
// Avoid a hang under CGContextDrawTiledImage on release builds.
return;
+#if !ASSERT_DISABLED
+ if (this->isBitmapImage())
+ ASSERT(static_cast<BitmapImage*>(this)->notSolidColor());
+#endif
+
CGContextRef context = ctxt->platformContext();
ctxt->save();
CGContextClipToRect(context, destRect);
@@ -346,4 +364,4 @@ void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const
}
-#endif // PLATFORM(CG)
+#endif // USE(CG)
diff --git a/Source/WebCore/platform/graphics/cg/ImageSourceCG.cpp b/Source/WebCore/platform/graphics/cg/ImageSourceCG.cpp
index 068ea5b..1a630d4 100644
--- a/Source/WebCore/platform/graphics/cg/ImageSourceCG.cpp
+++ b/Source/WebCore/platform/graphics/cg/ImageSourceCG.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#include "ImageSource.h"
-#if PLATFORM(CG)
+#if USE(CG)
#include "ImageSourceCG.h"
#include "IntPoint.h"
@@ -356,4 +356,4 @@ bool ImageSource::frameHasAlphaAtIndex(size_t)
}
-#endif // PLATFORM(CG)
+#endif // USE(CG)
diff --git a/Source/WebCore/platform/graphics/cg/IntPointCG.cpp b/Source/WebCore/platform/graphics/cg/IntPointCG.cpp
index 95dbe5f..4a1096b 100644
--- a/Source/WebCore/platform/graphics/cg/IntPointCG.cpp
+++ b/Source/WebCore/platform/graphics/cg/IntPointCG.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#include "IntPoint.h"
-#if PLATFORM(CG)
+#if USE(CG) || USE(SKIA_ON_MAC_CHROME)
#include <ApplicationServices/ApplicationServices.h>
@@ -43,4 +43,4 @@ IntPoint::operator CGPoint() const
}
-#endif // PLATFORM(CG)
+#endif // USE(CG)
diff --git a/Source/WebCore/platform/graphics/cg/IntRectCG.cpp b/Source/WebCore/platform/graphics/cg/IntRectCG.cpp
index 73fd63f..18edeb0 100644
--- a/Source/WebCore/platform/graphics/cg/IntRectCG.cpp
+++ b/Source/WebCore/platform/graphics/cg/IntRectCG.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#include "IntRect.h"
-#if PLATFORM(CG)
+#if USE(CG) || USE(SKIA_ON_MAC_CHROME)
#include <ApplicationServices/ApplicationServices.h>
@@ -48,4 +48,4 @@ IntRect enclosingIntRect(const CGRect& rect)
}
-#endif // PLATFORM(CG)
+#endif // USE(CG)
diff --git a/Source/WebCore/platform/graphics/cg/IntSizeCG.cpp b/Source/WebCore/platform/graphics/cg/IntSizeCG.cpp
index d8e8c83..c844cbc 100644
--- a/Source/WebCore/platform/graphics/cg/IntSizeCG.cpp
+++ b/Source/WebCore/platform/graphics/cg/IntSizeCG.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#include "IntSize.h"
-#if PLATFORM(CG)
+#if USE(CG) || USE(SKIA_ON_MAC_CHROME)
#include <ApplicationServices/ApplicationServices.h>
@@ -43,4 +43,4 @@ IntSize::operator CGSize() const
}
-#endif // PLATFORM(CG)
+#endif // USE(CG)
diff --git a/Source/WebCore/platform/graphics/cg/PDFDocumentImage.cpp b/Source/WebCore/platform/graphics/cg/PDFDocumentImage.cpp
index 8bf04f1..a7d465f 100644
--- a/Source/WebCore/platform/graphics/cg/PDFDocumentImage.cpp
+++ b/Source/WebCore/platform/graphics/cg/PDFDocumentImage.cpp
@@ -27,7 +27,7 @@
#include "config.h"
#include "PDFDocumentImage.h"
-#if PLATFORM(CG)
+#if USE(CG)
#include "GraphicsContext.h"
#include "ImageObserver.h"
@@ -188,4 +188,4 @@ void PDFDocumentImage::draw(GraphicsContext* context, const FloatRect& dstRect,
}
-#endif // PLATFORM(CG)
+#endif // USE(CG)
diff --git a/Source/WebCore/platform/graphics/cg/PDFDocumentImage.h b/Source/WebCore/platform/graphics/cg/PDFDocumentImage.h
index ecd57be..c69a222 100644
--- a/Source/WebCore/platform/graphics/cg/PDFDocumentImage.h
+++ b/Source/WebCore/platform/graphics/cg/PDFDocumentImage.h
@@ -31,7 +31,7 @@
#include "FloatRect.h"
#include "GraphicsTypes.h"
-#if PLATFORM(CG)
+#if USE(CG)
#include <ApplicationServices/ApplicationServices.h>
@@ -78,6 +78,6 @@ namespace WebCore {
}
-#endif // PLATFORM(CG)
+#endif // USE(CG)
#endif // PDFDocumentImage_h
diff --git a/Source/WebCore/platform/graphics/cg/PathCG.cpp b/Source/WebCore/platform/graphics/cg/PathCG.cpp
index b8fc7d4..3b9725a 100644
--- a/Source/WebCore/platform/graphics/cg/PathCG.cpp
+++ b/Source/WebCore/platform/graphics/cg/PathCG.cpp
@@ -27,7 +27,7 @@
#include "config.h"
#include "Path.h"
-#if PLATFORM(CG)
+#if USE(CG)
#include "AffineTransform.h"
#include "FloatRect.h"
@@ -309,4 +309,4 @@ void Path::transform(const AffineTransform& transform)
}
-#endif // PLATFORM(CG)
+#endif // USE(CG)
diff --git a/Source/WebCore/platform/graphics/cg/TransformationMatrixCG.cpp b/Source/WebCore/platform/graphics/cg/TransformationMatrixCG.cpp
index ec40836..b49a2ab 100644
--- a/Source/WebCore/platform/graphics/cg/TransformationMatrixCG.cpp
+++ b/Source/WebCore/platform/graphics/cg/TransformationMatrixCG.cpp
@@ -27,7 +27,7 @@
#include "AffineTransform.h"
#include "TransformationMatrix.h"
-#if PLATFORM(CG)
+#if USE(CG)
#include <CoreGraphics/CGAffineTransform.h>
#include "FloatConversion.h"
@@ -66,4 +66,4 @@ AffineTransform::operator CGAffineTransform() const
}
-#endif // PLATFORM(CG)
+#endif // USE(CG)
diff --git a/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp
index 4cb119a..26ad37a 100644
--- a/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp
@@ -36,6 +36,7 @@
#include "DrawingBuffer.h"
#include "GraphicsContext3D.h"
+#include "LayerRendererChromium.h"
namespace WebCore {
@@ -54,6 +55,8 @@ Canvas2DLayerChromium::~Canvas2DLayerChromium()
{
if (m_textureId)
layerRendererContext()->deleteTexture(m_textureId);
+ if (m_drawingBuffer && layerRenderer())
+ layerRenderer()->removeChildContext(m_drawingBuffer->graphicsContext3D().get());
}
void Canvas2DLayerChromium::updateCompositorResources()
@@ -103,8 +106,28 @@ unsigned Canvas2DLayerChromium::textureId() const
void Canvas2DLayerChromium::setDrawingBuffer(DrawingBuffer* drawingBuffer)
{
if (drawingBuffer != m_drawingBuffer) {
+ if (m_drawingBuffer && layerRenderer())
+ layerRenderer()->removeChildContext(m_drawingBuffer->graphicsContext3D().get());
+
m_drawingBuffer = drawingBuffer;
m_textureChanged = true;
+
+ if (drawingBuffer && layerRenderer())
+ layerRenderer()->addChildContext(m_drawingBuffer->graphicsContext3D().get());
+ }
+}
+
+void Canvas2DLayerChromium::setLayerRenderer(LayerRendererChromium* newLayerRenderer)
+{
+ if (layerRenderer() != newLayerRenderer) {
+ if (m_drawingBuffer->graphicsContext3D()) {
+ if (layerRenderer())
+ layerRenderer()->removeChildContext(m_drawingBuffer->graphicsContext3D().get());
+ if (newLayerRenderer)
+ newLayerRenderer->addChildContext(m_drawingBuffer->graphicsContext3D().get());
+ }
+
+ LayerChromium::setLayerRenderer(newLayerRenderer);
}
}
diff --git a/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h b/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h
index 81b118c..4224ab1 100644
--- a/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h
@@ -52,6 +52,8 @@ public:
unsigned textureId() const;
void setDrawingBuffer(DrawingBuffer*);
+ virtual void setLayerRenderer(LayerRendererChromium*);
+
private:
explicit Canvas2DLayerChromium(DrawingBuffer*, GraphicsLayerChromium* owner);
DrawingBuffer* m_drawingBuffer;
diff --git a/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp
index 4ea9c92..aff2981 100644
--- a/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp
@@ -41,6 +41,14 @@
#include "RenderLayerBacking.h"
#include "TextStream.h"
+// Maximum size the width or height of this layer can be before enabling tiling
+// when m_tilingOption == AutoTile.
+static int maxUntiledSize = 512;
+// When tiling is enabled, use tiles of this dimension squared.
+static int defaultTileSize = 256;
+
+using namespace std;
+
namespace WebCore {
PassRefPtr<ContentLayerChromium> ContentLayerChromium::create(GraphicsLayerChromium* owner)
@@ -50,240 +58,171 @@ PassRefPtr<ContentLayerChromium> ContentLayerChromium::create(GraphicsLayerChrom
ContentLayerChromium::ContentLayerChromium(GraphicsLayerChromium* owner)
: LayerChromium(owner)
- , m_contentsTexture(0)
- , m_skipsDraw(false)
+ , m_tilingOption(ContentLayerChromium::AutoTile)
{
}
ContentLayerChromium::~ContentLayerChromium()
{
- cleanupResources();
-}
-
-void ContentLayerChromium::cleanupResources()
-{
+ m_tiler.clear();
LayerChromium::cleanupResources();
- m_contentsTexture.clear();
}
-bool ContentLayerChromium::requiresClippedUpdateRect()
-{
- // To avoid allocating excessively large textures, switch into "large layer mode" if
- // one of the layer's dimensions is larger than 2000 pixels or the size of
- // surface it's rendering into. This is a temporary measure until layer tiling is implemented.
- static const int maxLayerSize = 2000;
- return (bounds().width() > max(maxLayerSize, ccLayerImpl()->targetRenderSurface()->contentRect().width())
- || bounds().height() > max(maxLayerSize, ccLayerImpl()->targetRenderSurface()->contentRect().height())
- || !layerRenderer()->checkTextureSize(bounds()));
-}
+class ContentLayerPainter : public TilePaintInterface {
+public:
+ explicit ContentLayerPainter(GraphicsLayerChromium* owner)
+ : m_owner(owner)
+ {
+ }
-void ContentLayerChromium::paintContentsIfDirty()
-{
- RenderLayerBacking* backing = static_cast<RenderLayerBacking*>(m_owner->client());
- if (!backing || backing->paintingGoesToWindow())
- return;
+ virtual void paint(GraphicsContext& context, const IntRect& contentRect)
+ {
+ context.save();
+ context.clearRect(contentRect);
+ context.clip(contentRect);
+ m_owner->paintGraphicsLayerContents(context, contentRect);
+ context.restore();
+ }
+private:
+ GraphicsLayerChromium* m_owner;
+};
+void ContentLayerChromium::paintContentsIfDirty(const IntRect& targetSurfaceRect)
+{
ASSERT(drawsContent());
-
ASSERT(layerRenderer());
- IntRect dirtyRect;
- IntRect boundsRect(IntPoint(0, 0), bounds());
- IntPoint paintingOffset;
-
- // FIXME: Remove this test when tiled layers are implemented.
- if (requiresClippedUpdateRect()) {
- // Calculate the region of this layer that is currently visible.
- const IntRect clipRect = ccLayerImpl()->targetRenderSurface()->contentRect();
-
- TransformationMatrix layerOriginTransform = ccLayerImpl()->drawTransform();
- layerOriginTransform.translate3d(-0.5 * bounds().width(), -0.5 * bounds().height(), 0);
-
- // We compute the visible portion of the layer by back-mapping the current RenderSurface
- // content area to the layer. To do that, we invert the drawing matrix of the layer
- // and project the content area rectangle to it. If the layer transform is not invertible
- // then we skip rendering the layer.
- if (!layerOriginTransform.isInvertible()) {
- m_skipsDraw = true;
- return;
- }
- TransformationMatrix targetToLayerMatrix = layerOriginTransform.inverse();
- FloatQuad mappedClipToLayer = targetToLayerMatrix.projectQuad(FloatRect(clipRect));
- IntRect visibleRectInLayerCoords = mappedClipToLayer.enclosingBoundingBox();
- visibleRectInLayerCoords.intersect(IntRect(0, 0, bounds().width(), bounds().height()));
-
- // If this is still too large to render, then skip the layer completely.
- if (!layerRenderer()->checkTextureSize(visibleRectInLayerCoords.size())) {
- m_skipsDraw = true;
- return;
- }
-
- // If we need to resize the upload buffer we have to repaint everything.
- if (m_canvas.size() != visibleRectInLayerCoords.size()) {
- resizeUploadBuffer(visibleRectInLayerCoords.size());
- m_dirtyRect = boundsRect;
- }
- // If the visible portion of the layer is different from the last upload.
- if (visibleRectInLayerCoords != m_visibleRectInLayerCoords)
- m_dirtyRect = boundsRect;
- m_visibleRectInLayerCoords = visibleRectInLayerCoords;
-
- // Calculate the portion of the dirty rectangle that is visible. m_dirtyRect is in layer space.
- IntRect visibleDirtyRectInLayerSpace = enclosingIntRect(m_dirtyRect);
- visibleDirtyRectInLayerSpace.intersect(visibleRectInLayerCoords);
-
- // What the rectangles mean:
- // dirtyRect: The region of this layer that will be updated.
- // m_uploadUpdateRect: The region of the layer's texture that will be uploaded into.
- dirtyRect = visibleDirtyRectInLayerSpace;
- m_uploadUpdateRect = dirtyRect;
- IntSize visibleRectOffsetInLayerCoords(visibleRectInLayerCoords.x(), visibleRectInLayerCoords.y());
- paintingOffset = IntPoint(visibleRectOffsetInLayerCoords);
- m_uploadUpdateRect.move(-visibleRectOffsetInLayerCoords);
- } else {
- dirtyRect = IntRect(m_dirtyRect);
- // If the texture needs to be reallocated then we must redraw the entire
- // contents of the layer.
- if (m_canvas.size() != bounds()) {
- resizeUploadBuffer(bounds());
- dirtyRect = boundsRect;
- } else {
- // Clip the dirtyRect to the size of the layer to avoid drawing
- // outside the bounds of the backing texture.
- dirtyRect.intersect(boundsRect);
- }
- m_uploadUpdateRect = dirtyRect;
- }
+ createTilerIfNeeded();
- if (dirtyRect.isEmpty())
- return;
+ ContentLayerPainter painter(m_owner);
+ updateLayerSize(layerBounds().size());
- PlatformCanvas::Painter painter(&m_canvas);
- painter.context()->save();
- painter.context()->translate(-paintingOffset.x(), -paintingOffset.y());
- painter.context()->clearRect(dirtyRect);
- painter.context()->clip(dirtyRect);
+ IntRect layerRect = visibleLayerRect(targetSurfaceRect);
+ if (layerRect.isEmpty())
+ return;
+ m_tiler->invalidateRect(enclosingIntRect(m_dirtyRect));
+ m_tiler->update(painter, layerRect);
+ m_dirtyRect = FloatRect();
+}
- m_owner->paintGraphicsLayerContents(*painter.context(), dirtyRect);
- painter.context()->restore();
+void ContentLayerChromium::setLayerRenderer(LayerRendererChromium* layerRenderer)
+{
+ LayerChromium::setLayerRenderer(layerRenderer);
+ createTilerIfNeeded();
+ m_tiler->setLayerRenderer(layerRenderer);
}
-void ContentLayerChromium::resizeUploadBuffer(const IntSize& size)
+TransformationMatrix ContentLayerChromium::tilingTransform()
{
- m_canvas.resize(size);
+ TransformationMatrix transform = ccLayerImpl()->drawTransform();
+ // Tiler draws from the upper left corner. The draw transform
+ // specifies the middle of the layer.
+ IntSize size = bounds();
+ transform.translate(-size.width() / 2.0, -size.height() / 2.0);
+
+ return transform;
}
-void ContentLayerChromium::updateTextureIfNeeded()
+IntRect ContentLayerChromium::visibleLayerRect(const IntRect& targetSurfaceRect)
+{
+ if (targetSurfaceRect.isEmpty())
+ return targetSurfaceRect;
+
+ const IntRect layerBoundRect = layerBounds();
+ const TransformationMatrix transform = tilingTransform();
+
+ // Is this layer fully contained within the target surface?
+ IntRect layerInSurfaceSpace = transform.mapRect(layerBoundRect);
+ if (targetSurfaceRect.contains(layerInSurfaceSpace))
+ return layerBoundRect;
+
+ // If the layer doesn't fill up the entire surface, then find the part of
+ // the surface rect where the layer could be visible. This avoids trying to
+ // project surface rect points that are behind the projection point.
+ IntRect minimalSurfaceRect = targetSurfaceRect;
+ minimalSurfaceRect.intersect(layerInSurfaceSpace);
+
+ // Project the corners of the target surface rect into the layer space.
+ // This bounding rectangle may be larger than it needs to be (being
+ // axis-aligned), but is a reasonable filter on the space to consider.
+ // Non-invertible transforms will create an empty rect here.
+ const TransformationMatrix surfaceToLayer = transform.inverse();
+ IntRect layerRect = surfaceToLayer.projectQuad(FloatQuad(FloatRect(minimalSurfaceRect))).enclosingBoundingBox();
+ layerRect.intersect(layerBoundRect);
+ return layerRect;
+}
+
+IntRect ContentLayerChromium::layerBounds() const
{
- PlatformCanvas::AutoLocker locker(&m_canvas);
- updateTexture(locker.pixels(), m_canvas.size());
+ return IntRect(IntPoint(0, 0), bounds());
}
-void ContentLayerChromium::updateTexture(const uint8_t* pixels, const IntSize& size)
+void ContentLayerChromium::updateLayerSize(const IntSize& layerSize)
{
- if (!pixels)
+ if (!m_tiler)
return;
- GraphicsContext3D* context = layerRendererContext();
- if (!m_contentsTexture)
- m_contentsTexture = LayerTexture::create(context, layerRenderer()->textureManager());
+ const IntSize tileSize(min(defaultTileSize, layerSize.width()), min(defaultTileSize, layerSize.height()));
+ const bool autoTiled = layerSize.width() > maxUntiledSize || layerSize.height() > maxUntiledSize;
- // If we have to allocate a new texture we have to upload the full contents.
- if (!m_contentsTexture->isValid(size, GraphicsContext3D::RGBA))
- m_uploadUpdateRect = IntRect(IntPoint(0, 0), size);
+ bool isTiled;
+ if (m_tilingOption == AlwaysTile)
+ isTiled = true;
+ else if (m_tilingOption == NeverTile)
+ isTiled = false;
+ else
+ isTiled = autoTiled;
- if (!m_contentsTexture->reserve(size, GraphicsContext3D::RGBA)) {
- m_skipsDraw = true;
- return;
- }
-
- IntRect srcRect = IntRect(IntPoint(0, 0), size);
- if (requiresClippedUpdateRect())
- srcRect = m_visibleRectInLayerCoords;
-
- const size_t destStride = m_uploadUpdateRect.width() * 4;
- const size_t srcStride = srcRect.width() * 4;
-
- const uint8_t* uploadPixels = pixels + srcStride * m_uploadUpdateRect.y();
- Vector<uint8_t> uploadBuffer;
- if (srcStride != destStride || m_uploadUpdateRect.x()) {
- uploadBuffer.resize(m_uploadUpdateRect.height() * destStride);
- for (int row = 0; row < m_uploadUpdateRect.height(); ++row) {
- size_t srcOffset = (m_uploadUpdateRect.y() + row) * srcStride + m_uploadUpdateRect.x() * 4;
- ASSERT(srcOffset + destStride <= static_cast<size_t>(size.width() * size.height() * 4));
- size_t destOffset = row * destStride;
- ASSERT(destOffset + destStride <= uploadBuffer.size());
- memcpy(uploadBuffer.data() + destOffset, pixels + srcOffset, destStride);
- }
- uploadPixels = uploadBuffer.data();
- }
-
- m_contentsTexture->bindTexture();
- GLC(context, context->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0,
- m_uploadUpdateRect.x(), m_uploadUpdateRect.y(), m_uploadUpdateRect.width(), m_uploadUpdateRect.height(),
- GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE,
- uploadPixels));
+ m_tiler->setTileSize(isTiled ? tileSize : layerSize);
+}
- m_uploadUpdateRect = IntRect();
- m_dirtyRect.setSize(FloatSize());
- // Large layers always stay dirty, because they need to update when the content rect changes.
- m_contentsDirty = requiresClippedUpdateRect();
+void ContentLayerChromium::draw(const IntRect& targetSurfaceRect)
+{
+ const TransformationMatrix transform = tilingTransform();
+ IntRect layerRect = visibleLayerRect(targetSurfaceRect);
+ if (!layerRect.isEmpty())
+ m_tiler->draw(layerRect, transform, ccLayerImpl()->drawOpacity());
+ m_tiler->unreserveTextures();
}
-void ContentLayerChromium::draw()
+void ContentLayerChromium::createTilerIfNeeded()
{
- if (m_skipsDraw)
+ if (m_tiler)
return;
+ m_tiler = LayerTilerChromium::create(layerRenderer(), IntSize(defaultTileSize, defaultTileSize), LayerTilerChromium::HasBorderTexels);
+}
- ASSERT(layerRenderer());
+void ContentLayerChromium::updateCompositorResources()
+{
+ m_tiler->uploadCanvas();
+}
- const ContentLayerChromium::Program* program = layerRenderer()->contentLayerProgram();
- ASSERT(program && program->initialized());
- GraphicsContext3D* context = layerRendererContext();
- GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
- bindContentsTexture();
- layerRenderer()->useShader(program->program());
- GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0));
- GLC(context, context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA));
-
- if (requiresClippedUpdateRect()) {
- // Compute the offset between the layer's center point and the center of the visible portion
- // of the layer.
- FloatPoint visibleRectCenterOffset = FloatRect(m_visibleRectInLayerCoords).center();
- visibleRectCenterOffset.move(-0.5 * bounds().width(), -0.5 * bounds().height());
-
- TransformationMatrix transform = ccLayerImpl()->drawTransform();
- transform.translate(visibleRectCenterOffset.x(), visibleRectCenterOffset.y());
-
- drawTexturedQuad(context, layerRenderer()->projectionMatrix(),
- transform, m_visibleRectInLayerCoords.width(),
- m_visibleRectInLayerCoords.height(), ccLayerImpl()->drawOpacity(),
- program->vertexShader().matrixLocation(),
- program->fragmentShader().alphaLocation());
- } else {
- drawTexturedQuad(context, layerRenderer()->projectionMatrix(),
- ccLayerImpl()->drawTransform(), bounds().width(), bounds().height(),
- ccLayerImpl()->drawOpacity(), program->vertexShader().matrixLocation(),
- program->fragmentShader().alphaLocation());
- }
- unreserveContentsTexture();
+void ContentLayerChromium::setTilingOption(TilingOption option)
+{
+ m_tilingOption = option;
+ updateLayerSize(bounds());
}
-void ContentLayerChromium::updateCompositorResources()
+void ContentLayerChromium::bindContentsTexture()
{
- updateTextureIfNeeded();
+ // This function is only valid for single texture layers, e.g. masks.
+ ASSERT(m_tilingOption == NeverTile);
+ ASSERT(m_tiler);
+
+ LayerTexture* texture = m_tiler->getSingleTexture();
+ ASSERT(texture);
+
+ texture->bindTexture();
}
void ContentLayerChromium::unreserveContentsTexture()
{
- if (!m_skipsDraw && m_contentsTexture)
- m_contentsTexture->unreserve();
+ m_tiler->unreserveTextures();
}
-void ContentLayerChromium::bindContentsTexture()
+void ContentLayerChromium::setIsMask(bool isMask)
{
- if (!m_skipsDraw && m_contentsTexture)
- m_contentsTexture->bindTexture();
+ setTilingOption(isMask ? NeverTile : AutoTile);
}
static void writeIndent(TextStream& ts, int indent)
@@ -296,7 +235,7 @@ void ContentLayerChromium::dumpLayerProperties(TextStream& ts, int indent) const
{
LayerChromium::dumpLayerProperties(ts, indent);
writeIndent(ts, indent);
- ts << "skipsDraw: " << m_skipsDraw << "\n";
+ ts << "skipsDraw: " << m_tiler->skipsDraw() << "\n";
}
}
diff --git a/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h b/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h
index cf296ab..c0cf582 100644
--- a/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h
@@ -35,7 +35,7 @@
#if USE(ACCELERATED_COMPOSITING)
#include "LayerChromium.h"
-#include "PlatformCanvas.h"
+#include "LayerTilerChromium.h"
#include "TextureManager.h"
namespace WebCore {
@@ -46,43 +46,43 @@ class LayerTexture;
class ContentLayerChromium : public LayerChromium {
friend class LayerRendererChromium;
public:
+ enum TilingOption { AlwaysTile, NeverTile, AutoTile };
+
static PassRefPtr<ContentLayerChromium> create(GraphicsLayerChromium* owner = 0);
virtual ~ContentLayerChromium();
- virtual void paintContentsIfDirty();
+ virtual void paintContentsIfDirty(const IntRect& targetSurfaceRect);
virtual void updateCompositorResources();
+ virtual void setIsMask(bool);
virtual void unreserveContentsTexture();
virtual void bindContentsTexture();
- virtual void draw();
- virtual bool drawsContent() const { return m_owner && m_owner->drawsContent(); }
-
- typedef ProgramBinding<VertexShaderPosTex, FragmentShaderTexAlpha> Program;
+ virtual void draw(const IntRect& targetSurfaceRect);
+ virtual bool drawsContent() const { return m_owner && m_owner->drawsContent() && (!m_tiler || !m_tiler->skipsDraw()); }
protected:
explicit ContentLayerChromium(GraphicsLayerChromium* owner);
- virtual void cleanupResources();
- bool requiresClippedUpdateRect();
- void resizeUploadBuffer(const IntSize&);
-
virtual const char* layerTypeAsString() const { return "ContentLayer"; }
virtual void dumpLayerProperties(TextStream&, int indent) const;
- OwnPtr<LayerTexture> m_contentsTexture;
- bool m_skipsDraw;
+ virtual void setLayerRenderer(LayerRendererChromium*);
+
+ virtual IntRect layerBounds() const;
- // The portion of the upload buffer that has a pending update, in the coordinates of the texture.
- IntRect m_uploadUpdateRect;
+ virtual TransformationMatrix tilingTransform();
- virtual void updateTextureIfNeeded();
- void updateTexture(const uint8_t* pixels, const IntSize&);
+ // For a given render surface rect that this layer will be transformed and
+ // drawn into, return the layer space rect that is visible in that surface.
+ IntRect visibleLayerRect(const IntRect&);
-private:
- PlatformCanvas m_canvas;
+ void updateLayerSize(const IntSize&);
+ void createTilerIfNeeded();
+ void setTilingOption(TilingOption);
- IntRect m_visibleRectInLayerCoords;
+ OwnPtr<LayerTilerChromium> m_tiler;
+ TilingOption m_tilingOption;
};
}
diff --git a/Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp b/Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp
index e559edb..bad0c6c 100644
--- a/Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp
@@ -76,7 +76,7 @@ DrawingBuffer::DrawingBuffer(GraphicsContext3D* context,
bool multisampleExtensionSupported,
bool packedDepthStencilExtensionSupported)
: m_context(context)
- , m_size(size)
+ , m_size(-1, -1)
, m_multisampleExtensionSupported(multisampleExtensionSupported)
, m_packedDepthStencilExtensionSupported(packedDepthStencilExtensionSupported)
, m_fbo(0)
@@ -173,6 +173,29 @@ void DrawingBuffer::setGrContext(GrContext* context)
// the SharedGraphicsContext3D object that is giving us the context.
m_grContext = context;
}
+
+void DrawingBuffer::getGrPlatformSurfaceDesc(GrPlatformSurfaceDesc* desc)
+{
+ desc->fSurfaceType = kTextureRenderTarget_GrPlatformSurfaceType;
+
+ desc->fPlatformTexture = m_colorBuffer;
+ if (multisample()) {
+ desc->fRenderTargetFlags = kIsMultisampled_GrPlatformRenderTargetFlagBit | kGrCanResolve_GrPlatformRenderTargetFlagBit;
+ desc->fPlatformRenderTarget = m_multisampleFBO;
+ desc->fPlatformResolveDestination = m_fbo;
+ } else {
+ desc->fRenderTargetFlags = kNone_GrPlatformRenderTargetFlagBit;
+ desc->fPlatformRenderTarget = m_fbo;
+ desc->fPlatformResolveDestination = 0;
+ }
+
+ desc->fWidth = m_size.width();
+ desc->fHeight = m_size.height();
+ desc->fConfig = kRGBA_8888_GrPixelConfig;
+
+ desc->fStencilBits = (m_depthStencilBuffer || m_stencilBuffer) ? 8 : 0;
+}
+
#endif
}
diff --git a/Source/WebCore/platform/graphics/chromium/Extensions3DChromium.h b/Source/WebCore/platform/graphics/chromium/Extensions3DChromium.h
index 3b0fdbf..c542351 100644
--- a/Source/WebCore/platform/graphics/chromium/Extensions3DChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/Extensions3DChromium.h
@@ -43,6 +43,7 @@ public:
// Extensions3D methods.
virtual bool supports(const String&);
virtual void ensureEnabled(const String&);
+ virtual bool isEnabled(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);
@@ -66,6 +67,12 @@ public:
// GL_CHROMIUM_copy_texture_to_parent_texture
void copyTextureToParentTextureCHROMIUM(unsigned texture, unsigned parentTexture);
+ // Latch support
+ void getParentToChildLatchCHROMIUM(GC3Duint* latchId);
+ void getChildToParentLatchCHROMIUM(GC3Duint* latchId);
+ void waitLatchCHROMIUM(GC3Duint latchId);
+ void setLatchCHROMIUM(GC3Duint latchId);
+
private:
// Instances of this class are strictly owned by the GraphicsContext3D implementation and do not
// need to be instantiated by any other code.
diff --git a/Source/WebCore/platform/graphics/chromium/FontChromiumWin.cpp b/Source/WebCore/platform/graphics/chromium/FontChromiumWin.cpp
index 3c254dc..ac1e1af 100644
--- a/Source/WebCore/platform/graphics/chromium/FontChromiumWin.cpp
+++ b/Source/WebCore/platform/graphics/chromium/FontChromiumWin.cpp
@@ -43,7 +43,7 @@
#include "TransparencyWin.h"
#include "UniscribeHelperTextRun.h"
-#include "skia/ext/platform_canvas_win.h"
+#include "skia/ext/platform_canvas.h"
#include "skia/ext/skia_utils_win.h" // FIXME: remove this dependency.
#include <windows.h>
@@ -165,7 +165,7 @@ void TransparencyAwareFontPainter::initializeForGDI()
// Set up the DC, using the one from the transparency helper.
if (m_transparency.platformContext()) {
- m_hdc = m_transparency.platformContext()->canvas()->beginPlatformPaint();
+ m_hdc = skia::BeginPlatformPaint(m_transparency.platformContext()->canvas());
SetTextColor(m_hdc, skia::SkColorToCOLORREF(color));
SetBkMode(m_hdc, TRANSPARENT);
}
@@ -179,7 +179,7 @@ TransparencyAwareFontPainter::~TransparencyAwareFontPainter()
if (m_createdTransparencyLayer)
m_graphicsContext->endTransparencyLayer();
m_graphicsContext->restore();
- m_platformContext->canvas()->endPlatformPaint();
+ skia::EndPlatformPaint(m_platformContext->canvas());
}
// Specialization for simple GlyphBuffer painting.
@@ -374,21 +374,14 @@ bool Font::canExpandAroundIdeographsInComplexText()
return false;
}
-void Font::drawGlyphs(GraphicsContext* graphicsContext,
- const SimpleFontData* font,
- const GlyphBuffer& glyphBuffer,
- int from,
- int numGlyphs,
- const FloatPoint& point) const
-{
+static void drawGlyphsWin(GraphicsContext* graphicsContext,
+ const SimpleFontData* font,
+ const GlyphBuffer& glyphBuffer,
+ int from,
+ int numGlyphs,
+ const FloatPoint& point) {
graphicsContext->platformContext()->prepareForSoftwareDraw();
- SkColor color = graphicsContext->platformContext()->effectiveFillColor();
- unsigned char alpha = SkColorGetA(color);
- // Skip 100% transparent text; no need to draw anything.
- if (!alpha && graphicsContext->platformContext()->getStrokeStyle() == NoStroke)
- return;
-
TransparencyAwareGlyphPainter painter(graphicsContext, font, glyphBuffer, from, numGlyphs, point);
// We draw the glyphs in chunks to avoid having to do a heap allocation for
@@ -449,6 +442,39 @@ void Font::drawGlyphs(GraphicsContext* graphicsContext,
}
}
+void Font::drawGlyphs(GraphicsContext* graphicsContext,
+ const SimpleFontData* font,
+ const GlyphBuffer& glyphBuffer,
+ int from,
+ int numGlyphs,
+ const FloatPoint& point) const
+{
+ SkColor color = graphicsContext->platformContext()->effectiveFillColor();
+ unsigned char alpha = SkColorGetA(color);
+ // Skip 100% transparent text; no need to draw anything.
+ if (!alpha && graphicsContext->platformContext()->getStrokeStyle() == NoStroke && !graphicsContext->hasShadow())
+ return;
+ if (!alpha || windowsCanHandleDrawTextShadow(graphicsContext) || !windowsCanHandleTextDrawingWithoutShadow(graphicsContext)) {
+ drawGlyphsWin(graphicsContext, font, glyphBuffer, from, numGlyphs, point);
+ return;
+ }
+ // Draw in two passes: skia for the shadow, GDI for foreground text
+ // pass1: shadow (will use skia)
+ graphicsContext->save();
+ graphicsContext->setFillColor(Color::transparent, graphicsContext->fillColorSpace());
+ drawGlyphsWin(graphicsContext, font, glyphBuffer, from, numGlyphs, point);
+ graphicsContext->restore();
+ // pass2: foreground text (will use GDI)
+ FloatSize shadowOffset;
+ float shadowBlur;
+ Color shadowColor;
+ ColorSpace shadowColorSpace;
+ graphicsContext->getShadow(shadowOffset, shadowBlur, shadowColor, shadowColorSpace);
+ graphicsContext->setShadow(shadowOffset, shadowBlur, Color::transparent, shadowColorSpace);
+ drawGlyphsWin(graphicsContext, font, glyphBuffer, from, numGlyphs, point);
+ graphicsContext->setShadow(shadowOffset, shadowBlur, shadowColor, shadowColorSpace);
+}
+
FloatRect Font::selectionRectForComplexText(const TextRun& run,
const FloatPoint& point,
int h,
@@ -516,7 +542,7 @@ void Font::drawComplexText(GraphicsContext* graphicsContext,
// the baseline, so we have to subtract off the ascent.
state.draw(graphicsContext, hdc, lroundf(point.x()), lroundf(point.y() - fontMetrics().ascent()), from, to);
- context->canvas()->endPlatformPaint();
+ skia::EndPlatformPaint(context->canvas());
}
void Font::drawEmphasisMarksForComplexText(GraphicsContext* /* context */, const TextRun& /* run */, const AtomicString& /* mark */, const FloatPoint& /* point */, int /* from */, int /* to */) const
diff --git a/Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp b/Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp
index c3edfac..1fb5957 100644
--- a/Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp
+++ b/Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp
@@ -122,7 +122,7 @@ int FontPlatformData::emSizeInFontUnits() const
if (m_emSizeInFontUnits)
return m_emSizeInFontUnits;
- SkAdvancedTypefaceMetrics* metrics = m_typeface->getAdvancedTypefaceMetrics(false);
+ SkAdvancedTypefaceMetrics* metrics = m_typeface->getAdvancedTypefaceMetrics(SkAdvancedTypefaceMetrics::kNo_PerGlyphInfo);
m_emSizeInFontUnits = metrics->fEmSize;
metrics->unref();
return m_emSizeInFontUnits;
diff --git a/Source/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp b/Source/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp
index bea0572..a4798dd 100644
--- a/Source/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp
+++ b/Source/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp
@@ -250,17 +250,31 @@ int getAscent(HFONT hfont)
return gotMetrics ? tm.tmAscent : kUndefinedAscent;
}
+WORD getSpaceGlyph(HFONT hfont)
+{
+ HDC dc = GetDC(0);
+ HGDIOBJ oldFont = SelectObject(dc, hfont);
+ WCHAR space = L' ';
+ WORD spaceGlyph = 0;
+ GetGlyphIndices(dc, &space, 1, &spaceGlyph, 0);
+ SelectObject(dc, oldFont);
+ ReleaseDC(0, dc);
+ return spaceGlyph;
+}
+
struct FontData {
FontData()
: hfont(0)
, ascent(kUndefinedAscent)
, scriptCache(0)
+ , spaceGlyph(0)
{
}
HFONT hfont;
int ascent;
mutable SCRIPT_CACHE scriptCache;
+ WORD spaceGlyph;
};
// Again, using hash_map does not earn us much here. page_cycler_test intl2
@@ -379,7 +393,8 @@ bool getDerivedFontData(const UChar* family,
LOGFONT* logfont,
int* ascent,
HFONT* hfont,
- SCRIPT_CACHE** scriptCache)
+ SCRIPT_CACHE** scriptCache,
+ WORD* spaceGlyph)
{
ASSERT(logfont);
ASSERT(family);
@@ -408,6 +423,7 @@ bool getDerivedFontData(const UChar* family,
// cache it so that we won't have to call CreateFontIndirect once
// more for HFONT next time.
derived->ascent = getAscent(derived->hfont);
+ derived->spaceGlyph = getSpaceGlyph(derived->hfont);
} else {
derived = &iter->second;
// Last time, GetAscent failed so that only HFONT was
@@ -419,6 +435,7 @@ bool getDerivedFontData(const UChar* family,
*hfont = derived->hfont;
*ascent = derived->ascent;
*scriptCache = &(derived->scriptCache);
+ *spaceGlyph = derived->spaceGlyph;
return *ascent != kUndefinedAscent;
}
diff --git a/Source/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.h b/Source/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.h
index b637ede..d9de002 100644
--- a/Source/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.h
+++ b/Source/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.h
@@ -78,7 +78,7 @@ const UChar* getFallbackFamily(const UChar* characters, int length,
// intl2 page-cycler test is noticeably slower with one out param than
// the current version although the subsequent 9 passes take about the
// same time.
-bool getDerivedFontData(const UChar* family, int style, LOGFONT*, int* ascent, HFONT*, SCRIPT_CACHE**);
+bool getDerivedFontData(const UChar* family, int style, LOGFONT*, int* ascent, HFONT*, SCRIPT_CACHE**, WORD* spaceGlyph);
enum {
FontStyleNormal = 0,
diff --git a/Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp b/Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp
index cc5a060..87d54b0 100644
--- a/Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp
+++ b/Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp
@@ -38,6 +38,7 @@
#include "GraphicsContext3D.h"
#include "internal_glu.h"
#include "IntRect.h"
+#include "LoopBlinnMathUtils.h"
#include "LoopBlinnPathProcessor.h"
#include "LoopBlinnSolidFillShader.h"
#include "Path.h"
@@ -60,7 +61,7 @@ namespace WebCore {
const int pathTesselation = 30;
typedef void (GLAPIENTRY *TESSCB)();
typedef WTF::Vector<float> FloatVector;
-typedef WTF::Vector<double> DoubleVector;
+typedef WTF::Vector<FloatPoint> FloatPointVector;
struct PathAndTransform {
PathAndTransform(const Path& p, const AffineTransform& t)
@@ -186,7 +187,7 @@ class Cubic {
FloatPoint d = -1.0f * p0 + 3.0f * p1s - 3.0f * p2s + p3s;
return Cubic(p0, b, c, d);
}
- FloatPoint evaluate(float t)
+ inline FloatPoint evaluate(float t)
{
return m_a + t * (m_b + t * (m_c + t * m_d));
}
@@ -198,6 +199,7 @@ GLES2Canvas::GLES2Canvas(SharedGraphicsContext3D* context, DrawingBuffer* drawin
, m_context(context)
, m_drawingBuffer(drawingBuffer)
, m_state(0)
+ , m_pathIndexBuffer(0)
, m_pathVertexBuffer(0)
{
m_flipMatrix.translate(-1.0f, 1.0f);
@@ -209,6 +211,10 @@ GLES2Canvas::GLES2Canvas(SharedGraphicsContext3D* context, DrawingBuffer* drawin
GLES2Canvas::~GLES2Canvas()
{
+ if (m_pathIndexBuffer)
+ m_context->graphicsContext3D()->deleteBuffer(m_pathIndexBuffer);
+ if (m_pathVertexBuffer)
+ m_context->graphicsContext3D()->deleteBuffer(m_pathVertexBuffer);
}
void GLES2Canvas::bindFramebuffer()
@@ -229,6 +235,13 @@ void GLES2Canvas::clearRect(const FloatRect& rect)
}
}
+void GLES2Canvas::applyState()
+{
+ bindFramebuffer();
+ m_context->applyCompositeOperator(m_state->m_compositeOp);
+ applyClipping(m_state->clippingEnabled());
+}
+
void GLES2Canvas::scissorClear(float x, float y, float width, float height)
{
int intX = static_cast<int>(x + 0.5f);
@@ -250,10 +263,7 @@ void GLES2Canvas::fillPath(const Path& path)
endShadowDraw(path.boundingRect());
}
- bindFramebuffer();
- m_context->applyCompositeOperator(m_state->m_compositeOp);
- applyClipping(m_state->clippingEnabled());
-
+ applyState();
fillPathInternal(path, m_state->applyAlpha(m_state->m_fillColor));
}
@@ -265,10 +275,7 @@ void GLES2Canvas::fillRect(const FloatRect& rect, const Color& color, ColorSpace
endShadowDraw(rect);
}
- bindFramebuffer();
- m_context->applyCompositeOperator(m_state->m_compositeOp);
- applyClipping(m_state->clippingEnabled());
-
+ applyState();
fillRectInternal(rect, color);
}
@@ -546,38 +553,30 @@ Texture* GLES2Canvas::getTexture(NativeImagePtr ptr)
#if USE(SKIA)
// This is actually cross-platform code, but since its only caller is inside a
// USE(SKIA), it will cause a warning-as-error on Chrome/Mac.
-static void interpolateQuadratic(DoubleVector* vertices, const FloatPoint& p0, const FloatPoint& p1, const FloatPoint& p2)
+static void interpolateQuadratic(FloatPointVector* vertices, const FloatPoint& p0, const FloatPoint& p1, const FloatPoint& p2)
{
float tIncrement = 1.0f / pathTesselation, t = tIncrement;
Quadratic c = Quadratic::fromBezier(p0, p1, p2);
- for (int i = 0; i < pathTesselation; ++i, t += tIncrement) {
- FloatPoint p = c.evaluate(t);
- vertices->append(p.x());
- vertices->append(p.y());
- vertices->append(1.0);
- }
+ for (int i = 0; i < pathTesselation; ++i, t += tIncrement)
+ vertices->append(c.evaluate(t));
}
-static void interpolateCubic(DoubleVector* vertices, const FloatPoint& p0, const FloatPoint& p1, const FloatPoint& p2, const FloatPoint& p3)
+static void interpolateCubic(FloatPointVector* vertices, const FloatPoint& p0, const FloatPoint& p1, const FloatPoint& p2, const FloatPoint& p3)
{
float tIncrement = 1.0f / pathTesselation, t = tIncrement;
Cubic c = Cubic::fromBezier(p0, p1, p2, p3);
- for (int i = 0; i < pathTesselation; ++i, t += tIncrement) {
- FloatPoint p = c.evaluate(t);
- vertices->append(p.x());
- vertices->append(p.y());
- vertices->append(1.0);
- }
+ for (int i = 0; i < pathTesselation; ++i, t += tIncrement)
+ vertices->append(c.evaluate(t));
}
#endif
struct PolygonData {
- PolygonData(FloatVector* vertices, WTF::Vector<short>* indices)
+ PolygonData(FloatPointVector* vertices, WTF::Vector<short>* indices)
: m_vertices(vertices)
, m_indices(indices)
{
}
- FloatVector* m_vertices;
+ FloatPointVector* m_vertices;
WTF::Vector<short>* m_indices;
};
@@ -603,22 +602,24 @@ static void combineData(GLdouble coords[3], void* vertexData[4],
GLfloat weight[4], void **outData, void* data)
{
PolygonData* polygonData = static_cast<PolygonData*>(data);
- int index = polygonData->m_vertices->size() / 3;
- polygonData->m_vertices->append(static_cast<float>(coords[0]));
- polygonData->m_vertices->append(static_cast<float>(coords[1]));
- polygonData->m_vertices->append(1.0f);
+ int index = polygonData->m_vertices->size();
+ polygonData->m_vertices->append(FloatPoint(static_cast<float>(coords[0]), static_cast<float>(coords[1])));
*outData = reinterpret_cast<void*>(index);
}
typedef void (*TESSCB)();
-void GLES2Canvas::createVertexBufferFromPath(const Path& path, int* count, unsigned* vertexBuffer, unsigned* indexBuffer)
+void GLES2Canvas::tesselateAndFillPath(const Path& path, const Color& color)
{
- *vertexBuffer = m_context->graphicsContext3D()->createBuffer();
- checkGLError("createVertexBufferFromPath, createBuffer");
- *indexBuffer = m_context->graphicsContext3D()->createBuffer();
- checkGLError("createVertexBufferFromPath, createBuffer");
- DoubleVector inVertices;
+ if (!m_pathVertexBuffer)
+ m_pathVertexBuffer = m_context->graphicsContext3D()->createBuffer();
+ if (!m_pathIndexBuffer)
+ m_pathIndexBuffer = m_context->graphicsContext3D()->createBuffer();
+
+ AffineTransform matrix(m_flipMatrix);
+ matrix *= m_state->m_ctm;
+
+ FloatPointVector inVertices;
WTF::Vector<size_t> contours;
#if USE(SKIA)
const SkPath* skPath = path.platformPath();
@@ -628,14 +629,10 @@ void GLES2Canvas::createVertexBufferFromPath(const Path& path, int* count, unsig
while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
switch (verb) {
case SkPath::kMove_Verb:
- inVertices.append(pts[0].fX);
- inVertices.append(pts[0].fY);
- inVertices.append(1.0);
+ inVertices.append(pts[0]);
break;
case SkPath::kLine_Verb:
- inVertices.append(pts[1].fX);
- inVertices.append(pts[1].fY);
- inVertices.append(1.0);
+ inVertices.append(pts[1]);
break;
case SkPath::kQuad_Verb:
interpolateQuadratic(&inVertices, pts[0], pts[1], pts[2]);
@@ -644,7 +641,7 @@ void GLES2Canvas::createVertexBufferFromPath(const Path& path, int* count, unsig
interpolateCubic(&inVertices, pts[0], pts[1], pts[2], pts[3]);
break;
case SkPath::kClose_Verb:
- contours.append(inVertices.size() / 3);
+ contours.append(inVertices.size());
break;
case SkPath::kDone_Verb:
break;
@@ -654,6 +651,21 @@ void GLES2Canvas::createVertexBufferFromPath(const Path& path, int* count, unsig
ASSERT(!"Path extraction not implemented on this platform.");
#endif
+ if (contours.size() == 1 && LoopBlinnMathUtils::isConvex(inVertices.begin(), inVertices.size())) {
+ m_context->graphicsContext3D()->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_pathVertexBuffer);
+ m_context->graphicsContext3D()->bufferData(GraphicsContext3D::ARRAY_BUFFER, inVertices.size() * 2 * sizeof(float), inVertices.data(), GraphicsContext3D::STREAM_DRAW);
+ m_context->useFillSolidProgram(matrix, color);
+ m_context->graphicsContext3D()->drawArrays(GraphicsContext3D::TRIANGLE_FAN, 0, inVertices.size());
+ return;
+ }
+
+ OwnArrayPtr<double> inVerticesDouble = adoptArrayPtr(new double[inVertices.size() * 3]);
+ for (size_t i = 0; i < inVertices.size(); ++i) {
+ inVerticesDouble[i * 3 ] = inVertices[i].x();
+ inVerticesDouble[i * 3 + 1] = inVertices[i].y();
+ inVerticesDouble[i * 3 + 2] = 1.0;
+ }
+
GLUtesselator* tess = internal_gluNewTess();
internal_gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO);
internal_gluTessCallback(tess, GLU_TESS_BEGIN_DATA, (TESSCB) &beginData);
@@ -662,7 +674,7 @@ void GLES2Canvas::createVertexBufferFromPath(const Path& path, int* count, unsig
internal_gluTessCallback(tess, GLU_TESS_EDGE_FLAG_DATA, (TESSCB) &edgeFlagData);
internal_gluTessCallback(tess, GLU_TESS_COMBINE_DATA, (TESSCB) &combineData);
WTF::Vector<short> indices;
- FloatVector vertices;
+ FloatPointVector vertices;
vertices.reserveInitialCapacity(inVertices.size());
PolygonData data(&vertices, &indices);
internal_gluTessBeginPolygon(tess, &data);
@@ -671,26 +683,27 @@ void GLES2Canvas::createVertexBufferFromPath(const Path& path, int* count, unsig
for (contour = contours.begin(); contour != contours.end(); ++contour) {
internal_gluTessBeginContour(tess);
for (; i < *contour; ++i) {
- vertices.append(inVertices[i * 3]);
- vertices.append(inVertices[i * 3 + 1]);
- vertices.append(1.0f);
- internal_gluTessVertex(tess, &inVertices[i * 3], reinterpret_cast<void*>(i));
+ double* inVertex = &inVerticesDouble[i * 3];
+ vertices.append(FloatPoint(inVertex[0], inVertex[1]));
+ internal_gluTessVertex(tess, inVertex, reinterpret_cast<void*>(i));
}
internal_gluTessEndContour(tess);
}
internal_gluTessEndPolygon(tess);
internal_gluDeleteTess(tess);
- m_context->graphicsContext3D()->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, *vertexBuffer);
+ m_context->graphicsContext3D()->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_pathVertexBuffer);
checkGLError("createVertexBufferFromPath, bindBuffer ARRAY_BUFFER");
- m_context->graphicsContext3D()->bufferData(GraphicsContext3D::ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GraphicsContext3D::STREAM_DRAW);
+ m_context->graphicsContext3D()->bufferData(GraphicsContext3D::ARRAY_BUFFER, vertices.size() * 2 * sizeof(float), vertices.data(), GraphicsContext3D::STREAM_DRAW);
checkGLError("createVertexBufferFromPath, bufferData ARRAY_BUFFER");
- m_context->graphicsContext3D()->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, *indexBuffer);
+ m_context->graphicsContext3D()->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, m_pathIndexBuffer);
checkGLError("createVertexBufferFromPath, bindBuffer ELEMENT_ARRAY_BUFFER");
m_context->graphicsContext3D()->bufferData(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(short), indices.data(), GraphicsContext3D::STREAM_DRAW);
checkGLError("createVertexBufferFromPath, bufferData ELEMENT_ARRAY_BUFFER");
- *count = indices.size();
+
+ m_context->useFillSolidProgram(matrix, color);
+ m_context->graphicsContext3D()->drawElements(GraphicsContext3D::TRIANGLES, indices.size(), GraphicsContext3D::UNSIGNED_SHORT, 0);
}
void GLES2Canvas::fillPathInternal(const Path& path, const Color& color)
@@ -723,29 +736,7 @@ void GLES2Canvas::fillPathInternal(const Path& path, const Color& color)
m_context->useLoopBlinnInteriorProgram(byteSizeOfVertices + byteSizeOfTexCoords, matrix, color);
m_context->drawArrays(GraphicsContext3D::TRIANGLES, 0, m_pathCache.numberOfInteriorVertices());
} else {
- int count;
- unsigned vertexBuffer, indexBuffer;
- createVertexBufferFromPath(path, &count, &vertexBuffer, &indexBuffer);
-
- AffineTransform matrix(m_flipMatrix);
- matrix *= m_state->m_ctm;
-
- m_context->graphicsContext3D()->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, vertexBuffer);
- checkGLError("bindBuffer");
- m_context->graphicsContext3D()->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, indexBuffer);
- checkGLError("bindBuffer");
-
- m_context->useFillSolidProgram(matrix, color);
- checkGLError("useFillSolidProgram");
-
- m_context->graphicsContext3D()->drawElements(GraphicsContext3D::TRIANGLES, count, GraphicsContext3D::UNSIGNED_SHORT, 0);
- checkGLError("drawArrays");
-
- m_context->graphicsContext3D()->deleteBuffer(vertexBuffer);
- checkGLError("deleteBuffer");
-
- m_context->graphicsContext3D()->deleteBuffer(indexBuffer);
- checkGLError("deleteBuffer");
+ tesselateAndFillPath(path, color);
}
}
@@ -787,9 +778,7 @@ void GLES2Canvas::beginShadowDraw()
m_context->clearColor(Color(RGBA32(0)));
m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT);
} else {
- bindFramebuffer();
- m_context->applyCompositeOperator(m_state->m_compositeOp);
- applyClipping(m_state->clippingEnabled());
+ applyState();
}
}
@@ -864,19 +853,14 @@ void GLES2Canvas::endShadowDraw(const FloatRect& boundingBox)
std::swap(srcBuffer, dstBuffer);
// Upsample srcBuffer -> main framebuffer using bicubic filtering.
- bindFramebuffer();
- m_context->applyCompositeOperator(m_state->m_compositeOp);
- applyClipping(m_state->clippingEnabled());
+ applyState();
m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, srcBuffer->colorBuffer());
FloatRect dstRect = srcRect;
dstRect.scale(scaleFactor);
drawTexturedQuadMitchell(srcBuffer->size(), flipRect(srcRect), dstRect, AffineTransform(), 1.0);
} else {
// Blur in Y directly to framebuffer.
- bindFramebuffer();
- m_context->applyCompositeOperator(m_state->m_compositeOp);
- applyClipping(m_state->clippingEnabled());
-
+ applyState();
convolveRect(srcBuffer->colorBuffer(), srcBuffer->size(), flipRect(srcRect), srcRect, imageIncrementY, kernel.get(), kernelWidth);
}
}
diff --git a/Source/WebCore/platform/graphics/chromium/GLES2Canvas.h b/Source/WebCore/platform/graphics/chromium/GLES2Canvas.h
index f6a8bcf..635eb10 100644
--- a/Source/WebCore/platform/graphics/chromium/GLES2Canvas.h
+++ b/Source/WebCore/platform/graphics/chromium/GLES2Canvas.h
@@ -100,14 +100,14 @@ public:
DrawingBuffer* drawingBuffer() const { return m_drawingBuffer; }
private:
+ void applyState();
void scissorClear(float x, float y, float width, float height);
void drawTexturedRectTile(Texture* texture, int tile, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform&, float alpha);
void drawTexturedQuad(const IntSize& textureSize, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform&, float alpha);
void drawTexturedQuadMitchell(const IntSize& textureSize, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform&, float alpha);
void convolveRect(unsigned texture, const IntSize& textureSize, const FloatRect& srcRect, const FloatRect& dstRect, float imageIncrement[2], const float* kernel, int kernelWidth);
- void applyCompositeOperator(CompositeOperator);
- void createVertexBufferFromPath(const Path&, int* count, unsigned* vertexBuffer, unsigned* indexBuffer);
+ void tesselateAndFillPath(const Path&, const Color&);
void fillPathInternal(const Path&, const Color&);
void fillRectInternal(const FloatRect&, const Color&);
FloatRect flipRect(const FloatRect&);
@@ -131,6 +131,7 @@ private:
// Members for GPU-accelerated path rendering.
LoopBlinnPathCache m_pathCache;
+ unsigned m_pathIndexBuffer;
unsigned m_pathVertexBuffer;
};
diff --git a/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp
index 067c54d..2301ca3 100644
--- a/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp
@@ -283,6 +283,8 @@ void GraphicsLayerChromium::setMaskLayer(GraphicsLayer* maskLayer)
GraphicsLayer::setMaskLayer(maskLayer);
LayerChromium* maskLayerChromium = m_maskLayer ? m_maskLayer->platformLayer() : 0;
+ if (maskLayerChromium)
+ maskLayerChromium->setIsMask(true);
m_layer->setMaskLayer(maskLayerChromium);
}
diff --git a/Source/WebCore/platform/graphics/chromium/ImageBufferData.h b/Source/WebCore/platform/graphics/chromium/ImageBufferDataSkia.h
index 504b893..75c91ed 100644
--- a/Source/WebCore/platform/graphics/chromium/ImageBufferData.h
+++ b/Source/WebCore/platform/graphics/chromium/ImageBufferDataSkia.h
@@ -28,9 +28,6 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ImageBufferData_h
-#define ImageBufferData_h
-
#include "PlatformContextSkia.h"
#include "skia/ext/platform_canvas.h"
@@ -41,10 +38,8 @@ class ImageBufferData {
public:
ImageBufferData(const IntSize&);
- skia::PlatformCanvas m_canvas;
+ OwnPtr<SkCanvas> m_canvas;
PlatformContextSkia m_platformContext;
};
-} // namespace WebCore
-
-#endif // ImageBufferData_h
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp
index 60c1332..d72fb1e 100644
--- a/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp
@@ -34,6 +34,7 @@
#include "ImageLayerChromium.h"
+#include "cc/CCLayerImpl.h"
#include "Image.h"
#include "LayerRendererChromium.h"
#include "LayerTexture.h"
@@ -47,42 +48,69 @@ PassRefPtr<ImageLayerChromium> ImageLayerChromium::create(GraphicsLayerChromium*
ImageLayerChromium::ImageLayerChromium(GraphicsLayerChromium* owner)
: ContentLayerChromium(owner)
+ , m_imageForCurrentFrame(0)
, m_contents(0)
{
}
void ImageLayerChromium::setContents(Image* contents)
{
- // Check if the image has changed.
- if (m_contents == contents)
+ // setContents() currently gets called whenever there is any
+ // style change that affects the layer even if that change doesn't
+ // affect the actual contents of the image (e.g. a CSS animation).
+ // With this check in place we avoid unecessary texture uploads.
+ if ((m_contents == contents) && (m_contents->nativeImageForCurrentFrame() == m_imageForCurrentFrame))
return;
+
m_contents = contents;
+ m_imageForCurrentFrame = m_contents->nativeImageForCurrentFrame();
+ m_dirtyRect = IntRect(IntPoint(0, 0), bounds());
setNeedsDisplay();
}
-void ImageLayerChromium::paintContentsIfDirty()
+void ImageLayerChromium::paintContentsIfDirty(const IntRect&)
{
ASSERT(layerRenderer());
- // FIXME: Remove this test when tiled layers are implemented.
- if (requiresClippedUpdateRect()) {
- // Use the base version of updateContents which draws a subset of the
- // image to a bitmap, as the pixel contents can't be uploaded directly.
- ContentLayerChromium::paintContentsIfDirty();
- return;
+ if (!m_dirtyRect.isEmpty()) {
+ m_decodedImage.updateFromImage(m_contents->nativeImageForCurrentFrame());
}
-
- m_decodedImage.updateFromImage(m_contents->nativeImageForCurrentFrame());
}
-void ImageLayerChromium::updateTextureIfNeeded()
+void ImageLayerChromium::updateCompositorResources()
{
- // FIXME: Remove this test when tiled layers are implemented.
- if (requiresClippedUpdateRect()) {
- ContentLayerChromium::updateTextureIfNeeded();
- return;
+ updateLayerSize(m_decodedImage.size());
+
+ IntRect paintRect(IntPoint(0, 0), m_decodedImage.size());
+ if (!m_dirtyRect.isEmpty()) {
+ m_tiler->invalidateRect(paintRect);
+ m_dirtyRect = IntRect();
}
- updateTexture(m_decodedImage.pixels(), m_decodedImage.size());
+ m_tiler->updateFromPixels(paintRect, m_decodedImage.pixels());
+}
+
+IntRect ImageLayerChromium::layerBounds() const
+{
+ return IntRect(IntPoint(0, 0), m_decodedImage.size());
+}
+
+TransformationMatrix ImageLayerChromium::tilingTransform()
+{
+ // Tiler draws from the upper left corner. The draw transform
+ // specifies the middle of the layer.
+ TransformationMatrix transform = ccLayerImpl()->drawTransform();
+ const IntRect sourceRect = layerBounds();
+ const IntSize destSize = bounds();
+
+ transform.translate(-destSize.width() / 2.0, -destSize.height() / 2.0);
+
+ // Tiler also draws at the original content size, so rescale the original
+ // image dimensions to the bounds that it is meant to be drawn at.
+ float scaleX = destSize.width() / static_cast<float>(sourceRect.size().width());
+ float scaleY = destSize.height() / static_cast<float>(sourceRect.size().height());
+ transform.scale3d(scaleX, scaleY, 1.0f);
+
+ return transform;
}
}
diff --git a/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.h b/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.h
index 6addabc..8ab76a8 100644
--- a/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.h
@@ -37,7 +37,7 @@
#include "ContentLayerChromium.h"
#include "PlatformImage.h"
-#if PLATFORM(CG)
+#if USE(CG)
#include <wtf/RetainPtr.h>
#endif
@@ -50,7 +50,8 @@ class ImageLayerChromium : public ContentLayerChromium {
public:
static PassRefPtr<ImageLayerChromium> create(GraphicsLayerChromium* owner = 0);
- virtual void paintContentsIfDirty();
+ virtual void paintContentsIfDirty(const IntRect& targetSurfaceRect);
+ virtual void updateCompositorResources();
virtual bool drawsContent() const { return m_contents; }
void setContents(Image* image);
@@ -58,12 +59,14 @@ public:
protected:
virtual const char* layerTypeAsString() const { return "ImageLayer"; }
-private:
- virtual void updateTextureIfNeeded();
+ virtual TransformationMatrix tilingTransform();
+ virtual IntRect layerBounds() const;
+private:
ImageLayerChromium(GraphicsLayerChromium* owner);
PlatformImage m_decodedImage;
+ NativeImagePtr m_imageForCurrentFrame;
RefPtr<Image> m_contents;
};
diff --git a/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp
index bc28239..fba1dc5 100644
--- a/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp
@@ -89,6 +89,9 @@ LayerChromium::~LayerChromium()
// way for us to be destroyed while we still have a superlayer.
ASSERT(!superlayer());
+ if (m_ccLayerImpl)
+ m_ccLayerImpl->resetOwner();
+
// Remove the superlayer reference from all sublayers.
removeAllSublayers();
}
diff --git a/Source/WebCore/platform/graphics/chromium/LayerChromium.h b/Source/WebCore/platform/graphics/chromium/LayerChromium.h
index 428ce61..5564f91 100644
--- a/Source/WebCore/platform/graphics/chromium/LayerChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/LayerChromium.h
@@ -50,11 +50,6 @@
#include <wtf/text/StringHash.h>
#include <wtf/text/WTFString.h>
-
-namespace skia {
-class PlatformCanvas;
-}
-
namespace WebCore {
class CCLayerImpl;
@@ -113,6 +108,7 @@ public:
void setNeedsDisplay(const FloatRect& dirtyRect);
void setNeedsDisplay();
+ virtual void invalidateRect(const FloatRect& dirtyRect) {}
const FloatRect& dirtyRect() const { return m_dirtyRect; }
void resetNeedsDisplay();
@@ -156,11 +152,13 @@ public:
// These methods typically need to be overwritten by derived classes.
virtual bool drawsContent() const { return false; }
+ virtual void paintContentsIfDirty(const IntRect&) { }
virtual void paintContentsIfDirty() { }
virtual void updateCompositorResources() { }
+ virtual void setIsMask(bool) {}
virtual void unreserveContentsTexture() { }
virtual void bindContentsTexture() { }
- virtual void draw() { }
+ virtual void draw(const IntRect&) { }
// These exists just for debugging (via drawDebugBorder()).
void setBorderColor(const Color&);
diff --git a/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp b/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
index fc15abd..27a67e9 100644
--- a/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
@@ -34,8 +34,8 @@
#if USE(ACCELERATED_COMPOSITING)
#include "LayerRendererChromium.h"
-#include "cc/CCLayerImpl.h"
#include "Canvas2DLayerChromium.h"
+#include "Extensions3DChromium.h"
#include "FloatQuad.h"
#include "GeometryBinding.h"
#include "GraphicsContext3D.h"
@@ -50,7 +50,7 @@
#if USE(SKIA)
#include "NativeImageSkia.h"
#include "PlatformContextSkia.h"
-#elif PLATFORM(CG)
+#elif USE(CG)
#include <CoreGraphics/CGBitmapContext.h>
#endif
@@ -88,35 +88,38 @@ static bool isScaleOrTranslation(const TransformationMatrix& m)
}
-bool LayerRendererChromium::compareLayerZ(const CCLayerImpl* a, const CCLayerImpl* b)
+bool LayerRendererChromium::compareLayerZ(const RefPtr<CCLayerImpl>& a, const RefPtr<CCLayerImpl>& b)
{
return a->drawDepth() < b->drawDepth();
}
-PassRefPtr<LayerRendererChromium> LayerRendererChromium::create(PassRefPtr<GraphicsContext3D> context, PassOwnPtr<TilePaintInterface> contentPaint, PassOwnPtr<TilePaintInterface> scrollbarPaint)
+PassRefPtr<LayerRendererChromium> LayerRendererChromium::create(PassRefPtr<GraphicsContext3D> context, PassOwnPtr<TilePaintInterface> contentPaint)
{
if (!context)
return 0;
- RefPtr<LayerRendererChromium> layerRenderer(adoptRef(new LayerRendererChromium(context, contentPaint, scrollbarPaint)));
+ RefPtr<LayerRendererChromium> layerRenderer(adoptRef(new LayerRendererChromium(context, contentPaint)));
if (!layerRenderer->hardwareCompositing())
return 0;
return layerRenderer.release();
}
-LayerRendererChromium::LayerRendererChromium(PassRefPtr<GraphicsContext3D> context, PassOwnPtr<TilePaintInterface> contentPaint, PassOwnPtr<TilePaintInterface> scrollbarPaint)
+LayerRendererChromium::LayerRendererChromium(PassRefPtr<GraphicsContext3D> context,
+ PassOwnPtr<TilePaintInterface> contentPaint)
: m_viewportScrollPosition(IntPoint(-1, -1))
, m_rootLayer(0)
, m_rootLayerContentPaint(contentPaint)
- , m_rootLayerScrollbarPaint(scrollbarPaint)
, m_currentShader(0)
, m_currentRenderSurface(0)
, m_offscreenFramebufferId(0)
, m_compositeOffscreen(false)
, m_context(context)
+ , m_childContextsWereCopied(false)
+ , m_contextSupportsLatch(false)
, m_defaultRenderSurface(0)
{
+ m_contextSupportsLatch = m_context->getExtensions()->supports("GL_CHROMIUM_latch");
m_hardwareCompositing = initializeSharedObjects();
m_rootLayerContentTiler = LayerTilerChromium::create(this, IntSize(256, 256), LayerTilerChromium::NoBorderTexels);
ASSERT(m_rootLayerContentTiler);
@@ -150,40 +153,9 @@ void LayerRendererChromium::useShader(unsigned programId)
}
}
-IntRect LayerRendererChromium::verticalScrollbarRect() const
-{
- IntRect verticalScrollbar(IntPoint(m_viewportContentRect.maxX(), m_viewportContentRect.y()), IntSize(m_viewportVisibleRect.width() - m_viewportContentRect.width(), m_viewportVisibleRect.height()));
- return verticalScrollbar;
-}
-
-IntRect LayerRendererChromium::horizontalScrollbarRect() const
-{
- IntRect horizontalScrollbar(IntPoint(m_viewportContentRect.x(), m_viewportContentRect.maxY()), IntSize(m_viewportVisibleRect.width(), m_viewportVisibleRect.height() - m_viewportContentRect.height()));
- return horizontalScrollbar;
-}
-
void LayerRendererChromium::invalidateRootLayerRect(const IntRect& dirtyRect)
{
m_rootLayerContentTiler->invalidateRect(dirtyRect);
-
- // Scrollbars never need to render beyond the fold, so clip to the viewport.
- IntRect visibleDirtyRect = dirtyRect;
- visibleDirtyRect.intersect(m_viewportVisibleRect);
-
- if (m_horizontalScrollbarTiler) {
- IntRect scrollbar = horizontalScrollbarRect();
- if (visibleDirtyRect.intersects(scrollbar)) {
- m_horizontalScrollbarTiler->setLayerPosition(scrollbar.location());
- m_horizontalScrollbarTiler->invalidateRect(visibleDirtyRect);
- }
- }
- if (m_verticalScrollbarTiler) {
- IntRect scrollbar = verticalScrollbarRect();
- if (visibleDirtyRect.intersects(scrollbar)) {
- m_verticalScrollbarTiler->setLayerPosition(scrollbar.location());
- m_verticalScrollbarTiler->invalidateRect(visibleDirtyRect);
- }
- }
}
void LayerRendererChromium::updateRootLayerContents()
@@ -192,43 +164,14 @@ void LayerRendererChromium::updateRootLayerContents()
m_rootLayerContentTiler->update(*m_rootLayerContentPaint, m_viewportVisibleRect);
}
-void LayerRendererChromium::updateRootLayerScrollbars()
-{
- TRACE_EVENT("LayerRendererChromium::updateRootLayerScrollbars", this, 0);
- if (m_viewportVisibleRect.width() > m_viewportContentRect.width()) {
- IntRect verticalScrollbar = verticalScrollbarRect();
- IntSize tileSize = verticalScrollbar.size().shrunkTo(IntSize(m_maxTextureSize, m_maxTextureSize));
- if (!m_verticalScrollbarTiler)
- m_verticalScrollbarTiler = LayerTilerChromium::create(this, tileSize, LayerTilerChromium::NoBorderTexels);
- else
- m_verticalScrollbarTiler->setTileSize(tileSize);
- m_verticalScrollbarTiler->setLayerPosition(verticalScrollbar.location());
- m_verticalScrollbarTiler->update(*m_rootLayerScrollbarPaint, m_viewportVisibleRect);
- } else
- m_verticalScrollbarTiler.clear();
-
- if (m_viewportVisibleRect.height() > m_viewportContentRect.height()) {
- IntRect horizontalScrollbar = horizontalScrollbarRect();
- IntSize tileSize = horizontalScrollbar.size().shrunkTo(IntSize(m_maxTextureSize, m_maxTextureSize));
- if (!m_horizontalScrollbarTiler)
- m_horizontalScrollbarTiler = LayerTilerChromium::create(this, tileSize, LayerTilerChromium::NoBorderTexels);
- else
- m_horizontalScrollbarTiler->setTileSize(tileSize);
- m_horizontalScrollbarTiler->setLayerPosition(horizontalScrollbar.location());
- m_horizontalScrollbarTiler->update(*m_rootLayerScrollbarPaint, m_viewportVisibleRect);
- } else
- m_horizontalScrollbarTiler.clear();
-}
-
void LayerRendererChromium::drawRootLayer()
{
- m_rootLayerContentTiler->draw(m_viewportVisibleRect);
-
- if (m_verticalScrollbarTiler)
- m_verticalScrollbarTiler->draw(m_viewportVisibleRect);
+ TransformationMatrix scroll;
+ scroll.translate(-m_viewportVisibleRect.x(), -m_viewportVisibleRect.y());
- if (m_horizontalScrollbarTiler)
- m_horizontalScrollbarTiler->draw(m_viewportVisibleRect);
+ m_rootLayerContentTiler->uploadCanvas();
+ m_rootLayerContentTiler->draw(m_viewportVisibleRect, scroll, 1.0f);
+ m_rootLayerContentTiler->unreserveTextures();
}
void LayerRendererChromium::setViewport(const IntRect& visibleRect, const IntRect& contentRect, const IntPoint& scrollPosition)
@@ -243,12 +186,7 @@ void LayerRendererChromium::setViewport(const IntRect& visibleRect, const IntRec
// Reset the current render surface to force an update of the viewport and
// projection matrix next time useRenderSurface is called.
m_currentRenderSurface = 0;
-
m_rootLayerContentTiler->invalidateEntireLayer();
- if (m_horizontalScrollbarTiler)
- m_horizontalScrollbarTiler->invalidateEntireLayer();
- if (m_verticalScrollbarTiler)
- m_verticalScrollbarTiler->invalidateEntireLayer();
}
}
@@ -266,18 +204,56 @@ void LayerRendererChromium::updateAndDrawLayers()
if (!m_rootLayer)
return;
- updateRootLayerScrollbars();
+ LayerList renderSurfaceLayerList;
- Vector<CCLayerImpl*> renderSurfaceLayerList;
updateLayers(renderSurfaceLayerList);
+ // Before drawLayers:
+ if (hardwareCompositing() && m_contextSupportsLatch) {
+ // FIXME: The multithreaded compositor case will not work as long as
+ // copyTexImage2D resolves to the parent texture, because the main
+ // thread can execute WebGL calls on the child context at any time,
+ // potentially clobbering the parent texture that is being renderered
+ // by the compositor thread.
+ if (m_childContextsWereCopied) {
+ Extensions3DChromium* parentExt = static_cast<Extensions3DChromium*>(m_context->getExtensions());
+ // For each child context:
+ // glWaitLatch(Offscreen->Compositor);
+ ChildContextMap::iterator i = m_childContexts.begin();
+ for (; i != m_childContexts.end(); ++i) {
+ Extensions3DChromium* childExt = static_cast<Extensions3DChromium*>(i->first->getExtensions());
+ GC3Duint latchId;
+ childExt->getChildToParentLatchCHROMIUM(&latchId);
+ parentExt->waitLatchCHROMIUM(latchId);
+ }
+ }
+ // Reset to false to indicate that we have consumed the dirty child
+ // contexts' parent textures. (This is only useful when the compositor
+ // is multithreaded.)
+ m_childContextsWereCopied = false;
+ }
+
drawLayers(renderSurfaceLayerList);
+ // After drawLayers:
+ if (hardwareCompositing() && m_contextSupportsLatch) {
+ Extensions3DChromium* parentExt = static_cast<Extensions3DChromium*>(m_context->getExtensions());
+ // For each child context:
+ // glSetLatch(Compositor->Offscreen);
+ ChildContextMap::iterator i = m_childContexts.begin();
+ for (; i != m_childContexts.end(); ++i) {
+ Extensions3DChromium* childExt = static_cast<Extensions3DChromium*>(i->first->getExtensions());
+ GC3Duint latchId;
+ childExt->getParentToChildLatchCHROMIUM(&latchId);
+ parentExt->setLatchCHROMIUM(latchId);
+ }
+ }
+
if (isCompositingOffscreen())
copyOffscreenTextureToDisplay();
}
-void LayerRendererChromium::updateLayers(Vector<CCLayerImpl*>& renderSurfaceLayerList)
+void LayerRendererChromium::updateLayers(LayerList& renderSurfaceLayerList)
{
TRACE_EVENT("LayerRendererChromium::updateLayers", this, 0);
m_rootLayer->createCCLayerImplIfNeeded();
@@ -289,8 +265,7 @@ void LayerRendererChromium::updateLayers(Vector<CCLayerImpl*>& renderSurfaceLaye
rootDrawLayer->renderSurface()->m_contentRect = IntRect(IntPoint(0, 0), m_viewportVisibleRect.size());
- // Scissor out the scrollbars to avoid rendering on top of them.
- IntRect rootScissorRect(m_viewportContentRect);
+ IntRect rootScissorRect(m_viewportVisibleRect);
// The scissorRect should not include the scroll offset.
rootScissorRect.move(-m_viewportScrollPosition.x(), -m_viewportScrollPosition.y());
rootDrawLayer->setScissorRect(rootScissorRect);
@@ -309,10 +284,51 @@ void LayerRendererChromium::updateLayers(Vector<CCLayerImpl*>& renderSurfaceLaye
paintContentsRecursive(m_rootLayer.get());
+ // FIXME: Before updateCompositorResourcesRecursive, when the compositor runs in
+ // its own thread, and when the copyTexImage2D bug is fixed, insert
+ // a glWaitLatch(Compositor->Offscreen) on all child contexts here instead
+ // of after updateCompositorResourcesRecursive.
+ // Also uncomment the glSetLatch(Compositor->Offscreen) code in addChildContext.
+// if (hardwareCompositing() && m_contextSupportsLatch) {
+// // For each child context:
+// // glWaitLatch(Compositor->Offscreen);
+// ChildContextMap::iterator i = m_childContexts.begin();
+// for (; i != m_childContexts.end(); ++i) {
+// Extensions3DChromium* ext = static_cast<Extensions3DChromium*>(i->first->getExtensions());
+// GC3Duint childToParentLatchId, parentToChildLatchId;
+// ext->getParentToChildLatchCHROMIUM(&parentToChildLatchId);
+// ext->waitLatchCHROMIUM(parentToChildLatchId);
+// }
+// }
+
updateCompositorResourcesRecursive(m_rootLayer.get());
+
+ // After updateCompositorResourcesRecursive, set/wait latches for all child
+ // contexts. This will prevent the compositor from using any of the child
+ // parent textures while WebGL commands are executing from javascript *and*
+ // while the final parent texture is being blit'd. copyTexImage2D
+ // uses the parent texture as a temporary resolve buffer, so that's why the
+ // waitLatch is below, to block the compositor from using the parent texture
+ // until the next WebGL SwapBuffers (or copyTextureToParentTexture for
+ // Canvas2D).
+ if (hardwareCompositing() && m_contextSupportsLatch) {
+ m_childContextsWereCopied = true;
+ // For each child context:
+ // glSetLatch(Offscreen->Compositor);
+ // glWaitLatch(Compositor->Offscreen);
+ ChildContextMap::iterator i = m_childContexts.begin();
+ for (; i != m_childContexts.end(); ++i) {
+ Extensions3DChromium* ext = static_cast<Extensions3DChromium*>(i->first->getExtensions());
+ GC3Duint childToParentLatchId, parentToChildLatchId;
+ ext->getParentToChildLatchCHROMIUM(&parentToChildLatchId);
+ ext->getChildToParentLatchCHROMIUM(&childToParentLatchId);
+ ext->setLatchCHROMIUM(childToParentLatchId);
+ ext->waitLatchCHROMIUM(parentToChildLatchId);
+ }
+ }
}
-void LayerRendererChromium::drawLayers(const Vector<CCLayerImpl*>& renderSurfaceLayerList)
+void LayerRendererChromium::drawLayers(const LayerList& renderSurfaceLayerList)
{
TRACE_EVENT("LayerRendererChromium::drawLayers", this, 0);
CCLayerImpl* rootDrawLayer = m_rootLayer->ccLayerImpl();
@@ -347,13 +363,14 @@ void LayerRendererChromium::drawLayers(const Vector<CCLayerImpl*>& renderSurface
m_context->colorMask(true, true, true, true);
GLC(m_context.get(), m_context->enable(GraphicsContext3D::BLEND));
+ GLC(m_context.get(), m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA));
GLC(m_context.get(), m_context->enable(GraphicsContext3D::SCISSOR_TEST));
// Update the contents of the render surfaces. We traverse the array from
// back to front to guarantee that nested render surfaces get rendered in the
// correct order.
for (int surfaceIndex = renderSurfaceLayerList.size() - 1; surfaceIndex >= 0 ; --surfaceIndex) {
- CCLayerImpl* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex];
+ CCLayerImpl* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex].get();
ASSERT(renderSurfaceLayer->renderSurface());
// Render surfaces whose drawable area has zero width or height
@@ -369,10 +386,10 @@ void LayerRendererChromium::drawLayers(const Vector<CCLayerImpl*>& renderSurface
GLC(m_context.get(), m_context->enable(GraphicsContext3D::SCISSOR_TEST));
}
- Vector<CCLayerImpl*>& layerList = renderSurfaceLayer->renderSurface()->m_layerList;
+ LayerList& layerList = renderSurfaceLayer->renderSurface()->m_layerList;
ASSERT(layerList.size());
for (unsigned layerIndex = 0; layerIndex < layerList.size(); ++layerIndex)
- drawLayer(layerList[layerIndex], renderSurfaceLayer->renderSurface());
+ drawLayer(layerList[layerIndex].get(), renderSurfaceLayer->renderSurface());
}
}
@@ -412,10 +429,6 @@ void LayerRendererChromium::setRootLayer(PassRefPtr<LayerChromium> layer)
if (m_rootLayer)
m_rootLayer->setLayerRenderer(this);
m_rootLayerContentTiler->invalidateEntireLayer();
- if (m_horizontalScrollbarTiler)
- m_horizontalScrollbarTiler->invalidateEntireLayer();
- if (m_verticalScrollbarTiler)
- m_verticalScrollbarTiler->invalidateEntireLayer();
}
void LayerRendererChromium::getFramebufferPixels(void *pixels, const IntRect& rect)
@@ -473,7 +486,7 @@ bool LayerRendererChromium::isLayerVisible(LayerChromium* layer, const Transform
// Recursively walks the layer tree starting at the given node and computes all the
// necessary transformations, scissor rectangles, render surfaces, etc.
-void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* layer, const TransformationMatrix& parentMatrix, Vector<CCLayerImpl*>& renderSurfaceLayerList, Vector<CCLayerImpl*>& layerList)
+void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* layer, const TransformationMatrix& parentMatrix, LayerList& renderSurfaceLayerList, LayerList& layerList)
{
// Make sure we have CCLayerImpls for this subtree.
layer->createCCLayerImplIfNeeded();
@@ -659,7 +672,18 @@ void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* lay
// M[s] = M * Tr[-center]
sublayerMatrix.translate3d(-bounds.width() * 0.5, -bounds.height() * 0.5, 0);
- Vector<CCLayerImpl*>& descendants = (drawLayer->renderSurface() ? drawLayer->renderSurface()->m_layerList : layerList);
+ // Compute the depth value of the center of the layer which will be used when
+ // sorting the layers for the preserves-3d property.
+ const TransformationMatrix& layerDrawMatrix = drawLayer->renderSurface() ? drawLayer->renderSurface()->m_drawTransform : drawLayer->drawTransform();
+ if (drawLayer->superlayer()) {
+ if (!drawLayer->superlayer()->preserves3D())
+ drawLayer->setDrawDepth(drawLayer->superlayer()->drawDepth());
+ else
+ drawLayer->setDrawDepth(layerDrawMatrix.m43());
+ } else
+ drawLayer->setDrawDepth(0);
+
+ LayerList& descendants = (drawLayer->renderSurface() ? drawLayer->renderSurface()->m_layerList : layerList);
descendants.append(drawLayer);
unsigned thisLayerIndex = descendants.size() - 1;
@@ -730,17 +754,6 @@ void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* lay
}
}
- // Compute the depth value of the center of the layer which will be used when
- // sorting the layers for the preserves-3d property.
- const TransformationMatrix& layerDrawMatrix = drawLayer->renderSurface() ? drawLayer->renderSurface()->m_drawTransform : drawLayer->drawTransform();
- if (drawLayer->superlayer()) {
- if (!drawLayer->superlayer()->preserves3D())
- drawLayer->setDrawDepth(drawLayer->superlayer()->drawDepth());
- else
- drawLayer->setDrawDepth(layerDrawMatrix.m43());
- } else
- drawLayer->setDrawDepth(0);
-
// If preserves-3d then sort all the descendants by the Z coordinate of their
// center. If the preserves-3d property is also set on the superlayer then
// skip the sorting as the superlayer will sort all the descendants anyway.
@@ -757,14 +770,16 @@ void LayerRendererChromium::paintContentsRecursive(LayerChromium* layer)
if (layer->bounds().isEmpty())
return;
+ const IntRect targetSurfaceRect = layer->ccLayerImpl()->scissorRect();
+
if (layer->drawsContent())
- layer->paintContentsIfDirty();
+ layer->paintContentsIfDirty(targetSurfaceRect);
if (layer->maskLayer() && layer->maskLayer()->drawsContent())
- layer->maskLayer()->paintContentsIfDirty();
+ layer->maskLayer()->paintContentsIfDirty(targetSurfaceRect);
if (layer->replicaLayer() && layer->replicaLayer()->drawsContent())
- layer->replicaLayer()->paintContentsIfDirty();
+ layer->replicaLayer()->paintContentsIfDirty(targetSurfaceRect);
if (layer->replicaLayer() && layer->replicaLayer()->maskLayer() && layer->replicaLayer()->maskLayer()->drawsContent())
- layer->replicaLayer()->maskLayer()->paintContentsIfDirty();
+ layer->replicaLayer()->maskLayer()->paintContentsIfDirty(targetSurfaceRect);
}
void LayerRendererChromium::updateCompositorResourcesRecursive(LayerChromium* layer)
@@ -816,7 +831,7 @@ void LayerRendererChromium::copyOffscreenTextureToDisplay()
m_defaultRenderSurface->m_drawTransform.translate3d(0.5 * m_defaultRenderSurface->m_contentRect.width(),
0.5 * m_defaultRenderSurface->m_contentRect.height(), 0);
m_defaultRenderSurface->m_drawOpacity = 1;
- m_defaultRenderSurface->draw();
+ m_defaultRenderSurface->draw(m_defaultRenderSurface->m_contentRect);
}
}
@@ -857,10 +872,13 @@ bool LayerRendererChromium::useRenderSurface(RenderSurfaceChromium* renderSurfac
void LayerRendererChromium::drawLayer(CCLayerImpl* layer, RenderSurfaceChromium* targetSurface)
{
if (layer->renderSurface() && layer->renderSurface() != targetSurface) {
- layer->renderSurface()->draw();
+ layer->renderSurface()->draw(layer->getDrawRect());
return;
}
+ if (!layer->drawsContent())
+ return;
+
if (layer->bounds().isEmpty()) {
layer->unreserveContentsTexture();
return;
@@ -894,8 +912,7 @@ void LayerRendererChromium::drawLayer(CCLayerImpl* layer, RenderSurfaceChromium*
}
}
- if (layer->drawsContent())
- layer->draw();
+ layer->draw(layer->scissorRect());
// Draw the debug border if there is one.
layer->drawDebugBorder();
@@ -968,7 +985,6 @@ bool LayerRendererChromium::initializeSharedObjects()
m_sharedGeometry = adoptPtr(new GeometryBinding(m_context.get()));
m_borderProgram = adoptPtr(new LayerChromium::BorderProgram(m_context.get()));
- m_contentLayerProgram = adoptPtr(new ContentLayerChromium::Program(m_context.get()));
m_canvasLayerProgram = adoptPtr(new CCCanvasLayerImpl::Program(m_context.get()));
m_videoLayerRGBAProgram = adoptPtr(new CCVideoLayerImpl::RGBAProgram(m_context.get()));
m_videoLayerYUVProgram = adoptPtr(new CCVideoLayerImpl::YUVProgram(m_context.get()));
@@ -978,7 +994,7 @@ bool LayerRendererChromium::initializeSharedObjects()
m_tilerProgram = adoptPtr(new LayerTilerChromium::Program(m_context.get()));
if (!m_sharedGeometry->initialized() || !m_borderProgram->initialized()
- || !m_contentLayerProgram->initialized() || !m_canvasLayerProgram->initialized()
+ || !m_canvasLayerProgram->initialized()
|| !m_videoLayerRGBAProgram->initialized() || !m_videoLayerYUVProgram->initialized()
|| !m_pluginLayerProgram->initialized() || !m_renderSurfaceProgram->initialized()
|| !m_renderSurfaceMaskProgram->initialized() || !m_tilerProgram->initialized()) {
@@ -997,7 +1013,6 @@ void LayerRendererChromium::cleanupSharedObjects()
m_sharedGeometry.clear();
m_borderProgram.clear();
- m_contentLayerProgram.clear();
m_canvasLayerProgram.clear();
m_videoLayerRGBAProgram.clear();
m_videoLayerYUVProgram.clear();
@@ -1010,8 +1025,6 @@ void LayerRendererChromium::cleanupSharedObjects()
// Clear tilers before the texture manager, as they have references to textures.
m_rootLayerContentTiler.clear();
- m_horizontalScrollbarTiler.clear();
- m_verticalScrollbarTiler.clear();
m_textureManager.clear();
}
@@ -1027,6 +1040,48 @@ String LayerRendererChromium::layerTreeAsText() const
return ts.release();
}
+void LayerRendererChromium::addChildContext(GraphicsContext3D* ctx)
+{
+ if (!ctx->getExtensions()->supports("GL_CHROMIUM_latch"))
+ return;
+
+ // This is a ref-counting map, because some contexts are shared by multiple
+ // layers (specifically, Canvas2DLayerChromium).
+
+ // Insert the ctx with a count of 1, or return the existing iterator.
+ std::pair<ChildContextMap::iterator, bool> insert_result = m_childContexts.add(ctx, 1);
+ if (!insert_result.second) {
+ // Already present in map, so increment.
+ ++insert_result.first->second;
+ } else {
+// FIXME(jbates): when compositor is multithreaded and copyTexImage2D bug is fixed,
+// uncomment this block:
+// // This is a new child context - set the parentToChild latch so that it
+// // can continue past its first wait latch.
+// Extensions3DChromium* ext = static_cast<Extensions3DChromium*>(ctx->getExtensions());
+// GC3Duint latchId;
+// ext->getParentToChildLatchCHROMIUM(&latchId);
+// ext->setLatchCHROMIUM(0, latchId);
+ }
+}
+
+void LayerRendererChromium::removeChildContext(GraphicsContext3D* ctx)
+{
+ if (!ctx->getExtensions()->supports("GL_CHROMIUM_latch"))
+ return;
+
+ ChildContextMap::iterator i = m_childContexts.find(ctx);
+ if (i != m_childContexts.end()) {
+ if (--i->second <= 0) {
+ // Count reached zero, so remove from map.
+ m_childContexts.remove(i);
+ }
+ } else {
+ // error
+ ASSERT(0 && "m_childContexts map has mismatched add/remove calls");
+ }
+}
+
void LayerRendererChromium::dumpRenderSurfaces(TextStream& ts, int indent, LayerChromium* layer) const
{
if (layer->ccLayerImpl()->renderSurface())
diff --git a/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h b/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h
index 667ede2..813eb46 100644
--- a/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h
@@ -52,22 +52,22 @@
#include <wtf/RefCounted.h>
#include <wtf/Vector.h>
-#if PLATFORM(CG)
+#if USE(CG)
#include <CoreGraphics/CGContext.h>
#include <wtf/RetainPtr.h>
#endif
namespace WebCore {
+class CCHeadsUpDisplay;
class CCLayerImpl;
class GeometryBinding;
class GraphicsContext3D;
-class CCHeadsUpDisplay;
// Class that handles drawing of composited render layers using GL.
class LayerRendererChromium : public RefCounted<LayerRendererChromium> {
public:
- static PassRefPtr<LayerRendererChromium> create(PassRefPtr<GraphicsContext3D>, PassOwnPtr<TilePaintInterface> contentPaint, PassOwnPtr<TilePaintInterface> scrollbarPaint);
+ static PassRefPtr<LayerRendererChromium> create(PassRefPtr<GraphicsContext3D>, PassOwnPtr<TilePaintInterface> contentPaint);
~LayerRendererChromium();
@@ -88,7 +88,7 @@ public:
IntSize viewportSize() const { return m_viewportVisibleRect.size(); }
- void setRootLayer(PassRefPtr<LayerChromium> layer);
+ void setRootLayer(PassRefPtr<LayerChromium>);
LayerChromium* rootLayer() { return m_rootLayer.get(); }
void transferRootLayer(LayerRendererChromium* other) { other->m_rootLayer = m_rootLayer.release(); }
@@ -110,7 +110,6 @@ public:
const GeometryBinding* sharedGeometry() const { return m_sharedGeometry.get(); }
const LayerChromium::BorderProgram* borderProgram() const { return m_borderProgram.get(); }
- const ContentLayerChromium::Program* contentLayerProgram() const { return m_contentLayerProgram.get(); }
const RenderSurfaceChromium::Program* renderSurfaceProgram() const { return m_renderSurfaceProgram.get(); }
const RenderSurfaceChromium::MaskProgram* renderSurfaceMaskProgram() const { return m_renderSurfaceMaskProgram.get(); }
const LayerTilerChromium::Program* tilerProgram() const { return m_tilerProgram.get(); }
@@ -131,17 +130,23 @@ public:
String layerTreeAsText() const;
+ void addChildContext(GraphicsContext3D*);
+ void removeChildContext(GraphicsContext3D*);
+
private:
- explicit LayerRendererChromium(PassRefPtr<GraphicsContext3D>, PassOwnPtr<TilePaintInterface> contentPaint, PassOwnPtr<TilePaintInterface> scrollbarPaint);
+ typedef Vector<RefPtr<CCLayerImpl> > LayerList;
+ typedef HashMap<GraphicsContext3D*, int> ChildContextMap;
+
+ explicit LayerRendererChromium(PassRefPtr<GraphicsContext3D>, PassOwnPtr<TilePaintInterface> contentPaint);
- void updateLayers(Vector<CCLayerImpl*>& renderSurfaceLayerList);
+ void updateLayers(LayerList& renderSurfaceLayerList);
void updateRootLayerContents();
- void updateRootLayerScrollbars();
- void updatePropertiesAndRenderSurfaces(LayerChromium*, const TransformationMatrix& parentMatrix, Vector<CCLayerImpl*>& renderSurfaceLayerList, Vector<CCLayerImpl*>& layerList);
+ void updatePropertiesAndRenderSurfaces(LayerChromium*, const TransformationMatrix& parentMatrix, LayerList& renderSurfaceLayerList, LayerList& layers);
+
void paintContentsRecursive(LayerChromium*);
void updateCompositorResourcesRecursive(LayerChromium*);
- void drawLayers(const Vector<CCLayerImpl*>& renderSurfaceLayerList);
+ void drawLayers(const LayerList& renderSurfaceLayerList);
void drawLayer(CCLayerImpl*, RenderSurfaceChromium*);
void drawRootLayer();
@@ -156,16 +161,13 @@ private:
bool makeContextCurrent();
- static bool compareLayerZ(const CCLayerImpl*, const CCLayerImpl*);
+ static bool compareLayerZ(const RefPtr<CCLayerImpl>&, const RefPtr<CCLayerImpl>&);
void dumpRenderSurfaces(TextStream&, int indent, LayerChromium*) const;
bool initializeSharedObjects();
void cleanupSharedObjects();
- IntRect verticalScrollbarRect() const;
- IntRect horizontalScrollbarRect() const;
-
IntRect m_viewportVisibleRect;
IntRect m_viewportContentRect;
IntPoint m_viewportScrollPosition;
@@ -174,10 +176,7 @@ private:
RefPtr<LayerChromium> m_rootLayer;
OwnPtr<TilePaintInterface> m_rootLayerContentPaint;
- OwnPtr<TilePaintInterface> m_rootLayerScrollbarPaint;
OwnPtr<LayerTilerChromium> m_rootLayerContentTiler;
- OwnPtr<LayerTilerChromium> m_horizontalScrollbarTiler;
- OwnPtr<LayerTilerChromium> m_verticalScrollbarTiler;
bool m_hardwareCompositing;
@@ -188,10 +187,10 @@ private:
bool m_compositeOffscreen;
#if USE(SKIA)
- OwnPtr<skia::PlatformCanvas> m_rootLayerCanvas;
+ OwnPtr<SkCanvas> m_rootLayerCanvas;
OwnPtr<PlatformContextSkia> m_rootLayerSkiaContext;
OwnPtr<GraphicsContext> m_rootLayerGraphicsContext;
-#elif PLATFORM(CG)
+#elif USE(CG)
Vector<uint8_t> m_rootLayerBackingStore;
RetainPtr<CGContextRef> m_rootLayerCGContext;
OwnPtr<GraphicsContext> m_rootLayerGraphicsContext;
@@ -206,7 +205,6 @@ private:
// we cannot store these values in static variables.
OwnPtr<GeometryBinding> m_sharedGeometry;
OwnPtr<LayerChromium::BorderProgram> m_borderProgram;
- OwnPtr<ContentLayerChromium::Program> m_contentLayerProgram;
OwnPtr<RenderSurfaceChromium::Program> m_renderSurfaceProgram;
OwnPtr<RenderSurfaceChromium::MaskProgram> m_renderSurfaceMaskProgram;
OwnPtr<LayerTilerChromium::Program> m_tilerProgram;
@@ -220,6 +218,15 @@ private:
OwnPtr<CCHeadsUpDisplay> m_headsUpDisplay;
RefPtr<GraphicsContext3D> m_context;
+ ChildContextMap m_childContexts;
+
+ // If true, the child contexts were copied to the compositor texture targets
+ // and the compositor will need to wait on the proper latches before using
+ // the target textures. If false, the compositor is reusing the textures
+ // from last frame.
+ bool m_childContextsWereCopied;
+
+ bool m_contextSupportsLatch;
RenderSurfaceChromium* m_defaultRenderSurface;
};
diff --git a/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp b/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp
index bc37201..54c6ac2 100644
--- a/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp
@@ -40,6 +40,8 @@
using namespace std;
+static int minTextureSize = 16;
+
namespace WebCore {
PassOwnPtr<LayerTilerChromium> LayerTilerChromium::create(LayerRendererChromium* layerRenderer, const IntSize& tileSize, BorderTexelOption border)
@@ -69,8 +71,10 @@ GraphicsContext3D* LayerTilerChromium::layerRendererContext() const
return layerRenderer()->context();
}
-void LayerTilerChromium::setTileSize(const IntSize& size)
+void LayerTilerChromium::setTileSize(const IntSize& requestedSize)
{
+ IntSize size(max(minTextureSize, requestedSize.width()), max(minTextureSize, requestedSize.height()));
+
if (m_tileSize == size)
return;
@@ -81,6 +85,12 @@ void LayerTilerChromium::setTileSize(const IntSize& size)
m_tilingData.setMaxTextureSize(max(size.width(), size.height()));
}
+LayerTexture* LayerTilerChromium::getSingleTexture()
+{
+ Tile* tile = tileAt(0, 0);
+ return tile ? tile->texture() : 0;
+}
+
void LayerTilerChromium::reset()
{
m_tiles.clear();
@@ -180,7 +190,7 @@ IntRect LayerTilerChromium::tileLayerRect(const Tile* tile) const
void LayerTilerChromium::invalidateRect(const IntRect& contentRect)
{
- if (contentRect.isEmpty())
+ if (contentRect.isEmpty() || m_skipsDraw)
return;
growLayerToContain(contentRect);
@@ -236,6 +246,8 @@ void LayerTilerChromium::update(TilePaintInterface& painter, const IntRect& cont
tile = createTile(i, j);
if (!tile->texture()->isValid(m_tileSize, GraphicsContext3D::RGBA))
tile->m_dirtyLayerRect = tileLayerRect(tile);
+ else
+ tile->texture()->reserve(m_tileSize, GraphicsContext3D::RGBA);
dirtyLayerRect.unite(tile->m_dirtyLayerRect);
}
}
@@ -243,27 +255,35 @@ void LayerTilerChromium::update(TilePaintInterface& painter, const IntRect& cont
if (dirtyLayerRect.isEmpty())
return;
- const IntRect paintRect = layerRectToContentRect(dirtyLayerRect);
+ m_paintRect = layerRectToContentRect(dirtyLayerRect);
+
+ m_canvas.resize(m_paintRect.size());
- m_canvas.resize(paintRect.size());
- PlatformCanvas::Painter canvasPainter(&m_canvas);
- canvasPainter.context()->translate(-paintRect.x(), -paintRect.y());
+ // Assumption: if a tiler is using border texels, then it is because the
+ // layer is likely to be filtered or transformed. Because of it might be
+ // transformed, draw the text in grayscale instead of subpixel antialiasing.
+ PlatformCanvas::Painter::TextOption textOption = m_tilingData.borderTexels() ? PlatformCanvas::Painter::GrayscaleText : PlatformCanvas::Painter::SubpixelText;
+ PlatformCanvas::Painter canvasPainter(&m_canvas, textOption);
+ canvasPainter.context()->translate(-m_paintRect.x(), -m_paintRect.y());
{
TRACE_EVENT("LayerTilerChromium::update::paint", this, 0);
- painter.paint(*canvasPainter.context(), paintRect);
+ painter.paint(*canvasPainter.context(), m_paintRect);
}
+}
+void LayerTilerChromium::uploadCanvas()
+{
PlatformCanvas::AutoLocker locker(&m_canvas);
{
TRACE_EVENT("LayerTilerChromium::updateFromPixels", this, 0);
- updateFromPixels(paintRect, locker.pixels());
+ updateFromPixels(m_paintRect, locker.pixels());
}
}
void LayerTilerChromium::updateFromPixels(const IntRect& paintRect, const uint8_t* paintPixels)
{
// Painting could cause compositing to get turned off, which may cause the tiler to become invalidated mid-update.
- if (!m_tiles.size())
+ if (!m_tilingData.totalSizeX() || !m_tilingData.totalSizeY())
return;
GraphicsContext3D* context = layerRendererContext();
@@ -274,21 +294,26 @@ void LayerTilerChromium::updateFromPixels(const IntRect& paintRect, const uint8_
for (int i = left; i <= right; ++i) {
Tile* tile = tileAt(i, j);
if (!tile)
- CRASH();
- if (!tile->dirty())
+ tile = createTile(i, j);
+ else if (!tile->dirty())
continue;
// Calculate page-space rectangle to copy from.
IntRect sourceRect = tileContentRect(tile);
const IntPoint anchor = sourceRect.location();
sourceRect.intersect(layerRectToContentRect(tile->m_dirtyLayerRect));
+ // Paint rect not guaranteed to line up on tile boundaries, so
+ // make sure that sourceRect doesn't extend outside of it.
+ sourceRect.intersect(paintRect);
if (sourceRect.isEmpty())
continue;
- if (!tile->texture()->reserve(m_tileSize, GraphicsContext3D::RGBA)) {
- m_skipsDraw = true;
- reset();
- return;
+ if (!tile->texture()->isReserved()) {
+ if (!tile->texture()->reserve(m_tileSize, GraphicsContext3D::RGBA)) {
+ m_skipsDraw = true;
+ reset();
+ return;
+ }
}
// Calculate tile-space rectangle to upload into.
@@ -324,8 +349,10 @@ void LayerTilerChromium::updateFromPixels(const IntRect& paintRect, const uint8_
}
tile->texture()->bindTexture();
- GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::NEAREST));
- GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::NEAREST));
+
+ const GC3Dint filter = m_tilingData.borderTexels() ? GraphicsContext3D::LINEAR : GraphicsContext3D::NEAREST;
+ GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, filter));
+ GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, filter));
GLC(context, context->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, destRect.x(), destRect.y(), destRect.width(), destRect.height(), GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixelSource));
@@ -339,7 +366,7 @@ void LayerTilerChromium::setLayerPosition(const IntPoint& layerPosition)
m_layerPosition = layerPosition;
}
-void LayerTilerChromium::draw(const IntRect& contentRect)
+void LayerTilerChromium::draw(const IntRect& contentRect, const TransformationMatrix& globalTransform, float opacity)
{
if (m_skipsDraw || !m_tiles.size())
return;
@@ -354,17 +381,18 @@ void LayerTilerChromium::draw(const IntRect& contentRect)
for (int j = top; j <= bottom; ++j) {
for (int i = left; i <= right; ++i) {
Tile* tile = tileAt(i, j);
- ASSERT(tile);
+ if (!tile)
+ continue;
tile->texture()->bindTexture();
- TransformationMatrix tileMatrix;
+ TransformationMatrix tileMatrix(globalTransform);
// Don't use tileContentRect here, as that contains the full
// rect with border texels which shouldn't be drawn.
IntRect tileRect = m_tilingData.tileBounds(m_tilingData.tileIndex(tile->i(), tile->j()));
tileRect.move(m_layerPosition.x(), m_layerPosition.y());
- tileMatrix.translate3d(tileRect.x() - contentRect.x() + tileRect.width() / 2.0, tileRect.y() - contentRect.y() + tileRect.height() / 2.0, 0);
+ tileMatrix.translate3d(tileRect.x() + tileRect.width() / 2.0, tileRect.y() + tileRect.height() / 2.0, 0);
IntPoint texOffset = m_tilingData.textureOffset(tile->i(), tile->j());
float tileWidth = static_cast<float>(m_tileSize.width());
@@ -374,13 +402,21 @@ void LayerTilerChromium::draw(const IntRect& contentRect)
float texScaleX = tileRect.width() / tileWidth;
float texScaleY = tileRect.height() / tileHeight;
- drawTexturedQuad(context, layerRenderer()->projectionMatrix(), tileMatrix, tileRect.width(), tileRect.height(), 1, texTranslateX, texTranslateY, texScaleX, texScaleY, program);
-
- tile->texture()->unreserve();
+ drawTexturedQuad(context, layerRenderer()->projectionMatrix(), tileMatrix, tileRect.width(), tileRect.height(), opacity, texTranslateX, texTranslateY, texScaleX, texScaleY, program);
}
}
}
+void LayerTilerChromium::unreserveTextures()
+{
+ for (TileMap::iterator iter = m_tiles.begin(); iter != m_tiles.end(); ++iter) {
+ Tile* tile = iter->second.get();
+ if (!tile)
+ continue;
+ tile->texture()->unreserve();
+ }
+}
+
void LayerTilerChromium::growLayerToContain(const IntRect& contentRect)
{
// Grow the tile array to contain this content rect.
diff --git a/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.h b/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.h
index 2f356e4..111dd7e 100644
--- a/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.h
@@ -56,19 +56,40 @@ public:
~LayerTilerChromium();
+ // Set invalidations to be potentially repainted during update().
void invalidateRect(const IntRect& contentRect);
void invalidateEntireLayer();
+
+ // Paint all invalidations and missing tiles needed to draw the contentRect
+ // into the internal canvas.
void update(TilePaintInterface& painter, const IntRect& contentRect);
+
+ // Reserve and upload tile textures from the internal canvas.
+ void uploadCanvas();
+
+ // Reserve and upload tile textures from an externally painted buffer.
void updateFromPixels(const IntRect& paintRect, const uint8_t* pixels);
- void draw(const IntRect& contentRect);
+
+ // Draw all tiles that intersect with the content rect.
+ void draw(const IntRect& contentRect, const TransformationMatrix&, float opacity);
+
+ // If uploadCanvas/updateFromPixels is called, this must be called after
+ // draw() to unreserve any textures that were reserved prior to uploading.
+ void unreserveTextures();
// Set position of this tiled layer in content space.
void setLayerPosition(const IntPoint& position);
// Change the tile size. This may invalidate all the existing tiles.
void setTileSize(const IntSize& size);
+ void setLayerRenderer(LayerRendererChromium* layerRenderer) { m_layerRenderer = layerRenderer; }
+
+ bool skipsDraw() const { return m_skipsDraw; }
typedef ProgramBinding<VertexShaderPosTexTransform, FragmentShaderTexAlpha> Program;
+ // If this tiler has exactly one tile, return its texture. Otherwise, null.
+ LayerTexture* getSingleTexture();
+
private:
LayerTilerChromium(LayerRendererChromium*, const IntSize& tileSize, BorderTexelOption);
@@ -140,6 +161,7 @@ private:
// Tightly packed set of unused tiles.
Vector<RefPtr<Tile> > m_unusedTiles;
+ IntRect m_paintRect;
PlatformCanvas m_canvas;
// Cache a tile-sized pixel buffer to draw into.
diff --git a/Source/WebCore/platform/graphics/chromium/PlatformCanvas.cpp b/Source/WebCore/platform/graphics/chromium/PlatformCanvas.cpp
index 29589f4..afaa6f7 100644
--- a/Source/WebCore/platform/graphics/chromium/PlatformCanvas.cpp
+++ b/Source/WebCore/platform/graphics/chromium/PlatformCanvas.cpp
@@ -34,7 +34,7 @@
#include "PlatformContextSkia.h"
#include "SkColorPriv.h"
#include "skia/ext/platform_canvas.h"
-#elif PLATFORM(CG)
+#elif USE(CG)
#include <CoreGraphics/CGBitmapContext.h>
#endif
@@ -52,8 +52,8 @@ void PlatformCanvas::resize(const IntSize& size)
{
m_size = size;
#if USE(SKIA)
- m_skiaCanvas = new skia::PlatformCanvas(size.width(), size.height(), false);
-#elif PLATFORM(CG)
+ m_skiaCanvas = skia::CreateBitmapCanvas(size.width(), size.height(), false);
+#elif USE(CG)
size_t bufferSize = size.width() * size.height() * 4;
m_pixelData = adoptArrayPtr(new uint8_t[bufferSize]);
memset(m_pixelData.get(), 0, bufferSize);
@@ -73,8 +73,9 @@ PlatformCanvas::AutoLocker::AutoLocker(PlatformCanvas* canvas)
m_pixels = static_cast<uint8_t*>(m_bitmap->getPixels());
} else
m_bitmap = 0;
-#elif PLATFORM(CG)
- m_pixels = &canvas->m_pixelData[0];
+#elif USE(CG)
+ if (canvas->m_pixelData)
+ m_pixels = &canvas->m_pixelData[0];
#endif
}
@@ -86,16 +87,15 @@ PlatformCanvas::AutoLocker::~AutoLocker()
#endif
}
-PlatformCanvas::Painter::Painter(PlatformCanvas* canvas)
+PlatformCanvas::Painter::Painter(PlatformCanvas* canvas, PlatformCanvas::Painter::TextOption option)
{
#if USE(SKIA)
m_skiaContext = adoptPtr(new PlatformContextSkia(canvas->m_skiaCanvas.get()));
- // This is needed to get text to show up correctly.
- m_skiaContext->setDrawingToImageBuffer(true);
+ m_skiaContext->setDrawingToImageBuffer(option == GrayscaleText);
m_context = adoptPtr(new GraphicsContext(reinterpret_cast<PlatformGraphicsContext*>(m_skiaContext.get())));
-#elif PLATFORM(CG)
+#elif USE(CG)
m_colorSpace = CGColorSpaceCreateDeviceRGB();
size_t rowBytes = canvas->size().width() * 4;
diff --git a/Source/WebCore/platform/graphics/chromium/PlatformCanvas.h b/Source/WebCore/platform/graphics/chromium/PlatformCanvas.h
index 262fdd0..b002d26 100644
--- a/Source/WebCore/platform/graphics/chromium/PlatformCanvas.h
+++ b/Source/WebCore/platform/graphics/chromium/PlatformCanvas.h
@@ -31,7 +31,7 @@
#include <wtf/Noncopyable.h>
#include <wtf/OwnPtr.h>
-#if PLATFORM(CG)
+#if USE(CG)
#include <CoreGraphics/CGColorSpace.h>
#include <CoreGraphics/CGContext.h>
#include <wtf/OwnArrayPtr.h>
@@ -39,8 +39,8 @@
#endif
#if USE(SKIA)
-namespace skia { class PlatformCanvas; }
class SkBitmap;
+class SkCanvas;
#endif
namespace WebCore {
@@ -78,7 +78,9 @@ public:
class Painter {
WTF_MAKE_NONCOPYABLE(Painter);
public:
- explicit Painter(PlatformCanvas*);
+ enum TextOption { GrayscaleText, SubpixelText };
+
+ Painter(PlatformCanvas*, TextOption);
~Painter();
GraphicsContext* context() const { return m_context.get(); }
@@ -86,7 +88,7 @@ public:
OwnPtr<GraphicsContext> m_context;
#if USE(SKIA)
OwnPtr<PlatformContextSkia> m_skiaContext;
-#elif PLATFORM(CG)
+#elif USE(CG)
RetainPtr<CGColorSpaceRef> m_colorSpace;
RetainPtr<CGContextRef> m_contextCG;
#endif
@@ -97,8 +99,8 @@ public:
private:
#if USE(SKIA)
- OwnPtr<skia::PlatformCanvas> m_skiaCanvas;
-#elif PLATFORM(CG)
+ OwnPtr<SkCanvas> m_skiaCanvas;
+#elif USE(CG)
OwnArrayPtr<uint8_t> m_pixelData;
#endif
IntSize m_size;
diff --git a/Source/WebCore/platform/graphics/chromium/PlatformImage.cpp b/Source/WebCore/platform/graphics/chromium/PlatformImage.cpp
index 62cf4f8..c31b29c 100644
--- a/Source/WebCore/platform/graphics/chromium/PlatformImage.cpp
+++ b/Source/WebCore/platform/graphics/chromium/PlatformImage.cpp
@@ -30,7 +30,7 @@
#if USE(SKIA)
#include "NativeImageSkia.h"
#include "PlatformContextSkia.h"
-#elif PLATFORM(CG)
+#elif USE(CG)
#include <CoreGraphics/CGBitmapContext.h>
#include <CoreGraphics/CGContext.h>
#include <CoreGraphics/CGImage.h>
@@ -54,7 +54,7 @@ void PlatformImage::updateFromImage(NativeImagePtr nativeImage)
IntSize bitmapSize(skiaBitmap->width(), skiaBitmap->height());
ASSERT(skiaBitmap);
-#elif PLATFORM(CG)
+#elif USE(CG)
// NativeImagePtr is a CGImageRef on Mac OS X.
int width = CGImageGetWidth(nativeImage);
int height = CGImageGetHeight(nativeImage);
@@ -73,7 +73,7 @@ void PlatformImage::updateFromImage(NativeImagePtr nativeImage)
// FIXME: do we need to support more image configurations?
ASSERT(skiaBitmap->config()== SkBitmap::kARGB_8888_Config);
skiaBitmap->copyPixelsTo(m_pixelData.get(), bufferSize);
-#elif PLATFORM(CG)
+#elif USE(CG)
// FIXME: we should get rid of this temporary copy where possible.
int tempRowBytes = width * 4;
// Note we do not zero this vector since we are going to
diff --git a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp
index ca42d0b..c93ef3f 100644
--- a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp
@@ -143,7 +143,7 @@ void RenderSurfaceChromium::drawSurface(CCLayerImpl* maskLayer, const Transforma
maskLayer->unreserveContentsTexture();
}
-void RenderSurfaceChromium::draw()
+void RenderSurfaceChromium::draw(const IntRect&)
{
if (m_skipsDraw || !m_contentsTexture)
return;
diff --git a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h
index 6400c63..7c0e984 100644
--- a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h
@@ -52,7 +52,7 @@ public:
bool prepareContentsTexture();
void cleanupResources();
- void draw();
+ void draw(const IntRect& targetSurfaceRect);
String name() const;
void dumpSurface(TextStream&, int indent) const;
@@ -84,7 +84,7 @@ private:
TransformationMatrix m_replicaDrawTransform;
TransformationMatrix m_originTransform;
IntRect m_scissorRect;
- Vector<CCLayerImpl*> m_layerList;
+ Vector<RefPtr<CCLayerImpl> > m_layerList;
};
}
diff --git a/Source/WebCore/platform/graphics/chromium/TransparencyWin.cpp b/Source/WebCore/platform/graphics/chromium/TransparencyWin.cpp
index 193271d..f2c2394 100644
--- a/Source/WebCore/platform/graphics/chromium/TransparencyWin.cpp
+++ b/Source/WebCore/platform/graphics/chromium/TransparencyWin.cpp
@@ -49,14 +49,14 @@ namespace {
// into. Buffers larger than this will be destroyed when we're done with them.
const int maxCachedBufferPixelSize = 65536;
-inline skia::PlatformCanvas* canvasForContext(const GraphicsContext& context)
+inline SkCanvas* canvasForContext(const GraphicsContext& context)
{
return context.platformContext()->canvas();
}
inline const SkBitmap& bitmapForContext(const GraphicsContext& context)
{
- return canvasForContext(context)->getTopPlatformDevice().accessBitmap(false);
+ return canvasForContext(context)->getTopDevice()->accessBitmap(false);
}
void compositeToCopy(const GraphicsContext& sourceLayers,
@@ -466,7 +466,7 @@ void TransparencyWin::compositeTextComposite()
if (!m_validLayer)
return;
- const SkBitmap& bitmap = m_layerBuffer->context()->platformContext()->canvas()->getTopPlatformDevice().accessBitmap(true);
+ const SkBitmap& bitmap = m_layerBuffer->context()->platformContext()->canvas()->getTopDevice()->accessBitmap(true);
SkColor textColor = m_textCompositeColor.rgb();
for (int y = 0; y < m_layerSize.height(); y++) {
uint32_t* row = bitmap.getAddr32(0, y);
@@ -502,7 +502,7 @@ void TransparencyWin::makeLayerOpaque()
return;
SkBitmap& bitmap = const_cast<SkBitmap&>(m_drawContext->platformContext()->
- canvas()->getTopPlatformDevice().accessBitmap(true));
+ canvas()->getTopDevice()->accessBitmap(true));
for (int y = 0; y < m_layerSize.height(); y++) {
uint32_t* row = bitmap.getAddr32(0, y);
for (int x = 0; x < m_layerSize.width(); x++)
diff --git a/Source/WebCore/platform/graphics/chromium/UniscribeHelper.cpp b/Source/WebCore/platform/graphics/chromium/UniscribeHelper.cpp
index dda84a9..524beec 100644
--- a/Source/WebCore/platform/graphics/chromium/UniscribeHelper.cpp
+++ b/Source/WebCore/platform/graphics/chromium/UniscribeHelper.cpp
@@ -31,45 +31,16 @@
#include "config.h"
#include "UniscribeHelper.h"
-#include <windows.h>
-
+#include "Font.h"
#include "FontUtilsChromiumWin.h"
#include "PlatformContextSkia.h"
#include "SkiaFontWin.h"
#include "SkPoint.h"
+#include <windows.h>
#include <wtf/Assertions.h>
namespace WebCore {
-// This function is used to see where word spacing should be applied inside
-// runs. Note that this must match Font::treatAsSpace so we all agree where
-// and how much space this is, so we don't want to do more general Unicode
-// "is this a word break" thing.
-static bool treatAsSpace(UChar c)
-{
- return c == ' ' || c == '\t' || c == '\n' || c == 0x00A0;
-}
-
-// SCRIPT_FONTPROPERTIES contains glyph indices for default, invalid
-// and blank glyphs. Just because ScriptShape succeeds does not mean
-// that a text run is rendered correctly. Some characters may be rendered
-// with default/invalid/blank glyphs. Therefore, we need to check if the glyph
-// array returned by ScriptShape contains any of those glyphs to make
-// sure that the text run is rendered successfully.
-static bool containsMissingGlyphs(WORD *glyphs,
- int length,
- SCRIPT_FONTPROPERTIES* properties)
-{
- for (int i = 0; i < length; ++i) {
- if (glyphs[i] == properties->wgDefault
- || (glyphs[i] == properties->wgInvalid
- && glyphs[i] != properties->wgBlank))
- return true;
- }
-
- return false;
-}
-
// HFONT is the 'incarnation' of 'everything' about font, but it's an opaque
// handle and we can't directly query it to make a new HFONT sharing
// its characteristics (height, style, etc) except for family name.
@@ -102,13 +73,15 @@ UniscribeHelper::UniscribeHelper(const UChar* input,
bool isRtl,
HFONT hfont,
SCRIPT_CACHE* scriptCache,
- SCRIPT_FONTPROPERTIES* fontProperties)
+ SCRIPT_FONTPROPERTIES* fontProperties,
+ WORD spaceGlyph)
: m_input(input)
, m_inputLength(inputLength)
, m_isRtl(isRtl)
, m_hfont(hfont)
, m_scriptCache(scriptCache)
, m_fontProperties(fontProperties)
+ , m_spaceGlyph(spaceGlyph)
, m_directionalOverride(false)
, m_inhibitLigate(false)
, m_letterSpacing(0)
@@ -546,6 +519,7 @@ bool UniscribeHelper::shape(const UChar* input,
SCRIPT_CACHE* scriptCache = m_scriptCache;
SCRIPT_FONTPROPERTIES* fontProperties = m_fontProperties;
int ascent = m_ascent;
+ WORD spaceGlyph = m_spaceGlyph;
HDC tempDC = 0;
HGDIOBJ oldFont = 0;
HRESULT hr;
@@ -601,7 +575,7 @@ bool UniscribeHelper::shape(const UChar* input,
} else if (hr == E_OUTOFMEMORY) {
numGlyphs *= 2;
continue;
- } else if (SUCCEEDED(hr) && (lastFallbackTried || !containsMissingGlyphs(&shaping.m_glyphs[0], generatedGlyphs, fontProperties)))
+ } else if (SUCCEEDED(hr) && (lastFallbackTried || !containsMissingGlyphs(shaping, run, fontProperties)))
break;
// The current font can't render this run. clear DC and try
@@ -632,7 +606,9 @@ bool UniscribeHelper::shape(const UChar* input,
const UChar *family = getFallbackFamily(input, itemLength,
FontDescription::StandardFamily, 0, 0);
bool fontOk = getDerivedFontData(family, m_style, &m_logfont,
- &ascent, &hfont, &scriptCache);
+ &ascent, &hfont, &scriptCache,
+ &spaceGlyph);
+
if (!fontOk) {
// If this GetDerivedFontData is called from the renderer it
@@ -644,7 +620,8 @@ bool UniscribeHelper::shape(const UChar* input,
// Try again.
fontOk = getDerivedFontData(family, m_style, &m_logfont,
- &ascent, &hfont, &scriptCache);
+ &ascent, &hfont, &scriptCache,
+ &spaceGlyph);
ASSERT(fontOk);
}
@@ -673,6 +650,7 @@ bool UniscribeHelper::shape(const UChar* input,
// because it's not used elsewhere.
shaping.m_hfont = hfont;
shaping.m_scriptCache = scriptCache;
+ shaping.m_spaceGlyph = spaceGlyph;
// The ascent of a font for this run can be different from
// that of the primary font so that we need to keep track of
@@ -806,22 +784,39 @@ void UniscribeHelper::adjustSpaceAdvances()
for (size_t run = 0; run < m_runs.size(); run++) {
Shaping& shaping = m_shapes[run];
+ // FIXME: This loop is not UTF-16-safe. Unicode 6.0 has a couple
+ // of complex script blocks in Plane 1.
for (int i = 0; i < shaping.charLength(); i++) {
- if (!treatAsSpace(m_input[m_runs[run].iCharPos + i]))
+ UChar c = m_input[m_runs[run].iCharPos + i];
+ bool treatAsSpace = Font::treatAsSpace(c);
+ if (!treatAsSpace && !Font::treatAsZeroWidthSpaceInComplexScript(c))
continue;
int glyphIndex = shaping.m_logs[i];
int currentAdvance = shaping.m_advance[glyphIndex];
- // currentAdvance does not include additional letter-spacing, but
- // space_width does. Here we find out how off we are from the
- // correct width for the space not including letter-spacing, then
- // just subtract that diff.
- int diff = currentAdvance - spaceWidthWithoutLetterSpacing;
- // The shaping can consist of a run of text, so only subtract the
- // difference in the width of the glyph.
- shaping.m_advance[glyphIndex] -= diff;
- shaping.m_abc.abcB -= diff;
+ if (treatAsSpace) {
+ // currentAdvance does not include additional letter-spacing,
+ // but m_spaceWidth does. Here we find out how off we are from
+ // the correct width (spaceWidthWithoutLetterSpacing) and
+ // just subtract that diff.
+ int diff = currentAdvance - spaceWidthWithoutLetterSpacing;
+ // The shaping can consist of a run of text, so only subtract
+ // the difference in the width of the glyph.
+ shaping.m_advance[glyphIndex] -= diff;
+ shaping.m_abc.abcB -= diff;
+ continue;
+ }
+
+ // For characters treated as zero-width space in complex
+ // scripts, set the advance width to zero, adjust
+ // |abcB| of the current run accordingly and set
+ // the glyph to m_spaceGlyph (invisible).
+ shaping.m_advance[glyphIndex] = 0;
+ shaping.m_abc.abcB -= currentAdvance;
+ shaping.m_offsets[glyphIndex].du = 0;
+ shaping.m_offsets[glyphIndex].dv = 0;
+ shaping.m_glyphs[glyphIndex] = shaping.m_spaceGlyph;
}
}
}
@@ -872,7 +867,7 @@ void UniscribeHelper::applySpacing()
// extra wordspacing amount for the glyphs they correspond to.
if (m_wordSpacing != 0) {
for (int i = 0; i < shaping.charLength(); i++) {
- if (!treatAsSpace(m_input[m_runs[run].iCharPos + i]))
+ if (!Font::treatAsSpace(m_input[m_runs[run].iCharPos + i]))
continue;
// The char in question is a word separator...
@@ -929,4 +924,31 @@ int UniscribeHelper::advanceForItem(int itemIndex) const
return shaping.m_prePadding + justification;
}
+// SCRIPT_FONTPROPERTIES contains glyph indices for default, invalid
+// and blank glyphs. Just because ScriptShape succeeds does not mean
+// that a text run is rendered correctly. Some characters may be rendered
+// with default/invalid/blank glyphs. Therefore, we need to check if the glyph
+// array returned by ScriptShape contains any of those glyphs to make
+// sure that the text run is rendered successfully.
+// However, we should not subject zero-width characters to this test.
+
+bool UniscribeHelper::containsMissingGlyphs(const Shaping& shaping,
+ const SCRIPT_ITEM& run,
+ const SCRIPT_FONTPROPERTIES* properties) const
+{
+ for (int i = 0; i < shaping.charLength(); i++) {
+ UChar c = m_input[run.iCharPos + i];
+ // Skip zero-width space characters because they're not considered to be missing in a font.
+ if (Font::treatAsZeroWidthSpaceInComplexScript(c))
+ continue;
+ int glyphIndex = shaping.m_logs[i];
+ WORD glyph = shaping.m_glyphs[glyphIndex];
+ if (glyph == properties->wgDefault
+ || (glyph == properties->wgInvalid && glyph != properties->wgBlank))
+ return true;
+ }
+ return false;
+}
+
+
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/chromium/UniscribeHelper.h b/Source/WebCore/platform/graphics/chromium/UniscribeHelper.h
index ffd57db..4bcdbd6 100644
--- a/Source/WebCore/platform/graphics/chromium/UniscribeHelper.h
+++ b/Source/WebCore/platform/graphics/chromium/UniscribeHelper.h
@@ -76,7 +76,8 @@ public:
bool isRtl,
HFONT,
SCRIPT_CACHE*,
- SCRIPT_FONTPROPERTIES*);
+ SCRIPT_FONTPROPERTIES*,
+ WORD);
virtual ~UniscribeHelper();
@@ -225,7 +226,9 @@ private:
: m_prePadding(0)
, m_hfont(NULL)
, m_scriptCache(NULL)
- , m_ascentOffset(0) {
+ , m_ascentOffset(0)
+ , m_spaceGlyph(0)
+ {
m_abc.abcA = 0;
m_abc.abcB = 0;
m_abc.abcC = 0;
@@ -319,6 +322,8 @@ private:
// when drawing a string, to align multiple runs rendered with
// different fonts.
int m_ascentOffset;
+
+ WORD m_spaceGlyph;
};
// Computes the runs_ array from the text run.
@@ -343,6 +348,10 @@ private:
// Returns the total width of a single item.
int advanceForItem(int) const;
+ bool containsMissingGlyphs(const Shaping&,
+ const SCRIPT_ITEM&,
+ const SCRIPT_FONTPROPERTIES*) const;
+
// Shapes a run (pointed to by |input|) using |hfont| first.
// Tries a series of fonts specified retrieved with NextWinFontData
// and finally a font covering characters in |*input|. A string pointed
@@ -384,6 +393,7 @@ private:
int m_ascent;
LOGFONT m_logfont;
int m_style;
+ WORD m_spaceGlyph;
// Options, see the getters/setters above.
bool m_directionalOverride;
diff --git a/Source/WebCore/platform/graphics/chromium/UniscribeHelperTextRun.cpp b/Source/WebCore/platform/graphics/chromium/UniscribeHelperTextRun.cpp
index c060b43..8e0bc04 100644
--- a/Source/WebCore/platform/graphics/chromium/UniscribeHelperTextRun.cpp
+++ b/Source/WebCore/platform/graphics/chromium/UniscribeHelperTextRun.cpp
@@ -43,7 +43,8 @@ UniscribeHelperTextRun::UniscribeHelperTextRun(const TextRun& run,
: UniscribeHelper(run.characters(), run.length(), run.rtl(),
font.primaryFont()->platformData().hfont(),
font.primaryFont()->platformData().scriptCache(),
- font.primaryFont()->platformData().scriptFontProperties())
+ font.primaryFont()->platformData().scriptFontProperties(),
+ font.primaryFont()->spaceGlyph())
, m_font(&font)
, m_fontIndex(0)
{
@@ -69,7 +70,7 @@ UniscribeHelperTextRun::UniscribeHelperTextRun(
SCRIPT_CACHE* scriptCache,
SCRIPT_FONTPROPERTIES* fontProperties)
: UniscribeHelper(input, inputLength, isRtl, hfont,
- scriptCache, fontProperties)
+ scriptCache, fontProperties, 0)
, m_font(0)
, m_fontIndex(-1)
{
diff --git a/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
index 182e730..e75df24 100644
--- a/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
@@ -96,7 +96,7 @@ void VideoLayerChromium::cleanupResources()
void VideoLayerChromium::updateCompositorResources()
{
- if (!m_contentsDirty)
+ if (!m_contentsDirty || !m_owner)
return;
RenderLayerBacking* backing = static_cast<RenderLayerBacking*>(m_owner->client());
diff --git a/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp
index 652e752..aef14ed 100644
--- a/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp
@@ -51,6 +51,12 @@ WebGLLayerChromium::WebGLLayerChromium(GraphicsLayerChromium* owner)
{
}
+WebGLLayerChromium::~WebGLLayerChromium()
+{
+ if (m_context && layerRenderer())
+ layerRenderer()->removeChildContext(m_context);
+}
+
void WebGLLayerChromium::updateCompositorResources()
{
if (!m_contentsDirty)
@@ -70,6 +76,9 @@ void WebGLLayerChromium::updateCompositorResources()
}
// Update the contents of the texture used by the compositor.
if (m_contentsDirty && m_textureUpdated) {
+ // prepareTexture copies the contents of the off-screen render target into the texture
+ // used by the compositor.
+ //
m_context->prepareTexture();
m_context->markLayerComposited();
m_contentsDirty = false;
@@ -84,6 +93,13 @@ void WebGLLayerChromium::setTextureUpdated()
void WebGLLayerChromium::setContext(const GraphicsContext3D* context)
{
+ if (m_context != context && layerRenderer()) {
+ if (m_context)
+ layerRenderer()->removeChildContext(m_context);
+ if (context)
+ layerRenderer()->addChildContext(const_cast<GraphicsContext3D*>(context));
+ }
+
m_context = const_cast<GraphicsContext3D*>(context);
unsigned int textureId = m_context->platformTexture();
@@ -95,5 +111,19 @@ void WebGLLayerChromium::setContext(const GraphicsContext3D* context)
m_premultipliedAlpha = m_context->getContextAttributes().premultipliedAlpha;
}
+void WebGLLayerChromium::setLayerRenderer(LayerRendererChromium* newLayerRenderer)
+{
+ if (layerRenderer() != newLayerRenderer) {
+ if (m_context) {
+ if (layerRenderer())
+ layerRenderer()->removeChildContext(m_context);
+ if (newLayerRenderer)
+ newLayerRenderer->addChildContext(m_context);
+ }
+
+ LayerChromium::setLayerRenderer(newLayerRenderer);
+ }
+}
+
}
#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h b/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h
index 33db730..342275b 100644
--- a/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h
@@ -44,12 +44,17 @@ class GraphicsContext3D;
class WebGLLayerChromium : public CanvasLayerChromium {
public:
static PassRefPtr<WebGLLayerChromium> create(GraphicsLayerChromium* owner = 0);
+
+ virtual ~WebGLLayerChromium();
+
virtual bool drawsContent() const { return m_context; }
virtual void updateCompositorResources();
void setTextureUpdated();
void setContext(const GraphicsContext3D* context);
+ virtual void setLayerRenderer(LayerRendererChromium*);
+
protected:
virtual const char* layerTypeAsString() const { return "WebGLLayer"; }
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.cpp
index 649d049..d70e15c 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.cpp
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.cpp
@@ -47,7 +47,7 @@ CCCanvasLayerImpl::~CCCanvasLayerImpl()
{
}
-void CCCanvasLayerImpl::draw()
+void CCCanvasLayerImpl::draw(const IntRect&)
{
ASSERT(layerRenderer());
const CCCanvasLayerImpl::Program* program = layerRenderer()->canvasLayerProgram();
@@ -77,4 +77,3 @@ void CCCanvasLayerImpl::dumpLayerProperties(TextStream& ts, int indent) const
}
#endif // USE(ACCELERATED_COMPOSITING)
-
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.h b/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.h
index 8cbf8d1..3aa917c 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.h
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.h
@@ -42,7 +42,7 @@ public:
typedef ProgramBinding<VertexShaderPosTex, FragmentShaderRGBATexFlipAlpha> Program;
- virtual void draw();
+ virtual void draw(const IntRect&);
virtual void dumpLayerProperties(TextStream&, int indent) const;
@@ -58,4 +58,3 @@ private:
}
#endif // CCCanvasLayerImpl_h
-
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCCompletionEvent.h b/Source/WebCore/platform/graphics/chromium/cc/CCCompletionEvent.h
new file mode 100644
index 0000000..a8ac151
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCCompletionEvent.h
@@ -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 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 CCCompletionEvent_h
+#define CCCompletionEvent_h
+
+#include <wtf/ThreadingPrimitives.h>
+
+namespace WebCore {
+
+class CCCompletionEvent {
+public:
+ CCCompletionEvent()
+ {
+ m_mutex.lock();
+ }
+
+ ~CCCompletionEvent()
+ {
+ m_mutex.unlock();
+ }
+
+ void wait()
+ {
+ m_condition.wait(m_mutex);
+ }
+
+ void signal()
+ {
+ MutexLocker lock(m_mutex);
+ m_condition.signal();
+ }
+
+private:
+ Mutex m_mutex;
+ ThreadCondition m_condition;
+};
+
+}
+
+#endif
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp
index 404944b..d22b098 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp
@@ -44,13 +44,30 @@ namespace WebCore {
using namespace std;
CCHeadsUpDisplay::CCHeadsUpDisplay(LayerRendererChromium* owner)
- : m_currentFrameNumber(0)
+ : m_currentFrameNumber(1)
+ , m_filteredFrameTime(0)
, m_layerRenderer(owner)
, m_showFPSCounter(false)
, m_showPlatformLayerTree(false)
{
m_presentTimeHistoryInSec[0] = currentTime();
m_presentTimeHistoryInSec[1] = m_presentTimeHistoryInSec[0];
+ for (int i = 2; i < kPresentHistorySize; i++)
+ m_presentTimeHistoryInSec[i] = 0;
+
+ FontDescription mediumFontDesc;
+ mediumFontDesc.setGenericFamily(FontDescription::MonospaceFamily);
+ mediumFontDesc.setComputedSize(20);
+
+ m_mediumFont = adoptPtr(new Font(mediumFontDesc, 0, 0));
+ m_mediumFont->update(0);
+
+ FontDescription smallFontDesc;
+ smallFontDesc.setGenericFamily(FontDescription::MonospaceFamily);
+ smallFontDesc.setComputedSize(10);
+
+ m_smallFont = adoptPtr(new Font(smallFontDesc, 0, 0));
+ m_smallFont->update(0);
}
CCHeadsUpDisplay::~CCHeadsUpDisplay()
@@ -79,7 +96,7 @@ void CCHeadsUpDisplay::draw()
PlatformCanvas canvas;
canvas.resize(hudSize);
{
- PlatformCanvas::Painter painter(&canvas);
+ PlatformCanvas::Painter painter(&canvas, PlatformCanvas::Painter::GrayscaleText);
drawHudContents(painter.context(), hudSize);
}
@@ -92,7 +109,7 @@ void CCHeadsUpDisplay::draw()
}
// Draw the HUD onto the default render surface.
- const ContentLayerChromium::Program* program = m_layerRenderer->contentLayerProgram();
+ const LayerTilerChromium::Program* program = m_layerRenderer->tilerProgram();
ASSERT(program && program->initialized());
GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
m_hudTexture->bindTexture();
@@ -111,59 +128,98 @@ void CCHeadsUpDisplay::draw()
void CCHeadsUpDisplay::drawHudContents(GraphicsContext* ctx, const IntSize& hudSize)
{
- FontDescription mediumFontDesc;
- mediumFontDesc.setGenericFamily(FontDescription::MonospaceFamily);
- mediumFontDesc.setComputedSize(12);
- Font mediumFont(mediumFontDesc, 0, 0);
- mediumFont.update(0);
-
- FontDescription smallFontDesc;
- smallFontDesc.setGenericFamily(FontDescription::MonospaceFamily);
- smallFontDesc.setComputedSize(10);
- Font smallFont(smallFontDesc, 0, 0);
- smallFont.update(0);
-
- // We haven't finished rendering yet, so we don't now the "current" present time.
- // So, consider the *last two* present times and use those as our present time.
- double secForLastFrame = m_presentTimeHistoryInSec[(m_currentFrameNumber - 1) % 2] - m_presentTimeHistoryInSec[m_currentFrameNumber % 2];
-
- int y = 14;
-
if (m_showPlatformLayerTree) {
ctx->setFillColor(Color(0, 0, 0, 192), ColorSpaceDeviceRGB);
ctx->fillRect(FloatRect(0, 0, hudSize.width(), hudSize.height()));
}
- // Draw fps.
- String topLine = "";
- if (secForLastFrame > 0 && m_showFPSCounter) {
- double fps = 1.0 / secForLastFrame;
- topLine += String::format("FPS: %3.1f", fps);
- }
- if (topLine.length()) {
- ctx->setFillColor(Color(0, 0, 0, 255), ColorSpaceDeviceRGB);
- TextRun run(topLine);
- ctx->fillRect(FloatRect(2, 2, mediumFont.width(run) + 2.0f, 15));
+ int fpsCounterHeight = m_mediumFont->fontMetrics().floatHeight() + 2;
+ int fpsCounterTop = 2;
+ int platformLayerTreeTop;
+ if (m_showFPSCounter)
+ platformLayerTreeTop = fpsCounterTop + fpsCounterHeight + 2;
+ else
+ platformLayerTreeTop = 0;
+
+ if (m_showFPSCounter)
+ drawFPSCounter(ctx, fpsCounterTop, fpsCounterHeight);
+
+ if (m_showPlatformLayerTree)
+ drawPlatformLayerTree(ctx, platformLayerTreeTop);
+}
+
+void CCHeadsUpDisplay::drawFPSCounter(GraphicsContext* ctx, int top, int height)
+{
+ // Note that since we haven't finished the current frame, the FPS counter
+ // actually reports the last frame's time.
+ double secForLastFrame = m_presentTimeHistoryInSec[(m_currentFrameNumber + kPresentHistorySize - 1) % kPresentHistorySize] -
+ m_presentTimeHistoryInSec[(m_currentFrameNumber + kPresentHistorySize - 2) % kPresentHistorySize];
+
+ // Filter the frame times to avoid spikes.
+ const float alpha = 0.1;
+ if (!m_filteredFrameTime) {
+ if (m_currentFrameNumber == 2)
+ m_filteredFrameTime = secForLastFrame;
+ } else
+ m_filteredFrameTime = ((1.0 - alpha) * m_filteredFrameTime) + (alpha * secForLastFrame);
+
+ // Create & measure FPS text.
+ String text(String::format("FPS: %5.1f", 1.0 / m_filteredFrameTime));
+ TextRun run(text);
+ float textWidth = m_mediumFont->width(run) + 2.0f;
+ float graphWidth = kPresentHistorySize;
+
+ // Draw background.
+ ctx->setFillColor(Color(0, 0, 0, 255), ColorSpaceDeviceRGB);
+ ctx->fillRect(FloatRect(2, top, textWidth + graphWidth, height));
+
+ // Draw FPS text.
+ if (m_filteredFrameTime) {
ctx->setFillColor(Color(255, 0, 0), ColorSpaceDeviceRGB);
- ctx->drawText(mediumFont, run, IntPoint(3, y));
- y = 26;
+ ctx->drawText(*m_mediumFont, run, IntPoint(3, top + height - 6));
}
- // Draw layer tree, if enabled.
- if (m_showPlatformLayerTree) {
- ctx->setFillColor(Color(255, 0, 0), ColorSpaceDeviceRGB);
- Vector<String> lines;
- m_layerRenderer->layerTreeAsText().split('\n', lines);
- for (size_t i = 0; i < lines.size(); ++i) {
- ctx->drawText(smallFont, TextRun(lines[i]), IntPoint(2, y));
- y += 12;
- }
+ // Draw FPS graph.
+ const double loFPS = 0.0;
+ const double hiFPS = 120.0;
+ ctx->setStrokeStyle(SolidStroke);
+ ctx->setStrokeColor(Color(255, 0, 0), ColorSpaceDeviceRGB);
+ int graphLeft = static_cast<int>(textWidth + 3);
+ IntPoint prev(-1, 0);
+ int x = 0;
+ double h = static_cast<double>(height - 2);
+ for (int i = m_currentFrameNumber % kPresentHistorySize; i != (m_currentFrameNumber - 1) % kPresentHistorySize; i = (i + 1) % kPresentHistorySize) {
+ int j = (i + 1) % kPresentHistorySize;
+ double fps = 1.0 / (m_presentTimeHistoryInSec[j] - m_presentTimeHistoryInSec[i]);
+ double p = 1 - ((fps - loFPS) / (hiFPS - loFPS));
+ if (p < 0)
+ p = 0;
+ if (p > 1)
+ p = 1;
+ IntPoint cur(graphLeft + x, 1 + top + p*h);
+ if (prev.x() != -1)
+ ctx->drawLine(prev, cur);
+ prev = cur;
+ x += 1;
+ }
+}
+
+void CCHeadsUpDisplay::drawPlatformLayerTree(GraphicsContext* ctx, int top)
+{
+ float smallFontHeight = m_smallFont->fontMetrics().floatHeight();
+ int y = top + smallFontHeight - 4;
+ ctx->setFillColor(Color(255, 0, 0), ColorSpaceDeviceRGB);
+ Vector<String> lines;
+ m_layerRenderer->layerTreeAsText().split('\n', lines);
+ for (size_t i = 0; i < lines.size(); ++i) {
+ ctx->drawText(*m_smallFont, TextRun(lines[i]), IntPoint(2, y));
+ y += smallFontHeight;
}
}
void CCHeadsUpDisplay::onPresent()
{
- m_presentTimeHistoryInSec[m_currentFrameNumber % 2] = currentTime();
+ m_presentTimeHistoryInSec[m_currentFrameNumber % kPresentHistorySize] = currentTime();
m_currentFrameNumber += 1;
}
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.h b/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.h
index d56f8ab..09f198a 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.h
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.h
@@ -27,8 +27,10 @@
#if USE(ACCELERATED_COMPOSITING)
+#include "Font.h"
#include "LayerRendererChromium.h"
+
namespace WebCore {
class GeometryBinding;
@@ -59,17 +61,26 @@ public:
private:
explicit CCHeadsUpDisplay(LayerRendererChromium* owner);
void drawHudContents(GraphicsContext*, const IntSize& hudSize);
+ void drawFPSCounter(GraphicsContext*, int top, int height);
+ void drawPlatformLayerTree(GraphicsContext*, int top);
+
int m_currentFrameNumber;
+ double m_filteredFrameTime;
+
OwnPtr<LayerTexture> m_hudTexture;
LayerRendererChromium* m_layerRenderer;
- double m_presentTimeHistoryInSec[2];
+ static const int kPresentHistorySize = 64;
+ double m_presentTimeHistoryInSec[kPresentHistorySize];
bool m_showFPSCounter;
bool m_showPlatformLayerTree;
+
+ OwnPtr<Font> m_smallFont;
+ OwnPtr<Font> m_mediumFont;
};
}
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp
index 9411e5a..e2d651d 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp
@@ -126,12 +126,12 @@ bool CCLayerImpl::descendantsDrawsContent()
// These belong on CCLayerImpl, but should be overridden by each type and not defer to the LayerChromium subtypes.
bool CCLayerImpl::drawsContent() const
{
- return m_owner->drawsContent();
+ return m_owner && m_owner->drawsContent();
}
-void CCLayerImpl::draw()
+void CCLayerImpl::draw(const IntRect& targetSurfaceRect)
{
- return m_owner->draw();
+ return m_owner->draw(targetSurfaceRect);
}
void CCLayerImpl::updateCompositorResources()
@@ -215,4 +215,3 @@ void CCLayerImpl::dumpLayerProperties(TextStream& ts, int indent) const
}
#endif // USE(ACCELERATED_COMPOSITING)
-
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h
index 96c4f1b..649f4dd 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h
@@ -50,6 +50,7 @@ public:
}
// When this class gets subclasses, remember to add 'virtual' here.
virtual ~CCLayerImpl();
+ void resetOwner() { m_owner = 0; }
#ifndef NDEBUG
int debugID() const { return m_debugID; }
@@ -59,7 +60,7 @@ public:
CCLayerImpl* maskLayer() const;
CCLayerImpl* replicaLayer() const;
- virtual void draw();
+ virtual void draw(const IntRect& contentRect);
virtual void updateCompositorResources();
void unreserveContentsTexture();
void bindContentsTexture();
@@ -205,4 +206,3 @@ private:
}
#endif // CCLayerImpl_h
-
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCMainThread.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCMainThread.cpp
new file mode 100644
index 0000000..cd36817
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCMainThread.cpp
@@ -0,0 +1,46 @@
+/*
+ * 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 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.
+ */
+#include "config.h"
+
+#include "CCMainThread.h"
+
+#include <wtf/MainThread.h>
+
+using namespace WTF;
+
+namespace WebCore {
+
+void CCMainThread::performTask(void* userdata)
+{
+ Task* task = static_cast<Task*>(userdata);
+ task->performTask();
+ delete task;
+}
+
+void CCMainThread::postTask(PassOwnPtr<Task> task)
+{
+ callOnMainThread(performTask, task.leakPtr());
+}
+
+}
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCMainThread.h b/Source/WebCore/platform/graphics/chromium/cc/CCMainThread.h
new file mode 100644
index 0000000..ca8e8c1
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCMainThread.h
@@ -0,0 +1,53 @@
+/*
+ * 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 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 CCMainThread_h
+#define CCMainThread_h
+
+#include <wtf/Noncopyable.h>
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+// Task wrapper around WTF::callOnMainThreadThread
+class CCMainThread {
+public:
+ class Task {
+ WTF_MAKE_NONCOPYABLE(Task);
+ public:
+ virtual ~Task() { }
+ virtual void performTask() = 0;
+ void* instance() const { return m_instance; }
+ protected:
+ Task(void* instance) : m_instance(instance) { }
+ void* m_instance;
+ };
+
+ static void postTask(PassOwnPtr<Task>); // Executes the task on main thread asynchronously.
+private:
+ static void performTask(void*);
+};
+
+} // namespace WebCore
+
+#endif // CCMainThread_h
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCMainThreadTask.h b/Source/WebCore/platform/graphics/chromium/cc/CCMainThreadTask.h
new file mode 100644
index 0000000..7de8d71
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCMainThreadTask.h
@@ -0,0 +1,220 @@
+/*
+ * 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 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 CCMainThreadTask_h
+#define CCMainThreadTask_h
+
+#include "CCMainThread.h"
+#include "CrossThreadCopier.h"
+#include "CrossThreadTask.h"
+#include <wtf/PassOwnPtr.h>
+#include <wtf/PassRefPtr.h>
+
+namespace WebCore {
+
+template<typename T>
+class MainThreadTask0 : public CCMainThread::Task {
+public:
+ typedef void (T::*Method)();
+ typedef MainThreadTask0<T> MainThreadTaskImpl;
+
+ static PassOwnPtr<MainThreadTaskImpl> create(T* instance, Method method)
+ {
+ return adoptPtr(new MainThreadTaskImpl(instance, method));
+ }
+
+private:
+ MainThreadTask0(T* instance, Method method)
+ : CCMainThread::Task(instance)
+ , m_method(method)
+ {
+ }
+
+ virtual void performTask()
+ {
+ (*static_cast<T*>(instance()).*m_method)();
+ }
+
+private:
+ Method m_method;
+};
+
+template<typename T, typename P1, typename MP1>
+class MainThreadTask1 : public CCMainThread::Task {
+public:
+ typedef void (T::*Method)(MP1);
+ typedef MainThreadTask1<T, P1, MP1> MainThreadTaskImpl;
+ typedef typename CrossThreadTaskTraits<P1>::ParamType Param1;
+
+ static PassOwnPtr<MainThreadTaskImpl> create(T* instance, Method method, Param1 parameter1)
+ {
+ return adoptPtr(new MainThreadTaskImpl(instance, method, parameter1));
+ }
+
+private:
+ MainThreadTask1(T* instance, Method method, Param1 parameter1)
+ : CCMainThread::Task(instance)
+ , m_method(method)
+ , m_parameter1(parameter1)
+ {
+ }
+
+ virtual void performTask()
+ {
+ (*static_cast<T*>(instance()).*m_method)(m_parameter1);
+ }
+
+private:
+ Method m_method;
+ P1 m_parameter1;
+};
+
+template<typename T, typename P1, typename MP1, typename P2, typename MP2>
+class MainThreadTask2 : public CCMainThread::Task {
+public:
+ typedef void (T::*Method)(MP1, MP2);
+ typedef MainThreadTask2<T, P1, MP1, P2, MP2> MainThreadTaskImpl;
+ typedef typename CrossThreadTaskTraits<P1>::ParamType Param1;
+ typedef typename CrossThreadTaskTraits<P2>::ParamType Param2;
+
+ static PassOwnPtr<MainThreadTaskImpl> create(T* instance, Method method, Param1 parameter1, Param2 parameter2)
+ {
+ return adoptPtr(new MainThreadTaskImpl(instance, method, parameter1, parameter2));
+ }
+
+private:
+ MainThreadTask2(T* instance, Method method, Param1 parameter1, Param2 parameter2)
+ : CCMainThread::Task(instance)
+ , m_method(method)
+ , m_parameter1(parameter1)
+ , m_parameter2(parameter2)
+ {
+ }
+
+ virtual void performTask()
+ {
+ (*static_cast<T*>(instance()).*m_method)(m_parameter1, m_parameter2);
+ }
+
+private:
+ Method m_method;
+ P1 m_parameter1;
+ P2 m_parameter2;
+};
+
+template<typename T, typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3>
+class MainThreadTask3 : public CCMainThread::Task {
+public:
+ typedef void (T::*Method)(MP1, MP2, MP3);
+ typedef MainThreadTask3<T, P1, MP1, P2, MP2, P3, MP3> MainThreadTaskImpl;
+ typedef typename CrossThreadTaskTraits<P1>::ParamType Param1;
+ typedef typename CrossThreadTaskTraits<P2>::ParamType Param2;
+ typedef typename CrossThreadTaskTraits<P3>::ParamType Param3;
+
+ static PassOwnPtr<MainThreadTaskImpl> create(T* instance, Method method, Param1 parameter1, Param2 parameter2, Param3 parameter3)
+ {
+ return adoptPtr(new MainThreadTaskImpl(instance, method, parameter1, parameter2, parameter3));
+ }
+
+private:
+ MainThreadTask3(T* instance, Method method, Param1 parameter1, Param2 parameter2, Param3 parameter3)
+ : CCMainThread::Task(instance)
+ , m_method(method)
+ , m_parameter1(parameter1)
+ , m_parameter2(parameter2)
+ , m_parameter3(parameter3)
+ {
+ }
+
+ virtual void performTask()
+ {
+ (*static_cast<T*>(instance()).*m_method)(m_parameter1, m_parameter2, m_parameter3);
+ }
+
+private:
+ Method m_method;
+ P1 m_parameter1;
+ P2 m_parameter2;
+ P3 m_parameter3;
+};
+
+template<typename T>
+PassOwnPtr<CCMainThread::Task> createMainThreadTask(
+ T* const callee,
+ void (T::*method)());
+
+template<typename T>
+PassOwnPtr<CCMainThread::Task> createMainThreadTask(
+ T* const callee,
+ void (T::*method)())
+{
+ return MainThreadTask0<T>::create(
+ callee,
+ method);
+}
+
+template<typename T, typename P1, typename MP1>
+PassOwnPtr<CCMainThread::Task> createMainThreadTask(
+ T* const callee,
+ void (T::*method)(MP1),
+ const P1& parameter1)
+{
+ return MainThreadTask1<T, typename CrossThreadCopier<P1>::Type, MP1>::create(
+ callee,
+ method,
+ CrossThreadCopier<P1>::copy(parameter1));
+}
+
+template<typename T, typename P1, typename MP1, typename P2, typename MP2>
+PassOwnPtr<CCMainThread::Task> createMainThreadTask(
+ T* const callee,
+ void (T::*method)(MP1, MP2),
+ const P1& parameter1,
+ const P2& parameter2)
+{
+ return MainThreadTask2<T, typename CrossThreadCopier<P1>::Type, MP1, typename CrossThreadCopier<P2>::Type, MP2>::create(
+ callee,
+ method,
+ CrossThreadCopier<P1>::copy(parameter1),
+ CrossThreadCopier<P2>::copy(parameter2));
+}
+
+template<typename T, typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3>
+PassOwnPtr<CCMainThread::Task> createMainThreadTask(
+ T* const callee,
+ void (T::*method)(MP1, MP2, MP3),
+ const P1& parameter1,
+ const P2& parameter2,
+ const P3& parameter3)
+{
+ return MainThreadTask3<T, typename CrossThreadCopier<P1>::Type, MP1, typename CrossThreadCopier<P2>::Type, MP2, typename CrossThreadCopier<P3>::Type, MP3>::create(
+ callee,
+ method,
+ CrossThreadCopier<P1>::copy(parameter1),
+ CrossThreadCopier<P2>::copy(parameter2),
+ CrossThreadCopier<P3>::copy(parameter3));
+}
+
+} // namespace WebCore
+
+#endif // CCMainThreadTask_h
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.cpp
index 4aef639..a428829 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.cpp
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.cpp
@@ -46,7 +46,7 @@ CCPluginLayerImpl::~CCPluginLayerImpl()
{
}
-void CCPluginLayerImpl::draw()
+void CCPluginLayerImpl::draw(const IntRect&)
{
ASSERT(layerRenderer());
const CCPluginLayerImpl::Program* program = layerRenderer()->pluginLayerProgram();
@@ -81,4 +81,3 @@ void CCPluginLayerImpl::dumpLayerProperties(TextStream& ts, int indent) const
}
#endif // USE(ACCELERATED_COMPOSITING)
-
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.h b/Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.h
index 65eb5b7..4fd7457 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.h
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.h
@@ -42,7 +42,7 @@ public:
typedef ProgramBinding<VertexShaderPosTex, FragmentShaderRGBATexFlipAlpha> Program;
- virtual void draw();
+ virtual void draw(const IntRect&);
virtual void dumpLayerProperties(TextStream&, int indent) const;
@@ -57,4 +57,3 @@ private:
}
#endif // CCPluginLayerImpl_h
-
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCThread.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCThread.cpp
new file mode 100644
index 0000000..9566584
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCThread.cpp
@@ -0,0 +1,79 @@
+/*
+ * 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 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.
+ */
+
+#include "config.h"
+
+#include "CCThread.h"
+
+#include "LayerRendererChromium.h"
+#include <wtf/CurrentTime.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/ThreadingPrimitives.h>
+
+namespace WebCore {
+
+using namespace WTF;
+
+CCThread::CCThread()
+{
+ MutexLocker lock(m_threadCreationMutex);
+ m_threadID = createThread(CCThread::compositorThreadStart, this, "Chromium Compositor");
+}
+
+CCThread::~CCThread()
+{
+ m_queue.kill();
+
+ // Stop thread.
+ void* exitCode;
+ waitForThreadCompletion(m_threadID, &exitCode);
+ m_threadID = 0;
+}
+
+void CCThread::postTask(PassOwnPtr<Task> task)
+{
+ m_queue.append(task);
+}
+
+void* CCThread::compositorThreadStart(void* userdata)
+{
+ CCThread* ccThread = static_cast<CCThread*>(userdata);
+ return ccThread->runLoop();
+}
+
+void* CCThread::runLoop()
+{
+ {
+ // Wait for CCThread::start() to complete to have m_threadID
+ // established before starting the main loop.
+ MutexLocker lock(m_threadCreationMutex);
+ }
+
+ while (OwnPtr<Task> task = m_queue.waitForMessage())
+ task->performTask();
+
+ return 0;
+}
+
+}
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCThread.h b/Source/WebCore/platform/graphics/chromium/cc/CCThread.h
new file mode 100644
index 0000000..177d3f3
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCThread.h
@@ -0,0 +1,75 @@
+/*
+ * 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 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 CCThread_h
+#define CCThread_h
+
+#include <wtf/MessageQueue.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Threading.h>
+
+namespace WebCore {
+
+// The CCThread singleton owns the compositor thread and provides
+// basic infrastructure for messaging between the two threads.
+class CCThread {
+public:
+ static PassOwnPtr<CCThread> create()
+ {
+ return adoptPtr(new CCThread());
+ }
+
+ virtual ~CCThread();
+
+ class Task {
+ WTF_MAKE_NONCOPYABLE(Task);
+ public:
+ virtual ~Task() { }
+ virtual void performTask() = 0;
+ void* instance() const { return m_instance; }
+ protected:
+ Task(void* instance) : m_instance(instance) { }
+ void* m_instance;
+ };
+
+ void postTask(PassOwnPtr<Task>); // Executes the task on context's thread asynchronously.
+
+ WTF::ThreadIdentifier threadID() const { return m_threadID; }
+
+protected:
+ explicit CCThread();
+
+ static void* compositorThreadStart(void*);
+ void* runLoop();
+
+ WTF::ThreadIdentifier m_threadID;
+ MessageQueue<Task> m_queue;
+
+ Mutex m_threadCreationMutex;
+};
+
+}
+
+#endif
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCThreadTask.h b/Source/WebCore/platform/graphics/chromium/cc/CCThreadTask.h
new file mode 100644
index 0000000..71245d3
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCThreadTask.h
@@ -0,0 +1,279 @@
+/*
+ * 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 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 CCThreadTask_h
+#define CCThreadTask_h
+
+#include "CCThread.h"
+#include "CrossThreadCopier.h"
+#include "CrossThreadTask.h"
+#include <wtf/PassOwnPtr.h>
+#include <wtf/PassRefPtr.h>
+
+namespace WebCore {
+
+template<typename T>
+class CCThreadTask0 : public CCThread::Task {
+public:
+ typedef void (T::*Method)();
+ typedef CCThreadTask0<T> CCThreadTaskImpl;
+
+ static PassOwnPtr<CCThreadTaskImpl> create(T* instance, Method method)
+ {
+ return adoptPtr(new CCThreadTaskImpl(instance, method));
+ }
+
+private:
+ CCThreadTask0(T* instance, Method method)
+ : CCThread::Task(instance)
+ , m_method(method)
+ {
+ }
+
+ virtual void performTask()
+ {
+ (*static_cast<T*>(instance()).*m_method)();
+ }
+
+private:
+ Method m_method;
+};
+
+template<typename T, typename P1, typename MP1>
+class CCThreadTask1 : public CCThread::Task {
+public:
+ typedef void (T::*Method)(MP1);
+ typedef CCThreadTask1<T, P1, MP1> CCThreadTaskImpl;
+ typedef typename CrossThreadTaskTraits<P1>::ParamType Param1;
+
+ static PassOwnPtr<CCThreadTaskImpl> create(T* instance, Method method, Param1 parameter1)
+ {
+ return adoptPtr(new CCThreadTaskImpl(instance, method, parameter1));
+ }
+
+private:
+ CCThreadTask1(T* instance, Method method, Param1 parameter1)
+ : CCThread::Task(instance)
+ , m_method(method)
+ , m_parameter1(parameter1)
+ {
+ }
+
+ virtual void performTask()
+ {
+ (*static_cast<T*>(instance()).*m_method)(m_parameter1);
+ }
+
+private:
+ Method m_method;
+ P1 m_parameter1;
+};
+
+template<typename T, typename P1, typename MP1, typename P2, typename MP2>
+class CCThreadTask2 : public CCThread::Task {
+public:
+ typedef void (T::*Method)(MP1, MP2);
+ typedef CCThreadTask2<T, P1, MP1, P2, MP2> CCThreadTaskImpl;
+ typedef typename CrossThreadTaskTraits<P1>::ParamType Param1;
+ typedef typename CrossThreadTaskTraits<P2>::ParamType Param2;
+
+ static PassOwnPtr<CCThreadTaskImpl> create(T* instance, Method method, Param1 parameter1, Param2 parameter2)
+ {
+ return adoptPtr(new CCThreadTaskImpl(instance, method, parameter1, parameter2));
+ }
+
+private:
+ CCThreadTask2(T* instance, Method method, Param1 parameter1, Param2 parameter2)
+ : CCThread::Task(instance)
+ , m_method(method)
+ , m_parameter1(parameter1)
+ , m_parameter2(parameter2)
+ {
+ }
+
+ virtual void performTask()
+ {
+ (*static_cast<T*>(instance()).*m_method)(m_parameter1, m_parameter2);
+ }
+
+private:
+ Method m_method;
+ P1 m_parameter1;
+ P2 m_parameter2;
+};
+
+template<typename T, typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3>
+class CCThreadTask3 : public CCThread::Task {
+public:
+ typedef void (T::*Method)(MP1, MP2, MP3);
+ typedef CCThreadTask3<T, P1, MP1, P2, MP2, P3, MP3> CCThreadTaskImpl;
+ typedef typename CrossThreadTaskTraits<P1>::ParamType Param1;
+ typedef typename CrossThreadTaskTraits<P2>::ParamType Param2;
+ typedef typename CrossThreadTaskTraits<P3>::ParamType Param3;
+
+ static PassOwnPtr<CCThreadTaskImpl> create(T* instance, Method method, Param1 parameter1, Param2 parameter2, Param3 parameter3)
+ {
+ return adoptPtr(new CCThreadTaskImpl(instance, method, parameter1, parameter2, parameter3));
+ }
+
+private:
+ CCThreadTask3(T* instance, Method method, Param1 parameter1, Param2 parameter2, Param3 parameter3)
+ : CCThread::Task(instance)
+ , m_method(method)
+ , m_parameter1(parameter1)
+ , m_parameter2(parameter2)
+ , m_parameter3(parameter3)
+ {
+ }
+
+ virtual void performTask()
+ {
+ (*static_cast<T*>(instance()).*m_method)(m_parameter1, m_parameter2, m_parameter3);
+ }
+
+private:
+ Method m_method;
+ P1 m_parameter1;
+ P2 m_parameter2;
+ P3 m_parameter3;
+};
+
+
+template<typename T, typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4>
+class CCThreadTask4 : public CCThread::Task {
+public:
+ typedef void (T::*Method)(MP1, MP2, MP3, MP4);
+ typedef CCThreadTask4<T, P1, MP1, P2, MP2, P3, MP3, P4, MP4> CCThreadTaskImpl;
+ typedef typename CrossThreadTaskTraits<P1>::ParamType Param1;
+ typedef typename CrossThreadTaskTraits<P2>::ParamType Param2;
+ typedef typename CrossThreadTaskTraits<P3>::ParamType Param3;
+ typedef typename CrossThreadTaskTraits<P4>::ParamType Param4;
+
+ static PassOwnPtr<CCThreadTaskImpl> create(T* instance, Method method, Param1 parameter1, Param2 parameter2, Param3 parameter3, Param4 parameter4)
+ {
+ return adoptPtr(new CCThreadTaskImpl(instance, method, parameter1, parameter2, parameter3, parameter4));
+ }
+
+private:
+ CCThreadTask4(T* instance, Method method, Param1 parameter1, Param2 parameter2, Param3 parameter3, Param4 parameter4)
+ : CCThread::Task(instance)
+ , m_method(method)
+ , m_parameter1(parameter1)
+ , m_parameter2(parameter2)
+ , m_parameter3(parameter3)
+ , m_parameter4(parameter4)
+ {
+ }
+
+ virtual void performTask()
+ {
+ (*static_cast<T*>(instance()).*m_method)(m_parameter1, m_parameter2, m_parameter3, m_parameter4);
+ }
+
+private:
+ Method m_method;
+ P1 m_parameter1;
+ P2 m_parameter2;
+ P3 m_parameter3;
+ P4 m_parameter4;
+};
+
+template<typename T>
+PassOwnPtr<CCThread::Task> createCCThreadTask(
+ T* const callee,
+ void (T::*method)());
+
+template<typename T>
+PassOwnPtr<CCThread::Task> createCCThreadTask(
+ T* const callee,
+ void (T::*method)())
+{
+ return CCThreadTask0<T>::create(
+ callee,
+ method);
+}
+
+template<typename T, typename P1, typename MP1>
+PassOwnPtr<CCThread::Task> createCCThreadTask(
+ T* const callee,
+ void (T::*method)(MP1),
+ const P1& parameter1)
+{
+ return CCThreadTask1<T, typename CrossThreadCopier<P1>::Type, MP1>::create(
+ callee,
+ method,
+ CrossThreadCopier<P1>::copy(parameter1));
+}
+
+template<typename T, typename P1, typename MP1, typename P2, typename MP2>
+PassOwnPtr<CCThread::Task> createCCThreadTask(
+ T* const callee,
+ void (T::*method)(MP1, MP2),
+ const P1& parameter1,
+ const P2& parameter2)
+{
+ return CCThreadTask2<T, typename CrossThreadCopier<P1>::Type, MP1, typename CrossThreadCopier<P2>::Type, MP2>::create(
+ callee,
+ method,
+ CrossThreadCopier<P1>::copy(parameter1),
+ CrossThreadCopier<P2>::copy(parameter2));
+}
+
+template<typename T, typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3>
+PassOwnPtr<CCThread::Task> createCCThreadTask(
+ T* const callee,
+ void (T::*method)(MP1, MP2, MP3),
+ const P1& parameter1,
+ const P2& parameter2,
+ const P3& parameter3)
+{
+ return CCThreadTask3<T, typename CrossThreadCopier<P1>::Type, MP1, typename CrossThreadCopier<P2>::Type, MP2, typename CrossThreadCopier<P3>::Type, MP3>::create(
+ callee,
+ method,
+ CrossThreadCopier<P1>::copy(parameter1),
+ CrossThreadCopier<P2>::copy(parameter2),
+ CrossThreadCopier<P3>::copy(parameter3));
+}
+
+template<typename T, typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4>
+PassOwnPtr<CCThread::Task> createCCThreadTask(
+ T* const callee,
+ void (T::*method)(MP1, MP2, MP3, MP4),
+ const P1& parameter1,
+ const P2& parameter2,
+ const P3& parameter3,
+ const P4& parameter4)
+{
+ return CCThreadTask4<T, typename CrossThreadCopier<P1>::Type, MP1, typename CrossThreadCopier<P2>::Type, MP2, typename CrossThreadCopier<P3>::Type, MP3, typename CrossThreadCopier<P4>::Type, MP4>::create(
+ callee,
+ method,
+ CrossThreadCopier<P1>::copy(parameter1),
+ CrossThreadCopier<P2>::copy(parameter2),
+ CrossThreadCopier<P3>::copy(parameter3),
+ CrossThreadCopier<P4>::copy(parameter4));
+
+}
+
+} // namespace WebCore
+
+#endif // CCThreadTask_h
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.cpp
index eb3612b..99a148d 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.cpp
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.cpp
@@ -75,7 +75,7 @@ void CCVideoLayerImpl::setTexture(size_t i, VideoLayerChromium::Texture texture)
m_textures[i] = texture;
}
-void CCVideoLayerImpl::draw()
+void CCVideoLayerImpl::draw(const IntRect&)
{
if (m_skipsDraw)
return;
@@ -170,4 +170,3 @@ void CCVideoLayerImpl::dumpLayerProperties(TextStream& ts, int indent) const
}
#endif // USE(ACCELERATED_COMPOSITING)
-
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.h b/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.h
index 62f8778..0e1d1f6 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.h
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.h
@@ -47,7 +47,7 @@ public:
typedef ProgramBinding<VertexShaderPosTexTransform, FragmentShaderRGBATexFlipAlpha> RGBAProgram;
typedef ProgramBinding<VertexShaderPosTexYUVStretch, FragmentShaderYUVVideo> YUVProgram;
- virtual void draw();
+ virtual void draw(const IntRect&);
virtual void dumpLayerProperties(TextStream&, int indent) const;
@@ -72,4 +72,3 @@ private:
}
#endif // CCVideoLayerImpl_h
-
diff --git a/Source/WebCore/platform/graphics/filters/FEFlood.cpp b/Source/WebCore/platform/graphics/filters/FEFlood.cpp
index 3c48cf9..d832d2b 100644
--- a/Source/WebCore/platform/graphics/filters/FEFlood.cpp
+++ b/Source/WebCore/platform/graphics/filters/FEFlood.cpp
@@ -49,9 +49,12 @@ Color FEFlood::floodColor() const
return m_floodColor;
}
-void FEFlood::setFloodColor(const Color& color)
+bool FEFlood::setFloodColor(const Color& color)
{
+ if (m_floodColor == color)
+ return false;
m_floodColor = color;
+ return true;
}
float FEFlood::floodOpacity() const
@@ -59,9 +62,12 @@ float FEFlood::floodOpacity() const
return m_floodOpacity;
}
-void FEFlood::setFloodOpacity(float floodOpacity)
+bool FEFlood::setFloodOpacity(float floodOpacity)
{
+ if (m_floodOpacity == floodOpacity)
+ return false;
m_floodOpacity = floodOpacity;
+ return true;
}
void FEFlood::apply()
diff --git a/Source/WebCore/platform/graphics/filters/FEFlood.h b/Source/WebCore/platform/graphics/filters/FEFlood.h
index 2e8824f..cac4153 100644
--- a/Source/WebCore/platform/graphics/filters/FEFlood.h
+++ b/Source/WebCore/platform/graphics/filters/FEFlood.h
@@ -34,10 +34,10 @@ public:
static PassRefPtr<FEFlood> create(Filter* filter, const Color&, float);
Color floodColor() const;
- void setFloodColor(const Color &);
+ bool setFloodColor(const Color &);
float floodOpacity() const;
- void setFloodOpacity(float);
+ bool setFloodOpacity(float);
virtual void apply();
virtual void dump();
diff --git a/Source/WebCore/platform/graphics/filters/FELighting.cpp b/Source/WebCore/platform/graphics/filters/FELighting.cpp
index ec1ca88..13a69fd 100644
--- a/Source/WebCore/platform/graphics/filters/FELighting.cpp
+++ b/Source/WebCore/platform/graphics/filters/FELighting.cpp
@@ -30,6 +30,13 @@
#include "FELighting.h"
#include "LightSource.h"
+#include "PointLightSource.h"
+#include "SpotLightSource.h"
+
+#if CPU(ARM_NEON) && COMPILER(GCC)
+#include "FELightingNEON.h"
+#include <wtf/Vector.h>
+#endif
namespace WebCore {
@@ -301,6 +308,9 @@ bool FELighting::drawLighting(ByteArray* pixels, int width, int height)
if (width >= 3 && height >= 3) {
// Interior pixels
+#if CPU(ARM_NEON) && COMPILER(GCC)
+ drawInteriorPixels(data, paintingData);
+#else
for (int y = 1; y < data.heightDecreasedByOne; ++y) {
offset = y * data.widthMultipliedByPixelSize + cPixelSize;
for (int x = 1; x < data.widthDecreasedByOne; ++x, offset += cPixelSize) {
@@ -308,6 +318,7 @@ bool FELighting::drawLighting(ByteArray* pixels, int width, int height)
inlineSetPixel(offset, data, paintingData, x, y, cFactor1div4, cFactor1div4, normalVector);
}
}
+#endif
}
int lastPixel = data.widthMultipliedByPixelSize * height;
@@ -354,6 +365,118 @@ void FELighting::apply()
drawLighting(srcPixelArray, absolutePaintSize.width(), absolutePaintSize.height());
}
+#if CPU(ARM_NEON) && COMPILER(GCC)
+
+static int getPowerCoefficients(float exponent)
+{
+ // Calling a powf function from the assembly code would require to save
+ // and reload a lot of NEON registers. Since the base is in range [0..1]
+ // and only 8 bit precision is required, we use our own powf function.
+ // This is probably not the best, but it uses only a few registers and
+ // gives us enough precision (modifying the exponent field directly would
+ // also be possible).
+
+ // First, we limit the exponent to maximum of 64, which gives us enough
+ // precision. We split the exponent to an integer and fraction part,
+ // since a^x = (a^y)*(a^z) where x = y+z. The integer exponent of the
+ // power is estimated by square, and the fraction exponent of the power
+ // is estimated by square root assembly instructions.
+ int i, result;
+
+ if (exponent < 0)
+ exponent = 1 / (-exponent);
+
+ if (exponent > 63.99)
+ exponent = 63.99;
+
+ exponent /= 64;
+ result = 0;
+ for (i = 11; i >= 0; --i) {
+ exponent *= 2;
+ if (exponent >= 1) {
+ result |= 1 << i;
+ exponent -= 1;
+ }
+ }
+ return result;
+}
+
+void FELighting::drawInteriorPixels(LightingData& data, LightSource::PaintingData& paintingData)
+{
+ WTF_ALIGNED(FELightingFloatArgumentsForNeon, floatArguments, 16);
+
+ FELightingPaintingDataForNeon neonData = {
+ data.pixels->data(),
+ data.widthDecreasedByOne - 1,
+ data.heightDecreasedByOne - 1,
+ 0,
+ 0,
+ 0,
+ &floatArguments,
+ feLightingConstantsForNeon()
+ };
+
+ // Set light source arguments.
+ floatArguments.constOne = 1;
+
+ floatArguments.colorRed = m_lightingColor.red();
+ floatArguments.colorGreen = m_lightingColor.green();
+ floatArguments.colorBlue = m_lightingColor.blue();
+ floatArguments.padding4 = 0;
+
+ if (m_lightSource->type() == LS_POINT) {
+ neonData.flags |= FLAG_POINT_LIGHT;
+ PointLightSource* pointLightSource = static_cast<PointLightSource*>(m_lightSource.get());
+ floatArguments.lightX = pointLightSource->position().x();
+ floatArguments.lightY = pointLightSource->position().y();
+ floatArguments.lightZ = pointLightSource->position().z();
+ floatArguments.padding2 = 0;
+ } else if (m_lightSource->type() == LS_SPOT) {
+ neonData.flags |= FLAG_SPOT_LIGHT;
+ SpotLightSource* spotLightSource = static_cast<SpotLightSource*>(m_lightSource.get());
+ floatArguments.lightX = spotLightSource->position().x();
+ floatArguments.lightY = spotLightSource->position().y();
+ floatArguments.lightZ = spotLightSource->position().z();
+ floatArguments.padding2 = 0;
+
+ floatArguments.directionX = paintingData.directionVector.x();
+ floatArguments.directionY = paintingData.directionVector.y();
+ floatArguments.directionZ = paintingData.directionVector.z();
+ floatArguments.padding3 = 0;
+
+ floatArguments.coneCutOffLimit = paintingData.coneCutOffLimit;
+ floatArguments.coneFullLight = paintingData.coneFullLight;
+ floatArguments.coneCutOffRange = paintingData.coneCutOffLimit - paintingData.coneFullLight;
+ neonData.coneExponent = getPowerCoefficients(spotLightSource->specularExponent());
+ if (spotLightSource->specularExponent() == 1)
+ neonData.flags |= FLAG_CONE_EXPONENT_IS_1;
+ } else {
+ ASSERT(m_lightSource.type == LS_DISTANT);
+ floatArguments.lightX = paintingData.lightVector.x();
+ floatArguments.lightY = paintingData.lightVector.y();
+ floatArguments.lightZ = paintingData.lightVector.z();
+ floatArguments.padding2 = 1;
+ }
+
+ // Set lighting arguments.
+ floatArguments.surfaceScale = data.surfaceScale;
+ floatArguments.minusSurfaceScaleDividedByFour = -data.surfaceScale / 4;
+ if (m_lightingType == FELighting::DiffuseLighting)
+ floatArguments.diffuseConstant = m_diffuseConstant;
+ else {
+ neonData.flags |= FLAG_SPECULAR_LIGHT;
+ floatArguments.diffuseConstant = m_specularConstant;
+ neonData.specularExponent = getPowerCoefficients(m_specularExponent);
+ if (m_specularExponent == 1)
+ neonData.flags |= FLAG_SPECULAR_EXPONENT_IS_1;
+ }
+ if (floatArguments.diffuseConstant == 1)
+ neonData.flags |= FLAG_DIFFUSE_CONST_IS_1;
+
+ neonDrawLighting(&neonData);
+}
+#endif // CPU(ARM_NEON) && COMPILER(GCC)
+
} // namespace WebCore
#endif // ENABLE(FILTERS)
diff --git a/Source/WebCore/platform/graphics/filters/FELighting.h b/Source/WebCore/platform/graphics/filters/FELighting.h
index fa1c0aa..3dc46e9 100644
--- a/Source/WebCore/platform/graphics/filters/FELighting.h
+++ b/Source/WebCore/platform/graphics/filters/FELighting.h
@@ -33,6 +33,7 @@
#include "FilterEffect.h"
#include "LightSource.h"
#include <wtf/ByteArray.h>
+#include <wtf/Platform.h>
// Common base class for FEDiffuseLighting and FESpecularLighting
@@ -79,6 +80,10 @@ protected:
void setPixel(int offset, LightingData&, LightSource::PaintingData&,
int lightX, int lightY, float factorX, float factorY, IntPoint& normalVector);
+#if CPU(ARM_NEON) && COMPILER(GCC)
+ void drawInteriorPixels(LightingData&, LightSource::PaintingData&);
+#endif
+
LightingType m_lightingType;
RefPtr<LightSource> m_lightSource;
diff --git a/Source/WebCore/platform/graphics/filters/FESpecularLighting.cpp b/Source/WebCore/platform/graphics/filters/FESpecularLighting.cpp
index a20eb8c..2c7b1eb 100644
--- a/Source/WebCore/platform/graphics/filters/FESpecularLighting.cpp
+++ b/Source/WebCore/platform/graphics/filters/FESpecularLighting.cpp
@@ -54,9 +54,12 @@ Color FESpecularLighting::lightingColor() const
return m_lightingColor;
}
-void FESpecularLighting::setLightingColor(const Color& lightingColor)
+bool FESpecularLighting::setLightingColor(const Color& lightingColor)
{
+ if (m_lightingColor == lightingColor)
+ return false;
m_lightingColor = lightingColor;
+ return true;
}
float FESpecularLighting::surfaceScale() const
diff --git a/Source/WebCore/platform/graphics/filters/FESpecularLighting.h b/Source/WebCore/platform/graphics/filters/FESpecularLighting.h
index 9d3ea2d..9fa3add 100644
--- a/Source/WebCore/platform/graphics/filters/FESpecularLighting.h
+++ b/Source/WebCore/platform/graphics/filters/FESpecularLighting.h
@@ -34,7 +34,7 @@ public:
virtual ~FESpecularLighting();
Color lightingColor() const;
- void setLightingColor(const Color&);
+ bool setLightingColor(const Color&);
float surfaceScale() const;
bool setSurfaceScale(float);
diff --git a/Source/WebCore/platform/graphics/filters/arm/FELightingNEON.cpp b/Source/WebCore/platform/graphics/filters/arm/FELightingNEON.cpp
new file mode 100644
index 0000000..3807f1f
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/arm/FELightingNEON.cpp
@@ -0,0 +1,464 @@
+/*
+ * Copyright (C) 2011 University of Szeged
+ * Copyright (C) 2011 Zoltan Herczeg
+ *
+ * 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"
+#include "FELightingNEON.h"
+
+#if CPU(ARM_NEON) && COMPILER(GCC)
+
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+// These constants are copied to the following SIMD registers:
+// ALPHAX_Q ALPHAY_Q REMAPX_D REMAPY_D
+
+WTF_ALIGNED(short, s_FELightingConstantsForNeon[], 16) = {
+ // Alpha coefficients.
+ -2, 1, 0, -1, 2, 1, 0, -1,
+ 0, -1, -2, -1, 0, 1, 2, 1,
+ // Remapping indicies.
+ 0x0f0e, 0x0302, 0x0504, 0x0706,
+ 0x0b0a, 0x1312, 0x1514, 0x1716,
+};
+
+short* feLightingConstantsForNeon()
+{
+ return s_FELightingConstantsForNeon;
+}
+
+#define ASSTRING(str) #str
+#define TOSTRING(value) ASSTRING(value)
+
+#define PIXELS_OFFSET TOSTRING(0)
+#define WIDTH_OFFSET TOSTRING(4)
+#define HEIGHT_OFFSET TOSTRING(8)
+#define FLAGS_OFFSET TOSTRING(12)
+#define SPECULAR_EXPONENT_OFFSET TOSTRING(16)
+#define CONE_EXPONENT_OFFSET TOSTRING(20)
+#define FLOAT_ARGUMENTS_OFFSET TOSTRING(24)
+#define DRAWING_CONSTANTS_OFFSET TOSTRING(28)
+#define NL "\n"
+
+// Register allocation
+#define PAINTING_DATA_R "r11"
+#define RESET_WIDTH_R PAINTING_DATA_R
+#define PIXELS_R "r4"
+#define WIDTH_R "r5"
+#define HEIGHT_R "r6"
+#define FLAGS_R "r7"
+#define SPECULAR_EXPONENT_R "r8"
+#define CONE_EXPONENT_R "r10"
+#define SCANLINE_R "r12"
+
+#define TMP1_Q "q0"
+#define TMP1_D0 "d0"
+#define TMP1_S0 "s0"
+#define TMP1_S1 "s1"
+#define TMP1_D1 "d1"
+#define TMP1_S2 "s2"
+#define TMP1_S3 "s3"
+#define TMP2_Q "q1"
+#define TMP2_D0 "d2"
+#define TMP2_S0 "s4"
+#define TMP2_S1 "s5"
+#define TMP2_D1 "d3"
+#define TMP2_S2 "s6"
+#define TMP2_S3 "s7"
+#define TMP3_Q "q2"
+#define TMP3_D0 "d4"
+#define TMP3_S0 "s8"
+#define TMP3_S1 "s9"
+#define TMP3_D1 "d5"
+#define TMP3_S2 "s10"
+#define TMP3_S3 "s11"
+
+#define COSINE_OF_ANGLE "s12"
+#define POWF_INT_S "s13"
+#define POWF_FRAC_S "s14"
+#define SPOT_COLOR_Q "q4"
+
+// Because of VMIN and VMAX CONST_ZERO_S and CONST_ONE_S
+// must be placed on the same side of the double vector
+
+// Current pixel position
+#define POSITION_Q "q5"
+#define POSITION_X_S "s20"
+#define POSITION_Y_S "s21"
+#define POSITION_Z_S "s22"
+#define CONST_ZERO_HI_D "d11"
+#define CONST_ZERO_S "s23"
+
+// -------------------------------
+// Variable arguments
+// Misc arguments
+#define READ1_RANGE "d12-d15"
+#define READ2_RANGE "d16-d19"
+#define READ3_RANGE "d20-d21"
+
+#define SCALE_S "s24"
+#define SCALE_DIV4_S "s25"
+#define DIFFUSE_CONST_S "s26"
+
+// Light source position
+#define CONE_CUT_OFF_S "s28"
+#define CONE_FULL_LIGHT_S "s29"
+#define CONE_CUT_OFF_RANGE_S "s30"
+#define CONST_ONE_HI_D "d15"
+#define CONST_ONE_S "s31"
+
+#define LIGHT_Q "q8"
+#define DIRECTION_Q "q9"
+#define COLOR_Q "q10"
+// -------------------------------
+// Constant coefficients
+#define READ4_RANGE "d22-d25"
+#define READ5_RANGE "d26-d27"
+
+#define ALPHAX_Q "q11"
+#define ALPHAY_Q "q12"
+#define REMAPX_D "d26"
+#define REMAPY_D "d27"
+// -------------------------------
+
+#define ALL_ROWS_D "{d28,d29,d30}"
+#define TOP_ROW_D "d28"
+#define MIDDLE_ROW_D "d29"
+#define BOTTOM_ROW_D "d30"
+
+#define GET_LENGTH(source, temp) \
+ "vmul.f32 " temp##_Q ", " source##_Q ", " source##_Q NL \
+ "vadd.f32 " source##_S3 ", " temp##_S0 ", " temp##_S1 NL \
+ "vadd.f32 " source##_S3 ", " source##_S3 ", " temp##_S2 NL \
+ "vsqrt.f32 " source##_S3 ", " source##_S3 NL
+
+// destination##_S3 can contain the multiply of length.
+#define DOT_PRODUCT(destination, source1, source2) \
+ "vmul.f32 " destination##_Q ", " source1##_Q ", " source2##_Q NL \
+ "vadd.f32 " destination##_S0 ", " destination##_S0 ", " destination##_S1 NL \
+ "vadd.f32 " destination##_S0 ", " destination##_S0 ", " destination##_S2 NL
+
+#define MULTIPLY_BY_DIFFUSE_CONST(normalVectorLength, dotProductLength) \
+ "tst " FLAGS_R ", #" TOSTRING(FLAG_DIFFUSE_CONST_IS_1) NL \
+ "vmuleq.f32 " TMP2_S1 ", " DIFFUSE_CONST_S ", " normalVectorLength NL \
+ "vdiveq.f32 " TMP2_S1 ", " TMP2_S1 ", " dotProductLength NL \
+ "vdivne.f32 " TMP2_S1 ", " normalVectorLength ", " dotProductLength NL
+
+#define POWF_SQR(value, exponent, current, remaining) \
+ "tst " exponent ", #" ASSTRING(current) NL \
+ "vmulne.f32 " value ", " value ", " POWF_INT_S NL \
+ "tst " exponent ", #" ASSTRING(remaining) NL \
+ "vmulne.f32 " POWF_INT_S ", " POWF_INT_S ", " POWF_INT_S NL
+
+#define POWF_SQRT(value, exponent, current, remaining) \
+ "tst " exponent ", #" ASSTRING(remaining) NL \
+ "vsqrtne.f32 " POWF_FRAC_S ", " POWF_FRAC_S NL \
+ "tst " exponent ", #" ASSTRING(current) NL \
+ "vmulne.f32 " value ", " value ", " POWF_FRAC_S NL
+
+// This simplified powf function is sufficiently accurate.
+#define POWF(value, exponent) \
+ "tst " exponent ", #0xfc0" NL \
+ "vmovne.f32 " POWF_INT_S ", " value NL \
+ "tst " exponent ", #0x03f" NL \
+ "vmovne.f32 " POWF_FRAC_S ", " value NL \
+ "vmov.f32 " value ", " CONST_ONE_S NL \
+ \
+ POWF_SQR(value, exponent, 0x040, 0xf80) \
+ POWF_SQR(value, exponent, 0x080, 0xf00) \
+ POWF_SQR(value, exponent, 0x100, 0xe00) \
+ POWF_SQR(value, exponent, 0x200, 0xc00) \
+ POWF_SQR(value, exponent, 0x400, 0x800) \
+ "tst " exponent ", #0x800" NL \
+ "vmulne.f32 " value ", " value ", " POWF_INT_S NL \
+ \
+ POWF_SQRT(value, exponent, 0x20, 0x3f) \
+ POWF_SQRT(value, exponent, 0x10, 0x1f) \
+ POWF_SQRT(value, exponent, 0x08, 0x0f) \
+ POWF_SQRT(value, exponent, 0x04, 0x07) \
+ POWF_SQRT(value, exponent, 0x02, 0x03) \
+ POWF_SQRT(value, exponent, 0x01, 0x01)
+
+// The following algorithm is an ARM-NEON optimized version of
+// the main loop found in FELighting.cpp. Since the whole code
+// is redesigned to be as effective as possible (ARM specific
+// thinking), it is four times faster than its C++ counterpart.
+
+asm ( // NOLINT
+".globl " TOSTRING(neonDrawLighting) NL
+TOSTRING(neonDrawLighting) ":" NL
+ // Because of the clever register allocation, nothing is stored on the stack
+ // except the saved registers.
+ // Stack must be aligned to 8 bytes.
+ "stmdb sp!, {r4-r8, r10, r11, lr}" NL
+ "vstmdb sp!, {d8-d15}" NL
+ "mov " PAINTING_DATA_R ", r0" NL
+
+ // The following two arguments are loaded to SIMD registers.
+ "ldr r0, [" PAINTING_DATA_R ", #" FLOAT_ARGUMENTS_OFFSET "]" NL
+ "ldr r1, [" PAINTING_DATA_R ", #" DRAWING_CONSTANTS_OFFSET "]" NL
+ "ldr " PIXELS_R ", [" PAINTING_DATA_R ", #" PIXELS_OFFSET "]" NL
+ "ldr " WIDTH_R ", [" PAINTING_DATA_R ", #" WIDTH_OFFSET "]" NL
+ "ldr " HEIGHT_R ", [" PAINTING_DATA_R ", #" HEIGHT_OFFSET "]" NL
+ "ldr " FLAGS_R ", [" PAINTING_DATA_R ", #" FLAGS_OFFSET "]" NL
+ "ldr " SPECULAR_EXPONENT_R ", [" PAINTING_DATA_R ", #" SPECULAR_EXPONENT_OFFSET "]" NL
+ "ldr " CONE_EXPONENT_R ", [" PAINTING_DATA_R ", #" CONE_EXPONENT_OFFSET "]" NL
+
+ // Load all data to the SIMD registers with the least number of instructions.
+ "vld1.f32 { " READ1_RANGE " }, [r0]!" NL
+ "vld1.f32 { " READ2_RANGE " }, [r0]!" NL
+ "vld1.f32 { " READ3_RANGE " }, [r0]!" NL
+ "vld1.s16 {" READ4_RANGE "}, [r1]!" NL
+ "vld1.s16 {" READ5_RANGE "}, [r1]!" NL
+
+ // Initializing local variables.
+ "mov " SCANLINE_R ", " WIDTH_R ", lsl #2" NL
+ "add " SCANLINE_R ", " SCANLINE_R ", #8" NL
+ "add " PIXELS_R ", " PIXELS_R ", " SCANLINE_R NL
+ "add " PIXELS_R ", " PIXELS_R ", #3" NL
+ "mov r0, #0" NL
+ "vmov.f32 " CONST_ZERO_S ", r0" NL
+ "vmov.f32 " POSITION_Y_S ", " CONST_ONE_S NL
+ "tst " FLAGS_R ", #" TOSTRING(FLAG_SPOT_LIGHT) NL
+ "vmov.f32 " SPOT_COLOR_Q ", " COLOR_Q NL
+ "mov " RESET_WIDTH_R ", " WIDTH_R NL
+
+".mainloop:" NL
+ "mov r3, #3" NL
+ "vmov.f32 " POSITION_X_S ", " CONST_ONE_S NL
+
+".scanline:" NL
+ // The ROW registers are storing the alpha channel of the last three pixels.
+ // The alpha channel is stored as signed short (sint16) values. The fourth value
+ // is garbage. The following instructions are shifting out the unnecessary alpha
+ // values and load the next ones.
+ "ldrb r0, [" PIXELS_R ", -" SCANLINE_R "]" NL
+ "ldrb r1, [" PIXELS_R ", +" SCANLINE_R "]" NL
+ "ldrb r2, [" PIXELS_R "], #4" NL
+ "vext.s16 " TOP_ROW_D ", " TOP_ROW_D ", " TOP_ROW_D ", #3" NL
+ "vext.s16 " MIDDLE_ROW_D ", " MIDDLE_ROW_D ", " MIDDLE_ROW_D ", #3" NL
+ "vext.s16 " BOTTOM_ROW_D ", " BOTTOM_ROW_D ", " BOTTOM_ROW_D ", #3" NL
+ "vmov.s16 " TOP_ROW_D "[1], r0" NL
+ "vmov.s16 " MIDDLE_ROW_D "[1], r2" NL
+ "vmov.s16 " BOTTOM_ROW_D "[1], r1" NL
+
+ // The two border pixels (rightmost and leftmost) are skipped when
+ // the next scanline is reached. It also jumps, when the algorithm
+ // is started, and the first free alpha values are loaded to each row.
+ "subs r3, r3, #1" NL
+ "bne .scanline" NL
+
+ // The light vector goes to TMP1_Q. It is constant in case of distant light.
+ // The fourth value contains the length of the light vector.
+ "tst " FLAGS_R ", #" TOSTRING(FLAG_POINT_LIGHT | FLAG_SPOT_LIGHT) NL
+ "beq .distantLight" NL
+
+ "vmov.s16 r3, " MIDDLE_ROW_D "[2]" NL
+ "vmov.f32 " POSITION_Z_S ", r3" NL
+ "vcvt.f32.s32 " POSITION_Z_S ", " POSITION_Z_S NL
+ "vmul.f32 " POSITION_Z_S ", " POSITION_Z_S ", " SCALE_S NL
+
+ "vsub.f32 " TMP1_Q ", " LIGHT_Q ", " POSITION_Q NL
+ GET_LENGTH(TMP1, TMP2)
+
+ "tst " FLAGS_R ", #" TOSTRING(FLAG_SPOT_LIGHT) NL
+ "bne .cosineOfAngle" NL
+".visiblePixel:" NL
+
+ // | -1 0 1 | | -1 -2 -1 |
+ // X = | -2 0 2 | Y = | 0 0 0 |
+ // | -1 0 1 | | 1 2 1 |
+
+ // Multiply the alpha values by the X and Y matrices.
+
+ // Moving the 8 alpha value to TMP3.
+ "vtbl.8 " TMP3_D0 ", " ALL_ROWS_D ", " REMAPX_D NL
+ "vtbl.8 " TMP3_D1 ", " ALL_ROWS_D ", " REMAPY_D NL
+
+ "vmul.s16 " TMP2_Q ", " TMP3_Q ", " ALPHAX_Q NL
+ "vpadd.s16 " TMP2_D0 ", " TMP2_D0 ", " TMP2_D1 NL
+ "vpadd.s16 " TMP2_D0 ", " TMP2_D0 ", " TMP2_D0 NL
+ "vpadd.s16 " TMP2_D0 ", " TMP2_D0 ", " TMP2_D0 NL
+ "vmov.s16 r0, " TMP2_D0 "[0]" NL
+
+ "vmul.s16 " TMP2_Q ", " TMP3_Q ", " ALPHAY_Q NL
+ "vpadd.s16 " TMP2_D0 ", " TMP2_D0 ", " TMP2_D1 NL
+ "vpadd.s16 " TMP2_D0 ", " TMP2_D0 ", " TMP2_D0 NL
+ "vpadd.s16 " TMP2_D0 ", " TMP2_D0 ", " TMP2_D0 NL
+ "vmov.s16 r1, " TMP2_D0 "[0]" NL
+
+ // r0 and r1 contains the X and Y coordinates of the
+ // normal vector, respectively.
+
+ // Calculating the spot light strength.
+ "tst " FLAGS_R ", #" TOSTRING(FLAG_SPOT_LIGHT) NL
+ "beq .endLight" NL
+
+ "vneg.f32 " TMP3_S1 ", " COSINE_OF_ANGLE NL
+ "tst " FLAGS_R ", #" TOSTRING(FLAG_CONE_EXPONENT_IS_1) NL
+ "beq .coneExpPowf" NL
+".coneExpPowfFinished:" NL
+
+ // Smoothing the cone edge if necessary.
+ "vcmp.f32 " COSINE_OF_ANGLE ", " CONE_FULL_LIGHT_S NL
+ "fmstat" NL
+ "bhi .cutOff" NL
+".cutOffFinished:" NL
+
+ "vmin.f32 " TMP3_D0 ", " TMP3_D0 ", " CONST_ONE_HI_D NL
+ "vmul.f32 " COLOR_Q ", " SPOT_COLOR_Q ", " TMP3_D0 "[1]" NL
+
+".endLight:" NL
+ // Summarize:
+ // r0 and r1 contains the normalVector.
+ // TMP1_Q contains the light vector and its length.
+ // COLOR_Q contains the color of the light vector.
+
+ // Test whether both r0 and r1 are zero (Normal vector is (0, 0, 1)).
+ "orrs r2, r0, r1" NL
+ "bne .normalVectorIsNonZero" NL
+
+ "tst " FLAGS_R ", #" TOSTRING(FLAG_SPECULAR_LIGHT) NL
+ "bne .specularLight1" NL
+
+ // Calculate diffuse light strength.
+ MULTIPLY_BY_DIFFUSE_CONST(TMP1_S2, TMP1_S3)
+ "b .lightStrengthCalculated" NL
+
+".specularLight1:" NL
+ // Calculating specular light strength.
+ "vadd.f32 " TMP1_S2 ", " TMP1_S2 ", " TMP1_S3 NL
+ GET_LENGTH(TMP1, TMP2)
+
+ // When the exponent is 1, we don't need to call an expensive powf function.
+ "tst " FLAGS_R ", #" TOSTRING(FLAG_SPECULAR_EXPONENT_IS_1) NL
+ "vdiveq.f32 " TMP2_S1 ", " TMP1_S2 ", " TMP1_S3 NL
+ "beq .specularExpPowf" NL
+
+ MULTIPLY_BY_DIFFUSE_CONST(TMP1_S2, TMP1_S3)
+ "b .lightStrengthCalculated" NL
+
+".normalVectorIsNonZero:" NL
+ // Normal vector goes to TMP2, and its length is calculated as well.
+ "vmov.s32 " TMP2_S0 ", r0" NL
+ "vcvt.f32.s32 " TMP2_S0 ", " TMP2_S0 NL
+ "vmul.f32 " TMP2_S0 ", " TMP2_S0 ", " SCALE_DIV4_S NL
+ "vmov.s32 " TMP2_S1 ", r1" NL
+ "vcvt.f32.s32 " TMP2_S1 ", " TMP2_S1 NL
+ "vmul.f32 " TMP2_S1 ", " TMP2_S1 ", " SCALE_DIV4_S NL
+ "vmov.f32 " TMP2_S2 ", " CONST_ONE_S NL
+ GET_LENGTH(TMP2, TMP3)
+
+ "tst " FLAGS_R ", #" TOSTRING(FLAG_SPECULAR_LIGHT) NL
+ "bne .specularLight2" NL
+
+ // Calculating diffuse light strength.
+ DOT_PRODUCT(TMP3, TMP2, TMP1)
+ MULTIPLY_BY_DIFFUSE_CONST(TMP3_S0, TMP3_S3)
+ "b .lightStrengthCalculated" NL
+
+".specularLight2:" NL
+ // Calculating specular light strength.
+ "vadd.f32 " TMP1_S2 ", " TMP1_S2 ", " TMP1_S3 NL
+ GET_LENGTH(TMP1, TMP3)
+ DOT_PRODUCT(TMP3, TMP2, TMP1)
+
+ // When the exponent is 1, we don't need to call an expensive powf function.
+ "tst " FLAGS_R ", #" TOSTRING(FLAG_SPECULAR_EXPONENT_IS_1) NL
+ "vdiveq.f32 " TMP2_S1 ", " TMP3_S0 ", " TMP3_S3 NL
+ "beq .specularExpPowf" NL
+ MULTIPLY_BY_DIFFUSE_CONST(TMP3_S0, TMP3_S3)
+
+".lightStrengthCalculated:" NL
+ // TMP2_S1 contains the light strength. Clamp it to [0, 1]
+ "vmax.f32 " TMP2_D0 ", " TMP2_D0 ", " CONST_ZERO_HI_D NL
+ "vmin.f32 " TMP2_D0 ", " TMP2_D0 ", " CONST_ONE_HI_D NL
+ "vmul.f32 " TMP3_Q ", " COLOR_Q ", " TMP2_D0 "[1]" NL
+ "vcvt.u32.f32 " TMP3_Q ", " TMP3_Q NL
+ "vmov.u32 r2, r3, " TMP3_S0 ", " TMP3_S1 NL
+ // The color values are stored in-place.
+ "strb r2, [" PIXELS_R ", #-11]" NL
+ "strb r3, [" PIXELS_R ", #-10]" NL
+ "vmov.u32 r2, " TMP3_S2 NL
+ "strb r2, [" PIXELS_R ", #-9]" NL
+
+ // Continue to the next pixel.
+".blackPixel:" NL
+ "vadd.f32 " POSITION_X_S ", " CONST_ONE_S NL
+ "mov r3, #1" NL
+ "subs " WIDTH_R ", " WIDTH_R ", #1" NL
+ "bne .scanline" NL
+
+ // If the end of the scanline is reached, we continue
+ // to the next scanline.
+ "vadd.f32 " POSITION_Y_S ", " CONST_ONE_S NL
+ "mov " WIDTH_R ", " RESET_WIDTH_R NL
+ "subs " HEIGHT_R ", " HEIGHT_R ", #1" NL
+ "bne .mainloop" NL
+
+ // Return.
+ "vldmia sp!, {d8-d15}" NL
+ "ldmia sp!, {r4-r8, r10, r11, pc}" NL
+
+".distantLight:" NL
+ // In case of distant light, the light vector is constant,
+ // we simply copy it.
+ "vmov.f32 " TMP1_Q ", " LIGHT_Q NL
+ "b .visiblePixel" NL
+
+".cosineOfAngle:" NL
+ // If the pixel is outside of the cone angle, it is simply a black pixel.
+ DOT_PRODUCT(TMP3, TMP1, DIRECTION)
+ "vdiv.f32 " COSINE_OF_ANGLE ", " TMP3_S0 ", " TMP1_S3 NL
+ "vcmp.f32 " COSINE_OF_ANGLE ", " CONE_CUT_OFF_S NL
+ "fmstat" NL
+ "bls .visiblePixel" NL
+ "mov r0, #0" NL
+ "strh r0, [" PIXELS_R ", #-11]" NL
+ "strb r0, [" PIXELS_R ", #-9]" NL
+ "b .blackPixel" NL
+
+".cutOff:" NL
+ // Smoothing the light strength on the cone edge.
+ "vsub.f32 " TMP3_S0 ", " CONE_CUT_OFF_S ", " COSINE_OF_ANGLE NL
+ "vdiv.f32 " TMP3_S0 ", " TMP3_S0 ", " CONE_CUT_OFF_RANGE_S NL
+ "vmul.f32 " TMP3_S1 ", " TMP3_S1 ", " TMP3_S0 NL
+ "b .cutOffFinished" NL
+
+".coneExpPowf:" NL
+ POWF(TMP3_S1, CONE_EXPONENT_R)
+ "b .coneExpPowfFinished" NL
+
+".specularExpPowf:" NL
+ POWF(TMP2_S1, SPECULAR_EXPONENT_R)
+ "tst " FLAGS_R ", #" TOSTRING(FLAG_DIFFUSE_CONST_IS_1) NL
+ "vmuleq.f32 " TMP2_S1 ", " TMP2_S1 ", " DIFFUSE_CONST_S NL
+ "b .lightStrengthCalculated" NL
+); // NOLINT
+
+} // namespace WebCore
+
+#endif // CPU(ARM_NEON) && COMPILER(GCC)
diff --git a/Source/WebCore/platform/graphics/filters/arm/FELightingNEON.h b/Source/WebCore/platform/graphics/filters/arm/FELightingNEON.h
new file mode 100644
index 0000000..d83b7fe
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/arm/FELightingNEON.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2011 University of Szeged
+ * Copyright (C) 2011 Zoltan Herczeg
+ *
+ * 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.
+ */
+
+#ifndef FELightingNeon_h
+#define FELightingNeon_h
+
+#include <wtf/Platform.h>
+
+#if CPU(ARM_NEON) && COMPILER(GCC)
+
+namespace WebCore {
+
+// Otherwise: Distant Light.
+#define FLAG_POINT_LIGHT 0x01
+#define FLAG_SPOT_LIGHT 0x02
+#define FLAG_CONE_EXPONENT_IS_1 0x04
+
+// Otherwise: Diffuse light.
+#define FLAG_SPECULAR_LIGHT 0x10
+#define FLAG_DIFFUSE_CONST_IS_1 0x20
+#define FLAG_SPECULAR_EXPONENT_IS_1 0x40
+
+// Must be aligned to 16 bytes.
+struct FELightingFloatArgumentsForNeon {
+ float surfaceScale;
+ float minusSurfaceScaleDividedByFour;
+ float diffuseConstant;
+ float padding1;
+
+ float coneCutOffLimit;
+ float coneFullLight;
+ float coneCutOffRange;
+ float constOne;
+
+ float lightX;
+ float lightY;
+ float lightZ;
+ float padding2;
+
+ float directionX;
+ float directionY;
+ float directionZ;
+ float padding3;
+
+ float colorRed;
+ float colorGreen;
+ float colorBlue;
+ float padding4;
+};
+
+struct FELightingPaintingDataForNeon {
+ unsigned char* pixels;
+ int widthDecreasedByTwo;
+ int heightDecreasedByTwo;
+ // Combination of FLAG constants above.
+ int flags;
+ int specularExponent;
+ int coneExponent;
+ FELightingFloatArgumentsForNeon* floatArguments;
+ short* paintingConstants;
+};
+
+short* feLightingConstantsForNeon();
+
+extern "C" {
+void neonDrawLighting(FELightingPaintingDataForNeon*);
+}
+
+} // namespace WebCore
+
+#endif // CPU(ARM_NEON) && COMPILER(GCC)
+
+#endif // FELightingNeon_h
diff --git a/Source/WebCore/platform/graphics/gpu/BicubicShader.cpp b/Source/WebCore/platform/graphics/gpu/BicubicShader.cpp
index 40c9843..f6f428d 100644
--- a/Source/WebCore/platform/graphics/gpu/BicubicShader.cpp
+++ b/Source/WebCore/platform/graphics/gpu/BicubicShader.cpp
@@ -55,11 +55,12 @@ PassOwnPtr<BicubicShader> BicubicShader::create(GraphicsContext3D* context)
static const char* vertexShaderSource =
"uniform mat3 matrix;\n"
"uniform mat3 texMatrix;\n"
- "attribute vec3 position;\n"
+ "attribute vec2 position;\n"
"varying vec2 texCoord;\n"
"void main() {\n"
- " texCoord = (texMatrix * position).xy;\n"
- " gl_Position = vec4(matrix * position, 1.0);\n"
+ " vec3 pos = vec3(position, 1.0);\n"
+ " texCoord = (texMatrix * pos).xy;\n"
+ " gl_Position = vec4(matrix * pos, 1.0);\n"
"}\n";
static const char* fragmentShaderSource =
"#ifdef GL_ES\n"
@@ -127,7 +128,7 @@ void BicubicShader::use(const AffineTransform& transform, const AffineTransform&
m_context->uniform1i(m_imageLocation, 0);
m_context->uniform1f(m_alphaLocation, alpha);
- m_context->vertexAttribPointer(m_positionLocation, 3, GraphicsContext3D::FLOAT, false, 0, 0);
+ m_context->vertexAttribPointer(m_positionLocation, 2, GraphicsContext3D::FLOAT, false, 0, 0);
m_context->enableVertexAttribArray(m_positionLocation);
}
diff --git a/Source/WebCore/platform/graphics/gpu/ConvolutionShader.cpp b/Source/WebCore/platform/graphics/gpu/ConvolutionShader.cpp
index f0b6bd9..b11d966 100644
--- a/Source/WebCore/platform/graphics/gpu/ConvolutionShader.cpp
+++ b/Source/WebCore/platform/graphics/gpu/ConvolutionShader.cpp
@@ -58,13 +58,14 @@ PassOwnPtr<ConvolutionShader> ConvolutionShader::create(GraphicsContext3D* conte
"uniform mat3 matrix;\n"
"uniform mat3 texMatrix;\n"
"uniform vec2 imageIncrement;\n"
- "attribute vec3 position;\n"
+ "attribute vec2 position;\n"
"varying vec2 imageCoord;\n"
"void main() {\n"
+ " vec3 pos = vec3(position, 1.0);\n"
" // Offset image coords by half of kernel width, in image texels\n"
- " gl_Position = vec4(matrix * position, 1.0);\n"
+ " gl_Position = vec4(matrix * pos, 1.0);\n"
" float scale = (float(KERNEL_WIDTH) - 1.0) / 2.0;\n"
- " imageCoord = (texMatrix * position).xy - vec2(scale, scale) * imageIncrement;\n"
+ " imageCoord = (texMatrix * pos).xy - vec2(scale, scale) * imageIncrement;\n"
"}\n";
char vertexShaderSource[1024];
snprintf(vertexShaderSource, sizeof(vertexShaderSource), vertexShaderRaw, kernelWidth);
@@ -115,7 +116,7 @@ void ConvolutionShader::use(const AffineTransform& transform, const AffineTransf
kernelWidth = m_kernelWidth;
m_context->uniform1fv(m_kernelLocation, const_cast<float*>(kernel), kernelWidth);
- m_context->vertexAttribPointer(m_positionLocation, 3, GraphicsContext3D::FLOAT, false, 0, 0);
+ m_context->vertexAttribPointer(m_positionLocation, 2, GraphicsContext3D::FLOAT, false, 0, 0);
m_context->enableVertexAttribArray(m_positionLocation);
}
diff --git a/Source/WebCore/platform/graphics/gpu/DrawingBuffer.cpp b/Source/WebCore/platform/graphics/gpu/DrawingBuffer.cpp
index 2a83fcf..8e293f7 100644
--- a/Source/WebCore/platform/graphics/gpu/DrawingBuffer.cpp
+++ b/Source/WebCore/platform/graphics/gpu/DrawingBuffer.cpp
@@ -144,112 +144,128 @@ void DrawingBuffer::resizeDepthStencil(int sampleCount)
m_context->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, 0);
}
-void DrawingBuffer::reset(const IntSize& newSize)
+void DrawingBuffer::clearFramebuffer()
{
- m_size = newSize;
+ m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO ? m_multisampleFBO : m_fbo);
+ const GraphicsContext3D::Attributes& attributes = m_context->getContextAttributes();
+ float clearDepth = 0;
+ int clearStencil = 0;
+ unsigned char depthMask = false;
+ unsigned int stencilMask = 0xffffffff;
+ unsigned char isScissorEnabled = false;
+ unsigned long clearMask = GraphicsContext3D::COLOR_BUFFER_BIT;
+ if (attributes.depth) {
+ m_context->getFloatv(GraphicsContext3D::DEPTH_CLEAR_VALUE, &clearDepth);
+ m_context->clearDepth(1);
+ m_context->getBooleanv(GraphicsContext3D::DEPTH_WRITEMASK, &depthMask);
+ m_context->depthMask(true);
+ clearMask |= GraphicsContext3D::DEPTH_BUFFER_BIT;
+ }
+ if (attributes.stencil) {
+ m_context->getIntegerv(GraphicsContext3D::STENCIL_CLEAR_VALUE, &clearStencil);
+ m_context->clearStencil(0);
+ m_context->getIntegerv(GraphicsContext3D::STENCIL_WRITEMASK, reinterpret_cast<int*>(&stencilMask));
+ m_context->stencilMaskSeparate(GraphicsContext3D::FRONT, 0xffffffff);
+ clearMask |= GraphicsContext3D::STENCIL_BUFFER_BIT;
+ }
+ isScissorEnabled = m_context->isEnabled(GraphicsContext3D::SCISSOR_TEST);
+ m_context->disable(GraphicsContext3D::SCISSOR_TEST);
+
+ float clearColor[4];
+ m_context->getFloatv(GraphicsContext3D::COLOR_CLEAR_VALUE, clearColor);
+ m_context->clearColor(0, 0, 0, 0);
+ m_context->clear(clearMask);
+ m_context->clearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
+
+ if (attributes.depth) {
+ m_context->clearDepth(clearDepth);
+ m_context->depthMask(depthMask);
+ }
+ if (attributes.stencil) {
+ m_context->clearStencil(clearStencil);
+ m_context->stencilMaskSeparate(GraphicsContext3D::FRONT, stencilMask);
+ }
+ if (isScissorEnabled)
+ m_context->enable(GraphicsContext3D::SCISSOR_TEST);
+ else
+ m_context->disable(GraphicsContext3D::SCISSOR_TEST);
+}
+bool DrawingBuffer::reset(const IntSize& newSize)
+{
if (!m_context)
- return;
-
+ return false;
+
m_context->makeContextCurrent();
-
- const GraphicsContext3D::Attributes& attributes = m_context->getContextAttributes();
- 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;
- }
+ int maxTextureSize = 0;
+ m_context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &maxTextureSize);
+ if (newSize.height() > maxTextureSize || newSize.width() > maxTextureSize) {
+ clear();
+ return false;
+ }
- // resize multisample FBO
- if (multisample()) {
- int maxSampleCount = 0;
-
- m_context->getIntegerv(Extensions3D::MAX_SAMPLES, &maxSampleCount);
- int sampleCount = std::min(8, maxSampleCount);
+ const GraphicsContext3D::Attributes& attributes = m_context->getContextAttributes();
- m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO);
+ if (newSize != m_size) {
+ m_size = newSize;
- m_context->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, m_multisampleColorBuffer);
- 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) {
- // Cleanup
- clear();
- return;
+ 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;
}
- }
- // resize regular FBO
- m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo);
- m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_colorBuffer);
- 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);
- if (!multisample())
- resizeDepthStencil(0);
- if (m_context->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) != GraphicsContext3D::FRAMEBUFFER_COMPLETE) {
- // Cleanup
- clear();
- return;
- }
+ // resize multisample FBO
+ if (multisample()) {
+ int maxSampleCount = 0;
+
+ m_context->getIntegerv(Extensions3D::MAX_SAMPLES, &maxSampleCount);
+ int sampleCount = std::min(8, maxSampleCount);
- if (multisample())
- m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO);
+ m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO);
- if (!m_context->getExtensions()->supports("GL_CHROMIUM_resource_safe")) {
- // Initialize renderbuffers (depth/stencil).
- float clearDepth = 0;
- int clearStencil = 0;
- unsigned char depthMask = true;
- unsigned int stencilMask = 0xffffffff;
- unsigned char isScissorEnabled = false;
- unsigned long clearMask = 0;
- if (attributes.depth) {
- m_context->getFloatv(GraphicsContext3D::DEPTH_CLEAR_VALUE, &clearDepth);
- m_context->clearDepth(1);
- m_context->getBooleanv(GraphicsContext3D::DEPTH_WRITEMASK, &depthMask);
- m_context->depthMask(true);
- clearMask |= GraphicsContext3D::DEPTH_BUFFER_BIT;
- }
- if (attributes.stencil) {
- m_context->getIntegerv(GraphicsContext3D::STENCIL_CLEAR_VALUE, &clearStencil);
- m_context->clearStencil(0);
- m_context->getIntegerv(GraphicsContext3D::STENCIL_WRITEMASK, reinterpret_cast<int*>(&stencilMask));
- m_context->stencilMaskSeparate(GraphicsContext3D::FRONT, 0xffffffff);
- clearMask |= GraphicsContext3D::STENCIL_BUFFER_BIT;
+ m_context->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, m_multisampleColorBuffer);
+ 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) {
+ // Cleanup
+ clear();
+ return false;
+ }
}
- if (clearMask) {
- isScissorEnabled = m_context->isEnabled(GraphicsContext3D::SCISSOR_TEST);
- m_context->disable(GraphicsContext3D::SCISSOR_TEST);
- m_context->clear(clearMask);
+ // resize regular FBO
+ m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo);
- if (attributes.depth) {
- m_context->clearDepth(clearDepth);
- m_context->depthMask(depthMask);
- }
- if (attributes.stencil) {
- m_context->clearStencil(clearStencil);
- m_context->stencilMaskSeparate(GraphicsContext3D::FRONT, stencilMask);
- }
- if (isScissorEnabled)
- m_context->enable(GraphicsContext3D::SCISSOR_TEST);
- else
- m_context->disable(GraphicsContext3D::SCISSOR_TEST);
+ m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_colorBuffer);
+
+ 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);
+
+ if (!multisample())
+ resizeDepthStencil(0);
+ if (m_context->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) != GraphicsContext3D::FRAMEBUFFER_COMPLETE) {
+ // Cleanup
+ clear();
+ return false;
}
}
- m_context->flush();
-
+ clearFramebuffer();
+
didReset();
+
+ return true;
}
void DrawingBuffer::commit(long x, long y, long width, long height)
diff --git a/Source/WebCore/platform/graphics/gpu/DrawingBuffer.h b/Source/WebCore/platform/graphics/gpu/DrawingBuffer.h
index 606484e..caf3aa5 100644
--- a/Source/WebCore/platform/graphics/gpu/DrawingBuffer.h
+++ b/Source/WebCore/platform/graphics/gpu/DrawingBuffer.h
@@ -44,6 +44,7 @@
#if ENABLE(SKIA_GPU)
class GrContext;
+struct GrPlatformSurfaceDesc;
#endif
namespace WebCore {
@@ -60,7 +61,10 @@ public:
~DrawingBuffer();
- void reset(const IntSize&);
+ void clearFramebuffer();
+
+ // Returns true if the buffer was successfully resized.
+ bool reset(const IntSize&);
void bind();
IntSize size() const { return m_size; }
Platform3DObject colorBuffer() const { return m_colorBuffer; }
@@ -101,6 +105,7 @@ public:
#if ENABLE(SKIA_GPU)
void setGrContext(GrContext* ctx);
+ void getGrPlatformSurfaceDesc(GrPlatformSurfaceDesc*);
#endif
PassRefPtr<GraphicsContext3D> graphicsContext3D() const { return m_context; }
diff --git a/Source/WebCore/platform/graphics/gpu/LoopBlinnMathUtils.cpp b/Source/WebCore/platform/graphics/gpu/LoopBlinnMathUtils.cpp
index 5b155a5..b228cbf 100644
--- a/Source/WebCore/platform/graphics/gpu/LoopBlinnMathUtils.cpp
+++ b/Source/WebCore/platform/graphics/gpu/LoopBlinnMathUtils.cpp
@@ -562,6 +562,108 @@ int numXRayCrossingsForCubic(const XRay& xRay, const FloatPoint cubic[4], bool&
return numCrossings;
}
+/*
+ * Based on C code from the article
+ * "Testing the Convexity of a Polygon"
+ * by Peter Schorn and Frederick Fisher,
+ * (schorn@inf.ethz.ch, fred@kpc.com)
+ * in "Graphics Gems IV", Academic Press, 1994
+ */
+
+static inline int convexCompare(const FloatSize& delta)
+{
+ return (delta.width() > 0) ? -1 : /* x coord diff, second pt > first pt */
+ (delta.width() < 0) ? 1 : /* x coord diff, second pt < first pt */
+ (delta.height() > 0) ? -1 : /* x coord same, second pt > first pt */
+ (delta.height() < 0) ? 1 : /* x coord same, second pt > first pt */
+ 0; /* second pt equals first point */
+}
+
+static inline float convexCross(const FloatSize& p, const FloatSize& q)
+{
+ return p.width() * q.height() - p.height() * q.width();
+}
+
+static inline bool convexCheckTriple(const FloatSize& dcur, const FloatSize& dprev, int* curDir, int* dirChanges, int* angleSign)
+{
+ int thisDir = convexCompare(dcur);
+ if (thisDir == -*curDir)
+ ++*dirChanges;
+ *curDir = thisDir;
+ float cross = convexCross(dprev, dcur);
+ if (cross > 0) {
+ if (*angleSign == -1)
+ return false;
+ *angleSign = 1;
+ } else if (cross < 0) {
+ if (*angleSign == 1)
+ return false;
+ *angleSign = -1;
+ }
+ return true;
+}
+
+bool isConvex(const FloatPoint* vertices, int nVertices)
+{
+ int dirChanges = 0, angleSign = 0;
+ FloatPoint second, third;
+ FloatSize dprev, dcur;
+
+ /* Get different point, return if less than 3 diff points. */
+ if (nVertices < 3)
+ return false;
+ int i = 1;
+ while (true) {
+ second = vertices[i++];
+ dprev = second - vertices[0];
+ if (dprev.width() || dprev.height())
+ break;
+ /* Check if out of points. Check here to avoid slowing down cases
+ * without repeated points.
+ */
+ if (i >= nVertices)
+ return false;
+ }
+ FloatPoint saveSecond = second;
+ int curDir = convexCompare(dprev); /* Find initial direction */
+ while (i < nVertices) {
+ /* Get different point, break if no more points */
+ third = vertices[i++];
+ dcur = third - second;
+ if (!dcur.width() && !dcur.height())
+ continue;
+
+ /* Check current three points */
+ if (!convexCheckTriple(dcur, dprev, &curDir, &dirChanges, &angleSign))
+ return false;
+ second = third; /* Remember ptr to current point. */
+ dprev = dcur; /* Remember current delta. */
+ }
+
+ /* Must check for direction changes from last vertex back to first */
+ third = vertices[0]; /* Prepare for 'ConvexCheckTriple' */
+ dcur = third - second;
+ if (convexCompare(dcur)) {
+ if (!convexCheckTriple(dcur, dprev, &curDir, &dirChanges, &angleSign))
+ return false;
+ second = third; /* Remember ptr to current point. */
+ dprev = dcur; /* Remember current delta. */
+ }
+
+ /* and check for direction changes back to second vertex */
+ dcur = saveSecond - second;
+ if (!convexCheckTriple(dcur, dprev, &curDir, &dirChanges, &angleSign))
+ return false;
+
+ /* Decide on polygon type given accumulated status */
+ if (dirChanges > 2)
+ return false;
+
+ if (angleSign > 0 || angleSign < 0)
+ return true;
+ return false;
+}
+
} // namespace LoopBlinnMathUtils
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/gpu/LoopBlinnMathUtils.h b/Source/WebCore/platform/graphics/gpu/LoopBlinnMathUtils.h
index b9d19c5..361d901 100644
--- a/Source/WebCore/platform/graphics/gpu/LoopBlinnMathUtils.h
+++ b/Source/WebCore/platform/graphics/gpu/LoopBlinnMathUtils.h
@@ -101,6 +101,9 @@ bool xRayCrossesLine(const XRay& xRay,
const FloatPoint lineEndpoints[2],
bool& ambiguous);
+
+bool isConvex(const FloatPoint* vertices, int nVertices);
+
} // namespace LoopBlinnMathUtils
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/gpu/Shader.cpp b/Source/WebCore/platform/graphics/gpu/Shader.cpp
index 1b9bfd5..13c5ebf 100644
--- a/Source/WebCore/platform/graphics/gpu/Shader.cpp
+++ b/Source/WebCore/platform/graphics/gpu/Shader.cpp
@@ -140,7 +140,7 @@ String Shader::generateVertex(Shader::VertexType vertexType, Shader::FillType fi
case TwoDimensional:
builder.append(
"uniform mat3 matrix;\n"
- "attribute vec3 position;\n");
+ "attribute vec2 position;\n");
break;
case LoopBlinnInterior:
builder.append(
@@ -167,7 +167,7 @@ String Shader::generateVertex(Shader::VertexType vertexType, Shader::FillType fi
if (vertexType == TwoDimensional) {
builder.append(
- "gl_Position = vec4(matrix * position, 1.0);\n");
+ "gl_Position = vec4(matrix * vec3(position, 1.0), 1.0);\n");
} else {
builder.append(
"gl_Position = worldViewProjection * vec4(position, 0.0, 1.0);\n");
@@ -179,7 +179,7 @@ String Shader::generateVertex(Shader::VertexType vertexType, Shader::FillType fi
if (fillType == TextureFill) {
builder.append(
- "texCoord = texMatrix * position;\n");
+ "texCoord = texMatrix * vec3(position, 1.0);\n");
}
builder.append(
diff --git a/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp b/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp
index 662d6a8..b7b94c4 100644
--- a/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp
+++ b/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp
@@ -346,10 +346,10 @@ void SharedGraphicsContext3D::enableStencil(bool enable)
void SharedGraphicsContext3D::useQuadVertices()
{
if (!m_quadVertices) {
- float vertices[] = { 0.0f, 0.0f, 1.0f,
- 1.0f, 0.0f, 1.0f,
- 0.0f, 1.0f, 1.0f,
- 1.0f, 1.0f, 1.0f };
+ float vertices[] = { 0.0f, 0.0f,
+ 1.0f, 0.0f,
+ 0.0f, 1.0f,
+ 1.0f, 1.0f };
m_quadVertices = m_context->createBuffer();
m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_quadVertices);
m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER, sizeof(vertices), vertices, GraphicsContext3D::STATIC_DRAW);
diff --git a/Source/WebCore/platform/graphics/gpu/SolidFillShader.cpp b/Source/WebCore/platform/graphics/gpu/SolidFillShader.cpp
index 78381f0..0a6e084 100644
--- a/Source/WebCore/platform/graphics/gpu/SolidFillShader.cpp
+++ b/Source/WebCore/platform/graphics/gpu/SolidFillShader.cpp
@@ -69,7 +69,7 @@ void SolidFillShader::use(const AffineTransform& transform, const Color& color)
affineTo3x3(transform, matrix);
m_context->uniformMatrix3fv(m_matrixLocation, false /*transpose*/, matrix, 1 /*count*/);
- m_context->vertexAttribPointer(m_positionLocation, 3, GraphicsContext3D::FLOAT, false, 0, 0);
+ m_context->vertexAttribPointer(m_positionLocation, 2, GraphicsContext3D::FLOAT, false, 0, 0);
m_context->enableVertexAttribArray(m_positionLocation);
}
diff --git a/Source/WebCore/platform/graphics/gpu/TexShader.cpp b/Source/WebCore/platform/graphics/gpu/TexShader.cpp
index 9eb5c16..ac141a5 100644
--- a/Source/WebCore/platform/graphics/gpu/TexShader.cpp
+++ b/Source/WebCore/platform/graphics/gpu/TexShader.cpp
@@ -72,7 +72,7 @@ void TexShader::use(const AffineTransform& transform, const AffineTransform& tex
m_context->uniform1i(m_samplerLocation, sampler);
m_context->uniform1f(m_alphaLocation, alpha);
- m_context->vertexAttribPointer(m_positionLocation, 3, GraphicsContext3D::FLOAT, false, 0, 0);
+ m_context->vertexAttribPointer(m_positionLocation, 2, GraphicsContext3D::FLOAT, false, 0, 0);
m_context->enableVertexAttribArray(m_positionLocation);
diff --git a/Source/WebCore/platform/graphics/gpu/TilingData.cpp b/Source/WebCore/platform/graphics/gpu/TilingData.cpp
index 1370543..2415ee4 100644
--- a/Source/WebCore/platform/graphics/gpu/TilingData.cpp
+++ b/Source/WebCore/platform/graphics/gpu/TilingData.cpp
@@ -44,6 +44,9 @@ namespace WebCore {
static int computeNumTiles(int maxTextureSize, int totalSize, int borderTexels)
{
+ if (maxTextureSize - 2 * borderTexels <= 0)
+ return totalSize > 0 && maxTextureSize >= totalSize ? 1 : 0;
+
int numTiles = max(1, 1 + (totalSize - 1 - 2 * borderTexels) / (maxTextureSize - 2 * borderTexels));
return totalSize > 0 ? numTiles : 0;
}
diff --git a/Source/WebCore/platform/graphics/gstreamer/ImageGStreamer.h b/Source/WebCore/platform/graphics/gstreamer/ImageGStreamer.h
index 6e53cfc..332908d 100644
--- a/Source/WebCore/platform/graphics/gstreamer/ImageGStreamer.h
+++ b/Source/WebCore/platform/graphics/gstreamer/ImageGStreamer.h
@@ -27,7 +27,7 @@
#include <gst/video/video.h>
#include <wtf/PassRefPtr.h>
-#if PLATFORM(CAIRO)
+#if USE(CAIRO)
#include <cairo.h>
#endif
@@ -48,7 +48,7 @@ class ImageGStreamer : public RefCounted<ImageGStreamer> {
private:
RefPtr<BitmapImage> m_image;
-#if PLATFORM(CAIRO)
+#if USE(CAIRO)
ImageGStreamer(GstBuffer*&, IntSize, cairo_format_t&);
#endif
diff --git a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
index 2fb4cef..56c2f30 100644
--- a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
+++ b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
@@ -81,194 +81,74 @@ static int greatestCommonDivisor(int a, int b)
return ABS(a);
}
-gboolean mediaPlayerPrivateMessageCallback(GstBus* bus, GstMessage* message, gpointer data)
+static gboolean mediaPlayerPrivateMessageCallback(GstBus*, GstMessage* message, MediaPlayerPrivateGStreamer* player)
{
- GOwnPtr<GError> err;
- GOwnPtr<gchar> debug;
- MediaPlayer::NetworkState error;
- MediaPlayerPrivateGStreamer* mp = reinterpret_cast<MediaPlayerPrivateGStreamer*>(data);
- bool issueError = true;
- bool attemptNextLocation = false;
- GstElement* pipeline = mp->pipeline();
-
- if (message->structure) {
- const gchar* messageTypeName = gst_structure_get_name(message->structure);
-
- // Redirect messages are sent from elements, like qtdemux, to
- // notify of the new location(s) of the media.
- if (!g_strcmp0(messageTypeName, "redirect")) {
- mp->mediaLocationChanged(message);
- return true;
- }
- }
-
- switch (GST_MESSAGE_TYPE(message)) {
- case GST_MESSAGE_ERROR:
- if (mp && mp->pipelineReset())
- break;
- gst_message_parse_error(message, &err.outPtr(), &debug.outPtr());
- LOG_VERBOSE(Media, "Error: %d, %s", err->code, err->message);
-
- error = MediaPlayer::Empty;
- if (err->code == GST_STREAM_ERROR_CODEC_NOT_FOUND
- || err->code == GST_STREAM_ERROR_WRONG_TYPE
- || err->code == GST_STREAM_ERROR_FAILED
- || err->code == GST_CORE_ERROR_MISSING_PLUGIN
- || err->code == GST_RESOURCE_ERROR_NOT_FOUND)
- error = MediaPlayer::FormatError;
- else if (err->domain == GST_STREAM_ERROR) {
- // Let the mediaPlayerClient handle the stream error, in
- // this case the HTMLMediaElement will emit a stalled
- // event.
- if (err->code == GST_STREAM_ERROR_TYPE_NOT_FOUND) {
- LOG_VERBOSE(Media, "Decode error, let the Media element emit a stalled event.");
- break;
- }
- error = MediaPlayer::DecodeError;
- attemptNextLocation = true;
- } else if (err->domain == GST_RESOURCE_ERROR)
- error = MediaPlayer::NetworkError;
-
- if (mp) {
- if (attemptNextLocation)
- issueError = !mp->loadNextLocation();
- if (issueError)
- mp->loadingFailed(error);
- }
- break;
- case GST_MESSAGE_EOS:
- LOG_VERBOSE(Media, "End of Stream");
- mp->didEnd();
- break;
- case GST_MESSAGE_STATE_CHANGED:
- // Ignore state changes if load is delayed (preload=none). The
- // player state will be updated once commitLoad() is called.
- if (mp->loadDelayed()) {
- LOG_VERBOSE(Media, "Media load has been delayed. Ignoring state changes for now");
- break;
- }
-
- // Ignore state changes from internal elements. They are
- // forwarded to playbin2 anyway.
- if (GST_MESSAGE_SRC(message) == reinterpret_cast<GstObject*>(pipeline))
- mp->updateStates();
- break;
- case GST_MESSAGE_BUFFERING:
- mp->processBufferingStats(message);
- break;
- case GST_MESSAGE_DURATION:
- LOG_VERBOSE(Media, "Duration changed");
- mp->durationChanged();
- break;
- default:
- LOG_VERBOSE(Media, "Unhandled GStreamer message type: %s",
- GST_MESSAGE_TYPE_NAME(message));
- break;
- }
- return true;
+ return player->handleMessage(message);
}
-void mediaPlayerPrivateSourceChangedCallback(GObject *object, GParamSpec *pspec, gpointer data)
+static void mediaPlayerPrivateSourceChangedCallback(GObject*, GParamSpec*, MediaPlayerPrivateGStreamer* player)
{
- MediaPlayerPrivateGStreamer* mp = reinterpret_cast<MediaPlayerPrivateGStreamer*>(data);
- GOwnPtr<GstElement> element;
-
- g_object_get(mp->m_playBin, "source", &element.outPtr(), NULL);
- gst_object_replace((GstObject**) &mp->m_source, (GstObject*) element.get());
-
- if (WEBKIT_IS_WEB_SRC(element.get())) {
- Frame* frame = mp->m_player->frameView() ? mp->m_player->frameView()->frame() : 0;
-
- if (frame)
- webKitWebSrcSetFrame(WEBKIT_WEB_SRC(element.get()), frame);
- }
+ player->sourceChanged();
}
-void mediaPlayerPrivateVolumeChangedCallback(GObject *element, GParamSpec *pspec, gpointer data)
+static void mediaPlayerPrivateVolumeChangedCallback(GObject*, GParamSpec*, MediaPlayerPrivateGStreamer* player)
{
// This is called when playbin receives the notify::volume signal.
- MediaPlayerPrivateGStreamer* mp = reinterpret_cast<MediaPlayerPrivateGStreamer*>(data);
- mp->volumeChanged();
+ player->volumeChanged();
}
-gboolean mediaPlayerPrivateVolumeChangeTimeoutCallback(MediaPlayerPrivateGStreamer* player)
+static gboolean mediaPlayerPrivateVolumeChangeTimeoutCallback(MediaPlayerPrivateGStreamer* player)
{
// This is the callback of the timeout source created in ::volumeChanged.
player->notifyPlayerOfVolumeChange();
return FALSE;
}
-void mediaPlayerPrivateMuteChangedCallback(GObject *element, GParamSpec *pspec, gpointer data)
+static void mediaPlayerPrivateMuteChangedCallback(GObject*, GParamSpec*, MediaPlayerPrivateGStreamer* player)
{
// This is called when playbin receives the notify::mute signal.
- MediaPlayerPrivateGStreamer* mp = reinterpret_cast<MediaPlayerPrivateGStreamer*>(data);
- mp->muteChanged();
+ player->muteChanged();
}
-gboolean mediaPlayerPrivateMuteChangeTimeoutCallback(MediaPlayerPrivateGStreamer* player)
+static gboolean mediaPlayerPrivateMuteChangeTimeoutCallback(MediaPlayerPrivateGStreamer* player)
{
// This is the callback of the timeout source created in ::muteChanged.
player->notifyPlayerOfMute();
return FALSE;
}
-void mediaPlayerPrivateVideoTagsChangedCallback(GObject* element, gint streamId, MediaPlayerPrivateGStreamer* player)
+static void mediaPlayerPrivateVideoSinkCapsChangedCallback(GObject*, GParamSpec*, MediaPlayerPrivateGStreamer* player)
{
- player->videoTagsChanged(streamId);
+ player->videoChanged();
}
-void mediaPlayerPrivateAudioTagsChangedCallback(GObject* element, gint streamId, MediaPlayerPrivateGStreamer* player)
+static void mediaPlayerPrivateVideoChangedCallback(GObject*, MediaPlayerPrivateGStreamer* player)
{
- player->audioTagsChanged(streamId);
+ player->videoChanged();
}
-gboolean mediaPlayerPrivateAudioTagsChangeTimeoutCallback(MediaPlayerPrivateGStreamer* player)
+static void mediaPlayerPrivateAudioChangedCallback(GObject*, MediaPlayerPrivateGStreamer* player)
{
- // This is the callback of the timeout source created in ::audioTagsChanged.
- player->notifyPlayerOfAudioTags();
- return FALSE;
+ player->audioChanged();
}
-gboolean mediaPlayerPrivateVideoTagsChangeTimeoutCallback(MediaPlayerPrivateGStreamer* player)
+static gboolean mediaPlayerPrivateAudioChangeTimeoutCallback(MediaPlayerPrivateGStreamer* player)
{
- // This is the callback of the timeout source created in ::videoTagsChanged.
- player->notifyPlayerOfVideoTags();
+ // This is the callback of the timeout source created in ::audioChanged.
+ player->notifyPlayerOfAudio();
return FALSE;
}
-static float playbackPosition(GstElement* playbin)
+static gboolean mediaPlayerPrivateVideoChangeTimeoutCallback(MediaPlayerPrivateGStreamer* player)
{
-
- float ret = 0.0f;
-
- GstQuery* query = gst_query_new_position(GST_FORMAT_TIME);
- if (!gst_element_query(playbin, query)) {
- LOG_VERBOSE(Media, "Position query failed...");
- gst_query_unref(query);
- return ret;
- }
-
- gint64 position;
- gst_query_parse_position(query, 0, &position);
-
- // Position is available only if the pipeline is not in GST_STATE_NULL or
- // GST_STATE_READY state.
- if (position != static_cast<gint64>(GST_CLOCK_TIME_NONE))
- ret = static_cast<float>(position) / static_cast<float>(GST_SECOND);
-
- LOG_VERBOSE(Media, "Position %" GST_TIME_FORMAT, GST_TIME_ARGS(position));
-
- gst_query_unref(query);
-
- return ret;
+ // This is the callback of the timeout source created in ::videoChanged.
+ player->notifyPlayerOfVideo();
+ return FALSE;
}
-
-void mediaPlayerPrivateRepaintCallback(WebKitVideoSink*, GstBuffer *buffer, MediaPlayerPrivateGStreamer* playerPrivate)
+static void mediaPlayerPrivateRepaintCallback(WebKitVideoSink*, GstBuffer *buffer, MediaPlayerPrivateGStreamer* playerPrivate)
{
- g_return_if_fail(GST_IS_BUFFER(buffer));
- gst_buffer_replace(&playerPrivate->m_buffer, buffer);
- playerPrivate->repaint();
+ playerPrivate->triggerRepaint(buffer);
}
MediaPlayerPrivateInterface* MediaPlayerPrivateGStreamer::create(MediaPlayer* player)
@@ -347,8 +227,9 @@ MediaPlayerPrivateGStreamer::MediaPlayerPrivateGStreamer(MediaPlayer* player)
, m_muteTimerHandler(0)
, m_hasVideo(false)
, m_hasAudio(false)
- , m_audioTagsTimerHandler(0)
- , m_videoTagsTimerHandler(0)
+ , m_audioTimerHandler(0)
+ , m_videoTimerHandler(0)
+ , m_webkitAudioSink(0)
{
if (doGstInit())
createGSTPlayBin();
@@ -392,11 +273,11 @@ MediaPlayerPrivateGStreamer::~MediaPlayerPrivateGStreamer()
if (m_volumeTimerHandler)
g_source_remove(m_volumeTimerHandler);
- if (m_videoTagsTimerHandler)
- g_source_remove(m_videoTagsTimerHandler);
+ if (m_videoTimerHandler)
+ g_source_remove(m_videoTimerHandler);
- if (m_audioTagsTimerHandler)
- g_source_remove(m_audioTagsTimerHandler);
+ if (m_audioTimerHandler)
+ g_source_remove(m_audioTimerHandler);
}
void MediaPlayerPrivateGStreamer::load(const String& url)
@@ -425,6 +306,32 @@ void MediaPlayerPrivateGStreamer::commitLoad()
updateStates();
}
+float MediaPlayerPrivateGStreamer::playbackPosition() const
+{
+ float ret = 0.0f;
+
+ GstQuery* query = gst_query_new_position(GST_FORMAT_TIME);
+ if (!gst_element_query(m_playBin, query)) {
+ LOG_VERBOSE(Media, "Position query failed...");
+ gst_query_unref(query);
+ return ret;
+ }
+
+ gint64 position;
+ gst_query_parse_position(query, 0, &position);
+
+ // Position is available only if the pipeline is not in GST_STATE_NULL or
+ // GST_STATE_READY state.
+ if (position != static_cast<gint64>(GST_CLOCK_TIME_NONE))
+ ret = static_cast<float>(position) / static_cast<float>(GST_SECOND);
+
+ LOG_VERBOSE(Media, "Position %" GST_TIME_FORMAT, GST_TIME_ARGS(position));
+
+ gst_query_unref(query);
+
+ return ret;
+}
+
bool MediaPlayerPrivateGStreamer::changePipelineState(GstState newState)
{
ASSERT(newState == GST_STATE_PLAYING || newState == GST_STATE_PAUSED);
@@ -504,14 +411,14 @@ float MediaPlayerPrivateGStreamer::currentTime() const
if (m_seeking)
return m_seekTime;
- return playbackPosition(m_playBin);
+ return playbackPosition();
}
void MediaPlayerPrivateGStreamer::seek(float time)
{
// Avoid useless seeking.
- if (time == playbackPosition(m_playBin))
+ if (time == playbackPosition())
return;
if (!m_playBin)
@@ -582,6 +489,7 @@ IntSize MediaPlayerPrivateGStreamer::naturalSize() const
|| !gst_video_parse_caps_pixel_aspect_ratio(caps, &pixelAspectRatioNumerator,
&pixelAspectRatioDenominator)) {
gst_object_unref(GST_OBJECT(pad));
+ // The video-sink has likely not yet negotiated its caps.
return IntSize();
}
@@ -618,39 +526,40 @@ IntSize MediaPlayerPrivateGStreamer::naturalSize() const
return IntSize(static_cast<int>(width), static_cast<int>(height));
}
-void MediaPlayerPrivateGStreamer::videoTagsChanged(gint streamId)
+void MediaPlayerPrivateGStreamer::videoChanged()
{
- if (m_videoTagsTimerHandler)
- g_source_remove(m_videoTagsTimerHandler);
- m_videoTagsTimerHandler = g_timeout_add(0, reinterpret_cast<GSourceFunc>(mediaPlayerPrivateVideoTagsChangeTimeoutCallback), this);
+ if (m_videoTimerHandler)
+ g_source_remove(m_videoTimerHandler);
+ m_videoTimerHandler = g_timeout_add(0, reinterpret_cast<GSourceFunc>(mediaPlayerPrivateVideoChangeTimeoutCallback), this);
}
-void MediaPlayerPrivateGStreamer::notifyPlayerOfVideoTags()
+void MediaPlayerPrivateGStreamer::notifyPlayerOfVideo()
{
- m_videoTagsTimerHandler = 0;
+ m_videoTimerHandler = 0;
- gint currentVideo = -1;
+ gint videoTracks = 0;
if (m_playBin)
- g_object_get(m_playBin, "current-video", &currentVideo, NULL);
- m_hasVideo = currentVideo > -1;
+ g_object_get(m_playBin, "n-video", &videoTracks, NULL);
+
+ m_hasVideo = videoTracks > 0;
m_player->mediaPlayerClient()->mediaPlayerEngineUpdated(m_player);
}
-void MediaPlayerPrivateGStreamer::audioTagsChanged(gint streamId)
+void MediaPlayerPrivateGStreamer::audioChanged()
{
- if (m_audioTagsTimerHandler)
- g_source_remove(m_audioTagsTimerHandler);
- m_audioTagsTimerHandler = g_timeout_add(0, reinterpret_cast<GSourceFunc>(mediaPlayerPrivateAudioTagsChangeTimeoutCallback), this);
+ if (m_audioTimerHandler)
+ g_source_remove(m_audioTimerHandler);
+ m_audioTimerHandler = g_timeout_add(0, reinterpret_cast<GSourceFunc>(mediaPlayerPrivateAudioChangeTimeoutCallback), this);
}
-void MediaPlayerPrivateGStreamer::notifyPlayerOfAudioTags()
+void MediaPlayerPrivateGStreamer::notifyPlayerOfAudio()
{
- m_audioTagsTimerHandler = 0;
+ m_audioTimerHandler = 0;
- gint currentAudio = -1;
+ gint audioTracks = 0;
if (m_playBin)
- g_object_get(m_playBin, "current-audio", &currentAudio, NULL);
- m_hasAudio = currentAudio > -1;
+ g_object_get(m_playBin, "n-audio", &audioTracks, NULL);
+ m_hasAudio = audioTracks > 0;
m_player->mediaPlayerClient()->mediaPlayerEngineUpdated(m_player);
}
@@ -704,13 +613,19 @@ void MediaPlayerPrivateGStreamer::setRate(float rate)
m_playbackRate = rate;
m_changingRate = true;
- float currentPosition = static_cast<float>(playbackPosition(m_playBin) * GST_SECOND);
+
+ if (!rate) {
+ gst_element_set_state(m_playBin, GST_STATE_PAUSED);
+ return;
+ }
+
+ float currentPosition = static_cast<float>(playbackPosition() * GST_SECOND);
GstSeekFlags flags = (GstSeekFlags)(GST_SEEK_FLAG_FLUSH);
gint64 start, end;
bool mute = false;
LOG_VERBOSE(Media, "Set Rate to %f", rate);
- if (rate >= 0) {
+ if (rate > 0) {
// Mute the sound if the playback rate is too extreme.
// TODO: in other cases we should perform pitch adjustments.
mute = (bool) (rate < 0.8 || rate > 2);
@@ -788,6 +703,89 @@ PassRefPtr<TimeRanges> MediaPlayerPrivateGStreamer::buffered() const
return timeRanges.release();
}
+gboolean MediaPlayerPrivateGStreamer::handleMessage(GstMessage* message)
+{
+ GOwnPtr<GError> err;
+ GOwnPtr<gchar> debug;
+ MediaPlayer::NetworkState error;
+ bool issueError = true;
+ bool attemptNextLocation = false;
+
+ if (message->structure) {
+ const gchar* messageTypeName = gst_structure_get_name(message->structure);
+
+ // Redirect messages are sent from elements, like qtdemux, to
+ // notify of the new location(s) of the media.
+ if (!g_strcmp0(messageTypeName, "redirect")) {
+ mediaLocationChanged(message);
+ return TRUE;
+ }
+ }
+
+ switch (GST_MESSAGE_TYPE(message)) {
+ case GST_MESSAGE_ERROR:
+ if (m_resetPipeline)
+ break;
+ gst_message_parse_error(message, &err.outPtr(), &debug.outPtr());
+ LOG_VERBOSE(Media, "Error: %d, %s", err->code, err->message);
+
+ error = MediaPlayer::Empty;
+ if (err->code == GST_STREAM_ERROR_CODEC_NOT_FOUND
+ || err->code == GST_STREAM_ERROR_WRONG_TYPE
+ || err->code == GST_STREAM_ERROR_FAILED
+ || err->code == GST_CORE_ERROR_MISSING_PLUGIN
+ || err->code == GST_RESOURCE_ERROR_NOT_FOUND)
+ error = MediaPlayer::FormatError;
+ else if (err->domain == GST_STREAM_ERROR) {
+ // Let the mediaPlayerClient handle the stream error, in
+ // this case the HTMLMediaElement will emit a stalled
+ // event.
+ if (err->code == GST_STREAM_ERROR_TYPE_NOT_FOUND) {
+ LOG_VERBOSE(Media, "Decode error, let the Media element emit a stalled event.");
+ break;
+ }
+ error = MediaPlayer::DecodeError;
+ attemptNextLocation = true;
+ } else if (err->domain == GST_RESOURCE_ERROR)
+ error = MediaPlayer::NetworkError;
+
+ if (attemptNextLocation)
+ issueError = !loadNextLocation();
+ if (issueError)
+ loadingFailed(error);
+ break;
+ case GST_MESSAGE_EOS:
+ LOG_VERBOSE(Media, "End of Stream");
+ didEnd();
+ break;
+ case GST_MESSAGE_STATE_CHANGED:
+ // Ignore state changes if load is delayed (preload=none). The
+ // player state will be updated once commitLoad() is called.
+ if (m_delayingLoad) {
+ LOG_VERBOSE(Media, "Media load has been delayed. Ignoring state changes for now");
+ break;
+ }
+
+ // Ignore state changes from internal elements. They are
+ // forwarded to playbin2 anyway.
+ if (GST_MESSAGE_SRC(message) == reinterpret_cast<GstObject*>(m_playBin))
+ updateStates();
+ break;
+ case GST_MESSAGE_BUFFERING:
+ processBufferingStats(message);
+ break;
+ case GST_MESSAGE_DURATION:
+ LOG_VERBOSE(Media, "Duration changed");
+ durationChanged();
+ break;
+ default:
+ LOG_VERBOSE(Media, "Unhandled GStreamer message type: %s",
+ GST_MESSAGE_TYPE_NAME(message));
+ break;
+ }
+ return TRUE;
+}
+
void MediaPlayerPrivateGStreamer::processBufferingStats(GstMessage* message)
{
// This is the immediate buffering that needs to happen so we have
@@ -952,6 +950,75 @@ unsigned MediaPlayerPrivateGStreamer::totalBytes() const
return static_cast<unsigned>(length);
}
+unsigned MediaPlayerPrivateGStreamer::decodedFrameCount() const
+{
+ guint64 decodedFrames = 0;
+ if (m_fpsSink)
+ g_object_get(m_fpsSink, "frames-rendered", &decodedFrames, NULL);
+ return static_cast<unsigned>(decodedFrames);
+}
+
+unsigned MediaPlayerPrivateGStreamer::droppedFrameCount() const
+{
+ guint64 framesDropped = 0;
+ if (m_fpsSink)
+ g_object_get(m_fpsSink, "frames-dropped", &framesDropped, NULL);
+ return static_cast<unsigned>(framesDropped);
+}
+
+unsigned MediaPlayerPrivateGStreamer::audioDecodedByteCount() const
+{
+ GstQuery* query = gst_query_new_position(GST_FORMAT_BYTES);
+ gint64 position = 0;
+
+ if (m_webkitAudioSink && gst_element_query(m_webkitAudioSink, query))
+ gst_query_parse_position(query, 0, &position);
+
+ gst_query_unref(query);
+ return static_cast<unsigned>(position);
+}
+
+unsigned MediaPlayerPrivateGStreamer::videoDecodedByteCount() const
+{
+ GstQuery* query = gst_query_new_position(GST_FORMAT_BYTES);
+ gint64 position = 0;
+
+ if (gst_element_query(m_webkitVideoSink, query))
+ gst_query_parse_position(query, 0, &position);
+
+ gst_query_unref(query);
+ return static_cast<unsigned>(position);
+}
+
+void MediaPlayerPrivateGStreamer::updateAudioSink()
+{
+ if (!m_playBin)
+ return;
+
+ GOwnPtr<GstElement> element;
+
+ g_object_get(m_playBin, "audio-sink", &element.outPtr(), NULL);
+ gst_object_replace(reinterpret_cast<GstObject**>(&m_webkitAudioSink),
+ reinterpret_cast<GstObject*>(element.get()));
+}
+
+
+void MediaPlayerPrivateGStreamer::sourceChanged()
+{
+ GOwnPtr<GstElement> element;
+
+ g_object_get(m_playBin, "source", &element.outPtr(), NULL);
+ gst_object_replace(reinterpret_cast<GstObject**>(&m_source),
+ reinterpret_cast<GstObject*>(element.get()));
+
+ if (WEBKIT_IS_WEB_SRC(element.get())) {
+ Frame* frame = m_player->frameView() ? m_player->frameView()->frame() : 0;
+
+ if (frame)
+ webKitWebSrcSetFrame(WEBKIT_WEB_SRC(element.get()), frame);
+ }
+}
+
void MediaPlayerPrivateGStreamer::cancelLoad()
{
if (m_networkState < MediaPlayer::Loading || m_networkState == MediaPlayer::Loaded)
@@ -1011,6 +1078,8 @@ void MediaPlayerPrivateGStreamer::updateStates()
// information from GStreamer, while we sync states where
// needed.
if (state == GST_STATE_PAUSED) {
+ if (!m_webkitAudioSink)
+ updateAudioSink();
if (m_buffering && m_bufferingPercentage == 100) {
m_buffering = false;
m_bufferingPercentage = 0;
@@ -1347,8 +1416,11 @@ void MediaPlayerPrivateGStreamer::setVisible(bool visible)
{
}
-void MediaPlayerPrivateGStreamer::repaint()
+
+void MediaPlayerPrivateGStreamer::triggerRepaint(GstBuffer* buffer)
{
+ g_return_if_fail(GST_IS_BUFFER(buffer));
+ gst_buffer_replace(&m_buffer, buffer);
m_player->repaint();
}
@@ -1359,6 +1431,7 @@ void MediaPlayerPrivateGStreamer::paint(GraphicsContext* context, const IntRect&
if (!m_player->visible())
return;
+
if (!m_buffer)
return;
@@ -1477,6 +1550,9 @@ static HashSet<String> mimeTypeCache()
|| (g_str_equal(mimetype[0], "application")
&& handledApplicationSubtypes.contains(String(mimetype[1]))))
cache.add(String(name));
+ else if (g_str_equal(name, "application/x-hls"))
+ cache.add(String("application/vnd.apple.mpegurl"));
+
g_strfreev(mimetype);
}
@@ -1584,8 +1660,8 @@ void MediaPlayerPrivateGStreamer::createGSTPlayBin()
g_signal_connect(m_playBin, "notify::volume", G_CALLBACK(mediaPlayerPrivateVolumeChangedCallback), this);
g_signal_connect(m_playBin, "notify::source", G_CALLBACK(mediaPlayerPrivateSourceChangedCallback), this);
g_signal_connect(m_playBin, "notify::mute", G_CALLBACK(mediaPlayerPrivateMuteChangedCallback), this);
- g_signal_connect(m_playBin, "video-tags-changed", G_CALLBACK(mediaPlayerPrivateVideoTagsChangedCallback), this);
- g_signal_connect(m_playBin, "audio-tags-changed", G_CALLBACK(mediaPlayerPrivateAudioTagsChangedCallback), this);
+ g_signal_connect(m_playBin, "video-changed", G_CALLBACK(mediaPlayerPrivateVideoChangedCallback), this);
+ g_signal_connect(m_playBin, "audio-changed", G_CALLBACK(mediaPlayerPrivateAudioChangedCallback), this);
m_webkitVideoSink = webkit_video_sink_new();
@@ -1613,39 +1689,44 @@ void MediaPlayerPrivateGStreamer::createGSTPlayBin()
gst_object_unref(GST_OBJECT(srcPad));
gst_object_unref(GST_OBJECT(sinkPad));
- WTFLogChannel* channel = getChannelFromName("Media");
- if (channel->state == WTFLogChannelOn) {
- m_fpsSink = gst_element_factory_make("fpsdisplaysink", "sink");
- if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_fpsSink), "video-sink")) {
- g_object_set(m_fpsSink, "video-sink", m_webkitVideoSink, NULL);
- gst_bin_add(GST_BIN(m_videoSinkBin), m_fpsSink);
-#if GST_CHECK_VERSION(0, 10, 30)
- // Faster elements linking, if possible.
- gst_element_link_pads_full(queue, "src", m_fpsSink, "sink", GST_PAD_LINK_CHECK_NOTHING);
-#else
- gst_element_link(queue, m_fpsSink);
-#endif
- } else {
+ GstElement* actualVideoSink = 0;
+ m_fpsSink = gst_element_factory_make("fpsdisplaysink", "sink");
+ if (m_fpsSink) {
+ // The verbose property has been added in -bad 0.10.22. Making
+ // this whole code depend on it because we don't want
+ // fpsdiplaysink to spit data on stdout.
+ GstElementFactory* factory = GST_ELEMENT_FACTORY(GST_ELEMENT_GET_CLASS(m_fpsSink)->elementfactory);
+ if (gst_plugin_feature_check_version(GST_PLUGIN_FEATURE(factory), 0, 10, 22)) {
+ g_object_set(m_fpsSink, "silent", TRUE , NULL);
+
+ // Turn off text overlay unless logging is enabled.
+ WTFLogChannel* channel = getChannelFromName("Media");
+ if (channel->state != WTFLogChannelOn)
+ g_object_set(m_fpsSink, "text-overlay", FALSE , NULL);
+
+ if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_fpsSink), "video-sink")) {
+ g_object_set(m_fpsSink, "video-sink", m_webkitVideoSink, NULL);
+ gst_bin_add(GST_BIN(m_videoSinkBin), m_fpsSink);
+ actualVideoSink = m_fpsSink;
+ } else
+ m_fpsSink = 0;
+ } else
m_fpsSink = 0;
- gst_bin_add(GST_BIN(m_videoSinkBin), m_webkitVideoSink);
-#if GST_CHECK_VERSION(0, 10, 30)
- // Faster elements linking, if possible.
- gst_element_link_pads_full(queue, "src", m_webkitVideoSink, "sink", GST_PAD_LINK_CHECK_NOTHING);
-#else
- gst_element_link(queue, m_webkitVideoSink);
-#endif
- LOG_VERBOSE(Media, "Can't display FPS statistics, you need gst-plugins-bad >= 0.10.18");
- }
- } else {
+ }
+
+ if (!m_fpsSink) {
gst_bin_add(GST_BIN(m_videoSinkBin), m_webkitVideoSink);
+ actualVideoSink = m_webkitVideoSink;
+ }
+
+ ASSERT(actualVideoSink);
#if GST_CHECK_VERSION(0, 10, 30)
// Faster elements linking, if possible.
gst_element_link_pads_full(queue, "src", identity, "sink", GST_PAD_LINK_CHECK_NOTHING);
- gst_element_link_pads_full(identity, "src", m_webkitVideoSink, "sink", GST_PAD_LINK_CHECK_NOTHING);
+ gst_element_link_pads_full(identity, "src", actualVideoSink, "sink", GST_PAD_LINK_CHECK_NOTHING);
#else
- gst_element_link_many(queue, identity, m_webkitVideoSink, NULL);
+ gst_element_link_many(queue, identity, actualVideoSink, NULL);
#endif
- }
// Add a ghostpad to the bin so it can proxy to tee.
GstPad* pad = gst_element_get_static_pad(videoTee, "sink");
@@ -1654,6 +1735,14 @@ void MediaPlayerPrivateGStreamer::createGSTPlayBin()
// Set the bin as video sink of playbin.
g_object_set(m_playBin, "video-sink", m_videoSinkBin, NULL);
+
+
+ pad = gst_element_get_static_pad(m_webkitVideoSink, "sink");
+ if (pad) {
+ g_signal_connect(pad, "notify::caps", G_CALLBACK(mediaPlayerPrivateVideoSinkCapsChangedCallback), this);
+ gst_object_unref(GST_OBJECT(pad));
+ }
+
}
}
diff --git a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h
index 8003887..024fad0 100644
--- a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h
+++ b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h
@@ -35,7 +35,6 @@ typedef struct _WebKitVideoSink WebKitVideoSink;
typedef struct _GstBuffer GstBuffer;
typedef struct _GstMessage GstMessage;
typedef struct _GstElement GstElement;
-typedef struct _GstBus GstBus;
namespace WebCore {
@@ -45,25 +44,11 @@ class IntRect;
class GStreamerGWorld;
class MediaPlayerPrivateGStreamer;
-gboolean mediaPlayerPrivateMessageCallback(GstBus* bus, GstMessage* message, gpointer data);
-void mediaPlayerPrivateVolumeChangedCallback(GObject* element, GParamSpec* pspec, gpointer data);
-void mediaPlayerPrivateMuteChangedCallback(GObject* element, GParamSpec* pspec, gpointer data);
-void mediaPlayerPrivateSourceChangedCallback(GObject* element, GParamSpec* pspec, gpointer data);
-void mediaPlayerPrivateVideoTagsChangedCallback(GObject* element, gint, MediaPlayerPrivateGStreamer*);
-void mediaPlayerPrivateAudioTagsChangedCallback(GObject* element, gint, MediaPlayerPrivateGStreamer*);
-gboolean mediaPlayerPrivateAudioTagsChangeTimeoutCallback(MediaPlayerPrivateGStreamer* player);
-gboolean mediaPlayerPrivateVideoTagsChangeTimeoutCallback(MediaPlayerPrivateGStreamer* player);
-
-gboolean mediaPlayerPrivateVolumeChangeTimeoutCallback(MediaPlayerPrivateGStreamer*);
-gboolean mediaPlayerPrivateMuteChangeTimeoutCallback(MediaPlayerPrivateGStreamer*);
-
class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateInterface {
- friend gboolean mediaPlayerPrivateMessageCallback(GstBus* bus, GstMessage* message, gpointer data);
- friend void mediaPlayerPrivateRepaintCallback(WebKitVideoSink*, GstBuffer* buffer, MediaPlayerPrivateGStreamer* playerPrivate);
- friend void mediaPlayerPrivateSourceChangedCallback(GObject* element, GParamSpec* pspec, gpointer data);
public:
static void registerMediaEngine(MediaEngineRegistrar);
+ gboolean handleMessage(GstMessage*);
IntSize naturalSize() const;
bool hasVideo() const { return m_hasVideo; }
@@ -72,7 +57,6 @@ class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateInterface {
void load(const String &url);
void commitLoad();
void cancelLoad();
- bool loadNextLocation();
void prepareToPlay();
void play();
@@ -96,7 +80,6 @@ class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateInterface {
void muteChanged();
void notifyPlayerOfMute();
- bool loadDelayed() const { return m_delayingLoad; }
void setPreload(MediaPlayer::Preload);
void fillTimerFired(Timer<MediaPlayerPrivateGStreamer>*);
@@ -111,7 +94,6 @@ class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateInterface {
void setVisible(bool);
void setSize(const IntSize&);
- void mediaLocationChanged(GstMessage*);
void loadStateChanged();
void sizeChanged();
void timeChanged();
@@ -119,6 +101,7 @@ class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateInterface {
void durationChanged();
void loadingFailed(MediaPlayer::NetworkState);
+ void triggerRepaint(GstBuffer*);
void repaint();
void paint(GraphicsContext*, const IntRect&);
@@ -127,13 +110,17 @@ class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateInterface {
bool supportsFullscreen() const;
PlatformMedia platformMedia() const;
- GstElement* pipeline() const { return m_playBin; }
- bool pipelineReset() const { return m_resetPipeline; }
+ void videoChanged();
+ void audioChanged();
+ void notifyPlayerOfVideo();
+ void notifyPlayerOfAudio();
+
+ void sourceChanged();
- void videoTagsChanged(gint);
- void audioTagsChanged(gint);
- void notifyPlayerOfVideoTags();
- void notifyPlayerOfAudioTags();
+ unsigned decodedFrameCount() const;
+ unsigned droppedFrameCount() const;
+ unsigned audioDecodedByteCount() const;
+ unsigned videoDecodedByteCount() const;
private:
MediaPlayerPrivateGStreamer(MediaPlayer*);
@@ -145,6 +132,10 @@ class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateInterface {
static MediaPlayer::SupportsType supportsType(const String& type, const String& codecs);
static bool isAvailable();
+ void updateAudioSink();
+
+ float playbackPosition() const;
+
void cacheDuration();
void updateStates();
float maxTimeLoaded() const;
@@ -152,7 +143,10 @@ class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateInterface {
void createGSTPlayBin();
bool changePipelineState(GstState state);
- void processBufferingStats(GstMessage* message);
+ bool loadNextLocation();
+ void mediaLocationChanged(GstMessage*);
+
+ void processBufferingStats(GstMessage*);
private:
MediaPlayer* m_player;
@@ -191,8 +185,9 @@ class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateInterface {
guint m_muteTimerHandler;
bool m_hasVideo;
bool m_hasAudio;
- guint m_audioTagsTimerHandler;
- guint m_videoTagsTimerHandler;
+ guint m_audioTimerHandler;
+ guint m_videoTimerHandler;
+ GstElement* m_webkitAudioSink;
};
}
diff --git a/Source/WebCore/platform/graphics/gstreamer/PlatformVideoWindowPrivate.h b/Source/WebCore/platform/graphics/gstreamer/PlatformVideoWindowPrivate.h
index 0ae4587..7b441f4 100644
--- a/Source/WebCore/platform/graphics/gstreamer/PlatformVideoWindowPrivate.h
+++ b/Source/WebCore/platform/graphics/gstreamer/PlatformVideoWindowPrivate.h
@@ -20,21 +20,37 @@
#ifndef PlatformVideoWindowPrivate_h
#define PlatformVideoWindowPrivate_h
+#include <QTimer>
#include <QWidget>
class QKeyEvent;
namespace WebCore {
+class HTMLVideoElement;
+
class FullScreenVideoWindow: public QWidget {
Q_OBJECT
public:
FullScreenVideoWindow();
+ void setVideoElement(HTMLVideoElement*);
signals:
void closed();
protected:
- void keyPressEvent(QKeyEvent* ev);
- bool event(QEvent* ev);
+ void closeEvent(QCloseEvent*);
+ void keyPressEvent(QKeyEvent*);
+ bool event(QEvent*);
+
+public slots:
+ void showFullScreen();
+
+private slots:
+ void hideCursor();
+
+private:
+ void showCursor();
+ QTimer m_cursorTimer;
+ HTMLVideoElement* m_mediaElement;
};
diff --git a/Source/WebCore/platform/graphics/gstreamer/PlatformVideoWindowQt.cpp b/Source/WebCore/platform/graphics/gstreamer/PlatformVideoWindowQt.cpp
index 872d055..7270785 100644
--- a/Source/WebCore/platform/graphics/gstreamer/PlatformVideoWindowQt.cpp
+++ b/Source/WebCore/platform/graphics/gstreamer/PlatformVideoWindowQt.cpp
@@ -20,6 +20,7 @@
#include "config.h"
#include "PlatformVideoWindow.h"
+#include "HTMLVideoElement.h"
#include "PlatformVideoWindowPrivate.h"
#include <QApplication>
@@ -28,29 +29,55 @@
#include <QPalette>
using namespace WebCore;
+static const int gHideMouseCursorDelay = 3000;
+
FullScreenVideoWindow::FullScreenVideoWindow()
: QWidget(0, Qt::Window)
+ , m_mediaElement(0)
{
setAttribute(Qt::WA_NativeWindow);
- // Setting these values ensures smooth resizing since it
- // will prevent the system from clearing the background.
+ setWindowModality(Qt::ApplicationModal);
setAttribute(Qt::WA_NoSystemBackground, true);
setAttribute(Qt::WA_PaintOnScreen, true);
+
+ m_cursorTimer.setSingleShot(true);
+ connect(&m_cursorTimer, SIGNAL(timeout()), this, SLOT(hideCursor()));
+}
+
+void FullScreenVideoWindow::setVideoElement(HTMLVideoElement* element)
+{
+ m_mediaElement = element;
+}
+
+void FullScreenVideoWindow::closeEvent(QCloseEvent*)
+{
+ m_cursorTimer.stop();
+ setMouseTracking(false);
+ releaseMouse();
+ QApplication::restoreOverrideCursor();
}
void FullScreenVideoWindow::keyPressEvent(QKeyEvent* ev)
{
- if (ev->key() == Qt::Key_Escape) {
- close();
+ if (m_mediaElement && ev->key() == Qt::Key_Space) {
+ if (!m_mediaElement->paused())
+ m_mediaElement->pause(true);
+ else
+ m_mediaElement->play(true);
+ } else if (ev->key() == Qt::Key_Escape)
emit closed();
- }
+ QWidget::keyPressEvent(ev);
}
bool FullScreenVideoWindow::event(QEvent* ev)
{
switch (ev->type()) {
+ case QEvent::MouseMove:
+ showCursor();
+ ev->accept();
+ return true;
case QEvent::MouseButtonDblClick:
- close();
+ emit closed();
ev->accept();
return true;
default:
@@ -58,6 +85,26 @@ bool FullScreenVideoWindow::event(QEvent* ev)
}
}
+void FullScreenVideoWindow::showFullScreen()
+{
+ QWidget::showFullScreen();
+ setMouseTracking(true);
+ raise();
+ setFocus();
+ hideCursor();
+}
+
+void FullScreenVideoWindow::hideCursor()
+{
+ QApplication::setOverrideCursor(QCursor(Qt::BlankCursor));
+}
+
+void FullScreenVideoWindow::showCursor()
+{
+ QApplication::restoreOverrideCursor();
+ m_cursorTimer.start(gHideMouseCursorDelay);
+}
+
PlatformVideoWindow::PlatformVideoWindow()
{
diff --git a/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp b/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp
index 66ea9ba..e48998f 100644
--- a/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp
+++ b/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp
@@ -791,7 +791,7 @@ void StreamingClient::didReceiveResponse(ResourceHandle*, const ResourceResponse
gst_element_found_tags_for_pad(GST_ELEMENT(m_src), m_src->priv->srcpad, tags);
}
-void StreamingClient::didReceiveData(ResourceHandle* handle, const char* data, int length, int lengthReceived)
+void StreamingClient::didReceiveData(ResourceHandle* handle, const char* data, int length, int encodedDataLength)
{
WebKitWebSrcPrivate* priv = m_src->priv;
diff --git a/Source/WebCore/platform/graphics/gtk/DrawingBufferGtk.cpp b/Source/WebCore/platform/graphics/gtk/DrawingBufferGtk.cpp
new file mode 100644
index 0000000..17fc334
--- /dev/null
+++ b/Source/WebCore/platform/graphics/gtk/DrawingBufferGtk.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(ACCELERATED_2D_CANVAS) || ENABLE(WEBGL)
+
+#include "DrawingBuffer.h"
+
+#include "Extensions3D.h"
+
+namespace WebCore {
+
+DrawingBuffer::DrawingBuffer(GraphicsContext3D* context,
+ const IntSize& size,
+ bool multisampleExtensionSupported,
+ bool packedDepthStencilExtensionSupported)
+ : m_context(context)
+ , m_size(-1, -1)
+ , m_multisampleExtensionSupported(multisampleExtensionSupported)
+ , m_packedDepthStencilExtensionSupported(packedDepthStencilExtensionSupported)
+ , m_fbo(context->createFramebuffer())
+ , m_colorBuffer(0)
+ , m_depthStencilBuffer(0)
+ , m_multisampleFBO(0)
+ , m_multisampleColorBuffer(0)
+{
+ ASSERT(m_fbo);
+ if (!m_fbo) {
+ clear();
+ return;
+ }
+
+ // create a texture to render into
+ m_colorBuffer = context->createTexture();
+ context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_colorBuffer);
+ context->texParameterf(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR);
+ context->texParameterf(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR);
+ context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE);
+ context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE);
+ context->bindTexture(GraphicsContext3D::TEXTURE_2D, 0);
+
+ // Create the FBO
+ m_fbo = context->createFramebuffer();
+ ASSERT(m_fbo);
+ if (!m_fbo) {
+ clear();
+ return;
+ }
+
+ createSecondaryBuffers();
+ reset(size);
+}
+
+DrawingBuffer::~DrawingBuffer()
+{
+ clear();
+}
+
+void DrawingBuffer::didReset()
+{
+}
+
+Platform3DObject DrawingBuffer::platformColorBuffer() const
+{
+ return m_colorBuffer;
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/platform/graphics/gtk/FontGtk.cpp b/Source/WebCore/platform/graphics/gtk/FontGtk.cpp
index d14b052..977aa62 100644
--- a/Source/WebCore/platform/graphics/gtk/FontGtk.cpp
+++ b/Source/WebCore/platform/graphics/gtk/FontGtk.cpp
@@ -35,9 +35,10 @@
#include "CairoUtilities.h"
#include "ContextShadow.h"
-#include "PlatformContextCairo.h"
+#include "GOwnPtr.h"
#include "GraphicsContext.h"
#include "NotImplemented.h"
+#include "PlatformContextCairo.h"
#include "SimpleFontData.h"
#include "TextRun.h"
#include <cairo.h>
@@ -84,75 +85,71 @@ IntRect getPangoRegionExtents(PangoRegionType region)
#define IS_HIGH_SURROGATE(u) ((UChar)(u) >= (UChar)0xd800 && (UChar)(u) <= (UChar)0xdbff)
#define IS_LOW_SURROGATE(u) ((UChar)(u) >= (UChar)0xdc00 && (UChar)(u) <= (UChar)0xdfff)
-static void utf16_to_utf8(const UChar* aText, gint aLength, char* &text, gint &length)
+static gchar* utf16ToUtf8(const UChar* aText, gint aLength, gint &length)
{
- gboolean need_copy = FALSE;
- int i;
+ gboolean needCopy = FALSE;
- for (i = 0; i < aLength; i++) {
- if (!aText[i] || IS_LOW_SURROGATE(aText[i])) {
- need_copy = TRUE;
- break;
- }
- else if (IS_HIGH_SURROGATE(aText[i])) {
- if (i < aLength - 1 && IS_LOW_SURROGATE(aText[i+1]))
- i++;
- else {
- need_copy = TRUE;
- break;
- }
+ for (int i = 0; i < aLength; i++) {
+ if (!aText[i] || IS_LOW_SURROGATE(aText[i])) {
+ needCopy = TRUE;
+ break;
+ }
+
+ if (IS_HIGH_SURROGATE(aText[i])) {
+ if (i < aLength - 1 && IS_LOW_SURROGATE(aText[i+1]))
+ i++;
+ else {
+ needCopy = TRUE;
+ break;
+ }
+ }
}
- }
-
- if (need_copy) {
- /* Pango doesn't correctly handle nuls. We convert them to 0xff. */
- /* Also "validate" UTF-16 text to make sure conversion doesn't fail. */
-
- UChar* p = (UChar*)g_memdup(aText, aLength * sizeof(aText[0]));
-
- /* don't need to reset i */
- for (i = 0; i < aLength; i++) {
- if (!p[i] || IS_LOW_SURROGATE(p[i]))
- p[i] = 0xFFFD;
- else if (IS_HIGH_SURROGATE(p[i])) {
- if (i < aLength - 1 && IS_LOW_SURROGATE(aText[i+1]))
- i++;
- else
- p[i] = 0xFFFD;
- }
+ GOwnPtr<UChar> copiedString;
+ if (needCopy) {
+ /* Pango doesn't correctly handle nuls. We convert them to 0xff. */
+ /* Also "validate" UTF-16 text to make sure conversion doesn't fail. */
+
+ copiedString.set(static_cast<UChar*>(g_memdup(aText, aLength * sizeof(aText[0]))));
+ UChar* p = copiedString.get();
+
+ /* don't need to reset i */
+ for (int i = 0; i < aLength; i++) {
+ if (!p[i] || IS_LOW_SURROGATE(p[i]))
+ p[i] = 0xFFFD;
+ else if (IS_HIGH_SURROGATE(p[i])) {
+ if (i < aLength - 1 && IS_LOW_SURROGATE(aText[i+1]))
+ i++;
+ else
+ p[i] = 0xFFFD;
+ }
+ }
+
+ aText = p;
}
- aText = p;
- }
-
- glong items_written;
- text = g_utf16_to_utf8(reinterpret_cast<const gunichar2*>(aText), aLength, NULL, &items_written, NULL);
- length = items_written;
-
- if (need_copy)
- g_free((gpointer)aText);
+ gchar* utf8Text;
+ glong itemsWritten;
+ utf8Text = g_utf16_to_utf8(static_cast<const gunichar2*>(aText), aLength, 0, &itemsWritten, 0);
+ length = itemsWritten;
+ return utf8Text;
}
static gchar* convertUniCharToUTF8(const UChar* characters, gint length, int from, int to)
{
- gchar* utf8 = 0;
- gint new_length = 0;
- utf16_to_utf8(characters, length, utf8, new_length);
- if (!utf8)
- return NULL;
+ gint newLength = 0;
+ GOwnPtr<gchar> utf8Text(utf16ToUtf8(characters, length, newLength));
+ if (!utf8Text)
+ return 0;
+ gchar* pos = utf8Text.get();
if (from > 0) {
// discard the first 'from' characters
// FIXME: we should do this before the conversion probably
- gchar* str_left = g_utf8_offset_to_pointer(utf8, from);
- gchar* tmp = g_strdup(str_left);
- g_free(utf8);
- utf8 = tmp;
+ pos = g_utf8_offset_to_pointer(utf8Text.get(), from);
}
- gchar* pos = utf8;
gint len = strlen(pos);
GString* ret = g_string_new_len(NULL, len);
diff --git a/Source/WebCore/platform/graphics/gtk/GraphicsContext3DGtk.cpp b/Source/WebCore/platform/graphics/gtk/GraphicsContext3DGtk.cpp
new file mode 100644
index 0000000..8e03ad7
--- /dev/null
+++ b/Source/WebCore/platform/graphics/gtk/GraphicsContext3DGtk.cpp
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "GraphicsContext3D.h"
+
+#if ENABLE(WEBGL)
+
+#include "Extensions3DOpenGL.h"
+#include "GraphicsContext3DInternal.h"
+#include "OpenGLShims.h"
+#include "ShaderLang.h"
+#include <wtf/NotFound.h>
+
+namespace WebCore {
+
+PassRefPtr<GraphicsContext3D> GraphicsContext3D::create(GraphicsContext3D::Attributes attributes, HostWindow* hostWindow, GraphicsContext3D::RenderStyle renderStyle)
+{
+ // This implementation doesn't currently support rendering directly to the HostWindow.
+ if (renderStyle == RenderDirectlyToHostWindow)
+ return 0;
+
+ GraphicsContext3DInternal* internal = GraphicsContext3DInternal::create();
+ if (!internal)
+ return 0;
+
+ RefPtr<GraphicsContext3D> context = adoptRef(new GraphicsContext3D(attributes, hostWindow, false));
+ context->m_internal.set(internal);
+ return context.release();
+}
+
+GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attributes, HostWindow*, bool)
+ : m_currentWidth(0)
+ , m_currentHeight(0)
+ , m_attrs(attributes)
+ , m_texture(0)
+ , m_fbo(0)
+ , m_depthStencilBuffer(0)
+ , m_boundFBO(0)
+ , m_multisampleFBO(0)
+ , m_multisampleDepthStencilBuffer(0)
+ , m_multisampleColorBuffer(0)
+{
+ GraphicsContext3DInternal::addActiveGraphicsContext(this);
+
+ validateAttributes();
+
+ // Create a texture to render into.
+ ::glGenTextures(1, &m_texture);
+ ::glBindTexture(GL_TEXTURE_2D, m_texture);
+ ::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ ::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ ::glBindTexture(GL_TEXTURE_2D, 0);
+
+ // Create an FBO.
+ ::glGenFramebuffersEXT(1, &m_fbo);
+ ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
+
+ m_boundFBO = m_fbo;
+ if (!m_attrs.antialias && (m_attrs.stencil || m_attrs.depth))
+ ::glGenRenderbuffersEXT(1, &m_depthStencilBuffer);
+
+ // Create a multisample FBO.
+ if (m_attrs.antialias) {
+ ::glGenFramebuffersEXT(1, &m_multisampleFBO);
+ ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
+ m_boundFBO = m_multisampleFBO;
+ ::glGenRenderbuffersEXT(1, &m_multisampleColorBuffer);
+ if (m_attrs.stencil || m_attrs.depth)
+ ::glGenRenderbuffersEXT(1, &m_multisampleDepthStencilBuffer);
+ }
+
+ // ANGLE initialization.
+ ShBuiltInResources ANGLEResources;
+ ShInitBuiltInResources(&ANGLEResources);
+
+ getIntegerv(GraphicsContext3D::MAX_VERTEX_ATTRIBS, &ANGLEResources.MaxVertexAttribs);
+ getIntegerv(GraphicsContext3D::MAX_VERTEX_UNIFORM_VECTORS, &ANGLEResources.MaxVertexUniformVectors);
+ getIntegerv(GraphicsContext3D::MAX_VARYING_VECTORS, &ANGLEResources.MaxVaryingVectors);
+ getIntegerv(GraphicsContext3D::MAX_VERTEX_TEXTURE_IMAGE_UNITS, &ANGLEResources.MaxVertexTextureImageUnits);
+ getIntegerv(GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS, &ANGLEResources.MaxCombinedTextureImageUnits);
+ getIntegerv(GraphicsContext3D::MAX_TEXTURE_IMAGE_UNITS, &ANGLEResources.MaxTextureImageUnits);
+ getIntegerv(GraphicsContext3D::MAX_FRAGMENT_UNIFORM_VECTORS, &ANGLEResources.MaxFragmentUniformVectors);
+
+ // Always set to 1 for OpenGL ES.
+ ANGLEResources.MaxDrawBuffers = 1;
+ m_compiler.setResources(ANGLEResources);
+
+ ::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
+ ::glEnable(GL_POINT_SPRITE);
+ ::glClearColor(0, 0, 0, 0);
+}
+
+GraphicsContext3D::~GraphicsContext3D()
+{
+ GraphicsContext3DInternal::removeActiveGraphicsContext(this);
+ if (!m_internal->m_context)
+ return;
+
+ makeContextCurrent();
+ ::glDeleteTextures(1, &m_texture);
+ if (m_attrs.antialias) {
+ ::glDeleteRenderbuffersEXT(1, &m_multisampleColorBuffer);
+ if (m_attrs.stencil || m_attrs.depth)
+ ::glDeleteRenderbuffersEXT(1, &m_multisampleDepthStencilBuffer);
+ ::glDeleteFramebuffersEXT(1, &m_multisampleFBO);
+ } else {
+ if (m_attrs.stencil || m_attrs.depth)
+ ::glDeleteRenderbuffersEXT(1, &m_depthStencilBuffer);
+ }
+ ::glDeleteFramebuffersEXT(1, &m_fbo);
+}
+
+void GraphicsContext3D::makeContextCurrent()
+{
+ if (!m_internal)
+ return;
+ m_internal->makeContextCurrent();
+}
+
+PlatformGraphicsContext3D GraphicsContext3D::platformGraphicsContext3D()
+{
+ return m_internal->m_context;
+}
+
+bool GraphicsContext3D::isGLES2Compliant() const
+{
+ return false;
+}
+
+}
+
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/platform/graphics/gtk/GraphicsContext3DInternal.cpp b/Source/WebCore/platform/graphics/gtk/GraphicsContext3DInternal.cpp
new file mode 100644
index 0000000..de24554
--- /dev/null
+++ b/Source/WebCore/platform/graphics/gtk/GraphicsContext3DInternal.cpp
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2011 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "GraphicsContext3DInternal.h"
+
+#if ENABLE(WEBGL)
+
+#include "GraphicsContext3D.h"
+#include "OpenGLShims.h"
+#include <GL/glx.h>
+#include <dlfcn.h>
+
+// We do not want to call glXMakeContextCurrent using different Display pointers,
+// because it might lead to crashes in some drivers (fglrx). We use a shared display
+// pointer here.
+static Display* gSharedDisplay = 0;
+static Display* sharedDisplay()
+{
+ if (!gSharedDisplay)
+ gSharedDisplay = XOpenDisplay(0);
+ return gSharedDisplay;
+}
+
+namespace WebCore {
+
+// Because of driver bugs, exiting the program when there are active pbuffers
+// can crash the X server (this has been observed with the official Nvidia drivers).
+// We need to ensure that we clean everything up on exit. There are several reasons
+// that GraphicsContext3Ds will still be alive at exit, including user error (memory
+// leaks) and the page cache. In any case, we don't want the X server to crash.
+static bool cleaningUpAtExit = false;
+static Vector<GraphicsContext3D*>& activeGraphicsContexts()
+{
+ DEFINE_STATIC_LOCAL(Vector<GraphicsContext3D*>, contexts, ());
+ return contexts;
+}
+
+void GraphicsContext3DInternal::addActiveGraphicsContext(GraphicsContext3D* context)
+{
+ static bool addedAtExitHandler = false;
+ if (!addedAtExitHandler) {
+ atexit(&GraphicsContext3DInternal::cleanupActiveContextsAtExit);
+ addedAtExitHandler = true;
+ }
+ activeGraphicsContexts().append(context);
+}
+
+void GraphicsContext3DInternal::removeActiveGraphicsContext(GraphicsContext3D* context)
+{
+ if (cleaningUpAtExit)
+ return;
+
+ Vector<GraphicsContext3D*>& contexts = activeGraphicsContexts();
+ size_t location = contexts.find(context);
+ if (location != WTF::notFound)
+ contexts.remove(location);
+}
+
+void GraphicsContext3DInternal::cleanupActiveContextsAtExit()
+{
+ cleaningUpAtExit = true;
+
+ Vector<GraphicsContext3D*>& contexts = activeGraphicsContexts();
+ for (size_t i = 0; i < contexts.size(); i++)
+ contexts[i]->~GraphicsContext3D();
+
+ if (!gSharedDisplay)
+ return;
+ XCloseDisplay(gSharedDisplay);
+ gSharedDisplay = 0;
+}
+
+GraphicsContext3DInternal* GraphicsContext3DInternal::create()
+{
+ if (!sharedDisplay())
+ return 0;
+
+ static bool initialized = false;
+ static bool success = true;
+ if (!initialized) {
+ success = initializeOpenGLShims();
+ initialized = true;
+ }
+ if (!success)
+ return 0;
+
+ GraphicsContext3DInternal* internal = createPbufferContext();
+ if (!internal)
+ internal = createPixmapContext();
+ if (!internal)
+ return 0;
+
+ // The GraphicsContext3D constructor requires that this context is the current OpenGL context.
+ internal->makeContextCurrent();
+ return internal;
+}
+
+GraphicsContext3DInternal* GraphicsContext3DInternal::createPbufferContext()
+{
+ int fbConfigAttributes[] = {
+ GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT,
+ GLX_RENDER_TYPE, GLX_RGBA_BIT,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ GLX_ALPHA_SIZE, 1,
+ GLX_DEPTH_SIZE, 1,
+ GLX_STENCIL_SIZE, 1,
+ GLX_SAMPLE_BUFFERS, 1,
+ GLX_DOUBLEBUFFER, GL_FALSE,
+ GLX_SAMPLES, 4,
+ 0
+ };
+ int returnedElements;
+ GLXFBConfig* configs = glXChooseFBConfig(sharedDisplay(), 0, fbConfigAttributes, &returnedElements);
+ if (!configs) {
+ fbConfigAttributes[20] = 0; // Attempt without anti-aliasing.
+ configs = glXChooseFBConfig(sharedDisplay(), 0, fbConfigAttributes, &returnedElements);
+ }
+ if (!returnedElements) {
+ XFree(configs);
+ return 0;
+ }
+
+ // We will be rendering to a texture, so our pbuffer does not need to be large.
+ static const int pbufferAttributes[] = { GLX_PBUFFER_WIDTH, 1, GLX_PBUFFER_HEIGHT, 1, 0 };
+ GLXPbuffer pbuffer = glXCreatePbuffer(sharedDisplay(), configs[0], pbufferAttributes);
+ if (!pbuffer) {
+ XFree(configs);
+ return 0;
+ }
+
+ GLXContext context = glXCreateNewContext(sharedDisplay(), configs[0], GLX_RGBA_TYPE, 0, GL_TRUE);
+ XFree(configs);
+ if (!context)
+ return 0;
+ return new GraphicsContext3DInternal(context, pbuffer);
+}
+
+GraphicsContext3DInternal* GraphicsContext3DInternal::createPixmapContext()
+{
+ static int visualAttributes[] = {
+ GLX_RGBA,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ GLX_ALPHA_SIZE, 1,
+ GLX_DOUBLEBUFFER,
+ 0
+ };
+
+ XVisualInfo* visualInfo = glXChooseVisual(sharedDisplay(), DefaultScreen(sharedDisplay()), visualAttributes);
+ if (!visualInfo)
+ return 0;
+
+ GLXContext context = glXCreateContext(sharedDisplay(), visualInfo, 0, GL_TRUE);
+ if (!context) {
+ XFree(visualInfo);
+ return 0;
+ }
+
+ Pixmap pixmap = XCreatePixmap(sharedDisplay(), DefaultRootWindow(sharedDisplay()), 1, 1, visualInfo->depth);
+ if (!pixmap) {
+ XFree(visualInfo);
+ return 0;
+ }
+
+ GLXPixmap glxPixmap = glXCreateGLXPixmap(sharedDisplay(), visualInfo, pixmap);
+ if (!glxPixmap) {
+ XFreePixmap(sharedDisplay(), pixmap);
+ XFree(visualInfo);
+ return 0;
+ }
+
+ return new GraphicsContext3DInternal(context, pixmap, glxPixmap);
+}
+
+GraphicsContext3DInternal::GraphicsContext3DInternal(GLXContext context, GLXPbuffer pbuffer)
+ : m_context(context)
+ , m_pbuffer(pbuffer)
+ , m_pixmap(0)
+ , m_glxPixmap(0)
+{
+}
+
+GraphicsContext3DInternal::GraphicsContext3DInternal(GLXContext context, Pixmap pixmap, GLXPixmap glxPixmap)
+ : m_context(context)
+ , m_pbuffer(0)
+ , m_pixmap(pixmap)
+ , m_glxPixmap(glxPixmap)
+{
+}
+
+GraphicsContext3DInternal::~GraphicsContext3DInternal()
+{
+ if (m_context) {
+ // This may be necessary to prevent crashes with NVidia's closed source drivers. Originally
+ // from Mozilla's 3D canvas implementation at: http://bitbucket.org/ilmari/canvas3d/
+ ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+
+ ::glXMakeContextCurrent(sharedDisplay(), 0, 0, 0);
+ ::glXDestroyContext(sharedDisplay(), m_context);
+ m_context = 0;
+ }
+
+ if (m_pbuffer) {
+ ::glXDestroyPbuffer(sharedDisplay(), m_pbuffer);
+ m_pbuffer = 0;
+ }
+ if (m_glxPixmap) {
+ glXDestroyGLXPixmap(sharedDisplay(), m_glxPixmap);
+ m_glxPixmap = 0;
+ }
+ if (m_pixmap) {
+ XFreePixmap(sharedDisplay(), m_pixmap);
+ m_pixmap = 0;
+ }
+}
+
+void GraphicsContext3DInternal::makeContextCurrent()
+{
+ if (::glXGetCurrentContext() == m_context)
+ return;
+ if (!m_context)
+ return;
+ if (m_pbuffer) {
+ ::glXMakeCurrent(sharedDisplay(), m_pbuffer, m_context);
+ return;
+ }
+
+ ASSERT(m_glxPixmap);
+ ::glXMakeCurrent(sharedDisplay(), m_glxPixmap, m_context);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE_WEBGL
diff --git a/Source/WebCore/platform/graphics/gtk/GraphicsContext3DInternal.h b/Source/WebCore/platform/graphics/gtk/GraphicsContext3DInternal.h
new file mode 100644
index 0000000..f4a60d9
--- /dev/null
+++ b/Source/WebCore/platform/graphics/gtk/GraphicsContext3DInternal.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2011 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#ifndef GraphicsContext3DInternal_h
+#define GraphicsContext3DInternal_h
+
+typedef struct __GLXcontextRec *GLXContext;
+typedef unsigned long GLXPbuffer;
+typedef unsigned long GLXPixmap;
+typedef unsigned char GLubyte;
+typedef unsigned long Pixmap;
+
+namespace WebCore {
+
+class GraphicsContext3D;
+
+class GraphicsContext3DInternal {
+ public:
+ static GraphicsContext3DInternal* create();
+ ~GraphicsContext3DInternal();
+ void makeContextCurrent();
+
+ private:
+ friend class GraphicsContext3D;
+ static GraphicsContext3DInternal* createPbufferContext();
+ static GraphicsContext3DInternal* createPixmapContext();
+ GraphicsContext3DInternal(GLXContext, GLXPbuffer);
+ GraphicsContext3DInternal(GLXContext, Pixmap, GLXPixmap);
+
+ static void addActiveGraphicsContext(GraphicsContext3D*);
+ static void removeActiveGraphicsContext(GraphicsContext3D*);
+ static void cleanupActiveContextsAtExit();
+
+ GLXContext m_context;
+ GLXPbuffer m_pbuffer;
+ Pixmap m_pixmap;
+ GLXPixmap m_glxPixmap;
+};
+
+}
+
+#endif // GraphicsContext3DIternal_h
diff --git a/Source/WebCore/platform/graphics/haiku/ImageBufferData.h b/Source/WebCore/platform/graphics/haiku/ImageBufferDataHaiku.h
index 7c676cd..10285fc 100644
--- a/Source/WebCore/platform/graphics/haiku/ImageBufferData.h
+++ b/Source/WebCore/platform/graphics/haiku/ImageBufferDataHaiku.h
@@ -25,9 +25,6 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ImageBufferData_h
-#define ImageBufferData_h
-
#include <Bitmap.h>
#include <View.h>
@@ -45,6 +42,3 @@ public:
};
} // namespace WebCore
-
-#endif // ImageBufferData_h
-
diff --git a/Source/WebCore/platform/graphics/mac/ComplexTextController.h b/Source/WebCore/platform/graphics/mac/ComplexTextController.h
index 44a7994..281e49f 100644
--- a/Source/WebCore/platform/graphics/mac/ComplexTextController.h
+++ b/Source/WebCore/platform/graphics/mac/ComplexTextController.h
@@ -116,9 +116,6 @@ private:
static OSStatus overrideLayoutOperation(ATSULayoutOperationSelector, ATSULineRef, URefCon, void*, ATSULayoutOperationCallbackStatus*);
#endif
-#if USE(CORE_TEXT)
- RetainPtr<CTRunRef> m_coreTextRun;
-#endif
unsigned m_glyphCount;
const SimpleFontData* m_fontData;
const UChar* m_characters;
@@ -159,6 +156,10 @@ private:
Vector<UChar, 256> m_smallCapsBuffer;
+#if USE(CORE_TEXT)
+ // Retain lines rather than their runs for better performance.
+ Vector<RetainPtr<CTLineRef> > m_coreTextLines;
+#endif
Vector<RefPtr<ComplexTextRun>, 16> m_complexTextRuns;
Vector<CGSize, 256> m_adjustedAdvances;
Vector<CGGlyph, 256> m_adjustedGlyphs;
diff --git a/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.cpp b/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.cpp
index d2fbaf5..1473b1e 100644
--- a/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.cpp
+++ b/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.cpp
@@ -43,33 +43,32 @@ extern const CFStringRef kCTTypesetterOptionForcedEmbeddingLevel;
namespace WebCore {
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_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());
- m_coreTextIndices = CTRunGetStringIndicesPtr(m_coreTextRun.get());
+ m_glyphCount = CTRunGetGlyphCount(ctRun);
+ m_coreTextIndices = CTRunGetStringIndicesPtr(ctRun);
if (!m_coreTextIndices) {
m_coreTextIndicesVector.grow(m_glyphCount);
- CTRunGetStringIndices(m_coreTextRun.get(), CFRangeMake(0, 0), m_coreTextIndicesVector.data());
+ CTRunGetStringIndices(ctRun, CFRangeMake(0, 0), m_coreTextIndicesVector.data());
m_coreTextIndices = m_coreTextIndicesVector.data();
}
- m_glyphs = CTRunGetGlyphsPtr(m_coreTextRun.get());
+ m_glyphs = CTRunGetGlyphsPtr(ctRun);
if (!m_glyphs) {
m_glyphsVector.grow(m_glyphCount);
- CTRunGetGlyphs(m_coreTextRun.get(), CFRangeMake(0, 0), m_glyphsVector.data());
+ CTRunGetGlyphs(ctRun, CFRangeMake(0, 0), m_glyphsVector.data());
m_glyphs = m_glyphsVector.data();
}
- m_advances = CTRunGetAdvancesPtr(m_coreTextRun.get());
+ m_advances = CTRunGetAdvancesPtr(ctRun);
if (!m_advances) {
m_advancesVector.grow(m_glyphCount);
- CTRunGetAdvances(m_coreTextRun.get(), CFRangeMake(0, 0), m_advancesVector.data());
+ CTRunGetAdvances(ctRun, CFRangeMake(0, 0), m_advancesVector.data());
m_advances = m_advancesVector.data();
}
}
@@ -159,6 +158,8 @@ void ComplexTextController::collectComplexTextRunsForCharactersCoreText(const UC
line.adoptCF(wkCreateCTLineWithUniCharProvider(&provideStringAndAttributes, 0, &info));
}
+ m_coreTextLines.append(line.get());
+
CFArrayRef runArray = CTLineGetGlyphRuns(line.get());
CFIndex runCount = CFArrayGetCount(runArray);
diff --git a/Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm b/Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm
index 997c976..2a469a7 100644
--- a/Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm
+++ b/Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm
@@ -90,8 +90,8 @@ PassRefPtr<GraphicsContext3D> GraphicsContext3D::create(GraphicsContext3D::Attri
GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow, bool)
: m_currentWidth(0)
, m_currentHeight(0)
- , m_attrs(attrs)
, m_contextObj(0)
+ , m_attrs(attrs)
, m_texture(0)
, m_compositorTexture(0)
, m_fbo(0)
diff --git a/Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm b/Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
index cd34000..f34d53b 100644
--- a/Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
+++ b/Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
@@ -241,6 +241,7 @@ void SimpleFontData::platformInit()
NSString *familyName = [m_platformData.font() familyName];
if ([familyName isEqualToString:@"Times"] || [familyName isEqualToString:@"Helvetica"] || [familyName isEqualToString:@"Courier"])
ascent += floorf(((ascent + descent) * 0.15f) + 0.5f);
+#if defined(BUILDING_ON_LEOPARD)
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
@@ -248,6 +249,7 @@ void SimpleFontData::platformInit()
ascent *= 1.08f;
descent *= 2.f;
}
+#endif
// Compute and store line spacing, before the line metrics hacks are applied.
m_fontMetrics.setLineSpacing(lroundf(ascent) + lroundf(descent) + lroundf(lineGap));
diff --git a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp
index e09534e..4c7164e 100644
--- a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp
+++ b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp
@@ -35,6 +35,8 @@
#if PLATFORM(MAC)
#include "ANGLE/ShaderLang.h"
#include <OpenGL/gl.h>
+#elif PLATFORM(GTK)
+#include "OpenGLShims.h"
#endif
namespace WebCore {
@@ -116,6 +118,17 @@ void Extensions3DOpenGL::ensureEnabled(const String& name)
#endif
}
+bool Extensions3DOpenGL::isEnabled(const String& name)
+{
+#if PLATFORM(MAC)
+ if (name == "GL_OES_standard_derivatives") {
+ ANGLEWebKitBridge& compiler = m_context->m_compiler;
+ return compiler.getResources().OES_standard_derivatives;
+ }
+#endif
+ return supports(name);
+}
+
int Extensions3DOpenGL::getGraphicsResetStatusARB()
{
return GraphicsContext3D::NO_ERROR;
@@ -134,7 +147,7 @@ void Extensions3DOpenGL::renderbufferStorageMultisample(unsigned long target, un
Platform3DObject Extensions3DOpenGL::createVertexArrayOES()
{
m_context->makeContextCurrent();
-#if defined GL_APPLE_vertex_array_object && GL_APPLE_vertex_array_object
+#if !PLATFORM(GTK) && defined(GL_APPLE_vertex_array_object) && GL_APPLE_vertex_array_object
GLuint array = 0;
glGenVertexArraysAPPLE(1, &array);
return array;
@@ -149,7 +162,7 @@ void Extensions3DOpenGL::deleteVertexArrayOES(Platform3DObject array)
return;
m_context->makeContextCurrent();
-#if defined GL_APPLE_vertex_array_object && GL_APPLE_vertex_array_object
+#if !PLATFORM(GTK) && defined(GL_APPLE_vertex_array_object) && GL_APPLE_vertex_array_object
glDeleteVertexArraysAPPLE(1, &array);
#endif
}
@@ -160,7 +173,7 @@ GC3Dboolean Extensions3DOpenGL::isVertexArrayOES(Platform3DObject array)
return GL_FALSE;
m_context->makeContextCurrent();
-#if defined GL_APPLE_vertex_array_object && GL_APPLE_vertex_array_object
+#if !PLATFORM(GTK) && defined(GL_APPLE_vertex_array_object) && GL_APPLE_vertex_array_object
return glIsVertexArrayAPPLE(array);
#else
return GL_FALSE;
@@ -173,7 +186,7 @@ void Extensions3DOpenGL::bindVertexArrayOES(Platform3DObject array)
return;
m_context->makeContextCurrent();
-#if defined GL_APPLE_vertex_array_object && GL_APPLE_vertex_array_object
+#if !PLATFORM(GTK) && defined(GL_APPLE_vertex_array_object) && GL_APPLE_vertex_array_object
glBindVertexArrayAPPLE(array);
#endif
}
diff --git a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h
index 9188507..e545fbc 100644
--- a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h
+++ b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h
@@ -41,6 +41,7 @@ public:
// Extensions3D methods.
virtual bool supports(const String&);
virtual void ensureEnabled(const String&);
+ virtual bool isEnabled(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);
diff --git a/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp b/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp
index f831550..af46293 100644
--- a/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp
+++ b/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp
@@ -42,14 +42,16 @@
#include "Int32Array.h"
#include "NotImplemented.h"
#include "Uint8Array.h"
+#include <cstring>
+#include <wtf/UnusedParam.h>
+#include <wtf/text/CString.h>
#if PLATFORM(MAC)
#include <OpenGL/gl.h>
+#elif PLATFORM(GTK)
+#include "OpenGLShims.h"
#endif
-#include <wtf/UnusedParam.h>
-#include <wtf/text/CString.h>
-
namespace WebCore {
void GraphicsContext3D::validateAttributes()
@@ -163,7 +165,7 @@ PassRefPtr<ImageData> GraphicsContext3D::paintRenderingResultsToImageData()
void GraphicsContext3D::reshape(int width, int height)
{
- if (!m_contextObj)
+ if (!platformGraphicsContext3D())
return;
if (width == m_currentWidth && height == m_currentHeight)
diff --git a/Source/WebCore/platform/graphics/opengl/TextureMapperGL.cpp b/Source/WebCore/platform/graphics/opengl/TextureMapperGL.cpp
index 9765937..1493966 100644
--- a/Source/WebCore/platform/graphics/opengl/TextureMapperGL.cpp
+++ b/Source/WebCore/platform/graphics/opengl/TextureMapperGL.cpp
@@ -388,7 +388,7 @@ void TextureMapperGL::drawTexture(const BitmapTexture& texture, const IntRect& t
GL_CMD(glBindTexture(GL_TEXTURE_2D, textureGL.m_id))
GL_CMD(glBindBuffer(GL_ARRAY_BUFFER, 0))
const GLfloat unitRect[] = {0, 0, 1, 0, 1, 1, 0, 1};
- GL_CMD(glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, unitRect))
+ GL_CMD(glVertexAttribPointer(gInVertexAttributeIndex, 2, GL_FLOAT, GL_FALSE, 0, unitRect))
TransformationMatrix matrix = TransformationMatrix(data().projectionMatrix).multiply(modelViewMatrix).multiply(TransformationMatrix(
targetRect.width(), 0, 0, 0,
@@ -641,7 +641,7 @@ void TextureMapperGL::paintToTarget(const BitmapTexture& aSurface, const IntSize
GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::ShaderInfo::InSourceMatrixVariable], 1, GL_FALSE, m4src))
GL_CMD(glBindBuffer(GL_ARRAY_BUFFER, 0))
const GLfloat unitRect[] = {0, 0, 1, 0, 1, 1, 0, 1};
- GL_CMD(glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, unitRect))
+ GL_CMD(glVertexAttribPointer(gInVertexAttributeIndex, 2, GL_FLOAT, GL_FALSE, 0, unitRect))
GL_CMD(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA))
GL_CMD(glEnable(GL_BLEND))
setClip(visibleRect);
diff --git a/Source/WebCore/platform/graphics/opentype/OpenTypeUtilities.cpp b/Source/WebCore/platform/graphics/opentype/OpenTypeUtilities.cpp
index 7f4547d..6afe3d9 100644
--- a/Source/WebCore/platform/graphics/opentype/OpenTypeUtilities.cpp
+++ b/Source/WebCore/platform/graphics/opentype/OpenTypeUtilities.cpp
@@ -70,7 +70,7 @@ struct TableDirectoryEntry {
BigEndianULong length;
};
-#if !PLATFORM(CG) || !defined(COREGRAPHICS_INCLUDES_CORESERVICES_HEADER)
+#if !USE(CG) || !defined(COREGRAPHICS_INCLUDES_CORESERVICES_HEADER)
// Fixed type is not defined on non-CG and Windows platforms. |version| in sfntHeader
// and headTable and |fontRevision| in headTable are of Fixed, but they're
// not actually refered to anywhere. Therefore, we just have to match
diff --git a/Source/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp b/Source/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp
index 75dbadb..1595692 100644
--- a/Source/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp
+++ b/Source/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp
@@ -257,7 +257,7 @@ void GraphicsContext::drawLineForTextChecking(const IntPoint& origin, int width,
UNUSED_PARAM(style);
}
-FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect)
+FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect, RoundingMode)
{
if (paintingDisabled())
return FloatRect();
diff --git a/Source/WebCore/platform/graphics/pango/FontPlatformData.h b/Source/WebCore/platform/graphics/pango/FontPlatformData.h
index 180d23b..bd9251b 100644
--- a/Source/WebCore/platform/graphics/pango/FontPlatformData.h
+++ b/Source/WebCore/platform/graphics/pango/FontPlatformData.h
@@ -68,6 +68,7 @@ public:
bool syntheticOblique() const { return m_syntheticOblique; }
FontOrientation orientation() const { return Horizontal; } // FIXME: Implement.
+ void setOrientation(FontOrientation) { } // FIXME: Implement.
cairo_scaled_font_t* scaledFont() const { return m_scaledFont; }
diff --git a/Source/WebCore/platform/graphics/qt/Extensions3DQt.cpp b/Source/WebCore/platform/graphics/qt/Extensions3DQt.cpp
index 3adc93f..45d5e9c 100644
--- a/Source/WebCore/platform/graphics/qt/Extensions3DQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/Extensions3DQt.cpp
@@ -52,6 +52,11 @@ void Extensions3DQt::ensureEnabled(const String& name)
ASSERT(supports(name));
}
+bool Extensions3DQt::isEnabled(const String& name)
+{
+ return supports(name);
+}
+
int Extensions3DQt::getGraphicsResetStatusARB()
{
return GraphicsContext3D::NO_ERROR;
diff --git a/Source/WebCore/platform/graphics/qt/Extensions3DQt.h b/Source/WebCore/platform/graphics/qt/Extensions3DQt.h
index c67fbed..1bc47b8 100644
--- a/Source/WebCore/platform/graphics/qt/Extensions3DQt.h
+++ b/Source/WebCore/platform/graphics/qt/Extensions3DQt.h
@@ -37,6 +37,7 @@ public:
// Extensions3D methods.
virtual bool supports(const String&);
virtual void ensureEnabled(const String&);
+ virtual bool isEnabled(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);
diff --git a/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp b/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
index 4daa4dc..e92f927 100644
--- a/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
@@ -447,6 +447,12 @@ GraphicsContext3DInternal::GraphicsContext3DInternal(GraphicsContext3D::Attribut
GraphicsContext3DInternal::~GraphicsContext3DInternal()
{
+ m_glWidget->makeCurrent();
+ if (m_glWidget->isValid()) {
+ ::glDeleteTextures(1, &m_texture);
+ deleteRenderbuffers(1, &m_depthBuffer);
+ deleteFramebuffers(1, &m_canvasFbo);
+ }
delete m_glWidget;
m_glWidget = 0;
}
@@ -588,7 +594,7 @@ void* GraphicsContext3DInternal::getProcAddress(const String& proc)
for (int i = 0; i < 3; i++) {
String nameWithExt = proc + ext[i];
- void* addr = m_glWidget->context()->getProcAddress(nameWithExt.utf8().data());
+ void* addr = m_glWidget->context()->getProcAddress(QString(nameWithExt));
if (addr)
return addr;
}
@@ -656,7 +662,7 @@ PassRefPtr<ImageData> GraphicsContext3D::paintRenderingResultsToImageData()
void GraphicsContext3D::reshape(int width, int height)
{
- if (width == m_currentWidth && height == m_currentHeight || (!m_internal))
+ if ((width == m_currentWidth && height == m_currentHeight) || (!m_internal))
return;
m_currentWidth = width;
diff --git a/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
index e3e0fa6..a3a08eb 100644
--- a/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
@@ -900,7 +900,7 @@ void GraphicsContext::drawLineForTextChecking(const FloatPoint&, float, TextChec
notImplemented();
}
-FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& frect)
+FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& frect, RoundingMode)
{
// It is not enough just to round to pixels in device space. The rotation part of the
// affine transform matrix to device space can mess with this conversion if we have a
diff --git a/Source/WebCore/platform/graphics/qt/ImageBufferData.h b/Source/WebCore/platform/graphics/qt/ImageBufferDataQt.h
index 602197e..8b49829 100644
--- a/Source/WebCore/platform/graphics/qt/ImageBufferData.h
+++ b/Source/WebCore/platform/graphics/qt/ImageBufferDataQt.h
@@ -23,16 +23,12 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ImageBufferData_h
-#define ImageBufferData_h
-
#include "Image.h"
-#include <wtf/RefPtr.h>
+#include "OwnPtr.h"
#include <QPainter>
#include <QPixmap>
-
-#include "OwnPtr.h"
+#include <wtf/RefPtr.h>
namespace WebCore {
@@ -49,6 +45,4 @@ public:
RefPtr<Image> m_image;
};
-} // namespace WebCore
-
-#endif // ImageBufferData_h
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp
index bc43acf..e7efdf9 100644
--- a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp
@@ -84,7 +84,17 @@ MediaPlayer::SupportsType MediaPlayerPrivateQt::supportsType(const String& mime,
if (!mime.startsWith("audio/") && !mime.startsWith("video/"))
return MediaPlayer::IsNotSupported;
- if (QMediaPlayer::hasSupport(mime, QStringList(codec)) >= QtMultimediaKit::ProbablySupported)
+ // Parse and trim codecs.
+ QString codecStr = codec;
+ QStringList codecList = codecStr.split(QLatin1Char(','), QString::SkipEmptyParts);
+ QStringList codecListTrimmed;
+ foreach (const QString& codecStrNotTrimmed, codecList) {
+ QString codecStrTrimmed = codecStrNotTrimmed.trimmed();
+ if (!codecStrTrimmed.isEmpty())
+ codecListTrimmed.append(codecStrTrimmed);
+ }
+
+ if (QMediaPlayer::hasSupport(mime, codecListTrimmed) >= QtMultimediaKit::ProbablySupported)
return MediaPlayer::IsSupported;
return MediaPlayer::MayBeSupported;
diff --git a/Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp b/Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp
index 5d0b302..9bf1030 100644
--- a/Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ Copyright (C) 2008, 2009, 2010, 2011 Nokia Corporation and/or its subsidiary(-ies)
Copyright (C) 2008 Holger Hans Peter Freyther
This library is free software; you can redistribute it and/or
@@ -48,11 +48,29 @@ void SimpleFontData::platformInit()
}
QFontMetricsF fm(m_platformData.font());
- m_fontMetrics.setAscent(fm.ascent());
- m_fontMetrics.setDescent(fm.descent());
+
+ // Qt subtracts 1 from the descent to account for the baseline,
+ // we add it back here to get correct metrics for WebKit.
+ float descent = fm.descent() + 1;
+ float ascent = fm.ascent();
+
+ float lineSpacing = fm.lineSpacing();
+
+ // The line spacing should always be >= (ascent + descent), but this
+ // may be false in some cases due to misbehaving platform libraries.
+ // Workaround from SimpleFontPango.cpp and SimpleFontFreeType.cpp
+ if (lineSpacing < ascent + descent)
+ lineSpacing = ascent + descent;
+
+ // QFontMetricsF::leading() may return negative values on platforms
+ // such as FreeType. Calculate the line gap manually instead.
+ float lineGap = lineSpacing - ascent - descent;
+
+ m_fontMetrics.setAscent(ascent);
+ m_fontMetrics.setDescent(descent);
+ m_fontMetrics.setLineSpacing(lineSpacing);
m_fontMetrics.setXHeight(fm.xHeight());
- m_fontMetrics.setLineGap(fm.leading());
- m_fontMetrics.setLineSpacing(fm.lineSpacing());
+ m_fontMetrics.setLineGap(lineGap);
m_spaceWidth = fm.width(QLatin1Char(' '));
}
diff --git a/Source/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp b/Source/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp
index 5950c35..0fb44e7 100644
--- a/Source/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp
+++ b/Source/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp
@@ -30,6 +30,7 @@
#include "GraphicsContext3D.h"
+#include "BitmapImage.h"
#include "Image.h"
#include "ImageSource.h"
#include "NativeImageSkia.h"
@@ -50,15 +51,17 @@ bool GraphicsContext3D::getImageData(Image* image,
if (!image)
return false;
OwnPtr<NativeImageSkia> pixels;
- NativeImageSkia* skiaImage = 0;
+ NativeImageSkia* skiaImage = image->nativeImageForCurrentFrame();
AlphaOp neededAlphaOp = AlphaDoNothing;
- if (image->data()) {
+ bool hasAlpha = skiaImage ? !skiaImage->isOpaque() : true;
+ if ((!skiaImage || ignoreGammaAndColorProfile || (hasAlpha && !premultiplyAlpha)) && image->data()) {
ImageSource decoder(ImageSource::AlphaNotPremultiplied,
ignoreGammaAndColorProfile ? ImageSource::GammaAndColorProfileIgnored : ImageSource::GammaAndColorProfileApplied);
+ // Attempt to get raw unpremultiplied image data
decoder.setData(image->data(), true);
if (!decoder.frameCount() || !decoder.frameIsCompleteAtIndex(0))
return false;
- bool hasAlpha = decoder.frameHasAlphaAtIndex(0);
+ hasAlpha = decoder.frameHasAlphaAtIndex(0);
pixels = adoptPtr(decoder.createFrameAtIndex(0));
if (!pixels.get() || !pixels->isDataComplete() || !pixels->width() || !pixels->height())
return false;
@@ -68,12 +71,8 @@ bool GraphicsContext3D::getImageData(Image* image,
skiaImage = pixels.get();
if (hasAlpha && premultiplyAlpha)
neededAlphaOp = AlphaDoPremultiply;
- } else {
- // This is a special case for texImage2D with HTMLCanvasElement input.
- skiaImage = image->nativeImageForCurrentFrame();
- if (!premultiplyAlpha)
- neededAlphaOp = AlphaDoUnmultiply;
- }
+ } else if (!premultiplyAlpha && hasAlpha)
+ neededAlphaOp = AlphaDoUnmultiply;
if (!skiaImage)
return false;
SkBitmap& skiaImageRef = *skiaImage;
diff --git a/Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp b/Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
index df680eb..f285c9b 100644
--- a/Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
+++ b/Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
@@ -44,8 +44,10 @@
#include "PlatformContextSkia.h"
#include "SkBitmap.h"
-#include "SkBlurDrawLooper.h"
+#include "SkBlurMaskFilter.h"
+#include "SkColorFilter.h"
#include "SkCornerPathEffect.h"
+#include "SkLayerDrawLooper.h"
#include "SkShader.h"
#include "SkiaUtils.h"
#include "skia/ext/platform_canvas.h"
@@ -853,6 +855,7 @@ void GraphicsContext::fillRoundedRect(const IntRect& rect,
SkPaint paint;
platformContext()->setupPaintForFilling(&paint);
+ paint.setColor(color.rgb());
platformContext()->canvas()->drawPath(path, paint);
}
@@ -867,7 +870,7 @@ AffineTransform GraphicsContext::getCTM() const
SkScalarToDouble(m.getTranslateY()));
}
-FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect)
+FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect, RoundingMode)
{
return rect;
}
@@ -1043,16 +1046,15 @@ void GraphicsContext::setPlatformShadow(const FloatSize& size,
double height = size.height();
double blur = blurFloat;
- uint32_t blurFlags = SkBlurDrawLooper::kHighQuality_BlurFlag |
- SkBlurDrawLooper::kOverrideColor_BlurFlag;
+ uint32_t mfFlags = SkBlurMaskFilter::kHighQuality_BlurFlag;
if (m_state.shadowsIgnoreTransforms) {
// Currently only the GraphicsContext associated with the
// CanvasRenderingContext for HTMLCanvasElement have shadows ignore
// Transforms. So with this flag set, we know this state is associated
// with a CanvasRenderingContext.
- blurFlags |= SkBlurDrawLooper::kIgnoreTransform_BlurFlag;
-
+ mfFlags |= SkBlurMaskFilter::kIgnoreTransform_BlurFlag;
+
// CG uses natural orientation for Y axis, but the HTML5 canvas spec
// does not.
// So we now flip the height since it was flipped in
@@ -1068,9 +1070,32 @@ void GraphicsContext::setPlatformShadow(const FloatSize& size,
// TODO(tc): Should we have a max value for the blur? CG clamps at 1000.0
// for perf reasons.
- SkDrawLooper* dl = new SkBlurDrawLooper(blur / 2, width, height, c, blurFlags);
+
+ SkLayerDrawLooper* dl = new SkLayerDrawLooper;
+ SkAutoUnref aur(dl);
+
+ // top layer, we just draw unchanged
+ dl->addLayer();
+
+ // lower layer contains our offset, blur, and colorfilter
+ SkLayerDrawLooper::LayerInfo info;
+
+ info.fPaintBits |= SkLayerDrawLooper::kMaskFilter_Bit; // our blur
+ info.fPaintBits |= SkLayerDrawLooper::kColorFilter_Bit;
+ info.fColorMode = SkXfermode::kDst_Mode;
+ info.fOffset.set(width, height);
+ info.fPostTranslate = m_state.shadowsIgnoreTransforms;
+
+ SkMaskFilter* mf = SkBlurMaskFilter::Create(blur / 2, SkBlurMaskFilter::kNormal_BlurStyle, mfFlags);
+
+ SkColorFilter* cf = SkColorFilter::CreateModeFilter(c, SkXfermode::kSrcIn_Mode);
+
+ SkPaint* paint = dl->addLayer(info);
+ SkSafeUnref(paint->setMaskFilter(mf));
+ SkSafeUnref(paint->setColorFilter(cf));
+
+ // dl is now built, just install it
platformContext()->setDrawLooper(dl);
- dl->unref();
}
void GraphicsContext::setPlatformStrokeColor(const Color& strokecolor, ColorSpace colorSpace)
diff --git a/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp b/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
index b89c68d..2352672 100644
--- a/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
+++ b/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
@@ -66,19 +66,21 @@ ImageBuffer::ImageBuffer(const IntSize& size, ColorSpace, RenderingMode, bool& s
: m_data(size)
, m_size(size)
{
- if (!m_data.m_canvas.initialize(size.width(), size.height(), false)) {
+ SkCanvas* canvas = skia::CreateBitmapCanvas(size.width(), size.height(), false);
+ if (!canvas) {
success = false;
return;
}
- m_data.m_platformContext.setCanvas(&m_data.m_canvas);
+ m_data.m_canvas = canvas;
+ m_data.m_platformContext.setCanvas(m_data.m_canvas.get());
m_context.set(new GraphicsContext(&m_data.m_platformContext));
m_context->platformContext()->setDrawingToImageBuffer(true);
// Make the background transparent. It would be nice if this wasn't
// required, but the canvas is currently filled with the magic transparency
// color. Can we have another way to manage this?
- m_data.m_canvas.drawARGB(0, 0, 0, 0, SkXfermode::kClear_Mode);
+ m_data.m_canvas->drawARGB(0, 0, 0, 0, SkXfermode::kClear_Mode);
success = true;
}
@@ -117,6 +119,7 @@ void ImageBuffer::draw(GraphicsContext* context, ColorSpace styleColorSpace, con
{
if (m_data.m_platformContext.useGPU() && context->platformContext()->useGPU()) {
if (context->platformContext()->canAccelerate()) {
+ m_data.m_platformContext.prepareForHardwareDraw();
DrawingBuffer* sourceDrawingBuffer = m_data.m_platformContext.gpuCanvas()->drawingBuffer();
unsigned sourceTexture = static_cast<unsigned>(sourceDrawingBuffer->platformColorBuffer());
FloatRect destRectNormalized(normalizeRect(destRect));
@@ -344,6 +347,8 @@ void ImageBuffer::putPremultipliedImageData(ByteArray* source, const IntSize& so
template <typename T>
static String ImageToDataURL(T& source, const String& mimeType, const double* quality)
{
+ ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType));
+
Vector<unsigned char> encodedImage;
if (mimeType == "image/jpeg") {
int compressionQuality = JPEGImageEncoder::DefaultCompressionQuality;
@@ -365,9 +370,6 @@ static String ImageToDataURL(T& source, const String& mimeType, const double* qu
String ImageBuffer::toDataURL(const String& mimeType, const double* quality) const
{
- ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType));
-
- Vector<unsigned char> encodedImage;
SkDevice* device = context()->platformContext()->canvas()->getDevice();
SkBitmap bitmap = device->accessBitmap(false);
diff --git a/Source/WebCore/platform/graphics/skia/ImageSkia.cpp b/Source/WebCore/platform/graphics/skia/ImageSkia.cpp
index 72bec29..6987e00 100644
--- a/Source/WebCore/platform/graphics/skia/ImageSkia.cpp
+++ b/Source/WebCore/platform/graphics/skia/ImageSkia.cpp
@@ -66,6 +66,7 @@ enum ResamplingMode {
RESAMPLE_AWESOME,
};
+#if !ENABLE(SKIA_GPU)
static ResamplingMode computeResamplingMode(PlatformContextSkia* platformContext, const NativeImageSkia& bitmap, int srcWidth, int srcHeight, float destWidth, float destHeight)
{
if (platformContext->hasImageResamplingHint()) {
@@ -150,6 +151,7 @@ static ResamplingMode computeResamplingMode(PlatformContextSkia* platformContext
return RESAMPLE_LINEAR;
}
+#endif
// Draws the given bitmap to the given canvas. The subset of the source bitmap
// identified by src_rect is drawn to the given destination rect. The bitmap
@@ -262,12 +264,17 @@ static void paintSkBitmap(PlatformContextSkia* platformContext, const NativeImag
paint.setAlpha(platformContext->getNormalizedAlpha());
paint.setLooper(platformContext->getDrawLooper());
- skia::PlatformCanvas* canvas = platformContext->canvas();
+ SkCanvas* canvas = platformContext->canvas();
- ResamplingMode resampling = platformContext->isPrinting() ? RESAMPLE_NONE :
+ ResamplingMode resampling;
+#if ENABLE(SKIA_GPU)
+ resampling = RESAMPLE_LINEAR;
+#else
+ resampling = platformContext->printing() ? RESAMPLE_NONE :
computeResamplingMode(platformContext, bitmap, srcRect.width(), srcRect.height(),
SkScalarToFloat(destRect.width()),
SkScalarToFloat(destRect.height()));
+#endif
if (resampling == RESAMPLE_AWESOME) {
drawResampledBitmap(*canvas, paint, bitmap, srcRect, destRect);
} else {
@@ -363,13 +370,17 @@ void Image::drawPattern(GraphicsContext* context,
// Compute the resampling mode.
ResamplingMode resampling;
- if (context->platformContext()->isPrinting())
+#if ENABLE(SKIA_GPU)
+ resampling = RESAMPLE_LINEAR;
+#else
+ if (context->platformContext()->printing())
resampling = RESAMPLE_LINEAR;
else {
resampling = computeResamplingMode(context->platformContext(), *bitmap,
srcRect.width(), srcRect.height(),
destBitmapWidth, destBitmapHeight);
}
+#endif
// Load the transform WebKit requested.
SkMatrix matrix(patternTransform);
diff --git a/Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp b/Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
index 8e1937f..4cc5457 100644
--- a/Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
+++ b/Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
@@ -213,8 +213,9 @@ SkColor PlatformContextSkia::State::applyAlpha(SkColor c) const
// PlatformContextSkia ---------------------------------------------------------
// Danger: canvas can be NULL.
-PlatformContextSkia::PlatformContextSkia(skia::PlatformCanvas* canvas)
+PlatformContextSkia::PlatformContextSkia(SkCanvas* canvas)
: m_canvas(canvas)
+ , m_printing(false)
, m_drawingToImageBuffer(false)
, m_useGPU(false)
#if ENABLE(ACCELERATED_2D_CANVAS)
@@ -232,15 +233,18 @@ PlatformContextSkia::~PlatformContextSkia()
if (m_gpuCanvas) {
#if ENABLE(SKIA_GPU)
// make sure everything related to this platform context has been flushed
- if (!m_useGPU)
- m_gpuCanvas->context()->grContext()->flush(0);
+ if (!m_useGPU) {
+ SharedGraphicsContext3D* context = m_gpuCanvas->context();
+ context->makeContextCurrent();
+ context->grContext()->flush(0);
+ }
#endif
m_gpuCanvas->drawingBuffer()->setWillPublishCallback(0);
}
#endif
}
-void PlatformContextSkia::setCanvas(skia::PlatformCanvas* canvas)
+void PlatformContextSkia::setCanvas(SkCanvas* canvas)
{
m_canvas = canvas;
}
@@ -609,12 +613,12 @@ const SkBitmap* PlatformContextSkia::bitmap() const
return &m_canvas->getDevice()->accessBitmap(false);
}
-bool PlatformContextSkia::isPrinting()
+bool PlatformContextSkia::isNativeFontRenderingAllowed()
{
#if ENABLE(SKIA_GPU)
- return true;
+ return false;
#else
- return m_canvas->getTopPlatformDevice().IsVectorial();
+ return skia::SupportsPlatformPaint(m_canvas);
#endif
}
@@ -738,7 +742,12 @@ void PlatformContextSkia::setSharedGraphicsContext3D(SharedGraphicsContext3D* co
gr->resetContext();
drawingBuffer->setGrContext(gr);
- SkDeviceFactory* factory = new SkGpuDeviceFactory(gr, SkGpuDevice::Current3DApiRenderTarget());
+ GrPlatformSurfaceDesc drawBufDesc;
+ drawingBuffer->getGrPlatformSurfaceDesc(&drawBufDesc);
+ GrTexture* drawBufTex = static_cast<GrTexture*>(gr->createPlatformSurface(drawBufDesc));
+ SkDeviceFactory* factory = new SkGpuDeviceFactory(gr, drawBufTex);
+ drawBufTex->unref();
+
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);
diff --git a/Source/WebCore/platform/graphics/skia/PlatformContextSkia.h b/Source/WebCore/platform/graphics/skia/PlatformContextSkia.h
index d7dd6a9..fc82221 100644
--- a/Source/WebCore/platform/graphics/skia/PlatformContextSkia.h
+++ b/Source/WebCore/platform/graphics/skia/PlatformContextSkia.h
@@ -72,12 +72,12 @@ class PlatformContextSkia {
public:
// For printing, there shouldn't be any canvas. canvas can be NULL. If you
// supply a NULL canvas, you can also call setCanvas later.
- PlatformContextSkia(skia::PlatformCanvas*);
+ PlatformContextSkia(SkCanvas*);
~PlatformContextSkia();
// Sets the canvas associated with this context. Use when supplying NULL
// to the constructor.
- void setCanvas(skia::PlatformCanvas*);
+ void setCanvas(SkCanvas*);
// If false we're rendering to a GraphicsContext for a web page, if false
// we're not (as is the case when rendering to a canvas object).
@@ -146,7 +146,8 @@ public:
// by the current alpha.
SkColor effectiveStrokeColor() const;
- skia::PlatformCanvas* canvas() { return m_canvas; }
+ // Returns the canvas used for painting, NOT guaranteed to be non-null.
+ SkCanvas* canvas() { return m_canvas; }
InterpolationQuality interpolationQuality() const;
void setInterpolationQuality(InterpolationQuality interpolationQuality);
@@ -159,17 +160,16 @@ public:
const SkBitmap* bitmap() const;
- // Returns the canvas used for painting, NOT guaranteed to be non-NULL.
- //
- // Warning: This function is deprecated so the users are reminded that they
- // should use this layer of indirection instead of using the canvas
- // directly. This is to help with the eventual serialization.
- skia::PlatformCanvas* canvas() const;
-
// Returns if the context is a printing context instead of a display
// context. Bitmap shouldn't be resampled when printing to keep the best
// possible quality.
- bool isPrinting();
+ bool printing() const { return m_printing; }
+ void setPrinting(bool p) { m_printing = p; }
+
+ // Returns if the context allows rendering of fonts using native platform
+ // APIs. If false is returned font rendering is performed using the skia
+ // text drawing APIs.
+ bool isNativeFontRenderingAllowed();
void getImageResamplingHint(IntSize* srcSize, FloatSize* dstSize) const;
void setImageResamplingHint(const IntSize& srcSize, const FloatSize& dstSize);
@@ -186,10 +186,10 @@ public:
GLES2Canvas* gpuCanvas() const { return 0; }
#endif
// Call these before making a call that manipulates the underlying
- // skia::PlatformCanvas or WebCore::GLES2Canvas
+ // SkCanvas or WebCore::GLES2Canvas
void prepareForSoftwareDraw() const;
void prepareForHardwareDraw() const;
- // Call to force the skia::PlatformCanvas to contain all rendering results.
+ // Call to force the SkCanvas to contain all rendering results.
void syncSoftwareCanvas() const;
void markDirtyRect(const IntRect& rect);
@@ -206,7 +206,7 @@ private:
struct State;
// NULL indicates painting is disabled. Never delete this object.
- skia::PlatformCanvas* m_canvas;
+ SkCanvas* m_canvas;
// States stack. Enables local drawing state change with save()/restore()
// calls.
@@ -219,6 +219,7 @@ private:
// Values are used in ImageSkia.cpp
IntSize m_imageResamplingHintSrcSize;
FloatSize m_imageResamplingHintDstSize;
+ bool m_printing;
bool m_drawingToImageBuffer;
bool m_useGPU;
#if ENABLE(ACCELERATED_2D_CANVAS)
diff --git a/Source/WebCore/platform/graphics/skia/SkiaFontWin.cpp b/Source/WebCore/platform/graphics/skia/SkiaFontWin.cpp
index b0cb0c7..8ab823e 100644
--- a/Source/WebCore/platform/graphics/skia/SkiaFontWin.cpp
+++ b/Source/WebCore/platform/graphics/skia/SkiaFontWin.cpp
@@ -39,16 +39,11 @@
#include "SkPaint.h"
#include "SkShader.h"
#include "SkTemplates.h"
-#include "SkTypeface.h"
+#include "SkTypeface_win.h"
#include <wtf/ListHashSet.h>
#include <wtf/Vector.h>
-#if ENABLE(SKIA_TEXT)
-// FIXME: a future role of skia will have this in a proper header
-extern SkTypeface* SkCreateTypefaceFromLOGFONT(const LOGFONT&);
-#endif
-
namespace WebCore {
struct CachedOutlineKey {
@@ -235,11 +230,23 @@ bool windowsCanHandleDrawTextShadow(GraphicsContext *context)
ColorSpace shadowColorSpace;
bool hasShadow = context->getShadow(shadowOffset, shadowBlur, shadowColor, shadowColorSpace);
- return (hasShadow && (shadowBlur == 0) && (shadowColor.alpha() == 255) && (context->fillColor().alpha() == 255));
+ return !hasShadow || (!shadowBlur && (shadowColor.alpha() == 255) && (context->fillColor().alpha() == 255));
}
bool windowsCanHandleTextDrawing(GraphicsContext* context)
{
+ if (!windowsCanHandleTextDrawingWithoutShadow(context))
+ return false;
+
+ // Check for shadow effects.
+ if (!windowsCanHandleDrawTextShadow(context))
+ return false;
+
+ return true;
+}
+
+bool windowsCanHandleTextDrawingWithoutShadow(GraphicsContext* context)
+{
// Check for non-translation transforms. Sometimes zooms will look better in
// Skia, and sometimes better in Windows. The main problem is that zooming
// in using Skia will show you the hinted outlines for the smaller size,
@@ -261,8 +268,7 @@ bool windowsCanHandleTextDrawing(GraphicsContext* context)
if (context->fillPattern() || context->strokePattern())
return false;
- // Check for shadow effects.
- if (context->platformContext()->getDrawLooper() && (!windowsCanHandleDrawTextShadow(context)))
+ if (!context->platformContext()->isNativeFontRenderingAllowed())
return false;
return true;
@@ -272,7 +278,7 @@ bool windowsCanHandleTextDrawing(GraphicsContext* context)
// pattern may be NULL, in which case a solid colour is used.
static bool skiaDrawText(HFONT hfont,
HDC dc,
- SkCanvas* canvas,
+ PlatformContextSkia* platformContext,
const SkPoint& point,
SkPaint* paint,
const WORD* glyphs,
@@ -280,47 +286,47 @@ static bool skiaDrawText(HFONT hfont,
const GOFFSET* offsets,
int numGlyphs)
{
-#if ENABLE(SKIA_TEXT)
- SkASSERT(sizeof(WORD) == sizeof(uint16_t));
-
- // Reserve space for 64 glyphs on the stack. If numGlyphs is larger, the array
- // will dynamically allocate it space for numGlyph glyphs.
- static const size_t kLocalGlyphMax = 64;
- SkAutoSTArray<kLocalGlyphMax, SkPoint> posStorage(numGlyphs);
- SkPoint* pos = posStorage.get();
- SkScalar x = point.fX;
- SkScalar y = point.fY;
- for (int i = 0; i < numGlyphs; i++) {
- pos[i].set(x + (offsets ? offsets[i].du : 0),
- y + (offsets ? offsets[i].dv : 0));
- x += SkIntToScalar(advances[i]);
- }
- canvas->drawPosText(glyphs, numGlyphs * sizeof(uint16_t), pos, *paint);
-#else
- float x = point.fX, y = point.fY;
-
- for (int i = 0; i < numGlyphs; i++) {
- const SkPath* path = SkiaWinOutlineCache::lookupOrCreatePathForGlyph(dc, hfont, glyphs[i]);
- if (!path)
- return false;
-
- float offsetX = 0.0f, offsetY = 0.0f;
- if (offsets && (offsets[i].du != 0 || offsets[i].dv != 0)) {
- offsetX = offsets[i].du;
- offsetY = offsets[i].dv;
+ SkCanvas* canvas = platformContext->canvas();
+ if (!platformContext->isNativeFontRenderingAllowed()) {
+ SkASSERT(sizeof(WORD) == sizeof(uint16_t));
+
+ // Reserve space for 64 glyphs on the stack. If numGlyphs is larger, the array
+ // will dynamically allocate it space for numGlyph glyphs.
+ static const size_t kLocalGlyphMax = 64;
+ SkAutoSTArray<kLocalGlyphMax, SkPoint> posStorage(numGlyphs);
+ SkPoint* pos = posStorage.get();
+ SkScalar x = point.fX;
+ SkScalar y = point.fY;
+ for (int i = 0; i < numGlyphs; i++) {
+ pos[i].set(x + (offsets ? offsets[i].du : 0),
+ y + (offsets ? offsets[i].dv : 0));
+ x += SkIntToScalar(advances[i]);
}
+ canvas->drawPosText(glyphs, numGlyphs * sizeof(uint16_t), pos, *paint);
+ } else {
+ float x = point.fX, y = point.fY;
+
+ for (int i = 0; i < numGlyphs; i++) {
+ const SkPath* path = SkiaWinOutlineCache::lookupOrCreatePathForGlyph(dc, hfont, glyphs[i]);
+ if (!path)
+ return false;
+
+ float offsetX = 0.0f, offsetY = 0.0f;
+ if (offsets && (offsets[i].du || offsets[i].dv)) {
+ offsetX = offsets[i].du;
+ offsetY = offsets[i].dv;
+ }
- SkPath newPath;
- newPath.addPath(*path, x + offsetX, y + offsetY);
- canvas->drawPath(newPath, *paint);
+ SkPath newPath;
+ newPath.addPath(*path, x + offsetX, y + offsetY);
+ canvas->drawPath(newPath, *paint);
- x += advances[i];
+ x += advances[i];
+ }
}
-#endif
return true;
}
-#if ENABLE(SKIA_TEXT)
static void setupPaintForFont(HFONT hfont, SkPaint* paint)
{
// FIXME:
@@ -339,7 +345,6 @@ static void setupPaintForFont(HFONT hfont, SkPaint* paint)
paint->setTypeface(face);
SkSafeUnref(face);
}
-#endif
bool paintSkiaText(GraphicsContext* context,
HFONT hfont,
@@ -359,14 +364,14 @@ bool paintSkiaText(GraphicsContext* context,
SkPaint paint;
platformContext->setupPaintForFilling(&paint);
paint.setFlags(SkPaint::kAntiAlias_Flag);
-#if ENABLE(SKIA_TEXT)
- paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
- setupPaintForFont(hfont, &paint);
-#endif
+ if (!platformContext->isNativeFontRenderingAllowed()) {
+ paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+ setupPaintForFont(hfont, &paint);
+ }
bool didFill = false;
- if ((textMode & TextModeFill) && SkColorGetA(paint.getColor())) {
- if (!skiaDrawText(hfont, dc, platformContext->canvas(), *origin, &paint,
+ if ((textMode & TextModeFill) && (SkColorGetA(paint.getColor()) || paint.getLooper())) {
+ if (!skiaDrawText(hfont, dc, platformContext, *origin, &paint,
&glyphs[0], &advances[0], &offsets[0], numGlyphs))
return false;
didFill = true;
@@ -380,10 +385,10 @@ bool paintSkiaText(GraphicsContext* context,
paint.reset();
platformContext->setupPaintForStroking(&paint, 0, 0);
paint.setFlags(SkPaint::kAntiAlias_Flag);
-#if ENABLE(SKIA_TEXT)
- paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
- setupPaintForFont(hfont, &paint);
-#endif
+ if (!platformContext->isNativeFontRenderingAllowed()) {
+ paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+ setupPaintForFont(hfont, &paint);
+ }
if (didFill) {
// If there is a shadow and we filled above, there will already be
@@ -398,7 +403,7 @@ bool paintSkiaText(GraphicsContext* context,
paint.setLooper(0);
}
- if (!skiaDrawText(hfont, dc, platformContext->canvas(), *origin, &paint,
+ if (!skiaDrawText(hfont, dc, platformContext, *origin, &paint,
&glyphs[0], &advances[0], &offsets[0], numGlyphs))
return false;
}
diff --git a/Source/WebCore/platform/graphics/skia/SkiaFontWin.h b/Source/WebCore/platform/graphics/skia/SkiaFontWin.h
index 40bee62..33b4aaf 100644
--- a/Source/WebCore/platform/graphics/skia/SkiaFontWin.h
+++ b/Source/WebCore/platform/graphics/skia/SkiaFontWin.h
@@ -76,6 +76,10 @@ bool windowsCanHandleDrawTextShadow(GraphicsContext*);
// Returns true if advanced font rendering is recommended.
bool windowsCanHandleTextDrawing(GraphicsContext*);
+// Returns true if advanced font rendering is recommended if shadows are
+// disregarded.
+bool windowsCanHandleTextDrawingWithoutShadow(GraphicsContext*);
+
// Note that the offsets parameter is optional. If not NULL it represents a
// per glyph offset (such as returned by ScriptPlace Windows API function).
//
diff --git a/Source/WebCore/platform/graphics/transforms/AffineTransform.h b/Source/WebCore/platform/graphics/transforms/AffineTransform.h
index 14431aa..176c41e 100644
--- a/Source/WebCore/platform/graphics/transforms/AffineTransform.h
+++ b/Source/WebCore/platform/graphics/transforms/AffineTransform.h
@@ -32,9 +32,9 @@
#include <string.h> // for memcpy
#include <wtf/FastAllocBase.h>
-#if PLATFORM(CG)
+#if USE(CG)
#include <CoreGraphics/CGAffineTransform.h>
-#elif PLATFORM(CAIRO)
+#elif USE(CAIRO)
#include <cairo.h>
#elif PLATFORM(OPENVG)
#include "VGUtils.h"
@@ -157,9 +157,9 @@ public:
return result;
}
-#if PLATFORM(CG)
+#if USE(CG)
operator CGAffineTransform() const;
-#elif PLATFORM(CAIRO)
+#elif USE(CAIRO)
operator cairo_matrix_t() const;
#elif PLATFORM(OPENVG)
operator VGMatrix() const;
diff --git a/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h b/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h
index adda46b..ff668bb 100644
--- a/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h
+++ b/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h
@@ -31,12 +31,12 @@
#include <string.h> //for memcpy
#include <wtf/FastAllocBase.h>
-#if PLATFORM(CA)
+#if USE(CA)
typedef struct CATransform3D CATransform3D;
#endif
-#if PLATFORM(CG)
+#if USE(CG)
typedef struct CGAffineTransform CGAffineTransform;
-#elif PLATFORM(CAIRO)
+#elif USE(CAIRO)
#include <cairo.h>
#elif PLATFORM(OPENVG)
#include "VGUtils.h"
@@ -308,14 +308,14 @@ public:
return result;
}
-#if PLATFORM(CA)
+#if USE(CA)
TransformationMatrix(const CATransform3D&);
operator CATransform3D() const;
#endif
-#if PLATFORM(CG)
+#if USE(CG)
TransformationMatrix(const CGAffineTransform&);
operator CGAffineTransform() const;
-#elif PLATFORM(CAIRO)
+#elif USE(CAIRO)
operator cairo_matrix_t() const;
#elif PLATFORM(OPENVG)
operator VGMatrix() const;
diff --git a/Source/WebCore/platform/graphics/win/DIBPixelData.cpp b/Source/WebCore/platform/graphics/win/DIBPixelData.cpp
new file mode 100644
index 0000000..e45ba06
--- /dev/null
+++ b/Source/WebCore/platform/graphics/win/DIBPixelData.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2011 Brent Fulgham <bfulgham@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 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 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 "DIBPixelData.h"
+
+namespace WebCore {
+
+static const WORD bitmapType = 0x4d42; // BMP format
+static const WORD bitmapPixelsPerMeter = 2834; // 72 dpi
+
+DIBPixelData::DIBPixelData(HBITMAP bitmap)
+{
+ initialize(bitmap);
+}
+
+void DIBPixelData::initialize(HBITMAP bitmap)
+{
+ BITMAP bmpInfo;
+ GetObject(bitmap, sizeof(bmpInfo), &bmpInfo);
+
+ m_bitmapBuffer = reinterpret_cast<UInt8*>(bmpInfo.bmBits);
+ m_bitmapBufferLength = bmpInfo.bmWidthBytes * bmpInfo.bmHeight;
+ m_size = IntSize(bmpInfo.bmWidth, bmpInfo.bmHeight);
+ m_bytesPerRow = bmpInfo.bmWidthBytes;
+ m_bitsPerPixel = bmpInfo.bmBitsPixel;
+}
+
+#ifndef NDEBUG
+void DIBPixelData::writeToFile(LPCWSTR filePath)
+{
+ HANDLE hFile = ::CreateFile(filePath, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
+ if (INVALID_HANDLE_VALUE == hFile)
+ return;
+
+ BITMAPFILEHEADER header;
+ header.bfType = bitmapType;
+ header.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
+ header.bfReserved1 = 0;
+ header.bfReserved2 = 0;
+ header.bfSize = sizeof(BITMAPFILEHEADER);
+
+ BITMAPINFOHEADER info;
+ info.biSize = sizeof(BITMAPINFOHEADER);
+ info.biWidth = m_size.width();
+ info.biHeight = m_size.height();
+ info.biPlanes = 1;
+ info.biBitCount = m_bitsPerPixel;
+ info.biCompression = BI_RGB;
+ info.biSizeImage = bufferLength();
+ info.biXPelsPerMeter = bitmapPixelsPerMeter;
+ info.biYPelsPerMeter = bitmapPixelsPerMeter;
+ info.biClrUsed = 0;
+ info.biClrImportant = 0;
+
+ DWORD bytesWritten = 0;
+ ::WriteFile(hFile, &header, sizeof(header), &bytesWritten, 0);
+ ::WriteFile(hFile, &info, sizeof(info), &bytesWritten, 0);
+ ::WriteFile(hFile, buffer(), bufferLength(), &bytesWritten, 0);
+
+ ::CloseHandle(hFile);
+}
+#endif
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/win/DIBPixelData.h b/Source/WebCore/platform/graphics/win/DIBPixelData.h
new file mode 100644
index 0000000..40afa2b
--- /dev/null
+++ b/Source/WebCore/platform/graphics/win/DIBPixelData.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2011 Brent Fulgham <bfulgham@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 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 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 DIBPixelData_h
+#define DIBPixelData_h
+
+#include "IntSize.h"
+#include <windows.h>
+
+#if !USE(CG)
+// UInt8 is defined in CoreFoundation/CFBase.h
+typedef unsigned char UInt8;
+#endif
+
+namespace WebCore {
+
+class DIBPixelData {
+ public:
+ DIBPixelData()
+ : m_bitmapBuffer(0)
+ , m_bitmapBufferLength(0)
+ , m_bytesPerRow(0)
+ , m_bitsPerPixel(0)
+ {
+ }
+ DIBPixelData(HBITMAP);
+
+ void initialize(HBITMAP);
+
+#ifndef NDEBUG
+ void writeToFile(LPCWSTR);
+#endif
+
+ UInt8* buffer() const { return m_bitmapBuffer; }
+ unsigned bufferLength() const { return m_bitmapBufferLength; }
+ const IntSize& size() const { return m_size; }
+ unsigned bytesPerRow() const { return m_bytesPerRow; }
+ unsigned short bitsPerPixel() const { return m_bitsPerPixel; }
+
+ private:
+ UInt8* m_bitmapBuffer;
+ unsigned m_bitmapBufferLength;
+ IntSize m_size;
+ unsigned m_bytesPerRow;
+ unsigned short m_bitsPerPixel;
+};
+
+} // namespace WebCore
+
+#endif // DIBPixelData_h
diff --git a/Source/WebCore/platform/graphics/win/FontCacheWin.cpp b/Source/WebCore/platform/graphics/win/FontCacheWin.cpp
index 5382ef7..46f6f11 100644
--- a/Source/WebCore/platform/graphics/win/FontCacheWin.cpp
+++ b/Source/WebCore/platform/graphics/win/FontCacheWin.cpp
@@ -36,7 +36,7 @@
#include <windows.h>
#include <wtf/StdLibExtras.h>
#include <wtf/text/StringHash.h>
-#if PLATFORM(CG)
+#if USE(CG)
#include <ApplicationServices/ApplicationServices.h>
#include <WebKitSystemInterface/WebKitSystemInterface.h>
#endif
@@ -48,7 +48,7 @@ namespace WebCore
void FontCache::platformInit()
{
-#if PLATFORM(CG)
+#if USE(CG)
wkSetUpFontCache(1536 * 1024 * 4); // This size matches Mac.
#endif
}
@@ -471,7 +471,7 @@ static HFONT createGDIFont(const AtomicString& family, LONG desiredWeight, bool
matchData.m_chosen.lfUnderline = false;
matchData.m_chosen.lfStrikeOut = false;
matchData.m_chosen.lfCharSet = DEFAULT_CHARSET;
-#if PLATFORM(CG) || PLATFORM(CAIRO)
+#if USE(CG) || USE(CAIRO)
matchData.m_chosen.lfOutPrecision = OUT_TT_ONLY_PRECIS;
#else
matchData.m_chosen.lfOutPrecision = OUT_TT_PRECIS;
@@ -581,9 +581,9 @@ FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontD
FontPlatformData* result = new FontPlatformData(hfont, fontDescription.computedPixelSize(), synthesizeBold, synthesizeItalic, useGDI);
-#if PLATFORM(CG)
+#if USE(CG)
bool fontCreationFailed = !result->cgFont();
-#elif PLATFORM(CAIRO)
+#elif USE(CAIRO)
bool fontCreationFailed = !result->scaledFont();
#endif
diff --git a/Source/WebCore/platform/graphics/win/FontPlatformDataWin.cpp b/Source/WebCore/platform/graphics/win/FontPlatformDataWin.cpp
index 301198d..d0b37bd 100644
--- a/Source/WebCore/platform/graphics/win/FontPlatformDataWin.cpp
+++ b/Source/WebCore/platform/graphics/win/FontPlatformDataWin.cpp
@@ -41,9 +41,9 @@ FontPlatformData::FontPlatformData(HFONT font, float size, bool bold, bool obliq
, m_orientation(Horizontal)
, m_textOrientation(TextOrientationVerticalRight)
, m_widthVariant(RegularWidth)
-#if PLATFORM(CG)
+#if USE(CG)
, m_cgFont(0)
-#elif PLATFORM(CAIRO)
+#elif USE(CAIRO)
, m_scaledFont(0)
#endif
, m_isColorBitmapFont(false)
diff --git a/Source/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp b/Source/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp
index d0bd4e9..cb0c9a7 100644
--- a/Source/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp
+++ b/Source/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp
@@ -40,25 +40,24 @@ namespace WebCore {
static CGContextRef CGContextWithHDC(HDC hdc, bool hasAlpha)
{
HBITMAP bitmap = static_cast<HBITMAP>(GetCurrentObject(hdc, OBJ_BITMAP));
- BITMAP info;
- GetObject(bitmap, sizeof(info), &info);
+ DIBPixelData pixelData(bitmap);
// FIXME: We can get here because we asked for a bitmap that is too big
// when we have a tiled layer and we're compositing. In that case
// bmBitsPixel will be 0. This seems to be benign, so for now we will
// exit gracefully and look at it later:
// https://bugs.webkit.org/show_bug.cgi?id=52041
- // ASSERT(info.bmBitsPixel == 32);
- if (info.bmBitsPixel != 32)
+ // ASSERT(bitmapBits.bitsPerPixel() == 32);
+ if (pixelData.bitsPerPixel() != 32)
return 0;
CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Little | (hasAlpha ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst);
- CGContextRef context = CGBitmapContextCreate(info.bmBits, info.bmWidth, info.bmHeight, 8,
- info.bmWidthBytes, deviceRGBColorSpaceRef(), bitmapInfo);
+ CGContextRef context = CGBitmapContextCreate(pixelData.buffer(), pixelData.size().width(), pixelData.size().height(), 8,
+ pixelData.bytesPerRow(), deviceRGBColorSpaceRef(), bitmapInfo);
// Flip coords
- CGContextTranslateCTM(context, 0, info.bmHeight);
+ CGContextTranslateCTM(context, 0, pixelData.size().height());
CGContextScaleCTM(context, 1, -1);
// Put the HDC In advanced mode so it will honor affine transforms.
@@ -99,16 +98,14 @@ void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect& dstRect, boo
if (dstRect.isEmpty())
return;
- HBITMAP bitmap = static_cast<HBITMAP>(GetCurrentObject(hdc, OBJ_BITMAP));
+ OwnPtr<HBITMAP> bitmap = adoptPtr(static_cast<HBITMAP>(GetCurrentObject(hdc, OBJ_BITMAP)));
+
+ DIBPixelData pixelData(bitmap.get());
- // Need to make a CGImage out of the bitmap's pixel buffer and then draw
- // it into our context.
- BITMAP info;
- GetObject(bitmap, sizeof(info), &info);
- ASSERT(info.bmBitsPixel == 32);
+ ASSERT(pixelData.bitsPerPixel() == 32);
- CGContextRef bitmapContext = CGBitmapContextCreate(info.bmBits, info.bmWidth, info.bmHeight, 8,
- info.bmWidthBytes, deviceRGBColorSpaceRef(), kCGBitmapByteOrder32Little |
+ CGContextRef bitmapContext = CGBitmapContextCreate(pixelData.buffer(), pixelData.size().width(), pixelData.size().height(), 8,
+ pixelData.bytesPerRow(), deviceRGBColorSpaceRef(), kCGBitmapByteOrder32Little |
(supportAlphaBlend ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst));
CGImageRef image = CGBitmapContextCreateImage(bitmapContext);
@@ -118,7 +115,6 @@ void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect& dstRect, boo
CGImageRelease(image);
CGContextRelease(bitmapContext);
::DeleteDC(hdc);
- ::DeleteObject(bitmap);
}
void GraphicsContext::drawWindowsBitmap(WindowsBitmap* image, const IntPoint& point)
diff --git a/Source/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp b/Source/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp
index 7ce7ee9..9f7aece 100644
--- a/Source/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp
+++ b/Source/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp
@@ -78,7 +78,7 @@ void GraphicsContext::platformInit(HDC dc, bool hasAlpha)
else
setPaintingDisabled(true);
- m_data = new GraphicsContextPlatformPrivateTopLevel(new PlatformContextCairo(cr));
+ m_data = new GraphicsContextPlatformPrivateToplevel(new PlatformContextCairo(cr));
m_data->m_hdc = dc;
if (platformContext()->cr()) {
// Make sure the context starts in sync with our state.
@@ -93,6 +93,33 @@ static void setRGBABitmapAlpha(unsigned char* bytes, size_t length, unsigned cha
bytes[i + 3] = level;
}
+static void drawBitmapToContext(GraphicsContextPlatformPrivate* context, cairo_t* cr, const DIBPixelData& pixelData, const IntSize& translate)
+{
+ // Need to make a cairo_surface_t out of the bitmap's pixel buffer and then draw
+ // it into our context.
+ cairo_surface_t* surface = cairo_image_surface_create_for_data(pixelData.buffer(),
+ CAIRO_FORMAT_ARGB32,
+ pixelData.size().width(),
+ pixelData.size().height(),
+ pixelData.bytesPerRow());
+
+ // Flip the target surface so that when we set the srcImage as
+ // the surface it will draw right-side-up.
+ cairo_save(cr);
+ cairo_translate(cr, static_cast<double>(translate.width()), static_cast<double>(translate.height()));
+ cairo_scale(cr, 1, -1);
+ cairo_set_source_surface(cr, surface, 0, 0);
+
+ if (context->layers.size())
+ cairo_paint_with_alpha(cr, context->layers.last());
+ else
+ cairo_paint(cr);
+
+ // Delete all our junk.
+ cairo_surface_destroy(surface);
+ cairo_restore(cr);
+}
+
void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect& dstRect, bool supportAlphaBlend, bool mayCreateBitmap)
{
bool createdBitmap = mayCreateBitmap && (!m_data->m_hdc || inTransparencyLayer());
@@ -104,46 +131,26 @@ void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect& dstRect, boo
if (dstRect.isEmpty())
return;
- HBITMAP bitmap = static_cast<HBITMAP>(GetCurrentObject(hdc, OBJ_BITMAP));
+ OwnPtr<HBITMAP> bitmap = adoptPtr(static_cast<HBITMAP>(GetCurrentObject(hdc, OBJ_BITMAP)));
- BITMAP info;
- GetObject(bitmap, sizeof(info), &info);
- ASSERT(info.bmBitsPixel == 32);
+ DIBPixelData pixelData(bitmap.get());
+ ASSERT(pixelData.bitsPerPixel() == 32);
// If this context does not support alpha blending, then it may have
// been drawn with GDI functions which always set the alpha channel
// to zero. We need to manually set the bitmap to be fully opaque.
- unsigned char* bytes = reinterpret_cast<unsigned char*>(info.bmBits);
+ unsigned char* bytes = reinterpret_cast<unsigned char*>(pixelData.buffer());
if (!supportAlphaBlend)
- setRGBABitmapAlpha(bytes, info.bmHeight * info.bmWidthBytes, 255);
+ setRGBABitmapAlpha(bytes, pixelData.size().height() * pixelData.bytesPerRow(), 255);
- // Need to make a cairo_surface_t out of the bitmap's pixel buffer and then draw
- // it into our context.
- cairo_surface_t* image = cairo_image_surface_create_for_data(bytes,
- CAIRO_FORMAT_ARGB32,
- info.bmWidth,
- info.bmHeight,
- info.bmWidthBytes);
-
- // Scale the target surface to the new image size, and flip it
- // so that when we set the srcImage as the surface it will draw
- // right-side-up.
- cairo_t* cr = platformContext()->cr();
- cairo_save(cr);
- cairo_translate(cr, dstRect.x(), dstRect.height() + dstRect.y());
- cairo_scale(cr, 1, -1);
- cairo_set_source_surface(cr, image, 0, 0);
+ drawBitmapToContext(m_data, platformContext()->cr(), pixelData, IntSize(dstRect.x(), dstRect.height() + dstRect.y()));
- if (m_data->layers.size())
- cairo_paint_with_alpha(cr, m_data->layers.last());
- else
- cairo_paint(cr);
-
- // Delete all our junk.
- cairo_surface_destroy(image);
::DeleteDC(hdc);
- ::DeleteObject(bitmap);
- cairo_restore(cr);
+}
+
+void GraphicsContext::drawWindowsBitmap(WindowsBitmap* bitmap, const IntPoint& point)
+{
+ drawBitmapToContext(m_data, platformContext()->cr(), bitmap->windowsDIB(), IntSize(point.x(), bitmap->size().height() + point.y()));
}
void GraphicsContextPlatformPrivate::syncContext(cairo_t* cr)
diff --git a/Source/WebCore/platform/graphics/win/GraphicsContextWin.cpp b/Source/WebCore/platform/graphics/win/GraphicsContextWin.cpp
index f2850e4..28ce55a 100644
--- a/Source/WebCore/platform/graphics/win/GraphicsContextWin.cpp
+++ b/Source/WebCore/platform/graphics/win/GraphicsContextWin.cpp
@@ -26,9 +26,9 @@
#include "config.h"
#include "GraphicsContext.h"
-#if PLATFORM(CG)
+#if USE(CG)
#include "GraphicsContextPlatformPrivateCG.h"
-#elif PLATFORM(CAIRO)
+#elif USE(CAIRO)
#include "GraphicsContextPlatformPrivateCairo.h"
#endif
@@ -65,21 +65,20 @@ bool GraphicsContext::shouldIncludeChildWindows() const
GraphicsContext::WindowsBitmap::WindowsBitmap(HDC hdc, IntSize size)
: m_hdc(0)
- , m_size(size)
{
- BitmapInfo bitmapInfo = BitmapInfo::create(m_size);
+ BitmapInfo bitmapInfo = BitmapInfo::create(size);
- m_bitmap = CreateDIBSection(0, &bitmapInfo, DIB_RGB_COLORS, reinterpret_cast<void**>(&m_bitmapBuffer), 0, 0);
+ void* storage = 0;
+ m_bitmap = CreateDIBSection(0, &bitmapInfo, DIB_RGB_COLORS, &storage, 0, 0);
if (!m_bitmap)
return;
m_hdc = CreateCompatibleDC(hdc);
SelectObject(m_hdc, m_bitmap);
- BITMAP bmpInfo;
- GetObject(m_bitmap, sizeof(bmpInfo), &bmpInfo);
- m_bytesPerRow = bmpInfo.bmWidthBytes;
- m_bitmapBufferLength = bmpInfo.bmWidthBytes * bmpInfo.bmHeight;
+ m_pixelData.initialize(m_bitmap);
+
+ ASSERT(storage == m_pixelData.buffer());
SetGraphicsMode(m_hdc, GM_ADVANCED);
}
diff --git a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateFullscreenWindow.cpp b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateFullscreenWindow.cpp
index dd3cd32..588146a 100644
--- a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateFullscreenWindow.cpp
+++ b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateFullscreenWindow.cpp
@@ -30,7 +30,7 @@
#include "WebCoreInstanceHandle.h"
#include <windows.h>
-#if PLATFORM(CG)
+#if USE(CG)
#include <CoreGraphics/CGColor.h>
#endif
diff --git a/Source/WebCore/platform/graphics/win/SimpleFontDataWin.cpp b/Source/WebCore/platform/graphics/win/SimpleFontDataWin.cpp
index 323ff73..db730ca 100644
--- a/Source/WebCore/platform/graphics/win/SimpleFontDataWin.cpp
+++ b/Source/WebCore/platform/graphics/win/SimpleFontDataWin.cpp
@@ -39,7 +39,7 @@
#include <winsock2.h>
#include <wtf/MathExtras.h>
-#if PLATFORM(CG)
+#if USE(CG)
#include <ApplicationServices/ApplicationServices.h>
#include <WebKitSystemInterface/WebKitSystemInterface.h>
#endif
diff --git a/Source/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp b/Source/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp
index 19683df..e501621 100644
--- a/Source/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp
+++ b/Source/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp
@@ -1300,7 +1300,7 @@ void GraphicsContext::drawRoundCorner(bool needsNewClip, RECT clipRect, RECT rec
}
-FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& frect)
+FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& frect, RoundingMode)
{
notImplemented();
return frect;
diff --git a/Source/WebCore/platform/graphics/wince/ImageBufferData.h b/Source/WebCore/platform/graphics/wince/ImageBufferDataWince.h
index cbd49dc..dd46d38 100644
--- a/Source/WebCore/platform/graphics/wince/ImageBufferData.h
+++ b/Source/WebCore/platform/graphics/wince/ImageBufferDataWince.h
@@ -17,9 +17,6 @@
* Boston, MA 02110-1301, USA.
*/
-#ifndef ImageBufferData_h
-#define ImageBufferData_h
-
#include "SharedBitmap.h"
namespace WebCore {
@@ -33,5 +30,3 @@ public:
};
} // namespace WebCore
-
-#endif // ImageBufferData_h
diff --git a/Source/WebCore/platform/graphics/wx/FontPlatformDataWx.cpp b/Source/WebCore/platform/graphics/wx/FontPlatformDataWx.cpp
index 830cd05..3d98aeb 100644
--- a/Source/WebCore/platform/graphics/wx/FontPlatformDataWx.cpp
+++ b/Source/WebCore/platform/graphics/wx/FontPlatformDataWx.cpp
@@ -99,12 +99,14 @@ FontPlatformData::FontPlatformData(const FontDescription& desc, const AtomicStri
)
));
#endif
-#if OS(DARWIN) && !defined(wxOSX_USE_CORE_TEXT)
+#if OS(DARWIN)
+#if !wxOSX_USE_CORE_TEXT
#if wxCHECK_VERSION(2,9,0)
m_atsuFontID = m_font->font()->OSXGetATSUFontID();
#else
m_atsuFontID = m_font->font()->MacGetATSUFontID();
#endif
+#endif
m_nsFont = 0;
cacheNSFont();
#endif
diff --git a/Source/WebCore/platform/graphics/wx/GraphicsContextWx.cpp b/Source/WebCore/platform/graphics/wx/GraphicsContextWx.cpp
index 47f3211..071df47 100644
--- a/Source/WebCore/platform/graphics/wx/GraphicsContextWx.cpp
+++ b/Source/WebCore/platform/graphics/wx/GraphicsContextWx.cpp
@@ -416,7 +416,7 @@ void GraphicsContext::scale(const FloatSize& scale)
}
-FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& frect)
+FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& frect, RoundingMode)
{
FloatRect result;
diff --git a/Source/WebCore/platform/graphics/wx/ImageBufferData.h b/Source/WebCore/platform/graphics/wx/ImageBufferDataWx.h
index d4a6114..9961fee 100644
--- a/Source/WebCore/platform/graphics/wx/ImageBufferData.h
+++ b/Source/WebCore/platform/graphics/wx/ImageBufferDataWx.h
@@ -23,10 +23,6 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ImageBufferData_h
-#define ImageBufferData_h
-
-
#include "OwnPtr.h"
namespace WebCore {
@@ -38,6 +34,4 @@ public:
ImageBufferData(const IntSize&);
};
-} // namespace WebCore
-
-#endif // ImageBufferData_h
+} // namespace WebCore
diff --git a/Source/WebCore/platform/gtk/GtkVersioning.c b/Source/WebCore/platform/gtk/GtkVersioning.c
index c3407ea..1138d56 100644
--- a/Source/WebCore/platform/gtk/GtkVersioning.c
+++ b/Source/WebCore/platform/gtk/GtkVersioning.c
@@ -271,3 +271,13 @@ gboolean g_signal_accumulator_first_wins(GSignalInvocationHint *invocationHint,
}
#endif
+#if !GTK_CHECK_VERSION(2, 22, 0)
+cairo_surface_t *gdk_window_create_similar_surface(GdkWindow *window, cairo_content_t content, int width, int height)
+{
+ cairo_t *cairoContext = gdk_cairo_create(window);
+ cairo_surface_t *cairoSurface = cairo_get_target(cairoContext);
+ cairo_surface_t *newSurface = cairo_surface_create_similar(cairoSurface, content, width, height);
+ cairo_destroy(cairoContext);
+ return newSurface;
+}
+#endif // GTK_CHECK_VERSION(2, 22, 0)
diff --git a/Source/WebCore/platform/gtk/GtkVersioning.h b/Source/WebCore/platform/gtk/GtkVersioning.h
index 70e1bbe..b44fc38 100644
--- a/Source/WebCore/platform/gtk/GtkVersioning.h
+++ b/Source/WebCore/platform/gtk/GtkVersioning.h
@@ -46,6 +46,10 @@ GdkPixbuf* gdk_pixbuf_get_from_surface(cairo_surface_t* surface, int srcX, int s
#define gdk_window_get_visual gdk_drawable_get_visual
#endif // GTK_CHECK_VERSION(2, 23, 0)
+#if !GTK_CHECK_VERSION(2, 22, 0)
+cairo_surface_t* gdk_window_create_similar_surface(GdkWindow* window, cairo_content_t content, int width, int height);
+#endif // GTK_CHECK_VERSION(2, 22, 0)
+
#if !GTK_CHECK_VERSION(2, 21, 2)
#define gdk_visual_get_depth(visual) (visual)->depth
#define gdk_visual_get_bits_per_rgb(visual) (visual)->bits_per_rgb
diff --git a/Source/WebCore/platform/gtk/LocalizedStringsGtk.cpp b/Source/WebCore/platform/gtk/LocalizedStringsGtk.cpp
index 02f6c47..13c46fc 100644
--- a/Source/WebCore/platform/gtk/LocalizedStringsGtk.cpp
+++ b/Source/WebCore/platform/gtk/LocalizedStringsGtk.cpp
@@ -642,4 +642,9 @@ String validationMessageStepMismatchText(const String&, const String&)
return String::fromUTF8(_("step mismatch"));
}
+String localizedString(const char* key)
+{
+ return String::fromUTF8(key, strlen(key));
+}
+
}
diff --git a/Source/WebCore/platform/gtk/KeyEventGtk.cpp b/Source/WebCore/platform/gtk/PlatformKeyboardEventGtk.cpp
index d010b37..d010b37 100644
--- a/Source/WebCore/platform/gtk/KeyEventGtk.cpp
+++ b/Source/WebCore/platform/gtk/PlatformKeyboardEventGtk.cpp
diff --git a/Source/WebCore/platform/gtk/MouseEventGtk.cpp b/Source/WebCore/platform/gtk/PlatformMouseEventGtk.cpp
index 69f938f..69f938f 100644
--- a/Source/WebCore/platform/gtk/MouseEventGtk.cpp
+++ b/Source/WebCore/platform/gtk/PlatformMouseEventGtk.cpp
diff --git a/Source/WebCore/platform/gtk/WheelEventGtk.cpp b/Source/WebCore/platform/gtk/PlatformWheelEventGtk.cpp
index fc6206f..fc6206f 100644
--- a/Source/WebCore/platform/gtk/WheelEventGtk.cpp
+++ b/Source/WebCore/platform/gtk/PlatformWheelEventGtk.cpp
diff --git a/Source/WebCore/platform/gtk/RenderThemeGtk.h b/Source/WebCore/platform/gtk/RenderThemeGtk.h
index 191a34b..09eb1df 100644
--- a/Source/WebCore/platform/gtk/RenderThemeGtk.h
+++ b/Source/WebCore/platform/gtk/RenderThemeGtk.h
@@ -147,6 +147,7 @@ protected:
void initMediaColors();
void initMediaButtons();
void adjustMediaSliderThumbSize(RenderObject*) const;
+ virtual bool hasOwnDisabledStateHandlingFor(ControlPart) const { return true; }
virtual bool paintMediaFullscreenButton(RenderObject*, const PaintInfo&, const IntRect&);
virtual bool paintMediaPlayButton(RenderObject*, const PaintInfo&, const IntRect&);
virtual bool paintMediaMuteButton(RenderObject*, const PaintInfo&, const IntRect&);
diff --git a/Source/WebCore/platform/gtk/RenderThemeGtk3.cpp b/Source/WebCore/platform/gtk/RenderThemeGtk3.cpp
index 527de1a..6e2c94c 100644
--- a/Source/WebCore/platform/gtk/RenderThemeGtk3.cpp
+++ b/Source/WebCore/platform/gtk/RenderThemeGtk3.cpp
@@ -34,6 +34,7 @@
#include "MediaControlElements.h"
#include "Page.h"
#include "PaintInfo.h"
+#include "PlatformContextCairo.h"
#include "RenderObject.h"
#include "TextDirection.h"
#include "UserAgentStyleSheets.h"
@@ -216,16 +217,16 @@ static void paintToggle(const RenderThemeGtk* theme, GType widgetType, RenderObj
gtk_style_context_set_state(context, static_cast<GtkStateFlags>(flags));
if (widgetType == GTK_TYPE_CHECK_BUTTON)
- gtk_render_check(context, paintInfo.context->platformContext(), rect.x(), rect.y(), rect.width(), rect.height());
+ gtk_render_check(context, paintInfo.context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
else
- gtk_render_option(context, paintInfo.context->platformContext(), rect.x(), rect.y(), rect.width(), rect.height());
+ gtk_render_option(context, paintInfo.context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
if (theme->isFocused(renderObject)) {
IntRect indicatorRect(rect);
gint indicatorSpacing;
gtk_style_context_get_style(context, "indicator-spacing", &indicatorSpacing, NULL);
indicatorRect.inflate(indicatorSpacing);
- gtk_render_focus(context, paintInfo.context->platformContext(), indicatorRect.x(), indicatorRect.y(),
+ gtk_render_focus(context, paintInfo.context->platformContext()->cr(), indicatorRect.x(), indicatorRect.y(),
indicatorRect.width(), indicatorRect.height());
}
@@ -284,8 +285,8 @@ static void renderButton(RenderTheme* theme, GtkStyleContext* context, RenderObj
gtk_style_context_add_class(context, GTK_STYLE_CLASS_DEFAULT);
}
- gtk_render_background(context, paintInfo.context->platformContext(), buttonRect.x(), buttonRect.y(), buttonRect.width(), buttonRect.height());
- gtk_render_frame(context, paintInfo.context->platformContext(), buttonRect.x(), buttonRect.y(), buttonRect.width(), buttonRect.height());
+ gtk_render_background(context, paintInfo.context->platformContext()->cr(), buttonRect.x(), buttonRect.y(), buttonRect.width(), buttonRect.height());
+ gtk_render_frame(context, paintInfo.context->platformContext()->cr(), buttonRect.x(), buttonRect.y(), buttonRect.width(), buttonRect.height());
if (theme->isFocused(renderObject)) {
gint focusWidth, focusPad;
@@ -317,7 +318,7 @@ static void renderButton(RenderTheme* theme, GtkStyleContext* context, RenderObj
buttonRect.move(childDisplacementX, childDisplacementY);
}
- gtk_render_focus(context, paintInfo.context->platformContext(), buttonRect.x(), buttonRect.y(), buttonRect.width(), buttonRect.height());
+ gtk_render_focus(context, paintInfo.context->platformContext()->cr(), buttonRect.x(), buttonRect.y(), buttonRect.width(), buttonRect.height());
}
}
bool RenderThemeGtk::paintButton(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect)
@@ -423,7 +424,7 @@ int RenderThemeGtk::popupInternalPaddingBottom(RenderStyle* style) const
bool RenderThemeGtk::paintMenuList(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect)
{
- cairo_t* cairoContext = paintInfo.context->platformContext();
+ cairo_t* cairoContext = paintInfo.context->platformContext()->cr();
GtkTextDirection direction = static_cast<GtkTextDirection>(gtkTextDirection(renderObject->style()->direction()));
// Paint the button.
@@ -568,8 +569,8 @@ bool RenderThemeGtk::paintTextField(RenderObject* renderObject, const PaintInfo&
flags |= GTK_STATE_FLAG_FOCUSED;
gtk_style_context_set_state(context, static_cast<GtkStateFlags>(flags));
- gtk_render_background(context, paintInfo.context->platformContext(), rect.x(), rect.y(), rect.width(), rect.height());
- gtk_render_frame(context, paintInfo.context->platformContext(), rect.x(), rect.y(), rect.width(), rect.height());
+ gtk_render_background(context, paintInfo.context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
+ gtk_render_frame(context, paintInfo.context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
if (isFocused(renderObject) && isEnabled(renderObject)) {
gboolean interiorFocus;
@@ -582,7 +583,7 @@ bool RenderThemeGtk::paintTextField(RenderObject* renderObject, const PaintInfo&
if (!interiorFocus) {
IntRect focusRect(rect);
focusRect.inflate(focusWidth + focusPad);
- gtk_render_focus(context, paintInfo.context->platformContext(),
+ gtk_render_focus(context, paintInfo.context->platformContext()->cr(),
focusRect.x(), focusRect.y(), focusRect.width(), focusRect.height());
}
}
@@ -607,9 +608,9 @@ bool RenderThemeGtk::paintSliderTrack(RenderObject* renderObject, const PaintInf
if (!isEnabled(renderObject) || isReadOnlyControl(renderObject))
gtk_style_context_set_state(context, GTK_STATE_FLAG_INSENSITIVE);
- gtk_render_background(context, paintInfo.context->platformContext(),
+ gtk_render_background(context, paintInfo.context->platformContext()->cr(),
rect.x(), rect.y(), rect.width(), rect.height());
- gtk_render_frame(context, paintInfo.context->platformContext(),
+ gtk_render_frame(context, paintInfo.context->platformContext()->cr(),
rect.x(), rect.y(), rect.width(), rect.height());
if (isFocused(renderObject)) {
@@ -619,7 +620,7 @@ bool RenderThemeGtk::paintSliderTrack(RenderObject* renderObject, const PaintInf
"focus-padding", &focusPad, NULL);
IntRect focusRect(rect);
focusRect.inflate(focusWidth + focusPad);
- gtk_render_focus(context, paintInfo.context->platformContext(),
+ gtk_render_focus(context, paintInfo.context->platformContext()->cr(),
focusRect.x(), focusRect.y(), focusRect.width(), focusRect.height());
}
@@ -654,7 +655,7 @@ bool RenderThemeGtk::paintSliderThumb(RenderObject* renderObject, const PaintInf
flags |= GTK_STATE_FLAG_ACTIVE;
gtk_style_context_set_state(context, static_cast<GtkStateFlags>(flags));
- gtk_render_slider(context, paintInfo.context->platformContext(), sliderRect.x(), sliderRect.y(), sliderRect.width(), sliderRect.height(),
+ gtk_render_slider(context, paintInfo.context->platformContext()->cr(), sliderRect.x(), sliderRect.y(), sliderRect.width(), sliderRect.height(),
part == SliderThumbHorizontalPart ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL);
gtk_style_context_restore(context);
@@ -698,8 +699,8 @@ bool RenderThemeGtk::paintProgressBar(RenderObject* renderObject, const PaintInf
gtk_style_context_add_class(context, GTK_STYLE_CLASS_TROUGH);
- gtk_render_background(context, paintInfo.context->platformContext(), rect.x(), rect.y(), rect.width(), rect.height());
- gtk_render_frame(context, paintInfo.context->platformContext(), rect.x(), rect.y(), rect.width(), rect.height());
+ gtk_render_background(context, paintInfo.context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
+ gtk_render_frame(context, paintInfo.context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
gtk_style_context_restore(context);
@@ -715,7 +716,7 @@ bool RenderThemeGtk::paintProgressBar(RenderObject* renderObject, const PaintInf
progressRect = RenderThemeGtk::calculateProgressRect(renderObject, progressRect);
if (!progressRect.isEmpty())
- gtk_render_activity(context, paintInfo.context->platformContext(), progressRect.x(), progressRect.y(), progressRect.width(), progressRect.height());
+ gtk_render_activity(context, paintInfo.context->platformContext()->cr(), progressRect.x(), progressRect.y(), progressRect.width(), progressRect.height());
gtk_style_context_restore(context);
return false;
@@ -777,8 +778,8 @@ static void paintSpinArrowButton(RenderTheme* theme, GtkStyleContext* context, R
buttonRect.setHeight(rect.height() / 2);
gtk_style_context_set_junction_sides(context, static_cast<GtkJunctionSides>(junction));
- gtk_render_background(context, paintInfo.context->platformContext(), buttonRect.x(), buttonRect.y(), buttonRect.width(), buttonRect.height());
- gtk_render_frame(context, paintInfo.context->platformContext(), buttonRect.x(), buttonRect.y(), buttonRect.width(), buttonRect.height());
+ gtk_render_background(context, paintInfo.context->platformContext()->cr(), buttonRect.x(), buttonRect.y(), buttonRect.width(), buttonRect.height());
+ gtk_render_frame(context, paintInfo.context->platformContext()->cr(), buttonRect.x(), buttonRect.y(), buttonRect.width(), buttonRect.height());
// Paint arrow centered inside button.
// This code is based on gtkspinbutton.c code.
@@ -804,7 +805,7 @@ static void paintSpinArrowButton(RenderTheme* theme, GtkStyleContext* context, R
gint height = (width + 1) / 2;
arrowRect.move((arrowRect.width() - width) / 2, (arrowRect.height() - height) / 2);
- gtk_render_arrow(context, paintInfo.context->platformContext(), angle, arrowRect.x(), arrowRect.y(), width);
+ gtk_render_arrow(context, paintInfo.context->platformContext()->cr(), angle, arrowRect.x(), arrowRect.y(), width);
gtk_style_context_restore(context);
}
diff --git a/Source/WebCore/platform/gtk/ScrollbarThemeGtk3.cpp b/Source/WebCore/platform/gtk/ScrollbarThemeGtk3.cpp
index b0b5146..f854037 100644
--- a/Source/WebCore/platform/gtk/ScrollbarThemeGtk3.cpp
+++ b/Source/WebCore/platform/gtk/ScrollbarThemeGtk3.cpp
@@ -28,6 +28,7 @@
#ifndef GTK_API_VERSION_2
+#include "PlatformContextCairo.h"
#include "PlatformMouseEvent.h"
#include "RenderThemeGtk.h"
#include "ScrollView.h"
@@ -77,9 +78,9 @@ void ScrollbarThemeGtk::paintTrackBackground(GraphicsContext* context, Scrollbar
gtk_style_context_add_class(m_context, GTK_STYLE_CLASS_SCROLLBAR);
gtk_style_context_add_class(m_context, GTK_STYLE_CLASS_TROUGH);
- gtk_render_background(m_context, context->platformContext(),
+ gtk_render_background(m_context, context->platformContext()->cr(),
fullScrollbarRect.x(), fullScrollbarRect.y(), fullScrollbarRect.width(), fullScrollbarRect.height());
- gtk_render_frame(m_context, context->platformContext(),
+ gtk_render_frame(m_context, context->platformContext()->cr(),
fullScrollbarRect.x(), fullScrollbarRect.y(), fullScrollbarRect.width(), fullScrollbarRect.height());
gtk_style_context_restore(m_context);
@@ -91,7 +92,7 @@ void ScrollbarThemeGtk::paintScrollbarBackground(GraphicsContext* context, Scrol
gtk_style_context_add_class(m_context, GTK_STYLE_CLASS_SCROLLBAR);
gtk_style_context_add_class(m_context, "scrolled-window");
- gtk_render_frame(m_context, context->platformContext(), scrollbar->x(), scrollbar->y(), scrollbar->width(), scrollbar->height());
+ gtk_render_frame(m_context, context->platformContext()->cr(), scrollbar->x(), scrollbar->y(), scrollbar->width(), scrollbar->height());
gtk_style_context_restore(m_context);
}
@@ -110,7 +111,7 @@ void ScrollbarThemeGtk::paintThumb(GraphicsContext* context, Scrollbar* scrollba
flags |= GTK_STATE_FLAG_PRELIGHT;
gtk_style_context_set_state(m_context, static_cast<GtkStateFlags>(flags));
- gtk_render_slider(m_context, context->platformContext(), rect.x(), rect.y(), rect.width(), rect.height(),
+ gtk_render_slider(m_context, context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height(),
scrollbar->orientation() == VerticalScrollbar ? GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL);
gtk_style_context_restore(m_context);
@@ -136,8 +137,8 @@ void ScrollbarThemeGtk::paintButton(GraphicsContext* context, Scrollbar* scrollb
gtk_style_context_set_state(m_context, static_cast<GtkStateFlags>(flags));
gtk_style_context_add_class(m_context, GTK_STYLE_CLASS_BUTTON);
- gtk_render_background(m_context, context->platformContext(), rect.x(), rect.y(), rect.width(), rect.height());
- gtk_render_frame(m_context, context->platformContext(), rect.x(), rect.y(), rect.width(), rect.height());
+ gtk_render_background(m_context, context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
+ gtk_render_frame(m_context, context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
gfloat arrowScaling;
gtk_style_context_get_style(m_context, "arrow-scaling", &arrowScaling, NULL);
@@ -162,7 +163,7 @@ void ScrollbarThemeGtk::paintButton(GraphicsContext* context, Scrollbar* scrollb
angle = (part == ForwardButtonEndPart || part == ForwardButtonStartPart) ? G_PI / 2 : 3 * (G_PI / 2);
}
- gtk_render_arrow(m_context, context->platformContext(), angle, arrowPoint.x(), arrowPoint.y(), arrowSize);
+ gtk_render_arrow(m_context, context->platformContext()->cr(), angle, arrowPoint.x(), arrowPoint.y(), arrowSize);
gtk_style_context_restore(m_context);
}
diff --git a/Source/WebCore/platform/image-decoders/ImageDecoder.cpp b/Source/WebCore/platform/image-decoders/ImageDecoder.cpp
index e59d461..24a9f90 100644
--- a/Source/WebCore/platform/image-decoders/ImageDecoder.cpp
+++ b/Source/WebCore/platform/image-decoders/ImageDecoder.cpp
@@ -172,7 +172,7 @@ void ImageFrame::zeroFillPixelData()
m_hasAlpha = true;
}
-#if !PLATFORM(CG)
+#if !USE(CG)
void ImageFrame::copyReferenceToBitmapData(const ImageFrame& other)
{
diff --git a/Source/WebCore/platform/image-decoders/ImageDecoder.h b/Source/WebCore/platform/image-decoders/ImageDecoder.h
index 801daf3..f45d708 100644
--- a/Source/WebCore/platform/image-decoders/ImageDecoder.h
+++ b/Source/WebCore/platform/image-decoders/ImageDecoder.h
@@ -147,7 +147,7 @@ namespace WebCore {
#endif
private:
-#if PLATFORM(CG)
+#if USE(CG)
typedef RetainPtr<CFMutableDataRef> NativeBackingStore;
#else
typedef Vector<PixelData> NativeBackingStore;
diff --git a/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.cpp b/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.cpp
index 060c62a..eacfd29 100644
--- a/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.cpp
+++ b/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.cpp
@@ -38,6 +38,8 @@ namespace WebCore {
WEBPImageDecoder::WEBPImageDecoder(ImageSource::AlphaOption alphaOption,
ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption)
: ImageDecoder(alphaOption, gammaAndColorProfileOption)
+ , m_decoder(0)
+ , m_lastVisibleRow(0)
{
}
@@ -79,12 +81,13 @@ bool WEBPImageDecoder::decode(bool onlySize)
if (failed())
return false;
+
const size_t dataSize = m_data->size();
- const uint8_t* dataBytes =
- reinterpret_cast<const uint8_t*>(m_data->data());
- int width, height;
if (dataSize < sizeOfHeader)
return true;
+
+ int width, height;
+ const uint8_t* dataBytes = reinterpret_cast<const uint8_t*>(m_data->data());
if (!WebPGetInfo(dataBytes, dataSize, &width, &height))
return setFailed();
if (!ImageDecoder::isSizeAvailable() && !setSize(width, height))
@@ -92,9 +95,8 @@ bool WEBPImageDecoder::decode(bool onlySize)
if (onlySize)
return true;
- // FIXME: Add support for progressive decoding.
- if (!isAllDataReceived())
- return true;
+ bool allDataReceived = isAllDataReceived();
+ int stride = width * bytesPerPixel;
ASSERT(!m_frameBufferCache.isEmpty());
ImageFrame& buffer = m_frameBufferCache[0];
if (buffer.status() == ImageFrame::FrameEmpty) {
@@ -102,22 +104,41 @@ bool WEBPImageDecoder::decode(bool onlySize)
ASSERT(height == size().height());
if (!buffer.setSize(width, height))
return setFailed();
+ buffer.setStatus(allDataReceived ? ImageFrame::FrameComplete : ImageFrame::FramePartial);
+ // FIXME: We currently hard code false below because libwebp doesn't support alpha yet.
+ buffer.setHasAlpha(false);
+ buffer.setOriginalFrameRect(IntRect(IntPoint(), size()));
+ m_rgbOutput.resize(height * stride);
+ }
+ int newLastVisibleRow = 0; // Last completed row.
+ if (allDataReceived) {
+ if (!WebPDecodeRGBInto(dataBytes, dataSize, m_rgbOutput.data(), m_rgbOutput.size(), stride))
+ return setFailed();
+ newLastVisibleRow = height;
+ } else {
+ if (!m_decoder) {
+ m_decoder = WebPINewRGB(MODE_RGB, m_rgbOutput.data(), m_rgbOutput.size(), stride);
+ if (!m_decoder)
+ return setFailed();
+ }
+ const VP8StatusCode status = WebPIUpdate(m_decoder, dataBytes, dataSize);
+ if (status != VP8_STATUS_OK && status != VP8_STATUS_SUSPENDED)
+ return setFailed();
+ if (!WebPIDecGetRGB(m_decoder, &newLastVisibleRow, 0, 0, 0))
+ return setFailed();
+ ASSERT(newLastVisibleRow >= 0);
+ ASSERT(newLastVisibleRow <= height);
}
- const int stride = width * bytesPerPixel;
- Vector<uint8_t> rgb;
- rgb.resize(height * stride);
- if (!WebPDecodeBGRInto(dataBytes, dataSize, rgb.data(), rgb.size(), stride))
- return setFailed();
// FIXME: remove this data copy.
- for (int y = 0; y < height; ++y) {
- const uint8_t* const src = &rgb[y * stride];
+ for (int y = m_lastVisibleRow; y < newLastVisibleRow; ++y) {
+ const uint8_t* const src = &m_rgbOutput[y * stride];
for (int x = 0; x < width; ++x)
- buffer.setRGBA(x, y, src[bytesPerPixel * x + 2], src[bytesPerPixel * x + 1], src[bytesPerPixel * x + 0], 0xff);
+ buffer.setRGBA(x, y, src[bytesPerPixel * x + 0], src[bytesPerPixel * x + 1], src[bytesPerPixel * x + 2], 0xff);
}
- buffer.setStatus(ImageFrame::FrameComplete);
- buffer.setHasAlpha(false);
- buffer.setOriginalFrameRect(IntRect(IntPoint(), size()));
- return true;
+ m_lastVisibleRow = newLastVisibleRow;
+ if (m_lastVisibleRow == height)
+ buffer.setStatus(ImageFrame::FrameComplete);
+ return m_lastVisibleRow == height;
}
}
diff --git a/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.h b/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.h
index c32e047..53da91f 100644
--- a/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.h
+++ b/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.h
@@ -33,6 +33,9 @@
#if USE(WEBP)
+// Forward declaration of libwebp's structure. Must be outside the WebCore scope.
+typedef struct WebPIDecoder WebPIDecoder;
+
namespace WebCore {
class WEBPImageDecoder : public ImageDecoder {
@@ -46,6 +49,10 @@ public:
private:
// Returns false in case of decoding failure.
bool decode(bool onlySize);
+
+ WebPIDecoder* m_decoder; // This is only used when we want to decode() but not all data is available yet.
+ int m_lastVisibleRow;
+ Vector<uint8_t> m_rgbOutput;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/leveldb/LevelDBComparator.h b/Source/WebCore/platform/leveldb/LevelDBComparator.h
new file mode 100644
index 0000000..08ac261
--- /dev/null
+++ b/Source/WebCore/platform/leveldb/LevelDBComparator.h
@@ -0,0 +1,48 @@
+/*
+ * 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 LevelDBComparator_h
+#define LevelDBComparator_h
+
+#if ENABLE(LEVELDB)
+
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class LevelDBSlice;
+
+class LevelDBComparator {
+public:
+ virtual ~LevelDBComparator() {}
+
+ virtual int compare(const LevelDBSlice&, const LevelDBSlice&) const = 0;
+ virtual const char* name() const = 0;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(LEVELDB)
+#endif // LevelDBComparator_h
diff --git a/Source/WebCore/platform/leveldb/LevelDBDatabase.cpp b/Source/WebCore/platform/leveldb/LevelDBDatabase.cpp
new file mode 100644
index 0000000..4587631
--- /dev/null
+++ b/Source/WebCore/platform/leveldb/LevelDBDatabase.cpp
@@ -0,0 +1,159 @@
+/*
+ * 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 "LevelDBDatabase.h"
+
+#if ENABLE(LEVELDB)
+
+#include "LevelDBComparator.h"
+#include "LevelDBIterator.h"
+#include "LevelDBSlice.h"
+#include <leveldb/comparator.h>
+#include <leveldb/db.h>
+#include <leveldb/slice.h>
+#include <string>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/text/CString.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+static leveldb::Slice makeSlice(const Vector<char>& value)
+{
+ return leveldb::Slice(value.data(), value.size());
+}
+
+static leveldb::Slice makeSlice(const LevelDBSlice& s)
+{
+ return leveldb::Slice(s.begin(), s.end() - s.begin());
+}
+
+static LevelDBSlice makeLevelDBSlice(const leveldb::Slice& s)
+{
+ return LevelDBSlice(s.data(), s.data() + s.size());
+}
+
+static Vector<char> makeVector(const std::string& s)
+{
+ Vector<char> res;
+ res.append(s.c_str(), s.length());
+ return res;
+}
+
+namespace {
+class ComparatorAdapter : public leveldb::Comparator {
+public:
+ ComparatorAdapter(const LevelDBComparator* comparator)
+ : m_comparator(comparator)
+ {
+ }
+
+ virtual int Compare(const leveldb::Slice& a, const leveldb::Slice& b) const
+ {
+ return m_comparator->compare(makeLevelDBSlice(a), makeLevelDBSlice(b));
+ }
+
+ virtual const char* Name() const { return m_comparator->name(); }
+
+ // FIXME: Support the methods below in the future.
+ virtual void FindShortestSeparator(std::string* start, const leveldb::Slice& limit) const { }
+ virtual void FindShortSuccessor(std::string* key) const { }
+
+private:
+ const LevelDBComparator* m_comparator;
+};
+}
+
+LevelDBDatabase::LevelDBDatabase()
+ : m_db(0)
+{
+}
+
+LevelDBDatabase::~LevelDBDatabase()
+{
+}
+
+LevelDBDatabase* LevelDBDatabase::open(const String& fileName, const LevelDBComparator* comparator)
+{
+ OwnPtr<ComparatorAdapter> comparatorAdapter(new ComparatorAdapter(comparator));
+
+ LevelDBDatabase* result = new LevelDBDatabase();
+
+ leveldb::Options options;
+ options.comparator = comparatorAdapter.get();
+ options.create_if_missing = true;
+ leveldb::DB* db;
+ leveldb::Status s = leveldb::DB::Open(options, fileName.utf8().data(), &db);
+
+ if (!s.ok()) {
+ delete result;
+ return 0;
+ }
+
+ result->m_db = WTF::adoptPtr(db);
+ result->m_comparatorAdapter = comparatorAdapter.release();
+
+ return result;
+}
+
+
+bool LevelDBDatabase::put(const LevelDBSlice& key, const Vector<char>& value)
+{
+ leveldb::WriteOptions writeOptions;
+ writeOptions.sync = false;
+
+ return m_db->Put(writeOptions, makeSlice(key), makeSlice(value)).ok();
+}
+
+bool LevelDBDatabase::remove(const LevelDBSlice& key)
+{
+ leveldb::WriteOptions writeOptions;
+ writeOptions.sync = false;
+
+ return m_db->Delete(writeOptions, makeSlice(key)).ok();
+}
+
+bool LevelDBDatabase::get(const LevelDBSlice& key, Vector<char>& value)
+{
+ std::string result;
+ if (!m_db->Get(leveldb::ReadOptions(), makeSlice(key), &result).ok())
+ return false;
+
+ value = makeVector(result);
+ return true;
+}
+
+LevelDBIterator* LevelDBDatabase::newIterator()
+{
+ leveldb::Iterator* i = m_db->NewIterator(leveldb::ReadOptions());
+ if (!i) // FIXME: Double check if we actually need to check this.
+ return 0;
+ return new LevelDBIterator(i);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(LEVELDB)
diff --git a/Source/WebCore/platform/leveldb/LevelDBDatabase.h b/Source/WebCore/platform/leveldb/LevelDBDatabase.h
new file mode 100644
index 0000000..471f335
--- /dev/null
+++ b/Source/WebCore/platform/leveldb/LevelDBDatabase.h
@@ -0,0 +1,66 @@
+/*
+ * 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 LevelDBDatabase_h
+#define LevelDBDatabase_h
+
+#if ENABLE(LEVELDB)
+
+#include "PlatformString.h"
+#include <OwnPtr.h>
+#include <Vector.h>
+
+namespace leveldb {
+class Comparator;
+class DB;
+}
+
+namespace WebCore {
+
+class LevelDBComparator;
+class LevelDBIterator;
+class LevelDBSlice;
+
+class LevelDBDatabase {
+public:
+ static LevelDBDatabase* open(const String& fileName, const LevelDBComparator*);
+ ~LevelDBDatabase();
+
+ bool put(const LevelDBSlice& key, const Vector<char>& value);
+ bool remove(const LevelDBSlice& key);
+ bool get(const LevelDBSlice& key, Vector<char>& value);
+ LevelDBIterator* newIterator();
+
+private:
+ LevelDBDatabase();
+
+ OwnPtr<leveldb::DB> m_db;
+ OwnPtr<leveldb::Comparator> m_comparatorAdapter;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(LEVELDB)
+#endif // LevelDBDatabase_h
diff --git a/Source/WebCore/platform/mac/RuntimeApplicationChecks.mm b/Source/WebCore/platform/leveldb/LevelDBIterator.cpp
index 7fe8378..de0f286 100644
--- a/Source/WebCore/platform/mac/RuntimeApplicationChecks.mm
+++ b/Source/WebCore/platform/leveldb/LevelDBIterator.cpp
@@ -1,15 +1,15 @@
/*
- * Copyright (C) 2009 Apple 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:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 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.
+ * 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
@@ -23,46 +23,72 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#import "config.h"
-#import "RuntimeApplicationChecks.h"
+#include "config.h"
+#include "LevelDBIterator.h"
+#if ENABLE(LEVELDB)
+
+#include <leveldb/iterator.h>
+#include <leveldb/slice.h>
+#include <wtf/text/CString.h>
+#include <wtf/text/WTFString.h>
namespace WebCore {
-bool applicationIsAppleMail()
+LevelDBIterator::~LevelDBIterator()
+{
+}
+
+LevelDBIterator::LevelDBIterator(leveldb::Iterator* it)
+ : m_iterator(it)
+{
+}
+
+static leveldb::Slice makeSlice(const Vector<char>& value)
+{
+ return leveldb::Slice(value.data(), value.size());
+}
+
+static LevelDBSlice makeLevelDBSlice(leveldb::Slice s)
{
- static const bool isAppleMail = [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.mail"];
- return isAppleMail;
+ return LevelDBSlice(s.data(), s.data() + s.size());
}
-bool applicationIsSafari()
+bool LevelDBIterator::isValid() const
{
- static const bool isSafari = [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.Safari"];
- return isSafari;
+ return m_iterator->Valid();
}
-bool applicationIsMicrosoftMessenger()
+void LevelDBIterator::seekToLast()
{
- static bool isMicrosoftMessenger = [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.microsoft.Messenger"];
- return isMicrosoftMessenger;
+ m_iterator->SeekToLast();
}
-bool applicationIsAdobeInstaller()
+void LevelDBIterator::seek(const Vector<char>& target)
{
- static bool isAdobeInstaller = [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.adobe.Installers.Setup"];
- return isAdobeInstaller;
+ m_iterator->Seek(makeSlice(target));
}
-
-bool applicationIsAOLInstantMessenger()
+
+void LevelDBIterator::next()
+{
+ m_iterator->Next();
+}
+
+void LevelDBIterator::prev()
{
- static bool isAOLInstantMessenger = [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.aol.aim.desktop"];
- return isAOLInstantMessenger;
+ m_iterator->Prev();
}
-bool applicationIsMicrosoftMyDay()
+LevelDBSlice LevelDBIterator::key() const
{
- static bool isMicrosoftMyDay = [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.microsoft.myday"];
- return isMicrosoftMyDay;
+ return makeLevelDBSlice(m_iterator->key());
+}
+
+LevelDBSlice LevelDBIterator::value() const
+{
+ return makeLevelDBSlice(m_iterator->value());
}
} // namespace WebCore
+
+#endif // ENABLE(LEVELDB)
diff --git a/Source/WebCore/platform/leveldb/LevelDBIterator.h b/Source/WebCore/platform/leveldb/LevelDBIterator.h
new file mode 100644
index 0000000..ff9cbca
--- /dev/null
+++ b/Source/WebCore/platform/leveldb/LevelDBIterator.h
@@ -0,0 +1,65 @@
+/*
+ * 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 LevelDBIterator_h
+#define LevelDBIterator_h
+
+#if ENABLE(LEVELDB)
+
+#include "LevelDBSlice.h"
+#include "PlatformString.h"
+#include <OwnPtr.h>
+#include <Vector.h>
+
+namespace leveldb {
+class Iterator;
+}
+
+namespace WebCore {
+
+class LevelDBIterator {
+public:
+ ~LevelDBIterator();
+
+ bool isValid() const;
+ void seekToLast();
+ void seek(const Vector<char>& target);
+ void next();
+ void prev();
+ LevelDBSlice key() const;
+ LevelDBSlice value() const;
+
+private:
+ LevelDBIterator(leveldb::Iterator*);
+ friend class LevelDBDatabase;
+
+ OwnPtr<leveldb::Iterator> m_iterator;
+};
+
+
+} // namespace WebCore
+
+#endif // ENABLE(LEVELDB)
+#endif // LevelDBIterator_h
diff --git a/Source/WebCore/platform/leveldb/LevelDBSlice.h b/Source/WebCore/platform/leveldb/LevelDBSlice.h
new file mode 100644
index 0000000..15c576c
--- /dev/null
+++ b/Source/WebCore/platform/leveldb/LevelDBSlice.h
@@ -0,0 +1,67 @@
+/*
+ * 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 LevelDBSlice_h
+#define LevelDBSlice_h
+
+#if ENABLE(LEVELDB)
+
+#include "PlatformString.h"
+#include <Vector.h>
+
+namespace WebCore {
+
+class LevelDBSlice {
+public:
+ LevelDBSlice(const char* begin, const char* end)
+ : m_begin(begin)
+ , m_end(end)
+ {
+ ASSERT(m_end >= m_begin);
+ }
+
+ LevelDBSlice(const Vector<char>& v)
+ : m_begin(v.data())
+ , m_end(m_begin + v.size())
+ {
+ ASSERT(m_end >= m_begin);
+ }
+
+ ~LevelDBSlice()
+ {
+ }
+
+ const char* begin() const { return m_begin; }
+ const char* end() const { return m_end; }
+
+private:
+ const char* m_begin;
+ const char* m_end;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(LEVELDB)
+#endif // LevelDBSlice_h
diff --git a/Source/WebCore/platform/mac/ClipboardMac.mm b/Source/WebCore/platform/mac/ClipboardMac.mm
index a41982a..a5005eb 100644
--- a/Source/WebCore/platform/mac/ClipboardMac.mm
+++ b/Source/WebCore/platform/mac/ClipboardMac.mm
@@ -49,7 +49,7 @@ namespace WebCore {
PassRefPtr<Clipboard> Clipboard::create(ClipboardAccessPolicy policy, DragData* dragData, Frame* frame)
{
- return ClipboardMac::create(DragAndDrop, [dragData->platformData() draggingPasteboard], policy, frame);
+ return ClipboardMac::create(DragAndDrop, dragData->pasteboard(), policy, frame);
}
ClipboardMac::ClipboardMac(ClipboardType clipboardType, NSPasteboard *pasteboard, ClipboardAccessPolicy policy, Frame *frame)
diff --git a/Source/WebCore/platform/mac/DragDataMac.mm b/Source/WebCore/platform/mac/DragDataMac.mm
index 64376b1..41d23db 100644
--- a/Source/WebCore/platform/mac/DragDataMac.mm
+++ b/Source/WebCore/platform/mac/DragDataMac.mm
@@ -104,7 +104,7 @@ String DragData::asPlainText(Frame *frame) const
Color DragData::asColor() const
{
- NSColor *color = [NSColor colorFromPasteboard:[m_platformDragData draggingPasteboard]];
+ NSColor *color = [NSColor colorFromPasteboard:m_pasteboard.get()];
return makeRGBA((int)([color redComponent] * 255.0 + 0.5), (int)([color greenComponent] * 255.0 + 0.5),
(int)([color blueComponent] * 255.0 + 0.5), (int)([color alphaComponent] * 255.0 + 0.5));
}
@@ -141,7 +141,7 @@ String DragData::asURL(Frame* frame, FilenameConversionPolicy filenamePolicy, St
(void)filenamePolicy;
if (title) {
- if (NSString *URLTitleString = [[m_platformDragData draggingPasteboard] stringForType:WebURLNamePboardType])
+ if (NSString *URLTitleString = [m_pasteboard.get() stringForType:WebURLNamePboardType])
*title = URLTitleString;
}
Pasteboard pasteboard(m_pasteboard.get());
diff --git a/Source/WebCore/platform/mac/HTMLConverter.h b/Source/WebCore/platform/mac/HTMLConverter.h
index 645c1d7..3250769 100644
--- a/Source/WebCore/platform/mac/HTMLConverter.h
+++ b/Source/WebCore/platform/mac/HTMLConverter.h
@@ -23,12 +23,12 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#import "DOM.h"
-#import "DOMDocument.h"
-#import "DOMRange.h"
+@class DOMDocument;
+@class DOMRange;
namespace WebCore {
-class DocumentLoader;
+ class DocumentLoader;
+ class Range;
}
@interface WebHTMLConverter : NSObject {
@@ -79,10 +79,13 @@ class DocumentLoader;
} _flags;
}
+#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
- (id)init;
- (id)initWithDOMRange:(DOMRange *)domRange;
- (NSAttributedString *)attributedString;
+#endif
++ (NSAttributedString *)editingAttributedStringFromRange:(WebCore::Range*)range;
@end
diff --git a/Source/WebCore/platform/mac/HTMLConverter.mm b/Source/WebCore/platform/mac/HTMLConverter.mm
index a4864c2..c0b0ba2 100644
--- a/Source/WebCore/platform/mac/HTMLConverter.mm
+++ b/Source/WebCore/platform/mac/HTMLConverter.mm
@@ -27,26 +27,35 @@
#import "HTMLConverter.h"
#import "ArchiveResource.h"
+#import "ColorMac.h"
#import "Document.h"
#import "DocumentLoader.h"
#import "DOMDocumentInternal.h"
#import "DOMElementInternal.h"
#import "DOMHTMLTableCellElement.h"
#import "DOMPrivate.h"
+#import "DOMRangeInternal.h"
#import "Element.h"
#import "Frame.h"
#import "HTMLNames.h"
#import "HTMLParserIdioms.h"
+#import "LoaderNSURLExtras.h"
+#import "RenderImage.h"
+#import "TextIterator.h"
#import <wtf/ASCIICType.h>
using namespace WebCore;
using namespace HTMLNames;
+static NSFileWrapper *fileWrapperForURL(DocumentLoader *, NSURL *);
+static NSFileWrapper *fileWrapperForElement(Element*);
+
#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+
// Additional control Unicode characters
const unichar WebNextLineCharacter = 0x0085;
-@interface NSTextList (TextListPrivate)
+@interface NSTextList (WebCoreNSTextListDetails)
+ (NSDictionary *)_standardMarkerAttributesForAttributes:(NSDictionary *)attrs;
@end
@@ -55,14 +64,12 @@ const unichar WebNextLineCharacter = 0x0085;
- (BOOL)ignoresOrientation;
@end
-@interface NSURL (WebDataURL)
-+ (NSURL *)_web_uniqueWebDataURL;
-+ (NSURL *)_web_uniqueWebDataURLWithRelativeString:(NSString *)string;
+@interface NSURL (WebCoreNSURLDetails)
+// FIXME: What is the reason to use this Foundation method, and not +[NSURL URLWithString:relativeToURL:]?
+ (NSURL *)_web_URLWithString:(NSString *)string relativeToURL:(NSURL *)baseURL;
-- (NSString *)_web_suggestedFilenameWithMIMEType:(NSString *)MIMEType;
@end
-@interface WebHTMLConverter(WebHTMLConverterPrivate)
+@interface WebHTMLConverter(WebHTMLConverterInternal)
- (NSString *)_stringForNode:(DOMNode *)node property:(NSString *)key;
- (NSColor *)_colorForNode:(DOMNode *)node property:(NSString *)key;
@@ -89,8 +96,12 @@ static NSFont *WebDefaultFont()
return defaultFont;
}
+#endif
+
@implementation WebHTMLConverter
+#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+
static NSFont *_fontForNameAndSize(NSString *fontName, CGFloat size, NSMutableDictionary *cache)
{
NSFontManager *fontManager = [NSFontManager sharedFontManager];
@@ -769,39 +780,6 @@ static inline NSShadow *_shadowForShadowStyle(NSString *shadowStyle)
[string release];
_flags.isSoft = YES;
}
-
-static NSFileWrapper *fileWrapperForURL(DocumentLoader *dataSource, NSURL *URL)
-{
- if ([URL isFileURL]) {
- NSString *path = [[URL path] stringByResolvingSymlinksInPath];
- return [[[NSFileWrapper alloc] initWithPath:path] autorelease];
- }
-
- RefPtr<ArchiveResource> resource = dataSource->subresource(URL);
- if (resource) {
- NSFileWrapper *wrapper = [[[NSFileWrapper alloc] initRegularFileWithContents:[resource->data()->createNSData() autorelease]] autorelease];
- NSString *filename = resource->response().suggestedFilename();
- if (!filename || ![filename length]) {
- NSURL *URL = resource->url();
- filename = [URL _web_suggestedFilenameWithMIMEType:resource->mimeType()];
- }
- [wrapper setPreferredFilename:filename];
- return wrapper;
- }
-
- NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:URL];
-
- NSCachedURLResponse *cachedResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:request];
- [request release];
-
- if (cachedResponse) {
- NSFileWrapper *wrapper = [[[NSFileWrapper alloc] initRegularFileWithContents:[cachedResponse data]] autorelease];
- [wrapper setPreferredFilename:[[cachedResponse response] suggestedFilename]];
- return wrapper;
- }
-
- return nil;
-}
- (BOOL)_addAttachmentForElement:(DOMElement *)element URL:(NSURL *)url needsParagraph:(BOOL)needsParagraph usePlaceholder:(BOOL)flag
{
@@ -823,7 +801,7 @@ static NSFileWrapper *fileWrapperForURL(DocumentLoader *dataSource, NSURL *URL)
if (flag && resource && [@"text/html" isEqual:resource->mimeType()]) notFound = YES;
if (resource && !notFound) {
fileWrapper = [[[NSFileWrapper alloc] initRegularFileWithContents:[resource->data()->createNSData() autorelease]] autorelease];
- [fileWrapper setPreferredFilename:[url _web_suggestedFilenameWithMIMEType:resource->mimeType()]];
+ [fileWrapper setPreferredFilename:suggestedFilenameWithMIMEType(url, resource->mimeType())];
}
}
if (!fileWrapper && !notFound) {
@@ -1672,11 +1650,119 @@ static NSInteger _colCompare(id block1, id block2, void *)
return self;
}
+// This function supports more HTML features than the editing variant below, such as tables.
- (NSAttributedString *)attributedString
{
[self _loadFromDOMRange];
return (0 == _errorCode) ? [[_attrStr retain] autorelease] : nil;
}
+#endif // !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+
+// This function uses TextIterator, which makes offsets in its result compatible with HTML editing.
++ (NSAttributedString *)editingAttributedStringFromRange:(Range*)range
+{
+ NSMutableAttributedString *string = [[NSMutableAttributedString alloc] init];
+ NSUInteger stringLength = 0;
+ RetainPtr<NSMutableDictionary> attrs(AdoptNS, [[NSMutableDictionary alloc] init]);
+
+ for (TextIterator it(range); !it.atEnd(); it.advance()) {
+ RefPtr<Range> currentTextRange = it.range();
+ ExceptionCode ec = 0;
+ Node* startContainer = currentTextRange->startContainer(ec);
+ Node* endContainer = currentTextRange->endContainer(ec);
+ int startOffset = currentTextRange->startOffset(ec);
+ int endOffset = currentTextRange->endOffset(ec);
+
+ if (startContainer == endContainer && (startOffset == endOffset - 1)) {
+ Node* node = startContainer->childNode(startOffset);
+ if (node && node->hasTagName(imgTag)) {
+ NSFileWrapper *fileWrapper = fileWrapperForElement(static_cast<Element*>(node));
+ NSTextAttachment *attachment = [[NSTextAttachment alloc] initWithFileWrapper:fileWrapper];
+ [string appendAttributedString:[NSAttributedString attributedStringWithAttachment:attachment]];
+ [attachment release];
+ }
+ }
+
+ int currentTextLength = it.length();
+ if (!currentTextLength)
+ continue;
+
+ RenderObject* renderer = startContainer->renderer();
+ ASSERT(renderer);
+ if (!renderer)
+ continue;
+ RenderStyle* style = renderer->style();
+ NSFont *font = style->font().primaryFont()->getNSFont();
+ [attrs.get() setObject:font forKey:NSFontAttributeName];
+ if (style->visitedDependentColor(CSSPropertyColor).alpha())
+ [attrs.get() setObject:nsColor(style->visitedDependentColor(CSSPropertyColor)) forKey:NSForegroundColorAttributeName];
+ else
+ [attrs.get() removeObjectForKey:NSForegroundColorAttributeName];
+ if (style->visitedDependentColor(CSSPropertyBackgroundColor).alpha())
+ [attrs.get() setObject:nsColor(style->visitedDependentColor(CSSPropertyBackgroundColor)) forKey:NSBackgroundColorAttributeName];
+ else
+ [attrs.get() removeObjectForKey:NSBackgroundColorAttributeName];
+
+ RetainPtr<NSString> substring(AdoptNS, [[NSString alloc] initWithCharactersNoCopy:const_cast<UChar*>(it.characters()) length:currentTextLength freeWhenDone:NO]);
+ [string replaceCharactersInRange:NSMakeRange(stringLength, 0) withString:substring.get()];
+ [string setAttributes:attrs.get() range:NSMakeRange(stringLength, currentTextLength)];
+ stringLength += currentTextLength;
+ }
+
+ return [string autorelease];
+}
+
@end
-#endif
+
+static NSFileWrapper *fileWrapperForURL(DocumentLoader *dataSource, NSURL *URL)
+{
+ if ([URL isFileURL]) {
+ NSString *path = [[URL path] stringByResolvingSymlinksInPath];
+ return [[[NSFileWrapper alloc] initWithPath:path] autorelease];
+ }
+
+ RefPtr<ArchiveResource> resource = dataSource->subresource(URL);
+ if (resource) {
+ NSFileWrapper *wrapper = [[[NSFileWrapper alloc] initRegularFileWithContents:[resource->data()->createNSData() autorelease]] autorelease];
+ NSString *filename = resource->response().suggestedFilename();
+ if (!filename || ![filename length])
+ filename = suggestedFilenameWithMIMEType(resource->url(), resource->mimeType());
+ [wrapper setPreferredFilename:filename];
+ return wrapper;
+ }
+
+ NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:URL];
+
+ NSCachedURLResponse *cachedResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:request];
+ [request release];
+
+ if (cachedResponse) {
+ NSFileWrapper *wrapper = [[[NSFileWrapper alloc] initRegularFileWithContents:[cachedResponse data]] autorelease];
+ [wrapper setPreferredFilename:[[cachedResponse response] suggestedFilename]];
+ return wrapper;
+ }
+
+ return nil;
+}
+
+static NSFileWrapper *fileWrapperForElement(Element* element)
+{
+ NSFileWrapper *wrapper = nil;
+
+ const AtomicString& attr = element->getAttribute(srcAttr);
+ if (!attr.isEmpty()) {
+ NSURL *URL = element->document()->completeURL(attr);
+ wrapper = fileWrapperForURL(element->document()->loader(), URL);
+ }
+ if (!wrapper) {
+ RenderImage* renderer = toRenderImage(element->renderer());
+ if (renderer->cachedImage() && !renderer->cachedImage()->errorOccurred()) {
+ wrapper = [[NSFileWrapper alloc] initRegularFileWithContents:(NSData *)(renderer->cachedImage()->image()->getTIFFRepresentation())];
+ [wrapper setPreferredFilename:@"image.tiff"];
+ [wrapper autorelease];
+ }
+ }
+
+ return wrapper;
+}
diff --git a/Source/WebCore/platform/mac/PasteboardMac.mm b/Source/WebCore/platform/mac/PasteboardMac.mm
index da06606..69782ab 100644
--- a/Source/WebCore/platform/mac/PasteboardMac.mm
+++ b/Source/WebCore/platform/mac/PasteboardMac.mm
@@ -38,9 +38,7 @@
#import "FrameLoaderClient.h"
#import "HitTestResult.h"
#import "HTMLAnchorElement.h"
-#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
#import "HTMLConverter.h"
-#endif
#import "htmlediting.h"
#import "HTMLNames.h"
#import "Image.h"
@@ -52,6 +50,7 @@
#import "RenderImage.h"
#import "Text.h"
#import "WebCoreNSStringExtras.h"
+#import "WebNSAttributedStringExtras.h"
#import "markup.h"
#import <wtf/StdLibExtras.h>
#import <wtf/RetainPtr.h>
@@ -129,19 +128,6 @@ void Pasteboard::clear()
[m_pasteboard.get() declareTypes:[NSArray array] owner:nil];
}
-static NSAttributedString *stripAttachmentCharacters(NSAttributedString *string)
-{
- const unichar attachmentCharacter = NSAttachmentCharacter;
- DEFINE_STATIC_LOCAL(RetainPtr<NSString>, attachmentCharacterString, ([NSString stringWithCharacters:&attachmentCharacter length:1]));
- NSMutableAttributedString *result = [[string mutableCopy] autorelease];
- NSRange attachmentRange = [[result string] rangeOfString:attachmentCharacterString.get()];
- while (attachmentRange.location != NSNotFound) {
- [result replaceCharactersInRange:attachmentRange withString:@""];
- attachmentRange = [[result string] rangeOfString:attachmentCharacterString.get()];
- }
- return result;
-}
-
void Pasteboard::writeSelection(NSPasteboard* pasteboard, NSArray* pasteboardTypes, Range* selectedRange, bool canSmartCopyOrDelete, Frame* frame)
{
if (!WebArchivePboardType)
@@ -207,7 +193,7 @@ void Pasteboard::writeSelection(NSPasteboard* pasteboard, NSArray* pasteboardTyp
}
if ([types containsObject:NSRTFPboardType]) {
if ([attributedString containsAttachments])
- attributedString = stripAttachmentCharacters(attributedString);
+ attributedString = attributedStringByStrippingAttachmentCharacters(attributedString);
NSData *RTFData = [attributedString RTFFromRange:NSMakeRange(0, [attributedString length]) documentAttributes:nil];
[pasteboard setData:RTFData forType:NSRTFPboardType];
}
diff --git a/Source/WebCore/platform/mac/ScrollAnimatorMac.h b/Source/WebCore/platform/mac/ScrollAnimatorMac.h
index f7b6332..382052e 100644
--- a/Source/WebCore/platform/mac/ScrollAnimatorMac.h
+++ b/Source/WebCore/platform/mac/ScrollAnimatorMac.h
@@ -106,6 +106,8 @@ private:
virtual void willEndLiveResize();
virtual void contentAreaDidShow() const;
virtual void contentAreaDidHide() const;
+ void didBeginScrollGesture() const;
+ void didEndScrollGesture() const;
virtual void didAddVerticalScrollbar(Scrollbar*);
virtual void willRemoveVerticalScrollbar(Scrollbar*);
diff --git a/Source/WebCore/platform/mac/ScrollAnimatorMac.mm b/Source/WebCore/platform/mac/ScrollAnimatorMac.mm
index 5725880..321ef0f 100644
--- a/Source/WebCore/platform/mac/ScrollAnimatorMac.mm
+++ b/Source/WebCore/platform/mac/ScrollAnimatorMac.mm
@@ -100,6 +100,11 @@ static NSSize abs(NSSize size)
_animator->immediateScrollToPoint(newPosition);
}
+- (NSPoint)_pixelAlignProposedScrollPosition:(NSPoint)newOrigin
+{
+ return newOrigin;
+}
+
- (NSSize)convertSizeToBase:(NSSize)size
{
return abs(size);
@@ -322,9 +327,9 @@ static NSSize abs(NSSize size)
// Invalidate the scrollbars so that they paint the animation
if (WebCore::Scrollbar* verticalScrollbar = _animator->scrollableArea()->verticalScrollbar())
- _animator->scrollableArea()->invalidateScrollbarRect(verticalScrollbar, WebCore::IntRect(0, 0, verticalScrollbar->width(), verticalScrollbar->height()));
+ verticalScrollbar->invalidateRect(WebCore::IntRect(0, 0, verticalScrollbar->width(), verticalScrollbar->height()));
if (WebCore::Scrollbar* horizontalScrollbar = _animator->scrollableArea()->horizontalScrollbar())
- _animator->scrollableArea()->invalidateScrollbarRect(horizontalScrollbar, WebCore::IntRect(0, 0, horizontalScrollbar->width(), horizontalScrollbar->height()));
+ horizontalScrollbar->invalidateRect(WebCore::IntRect(0, 0, horizontalScrollbar->width(), horizontalScrollbar->height()));
}
- (void)scrollAnimatorDestroyed
@@ -575,6 +580,9 @@ void ScrollAnimatorMac::immediateScrollToPoint(const FloatPoint& newPosition)
{
FloatPoint adjustedPosition = adjustScrollPositionIfNecessary(newPosition);
+ if (adjustedPosition.x() == m_currentPosX && adjustedPosition.y() == m_currentPosY)
+ return;
+
m_currentPosX = adjustedPosition.x();
m_currentPosY = adjustedPosition.y();
notityPositionChanged();
@@ -582,13 +590,23 @@ void ScrollAnimatorMac::immediateScrollToPoint(const FloatPoint& newPosition)
void ScrollAnimatorMac::immediateScrollByDeltaX(float deltaX)
{
- m_currentPosX = adjustScrollXPositionIfNecessary(m_currentPosX + deltaX);
+ float newPosX = adjustScrollXPositionIfNecessary(m_currentPosX + deltaX);
+
+ if (newPosX == m_currentPosX)
+ return;
+
+ m_currentPosX = newPosX;
notityPositionChanged();
}
void ScrollAnimatorMac::immediateScrollByDeltaY(float deltaY)
{
- m_currentPosY = adjustScrollYPositionIfNecessary(m_currentPosY + deltaY);
+ float newPosY = adjustScrollYPositionIfNecessary(m_currentPosY + deltaY);
+
+ if (newPosY == m_currentPosY)
+ return;
+
+ m_currentPosY = newPosY;
notityPositionChanged();
}
@@ -663,6 +681,20 @@ void ScrollAnimatorMac::contentAreaDidHide() const
#endif
}
+void ScrollAnimatorMac::didBeginScrollGesture() const
+{
+#if USE(WK_SCROLLBAR_PAINTER)
+ wkDidBeginScrollGesture(m_scrollbarPainterController.get());
+#endif
+}
+
+void ScrollAnimatorMac::didEndScrollGesture() const
+{
+#if USE(WK_SCROLLBAR_PAINTER)
+ wkDidEndScrollGesture(m_scrollbarPainterController.get());
+#endif
+}
+
void ScrollAnimatorMac::didAddVerticalScrollbar(Scrollbar* scrollbar)
{
#if USE(WK_SCROLLBAR_PAINTER)
@@ -771,6 +803,22 @@ void ScrollAnimatorMac::handleWheelEvent(PlatformWheelEvent& wheelEvent)
return;
}
+ // FIXME: This is somewhat roundabout hack to allow forwarding wheel events
+ // up to the parent scrollable area. It takes advantage of the fact that
+ // the base class implemenatation of handleWheelEvent will not accept the
+ // wheel event if there is nowhere to scroll.
+ if (fabsf(wheelEvent.deltaY()) >= fabsf(wheelEvent.deltaX())) {
+ if (!allowsVerticalStretching()) {
+ ScrollAnimator::handleWheelEvent(wheelEvent);
+ return;
+ }
+ } else {
+ if (!allowsHorizontalStretching()) {
+ ScrollAnimator::handleWheelEvent(wheelEvent);
+ return;
+ }
+ }
+
wheelEvent.accept();
bool isMometumScrollEvent = (wheelEvent.momentumPhase() != PlatformWheelEventPhaseNone);
@@ -819,21 +867,37 @@ bool ScrollAnimatorMac::pinnedInDirection(float deltaX, float deltaY)
bool ScrollAnimatorMac::allowsVerticalStretching() const
{
- Scrollbar* hScroller = m_scrollableArea->horizontalScrollbar();
- Scrollbar* vScroller = m_scrollableArea->verticalScrollbar();
- if (((vScroller && vScroller->enabled()) || (!hScroller || !hScroller->enabled())))
+ switch (m_scrollableArea->verticalScrollElasticity()) {
+ case ScrollElasticityAutomatic: {
+ Scrollbar* hScroller = m_scrollableArea->horizontalScrollbar();
+ Scrollbar* vScroller = m_scrollableArea->verticalScrollbar();
+ return (((vScroller && vScroller->enabled()) || (!hScroller || !hScroller->enabled())));
+ }
+ case ScrollElasticityNone:
+ return false;
+ case ScrollElasticityAllowed:
return true;
+ }
+ ASSERT_NOT_REACHED();
return false;
}
bool ScrollAnimatorMac::allowsHorizontalStretching() const
{
- Scrollbar* hScroller = m_scrollableArea->horizontalScrollbar();
- Scrollbar* vScroller = m_scrollableArea->verticalScrollbar();
- if (((hScroller && hScroller->enabled()) || (!vScroller || !vScroller->enabled())))
+ switch (m_scrollableArea->horizontalScrollElasticity()) {
+ case ScrollElasticityAutomatic: {
+ Scrollbar* hScroller = m_scrollableArea->horizontalScrollbar();
+ Scrollbar* vScroller = m_scrollableArea->verticalScrollbar();
+ return (((hScroller && hScroller->enabled()) || (!vScroller || !vScroller->enabled())));
+ }
+ case ScrollElasticityNone:
+ return false;
+ case ScrollElasticityAllowed:
return true;
+ }
+ ASSERT_NOT_REACHED();
return false;
}
@@ -858,7 +922,7 @@ void ScrollAnimatorMac::smoothScrollWithEvent(PlatformWheelEvent& wheelEvent)
deltaX = 0;
else
deltaY = 0;
-
+
bool isVerticallyStretched = false;
bool isHorizontallyStretched = false;
bool shouldStretch = false;
@@ -993,6 +1057,8 @@ void ScrollAnimatorMac::smoothScrollWithEvent(PlatformWheelEvent& wheelEvent)
void ScrollAnimatorMac::beginScrollGesture()
{
+ didBeginScrollGesture();
+
m_haveScrolledSincePageLoad = true;
m_inScrollGesture = true;
m_momentumScrollInProgress = false;
@@ -1012,6 +1078,8 @@ void ScrollAnimatorMac::beginScrollGesture()
void ScrollAnimatorMac::endScrollGesture()
{
+ didEndScrollGesture();
+
snapRubberBand();
}
diff --git a/Source/WebCore/platform/mac/WebCoreSystemInterface.h b/Source/WebCore/platform/mac/WebCoreSystemInterface.h
index 308a551..3c9850b 100644
--- a/Source/WebCore/platform/mac/WebCoreSystemInterface.h
+++ b/Source/WebCore/platform/mac/WebCoreSystemInterface.h
@@ -29,7 +29,7 @@
#include <ApplicationServices/ApplicationServices.h>
#include <objc/objc.h>
-#if PLATFORM(MAC) && PLATFORM(CA) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
+#if PLATFORM(MAC) && USE(CA) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
#include <IOSurface/IOSurface.h>
#endif
@@ -155,11 +155,12 @@ extern void (*wkSignalCFReadStreamError)(CFReadStreamRef stream, CFStreamError *
extern void (*wkSignalCFReadStreamHasBytes)(CFReadStreamRef stream);
extern unsigned (*wkInitializeMaximumHTTPConnectionCountPerHost)(unsigned preferredConnectionCount);
extern int (*wkGetHTTPPipeliningPriority)(NSURLRequest *);
+extern void (*wkSetHTTPPipeliningMaximumPriority)(int maximumPriority);
extern void (*wkSetHTTPPipeliningPriority)(NSMutableURLRequest *, int priority);
+extern void (*wkSetHTTPPipeliningMinimumFastLanePriority)(int priority);
extern void (*wkSetCONNECTProxyForStream)(CFReadStreamRef, CFStringRef proxyHost, CFNumberRef proxyPort);
extern void (*wkSetCONNECTProxyAuthorizationForStream)(CFReadStreamRef, CFStringRef proxyAuthorizationString);
extern CFHTTPMessageRef (*wkCopyCONNECTProxyResponse)(CFReadStreamRef, CFURLRef responseURL);
-extern BOOL (*wkIsLatchingWheelEvent)(NSEvent *);
#ifndef BUILDING_ON_TIGER
extern void (*wkGetGlyphsForCharacters)(CGFontRef, const UniChar[], CGGlyph[], size_t);
@@ -187,6 +188,15 @@ extern BOOL (*wkUseSharedMediaUI)();
extern void* wkGetHyphenationLocationBeforeIndex;
#else
extern CFIndex (*wkGetHyphenationLocationBeforeIndex)(CFStringRef string, CFIndex index);
+
+typedef enum {
+ wkEventPhaseNone = 0,
+ wkEventPhaseBegan = 1,
+ wkEventPhaseChanged = 2,
+ wkEventPhaseEnded = 3,
+} wkEventPhase;
+
+extern int (*wkGetNSEventMomentumPhase)(NSEvent *);
#endif
extern CTLineRef (*wkCreateCTLineWithUniCharProvider)(const UniChar* (*provide)(CFIndex stringIndex, CFIndex* charCount, CFDictionaryRef* attributes, void*), void (*dispose)(const UniChar* chars, void*), void*);
@@ -229,6 +239,8 @@ extern void (*wkContentAreaResized)(WKScrollbarPainterControllerRef);
extern void (*wkWillEndLiveResize)(WKScrollbarPainterControllerRef);
extern void (*wkContentAreaDidShow)(WKScrollbarPainterControllerRef);
extern void (*wkContentAreaDidHide)(WKScrollbarPainterControllerRef);
+extern void (*wkDidBeginScrollGesture)(WKScrollbarPainterControllerRef);
+extern void (*wkDidEndScrollGesture)(WKScrollbarPainterControllerRef);
extern bool (*wkScrollbarPainterUsesOverlayScrollers)(void);
#endif
diff --git a/Source/WebCore/platform/mac/WebCoreSystemInterface.mm b/Source/WebCore/platform/mac/WebCoreSystemInterface.mm
index ab059bd..6a78ff6 100644
--- a/Source/WebCore/platform/mac/WebCoreSystemInterface.mm
+++ b/Source/WebCore/platform/mac/WebCoreSystemInterface.mm
@@ -91,11 +91,12 @@ void (*wkSetNSURLRequestShouldContentSniff)(NSMutableURLRequest *, BOOL);
id (*wkCreateNSURLConnectionDelegateProxy)(void);
unsigned (*wkInitializeMaximumHTTPConnectionCountPerHost)(unsigned preferredConnectionCount);
int (*wkGetHTTPPipeliningPriority)(NSURLRequest *);
+void (*wkSetHTTPPipeliningMaximumPriority)(int priority);
void (*wkSetHTTPPipeliningPriority)(NSMutableURLRequest *, int priority);
+void (*wkSetHTTPPipeliningMinimumFastLanePriority)(int priority);
void (*wkSetCONNECTProxyForStream)(CFReadStreamRef, CFStringRef proxyHost, CFNumberRef proxyPort);
void (*wkSetCONNECTProxyAuthorizationForStream)(CFReadStreamRef, CFStringRef proxyAuthorizationString);
CFHTTPMessageRef (*wkCopyCONNECTProxyResponse)(CFReadStreamRef, CFURLRef responseURL);
-BOOL (*wkIsLatchingWheelEvent)(NSEvent *);
#ifndef BUILDING_ON_TIGER
void (*wkGetGlyphsForCharacters)(CGFontRef, const UniChar[], CGGlyph[], size_t);
@@ -120,6 +121,7 @@ BOOL (*wkSupportsMultipartXMixedReplace)(NSMutableURLRequest *);
void* wkGetHyphenationLocationBeforeIndex;
#else
CFIndex (*wkGetHyphenationLocationBeforeIndex)(CFStringRef string, CFIndex index);
+int (*wkGetNSEventMomentumPhase)(NSEvent *);
#endif
CTLineRef (*wkCreateCTLineWithUniCharProvider)(const UniChar* (*provide)(CFIndex stringIndex, CFIndex* charCount, CFDictionaryRef* attributes, void*), void (*dispose)(const UniChar* chars, void*), void*);
@@ -159,6 +161,8 @@ void (*wkContentAreaResized)(WKScrollbarPainterControllerRef);
void (*wkWillEndLiveResize)(WKScrollbarPainterControllerRef);
void (*wkContentAreaDidShow)(WKScrollbarPainterControllerRef);
void (*wkContentAreaDidHide)(WKScrollbarPainterControllerRef);
+void (*wkDidBeginScrollGesture)(WKScrollbarPainterControllerRef);
+void (*wkDidEndScrollGesture)(WKScrollbarPainterControllerRef);
bool (*wkScrollbarPainterUsesOverlayScrollers)(void);
#endif
diff --git a/Source/WebCore/platform/mac/WebNSAttributedStringExtras.h b/Source/WebCore/platform/mac/WebNSAttributedStringExtras.h
new file mode 100644
index 0000000..ce4cfe4
--- /dev/null
+++ b/Source/WebCore/platform/mac/WebNSAttributedStringExtras.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2005, 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.
+ */
+
+namespace WebCore {
+
+NSAttributedString *attributedStringByStrippingAttachmentCharacters(NSAttributedString *);
+
+}
diff --git a/Source/WebCore/platform/mac/WebNSAttributedStringExtras.mm b/Source/WebCore/platform/mac/WebNSAttributedStringExtras.mm
new file mode 100644
index 0000000..f64e24d
--- /dev/null
+++ b/Source/WebCore/platform/mac/WebNSAttributedStringExtras.mm
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2005, 2007, 2008, 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.
+ */
+
+#import "WebNSAttributedStringExtras.h"
+
+namespace WebCore {
+
+NSAttributedString *attributedStringByStrippingAttachmentCharacters(NSAttributedString *attributedString)
+{
+ NSRange attachmentRange;
+ NSString *originalString = [attributedString string];
+ static NSString *attachmentCharString = nil;
+
+ if (!attachmentCharString) {
+ unichar chars[2];
+ if (!attachmentCharString) {
+ chars[0] = NSAttachmentCharacter;
+ chars[1] = 0;
+ attachmentCharString = [[NSString alloc] initWithCharacters:chars length:1];
+ }
+ }
+
+ attachmentRange = [originalString rangeOfString:attachmentCharString];
+ if (attachmentRange.location != NSNotFound && attachmentRange.length > 0) {
+ NSMutableAttributedString *newAttributedString = [[attributedString mutableCopyWithZone:NULL] autorelease];
+
+ while (attachmentRange.location != NSNotFound && attachmentRange.length > 0) {
+ [newAttributedString replaceCharactersInRange:attachmentRange withString:@""];
+ attachmentRange = [[newAttributedString string] rangeOfString:attachmentCharString];
+ }
+ return newAttributedString;
+ }
+
+ return attributedString;
+}
+
+}
diff --git a/Source/WebCore/platform/mac/WheelEventMac.mm b/Source/WebCore/platform/mac/WheelEventMac.mm
index 4e9a8b7..2494e69 100644
--- a/Source/WebCore/platform/mac/WheelEventMac.mm
+++ b/Source/WebCore/platform/mac/WheelEventMac.mm
@@ -35,8 +35,9 @@ namespace WebCore {
static PlatformWheelEventPhase momentumPhaseForEvent(NSEvent *event)
{
+ uint32_t phase = PlatformWheelEventPhaseNone;
+
#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
- uint32_t phase = PlatformWheelEventPhaseNone;
if ([event momentumPhase] & NSEventPhaseBegan)
phase |= PlatformWheelEventPhaseBegan;
if ([event momentumPhase] & NSEventPhaseStationary)
@@ -47,11 +48,24 @@ static PlatformWheelEventPhase momentumPhaseForEvent(NSEvent *event)
phase |= PlatformWheelEventPhaseEnded;
if ([event momentumPhase] & NSEventPhaseCancelled)
phase |= PlatformWheelEventPhaseCancelled;
- return static_cast<PlatformWheelEventPhase>(phase);
#else
- UNUSED_PARAM(event);
- return PlatformWheelEventPhaseNone;
+ switch (wkGetNSEventMomentumPhase(event)) {
+ case wkEventPhaseNone:
+ phase = PlatformWheelEventPhaseNone;
+ break;
+ case wkEventPhaseBegan:
+ phase = PlatformWheelEventPhaseBegan;
+ break;
+ case wkEventPhaseChanged:
+ phase = PlatformWheelEventPhaseChanged;
+ break;
+ case wkEventPhaseEnded:
+ phase = PlatformWheelEventPhaseEnded;
+ break;
+ }
#endif
+
+ return static_cast<PlatformWheelEventPhase>(phase);
}
static PlatformWheelEventPhase phaseForEvent(NSEvent *event)
diff --git a/Source/WebCore/platform/network/BlobResourceHandle.cpp b/Source/WebCore/platform/network/BlobResourceHandle.cpp
index 24c9088..d4cf452 100644
--- a/Source/WebCore/platform/network/BlobResourceHandle.cpp
+++ b/Source/WebCore/platform/network/BlobResourceHandle.cpp
@@ -79,7 +79,7 @@ public:
BlobResourceSynchronousLoader(ResourceError&, ResourceResponse&, Vector<char>&);
virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&);
- virtual void didReceiveData(ResourceHandle*, const char*, int, int /*lengthReceived*/);
+ virtual void didReceiveData(ResourceHandle*, const char*, int, int /*encodedDataLength*/);
virtual void didFinishLoading(ResourceHandle*, double /*finishTime*/);
virtual void didFail(ResourceHandle*, const ResourceError&);
diff --git a/Source/WebCore/platform/network/MIMESniffing.cpp b/Source/WebCore/platform/network/MIMESniffing.cpp
new file mode 100644
index 0000000..f9868c1
--- /dev/null
+++ b/Source/WebCore/platform/network/MIMESniffing.cpp
@@ -0,0 +1,495 @@
+/*
+ Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+#include "MIMESniffing.h"
+
+#include <cstring>
+#include <stdint.h>
+
+// MIME type sniffing implementation based on http://tools.ietf.org/html/draft-abarth-mime-sniff-06
+
+namespace {
+
+static inline bool isTextInList(const char* text, size_t size, const char** data)
+{
+ for (size_t i = 0; i < size; ++i) {
+ if (!strcmp(text, data[i]))
+ return true;
+ }
+ return false;
+
+}
+
+// http://tools.ietf.org/html/draft-abarth-mime-sniff-06#page-6
+const char* textTypes[] = {
+ "text/plain",
+ "text/plain; charset=ISO-8859-1",
+ "text/plain; charset=iso-8859-1",
+ "text/plain; charset=UTF-8"
+};
+const size_t textTypesSize = sizeof(textTypes) / sizeof(textTypes[0]);
+
+static inline bool isTextOrBinaryType(const char* type)
+{
+ return isTextInList(type, textTypesSize, textTypes);
+}
+
+// http://tools.ietf.org/html/draft-abarth-mime-sniff-06#page-6
+const char* unknownTypes[] = {
+ "",
+ "unknown/unknown",
+ "application/unknown",
+ "*/*"
+};
+const size_t unknownTypesSize = sizeof(unknownTypes) / sizeof(unknownTypes[0]);
+
+static inline bool isUnknownType(const char* type)
+{
+ return isTextInList(type, unknownTypesSize, unknownTypes);
+}
+
+const char* xmlTypes[] = {
+ "text/xml",
+ "application/xml"
+};
+const size_t xmlTypesSize = sizeof(xmlTypes) / sizeof(xmlTypes[0]);
+
+const char xmlSuffix[] = "+xml";
+
+static inline bool isXMLType(const char* type)
+{
+ const size_t xmlSuffixSize = sizeof(xmlSuffix) - 1;
+ size_t typeSize = strlen(type);
+ if (typeSize >= xmlSuffixSize && !memcmp(type + typeSize - xmlSuffixSize, xmlSuffix, xmlSuffixSize))
+ return true;
+
+ return isTextInList(type, xmlTypesSize, xmlTypes);
+}
+
+// http://tools.ietf.org/html/draft-abarth-mime-sniff-06#page-8
+const char binaryFlags[256] = {
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static inline bool isBinaryChar(unsigned char data)
+{
+ return binaryFlags[data];
+}
+
+static inline bool isBinaryData(const char* data, size_t size)
+{
+ for (size_t i = 0; i < size; ++i) {
+ if (isBinaryChar(data[i]))
+ return true;
+ }
+ return false;
+}
+
+// http://tools.ietf.org/html/draft-abarth-mime-sniff-06#page-11
+const char whiteSpaceChars[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static inline bool isWhiteSpace(unsigned char data)
+{
+ return whiteSpaceChars[data];
+}
+
+static inline void skipWhiteSpace(const char* data, size_t& pos, size_t dataSize)
+{
+ while (pos < dataSize && isWhiteSpace(data[pos]))
+ ++pos;
+}
+
+enum {
+ SkipWhiteSpace = 1,
+ TrailingSpaceOrBracket = 2
+};
+
+struct MagicNumbers {
+ const char* pattern;
+ const char* mask;
+ const char* mimeType;
+ size_t size;
+ int flags;
+};
+
+#define MAGIC_NUMBERS_MASKED(pattern, mask, mimeType, flags) {(pattern), (mask), (mimeType), sizeof(pattern) - 1, (flags)}
+#define MAGIC_NUMBERS_SIMPLE(pattern, mimeType) {(pattern), 0, (mimeType), sizeof(pattern) - 1, 0}
+
+// http://tools.ietf.org/html/draft-abarth-mime-sniff-06#page-12
+const MagicNumbers securityConstrainedTypes[] = {
+ MAGIC_NUMBERS_MASKED("<!DOCTYPE HTML", "\xFF\xFF\xDF\xDF\xDF\xDF\xDF\xDF\xDF\xFF\xDF\xDF\xDF\xDF", "text/html", SkipWhiteSpace | TrailingSpaceOrBracket),
+ MAGIC_NUMBERS_MASKED("<HTML", "\xFF\xDF\xDF\xDF\xDF", "text/html", SkipWhiteSpace | TrailingSpaceOrBracket),
+ MAGIC_NUMBERS_MASKED("<HEAD", "\xFF\xDF\xDF\xDF\xDF", "text/html", SkipWhiteSpace | TrailingSpaceOrBracket),
+ MAGIC_NUMBERS_MASKED("<SCRIPT", "\xFF\xDF\xDF\xDF\xDF\xDF\xDF", "text/html", SkipWhiteSpace | TrailingSpaceOrBracket),
+ MAGIC_NUMBERS_MASKED("<IFRAME", "\xFF\xDF\xDF\xDF\xDF\xDF\xDF", "text/html", SkipWhiteSpace | TrailingSpaceOrBracket),
+ MAGIC_NUMBERS_MASKED("<H1", "\xFF\xDF\xFF", "text/html", SkipWhiteSpace | TrailingSpaceOrBracket),
+ MAGIC_NUMBERS_MASKED("<DIV", "\xFF\xDF\xDF\xDF", "text/html", SkipWhiteSpace | TrailingSpaceOrBracket),
+ MAGIC_NUMBERS_MASKED("<FONT", "\xFF\xDF\xDF\xDF\xDF", "text/html", SkipWhiteSpace | TrailingSpaceOrBracket),
+ MAGIC_NUMBERS_MASKED("<TABLE", "\xFF\xDF\xDF\xDF\xDF\xDF", "text/html", SkipWhiteSpace | TrailingSpaceOrBracket),
+ MAGIC_NUMBERS_MASKED("<A", "\xFF\xDF", "text/html", SkipWhiteSpace | TrailingSpaceOrBracket),
+ MAGIC_NUMBERS_MASKED("<STYLE", "\xFF\xDF\xDF\xDF\xDF\xDF", "text/html", SkipWhiteSpace | TrailingSpaceOrBracket),
+ MAGIC_NUMBERS_MASKED("<TITLE", "\xFF\xDF\xDF\xDF\xDF\xDF", "text/html", SkipWhiteSpace | TrailingSpaceOrBracket),
+ MAGIC_NUMBERS_MASKED("<B", "\xFF\xDF", "text/html", SkipWhiteSpace | TrailingSpaceOrBracket),
+ MAGIC_NUMBERS_MASKED("<BODY", "\xFF\xDF\xDF\xDF\xDF", "text/html", SkipWhiteSpace | TrailingSpaceOrBracket),
+ MAGIC_NUMBERS_MASKED("<BR", "\xFF\xDF\xDF", "text/html", SkipWhiteSpace | TrailingSpaceOrBracket),
+ MAGIC_NUMBERS_MASKED("<P", "\xFF\xDF", "text/html", SkipWhiteSpace | TrailingSpaceOrBracket),
+ MAGIC_NUMBERS_MASKED("<!--", 0, "text/html", SkipWhiteSpace | TrailingSpaceOrBracket),
+ MAGIC_NUMBERS_MASKED("<?xml", 0, "text/xml", SkipWhiteSpace),
+ MAGIC_NUMBERS_SIMPLE("%PDF-", "application/pdf")
+};
+const size_t securityConstrainedTypesSize = sizeof(securityConstrainedTypes) / sizeof(securityConstrainedTypes[0]);
+
+// http://tools.ietf.org/html/draft-abarth-mime-sniff-06#page-8
+const MagicNumbers bomTypes[] = {
+ MAGIC_NUMBERS_SIMPLE("\xFE\xFF", "text/plain"), // UTF-16BE BOM
+ MAGIC_NUMBERS_SIMPLE("\xFF\xFE", "text/plain"), // UTF-16LE BOM
+ MAGIC_NUMBERS_SIMPLE("\xEF\xBB\xBF", "text/plain") // UTF-8 BOM
+};
+const size_t bomTypesSize = sizeof(bomTypes) / sizeof(bomTypes[0]);
+
+// http://tools.ietf.org/html/draft-abarth-mime-sniff-06#page-13
+const MagicNumbers safeTypes[] = {
+ MAGIC_NUMBERS_SIMPLE("%!PS-Adobe-", "application/postscript"),
+ MAGIC_NUMBERS_SIMPLE("\x4F\x67\x67\x53\x00", "application/ogg"), // An Ogg Vorbis audio or video signature.
+ MAGIC_NUMBERS_MASKED("RIFF\x00\x00\x00\x00WAVE", "\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF", "audio/x-wave", 0), // "RIFF" followed by four bytes, followed by "WAVE".
+ MAGIC_NUMBERS_SIMPLE("\x1A\x45\xDF\xA3", "video/webm"), // The WebM signature.
+ MAGIC_NUMBERS_SIMPLE("Rar!\x1A\x07\x00", "application/x-rar-compressed"), // A RAR archive.
+ MAGIC_NUMBERS_SIMPLE("\x50\x4B\x03\x04", "application/zip"), // A ZIP archive.
+ MAGIC_NUMBERS_SIMPLE("\x1F\x8B\x08", "application/x-gzip") // A GZIP archive.
+};
+const size_t safeTypesSize = sizeof(safeTypes) / sizeof(safeTypes[0]);
+
+// http://tools.ietf.org/html/draft-abarth-mime-sniff-06#page-16
+const MagicNumbers imageTypes[] = {
+ MAGIC_NUMBERS_MASKED("RIFF\x00\x00\x00\x00WEBPVP", "\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF", "image/webp", 0), // "RIFF" followed by four bytes, followed by "WEBPVP".
+ MAGIC_NUMBERS_SIMPLE("GIF87a", "image/gif"),
+ MAGIC_NUMBERS_SIMPLE("GIF89a", "image/gif"),
+ MAGIC_NUMBERS_SIMPLE("\x89\x50\x4E\x47\x0D\x0A\x1A\x0A", "image/png"),
+ MAGIC_NUMBERS_SIMPLE("\xFF\xD8\xFF", "image/jpeg"),
+ MAGIC_NUMBERS_SIMPLE("BM", "image/bmp"),
+ MAGIC_NUMBERS_SIMPLE("\x00\x00\x01\x00", "image/vnd.microsoft.icon") // A Windows Icon signature.
+};
+const size_t imageTypesSize = sizeof(imageTypes) / sizeof(imageTypes[0]);
+
+static inline size_t dataSizeNeededForImageSniffing()
+{
+ size_t result = 0;
+ for (int i = 0; i < imageTypesSize; ++i) {
+ if (imageTypes[i].size > result)
+ result = imageTypes[i].size;
+ }
+ return result;
+}
+
+static inline bool maskedCompare(const MagicNumbers& info, const char* data, size_t dataSize)
+{
+ if (dataSize < info.size)
+ return false;
+
+ const uint32_t* pattern32 = reinterpret_cast<const uint32_t*>(info.pattern);
+ const uint32_t* mask32 = reinterpret_cast<const uint32_t*>(info.mask);
+ const uint32_t* data32 = reinterpret_cast<const uint32_t*>(data);
+
+ size_t count = info.size >> 2;
+
+ for (size_t i = 0; i < count; ++i) {
+ if ((*data32++ & *mask32++) != *pattern32++)
+ return false;
+ }
+
+ const char* p = reinterpret_cast<const char*>(pattern32);
+ const char* m = reinterpret_cast<const char*>(mask32);
+ const char* d = reinterpret_cast<const char*>(data32);
+
+ count = info.size & 3;
+
+ for (size_t i = 0; i < count; ++i) {
+ if ((*d++ & *m++) != *p++)
+ return false;
+ }
+
+ return true;
+}
+
+// http://tools.ietf.org/html/draft-abarth-mime-sniff-06#page-11
+static inline bool checkSpaceOrBracket(const char* data)
+{
+ return isWhiteSpace(*data) || *data == 0x3E;
+}
+
+static inline bool compare(const MagicNumbers& info, const char* data, size_t dataSize)
+{
+ if (info.flags & SkipWhiteSpace) {
+ size_t pos = 0;
+ skipWhiteSpace(data, pos, dataSize);
+ data += pos;
+ dataSize -= pos;
+ }
+
+ bool result;
+ if (info.mask)
+ result = maskedCompare(info, data, info.size);
+ else
+ result = dataSize >= info.size && !memcmp(data, info.pattern, info.size);
+
+ return result && (!(info.flags & TrailingSpaceOrBracket) || checkSpaceOrBracket(data + info.size));
+}
+
+static inline const char* findMIMEType(const char* data, size_t dataSize, const MagicNumbers* types, size_t typesCount)
+{
+ for (size_t i = 0; i < typesCount; ++i) {
+ if (compare(types[i], data, dataSize))
+ return types[i].mimeType;
+ }
+ return 0;
+}
+
+static inline const char* findSimpleMIMEType(const char* data, size_t dataSize, const MagicNumbers* types, size_t typesCount)
+{
+ for (size_t i = 0; i < typesCount; ++i) {
+ ASSERT(!types[i].mask);
+ ASSERT(!types[i].flags);
+
+ if (dataSize >= types[i].size && !memcmp(data, types[i].pattern, types[i].size))
+ return types[i].mimeType;
+ }
+ return 0;
+}
+
+bool isTypeInList(const char* type, const MagicNumbers* types, size_t typesCount)
+{
+ for (size_t i = 0; i < typesCount; ++i) {
+ if (!strcmp(type, types[i].mimeType))
+ return true;
+ }
+ return false;
+}
+
+// http://tools.ietf.org/html/draft-abarth-mime-sniff-06#page-8
+static const char* internalTextOrBinaryTypeSniffingProcedure(const char* data, size_t dataSize)
+{
+ const char* mimeType = 0;
+
+ mimeType = findSimpleMIMEType(data, dataSize, bomTypes, bomTypesSize);
+ if (mimeType)
+ return mimeType;
+
+ if (!isBinaryData(data, dataSize))
+ return "text/plain";
+
+ mimeType = findMIMEType(data, dataSize, safeTypes, safeTypesSize);
+ if (mimeType)
+ return mimeType;
+
+ mimeType = findMIMEType(data, dataSize, imageTypes, imageTypesSize);
+ if (mimeType)
+ return mimeType;
+
+ return "application/octet-stream";
+}
+
+static const char* textOrBinaryTypeSniffingProcedure(const char* data, size_t dataSize)
+{
+ const char* result = internalTextOrBinaryTypeSniffingProcedure(data, dataSize);
+ ASSERT(!isTypeInList(result, securityConstrainedTypes, securityConstrainedTypesSize));
+ return result;
+}
+
+// http://tools.ietf.org/html/draft-abarth-mime-sniff-06#page-10
+static const char* unknownTypeSniffingProcedure(const char* data, size_t dataSize)
+{
+ const char* mimeType = 0;
+
+ mimeType = findMIMEType(data, dataSize, securityConstrainedTypes, securityConstrainedTypesSize);
+ if (mimeType)
+ return mimeType;
+
+ mimeType = findSimpleMIMEType(data, dataSize, bomTypes, bomTypesSize);
+ if (mimeType)
+ return mimeType;
+
+ mimeType = findMIMEType(data, dataSize, safeTypes, safeTypesSize);
+ if (mimeType)
+ return mimeType;
+
+ mimeType = findMIMEType(data, dataSize, imageTypes, imageTypesSize);
+ if (mimeType)
+ return mimeType;
+
+ if (!isBinaryData(data, dataSize))
+ return "text/plain";
+
+ return "application/octet-stream";
+}
+
+// http://tools.ietf.org/html/draft-abarth-mime-sniff-06#page-16
+static const char* imageTypeSniffingProcedure(const char* data, size_t dataSize)
+{
+ return findMIMEType(data, dataSize, imageTypes, imageTypesSize);
+}
+
+static inline bool checkText(const char* data, size_t& pos, size_t dataSize, const char* text, size_t textSize)
+{
+ if (dataSize - pos < textSize || memcmp(data + pos, text, textSize))
+ return false;
+
+ pos += textSize;
+ return true;
+}
+
+const char rssUrl[] = "http://purl.org/rss/1.0";
+const char rdfUrl[] = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+
+static inline const char* checkRDF(const char* data, size_t pos, size_t dataSize)
+{
+ bool isRDF = false;
+ bool isRSS = false;
+
+ while (pos <= dataSize) {
+ if (checkText(data, pos, dataSize, rssUrl, sizeof(rssUrl) - 1)) {
+ isRSS = true;
+ continue;
+ }
+
+ if (checkText(data, pos, dataSize, rdfUrl, sizeof(rdfUrl) - 1)) {
+ isRDF = true;
+ continue;
+ }
+
+ ++pos;
+
+ if (isRSS && isRDF)
+ return "application/rdf+xml";
+ }
+
+ return 0;
+}
+
+static inline bool skipTag(const char*& data, size_t& pos, size_t dataSize, const char* tag, size_t tagSize, const char* tagEnd, size_t tagEndSize)
+{
+ if (!checkText(data, pos, dataSize, tag, tagSize))
+ return false;
+
+ while (pos < dataSize && !checkText(data, pos, dataSize, tagEnd, tagEndSize))
+ ++pos;
+
+ return true;
+}
+
+// http://tools.ietf.org/html/draft-abarth-mime-sniff-06#page-17
+static const char* feedTypeSniffingProcedure(const char* data, size_t dataSize)
+{
+ size_t pos = 0;
+
+ if (dataSize >= 3 && !memcmp(data, "\xEF\xBB\xBF", 3))
+ pos += 3;
+
+ while (pos < dataSize) {
+ skipWhiteSpace(data, pos, dataSize);
+
+ if (!skipTag(data, pos, dataSize, "<!--", 4, "-->", 3) && !skipTag(data, pos, dataSize, "<!", 2, "!>", 2) && !skipTag(data, pos, dataSize, "<?", 2, "?>", 2))
+ break;
+ }
+
+ if (checkText(data, pos, dataSize, "<rss", 4))
+ return "application/rss+xml";
+
+ if (checkText(data, pos, dataSize, "<feed", 5))
+ return "application/atom+xml";
+
+ if (checkText(data, pos, dataSize, "<rdf:RDF", 8))
+ return checkRDF(data, pos, dataSize);
+
+ return 0;
+}
+
+}
+
+// http://tools.ietf.org/html/draft-abarth-mime-sniff-06#page-6
+MIMESniffer::MIMESniffer(const char* advertisedMIMEType, bool isSupportedImageType)
+ : m_dataSize(0)
+ , m_function(0)
+{
+ if (!advertisedMIMEType) {
+ m_dataSize = 512;
+ m_function = &unknownTypeSniffingProcedure;
+ return;
+ }
+
+ if (isTextOrBinaryType(advertisedMIMEType)) {
+ m_dataSize = 512;
+ m_function = &textOrBinaryTypeSniffingProcedure;
+ return;
+ }
+
+ if (isUnknownType(advertisedMIMEType)) {
+ m_dataSize = 512;
+ m_function = &unknownTypeSniffingProcedure;
+ return;
+ }
+
+ if (isXMLType(advertisedMIMEType))
+ return;
+
+ if (isSupportedImageType) {
+ static const size_t dataSize = dataSizeNeededForImageSniffing();
+ m_dataSize = dataSize;
+ m_function = &imageTypeSniffingProcedure;
+ return;
+ }
+
+ if (!strcmp(advertisedMIMEType, "text/html")) {
+ m_dataSize = 512;
+ m_function = &feedTypeSniffingProcedure;
+ return;
+ }
+}
diff --git a/Source/WebCore/platform/network/MIMESniffing.h b/Source/WebCore/platform/network/MIMESniffing.h
new file mode 100644
index 0000000..cd1c52b
--- /dev/null
+++ b/Source/WebCore/platform/network/MIMESniffing.h
@@ -0,0 +1,41 @@
+/*
+ Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef MIMESniffing_h
+#define MIMESniffing_h
+
+#include <stddef.h>
+
+// MIME type sniffing implementation based on http://tools.ietf.org/html/draft-abarth-mime-sniff-06
+
+class MIMESniffer {
+public:
+ MIMESniffer(const char* advertisedMIMEType, bool isSupportedImageType);
+
+ size_t dataSize() const { return m_dataSize; }
+ const char* sniff(const char* data, size_t size) const { return m_function ? m_function(data, size) : 0; }
+ bool isValid() const { return m_dataSize > 0; }
+
+private:
+ typedef const char* (*SniffFunction)(const char*, size_t);
+ size_t m_dataSize;
+ SniffFunction m_function;
+};
+
+#endif // MIMESniffing_h
diff --git a/Source/WebCore/platform/network/NetworkingContext.h b/Source/WebCore/platform/network/NetworkingContext.h
index e8a3776..134394e 100644
--- a/Source/WebCore/platform/network/NetworkingContext.h
+++ b/Source/WebCore/platform/network/NetworkingContext.h
@@ -58,6 +58,7 @@ public:
#if PLATFORM(QT)
virtual QObject* originatingObject() const = 0;
virtual QNetworkAccessManager* networkAccessManager() const = 0;
+ virtual bool mimeSniffingEnabled() const = 0;
#endif
#if PLATFORM(WIN)
diff --git a/Source/WebCore/platform/network/ProtectionSpaceHash.h b/Source/WebCore/platform/network/ProtectionSpaceHash.h
index 40eb9b6..edd95db 100644
--- a/Source/WebCore/platform/network/ProtectionSpaceHash.h
+++ b/Source/WebCore/platform/network/ProtectionSpaceHash.h
@@ -57,12 +57,7 @@ struct ProtectionSpaceHash {
namespace WTF {
- // WebCore::ProtectionSpaceHash is the default hash for ProtectionSpace
- template<> struct HashTraits<WebCore::ProtectionSpace> : GenericHashTraits<WebCore::ProtectionSpace> {
- static const bool emptyValueIsZero = true;
- static void constructDeletedValue(WebCore::ProtectionSpace& slot) { new (&slot) WebCore::ProtectionSpace(HashTableDeletedValue); }
- static bool isDeletedValue(const WebCore::ProtectionSpace& slot) { return slot.isHashTableDeletedValue(); }
- };
+ template<> struct HashTraits<WebCore::ProtectionSpace> : SimpleClassHashTraits<WebCore::ProtectionSpace> { };
template<typename T> struct DefaultHash;
template<> struct DefaultHash<WebCore::ProtectionSpace> {
diff --git a/Source/WebCore/platform/network/ResourceHandleClient.h b/Source/WebCore/platform/network/ResourceHandleClient.h
index e92b376..8b064c5 100644
--- a/Source/WebCore/platform/network/ResourceHandleClient.h
+++ b/Source/WebCore/platform/network/ResourceHandleClient.h
@@ -71,7 +71,7 @@ namespace WebCore {
virtual void didSendData(ResourceHandle*, unsigned long long /*bytesSent*/, unsigned long long /*totalBytesToBeSent*/) { }
virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&) { }
- virtual void didReceiveData(ResourceHandle*, const char*, int, int /*lengthReceived*/) { }
+ virtual void didReceiveData(ResourceHandle*, const char*, int, int /*encodedDataLength*/) { }
virtual void didReceiveCachedMetadata(ResourceHandle*, const char*, int) { }
virtual void didFinishLoading(ResourceHandle*, double /*finishTime*/) { }
virtual void didFail(ResourceHandle*, const ResourceError&) { }
diff --git a/Source/WebCore/platform/network/ResourceHandleInternal.h b/Source/WebCore/platform/network/ResourceHandleInternal.h
index b622801..bd24d22 100644
--- a/Source/WebCore/platform/network/ResourceHandleInternal.h
+++ b/Source/WebCore/platform/network/ResourceHandleInternal.h
@@ -116,7 +116,6 @@ namespace WebCore {
, m_buffer(0)
, m_bodySize(0)
, m_bodyDataSent(0)
- , m_idleHandler(0)
, m_gotChunkHandler(0)
#endif
#if PLATFORM(QT)
@@ -195,7 +194,6 @@ namespace WebCore {
char* m_buffer;
unsigned long m_bodySize;
unsigned long m_bodyDataSent;
- guint m_idleHandler;
RefPtr<NetworkingContext> m_context;
gulong m_gotChunkHandler;
#endif
diff --git a/Source/WebCore/platform/network/ResourceLoadInfo.h b/Source/WebCore/platform/network/ResourceLoadInfo.h
index a1b958c..94c5f24 100644
--- a/Source/WebCore/platform/network/ResourceLoadInfo.h
+++ b/Source/WebCore/platform/network/ResourceLoadInfo.h
@@ -33,12 +33,16 @@ namespace WebCore {
struct ResourceLoadInfo : RefCounted<ResourceLoadInfo> {
ResourceLoadInfo()
- : httpStatusCode(0) { }
+ : httpStatusCode(0)
+ , encodedDataLength(-1) { }
int httpStatusCode;
String httpStatusText;
+ long long encodedDataLength;
HTTPHeaderMap requestHeaders;
HTTPHeaderMap responseHeaders;
+ String requestHeadersText;
+ String responseHeadersText;
};
}
diff --git a/Source/WebCore/platform/network/ResourceLoadPriority.h b/Source/WebCore/platform/network/ResourceLoadPriority.h
index 1c9d5d2..45238d7 100644
--- a/Source/WebCore/platform/network/ResourceLoadPriority.h
+++ b/Source/WebCore/platform/network/ResourceLoadPriority.h
@@ -28,15 +28,15 @@
namespace WebCore {
-enum ResourceLoadPriority {
- ResourceLoadPriorityVeryLow,
- ResourceLoadPriorityLow,
- ResourceLoadPriorityMedium,
- ResourceLoadPriorityHigh,
- ResourceLoadPriorityLowest = ResourceLoadPriorityVeryLow,
- ResourceLoadPriorityHighest = ResourceLoadPriorityHigh,
+enum ResourceLoadPriority {
// The unresolved priority is here for the convenience of the clients. It should not be passed to the ResourceLoadScheduler.
- ResourceLoadPriorityUnresolved,
+ ResourceLoadPriorityUnresolved = -1,
+ ResourceLoadPriorityVeryLow = 0,
+ ResourceLoadPriorityLow,
+ ResourceLoadPriorityMedium,
+ ResourceLoadPriorityHigh,
+ ResourceLoadPriorityLowest = ResourceLoadPriorityVeryLow,
+ ResourceLoadPriorityHighest = ResourceLoadPriorityHigh,
};
}
diff --git a/Source/WebCore/platform/network/ResourceRequestBase.h b/Source/WebCore/platform/network/ResourceRequestBase.h
index 31a1e69..53e1160 100644
--- a/Source/WebCore/platform/network/ResourceRequestBase.h
+++ b/Source/WebCore/platform/network/ResourceRequestBase.h
@@ -65,6 +65,7 @@ namespace WebCore {
TargetIsWorker,
TargetIsSharedWorker,
TargetIsPrefetch,
+ TargetIsFavicon,
};
static PassOwnPtr<ResourceRequest> adopt(PassOwnPtr<CrossThreadResourceRequestData>);
@@ -240,14 +241,6 @@ namespace WebCore {
unsigned initializeMaximumHTTPConnectionCountPerHost();
-#if USE(CF)
- bool isHTTPPipeliningEnabled();
- bool shouldForceHTTPPipeliningPriorityHigh();
-#else
- inline bool isHTTPPipeliningEnabled() { return false; }
- inline bool shouldForceHTTPPipeliningPriorityHigh() { return false; }
-#endif
-
} // namespace WebCore
#endif // ResourceRequestBase_h
diff --git a/Source/WebCore/platform/network/ResourceResponseBase.cpp b/Source/WebCore/platform/network/ResourceResponseBase.cpp
index 55eac76..5fcc328 100644
--- a/Source/WebCore/platform/network/ResourceResponseBase.cpp
+++ b/Source/WebCore/platform/network/ResourceResponseBase.cpp
@@ -108,7 +108,7 @@ PassOwnPtr<ResourceResponse> ResourceResponseBase::adopt(PassOwnPtr<CrossThreadR
response->setHTTPStatusCode(data->m_httpStatusCode);
response->setHTTPStatusText(data->m_httpStatusText);
- response->lazyInit();
+ response->lazyInit(AllFields);
response->m_httpHeaderFields.adopt(data->m_httpHeaders.release());
response->setLastModifiedDate(data->m_lastModifiedDate);
response->setResourceLoadTiming(data->m_resourceLoadTiming.release());
@@ -135,7 +135,7 @@ PassOwnPtr<CrossThreadResourceResponseData> ResourceResponseBase::copyData() con
bool ResourceResponseBase::isHTTP() const
{
- lazyInit();
+ lazyInit(CommonFieldsOnly);
String protocol = m_url.protocol();
@@ -144,126 +144,140 @@ bool ResourceResponseBase::isHTTP() const
const KURL& ResourceResponseBase::url() const
{
- lazyInit();
-
+ lazyInit(CommonFieldsOnly);
+
return m_url;
}
void ResourceResponseBase::setURL(const KURL& url)
{
- lazyInit();
+ lazyInit(CommonFieldsOnly);
m_isNull = false;
-
+
m_url = url;
}
const String& ResourceResponseBase::mimeType() const
{
- lazyInit();
+ lazyInit(CommonFieldsOnly);
return m_mimeType;
}
void ResourceResponseBase::setMimeType(const String& mimeType)
{
- lazyInit();
+ lazyInit(CommonFieldsOnly);
m_isNull = false;
-
+
m_mimeType = mimeType;
}
long long ResourceResponseBase::expectedContentLength() const
{
- lazyInit();
+ lazyInit(CommonFieldsOnly);
return m_expectedContentLength;
}
void ResourceResponseBase::setExpectedContentLength(long long expectedContentLength)
{
- lazyInit();
+ lazyInit(CommonFieldsOnly);
m_isNull = false;
-
+
m_expectedContentLength = expectedContentLength;
}
const String& ResourceResponseBase::textEncodingName() const
{
- lazyInit();
+ lazyInit(CommonFieldsOnly);
return m_textEncodingName;
}
void ResourceResponseBase::setTextEncodingName(const String& encodingName)
{
- lazyInit();
+ lazyInit(CommonFieldsOnly);
m_isNull = false;
-
+
m_textEncodingName = encodingName;
}
// FIXME should compute this on the fly
const String& ResourceResponseBase::suggestedFilename() const
{
- lazyInit();
+ lazyInit(CommonFieldsOnly);
return m_suggestedFilename;
}
void ResourceResponseBase::setSuggestedFilename(const String& suggestedName)
{
- lazyInit();
+ lazyInit(CommonFieldsOnly);
m_isNull = false;
-
+
m_suggestedFilename = suggestedName;
}
int ResourceResponseBase::httpStatusCode() const
{
- lazyInit();
+ lazyInit(CommonFieldsOnly);
return m_httpStatusCode;
}
void ResourceResponseBase::setHTTPStatusCode(int statusCode)
{
- lazyInit();
+ lazyInit(CommonFieldsOnly);
m_httpStatusCode = statusCode;
}
const String& ResourceResponseBase::httpStatusText() const
{
- lazyInit();
+ lazyInit(AllFields);
return m_httpStatusText;
}
void ResourceResponseBase::setHTTPStatusText(const String& statusText)
{
- lazyInit();
+ lazyInit(AllFields);
m_httpStatusText = statusText;
}
String ResourceResponseBase::httpHeaderField(const AtomicString& name) const
{
- lazyInit();
+ lazyInit(CommonFieldsOnly);
+
+ // If we already have the header, just return it instead of consuming memory by grabing all headers.
+ String value = m_httpHeaderFields.get(name);
+ if (!value.isEmpty())
+ return value;
+
+ lazyInit(AllFields);
return m_httpHeaderFields.get(name);
}
String ResourceResponseBase::httpHeaderField(const char* name) const
{
- lazyInit();
+ lazyInit(CommonFieldsOnly);
+
+ // If we already have the header, just return it instead of consuming memory by grabing all headers.
+ String value = m_httpHeaderFields.get(name);
+ if (!value.isEmpty())
+ return value;
+
+ lazyInit(AllFields);
return m_httpHeaderFields.get(name);
}
void ResourceResponseBase::setHTTPHeaderField(const AtomicString& name, const String& value)
{
- lazyInit();
-
+ lazyInit(AllFields);
+
DEFINE_STATIC_LOCAL(const AtomicString, ageHeader, ("age"));
DEFINE_STATIC_LOCAL(const AtomicString, cacheControlHeader, ("cache-control"));
DEFINE_STATIC_LOCAL(const AtomicString, dateHeader, ("date"));
@@ -286,7 +300,7 @@ void ResourceResponseBase::setHTTPHeaderField(const AtomicString& name, const St
const HTTPHeaderMap& ResourceResponseBase::httpHeaderFields() const
{
- lazyInit();
+ lazyInit(AllFields);
return m_httpHeaderFields;
}
@@ -295,7 +309,7 @@ void ResourceResponseBase::parseCacheControlDirectives() const
{
ASSERT(!m_haveParsedCacheControlHeader);
- lazyInit();
+ lazyInit(CommonFieldsOnly);
m_haveParsedCacheControlHeader = true;
@@ -332,13 +346,14 @@ void ResourceResponseBase::parseCacheControlDirectives() const
}
}
}
-
+
if (!m_cacheControlContainsNoCache) {
// Handle Pragma: no-cache
// This is deprecated and equivalent to Cache-control: no-cache
// Don't bother tokenizing the value, it is not important
DEFINE_STATIC_LOCAL(const AtomicString, pragmaHeader, ("pragma"));
String pragmaValue = m_httpHeaderFields.get(pragmaHeader);
+
m_cacheControlContainsNoCache = pragmaValue.lower().contains(noCacheDirective);
}
}
@@ -364,6 +379,15 @@ bool ResourceResponseBase::cacheControlContainsMustRevalidate() const
return m_cacheControlContainsMustRevalidate;
}
+bool ResourceResponseBase::hasCacheValidatorFields() const
+{
+ lazyInit(CommonFieldsOnly);
+
+ DEFINE_STATIC_LOCAL(const AtomicString, lastModifiedHeader, ("last-modified"));
+ DEFINE_STATIC_LOCAL(const AtomicString, eTagHeader, ("etag"));
+ return !m_httpHeaderFields.get(lastModifiedHeader).isEmpty() || !m_httpHeaderFields.get(eTagHeader).isEmpty();
+}
+
double ResourceResponseBase::cacheControlMaxAge() const
{
if (!m_haveParsedCacheControlHeader)
@@ -388,7 +412,7 @@ static double parseDateValueInHeader(const HTTPHeaderMap& headers, const AtomicS
double ResourceResponseBase::date() const
{
- lazyInit();
+ lazyInit(CommonFieldsOnly);
if (!m_haveParsedDateHeader) {
DEFINE_STATIC_LOCAL(const AtomicString, headerName, ("date"));
@@ -400,8 +424,8 @@ double ResourceResponseBase::date() const
double ResourceResponseBase::age() const
{
- lazyInit();
-
+ lazyInit(CommonFieldsOnly);
+
if (!m_haveParsedAgeHeader) {
DEFINE_STATIC_LOCAL(const AtomicString, headerName, ("age"));
String headerValue = m_httpHeaderFields.get(headerName);
@@ -416,7 +440,7 @@ double ResourceResponseBase::age() const
double ResourceResponseBase::expires() const
{
- lazyInit();
+ lazyInit(CommonFieldsOnly);
if (!m_haveParsedExpiresHeader) {
DEFINE_STATIC_LOCAL(const AtomicString, headerName, ("expires"));
@@ -428,8 +452,8 @@ double ResourceResponseBase::expires() const
double ResourceResponseBase::lastModified() const
{
- lazyInit();
-
+ lazyInit(CommonFieldsOnly);
+
if (!m_haveParsedLastModifiedHeader) {
DEFINE_STATIC_LOCAL(const AtomicString, headerName, ("last-modified"));
m_lastModified = parseDateValueInHeader(m_httpHeaderFields, headerName);
@@ -440,7 +464,7 @@ double ResourceResponseBase::lastModified() const
bool ResourceResponseBase::isAttachment() const
{
- lazyInit();
+ lazyInit(AllFields);
DEFINE_STATIC_LOCAL(const AtomicString, headerName, ("content-disposition"));
String value = m_httpHeaderFields.get(headerName);
@@ -454,21 +478,21 @@ bool ResourceResponseBase::isAttachment() const
void ResourceResponseBase::setLastModifiedDate(time_t lastModifiedDate)
{
- lazyInit();
+ lazyInit(AllFields);
m_lastModifiedDate = lastModifiedDate;
}
time_t ResourceResponseBase::lastModifiedDate() const
{
- lazyInit();
+ lazyInit(AllFields);
return m_lastModifiedDate;
}
bool ResourceResponseBase::wasCached() const
{
- lazyInit();
+ lazyInit(AllFields);
return m_wasCached;
}
@@ -480,65 +504,65 @@ void ResourceResponseBase::setWasCached(bool value)
bool ResourceResponseBase::connectionReused() const
{
- lazyInit();
+ lazyInit(AllFields);
return m_connectionReused;
}
void ResourceResponseBase::setConnectionReused(bool connectionReused)
{
- lazyInit();
+ lazyInit(AllFields);
m_connectionReused = connectionReused;
}
unsigned ResourceResponseBase::connectionID() const
{
- lazyInit();
+ lazyInit(AllFields);
return m_connectionID;
}
void ResourceResponseBase::setConnectionID(unsigned connectionID)
{
- lazyInit();
+ lazyInit(AllFields);
m_connectionID = connectionID;
}
ResourceLoadTiming* ResourceResponseBase::resourceLoadTiming() const
{
- lazyInit();
+ lazyInit(AllFields);
return m_resourceLoadTiming.get();
}
void ResourceResponseBase::setResourceLoadTiming(PassRefPtr<ResourceLoadTiming> resourceLoadTiming)
{
- lazyInit();
+ lazyInit(AllFields);
m_resourceLoadTiming = resourceLoadTiming;
}
PassRefPtr<ResourceLoadInfo> ResourceResponseBase::resourceLoadInfo() const
{
- lazyInit();
+ lazyInit(AllFields);
return m_resourceLoadInfo.get();
}
void ResourceResponseBase::setResourceLoadInfo(PassRefPtr<ResourceLoadInfo> loadInfo)
{
- lazyInit();
+ lazyInit(AllFields);
m_resourceLoadInfo = loadInfo;
}
-void ResourceResponseBase::lazyInit() const
+void ResourceResponseBase::lazyInit(InitLevel initLevel) const
{
- const_cast<ResourceResponse*>(static_cast<const ResourceResponse*>(this))->platformLazyInit();
+ const_cast<ResourceResponse*>(static_cast<const ResourceResponse*>(this))->platformLazyInit(initLevel);
}
-
+
bool ResourceResponseBase::compare(const ResourceResponse& a, const ResourceResponse& b)
{
if (a.isNull() != b.isNull())
diff --git a/Source/WebCore/platform/network/ResourceResponseBase.h b/Source/WebCore/platform/network/ResourceResponseBase.h
index e0774c2..250411c 100644
--- a/Source/WebCore/platform/network/ResourceResponseBase.h
+++ b/Source/WebCore/platform/network/ResourceResponseBase.h
@@ -35,6 +35,10 @@
#include <wtf/PassOwnPtr.h>
#include <wtf/RefPtr.h>
+#if OS(SOLARIS)
+#include <sys/time.h> // For time_t structure.
+#endif
+
namespace WebCore {
class ResourceResponse;
@@ -93,6 +97,7 @@ public:
bool cacheControlContainsNoCache() const;
bool cacheControlContainsNoStore() const;
bool cacheControlContainsMustRevalidate() const;
+ bool hasCacheValidatorFields() const;
double cacheControlMaxAge() const;
double date() const;
double age() const;
@@ -124,13 +129,19 @@ public:
static bool compare(const ResourceResponse&, const ResourceResponse&);
protected:
+ enum InitLevel {
+ Uninitialized,
+ CommonFieldsOnly,
+ AllFields
+ };
+
ResourceResponseBase();
ResourceResponseBase(const KURL& url, const String& mimeType, long long expectedLength, const String& textEncodingName, const String& filename);
- void lazyInit() const;
+ void lazyInit(InitLevel) const;
// The ResourceResponse subclass may "shadow" this method to lazily initialize platform specific fields
- void platformLazyInit() { }
+ void platformLazyInit(InitLevel) { }
// The ResourceResponse subclass may "shadow" this method to compare platform specific fields
static bool platformCompare(const ResourceResponse&, const ResourceResponse&) { return true; }
diff --git a/Source/WebCore/platform/network/android/ResourceHandleAndroid.cpp b/Source/WebCore/platform/network/android/ResourceHandleAndroid.cpp
index 8837cf8..13a26f0 100644
--- a/Source/WebCore/platform/network/android/ResourceHandleAndroid.cpp
+++ b/Source/WebCore/platform/network/android/ResourceHandleAndroid.cpp
@@ -131,7 +131,7 @@ public:
*m_response = response;
}
- virtual void didReceiveData(ResourceHandle*, const char* data, int len, int lengthReceived)
+ virtual void didReceiveData(ResourceHandle*, const char* data, int len, int encodedDataLength)
{
m_data->append(data, len);
}
diff --git a/Source/WebCore/platform/network/cf/ResourceHandleCFNet.cpp b/Source/WebCore/platform/network/cf/ResourceHandleCFNet.cpp
index f840b04..83cd793 100644
--- a/Source/WebCore/platform/network/cf/ResourceHandleCFNet.cpp
+++ b/Source/WebCore/platform/network/cf/ResourceHandleCFNet.cpp
@@ -93,7 +93,7 @@ private:
virtual bool shouldUseCredentialStorage(ResourceHandle*);
virtual void didReceiveAuthenticationChallenge(ResourceHandle*, const AuthenticationChallenge&);
virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&);
- virtual void didReceiveData(ResourceHandle*, const char*, int, int /*lengthReceived*/);
+ virtual void didReceiveData(ResourceHandle*, const char*, int, int /*encodedDataLength*/);
virtual void didFinishLoading(ResourceHandle*, double /*finishTime*/);
virtual void didFail(ResourceHandle*, const ResourceError&);
@@ -757,7 +757,7 @@ void WebCoreSynchronousLoaderClient::didReceiveResponse(ResourceHandle*, const R
m_response = response;
}
-void WebCoreSynchronousLoaderClient::didReceiveData(ResourceHandle*, const char* data, int length, int /*lengthReceived*/)
+void WebCoreSynchronousLoaderClient::didReceiveData(ResourceHandle*, const char* data, int length, int /*encodedDataLength*/)
{
if (!m_data)
m_data.adoptCF(CFDataCreateMutable(kCFAllocatorDefault, 0));
diff --git a/Source/WebCore/platform/network/cf/ResourceRequest.h b/Source/WebCore/platform/network/cf/ResourceRequest.h
index 2da5026..5a14342 100644
--- a/Source/WebCore/platform/network/cf/ResourceRequest.h
+++ b/Source/WebCore/platform/network/cf/ResourceRequest.h
@@ -88,6 +88,9 @@ namespace WebCore {
void setStorageSession(CFURLStorageSessionRef);
#endif
+ static bool httpPipeliningEnabled();
+ static void setHTTPPipeliningEnabled(bool);
+
private:
friend class ResourceRequestBase;
@@ -102,6 +105,8 @@ namespace WebCore {
#else
RetainPtr<NSURLRequest> m_nsRequest;
#endif
+
+ static bool s_httpPipeliningEnabled;
};
struct CrossThreadResourceRequestData : public CrossThreadResourceRequestDataBase {
diff --git a/Source/WebCore/platform/network/cf/ResourceRequestCFNet.cpp b/Source/WebCore/platform/network/cf/ResourceRequestCFNet.cpp
index fdccc11..d0ef1f9 100644
--- a/Source/WebCore/platform/network/cf/ResourceRequestCFNet.cpp
+++ b/Source/WebCore/platform/network/cf/ResourceRequestCFNet.cpp
@@ -29,6 +29,7 @@
#include "ResourceRequest.h"
#if PLATFORM(MAC)
+#include "ResourceLoadPriority.h"
#include "WebCoreSystemInterface.h"
#endif
@@ -40,6 +41,8 @@
namespace WebCore {
+bool ResourceRequest::s_httpPipeliningEnabled = false;
+
#if USE(CFNETWORK)
typedef void (*CFURLRequestSetContentDispositionEncodingFallbackArrayFunction)(CFMutableURLRequestRef, CFArrayRef);
@@ -208,6 +211,16 @@ void ResourceRequest::setStorageSession(CFURLStorageSessionRef storageSession)
#endif // USE(CFNETWORK)
+bool ResourceRequest::httpPipeliningEnabled()
+{
+ return s_httpPipeliningEnabled;
+}
+
+void ResourceRequest::setHTTPPipeliningEnabled(bool flag)
+{
+ s_httpPipeliningEnabled = flag;
+}
+
unsigned initializeMaximumHTTPConnectionCountPerHost()
{
static const unsigned preferredConnectionCount = 6;
@@ -217,7 +230,9 @@ unsigned initializeMaximumHTTPConnectionCountPerHost()
unsigned maximumHTTPConnectionCountPerHost = wkInitializeMaximumHTTPConnectionCountPerHost(preferredConnectionCount);
#if PLATFORM(MAC)
- if (isHTTPPipeliningEnabled()) {
+ if (ResourceRequest::httpPipeliningEnabled()) {
+ wkSetHTTPPipeliningMaximumPriority(ResourceLoadPriorityHighest);
+ wkSetHTTPPipeliningMinimumFastLanePriority(ResourceLoadPriorityMedium);
// When pipelining do not rate-limit requests sent from WebCore since CFNetwork handles that.
return unlimitedConnectionCount;
}
@@ -226,23 +241,4 @@ unsigned initializeMaximumHTTPConnectionCountPerHost()
return maximumHTTPConnectionCountPerHost;
}
-static inline bool readBooleanPreference(CFStringRef key)
-{
- Boolean keyExistsAndHasValidFormat;
- Boolean result = CFPreferencesGetAppBooleanValue(key, kCFPreferencesCurrentApplication, &keyExistsAndHasValidFormat);
- return keyExistsAndHasValidFormat ? result : false;
-}
-
-bool isHTTPPipeliningEnabled()
-{
- static bool isEnabled = readBooleanPreference(CFSTR("WebKitEnableHTTPPipelining"));
- return isEnabled;
-}
-
-bool shouldForceHTTPPipeliningPriorityHigh()
-{
- static bool shouldForcePriorityHigh = readBooleanPreference(CFSTR("WebKitForceHTTPPipeliningPriorityHigh"));
- return shouldForcePriorityHigh;
-}
-
} // namespace WebCore
diff --git a/Source/WebCore/platform/network/cf/ResourceRequestCFNet.h b/Source/WebCore/platform/network/cf/ResourceRequestCFNet.h
index 271dcd2..987508f 100644
--- a/Source/WebCore/platform/network/cf/ResourceRequestCFNet.h
+++ b/Source/WebCore/platform/network/cf/ResourceRequestCFNet.h
@@ -41,34 +41,37 @@ void getResourceRequest(ResourceRequest&, CFURLRequestRef);
CFURLRequestRef cfURLRequest(const ResourceRequest&);
#endif
-inline ResourceLoadPriority mapHTTPPipeliningPriorityToResourceLoadPriority(int priority)
+inline ResourceLoadPriority toResourceLoadPriority(int priority)
{
switch (priority) {
+ case -1:
+ return ResourceLoadPriorityUnresolved;
case 0:
- return ResourceLoadPriorityLow;
+ return ResourceLoadPriorityVeryLow;
case 1:
- return ResourceLoadPriorityMedium;
+ return ResourceLoadPriorityLow;
case 2:
- return ResourceLoadPriorityHigh;
+ return ResourceLoadPriorityMedium;
case 3:
- return ResourceLoadPriorityUnresolved;
+ return ResourceLoadPriorityHigh;
default:
ASSERT_NOT_REACHED();
return ResourceLoadPriorityLowest;
}
}
-inline int mapResourceLoadPriorityToHTTPPipeliningPriority(ResourceLoadPriority priority)
+inline int toHTTPPipeliningPriority(ResourceLoadPriority priority)
{
switch (priority) {
+ case ResourceLoadPriorityUnresolved:
+ return -1;
case ResourceLoadPriorityVeryLow:
- case ResourceLoadPriorityLow:
return 0;
- case ResourceLoadPriorityMedium:
+ case ResourceLoadPriorityLow:
return 1;
- case ResourceLoadPriorityHigh:
+ case ResourceLoadPriorityMedium:
return 2;
- case ResourceLoadPriorityUnresolved:
+ case ResourceLoadPriorityHigh:
return 3;
}
diff --git a/Source/WebCore/platform/network/cf/ResourceResponse.h b/Source/WebCore/platform/network/cf/ResourceResponse.h
index 0551ede..675d431 100644
--- a/Source/WebCore/platform/network/cf/ResourceResponse.h
+++ b/Source/WebCore/platform/network/cf/ResourceResponse.h
@@ -44,21 +44,21 @@ namespace WebCore {
class ResourceResponse : public ResourceResponseBase {
public:
ResourceResponse()
- : m_isUpToDate(true)
+ : m_initLevel(AllFields)
{
}
#if USE(CFNETWORK)
ResourceResponse(CFURLResponseRef cfResponse)
: m_cfResponse(cfResponse)
- , m_isUpToDate(false)
+ , m_initLevel(Uninitialized)
{
m_isNull = !cfResponse;
}
#else
ResourceResponse(NSURLResponse* nsResponse)
: m_nsResponse(nsResponse)
- , m_isUpToDate(false)
+ , m_initLevel(Uninitialized)
{
m_isNull = !nsResponse;
}
@@ -66,15 +66,15 @@ public:
ResourceResponse(const KURL& url, const String& mimeType, long long expectedLength, const String& textEncodingName, const String& filename)
: ResourceResponseBase(url, mimeType, expectedLength, textEncodingName, filename)
- , m_isUpToDate(true)
+ , m_initLevel(AllFields)
{
}
unsigned memoryUsage() const
{
// FIXME: Find some programmatic lighweight way to calculate ResourceResponse and associated classes.
- // This is a rough estimate of resource overhead based on stats collected from the stress test.
- return 3072;
+ // This is a rough estimate of resource overhead based on stats collected from memory usage tests.
+ return 3800;
/* 1280 * 2 + // average size of ResourceResponse. Doubled to account for the WebCore copy and the CF copy.
// Mostly due to the size of the hash maps, the Header Map strings and the URL.
256 * 2 // Overhead from ResourceRequest, doubled to account for WebCore copy and CF copy.
@@ -91,7 +91,7 @@ public:
private:
friend class ResourceResponseBase;
- void platformLazyInit();
+ void platformLazyInit(InitLevel);
PassOwnPtr<CrossThreadResourceResponseData> doPlatformCopyData(PassOwnPtr<CrossThreadResourceResponseData> data) const { return data; }
void doPlatformAdopt(PassOwnPtr<CrossThreadResourceResponseData>) { }
@@ -102,7 +102,7 @@ private:
#else
mutable RetainPtr<NSURLResponse> m_nsResponse;
#endif
- bool m_isUpToDate;
+ InitLevel m_initLevel;
};
struct CrossThreadResourceResponseData : public CrossThreadResourceResponseDataBase {
diff --git a/Source/WebCore/platform/network/cf/ResourceResponseCFNet.cpp b/Source/WebCore/platform/network/cf/ResourceResponseCFNet.cpp
index d4a0b31..06cc706 100644
--- a/Source/WebCore/platform/network/cf/ResourceResponseCFNet.cpp
+++ b/Source/WebCore/platform/network/cf/ResourceResponseCFNet.cpp
@@ -42,6 +42,11 @@ using namespace std;
namespace WebCore {
+static CFStringRef const commonHeaderFields[] = {
+ CFSTR("Age"), CFSTR("Cache-Control"), CFSTR("Date"), CFSTR("Etag"), CFSTR("Expires"), CFSTR("Last-Modified"), CFSTR("Pragma")
+};
+static const int numCommonHeaderFields = sizeof(commonHeaderFields) / sizeof(CFStringRef);
+
CFURLResponseRef ResourceResponse::cfURLResponse() const
{
if (!m_cfResponse && !m_isNull) {
@@ -70,52 +75,66 @@ static time_t toTimeT(CFAbsoluteTime time)
return min(max(minTimeAsDouble, time + kCFAbsoluteTimeIntervalSince1970), maxTimeAsDouble);
}
-void ResourceResponse::platformLazyInit()
+void ResourceResponse::platformLazyInit(InitLevel initLevel)
{
- if (m_isUpToDate)
+ if (m_initLevel > initLevel)
return;
- m_isUpToDate = true;
if (m_isNull) {
ASSERT(!m_cfResponse.get());
return;
}
- // FIXME: We may need to do MIME type sniffing here (unless that is done in CFURLResponseGetMIMEType).
-
- m_url = CFURLResponseGetURL(m_cfResponse.get());
- m_mimeType = CFURLResponseGetMIMEType(m_cfResponse.get());
- m_expectedContentLength = CFURLResponseGetExpectedContentLength(m_cfResponse.get());
- m_textEncodingName = CFURLResponseGetTextEncodingName(m_cfResponse.get());
-
- // Workaround for <rdar://problem/8757088>, can be removed once that is fixed.
- unsigned textEncodingNameLength = m_textEncodingName.length();
- if (textEncodingNameLength >= 2 && m_textEncodingName[0U] == '"' && m_textEncodingName[textEncodingNameLength - 1] == '"')
- m_textEncodingName = m_textEncodingName.substring(1, textEncodingNameLength - 2);
-
- m_lastModifiedDate = toTimeT(CFURLResponseGetLastModifiedDate(m_cfResponse.get()));
-
- RetainPtr<CFStringRef> suggestedFilename(AdoptCF, CFURLResponseCopySuggestedFilename(m_cfResponse.get()));
- m_suggestedFilename = suggestedFilename.get();
-
- CFHTTPMessageRef httpResponse = CFURLResponseGetHTTPResponse(m_cfResponse.get());
- if (httpResponse) {
- m_httpStatusCode = CFHTTPMessageGetResponseStatusCode(httpResponse);
+ if (m_initLevel < CommonFieldsOnly && initLevel >= CommonFieldsOnly) {
+ m_url = CFURLResponseGetURL(m_cfResponse.get());
+ m_mimeType = CFURLResponseGetMIMEType(m_cfResponse.get());
+ m_expectedContentLength = CFURLResponseGetExpectedContentLength(m_cfResponse.get());
+ m_textEncodingName = CFURLResponseGetTextEncodingName(m_cfResponse.get());
+
+ // Workaround for <rdar://problem/8757088>, can be removed once that is fixed.
+ unsigned textEncodingNameLength = m_textEncodingName.length();
+ if (textEncodingNameLength >= 2 && m_textEncodingName[0U] == '"' && m_textEncodingName[textEncodingNameLength - 1] == '"')
+ m_textEncodingName = m_textEncodingName.substring(1, textEncodingNameLength - 2);
+
+ m_lastModifiedDate = toTimeT(CFURLResponseGetLastModifiedDate(m_cfResponse.get()));
+
+ RetainPtr<CFStringRef> suggestedFilename(AdoptCF, CFURLResponseCopySuggestedFilename(m_cfResponse.get()));
+ m_suggestedFilename = suggestedFilename.get();
+
+ CFHTTPMessageRef httpResponse = CFURLResponseGetHTTPResponse(m_cfResponse.get());
+ if (httpResponse) {
+ m_httpStatusCode = CFHTTPMessageGetResponseStatusCode(httpResponse);
+
+ RetainPtr<CFDictionaryRef> headers(AdoptCF, CFHTTPMessageCopyAllHeaderFields(httpResponse));
+
+ for (int i = 0; i < numCommonHeaderFields; i++) {
+ CFStringRef value;
+ if (CFDictionaryGetValueIfPresent(headers.get(), commonHeaderFields[i], (const void **)&value))
+ m_httpHeaderFields.set(commonHeaderFields[i], value);
+ }
+ } else
+ m_httpStatusCode = 0;
+ }
- RetainPtr<CFStringRef> statusLine(AdoptCF, CFHTTPMessageCopyResponseStatusLine(httpResponse));
- m_httpStatusText = extractReasonPhraseFromHTTPStatusLine(statusLine.get());
+ if (m_initLevel < AllFields && initLevel >= AllFields) {
+ CFHTTPMessageRef httpResponse = CFURLResponseGetHTTPResponse(m_cfResponse.get());
+ if (httpResponse) {
+ RetainPtr<CFStringRef> statusLine(AdoptCF, CFHTTPMessageCopyResponseStatusLine(httpResponse));
+ m_httpStatusText = extractReasonPhraseFromHTTPStatusLine(statusLine.get());
+
+ RetainPtr<CFDictionaryRef> headers(AdoptCF, CFHTTPMessageCopyAllHeaderFields(httpResponse));
+ CFIndex headerCount = CFDictionaryGetCount(headers.get());
+ Vector<const void*, 128> keys(headerCount);
+ Vector<const void*, 128> values(headerCount);
+ CFDictionaryGetKeysAndValues(headers.get(), keys.data(), values.data());
+ for (int i = 0; i < headerCount; ++i)
+ m_httpHeaderFields.set((CFStringRef)keys[i], (CFStringRef)values[i]);
+ }
+ }
- RetainPtr<CFDictionaryRef> headers(AdoptCF, CFHTTPMessageCopyAllHeaderFields(httpResponse));
- CFIndex headerCount = CFDictionaryGetCount(headers.get());
- Vector<const void*, 128> keys(headerCount);
- Vector<const void*, 128> values(headerCount);
- CFDictionaryGetKeysAndValues(headers.get(), keys.data(), values.data());
- for (int i = 0; i < headerCount; ++i)
- m_httpHeaderFields.set((CFStringRef)keys[i], (CFStringRef)values[i]);
- } else
- m_httpStatusCode = 0;
+ m_initLevel = initLevel;
}
-
+
bool ResourceResponse::platformCompare(const ResourceResponse& a, const ResourceResponse& b)
{
return CFEqual(a.cfURLResponse(), b.cfURLResponse());
diff --git a/Source/WebCore/platform/network/curl/ResourceHandleCurl.cpp b/Source/WebCore/platform/network/curl/ResourceHandleCurl.cpp
index 1d276aa..d982186 100644
--- a/Source/WebCore/platform/network/curl/ResourceHandleCurl.cpp
+++ b/Source/WebCore/platform/network/curl/ResourceHandleCurl.cpp
@@ -46,7 +46,7 @@ public:
WebCoreSynchronousLoader();
virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&);
- virtual void didReceiveData(ResourceHandle*, const char*, int, int lengthReceived);
+ virtual void didReceiveData(ResourceHandle*, const char*, int, int encodedDataLength);
virtual void didFinishLoading(ResourceHandle*, double /*finishTime*/);
virtual void didFail(ResourceHandle*, const ResourceError&);
diff --git a/Source/WebCore/platform/network/mac/ResourceHandleMac.mm b/Source/WebCore/platform/network/mac/ResourceHandleMac.mm
index b2a89f0..c0a49d7 100644
--- a/Source/WebCore/platform/network/mac/ResourceHandleMac.mm
+++ b/Source/WebCore/platform/network/mac/ResourceHandleMac.mm
@@ -117,7 +117,7 @@ private:
virtual bool shouldUseCredentialStorage(ResourceHandle*);
virtual void didReceiveAuthenticationChallenge(ResourceHandle*, const AuthenticationChallenge&);
virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&);
- virtual void didReceiveData(ResourceHandle*, const char*, int, int /*lengthReceived*/);
+ virtual void didReceiveData(ResourceHandle*, const char*, int, int /*encodedDataLength*/);
virtual void didFinishLoading(ResourceHandle*, double /*finishTime*/);
virtual void didFail(ResourceHandle*, const ResourceError&);
#if USE(PROTECTION_SPACE_AUTH_CALLBACK)
@@ -1127,7 +1127,7 @@ void WebCoreSynchronousLoaderClient::didReceiveResponse(ResourceHandle*, const R
m_response = [response.nsURLResponse() copy];
}
-void WebCoreSynchronousLoaderClient::didReceiveData(ResourceHandle*, const char* data, int length, int /*lengthReceived*/)
+void WebCoreSynchronousLoaderClient::didReceiveData(ResourceHandle*, const char* data, int length, int /*encodedDataLength*/)
{
if (!m_data)
m_data = [[NSMutableData alloc] init];
diff --git a/Source/WebCore/platform/network/mac/ResourceRequestMac.mm b/Source/WebCore/platform/network/mac/ResourceRequestMac.mm
index 8446782..d99e1b7 100644
--- a/Source/WebCore/platform/network/mac/ResourceRequestMac.mm
+++ b/Source/WebCore/platform/network/mac/ResourceRequestMac.mm
@@ -70,8 +70,8 @@ void ResourceRequest::doUpdateResourceRequest()
m_allowCookies = [m_nsRequest.get() HTTPShouldHandleCookies];
#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
- if (isHTTPPipeliningEnabled() && !shouldForceHTTPPipeliningPriorityHigh())
- m_priority = mapHTTPPipeliningPriorityToResourceLoadPriority(wkGetHTTPPipeliningPriority(m_nsRequest.get()));
+ if (ResourceRequest::httpPipeliningEnabled())
+ m_priority = toResourceLoadPriority(wkGetHTTPPipeliningPriority(m_nsRequest.get()));
#endif
NSDictionary *headers = [m_nsRequest.get() allHTTPHeaderFields];
@@ -120,10 +120,8 @@ void ResourceRequest::doUpdatePlatformRequest()
#endif
#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
- if (isHTTPPipeliningEnabled()) {
- int priority = mapResourceLoadPriorityToHTTPPipeliningPriority(m_priority);
- wkSetHTTPPipeliningPriority(nsRequest, shouldForceHTTPPipeliningPriorityHigh() ? 2 : priority);
- }
+ if (ResourceRequest::httpPipeliningEnabled())
+ wkSetHTTPPipeliningPriority(nsRequest, toHTTPPipeliningPriority(m_priority));
#endif
[nsRequest setCachePolicy:(NSURLRequestCachePolicy)cachePolicy()];
diff --git a/Source/WebCore/platform/network/mac/ResourceResponseMac.mm b/Source/WebCore/platform/network/mac/ResourceResponseMac.mm
index 58c3641..704592a 100644
--- a/Source/WebCore/platform/network/mac/ResourceResponseMac.mm
+++ b/Source/WebCore/platform/network/mac/ResourceResponseMac.mm
@@ -34,6 +34,7 @@
#import <Foundation/Foundation.h>
#import <wtf/StdLibExtras.h>
#import <limits>
+#include <wtf/text/CString.h>
@interface NSURLResponse (FoundationSecretsWebCoreKnowsAbout)
- (NSTimeInterval)_calculatedExpiration;
@@ -45,6 +46,11 @@ typedef int NSInteger;
namespace WebCore {
+static NSString* const commonHeaderFields[] = {
+ @"Age", @"Cache-Control", @"Date", @"Etag", @"Expires", @"Last-Modified", @"Pragma"
+};
+static const int numCommonHeaderFields = sizeof(commonHeaderFields) / sizeof(AtomicString*);
+
NSURLResponse *ResourceResponse::nsURLResponse() const
{
if (!m_nsResponse && !m_isNull) {
@@ -61,48 +67,72 @@ NSURLResponse *ResourceResponse::nsURLResponse() const
return m_nsResponse.get();
}
-void ResourceResponse::platformLazyInit()
+void ResourceResponse::platformLazyInit(InitLevel initLevel)
{
- if (m_isUpToDate)
+ if (m_initLevel >= initLevel)
return;
- m_isUpToDate = true;
if (m_isNull) {
ASSERT(!m_nsResponse);
return;
}
-
- m_url = [m_nsResponse.get() URL];
- m_mimeType = [m_nsResponse.get() MIMEType];
- m_expectedContentLength = [m_nsResponse.get() expectedContentLength];
- m_textEncodingName = [m_nsResponse.get() textEncodingName];
- // Workaround for <rdar://problem/8757088>, can be removed once that is fixed.
- unsigned textEncodingNameLength = m_textEncodingName.length();
- if (textEncodingNameLength >= 2 && m_textEncodingName[0U] == '"' && m_textEncodingName[textEncodingNameLength - 1] == '"')
- m_textEncodingName = m_textEncodingName.substring(1, textEncodingNameLength - 2);
+ if (m_initLevel < CommonFieldsOnly && initLevel >= CommonFieldsOnly) {
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- m_suggestedFilename = [m_nsResponse.get() suggestedFilename];
-
- if ([m_nsResponse.get() isKindOfClass:[NSHTTPURLResponse class]]) {
- NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)m_nsResponse.get();
+ m_httpHeaderFields.clear();
+ m_url = [m_nsResponse.get() URL];
+ m_mimeType = [m_nsResponse.get() MIMEType];
+ m_expectedContentLength = [m_nsResponse.get() expectedContentLength];
+ m_textEncodingName = [m_nsResponse.get() textEncodingName];
+
+ // Workaround for <rdar://problem/8757088>, can be removed once that is fixed.
+ unsigned textEncodingNameLength = m_textEncodingName.length();
+ if (textEncodingNameLength >= 2 && m_textEncodingName[0U] == '"' && m_textEncodingName[textEncodingNameLength - 1] == '"')
+ m_textEncodingName = m_textEncodingName.substring(1, textEncodingNameLength - 2);
+
+ m_suggestedFilename = [m_nsResponse.get() suggestedFilename];
+
+ if ([m_nsResponse.get() isKindOfClass:[NSHTTPURLResponse class]]) {
+ NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)m_nsResponse.get();
+
+ m_httpStatusCode = [httpResponse statusCode];
+
+ NSDictionary *headers = [httpResponse allHeaderFields];
+
+ for (int i = 0; i < numCommonHeaderFields; i++) {
+ if (NSString* headerValue = [headers objectForKey:commonHeaderFields[i]])
+ m_httpHeaderFields.set([commonHeaderFields[i] UTF8String], headerValue);
+ }
+ } else
+ m_httpStatusCode = 0;
- m_httpStatusCode = [httpResponse statusCode];
+ [pool drain];
+ }
+
+ if (m_initLevel < AllFields && initLevel >= AllFields && [m_nsResponse.get() isKindOfClass:[NSHTTPURLResponse class]]) {
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
+ NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)m_nsResponse.get();
RetainPtr<NSString> httpStatusLine(AdoptNS, wkCopyNSURLResponseStatusLine(m_nsResponse.get()));
if (httpStatusLine)
m_httpStatusText = extractReasonPhraseFromHTTPStatusLine(httpStatusLine.get());
else
m_httpStatusText = "OK";
-
+
NSDictionary *headers = [httpResponse allHeaderFields];
NSEnumerator *e = [headers keyEnumerator];
while (NSString *name = [e nextObject])
m_httpHeaderFields.set(name, [headers objectForKey:name]);
- } else
- m_httpStatusCode = 0;
+
+ [pool drain];
+ }
+
+ m_initLevel = initLevel;
}
+
bool ResourceResponse::platformCompare(const ResourceResponse& a, const ResourceResponse& b)
{
return a.nsURLResponse() == b.nsURLResponse();
diff --git a/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp b/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp
index 6e63145..b27c8f4 100644
--- a/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp
+++ b/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp
@@ -149,13 +149,72 @@ bool FormDataIODevice::isSequential() const
return true;
}
-QNetworkReplyWrapper::QNetworkReplyWrapper(QNetworkReply* reply, QObject* parent)
+QNetworkReplyHandlerCallQueue::QNetworkReplyHandlerCallQueue(QNetworkReplyHandler* handler, bool deferSignals)
+ : m_replyHandler(handler)
+ , m_locks(0)
+ , m_deferSignals(deferSignals)
+ , m_flushing(false)
+{
+ Q_ASSERT(handler);
+}
+
+void QNetworkReplyHandlerCallQueue::push(EnqueuedCall method)
+{
+ m_enqueuedCalls.append(method);
+ flush();
+}
+
+void QNetworkReplyHandlerCallQueue::lock()
+{
+ ++m_locks;
+}
+
+void QNetworkReplyHandlerCallQueue::unlock()
+{
+ if (!m_locks)
+ return;
+
+ --m_locks;
+ flush();
+}
+
+void QNetworkReplyHandlerCallQueue::setDeferSignals(bool defer)
+{
+ m_deferSignals = defer;
+ flush();
+}
+
+void QNetworkReplyHandlerCallQueue::flush()
+{
+ if (m_flushing)
+ return;
+
+ m_flushing = true;
+
+ while (!m_deferSignals && !m_locks && !m_enqueuedCalls.isEmpty())
+ (m_replyHandler->*(m_enqueuedCalls.takeFirst()))();
+
+ m_flushing = false;
+}
+
+class QueueLocker {
+public:
+ QueueLocker(QNetworkReplyHandlerCallQueue* queue) : m_queue(queue) { m_queue->lock(); }
+ ~QueueLocker() { m_queue->unlock(); }
+private:
+ QNetworkReplyHandlerCallQueue* m_queue;
+};
+
+QNetworkReplyWrapper::QNetworkReplyWrapper(QNetworkReplyHandlerCallQueue* queue, QNetworkReply* reply, bool sniffMIMETypes, QObject* parent)
: QObject(parent)
, m_reply(reply)
+ , m_queue(queue)
+ , m_responseContainsData(false)
+ , m_sniffer(0)
+ , m_sniffMIMETypes(sniffMIMETypes)
{
Q_ASSERT(m_reply);
- connect(m_reply, SIGNAL(metaDataChanged()), this, SLOT(receiveMetaData()));
connect(m_reply, SIGNAL(readyRead()), this, SLOT(receiveMetaData()));
connect(m_reply, SIGNAL(finished()), this, SLOT(receiveMetaData()));
}
@@ -164,6 +223,7 @@ QNetworkReplyWrapper::~QNetworkReplyWrapper()
{
if (m_reply)
m_reply->deleteLater();
+ m_queue->clear();
}
QNetworkReply* QNetworkReplyWrapper::release()
@@ -174,6 +234,8 @@ QNetworkReply* QNetworkReplyWrapper::release()
resetConnections();
QNetworkReply* reply = m_reply;
m_reply = 0;
+ m_sniffer = 0;
+
reply->setParent(0);
return reply;
}
@@ -190,43 +252,80 @@ void QNetworkReplyWrapper::receiveMetaData()
// This slot is only used to receive the first signal from the QNetworkReply object.
resetConnections();
+
+ WTF::String contentType = m_reply->header(QNetworkRequest::ContentTypeHeader).toString();
+ m_encoding = extractCharsetFromMediaType(contentType);
+ m_advertisedMIMEType = extractMIMETypeFromMediaType(contentType);
+
m_redirectionTargetUrl = m_reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
if (m_redirectionTargetUrl.isValid()) {
- emit metaDataChanged();
- emit finished();
+ QueueLocker lock(m_queue);
+ m_queue->push(&QNetworkReplyHandler::sendResponseIfNeeded);
+ m_queue->push(&QNetworkReplyHandler::finish);
return;
}
- WTF::String contentType = m_reply->header(QNetworkRequest::ContentTypeHeader).toString();
- m_encoding = extractCharsetFromMediaType(contentType);
- m_advertisedMimeType = extractMIMETypeFromMediaType(contentType);
+ if (!m_sniffMIMETypes) {
+ emitMetaDataChanged();
+ return;
+ }
+
+ bool isSupportedImageType = MIMETypeRegistry::isSupportedImageMIMEType(m_advertisedMIMEType);
- bool hasData = m_reply->bytesAvailable();
- bool isFinished = m_reply->isFinished();
+ Q_ASSERT(!m_sniffer);
- if (!isFinished) {
- // If not finished, connect to the slots that will be used from this point on.
- connect(m_reply, SIGNAL(readyRead()), this, SIGNAL(readyRead()));
- connect(m_reply, SIGNAL(finished()), this, SLOT(didReceiveFinished()));
+ m_sniffer = new QtMIMETypeSniffer(m_reply, m_advertisedMIMEType, isSupportedImageType);
+
+ if (m_sniffer->isFinished()) {
+ receiveSniffedMIMEType();
+ return;
}
- emit metaDataChanged();
+ connect(m_sniffer.get(), SIGNAL(finished()), this, SLOT(receiveSniffedMIMEType()));
+}
+
+void QNetworkReplyWrapper::receiveSniffedMIMEType()
+{
+ Q_ASSERT(m_sniffer);
+
+ m_sniffedMIMEType = m_sniffer->mimeType();
+ m_sniffer = 0;
+
+ emitMetaDataChanged();
+}
- if (hasData)
- emit readyRead();
+void QNetworkReplyWrapper::emitMetaDataChanged()
+{
+ QueueLocker lock(m_queue);
+ m_queue->push(&QNetworkReplyHandler::sendResponseIfNeeded);
- if (isFinished) {
- emit finished();
+ if (m_reply->bytesAvailable()) {
+ m_responseContainsData = true;
+ m_queue->push(&QNetworkReplyHandler::forwardData);
+ }
+
+ if (m_reply->isFinished()) {
+ m_queue->push(&QNetworkReplyHandler::finish);
return;
}
+ // If not finished, connect to the slots that will be used from this point on.
+ connect(m_reply, SIGNAL(readyRead()), this, SLOT(didReceiveReadyRead()));
+ connect(m_reply, SIGNAL(finished()), this, SLOT(didReceiveFinished()));
+}
+
+void QNetworkReplyWrapper::didReceiveReadyRead()
+{
+ if (m_reply->bytesAvailable())
+ m_responseContainsData = true;
+ m_queue->push(&QNetworkReplyHandler::forwardData);
}
void QNetworkReplyWrapper::didReceiveFinished()
{
// Disconnecting will make sure that nothing will happen after emitting the finished signal.
resetConnections();
- emit finished();
+ m_queue->push(&QNetworkReplyHandler::finish);
}
String QNetworkReplyHandler::httpMethod() const
@@ -255,11 +354,9 @@ QNetworkReplyHandler::QNetworkReplyHandler(ResourceHandle* handle, LoadType load
, m_replyWrapper(0)
, m_resourceHandle(handle)
, m_loadType(loadType)
- , m_deferred(deferred)
, m_redirectionTries(gMaxRedirections)
+ , m_queue(this, deferred)
{
- resetState();
-
const ResourceRequest &r = m_resourceHandle->firstRequest();
if (r.httpMethod() == "GET")
@@ -281,52 +378,7 @@ QNetworkReplyHandler::QNetworkReplyHandler(ResourceHandle* handle, LoadType load
m_request = r.toNetworkRequest(originatingObject);
- if (!m_deferred)
- start();
-}
-
-void QNetworkReplyHandler::resetState()
-{
- m_redirected = false;
- m_responseSent = false;
- m_responseContainsData = false;
- m_hasStarted = false;
- m_callFinishOnResume = false;
- m_callSendResponseIfNeededOnResume = false;
- m_callForwardDataOnResume = false;
-
- if (m_replyWrapper) {
- m_replyWrapper->deleteLater();
- m_replyWrapper = 0;
- }
-}
-
-void QNetworkReplyHandler::setLoadingDeferred(bool deferred)
-{
- m_deferred = deferred;
-
- if (!deferred)
- resumeDeferredLoad();
-}
-
-void QNetworkReplyHandler::resumeDeferredLoad()
-{
- if (!m_hasStarted) {
- ASSERT(!m_callSendResponseIfNeededOnResume);
- ASSERT(!m_callForwardDataOnResume);
- ASSERT(!m_callFinishOnResume);
- start();
- return;
- }
-
- if (m_callSendResponseIfNeededOnResume)
- sendResponseIfNeeded();
-
- if (m_callForwardDataOnResume)
- forwardData();
-
- if (m_callFinishOnResume)
- finish();
+ m_queue.push(&QNetworkReplyHandler::start);
}
void QNetworkReplyHandler::abort()
@@ -345,7 +397,6 @@ QNetworkReply* QNetworkReplyHandler::release()
return 0;
QNetworkReply* reply = m_replyWrapper->release();
- m_replyWrapper->deleteLater();
m_replyWrapper = 0;
return reply;
}
@@ -365,35 +416,21 @@ static bool shouldIgnoreHttpError(QNetworkReply* reply, bool receivedData)
void QNetworkReplyHandler::finish()
{
- ASSERT(m_hasStarted);
-
- m_callFinishOnResume = m_deferred;
- if (m_deferred)
- return;
-
- if (!m_replyWrapper || !m_replyWrapper->reply())
- return;
-
-
- sendResponseIfNeeded();
-
- if (wasAborted())
- return;
+ ASSERT(m_replyWrapper && m_replyWrapper->reply() && !wasAborted());
ResourceHandleClient* client = m_resourceHandle->client();
if (!client) {
- m_replyWrapper->deleteLater();
m_replyWrapper = 0;
return;
}
- if (m_redirected) {
- resetState();
- start();
+ if (m_replyWrapper->wasRedirected()) {
+ m_replyWrapper = 0;
+ m_queue.push(&QNetworkReplyHandler::start);
return;
}
- if (!m_replyWrapper->reply()->error() || shouldIgnoreHttpError(m_replyWrapper->reply(), m_responseContainsData))
+ if (!m_replyWrapper->reply()->error() || shouldIgnoreHttpError(m_replyWrapper->reply(), m_replyWrapper->responseContainsData()))
client->didFinishLoading(m_resourceHandle, 0);
else {
QUrl url = m_replyWrapper->reply()->url();
@@ -408,40 +445,21 @@ void QNetworkReplyHandler::finish()
}
}
- if (m_replyWrapper) {
- m_replyWrapper->deleteLater();
- m_replyWrapper = 0;
- }
+ m_replyWrapper = 0;
}
void QNetworkReplyHandler::sendResponseIfNeeded()
{
- ASSERT(m_hasStarted);
+ ASSERT(m_replyWrapper && m_replyWrapper->reply() && !wasAborted());
- m_callSendResponseIfNeededOnResume = m_deferred;
- if (m_deferred)
+ if (m_replyWrapper->reply()->error() && m_replyWrapper->reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).isNull())
return;
- if (!m_replyWrapper || !m_replyWrapper->reply())
- return;
-
- if (m_replyWrapper->reply()->error() && !shouldIgnoreHttpError(m_replyWrapper->reply(), m_responseContainsData))
- return;
-
- if (wasAborted())
- return;
-
- if (m_responseSent)
- return;
- m_responseSent = true;
-
ResourceHandleClient* client = m_resourceHandle->client();
if (!client)
return;
- WTF::String contentType = m_replyWrapper->reply()->header(QNetworkRequest::ContentTypeHeader).toString();
- WTF::String encoding = extractCharsetFromMediaType(contentType);
- WTF::String mimeType = extractMIMETypeFromMediaType(contentType);
+ WTF::String mimeType = m_replyWrapper->mimeType();
if (mimeType.isEmpty()) {
// let's try to guess from the extension
@@ -451,7 +469,7 @@ void QNetworkReplyHandler::sendResponseIfNeeded()
KURL url(m_replyWrapper->reply()->url());
ResourceResponse response(url, mimeType.lower(),
m_replyWrapper->reply()->header(QNetworkRequest::ContentLengthHeader).toLongLong(),
- encoding, String());
+ m_replyWrapper->encoding(), String());
if (url.isLocalFile()) {
client->didReceiveResponse(m_resourceHandle, response);
@@ -501,9 +519,9 @@ void QNetworkReplyHandler::redirect(ResourceResponse& response, const QUrl& redi
newUrl.toString(),
QCoreApplication::translate("QWebPage", "Redirection limit reached"));
client->didFail(m_resourceHandle, error);
+ m_replyWrapper = 0;
return;
}
- m_redirected = true;
// Status Code 301 (Moved Permanently), 302 (Moved Temporarily), 303 (See Other):
// - If original request is POST convert to GET and redirect automatically
@@ -533,26 +551,7 @@ void QNetworkReplyHandler::redirect(ResourceResponse& response, const QUrl& redi
void QNetworkReplyHandler::forwardData()
{
- ASSERT(m_hasStarted);
-
- m_callForwardDataOnResume = m_deferred;
- if (m_deferred)
- return;
-
- if (!m_replyWrapper || !m_replyWrapper->reply())
- return;
-
- if (m_replyWrapper->reply()->bytesAvailable())
- m_responseContainsData = true;
-
- sendResponseIfNeeded();
-
- // don't emit the "Document has moved here" type of HTML
- if (m_redirected)
- return;
-
- if (wasAborted())
- return;
+ ASSERT(m_replyWrapper && m_replyWrapper->reply() && !wasAborted() && !m_replyWrapper->wasRedirected());
QByteArray data = m_replyWrapper->reply()->read(m_replyWrapper->reply()->bytesAvailable());
@@ -579,17 +578,11 @@ void QNetworkReplyHandler::uploadProgress(qint64 bytesSent, qint64 bytesTotal)
client->didSendData(m_resourceHandle, bytesSent, bytesTotal);
}
-QNetworkReply* QNetworkReplyHandler::sendNetworkRequest()
+QNetworkReply* QNetworkReplyHandler::sendNetworkRequest(QNetworkAccessManager* manager, const ResourceRequest& request)
{
if (m_loadType == SynchronousLoad)
m_request.setAttribute(gSynchronousNetworkRequestAttribute, true);
- ResourceHandleInternal* d = m_resourceHandle->getInternal();
-
- QNetworkAccessManager* manager = 0;
- if (d->m_context)
- manager = d->m_context->networkAccessManager();
-
if (!manager)
return 0;
@@ -606,7 +599,7 @@ QNetworkReply* QNetworkReplyHandler::sendNetworkRequest()
case QNetworkAccessManager::GetOperation:
return manager->get(m_request);
case QNetworkAccessManager::PostOperation: {
- FormDataIODevice* postDevice = new FormDataIODevice(d->m_firstRequest.httpBody());
+ FormDataIODevice* postDevice = new FormDataIODevice(request.httpBody());
// We may be uploading files so prevent QNR from buffering data
m_request.setHeader(QNetworkRequest::ContentLengthHeader, postDevice->getFormDataSize());
m_request.setAttribute(QNetworkRequest::DoNotBufferUploadDataAttribute, QVariant(true));
@@ -617,7 +610,7 @@ QNetworkReply* QNetworkReplyHandler::sendNetworkRequest()
case QNetworkAccessManager::HeadOperation:
return manager->head(m_request);
case QNetworkAccessManager::PutOperation: {
- FormDataIODevice* putDevice = new FormDataIODevice(d->m_firstRequest.httpBody());
+ FormDataIODevice* putDevice = new FormDataIODevice(request.httpBody());
// We may be uploading files so prevent QNR from buffering data
m_request.setHeader(QNetworkRequest::ContentLengthHeader, putDevice->getFormDataSize());
m_request.setAttribute(QNetworkRequest::DoNotBufferUploadDataAttribute, QVariant(true));
@@ -639,24 +632,22 @@ QNetworkReply* QNetworkReplyHandler::sendNetworkRequest()
void QNetworkReplyHandler::start()
{
- ASSERT(!m_hasStarted);
- m_hasStarted = true;
+ ResourceHandleInternal* d = m_resourceHandle->getInternal();
+ if (!d || !d->m_context)
+ return;
- QNetworkReply* reply = sendNetworkRequest();
+ QNetworkReply* reply = sendNetworkRequest(d->m_context->networkAccessManager(), d->m_firstRequest);
if (!reply)
return;
- m_replyWrapper = new QNetworkReplyWrapper(reply, this);
+ m_replyWrapper = new QNetworkReplyWrapper(&m_queue, reply, m_resourceHandle->shouldContentSniff() && d->m_context->mimeSniffingEnabled(), this);
if (m_loadType == SynchronousLoad && m_replyWrapper->reply()->isFinished()) {
+ m_replyWrapper->synchronousLoad();
// If supported, a synchronous request will be finished at this point, no need to hook up the signals.
return;
}
- connect(m_replyWrapper, SIGNAL(finished()), this, SLOT(finish()));
- connect(m_replyWrapper, SIGNAL(metaDataChanged()), this, SLOT(sendResponseIfNeeded()));
- connect(m_replyWrapper, SIGNAL(readyRead()), this, SLOT(forwardData()));
-
if (m_resourceHandle->firstRequest().reportUploadProgress())
connect(m_replyWrapper->reply(), SIGNAL(uploadProgress(qint64, qint64)), this, SLOT(uploadProgress(qint64, qint64)));
}
diff --git a/Source/WebCore/platform/network/qt/QNetworkReplyHandler.h b/Source/WebCore/platform/network/qt/QNetworkReplyHandler.h
index 61694d6..ec4e65a 100644
--- a/Source/WebCore/platform/network/qt/QNetworkReplyHandler.h
+++ b/Source/WebCore/platform/network/qt/QNetworkReplyHandler.h
@@ -25,6 +25,7 @@
#include <QNetworkAccessManager>
#include "FormData.h"
+#include "QtMIMETypeSniffer.h"
QT_BEGIN_NAMESPACE
class QFile;
@@ -34,39 +35,73 @@ QT_END_NAMESPACE
namespace WebCore {
class ResourceHandle;
+class ResourceRequest;
class ResourceResponse;
+class QNetworkReplyHandler;
+
+class QNetworkReplyHandlerCallQueue {
+public:
+ QNetworkReplyHandlerCallQueue(QNetworkReplyHandler*, bool deferSignals);
+ bool deferSignals() const { return m_deferSignals; }
+ void setDeferSignals(bool);
+
+ typedef void (QNetworkReplyHandler::*EnqueuedCall)();
+ void push(EnqueuedCall method);
+ void clear() { m_enqueuedCalls.clear(); }
+
+ void lock();
+ void unlock();
+private:
+ QNetworkReplyHandler* m_replyHandler;
+ int m_locks;
+ bool m_deferSignals;
+ bool m_flushing;
+ QList<EnqueuedCall> m_enqueuedCalls;
+
+ void flush();
+};
class QNetworkReplyWrapper : public QObject {
Q_OBJECT
public:
- QNetworkReplyWrapper(QNetworkReply*, QObject* parent = 0);
+ QNetworkReplyWrapper(QNetworkReplyHandlerCallQueue*, QNetworkReply*, bool sniffMIMETypes, QObject* parent = 0);
~QNetworkReplyWrapper();
QNetworkReply* reply() const { return m_reply; }
QNetworkReply* release();
+ void synchronousLoad() { receiveMetaData(); }
+
QUrl redirectionTargetUrl() const { return m_redirectionTargetUrl; }
QString encoding() const { return m_encoding; }
- QString advertisedMimeType() const { return m_advertisedMimeType; }
+ QString advertisedMIMEType() const { return m_advertisedMIMEType; }
+ QString mimeType() const { return m_sniffedMIMEType.isEmpty() ? m_advertisedMIMEType : m_sniffedMIMEType; }
-Q_SIGNALS:
- void finished();
- void metaDataChanged();
- void readyRead();
- void uploadProgress(qint64 bytesSent, qint64 bytesTotal);
+ bool responseContainsData() const { return m_responseContainsData; }
+ bool wasRedirected() const { return m_redirectionTargetUrl.isValid(); }
private Q_SLOTS:
void receiveMetaData();
void didReceiveFinished();
+ void didReceiveReadyRead();
+ void receiveSniffedMIMEType();
private:
void resetConnections();
+ void emitMetaDataChanged();
QNetworkReply* m_reply;
QUrl m_redirectionTargetUrl;
QString m_encoding;
- QString m_advertisedMimeType;
+ QNetworkReplyHandlerCallQueue* m_queue;
+ bool m_responseContainsData;
+
+ QString m_advertisedMIMEType;
+
+ QString m_sniffedMIMEType;
+ OwnPtr<QtMIMETypeSniffer> m_sniffer;
+ bool m_sniffMIMETypes;
};
class QNetworkReplyHandler : public QObject
@@ -79,7 +114,7 @@ public:
};
QNetworkReplyHandler(ResourceHandle*, LoadType, bool deferred = false);
- void setLoadingDeferred(bool);
+ void setLoadingDeferred(bool deferred) { m_queue.setDeferSignals(deferred); }
QNetworkReply* reply() const { return m_replyWrapper ? m_replyWrapper->reply() : 0; }
@@ -87,38 +122,30 @@ public:
QNetworkReply* release();
-public slots:
void finish();
- void sendResponseIfNeeded();
void forwardData();
+ void sendResponseIfNeeded();
+
+private slots:
void uploadProgress(qint64 bytesSent, qint64 bytesTotal);
private:
void start();
- void resetState();
String httpMethod() const;
- void resumeDeferredLoad();
void redirect(ResourceResponse&, const QUrl&);
bool wasAborted() const { return !m_resourceHandle; }
- QNetworkReply* sendNetworkRequest();
+ QNetworkReply* sendNetworkRequest(QNetworkAccessManager*, const ResourceRequest&);
- QNetworkReplyWrapper* m_replyWrapper;
+ OwnPtr<QNetworkReplyWrapper> m_replyWrapper;
ResourceHandle* m_resourceHandle;
- bool m_redirected;
- bool m_responseSent;
- bool m_responseContainsData;
LoadType m_loadType;
QNetworkAccessManager::Operation m_method;
QNetworkRequest m_request;
- bool m_deferred;
-
// defer state holding
- bool m_hasStarted;
- bool m_callFinishOnResume;
- bool m_callSendResponseIfNeededOnResume;
- bool m_callForwardDataOnResume;
int m_redirectionTries;
+
+ QNetworkReplyHandlerCallQueue m_queue;
};
// Self destructing QIODevice for FormData
diff --git a/Source/WebCore/platform/network/qt/QtMIMETypeSniffer.cpp b/Source/WebCore/platform/network/qt/QtMIMETypeSniffer.cpp
new file mode 100644
index 0000000..e719b80
--- /dev/null
+++ b/Source/WebCore/platform/network/qt/QtMIMETypeSniffer.cpp
@@ -0,0 +1,63 @@
+/*
+ Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+#include "QtMIMETypeSniffer.h"
+
+#include "MIMESniffing.h"
+#include <QCoreApplication>
+#include <QNetworkReply>
+
+QtMIMETypeSniffer::QtMIMETypeSniffer(QNetworkReply* reply, const QString& advertisedMimeType, bool isSupportedImageType)
+ : QObject(0)
+ , m_reply(reply)
+ , m_mimeType(advertisedMimeType)
+ , m_sniffer(advertisedMimeType.toLatin1().constData(), isSupportedImageType)
+ , m_isFinished(false)
+{
+ m_isFinished = !m_sniffer.isValid() || sniff();
+ if (m_isFinished)
+ return;
+
+ connect(m_reply, SIGNAL(readyRead()), this, SLOT(trySniffing()));
+ connect(m_reply, SIGNAL(finished()), this, SLOT(trySniffing()));
+}
+
+bool QtMIMETypeSniffer::sniff()
+{
+ if (!m_reply->isFinished() && m_reply->bytesAvailable() < m_sniffer.dataSize())
+ return false;
+
+ QByteArray data = m_reply->peek(m_sniffer.dataSize());
+ const char* sniffedMimeType = m_sniffer.sniff(data.constData(), data.size());
+ if (sniffedMimeType)
+ m_mimeType = QString::fromLatin1(sniffedMimeType);
+ return true;
+}
+
+void QtMIMETypeSniffer::trySniffing()
+{
+ if (!sniff())
+ return;
+
+ m_reply->disconnect(this);
+ QCoreApplication::removePostedEvents(this, QEvent::MetaCall);
+ m_isFinished = true;
+ emit finished();
+}
diff --git a/Source/WebCore/platform/network/qt/QtMIMETypeSniffer.h b/Source/WebCore/platform/network/qt/QtMIMETypeSniffer.h
new file mode 100644
index 0000000..5424906
--- /dev/null
+++ b/Source/WebCore/platform/network/qt/QtMIMETypeSniffer.h
@@ -0,0 +1,50 @@
+/*
+ Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef QtMIMETypeSniffer_h
+#define QtMIMETypeSniffer_h
+
+#include "MIMESniffing.h"
+#include <QObject>
+
+class QNetworkReply;
+
+class QtMIMETypeSniffer : public QObject {
+ Q_OBJECT
+public:
+ QtMIMETypeSniffer(QNetworkReply*, const QString& advertisedMimeType, bool isSupportedImageType);
+ QString mimeType() const { return m_mimeType; }
+ bool isFinished() const { return m_isFinished; }
+
+signals:
+ void finished();
+
+private slots:
+ void trySniffing();
+
+private:
+ bool sniff();
+
+ QNetworkReply* m_reply;
+ QString m_mimeType;
+ MIMESniffer m_sniffer;
+ bool m_isFinished;
+};
+
+#endif // QtMIMETypeSniffer_h
diff --git a/Source/WebCore/platform/network/qt/ResourceHandleQt.cpp b/Source/WebCore/platform/network/qt/ResourceHandleQt.cpp
index a6da432..642d0a6 100644
--- a/Source/WebCore/platform/network/qt/ResourceHandleQt.cpp
+++ b/Source/WebCore/platform/network/qt/ResourceHandleQt.cpp
@@ -53,62 +53,22 @@ namespace WebCore {
class WebCoreSynchronousLoader : public ResourceHandleClient {
public:
- WebCoreSynchronousLoader();
-
- void waitForCompletion();
-
- virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&);
- virtual void didReceiveData(ResourceHandle*, const char*, int, int lengthReceived);
- virtual void didFinishLoading(ResourceHandle*, double /*finishTime*/);
- virtual void didFail(ResourceHandle*, const ResourceError&);
-
- ResourceResponse resourceResponse() const { return m_response; }
- ResourceError resourceError() const { return m_error; }
- Vector<char> data() const { return m_data; }
-
- void setReplyFinished(bool finished) { m_replyFinished = finished; }
-
+ WebCoreSynchronousLoader(ResourceError& error, ResourceResponse& response, Vector<char>& data)
+ : m_error(error)
+ , m_response(response)
+ , m_data(data)
+ {}
+
+ virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse& response) { m_response = response; }
+ virtual void didReceiveData(ResourceHandle*, const char* data, int length, int) { m_data.append(data, length); }
+ virtual void didFinishLoading(ResourceHandle*, double /*finishTime*/) {}
+ virtual void didFail(ResourceHandle*, const ResourceError& error) { m_error = error; }
private:
- ResourceResponse m_response;
- ResourceError m_error;
- Vector<char> m_data;
- QEventLoop m_eventLoop;
- bool m_replyFinished;
+ ResourceError& m_error;
+ ResourceResponse& m_response;
+ Vector<char>& m_data;
};
-WebCoreSynchronousLoader::WebCoreSynchronousLoader()
- : m_replyFinished(false)
-{
-}
-
-void WebCoreSynchronousLoader::didReceiveResponse(ResourceHandle*, const ResourceResponse& response)
-{
- m_response = response;
-}
-
-void WebCoreSynchronousLoader::didReceiveData(ResourceHandle*, const char* data, int length, int)
-{
- m_data.append(data, length);
-}
-
-void WebCoreSynchronousLoader::didFinishLoading(ResourceHandle*, double)
-{
- if (!m_replyFinished)
- m_eventLoop.exit();
-}
-
-void WebCoreSynchronousLoader::didFail(ResourceHandle*, const ResourceError& error)
-{
- m_error = error;
- if (!m_replyFinished)
- m_eventLoop.exit();
-}
-
-void WebCoreSynchronousLoader::waitForCompletion()
-{
- m_eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
-}
-
ResourceHandleInternal::~ResourceHandleInternal()
{
}
@@ -191,7 +151,7 @@ PassRefPtr<SharedBuffer> ResourceHandle::bufferedData()
void ResourceHandle::loadResourceSynchronously(NetworkingContext* context, const ResourceRequest& request, StoredCredentials /*storedCredentials*/, ResourceError& error, ResourceResponse& response, Vector<char>& data)
{
- WebCoreSynchronousLoader syncLoader;
+ WebCoreSynchronousLoader syncLoader(error, response, data);
RefPtr<ResourceHandle> handle = adoptRef(new ResourceHandle(request, &syncLoader, true, false));
ResourceHandleInternal* d = handle->getInternal();
@@ -204,20 +164,10 @@ void ResourceHandle::loadResourceSynchronously(NetworkingContext* context, const
d->m_firstRequest.setURL(urlWithCredentials);
}
d->m_context = context;
- d->m_job = new QNetworkReplyHandler(handle.get(), QNetworkReplyHandler::SynchronousLoad);
-
- QNetworkReply* reply = d->m_job->reply();
- // When using synchronous calls, we are finished when reaching this point.
- if (reply->isFinished()) {
- syncLoader.setReplyFinished(true);
- d->m_job->forwardData();
- d->m_job->finish();
- } else
- syncLoader.waitForCompletion();
-
- error = syncLoader.resourceError();
- data = syncLoader.data();
- response = syncLoader.resourceResponse();
+
+ // starting in deferred mode gives d->m_job the chance of being set before sending the request.
+ d->m_job = new QNetworkReplyHandler(handle.get(), QNetworkReplyHandler::SynchronousLoad, true);
+ d->m_job->setLoadingDeferred(false);
}
void ResourceHandle::platformSetDefersLoading(bool defers)
diff --git a/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp b/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp
index e5da0e3..dc22fca 100644
--- a/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp
+++ b/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp
@@ -69,7 +69,7 @@ public:
~WebCoreSynchronousLoader();
virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&);
- virtual void didReceiveData(ResourceHandle*, const char*, int, int lengthReceived);
+ virtual void didReceiveData(ResourceHandle*, const char*, int, int encodedDataLength);
virtual void didFinishLoading(ResourceHandle*, double /*finishTime*/);
virtual void didFail(ResourceHandle*, const ResourceError&);
@@ -135,11 +135,6 @@ ResourceHandleInternal::~ResourceHandleInternal()
{
if (m_soupRequest)
g_object_set_data(G_OBJECT(m_soupRequest.get()), "webkit-resource", 0);
-
- if (m_idleHandler) {
- g_source_remove(m_idleHandler);
- m_idleHandler = 0;
- }
}
ResourceHandle::~ResourceHandle()
diff --git a/Source/WebCore/platform/network/win/ResourceHandleWin.cpp b/Source/WebCore/platform/network/win/ResourceHandleWin.cpp
index dc5adc8..3e596be 100644
--- a/Source/WebCore/platform/network/win/ResourceHandleWin.cpp
+++ b/Source/WebCore/platform/network/win/ResourceHandleWin.cpp
@@ -85,7 +85,7 @@ public:
HINTERNET internetHandle() const { return m_internetHandle; }
virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&);
- virtual void didReceiveData(ResourceHandle*, const char*, int, int lengthReceived);
+ virtual void didReceiveData(ResourceHandle*, const char*, int, int encodedDataLength);
virtual void didFinishLoading(ResourceHandle*, double /*finishTime*/);
virtual void didFail(ResourceHandle*, const ResourceError&);
diff --git a/Source/WebCore/platform/qt/ClipboardQt.cpp b/Source/WebCore/platform/qt/ClipboardQt.cpp
index c14d362..723cdd4 100644
--- a/Source/WebCore/platform/qt/ClipboardQt.cpp
+++ b/Source/WebCore/platform/qt/ClipboardQt.cpp
@@ -299,6 +299,7 @@ void ClipboardQt::declareAndWriteDragImage(Element* element, const KURL& url, co
m_writableData->setText(title);
m_writableData->setUrls(urls);
+ m_writableData->setHtml(createMarkup(element, IncludeNode, 0, AbsoluteURLs));
#ifndef QT_NO_CLIPBOARD
if (isForCopyAndPaste())
QApplication::clipboard()->setMimeData(m_writableData);
diff --git a/Source/WebCore/platform/qt/QtMobileWebStyle.cpp b/Source/WebCore/platform/qt/QtMobileWebStyle.cpp
index 240faa5..6ca1817 100644
--- a/Source/WebCore/platform/qt/QtMobileWebStyle.cpp
+++ b/Source/WebCore/platform/qt/QtMobileWebStyle.cpp
@@ -34,12 +34,13 @@ static inline void drawRectangularControlBackground(QPainter* painter, const QPe
{
QPen oldPen = painter->pen();
QBrush oldBrush = painter->brush();
+ painter->setRenderHint(QPainter::Antialiasing, true);
painter->setPen(pen);
painter->setBrush(brush);
int line = 1;
- painter->drawRect(rect.adjusted(line, line, -line, -line));
-
+ painter->drawRoundedRect(rect.adjusted(line, line, -line, -line),
+ /* xRadius */ 5.0, /* yRadious */ 5.0);
painter->setPen(oldPen);
painter->setBrush(oldBrush);
}
@@ -71,8 +72,8 @@ QPixmap QtMobileWebStyle::findChecker(const QRect& rect, bool disabled) const
{
int size = qMin(rect.width(), rect.height());
QPixmap result;
- static const QString prefix = "$qt-maemo5-" + QLatin1String(metaObject()->className()) + "-checker-";
- QString key = prefix + QString::number(size) + "-" + (disabled ? "disabled" : "enabled");
+ static const QString prefix = QLatin1String("$qt-maemo5-") + QLatin1String(metaObject()->className())+ QLatin1String("-checker-");
+ QString key = prefix + QString::number(size) + QLatin1String("-") + (disabled ? QLatin1String("disabled") : QLatin1String("enabled"));
if (!QPixmapCache::find(key, result)) {
result = QPixmap(size, size);
result.fill(Qt::transparent);
@@ -87,8 +88,10 @@ void QtMobileWebStyle::drawRadio(QPainter* painter, const QSize& size, bool chec
{
painter->setRenderHint(QPainter::Antialiasing, true);
+ // get minor size to do not paint a wide elipse
+ qreal squareSize = qMin(size.width(), size.height());
// deflate one pixel
- QRect rect = QRect(QPoint(1, 1), QSize(size.width() - 2, size.height() - 2));
+ QRect rect = QRect(QPoint(1, 1), QSize(squareSize - 2, squareSize - 2));
const QPoint centerGradient(rect.bottomRight() * 0.7);
QRadialGradient radialGradient(centerGradient, centerGradient.x() - 1);
@@ -115,9 +118,9 @@ void QtMobileWebStyle::drawRadio(QPainter* painter, const QSize& size, bool chec
QPixmap QtMobileWebStyle::findRadio(const QSize& size, bool checked, bool disabled) const
{
QPixmap result;
- static const QString prefix = "$qt-maemo5-" + QLatin1String(metaObject()->className()) + "-radio-";
- QString key = prefix + QString::number(size.width()) + "-" + QString::number(size.height()) +
- + "-" + (disabled ? "disabled" : "enabled") + (checked ? "-checked" : "");
+ static const QString prefix = QLatin1String("$qt-maemo5-") + QLatin1String(metaObject()->className()) + QLatin1String("-radio-");
+ QString key = prefix + QString::number(size.width()) + QLatin1String("-") + QString::number(size.height()) + QLatin1String("-")
+ + (disabled ? QLatin1String("disabled") : QLatin1String("enabled")) + (checked ? QLatin1String("-checked") : QLatin1String(""));
if (!QPixmapCache::find(key, result)) {
result = QPixmap(size);
result.fill(Qt::transparent);
@@ -144,7 +147,9 @@ void QtMobileWebStyle::drawControl(ControlElement element, const QStyleOption* o
linearGradient.setColorAt(0.5, Qt::white);
}
- drawRectangularControlBackground(painter, QPen(disabled ? Qt::lightGray : Qt::darkGray), rect, linearGradient);
+ painter->setPen(QPen(disabled ? Qt::lightGray : Qt::darkGray));
+ painter->setBrush(linearGradient);
+ painter->drawRect(rect);
rect.adjust(1, 1, -1, -1);
if (option->state & State_Off)
@@ -167,10 +172,75 @@ void QtMobileWebStyle::drawControl(ControlElement element, const QStyleOption* o
painter->drawPixmap(option->rect.x(), option->rect.y(), radio);
break;
}
+ case CE_PushButton: {
+ const bool disabled = !(option->state & State_Enabled);
+ QRect rect = option->rect;
+ QPen pen(Qt::darkGray, 1.0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
+ painter->setPen(pen);
+
+ const bool sunken = (option->state & State_Sunken);
+ if (sunken) {
+ drawRectangularControlBackground(painter, pen, rect, QBrush(Qt::darkGray));
+ break;
+ }
+
+ QLinearGradient linearGradient;
+ if (disabled) {
+ linearGradient.setStart(rect.bottomLeft());
+ linearGradient.setFinalStop(rect.topLeft());
+ linearGradient.setColorAt(0.0, Qt::gray);
+ linearGradient.setColorAt(1.0, Qt::white);
+ } else {
+ linearGradient.setStart(rect.bottomLeft());
+ linearGradient.setFinalStop(QPoint(rect.bottomLeft().x(),
+ rect.bottomLeft().y() - /* offset limit for gradient */ 20));
+ linearGradient.setColorAt(0.0, Qt::gray);
+ linearGradient.setColorAt(0.4, Qt::white);
+ }
+
+ drawRectangularControlBackground(painter, pen, rect, linearGradient);
+ break;
+ }
default:
QWindowsStyle::drawControl(element, option, painter, widget);
}
}
+void QtMobileWebStyle::drawPrimitive(PrimitiveElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget) const
+{
+ switch (element) {
+ case QStyle::PE_PanelLineEdit: {
+ const bool disabled = !(option->state & State_Enabled);
+ const bool sunken = (option->state & State_Sunken);
+ QRect rect = option->rect;
+ QPen pen(Qt::darkGray, 1.0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
+ painter->setPen(pen);
+
+ if (sunken) {
+ drawRectangularControlBackground(painter, pen, rect, QBrush(Qt::darkGray));
+ break;
+ }
+
+ QLinearGradient linearGradient;
+ if (disabled) {
+ linearGradient.setStart(rect.topLeft());
+ linearGradient.setFinalStop(rect.bottomLeft());
+ linearGradient.setColorAt(0.0, Qt::lightGray);
+ linearGradient.setColorAt(1.0, Qt::white);
+ } else {
+ linearGradient.setStart(rect.topLeft());
+ linearGradient.setFinalStop(QPoint(rect.topLeft().x(),
+ rect.topLeft().y() + /* offset limit for gradient */ 20));
+ linearGradient.setColorAt(0.0, Qt::darkGray);
+ linearGradient.setColorAt(0.35, Qt::white);
+ }
+
+ drawRectangularControlBackground(painter, pen, rect, linearGradient);
+ break;
+ }
+ default:
+ QWindowsStyle::drawPrimitive(element, option, painter, widget);
+ }
+}
void QtMobileWebStyle::drawMultipleComboButton(QPainter* painter, const QSize& size, QColor color) const
{
@@ -230,10 +300,10 @@ QPixmap QtMobileWebStyle::findComboButton(const QSize& size, bool multiple, bool
if (imageSize.isNull())
return QPixmap();
- static const QString prefix = "$qt-maemo5-" + QLatin1String(metaObject()->className()) + "-combo-";
- QString key = prefix + (multiple ? "multiple-" : "simple-") +
- QString::number(imageSize.width()) + "-" + QString::number(imageSize.height()) +
- + "-" + (disabled ? "disabled" : "enabled");
+ static const QString prefix = QLatin1String("$qt-maemo5-") + QLatin1String(metaObject()->className()) + QLatin1String("-combo-");
+ QString key = prefix + (multiple ? QLatin1String("multiple-") : QLatin1String("simple-"))
+ + QString::number(imageSize.width()) + QLatin1String("-") + QString::number(imageSize.height())
+ + QLatin1String("-") + (disabled ? QLatin1String("disabled") : QLatin1String("enabled"));
if (!QPixmapCache::find(key, result)) {
result = QPixmap(imageSize);
result.fill(Qt::transparent);
@@ -251,7 +321,6 @@ void QtMobileWebStyle::drawComplexControl(ComplexControl control, const QStyleOp
{
switch (control) {
case CC_ComboBox: {
-
bool multiple = false;
const bool disabled = !(option->state & State_Enabled);
@@ -272,7 +341,25 @@ void QtMobileWebStyle::drawComplexControl(ComplexControl control, const QStyleOp
if (!(cmb->subControls & SC_ComboBoxArrow))
break;
- QRect rect = subControlRect(CC_ComboBox, cmb, SC_ComboBoxArrow, widget);
+ QRect rect = option->rect;
+ QPen pen(Qt::darkGray, 1.0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
+ QLinearGradient linearGradient;
+ if (disabled) {
+ linearGradient.setStart(rect.bottomLeft());
+ linearGradient.setFinalStop(rect.topLeft());
+ linearGradient.setColorAt(0.0, Qt::gray);
+ linearGradient.setColorAt(1.0, Qt::white);
+ } else {
+ linearGradient.setStart(rect.bottomLeft());
+ linearGradient.setFinalStop(QPoint(rect.bottomLeft().x(),
+ rect.bottomLeft().y() - /* offset limit for gradient */ 20));
+ linearGradient.setColorAt(0.0, Qt::gray);
+ linearGradient.setColorAt(0.4, Qt::white);
+ }
+
+ drawRectangularControlBackground(painter, pen, rect, linearGradient);
+
+ rect = subControlRect(CC_ComboBox, cmb, SC_ComboBoxArrow, widget);
QPixmap pic = findComboButton(rect.size(), multiple, disabled);
if (pic.isNull())
@@ -291,3 +378,4 @@ void QtMobileWebStyle::drawComplexControl(ComplexControl control, const QStyleOp
QWindowsStyle::drawComplexControl(control, option, painter, widget);
}
}
+
diff --git a/Source/WebCore/platform/qt/QtMobileWebStyle.h b/Source/WebCore/platform/qt/QtMobileWebStyle.h
index 779bd26..1b99d2b 100644
--- a/Source/WebCore/platform/qt/QtMobileWebStyle.h
+++ b/Source/WebCore/platform/qt/QtMobileWebStyle.h
@@ -27,8 +27,9 @@ class QtMobileWebStyle : public QWindowsStyle {
public:
QtMobileWebStyle();
- void drawControl(ControlElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget = 0) const;
- void drawComplexControl(ComplexControl cc, const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget = 0) const;
+ void drawControl(ControlElement, const QStyleOption*, QPainter*, const QWidget*) const;
+ void drawComplexControl(ComplexControl, const QStyleOptionComplex*, QPainter*, const QWidget*) const;
+ void drawPrimitive(PrimitiveElement, const QStyleOption*, QPainter*, const QWidget*) const;
private:
void drawChecker(QPainter* painter, int size, QColor color) const;
diff --git a/Source/WebCore/platform/qt/RenderThemeQt.cpp b/Source/WebCore/platform/qt/RenderThemeQt.cpp
index cc654d5..8cb59c1 100644
--- a/Source/WebCore/platform/qt/RenderThemeQt.cpp
+++ b/Source/WebCore/platform/qt/RenderThemeQt.cpp
@@ -46,6 +46,9 @@
#if USE(QT_MOBILE_THEME)
#include "QtMobileWebStyle.h"
#endif
+#if ENABLE(VIDEO)
+#include "MediaControlElements.h"
+#endif
#include "NotImplemented.h"
#include "PaintInfo.h"
#include "Page.h"
@@ -78,7 +81,6 @@
#include <QStyleOptionSlider>
#include <QWidget>
-
namespace WebCore {
using namespace HTMLNames;
@@ -105,6 +107,16 @@ static const float minSearchFieldResultsDecorationSize = 9;
static const float maxSearchFieldResultsDecorationSize = 30;
static const float defaultSearchFieldResultsButtonWidth = 18;
+#if USE(QT_MOBILE_THEME)
+namespace {
+ float buttonPaddingLeft = 18;
+ float buttonPaddingRight = 18;
+ float buttonPaddingTop = 2;
+ float buttonPaddingBottom = 3;
+ float menuListPadding = 9;
+ float textFieldPadding = 5;
+}
+#endif
StylePainter::StylePainter(RenderThemeQt* theme, const PaintInfo& paintInfo)
{
@@ -198,10 +210,13 @@ bool RenderThemeQt::isControlStyled(const RenderStyle* style, const BorderData&
case PushButtonPart:
case ButtonPart:
case MenulistPart:
- // FIXME: Need to add SearchFieldPart if it should be style-able.
+ case SearchFieldPart:
case TextFieldPart:
case TextAreaPart:
- return true;
+ // Test the style to see if the UA border and background match.
+ return (style->border() != border
+ || *style->backgroundLayers() != fill
+ || style->visitedDependentColor(CSSPropertyBackgroundColor) != backgroundColor);
case CheckboxPart:
case RadioPart:
return false;
@@ -258,9 +273,6 @@ String RenderThemeQt::extraDefaultStyleSheet()
#if ENABLE(NO_LISTBOX_RENDERING)
result += String(themeQtNoListboxesUserAgentStyleSheet, sizeof(themeQtNoListboxesUserAgentStyleSheet));
#endif
-#if USE(QT_MOBILE_THEME)
- result += String(themeQtMobileUserAgentStyleSheet, sizeof(themeQtMobileUserAgentStyleSheet));
-#endif
return result;
}
@@ -448,7 +460,6 @@ void RenderThemeQt::computeSizeBasedOnStyle(RenderStyle* renderStyle) const
case SearchFieldPart:
case TextFieldPart: {
int padding = findFrameLineWidth(style);
-
renderStyle->setPaddingLeft(Length(padding, Fixed));
renderStyle->setPaddingRight(Length(padding, Fixed));
renderStyle->setPaddingTop(Length(padding, Fixed));
@@ -458,7 +469,6 @@ void RenderThemeQt::computeSizeBasedOnStyle(RenderStyle* renderStyle) const
default:
break;
}
-
// If the width and height are both specified, then we have nothing to do.
if (!renderStyle->width().isIntrinsicOrAuto() && !renderStyle->height().isAuto())
return;
@@ -480,6 +490,7 @@ void RenderThemeQt::computeSizeBasedOnStyle(RenderStyle* renderStyle) const
size = QSize(radioWidth, radioWidth);
break;
}
+#if !USE(QT_MOBILE_THEME)
case PushButtonPart:
case ButtonPart: {
QStyleOptionButton styleOption;
@@ -509,6 +520,7 @@ void RenderThemeQt::computeSizeBasedOnStyle(RenderStyle* renderStyle) const
size.setHeight(menuListSize.height());
break;
}
+#endif
default:
break;
}
@@ -564,13 +576,14 @@ void RenderThemeQt::adjustButtonStyle(CSSStyleSelector* selector, RenderStyle* s
fontDescription.setComputedSize(style->fontSize());
#endif
+#if !USE(QT_MOBILE_THEME)
FontFamily fontFamily;
fontFamily.setFamily(m_buttonFontFamily);
fontDescription.setFamily(fontFamily);
style->setFontDescription(fontDescription);
style->font().update(selector->fontSelector());
+#endif
style->setLineHeight(RenderStyle::initialLineHeight());
-
setButtonSize(style);
setButtonPadding(style);
}
@@ -580,6 +593,7 @@ void RenderThemeQt::setButtonSize(RenderStyle* style) const
computeSizeBasedOnStyle(style);
}
+#if !USE(QT_MOBILE_THEME)
void RenderThemeQt::setButtonPadding(RenderStyle* style) const
{
QStyleOptionButton styleOption;
@@ -609,12 +623,22 @@ void RenderThemeQt::setButtonPadding(RenderStyle* style) const
// Can't use this right now because we don't have the baseline to compensate
// paddingBottom = layoutRect.bottom() - contentsRect.bottom();
}
-
style->setPaddingLeft(Length(paddingLeft, Fixed));
style->setPaddingRight(Length(paddingRight, Fixed));
style->setPaddingTop(Length(paddingTop, Fixed));
style->setPaddingBottom(Length(paddingBottom, Fixed));
}
+#else
+void RenderThemeQt::setButtonPadding(RenderStyle* style) const
+{
+ if (!style)
+ return;
+ style->setPaddingLeft(Length(buttonPaddingLeft, Fixed));
+ style->setPaddingRight(Length(buttonPaddingRight, Fixed));
+ style->setPaddingTop(Length(buttonPaddingTop, Fixed));
+ style->setPaddingBottom(Length(buttonPaddingBottom, Fixed));
+}
+#endif
bool RenderThemeQt::paintButton(RenderObject* o, const PaintInfo& i, const IntRect& r)
{
@@ -650,6 +674,10 @@ void RenderThemeQt::adjustTextFieldStyle(CSSStyleSelector*, RenderStyle* style,
style->resetBorder();
style->resetPadding();
computeSizeBasedOnStyle(style);
+#if USE(QT_MOBILE_THEME)
+ style->setPaddingLeft(Length(textFieldPadding, Fixed));
+ style->setPaddingRight(Length(textFieldPadding, Fixed));
+#endif
}
bool RenderThemeQt::paintTextField(RenderObject* o, const PaintInfo& i, const IntRect& r)
@@ -662,7 +690,12 @@ bool RenderThemeQt::paintTextField(RenderObject* o, const PaintInfo& i, const In
initStyleOption(p.widget, panel);
panel.rect = r;
panel.lineWidth = findFrameLineWidth(qStyle());
+#if USE(QT_MOBILE_THEME)
+ if (isPressed(o))
+ panel.state |= QStyle::State_Sunken;
+#else
panel.state |= QStyle::State_Sunken;
+#endif
panel.features = QStyleOptionFrameV2::None;
// Get the correct theme data for a text field
@@ -675,7 +708,6 @@ bool RenderThemeQt::paintTextField(RenderObject* o, const PaintInfo& i, const In
// Now paint the text field.
p.drawPrimitive(QStyle::PE_PanelLineEdit, panel);
-
return false;
}
@@ -703,6 +735,9 @@ void RenderThemeQt::adjustMenuListStyle(CSSStyleSelector*, RenderStyle* style, E
// Add in the padding that we'd like to use.
setPopupPadding(style);
+#if USE(QT_MOBILE_THEME)
+ style->setPaddingLeft(Length(menuListPadding, Fixed));
+#endif
}
void RenderThemeQt::setPopupPadding(RenderStyle* style) const
@@ -1076,9 +1111,6 @@ ControlPart RenderThemeQt::initializeCommonQStyleOptions(QStyleOption& option, R
// Default bits: no focus, no mouse over
option.state &= ~(QStyle::State_HasFocus | QStyle::State_MouseOver);
- if (!isEnabled(o))
- option.state &= ~QStyle::State_Enabled;
-
if (isReadOnlyControl(o))
// Readonly is supported on textfields.
option.state |= QStyle::State_ReadOnly;
@@ -1089,6 +1121,12 @@ ControlPart RenderThemeQt::initializeCommonQStyleOptions(QStyleOption& option, R
option.state |= QStyle::State_MouseOver;
setPaletteFromPageClientIfExists(option.palette);
+
+ if (!isEnabled(o)) {
+ option.palette.setCurrentColorGroup(QPalette::Disabled);
+ option.state &= ~QStyle::State_Enabled;
+ }
+
RenderStyle* style = o->style();
if (!style)
return NoControlPart;
@@ -1156,16 +1194,6 @@ private:
QTransform m_originalTransform;
};
-HTMLMediaElement* RenderThemeQt::getMediaElementFromRenderObject(RenderObject* o) const
-{
- Node* node = o->node();
- Node* mediaNode = node ? node->shadowAncestorNode() : 0;
- if (!mediaNode || (!mediaNode->hasTagName(videoTag) && !mediaNode->hasTagName(audioTag)))
- return 0;
-
- return static_cast<HTMLMediaElement*>(mediaNode);
-}
-
double RenderThemeQt::mediaControlsBaselineOpacity() const
{
return 0.4;
@@ -1189,7 +1217,7 @@ QColor RenderThemeQt::getMediaControlForegroundColor(RenderObject* o) const
bool RenderThemeQt::paintMediaFullscreenButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
{
- HTMLMediaElement* mediaElement = getMediaElementFromRenderObject(o);
+ HTMLMediaElement* mediaElement = toParentMediaElement(o);
if (!mediaElement)
return false;
@@ -1213,7 +1241,7 @@ bool RenderThemeQt::paintMediaFullscreenButton(RenderObject* o, const PaintInfo&
bool RenderThemeQt::paintMediaMuteButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
{
- HTMLMediaElement* mediaElement = getMediaElementFromRenderObject(o);
+ HTMLMediaElement* mediaElement = toParentMediaElement(o);
if (!mediaElement)
return false;
@@ -1237,7 +1265,7 @@ bool RenderThemeQt::paintMediaMuteButton(RenderObject* o, const PaintInfo& paint
bool RenderThemeQt::paintMediaPlayButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
{
- HTMLMediaElement* mediaElement = getMediaElementFromRenderObject(o);
+ HTMLMediaElement* mediaElement = toParentMediaElement(o);
if (!mediaElement)
return false;
@@ -1356,7 +1384,7 @@ bool RenderThemeQt::paintMediaVolumeSliderThumb(RenderObject *o, const PaintInfo
bool RenderThemeQt::paintMediaSliderTrack(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
{
- HTMLMediaElement* mediaElement = getMediaElementFromRenderObject(o);
+ HTMLMediaElement* mediaElement = toParentMediaElement(o);
if (!mediaElement)
return false;
diff --git a/Source/WebCore/platform/qt/RenderThemeQt.h b/Source/WebCore/platform/qt/RenderThemeQt.h
index 6981641..b436a03 100644
--- a/Source/WebCore/platform/qt/RenderThemeQt.h
+++ b/Source/WebCore/platform/qt/RenderThemeQt.h
@@ -158,8 +158,8 @@ protected:
virtual bool paintMediaVolumeSliderThumb(RenderObject*, const PaintInfo&, const IntRect&);
virtual String formatMediaControlsCurrentTime(float currentTime, float duration) const;
virtual String formatMediaControlsRemainingTime(float currentTime, float duration) const;
+ virtual bool hasOwnDisabledStateHandlingFor(ControlPart) const { return true; }
private:
- HTMLMediaElement* getMediaElementFromRenderObject(RenderObject* o) const;
void paintMediaBackground(QPainter* painter, const IntRect& r) const;
double mediaControlsBaselineOpacity() const;
QColor getMediaControlForegroundColor(RenderObject* o = 0) const;
diff --git a/Source/WebCore/platform/qt/ScrollbarThemeQt.cpp b/Source/WebCore/platform/qt/ScrollbarThemeQt.cpp
index 67226b0..079c676 100644
--- a/Source/WebCore/platform/qt/ScrollbarThemeQt.cpp
+++ b/Source/WebCore/platform/qt/ScrollbarThemeQt.cpp
@@ -110,8 +110,12 @@ static QStyleOptionSlider* styleOptionSlider(Scrollbar* scrollbar, QWidget* widg
if (scrollbar->controlSize() != RegularScrollbar)
opt.state |= QStyle::State_Mini;
opt.orientation = (scrollbar->orientation() == VerticalScrollbar) ? Qt::Vertical : Qt::Horizontal;
+
if (scrollbar->orientation() == HorizontalScrollbar)
opt.state |= QStyle::State_Horizontal;
+ else
+ opt.state &= ~QStyle::State_Horizontal;
+
opt.sliderValue = scrollbar->value();
opt.sliderPosition = opt.sliderValue;
opt.pageStep = scrollbar->pageStep();
@@ -190,6 +194,9 @@ void ScrollbarThemeQt::invalidatePart(Scrollbar* scrollbar, ScrollbarPart)
int ScrollbarThemeQt::scrollbarThickness(ScrollbarControlSize controlSize)
{
+#if USE(QT_MOBILE_THEME)
+ return 0;
+#endif
QStyleOptionSlider o;
o.orientation = Qt::Vertical;
o.state &= ~QStyle::State_Horizontal;
diff --git a/Source/WebCore/platform/text/BidiResolver.h b/Source/WebCore/platform/text/BidiResolver.h
index 5b92ee2..c6efdd8 100644
--- a/Source/WebCore/platform/text/BidiResolver.h
+++ b/Source/WebCore/platform/text/BidiResolver.h
@@ -23,6 +23,7 @@
#define BidiResolver_h
#include "BidiContext.h"
+#include "BidiRunList.h"
#include <wtf/Noncopyable.h>
#include <wtf/PassRefPtr.h>
#include <wtf/Vector.h>
@@ -147,17 +148,15 @@ enum VisualDirectionOverride {
VisualRightToLeftOverride
};
+// BidiResolver is WebKit's implementation of the Unicode Bidi Algorithm
+// http://unicode.org/reports/tr9
template <class Iterator, class Run> class BidiResolver {
WTF_MAKE_NONCOPYABLE(BidiResolver);
public:
BidiResolver()
: m_direction(WTF::Unicode::OtherNeutral)
, m_reachedEndOfLine(false)
- , emptyRun(true)
- , m_firstRun(0)
- , m_lastRun(0)
- , m_logicallyLastRun(0)
- , m_runCount(0)
+ , m_emptyRun(true)
{
}
@@ -186,22 +185,16 @@ public:
void createBidiRunsForLine(const Iterator& end, VisualDirectionOverride = NoVisualOverride, bool hardLineBreak = false);
- Run* firstRun() const { return m_firstRun; }
- Run* lastRun() const { return m_lastRun; }
- Run* logicallyLastRun() const { return m_logicallyLastRun; }
- unsigned runCount() const { return m_runCount; }
+ BidiRunList<Run>& runs() { return m_runs; }
- void addRun(Run*);
- void prependRun(Run*);
-
- void moveRunToEnd(Run*);
- void moveRunToBeginning(Run*);
-
- void deleteRuns();
+ // FIXME: This used to be part of deleteRuns() but was a layering violation.
+ // It's unclear if this is still needed.
+ void markCurrentRunEmpty() { m_emptyRun = true; }
protected:
+ // FIXME: Instead of InlineBidiResolvers subclassing this method, we should
+ // pass in some sort of Traits object which knows how to create runs for appending.
void appendRun();
- void reverseRuns(unsigned start, unsigned end);
Iterator m_current;
// sor and eor are "start of run" and "end of run" respectively and correpond
@@ -213,13 +206,13 @@ protected:
WTF::Unicode::Direction m_direction;
Iterator endOfLine;
bool m_reachedEndOfLine;
- Iterator lastBeforeET;
- bool emptyRun;
+ Iterator m_lastBeforeET; // Before a EuropeanNumberTerminator
+ bool m_emptyRun;
+
+ // FIXME: This should not belong to the resolver, but rather be passed
+ // into createBidiRunsForLine by the caller.
+ BidiRunList<Run> m_runs;
- Run* m_firstRun;
- Run* m_lastRun;
- Run* m_logicallyLastRun;
- unsigned m_runCount;
MidpointState<Iterator> m_midpointState;
private:
@@ -234,79 +227,9 @@ private:
};
template <class Iterator, class Run>
-inline void BidiResolver<Iterator, Run>::addRun(Run* run)
-{
- if (!m_firstRun)
- m_firstRun = run;
- else
- m_lastRun->m_next = run;
- m_lastRun = run;
- m_runCount++;
-}
-
-template <class Iterator, class Run>
-inline void BidiResolver<Iterator, Run>::prependRun(Run* run)
-{
- ASSERT(!run->m_next);
-
- if (!m_lastRun)
- m_lastRun = run;
- else
- run->m_next = m_firstRun;
- m_firstRun = run;
- m_runCount++;
-}
-
-template <class Iterator, class Run>
-inline void BidiResolver<Iterator, Run>::moveRunToEnd(Run* run)
-{
- ASSERT(m_firstRun);
- ASSERT(m_lastRun);
- ASSERT(run->m_next);
-
- Run* current = 0;
- Run* next = m_firstRun;
- while (next != run) {
- current = next;
- next = current->next();
- }
-
- if (!current)
- m_firstRun = run->next();
- else
- current->m_next = run->m_next;
-
- run->m_next = 0;
- m_lastRun->m_next = run;
- m_lastRun = run;
-}
-
-template <class Iterator, class Run>
-inline void BidiResolver<Iterator, Run>::moveRunToBeginning(Run* run)
-{
- ASSERT(m_firstRun);
- ASSERT(m_lastRun);
- ASSERT(run != m_firstRun);
-
- Run* current = m_firstRun;
- Run* next = current->next();
- while (next != run) {
- current = next;
- next = current->next();
- }
-
- current->m_next = run->m_next;
- if (run == m_lastRun)
- m_lastRun = current;
-
- run->m_next = m_firstRun;
- m_firstRun = run;
-}
-
-template <class Iterator, class Run>
void BidiResolver<Iterator, Run>::appendRun()
{
- if (!emptyRun && !m_eor.atEnd()) {
+ if (!m_emptyRun && !m_eor.atEnd()) {
unsigned startOffset = m_sor.offset();
unsigned endOffset = m_eor.offset();
@@ -316,7 +239,7 @@ void BidiResolver<Iterator, Run>::appendRun()
}
if (endOffset >= startOffset)
- addRun(new Run(startOffset, endOffset + 1, context(), m_direction));
+ m_runs.addRun(new Run(startOffset, endOffset + 1, context(), m_direction));
m_eor.increment();
m_sor = m_eor;
@@ -357,7 +280,7 @@ void BidiResolver<Iterator, Run>::lowerExplicitEmbeddingLevel(WTF::Unicode::Dire
{
using namespace WTF::Unicode;
- if (!emptyRun && m_eor != m_last) {
+ if (!m_emptyRun && m_eor != m_last) {
checkDirectionInLowerRaiseEmbeddingLevel();
// bidi.sor ... bidi.eor ... bidi.last eor; need to append the bidi.sor-bidi.eor run or extend it through bidi.last
if (from == LeftToRight) {
@@ -380,8 +303,10 @@ void BidiResolver<Iterator, Run>::lowerExplicitEmbeddingLevel(WTF::Unicode::Dire
}
m_eor = m_last;
}
+
appendRun();
- emptyRun = true;
+ m_emptyRun = true;
+
// sor for the new run is determined by the higher level (rule X10)
setLastDir(from);
setLastStrongDir(from);
@@ -393,7 +318,7 @@ void BidiResolver<Iterator, Run>::raiseExplicitEmbeddingLevel(WTF::Unicode::Dire
{
using namespace WTF::Unicode;
- if (!emptyRun && m_eor != m_last) {
+ if (!m_emptyRun && m_eor != m_last) {
checkDirectionInLowerRaiseEmbeddingLevel();
// bidi.sor ... bidi.eor ... bidi.last eor; need to append the bidi.sor-bidi.eor run or extend it through bidi.last
if (to == LeftToRight) {
@@ -418,8 +343,10 @@ void BidiResolver<Iterator, Run>::raiseExplicitEmbeddingLevel(WTF::Unicode::Dire
}
m_eor = m_last;
}
+
appendRun();
- emptyRun = true;
+ m_emptyRun = true;
+
setLastDir(to);
setLastStrongDir(to);
m_eor = Iterator();
@@ -466,75 +393,6 @@ bool BidiResolver<Iterator, Run>::commitExplicitEmbedding()
}
template <class Iterator, class Run>
-void BidiResolver<Iterator, Run>::deleteRuns()
-{
- emptyRun = true;
- if (!m_firstRun)
- return;
-
- Run* curr = m_firstRun;
- while (curr) {
- Run* s = curr->next();
- curr->destroy();
- curr = s;
- }
-
- m_firstRun = 0;
- m_lastRun = 0;
- m_runCount = 0;
-}
-
-template <class Iterator, class Run>
-void BidiResolver<Iterator, Run>::reverseRuns(unsigned start, unsigned end)
-{
- if (start >= end)
- return;
-
- ASSERT(end < m_runCount);
-
- // Get the item before the start of the runs to reverse and put it in
- // |beforeStart|. |curr| should point to the first run to reverse.
- Run* curr = m_firstRun;
- Run* beforeStart = 0;
- unsigned i = 0;
- while (i < start) {
- i++;
- beforeStart = curr;
- curr = curr->next();
- }
-
- Run* startRun = curr;
- while (i < end) {
- i++;
- curr = curr->next();
- }
- Run* endRun = curr;
- Run* afterEnd = curr->next();
-
- i = start;
- curr = startRun;
- Run* newNext = afterEnd;
- while (i <= end) {
- // Do the reversal.
- Run* next = curr->next();
- curr->m_next = newNext;
- newNext = curr;
- curr = next;
- i++;
- }
-
- // Now hook up beforeStart and afterEnd to the startRun and endRun.
- if (beforeStart)
- beforeStart->m_next = endRun;
- else
- m_firstRun = endRun;
-
- startRun->m_next = afterEnd;
- if (!afterEnd)
- m_lastRun = startRun;
-}
-
-template <class Iterator, class Run>
inline void BidiResolver<Iterator, Run>::updateStatusLastFromCurrentDirection(WTF::Unicode::Direction dirCurrent)
{
using namespace WTF::Unicode;
@@ -581,7 +439,7 @@ inline void BidiResolver<Iterator, Run>::reorderRunsFromLevels()
{
unsigned char levelLow = 128;
unsigned char levelHigh = 0;
- for (Run* run = firstRun(); run; run = run->next()) {
+ for (Run* run = m_runs.firstRun(); run; run = run->next()) {
levelHigh = std::max(run->level(), levelHigh);
levelLow = std::min(run->level(), levelLow);
}
@@ -595,11 +453,11 @@ inline void BidiResolver<Iterator, Run>::reorderRunsFromLevels()
if (!(levelLow % 2))
levelLow++;
- unsigned count = runCount() - 1;
+ unsigned count = m_runs.runCount() - 1;
while (levelHigh >= levelLow) {
unsigned i = 0;
- Run* run = firstRun();
+ Run* run = m_runs.firstRun();
while (i < count) {
for (;i < count && run && run->level() < levelHigh; i++)
run = run->next();
@@ -607,7 +465,7 @@ inline void BidiResolver<Iterator, Run>::reorderRunsFromLevels()
for (;i <= count && run && run->level() >= levelHigh; i++)
run = run->next();
unsigned end = i - 1;
- reverseRuns(start, end);
+ m_runs.reverseRuns(start, end);
}
levelHigh--;
}
@@ -621,7 +479,7 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
ASSERT(m_direction == OtherNeutral);
if (override != NoVisualOverride) {
- emptyRun = false;
+ m_emptyRun = false;
m_sor = m_current;
m_eor = Iterator();
while (m_current != end && !m_current.atEnd()) {
@@ -630,13 +488,13 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
}
m_direction = override == VisualLeftToRightOverride ? LeftToRight : RightToLeft;
appendRun();
- m_logicallyLastRun = m_lastRun;
+ m_runs.setLogicallyLastRun(m_runs.lastRun());
if (override == VisualRightToLeftOverride)
- reverseRuns(0, runCount() - 1);
+ m_runs.reverseRuns(0, m_runs.runCount() - 1);
return;
}
- emptyRun = true;
+ m_emptyRun = true;
m_eor = Iterator();
@@ -818,7 +676,7 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
// Terminate the EN run.
appendRun();
// Make an R run.
- m_eor = m_status.last == EuropeanNumberTerminator ? lastBeforeET : m_last;
+ m_eor = m_status.last == EuropeanNumberTerminator ? m_lastBeforeET : m_last;
m_direction = RightToLeft;
appendRun();
// Begin a new EN run.
@@ -829,7 +687,7 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
appendRun();
if (m_status.lastStrong == RightToLeft || context()->dir() == RightToLeft) {
// Make an R run.
- m_eor = m_status.last == EuropeanNumberTerminator ? lastBeforeET : m_last;
+ m_eor = m_status.last == EuropeanNumberTerminator ? m_lastBeforeET : m_last;
m_direction = RightToLeft;
appendRun();
// Begin a new EN run.
@@ -837,7 +695,7 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
}
} else if (m_status.lastStrong == RightToLeft) {
// Extend the R run to include the neutrals.
- m_eor = m_status.last == EuropeanNumberTerminator ? lastBeforeET : m_last;
+ m_eor = m_status.last == EuropeanNumberTerminator ? m_lastBeforeET : m_last;
m_direction = RightToLeft;
appendRun();
// Begin a new EN run.
@@ -905,7 +763,7 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
m_eor = m_current;
m_status.eor = dirCurrent;
} else if (m_status.last != EuropeanNumberTerminator)
- lastBeforeET = emptyRun ? m_eor : m_last;
+ m_lastBeforeET = m_emptyRun ? m_eor : m_last;
break;
// boundary neutrals should be ignored
@@ -951,8 +809,8 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
m_eor = stateAtEnd.m_eor;
m_last = stateAtEnd.m_last;
m_reachedEndOfLine = stateAtEnd.m_reachedEndOfLine;
- lastBeforeET = stateAtEnd.lastBeforeET;
- emptyRun = stateAtEnd.emptyRun;
+ m_lastBeforeET = stateAtEnd.m_lastBeforeET;
+ m_emptyRun = stateAtEnd.m_emptyRun;
m_direction = OtherNeutral;
break;
}
@@ -960,9 +818,9 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
updateStatusLastFromCurrentDirection(dirCurrent);
m_last = m_current;
- if (emptyRun) {
+ if (m_emptyRun) {
m_sor = m_current;
- emptyRun = false;
+ m_emptyRun = false;
}
increment();
@@ -975,29 +833,29 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
m_eor = stateAtEnd.m_eor;
m_last = stateAtEnd.m_last;
m_reachedEndOfLine = stateAtEnd.m_reachedEndOfLine;
- lastBeforeET = stateAtEnd.lastBeforeET;
- emptyRun = stateAtEnd.emptyRun;
+ m_lastBeforeET = stateAtEnd.m_lastBeforeET;
+ m_emptyRun = stateAtEnd.m_emptyRun;
m_direction = OtherNeutral;
break;
}
}
if (!pastEnd && (m_current == end || m_current.atEnd())) {
- if (emptyRun)
+ if (m_emptyRun)
break;
stateAtEnd.m_status = m_status;
stateAtEnd.m_sor = m_sor;
stateAtEnd.m_eor = m_eor;
stateAtEnd.m_last = m_last;
stateAtEnd.m_reachedEndOfLine = m_reachedEndOfLine;
- stateAtEnd.lastBeforeET = lastBeforeET;
- stateAtEnd.emptyRun = emptyRun;
+ stateAtEnd.m_lastBeforeET = m_lastBeforeET;
+ stateAtEnd.m_emptyRun = m_emptyRun;
endOfLine = m_last;
pastEnd = true;
}
}
- m_logicallyLastRun = m_lastRun;
+ m_runs.setLogicallyLastRun(m_runs.lastRun());
reorderRunsFromLevels();
endOfLine = Iterator();
}
diff --git a/Source/WebCore/platform/text/BidiRunList.h b/Source/WebCore/platform/text/BidiRunList.h
new file mode 100644
index 0000000..a4aa3c2
--- /dev/null
+++ b/Source/WebCore/platform/text/BidiRunList.h
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2003, 2004, 2006, 2007, 2008 Apple Inc. All right reserved.
+ * Copyright (C) 2011 Google, 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
+ * 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 BidiRunList_h
+#define BidiRunList_h
+
+#include <wtf/Noncopyable.h>
+
+namespace WebCore {
+
+template <class Run>
+class BidiRunList {
+ WTF_MAKE_NONCOPYABLE(BidiRunList);
+public:
+ BidiRunList()
+ : m_firstRun(0)
+ , m_lastRun(0)
+ , m_logicallyLastRun(0)
+ , m_runCount(0)
+ {
+ }
+
+ // FIXME: Once BidiResolver no longer owns the BidiRunList,
+ // then ~BidiRunList should call deleteRuns() automatically.
+
+ Run* firstRun() const { return m_firstRun; }
+ Run* lastRun() const { return m_lastRun; }
+ Run* logicallyLastRun() const { return m_logicallyLastRun; }
+ unsigned runCount() const { return m_runCount; }
+
+ void addRun(Run*);
+ void prependRun(Run*);
+
+ void moveRunToEnd(Run*);
+ void moveRunToBeginning(Run*);
+
+ void deleteRuns();
+ void reverseRuns(unsigned start, unsigned end);
+ void reorderRunsFromLevels();
+
+ void setLogicallyLastRun(Run* run) { m_logicallyLastRun = run; }
+
+private:
+ Run* m_firstRun;
+ Run* m_lastRun;
+ Run* m_logicallyLastRun;
+ unsigned m_runCount;
+};
+
+template <class Run>
+inline void BidiRunList<Run>::addRun(Run* run)
+{
+ if (!m_firstRun)
+ m_firstRun = run;
+ else
+ m_lastRun->m_next = run;
+ m_lastRun = run;
+ m_runCount++;
+}
+
+template <class Run>
+inline void BidiRunList<Run>::prependRun(Run* run)
+{
+ ASSERT(!run->m_next);
+
+ if (!m_lastRun)
+ m_lastRun = run;
+ else
+ run->m_next = m_firstRun;
+ m_firstRun = run;
+ m_runCount++;
+}
+
+template <class Run>
+inline void BidiRunList<Run>::moveRunToEnd(Run* run)
+{
+ ASSERT(m_firstRun);
+ ASSERT(m_lastRun);
+ ASSERT(run->m_next);
+
+ Run* current = 0;
+ Run* next = m_firstRun;
+ while (next != run) {
+ current = next;
+ next = current->next();
+ }
+
+ if (!current)
+ m_firstRun = run->next();
+ else
+ current->m_next = run->m_next;
+
+ run->m_next = 0;
+ m_lastRun->m_next = run;
+ m_lastRun = run;
+}
+
+template <class Run>
+inline void BidiRunList<Run>::moveRunToBeginning(Run* run)
+{
+ ASSERT(m_firstRun);
+ ASSERT(m_lastRun);
+ ASSERT(run != m_firstRun);
+
+ Run* current = m_firstRun;
+ Run* next = current->next();
+ while (next != run) {
+ current = next;
+ next = current->next();
+ }
+
+ current->m_next = run->m_next;
+ if (run == m_lastRun)
+ m_lastRun = current;
+
+ run->m_next = m_firstRun;
+ m_firstRun = run;
+}
+
+template <class Run>
+void BidiRunList<Run>::deleteRuns()
+{
+ if (!m_firstRun)
+ return;
+
+ Run* curr = m_firstRun;
+ while (curr) {
+ Run* s = curr->next();
+ curr->destroy();
+ curr = s;
+ }
+
+ m_firstRun = 0;
+ m_lastRun = 0;
+ m_runCount = 0;
+}
+
+template <class Run>
+void BidiRunList<Run>::reverseRuns(unsigned start, unsigned end)
+{
+ if (start >= end)
+ return;
+
+ ASSERT(end < m_runCount);
+
+ // Get the item before the start of the runs to reverse and put it in
+ // |beforeStart|. |curr| should point to the first run to reverse.
+ Run* curr = m_firstRun;
+ Run* beforeStart = 0;
+ unsigned i = 0;
+ while (i < start) {
+ i++;
+ beforeStart = curr;
+ curr = curr->next();
+ }
+
+ Run* startRun = curr;
+ while (i < end) {
+ i++;
+ curr = curr->next();
+ }
+ Run* endRun = curr;
+ Run* afterEnd = curr->next();
+
+ i = start;
+ curr = startRun;
+ Run* newNext = afterEnd;
+ while (i <= end) {
+ // Do the reversal.
+ Run* next = curr->next();
+ curr->m_next = newNext;
+ newNext = curr;
+ curr = next;
+ i++;
+ }
+
+ // Now hook up beforeStart and afterEnd to the startRun and endRun.
+ if (beforeStart)
+ beforeStart->m_next = endRun;
+ else
+ m_firstRun = endRun;
+
+ startRun->m_next = afterEnd;
+ if (!afterEnd)
+ m_lastRun = startRun;
+}
+
+} // namespace WebCore
+
+#endif // BidiRunList
diff --git a/Source/WebCore/platform/text/LocalizedNumberICU.cpp b/Source/WebCore/platform/text/LocalizedNumberICU.cpp
index 7c4b1cb..da16262 100644
--- a/Source/WebCore/platform/text/LocalizedNumberICU.cpp
+++ b/Source/WebCore/platform/text/LocalizedNumberICU.cpp
@@ -37,6 +37,7 @@
#include <wtf/MathExtras.h>
#include <wtf/PassOwnPtr.h>
+using namespace icu;
using namespace std;
namespace WebCore {
diff --git a/Source/WebCore/platform/text/StringWithDirection.h b/Source/WebCore/platform/text/StringWithDirection.h
new file mode 100644
index 0000000..3302f81
--- /dev/null
+++ b/Source/WebCore/platform/text/StringWithDirection.h
@@ -0,0 +1,79 @@
+/*
+ * 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
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef StringWithDirection_h
+#define StringWithDirection_h
+
+#include "PlatformString.h"
+#include "TextDirection.h"
+
+namespace WebCore {
+
+// In some circumstances we want to store a String along with the TextDirection
+// of the String as learned from the context of the String. For example,
+// consider storing the title derived from <title dir='rtl'>some title</title>
+// in the history.
+//
+// Note that is explicitly *not* the direction of the string as learned
+// from the characters of the string; it's extra metadata we have external
+// to the string.
+class StringWithDirection {
+public:
+ StringWithDirection()
+ : m_direction(LTR)
+ {
+ }
+
+ StringWithDirection(const String& string, TextDirection dir)
+ : m_string(string)
+ , m_direction(dir)
+ {
+ }
+
+ const String& string() const { return m_string; }
+ TextDirection direction() const { return m_direction; }
+
+ bool isEmpty() const { return m_string.isEmpty(); }
+ bool isNull() const { return m_string.isNull(); }
+
+ bool operator==(const StringWithDirection& other) const
+ {
+ return other.m_string == m_string && other.m_direction == m_direction;
+ }
+ bool operator!=(const StringWithDirection& other) const { return !((*this) == other); }
+
+private:
+ String m_string;
+ TextDirection m_direction;
+};
+
+}
+
+#endif // StringWithDirection_h
diff --git a/Source/WebCore/platform/text/TextCheckerClient.h b/Source/WebCore/platform/text/TextCheckerClient.h
index 8abbed4..d16ade1 100644
--- a/Source/WebCore/platform/text/TextCheckerClient.h
+++ b/Source/WebCore/platform/text/TextCheckerClient.h
@@ -45,16 +45,6 @@ struct GrammarDetail {
String userDescription;
};
-enum TextCheckingType {
- TextCheckingTypeSpelling = 1 << 1,
- TextCheckingTypeGrammar = 1 << 2,
- TextCheckingTypeLink = 1 << 5,
- TextCheckingTypeQuote = 1 << 6,
- TextCheckingTypeDash = 1 << 7,
- TextCheckingTypeReplacement = 1 << 8,
- TextCheckingTypeCorrection = 1 << 9
-};
-
struct TextCheckingResult {
TextCheckingType type;
int location;
@@ -72,15 +62,16 @@ public:
virtual void checkSpellingOfString(const UChar*, int length, int* misspellingLocation, int* misspellingLength) = 0;
virtual String getAutoCorrectSuggestionForMisspelledWord(const String& misspelledWord) = 0;
virtual void checkGrammarOfString(const UChar*, int length, Vector<GrammarDetail>&, int* badGrammarLocation, int* badGrammarLength) = 0;
+
#if USE(UNIFIED_TEXT_CHECKING)
- virtual void checkTextOfParagraph(const UChar* text, int length, uint64_t checkingTypes, Vector<TextCheckingResult>& results) = 0;
+ virtual void checkTextOfParagraph(const UChar* text, int length, TextCheckingTypeMask checkingTypes, Vector<TextCheckingResult>& results) = 0;
#endif
// For spellcheckers that support multiple languages, it's often important to be able to identify the language in order to
// provide more accurate correction suggestions. Caller can pass in more text in "context" to aid such spellcheckers on language
// identification. Noramlly it's the text surrounding the "word" for which we are getting correction suggestions.
virtual void getGuessesForWord(const String& word, const String& context, Vector<String>& guesses) = 0;
- virtual void requestCheckingOfString(SpellChecker*, int, const String&) = 0;
+ virtual void requestCheckingOfString(SpellChecker*, int, TextCheckingTypeMask, const String&) = 0;
};
}
diff --git a/Source/WebCore/platform/text/TextChecking.h b/Source/WebCore/platform/text/TextChecking.h
index 022fb82..d2040d5 100644
--- a/Source/WebCore/platform/text/TextChecking.h
+++ b/Source/WebCore/platform/text/TextChecking.h
@@ -42,6 +42,18 @@ namespace WebCore {
#define WTF_USE_AUTOMATIC_TEXT_REPLACEMENT 1
#endif
+enum TextCheckingType {
+ TextCheckingTypeSpelling = 1 << 1,
+ TextCheckingTypeGrammar = 1 << 2,
+ TextCheckingTypeLink = 1 << 5,
+ TextCheckingTypeQuote = 1 << 6,
+ TextCheckingTypeDash = 1 << 7,
+ TextCheckingTypeReplacement = 1 << 8,
+ TextCheckingTypeCorrection = 1 << 9
+};
+
+typedef unsigned TextCheckingTypeMask;
+
}
#endif // TextChecking_h
diff --git a/Source/WebCore/platform/text/UnicodeBidi.h b/Source/WebCore/platform/text/UnicodeBidi.h
new file mode 100644
index 0000000..8e0d86e
--- /dev/null
+++ b/Source/WebCore/platform/text/UnicodeBidi.h
@@ -0,0 +1,40 @@
+/*
+ * 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 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 UnicodeBidi_h
+#define UnicodeBidi_h
+
+namespace WebCore {
+
+enum EUnicodeBidi {
+ UBNormal,
+ Embed,
+ Override,
+ Isolate
+};
+
+}
+
+#endif
diff --git a/Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp b/Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp
index 33d8ccd..7bd97d6 100644
--- a/Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp
+++ b/Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp
@@ -444,7 +444,7 @@ String getURL(const DragDataMap* data, DragData::FilenameConversionPolicy filena
if (stringData.isEmpty() || (!PathFileExists(stringData.charactersWithNullTermination()) && !PathIsUNC(stringData.charactersWithNullTermination())))
return url;
- RetainPtr<CFStringRef> pathAsCFString(AdoptCF, CFStringCreateWithCharacters(kCFAllocatorDefault, (const UniChar *)stringData.charactersWithNullTermination(), stringData.length()));
+ RetainPtr<CFStringRef> pathAsCFString(AdoptCF, CFStringCreateWithCharacters(kCFAllocatorDefault, (const UniChar *)stringData.charactersWithNullTermination(), wcslen(stringData.charactersWithNullTermination())));
if (urlFromPath(pathAsCFString.get(), url) && title)
*title = url;
#endif
diff --git a/Source/WebCore/platform/win/ClipboardWin.cpp b/Source/WebCore/platform/win/ClipboardWin.cpp
index 791ec86..0b5a3d3 100644
--- a/Source/WebCore/platform/win/ClipboardWin.cpp
+++ b/Source/WebCore/platform/win/ClipboardWin.cpp
@@ -703,7 +703,6 @@ void ClipboardWin::declareAndWriteDragImage(Element* element, const KURL& url, c
return;
STGMEDIUM medium = {0};
medium.tymed = TYMED_HGLOBAL;
- ExceptionCode ec = 0;
// Put img tag on the clipboard referencing the image
Vector<char> data;
@@ -791,7 +790,6 @@ void ClipboardWin::writePlainText(const String& text)
STGMEDIUM medium = {0};
medium.tymed = TYMED_HGLOBAL;
- ExceptionCode ec = 0;
String str = text;
replaceNewlinesWithWindowsStyleNewlines(str);
diff --git a/Source/WebCore/platform/win/DragImageCairoWin.cpp b/Source/WebCore/platform/win/DragImageCairoWin.cpp
index e356575..a67a82c 100644
--- a/Source/WebCore/platform/win/DragImageCairoWin.cpp
+++ b/Source/WebCore/platform/win/DragImageCairoWin.cpp
@@ -29,26 +29,20 @@
#include "BitmapInfo.h"
#include "CachedImage.h"
#include "GraphicsContext.h"
+#include "GraphicsContextPlatformPrivateCairo.h"
#include "Image.h"
#include "RetainPtr.h"
-
#include <cairo-win32.h>
-#include "GraphicsContextPlatformPrivateCairo.h"
-
#include <windows.h>
-extern "C" {
-typedef struct _cairo* CairoContextRef;
-}
-
namespace WebCore {
-void deallocContext(CairoContextRef target)
+void deallocContext(PlatformContextCairo* target)
{
- cairo_destroy(target);
+ delete target;
}
-HBITMAP allocImage(HDC dc, IntSize size, CairoContextRef* targetRef)
+HBITMAP allocImage(HDC dc, IntSize size, PlatformContextCairo** targetRef)
{
BitmapInfo bmpInfo = BitmapInfo::create(size);
@@ -72,8 +66,8 @@ HBITMAP allocImage(HDC dc, IntSize size, CairoContextRef* targetRef)
return 0;
}
- *targetRef = cairo_create (bitmapContext);
- cairo_surface_destroy (bitmapContext);
+ cairo_t* cr = cairo_create(bitmapContext);
+ cairo_surface_destroy(bitmapContext);
// At this point, we have a Cairo surface that points to a Windows DIB. The DIB interprets
// with the opposite meaning of positive Y axis, so everything we draw into this cairo
@@ -83,7 +77,10 @@ HBITMAP allocImage(HDC dc, IntSize size, CairoContextRef* targetRef)
// before they get written to the internal buffer.
cairo_matrix_t matrix;
cairo_matrix_init(&matrix, 1.0, 0.0, 0.0, -1.0, 0.0, size.height());
- cairo_set_matrix(*targetRef, &matrix);
+ cairo_set_matrix(cr, &matrix);
+
+ *targetRef = new PlatformGraphicsContext(cr);
+ cairo_destroy(cr);
return hbmp;
}
@@ -121,7 +118,7 @@ DragImageRef scaleDragImage(DragImageRef image, FloatSize scale)
if (!dstDC)
goto exit;
- CairoContextRef targetContext;
+ PlatformContextCairo* targetContext;
hbmp = allocImage(dstDC, dstSize, &targetContext);
if (!hbmp)
goto exit;
@@ -131,15 +128,16 @@ DragImageRef scaleDragImage(DragImageRef image, FloatSize scale)
// Scale the target surface to the new image size, and flip it
// so that when we set the srcImage as the surface it will draw
// right-side-up.
- cairo_translate(targetContext, 0, dstSize.height());
- cairo_scale(targetContext, scale.width(), -scale.height());
- cairo_set_source_surface (targetContext, srcImage, 0.0, 0.0);
+ cairo_t* cr = targetContext->cr();
+ cairo_translate(cr, 0, dstSize.height());
+ cairo_scale(cr, scale.width(), -scale.height());
+ cairo_set_source_surface(cr, srcImage, 0.0, 0.0);
// Now we can paint and get the correct result
- cairo_paint(targetContext);
+ cairo_paint(cr);
- cairo_surface_destroy (srcImage);
- cairo_destroy(targetContext);
+ cairo_surface_destroy(srcImage);
+ deallocContext(targetContext);
::DeleteObject(image);
image = 0;
@@ -160,7 +158,7 @@ DragImageRef createDragImageFromImage(Image* img)
if (!workingDC)
goto exit;
- CairoContextRef drawContext = 0;
+ PlatformContextCairo* drawContext = 0;
hbmp = allocImage(workingDC, img->size(), &drawContext);
if (!hbmp)
goto exit;
@@ -170,16 +168,17 @@ DragImageRef createDragImageFromImage(Image* img)
hbmp = 0;
}
- cairo_set_source_rgb (drawContext, 1.0, 0.0, 1.0);
- cairo_fill_preserve (drawContext);
+ cairo_t* cr = drawContext->cr();
+ cairo_set_source_rgb(cr, 1.0, 0.0, 1.0);
+ cairo_fill_preserve(cr);
cairo_surface_t* srcImage = img->nativeImageForCurrentFrame();
// Draw the image.
- cairo_set_source_surface(drawContext, srcImage, 0.0, 0.0);
- cairo_paint(drawContext);
+ cairo_set_source_surface(cr, srcImage, 0.0, 0.0);
+ cairo_paint(cr);
- cairo_destroy (drawContext);
+ deallocContext(drawContext);
exit:
if (workingDC)
diff --git a/Source/WebCore/platform/win/FileSystemWin.cpp b/Source/WebCore/platform/win/FileSystemWin.cpp
index 03a2eaf..7d1c8f2 100644
--- a/Source/WebCore/platform/win/FileSystemWin.cpp
+++ b/Source/WebCore/platform/win/FileSystemWin.cpp
@@ -136,7 +136,12 @@ String pathGetFileName(const String& path)
String directoryName(const String& path)
{
- return path.left(path.length() - pathGetFileName(path).length());
+ String name = path.left(path.length() - pathGetFileName(path).length());
+ if (name.characterStartingAt(name.length() - 1) == '\\') {
+ // Remove any trailing "\".
+ name.truncate(name.length() - 1);
+ }
+ return name;
}
static String bundleName()
@@ -241,9 +246,11 @@ PlatformFileHandle openFile(const String& path, FileOpenMode mode)
case OpenForRead:
desiredAccess = GENERIC_READ;
creationDisposition = OPEN_EXISTING;
+ break;
case OpenForWrite:
desiredAccess = GENERIC_WRITE;
creationDisposition = CREATE_ALWAYS;
+ break;
default:
ASSERT_NOT_REACHED();
}
diff --git a/Source/WebCore/platform/win/LocalizedStringsWin.cpp b/Source/WebCore/platform/win/LocalizedStringsWin.cpp
index 67de0fc..c079441 100644
--- a/Source/WebCore/platform/win/LocalizedStringsWin.cpp
+++ b/Source/WebCore/platform/win/LocalizedStringsWin.cpp
@@ -26,14 +26,66 @@
#include "config.h"
#include "LocalizedStrings.h"
+#include "WebCoreInstanceHandle.h"
+#include <wtf/Assertions.h>
+#include <wtf/StdLibExtras.h>
+#include <wtf/Threading.h>
#include <wtf/text/WTFString.h>
+#if USE(CF)
+#include <CoreFoundation/CFBundle.h>
+#include <wtf/RetainPtr.h>
+#endif
+
namespace WebCore {
+#if USE(CF)
+
+static CFBundleRef createWebKitBundle()
+{
+ if (CFBundleRef existingBundle = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.WebKit"))) {
+ CFRetain(existingBundle);
+ return existingBundle;
+ }
+
+ wchar_t dllPathBuffer[MAX_PATH];
+ DWORD length = ::GetModuleFileNameW(instanceHandle(), dllPathBuffer, WTF_ARRAY_LENGTH(dllPathBuffer));
+ ASSERT(length);
+ ASSERT(length < WTF_ARRAY_LENGTH(dllPathBuffer));
+
+ RetainPtr<CFStringRef> dllPath(AdoptCF, CFStringCreateWithCharactersNoCopy(0, reinterpret_cast<const UniChar*>(dllPathBuffer), length, kCFAllocatorNull));
+ RetainPtr<CFURLRef> dllURL(AdoptCF, CFURLCreateWithFileSystemPath(0, dllPath.get(), kCFURLWindowsPathStyle, false));
+ RetainPtr<CFURLRef> dllDirectoryURL(AdoptCF, CFURLCreateCopyDeletingLastPathComponent(0, dllURL.get()));
+ RetainPtr<CFURLRef> resourcesDirectoryURL(AdoptCF, CFURLCreateCopyAppendingPathComponent(0, dllDirectoryURL.get(), CFSTR("WebKit.resources"), true));
+
+ return CFBundleCreate(0, resourcesDirectoryURL.get());
+}
+
+static CFBundleRef webKitBundle()
+{
+ static CFBundleRef bundle = createWebKitBundle();
+ ASSERT(bundle);
+ return bundle;
+}
+
+#endif // USE(CF)
+
String localizedString(const char* key)
{
- // FIXME: <rdar://problem/9119405> Win: WebKit2 needs to be made localizable
+ ASSERT(isMainThread());
+
+#if USE(CF)
+ static CFStringRef notFound = CFSTR("localized string not found");
+
+ RetainPtr<CFStringRef> keyString(AdoptCF, CFStringCreateWithCStringNoCopy(NULL, key, kCFStringEncodingUTF8, kCFAllocatorNull));
+ RetainPtr<CFStringRef> result(AdoptCF, CFCopyLocalizedStringWithDefaultValue(keyString.get(), 0, webKitBundle(), notFound, 0));
+ ASSERT_WITH_MESSAGE(result.get() != notFound, "could not find localizable string %s in bundle", key);
+
+ return result.get();
+#else
+ // FIXME: Implement localizedString() for !USE(CF).
return String::fromUTF8(key, strlen(key));
+#endif
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/win/LoggingWin.cpp b/Source/WebCore/platform/win/LoggingWin.cpp
index 1d051ae..5e9fbda 100644
--- a/Source/WebCore/platform/win/LoggingWin.cpp
+++ b/Source/WebCore/platform/win/LoggingWin.cpp
@@ -88,6 +88,7 @@ void InitializeLoggingChannelsIfNecessary()
initializeWithUserDefault(LogHistory);
initializeWithUserDefault(LogPageCache);
initializeWithUserDefault(LogPlatformLeaks);
+ initializeWithUserDefault(LogResourceLoading);
initializeWithUserDefault(LogNetwork);
initializeWithUserDefault(LogFTP);
initializeWithUserDefault(LogThreading);
@@ -95,6 +96,8 @@ void InitializeLoggingChannelsIfNecessary()
initializeWithUserDefault(LogMedia);
initializeWithUserDefault(LogPlugins);
initializeWithUserDefault(LogArchives);
+ initializeWithUserDefault(LogProgress);
+ initializeWithUserDefault(LogFileAPI);
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/win/PopupMenuWin.h b/Source/WebCore/platform/win/PopupMenuWin.h
index 05edb07..0684424 100644
--- a/Source/WebCore/platform/win/PopupMenuWin.h
+++ b/Source/WebCore/platform/win/PopupMenuWin.h
@@ -95,8 +95,10 @@ private:
virtual int scrollPosition(Scrollbar*) const;
virtual void setScrollOffset(const IntPoint&);
virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&);
+ virtual void invalidateScrollCornerRect(const WebCore::IntRect&) { }
virtual bool isActive() const { return true; }
- virtual bool scrollbarCornerPresent() const { return false; }
+ virtual bool isScrollCornerVisible() const { return false; }
+ virtual WebCore::IntRect scrollCornerRect() const { return WebCore::IntRect(); }
virtual Scrollbar* verticalScrollbar() const { return m_scrollbar.get(); }
// NOTE: This should only be called by the overriden setScrollOffset from ScrollableArea.
diff --git a/Source/WebCore/platform/win/WindowsTouch.h b/Source/WebCore/platform/win/WindowsTouch.h
new file mode 100644
index 0000000..9048103
--- /dev/null
+++ b/Source/WebCore/platform/win/WindowsTouch.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2009 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 WindowsTouch_h
+#define WindowsTouch_h
+
+/*
+ * The following constants are used to determine multitouch and gesture behavior
+ * for Windows 7. For more information, see:
+ * http://msdn.microsoft.com/en-us/library/dd562197(VS.85).aspx
+ */
+
+// Value used in WebViewWndProc for Gestures
+#define WM_GESTURE 0x0119
+#define WM_GESTURENOTIFY 0x011A
+
+// Gesture Information Flags
+#define GF_BEGIN 0x00000001
+#define GF_INERTIA 0x00000002
+#define GF_END 0x00000004
+
+// Gesture IDs
+#define GID_BEGIN 1
+#define GID_END 2
+#define GID_ZOOM 3
+#define GID_PAN 4
+#define GID_ROTATE 5
+#define GID_TWOFINGERTAP 6
+#define GID_PRESSANDTAP 7
+#define GID_ROLLOVER GID_PRESSANDTAP
+
+// Zoom Gesture Confiration Flags
+#define GC_ZOOM 0x00000001
+
+// Pan Gesture Configuration Flags
+#define GC_PAN 0x00000001
+#define GC_PAN_WITH_SINGLE_FINGER_VERTICALLY 0x00000002
+#define GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY 0x00000004
+#define GC_PAN_WITH_GUTTER 0x00000008
+#define GC_PAN_WITH_INERTIA 0x00000010
+
+// Rotate Gesture Configuration Flags
+#define GC_ROTATE 0x00000001
+
+// Two finger tap configuration flags
+#define GC_TWOFINGERTAP 0x00000001
+
+// Press and tap Configuration Flags
+#define GC_PRESSANDTAP 0x00000001
+#define GC_ROLLOVER GC_PRESSANDTAP
+
+// GESTUREINFO struct definition
+typedef struct tagGESTUREINFO {
+ UINT cbSize; // size, in bytes, of this structure (including variable length Args field)
+ DWORD dwFlags; // see GF_* flags
+ DWORD dwID; // gesture ID, see GID_* defines
+ HWND hwndTarget; // handle to window targeted by this gesture
+ POINTS ptsLocation; // current location of this gesture
+ DWORD dwInstanceID; // internally used
+ DWORD dwSequenceID; // internally used
+ ULONGLONG ullArguments; // arguments for gestures whose arguments fit in 8 BYTES
+ UINT cbExtraArgs; // size, in bytes, of extra arguments, if any, that accompany this gesture
+} GESTUREINFO, *PGESTUREINFO;
+typedef GESTUREINFO const * PCGESTUREINFO;
+
+// GESTURECONFIG struct defintion
+typedef struct tagGESTURECONFIG {
+ DWORD dwID; // gesture ID
+ DWORD dwWant; // settings related to gesture ID that are to be turned on
+ DWORD dwBlock; // settings related to gesture ID that are to be turned off
+} GESTURECONFIG, *PGESTURECONFIG;
+
+/*
+ * Gesture notification structure
+ * - The WM_GESTURENOTIFY message lParam contains a pointer to this structure.
+ * - The WM_GESTURENOTIFY message notifies a window that gesture recognition is
+ * in progress and a gesture will be generated if one is recognized under the
+ * current gesture settings.
+ */
+typedef struct tagGESTURENOTIFYSTRUCT {
+ UINT cbSize; // size, in bytes, of this structure
+ DWORD dwFlags; // unused
+ HWND hwndTarget; // handle to window targeted by the gesture
+ POINTS ptsLocation; // starting location
+ DWORD dwInstanceID; // internally used
+} GESTURENOTIFYSTRUCT, *PGESTURENOTIFYSTRUCT;
+
+DECLARE_HANDLE(HGESTUREINFO);
+
+#endif
diff --git a/Source/WebCore/platform/wx/FileSystemWx.cpp b/Source/WebCore/platform/wx/FileSystemWx.cpp
index 3c2b453..3644a42 100644
--- a/Source/WebCore/platform/wx/FileSystemWx.cpp
+++ b/Source/WebCore/platform/wx/FileSystemWx.cpp
@@ -78,8 +78,11 @@ bool getFileSize(const String& path, long long& resultSize)
bool getFileModificationTime(const String& path, time_t& t)
{
- t = wxFileName(path).GetModificationTime().GetTicks();
- return true;
+ if (wxFileExists(path)) {
+ t = wxFileName(path).GetModificationTime().GetTicks();
+ return true;
+ }
+ return false;
}
bool makeAllDirectories(const String& path)
@@ -107,22 +110,26 @@ String directoryName(const String& path)
return wxFileName(path).GetPath();
}
-String openTemporaryFile(const String&, PlatformFileHandle& handle)
+String openTemporaryFile(const String& prefix, PlatformFileHandle& handle)
{
- notImplemented();
- handle = invalidPlatformFileHandle;
- return String();
+ wxString sFilename = wxFileName::CreateTempFileName(prefix);
+ wxFile* temp = new wxFile();
+ temp->Open(sFilename.c_str(), wxFile::read_write);
+ handle = temp;
+ return String(sFilename);
}
-void closeFile(PlatformFileHandle&)
+void closeFile(PlatformFileHandle& handle)
{
- notImplemented();
+ if (handle)
+ delete handle;
}
-int writeToFile(PlatformFileHandle, const char* data, int length)
+int writeToFile(PlatformFileHandle handle, const char* data, int length)
{
- notImplemented();
- return 0;
+ if (handle)
+ return static_cast<wxFile*>(handle)->Write(data, length);
+ return -1;
}
bool unloadModule(PlatformModule mod)
diff --git a/Source/WebCore/platform/wx/WidgetWx.cpp b/Source/WebCore/platform/wx/WidgetWx.cpp
index 9de4c3d..e9a3c98 100644
--- a/Source/WebCore/platform/wx/WidgetWx.cpp
+++ b/Source/WebCore/platform/wx/WidgetWx.cpp
@@ -27,8 +27,10 @@
#include "Cursor.h"
#include "GraphicsContext.h"
+#include "HostWindow.h"
#include "IntRect.h"
#include "NotImplemented.h"
+#include "ScrollView.h"
#include <wx/defs.h>
#include <wx/scrolwin.h>
@@ -54,8 +56,10 @@ void Widget::setFocus(bool focused)
void Widget::setCursor(const Cursor& cursor)
{
- if (platformWidget() && cursor.impl())
- platformWidget()->SetCursor(*cursor.impl());
+ ScrollView* view = root();
+ if (!view)
+ return;
+ view->hostWindow()->setCursor(cursor);
}
void Widget::show()