summaryrefslogtreecommitdiffstats
path: root/WebCore/platform
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/platform')
-rw-r--r--WebCore/platform/ContextMenu.cpp18
-rw-r--r--WebCore/platform/ContextMenuItem.h6
-rw-r--r--WebCore/platform/Cookie.h82
-rw-r--r--WebCore/platform/CookieJar.h8
-rw-r--r--WebCore/platform/CrossThreadCopier.cpp2
-rw-r--r--WebCore/platform/CrossThreadCopier.h4
-rw-r--r--WebCore/platform/Cursor.h5
-rw-r--r--WebCore/platform/DragData.cpp5
-rw-r--r--WebCore/platform/DragData.h3
-rw-r--r--WebCore/platform/DragImage.cpp6
-rw-r--r--WebCore/platform/DragImage.h7
-rw-r--r--WebCore/platform/FileSystem.h4
-rw-r--r--WebCore/platform/HostWindow.h7
-rw-r--r--WebCore/platform/KURL.cpp8
-rw-r--r--WebCore/platform/KURL.h11
-rw-r--r--WebCore/platform/KURLGoogle.cpp27
-rw-r--r--WebCore/platform/KURLHash.h2
-rw-r--r--WebCore/platform/LocalizedStrings.h8
-rw-r--r--WebCore/platform/MIMETypeRegistry.cpp4
-rw-r--r--WebCore/platform/Pasteboard.h10
-rw-r--r--WebCore/platform/PlatformKeyboardEvent.h8
-rw-r--r--WebCore/platform/PlatformMenuDescription.h4
-rw-r--r--WebCore/platform/PlatformMouseEvent.h10
-rw-r--r--WebCore/platform/PlatformWheelEvent.h20
-rw-r--r--WebCore/platform/PopupMenu.h11
-rw-r--r--WebCore/platform/PopupMenuClient.h2
-rw-r--r--WebCore/platform/ScrollView.cpp102
-rw-r--r--WebCore/platform/ScrollView.h6
-rw-r--r--WebCore/platform/Scrollbar.cpp14
-rw-r--r--WebCore/platform/StaticConstructors.h6
-rw-r--r--WebCore/platform/ThemeTypes.h7
-rw-r--r--WebCore/platform/ThreadTimers.cpp66
-rw-r--r--WebCore/platform/ThreadTimers.h4
-rw-r--r--WebCore/platform/Timer.cpp10
-rw-r--r--WebCore/platform/TreeShared.h15
-rw-r--r--WebCore/platform/Widget.h12
-rw-r--r--WebCore/platform/android/TemporaryLinkStubs.cpp5
-rw-r--r--WebCore/platform/chromium/ChromiumBridge.h23
-rw-r--r--WebCore/platform/chromium/ChromiumDataObject.h31
-rw-r--r--WebCore/platform/chromium/ClipboardChromium.cpp27
-rw-r--r--WebCore/platform/chromium/DragDataChromium.cpp20
-rw-r--r--WebCore/platform/chromium/FileChooserChromium.cpp2
-rw-r--r--WebCore/platform/chromium/FileSystemChromiumLinux.cpp5
-rw-r--r--WebCore/platform/chromium/FileSystemChromiumMac.mm5
-rw-r--r--WebCore/platform/chromium/FileSystemChromiumWin.cpp5
-rw-r--r--WebCore/platform/chromium/KeyCodeConversionGtk.cpp25
-rw-r--r--WebCore/platform/chromium/PasteboardChromium.cpp34
-rw-r--r--WebCore/platform/chromium/PasteboardPrivate.h4
-rw-r--r--WebCore/platform/chromium/PopupMenuChromium.cpp142
-rw-r--r--WebCore/platform/chromium/PopupMenuChromium.h30
-rw-r--r--WebCore/platform/chromium/ThemeChromiumMac.h60
-rw-r--r--WebCore/platform/chromium/ThemeChromiumMac.mm569
-rw-r--r--WebCore/platform/graphics/BitmapImage.h15
-rw-r--r--WebCore/platform/graphics/Color.h9
-rw-r--r--WebCore/platform/graphics/FloatPoint.h18
-rw-r--r--WebCore/platform/graphics/FloatRect.h22
-rw-r--r--WebCore/platform/graphics/FloatSize.h5
-rw-r--r--WebCore/platform/graphics/FontCache.h11
-rw-r--r--WebCore/platform/graphics/FontDescription.h17
-rw-r--r--WebCore/platform/graphics/FontFastPath.cpp4
-rw-r--r--WebCore/platform/graphics/FontSmoothingMode.h35
-rw-r--r--WebCore/platform/graphics/GlyphPageTreeNode.cpp6
-rw-r--r--WebCore/platform/graphics/GraphicsContext.cpp49
-rw-r--r--WebCore/platform/graphics/GraphicsContext.h42
-rw-r--r--WebCore/platform/graphics/GraphicsContext3D.h335
-rw-r--r--WebCore/platform/graphics/GraphicsLayer.cpp3
-rw-r--r--WebCore/platform/graphics/GraphicsLayer.h19
-rw-r--r--WebCore/platform/graphics/GraphicsLayerClient.h7
-rw-r--r--WebCore/platform/graphics/ImageBuffer.h12
-rw-r--r--WebCore/platform/graphics/ImageSource.cpp (renamed from WebCore/platform/graphics/cairo/ImageSourceCairo.cpp)152
-rw-r--r--WebCore/platform/graphics/ImageSource.h31
-rw-r--r--WebCore/platform/graphics/IntPoint.h5
-rw-r--r--WebCore/platform/graphics/IntRect.h13
-rw-r--r--WebCore/platform/graphics/IntSize.h15
-rw-r--r--WebCore/platform/graphics/MediaPlayer.cpp36
-rw-r--r--WebCore/platform/graphics/MediaPlayer.h26
-rw-r--r--WebCore/platform/graphics/MediaPlayerPrivate.h8
-rw-r--r--WebCore/platform/graphics/Path.h3
-rw-r--r--WebCore/platform/graphics/Pattern.h3
-rw-r--r--WebCore/platform/graphics/SimpleFontData.cpp4
-rw-r--r--WebCore/platform/graphics/SimpleFontData.h21
-rw-r--r--WebCore/platform/graphics/TextRenderingMode.h35
-rw-r--r--WebCore/platform/graphics/cairo/FontCairo.cpp2
-rw-r--r--WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp172
-rw-r--r--WebCore/platform/graphics/cairo/ImageBufferCairo.cpp69
-rw-r--r--WebCore/platform/graphics/cg/ColorCG.cpp12
-rw-r--r--WebCore/platform/graphics/cg/GradientCG.cpp11
-rw-r--r--WebCore/platform/graphics/cg/GraphicsContextCG.cpp402
-rw-r--r--WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h4
-rw-r--r--WebCore/platform/graphics/cg/ImageBufferCG.cpp79
-rw-r--r--WebCore/platform/graphics/cg/ImageCG.cpp77
-rw-r--r--WebCore/platform/graphics/cg/ImageSourceCG.cpp48
-rw-r--r--WebCore/platform/graphics/cg/PDFDocumentImage.cpp10
-rw-r--r--WebCore/platform/graphics/cg/PathCG.cpp10
-rw-r--r--WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp6
-rw-r--r--WebCore/platform/graphics/chromium/FontChromiumWin.cpp8
-rw-r--r--WebCore/platform/graphics/chromium/FontLinux.cpp63
-rw-r--r--WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp6
-rw-r--r--WebCore/platform/graphics/chromium/UniscribeHelper.cpp14
-rw-r--r--WebCore/platform/graphics/filters/FEBlend.cpp78
-rw-r--r--WebCore/platform/graphics/filters/FEBlend.h2
-rw-r--r--WebCore/platform/graphics/filters/FEColorMatrix.cpp4
-rw-r--r--WebCore/platform/graphics/filters/FEComponentTransfer.cpp92
-rw-r--r--WebCore/platform/graphics/filters/FEComposite.cpp72
-rw-r--r--WebCore/platform/graphics/filters/FilterEffect.cpp7
-rw-r--r--WebCore/platform/graphics/filters/FilterEffect.h1
-rw-r--r--WebCore/platform/graphics/filters/SourceAlpha.cpp23
-rw-r--r--WebCore/platform/graphics/filters/SourceAlpha.h2
-rw-r--r--WebCore/platform/graphics/gtk/DataSourceGStreamer.cpp243
-rw-r--r--WebCore/platform/graphics/gtk/DataSourceGStreamer.h54
-rw-r--r--WebCore/platform/graphics/gtk/FontPlatformData.h2
-rw-r--r--WebCore/platform/graphics/gtk/FontPlatformDataGtk.cpp11
-rw-r--r--WebCore/platform/graphics/gtk/FontPlatformDataPango.cpp7
-rw-r--r--WebCore/platform/graphics/gtk/ImageGtk.cpp73
-rw-r--r--WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp395
-rw-r--r--WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h13
-rw-r--r--WebCore/platform/graphics/gtk/SimpleFontDataGtk.cpp14
-rw-r--r--WebCore/platform/graphics/gtk/SimpleFontDataPango.cpp14
-rw-r--r--WebCore/platform/graphics/gtk/VideoSinkGStreamer.cpp66
-rw-r--r--WebCore/platform/graphics/haiku/ColorHaiku.cpp54
-rw-r--r--WebCore/platform/graphics/haiku/FloatPointHaiku.cpp48
-rw-r--r--WebCore/platform/graphics/haiku/FloatRectHaiku.cpp48
-rw-r--r--WebCore/platform/graphics/haiku/FontCacheHaiku.cpp79
-rw-r--r--WebCore/platform/graphics/haiku/FontCustomPlatformData.cpp45
-rw-r--r--WebCore/platform/graphics/haiku/FontCustomPlatformData.h44
-rw-r--r--WebCore/platform/graphics/haiku/FontHaiku.cpp116
-rw-r--r--WebCore/platform/graphics/haiku/FontPlatformData.h81
-rw-r--r--WebCore/platform/graphics/haiku/GradientHaiku.cpp53
-rw-r--r--WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp536
-rw-r--r--WebCore/platform/graphics/haiku/IconHaiku.cpp57
-rw-r--r--WebCore/platform/graphics/haiku/ImageBufferData.h43
-rw-r--r--WebCore/platform/graphics/haiku/ImageBufferHaiku.cpp97
-rw-r--r--WebCore/platform/graphics/haiku/ImageHaiku.cpp152
-rw-r--r--WebCore/platform/graphics/haiku/IntPointHaiku.cpp48
-rw-r--r--WebCore/platform/graphics/haiku/IntRectHaiku.cpp48
-rw-r--r--WebCore/platform/graphics/haiku/IntSizeHaiku.cpp48
-rw-r--r--WebCore/platform/graphics/haiku/PathHaiku.cpp161
-rw-r--r--WebCore/platform/graphics/haiku/SimpleFontDataHaiku.cpp108
-rw-r--r--WebCore/platform/graphics/mac/Canvas3DLayer.h50
-rw-r--r--WebCore/platform/graphics/mac/Canvas3DLayer.mm123
-rw-r--r--WebCore/platform/graphics/mac/CoreTextController.cpp2
-rw-r--r--WebCore/platform/graphics/mac/FontCustomPlatformData.cpp12
-rw-r--r--WebCore/platform/graphics/mac/FontMac.mm27
-rw-r--r--WebCore/platform/graphics/mac/FontMacATSUI.mm47
-rw-r--r--WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp1698
-rw-r--r--WebCore/platform/graphics/mac/GraphicsContextMac.mm15
-rw-r--r--WebCore/platform/graphics/mac/GraphicsLayerCA.h29
-rw-r--r--WebCore/platform/graphics/mac/GraphicsLayerCA.mm127
-rw-r--r--WebCore/platform/graphics/mac/ImageMac.mm9
-rw-r--r--WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h6
-rw-r--r--WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm42
-rw-r--r--WebCore/platform/graphics/mac/SimpleFontDataMac.mm31
-rw-r--r--WebCore/platform/graphics/opentype/OpenTypeUtilities.cpp45
-rw-r--r--WebCore/platform/graphics/opentype/OpenTypeUtilities.h5
-rw-r--r--WebCore/platform/graphics/qt/ColorQt.cpp5
-rw-r--r--WebCore/platform/graphics/qt/FontCacheQt.cpp6
-rw-r--r--WebCore/platform/graphics/qt/FontFallbackListQt.cpp2
-rw-r--r--WebCore/platform/graphics/qt/FontQt.cpp2
-rw-r--r--WebCore/platform/graphics/qt/GraphicsContextQt.cpp466
-rw-r--r--WebCore/platform/graphics/qt/IconQt.cpp2
-rw-r--r--WebCore/platform/graphics/qt/ImageBufferQt.cpp73
-rw-r--r--WebCore/platform/graphics/qt/ImageDecoderQt.cpp376
-rw-r--r--WebCore/platform/graphics/qt/ImageDecoderQt.h54
-rw-r--r--WebCore/platform/graphics/qt/ImageQt.cpp1
-rw-r--r--WebCore/platform/graphics/qt/ImageSourceQt.cpp173
-rw-r--r--WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp23
-rw-r--r--WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.h3
-rw-r--r--WebCore/platform/graphics/qt/SimpleFontDataQt.cpp2
-rw-r--r--WebCore/platform/graphics/qt/StillImageQt.h2
-rw-r--r--WebCore/platform/graphics/skia/GradientSkia.cpp28
-rw-r--r--WebCore/platform/graphics/skia/GraphicsContextSkia.cpp105
-rw-r--r--WebCore/platform/graphics/skia/ImageBufferSkia.cpp81
-rw-r--r--WebCore/platform/graphics/skia/ImageSkia.cpp19
-rw-r--r--WebCore/platform/graphics/skia/ImageSourceSkia.cpp238
-rw-r--r--WebCore/platform/graphics/skia/PlatformContextSkia.cpp8
-rw-r--r--WebCore/platform/graphics/win/FontCGWin.cpp24
-rw-r--r--WebCore/platform/graphics/win/FontCacheWin.cpp15
-rw-r--r--WebCore/platform/graphics/win/FontDatabase.cpp92
-rw-r--r--WebCore/platform/graphics/win/FontPlatformData.h1
-rw-r--r--WebCore/platform/graphics/win/FontPlatformDataCairoWin.cpp6
-rw-r--r--WebCore/platform/graphics/win/GraphicsContextCGWin.cpp8
-rw-r--r--WebCore/platform/graphics/win/ImageCGWin.cpp25
-rw-r--r--WebCore/platform/graphics/win/ImageCairoWin.cpp21
-rw-r--r--WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp65
-rw-r--r--WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h5
-rw-r--r--WebCore/platform/graphics/win/QTMovieWin.cpp24
-rw-r--r--WebCore/platform/graphics/win/QTMovieWin.h6
-rw-r--r--WebCore/platform/graphics/win/SimpleFontDataCairoWin.cpp6
-rw-r--r--WebCore/platform/graphics/wince/ColorWince.cpp38
-rw-r--r--WebCore/platform/graphics/wince/FontCustomPlatformData.cpp12
-rw-r--r--WebCore/platform/graphics/wince/FontCustomPlatformData.h6
-rw-r--r--WebCore/platform/graphics/wince/GradientWince.cpp52
-rw-r--r--WebCore/platform/graphics/wince/ImageBufferData.h34
-rw-r--r--WebCore/platform/graphics/wince/ImageBufferWince.cpp246
-rw-r--r--WebCore/platform/graphics/wince/MediaPlayerPrivateWince.h129
-rw-r--r--WebCore/platform/graphics/wince/MediaPlayerProxy.cpp145
-rw-r--r--WebCore/platform/graphics/wince/MediaPlayerProxy.h70
-rw-r--r--WebCore/platform/graphics/wince/PathWince.cpp163
-rw-r--r--WebCore/platform/graphics/wince/PlatformPathWince.cpp810
-rw-r--r--WebCore/platform/graphics/wince/PlatformPathWince.h178
-rw-r--r--WebCore/platform/graphics/wince/WinceGraphicsExtras.h39
-rw-r--r--WebCore/platform/graphics/wx/GraphicsContextWx.cpp55
-rw-r--r--WebCore/platform/graphics/wx/IconWx.cpp53
-rw-r--r--WebCore/platform/graphics/wx/ImageBufferWx.cpp15
-rw-r--r--WebCore/platform/graphics/wx/ImageSourceWx.cpp226
-rw-r--r--WebCore/platform/graphics/wx/ImageWx.cpp13
-rw-r--r--WebCore/platform/graphics/wx/IntSizeWx.cpp45
-rw-r--r--WebCore/platform/gtk/ClipboardGtk.cpp69
-rw-r--r--WebCore/platform/gtk/ClipboardGtk.h4
-rw-r--r--WebCore/platform/gtk/CursorGtk.cpp15
-rw-r--r--WebCore/platform/gtk/GeolocationServiceGtk.cpp4
-rw-r--r--WebCore/platform/gtk/GeolocationServiceGtk.h4
-rw-r--r--WebCore/platform/gtk/KeyEventGtk.cpp4
-rw-r--r--WebCore/platform/gtk/LocalizedStringsGtk.cpp112
-rw-r--r--WebCore/platform/gtk/PasteboardGtk.cpp23
-rw-r--r--WebCore/platform/gtk/PasteboardHelper.h1
-rw-r--r--WebCore/platform/gtk/PlatformScreenGtk.cpp6
-rw-r--r--WebCore/platform/gtk/PopupMenuGtk.cpp4
-rw-r--r--WebCore/platform/gtk/ScrollViewGtk.cpp35
-rw-r--r--WebCore/platform/gtk/WidgetGtk.cpp4
-rw-r--r--WebCore/platform/haiku/ClipboardHaiku.cpp36
-rw-r--r--WebCore/platform/haiku/ContextMenuHaiku.cpp40
-rw-r--r--WebCore/platform/haiku/CookieJarHaiku.cpp19
-rw-r--r--WebCore/platform/haiku/DragDataHaiku.cpp7
-rw-r--r--WebCore/platform/haiku/LocalizedStringsHaiku.cpp346
-rw-r--r--WebCore/platform/haiku/LoggingHaiku.cpp48
-rw-r--r--WebCore/platform/haiku/PasteboardHaiku.cpp17
-rw-r--r--WebCore/platform/haiku/RenderThemeHaiku.cpp178
-rw-r--r--WebCore/platform/haiku/RenderThemeHaiku.h70
-rw-r--r--WebCore/platform/haiku/ScrollbarThemeHaiku.cpp164
-rw-r--r--WebCore/platform/haiku/ScrollbarThemeHaiku.h55
-rw-r--r--WebCore/platform/haiku/SharedBufferHaiku.cpp55
-rw-r--r--WebCore/platform/haiku/SharedTimerHaiku.cpp124
-rw-r--r--WebCore/platform/haiku/TemporaryLinkStubs.cpp58
-rw-r--r--WebCore/platform/image-decoders/ImageDecoder.cpp248
-rw-r--r--WebCore/platform/image-decoders/ImageDecoder.h64
-rw-r--r--WebCore/platform/image-decoders/cairo/ImageDecoderCairo.cpp83
-rw-r--r--WebCore/platform/image-decoders/haiku/ImageDecoderHaiku.cpp92
-rw-r--r--WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp38
-rw-r--r--WebCore/platform/image-decoders/ico/ICOImageDecoder.h5
-rw-r--r--WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp86
-rw-r--r--WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h11
-rw-r--r--WebCore/platform/image-decoders/png/PNGImageDecoder.cpp36
-rw-r--r--WebCore/platform/image-decoders/qt/RGBA32BufferQt.cpp144
-rw-r--r--WebCore/platform/image-decoders/wx/ImageDecoderWx.cpp105
-rw-r--r--WebCore/platform/mac/ClipboardMac.h2
-rw-r--r--WebCore/platform/mac/ClipboardMac.mm77
-rw-r--r--WebCore/platform/mac/ContextMenuItemMac.mm6
-rw-r--r--WebCore/platform/mac/ContextMenuMac.mm6
-rw-r--r--WebCore/platform/mac/CookieJar.mm49
-rw-r--r--WebCore/platform/mac/DragDataMac.mm4
-rw-r--r--WebCore/platform/mac/DragImageMac.mm5
-rw-r--r--WebCore/platform/mac/GeolocationServiceMac.h4
-rw-r--r--WebCore/platform/mac/GeolocationServiceMac.mm4
-rw-r--r--WebCore/platform/mac/LocalizedStringsMac.mm37
-rw-r--r--WebCore/platform/mac/PasteboardMac.mm22
-rw-r--r--WebCore/platform/mac/PopupMenuMac.mm4
-rw-r--r--WebCore/platform/mac/ScrollViewMac.mm22
-rw-r--r--WebCore/platform/mac/ThemeMac.mm26
-rw-r--r--WebCore/platform/mac/WebCoreNSStringExtras.mm41
-rw-r--r--WebCore/platform/network/Credential.cpp5
-rw-r--r--WebCore/platform/network/Credential.h2
-rw-r--r--WebCore/platform/network/CredentialStorage.cpp124
-rw-r--r--WebCore/platform/network/CredentialStorage.h44
-rw-r--r--WebCore/platform/network/HTTPHeaderMap.cpp2
-rw-r--r--WebCore/platform/network/ProtectionSpace.cpp5
-rw-r--r--WebCore/platform/network/ProtectionSpace.h10
-rw-r--r--WebCore/platform/network/ProtectionSpaceHash.h70
-rw-r--r--WebCore/platform/network/ResourceErrorBase.cpp6
-rw-r--r--WebCore/platform/network/ResourceHandleInternal.h2
-rw-r--r--WebCore/platform/network/ResourceRequestBase.cpp25
-rw-r--r--WebCore/platform/network/ResourceRequestBase.h10
-rw-r--r--WebCore/platform/network/ResourceResponseBase.cpp8
-rw-r--r--WebCore/platform/network/SocketStreamErrorBase.cpp (renamed from WebCore/platform/sql/chromium/SQLiteFileSystemChromiumMac.cpp)18
-rw-r--r--WebCore/platform/network/SocketStreamErrorBase.h72
-rw-r--r--WebCore/platform/network/SocketStreamHandleBase.cpp106
-rw-r--r--WebCore/platform/network/SocketStreamHandleBase.h72
-rw-r--r--WebCore/platform/network/SocketStreamHandleClient.h62
-rw-r--r--WebCore/platform/network/cf/AuthenticationCF.cpp2
-rw-r--r--WebCore/platform/network/cf/AuthenticationCF.h20
-rw-r--r--WebCore/platform/network/cf/DNSCFNet.cpp122
-rw-r--r--WebCore/platform/network/cf/ResourceErrorCF.cpp2
-rw-r--r--WebCore/platform/network/cf/ResourceHandleCFNet.cpp107
-rw-r--r--WebCore/platform/network/cf/ResourceRequest.h2
-rw-r--r--WebCore/platform/network/cf/ResourceRequestCFNet.cpp4
-rw-r--r--WebCore/platform/network/cf/SocketStreamError.h50
-rw-r--r--WebCore/platform/network/cf/SocketStreamHandle.h68
-rw-r--r--WebCore/platform/network/cf/SocketStreamHandleCFNet.cpp88
-rw-r--r--WebCore/platform/network/chromium/CookieJarChromium.cpp13
-rw-r--r--WebCore/platform/network/chromium/ResourceRequest.h20
-rw-r--r--WebCore/platform/network/chromium/ResourceResponse.h12
-rw-r--r--WebCore/platform/network/chromium/SocketStreamError.h (renamed from WebCore/platform/sql/chromium/SQLiteFileSystemChromiumLinux.cpp)21
-rw-r--r--WebCore/platform/network/chromium/SocketStreamHandle.h72
-rw-r--r--WebCore/platform/network/curl/CookieJarCurl.cpp13
-rw-r--r--WebCore/platform/network/curl/ResourceHandleCurl.cpp8
-rw-r--r--WebCore/platform/network/curl/ResourceHandleManager.cpp105
-rw-r--r--WebCore/platform/network/curl/ResourceHandleManager.h2
-rw-r--r--WebCore/platform/network/curl/ResourceRequest.h2
-rw-r--r--WebCore/platform/network/curl/SocketStreamError.h50
-rw-r--r--WebCore/platform/network/curl/SocketStreamHandle.h68
-rw-r--r--WebCore/platform/network/curl/SocketStreamHandleCurl.cpp89
-rw-r--r--WebCore/platform/network/mac/AuthenticationMac.h18
-rw-r--r--WebCore/platform/network/mac/AuthenticationMac.mm3
-rw-r--r--WebCore/platform/network/mac/FormDataStreamMac.mm15
-rw-r--r--WebCore/platform/network/mac/ResourceErrorMac.mm2
-rw-r--r--WebCore/platform/network/mac/ResourceHandleMac.mm151
-rw-r--r--WebCore/platform/network/mac/ResourceRequest.h2
-rw-r--r--WebCore/platform/network/mac/ResourceRequestMac.mm4
-rw-r--r--WebCore/platform/network/mac/WebCoreURLResponse.h8
-rw-r--r--WebCore/platform/network/mac/WebCoreURLResponse.mm40
-rw-r--r--WebCore/platform/network/qt/DnsPrefetchHelper.cpp35
-rw-r--r--WebCore/platform/network/qt/DnsPrefetchHelper.h75
-rw-r--r--WebCore/platform/network/qt/QNetworkReplyHandler.cpp105
-rw-r--r--WebCore/platform/network/qt/QNetworkReplyHandler.h1
-rw-r--r--WebCore/platform/network/qt/ResourceRequest.h2
-rw-r--r--WebCore/platform/network/qt/SocketStreamError.h50
-rw-r--r--WebCore/platform/network/qt/SocketStreamHandle.h68
-rw-r--r--WebCore/platform/network/qt/SocketStreamHandleSoup.cpp88
-rw-r--r--WebCore/platform/network/soup/CookieJarSoup.cpp13
-rw-r--r--WebCore/platform/network/soup/ResourceHandleSoup.cpp178
-rw-r--r--WebCore/platform/network/soup/ResourceRequest.h2
-rw-r--r--WebCore/platform/network/soup/ResourceRequestSoup.cpp13
-rw-r--r--WebCore/platform/network/soup/ResourceResponse.h4
-rw-r--r--WebCore/platform/network/soup/ResourceResponseSoup.cpp52
-rw-r--r--WebCore/platform/network/soup/SocketStreamError.h50
-rw-r--r--WebCore/platform/network/soup/SocketStreamHandle.h68
-rw-r--r--WebCore/platform/network/soup/SocketStreamHandleSoup.cpp88
-rw-r--r--WebCore/platform/network/win/CookieJarCFNetWin.cpp57
-rw-r--r--WebCore/platform/network/win/CookieJarWin.cpp14
-rw-r--r--WebCore/platform/qt/ClipboardQt.cpp4
-rw-r--r--WebCore/platform/qt/ContextMenuQt.cpp2
-rw-r--r--WebCore/platform/qt/CookieJarQt.cpp15
-rw-r--r--WebCore/platform/qt/DragDataQt.cpp4
-rw-r--r--WebCore/platform/qt/FileSystemQt.cpp6
-rw-r--r--WebCore/platform/qt/Localizations.cpp106
-rw-r--r--WebCore/platform/qt/PasteboardQt.cpp12
-rw-r--r--WebCore/platform/qt/PlatformKeyboardEventQt.cpp2
-rw-r--r--WebCore/platform/qt/PlatformMouseEventQt.cpp37
-rw-r--r--WebCore/platform/qt/PlatformScreenQt.cpp36
-rw-r--r--WebCore/platform/qt/PopupMenuQt.cpp7
-rw-r--r--WebCore/platform/qt/QWebPageClient.h72
-rw-r--r--WebCore/platform/qt/QWebPopup.cpp2
-rw-r--r--WebCore/platform/qt/RenderThemeQt.cpp24
-rw-r--r--WebCore/platform/qt/ScrollViewQt.cpp2
-rw-r--r--WebCore/platform/qt/SearchPopupMenuQt.cpp4
-rw-r--r--WebCore/platform/qt/TemporaryLinkStubs.cpp7
-rw-r--r--WebCore/platform/qt/WheelEventQt.cpp55
-rw-r--r--WebCore/platform/qt/WidgetQt.cpp16
-rw-r--r--WebCore/platform/sql/SQLValue.cpp8
-rw-r--r--WebCore/platform/sql/SQLValue.h4
-rw-r--r--WebCore/platform/sql/SQLiteTransaction.cpp15
-rw-r--r--WebCore/platform/sql/SQLiteTransaction.h5
-rw-r--r--WebCore/platform/sql/chromium/SQLiteFileSystemChromium.cpp10
-rw-r--r--WebCore/platform/sql/chromium/SQLiteFileSystemChromiumPosix.cpp190
-rw-r--r--WebCore/platform/sql/chromium/SQLiteFileSystemChromiumWin.cpp13
-rw-r--r--WebCore/platform/text/CString.cpp2
-rw-r--r--WebCore/platform/text/CString.h2
-rw-r--r--WebCore/platform/text/PlatformString.h30
-rw-r--r--WebCore/platform/text/RegularExpression.cpp2
-rw-r--r--WebCore/platform/text/String.cpp44
-rw-r--r--WebCore/platform/text/StringImpl.cpp114
-rw-r--r--WebCore/platform/text/StringImpl.h33
-rw-r--r--WebCore/platform/text/TextEncoding.cpp1
-rw-r--r--WebCore/platform/text/TextEncodingRegistry.cpp6
-rw-r--r--WebCore/platform/text/UnicodeRange.h4
-rw-r--r--WebCore/platform/text/cf/StringCF.cpp2
-rw-r--r--WebCore/platform/text/haiku/TextBreakIteratorInternalICUHaiku.cpp6
-rw-r--r--WebCore/platform/text/mac/TextCodecMac.cpp17
-rw-r--r--WebCore/platform/text/qt/TextCodecQt.cpp21
-rw-r--r--WebCore/platform/win/ClipboardWin.cpp51
-rw-r--r--WebCore/platform/win/CursorWin.cpp2
-rw-r--r--WebCore/platform/win/PasteboardWin.cpp17
-rw-r--r--WebCore/platform/win/PlatformScreenWin.cpp2
-rw-r--r--WebCore/platform/win/PopupMenuWin.cpp579
-rw-r--r--WebCore/platform/win/SharedBufferWin.cpp4
-rw-r--r--WebCore/platform/win/SharedTimerWin.cpp58
-rw-r--r--WebCore/platform/wince/CursorWince.cpp109
-rw-r--r--WebCore/platform/wince/DragDataWince.cpp90
-rw-r--r--WebCore/platform/wince/DragImageWince.cpp63
-rw-r--r--WebCore/platform/wince/EditorWince.cpp43
-rw-r--r--WebCore/platform/wince/FileChooserWince.cpp60
-rw-r--r--WebCore/platform/wince/FileSystemWince.cpp283
-rw-r--r--WebCore/platform/wince/KURLWince.cpp30
-rw-r--r--WebCore/platform/wince/KeygenWince.cpp101
-rw-r--r--WebCore/platform/wince/MIMETypeRegistryWince.cpp135
-rw-r--r--WebCore/platform/wince/PasteboardWince.cpp330
-rw-r--r--WebCore/platform/wince/SearchPopupMenuWince.cpp53
-rw-r--r--WebCore/platform/wince/SharedTimerWince.cpp130
-rw-r--r--WebCore/platform/wince/SystemTimeWince.cpp39
-rw-r--r--WebCore/platform/wx/CursorWx.cpp6
-rw-r--r--WebCore/platform/wx/FileChooserWx.cpp40
-rw-r--r--WebCore/platform/wx/FileSystemWx.cpp35
-rw-r--r--WebCore/platform/wx/KURLWx.cpp40
-rw-r--r--WebCore/platform/wx/PasteboardWx.cpp14
-rw-r--r--WebCore/platform/wx/PopupMenuWx.cpp2
-rw-r--r--WebCore/platform/wx/RenderThemeWx.cpp43
-rw-r--r--WebCore/platform/wx/SSLKeyGeneratorWx.cpp44
-rw-r--r--WebCore/platform/wx/ScrollbarThemeWx.cpp184
-rw-r--r--WebCore/platform/wx/ScrollbarThemeWx.h54
-rw-r--r--WebCore/platform/wx/SearchPopupMenuWx.cpp55
-rw-r--r--WebCore/platform/wx/SharedBufferWx.cpp40
-rw-r--r--WebCore/platform/wx/SystemTimeWx.cpp43
-rw-r--r--WebCore/platform/wx/TemporaryLinkStubs.cpp3
-rw-r--r--WebCore/platform/wx/TextBreakIteratorInternalICUWx.cpp42
-rw-r--r--WebCore/platform/wx/WidgetWx.cpp6
-rw-r--r--WebCore/platform/wx/wxcode/gtk/scrollbar_render.cpp166
-rw-r--r--WebCore/platform/wx/wxcode/mac/carbon/non-kerned-drawing.cpp2
-rw-r--r--WebCore/platform/wx/wxcode/mac/carbon/scrollbar_render.cpp107
-rw-r--r--WebCore/platform/wx/wxcode/scrollbar_render.h67
-rw-r--r--WebCore/platform/wx/wxcode/win/non-kerned-drawing.cpp14
-rw-r--r--WebCore/platform/wx/wxcode/win/scrollbar_render.cpp195
411 files changed, 18982 insertions, 3921 deletions
diff --git a/WebCore/platform/ContextMenu.cpp b/WebCore/platform/ContextMenu.cpp
index cca11b5..ee6aa4e 100644
--- a/WebCore/platform/ContextMenu.cpp
+++ b/WebCore/platform/ContextMenu.cpp
@@ -27,6 +27,8 @@
#include "config.h"
#include "ContextMenu.h"
+#if ENABLE(CONTEXT_MENUS)
+
#include "ContextMenuController.h"
#include "ContextMenuClient.h"
#include "CSSComputedStyleDeclaration.h"
@@ -359,10 +361,10 @@ void ContextMenu::populate()
appendItem(StopItem);
appendItem(ReloadItem);
#else
- if (loader->canGoBackOrForward(-1))
+ if (frame->page() && frame->page()->canGoBackOrForward(-1))
appendItem(BackItem);
- if (loader->canGoBackOrForward(1))
+ if (frame->page() && frame->page()->canGoBackOrForward(1))
appendItem(ForwardItem);
// use isLoadingInAPISense rather than isLoading because Stop/Reload are
@@ -514,6 +516,7 @@ void ContextMenu::populate()
}
}
+#if ENABLE(INSPECTOR)
void ContextMenu::addInspectElementItem()
{
Node* node = m_hitTestResult.innerNonSharedNode();
@@ -535,6 +538,7 @@ void ContextMenu::addInspectElementItem()
appendItem(*separatorItem());
appendItem(InspectElementItem);
}
+#endif // ENABLE(INSPECTOR)
void ContextMenu::checkOrEnableIfNeeded(ContextMenuItem& item) const
{
@@ -717,10 +721,10 @@ void ContextMenu::checkOrEnableIfNeeded(ContextMenuItem& item) const
#endif
#if PLATFORM(GTK)
case ContextMenuItemTagGoBack:
- shouldEnable = frame->loader()->canGoBackOrForward(-1);
+ shouldEnable = frame->page() && frame->page()->canGoBackOrForward(-1);
break;
case ContextMenuItemTagGoForward:
- shouldEnable = frame->loader()->canGoBackOrForward(1);
+ shouldEnable = frame->page() && frame->page()->canGoBackOrForward(1);
break;
case ContextMenuItemTagStop:
shouldEnable = frame->loader()->documentLoader()->isLoadingInAPISense();
@@ -772,7 +776,9 @@ void ContextMenu::checkOrEnableIfNeeded(ContextMenuItem& item) const
case ContextMenuItemTagTextDirectionMenu:
case ContextMenuItemTagPDFSinglePageScrolling:
case ContextMenuItemTagPDFFacingPagesScrolling:
+#if ENABLE(INSPECTOR)
case ContextMenuItemTagInspectElement:
+#endif
case ContextMenuItemBaseApplicationTag:
break;
}
@@ -781,4 +787,6 @@ void ContextMenu::checkOrEnableIfNeeded(ContextMenuItem& item) const
item.setEnabled(shouldEnable);
}
-}
+} // namespace WebCore
+
+#endif // ENABLE(CONTEXT_MENUS)
diff --git a/WebCore/platform/ContextMenuItem.h b/WebCore/platform/ContextMenuItem.h
index 3a4cdfa..6b9d0a9 100644
--- a/WebCore/platform/ContextMenuItem.h
+++ b/WebCore/platform/ContextMenuItem.h
@@ -46,6 +46,8 @@ typedef struct _GtkMenuItem GtkMenuItem;
#include <QAction>
#elif PLATFORM(WX)
class wxMenuItem;
+#elif PLATFORM(HAIKU)
+class BMenuItem;
#endif
namespace WebCore {
@@ -119,7 +121,9 @@ namespace WebCore {
ContextMenuItemTagRightToLeft,
ContextMenuItemTagPDFSinglePageScrolling,
ContextMenuItemTagPDFFacingPagesScrolling,
+#if ENABLE(INSPECTOR)
ContextMenuItemTagInspectElement,
+#endif
ContextMenuItemTagTextDirectionMenu, // Text Direction sub-menu
ContextMenuItemTagTextDirectionDefault,
ContextMenuItemTagTextDirectionLeftToRight,
@@ -204,6 +208,8 @@ namespace WebCore {
bool checked;
bool enabled;
};
+#elif PLATFORM(HAIKU)
+ typedef BMenuItem* PlatformMenuItemDescription;
#else
typedef void* PlatformMenuItemDescription;
#endif
diff --git a/WebCore/platform/Cookie.h b/WebCore/platform/Cookie.h
new file mode 100644
index 0000000..0fe3851
--- /dev/null
+++ b/WebCore/platform/Cookie.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2009 Joseph Pecoraro. 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 Cookie_h
+#define Cookie_h
+
+#include "PlatformString.h"
+#include "StringHash.h"
+
+namespace WebCore {
+
+ // This struct is currently only used to provide more cookies information
+ // to the Web Inspector.
+
+ struct Cookie {
+ Cookie(const String& name, const String& value, const String& domain,
+ const String& path, double expires, bool httpOnly, bool secure,
+ bool session)
+ : name(name)
+ , value(value)
+ , domain(domain)
+ , path(path)
+ , expires(expires)
+ , httpOnly(httpOnly)
+ , secure(secure)
+ , session(session)
+ {
+ }
+
+ String name;
+ String value;
+ String domain;
+ String path;
+ double expires;
+ bool httpOnly;
+ bool secure;
+ bool session;
+ };
+
+ struct CookieHash {
+ static unsigned hash(Cookie key)
+ {
+ return StringHash::hash(key.name) + StringHash::hash(key.domain) + StringHash::hash(key.path) + key.secure;
+ }
+
+ static bool equal(Cookie a, Cookie b)
+ {
+ return a.name == b.name && a.domain == b.domain && a.path == b.path && a.secure == b.secure;
+ }
+ };
+}
+
+namespace WTF {
+ template<typename T> struct DefaultHash;
+ template<> struct DefaultHash<WebCore::Cookie> {
+ typedef WebCore::CookieHash Hash;
+ };
+}
+
+#endif
diff --git a/WebCore/platform/CookieJar.h b/WebCore/platform/CookieJar.h
index 6159386..987543e 100644
--- a/WebCore/platform/CookieJar.h
+++ b/WebCore/platform/CookieJar.h
@@ -26,15 +26,21 @@
#ifndef CookieJar_h
#define CookieJar_h
+#include <wtf/Vector.h>
+
namespace WebCore {
+ class Document;
class KURL;
class String;
- class Document;
+
+ struct Cookie;
String cookies(const Document*, const KURL&);
void setCookies(Document*, const KURL&, const String&);
bool cookiesEnabled(const Document*);
+ bool getRawCookies(const Document*, const KURL&, Vector<Cookie>&);
+ void deleteCookie(const Document*, const KURL&, const String&);
}
diff --git a/WebCore/platform/CrossThreadCopier.cpp b/WebCore/platform/CrossThreadCopier.cpp
index 9ca626f..d02da6c 100644
--- a/WebCore/platform/CrossThreadCopier.cpp
+++ b/WebCore/platform/CrossThreadCopier.cpp
@@ -41,7 +41,7 @@ namespace WebCore {
CrossThreadCopierBase<false, String>::Type CrossThreadCopierBase<false, String>::copy(const String& str)
{
- return str.copy();
+ return str.crossThreadString();
}
CrossThreadCopierBase<false, ResourceError>::Type CrossThreadCopierBase<false, ResourceError>::copy(const ResourceError& error)
diff --git a/WebCore/platform/CrossThreadCopier.h b/WebCore/platform/CrossThreadCopier.h
index d12d72d..178e056 100644
--- a/WebCore/platform/CrossThreadCopier.h
+++ b/WebCore/platform/CrossThreadCopier.h
@@ -46,6 +46,7 @@ namespace WebCore {
class String;
struct CrossThreadResourceResponseData;
struct CrossThreadResourceRequestData;
+ struct ThreadableLoaderOptions;
template<typename T> struct CrossThreadCopierPassThrough {
typedef T Type;
@@ -65,6 +66,9 @@ namespace WebCore {
template<typename T> struct CrossThreadCopierBase<false, T*> : public CrossThreadCopierPassThrough<T*> {
};
+ template<> struct CrossThreadCopierBase<false, ThreadableLoaderOptions> : public CrossThreadCopierPassThrough<ThreadableLoaderOptions> {
+ };
+
// Custom copy methods.
template<typename T> struct CrossThreadCopierBase<false, RefPtr<ThreadSafeShared<T> > > {
typedef PassRefPtr<T> Type;
diff --git a/WebCore/platform/Cursor.h b/WebCore/platform/Cursor.h
index ea75191..2d041d2 100644
--- a/WebCore/platform/Cursor.h
+++ b/WebCore/platform/Cursor.h
@@ -40,6 +40,8 @@ typedef struct _GdkCursor GdkCursor;
#include <QCursor>
#elif PLATFORM(CHROMIUM)
#include "PlatformCursor.h"
+#elif PLATFORM(HAIKU)
+#include <app/Cursor.h>
#endif
#if PLATFORM(MAC)
@@ -86,6 +88,9 @@ namespace WebCore {
#elif PLATFORM(CHROMIUM)
// See PlatformCursor.h
typedef void* PlatformCursorHandle;
+#elif PLATFORM(HAIKU)
+ typedef BCursor* PlatformCursor;
+ typedef BCursor* PlatformCursorHandle;
#else
typedef void* PlatformCursor;
typedef void* PlatformCursorHandle;
diff --git a/WebCore/platform/DragData.cpp b/WebCore/platform/DragData.cpp
index bf2275a..4518909 100644
--- a/WebCore/platform/DragData.cpp
+++ b/WebCore/platform/DragData.cpp
@@ -26,6 +26,7 @@
#include "config.h"
#include "DragData.h"
+#if ENABLE(DRAG_SUPPORT)
namespace WebCore {
#if !PLATFORM(MAC)
@@ -39,4 +40,6 @@ DragData::DragData(DragDataRef data, const IntPoint& clientPosition, const IntPo
}
#endif
-}
+} // namespace WebCore
+
+#endif // ENABLE(DRAG_SUPPORT)
diff --git a/WebCore/platform/DragData.h b/WebCore/platform/DragData.h
index a1555e3..116ffdd 100644
--- a/WebCore/platform/DragData.h
+++ b/WebCore/platform/DragData.h
@@ -58,6 +58,9 @@ typedef void* DragDataRef;
typedef void* DragDataRef;
#elif PLATFORM(CHROMIUM)
#include "DragDataRef.h"
+#elif PLATFORM(HAIKU)
+class BMessage;
+typedef class BMessage* DragDataRef;
#endif
diff --git a/WebCore/platform/DragImage.cpp b/WebCore/platform/DragImage.cpp
index adf9a57..aff4aba 100644
--- a/WebCore/platform/DragImage.cpp
+++ b/WebCore/platform/DragImage.cpp
@@ -25,6 +25,8 @@
#include "config.h"
#include "DragImage.h"
+
+#if ENABLE(DRAG_SUPPORT)
#include "DragController.h"
#include "Frame.h"
@@ -71,4 +73,6 @@ DragImageRef createDragImageForSelection(Frame* frame)
return image;
}
-}
+} // namespace WebCore
+
+#endif // ENABLE(DRAG_SUPPORT)
diff --git a/WebCore/platform/DragImage.h b/WebCore/platform/DragImage.h
index 4887066..00bd7ed 100644
--- a/WebCore/platform/DragImage.h
+++ b/WebCore/platform/DragImage.h
@@ -48,6 +48,8 @@ class wxDragImage;
#include "DragImageRef.h"
#elif PLATFORM(GTK)
typedef struct _GdkPixbuf GdkPixbuf;
+#elif PLATFORM(HAIKU)
+class BBitmap;
#endif
//We need to #define YOffset as it needs to be shared with WebKit
@@ -72,8 +74,13 @@ namespace WebCore {
typedef wxDragImage* DragImageRef;
#elif PLATFORM(GTK)
typedef GdkPixbuf* DragImageRef;
+<<<<<<< HEAD:WebCore/platform/DragImage.h
#elif PLATFORM(ANDROID)
typedef void* DragImageRef;
+=======
+#elif PLATFORM(HAIKU)
+ typedef BBitmap* DragImageRef;
+>>>>>>> webkit.org at 49305:WebCore/platform/DragImage.h
#endif
IntSize dragImageSize(DragImageRef);
diff --git a/WebCore/platform/FileSystem.h b/WebCore/platform/FileSystem.h
index e23b6da..958eb73 100644
--- a/WebCore/platform/FileSystem.h
+++ b/WebCore/platform/FileSystem.h
@@ -170,6 +170,10 @@ char* filenameFromString(const String&);
String filenameForDisplay(const String&);
#endif
+#if PLATFORM(CHROMIUM)
+String pathGetDisplayFileName(const String&);
+#endif
+
} // namespace WebCore
#endif // FileSystem_h
diff --git a/WebCore/platform/HostWindow.h b/WebCore/platform/HostWindow.h
index 3a024de..80f6bdc 100644
--- a/WebCore/platform/HostWindow.h
+++ b/WebCore/platform/HostWindow.h
@@ -48,12 +48,15 @@ public:
virtual IntPoint screenToWindow(const IntPoint&) const = 0;
virtual IntRect windowToScreen(const IntRect&) const = 0;
- // Method for retrieving the native window.
- virtual PlatformWidget platformWindow() const = 0;
+ // Method for retrieving the native client of the page.
+ virtual PlatformPageClient platformPageClient() const = 0;
// For scrolling a rect into view recursively. Useful in the cases where a WebView is embedded inside some containing
// platform-specific ScrollView.
virtual void scrollRectIntoView(const IntRect&, const ScrollView*) const = 0;
+
+ // To notify WebKit of scrollbar mode changes.
+ virtual void scrollbarsModeDidChange() const = 0;
};
} // namespace WebCore
diff --git a/WebCore/platform/KURL.cpp b/WebCore/platform/KURL.cpp
index ec8c55c..ffacc19 100644
--- a/WebCore/platform/KURL.cpp
+++ b/WebCore/platform/KURL.cpp
@@ -302,13 +302,13 @@ void KURL::invalidate()
m_fragmentEnd = 0;
}
-KURL::KURL(const char* url)
+KURL::KURL(ParsedURLStringTag, const char* url)
{
parse(url, 0);
ASSERT(url == m_string);
}
-KURL::KURL(const String& url)
+KURL::KURL(ParsedURLStringTag, const String& url)
{
parse(url);
ASSERT(url == m_string);
@@ -529,7 +529,7 @@ void KURL::init(const KURL& base, const String& relative, const TextEncoding& en
KURL KURL::copy() const
{
KURL result = *this;
- result.m_string = result.m_string.copy();
+ result.m_string = result.m_string.crossThreadString();
return result;
}
@@ -1641,7 +1641,7 @@ String mimeTypeFromDataURL(const String& url)
const KURL& blankURL()
{
- DEFINE_STATIC_LOCAL(KURL, staticBlankURL, ("about:blank"));
+ DEFINE_STATIC_LOCAL(KURL, staticBlankURL, (ParsedURLString, "about:blank"));
return staticBlankURL;
}
diff --git a/WebCore/platform/KURL.h b/WebCore/platform/KURL.h
index 0809f7e..73fadd1 100644
--- a/WebCore/platform/KURL.h
+++ b/WebCore/platform/KURL.h
@@ -55,15 +55,18 @@ namespace WebCore {
class TextEncoding;
struct KURLHash;
+enum ParsedURLStringTag { ParsedURLString };
+
class KURL {
public:
// Generates a URL which contains a null string.
KURL() { invalidate(); }
- // The argument is an absolute URL string. The string is assumed to be
- // an already encoded (ASCII-only) valid absolute URL.
- explicit KURL(const char*);
- explicit KURL(const String&);
+ // The argument is an absolute URL string. The string is assumed to be output of KURL::string() called on a valid
+ // KURL object, or indiscernible from such.
+ // It is usually best to avoid repeatedly parsing a string, unless memory saving outweigh the possible slow-downs.
+ KURL(ParsedURLStringTag, const char*);
+ KURL(ParsedURLStringTag, const String&);
// 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/WebCore/platform/KURLGoogle.cpp b/WebCore/platform/KURLGoogle.cpp
index 1cb08c1..b323332 100644
--- a/WebCore/platform/KURLGoogle.cpp
+++ b/WebCore/platform/KURLGoogle.cpp
@@ -331,7 +331,7 @@ const String& KURLGooglePrivate::string() const
// Creates with NULL-terminated string input representing an absolute URL.
// WebCore generally calls this only with hardcoded strings, so the input is
// ASCII. We treat is as UTF-8 just in case.
-KURL::KURL(const char *url)
+KURL::KURL(ParsedURLStringTag, const char *url)
{
// FIXME The Mac code checks for beginning with a slash and converting to a
// file: URL. We will want to add this as well once we can compile on a
@@ -349,7 +349,7 @@ KURL::KURL(const char *url)
// to a string and then converted back. In this case, the URL is already
// canonical and in proper escaped form so needs no encoding. We treat it was
// UTF-8 just in case.
-KURL::KURL(const String& url)
+KURL::KURL(ParsedURLStringTag, const String& url)
{
if (!url.isNull())
m_url.init(KURL(), url, 0);
@@ -728,13 +728,8 @@ String decodeURLEscapeSequences(const String& str)
// cause security holes. We never call this function for components, and
// just return the ASCII versions instead.
//
-// However, this static function is called directly in some cases. It appears
-// that this only happens for javascript: URLs, so this is essentially the
-// JavaScript URL decoder. It assumes UTF-8 encoding.
-//
-// IE doesn't unescape %00, forcing you to use \x00 in JS strings, so we do
-// the same. This also eliminates NULL-related problems should a consumer
-// incorrectly call this function for non-JavaScript.
+// This function is also used to decode javascript: URLs and as a general
+// purpose unescaping function.
//
// FIXME These should be merged to the KURL.cpp implementation.
String decodeURLEscapeSequences(const String& str, const TextEncoding& encoding)
@@ -757,15 +752,9 @@ String decodeURLEscapeSequences(const String& str, const TextEncoding& encoding)
for (int i = 0; i < inputLength; i++) {
if (input[i] == '%') {
unsigned char ch;
- if (url_canon::DecodeEscaped(input, &i, inputLength, &ch)) {
- if (!ch) {
- // Never unescape NULLs.
- unescaped.push_back('%');
- unescaped.push_back('0');
- unescaped.push_back('0');
- } else
- unescaped.push_back(ch);
- } else {
+ if (url_canon::DecodeEscaped(input, &i, inputLength, &ch))
+ unescaped.push_back(ch);
+ else {
// Invalid escape sequence, copy the percent literal.
unescaped.push_back('%');
}
@@ -936,7 +925,7 @@ unsigned KURL::pathAfterLastSlash() const
const KURL& blankURL()
{
- static KURL staticBlankURL("about:blank");
+ static KURL staticBlankURL(ParsedURLString, "about:blank");
return staticBlankURL;
}
diff --git a/WebCore/platform/KURLHash.h b/WebCore/platform/KURLHash.h
index 4deb078..7448a49 100644
--- a/WebCore/platform/KURLHash.h
+++ b/WebCore/platform/KURLHash.h
@@ -52,7 +52,7 @@ 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::String(HashTableDeletedValue)); }
+ static void constructDeletedValue(WebCore::KURL& slot) { new (&slot) WebCore::KURL(WebCore::ParsedURLString, WebCore::String(HashTableDeletedValue)); }
static bool isDeletedValue(const WebCore::KURL& slot) { return slot.string().isHashTableDeletedValue(); }
};
diff --git a/WebCore/platform/LocalizedStrings.h b/WebCore/platform/LocalizedStrings.h
index 7c586d3..0fa9f71 100644
--- a/WebCore/platform/LocalizedStrings.h
+++ b/WebCore/platform/LocalizedStrings.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003, 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2003, 2006, 2009 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -38,6 +38,7 @@ namespace WebCore {
String fileButtonChooseFileLabel();
String fileButtonNoFileSelectedLabel();
String copyImageUnknownFileLabel();
+#if ENABLE(CONTEXT_MENUS)
String contextMenuItemTagOpenLinkInNewWindow();
String contextMenuItemTagDownloadLinkToDisk();
String contextMenuItemTagCopyLinkToClipboard();
@@ -103,6 +104,7 @@ namespace WebCore {
String contextMenuItemTagChangeBack(const String& replacedString);
#endif
String contextMenuItemTagInspectElement();
+#endif // ENABLE(CONTEXT_MENUS)
String searchMenuNoRecentSearchesText();
String searchMenuRecentSearchesText();
@@ -115,6 +117,7 @@ namespace WebCore {
String AXHeadingText();
String AXDefinitionListTermText();
String AXDefinitionListDefinitionText();
+ String AXARIAContentGroupText(const String& ariaType);
String AXButtonActionVerb();
String AXRadioButtonActionVerb();
@@ -135,6 +138,9 @@ namespace WebCore {
String mediaElementLoadingStateText();
String mediaElementLiveBroadcastStateText();
+ String localizedMediaControlElementString(const String&);
+ String localizedMediaControlElementHelpText(const String&);
+ String localizedMediaTimeDescription(float);
}
#endif
diff --git a/WebCore/platform/MIMETypeRegistry.cpp b/WebCore/platform/MIMETypeRegistry.cpp
index 1819e1d..32dd3f6 100644
--- a/WebCore/platform/MIMETypeRegistry.cpp
+++ b/WebCore/platform/MIMETypeRegistry.cpp
@@ -94,7 +94,7 @@ static void initializeSupportedImageMIMETypes()
#elif PLATFORM(QT)
QList<QByteArray> formats = QImageReader::supportedImageFormats();
- for (size_t i = 0; i < formats.size(); ++i) {
+ for (size_t i = 0; i < static_cast<size_t>(formats.size()); ++i) {
#if ENABLE(SVG)
/*
* Qt has support for SVG, but we want to use KSVG2
@@ -173,7 +173,7 @@ static void initializeSupportedImageMIMETypesForEncoding()
#endif
#elif PLATFORM(QT)
QList<QByteArray> formats = QImageWriter::supportedImageFormats();
- for (size_t i = 0; i < formats.size(); ++i) {
+ for (int i = 0; i < formats.size(); ++i) {
String mimeType = MIMETypeRegistry::getMIMETypeForExtension(formats.at(i).constData());
supportedImageMIMETypesForEncoding->add(mimeType);
}
diff --git a/WebCore/platform/Pasteboard.h b/WebCore/platform/Pasteboard.h
index 883364a..188b962 100644
--- a/WebCore/platform/Pasteboard.h
+++ b/WebCore/platform/Pasteboard.h
@@ -86,6 +86,7 @@ public:
static Pasteboard* generalPasteboard();
void writeSelection(Range*, bool canSmartCopyOrDelete, Frame*);
+ void writePlainText(const String&);
void writeURL(const KURL&, const String&, Frame* = 0);
void writeImage(Node*, const KURL&, const String& title);
#if PLATFORM(MAC)
@@ -95,13 +96,14 @@ public:
bool canSmartReplace();
PassRefPtr<DocumentFragment> documentFragment(Frame*, PassRefPtr<Range>, bool allowPlainText, bool& chosePlainText);
String plainText(Frame* = 0);
-#if PLATFORM(QT)
+#if PLATFORM(QT) || PLATFORM(CHROMIUM)
bool isSelectionMode() const;
void setSelectionMode(bool selectionMode);
#endif
#if PLATFORM(GTK)
void setHelper(PasteboardHelper*);
+ PasteboardHelper* m_helper;
#endif
private:
@@ -117,11 +119,7 @@ private:
HWND m_owner;
#endif
-#if PLATFORM(GTK)
- PasteboardHelper* m_helper;
-#endif
-
-#if PLATFORM(QT)
+#if PLATFORM(QT) || PLATFORM(CHROMIUM)
bool m_selectionMode;
#endif
diff --git a/WebCore/platform/PlatformKeyboardEvent.h b/WebCore/platform/PlatformKeyboardEvent.h
index 1499ac5..b5c2e95 100644
--- a/WebCore/platform/PlatformKeyboardEvent.h
+++ b/WebCore/platform/PlatformKeyboardEvent.h
@@ -59,6 +59,10 @@ QT_END_NAMESPACE
class wxKeyEvent;
#endif
+#if PLATFORM(HAIKU)
+class BMessage;
+#endif
+
namespace WebCore {
class PlatformKeyboardEvent {
@@ -155,6 +159,10 @@ namespace WebCore {
PlatformKeyboardEvent(wxKeyEvent&);
#endif
+#if PLATFORM(HAIKU)
+ PlatformKeyboardEvent(BMessage*);
+#endif
+
#if PLATFORM(WIN) || PLATFORM(CHROMIUM)
bool isSystemKey() const { return m_isSystemKey; }
#endif
diff --git a/WebCore/platform/PlatformMenuDescription.h b/WebCore/platform/PlatformMenuDescription.h
index ab71710..c986207 100644
--- a/WebCore/platform/PlatformMenuDescription.h
+++ b/WebCore/platform/PlatformMenuDescription.h
@@ -40,6 +40,8 @@ typedef struct HMENU__* HMENU;
typedef struct _GtkMenu GtkMenu;
#elif PLATFORM(WX)
class wxMenu;
+#elif PLATFORM(HAIKU)
+class BMenu;
#endif
namespace WebCore {
@@ -58,6 +60,8 @@ namespace WebCore {
typedef void* PlatformMenuDescription;
#elif PLATFORM(WX)
typedef wxMenu* PlatformMenuDescription;
+#elif PLATFORM(HAIKU)
+ typedef BMenu* PlatformMenuDescription;
#else
typedef void* PlatformMenuDescription;
#endif
diff --git a/WebCore/platform/PlatformMouseEvent.h b/WebCore/platform/PlatformMouseEvent.h
index 2543d40..99acc63 100644
--- a/WebCore/platform/PlatformMouseEvent.h
+++ b/WebCore/platform/PlatformMouseEvent.h
@@ -36,6 +36,7 @@ typedef struct _GdkEventMotion GdkEventMotion;
#if PLATFORM(QT)
QT_BEGIN_NAMESPACE
class QInputEvent;
+class QGraphicsSceneMouseEvent;
QT_END_NAMESPACE
#endif
@@ -50,6 +51,10 @@ typedef long LPARAM;
class wxMouseEvent;
#endif
+#if PLATFORM(HAIKU)
+class BMessage;
+#endif
+
namespace WebCore {
// These button numbers match the ones used in the DOM API, 0 through 2, except for NoButton which isn't specified.
@@ -116,6 +121,7 @@ namespace WebCore {
#if PLATFORM(QT)
PlatformMouseEvent(QInputEvent*, int clickCount);
+ PlatformMouseEvent(QGraphicsSceneMouseEvent*, int clickCount);
#endif
#if PLATFORM(WIN)
@@ -128,6 +134,10 @@ namespace WebCore {
PlatformMouseEvent(const wxMouseEvent&, const wxPoint& globalPoint, int clickCount);
#endif
+#if PLATFORM(HAIKU)
+ PlatformMouseEvent(const BMessage*);
+#endif
+
protected:
IntPoint m_position;
IntPoint m_globalPosition;
diff --git a/WebCore/platform/PlatformWheelEvent.h b/WebCore/platform/PlatformWheelEvent.h
index ae8df4e..9a4a0cb 100644
--- a/WebCore/platform/PlatformWheelEvent.h
+++ b/WebCore/platform/PlatformWheelEvent.h
@@ -35,6 +35,7 @@ typedef struct _GdkEventScroll GdkEventScroll;
#if PLATFORM(QT)
QT_BEGIN_NAMESPACE
class QWheelEvent;
+class QGraphicsSceneWheelEvent;
QT_END_NAMESPACE
#endif
@@ -49,6 +50,10 @@ class wxMouseEvent;
class wxPoint;
#endif
+#if PLATFORM(HAIKU)
+class BMessage;
+#endif
+
namespace WebCore {
class FloatPoint;
@@ -88,6 +93,15 @@ namespace WebCore {
void accept() { m_isAccepted = true; }
void ignore() { m_isAccepted = false; }
+ void turnVerticalTicksIntoHorizontal()
+ {
+ m_deltaX = m_deltaY;
+ m_deltaY = 0;
+
+ m_wheelTicksX = m_wheelTicksY;
+ m_wheelTicksY = 0;
+ }
+
#if PLATFORM(GTK)
PlatformWheelEvent(GdkEventScroll*);
#endif
@@ -98,6 +112,8 @@ namespace WebCore {
#if PLATFORM(QT)
PlatformWheelEvent(QWheelEvent*);
+ PlatformWheelEvent(QGraphicsSceneWheelEvent*);
+ void applyDelta(int delta, Qt::Orientation);
#endif
#if PLATFORM(WIN)
@@ -109,6 +125,10 @@ namespace WebCore {
PlatformWheelEvent(const wxMouseEvent&, const wxPoint&);
#endif
+#if PLATFORM(HAIKU)
+ PlatformWheelEvent(BMessage*);
+#endif
+
protected:
IntPoint m_position;
IntPoint m_globalPosition;
diff --git a/WebCore/platform/PopupMenu.h b/WebCore/platform/PopupMenu.h
index fc85d60..2315f02 100644
--- a/WebCore/platform/PopupMenu.h
+++ b/WebCore/platform/PopupMenu.h
@@ -59,6 +59,8 @@ class wxMenu;
#include <wx/event.h>
#elif PLATFORM(CHROMIUM)
#include "PopupMenuPrivate.h"
+#elif PLATFORM(HAIKU)
+class BMenu;
#endif
namespace WebCore {
@@ -92,6 +94,8 @@ public:
#if PLATFORM(WIN)
Scrollbar* scrollbar() const { return m_scrollbar.get(); }
+ static LPCTSTR popupClassName();
+
bool up(unsigned lines = 1);
bool down(unsigned lines = 1);
@@ -153,6 +157,10 @@ private:
void calculatePositionAndSize(const IntRect&, FrameView*);
void invalidateItem(int index);
+ static LRESULT CALLBACK PopupMenuWndProc(HWND, UINT, WPARAM, LPARAM);
+ LRESULT wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
+ static void registerClass();
+
RefPtr<Scrollbar> m_scrollbar;
HWND m_popup;
HDC m_DC;
@@ -164,6 +172,7 @@ private:
int m_wheelDelta;
int m_focusedIndex;
bool m_scrollbarCapturingMouse;
+ bool m_showPopup;
#elif PLATFORM(GTK)
IntPoint m_menuPosition;
GtkMenu* m_popup;
@@ -177,6 +186,8 @@ private:
void OnMenuItemSelected(wxCommandEvent&);
#elif PLATFORM(CHROMIUM)
PopupMenuPrivate p;
+#elif PLATFORM(HAIKU)
+ BMenu* m_menu;
#endif
};
diff --git a/WebCore/platform/PopupMenuClient.h b/WebCore/platform/PopupMenuClient.h
index 2a9625b..2614fe2 100644
--- a/WebCore/platform/PopupMenuClient.h
+++ b/WebCore/platform/PopupMenuClient.h
@@ -49,7 +49,7 @@ public:
virtual int clientPaddingRight() const = 0;
virtual int listSize() const = 0;
virtual int selectedIndex() const = 0;
- virtual void hidePopup() = 0;
+ virtual void popupDidHide() = 0;
virtual bool itemIsSeparator(unsigned listIndex) const = 0;
virtual bool itemIsLabel(unsigned listIndex) const = 0;
virtual bool itemIsSelected(unsigned listIndex) const = 0;
diff --git a/WebCore/platform/ScrollView.cpp b/WebCore/platform/ScrollView.cpp
index 54fa998..8c4b115 100644
--- a/WebCore/platform/ScrollView.cpp
+++ b/WebCore/platform/ScrollView.cpp
@@ -83,6 +83,7 @@ void ScrollView::setHasHorizontalScrollbar(bool hasBar)
if (hasBar && !m_horizontalScrollbar) {
m_horizontalScrollbar = createScrollbar(HorizontalScrollbar);
addChild(m_horizontalScrollbar.get());
+ m_horizontalScrollbar->styleChanged();
} else if (!hasBar && m_horizontalScrollbar) {
removeChild(m_horizontalScrollbar.get());
m_horizontalScrollbar = 0;
@@ -94,6 +95,7 @@ void ScrollView::setHasVerticalScrollbar(bool hasBar)
if (hasBar && !m_verticalScrollbar) {
m_verticalScrollbar = createScrollbar(VerticalScrollbar);
addChild(m_verticalScrollbar.get());
+ m_verticalScrollbar->styleChanged();
} else if (!hasBar && m_verticalScrollbar) {
removeChild(m_verticalScrollbar.get());
m_verticalScrollbar = 0;
@@ -105,7 +107,6 @@ PassRefPtr<Scrollbar> ScrollView::createScrollbar(ScrollbarOrientation orientati
{
return Scrollbar::createNativeScrollbar(this, orientation, RegularScrollbar);
}
-#endif
void ScrollView::setScrollbarModes(ScrollbarMode horizontalMode, ScrollbarMode verticalMode)
{
@@ -118,6 +119,7 @@ void ScrollView::setScrollbarModes(ScrollbarMode horizontalMode, ScrollbarMode v
else
updateScrollbars(scrollOffset());
}
+#endif
void ScrollView::scrollbarModes(ScrollbarMode& horizontalMode, ScrollbarMode& verticalMode) const
{
@@ -332,6 +334,15 @@ void ScrollView::updateScrollbars(const IntSize& desiredOffset)
if (m_inUpdateScrollbars || prohibitsScrolling() || platformWidget())
return;
+ // If we came in here with the view already needing a layout, then go ahead and do that
+ // first. (This will be the common case, e.g., when the page changes due to window resizing for example).
+ // This layout will not re-enter updateScrollbars and does not count towards our max layout pass total.
+ if (!m_scrollbarsSuppressed) {
+ m_inUpdateScrollbars = true;
+ visibleContentsResized();
+ m_inUpdateScrollbars = false;
+ }
+
bool hasHorizontalScrollbar = m_horizontalScrollbar;
bool hasVerticalScrollbar = m_verticalScrollbar;
@@ -352,13 +363,6 @@ void ScrollView::updateScrollbars(const IntSize& desiredOffset)
if (hasVerticalScrollbar != newHasVerticalScrollbar)
setHasVerticalScrollbar(newHasVerticalScrollbar);
} else {
- // If we came in here with the view already needing a layout, then go ahead and do that
- // first. (This will be the common case, e.g., when the page changes due to window resizing for example).
- // This layout will not re-enter updateScrollers and does not count towards our max layout pass total.
- m_inUpdateScrollbars = true;
- visibleContentsResized();
- m_inUpdateScrollbars = false;
-
bool sendContentResizedNotification = false;
IntSize docSize = contentsSize();
@@ -465,8 +469,10 @@ void ScrollView::updateScrollbars(const IntSize& desiredOffset)
m_verticalScrollbar->setSuppressInvalidation(false);
}
- if (hasHorizontalScrollbar != (m_horizontalScrollbar != 0) || hasVerticalScrollbar != (m_verticalScrollbar != 0))
+ if (hasHorizontalScrollbar != (m_horizontalScrollbar != 0) || hasVerticalScrollbar != (m_verticalScrollbar != 0)) {
frameRectsChanged();
+ updateScrollCorner();
+ }
// See if our offset has changed in a situation where we might not have scrollbars.
// This can happen when editing a body with overflow:hidden and scrolling to reveal selection.
@@ -481,7 +487,7 @@ void ScrollView::updateScrollbars(const IntSize& desiredOffset)
m_inUpdateScrollbars = false;
}
-const int panIconSizeLength = 20;
+const int panIconSizeLength = 16;
void ScrollView::scrollContents(const IntSize& scrollDelta)
{
@@ -626,23 +632,7 @@ void ScrollView::setScrollbarsSuppressed(bool suppressed, bool repaintOnUnsuppre
m_verticalScrollbar->invalidate();
// Invalidate the scroll corner too on unsuppress.
- IntRect hCorner;
- if (m_horizontalScrollbar && width() - m_horizontalScrollbar->width() > 0) {
- hCorner = IntRect(m_horizontalScrollbar->width(),
- height() - m_horizontalScrollbar->height(),
- width() - m_horizontalScrollbar->width(),
- m_horizontalScrollbar->height());
- invalidateRect(hCorner);
- }
-
- if (m_verticalScrollbar && height() - m_verticalScrollbar->height() > 0) {
- IntRect vCorner(width() - m_verticalScrollbar->width(),
- m_verticalScrollbar->height(),
- m_verticalScrollbar->width(),
- height() - m_verticalScrollbar->height());
- if (vCorner != hCorner)
- invalidateRect(vCorner);
- }
+ invalidateRect(scrollCornerRect());
}
}
@@ -722,16 +712,48 @@ void ScrollView::frameRectsChanged()
void ScrollView::repaintContentRectangle(const IntRect& rect, bool now)
{
- if (rect.isEmpty())
+ IntRect visibleContent = visibleContentRect();
+ visibleContent.intersect(rect);
+ if (visibleContent.isEmpty())
return;
if (platformWidget()) {
- platformRepaintContentRectangle(rect, now);
+ platformRepaintContentRectangle(visibleContent, now);
return;
}
if (hostWindow())
- hostWindow()->repaint(contentsToWindow(rect), true, now);
+ hostWindow()->repaint(contentsToWindow(visibleContent), true, now);
+}
+
+IntRect ScrollView::scrollCornerRect() const
+{
+ IntRect cornerRect;
+
+ if (m_horizontalScrollbar && width() - m_horizontalScrollbar->width() > 0) {
+ cornerRect.unite(IntRect(m_horizontalScrollbar->width(),
+ height() - m_horizontalScrollbar->height(),
+ width() - m_horizontalScrollbar->width(),
+ m_horizontalScrollbar->height()));
+ }
+
+ if (m_verticalScrollbar && height() - m_verticalScrollbar->height() > 0) {
+ cornerRect.unite(IntRect(width() - m_verticalScrollbar->width(),
+ m_verticalScrollbar->height(),
+ m_verticalScrollbar->width(),
+ height() - m_verticalScrollbar->height()));
+ }
+
+ return cornerRect;
+}
+
+void ScrollView::updateScrollCorner()
+{
+}
+
+void ScrollView::paintScrollCorner(GraphicsContext* context, const IntRect& cornerRect)
+{
+ ScrollbarTheme::nativeTheme()->paintScrollCorner(this, context, cornerRect);
}
void ScrollView::paint(GraphicsContext* context, const IntRect& rect)
@@ -773,25 +795,7 @@ void ScrollView::paint(GraphicsContext* context, const IntRect& rect)
if (m_verticalScrollbar)
m_verticalScrollbar->paint(context, scrollViewDirtyRect);
- IntRect hCorner;
- if (m_horizontalScrollbar && width() - m_horizontalScrollbar->width() > 0) {
- hCorner = IntRect(m_horizontalScrollbar->width(),
- height() - m_horizontalScrollbar->height(),
- width() - m_horizontalScrollbar->width(),
- m_horizontalScrollbar->height());
- if (hCorner.intersects(scrollViewDirtyRect))
- ScrollbarTheme::nativeTheme()->paintScrollCorner(this, context, hCorner);
- }
-
- if (m_verticalScrollbar && height() - m_verticalScrollbar->height() > 0) {
- IntRect vCorner(width() - m_verticalScrollbar->width(),
- m_verticalScrollbar->height(),
- m_verticalScrollbar->width(),
- height() - m_verticalScrollbar->height());
- if (vCorner != hCorner && vCorner.intersects(scrollViewDirtyRect))
- ScrollbarTheme::nativeTheme()->paintScrollCorner(this, context, vCorner);
- }
-
+ paintScrollCorner(context, scrollCornerRect());
context->restore();
}
diff --git a/WebCore/platform/ScrollView.h b/WebCore/platform/ScrollView.h
index 88e2564..ef3d03d 100644
--- a/WebCore/platform/ScrollView.h
+++ b/WebCore/platform/ScrollView.h
@@ -89,7 +89,7 @@ public:
void scrollbarModes(ScrollbarMode& horizontalMode, ScrollbarMode& verticalMode) const;
ScrollbarMode horizontalScrollbarMode() const { ScrollbarMode horizontal, vertical; scrollbarModes(horizontal, vertical); return horizontal; }
ScrollbarMode verticalScrollbarMode() const { ScrollbarMode horizontal, vertical; scrollbarModes(horizontal, vertical); return vertical; }
- virtual void setCanHaveScrollbars(bool flag);
+ void setCanHaveScrollbars(bool flag);
bool canHaveScrollbars() const { return horizontalScrollbarMode() != ScrollbarAlwaysOff || verticalScrollbarMode() != ScrollbarAlwaysOff; }
// Overridden by FrameView to create custom CSS scrollbars if applicable.
@@ -239,6 +239,10 @@ protected:
void setHasHorizontalScrollbar(bool);
void setHasVerticalScrollbar(bool);
+ IntRect scrollCornerRect() const;
+ virtual void updateScrollCorner();
+ virtual void paintScrollCorner(GraphicsContext*, const IntRect& cornerRect);
+
private:
RefPtr<Scrollbar> m_horizontalScrollbar;
RefPtr<Scrollbar> m_verticalScrollbar;
diff --git a/WebCore/platform/Scrollbar.cpp b/WebCore/platform/Scrollbar.cpp
index 4574f63..4eb2c4a 100644
--- a/WebCore/platform/Scrollbar.cpp
+++ b/WebCore/platform/Scrollbar.cpp
@@ -392,9 +392,9 @@ void Scrollbar::setFrameRect(const IntRect& rect)
// Get our window resizer rect and see if we overlap. Adjust to avoid the overlap
// if necessary.
IntRect adjustedRect(rect);
- if (parent()) {
- bool overlapsResizer = false;
- ScrollView* view = parent();
+ bool overlapsResizer = false;
+ ScrollView* view = parent();
+ if (view && !rect.isEmpty() && !view->windowResizerRect().isEmpty()) {
IntRect resizerRect = view->convertFromContainingWindow(view->windowResizerRect());
if (rect.intersects(resizerRect)) {
if (orientation() == HorizontalScrollbar) {
@@ -411,11 +411,11 @@ void Scrollbar::setFrameRect(const IntRect& rect)
}
}
}
-
- if (overlapsResizer != m_overlapsResizer) {
- m_overlapsResizer = overlapsResizer;
+ }
+ if (overlapsResizer != m_overlapsResizer) {
+ m_overlapsResizer = overlapsResizer;
+ if (view)
view->adjustScrollbarsAvoidingResizerCount(m_overlapsResizer ? 1 : -1);
- }
}
Widget::setFrameRect(adjustedRect);
diff --git a/WebCore/platform/StaticConstructors.h b/WebCore/platform/StaticConstructors.h
index 26b44de..5bc792c 100644
--- a/WebCore/platform/StaticConstructors.h
+++ b/WebCore/platform/StaticConstructors.h
@@ -56,6 +56,9 @@
#if COMPILER(MSVC7)
#define DEFINE_GLOBAL(type, name) \
const type name;
+#elif COMPILER(WINSCW)
+#define DEFINE_GLOBAL(type, name, arg...) \
+ const type name;
#else
#define DEFINE_GLOBAL(type, name, ...) \
const type name;
@@ -67,6 +70,9 @@
#if COMPILER(MSVC7)
#define DEFINE_GLOBAL(type, name) \
void * name[(sizeof(type) + sizeof(void *) - 1) / sizeof(void *)];
+#elif COMPILER(WINSCW)
+#define DEFINE_GLOBAL(type, name, arg...) \
+ void * name[(sizeof(type) + sizeof(void *) - 1) / sizeof(void *)];
#else
#define DEFINE_GLOBAL(type, name, ...) \
void * name[(sizeof(type) + sizeof(void *) - 1) / sizeof(void *)];
diff --git a/WebCore/platform/ThemeTypes.h b/WebCore/platform/ThemeTypes.h
index b763675..e132313 100644
--- a/WebCore/platform/ThemeTypes.h
+++ b/WebCore/platform/ThemeTypes.h
@@ -46,12 +46,11 @@ typedef unsigned ControlStates;
// Must follow CSSValueKeywords.in order
enum ControlPart {
NoControlPart, CheckboxPart, RadioPart, PushButtonPart, SquareButtonPart, ButtonPart,
- ButtonBevelPart, DefaultButtonPart, ListboxPart, ListItemPart,
+ ButtonBevelPart, DefaultButtonPart, ListButtonPart, ListboxPart, ListItemPart,
MediaFullscreenButtonPart, MediaMuteButtonPart, MediaPlayButtonPart, MediaSeekBackButtonPart,
MediaSeekForwardButtonPart, MediaRewindButtonPart, MediaReturnToRealtimeButtonPart,
- MediaSliderPart,
- MediaSliderThumbPart, MediaControlsBackgroundPart,
- MediaCurrentTimePart, MediaTimeRemainingPart,
+ MediaSliderPart, MediaSliderThumbPart, MediaVolumeSliderContainerPart, MediaVolumeSliderPart, MediaVolumeSliderThumbPart,
+ MediaControlsBackgroundPart, MediaCurrentTimePart, MediaTimeRemainingPart,
MenulistPart, MenulistButtonPart, MenulistTextPart, MenulistTextFieldPart,
SliderHorizontalPart, SliderVerticalPart, SliderThumbHorizontalPart,
SliderThumbVerticalPart, CaretPart, SearchFieldPart, SearchFieldDecorationPart,
diff --git a/WebCore/platform/ThreadTimers.cpp b/WebCore/platform/ThreadTimers.cpp
index 71a06b0..3ae8207 100644
--- a/WebCore/platform/ThreadTimers.cpp
+++ b/WebCore/platform/ThreadTimers.cpp
@@ -34,6 +34,11 @@
namespace WebCore {
+// Fire timers for this length of time, and then quit to let the run loop process user input events.
+// 100ms is about a perceptable delay in UI, so use a half of that as a threshold.
+// This is to prevent UI freeze when there are too many timers or machine performance is low.
+static const double maxDurationOfFiringTimers = 0.050;
+
// Timers are created, started and fired on the same thread, and each thread has its own ThreadTimers
// copy to keep the heap and a set of currently firing timers.
@@ -79,43 +84,6 @@ void ThreadTimers::updateSharedTimer()
m_sharedTimer->setFireTime(m_timerHeap.first()->m_nextFireTime);
}
-
-void ThreadTimers::collectFiringTimers(double fireTime, Vector<TimerBase*>& firingTimers)
-{
- while (!m_timerHeap.isEmpty() && m_timerHeap.first()->m_nextFireTime <= fireTime) {
- TimerBase* timer = m_timerHeap.first();
- firingTimers.append(timer);
- m_timersReadyToFire.add(timer);
- timer->m_nextFireTime = 0;
- timer->heapDeleteMin();
- }
-}
-
-void ThreadTimers::fireTimers(double fireTime, const Vector<TimerBase*>& firingTimers)
-{
- size_t size = firingTimers.size();
- for (size_t i = 0; i != size; ++i) {
- TimerBase* timer = firingTimers[i];
-
- // If not in the set, this timer has been deleted or re-scheduled in another timer's fired function.
- // So either we don't want to fire it at all or we will fire it next time the shared timer goes off.
- // It might even have been deleted; that's OK because we won't do anything else with the pointer.
- if (!m_timersReadyToFire.contains(timer))
- continue;
-
- // Setting the next fire time has a side effect of removing the timer from the firing timers set.
- double interval = timer->repeatInterval();
- timer->setNextFireTime(interval ? fireTime + interval : 0);
-
- // Once the timer has been fired, it may be deleted, so do nothing else with it after this point.
- timer->fired();
-
- // Catch the case where the timer asked timers to fire in a nested event loop.
- if (!m_firingTimers)
- break;
- }
-}
-
void ThreadTimers::sharedTimerFired()
{
// Redirect to non-static method.
@@ -130,17 +98,24 @@ void ThreadTimers::sharedTimerFiredInternal()
m_firingTimers = true;
double fireTime = currentTime();
- Vector<TimerBase*> firingTimers;
+ double timeToQuit = fireTime + maxDurationOfFiringTimers;
- // m_timersReadyToFire will initially contain the same set as firingTimers, but
- // as timers fire some mat become re-scheduled or deleted. They get removed from
- // m_timersReadyToFire so we can avoid firing them.
- ASSERT(m_timersReadyToFire.isEmpty());
+ while (!m_timerHeap.isEmpty() && m_timerHeap.first()->m_nextFireTime <= fireTime) {
+ TimerBase* timer = m_timerHeap.first();
+ timer->m_nextFireTime = 0;
+ timer->heapDeleteMin();
- collectFiringTimers(fireTime, firingTimers);
- fireTimers(fireTime, firingTimers);
+ double interval = timer->repeatInterval();
+ timer->setNextFireTime(interval ? fireTime + interval : 0);
+
+ // Once the timer has been fired, it may be deleted, so do nothing else with it after this point.
+ timer->fired();
+
+ // Catch the case where the timer asked timers to fire in a nested event loop, or we are over time limit.
+ if (!m_firingTimers || timeToQuit < currentTime())
+ break;
+ }
- m_timersReadyToFire.clear();
m_firingTimers = false;
updateSharedTimer();
@@ -150,7 +125,6 @@ void ThreadTimers::fireTimersInNestedEventLoop()
{
// Reset the reentrancy guard so the timers can fire again.
m_firingTimers = false;
- m_timersReadyToFire.clear();
updateSharedTimer();
}
diff --git a/WebCore/platform/ThreadTimers.h b/WebCore/platform/ThreadTimers.h
index ea0a366..01b4c71 100644
--- a/WebCore/platform/ThreadTimers.h
+++ b/WebCore/platform/ThreadTimers.h
@@ -45,7 +45,6 @@ namespace WebCore {
void setSharedTimer(SharedTimer*);
Vector<TimerBase*>& timerHeap() { return m_timerHeap; }
- HashSet<const TimerBase*>& timersReadyToFire() { return m_timersReadyToFire; }
void updateSharedTimer();
void fireTimersInNestedEventLoop();
@@ -53,13 +52,10 @@ namespace WebCore {
private:
static void sharedTimerFired();
- void fireTimers(double fireTime, const Vector<TimerBase*>&);
- void collectFiringTimers(double fireTime, Vector<TimerBase*>&);
void sharedTimerFiredInternal();
void fireTimersInNestedEventLoopInternal();
Vector<TimerBase*> m_timerHeap;
- HashSet<const TimerBase*> m_timersReadyToFire; // Temporarily holds a pointer to a stack object. No ownership.
SharedTimer* m_sharedTimer; // External object, can be a run loop on a worker thread. Normally set/reset by worker thread.
bool m_firingTimers; // Reentrancy guard.
};
diff --git a/WebCore/platform/Timer.cpp b/WebCore/platform/Timer.cpp
index bd29fd8..539846c 100644
--- a/WebCore/platform/Timer.cpp
+++ b/WebCore/platform/Timer.cpp
@@ -53,11 +53,6 @@ static Vector<TimerBase*>& timerHeap()
return threadGlobalData().threadTimers().timerHeap();
}
-static HashSet<const TimerBase*>& timersReadyToFire()
-{
- return threadGlobalData().threadTimers().timersReadyToFire();
-}
-
// Class to represent elements in the heap when calling the standard library heap algorithms.
// Maintains the m_heapIndex value in the timers themselves, which allows us to do efficient
// modification of the heap.
@@ -205,7 +200,7 @@ bool TimerBase::isActive() const
{
ASSERT(m_thread == currentThread());
- return m_nextFireTime || timersReadyToFire().contains(this);
+ return m_nextFireTime;
}
double TimerBase::nextFireInterval() const
@@ -296,9 +291,6 @@ void TimerBase::setNextFireTime(double newTime)
ASSERT(m_thread == currentThread());
// Keep heap valid while changing the next-fire time.
-
- timersReadyToFire().remove(this);
-
double oldTime = m_nextFireTime;
if (oldTime != newTime) {
m_nextFireTime = newTime;
diff --git a/WebCore/platform/TreeShared.h b/WebCore/platform/TreeShared.h
index 1ac1b33..02728ff 100644
--- a/WebCore/platform/TreeShared.h
+++ b/WebCore/platform/TreeShared.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -28,17 +28,8 @@ namespace WebCore {
template<class T> class TreeShared : public Noncopyable {
public:
- TreeShared()
- : m_refCount(0)
- , m_parent(0)
- {
-#ifndef NDEBUG
- m_deletionHasBegun = false;
- m_inRemovedLastRefFunction = false;
-#endif
- }
- TreeShared(T* parent)
- : m_refCount(0)
+ TreeShared(int initialRefCount = 1)
+ : m_refCount(initialRefCount)
, m_parent(0)
{
#ifndef NDEBUG
diff --git a/WebCore/platform/Widget.h b/WebCore/platform/Widget.h
index 4534d58..cbbc427 100644
--- a/WebCore/platform/Widget.h
+++ b/WebCore/platform/Widget.h
@@ -70,10 +70,22 @@ class wxWindow;
typedef wxWindow* PlatformWidget;
#endif
+#if PLATFORM(HAIKU)
+class BView;
+typedef BView* PlatformWidget;
+#endif
+
#if PLATFORM(CHROMIUM)
#include "PlatformWidget.h"
#endif
+#if PLATFORM(QT)
+class QWebPageClient;
+typedef QWebPageClient* PlatformPageClient;
+#else
+typedef PlatformWidget PlatformPageClient;
+#endif
+
#include "IntPoint.h"
#include "IntRect.h"
#include "IntSize.h"
diff --git a/WebCore/platform/android/TemporaryLinkStubs.cpp b/WebCore/platform/android/TemporaryLinkStubs.cpp
index 482565b..215c7f5 100644
--- a/WebCore/platform/android/TemporaryLinkStubs.cpp
+++ b/WebCore/platform/android/TemporaryLinkStubs.cpp
@@ -174,6 +174,11 @@ void Pasteboard::writeSelection(Range*, bool, Frame*)
notImplemented();
}
+void Pasteboard::writePlainText(const String&)
+{
+ notImplemented();
+}
+
void Pasteboard::writeURL(const KURL&, const String&, Frame*)
{
notImplemented();
diff --git a/WebCore/platform/chromium/ChromiumBridge.h b/WebCore/platform/chromium/ChromiumBridge.h
index bca8c52..1afcc23 100644
--- a/WebCore/platform/chromium/ChromiumBridge.h
+++ b/WebCore/platform/chromium/ChromiumBridge.h
@@ -67,12 +67,16 @@ namespace WebCore {
class ChromiumBridge {
public:
// Clipboard ----------------------------------------------------------
- static bool clipboardIsFormatAvailable(PasteboardPrivate::ClipboardFormat);
+ static bool clipboardIsFormatAvailable(PasteboardPrivate::ClipboardFormat, PasteboardPrivate::ClipboardBuffer);
- static String clipboardReadPlainText();
- static void clipboardReadHTML(String*, KURL*);
+ static String clipboardReadPlainText(PasteboardPrivate::ClipboardBuffer);
+ static void clipboardReadHTML(PasteboardPrivate::ClipboardBuffer, String*, KURL*);
+ // Only the clipboardRead functions take a buffer argument because
+ // Chromium currently uses a different technique to write to alternate
+ // clipboard buffers.
static void clipboardWriteSelection(const String&, const KURL&, const String&, bool);
+ static void clipboardWritePlainText(const String&);
static void clipboardWriteURL(const KURL&, const String&);
static void clipboardWriteImage(const NativeImageSkia*, const KURL&, const String&);
@@ -92,6 +96,9 @@ namespace WebCore {
static String directoryName(const String& path);
static String pathByAppendingComponent(const String& path, const String& component);
static bool makeAllDirectories(const String& path);
+ static String getAbsolutePath(const String&);
+ static bool isDirectory(const String&);
+ static KURL filePathToURL(const String&);
// Font ---------------------------------------------------------------
#if PLATFORM(WIN_OS)
@@ -103,12 +110,16 @@ namespace WebCore {
// Forms --------------------------------------------------------------
static void notifyFormStateChanged(const Document*);
-
+
// HTML5 DB -----------------------------------------------------------
#if ENABLE(DATABASE)
- static PlatformFileHandle databaseOpenFile(const String& fileName, int desiredFlags);
- static bool databaseDeleteFile(const String& fileName);
+ // Returns a handle to the DB file and ooptionally a handle to its containing directory
+ static PlatformFileHandle databaseOpenFile(const String& fileName, int desiredFlags, PlatformFileHandle* dirHandle = 0);
+ // Returns a SQLite code (SQLITE_OK = 0, on success)
+ static int databaseDeleteFile(const String& fileName, bool syncDir = false);
+ // Returns the attributes of the DB file
static long databaseGetFileAttributes(const String& fileName);
+ // Returns the size of the DB file
static long long databaseGetFileSize(const String& fileName);
#endif
diff --git a/WebCore/platform/chromium/ChromiumDataObject.h b/WebCore/platform/chromium/ChromiumDataObject.h
index 3e8675e..a227001 100644
--- a/WebCore/platform/chromium/ChromiumDataObject.h
+++ b/WebCore/platform/chromium/ChromiumDataObject.h
@@ -55,7 +55,38 @@ namespace WebCore {
void clear();
bool hasData() const;
+
+ KURL mainURL() const { return url; }
+ void setMainURL(const KURL& newURL) { url = newURL; }
+ String mainURLTitle() const { return urlTitle; }
+ void setMainURLTitle(const String& newURLTitle) { urlTitle = newURLTitle; }
+
+ String textPlain() const { return plainText; }
+ void setTextPlain(const String& newText) { plainText = newText; }
+
+ String textHTML() const { return textHtml; }
+ void setTextHTML(const String& newText) { textHtml = newText; }
+
+ KURL htmlBaseURL() const { return htmlBaseUrl; }
+ void setHTMLBaseURL(const KURL& newURL) { htmlBaseUrl = newURL; }
+
+ SharedBuffer* content() const { return fileContent.get(); }
+ PassRefPtr<SharedBuffer> releaseContent() { return fileContent.release(); }
+ void setContent(PassRefPtr<SharedBuffer> newContent) { fileContent = newContent; }
+
+ String contentFileExtension() const { return fileExtension; }
+ void setContentFileExtension(const String& newFileExtension) { fileExtension = newFileExtension; }
+
+ String contentFileName() const { return fileContentFilename; }
+ void setContentFileName(const String& newFilename) { fileContentFilename = newFilename; }
+
+ const Vector<String>& fileNames() const { return filenames; }
+ void setFileNames(const Vector<String>& newFilenames) { filenames = newFilenames; }
+ void takeFileNames(Vector<String>& newFilenames) { filenames.swap(newFilenames); }
+
+ // Interim state: All members will become private, do NOT access them directly!
+ // Rather use the above accessor methods (or devise new ones if necessary).
KURL url;
String urlTitle;
diff --git a/WebCore/platform/chromium/ClipboardChromium.cpp b/WebCore/platform/chromium/ClipboardChromium.cpp
index 4050294..d330d3b 100644
--- a/WebCore/platform/chromium/ClipboardChromium.cpp
+++ b/WebCore/platform/chromium/ClipboardChromium.cpp
@@ -40,6 +40,7 @@
#include "MIMETypeRegistry.h"
#include "markup.h"
#include "NamedNodeMap.h"
+#include "Pasteboard.h"
#include "PlatformString.h"
#include "Range.h"
#include "RenderImage.h"
@@ -92,6 +93,7 @@ void ClipboardChromium::clearData(const String& type)
m_dataObject->url = KURL();
m_dataObject->urlTitle = "";
}
+
if (dataType == ClipboardDataTypeText)
m_dataObject->plainText = "";
}
@@ -116,7 +118,11 @@ String ClipboardChromium::getData(const String& type, bool& success) const
if (!isForDragging()) {
// If this isn't for a drag, it's for a cut/paste event handler.
// In this case, we need to check the clipboard.
- text = ChromiumBridge::clipboardReadPlainText();
+ PasteboardPrivate::ClipboardBuffer buffer =
+ Pasteboard::generalPasteboard()->isSelectionMode() ?
+ PasteboardPrivate::SelectionBuffer :
+ PasteboardPrivate::StandardBuffer;
+ text = ChromiumBridge::clipboardReadPlainText(buffer);
success = !text.isEmpty();
} else if (!m_dataObject->plainText.isEmpty()) {
success = true;
@@ -142,7 +148,7 @@ bool ClipboardChromium::setData(const String& type, const String& data)
ClipboardDataType winType = clipboardTypeFromMIMEType(type);
if (winType == ClipboardDataTypeURL) {
- m_dataObject->url = KURL(data);
+ m_dataObject->url = KURL(ParsedURLString, data);
return m_dataObject->url.isValid();
}
@@ -150,6 +156,7 @@ bool ClipboardChromium::setData(const String& type, const String& data)
m_dataObject->plainText = data;
return true;
}
+
return false;
}
@@ -163,6 +170,9 @@ HashSet<String> ClipboardChromium::types() const
if (!m_dataObject)
return results;
+ if (!m_dataObject->filenames.isEmpty())
+ results.add("Files");
+
if (m_dataObject->url.isValid()) {
results.add("URL");
results.add("text/uri-list");
@@ -178,8 +188,17 @@ HashSet<String> ClipboardChromium::types() const
PassRefPtr<FileList> ClipboardChromium::files() const
{
- notImplemented();
- return 0;
+ if (policy() != ClipboardReadable)
+ return FileList::create();
+
+ if (!m_dataObject || m_dataObject->filenames.isEmpty())
+ return FileList::create();
+
+ RefPtr<FileList> fileList = FileList::create();
+ for (size_t i = 0; i < m_dataObject->filenames.size(); ++i)
+ fileList->append(File::create(m_dataObject->filenames.at(i)));
+
+ return fileList.release();
}
void ClipboardChromium::setDragImage(CachedImage* image, Node* node, const IntPoint& loc)
diff --git a/WebCore/platform/chromium/DragDataChromium.cpp b/WebCore/platform/chromium/DragDataChromium.cpp
index eaec025..133ba24 100644
--- a/WebCore/platform/chromium/DragDataChromium.cpp
+++ b/WebCore/platform/chromium/DragDataChromium.cpp
@@ -30,10 +30,12 @@
#include "config.h"
#include "DragData.h"
+#include "ChromiumBridge.h"
#include "ChromiumDataObject.h"
#include "Clipboard.h"
#include "ClipboardChromium.h"
#include "DocumentFragment.h"
+#include "FileSystem.h"
#include "KURL.h"
#include "markup.h"
#include "NotImplemented.h"
@@ -56,18 +58,25 @@ PassRefPtr<Clipboard> DragData::createClipboard(ClipboardAccessPolicy policy) co
bool DragData::containsURL() const
{
- return m_platformDragData->url.isValid();
+ return !asURL().isEmpty();
}
String DragData::asURL(String* title) const
{
- if (!m_platformDragData->url.isValid())
- return String();
+ String url;
+ if (m_platformDragData->url.isValid())
+ url = m_platformDragData->url.string();
+ else if (m_platformDragData->filenames.size() == 1) {
+ String fileName = m_platformDragData->filenames[0];
+ fileName = ChromiumBridge::getAbsolutePath(fileName);
+ if (fileExists(fileName) && !ChromiumBridge::isDirectory(fileName))
+ url = ChromiumBridge::filePathToURL(fileName).string();
+ }
// |title| can be NULL
if (title)
*title = m_platformDragData->urlTitle;
- return m_platformDragData->url.string();
+ return url;
}
bool DragData::containsFiles() const
@@ -112,7 +121,8 @@ bool DragData::containsCompatibleContent() const
return containsPlainText()
|| containsURL()
|| containsHTML(m_platformDragData)
- || containsColor();
+ || containsColor()
+ || containsFiles();
}
PassRefPtr<DocumentFragment> DragData::asFragment(Document* doc) const
diff --git a/WebCore/platform/chromium/FileChooserChromium.cpp b/WebCore/platform/chromium/FileChooserChromium.cpp
index 08d33a3..3d75b42 100644
--- a/WebCore/platform/chromium/FileChooserChromium.cpp
+++ b/WebCore/platform/chromium/FileChooserChromium.cpp
@@ -42,7 +42,7 @@ String FileChooser::basenameForWidth(const Font& font, int width) const
if (m_filenames.isEmpty())
string = fileButtonNoFileSelectedLabel();
else if (m_filenames.size() == 1)
- string = pathGetFileName(m_filenames[0]);
+ string = pathGetDisplayFileName(m_filenames[0]);
else
return StringTruncator::rightTruncate(multipleFileUploadText(m_filenames.size()), width, font, false);
diff --git a/WebCore/platform/chromium/FileSystemChromiumLinux.cpp b/WebCore/platform/chromium/FileSystemChromiumLinux.cpp
index e388dee..24f8da5 100644
--- a/WebCore/platform/chromium/FileSystemChromiumLinux.cpp
+++ b/WebCore/platform/chromium/FileSystemChromiumLinux.cpp
@@ -38,4 +38,9 @@ String pathGetFileName(const String& path)
return path.substring(path.reverseFind('/') + 1);
}
+String pathGetDisplayFileName(const String& path)
+{
+ return pathGetFileName(path);
+}
+
} // namespace WebCore
diff --git a/WebCore/platform/chromium/FileSystemChromiumMac.mm b/WebCore/platform/chromium/FileSystemChromiumMac.mm
index 7e880e1..29563de 100644
--- a/WebCore/platform/chromium/FileSystemChromiumMac.mm
+++ b/WebCore/platform/chromium/FileSystemChromiumMac.mm
@@ -38,6 +38,11 @@ namespace WebCore {
String pathGetFileName(const String& path)
{
+ return [path lastPathComponent];
+}
+
+String pathGetDisplayFileName(const String& path)
+{
return [[NSFileManager defaultManager] displayNameAtPath:path];
}
diff --git a/WebCore/platform/chromium/FileSystemChromiumWin.cpp b/WebCore/platform/chromium/FileSystemChromiumWin.cpp
index 704c39a..0e605dc 100644
--- a/WebCore/platform/chromium/FileSystemChromiumWin.cpp
+++ b/WebCore/platform/chromium/FileSystemChromiumWin.cpp
@@ -41,4 +41,9 @@ String pathGetFileName(const String& path)
return String(PathFindFileName(String(path).charactersWithNullTermination()));
}
+String pathGetDisplayFileName(const String& path)
+{
+ return pathGetFileName(path);
+}
+
} // namespace WebCore
diff --git a/WebCore/platform/chromium/KeyCodeConversionGtk.cpp b/WebCore/platform/chromium/KeyCodeConversionGtk.cpp
index 4fc7f32..5950de1 100644
--- a/WebCore/platform/chromium/KeyCodeConversionGtk.cpp
+++ b/WebCore/platform/chromium/KeyCodeConversionGtk.cpp
@@ -357,6 +357,31 @@ int windowsKeyCodeForKeyEvent(unsigned keycode)
// VKEY_NONAME (FC) Reserved for future use
// VKEY_PA1 (FD) PA1 key
// VKEY_OEM_CLEAR (FE) Clear key
+ case GDK_F1:
+ case GDK_F2:
+ case GDK_F3:
+ case GDK_F4:
+ case GDK_F5:
+ case GDK_F6:
+ case GDK_F7:
+ case GDK_F8:
+ case GDK_F9:
+ case GDK_F10:
+ case GDK_F11:
+ case GDK_F12:
+ case GDK_F13:
+ case GDK_F14:
+ case GDK_F15:
+ case GDK_F16:
+ case GDK_F17:
+ case GDK_F18:
+ case GDK_F19:
+ case GDK_F20:
+ case GDK_F21:
+ case GDK_F22:
+ case GDK_F23:
+ case GDK_F24:
+ return VKEY_F1 + (keycode - GDK_F1);
default:
return 0;
}
diff --git a/WebCore/platform/chromium/PasteboardChromium.cpp b/WebCore/platform/chromium/PasteboardChromium.cpp
index c5dee82..7702730 100644
--- a/WebCore/platform/chromium/PasteboardChromium.cpp
+++ b/WebCore/platform/chromium/PasteboardChromium.cpp
@@ -59,6 +59,7 @@ Pasteboard* Pasteboard::generalPasteboard()
}
Pasteboard::Pasteboard()
+ : m_selectionMode(false)
{
}
@@ -68,6 +69,16 @@ void Pasteboard::clear()
// previous contents.
}
+bool Pasteboard::isSelectionMode() const
+{
+ return m_selectionMode;
+}
+
+void Pasteboard::setSelectionMode(bool selectionMode)
+{
+ m_selectionMode = selectionMode;
+}
+
void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete, Frame* frame)
{
String html = createMarkup(selectedRange, 0, AnnotateForInterchange);
@@ -85,6 +96,17 @@ void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete,
ChromiumBridge::clipboardWriteSelection(html, url, plainText, canSmartCopyOrDelete);
}
+void Pasteboard::writePlainText(const String& text)
+{
+#if PLATFORM(WIN_OS)
+ String plainText(text);
+ replaceNewlinesWithWindowsStyleNewlines(plainText);
+ ChromiumBridge::clipboardWritePlainText(plainText);
+#else
+ ChromiumBridge::clipboardWritePlainText(text);
+#endif
+}
+
void Pasteboard::writeURL(const KURL& url, const String& titleStr, Frame* frame)
{
ASSERT(!url.isEmpty());
@@ -134,23 +156,23 @@ void Pasteboard::writeImage(Node* node, const KURL&, const String& title)
bool Pasteboard::canSmartReplace()
{
- return ChromiumBridge::clipboardIsFormatAvailable(
- PasteboardPrivate::WebSmartPasteFormat);
+ return ChromiumBridge::clipboardIsFormatAvailable(PasteboardPrivate::WebSmartPasteFormat, m_selectionMode ? PasteboardPrivate::SelectionBuffer : PasteboardPrivate::StandardBuffer);
}
String Pasteboard::plainText(Frame* frame)
{
- return ChromiumBridge::clipboardReadPlainText();
+ return ChromiumBridge::clipboardReadPlainText(m_selectionMode ? PasteboardPrivate::SelectionBuffer : PasteboardPrivate::StandardBuffer);
}
PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefPtr<Range> context, bool allowPlainText, bool& chosePlainText)
{
chosePlainText = false;
+ PasteboardPrivate::ClipboardBuffer buffer = m_selectionMode ? PasteboardPrivate::SelectionBuffer : PasteboardPrivate::StandardBuffer;
- if (ChromiumBridge::clipboardIsFormatAvailable(PasteboardPrivate::HTMLFormat)) {
+ if (ChromiumBridge::clipboardIsFormatAvailable(PasteboardPrivate::HTMLFormat, buffer)) {
String markup;
KURL srcURL;
- ChromiumBridge::clipboardReadHTML(&markup, &srcURL);
+ ChromiumBridge::clipboardReadHTML(buffer, &markup, &srcURL);
RefPtr<DocumentFragment> fragment =
createFragmentFromMarkup(frame->document(), markup, srcURL);
@@ -159,7 +181,7 @@ PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefP
}
if (allowPlainText) {
- String markup = ChromiumBridge::clipboardReadPlainText();
+ String markup = ChromiumBridge::clipboardReadPlainText(buffer);
if (!markup.isEmpty()) {
chosePlainText = true;
diff --git a/WebCore/platform/chromium/PasteboardPrivate.h b/WebCore/platform/chromium/PasteboardPrivate.h
index 26d45a0..95cc697 100644
--- a/WebCore/platform/chromium/PasteboardPrivate.h
+++ b/WebCore/platform/chromium/PasteboardPrivate.h
@@ -41,6 +41,10 @@ namespace WebCore {
BookmarkFormat,
WebSmartPasteFormat,
};
+ enum ClipboardBuffer {
+ StandardBuffer,
+ SelectionBuffer,
+ };
};
} // namespace WebCore
diff --git a/WebCore/platform/chromium/PopupMenuChromium.cpp b/WebCore/platform/chromium/PopupMenuChromium.cpp
index 51ed6ce..d6f895d 100644
--- a/WebCore/platform/chromium/PopupMenuChromium.cpp
+++ b/WebCore/platform/chromium/PopupMenuChromium.cpp
@@ -50,6 +50,7 @@
#include "PopupMenu.h"
#include "RenderTheme.h"
#include "ScrollbarTheme.h"
+#include "StringTruncator.h"
#include "SystemTime.h"
#include <wtf/CurrentTime.h>
@@ -72,10 +73,13 @@ static const TimeStamp kTypeAheadTimeoutMs = 1000;
// The settings used for the drop down menu.
// This is the delegate used if none is provided.
static const PopupContainerSettings dropDownSettings = {
- true, // focusOnShow
- true, // setTextOnIndexChange
- true, // acceptOnAbandon
- false // loopSelectionNavigation
+ true, // focusOnShow
+ true, // setTextOnIndexChange
+ true, // acceptOnAbandon
+ false, // loopSelectionNavigation
+ false, // restrictWidthOfListBox
+ // display item text in its first strong directional character's directionality.
+ PopupContainerSettings::FirstStrongDirectionalCharacterDirection,
};
// This class uses WebCore code to paint and handle events for a drop-down list
@@ -100,10 +104,7 @@ public:
// PopupListBox methods
- // Shows the popup
- void showPopup();
-
- // Hides the popup. Do not call this directly: use client->hidePopup().
+ // Hides the popup.
void hidePopup();
// Updates our internal list to match the client.
@@ -373,8 +374,7 @@ void PopupContainer::showExternal(const IntRect& rect, FrameView* v, int index)
void PopupContainer::hidePopup()
{
- if (client())
- client()->popupClosed(this);
+ listBox()->hidePopup();
}
void PopupContainer::layout()
@@ -601,6 +601,22 @@ bool PopupListBox::isInterestedInEventForKey(int keyCode)
}
}
+static bool isCharacterTypeEvent(const PlatformKeyboardEvent& event)
+{
+ // Check whether the event is a character-typed event or not.
+ // In Windows, PlatformKeyboardEvent::Char (not RawKeyDown) type event
+ // is considered as character type event. In Mac OS, KeyDown (not
+ // KeyUp) is considered as character type event.
+#if PLATFORM(WIN_OS)
+ if (event.type() == PlatformKeyboardEvent::Char)
+ return true;
+#else
+ if (event.type() == PlatformKeyboardEvent::KeyDown)
+ return true;
+#endif
+ return false;
+}
+
bool PopupListBox::handleKeyEvent(const PlatformKeyboardEvent& event)
{
if (event.type() == PlatformKeyboardEvent::KeyUp)
@@ -615,7 +631,7 @@ bool PopupListBox::handleKeyEvent(const PlatformKeyboardEvent& event)
return true;
case VKEY_RETURN:
if (m_selectedIndex == -1) {
- m_popupClient->hidePopup();
+ hidePopup();
// Don't eat the enter if nothing is selected.
return false;
}
@@ -641,7 +657,8 @@ bool PopupListBox::handleKeyEvent(const PlatformKeyboardEvent& event)
break;
default:
if (!event.ctrlKey() && !event.altKey() && !event.metaKey()
- && isPrintableChar(event.windowsVirtualKeyCode()))
+ && isPrintableChar(event.windowsVirtualKeyCode())
+ && isCharacterTypeEvent(event))
typeAheadFind(event);
break;
}
@@ -690,21 +707,6 @@ static String stripLeadingWhiteSpace(const String& string)
return string.substring(i, length - i);
}
-static bool isCharacterTypeEvent(const PlatformKeyboardEvent& event) {
- // Check whether the event is a character-typed event or not.
- // In Windows, PlatformKeyboardEvent::Char (not RawKeyDown) type event
- // is considered as character type event. In Mac OS, KeyDown (not
- // KeyUp) is considered as character type event.
-#if PLATFORM(WIN_OS)
- if (event.type() == PlatformKeyboardEvent::Char)
- return true;
-#else
- if (event.type() == PlatformKeyboardEvent::KeyDown)
- return true;
-#endif
- return false;
-}
-
// From HTMLSelectElement.cpp, with modifications
void PopupListBox::typeAheadFind(const PlatformKeyboardEvent& event)
{
@@ -714,8 +716,7 @@ void PopupListBox::typeAheadFind(const PlatformKeyboardEvent& event)
// Reset the time when user types in a character. The time gap between
// last character and the current character is used to indicate whether
// user typed in a string or just a character as the search prefix.
- if (isCharacterTypeEvent(event))
- m_lastCharTime = now;
+ m_lastCharTime = now;
UChar c = event.windowsVirtualKeyCode();
@@ -817,25 +818,44 @@ void PopupListBox::paintRow(GraphicsContext* gc, const IntRect& rect, int rowInd
return;
}
+ if (!style.isVisible())
+ return;
+
gc->setFillColor(textColor);
- // Bunch of shit to deal with RTL text...
+ Font itemFont = getRowFont(rowIndex);
+ // FIXME: http://crbug.com/19872 We should get the padding of individual option
+ // elements. This probably implies changes to PopupMenuClient.
+ bool rightAligned = m_popupClient->menuStyle().textDirection() == RTL;
+ int textX = 0;
+ int maxWidth = 0;
+ if (rightAligned)
+ maxWidth = rowRect.width() - max(0, m_popupClient->clientPaddingRight() - m_popupClient->clientInsetRight());
+ else {
+ textX = max(0, m_popupClient->clientPaddingLeft() - m_popupClient->clientInsetLeft());
+ maxWidth = rowRect.width() - textX;
+ }
+ // Prepare text to be drawn.
String itemText = m_popupClient->itemText(rowIndex);
+ if (m_settings.restrictWidthOfListBox) // truncate string to fit in.
+ itemText = StringTruncator::rightTruncate(itemText, maxWidth, itemFont);
unsigned length = itemText.length();
const UChar* str = itemText.characters();
-
- TextRun textRun(str, length, false, 0, 0, itemText.defaultWritingDirection() == WTF::Unicode::RightToLeft);
-
- // FIXME: http://b/1210481 We should get the padding of individual option
- // elements. This probably implies changes to PopupMenuClient.
-
- // Draw the item text
- if (style.isVisible()) {
- Font itemFont = getRowFont(rowIndex);
- int textX = max(0, m_popupClient->clientPaddingLeft() - m_popupClient->clientInsetLeft());
- int textY = rowRect.y() + itemFont.ascent() + (rowRect.height() - itemFont.height()) / 2;
- gc->drawBidiText(itemFont, textRun, IntPoint(textX, textY));
- }
+ // Prepare the directionality to draw text.
+ bool rtl = false;
+ if (m_settings.itemTextDirectionalityHint == PopupContainerSettings::DOMElementDirection)
+ rtl = style.textDirection() == RTL;
+ else if (m_settings.itemTextDirectionalityHint ==
+ PopupContainerSettings::FirstStrongDirectionalCharacterDirection)
+ rtl = itemText.defaultWritingDirection() == WTF::Unicode::RightToLeft;
+ TextRun textRun(str, length, false, 0, 0, rtl);
+ // If the text is right-to-left, make it right-aligned by adjusting its
+ // beginning position.
+ if (rightAligned)
+ textX += maxWidth - itemFont.width(textRun);
+ // Draw the item text.
+ int textY = rowRect.y() + itemFont.ascent() + (rowRect.height() - itemFont.height()) / 2;
+ gc->drawBidiText(itemFont, textRun, IntPoint(textX, textY));
}
Font PopupListBox::getRowFont(int rowIndex)
@@ -859,7 +879,7 @@ void PopupListBox::abandon()
m_selectedIndex = m_originalIndex;
- m_popupClient->hidePopup();
+ hidePopup();
if (m_acceptedIndexOnAbandon >= 0) {
m_popupClient->valueChanged(m_acceptedIndexOnAbandon);
@@ -892,7 +912,7 @@ void PopupListBox::acceptIndex(int index)
if (index < 0) {
if (m_popupClient) {
// Enter pressed with no selection, just close the popup.
- m_popupClient->hidePopup();
+ hidePopup();
}
return;
}
@@ -901,7 +921,7 @@ void PopupListBox::acceptIndex(int index)
RefPtr<PopupListBox> keepAlive(this);
// Hide ourselves first since valueChanged may have numerous side-effects.
- m_popupClient->hidePopup();
+ hidePopup();
// Tell the <select> PopupMenuClient what index was selected.
m_popupClient->valueChanged(index);
@@ -1047,6 +1067,17 @@ void PopupListBox::adjustSelectedIndex(int delta)
scrollToRevealSelection();
}
+void PopupListBox::hidePopup()
+{
+ if (parent()) {
+ PopupContainer* container = static_cast<PopupContainer*>(parent());
+ if (container->client())
+ container->client()->popupClosed(container);
+ }
+
+ m_popupClient->popupDidHide();
+}
+
void PopupListBox::updateFromElement()
{
clear();
@@ -1090,10 +1121,11 @@ void PopupListBox::layout()
baseWidth = max(baseWidth, width);
}
// FIXME: http://b/1210481 We should get the padding of individual option elements.
- paddingWidth = max(paddingWidth,
+ paddingWidth = max(paddingWidth,
m_popupClient->clientPaddingLeft() + m_popupClient->clientPaddingRight());
}
+ // Calculate scroll bar width.
int windowHeight = 0;
#if PLATFORM(DARWIN)
@@ -1124,14 +1156,20 @@ void PopupListBox::layout()
if (m_visibleRows < numItems())
scrollbarWidth = ScrollbarTheme::nativeTheme()->scrollbarThickness();
- int windowWidth = baseWidth + scrollbarWidth + paddingWidth;
- int contentWidth = baseWidth;
-
- if (windowWidth < m_baseWidth) {
+ int windowWidth;
+ int contentWidth;
+ if (m_settings.restrictWidthOfListBox) {
windowWidth = m_baseWidth;
contentWidth = m_baseWidth - scrollbarWidth - paddingWidth;
} else {
- m_baseWidth = baseWidth;
+ windowWidth = baseWidth + scrollbarWidth + paddingWidth;
+ contentWidth = baseWidth;
+
+ if (windowWidth < m_baseWidth) {
+ windowWidth = m_baseWidth;
+ contentWidth = m_baseWidth - scrollbarWidth - paddingWidth;
+ } else
+ m_baseWidth = baseWidth;
}
resize(windowWidth, windowHeight);
diff --git a/WebCore/platform/chromium/PopupMenuChromium.h b/WebCore/platform/chromium/PopupMenuChromium.h
index f394bc2..ee094b3 100644
--- a/WebCore/platform/chromium/PopupMenuChromium.h
+++ b/WebCore/platform/chromium/PopupMenuChromium.h
@@ -52,7 +52,11 @@ namespace WebCore {
};
PopupItem(const String& label, Type type)
- : label(label), type(type), yOffset(0) { }
+ : label(label)
+ , type(type)
+ , yOffset(0)
+ {
+ }
String label;
Type type;
int yOffset; // y offset of this item, relative to the top of the popup.
@@ -83,10 +87,30 @@ namespace WebCore {
// regardless of this setting.
bool acceptOnAbandon;
- // Whether the we should move the selection to the first/last item when
+ // Whether we should move the selection to the first/last item when
// the user presses down/up arrow keys and the last/first item is
// selected.
bool loopSelectionNavigation;
+
+ // Whether we should restrict the width of the PopupListBox or not.
+ // Autocomplete popups are restricted, combo-boxes (select tags) aren't.
+ bool restrictWidthOfListBox;
+
+ // A hint on the display directionality of the item text in popup menu.
+ //
+ // We could either display the items in the drop-down using its DOM element's
+ // directionality, or we could display the items in the drop-down using heuristics:
+ // such as in its first strong directionality character's direction.
+ // Please refer to the discussion (especially comment #7 and #10) in
+ // https://bugs.webkit.org/show_bug.cgi?id=27889 for details.
+ enum DirectionalityHint {
+ // Use the DOM element's directionality to display the item text in popup menu.
+ DOMElementDirection,
+ // Use the item text's first strong-directional character's directionality
+ // to display the item text in popup menu.
+ FirstStrongDirectionalCharacterDirection,
+ };
+ DirectionalityHint itemTextDirectionalityHint;
};
class PopupContainer : public FramelessScrollView {
@@ -121,7 +145,7 @@ namespace WebCore {
// popups on other platforms.
void show(const IntRect&, FrameView*, int index);
- // Hide the popup. Do not call this directly: use client->hidePopup().
+ // Hide the popup.
void hidePopup();
// Compute size of widget and children.
diff --git a/WebCore/platform/chromium/ThemeChromiumMac.h b/WebCore/platform/chromium/ThemeChromiumMac.h
new file mode 100644
index 0000000..5580d1d
--- /dev/null
+++ b/WebCore/platform/chromium/ThemeChromiumMac.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2009 Google Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 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 ThemeChromiumMac_h
+#define ThemeChromiumMac_h
+
+#include "Theme.h"
+
+// This file (and its associated .mm file) is a clone of ThemeMac.h. See
+// the .mm file for details.
+
+namespace WebCore {
+
+class ThemeChromiumMac : public Theme {
+public:
+ ThemeChromiumMac() { }
+ virtual ~ThemeChromiumMac() { }
+
+ virtual int baselinePositionAdjustment(ControlPart) const;
+
+ virtual FontDescription controlFont(ControlPart, const Font&, float zoomFactor) const;
+
+ virtual LengthSize controlSize(ControlPart, const Font&, const LengthSize&, float zoomFactor) const;
+ virtual LengthSize minimumControlSize(ControlPart, const Font&, float zoomFactor) const;
+
+ virtual LengthBox controlPadding(ControlPart, const Font&, const LengthBox& zoomedBox, float zoomFactor) const;
+ virtual LengthBox controlBorder(ControlPart, const Font&, const LengthBox& zoomedBox, float zoomFactor) const;
+
+ virtual bool controlRequiresPreWhiteSpace(ControlPart part) const { return part == PushButtonPart; }
+
+ virtual void paint(ControlPart, ControlStates, GraphicsContext*, const IntRect&, float zoomFactor, ScrollView*) const;
+ virtual void inflateControlPaintRect(ControlPart, ControlStates, IntRect&, float zoomFactor) const;
+};
+
+} // namespace WebCore
+
+#endif // ThemeChromiumMac_h
diff --git a/WebCore/platform/chromium/ThemeChromiumMac.mm b/WebCore/platform/chromium/ThemeChromiumMac.mm
new file mode 100644
index 0000000..3c97428
--- /dev/null
+++ b/WebCore/platform/chromium/ThemeChromiumMac.mm
@@ -0,0 +1,569 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2009 Google Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 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.
+ */
+
+#import "config.h"
+#import "ThemeChromiumMac.h"
+
+#import "BlockExceptions.h"
+#import "GraphicsContext.h"
+#import "LocalCurrentGraphicsContext.h"
+#import "ScrollView.h"
+#import "WebCoreSystemInterface.h"
+#include <wtf/StdLibExtras.h>
+
+using namespace std;
+
+// This file (and its associated .h file) is a clone of ThemeMac.mm.
+// Because the original file is designed to run in-process inside a Cocoa view,
+// we must maintain a fork. Please maintain this file by performing parallel
+// changes to it.
+//
+// The only changes from ThemeMac should be:
+// - The classname change from ThemeMac to ThemeChromiumMac.
+// - The import of FlippedView() and its use as the parent view for cell
+// rendering.
+// - In updateStates() the code to update the cells' inactive state.
+// - In paintButton() the code to save/restore the window's default button cell.
+//
+// For all other differences, if it was introduced in this file, then the
+// maintainer forgot to include it in the list; otherwise it is an update that
+// should have been applied to this file but was not.
+
+// FIXME: Default buttons really should be more like push buttons and not like buttons.
+
+namespace WebCore {
+
+// Pick up utility function from RenderThemeChromiumMac.
+extern NSView* FlippedView();
+
+enum {
+ topMargin,
+ rightMargin,
+ bottomMargin,
+ leftMargin
+};
+
+Theme* platformTheme()
+{
+ DEFINE_STATIC_LOCAL(ThemeChromiumMac, themeMac, ());
+ return &themeMac;
+}
+
+// Helper functions used by a bunch of different control parts.
+
+static NSControlSize controlSizeForFont(const Font& font)
+{
+ int fontSize = font.pixelSize();
+ if (fontSize >= 16)
+ return NSRegularControlSize;
+ if (fontSize >= 11)
+ return NSSmallControlSize;
+ return NSMiniControlSize;
+}
+
+static LengthSize sizeFromFont(const Font& font, const LengthSize& zoomedSize, float zoomFactor, const IntSize* sizes)
+{
+ IntSize controlSize = sizes[controlSizeForFont(font)];
+ if (zoomFactor != 1.0f)
+ controlSize = IntSize(controlSize.width() * zoomFactor, controlSize.height() * zoomFactor);
+ LengthSize result = zoomedSize;
+ if (zoomedSize.width().isIntrinsicOrAuto() && controlSize.width() > 0)
+ result.setWidth(Length(controlSize.width(), Fixed));
+ if (zoomedSize.height().isIntrinsicOrAuto() && controlSize.height() > 0)
+ result.setHeight(Length(controlSize.height(), Fixed));
+ return result;
+}
+
+static void setControlSize(NSCell* cell, const IntSize* sizes, const IntSize& minZoomedSize, float zoomFactor)
+{
+ NSControlSize size;
+ if (minZoomedSize.width() >= static_cast<int>(sizes[NSRegularControlSize].width() * zoomFactor) &&
+ minZoomedSize.height() >= static_cast<int>(sizes[NSRegularControlSize].height() * zoomFactor))
+ size = NSRegularControlSize;
+ else if (minZoomedSize.width() >= static_cast<int>(sizes[NSSmallControlSize].width() * zoomFactor) &&
+ minZoomedSize.height() >= static_cast<int>(sizes[NSSmallControlSize].height() * zoomFactor))
+ size = NSSmallControlSize;
+ else
+ size = NSMiniControlSize;
+ if (size != [cell controlSize]) // Only update if we have to, since AppKit does work even if the size is the same.
+ [cell setControlSize:size];
+}
+
+static void updateStates(NSCell* cell, ControlStates states)
+{
+ // Hover state is not supported by Aqua.
+
+ // Pressed state
+ bool oldPressed = [cell isHighlighted];
+ bool pressed = states & PressedState;
+ if (pressed != oldPressed)
+ [cell setHighlighted:pressed];
+
+ // Enabled state
+ bool oldEnabled = [cell isEnabled];
+ bool enabled = states & EnabledState;
+ if (enabled != oldEnabled)
+ [cell setEnabled:enabled];
+
+ // Focused state
+ bool oldFocused = [cell showsFirstResponder];
+ bool focused = states & FocusState;
+ if (focused != oldFocused)
+ [cell setShowsFirstResponder:focused];
+
+ // Checked and Indeterminate
+ bool oldIndeterminate = [cell state] == NSMixedState;
+ bool indeterminate = (states & IndeterminateState);
+ bool checked = states & CheckedState;
+ bool oldChecked = [cell state] == NSOnState;
+ if (oldIndeterminate != indeterminate || checked != oldChecked)
+ [cell setState:indeterminate ? NSMixedState : (checked ? NSOnState : NSOffState)];
+
+ // Window Inactive state
+ NSControlTint oldTint = [cell controlTint];
+ bool windowInactive = (states & WindowInactiveState);
+ NSControlTint tint = windowInactive ? NSClearControlTint : [NSColor currentControlTint];
+ if (tint != oldTint)
+ [cell setControlTint:tint];
+}
+
+static IntRect inflateRect(const IntRect& zoomedRect, const IntSize& zoomedSize, const int* margins, float zoomFactor)
+{
+ // Only do the inflation if the available width/height are too small. Otherwise try to
+ // fit the glow/check space into the available box's width/height.
+ int widthDelta = zoomedRect.width() - (zoomedSize.width() + margins[leftMargin] * zoomFactor + margins[rightMargin] * zoomFactor);
+ int heightDelta = zoomedRect.height() - (zoomedSize.height() + margins[topMargin] * zoomFactor + margins[bottomMargin] * zoomFactor);
+ IntRect result(zoomedRect);
+ if (widthDelta < 0) {
+ result.setX(result.x() - margins[leftMargin] * zoomFactor);
+ result.setWidth(result.width() - widthDelta);
+ }
+ if (heightDelta < 0) {
+ result.setY(result.y() - margins[topMargin] * zoomFactor);
+ result.setHeight(result.height() - heightDelta);
+ }
+ return result;
+}
+
+// Checkboxes
+
+static const IntSize* checkboxSizes()
+{
+ static const IntSize sizes[3] = { IntSize(14, 14), IntSize(12, 12), IntSize(10, 10) };
+ return sizes;
+}
+
+static const int* checkboxMargins(NSControlSize controlSize)
+{
+ static const int margins[3][4] =
+ {
+ { 3, 4, 4, 2 },
+ { 4, 3, 3, 3 },
+ { 4, 3, 3, 3 },
+ };
+ return margins[controlSize];
+}
+
+static LengthSize checkboxSize(const Font& font, const LengthSize& zoomedSize, float zoomFactor)
+{
+ // If the width and height are both specified, then we have nothing to do.
+ if (!zoomedSize.width().isIntrinsicOrAuto() && !zoomedSize.height().isIntrinsicOrAuto())
+ return zoomedSize;
+
+ // Use the font size to determine the intrinsic width of the control.
+ return sizeFromFont(font, zoomedSize, zoomFactor, checkboxSizes());
+}
+
+static NSButtonCell* checkbox(ControlStates states, const IntRect& zoomedRect, float zoomFactor)
+{
+ static NSButtonCell* checkboxCell;
+ if (!checkboxCell) {
+ checkboxCell = [[NSButtonCell alloc] init];
+ [checkboxCell setButtonType:NSSwitchButton];
+ [checkboxCell setTitle:nil];
+ [checkboxCell setAllowsMixedState:YES];
+ [checkboxCell setFocusRingType:NSFocusRingTypeExterior];
+ }
+
+ // Set the control size based off the rectangle we're painting into.
+ setControlSize(checkboxCell, checkboxSizes(), zoomedRect.size(), zoomFactor);
+
+ // Update the various states we respond to.
+ updateStates(checkboxCell, states);
+
+ return checkboxCell;
+}
+
+// FIXME: Share more code with radio buttons.
+static void paintCheckbox(ControlStates states, GraphicsContext* context, const IntRect& zoomedRect, float zoomFactor, ScrollView* scrollView)
+{
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+
+ // Determine the width and height needed for the control and prepare the cell for painting.
+ NSButtonCell* checkboxCell = checkbox(states, zoomedRect, zoomFactor);
+
+ context->save();
+
+ NSControlSize controlSize = [checkboxCell controlSize];
+ IntSize zoomedSize = checkboxSizes()[controlSize];
+ zoomedSize.setWidth(zoomedSize.width() * zoomFactor);
+ zoomedSize.setHeight(zoomedSize.height() * zoomFactor);
+ IntRect inflatedRect = inflateRect(zoomedRect, zoomedSize, checkboxMargins(controlSize), zoomFactor);
+
+ if (zoomFactor != 1.0f) {
+ inflatedRect.setWidth(inflatedRect.width() / zoomFactor);
+ inflatedRect.setHeight(inflatedRect.height() / zoomFactor);
+ context->translate(inflatedRect.x(), inflatedRect.y());
+ context->scale(FloatSize(zoomFactor, zoomFactor));
+ context->translate(-inflatedRect.x(), -inflatedRect.y());
+ }
+
+ [checkboxCell drawWithFrame:NSRect(inflatedRect) inView:FlippedView()];
+ [checkboxCell setControlView:nil];
+
+ context->restore();
+
+ END_BLOCK_OBJC_EXCEPTIONS
+}
+
+// Radio Buttons
+
+static const IntSize* radioSizes()
+{
+ static const IntSize sizes[3] = { IntSize(14, 15), IntSize(12, 13), IntSize(10, 10) };
+ return sizes;
+}
+
+static const int* radioMargins(NSControlSize controlSize)
+{
+ static const int margins[3][4] =
+ {
+ { 2, 2, 4, 2 },
+ { 3, 2, 3, 2 },
+ { 1, 0, 2, 0 },
+ };
+ return margins[controlSize];
+}
+
+static LengthSize radioSize(const Font& font, const LengthSize& zoomedSize, float zoomFactor)
+{
+ // If the width and height are both specified, then we have nothing to do.
+ if (!zoomedSize.width().isIntrinsicOrAuto() && !zoomedSize.height().isIntrinsicOrAuto())
+ return zoomedSize;
+
+ // Use the font size to determine the intrinsic width of the control.
+ return sizeFromFont(font, zoomedSize, zoomFactor, radioSizes());
+}
+
+static NSButtonCell* radio(ControlStates states, const IntRect& zoomedRect, float zoomFactor)
+{
+ static NSButtonCell* radioCell;
+ if (!radioCell) {
+ radioCell = [[NSButtonCell alloc] init];
+ [radioCell setButtonType:NSRadioButton];
+ [radioCell setTitle:nil];
+ [radioCell setFocusRingType:NSFocusRingTypeExterior];
+ }
+
+ // Set the control size based off the rectangle we're painting into.
+ setControlSize(radioCell, radioSizes(), zoomedRect.size(), zoomFactor);
+
+ // Update the various states we respond to.
+ updateStates(radioCell, states);
+
+ return radioCell;
+}
+
+static void paintRadio(ControlStates states, GraphicsContext* context, const IntRect& zoomedRect, float zoomFactor, ScrollView* scrollView)
+{
+ // Determine the width and height needed for the control and prepare the cell for painting.
+ NSButtonCell* radioCell = radio(states, zoomedRect, zoomFactor);
+
+ context->save();
+
+ NSControlSize controlSize = [radioCell controlSize];
+ IntSize zoomedSize = radioSizes()[controlSize];
+ zoomedSize.setWidth(zoomedSize.width() * zoomFactor);
+ zoomedSize.setHeight(zoomedSize.height() * zoomFactor);
+ IntRect inflatedRect = inflateRect(zoomedRect, zoomedSize, radioMargins(controlSize), zoomFactor);
+
+ if (zoomFactor != 1.0f) {
+ inflatedRect.setWidth(inflatedRect.width() / zoomFactor);
+ inflatedRect.setHeight(inflatedRect.height() / zoomFactor);
+ context->translate(inflatedRect.x(), inflatedRect.y());
+ context->scale(FloatSize(zoomFactor, zoomFactor));
+ context->translate(-inflatedRect.x(), -inflatedRect.y());
+ }
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+ [radioCell drawWithFrame:NSRect(inflatedRect) inView:FlippedView()];
+ [radioCell setControlView:nil];
+ END_BLOCK_OBJC_EXCEPTIONS
+
+ context->restore();
+}
+
+// Buttons
+
+// Buttons really only constrain height. They respect width.
+static const IntSize* buttonSizes()
+{
+ static const IntSize sizes[3] = { IntSize(0, 21), IntSize(0, 18), IntSize(0, 15) };
+ return sizes;
+}
+
+static const int* buttonMargins(NSControlSize controlSize)
+{
+ static const int margins[3][4] =
+ {
+ { 4, 6, 7, 6 },
+ { 4, 5, 6, 5 },
+ { 0, 1, 1, 1 },
+ };
+ return margins[controlSize];
+}
+
+static NSButtonCell* button(ControlPart part, ControlStates states, const IntRect& zoomedRect, float zoomFactor)
+{
+ static NSButtonCell *buttonCell;
+ static bool defaultButton;
+ if (!buttonCell) {
+ buttonCell = [[NSButtonCell alloc] init];
+ [buttonCell setTitle:nil];
+ [buttonCell setButtonType:NSMomentaryPushInButton];
+ }
+
+ // Set the control size based off the rectangle we're painting into.
+ if (part == SquareButtonPart || zoomedRect.height() > buttonSizes()[NSRegularControlSize].height() * zoomFactor) {
+ // Use the square button
+ if ([buttonCell bezelStyle] != NSShadowlessSquareBezelStyle)
+ [buttonCell setBezelStyle:NSShadowlessSquareBezelStyle];
+ } else if ([buttonCell bezelStyle] != NSRoundedBezelStyle)
+ [buttonCell setBezelStyle:NSRoundedBezelStyle];
+
+ setControlSize(buttonCell, buttonSizes(), zoomedRect.size(), zoomFactor);
+
+ if (defaultButton != (states & DefaultState)) {
+ defaultButton = !defaultButton;
+ [buttonCell setKeyEquivalent:(defaultButton ? @"\r" : @"")];
+ }
+
+ // Update the various states we respond to.
+ updateStates(buttonCell, states);
+
+ return buttonCell;
+}
+
+static void paintButton(ControlPart part, ControlStates states, GraphicsContext* context, const IntRect& zoomedRect, float zoomFactor, ScrollView* scrollView)
+{
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+
+ // Determine the width and height needed for the control and prepare the cell for painting.
+ NSButtonCell *buttonCell = button(part, states, zoomedRect, zoomFactor);
+ LocalCurrentGraphicsContext localContext(context);
+
+ NSControlSize controlSize = [buttonCell controlSize];
+ IntSize zoomedSize = buttonSizes()[controlSize];
+ zoomedSize.setWidth(zoomedRect.width()); // Buttons don't ever constrain width, so the zoomed width can just be honored.
+ zoomedSize.setHeight(zoomedSize.height() * zoomFactor);
+ IntRect inflatedRect = zoomedRect;
+ if ([buttonCell bezelStyle] == NSRoundedBezelStyle) {
+ // Center the button within the available space.
+ if (inflatedRect.height() > zoomedSize.height()) {
+ inflatedRect.setY(inflatedRect.y() + (inflatedRect.height() - zoomedSize.height()) / 2);
+ inflatedRect.setHeight(zoomedSize.height());
+ }
+
+ // Now inflate it to account for the shadow.
+ inflatedRect = inflateRect(inflatedRect, zoomedSize, buttonMargins(controlSize), zoomFactor);
+
+ if (zoomFactor != 1.0f) {
+ inflatedRect.setWidth(inflatedRect.width() / zoomFactor);
+ inflatedRect.setHeight(inflatedRect.height() / zoomFactor);
+ context->translate(inflatedRect.x(), inflatedRect.y());
+ context->scale(FloatSize(zoomFactor, zoomFactor));
+ context->translate(-inflatedRect.x(), -inflatedRect.y());
+ }
+ }
+
+ [buttonCell drawWithFrame:NSRect(inflatedRect) inView:FlippedView()];
+ [buttonCell setControlView:nil];
+
+ END_BLOCK_OBJC_EXCEPTIONS
+}
+
+// Theme overrides
+
+int ThemeChromiumMac::baselinePositionAdjustment(ControlPart part) const
+{
+ if (part == CheckboxPart || part == RadioPart)
+ return -2;
+ return Theme::baselinePositionAdjustment(part);
+}
+
+FontDescription ThemeChromiumMac::controlFont(ControlPart part, const Font& font, float zoomFactor) const
+{
+ switch (part) {
+ case PushButtonPart: {
+ FontDescription fontDescription;
+ fontDescription.setIsAbsoluteSize(true);
+ fontDescription.setGenericFamily(FontDescription::SerifFamily);
+
+ NSFont* nsFont = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:controlSizeForFont(font)]];
+ fontDescription.firstFamily().setFamily([nsFont familyName]);
+ fontDescription.setComputedSize([nsFont pointSize] * zoomFactor);
+ fontDescription.setSpecifiedSize([nsFont pointSize] * zoomFactor);
+ return fontDescription;
+ }
+ default:
+ return Theme::controlFont(part, font, zoomFactor);
+ }
+}
+
+LengthSize ThemeChromiumMac::controlSize(ControlPart part, const Font& font, const LengthSize& zoomedSize, float zoomFactor) const
+{
+ switch (part) {
+ case CheckboxPart:
+ return checkboxSize(font, zoomedSize, zoomFactor);
+ case RadioPart:
+ return radioSize(font, zoomedSize, zoomFactor);
+ case PushButtonPart:
+ // Height is reset to auto so that specified heights can be ignored.
+ return sizeFromFont(font, LengthSize(zoomedSize.width(), Length()), zoomFactor, buttonSizes());
+ default:
+ return zoomedSize;
+ }
+}
+
+LengthSize ThemeChromiumMac::minimumControlSize(ControlPart part, const Font& font, float zoomFactor) const
+{
+ switch (part) {
+ case SquareButtonPart:
+ case DefaultButtonPart:
+ case ButtonPart:
+ return LengthSize(Length(0, Fixed), Length(static_cast<int>(15 * zoomFactor), Fixed));
+ default:
+ return Theme::minimumControlSize(part, font, zoomFactor);
+ }
+}
+
+LengthBox ThemeChromiumMac::controlBorder(ControlPart part, const Font& font, const LengthBox& zoomedBox, float zoomFactor) const
+{
+ switch (part) {
+ case SquareButtonPart:
+ case DefaultButtonPart:
+ case ButtonPart:
+ return LengthBox(0, zoomedBox.right().value(), 0, zoomedBox.left().value());
+ default:
+ return Theme::controlBorder(part, font, zoomedBox, zoomFactor);
+ }
+}
+
+LengthBox ThemeChromiumMac::controlPadding(ControlPart part, const Font& font, const LengthBox& zoomedBox, float zoomFactor) const
+{
+ switch (part) {
+ case PushButtonPart: {
+ // Just use 8px. AppKit wants to use 11px for mini buttons, but that padding is just too large
+ // for real-world Web sites (creating a huge necessary minimum width for buttons whose space is
+ // by definition constrained, since we select mini only for small cramped environments.
+ // This also guarantees the HTML <button> will match our rendering by default, since we're using a consistent
+ // padding.
+ const int padding = 8 * zoomFactor;
+ return LengthBox(0, padding, 0, padding);
+ }
+ default:
+ return Theme::controlPadding(part, font, zoomedBox, zoomFactor);
+ }
+}
+
+void ThemeChromiumMac::inflateControlPaintRect(ControlPart part, ControlStates states, IntRect& zoomedRect, float zoomFactor) const
+{
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+ switch (part) {
+ case CheckboxPart: {
+ // We inflate the rect as needed to account for padding included in the cell to accommodate the checkbox
+ // shadow" and the check. We don't consider this part of the bounds of the control in WebKit.
+ NSCell *cell = checkbox(states, zoomedRect, zoomFactor);
+ NSControlSize controlSize = [cell controlSize];
+ IntSize zoomedSize = checkboxSizes()[controlSize];
+ zoomedSize.setHeight(zoomedSize.height() * zoomFactor);
+ zoomedSize.setWidth(zoomedSize.width() * zoomFactor);
+ zoomedRect = inflateRect(zoomedRect, zoomedSize, checkboxMargins(controlSize), zoomFactor);
+ break;
+ }
+ case RadioPart: {
+ // We inflate the rect as needed to account for padding included in the cell to accommodate the radio button
+ // shadow". We don't consider this part of the bounds of the control in WebKit.
+ NSCell *cell = radio(states, zoomedRect, zoomFactor);
+ NSControlSize controlSize = [cell controlSize];
+ IntSize zoomedSize = radioSizes()[controlSize];
+ zoomedSize.setHeight(zoomedSize.height() * zoomFactor);
+ zoomedSize.setWidth(zoomedSize.width() * zoomFactor);
+ zoomedRect = inflateRect(zoomedRect, zoomedSize, radioMargins(controlSize), zoomFactor);
+ break;
+ }
+ case PushButtonPart:
+ case DefaultButtonPart:
+ case ButtonPart: {
+ NSButtonCell *cell = button(part, states, zoomedRect, zoomFactor);
+ NSControlSize controlSize = [cell controlSize];
+
+ // We inflate the rect as needed to account for the Aqua button's shadow.
+ if ([cell bezelStyle] == NSRoundedBezelStyle) {
+ IntSize zoomedSize = buttonSizes()[controlSize];
+ zoomedSize.setHeight(zoomedSize.height() * zoomFactor);
+ zoomedSize.setWidth(zoomedRect.width()); // Buttons don't ever constrain width, so the zoomed width can just be honored.
+ zoomedRect = inflateRect(zoomedRect, zoomedSize, buttonMargins(controlSize), zoomFactor);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ END_BLOCK_OBJC_EXCEPTIONS
+}
+
+void ThemeChromiumMac::paint(ControlPart part, ControlStates states, GraphicsContext* context, const IntRect& zoomedRect, float zoomFactor, ScrollView* scrollView) const
+{
+ switch (part) {
+ case CheckboxPart:
+ paintCheckbox(states, context, zoomedRect, zoomFactor, scrollView);
+ break;
+ case RadioPart:
+ paintRadio(states, context, zoomedRect, zoomFactor, scrollView);
+ break;
+ case PushButtonPart:
+ case DefaultButtonPart:
+ case ButtonPart:
+ case SquareButtonPart:
+ paintButton(part, states, context, zoomedRect, zoomFactor, scrollView);
+ break;
+ default:
+ break;
+ }
+}
+
+}
diff --git a/WebCore/platform/graphics/BitmapImage.h b/WebCore/platform/graphics/BitmapImage.h
index 807c11b..13641d2 100644
--- a/WebCore/platform/graphics/BitmapImage.h
+++ b/WebCore/platform/graphics/BitmapImage.h
@@ -45,6 +45,10 @@ class NSImage;
typedef struct HBITMAP__ *HBITMAP;
#endif
+#if PLATFORM(HAIKU)
+class BBitmap;
+#endif
+
namespace WebCore {
struct FrameData;
}
@@ -137,6 +141,7 @@ public:
#endif
#if PLATFORM(WIN)
+ static PassRefPtr<BitmapImage> create(HBITMAP);
virtual bool getHBITMAP(HBITMAP);
virtual bool getHBITMAPOfSize(HBITMAP, LPSIZE);
#endif
@@ -165,10 +170,16 @@ protected:
virtual void drawFrameMatchingSourceSize(GraphicsContext*, const FloatRect& dstRect, const IntSize& srcSize, CompositeOperator);
#endif
virtual void draw(GraphicsContext*, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator);
-#if PLATFORM(WX) || PLATFORM(WINCE)
+
+#if PLATFORM(WX) || (PLATFORM(WINCE) && !PLATFORM(QT))
virtual void drawPattern(GraphicsContext*, const FloatRect& srcRect, const TransformationMatrix& patternTransform,
const FloatPoint& phase, CompositeOperator, const FloatRect& destRect);
-#endif
+#endif
+
+#if PLATFORM(HAIKU)
+ virtual BBitmap* getBBitmap() const;
+#endif
+
size_t currentFrame() const { return m_currentFrame; }
size_t frameCount();
NativeImagePtr frameAtIndex(size_t);
diff --git a/WebCore/platform/graphics/Color.h b/WebCore/platform/graphics/Color.h
index 5baa56e..8e51b95 100644
--- a/WebCore/platform/graphics/Color.h
+++ b/WebCore/platform/graphics/Color.h
@@ -47,6 +47,10 @@ typedef struct _GdkColor GdkColor;
class wxColour;
#endif
+#if PLATFORM(HAIKU)
+struct rgb_color;
+#endif
+
namespace WebCore {
class String;
@@ -121,6 +125,11 @@ public:
Color(CGColorRef);
#endif
+#if PLATFORM(HAIKU)
+ Color(const rgb_color&);
+ operator rgb_color() const;
+#endif
+
static bool parseHexColor(const String& name, RGBA32& rgb);
static const RGBA32 black = 0xFF000000;
diff --git a/WebCore/platform/graphics/FloatPoint.h b/WebCore/platform/graphics/FloatPoint.h
index 0c97c49..06b280b 100644
--- a/WebCore/platform/graphics/FloatPoint.h
+++ b/WebCore/platform/graphics/FloatPoint.h
@@ -36,7 +36,7 @@
typedef struct CGPoint CGPoint;
#endif
-#if PLATFORM(MAC)
+#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN))
#ifdef NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES
typedef struct CGPoint NSPoint;
#else
@@ -51,6 +51,10 @@ class QPointF;
QT_END_NAMESPACE
#endif
+#if PLATFORM(HAIKU)
+class BPoint;
+#endif
+
#if PLATFORM(SKIA)
struct SkPoint;
#endif
@@ -80,7 +84,8 @@ public:
operator CGPoint() const;
#endif
-#if PLATFORM(MAC) && !defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES)
+#if (PLATFORM(MAC) && !defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES)) \
+ || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN))
FloatPoint(const NSPoint&);
operator NSPoint() const;
#endif
@@ -90,7 +95,16 @@ public:
operator QPointF() const;
#endif
+<<<<<<< HEAD:WebCore/platform/graphics/FloatPoint.h
#if (PLATFORM(SKIA) || PLATFORM(SGL))
+=======
+#if PLATFORM(HAIKU)
+ FloatPoint(const BPoint&);
+ operator BPoint() const;
+#endif
+
+#if PLATFORM(SKIA)
+>>>>>>> webkit.org at 49305:WebCore/platform/graphics/FloatPoint.h
operator SkPoint() const;
FloatPoint(const SkPoint&);
#endif
diff --git a/WebCore/platform/graphics/FloatRect.h b/WebCore/platform/graphics/FloatRect.h
index e906812..704241a 100644
--- a/WebCore/platform/graphics/FloatRect.h
+++ b/WebCore/platform/graphics/FloatRect.h
@@ -33,7 +33,7 @@
typedef struct CGRect CGRect;
#endif
-#if PLATFORM(MAC)
+#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN))
#ifdef NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES
typedef struct CGRect NSRect;
#else
@@ -51,7 +51,15 @@ QT_END_NAMESPACE
class wxRect2DDouble;
#endif
+<<<<<<< HEAD:WebCore/platform/graphics/FloatRect.h
#if (PLATFORM(SKIA) || PLATFORM(SGL))
+=======
+#if PLATFORM(HAIKU)
+class BRect;
+#endif
+
+#if PLATFORM(SKIA)
+>>>>>>> webkit.org at 49305:WebCore/platform/graphics/FloatRect.h
struct SkRect;
#endif
@@ -123,7 +131,8 @@ public:
operator CGRect() const;
#endif
-#if PLATFORM(MAC) && !defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES)
+#if (PLATFORM(MAC) && !defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES)) \
+ || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN))
FloatRect(const NSRect&);
operator NSRect() const;
#endif
@@ -138,7 +147,16 @@ public:
operator wxRect2DDouble() const;
#endif
+<<<<<<< HEAD:WebCore/platform/graphics/FloatRect.h
#if (PLATFORM(SKIA) || PLATFORM(SGL))
+=======
+#if PLATFORM(HAIKU)
+ FloatRect(const BRect&);
+ operator BRect() const;
+#endif
+
+#if PLATFORM(SKIA)
+>>>>>>> webkit.org at 49305:WebCore/platform/graphics/FloatRect.h
FloatRect(const SkRect&);
operator SkRect() const;
#endif
diff --git a/WebCore/platform/graphics/FloatSize.h b/WebCore/platform/graphics/FloatSize.h
index 6e792b6..5a84fd1 100644
--- a/WebCore/platform/graphics/FloatSize.h
+++ b/WebCore/platform/graphics/FloatSize.h
@@ -34,7 +34,7 @@
typedef struct CGSize CGSize;
#endif
-#if PLATFORM(MAC)
+#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN))
#ifdef NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES
typedef struct CGSize NSSize;
#else
@@ -79,7 +79,8 @@ public:
operator CGSize() const;
#endif
-#if PLATFORM(MAC) && !defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES)
+#if (PLATFORM(MAC) && !defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES)) \
+ || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN))
explicit FloatSize(const NSSize &); // don't do this implicitly since it's lossy
operator NSSize() const;
#endif
diff --git a/WebCore/platform/graphics/FontCache.h b/WebCore/platform/graphics/FontCache.h
index 3c0f2d9..b88305f 100644
--- a/WebCore/platform/graphics/FontCache.h
+++ b/WebCore/platform/graphics/FontCache.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2006, 2008 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2007-2008 Torch Mobile, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -63,7 +64,15 @@ public:
// Also implemented by the platform.
void platformInit();
-#if PLATFORM(WIN)
+#if PLATFORM(WINCE) && !PLATFORM(QT)
+#if defined(IMLANG_FONT_LINK) && (IMLANG_FONT_LINK == 2)
+ IMLangFontLink2* getFontLinkInterface();
+#else
+ IMLangFontLink* getFontLinkInterface();
+#endif
+ static void comInitialize();
+ static void comUninitialize();
+#elif PLATFORM(WIN)
IMLangFontLink2* getFontLinkInterface();
#endif
diff --git a/WebCore/platform/graphics/FontDescription.h b/WebCore/platform/graphics/FontDescription.h
index c893b8a..fc63db9 100644
--- a/WebCore/platform/graphics/FontDescription.h
+++ b/WebCore/platform/graphics/FontDescription.h
@@ -27,7 +27,9 @@
#include "FontFamily.h"
#include "FontRenderingMode.h"
+#include "FontSmoothingMode.h"
#include "FontTraitsMask.h"
+#include "TextRenderingMode.h"
namespace WebCore {
@@ -61,6 +63,8 @@ public:
, m_usePrinterFont(false)
, m_renderingMode(NormalRenderingMode)
, m_keywordSize(0)
+ , m_fontSmoothing(AutoSmoothing)
+ , m_textRendering(AutoTextRendering)
{
}
@@ -80,8 +84,12 @@ public:
FontWeight bolderWeight() const;
GenericFamilyType genericFamily() const { return static_cast<GenericFamilyType>(m_genericFamily); }
bool usePrinterFont() const { return m_usePrinterFont; }
+ // only use fixed default size when there is only one font family, and that family is "monospace"
+ bool useFixedDefaultSize() const { return genericFamily() == MonospaceFamily && !family().next() && family().family() == "-webkit-monospace"; }
FontRenderingMode renderingMode() const { return static_cast<FontRenderingMode>(m_renderingMode); }
unsigned keywordSize() const { return m_keywordSize; }
+ FontSmoothingMode fontSmoothing() const { return static_cast<FontSmoothingMode>(m_fontSmoothing); }
+ TextRenderingMode textRenderingMode() const { return static_cast<TextRenderingMode>(m_textRendering); }
FontTraitsMask traitsMask() const;
@@ -96,6 +104,8 @@ public:
void setUsePrinterFont(bool p) { m_usePrinterFont = p; }
void setRenderingMode(FontRenderingMode mode) { m_renderingMode = mode; }
void setKeywordSize(unsigned s) { m_keywordSize = s; }
+ void setFontSmoothing(FontSmoothingMode smoothing) { m_fontSmoothing = smoothing; }
+ void setTextRenderingMode(TextRenderingMode rendering) { m_textRendering = rendering; }
private:
FontFamily m_familyList; // The list of font families to be used.
@@ -117,6 +127,9 @@ private:
unsigned m_keywordSize : 4; // We cache whether or not a font is currently represented by a CSS keyword (e.g., medium). If so,
// then we can accurately translate across different generic families to adjust for different preference settings
// (e.g., 13px monospace vs. 16px everything else). Sizes are 1-8 (like the HTML size values for <font>).
+
+ unsigned m_fontSmoothing : 2; // FontSmoothingMode
+ unsigned m_textRendering : 2; // TextRenderingMode
};
inline bool FontDescription::operator==(const FontDescription& other) const
@@ -131,7 +144,9 @@ inline bool FontDescription::operator==(const FontDescription& other) const
&& m_genericFamily == other.m_genericFamily
&& m_usePrinterFont == other.m_usePrinterFont
&& m_renderingMode == other.m_renderingMode
- && m_keywordSize == other.m_keywordSize;
+ && m_keywordSize == other.m_keywordSize
+ && m_fontSmoothing == other.m_fontSmoothing
+ && m_textRendering == other.m_textRendering;
}
}
diff --git a/WebCore/platform/graphics/FontFastPath.cpp b/WebCore/platform/graphics/FontFastPath.cpp
index b0e39db..5246593 100644
--- a/WebCore/platform/graphics/FontFastPath.cpp
+++ b/WebCore/platform/graphics/FontFastPath.cpp
@@ -251,6 +251,10 @@ bool Font::canUseGlyphCache(const TextRun& run) const
return false;
}
+ TextRenderingMode textMode = m_fontDescription.textRenderingMode();
+ if (textMode == OptimizeLegibility || textMode == GeometricPrecision)
+ return false;
+
return true;
}
diff --git a/WebCore/platform/graphics/FontSmoothingMode.h b/WebCore/platform/graphics/FontSmoothingMode.h
new file mode 100644
index 0000000..7c23394
--- /dev/null
+++ b/WebCore/platform/graphics/FontSmoothingMode.h
@@ -0,0 +1,35 @@
+/*
+ * 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 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 FontSmoothingMode_h
+#define FontSmoothingMode_h
+
+namespace WebCore {
+
+ enum FontSmoothingMode { AutoSmoothing, NoSmoothing, Antialiased, SubpixelAntialiased };
+
+} // namespace WebCore
+
+#endif // FontSmoothingMode_h
diff --git a/WebCore/platform/graphics/GlyphPageTreeNode.cpp b/WebCore/platform/graphics/GlyphPageTreeNode.cpp
index 6419e0c..9f53f0b 100644
--- a/WebCore/platform/graphics/GlyphPageTreeNode.cpp
+++ b/WebCore/platform/graphics/GlyphPageTreeNode.cpp
@@ -202,8 +202,10 @@ void GlyphPageTreeNode::initializePage(const FontData* fontData, unsigned pageNu
GlyphPage* pageToFill = m_page.get();
for (unsigned i = 0; i < numRanges; i++) {
const FontDataRange& range = segmentedFontData->rangeAt(i);
- int from = max(0, range.from() - static_cast<int>(start));
- int to = 1 + min(range.to() - static_cast<int>(start), static_cast<int>(GlyphPage::size) - 1);
+ // all this casting is to ensure all the parameters to min and max have the same type,
+ // to avoid ambiguous template parameter errors on Windows
+ int from = max(0, static_cast<int>(range.from()) - static_cast<int>(start));
+ int to = 1 + min(static_cast<int>(range.to()) - static_cast<int>(start), static_cast<int>(GlyphPage::size) - 1);
if (from < static_cast<int>(GlyphPage::size) && to > 0) {
if (haveGlyphs && !scratchPage) {
scratchPage = GlyphPage::create(this);
diff --git a/WebCore/platform/graphics/GraphicsContext.cpp b/WebCore/platform/graphics/GraphicsContext.cpp
index a4e8408..ccdce08 100644
--- a/WebCore/platform/graphics/GraphicsContext.cpp
+++ b/WebCore/platform/graphics/GraphicsContext.cpp
@@ -27,9 +27,9 @@
#include "GraphicsContext.h"
#include "BidiResolver.h"
+#include "Font.h"
#include "Generator.h"
#include "GraphicsContextPrivate.h"
-#include "Font.h"
using namespace std;
@@ -89,7 +89,7 @@ void GraphicsContext::save()
return;
m_common->stack.append(m_common->state);
-
+
savePlatformState();
}
@@ -104,7 +104,7 @@ void GraphicsContext::restore()
}
m_common->state = m_common->stack.last();
m_common->stack.removeLast();
-
+
restorePlatformState();
}
@@ -305,7 +305,7 @@ bool GraphicsContext::paintingDisabled() const
}
void GraphicsContext::drawImage(Image* image, const IntPoint& p, CompositeOperator op)
-{
+{
drawImage(image, p, IntRect(0, 0, -1, -1), op);
}
@@ -329,7 +329,7 @@ void GraphicsContext::drawText(const Font& font, const TextRun& run, const IntPo
{
if (paintingDisabled())
return;
-
+
font.drawText(this, run, point, from, to);
}
#endif
@@ -383,7 +383,7 @@ void GraphicsContext::initFocusRing(int width, int offset)
if (paintingDisabled())
return;
clearFocusRing();
-
+
m_common->m_focusRingWidth = width;
m_common->m_focusRingOffset = offset;
}
@@ -396,12 +396,12 @@ void GraphicsContext::clearFocusRing()
IntRect GraphicsContext::focusRingBoundingRect()
{
IntRect result = IntRect(0, 0, 0, 0);
-
+
const Vector<IntRect>& rects = focusRingRects();
unsigned rectCount = rects.size();
for (unsigned i = 0; i < rectCount; i++)
result.unite(rects[i]);
-
+
return result;
}
@@ -436,7 +436,7 @@ void GraphicsContext::drawImage(Image* image, const FloatRect& dest, const Float
float tsh = src.height();
float tw = dest.width();
float th = dest.height();
-
+
if (tsw == -1)
tsw = image->width();
if (tsh == -1)
@@ -540,10 +540,39 @@ void GraphicsContext::setPlatformTextDrawingMode(int mode)
}
#endif
-#if !PLATFORM(QT) && !PLATFORM(CAIRO) && !PLATFORM(SKIA)
+#if !PLATFORM(QT) && !PLATFORM(CAIRO) && !PLATFORM(SKIA) && !PLATFORM(HAIKU)
void GraphicsContext::setPlatformStrokeStyle(const StrokeStyle&)
{
}
#endif
+void GraphicsContext::adjustLineToPixelBoundaries(FloatPoint& p1, FloatPoint& p2, float strokeWidth, const StrokeStyle& penStyle)
+{
+ // For odd widths, we add in 0.5 to the appropriate x/y so that the float arithmetic
+ // works out. For example, with a border width of 3, WebKit will pass us (y1+y2)/2, e.g.,
+ // (50+53)/2 = 103/2 = 51 when we want 51.5. It is always true that an even width gave
+ // us a perfect position, but an odd width gave us a position that is off by exactly 0.5.
+ if (penStyle == DottedStroke || penStyle == DashedStroke) {
+ if (p1.x() == p2.x()) {
+ p1.setY(p1.y() + strokeWidth);
+ p2.setY(p2.y() - strokeWidth);
+ } else {
+ p1.setX(p1.x() + strokeWidth);
+ p2.setX(p2.x() - strokeWidth);
+ }
+ }
+
+ if (static_cast<int>(strokeWidth) % 2) { //odd
+ if (p1.x() == p2.x()) {
+ // We're a vertical line. Adjust our x.
+ p1.setX(p1.x() + 0.5f);
+ p2.setX(p2.x() + 0.5f);
+ } else {
+ // We're a horizontal line. Adjust our y.
+ p1.setY(p1.y() + 0.5f);
+ p2.setY(p2.y() + 0.5f);
+ }
+ }
+}
+
}
diff --git a/WebCore/platform/graphics/GraphicsContext.h b/WebCore/platform/graphics/GraphicsContext.h
index 233c14c..b1d1ef9 100644
--- a/WebCore/platform/graphics/GraphicsContext.h
+++ b/WebCore/platform/graphics/GraphicsContext.h
@@ -55,8 +55,8 @@ struct SkPoint;
class wxGCDC;
class wxWindowDC;
-// wxGraphicsContext allows us to support Path, etc.
-// but on some platforms, e.g. Linux, it requires fairly
+// wxGraphicsContext allows us to support Path, etc.
+// but on some platforms, e.g. Linux, it requires fairly
// new software.
#if USE(WXGC)
// On OS X, wxGCDC is just a typedef for wxDC, so use wxDC explicitly to make
@@ -72,6 +72,10 @@ class wxWindowDC;
#endif
#elif PLATFORM(SKIA)
typedef class PlatformContextSkia PlatformGraphicsContext;
+#elif PLATFORM(HAIKU)
+class BView;
+typedef BView PlatformGraphicsContext;
+struct pattern;
#elif PLATFORM(WINCE)
typedef struct HDC__ PlatformGraphicsContext;
#else
@@ -124,7 +128,7 @@ namespace WebCore {
const int cTextFill = 1;
const int cTextStroke = 2;
const int cTextClip = 4;
-
+
enum StrokeStyle {
NoStroke,
SolidStroke,
@@ -132,12 +136,12 @@ namespace WebCore {
DashedStroke
};
-// FIXME: This is a place-holder until we decide to add
-// real color space support to WebCore. At that time, ColorSpace will be a
-// class and instances will be held off of Colors. There will be
-// special singleton Gradient and Pattern color spaces to mark when
-// a fill or stroke is using a gradient or pattern instead of a solid color.
-// https://bugs.webkit.org/show_bug.cgi?id=20558
+ // FIXME: This is a place-holder until we decide to add
+ // real color space support to WebCore. At that time, ColorSpace will be a
+ // class and instances will be held off of Colors. There will be
+ // special singleton Gradient and Pattern color spaces to mark when
+ // a fill or stroke is using a gradient or pattern instead of a solid color.
+ // https://bugs.webkit.org/show_bug.cgi?id=20558
enum ColorSpace {
SolidColorSpace,
PatternColorSpace,
@@ -156,11 +160,11 @@ namespace WebCore {
public:
GraphicsContext(PlatformGraphicsContext*);
~GraphicsContext();
-
+
#if !PLATFORM(WINCE) || PLATFORM(QT)
PlatformGraphicsContext* platformContext() const;
#endif
-
+
float strokeThickness() const;
void setStrokeThickness(float);
StrokeStyle strokeStyle() const;
@@ -267,7 +271,7 @@ namespace WebCore {
CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false);
void drawTiledImage(Image*, const IntRect& destRect, const IntPoint& srcPoint, const IntSize& tileSize,
CompositeOperator = CompositeSourceOver);
- void drawTiledImage(Image*, const IntRect& destRect, const IntRect& srcRect,
+ void drawTiledImage(Image*, const IntRect& destRect, const IntRect& srcRect,
Image::TileRule hRule = Image::StretchTile, Image::TileRule vRule = Image::StretchTile,
CompositeOperator = CompositeSourceOver);
@@ -291,13 +295,13 @@ namespace WebCore {
void drawHighlightForText(const Font&, const TextRun&, const IntPoint&, int h, const Color& backgroundColor, int from = 0, int to = -1);
FloatRect roundToDevicePixels(const FloatRect&);
-
+
void drawLineForText(const IntPoint&, int width, bool printing);
void drawLineForMisspellingOrBadGrammar(const IntPoint&, int width, bool grammar);
-
+
bool paintingDisabled() const;
void setPaintingDisabled(bool);
-
+
bool updatingControlTints() const;
void setUpdatingControlTints(bool);
@@ -336,7 +340,7 @@ namespace WebCore {
void rotate(float angleInRadians);
void translate(float x, float y);
IntPoint origin();
-
+
void setURLForRect(const KURL&, const IntRect&);
void concatCTM(const TransformationMatrix&);
@@ -418,6 +422,10 @@ namespace WebCore {
GdkEventExpose* gdkExposeEvent() const;
#endif
+#if PLATFORM(HAIKU)
+ pattern getHaikuStrokeStyle();
+#endif
+
private:
void savePlatformState();
void restorePlatformState();
@@ -440,6 +448,8 @@ namespace WebCore {
void setPlatformShadow(const IntSize&, int blur, const Color&);
void clearPlatformShadow();
+ static void adjustLineToPixelBoundaries(FloatPoint& p1, FloatPoint& p2, float strokeWidth, const StrokeStyle&);
+
int focusRingWidth() const;
int focusRingOffset() const;
const Vector<IntRect>& focusRingRects() const;
diff --git a/WebCore/platform/graphics/GraphicsContext3D.h b/WebCore/platform/graphics/GraphicsContext3D.h
new file mode 100644
index 0000000..5223e05
--- /dev/null
+++ b/WebCore/platform/graphics/GraphicsContext3D.h
@@ -0,0 +1,335 @@
+/*
+ * 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 GraphicsContext3D_h
+#define GraphicsContext3D_h
+
+#include "PlatformString.h"
+
+#include <wtf/Noncopyable.h>
+
+#if PLATFORM(MAC)
+#include <OpenGL/OpenGL.h>
+
+typedef void* PlatformGraphicsContext3D;
+const PlatformGraphicsContext3D NullPlatformGraphicsContext3D = 0;
+typedef GLuint Platform3DObject;
+const Platform3DObject NullPlatform3DObject = 0;
+#else
+typedef void* PlatformGraphicsContext3D;
+const PlatformGraphicsContext3D NullPlatformGraphicsContext3D = 0;
+typedef int Platform3DObject;
+const Platform3DObject NullPlatform3DObject = 0;
+#endif
+
+namespace WebCore {
+ class CanvasArray;
+ class CanvasBuffer;
+ class CanvasUnsignedByteArray;
+ class CanvasFloatArray;
+ class CanvasFramebuffer;
+ class CanvasIntArray;
+ class CanvasProgram;
+ class CanvasRenderbuffer;
+ class CanvasRenderingContext3D;
+ class CanvasShader;
+ class CanvasTexture;
+ class HTMLCanvasElement;
+ class HTMLImageElement;
+ class HTMLVideoElement;
+ class ImageData;
+ class WebKitCSSMatrix;
+
+ // FIXME: ideally this would be used on all platforms.
+#if PLATFORM(CHROMIUM)
+ class GraphicsContext3DInternal;
+#endif
+
+ class GraphicsContext3D : Noncopyable {
+ public:
+ enum ShaderType { FRAGMENT_SHADER, VERTEX_SHADER };
+
+ GraphicsContext3D();
+ virtual ~GraphicsContext3D();
+
+#if PLATFORM(MAC)
+ PlatformGraphicsContext3D platformGraphicsContext3D() const { return m_contextObj; }
+ Platform3DObject platformTexture() const { return m_texture; }
+#elif PLATFORM(CHROMIUM)
+ PlatformGraphicsContext3D platformGraphicsContext3D() const;
+ Platform3DObject platformTexture() const;
+#else
+ PlatformGraphicsContext3D platformGraphicsContext3D() const { return NullPlatformGraphicsContext3D; }
+ Platform3DObject platformTexture() const { return NullPlatform3DObject; }
+#endif
+ void checkError() const;
+
+ void makeContextCurrent();
+
+ // Helper to return the size in bytes of OpenGL data types
+ // like GL_FLOAT, GL_INT, etc.
+ int sizeInBytes(int type);
+
+ void activeTexture(unsigned long texture);
+ void attachShader(CanvasProgram* program, CanvasShader* shader);
+ void bindAttribLocation(CanvasProgram*, unsigned long index, const String& name);
+ void bindBuffer(unsigned long target, CanvasBuffer*);
+ void bindFramebuffer(unsigned long target, CanvasFramebuffer*);
+ void bindRenderbuffer(unsigned long target, CanvasRenderbuffer*);
+ void bindTexture(unsigned long target, CanvasTexture* texture);
+ void blendColor(double red, double green, double blue, double alpha);
+ void blendEquation(unsigned long mode);
+ void blendEquationSeparate(unsigned long modeRGB, unsigned long modeAlpha);
+ void blendFunc(unsigned long sfactor, unsigned long dfactor);
+ void blendFuncSeparate(unsigned long srcRGB, unsigned long dstRGB, unsigned long srcAlpha, unsigned long dstAlpha);
+
+ void bufferData(unsigned long target, int size, unsigned long usage);
+ void bufferData(unsigned long target, CanvasArray* data, unsigned long usage);
+ void bufferSubData(unsigned long target, long offset, CanvasArray* data);
+
+ unsigned long checkFramebufferStatus(unsigned long target);
+ void clear(unsigned long mask);
+ void clearColor(double red, double green, double blue, double alpha);
+ void clearDepth(double depth);
+ void clearStencil(long s);
+ void colorMask(bool red, bool green, bool blue, bool alpha);
+ void compileShader(CanvasShader*);
+
+ //void compressedTexImage2D(unsigned long target, long level, unsigned long internalformat, unsigned long width, unsigned long height, long border, unsigned long imageSize, const void* data);
+ //void compressedTexSubImage2D(unsigned long target, long level, long xoffset, long yoffset, unsigned long width, unsigned long height, unsigned long format, unsigned long imageSize, const void* data);
+
+ void copyTexImage2D(unsigned long target, long level, unsigned long internalformat, long x, long y, unsigned long width, unsigned long height, long border);
+ void copyTexSubImage2D(unsigned long target, long level, long xoffset, long yoffset, long x, long y, unsigned long width, unsigned long height);
+ void cullFace(unsigned long mode);
+ void depthFunc(unsigned long func);
+ void depthMask(bool flag);
+ void depthRange(double zNear, double zFar);
+ void detachShader(CanvasProgram*, CanvasShader*);
+ void disable(unsigned long cap);
+ void disableVertexAttribArray(unsigned long index);
+ void drawArrays(unsigned long mode, long first, long count);
+ void drawElements(unsigned long mode, unsigned long count, unsigned long type, long offset);
+
+ void enable(unsigned long cap);
+ void enableVertexAttribArray(unsigned long index);
+ void finish();
+ void flush();
+ void framebufferRenderbuffer(unsigned long target, unsigned long attachment, unsigned long renderbuffertarget, CanvasRenderbuffer*);
+ void framebufferTexture2D(unsigned long target, unsigned long attachment, unsigned long textarget, CanvasTexture*, long level);
+ void frontFace(unsigned long mode);
+ void generateMipmap(unsigned long target);
+
+ int getAttribLocation(CanvasProgram*, const String& name);
+
+ bool getBoolean(unsigned long pname);
+ PassRefPtr<CanvasUnsignedByteArray> getBooleanv(unsigned long pname);
+ int getBufferParameteri(unsigned long target, unsigned long pname);
+ PassRefPtr<CanvasIntArray> getBufferParameteriv(unsigned long target, unsigned long pname);
+
+ unsigned long getError();
+
+ float getFloat(unsigned long pname);
+ PassRefPtr<CanvasFloatArray> getFloatv(unsigned long pname);
+ int getFramebufferAttachmentParameteri(unsigned long target, unsigned long attachment, unsigned long pname);
+ PassRefPtr<CanvasIntArray> getFramebufferAttachmentParameteriv(unsigned long target, unsigned long attachment, unsigned long pname);
+ int getInteger(unsigned long pname);
+ PassRefPtr<CanvasIntArray> getIntegerv(unsigned long pname);
+ int getProgrami(CanvasProgram*, unsigned long pname);
+ PassRefPtr<CanvasIntArray> getProgramiv(CanvasProgram*, unsigned long pname);
+ String getProgramInfoLog(CanvasProgram*);
+ int getRenderbufferParameteri(unsigned long target, unsigned long pname);
+ PassRefPtr<CanvasIntArray> getRenderbufferParameteriv(unsigned long target, unsigned long pname);
+ int getShaderi(CanvasShader*, unsigned long pname);
+ PassRefPtr<CanvasIntArray> getShaderiv(CanvasShader*, unsigned long pname);
+
+ String getShaderInfoLog(CanvasShader*);
+
+ // TBD
+ // void glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
+
+ String getShaderSource(CanvasShader*);
+ String getString(unsigned long name);
+
+ float getTexParameterf(unsigned long target, unsigned long pname);
+ PassRefPtr<CanvasFloatArray> getTexParameterfv(unsigned long target, unsigned long pname);
+ int getTexParameteri(unsigned long target, unsigned long pname);
+ PassRefPtr<CanvasIntArray> getTexParameteriv(unsigned long target, unsigned long pname);
+
+ float getUniformf(CanvasProgram* program, long location);
+ PassRefPtr<CanvasFloatArray> getUniformfv(CanvasProgram* program, long location);
+ int getUniformi(CanvasProgram* program, long location);
+ PassRefPtr<CanvasIntArray> getUniformiv(CanvasProgram* program, long location);
+
+ long getUniformLocation(CanvasProgram*, const String& name);
+
+ float getVertexAttribf(unsigned long index, unsigned long pname);
+ PassRefPtr<CanvasFloatArray> getVertexAttribfv(unsigned long index, unsigned long pname);
+ int getVertexAttribi(unsigned long index, unsigned long pname);
+ PassRefPtr<CanvasIntArray> getVertexAttribiv(unsigned long index, unsigned long pname);
+
+ long getVertexAttribOffset(unsigned long index, unsigned long pname);
+
+ void hint(unsigned long target, unsigned long mode);
+ bool isBuffer(CanvasBuffer*);
+ bool isEnabled(unsigned long cap);
+ bool isFramebuffer(CanvasFramebuffer*);
+ bool isProgram(CanvasProgram*);
+ bool isRenderbuffer(CanvasRenderbuffer*);
+ bool isShader(CanvasShader*);
+ bool isTexture(CanvasTexture*);
+ void lineWidth(double);
+ void linkProgram(CanvasProgram*);
+ void pixelStorei(unsigned long pname, long param);
+ void polygonOffset(double factor, double units);
+
+ // TBD
+ //void readPixels(long x, long y, unsigned long width, unsigned long height, unsigned long format, unsigned long type, void* pixels);
+
+ void releaseShaderCompiler();
+ void renderbufferStorage(unsigned long target, unsigned long internalformat, unsigned long width, unsigned long height);
+ void sampleCoverage(double value, bool invert);
+ void scissor(long x, long y, unsigned long width, unsigned long height);
+ void shaderSource(CanvasShader*, const String& string);
+ void stencilFunc(unsigned long func, long ref, unsigned long mask);
+ void stencilFuncSeparate(unsigned long face, unsigned long func, long ref, unsigned long mask);
+ void stencilMask(unsigned long mask);
+ void stencilMaskSeparate(unsigned long face, unsigned long mask);
+ void stencilOp(unsigned long fail, unsigned long zfail, unsigned long zpass);
+ void stencilOpSeparate(unsigned long face, unsigned long fail, unsigned long zfail, unsigned long zpass);
+
+ // These next several functions return an error code (0 if no errors) rather than using an ExceptionCode.
+ // Currently they return -1 on any error.
+ int texImage2D(unsigned target, unsigned level, unsigned internalformat,
+ unsigned width, unsigned height, unsigned border,
+ unsigned format, unsigned type, CanvasArray* pixels);
+ int texImage2D(unsigned target, unsigned level, unsigned internalformat,
+ unsigned width, unsigned height, unsigned border,
+ unsigned format, unsigned type, ImageData* pixels);
+ int texImage2D(unsigned target, unsigned level, HTMLImageElement* image,
+ bool flipY, bool premultiplyAlpha);
+ int texImage2D(unsigned target, unsigned level, HTMLCanvasElement* canvas,
+ bool flipY, bool premultiplyAlpha);
+ int texImage2D(unsigned target, unsigned level, HTMLVideoElement* video,
+ bool flipY, bool premultiplyAlpha);
+
+ void texParameterf(unsigned target, unsigned pname, float param);
+ void texParameteri(unsigned target, unsigned pname, int param);
+
+ int texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
+ unsigned width, unsigned height,
+ unsigned format, unsigned type, CanvasArray* pixels);
+ int texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
+ unsigned width, unsigned height,
+ unsigned format, unsigned type, ImageData* pixels);
+ int texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
+ unsigned width, unsigned height, HTMLImageElement* image,
+ bool flipY, bool premultiplyAlpha);
+ int texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
+ unsigned width, unsigned height, HTMLCanvasElement* canvas,
+ bool flipY, bool premultiplyAlpha);
+ int texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
+ unsigned width, unsigned height, HTMLVideoElement* video,
+ bool flipY, bool premultiplyAlpha);
+
+ void uniform1f(long location, float x);
+ void uniform1fv(long location, float* v, int size);
+ void uniform1i(long location, int x);
+ void uniform1iv(long location, int* v, int size);
+ void uniform2f(long location, float x, float y);
+ void uniform2fv(long location, float* v, int size);
+ void uniform2i(long location, int x, int y);
+ void uniform2iv(long location, int* v, int size);
+ void uniform3f(long location, float x, float y, float z);
+ void uniform3fv(long location, float* v, int size);
+ void uniform3i(long location, int x, int y, int z);
+ void uniform3iv(long location, int* v, int size);
+ void uniform4f(long location, float x, float y, float z, float w);
+ void uniform4fv(long location, float* v, int size);
+ void uniform4i(long location, int x, int y, int z, int w);
+ void uniform4iv(long location, int* v, int size);
+ void uniformMatrix2fv(long location, bool transpose, float* value, int size);
+ void uniformMatrix3fv(long location, bool transpose, float* value, int size);
+ void uniformMatrix4fv(long location, bool transpose, float* value, int size);
+
+ void useProgram(CanvasProgram*);
+ void validateProgram(CanvasProgram*);
+
+ void vertexAttrib1f(unsigned long indx, float x);
+ void vertexAttrib1fv(unsigned long indx, float* values);
+ void vertexAttrib2f(unsigned long indx, float x, float y);
+ void vertexAttrib2fv(unsigned long indx, float* values);
+ void vertexAttrib3f(unsigned long indx, float x, float y, float z);
+ void vertexAttrib3fv(unsigned long indx, float* values);
+ void vertexAttrib4f(unsigned long indx, float x, float y, float z, float w);
+ void vertexAttrib4fv(unsigned long indx, float* values);
+ void vertexAttribPointer(unsigned long indx, int size, int type, bool normalized,
+ unsigned long stride, unsigned long offset);
+
+ void viewport(long x, long y, unsigned long width, unsigned long height);
+
+ void reshape(int width, int height);
+
+ // Helpers for notification about paint events
+ void beginPaint(CanvasRenderingContext3D* context);
+ void endPaint();
+
+ // Support for buffer creation and deletion
+ unsigned createBuffer();
+ unsigned createFramebuffer();
+ unsigned createProgram();
+ unsigned createRenderbuffer();
+ unsigned createShader(ShaderType);
+ unsigned createTexture();
+
+ void deleteBuffer(unsigned);
+ void deleteFramebuffer(unsigned);
+ void deleteProgram(unsigned);
+ void deleteRenderbuffer(unsigned);
+ void deleteShader(unsigned);
+ void deleteTexture(unsigned);
+
+ private:
+ int m_currentWidth, m_currentHeight;
+
+#if PLATFORM(MAC)
+ Vector<Vector<float> > m_vertexArray;
+
+ CGLContextObj m_contextObj;
+ GLuint m_texture;
+ GLuint m_fbo;
+ GLuint m_depthBuffer;
+#endif
+
+ // FIXME: ideally this would be used on all platforms.
+#if PLATFORM(CHROMIUM)
+ friend class GraphicsContext3DInternal;
+ OwnPtr<GraphicsContext3DInternal> m_internal;
+#endif
+ };
+
+} // namespace WebCore
+
+#endif // GraphicsContext3D_h
+
diff --git a/WebCore/platform/graphics/GraphicsLayer.cpp b/WebCore/platform/graphics/GraphicsLayer.cpp
index 7d43832..b375bd3 100644
--- a/WebCore/platform/graphics/GraphicsLayer.cpp
+++ b/WebCore/platform/graphics/GraphicsLayer.cpp
@@ -69,10 +69,11 @@ GraphicsLayer::GraphicsLayer(GraphicsLayerClient* client)
, m_usingTiledLayer(false)
, m_masksToBounds(false)
, m_drawsContent(false)
- , m_paintingPhase(GraphicsLayerPaintAllMask)
+ , m_paintingPhase(GraphicsLayerPaintAll)
, m_geometryOrientation(CompositingCoordinatesTopDown)
, m_contentsOrientation(CompositingCoordinatesTopDown)
, m_parent(0)
+ , m_maskLayer(0)
#ifndef NDEBUG
, m_repaintCount(0)
#endif
diff --git a/WebCore/platform/graphics/GraphicsLayer.h b/WebCore/platform/graphics/GraphicsLayer.h
index 4d7668a..2924073 100644
--- a/WebCore/platform/graphics/GraphicsLayer.h
+++ b/WebCore/platform/graphics/GraphicsLayer.h
@@ -33,11 +33,15 @@
#include "FloatPoint.h"
#include "FloatPoint3D.h"
#include "FloatSize.h"
+#if ENABLE(3D_CANVAS)
+#include "GraphicsContext3D.h"
+#endif
#include "GraphicsLayerClient.h"
#include "IntRect.h"
#include "TransformationMatrix.h"
#include "TransformOperations.h"
#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
#if PLATFORM(MAC)
#ifdef __OBJC__
@@ -152,7 +156,7 @@ protected:
class GraphicsLayer {
public:
- static GraphicsLayer* createGraphicsLayer(GraphicsLayerClient*);
+ static PassOwnPtr<GraphicsLayer> create(GraphicsLayerClient*);
virtual ~GraphicsLayer();
@@ -180,6 +184,9 @@ public:
void removeAllChildren();
virtual void removeFromParent();
+ GraphicsLayer* maskLayer() const { return m_maskLayer; }
+ virtual void setMaskLayer(GraphicsLayer* layer) { m_maskLayer = layer; }
+
// Offset is origin of the renderer minus origin of the graphics layer (so either zero or negative).
IntSize offsetFromRenderer() const { return m_offsetFromRenderer; }
void setOffsetFromRenderer(const IntSize& offset) { m_offsetFromRenderer = offset; }
@@ -229,8 +236,8 @@ public:
virtual void setOpacity(float opacity) { m_opacity = opacity; }
// Some GraphicsLayers paint only the foreground or the background content
- GraphicsLayerPaintingPhase drawingPhase() const { return m_paintingPhase; }
- void setDrawingPhase(GraphicsLayerPaintingPhase phase) { m_paintingPhase = phase; }
+ GraphicsLayerPaintingPhase paintingPhase() const { return m_paintingPhase; }
+ void setPaintingPhase(GraphicsLayerPaintingPhase phase) { m_paintingPhase = phase; }
virtual void setNeedsDisplay() = 0;
// mark the given rect (in layer coords) as needing dispay. Never goes deep.
@@ -255,6 +262,10 @@ public:
virtual void setContentsToVideo(PlatformLayer*) { }
virtual void setContentsBackgroundColor(const Color&) { }
+#if ENABLE(3D_CANVAS)
+ virtual void setContentsToGraphicsContext3D(const GraphicsContext3D*) { }
+ virtual void setGraphicsContext3DNeedsDisplay() { }
+#endif
// Callback from the underlying graphics system to draw layer contents.
void paintGraphicsLayerContents(GraphicsContext&, const IntRect& clip);
@@ -347,6 +358,8 @@ protected:
Vector<GraphicsLayer*> m_children;
GraphicsLayer* m_parent;
+ GraphicsLayer* m_maskLayer; // Reference to mask layer. We don't own this.
+
IntRect m_contentsRect;
#ifndef NDEBUG
diff --git a/WebCore/platform/graphics/GraphicsLayerClient.h b/WebCore/platform/graphics/GraphicsLayerClient.h
index 8c0b7ed..5facc94 100644
--- a/WebCore/platform/graphics/GraphicsLayerClient.h
+++ b/WebCore/platform/graphics/GraphicsLayerClient.h
@@ -37,9 +37,10 @@ class IntRect;
class FloatPoint;
enum GraphicsLayerPaintingPhase {
- GraphicsLayerPaintBackgroundMask = (1 << 0),
- GraphicsLayerPaintForegroundMask = (1 << 1),
- GraphicsLayerPaintAllMask = (GraphicsLayerPaintBackgroundMask | GraphicsLayerPaintForegroundMask)
+ GraphicsLayerPaintBackground = (1 << 0),
+ GraphicsLayerPaintForeground = (1 << 1),
+ GraphicsLayerPaintMask = (1 << 2),
+ GraphicsLayerPaintAll = (GraphicsLayerPaintBackground | GraphicsLayerPaintForeground | GraphicsLayerPaintMask)
};
enum AnimatedPropertyID {
diff --git a/WebCore/platform/graphics/ImageBuffer.h b/WebCore/platform/graphics/ImageBuffer.h
index 2a96d3b..9432058 100644
--- a/WebCore/platform/graphics/ImageBuffer.h
+++ b/WebCore/platform/graphics/ImageBuffer.h
@@ -50,6 +50,11 @@ namespace WebCore {
LinearRGB
};
+ enum Multiply {
+ Premultiplied,
+ Unmultiplied
+ };
+
class ImageBuffer : public Noncopyable {
public:
// Will return a null pointer on allocation failure.
@@ -71,8 +76,11 @@ namespace WebCore {
void clearImage() { m_image.clear(); }
- PassRefPtr<ImageData> getImageData(const IntRect& rect) const;
- void putImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint);
+ PassRefPtr<ImageData> getUnmultipliedImageData(const IntRect&) const;
+ PassRefPtr<ImageData> getPremultipliedImageData(const IntRect&) const;
+
+ void putUnmultipliedImageData(ImageData*, const IntRect& sourceRect, const IntPoint& destPoint);
+ void putPremultipliedImageData(ImageData*, const IntRect& sourceRect, const IntPoint& destPoint);
String toDataURL(const String& mimeType) const;
#if !PLATFORM(CG)
diff --git a/WebCore/platform/graphics/cairo/ImageSourceCairo.cpp b/WebCore/platform/graphics/ImageSource.cpp
index df62618..bf7ae21 100644
--- a/WebCore/platform/graphics/cairo/ImageSourceCairo.cpp
+++ b/WebCore/platform/graphics/ImageSource.cpp
@@ -1,6 +1,8 @@
/*
* Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
* Copyright (C) 2007 Alp Toker <alp.toker@collabora.co.uk>
+ * Copyright (C) 2008, Google Inc. All rights reserved.
+ * Copyright (C) 2007-2009 Torch Mobile, Inc
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,64 +29,20 @@
#include "config.h"
#include "ImageSource.h"
-#if PLATFORM(CAIRO)
+#if PLATFORM(QT)
+#include "ImageDecoderQt.h"
+#else
+#include "ImageDecoder.h"
+#endif
-#include "BMPImageDecoder.h"
-#include "GIFImageDecoder.h"
-#include "ICOImageDecoder.h"
-#include "JPEGImageDecoder.h"
-#include "PNGImageDecoder.h"
-#include "XBMImageDecoder.h"
-#include "SharedBuffer.h"
-#include <cairo.h>
+#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
+#ifndef IMAGE_DECODER_DOWN_SAMPLING_MAX_NUMBER_OF_PIXELS
+#define IMAGE_DECODER_DOWN_SAMPLING_MAX_NUMBER_OF_PIXELS (1024 * 1024)
+#endif
+#endif
namespace WebCore {
-ImageDecoder* createDecoder(const Vector<char>& data)
-{
- // We need at least 4 bytes to figure out what kind of image we're dealing with.
- int length = data.size();
- if (length < 4)
- return 0;
-
- const unsigned char* uContents = (const unsigned char*)data.data();
- const char* contents = data.data();
-
- // GIFs begin with GIF8(7 or 9).
- if (strncmp(contents, "GIF8", 4) == 0)
- return new GIFImageDecoder();
-
- // Test for PNG.
- if (uContents[0]==0x89 &&
- uContents[1]==0x50 &&
- uContents[2]==0x4E &&
- uContents[3]==0x47)
- return new PNGImageDecoder();
-
- // JPEG
- if (uContents[0]==0xFF &&
- uContents[1]==0xD8 &&
- uContents[2]==0xFF)
- return new JPEGImageDecoder();
-
- // BMP
- if (strncmp(contents, "BM", 2) == 0)
- return new BMPImageDecoder();
-
- // ICOs always begin with a 2-byte 0 followed by a 2-byte 1.
- // CURs begin with 2-byte 0 followed by 2-byte 2.
- if (!memcmp(contents, "\000\000\001\000", 4) ||
- !memcmp(contents, "\000\000\002\000", 4))
- return new ICOImageDecoder();
-
- // XBMs require 8 bytes of info.
- if (length >= 8 && strncmp(contents, "#define ", 8) == 0)
- return new XBMImageDecoder();
-
- // Give up. We don't know what the heck this is.
- return 0;
-}
-
ImageSource::ImageSource()
: m_decoder(0)
{
@@ -120,53 +78,41 @@ void ImageSource::setData(SharedBuffer* data, bool allDataReceived)
// This method will examine the data and instantiate an instance of the appropriate decoder plugin.
// If insufficient bytes are available to determine the image type, no decoder plugin will be
// made.
- if (!m_decoder)
- m_decoder = createDecoder(data->buffer());
-
- if (!m_decoder)
- return;
+ if (!m_decoder) {
+ m_decoder = static_cast<NativeImageSourcePtr>(ImageDecoder::create(*data));
+#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
+ if (m_decoder)
+ m_decoder->setMaxNumPixels(IMAGE_DECODER_DOWN_SAMPLING_MAX_NUMBER_OF_PIXELS);
+#endif
+ }
- m_decoder->setData(data, allDataReceived);
+ if (m_decoder)
+ m_decoder->setData(data, allDataReceived);
}
String ImageSource::filenameExtension() const
{
- if (!m_decoder)
- return String();
-
- return m_decoder->filenameExtension();
+ return m_decoder ? m_decoder->filenameExtension() : String();
}
bool ImageSource::isSizeAvailable()
{
- if (!m_decoder)
- return false;
-
- return m_decoder->isSizeAvailable();
+ return m_decoder && m_decoder->isSizeAvailable();
}
IntSize ImageSource::size() const
{
- if (!m_decoder)
- return IntSize();
-
- return m_decoder->size();
+ return m_decoder ? m_decoder->size() : IntSize();
}
IntSize ImageSource::frameSizeAtIndex(size_t index) const
{
- if (!m_decoder)
- return IntSize();
-
- return m_decoder->frameSizeAtIndex(index);
+ return m_decoder ? m_decoder->frameSizeAtIndex(index) : IntSize();
}
int ImageSource::repetitionCount()
{
- if (!m_decoder)
- return cAnimationNone;
-
- return m_decoder->repetitionCount();
+ return m_decoder ? m_decoder->repetitionCount() : cAnimationNone;
}
size_t ImageSource::frameCount() const
@@ -176,9 +122,6 @@ size_t ImageSource::frameCount() const
NativeImagePtr ImageSource::createFrameAtIndex(size_t index)
{
- if (!initialized())
- return 0;
-
if (!m_decoder)
return 0;
@@ -186,23 +129,16 @@ NativeImagePtr ImageSource::createFrameAtIndex(size_t index)
if (!buffer || buffer->status() == RGBA32Buffer::FrameEmpty)
return 0;
- // Cairo does not like zero height images.
- // If we have a zero height image, just pretend we don't have enough data yet.
- if (!size().height())
+ // Zero-height images can cause problems for some ports. If we have an
+ // empty image dimension, just bail.
+ if (size().isEmpty())
return 0;
+ // Return the buffer contents as a native image. For some ports, the data
+ // is already in a native container, and this just increments its refcount.
return buffer->asNewNativeImage();
}
-bool ImageSource::frameIsCompleteAtIndex(size_t index)
-{
- if (!m_decoder)
- return false;
-
- RGBA32Buffer* buffer = m_decoder->frameBufferAtIndex(index);
- return buffer && buffer->status() == RGBA32Buffer::FrameComplete;
-}
-
float ImageSource::frameDurationAtIndex(size_t index)
{
if (!m_decoder)
@@ -223,17 +159,23 @@ float ImageSource::frameDurationAtIndex(size_t index)
bool ImageSource::frameHasAlphaAtIndex(size_t index)
{
- // When a frame has not finished decoding, always mark it as having alpha,
- // so we don't get a black background for the undecoded sections.
- // TODO: A better solution is probably to have the underlying buffer's
- // hasAlpha() return true in these cases, since it is, in fact, technically
- // true.
- if (!frameIsCompleteAtIndex(index))
- return true;
-
- return m_decoder->frameBufferAtIndex(index)->hasAlpha();
+ // When a frame has not finished decoding, always mark it as having alpha.
+ // Ports that check the result of this function to determine their
+ // compositing op need this in order to not draw the undecoded portion as
+ // black.
+ // TODO: Perhaps we should ensure that each individual decoder returns true
+ // in this case.
+ return !frameIsCompleteAtIndex(index)
+ || m_decoder->frameBufferAtIndex(index)->hasAlpha();
}
+bool ImageSource::frameIsCompleteAtIndex(size_t index)
+{
+ if (!m_decoder)
+ return false;
+
+ RGBA32Buffer* buffer = m_decoder->frameBufferAtIndex(index);
+ return buffer && buffer->status() == RGBA32Buffer::FrameComplete;
}
-#endif // PLATFORM(CAIRO)
+}
diff --git a/WebCore/platform/graphics/ImageSource.h b/WebCore/platform/graphics/ImageSource.h
index 173d50b..eabeeab 100644
--- a/WebCore/platform/graphics/ImageSource.h
+++ b/WebCore/platform/graphics/ImageSource.h
@@ -51,6 +51,8 @@ class SkBitmapRef;
class PrivateAndroidImageSourceRec;
#elif PLATFORM(SKIA)
class NativeImageSkia;
+#elif PLATFORM(HAIKU)
+class BBitmap;
#elif PLATFORM(WINCE)
#include "SharedBitmap.h"
#endif
@@ -61,22 +63,14 @@ class IntSize;
class SharedBuffer;
class String;
-#if PLATFORM(WX)
-class ImageDecoder;
-typedef ImageDecoder* NativeImageSourcePtr;
-typedef const Vector<char>* NativeBytePtr;
-#if USE(WXGC)
-typedef wxGraphicsBitmap* NativeImagePtr;
-#else
-typedef wxBitmap* NativeImagePtr;
-#endif
-#elif PLATFORM(CG)
+#if PLATFORM(CG)
typedef CGImageSourceRef NativeImageSourcePtr;
typedef CGImageRef NativeImagePtr;
#elif PLATFORM(QT)
class ImageDecoderQt;
typedef ImageDecoderQt* NativeImageSourcePtr;
typedef QPixmap* NativeImagePtr;
+<<<<<<< HEAD:WebCore/platform/graphics/ImageSource.h
#elif PLATFORM(ANDROID)
#if PLATFORM(SGL)
class String;
@@ -98,18 +92,27 @@ typedef ImageDecoder* NativeImageSourcePtr;
typedef NativeImageSkia* NativeImagePtr;
#endif
#elif PLATFORM(CAIRO)
+=======
+#else
+>>>>>>> webkit.org at 49305:WebCore/platform/graphics/ImageSource.h
class ImageDecoder;
typedef ImageDecoder* NativeImageSourcePtr;
+#if PLATFORM(WX)
+#if USE(WXGC)
+typedef wxGraphicsBitmap* NativeImagePtr;
+#else
+typedef wxBitmap* NativeImagePtr;
+#endif
+#elif PLATFORM(CAIRO)
typedef cairo_surface_t* NativeImagePtr;
#elif PLATFORM(SKIA)
-class ImageDecoder;
-typedef ImageDecoder* NativeImageSourcePtr;
typedef NativeImageSkia* NativeImagePtr;
+#elif PLATFORM(HAIKU)
+typedef BBitmap* NativeImagePtr;
#elif PLATFORM(WINCE)
-class ImageDecoder;
-typedef ImageDecoder* NativeImageSourcePtr;
typedef RefPtr<SharedBitmap> NativeImagePtr;
#endif
+#endif
const int cAnimationLoopOnce = -1;
const int cAnimationNone = -2;
diff --git a/WebCore/platform/graphics/IntPoint.h b/WebCore/platform/graphics/IntPoint.h
index e6d4816..afbfb46 100644
--- a/WebCore/platform/graphics/IntPoint.h
+++ b/WebCore/platform/graphics/IntPoint.h
@@ -55,6 +55,8 @@ class QPoint;
QT_END_NAMESPACE
#elif PLATFORM(GTK)
typedef struct _GdkPoint GdkPoint;
+#elif PLATFORM(HAIKU)
+class BPoint;
#endif
#if PLATFORM(WX)
@@ -121,6 +123,9 @@ public:
#elif PLATFORM(GTK)
IntPoint(const GdkPoint&);
operator GdkPoint() const;
+#elif PLATFORM(HAIKU)
+ explicit IntPoint(const BPoint&);
+ operator BPoint() const;
#endif
#if PLATFORM(WX)
diff --git a/WebCore/platform/graphics/IntRect.h b/WebCore/platform/graphics/IntRect.h
index 0b607f5..cd912ff 100644
--- a/WebCore/platform/graphics/IntRect.h
+++ b/WebCore/platform/graphics/IntRect.h
@@ -33,7 +33,7 @@
typedef struct CGRect CGRect;
#endif
-#if PLATFORM(MAC)
+#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN))
#ifdef NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES
typedef struct CGRect NSRect;
#else
@@ -49,6 +49,8 @@ class QRect;
QT_END_NAMESPACE
#elif PLATFORM(GTK)
typedef struct _GdkRectangle GdkRectangle;
+#elif PLATFORM(HAIKU)
+class BRect;
#endif
#if PLATFORM(WX)
@@ -144,6 +146,9 @@ public:
#elif PLATFORM(GTK)
IntRect(const GdkRectangle&);
operator GdkRectangle() const;
+#elif PLATFORM(HAIKU)
+ explicit IntRect(const BRect&);
+ operator BRect() const;
#endif
#if PLATFORM(CG)
@@ -156,7 +161,8 @@ public:
operator SkIRect() const;
#endif
-#if PLATFORM(MAC) && !defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES)
+#if (PLATFORM(MAC) && !defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES)) \
+ || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN))
operator NSRect() const;
#endif
@@ -193,7 +199,8 @@ inline bool operator!=(const IntRect& a, const IntRect& b)
IntRect enclosingIntRect(const CGRect&);
#endif
-#if PLATFORM(MAC) && !defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES)
+#if (PLATFORM(MAC) && !defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES)) \
+ || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN))
IntRect enclosingIntRect(const NSRect&);
#endif
diff --git a/WebCore/platform/graphics/IntSize.h b/WebCore/platform/graphics/IntSize.h
index dc7a85d..b242784 100644
--- a/WebCore/platform/graphics/IntSize.h
+++ b/WebCore/platform/graphics/IntSize.h
@@ -47,6 +47,12 @@ typedef struct tagSIZE SIZE;
QT_BEGIN_NAMESPACE
class QSize;
QT_END_NAMESPACE
+#elif PLATFORM(HAIKU)
+class BSize;
+#endif
+
+#if PLATFORM(WX)
+class wxSize;
#endif
namespace WebCore {
@@ -113,6 +119,15 @@ public:
operator QSize() const;
#endif
+#if PLATFORM(HAIKU)
+ explicit IntSize(const BSize&);
+ operator BSize() const;
+#endif
+
+#if PLATFORM(WX)
+ IntSize(const wxSize&);
+ operator wxSize() const;
+#endif
private:
int m_width, m_height;
diff --git a/WebCore/platform/graphics/MediaPlayer.cpp b/WebCore/platform/graphics/MediaPlayer.cpp
index 8792640..3898386 100644
--- a/WebCore/platform/graphics/MediaPlayer.cpp
+++ b/WebCore/platform/graphics/MediaPlayer.cpp
@@ -35,10 +35,11 @@
#include "FrameView.h"
#include "Frame.h"
#include "Document.h"
+#include "TimeRanges.h"
#if PLATFORM(MAC)
#include "MediaPlayerPrivateQTKit.h"
-#elif PLATFORM(WINCE)
+#elif PLATFORM(WINCE) && !PLATFORM(QT)
#include "MediaPlayerPrivateWince.h"
#elif PLATFORM(WIN)
#include "MediaPlayerPrivateQuickTimeWin.h"
@@ -67,11 +68,12 @@ public:
virtual void play() { }
virtual void pause() { }
- virtual bool supportsFullscreen() const { return false; }
+ virtual PlatformMedia platformMedia() const { return NoPlatformMedia; }
virtual IntSize naturalSize() const { return IntSize(0, 0); }
virtual bool hasVideo() const { return false; }
+ virtual bool hasAudio() const { return false; }
virtual void setVisible(bool) { }
@@ -93,7 +95,7 @@ public:
virtual MediaPlayer::ReadyState readyState() const { return MediaPlayer::HaveNothing; }
virtual float maxTimeSeekable() const { return 0; }
- virtual float maxTimeBuffered() const { return 0; }
+ virtual PassRefPtr<TimeRanges> buffered() const { return TimeRanges::create(); }
virtual int dataRate() const { return 0; }
@@ -260,11 +262,19 @@ bool MediaPlayer::canLoadPoster() const
{
return m_private->canLoadPoster();
}
+<<<<<<< HEAD:WebCore/platform/graphics/MediaPlayer.cpp
+=======
+
+>>>>>>> webkit.org at 49305:WebCore/platform/graphics/MediaPlayer.cpp
void MediaPlayer::setPoster(const String& url)
{
m_private->setPoster(url);
+<<<<<<< HEAD:WebCore/platform/graphics/MediaPlayer.cpp
}
+=======
+}
+>>>>>>> webkit.org at 49305:WebCore/platform/graphics/MediaPlayer.cpp
void MediaPlayer::cancelLoad()
{
@@ -275,7 +285,11 @@ void MediaPlayer::prepareToPlay()
{
m_private->prepareToPlay();
}
+<<<<<<< HEAD:WebCore/platform/graphics/MediaPlayer.cpp
+=======
+
+>>>>>>> webkit.org at 49305:WebCore/platform/graphics/MediaPlayer.cpp
void MediaPlayer::play()
{
m_private->play();
@@ -331,11 +345,16 @@ IntSize MediaPlayer::naturalSize()
return m_private->naturalSize();
}
-bool MediaPlayer::hasVideo()
+bool MediaPlayer::hasVideo() const
{
return m_private->hasVideo();
}
+bool MediaPlayer::hasAudio() const
+{
+ return m_private->hasAudio();
+}
+
bool MediaPlayer::inMediaDocument()
{
Frame* frame = m_frameView ? m_frameView->frame() : 0;
@@ -344,6 +363,11 @@ bool MediaPlayer::inMediaDocument()
return document && document->isMediaDocument();
}
+PlatformMedia MediaPlayer::platformMedia() const
+{
+ return m_private->platformMedia();
+}
+
MediaPlayer::NetworkState MediaPlayer::networkState()
{
return m_private->networkState();
@@ -397,9 +421,9 @@ void MediaPlayer::setEndTime(float time)
m_private->setEndTime(time);
}
-float MediaPlayer::maxTimeBuffered()
+PassRefPtr<TimeRanges> MediaPlayer::buffered()
{
- return m_private->maxTimeBuffered();
+ return m_private->buffered();
}
float MediaPlayer::maxTimeSeekable()
diff --git a/WebCore/platform/graphics/MediaPlayer.h b/WebCore/platform/graphics/MediaPlayer.h
index d0220ed..4cc6476 100644
--- a/WebCore/platform/graphics/MediaPlayer.h
+++ b/WebCore/platform/graphics/MediaPlayer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 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
@@ -38,8 +38,24 @@
#include <wtf/OwnPtr.h>
#include <wtf/Noncopyable.h>
+#ifdef __OBJC__
+@class QTMovie;
+#else
+class QTMovie;
+#endif
+
namespace WebCore {
+// Structure that will hold every native
+// types supported by the current media player.
+// We have to do that has multiple media players
+// backend can live at runtime.
+typedef struct PlatformMedia {
+ QTMovie* qtMovie;
+} PlatformMedia;
+
+static const PlatformMedia NoPlatformMedia = { 0 };
+
class ContentType;
class FrameView;
class GraphicsContext;
@@ -48,6 +64,7 @@ class IntSize;
class MediaPlayer;
class MediaPlayerPrivateInterface;
class String;
+class TimeRanges;
#if USE(ACCELERATED_COMPOSITING)
class GraphicsLayer;
@@ -109,8 +126,11 @@ public:
bool supportsFullscreen() const;
bool supportsSave() const;
+ PlatformMedia platformMedia() const;
+
IntSize naturalSize();
- bool hasVideo();
+ bool hasVideo() const;
+ bool hasAudio() const;
void setFrameView(FrameView* frameView) { m_frameView = frameView; }
FrameView* frameView() { return m_frameView; }
@@ -146,7 +166,7 @@ public:
bool preservesPitch() const;
void setPreservesPitch(bool);
- float maxTimeBuffered();
+ PassRefPtr<TimeRanges> buffered();
float maxTimeSeekable();
unsigned bytesLoaded();
diff --git a/WebCore/platform/graphics/MediaPlayerPrivate.h b/WebCore/platform/graphics/MediaPlayerPrivate.h
index de7f75c..925e563 100644
--- a/WebCore/platform/graphics/MediaPlayerPrivate.h
+++ b/WebCore/platform/graphics/MediaPlayerPrivate.h
@@ -44,6 +44,11 @@ public:
virtual void cancelLoad() = 0;
virtual void prepareToPlay() { }
+<<<<<<< HEAD:WebCore/platform/graphics/MediaPlayerPrivate.h
+=======
+ virtual PlatformMedia platformMedia() const { return NoPlatformMedia; }
+
+>>>>>>> webkit.org at 49305:WebCore/platform/graphics/MediaPlayerPrivate.h
virtual void play() = 0;
virtual void pause() = 0;
@@ -53,6 +58,7 @@ public:
virtual IntSize naturalSize() const = 0;
virtual bool hasVideo() const = 0;
+ virtual bool hasAudio() const = 0;
virtual void setVisible(bool) = 0;
@@ -77,7 +83,7 @@ public:
virtual MediaPlayer::ReadyState readyState() const = 0;
virtual float maxTimeSeekable() const = 0;
- virtual float maxTimeBuffered() const = 0;
+ virtual PassRefPtr<TimeRanges> buffered() const = 0;
virtual int dataRate() const = 0;
diff --git a/WebCore/platform/graphics/Path.h b/WebCore/platform/graphics/Path.h
index da324bc..6b617a0 100644
--- a/WebCore/platform/graphics/Path.h
+++ b/WebCore/platform/graphics/Path.h
@@ -52,6 +52,9 @@ typedef WebCore::CairoPath PlatformPath;
#elif PLATFORM(SKIA)
class SkPath;
typedef SkPath PlatformPath;
+#elif PLATFORM(HAIKU)
+class BRegion;
+typedef BRegion PlatformPath;
#elif PLATFORM(WINCE)
namespace WebCore {
class PlatformPath;
diff --git a/WebCore/platform/graphics/Pattern.h b/WebCore/platform/graphics/Pattern.h
index 02ad3ec..2f1192c 100644
--- a/WebCore/platform/graphics/Pattern.h
+++ b/WebCore/platform/graphics/Pattern.h
@@ -53,6 +53,9 @@ typedef wxGraphicsBrush* PlatformPatternPtr;
class wxBrush;
typedef wxBrush* PlatformPatternPtr;
#endif // USE(WXGC)
+#elif PLATFORM(HAIKU)
+#include <interface/GraphicsDefs.h>
+typedef pattern* PlatformPatternPtr;
#elif PLATFORM(WINCE)
typedef void* PlatformPatternPtr;
#endif
diff --git a/WebCore/platform/graphics/SimpleFontData.cpp b/WebCore/platform/graphics/SimpleFontData.cpp
index c879228..2ec8abb 100644
--- a/WebCore/platform/graphics/SimpleFontData.cpp
+++ b/WebCore/platform/graphics/SimpleFontData.cpp
@@ -48,7 +48,9 @@ using namespace std;
namespace WebCore {
SimpleFontData::SimpleFontData(const FontPlatformData& f, bool customFont, bool loading, SVGFontData* svgFontData)
- : m_unitsPerEm(defaultUnitsPerEm)
+ : m_maxCharWidth(-1)
+ , m_avgCharWidth(-1)
+ , m_unitsPerEm(defaultUnitsPerEm)
, m_platformData(f)
, m_treatAsFixedPitch(false)
#if ENABLE(SVG_FONTS)
diff --git a/WebCore/platform/graphics/SimpleFontData.h b/WebCore/platform/graphics/SimpleFontData.h
index cb472b0..387a5c7 100644
--- a/WebCore/platform/graphics/SimpleFontData.h
+++ b/WebCore/platform/graphics/SimpleFontData.h
@@ -2,6 +2,7 @@
* This file is part of the internal font implementation.
*
* Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007-2008 Torch Mobile, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -27,13 +28,14 @@
#include "FontPlatformData.h"
#include "GlyphPageTreeNode.h"
#include "GlyphWidthMap.h"
+#include "TextRenderingMode.h"
#include <wtf/OwnPtr.h>
#if USE(ATSUI)
typedef struct OpaqueATSUStyle* ATSUStyle;
#endif
-#if PLATFORM(WIN)
+#if PLATFORM(WIN) && !PLATFORM(WINCE)
#include <usp10.h>
#endif
@@ -45,6 +47,10 @@ typedef struct OpaqueATSUStyle* ATSUStyle;
#include <QFont>
#endif
+#if PLATFORM(HAIKU)
+#include <Font.h>
+#endif
+
namespace WebCore {
class FontDescription;
@@ -115,7 +121,7 @@ public:
#if USE(CORE_TEXT)
CTFontRef getCTFont() const;
- CFDictionaryRef getCFStringAttributes() const;
+ CFDictionaryRef getCFStringAttributes(TextRenderingMode) const;
#endif
#if USE(ATSUI)
@@ -134,17 +140,14 @@ public:
#if PLATFORM(WIN)
bool isSystemFont() const { return m_isSystemFont; }
+#if !PLATFORM(WINCE) // disable unused members to save space
SCRIPT_FONTPROPERTIES* scriptFontProperties() const;
SCRIPT_CACHE* scriptCache() const { return &m_scriptCache; }
-
+#endif
static void setShouldApplyMacAscentHack(bool);
static bool shouldApplyMacAscentHack();
#endif
-#if PLATFORM(CAIRO)
- void setFont(cairo_t*) const;
-#endif
-
#if PLATFORM(WX)
wxFont* getWxFont() const { return m_platformData.font(); }
#endif
@@ -159,7 +162,7 @@ private:
void commonInit();
-#if PLATFORM(WIN)
+#if PLATFORM(WIN) && !PLATFORM(WINCE)
void initGDIFont();
void platformCommonDestroy();
float widthForGDIGlyph(Glyph glyph) const;
@@ -224,9 +227,11 @@ private:
#if PLATFORM(WIN)
bool m_isSystemFont;
+#if !PLATFORM(WINCE) // disable unused members to save space
mutable SCRIPT_CACHE m_scriptCache;
mutable SCRIPT_FONTPROPERTIES* m_scriptFontProperties;
#endif
+#endif
};
diff --git a/WebCore/platform/graphics/TextRenderingMode.h b/WebCore/platform/graphics/TextRenderingMode.h
new file mode 100644
index 0000000..4f817a4
--- /dev/null
+++ b/WebCore/platform/graphics/TextRenderingMode.h
@@ -0,0 +1,35 @@
+/*
+ * 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 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 TextRenderingMode_h
+#define TextRenderingMode_h
+
+namespace WebCore {
+
+ enum TextRenderingMode { AutoTextRendering, OptimizeSpeed, OptimizeLegibility, GeometricPrecision };
+
+} // namespace WebCore
+
+#endif // TextRenderingMode_h
diff --git a/WebCore/platform/graphics/cairo/FontCairo.cpp b/WebCore/platform/graphics/cairo/FontCairo.cpp
index 0f7ae79..1a951c2 100644
--- a/WebCore/platform/graphics/cairo/FontCairo.cpp
+++ b/WebCore/platform/graphics/cairo/FontCairo.cpp
@@ -46,7 +46,7 @@ void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, cons
cairo_t* cr = context->platformContext();
cairo_save(cr);
- font->setFont(cr);
+ cairo_set_scaled_font(cr, font->platformData().scaledFont());
GlyphBufferGlyph* glyphs = (GlyphBufferGlyph*)glyphBuffer.glyphs(from);
diff --git a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
index 5765546..de8afb3 100644
--- a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
+++ b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
@@ -31,7 +31,6 @@
#if PLATFORM(CAIRO)
-#include "TransformationMatrix.h"
#include "CairoPath.h"
#include "FloatRect.h"
#include "Font.h"
@@ -41,6 +40,7 @@
#include "Path.h"
#include "Pattern.h"
#include "SimpleFontData.h"
+#include "TransformationMatrix.h"
#include <cairo.h>
#include <math.h>
@@ -53,8 +53,8 @@
#elif PLATFORM(WIN)
#include <cairo-win32.h>
#endif
-#include "GraphicsContextPrivate.h"
#include "GraphicsContextPlatformPrivateCairo.h"
+#include "GraphicsContextPrivate.h"
#ifndef M_PI
#define M_PI 3.14159265358979323846
@@ -142,38 +142,6 @@ void GraphicsContext::drawRect(const IntRect& rect)
cairo_restore(cr);
}
-// FIXME: Now that this is refactored, it should be shared by all contexts.
-static void adjustLineToPixelBoundaries(FloatPoint& p1, FloatPoint& p2, float strokeWidth, StrokeStyle style)
-{
- // For odd widths, we add in 0.5 to the appropriate x/y so that the float arithmetic
- // works out. For example, with a border width of 3, KHTML will pass us (y1+y2)/2, e.g.,
- // (50+53)/2 = 103/2 = 51 when we want 51.5. It is always true that an even width gave
- // us a perfect position, but an odd width gave us a position that is off by exactly 0.5.
- if (style == DottedStroke || style == DashedStroke) {
- if (p1.x() == p2.x()) {
- p1.setY(p1.y() + strokeWidth);
- p2.setY(p2.y() - strokeWidth);
- }
- else {
- p1.setX(p1.x() + strokeWidth);
- p2.setX(p2.x() - strokeWidth);
- }
- }
-
- if (static_cast<int>(strokeWidth) % 2) {
- if (p1.x() == p2.x()) {
- // We're a vertical line. Adjust our x.
- p1.setX(p1.x() + 0.5);
- p2.setX(p2.x() + 0.5);
- }
- else {
- // We're a horizontal line. Adjust our y.
- p1.setY(p1.y() + 0.5);
- p2.setY(p2.y() + 0.5);
- }
- }
-}
-
// This is only used to draw borders.
void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
{
@@ -239,20 +207,18 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
if (patWidth == 1)
patternOffset = 1.0;
else {
- bool evenNumberOfSegments = numSegments%2 == 0;
+ bool evenNumberOfSegments = !(numSegments % 2);
if (remainder)
evenNumberOfSegments = !evenNumberOfSegments;
if (evenNumberOfSegments) {
if (remainder) {
patternOffset += patWidth - remainder;
- patternOffset += remainder/2;
- }
- else
- patternOffset = patWidth/2;
- }
- else if (!evenNumberOfSegments) {
+ patternOffset += remainder / 2;
+ } else
+ patternOffset = patWidth / 2;
+ } else if (!evenNumberOfSegments) {
if (remainder)
- patternOffset = (patWidth - remainder)/2;
+ patternOffset = (patWidth - remainder) / 2;
}
}
@@ -318,7 +284,7 @@ void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSp
if (w != h)
cairo_scale(cr, 1., scaleFactor);
-
+
cairo_arc_negative(cr, x + hRadius, (y + vRadius) * reverseScaleFactor, hRadius, -fa * M_PI/180, -falen * M_PI/180);
if (w != h)
@@ -326,16 +292,16 @@ void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSp
float width = strokeThickness();
int patWidth = 0;
-
+
switch (strokeStyle()) {
- case DottedStroke:
- patWidth = static_cast<int>(width / 2);
- break;
- case DashedStroke:
- patWidth = 3 * static_cast<int>(width / 2);
- break;
- default:
- break;
+ case DottedStroke:
+ patWidth = static_cast<int>(width / 2);
+ break;
+ case DashedStroke:
+ patWidth = 3 * static_cast<int>(width / 2);
+ break;
+ default:
+ break;
}
setColor(cr, strokeColor());
@@ -349,7 +315,7 @@ void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSp
distance = static_cast<int>((M_PI * hRadius) / 2.0);
else // We are elliptical and will have to estimate the distance
distance = static_cast<int>((M_PI * sqrtf((hRadius * hRadius + vRadius * vRadius) / 2.0)) / 2.0);
-
+
int remainder = distance % patWidth;
int coverage = distance - remainder;
int numSegments = coverage / patWidth;
@@ -359,7 +325,7 @@ void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSp
if (patWidth == 1)
patternOffset = 1.0;
else {
- bool evenNumberOfSegments = numSegments % 2 == 0;
+ bool evenNumberOfSegments = !(numSegments % 2);
if (remainder)
evenNumberOfSegments = !evenNumberOfSegments;
if (evenNumberOfSegments) {
@@ -828,15 +794,15 @@ void GraphicsContext::setLineCap(LineCap lineCap)
cairo_line_cap_t cairoCap = CAIRO_LINE_CAP_BUTT;
switch (lineCap) {
- case ButtCap:
- // no-op
- break;
- case RoundCap:
- cairoCap = CAIRO_LINE_CAP_ROUND;
- break;
- case SquareCap:
- cairoCap = CAIRO_LINE_CAP_SQUARE;
- break;
+ case ButtCap:
+ // no-op
+ break;
+ case RoundCap:
+ cairoCap = CAIRO_LINE_CAP_ROUND;
+ break;
+ case SquareCap:
+ cairoCap = CAIRO_LINE_CAP_SQUARE;
+ break;
}
cairo_set_line_cap(m_data->cr, cairoCap);
}
@@ -853,15 +819,15 @@ void GraphicsContext::setLineJoin(LineJoin lineJoin)
cairo_line_join_t cairoJoin = CAIRO_LINE_JOIN_MITER;
switch (lineJoin) {
- case MiterJoin:
- // no-op
- break;
- case RoundJoin:
- cairoJoin = CAIRO_LINE_JOIN_ROUND;
- break;
- case BevelJoin:
- cairoJoin = CAIRO_LINE_JOIN_BEVEL;
- break;
+ case MiterJoin:
+ // no-op
+ break;
+ case RoundJoin:
+ cairoJoin = CAIRO_LINE_JOIN_ROUND;
+ break;
+ case BevelJoin:
+ cairoJoin = CAIRO_LINE_JOIN_BEVEL;
+ break;
}
cairo_set_line_join(m_data->cr, cairoJoin);
}
@@ -887,37 +853,37 @@ float GraphicsContext::getAlpha()
static inline cairo_operator_t toCairoOperator(CompositeOperator op)
{
switch (op) {
- case CompositeClear:
- return CAIRO_OPERATOR_CLEAR;
- case CompositeCopy:
- return CAIRO_OPERATOR_SOURCE;
- case CompositeSourceOver:
- return CAIRO_OPERATOR_OVER;
- case CompositeSourceIn:
- return CAIRO_OPERATOR_IN;
- case CompositeSourceOut:
- return CAIRO_OPERATOR_OUT;
- case CompositeSourceAtop:
- return CAIRO_OPERATOR_ATOP;
- case CompositeDestinationOver:
- return CAIRO_OPERATOR_DEST_OVER;
- case CompositeDestinationIn:
- return CAIRO_OPERATOR_DEST_IN;
- case CompositeDestinationOut:
- return CAIRO_OPERATOR_DEST_OUT;
- case CompositeDestinationAtop:
- return CAIRO_OPERATOR_DEST_ATOP;
- case CompositeXOR:
- return CAIRO_OPERATOR_XOR;
- case CompositePlusDarker:
- return CAIRO_OPERATOR_SATURATE;
- case CompositeHighlight:
- // There is no Cairo equivalent for CompositeHighlight.
- return CAIRO_OPERATOR_OVER;
- case CompositePlusLighter:
- return CAIRO_OPERATOR_ADD;
- default:
- return CAIRO_OPERATOR_SOURCE;
+ case CompositeClear:
+ return CAIRO_OPERATOR_CLEAR;
+ case CompositeCopy:
+ return CAIRO_OPERATOR_SOURCE;
+ case CompositeSourceOver:
+ return CAIRO_OPERATOR_OVER;
+ case CompositeSourceIn:
+ return CAIRO_OPERATOR_IN;
+ case CompositeSourceOut:
+ return CAIRO_OPERATOR_OUT;
+ case CompositeSourceAtop:
+ return CAIRO_OPERATOR_ATOP;
+ case CompositeDestinationOver:
+ return CAIRO_OPERATOR_DEST_OVER;
+ case CompositeDestinationIn:
+ return CAIRO_OPERATOR_DEST_IN;
+ case CompositeDestinationOut:
+ return CAIRO_OPERATOR_DEST_OUT;
+ case CompositeDestinationAtop:
+ return CAIRO_OPERATOR_DEST_ATOP;
+ case CompositeXOR:
+ return CAIRO_OPERATOR_XOR;
+ case CompositePlusDarker:
+ return CAIRO_OPERATOR_SATURATE;
+ case CompositeHighlight:
+ // There is no Cairo equivalent for CompositeHighlight.
+ return CAIRO_OPERATOR_OVER;
+ case CompositePlusLighter:
+ return CAIRO_OPERATOR_ADD;
+ default:
+ return CAIRO_OPERATOR_SOURCE;
}
}
diff --git a/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp b/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
index c905ee8..0213944 100644
--- a/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
+++ b/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
@@ -138,16 +138,17 @@ void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookUpTable)
}
}
-PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const
+template <Multiply multiplied>
+PassRefPtr<ImageData> getImageData(const IntRect& rect, const ImageBufferData& data, const IntSize& size)
{
- ASSERT(cairo_surface_get_type(m_data.m_surface) == CAIRO_SURFACE_TYPE_IMAGE);
+ ASSERT(cairo_surface_get_type(data.m_surface) == CAIRO_SURFACE_TYPE_IMAGE);
PassRefPtr<ImageData> result = ImageData::create(rect.width(), rect.height());
- unsigned char* dataSrc = cairo_image_surface_get_data(m_data.m_surface);
+ unsigned char* dataSrc = cairo_image_surface_get_data(data.m_surface);
unsigned char* dataDst = result->data()->data()->data();
- if (rect.x() < 0 || rect.y() < 0 || (rect.x() + rect.width()) > m_size.width() || (rect.y() + rect.height()) > m_size.height())
- memset(dataSrc, 0, result->data()->length());
+ if (rect.x() < 0 || rect.y() < 0 || (rect.x() + rect.width()) > size.width() || (rect.y() + rect.height()) > size.height())
+ memset(dataDst, 0, result->data()->length());
int originx = rect.x();
int destx = 0;
@@ -156,8 +157,8 @@ PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const
originx = 0;
}
int endx = rect.x() + rect.width();
- if (endx > m_size.width())
- endx = m_size.width();
+ if (endx > size.width())
+ endx = size.width();
int numColumns = endx - originx;
int originy = rect.y();
@@ -167,11 +168,11 @@ PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const
originy = 0;
}
int endy = rect.y() + rect.height();
- if (endy > m_size.height())
- endy = m_size.height();
+ if (endy > size.height())
+ endy = size.height();
int numRows = endy - originy;
- int stride = cairo_image_surface_get_stride(m_data.m_surface);
+ int stride = cairo_image_surface_get_stride(data.m_surface);
unsigned destBytesPerRow = 4 * rect.width();
unsigned char* destRows = dataDst + desty * destBytesPerRow + destx * 4;
@@ -180,7 +181,11 @@ PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const
for (int x = 0; x < numColumns; x++) {
int basex = x * 4;
unsigned* pixel = row + x + originx;
- Color pixelColor = colorFromPremultipliedARGB(*pixel);
+ Color pixelColor;
+ if (multiplied == Unmultiplied)
+ pixelColor = colorFromPremultipliedARGB(*pixel);
+ else
+ pixelColor = Color(*pixel);
destRows[basex] = pixelColor.red();
destRows[basex + 1] = pixelColor.green();
destRows[basex + 2] = pixelColor.blue();
@@ -192,11 +197,22 @@ PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const
return result;
}
-void ImageBuffer::putImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint)
+PassRefPtr<ImageData> ImageBuffer::getUnmultipliedImageData(const IntRect& rect) const
{
- ASSERT(cairo_surface_get_type(m_data.m_surface) == CAIRO_SURFACE_TYPE_IMAGE);
+ return getImageData<Unmultiplied>(rect, m_data, m_size);
+}
- unsigned char* dataDst = cairo_image_surface_get_data(m_data.m_surface);
+PassRefPtr<ImageData> ImageBuffer::getPremultipliedImageData(const IntRect& rect) const
+{
+ return getImageData<Premultiplied>(rect, m_data, m_size);
+}
+
+template <Multiply multiplied>
+void putImageData(ImageData*& source, const IntRect& sourceRect, const IntPoint& destPoint, ImageBufferData& data, const IntSize& size)
+{
+ ASSERT(cairo_surface_get_type(data.m_surface) == CAIRO_SURFACE_TYPE_IMAGE);
+
+ unsigned char* dataDst = cairo_image_surface_get_data(data.m_surface);
ASSERT(sourceRect.width() > 0);
ASSERT(sourceRect.height() > 0);
@@ -204,28 +220,28 @@ void ImageBuffer::putImageData(ImageData* source, const IntRect& sourceRect, con
int originx = sourceRect.x();
int destx = destPoint.x() + sourceRect.x();
ASSERT(destx >= 0);
- ASSERT(destx < m_size.width());
+ ASSERT(destx < size.width());
ASSERT(originx >= 0);
ASSERT(originx <= sourceRect.right());
int endx = destPoint.x() + sourceRect.right();
- ASSERT(endx <= m_size.width());
+ ASSERT(endx <= size.width());
int numColumns = endx - destx;
int originy = sourceRect.y();
int desty = destPoint.y() + sourceRect.y();
ASSERT(desty >= 0);
- ASSERT(desty < m_size.height());
+ ASSERT(desty < size.height());
ASSERT(originy >= 0);
ASSERT(originy <= sourceRect.bottom());
int endy = destPoint.y() + sourceRect.bottom();
- ASSERT(endy <= m_size.height());
+ ASSERT(endy <= size.height());
int numRows = endy - desty;
unsigned srcBytesPerRow = 4 * source->width();
- int stride = cairo_image_surface_get_stride(m_data.m_surface);
+ int stride = cairo_image_surface_get_stride(data.m_surface);
unsigned char* srcRows = source->data()->data()->data() + originy * srcBytesPerRow + originx * 4;
for (int y = 0; y < numRows; ++y) {
@@ -237,12 +253,25 @@ void ImageBuffer::putImageData(ImageData* source, const IntRect& sourceRect, con
srcRows[basex + 1],
srcRows[basex + 2],
srcRows[basex + 3]);
- *pixel = premultipliedARGBFromColor(pixelColor);
+ if (multiplied == Unmultiplied)
+ *pixel = premultipliedARGBFromColor(pixelColor);
+ else
+ *pixel = pixelColor.rgb();
}
srcRows += srcBytesPerRow;
}
}
+void ImageBuffer::putUnmultipliedImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint)
+{
+ putImageData<Unmultiplied>(source, sourceRect, destPoint, m_data, m_size);
+}
+
+void ImageBuffer::putPremultipliedImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint)
+{
+ putImageData<Premultiplied>(source, sourceRect, destPoint, m_data, m_size);
+}
+
static cairo_status_t writeFunction(void* closure, const unsigned char* data, unsigned int length)
{
Vector<char>* in = reinterpret_cast<Vector<char>*>(closure);
diff --git a/WebCore/platform/graphics/cg/ColorCG.cpp b/WebCore/platform/graphics/cg/ColorCG.cpp
index 0465c0b..40aacc5 100644
--- a/WebCore/platform/graphics/cg/ColorCG.cpp
+++ b/WebCore/platform/graphics/cg/ColorCG.cpp
@@ -29,6 +29,7 @@
#if PLATFORM(CG)
#include <wtf/Assertions.h>
+#include <wtf/RetainPtr.h>
#include <ApplicationServices/ApplicationServices.h>
namespace WebCore {
@@ -75,13 +76,12 @@ CGColorRef createCGColor(const Color& c)
CMProfileRef prof = NULL;
CMGetSystemProfile(&prof);
- CGColorSpaceRef rgbSpace = CGColorSpaceCreateWithPlatformColorSpace(prof);
+ RetainPtr<CGColorSpaceRef> rgbSpace(AdoptCF, CGColorSpaceCreateWithPlatformColorSpace(prof));
- if (rgbSpace != NULL)
- {
- float components[4] = {c.red() / 255.0f, c.green() / 255.0f, c.blue() / 255.0f, c.alpha() / 255.0f};
- color = CGColorCreate(rgbSpace, components);
- CGColorSpaceRelease(rgbSpace);
+ if (rgbSpace) {
+ CGFloat components[4] = { static_cast<CGFloat>(c.red()) / 255, static_cast<CGFloat>(c.green()) / 255,
+ static_cast<CGFloat>(c.blue()) / 255, static_cast<CGFloat>(c.alpha()) / 255 };
+ color = CGColorCreate(rgbSpace.get(), components);
}
CMCloseProfile(prof);
diff --git a/WebCore/platform/graphics/cg/GradientCG.cpp b/WebCore/platform/graphics/cg/GradientCG.cpp
index c189fd5..05a0aad 100644
--- a/WebCore/platform/graphics/cg/GradientCG.cpp
+++ b/WebCore/platform/graphics/cg/GradientCG.cpp
@@ -58,17 +58,14 @@ CGShadingRef Gradient::platformGradient()
const CGFloat intervalRanges[2] = { 0, 1 };
const CGFloat colorComponentRanges[4 * 2] = { 0, 1, 0, 1, 0, 1, 0, 1 };
const CGFunctionCallbacks gradientCallbacks = { 0, gradientCallback, 0 };
- CGFunctionRef colorFunction = CGFunctionCreate(this, 1, intervalRanges, 4, colorComponentRanges, &gradientCallbacks);
+ RetainPtr<CGFunctionRef> colorFunction(AdoptCF, CGFunctionCreate(this, 1, intervalRanges, 4, colorComponentRanges, &gradientCallbacks));
- CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+ static CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
if (m_radial)
- m_gradient = CGShadingCreateRadial(colorSpace, m_p0, m_r0, m_p1, m_r1, colorFunction, true, true);
+ m_gradient = CGShadingCreateRadial(colorSpace, m_p0, m_r0, m_p1, m_r1, colorFunction.get(), true, true);
else
- m_gradient = CGShadingCreateAxial(colorSpace, m_p0, m_p1, colorFunction, true, true);
-
- CGColorSpaceRelease(colorSpace);
- CGFunctionRelease(colorFunction);
+ m_gradient = CGShadingCreateAxial(colorSpace, m_p0, m_p1, colorFunction.get(), true, true);
return m_gradient;
}
diff --git a/WebCore/platform/graphics/cg/GraphicsContextCG.cpp b/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
index ab8eb3c..1b843e4 100644
--- a/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
+++ b/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
@@ -28,14 +28,15 @@
#include "config.h"
#include "GraphicsContext.h"
-#include "TransformationMatrix.h"
#include "FloatConversion.h"
-#include "GraphicsContextPrivate.h"
#include "GraphicsContextPlatformPrivateCG.h"
+#include "GraphicsContextPrivate.h"
#include "ImageBuffer.h"
#include "KURL.h"
#include "Path.h"
#include "Pattern.h"
+#include "TransformationMatrix.h"
+
#include <CoreGraphics/CGBitmapContext.h>
#include <CoreGraphics/CGPDFContext.h>
#include <wtf/MathExtras.h>
@@ -86,7 +87,7 @@ CGContextRef GraphicsContext::platformContext() const
{
ASSERT(!paintingDisabled());
ASSERT(m_data->m_cgContext);
- return m_data->m_cgContext;
+ return m_data->m_cgContext.get();
}
void GraphicsContext::savePlatformState()
@@ -178,19 +179,19 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
int patWidth = 0;
switch (strokeStyle()) {
- case NoStroke:
- case SolidStroke:
- break;
- case DottedStroke:
- patWidth = (int)width;
- break;
- case DashedStroke:
- patWidth = 3 * (int)width;
- break;
+ case NoStroke:
+ case SolidStroke:
+ break;
+ case DottedStroke:
+ patWidth = (int)width;
+ break;
+ case DashedStroke:
+ patWidth = 3 * (int)width;
+ break;
}
CGContextRef context = platformContext();
-
+
if (shouldAntialias())
CGContextSetShouldAntialias(context, false);
@@ -221,7 +222,7 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
if (patWidth == 1)
patternOffset = 1.0f;
else {
- bool evenNumberOfSegments = numSegments % 2 == 0;
+ bool evenNumberOfSegments = !(numSegments % 2);
if (remainder)
evenNumberOfSegments = !evenNumberOfSegments;
if (evenNumberOfSegments) {
@@ -235,7 +236,7 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
patternOffset = (patWidth - remainder)/2;
}
}
-
+
const CGFloat dottedLine[2] = { patWidth, patWidth };
CGContextSetLineDash(context, patternOffset, dottedLine, 2);
}
@@ -248,7 +249,7 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
if (patWidth)
CGContextRestoreGState(context);
-
+
if (shouldAntialias())
CGContextSetShouldAntialias(context, true);
}
@@ -263,7 +264,7 @@ void GraphicsContext::drawEllipse(const IntRect& rect)
if (paintingDisabled())
return;
-
+
CGContextRef context = platformContext();
CGContextBeginPath(context);
float r = (float)rect.width() / 2;
@@ -275,25 +276,25 @@ void GraphicsContext::drawEllipse(const IntRect& rect)
void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSpan)
-{
+{
if (paintingDisabled() || strokeStyle() == NoStroke || strokeThickness() <= 0.0f)
return;
-
+
CGContextRef context = platformContext();
CGContextSaveGState(context);
CGContextBeginPath(context);
CGContextSetShouldAntialias(context, false);
-
+
int x = rect.x();
int y = rect.y();
float w = (float)rect.width();
float h = (float)rect.height();
float scaleFactor = h / w;
float reverseScaleFactor = w / h;
-
+
if (w != h)
scale(FloatSize(1, scaleFactor));
-
+
float hRadius = w / 2;
float vRadius = h / 2;
float fa = startAngle;
@@ -304,22 +305,21 @@ void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSp
if (w != h)
scale(FloatSize(1, reverseScaleFactor));
-
-
+
float width = strokeThickness();
int patWidth = 0;
-
+
switch (strokeStyle()) {
- case DottedStroke:
- patWidth = (int)(width / 2);
- break;
- case DashedStroke:
- patWidth = 3 * (int)(width / 2);
- break;
- default:
- break;
+ case DottedStroke:
+ patWidth = (int)(width / 2);
+ break;
+ case DashedStroke:
+ patWidth = 3 * (int)(width / 2);
+ break;
+ default:
+ break;
}
-
+
if (patWidth) {
// Example: 80 pixels with a width of 30 pixels.
// Remainder is 20. The maximum pixels of line we could paint
@@ -329,7 +329,7 @@ void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSp
distance = static_cast<int>((piFloat * hRadius) / 2.0f);
else // We are elliptical and will have to estimate the distance
distance = static_cast<int>((piFloat * sqrtf((hRadius * hRadius + vRadius * vRadius) / 2.0f)) / 2.0f);
-
+
int remainder = distance % patWidth;
int coverage = distance - remainder;
int numSegments = coverage / patWidth;
@@ -339,7 +339,7 @@ void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSp
if (patWidth == 1)
patternOffset = 1.0f;
else {
- bool evenNumberOfSegments = numSegments % 2 == 0;
+ bool evenNumberOfSegments = !(numSegments % 2);
if (remainder)
evenNumberOfSegments = !evenNumberOfSegments;
if (evenNumberOfSegments) {
@@ -353,13 +353,13 @@ void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSp
patternOffset = (patWidth - remainder) / 2.0f;
}
}
-
+
const CGFloat dottedLine[2] = { patWidth, patWidth };
CGContextSetLineDash(context, patternOffset, dottedLine, 2);
}
CGContextStrokePath(context);
-
+
CGContextRestoreGState(context);
}
@@ -375,7 +375,7 @@ void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points
if (antialiased != shouldAntialias())
CGContextSetShouldAntialias(context, antialiased);
-
+
CGContextBeginPath(context);
CGContextMoveToPoint(context, points[0].x(), points[0].y());
for (size_t i = 1; i < npoints; i++)
@@ -383,7 +383,7 @@ void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points
CGContextClosePath(context);
drawPath();
-
+
if (antialiased != shouldAntialias())
CGContextSetShouldAntialias(context, shouldAntialias());
}
@@ -391,35 +391,31 @@ void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points
void GraphicsContext::applyStrokePattern()
{
CGContextRef cgContext = platformContext();
-
- CGPatternRef platformPattern = m_common->state.strokePattern.get()->createPlatformPattern(getCTM());
+
+ RetainPtr<CGPatternRef> platformPattern(AdoptCF, m_common->state.strokePattern.get()->createPlatformPattern(getCTM()));
if (!platformPattern)
return;
- CGColorSpaceRef patternSpace = CGColorSpaceCreatePattern(0);
- CGContextSetStrokeColorSpace(cgContext, patternSpace);
- CGColorSpaceRelease(patternSpace);
+ RetainPtr<CGColorSpaceRef> patternSpace(AdoptCF, CGColorSpaceCreatePattern(0));
+ CGContextSetStrokeColorSpace(cgContext, patternSpace.get());
const CGFloat patternAlpha = 1;
- CGContextSetStrokePattern(cgContext, platformPattern, &patternAlpha);
- CGPatternRelease(platformPattern);
+ CGContextSetStrokePattern(cgContext, platformPattern.get(), &patternAlpha);
}
void GraphicsContext::applyFillPattern()
{
CGContextRef cgContext = platformContext();
- CGPatternRef platformPattern = m_common->state.fillPattern.get()->createPlatformPattern(getCTM());
+ RetainPtr<CGPatternRef> platformPattern(AdoptCF, m_common->state.fillPattern.get()->createPlatformPattern(getCTM()));
if (!platformPattern)
return;
- CGColorSpaceRef patternSpace = CGColorSpaceCreatePattern(0);
- CGContextSetFillColorSpace(cgContext, patternSpace);
- CGColorSpaceRelease(patternSpace);
+ RetainPtr<CGColorSpaceRef> patternSpace(AdoptCF, CGColorSpaceCreatePattern(0));
+ CGContextSetFillColorSpace(cgContext, patternSpace.get());
const CGFloat patternAlpha = 1;
- CGContextSetFillPattern(cgContext, platformPattern, &patternAlpha);
- CGPatternRelease(platformPattern);
+ CGContextSetFillPattern(cgContext, platformPattern.get(), &patternAlpha);
}
static inline bool calculateDrawingMode(const GraphicsContextState& state, CGPathDrawingMode& mode)
@@ -463,7 +459,7 @@ void GraphicsContext::drawPath()
strokePath();
return;
}
-
+
if (state.fillColorSpace == PatternColorSpace)
applyFillPattern();
if (state.strokeColorSpace == PatternColorSpace)
@@ -599,7 +595,7 @@ void GraphicsContext::clipOut(const IntRect& rect)
{
if (paintingDisabled())
return;
-
+
CGRect rects[2] = { CGContextGetClipBoundingBox(platformContext()), rect };
CGContextBeginPath(platformContext());
CGContextAddRects(platformContext(), rects, 2);
@@ -610,7 +606,7 @@ void GraphicsContext::clipOutEllipseInRect(const IntRect& rect)
{
if (paintingDisabled())
return;
-
+
CGContextBeginPath(platformContext());
CGContextAddRect(platformContext(), CGContextGetClipBoundingBox(platformContext()));
CGContextAddEllipseInRect(platformContext(), rect);
@@ -639,13 +635,13 @@ void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness
clip(rect);
CGContextRef context = platformContext();
-
+
// Add outer ellipse
CGContextAddEllipseInRect(context, CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()));
// Add inner ellipse.
CGContextAddEllipseInRect(context, CGRectMake(rect.x() + thickness, rect.y() + thickness,
rect.width() - (thickness * 2), rect.height() - (thickness * 2)));
-
+
CGContextEOClip(context);
}
@@ -653,7 +649,7 @@ void GraphicsContext::clipToImageBuffer(const FloatRect& rect, const ImageBuffer
{
if (paintingDisabled())
return;
-
+
CGContextTranslateCTM(platformContext(), rect.x(), rect.y() + rect.height());
CGContextScaleCTM(platformContext(), 1, -1);
CGContextClipToMask(platformContext(), FloatRect(FloatPoint(), rect.size()), imageBuffer->image()->getCGImageRef());
@@ -731,12 +727,11 @@ void GraphicsContext::setPlatformShadow(const IntSize& size, int blur, const Col
if (!color.isValid())
CGContextSetShadow(context, CGSizeMake(width, height), blurRadius);
else {
- CGColorRef colorCG = createCGColor(color);
+ RetainPtr<CGColorRef> colorCG(AdoptCF, createCGColor(color));
CGContextSetShadowWithColor(context,
CGSizeMake(width, height),
- blurRadius,
- colorCG);
- CGColorRelease(colorCG);
+ blurRadius,
+ colorCG.get());
}
}
@@ -799,15 +794,15 @@ void GraphicsContext::setLineCap(LineCap cap)
if (paintingDisabled())
return;
switch (cap) {
- case ButtCap:
- CGContextSetLineCap(platformContext(), kCGLineCapButt);
- break;
- case RoundCap:
- CGContextSetLineCap(platformContext(), kCGLineCapRound);
- break;
- case SquareCap:
- CGContextSetLineCap(platformContext(), kCGLineCapSquare);
- break;
+ case ButtCap:
+ CGContextSetLineCap(platformContext(), kCGLineCapButt);
+ break;
+ case RoundCap:
+ CGContextSetLineCap(platformContext(), kCGLineCapRound);
+ break;
+ case SquareCap:
+ CGContextSetLineCap(platformContext(), kCGLineCapSquare);
+ break;
}
}
@@ -821,15 +816,15 @@ void GraphicsContext::setLineJoin(LineJoin join)
if (paintingDisabled())
return;
switch (join) {
- case MiterJoin:
- CGContextSetLineJoin(platformContext(), kCGLineJoinMiter);
- break;
- case RoundJoin:
- CGContextSetLineJoin(platformContext(), kCGLineJoinRound);
- break;
- case BevelJoin:
- CGContextSetLineJoin(platformContext(), kCGLineJoinBevel);
- break;
+ case MiterJoin:
+ CGContextSetLineJoin(platformContext(), kCGLineJoinMiter);
+ break;
+ case RoundJoin:
+ CGContextSetLineJoin(platformContext(), kCGLineJoinRound);
+ break;
+ case BevelJoin:
+ CGContextSetLineJoin(platformContext(), kCGLineJoinBevel);
+ break;
}
}
@@ -858,7 +853,7 @@ void GraphicsContext::clipOut(const Path& path)
{
if (paintingDisabled())
return;
-
+
CGContextBeginPath(platformContext());
CGContextAddRect(platformContext(), CGContextGetClipBoundingBox(platformContext()));
CGContextAddPath(platformContext(), path.platformPath());
@@ -909,9 +904,9 @@ TransformationMatrix GraphicsContext::getCTM() const
FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect)
{
- // It is not enough just to round to pixels in device space. The rotation part of the
+ // 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
+ // rotating image like the hands of the world clock widget. We just need the scale, so
// we get the affine transform matrix and extract the scale.
if (m_data->m_userToDeviceTransformKnownToBeIdentity)
@@ -934,11 +929,11 @@ FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect)
deviceOrigin.y = roundf(deviceOrigin.y);
deviceLowerRight.x = roundf(deviceLowerRight.x);
deviceLowerRight.y = roundf(deviceLowerRight.y);
-
+
// Don't let the height or width round to 0 unless either was originally 0
- if (deviceOrigin.y == deviceLowerRight.y && rect.height() != 0)
+ if (deviceOrigin.y == deviceLowerRight.y && rect.height())
deviceLowerRight.y += 1;
- if (deviceOrigin.x == deviceLowerRight.x && rect.width() != 0)
+ if (deviceOrigin.x == deviceLowerRight.x && rect.width())
deviceLowerRight.x += 1;
FloatPoint roundedOrigin = FloatPoint(deviceOrigin.x / deviceScaleX, deviceOrigin.y / deviceScaleY);
@@ -984,13 +979,13 @@ void GraphicsContext::drawLineForText(const IntPoint& point, int width, bool pri
}
}
}
-
+
if (fillColor() != strokeColor())
setCGFillColor(platformContext(), strokeColor());
CGContextFillRect(platformContext(), CGRectMake(x, y, lineLength, thickness));
if (fillColor() != strokeColor())
setCGFillColor(platformContext(), fillColor());
-
+
if (restoreAntialiasMode)
CGContextSetShouldAntialias(platformContext(), true);
}
@@ -999,51 +994,50 @@ void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect)
{
if (paintingDisabled())
return;
-
- CFURLRef urlRef = link.createCFURL();
- if (urlRef) {
- CGContextRef context = platformContext();
-
- // Get the bounding box to handle clipping.
- CGRect box = CGContextGetClipBoundingBox(context);
-
- IntRect intBox((int)box.origin.x, (int)box.origin.y, (int)box.size.width, (int)box.size.height);
- IntRect rect = destRect;
- rect.intersect(intBox);
-
- CGPDFContextSetURLForRect(context, urlRef,
- CGRectApplyAffineTransform(rect, CGContextGetCTM(context)));
-
- CFRelease(urlRef);
- }
+
+ RetainPtr<CFURLRef> urlRef(AdoptCF, link.createCFURL());
+ if (!urlRef)
+ return;
+
+ CGContextRef context = platformContext();
+
+ // Get the bounding box to handle clipping.
+ CGRect box = CGContextGetClipBoundingBox(context);
+
+ IntRect intBox((int)box.origin.x, (int)box.origin.y, (int)box.size.width, (int)box.size.height);
+ IntRect rect = destRect;
+ rect.intersect(intBox);
+
+ CGPDFContextSetURLForRect(context, urlRef.get(),
+ CGRectApplyAffineTransform(rect, CGContextGetCTM(context)));
}
void GraphicsContext::setImageInterpolationQuality(InterpolationQuality mode)
{
if (paintingDisabled())
return;
-
+
CGInterpolationQuality quality = kCGInterpolationDefault;
switch (mode) {
- case InterpolationDefault:
- quality = kCGInterpolationDefault;
- break;
- case InterpolationNone:
- quality = kCGInterpolationNone;
- break;
- case InterpolationLow:
- quality = kCGInterpolationLow;
- break;
-
- // Fall through to InterpolationHigh if kCGInterpolationMedium is not available
- case InterpolationMedium:
+ case InterpolationDefault:
+ quality = kCGInterpolationDefault;
+ break;
+ case InterpolationNone:
+ quality = kCGInterpolationNone;
+ break;
+ case InterpolationLow:
+ quality = kCGInterpolationLow;
+ break;
+
+ // Fall through to InterpolationHigh if kCGInterpolationMedium is not available
+ case InterpolationMedium:
#if HAVE(CG_INTERPOLATION_MEDIUM)
- quality = kCGInterpolationMedium;
- break;
+ quality = kCGInterpolationMedium;
+ break;
#endif
- case InterpolationHigh:
- quality = kCGInterpolationHigh;
- break;
+ case InterpolationHigh:
+ quality = kCGInterpolationHigh;
+ break;
}
CGContextSetInterpolationQuality(platformContext(), quality);
}
@@ -1055,18 +1049,18 @@ InterpolationQuality GraphicsContext::imageInterpolationQuality() const
CGInterpolationQuality quality = CGContextGetInterpolationQuality(platformContext());
switch (quality) {
- case kCGInterpolationDefault:
- return InterpolationDefault;
- case kCGInterpolationNone:
- return InterpolationNone;
- case kCGInterpolationLow:
- return InterpolationLow;
+ case kCGInterpolationDefault:
+ return InterpolationDefault;
+ case kCGInterpolationNone:
+ return InterpolationNone;
+ case kCGInterpolationLow:
+ return InterpolationLow;
#if HAVE(CG_INTERPOLATION_MEDIUM)
- case kCGInterpolationMedium:
- return InterpolationMedium;
+ case kCGInterpolationMedium:
+ return InterpolationMedium;
#endif
- case kCGInterpolationHigh:
- return InterpolationHigh;
+ case kCGInterpolationHigh:
+ return InterpolationHigh;
}
return InterpolationDefault;
}
@@ -1079,32 +1073,32 @@ void GraphicsContext::setPlatformTextDrawingMode(int mode)
// Wow, wish CG had used bits here.
CGContextRef context = platformContext();
switch (mode) {
- case cTextInvisible: // Invisible
- CGContextSetTextDrawingMode(context, kCGTextInvisible);
- break;
- case cTextFill: // Fill
- CGContextSetTextDrawingMode(context, kCGTextFill);
- break;
- case cTextStroke: // Stroke
- CGContextSetTextDrawingMode(context, kCGTextStroke);
- break;
- case 3: // Fill | Stroke
- CGContextSetTextDrawingMode(context, kCGTextFillStroke);
- break;
- case cTextClip: // Clip
- CGContextSetTextDrawingMode(context, kCGTextClip);
- break;
- case 5: // Fill | Clip
- CGContextSetTextDrawingMode(context, kCGTextFillClip);
- break;
- case 6: // Stroke | Clip
- CGContextSetTextDrawingMode(context, kCGTextStrokeClip);
- break;
- case 7: // Fill | Stroke | Clip
- CGContextSetTextDrawingMode(context, kCGTextFillStrokeClip);
- break;
- default:
- break;
+ case cTextInvisible: // Invisible
+ CGContextSetTextDrawingMode(context, kCGTextInvisible);
+ break;
+ case cTextFill: // Fill
+ CGContextSetTextDrawingMode(context, kCGTextFill);
+ break;
+ case cTextStroke: // Stroke
+ CGContextSetTextDrawingMode(context, kCGTextStroke);
+ break;
+ case 3: // Fill | Stroke
+ CGContextSetTextDrawingMode(context, kCGTextFillStroke);
+ break;
+ case cTextClip: // Clip
+ CGContextSetTextDrawingMode(context, kCGTextClip);
+ break;
+ case 5: // Fill | Clip
+ CGContextSetTextDrawingMode(context, kCGTextFillClip);
+ break;
+ case 6: // Stroke | Clip
+ CGContextSetTextDrawingMode(context, kCGTextStrokeClip);
+ break;
+ case 7: // Fill | Stroke | Clip
+ CGContextSetTextDrawingMode(context, kCGTextFillStrokeClip);
+ break;
+ default:
+ break;
}
}
@@ -1138,54 +1132,54 @@ void GraphicsContext::setPlatformShouldAntialias(bool enable)
#ifndef BUILDING_ON_TIGER // Tiger's setCompositeOperation() is defined in GraphicsContextMac.mm.
void GraphicsContext::setCompositeOperation(CompositeOperator mode)
-{
+{
if (paintingDisabled())
return;
- CGBlendMode target = kCGBlendModeNormal;
+ CGBlendMode target = kCGBlendModeNormal;
switch (mode) {
- case CompositeClear:
- target = kCGBlendModeClear;
- break;
- case CompositeCopy:
- target = kCGBlendModeCopy;
- break;
- case CompositeSourceOver:
- //kCGBlendModeNormal
- break;
- case CompositeSourceIn:
- target = kCGBlendModeSourceIn;
- break;
- case CompositeSourceOut:
- target = kCGBlendModeSourceOut;
- break;
- case CompositeSourceAtop:
- target = kCGBlendModeSourceAtop;
- break;
- case CompositeDestinationOver:
- target = kCGBlendModeDestinationOver;
- break;
- case CompositeDestinationIn:
- target = kCGBlendModeDestinationIn;
- break;
- case CompositeDestinationOut:
- target = kCGBlendModeDestinationOut;
- break;
- case CompositeDestinationAtop:
- target = kCGBlendModeDestinationAtop;
- break;
- case CompositeXOR:
- target = kCGBlendModeXOR;
- break;
- case CompositePlusDarker:
- target = kCGBlendModePlusDarker;
- break;
- case CompositeHighlight:
- // currently unsupported
- break;
- case CompositePlusLighter:
- target = kCGBlendModePlusLighter;
- break;
+ case CompositeClear:
+ target = kCGBlendModeClear;
+ break;
+ case CompositeCopy:
+ target = kCGBlendModeCopy;
+ break;
+ case CompositeSourceOver:
+ //kCGBlendModeNormal
+ break;
+ case CompositeSourceIn:
+ target = kCGBlendModeSourceIn;
+ break;
+ case CompositeSourceOut:
+ target = kCGBlendModeSourceOut;
+ break;
+ case CompositeSourceAtop:
+ target = kCGBlendModeSourceAtop;
+ break;
+ case CompositeDestinationOver:
+ target = kCGBlendModeDestinationOver;
+ break;
+ case CompositeDestinationIn:
+ target = kCGBlendModeDestinationIn;
+ break;
+ case CompositeDestinationOut:
+ target = kCGBlendModeDestinationOut;
+ break;
+ case CompositeDestinationAtop:
+ target = kCGBlendModeDestinationAtop;
+ break;
+ case CompositeXOR:
+ target = kCGBlendModeXOR;
+ break;
+ case CompositePlusDarker:
+ target = kCGBlendModePlusDarker;
+ break;
+ case CompositeHighlight:
+ // currently unsupported
+ break;
+ case CompositePlusLighter:
+ target = kCGBlendModePlusLighter;
+ break;
}
CGContextSetBlendMode(platformContext(), target);
}
diff --git a/WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h b/WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h
index f63a8dd..38c5506 100644
--- a/WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h
+++ b/WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h
@@ -38,12 +38,10 @@ public:
#endif
, m_userToDeviceTransformKnownToBeIdentity(false)
{
- CGContextRetain(m_cgContext);
}
~GraphicsContextPlatformPrivate()
{
- CGContextRelease(m_cgContext);
}
#if PLATFORM(MAC) || PLATFORM(CHROMIUM)
@@ -80,7 +78,7 @@ public:
bool m_shouldIncludeChildWindows;
#endif
- CGContextRef m_cgContext;
+ RetainPtr<CGContextRef> m_cgContext;
bool m_userToDeviceTransformKnownToBeIdentity;
};
diff --git a/WebCore/platform/graphics/cg/ImageBufferCG.cpp b/WebCore/platform/graphics/cg/ImageBufferCG.cpp
index 6db7e88..b1896f8 100644
--- a/WebCore/platform/graphics/cg/ImageBufferCG.cpp
+++ b/WebCore/platform/graphics/cg/ImageBufferCG.cpp
@@ -65,37 +65,37 @@ ImageBuffer::ImageBuffer(const IntSize& size, ImageColorSpace imageColorSpace, b
bytesPerRow *= 4;
}
- m_data.m_data = tryFastCalloc(size.height(), bytesPerRow);
+ if (!tryFastCalloc(size.height(), bytesPerRow).getValue(m_data.m_data))
+ return;
+
ASSERT((reinterpret_cast<size_t>(m_data.m_data) & 2) == 0);
- CGColorSpaceRef colorSpace;
+ RetainPtr<CGColorSpaceRef> colorSpace;
switch(imageColorSpace) {
case DeviceRGB:
- colorSpace = CGColorSpaceCreateDeviceRGB();
+ colorSpace.adoptCF(CGColorSpaceCreateDeviceRGB());
break;
case GrayScale:
- colorSpace = CGColorSpaceCreateDeviceGray();
+ colorSpace.adoptCF(CGColorSpaceCreateDeviceGray());
break;
#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER)
case LinearRGB:
- colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGBLinear);
+ colorSpace.adoptCF(CGColorSpaceCreateWithName(kCGColorSpaceGenericRGBLinear));
break;
#endif
default:
- colorSpace = CGColorSpaceCreateDeviceRGB();
+ colorSpace.adoptCF(CGColorSpaceCreateDeviceRGB());
break;
}
- CGContextRef cgContext = CGBitmapContextCreate(m_data.m_data, size.width(), size.height(), 8, bytesPerRow,
- colorSpace, (imageColorSpace == GrayScale) ? kCGImageAlphaNone : kCGImageAlphaPremultipliedLast);
- CGColorSpaceRelease(colorSpace);
+ RetainPtr<CGContextRef> cgContext(AdoptCF, CGBitmapContextCreate(m_data.m_data, size.width(), size.height(), 8, bytesPerRow,
+ colorSpace.get(), (imageColorSpace == GrayScale) ? kCGImageAlphaNone : kCGImageAlphaPremultipliedLast));
if (!cgContext)
return;
- m_context.set(new GraphicsContext(cgContext));
+ m_context.set(new GraphicsContext(cgContext.get()));
m_context->scale(FloatSize(1, -1));
m_context->translate(0, -size.height());
- CGContextRelease(cgContext);
success = true;
}
@@ -122,12 +122,13 @@ Image* ImageBuffer::image() const
return m_image.get();
}
-PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const
+template <Multiply multiplied>
+PassRefPtr<ImageData> getImageData(const IntRect& rect, const ImageBufferData& imageData, const IntSize& size)
{
PassRefPtr<ImageData> result = ImageData::create(rect.width(), rect.height());
unsigned char* data = result->data()->data()->data();
- if (rect.x() < 0 || rect.y() < 0 || (rect.x() + rect.width()) > m_size.width() || (rect.y() + rect.height()) > m_size.height())
+ if (rect.x() < 0 || rect.y() < 0 || (rect.x() + rect.width()) > size.width() || (rect.y() + rect.height()) > size.height())
memset(data, 0, result->data()->length());
int originx = rect.x();
@@ -137,8 +138,8 @@ PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const
originx = 0;
}
int endx = rect.x() + rect.width();
- if (endx > m_size.width())
- endx = m_size.width();
+ if (endx > size.width())
+ endx = size.width();
int numColumns = endx - originx;
int originy = rect.y();
@@ -148,20 +149,21 @@ PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const
originy = 0;
}
int endy = rect.y() + rect.height();
- if (endy > m_size.height())
- endy = m_size.height();
+ if (endy > size.height())
+ endy = size.height();
int numRows = endy - originy;
- unsigned srcBytesPerRow = 4 * m_size.width();
+ unsigned srcBytesPerRow = 4 * size.width();
unsigned destBytesPerRow = 4 * rect.width();
// ::create ensures that all ImageBuffers have valid data, so we don't need to check it here.
- unsigned char* srcRows = reinterpret_cast<unsigned char*>(m_data.m_data) + originy * srcBytesPerRow + originx * 4;
+ unsigned char* srcRows = reinterpret_cast<unsigned char*>(imageData.m_data) + originy * srcBytesPerRow + originx * 4;
unsigned char* destRows = data + desty * destBytesPerRow + destx * 4;
for (int y = 0; y < numRows; ++y) {
for (int x = 0; x < numColumns; x++) {
int basex = x * 4;
- if (unsigned char alpha = srcRows[basex + 3]) {
+ 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;
@@ -175,7 +177,18 @@ PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const
return result;
}
-void ImageBuffer::putImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint)
+PassRefPtr<ImageData> ImageBuffer::getUnmultipliedImageData(const IntRect& rect) const
+{
+ return getImageData<Unmultiplied>(rect, m_data, m_size);
+}
+
+PassRefPtr<ImageData> ImageBuffer::getPremultipliedImageData(const IntRect& rect) const
+{
+ return getImageData<Premultiplied>(rect, m_data, m_size);
+}
+
+template <Multiply multiplied>
+void putImageData(ImageData*& source, const IntRect& sourceRect, const IntPoint& destPoint, ImageBufferData& imageData, const IntSize& size)
{
ASSERT(sourceRect.width() > 0);
ASSERT(sourceRect.height() > 0);
@@ -183,36 +196,36 @@ void ImageBuffer::putImageData(ImageData* source, const IntRect& sourceRect, con
int originx = sourceRect.x();
int destx = destPoint.x() + sourceRect.x();
ASSERT(destx >= 0);
- ASSERT(destx < m_size.width());
+ ASSERT(destx < size.width());
ASSERT(originx >= 0);
ASSERT(originx <= sourceRect.right());
int endx = destPoint.x() + sourceRect.right();
- ASSERT(endx <= m_size.width());
+ ASSERT(endx <= size.width());
int numColumns = endx - destx;
int originy = sourceRect.y();
int desty = destPoint.y() + sourceRect.y();
ASSERT(desty >= 0);
- ASSERT(desty < m_size.height());
+ ASSERT(desty < size.height());
ASSERT(originy >= 0);
ASSERT(originy <= sourceRect.bottom());
int endy = destPoint.y() + sourceRect.bottom();
- ASSERT(endy <= m_size.height());
+ ASSERT(endy <= size.height());
int numRows = endy - desty;
unsigned srcBytesPerRow = 4 * source->width();
- unsigned destBytesPerRow = 4 * m_size.width();
+ unsigned destBytesPerRow = 4 * size.width();
unsigned char* srcRows = source->data()->data()->data() + originy * srcBytesPerRow + originx * 4;
- unsigned char* destRows = reinterpret_cast<unsigned char*>(m_data.m_data) + desty * destBytesPerRow + destx * 4;
+ unsigned char* 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 (alpha != 255) {
+ 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;
@@ -225,6 +238,16 @@ void ImageBuffer::putImageData(ImageData* source, const IntRect& sourceRect, con
}
}
+void ImageBuffer::putUnmultipliedImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint)
+{
+ putImageData<Unmultiplied>(source, sourceRect, destPoint, m_data, m_size);
+}
+
+void ImageBuffer::putPremultipliedImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint)
+{
+ putImageData<Premultiplied>(source, sourceRect, destPoint, m_data, m_size);
+}
+
static RetainPtr<CFStringRef> utiFromMIMEType(const String& mimeType)
{
#if PLATFORM(MAC)
diff --git a/WebCore/platform/graphics/cg/ImageCG.cpp b/WebCore/platform/graphics/cg/ImageCG.cpp
index a5620e8..4da7018 100644
--- a/WebCore/platform/graphics/cg/ImageCG.cpp
+++ b/WebCore/platform/graphics/cg/ImageCG.cpp
@@ -101,30 +101,29 @@ BitmapImage::BitmapImage(CGImageRef cgImage, ImageObserver* observer)
void BitmapImage::checkForSolidColor()
{
m_checkedForSolidColor = true;
- if (frameCount() > 1)
+ if (frameCount() > 1) {
m_isSolidColor = false;
- else {
- CGImageRef image = frameAtIndex(0);
-
- // Currently we only check for solid color in the important special case of a 1x1 image.
- if (image && CGImageGetWidth(image) == 1 && CGImageGetHeight(image) == 1) {
- unsigned char pixel[4]; // RGBA
- CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
- CGContextRef bmap = CGBitmapContextCreate(pixel, 1, 1, 8, sizeof(pixel), space,
- kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
- if (bmap) {
- GraphicsContext(bmap).setCompositeOperation(CompositeCopy);
- CGRect dst = { {0, 0}, {1, 1} };
- CGContextDrawImage(bmap, dst, image);
- if (pixel[3] == 0)
- m_solidColor = Color(0, 0, 0, 0);
- else
- m_solidColor = Color(pixel[0] * 255 / pixel[3], pixel[1] * 255 / pixel[3], pixel[2] * 255 / pixel[3], pixel[3]);
- m_isSolidColor = true;
- CFRelease(bmap);
- }
- CFRelease(space);
- }
+ return;
+ }
+
+ CGImageRef image = frameAtIndex(0);
+
+ // Currently we only check for solid color in the important special case of a 1x1 image.
+ if (image && CGImageGetWidth(image) == 1 && CGImageGetHeight(image) == 1) {
+ unsigned char pixel[4]; // RGBA
+ static CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
+ RetainPtr<CGContextRef> bmap(AdoptCF, CGBitmapContextCreate(pixel, 1, 1, 8, sizeof(pixel), space,
+ kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big));
+ if (!bmap)
+ return;
+ GraphicsContext(bmap.get()).setCompositeOperation(CompositeCopy);
+ CGRect dst = { {0, 0}, {1, 1} };
+ CGContextDrawImage(bmap.get(), dst, image);
+ if (pixel[3] == 0)
+ m_solidColor = Color(0, 0, 0, 0);
+ else
+ m_solidColor = Color(pixel[0] * 255 / pixel[3], pixel[1] * 255 / pixel[3], pixel[2] * 255 / pixel[3], pixel[3]);
+ m_isSolidColor = true;
}
}
@@ -252,14 +251,14 @@ void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const
CGImageRef tileImage = nativeImageForCurrentFrame();
float h = CGImageGetHeight(tileImage);
- CGImageRef subImage;
+ RetainPtr<CGImageRef> subImage;
if (tileRect.size() == size())
subImage = tileImage;
else {
// Copying a sub-image out of a partially-decoded image stops the decoding of the original image. It should never happen
// because sub-images are only used for border-image, which only renders when the image is fully decoded.
ASSERT(h == height());
- subImage = CGImageCreateWithImageInRect(tileImage, tileRect);
+ subImage.adoptCF(CGImageCreateWithImageInRect(tileImage, tileRect));
}
#ifndef BUILDING_ON_TIGER
@@ -275,7 +274,7 @@ void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const
#else
if (w == size().width() && h == size().height())
#endif
- CGContextDrawTiledImage(context, FloatRect(adjustedX, adjustedY, scaledTileWidth, scaledTileHeight), subImage);
+ CGContextDrawTiledImage(context, FloatRect(adjustedX, adjustedY, scaledTileWidth, scaledTileHeight), subImage.get());
else {
#endif
@@ -288,39 +287,31 @@ void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const
matrix = CGAffineTransformConcat(matrix, CGContextGetCTM(context));
// The top of a partially-decoded image is drawn at the bottom of the tile. Map it to the top.
matrix = CGAffineTransformTranslate(matrix, 0, size().height() - h);
- CGPatternRef pattern = CGPatternCreate(subImage, CGRectMake(0, 0, tileRect.width(), tileRect.height()),
- matrix, tileRect.width(), tileRect.height(),
- kCGPatternTilingConstantSpacing, true, &patternCallbacks);
- if (pattern == NULL) {
- if (subImage != tileImage)
- CGImageRelease(subImage);
+ RetainPtr<CGPatternRef> pattern(AdoptCF, CGPatternCreate(subImage.get(), CGRectMake(0, 0, tileRect.width(), tileRect.height()),
+ matrix, tileRect.width(), tileRect.height(),
+ kCGPatternTilingConstantSpacing, true, &patternCallbacks));
+ if (!pattern) {
ctxt->restore();
return;
}
- CGColorSpaceRef patternSpace = CGColorSpaceCreatePattern(NULL);
+ RetainPtr<CGColorSpaceRef> patternSpace(AdoptCF, CGColorSpaceCreatePattern(0));
CGFloat alpha = 1;
- CGColorRef color = CGColorCreateWithPattern(patternSpace, pattern, &alpha);
- CGContextSetFillColorSpace(context, patternSpace);
- CGColorSpaceRelease(patternSpace);
- CGPatternRelease(pattern);
+ RetainPtr<CGColorRef> color(AdoptCF, CGColorCreateWithPattern(patternSpace.get(), pattern.get(), &alpha));
+ CGContextSetFillColorSpace(context, patternSpace.get());
// FIXME: Really want a public API for this. It is just CGContextSetBaseCTM(context, CGAffineTransformIdentiy).
wkSetPatternBaseCTM(context, CGAffineTransformIdentity);
CGContextSetPatternPhase(context, CGSizeZero);
- CGContextSetFillColorWithColor(context, color);
+ CGContextSetFillColorWithColor(context, color.get());
CGContextFillRect(context, CGContextGetClipBoundingBox(context));
-
- CGColorRelease(color);
-
+
#ifndef BUILDING_ON_TIGER
}
#endif
- if (subImage != tileImage)
- CGImageRelease(subImage);
ctxt->restore();
if (imageObserver())
diff --git a/WebCore/platform/graphics/cg/ImageSourceCG.cpp b/WebCore/platform/graphics/cg/ImageSourceCG.cpp
index b716060..66246fe 100644
--- a/WebCore/platform/graphics/cg/ImageSourceCG.cpp
+++ b/WebCore/platform/graphics/cg/ImageSourceCG.cpp
@@ -109,18 +109,16 @@ void ImageSource::setData(SharedBuffer* data, bool allDataReceived)
#if PLATFORM(MAC)
// On Mac the NSData inside the SharedBuffer can be secretly appended to without the SharedBuffer's knowledge. We use SharedBuffer's ability
// to wrap itself inside CFData to get around this, ensuring that ImageIO is really looking at the SharedBuffer.
- CFDataRef cfData = data->createCFData();
+ RetainPtr<CFDataRef> cfData(AdoptCF, data->createCFData());
#else
// If no NSData is available, then we know SharedBuffer will always just be a vector. That means no secret changes can occur to it behind the
// scenes. We use CFDataCreateWithBytesNoCopy in that case. Ensure that the SharedBuffer lives as long as the CFDataRef.
data->ref();
CFAllocatorContext context = {0, data, 0, 0, 0, 0, 0, &sharedBufferDerefCallback, 0};
- CFAllocatorRef derefAllocator = CFAllocatorCreate(kCFAllocatorDefault, &context);
- CFDataRef cfData = CFDataCreateWithBytesNoCopy(0, reinterpret_cast<const UInt8*>(data->data()), data->size(), derefAllocator);
- CFRelease(derefAllocator);
+ RetainPtr<CFAllocatorRef> derefAllocator(AdoptCF, CFAllocatorCreate(kCFAllocatorDefault, &context));
+ RetainPtr<CFDataRef> cfData(AdoptCF, CFDataCreateWithBytesNoCopy(0, reinterpret_cast<const UInt8*>(data->data()), data->size(), derefAllocator.get()));
#endif
- CGImageSourceUpdateData(m_decoder, cfData, allDataReceived);
- CFRelease(cfData);
+ CGImageSourceUpdateData(m_decoder, cfData.get(), allDataReceived);
}
String ImageSource::filenameExtension() const
@@ -138,12 +136,11 @@ bool ImageSource::isSizeAvailable()
// Ragnaros yells: TOO SOON! You have awakened me TOO SOON, Executus!
if (imageSourceStatus >= kCGImageStatusIncomplete) {
- CFDictionaryRef image0Properties = CGImageSourceCopyPropertiesAtIndex(m_decoder, 0, imageSourceOptions());
+ RetainPtr<CFDictionaryRef> image0Properties(AdoptCF, CGImageSourceCopyPropertiesAtIndex(m_decoder, 0, imageSourceOptions()));
if (image0Properties) {
- CFNumberRef widthNumber = (CFNumberRef)CFDictionaryGetValue(image0Properties, kCGImagePropertyPixelWidth);
- CFNumberRef heightNumber = (CFNumberRef)CFDictionaryGetValue(image0Properties, kCGImagePropertyPixelHeight);
+ CFNumberRef widthNumber = (CFNumberRef)CFDictionaryGetValue(image0Properties.get(), kCGImagePropertyPixelWidth);
+ CFNumberRef heightNumber = (CFNumberRef)CFDictionaryGetValue(image0Properties.get(), kCGImagePropertyPixelHeight);
result = widthNumber && heightNumber;
- CFRelease(image0Properties);
}
}
@@ -153,17 +150,16 @@ bool ImageSource::isSizeAvailable()
IntSize ImageSource::frameSizeAtIndex(size_t index) const
{
IntSize result;
- CFDictionaryRef properties = CGImageSourceCopyPropertiesAtIndex(m_decoder, index, imageSourceOptions());
+ RetainPtr<CFDictionaryRef> properties(AdoptCF, CGImageSourceCopyPropertiesAtIndex(m_decoder, index, imageSourceOptions()));
if (properties) {
int w = 0, h = 0;
- CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(properties, kCGImagePropertyPixelWidth);
+ CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyPixelWidth);
if (num)
CFNumberGetValue(num, kCFNumberIntType, &w);
- num = (CFNumberRef)CFDictionaryGetValue(properties, kCGImagePropertyPixelHeight);
+ num = (CFNumberRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyPixelHeight);
if (num)
CFNumberGetValue(num, kCFNumberIntType, &h);
result = IntSize(w, h);
- CFRelease(properties);
}
return result;
}
@@ -180,17 +176,15 @@ int ImageSource::repetitionCount()
return result;
// A property with value 0 means loop forever.
- CFDictionaryRef properties = CGImageSourceCopyProperties(m_decoder, imageSourceOptions());
+ RetainPtr<CFDictionaryRef> properties(AdoptCF, CGImageSourceCopyProperties(m_decoder, imageSourceOptions()));
if (properties) {
- CFDictionaryRef gifProperties = (CFDictionaryRef)CFDictionaryGetValue(properties, kCGImagePropertyGIFDictionary);
+ CFDictionaryRef gifProperties = (CFDictionaryRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyGIFDictionary);
if (gifProperties) {
CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(gifProperties, kCGImagePropertyGIFLoopCount);
if (num)
CFNumberGetValue(num, kCFNumberIntType, &result);
} else
result = cAnimationNone; // Turns out we're not a GIF after all, so we don't animate.
-
- CFRelease(properties);
}
return result;
@@ -206,20 +200,19 @@ CGImageRef ImageSource::createFrameAtIndex(size_t index)
if (!initialized())
return 0;
- CGImageRef image = CGImageSourceCreateImageAtIndex(m_decoder, index, imageSourceOptions());
+ RetainPtr<CGImageRef> image(AdoptCF, CGImageSourceCreateImageAtIndex(m_decoder, index, imageSourceOptions()));
CFStringRef imageUTI = CGImageSourceGetType(m_decoder);
static const CFStringRef xbmUTI = CFSTR("public.xbitmap-image");
if (!imageUTI || !CFEqual(imageUTI, xbmUTI))
- return image;
+ return image.releaseRef();
// If it is an xbm image, mask out all the white areas to render them transparent.
const CGFloat maskingColors[6] = {255, 255, 255, 255, 255, 255};
- CGImageRef maskedImage = CGImageCreateWithMaskingColors(image, maskingColors);
+ RetainPtr<CGImageRef> maskedImage(AdoptCF, CGImageCreateWithMaskingColors(image.get(), maskingColors));
if (!maskedImage)
- return image;
-
- CGImageRelease(image);
- return maskedImage;
+ return image.releaseRef();
+
+ return maskedImage.releaseRef();
}
bool ImageSource::frameIsCompleteAtIndex(size_t index)
@@ -233,15 +226,14 @@ float ImageSource::frameDurationAtIndex(size_t index)
return 0;
float duration = 0;
- CFDictionaryRef properties = CGImageSourceCopyPropertiesAtIndex(m_decoder, index, imageSourceOptions());
+ RetainPtr<CFDictionaryRef> properties(AdoptCF, CGImageSourceCopyPropertiesAtIndex(m_decoder, index, imageSourceOptions()));
if (properties) {
- CFDictionaryRef typeProperties = (CFDictionaryRef)CFDictionaryGetValue(properties, kCGImagePropertyGIFDictionary);
+ CFDictionaryRef typeProperties = (CFDictionaryRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyGIFDictionary);
if (typeProperties) {
CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(typeProperties, kCGImagePropertyGIFDelayTime);
if (num)
CFNumberGetValue(num, kCFNumberFloatType, &duration);
}
- CFRelease(properties);
}
// Many annoying ads specify a 0 duration to make an image flash as quickly as possible.
diff --git a/WebCore/platform/graphics/cg/PDFDocumentImage.cpp b/WebCore/platform/graphics/cg/PDFDocumentImage.cpp
index 858b18e..2f5c15e 100644
--- a/WebCore/platform/graphics/cg/PDFDocumentImage.cpp
+++ b/WebCore/platform/graphics/cg/PDFDocumentImage.cpp
@@ -68,16 +68,14 @@ bool PDFDocumentImage::dataChanged(bool allDataReceived)
#if PLATFORM(MAC)
// On Mac the NSData inside the SharedBuffer can be secretly appended to without the SharedBuffer's knowledge. We use SharedBuffer's ability
// to wrap itself inside CFData to get around this, ensuring that ImageIO is really looking at the SharedBuffer.
- CFDataRef data = this->data()->createCFData();
+ RetainPtr<CFDataRef> data(AdoptCF, this->data()->createCFData());
#else
// If no NSData is available, then we know SharedBuffer will always just be a vector. That means no secret changes can occur to it behind the
// scenes. We use CFDataCreateWithBytesNoCopy in that case.
- CFDataRef data = CFDataCreateWithBytesNoCopy(0, reinterpret_cast<const UInt8*>(this->data()->data()), this->data()->size(), kCFAllocatorNull);
+ RetainPtr<CFDataRef> data(AdoptCF, CFDataCreateWithBytesNoCopy(0, reinterpret_cast<const UInt8*>(this->data()->data()), this->data()->size(), kCFAllocatorNull));
#endif
- CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData(data);
- CFRelease(data);
- m_document = CGPDFDocumentCreateWithProvider(dataProvider);
- CGDataProviderRelease(dataProvider);
+ RetainPtr<CGDataProviderRef> dataProvider(AdoptCF, CGDataProviderCreateWithCFData(data.get()));
+ m_document = CGPDFDocumentCreateWithProvider(dataProvider.get());
setCurrentPage(0);
}
return m_document; // return true if size is available
diff --git a/WebCore/platform/graphics/cg/PathCG.cpp b/WebCore/platform/graphics/cg/PathCG.cpp
index 5812cea..3b05641 100644
--- a/WebCore/platform/graphics/cg/PathCG.cpp
+++ b/WebCore/platform/graphics/cg/PathCG.cpp
@@ -49,9 +49,8 @@ static size_t putBytesNowhere(void*, const void*, size_t count)
static CGContextRef createScratchContext()
{
CGDataConsumerCallbacks callbacks = { putBytesNowhere, 0 };
- CGDataConsumerRef consumer = CGDataConsumerCreate(0, &callbacks);
- CGContextRef context = CGPDFContextCreate(consumer, 0, 0);
- CGDataConsumerRelease(consumer);
+ RetainPtr<CGDataConsumerRef> consumer(AdoptCF, CGDataConsumerCreate(0, &callbacks));
+ CGContextRef context = CGPDFContextCreate(consumer.get(), 0, 0);
CGFloat black[4] = { 0, 0, 0, 1 };
CGContextSetFillColor(context, black);
@@ -129,9 +128,8 @@ bool Path::contains(const FloatPoint &point, WindRule rule) const
return false;
// CGPathContainsPoint returns false for non-closed paths, as a work-around, we copy and close the path first. Radar 4758998 asks for a better CG API to use
- CGMutablePathRef path = copyCGPathClosingSubpaths(m_path);
- bool ret = CGPathContainsPoint(path, 0, point, rule == RULE_EVENODD ? true : false);
- CGPathRelease(path);
+ RetainPtr<CGMutablePathRef> path(AdoptCF, copyCGPathClosingSubpaths(m_path));
+ bool ret = CGPathContainsPoint(path.get(), 0, point, rule == RULE_EVENODD ? true : false);
return ret;
}
diff --git a/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp b/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp
index 9252ae0..e8fa860 100644
--- a/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp
+++ b/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp
@@ -261,7 +261,7 @@ static HFONT createFontIndirectAndGetWinName(const String& family, LOGFONT* winf
// characters. Because it's family names rather than font faces we use
// as keys, there might be edge cases where one face of a font family
// has a different repertoire from another face of the same family.
-typedef HashMap<const wchar_t*, UnicodeSet*> FontCmapCache;
+typedef HashMap<const wchar_t*, icu::UnicodeSet*> FontCmapCache;
static bool fontContainsCharacter(const FontPlatformData* fontData,
const wchar_t* family, UChar32 character)
@@ -277,7 +277,7 @@ static bool fontContainsCharacter(const FontPlatformData* fontData,
if (!fontCmapCache)
fontCmapCache = new FontCmapCache;
- HashMap<const wchar_t*, UnicodeSet*>::iterator it = fontCmapCache->find(family);
+ HashMap<const wchar_t*, icu::UnicodeSet*>::iterator it = fontCmapCache->find(family);
if (it != fontCmapCache->end())
return it->second->contains(character);
@@ -308,7 +308,7 @@ static bool fontContainsCharacter(const FontPlatformData* fontData,
// 1) port back ICU 4.0's faster look-up code for UnicodeSet
// 2) port Mozilla's CompressedCharMap or gfxSparseBitset
unsigned i = 0;
- UnicodeSet* cmap = new UnicodeSet;
+ icu::UnicodeSet* cmap = new icu::UnicodeSet;
while (i < glyphset->cRanges) {
WCHAR start = glyphset->ranges[i].wcLow;
cmap->add(start, start + glyphset->ranges[i].cGlyphs - 1);
diff --git a/WebCore/platform/graphics/chromium/FontChromiumWin.cpp b/WebCore/platform/graphics/chromium/FontChromiumWin.cpp
index 3d67992..229188e 100644
--- a/WebCore/platform/graphics/chromium/FontChromiumWin.cpp
+++ b/WebCore/platform/graphics/chromium/FontChromiumWin.cpp
@@ -459,14 +459,16 @@ void Font::drawComplexText(GraphicsContext* graphicsContext,
TransparencyAwareUniscribePainter painter(graphicsContext, this, run, from, to, point);
HDC hdc = painter.hdc();
- if (!hdc)
+ if (windowsCanHandleTextDrawing(graphicsContext) && !hdc)
return;
// TODO(maruel): http://b/700464 SetTextColor doesn't support transparency.
// Enforce non-transparent color.
color = SkColorSetRGB(SkColorGetR(color), SkColorGetG(color), SkColorGetB(color));
- SetTextColor(hdc, skia::SkColorToCOLORREF(color));
- SetBkMode(hdc, TRANSPARENT);
+ if (hdc) {
+ SetTextColor(hdc, skia::SkColorToCOLORREF(color));
+ SetBkMode(hdc, TRANSPARENT);
+ }
// If there is a non-blur shadow and both the fill color and shadow color
// are opaque, handle without skia.
diff --git a/WebCore/platform/graphics/chromium/FontLinux.cpp b/WebCore/platform/graphics/chromium/FontLinux.cpp
index d4e45fb..dca0efb 100644
--- a/WebCore/platform/graphics/chromium/FontLinux.cpp
+++ b/WebCore/platform/graphics/chromium/FontLinux.cpp
@@ -45,6 +45,11 @@
#include "SkTypeface.h"
#include "SkUtils.h"
+#include <unicode/normlzr.h>
+#include <unicode/uchar.h>
+#include <wtf/OwnArrayPtr.h>
+#include <wtf/OwnPtr.h>
+
namespace WebCore {
bool Font::canReturnFallbackFontsForComplexText()
@@ -136,27 +141,29 @@ class TextRunWalker {
public:
TextRunWalker(const TextRun& run, unsigned startingX, const Font* font)
: m_font(font)
- , m_run(run)
, m_startingX(startingX)
, m_offsetX(m_startingX)
- , m_iterateBackwards(run.rtl())
+ , m_run(getTextRun(run))
+ , m_iterateBackwards(m_run.rtl())
{
+ // Do not use |run| inside this constructor. Use |m_run| instead.
+
memset(&m_item, 0, sizeof(m_item));
// We cannot know, ahead of time, how many glyphs a given script run
// will produce. We take a guess that script runs will not produce more
// than twice as many glyphs as there are code points and fallback if
// we find that we are wrong.
- m_maxGlyphs = run.length() * 2;
+ m_maxGlyphs = m_run.length() * 2;
createGlyphArrays();
- m_item.log_clusters = new unsigned short[run.length()];
+ m_item.log_clusters = new unsigned short[m_run.length()];
m_item.face = 0;
m_item.font = allocHarfbuzzFont();
- m_item.string = run.characters();
- m_item.stringLength = run.length();
- m_item.item.bidiLevel = run.rtl();
+ m_item.string = m_run.characters();
+ m_item.stringLength = m_run.length();
+ m_item.item.bidiLevel = m_run.rtl();
reset();
}
@@ -283,6 +290,43 @@ public:
}
private:
+ const TextRun& getTextRun(const TextRun& originalRun)
+ {
+ // Convert the |originalRun| to NFC normalized form if combining diacritical marks
+ // (U+0300..) are used in the run. This conversion is necessary since most OpenType
+ // fonts (e.g., Arial) don't have substitution rules for the diacritical marks in
+ // their GSUB tables.
+ //
+ // Note that we don't use the icu::Normalizer::isNormalized(UNORM_NFC) API here since
+ // the API returns FALSE (= not normalized) for complex runs that don't require NFC
+ // normalization (e.g., Arabic text). Unless the run contains the diacritical marks,
+ // Harfbuzz will do the same thing for us using the GSUB table.
+ for (unsigned i = 0; i < originalRun.length(); ++i) {
+ UBlockCode block = ::ublock_getCode(originalRun[i]);
+ if (block == UBLOCK_COMBINING_DIACRITICAL_MARKS) {
+ return getNormalizedTextRun(originalRun);
+ }
+ }
+ return originalRun;
+ }
+
+ const TextRun& getNormalizedTextRun(const TextRun& originalRun)
+ {
+ icu::UnicodeString normalizedString;
+ UErrorCode error = U_ZERO_ERROR;
+ icu::Normalizer::normalize(icu::UnicodeString(originalRun.characters(), originalRun.length()), UNORM_NFC, 0 /* no options */, normalizedString, error);
+ if (U_FAILURE(error))
+ return originalRun;
+
+ m_normalizedBuffer.set(new UChar[normalizedString.length() + 1]);
+ normalizedString.extract(m_normalizedBuffer.get(), normalizedString.length() + 1, error);
+ ASSERT(U_SUCCESS(error));
+
+ m_normalizedRun.set(new TextRun(originalRun));
+ m_normalizedRun->setText(m_normalizedBuffer.get(), normalizedString.length());
+ return *m_normalizedRun;
+ }
+
void setupFontForScriptRun()
{
const FontData* fontData = m_font->fontDataAt(0);
@@ -379,7 +423,6 @@ private:
}
const Font* const m_font;
- const TextRun& m_run;
HB_ShaperItem m_item;
uint16_t* m_glyphs16; // A vector of 16-bit glyph ids.
SkScalar* m_xPositions; // A vector of x positions for each glyph.
@@ -389,6 +432,10 @@ private:
unsigned m_pixelWidth; // Width (in px) of the current script run.
unsigned m_numCodePoints; // Code points in current script run.
unsigned m_maxGlyphs; // Current size of all the Harfbuzz arrays.
+
+ OwnPtr<TextRun> m_normalizedRun;
+ OwnArrayPtr<UChar> m_normalizedBuffer; // A buffer for normalized run.
+ const TextRun& m_run;
bool m_iterateBackwards;
};
diff --git a/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp b/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp
index 9596a4c..4e2a226 100644
--- a/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp
+++ b/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp
@@ -100,11 +100,11 @@ void initializeScriptFontMap(ScriptToFontMap& scriptFontMap)
// Initialize the locale-dependent mapping.
// Since Chrome synchronizes the ICU default locale with its UI locale,
// this ICU locale tells the current UI locale of Chrome.
- Locale locale = Locale::getDefault();
+ icu::Locale locale = icu::Locale::getDefault();
const UChar* localeFamily = 0;
- if (locale == Locale::getJapanese())
+ if (locale == icu::Locale::getJapanese())
localeFamily = scriptFontMap[USCRIPT_HIRAGANA];
- else if (locale == Locale::getKorean())
+ else if (locale == icu::Locale::getKorean())
localeFamily = scriptFontMap[USCRIPT_HANGUL];
else {
// Use Simplified Chinese font for all other locales including
diff --git a/WebCore/platform/graphics/chromium/UniscribeHelper.cpp b/WebCore/platform/graphics/chromium/UniscribeHelper.cpp
index 39b0847..10fcdf6 100644
--- a/WebCore/platform/graphics/chromium/UniscribeHelper.cpp
+++ b/WebCore/platform/graphics/chromium/UniscribeHelper.cpp
@@ -375,11 +375,13 @@ void UniscribeHelper::draw(GraphicsContext* graphicsContext,
// Pass 0 in when there is no justification.
const int* justify = shaping.m_justify.size() == 0 ? 0 : &shaping.m_justify[fromGlyph];
- if (firstRun) {
- oldFont = SelectObject(dc, shaping.m_hfont);
- firstRun = false;
- } else
- SelectObject(dc, shaping.m_hfont);
+ if (useWindowsDrawing) {
+ if (firstRun) {
+ oldFont = SelectObject(dc, shaping.m_hfont);
+ firstRun = false;
+ } else
+ SelectObject(dc, shaping.m_hfont);
+ }
// Fonts with different ascents can be used to render different
// runs. 'Across-runs' y-coordinate correction needs to be
@@ -401,7 +403,7 @@ void UniscribeHelper::draw(GraphicsContext* graphicsContext,
} else {
SkPoint origin;
origin.fX = curX + + innerOffset;
- origin.fY = y + m_ascent - shaping.m_ascentOffset;
+ origin.fY = y + m_ascent;
textOutOk = paintSkiaText(graphicsContext,
shaping.m_hfont,
glyphCount,
diff --git a/WebCore/platform/graphics/filters/FEBlend.cpp b/WebCore/platform/graphics/filters/FEBlend.cpp
index 86b702f..2364cc4 100644
--- a/WebCore/platform/graphics/filters/FEBlend.cpp
+++ b/WebCore/platform/graphics/filters/FEBlend.cpp
@@ -2,6 +2,7 @@
Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
2004, 2005 Rob Buis <buis@kde.org>
2005 Eric Seidel <eric@webkit.org>
+ 2009 Dirk Schulze <krit@webkit.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -24,7 +25,13 @@
#if ENABLE(FILTERS)
#include "FEBlend.h"
+#include "CanvasPixelArray.h"
#include "Filter.h"
+#include "FloatPoint.h"
+#include "GraphicsContext.h"
+#include "ImageData.h"
+
+typedef unsigned char (*BlendType)(unsigned char colorA, unsigned char colorB, unsigned char alphaA, unsigned char alphaB);
namespace WebCore {
@@ -61,8 +68,77 @@ void FEBlend::setBlendMode(BlendModeType mode)
m_mode = mode;
}
-void FEBlend::apply(Filter*)
+static unsigned char unknown(unsigned char, unsigned char, unsigned char, unsigned char)
+{
+ return 0;
+}
+
+static unsigned char normal(unsigned char colorA, unsigned char colorB, unsigned char alphaA, unsigned char)
+{
+ return (((255 - alphaA) * colorB + colorA * 255) / 255);
+}
+
+static unsigned char multiply(unsigned char colorA, unsigned char colorB, unsigned char alphaA, unsigned char alphaB)
+{
+ return (((255 - alphaA) * colorB + (255 - alphaB + colorB) * colorA) / 255);
+}
+
+static unsigned char screen(unsigned char colorA, unsigned char colorB, unsigned char, unsigned char)
+{
+ return (((colorB + colorA) * 255 - colorA * colorB) / 255);
+}
+
+static unsigned char darken(unsigned char colorA, unsigned char colorB, unsigned char alphaA, unsigned char alphaB)
+{
+ return ((std::min((255 - alphaA) * colorB + colorA * 255, (255 - alphaB) * colorA + colorB * 255)) / 255);
+}
+
+static unsigned char lighten(unsigned char colorA, unsigned char colorB, unsigned char alphaA, unsigned char alphaB)
{
+ return ((std::max((255 - alphaA) * colorB + colorA * 255, (255 - alphaB) * colorA + colorB * 255)) / 255);
+}
+
+void FEBlend::apply(Filter* filter)
+{
+ m_in->apply(filter);
+ m_in2->apply(filter);
+ if (!m_in->resultImage() || !m_in2->resultImage())
+ return;
+
+ if (m_mode == FEBLEND_MODE_UNKNOWN)
+ return;
+
+ if (!getEffectContext())
+ return;
+
+ IntRect effectADrawingRect = calculateDrawingIntRect(m_in->subRegion());
+ RefPtr<CanvasPixelArray> srcPixelArrayA(m_in->resultImage()->getPremultipliedImageData(effectADrawingRect)->data());
+
+ IntRect effectBDrawingRect = calculateDrawingIntRect(m_in2->subRegion());
+ RefPtr<CanvasPixelArray> srcPixelArrayB(m_in2->resultImage()->getPremultipliedImageData(effectBDrawingRect)->data());
+
+ IntRect imageRect(IntPoint(), resultImage()->size());
+ RefPtr<ImageData> imageData = ImageData::create(imageRect.width(), imageRect.height());
+
+ // Keep synchronized with BlendModeType
+ static const BlendType callEffect[] = {unknown, normal, multiply, screen, darken, lighten};
+
+ ASSERT(srcPixelArrayA->length() == srcPixelArrayB->length());
+ for (unsigned pixelOffset = 0; pixelOffset < srcPixelArrayA->length(); pixelOffset += 4) {
+ unsigned char alphaA = srcPixelArrayA->get(pixelOffset + 3);
+ unsigned char alphaB = srcPixelArrayB->get(pixelOffset + 3);
+ for (unsigned channel = 0; channel < 3; ++channel) {
+ unsigned char colorA = srcPixelArrayA->get(pixelOffset + channel);
+ unsigned char colorB = srcPixelArrayB->get(pixelOffset + channel);
+
+ unsigned char result = (*callEffect[m_mode])(colorA, colorB, alphaA, alphaB);
+ imageData->data()->set(pixelOffset + channel, result);
+ }
+ unsigned char alphaR = 255 - ((255 - alphaA) * (255 - alphaB)) / 255;
+ imageData->data()->set(pixelOffset + 3, alphaR);
+ }
+
+ resultImage()->putPremultipliedImageData(imageData.get(), imageRect, IntPoint());
}
void FEBlend::dump()
diff --git a/WebCore/platform/graphics/filters/FEBlend.h b/WebCore/platform/graphics/filters/FEBlend.h
index b09cd72..31c625f 100644
--- a/WebCore/platform/graphics/filters/FEBlend.h
+++ b/WebCore/platform/graphics/filters/FEBlend.h
@@ -41,7 +41,7 @@ namespace WebCore {
class FEBlend : public FilterEffect {
public:
static PassRefPtr<FEBlend> create(FilterEffect*, FilterEffect*, BlendModeType);
-
+
FilterEffect* in2() const;
void setIn2(FilterEffect*);
diff --git a/WebCore/platform/graphics/filters/FEColorMatrix.cpp b/WebCore/platform/graphics/filters/FEColorMatrix.cpp
index fb0a194..1e2e552 100644
--- a/WebCore/platform/graphics/filters/FEColorMatrix.cpp
+++ b/WebCore/platform/graphics/filters/FEColorMatrix.cpp
@@ -166,7 +166,7 @@ void FEColorMatrix::apply(Filter* filter)
filterContext->drawImage(m_in->resultImage()->image(), calculateDrawingRect(m_in->subRegion()));
IntRect imageRect(IntPoint(), resultImage()->size());
- PassRefPtr<ImageData> imageData(resultImage()->getImageData(imageRect));
+ PassRefPtr<ImageData> imageData(resultImage()->getUnmultipliedImageData(imageRect));
PassRefPtr<CanvasPixelArray> srcPixelArray(imageData->data());
switch (m_type) {
@@ -186,7 +186,7 @@ void FEColorMatrix::apply(Filter* filter)
break;
}
- resultImage()->putImageData(imageData.get(), imageRect, IntPoint());
+ resultImage()->putUnmultipliedImageData(imageData.get(), imageRect, IntPoint());
}
void FEColorMatrix::dump()
diff --git a/WebCore/platform/graphics/filters/FEComponentTransfer.cpp b/WebCore/platform/graphics/filters/FEComponentTransfer.cpp
index 54ac123..43e5edd 100644
--- a/WebCore/platform/graphics/filters/FEComponentTransfer.cpp
+++ b/WebCore/platform/graphics/filters/FEComponentTransfer.cpp
@@ -2,6 +2,7 @@
Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
2004, 2005 Rob Buis <buis@kde.org>
2005 Eric Seidel <eric@webkit.org>
+ 2009 Dirk Schulze <krit@webkit.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -24,10 +25,16 @@
#if ENABLE(FILTERS)
#include "FEComponentTransfer.h"
+#include "CanvasPixelArray.h"
#include "Filter.h"
+#include "GraphicsContext.h"
+#include "ImageData.h"
+#include <math.h>
namespace WebCore {
+typedef void (*TransferType)(unsigned char*, const ComponentTransferFunction&);
+
FEComponentTransfer::FEComponentTransfer(FilterEffect* in, const ComponentTransferFunction& redFunc,
const ComponentTransferFunction& greenFunc, const ComponentTransferFunction& blueFunc, const ComponentTransferFunction& alphaFunc)
: FilterEffect()
@@ -85,8 +92,91 @@ void FEComponentTransfer::setAlphaFunction(const ComponentTransferFunction& func
m_alphaFunc = func;
}
-void FEComponentTransfer::apply(Filter*)
+void identity(unsigned char*, const ComponentTransferFunction&)
+{
+}
+
+void table(unsigned char* values, const ComponentTransferFunction& transferFunction)
+{
+ const Vector<float>& tableValues = transferFunction.tableValues;
+ unsigned n = tableValues.size();
+ if (n < 1)
+ return;
+ for (unsigned i = 0; i < 256; ++i) {
+ double c = i / 255.0;
+ unsigned k = static_cast<unsigned>(c * (n - 1));
+ double v1 = tableValues[k];
+ double v2 = tableValues[std::min((k + 1), (n - 1))];
+ double val = 255.0 * (v1 + (c * (n - 1) - k) * (v2 - v1));
+ val = std::max(0.0, std::min(255.0, val));
+ values[i] = static_cast<unsigned char>(val);
+ }
+}
+
+void discrete(unsigned char* values, const ComponentTransferFunction& transferFunction)
+{
+ const Vector<float>& tableValues = transferFunction.tableValues;
+ unsigned n = tableValues.size();
+ if (n < 1)
+ return;
+ for (unsigned i = 0; i < 256; ++i) {
+ unsigned k = static_cast<unsigned>((i * n) / 255.0);
+ k = std::min(k, n - 1);
+ double val = 255 * tableValues[k];
+ val = std::max(0.0, std::min(255.0, val));
+ values[i] = static_cast<unsigned char>(val);
+ }
+}
+
+void linear(unsigned char* values, const ComponentTransferFunction& transferFunction)
+{
+ for (unsigned i = 0; i < 256; ++i) {
+ double val = transferFunction.slope * i + 255 * transferFunction.intercept;
+ val = std::max(0.0, std::min(255.0, val));
+ values[i] = static_cast<unsigned char>(val);
+ }
+}
+
+void gamma(unsigned char* values, const ComponentTransferFunction& transferFunction)
+{
+ for (unsigned i = 0; i < 256; ++i) {
+ double val = 255.0 * (transferFunction.amplitude * pow((i / 255.0), transferFunction.exponent) + transferFunction.offset);
+ val = std::max(0.0, std::min(255.0, val));
+ values[i] = static_cast<unsigned char>(val);
+ }
+}
+
+void FEComponentTransfer::apply(Filter* filter)
{
+ m_in->apply(filter);
+ if (!m_in->resultImage())
+ return;
+
+ if (!getEffectContext())
+ return;
+
+ unsigned char rValues[256], gValues[256], bValues[256], aValues[256];
+ for (unsigned i = 0; i < 256; ++i)
+ rValues[i] = gValues[i] = bValues[i] = aValues[i] = i;
+ unsigned char* tables[] = { rValues, gValues, bValues, aValues };
+ ComponentTransferFunction transferFunction[] = {m_redFunc, m_greenFunc, m_blueFunc, m_alphaFunc};
+ TransferType callEffect[] = {identity, identity, table, discrete, linear, gamma};
+
+ for (unsigned channel = 0; channel < 4; channel++)
+ (*callEffect[transferFunction[channel].type])(tables[channel], transferFunction[channel]);
+
+ IntRect drawingRect = calculateDrawingIntRect(m_in->subRegion());
+ RefPtr<ImageData> imageData(m_in->resultImage()->getUnmultipliedImageData(drawingRect));
+ CanvasPixelArray* srcPixelArray(imageData->data());
+
+ for (unsigned pixelOffset = 0; pixelOffset < srcPixelArray->length(); pixelOffset += 4) {
+ for (unsigned channel = 0; channel < 4; ++channel) {
+ unsigned char c = srcPixelArray->get(pixelOffset + channel);
+ imageData->data()->set(pixelOffset + channel, tables[channel][c]);
+ }
+ }
+
+ resultImage()->putUnmultipliedImageData(imageData.get(), IntRect(IntPoint(), resultImage()->size()), IntPoint());
}
void FEComponentTransfer::dump()
diff --git a/WebCore/platform/graphics/filters/FEComposite.cpp b/WebCore/platform/graphics/filters/FEComposite.cpp
index 0706358..1b41165 100644
--- a/WebCore/platform/graphics/filters/FEComposite.cpp
+++ b/WebCore/platform/graphics/filters/FEComposite.cpp
@@ -2,6 +2,7 @@
Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
2004, 2005 Rob Buis <buis@kde.org>
2005 Eric Seidel <eric@webkit.org>
+ 2009 Dirk Schulze <krit@webkit.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -24,7 +25,10 @@
#if ENABLE(FILTERS)
#include "FEComposite.h"
+#include "CanvasPixelArray.h"
#include "Filter.h"
+#include "GraphicsContext.h"
+#include "ImageData.h"
namespace WebCore {
@@ -97,8 +101,74 @@ void FEComposite::setK4(float k4)
m_k4 = k4;
}
-void FEComposite::apply(Filter*)
+inline void arithmetic(const RefPtr<CanvasPixelArray>& srcPixelArrayA, CanvasPixelArray*& srcPixelArrayB,
+ float k1, float k2, float k3, float k4)
{
+ float scaledK1 = k1 / 255.f;
+ float scaledK4 = k4 * 255.f;
+ for (unsigned pixelOffset = 0; pixelOffset < srcPixelArrayA->length(); pixelOffset += 4) {
+ for (unsigned channel = 0; channel < 4; ++channel) {
+ unsigned char i1 = srcPixelArrayA->get(pixelOffset + channel);
+ unsigned char i2 = srcPixelArrayB->get(pixelOffset + channel);
+
+ unsigned char result = scaledK1 * i1 * i2 + k2 * i1 + k3 * i2 + scaledK4;
+ if (channel == 3 && i1 == 0 && i2 == 0)
+ result = 0;
+ srcPixelArrayB->set(pixelOffset + channel, result);
+ }
+ }
+}
+
+void FEComposite::apply(Filter* filter)
+{
+ m_in->apply(filter);
+ m_in2->apply(filter);
+ if (!m_in->resultImage() || !m_in2->resultImage())
+ return;
+
+ GraphicsContext* filterContext = getEffectContext();
+ if (!filterContext)
+ return;
+
+ FloatRect srcRect = FloatRect(0.f, 0.f, -1.f, -1.f);
+ switch (m_type) {
+ case FECOMPOSITE_OPERATOR_OVER:
+ filterContext->drawImage(m_in2->resultImage()->image(), calculateDrawingRect(m_in2->subRegion()));
+ filterContext->drawImage(m_in->resultImage()->image(), calculateDrawingRect(m_in->subRegion()));
+ break;
+ case FECOMPOSITE_OPERATOR_IN:
+ filterContext->save();
+ filterContext->clipToImageBuffer(calculateDrawingRect(m_in2->subRegion()), m_in2->resultImage());
+ filterContext->drawImage(m_in->resultImage()->image(), calculateDrawingRect(m_in->subRegion()));
+ filterContext->restore();
+ break;
+ case FECOMPOSITE_OPERATOR_OUT:
+ filterContext->drawImage(m_in->resultImage()->image(), calculateDrawingRect(m_in->subRegion()));
+ filterContext->drawImage(m_in2->resultImage()->image(), calculateDrawingRect(m_in2->subRegion()), srcRect, CompositeDestinationOut);
+ break;
+ case FECOMPOSITE_OPERATOR_ATOP:
+ filterContext->drawImage(m_in2->resultImage()->image(), calculateDrawingRect(m_in2->subRegion()));
+ filterContext->drawImage(m_in->resultImage()->image(), calculateDrawingRect(m_in->subRegion()), srcRect, CompositeSourceAtop);
+ break;
+ case FECOMPOSITE_OPERATOR_XOR:
+ filterContext->drawImage(m_in2->resultImage()->image(), calculateDrawingRect(m_in2->subRegion()));
+ filterContext->drawImage(m_in->resultImage()->image(), calculateDrawingRect(m_in->subRegion()), srcRect, CompositeXOR);
+ break;
+ case FECOMPOSITE_OPERATOR_ARITHMETIC: {
+ IntRect effectADrawingRect = calculateDrawingIntRect(m_in->subRegion());
+ RefPtr<CanvasPixelArray> srcPixelArrayA(m_in->resultImage()->getPremultipliedImageData(effectADrawingRect)->data());
+
+ IntRect effectBDrawingRect = calculateDrawingIntRect(m_in2->subRegion());
+ RefPtr<ImageData> imageData(m_in2->resultImage()->getPremultipliedImageData(effectBDrawingRect));
+ CanvasPixelArray* srcPixelArrayB(imageData->data());
+
+ arithmetic(srcPixelArrayA, srcPixelArrayB, m_k1, m_k2, m_k3, m_k4);
+ resultImage()->putPremultipliedImageData(imageData.get(), IntRect(IntPoint(), resultImage()->size()), IntPoint());
+ }
+ break;
+ default:
+ break;
+ }
}
void FEComposite::dump()
diff --git a/WebCore/platform/graphics/filters/FilterEffect.cpp b/WebCore/platform/graphics/filters/FilterEffect.cpp
index 41e8a39..5818e50 100644
--- a/WebCore/platform/graphics/filters/FilterEffect.cpp
+++ b/WebCore/platform/graphics/filters/FilterEffect.cpp
@@ -59,6 +59,13 @@ FloatRect FilterEffect::calculateEffectRect(Filter* filter)
return subRegion();
}
+IntRect FilterEffect::calculateDrawingIntRect(const FloatRect& effectRect)
+{
+ IntPoint location = roundedIntPoint(FloatPoint(subRegion().x() - effectRect.x(),
+ subRegion().y() - effectRect.y()));
+ return IntRect(location, resultImage()->size());
+}
+
FloatRect FilterEffect::calculateDrawingRect(const FloatRect& srcRect)
{
FloatPoint startPoint = FloatPoint(srcRect.x() - subRegion().x(), srcRect.y() - subRegion().y());
diff --git a/WebCore/platform/graphics/filters/FilterEffect.h b/WebCore/platform/graphics/filters/FilterEffect.h
index 8dc6233..e2b8a0e 100644
--- a/WebCore/platform/graphics/filters/FilterEffect.h
+++ b/WebCore/platform/graphics/filters/FilterEffect.h
@@ -77,6 +77,7 @@ namespace WebCore {
GraphicsContext* getEffectContext();
FloatRect calculateDrawingRect(const FloatRect&);
+ IntRect calculateDrawingIntRect(const FloatRect&);
virtual FloatRect uniteChildEffectSubregions(Filter* filter) { return filter->filterRegion(); }
virtual FloatRect calculateEffectRect(Filter*);
diff --git a/WebCore/platform/graphics/filters/SourceAlpha.cpp b/WebCore/platform/graphics/filters/SourceAlpha.cpp
index 646a57b..57436be 100644
--- a/WebCore/platform/graphics/filters/SourceAlpha.cpp
+++ b/WebCore/platform/graphics/filters/SourceAlpha.cpp
@@ -22,6 +22,7 @@
#if ENABLE(FILTERS)
#include "SourceAlpha.h"
+#include "Color.h"
#include "GraphicsContext.h"
#include "PlatformString.h"
#include "Filter.h"
@@ -41,8 +42,28 @@ const AtomicString& SourceAlpha::effectName()
return s_effectName;
}
-void SourceAlpha::apply(Filter*)
+FloatRect SourceAlpha::calculateEffectRect(Filter* filter)
{
+ FloatRect clippedSourceRect = filter->sourceImageRect();
+ if (filter->sourceImageRect().x() < filter->filterRegion().x())
+ clippedSourceRect.setX(filter->filterRegion().x());
+ if (filter->sourceImageRect().y() < filter->filterRegion().y())
+ clippedSourceRect.setY(filter->filterRegion().y());
+ setSubRegion(clippedSourceRect);
+ return filter->filterRegion();
+}
+
+void SourceAlpha::apply(Filter* filter)
+{
+ GraphicsContext* filterContext = getEffectContext();
+ if (!filterContext)
+ return;
+
+ FloatRect imageRect(FloatPoint(), filter->sourceImage()->image()->size());
+ filterContext->save();
+ filterContext->clipToImageBuffer(imageRect, filter->sourceImage());
+ filterContext->fillRect(imageRect, Color::black);
+ filterContext->restore();
}
void SourceAlpha::dump()
diff --git a/WebCore/platform/graphics/filters/SourceAlpha.h b/WebCore/platform/graphics/filters/SourceAlpha.h
index 5341562..172d05a 100644
--- a/WebCore/platform/graphics/filters/SourceAlpha.h
+++ b/WebCore/platform/graphics/filters/SourceAlpha.h
@@ -35,7 +35,7 @@ namespace WebCore {
static const AtomicString& effectName();
virtual bool isSourceInput() { return true; }
- virtual FloatRect calculateEffectRect(Filter* filter) { return filter->sourceImageRect(); }
+ virtual FloatRect calculateEffectRect(Filter*);
void apply(Filter*);
void dump();
diff --git a/WebCore/platform/graphics/gtk/DataSourceGStreamer.cpp b/WebCore/platform/graphics/gtk/DataSourceGStreamer.cpp
new file mode 100644
index 0000000..a6c2dfb
--- /dev/null
+++ b/WebCore/platform/graphics/gtk/DataSourceGStreamer.cpp
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2009 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 "DataSourceGStreamer.h"
+
+#include <gio/gio.h>
+#include <glib.h>
+#include <gst/gst.h>
+#include <gst/pbutils/missing-plugins.h>
+
+static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE("src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS_ANY);
+
+GST_DEBUG_CATEGORY_STATIC(webkit_data_src_debug);
+#define GST_CAT_DEFAULT webkit_data_src_debug
+
+static void webkit_data_src_uri_handler_init(gpointer g_iface,
+ gpointer iface_data);
+
+static void webkit_data_src_finalize(WebkitDataSrc* src);
+static GstStateChangeReturn webkit_data_src_change_state(GstElement* element,
+ GstStateChange transition);
+
+static const GInterfaceInfo urihandler_info = {
+ webkit_data_src_uri_handler_init,
+ 0, 0
+};
+
+
+static void _do_init(GType datasrc_type)
+{
+ GST_DEBUG_CATEGORY_INIT(webkit_data_src_debug, "webkit_data_src", 0, "datasrc element");
+ g_type_add_interface_static(datasrc_type, GST_TYPE_URI_HANDLER,
+ &urihandler_info);
+}
+
+GST_BOILERPLATE_FULL(WebkitDataSrc, webkit_data_src, GstBin, GST_TYPE_BIN, _do_init);
+
+static void webkit_data_src_base_init(gpointer klass)
+{
+ GstElementClass* element_class = GST_ELEMENT_CLASS(klass);
+
+ gst_element_class_add_pad_template(element_class,
+ gst_static_pad_template_get(&src_template));
+ gst_element_class_set_details_simple(element_class, (gchar*) "WebKit data source element",
+ (gchar*) "Source",
+ (gchar*) "Handles data: uris",
+ (gchar*) "Philippe Normand <pnormand@igalia.com>");
+
+}
+
+static void webkit_data_src_class_init(WebkitDataSrcClass* klass)
+{
+ GObjectClass* oklass = G_OBJECT_CLASS(klass);
+ GstElementClass* eklass = GST_ELEMENT_CLASS(klass);
+
+ oklass->finalize = (GObjectFinalizeFunc) webkit_data_src_finalize;
+ eklass->change_state = webkit_data_src_change_state;
+}
+
+
+static gboolean webkit_data_src_reset(WebkitDataSrc* src)
+{
+ GstPad* targetpad;
+
+ if (src->kid) {
+ gst_element_set_state(src->kid, GST_STATE_NULL);
+ gst_bin_remove(GST_BIN(src), src->kid);
+ }
+
+ src->kid = gst_element_factory_make("giostreamsrc", "streamsrc");
+ if (!src->kid) {
+ GST_ERROR_OBJECT(src, "Failed to create giostreamsrc");
+ return FALSE;
+ }
+
+ gst_bin_add(GST_BIN(src), src->kid);
+
+ targetpad = gst_element_get_static_pad(src->kid, "src");
+ gst_ghost_pad_set_target(GST_GHOST_PAD(src->pad), targetpad);
+ gst_object_unref(targetpad);
+
+ return TRUE;
+}
+
+static void webkit_data_src_init(WebkitDataSrc* src,
+ WebkitDataSrcClass* g_class)
+{
+ GstPadTemplate* pad_template = gst_static_pad_template_get(&src_template);
+ src->pad = gst_ghost_pad_new_no_target_from_template("src",
+ pad_template);
+
+ gst_element_add_pad(GST_ELEMENT(src), src->pad);
+
+ webkit_data_src_reset(src);
+}
+
+static void webkit_data_src_finalize(WebkitDataSrc* src)
+{
+ g_free(src->uri);
+
+ if (src->kid) {
+ GST_DEBUG_OBJECT(src, "Removing giostreamsrc element");
+ gst_element_set_state(src->kid, GST_STATE_NULL);
+ gst_bin_remove(GST_BIN(src), src->kid);
+ src->kid = 0;
+ }
+
+ GST_CALL_PARENT(G_OBJECT_CLASS, finalize, ((GObject* )(src)));
+}
+
+static GstStateChangeReturn webkit_data_src_change_state(GstElement* element, GstStateChange transition)
+{
+ GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
+ WebkitDataSrc* src = WEBKIT_DATA_SRC(element);
+
+ switch (transition) {
+ case GST_STATE_CHANGE_NULL_TO_READY:
+ if (!src->kid) {
+ gst_element_post_message(element,
+ gst_missing_element_message_new(element, "giostreamsrc"));
+ GST_ELEMENT_ERROR(src, CORE, MISSING_PLUGIN, (0), ("no giostreamsrc"));
+ return GST_STATE_CHANGE_FAILURE;
+ }
+ break;
+ default:
+ break;
+ }
+
+ ret = GST_ELEMENT_CLASS(parent_class)->change_state(element, transition);
+ if (G_UNLIKELY(ret == GST_STATE_CHANGE_FAILURE))
+ return ret;
+
+ // Downwards state change code should be here, after chaining up
+ // to the parent class.
+
+ return ret;
+}
+
+/*** GSTURIHANDLER INTERFACE *************************************************/
+
+static GstURIType webkit_data_src_uri_get_type(void)
+{
+ return GST_URI_SRC;
+}
+
+static gchar** webkit_data_src_uri_get_protocols(void)
+{
+ static gchar* protocols[] = {(gchar*) "data", 0 };
+
+ return protocols;
+}
+
+static const gchar* webkit_data_src_uri_get_uri(GstURIHandler* handler)
+{
+ WebkitDataSrc* src = WEBKIT_DATA_SRC(handler);
+
+ return src->uri;
+}
+
+static gboolean webkit_data_src_uri_set_uri(GstURIHandler* handler, const gchar* uri)
+{
+ WebkitDataSrc* src = WEBKIT_DATA_SRC(handler);
+
+ // URI as defined in RFC2397:
+ // "data:" [ mediatype ] [ ";base64" ] "," data
+ // we parse URIs like this one:
+ // data:audio/3gpp;base64,AA...
+
+ gchar** scheme_and_remains = g_strsplit(uri, ":", 2);
+ gchar** mime_type_and_options = g_strsplit(scheme_and_remains[1], ";", 0);
+ gint options_size = g_strv_length(mime_type_and_options);
+ gchar* data = 0;
+ gchar* mime_type = 0;
+ gint ret = FALSE;
+
+ // we require uris with a specified mime-type and base64-encoded
+ // data. It doesn't make much sense anyway to play plain/text data
+ // with very few allowed characters (as per the RFC).
+
+ if (GST_STATE(src) >= GST_STATE_PAUSED) {
+ GST_ERROR_OBJECT(src, "Element already configured. Reset it and retry");
+ } else if (!options_size)
+ GST_ERROR_OBJECT(src, "A mime-type is needed in %s", uri);
+ else {
+ mime_type = mime_type_and_options[0];
+ data = mime_type_and_options[options_size-1];
+
+ guchar* decoded_data = 0;
+ gsize decoded_size;
+
+ if (!g_str_has_prefix(data, "base64"))
+ GST_ERROR_OBJECT(src, "Data has to be base64-encoded in %s", uri);
+ else {
+ decoded_data = g_base64_decode(data+7, &decoded_size);
+ GInputStream* stream = g_memory_input_stream_new_from_data(decoded_data,
+ decoded_size,
+ g_free);
+ g_object_set(src->kid, "stream", stream, 0);
+ g_object_unref(stream);
+
+ if (src->uri) {
+ g_free(src->uri);
+ src->uri = 0;
+ }
+
+ src->uri = g_strdup(uri);
+ ret = TRUE;
+ }
+ }
+
+ g_strfreev(scheme_and_remains);
+ g_strfreev(mime_type_and_options);
+ return ret;
+}
+
+static void webkit_data_src_uri_handler_init(gpointer g_iface, gpointer iface_data)
+{
+ GstURIHandlerInterface* iface = (GstURIHandlerInterface *) g_iface;
+
+ iface->get_type = webkit_data_src_uri_get_type;
+ iface->get_protocols = webkit_data_src_uri_get_protocols;
+ iface->get_uri = webkit_data_src_uri_get_uri;
+ iface->set_uri = webkit_data_src_uri_set_uri;
+}
diff --git a/WebCore/platform/graphics/gtk/DataSourceGStreamer.h b/WebCore/platform/graphics/gtk/DataSourceGStreamer.h
new file mode 100644
index 0000000..3e88f63
--- /dev/null
+++ b/WebCore/platform/graphics/gtk/DataSourceGStreamer.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2009 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 DATA_SOURCE_GSTREAMER_H
+#define DATA_SOURCE_GSTREAMER_H
+
+#include <glib-object.h>
+#include <gst/base/gstbasesrc.h>
+
+G_BEGIN_DECLS
+
+#define WEBKIT_TYPE_DATA_SRC (webkit_data_src_get_type ())
+#define WEBKIT_DATA_SRC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), WEBKIT_TYPE_DATA_SRC, WebkitDataSrc))
+#define WEBKIT_DATA_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), WEBKIT_TYPE_DATA_SRC, WebkitDataSrcClass))
+#define WEBKIT_IS_DATA_SRC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), WEBKIT_TYPE_DATA_SRC))
+#define WEBKIT_IS_DATA_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), WEBKIT_TYPE_DATA_SRC))
+
+typedef struct _WebkitDataSrc WebkitDataSrc;
+typedef struct _WebkitDataSrcClass WebkitDataSrcClass;
+
+
+struct _WebkitDataSrc {
+ GstBin parent;
+
+ /* explicit pointers to stuff used */
+ GstElement* kid;
+ GstPad* pad;
+ gchar* uri;
+};
+
+struct _WebkitDataSrcClass {
+ GstBinClass parent_class;
+};
+
+GType webkit_data_src_get_type(void);
+
+G_END_DECLS
+
+#endif
diff --git a/WebCore/platform/graphics/gtk/FontPlatformData.h b/WebCore/platform/graphics/gtk/FontPlatformData.h
index 2a65f1e..d30b480 100644
--- a/WebCore/platform/graphics/gtk/FontPlatformData.h
+++ b/WebCore/platform/graphics/gtk/FontPlatformData.h
@@ -87,7 +87,7 @@ public:
bool syntheticBold() const { return m_syntheticBold; }
bool syntheticOblique() const { return m_syntheticOblique; }
- void setFont(cairo_t*) const;
+ cairo_scaled_font_t* scaledFont() const { return m_scaledFont; }
unsigned hash() const
{
diff --git a/WebCore/platform/graphics/gtk/FontPlatformDataGtk.cpp b/WebCore/platform/graphics/gtk/FontPlatformDataGtk.cpp
index f2c5f0c..0b1280e 100644
--- a/WebCore/platform/graphics/gtk/FontPlatformDataGtk.cpp
+++ b/WebCore/platform/graphics/gtk/FontPlatformDataGtk.cpp
@@ -224,10 +224,8 @@ FontPlatformData::~FontPlatformData()
m_fallbacks = 0;
}
- if (m_scaledFont) {
+ if (m_scaledFont)
cairo_scaled_font_destroy(m_scaledFont);
- m_scaledFont = 0;
- }
}
bool FontPlatformData::isFixedPitch()
@@ -242,13 +240,6 @@ bool FontPlatformData::isFixedPitch()
return false;
}
-void FontPlatformData::setFont(cairo_t* cr) const
-{
- ASSERT(m_scaledFont);
-
- cairo_set_scaled_font(cr, m_scaledFont);
-}
-
bool FontPlatformData::operator==(const FontPlatformData& other) const
{
if (m_pattern == other.m_pattern)
diff --git a/WebCore/platform/graphics/gtk/FontPlatformDataPango.cpp b/WebCore/platform/graphics/gtk/FontPlatformDataPango.cpp
index 9ea6811..8a1a5f1 100644
--- a/WebCore/platform/graphics/gtk/FontPlatformDataPango.cpp
+++ b/WebCore/platform/graphics/gtk/FontPlatformDataPango.cpp
@@ -214,13 +214,6 @@ bool FontPlatformData::isFixedPitch()
return pango_font_family_is_monospace(family);
}
-void FontPlatformData::setFont(cairo_t* cr) const
-{
- ASSERT(m_scaledFont);
-
- cairo_set_scaled_font(cr, m_scaledFont);
-}
-
FontPlatformData& FontPlatformData::operator=(const FontPlatformData& other)
{
// Check for self-assignment.
diff --git a/WebCore/platform/graphics/gtk/ImageGtk.cpp b/WebCore/platform/graphics/gtk/ImageGtk.cpp
index 0e92d6c..38da70d 100644
--- a/WebCore/platform/graphics/gtk/ImageGtk.cpp
+++ b/WebCore/platform/graphics/gtk/ImageGtk.cpp
@@ -88,26 +88,67 @@ PassRefPtr<Image> Image::loadPlatformResource(const char* name)
return img.release();
}
+static inline unsigned char* getCairoSurfacePixel(unsigned char* data, uint x, uint y, uint rowStride)
+{
+ return data + (y * rowStride) + x * 4;
+}
+
+static inline guchar* getGdkPixbufPixel(guchar* data, uint x, uint y, uint rowStride)
+{
+ return data + (y * rowStride) + x * 4;
+}
+
GdkPixbuf* BitmapImage::getGdkPixbuf()
{
int width = cairo_image_surface_get_width(frameAtIndex(currentFrame()));
int height = cairo_image_surface_get_height(frameAtIndex(currentFrame()));
-
- int bestDepth = gdk_visual_get_best_depth();
- GdkColormap* cmap = gdk_colormap_new(gdk_visual_get_best_with_depth(bestDepth), true);
-
- GdkPixmap* pixmap = gdk_pixmap_new(0, width, height, bestDepth);
- gdk_drawable_set_colormap(GDK_DRAWABLE(pixmap), cmap);
- cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(pixmap));
- cairo_set_source_surface(cr, frameAtIndex(currentFrame()), 0, 0);
- cairo_paint(cr);
- cairo_destroy(cr);
-
- GdkPixbuf* pixbuf = gdk_pixbuf_get_from_drawable(0, GDK_DRAWABLE(pixmap), 0, 0, 0, 0, 0, width, height);
- g_object_unref(pixmap);
- g_object_unref(cmap);
-
- return pixbuf;
+ unsigned char* surfaceData = cairo_image_surface_get_data(frameAtIndex(currentFrame()));
+ int surfaceRowStride = cairo_image_surface_get_stride(frameAtIndex(currentFrame()));
+
+ GdkPixbuf* dest = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, width, height);
+ if (!dest)
+ return 0;
+
+ guchar* pixbufData = gdk_pixbuf_get_pixels(dest);
+ int pixbufRowStride = gdk_pixbuf_get_rowstride(dest);
+
+ /* From: http://cairographics.org/manual/cairo-image-surface.html#cairo-format-t
+ * "CAIRO_FORMAT_ARGB32: each pixel is a 32-bit quantity, with alpha in
+ * the upper 8 bits, then red, then green, then blue. The 32-bit
+ * quantities are stored native-endian. Pre-multiplied alpha is used.
+ * (That is, 50% transparent red is 0x80800000, not 0x80ff0000.)"
+ *
+ * See http://developer.gimp.org/api/2.0/gdk-pixbuf/gdk-pixbuf-gdk-pixbuf.html#GdkPixbuf
+ * for information on the structure of GdkPixbufs stored with GDK_COLORSPACE_RGB.
+ *
+ * RGB color channels in CAIRO_FORMAT_ARGB32 are stored based on the
+ * endianness of the machine and are also multiplied by the alpha channel.
+ * To properly transfer the data from the Cairo surface we must divide each
+ * of the RGB channels by the alpha channel and then reorder all channels
+ * if this machine is little-endian.
+ */
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ unsigned char* source = getCairoSurfacePixel(surfaceData, x, y, surfaceRowStride);
+ guchar* dest = getGdkPixbufPixel(pixbufData, x, y, pixbufRowStride);
+
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+ guchar alpha = source[3];
+ dest[0] = alpha ? ((source[2] * 255) / alpha) : 0;
+ dest[1] = alpha ? ((source[1] * 255) / alpha) : 0;
+ dest[2] = alpha ? ((source[0] * 255) / alpha) : 0;
+ dest[3] = alpha;
+#else
+ guchar alpha = source[0];
+ dest[0] = alpha ? ((source[1] * 255) / alpha) : 0;
+ dest[1] = alpha ? ((source[2] * 255) / alpha) : 0;
+ dest[2] = alpha ? ((source[3] * 255) / alpha) : 0;
+ dest[3] = alpha;
+#endif
+ }
+ }
+
+ return dest;
}
}
diff --git a/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp b/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp
index 4e4bda9..65c64b4 100644
--- a/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp
+++ b/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp
@@ -2,6 +2,7 @@
* Copyright (C) 2007, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2007 Collabora Ltd. All rights reserved.
* Copyright (C) 2007 Alp Toker <alp@atoker.com>
+ * Copyright (C) 2009 Gustavo Noronha Silva <gns@gnome.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -24,6 +25,7 @@
#if ENABLE(VIDEO)
#include "MediaPlayerPrivateGStreamer.h"
+#include "DataSourceGStreamer.h"
#include "CString.h"
#include "GraphicsContext.h"
@@ -35,6 +37,7 @@
#include "ScrollView.h"
#include "VideoSinkGStreamer.h"
#include "Widget.h"
+#include "TimeRanges.h"
#include <gst/base/gstbasesrc.h>
#include <gst/gst.h>
@@ -56,13 +59,19 @@ gboolean mediaPlayerPrivateErrorCallback(GstBus* bus, GstMessage* message, gpoin
GOwnPtr<gchar> debug;
gst_message_parse_error(message, &err.outPtr(), &debug.outPtr());
- if (err->code == 3) {
- LOG_VERBOSE(Media, "File not found");
- MediaPlayerPrivate* mp = reinterpret_cast<MediaPlayerPrivate*>(data);
- if (mp)
- mp->loadingFailed();
- } else
- LOG_VERBOSE(Media, "Error: %d, %s", err->code, err->message);
+ LOG_VERBOSE(Media, "Error: %d, %s", err->code, err->message);
+
+ MediaPlayer::NetworkState error = MediaPlayer::Empty;
+ if (err->domain == GST_CORE_ERROR || err->domain == GST_LIBRARY_ERROR)
+ error = MediaPlayer::DecodeError;
+ else if (err->domain == GST_RESOURCE_ERROR)
+ error = MediaPlayer::FormatError;
+ else if (err->domain == GST_STREAM_ERROR)
+ error = MediaPlayer::NetworkError;
+
+ MediaPlayerPrivate* mp = reinterpret_cast<MediaPlayerPrivate*>(data);
+ if (mp)
+ mp->loadingFailed(error);
}
return true;
}
@@ -112,6 +121,19 @@ void MediaPlayerPrivate::registerMediaEngine(MediaEngineRegistrar registrar)
registrar(create, getSupportedTypes, supportsType);
}
+static bool gstInitialized = false;
+
+static void do_gst_init() {
+ // FIXME: We should pass the arguments from the command line
+ if (!gstInitialized) {
+ gst_init(0, 0);
+ gstInitialized = true;
+ gst_element_register(0, "webkitmediasrc", GST_RANK_PRIMARY,
+ WEBKIT_TYPE_DATA_SRC);
+
+ }
+}
+
MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
: m_player(player)
, m_playBin(0)
@@ -119,7 +141,6 @@ MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
, m_source(0)
, m_rate(1.0f)
, m_endTime(numeric_limits<float>::infinity())
- , m_isEndReached(false)
, m_volume(0.5f)
, m_networkState(MediaPlayer::Empty)
, m_readyState(MediaPlayer::HaveNothing)
@@ -127,19 +148,22 @@ MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
, m_isStreaming(false)
, m_size(IntSize())
, m_visible(true)
+ , m_paused(true)
+ , m_seeking(false)
+ , m_errorOccured(false)
{
-
- static bool gstInitialized = false;
- // FIXME: We should pass the arguments from the command line
- if (!gstInitialized) {
- gst_init(0, 0);
- gstInitialized = true;
- }
+ do_gst_init();
// FIXME: The size shouldn't be fixed here, this is just a quick hack.
m_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 640, 480);
}
+static gboolean idleUnref(gpointer data)
+{
+ g_object_unref(reinterpret_cast<GObject*>(data));
+ return FALSE;
+}
+
MediaPlayerPrivate::~MediaPlayerPrivate()
{
if (m_surface)
@@ -149,6 +173,18 @@ MediaPlayerPrivate::~MediaPlayerPrivate()
gst_element_set_state(m_playBin, GST_STATE_NULL);
gst_object_unref(GST_OBJECT(m_playBin));
}
+
+ // FIXME: We should find a better way to handle the lifetime of this object; this is
+ // needed because the object is sometimes being destroyed inbetween a call to
+ // webkit_video_sink_render, and the idle it schedules. Adding a ref in
+ // webkit_video_sink_render that would be balanced by the idle is not an option,
+ // because in some cases the destruction of the sink may happen in time for the idle
+ // to be removed from the queue, so it may not run. It would also cause lots of ref
+ // counting churn (render/idle are called many times). This is an ugly race.
+ if (m_videoSink) {
+ g_idle_add(idleUnref, m_videoSink);
+ m_videoSink = 0;
+ }
}
void MediaPlayerPrivate::load(const String& url)
@@ -170,20 +206,13 @@ void MediaPlayerPrivate::load(const String& url)
void MediaPlayerPrivate::play()
{
LOG_VERBOSE(Media, "Play");
- // When end reached, rewind for Test video-seek-past-end-playing
- if (m_isEndReached)
- seek(0);
- m_isEndReached = false;
-
gst_element_set_state(m_playBin, GST_STATE_PLAYING);
- m_startedPlaying = true;
}
void MediaPlayerPrivate::pause()
{
LOG_VERBOSE(Media, "Pause");
gst_element_set_state(m_playBin, GST_STATE_PAUSED);
- m_startedPlaying = false;
}
float MediaPlayerPrivate::duration() const
@@ -191,17 +220,24 @@ float MediaPlayerPrivate::duration() const
if (!m_playBin)
return 0.0;
+ if (m_errorOccured)
+ return 0.0;
+
GstFormat timeFormat = GST_FORMAT_TIME;
gint64 timeLength = 0;
- // FIXME: We try to get the duration, but we do not trust the
+#if !GST_CHECK_VERSION(0, 10, 23)
+ // We try to get the duration, but we do not trust the
// return value of the query function only; the problem we are
// trying to work-around here is that pipelines in stream mode may
// not be able to figure out the duration, but still return true!
- // See https://bugs.webkit.org/show_bug.cgi?id=24639.
+ // See https://bugs.webkit.org/show_bug.cgi?id=24639 which has been
+ // fixed in gst-plugins-base 0.10.23
if (!gst_element_query_duration(m_playBin, &timeFormat, &timeLength) || timeLength <= 0) {
+#else
+ if (!gst_element_query_duration(m_playBin, &timeFormat, &timeLength)) {
+#endif
LOG_VERBOSE(Media, "Time duration query failed.");
- m_isStreaming = true;
return numeric_limits<float>::infinity();
}
@@ -215,22 +251,24 @@ float MediaPlayerPrivate::currentTime() const
{
if (!m_playBin)
return 0;
- // Necessary as sometimes, gstreamer return 0:00 at the EOS
- if (m_isEndReached)
- return m_endTime;
- float ret;
+ if (m_errorOccured)
+ return 0;
+
+ float ret = 0.0;
GstQuery* query = gst_query_new_position(GST_FORMAT_TIME);
- if (gst_element_query(m_playBin, query)) {
- gint64 position;
- gst_query_parse_position(query, 0, &position);
- ret = (float) (position / 1000000000.0);
- LOG_VERBOSE(Media, "Position %" GST_TIME_FORMAT, GST_TIME_ARGS(position));
- } else {
+ if (!gst_element_query(m_playBin, query)) {
LOG_VERBOSE(Media, "Position query failed...");
- ret = 0.0;
+ gst_query_unref(query);
+ return ret;
}
+
+ gint64 position;
+ gst_query_parse_position(query, 0, &position);
+ ret = (float) (position / 1000000000.0);
+ LOG_VERBOSE(Media, "Position %" GST_TIME_FORMAT, GST_TIME_ARGS(position));
+
gst_query_unref(query);
return ret;
@@ -246,35 +284,23 @@ void MediaPlayerPrivate::seek(float time)
if (m_isStreaming)
return;
+ if (m_errorOccured)
+ return;
+
LOG_VERBOSE(Media, "Seek: %" GST_TIME_FORMAT, GST_TIME_ARGS(sec));
- // FIXME: What happens when the seeked position is not available?
if (!gst_element_seek( m_playBin, m_rate,
GST_FORMAT_TIME,
(GstSeekFlags)(GST_SEEK_FLAG_FLUSH),
GST_SEEK_TYPE_SET, sec,
GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE))
LOG_VERBOSE(Media, "Seek to %f failed", time);
+ else
+ m_seeking = true;
}
void MediaPlayerPrivate::setEndTime(float time)
{
- if (!m_playBin)
- return;
- if (m_isStreaming)
- return;
- if (m_endTime != time) {
- m_endTime = time;
- GstClockTime start = (GstClockTime)(currentTime() * GST_SECOND);
- GstClockTime end = (GstClockTime)(time * GST_SECOND);
- LOG_VERBOSE(Media, "setEndTime: %" GST_TIME_FORMAT, GST_TIME_ARGS(end));
- // FIXME: What happens when the seeked position is not available?
- if (!gst_element_seek(m_playBin, m_rate,
- GST_FORMAT_TIME,
- (GstSeekFlags)(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE),
- GST_SEEK_TYPE_SET, start,
- GST_SEEK_TYPE_SET, end))
- LOG_VERBOSE(Media, "Seek to %f failed", time);
- }
+ notImplemented();
}
void MediaPlayerPrivate::startEndPointTimerIfNeeded()
@@ -294,12 +320,12 @@ void MediaPlayerPrivate::endPointTimerFired(Timer<MediaPlayerPrivate>*)
bool MediaPlayerPrivate::paused() const
{
- return !m_startedPlaying;
+ return m_paused;
}
bool MediaPlayerPrivate::seeking() const
{
- return false;
+ return m_seeking;
}
// Returns the size of the video
@@ -308,13 +334,28 @@ IntSize MediaPlayerPrivate::naturalSize() const
if (!hasVideo())
return IntSize();
- int x = 0, y = 0;
+ // TODO: handle possible clean aperture data. See
+ // https://bugzilla.gnome.org/show_bug.cgi?id=596571
+ // TODO: handle possible transformation matrix. See
+ // https://bugzilla.gnome.org/show_bug.cgi?id=596326
+ int width = 0, height = 0;
if (GstPad* pad = gst_element_get_static_pad(m_videoSink, "sink")) {
- gst_video_get_size(GST_PAD(pad), &x, &y);
+ gst_video_get_size(GST_PAD(pad), &width, &height);
+ GstCaps* caps = GST_PAD_CAPS(pad);
+ gfloat pixelAspectRatio;
+ gint pixelAspectRatioNumerator, pixelAspectRatioDenominator;
+
+ if (!gst_video_parse_caps_pixel_aspect_ratio(caps, &pixelAspectRatioNumerator,
+ &pixelAspectRatioDenominator))
+ pixelAspectRatioNumerator = pixelAspectRatioDenominator = 1;
+
+ pixelAspectRatio = (gfloat) pixelAspectRatioNumerator / (gfloat) pixelAspectRatioDenominator;
+ width *= pixelAspectRatio;
+ height /= pixelAspectRatio;
gst_object_unref(GST_OBJECT(pad));
}
- return IntSize(x, y);
+ return IntSize(width, height);
}
bool MediaPlayerPrivate::hasVideo() const
@@ -325,24 +366,31 @@ bool MediaPlayerPrivate::hasVideo() const
return currentVideo > -1;
}
+bool MediaPlayerPrivate::hasAudio() const
+{
+ gint currentAudio = -1;
+ if (m_playBin)
+ g_object_get(G_OBJECT(m_playBin), "current-audio", &currentAudio, NULL);
+ return currentAudio > -1;
+}
+
void MediaPlayerPrivate::setVolume(float volume)
{
m_volume = volume;
LOG_VERBOSE(Media, "Volume to %f", volume);
- setMuted(false);
+
+ if (!m_playBin)
+ return;
+
+ g_object_set(G_OBJECT(m_playBin), "volume", m_volume, NULL);
}
-void MediaPlayerPrivate::setMuted(bool b)
+void MediaPlayerPrivate::setMuted(bool mute)
{
if (!m_playBin)
return;
- if (b) {
- g_object_get(G_OBJECT(m_playBin), "volume", &m_volume, NULL);
- g_object_set(G_OBJECT(m_playBin), "volume", (double)0.0, NULL);
- } else
- g_object_set(G_OBJECT(m_playBin), "volume", m_volume, NULL);
-
+ g_object_set(G_OBJECT(m_playBin), "mute", mute, NULL);
}
void MediaPlayerPrivate::setRate(float rate)
@@ -351,17 +399,13 @@ void MediaPlayerPrivate::setRate(float rate)
gst_element_set_state(m_playBin, GST_STATE_PAUSED);
return;
}
+
if (m_isStreaming)
return;
m_rate = rate;
LOG_VERBOSE(Media, "Set Rate to %f", rate);
- if (!gst_element_seek(m_playBin, rate,
- GST_FORMAT_TIME,
- (GstSeekFlags)(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE),
- GST_SEEK_TYPE_SET, (GstClockTime) (currentTime() * GST_SECOND),
- GST_SEEK_TYPE_SET, (GstClockTime) (m_endTime * GST_SECOND)))
- LOG_VERBOSE(Media, "Set Rate to %f failed", rate);
+ seek(currentTime());
}
int MediaPlayerPrivate::dataRate() const
@@ -380,16 +424,20 @@ MediaPlayer::ReadyState MediaPlayerPrivate::readyState() const
return m_readyState;
}
-float MediaPlayerPrivate::maxTimeBuffered() const
+PassRefPtr<TimeRanges> MediaPlayerPrivate::buffered() const
{
- notImplemented();
- LOG_VERBOSE(Media, "maxTimeBuffered");
- // rtsp streams are not buffered
- return m_isStreaming ? 0 : maxTimeLoaded();
+ RefPtr<TimeRanges> timeRanges = TimeRanges::create();
+ float loaded = maxTimeLoaded();
+ if (!m_errorOccured && !m_isStreaming && loaded > 0)
+ timeRanges->add(0, loaded);
+ return timeRanges.release();
}
float MediaPlayerPrivate::maxTimeSeekable() const
{
+ if (m_errorOccured)
+ return 0.0;
+
// TODO
LOG_VERBOSE(Media, "maxTimeSeekable");
if (m_isStreaming)
@@ -400,6 +448,9 @@ float MediaPlayerPrivate::maxTimeSeekable() const
float MediaPlayerPrivate::maxTimeLoaded() const
{
+ if (m_errorOccured)
+ return 0.0;
+
// TODO
LOG_VERBOSE(Media, "maxTimeLoaded");
notImplemented();
@@ -416,29 +467,30 @@ unsigned MediaPlayerPrivate::bytesLoaded() const
float maxTime = maxTimeLoaded();
if (!dur)
return 0;*/
+
return 1;//totalBytes() * maxTime / dur;
}
bool MediaPlayerPrivate::totalBytesKnown() const
{
- notImplemented();
LOG_VERBOSE(Media, "totalBytesKnown");
return totalBytes() > 0;
}
unsigned MediaPlayerPrivate::totalBytes() const
{
- notImplemented();
LOG_VERBOSE(Media, "totalBytes");
- if (!m_playBin)
+ if (!m_source)
return 0;
- if (!m_source)
+ if (m_errorOccured)
return 0;
- // Do something with m_source to get the total bytes of the media
+ GstFormat fmt = GST_FORMAT_BYTES;
+ gint64 length = 0;
+ gst_element_query_duration(m_source, &fmt, &length);
- return 100;
+ return length;
}
void MediaPlayerPrivate::cancelLoad()
@@ -452,17 +504,21 @@ void MediaPlayerPrivate::updateStates()
// the state of GStreamer, therefore, when in PAUSED state,
// we are sure we can display the first frame and go to play
+ if (!m_playBin)
+ return;
+
+ if (m_errorOccured)
+ return;
+
MediaPlayer::NetworkState oldNetworkState = m_networkState;
MediaPlayer::ReadyState oldReadyState = m_readyState;
GstState state;
GstState pending;
- if (!m_playBin)
- return;
-
GstStateChangeReturn ret = gst_element_get_state(m_playBin,
&state, &pending, 250 * GST_NSECOND);
+ bool shouldUpdateAfterSeek = false;
switch (ret) {
case GST_STATE_CHANGE_SUCCESS:
LOG_VERBOSE(Media, "State: %s, pending: %s",
@@ -474,6 +530,16 @@ void MediaPlayerPrivate::updateStates()
} else if (state == GST_STATE_PAUSED)
m_readyState = MediaPlayer::HaveEnoughData;
+ if (state == GST_STATE_PLAYING)
+ m_paused = false;
+ else
+ m_paused = true;
+
+ if (m_seeking) {
+ shouldUpdateAfterSeek = true;
+ m_seeking = false;
+ }
+
m_networkState = MediaPlayer::Loaded;
g_object_get(m_playBin, "source", &m_source, NULL);
@@ -486,11 +552,17 @@ void MediaPlayerPrivate::updateStates()
gst_element_state_get_name(pending));
// Change in progress
return;
- break;
+ case GST_STATE_CHANGE_FAILURE:
+ LOG_VERBOSE(Media, "Failure: State: %s, pending: %s",
+ gst_element_state_get_name(state),
+ gst_element_state_get_name(pending));
+ // Change failed
+ return;
case GST_STATE_CHANGE_NO_PREROLL:
LOG_VERBOSE(Media, "No preroll: State: %s, pending: %s",
gst_element_state_get_name(state),
gst_element_state_get_name(pending));
+
if (state == GST_STATE_READY) {
m_readyState = MediaPlayer::HaveFutureData;
} else if (state == GST_STATE_PAUSED)
@@ -506,6 +578,9 @@ void MediaPlayerPrivate::updateStates()
if (seeking())
m_readyState = MediaPlayer::HaveNothing;
+ if (shouldUpdateAfterSeek)
+ timeChanged();
+
if (m_networkState != oldNetworkState) {
LOG_VERBOSE(Media, "Network State Changed from %u to %u",
oldNetworkState, m_networkState);
@@ -546,15 +621,14 @@ void MediaPlayerPrivate::volumeChanged()
void MediaPlayerPrivate::didEnd()
{
- m_isEndReached = true;
- pause();
timeChanged();
}
-void MediaPlayerPrivate::loadingFailed()
+void MediaPlayerPrivate::loadingFailed(MediaPlayer::NetworkState error)
{
- if (m_networkState != MediaPlayer::NetworkError) {
- m_networkState = MediaPlayer::NetworkError;
+ m_errorOccured = true;
+ if (m_networkState != error) {
+ m_networkState = error;
m_player->networkStateChanged();
}
if (m_readyState != MediaPlayer::HaveNothing) {
@@ -565,7 +639,18 @@ void MediaPlayerPrivate::loadingFailed()
void MediaPlayerPrivate::setSize(const IntSize& size)
{
+ // Destroy and re-create the cairo surface only if the size
+ // changed.
+ if (size != m_size) {
+ if (m_surface)
+ cairo_surface_destroy(m_surface);
+ m_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, size.width(),
+ size.height());
+ g_object_set(m_videoSink, "surface", m_surface, 0);
+ }
+
m_size = size;
+
}
void MediaPlayerPrivate::setVisible(bool visible)
@@ -586,11 +671,12 @@ void MediaPlayerPrivate::paint(GraphicsContext* context, const IntRect& rect)
if (!m_visible)
return;
- //TODO: m_size vs rect?
cairo_t* cr = context->platformContext();
cairo_save(cr);
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+
+ // paint the rectangle on the context and draw the surface inside.
cairo_translate(cr, rect.x(), rect.y());
cairo_rectangle(cr, 0, 0, rect.width(), rect.height());
cairo_set_source_surface(cr, m_surface, 0, 0);
@@ -598,24 +684,124 @@ void MediaPlayerPrivate::paint(GraphicsContext* context, const IntRect& rect)
cairo_restore(cr);
}
+static HashSet<String> mimeTypeCache()
+{
+
+ do_gst_init();
+
+ static HashSet<String> cache;
+ static bool typeListInitialized = false;
+
+ if (!typeListInitialized) {
+ // These subtypes are already beeing supported by WebKit itself
+ HashSet<String> ignoredApplicationSubtypes;
+ ignoredApplicationSubtypes.add(String("javascript"));
+ ignoredApplicationSubtypes.add(String("ecmascript"));
+ ignoredApplicationSubtypes.add(String("x-javascript"));
+ ignoredApplicationSubtypes.add(String("xml"));
+ ignoredApplicationSubtypes.add(String("xhtml+xml"));
+ ignoredApplicationSubtypes.add(String("rss+xml"));
+ ignoredApplicationSubtypes.add(String("atom+xml"));
+ ignoredApplicationSubtypes.add(String("x-ftp-directory"));
+ ignoredApplicationSubtypes.add(String("x-java-applet"));
+ ignoredApplicationSubtypes.add(String("x-java-bean"));
+ ignoredApplicationSubtypes.add(String("x-java-vm"));
+ ignoredApplicationSubtypes.add(String("x-shockwave-flash"));
+
+ GList* factories = gst_type_find_factory_get_list();
+ for (GList* iterator = factories; iterator; iterator = iterator->next) {
+ GstTypeFindFactory* factory = GST_TYPE_FIND_FACTORY(iterator->data);
+ GstCaps* caps = gst_type_find_factory_get_caps(factory);
+
+ // Splitting the capability by comma and taking the first part
+ // as capability can be something like "audio/x-wavpack, framed=(boolean)false"
+ GOwnPtr<gchar> capabilityString(gst_caps_to_string(caps));
+ gchar** capability = g_strsplit(capabilityString.get(), ",", 2);
+ gchar** mimetype = g_strsplit(capability[0], "/", 2);
+
+ // GStreamer plugins can be capable of supporting types which WebKit supports
+ // by default. In that case, we should not consider these types supportable by GStreamer.
+ // Examples of what GStreamer can support but should not be added:
+ // text/plain, text/html, image/jpeg, application/xml
+ if (g_str_equal(mimetype[0], "audio") ||
+ g_str_equal(mimetype[0], "video") ||
+ (g_str_equal(mimetype[0], "application") &&
+ !ignoredApplicationSubtypes.contains(String(mimetype[1])))) {
+ cache.add(String(capability[0]));
+
+ // These formats are supported by GStreamer, but not correctly advertised
+ if (g_str_equal(capability[0], "video/x-h264") ||
+ g_str_equal(capability[0], "audio/x-m4a")) {
+ cache.add(String("video/mp4"));
+ cache.add(String("audio/aac"));
+ }
+
+ if (g_str_equal(capability[0], "video/x-theora"))
+ cache.add(String("video/ogg"));
+
+ if (g_str_equal(capability[0], "audio/x-wav"))
+ cache.add(String("audio/wav"));
+
+ if (g_str_equal(capability[0], "audio/mpeg")) {
+ // This is what we are handling: mpegversion=(int)1, layer=(int)[ 1, 3 ]
+ gchar** versionAndLayer = g_strsplit(capability[1], ",", 2);
+
+ if (g_str_has_suffix (versionAndLayer[0], "(int)1")) {
+ for (int i = 0; versionAndLayer[1][i] != '\0'; i++) {
+ if (versionAndLayer[1][i] == '1')
+ cache.add(String("audio/mp1"));
+ else if (versionAndLayer[1][i] == '2')
+ cache.add(String("audio/mp2"));
+ else if (versionAndLayer[1][i] == '3')
+ cache.add(String("audio/mp3"));
+ }
+ }
+
+ g_strfreev(versionAndLayer);
+ }
+ }
+
+ g_strfreev(capability);
+ g_strfreev(mimetype);
+ }
+
+ gst_plugin_feature_list_free(factories);
+ typeListInitialized = true;
+ }
+
+ return cache;
+}
+
void MediaPlayerPrivate::getSupportedTypes(HashSet<String>& types)
{
- // FIXME: query the engine to see what types are supported
- notImplemented();
- types.add(String("video/x-theora+ogg"));
+ types = mimeTypeCache();
}
MediaPlayer::SupportsType MediaPlayerPrivate::supportsType(const String& type, const String& codecs)
{
- // FIXME: query the engine to see what types are supported
- notImplemented();
- return type == "video/x-theora+ogg" ? (codecs.isEmpty() ? MediaPlayer::MayBeSupported : MediaPlayer::IsSupported) : MediaPlayer::IsNotSupported;
+ if (type.isNull() || type.isEmpty())
+ return MediaPlayer::IsNotSupported;
+
+ // spec says we should not return "probably" if the codecs string is empty
+ if (mimeTypeCache().contains(type))
+ return codecs.isEmpty() ? MediaPlayer::MayBeSupported : MediaPlayer::IsSupported;
+ return MediaPlayer::IsNotSupported;
+}
+
+bool MediaPlayerPrivate::hasSingleSecurityOrigin() const
+{
+ return true;
+}
+
+bool MediaPlayerPrivate::supportsFullscreen() const
+{
+ return true;
}
void MediaPlayerPrivate::createGSTPlayBin(String url)
{
ASSERT(!m_playBin);
- m_playBin = gst_element_factory_make("playbin", "play");
+ m_playBin = gst_element_factory_make("playbin2", "play");
GstBus* bus = gst_pipeline_get_bus(GST_PIPELINE(m_playBin));
gst_bus_add_signal_watch(bus);
@@ -627,10 +813,12 @@ void MediaPlayerPrivate::createGSTPlayBin(String url)
g_object_set(G_OBJECT(m_playBin), "uri", url.utf8().data(), NULL);
- GstElement* audioSink = gst_element_factory_make("gconfaudiosink", 0);
m_videoSink = webkit_video_sink_new(m_surface);
- g_object_set(m_playBin, "audio-sink", audioSink, NULL);
+ // This ref is to protect the sink from being destroyed before we stop the idle it
+ // creates internally. See the comment in ~MediaPlayerPrivate.
+ g_object_ref(m_videoSink);
+
g_object_set(m_playBin, "video-sink", m_videoSink, NULL);
g_signal_connect(m_videoSink, "repaint-requested", G_CALLBACK(mediaPlayerPrivateRepaintCallback), this);
@@ -641,4 +829,3 @@ void MediaPlayerPrivate::createGSTPlayBin(String url)
}
#endif
-
diff --git a/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h b/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h
index 8842f84..d305759 100644
--- a/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h
+++ b/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h
@@ -56,6 +56,7 @@ namespace WebCore {
IntSize naturalSize() const;
bool hasVideo() const;
+ bool hasAudio() const;
void load(const String &url);
void cancelLoad();
@@ -80,7 +81,7 @@ namespace WebCore {
MediaPlayer::NetworkState networkState() const;
MediaPlayer::ReadyState readyState() const;
- float maxTimeBuffered() const;
+ PassRefPtr<TimeRanges> buffered() const;
float maxTimeSeekable() const;
unsigned bytesLoaded() const;
bool totalBytesKnown() const;
@@ -95,11 +96,15 @@ namespace WebCore {
void timeChanged();
void volumeChanged();
void didEnd();
- void loadingFailed();
+ void loadingFailed(MediaPlayer::NetworkState);
void repaint();
void paint(GraphicsContext*, const IntRect&);
+ bool hasSingleSecurityOrigin() const;
+
+ bool supportsFullscreen() const;
+
private:
MediaPlayerPrivate(MediaPlayer*);
static MediaPlayerPrivateInterface* create(MediaPlayer* player);
@@ -132,6 +137,10 @@ namespace WebCore {
IntSize m_size;
bool m_visible;
cairo_surface_t* m_surface;
+
+ bool m_paused;
+ bool m_seeking;
+ bool m_errorOccured;
};
}
diff --git a/WebCore/platform/graphics/gtk/SimpleFontDataGtk.cpp b/WebCore/platform/graphics/gtk/SimpleFontDataGtk.cpp
index a77c1cf..9a616f4 100644
--- a/WebCore/platform/graphics/gtk/SimpleFontDataGtk.cpp
+++ b/WebCore/platform/graphics/gtk/SimpleFontDataGtk.cpp
@@ -50,9 +50,9 @@ void SimpleFontData::platformInit()
cairo_font_extents_t font_extents;
cairo_text_extents_t text_extents;
cairo_scaled_font_extents(m_platformData.m_scaledFont, &font_extents);
- m_ascent = static_cast<int>(font_extents.ascent);
- m_descent = static_cast<int>(font_extents.descent);
- m_lineSpacing = static_cast<int>(font_extents.height);
+ m_ascent = static_cast<int>(lroundf(font_extents.ascent));
+ m_descent = static_cast<int>(lroundf(font_extents.descent));
+ m_lineSpacing = static_cast<int>(lroundf(font_extents.height));
// There seems to be some rounding error in cairo (or in how we
// use cairo) with some fonts, like DejaVu Sans Mono, which makes
// cairo report a height smaller than ascent + descent, which is
@@ -63,7 +63,7 @@ void SimpleFontData::platformInit()
cairo_scaled_font_text_extents(m_platformData.m_scaledFont, "x", &text_extents);
m_xHeight = text_extents.height;
cairo_scaled_font_text_extents(m_platformData.m_scaledFont, " ", &text_extents);
- m_spaceWidth = static_cast<int>(text_extents.x_advance);
+ m_spaceWidth = static_cast<float>(text_extents.x_advance);
m_lineGap = m_lineSpacing - m_ascent - m_descent;
m_syntheticBoldOffset = m_platformData.syntheticBold() ? 1.0f : 0.f;
}
@@ -130,10 +130,4 @@ float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
return w;
}
-void SimpleFontData::setFont(cairo_t* cr) const
-{
- ASSERT(cr);
- m_platformData.setFont(cr);
-}
-
}
diff --git a/WebCore/platform/graphics/gtk/SimpleFontDataPango.cpp b/WebCore/platform/graphics/gtk/SimpleFontDataPango.cpp
index e57d9e6..975143e 100644
--- a/WebCore/platform/graphics/gtk/SimpleFontDataPango.cpp
+++ b/WebCore/platform/graphics/gtk/SimpleFontDataPango.cpp
@@ -49,9 +49,9 @@ void SimpleFontData::platformInit()
cairo_font_extents_t font_extents;
cairo_text_extents_t text_extents;
cairo_scaled_font_extents(m_platformData.m_scaledFont, &font_extents);
- m_ascent = static_cast<int>(font_extents.ascent);
- m_descent = static_cast<int>(font_extents.descent);
- m_lineSpacing = static_cast<int>(font_extents.height);
+ m_ascent = static_cast<int>(lroundf(font_extents.ascent));
+ m_descent = static_cast<int>(lroundf(font_extents.descent));
+ m_lineSpacing = static_cast<int>(lroundf(font_extents.height));
// There seems to be some rounding error in cairo (or in how we
// use cairo) with some fonts, like DejaVu Sans Mono, which makes
// cairo report a height smaller than ascent + descent, which is
@@ -62,7 +62,7 @@ void SimpleFontData::platformInit()
cairo_scaled_font_text_extents(m_platformData.m_scaledFont, "x", &text_extents);
m_xHeight = text_extents.height;
cairo_scaled_font_text_extents(m_platformData.m_scaledFont, " ", &text_extents);
- m_spaceWidth = static_cast<int>(text_extents.x_advance);
+ m_spaceWidth = static_cast<float>(text_extents.x_advance);
m_lineGap = m_lineSpacing - m_ascent - m_descent;
m_syntheticBoldOffset = m_platformData.syntheticBold() ? 1.0f : 0.f;
}
@@ -133,10 +133,4 @@ float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
return w;
}
-void SimpleFontData::setFont(cairo_t* cr) const
-{
- ASSERT(cr);
- m_platformData.setFont(cr);
-}
-
}
diff --git a/WebCore/platform/graphics/gtk/VideoSinkGStreamer.cpp b/WebCore/platform/graphics/gtk/VideoSinkGStreamer.cpp
index f049998..fb86fe9 100644
--- a/WebCore/platform/graphics/gtk/VideoSinkGStreamer.cpp
+++ b/WebCore/platform/graphics/gtk/VideoSinkGStreamer.cpp
@@ -33,8 +33,14 @@
#include <gst/video/video.h>
static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE("sink",
- GST_PAD_SINK, GST_PAD_ALWAYS,
- GST_STATIC_CAPS(GST_VIDEO_CAPS_RGBx ";" GST_VIDEO_CAPS_BGRx));
+ GST_PAD_SINK, GST_PAD_ALWAYS,
+// CAIRO_FORMAT_RGB24 used to render the video buffers is little/big endian dependant.
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+ GST_STATIC_CAPS(GST_VIDEO_CAPS_BGRx)
+#else
+ GST_STATIC_CAPS(GST_VIDEO_CAPS_xRGB)
+#endif
+);
GST_DEBUG_CATEGORY_STATIC(webkit_video_sink_debug);
#define GST_CAT_DEFAULT webkit_video_sink_debug
@@ -102,9 +108,14 @@ webkit_video_sink_init(WebKitVideoSink* sink, WebKitVideoSinkClass* klass)
static gboolean
webkit_video_sink_idle_func(gpointer data)
{
- WebKitVideoSink* sink = WEBKIT_VIDEO_SINK(data);
+ WebKitVideoSink* sink = reinterpret_cast<WebKitVideoSink*>(data);
WebKitVideoSinkPrivate* priv = sink->priv;
GstBuffer* buffer;
+ GstCaps* caps;
+ GstVideoFormat format;
+ gint par_n, par_d;
+ gfloat par;
+ gint bwidth, bheight;
if (!priv->async_queue)
return FALSE;
@@ -113,19 +124,35 @@ webkit_video_sink_idle_func(gpointer data)
if (!buffer || G_UNLIKELY(!GST_IS_BUFFER(buffer)))
return FALSE;
+ caps = GST_BUFFER_CAPS(buffer);
+ if (!gst_video_format_parse_caps(caps, &format, &bwidth, &bheight)) {
+ GST_ERROR_OBJECT(sink, "Unknown video format in buffer caps '%s'",
+ gst_caps_to_string(caps));
+ return FALSE;
+ }
+
+ if (!gst_video_parse_caps_pixel_aspect_ratio(caps, &par_n, &par_d))
+ par_n = par_d = 1;
+
+ par = (gfloat) par_n / (gfloat) par_d;
+
// TODO: consider priv->rgb_ordering?
- cairo_surface_t* src = cairo_image_surface_create_for_data(GST_BUFFER_DATA(buffer), CAIRO_FORMAT_RGB24, priv->width, priv->height, (4 * priv->width + 3) & ~3);
+ cairo_surface_t* src = cairo_image_surface_create_for_data(GST_BUFFER_DATA(buffer),
+ CAIRO_FORMAT_RGB24,
+ bwidth, bheight,
+ 4 * bwidth);
// TODO: We copy the data twice right now. This could be easily improved.
cairo_t* cr = cairo_create(priv->surface);
+ cairo_scale(cr, par, 1.0 / par);
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
cairo_set_source_surface(cr, src, 0, 0);
cairo_surface_destroy(src);
cairo_rectangle(cr, 0, 0, priv->width, priv->height);
cairo_fill(cr);
cairo_destroy(cr);
-
gst_buffer_unref(buffer);
+ g_async_queue_unref(priv->async_queue);
g_signal_emit(sink, webkit_video_sink_signals[REPAINT_REQUESTED], 0);
@@ -138,6 +165,7 @@ webkit_video_sink_render(GstBaseSink* bsink, GstBuffer* buffer)
WebKitVideoSink* sink = WEBKIT_VIDEO_SINK(bsink);
WebKitVideoSinkPrivate* priv = sink->priv;
+ g_async_queue_ref(priv->async_queue);
g_async_queue_push(priv->async_queue, gst_buffer_ref(buffer));
g_idle_add_full(G_PRIORITY_HIGH_IDLE, webkit_video_sink_idle_func, sink, 0);
@@ -151,9 +179,7 @@ webkit_video_sink_set_caps(GstBaseSink* bsink, GstCaps* caps)
WebKitVideoSinkPrivate* priv = sink->priv;
GstStructure* structure;
gboolean ret;
- const GValue* fps;
- const GValue* par;
- gint width, height;
+ gint width, height, fps_n, fps_d;
int red_mask;
GstCaps* intersection = gst_caps_intersect(gst_static_pad_template_get_caps(&sinktemplate), caps);
@@ -167,25 +193,19 @@ webkit_video_sink_set_caps(GstBaseSink* bsink, GstCaps* caps)
ret = gst_structure_get_int(structure, "width", &width);
ret &= gst_structure_get_int(structure, "height", &height);
- fps = gst_structure_get_value(structure, "framerate");
- ret &= (fps != 0);
-
- par = gst_structure_get_value(structure, "pixel-aspect-ratio");
- if (!ret)
- return FALSE;
+ /* We dont yet use fps but handy to have */
+ ret &= gst_structure_get_fraction(structure, "framerate",
+ &fps_n, &fps_d);
+ g_return_val_if_fail(ret, FALSE);
priv->width = width;
priv->height = height;
+ priv->fps_n = fps_n;
+ priv->fps_d = fps_d;
- /* We dont yet use fps or pixel aspect into but handy to have */
- priv->fps_n = gst_value_get_fraction_numerator(fps);
- priv->fps_d = gst_value_get_fraction_denominator(fps);
-
- if (par) {
- priv->par_n = gst_value_get_fraction_numerator(par);
- priv->par_d = gst_value_get_fraction_denominator(par);
- } else
+ if (!gst_structure_get_fraction(structure, "pixel-aspect-ratio",
+ &priv->par_n, &priv->par_d))
priv->par_n = priv->par_d = 1;
gst_structure_get_int(structure, "red_mask", &red_mask);
@@ -265,6 +285,8 @@ webkit_video_sink_stop(GstBaseSink* base_sink)
g_async_queue_unlock(priv->async_queue);
+ g_idle_remove_by_data(base_sink);
+
return TRUE;
}
diff --git a/WebCore/platform/graphics/haiku/ColorHaiku.cpp b/WebCore/platform/graphics/haiku/ColorHaiku.cpp
new file mode 100644
index 0000000..a9ac186
--- /dev/null
+++ b/WebCore/platform/graphics/haiku/ColorHaiku.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2007 Ryan Leavengood <leavengood@gmail.com>
+ *
+ * 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 "Color.h"
+
+#include <InterfaceDefs.h>
+
+
+namespace WebCore {
+
+Color::Color(const rgb_color& color)
+ : m_color(makeRGBA(color.red, color.green, color.blue, color.alpha))
+ , m_valid(true)
+{
+}
+
+Color::operator rgb_color() const
+{
+ return make_color(red(), green(), blue(), alpha());
+}
+
+
+Color focusRingColor()
+{
+ return Color(keyboard_navigation_color());
+}
+
+} // namespace WebCore
+
diff --git a/WebCore/platform/graphics/haiku/FloatPointHaiku.cpp b/WebCore/platform/graphics/haiku/FloatPointHaiku.cpp
new file mode 100644
index 0000000..0f50898
--- /dev/null
+++ b/WebCore/platform/graphics/haiku/FloatPointHaiku.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2007 Ryan Leavengood <leavengood@gmail.com>
+ *
+ * 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 "FloatPoint.h"
+
+#include <Point.h>
+
+
+namespace WebCore {
+
+FloatPoint::FloatPoint(const BPoint& point)
+ : m_x(point.x)
+ , m_y(point.y)
+{
+}
+
+FloatPoint::operator BPoint() const
+{
+ return BPoint(m_x, m_y);
+}
+
+} // namespace WebCore
+
diff --git a/WebCore/platform/graphics/haiku/FloatRectHaiku.cpp b/WebCore/platform/graphics/haiku/FloatRectHaiku.cpp
new file mode 100644
index 0000000..67af3af
--- /dev/null
+++ b/WebCore/platform/graphics/haiku/FloatRectHaiku.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2007 Ryan Leavengood <leavengood@gmail.com>
+ *
+ * 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 "FloatRect.h"
+
+#include <Rect.h>
+
+
+namespace WebCore {
+
+FloatRect::FloatRect(const BRect& rect)
+ : m_location(rect.LeftTop())
+ , m_size(rect.Width(), rect.Height())
+{
+}
+
+FloatRect::operator BRect() const
+{
+ return BRect(BPoint(x(), y()), BSize(width(), height()));
+}
+
+} // namespace WebCore
+
diff --git a/WebCore/platform/graphics/haiku/FontCacheHaiku.cpp b/WebCore/platform/graphics/haiku/FontCacheHaiku.cpp
new file mode 100644
index 0000000..b99bf42
--- /dev/null
+++ b/WebCore/platform/graphics/haiku/FontCacheHaiku.cpp
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2006 Dirk Mueller <mueller@kde.org>
+ * Copyright (C) 2007 Ryan Leavengood <leavengood@gmail.com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "FontCache.h"
+
+#include "Font.h"
+#include "FontData.h"
+#include "FontPlatformData.h"
+#include "NotImplemented.h"
+#include <String.h>
+
+
+namespace WebCore {
+
+void FontCache::platformInit()
+{
+}
+
+const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length)
+{
+ FontPlatformData data(font.fontDescription(), font.family().family());
+ return getCachedFontData(&data);
+}
+
+FontPlatformData* FontCache::getSimilarFontPlatformData(const Font& font)
+{
+ notImplemented();
+ return 0;
+}
+
+FontPlatformData* FontCache::getLastResortFallbackFont(const FontDescription& fontDescription)
+{
+ // FIXME: Would be even better to somehow get the user's default font here.
+ // For now we'll pick the default that the user would get without changing any prefs.
+ static AtomicString defaultString("DejaVu Serif");
+ return getCachedFontPlatformData(fontDescription, defaultString);
+}
+
+FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family)
+{
+ return new FontPlatformData(fontDescription, family);
+}
+
+void FontCache::getTraitsInFamily(const AtomicString& familyName, Vector<unsigned>& traitsMasks)
+{
+ notImplemented();
+}
+
+} // namespace WebCore
+
diff --git a/WebCore/platform/graphics/haiku/FontCustomPlatformData.cpp b/WebCore/platform/graphics/haiku/FontCustomPlatformData.cpp
new file mode 100644
index 0000000..6008bb1
--- /dev/null
+++ b/WebCore/platform/graphics/haiku/FontCustomPlatformData.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2008 Alp Toker <alp@atoker.com>
+ *
+ * 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 "FontCustomPlatformData.h"
+
+#include "SharedBuffer.h"
+#include "FontPlatformData.h"
+
+
+namespace WebCore {
+
+FontCustomPlatformData::~FontCustomPlatformData()
+{
+}
+
+FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontRenderingMode)
+{
+ return FontPlatformData(size, bold, italic);
+}
+
+FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
+{
+ // FIXME: We need support in Haiku to read fonts from memory to implement this.
+ return 0;
+}
+
+}
diff --git a/WebCore/platform/graphics/haiku/FontCustomPlatformData.h b/WebCore/platform/graphics/haiku/FontCustomPlatformData.h
new file mode 100644
index 0000000..c5a814e
--- /dev/null
+++ b/WebCore/platform/graphics/haiku/FontCustomPlatformData.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2008 Alp Toker <alp@atoker.com>
+ *
+ * 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 FontCustomPlatformData_h
+#define FontCustomPlatformData_h
+
+#include "FontRenderingMode.h"
+#include <wtf/Noncopyable.h>
+
+namespace WebCore {
+
+ class FontPlatformData;
+ class SharedBuffer;
+
+ struct FontCustomPlatformData : Noncopyable {
+ public:
+ FontCustomPlatformData() { }
+ ~FontCustomPlatformData();
+
+ FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontRenderingMode = NormalRenderingMode);
+ };
+
+ FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer*);
+
+}
+
+#endif
diff --git a/WebCore/platform/graphics/haiku/FontHaiku.cpp b/WebCore/platform/graphics/haiku/FontHaiku.cpp
new file mode 100644
index 0000000..48744d9
--- /dev/null
+++ b/WebCore/platform/graphics/haiku/FontHaiku.cpp
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2007 Ryan Leavengood <leavengood@gmail.com>
+ *
+ * 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 "Font.h"
+
+#include "FontData.h"
+#include "FontDescription.h"
+#include "FontSelector.h"
+#include "GraphicsContext.h"
+#include "NotImplemented.h"
+#include <Font.h>
+#include <String.h>
+#include <View.h>
+
+
+// FIXME: Temp routine to convert unicode character to UTF8.
+int charUnicodeToUTF8HACK(unsigned short glyph, char* out)
+{
+ int i = 0;
+
+ if (glyph < 0x0080)
+ out[i++] = static_cast<char>(glyph);
+ else if (glyph < 0x0800) { // 2 bytes
+ out[i++] = 0xc0 | (glyph >> 6);
+ out[i++] = 0x80 | (glyph & 0x3F);
+ } else if (glyph > 0x0800) { // 3 bytes
+ out[i++] = 0xe0 | (glyph >> 12);
+ out[i++] = 0x80 | ((glyph >> 6) & 0x3F);
+ out[i++] = 0x80 | (glyph & 0x3F);
+ }
+
+ out[i] = '\0';
+ return i;
+}
+
+namespace WebCore {
+
+bool Font::canReturnFallbackFontsForComplexText()
+{
+ return false;
+}
+
+void Font::drawGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* font,
+ const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point) const
+{
+ Color color = graphicsContext->fillColor();
+ BView* view = graphicsContext->platformContext();
+ BFont* m_font = font->platformData().font();
+
+ graphicsContext->setCompositeOperation(CompositeSourceOver);
+ view->SetHighColor(color);
+ view->SetFont(m_font);
+
+ GlyphBufferGlyph* glyphs = const_cast<GlyphBufferGlyph*>(glyphBuffer.glyphs(from));
+ float offset = point.x();
+ for (int i = 0; i < numGlyphs; i++) {
+ char out[4];
+ charUnicodeToUTF8HACK(glyphs[i], out);
+
+ view->DrawString(out, sizeof(out), BPoint(offset, point.y()));
+ offset += glyphBuffer.advanceAt(from + i);
+ }
+}
+
+void Font::drawComplexText(GraphicsContext* ctx, const TextRun& run, const FloatPoint& point,
+ int from, int to) const
+{
+ notImplemented();
+}
+
+
+float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts) const
+{
+ notImplemented();
+ return 0;
+}
+
+FloatRect Font::selectionRectForComplexText(const TextRun&, const IntPoint&, int, int, int) const
+{
+ notImplemented();
+ return FloatRect();
+}
+
+int Font::offsetForPositionForComplexText(const TextRun&, int, bool) const
+{
+ notImplemented();
+ return 0;
+}
+
+} // namespace WebCore
+
diff --git a/WebCore/platform/graphics/haiku/FontPlatformData.h b/WebCore/platform/graphics/haiku/FontPlatformData.h
new file mode 100644
index 0000000..9feab8e
--- /dev/null
+++ b/WebCore/platform/graphics/haiku/FontPlatformData.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.
+ * Copyright (C) 2006 Zack Rusin <zack@kde.org>
+ * Copyright (C) 2006 Dirk Mueller <mueller@kde.org>
+ * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2007 Ryan Leavengood <leavengood@gmail.com>
+ * Copyright (C) 2009 Maxime Simon <simon.maxime@gmail.com>
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef FontPlatformData_H
+#define FontPlatformData_H
+
+#include "FontDescription.h"
+#include "GlyphBuffer.h"
+#include <interface/Font.h>
+
+namespace WebCore {
+
+ class FontPlatformData {
+ public:
+ FontPlatformData(WTF::HashTableDeletedValueType)
+ : m_font(hashTableDeletedFontValue())
+ { }
+
+ FontPlatformData()
+ : m_font(0)
+ { }
+
+ FontPlatformData(const FontDescription&, const AtomicString& family);
+ FontPlatformData(float size, bool bold, bool oblique);
+ FontPlatformData(const FontPlatformData&);
+
+ ~FontPlatformData();
+
+ BFont* font() const { return m_font; }
+
+ bool isFixedPitch();
+ float size() const { return m_size; }
+ bool bold() const { return m_bold; }
+ bool oblique() const { return m_oblique; }
+
+ unsigned hash() const;
+ bool isHashTableDeletedValue() const;
+
+ bool operator==(const FontPlatformData&) const;
+
+#ifndef NDEBUG
+ String description() const;
+#endif
+
+ BFont* m_font;
+ float m_size;
+ bool m_bold;
+ bool m_oblique;
+
+ private:
+ static BFont* hashTableDeletedFontValue() { return reinterpret_cast<BFont*>(-1); }
+ };
+
+} // namespace WebCore
+
+#endif
+
diff --git a/WebCore/platform/graphics/haiku/GradientHaiku.cpp b/WebCore/platform/graphics/haiku/GradientHaiku.cpp
new file mode 100644
index 0000000..469a17f
--- /dev/null
+++ b/WebCore/platform/graphics/haiku/GradientHaiku.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2008 Kevin Ollivier <kevino@theolliviers.com> All rights reserved.
+ * Copyright (C) 2009 Maxime Simon <simon.maxime@theolliviers.com>
+ *
+ * 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 "Gradient.h"
+
+#include "CSSParser.h"
+#include "NotImplemented.h"
+
+
+namespace WebCore {
+
+void Gradient::platformDestroy()
+{
+ notImplemented();
+}
+
+PlatformGradient Gradient::platformGradient()
+{
+ notImplemented();
+ return 0;
+}
+
+void Gradient::fill(GraphicsContext*, const FloatRect&)
+{
+ notImplemented();
+}
+
+} // namespace WebCore
+
diff --git a/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp b/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp
new file mode 100644
index 0000000..d785ef4
--- /dev/null
+++ b/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp
@@ -0,0 +1,536 @@
+/*
+ * Copyright (C) 2007 Ryan Leavengood <leavengood@gmail.com>
+ *
+ * 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 "GraphicsContext.h"
+
+#include "CString.h"
+#include "Color.h"
+#include "Font.h"
+#include "FontData.h"
+#include "NotImplemented.h"
+#include "Path.h"
+#include "Pen.h"
+#include "TransformationMatrix.h"
+#include <GraphicsDefs.h>
+#include <Region.h>
+#include <View.h>
+#include <Window.h>
+#include <stdio.h>
+
+
+namespace WebCore {
+
+class GraphicsContextPlatformPrivate {
+public:
+ GraphicsContextPlatformPrivate(BView* view);
+ ~GraphicsContextPlatformPrivate();
+
+ BView* m_view;
+};
+
+GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate(BView* view)
+ : m_view(view)
+{
+}
+
+GraphicsContextPlatformPrivate::~GraphicsContextPlatformPrivate()
+{
+}
+
+GraphicsContext::GraphicsContext(PlatformGraphicsContext* context)
+ : m_common(createGraphicsContextPrivate())
+ , m_data(new GraphicsContextPlatformPrivate(context))
+{
+ setPaintingDisabled(!context);
+}
+
+GraphicsContext::~GraphicsContext()
+{
+ destroyGraphicsContextPrivate(m_common);
+ delete m_data;
+}
+
+PlatformGraphicsContext* GraphicsContext::platformContext() const
+{
+ return m_data->m_view;
+}
+
+void GraphicsContext::savePlatformState()
+{
+ m_data->m_view->PushState();
+}
+
+void GraphicsContext::restorePlatformState()
+{
+ m_data->m_view->PopState();
+}
+
+// Draws a filled rectangle with a stroked border.
+void GraphicsContext::drawRect(const IntRect& rect)
+{
+ if (paintingDisabled())
+ return;
+
+ m_data->m_view->FillRect(rect);
+ if (strokeStyle() != NoStroke)
+ m_data->m_view->StrokeRect(rect, getHaikuStrokeStyle());
+}
+
+// This is only used to draw borders.
+void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
+{
+ if (paintingDisabled())
+ return;
+
+ if (strokeStyle() == NoStroke)
+ return;
+
+ m_data->m_view->StrokeLine(point1, point2, getHaikuStrokeStyle());
+}
+
+// This method is only used to draw the little circles used in lists.
+void GraphicsContext::drawEllipse(const IntRect& rect)
+{
+ if (paintingDisabled())
+ return;
+
+ m_data->m_view->FillEllipse(rect);
+ if (strokeStyle() != NoStroke)
+ m_data->m_view->StrokeEllipse(rect, getHaikuStrokeStyle());
+}
+
+void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSpan)
+{
+ if (paintingDisabled())
+ return;
+
+ m_data->m_view->StrokeArc(rect, startAngle, angleSpan, getHaikuStrokeStyle());
+}
+
+void GraphicsContext::strokePath()
+{
+ notImplemented();
+}
+
+void GraphicsContext::drawConvexPolygon(size_t pointsLength, const FloatPoint* points, bool shouldAntialias)
+{
+ if (paintingDisabled())
+ return;
+
+ BPoint bPoints[pointsLength];
+ for (size_t i = 0; i < pointsLength; i++)
+ bPoints[i] = points[i];
+
+ m_data->m_view->FillPolygon(bPoints, pointsLength);
+ if (strokeStyle() != NoStroke)
+ // Stroke with low color
+ m_data->m_view->StrokePolygon(bPoints, pointsLength, true, getHaikuStrokeStyle());
+}
+
+void GraphicsContext::fillRect(const FloatRect& rect, const Color& color)
+{
+ if (paintingDisabled())
+ return;
+
+ rgb_color oldColor = m_data->m_view->HighColor();
+ m_data->m_view->SetHighColor(color);
+ m_data->m_view->FillRect(rect);
+ m_data->m_view->SetHighColor(oldColor);
+}
+
+void GraphicsContext::fillRect(const FloatRect& rect)
+{
+ if (paintingDisabled())
+ return;
+}
+
+void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color)
+{
+ if (paintingDisabled() || !color.alpha())
+ return;
+
+ notImplemented();
+ // FIXME: A simple implementation could just use FillRoundRect if all
+ // the sizes are the same, or even if they are not. Otherwise several
+ // FillRect and FillArc calls are needed.
+}
+
+void GraphicsContext::fillPath()
+{
+ notImplemented();
+}
+
+void GraphicsContext::beginPath()
+{
+ notImplemented();
+}
+
+void GraphicsContext::addPath(const Path& path)
+{
+ notImplemented();
+}
+
+void GraphicsContext::clip(const FloatRect& rect)
+{
+ if (paintingDisabled())
+ return;
+
+ BRegion region(rect);
+ m_data->m_view->ConstrainClippingRegion(&region);
+}
+
+void GraphicsContext::drawFocusRing(const Color& color)
+{
+ if (paintingDisabled())
+ return;
+
+ const Vector<IntRect>& rects = focusRingRects();
+ unsigned rectCount = rects.size();
+
+ // FIXME: maybe we should implement this with BShape?
+
+ if (rects.size() > 1) {
+ BRegion region;
+ for (int i = 0; i < rectCount; ++i)
+ region.Include(BRect(rects[i]));
+
+ m_data->m_view->SetHighColor(color);
+ m_data->m_view->StrokeRect(region.Frame(), B_MIXED_COLORS);
+ }
+}
+
+void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool printing)
+{
+ if (paintingDisabled())
+ return;
+
+ IntPoint endPoint = origin + IntSize(width, 0);
+ drawLine(origin, endPoint);
+}
+
+void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint&, int width, bool grammar)
+{
+ if (paintingDisabled())
+ return;
+
+ notImplemented();
+}
+
+FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect)
+{
+ notImplemented();
+ return rect;
+}
+
+void GraphicsContext::beginTransparencyLayer(float opacity)
+{
+ if (paintingDisabled())
+ return;
+
+ notImplemented();
+}
+
+void GraphicsContext::endTransparencyLayer()
+{
+ if (paintingDisabled())
+ return;
+
+ notImplemented();
+}
+
+void GraphicsContext::clearRect(const FloatRect& rect)
+{
+ if (paintingDisabled())
+ return;
+
+ notImplemented();
+}
+
+void GraphicsContext::strokeRect(const FloatRect& rect, float width)
+{
+ if (paintingDisabled())
+ return;
+
+ float oldSize = m_data->m_view->PenSize();
+ m_data->m_view->SetPenSize(width);
+ m_data->m_view->StrokeRect(rect, getHaikuStrokeStyle());
+ m_data->m_view->SetPenSize(oldSize);
+}
+
+void GraphicsContext::setLineCap(LineCap lineCap)
+{
+ if (paintingDisabled())
+ return;
+
+ cap_mode mode = B_BUTT_CAP;
+ switch (lineCap) {
+ case RoundCap:
+ mode = B_ROUND_CAP;
+ break;
+ case SquareCap:
+ mode = B_SQUARE_CAP;
+ break;
+ case ButtCap:
+ default:
+ break;
+ }
+
+ m_data->m_view->SetLineMode(mode, m_data->m_view->LineJoinMode(), m_data->m_view->LineMiterLimit());
+}
+
+void GraphicsContext::setLineJoin(LineJoin lineJoin)
+{
+ if (paintingDisabled())
+ return;
+
+ join_mode mode = B_MITER_JOIN;
+ switch (lineJoin) {
+ case RoundJoin:
+ mode = B_ROUND_JOIN;
+ break;
+ case BevelJoin:
+ mode = B_BEVEL_JOIN;
+ break;
+ case MiterJoin:
+ default:
+ break;
+ }
+
+ m_data->m_view->SetLineMode(m_data->m_view->LineCapMode(), mode, m_data->m_view->LineMiterLimit());
+}
+
+void GraphicsContext::setMiterLimit(float limit)
+{
+ if (paintingDisabled())
+ return;
+
+ m_data->m_view->SetLineMode(m_data->m_view->LineCapMode(), m_data->m_view->LineJoinMode(), limit);
+}
+
+void GraphicsContext::setAlpha(float opacity)
+{
+ if (paintingDisabled())
+ return;
+
+ notImplemented();
+}
+
+void GraphicsContext::setCompositeOperation(CompositeOperator op)
+{
+ if (paintingDisabled())
+ return;
+
+ drawing_mode mode = B_OP_COPY;
+ switch (op) {
+ case CompositeClear:
+ case CompositeCopy:
+ // Use the default above
+ break;
+ case CompositeSourceOver:
+ mode = B_OP_OVER;
+ break;
+ default:
+ printf("GraphicsContext::setCompositeOperation: Unsupported composite operation %s\n",
+ compositeOperatorName(op).utf8().data());
+ }
+ m_data->m_view->SetDrawingMode(mode);
+}
+
+void GraphicsContext::clip(const Path& path)
+{
+ if (paintingDisabled())
+ return;
+
+ m_data->m_view->ConstrainClippingRegion(path.platformPath());
+}
+
+void GraphicsContext::clipOut(const Path& path)
+{
+ if (paintingDisabled())
+ return;
+
+ notImplemented();
+}
+
+void GraphicsContext::clipToImageBuffer(const FloatRect&, const ImageBuffer*)
+{
+ notImplemented();
+}
+
+TransformationMatrix GraphicsContext::getCTM() const
+{
+ notImplemented();
+ return TransformationMatrix();
+}
+
+void GraphicsContext::translate(float x, float y)
+{
+ if (paintingDisabled())
+ return;
+
+ notImplemented();
+}
+
+IntPoint GraphicsContext::origin()
+{
+ notImplemented();
+ return IntPoint(0, 0);
+}
+
+void GraphicsContext::rotate(float radians)
+{
+ if (paintingDisabled())
+ return;
+
+ notImplemented();
+}
+
+void GraphicsContext::scale(const FloatSize& size)
+{
+ if (paintingDisabled())
+ return;
+
+ notImplemented();
+}
+
+void GraphicsContext::clipOut(const IntRect& rect)
+{
+ if (paintingDisabled())
+ return;
+
+ notImplemented();
+}
+
+void GraphicsContext::clipOutEllipseInRect(const IntRect& rect)
+{
+ if (paintingDisabled())
+ return;
+
+ notImplemented();
+}
+
+void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness)
+{
+ if (paintingDisabled())
+ return;
+
+ notImplemented();
+}
+
+void GraphicsContext::concatCTM(const TransformationMatrix& transform)
+{
+ if (paintingDisabled())
+ return;
+
+ notImplemented();
+}
+
+void GraphicsContext::setPlatformShouldAntialias(bool enable)
+{
+ if (paintingDisabled())
+ return;
+
+ notImplemented();
+}
+
+void GraphicsContext::setImageInterpolationQuality(InterpolationQuality)
+{
+}
+
+void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect)
+{
+ notImplemented();
+}
+
+void GraphicsContext::setPlatformFont(const Font& font)
+{
+ m_data->m_view->SetFont(font.primaryFont()->platformData().font());
+}
+
+void GraphicsContext::setPlatformStrokeColor(const Color& color)
+{
+ if (paintingDisabled())
+ return;
+
+ m_data->m_view->SetHighColor(color);
+}
+
+pattern GraphicsContext::getHaikuStrokeStyle()
+{
+ switch (strokeStyle()) {
+ case SolidStroke:
+ return B_SOLID_HIGH;
+ break;
+ case DottedStroke:
+ return B_MIXED_COLORS;
+ break;
+ case DashedStroke:
+ // FIXME: use a better dashed stroke!
+ notImplemented();
+ return B_MIXED_COLORS;
+ break;
+ default:
+ return B_SOLID_LOW;
+ break;
+ }
+}
+
+void GraphicsContext::setPlatformStrokeStyle(const StrokeStyle& strokeStyle)
+{
+ // FIXME: see getHaikuStrokeStyle.
+ notImplemented();
+}
+
+void GraphicsContext::setPlatformStrokeThickness(float thickness)
+{
+ if (paintingDisabled())
+ return;
+
+ m_data->m_view->SetPenSize(thickness);
+}
+
+void GraphicsContext::setPlatformFillColor(const Color& color)
+{
+ if (paintingDisabled())
+ return;
+
+ m_data->m_view->SetHighColor(color);
+}
+
+void GraphicsContext::clearPlatformShadow()
+{
+ notImplemented();
+}
+
+void GraphicsContext::setPlatformShadow(IntSize const&, int, Color const&)
+{
+ notImplemented();
+}
+
+} // namespace WebCore
+
diff --git a/WebCore/platform/graphics/haiku/IconHaiku.cpp b/WebCore/platform/graphics/haiku/IconHaiku.cpp
new file mode 100644
index 0000000..dccac4a
--- /dev/null
+++ b/WebCore/platform/graphics/haiku/IconHaiku.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2007 Ryan Leavengood <leavengood@gmail.com>
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "config.h"
+#include "Icon.h"
+
+#include "GraphicsContext.h"
+#include "IntRect.h"
+#include "NotImplemented.h"
+#include "PlatformString.h"
+
+
+namespace WebCore {
+
+Icon::~Icon()
+{
+ notImplemented();
+}
+
+PassRefPtr<Icon> Icon::createIconForFile(const String& filename)
+{
+ notImplemented();
+ return 0;
+}
+
+PassRefPtr<Icon> Icon::createIconForFiles(const Vector<String>& filenames)
+{
+ notImplemented();
+ return 0;
+}
+
+void Icon::paint(GraphicsContext*, const IntRect&)
+{
+ notImplemented();
+}
+
+} // namespace WebCore
+
diff --git a/WebCore/platform/graphics/haiku/ImageBufferData.h b/WebCore/platform/graphics/haiku/ImageBufferData.h
new file mode 100644
index 0000000..f978c34
--- /dev/null
+++ b/WebCore/platform/graphics/haiku/ImageBufferData.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2009 Maxime Simon <simon.maxime@gmail.com>
+ *
+ * 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 ImageBufferData_h
+#define ImageBufferData_h
+
+namespace WebCore {
+
+ class IntSize;
+
+ class ImageBufferData {
+ public:
+ ImageBufferData(const IntSize&);
+ };
+
+} // namespace WebCore
+
+#endif // ImageBufferData_h
+
diff --git a/WebCore/platform/graphics/haiku/ImageBufferHaiku.cpp b/WebCore/platform/graphics/haiku/ImageBufferHaiku.cpp
new file mode 100644
index 0000000..276c968
--- /dev/null
+++ b/WebCore/platform/graphics/haiku/ImageBufferHaiku.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2009 Maxime Simon <simon.maxime@gmail.com>
+ *
+ * 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 "ImageBuffer.h"
+
+#include "GraphicsContext.h"
+#include "ImageData.h"
+#include "NotImplemented.h"
+
+
+namespace WebCore {
+
+ImageBufferData::ImageBufferData(const IntSize&)
+{
+}
+
+ImageBuffer::ImageBuffer(const IntSize&, ImageColorSpace imageColorSpace, bool& success)
+ : m_data(IntSize())
+{
+ notImplemented();
+ success = false;
+}
+
+ImageBuffer::~ImageBuffer()
+{
+}
+
+GraphicsContext* ImageBuffer::context() const
+{
+ notImplemented();
+ return 0;
+}
+
+PassRefPtr<ImageData> ImageBuffer::getUnmultipliedImageData(const IntRect& rect) const
+{
+ notImplemented();
+ return 0;
+}
+
+PassRefPtr<ImageData> ImageBuffer::getPremultipliedImageData(const IntRect& rect) const
+{
+ notImplemented();
+ return 0;
+}
+
+void ImageBuffer::putUnmultipliedImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint)
+{
+ notImplemented();
+}
+
+void ImageBuffer::putPremultipliedImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint)
+{
+ notImplemented();
+}
+
+String ImageBuffer::toDataURL(const String&) const
+{
+ notImplemented();
+ return String();
+}
+
+Image* ImageBuffer::image() const
+{
+ notImplemented();
+ return 0;
+}
+
+void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookUpTable)
+{
+ notImplemented();
+}
+
+} // namespace WebCore
+
diff --git a/WebCore/platform/graphics/haiku/ImageHaiku.cpp b/WebCore/platform/graphics/haiku/ImageHaiku.cpp
new file mode 100644
index 0000000..323d6ab
--- /dev/null
+++ b/WebCore/platform/graphics/haiku/ImageHaiku.cpp
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2006 Dirk Mueller <mueller@kde.org>
+ * Copyright (C) 2006 Zack Rusin <zack@kde.org>
+ * Copyright (C) 2006 Simon Hausmann <hausmann@kde.org>
+ * Copyright (C) 2007 Ryan Leavengood <leavengood@gmail.com>
+ * Copyright (C) 2008 Andrea Anzani <andrea.anzani@gmail.com>
+ *
+ * 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 "Image.h"
+
+#include "BitmapImage.h"
+#include "FloatRect.h"
+#include "GraphicsContext.h"
+#include "NotImplemented.h"
+#include "PlatformString.h"
+#include <Application.h>
+#include <Bitmap.h>
+#include <View.h>
+
+
+// This function loads resources from WebKit
+Vector<char> loadResourceIntoArray(const char*);
+
+
+namespace WebCore {
+
+bool FrameData::clear(bool clearMetadata)
+{
+ if (clearMetadata)
+ m_haveMetadata = false;
+
+ if (m_frame) {
+ delete m_frame;
+ m_frame = 0;
+ m_duration = 0.0f;
+ m_hasAlpha = true;
+ return true;
+ }
+
+ return false;
+}
+
+WTF::PassRefPtr<Image> Image::loadPlatformResource(const char* name)
+{
+ Vector<char> array = loadResourceIntoArray(name);
+ WTF::PassRefPtr<BitmapImage> image = BitmapImage::create();
+ RefPtr<SharedBuffer> buffer = SharedBuffer::create(array.data(), array.size());
+ image->setData(buffer, true);
+
+ return image;
+}
+
+void BitmapImage::initPlatformData()
+{
+}
+
+void BitmapImage::invalidatePlatformData()
+{
+}
+
+// Drawing Routines
+void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst, const FloatRect& src, CompositeOperator op)
+{
+ startAnimation();
+
+ BBitmap* image = nativeImageForCurrentFrame();
+ if (!image || !image->IsValid()) // If the image hasn't fully loaded.
+ return;
+
+ if (mayFillWithSolidColor()) {
+ fillWithSolidColor(ctxt, dst, solidColor(), op);
+ return;
+ }
+
+ ctxt->save();
+ ctxt->setCompositeOperation(op);
+
+ BRect srcRect(src);
+ BRect dstRect(dst);
+
+ // Test using example site at
+ // http://www.meyerweb.com/eric/css/edge/complexspiral/demo.html
+ ctxt->platformContext()->SetDrawingMode(B_OP_ALPHA);
+ ctxt->platformContext()->DrawBitmap(image, srcRect & image->Bounds(), dstRect);
+ ctxt->restore();
+}
+
+void Image::drawPattern(GraphicsContext* context, const FloatRect& tileRect, const TransformationMatrix& patternTransform, const FloatPoint& srcPoint, CompositeOperator op, const FloatRect& dstRect)
+{
+ // FIXME: finish this to support also phased position (srcPoint)
+ startAnimation();
+
+ BBitmap* image = nativeImageForCurrentFrame();
+ if (!image || !image->IsValid()) // If the image hasn't fully loaded.
+ return;
+
+ float currentW = 0;
+ float currentH = 0;
+
+ context->save();
+ context->platformContext()->SetDrawingMode(B_OP_ALPHA);
+ context->clip(enclosingIntRect(dstRect));
+
+ while (currentW < dstRect.width()) {
+ while (currentH < dstRect.height()) {
+ context->platformContext()->DrawBitmap(image, BPoint(dstRect.x() + currentW, dstRect.y() + currentH));
+ currentH += tileRect.height();
+ }
+ currentW += tileRect.width();
+ currentH = 0;
+ }
+ context->restore();
+}
+
+void BitmapImage::checkForSolidColor()
+{
+ // FIXME: need to check the RGBA32 buffer to see if it is 1x1.
+ m_isSolidColor = false;
+ m_checkedForSolidColor = true;
+}
+
+BBitmap* BitmapImage::getBBitmap() const
+{
+ return const_cast<BitmapImage*>(this)->frameAtIndex(0);
+}
+
+} // namespace WebCore
+
diff --git a/WebCore/platform/graphics/haiku/IntPointHaiku.cpp b/WebCore/platform/graphics/haiku/IntPointHaiku.cpp
new file mode 100644
index 0000000..327e503
--- /dev/null
+++ b/WebCore/platform/graphics/haiku/IntPointHaiku.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2007 Ryan Leavengood <leavengood@gmail.com>
+ *
+ * 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 "IntPoint.h"
+
+#include <Point.h>
+
+
+namespace WebCore {
+
+IntPoint::IntPoint(const BPoint& point)
+ : m_x(static_cast<int>(point.x))
+ , m_y(static_cast<int>(point.y))
+{
+}
+
+IntPoint::operator BPoint() const
+{
+ return BPoint(m_x, m_y);
+}
+
+} // namespace WebCore
+
diff --git a/WebCore/platform/graphics/haiku/IntRectHaiku.cpp b/WebCore/platform/graphics/haiku/IntRectHaiku.cpp
new file mode 100644
index 0000000..74a0b9d
--- /dev/null
+++ b/WebCore/platform/graphics/haiku/IntRectHaiku.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2007 Ryan Leavengood <leavengood@gmail.com>
+ *
+ * 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 "IntRect.h"
+
+#include <Rect.h>
+
+
+namespace WebCore {
+
+IntRect::IntRect(const BRect& rect)
+ : m_location(rect.LeftTop())
+ , m_size(rect.IntegerWidth(), rect.IntegerHeight())
+{
+}
+
+IntRect::operator BRect() const
+{
+ return BRect(BPoint(x(), y()), BSize(width(), height()));
+}
+
+} // namespace WebCore
+
diff --git a/WebCore/platform/graphics/haiku/IntSizeHaiku.cpp b/WebCore/platform/graphics/haiku/IntSizeHaiku.cpp
new file mode 100644
index 0000000..08c3a9d
--- /dev/null
+++ b/WebCore/platform/graphics/haiku/IntSizeHaiku.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2007 Ryan Leavengood <leavengood@gmail.com>
+ *
+ * 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 "IntSize.h"
+
+#include <Size.h>
+
+
+namespace WebCore {
+
+IntSize::IntSize(const BSize& size)
+ : m_width(size.IntegerWidth())
+ , m_height(size.IntegerHeight())
+{
+}
+
+IntSize::operator BSize() const
+{
+ return BSize(width(), height());
+}
+
+} // namespace WebCore
+
diff --git a/WebCore/platform/graphics/haiku/PathHaiku.cpp b/WebCore/platform/graphics/haiku/PathHaiku.cpp
new file mode 100644
index 0000000..d0da025
--- /dev/null
+++ b/WebCore/platform/graphics/haiku/PathHaiku.cpp
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2007 Ryan Leavengood <leavengood@gmail.com>
+ *
+ * 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 "Path.h"
+
+#include "FloatRect.h"
+#include "NotImplemented.h"
+#include "PlatformString.h"
+#include <Region.h>
+
+
+namespace WebCore {
+
+Path::Path()
+ : m_path(new BRegion())
+{
+}
+
+Path::~Path()
+{
+ delete m_path;
+}
+
+Path::Path(const Path& other)
+ : m_path(new BRegion(*other.platformPath()))
+{
+}
+
+Path& Path::operator=(const Path& other)
+{
+ if (&other != this)
+ m_path = other.platformPath();
+
+ return *this;
+}
+
+bool Path::hasCurrentPoint() const
+{
+ return !isEmpty();
+}
+
+bool Path::contains(const FloatPoint& point, WindRule rule) const
+{
+ return m_path->Contains(point);
+}
+
+void Path::translate(const FloatSize& size)
+{
+ notImplemented();
+}
+
+FloatRect Path::boundingRect() const
+{
+ return m_path->Frame();
+}
+
+void Path::moveTo(const FloatPoint& point)
+{
+ // FIXME: Use OffsetBy?
+ notImplemented();
+}
+
+void Path::addLineTo(const FloatPoint& p)
+{
+ notImplemented();
+}
+
+void Path::addQuadCurveTo(const FloatPoint& cp, const FloatPoint& p)
+{
+ notImplemented();
+}
+
+void Path::addBezierCurveTo(const FloatPoint& cp1, const FloatPoint& cp2, const FloatPoint& p)
+{
+ notImplemented();
+}
+
+void Path::addArcTo(const FloatPoint& p1, const FloatPoint& p2, float radius)
+{
+ notImplemented();
+}
+
+void Path::closeSubpath()
+{
+ notImplemented();
+}
+
+void Path::addArc(const FloatPoint& p, float r, float sar, float ear, bool anticlockwise)
+{
+ notImplemented();
+}
+
+void Path::addRect(const FloatRect& r)
+{
+ m_path->Include(r);
+}
+
+void Path::addEllipse(const FloatRect& r)
+{
+ notImplemented();
+}
+
+void Path::clear()
+{
+ m_path->MakeEmpty();
+}
+
+bool Path::isEmpty() const
+{
+ return !m_path->Frame().IsValid();
+}
+
+String Path::debugString() const
+{
+ notImplemented();
+ return String();
+}
+
+void Path::apply(void* info, PathApplierFunction function) const
+{
+ notImplemented();
+}
+
+void Path::transform(const TransformationMatrix& transform)
+{
+ notImplemented();
+}
+
+FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier)
+{
+ notImplemented();
+ return FloatRect();
+}
+
+} // namespace WebCore
+
diff --git a/WebCore/platform/graphics/haiku/SimpleFontDataHaiku.cpp b/WebCore/platform/graphics/haiku/SimpleFontDataHaiku.cpp
new file mode 100644
index 0000000..34941c0
--- /dev/null
+++ b/WebCore/platform/graphics/haiku/SimpleFontDataHaiku.cpp
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2009 Maxime Simon <simon.maxime@gmail.com> All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "SimpleFontData.h"
+
+#include "FloatRect.h"
+#include "FontCache.h"
+#include "FontDescription.h"
+#include "NotImplemented.h"
+#include <Rect.h>
+#include <unicode/uchar.h>
+#include <unicode/unorm.h>
+
+
+namespace WebCore {
+
+void SimpleFontData::platformInit()
+{
+ BFont* font = m_platformData.font();
+ if (!font)
+ return;
+
+ font_height height;
+ font->GetHeight(&height);
+ m_ascent = static_cast<int>(height.ascent);
+ m_descent = static_cast<int>(height.descent);
+ m_lineSpacing = m_ascent + m_descent;
+ m_xHeight = height.ascent * 0.56f; // Hack taken from the win port.
+ m_lineGap = height.leading;
+}
+
+void SimpleFontData::platformCharWidthInit()
+{
+ m_avgCharWidth = 0.f;
+ m_maxCharWidth = 0.f;
+ initCharWidths();
+}
+
+void SimpleFontData::platformDestroy()
+{
+ delete m_smallCapsFontData;
+ m_smallCapsFontData = 0;
+}
+
+SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
+{
+ if (!m_smallCapsFontData) {
+ FontDescription desc = FontDescription(fontDescription);
+ desc.setSpecifiedSize(0.70f * fontDescription.computedSize());
+ const FontPlatformData* fontPlatformData = new FontPlatformData(desc, desc.family().family());
+ m_smallCapsFontData = new SimpleFontData(*fontPlatformData);
+ }
+ return m_smallCapsFontData;
+}
+
+bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
+{
+ // FIXME: We will need to implement this to load non-ASCII encoding sites
+ return true;
+}
+
+void SimpleFontData::determinePitch()
+{
+ m_treatAsFixedPitch = m_platformData.font() && m_platformData.font()->IsFixed();
+}
+
+float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
+{
+ const char charArray[1] = { glyph };
+ float escapements[1];
+
+ if (m_platformData.font()) {
+ m_platformData.font()->GetEscapements(charArray, 1, escapements);
+ return escapements[0] * m_platformData.font()->Size();
+ }
+
+ return 0;
+}
+
+} // namespace WebCore
+
diff --git a/WebCore/platform/graphics/mac/Canvas3DLayer.h b/WebCore/platform/graphics/mac/Canvas3DLayer.h
new file mode 100644
index 0000000..6c65676
--- /dev/null
+++ b/WebCore/platform/graphics/mac/Canvas3DLayer.h
@@ -0,0 +1,50 @@
+/*
+ * 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 Canvas3DLayer_h
+#define Canvas3DLayer_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#import "WebLayer.h"
+
+namespace WebCore {
+ class GraphicsLayer;
+}
+
+@interface Canvas3DLayer : CAOpenGLLayer
+{
+ WebCore::GraphicsLayer* m_layerOwner;
+ CGLContextObj m_contextObj;
+ GLuint m_texture;
+}
+
+-(id)initWithContext:(CGLContextObj)context texture:(GLuint)texture;
+
+@end
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
+#endif // Canvas3DLayer_h
diff --git a/WebCore/platform/graphics/mac/Canvas3DLayer.mm b/WebCore/platform/graphics/mac/Canvas3DLayer.mm
new file mode 100644
index 0000000..545c58b
--- /dev/null
+++ b/WebCore/platform/graphics/mac/Canvas3DLayer.mm
@@ -0,0 +1,123 @@
+/*
+ * 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.
+ */
+
+#include "config.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+#if ENABLE(3D_CANVAS)
+
+#import "Canvas3DLayer.h"
+
+#import "GraphicsLayer.h"
+#import <QuartzCore/QuartzCore.h>
+#import <OpenGL/OpenGL.h>
+
+using namespace WebCore;
+
+@implementation Canvas3DLayer
+
+-(id)initWithContext:(CGLContextObj)context texture:(GLuint)texture
+{
+ m_contextObj = context;
+ m_texture = texture;
+ self = [super init];
+ return self;
+}
+
+-(CGLPixelFormatObj)copyCGLPixelFormatForDisplayMask:(uint32_t)mask
+{
+ CGLPixelFormatAttribute attribs[] =
+ {
+ (CGLPixelFormatAttribute) kCGLPFAAccelerated,
+ (CGLPixelFormatAttribute) kCGLPFAColorSize, (CGLPixelFormatAttribute) 32,
+ (CGLPixelFormatAttribute) kCGLPFADisplayMask, (CGLPixelFormatAttribute) mask,
+ (CGLPixelFormatAttribute) 0
+ };
+
+ CGLPixelFormatObj pixelFormatObj;
+ GLint numPixelFormats;
+
+ CGLChoosePixelFormat(attribs, &pixelFormatObj, &numPixelFormats);
+ return pixelFormatObj;
+}
+
+-(CGLContextObj)copyCGLContextForPixelFormat:(CGLPixelFormatObj)pixelFormat
+{
+ CGLContextObj contextObj;
+ CGLCreateContext(pixelFormat, m_contextObj, &contextObj);
+ return contextObj;
+}
+
+-(void)drawInCGLContext:(CGLContextObj)glContext pixelFormat:(CGLPixelFormatObj)pixelFormat forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp
+{
+ CGRect frame = [self frame];
+
+ // draw the FBO into the layer
+ glViewport(0, 0, frame.size.width, frame.size.height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(-1, 1, -1, 1, -1, 1);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, m_texture);
+
+ glBegin(GL_TRIANGLE_FAN);
+ glTexCoord2f(0, 0);
+ glVertex2f(-1, -1);
+ glTexCoord2f(1, 0);
+ glVertex2f(1, -1);
+ glTexCoord2f(1, 1);
+ glVertex2f(1, 1);
+ glTexCoord2f(0, 1);
+ glVertex2f(-1, 1);
+ glEnd();
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glDisable(GL_TEXTURE_2D);
+
+ // Call super to finalize the drawing. By default all it does is call glFlush().
+ [super drawInCGLContext:glContext pixelFormat:pixelFormat forLayerTime:timeInterval displayTime:timeStamp];
+}
+
+@end
+
+@implementation Canvas3DLayer(WebLayerAdditions)
+
+-(void)setLayerOwner:(GraphicsLayer*)aLayer
+{
+ m_layerOwner = aLayer;
+}
+
+-(GraphicsLayer*)layerOwner
+{
+ return m_layerOwner;
+}
+
+@end
+
+#endif // ENABLE(3D_CANVAS)
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/mac/CoreTextController.cpp b/WebCore/platform/graphics/mac/CoreTextController.cpp
index 05f29b5..b2682e4 100644
--- a/WebCore/platform/graphics/mac/CoreTextController.cpp
+++ b/WebCore/platform/graphics/mac/CoreTextController.cpp
@@ -365,7 +365,7 @@ void CoreTextController::collectCoreTextRunsForCharacters(const UChar* cp, unsig
RetainPtr<CFStringRef> string(AdoptCF, CFStringCreateWithCharactersNoCopy(NULL, cp, length, kCFAllocatorNull));
- RetainPtr<CFAttributedStringRef> attributedString(AdoptCF, CFAttributedStringCreate(NULL, string.get(), fontData->getCFStringAttributes()));
+ RetainPtr<CFAttributedStringRef> attributedString(AdoptCF, CFAttributedStringCreate(NULL, string.get(), fontData->getCFStringAttributes(m_font.fontDescription().textRenderingMode())));
RetainPtr<CTTypesetterRef> typesetter;
diff --git a/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp b/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp
index e40bbab..5e72101 100644
--- a/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp
+++ b/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp
@@ -46,11 +46,13 @@ FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
ATSFontContainerRef containerRef = 0;
ATSFontRef fontRef = 0;
+ RetainPtr<CGFontRef> cgFontRef;
+
#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
RetainPtr<CFDataRef> bufferData(AdoptCF, buffer->createCFData());
RetainPtr<CGDataProviderRef> dataProvider(AdoptCF, CGDataProviderCreateWithCFData(bufferData.get()));
- CGFontRef cgFontRef = CGFontCreateWithDataProvider(dataProvider.get());
+ cgFontRef.adoptCF(CGFontCreateWithDataProvider(dataProvider.get()));
if (!cgFontRef)
return 0;
#else
@@ -75,13 +77,11 @@ FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
return 0;
}
- CGFontRef cgFontRef = CGFontCreateWithPlatformFont(&fontRef);
+ cgFontRef.adoptCF(CGFontCreateWithPlatformFont(&fontRef));
#ifndef BUILDING_ON_TIGER
// Workaround for <rdar://problem/5675504>.
- if (cgFontRef && !CGFontGetNumberOfGlyphs(cgFontRef)) {
- CFRelease(cgFontRef);
+ if (cgFontRef && !CGFontGetNumberOfGlyphs(cgFontRef.get()))
cgFontRef = 0;
- }
#endif
if (!cgFontRef) {
ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault);
@@ -89,7 +89,7 @@ FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
}
#endif // !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
- return new FontCustomPlatformData(containerRef, fontRef, cgFontRef);
+ return new FontCustomPlatformData(containerRef, fontRef, cgFontRef.releaseRef());
}
}
diff --git a/WebCore/platform/graphics/mac/FontMac.mm b/WebCore/platform/graphics/mac/FontMac.mm
index df9494a..b2b9a5c 100644
--- a/WebCore/platform/graphics/mac/FontMac.mm
+++ b/WebCore/platform/graphics/mac/FontMac.mm
@@ -50,10 +50,33 @@ bool Font::canReturnFallbackFontsForComplexText()
void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point) const
{
CGContextRef cgContext = context->platformContext();
+ bool newShouldUseFontSmoothing = shouldUseSmoothing();
+
+ switch(fontDescription().fontSmoothing()) {
+ case Antialiased: {
+ context->setShouldAntialias(true);
+ newShouldUseFontSmoothing = false;
+ break;
+ }
+ case SubpixelAntialiased: {
+ context->setShouldAntialias(true);
+ newShouldUseFontSmoothing = true;
+ break;
+ }
+ case NoSmoothing: {
+ context->setShouldAntialias(false);
+ newShouldUseFontSmoothing = false;
+ break;
+ }
+ case AutoSmoothing: {
+ // For the AutoSmooth case, don't do anything! Keep the default settings.
+ break;
+ }
+ default:
+ ASSERT_NOT_REACHED();
+ }
bool originalShouldUseFontSmoothing = wkCGContextGetShouldSmoothFonts(cgContext);
- bool newShouldUseFontSmoothing = shouldUseSmoothing();
-
if (originalShouldUseFontSmoothing != newShouldUseFontSmoothing)
CGContextSetShouldSmoothFonts(cgContext, newShouldUseFontSmoothing);
diff --git a/WebCore/platform/graphics/mac/FontMacATSUI.mm b/WebCore/platform/graphics/mac/FontMacATSUI.mm
index 051abb7..409bda4 100644
--- a/WebCore/platform/graphics/mac/FontMacATSUI.mm
+++ b/WebCore/platform/graphics/mac/FontMacATSUI.mm
@@ -105,12 +105,12 @@ static bool fontHasMirroringInfo(ATSUFontID fontID)
return false;
}
-static void disableLigatures(const SimpleFontData* fontData)
+static void disableLigatures(const SimpleFontData* fontData, TextRenderingMode textMode)
{
// Don't be too aggressive: if the font doesn't contain 'a', then assume that any ligatures it contains are
// in characters that always go through ATSUI, and therefore allow them. Geeza Pro is an example.
// See bugzilla 5166.
- if (fontData->platformData().allowsLigatures())
+ if (textMode == OptimizeLegibility || textMode == GeometricPrecision || fontData->platformData().allowsLigatures())
return;
ATSUFontFeatureType featureTypes[] = { kLigaturesType };
@@ -120,7 +120,7 @@ static void disableLigatures(const SimpleFontData* fontData)
LOG_ERROR("ATSUSetFontFeatures failed (%d) -- ligatures remain enabled", status);
}
-static void initializeATSUStyle(const SimpleFontData* fontData)
+static void initializeATSUStyle(const SimpleFontData* fontData, TextRenderingMode textMode)
{
if (fontData->m_ATSUStyleInitialized)
return;
@@ -141,19 +141,28 @@ static void initializeATSUStyle(const SimpleFontData* fontData)
transform = CGAffineTransformConcat(transform, CGAffineTransformMake(1, 0, -tanf(SYNTHETIC_OBLIQUE_ANGLE * acosf(0) / 90), 1, 0, 0));
Fixed fontSize = FloatToFixed(fontData->platformData().m_size);
ByteCount styleSizes[4] = { sizeof(Fixed), sizeof(ATSUFontID), sizeof(CGAffineTransform), sizeof(Fract) };
- // Turn off automatic kerning until it is supported in the CG code path (bug 6136)
- Fract kerningInhibitFactor = FloatToFract(1.0);
- ATSUAttributeTag styleTags[4] = { kATSUSizeTag, kATSUFontTag, kATSUFontMatrixTag, kATSUKerningInhibitFactorTag };
- ATSUAttributeValuePtr styleValues[4] = { &fontSize, &fontID, &transform, &kerningInhibitFactor };
- status = ATSUSetAttributes(fontData->m_ATSUStyle, 4, styleTags, styleSizes, styleValues);
- if (status != noErr)
- LOG_ERROR("ATSUSetAttributes failed (%d)", status);
+ bool allowKerning = textMode == OptimizeLegibility || textMode == GeometricPrecision;
+ if (!allowKerning) {
+ // Turn off automatic kerning until it is supported in the CG code path (bug 6136)
+ Fract kerningInhibitFactor = FloatToFract(1.0);
+ ATSUAttributeTag styleTags[4] = { kATSUSizeTag, kATSUFontTag, kATSUFontMatrixTag, kATSUKerningInhibitFactorTag };
+ ATSUAttributeValuePtr styleValues[4] = { &fontSize, &fontID, &transform, &kerningInhibitFactor };
+ status = ATSUSetAttributes(fontData->m_ATSUStyle, 4, styleTags, styleSizes, styleValues);
+ if (status != noErr)
+ LOG_ERROR("ATSUSetAttributes failed (%d)", status);
+ } else {
+ ATSUAttributeTag styleTags[3] = { kATSUSizeTag, kATSUFontTag, kATSUFontMatrixTag };
+ ATSUAttributeValuePtr styleValues[3] = { &fontSize, &fontID, &transform, };
+ status = ATSUSetAttributes(fontData->m_ATSUStyle, 3, styleTags, styleSizes, styleValues);
+ if (status != noErr)
+ LOG_ERROR("ATSUSetAttributes failed (%d)", status);
+ }
fontData->m_ATSUMirrors = fontHasMirroringInfo(fontID);
// Turn off ligatures such as 'fi' to match the CG code path's behavior, until bug 6135 is fixed.
- disableLigatures(fontData);
+ disableLigatures(fontData, textMode);
fontData->m_ATSUStyleInitialized = true;
}
@@ -329,7 +338,7 @@ void ATSULayoutParameters::initialize(const Font* font, const GraphicsContext* g
OSStatus status;
ATSULayoutOperationOverrideSpecifier overrideSpecifier;
- initializeATSUStyle(fontData);
+ initializeATSUStyle(fontData, m_font->fontDescription().textRenderingMode());
// FIXME: This is currently missing the following required features that the CoreGraphics code path has:
// - \n, \t, and nonbreaking space render as a space.
@@ -393,7 +402,7 @@ void ATSULayoutParameters::initialize(const Font* font, const GraphicsContext* g
const FontData* fallbackFontData = m_font->fontDataForCharacters(m_run.characters() + substituteOffset, substituteLength);
substituteFontData = fallbackFontData ? fallbackFontData->fontDataForCharacter(m_run[0]) : 0;
if (substituteFontData) {
- initializeATSUStyle(substituteFontData);
+ initializeATSUStyle(substituteFontData, m_font->fontDescription().textRenderingMode());
if (substituteFontData->m_ATSUStyle)
ATSUSetRunStyle(layout, substituteFontData->m_ATSUStyle, substituteOffset, substituteLength);
} else
@@ -412,7 +421,7 @@ void ATSULayoutParameters::initialize(const Font* font, const GraphicsContext* g
if (i == substituteOffset || i == substituteOffset + substituteLength) {
if (isSmallCap) {
isSmallCap = false;
- initializeATSUStyle(r->smallCapsFontData(m_font->fontDescription()));
+ initializeATSUStyle(r->smallCapsFontData(m_font->fontDescription()), m_font->fontDescription().textRenderingMode());
ATSUSetRunStyle(layout, r->smallCapsFontData(m_font->fontDescription())->m_ATSUStyle, firstSmallCap, i - firstSmallCap);
}
if (i == substituteOffset && substituteLength > 0)
@@ -456,7 +465,7 @@ void ATSULayoutParameters::initialize(const Font* font, const GraphicsContext* g
} else {
if (isSmallCap) {
isSmallCap = false;
- initializeATSUStyle(smallCapsData);
+ initializeATSUStyle(smallCapsData, m_font->fontDescription().textRenderingMode());
ATSUSetRunStyle(layout, smallCapsData->m_ATSUStyle, firstSmallCap, i - firstSmallCap);
}
m_fonts[i] = r;
@@ -504,8 +513,8 @@ FloatRect Font::selectionRectForComplexText(const TextRun& run, const IntPoint&
firstGlyphBounds = zeroTrapezoid;
}
- float beforeWidth = MIN(FixedToFloat(firstGlyphBounds.lowerLeft.x), FixedToFloat(firstGlyphBounds.upperLeft.x));
- float afterWidth = MAX(FixedToFloat(firstGlyphBounds.lowerRight.x), FixedToFloat(firstGlyphBounds.upperRight.x));
+ float beforeWidth = min(FixedToFloat(firstGlyphBounds.lowerLeft.x), FixedToFloat(firstGlyphBounds.upperLeft.x));
+ float afterWidth = max(FixedToFloat(firstGlyphBounds.lowerRight.x), FixedToFloat(firstGlyphBounds.upperRight.x));
FloatRect rect(point.x() + floorf(beforeWidth), point.y(), roundf(afterWidth) - floorf(beforeWidth), h);
@@ -591,8 +600,8 @@ float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFon
if (actualNumBounds != 1)
LOG_ERROR("unexpected result from ATSUGetGlyphBounds(): actualNumBounds(%d) != 1", actualNumBounds);
- return MAX(FixedToFloat(firstGlyphBounds.upperRight.x), FixedToFloat(firstGlyphBounds.lowerRight.x)) -
- MIN(FixedToFloat(firstGlyphBounds.upperLeft.x), FixedToFloat(firstGlyphBounds.lowerLeft.x));
+ return max(FixedToFloat(firstGlyphBounds.upperRight.x), FixedToFloat(firstGlyphBounds.lowerRight.x)) -
+ min(FixedToFloat(firstGlyphBounds.upperLeft.x), FixedToFloat(firstGlyphBounds.lowerLeft.x));
}
int Font::offsetForPositionForComplexText(const TextRun& run, int x, bool /*includePartialGlyphs*/) const
diff --git a/WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp b/WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp
new file mode 100644
index 0000000..cd66445
--- /dev/null
+++ b/WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp
@@ -0,0 +1,1698 @@
+/*
+ * 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.
+ */
+
+#include "config.h"
+
+#if ENABLE(3D_CANVAS)
+
+#include "GraphicsContext3D.h"
+
+#include "CachedImage.h"
+#include "CanvasBuffer.h"
+#include "CanvasFramebuffer.h"
+#include "CanvasArray.h"
+#include "CanvasFloatArray.h"
+#include "CanvasIntArray.h"
+#include "CanvasObject.h"
+#include "CanvasProgram.h"
+#include "CanvasRenderbuffer.h"
+#include "CanvasShader.h"
+#include "CanvasTexture.h"
+#include "CanvasUnsignedByteArray.h"
+#include "CString.h"
+#include "HTMLCanvasElement.h"
+#include "HTMLImageElement.h"
+#include "ImageBuffer.h"
+#include "NotImplemented.h"
+#include "WebKitCSSMatrix.h"
+
+#include <CoreGraphics/CGBitmapContext.h>
+
+namespace WebCore {
+
+GraphicsContext3D::GraphicsContext3D()
+{
+ CGLPixelFormatAttribute attribs[] =
+ {
+ (CGLPixelFormatAttribute) kCGLPFAAccelerated,
+ (CGLPixelFormatAttribute) kCGLPFAColorSize, (CGLPixelFormatAttribute) 32,
+ (CGLPixelFormatAttribute) kCGLPFADepthSize, (CGLPixelFormatAttribute) 32,
+ (CGLPixelFormatAttribute) kCGLPFASupersample,
+ (CGLPixelFormatAttribute) 0
+ };
+
+ CGLPixelFormatObj pixelFormatObj;
+ GLint numPixelFormats;
+
+ CGLChoosePixelFormat(attribs, &pixelFormatObj, &numPixelFormats);
+
+ CGLCreateContext(pixelFormatObj, 0, &m_contextObj);
+
+ CGLDestroyPixelFormat(pixelFormatObj);
+
+ // Set the current context to the one given to us.
+ CGLSetCurrentContext(m_contextObj);
+
+ // 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);
+ ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
+ ::glBindTexture(GL_TEXTURE_2D, 0);
+
+ // create an FBO
+ ::glGenFramebuffersEXT(1, &m_fbo);
+ ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
+
+ ::glGenRenderbuffersEXT(1, &m_depthBuffer);
+ ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthBuffer);
+ ::glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, 1, 1);
+ ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
+
+ ::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0);
+ ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthBuffer);
+
+ ::glClearColor(0, 0, 0, 0);
+}
+
+GraphicsContext3D::~GraphicsContext3D()
+{
+ CGLSetCurrentContext(m_contextObj);
+ ::glDeleteRenderbuffersEXT(1, & m_depthBuffer);
+ ::glDeleteTextures(1, &m_texture);
+ ::glDeleteFramebuffersEXT(1, &m_fbo);
+ CGLSetCurrentContext(0);
+ CGLDestroyContext(m_contextObj);
+}
+
+void GraphicsContext3D::checkError() const
+{
+ // FIXME: This needs to only be done in the debug context. It will probably throw an exception
+ // on error and print the error message to the debug console
+ GLenum error = ::glGetError();
+ if (error != GL_NO_ERROR)
+ notImplemented();
+}
+
+void GraphicsContext3D::makeContextCurrent()
+{
+ CGLSetCurrentContext(m_contextObj);
+}
+
+void GraphicsContext3D::beginPaint(CanvasRenderingContext3D* context)
+{
+ UNUSED_PARAM(context);
+}
+
+void GraphicsContext3D::endPaint()
+{
+}
+
+void GraphicsContext3D::reshape(int width, int height)
+{
+ if (width == m_currentWidth && height == m_currentHeight)
+ return;
+
+ m_currentWidth = width;
+ m_currentHeight = height;
+
+ CGLSetCurrentContext(m_contextObj);
+
+ ::glBindTexture(GL_TEXTURE_2D, m_texture);
+ ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
+ ::glBindTexture(GL_TEXTURE_2D, 0);
+
+ ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
+ ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthBuffer);
+ ::glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height);
+ ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
+
+ ::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0);
+ ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthBuffer);
+ GLenum status = ::glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
+ if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ // FIXME: cleanup
+ notImplemented();
+ }
+
+ ::glViewport(0, 0, m_currentWidth, m_currentHeight);
+ ::glClear(GL_COLOR_BUFFER_BIT);
+ ::glFlush();
+}
+
+static inline void ensureContext(CGLContextObj context)
+{
+ CGLContextObj currentContext = CGLGetCurrentContext();
+ if (currentContext != context)
+ CGLSetCurrentContext(context);
+}
+
+void GraphicsContext3D::activeTexture(unsigned long texture)
+{
+ ensureContext(m_contextObj);
+ ::glActiveTexture(texture);
+}
+
+void GraphicsContext3D::attachShader(CanvasProgram* program, CanvasShader* shader)
+{
+ if (!program || !shader)
+ return;
+ ensureContext(m_contextObj);
+ ::glAttachShader((GLuint) program->object(), (GLuint) shader->object());
+}
+
+void GraphicsContext3D::bindAttribLocation(CanvasProgram* program, unsigned long index, const String& name)
+{
+ if (!program)
+ return;
+ ensureContext(m_contextObj);
+ ::glBindAttribLocation((GLuint) program->object(), index, name.utf8().data());
+}
+
+void GraphicsContext3D::bindBuffer(unsigned long target, CanvasBuffer* buffer)
+{
+ ensureContext(m_contextObj);
+ ::glBindBuffer(target, buffer ? (GLuint) buffer->object() : 0);
+}
+
+
+void GraphicsContext3D::bindFramebuffer(unsigned long target, CanvasFramebuffer* buffer)
+{
+ ensureContext(m_contextObj);
+ ::glBindFramebufferEXT(target, buffer ? (GLuint) buffer->object() : m_fbo);
+}
+
+void GraphicsContext3D::bindRenderbuffer(unsigned long target, CanvasRenderbuffer* renderbuffer)
+{
+ ensureContext(m_contextObj);
+ ::glBindBuffer(target, renderbuffer ? (GLuint) renderbuffer->object() : 0);
+}
+
+
+void GraphicsContext3D::bindTexture(unsigned long target, CanvasTexture* texture)
+{
+ ensureContext(m_contextObj);
+ ::glBindTexture(target, texture ? (GLuint) texture->object() : 0);
+}
+
+void GraphicsContext3D::blendColor(double red, double green, double blue, double alpha)
+{
+ ensureContext(m_contextObj);
+ ::glBlendColor(static_cast<float>(red), static_cast<float>(green), static_cast<float>(blue), static_cast<float>(alpha));
+}
+
+void GraphicsContext3D::blendEquation( unsigned long mode )
+{
+ ensureContext(m_contextObj);
+ ::glBlendEquation(mode);
+}
+
+void GraphicsContext3D::blendEquationSeparate(unsigned long modeRGB, unsigned long modeAlpha)
+{
+ ensureContext(m_contextObj);
+ ::glBlendEquationSeparate(modeRGB, modeAlpha);
+}
+
+
+void GraphicsContext3D::blendFunc(unsigned long sfactor, unsigned long dfactor)
+{
+ ensureContext(m_contextObj);
+ ::glBlendFunc(sfactor, dfactor);
+}
+
+void GraphicsContext3D::blendFuncSeparate(unsigned long srcRGB, unsigned long dstRGB, unsigned long srcAlpha, unsigned long dstAlpha)
+{
+ ensureContext(m_contextObj);
+ ::glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
+}
+
+void GraphicsContext3D::bufferData(unsigned long target, int size, unsigned long usage)
+{
+ ensureContext(m_contextObj);
+ ::glBufferData(target, size, 0, usage);
+}
+void GraphicsContext3D::bufferData(unsigned long target, CanvasArray* array, unsigned long usage)
+{
+ if (!array || !array->length())
+ return;
+
+ ensureContext(m_contextObj);
+ ::glBufferData(target, array->sizeInBytes(), array->baseAddress(), usage);
+}
+
+void GraphicsContext3D::bufferSubData(unsigned long target, long offset, CanvasArray* array)
+{
+ if (!array || !array->length())
+ return;
+
+ ensureContext(m_contextObj);
+ ::glBufferSubData(target, offset, array->sizeInBytes(), array->baseAddress());
+}
+
+unsigned long GraphicsContext3D::checkFramebufferStatus(unsigned long target)
+{
+ ensureContext(m_contextObj);
+ return ::glCheckFramebufferStatusEXT(target);
+}
+
+void GraphicsContext3D::clearColor(double r, double g, double b, double a)
+{
+ ensureContext(m_contextObj);
+ ::glClearColor(static_cast<float>(r), static_cast<float>(g), static_cast<float>(b), static_cast<float>(a));
+}
+
+void GraphicsContext3D::clear(unsigned long mask)
+{
+ ensureContext(m_contextObj);
+ ::glClear(mask);
+}
+
+void GraphicsContext3D::clearDepth(double depth)
+{
+ ensureContext(m_contextObj);
+ ::glClearDepth(depth);
+}
+
+void GraphicsContext3D::clearStencil(long s)
+{
+ ensureContext(m_contextObj);
+ ::glClearStencil(s);
+}
+
+void GraphicsContext3D::colorMask(bool red, bool green, bool blue, bool alpha)
+{
+ ensureContext(m_contextObj);
+ ::glColorMask(red, green, blue, alpha);
+}
+
+void GraphicsContext3D::compileShader(CanvasShader* shader)
+{
+ if (!shader)
+ return;
+
+ ensureContext(m_contextObj);
+ ::glCompileShader((GLuint) shader->object());
+}
+
+void GraphicsContext3D::copyTexImage2D(unsigned long target, long level, unsigned long internalformat, long x, long y, unsigned long width, unsigned long height, long border)
+{
+ ensureContext(m_contextObj);
+ ::glCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
+}
+
+void GraphicsContext3D::copyTexSubImage2D(unsigned long target, long level, long xoffset, long yoffset, long x, long y, unsigned long width, unsigned long height)
+{
+ ensureContext(m_contextObj);
+ ::glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
+}
+
+void GraphicsContext3D::cullFace(unsigned long mode)
+{
+ ensureContext(m_contextObj);
+ ::glCullFace(mode);
+}
+
+void GraphicsContext3D::depthFunc(unsigned long func)
+{
+ ensureContext(m_contextObj);
+ ::glDepthFunc(func);
+}
+
+void GraphicsContext3D::depthMask(bool flag)
+{
+ ensureContext(m_contextObj);
+ ::glDepthMask(flag);
+}
+
+void GraphicsContext3D::depthRange(double zNear, double zFar)
+{
+ ensureContext(m_contextObj);
+ ::glDepthRange(zNear, zFar);
+}
+
+void GraphicsContext3D::detachShader(CanvasProgram* program, CanvasShader* shader)
+{
+ if (!program || !shader)
+ return;
+
+ ensureContext(m_contextObj);
+ ::glDetachShader((GLuint) program->object(), (GLuint) shader->object());
+}
+
+void GraphicsContext3D::disable(unsigned long cap)
+{
+ ensureContext(m_contextObj);
+ ::glDisable(cap);
+}
+
+void GraphicsContext3D::disableVertexAttribArray(unsigned long index)
+{
+ ensureContext(m_contextObj);
+ ::glDisableVertexAttribArray(index);
+}
+
+void GraphicsContext3D::drawArrays(unsigned long mode, long first, long count)
+{
+ ensureContext(m_contextObj);
+ ::glDrawArrays(mode, first, count);
+}
+
+void GraphicsContext3D::drawElements(unsigned long mode, unsigned long count, unsigned long type, long offset)
+{
+ ensureContext(m_contextObj);
+ ::glDrawElements(mode, count, type, reinterpret_cast<void*>(static_cast<intptr_t>(offset)));
+}
+
+void GraphicsContext3D::enable(unsigned long cap)
+{
+ ensureContext(m_contextObj);
+ ::glEnable(cap);
+}
+
+void GraphicsContext3D::enableVertexAttribArray(unsigned long index)
+{
+ ensureContext(m_contextObj);
+ ::glEnableVertexAttribArray(index);
+}
+
+void GraphicsContext3D::finish()
+{
+ ensureContext(m_contextObj);
+ ::glFinish();
+}
+
+void GraphicsContext3D::flush()
+{
+ ensureContext(m_contextObj);
+ ::glFlush();
+}
+
+void GraphicsContext3D::framebufferRenderbuffer(unsigned long target, unsigned long attachment, unsigned long renderbuffertarget, CanvasRenderbuffer* buffer)
+{
+ if (!buffer)
+ return;
+
+ ensureContext(m_contextObj);
+ ::glFramebufferRenderbufferEXT(target, attachment, renderbuffertarget, (GLuint) buffer->object());
+}
+
+void GraphicsContext3D::framebufferTexture2D(unsigned long target, unsigned long attachment, unsigned long textarget, CanvasTexture* texture, long level)
+{
+ if (!texture)
+ return;
+
+ ensureContext(m_contextObj);
+ ::glFramebufferTexture2DEXT(target, attachment, textarget, (GLuint) texture->object(), level);
+}
+
+void GraphicsContext3D::frontFace(unsigned long mode)
+{
+ ensureContext(m_contextObj);
+ ::glFrontFace(mode);
+}
+
+void GraphicsContext3D::generateMipmap(unsigned long target)
+{
+ ensureContext(m_contextObj);
+ ::glGenerateMipmapEXT(target);
+}
+
+int GraphicsContext3D::getAttribLocation(CanvasProgram* program, const String& name)
+{
+ if (!program)
+ return -1;
+
+ ensureContext(m_contextObj);
+ return ::glGetAttribLocation((GLuint) program->object(), name.utf8().data());
+}
+
+unsigned long GraphicsContext3D::getError()
+{
+ ensureContext(m_contextObj);
+ return ::glGetError();
+}
+
+String GraphicsContext3D::getString(unsigned long name)
+{
+ ensureContext(m_contextObj);
+ return String((const char*) ::glGetString(name));
+}
+
+void GraphicsContext3D::hint(unsigned long target, unsigned long mode)
+{
+ ensureContext(m_contextObj);
+ ::glHint(target, mode);
+}
+
+bool GraphicsContext3D::isBuffer(CanvasBuffer* buffer)
+{
+ if (!buffer)
+ return false;
+
+ ensureContext(m_contextObj);
+ return ::glIsBuffer((GLuint) buffer->object());
+}
+
+bool GraphicsContext3D::isEnabled(unsigned long cap)
+{
+ ensureContext(m_contextObj);
+ return ::glIsEnabled(cap);
+}
+
+bool GraphicsContext3D::isFramebuffer(CanvasFramebuffer* framebuffer)
+{
+ if (!framebuffer)
+ return false;
+
+ ensureContext(m_contextObj);
+ return ::glIsFramebufferEXT((GLuint) framebuffer->object());
+}
+
+bool GraphicsContext3D::isProgram(CanvasProgram* program)
+{
+ if (!program)
+ return false;
+
+ ensureContext(m_contextObj);
+ return ::glIsProgram((GLuint) program->object());
+}
+
+bool GraphicsContext3D::isRenderbuffer(CanvasRenderbuffer* renderbuffer)
+{
+ if (!renderbuffer)
+ return false;
+
+ ensureContext(m_contextObj);
+ return ::glIsRenderbufferEXT((GLuint) renderbuffer->object());
+}
+
+bool GraphicsContext3D::isShader(CanvasShader* shader)
+{
+ if (!shader)
+ return false;
+
+ ensureContext(m_contextObj);
+ return ::glIsShader((GLuint) shader->object());
+}
+
+bool GraphicsContext3D::isTexture(CanvasTexture* texture)
+{
+ if (!texture)
+ return false;
+
+ ensureContext(m_contextObj);
+ return ::glIsTexture((GLuint) texture->object());
+}
+
+void GraphicsContext3D::lineWidth(double width)
+{
+ ensureContext(m_contextObj);
+ ::glLineWidth(static_cast<float>(width));
+}
+
+void GraphicsContext3D::linkProgram(CanvasProgram* program)
+{
+ if (!program)
+ return;
+
+ ensureContext(m_contextObj);
+ ::glLinkProgram((GLuint) program->object());
+}
+
+void GraphicsContext3D::pixelStorei(unsigned long pname, long param)
+{
+ ensureContext(m_contextObj);
+ ::glPixelStorei(pname, param);
+}
+
+void GraphicsContext3D::polygonOffset(double factor, double units)
+{
+ ensureContext(m_contextObj);
+ ::glPolygonOffset(static_cast<float>(factor), static_cast<float>(units));
+}
+
+void GraphicsContext3D::releaseShaderCompiler()
+{
+ // FIXME: This is not implemented on desktop OpenGL. We need to have ifdefs for the different GL variants
+ ensureContext(m_contextObj);
+ //::glReleaseShaderCompiler();
+}
+
+void GraphicsContext3D::renderbufferStorage(unsigned long target, unsigned long internalformat, unsigned long width, unsigned long height)
+{
+ ensureContext(m_contextObj);
+ ::glRenderbufferStorageEXT(target, internalformat, width, height);
+}
+
+void GraphicsContext3D::sampleCoverage(double value, bool invert)
+{
+ ensureContext(m_contextObj);
+ ::glSampleCoverage(static_cast<float>(value), invert);
+}
+
+void GraphicsContext3D::scissor(long x, long y, unsigned long width, unsigned long height)
+{
+ ensureContext(m_contextObj);
+ ::glScissor(x, y, width, height);
+}
+
+void GraphicsContext3D::shaderSource(CanvasShader* shader, const String& string)
+{
+ if (!shader)
+ return;
+
+ ensureContext(m_contextObj);
+ const CString& cs = string.utf8();
+ const char* s = cs.data();
+
+ int length = string.length();
+ ::glShaderSource((GLuint) shader->object(), 1, &s, &length);
+}
+
+void GraphicsContext3D::stencilFunc(unsigned long func, long ref, unsigned long mask)
+{
+ ensureContext(m_contextObj);
+ ::glStencilFunc(func, ref, mask);
+}
+
+void GraphicsContext3D::stencilFuncSeparate(unsigned long face, unsigned long func, long ref, unsigned long mask)
+{
+ ensureContext(m_contextObj);
+ ::glStencilFuncSeparate(face, func, ref, mask);
+}
+
+void GraphicsContext3D::stencilMask(unsigned long mask)
+{
+ ensureContext(m_contextObj);
+ ::glStencilMask(mask);
+}
+
+void GraphicsContext3D::stencilMaskSeparate(unsigned long face, unsigned long mask)
+{
+ ensureContext(m_contextObj);
+ ::glStencilMaskSeparate(face, mask);
+}
+
+void GraphicsContext3D::stencilOp(unsigned long fail, unsigned long zfail, unsigned long zpass)
+{
+ ensureContext(m_contextObj);
+ ::glStencilOp(fail, zfail, zpass);
+}
+
+void GraphicsContext3D::stencilOpSeparate(unsigned long face, unsigned long fail, unsigned long zfail, unsigned long zpass)
+{
+ ensureContext(m_contextObj);
+ ::glStencilOpSeparate(face, fail, zfail, zpass);
+}
+
+void GraphicsContext3D::texParameterf(unsigned target, unsigned pname, float value)
+{
+ ensureContext(m_contextObj);
+ ::glTexParameterf(target, pname, static_cast<float>(value));
+}
+
+void GraphicsContext3D::texParameteri(unsigned target, unsigned pname, int value)
+{
+ ensureContext(m_contextObj);
+ ::glTexParameteri(target, pname, static_cast<float>(value));
+}
+
+void GraphicsContext3D::uniform1f(long location, float v0)
+{
+ ensureContext(m_contextObj);
+ ::glUniform1f(location, v0);
+}
+
+void GraphicsContext3D::uniform1fv(long location, float* array, int size)
+{
+ ensureContext(m_contextObj);
+ ::glUniform1fv(location, size, array);
+}
+
+void GraphicsContext3D::uniform2f(long location, float v0, float v1)
+{
+ ensureContext(m_contextObj);
+ ::glUniform2f(location, v0, v1);
+}
+
+void GraphicsContext3D::uniform2fv(long location, float* array, int size)
+{
+ // FIXME: length needs to be a multiple of 2
+ ensureContext(m_contextObj);
+ ::glUniform2fv(location, size, array);
+}
+
+void GraphicsContext3D::uniform3f(long location, float v0, float v1, float v2)
+{
+ ensureContext(m_contextObj);
+ ::glUniform3f(location, v0, v1, v2);
+}
+
+void GraphicsContext3D::uniform3fv(long location, float* array, int size)
+{
+ // FIXME: length needs to be a multiple of 3
+ ensureContext(m_contextObj);
+ ::glUniform3fv(location, size, array);
+}
+
+void GraphicsContext3D::uniform4f(long location, float v0, float v1, float v2, float v3)
+{
+ ensureContext(m_contextObj);
+ ::glUniform4f(location, v0, v1, v2, v3);
+}
+
+void GraphicsContext3D::uniform4fv(long location, float* array, int size)
+{
+ // FIXME: length needs to be a multiple of 4
+ ensureContext(m_contextObj);
+ ::glUniform4fv(location, size, array);
+}
+
+void GraphicsContext3D::uniform1i(long location, int v0)
+{
+ ensureContext(m_contextObj);
+ ::glUniform1i(location, v0);
+}
+
+void GraphicsContext3D::uniform1iv(long location, int* array, int size)
+{
+ ensureContext(m_contextObj);
+ ::glUniform1iv(location, size, array);
+}
+
+void GraphicsContext3D::uniform2i(long location, int v0, int v1)
+{
+ ensureContext(m_contextObj);
+ ::glUniform2i(location, v0, v1);
+}
+
+void GraphicsContext3D::uniform2iv(long location, int* array, int size)
+{
+ // FIXME: length needs to be a multiple of 2
+ ensureContext(m_contextObj);
+ ::glUniform2iv(location, size, array);
+}
+
+void GraphicsContext3D::uniform3i(long location, int v0, int v1, int v2)
+{
+ ensureContext(m_contextObj);
+ ::glUniform3i(location, v0, v1, v2);
+}
+
+void GraphicsContext3D::uniform3iv(long location, int* array, int size)
+{
+ // FIXME: length needs to be a multiple of 3
+ ensureContext(m_contextObj);
+ ::glUniform3iv(location, size, array);
+}
+
+void GraphicsContext3D::uniform4i(long location, int v0, int v1, int v2, int v3)
+{
+ ensureContext(m_contextObj);
+ ::glUniform4i(location, v0, v1, v2, v3);
+}
+
+void GraphicsContext3D::uniform4iv(long location, int* array, int size)
+{
+ // FIXME: length needs to be a multiple of 4
+ ensureContext(m_contextObj);
+ ::glUniform4iv(location, size, array);
+}
+
+void GraphicsContext3D::uniformMatrix2fv(long location, bool transpose, float* array, int size)
+{
+ // FIXME: length needs to be a multiple of 4
+ ensureContext(m_contextObj);
+ ::glUniformMatrix2fv(location, size, transpose, array);
+}
+
+void GraphicsContext3D::uniformMatrix3fv(long location, bool transpose, float* array, int size)
+{
+ // FIXME: length needs to be a multiple of 9
+ ensureContext(m_contextObj);
+ ::glUniformMatrix3fv(location, size, transpose, array);
+}
+
+void GraphicsContext3D::uniformMatrix4fv(long location, bool transpose, float* array, int size)
+{
+ // FIXME: length needs to be a multiple of 16
+ ensureContext(m_contextObj);
+ ::glUniformMatrix4fv(location, size, transpose, array);
+}
+
+void GraphicsContext3D::useProgram(CanvasProgram* program)
+{
+ if (!program)
+ return;
+
+ ensureContext(m_contextObj);
+ ::glUseProgram((GLuint) program->object());
+}
+
+void GraphicsContext3D::validateProgram(CanvasProgram* program)
+{
+ if (!program)
+ return;
+
+ ensureContext(m_contextObj);
+ ::glValidateProgram((GLuint) program->object());
+}
+
+void GraphicsContext3D::vertexAttrib1f(unsigned long indx, float v0)
+{
+ ensureContext(m_contextObj);
+ ::glVertexAttrib1f(indx, v0);
+}
+
+void GraphicsContext3D::vertexAttrib1fv(unsigned long indx, float* array)
+{
+ ensureContext(m_contextObj);
+ ::glVertexAttrib1fv(indx, array);
+}
+
+void GraphicsContext3D::vertexAttrib2f(unsigned long indx, float v0, float v1)
+{
+ ensureContext(m_contextObj);
+ ::glVertexAttrib2f(indx, v0, v1);
+}
+
+void GraphicsContext3D::vertexAttrib2fv(unsigned long indx, float* array)
+{
+ ensureContext(m_contextObj);
+ ::glVertexAttrib2fv(indx, array);
+}
+
+void GraphicsContext3D::vertexAttrib3f(unsigned long indx, float v0, float v1, float v2)
+{
+ ensureContext(m_contextObj);
+ ::glVertexAttrib3f(indx, v0, v1, v2);
+}
+
+void GraphicsContext3D::vertexAttrib3fv(unsigned long indx, float* array)
+{
+ ensureContext(m_contextObj);
+ ::glVertexAttrib3fv(indx, array);
+}
+
+void GraphicsContext3D::vertexAttrib4f(unsigned long indx, float v0, float v1, float v2, float v3)
+{
+ ensureContext(m_contextObj);
+ ::glVertexAttrib4f(indx, v0, v1, v2, v3);
+}
+
+void GraphicsContext3D::vertexAttrib4fv(unsigned long indx, float* array)
+{
+ ensureContext(m_contextObj);
+ ::glVertexAttrib4fv(indx, array);
+}
+
+void GraphicsContext3D::vertexAttribPointer(unsigned long indx, int size, int type, bool normalized, unsigned long stride, unsigned long offset)
+{
+ ensureContext(m_contextObj);
+ ::glVertexAttribPointer(indx, size, type, normalized, stride, reinterpret_cast<void*>(static_cast<intptr_t>(offset)));
+}
+
+void GraphicsContext3D::viewport(long x, long y, unsigned long width, unsigned long height)
+{
+ ensureContext(m_contextObj);
+ ::glViewport(static_cast<GLint>(x), static_cast<GLint>(y), static_cast<GLsizei>(width), static_cast<GLsizei>(height));
+}
+
+static int sizeForGetParam(unsigned long pname)
+{
+ switch(pname) {
+ case GL_ACTIVE_TEXTURE: return 1;
+ case GL_ALIASED_LINE_WIDTH_RANGE: return 2;
+ case GL_ALIASED_POINT_SIZE_RANGE: return 2;
+ case GL_ALPHA_BITS: return 1;
+ case GL_ARRAY_BUFFER_BINDING: return 1; // (* actually a CanvasBuffer*)
+ case GL_BLEND: return 1;
+ case GL_BLEND_COLOR: return 4;
+ case GL_BLEND_DST_ALPHA: return 1;
+ case GL_BLEND_DST_RGB: return 1;
+ case GL_BLEND_EQUATION_ALPHA: return 1;
+ case GL_BLEND_EQUATION_RGB: return 1;
+ case GL_BLEND_SRC_ALPHA: return 1;
+ case GL_BLEND_SRC_RGB: return 1;
+ case GL_BLUE_BITS: return 1;
+ case GL_COLOR_CLEAR_VALUE: return 4;
+ case GL_COLOR_WRITEMASK: return 4;
+ case GL_COMPRESSED_TEXTURE_FORMATS: return GL_NUM_COMPRESSED_TEXTURE_FORMATS;
+ case GL_CULL_FACE: return 1;
+ case GL_CULL_FACE_MODE: return 1;
+ case GL_CURRENT_PROGRAM: return 1; // (* actually a CanvasProgram*)
+ case GL_DEPTH_BITS: return 1;
+ case GL_DEPTH_CLEAR_VALUE: return 1;
+ case GL_DEPTH_FUNC: return 1;
+ case GL_DEPTH_RANGE: return 2;
+ case GL_DEPTH_TEST: return 1;
+ case GL_DEPTH_WRITEMASK: return 1;
+ case GL_DITHER: return 1;
+ case GL_ELEMENT_ARRAY_BUFFER_BINDING: return 1; // (* actually a CanvasBuffer*)
+ case GL_FRAMEBUFFER_BINDING_EXT: return 1; // (* actually a CanvasFramebuffer*)
+ case GL_FRONT_FACE: return 1;
+ case GL_GENERATE_MIPMAP_HINT: return 1;
+ case GL_GREEN_BITS: return 1;
+ //case GL_IMPLEMENTATION_COLOR_READ_FORMAT:return 1;
+ //case GL_IMPLEMENTATION_COLOR_READ_TYPE: return 1;
+ case GL_LINE_WIDTH: return 1;
+ case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:return 1;
+ case GL_MAX_CUBE_MAP_TEXTURE_SIZE: return 1;
+ //case GL_MAX_FRAGMENT_UNIFORM_VECTORS: return 1;
+ case GL_MAX_RENDERBUFFER_SIZE_EXT: return 1;
+ case GL_MAX_TEXTURE_IMAGE_UNITS: return 1;
+ case GL_MAX_TEXTURE_SIZE: return 1;
+ //case GL_MAX_VARYING_VECTORS: return 1;
+ case GL_MAX_VERTEX_ATTRIBS: return 1;
+ case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: return 1;
+ //case GL_MAX_VERTEX_UNIFORM_VECTORS: return 1;
+ case GL_MAX_VIEWPORT_DIMS: return 2;
+ case GL_NUM_COMPRESSED_TEXTURE_FORMATS: return 1;
+ //case GL_NUM_SHADER_BINARY_FORMATS: return 1;
+ case GL_PACK_ALIGNMENT: return 1;
+ case GL_POLYGON_OFFSET_FACTOR: return 1;
+ case GL_POLYGON_OFFSET_FILL: return 1;
+ case GL_POLYGON_OFFSET_UNITS: return 1;
+ case GL_RED_BITS: return 1;
+ case GL_RENDERBUFFER_BINDING_EXT: return 1; // (* actually a CanvasRenderbuffer*)
+ case GL_SAMPLE_BUFFERS: return 1;
+ case GL_SAMPLE_COVERAGE_INVERT: return 1;
+ case GL_SAMPLE_COVERAGE_VALUE: return 1;
+ case GL_SAMPLES: return 1;
+ case GL_SCISSOR_BOX: return 4;
+ case GL_SCISSOR_TEST: return 1;
+ //case GL_SHADER_BINARY_FORMATS: return GL_NUM_SHADER_BINARY_FORMATS;
+ //case GL_SHADER_COMPILER: return 1;
+ case GL_STENCIL_BACK_FAIL: return 1;
+ case GL_STENCIL_BACK_FUNC: return 1;
+ case GL_STENCIL_BACK_PASS_DEPTH_FAIL: return 1;
+ case GL_STENCIL_BACK_PASS_DEPTH_PASS: return 1;
+ case GL_STENCIL_BACK_REF: return 1;
+ case GL_STENCIL_BACK_VALUE_MASK: return 1;
+ case GL_STENCIL_BACK_WRITEMASK: return 1;
+ case GL_STENCIL_BITS: return 1;
+ case GL_STENCIL_CLEAR_VALUE: return 1;
+ case GL_STENCIL_FAIL: return 1;
+ case GL_STENCIL_FUNC: return 1;
+ case GL_STENCIL_PASS_DEPTH_FAIL: return 1;
+ case GL_STENCIL_PASS_DEPTH_PASS: return 1;
+ case GL_STENCIL_REF: return 1;
+ case GL_STENCIL_TEST: return 1;
+ case GL_STENCIL_VALUE_MASK: return 1;
+ case GL_STENCIL_WRITEMASK: return 1;
+ case GL_SUBPIXEL_BITS: return 1;
+ case GL_TEXTURE_BINDING_2D: return 1; // (* actually a CanvasTexture*)
+ case GL_TEXTURE_BINDING_CUBE_MAP: return 1; // (* actually a CanvasTexture*)
+ case GL_UNPACK_ALIGNMENT: return 1;
+ case GL_VIEWPORT: return 4;
+ }
+
+ return -1;
+}
+
+bool GraphicsContext3D::getBoolean(unsigned long pname)
+{
+ int size = sizeForGetParam(pname);
+ if (size < 1)
+ return 0;
+
+ ensureContext(m_contextObj);
+
+ bool isAlloced = false;
+ GLboolean buf[4];
+ GLboolean* pbuf = buf;
+
+ if (size > 4) {
+ pbuf = (GLboolean*) malloc(size * sizeof(GLboolean));
+ isAlloced = true;
+ }
+
+ ::glGetBooleanv(pname, pbuf);
+
+ bool value = pbuf[0];
+
+ if (isAlloced)
+ free(pbuf);
+
+ return value;
+}
+
+PassRefPtr<CanvasUnsignedByteArray> GraphicsContext3D::getBooleanv(unsigned long pname)
+{
+ int size = sizeForGetParam(pname);
+ if (size < 1)
+ return 0;
+
+ ensureContext(m_contextObj);
+
+ RefPtr<CanvasUnsignedByteArray> array = CanvasUnsignedByteArray::create(size);
+ bool isAlloced = false;
+ GLboolean buf[4];
+ GLboolean* pbuf = buf;
+
+ if (size > 4) {
+ pbuf = (GLboolean*) malloc(size * sizeof(GLboolean));
+ isAlloced = true;
+ }
+
+ ::glGetBooleanv(pname, pbuf);
+
+ for (int i = 0; i < size; ++i)
+ array->set(i, static_cast<unsigned char>(pbuf[i]));
+
+ if (isAlloced)
+ free(pbuf);
+
+ return array;
+}
+
+float GraphicsContext3D::getFloat(unsigned long pname)
+{
+ int size = sizeForGetParam(pname);
+ if (size < 1)
+ return 0;
+
+ ensureContext(m_contextObj);
+
+ bool isAlloced = false;
+ GLfloat buf[4];
+ GLfloat* pbuf = buf;
+
+ if (size > 4) {
+ pbuf = (GLfloat*) malloc(size * sizeof(GLfloat));
+ isAlloced = true;
+ }
+
+ ::glGetFloatv(pname, pbuf);
+
+ float value = pbuf[0];
+
+ if (isAlloced)
+ free(pbuf);
+
+ return value;
+}
+
+PassRefPtr<CanvasFloatArray> GraphicsContext3D::getFloatv(unsigned long pname)
+{
+ int size = sizeForGetParam(pname);
+ if (size < 1)
+ return 0;
+
+ ensureContext(m_contextObj);
+
+ RefPtr<CanvasFloatArray> array = CanvasFloatArray::create(size);
+ bool isAlloced = false;
+ GLfloat buf[4];
+ GLfloat* pbuf = buf;
+
+ if (size > 4) {
+ pbuf = (GLfloat*) malloc(size * sizeof(GLfloat));
+ isAlloced = true;
+ }
+
+ ::glGetFloatv(pname, pbuf);
+
+ for (int i = 0; i < size; ++i)
+ array->set(i, static_cast<float>(pbuf[i]));
+
+ if (isAlloced)
+ free(pbuf);
+
+ return array;
+}
+
+int GraphicsContext3D::getInteger(unsigned long pname)
+{
+ int size = sizeForGetParam(pname);
+ if (size < 1)
+ return 0;
+
+ ensureContext(m_contextObj);
+
+ bool isAlloced = false;
+ GLint buf[4];
+ GLint* pbuf = buf;
+
+ if (size > 4) {
+ pbuf = (GLint*) malloc(size * sizeof(GLint));
+ isAlloced = true;
+ }
+
+ ::glGetIntegerv(pname, pbuf);
+
+ int value = pbuf[0];
+
+ if (isAlloced)
+ free(pbuf);
+
+ return value;
+}
+
+PassRefPtr<CanvasIntArray> GraphicsContext3D::getIntegerv(unsigned long pname)
+{
+ int size = sizeForGetParam(pname);
+ if (size < 1)
+ return 0;
+
+ ensureContext(m_contextObj);
+
+ RefPtr<CanvasIntArray> array = CanvasIntArray::create(size);
+ bool isAlloced = false;
+ GLint buf[4];
+ GLint* pbuf = buf;
+
+ if (size > 4) {
+ pbuf = (GLint*) malloc(size * sizeof(GLint));
+ isAlloced = true;
+ }
+
+ ::glGetIntegerv(pname, pbuf);
+
+ for (int i = 0; i < size; ++i)
+ array->set(i, static_cast<int>(pbuf[i]));
+
+ if (isAlloced)
+ free(pbuf);
+
+ return array;
+}
+
+int GraphicsContext3D::getBufferParameteri(unsigned long target, unsigned long pname)
+{
+ ensureContext(m_contextObj);
+ GLint data;
+ ::glGetBufferParameteriv(target, pname, &data);
+ return data;
+}
+
+PassRefPtr<CanvasIntArray> GraphicsContext3D::getBufferParameteriv(unsigned long target, unsigned long pname)
+{
+ ensureContext(m_contextObj);
+ RefPtr<CanvasIntArray> array = CanvasIntArray::create(1);
+ GLint data;
+ ::glGetBufferParameteriv(target, pname, &data);
+ array->set(0, static_cast<int>(data));
+
+ return array;
+}
+
+int GraphicsContext3D::getFramebufferAttachmentParameteri(unsigned long target, unsigned long attachment, unsigned long pname)
+{
+ ensureContext(m_contextObj);
+ GLint data;
+ ::glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, &data);
+ return data;
+}
+
+PassRefPtr<CanvasIntArray> GraphicsContext3D::getFramebufferAttachmentParameteriv(unsigned long target, unsigned long attachment, unsigned long pname)
+{
+ ensureContext(m_contextObj);
+ RefPtr<CanvasIntArray> array = CanvasIntArray::create(1);
+ GLint data;
+ ::glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, &data);
+ array->set(0, static_cast<int>(data));
+
+ return array;
+}
+
+int GraphicsContext3D::getProgrami(CanvasProgram* program, unsigned long pname)
+{
+ ensureContext(m_contextObj);
+ GLint data;
+ ::glGetProgramiv((GLuint) program->object(), pname, &data);
+ return data;
+}
+
+PassRefPtr<CanvasIntArray> GraphicsContext3D::getProgramiv(CanvasProgram* program, unsigned long pname)
+{
+ ensureContext(m_contextObj);
+ RefPtr<CanvasIntArray> array = CanvasIntArray::create(1);
+ GLint data;
+ ::glGetProgramiv((GLuint) program->object(), pname, &data);
+ array->set(0, static_cast<int>(data));
+
+ return array;
+}
+
+String GraphicsContext3D::getProgramInfoLog(CanvasProgram* program)
+{
+ if (!program)
+ return String();
+
+ ensureContext(m_contextObj);
+ GLint length;
+ ::glGetProgramiv((GLuint) program->object(), GL_INFO_LOG_LENGTH, &length);
+
+ GLsizei size;
+ GLchar* info = (GLchar*) malloc(length);
+ ::glGetProgramInfoLog((GLuint) program->object(), length, &size, info);
+ String s(info);
+ free(info);
+ return s;
+}
+
+int GraphicsContext3D::getRenderbufferParameteri(unsigned long target, unsigned long pname)
+{
+ ensureContext(m_contextObj);
+ GLint data;
+ ::glGetBufferParameteriv(target, pname, &data);
+ return data;
+}
+
+PassRefPtr<CanvasIntArray> GraphicsContext3D::getRenderbufferParameteriv(unsigned long target, unsigned long pname)
+{
+ ensureContext(m_contextObj);
+ RefPtr<CanvasIntArray> array = CanvasIntArray::create(1);
+ GLint data;
+ ::glGetBufferParameteriv(target, pname, &data);
+ array->set(0, static_cast<int>(data));
+
+ return array;
+}
+
+int GraphicsContext3D::getShaderi(CanvasShader* shader, unsigned long pname)
+{
+ if (!shader)
+ return 0;
+
+ ensureContext(m_contextObj);
+ GLint data;
+ ::glGetShaderiv((GLuint) shader->object(), pname, &data);
+ return data;
+}
+
+PassRefPtr<CanvasIntArray> GraphicsContext3D::getShaderiv(CanvasShader* shader, unsigned long pname)
+{
+ if (!shader)
+ return 0;
+
+ ensureContext(m_contextObj);
+ RefPtr<CanvasIntArray> array = CanvasIntArray::create(1);
+ GLint data;
+ ::glGetShaderiv((GLuint) shader->object(), pname, &data);
+ array->set(0, static_cast<int>(data));
+
+ return array;
+}
+
+String GraphicsContext3D::getShaderInfoLog(CanvasShader* shader)
+{
+ if (!shader)
+ return String();
+
+ ensureContext(m_contextObj);
+ GLint length;
+ ::glGetShaderiv((GLuint) shader->object(), GL_INFO_LOG_LENGTH, &length);
+
+ GLsizei size;
+ GLchar* info = (GLchar*) malloc(length);
+ ::glGetShaderInfoLog((GLuint) shader->object(), length, &size, info);
+ String s(info);
+ free(info);
+ return s;
+}
+
+String GraphicsContext3D::getShaderSource(CanvasShader* shader)
+{
+ if (!shader)
+ return String();
+
+ ensureContext(m_contextObj);
+ GLint length;
+ ::glGetShaderiv((GLuint) shader->object(), GL_SHADER_SOURCE_LENGTH, &length);
+
+ GLsizei size;
+ GLchar* info = (GLchar*) malloc(length);
+ ::glGetShaderSource((GLuint) shader->object(), length, &size, info);
+ String s(info);
+ free(info);
+ return s;
+}
+
+
+float GraphicsContext3D::getTexParameterf(unsigned long target, unsigned long pname)
+{
+ ensureContext(m_contextObj);
+ GLfloat data;
+ ::glGetTexParameterfv(target, pname, &data);
+ return data;
+}
+
+PassRefPtr<CanvasFloatArray> GraphicsContext3D::getTexParameterfv(unsigned long target, unsigned long pname)
+{
+ ensureContext(m_contextObj);
+ RefPtr<CanvasFloatArray> array = CanvasFloatArray::create(1);
+ GLfloat data;
+ ::glGetTexParameterfv(target, pname, &data);
+ array->set(0, static_cast<float>(data));
+
+ return array;
+}
+
+int GraphicsContext3D::getTexParameteri(unsigned long target, unsigned long pname)
+{
+ ensureContext(m_contextObj);
+ GLint data;
+ ::glGetTexParameteriv(target, pname, &data);
+ return data;
+}
+
+PassRefPtr<CanvasIntArray> GraphicsContext3D::getTexParameteriv(unsigned long target, unsigned long pname)
+{
+ ensureContext(m_contextObj);
+ RefPtr<CanvasIntArray> array = CanvasIntArray::create(1);
+ GLint data;
+ ::glGetTexParameteriv(target, pname, &data);
+ array->set(0, static_cast<int>(data));
+
+ return array;
+}
+
+float GraphicsContext3D::getUniformf(CanvasProgram* program, long location)
+{
+ // FIXME: We need to query glGetUniformLocation to determine the size needed
+ UNUSED_PARAM(program);
+ UNUSED_PARAM(location);
+ notImplemented();
+ return 0;
+}
+
+PassRefPtr<CanvasFloatArray> GraphicsContext3D::getUniformfv(CanvasProgram* program, long location)
+{
+ // FIXME: We need to query glGetUniformLocation to determine the size needed
+ UNUSED_PARAM(program);
+ UNUSED_PARAM(location);
+ notImplemented();
+ return 0;
+}
+
+int GraphicsContext3D::getUniformi(CanvasProgram* program, long location)
+{
+ // FIXME: We need to query glGetUniformLocation to determine the size needed
+ UNUSED_PARAM(program);
+ UNUSED_PARAM(location);
+ notImplemented();
+ return 0;
+}
+
+PassRefPtr<CanvasIntArray> GraphicsContext3D::getUniformiv(CanvasProgram* program, long location)
+{
+ // FIXME: We need to query glGetUniformLocation to determine the size needed
+ UNUSED_PARAM(program);
+ UNUSED_PARAM(location);
+ notImplemented();
+ return 0;
+}
+
+long GraphicsContext3D::getUniformLocation(CanvasProgram* program, const String& name)
+{
+ if (!program)
+ return -1;
+
+ ensureContext(m_contextObj);
+ return ::glGetUniformLocation((GLuint) program->object(), name.utf8().data());
+}
+
+static int sizeForGetVertexAttribParam(unsigned long pname)
+{
+ switch(pname) {
+ case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: return 1; // (* actually a CanvasBuffer*)
+ case GL_VERTEX_ATTRIB_ARRAY_ENABLED: return 1;
+ case GL_VERTEX_ATTRIB_ARRAY_SIZE: return 1;
+ case GL_VERTEX_ATTRIB_ARRAY_STRIDE: return 1;
+ case GL_VERTEX_ATTRIB_ARRAY_TYPE: return 1;
+ case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: return 1;
+ case GL_CURRENT_VERTEX_ATTRIB: return 4;
+ }
+
+ return -1;
+}
+
+float GraphicsContext3D::getVertexAttribf(unsigned long index, unsigned long pname)
+{
+ ensureContext(m_contextObj);
+ GLfloat buf[4];
+ ::glGetVertexAttribfv(index, pname, buf);
+ return buf[0];
+}
+
+PassRefPtr<CanvasFloatArray> GraphicsContext3D::getVertexAttribfv(unsigned long index, unsigned long pname)
+{
+ int size = sizeForGetVertexAttribParam(pname);
+ if (size < 1)
+ return 0;
+
+ ensureContext(m_contextObj);
+
+ RefPtr<CanvasFloatArray> array = CanvasFloatArray::create(size);
+ GLfloat buf[4];
+ ::glGetVertexAttribfv(index, pname, buf);
+
+ for (int i = 0; i < size; ++i)
+ array->set(i, static_cast<float>(buf[i]));
+
+ return array;
+}
+
+int GraphicsContext3D::getVertexAttribi(unsigned long index, unsigned long pname)
+{
+ ensureContext(m_contextObj);
+ GLint buf[4];
+ ::glGetVertexAttribiv(index, pname, buf);
+ return buf[0];
+}
+
+PassRefPtr<CanvasIntArray> GraphicsContext3D::getVertexAttribiv(unsigned long index, unsigned long pname)
+{
+ int size = sizeForGetVertexAttribParam(pname);
+ if (size < 1)
+ return 0;
+
+ ensureContext(m_contextObj);
+
+ RefPtr<CanvasIntArray> array = CanvasIntArray::create(size);
+ GLint buf[4];
+ ::glGetVertexAttribiv(index, pname, buf);
+
+ for (int i = 0; i < size; ++i)
+ array->set(i, static_cast<int>(buf[i]));
+
+ return array;
+}
+
+long GraphicsContext3D::getVertexAttribOffset(unsigned long index, unsigned long pname)
+{
+ ensureContext(m_contextObj);
+
+ void* pointer;
+ ::glGetVertexAttribPointerv(index, pname, &pointer);
+ return reinterpret_cast<long>(pointer);
+}
+
+// Assumes the texture you want to go into is bound
+static void imageToTexture(Image* image, unsigned target, unsigned level)
+{
+ if (!image)
+ return;
+
+ CGImageRef textureImage = image->getCGImageRef();
+ if (!textureImage)
+ return;
+
+ size_t textureWidth = CGImageGetWidth(textureImage);
+ size_t textureHeight = CGImageGetHeight(textureImage);
+
+ GLubyte* textureData = (GLubyte*) malloc(textureWidth * textureHeight * 4);
+ CGContextRef textureContext = CGBitmapContextCreate(textureData, textureWidth, textureHeight, 8, textureWidth * 4,
+ CGImageGetColorSpace(textureImage), kCGImageAlphaPremultipliedLast);
+
+ CGContextDrawImage(textureContext, CGRectMake(0, 0, (CGFloat)textureWidth, (CGFloat)textureHeight), textureImage);
+ CGContextRelease(textureContext);
+
+ ::glTexImage2D(target, level, GL_RGBA, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData);
+ free(textureData);
+}
+
+int GraphicsContext3D::texImage2D(unsigned target, unsigned level, unsigned internalformat, unsigned width, unsigned height, unsigned border, unsigned format, unsigned type, CanvasArray* pixels)
+{
+ // FIXME: Need to do bounds checking on the buffer here.
+ ::glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels->baseAddress());
+ return 0;
+}
+
+int GraphicsContext3D::texImage2D(unsigned target, unsigned level, unsigned internalformat, unsigned width, unsigned height, unsigned border, unsigned format, unsigned type, ImageData* pixels)
+{
+ // FIXME: need to implement this form
+ UNUSED_PARAM(target);
+ UNUSED_PARAM(level);
+ UNUSED_PARAM(internalformat);
+ UNUSED_PARAM(width);
+ UNUSED_PARAM(height);
+ UNUSED_PARAM(border);
+ UNUSED_PARAM(format);
+ UNUSED_PARAM(type);
+ UNUSED_PARAM(pixels);
+ return -1;
+}
+
+int GraphicsContext3D::texImage2D(unsigned target, unsigned level, HTMLImageElement* image, bool flipY, bool premultiplyAlpha)
+{
+ // FIXME: need to support flipY and premultiplyAlpha
+ UNUSED_PARAM(flipY);
+ UNUSED_PARAM(premultiplyAlpha);
+
+ if (!image)
+ return -1;
+
+ ensureContext(m_contextObj);
+ CachedImage* cachedImage = image->cachedImage();
+ if (!cachedImage)
+ return -1;
+
+ imageToTexture(cachedImage->image(), target, level);
+ return 0;
+}
+
+int GraphicsContext3D::texImage2D(unsigned target, unsigned level, HTMLCanvasElement* canvas, bool flipY, bool premultiplyAlpha)
+{
+ // FIXME: need to support flipY and premultiplyAlpha
+ UNUSED_PARAM(flipY);
+ UNUSED_PARAM(premultiplyAlpha);
+
+ if (!canvas)
+ return -1;
+
+ ensureContext(m_contextObj);
+ ImageBuffer* buffer = canvas->buffer();
+ if (!buffer)
+ return -1;
+
+ imageToTexture(buffer->image(), target, level);
+ return 0;
+}
+
+int GraphicsContext3D::texImage2D(unsigned target, unsigned level, HTMLVideoElement* video, bool flipY, bool premultiplyAlpha)
+{
+ // FIXME: need to implement this form
+ UNUSED_PARAM(target);
+ UNUSED_PARAM(level);
+ UNUSED_PARAM(video);
+
+ // FIXME: need to support flipY and premultiplyAlpha
+ UNUSED_PARAM(flipY);
+ UNUSED_PARAM(premultiplyAlpha);
+ return -1;
+}
+
+int GraphicsContext3D::texSubImage2D(unsigned target, unsigned level, unsigned xoff, unsigned yoff, unsigned width, unsigned height, unsigned format, unsigned type, CanvasArray* pixels)
+{
+ // FIXME: we will need to deal with PixelStore params when dealing with image buffers that differ from the subimage size
+ UNUSED_PARAM(target);
+ UNUSED_PARAM(level);
+ UNUSED_PARAM(xoff);
+ UNUSED_PARAM(yoff);
+ UNUSED_PARAM(width);
+ UNUSED_PARAM(height);
+ UNUSED_PARAM(format);
+ UNUSED_PARAM(type);
+ UNUSED_PARAM(pixels);
+ return -1;
+}
+
+int GraphicsContext3D::texSubImage2D(unsigned target, unsigned level, unsigned xoff, unsigned yoff, unsigned width, unsigned height, unsigned format, unsigned type, ImageData* pixels)
+{
+ // FIXME: we will need to deal with PixelStore params when dealing with image buffers that differ from the subimage size
+ UNUSED_PARAM(target);
+ UNUSED_PARAM(level);
+ UNUSED_PARAM(xoff);
+ UNUSED_PARAM(yoff);
+ UNUSED_PARAM(width);
+ UNUSED_PARAM(height);
+ UNUSED_PARAM(format);
+ UNUSED_PARAM(type);
+ UNUSED_PARAM(pixels);
+ return -1;
+}
+
+int GraphicsContext3D::texSubImage2D(unsigned target, unsigned level, unsigned xoff, unsigned yoff, unsigned width, unsigned height, HTMLImageElement* image, bool flipY, bool premultiplyAlpha)
+{
+ // FIXME: we will need to deal with PixelStore params when dealing with image buffers that differ from the subimage size
+ UNUSED_PARAM(target);
+ UNUSED_PARAM(level);
+ UNUSED_PARAM(xoff);
+ UNUSED_PARAM(yoff);
+ UNUSED_PARAM(width);
+ UNUSED_PARAM(height);
+ UNUSED_PARAM(image);
+
+ // FIXME: need to support flipY and premultiplyAlpha
+ UNUSED_PARAM(flipY);
+ UNUSED_PARAM(premultiplyAlpha);
+ return -1;
+}
+
+int GraphicsContext3D::texSubImage2D(unsigned target, unsigned level, unsigned xoff, unsigned yoff, unsigned width, unsigned height, HTMLCanvasElement* canvas, bool flipY, bool premultiplyAlpha)
+{
+ // FIXME: we will need to deal with PixelStore params when dealing with image buffers that differ from the subimage size
+ UNUSED_PARAM(target);
+ UNUSED_PARAM(level);
+ UNUSED_PARAM(xoff);
+ UNUSED_PARAM(yoff);
+ UNUSED_PARAM(width);
+ UNUSED_PARAM(height);
+ UNUSED_PARAM(canvas);
+
+ // FIXME: need to support flipY and premultiplyAlpha
+ UNUSED_PARAM(flipY);
+ UNUSED_PARAM(premultiplyAlpha);
+ return -1;
+}
+
+int GraphicsContext3D::texSubImage2D(unsigned target, unsigned level, unsigned xoff, unsigned yoff, unsigned width, unsigned height, HTMLVideoElement* video, bool flipY, bool premultiplyAlpha)
+{
+ // FIXME: we will need to deal with PixelStore params when dealing with image buffers that differ from the subimage size
+ UNUSED_PARAM(target);
+ UNUSED_PARAM(level);
+ UNUSED_PARAM(xoff);
+ UNUSED_PARAM(yoff);
+ UNUSED_PARAM(width);
+ UNUSED_PARAM(height);
+ UNUSED_PARAM(video);
+
+ // FIXME: need to support flipY and premultiplyAlpha
+ UNUSED_PARAM(flipY);
+ UNUSED_PARAM(premultiplyAlpha);
+ return -1;
+}
+
+unsigned GraphicsContext3D::createBuffer()
+{
+ ensureContext(m_contextObj);
+ GLuint o;
+ glGenBuffers(1, &o);
+ return o;
+}
+
+unsigned GraphicsContext3D::createFramebuffer()
+{
+ ensureContext(m_contextObj);
+ GLuint o;
+ glGenFramebuffersEXT(1, &o);
+ return o;
+}
+
+unsigned GraphicsContext3D::createProgram()
+{
+ ensureContext(m_contextObj);
+ return glCreateProgram();
+}
+
+unsigned GraphicsContext3D::createRenderbuffer()
+{
+ ensureContext(m_contextObj);
+ GLuint o;
+ glGenRenderbuffersEXT(1, &o);
+ return o;
+}
+
+unsigned GraphicsContext3D::createShader(ShaderType type)
+{
+ ensureContext(m_contextObj);
+ return glCreateShader((type == FRAGMENT_SHADER) ? GL_FRAGMENT_SHADER : GL_VERTEX_SHADER);
+}
+
+unsigned GraphicsContext3D::createTexture()
+{
+ ensureContext(m_contextObj);
+ GLuint o;
+ glGenTextures(1, &o);
+ return o;
+}
+
+void GraphicsContext3D::deleteBuffer(unsigned buffer)
+{
+ ensureContext(m_contextObj);
+ glDeleteBuffers(1, &buffer);
+}
+
+void GraphicsContext3D::deleteFramebuffer(unsigned framebuffer)
+{
+ ensureContext(m_contextObj);
+ glDeleteFramebuffersEXT(1, &framebuffer);
+}
+
+void GraphicsContext3D::deleteProgram(unsigned program)
+{
+ ensureContext(m_contextObj);
+ glDeleteProgram(program);
+}
+
+void GraphicsContext3D::deleteRenderbuffer(unsigned renderbuffer)
+{
+ ensureContext(m_contextObj);
+ glDeleteRenderbuffersEXT(1, &renderbuffer);
+}
+
+void GraphicsContext3D::deleteShader(unsigned shader)
+{
+ ensureContext(m_contextObj);
+ glDeleteShader(shader);
+}
+
+void GraphicsContext3D::deleteTexture(unsigned texture)
+{
+ ensureContext(m_contextObj);
+ glDeleteTextures(1, &texture);
+}
+
+int GraphicsContext3D::sizeInBytes(int type)
+{
+ switch (type) {
+ case GL_BYTE:
+ return sizeof(GLbyte);
+ case GL_UNSIGNED_BYTE:
+ return sizeof(GLubyte);
+ case GL_SHORT:
+ return sizeof(GLshort);
+ case GL_UNSIGNED_SHORT:
+ return sizeof(GLushort);
+ case GL_INT:
+ return sizeof(GLint);
+ case GL_UNSIGNED_INT:
+ return sizeof(GLuint);
+ case GL_FLOAT:
+ return sizeof(GLfloat);
+ default:
+ return 0;
+ }
+}
+
+}
+
+#endif // ENABLE(3D_CANVAS)
diff --git a/WebCore/platform/graphics/mac/GraphicsContextMac.mm b/WebCore/platform/graphics/mac/GraphicsContextMac.mm
index 2404319..6c9b872 100644
--- a/WebCore/platform/graphics/mac/GraphicsContextMac.mm
+++ b/WebCore/platform/graphics/mac/GraphicsContextMac.mm
@@ -50,27 +50,26 @@ void GraphicsContext::drawFocusRing(const Color& color)
int radius = (focusRingWidth() - 1) / 2;
int offset = radius + focusRingOffset();
- CGColorRef colorRef = color.isValid() ? createCGColor(color) : 0;
+ RetainPtr<CGColorRef> colorRef;
+ if (color.isValid())
+ colorRef.adoptCF(createCGColor(color));
- CGMutablePathRef focusRingPath = CGPathCreateMutable();
+ RetainPtr<CGMutablePathRef> focusRingPath(AdoptCF, CGPathCreateMutable());
const Vector<IntRect>& rects = focusRingRects();
unsigned rectCount = rects.size();
for (unsigned i = 0; i < rectCount; i++)
- CGPathAddRect(focusRingPath, 0, CGRectInset(rects[i], -offset, -offset));
+ CGPathAddRect(focusRingPath.get(), 0, CGRectInset(rects[i], -offset, -offset));
CGContextRef context = platformContext();
#ifdef BUILDING_ON_TIGER
CGContextBeginTransparencyLayer(context, NULL);
#endif
CGContextBeginPath(context);
- CGContextAddPath(context, focusRingPath);
- wkDrawFocusRing(context, colorRef, radius);
+ CGContextAddPath(context, focusRingPath.get());
+ wkDrawFocusRing(context, colorRef.get(), radius);
#ifdef BUILDING_ON_TIGER
CGContextEndTransparencyLayer(context);
#endif
- CGColorRelease(colorRef);
-
- CGPathRelease(focusRingPath);
}
#ifdef BUILDING_ON_TIGER // Post-Tiger's setCompositeOperation() is defined in GraphicsContextCG.cpp.
diff --git a/WebCore/platform/graphics/mac/GraphicsLayerCA.h b/WebCore/platform/graphics/mac/GraphicsLayerCA.h
index ebdc6ac..d0e1108 100644
--- a/WebCore/platform/graphics/mac/GraphicsLayerCA.h
+++ b/WebCore/platform/graphics/mac/GraphicsLayerCA.h
@@ -62,6 +62,8 @@ public:
virtual void removeFromParent();
+ virtual void setMaskLayer(GraphicsLayer*);
+
virtual void setPosition(const FloatPoint&);
virtual void setAnchorPoint(const FloatPoint3D&);
virtual void setSize(const FloatSize&);
@@ -86,6 +88,10 @@ public:
virtual void setNeedsDisplay();
virtual void setNeedsDisplayInRect(const FloatRect&);
+#if ENABLE(3D_CANVAS)
+ virtual void setGraphicsContext3DNeedsDisplay();
+#endif
+
virtual void setContentsRect(const IntRect&);
virtual void suspendAnimations(double time);
@@ -98,6 +104,9 @@ public:
virtual void setContentsToImage(Image*);
virtual void setContentsToVideo(PlatformLayer*);
+#if ENABLE(3D_CANVAS)
+ virtual void setContentsToGraphicsContext3D(const GraphicsContext3D*);
+#endif
virtual PlatformLayer* platformLayer() const;
@@ -170,8 +179,12 @@ private:
void updateContentsImage();
void updateContentsVideo();
+#if ENABLE(3D_CANVAS)
+ void updateContentsGraphicsContext3D();
+#endif
void updateContentsRect();
void updateGeometryOrientation();
+ void updateMaskLayer();
void updateLayerAnimations();
@@ -199,8 +212,12 @@ private:
DirtyRectsChanged = 1 << 16,
ContentsImageChanged = 1 << 17,
ContentsVideoChanged = 1 << 18,
- ContentsRectChanged = 1 << 19,
- GeometryOrientationChanged = 1 << 20
+#if ENABLE(3D_CANVAS)
+ ContentsGraphicsContext3DChanged = 1 << 19,
+#endif
+ ContentsRectChanged = 1 << 20,
+ GeometryOrientationChanged = 1 << 21,
+ MaskLayerChanged = 1 << 22
};
typedef unsigned LayerChangeFlags;
void noteLayerPropertyChanged(LayerChangeFlags flags);
@@ -215,6 +232,9 @@ private:
NoContentsLayer = 0,
ContentsLayerForImage,
ContentsLayerForVideo
+#if ENABLE(3D_CANVAS)
+ ,ContentsLayerForGraphicsLayer3D
+#endif
};
ContentsLayerPurpose m_contentsLayerPurpose;
@@ -260,6 +280,11 @@ private:
Vector<FloatRect> m_dirtyRects;
LayerChangeFlags m_uncommittedChanges;
+
+#if ENABLE(3D_CANVAS)
+ PlatformGraphicsContext3D m_platformGraphicsContext3D;
+ Platform3DObject m_platformTexture;
+#endif
};
} // namespace WebCore
diff --git a/WebCore/platform/graphics/mac/GraphicsLayerCA.mm b/WebCore/platform/graphics/mac/GraphicsLayerCA.mm
index e5b9035..e9960f1 100644
--- a/WebCore/platform/graphics/mac/GraphicsLayerCA.mm
+++ b/WebCore/platform/graphics/mac/GraphicsLayerCA.mm
@@ -31,6 +31,9 @@
#import "Animation.h"
#import "BlockExceptions.h"
+#if ENABLE(3D_CANVAS)
+#import "Canvas3DLayer.h"
+#endif
#import "CString.h"
#import "FloatConversion.h"
#import "FloatRect.h"
@@ -145,11 +148,11 @@ static NSValue* getTransformFunctionValue(const TransformOperation* transformOp,
case TransformOperation::ROTATE_Y:
return [NSNumber numberWithDouble:transformOp ? deg2rad(static_cast<const RotateTransformOperation*>(transformOp)->angle()) : 0];
case TransformOperation::SCALE_X:
- return [NSNumber numberWithDouble:transformOp ? static_cast<const ScaleTransformOperation*>(transformOp)->x() : 0];
+ return [NSNumber numberWithDouble:transformOp ? static_cast<const ScaleTransformOperation*>(transformOp)->x() : 1];
case TransformOperation::SCALE_Y:
- return [NSNumber numberWithDouble:transformOp ? static_cast<const ScaleTransformOperation*>(transformOp)->y() : 0];
+ return [NSNumber numberWithDouble:transformOp ? static_cast<const ScaleTransformOperation*>(transformOp)->y() : 1];
case TransformOperation::SCALE_Z:
- return [NSNumber numberWithDouble:transformOp ? static_cast<const ScaleTransformOperation*>(transformOp)->z() : 0];
+ return [NSNumber numberWithDouble:transformOp ? static_cast<const ScaleTransformOperation*>(transformOp)->z() : 1];
case TransformOperation::TRANSLATE_X:
return [NSNumber numberWithDouble:transformOp ? static_cast<const TranslateTransformOperation*>(transformOp)->x(size) : 0];
case TransformOperation::TRANSLATE_Y:
@@ -157,13 +160,23 @@ static NSValue* getTransformFunctionValue(const TransformOperation* transformOp,
case TransformOperation::TRANSLATE_Z:
return [NSNumber numberWithDouble:transformOp ? static_cast<const TranslateTransformOperation*>(transformOp)->z(size) : 0];
case TransformOperation::SCALE:
+ case TransformOperation::SCALE_3D:
+ return [NSArray arrayWithObjects:
+ [NSNumber numberWithDouble:transformOp ? static_cast<const ScaleTransformOperation*>(transformOp)->x() : 1],
+ [NSNumber numberWithDouble:transformOp ? static_cast<const ScaleTransformOperation*>(transformOp)->y() : 1],
+ [NSNumber numberWithDouble:transformOp ? static_cast<const ScaleTransformOperation*>(transformOp)->z() : 1],
+ nil];
case TransformOperation::TRANSLATE:
+ case TransformOperation::TRANSLATE_3D:
+ return [NSArray arrayWithObjects:
+ [NSNumber numberWithDouble:transformOp ? static_cast<const TranslateTransformOperation*>(transformOp)->x(size) : 0],
+ [NSNumber numberWithDouble:transformOp ? static_cast<const TranslateTransformOperation*>(transformOp)->y(size) : 0],
+ [NSNumber numberWithDouble:transformOp ? static_cast<const TranslateTransformOperation*>(transformOp)->z(size) : 0],
+ nil];
case TransformOperation::SKEW_X:
case TransformOperation::SKEW_Y:
case TransformOperation::SKEW:
case TransformOperation::MATRIX:
- case TransformOperation::SCALE_3D:
- case TransformOperation::TRANSLATE_3D:
case TransformOperation::ROTATE_3D:
case TransformOperation::MATRIX_3D:
case TransformOperation::PERSPECTIVE:
@@ -204,6 +217,12 @@ static NSString* getValueFunctionNameForTransformOperation(TransformOperation::O
return @"translateY"; // kCAValueFunctionTranslateY;
case TransformOperation::TRANSLATE_Z:
return @"translateZ"; // kCAValueFunctionTranslateZ;
+ case TransformOperation::SCALE:
+ case TransformOperation::SCALE_3D:
+ return @"scale"; // kCAValueFunctionScale;
+ case TransformOperation::TRANSLATE:
+ case TransformOperation::TRANSLATE_3D:
+ return @"translate"; // kCAValueFunctionTranslate;
default:
return nil;
}
@@ -331,7 +350,7 @@ static NSDictionary* nullActionsDictionary()
return actions;
}
-GraphicsLayer* GraphicsLayer::createGraphicsLayer(GraphicsLayerClient* client)
+PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerClient* client)
{
return new GraphicsLayerCA(client);
}
@@ -341,6 +360,10 @@ GraphicsLayerCA::GraphicsLayerCA(GraphicsLayerClient* client)
, m_contentsLayerPurpose(NoContentsLayer)
, m_contentsLayerHasBackgroundColor(false)
, m_uncommittedChanges(NoChange)
+#if ENABLE(3D_CANVAS)
+, m_platformGraphicsContext3D(NullPlatformGraphicsContext3D)
+, m_platformTexture(NullPlatform3DObject)
+#endif
{
BEGIN_BLOCK_OBJC_EXCEPTIONS
m_layer.adoptNS([[WebLayer alloc] init]);
@@ -432,6 +455,15 @@ void GraphicsLayerCA::removeFromParent()
GraphicsLayer::removeFromParent();
}
+void GraphicsLayerCA::setMaskLayer(GraphicsLayer* layer)
+{
+ if (layer == m_maskLayer)
+ return;
+
+ GraphicsLayer::setMaskLayer(layer);
+ noteLayerPropertyChanged(MaskLayerChanged);
+}
+
void GraphicsLayerCA::setPosition(const FloatPoint& point)
{
if (point == m_position)
@@ -672,10 +704,10 @@ void GraphicsLayerCA::setContentsToImage(Image* image)
CGColorSpaceRef colorSpace = CGImageGetColorSpace(m_pendingContentsImage.get());
static CGColorSpaceRef deviceRGB = CGColorSpaceCreateDeviceRGB();
- if (CFEqual(colorSpace, deviceRGB)) {
- // CoreGraphics renders images tagged with DeviceRGB using GenericRGB. When we hand such
+ if (colorSpace && CFEqual(colorSpace, deviceRGB)) {
+ // CoreGraphics renders images tagged with DeviceRGB using the color space of the main display. When we hand such
// images to CA we need to tag them similarly so CA rendering matches CG rendering.
- static CGColorSpaceRef genericRGB = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
+ static CGColorSpaceRef genericRGB = CGDisplayCopyColorSpace(kCGDirectMainDisplay);
m_pendingContentsImage.adoptCF(CGImageCreateCopyWithColorSpace(m_pendingContentsImage.get(), genericRGB));
}
m_contentsLayerPurpose = ContentsLayerForImage;
@@ -733,6 +765,9 @@ void GraphicsLayerCA::recursiveCommitChanges()
{
commitLayerChanges();
+ if (m_maskLayer)
+ static_cast<GraphicsLayerCA*>(m_maskLayer)->commitLayerChanges();
+
const Vector<GraphicsLayer*>& childLayers = children();
size_t numChildren = childLayers.size();
for (size_t i = 0; i < numChildren; ++i) {
@@ -763,7 +798,12 @@ void GraphicsLayerCA::commitLayerChanges()
if (m_uncommittedChanges & ContentsVideoChanged) // Needs to happen before ChildrenChanged
updateContentsVideo();
-
+
+#if ENABLE(3D_CANVAS)
+ if (m_uncommittedChanges & ContentsGraphicsContext3DChanged) // Needs to happen before ChildrenChanged
+ updateContentsGraphicsContext3D();
+#endif
+
if (m_uncommittedChanges & BackgroundColorChanged) // Needs to happen before ChildrenChanged, and after updating image or video
updateLayerBackgroundColor();
@@ -812,6 +852,9 @@ void GraphicsLayerCA::commitLayerChanges()
if (m_uncommittedChanges & GeometryOrientationChanged)
updateGeometryOrientation();
+ if (m_uncommittedChanges & MaskLayerChanged)
+ updateMaskLayer();
+
m_uncommittedChanges = NoChange;
END_BLOCK_OBJC_EXCEPTIONS
}
@@ -821,10 +864,12 @@ void GraphicsLayerCA::updateSublayerList()
NSMutableArray* newSublayers = nil;
if (m_transformLayer) {
- // FIXME: add the primary layer in the correct order with negative z-order children.
+ // Add the primary layer first. Even if we have negative z-order children, the primary layer always comes behind.
newSublayers = [[NSMutableArray alloc] initWithObjects:m_layer.get(), nil];
} else if (m_contentsLayer) {
// FIXME: add the contents layer in the correct order with negative z-order children.
+ // This does not cause visible rendering issues because currently contents layers are only used
+ // for replaced elements that don't have children.
newSublayers = [[NSMutableArray alloc] initWithObjects:m_contentsLayer.get(), nil];
}
@@ -1061,6 +1106,18 @@ void GraphicsLayerCA::updateContentsVideo()
}
}
+#if ENABLE(3D_CANVAS)
+void GraphicsLayerCA::updateContentsGraphicsContext3D()
+{
+ // Canvas3D layer was set as m_contentsLayer, and will get parented in updateSublayerList().
+ if (m_contentsLayer) {
+ setupContentsLayer(m_contentsLayer.get());
+ [m_contentsLayer.get() setNeedsDisplay];
+ updateContentsRect();
+ }
+}
+#endif
+
void GraphicsLayerCA::updateContentsRect()
{
if (!m_contentsLayer)
@@ -1094,6 +1151,12 @@ void GraphicsLayerCA::updateGeometryOrientation()
#endif
}
+void GraphicsLayerCA::updateMaskLayer()
+{
+ CALayer* maskCALayer = m_maskLayer ? m_maskLayer->platformLayer() : 0;
+ [m_layer.get() setMask:maskCALayer];
+}
+
void GraphicsLayerCA::updateLayerAnimations()
{
if (m_transitionPropertiesToRemove.size()) {
@@ -1247,6 +1310,40 @@ void GraphicsLayerCA::pauseAnimationOnLayer(AnimatedPropertyID property, int ind
[layer addAnimation:pausedAnim forKey:animationName]; // This will replace the running animation.
}
+#if ENABLE(3D_CANVAS)
+void GraphicsLayerCA::setContentsToGraphicsContext3D(const GraphicsContext3D* graphicsContext3D)
+{
+ PlatformGraphicsContext3D context = graphicsContext3D->platformGraphicsContext3D();
+ Platform3DObject texture = graphicsContext3D->platformTexture();
+
+ if (context == m_platformGraphicsContext3D && texture == m_platformTexture)
+ return;
+
+ m_platformGraphicsContext3D = context;
+ m_platformTexture = texture;
+
+ noteLayerPropertyChanged(ChildrenChanged);
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+
+ if (m_platformGraphicsContext3D != NullPlatformGraphicsContext3D && m_platformTexture != NullPlatform3DObject) {
+ // create the inner 3d layer
+ m_contentsLayer.adoptNS([[Canvas3DLayer alloc] initWithContext:static_cast<CGLContextObj>(m_platformGraphicsContext3D) texture:static_cast<GLuint>(m_platformTexture)]);
+#ifndef NDEBUG
+ [m_contentsLayer.get() setName:@"3D Layer"];
+#endif
+ } else {
+ // remove the inner layer
+ m_contentsLayer = 0;
+ }
+
+ END_BLOCK_OBJC_EXCEPTIONS
+
+ noteLayerPropertyChanged(ContentsGraphicsContext3DChanged);
+ m_contentsLayerPurpose = m_contentsLayer ? ContentsLayerForGraphicsLayer3D : NoContentsLayer;
+}
+#endif
+
void GraphicsLayerCA::repaintLayerDirtyRects()
{
if (!m_dirtyRects.size())
@@ -1765,6 +1862,14 @@ void GraphicsLayerCA::noteLayerPropertyChanged(LayerChangeFlags flags)
m_uncommittedChanges |= flags;
}
+#if ENABLE(3D_CANVAS)
+void GraphicsLayerCA::setGraphicsContext3DNeedsDisplay()
+{
+ if (m_contentsLayerPurpose == ContentsLayerForGraphicsLayer3D)
+ [m_contentsLayer.get() setNeedsDisplay];
+}
+#endif
+
} // namespace WebCore
#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/mac/ImageMac.mm b/WebCore/platform/graphics/mac/ImageMac.mm
index a0d257b..672c3c8 100644
--- a/WebCore/platform/graphics/mac/ImageMac.mm
+++ b/WebCore/platform/graphics/mac/ImageMac.mm
@@ -94,16 +94,15 @@ CFDataRef BitmapImage::getTIFFRepresentation()
RetainPtr<CFMutableDataRef> data(AdoptCF, CFDataCreateMutable(0, 0));
// FIXME: Use type kCGImageTypeIdentifierTIFF constant once is becomes available in the API
- CGImageDestinationRef destination = CGImageDestinationCreateWithData(data.get(), CFSTR("public.tiff"), numValidFrames, 0);
-
+ RetainPtr<CGImageDestinationRef> destination(AdoptCF, CGImageDestinationCreateWithData(data.get(), CFSTR("public.tiff"), numValidFrames, 0));
+
if (!destination)
return 0;
for (unsigned i = 0; i < numValidFrames; ++i)
- CGImageDestinationAddImage(destination, images[i], 0);
+ CGImageDestinationAddImage(destination.get(), images[i], 0);
- CGImageDestinationFinalize(destination);
- CFRelease(destination);
+ CGImageDestinationFinalize(destination.get());
m_tiffRep = data;
return m_tiffRep.get();
diff --git a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h
index 54eea00..0a63626 100644
--- a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h
+++ b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h
@@ -77,8 +77,12 @@ private:
static MediaPlayer::SupportsType supportsType(const String& type, const String& codecs);
static bool isAvailable();
+ PlatformMedia platformMedia() const;
+
IntSize naturalSize() const;
bool hasVideo() const;
+ bool hasAudio() const;
+ bool supportsFullscreen() const;
void load(const String& url);
void cancelLoad();
@@ -104,7 +108,7 @@ private:
MediaPlayer::NetworkState networkState() const { return m_networkState; }
MediaPlayer::ReadyState readyState() const { return m_readyState; }
- float maxTimeBuffered() const;
+ PassRefPtr<TimeRanges> buffered() const;
float maxTimeSeekable() const;
unsigned bytesLoaded() const;
bool totalBytesKnown() const;
diff --git a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
index c1d7fcb..30d0c82 100644
--- a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
+++ b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
@@ -39,6 +39,7 @@
#import "KURL.h"
#import "MIMETypeRegistry.h"
#import "SoftLinking.h"
+#import "TimeRanges.h"
#import "WebCoreSystemInterface.h"
#import <QTKit/QTKit.h>
#import <objc/objc-runtime.h>
@@ -84,6 +85,7 @@ SOFT_LINK_POINTER(QTKit, QTMovieAskUnresolvedDataRefsAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieDataSizeAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieDidEndNotification, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieHasVideoAttribute, NSString *)
+SOFT_LINK_POINTER(QTKit, QTMovieHasAudioAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieIsActiveAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieLoadStateAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieLoadStateDidChangeNotification, NSString *)
@@ -119,6 +121,7 @@ SOFT_LINK_POINTER(QTKit, QTMovieApertureModeAttribute, NSString *)
#define QTMovieDataSizeAttribute getQTMovieDataSizeAttribute()
#define QTMovieDidEndNotification getQTMovieDidEndNotification()
#define QTMovieHasVideoAttribute getQTMovieHasVideoAttribute()
+#define QTMovieHasAudioAttribute getQTMovieHasAudioAttribute()
#define QTMovieIsActiveAttribute getQTMovieIsActiveAttribute()
#define QTMovieLoadStateAttribute getQTMovieLoadStateAttribute()
#define QTMovieLoadStateDidChangeNotification getQTMovieLoadStateDidChangeNotification()
@@ -230,7 +233,7 @@ MediaPlayerPrivate::~MediaPlayerPrivate()
void MediaPlayerPrivate::createQTMovie(const String& url)
{
- NSURL *cocoaURL = KURL(url);
+ NSURL *cocoaURL = KURL(ParsedURLString, url);
NSDictionary *movieAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
cocoaURL, QTMovieURLAttribute,
[NSNumber numberWithBool:m_player->preservesPitch()], QTMovieRateChangesPreservePitchAttribute,
@@ -562,6 +565,12 @@ void MediaPlayerPrivate::load(const String& url)
[m_objcObserver.get() setDelayCallbacks:NO];
}
+PlatformMedia MediaPlayerPrivate::platformMedia() const
+{
+ PlatformMedia plaftformMedia = { m_qtMovie.get() };
+ return plaftformMedia;
+}
+
void MediaPlayerPrivate::play()
{
if (!metaDataAvailable())
@@ -719,18 +728,28 @@ bool MediaPlayerPrivate::hasVideo() const
return [[m_qtMovie.get() attributeForKey:QTMovieHasVideoAttribute] boolValue];
}
+bool MediaPlayerPrivate::hasAudio() const
+{
+ if (!m_qtMovie)
+ return false;
+ return [[m_qtMovie.get() attributeForKey:QTMovieHasAudioAttribute] boolValue];
+}
+
+bool MediaPlayerPrivate::supportsFullscreen() const
+{
+ return true;
+}
+
void MediaPlayerPrivate::setVolume(float volume)
{
- if (!metaDataAvailable())
- return;
- [m_qtMovie.get() setVolume:volume];
+ if (m_qtMovie)
+ [m_qtMovie.get() setVolume:volume];
}
void MediaPlayerPrivate::setRate(float rate)
{
- if (!metaDataAvailable())
- return;
- [m_qtMovie.get() setRate:rate];
+ if (m_qtMovie)
+ [m_qtMovie.get() setRate:rate];
}
void MediaPlayerPrivate::setPreservesPitch(bool preservesPitch)
@@ -758,10 +777,13 @@ int MediaPlayerPrivate::dataRate() const
return wkQTMovieDataRate(m_qtMovie.get());
}
-
-float MediaPlayerPrivate::maxTimeBuffered() const
+PassRefPtr<TimeRanges> MediaPlayerPrivate::buffered() const
{
- return maxTimeLoaded();
+ RefPtr<TimeRanges> timeRanges = TimeRanges::create();
+ float loaded = maxTimeLoaded();
+ if (loaded > 0)
+ timeRanges->add(0, loaded);
+ return timeRanges.release();
}
float MediaPlayerPrivate::maxTimeSeekable() const
diff --git a/WebCore/platform/graphics/mac/SimpleFontDataMac.mm b/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
index cdde7cf..97a7251 100644
--- a/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
+++ b/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
@@ -50,6 +50,8 @@
- (BOOL)_isFakeFixedPitch;
@end
+using namespace std;
+
namespace WebCore {
const float smallCapsFontSizeMultiplier = 0.7f;
@@ -269,7 +271,7 @@ void SimpleFontData::platformInit()
// and web pages that foolishly use this metric for width will be laid out
// poorly if we return an accurate height. Classic case is Times 13 point,
// which has an "x" that is 7x6 pixels.
- m_xHeight = MAX(NSMaxX(xBox), NSMaxY(xBox));
+ m_xHeight = max(NSMaxX(xBox), NSMaxY(xBox));
} else
m_xHeight = [m_platformData.font() xHeight];
}
@@ -443,13 +445,13 @@ CTFontRef SimpleFontData::getCTFont() const
return m_CTFont.get();
}
-CFDictionaryRef SimpleFontData::getCFStringAttributes() const
+CFDictionaryRef SimpleFontData::getCFStringAttributes(TextRenderingMode textMode) const
{
if (m_CFStringAttributes)
return m_CFStringAttributes.get();
- static const float kerningAdjustmentValue = 0;
- static CFNumberRef kerningAdjustment = CFNumberCreate(kCFAllocatorDefault, kCFNumberFloatType, &kerningAdjustmentValue);
+ bool allowKerning = textMode == OptimizeLegibility || textMode == GeometricPrecision;
+ bool allowLigatures = platformData().allowsLigatures() || allowKerning;
static const int ligaturesNotAllowedValue = 0;
static CFNumberRef ligaturesNotAllowed = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &ligaturesNotAllowedValue);
@@ -457,10 +459,23 @@ CFDictionaryRef SimpleFontData::getCFStringAttributes() const
static const int ligaturesAllowedValue = 1;
static CFNumberRef ligaturesAllowed = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &ligaturesAllowedValue);
- static const void* attributeKeys[] = { kCTFontAttributeName, kCTKernAttributeName, kCTLigatureAttributeName };
- const void* attributeValues[] = { getCTFont(), kerningAdjustment, platformData().allowsLigatures() ? ligaturesAllowed : ligaturesNotAllowed };
-
- m_CFStringAttributes.adoptCF(CFDictionaryCreate(NULL, attributeKeys, attributeValues, sizeof(attributeKeys) / sizeof(*attributeKeys), &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+ if (!allowKerning) {
+ static const float kerningAdjustmentValue = 0;
+ static CFNumberRef kerningAdjustment = CFNumberCreate(kCFAllocatorDefault, kCFNumberFloatType, &kerningAdjustmentValue);
+ static const void* keysWithKerningDisabled[] = { kCTFontAttributeName, kCTKernAttributeName, kCTLigatureAttributeName };
+ const void* valuesWithKerningDisabled[] = { getCTFont(), kerningAdjustment, allowLigatures
+ ? ligaturesAllowed : ligaturesNotAllowed };
+ m_CFStringAttributes.adoptCF(CFDictionaryCreate(NULL, keysWithKerningDisabled, valuesWithKerningDisabled,
+ sizeof(keysWithKerningDisabled) / sizeof(*keysWithKerningDisabled),
+ &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+ } else {
+ // By omitting the kCTKernAttributeName attribute, we get Core Text's standard kerning.
+ static const void* keysWithKerningEnabled[] = { kCTFontAttributeName, kCTLigatureAttributeName };
+ const void* valuesWithKerningEnabled[] = { getCTFont(), allowLigatures ? ligaturesAllowed : ligaturesNotAllowed };
+ m_CFStringAttributes.adoptCF(CFDictionaryCreate(NULL, keysWithKerningEnabled, valuesWithKerningEnabled,
+ sizeof(keysWithKerningEnabled) / sizeof(*keysWithKerningEnabled),
+ &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+ }
return m_CFStringAttributes.get();
}
diff --git a/WebCore/platform/graphics/opentype/OpenTypeUtilities.cpp b/WebCore/platform/graphics/opentype/OpenTypeUtilities.cpp
index 895887f..b2e3d92 100644
--- a/WebCore/platform/graphics/opentype/OpenTypeUtilities.cpp
+++ b/WebCore/platform/graphics/opentype/OpenTypeUtilities.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Torch Mobile, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -339,7 +340,10 @@ bool getEOTHeader(SharedBuffer* fontData, EOTHeader& eotHeader, size_t& overlayD
return true;
}
-HANDLE renameAndActivateFont(SharedBuffer* fontData, const String& fontName)
+// code shared by renameFont and renameAndActivateFont
+// adds fontName to the font table in fontData, and writes the new font table to rewrittenFontTable
+// returns the size of the name table (which is used by renameAndActivateFont), or 0 on early abort
+static size_t renameFontInternal(SharedBuffer* fontData, const String& fontName, Vector<char> &rewrittenFontData)
{
size_t originalDataSize = fontData->size();
const sfntHeader* sfnt = reinterpret_cast<const sfntHeader*>(fontData->data());
@@ -357,7 +361,7 @@ HANDLE renameAndActivateFont(SharedBuffer* fontData, const String& fontName)
// Rounded up to a multiple of 4 to simplify the checksum calculation.
size_t nameTableSize = ((offsetof(nameTable, nameRecords) + nameRecordCount * sizeof(nameRecord) + fontName.length() * sizeof(UChar)) & ~3) + 4;
- Vector<char> rewrittenFontData(fontData->size() + nameTableSize);
+ rewrittenFontData.resize(fontData->size() + nameTableSize);
char* data = rewrittenFontData.data();
memcpy(data, fontData->data(), originalDataSize);
@@ -394,8 +398,42 @@ HANDLE renameAndActivateFont(SharedBuffer* fontData, const String& fontName)
for (unsigned i = 0; i * sizeof(BigEndianULong) < nameTableSize; ++i)
rewrittenSfnt->tables[t].checkSum = rewrittenSfnt->tables[t].checkSum + reinterpret_cast<BigEndianULong*>(name)[i];
+ return nameTableSize;
+}
+
+#if PLATFORM(WINCE)
+// AddFontMemResourceEx does not exist on WinCE, so we must handle the font data manually
+// This function just renames the font and overwrites the old font data with the new
+bool renameFont(SharedBuffer* fontData, const String& fontName)
+{
+ // abort if the data is too small to be a font header with a "tables" entry
+ if (fontData->size() < offsetof(sfntHeader, tables))
+ return false;
+
+ // abort if the data is too small to hold all the tables specified in the header
+ const sfntHeader* header = reinterpret_cast<const sfntHeader*>(fontData->data());
+ if (fontData->size() < offsetof(sfntHeader, tables) + header->numTables * sizeof(TableDirectoryEntry))
+ return false;
+
+ Vector<char> rewrittenFontData;
+ if (!renameFontInternal(fontData, fontName, rewrittenFontData))
+ return false;
+
+ fontData->clear();
+ fontData->append(rewrittenFontData.data(), rewrittenFontData.size());
+ return true;
+}
+#else
+// Rename the font and install the new font data into the system
+HANDLE renameAndActivateFont(SharedBuffer* fontData, const String& fontName)
+{
+ Vector<char> rewrittenFontData;
+ size_t nameTableSize = renameFontInternal(fontData, fontName, rewrittenFontData);
+ if (!nameTableSize)
+ return 0;
+
DWORD numFonts = 0;
- HANDLE fontHandle = AddFontMemResourceEx(data, originalDataSize + nameTableSize, 0, &numFonts);
+ HANDLE fontHandle = AddFontMemResourceEx(rewrittenFontData.data(), fontData->size() + nameTableSize, 0, &numFonts);
if (fontHandle && numFonts != 1) {
RemoveFontMemResourceEx(fontHandle);
@@ -404,5 +442,6 @@ HANDLE renameAndActivateFont(SharedBuffer* fontData, const String& fontName)
return fontHandle;
}
+#endif
}
diff --git a/WebCore/platform/graphics/opentype/OpenTypeUtilities.h b/WebCore/platform/graphics/opentype/OpenTypeUtilities.h
index 13dad6f..4c75314 100644
--- a/WebCore/platform/graphics/opentype/OpenTypeUtilities.h
+++ b/WebCore/platform/graphics/opentype/OpenTypeUtilities.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Torch Mobile, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -35,6 +36,10 @@ struct BigEndianUShort;
struct EOTPrefix;
class SharedBuffer;
+#if PLATFORM(WINCE)
+typedef unsigned __int8 UInt8;
+#endif
+
struct EOTHeader {
EOTHeader();
diff --git a/WebCore/platform/graphics/qt/ColorQt.cpp b/WebCore/platform/graphics/qt/ColorQt.cpp
index 5d16740..151766a 100644
--- a/WebCore/platform/graphics/qt/ColorQt.cpp
+++ b/WebCore/platform/graphics/qt/ColorQt.cpp
@@ -40,7 +40,10 @@ Color::Color(const QColor& c)
Color::operator QColor() const
{
- return QColor(red(), green(), blue(), alpha());
+ if (m_valid)
+ return QColor(red(), green(), blue(), alpha());
+ else
+ return QColor();
}
}
diff --git a/WebCore/platform/graphics/qt/FontCacheQt.cpp b/WebCore/platform/graphics/qt/FontCacheQt.cpp
index 5d29389..1113eae 100644
--- a/WebCore/platform/graphics/qt/FontCacheQt.cpp
+++ b/WebCore/platform/graphics/qt/FontCacheQt.cpp
@@ -48,7 +48,7 @@ FontCache::FontCache()
{
}
-void FontCache::getTraitsInFamily(const AtomicString& familyName, Vector<unsigned>& traitsMasks)
+void FontCache::getTraitsInFamily(const AtomicString&, Vector<unsigned>&)
{
}
@@ -58,8 +58,8 @@ class FontPlatformDataCacheKey {
public:
FontPlatformDataCacheKey(const FontDescription& description)
: m_familyName()
- , m_bold(false)
, m_size(description.computedPixelSize())
+ , m_bold(false)
, m_italic(description.italic())
, m_smallCaps(description.smallCaps())
, m_hash(0)
@@ -177,7 +177,7 @@ typedef HashMap<FontPlatformDataCacheKey, FontPlatformData*, FontPlatformDataCac
// using Q_GLOBAL_STATIC leads to crash. TODO investigate the way to fix this.
static FontPlatformDataCache* gFontPlatformDataCache = 0;
-FontPlatformData* FontCache::getCachedFontPlatformData(const FontDescription& description, const AtomicString& family, bool checkingAlternateName)
+FontPlatformData* FontCache::getCachedFontPlatformData(const FontDescription& description, const AtomicString&, bool)
{
if (!gFontPlatformDataCache)
gFontPlatformDataCache = new FontPlatformDataCache;
diff --git a/WebCore/platform/graphics/qt/FontFallbackListQt.cpp b/WebCore/platform/graphics/qt/FontFallbackListQt.cpp
index c29fd56..8e1e4f6 100644
--- a/WebCore/platform/graphics/qt/FontFallbackListQt.cpp
+++ b/WebCore/platform/graphics/qt/FontFallbackListQt.cpp
@@ -130,7 +130,7 @@ const FontData* FontFallbackList::fontDataForCharacters(const WebCore::Font* fon
return primaryFontData(font);
}
-void FontFallbackList::setPlatformFont(const WebCore::FontPlatformData& platformData)
+void FontFallbackList::setPlatformFont(const WebCore::FontPlatformData&)
{
m_familyIndex = cAllFamiliesScanned;
}
diff --git a/WebCore/platform/graphics/qt/FontQt.cpp b/WebCore/platform/graphics/qt/FontQt.cpp
index e8eb923..c5960ac 100644
--- a/WebCore/platform/graphics/qt/FontQt.cpp
+++ b/WebCore/platform/graphics/qt/FontQt.cpp
@@ -197,7 +197,7 @@ float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFon
return w + run.padding();
}
-int Font::offsetForPositionForComplexText(const TextRun& run, int position, bool includePartialGlyphs) const
+int Font::offsetForPositionForComplexText(const TextRun& run, int position, bool) const
{
const QString string = fixSpacing(qstring(run));
QTextLayout layout(string, font());
diff --git a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
index e259a4e..fa7b070 100644
--- a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
+++ b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
@@ -34,29 +34,29 @@
*/
#include "config.h"
+#include "GraphicsContext.h"
#ifdef Q_WS_WIN
#include <windows.h>
#endif
-#include "TransformationMatrix.h"
#include "Color.h"
#include "FloatConversion.h"
#include "Font.h"
-#include "GraphicsContext.h"
#include "GraphicsContextPrivate.h"
#include "ImageBuffer.h"
+#include "NotImplemented.h"
#include "Path.h"
#include "Pattern.h"
#include "Pen.h"
-#include "NotImplemented.h"
+#include "TransformationMatrix.h"
#include <QBrush>
#include <QDebug>
#include <QGradient>
-#include <QPainter>
#include <QPaintDevice>
#include <QPaintEngine>
+#include <QPainter>
#include <QPainterPath>
#include <QPixmap>
#include <QPolygonF>
@@ -72,35 +72,35 @@ namespace WebCore {
static inline QPainter::CompositionMode toQtCompositionMode(CompositeOperator op)
{
switch (op) {
- case CompositeClear:
- return QPainter::CompositionMode_Clear;
- case CompositeCopy:
- return QPainter::CompositionMode_Source;
- case CompositeSourceOver:
- return QPainter::CompositionMode_SourceOver;
- case CompositeSourceIn:
- return QPainter::CompositionMode_SourceIn;
- case CompositeSourceOut:
- return QPainter::CompositionMode_SourceOut;
- case CompositeSourceAtop:
- return QPainter::CompositionMode_SourceAtop;
- case CompositeDestinationOver:
- return QPainter::CompositionMode_DestinationOver;
- case CompositeDestinationIn:
- return QPainter::CompositionMode_DestinationIn;
- case CompositeDestinationOut:
- return QPainter::CompositionMode_DestinationOut;
- case CompositeDestinationAtop:
- return QPainter::CompositionMode_DestinationAtop;
- case CompositeXOR:
- return QPainter::CompositionMode_Xor;
- case CompositePlusDarker:
- // there is no exact match, but this is the closest
- return QPainter::CompositionMode_Darken;
- case CompositeHighlight:
- return QPainter::CompositionMode_SourceOver;
- case CompositePlusLighter:
- return QPainter::CompositionMode_Plus;
+ case CompositeClear:
+ return QPainter::CompositionMode_Clear;
+ case CompositeCopy:
+ return QPainter::CompositionMode_Source;
+ case CompositeSourceOver:
+ return QPainter::CompositionMode_SourceOver;
+ case CompositeSourceIn:
+ return QPainter::CompositionMode_SourceIn;
+ case CompositeSourceOut:
+ return QPainter::CompositionMode_SourceOut;
+ case CompositeSourceAtop:
+ return QPainter::CompositionMode_SourceAtop;
+ case CompositeDestinationOver:
+ return QPainter::CompositionMode_DestinationOver;
+ case CompositeDestinationIn:
+ return QPainter::CompositionMode_DestinationIn;
+ case CompositeDestinationOut:
+ return QPainter::CompositionMode_DestinationOut;
+ case CompositeDestinationAtop:
+ return QPainter::CompositionMode_DestinationAtop;
+ case CompositeXOR:
+ return QPainter::CompositionMode_Xor;
+ case CompositePlusDarker:
+ // there is no exact match, but this is the closest
+ return QPainter::CompositionMode_Darken;
+ case CompositeHighlight:
+ return QPainter::CompositionMode_SourceOver;
+ case CompositePlusLighter:
+ return QPainter::CompositionMode_Plus;
}
return QPainter::CompositionMode_SourceOver;
@@ -109,12 +109,12 @@ static inline QPainter::CompositionMode toQtCompositionMode(CompositeOperator op
static inline Qt::PenCapStyle toQtLineCap(LineCap lc)
{
switch (lc) {
- case ButtCap:
- return Qt::FlatCap;
- case RoundCap:
- return Qt::RoundCap;
- case SquareCap:
- return Qt::SquareCap;
+ case ButtCap:
+ return Qt::FlatCap;
+ case RoundCap:
+ return Qt::RoundCap;
+ case SquareCap:
+ return Qt::SquareCap;
}
return Qt::FlatCap;
@@ -123,12 +123,12 @@ static inline Qt::PenCapStyle toQtLineCap(LineCap lc)
static inline Qt::PenJoinStyle toQtLineJoin(LineJoin lj)
{
switch (lj) {
- case MiterJoin:
- return Qt::SvgMiterJoin;
- case RoundJoin:
- return Qt::RoundJoin;
- case BevelJoin:
- return Qt::BevelJoin;
+ case MiterJoin:
+ return Qt::SvgMiterJoin;
+ case RoundJoin:
+ return Qt::RoundJoin;
+ case BevelJoin:
+ return Qt::BevelJoin;
}
return Qt::MiterJoin;
@@ -210,8 +210,8 @@ public:
return redirect;
return painter;
- } else
- return &layers.top()->painter;
+ }
+ return &layers.top()->painter;
}
bool antiAliasingForRectsAndLines;
@@ -411,46 +411,25 @@ void GraphicsContext::drawRect(const IntRect& rect)
if (paintingDisabled())
return;
- QPainter *p = m_data->p();
+ QPainter* p = m_data->p();
const bool antiAlias = p->testRenderHint(QPainter::Antialiasing);
p->setRenderHint(QPainter::Antialiasing, m_data->antiAliasingForRectsAndLines);
+ IntSize shadowSize;
+ int shadowBlur;
+ Color shadowColor;
+ if (getShadow(shadowSize, shadowBlur, shadowColor)) {
+ IntRect shadowRect = rect;
+ shadowRect.move(shadowSize.width(), shadowSize.height());
+ shadowRect.inflate(static_cast<int>(p->pen().widthF()));
+ p->fillRect(shadowRect, QColor(shadowColor));
+ }
+
p->drawRect(rect);
p->setRenderHint(QPainter::Antialiasing, antiAlias);
}
-// FIXME: Now that this is refactored, it should be shared by all contexts.
-static void adjustLineToPixelBoundaries(FloatPoint& p1, FloatPoint& p2, float strokeWidth,
- const StrokeStyle& penStyle)
-{
- // For odd widths, we add in 0.5 to the appropriate x/y so that the float arithmetic
- // works out. For example, with a border width of 3, KHTML will pass us (y1+y2)/2, e.g.,
- // (50+53)/2 = 103/2 = 51 when we want 51.5. It is always true that an even width gave
- // us a perfect position, but an odd width gave us a position that is off by exactly 0.5.
- if (penStyle == DottedStroke || penStyle == DashedStroke) {
- if (p1.x() == p2.x()) {
- p1.setY(p1.y() + strokeWidth);
- p2.setY(p2.y() - strokeWidth);
- } else {
- p1.setX(p1.x() + strokeWidth);
- p2.setX(p2.x() - strokeWidth);
- }
- }
-
- if (((int) strokeWidth) % 2) {
- if (p1.x() == p2.x()) {
- // We're a vertical line. Adjust our x.
- p1.setX(p1.x() + 0.5);
- p2.setX(p2.x() + 0.5);
- } else {
- // We're a horizontal line. Adjust our y.
- p1.setY(p1.y() + 0.5);
- p2.setY(p2.y() + 0.5);
- }
- }
-}
-
// This is only used to draw borders.
void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
{
@@ -468,7 +447,7 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
FloatPoint p2 = point2;
bool isVerticalLine = (p1.x() == p2.x());
- QPainter *p = m_data->p();
+ QPainter* p = m_data->p();
const bool antiAlias = p->testRenderHint(QPainter::Antialiasing);
p->setRenderHint(QPainter::Antialiasing, m_data->antiAliasingForRectsAndLines);
adjustLineToPixelBoundaries(p1, p2, width, style);
@@ -479,22 +458,22 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
if (textDrawingMode() == cTextFill && getShadow(shadowSize, shadowBlur, shadowColor)) {
p->save();
p->translate(shadowSize.width(), shadowSize.height());
- p->setPen(QColor(shadowColor));
+ p->setPen(shadowColor);
p->drawLine(p1, p2);
p->restore();
}
int patWidth = 0;
switch (style) {
- case NoStroke:
- case SolidStroke:
- break;
- case DottedStroke:
- patWidth = (int)width;
- break;
- case DashedStroke:
- patWidth = 3 * (int)width;
- break;
+ case NoStroke:
+ case SolidStroke:
+ break;
+ case DottedStroke:
+ patWidth = static_cast<int>(width);
+ break;
+ case DashedStroke:
+ patWidth = 3 * static_cast<int>(width);
+ break;
}
if (patWidth) {
@@ -523,7 +502,7 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
if (patWidth == 1)
patternOffset = 1.0f;
else {
- bool evenNumberOfSegments = numSegments % 2 == 0;
+ bool evenNumberOfSegments = !(numSegments % 2);
if (remainder)
evenNumberOfSegments = !evenNumberOfSegments;
if (evenNumberOfSegments) {
@@ -571,11 +550,25 @@ void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSp
if (paintingDisabled() || strokeStyle() == NoStroke || strokeThickness() <= 0.0f || !strokeColor().alpha())
return;
- QPainter *p = m_data->p();
+ QPainter* p = m_data->p();
const bool antiAlias = p->testRenderHint(QPainter::Antialiasing);
p->setRenderHint(QPainter::Antialiasing, true);
- p->drawArc(rect, startAngle * 16, angleSpan * 16);
+ IntSize shadowSize;
+ int shadowBlur;
+ Color shadowColor;
+ startAngle *= 16;
+ angleSpan *= 16;
+ if (getShadow(shadowSize, shadowBlur, shadowColor)) {
+ p->save();
+ p->translate(shadowSize.width(), shadowSize.height());
+ QPen pen(p->pen());
+ pen.setColor(shadowColor);
+ p->setPen(pen);
+ p->drawArc(rect, startAngle, angleSpan);
+ p->restore();
+ }
+ p->drawArc(rect, startAngle, angleSpan);
p->setRenderHint(QPainter::Antialiasing, antiAlias);
}
@@ -593,9 +586,25 @@ void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points
for (size_t i = 0; i < npoints; i++)
polygon[i] = points[i];
- QPainter *p = m_data->p();
+ QPainter* p = m_data->p();
p->save();
p->setRenderHint(QPainter::Antialiasing, shouldAntialias);
+ IntSize shadowSize;
+ int shadowBlur;
+ Color shadowColor;
+ if (getShadow(shadowSize, shadowBlur, shadowColor)) {
+ p->save();
+ p->translate(shadowSize.width(), shadowSize.height());
+ if (p->brush().style() != Qt::NoBrush)
+ p->setBrush(QBrush(shadowColor));
+ QPen pen(p->pen());
+ if (pen.style() != Qt::NoPen) {
+ pen.setColor(shadowColor);
+ p->setPen(pen);
+ }
+ p->drawConvexPolygon(polygon);
+ p->restore();
+ }
p->drawConvexPolygon(polygon);
p->restore();
}
@@ -605,34 +614,50 @@ QPen GraphicsContext::pen()
if (paintingDisabled())
return QPen();
- QPainter *p = m_data->p();
+ QPainter* p = m_data->p();
return p->pen();
}
+static void inline drawFilledShadowPath(GraphicsContext* context, QPainter* p, const QPainterPath *path)
+{
+ IntSize shadowSize;
+ int shadowBlur;
+ Color shadowColor;
+ if (context->getShadow(shadowSize, shadowBlur, shadowColor)) {
+ p->translate(shadowSize.width(), shadowSize.height());
+ p->fillPath(*path, QBrush(shadowColor));
+ p->translate(-shadowSize.width(), -shadowSize.height());
+ }
+}
+
void GraphicsContext::fillPath()
{
if (paintingDisabled())
return;
- QPainter *p = m_data->p();
+ QPainter* p = m_data->p();
QPainterPath path = m_data->currentPath;
path.setFillRule(toQtFillRule(fillRule()));
- switch (m_common->state.fillColorSpace) {
- case SolidColorSpace:
- if (fillColor().alpha())
- p->fillPath(path, p->brush());
- break;
- case PatternColorSpace: {
- TransformationMatrix affine;
- p->fillPath(path, QBrush(m_common->state.fillPattern->createPlatformPattern(affine)));
- break;
- }
- case GradientColorSpace:
- QBrush brush(*m_common->state.fillGradient->platformGradient());
- brush.setTransform(m_common->state.fillGradient->gradientSpaceTransform());
- p->fillPath(path, brush);
- break;
+ if ((m_common->state.fillColorSpace != SolidColorSpace)
+ || (fillColor().alpha())) {
+ drawFilledShadowPath(this, p, &path);
+ switch (m_common->state.fillColorSpace) {
+ case SolidColorSpace:
+ if (fillColor().alpha())
+ p->fillPath(path, p->brush());
+ break;
+ case PatternColorSpace: {
+ TransformationMatrix affine;
+ p->fillPath(path, QBrush(m_common->state.fillPattern->createPlatformPattern(affine)));
+ break;
+ }
+ case GradientColorSpace:
+ QBrush brush(*m_common->state.fillGradient->platformGradient());
+ brush.setTransform(m_common->state.fillGradient->gradientSpaceTransform());
+ p->fillPath(path, brush);
+ break;
+ }
}
m_data->currentPath = QPainterPath();
}
@@ -642,59 +667,88 @@ void GraphicsContext::strokePath()
if (paintingDisabled())
return;
- QPainter *p = m_data->p();
- QPen pen = p->pen();
+ QPainter* p = m_data->p();
+ QPen pen(p->pen());
QPainterPath path = m_data->currentPath;
path.setFillRule(toQtFillRule(fillRule()));
- switch (m_common->state.strokeColorSpace) {
- case SolidColorSpace:
- if (strokeColor().alpha())
+ if ((m_common->state.strokeColorSpace != SolidColorSpace)
+ || (strokeColor().alpha())) {
+ IntSize shadowSize;
+ int shadowBlur;
+ Color shadowColor;
+ if (getShadow(shadowSize, shadowBlur, shadowColor)) {
+ QTransform t(p->worldTransform());
+ p->translate(shadowSize.width(), shadowSize.height());
+ QPen shadowPen(pen);
+ shadowPen.setColor(shadowColor);
+ p->strokePath(path, shadowPen);
+ p->setWorldTransform(t);
+ }
+ switch (m_common->state.strokeColorSpace) {
+ case SolidColorSpace:
+ if (strokeColor().alpha())
+ p->strokePath(path, pen);
+ break;
+ case PatternColorSpace: {
+ TransformationMatrix affine;
+ pen.setBrush(QBrush(m_common->state.strokePattern->createPlatformPattern(affine)));
+ p->setPen(pen);
p->strokePath(path, pen);
- break;
- case PatternColorSpace: {
- TransformationMatrix affine;
- pen.setBrush(QBrush(m_common->state.strokePattern->createPlatformPattern(affine)));
- p->setPen(pen);
- p->strokePath(path, pen);
- break;
- }
- case GradientColorSpace: {
- QBrush brush(*m_common->state.strokeGradient->platformGradient());
- brush.setTransform(m_common->state.strokeGradient->gradientSpaceTransform());
- pen.setBrush(brush);
- p->setPen(pen);
- p->strokePath(path, pen);
- break;
- }
+ break;
+ }
+ case GradientColorSpace: {
+ QBrush brush(*m_common->state.strokeGradient->platformGradient());
+ brush.setTransform(m_common->state.strokeGradient->gradientSpaceTransform());
+ pen.setBrush(brush);
+ p->setPen(pen);
+ p->strokePath(path, pen);
+ break;
+ }
+ }
}
m_data->currentPath = QPainterPath();
}
+static inline void drawBorderlessRectShadow(GraphicsContext* context, QPainter* p, const FloatRect& rect)
+{
+ IntSize shadowSize;
+ int shadowBlur;
+ Color shadowColor;
+ if (context->getShadow(shadowSize, shadowBlur, shadowColor)) {
+ FloatRect shadowRect(rect);
+ shadowRect.move(shadowSize.width(), shadowSize.height());
+ p->fillRect(shadowRect, QColor(shadowColor));
+ }
+}
+
void GraphicsContext::fillRect(const FloatRect& rect)
{
if (paintingDisabled())
return;
- QPainter *p = m_data->p();
+ QPainter* p = m_data->p();
- switch (m_common->state.fillColorSpace) {
- case SolidColorSpace:
- if (fillColor().alpha())
- p->fillRect(rect, p->brush());
- break;
- case PatternColorSpace: {
- TransformationMatrix affine;
- p->fillRect(rect, QBrush(m_common->state.fillPattern->createPlatformPattern(affine)));
- break;
- }
- case GradientColorSpace:
- QBrush brush(*m_common->state.fillGradient->platformGradient());
- brush.setTransform(m_common->state.fillGradient->gradientSpaceTransform());
- p->fillRect(rect, brush);
- break;
+ if ((m_common->state.fillColorSpace != SolidColorSpace)
+ || (fillColor().alpha())) {
+ drawBorderlessRectShadow(this, p, rect);
+ switch (m_common->state.fillColorSpace) {
+ case SolidColorSpace:
+ if (fillColor().alpha())
+ p->fillRect(rect, p->brush());
+ break;
+ case PatternColorSpace: {
+ TransformationMatrix affine;
+ p->fillRect(rect, QBrush(m_common->state.fillPattern->createPlatformPattern(affine)));
+ break;
+ }
+ case GradientColorSpace:
+ QBrush brush(*m_common->state.fillGradient->platformGradient());
+ brush.setTransform(m_common->state.fillGradient->gradientSpaceTransform());
+ p->fillRect(rect, brush);
+ break;
+ }
}
- m_data->currentPath = QPainterPath();
}
void GraphicsContext::fillRect(const FloatRect& rect, const Color& c)
@@ -702,8 +756,10 @@ void GraphicsContext::fillRect(const FloatRect& rect, const Color& c)
if (paintingDisabled())
return;
- m_data->solidColor.setColor(QColor(c));
- m_data->p()->fillRect(rect, m_data->solidColor);
+ m_data->solidColor.setColor(c);
+ QPainter* p = m_data->p();
+ drawBorderlessRectShadow(this, p, rect);
+ p->fillRect(rect, m_data->solidColor);
}
void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color)
@@ -712,7 +768,9 @@ void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLef
return;
Path path = Path::createRoundedRectangle(rect, topLeft, topRight, bottomLeft, bottomRight);
- m_data->p()->fillPath(*path.platformPath(), QColor(color));
+ QPainter* p = m_data->p();
+ drawFilledShadowPath(this, p, path.platformPath());
+ p->fillPath(*path.platformPath(), QColor(color));
}
void GraphicsContext::beginPath()
@@ -750,7 +808,7 @@ void GraphicsContext::clipPath(WindRule clipRule)
if (paintingDisabled())
return;
- QPainter *p = m_data->p();
+ QPainter* p = m_data->p();
QPainterPath newPath = m_data->currentPath;
newPath.setFillRule(clipRule == RULE_EVENODD ? Qt::OddEvenFill : Qt::WindingFill);
p->setClipPath(newPath);
@@ -769,10 +827,10 @@ void GraphicsContext::drawFocusRing(const Color& color)
const Vector<IntRect>& rects = focusRingRects();
unsigned rectCount = rects.size();
- if (rects.size() == 0)
+ if (!rects.size())
return;
- QPainter *p = m_data->p();
+ QPainter* p = m_data->p();
const bool antiAlias = p->testRenderHint(QPainter::Antialiasing);
p->setRenderHint(QPainter::Antialiasing, m_data->antiAliasingForRectsAndLines);
@@ -793,7 +851,7 @@ void GraphicsContext::drawFocusRing(const Color& color)
QPainterPath newPath = stroker.createStroke(path);
p->strokePath(newPath, nPen);
#else
- for (int i = 0; i < rectCount; ++i)
+ for (unsigned i = 0; i < rectCount; ++i)
p->drawRect(QRectF(rects[i]));
#endif
p->setPen(oldPen);
@@ -802,7 +860,7 @@ void GraphicsContext::drawFocusRing(const Color& color)
p->setRenderHint(QPainter::Antialiasing, antiAlias);
}
-void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool printing)
+void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool)
{
if (paintingDisabled())
return;
@@ -811,8 +869,7 @@ void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool pr
drawLine(origin, endPoint);
}
-void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint&,
- int width, bool grammar)
+void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint&, int, bool)
{
if (paintingDisabled())
return;
@@ -829,10 +886,16 @@ FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& frect)
return FloatRect(QRectF(result));
}
-void GraphicsContext::setPlatformShadow(const IntSize& pos, int blur, const Color &color)
+void GraphicsContext::setPlatformShadow(const IntSize& size, int, const Color&)
{
// Qt doesn't support shadows natively, they are drawn manually in the draw*
// functions
+
+ if (m_common->state.shadowsIgnoreTransforms) {
+ // Meaning that this graphics context is associated with a CanvasRenderingContext
+ // We flip the height since CG and HTML5 Canvas have opposite Y axis
+ m_common->state.shadowSize = IntSize(size.width(), -size.height());
+ }
}
void GraphicsContext::clearPlatformShadow()
@@ -848,8 +911,8 @@ void GraphicsContext::beginTransparencyLayer(float opacity)
int x, y, w, h;
x = y = 0;
- QPainter *p = m_data->p();
- const QPaintDevice *device = p->device();
+ QPainter* p = m_data->p();
+ const QPaintDevice* device = p->device();
w = device->width();
h = device->height();
@@ -871,10 +934,10 @@ void GraphicsContext::endTransparencyLayer()
if (paintingDisabled())
return;
- TransparencyLayer *layer = m_data->layers.pop();
+ TransparencyLayer* layer = m_data->layers.pop();
layer->painter.end();
- QPainter *p = m_data->p();
+ QPainter* p = m_data->p();
p->save();
p->resetTransform();
p->setOpacity(layer->opacity);
@@ -889,7 +952,7 @@ void GraphicsContext::clearRect(const FloatRect& rect)
if (paintingDisabled())
return;
- QPainter *p = m_data->p();
+ QPainter* p = m_data->p();
QPainter::CompositionMode currentCompositionMode = p->compositionMode();
if (p->paintEngine()->hasFeature(QPaintEngine::PorterDuff))
p->setCompositionMode(QPainter::CompositionMode_Source);
@@ -916,7 +979,7 @@ void GraphicsContext::setLineCap(LineCap lc)
if (paintingDisabled())
return;
- QPainter *p = m_data->p();
+ QPainter* p = m_data->p();
QPen nPen = p->pen();
nPen.setCapStyle(toQtLineCap(lc));
p->setPen(nPen);
@@ -948,7 +1011,7 @@ void GraphicsContext::setLineJoin(LineJoin lj)
if (paintingDisabled())
return;
- QPainter *p = m_data->p();
+ QPainter* p = m_data->p();
QPen nPen = p->pen();
nPen.setJoinStyle(toQtLineJoin(lj));
p->setPen(nPen);
@@ -959,7 +1022,7 @@ void GraphicsContext::setMiterLimit(float limit)
if (paintingDisabled())
return;
- QPainter *p = m_data->p();
+ QPainter* p = m_data->p();
QPen nPen = p->pen();
nPen.setMiterLimit(limit);
p->setPen(nPen);
@@ -969,7 +1032,7 @@ void GraphicsContext::setAlpha(float opacity)
{
if (paintingDisabled())
return;
- QPainter *p = m_data->p();
+ QPainter* p = m_data->p();
p->setOpacity(opacity);
}
@@ -995,15 +1058,19 @@ void GraphicsContext::clipOut(const Path& path)
if (paintingDisabled())
return;
- QPainter *p = m_data->p();
- QRectF clipBounds = p->clipPath().boundingRect();
+ QPainter* p = m_data->p();
QPainterPath clippedOut = *path.platformPath();
QPainterPath newClip;
newClip.setFillRule(Qt::OddEvenFill);
- newClip.addRect(clipBounds);
- newClip.addPath(clippedOut);
-
- p->setClipPath(newClip, Qt::IntersectClip);
+ if (p->hasClipping()) {
+ newClip.addRect(p->clipPath().boundingRect());
+ newClip.addPath(clippedOut);
+ p->setClipPath(newClip, Qt::IntersectClip);
+ } else {
+ newClip.addRect(p->window());
+ newClip.addPath(clippedOut & newClip);
+ p->setClipPath(newClip);
+ }
}
void GraphicsContext::translate(float x, float y)
@@ -1061,14 +1128,21 @@ void GraphicsContext::clipOut(const IntRect& rect)
if (paintingDisabled())
return;
- QPainter *p = m_data->p();
- QRectF clipBounds = p->clipPath().boundingRect();
+ QPainter* p = m_data->p();
QPainterPath newClip;
newClip.setFillRule(Qt::OddEvenFill);
- newClip.addRect(clipBounds);
- newClip.addRect(QRect(rect));
-
- p->setClipPath(newClip, Qt::IntersectClip);
+ if (p->hasClipping()) {
+ newClip.addRect(p->clipPath().boundingRect());
+ newClip.addRect(QRect(rect));
+ p->setClipPath(newClip, Qt::IntersectClip);
+ } else {
+ QRect clipOutRect(rect);
+ QRect window(p->window());
+ clipOutRect &= window;
+ newClip.addRect(window);
+ newClip.addRect(clipOutRect);
+ p->setClipPath(newClip);
+ }
}
void GraphicsContext::clipOutEllipseInRect(const IntRect& rect)
@@ -1076,14 +1150,21 @@ void GraphicsContext::clipOutEllipseInRect(const IntRect& rect)
if (paintingDisabled())
return;
- QPainter *p = m_data->p();
- QRectF clipBounds = p->clipPath().boundingRect();
+ QPainter* p = m_data->p();
QPainterPath newClip;
newClip.setFillRule(Qt::OddEvenFill);
- newClip.addRect(clipBounds);
- newClip.addEllipse(QRect(rect));
-
- p->setClipPath(newClip, Qt::IntersectClip);
+ if (p->hasClipping()) {
+ newClip.addRect(p->clipPath().boundingRect());
+ newClip.addEllipse(QRect(rect));
+ p->setClipPath(newClip, Qt::IntersectClip);
+ } else {
+ QRect clipOutRect(rect);
+ QRect window(p->window());
+ clipOutRect &= window;
+ newClip.addRect(window);
+ newClip.addEllipse(clipOutRect);
+ p->setClipPath(newClip);
+ }
}
void GraphicsContext::clipToImageBuffer(const FloatRect&, const ImageBuffer*)
@@ -1109,7 +1190,7 @@ void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect,
path.setFillRule(Qt::OddEvenFill);
- QPainter *p = m_data->p();
+ QPainter* p = m_data->p();
const bool antiAlias = p->testRenderHint(QPainter::Antialiasing);
p->setRenderHint(QPainter::Antialiasing, true);
@@ -1134,7 +1215,7 @@ void GraphicsContext::concatCTM(const TransformationMatrix& transform)
}
}
-void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect)
+void GraphicsContext::setURLForRect(const KURL&, const IntRect&)
{
notImplemented();
}
@@ -1143,7 +1224,7 @@ void GraphicsContext::setPlatformStrokeColor(const Color& color)
{
if (paintingDisabled())
return;
- QPainter *p = m_data->p();
+ QPainter* p = m_data->p();
QPen newPen(p->pen());
newPen.setColor(color);
p->setPen(newPen);
@@ -1153,7 +1234,7 @@ void GraphicsContext::setPlatformStrokeStyle(const StrokeStyle& strokeStyle)
{
if (paintingDisabled())
return;
- QPainter *p = m_data->p();
+ QPainter* p = m_data->p();
QPen newPen(p->pen());
newPen.setStyle(toQPenStyle(strokeStyle));
p->setPen(newPen);
@@ -1163,7 +1244,7 @@ void GraphicsContext::setPlatformStrokeThickness(float thickness)
{
if (paintingDisabled())
return;
- QPainter *p = m_data->p();
+ QPainter* p = m_data->p();
QPen newPen(p->pen());
newPen.setWidthF(thickness);
p->setPen(newPen);
@@ -1184,7 +1265,6 @@ void GraphicsContext::setPlatformShouldAntialias(bool enable)
}
#ifdef Q_WS_WIN
-#include <windows.h>
HDC GraphicsContext::getWindowsContext(const IntRect& dstRect, bool supportAlphaBlend, bool mayCreateBitmap)
{
diff --git a/WebCore/platform/graphics/qt/IconQt.cpp b/WebCore/platform/graphics/qt/IconQt.cpp
index 34c3c47..98f4606 100644
--- a/WebCore/platform/graphics/qt/IconQt.cpp
+++ b/WebCore/platform/graphics/qt/IconQt.cpp
@@ -47,7 +47,7 @@ PassRefPtr<Icon> Icon::createIconForFile(const String& filename)
return i.release();
}
-PassRefPtr<Icon> Icon::createIconForFiles(const Vector<String>& filenames)
+PassRefPtr<Icon> Icon::createIconForFiles(const Vector<String>&)
{
//FIXME: Implement this
return 0;
diff --git a/WebCore/platform/graphics/qt/ImageBufferQt.cpp b/WebCore/platform/graphics/qt/ImageBufferQt.cpp
index 22a5a43..5255428 100644
--- a/WebCore/platform/graphics/qt/ImageBufferQt.cpp
+++ b/WebCore/platform/graphics/qt/ImageBufferQt.cpp
@@ -68,7 +68,7 @@ ImageBufferData::ImageBufferData(const IntSize& size)
painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
}
-ImageBuffer::ImageBuffer(const IntSize& size, ImageColorSpace imageColorSpace, bool& success)
+ImageBuffer::ImageBuffer(const IntSize& size, ImageColorSpace, bool& success)
: m_data(size)
, m_size(size)
{
@@ -125,12 +125,13 @@ void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookUpTable)
m_data.m_painter->begin(&m_data.m_pixmap);
}
-PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const
+template <Multiply multiplied>
+PassRefPtr<ImageData> getImageData(const IntRect& rect, const ImageBufferData& imageData, const IntSize& size)
{
PassRefPtr<ImageData> result = ImageData::create(rect.width(), rect.height());
unsigned char* data = result->data()->data()->data();
- if (rect.x() < 0 || rect.y() < 0 || (rect.x() + rect.width()) > m_size.width() || (rect.y() + rect.height()) > m_size.height())
+ if (rect.x() < 0 || rect.y() < 0 || (rect.x() + rect.width()) > size.width() || (rect.y() + rect.height()) > size.height())
memset(data, 0, result->data()->length());
int originx = rect.x();
@@ -140,8 +141,8 @@ PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const
originx = 0;
}
int endx = rect.x() + rect.width();
- if (endx > m_size.width())
- endx = m_size.width();
+ if (endx > size.width())
+ endx = size.width();
int numColumns = endx - originx;
int originy = rect.y();
@@ -151,11 +152,16 @@ PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const
originy = 0;
}
int endy = rect.y() + rect.height();
- if (endy > m_size.height())
- endy = m_size.height();
+ if (endy > size.height())
+ endy = size.height();
int numRows = endy - originy;
- QImage image = m_data.m_pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
+ QImage image = imageData.m_pixmap.toImage();
+ if (multiplied == Unmultiplied)
+ image = image.convertToFormat(QImage::Format_ARGB32);
+ else
+ image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
+
ASSERT(!image.isNull());
unsigned destBytesPerRow = 4 * rect.width();
@@ -176,7 +182,18 @@ PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const
return result;
}
-void ImageBuffer::putImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint)
+PassRefPtr<ImageData> ImageBuffer::getUnmultipliedImageData(const IntRect& rect) const
+{
+ return getImageData<Unmultiplied>(rect, m_data, m_size);
+}
+
+PassRefPtr<ImageData> ImageBuffer::getPremultipliedImageData(const IntRect& rect) const
+{
+ return getImageData<Premultiplied>(rect, m_data, m_size);
+}
+
+template <Multiply multiplied>
+void putImageData(ImageData*& source, const IntRect& sourceRect, const IntPoint& destPoint, ImageBufferData& data, const IntSize& size)
{
ASSERT(sourceRect.width() > 0);
ASSERT(sourceRect.height() > 0);
@@ -184,49 +201,65 @@ void ImageBuffer::putImageData(ImageData* source, const IntRect& sourceRect, con
int originx = sourceRect.x();
int destx = destPoint.x() + sourceRect.x();
ASSERT(destx >= 0);
- ASSERT(destx < m_size.width());
+ ASSERT(destx < size.width());
ASSERT(originx >= 0);
ASSERT(originx <= sourceRect.right());
int endx = destPoint.x() + sourceRect.right();
- ASSERT(endx <= m_size.width());
+ ASSERT(endx <= size.width());
int numColumns = endx - destx;
int originy = sourceRect.y();
int desty = destPoint.y() + sourceRect.y();
ASSERT(desty >= 0);
- ASSERT(desty < m_size.height());
+ ASSERT(desty < size.height());
ASSERT(originy >= 0);
ASSERT(originy <= sourceRect.bottom());
int endy = destPoint.y() + sourceRect.bottom();
- ASSERT(endy <= m_size.height());
+ ASSERT(endy <= size.height());
int numRows = endy - desty;
unsigned srcBytesPerRow = 4 * source->width();
- bool isPainting = m_data.m_painter->isActive();
+ bool isPainting = data.m_painter->isActive();
if (isPainting)
- m_data.m_painter->end();
+ data.m_painter->end();
- QImage image = m_data.m_pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
+ QImage image = data.m_pixmap.toImage();
+ if (multiplied == Unmultiplied)
+ image = image.convertToFormat(QImage::Format_ARGB32);
+ else
+ image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
unsigned char* srcRows = source->data()->data()->data() + originy * srcBytesPerRow + originx * 4;
for (int y = 0; y < numRows; ++y) {
quint32* scanLine = reinterpret_cast<quint32*>(image.scanLine(y + desty));
for (int x = 0; x < numColumns; x++) {
- int basex = x * 4;
- scanLine[x + destx] = reinterpret_cast<quint32*>(srcRows + basex)[0];
+ // ImageData stores the pixels in RGBA while QImage is ARGB
+ quint32 pixel = reinterpret_cast<quint32*>(srcRows + 4 * x)[0];
+ pixel = ((pixel << 16) & 0xff0000) | ((pixel >> 16) & 0xff) | (pixel & 0xff00ff00);
+ scanLine[x + destx] = pixel;
}
srcRows += srcBytesPerRow;
}
- m_data.m_pixmap = QPixmap::fromImage(image);
+ data.m_pixmap = QPixmap::fromImage(image);
if (isPainting)
- m_data.m_painter->begin(&m_data.m_pixmap);
+ data.m_painter->begin(&data.m_pixmap);
+}
+
+void ImageBuffer::putUnmultipliedImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint)
+{
+ putImageData<Unmultiplied>(source, sourceRect, destPoint, m_data, m_size);
+}
+
+void ImageBuffer::putPremultipliedImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint)
+{
+ putImageData<Premultiplied>(source, sourceRect, destPoint, m_data, m_size);
}
// We get a mimeType here but QImageWriter does not support mimetypes but
diff --git a/WebCore/platform/graphics/qt/ImageDecoderQt.cpp b/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
index 7bbdcc0..3a27fe3 100644
--- a/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
+++ b/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
@@ -35,150 +35,9 @@
#include <QtGui/QImageReader>
#include <qdebug.h>
-namespace {
- const QImage::Format DesiredFormat = QImage::Format_ARGB32;
- const bool debugImageDecoderQt = false;
-}
-
namespace WebCore {
-ImageDecoderQt::ImageData::ImageData(const QImage& image, ImageState imageState, int duration) :
- m_image(image), m_imageState(imageState), m_duration(duration)
-{
-}
-
-// Context, maintains IODevice on a data buffer.
-class ImageDecoderQt::ReadContext {
-public:
-
- enum LoadMode {
- // Load images incrementally. This is still experimental and
- // will cause the image plugins to report errors.
- // Also note that as of Qt 4.2.2, the JPEG loader does not return error codes
- // on "preliminary end of data".
- LoadIncrementally,
- // Load images only if all data have been received
- LoadComplete };
-
- ReadContext(const IncomingData & data, LoadMode loadMode, ImageList &target);
-
- enum ReadResult { ReadEOF, ReadFailed, ReadPartial, ReadComplete };
-
- // Append data and read out all images. Returns the result
- // of the last read operation, so, even if ReadPartial is returned,
- // a few images might have been read.
- ReadResult read(bool allDataReceived);
-
- QImageReader *reader() { return &m_reader; }
-private:
- enum IncrementalReadResult { IncrementalReadFailed, IncrementalReadPartial, IncrementalReadComplete };
- // Incrementally read an image
- IncrementalReadResult readImageLines(ImageData &);
-
- const LoadMode m_loadMode;
-
- QByteArray m_data;
- QBuffer m_buffer;
- QImageReader m_reader;
-
- ImageList &m_target;
-
- // Detected data format of the stream
- enum QImage::Format m_dataFormat;
- QSize m_size;
-
-};
-
-ImageDecoderQt::ReadContext::ReadContext(const IncomingData & data, LoadMode loadMode, ImageList &target)
- : m_loadMode(loadMode)
- , m_data(data.data(), data.size())
- , m_buffer(&m_data)
- , m_reader(&m_buffer)
- , m_target(target)
- , m_dataFormat(QImage::Format_Invalid)
-{
- m_buffer.open(QIODevice::ReadOnly);
-}
-
-
-ImageDecoderQt::ReadContext::ReadResult
- ImageDecoderQt::ReadContext::read(bool allDataReceived)
-{
- // Complete mode: Read only all all data received
- if (m_loadMode == LoadComplete && !allDataReceived)
- return ReadPartial;
-
- // Attempt to read out all images
- while (true) {
- if (m_target.empty() || m_target.back().m_imageState == ImageComplete) {
- // Start a new image.
- if (!m_reader.canRead())
- return ReadEOF;
-
- // Attempt to construct an empty image of the matching size and format
- // for efficient reading
- QImage newImage = m_dataFormat != QImage::Format_Invalid ?
- QImage(m_size, m_dataFormat) : QImage();
- m_target.push_back(ImageData(newImage));
- }
-
- // read chunks
- switch (readImageLines(m_target.back())) {
- case IncrementalReadFailed:
- m_target.pop_back();
- return ReadFailed;
- case IncrementalReadPartial:
- return ReadPartial;
- case IncrementalReadComplete:
- m_target.back().m_imageState = ImageComplete;
- //store for next
- m_dataFormat = m_target.back().m_image.format();
- m_size = m_target.back().m_image.size();
- const bool supportsAnimation = m_reader.supportsAnimation();
-
- if (debugImageDecoderQt)
- qDebug() << "readImage(): #" << m_target.size() << " complete, " << m_size
- << " format " << m_dataFormat << " supportsAnimation=" << supportsAnimation;
- // No point in readinfg further
- if (!supportsAnimation)
- return ReadComplete;
-
- break;
- }
- }
- return ReadComplete;
-}
-
-
-
-ImageDecoderQt::ReadContext::IncrementalReadResult
- ImageDecoderQt::ReadContext::readImageLines(ImageData &imageData)
-{
- // TODO: Implement incremental reading here,
- // set state to reflect complete header, etc.
- // For now, we read the whole image.
-
- const qint64 startPos = m_buffer.pos();
- // Oops, failed. Rewind.
- if (!m_reader.read(&imageData.m_image)) {
- m_buffer.seek(startPos);
- const bool gotHeader = imageData.m_image.size().width();
-
- if (debugImageDecoderQt)
- qDebug() << "readImageLines(): read() failed: " << m_reader.errorString()
- << " got header=" << gotHeader;
- // [Experimental] Did we manage to read the header?
- if (gotHeader) {
- imageData.m_imageState = ImageHeaderValid;
- return IncrementalReadPartial;
- }
- return IncrementalReadFailed;
- }
- imageData.m_duration = m_reader.nextImageDelay();
- return IncrementalReadComplete;
-}
-
-ImageDecoderQt* ImageDecoderQt::create(const SharedBuffer& data)
+ImageDecoder* ImageDecoder::create(const SharedBuffer& data)
{
// We need at least 4 bytes to figure out what kind of image we're dealing with.
if (data.size() < 4)
@@ -189,149 +48,196 @@ ImageDecoderQt* ImageDecoderQt::create(const SharedBuffer& data)
if (!buffer.open(QBuffer::ReadOnly))
return 0;
- QString imageFormat = QString::fromLatin1(QImageReader::imageFormat(&buffer).toLower());
+ QByteArray imageFormat = QImageReader::imageFormat(&buffer);
if (imageFormat.isEmpty())
return 0; // Image format not supported
return new ImageDecoderQt(imageFormat);
}
-ImageDecoderQt::ImageDecoderQt(const QString &imageFormat)
- : m_hasAlphaChannel(false)
- , m_imageFormat(imageFormat)
+ImageDecoderQt::ImageDecoderQt(const QByteArray& imageFormat)
+ : m_buffer(0)
+ , m_reader(0)
+ , m_repetitionCount(-1)
{
}
ImageDecoderQt::~ImageDecoderQt()
{
+ delete m_reader;
+ delete m_buffer;
}
-bool ImageDecoderQt::hasFirstImageHeader() const
+void ImageDecoderQt::setData(SharedBuffer* data, bool allDataReceived)
{
- return !m_imageList.empty() && m_imageList[0].m_imageState >= ImageHeaderValid;
-}
+ if (m_failed)
+ return;
-void ImageDecoderQt::reset()
-{
- m_hasAlphaChannel = false;
- m_failed = false;
- m_imageList.clear();
- m_pixmapCache.clear();
- m_loopCount = cAnimationNone;
-}
+ // Cache our own new data.
+ ImageDecoder::setData(data, allDataReceived);
-void ImageDecoderQt::setData(const IncomingData &data, bool allDataReceived)
-{
- reset();
- ReadContext readContext(data, ReadContext::LoadComplete, m_imageList);
-
- if (debugImageDecoderQt)
- qDebug() << " setData " << data.size() << " image bytes, complete=" << allDataReceived;
-
- const ReadContext::ReadResult readResult = readContext.read(allDataReceived);
-
- if (hasFirstImageHeader())
- m_hasAlphaChannel = m_imageList[0].m_image.hasAlphaChannel();
-
- if (debugImageDecoderQt)
- qDebug() << " read returns " << readResult;
-
- switch (readResult) {
- case ReadContext::ReadFailed:
- m_failed = true;
- break;
- case ReadContext::ReadEOF:
- case ReadContext::ReadPartial:
- case ReadContext::ReadComplete:
- // Did we read anything - try to set the size.
- if (hasFirstImageHeader()) {
- QSize imgSize = m_imageList[0].m_image.size();
- setSize(imgSize.width(), imgSize.height());
-
- if (readContext.reader()->supportsAnimation()) {
- if (readContext.reader()->loopCount() != -1)
- m_loopCount = readContext.reader()->loopCount();
- else
- m_loopCount = 0; //loop forever
- }
- }
- break;
- }
-}
+ // No progressive loading possible
+ if (!allDataReceived)
+ return;
+
+ // We expect to be only called once with allDataReceived
+ ASSERT(!m_buffer);
+ ASSERT(!m_reader);
+ // Attempt to load the data
+ QByteArray imageData = QByteArray::fromRawData(m_data->data(), m_data->size());
+ m_buffer = new QBuffer;
+ m_buffer->setData(imageData);
+ m_buffer->open(QBuffer::ReadOnly);
+ m_reader = new QImageReader(m_buffer);
+
+ if (!m_reader->canRead())
+ failRead();
+}
bool ImageDecoderQt::isSizeAvailable()
{
- if (debugImageDecoderQt)
- qDebug() << " ImageDecoderQt::isSizeAvailable() returns" << ImageDecoder::isSizeAvailable();
+ if (!m_failed && !ImageDecoder::isSizeAvailable() && m_reader)
+ internalDecodeSize();
+
return ImageDecoder::isSizeAvailable();
}
-size_t ImageDecoderQt::frameCount() const
+size_t ImageDecoderQt::frameCount()
{
- if (debugImageDecoderQt)
- qDebug() << " ImageDecoderQt::frameCount() returns" << m_imageList.size();
- return m_imageList.size();
+ if (m_frameBufferCache.isEmpty() && m_reader) {
+ if (m_reader->supportsAnimation()) {
+ int imageCount = m_reader->imageCount();
+
+ // Fixup for Qt decoders... imageCount() is wrong
+ // and jumpToNextImage does not work either... so
+ // we will have to parse everything...
+ if (imageCount == 0)
+ forceLoadEverything();
+ else
+ m_frameBufferCache.resize(imageCount);
+ } else {
+ m_frameBufferCache.resize(1);
+ }
+ }
+
+ return m_frameBufferCache.size();
}
int ImageDecoderQt::repetitionCount() const
{
- if (debugImageDecoderQt)
- qDebug() << " ImageDecoderQt::repetitionCount() returns" << m_loopCount;
- return m_loopCount;
+ if (m_reader && m_reader->supportsAnimation())
+ m_repetitionCount = qMax(0, m_reader->loopCount());
+
+ return m_repetitionCount;
}
-bool ImageDecoderQt::supportsAlpha() const
+String ImageDecoderQt::filenameExtension() const
{
- return m_hasAlphaChannel;
-}
+ return m_format;
+};
-int ImageDecoderQt::duration(size_t index) const
+RGBA32Buffer* ImageDecoderQt::frameBufferAtIndex(size_t index)
{
- if (index >= m_imageList.size())
+ // this information might not have been set
+ int count = m_frameBufferCache.size();
+ if (count == 0) {
+ internalDecodeSize();
+ count = frameCount();
+ }
+
+ if (index >= static_cast<size_t>(count))
return 0;
- return m_imageList[index].m_duration;
+
+ RGBA32Buffer& frame = m_frameBufferCache[index];
+ if (frame.status() != RGBA32Buffer::FrameComplete && m_reader)
+ internalReadImage(index);
+ return &frame;
}
-String ImageDecoderQt::filenameExtension() const
+void ImageDecoderQt::clearFrameBufferCache(size_t index)
{
- if (debugImageDecoderQt)
- qDebug() << " ImageDecoderQt::filenameExtension() returns" << m_imageFormat;
- return m_imageFormat;
-};
+ // Currently QImageReader will be asked to read everything. This
+ // might change when we read gif images on demand. For now we
+ // can have a rather simple implementation.
+ if (index > m_frameBufferCache.size())
+ return;
-RGBA32Buffer* ImageDecoderQt::frameBufferAtIndex(size_t index)
+ for (size_t i = 0; i < index; ++index)
+ m_frameBufferCache[index].clear();
+}
+
+void ImageDecoderQt::internalDecodeSize()
{
- Q_ASSERT("use imageAtIndex instead");
- return 0;
+ ASSERT(m_reader);
+
+ QSize size = m_reader->size();
+ setSize(size.width(), size.height());
}
-QPixmap* ImageDecoderQt::imageAtIndex(size_t index) const
+void ImageDecoderQt::internalReadImage(size_t frameIndex)
{
- if (debugImageDecoderQt)
- qDebug() << "ImageDecoderQt::imageAtIndex(" << index << ')';
+ ASSERT(m_reader);
- if (index >= m_imageList.size())
- return 0;
+ if (m_reader->supportsAnimation())
+ m_reader->jumpToImage(frameIndex);
+ else if (frameIndex != 0)
+ return failRead();
- if (!m_pixmapCache.contains(index)) {
- m_pixmapCache.insert(index,
- QPixmap::fromImage(m_imageList[index].m_image));
+ internalHandleCurrentImage(frameIndex);
- // store null image since the converted pixmap is already in pixmap cache
- Q_ASSERT(m_imageList[index].m_imageState == ImageComplete);
- m_imageList[index].m_image = QImage();
- }
- return &m_pixmapCache[index];
+ // Attempt to return some memory
+ for (int i = 0; i < m_frameBufferCache.size(); ++i)
+ if (m_frameBufferCache[i].status() != RGBA32Buffer::FrameComplete)
+ return;
+
+ delete m_reader;
+ delete m_buffer;
+ m_buffer = 0;
+ m_reader = 0;
}
-void ImageDecoderQt::clearFrame(size_t index)
+void ImageDecoderQt::internalHandleCurrentImage(size_t frameIndex)
{
- if (m_imageList.size() < (int)index)
- m_imageList[index].m_image = QImage();
- m_pixmapCache.take(index);
+ // Now get the QImage from Qt and place it in the RGBA32Buffer
+ QImage img;
+ if (!m_reader->read(&img))
+ return failRead();
+
+ // now into the RGBA32Buffer - even if the image is not
+ QSize imageSize = img.size();
+ RGBA32Buffer* const buffer = &m_frameBufferCache[frameIndex];
+ buffer->setRect(m_reader->currentImageRect());
+ buffer->setStatus(RGBA32Buffer::FrameComplete);
+ buffer->setDuration(m_reader->nextImageDelay());
+ buffer->setDecodedImage(img);
}
+// We will parse everything and we have no idea how
+// many images we have... We will have to find out the
+// hard way.
+void ImageDecoderQt::forceLoadEverything()
+{
+ int imageCount = 0;
+
+ do {
+ m_frameBufferCache.resize(++imageCount);
+ internalHandleCurrentImage(imageCount - 1);
+ } while(!m_failed);
+
+ // reset the failed state and resize the vector...
+ m_frameBufferCache.resize(imageCount - 1);
+ m_failed = false;
+}
+
+void ImageDecoderQt::failRead()
+{
+ setFailed();
+ delete m_reader;
+ delete m_buffer;
+ m_reader = 0;
+ m_buffer = 0;
+}
}
// vim: ts=4 sw=4 et
diff --git a/WebCore/platform/graphics/qt/ImageDecoderQt.h b/WebCore/platform/graphics/qt/ImageDecoderQt.h
index fc52479..7b3b686 100644
--- a/WebCore/platform/graphics/qt/ImageDecoderQt.h
+++ b/WebCore/platform/graphics/qt/ImageDecoderQt.h
@@ -28,10 +28,11 @@
#define ImageDecoderQt_h
#include "ImageDecoder.h"
-#include <QtGui/QImage>
+#include <QtGui/QImageReader>
#include <QtGui/QPixmap>
#include <QtCore/QList>
#include <QtCore/QHash>
+#include <QtCore/QBuffer>
namespace WebCore {
@@ -39,54 +40,35 @@ namespace WebCore {
class ImageDecoderQt : public ImageDecoder
{
public:
- static ImageDecoderQt* create(const SharedBuffer& data);
+ ImageDecoderQt(const QByteArray& imageFormat);
~ImageDecoderQt();
- typedef Vector<char> IncomingData;
-
- virtual void setData(const IncomingData& data, bool allDataReceived);
+ virtual void setData(SharedBuffer* data, bool allDataReceived);
virtual bool isSizeAvailable();
- virtual size_t frameCount() const;
+ virtual size_t frameCount();
virtual int repetitionCount() const;
virtual RGBA32Buffer* frameBufferAtIndex(size_t index);
- QPixmap* imageAtIndex(size_t index) const;
- virtual bool supportsAlpha() const;
- int duration(size_t index) const;
virtual String filenameExtension() const;
- void clearFrame(size_t index);
+ virtual void clearFrameBufferCache(size_t clearBeforeFrame);
private:
- ImageDecoderQt(const QString &imageFormat);
ImageDecoderQt(const ImageDecoderQt&);
ImageDecoderQt &operator=(const ImageDecoderQt&);
- class ReadContext;
- void reset();
- bool hasFirstImageHeader() const;
-
- enum ImageState {
- // Started image reading
- ImagePartial,
- // Header (size / alpha) are known
- ImageHeaderValid,
- // Image is complete
- ImageComplete };
-
- struct ImageData {
- ImageData(const QImage& image, ImageState imageState = ImagePartial, int duration=0);
- QImage m_image;
- ImageState m_imageState;
- int m_duration;
- };
-
- bool m_hasAlphaChannel;
- typedef QList<ImageData> ImageList;
- mutable ImageList m_imageList;
- mutable QHash<int, QPixmap> m_pixmapCache;
- int m_loopCount;
- QString m_imageFormat;
+private:
+ void internalDecodeSize();
+ void internalReadImage(size_t);
+ void internalHandleCurrentImage(size_t);
+ void forceLoadEverything();
+ void failRead();
+
+private:
+ String m_format;
+ QBuffer* m_buffer;
+ QImageReader* m_reader;
+ mutable int m_repetitionCount;
};
diff --git a/WebCore/platform/graphics/qt/ImageQt.cpp b/WebCore/platform/graphics/qt/ImageQt.cpp
index 5d40e26..da6ddac 100644
--- a/WebCore/platform/graphics/qt/ImageQt.cpp
+++ b/WebCore/platform/graphics/qt/ImageQt.cpp
@@ -76,6 +76,7 @@ bool FrameData::clear(bool clearMetadata)
m_haveMetadata = false;
if (m_frame) {
+ delete m_frame;
m_frame = 0;
return true;
}
diff --git a/WebCore/platform/graphics/qt/ImageSourceQt.cpp b/WebCore/platform/graphics/qt/ImageSourceQt.cpp
deleted file mode 100644
index 8ae449c..0000000
--- a/WebCore/platform/graphics/qt/ImageSourceQt.cpp
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
- *
- * 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 "ImageSource.h"
-#include "ImageDecoderQt.h"
-#include "SharedBuffer.h"
-
-#include <QBuffer>
-#include <QImage>
-#include <QImageReader>
-
-namespace WebCore {
-
-ImageSource::ImageSource()
- : m_decoder(0)
-{
-}
-
-ImageSource::~ImageSource()
-{
- clear(true);
-}
-
-bool ImageSource::initialized() const
-{
- return m_decoder;
-}
-
-void ImageSource::setData(SharedBuffer* data, bool allDataReceived)
-{
- // Make the decoder by sniffing the bytes.
- // This method will examine the data and instantiate an instance of the appropriate decoder plugin.
- // If insufficient bytes are available to determine the image type, no decoder plugin will be
- // made.
- if (!m_decoder)
- m_decoder = ImageDecoderQt::create(*data);
-
- if (!m_decoder)
- return;
-
- m_decoder->setData(data->buffer(), allDataReceived);
-}
-
-String ImageSource::filenameExtension() const
-{
- if (!m_decoder)
- return String();
-
- return m_decoder->filenameExtension();
-}
-
-bool ImageSource::isSizeAvailable()
-{
- if (!m_decoder)
- return false;
-
- return m_decoder->isSizeAvailable();
-}
-
-IntSize ImageSource::size() const
-{
- if (!m_decoder)
- return IntSize();
-
- return m_decoder->size();
-}
-
-IntSize ImageSource::frameSizeAtIndex(size_t index) const
-{
- if (!m_decoder)
- return IntSize();
-
- return m_decoder->frameSizeAtIndex(index);
-}
-
-int ImageSource::repetitionCount()
-{
- if (!m_decoder)
- return cAnimationNone;
-
- return m_decoder->repetitionCount();
-}
-
-size_t ImageSource::frameCount() const
-{
- if (!m_decoder)
- return 0;
-
- return m_decoder->frameCount();
-}
-
-NativeImagePtr ImageSource::createFrameAtIndex(size_t index)
-{
- if (!m_decoder)
- return 0;
-
- return m_decoder->imageAtIndex(index);
-}
-
-float ImageSource::frameDurationAtIndex(size_t index)
-{
- if (!m_decoder)
- return 0;
-
- // Many annoying ads specify a 0 duration to make an image flash as quickly
- // as possible. We follow WinIE's behavior and use a duration of 100 ms
- // for any frames that specify a duration of <= 50 ms. See
- // <http://bugs.webkit.org/show_bug.cgi?id=14413> or Radar 4051389 for
- // more.
- const float duration = m_decoder->duration(index) / 1000.0f;
- return (duration < 0.051f) ? 0.100f : duration;
-}
-
-bool ImageSource::frameHasAlphaAtIndex(size_t index)
-{
- if (!m_decoder || !m_decoder->supportsAlpha())
- return false;
-
- const QPixmap* source = m_decoder->imageAtIndex(index);
- if (!source)
- return false;
-
- return source->hasAlphaChannel();
-}
-
-bool ImageSource::frameIsCompleteAtIndex(size_t index)
-{
- return (m_decoder && m_decoder->imageAtIndex(index));
-}
-
-void ImageSource::clear(bool destroyAll, size_t clearBeforeFrame, SharedBuffer* data, bool allDataReceived)
-{
- if (!destroyAll) {
- if (m_decoder)
- m_decoder->clearFrameBufferCache(clearBeforeFrame);
- return;
- }
-
- delete m_decoder;
- m_decoder = 0;
- if (data)
- setData(data, allDataReceived);
-}
-
-}
-
-// vim: ts=4 sw=4 et
diff --git a/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp b/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp
index 76b1494..7078d16 100644
--- a/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp
+++ b/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp
@@ -27,6 +27,7 @@
#include "FrameView.h"
#include "GraphicsContext.h"
#include "NotImplemented.h"
+#include "TimeRanges.h"
#include "Widget.h"
#include <wtf/HashSet.h>
@@ -37,9 +38,9 @@
#include <QUrl>
#include <QEvent>
-#include <Phonon/AudioOutput>
-#include <Phonon/MediaObject>
-#include <Phonon/VideoWidget>
+#include <audiooutput.h>
+#include <mediaobject.h>
+#include <videowidget.h>
using namespace Phonon;
@@ -146,7 +147,7 @@ void MediaPlayerPrivate::getSupportedTypes(HashSet<String>&)
notImplemented();
}
-MediaPlayer::SupportsType MediaPlayerPrivate::supportsType(const String& type, const String& codecs)
+MediaPlayer::SupportsType MediaPlayerPrivate::supportsType(const String&, const String&)
{
// FIXME: do the real thing
notImplemented();
@@ -160,6 +161,14 @@ bool MediaPlayerPrivate::hasVideo() const
return hasVideo;
}
+bool MediaPlayerPrivate::hasAudio() const
+{
+ // FIXME: Phonon::MediaObject does not have such a hasAudio() function
+ bool hasAudio = true;
+ LOG(Media, "MediaPlayerPrivatePhonon::hasAudio() -> %s", hasAudio ? "true" : "false");
+ return hasAudio;
+}
+
void MediaPlayerPrivate::load(const String& url)
{
LOG(Media, "MediaPlayerPrivatePhonon::load(\"%s\")", url.utf8().data());
@@ -247,15 +256,15 @@ float MediaPlayerPrivate::currentTime() const
return currentTime;
}
-void MediaPlayerPrivate::setEndTime(float endTime)
+void MediaPlayerPrivate::setEndTime(float)
{
notImplemented();
}
-float MediaPlayerPrivate::maxTimeBuffered() const
+PassRefPtr<TimeRanges> MediaPlayerPrivate::buffered() const
{
notImplemented();
- return 0.0f;
+ return TimeRanges::create();
}
float MediaPlayerPrivate::maxTimeSeekable() const
diff --git a/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.h b/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.h
index 9572d61..e1193b6 100644
--- a/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.h
+++ b/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.h
@@ -80,6 +80,7 @@ namespace WebCore {
IntSize naturalSize() const;
bool hasVideo() const;
+ bool hasAudio() const;
void load(const String &url);
void cancelLoad();
@@ -104,7 +105,7 @@ namespace WebCore {
MediaPlayer::NetworkState networkState() const;
MediaPlayer::ReadyState readyState() const;
- float maxTimeBuffered() const;
+ PassRefPtr<TimeRanges> buffered() const;
float maxTimeSeekable() const;
unsigned bytesLoaded() const;
bool totalBytesKnown() const;
diff --git a/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp b/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp
index f823f84..f093d7d 100644
--- a/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp
+++ b/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp
@@ -33,7 +33,7 @@ void SimpleFontData::determinePitch()
m_treatAsFixedPitch = m_platformData.font().fixedPitch();
}
-bool SimpleFontData::containsCharacters(const UChar*, int length) const
+bool SimpleFontData::containsCharacters(const UChar*, int) const
{
return true;
}
diff --git a/WebCore/platform/graphics/qt/StillImageQt.h b/WebCore/platform/graphics/qt/StillImageQt.h
index 2b2c1f7..6c417b1 100644
--- a/WebCore/platform/graphics/qt/StillImageQt.h
+++ b/WebCore/platform/graphics/qt/StillImageQt.h
@@ -41,7 +41,7 @@ namespace WebCore {
// FIXME: StillImages are underreporting decoded sizes and will be unable
// to prune because these functions are not implemented yet.
- virtual void destroyDecodedData(bool destroyAll = true) { }
+ virtual void destroyDecodedData(bool destroyAll = true) { Q_UNUSED(destroyAll); }
virtual unsigned decodedSize() const { return 0; }
virtual IntSize size() const;
diff --git a/WebCore/platform/graphics/skia/GradientSkia.cpp b/WebCore/platform/graphics/skia/GradientSkia.cpp
index 3bdddb2..268b17e 100644
--- a/WebCore/platform/graphics/skia/GradientSkia.cpp
+++ b/WebCore/platform/graphics/skia/GradientSkia.cpp
@@ -152,19 +152,21 @@ SkShader* Gradient::platformGradient()
}
if (m_radial) {
- // FIXME: CSS radial Gradients allow an offset focal point (the
- // "start circle"), but skia doesn't seem to support that, so this just
- // ignores m_p0/m_r0 and draws the gradient centered in the "end
- // circle" (m_p1/m_r1).
- // See http://webkit.org/blog/175/introducing-css-gradients/ for a
- // description of the expected behavior.
-
- // The radius we give to Skia must be positive (and non-zero). If
- // we're given a zero radius, just ask for a very small radius so
- // Skia will still return an object.
- SkScalar radius = m_r1 > 0 ? WebCoreFloatToSkScalar(m_r1) : SK_ScalarMin;
- m_gradient = SkGradientShader::CreateRadial(m_p1,
- radius, colors, pos, static_cast<int>(countUsed), tile);
+ // Since the two-point radial gradient is slower than the plain radial,
+ // only use it if we have to.
+ if (m_p0 != m_p1) {
+ // The radii we give to Skia must be positive. If we're given a
+ // negative radius, ask for zero instead.
+ SkScalar radius0 = m_r0 >= 0.0f ? WebCoreFloatToSkScalar(m_r0) : 0;
+ SkScalar radius1 = m_r1 >= 0.0f ? WebCoreFloatToSkScalar(m_r1) : 0;
+ m_gradient = SkGradientShader::CreateTwoPointRadial(m_p0, radius0, m_p1, radius1, colors, pos, static_cast<int>(countUsed), tile);
+ } else {
+ // The radius we give to Skia must be positive (and non-zero). If
+ // we're given a zero radius, just ask for a very small radius so
+ // Skia will still return an object.
+ SkScalar radius = m_r1 > 0 ? WebCoreFloatToSkScalar(m_r1) : SK_ScalarMin;
+ m_gradient = SkGradientShader::CreateRadial(m_p1, radius, colors, pos, static_cast<int>(countUsed), tile);
+ }
} else {
SkPoint pts[2] = { m_p0, m_p1 };
m_gradient = SkGradientShader::CreateLinear(pts, colors, pos,
diff --git a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
index bbb42c9..c9f1349 100644
--- a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
+++ b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
@@ -31,11 +31,11 @@
#include "config.h"
#include "GraphicsContext.h"
-#include "GraphicsContextPlatformPrivate.h"
-#include "GraphicsContextPrivate.h"
#include "Color.h"
#include "FloatRect.h"
#include "Gradient.h"
+#include "GraphicsContextPlatformPrivate.h"
+#include "GraphicsContextPrivate.h"
#include "ImageBuffer.h"
#include "IntRect.h"
#include "NativeImageSkia.h"
@@ -46,9 +46,9 @@
#include "SkBitmap.h"
#include "SkBlurDrawLooper.h"
#include "SkCornerPathEffect.h"
-#include "skia/ext/platform_canvas.h"
-#include "SkiaUtils.h"
#include "SkShader.h"
+#include "SkiaUtils.h"
+#include "skia/ext/platform_canvas.h"
#include <math.h>
#include <wtf/Assertions.h>
@@ -60,6 +60,23 @@ namespace WebCore {
namespace {
+inline int fastMod(int value, int max)
+{
+ int sign = SkExtractSign(value);
+
+ value = SkApplySign(value, sign);
+ if (value >= max)
+ value %= max;
+ return SkApplySign(value, sign);
+}
+
+inline float square(float n)
+{
+ return n * n;
+}
+
+} // namespace
+
// "Seatbelt" functions ------------------------------------------------------
//
// These functions check certain graphics primitives for being "safe".
@@ -195,23 +212,6 @@ void addCornerArc(SkPath* path, const SkRect& rect, const IntSize& size, int sta
path->arcTo(r, SkIntToScalar(startAngle), SkIntToScalar(90), false);
}
-inline int fastMod(int value, int max)
-{
- int sign = SkExtractSign(value);
-
- value = SkApplySign(value, sign);
- if (value >= max)
- value %= max;
- return SkApplySign(value, sign);
-}
-
-inline float square(float n)
-{
- return n * n;
-}
-
-} // namespace
-
// -----------------------------------------------------------------------------
// This may be called with a NULL pointer to create a graphics context that has
@@ -293,7 +293,7 @@ void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness
path.addOval(r, SkPath::kCW_Direction);
// only perform the inset if we won't invert r
if (2 * thickness < rect.width() && 2 * thickness < rect.height()) {
- r.inset(SkIntToScalar(thickness) ,SkIntToScalar(thickness));
+ r.inset(SkIntToScalar(thickness), SkIntToScalar(thickness));
path.addOval(r, SkPath::kCCW_Direction);
}
platformContext()->canvas()->clipPath(path);
@@ -403,6 +403,9 @@ void GraphicsContext::clipPath(WindRule clipRule)
return;
SkPath path = platformContext()->currentPathInLocalCoordinates();
+ if (!isPathSkiaSafe(getCTM(), path))
+ return;
+
path.setFillType(clipRule == RULE_EVENODD ? SkPath::kEvenOdd_FillType : SkPath::kWinding_FillType);
platformContext()->canvas()->clipPath(path);
}
@@ -487,7 +490,7 @@ void GraphicsContext::drawFocusRing(const Color& color)
const Vector<IntRect>& rects = focusRingRects();
unsigned rectCount = rects.size();
- if (0 == rectCount)
+ if (!rectCount)
return;
SkRegion focusRingRegion;
@@ -521,26 +524,28 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
return;
SkPaint paint;
- SkPoint pts[2] = { (SkPoint)point1, (SkPoint)point2 };
- if (!isPointSkiaSafe(getCTM(), pts[0]) || !isPointSkiaSafe(getCTM(), pts[1]))
+ if (!isPointSkiaSafe(getCTM(), point1) || !isPointSkiaSafe(getCTM(), point2))
return;
+ FloatPoint p1 = point1;
+ FloatPoint p2 = point2;
+ bool isVerticalLine = (p1.x() == p2.x());
+ int width = roundf(strokeThickness());
+
// We know these are vertical or horizontal lines, so the length will just
// be the sum of the displacement component vectors give or take 1 -
// probably worth the speed up of no square root, which also won't be exact.
- SkPoint disp = pts[1] - pts[0];
- int length = SkScalarRound(disp.fX + disp.fY);
+ FloatSize disp = p2 - p1;
+ int length = SkScalarRound(disp.width() + disp.height());
platformContext()->setupPaintForStroking(&paint, 0, length);
- int width = roundf(strokeThickness());
- bool isVerticalLine = pts[0].fX == pts[1].fX;
if (strokeStyle() == DottedStroke || strokeStyle() == DashedStroke) {
// Do a rect fill of our endpoints. This ensures we always have the
// appearance of being a border. We then draw the actual dotted/dashed line.
SkRect r1, r2;
- r1.set(pts[0].fX, pts[0].fY, pts[0].fX + width, pts[0].fY + width);
- r2.set(pts[1].fX, pts[1].fY, pts[1].fX + width, pts[1].fY + width);
+ r1.set(p1.x(), p1.y(), p1.x() + width, p1.y() + width);
+ r2.set(p2.x(), p2.y(), p2.x() + width, p2.y() + width);
if (isVerticalLine) {
r1.offset(-width / 2, 0);
@@ -553,35 +558,11 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
fillPaint.setColor(paint.getColor());
platformContext()->canvas()->drawRect(r1, fillPaint);
platformContext()->canvas()->drawRect(r2, fillPaint);
-
- // Since we've already rendered the endcaps, adjust the endpoints to
- // exclude them from the line itself.
- if (isVerticalLine) {
- pts[0].fY += width;
- pts[1].fY -= width;
- } else {
- pts[0].fX += width;
- pts[1].fX -= width;
- }
}
- // "Borrowed" this comment and idea from GraphicsContextCG.cpp
- //
- // For odd widths, we add in 0.5 to the appropriate x/y so that the float
- // arithmetic works out. For example, with a border width of 3, KHTML will
- // pass us (y1+y2)/2, e.g., (50+53)/2 = 103/2 = 51 when we want 51.5. It is
- // always true that an even width gave us a perfect position, but an odd
- // width gave us a position that is off by exactly 0.5.
+ adjustLineToPixelBoundaries(p1, p2, width, penStyle);
+ SkPoint pts[2] = { (SkPoint)p1, (SkPoint)p2 };
- if (width & 1) { // Odd.
- if (isVerticalLine) {
- pts[0].fX = pts[0].fX + SK_ScalarHalf;
- pts[1].fX = pts[0].fX;
- } else { // Horizontal line
- pts[0].fY = pts[0].fY + SK_ScalarHalf;
- pts[1].fY = pts[0].fY;
- }
- }
platformContext()->canvas()->drawPoints(SkCanvas::kLines_PointMode, 2, pts, paint);
}
@@ -844,9 +825,9 @@ FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect)
deviceLowerRight.setY(roundf(deviceLowerRight.y()));
// Don't let the height or width round to 0 unless either was originally 0
- if (deviceOrigin.y() == deviceLowerRight.y() && rect.height() != 0)
+ if (deviceOrigin.y() == deviceLowerRight.y() && rect.height())
deviceLowerRight.move(0, 1);
- if (deviceOrigin.x() == deviceLowerRight.x() && rect.width() != 0)
+ if (deviceOrigin.x() == deviceLowerRight.x() && rect.width())
deviceLowerRight.move(1, 0);
FloatPoint roundedOrigin(deviceOrigin.x() / deviceScaleX,
@@ -919,7 +900,7 @@ void GraphicsContext::setLineDash(const DashArray& dashes, float dashOffset)
return;
}
- size_t count = (dashLength % 2) == 0 ? dashLength : dashLength * 2;
+ size_t count = !(dashLength % 2) ? dashLength : dashLength * 2;
SkScalar* intervals = new SkScalar[count];
for (unsigned int i = 0; i < count; i++)
@@ -990,8 +971,8 @@ void GraphicsContext::setPlatformShadow(const IntSize& size,
return;
// Detect when there's no effective shadow and clear the looper.
- if (size.width() == 0 && size.height() == 0 && blurInt == 0) {
- platformContext()->setDrawLooper(NULL);
+ if (!size.width() && !size.height() && !blurInt) {
+ platformContext()->setDrawLooper(0);
return;
}
diff --git a/WebCore/platform/graphics/skia/ImageBufferSkia.cpp b/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
index 7935ff1..a5c8926 100644
--- a/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
+++ b/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
@@ -39,6 +39,7 @@
#include "ImageData.h"
#include "PlatformContextSkia.h"
#include "PNGImageEncoder.h"
+#include "SkColorPriv.h"
#include "SkiaUtils.h"
using namespace std;
@@ -118,16 +119,16 @@ void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookUpTable)
}
}
-PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const
+template <Multiply multiplied>
+PassRefPtr<ImageData> getImageData(const IntRect& rect, const SkBitmap& bitmap,
+ const IntSize& size)
{
- ASSERT(context());
-
RefPtr<ImageData> result = ImageData::create(rect.width(), rect.height());
unsigned char* data = result->data()->data()->data();
if (rect.x() < 0 || rect.y() < 0 ||
- (rect.x() + rect.width()) > m_size.width() ||
- (rect.y() + rect.height()) > m_size.height())
+ (rect.x() + rect.width()) > size.width() ||
+ (rect.y() + rect.height()) > size.height())
memset(data, 0, result->data()->length());
int originX = rect.x();
@@ -137,8 +138,8 @@ PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const
originX = 0;
}
int endX = rect.x() + rect.width();
- if (endX > m_size.width())
- endX = m_size.width();
+ if (endX > size.width())
+ endX = size.width();
int numColumns = endX - originX;
int originY = rect.y();
@@ -148,11 +149,10 @@ PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const
originY = 0;
}
int endY = rect.y() + rect.height();
- if (endY > m_size.height())
- endY = m_size.height();
+ if (endY > size.height())
+ endY = size.height();
int numRows = endY - originY;
- const SkBitmap& bitmap = *context()->platformContext()->bitmap();
ASSERT(bitmap.config() == SkBitmap::kARGB_8888_Config);
SkAutoLockPixels bitmapLock(bitmap);
@@ -162,12 +162,21 @@ PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const
for (int y = 0; y < numRows; ++y) {
uint32_t* srcRow = bitmap.getAddr32(originX, originY + y);
for (int x = 0; x < numColumns; ++x) {
- SkColor color = SkPMColorToColor(srcRow[x]);
unsigned char* destPixel = &destRow[x * 4];
- destPixel[0] = SkColorGetR(color);
- destPixel[1] = SkColorGetG(color);
- destPixel[2] = SkColorGetB(color);
- destPixel[3] = SkColorGetA(color);
+ if (multiplied == Unmultiplied) {
+ SkColor color = SkPMColorToColor(srcRow[x]);
+ destPixel[0] = SkColorGetR(color);
+ destPixel[1] = SkColorGetG(color);
+ destPixel[2] = SkColorGetB(color);
+ destPixel[3] = SkColorGetA(color);
+ } else {
+ // Input and output are both pre-multiplied, we just need to re-arrange the
+ // bytes from the bitmap format to RGBA.
+ destPixel[0] = SkGetPackedR32(srcRow[x]);
+ destPixel[1] = SkGetPackedG32(srcRow[x]);
+ destPixel[2] = SkGetPackedB32(srcRow[x]);
+ destPixel[3] = SkGetPackedA32(srcRow[x]);
+ }
}
destRow += destBytesPerRow;
}
@@ -175,8 +184,19 @@ PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const
return result;
}
-void ImageBuffer::putImageData(ImageData* source, const IntRect& sourceRect,
- const IntPoint& destPoint)
+PassRefPtr<ImageData> ImageBuffer::getUnmultipliedImageData(const IntRect& rect) const
+{
+ return getImageData<Unmultiplied>(rect, *context()->platformContext()->bitmap(), m_size);
+}
+
+PassRefPtr<ImageData> ImageBuffer::getPremultipliedImageData(const IntRect& rect) const
+{
+ return getImageData<Premultiplied>(rect, *context()->platformContext()->bitmap(), m_size);
+}
+
+template <Multiply multiplied>
+void putImageData(ImageData*& source, const IntRect& sourceRect, const IntPoint& destPoint,
+ const SkBitmap& bitmap, const IntSize& size)
{
ASSERT(sourceRect.width() > 0);
ASSERT(sourceRect.height() > 0);
@@ -184,27 +204,26 @@ void ImageBuffer::putImageData(ImageData* source, const IntRect& sourceRect,
int originX = sourceRect.x();
int destX = destPoint.x() + sourceRect.x();
ASSERT(destX >= 0);
- ASSERT(destX < m_size.width());
+ ASSERT(destX < size.width());
ASSERT(originX >= 0);
ASSERT(originX < sourceRect.right());
int endX = destPoint.x() + sourceRect.right();
- ASSERT(endX <= m_size.width());
+ ASSERT(endX <= size.width());
int numColumns = endX - destX;
int originY = sourceRect.y();
int destY = destPoint.y() + sourceRect.y();
ASSERT(destY >= 0);
- ASSERT(destY < m_size.height());
+ ASSERT(destY < size.height());
ASSERT(originY >= 0);
ASSERT(originY < sourceRect.bottom());
int endY = destPoint.y() + sourceRect.bottom();
- ASSERT(endY <= m_size.height());
+ ASSERT(endY <= size.height());
int numRows = endY - destY;
- const SkBitmap& bitmap = *context()->platformContext()->bitmap();
ASSERT(bitmap.config() == SkBitmap::kARGB_8888_Config);
SkAutoLockPixels bitmapLock(bitmap);
@@ -216,13 +235,27 @@ void ImageBuffer::putImageData(ImageData* source, const IntRect& sourceRect,
uint32_t* destRow = bitmap.getAddr32(destX, destY + y);
for (int x = 0; x < numColumns; ++x) {
const unsigned char* srcPixel = &srcRow[x * 4];
- destRow[x] = SkPreMultiplyARGB(srcPixel[3], srcPixel[0],
- srcPixel[1], srcPixel[2]);
+ if (multiplied == Unmultiplied)
+ destRow[x] = SkPreMultiplyARGB(srcPixel[3], srcPixel[0],
+ srcPixel[1], srcPixel[2]);
+ else
+ destRow[x] = SkPackARGB32(srcPixel[3], srcPixel[0],
+ srcPixel[1], srcPixel[2]);
}
srcRow += srcBytesPerRow;
}
}
+void ImageBuffer::putUnmultipliedImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint)
+{
+ putImageData<Unmultiplied>(source, sourceRect, destPoint, *context()->platformContext()->bitmap(), m_size);
+}
+
+void ImageBuffer::putPremultipliedImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint)
+{
+ putImageData<Premultiplied>(source, sourceRect, destPoint, *context()->platformContext()->bitmap(), m_size);
+}
+
String ImageBuffer::toDataURL(const String&) const
{
// Encode the image into a vector.
diff --git a/WebCore/platform/graphics/skia/ImageSkia.cpp b/WebCore/platform/graphics/skia/ImageSkia.cpp
index 45c3dcd..ecab364 100644
--- a/WebCore/platform/graphics/skia/ImageSkia.cpp
+++ b/WebCore/platform/graphics/skia/ImageSkia.cpp
@@ -41,6 +41,7 @@
#include "PlatformContextSkia.h"
#include "PlatformString.h"
#include "SkiaUtils.h"
+#include "SkRect.h"
#include "SkShader.h"
#include "TransformationMatrix.h"
@@ -158,8 +159,8 @@ static void drawResampledBitmap(SkCanvas& canvas, SkPaint& paint, const NativeIm
// We will always draw in integer sizes, so round the destination rect.
SkIRect destRectRounded;
destRect.round(&destRectRounded);
- SkIRect resizedImageRect; // Represents the size of the resized image.
- resizedImageRect.set(0, 0, destRectRounded.width(), destRectRounded.height());
+ SkIRect resizedImageRect = // Represents the size of the resized image.
+ { 0, 0, destRectRounded.width(), destRectRounded.height() };
if (srcIsFull && bitmap.hasResizedBitmap(destRectRounded.width(), destRectRounded.height())) {
// Yay, this bitmap frame already has a resized version.
@@ -196,25 +197,19 @@ static void drawResampledBitmap(SkCanvas& canvas, SkPaint& paint, const NativeIm
} else {
// We should only resize the exposed part of the bitmap to do the
// minimal possible work.
- gfx::Rect destBitmapSubset(destBitmapSubsetSkI.fLeft,
- destBitmapSubsetSkI.fTop,
- destBitmapSubsetSkI.width(),
- destBitmapSubsetSkI.height());
// Resample the needed part of the image.
SkBitmap resampled = skia::ImageOperations::Resize(subset,
skia::ImageOperations::RESIZE_LANCZOS3,
destRectRounded.width(), destRectRounded.height(),
- destBitmapSubset);
+ destBitmapSubsetSkI);
// Compute where the new bitmap should be drawn. Since our new bitmap
// may be smaller than the original, we have to shift it over by the
// same amount that we cut off the top and left.
- SkRect offsetDestRect = {
- destBitmapSubset.x() + destRect.fLeft,
- destBitmapSubset.y() + destRect.fTop,
- destBitmapSubset.right() + destRect.fLeft,
- destBitmapSubset.bottom() + destRect.fTop };
+ destBitmapSubsetSkI.offset(destRect.fLeft, destRect.fTop);
+ SkRect offsetDestRect;
+ offsetDestRect.set(destBitmapSubsetSkI);
canvas.drawBitmapRect(resampled, 0, offsetDestRect, &paint);
}
diff --git a/WebCore/platform/graphics/skia/ImageSourceSkia.cpp b/WebCore/platform/graphics/skia/ImageSourceSkia.cpp
deleted file mode 100644
index 1647b86..0000000
--- a/WebCore/platform/graphics/skia/ImageSourceSkia.cpp
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Copyright (c) 2008, Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-#include "config.h"
-#include "ImageSource.h"
-#include "SharedBuffer.h"
-
-#include "GIFImageDecoder.h"
-#include "ICOImageDecoder.h"
-#include "JPEGImageDecoder.h"
-#include "PNGImageDecoder.h"
-#include "BMPImageDecoder.h"
-#include "XBMImageDecoder.h"
-
-#include "SkBitmap.h"
-
-namespace WebCore {
-
-ImageDecoder* createDecoder(const Vector<char>& data)
-{
- // We need at least 4 bytes to figure out what kind of image we're dealing with.
- int length = data.size();
- if (length < 4)
- return 0;
-
- const unsigned char* uContents = (const unsigned char*)data.data();
- const char* contents = data.data();
-
- // GIFs begin with GIF8(7 or 9).
- if (strncmp(contents, "GIF8", 4) == 0)
- return new GIFImageDecoder();
-
- // Test for PNG.
- if (uContents[0]==0x89 &&
- uContents[1]==0x50 &&
- uContents[2]==0x4E &&
- uContents[3]==0x47)
- return new PNGImageDecoder();
-
- // JPEG
- if (uContents[0]==0xFF &&
- uContents[1]==0xD8 &&
- uContents[2]==0xFF)
- return new JPEGImageDecoder();
-
- // BMP
- if (strncmp(contents, "BM", 2) == 0)
- return new BMPImageDecoder();
-
- // ICOs always begin with a 2-byte 0 followed by a 2-byte 1.
- // CURs begin with 2-byte 0 followed by 2-byte 2.
- if (!memcmp(contents, "\000\000\001\000", 4) ||
- !memcmp(contents, "\000\000\002\000", 4))
- return new ICOImageDecoder();
-
- // XBMs require 8 bytes of info.
- if (length >= 8 && strncmp(contents, "#define ", 8) == 0)
- return new XBMImageDecoder();
-
- // Give up. We don't know what the heck this is.
- return 0;
-}
-
-ImageSource::ImageSource()
- : m_decoder(0)
-{}
-
-ImageSource::~ImageSource()
-{
- clear(true);
-}
-
-void ImageSource::clear(bool destroyAll, size_t clearBeforeFrame, SharedBuffer* data, bool allDataReceived)
-{
- if (!destroyAll) {
- if (m_decoder)
- m_decoder->clearFrameBufferCache(clearBeforeFrame);
- return;
- }
-
- delete m_decoder;
- m_decoder = 0;
- if (data)
- setData(data, allDataReceived);
-}
-
-bool ImageSource::initialized() const
-{
- return m_decoder;
-}
-
-void ImageSource::setData(SharedBuffer* data, bool allDataReceived)
-{
- // Make the decoder by sniffing the bytes.
- // This method will examine the data and instantiate an instance of the appropriate decoder plugin.
- // If insufficient bytes are available to determine the image type, no decoder plugin will be
- // made.
- if (!m_decoder)
- m_decoder = createDecoder(data->buffer());
-
- // CreateDecoder will return NULL if the decoder could not be created. Plus,
- // we should not send more data to a decoder which has already decided it
- // has failed.
- if (!m_decoder || m_decoder->failed())
- return;
- m_decoder->setData(data, allDataReceived);
-}
-
-bool ImageSource::isSizeAvailable()
-{
- if (!m_decoder)
- return false;
-
- return m_decoder->isSizeAvailable();
-}
-
-IntSize ImageSource::size() const
-{
- if (!m_decoder)
- return IntSize();
-
- return m_decoder->size();
-}
-
-IntSize ImageSource::frameSizeAtIndex(size_t index) const
-{
- if (!m_decoder)
- return IntSize();
-
- return m_decoder->frameSizeAtIndex(index);
-}
-
-int ImageSource::repetitionCount()
-{
- if (!m_decoder)
- return cAnimationNone;
-
- return m_decoder->repetitionCount();
-}
-
-size_t ImageSource::frameCount() const
-{
- if (!m_decoder)
- return 0;
- return m_decoder->failed() ? 0 : m_decoder->frameCount();
-}
-
-NativeImagePtr ImageSource::createFrameAtIndex(size_t index)
-{
- if (!m_decoder)
- return 0;
-
- // Note that the buffer can have NULL bytes even when it is marked as
- // non-empty. It seems "FrameEmpty" is only set before the frame has been
- // initialized. If it is decoded and it happens to be empty, it will be
- // marked as "FrameComplete" but will still have NULL bytes.
- RGBA32Buffer* buffer = m_decoder->frameBufferAtIndex(index);
- if (!buffer || buffer->status() == RGBA32Buffer::FrameEmpty)
- return 0;
-
- // Copy the bitmap. The pixel data is refcounted internally by SkBitmap, so
- // this doesn't cost much.
- return buffer->asNewNativeImage();
-}
-
-bool ImageSource::frameIsCompleteAtIndex(size_t index)
-{
- if (!m_decoder)
- return false;
-
- RGBA32Buffer* buffer = m_decoder->frameBufferAtIndex(index);
- return buffer && buffer->status() == RGBA32Buffer::FrameComplete;
-}
-
-float ImageSource::frameDurationAtIndex(size_t index)
-{
- if (!m_decoder)
- return 0;
-
- RGBA32Buffer* buffer = m_decoder->frameBufferAtIndex(index);
- if (!buffer || buffer->status() == RGBA32Buffer::FrameEmpty)
- return 0;
-
- // Many annoying ads specify a 0 duration to make an image flash as quickly
- // as possible. We follow WinIE's behavior and use a duration of 100 ms
- // for any frames that specify a duration of <= 50 ms. See
- // <http://bugs.webkit.org/show_bug.cgi?id=14413> or Radar 4051389 for
- // more.
- const float duration = buffer->duration() / 1000.0f;
- return (duration < 0.051f) ? 0.100f : duration;
-}
-
-bool ImageSource::frameHasAlphaAtIndex(size_t index)
-{
- if (!m_decoder || !m_decoder->supportsAlpha())
- return false;
-
- RGBA32Buffer* buffer = m_decoder->frameBufferAtIndex(index);
- if (!buffer || buffer->status() == RGBA32Buffer::FrameEmpty)
- return false;
-
- return buffer->hasAlpha();
-}
-
-String ImageSource::filenameExtension() const
-{
- return m_decoder ? m_decoder->filenameExtension() : String();
-}
-
-}
diff --git a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
index e0a292c..1fb62fc 100644
--- a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
+++ b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
@@ -46,6 +46,11 @@
#include <wtf/MathExtras.h>
+namespace WebCore
+{
+extern bool isPathSkiaSafe(const SkMatrix& transform, const SkPath& path);
+}
+
// State -----------------------------------------------------------------------
// Encapsulates the additional painting state information we store for each
@@ -278,6 +283,7 @@ void PlatformContextSkia::drawRect(SkRect rect)
SkShader* oldFillShader = m_state->m_fillShader;
oldFillShader->safeRef();
setFillColor(m_state->m_strokeColor);
+ paint.reset();
setupPaintForFilling(&paint);
SkRect topBorder = { rect.fLeft, rect.fTop, rect.fRight, rect.fTop + 1 };
canvas()->drawRect(topBorder, paint);
@@ -295,7 +301,7 @@ void PlatformContextSkia::drawRect(SkRect rect)
void PlatformContextSkia::setupPaintCommon(SkPaint* paint) const
{
-#ifdef SK_DEBUGx
+#if defined(SK_DEBUG)
{
SkPaint defaultPaint;
SkASSERT(*paint == defaultPaint);
diff --git a/WebCore/platform/graphics/win/FontCGWin.cpp b/WebCore/platform/graphics/win/FontCGWin.cpp
index 803f5db..e2ed130 100644
--- a/WebCore/platform/graphics/win/FontCGWin.cpp
+++ b/WebCore/platform/graphics/win/FontCGWin.cpp
@@ -297,6 +297,30 @@ void Font::drawGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* fo
CGContextRef cgContext = graphicsContext->platformContext();
bool shouldUseFontSmoothing = WebCoreShouldUseFontSmoothing();
+ switch(fontDescription().fontSmoothing()) {
+ case Antialiased: {
+ graphicsContext->setShouldAntialias(true);
+ shouldUseFontSmoothing = false;
+ break;
+ }
+ case SubpixelAntialiased: {
+ graphicsContext->setShouldAntialias(true);
+ shouldUseFontSmoothing = true;
+ break;
+ }
+ case NoSmoothing: {
+ graphicsContext->setShouldAntialias(false);
+ shouldUseFontSmoothing = false;
+ break;
+ }
+ case AutoSmoothing: {
+ // For the AutoSmooth case, don't do anything! Keep the default settings.
+ break;
+ }
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
if (font->platformData().useGDI()) {
if (!shouldUseFontSmoothing || (graphicsContext->textDrawingMode() & cTextStroke)) {
drawGDIGlyphs(graphicsContext, font, glyphBuffer, from, numGlyphs, point);
diff --git a/WebCore/platform/graphics/win/FontCacheWin.cpp b/WebCore/platform/graphics/win/FontCacheWin.cpp
index 887bf79..8663623 100644
--- a/WebCore/platform/graphics/win/FontCacheWin.cpp
+++ b/WebCore/platform/graphics/win/FontCacheWin.cpp
@@ -33,8 +33,9 @@
#include "SimpleFontData.h"
#include "StringHash.h"
#include "UnicodeRange.h"
-#include <windows.h>
#include <mlang.h>
+#include <windows.h>
+#include <wtf/StdLibExtras.h>
#if PLATFORM(CG)
#include <ApplicationServices/ApplicationServices.h>
#include <WebKitSystemInterface/WebKitSystemInterface.h>
@@ -305,7 +306,17 @@ FontPlatformData* FontCache::getLastResortFallbackFont(const FontDescription& fo
// FIXME: Would be even better to somehow get the user's default font here. For now we'll pick
// the default that the user would get without changing any prefs.
static AtomicString timesStr("Times New Roman");
- return getCachedFontPlatformData(fontDescription, timesStr);
+ if (FontPlatformData* platformFont = getCachedFontPlatformData(fontDescription, timesStr))
+ return platformFont;
+
+ DEFINE_STATIC_LOCAL(String, defaultGUIFontFamily, ());
+ if (defaultGUIFontFamily.isEmpty()) {
+ HFONT defaultGUIFont = static_cast<HFONT>(GetStockObject(DEFAULT_GUI_FONT));
+ LOGFONT logFont;
+ GetObject(defaultGUIFont, sizeof(logFont), &logFont);
+ defaultGUIFontFamily = String(logFont.lfFaceName, wcsnlen(logFont.lfFaceName, LF_FACESIZE));
+ }
+ return getCachedFontPlatformData(fontDescription, defaultGUIFontFamily);
}
static LONG toGDIFontWeight(FontWeight fontWeight)
diff --git a/WebCore/platform/graphics/win/FontDatabase.cpp b/WebCore/platform/graphics/win/FontDatabase.cpp
index 1308ff0..d0773ea 100644
--- a/WebCore/platform/graphics/win/FontDatabase.cpp
+++ b/WebCore/platform/graphics/win/FontDatabase.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 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
@@ -99,17 +99,12 @@ static RetainPtr<CFPropertyListRef> readFontPlist()
return plist;
}
-static bool populateFontDatabaseFromPlist()
+static bool populateFontDatabaseFromPlist(CFPropertyListRef plist)
{
- RetainPtr<CFPropertyListRef> plist = readFontPlist();
if (!plist)
return false;
- RetainPtr<CFDataRef> data(AdoptCF, CFPropertyListCreateXMLData(0, plist.get()));
- if (!data)
- return false;
-
- wkAddFontsFromPlistRepresentation(data.get());
+ wkAddFontsFromPlist(plist);
return true;
}
@@ -123,15 +118,69 @@ static bool populateFontDatabaseFromFileSystem()
return true;
}
-static void writeFontDatabaseToPlist()
+static CFStringRef fontFilenamesFromRegistryKey()
+{
+ static CFStringRef key = CFSTR("WebKitFontFilenamesFromRegistry");
+ return key;
+}
+
+static void writeFontDatabaseToPlist(CFPropertyListRef cgFontDBPropertyList, CFPropertyListRef filenamesFromRegistry)
{
- RetainPtr<CFDataRef> data(AdoptCF, wkCreateFontsPlistRepresentation());
+ if (!cgFontDBPropertyList)
+ return;
+
+ RetainPtr<CFDataRef> data;
+
+ if (!filenamesFromRegistry || CFGetTypeID(cgFontDBPropertyList) != CFDictionaryGetTypeID())
+ data.adoptCF(CFPropertyListCreateXMLData(kCFAllocatorDefault, cgFontDBPropertyList));
+ else {
+ RetainPtr<CFMutableDictionaryRef> dictionary(AdoptCF, CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 2, static_cast<CFDictionaryRef>(cgFontDBPropertyList)));
+ CFDictionarySetValue(dictionary.get(), fontFilenamesFromRegistryKey(), filenamesFromRegistry);
+ data.adoptCF(CFPropertyListCreateXMLData(kCFAllocatorDefault, dictionary.get()));
+ }
+
if (!data)
return;
safeCreateFile(fontsPlistPath(), data.get());
}
+static RetainPtr<CFArrayRef> fontFilenamesFromRegistry()
+{
+ RetainPtr<CFMutableArrayRef> filenames(AdoptCF, CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks));
+
+ HKEY key;
+ if (FAILED(RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"), 0, KEY_READ, &key)))
+ return filenames;
+
+ DWORD valueCount;
+ DWORD maxNameLength;
+ DWORD maxValueLength;
+ if (FAILED(RegQueryInfoKey(key, 0, 0, 0, 0, 0, 0, &valueCount, &maxNameLength, &maxValueLength, 0, 0))) {
+ RegCloseKey(key);
+ return filenames;
+ }
+
+ Vector<TCHAR> name(maxNameLength + 1);
+ Vector<BYTE> value(maxValueLength + 1);
+
+ for (size_t i = 0; i < valueCount; ++i) {
+ DWORD nameLength = name.size();
+ DWORD valueLength = value.size();
+ DWORD type;
+ if (FAILED(RegEnumValue(key, i, name.data(), &nameLength, 0, &type, value.data(), &valueLength)))
+ continue;
+ if (type != REG_SZ)
+ continue;
+
+ RetainPtr<CFDataRef> filename(AdoptCF, CFDataCreate(kCFAllocatorDefault, value.data(), valueLength));
+ CFArrayAppendValue(filenames.get(), filename.get());
+ }
+
+ RegCloseKey(key);
+ return filenames;
+}
+
void populateFontDatabase()
{
static bool initialized;
@@ -139,12 +188,27 @@ void populateFontDatabase()
return;
initialized = true;
- if (!systemHasFontsNewerThanFontsPlist())
- if (populateFontDatabaseFromPlist())
+ RetainPtr<CFPropertyListRef> propertyList = readFontPlist();
+ RetainPtr<CFArrayRef> lastFilenamesFromRegistry;
+ if (propertyList && CFGetTypeID(propertyList.get()) == CFDictionaryGetTypeID()) {
+ CFDictionaryRef dictionary = static_cast<CFDictionaryRef>(propertyList.get());
+ CFArrayRef array = static_cast<CFArrayRef>(CFDictionaryGetValue(dictionary, fontFilenamesFromRegistryKey()));
+ if (array && CFGetTypeID(array) == CFArrayGetTypeID())
+ lastFilenamesFromRegistry = array;
+ }
+ RetainPtr<CFArrayRef> currentFilenamesFromRegistry = fontFilenamesFromRegistry();
+ bool registryChanged = !lastFilenamesFromRegistry || !CFEqual(lastFilenamesFromRegistry.get(), currentFilenamesFromRegistry.get());
+
+ if (!registryChanged && !systemHasFontsNewerThanFontsPlist()) {
+ if (populateFontDatabaseFromPlist(propertyList.get()))
return;
+ }
- if (populateFontDatabaseFromFileSystem())
- writeFontDatabaseToPlist();
+ if (populateFontDatabaseFromFileSystem()) {
+ wkAddFontsFromRegistry();
+ RetainPtr<CFPropertyListRef> cgFontDBPropertyList(AdoptCF, wkCreateFontsPlist());
+ writeFontDatabaseToPlist(cgFontDBPropertyList.get(), currentFilenamesFromRegistry.get());
+ }
}
} // namespace WebCore
diff --git a/WebCore/platform/graphics/win/FontPlatformData.h b/WebCore/platform/graphics/win/FontPlatformData.h
index 0660d90..5084469 100644
--- a/WebCore/platform/graphics/win/FontPlatformData.h
+++ b/WebCore/platform/graphics/win/FontPlatformData.h
@@ -78,7 +78,6 @@ public:
#if PLATFORM(CG)
CGFontRef cgFont() const { return m_cgFont.get(); }
#elif PLATFORM(CAIRO)
- void setFont(cairo_t* ft) const;
cairo_font_face_t* fontFace() const { return m_fontFace; }
cairo_scaled_font_t* scaledFont() const { return m_scaledFont; }
#endif
diff --git a/WebCore/platform/graphics/win/FontPlatformDataCairoWin.cpp b/WebCore/platform/graphics/win/FontPlatformDataCairoWin.cpp
index b56a71c..9fce68a 100644
--- a/WebCore/platform/graphics/win/FontPlatformDataCairoWin.cpp
+++ b/WebCore/platform/graphics/win/FontPlatformDataCairoWin.cpp
@@ -96,12 +96,6 @@ FontPlatformData::FontPlatformData(const FontPlatformData& source)
m_scaledFont = cairo_scaled_font_reference(source.m_scaledFont);
}
-void FontPlatformData::setFont(cairo_t* cr) const
-{
- ASSERT(m_scaledFont);
-
- cairo_set_scaled_font(cr, m_scaledFont);
-}
FontPlatformData::~FontPlatformData()
{
diff --git a/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp b/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp
index 9eaf54b..1923ecc 100644
--- a/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp
+++ b/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp
@@ -65,7 +65,7 @@ GraphicsContext::GraphicsContext(HDC hdc, bool hasAlpha)
: m_common(createGraphicsContextPrivate())
, m_data(new GraphicsContextPlatformPrivate(CGContextWithHDC(hdc, hasAlpha)))
{
- CGContextRelease(m_data->m_cgContext);
+ CGContextRelease(m_data->m_cgContext.get());
m_data->m_hdc = hdc;
setPaintingDisabled(!m_data->m_cgContext);
if (m_data->m_cgContext) {
@@ -98,7 +98,7 @@ void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect& dstRect, boo
CGColorSpaceRelease(deviceRGB);
CGImageRef image = CGBitmapContextCreateImage(bitmapContext);
- CGContextDrawImage(m_data->m_cgContext, dstRect, image);
+ CGContextDrawImage(m_data->m_cgContext.get(), dstRect, image);
// Delete all our junk.
CGImageRelease(image);
@@ -121,7 +121,7 @@ void GraphicsContext::drawWindowsBitmap(WindowsBitmap* image, const IntPoint& po
RetainPtr<CGDataProviderRef> dataProvider(AdoptCF, CGDataProviderCreateWithCFData(imageData.get()));
RetainPtr<CGImageRef> cgImage(AdoptCF, CGImageCreate(image->size().width(), image->size().height(), 8, 32, image->bytesPerRow(), deviceRGB.get(),
kCGBitmapByteOrder32Little | kCGImageAlphaFirst, dataProvider.get(), 0, true, kCGRenderingIntentDefault));
- CGContextDrawImage(m_data->m_cgContext, CGRectMake(point.x(), point.y(), image->size().width(), image->size().height()), cgImage.get());
+ CGContextDrawImage(m_data->m_cgContext.get(), CGRectMake(point.x(), point.y(), image->size().width(), image->size().height()), cgImage.get());
}
void GraphicsContext::drawFocusRing(const Color& color)
@@ -243,7 +243,7 @@ void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint& point,
void GraphicsContextPlatformPrivate::flush()
{
- CGContextFlush(m_cgContext);
+ CGContextFlush(m_cgContext.get());
}
}
diff --git a/WebCore/platform/graphics/win/ImageCGWin.cpp b/WebCore/platform/graphics/win/ImageCGWin.cpp
index 8a8e943..285fb71 100644
--- a/WebCore/platform/graphics/win/ImageCGWin.cpp
+++ b/WebCore/platform/graphics/win/ImageCGWin.cpp
@@ -26,6 +26,7 @@
#include "config.h"
#include "Image.h"
#include "BitmapImage.h"
+#include "BitmapInfo.h"
#include "GraphicsContext.h"
#include <ApplicationServices/ApplicationServices.h>
@@ -34,6 +35,30 @@
namespace WebCore {
+PassRefPtr<BitmapImage> BitmapImage::create(HBITMAP hBitmap)
+{
+ DIBSECTION dibSection;
+ if (!GetObject(hBitmap, sizeof(DIBSECTION), &dibSection))
+ return 0;
+
+ ASSERT(dibSection.dsBm.bmBitsPixel == 32);
+ if (dibSection.dsBm.bmBitsPixel != 32)
+ return 0;
+
+ ASSERT(dibSection.dsBm.bmBits);
+ if (!dibSection.dsBm.bmBits)
+ return 0;
+
+ RetainPtr<CGColorSpaceRef> deviceRGB(AdoptCF, CGColorSpaceCreateDeviceRGB());
+ RetainPtr<CGContextRef> bitmapContext(AdoptCF, CGBitmapContextCreate(dibSection.dsBm.bmBits, dibSection.dsBm.bmWidth, dibSection.dsBm.bmHeight, 8,
+ dibSection.dsBm.bmWidthBytes, deviceRGB.get(), kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst));
+
+ // The BitmapImage takes ownership of this.
+ CGImageRef cgImage = CGBitmapContextCreateImage(bitmapContext.get());
+
+ return adoptRef(new BitmapImage(cgImage));
+}
+
bool BitmapImage::getHBITMAPOfSize(HBITMAP bmp, LPSIZE size)
{
ASSERT(bmp);
diff --git a/WebCore/platform/graphics/win/ImageCairoWin.cpp b/WebCore/platform/graphics/win/ImageCairoWin.cpp
index 591375f..0b27438 100644
--- a/WebCore/platform/graphics/win/ImageCairoWin.cpp
+++ b/WebCore/platform/graphics/win/ImageCairoWin.cpp
@@ -28,12 +28,33 @@
#include "BitmapImage.h"
#include "GraphicsContext.h"
#include <cairo.h>
+#include <cairo-win32.h>
#include <windows.h>
#include "PlatformString.h"
namespace WebCore {
+PassRefPtr<BitmapImage> BitmapImage::create(HBITMAP hBitmap)
+{
+ DIBSECTION dibSection;
+ if (!GetObject(hBitmap, sizeof(DIBSECTION), &dibSection))
+ return 0;
+
+ ASSERT(dibSection.dsBm.bmBitsPixel == 32);
+ if (dibSection.dsBm.bmBitsPixel != 32)
+ return 0;
+
+ ASSERT(dibSection.dsBm.bmBits);
+ if (!dibSection.dsBm.bmBits)
+ return 0;
+
+ cairo_surface_t* image = cairo_win32_surface_create_with_dib (CAIRO_FORMAT_ARGB32, dibSection.dsBm.bmWidth, dibSection.dsBm.bmHeight);
+
+ // The BitmapImage object takes over ownership of the cairo_surface_t*, so no need to destroy here.
+ return adoptRef(new BitmapImage(image));
+}
+
bool BitmapImage::getHBITMAPOfSize(HBITMAP bmp, LPSIZE size)
{
ASSERT(bmp);
diff --git a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp
index eb7334e..15e1001 100644
--- a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp
+++ b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp
@@ -33,6 +33,8 @@
#include "QTMovieWin.h"
#include "ScrollView.h"
#include "StringHash.h"
+#include "TimeRanges.h"
+#include "Timer.h"
#include <wtf/HashSet.h>
#include <wtf/MathExtras.h>
#include <wtf/StdLibExtras.h>
@@ -86,6 +88,50 @@ MediaPlayerPrivate::~MediaPlayerPrivate()
{
}
+class TaskTimer : TimerBase {
+public:
+ static void initialize();
+
+private:
+ static void setTaskTimerDelay(double);
+ static void stopTaskTimer();
+
+ void fired();
+
+ static TaskTimer* s_timer;
+};
+
+TaskTimer* TaskTimer::s_timer = 0;
+
+void TaskTimer::initialize()
+{
+ if (s_timer)
+ return;
+
+ s_timer = new TaskTimer;
+
+ QTMovieWin::setTaskTimerFuncs(setTaskTimerDelay, stopTaskTimer);
+}
+
+void TaskTimer::setTaskTimerDelay(double delayInSeconds)
+{
+ ASSERT(s_timer);
+
+ s_timer->startOneShot(delayInSeconds);
+}
+
+void TaskTimer::stopTaskTimer()
+{
+ ASSERT(s_timer);
+
+ s_timer->stop();
+}
+
+void TaskTimer::fired()
+{
+ QTMovieWin::taskTimerFired();
+}
+
void MediaPlayerPrivate::load(const String& url)
{
if (!QTMovieWin::initializeQuickTime()) {
@@ -95,6 +141,9 @@ void MediaPlayerPrivate::load(const String& url)
return;
}
+ // Initialize the task timer.
+ TaskTimer::initialize();
+
if (m_networkState != MediaPlayer::Loading) {
m_networkState = MediaPlayer::Loading;
m_player->networkStateChanged();
@@ -241,6 +290,13 @@ bool MediaPlayerPrivate::hasVideo() const
return m_qtMovie->hasVideo();
}
+bool MediaPlayerPrivate::hasAudio() const
+{
+ if (!m_qtMovie)
+ return false;
+ return m_qtMovie->hasAudio();
+}
+
void MediaPlayerPrivate::setVolume(float volume)
{
if (!m_qtMovie)
@@ -268,10 +324,14 @@ int MediaPlayerPrivate::dataRate() const
return 0;
}
-float MediaPlayerPrivate::maxTimeBuffered() const
+PassRefPtr<TimeRanges> MediaPlayerPrivate::buffered() const
{
+ RefPtr<TimeRanges> timeRanges = TimeRanges::create();
+ float loaded = maxTimeLoaded();
// rtsp streams are not buffered
- return m_isStreaming ? 0 : maxTimeLoaded();
+ if (!m_isStreaming && loaded > 0)
+ timeRanges->add(0, loaded);
+ return timeRanges.release();
}
float MediaPlayerPrivate::maxTimeSeekable() const
@@ -575,4 +635,3 @@ bool MediaPlayerPrivate::hasSingleSecurityOrigin() const
}
#endif
-
diff --git a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h
index f584148..4a3a28e 100644
--- a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h
+++ b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h
@@ -52,7 +52,8 @@ public:
IntSize naturalSize() const;
bool hasVideo() const;
-
+ bool hasAudio() const;
+
void load(const String& url);
void cancelLoad();
@@ -76,7 +77,7 @@ public:
MediaPlayer::NetworkState networkState() const { return m_networkState; }
MediaPlayer::ReadyState readyState() const { return m_readyState; }
- float maxTimeBuffered() const;
+ PassRefPtr<TimeRanges> buffered() const;
float maxTimeSeekable() const;
unsigned bytesLoaded() const;
bool totalBytesKnown() const;
diff --git a/WebCore/platform/graphics/win/QTMovieWin.cpp b/WebCore/platform/graphics/win/QTMovieWin.cpp
index aaa61f1..56f3d0b 100644
--- a/WebCore/platform/graphics/win/QTMovieWin.cpp
+++ b/WebCore/platform/graphics/win/QTMovieWin.cpp
@@ -62,10 +62,13 @@ static HashSet<QTMovieWinPrivate*>* gTaskList;
static Vector<CFStringRef>* gSupportedTypes = 0;
static SInt32 quickTimeVersion = 0;
+static QTMovieWin::SetTaskTimerDelayFunc gSetTaskTimerDelay = 0;
+static QTMovieWin::StopTaskTimerFunc gStopTaskTimer = 0;
+
static void updateTaskTimer(int maxInterval = 1000)
{
if (!gTaskList->size()) {
- stopSharedTimer();
+ gStopTaskTimer();
return;
}
@@ -73,7 +76,7 @@ static void updateTaskTimer(int maxInterval = 1000)
QTGetTimeUntilNextTask(&intervalInMS, 1000);
if (intervalInMS > maxInterval)
intervalInMS = maxInterval;
- setSharedTimerFireDelay(static_cast<float>(intervalInMS) / 1000);
+ gSetTaskTimerDelay(static_cast<float>(intervalInMS) / 1000);
}
class QTMovieWinPrivate : public Noncopyable {
@@ -166,7 +169,7 @@ QTMovieWinPrivate::~QTMovieWinPrivate()
CFRelease(m_currentURL);
}
-static void taskTimerFired()
+void QTMovieWin::taskTimerFired()
{
// The hash content might change during task()
Vector<QTMovieWinPrivate*> tasks;
@@ -867,6 +870,13 @@ bool QTMovieWin::hasVideo() const
return (GetMovieIndTrackType(m_private->m_movie, 1, VisualMediaCharacteristic, movieTrackCharacteristic | movieTrackEnabledOnly));
}
+bool QTMovieWin::hasAudio() const
+{
+ if (!m_private->m_movie)
+ return false;
+ return (GetMovieIndTrackType(m_private->m_movie, 1, AudioMediaCharacteristic, movieTrackCharacteristic | movieTrackEnabledOnly));
+}
+
pascal OSErr movieDrawingCompleteProc(Movie movie, long data)
{
UppParam param;
@@ -990,6 +1000,12 @@ void QTMovieWin::getSupportedType(unsigned index, const UChar*& str, unsigned& l
}
+void QTMovieWin::setTaskTimerFuncs(SetTaskTimerDelayFunc setTaskTimerDelay, StopTaskTimerFunc stopTaskTimer)
+{
+ gSetTaskTimerDelay = setTaskTimerDelay;
+ gStopTaskTimer = stopTaskTimer;
+}
+
bool QTMovieWin::initializeQuickTime()
{
static bool initialized = false;
@@ -1009,7 +1025,6 @@ bool QTMovieWin::initializeQuickTime()
return false;
}
EnterMovies();
- setSharedTimerFiredFunction(taskTimerFired);
gMovieDrawingCompleteUPP = NewMovieDrawingCompleteUPP(movieDrawingCompleteProc);
initializationSucceeded = true;
}
@@ -1020,7 +1035,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
- setSharedTimerInstanceHandle(hinstDLL);
return TRUE;
case DLL_PROCESS_DETACH:
case DLL_THREAD_ATTACH:
diff --git a/WebCore/platform/graphics/win/QTMovieWin.h b/WebCore/platform/graphics/win/QTMovieWin.h
index f46efd3..d178eb8 100644
--- a/WebCore/platform/graphics/win/QTMovieWin.h
+++ b/WebCore/platform/graphics/win/QTMovieWin.h
@@ -59,6 +59,11 @@ class QTMOVIEWIN_API QTMovieWin {
public:
static bool initializeQuickTime();
+ typedef void (*SetTaskTimerDelayFunc)(double);
+ typedef void (*StopTaskTimerFunc)();
+ static void setTaskTimerFuncs(SetTaskTimerDelayFunc, StopTaskTimerFunc);
+ static void taskTimerFired();
+
QTMovieWin(QTMovieWinClient*);
~QTMovieWin();
@@ -91,6 +96,7 @@ public:
void setDisabled(bool);
bool hasVideo() const;
+ bool hasAudio() const;
static unsigned countSupportedTypes();
static void getSupportedType(unsigned index, const UChar*& str, unsigned& len);
diff --git a/WebCore/platform/graphics/win/SimpleFontDataCairoWin.cpp b/WebCore/platform/graphics/win/SimpleFontDataCairoWin.cpp
index 0343007..26b22af 100644
--- a/WebCore/platform/graphics/win/SimpleFontDataCairoWin.cpp
+++ b/WebCore/platform/graphics/win/SimpleFontDataCairoWin.cpp
@@ -119,10 +119,4 @@ float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
return width * metricsMultiplier;
}
-void SimpleFontData::setFont(cairo_t* cr) const
-{
- ASSERT(cr);
- m_platformData.setFont(cr);
-}
-
}
diff --git a/WebCore/platform/graphics/wince/ColorWince.cpp b/WebCore/platform/graphics/wince/ColorWince.cpp
new file mode 100644
index 0000000..820b9d2
--- /dev/null
+++ b/WebCore/platform/graphics/wince/ColorWince.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2007-2008 Torch Mobile, Inc.
+ *
+ * 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 "Color.h"
+
+#include "NotImplemented.h"
+
+namespace WebCore {
+
+Color focusRingColor()
+{
+ return Color(0, 0, 0);
+}
+
+void setFocusRingColorChangeFunction(void (*)())
+{
+ notImplemented();
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/graphics/wince/FontCustomPlatformData.cpp b/WebCore/platform/graphics/wince/FontCustomPlatformData.cpp
index 7c6853c..699ff25 100644
--- a/WebCore/platform/graphics/wince/FontCustomPlatformData.cpp
+++ b/WebCore/platform/graphics/wince/FontCustomPlatformData.cpp
@@ -33,6 +33,11 @@ static CustomFontCache* g_customFontCache = 0;
bool renameFont(SharedBuffer* fontData, const String& fontName);
+void setCustomFontCache(CustomFontCache* cache)
+{
+ g_customFontCache = cache;
+}
+
FontCustomPlatformData::~FontCustomPlatformData()
{
if (g_customFontCache && !m_name.isEmpty())
@@ -66,11 +71,12 @@ static String createUniqueFontName()
return fontName.replace('/', '_');
}
-FontCustomPlatformData* createFontCustomPlatformData(CachedFont* cachedFont)
+FontCustomPlatformData* createFontCustomPlatformData(const SharedBuffer* buffer)
{
- if (g_customFontCache && cachedFont->CachedResource::data()) {
+ if (g_customFontCache) {
String fontName = createUniqueFontName();
- if (renameFont(cachedFont->CachedResource::data(), fontName) && g_customFontCache->registerFont(fontName, cachedFont))
+ RefPtr<SharedBuffer> localBuffer = SharedBuffer::create(buffer->data(), buffer->size());
+ if (renameFont(localBuffer.get(), fontName) && g_customFontCache->registerFont(fontName, localBuffer.get()))
return new FontCustomPlatformData(fontName);
}
return 0;
diff --git a/WebCore/platform/graphics/wince/FontCustomPlatformData.h b/WebCore/platform/graphics/wince/FontCustomPlatformData.h
index b1f64a0..89d1fdd 100644
--- a/WebCore/platform/graphics/wince/FontCustomPlatformData.h
+++ b/WebCore/platform/graphics/wince/FontCustomPlatformData.h
@@ -32,7 +32,7 @@ namespace WebCore {
class CustomFontCache {
public:
- virtual bool registerFont(const String& fontName, CachedFont*) = 0;
+ virtual bool registerFont(const String& fontName, const SharedBuffer*) = 0;
virtual void unregisterFont(const String& fontName) = 0;
};
@@ -48,8 +48,8 @@ namespace WebCore {
String m_name;
};
- FontCustomPlatformData* createFontCustomPlatformData(CachedFont*);
-
+ FontCustomPlatformData* createFontCustomPlatformData(const SharedBuffer*);
+ void setCustomFontCache(CustomFontCache*);
}
#endif
diff --git a/WebCore/platform/graphics/wince/GradientWince.cpp b/WebCore/platform/graphics/wince/GradientWince.cpp
new file mode 100644
index 0000000..49fa970
--- /dev/null
+++ b/WebCore/platform/graphics/wince/GradientWince.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2009 Torch Mobile, 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.
+ */
+
+
+#include "config.h"
+#include "Gradient.h"
+
+#include "GraphicsContext.h"
+
+namespace WebCore {
+
+void Gradient::platformDestroy()
+{
+}
+
+static inline bool compareStops(const Gradient::ColorStop& a, const Gradient::ColorStop& b)
+{
+ return a.stop < b.stop;
+}
+
+const Vector<Gradient::ColorStop>& Gradient::getStops() const
+{
+ if (!m_stopsSorted) {
+ if (m_stops.size())
+ std::stable_sort(m_stops.begin(), m_stops.end(), compareStops);
+ m_stopsSorted = true;
+ }
+ return m_stops;
+}
+
+void Gradient::fill(GraphicsContext* c, const FloatRect& r)
+{
+ c->fillRect(r, this);
+}
+
+}
diff --git a/WebCore/platform/graphics/wince/ImageBufferData.h b/WebCore/platform/graphics/wince/ImageBufferData.h
new file mode 100644
index 0000000..01b7d06
--- /dev/null
+++ b/WebCore/platform/graphics/wince/ImageBufferData.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2009 Torch Mobile, 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 ImageBufferData_h
+#define ImageBufferData_h
+
+namespace WebCore {
+
+ class IntSize;
+ class ImageBufferData {
+ public:
+ ImageBufferData(const IntSize& size);
+ RefPtr<SharedBitmap> m_bitmap;
+ };
+
+} // namespace WebCore
+
+#endif // ImageBufferData_h
diff --git a/WebCore/platform/graphics/wince/ImageBufferWince.cpp b/WebCore/platform/graphics/wince/ImageBufferWince.cpp
new file mode 100644
index 0000000..3417f5f
--- /dev/null
+++ b/WebCore/platform/graphics/wince/ImageBufferWince.cpp
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2009 Torch Mobile, 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.
+ */
+
+#include "config.h"
+#include "ImageBuffer.h"
+
+#include "Base64.h"
+#include "GraphicsContext.h"
+#include "Image.h"
+#include "ImageData.h"
+#include "JPEGEncoder.h"
+#include "PNGEncoder.h"
+#include "SharedBitmap.h"
+
+namespace WebCore {
+
+class BufferedImage: public Image {
+
+public:
+ BufferedImage(const ImageBufferData* data)
+ : m_data(data)
+ {
+ }
+
+ virtual IntSize size() const { return IntSize(m_data->m_bitmap->width(), m_data->m_bitmap->height()); }
+ virtual void destroyDecodedData(bool destroyAll = true) {}
+ virtual unsigned decodedSize() const { return 0; }
+ virtual void draw(GraphicsContext*, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator);
+ virtual void drawPattern(GraphicsContext*, const FloatRect& srcRect, const TransformationMatrix& patternTransform,
+ const FloatPoint& phase, CompositeOperator, const FloatRect& destRect);
+
+ const ImageBufferData* m_data;
+};
+
+void BufferedImage::draw(GraphicsContext* ctxt, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator compositeOp)
+{
+ IntRect intDstRect = enclosingIntRect(dstRect);
+ IntRect intSrcRect(srcRect);
+ m_data->m_bitmap->draw(ctxt, intDstRect, intSrcRect, compositeOp);
+}
+
+void BufferedImage::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRectIn, const TransformationMatrix& patternTransform,
+ const FloatPoint& phase, CompositeOperator op, const FloatRect& destRect)
+{
+ m_data->m_bitmap->drawPattern(ctxt, tileRectIn, patternTransform, phase, op, destRect, size());
+}
+
+ImageBufferData::ImageBufferData(const IntSize& size)
+: m_bitmap(SharedBitmap::createInstance(false, size.width(), size.height(), false))
+{
+ // http://www.w3.org/TR/2009/WD-html5-20090212/the-canvas-element.html#canvaspixelarray
+ // "When the canvas is initialized it must be set to fully transparent black."
+ m_bitmap->resetPixels(true);
+ m_bitmap->setHasAlpha(true);
+}
+
+ImageBuffer::ImageBuffer(const IntSize& size, ImageColorSpace colorSpace, bool& success)
+ : m_data(size)
+ , m_size(size)
+{
+ // FIXME: colorSpace is not used
+ UNUSED_PARAM(colorSpace);
+
+ m_context.set(new GraphicsContext(0));
+ m_context->setBitmap(m_data.m_bitmap);
+ success = true;
+}
+
+ImageBuffer::~ImageBuffer()
+{
+}
+
+GraphicsContext* ImageBuffer::context() const
+{
+ return m_context.get();
+}
+
+Image* ImageBuffer::image() const
+{
+ if (!m_image)
+ m_image = adoptRef(new BufferedImage(&m_data));
+
+ return m_image.get();
+}
+
+template <bool premultiplied> PassRefPtr<ImageData>
+static getImageData(const IntRect& rect, const SharedBitmap* bitmap)
+{
+ PassRefPtr<ImageData> imageData = ImageData::create(rect.width(), rect.height());
+
+ const unsigned char* src = static_cast<const unsigned char*>(bitmap->bytes());
+ if (!src)
+ return imageData;
+
+ IntRect sourceRect(0, 0, bitmap->width(), bitmap->height());
+ sourceRect.intersect(rect);
+ if (sourceRect.isEmpty())
+ return imageData;
+
+ unsigned char* dst = imageData->data()->data()->data();
+ memset(dst, 0, imageData->data()->data()->length());
+ src += (sourceRect.y() * bitmap->width() + sourceRect.x()) * 4;
+ dst += ((sourceRect.y() - rect.y()) * imageData->width() + sourceRect.x() - rect.x()) * 4;
+ int bytesToCopy = sourceRect.width() * 4;
+ int srcSkip = (bitmap->width() - sourceRect.width()) * 4;
+ int dstSkip = (imageData->width() - sourceRect.width()) * 4;
+ const unsigned char* dstEnd = dst + sourceRect.height() * imageData->width() * 4;
+ while (dst < dstEnd) {
+ const unsigned char* dstRowEnd = dst + bytesToCopy;
+ while (dst < dstRowEnd) {
+ // Convert ARGB little endian to RGBA big endian
+ int blue = *src++;
+ int green = *src++;
+ int red = *src++;
+ int alpha = *src++;
+ if (premultiplied) {
+ *dst++ = static_cast<unsigned char>((red * alpha + 254) / 255);
+ *dst++ = static_cast<unsigned char>((green * alpha + 254) / 255);
+ *dst++ = static_cast<unsigned char>((blue * alpha + 254) / 255);
+ *dst++ = static_cast<unsigned char>(alpha);
+ } else {
+ *dst++ = static_cast<unsigned char>(red);
+ *dst++ = static_cast<unsigned char>(green);
+ *dst++ = static_cast<unsigned char>(blue);
+ *dst++ = static_cast<unsigned char>(alpha);
+ ++src;
+ }
+ }
+ src += srcSkip;
+ dst += dstSkip;
+ }
+
+ return imageData;
+}
+
+PassRefPtr<ImageData> ImageBuffer::getUnmultipliedImageData(const IntRect& rect) const
+{
+ return getImageData<false>(rect, m_data.m_bitmap.get());
+}
+
+PassRefPtr<ImageData> ImageBuffer::getPremultipliedImageData(const IntRect& rect) const
+{
+ return getImageData<true>(rect, m_data.m_bitmap.get());
+}
+
+template <bool premultiplied>
+static void putImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint, SharedBitmap* bitmap)
+{
+ unsigned char* dst = (unsigned char*)bitmap->bytes();
+ if (!dst)
+ return;
+
+ IntRect destRect(destPoint, sourceRect.size());
+ destRect.intersect(IntRect(0, 0, bitmap->width(), bitmap->height()));
+
+ if (destRect.isEmpty())
+ return;
+
+ const unsigned char* src = source->data()->data()->data();
+ dst += (destRect.y() * bitmap->width() + destRect.x()) * 4;
+ src += (sourceRect.y() * source->width() + sourceRect.x()) * 4;
+ int bytesToCopy = destRect.width() * 4;
+ int dstSkip = (bitmap->width() - destRect.width()) * 4;
+ int srcSkip = (source->width() - destRect.width()) * 4;
+ const unsigned char* dstEnd = dst + destRect.height() * bitmap->width() * 4;
+ while (dst < dstEnd) {
+ const unsigned char* dstRowEnd = dst + bytesToCopy;
+ while (dst < dstRowEnd) {
+ // Convert RGBA big endian to ARGB little endian
+ int red = *src++;
+ int green = *src++;
+ int blue = *src++;
+ int alpha = *src++;
+ if (premultiplied) {
+ *dst++ = static_cast<unsigned char>(blue * 255 / alpha);
+ *dst++ = static_cast<unsigned char>(green * 255 / alpha);
+ *dst++ = static_cast<unsigned char>(red * 255 / alpha);
+ *dst++ = static_cast<unsigned char>(alpha);
+ } else {
+ *dst++ = static_cast<unsigned char>(blue);
+ *dst++ = static_cast<unsigned char>(green);
+ *dst++ = static_cast<unsigned char>(red);
+ *dst++ = static_cast<unsigned char>(alpha);
+ }
+ }
+ src += srcSkip;
+ dst += dstSkip;
+ }
+}
+
+void ImageBuffer::putUnmultipliedImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint)
+{
+ putImageData<false>(source, sourceRect, destPoint, m_data.m_bitmap.get());
+}
+
+void ImageBuffer::putPremultipliedImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint)
+{
+ putImageData<true>(source, sourceRect, destPoint, m_data.m_bitmap.get());
+}
+
+String ImageBuffer::toDataURL(const String& mimeType) const
+{
+ if (!m_data.m_bitmap->bytes())
+ return "data:,";
+
+ Vector<char> output;
+ const char* header;
+ if (mimeType.lower() == "image/png") {
+ if (!compressBitmapToPng(m_data.m_bitmap.get(), output))
+ return "data:,";
+ header = "data:image/png;base64,";
+ } else {
+ if (!compressBitmapToJpeg(m_data.m_bitmap.get(), output))
+ return "data:,";
+ header = "data:image/jpeg;base64,";
+ }
+
+ Vector<char> base64;
+ base64Encode(output, base64);
+
+ output.clear();
+
+ Vector<char> url;
+ url.append(header, strlen(header));
+ url.append(base64);
+
+ return String(url.data(), url.size());
+}
+
+}
diff --git a/WebCore/platform/graphics/wince/MediaPlayerPrivateWince.h b/WebCore/platform/graphics/wince/MediaPlayerPrivateWince.h
new file mode 100644
index 0000000..2d6c358
--- /dev/null
+++ b/WebCore/platform/graphics/wince/MediaPlayerPrivateWince.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Torch Mobile 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 MediaPlayerPrivateWince_h
+#define MediaPlayerPrivateWince_h
+
+#if ENABLE(VIDEO)
+
+#include "MediaPlayerPrivate.h"
+#include "Timer.h"
+#include <wtf/OwnPtr.h>
+
+namespace WebCore {
+
+ class GraphicsContext;
+ class IntSize;
+ class IntRect;
+ class String;
+
+ class MediaPlayerPrivate : public MediaPlayerPrivateInterface {
+ public:
+ static void registerMediaEngine(MediaEngineRegistrar);
+
+ ~MediaPlayerPrivate();
+
+ IntSize naturalSize() const;
+ bool hasVideo() const;
+
+ void load(const String& url);
+ void cancelLoad();
+
+ void play();
+ void pause();
+
+ bool paused() const;
+ bool seeking() const;
+
+ float duration() const;
+ float currentTime() const;
+ void seek(float time);
+ void setEndTime(float);
+
+ void setRate(float);
+ void setVolume(float);
+
+ int dataRate() const;
+
+ MediaPlayer::NetworkState networkState() const { return m_networkState; }
+ MediaPlayer::ReadyState readyState() const { return m_readyState; }
+
+ PassRefPtr<TimeRanges> buffered() const;
+ float maxTimeSeekable() const;
+ unsigned bytesLoaded() const;
+ bool totalBytesKnown() const;
+ unsigned totalBytes() const;
+
+ void setVisible(bool);
+ void setSize(const IntSize&);
+
+ void loadStateChanged();
+ void didEnd();
+
+ void paint(GraphicsContext*, const IntRect&);
+
+ private:
+ MediaPlayerPrivate(MediaPlayer*);
+
+ void updateStates();
+ void doSeek();
+ void cancelSeek();
+ void seekTimerFired(Timer<MediaPlayerPrivate>*);
+ float maxTimeLoaded() const;
+ void sawUnsupportedTracks();
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ void setMediaPlayerProxy(WebMediaPlayerProxy*);
+ void setPoster(const String& url);
+ void deliverNotification(MediaPlayerProxyNotificationType);
+#endif
+
+ // engine support
+ static MediaPlayerPrivateInterface* create(MediaPlayer*);
+ static void getSupportedTypes(HashSet<String>& types);
+ static MediaPlayer::SupportsType supportsType(const String& type, const String& codecs);
+ static bool isAvailable();
+
+ MediaPlayer* m_player;
+ float m_seekTo;
+ float m_endTime;
+ Timer<MediaPlayerPrivate> m_seekTimer;
+ MediaPlayer::NetworkState m_networkState;
+ MediaPlayer::ReadyState m_readyState;
+ unsigned m_enabledTrackCount;
+ unsigned m_totalTrackCount;
+ bool m_hasUnsupportedTracks;
+ bool m_startedPlaying;
+ bool m_isStreaming;
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ WebMediaPlayerProxy* m_proxy;
+#endif
+ };
+
+}
+
+#endif
+
+#endif
diff --git a/WebCore/platform/graphics/wince/MediaPlayerProxy.cpp b/WebCore/platform/graphics/wince/MediaPlayerProxy.cpp
new file mode 100644
index 0000000..9673d18
--- /dev/null
+++ b/WebCore/platform/graphics/wince/MediaPlayerProxy.cpp
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2009 Torch Mobile, 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.
+ */
+
+#if ENABLE(VIDEO)
+
+#include "config.h"
+#include "MediaPlayerProxy.h"
+
+#include "c_class.h"
+#include "c_instance.h"
+#include "c_runtime.h"
+#include "DocumentLoader.h"
+#include "HTMLPlugInElement.h"
+#include "HTMLVideoElement.h"
+#include "JSDOMBinding.h"
+#include "JSPluginElementFunctions.h"
+#include "MediaPlayer.h"
+#include "Node.h"
+#include "npruntime_impl.h"
+#include "PlatformString.h"
+#include "PluginView.h"
+#include "RenderPartObject.h"
+#include "RenderWidget.h"
+#include "runtime.h"
+#include <runtime/Identifier.h>
+#include "Widget.h"
+
+using namespace JSC;
+
+namespace WebCore {
+
+using namespace Bindings;
+using namespace HTMLNames;
+
+WebMediaPlayerProxy::WebMediaPlayerProxy(MediaPlayer* player)
+ : m_mediaPlayer(player)
+ , m_init(false)
+ , m_hasSentResponseToPlugin(false)
+{
+ if (!m_init)
+ initEngine();
+}
+
+WebMediaPlayerProxy::~WebMediaPlayerProxy()
+{
+ m_instance.release();
+}
+
+ScriptInstance WebMediaPlayerProxy::pluginInstance()
+{
+ if (!m_instance) {
+ RenderObject* r = element()->renderer();
+ if (!r || !r->isWidget())
+ return 0;
+
+ Frame* frame = element()->document()->frame();
+
+ RenderWidget* renderWidget = static_cast<RenderWidget*>(element()->renderer());
+ if (renderWidget && renderWidget->widget())
+ m_instance = frame->script()->createScriptInstanceForWidget(renderWidget->widget());
+ }
+
+ return m_instance;
+}
+
+void WebMediaPlayerProxy::load(const String& url)
+{
+ if (!m_init)
+ initEngine();
+ if (m_init)
+ invokeMethod("play");
+}
+
+void WebMediaPlayerProxy::initEngine()
+{
+ HTMLMediaElement* element = static_cast<HTMLMediaElement*>(m_mediaPlayer->mediaPlayerClient());
+ String url = element->initialURL();
+
+ if (url.isEmpty())
+ return;
+
+ Frame* frame = element->document()->frame();
+ Vector<String> paramNames;
+ Vector<String> paramValues;
+ String serviceType;
+
+ // add all attributes set on the embed object
+ if (NamedNodeMap* attributes = element->attributes()) {
+ for (unsigned i = 0; i < attributes->length(); ++i) {
+ Attribute* it = attributes->attributeItem(i);
+ paramNames.append(it->name().localName().string());
+ paramValues.append(it->value().string());
+ }
+ }
+ serviceType = "application/x-mplayer2";
+ frame->loader()->requestObject(static_cast<RenderPartObject*>(element->renderer()), url, nullAtom, serviceType, paramNames, paramValues);
+ m_init = true;
+
+}
+
+HTMLMediaElement* WebMediaPlayerProxy::element()
+{
+ return static_cast<HTMLMediaElement*>(m_mediaPlayer->mediaPlayerClient());
+
+}
+
+void WebMediaPlayerProxy::invokeMethod(const String& methodName)
+{
+ Frame* frame = element()->document()->frame();
+ RootObject *root = frame->script()->bindingRootObject();
+ if (!root)
+ return;
+ ExecState *exec = root->globalObject()->globalExec();
+ Instance* instance = pluginInstance().get();
+ if (!instance)
+ return;
+
+ instance->begin();
+ Class *aClass = instance->getClass();
+ Identifier iden(exec, methodName);
+ MethodList methodList = aClass->methodsNamed(iden, instance);
+ ArgList args;
+ instance->invokeMethod(exec, methodList , args);
+ instance->end();
+}
+
+}
+
+#endif
diff --git a/WebCore/platform/graphics/wince/MediaPlayerProxy.h b/WebCore/platform/graphics/wince/MediaPlayerProxy.h
new file mode 100644
index 0000000..05f9b21
--- /dev/null
+++ b/WebCore/platform/graphics/wince/MediaPlayerProxy.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2009 Torch Mobile, 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 MediaPlayerProxy_h
+#define MediaPlayerProxy_h
+
+#if ENABLE(VIDEO)
+
+#include "ScriptInstance.h"
+
+namespace WebCore {
+
+ class IntRect;
+ class IntSize;
+ class String;
+ class MediaPlayer;
+ class PluginView;
+ class HTMLMediaElement;
+
+ enum MediaPlayerProxyNotificationType {
+ MediaPlayerNotificationPlayPauseButtonPressed,
+ Idle,
+ Loading,
+ Loaded,
+ FormatError,
+ NetworkError,
+ DecodeError
+ };
+
+ class WebMediaPlayerProxy {
+ public:
+ WebMediaPlayerProxy(MediaPlayer* player);
+ ~WebMediaPlayerProxy();
+
+ MediaPlayer* mediaPlayer() {return m_mediaPlayer;}
+ void initEngine();
+ void load(const String& url);
+ HTMLMediaElement* element();
+ void invokeMethod(const String& methodName);
+ ScriptInstance pluginInstance();
+
+ private:
+ MediaPlayer* m_mediaPlayer;
+ bool m_init;
+ WebCore::PluginView* m_pluginView;
+ bool m_hasSentResponseToPlugin;
+ ScriptInstance m_instance;
+ };
+
+}
+#endif // ENABLE(VIDEO)
+
+#endif
diff --git a/WebCore/platform/graphics/wince/PathWince.cpp b/WebCore/platform/graphics/wince/PathWince.cpp
new file mode 100644
index 0000000..7589ccb
--- /dev/null
+++ b/WebCore/platform/graphics/wince/PathWince.cpp
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2007-2009 Torch Mobile, Inc.
+ *
+ * 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 "Path.h"
+
+#include "FloatRect.h"
+#include "NotImplemented.h"
+#include "PlatformPathWince.h"
+#include "PlatformString.h"
+#include "TransformationMatrix.h"
+#include <wtf/OwnPtr.h>
+
+namespace WebCore {
+
+Path::Path()
+ : m_path(new PlatformPath())
+{
+}
+
+Path::Path(const Path& other)
+ : m_path(new PlatformPath(*other.m_path))
+{
+}
+
+Path::~Path()
+{
+ delete m_path;
+}
+
+Path& Path::operator=(const Path& other)
+{
+ if (&other != this) {
+ delete m_path;
+ m_path = new PlatformPath(*other.m_path);
+ }
+ return *this;
+}
+
+bool Path::contains(const FloatPoint& point, WindRule rule) const
+{
+ return m_path->contains(point, rule);
+}
+
+void Path::translate(const FloatSize& size)
+{
+ m_path->translate(size);
+}
+
+FloatRect Path::boundingRect() const
+{
+ return m_path->boundingRect();
+}
+
+void Path::moveTo(const FloatPoint& point)
+{
+ m_path->moveTo(point);
+}
+
+void Path::addLineTo(const FloatPoint& point)
+{
+ m_path->addLineTo(point);
+}
+
+void Path::addQuadCurveTo(const FloatPoint& cp, const FloatPoint& p)
+{
+ m_path->addQuadCurveTo(cp, p);
+}
+
+void Path::addBezierCurveTo(const FloatPoint& cp1, const FloatPoint& cp2, const FloatPoint& p)
+{
+ m_path->addBezierCurveTo(cp1, cp2, p);
+}
+
+void Path::addArcTo(const FloatPoint& p1, const FloatPoint& p2, float radius)
+{
+ m_path->addArcTo(p1, p2, radius);
+}
+
+void Path::closeSubpath()
+{
+ m_path->closeSubpath();
+}
+
+void Path::addArc(const FloatPoint& p, float r, float sar, float ear, bool anticlockwise)
+{
+ m_path->addEllipse(p, r, r, sar, ear, anticlockwise);
+}
+
+void Path::addRect(const FloatRect& r)
+{
+ m_path->addRect(r);
+}
+
+void Path::addEllipse(const FloatRect& r)
+{
+ m_path->addEllipse(r);
+}
+
+void Path::clear()
+{
+ m_path->clear();
+}
+
+bool Path::isEmpty() const
+{
+ return m_path->isEmpty();
+}
+
+String Path::debugString() const
+{
+ return m_path->debugString();
+}
+
+void Path::apply(void* info, PathApplierFunction function) const
+{
+ m_path->apply(info, function);
+}
+
+void Path::transform(const TransformationMatrix& t)
+{
+ m_path->transform(t);
+}
+
+FloatRect Path::strokeBoundingRect(StrokeStyleApplier *)
+{
+ notImplemented();
+ return FloatRect();
+}
+
+bool Path::strokeContains(StrokeStyleApplier*, const FloatPoint&) const
+{
+ notImplemented();
+ return false;
+}
+
+bool Path::hasCurrentPoint() const
+{
+ // Not sure if this is correct. At the meantime, we do what other ports
+ // do.
+ // See https://bugs.webkit.org/show_bug.cgi?id=27266,
+ // https://bugs.webkit.org/show_bug.cgi?id=27187, and
+ // http://trac.webkit.org/changeset/45873
+ return !isEmpty();
+}
+
+}
diff --git a/WebCore/platform/graphics/wince/PlatformPathWince.cpp b/WebCore/platform/graphics/wince/PlatformPathWince.cpp
new file mode 100644
index 0000000..66fad50
--- /dev/null
+++ b/WebCore/platform/graphics/wince/PlatformPathWince.cpp
@@ -0,0 +1,810 @@
+/*
+ * Copyright (C) 2007-2009 Torch Mobile, Inc.
+ *
+ * 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 "PlatformPathWince.h"
+
+#include "FloatRect.h"
+#include "GraphicsContext.h"
+#include "Path.h"
+#include "PlatformString.h"
+#include "TransformationMatrix.h"
+#include "WinceGraphicsExtras.h"
+#include <wtf/MathExtras.h>
+#include <wtf/OwnPtr.h>
+
+#include <windows.h>
+
+namespace WebCore {
+
+// Implemented in GraphicsContextWince.cpp
+void getEllipsePointByAngle(double angle, double a, double b, float& x, float& y);
+
+static void quadCurve(int segments, Vector<PathPoint>& pts, const PathPoint* control)
+{
+ const float step = 1.0 / segments;
+ register float tA = 0.0;
+ register float tB = 1.0;
+
+ float c1x = control[0].x();
+ float c1y = control[0].y();
+ float c2x = control[1].x();
+ float c2y = control[1].y();
+ float c3x = control[2].x();
+ float c3y = control[2].y();
+
+ const int offset = pts.size();
+ pts.resize(offset + segments);
+ PathPoint pp;
+ pp.m_x = c1x;
+ pp.m_y = c1y;
+
+ for (int i = 1; i < segments; ++i) {
+ tA += step;
+ tB -= step;
+
+ const float a = tB * tB;
+ const float b = 2.0 * tA * tB;
+ const float c = tA * tA;
+
+ pp.m_x = c1x * a + c2x * b + c3x * c;
+ pp.m_y = c1y * a + c2y * b + c3y * c;
+
+ pts[offset + i - 1] = pp;
+ }
+
+ pp.m_x = c3x;
+ pp.m_y = c3y;
+ pts[offset + segments - 1] = pp;
+}
+
+static inline void bezier(int segments, Vector<PathPoint>& pts, const PathPoint* control)
+{
+ const float step = 1.0 / segments;
+ register float tA = 0.0;
+ register float tB = 1.0;
+
+ float c1x = control[0].x();
+ float c1y = control[0].y();
+ float c2x = control[1].x();
+ float c2y = control[1].y();
+ float c3x = control[2].x();
+ float c3y = control[2].y();
+ float c4x = control[3].x();
+ float c4y = control[3].y();
+
+ const int offset = pts.size();
+ pts.resize(offset + segments);
+ PathPoint pp;
+ pp.m_x = c1x;
+ pp.m_y = c1y;
+
+ for (int i = 1; i < segments; ++i) {
+ tA += step;
+ tB -= step;
+ const float tAsq = tA * tA;
+ const float tBsq = tB * tB;
+
+ const float a = tBsq * tB;
+ const float b = 3.0 * tA * tBsq;
+ const float c = 3.0 * tB * tAsq;
+ const float d = tAsq * tA;
+
+ pp.m_x = c1x * a + c2x * b + c3x * c + c4x * d;
+ pp.m_y = c1y * a + c2y * b + c3y * c + c4y * d;
+
+ pts[offset + i - 1] = pp;
+ }
+
+ pp.m_x = c4x;
+ pp.m_y = c4y;
+ pts[offset + segments - 1] = pp;
+}
+
+static bool containsPoint(const FloatRect& r, const FloatPoint& p)
+{
+ return p.x() >= r.x() && p.y() >= r.y() && p.x() < r.right() && p.y() < r.bottom();
+}
+
+static void normalizeAngle(float& angle)
+{
+ angle = fmod(angle, 2 * piFloat);
+ if (angle < 0)
+ angle += 2 * piFloat;
+ if (angle < 0.00001f)
+ angle = 0;
+}
+
+static void transformArcPoint(float& x, float& y, const FloatPoint& c)
+{
+ x += c.x();
+ y += c.y();
+}
+
+static void inflateRectToContainPoint(FloatRect& r, float x, float y)
+{
+ if (r.isEmpty()) {
+ r.setX(x);
+ r.setY(y);
+ r.setSize(FloatSize(1, 1));
+ return;
+ }
+ if (x < r.x()) {
+ r.setWidth(r.right() - x);
+ r.setX(x);
+ } else {
+ float w = x - r.x() + 1;
+ if (w > r.width())
+ r.setWidth(w);
+ }
+ if (y < r.y()) {
+ r.setHeight(r.bottom() - y);
+ r.setY(y);
+ } else {
+ float h = y - r.y() + 1;
+ if (h > r.height())
+ r.setHeight(h);
+ }
+}
+
+// return 0-based value: 0 - first Quadrant ( 0 - 90 degree)
+static inline int quadrant(const PathPoint& point, const PathPoint& origin)
+{
+ return point.m_x < origin.m_x ?
+ (point.m_y < origin.m_y ? 2 : 1)
+ : (point.m_y < origin.m_y ? 3 : 0);
+}
+
+static inline bool isQuadrantOnLeft(int q) { return q == 1 || q == 2; }
+static inline bool isQuadrantOnRight(int q) { return q == 0 || q == 3; }
+static inline bool isQuadrantOnTop(int q) { return q == 2 || q == 3; }
+static inline bool isQuadrantOnBottom(int q) { return q == 0 || q == 1; }
+
+static inline int nextQuadrant(int q) { return q == 3 ? 0 : q + 1; }
+static inline int quadrantDiff(int q1, int q2)
+{
+ int d = q1 - q2;
+ while (d < 0)
+ d += 4;
+ return d;
+}
+
+struct PathVector {
+ float m_x;
+ float m_y;
+
+ PathVector() : m_x(0), m_y(0) {}
+ PathVector(float x, float y) : m_x(x), m_y(y) {}
+ double angle() const { return atan2(m_y, m_x); }
+ operator double () const { return angle(); }
+ double length() const { return _hypot(m_x, m_y); }
+};
+
+PathVector operator-(const PathPoint& p1, const PathPoint& p2)
+{
+ return PathVector(p1.m_x - p2.m_x, p1.m_y - p2.m_y);
+}
+
+static void addArcPoint(PathPolygon& poly, const PathPoint& center, const PathPoint& radius, double angle)
+{
+ PathPoint p;
+ getEllipsePointByAngle(angle, radius.m_x, radius.m_y, p.m_x, p.m_y);
+ transformArcPoint(p.m_x, p.m_y, center);
+ if (poly.isEmpty() || poly.last() != p)
+ poly.append(p);
+}
+
+static void addArcPoints(PathPolygon& poly, const PlatformPathElement::ArcTo& data)
+{
+ const PathPoint& startPoint = poly.last();
+ double curAngle = startPoint - data.m_center;
+ double endAngle = data.m_end - data.m_center;
+ double angleStep = 2. / std::max(data.m_radius.m_x, data.m_radius.m_y);
+ if (data.m_clockwise) {
+ if (endAngle <= curAngle || startPoint == data.m_end)
+ endAngle += 2 * piDouble;
+ } else {
+ angleStep = -angleStep;
+ if (endAngle >= curAngle || startPoint == data.m_end)
+ endAngle -= 2 * piDouble;
+ }
+
+ for (curAngle += angleStep; data.m_clockwise ? curAngle < endAngle : curAngle > endAngle; curAngle += angleStep)
+ addArcPoint(poly, data.m_center, data.m_radius, curAngle);
+
+ if (poly.isEmpty() || poly.last() != data.m_end)
+ poly.append(data.m_end);
+}
+
+static void drawPolygons(HDC dc, const Vector<PathPolygon>& polygons, bool fill, const TransformationMatrix* transformation)
+{
+ MemoryAllocationCanFail canFail;
+ for (Vector<PathPolygon>::const_iterator i = polygons.begin(); i != polygons.end(); ++i) {
+ int npoints = i->size();
+ if (!npoints)
+ continue;
+
+ POINT* winPoints = 0;
+ if (fill) {
+ if (npoints > 2)
+ winPoints = new POINT[npoints + 1];
+ } else
+ winPoints = new POINT[npoints];
+
+ if (winPoints) {
+ if (transformation) {
+ for (int i2 = 0; i2 < npoints; ++i2) {
+ FloatPoint trPoint = transformation->mapPoint(i->at(i2));
+ winPoints[i2].x = stableRound(trPoint.x());
+ winPoints[i2].y = stableRound(trPoint.y());
+ }
+ } else {
+ for (int i2 = 0; i2 < npoints; ++i2) {
+ winPoints[i2].x = stableRound(i->at(i2).x());
+ winPoints[i2].y = stableRound(i->at(i2).y());
+ }
+ }
+
+ if (fill && winPoints[npoints - 1] != winPoints[0]) {
+ winPoints[npoints].x = winPoints[0].x;
+ winPoints[npoints].y = winPoints[0].y;
+ ++npoints;
+ }
+
+ if (fill)
+ ::Polygon(dc, winPoints, npoints);
+ else
+ ::Polyline(dc, winPoints, npoints);
+ delete[] winPoints;
+ }
+ }
+}
+
+
+int PlatformPathElement::numControlPoints() const
+{
+ switch (m_type) {
+ case PathMoveTo:
+ case PathLineTo:
+ return 1;
+ case PathQuadCurveTo:
+ case PathArcTo:
+ return 2;
+ case PathBezierCurveTo:
+ return 3;
+ default:
+ ASSERT(m_type == PathCloseSubpath);
+ return 0;
+ }
+}
+
+int PlatformPathElement::numPoints() const
+{
+ switch (m_type) {
+ case PathMoveTo:
+ case PathLineTo:
+ case PathArcTo:
+ return 1;
+ case PathQuadCurveTo:
+ return 2;
+ case PathBezierCurveTo:
+ return 3;
+ default:
+ ASSERT(m_type == PathCloseSubpath);
+ return 0;
+ }
+}
+
+void PathPolygon::move(const FloatSize& offset)
+{
+ for (Vector<PathPoint>::iterator i = begin(); i < end(); ++i)
+ i->move(offset);
+}
+
+void PathPolygon::transform(const TransformationMatrix& t)
+{
+ for (Vector<PathPoint>::iterator i = begin(); i < end(); ++i)
+ *i = t.mapPoint(*i);
+}
+
+bool PathPolygon::contains(const FloatPoint& point) const
+{
+ if (size() < 3)
+ return false;
+
+ // Test intersections between the polygon and the vertical line: x = point.x()
+
+ int intersected = 0;
+ const PathPoint* point1 = &last();
+ Vector<PathPoint>::const_iterator last = end();
+ // wasNegative: -1 means unknown, 0 means false, 1 means true.
+ int wasNegative = -1;
+ for (Vector<PathPoint>::const_iterator i = begin(); i != last; ++i) {
+ const PathPoint& point2 = *i;
+ if (point1->x() != point.x()) {
+ if (point2.x() == point.x()) {
+ // We are getting on the vertical line
+ wasNegative = point1->x() < point.x() ? 1 : 0;
+ } else if (point2.x() < point.x() != point1->x() < point.x()) {
+ float y = (point2.y() - point1->y()) / (point2.x() - point1->x()) * (point.x() - point1->x()) + point1->y();
+ if (y >= point.y())
+ ++intersected;
+ }
+ } else {
+ // We were on the vertical line
+
+ // handle special case
+ if (point1->y() == point.y())
+ return true;
+
+ if (point1->y() > point.y()) {
+ if (point2.x() == point.x()) {
+ // see if the point is on this segment
+ if (point2.y() <= point.y())
+ return true;
+
+ // We are still on the line
+ } else {
+ // We are leaving the line now.
+ // We have to get back to see which side we come from. If we come from
+ // the same side we are leaving, no intersection should be counted
+ if (wasNegative < 0) {
+ Vector<PathPoint>::const_iterator jLast = i;
+ Vector<PathPoint>::const_iterator j = i;
+ do {
+ if (j == begin())
+ j = last;
+ else
+ --j;
+ if (j->x() != point.x()) {
+ if (j->x() > point.x())
+ wasNegative = 0;
+ else
+ wasNegative = 1;
+ break;
+ }
+ } while (j != jLast);
+
+ if (wasNegative < 0)
+ return false;
+ }
+ if (wasNegative ? point2.x() > point.x() : point2.x() < point.x())
+ ++intersected;
+ }
+ } else if (point2.x() == point.x() && point2.y() >= point.y())
+ return true;
+ }
+ point1 = &point2;
+ }
+
+ return intersected & 1;
+}
+
+void PlatformPathElement::move(const FloatSize& offset)
+{
+ int n = numControlPoints();
+ for (int i = 0; i < n; ++i)
+ m_data.m_points[i].move(offset);
+}
+
+void PlatformPathElement::transform(const TransformationMatrix& t)
+{
+ int n = numControlPoints();
+ for (int i = 0; i < n; ++i) {
+ FloatPoint p = t.mapPoint(m_data.m_points[i]);
+ m_data.m_points[i].set(p.x(), p.y());
+ }
+}
+
+void PlatformPathElement::inflateRectToContainMe(FloatRect& r, const FloatPoint& lastPoint) const
+{
+ if (m_type == PathArcTo) {
+ const ArcTo& data = m_data.m_arcToData;
+ PathPoint startPoint;
+ startPoint = lastPoint;
+ PathPoint endPoint = data.m_end;
+ if (!data.m_clockwise)
+ std::swap(startPoint, endPoint);
+
+ int q0 = quadrant(startPoint, data.m_center);
+ int q1 = quadrant(endPoint, data.m_center);
+ bool containsExtremes[4] = { false }; // bottom, left, top, right
+ static const PathPoint extremeVectors[4] = { { 0, 1 }, { -1, 0 }, { 0, -1 }, { 1, 0 } };
+ if (q0 == q1) {
+ if (startPoint.m_x == endPoint.m_x || isQuadrantOnBottom(q0) != startPoint.m_x > endPoint.m_x) {
+ for (int i = 0; i < 4; ++i)
+ containsExtremes[i] = true;
+ }
+ } else {
+ int extreme = q0;
+ int diff = quadrantDiff(q1, q0);
+ for (int i = 0; i < diff; ++i) {
+ containsExtremes[extreme] = true;
+ extreme = nextQuadrant(extreme);
+ }
+ }
+
+ inflateRectToContainPoint(r, startPoint.m_x, startPoint.m_y);
+ inflateRectToContainPoint(r, endPoint.m_x, endPoint.m_y);
+ for (int i = 0; i < 4; ++i) {
+ if (containsExtremes[i])
+ inflateRectToContainPoint(r, data.m_center.m_x + data.m_radius.m_x * extremeVectors[i].m_x, data.m_center.m_y + data.m_radius.m_y * extremeVectors[i].m_y);
+ }
+ } else {
+ int n = numPoints();
+ for (int i = 0; i < n; ++i)
+ inflateRectToContainPoint(r, m_data.m_points[i].m_x, m_data.m_points[i].m_y);
+ }
+}
+
+PathElementType PlatformPathElement::type() const
+{
+ switch (m_type) {
+ case PathMoveTo:
+ return PathElementMoveToPoint;
+ case PathLineTo:
+ return PathElementAddLineToPoint;
+ case PathArcTo:
+ // FIXME: there's no arcTo type for PathElement
+ return PathElementAddLineToPoint;
+ // return PathElementAddQuadCurveToPoint;
+ case PathQuadCurveTo:
+ return PathElementAddQuadCurveToPoint;
+ case PathBezierCurveTo:
+ return PathElementAddCurveToPoint;
+ default:
+ ASSERT(m_type == PathCloseSubpath);
+ return PathElementCloseSubpath;
+ }
+}
+
+PlatformPath::PlatformPath()
+ : m_penLifted(true)
+{
+ m_currentPoint.clear();
+}
+
+void PlatformPath::ensureSubpath()
+{
+ if (m_penLifted) {
+ m_penLifted = false;
+ m_subpaths.append(PathPolygon());
+ m_subpaths.last().append(m_currentPoint);
+ } else
+ ASSERT(!m_subpaths.isEmpty());
+}
+
+void PlatformPath::addToSubpath(const PlatformPathElement& e)
+{
+ if (e.platformType() == PlatformPathElement::PathMoveTo) {
+ m_penLifted = true;
+ m_currentPoint = e.pointAt(0);
+ } else if (e.platformType() == PlatformPathElement::PathCloseSubpath) {
+ m_penLifted = true;
+ if (!m_subpaths.isEmpty()) {
+ if (m_currentPoint != m_subpaths.last()[0]) {
+ // According to W3C, we have to draw a line from current point to the initial point
+ m_subpaths.last().append(m_subpaths.last()[0]);
+ m_currentPoint = m_subpaths.last()[0];
+ }
+ } else
+ m_currentPoint.clear();
+ } else {
+ ensureSubpath();
+ switch (e.platformType()) {
+ case PlatformPathElement::PathLineTo:
+ m_subpaths.last().append(e.pointAt(0));
+ break;
+ case PlatformPathElement::PathArcTo:
+ addArcPoints(m_subpaths.last(), e.arcTo());
+ break;
+ case PlatformPathElement::PathQuadCurveTo:
+ {
+ PathPoint control[] = {
+ m_currentPoint,
+ e.pointAt(0),
+ e.pointAt(1),
+ };
+ // FIXME: magic number?
+ quadCurve(50, m_subpaths.last(), control);
+ }
+ break;
+ case PlatformPathElement::PathBezierCurveTo:
+ {
+ PathPoint control[] = {
+ m_currentPoint,
+ e.pointAt(0),
+ e.pointAt(1),
+ e.pointAt(2),
+ };
+ // FIXME: magic number?
+ bezier(100, m_subpaths.last(), control);
+ }
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+ m_currentPoint = m_subpaths.last().last();
+ }
+}
+
+void PlatformPath::append(const PlatformPathElement& e)
+{
+ e.inflateRectToContainMe(m_boundingRect, lastPoint());
+ addToSubpath(e);
+ m_elements.append(e);
+}
+
+void PlatformPath::append(const PlatformPath& p)
+{
+ const PlatformPathElements& e = p.elements();
+ for (PlatformPathElements::const_iterator it(e.begin()); it != e.end(); ++it) {
+ addToSubpath(*it);
+ it->inflateRectToContainMe(m_boundingRect, lastPoint());
+ m_elements.append(*it);
+ }
+}
+
+void PlatformPath::clear()
+{
+ m_elements.clear();
+ m_boundingRect = FloatRect();
+ m_subpaths.clear();
+ m_currentPoint.clear();
+ m_penLifted = true;
+}
+
+void PlatformPath::strokePath(HDC dc, const TransformationMatrix* transformation) const
+{
+ drawPolygons(dc, m_subpaths, false, transformation);
+}
+
+void PlatformPath::fillPath(HDC dc, const TransformationMatrix* transformation) const
+{
+ HGDIOBJ oldPen = SelectObject(dc, GetStockObject(NULL_PEN));
+ drawPolygons(dc, m_subpaths, true, transformation);
+ SelectObject(dc, oldPen);
+}
+
+void PlatformPath::translate(const FloatSize& size)
+{
+ for (PlatformPathElements::iterator it(m_elements.begin()); it != m_elements.end(); ++it)
+ it->move(size);
+
+ m_boundingRect.move(size);
+ for (Vector<PathPolygon>::iterator it = m_subpaths.begin(); it != m_subpaths.end(); ++it)
+ it->move(size);
+}
+
+void PlatformPath::transform(const TransformationMatrix& t)
+{
+ for (PlatformPathElements::iterator it(m_elements.begin()); it != m_elements.end(); ++it)
+ it->transform(t);
+
+ m_boundingRect = t.mapRect(m_boundingRect);
+ for (Vector<PathPolygon>::iterator it = m_subpaths.begin(); it != m_subpaths.end(); ++it)
+ it->transform(t);
+}
+
+bool PlatformPath::contains(const FloatPoint& point, WindRule rule) const
+{
+ // optimization: check the bounding rect first
+ if (!containsPoint(m_boundingRect, point))
+ return false;
+
+ for (Vector<PathPolygon>::const_iterator i = m_subpaths.begin(); i != m_subpaths.end(); ++i) {
+ if (i->contains(point))
+ return true;
+ }
+
+ return false;
+}
+
+void PlatformPath::moveTo(const FloatPoint& point)
+{
+ PlatformPathElement::MoveTo data = { { point.x(), point.y() } };
+ PlatformPathElement pe(data);
+ append(pe);
+}
+
+void PlatformPath::addLineTo(const FloatPoint& point)
+{
+ PlatformPathElement::LineTo data = { { point.x(), point.y() } };
+ PlatformPathElement pe(data);
+ append(pe);
+}
+
+void PlatformPath::addQuadCurveTo(const FloatPoint& cp, const FloatPoint& p)
+{
+ PlatformPathElement::QuadCurveTo data = { { cp.x(), cp.y() }, { p.x(), p.y() } };
+ PlatformPathElement pe(data);
+ append(pe);
+}
+
+void PlatformPath::addBezierCurveTo(const FloatPoint& cp1, const FloatPoint& cp2, const FloatPoint& p)
+{
+ PlatformPathElement::BezierCurveTo data = { { cp1.x(), cp1.y() }, { cp2.x(), cp2.y() }, { p.x(), p.y() } };
+ PlatformPathElement pe(data);
+ append(pe);
+}
+
+void PlatformPath::addArcTo(const FloatPoint& fp1, const FloatPoint& fp2, float radius)
+{
+ const PathPoint& p0 = m_currentPoint;
+ PathPoint p1;
+ p1 = fp1;
+ PathPoint p2;
+ p2 = fp2;
+ if (!radius || p0 == p1 || p1 == p2) {
+ addLineTo(p1);
+ return;
+ }
+
+ PathVector v01 = p0 - p1;
+ PathVector v21 = p2 - p1;
+
+ // sin(A - B) = sin(A) * cos(B) - sin(B) * cos(A)
+ double cross = v01.m_x * v21.m_y - v01.m_y * v21.m_x;
+
+ if (fabs(cross) < 1E-10) {
+ // on one line
+ addLineTo(p1);
+ return;
+ }
+
+ double d01 = v01.length();
+ double d21 = v21.length();
+ double angle = (piDouble - abs(asin(cross / (d01 * d21)))) * 0.5;
+ double span = radius * tan(angle);
+ double rate = span / d01;
+ PathPoint startPoint;
+ startPoint.m_x = p1.m_x + v01.m_x * rate;
+ startPoint.m_y = p1.m_y + v01.m_y * rate;
+
+ addLineTo(startPoint);
+
+ PathPoint endPoint;
+ rate = span / d21;
+ endPoint.m_x = p1.m_x + v21.m_x * rate;
+ endPoint.m_y = p1.m_y + v21.m_y * rate;
+
+ PathPoint midPoint;
+ midPoint.m_x = (startPoint.m_x + endPoint.m_x) * 0.5;
+ midPoint.m_y = (startPoint.m_y + endPoint.m_y) * 0.5;
+
+ PathVector vm1 = midPoint - p1;
+ double dm1 = vm1.length();
+ double d = _hypot(radius, span);
+
+ PathPoint centerPoint;
+ rate = d / dm1;
+ centerPoint.m_x = p1.m_x + vm1.m_x * rate;
+ centerPoint.m_y = p1.m_y + vm1.m_y * rate;
+
+ PlatformPathElement::ArcTo data = {
+ endPoint,
+ centerPoint,
+ { radius, radius },
+ cross < 0
+ };
+ PlatformPathElement pe(data);
+ append(pe);
+}
+
+void PlatformPath::closeSubpath()
+{
+ PlatformPathElement pe;
+ append(pe);
+}
+
+// add a circular arc centred at p with radius r from start angle sar (radians) to end angle ear
+void PlatformPath::addEllipse(const FloatPoint& p, float a, float b, float sar, float ear, bool anticlockwise)
+{
+ float startX, startY, endX, endY;
+
+ normalizeAngle(sar);
+ normalizeAngle(ear);
+
+ getEllipsePointByAngle(sar, a, b, startX, startY);
+ getEllipsePointByAngle(ear, a, b, endX, endY);
+
+ transformArcPoint(startX, startY, p);
+ transformArcPoint(endX, endY, p);
+
+ FloatPoint start(startX, startY);
+ moveTo(start);
+
+ PlatformPathElement::ArcTo data = { { endX, endY }, { p.x(), p.y() }, { a, b }, !anticlockwise };
+ PlatformPathElement pe(data);
+ append(pe);
+}
+
+
+void PlatformPath::addRect(const FloatRect& r)
+{
+ moveTo(r.location());
+
+ float right = r.right() - 1;
+ float bottom = r.bottom() - 1;
+ addLineTo(FloatPoint(right, r.y()));
+ addLineTo(FloatPoint(right, bottom));
+ addLineTo(FloatPoint(r.x(), bottom));
+ addLineTo(r.location());
+}
+
+void PlatformPath::addEllipse(const FloatRect& r)
+{
+ FloatSize radius(r.width() * 0.5, r.height() * 0.5);
+ addEllipse(r.location() + radius, radius.width(), radius.height(), 0, 0, true);
+}
+
+String PlatformPath::debugString() const
+{
+ String ret;
+ for (PlatformPathElements::const_iterator i(m_elements.begin()); i != m_elements.end(); ++i) {
+ switch (i->platformType()) {
+ case PlatformPathElement::PathMoveTo:
+ case PlatformPathElement::PathLineTo:
+ ret += String::format("M %f %f\n", i->pointAt(0).m_x, i->pointAt(0).m_y);
+ break;
+ case PlatformPathElement::PathArcTo:
+ ret += String::format("A %f %f %f %f %f %f %c\n"
+ , i->arcTo().m_end.m_x, i->arcTo().m_end.m_y
+ , i->arcTo().m_center.m_x, i->arcTo().m_center.m_y
+ , i->arcTo().m_radius.m_x, i->arcTo().m_radius.m_y
+ , i->arcTo().m_clockwise? 'Y' : 'N');
+ break;
+ case PlatformPathElement::PathQuadCurveTo:
+ ret += String::format("Q %f %f %f %f\n"
+ , i->pointAt(0).m_x, i->pointAt(0).m_y
+ , i->pointAt(1).m_x, i->pointAt(1).m_y);
+ break;
+ case PlatformPathElement::PathBezierCurveTo:
+ ret += String::format("B %f %f %f %f %f %f\n"
+ , i->pointAt(0).m_x, i->pointAt(0).m_y
+ , i->pointAt(1).m_x, i->pointAt(1).m_y
+ , i->pointAt(2).m_x, i->pointAt(2).m_y);
+ break;
+ default:
+ ASSERT(i->platformType() == PlatformPathElement::PathCloseSubpath);
+ ret += "S\n";
+ break;
+ }
+ }
+
+ return ret;
+}
+
+void PlatformPath::apply(void* info, PathApplierFunction function) const
+{
+ PathElement pelement;
+ FloatPoint points[3];
+ pelement.points = points;
+
+ for (PlatformPathElements::const_iterator it(m_elements.begin()); it != m_elements.end(); ++it) {
+ pelement.type = it->type();
+ int n = it->numPoints();
+ for (int i = 0; i < n; ++i)
+ points[i] = it->pointAt(i);
+ function(info, &pelement);
+ }
+}
+
+} // namespace Webcore
diff --git a/WebCore/platform/graphics/wince/PlatformPathWince.h b/WebCore/platform/graphics/wince/PlatformPathWince.h
new file mode 100644
index 0000000..fca00a7
--- /dev/null
+++ b/WebCore/platform/graphics/wince/PlatformPathWince.h
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2007-2009 Torch Mobile, Inc.
+ *
+ * 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 PlatformPathWince_h
+#define PlatformPathWince_h
+
+namespace WebCore {
+
+ class GraphicsContext;
+
+ struct PathPoint {
+ float m_x;
+ float m_y;
+ const float& x() const { return m_x; }
+ const float& y() const { return m_y; }
+ void set(float x, float y)
+ {
+ m_x = x;
+ m_y = y;
+ };
+ operator FloatPoint() const { return FloatPoint(m_x, m_y); }
+ void move(const FloatSize& offset)
+ {
+ m_x += offset.width();
+ m_y += offset.height();
+ }
+ PathPoint& operator=(const FloatPoint& p)
+ {
+ m_x = p.x();
+ m_y = p.y();
+ return *this;
+ }
+ void clear() { m_x = m_y = 0; }
+ };
+
+ struct PathPolygon: public Vector<PathPoint> {
+ void move(const FloatSize& offset);
+ void transform(const TransformationMatrix& t);
+ bool contains(const FloatPoint& point) const;
+ };
+
+ class PlatformPathElement {
+ public:
+ enum PlaformPathElementType {
+ PathMoveTo,
+ PathLineTo,
+ PathArcTo,
+ PathQuadCurveTo,
+ PathBezierCurveTo,
+ PathCloseSubpath,
+ };
+
+ struct MoveTo {
+ PathPoint m_end;
+ };
+
+ struct LineTo {
+ PathPoint m_end;
+ };
+
+ struct ArcTo {
+ PathPoint m_end;
+ PathPoint m_center;
+ PathPoint m_radius;
+ bool m_clockwise;
+ };
+
+ struct QuadCurveTo {
+ PathPoint m_point0;
+ PathPoint m_point1;
+ };
+
+ struct BezierCurveTo {
+ PathPoint m_point0;
+ PathPoint m_point1;
+ PathPoint m_point2;
+ };
+
+ PlatformPathElement(): m_type(PathCloseSubpath) { m_data.m_points[0].set(0, 0); }
+ PlatformPathElement(const MoveTo& data): m_type(PathMoveTo) { m_data.m_moveToData = data; }
+ PlatformPathElement(const LineTo& data): m_type(PathLineTo) { m_data.m_lineToData = data; }
+ PlatformPathElement(const ArcTo& data): m_type(PathArcTo) { m_data.m_arcToData = data; }
+ PlatformPathElement(const QuadCurveTo& data): m_type(PathQuadCurveTo) { m_data.m_quadCurveToData = data; }
+ PlatformPathElement(const BezierCurveTo& data): m_type(PathBezierCurveTo) { m_data.m_bezierCurveToData = data; }
+
+ const MoveTo& moveTo() const { return m_data.m_moveToData; }
+ const LineTo& lineTo() const { return m_data.m_lineToData; }
+ const ArcTo& arcTo() const { return m_data.m_arcToData; }
+ const QuadCurveTo& quadCurveTo() const { return m_data.m_quadCurveToData; }
+ const BezierCurveTo& bezierCurveTo() const { return m_data.m_bezierCurveToData; }
+ const PathPoint& lastPoint() const
+ {
+ int n = numPoints();
+ return n > 1 ? m_data.m_points[n - 1] : m_data.m_points[0];
+ }
+ const PathPoint& pointAt(int index) const { return m_data.m_points[index]; }
+ int numPoints() const;
+ int numControlPoints() const;
+ void move(const FloatSize& offset);
+ void transform(const TransformationMatrix& t);
+ PathElementType type() const;
+ PlaformPathElementType platformType() const { return m_type; }
+ void inflateRectToContainMe(FloatRect& r, const FloatPoint& lastPoint) const;
+
+ private:
+ PlaformPathElementType m_type;
+ union {
+ MoveTo m_moveToData;
+ LineTo m_lineToData;
+ ArcTo m_arcToData;
+ QuadCurveTo m_quadCurveToData;
+ BezierCurveTo m_bezierCurveToData;
+ PathPoint m_points[4];
+ } m_data;
+ };
+
+ typedef Vector<PlatformPathElement> PlatformPathElements;
+
+ class PlatformPath {
+ public:
+ PlatformPath();
+ const PlatformPathElements& elements() const { return m_elements; }
+ void append(const PlatformPathElement& e);
+ void append(const PlatformPath& p);
+ void clear();
+ bool isEmpty() const { return m_elements.isEmpty(); }
+
+ void strokePath(HDC, const TransformationMatrix* tr) const;
+ void fillPath(HDC, const TransformationMatrix* tr) const;
+ FloatPoint lastPoint() const { return m_elements.isEmpty() ? FloatPoint(0, 0) : m_elements.last().lastPoint(); }
+
+ const FloatRect& boundingRect() const { return m_boundingRect; }
+ bool contains(const FloatPoint& point, WindRule rule) const;
+ void translate(const FloatSize& size);
+ void transform(const TransformationMatrix& t);
+
+ void moveTo(const FloatPoint&);
+ void addLineTo(const FloatPoint&);
+ void addQuadCurveTo(const FloatPoint& controlPoint, const FloatPoint& point);
+ void addBezierCurveTo(const FloatPoint& controlPoint1, const FloatPoint& controlPoint2, const FloatPoint&);
+ void addArcTo(const FloatPoint&, const FloatPoint&, float radius);
+ void closeSubpath();
+ void addEllipse(const FloatPoint& p, float a, float b, float sar, float ear, bool anticlockwise);
+ void addRect(const FloatRect& r);
+ void addEllipse(const FloatRect& r);
+ String debugString() const;
+ void apply(void* info, PathApplierFunction function) const;
+
+ private:
+ void ensureSubpath();
+ void addToSubpath(const PlatformPathElement& e);
+
+ PlatformPathElements m_elements;
+ FloatRect m_boundingRect;
+ Vector<PathPolygon> m_subpaths;
+ PathPoint m_currentPoint;
+ bool m_penLifted;
+ };
+
+}
+
+#endif // PlatformPathWince_h
diff --git a/WebCore/platform/graphics/wince/WinceGraphicsExtras.h b/WebCore/platform/graphics/wince/WinceGraphicsExtras.h
new file mode 100644
index 0000000..2a6fae1
--- /dev/null
+++ b/WebCore/platform/graphics/wince/WinceGraphicsExtras.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2007-2009 Torch Mobile, Inc.
+ *
+ * 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 WinceGraphicsExtras_h
+#define WinceGraphicsExtras_h
+
+// This file is used to contain small utilities used by WINCE graphics code.
+
+namespace WebCore {
+ // Always round to same direction. 0.5 is rounded to 1,
+ // and -0.5 (0.5 - 1) is rounded to 0 (1 - 1), so that it
+ // is consistent when transformation shifts.
+ static inline int stableRound(double d)
+ {
+ if (d > 0)
+ return static_cast<int>(d + 0.5);
+
+ int i = static_cast<int>(d);
+ return i - d > 0.5 ? i - 1 : i;
+ }
+}
+
+#endif WinceGraphicsExtras_h
diff --git a/WebCore/platform/graphics/wx/GraphicsContextWx.cpp b/WebCore/platform/graphics/wx/GraphicsContextWx.cpp
index 59e388e..686fb07 100644
--- a/WebCore/platform/graphics/wx/GraphicsContextWx.cpp
+++ b/WebCore/platform/graphics/wx/GraphicsContextWx.cpp
@@ -506,4 +506,59 @@ void GraphicsContext::fillRect(const FloatRect& rect)
return;
}
+void GraphicsContext::setPlatformShadow(IntSize const&,int,Color const&)
+{
+ notImplemented();
+}
+
+void GraphicsContext::clearPlatformShadow()
+{
+ notImplemented();
+}
+
+void GraphicsContext::beginTransparencyLayer(float)
+{
+ notImplemented();
+}
+
+void GraphicsContext::endTransparencyLayer()
+{
+ notImplemented();
+}
+
+void GraphicsContext::clearRect(const FloatRect&)
+{
+ notImplemented();
+}
+
+void GraphicsContext::strokeRect(const FloatRect&, float)
+{
+ notImplemented();
+}
+
+void GraphicsContext::setLineCap(LineCap)
+{
+ notImplemented();
+}
+
+void GraphicsContext::setLineJoin(LineJoin)
+{
+ notImplemented();
+}
+
+void GraphicsContext::setMiterLimit(float)
+{
+ notImplemented();
+}
+
+void GraphicsContext::setAlpha(float)
+{
+ notImplemented();
+}
+
+void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness)
+{
+ notImplemented();
+}
+
}
diff --git a/WebCore/platform/graphics/wx/IconWx.cpp b/WebCore/platform/graphics/wx/IconWx.cpp
new file mode 100644
index 0000000..e82091e
--- /dev/null
+++ b/WebCore/platform/graphics/wx/IconWx.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * 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 "Icon.h"
+
+#include "GraphicsContext.h"
+#include "PlatformString.h"
+#include "IntRect.h"
+#include "NotImplemented.h"
+
+namespace WebCore {
+
+Icon::~Icon()
+{
+}
+
+PassRefPtr<Icon> Icon::createIconForFile(const String& filename)
+{
+ notImplemented();
+ return 0;
+}
+
+PassRefPtr<Icon> Icon::createIconForFiles(const Vector<String>& filenames)
+{
+ notImplemented();
+ return 0;
+}
+
+void Icon::paint(GraphicsContext* ctx, const IntRect& rect)
+{
+ notImplemented();
+}
+
+}
+
diff --git a/WebCore/platform/graphics/wx/ImageBufferWx.cpp b/WebCore/platform/graphics/wx/ImageBufferWx.cpp
index e71dbde..49f3f3b 100644
--- a/WebCore/platform/graphics/wx/ImageBufferWx.cpp
+++ b/WebCore/platform/graphics/wx/ImageBufferWx.cpp
@@ -53,13 +53,24 @@ GraphicsContext* ImageBuffer::context() const
return 0;
}
-PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect&) const
+PassRefPtr<ImageData> ImageBuffer::getUnmultipliedImageData(const IntRect& rect) const
{
notImplemented();
return 0;
}
-void ImageBuffer::putImageData(ImageData*, const IntRect&, const IntPoint&)
+PassRefPtr<ImageData> ImageBuffer::getPremultipliedImageData(const IntRect& rect) const
+{
+ notImplemented();
+ return 0;
+}
+
+void ImageBuffer::putUnmultipliedImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint)
+{
+ notImplemented();
+}
+
+void ImageBuffer::putPremultipliedImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint)
{
notImplemented();
}
diff --git a/WebCore/platform/graphics/wx/ImageSourceWx.cpp b/WebCore/platform/graphics/wx/ImageSourceWx.cpp
deleted file mode 100644
index 06c165d..0000000
--- a/WebCore/platform/graphics/wx/ImageSourceWx.cpp
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright (C) 2006, 2007 Apple Computer, Kevin Ollivier. 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 "ImageSource.h"
-
-#include "BMPImageDecoder.h"
-#include "GIFImageDecoder.h"
-#include "ICOImageDecoder.h"
-#include "JPEGImageDecoder.h"
-#include "NotImplemented.h"
-#include "PNGImageDecoder.h"
-#include "SharedBuffer.h"
-#include "XBMImageDecoder.h"
-
-#include <wx/defs.h>
-#include <wx/bitmap.h>
-#if USE(WXGC)
-#include <wx/graphics.h>
-#endif
-#include <wx/image.h>
-#include <wx/rawbmp.h>
-
-namespace WebCore {
-
-ImageDecoder* createDecoder(const SharedBuffer& data)
-{
- // We need at least 4 bytes to figure out what kind of image we're dealing with.
- int length = data.size();
- if (length < 4)
- return 0;
-
- const unsigned char* uContents = (const unsigned char*)data.data();
- const char* contents = data.data();
-
- // GIFs begin with GIF8(7 or 9).
- if (strncmp(contents, "GIF8", 4) == 0)
- return new GIFImageDecoder();
-
- // Test for PNG.
- if (uContents[0]==0x89 &&
- uContents[1]==0x50 &&
- uContents[2]==0x4E &&
- uContents[3]==0x47)
- return new PNGImageDecoder();
-
- // JPEG
- if (uContents[0]==0xFF &&
- uContents[1]==0xD8 &&
- uContents[2]==0xFF)
- return new JPEGImageDecoder();
-
- // BMP
- if (strncmp(contents, "BM", 2) == 0)
- return new BMPImageDecoder();
-
- // ICOs always begin with a 2-byte 0 followed by a 2-byte 1.
- // CURs begin with 2-byte 0 followed by 2-byte 2.
- if (!memcmp(contents, "\000\000\001\000", 4) ||
- !memcmp(contents, "\000\000\002\000", 4))
- return new ICOImageDecoder();
-
- // XBMs require 8 bytes of info.
- if (length >= 8 && strncmp(contents, "#define ", 8) == 0)
- return new XBMImageDecoder();
-
- // Give up. We don't know what the heck this is.
- return 0;
-}
-
-ImageSource::ImageSource()
- : m_decoder(0)
-{}
-
-ImageSource::~ImageSource()
-{
- clear(true);
-}
-
-bool ImageSource::initialized() const
-{
- return m_decoder;
-}
-
-void ImageSource::setData(SharedBuffer* data, bool allDataReceived)
-{
- // Make the decoder by sniffing the bytes.
- // This method will examine the data and instantiate an instance of the appropriate decoder plugin.
- // If insufficient bytes are available to determine the image type, no decoder plugin will be
- // made.
- if (m_decoder)
- delete m_decoder;
- m_decoder = createDecoder(*data);
- if (!m_decoder)
- return;
- m_decoder->setData(data, allDataReceived);
-}
-
-bool ImageSource::isSizeAvailable()
-{
- if (!m_decoder)
- return false;
-
- return m_decoder->isSizeAvailable();
-}
-
-IntSize ImageSource::size() const
-{
- if (!m_decoder)
- return IntSize();
-
- return m_decoder->size();
-}
-
-IntSize ImageSource::frameSizeAtIndex(size_t index) const
-{
- if (!m_decoder)
- return IntSize();
-
- return m_decoder->frameSizeAtIndex(index);
-}
-
-int ImageSource::repetitionCount()
-{
- if (!m_decoder)
- return cAnimationNone;
-
- return m_decoder->repetitionCount();
-}
-
-String ImageSource::filenameExtension() const
-{
- notImplemented();
- return String();
-}
-
-size_t ImageSource::frameCount() const
-{
- return m_decoder ? m_decoder->frameCount() : 0;
-}
-
-bool ImageSource::frameIsCompleteAtIndex(size_t index)
-{
- // FIXME: should we be testing the RGBA32Buffer's status as well?
- return (m_decoder && m_decoder->frameBufferAtIndex(index) != 0);
-}
-
-void ImageSource::clear(bool destroyAll, size_t clearBeforeFrame, SharedBuffer* data, bool allDataReceived)
-{
- if (!destroyAll) {
- if (m_decoder)
- m_decoder->clearFrameBufferCache(clearBeforeFrame);
- return;
- }
-
- delete m_decoder;
- m_decoder = 0;
- if (data)
- setData(data, allDataReceived);
-}
-
-NativeImagePtr ImageSource::createFrameAtIndex(size_t index)
-{
- if (!m_decoder)
- return 0;
-
- RGBA32Buffer* buffer = m_decoder->frameBufferAtIndex(index);
- if (!buffer || buffer->status() == RGBA32Buffer::FrameEmpty)
- return 0;
-
- return buffer->asNewNativeImage();
-}
-
-float ImageSource::frameDurationAtIndex(size_t index)
-{
- if (!m_decoder)
- return 0;
-
- RGBA32Buffer* buffer = m_decoder->frameBufferAtIndex(index);
- if (!buffer || buffer->status() == RGBA32Buffer::FrameEmpty)
- return 0;
-
- float duration = buffer->duration() / 1000.0f;
-
- // Follow other ports (and WinIE's) behavior to slow annoying ads that
- // specify a 0 duration.
- if (duration < 0.051f)
- return 0.100f;
- return duration;
-}
-
-bool ImageSource::frameHasAlphaAtIndex(size_t index)
-{
- if (!m_decoder || !m_decoder->supportsAlpha())
- return false;
-
- RGBA32Buffer* buffer = m_decoder->frameBufferAtIndex(index);
- if (!buffer || buffer->status() == RGBA32Buffer::FrameEmpty)
- return false;
-
- return buffer->hasAlpha();
-}
-
-}
diff --git a/WebCore/platform/graphics/wx/ImageWx.cpp b/WebCore/platform/graphics/wx/ImageWx.cpp
index b0a993e..bd129cf 100644
--- a/WebCore/platform/graphics/wx/ImageWx.cpp
+++ b/WebCore/platform/graphics/wx/ImageWx.cpp
@@ -31,6 +31,7 @@
#include "FloatRect.h"
#include "GraphicsContext.h"
#include "ImageObserver.h"
+#include "NotImplemented.h"
#include "TransformationMatrix.h"
#include <math.h>
@@ -45,9 +46,6 @@
#include <wx/image.h>
#include <wx/thread.h>
-// This function loads resources from WebKit
-Vector<char> loadResourceIntoArray(const char*);
-
namespace WebCore {
// this is in GraphicsContextWx.cpp
@@ -72,7 +70,9 @@ bool FrameData::clear(bool clearMetadata)
PassRefPtr<Image> Image::loadPlatformResource(const char *name)
{
- Vector<char> arr = loadResourceIntoArray(name);
+ // FIXME: We need to have some 'placeholder' graphics for things like missing
+ // plugins or broken images.
+ Vector<char> arr;
RefPtr<Image> img = BitmapImage::create();
RefPtr<SharedBuffer> buffer = SharedBuffer::create(arr.data(), arr.size());
img->setData(buffer, true);
@@ -261,4 +261,9 @@ void BitmapImage::invalidatePlatformData()
}
+void Image::drawPattern(GraphicsContext*, const FloatRect& srcRect, const TransformationMatrix& patternTransform, const FloatPoint& phase, CompositeOperator, const FloatRect& destRect)
+{
+ notImplemented();
+}
+
}
diff --git a/WebCore/platform/graphics/wx/IntSizeWx.cpp b/WebCore/platform/graphics/wx/IntSizeWx.cpp
new file mode 100644
index 0000000..8c82854
--- /dev/null
+++ b/WebCore/platform/graphics/wx/IntSizeWx.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2009 Kevin Watters. 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 "IntSize.h"
+
+#include <wx/defs.h>
+#include <wx/gdicmn.h>
+
+namespace WebCore {
+
+IntSize::IntSize(const wxSize& s)
+ : m_width(s.x)
+ , m_height(s.y)
+{
+}
+
+IntSize::operator wxSize() const
+{
+ return wxSize(m_width, m_height);
+}
+
+}
diff --git a/WebCore/platform/gtk/ClipboardGtk.cpp b/WebCore/platform/gtk/ClipboardGtk.cpp
index 8cbf590..450966e 100644
--- a/WebCore/platform/gtk/ClipboardGtk.cpp
+++ b/WebCore/platform/gtk/ClipboardGtk.cpp
@@ -17,11 +17,18 @@
#include "config.h"
#include "ClipboardGtk.h"
+#include "CachedImage.h"
+#include "CString.h"
+#include "Editor.h"
+#include "Element.h"
#include "FileList.h"
+#include "Frame.h"
+#include "markup.h"
#include "NotImplemented.h"
+#include "RenderImage.h"
#include "StringHash.h"
-#include "Editor.h"
+#include <gtk/gtk.h>
namespace WebCore {
@@ -33,12 +40,10 @@ PassRefPtr<Clipboard> Editor::newGeneralClipboard(ClipboardAccessPolicy policy)
ClipboardGtk::ClipboardGtk(ClipboardAccessPolicy policy, bool forDragging)
: Clipboard(policy, forDragging)
{
- notImplemented();
}
ClipboardGtk::~ClipboardGtk()
{
- notImplemented();
}
void ClipboardGtk::clearData(const String&)
@@ -110,19 +115,65 @@ DragImageRef ClipboardGtk::createDragImage(IntPoint&) const
return 0;
}
-void ClipboardGtk::declareAndWriteDragImage(Element*, const KURL&, const String&, Frame*)
+static CachedImage* getCachedImage(Element* element)
{
- notImplemented();
+ // Attempt to pull CachedImage from element
+ ASSERT(element);
+ RenderObject* renderer = element->renderer();
+ if (!renderer || !renderer->isImage())
+ return 0;
+
+ RenderImage* image = static_cast<RenderImage*>(renderer);
+ if (image->cachedImage() && !image->cachedImage()->errorOccurred())
+ return image->cachedImage();
+
+ return 0;
}
-void ClipboardGtk::writeURL(const KURL&, const String&, Frame*)
+void ClipboardGtk::declareAndWriteDragImage(Element* element, const KURL& url, const String& label, Frame*)
{
- notImplemented();
+ CachedImage* cachedImage = getCachedImage(element);
+ if (!cachedImage || !cachedImage->isLoaded())
+ return;
+
+ GdkPixbuf* pixbuf = cachedImage->image()->getGdkPixbuf();
+ if (!pixbuf)
+ return;
+
+ GtkClipboard* imageClipboard = gtk_clipboard_get(gdk_atom_intern_static_string("WebKitClipboardImage"));
+ gtk_clipboard_clear(imageClipboard);
+
+ gtk_clipboard_set_image(imageClipboard, pixbuf);
+ g_object_unref(pixbuf);
+
+ writeURL(url, label, 0);
}
-void ClipboardGtk::writeRange(Range*, Frame*)
+void ClipboardGtk::writeURL(const KURL& url, const String& label, Frame*)
{
- notImplemented();
+ GtkClipboard* textClipboard = gtk_clipboard_get(gdk_atom_intern_static_string("WebKitClipboardText"));
+ GtkClipboard* urlClipboard = gtk_clipboard_get(gdk_atom_intern_static_string("WebKitClipboardUrl"));
+ GtkClipboard* urlLabelClipboard = gtk_clipboard_get(gdk_atom_intern_static_string("WebKitClipboardUrlLabel"));
+
+ gtk_clipboard_clear(textClipboard);
+ gtk_clipboard_clear(urlClipboard);
+ gtk_clipboard_clear(urlLabelClipboard);
+
+ gtk_clipboard_set_text(textClipboard, url.string().utf8().data(), -1);
+ gtk_clipboard_set_text(urlClipboard, url.string().utf8().data(), -1);
+ gtk_clipboard_set_text(urlLabelClipboard, label.utf8().data(), -1);
+}
+
+void ClipboardGtk::writeRange(Range* range, Frame* frame)
+{
+ GtkClipboard* textClipboard = gtk_clipboard_get(gdk_atom_intern_static_string("WebKitClipboardText"));
+ GtkClipboard* htmlClipboard = gtk_clipboard_get(gdk_atom_intern_static_string("WebKitClipboardHtml"));
+
+ gtk_clipboard_clear(textClipboard);
+ gtk_clipboard_clear(htmlClipboard);
+
+ gtk_clipboard_set_text(textClipboard, frame->selectedText().utf8().data(), -1);
+ gtk_clipboard_set_text(htmlClipboard, createMarkup(range, 0, AnnotateForInterchange).utf8().data(), -1);
}
bool ClipboardGtk::hasData()
diff --git a/WebCore/platform/gtk/ClipboardGtk.h b/WebCore/platform/gtk/ClipboardGtk.h
index 7314ae4..bb21d92 100644
--- a/WebCore/platform/gtk/ClipboardGtk.h
+++ b/WebCore/platform/gtk/ClipboardGtk.h
@@ -24,8 +24,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ClipboardGdk_h
-#define ClipboardGdk_h
+#ifndef ClipboardGtk_h
+#define ClipboardGtk_h
#include "Clipboard.h"
diff --git a/WebCore/platform/gtk/CursorGtk.cpp b/WebCore/platform/gtk/CursorGtk.cpp
index 115760e..1c669f3 100644
--- a/WebCore/platform/gtk/CursorGtk.cpp
+++ b/WebCore/platform/gtk/CursorGtk.cpp
@@ -28,6 +28,9 @@
#include "config.h"
#include "CursorGtk.h"
+#include "Image.h"
+#include "IntPoint.h"
+
#include <wtf/Assertions.h>
#include <gdk/gdk.h>
@@ -60,15 +63,11 @@ Cursor::Cursor(const Cursor& other)
gdk_cursor_ref(m_impl);
}
-Cursor::Cursor(Image*, const IntPoint&)
+Cursor::Cursor(Image* image, const IntPoint& hotSpot)
{
- // FIXME: We don't support images for cursors yet.
- // This is just a placeholder to avoid crashes.
- Cursor other(crossCursor());
- m_impl = other.m_impl;
-
- if (m_impl)
- gdk_cursor_ref(m_impl);
+ GdkPixbuf* pixbuf = image->getGdkPixbuf();
+ m_impl = gdk_cursor_new_from_pixbuf(gdk_display_get_default(), pixbuf, hotSpot.x(), hotSpot.y());
+ g_object_unref(pixbuf);
}
Cursor::~Cursor()
diff --git a/WebCore/platform/gtk/GeolocationServiceGtk.cpp b/WebCore/platform/gtk/GeolocationServiceGtk.cpp
index fc15833..cf35346 100644
--- a/WebCore/platform/gtk/GeolocationServiceGtk.cpp
+++ b/WebCore/platform/gtk/GeolocationServiceGtk.cpp
@@ -37,11 +37,13 @@ namespace WTF {
namespace WebCore {
-GeolocationService* GeolocationService::create(GeolocationServiceClient* client)
+GeolocationService* GeolocationServiceGtk::create(GeolocationServiceClient* client)
{
return new GeolocationServiceGtk(client);
}
+GeolocationService::FactoryFunction* GeolocationService::s_factoryFunction = &GeolocationServiceGtk::create;
+
GeolocationServiceGtk::GeolocationServiceGtk(GeolocationServiceClient* client)
: GeolocationService(client)
, m_geoclueClient(0)
diff --git a/WebCore/platform/gtk/GeolocationServiceGtk.h b/WebCore/platform/gtk/GeolocationServiceGtk.h
index 90699ad..a198dc0 100644
--- a/WebCore/platform/gtk/GeolocationServiceGtk.h
+++ b/WebCore/platform/gtk/GeolocationServiceGtk.h
@@ -31,7 +31,7 @@
namespace WebCore {
class GeolocationServiceGtk : public GeolocationService {
public:
- GeolocationServiceGtk(GeolocationServiceClient*);
+ static GeolocationService* create(GeolocationServiceClient*);
~GeolocationServiceGtk();
virtual bool startUpdating(PositionOptions*);
@@ -44,6 +44,8 @@ namespace WebCore {
PositionError* lastError() const;
private:
+ GeolocationServiceGtk(GeolocationServiceClient*);
+
void updateLocationInformation();
void setError(PositionError::ErrorCode, const char* message);
void updatePosition();
diff --git a/WebCore/platform/gtk/KeyEventGtk.cpp b/WebCore/platform/gtk/KeyEventGtk.cpp
index 5875547..4186c2f 100644
--- a/WebCore/platform/gtk/KeyEventGtk.cpp
+++ b/WebCore/platform/gtk/KeyEventGtk.cpp
@@ -136,6 +136,8 @@ static String keyIdentifierForGdkKeyCode(guint keyCode)
// Standard says that DEL becomes U+007F.
case GDK_Delete:
return "U+007F";
+ case GDK_BackSpace:
+ return "U+0008";
case GDK_ISO_Left_Tab:
case GDK_3270_BackTab:
case GDK_Tab:
@@ -503,6 +505,8 @@ static String singleCharacterString(guint val)
case GDK_KP_Enter:
case GDK_Return:
return String("\r");
+ case GDK_BackSpace:
+ return String("\x8");
default:
gunichar c = gdk_keyval_to_unicode(val);
glong nwc;
diff --git a/WebCore/platform/gtk/LocalizedStringsGtk.cpp b/WebCore/platform/gtk/LocalizedStringsGtk.cpp
index 2ba4fbb..85e071b 100644
--- a/WebCore/platform/gtk/LocalizedStringsGtk.cpp
+++ b/WebCore/platform/gtk/LocalizedStringsGtk.cpp
@@ -345,6 +345,9 @@ String imageTitle(const String& filename, const IntSize& size)
return String::fromUTF8(string.get());
}
+
+#if ENABLE(VIDEO)
+
String mediaElementLoadingStateText()
{
return String::fromUTF8(_("Loading..."));
@@ -355,4 +358,113 @@ String mediaElementLiveBroadcastStateText()
return String::fromUTF8(_("Live Broadcast"));
}
+String localizedMediaControlElementString(const String& name)
+{
+ if (name == "AudioElement")
+ return String::fromUTF8(_("audio element controller"));
+ if (name == "VideoElement")
+ return String::fromUTF8(_("video element controller"));
+ if (name == "MuteButton")
+ return String::fromUTF8(_("mute"));
+ if (name == "UnMuteButton")
+ return String::fromUTF8(_("unmute"));
+ if (name == "PlayButton")
+ return String::fromUTF8(_("play"));
+ if (name == "PauseButton")
+ return String::fromUTF8(_("pause"));
+ if (name == "Slider")
+ return String::fromUTF8(_("movie time"));
+ if (name == "SliderThumb")
+ return String::fromUTF8(_("timeline slider thumb"));
+ if (name == "RewindButton")
+ return String::fromUTF8(_("back 30 seconds"));
+ if (name == "ReturnToRealtimeButton")
+ return String::fromUTF8(_("return to realtime"));
+ if (name == "CurrentTimeDisplay")
+ return String::fromUTF8(_("elapsed time"));
+ if (name == "TimeRemainingDisplay")
+ return String::fromUTF8(_("remaining time"));
+ if (name == "StatusDisplay")
+ return String::fromUTF8(_("status"));
+ if (name == "FullscreenButton")
+ return String::fromUTF8(_("fullscreen"));
+ if (name == "SeekForwardButton")
+ return String::fromUTF8(_("fast forward"));
+ if (name == "SeekBackButton")
+ return String::fromUTF8(_("fast reverse"));
+
+ ASSERT_NOT_REACHED();
+ return String();
+}
+
+String localizedMediaControlElementHelpText(const String& name)
+{
+ if (name == "AudioElement")
+ return String::fromUTF8(_("audio element playback controls and status display"));
+ if (name == "VideoElement")
+ return String::fromUTF8(_("video element playback controls and status display"));
+ if (name == "MuteButton")
+ return String::fromUTF8(_("mute audio tracks"));
+ if (name == "UnMuteButton")
+ return String::fromUTF8(_("unmute audio tracks"));
+ if (name == "PlayButton")
+ return String::fromUTF8(_("begin playback"));
+ if (name == "PauseButton")
+ return String::fromUTF8(_("pause playback"));
+ if (name == "Slider")
+ return String::fromUTF8(_("movie time scrubber"));
+ if (name == "SliderThumb")
+ return String::fromUTF8(_("movie time scrubber thumb"));
+ if (name == "RewindButton")
+ return String::fromUTF8(_("seek movie back 30 seconds"));
+ if (name == "ReturnToRealtimeButton")
+ return String::fromUTF8(_("return streaming movie to real time"));
+ if (name == "CurrentTimeDisplay")
+ return String::fromUTF8(_("current movie time in seconds"));
+ if (name == "TimeRemainingDisplay")
+ return String::fromUTF8(_("number of seconds of movie remaining"));
+ if (name == "StatusDisplay")
+ return String::fromUTF8(_("current movie status"));
+ if (name == "SeekBackButton")
+ return String::fromUTF8(_("seek quickly back"));
+ if (name == "SeekForwardButton")
+ return String::fromUTF8(_("seek quickly forward"));
+ if (name == "FullscreenButton")
+ return String::fromUTF8(_("Play movie in fullscreen mode"));
+
+ ASSERT_NOT_REACHED();
+ return String();
+}
+
+String localizedMediaTimeDescription(float time)
+{
+ if (!isfinite(time))
+ return String::fromUTF8(_("indefinite time"));
+
+ int seconds = (int)fabsf(time);
+ int days = seconds / (60 * 60 * 24);
+ int hours = seconds / (60 * 60);
+ int minutes = (seconds / 60) % 60;
+ seconds %= 60;
+
+ if (days) {
+ GOwnPtr<gchar> string(g_strdup_printf("%d days %d hours %d minutes %d seconds", days, hours, minutes, seconds));
+ return String::fromUTF8(string.get());
+ }
+
+ if (hours) {
+ GOwnPtr<gchar> string(g_strdup_printf("%d hours %d minutes %d seconds", hours, minutes, seconds));
+ return String::fromUTF8(string.get());
+ }
+
+ if (minutes) {
+ GOwnPtr<gchar> string(g_strdup_printf("%d minutes %d seconds", minutes, seconds));
+ return String::fromUTF8(string.get());
+ }
+
+ GOwnPtr<gchar> string(g_strdup_printf("%d seconds", seconds));
+ return String::fromUTF8(string.get());
+}
+#endif // ENABLE(VIDEO)
+
}
diff --git a/WebCore/platform/gtk/PasteboardGtk.cpp b/WebCore/platform/gtk/PasteboardGtk.cpp
index 9f72923..0ff26f7 100644
--- a/WebCore/platform/gtk/PasteboardGtk.cpp
+++ b/WebCore/platform/gtk/PasteboardGtk.cpp
@@ -35,13 +35,6 @@
namespace WebCore {
-/* FIXME: we must get rid of this and use the enum in webkitwebview.h someway */
-typedef enum
-{
- WEBKIT_WEB_VIEW_TARGET_INFO_HTML = - 1,
- WEBKIT_WEB_VIEW_TARGET_INFO_TEXT = - 2
-} WebKitWebViewTargetInfo;
-
class PasteboardSelectionData {
public:
PasteboardSelectionData(gchar* text, gchar* markup)
@@ -65,11 +58,11 @@ static void clipboard_get_contents_cb(GtkClipboard *clipboard, GtkSelectionData
guint info, gpointer data) {
PasteboardSelectionData* clipboardData = reinterpret_cast<PasteboardSelectionData*>(data);
ASSERT(clipboardData);
- if ((gint)info == WEBKIT_WEB_VIEW_TARGET_INFO_HTML) {
+ if ((gint)info == Pasteboard::generalPasteboard()->m_helper->getWebViewTargetInfoHtml())
gtk_selection_data_set(selection_data, selection_data->target, 8,
reinterpret_cast<const guchar*>(clipboardData->markup()),
g_utf8_strlen(clipboardData->markup(), -1));
- } else
+ else
gtk_selection_data_set_text(selection_data, clipboardData->text(), -1);
}
@@ -115,6 +108,13 @@ void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete,
gtk_target_table_free(targets, n_targets);
}
+void Pasteboard::writePlainText(const String& text)
+{
+ CString utf8 = text.utf8();
+ GtkClipboard* clipboard = gtk_clipboard_get_for_display(gdk_display_get_default(), GDK_SELECTION_CLIPBOARD);
+ gtk_clipboard_set_text(clipboard, utf8.data(), utf8.length());
+}
+
void Pasteboard::writeURL(const KURL& url, const String&, Frame* frame)
{
if (url.isEmpty())
@@ -122,8 +122,9 @@ void Pasteboard::writeURL(const KURL& url, const String&, Frame* frame)
GtkClipboard* clipboard = m_helper->getClipboard(frame);
GtkClipboard* primary = m_helper->getPrimary(frame);
- gtk_clipboard_set_text(clipboard, url.string().utf8().data(), url.string().utf8().length());
- gtk_clipboard_set_text(primary, url.string().utf8().data(), url.string().utf8().length());
+ CString utf8 = url.string().utf8();
+ gtk_clipboard_set_text(clipboard, utf8.data(), utf8.length());
+ gtk_clipboard_set_text(primary, utf8.data(), utf8.length());
}
void Pasteboard::writeImage(Node* node, const KURL&, const String&)
diff --git a/WebCore/platform/gtk/PasteboardHelper.h b/WebCore/platform/gtk/PasteboardHelper.h
index 9943a2d..8e67127 100644
--- a/WebCore/platform/gtk/PasteboardHelper.h
+++ b/WebCore/platform/gtk/PasteboardHelper.h
@@ -43,6 +43,7 @@ public:
virtual GtkClipboard* getPrimary(Frame*) const = 0;
virtual GtkTargetList* getCopyTargetList(Frame*) const = 0;
virtual GtkTargetList* getPasteTargetList(Frame*) const = 0;
+ virtual gint getWebViewTargetInfoHtml() const = 0;
};
}
diff --git a/WebCore/platform/gtk/PlatformScreenGtk.cpp b/WebCore/platform/gtk/PlatformScreenGtk.cpp
index 4ba6d43..a6ff954 100644
--- a/WebCore/platform/gtk/PlatformScreenGtk.cpp
+++ b/WebCore/platform/gtk/PlatformScreenGtk.cpp
@@ -49,7 +49,7 @@ static GdkVisual* getVisual(Widget* widget)
if (!widget)
return 0;
- GtkWidget* container = GTK_WIDGET(widget->root()->hostWindow()->platformWindow());
+ GtkWidget* container = GTK_WIDGET(widget->root()->hostWindow()->platformPageClient());
if (!container)
return 0;
@@ -93,7 +93,7 @@ FloatRect screenRect(Widget* widget)
if (!widget)
return FloatRect();
- GtkWidget* container = gtk_widget_get_toplevel(GTK_WIDGET(widget->root()->hostWindow()->platformWindow()));
+ GtkWidget* container = gtk_widget_get_toplevel(GTK_WIDGET(widget->root()->hostWindow()->platformPageClient()));
if (!GTK_WIDGET_TOPLEVEL(container))
return FloatRect();
@@ -114,7 +114,7 @@ FloatRect screenAvailableRect(Widget* widget)
return FloatRect();
#if PLATFORM(X11)
- GtkWidget* container = GTK_WIDGET(widget->root()->hostWindow()->platformWindow());
+ GtkWidget* container = GTK_WIDGET(widget->root()->hostWindow()->platformPageClient());
if (!container)
return FloatRect();
diff --git a/WebCore/platform/gtk/PopupMenuGtk.cpp b/WebCore/platform/gtk/PopupMenuGtk.cpp
index 121d7b0..3f6b02a 100644
--- a/WebCore/platform/gtk/PopupMenuGtk.cpp
+++ b/WebCore/platform/gtk/PopupMenuGtk.cpp
@@ -60,7 +60,7 @@ void PopupMenu::show(const IntRect& rect, FrameView* view, int index)
gtk_container_foreach(GTK_CONTAINER(m_popup), reinterpret_cast<GtkCallback>(menuRemoveItem), this);
int x, y;
- gdk_window_get_origin(GTK_WIDGET(view->hostWindow()->platformWindow())->window, &x, &y);
+ gdk_window_get_origin(GTK_WIDGET(view->hostWindow()->platformPageClient())->window, &x, &y);
m_menuPosition = view->contentsToWindow(rect.location());
m_menuPosition = IntPoint(m_menuPosition.x() + x, m_menuPosition.y() + y + rect.height());
m_indexMap.clear();
@@ -137,7 +137,7 @@ void PopupMenu::menuItemActivated(GtkMenuItem* item, PopupMenu* that)
void PopupMenu::menuUnmapped(GtkWidget*, PopupMenu* that)
{
ASSERT(that->client());
- that->client()->hidePopup();
+ that->client()->popupDidHide();
}
void PopupMenu::menuPositionFunction(GtkMenu*, gint* x, gint* y, gboolean* pushIn, PopupMenu* that)
diff --git a/WebCore/platform/gtk/ScrollViewGtk.cpp b/WebCore/platform/gtk/ScrollViewGtk.cpp
index 0e811ef..a1ed8c3 100644
--- a/WebCore/platform/gtk/ScrollViewGtk.cpp
+++ b/WebCore/platform/gtk/ScrollViewGtk.cpp
@@ -31,10 +31,14 @@
#include "config.h"
#include "ScrollView.h"
+#include "ChromeClient.h"
#include "FloatRect.h"
+#include "Frame.h"
+#include "FrameView.h"
#include "GraphicsContext.h"
#include "HostWindow.h"
#include "IntRect.h"
+#include "Page.h"
#include "PlatformMouseEvent.h"
#include "PlatformWheelEvent.h"
#include "ScrollbarGtk.h"
@@ -103,7 +107,7 @@ void ScrollView::setGtkAdjustments(GtkAdjustment* hadj, GtkAdjustment* vadj)
void ScrollView::platformAddChild(Widget* child)
{
if (!GTK_IS_SOCKET(child->platformWidget()))
- gtk_container_add(GTK_CONTAINER(hostWindow()->platformWindow()), child->platformWidget());
+ gtk_container_add(GTK_CONTAINER(hostWindow()->platformPageClient()), child->platformWidget());
}
void ScrollView::platformRemoveChild(Widget* child)
@@ -113,7 +117,7 @@ void ScrollView::platformRemoveChild(Widget* child)
// HostWindow can be NULL here. If that's the case
// let's grab the child's parent instead.
if (hostWindow())
- parent = GTK_WIDGET(hostWindow()->platformWindow());
+ parent = GTK_WIDGET(hostWindow()->platformPageClient());
else
parent = GTK_WIDGET(child->platformWidget()->parent);
@@ -129,7 +133,7 @@ IntRect ScrollView::visibleContentRect(bool includeScrollbars) const
max(0, height() - (horizontalScrollbar() && !includeScrollbars ? horizontalScrollbar()->height() : 0))));
// Main frame.
- GtkWidget* measuredWidget = hostWindow()->platformWindow();
+ GtkWidget* measuredWidget = hostWindow()->platformPageClient();
GtkWidget* parent = gtk_widget_get_parent(measuredWidget);
// We may not be in a widget that displays scrollbars, but we may
@@ -142,4 +146,29 @@ IntRect ScrollView::visibleContentRect(bool includeScrollbars) const
measuredWidget->allocation.height));
}
+void ScrollView::setScrollbarModes(ScrollbarMode horizontalMode, ScrollbarMode verticalMode)
+{
+ if (horizontalMode == m_horizontalScrollbarMode && verticalMode == m_verticalScrollbarMode)
+ return;
+
+ m_horizontalScrollbarMode = horizontalMode;
+ m_verticalScrollbarMode = verticalMode;
+
+ // We don't really care about reporting policy changes on frames
+ // that have no adjustments attached to them.
+ if (!m_horizontalAdjustment) {
+ updateScrollbars(scrollOffset());
+ return;
+ }
+
+ if (!isFrameView())
+ return;
+
+ // For frames that do have adjustments attached, we want to report
+ // policy changes, so that they may be applied to the widget to
+ // which the WebView has been added, for instance.
+ if (hostWindow())
+ hostWindow()->scrollbarsModeDidChange();
+}
+
}
diff --git a/WebCore/platform/gtk/WidgetGtk.cpp b/WebCore/platform/gtk/WidgetGtk.cpp
index 007f2ee..53c10f1 100644
--- a/WebCore/platform/gtk/WidgetGtk.cpp
+++ b/WebCore/platform/gtk/WidgetGtk.cpp
@@ -55,7 +55,7 @@ Widget::~Widget()
void Widget::setFocus()
{
- gtk_widget_grab_focus(platformWidget() ? platformWidget() : GTK_WIDGET(root()->hostWindow()->platformWindow()));
+ gtk_widget_grab_focus(platformWidget() ? platformWidget() : GTK_WIDGET(root()->hostWindow()->platformPageClient()));
}
static GdkDrawable* gdkDrawable(PlatformWidget widget)
@@ -76,7 +76,7 @@ void Widget::setCursor(const Cursor& cursor)
if (platformCursor == lastSetCursor)
return;
- gdk_window_set_cursor(gdkDrawable(platformWidget()) ? GDK_WINDOW(gdkDrawable(platformWidget())) : GTK_WIDGET(root()->hostWindow()->platformWindow())->window, platformCursor);
+ gdk_window_set_cursor(gdkDrawable(platformWidget()) ? GDK_WINDOW(gdkDrawable(platformWidget())) : GTK_WIDGET(root()->hostWindow()->platformPageClient())->window, platformCursor);
lastSetCursor = platformCursor;
}
diff --git a/WebCore/platform/haiku/ClipboardHaiku.cpp b/WebCore/platform/haiku/ClipboardHaiku.cpp
index 845c08c..a62c30c 100644
--- a/WebCore/platform/haiku/ClipboardHaiku.cpp
+++ b/WebCore/platform/haiku/ClipboardHaiku.cpp
@@ -27,8 +27,8 @@
#include "config.h"
#include "ClipboardHaiku.h"
-#include "IntPoint.h"
#include "FileList.h"
+#include "IntPoint.h"
#include "NotImplemented.h"
#include "PlatformString.h"
#include "StringHash.h"
@@ -42,7 +42,7 @@
namespace WebCore {
-ClipboardHaiku::ClipboardHaiku(ClipboardAccessPolicy policy, bool forDragging)
+ClipboardHaiku::ClipboardHaiku(ClipboardAccessPolicy policy, bool forDragging)
: Clipboard(policy, forDragging)
{
}
@@ -61,7 +61,7 @@ void ClipboardHaiku::clearData(const String& type)
}
}
-void ClipboardHaiku::clearAllData()
+void ClipboardHaiku::clearAllData()
{
if (be_clipboard->Lock()) {
be_clipboard->Clear();
@@ -70,7 +70,7 @@ void ClipboardHaiku::clearAllData()
}
}
-String ClipboardHaiku::getData(const String& type, bool& success) const
+String ClipboardHaiku::getData(const String& type, bool& success) const
{
BString result;
success = false;
@@ -88,7 +88,7 @@ String ClipboardHaiku::getData(const String& type, bool& success) const
return result;
}
-bool ClipboardHaiku::setData(const String& type, const String& data)
+bool ClipboardHaiku::setData(const String& type, const String& data)
{
bool result = false;
@@ -110,7 +110,7 @@ bool ClipboardHaiku::setData(const String& type, const String& data)
}
// Extensions beyond IE's API.
-HashSet<String> ClipboardHaiku::types() const
+HashSet<String> ClipboardHaiku::types() const
{
HashSet<String> result;
@@ -138,27 +138,27 @@ PassRefPtr<FileList> ClipboardHaiku::files() const
return 0;
}
-IntPoint ClipboardHaiku::dragLocation() const
-{
+IntPoint ClipboardHaiku::dragLocation() const
+{
notImplemented();
return IntPoint(0, 0);
}
-CachedImage* ClipboardHaiku::dragImage() const
+CachedImage* ClipboardHaiku::dragImage() const
{
notImplemented();
- return 0;
+ return 0;
}
-void ClipboardHaiku::setDragImage(CachedImage*, const IntPoint&)
+void ClipboardHaiku::setDragImage(CachedImage*, const IntPoint&)
{
notImplemented();
}
-Node* ClipboardHaiku::dragImageElement()
+Node* ClipboardHaiku::dragImageElement()
{
notImplemented();
- return 0;
+ return 0;
}
void ClipboardHaiku::setDragImageElement(Node*, const IntPoint&)
@@ -167,27 +167,27 @@ void ClipboardHaiku::setDragImageElement(Node*, const IntPoint&)
}
DragImageRef ClipboardHaiku::createDragImage(IntPoint& dragLocation) const
-{
+{
notImplemented();
return 0;
}
-void ClipboardHaiku::declareAndWriteDragImage(Element*, const KURL&, const String&, Frame*)
+void ClipboardHaiku::declareAndWriteDragImage(Element*, const KURL&, const String&, Frame*)
{
notImplemented();
}
-void ClipboardHaiku::writeURL(const KURL&, const String&, Frame*)
+void ClipboardHaiku::writeURL(const KURL&, const String&, Frame*)
{
notImplemented();
}
-void ClipboardHaiku::writeRange(Range*, Frame*)
+void ClipboardHaiku::writeRange(Range*, Frame*)
{
notImplemented();
}
-bool ClipboardHaiku::hasData()
+bool ClipboardHaiku::hasData()
{
bool result = false;
diff --git a/WebCore/platform/haiku/ContextMenuHaiku.cpp b/WebCore/platform/haiku/ContextMenuHaiku.cpp
index 03b8978..b978433 100644
--- a/WebCore/platform/haiku/ContextMenuHaiku.cpp
+++ b/WebCore/platform/haiku/ContextMenuHaiku.cpp
@@ -27,30 +27,27 @@
#include "config.h"
#include "ContextMenu.h"
-#include "ContextMenuItem.h"
#include "ContextMenuController.h"
+#include "ContextMenuItem.h"
+#include "Document.h"
#include "Frame.h"
#include "FrameView.h"
-#include "Document.h"
-
-#include <wtf/Assertions.h>
-
#include <Looper.h>
#include <Menu.h>
#include <Message.h>
+#include <wtf/Assertions.h>
namespace WebCore {
// FIXME: This class isn't used yet
-class ContextMenuReceiver : public BLooper
-{
+class ContextMenuReceiver : public BLooper {
public:
ContextMenuReceiver(ContextMenu* menu)
: BLooper("context_menu_receiver")
, m_menu(menu)
+ , m_result(-1)
{
- m_result = -1;
}
void HandleMessage(BMessage* msg)
@@ -80,21 +77,8 @@ private:
ContextMenu::ContextMenu(const HitTestResult& result)
: m_hitTestResult(result)
- , m_platformDescription(NULL)
+ , m_platformDescription(new BMenu("context_menu"))
{
- /* Get position */
- if (result.innerNode() && result.innerNode()->document()) {
- BView* view = result.innerNode()->document()->frame()->view()->platformWidget();
- int child = 0;
- while (view->ChildAt(child)) {
- if (view->ChildAt(child)->Name() == "scroll_view_canvas") {
- m_point = view->ChildAt(child)->ConvertToScreen(BPoint(result.point().x(), result.point().y()));
- break;
- }
- child++;
- }
- }
- m_platformDescription = new BMenu("context_menu");
}
ContextMenu::~ContextMenu()
@@ -106,9 +90,9 @@ void ContextMenu::appendItem(ContextMenuItem& item)
{
checkOrEnableIfNeeded(item);
- BMenuItem* bItem = item.releasePlatformDescription();
- if (bItem)
- m_platformDescription->AddItem(bItem);
+ BMenuItem* menuItem = item.releasePlatformDescription();
+ if (menuItem)
+ m_platformDescription->AddItem(menuItem);
}
unsigned ContextMenu::itemCount() const
@@ -120,9 +104,9 @@ void ContextMenu::insertItem(unsigned position, ContextMenuItem& item)
{
checkOrEnableIfNeeded(item);
- BMenuItem* bItem = item.releasePlatformDescription();
- if (bItem)
- m_platformDescription->AddItem(bItem, position);
+ BMenuItem* menuItem = item.releasePlatformDescription();
+ if (menuItem)
+ m_platformDescription->AddItem(menuItem, position);
}
PlatformMenuDescription ContextMenu::platformDescription() const
diff --git a/WebCore/platform/haiku/CookieJarHaiku.cpp b/WebCore/platform/haiku/CookieJarHaiku.cpp
index 73519d7..831b379 100644
--- a/WebCore/platform/haiku/CookieJarHaiku.cpp
+++ b/WebCore/platform/haiku/CookieJarHaiku.cpp
@@ -29,6 +29,7 @@
#include "config.h"
#include "CookieJar.h"
+#include "Cookie.h"
#include "KURL.h"
#include "PlatformString.h"
#include "StringHash.h"
@@ -41,21 +42,33 @@ namespace WebCore {
// FIXME: Shouldn't this be saved to and restored from disk too?
static HashMap<String, String> cookieJar;
-void setCookies(const KURL& url, const KURL& /*policyURL*/, const String& value)
+void setCookies(Document*, const KURL& url, const String& value)
{
cookieJar.set(url.string(), value);
}
-String cookies(const KURL& url)
+String cookies(const Document*, const KURL& url)
{
return cookieJar.get(url.string());
}
-bool cookiesEnabled()
+bool cookiesEnabled(const Document*)
{
// FIXME: This should probably be a setting
return true;
}
+bool getRawCookies(const Document*, const KURL&, Vector<Cookie>& rawCookies)
+{
+ // FIXME: Not yet implemented
+ rawCookies.clear();
+ return false; // return true when implemented
+}
+
+void deleteCookie(const Document*, const KURL&, const String&)
+{
+ // FIXME: Not yet implemented
+}
+
} // namespace WebCore
diff --git a/WebCore/platform/haiku/DragDataHaiku.cpp b/WebCore/platform/haiku/DragDataHaiku.cpp
index b42b311..4a20147 100644
--- a/WebCore/platform/haiku/DragDataHaiku.cpp
+++ b/WebCore/platform/haiku/DragDataHaiku.cpp
@@ -27,10 +27,9 @@
#include "config.h"
#include "DragData.h"
+#include "ClipboardHaiku.h"
#include "Document.h"
#include "DocumentFragment.h"
-#include "ClipboardHaiku.h"
-
#include "NotImplemented.h"
@@ -79,7 +78,7 @@ Color DragData::asColor() const
WTF::PassRefPtr<Clipboard> DragData::createClipboard(ClipboardAccessPolicy policy) const
{
- return new ClipboardHaiku(policy, true);
+ return ClipboardHaiku::create(policy, true);
}
bool DragData::containsCompatibleContent() const
@@ -104,6 +103,6 @@ PassRefPtr<DocumentFragment> DragData::asFragment(Document*) const
notImplemented();
return 0;
}
-
+
} // namespace WebCore
diff --git a/WebCore/platform/haiku/LocalizedStringsHaiku.cpp b/WebCore/platform/haiku/LocalizedStringsHaiku.cpp
new file mode 100644
index 0000000..a37ffcc
--- /dev/null
+++ b/WebCore/platform/haiku/LocalizedStringsHaiku.cpp
@@ -0,0 +1,346 @@
+/*
+ * Copyright (C) 2009 Maxime Simon <simon.maxime@gmail.com>
+ *
+ * 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 "LocalizedStrings.h"
+
+#include "PlatformString.h"
+
+
+namespace WebCore {
+String submitButtonDefaultLabel()
+{
+ return "Submit";
+}
+
+String inputElementAltText()
+{
+ return String();
+}
+
+String resetButtonDefaultLabel()
+{
+ return "Reset";
+}
+
+String defaultLanguage()
+{
+ return "en";
+}
+
+String searchableIndexIntroduction()
+{
+ return "Searchable Index";
+}
+
+String fileButtonChooseFileLabel()
+{
+ return "Choose File";
+}
+
+String fileButtonNoFileSelectedLabel()
+{
+ return "No file selected";
+}
+
+String contextMenuItemTagOpenLinkInNewWindow()
+{
+ return "Open in new tab";
+}
+
+String contextMenuItemTagDownloadLinkToDisk()
+{
+ return "Download link to disk";
+}
+
+String contextMenuItemTagCopyLinkToClipboard()
+{
+ return "Copy link to clipboard";
+}
+
+String contextMenuItemTagOpenImageInNewWindow()
+{
+ return "Open image in new window";
+}
+
+String contextMenuItemTagDownloadImageToDisk()
+{
+ return "Download image to disk";
+}
+
+String contextMenuItemTagCopyImageToClipboard()
+{
+ return "Copy image to clipboard";
+}
+
+String contextMenuItemTagOpenFrameInNewWindow()
+{
+ return "Open frame in new window";
+}
+
+String contextMenuItemTagCopy()
+{
+ return "Copy";
+}
+
+String contextMenuItemTagGoBack()
+{
+ return "Go back";
+}
+
+String contextMenuItemTagGoForward()
+{
+ return "Go forward";
+}
+
+String contextMenuItemTagStop()
+{
+ return "Stop";
+}
+
+String contextMenuItemTagReload()
+{
+ return "Reload";
+}
+
+String contextMenuItemTagCut()
+{
+ return "Cut";
+}
+
+String contextMenuItemTagPaste()
+{
+ return "Paste";
+}
+
+String contextMenuItemTagNoGuessesFound()
+{
+ return "No guesses found";
+}
+
+String contextMenuItemTagIgnoreSpelling()
+{
+ return "Ignore spelling";
+}
+
+String contextMenuItemTagLearnSpelling()
+{
+ return "Learn spelling";
+}
+
+String contextMenuItemTagSearchWeb()
+{
+ return "Search web";
+}
+
+String contextMenuItemTagLookUpInDictionary()
+{
+ return "Lookup in dictionary";
+}
+
+String contextMenuItemTagOpenLink()
+{
+ return "Open link";
+}
+
+String contextMenuItemTagIgnoreGrammar()
+{
+ return "Ignore grammar";
+}
+
+String contextMenuItemTagSpellingMenu()
+{
+ return "Spelling menu";
+}
+
+String contextMenuItemTagShowSpellingPanel(bool show)
+{
+ return "Show spelling panel";
+}
+
+String contextMenuItemTagCheckSpelling()
+{
+ return "Check spelling";
+}
+
+String contextMenuItemTagCheckSpellingWhileTyping()
+{
+ return "Check spelling while typing";
+}
+
+String contextMenuItemTagCheckGrammarWithSpelling()
+{
+ return "Check for grammar with spelling";
+}
+
+String contextMenuItemTagFontMenu()
+{
+ return "Font menu";
+}
+
+String contextMenuItemTagBold()
+{
+ return "Bold";
+}
+
+String contextMenuItemTagItalic()
+{
+ return "Italic";
+}
+
+String contextMenuItemTagUnderline()
+{
+ return "Underline";
+}
+
+String contextMenuItemTagOutline()
+{
+ return "Outline";
+}
+
+String contextMenuItemTagWritingDirectionMenu()
+{
+ return "Writing direction menu";
+}
+
+String contextMenuItemTagDefaultDirection()
+{
+ return "Default direction";
+}
+
+String contextMenuItemTagLeftToRight()
+{
+ return "Left to right";
+}
+
+String contextMenuItemTagRightToLeft()
+{
+ return "Right to left";
+}
+
+String contextMenuItemTagInspectElement()
+{
+ return "Inspect";
+}
+
+String searchMenuNoRecentSearchesText()
+{
+ return "No recent text searches";
+}
+
+String searchMenuRecentSearchesText()
+{
+ return "Recent text searches";
+}
+
+String searchMenuClearRecentSearchesText()
+{
+ return "Clear recent text searches";
+}
+
+String unknownFileSizeText()
+{
+ return "Unknown";
+}
+
+String AXWebAreaText()
+{
+ return String();
+}
+
+String AXLinkText()
+{
+ return String();
+}
+
+String AXListMarkerText()
+{
+ return String();
+}
+
+String AXImageMapText()
+{
+ return String();
+}
+
+String AXHeadingText()
+{
+ return String();
+}
+
+String imageTitle(const String& filename, const IntSize& size)
+{
+ return String(filename);
+}
+
+String contextMenuItemTagTextDirectionMenu()
+{
+ return String();
+}
+
+String AXButtonActionVerb()
+{
+ return String();
+}
+
+String AXTextFieldActionVerb()
+{
+ return String();
+}
+
+String AXRadioButtonActionVerb()
+{
+ return String();
+}
+
+String AXCheckedCheckBoxActionVerb()
+{
+ return String();
+}
+
+String AXUncheckedCheckBoxActionVerb()
+{
+ return String();
+}
+
+String AXLinkActionVerb()
+{
+ return String();
+}
+
+String AXDefinitionListTermText()
+{
+ return String();
+}
+
+String AXDefinitionListDefinitionText()
+{
+ return String();
+}
+
+} // namespace WebCore
+
diff --git a/WebCore/platform/haiku/LoggingHaiku.cpp b/WebCore/platform/haiku/LoggingHaiku.cpp
new file mode 100644
index 0000000..f09c483
--- /dev/null
+++ b/WebCore/platform/haiku/LoggingHaiku.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2009 Maxime Simon <simon.maxime@gmail.com>
+ *
+ * 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 "Logging.h"
+
+
+namespace WebCore {
+
+void InitializeLoggingChannelsIfNecessary()
+{
+ // FIXME: Should read the logging channels from a file.
+ static bool haveInitializedLoggingChannels = false;
+ if (haveInitializedLoggingChannels)
+ return;
+
+ haveInitializedLoggingChannels = true;
+
+ LogEvents.state = WTFLogChannelOn;
+ LogFrames.state = WTFLogChannelOn;
+ LogLoading.state = WTFLogChannelOn;
+ LogPlatformLeaks.state = WTFLogChannelOn;
+}
+
+} // namespace WebCore
+
diff --git a/WebCore/platform/haiku/PasteboardHaiku.cpp b/WebCore/platform/haiku/PasteboardHaiku.cpp
index 67a7f5b..8ad72ca 100644
--- a/WebCore/platform/haiku/PasteboardHaiku.cpp
+++ b/WebCore/platform/haiku/PasteboardHaiku.cpp
@@ -68,6 +68,23 @@ void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete,
clipboard.Unlock();
}
+void Pasteboard::writePlainText(const String& text)
+{
+ BClipboard clipboard("WebKit");
+ if (!clipboard.Lock())
+ return;
+
+ clipboard.Clear();
+ BMessage* data = clipboard.Data();
+ if (!data)
+ return;
+
+ data->AddString("text/plain", BString(text));
+ clipboard.Commit();
+
+ clipboard.Unlock();
+}
+
bool Pasteboard::canSmartReplace()
{
notImplemented();
diff --git a/WebCore/platform/haiku/RenderThemeHaiku.cpp b/WebCore/platform/haiku/RenderThemeHaiku.cpp
new file mode 100644
index 0000000..4327795
--- /dev/null
+++ b/WebCore/platform/haiku/RenderThemeHaiku.cpp
@@ -0,0 +1,178 @@
+/*
+ * This file is part of the WebKit project.
+ *
+ * Copyright (C) 2006 Dirk Mueller <mueller@kde.org>
+ * 2006 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2007 Ryan Leavengood <leavengood@gmail.com>
+ * Copyright (C) 2009 Maxime Simon <simon.maxime@gmail.com>
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "config.h"
+#include "RenderThemeHaiku.h"
+
+#include "GraphicsContext.h"
+#include "NotImplemented.h"
+#include <ControlLook.h>
+#include <View.h>
+
+
+namespace WebCore {
+
+PassRefPtr<RenderTheme> RenderThemeHaiku::create()
+{
+ return adoptRef(new RenderThemeHaiku());
+}
+
+PassRefPtr<RenderTheme> RenderTheme::themeForPage(Page*)
+{
+ static RenderTheme* renderTheme = RenderThemeHaiku::create().releaseRef();
+ return renderTheme;
+}
+
+RenderThemeHaiku::RenderThemeHaiku()
+{
+}
+
+RenderThemeHaiku::~RenderThemeHaiku()
+{
+}
+
+static bool supportsFocus(ControlPart appearance)
+{
+ switch (appearance) {
+ case PushButtonPart:
+ case ButtonPart:
+ case TextFieldPart:
+ case TextAreaPart:
+ case SearchFieldPart:
+ case MenulistPart:
+ case RadioPart:
+ case CheckboxPart:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool RenderThemeHaiku::supportsFocusRing(const RenderStyle* style) const
+{
+ return supportsFocus(style->appearance());
+}
+
+Color RenderThemeHaiku::platformActiveSelectionBackgroundColor() const
+{
+ return Color(ui_color(B_CONTROL_HIGHLIGHT_COLOR));
+}
+
+Color RenderThemeHaiku::platformInactiveSelectionBackgroundColor() const
+{
+ return Color(ui_color(B_CONTROL_HIGHLIGHT_COLOR));
+}
+
+Color RenderThemeHaiku::platformActiveSelectionForegroundColor() const
+{
+ return Color(ui_color(B_CONTROL_TEXT_COLOR));
+}
+
+Color RenderThemeHaiku::platformInactiveSelectionForegroundColor() const
+{
+ return Color(ui_color(B_CONTROL_TEXT_COLOR));
+}
+
+Color RenderThemeHaiku::platformTextSearchHighlightColor() const
+{
+ return Color(ui_color(B_MENU_SELECTED_BACKGROUND_COLOR));
+}
+
+void RenderThemeHaiku::systemFont(int propId, FontDescription&) const
+{
+ notImplemented();
+}
+
+bool RenderThemeHaiku::paintCheckbox(RenderObject*, const RenderObject::PaintInfo& info, const IntRect& intRect)
+{
+ if (info.context->paintingDisabled())
+ return false;
+
+ rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR);
+ BRect rect = intRect;
+ BView* view = info.context->platformContext();
+
+ if (!be_control_look)
+ return false;
+
+ be_control_look->DrawCheckBox(view, rect, rect, base);
+ return true;
+}
+
+void RenderThemeHaiku::setCheckboxSize(RenderStyle* style) const
+{
+ int size = 10;
+
+ // If the width and height are both specified, then we have nothing to do.
+ if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto())
+ return;
+
+ // FIXME: A hard-coded size of 'size' is used. This is wrong but necessary for now.
+ if (style->width().isIntrinsicOrAuto())
+ style->setWidth(Length(size, Fixed));
+
+ if (style->height().isAuto())
+ style->setHeight(Length(size, Fixed));
+}
+
+bool RenderThemeHaiku::paintRadio(RenderObject*, const RenderObject::PaintInfo& info, const IntRect& intRect)
+{
+ if (info.context->paintingDisabled())
+ return false;
+
+ rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR);
+ BRect rect = intRect;
+ BView* view = info.context->platformContext();
+
+ if (!be_control_look)
+ return false;
+
+ be_control_look->DrawRadioButton(view, rect, rect, base);
+ return true;
+}
+
+void RenderThemeHaiku::setRadioSize(RenderStyle* style) const
+{
+ // This is the same as checkboxes.
+ setCheckboxSize(style);
+}
+
+void RenderThemeHaiku::adjustMenuListStyle(CSSStyleSelector*, RenderStyle* style, Element*) const
+{
+ // Leave some space for the arrow.
+ style->setPaddingRight(Length(22, Fixed));
+ const int minHeight = 20;
+ style->setMinHeight(Length(minHeight, Fixed));
+}
+
+bool RenderThemeHaiku::paintMenuList(RenderObject*, const RenderObject::PaintInfo&, const IntRect&)
+{
+ notImplemented();
+ return false;
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/haiku/RenderThemeHaiku.h b/WebCore/platform/haiku/RenderThemeHaiku.h
new file mode 100644
index 0000000..7daebc4
--- /dev/null
+++ b/WebCore/platform/haiku/RenderThemeHaiku.h
@@ -0,0 +1,70 @@
+/*
+ * This file is part of the WebKit project.
+ *
+ * Copyright (C) 2009 Maxime Simon <simon.maxime@gmail.com>
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef RenderThemeHaiku_h
+#define RenderThemeHaiku_h
+
+#include "RenderTheme.h"
+
+namespace WebCore {
+
+ class RenderThemeHaiku : public RenderTheme {
+ private:
+ RenderThemeHaiku();
+ virtual ~RenderThemeHaiku();
+
+ public:
+ static PassRefPtr<RenderTheme> create();
+
+ // A method asking if the theme's controls actually care about redrawing when hovered.
+ virtual bool supportsHover(const RenderStyle* style) const { return false; }
+
+ // A method asking if the theme is able to draw the focus ring.
+ virtual bool supportsFocusRing(const RenderStyle*) const;
+
+ // The platform selection color.
+ virtual Color platformActiveSelectionBackgroundColor() const;
+ virtual Color platformInactiveSelectionBackgroundColor() const;
+ virtual Color platformActiveSelectionForegroundColor() const;
+ virtual Color platformInactiveSelectionForegroundColor() const;
+
+ virtual Color platformTextSearchHighlightColor() const;
+
+ // System fonts.
+ virtual void systemFont(int propId, FontDescription&) const;
+
+ protected:
+ virtual bool paintCheckbox(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
+ virtual void setCheckboxSize(RenderStyle*) const;
+
+ virtual bool paintRadio(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
+ virtual void setRadioSize(RenderStyle*) const;
+
+ virtual void adjustMenuListStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
+ virtual bool paintMenuList(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
+ };
+
+} // namespace WebCore
+
+#endif // RenderThemeHaiku_h
diff --git a/WebCore/platform/haiku/ScrollbarThemeHaiku.cpp b/WebCore/platform/haiku/ScrollbarThemeHaiku.cpp
new file mode 100644
index 0000000..8adab3d
--- /dev/null
+++ b/WebCore/platform/haiku/ScrollbarThemeHaiku.cpp
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright 2009 Maxime Simon <simon.maxime@gmail.com> 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 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 "ScrollbarThemeHaiku.h"
+
+#include "GraphicsContext.h"
+#include "Scrollbar.h"
+#include <ControlLook.h>
+#include <InterfaceDefs.h>
+
+
+int buttonWidth(int scrollbarWidth, int thickness)
+{
+ return scrollbarWidth < 2 * thickness ? scrollbarWidth / 2 : thickness;
+}
+
+namespace WebCore {
+
+ScrollbarTheme* ScrollbarTheme::nativeTheme()
+{
+ static ScrollbarThemeHaiku theme;
+ return &theme;
+}
+
+ScrollbarThemeHaiku::ScrollbarThemeHaiku()
+{
+}
+
+ScrollbarThemeHaiku::~ScrollbarThemeHaiku()
+{
+}
+
+int ScrollbarThemeHaiku::scrollbarThickness(ScrollbarControlSize controlSize)
+{
+ // FIXME: Should we make a distinction between a Small and a Regular Scrollbar?
+ return 16;
+}
+
+bool ScrollbarThemeHaiku::hasButtons(Scrollbar* scrollbar)
+{
+ return scrollbar->enabled();
+}
+
+bool ScrollbarThemeHaiku::hasThumb(Scrollbar* scrollbar)
+{
+ return scrollbar->enabled() && thumbLength(scrollbar) > 0;
+}
+
+IntRect ScrollbarThemeHaiku::backButtonRect(Scrollbar* scrollbar, ScrollbarPart part, bool)
+{
+ if (part == BackButtonEndPart)
+ return IntRect();
+
+ int thickness = scrollbarThickness();
+ IntPoint buttonOrigin(scrollbar->x(), scrollbar->y());
+ IntSize buttonSize = scrollbar->orientation() == HorizontalScrollbar
+ ? IntSize(buttonWidth(scrollbar->width(), thickness), thickness)
+ : IntSize(thickness, buttonWidth(scrollbar->height(), thickness));
+ IntRect buttonRect(buttonOrigin, buttonSize);
+
+ return buttonRect;
+}
+
+IntRect ScrollbarThemeHaiku::forwardButtonRect(Scrollbar* scrollbar, ScrollbarPart part, bool)
+{
+ if (part == BackButtonStartPart)
+ return IntRect();
+
+ int thickness = scrollbarThickness();
+ if (scrollbar->orientation() == HorizontalScrollbar) {
+ int width = buttonWidth(scrollbar->width(), thickness);
+ return IntRect(scrollbar->x() + scrollbar->width() - width, scrollbar->y(), width, thickness);
+ }
+
+ int height = buttonWidth(scrollbar->height(), thickness);
+ return IntRect(scrollbar->x(), scrollbar->y() + scrollbar->height() - height, thickness, height);
+}
+
+IntRect ScrollbarThemeHaiku::trackRect(Scrollbar* scrollbar, bool)
+{
+ int thickness = scrollbarThickness();
+ if (scrollbar->orientation() == HorizontalScrollbar) {
+ if (scrollbar->width() < 2 * thickness)
+ return IntRect();
+ return IntRect(scrollbar->x() + thickness, scrollbar->y(), scrollbar->width() - 2 * thickness, thickness);
+ }
+ if (scrollbar->height() < 2 * thickness)
+ return IntRect();
+ return IntRect(scrollbar->x(), scrollbar->y() + thickness, thickness, scrollbar->height() - 2 * thickness);
+}
+
+void ScrollbarThemeHaiku::paintScrollbarBackground(GraphicsContext* context, Scrollbar* scrollbar)
+{
+ if (!be_control_look)
+ return;
+
+ BRect rect = trackRect(scrollbar, false);
+ orientation scrollbarOrientation = scrollbar->orientation() == HorizontalScrollbar ? B_HORIZONTAL : B_VERTICAL;
+
+ be_control_look->DrawScrollBarBackground(context->platformContext(), rect, rect, ui_color(B_PANEL_BACKGROUND_COLOR), 0, scrollbarOrientation);
+}
+
+void ScrollbarThemeHaiku::paintButton(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& rect, ScrollbarPart part)
+{
+ if (!be_control_look)
+ return;
+
+ BRect drawRect = BRect(rect);
+ BView* view = context->platformContext();
+ rgb_color panelBgColor = ui_color(B_PANEL_BACKGROUND_COLOR);
+ rgb_color buttonBgColor = tint_color(panelBgColor, B_LIGHTEN_1_TINT);
+
+ be_control_look->DrawButtonFrame(view, drawRect, drawRect, buttonBgColor, panelBgColor);
+ be_control_look->DrawButtonBackground(view, drawRect, drawRect, buttonBgColor);
+
+ int arrowDirection;
+ if (scrollbar->orientation() == VerticalScrollbar)
+ arrowDirection = part == BackButtonStartPart ? BControlLook::B_UP_ARROW : BControlLook::B_DOWN_ARROW;
+ else
+ arrowDirection = part == BackButtonStartPart ? BControlLook::B_LEFT_ARROW : BControlLook::B_RIGHT_ARROW;
+
+ be_control_look->DrawArrowShape(view, drawRect, drawRect, ui_color(B_CONTROL_TEXT_COLOR), arrowDirection);
+}
+
+void ScrollbarThemeHaiku::paintThumb(GraphicsContext* context, Scrollbar*, const IntRect& rect)
+{
+ if (!be_control_look)
+ return;
+
+ BRect drawRect = BRect(rect);
+ BView* view = context->platformContext();
+ rgb_color panelBgColor = ui_color(B_PANEL_BACKGROUND_COLOR);
+ rgb_color buttonBgColor = tint_color(panelBgColor, B_LIGHTEN_1_TINT);
+
+ be_control_look->DrawButtonFrame(view, drawRect, drawRect, buttonBgColor, panelBgColor);
+ be_control_look->DrawButtonBackground(view, drawRect, drawRect, buttonBgColor);
+}
+
+}
+
diff --git a/WebCore/platform/haiku/ScrollbarThemeHaiku.h b/WebCore/platform/haiku/ScrollbarThemeHaiku.h
new file mode 100644
index 0000000..18e2cc0
--- /dev/null
+++ b/WebCore/platform/haiku/ScrollbarThemeHaiku.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright 2009 Maxime Simon <simon.maxime@gmail.com> 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 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 ScrollbarThemeHaiku_h
+#define ScrollbarThemeHaiku_h
+
+#include "ScrollbarThemeComposite.h"
+
+namespace WebCore {
+ class Scrollbar;
+
+ class ScrollbarThemeHaiku : public ScrollbarThemeComposite {
+ public:
+ ScrollbarThemeHaiku();
+ virtual ~ScrollbarThemeHaiku();
+
+ virtual int scrollbarThickness(ScrollbarControlSize = RegularScrollbar);
+
+ virtual bool hasButtons(Scrollbar*);
+ virtual bool hasThumb(Scrollbar*);
+
+ virtual IntRect backButtonRect(Scrollbar*, ScrollbarPart, bool painting);
+ virtual IntRect forwardButtonRect(Scrollbar*, ScrollbarPart, bool painting);
+ virtual IntRect trackRect(Scrollbar*, bool painting);
+
+ virtual void paintScrollbarBackground(GraphicsContext*, Scrollbar*);
+ virtual void paintButton(GraphicsContext*, Scrollbar*, const IntRect&, ScrollbarPart);
+ virtual void paintThumb(GraphicsContext*, Scrollbar*, const IntRect&);
+ };
+
+}
+#endif
diff --git a/WebCore/platform/haiku/SharedBufferHaiku.cpp b/WebCore/platform/haiku/SharedBufferHaiku.cpp
new file mode 100644
index 0000000..113cd2e
--- /dev/null
+++ b/WebCore/platform/haiku/SharedBufferHaiku.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2009 Maxime Simon <simon.maxime@gmail.com>
+ *
+ * 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 "SharedBuffer.h"
+
+#include <File.h>
+#include <String.h>
+
+namespace WebCore {
+
+PassRefPtr<SharedBuffer> SharedBuffer::createWithContentsOfFile(const String& fileName)
+{
+ if (fileName.isEmpty())
+ return 0;
+
+ BFile file(BString(fileName).String(), B_READ_ONLY);
+ if (file.InitCheck() != B_OK)
+ return 0;
+
+ RefPtr<SharedBuffer> result = SharedBuffer::create();
+
+ off_t size;
+ file.GetSize(&size);
+ result->m_buffer.resize(size);
+ if (result->m_buffer.size() != size)
+ return 0;
+
+ file.Read(result->m_buffer.data(), result->m_buffer.size());
+ return result.release();
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/haiku/SharedTimerHaiku.cpp b/WebCore/platform/haiku/SharedTimerHaiku.cpp
new file mode 100644
index 0000000..6265a2a
--- /dev/null
+++ b/WebCore/platform/haiku/SharedTimerHaiku.cpp
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2009 Maxime Simon <simon.maxime@gmail.com>
+ *
+ * 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 "SharedTimer.h"
+
+#include <MessageFilter.h>
+#include <MessageRunner.h>
+#include <Looper.h>
+#include <support/Locker.h>
+#include <support/Autolock.h>
+#include <wtf/CurrentTime.h>
+
+#define FIRE_MESSAGE 'fire'
+
+
+namespace WebCore {
+
+class SharedTimerHaiku: public BMessageFilter {
+ friend void setSharedTimerFiredFunction(void (*f)());
+public:
+ static SharedTimerHaiku* instance();
+
+ void start(double);
+ void stop();
+
+protected:
+ virtual filter_result Filter(BMessage*, BHandler**);
+
+private:
+ SharedTimerHaiku();
+ ~SharedTimerHaiku();
+
+ void (*m_timerFunction)();
+ bool m_shouldRun;
+};
+
+SharedTimerHaiku::SharedTimerHaiku()
+ : BMessageFilter(FIRE_MESSAGE)
+ , m_timerFunction(0)
+ , m_shouldRun(false)
+{
+}
+
+SharedTimerHaiku::~SharedTimerHaiku()
+{
+}
+
+SharedTimerHaiku* SharedTimerHaiku::instance()
+{
+ BLooper* looper = BLooper::LooperForThread(find_thread(0));
+ static SharedTimerHaiku* timer;
+
+ if (!timer) {
+ BAutolock lock(looper);
+ timer = new SharedTimerHaiku();
+ looper->AddCommonFilter(timer);
+ }
+
+ return timer;
+}
+
+void SharedTimerHaiku::start(double fireTime)
+{
+ m_shouldRun = true;
+
+ double intervalInSeconds = fireTime - currentTime();
+ bigtime_t intervalInMicroSeconds = intervalInSeconds < 0 ? 0 : intervalInSeconds * 1000000;
+
+ BMessageRunner::StartSending(Looper(), new BMessage(FIRE_MESSAGE), intervalInMicroSeconds, 1);
+}
+
+void SharedTimerHaiku::stop()
+{
+ m_shouldRun = false;
+}
+
+filter_result SharedTimerHaiku::Filter(BMessage*, BHandler**)
+{
+ if (m_shouldRun && m_timerFunction)
+ m_timerFunction();
+
+ return B_SKIP_MESSAGE;
+}
+
+// WebCore functions
+void setSharedTimerFiredFunction(void (*f)())
+{
+ SharedTimerHaiku::instance()->m_timerFunction = f;
+}
+
+void setSharedTimerFireTime(double fireTime)
+{
+ SharedTimerHaiku::instance()->start(fireTime);
+}
+
+void stopSharedTimer()
+{
+ SharedTimerHaiku::instance()->stop();
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/haiku/TemporaryLinkStubs.cpp b/WebCore/platform/haiku/TemporaryLinkStubs.cpp
index 48380fc..aa3d538 100644
--- a/WebCore/platform/haiku/TemporaryLinkStubs.cpp
+++ b/WebCore/platform/haiku/TemporaryLinkStubs.cpp
@@ -33,40 +33,11 @@
#include "config.h"
-#include "AXObjectCache.h"
-#include "CachedResource.h"
-#include "CookieJar.h"
-#include "Cursor.h"
-#include "DataGridColumnList.h"
-#include "FileSystem.h"
-#include "Font.h"
-#include "Frame.h"
-#include "FrameView.h"
-#include "GraphicsContext.h"
-#include "History.h"
-#include "IconLoader.h"
-#include "InspectorController.h"
-#include "IntPoint.h"
#include "KURL.h"
-#include "Language.h"
-#include "Node.h"
#include "NotImplemented.h"
-#include "Path.h"
-#include "PlatformMouseEvent.h"
-#include "PlatformScrollBar.h"
-#include "PluginInfoStore.h"
-#include "RenderTheme.h"
-#include "Screen.h"
-#include "Scrollbar.h"
-#include "ScrollbarTheme.h"
-#include "SharedBuffer.h"
-#include "TextBoundaries.h"
-#include "Threading.h"
-#include "Widget.h"
-#include "loader.h"
-#include <runtime/JSValue.h>
-#include <stdio.h>
-#include <stdlib.h>
+#include "PlatformString.h"
+#include "SSLKeyGenerator.h"
+#include "SystemTime.h"
using namespace WebCore;
@@ -78,20 +49,14 @@ Vector<char> loadResourceIntoArray(const char*)
namespace WebCore {
-bool historyContains(String const&)
+String signedPublicKeyAndChallengeString(unsigned keySizeIndex, const String &challengeString, const KURL &url)
{
- return false;
+ return String();
}
-Vector<String> supportedKeySizes()
+void getSupportedKeySizes(Vector<String>&)
{
notImplemented();
- return Vector<String>();
-}
-
-String signedPublicKeyAndChallengeString(unsigned keySizeIndex, const String &challengeString, const KURL &url)
-{
- return String();
}
float userIdleTime()
@@ -105,22 +70,11 @@ void callOnMainThread(void (*)())
notImplemented();
}
-PassRefPtr<SharedBuffer> SharedBuffer::createWithContentsOfFile(const String&)
-{
- notImplemented();
- return 0;
-}
-
String KURL::fileSystemPath() const
{
notImplemented();
return String();
}
-void getSupportedKeySizes(Vector<String>&)
-{
- notImplemented();
-}
-
} // namespace WebCore
diff --git a/WebCore/platform/image-decoders/ImageDecoder.cpp b/WebCore/platform/image-decoders/ImageDecoder.cpp
new file mode 100644
index 0000000..a16b940
--- /dev/null
+++ b/WebCore/platform/image-decoders/ImageDecoder.cpp
@@ -0,0 +1,248 @@
+/*
+ * Copyright (C) 2008-2009 Torch Mobile, Inc.
+ *
+ * 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 "ImageDecoder.h"
+
+#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
+#include <algorithm>
+#endif
+
+#include "BMPImageDecoder.h"
+#include "GIFImageDecoder.h"
+#include "ICOImageDecoder.h"
+#include "JPEGImageDecoder.h"
+#include "PNGImageDecoder.h"
+#include "SharedBuffer.h"
+#include "XBMImageDecoder.h"
+
+namespace WebCore {
+
+ImageDecoder* ImageDecoder::create(const SharedBuffer& data)
+{
+ // We need at least 4 bytes to figure out what kind of image we're dealing with.
+ int length = data.size();
+ if (length < 4)
+ return 0;
+
+ const unsigned char* uContents = (const unsigned char*)data.data();
+ const char* contents = data.data();
+
+ // GIFs begin with GIF8(7 or 9).
+ if (strncmp(contents, "GIF8", 4) == 0)
+ return new GIFImageDecoder();
+
+ // Test for PNG.
+ if (uContents[0]==0x89 &&
+ uContents[1]==0x50 &&
+ uContents[2]==0x4E &&
+ uContents[3]==0x47)
+ return new PNGImageDecoder();
+
+ // JPEG
+ if (uContents[0]==0xFF &&
+ uContents[1]==0xD8 &&
+ uContents[2]==0xFF)
+ return new JPEGImageDecoder();
+
+ // BMP
+ if (strncmp(contents, "BM", 2) == 0)
+ return new BMPImageDecoder();
+
+ // ICOs always begin with a 2-byte 0 followed by a 2-byte 1.
+ // CURs begin with 2-byte 0 followed by 2-byte 2.
+ if (!memcmp(contents, "\000\000\001\000", 4) ||
+ !memcmp(contents, "\000\000\002\000", 4))
+ return new ICOImageDecoder();
+
+ // XBMs require 8 bytes of info.
+ if (length >= 8 && strncmp(contents, "#define ", 8) == 0)
+ return new XBMImageDecoder();
+
+ // Give up. We don't know what the heck this is.
+ return 0;
+}
+
+#if !PLATFORM(SKIA)
+
+RGBA32Buffer::RGBA32Buffer()
+ : m_hasAlpha(false)
+ , m_status(FrameEmpty)
+ , m_duration(0)
+ , m_disposalMethod(DisposeNotSpecified)
+{
+}
+
+void RGBA32Buffer::clear()
+{
+ m_bytes.clear();
+ m_status = FrameEmpty;
+ // NOTE: Do not reset other members here; clearFrameBufferCache()
+ // calls this to free the bitmap data, but other functions like
+ // initFrameBuffer() and frameComplete() may still need to read
+ // other metadata out of this frame later.
+}
+
+void RGBA32Buffer::zeroFill()
+{
+ m_bytes.fill(0);
+ m_hasAlpha = true;
+}
+
+void RGBA32Buffer::copyBitmapData(const RGBA32Buffer& other)
+{
+ if (this == &other)
+ return;
+
+ m_bytes = other.m_bytes;
+ m_size = other.m_size;
+ setHasAlpha(other.m_hasAlpha);
+}
+
+bool RGBA32Buffer::setSize(int newWidth, int newHeight)
+{
+ // NOTE: This has no way to check for allocation failure if the
+ // requested size was too big...
+ m_bytes.resize(newWidth * newHeight);
+ m_size = IntSize(newWidth, newHeight);
+
+ // Zero the image.
+ zeroFill();
+
+ return true;
+}
+
+bool RGBA32Buffer::hasAlpha() const
+{
+ return m_hasAlpha;
+}
+
+void RGBA32Buffer::setHasAlpha(bool alpha)
+{
+ m_hasAlpha = alpha;
+}
+
+void RGBA32Buffer::setStatus(FrameStatus status)
+{
+ m_status = status;
+}
+
+RGBA32Buffer& RGBA32Buffer::operator=(const RGBA32Buffer& other)
+{
+ if (this == &other)
+ return *this;
+
+ copyBitmapData(other);
+ setRect(other.rect());
+ setStatus(other.status());
+ setDuration(other.duration());
+ setDisposalMethod(other.disposalMethod());
+ return *this;
+}
+
+int RGBA32Buffer::width() const
+{
+ return m_size.width();
+}
+
+int RGBA32Buffer::height() const
+{
+ return m_size.height();
+}
+
+#endif
+
+#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
+
+namespace {
+
+enum MatchType {
+ Exact,
+ UpperBound,
+ LowerBound
+};
+
+inline void fillScaledValues(Vector<int>& scaledValues, double scaleRate, int length)
+{
+ double inflateRate = 1. / scaleRate;
+ scaledValues.reserveCapacity(static_cast<int>(length * scaleRate + 0.5));
+ for (int scaledIndex = 0;;) {
+ int index = static_cast<int>(scaledIndex * inflateRate + 0.5);
+ if (index < length) {
+ scaledValues.append(index);
+ ++scaledIndex;
+ } else
+ break;
+ }
+}
+
+template <MatchType type> int getScaledValue(const Vector<int>& scaledValues, int valueToMatch, int searchStart)
+{
+ const int* dataStart = scaledValues.data();
+ const int* dataEnd = dataStart + scaledValues.size();
+ const int* matched = std::lower_bound(dataStart + searchStart, dataEnd, valueToMatch);
+ switch (type) {
+ case Exact:
+ return matched != dataEnd && *matched == valueToMatch ? matched - dataStart : -1;
+ case LowerBound:
+ return matched != dataEnd && *matched == valueToMatch ? matched - dataStart : matched - dataStart - 1;
+ case UpperBound:
+ default:
+ return matched != dataEnd ? matched - dataStart : -1;
+ }
+}
+
+}
+
+void ImageDecoder::prepareScaleDataIfNecessary()
+{
+ int width = m_size.width();
+ int height = m_size.height();
+ int numPixels = height * width;
+ if (m_maxNumPixels <= 0 || numPixels <= m_maxNumPixels) {
+ m_scaled = false;
+ return;
+ }
+
+ m_scaled = true;
+ double scale = sqrt(m_maxNumPixels / (double)numPixels);
+ fillScaledValues(m_scaledColumns, scale, width);
+ fillScaledValues(m_scaledRows, scale, height);
+}
+
+int ImageDecoder::upperBoundScaledX(int origX, int searchStart)
+{
+ return getScaledValue<UpperBound>(m_scaledColumns, origX, searchStart);
+}
+
+int ImageDecoder::lowerBoundScaledX(int origX, int searchStart)
+{
+ return getScaledValue<LowerBound>(m_scaledColumns, origX, searchStart);
+}
+
+int ImageDecoder::scaledY(int origY, int searchStart)
+{
+ return getScaledValue<Exact>(m_scaledRows, origY, searchStart);
+}
+
+#endif // ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
+
+}
diff --git a/WebCore/platform/image-decoders/ImageDecoder.h b/WebCore/platform/image-decoders/ImageDecoder.h
index 57f8735..37196fe 100644
--- a/WebCore/platform/image-decoders/ImageDecoder.h
+++ b/WebCore/platform/image-decoders/ImageDecoder.h
@@ -1,5 +1,7 @@
/*
* Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2008-2009 Torch Mobile, Inc.
+ * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -37,7 +39,8 @@
#if (PLATFORM(SKIA) || PLATFORM(SGL))
// TODO(benm): ANDROID: Can we define PLATFORM(SKIA) instead of PLATFORM(SGL) before upstreaming?
#include "NativeImageSkia.h"
-#include "SkBitmap.h"
+#elif PLATFORM(QT)
+#include <QImage>
#endif
namespace WebCore {
@@ -55,7 +58,11 @@ namespace WebCore {
DisposeOverwriteBgcolor, // Clear frame to transparent
DisposeOverwritePrevious, // Clear frame to previous framebuffer contents
};
+<<<<<<< HEAD:WebCore/platform/image-decoders/ImageDecoder.h
#if (PLATFORM(SKIA) || PLATFORM(SGL))
+=======
+#if PLATFORM(SKIA) || PLATFORM(QT)
+>>>>>>> webkit.org at 49305:WebCore/platform/image-decoders/ImageDecoder.h
typedef uint32_t PixelData;
#else
typedef unsigned PixelData;
@@ -132,6 +139,11 @@ namespace WebCore {
setRGBA(getAddr(x, y), r, g, b, a);
}
+#if PLATFORM(QT)
+ void setDecodedImage(const QImage& image);
+ QImage decodedImage() const { return m_image; }
+#endif
+
private:
RGBA32Buffer& operator=(const RGBA32Buffer& other);
@@ -140,13 +152,18 @@ namespace WebCore {
inline PixelData* getAddr(int x, int y)
{
+<<<<<<< HEAD:WebCore/platform/image-decoders/ImageDecoder.h
#if PLATFORM(CAIRO) || PLATFORM(WX)
return m_bytes.data() + (y * width()) + x;
#elif (PLATFORM(SKIA) || PLATFORM(SGL))
+=======
+#if PLATFORM(SKIA)
+>>>>>>> webkit.org at 49305:WebCore/platform/image-decoders/ImageDecoder.h
return m_bitmap.getAddr32(x, y);
+#elif PLATFORM(QT)
+ return reinterpret_cast<QRgb*>(m_image.scanLine(y)) + x;
#else
- ASSERT_NOT_REACHED();
- return 0;
+ return m_bytes.data() + (y * width()) + x;
#endif
}
@@ -166,13 +183,22 @@ namespace WebCore {
}
}
-#if PLATFORM(CAIRO) || PLATFORM(WX)
+#if PLATFORM(SKIA)
+ NativeImageSkia m_bitmap;
+#elif PLATFORM(QT)
+ mutable QImage m_image;
+ bool m_hasAlpha;
+ IntSize m_size;
+#else
Vector<PixelData> m_bytes;
IntSize m_size; // The size of the buffer. This should be the
// same as ImageDecoder::m_size.
bool m_hasAlpha; // Whether or not any of the pixels in the buffer have transparency.
+<<<<<<< HEAD:WebCore/platform/image-decoders/ImageDecoder.h
#elif (PLATFORM(SKIA) || PLATFORM(SGL))
NativeImageSkia m_bitmap;
+=======
+>>>>>>> webkit.org at 49305:WebCore/platform/image-decoders/ImageDecoder.h
#endif
IntRect m_rect; // The rect of the original specified frame within the overall buffer.
// This will always just be the entire buffer except for GIF frames
@@ -188,14 +214,27 @@ namespace WebCore {
// and the base class manages the RGBA32 frame cache.
class ImageDecoder {
public:
+ // ENABLE(IMAGE_DECODER_DOWN_SAMPLING) allows image decoders to write directly to
+ // scaled output buffers by down sampling. Call setMaxNumPixels() to specify the
+ // biggest size that decoded images can have. Image decoders will deflate those
+ // images that are bigger than m_maxNumPixels. (Not supported by all image decoders yet)
ImageDecoder()
: m_failed(false)
, m_sizeAvailable(false)
+#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
+ , m_maxNumPixels(-1)
+ , m_scaled(false)
+#endif
{
}
virtual ~ImageDecoder() {}
+ // Factory function to create an ImageDecoder. Ports that subclass
+ // ImageDecoder can provide their own implementation of this to avoid
+ // needing to write a dedicated setData() implementation.
+ static ImageDecoder* create(const SharedBuffer& data);
+
// The the filename extension usually associated with an undecoded image of this type.
virtual String filenameExtension() const = 0;
@@ -272,8 +311,25 @@ namespace WebCore {
// since in practice only GIFs will ever use this.
virtual void clearFrameBufferCache(size_t clearBeforeFrame) { }
+#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
+ void setMaxNumPixels(int m) { m_maxNumPixels = m; }
+#endif
+
protected:
+#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
+ void prepareScaleDataIfNecessary();
+ int upperBoundScaledX(int origX, int searchStart = 0);
+ int lowerBoundScaledX(int origX, int searchStart = 0);
+ int scaledY(int origY, int searchStart = 0);
+#endif
+
RefPtr<SharedBuffer> m_data; // The encoded data.
+#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
+ int m_maxNumPixels;
+ Vector<int> m_scaledColumns;
+ Vector<int> m_scaledRows;
+ bool m_scaled;
+#endif
Vector<RGBA32Buffer> m_frameBufferCache;
bool m_failed;
diff --git a/WebCore/platform/image-decoders/cairo/ImageDecoderCairo.cpp b/WebCore/platform/image-decoders/cairo/ImageDecoderCairo.cpp
index c53eabd..203205d 100644
--- a/WebCore/platform/image-decoders/cairo/ImageDecoderCairo.cpp
+++ b/WebCore/platform/image-decoders/cairo/ImageDecoderCairo.cpp
@@ -30,53 +30,6 @@
namespace WebCore {
-RGBA32Buffer::RGBA32Buffer()
- : m_hasAlpha(false)
- , m_status(FrameEmpty)
- , m_duration(0)
- , m_disposalMethod(DisposeNotSpecified)
-{
-}
-
-void RGBA32Buffer::clear()
-{
- m_bytes.clear();
- m_status = FrameEmpty;
- // NOTE: Do not reset other members here; clearFrameBufferCache()
- // calls this to free the bitmap data, but other functions like
- // initFrameBuffer() and frameComplete() may still need to read
- // other metadata out of this frame later.
-}
-
-void RGBA32Buffer::zeroFill()
-{
- m_bytes.fill(0);
- m_hasAlpha = true;
-}
-
-void RGBA32Buffer::copyBitmapData(const RGBA32Buffer& other)
-{
- if (this == &other)
- return;
-
- m_bytes = other.m_bytes;
- m_size = other.m_size;
- setHasAlpha(other.m_hasAlpha);
-}
-
-bool RGBA32Buffer::setSize(int newWidth, int newHeight)
-{
- // NOTE: This has no way to check for allocation failure if the
- // requested size was too big...
- m_bytes.resize(newWidth * newHeight);
- m_size = IntSize(newWidth, newHeight);
-
- // Zero the image.
- zeroFill();
-
- return true;
-}
-
NativeImagePtr RGBA32Buffer::asNewNativeImage() const
{
return cairo_image_surface_create_for_data(
@@ -85,40 +38,4 @@ NativeImagePtr RGBA32Buffer::asNewNativeImage() const
width() * sizeof(PixelData));
}
-bool RGBA32Buffer::hasAlpha() const
-{
- return m_hasAlpha;
-}
-
-void RGBA32Buffer::setHasAlpha(bool alpha)
-{
- m_hasAlpha = alpha;
-}
-
-void RGBA32Buffer::setStatus(FrameStatus status)
-{
- m_status = status;
-}
-
-RGBA32Buffer& RGBA32Buffer::operator=(const RGBA32Buffer& other)
-{
- if (this == &other)
- return *this;
-
- copyBitmapData(other);
- setRect(other.rect());
- setStatus(other.status());
- setDuration(other.duration());
- setDisposalMethod(other.disposalMethod());
- return *this;
-}
-
-int RGBA32Buffer::width() const {
- return m_size.width();
-}
-
-int RGBA32Buffer::height() const {
- return m_size.height();
-}
-
} // namespace WebCore
diff --git a/WebCore/platform/image-decoders/haiku/ImageDecoderHaiku.cpp b/WebCore/platform/image-decoders/haiku/ImageDecoderHaiku.cpp
index 3542cc2..dc120e3 100644
--- a/WebCore/platform/image-decoders/haiku/ImageDecoderHaiku.cpp
+++ b/WebCore/platform/image-decoders/haiku/ImageDecoderHaiku.cpp
@@ -28,104 +28,14 @@
#include <Bitmap.h>
-
namespace WebCore {
-RGBA32Buffer::RGBA32Buffer()
- : m_hasAlpha(false)
- , m_status(FrameEmpty)
- , m_duration(0)
- , m_disposalMethod(DisposeNotSpecified)
-{
-}
-
-void RGBA32Buffer::clear()
-{
- m_bytes.clear();
- m_status = FrameEmpty;
- // NOTE: Do not reset other members here; clearFrameBufferCache()
- // calls this to free the bitmap data, but other functions like
- // initFrameBuffer() and frameComplete() may still need to read
- // other metadata out of this frame later.
-}
-
-void RGBA32Buffer::zeroFill()
-{
- m_bytes.fill(0);
- m_hasAlpha = true;
-}
-
-void RGBA32Buffer::copyBitmapData(const RGBA32Buffer& other)
-{
- if (this == &other)
- return;
-
- m_bytes = other.m_bytes;
- setHasAlpha(other.m_hasAlpha);
-}
-
-bool RGBA32Buffer::setSize(int newWidth, int newHeight)
-{
- // NOTE: This has no way to check for allocation failure if the
- // requested size was too big...
- m_bytes.resize(newWidth * newHeight);
- m_size = IntSize(newWidth, newHeight);
-
- // Zero the image.
- zeroFill();
-
- return true;
-}
-
NativeImagePtr RGBA32Buffer::asNewNativeImage() const
{
- const void* bytes = m_bytes.data();
-
BBitmap* bmp = new BBitmap(BRect(0, 0, width(), height()), B_RGB32);
- bmp->SetBits(bytes, m_size.width() * m_size.height(), 0, B_RGB32);
-
+ bmp->SetBits(m_bytes.data(), m_size.width() * m_size.height(), 0, B_RGB32);
return bmp;
}
-bool RGBA32Buffer::hasAlpha() const
-{
- return m_hasAlpha;
-}
-
-void RGBA32Buffer::setHasAlpha(bool alpha)
-{
- m_hasAlpha = alpha;
-}
-
-void RGBA32Buffer::setStatus(FrameStatus status)
-{
- m_status = status;
-}
-
-RGBA32Buffer& RGBA32Buffer::operator=(const RGBA32Buffer& other)
-{
- if (this == &other)
- return *this;
-
- m_bytes = other.m_bytes;
- m_size = other.m_size;
- setHasAlpha(other.hasAlpha());
- setRect(other.rect());
- setStatus(other.status());
- setDuration(other.duration());
- setDisposalMethod(other.disposalMethod());
- return *this;
-}
-
-int RGBA32Buffer::width() const
-{
- return m_size.width();
-}
-
-int RGBA32Buffer::height() const
-{
- return m_size.height();
-}
-
} // namespace WebCore
diff --git a/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp b/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp
index e9296ad..a0ec4f7 100644
--- a/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp
+++ b/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp
@@ -51,12 +51,6 @@ ICOImageDecoder::ICOImageDecoder()
{
}
-ICOImageDecoder::~ICOImageDecoder()
-{
- deleteAllValues(m_bmpReaders);
- deleteAllValues(m_pngDecoders);
-}
-
void ICOImageDecoder::setData(SharedBuffer* data, bool allDataReceived)
{
if (failed())
@@ -208,12 +202,12 @@ bool ICOImageDecoder::decodeAtIndex(size_t index)
// We need to have already sized m_frameBufferCache before this, and
// we must not resize it again later (see caution in frameCount()).
ASSERT(m_frameBufferCache.size() == m_dirEntries.size());
- m_bmpReaders[index] =
- new BMPImageReader(this, dirEntry.m_imageOffset, 0, true);
+ m_bmpReaders[index].set(
+ new BMPImageReader(this, dirEntry.m_imageOffset, 0, true));
m_bmpReaders[index]->setData(m_data.get());
m_bmpReaders[index]->setBuffer(&m_frameBufferCache[index]);
} else if (imageType == PNG) {
- m_pngDecoders[index] = new PNGImageDecoder();
+ m_pngDecoders[index].set(new PNGImageDecoder());
setDataForPNGDecoderAtIndex(index);
} else {
// Not enough data to determine image type yet.
@@ -249,18 +243,15 @@ bool ICOImageDecoder::processDirectory()
ICON = 1,
CURSOR = 2,
};
- if (((fileType != ICON) && (fileType != CURSOR)) || (idCount == 0)) {
+ if (((fileType != ICON) && (fileType != CURSOR)) || (!idCount)) {
setFailed();
return false;
}
- // Enlarge member vectors to hold all the entries. We must initialize the
- // BMP and PNG decoding vectors to 0 so that all entries can be safely
- // deleted in our destructor. If we don't do this, they'll contain garbage
- // values, and deleting those will corrupt memory.
+ // Enlarge member vectors to hold all the entries.
m_dirEntries.resize(idCount);
- m_bmpReaders.fill(0, idCount);
- m_pngDecoders.fill(0, idCount);
+ m_bmpReaders.resize(idCount);
+ m_pngDecoders.resize(idCount);
return true;
}
@@ -303,10 +294,10 @@ ICOImageDecoder::IconDirectoryEntry ICOImageDecoder::readDirectoryEntry()
// matching uint8_ts) is so we can record dimensions of size 256 (which is
// what a zero byte really means).
int width = static_cast<uint8_t>(m_data->data()[m_decodedOffset]);
- if (width == 0)
+ if (!width)
width = 256;
int height = static_cast<uint8_t>(m_data->data()[m_decodedOffset + 1]);
- if (height == 0)
+ if (!height)
height = 256;
IconDirectoryEntry entry;
entry.m_size = IntSize(width, height);
@@ -318,11 +309,12 @@ ICOImageDecoder::IconDirectoryEntry ICOImageDecoder::readDirectoryEntry()
// this isn't quite what the bitmap info header says later, as we only use
// this value to determine which icon entry is best.
if (!entry.m_bitCount) {
- uint8_t colorCount = m_data->data()[m_decodedOffset + 2];
- if (colorCount) {
- for (--colorCount; colorCount; colorCount >>= 1)
- ++entry.m_bitCount;
- }
+ int colorCount =
+ static_cast<uint8_t>(m_data->data()[m_decodedOffset + 2]);
+ if (!colorCount)
+ colorCount = 256; // Vague in the spec, needed by real-world icons.
+ for (--colorCount; colorCount; colorCount >>= 1)
+ ++entry.m_bitCount;
}
m_decodedOffset += sizeOfDirEntry;
diff --git a/WebCore/platform/image-decoders/ico/ICOImageDecoder.h b/WebCore/platform/image-decoders/ico/ICOImageDecoder.h
index f8bddf9..6117e06 100644
--- a/WebCore/platform/image-decoders/ico/ICOImageDecoder.h
+++ b/WebCore/platform/image-decoders/ico/ICOImageDecoder.h
@@ -41,7 +41,6 @@ namespace WebCore {
class ICOImageDecoder : public ImageDecoder {
public:
ICOImageDecoder();
- virtual ~ICOImageDecoder();
// ImageDecoder
virtual String filenameExtension() const { return "ico"; }
@@ -134,9 +133,9 @@ namespace WebCore {
IconDirectoryEntries m_dirEntries;
// The image decoders for the various frames.
- typedef Vector<BMPImageReader*> BMPReaders;
+ typedef Vector<OwnPtr<BMPImageReader> > BMPReaders;
BMPReaders m_bmpReaders;
- typedef Vector<PNGImageDecoder*> PNGDecoders;
+ typedef Vector<OwnPtr<PNGImageDecoder> > PNGDecoders;
PNGDecoders m_pngDecoders;
// Valid only while a BMPImageReader is decoding, this holds the size
diff --git a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
index ae09586..410ef60 100644
--- a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
+++ b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
@@ -461,11 +461,27 @@ void JPEGImageDecoder::decode(bool sizeOnly)
}
}
-static void convertCMYKToRGBA(RGBA32Buffer& dest, JSAMPROW src, jpeg_decompress_struct* info)
+static void convertCMYKToRGBA(RGBA32Buffer& dest, int destY, JSAMPROW src, JDIMENSION srcWidth
+#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
+ , bool scaled, const Vector<int>& scaledColumns
+#endif
+ )
{
- ASSERT(info->out_color_space == JCS_CMYK);
-
- for (unsigned x = 0; x < info->output_width; ++x) {
+#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
+ if (scaled) {
+ int numColumns = scaledColumns.size();
+ for (int x = 0; x < numColumns; ++x) {
+ JSAMPLE* jsample = src + scaledColumns[x] * 3;
+ unsigned c = jsample[0];
+ unsigned m = jsample[1];
+ unsigned y = jsample[2];
+ unsigned k = jsample[3];
+ dest.setRGBA(x, destY, c * k / 255, m * k / 255, y * k / 255, 0xFF);
+ }
+ return;
+ }
+#endif
+ for (JDIMENSION x = 0; x < srcWidth; ++x) {
unsigned c = *src++;
unsigned m = *src++;
unsigned y = *src++;
@@ -489,23 +505,31 @@ static void convertCMYKToRGBA(RGBA32Buffer& dest, JSAMPROW src, jpeg_decompress_
// G = 1 - M => 1 - (1 - iM*iK) => iM*iK
// B = 1 - Y => 1 - (1 - iY*iK) => iY*iK
- // read_scanlines has increased the scanline counter, so we
- // actually mean the previous one.
- dest.setRGBA(x, info->output_scanline - 1, c * k / 255, m * k / 255, y * k / 255, 0xFF);
+ dest.setRGBA(x, destY, c * k / 255, m * k / 255, y * k / 255, 0xFF);
}
}
-static void convertRGBToRGBA(RGBA32Buffer& dest, JSAMPROW src, jpeg_decompress_struct* info)
+static void convertRGBToRGBA(RGBA32Buffer& dest, int destY, JSAMPROW src, JDIMENSION srcWidth
+#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
+ , bool scaled, const Vector<int>& scaledColumns
+#endif
+ )
{
- ASSERT(info->out_color_space == JCS_RGB);
-
- for (unsigned x = 0; x < info->output_width; ++x) {
+#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
+ if (scaled) {
+ int numColumns = scaledColumns.size();
+ for (int x = 0; x < numColumns; ++x) {
+ JSAMPLE* jsample = src + scaledColumns[x] * 3;
+ dest.setRGBA(x, destY, jsample[0], jsample[1], jsample[2], 0xFF);
+ }
+ return;
+ }
+#endif
+ for (JDIMENSION x = 0; x < srcWidth; ++x) {
unsigned r = *src++;
unsigned g = *src++;
unsigned b = *src++;
- // read_scanlines has increased the scanline counter, so we
- // actually mean the previous one.
- dest.setRGBA(x, info->output_scanline - 1, r, g, b, 0xFF);
+ dest.setRGBA(x, destY, r, g, b, 0xFF);
}
}
@@ -517,7 +541,17 @@ bool JPEGImageDecoder::outputScanlines()
// Initialize the framebuffer if needed.
RGBA32Buffer& buffer = m_frameBufferCache[0];
if (buffer.status() == RGBA32Buffer::FrameEmpty) {
- if (!buffer.setSize(size().width(), size().height())) {
+ int bufferWidth = size().width();
+ int bufferHeight = size().height();
+#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
+ // Let's resize our buffer now to the correct width/height.
+ if (m_scaled) {
+ bufferWidth = m_scaledColumns.size();
+ bufferHeight = m_scaledRows.size();
+ }
+#endif
+
+ if (!buffer.setSize(bufferWidth, bufferHeight)) {
m_failed = true;
return false;
}
@@ -532,16 +566,34 @@ bool JPEGImageDecoder::outputScanlines()
JSAMPARRAY samples = m_reader->samples();
while (info->output_scanline < info->output_height) {
+ // jpeg_read_scanlines will increase the scanline counter, so we
+ // save the scanline before calling it.
+ int sourceY = info->output_scanline;
/* Request one scanline. Returns 0 or 1 scanlines. */
if (jpeg_read_scanlines(info, samples, 1) != 1)
return false;
+ int destY = sourceY;
+#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
+ if (m_scaled) {
+ destY = scaledY(sourceY);
+ if (destY < 0)
+ continue;
+ }
if (info->out_color_space == JCS_RGB)
- convertRGBToRGBA(buffer, *samples, info);
+ convertRGBToRGBA(buffer, destY, *samples, info->output_width, m_scaled, m_scaledColumns);
else if (info->out_color_space == JCS_CMYK)
- convertCMYKToRGBA(buffer, *samples, info);
+ convertCMYKToRGBA(buffer, destY, *samples, info->output_width, m_scaled, m_scaledColumns);
else
return false;
+#else
+ if (info->out_color_space == JCS_RGB)
+ convertRGBToRGBA(buffer, destY, *samples, info->output_width);
+ else if (info->out_color_space == JCS_CMYK)
+ convertCMYKToRGBA(buffer, destY, *samples, info->output_width);
+ else
+ return false;
+#endif
}
return true;
diff --git a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h
index 56e007d..4a822d7 100644
--- a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h
+++ b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2008-2009 Torch Mobile, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -57,6 +58,16 @@ namespace WebCore {
bool outputScanlines();
void jpegComplete();
+#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
+ bool setSize(int width, int height)
+ {
+ if (!ImageDecoder::setSize(width, height))
+ return false;
+ prepareScaleDataIfNecessary();
+ return true;
+ }
+#endif
+
private:
JPEGImageReader* m_reader;
};
diff --git a/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp b/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp
index d14333f..ad79fc8 100644
--- a/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp
+++ b/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2006 Apple Computer, Inc.
+ * Copyright (C) 2007-2009 Torch Mobile, Inc.
*
* Portions are Copyright (C) 2001 mozilla.org
*
@@ -242,6 +243,9 @@ void PNGImageDecoder::headerAvailable()
longjmp(png->jmpbuf, 1);
return;
}
+#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
+ prepareScaleDataIfNecessary();
+#endif
}
int bitDepth, colorType, interlaceType, compressionType, filterType, channels;
@@ -313,7 +317,14 @@ void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex,
// Initialize the framebuffer if needed.
RGBA32Buffer& buffer = m_frameBufferCache[0];
if (buffer.status() == RGBA32Buffer::FrameEmpty) {
- if (!buffer.setSize(size().width(), size().height())) {
+#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
+ int width = m_scaled ? m_scaledColumns.size() : size().width();
+ int height = m_scaled ? m_scaledRows.size() : size().height();
+#else
+ int width = size().width();
+ int height = size().height();
+#endif
+ if (!buffer.setSize(width, height)) {
static_cast<PNGImageDecoder*>(png_get_progressive_ptr(reader()->pngPtr()))->decodingFailed();
longjmp(reader()->pngPtr()->jmpbuf, 1);
return;
@@ -358,7 +369,7 @@ void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex,
* to pass the current row, and the function will combine the
* old row and the new row.
*/
-
+
png_structp png = reader()->pngPtr();
bool hasAlpha = reader()->hasAlpha();
unsigned colorChannels = hasAlpha ? 4 : 3;
@@ -372,8 +383,27 @@ void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex,
row = rowBuffer;
// Copy the data into our buffer.
+#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
+ if (m_scaled) {
+ int destY = scaledY(rowIndex);
+ if (destY < 0)
+ return;
+ int columns = m_scaledColumns.size();
+ bool sawAlpha = buffer.hasAlpha();
+ for (int x = 0; x < columns; ++x) {
+ png_bytep pixel = row + m_scaledColumns[x] * 4;
+ unsigned alpha = pixel[3];
+ buffer.setRGBA(x, destY, pixel[0], pixel[1], pixel[2], alpha);
+ if (!sawAlpha && alpha < 255) {
+ sawAlpha = true;
+ buffer.setHasAlpha(true);
+ }
+ }
+ return;
+ }
+#endif
int width = size().width();
- bool sawAlpha = false;
+ bool sawAlpha = buffer.hasAlpha();
for (int x = 0; x < width; x++) {
unsigned red = *row++;
unsigned green = *row++;
diff --git a/WebCore/platform/image-decoders/qt/RGBA32BufferQt.cpp b/WebCore/platform/image-decoders/qt/RGBA32BufferQt.cpp
new file mode 100644
index 0000000..da6ab38
--- /dev/null
+++ b/WebCore/platform/image-decoders/qt/RGBA32BufferQt.cpp
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Google, Inc.
+ * Copyright (C) 2009 Holger Hans Peter Freyther
+ *
+ * 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 "ImageDecoder.h"
+
+#include <QPixmap>
+#include <stdio.h>
+
+namespace WebCore {
+
+RGBA32Buffer::RGBA32Buffer()
+ : m_status(FrameEmpty)
+ , m_hasAlpha(false)
+ , m_size()
+ , m_duration(0)
+ , m_disposalMethod(DisposeNotSpecified)
+{
+}
+
+// The image must not have format 8888 pre multiplied...
+void RGBA32Buffer::setDecodedImage(const QImage& image)
+{
+ m_image = image;
+ m_size = image.size();
+ m_hasAlpha = image.hasAlphaChannel();
+}
+
+void RGBA32Buffer::clear()
+{
+ m_image = QImage();
+ m_status = FrameEmpty;
+ // NOTE: Do not reset other members here; clearFrameBufferCache()
+ // calls this to free the bitmap data, but other functions like
+ // initFrameBuffer() and frameComplete() may still need to read
+ // other metadata out of this frame later.
+}
+
+void RGBA32Buffer::zeroFill()
+{
+ m_image.fill(0);
+}
+
+void RGBA32Buffer::copyBitmapData(const RGBA32Buffer& other)
+{
+ if (this == &other)
+ return;
+
+ m_image = other.m_image;
+ m_size = other.m_size;
+ m_hasAlpha = other.m_hasAlpha;
+}
+
+bool RGBA32Buffer::setSize(int newWidth, int newHeight)
+{
+ // This function should only be called once, it will leak memory
+ // otherwise.
+ ASSERT(width() == 0 && height() == 0);
+
+ m_size = IntSize(newWidth, newHeight);
+ m_image = QImage(newWidth, newHeight, QImage::Format_ARGB32_Premultiplied);
+ if (m_image.isNull()) {
+ // Allocation failure, maybe the bitmap was too big.
+ setStatus(FrameComplete);
+ return false;
+ }
+
+ // Zero the image.
+ zeroFill();
+
+ return true;
+}
+
+QPixmap* RGBA32Buffer::asNewNativeImage() const
+{
+ QPixmap pix = QPixmap::fromImage(m_image);
+ m_image = QImage();
+
+ return new QPixmap(pix);
+}
+
+bool RGBA32Buffer::hasAlpha() const
+{
+ return m_hasAlpha;
+}
+
+void RGBA32Buffer::setHasAlpha(bool alpha)
+{
+ m_hasAlpha = alpha;
+}
+
+void RGBA32Buffer::setStatus(FrameStatus status)
+{
+ m_status = status;
+}
+
+RGBA32Buffer& RGBA32Buffer::operator=(const RGBA32Buffer& other)
+{
+ if (this == &other)
+ return *this;
+
+ copyBitmapData(other);
+ setRect(other.rect());
+ setStatus(other.status());
+ setDuration(other.duration());
+ setDisposalMethod(other.disposalMethod());
+ return *this;
+}
+
+int RGBA32Buffer::width() const
+{
+ return m_size.width();
+}
+
+int RGBA32Buffer::height() const
+{
+ return m_size.height();
+}
+
+}
diff --git a/WebCore/platform/image-decoders/wx/ImageDecoderWx.cpp b/WebCore/platform/image-decoders/wx/ImageDecoderWx.cpp
index 8e8809e..3cadf1c 100644
--- a/WebCore/platform/image-decoders/wx/ImageDecoderWx.cpp
+++ b/WebCore/platform/image-decoders/wx/ImageDecoderWx.cpp
@@ -37,73 +37,21 @@
namespace WebCore {
-RGBA32Buffer::RGBA32Buffer()
- : m_hasAlpha(false)
- , m_status(FrameEmpty)
- , m_duration(0)
- , m_disposalMethod(DisposeNotSpecified)
-{
-}
-
-void RGBA32Buffer::clear()
-{
- m_bytes.clear();
- m_status = FrameEmpty;
- // NOTE: Do not reset other members here; clearFrameBufferCache()
- // calls this to free the bitmap data, but other functions like
- // initFrameBuffer() and frameComplete() may still need to read
- // other metadata out of this frame later.
-}
-
-void RGBA32Buffer::zeroFill()
-{
- m_bytes.fill(0);
- m_hasAlpha = true;
-}
-
-void RGBA32Buffer::copyBitmapData(const RGBA32Buffer& other)
-{
- if (this == &other)
- return;
-
- m_bytes = other.m_bytes;
- m_size = other.m_size;
- setHasAlpha(other.m_hasAlpha);
-}
-
-bool RGBA32Buffer::setSize(int newWidth, int newHeight)
-{
- // NOTE: This has no way to check for allocation failure if the
- // requested size was too big...
- m_bytes.resize(newWidth * newHeight);
- m_size = IntSize(newWidth, newHeight);
-
- // Zero the image.
- zeroFill();
-
- return true;
-}
-
NativeImagePtr RGBA32Buffer::asNewNativeImage() const
{
- const unsigned char* bytes = (const unsigned char*)m_bytes.data();
-
- typedef wxPixelData<wxBitmap, wxAlphaPixelFormat> WxPixelData;
-
wxBitmap* bmp = new wxBitmap(width(), height(), 32);
+ typedef wxPixelData<wxBitmap, wxAlphaPixelFormat> WxPixelData;
WxPixelData data(*bmp);
+ // NB: It appears that the data is in BGRA format instead of RGBA format.
+ // This code works properly on both ppc and intel, meaning the issue is
+ // likely not an issue of byte order getting mixed up on different archs.
+ const unsigned char* bytes = (const unsigned char*)m_bytes.data();
int rowCounter = 0;
long pixelCounter = 0;
-
WxPixelData::Iterator p(data);
-
WxPixelData::Iterator rowStart = p;
-
- // NB: It appears that the data is in BGRA format instead of RGBA format.
- // This code works properly on both ppc and intel, meaning the issue is
- // likely not an issue of byte order getting mixed up on different archs.
- for (long i = 0; i < m_bytes.size() * sizeof(PixelData); i += sizeof(PixelData)) {
+ for (size_t i = 0; i < m_bytes.size() * sizeof(PixelData); i += sizeof(PixelData)) {
p.Red() = bytes[i+2];
p.Green() = bytes[i+1];
p.Blue() = bytes[i+0];
@@ -112,12 +60,11 @@ NativeImagePtr RGBA32Buffer::asNewNativeImage() const
p++;
pixelCounter++;
- if ( (pixelCounter % width() ) == 0 ) {
+ if ((pixelCounter % width()) == 0) {
rowCounter++;
p = rowStart;
p.MoveTo(data, 0, rowCounter);
}
-
}
#if !wxCHECK_VERSION(2,9,0)
bmp->UseAlpha();
@@ -125,7 +72,7 @@ NativeImagePtr RGBA32Buffer::asNewNativeImage() const
ASSERT(bmp->IsOk());
#if USE(WXGC)
- wxGraphicsBitmap* bitmap = new wxGraphicsBitmap(wxGraphicsRenderer::GetDefaultRenderer()->CreateBitmap(*bmp));
+ wxGraphicsBitmap* bitmap = new wxGraphicsBitmap(wxGraphicsRenderer::GetDefaultRenderer()->CreateBitmap(*bmp));
delete bmp;
return bitmap;
#else
@@ -133,40 +80,4 @@ NativeImagePtr RGBA32Buffer::asNewNativeImage() const
#endif
}
-bool RGBA32Buffer::hasAlpha() const
-{
- return m_hasAlpha;
-}
-
-void RGBA32Buffer::setHasAlpha(bool alpha)
-{
- m_hasAlpha = alpha;
-}
-
-void RGBA32Buffer::setStatus(FrameStatus status)
-{
- m_status = status;
-}
-
-RGBA32Buffer& RGBA32Buffer::operator=(const RGBA32Buffer& other)
-{
- if (this == &other)
- return *this;
-
- copyBitmapData(other);
- setRect(other.rect());
- setStatus(other.status());
- setDuration(other.duration());
- setDisposalMethod(other.disposalMethod());
- return *this;
-}
-
-int RGBA32Buffer::width() const {
- return m_size.width();
-}
-
-int RGBA32Buffer::height() const {
- return m_size.height();
-}
-
} // namespace WebCore
diff --git a/WebCore/platform/mac/ClipboardMac.h b/WebCore/platform/mac/ClipboardMac.h
index 9bdd276..3d3c78e 100644
--- a/WebCore/platform/mac/ClipboardMac.h
+++ b/WebCore/platform/mac/ClipboardMac.h
@@ -67,7 +67,9 @@ public:
void setDragImageElement(Node *, const IntPoint&);
virtual DragImageRef createDragImage(IntPoint& dragLoc) const;
+#if ENABLE(DRAG_SUPPORT)
virtual void declareAndWriteDragImage(Element*, const KURL&, const String& title, Frame*);
+#endif
virtual void writeRange(Range*, Frame* frame);
virtual void writeURL(const KURL&, const String&, Frame* frame);
diff --git a/WebCore/platform/mac/ClipboardMac.mm b/WebCore/platform/mac/ClipboardMac.mm
index 52bc952..78fb659 100644
--- a/WebCore/platform/mac/ClipboardMac.mm
+++ b/WebCore/platform/mac/ClipboardMac.mm
@@ -63,7 +63,7 @@ bool ClipboardMac::hasData()
return m_pasteboard && [m_pasteboard.get() types] && [[m_pasteboard.get() types] count] > 0;
}
-static NSString *cocoaTypeFromMIMEType(const String& type)
+static NSString *cocoaTypeFromHTMLClipboardType(const String& type)
{
String qType = type.stripWhiteSpace();
@@ -82,10 +82,9 @@ static NSString *cocoaTypeFromMIMEType(const String& type)
// Try UTI now
NSString *mimeType = qType;
- CFStringRef UTIType = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, (CFStringRef)mimeType, NULL);
- if (UTIType) {
- CFStringRef pbType = UTTypeCopyPreferredTagWithClass(UTIType, kUTTagClassNSPboardType);
- CFRelease(UTIType);
+ RetainPtr<CFStringRef> utiType(AdoptCF, UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, (CFStringRef)mimeType, NULL));
+ if (utiType) {
+ CFStringRef pbType = UTTypeCopyPreferredTagWithClass(utiType.get(), kUTTagClassNSPboardType);
if (pbType)
return HardAutorelease(pbType);
}
@@ -94,28 +93,41 @@ static NSString *cocoaTypeFromMIMEType(const String& type)
return qType;
}
-static String MIMETypeFromCocoaType(NSString *type)
+static String utiTypeFromCocoaType(NSString *type)
+{
+ RetainPtr<CFStringRef> utiType(AdoptCF, UTTypeCreatePreferredIdentifierForTag(kUTTagClassNSPboardType, (CFStringRef)type, NULL));
+ if (utiType) {
+ RetainPtr<CFStringRef> mimeType(AdoptCF, UTTypeCopyPreferredTagWithClass(utiType.get(), kUTTagClassMIMEType));
+ if (mimeType)
+ return String(mimeType.get());
+ }
+ return String();
+}
+
+static void addHTMLClipboardTypesForCocoaType(HashSet<String>& resultTypes, NSString *cocoaType, NSPasteboard *pasteboard)
{
// UTI may not do these right, so make sure we get the right, predictable result
- if ([type isEqualToString:NSStringPboardType])
- return "text/plain";
- if ([type isEqualToString:NSURLPboardType] || [type isEqualToString:NSFilenamesPboardType])
- return "text/uri-list";
-
- // Now try the general UTI mechanism
- CFStringRef UTIType = UTTypeCreatePreferredIdentifierForTag(kUTTagClassNSPboardType, (CFStringRef)type, NULL);
- if (UTIType) {
- CFStringRef mimeType = UTTypeCopyPreferredTagWithClass(UTIType, kUTTagClassMIMEType);
- CFRelease(UTIType);
- if (mimeType) {
- String result = mimeType;
- CFRelease(mimeType);
- return result;
+ if ([cocoaType isEqualToString:NSStringPboardType])
+ resultTypes.add("text/plain");
+ else if ([cocoaType isEqualToString:NSURLPboardType])
+ resultTypes.add("text/uri-list");
+ else if ([cocoaType isEqualToString:NSFilenamesPboardType]) {
+ // If file list is empty, add nothing.
+ // Note that there is a chance that the file list count could have changed since we grabbed the types array.
+ // However, this is not really an issue for us doing a sanity check here.
+ NSArray *fileList = [pasteboard propertyListForType:NSFilenamesPboardType];
+ if ([fileList count]) {
+ // It is unknown if NSFilenamesPboardType always implies NSURLPboardType in Cocoa,
+ // but NSFilenamesPboardType should imply both 'text/uri-list' and 'Files'
+ resultTypes.add("text/uri-list");
+ resultTypes.add("Files");
}
+ } else if (String utiType = utiTypeFromCocoaType(cocoaType))
+ resultTypes.add(utiType);
+ else {
+ // No mapping, just pass the whole string though
+ resultTypes.add(cocoaType);
}
-
- // No mapping, just pass the whole string though
- return type;
}
void ClipboardMac::clearData(const String& type)
@@ -125,7 +137,7 @@ void ClipboardMac::clearData(const String& type)
// note NSPasteboard enforces changeCount itself on writing - can't write if not the owner
- NSString *cocoaType = cocoaTypeFromMIMEType(type);
+ NSString *cocoaType = cocoaTypeFromHTMLClipboardType(type);
if (cocoaType)
[m_pasteboard.get() setString:@"" forType:cocoaType];
}
@@ -192,12 +204,12 @@ String ClipboardMac::getData(const String& type, bool& success) const
if (policy() != ClipboardReadable)
return String();
- NSString *cocoaType = cocoaTypeFromMIMEType(type);
+ NSString *cocoaType = cocoaTypeFromHTMLClipboardType(type);
NSString *cocoaValue = nil;
// Grab the value off the pasteboard corresponding to the cocoaType
if ([cocoaType isEqualToString:NSURLPboardType]) {
- // "URL" and "text/url-list" both map to NSURLPboardType in cocoaTypeFromMIMEType(), "URL" only wants the first URL
+ // "URL" and "text/url-list" both map to NSURLPboardType in cocoaTypeFromHTMLClipboardType(), "URL" only wants the first URL
bool onlyFirstURL = (type == "URL");
NSArray *absoluteURLs = absoluteURLsFromPasteboard(m_pasteboard.get(), onlyFirstURL);
cocoaValue = [absoluteURLs componentsJoinedByString:@"\n"];
@@ -222,7 +234,7 @@ bool ClipboardMac::setData(const String &type, const String &data)
return false;
// note NSPasteboard enforces changeCount itself on writing - can't write if not the owner
- NSString *cocoaType = cocoaTypeFromMIMEType(type);
+ NSString *cocoaType = cocoaTypeFromHTMLClipboardType(type);
NSString *cocoaData = data;
if ([cocoaType isEqualToString:NSURLPboardType]) {
@@ -263,15 +275,16 @@ HashSet<String> ClipboardMac::types() const
HashSet<String> result;
NSUInteger count = [types count];
+ // FIXME: This loop could be split into two stages. One which adds all the HTML5 specified types
+ // and a second which adds all the extra types from the cocoa clipboard (which is Mac-only behavior).
for (NSUInteger i = 0; i < count; i++) {
NSString *pbType = [types objectAtIndex:i];
if ([pbType isEqualToString:@"NeXT plain ascii pasteboard type"])
continue; // skip this ancient type that gets auto-supplied by some system conversion
- String str = MIMETypeFromCocoaType(pbType);
- if (!result.contains(str))
- result.add(str);
+ addHTMLClipboardTypesForCocoaType(result, pbType, m_pasteboard.get());
}
+
return result;
}
@@ -283,7 +296,7 @@ PassRefPtr<FileList> ClipboardMac::files() const
if (policy() != ClipboardReadable)
return FileList::create();
- NSArray *absoluteURLs = absoluteURLsFromPasteboard(m_pasteboard.get());
+ NSArray *absoluteURLs = absoluteURLsFromPasteboardFilenames(m_pasteboard.get());
NSUInteger count = [absoluteURLs count];
RefPtr<FileList> fileList = FileList::create();
@@ -355,12 +368,14 @@ void ClipboardMac::writeURL(const KURL& url, const String& title, Frame* frame)
Pasteboard::writeURL(m_pasteboard.get(), nil, url, title, frame);
}
+#if ENABLE(DRAG_SUPPORT)
void ClipboardMac::declareAndWriteDragImage(Element* element, const KURL& url, const String& title, Frame* frame)
{
ASSERT(frame);
if (Page* page = frame->page())
page->dragController()->client()->declareAndWriteDragImage(m_pasteboard.get(), kit(element), url, title, frame);
}
+#endif // ENABLE(DRAG_SUPPORT)
DragImageRef ClipboardMac::createDragImage(IntPoint& loc) const
{
diff --git a/WebCore/platform/mac/ContextMenuItemMac.mm b/WebCore/platform/mac/ContextMenuItemMac.mm
index c5e2942..48da786 100644
--- a/WebCore/platform/mac/ContextMenuItemMac.mm
+++ b/WebCore/platform/mac/ContextMenuItemMac.mm
@@ -26,6 +26,8 @@
#include "config.h"
#include "ContextMenuItem.h"
+#if ENABLE(CONTEXT_MENUS)
+
#include "ContextMenu.h"
namespace WebCore {
@@ -152,4 +154,6 @@ bool ContextMenuItem::enabled() const
return [m_platformDescription.get() isEnabled];
}
-}
+} // namespace WebCore
+
+#endif // ENABLE(CONTEXT_MENUS)
diff --git a/WebCore/platform/mac/ContextMenuMac.mm b/WebCore/platform/mac/ContextMenuMac.mm
index b56d0b9..8ced8cb 100644
--- a/WebCore/platform/mac/ContextMenuMac.mm
+++ b/WebCore/platform/mac/ContextMenuMac.mm
@@ -26,6 +26,8 @@
#include "config.h"
#include "ContextMenu.h"
+#if ENABLE(CONTEXT_MENUS)
+
#include "ContextMenuController.h"
@interface WebCoreMenuTarget : NSObject {
@@ -151,4 +153,6 @@ NSMutableArray* ContextMenu::releasePlatformDescription()
return m_platformDescription.releaseRef();
}
-}
+} // namespace WebCore
+
+#endif // ENABLE(CONTEXT_MENUS)
diff --git a/WebCore/platform/mac/CookieJar.mm b/WebCore/platform/mac/CookieJar.mm
index d8df601..e1d3e5a 100644
--- a/WebCore/platform/mac/CookieJar.mm
+++ b/WebCore/platform/mac/CookieJar.mm
@@ -27,6 +27,7 @@
#import "CookieJar.h"
#import "BlockExceptions.h"
+#import "Cookie.h"
#import "Document.h"
#import "KURL.h"
#import <wtf/RetainPtr.h>
@@ -116,4 +117,52 @@ bool cookiesEnabled(const Document*)
return false;
}
+bool getRawCookies(const Document*, const KURL& url, Vector<Cookie>& rawCookies)
+{
+ rawCookies.clear();
+ BEGIN_BLOCK_OBJC_EXCEPTIONS;
+
+ NSURL *cookieURL = url;
+ NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:cookieURL];
+
+ NSUInteger count = [cookies count];
+ rawCookies.reserveCapacity(count);
+ for (NSUInteger i = 0; i < count; ++i) {
+ NSHTTPCookie *cookie = (NSHTTPCookie *)[cookies objectAtIndex:i];
+ NSString *name = [cookie name];
+ NSString *value = [cookie value];
+ NSString *domain = [cookie domain];
+ NSString *path = [cookie path];
+ NSTimeInterval expires = [[cookie expiresDate] timeIntervalSince1970] * 1000;
+ bool httpOnly = [cookie isHTTPOnly];
+ bool secure = [cookie isSecure];
+ bool session = [cookie isSessionOnly];
+ rawCookies.uncheckedAppend(Cookie(name, value, domain, path, expires, httpOnly, secure, session));
+ }
+
+ END_BLOCK_OBJC_EXCEPTIONS;
+ return true;
+}
+
+void deleteCookie(const Document*, const KURL& url, const String& cookieName)
+{
+ BEGIN_BLOCK_OBJC_EXCEPTIONS;
+
+ NSURL *cookieURL = url;
+ NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
+ NSArray *cookies = [cookieStorage cookiesForURL:cookieURL];
+ NSString *cookieNameString = (NSString *) cookieName;
+
+ NSUInteger count = [cookies count];
+ for (NSUInteger i = 0; i < count; ++i) {
+ NSHTTPCookie *cookie = (NSHTTPCookie *)[cookies objectAtIndex:i];
+ if ([[cookie name] isEqualToString:cookieNameString]) {
+ [cookieStorage deleteCookie:cookie];
+ break;
+ }
+ }
+
+ END_BLOCK_OBJC_EXCEPTIONS;
+}
+
}
diff --git a/WebCore/platform/mac/DragDataMac.mm b/WebCore/platform/mac/DragDataMac.mm
index a7b751c..02a6af7 100644
--- a/WebCore/platform/mac/DragDataMac.mm
+++ b/WebCore/platform/mac/DragDataMac.mm
@@ -26,6 +26,7 @@
#import "config.h"
#import "DragData.h"
+#if ENABLE(DRAG_SUPPORT)
#import "ClipboardMac.h"
#import "ClipboardAccessPolicy.h"
#import "Document.h"
@@ -127,5 +128,6 @@ PassRefPtr<DocumentFragment> DragData::asFragment(Document*) const
return core(m_pasteboardHelper->fragmentFromPasteboard([m_platformDragData draggingPasteboard]));
}
-}
+} // namespace WebCore
+#endif // ENABLE(DRAG_SUPPORT)
diff --git a/WebCore/platform/mac/DragImageMac.mm b/WebCore/platform/mac/DragImageMac.mm
index 842e6d4..7b51018 100644
--- a/WebCore/platform/mac/DragImageMac.mm
+++ b/WebCore/platform/mac/DragImageMac.mm
@@ -26,6 +26,7 @@
#import "config.h"
#import "DragImage.h"
+#if ENABLE(DRAG_SUPPORT)
#import "CachedImage.h"
#import "Image.h"
#import "KURL.h"
@@ -98,4 +99,6 @@ RetainPtr<NSImage> createDragImageIconForCachedImage(CachedImage* image)
return [[NSWorkspace sharedWorkspace] iconForFileType:extension];
}
-}
+} // namespace WebCore
+
+#endif // ENABLE(DRAG_SUPPORT)
diff --git a/WebCore/platform/mac/GeolocationServiceMac.h b/WebCore/platform/mac/GeolocationServiceMac.h
index d0342e7..4beefca 100644
--- a/WebCore/platform/mac/GeolocationServiceMac.h
+++ b/WebCore/platform/mac/GeolocationServiceMac.h
@@ -45,7 +45,7 @@ namespace WebCore {
class GeolocationServiceMac : public GeolocationService {
public:
- GeolocationServiceMac(GeolocationServiceClient*);
+ static GeolocationService* create(GeolocationServiceClient*);
virtual ~GeolocationServiceMac();
virtual bool startUpdating(PositionOptions*);
@@ -61,6 +61,8 @@ public:
void errorOccurred(PassRefPtr<PositionError>);
private:
+ GeolocationServiceMac(GeolocationServiceClient*);
+
RetainPtr<CLLocationManager> m_locationManager;
RetainPtr<WebCoreCoreLocationObserver> m_objcObserver;
diff --git a/WebCore/platform/mac/GeolocationServiceMac.mm b/WebCore/platform/mac/GeolocationServiceMac.mm
index 01eca4a..1093e69 100644
--- a/WebCore/platform/mac/GeolocationServiceMac.mm
+++ b/WebCore/platform/mac/GeolocationServiceMac.mm
@@ -65,11 +65,13 @@ using namespace WebCore;
namespace WebCore {
-GeolocationService* GeolocationService::create(GeolocationServiceClient* client)
+GeolocationService* GeolocationServiceMac::create(GeolocationServiceClient* client)
{
return new GeolocationServiceMac(client);
}
+GeolocationService::FactoryFunction* GeolocationService::s_factoryFunction = &GeolocationServiceMac::create;
+
GeolocationServiceMac::GeolocationServiceMac(GeolocationServiceClient* client)
: GeolocationService(client)
, m_objcObserver(AdoptNS, [[WebCoreCoreLocationObserver alloc] initWithCallback:this])
diff --git a/WebCore/platform/mac/LocalizedStringsMac.mm b/WebCore/platform/mac/LocalizedStringsMac.mm
index fdd7df5..261347f 100644
--- a/WebCore/platform/mac/LocalizedStringsMac.mm
+++ b/WebCore/platform/mac/LocalizedStringsMac.mm
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003, 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2003, 2006, 2009 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -89,6 +89,7 @@ String copyImageUnknownFileLabel()
return String();
}
+#if ENABLE(CONTEXT_MENUS)
String contextMenuItemTagOpenLinkInNewWindow()
{
BEGIN_BLOCK_OBJC_EXCEPTIONS;
@@ -544,6 +545,7 @@ String contextMenuItemTagInspectElement()
END_BLOCK_OBJC_EXCEPTIONS;
return String();
}
+#endif // ENABLE(CONTEXT_MENUS)
String searchMenuNoRecentSearchesText()
{
@@ -625,6 +627,14 @@ String AXDefinitionListDefinitionText()
return String();
}
+String AXARIAContentGroupText(const String& ariaType)
+{
+ BEGIN_BLOCK_OBJC_EXCEPTIONS;
+ return [[WebCoreViewFactory sharedFactory] AXARIAContentGroupText:ariaType];
+ END_BLOCK_OBJC_EXCEPTIONS;
+ return String();
+}
+
String AXButtonActionVerb()
{
BEGIN_BLOCK_OBJC_EXCEPTIONS;
@@ -713,4 +723,29 @@ String mediaElementLiveBroadcastStateText()
return String();
}
+String localizedMediaControlElementString(const String& controlName)
+{
+ BEGIN_BLOCK_OBJC_EXCEPTIONS;
+ return [[WebCoreViewFactory sharedFactory] localizedMediaControlElementString:controlName];
+ END_BLOCK_OBJC_EXCEPTIONS;
+ return String();
+}
+
+String localizedMediaControlElementHelpText(const String& controlName)
+{
+ BEGIN_BLOCK_OBJC_EXCEPTIONS;
+ return [[WebCoreViewFactory sharedFactory] localizedMediaControlElementHelpText:controlName];
+ END_BLOCK_OBJC_EXCEPTIONS;
+ return String();
+}
+
+String localizedMediaTimeDescription(float time)
+{
+ BEGIN_BLOCK_OBJC_EXCEPTIONS;
+ return [[WebCoreViewFactory sharedFactory] localizedMediaTimeDescription:time];
+ END_BLOCK_OBJC_EXCEPTIONS;
+ return String();
+}
+
+
}
diff --git a/WebCore/platform/mac/PasteboardMac.mm b/WebCore/platform/mac/PasteboardMac.mm
index e21f549..f048791 100644
--- a/WebCore/platform/mac/PasteboardMac.mm
+++ b/WebCore/platform/mac/PasteboardMac.mm
@@ -135,8 +135,8 @@ static NSAttributedString *stripAttachmentCharacters(NSAttributedString *string)
void Pasteboard::writeSelection(NSPasteboard* pasteboard, Range* selectedRange, bool canSmartCopyOrDelete, Frame* frame)
{
- if (WebArchivePboardType == nil)
- Pasteboard::generalPasteboard(); //Initialises pasteboard types
+ if (!WebArchivePboardType)
+ Pasteboard::generalPasteboard(); // Initialises pasteboard types
ASSERT(selectedRange);
NSAttributedString *attributedString = [[[NSAttributedString alloc] _initWithDOMRange:kit(selectedRange)] autorelease];
@@ -203,12 +203,24 @@ void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete,
Pasteboard::writeSelection(m_pasteboard.get(), selectedRange, canSmartCopyOrDelete, frame);
}
+void Pasteboard::writePlainText(const String& text)
+{
+ if (!WebArchivePboardType)
+ Pasteboard::generalPasteboard(); // Initialises pasteboard types
+
+ NSArray *types = [NSArray arrayWithObject:NSStringPboardType];
+ NSPasteboard *pasteboard = m_pasteboard.get();
+ [pasteboard declareTypes:types owner:nil];
+
+ [pasteboard setString:text forType:NSStringPboardType];
+}
+
void Pasteboard::writeURL(NSPasteboard* pasteboard, NSArray* types, const KURL& url, const String& titleStr, Frame* frame)
{
- if (WebArchivePboardType == nil)
- Pasteboard::generalPasteboard(); //Initialises pasteboard types
+ if (!WebArchivePboardType)
+ Pasteboard::generalPasteboard(); // Initialises pasteboard types
- if (types == nil) {
+ if (!types) {
types = writableTypesForURL();
[pasteboard declareTypes:types owner:nil];
}
diff --git a/WebCore/platform/mac/PopupMenuMac.mm b/WebCore/platform/mac/PopupMenuMac.mm
index b98235d..dfb0fff 100644
--- a/WebCore/platform/mac/PopupMenuMac.mm
+++ b/WebCore/platform/mac/PopupMenuMac.mm
@@ -105,7 +105,7 @@ void PopupMenu::show(const IntRect& r, FrameView* v, int index)
int numItems = [m_popup.get() numberOfItems];
if (numItems <= 0) {
if (client())
- client()->hidePopup();
+ client()->popupDidHide();
return;
}
ASSERT(numItems > index);
@@ -162,7 +162,7 @@ void PopupMenu::show(const IntRect& r, FrameView* v, int index)
if (client()) {
int newIndex = [m_popup.get() indexOfSelectedItem];
- client()->hidePopup();
+ client()->popupDidHide();
// Adjust newIndex for hidden first item.
if (!client()->shouldPopOver())
diff --git a/WebCore/platform/mac/ScrollViewMac.mm b/WebCore/platform/mac/ScrollViewMac.mm
index 5ff0ff5..202d49e 100644
--- a/WebCore/platform/mac/ScrollViewMac.mm
+++ b/WebCore/platform/mac/ScrollViewMac.mm
@@ -163,26 +163,12 @@ bool ScrollView::platformScroll(ScrollDirection, ScrollGranularity)
void ScrollView::platformRepaintContentRectangle(const IntRect& rect, bool now)
{
BEGIN_BLOCK_OBJC_EXCEPTIONS;
-
NSView *view = documentView();
- NSRect visibleRect = visibleContentRect();
-
- // FIXME: I don't think this intersection is necessary any more now that
- // selection doesn't call this method directly (but has to go through FrameView's
- // repaintContentRectangle, which does the intersection test also). Leaving it in
- // for now until I'm sure.
- // Checking for rect visibility is an important optimization for the case of
- // Select All of a large document. AppKit does not do this check, and so ends
- // up building a large complicated NSRegion if we don't perform the check.
- NSRect dirtyRect = NSIntersectionRect(rect, visibleRect);
- if (!NSIsEmptyRect(dirtyRect)) {
- [view setNeedsDisplayInRect:dirtyRect];
- if (now) {
- [[view window] displayIfNeeded];
- [[view window] flushWindowIfNeeded];
- }
+ [view setNeedsDisplayInRect:rect];
+ if (now) {
+ [[view window] displayIfNeeded];
+ [[view window] flushWindowIfNeeded];
}
-
END_BLOCK_OBJC_EXCEPTIONS;
}
diff --git a/WebCore/platform/mac/ThemeMac.mm b/WebCore/platform/mac/ThemeMac.mm
index e7e12ac..fd2f944 100644
--- a/WebCore/platform/mac/ThemeMac.mm
+++ b/WebCore/platform/mac/ThemeMac.mm
@@ -311,6 +311,14 @@ static const IntSize* buttonSizes()
return sizes;
}
+#if ENABLE(DATALIST)
+static const IntSize* listButtonSizes()
+{
+ static const IntSize sizes[3] = { IntSize(21, 21), IntSize(19, 18), IntSize(17, 16) };
+ return sizes;
+}
+#endif
+
static const int* buttonMargins(NSControlSize controlSize)
{
static const int margins[3][4] =
@@ -333,6 +341,13 @@ static NSButtonCell* button(ControlPart part, ControlStates states, const IntRec
}
// Set the control size based off the rectangle we're painting into.
+ const IntSize* sizes = buttonSizes();
+#if ENABLE(DATALIST)
+ if (part == ListButtonPart) {
+ [buttonCell setBezelStyle:NSRoundedDisclosureBezelStyle];
+ sizes = listButtonSizes();
+ } else
+#endif
if (part == SquareButtonPart || zoomedRect.height() > buttonSizes()[NSRegularControlSize].height() * zoomFactor) {
// Use the square button
if ([buttonCell bezelStyle] != NSShadowlessSquareBezelStyle)
@@ -362,7 +377,11 @@ static void paintButton(ControlPart part, ControlStates states, GraphicsContext*
LocalCurrentGraphicsContext localContext(context);
NSControlSize controlSize = [buttonCell controlSize];
+#if ENABLE(DATALIST)
+ IntSize zoomedSize = (part == ListButtonPart ? listButtonSizes() : buttonSizes())[controlSize];
+#else
IntSize zoomedSize = buttonSizes()[controlSize];
+#endif
zoomedSize.setWidth(zoomedRect.width()); // Buttons don't ever constrain width, so the zoomed width can just be honored.
zoomedSize.setHeight(zoomedSize.height() * zoomFactor);
IntRect inflatedRect = zoomedRect;
@@ -442,6 +461,10 @@ LengthSize ThemeMac::controlSize(ControlPart part, const Font& font, const Lengt
case PushButtonPart:
// Height is reset to auto so that specified heights can be ignored.
return sizeFromFont(font, LengthSize(zoomedSize.width(), Length()), zoomFactor, buttonSizes());
+#if ENABLE(DATALIST)
+ case ListButtonPart:
+ return sizeFromFont(font, LengthSize(zoomedSize.width(), Length()), zoomFactor, listButtonSizes());
+#endif
default:
return zoomedSize;
}
@@ -453,6 +476,7 @@ LengthSize ThemeMac::minimumControlSize(ControlPart part, const Font& font, floa
case SquareButtonPart:
case DefaultButtonPart:
case ButtonPart:
+ case ListButtonPart:
return LengthSize(Length(0, Fixed), Length(static_cast<int>(15 * zoomFactor), Fixed));
default:
return Theme::minimumControlSize(part, font, zoomFactor);
@@ -465,6 +489,7 @@ LengthBox ThemeMac::controlBorder(ControlPart part, const Font& font, const Leng
case SquareButtonPart:
case DefaultButtonPart:
case ButtonPart:
+ case ListButtonPart:
return LengthBox(0, zoomedBox.right().value(), 0, zoomedBox.left().value());
default:
return Theme::controlBorder(part, font, zoomedBox, zoomFactor);
@@ -548,6 +573,7 @@ void ThemeMac::paint(ControlPart part, ControlStates states, GraphicsContext* co
case DefaultButtonPart:
case ButtonPart:
case SquareButtonPart:
+ case ListButtonPart:
paintButton(part, states, context, zoomedRect, zoomFactor, scrollView);
break;
default:
diff --git a/WebCore/platform/mac/WebCoreNSStringExtras.mm b/WebCore/platform/mac/WebCoreNSStringExtras.mm
index b7087f1..d6c3f0c 100644
--- a/WebCore/platform/mac/WebCoreNSStringExtras.mm
+++ b/WebCore/platform/mac/WebCoreNSStringExtras.mm
@@ -29,6 +29,8 @@
#import "config.h"
#import "WebCoreNSStringExtras.h"
+#import <wtf/RetainPtr.h>
+
BOOL stringIsCaseInsensitiveEqualToString(NSString *first, NSString *second)
{
return [first compare:second options:(NSCaseInsensitiveSearch|NSLiteralSearch)] == NSOrderedSame;
@@ -69,50 +71,41 @@ NSString *filenameByFixingIllegalCharacters(NSString *string)
CFStringEncoding stringEncodingForResource(Handle resource)
{
short resRef = HomeResFile(resource);
- if (ResError() != noErr) {
+ if (ResError() != noErr)
return NSMacOSRomanStringEncoding;
- }
// Get the FSRef for the current resource file
FSRef fref;
OSStatus error = FSGetForkCBInfo(resRef, 0, NULL, NULL, NULL, &fref, NULL);
- if (error != noErr) {
+ if (error != noErr)
return NSMacOSRomanStringEncoding;
- }
- CFURLRef URL = CFURLCreateFromFSRef(NULL, &fref);
- if (URL == NULL) {
+ RetainPtr<CFURLRef> url(AdoptCF, CFURLCreateFromFSRef(NULL, &fref));
+ if (!url)
return NSMacOSRomanStringEncoding;
- }
-
- NSString *path = [(NSURL *)URL path];
- CFRelease(URL);
-
+
+ NSString *path = [(NSURL *)url.get() path];
+
// Get the lproj directory name
path = [path stringByDeletingLastPathComponent];
- if (!stringIsCaseInsensitiveEqualToString([path pathExtension], @"lproj")) {
+ if (!stringIsCaseInsensitiveEqualToString([path pathExtension], @"lproj"))
return NSMacOSRomanStringEncoding;
- }
NSString *directoryName = [[path stringByDeletingPathExtension] lastPathComponent];
- CFStringRef locale = CFLocaleCreateCanonicalLocaleIdentifierFromString(NULL, (CFStringRef)directoryName);
- if (locale == NULL) {
+ RetainPtr<CFStringRef> locale(AdoptCF, CFLocaleCreateCanonicalLocaleIdentifierFromString(NULL, (CFStringRef)directoryName));
+ if (!locale)
return NSMacOSRomanStringEncoding;
- }
-
+
LangCode lang;
RegionCode region;
- error = LocaleStringToLangAndRegionCodes([(NSString *)locale UTF8String], &lang, &region);
- CFRelease(locale);
- if (error != noErr) {
+ error = LocaleStringToLangAndRegionCodes([(NSString *)locale.get() UTF8String], &lang, &region);
+ if (error != noErr)
return NSMacOSRomanStringEncoding;
- }
-
+
TextEncoding encoding;
error = UpgradeScriptInfoToTextEncoding(kTextScriptDontCare, lang, region, NULL, &encoding);
- if (error != noErr) {
+ if (error != noErr)
return NSMacOSRomanStringEncoding;
- }
return encoding;
}
diff --git a/WebCore/platform/network/Credential.cpp b/WebCore/platform/network/Credential.cpp
index 4743959..caca785 100644
--- a/WebCore/platform/network/Credential.cpp
+++ b/WebCore/platform/network/Credential.cpp
@@ -43,6 +43,11 @@ Credential::Credential(const String& user, const String& password, CredentialPer
, m_persistence(persistence)
{
}
+
+bool Credential::isEmpty()
+{
+ return m_user.isEmpty() && m_password.isEmpty();
+}
const String& Credential::user() const
{
diff --git a/WebCore/platform/network/Credential.h b/WebCore/platform/network/Credential.h
index 4d80490..ca4a45a 100644
--- a/WebCore/platform/network/Credential.h
+++ b/WebCore/platform/network/Credential.h
@@ -41,6 +41,8 @@ public:
Credential();
Credential(const String& user, const String& password, CredentialPersistence);
+ bool isEmpty();
+
const String& user() const;
const String& password() const;
bool hasPassword() const;
diff --git a/WebCore/platform/network/CredentialStorage.cpp b/WebCore/platform/network/CredentialStorage.cpp
new file mode 100644
index 0000000..407ed5b
--- /dev/null
+++ b/WebCore/platform/network/CredentialStorage.cpp
@@ -0,0 +1,124 @@
+/*
+ * 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 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 "CredentialStorage.h"
+
+#include "CString.h"
+#include "Credential.h"
+#include "KURL.h"
+#include "ProtectionSpaceHash.h"
+#include "StringHash.h"
+
+#include <wtf/StdLibExtras.h>
+
+namespace WebCore {
+
+typedef HashMap<ProtectionSpace, Credential> ProtectionSpaceToCredentialMap;
+static ProtectionSpaceToCredentialMap& protectionSpaceToCredentialMap()
+{
+ DEFINE_STATIC_LOCAL(ProtectionSpaceToCredentialMap, map, ());
+ return map;
+}
+
+typedef HashMap<String, HashMap<String, Credential> > OriginToDefaultBasicCredentialMap;
+static OriginToDefaultBasicCredentialMap& originToDefaultBasicCredentialMap()
+{
+ DEFINE_STATIC_LOCAL(OriginToDefaultBasicCredentialMap, map, ());
+ return map;
+}
+
+static String originStringFromURL(const KURL& url)
+{
+ if (url.port())
+ return url.protocol() + "://" + url.host() + String::format(":%i/", url.port());
+
+ return url.protocol() + "://" + url.host() + "/";
+}
+
+void CredentialStorage::set(const Credential& credential, const ProtectionSpace& protectionSpace, const KURL& url)
+{
+ ASSERT(url.protocolInHTTPFamily());
+ ASSERT(url.isValid());
+
+ protectionSpaceToCredentialMap().set(protectionSpace, credential);
+
+ ProtectionSpaceAuthenticationScheme scheme = protectionSpace.authenticationScheme();
+ if (url.protocolInHTTPFamily() && (scheme == ProtectionSpaceAuthenticationSchemeHTTPBasic || scheme == ProtectionSpaceAuthenticationSchemeDefault)) {
+ String origin = originStringFromURL(url);
+
+ HashMap<String, Credential> pathToCredentialMap;
+ pair<HashMap<String, HashMap<String, Credential> >::iterator, bool> result = originToDefaultBasicCredentialMap().add(origin, pathToCredentialMap);
+
+ // Remove the last path component that is not a directory to determine the subpath for which this credential applies.
+ // We keep a leading slash, but remove a trailing one.
+ String path = url.path();
+ ASSERT(path.length() > 0);
+ ASSERT(path[0] == '/');
+ if (path.length() > 1) {
+ int index = path.reverseFind('/');
+ path = path.substring(0, index ? index : 1);
+ }
+ ASSERT(path.length() == 1 || path[path.length() - 1] != '/');
+
+ result.first->second.set(path, credential);
+ }
+}
+
+Credential CredentialStorage::get(const ProtectionSpace& protectionSpace)
+{
+ return protectionSpaceToCredentialMap().get(protectionSpace);
+}
+
+Credential CredentialStorage::getDefaultAuthenticationCredential(const KURL& url)
+{
+ ASSERT(url.protocolInHTTPFamily());
+ String origin = originStringFromURL(url);
+ const HashMap<String, Credential>& pathToCredentialMap(originToDefaultBasicCredentialMap().get(origin));
+ if (pathToCredentialMap.isEmpty())
+ return Credential();
+
+ // Check to see if there is a stored credential for the subpath ancestry of this url.
+ String path = url.path();
+ Credential credential = pathToCredentialMap.get(path);
+ while (credential.isEmpty() && !path.isNull()) {
+ int index = path.reverseFind('/');
+ if (index == 0) {
+ credential = pathToCredentialMap.get("/");
+ break;
+ } else if (index == -1) {
+ // This case should never happen, as all HTTP URL paths should start with a leading /
+ ASSERT_NOT_REACHED();
+ credential = pathToCredentialMap.get(path);
+ break;
+ } else {
+ path = path.substring(0, index);
+ credential = pathToCredentialMap.get(path);
+ }
+ }
+ return credential;
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/network/CredentialStorage.h b/WebCore/platform/network/CredentialStorage.h
new file mode 100644
index 0000000..737efa6
--- /dev/null
+++ b/WebCore/platform/network/CredentialStorage.h
@@ -0,0 +1,44 @@
+/*
+ * 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 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 SessionCredentialStorage_h
+#define SessionCredentialStorage_h
+
+namespace WebCore {
+
+class Credential;
+class KURL;
+class ProtectionSpace;
+
+class CredentialStorage {
+public:
+ static void set(const Credential&, const ProtectionSpace&, const KURL&);
+ static Credential get(const ProtectionSpace&);
+ static Credential getDefaultAuthenticationCredential(const KURL&);
+};
+
+} // namespace WebCore
+
+#endif // SessionCredentialStorage_h
diff --git a/WebCore/platform/network/HTTPHeaderMap.cpp b/WebCore/platform/network/HTTPHeaderMap.cpp
index ff470a0..07c66e8 100644
--- a/WebCore/platform/network/HTTPHeaderMap.cpp
+++ b/WebCore/platform/network/HTTPHeaderMap.cpp
@@ -45,7 +45,7 @@ auto_ptr<CrossThreadHTTPHeaderMapData> HTTPHeaderMap::copyData() const
HTTPHeaderMap::const_iterator end_it = end();
for (HTTPHeaderMap::const_iterator it = begin(); it != end_it; ++it) {
- data->append(make_pair(it->first.string().copy(), it->second.copy()));
+ data->append(make_pair(it->first.string().crossThreadString(), it->second.crossThreadString()));
}
return data;
}
diff --git a/WebCore/platform/network/ProtectionSpace.cpp b/WebCore/platform/network/ProtectionSpace.cpp
index bd73558..d04bcbe 100644
--- a/WebCore/platform/network/ProtectionSpace.cpp
+++ b/WebCore/platform/network/ProtectionSpace.cpp
@@ -37,7 +37,11 @@ namespace WebCore {
// combined with the semantics of the String(NSString*) constructor
ProtectionSpace::ProtectionSpace()
: m_host("")
+ , m_port(0)
+ , m_serverType(ProtectionSpaceServerHTTP)
, m_realm("")
+ , m_authenticationScheme(ProtectionSpaceAuthenticationSchemeDefault)
+ , m_isHashTableDeletedValue(false)
{
}
@@ -49,6 +53,7 @@ ProtectionSpace::ProtectionSpace(const String& host, int port, ProtectionSpaceSe
, m_serverType(serverType)
, m_realm(realm.length() ? realm : "")
, m_authenticationScheme(authenticationScheme)
+ , m_isHashTableDeletedValue(false)
{
}
diff --git a/WebCore/platform/network/ProtectionSpace.h b/WebCore/platform/network/ProtectionSpace.h
index 9a73cff..126b499 100644
--- a/WebCore/platform/network/ProtectionSpace.h
+++ b/WebCore/platform/network/ProtectionSpace.h
@@ -54,6 +54,10 @@ class ProtectionSpace {
public:
ProtectionSpace();
ProtectionSpace(const String& host, int port, ProtectionSpaceServerType, const String& realm, ProtectionSpaceAuthenticationScheme);
+
+ // Hash table deleted values, which are only constructed and never copied or destroyed.
+ ProtectionSpace(WTF::HashTableDeletedValueType) : m_isHashTableDeletedValue(true) { }
+ bool isHashTableDeletedValue() const { return m_isHashTableDeletedValue; }
const String& host() const;
int port() const;
@@ -70,10 +74,12 @@ private:
ProtectionSpaceServerType m_serverType;
String m_realm;
ProtectionSpaceAuthenticationScheme m_authenticationScheme;
+ bool m_isHashTableDeletedValue;
};
bool operator==(const ProtectionSpace& a, const ProtectionSpace& b);
inline bool operator!=(const ProtectionSpace& a, const ProtectionSpace& b) { return !(a == b); }
-}
-#endif
+} // namespace WebCore
+
+#endif // ProtectionSpace_h
diff --git a/WebCore/platform/network/ProtectionSpaceHash.h b/WebCore/platform/network/ProtectionSpaceHash.h
new file mode 100644
index 0000000..6f68b5b
--- /dev/null
+++ b/WebCore/platform/network/ProtectionSpaceHash.h
@@ -0,0 +1,70 @@
+/*
+ * 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 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 ProtectionSpaceHash_h
+#define ProtectionSpaceHash_h
+
+#include "ProtectionSpace.h"
+
+namespace WebCore {
+
+struct ProtectionSpaceHash {
+ static unsigned hash(const ProtectionSpace& protectionSpace)
+ {
+ unsigned hashCodes[5] = {
+ protectionSpace.host().impl() ? protectionSpace.host().impl()->hash() : 0,
+ protectionSpace.port(),
+ protectionSpace.serverType(),
+ protectionSpace.realm().impl() ? protectionSpace.realm().impl()->hash() : 0,
+ protectionSpace.authenticationScheme()
+ };
+
+ return StringImpl::computeHash(reinterpret_cast<UChar*>(hashCodes), sizeof(hashCodes) / sizeof(UChar));
+ }
+
+ static bool equal(const ProtectionSpace& a, const ProtectionSpace& b) { return a == b; }
+ static const bool safeToCompareToEmptyOrDeleted = false;
+};
+
+} // namespace WebCore
+
+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<typename T> struct DefaultHash;
+ template<> struct DefaultHash<WebCore::ProtectionSpace> {
+ typedef WebCore::ProtectionSpaceHash Hash;
+ };
+
+} // namespace WTF
+
+
+#endif // ProtectionSpaceHash_h
diff --git a/WebCore/platform/network/ResourceErrorBase.cpp b/WebCore/platform/network/ResourceErrorBase.cpp
index 370650f..97435ba 100644
--- a/WebCore/platform/network/ResourceErrorBase.cpp
+++ b/WebCore/platform/network/ResourceErrorBase.cpp
@@ -34,10 +34,10 @@ ResourceError ResourceErrorBase::copy() const
lazyInit();
ResourceError errorCopy;
- errorCopy.m_domain = m_domain.copy();
+ errorCopy.m_domain = m_domain.crossThreadString();
errorCopy.m_errorCode = m_errorCode;
- errorCopy.m_failingURL = m_failingURL.copy();
- errorCopy.m_localizedDescription = m_localizedDescription.copy();
+ errorCopy.m_failingURL = m_failingURL.crossThreadString();
+ errorCopy.m_localizedDescription = m_localizedDescription.crossThreadString();
errorCopy.m_isNull = m_isNull;
errorCopy.m_isCancellation = m_isCancellation;
return errorCopy;
diff --git a/WebCore/platform/network/ResourceHandleInternal.h b/WebCore/platform/network/ResourceHandleInternal.h
index 7951109..31d740a 100644
--- a/WebCore/platform/network/ResourceHandleInternal.h
+++ b/WebCore/platform/network/ResourceHandleInternal.h
@@ -159,6 +159,8 @@ namespace WebCore {
String m_user;
String m_pass;
+ Credential m_initialCredential;
+
int status;
bool m_defersLoading;
diff --git a/WebCore/platform/network/ResourceRequestBase.cpp b/WebCore/platform/network/ResourceRequestBase.cpp
index f9ecb6b..a568cc7 100644
--- a/WebCore/platform/network/ResourceRequestBase.cpp
+++ b/WebCore/platform/network/ResourceRequestBase.cpp
@@ -62,7 +62,7 @@ auto_ptr<ResourceRequest> ResourceRequestBase::adopt(auto_ptr<CrossThreadResourc
request->setResponseContentDispositionEncodingFallbackArray(encoding1, encoding2, encoding3);
}
request->setHTTPBody(data->m_httpBody);
- request->setAllowHTTPCookies(data->m_allowHTTPCookies);
+ request->setAllowCookies(data->m_allowCookies);
return request;
}
@@ -73,17 +73,17 @@ auto_ptr<CrossThreadResourceRequestData> ResourceRequestBase::copyData() const
data->m_cachePolicy = cachePolicy();
data->m_timeoutInterval = timeoutInterval();
data->m_firstPartyForCookies = firstPartyForCookies().copy();
- data->m_httpMethod = httpMethod().copy();
+ data->m_httpMethod = httpMethod().crossThreadString();
data->m_httpHeaders.adopt(httpHeaderFields().copyData());
data->m_responseContentDispositionEncodingFallbackArray.reserveInitialCapacity(m_responseContentDispositionEncodingFallbackArray.size());
size_t encodingArraySize = m_responseContentDispositionEncodingFallbackArray.size();
for (size_t index = 0; index < encodingArraySize; ++index) {
- data->m_responseContentDispositionEncodingFallbackArray.append(m_responseContentDispositionEncodingFallbackArray[index].copy());
+ data->m_responseContentDispositionEncodingFallbackArray.append(m_responseContentDispositionEncodingFallbackArray[index].crossThreadString());
}
if (m_httpBody)
data->m_httpBody = m_httpBody->deepCopy();
- data->m_allowHTTPCookies = m_allowHTTPCookies;
+ data->m_allowCookies = m_allowCookies;
return data;
}
@@ -251,18 +251,18 @@ void ResourceRequestBase::setHTTPBody(PassRefPtr<FormData> httpBody)
m_platformRequestUpdated = false;
}
-bool ResourceRequestBase::allowHTTPCookies() const
+bool ResourceRequestBase::allowCookies() const
{
updateResourceRequest();
- return m_allowHTTPCookies;
+ return m_allowCookies;
}
-void ResourceRequestBase::setAllowHTTPCookies(bool allowHTTPCookies)
+void ResourceRequestBase::setAllowCookies(bool allowCookies)
{
updateResourceRequest();
- m_allowHTTPCookies = allowHTTPCookies;
+ m_allowCookies = allowCookies;
if (url().protocolInHTTPFamily())
m_platformRequestUpdated = false;
@@ -274,6 +274,9 @@ void ResourceRequestBase::addHTTPHeaderField(const AtomicString& name, const Str
pair<HTTPHeaderMap::iterator, bool> result = m_httpHeaderFields.add(name, value);
if (!result.second)
result.first->second += "," + value;
+
+ if (url().protocolInHTTPFamily())
+ m_platformRequestUpdated = false;
}
void ResourceRequestBase::addHTTPHeaderFields(const HTTPHeaderMap& headerFields)
@@ -300,7 +303,7 @@ bool equalIgnoringHeaderFields(const ResourceRequestBase& a, const ResourceReque
if (a.httpMethod() != b.httpMethod())
return false;
- if (a.allowHTTPCookies() != b.allowHTTPCookies())
+ if (a.allowCookies() != b.allowCookies())
return false;
FormData* formDataA = a.httpBody();
@@ -355,7 +358,11 @@ void ResourceRequestBase::updateResourceRequest() const
m_resourceRequestUpdated = true;
}
+<<<<<<< HEAD:WebCore/platform/network/ResourceRequestBase.cpp
#if !PLATFORM(MAC) && !USE(CFNETWORK) && !PLATFORM(ANDROID)
+=======
+#if !PLATFORM(MAC) && !USE(CFNETWORK) && !USE(SOUP)
+>>>>>>> webkit.org at 49305:WebCore/platform/network/ResourceRequestBase.cpp
unsigned initializeMaximumHTTPConnectionCountPerHost()
{
// This is used by the loader to control the number of issued parallel load requests.
diff --git a/WebCore/platform/network/ResourceRequestBase.h b/WebCore/platform/network/ResourceRequestBase.h
index 2d87d6e..348e6b3 100644
--- a/WebCore/platform/network/ResourceRequestBase.h
+++ b/WebCore/platform/network/ResourceRequestBase.h
@@ -105,8 +105,8 @@ namespace WebCore {
FormData* httpBody() const;
void setHTTPBody(PassRefPtr<FormData> httpBody);
- bool allowHTTPCookies() const;
- void setAllowHTTPCookies(bool allowHTTPCookies);
+ bool allowCookies() const;
+ void setAllowCookies(bool allowCookies);
bool isConditional() const;
@@ -129,7 +129,7 @@ namespace WebCore {
, m_cachePolicy(policy)
, m_timeoutInterval(unspecifiedTimeoutInterval)
, m_httpMethod("GET")
- , m_allowHTTPCookies(true)
+ , m_allowCookies(true)
, m_resourceRequestUpdated(true)
, m_platformRequestUpdated(false)
, m_reportUploadProgress(false)
@@ -148,7 +148,7 @@ namespace WebCore {
HTTPHeaderMap m_httpHeaderFields;
Vector<String> m_responseContentDispositionEncodingFallbackArray;
RefPtr<FormData> m_httpBody;
- bool m_allowHTTPCookies;
+ bool m_allowCookies;
mutable bool m_resourceRequestUpdated;
mutable bool m_platformRequestUpdated;
bool m_reportUploadProgress;
@@ -173,7 +173,7 @@ namespace WebCore {
OwnPtr<CrossThreadHTTPHeaderMapData> m_httpHeaders;
Vector<String> m_responseContentDispositionEncodingFallbackArray;
RefPtr<FormData> m_httpBody;
- bool m_allowHTTPCookies;
+ bool m_allowCookies;
};
unsigned initializeMaximumHTTPConnectionCountPerHost();
diff --git a/WebCore/platform/network/ResourceResponseBase.cpp b/WebCore/platform/network/ResourceResponseBase.cpp
index 7f8a4e2..fd44225 100644
--- a/WebCore/platform/network/ResourceResponseBase.cpp
+++ b/WebCore/platform/network/ResourceResponseBase.cpp
@@ -108,12 +108,12 @@ auto_ptr<CrossThreadResourceResponseData> ResourceResponseBase::copyData() const
{
auto_ptr<CrossThreadResourceResponseData> data(new CrossThreadResourceResponseData());
data->m_url = url().copy();
- data->m_mimeType = mimeType().copy();
+ data->m_mimeType = mimeType().crossThreadString();
data->m_expectedContentLength = expectedContentLength();
- data->m_textEncodingName = textEncodingName().copy();
- data->m_suggestedFilename = suggestedFilename().copy();
+ data->m_textEncodingName = textEncodingName().crossThreadString();
+ data->m_suggestedFilename = suggestedFilename().crossThreadString();
data->m_httpStatusCode = httpStatusCode();
- data->m_httpStatusText = httpStatusText().copy();
+ data->m_httpStatusText = httpStatusText().crossThreadString();
data->m_httpHeaders.adopt(httpHeaderFields().copyData());
data->m_lastModifiedDate = lastModifiedDate();
return data;
diff --git a/WebCore/platform/sql/chromium/SQLiteFileSystemChromiumMac.cpp b/WebCore/platform/network/SocketStreamErrorBase.cpp
index 35a40f5..72fb44c 100644
--- a/WebCore/platform/sql/chromium/SQLiteFileSystemChromiumMac.cpp
+++ b/WebCore/platform/network/SocketStreamErrorBase.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -29,14 +29,20 @@
*/
#include "config.h"
-#include "SQLiteFileSystem.h"
+#include "SocketStreamError.h"
namespace WebCore {
-void SQLiteFileSystem::registerSQLiteVFS()
+SocketStreamError SocketStreamErrorBase::copy() const
{
- // stub for registering Chromium's SQLite VFS for Mac
- ASSERT_NOT_REACHED();
+ SocketStreamError errorCopy;
+ errorCopy.m_errorCode = m_errorCode;
+ return errorCopy;
}
-} // namespace WebCore
+bool SocketStreamErrorBase::compare(const SocketStreamError& a, const SocketStreamError& b)
+{
+ return a.errorCode() == b.errorCode();
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/network/SocketStreamErrorBase.h b/WebCore/platform/network/SocketStreamErrorBase.h
new file mode 100644
index 0000000..b7ca35b
--- /dev/null
+++ b/WebCore/platform/network/SocketStreamErrorBase.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SocketStreamErrorBase_h
+#define SocketStreamErrorBase_h
+
+namespace WebCore {
+
+ class SocketStreamError;
+
+ class SocketStreamErrorBase {
+ public:
+ // Makes a deep copy. Useful for when you need to use a SocketStreamError on another thread.
+ SocketStreamError copy() const;
+
+ bool isNull() const { return m_isNull; }
+
+ int errorCode() const { return m_errorCode; }
+
+ static bool compare(const SocketStreamError&, const SocketStreamError&);
+
+ protected:
+ SocketStreamErrorBase()
+ : m_errorCode(0)
+ , m_isNull(true)
+ {
+ }
+
+ explicit SocketStreamErrorBase(int errorCode)
+ : m_errorCode(errorCode)
+ , m_isNull(false)
+ {
+ }
+
+ int m_errorCode;
+ bool m_isNull;
+ };
+
+ inline bool operator==(const SocketStreamError& a, const SocketStreamError& b) { return SocketStreamErrorBase::compare(a, b); }
+ inline bool operator!=(const SocketStreamError& a, const SocketStreamError& b) { return !(a == b); }
+
+} // namespace WebCore
+
+#endif // SocketStreamErrorBase_h
diff --git a/WebCore/platform/network/SocketStreamHandleBase.cpp b/WebCore/platform/network/SocketStreamHandleBase.cpp
new file mode 100644
index 0000000..875c248
--- /dev/null
+++ b/WebCore/platform/network/SocketStreamHandleBase.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "SocketStreamHandleBase.h"
+
+#include "SocketStreamHandleClient.h"
+
+namespace WebCore {
+
+const unsigned int bufferSize = 100 * 1024 * 1024;
+
+SocketStreamHandleBase::SocketStreamHandleBase(const KURL& url, SocketStreamHandleClient* client)
+ : m_url(url)
+ , m_client(client)
+ , m_state(Connecting)
+{
+}
+
+SocketStreamHandleBase::SocketStreamState SocketStreamHandleBase::state() const
+{
+ return m_state;
+}
+
+bool SocketStreamHandleBase::send(const char* data, int length)
+{
+ if (m_state == Connecting)
+ return false;
+ if (!m_buffer.isEmpty()) {
+ if (m_buffer.size() + length > bufferSize) {
+ // FIXME: report error to indicate that buffer has no more space.
+ return false;
+ }
+ m_buffer.append(data, length);
+ return true;
+ }
+ int bytesWritten = 0;
+ if (m_state == Open)
+ bytesWritten = platformSend(data, length);
+ if (bytesWritten <= 0)
+ return false;
+ if (m_buffer.size() + length - bytesWritten > bufferSize) {
+ // FIXME: report error to indicate that buffer has no more space.
+ return false;
+ }
+ if (bytesWritten < length)
+ m_buffer.append(data + bytesWritten, length - bytesWritten);
+ return true;
+}
+
+void SocketStreamHandleBase::close()
+{
+ platformClose();
+ m_state = Closed;
+}
+
+void SocketStreamHandleBase::setClient(SocketStreamHandleClient* client)
+{
+ ASSERT(!client || (!m_client && m_state == Connecting));
+ m_client = client;
+}
+
+bool SocketStreamHandleBase::sendPendingData()
+{
+ if (m_state != Open)
+ return false;
+ if (m_buffer.isEmpty())
+ return false;
+ int bytesWritten = platformSend(m_buffer.data(), m_buffer.size());
+ if (bytesWritten <= 0)
+ return false;
+ Vector<char> remainingData;
+ ASSERT(m_buffer.size() - bytesWritten <= bufferSize);
+ remainingData.append(m_buffer.data() + bytesWritten, m_buffer.size() - bytesWritten);
+ m_buffer.swap(remainingData);
+ return true;
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/network/SocketStreamHandleBase.h b/WebCore/platform/network/SocketStreamHandleBase.h
new file mode 100644
index 0000000..fc011dd
--- /dev/null
+++ b/WebCore/platform/network/SocketStreamHandleBase.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SocketStreamHandleBase_h
+#define SocketStreamHandleBase_h
+
+#include "KURL.h"
+
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+ class SocketStreamHandle;
+ class SocketStreamHandleClient;
+
+ class SocketStreamHandleBase {
+ public:
+ enum SocketStreamState { Connecting, Open, Closed };
+ virtual ~SocketStreamHandleBase() { }
+ SocketStreamState state() const;
+
+ bool send(const char* data, int length);
+ void close();
+ int bufferedAmount() const { return m_buffer.size(); }
+
+ SocketStreamHandleClient* client() const { return m_client; }
+ void setClient(SocketStreamHandleClient*);
+
+ protected:
+ SocketStreamHandleBase(const KURL&, SocketStreamHandleClient*);
+
+ bool sendPendingData();
+ virtual int platformSend(const char* data, int length) = 0;
+ virtual void platformClose() = 0;
+
+ KURL m_url;
+ SocketStreamHandleClient* m_client;
+ Vector<char> m_buffer;
+ SocketStreamState m_state;
+ };
+
+} // namespace WebCore
+
+#endif // SocketStreamHandleBase_h
diff --git a/WebCore/platform/network/SocketStreamHandleClient.h b/WebCore/platform/network/SocketStreamHandleClient.h
new file mode 100644
index 0000000..04c744e
--- /dev/null
+++ b/WebCore/platform/network/SocketStreamHandleClient.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SocketStreamHandleClient_h
+#define SocketStreamHandleClient_h
+
+namespace WebCore {
+
+ class AuthenticationChallenge;
+ class KURL;
+ class SocketStreamError;
+ class SocketStreamHandle;
+
+ class SocketStreamHandleClient {
+ public:
+ virtual ~SocketStreamHandleClient() { }
+
+ virtual void willOpenStream(SocketStreamHandle*, const KURL&) { }
+ virtual void willSendData(SocketStreamHandle*, const char* /*data*/, int /*length*/) { }
+
+ virtual void didOpen(SocketStreamHandle*) { }
+ virtual void didClose(SocketStreamHandle*) { }
+ virtual void didReceiveData(SocketStreamHandle*, const char* /*data*/, int /*length*/) { }
+
+ virtual void didFail(SocketStreamHandle*, const SocketStreamError&) { }
+
+ virtual void didReceiveAuthenticationChallenge(SocketStreamHandle*, const AuthenticationChallenge&) { }
+ virtual void didCancelAuthenticationChallenge(SocketStreamHandle*, const AuthenticationChallenge&) { }
+ virtual void receivedCancellation(SocketStreamHandle*, const AuthenticationChallenge&) { }
+ };
+
+} // namespace WebCore
+
+#endif // SocketStreamHandleClient_h
diff --git a/WebCore/platform/network/cf/AuthenticationCF.cpp b/WebCore/platform/network/cf/AuthenticationCF.cpp
index 51d60a4..bb05a39 100644
--- a/WebCore/platform/network/cf/AuthenticationCF.cpp
+++ b/WebCore/platform/network/cf/AuthenticationCF.cpp
@@ -37,8 +37,6 @@
namespace WebCore {
-CFMutableDictionaryRef WebCoreCredentialStorage::m_storage;
-
AuthenticationChallenge::AuthenticationChallenge(const ProtectionSpace& protectionSpace,
const Credential& proposedCredential,
unsigned previousFailureCount,
diff --git a/WebCore/platform/network/cf/AuthenticationCF.h b/WebCore/platform/network/cf/AuthenticationCF.h
index d3fc014..55f3e5f 100644
--- a/WebCore/platform/network/cf/AuthenticationCF.h
+++ b/WebCore/platform/network/cf/AuthenticationCF.h
@@ -43,26 +43,6 @@ CFURLProtectionSpaceRef createCF(const ProtectionSpace&);
Credential core(CFURLCredentialRef);
ProtectionSpace core(CFURLProtectionSpaceRef);
-class WebCoreCredentialStorage {
-public:
- static void set(CFURLProtectionSpaceRef protectionSpace, CFURLCredentialRef credential)
- {
- if (!m_storage)
- m_storage = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
- CFDictionarySetValue(m_storage, protectionSpace, credential);
- }
-
- static CFURLCredentialRef get(CFURLProtectionSpaceRef protectionSpace)
- {
- if (!m_storage)
- return 0;
- return (CFURLCredentialRef)CFDictionaryGetValue(m_storage, protectionSpace);
- }
-
-private:
- static CFMutableDictionaryRef m_storage;
-};
-
}
#endif
diff --git a/WebCore/platform/network/cf/DNSCFNet.cpp b/WebCore/platform/network/cf/DNSCFNet.cpp
index bf21ab1..381dff2 100644
--- a/WebCore/platform/network/cf/DNSCFNet.cpp
+++ b/WebCore/platform/network/cf/DNSCFNet.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008 Collin Jackson <collinj@webkit.org>
+ * 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
@@ -26,13 +27,128 @@
#include "config.h"
#include "DNS.h"
-#include "NotImplemented.h"
+#include "StringHash.h"
+#include "Timer.h"
+#include <wtf/RetainPtr.h>
+#include <wtf/StdLibExtras.h>
+
+#if PLATFORM(WIN)
+#include "ResourceHandle.h" // for loaderRunLoop()
+#endif
+
+#ifdef BUILDING_ON_TIGER
+// This function is available on Tiger, but not declared in the CFRunLoop.h header on Tiger.
+extern "C" CFRunLoopRef CFRunLoopGetMain();
+#endif
namespace WebCore {
-void prefetchDNS(const String&)
+// When resolve queue is empty, we fire async resolution requests immediately (which is important if the prefetch is triggered by hovering).
+// But during page parsing, we should coalesce identical requests to avoid stressing out CFHost.
+const int namesToResolveImmediately = 4;
+
+// Coalesce prefetch requests for this long before sending them out.
+const double coalesceDelay = 1.0;
+
+// For a page has links to many outside sites, it is likely that the system DNS resolver won't be able to cache them all anyway, and we don't want
+// to negatively affect other appications' performance, by pushing their cached entries out, too.
+// If we end up with lots of names to prefetch, some will be dropped.
+const int maxRequestsToSend = 64;
+
+class DNSResolveQueue : public TimerBase {
+public:
+ static DNSResolveQueue& shared();
+ void add(const String&);
+ void decrementRequestCount();
+
+private:
+ DNSResolveQueue();
+
+ void resolve(const String&);
+ virtual void fired();
+ HashSet<String> m_names;
+ int m_requestsInFlight;
+};
+
+DNSResolveQueue::DNSResolveQueue()
+ : m_requestsInFlight(0)
+{
+}
+
+DNSResolveQueue& DNSResolveQueue::shared()
+{
+ DEFINE_STATIC_LOCAL(DNSResolveQueue, names, ());
+ return names;
+}
+
+void DNSResolveQueue::add(const String& name)
+{
+ // If there are no names queued, and few enough are in flight, resolve immediately (the mouse may be over a link).
+ if (!m_names.size()) {
+ if (atomicIncrement(&m_requestsInFlight) <= namesToResolveImmediately) {
+ resolve(name);
+ return;
+ }
+ atomicDecrement(&m_requestsInFlight);
+ }
+ m_names.add(name);
+ if (!isActive())
+ startOneShot(coalesceDelay);
+}
+
+void DNSResolveQueue::decrementRequestCount()
+{
+ atomicDecrement(&m_requestsInFlight);
+}
+
+void DNSResolveQueue::fired()
+{
+ int requestsAllowed = maxRequestsToSend - m_requestsInFlight;
+
+ for (HashSet<String>::iterator iter = m_names.begin(); iter != m_names.end() && requestsAllowed > 0; ++iter, --requestsAllowed) {
+ atomicIncrement(&m_requestsInFlight);
+ resolve(*iter);
+ }
+
+ // It's better to skip some names than to clog the queue.
+ m_names.clear();
+}
+
+static void clientCallback(CFHostRef theHost, CFHostInfoType, const CFStreamError*, void*)
+{
+ DNSResolveQueue::shared().decrementRequestCount(); // It's ok to call shared() from a secondary thread, the static variable has already been initialized by now.
+ CFRelease(theHost);
+}
+
+void DNSResolveQueue::resolve(const String& hostname)
+{
+ ASSERT(isMainThread());
+
+ RetainPtr<CFStringRef> hostnameCF(AdoptCF, hostname.createCFString());
+ RetainPtr<CFHostRef> host(AdoptCF, CFHostCreateWithName(0, hostnameCF.get()));
+ if (!host) {
+ atomicDecrement(&m_requestsInFlight);
+ return;
+ }
+ CFHostClientContext context = { 0, 0, 0, 0, 0 };
+ Boolean result = CFHostSetClient(host.get(), clientCallback, &context);
+ ASSERT_UNUSED(result, result);
+#if !PLATFORM(WIN)
+ CFHostScheduleWithRunLoop(host.get(), CFRunLoopGetMain(), kCFRunLoopCommonModes);
+#else
+ // On Windows, we run a separate thread with CFRunLoop, which is where clientCallback will be called.
+ CFHostScheduleWithRunLoop(host.get(), ResourceHandle::loaderRunLoop(), kCFRunLoopDefaultMode);
+#endif
+ CFHostStartInfoResolution(host.get(), kCFHostAddresses, 0);
+ host.releaseRef(); // The host will be released from clientCallback().
+}
+
+void prefetchDNS(const String& hostname)
{
- notImplemented();
+ ASSERT(isMainThread());
+ if (hostname.isEmpty())
+ return;
+ DNSResolveQueue::shared().add(hostname);
}
}
diff --git a/WebCore/platform/network/cf/ResourceErrorCF.cpp b/WebCore/platform/network/cf/ResourceErrorCF.cpp
index 8e82cd5..dacc68b 100644
--- a/WebCore/platform/network/cf/ResourceErrorCF.cpp
+++ b/WebCore/platform/network/cf/ResourceErrorCF.cpp
@@ -129,7 +129,7 @@ ResourceError::operator CFErrorRef() const
if (!m_failingURL.isEmpty()) {
RetainPtr<CFStringRef> failingURLString(AdoptCF, m_failingURL.createCFString());
CFDictionarySetValue(userInfo.get(), failingURLStringKey, failingURLString.get());
- RetainPtr<CFURLRef> url(AdoptCF, KURL(m_failingURL).createCFURL());
+ RetainPtr<CFURLRef> url(AdoptCF, KURL(ParsedURLString, m_failingURL).createCFURL());
CFDictionarySetValue(userInfo.get(), failingURLKey, url.get());
}
diff --git a/WebCore/platform/network/cf/ResourceHandleCFNet.cpp b/WebCore/platform/network/cf/ResourceHandleCFNet.cpp
index e348f83..ea5fcc6 100644
--- a/WebCore/platform/network/cf/ResourceHandleCFNet.cpp
+++ b/WebCore/platform/network/cf/ResourceHandleCFNet.cpp
@@ -31,9 +31,12 @@
#include "AuthenticationCF.h"
#include "AuthenticationChallenge.h"
-#include "CookieStorageWin.h"
+#include "Base64.h"
#include "CString.h"
+#include "CookieStorageWin.h"
+#include "CredentialStorage.h"
#include "DocLoader.h"
+#include "FormDataStreamCFNet.h"
#include "Frame.h"
#include "FrameLoader.h"
#include "Logging.h"
@@ -79,6 +82,8 @@ private:
RetainPtr<CFURLRef> m_url;
RetainPtr<CFStringRef> m_user;
RetainPtr<CFStringRef> m_pass;
+ // Store the preemptively used initial credential so that if we get an authentication challenge, we won't use the same one again.
+ Credential m_initialCredential;
bool m_allowStoredCredentials;
ResourceResponse& m_response;
RetainPtr<CFMutableDataRef> m_data;
@@ -105,6 +110,16 @@ static void setDefaultMIMEType(CFURLResponseRef response)
CFURLResponseSetMIMEType(response, defaultMIMETypeString);
}
+static String encodeBasicAuthorization(const String& user, const String& password)
+{
+ CString unencodedString = (user + ":" + password).utf8();
+ Vector<char> unencoded(unencodedString.length());
+ std::copy(unencodedString.data(), unencodedString.data() + unencodedString.length(), unencoded.begin());
+ Vector<char> encoded;
+ base64Encode(unencoded, encoded);
+ return String(encoded.data(), encoded.size());
+}
+
CFURLRequestRef willSendRequest(CFURLConnectionRef conn, CFURLRequestRef cfRequest, CFURLResponseRef cfRedirectResponse, const void* clientInfo)
{
ResourceHandle* handle = static_cast<ResourceHandle*>(const_cast<void*>(clientInfo));
@@ -125,6 +140,16 @@ CFURLRequestRef willSendRequest(CFURLConnectionRef conn, CFURLRequestRef cfReque
if (CFStringCompareWithOptions(originalMethod.get(), newMethod.get(), CFRangeMake(0, CFStringGetLength(originalMethod.get())), kCFCompareCaseInsensitive)) {
RetainPtr<CFMutableURLRequestRef> mutableRequest(AdoptCF, CFURLRequestCreateMutableCopy(0, cfRequest));
CFURLRequestSetHTTPRequestMethod(mutableRequest.get(), originalMethod.get());
+
+ FormData* body = handle->request().httpBody();
+ if (!equalIgnoringCase(handle->request().httpMethod(), "GET") && body && !body->isEmpty())
+ WebCore::setHTTPBody(mutableRequest.get(), body);
+
+ String originalContentType = handle->request().httpContentType();
+ RetainPtr<CFStringRef> originalContentTypeCF(AdoptCF, originalContentType.createCFString());
+ if (!originalContentType.isEmpty())
+ CFURLRequestSetHTTPHeaderFieldValue(mutableRequest.get(), CFSTR("Content-Type"), originalContentTypeCF.get());
+
request = mutableRequest.get();
}
}
@@ -374,6 +399,16 @@ bool ResourceHandle::start(Frame* frame)
d->m_request.setURL(urlWithCredentials);
}
+ // <rdar://problem/7174050> - For URLs that match the paths of those previously challenged for HTTP Basic authentication,
+ // try and reuse the credential preemptively, as allowed by RFC 2617.
+ if (!client() || client()->shouldUseCredentialStorage(this) && d->m_request.url().protocolInHTTPFamily())
+ d->m_initialCredential = CredentialStorage::getDefaultAuthenticationCredential(d->m_request.url());
+
+ if (!d->m_initialCredential.isEmpty()) {
+ String authHeader = "Basic " + encodeBasicAuthorization(d->m_initialCredential.user(), d->m_initialCredential.password());
+ d->m_request.addHTTPHeaderField("Authorization", authHeader);
+ }
+
RetainPtr<CFURLRequestRef> request(AdoptCF, makeFinalRequest(d->m_request, d->m_shouldContentSniff));
CFURLConnectionClient_V3 client = { 3, this, 0, 0, 0, WebCore::willSendRequest, didReceiveResponse, didReceiveData, NULL, didFinishLoading, didFail, willCacheResponse, didReceiveChallenge, didSendBodyData, shouldUseCredentialStorageCallback, 0};
@@ -441,7 +476,12 @@ void ResourceHandle::didReceiveAuthenticationChallenge(const AuthenticationChall
RetainPtr<CFStringRef> pass(AdoptCF, d->m_pass.createCFString());
RetainPtr<CFURLCredentialRef> credential(AdoptCF,
CFURLCredentialCreate(kCFAllocatorDefault, user.get(), pass.get(), 0, kCFURLCredentialPersistenceNone));
- WebCoreCredentialStorage::set(CFURLAuthChallengeGetProtectionSpace(challenge.cfURLAuthChallengeRef()), credential.get());
+
+ KURL urlToStore;
+ if (challenge.failureResponse().httpStatusCode() == 401)
+ urlToStore = d->m_request.url();
+ CredentialStorage::set(core(credential.get()), challenge.protectionSpace(), urlToStore);
+
CFURLConnectionUseCredential(d->m_connection.get(), credential.get(), challenge.cfURLAuthChallengeRef());
d->m_user = String();
d->m_pass = String();
@@ -450,10 +490,11 @@ void ResourceHandle::didReceiveAuthenticationChallenge(const AuthenticationChall
}
if (!challenge.previousFailureCount() && (!client() || client()->shouldUseCredentialStorage(this))) {
- CFURLCredentialRef credential = WebCoreCredentialStorage::get(CFURLAuthChallengeGetProtectionSpace(challenge.cfURLAuthChallengeRef()));
- if (credential) {
- ASSERT(CFURLCredentialGetPersistence(credential) == kCFURLCredentialPersistenceNone);
- CFURLConnectionUseCredential(d->m_connection.get(), credential, challenge.cfURLAuthChallengeRef());
+ Credential credential = CredentialStorage::get(challenge.protectionSpace());
+ if (!credential.isEmpty() && credential != d->m_initialCredential) {
+ ASSERT(credential.persistence() == CredentialPersistenceNone);
+ RetainPtr<CFURLCredentialRef> cfCredential(AdoptCF, createCF(credential));
+ CFURLConnectionUseCredential(d->m_connection.get(), cfCredential.get(), challenge.cfURLAuthChallengeRef());
return;
}
}
@@ -478,7 +519,12 @@ void ResourceHandle::receivedCredential(const AuthenticationChallenge& challenge
// to ignore it for a particular request (short of removing it altogether).
Credential webCredential(credential.user(), credential.password(), CredentialPersistenceNone);
RetainPtr<CFURLCredentialRef> cfCredential(AdoptCF, createCF(webCredential));
- WebCoreCredentialStorage::set(CFURLAuthChallengeGetProtectionSpace(challenge.cfURLAuthChallengeRef()), cfCredential.get());
+
+ KURL urlToStore;
+ if (challenge.failureResponse().httpStatusCode() == 401)
+ urlToStore = d->m_request.url();
+ CredentialStorage::set(webCredential, challenge.protectionSpace(), urlToStore);
+
CFURLConnectionUseCredential(d->m_connection.get(), cfCredential.get(), challenge.cfURLAuthChallengeRef());
} else {
RetainPtr<CFURLCredentialRef> cfCredential(AdoptCF, createCF(credential));
@@ -659,19 +705,28 @@ void WebCoreSynchronousLoader::didReceiveChallenge(CFURLConnectionRef conn, CFUR
WebCoreSynchronousLoader* loader = static_cast<WebCoreSynchronousLoader*>(const_cast<void*>(clientInfo));
if (loader->m_user && loader->m_pass) {
- RetainPtr<CFURLCredentialRef> credential(AdoptCF,
- CFURLCredentialCreate(kCFAllocatorDefault, loader->m_user.get(), loader->m_pass.get(), 0, kCFURLCredentialPersistenceNone));
- WebCoreCredentialStorage::set(CFURLAuthChallengeGetProtectionSpace(challenge), credential.get());
- CFURLConnectionUseCredential(conn, credential.get(), challenge);
+ Credential credential(loader->m_user.get(), loader->m_pass.get(), CredentialPersistenceNone);
+ RetainPtr<CFURLCredentialRef> cfCredential(AdoptCF, createCF(credential));
+
+ CFURLResponseRef urlResponse = (CFURLResponseRef)CFURLAuthChallengeGetFailureResponse(challenge);
+ CFHTTPMessageRef httpResponse = urlResponse ? CFURLResponseGetHTTPResponse(urlResponse) : 0;
+ KURL urlToStore;
+ if (httpResponse && CFHTTPMessageGetResponseStatusCode(httpResponse) == 401)
+ urlToStore = loader->m_url.get();
+
+ CredentialStorage::set(credential, core(CFURLAuthChallengeGetProtectionSpace(challenge)), urlToStore);
+
+ CFURLConnectionUseCredential(conn, cfCredential.get(), challenge);
loader->m_user = 0;
loader->m_pass = 0;
return;
}
if (!CFURLAuthChallengeGetPreviousFailureCount(challenge) && loader->m_allowStoredCredentials) {
- CFURLCredentialRef credential = WebCoreCredentialStorage::get(CFURLAuthChallengeGetProtectionSpace(challenge));
- if (credential) {
- ASSERT(CFURLCredentialGetPersistence(credential) == kCFURLCredentialPersistenceNone);
- CFURLConnectionUseCredential(conn, credential, challenge);
+ Credential credential = CredentialStorage::get(core(CFURLAuthChallengeGetProtectionSpace(challenge)));
+ if (!credential.isEmpty() && credential != loader->m_initialCredential) {
+ ASSERT(credential.persistence() == CredentialPersistenceNone);
+ RetainPtr<CFURLCredentialRef> cfCredential(AdoptCF, createCF(credential));
+ CFURLConnectionUseCredential(conn, cfCredential.get(), challenge);
return;
}
}
@@ -696,8 +751,10 @@ RetainPtr<CFDataRef> WebCoreSynchronousLoader::load(const ResourceRequest& reque
KURL url = request.url();
- loader.m_user.adoptCF(url.user().createCFString());
- loader.m_pass.adoptCF(url.pass().createCFString());
+ if (url.user().length())
+ loader.m_user.adoptCF(url.user().createCFString());
+ if (url.pass().length())
+ loader.m_pass.adoptCF(url.pass().createCFString());
loader.m_allowStoredCredentials = (storedCredentials == AllowStoredCredentials);
// Take user/pass out of the URL.
@@ -707,8 +764,20 @@ RetainPtr<CFDataRef> WebCoreSynchronousLoader::load(const ResourceRequest& reque
ResourceRequest requestWithoutCredentials(request);
requestWithoutCredentials.removeCredentials();
cfRequest.adoptCF(makeFinalRequest(requestWithoutCredentials, ResourceHandle::shouldContentSniffURL(requestWithoutCredentials.url())));
- } else
- cfRequest.adoptCF(makeFinalRequest(request, ResourceHandle::shouldContentSniffURL(request.url())));
+ } else {
+ // <rdar://problem/7174050> - For URLs that match the paths of those previously challenged for HTTP Basic authentication,
+ // try and reuse the credential preemptively, as allowed by RFC 2617.
+ ResourceRequest requestWithInitialCredential(request);
+ if (loader.m_allowStoredCredentials && url.protocolInHTTPFamily())
+ loader.m_initialCredential = CredentialStorage::getDefaultAuthenticationCredential(url);
+
+ if (!loader.m_initialCredential.isEmpty()) {
+ String authHeader = "Basic " + encodeBasicAuthorization(loader.m_initialCredential.user(), loader.m_initialCredential.password());
+ requestWithInitialCredential.addHTTPHeaderField("Authorization", authHeader);
+ }
+
+ cfRequest.adoptCF(makeFinalRequest(requestWithInitialCredential, ResourceHandle::shouldContentSniffURL(requestWithInitialCredential.url())));
+ }
CFURLConnectionClient_V3 client = { 3, &loader, 0, 0, 0, willSendRequest, didReceiveResponse, didReceiveData, 0, didFinishLoading, didFail, 0, didReceiveChallenge, 0, shouldUseCredentialStorage, 0 };
RetainPtr<CFURLConnectionRef> connection(AdoptCF, CFURLConnectionCreate(kCFAllocatorDefault, cfRequest.get(), reinterpret_cast<CFURLConnectionClient*>(&client)));
diff --git a/WebCore/platform/network/cf/ResourceRequest.h b/WebCore/platform/network/cf/ResourceRequest.h
index a4e9749..8ead412 100644
--- a/WebCore/platform/network/cf/ResourceRequest.h
+++ b/WebCore/platform/network/cf/ResourceRequest.h
@@ -37,7 +37,7 @@ namespace WebCore {
struct ResourceRequest : ResourceRequestBase {
ResourceRequest(const String& url)
- : ResourceRequestBase(KURL(url), UseProtocolCachePolicy)
+ : ResourceRequestBase(KURL(ParsedURLString, url), UseProtocolCachePolicy)
{
}
diff --git a/WebCore/platform/network/cf/ResourceRequestCFNet.cpp b/WebCore/platform/network/cf/ResourceRequestCFNet.cpp
index 7355401..bba3d3e 100644
--- a/WebCore/platform/network/cf/ResourceRequestCFNet.cpp
+++ b/WebCore/platform/network/cf/ResourceRequestCFNet.cpp
@@ -112,7 +112,7 @@ void ResourceRequest::doUpdatePlatformRequest()
addHeadersFromHashMap(cfRequest, httpHeaderFields());
WebCore::setHTTPBody(cfRequest, httpBody());
- CFURLRequestSetShouldHandleHTTPCookies(cfRequest, allowHTTPCookies());
+ CFURLRequestSetShouldHandleHTTPCookies(cfRequest, allowCookies());
unsigned fallbackCount = m_responseContentDispositionEncodingFallbackArray.size();
RetainPtr<CFMutableArrayRef> encodingFallbacks(AdoptCF, CFArrayCreateMutable(kCFAllocatorDefault, fallbackCount, 0));
@@ -146,7 +146,7 @@ void ResourceRequest::doUpdateResourceRequest()
m_httpMethod = method;
CFRelease(method);
}
- m_allowHTTPCookies = CFURLRequestShouldHandleHTTPCookies(m_cfRequest.get());
+ m_allowCookies = CFURLRequestShouldHandleHTTPCookies(m_cfRequest.get());
if (CFDictionaryRef headers = CFURLRequestCopyAllHTTPHeaderFields(m_cfRequest.get())) {
CFIndex headerCount = CFDictionaryGetCount(headers);
diff --git a/WebCore/platform/network/cf/SocketStreamError.h b/WebCore/platform/network/cf/SocketStreamError.h
new file mode 100644
index 0000000..f9641ad
--- /dev/null
+++ b/WebCore/platform/network/cf/SocketStreamError.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SocketStreamError_h
+#define SocketStreamError_h
+
+#include "SocketStreamErrorBase.h"
+
+namespace WebCore {
+
+ class SocketStreamError : public SocketStreamErrorBase {
+ public:
+ SocketStreamError() { }
+ explicit SocketStreamError(int errorCode)
+ : SocketStreamErrorBase(errorCode)
+ {
+ }
+
+ };
+
+} // namespace WebCore
+
+#endif // SocketStreamError_h
diff --git a/WebCore/platform/network/cf/SocketStreamHandle.h b/WebCore/platform/network/cf/SocketStreamHandle.h
new file mode 100644
index 0000000..64139e5
--- /dev/null
+++ b/WebCore/platform/network/cf/SocketStreamHandle.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SocketStreamHandle_h
+#define SocketStreamHandle_h
+
+#include "SocketStreamHandleBase.h"
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+ class AuthenticationChallenge;
+ class Credential;
+ class SocketStreamHandleClient;
+
+ class SocketStreamHandle : public RefCounted<SocketStreamHandle>, public SocketStreamHandleBase {
+ public:
+ static PassRefPtr<SocketStreamHandle> create(const KURL& url, SocketStreamHandleClient* client) { return adoptRef(new SocketStreamHandle(url, client)); }
+
+ virtual ~SocketStreamHandle();
+
+ protected:
+ virtual int platformSend(const char* data, int length);
+ virtual void platformClose();
+
+ private:
+ SocketStreamHandle(const KURL&, SocketStreamHandleClient*);
+
+ // No authentication for streams per se, but proxy may ask for credentials.
+ void didReceiveAuthenticationChallenge(const AuthenticationChallenge&);
+ void receivedCredential(const AuthenticationChallenge&, const Credential&);
+ void receivedRequestToContinueWithoutCredential(const AuthenticationChallenge&);
+ void receivedCancellation(const AuthenticationChallenge&);
+ };
+
+} // namespace WebCore
+
+#endif // SocketStreamHandle_h
diff --git a/WebCore/platform/network/cf/SocketStreamHandleCFNet.cpp b/WebCore/platform/network/cf/SocketStreamHandleCFNet.cpp
new file mode 100644
index 0000000..6aa33fc
--- /dev/null
+++ b/WebCore/platform/network/cf/SocketStreamHandleCFNet.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "SocketStreamHandle.h"
+
+#include "KURL.h"
+#include "Logging.h"
+#include "NotImplemented.h"
+#include "SocketStreamHandleClient.h"
+
+namespace WebCore {
+
+SocketStreamHandle::SocketStreamHandle(const KURL& url, SocketStreamHandleClient* client)
+ : SocketStreamHandleBase(url, client)
+{
+ LOG(Network, "SocketStreamHandle %p new client %p", this, m_client);
+ notImplemented();
+}
+
+SocketStreamHandle::~SocketStreamHandle()
+{
+ LOG(Network, "SocketStreamHandle %p delete", this);
+ setClient(0);
+ notImplemented();
+}
+
+int SocketStreamHandle::platformSend(const char*, int)
+{
+ LOG(Network, "SocketStreamHandle %p platformSend", this);
+ notImplemented();
+ return 0;
+}
+
+void SocketStreamHandle::platformClose()
+{
+ LOG(Network, "SocketStreamHandle %p platformClose", this);
+ notImplemented();
+}
+
+void SocketStreamHandle::didReceiveAuthenticationChallenge(const AuthenticationChallenge&)
+{
+ notImplemented();
+}
+
+void SocketStreamHandle::receivedCredential(const AuthenticationChallenge&, const Credential&)
+{
+ notImplemented();
+}
+
+void SocketStreamHandle::receivedRequestToContinueWithoutCredential(const AuthenticationChallenge&)
+{
+ notImplemented();
+}
+
+void SocketStreamHandle::receivedCancellation(const AuthenticationChallenge&)
+{
+ notImplemented();
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/network/chromium/CookieJarChromium.cpp b/WebCore/platform/network/chromium/CookieJarChromium.cpp
index 65be451..7862cc3 100644
--- a/WebCore/platform/network/chromium/CookieJarChromium.cpp
+++ b/WebCore/platform/network/chromium/CookieJarChromium.cpp
@@ -31,6 +31,7 @@
#include "config.h"
#include "CookieJar.h"
+#include "Cookie.h"
#include "ChromiumBridge.h"
#include "Document.h"
@@ -52,4 +53,16 @@ bool cookiesEnabled(const Document*)
return true;
}
+bool getRawCookies(const Document*, const KURL&, Vector<Cookie>& rawCookies)
+{
+ // FIXME: Not yet implemented
+ rawCookies.clear();
+ return false; // return true when implemented
+}
+
+void deleteCookie(const Document*, const KURL&, const String&)
+{
+ // FIXME: Not yet implemented
+}
+
} // namespace WebCore
diff --git a/WebCore/platform/network/chromium/ResourceRequest.h b/WebCore/platform/network/chromium/ResourceRequest.h
index aa76de4..48ff1e7 100644
--- a/WebCore/platform/network/chromium/ResourceRequest.h
+++ b/WebCore/platform/network/chromium/ResourceRequest.h
@@ -46,10 +46,10 @@ namespace WebCore {
};
ResourceRequest(const String& url)
- : ResourceRequestBase(KURL(url), UseProtocolCachePolicy)
+ : ResourceRequestBase(KURL(ParsedURLString, url), UseProtocolCachePolicy)
, m_requestorID(0)
, m_requestorProcessID(0)
- , m_appCacheContextID(0)
+ , m_appCacheHostID(0)
, m_targetType(TargetIsSubResource)
{
}
@@ -58,7 +58,7 @@ namespace WebCore {
: ResourceRequestBase(url, UseProtocolCachePolicy)
, m_requestorID(0)
, m_requestorProcessID(0)
- , m_appCacheContextID(0)
+ , m_appCacheHostID(0)
, m_targetType(TargetIsSubResource)
, m_securityInfo(securityInfo)
{
@@ -68,7 +68,7 @@ namespace WebCore {
: ResourceRequestBase(url, UseProtocolCachePolicy)
, m_requestorID(0)
, m_requestorProcessID(0)
- , m_appCacheContextID(0)
+ , m_appCacheHostID(0)
, m_targetType(TargetIsSubResource)
{
}
@@ -77,7 +77,7 @@ namespace WebCore {
: ResourceRequestBase(url, policy)
, m_requestorID(0)
, m_requestorProcessID(0)
- , m_appCacheContextID(0)
+ , m_appCacheHostID(0)
, m_targetType(TargetIsSubResource)
{
setHTTPReferrer(referrer);
@@ -87,7 +87,7 @@ namespace WebCore {
: ResourceRequestBase(KURL(), UseProtocolCachePolicy)
, m_requestorID(0)
, m_requestorProcessID(0)
- , m_appCacheContextID(0)
+ , m_appCacheHostID(0)
, m_targetType(TargetIsSubResource)
{
}
@@ -107,9 +107,9 @@ namespace WebCore {
int requestorProcessID() const { return m_requestorProcessID; }
void setRequestorProcessID(int requestorProcessID) { m_requestorProcessID = requestorProcessID; }
- // Allows the request to be matched up with its app cache context.
- int appCacheContextID() const { return m_appCacheContextID; }
- void setAppCacheContextID(int id) { m_appCacheContextID = id; }
+ // Allows the request to be matched up with its app cache host.
+ int appCacheHostID() const { return m_appCacheHostID; }
+ void setAppCacheHostID(int id) { m_appCacheHostID = id; }
// Opaque buffer that describes the security state (including SSL
// connection state) for the resource that should be reported when the
@@ -128,7 +128,7 @@ namespace WebCore {
int m_requestorID;
int m_requestorProcessID;
- int m_appCacheContextID;
+ int m_appCacheHostID;
TargetType m_targetType;
CString m_securityInfo;
};
diff --git a/WebCore/platform/network/chromium/ResourceResponse.h b/WebCore/platform/network/chromium/ResourceResponse.h
index 6c928c0..0c2b5d9 100644
--- a/WebCore/platform/network/chromium/ResourceResponse.h
+++ b/WebCore/platform/network/chromium/ResourceResponse.h
@@ -60,12 +60,18 @@ namespace WebCore {
m_isContentFiltered = isContentFiltered;
}
- long long getAppCacheID() const { return m_appCacheID; }
+ long long appCacheID() const { return m_appCacheID; }
void setAppCacheID(long long id)
{
m_appCacheID = id;
}
+ const KURL& appCacheManifestURL() const { return m_appCacheManifestURL; }
+ void setAppCacheManifestURL(const KURL& url)
+ {
+ m_appCacheManifestURL = url;
+ }
+
private:
friend class ResourceResponseBase;
@@ -86,6 +92,10 @@ namespace WebCore {
// The id of the appcache this response was retrieved from, or zero if
// the response was not retrieved from an appcache.
long long m_appCacheID;
+
+ // The manifest url of the appcache this response was retrieved from, if any.
+ // Note: only valid for main resource responses.
+ KURL m_appCacheManifestURL;
};
} // namespace WebCore
diff --git a/WebCore/platform/sql/chromium/SQLiteFileSystemChromiumLinux.cpp b/WebCore/platform/network/chromium/SocketStreamError.h
index 3582448..540496b 100644
--- a/WebCore/platform/sql/chromium/SQLiteFileSystemChromiumLinux.cpp
+++ b/WebCore/platform/network/chromium/SocketStreamError.h
@@ -28,15 +28,20 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "config.h"
-#include "SQLiteFileSystem.h"
+#ifndef SocketStreamError_h
+#define SocketStreamError_h
+
+#include "SocketStreamErrorBase.h"
namespace WebCore {
-void SQLiteFileSystem::registerSQLiteVFS()
-{
- // stub for registering Chromium's SQLite VFS for Linux
- ASSERT_NOT_REACHED();
-}
+class SocketStreamError : public SocketStreamErrorBase {
+public:
+ SocketStreamError() { }
+ explicit SocketStreamError(int errorCode)
+ : SocketStreamErrorBase(errorCode) { }
+};
+
+} // namespace WebCore
-} // namespace WebCore
+#endif // SocketStreamError_h
diff --git a/WebCore/platform/network/chromium/SocketStreamHandle.h b/WebCore/platform/network/chromium/SocketStreamHandle.h
new file mode 100644
index 0000000..5a905cb
--- /dev/null
+++ b/WebCore/platform/network/chromium/SocketStreamHandle.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SocketStreamHandle_h
+#define SocketStreamHandle_h
+
+#include "SocketStreamHandleBase.h"
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+ class AuthenticationChallenge;
+ class Credential;
+ class SocketStreamHandleClient;
+ class SocketStreamHandleInternal;
+
+ class SocketStreamHandle : public RefCounted<SocketStreamHandle>, public SocketStreamHandleBase {
+ public:
+ static PassRefPtr<SocketStreamHandle> create(const KURL& url, SocketStreamHandleClient* client) { return adoptRef(new SocketStreamHandle(url, client)); }
+
+ virtual ~SocketStreamHandle();
+
+ protected:
+ virtual int platformSend(const char* data, int length);
+ virtual void platformClose();
+
+ private:
+ SocketStreamHandle(const KURL&, SocketStreamHandleClient*);
+
+ // No authentication for streams per se, but proxy may ask for credentials.
+ void didReceiveAuthenticationChallenge(const AuthenticationChallenge&);
+ void receivedCredential(const AuthenticationChallenge&, const Credential&);
+ void receivedRequestToContinueWithoutCredential(const AuthenticationChallenge&);
+ void receivedCancellation(const AuthenticationChallenge&);
+
+ friend class SocketStreamHandleInternal;
+ OwnPtr<SocketStreamHandleInternal> m_internal;
+ };
+
+} // namespace WebCore
+
+#endif // SocketStreamHandle_h
diff --git a/WebCore/platform/network/curl/CookieJarCurl.cpp b/WebCore/platform/network/curl/CookieJarCurl.cpp
index 5ac0f9c..3bad4e4 100644
--- a/WebCore/platform/network/curl/CookieJarCurl.cpp
+++ b/WebCore/platform/network/curl/CookieJarCurl.cpp
@@ -17,6 +17,7 @@
#include "config.h"
#include "CookieJar.h"
+#include "Cookie.h"
#include "Document.h"
#include "KURL.h"
#include "PlatformString.h"
@@ -43,4 +44,16 @@ bool cookiesEnabled(const Document* /*document*/)
return true;
}
+bool getRawCookies(const Document*, const KURL&, Vector<Cookie>& rawCookies)
+{
+ // FIXME: Not yet implemented
+ rawCookies.clear();
+ return false; // return true when implemented
+}
+
+void deleteCookie(const Document*, const KURL&, const String&)
+{
+ // FIXME: Not yet implemented
+}
+
}
diff --git a/WebCore/platform/network/curl/ResourceHandleCurl.cpp b/WebCore/platform/network/curl/ResourceHandleCurl.cpp
index a6f5dca..5469ec9 100644
--- a/WebCore/platform/network/curl/ResourceHandleCurl.cpp
+++ b/WebCore/platform/network/curl/ResourceHandleCurl.cpp
@@ -103,7 +103,13 @@ ResourceHandle::~ResourceHandle()
bool ResourceHandle::start(Frame* frame)
{
- ASSERT(frame);
+ // The frame could be null if the ResourceHandle is not associated to any
+ // Frame, e.g. if we are downloading a file.
+ // If the frame is not null but the page is null this must be an attempted
+ // load from an onUnload handler, so let's just block it.
+ if (frame && !frame->page())
+ return false;
+
ResourceHandleManager::sharedInstance()->add(this);
return true;
}
diff --git a/WebCore/platform/network/curl/ResourceHandleManager.cpp b/WebCore/platform/network/curl/ResourceHandleManager.cpp
index 2aa286a..14c6f31 100644
--- a/WebCore/platform/network/curl/ResourceHandleManager.cpp
+++ b/WebCore/platform/network/curl/ResourceHandleManager.cpp
@@ -5,6 +5,8 @@
* Copyright (C) 2007 Holger Hans Peter Freyther
* Copyright (C) 2008 Collabora Ltd.
* Copyright (C) 2008 Nuanti Ltd.
+ * Copyright (C) 2009 Appcelerator Inc.
+ * Copyright (C) 2009 Brent Fulgham <bfulgham@webkit.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -44,6 +46,7 @@
#include <errno.h>
#include <stdio.h>
+#include <wtf/Threading.h>
#include <wtf/Vector.h>
namespace WebCore {
@@ -54,16 +57,72 @@ const int maxRunningJobs = 5;
static const bool ignoreSSLErrors = getenv("WEBKIT_IGNORE_SSL_ERRORS");
+static CString certificatePath()
+{
+#if PLATFORM(CF)
+ CFBundleRef webKitBundle = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.WebKit"));
+ if (webKitBundle) {
+ RetainPtr<CFURLRef> certURLRef(AdoptCF, CFBundleCopyResourceURL(webKitBundle, CFSTR("cacert"), CFSTR("pem"), CFSTR("certificates")));
+ if (certURLRef) {
+ char path[MAX_PATH];
+ CFURLGetFileSystemRepresentation(certURLRef.get(), false, reinterpret_cast<UInt8*>(path), MAX_PATH);
+ return path;
+ }
+ }
+#endif
+ char* envPath = getenv("CURL_CA_BUNDLE_PATH");
+ if (envPath)
+ return envPath;
+
+ return CString();
+}
+
+static Mutex* sharedResourceMutex(curl_lock_data data) {
+ DEFINE_STATIC_LOCAL(Mutex, cookieMutex, ());
+ DEFINE_STATIC_LOCAL(Mutex, dnsMutex, ());
+ DEFINE_STATIC_LOCAL(Mutex, shareMutex, ());
+
+ switch (data) {
+ case CURL_LOCK_DATA_COOKIE:
+ return &cookieMutex;
+ case CURL_LOCK_DATA_DNS:
+ return &dnsMutex;
+ case CURL_LOCK_DATA_SHARE:
+ return &shareMutex;
+ default:
+ ASSERT_NOT_REACHED();
+ return NULL;
+ }
+}
+
+// libcurl does not implement its own thread synchronization primitives.
+// these two functions provide mutexes for cookies, and for the global DNS
+// cache.
+static void curl_lock_callback(CURL* handle, curl_lock_data data, curl_lock_access access, void* userPtr)
+{
+ if (Mutex* mutex = sharedResourceMutex(data))
+ mutex->lock();
+}
+
+static void curl_unlock_callback(CURL* handle, curl_lock_data data, void* userPtr)
+{
+ if (Mutex* mutex = sharedResourceMutex(data))
+ mutex->unlock();
+}
+
ResourceHandleManager::ResourceHandleManager()
: m_downloadTimer(this, &ResourceHandleManager::downloadTimerCallback)
, m_cookieJarFileName(0)
, m_runningJobs(0)
+ , m_certificatePath (certificatePath())
{
curl_global_init(CURL_GLOBAL_ALL);
m_curlMultiHandle = curl_multi_init();
m_curlShareHandle = curl_share_init();
curl_share_setopt(m_curlShareHandle, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE);
curl_share_setopt(m_curlShareHandle, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
+ curl_share_setopt(m_curlShareHandle, CURLSHOPT_LOCKFUNC, curl_lock_callback);
+ curl_share_setopt(m_curlShareHandle, CURLSHOPT_UNLOCKFUNC, curl_unlock_callback);
}
ResourceHandleManager::~ResourceHandleManager()
@@ -88,6 +147,23 @@ ResourceHandleManager* ResourceHandleManager::sharedInstance()
return sharedInstance;
}
+static void handleLocalReceiveResponse (CURL* handle, ResourceHandle* job, ResourceHandleInternal* d)
+{
+ // since the code in headerCallback will not have run for local files
+ // the code to set the URL and fire didReceiveResponse is never run,
+ // which means the ResourceLoader's response does not contain the URL.
+ // Run the code here for local files to resolve the issue.
+ // TODO: See if there is a better approach for handling this.
+ const char* hdr;
+ CURLcode err = curl_easy_getinfo(handle, CURLINFO_EFFECTIVE_URL, &hdr);
+ ASSERT(CURLE_OK == err);
+ d->m_response.setURL(KURL(ParsedURLString, hdr));
+ if (d->client())
+ d->client()->didReceiveResponse(job, d->m_response);
+ d->m_response.setResponseFired(true);
+}
+
+
// called with data after all headers have been processed via headerCallback
static size_t writeCallback(void* ptr, size_t size, size_t nmemb, void* data)
{
@@ -112,18 +188,10 @@ static size_t writeCallback(void* ptr, size_t size, size_t nmemb, void* data)
if (CURLE_OK == err && httpCode >= 300 && httpCode < 400)
return totalSize;
- // since the code in headerCallback will not have run for local files
- // the code to set the URL and fire didReceiveResponse is never run,
- // which means the ResourceLoader's response does not contain the URL.
- // Run the code here for local files to resolve the issue.
- // TODO: See if there is a better approach for handling this.
if (!d->m_response.responseFired()) {
- const char* hdr;
- err = curl_easy_getinfo(h, CURLINFO_EFFECTIVE_URL, &hdr);
- d->m_response.setURL(KURL(hdr));
- if (d->client())
- d->client()->didReceiveResponse(job, d->m_response);
- d->m_response.setResponseFired(true);
+ handleLocalReceiveResponse(h, job, d);
+ if (d->m_cancelled)
+ return 0;
}
if (d->client())
@@ -174,7 +242,7 @@ static size_t headerCallback(char* ptr, size_t size, size_t nmemb, void* data)
const char* hdr;
err = curl_easy_getinfo(h, CURLINFO_EFFECTIVE_URL, &hdr);
- d->m_response.setURL(KURL(hdr));
+ d->m_response.setURL(KURL(ParsedURLString, hdr));
long httpCode = 0;
err = curl_easy_getinfo(h, CURLINFO_RESPONSE_CODE, &httpCode);
@@ -222,6 +290,7 @@ size_t readCallback(void* ptr, size_t size, size_t nmemb, void* data)
{
ResourceHandle* job = static_cast<ResourceHandle*>(data);
ResourceHandleInternal* d = job->getInternal();
+
if (d->m_cancelled)
return 0;
@@ -311,6 +380,14 @@ void ResourceHandleManager::downloadTimerCallback(Timer<ResourceHandleManager>*
continue;
if (CURLE_OK == msg->data.result) {
+ if (!d->m_response.responseFired()) {
+ handleLocalReceiveResponse(d->m_handle, job, d);
+ if (d->m_cancelled) {
+ removeFromCurl(job);
+ continue;
+ }
+ }
+
if (d->client())
d->client()->didFinishLoading(job);
} else {
@@ -629,6 +706,10 @@ void ResourceHandleManager::initializeHandle(ResourceHandle* job)
// and/or reporting SSL errors to the user.
if (ignoreSSLErrors)
curl_easy_setopt(d->m_handle, CURLOPT_SSL_VERIFYPEER, false);
+
+ if (!m_certificatePath.isNull())
+ curl_easy_setopt(d->m_handle, CURLOPT_CAINFO, m_certificatePath.data());
+
// enable gzip and deflate through Accept-Encoding:
curl_easy_setopt(d->m_handle, CURLOPT_ENCODING, "");
diff --git a/WebCore/platform/network/curl/ResourceHandleManager.h b/WebCore/platform/network/curl/ResourceHandleManager.h
index d38e577..89b27d7 100644
--- a/WebCore/platform/network/curl/ResourceHandleManager.h
+++ b/WebCore/platform/network/curl/ResourceHandleManager.h
@@ -29,6 +29,7 @@
#define ResourceHandleManager_h
#include "Frame.h"
+#include "CString.h"
#include "Timer.h"
#include "ResourceHandleClient.h"
@@ -71,6 +72,7 @@ private:
char* m_cookieJarFileName;
char m_curlErrorBuffer[CURL_ERROR_SIZE];
Vector<ResourceHandle*> m_resourceHandleList;
+ const CString m_certificatePath;
int m_runningJobs;
};
diff --git a/WebCore/platform/network/curl/ResourceRequest.h b/WebCore/platform/network/curl/ResourceRequest.h
index b3032aa..3fa2795 100644
--- a/WebCore/platform/network/curl/ResourceRequest.h
+++ b/WebCore/platform/network/curl/ResourceRequest.h
@@ -36,7 +36,7 @@ namespace WebCore {
struct ResourceRequest : ResourceRequestBase {
ResourceRequest(const String& url)
- : ResourceRequestBase(KURL(url), UseProtocolCachePolicy)
+ : ResourceRequestBase(KURL(ParsedURLString, url), UseProtocolCachePolicy)
{
}
diff --git a/WebCore/platform/network/curl/SocketStreamError.h b/WebCore/platform/network/curl/SocketStreamError.h
new file mode 100644
index 0000000..f9641ad
--- /dev/null
+++ b/WebCore/platform/network/curl/SocketStreamError.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SocketStreamError_h
+#define SocketStreamError_h
+
+#include "SocketStreamErrorBase.h"
+
+namespace WebCore {
+
+ class SocketStreamError : public SocketStreamErrorBase {
+ public:
+ SocketStreamError() { }
+ explicit SocketStreamError(int errorCode)
+ : SocketStreamErrorBase(errorCode)
+ {
+ }
+
+ };
+
+} // namespace WebCore
+
+#endif // SocketStreamError_h
diff --git a/WebCore/platform/network/curl/SocketStreamHandle.h b/WebCore/platform/network/curl/SocketStreamHandle.h
new file mode 100644
index 0000000..64139e5
--- /dev/null
+++ b/WebCore/platform/network/curl/SocketStreamHandle.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SocketStreamHandle_h
+#define SocketStreamHandle_h
+
+#include "SocketStreamHandleBase.h"
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+ class AuthenticationChallenge;
+ class Credential;
+ class SocketStreamHandleClient;
+
+ class SocketStreamHandle : public RefCounted<SocketStreamHandle>, public SocketStreamHandleBase {
+ public:
+ static PassRefPtr<SocketStreamHandle> create(const KURL& url, SocketStreamHandleClient* client) { return adoptRef(new SocketStreamHandle(url, client)); }
+
+ virtual ~SocketStreamHandle();
+
+ protected:
+ virtual int platformSend(const char* data, int length);
+ virtual void platformClose();
+
+ private:
+ SocketStreamHandle(const KURL&, SocketStreamHandleClient*);
+
+ // No authentication for streams per se, but proxy may ask for credentials.
+ void didReceiveAuthenticationChallenge(const AuthenticationChallenge&);
+ void receivedCredential(const AuthenticationChallenge&, const Credential&);
+ void receivedRequestToContinueWithoutCredential(const AuthenticationChallenge&);
+ void receivedCancellation(const AuthenticationChallenge&);
+ };
+
+} // namespace WebCore
+
+#endif // SocketStreamHandle_h
diff --git a/WebCore/platform/network/curl/SocketStreamHandleCurl.cpp b/WebCore/platform/network/curl/SocketStreamHandleCurl.cpp
new file mode 100644
index 0000000..891e96e
--- /dev/null
+++ b/WebCore/platform/network/curl/SocketStreamHandleCurl.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2009 Brent Fulgham. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "SocketStreamHandle.h"
+
+#include "KURL.h"
+#include "Logging.h"
+#include "NotImplemented.h"
+#include "SocketStreamHandleClient.h"
+
+namespace WebCore {
+
+SocketStreamHandle::SocketStreamHandle(const KURL& url, SocketStreamHandleClient* client)
+ : SocketStreamHandleBase(url, client)
+{
+ LOG(Network, "SocketStreamHandle %p new client %p", this, m_client);
+ notImplemented();
+}
+
+SocketStreamHandle::~SocketStreamHandle()
+{
+ LOG(Network, "SocketStreamHandle %p delete", this);
+ setClient(0);
+ notImplemented();
+}
+
+int SocketStreamHandle::platformSend(const char*, int)
+{
+ LOG(Network, "SocketStreamHandle %p platformSend", this);
+ notImplemented();
+ return 0;
+}
+
+void SocketStreamHandle::platformClose()
+{
+ LOG(Network, "SocketStreamHandle %p platformClose", this);
+ notImplemented();
+}
+
+void SocketStreamHandle::didReceiveAuthenticationChallenge(const AuthenticationChallenge&)
+{
+ notImplemented();
+}
+
+void SocketStreamHandle::receivedCredential(const AuthenticationChallenge&, const Credential&)
+{
+ notImplemented();
+}
+
+void SocketStreamHandle::receivedRequestToContinueWithoutCredential(const AuthenticationChallenge&)
+{
+ notImplemented();
+}
+
+void SocketStreamHandle::receivedCancellation(const AuthenticationChallenge&)
+{
+ notImplemented();
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/network/mac/AuthenticationMac.h b/WebCore/platform/network/mac/AuthenticationMac.h
index 7fb6bee..f55ac24 100644
--- a/WebCore/platform/network/mac/AuthenticationMac.h
+++ b/WebCore/platform/network/mac/AuthenticationMac.h
@@ -45,24 +45,6 @@ AuthenticationChallenge core(NSURLAuthenticationChallenge *);
ProtectionSpace core(NSURLProtectionSpace *);
Credential core(NSURLCredential *);
-class WebCoreCredentialStorage {
-public:
- static void set(NSURLCredential *credential, NSURLProtectionSpace *protectionSpace)
- {
- if (!m_storage)
- m_storage = [[NSMutableDictionary alloc] init];
- [m_storage setObject:credential forKey:protectionSpace];
- }
-
- static NSURLCredential *get(NSURLProtectionSpace *protectionSpace)
- {
- return static_cast<NSURLCredential *>([m_storage objectForKey:protectionSpace]);
- }
-
-private:
- static NSMutableDictionary* m_storage;
-};
-
}
#endif
diff --git a/WebCore/platform/network/mac/AuthenticationMac.mm b/WebCore/platform/network/mac/AuthenticationMac.mm
index 961a79d..355931d 100644
--- a/WebCore/platform/network/mac/AuthenticationMac.mm
+++ b/WebCore/platform/network/mac/AuthenticationMac.mm
@@ -36,9 +36,6 @@
namespace WebCore {
-
-NSMutableDictionary* WebCoreCredentialStorage::m_storage;
-
AuthenticationChallenge::AuthenticationChallenge(const ProtectionSpace& protectionSpace,
const Credential& proposedCredential,
unsigned previousFailureCount,
diff --git a/WebCore/platform/network/mac/FormDataStreamMac.mm b/WebCore/platform/network/mac/FormDataStreamMac.mm
index a8d6887..8aa9a6d 100644
--- a/WebCore/platform/network/mac/FormDataStreamMac.mm
+++ b/WebCore/platform/network/mac/FormDataStreamMac.mm
@@ -161,11 +161,9 @@ static void advanceCurrentStream(FormStreamFields *form)
form->currentData = data;
} else {
const String& path = nextInput.m_shouldGenerateFile ? nextInput.m_generatedFilename : nextInput.m_filename;
- CFStringRef filename = path.createCFString();
- CFURLRef fileURL = CFURLCreateWithFileSystemPath(0, filename, kCFURLPOSIXPathStyle, FALSE);
- CFRelease(filename);
- form->currentStream = CFReadStreamCreateWithFile(0, fileURL);
- CFRelease(fileURL);
+ RetainPtr<CFStringRef> filename(AdoptCF, path.createCFString());
+ RetainPtr<CFURLRef> fileURL(AdoptCF, CFURLCreateWithFileSystemPath(0, filename.get(), kCFURLPOSIXPathStyle, FALSE));
+ form->currentStream = CFReadStreamCreateWithFile(0, fileURL.get());
}
form->remainingElements.removeLast();
@@ -375,11 +373,10 @@ void setHTTPBody(NSMutableURLRequest *request, PassRefPtr<FormData> formData)
// Pass the length along with the formData so it does not have to be recomputed.
FormContext formContext = { formData.releaseRef(), length };
- CFReadStreamRef stream = wkCreateCustomCFReadStream(formCreate, formFinalize,
+ RetainPtr<CFReadStreamRef> stream(AdoptCF, wkCreateCustomCFReadStream(formCreate, formFinalize,
formOpen, formRead, formCanRead, formClose, formSchedule, formUnschedule,
- &formContext);
- [request setHTTPBodyStream:(NSInputStream *)stream];
- CFRelease(stream);
+ &formContext));
+ [request setHTTPBodyStream:(NSInputStream *)stream.get()];
}
FormData* httpBodyFromStream(NSInputStream* stream)
diff --git a/WebCore/platform/network/mac/ResourceErrorMac.mm b/WebCore/platform/network/mac/ResourceErrorMac.mm
index 94c2124..efd738f 100644
--- a/WebCore/platform/network/mac/ResourceErrorMac.mm
+++ b/WebCore/platform/network/mac/ResourceErrorMac.mm
@@ -76,7 +76,7 @@ ResourceError::operator NSError*() const
[userInfo.get() setValue:m_localizedDescription forKey:NSLocalizedDescriptionKey];
if (!m_failingURL.isEmpty()) {
- NSURL *cocoaURL = KURL(m_failingURL);
+ NSURL *cocoaURL = KURL(ParsedURLString, m_failingURL);
[userInfo.get() setValue:m_failingURL forKey:@"NSErrorFailingURLStringKey"];
[userInfo.get() setValue:cocoaURL forKey:@"NSErrorFailingURLKey"];
}
diff --git a/WebCore/platform/network/mac/ResourceHandleMac.mm b/WebCore/platform/network/mac/ResourceHandleMac.mm
index db76d1a..ec60079 100644
--- a/WebCore/platform/network/mac/ResourceHandleMac.mm
+++ b/WebCore/platform/network/mac/ResourceHandleMac.mm
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2006 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2006-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
@@ -28,7 +28,10 @@
#import "AuthenticationChallenge.h"
#import "AuthenticationMac.h"
+#import "Base64.h"
#import "BlockExceptions.h"
+#import "CString.h"
+#import "CredentialStorage.h"
#import "DocLoader.h"
#import "FormDataStreamMac.h"
#import "Frame.h"
@@ -64,10 +67,6 @@ using namespace WebCore;
- (NSData *)_bufferedData;
@end
-@interface NSURLResponse (Details)
-- (void)_setMIMEType:(NSString *)type;
-@end
-
@interface NSURLRequest (Details)
- (id)_propertyForKey:(NSString *)key;
@end
@@ -78,6 +77,8 @@ using namespace WebCore;
NSURL *m_url;
NSString *m_user;
NSString *m_pass;
+ // Store the preemptively used initial credential so that if we get an authentication challenge, we won't use the same one again.
+ Credential m_initialCredential;
BOOL m_allowStoredCredentials;
NSURLResponse *m_response;
NSMutableData *m_data;
@@ -118,6 +119,16 @@ public:
}
};
+static String encodeBasicAuthorization(const String& user, const String& password)
+{
+ CString unencodedString = (user + ":" + password).utf8();
+ Vector<char> unencoded(unencodedString.length());
+ std::copy(unencodedString.data(), unencodedString.data() + unencodedString.length(), unencoded.begin());
+ Vector<char> encoded;
+ base64Encode(unencoded, encoded);
+ return String(encoded.data(), encoded.size());
+}
+
ResourceHandleInternal::~ResourceHandleInternal()
{
}
@@ -171,6 +182,16 @@ bool ResourceHandle::start(Frame* frame)
urlWithCredentials.setPass(d->m_pass);
d->m_request.setURL(urlWithCredentials);
}
+
+ // <rdar://problem/7174050> - For URLs that match the paths of those previously challenged for HTTP Basic authentication,
+ // try and reuse the credential preemptively, as allowed by RFC 2617.
+ if (!client() || client()->shouldUseCredentialStorage(this) && d->m_request.url().protocolInHTTPFamily())
+ d->m_initialCredential = CredentialStorage::getDefaultAuthenticationCredential(d->m_request.url());
+
+ if (!d->m_initialCredential.isEmpty()) {
+ String authHeader = "Basic " + encodeBasicAuthorization(d->m_initialCredential.user(), d->m_initialCredential.password());
+ d->m_request.addHTTPHeaderField("Authorization", authHeader);
+ }
if (!ResourceHandle::didSendBodyDataDelegateExists())
associateStreamWithResourceHandle([d->m_request.nsURLRequest() HTTPBodyStream], this);
@@ -249,6 +270,10 @@ void ResourceHandle::cancel()
{
LOG(Network, "Handle %p cancel connection %p", this, d->m_connection.get());
+ // Leaks were seen on HTTP tests without this; can be removed once <rdar://problem/6886937> is fixed.
+ if (d->m_currentMacChallenge)
+ [[d->m_currentMacChallenge sender] cancelAuthenticationChallenge:d->m_currentMacChallenge];
+
if (!ResourceHandle::didSendBodyDataDelegateExists())
disassociateStreamWithResourceHandle([d->m_request.nsURLRequest() HTTPBodyStream]);
[d->m_connection.get() cancel];
@@ -458,9 +483,10 @@ void ResourceHandle::didReceiveAuthenticationChallenge(const AuthenticationChall
}
if (!challenge.previousFailureCount() && (!client() || client()->shouldUseCredentialStorage(this))) {
- NSURLCredential *credential = WebCoreCredentialStorage::get([mac(challenge) protectionSpace]);
- if (credential) {
- [challenge.sender() useCredential:credential forAuthenticationChallenge:mac(challenge)];
+ Credential credential = CredentialStorage::get(challenge.protectionSpace());
+ if (!credential.isEmpty() && credential != d->m_initialCredential) {
+ ASSERT(credential.persistence() == CredentialPersistenceNone);
+ [challenge.sender() useCredential:mac(credential) forAuthenticationChallenge:mac(challenge)];
return;
}
}
@@ -495,7 +521,11 @@ void ResourceHandle::receivedCredential(const AuthenticationChallenge& challenge
if (credential.persistence() == CredentialPersistenceNone) {
// NSURLCredentialPersistenceNone doesn't work on Tiger, so we have to use session persistence.
Credential webCredential(credential.user(), credential.password(), CredentialPersistenceForSession);
- WebCoreCredentialStorage::set(mac(webCredential), [d->m_currentMacChallenge protectionSpace]);
+ KURL urlToStore;
+ if (challenge.failureResponse().httpStatusCode() == 401)
+ urlToStore = d->m_request.url();
+ CredentialStorage::set(webCredential, core([d->m_currentMacChallenge protectionSpace]), urlToStore);
+
[[d->m_currentMacChallenge sender] useCredential:mac(webCredential) forAuthenticationChallenge:d->m_currentMacChallenge];
} else
#else
@@ -504,7 +534,10 @@ void ResourceHandle::receivedCredential(const AuthenticationChallenge& challenge
// to ignore it for a particular request (short of removing it altogether).
// <rdar://problem/6867598> gallery.me.com is temporarily whitelisted, so that QuickTime plug-in could see the credentials.
Credential webCredential(credential.user(), credential.password(), CredentialPersistenceNone);
- WebCoreCredentialStorage::set(mac(webCredential), [d->m_currentMacChallenge protectionSpace]);
+ KURL urlToStore;
+ if (challenge.failureResponse().httpStatusCode() == 401)
+ urlToStore = d->m_request.url();
+ CredentialStorage::set(webCredential, core([d->m_currentMacChallenge protectionSpace]), urlToStore);
[[d->m_currentMacChallenge sender] useCredential:mac(webCredential) forAuthenticationChallenge:d->m_currentMacChallenge];
} else
#endif
@@ -572,6 +605,15 @@ void ResourceHandle::receivedCancellation(const AuthenticationChallenge& challen
if (!equalIgnoringCase(originalMethod, String([newRequest HTTPMethod]))) {
NSMutableURLRequest *mutableRequest = [newRequest mutableCopy];
[mutableRequest setHTTPMethod:originalMethod];
+
+ FormData* body = m_handle->request().httpBody();
+ if (!equalIgnoringCase(originalMethod, "GET") && body && !body->isEmpty())
+ WebCore::setHTTPBody(mutableRequest, body);
+
+ String originalContentType = m_handle->request().httpContentType();
+ if (!originalContentType.isEmpty())
+ [mutableRequest setValue:originalContentType forHTTPHeaderField:@"Content-Type"];
+
newRequest = [mutableRequest autorelease];
}
}
@@ -635,13 +677,13 @@ void ResourceHandle::receivedCancellation(const AuthenticationChallenge& challen
{
UNUSED_PARAM(connection);
- LOG(Network, "Handle %p delegate connection:%p didReceiveResponse:%p (HTTP status %d, MIMEType '%s', reported MIMEType '%s')", m_handle, connection, r, [r respondsToSelector:@selector(statusCode)] ? [(id)r statusCode] : 0, [[r MIMEType] UTF8String], [[r _webcore_reportedMIMEType] UTF8String]);
+ LOG(Network, "Handle %p delegate connection:%p didReceiveResponse:%p (HTTP status %d, reported MIMEType '%s')", m_handle, connection, r, [r respondsToSelector:@selector(statusCode)] ? [(id)r statusCode] : 0, [[r MIMEType] UTF8String]);
if (!m_handle || !m_handle->client())
return;
CallbackGuard guard;
- swizzleMIMETypeMethodIfNecessary();
+ [r adjustMIMETypeIfNecessary];
if ([m_handle->request().nsURLRequest() _propertyForKey:@"ForceHTMLMIMEType"])
[r _setMIMEType:@"text/html"];
@@ -851,9 +893,11 @@ void ResourceHandle::receivedCancellation(const AuthenticationChallenge& challen
[super dealloc];
}
-- (NSURLRequest *)connection:(NSURLConnection *)unusedConnection willSendRequest:(NSURLRequest *)newRequest redirectResponse:(NSURLResponse *)redirectResponse
+- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)newRequest redirectResponse:(NSURLResponse *)redirectResponse
{
- UNUSED_PARAM(unusedConnection);
+ UNUSED_PARAM(connection);
+
+ LOG(Network, "WebCoreSynchronousLoader delegate connection:%p willSendRequest:%@ redirectResponse:%p", connection, [newRequest description], redirectResponse);
// FIXME: This needs to be fixed to follow the redirect correctly even for cross-domain requests.
if (m_url && !protocolHostAndPortAreEqual(m_url, [newRequest URL])) {
@@ -882,23 +926,31 @@ void ResourceHandle::receivedCancellation(const AuthenticationChallenge& challen
return newRequest;
}
-- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection *)unusedConnection
+- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection *)connection
{
- UNUSED_PARAM(unusedConnection);
+ UNUSED_PARAM(connection);
+
+ LOG(Network, "WebCoreSynchronousLoader delegate connectionShouldUseCredentialStorage:%p", connection);
// FIXME: We should ask FrameLoaderClient whether using credential storage is globally forbidden.
return m_allowStoredCredentials;
}
-- (void)connection:(NSURLConnection *)unusedConnection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
+- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
- UNUSED_PARAM(unusedConnection);
+ UNUSED_PARAM(connection);
+
+ LOG(Network, "WebCoreSynchronousLoader delegate connection:%p didReceiveAuthenticationChallenge:%p", connection, challenge);
if (m_user && m_pass) {
NSURLCredential *credential = [[NSURLCredential alloc] initWithUser:m_user
password:m_pass
persistence:NSURLCredentialPersistenceNone];
- WebCoreCredentialStorage::set(credential, [challenge protectionSpace]);
+ KURL urlToStore;
+ if ([[challenge failureResponse] isKindOfClass:[NSHTTPURLResponse class]] && [(NSHTTPURLResponse*)[challenge failureResponse] statusCode] == 401)
+ urlToStore = m_url;
+ CredentialStorage::set(core(credential), core([challenge protectionSpace]), urlToStore);
+
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
[credential release];
[m_user release];
@@ -908,10 +960,10 @@ void ResourceHandle::receivedCancellation(const AuthenticationChallenge& challen
return;
}
if ([challenge previousFailureCount] == 0 && m_allowStoredCredentials) {
- NSURLCredential *credential = WebCoreCredentialStorage::get([challenge protectionSpace]);
- ASSERT([credential persistence] == NSURLCredentialPersistenceNone);
- if (credential) {
- [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
+ Credential credential = CredentialStorage::get(core([challenge protectionSpace]));
+ if (!credential.isEmpty() && credential != m_initialCredential) {
+ ASSERT(credential.persistence() == CredentialPersistenceNone);
+ [[challenge sender] useCredential:mac(credential) forAuthenticationChallenge:challenge];
return;
}
}
@@ -919,9 +971,11 @@ void ResourceHandle::receivedCancellation(const AuthenticationChallenge& challen
[[challenge sender] continueWithoutCredentialForAuthenticationChallenge:challenge];
}
-- (void)connection:(NSURLConnection *)unusedConnection didReceiveResponse:(NSURLResponse *)response
+- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
- UNUSED_PARAM(unusedConnection);
+ UNUSED_PARAM(connection);
+
+ LOG(Network, "WebCoreSynchronousLoader delegate connection:%p didReceiveResponse:%p (HTTP status %d, reported MIMEType '%s')", connection, response, [response respondsToSelector:@selector(statusCode)] ? [(id)response statusCode] : 0, [[response MIMEType] UTF8String]);
NSURLResponse *r = [response copy];
@@ -929,9 +983,11 @@ void ResourceHandle::receivedCancellation(const AuthenticationChallenge& challen
m_response = r;
}
-- (void)connection:(NSURLConnection *)unusedConnection didReceiveData:(NSData *)data
+- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
- UNUSED_PARAM(unusedConnection);
+ UNUSED_PARAM(connection);
+
+ LOG(Network, "WebCoreSynchronousLoader delegate connection:%p didReceiveData:%p", connection, data);
if (!m_data)
m_data = [[NSMutableData alloc] init];
@@ -939,16 +995,20 @@ void ResourceHandle::receivedCancellation(const AuthenticationChallenge& challen
[m_data appendData:data];
}
-- (void)connectionDidFinishLoading:(NSURLConnection *)unusedConnection
+- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
- UNUSED_PARAM(unusedConnection);
+ UNUSED_PARAM(connection);
+
+ LOG(Network, "WebCoreSynchronousLoader delegate connectionDidFinishLoading:%p", connection);
m_isDone = YES;
}
-- (void)connection:(NSURLConnection *)unusedConnection didFailWithError:(NSError *)error
+- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
- UNUSED_PARAM(unusedConnection);
+ UNUSED_PARAM(connection);
+
+ LOG(Network, "WebCoreSynchronousLoader delegate connection:%p didFailWithError:%@", connection, error);
ASSERT(!m_error);
@@ -973,23 +1033,36 @@ void ResourceHandle::receivedCancellation(const AuthenticationChallenge& challen
+ (NSData *)loadRequest:(NSURLRequest *)request allowStoredCredentials:(BOOL)allowStoredCredentials returningResponse:(NSURLResponse **)response error:(NSError **)error
{
+ LOG(Network, "WebCoreSynchronousLoader loadRequest:%@ allowStoredCredentials:%u", request, allowStoredCredentials);
+
WebCoreSynchronousLoader *delegate = [[WebCoreSynchronousLoader alloc] init];
- NSURL *url = [request URL];
- delegate->m_user = [[url user] copy];
- delegate->m_pass = [[url password] copy];
+ KURL url([request URL]);
+ delegate->m_user = [nsStringNilIfEmpty(url.user()) retain];
+ delegate->m_pass = [nsStringNilIfEmpty(url.pass()) retain];
delegate->m_allowStoredCredentials = allowStoredCredentials;
NSURLConnection *connection;
// Take user/pass out of the URL.
// Credentials for ftp can only be passed in URL, the connection:didReceiveAuthenticationChallenge: delegate call won't be made.
- if ((delegate->m_user || delegate->m_pass) && KURL(url).protocolInHTTPFamily()) {
+ if ((delegate->m_user || delegate->m_pass) && url.protocolInHTTPFamily()) {
ResourceRequest requestWithoutCredentials = request;
requestWithoutCredentials.removeCredentials();
connection = [[NSURLConnection alloc] initWithRequest:requestWithoutCredentials.nsURLRequest() delegate:delegate startImmediately:NO];
- } else
- connection = [[NSURLConnection alloc] initWithRequest:request delegate:delegate startImmediately:NO];
+ } else {
+ // <rdar://problem/7174050> - For URLs that match the paths of those previously challenged for HTTP Basic authentication,
+ // try and reuse the credential preemptively, as allowed by RFC 2617.
+ ResourceRequest requestWithInitialCredentials = request;
+ if (allowStoredCredentials && url.protocolInHTTPFamily())
+ delegate->m_initialCredential = CredentialStorage::getDefaultAuthenticationCredential(url);
+
+ if (!delegate->m_initialCredential.isEmpty()) {
+ String authHeader = "Basic " + encodeBasicAuthorization(delegate->m_initialCredential.user(), delegate->m_initialCredential.password());
+ requestWithInitialCredentials.addHTTPHeaderField("Authorization", authHeader);
+ }
+ connection = [[NSURLConnection alloc] initWithRequest:requestWithInitialCredentials.nsURLRequest() delegate:delegate startImmediately:NO];
+ }
[connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:WebCoreSynchronousLoaderRunLoopMode];
[connection start];
@@ -1005,7 +1078,9 @@ void ResourceHandle::receivedCancellation(const AuthenticationChallenge& challen
[connection release];
[delegate release];
-
+
+ LOG(Network, "WebCoreSynchronousLoader done");
+
return data;
}
diff --git a/WebCore/platform/network/mac/ResourceRequest.h b/WebCore/platform/network/mac/ResourceRequest.h
index 5bcb33e..b09e72d 100644
--- a/WebCore/platform/network/mac/ResourceRequest.h
+++ b/WebCore/platform/network/mac/ResourceRequest.h
@@ -41,7 +41,7 @@ namespace WebCore {
class ResourceRequest : public ResourceRequestBase {
public:
ResourceRequest(const String& url)
- : ResourceRequestBase(KURL(url), UseProtocolCachePolicy)
+ : ResourceRequestBase(KURL(ParsedURLString, url), UseProtocolCachePolicy)
{
}
diff --git a/WebCore/platform/network/mac/ResourceRequestMac.mm b/WebCore/platform/network/mac/ResourceRequestMac.mm
index 6bb36a0..c4355b2 100644
--- a/WebCore/platform/network/mac/ResourceRequestMac.mm
+++ b/WebCore/platform/network/mac/ResourceRequestMac.mm
@@ -61,7 +61,7 @@ void ResourceRequest::doUpdateResourceRequest()
if (NSString* method = [m_nsRequest.get() HTTPMethod])
m_httpMethod = method;
- m_allowHTTPCookies = [m_nsRequest.get() HTTPShouldHandleCookies];
+ m_allowCookies = [m_nsRequest.get() HTTPShouldHandleCookies];
NSDictionary *headers = [m_nsRequest.get() allHTTPHeaderFields];
NSEnumerator *e = [headers keyEnumerator];
@@ -113,7 +113,7 @@ void ResourceRequest::doUpdatePlatformRequest()
[nsRequest setMainDocumentURL:firstPartyForCookies()];
if (!httpMethod().isEmpty())
[nsRequest setHTTPMethod:httpMethod()];
- [nsRequest setHTTPShouldHandleCookies:allowHTTPCookies()];
+ [nsRequest setHTTPShouldHandleCookies:allowCookies()];
HTTPHeaderMap::const_iterator end = httpHeaderFields().end();
for (HTTPHeaderMap::const_iterator it = httpHeaderFields().begin(); it != end; ++it)
diff --git a/WebCore/platform/network/mac/WebCoreURLResponse.h b/WebCore/platform/network/mac/WebCoreURLResponse.h
index 0a9a7c4..8d43a21 100644
--- a/WebCore/platform/network/mac/WebCoreURLResponse.h
+++ b/WebCore/platform/network/mac/WebCoreURLResponse.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 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
@@ -27,7 +27,9 @@
*/
@interface NSURLResponse (WebCoreURLResponse)
--(NSString *)_webcore_reportedMIMEType;
+-(void)adjustMIMETypeIfNecessary;
@end
-void swizzleMIMETypeMethodIfNecessary();
+@interface NSURLResponse (Details)
+- (void)_setMIMEType:(NSString *)type;
+@end
diff --git a/WebCore/platform/network/mac/WebCoreURLResponse.mm b/WebCore/platform/network/mac/WebCoreURLResponse.mm
index f025769..9be4714 100644
--- a/WebCore/platform/network/mac/WebCoreURLResponse.mm
+++ b/WebCore/platform/network/mac/WebCoreURLResponse.mm
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 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
@@ -327,23 +327,6 @@ static NSDictionary *createExtensionToMIMETypeMap()
];
}
-static IMP oldNSURLResponseMIMETypeIMP = 0;
-static NSString *webNSURLResponseMIMEType(id, SEL);
-
-void swizzleMIMETypeMethodIfNecessary()
-{
- if (!oldNSURLResponseMIMETypeIMP) {
- Method nsURLResponseMIMETypeMethod = class_getInstanceMethod([NSURLResponse class], @selector(MIMEType));
- ASSERT(nsURLResponseMIMETypeMethod);
-#ifdef BUILDING_ON_TIGER
- oldNSURLResponseMIMETypeIMP = nsURLResponseMIMETypeMethod->method_imp;
- nsURLResponseMIMETypeMethod->method_imp = (IMP)webNSURLResponseMIMEType;
-#else
- oldNSURLResponseMIMETypeIMP = method_setImplementation(nsURLResponseMIMETypeMethod, (IMP)webNSURLResponseMIMEType);
-#endif
- }
-}
-
static NSString *mimeTypeFromUTITree(CFStringRef uti)
{
// Check if this UTI has a MIME type.
@@ -379,10 +362,12 @@ static NSString *mimeTypeFromUTITree(CFStringRef uti)
return nil;
}
-static NSString *webNSURLResponseMIMEType(id self, SEL _cmd)
+@implementation NSURLResponse (WebCoreURLResponse)
+
+-(void)adjustMIMETypeIfNecessary
{
- ASSERT(oldNSURLResponseMIMETypeIMP);
- NSString *result = oldNSURLResponseMIMETypeIMP(self, _cmd);
+ NSString *result = [self MIMEType];
+ NSString *originalResult = result;
#ifdef BUILDING_ON_TIGER
// When content sniffing is disabled, Tiger's CFNetwork automatically returns application/octet-stream for certain
@@ -418,7 +403,7 @@ static NSString *webNSURLResponseMIMEType(id self, SEL _cmd)
#ifndef BUILDING_ON_TIGER
// <rdar://problem/5321972> Plain text document from HTTP server detected as application/octet-stream
// Make the best guess when deciding between "generic binary" and "generic text" using a table of known binary MIME types.
- if ([result isEqualToString:@"application/octet-stream"] && [self respondsToSelector:@selector(allHeaderFields)] && [[[self allHeaderFields] objectForKey:@"Content-Type"] hasPrefix:@"text/plain"]) {
+ if ([result isEqualToString:@"application/octet-stream"] && [self respondsToSelector:@selector(allHeaderFields)] && [[[self performSelector:@selector(allHeaderFields)] objectForKey:@"Content-Type"] hasPrefix:@"text/plain"]) {
static NSSet *binaryExtensions = createBinaryExtensionsSet();
if (![binaryExtensions containsObject:[[[self suggestedFilename] pathExtension] lowercaseString]])
result = @"text/plain";
@@ -432,15 +417,8 @@ static NSString *webNSURLResponseMIMEType(id self, SEL _cmd)
result = @"application/xml";
#endif
- return result;
-}
-
-@implementation NSURLResponse (WebCoreURLResponse)
-
--(NSString *)_webcore_reportedMIMEType
-{
- swizzleMIMETypeMethodIfNecessary();
- return oldNSURLResponseMIMETypeIMP(self, @selector(_webcore_realMIMEType));
+ if (result != originalResult)
+ [self _setMIMEType:result];
}
@end
diff --git a/WebCore/platform/network/qt/DnsPrefetchHelper.cpp b/WebCore/platform/network/qt/DnsPrefetchHelper.cpp
new file mode 100644
index 0000000..e687976
--- /dev/null
+++ b/WebCore/platform/network/qt/DnsPrefetchHelper.cpp
@@ -0,0 +1,35 @@
+/*
+ Copyright (C) 2009 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 "DnsPrefetchHelper.h"
+
+#include "CString.h"
+
+namespace WebCore {
+// this is called on mouse over a href and on page loading
+void prefetchDNS(const String& hostname)
+{
+ if (QWebSettings::globalSettings()->testAttribute(QWebSettings::DnsPrefetchEnabled)) {
+ static DnsPrefetchHelper dnsPrefetchHelper;
+ dnsPrefetchHelper.lookup(QString(hostname));
+ }
+}
+
+}
diff --git a/WebCore/platform/network/qt/DnsPrefetchHelper.h b/WebCore/platform/network/qt/DnsPrefetchHelper.h
new file mode 100644
index 0000000..0d98fcb
--- /dev/null
+++ b/WebCore/platform/network/qt/DnsPrefetchHelper.h
@@ -0,0 +1,75 @@
+/*
+ Copyright (C) 2009 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 DNSPREFETCHHELPER_H
+#define DNSPREFETCHHELPER_H
+
+#include <QObject>
+#include <QCache>
+#include <QHostInfo>
+#include <QSet>
+#include <QString>
+#include <QTime>
+#include "qwebsettings.h"
+
+namespace WebCore {
+
+ class DnsPrefetchHelper : public QObject {
+ Q_OBJECT
+ public:
+ DnsPrefetchHelper() : QObject(), currentLookups(0) {};
+
+ public slots:
+ void lookup(QString hostname)
+ {
+ if (hostname.isEmpty())
+ return; // this actually happens
+ if (currentLookups >= 10)
+ return; // do not launch more than 10 lookups at the same time
+
+ QTime* entryTime = lookupCache.object(hostname);
+ if (entryTime && entryTime->elapsed() > 300*1000) {
+ // delete knowledge about lookup if it is already 300 seconds old
+ lookupCache.remove(hostname);
+ } else if (!entryTime) {
+ // not in cache yet, can look it up
+ QTime *tmpTime = new QTime();
+ *tmpTime = QTime::currentTime();
+ lookupCache.insert(hostname, tmpTime);
+ currentLookups++;
+ QHostInfo::lookupHost(hostname, this, SLOT(lookedUp(QHostInfo)));
+ }
+ }
+
+ void lookedUp(const QHostInfo&)
+ {
+ // we do not cache the result, we throw it away.
+ // we currently rely on the OS to cache the results. If it does not do that
+ // then at least the ISP nameserver did it.
+ currentLookups--;
+ }
+
+ protected:
+ QCache<QString, QTime> lookupCache; // 100 entries
+ int currentLookups;
+ };
+
+
+}
+
+#endif // DNSPREFETCHHELPER_H
diff --git a/WebCore/platform/network/qt/QNetworkReplyHandler.cpp b/WebCore/platform/network/qt/QNetworkReplyHandler.cpp
index 898e5f4..7a3703d 100644
--- a/WebCore/platform/network/qt/QNetworkReplyHandler.cpp
+++ b/WebCore/platform/network/qt/QNetworkReplyHandler.cpp
@@ -131,10 +131,11 @@ void FormDataIODevice::slotFinished()
QNetworkReplyHandler::QNetworkReplyHandler(ResourceHandle* handle, LoadMode loadMode)
: QObject(0)
- , m_resourceHandle(handle)
, m_reply(0)
+ , m_resourceHandle(handle)
, m_redirected(false)
, m_responseSent(false)
+ , m_responseDataSent(false)
, m_loadMode(loadMode)
, m_shouldStart(true)
, m_shouldFinish(false)
@@ -204,6 +205,19 @@ QNetworkReply* QNetworkReplyHandler::release()
return reply;
}
+static bool ignoreHttpError(QNetworkReply* reply, bool receivedData)
+{
+ int httpStatusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
+
+ if (httpStatusCode == 401 || httpStatusCode == 407)
+ return true;
+
+ if (receivedData && (httpStatusCode >= 400 && httpStatusCode < 600))
+ return true;
+
+ return false;
+}
+
void QNetworkReplyHandler::finish()
{
m_shouldFinish = (m_loadMode != LoadNormal);
@@ -220,23 +234,27 @@ void QNetworkReplyHandler::finish()
m_reply = 0;
return;
}
+
QNetworkReply* oldReply = m_reply;
+
if (m_redirected) {
resetState();
start();
- } else if (m_reply->error() != QNetworkReply::NoError
- // a web page that returns 401/403/404 can still have content
- && m_reply->error() != QNetworkReply::ContentOperationNotPermittedError
- && m_reply->error() != QNetworkReply::ContentNotFoundError
- && m_reply->error() != QNetworkReply::AuthenticationRequiredError
- && m_reply->error() != QNetworkReply::ProxyAuthenticationRequiredError) {
- QUrl url = m_reply->url();
- ResourceError error(url.host(), m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(),
- url.toString(), m_reply->errorString());
- client->didFail(m_resourceHandle, error);
- } else {
+ } else if (!m_reply->error() || ignoreHttpError(m_reply, m_responseDataSent)) {
client->didFinishLoading(m_resourceHandle);
+ } else {
+ QUrl url = m_reply->url();
+ int httpStatusCode = m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
+
+ if (httpStatusCode) {
+ ResourceError error("HTTP", httpStatusCode, url.toString(), m_reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString());
+ client->didFail(m_resourceHandle, error);
+ } else {
+ ResourceError error("QtNetwork", m_reply->error(), url.toString(), m_reply->errorString());
+ client->didFail(m_resourceHandle, error);
+ }
}
+
oldReply->deleteLater();
if (oldReply == m_reply)
m_reply = 0;
@@ -248,6 +266,9 @@ void QNetworkReplyHandler::sendResponseIfNeeded()
if (m_shouldSendResponse)
return;
+ if (m_reply->error())
+ return;
+
if (m_responseSent || !m_resourceHandle)
return;
m_responseSent = true;
@@ -271,41 +292,34 @@ void QNetworkReplyHandler::sendResponseIfNeeded()
}
KURL url(m_reply->url());
- String suggestedFilename = filenameFromHTTPContentDisposition(QString::fromAscii(m_reply->rawHeader("Content-Disposition")));
-
- if (suggestedFilename.isEmpty())
- suggestedFilename = url.lastPathComponent();
-
ResourceResponse response(url, mimeType,
m_reply->header(QNetworkRequest::ContentLengthHeader).toLongLong(),
- encoding,
- suggestedFilename);
+ encoding, String());
- const bool isLocalFileReply = (m_reply->url().scheme() == QLatin1String("file"));
- int statusCode = m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
- if (!isLocalFileReply) {
- response.setHTTPStatusCode(statusCode);
- response.setHTTPStatusText(m_reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toByteArray().constData());
+ if (url.isLocalFile()) {
+ client->didReceiveResponse(m_resourceHandle, response);
+ return;
}
- else if (m_reply->error() == QNetworkReply::ContentNotFoundError)
- response.setHTTPStatusCode(404);
+ // The status code is equal to 0 for protocols not in the HTTP family.
+ int statusCode = m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
- /* Fill in the other fields
- * For local file requests remove the content length and the last-modified
- * headers as required by fast/dom/xmlhttprequest-get.xhtml
- */
- foreach (QByteArray headerName, m_reply->rawHeaderList()) {
+ if (url.protocolInHTTPFamily()) {
+ String suggestedFilename = filenameFromHTTPContentDisposition(QString::fromAscii(m_reply->rawHeader("Content-Disposition")));
- if (isLocalFileReply
- && (headerName == "Content-Length" || headerName == "Last-Modified"))
- continue;
+ if (!suggestedFilename.isEmpty())
+ response.setSuggestedFilename(suggestedFilename);
+ else
+ response.setSuggestedFilename(url.lastPathComponent());
- response.setHTTPHeaderField(QString::fromAscii(headerName), QString::fromAscii(m_reply->rawHeader(headerName)));
- }
+ response.setHTTPStatusCode(statusCode);
+ response.setHTTPStatusText(m_reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toByteArray().constData());
- if (isLocalFileReply)
- response.setHTTPHeaderField(QString::fromAscii("Cache-Control"), QString::fromAscii("no-cache"));
+ // Add remaining headers.
+ foreach (const QByteArray& headerName, m_reply->rawHeaderList()) {
+ response.setHTTPHeaderField(QString::fromAscii(headerName), QString::fromAscii(m_reply->rawHeader(headerName)));
+ }
+ }
QUrl redirection = m_reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
if (redirection.isValid()) {
@@ -321,9 +335,13 @@ void QNetworkReplyHandler::sendResponseIfNeeded()
client->willSendRequest(m_resourceHandle, newRequest, response);
m_redirected = true;
m_request = newRequest.toNetworkRequest();
- } else {
- client->didReceiveResponse(m_resourceHandle, response);
+
+ ResourceHandleInternal* d = m_resourceHandle->getInternal();
+ emit d->m_frame->page()->networkRequestStarted(d->m_frame, &m_request);
+ return;
}
+
+ client->didReceiveResponse(m_resourceHandle, response);
}
void QNetworkReplyHandler::forwardData()
@@ -347,8 +365,10 @@ void QNetworkReplyHandler::forwardData()
if (!client)
return;
- if (!data.isEmpty())
+ if (!data.isEmpty()) {
+ m_responseDataSent = true;
client->didReceiveData(m_resourceHandle, data.constData(), data.length(), data.length() /*FixMe*/);
+ }
}
void QNetworkReplyHandler::start()
@@ -359,6 +379,8 @@ void QNetworkReplyHandler::start()
QNetworkAccessManager* manager = d->m_frame->page()->networkAccessManager();
+ emit d->m_frame->page()->networkRequestStarted(d->m_frame, &m_request);
+
const QUrl url = m_request.url();
const QString scheme = url.scheme();
// Post requests on files and data don't really make sense, but for
@@ -421,6 +443,7 @@ void QNetworkReplyHandler::resetState()
{
m_redirected = false;
m_responseSent = false;
+ m_responseDataSent = false;
m_shouldStart = true;
m_shouldFinish = false;
m_shouldSendResponse = false;
diff --git a/WebCore/platform/network/qt/QNetworkReplyHandler.h b/WebCore/platform/network/qt/QNetworkReplyHandler.h
index f88ce8a..545119e 100644
--- a/WebCore/platform/network/qt/QNetworkReplyHandler.h
+++ b/WebCore/platform/network/qt/QNetworkReplyHandler.h
@@ -73,6 +73,7 @@ private:
ResourceHandle* m_resourceHandle;
bool m_redirected;
bool m_responseSent;
+ bool m_responseDataSent;
LoadMode m_loadMode;
QNetworkAccessManager::Operation m_method;
QNetworkRequest m_request;
diff --git a/WebCore/platform/network/qt/ResourceRequest.h b/WebCore/platform/network/qt/ResourceRequest.h
index af76f61..93dacf3 100644
--- a/WebCore/platform/network/qt/ResourceRequest.h
+++ b/WebCore/platform/network/qt/ResourceRequest.h
@@ -38,7 +38,7 @@ namespace WebCore {
struct ResourceRequest : ResourceRequestBase {
ResourceRequest(const String& url)
- : ResourceRequestBase(KURL(url), UseProtocolCachePolicy)
+ : ResourceRequestBase(KURL(ParsedURLString, url), UseProtocolCachePolicy)
{
}
diff --git a/WebCore/platform/network/qt/SocketStreamError.h b/WebCore/platform/network/qt/SocketStreamError.h
new file mode 100644
index 0000000..f9641ad
--- /dev/null
+++ b/WebCore/platform/network/qt/SocketStreamError.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SocketStreamError_h
+#define SocketStreamError_h
+
+#include "SocketStreamErrorBase.h"
+
+namespace WebCore {
+
+ class SocketStreamError : public SocketStreamErrorBase {
+ public:
+ SocketStreamError() { }
+ explicit SocketStreamError(int errorCode)
+ : SocketStreamErrorBase(errorCode)
+ {
+ }
+
+ };
+
+} // namespace WebCore
+
+#endif // SocketStreamError_h
diff --git a/WebCore/platform/network/qt/SocketStreamHandle.h b/WebCore/platform/network/qt/SocketStreamHandle.h
new file mode 100644
index 0000000..64139e5
--- /dev/null
+++ b/WebCore/platform/network/qt/SocketStreamHandle.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SocketStreamHandle_h
+#define SocketStreamHandle_h
+
+#include "SocketStreamHandleBase.h"
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+ class AuthenticationChallenge;
+ class Credential;
+ class SocketStreamHandleClient;
+
+ class SocketStreamHandle : public RefCounted<SocketStreamHandle>, public SocketStreamHandleBase {
+ public:
+ static PassRefPtr<SocketStreamHandle> create(const KURL& url, SocketStreamHandleClient* client) { return adoptRef(new SocketStreamHandle(url, client)); }
+
+ virtual ~SocketStreamHandle();
+
+ protected:
+ virtual int platformSend(const char* data, int length);
+ virtual void platformClose();
+
+ private:
+ SocketStreamHandle(const KURL&, SocketStreamHandleClient*);
+
+ // No authentication for streams per se, but proxy may ask for credentials.
+ void didReceiveAuthenticationChallenge(const AuthenticationChallenge&);
+ void receivedCredential(const AuthenticationChallenge&, const Credential&);
+ void receivedRequestToContinueWithoutCredential(const AuthenticationChallenge&);
+ void receivedCancellation(const AuthenticationChallenge&);
+ };
+
+} // namespace WebCore
+
+#endif // SocketStreamHandle_h
diff --git a/WebCore/platform/network/qt/SocketStreamHandleSoup.cpp b/WebCore/platform/network/qt/SocketStreamHandleSoup.cpp
new file mode 100644
index 0000000..6aa33fc
--- /dev/null
+++ b/WebCore/platform/network/qt/SocketStreamHandleSoup.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "SocketStreamHandle.h"
+
+#include "KURL.h"
+#include "Logging.h"
+#include "NotImplemented.h"
+#include "SocketStreamHandleClient.h"
+
+namespace WebCore {
+
+SocketStreamHandle::SocketStreamHandle(const KURL& url, SocketStreamHandleClient* client)
+ : SocketStreamHandleBase(url, client)
+{
+ LOG(Network, "SocketStreamHandle %p new client %p", this, m_client);
+ notImplemented();
+}
+
+SocketStreamHandle::~SocketStreamHandle()
+{
+ LOG(Network, "SocketStreamHandle %p delete", this);
+ setClient(0);
+ notImplemented();
+}
+
+int SocketStreamHandle::platformSend(const char*, int)
+{
+ LOG(Network, "SocketStreamHandle %p platformSend", this);
+ notImplemented();
+ return 0;
+}
+
+void SocketStreamHandle::platformClose()
+{
+ LOG(Network, "SocketStreamHandle %p platformClose", this);
+ notImplemented();
+}
+
+void SocketStreamHandle::didReceiveAuthenticationChallenge(const AuthenticationChallenge&)
+{
+ notImplemented();
+}
+
+void SocketStreamHandle::receivedCredential(const AuthenticationChallenge&, const Credential&)
+{
+ notImplemented();
+}
+
+void SocketStreamHandle::receivedRequestToContinueWithoutCredential(const AuthenticationChallenge&)
+{
+ notImplemented();
+}
+
+void SocketStreamHandle::receivedCancellation(const AuthenticationChallenge&)
+{
+ notImplemented();
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/network/soup/CookieJarSoup.cpp b/WebCore/platform/network/soup/CookieJarSoup.cpp
index 705fdf2..3eb578a 100644
--- a/WebCore/platform/network/soup/CookieJarSoup.cpp
+++ b/WebCore/platform/network/soup/CookieJarSoup.cpp
@@ -21,6 +21,7 @@
#include "config.h"
#include "CookieJarSoup.h"
+#include "Cookie.h"
#include "CString.h"
#include "Document.h"
#include "KURL.h"
@@ -86,4 +87,16 @@ bool cookiesEnabled(const Document* /*document*/)
return defaultCookieJar();
}
+bool getRawCookies(const Document*, const KURL&, Vector<Cookie>& rawCookies)
+{
+ // FIXME: Not yet implemented
+ rawCookies.clear();
+ return false; // return true when implemented
+}
+
+void deleteCookie(const Document*, const KURL&, const String&)
+{
+ // FIXME: Not yet implemented
+}
+
}
diff --git a/WebCore/platform/network/soup/ResourceHandleSoup.cpp b/WebCore/platform/network/soup/ResourceHandleSoup.cpp
index 4a22d8a..2177bd2 100644
--- a/WebCore/platform/network/soup/ResourceHandleSoup.cpp
+++ b/WebCore/platform/network/soup/ResourceHandleSoup.cpp
@@ -118,7 +118,7 @@ void WebCoreSynchronousLoader::run()
g_main_loop_run(m_mainLoop);
}
-static void cleanupGioOperation(ResourceHandleInternal* handle);
+static void cleanupGioOperation(ResourceHandle* handle, bool isDestroying);
static bool startData(ResourceHandle* handle, String urlString);
static bool startGio(ResourceHandle* handle, KURL url);
@@ -129,8 +129,6 @@ ResourceHandleInternal::~ResourceHandleInternal()
m_msg = 0;
}
- cleanupGioOperation(this);
-
if (m_idleHandler) {
g_source_remove(m_idleHandler);
m_idleHandler = 0;
@@ -142,6 +140,21 @@ ResourceHandle::~ResourceHandle()
if (d->m_msg)
g_signal_handlers_disconnect_matched(d->m_msg, G_SIGNAL_MATCH_DATA,
0, 0, 0, 0, this);
+
+ cleanupGioOperation(this, true);
+}
+
+// All other kinds of redirections, except for the *304* status code
+// (SOUP_STATUS_NOT_MODIFIED) which needs to be fed into WebCore, will be
+// handled by soup directly.
+static gboolean statusWillBeHandledBySoup(guint statusCode)
+{
+ if (SOUP_STATUS_IS_TRANSPORT_ERROR(statusCode)
+ || (SOUP_STATUS_IS_REDIRECTION(statusCode) && (statusCode != SOUP_STATUS_NOT_MODIFIED))
+ || (statusCode == SOUP_STATUS_UNAUTHORIZED))
+ return true;
+
+ return false;
}
static void fillResponseFromMessage(SoupMessage* msg, ResourceResponse* response)
@@ -185,6 +198,7 @@ static void restartedCallback(SoupMessage* msg, gpointer data)
ResourceRequest request = handle->request();
ResourceResponse response;
request.setURL(newURL);
+ request.setHTTPMethod(msg->method);
fillResponseFromMessage(msg, &response);
if (d->client())
d->client()->willSendRequest(handle, request, response);
@@ -204,22 +218,25 @@ static void gotHeadersCallback(SoupMessage* msg, gpointer data)
// we got, when we finish downloading.
soup_message_body_set_accumulate(msg->response_body, FALSE);
- if (msg->status_code == SOUP_STATUS_NOT_MODIFIED) {
- RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(data);
- if (!handle)
- return;
- ResourceHandleInternal* d = handle->getInternal();
- if (d->m_cancelled)
- return;
- ResourceHandleClient* client = handle->client();
- if (!client)
- return;
+ RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(data);
- fillResponseFromMessage(msg, &d->m_response);
- client->didReceiveResponse(handle.get(), d->m_response);
- }
+ // The content-sniffed callback will handle the response if WebCore
+ // require us to sniff.
+ if(!handle || statusWillBeHandledBySoup(msg->status_code) || handle->shouldContentSniff())
+ return;
+
+ ResourceHandleInternal* d = handle->getInternal();
+ if (d->m_cancelled)
+ return;
+ ResourceHandleClient* client = handle->client();
+ if (!client)
+ return;
+
+ fillResponseFromMessage(msg, &d->m_response);
+ client->didReceiveResponse(handle.get(), d->m_response);
}
+// This callback will not be called if the content sniffer is disabled in startHttp.
static void contentSniffedCallback(SoupMessage* msg, const char* sniffedType, GHashTable *params, gpointer data)
{
if (sniffedType) {
@@ -229,13 +246,7 @@ static void contentSniffedCallback(SoupMessage* msg, const char* sniffedType, GH
soup_message_headers_set_content_type(msg->response_headers, sniffedType, params);
}
- // The 304 status code (SOUP_STATUS_NOT_MODIFIED) needs to be fed
- // into WebCore, as opposed to other kinds of redirections, which
- // are handled by soup directly, so we special-case it here and in
- // gotChunk.
- if (SOUP_STATUS_IS_TRANSPORT_ERROR(msg->status_code)
- || (SOUP_STATUS_IS_REDIRECTION(msg->status_code) && (msg->status_code != SOUP_STATUS_NOT_MODIFIED))
- || (msg->status_code == SOUP_STATUS_UNAUTHORIZED))
+ if (statusWillBeHandledBySoup(msg->status_code))
return;
RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(data);
@@ -254,9 +265,7 @@ static void contentSniffedCallback(SoupMessage* msg, const char* sniffedType, GH
static void gotChunkCallback(SoupMessage* msg, SoupBuffer* chunk, gpointer data)
{
- if (SOUP_STATUS_IS_TRANSPORT_ERROR(msg->status_code)
- || (SOUP_STATUS_IS_REDIRECTION(msg->status_code) && (msg->status_code != SOUP_STATUS_NOT_MODIFIED))
- || (msg->status_code == SOUP_STATUS_UNAUTHORIZED))
+ if (statusWillBeHandledBySoup(msg->status_code))
return;
RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(data);
@@ -276,7 +285,7 @@ static void gotChunkCallback(SoupMessage* msg, SoupBuffer* chunk, gpointer data)
// Doesn't get called for redirects.
static void finishedCallback(SoupSession *session, SoupMessage* msg, gpointer data)
{
- RefPtr<ResourceHandle>handle = adoptRef(static_cast<ResourceHandle*>(data));
+ RefPtr<ResourceHandle> handle = adoptRef(static_cast<ResourceHandle*>(data));
// TODO: maybe we should run this code even if there's no client?
if (!handle)
return;
@@ -410,6 +419,13 @@ static SoupSession* createSoupSession()
return soup_session_async_new();
}
+// Values taken from http://stevesouders.com/ua/index.php following
+// the rule "Do What Every Other Modern Browser Is Doing". They seem
+// to significantly improve page loading time compared to soup's
+// default values.
+#define MAX_CONNECTIONS 60
+#define MAX_CONNECTIONS_PER_HOST 6
+
static void ensureSessionIsInitialized(SoupSession* session)
{
if (g_object_get_data(G_OBJECT(session), "webkit-init"))
@@ -427,27 +443,34 @@ static void ensureSessionIsInitialized(SoupSession* session)
g_object_unref(logger);
}
+ g_object_set(session,
+ SOUP_SESSION_MAX_CONNS, MAX_CONNECTIONS,
+ SOUP_SESSION_MAX_CONNS_PER_HOST, MAX_CONNECTIONS_PER_HOST,
+ NULL);
+
g_object_set_data(G_OBJECT(session), "webkit-init", reinterpret_cast<void*>(0xdeadbeef));
}
-static bool startHttp(ResourceHandle* handle, String urlString)
+static bool startHttp(ResourceHandle* handle)
{
ASSERT(handle);
-
+
SoupSession* session = handle->defaultSession();
ensureSessionIsInitialized(session);
ResourceHandleInternal* d = handle->getInternal();
- d->m_msg = handle->request().toSoupMessage();
- if (!d->m_msg) {
- ResourceError resourceError(g_quark_to_string(SOUP_HTTP_ERROR),
- SOUP_STATUS_MALFORMED,
- urlString,
- handle->request().httpMethod());
- d->client()->didFail(handle, resourceError);
+ ResourceRequest request(handle->request());
+ KURL url(request.url());
+ url.removeFragmentIdentifier();
+ request.setURL(url);
+
+ d->m_msg = request.toSoupMessage();
+ if (!d->m_msg)
return false;
- }
+
+ if(!handle->shouldContentSniff())
+ soup_message_disable_feature(d->m_msg, SOUP_TYPE_CONTENT_SNIFFER);
g_signal_connect(d->m_msg, "restarted", G_CALLBACK(restartedCallback), handle);
g_signal_connect(d->m_msg, "got-headers", G_CALLBACK(gotHeadersCallback), handle);
@@ -491,14 +514,7 @@ static bool startHttp(ResourceHandle* handle, String urlString)
g_free(fileName);
if (error) {
- ResourceError resourceError(g_quark_to_string(SOUP_HTTP_ERROR),
- d->m_msg->status_code,
- urlString,
- String::fromUTF8(error->message));
g_error_free(error);
-
- d->client()->didFail(handle, resourceError);
-
g_signal_handlers_disconnect_matched(d->m_msg, G_SIGNAL_MATCH_DATA,
0, 0, 0, 0, handle);
g_object_unref(d->m_msg);
@@ -562,12 +578,16 @@ bool ResourceHandle::start(Frame* frame)
if (equalIgnoringCase(protocol, "data"))
return startData(this, urlString);
- if (equalIgnoringCase(protocol, "http") || equalIgnoringCase(protocol, "https"))
- return startHttp(this, urlString);
+ if (equalIgnoringCase(protocol, "http") || equalIgnoringCase(protocol, "https")) {
+ if (startHttp(this))
+ return true;
+ }
- if (equalIgnoringCase(protocol, "file") || equalIgnoringCase(protocol, "ftp") || equalIgnoringCase(protocol, "ftps"))
+ if (equalIgnoringCase(protocol, "file") || equalIgnoringCase(protocol, "ftp") || equalIgnoringCase(protocol, "ftps")) {
// FIXME: should we be doing any other protocols here?
- return startGio(this, url);
+ if (startGio(this, url))
+ return true;
+ }
// Error must not be reported immediately
this->scheduleFailure(InvalidURLFailure);
@@ -625,8 +645,10 @@ void ResourceHandle::loadResourceSynchronously(const ResourceRequest& request, S
// GIO-based loader
-static void cleanupGioOperation(ResourceHandleInternal* d)
+static void cleanupGioOperation(ResourceHandle* handle, bool isDestroying = false)
{
+ ResourceHandleInternal* d = handle->getInternal();
+
if (d->m_gfile) {
g_object_set_data(G_OBJECT(d->m_gfile), "webkit-resource", 0);
g_object_unref(d->m_gfile);
@@ -648,11 +670,14 @@ static void cleanupGioOperation(ResourceHandleInternal* d)
g_free(d->m_buffer);
d->m_buffer = 0;
}
+
+ if (!isDestroying)
+ handle->deref();
}
static void closeCallback(GObject* source, GAsyncResult* res, gpointer)
{
- ResourceHandle* handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource"));
+ RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource"));
if (!handle)
return;
@@ -660,13 +685,12 @@ static void closeCallback(GObject* source, GAsyncResult* res, gpointer)
ResourceHandleClient* client = handle->client();
g_input_stream_close_finish(d->m_inputStream, res, 0);
- cleanupGioOperation(d);
- client->didFinishLoading(handle);
+ cleanupGioOperation(handle.get());
+ client->didFinishLoading(handle.get());
}
static void readCallback(GObject* source, GAsyncResult* res, gpointer)
{
- // didReceiveData may cancel the load, which may release the last reference.
RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource"));
if (!handle)
return;
@@ -675,7 +699,7 @@ static void readCallback(GObject* source, GAsyncResult* res, gpointer)
ResourceHandleClient* client = handle->client();
if (d->m_cancelled || !client) {
- cleanupGioOperation(d);
+ cleanupGioOperation(handle.get());
return;
}
@@ -690,7 +714,7 @@ static void readCallback(GObject* source, GAsyncResult* res, gpointer)
error ? String::fromUTF8(error->message) : String());
g_free(uri);
g_error_free(error);
- cleanupGioOperation(d);
+ cleanupGioOperation(handle.get());
client->didFail(handle.get(), resourceError);
return;
}
@@ -704,8 +728,9 @@ static void readCallback(GObject* source, GAsyncResult* res, gpointer)
d->m_total += bytesRead;
client->didReceiveData(handle.get(), d->m_buffer, bytesRead, d->m_total);
+ // didReceiveData may cancel the load, which may release the last reference.
if (d->m_cancelled) {
- cleanupGioOperation(d);
+ cleanupGioOperation(handle.get());
return;
}
@@ -716,7 +741,7 @@ static void readCallback(GObject* source, GAsyncResult* res, gpointer)
static void openCallback(GObject* source, GAsyncResult* res, gpointer)
{
- ResourceHandle* handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource"));
+ RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource"));
if (!handle)
return;
@@ -724,7 +749,7 @@ static void openCallback(GObject* source, GAsyncResult* res, gpointer)
ResourceHandleClient* client = handle->client();
if (d->m_cancelled || !client) {
- cleanupGioOperation(d);
+ cleanupGioOperation(handle.get());
return;
}
@@ -738,8 +763,8 @@ static void openCallback(GObject* source, GAsyncResult* res, gpointer)
error ? String::fromUTF8(error->message) : String());
g_free(uri);
g_error_free(error);
- cleanupGioOperation(d);
- client->didFail(handle, resourceError);
+ cleanupGioOperation(handle.get());
+ client->didFail(handle.get(), resourceError);
return;
}
@@ -747,7 +772,8 @@ static void openCallback(GObject* source, GAsyncResult* res, gpointer)
d->m_bufferSize = 8192;
d->m_buffer = static_cast<char*>(g_malloc(d->m_bufferSize));
d->m_total = 0;
- g_object_set_data(G_OBJECT(d->m_inputStream), "webkit-resource", handle);
+
+ g_object_set_data(G_OBJECT(d->m_inputStream), "webkit-resource", handle.get());
g_input_stream_read_async(d->m_inputStream, d->m_buffer, d->m_bufferSize,
G_PRIORITY_DEFAULT, d->m_cancellable,
readCallback, 0);
@@ -755,7 +781,7 @@ static void openCallback(GObject* source, GAsyncResult* res, gpointer)
static void queryInfoCallback(GObject* source, GAsyncResult* res, gpointer)
{
- ResourceHandle* handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource"));
+ RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource"));
if (!handle)
return;
@@ -763,7 +789,7 @@ static void queryInfoCallback(GObject* source, GAsyncResult* res, gpointer)
ResourceHandleClient* client = handle->client();
if (d->m_cancelled) {
- cleanupGioOperation(d);
+ cleanupGioOperation(handle.get());
return;
}
@@ -790,8 +816,8 @@ static void queryInfoCallback(GObject* source, GAsyncResult* res, gpointer)
error ? String::fromUTF8(error->message) : String());
g_free(uri);
g_error_free(error);
- cleanupGioOperation(d);
- client->didFail(handle, resourceError);
+ cleanupGioOperation(handle.get());
+ client->didFail(handle.get(), resourceError);
return;
}
@@ -804,8 +830,8 @@ static void queryInfoCallback(GObject* source, GAsyncResult* res, gpointer)
uri,
String());
g_free(uri);
- cleanupGioOperation(d);
- client->didFail(handle, resourceError);
+ cleanupGioOperation(handle.get());
+ client->didFail(handle.get(), resourceError);
return;
}
@@ -816,7 +842,12 @@ static void queryInfoCallback(GObject* source, GAsyncResult* res, gpointer)
g_file_info_get_modification_time(info, &tv);
response.setLastModifiedDate(tv.tv_sec);
- client->didReceiveResponse(handle, response);
+ client->didReceiveResponse(handle.get(), response);
+
+ if (d->m_cancelled) {
+ cleanupGioOperation(handle.get());
+ return;
+ }
g_file_read_async(d->m_gfile, G_PRIORITY_DEFAULT, d->m_cancellable,
openCallback, 0);
@@ -827,13 +858,8 @@ static bool startGio(ResourceHandle* handle, KURL url)
ResourceHandleInternal* d = handle->getInternal();
- if (handle->request().httpMethod() != "GET" && handle->request().httpMethod() != "POST") {
- ResourceError error(g_quark_to_string(SOUP_HTTP_ERROR),
- SOUP_STATUS_METHOD_NOT_ALLOWED,
- url.string(), handle->request().httpMethod());
- d->client()->didFail(handle, error);
+ if (handle->request().httpMethod() != "GET" && handle->request().httpMethod() != "POST")
return false;
- }
// GIO doesn't know how to handle refs and queries, so remove them
// TODO: use KURL.fileSystemPath after KURLGtk and FileSystemGtk are
@@ -852,6 +878,10 @@ static bool startGio(ResourceHandle* handle, KURL url)
#endif
d->m_gfile = g_file_new_for_uri(url.string().utf8().data());
g_object_set_data(G_OBJECT(d->m_gfile), "webkit-resource", handle);
+
+ // balanced by a deref() in cleanupGioOperation, which should always run
+ handle->ref();
+
d->m_cancellable = g_cancellable_new();
g_file_query_info_async(d->m_gfile,
G_FILE_ATTRIBUTE_STANDARD_TYPE ","
diff --git a/WebCore/platform/network/soup/ResourceRequest.h b/WebCore/platform/network/soup/ResourceRequest.h
index 82b4eb9..42b7baa 100644
--- a/WebCore/platform/network/soup/ResourceRequest.h
+++ b/WebCore/platform/network/soup/ResourceRequest.h
@@ -36,7 +36,7 @@ namespace WebCore {
struct ResourceRequest : ResourceRequestBase {
ResourceRequest(const String& url)
- : ResourceRequestBase(KURL(url), UseProtocolCachePolicy)
+ : ResourceRequestBase(KURL(ParsedURLString, url), UseProtocolCachePolicy)
{
}
diff --git a/WebCore/platform/network/soup/ResourceRequestSoup.cpp b/WebCore/platform/network/soup/ResourceRequestSoup.cpp
index f2011bb..0d4e0f9 100644
--- a/WebCore/platform/network/soup/ResourceRequestSoup.cpp
+++ b/WebCore/platform/network/soup/ResourceRequestSoup.cpp
@@ -66,11 +66,20 @@ void ResourceRequest::updateFromSoupMessage(SoupMessage* soupMessage)
while (soup_message_headers_iter_next(&headersIter, &headerName, &headerValue))
m_httpHeaderFields.set(String::fromUTF8(headerName), String::fromUTF8(headerValue));
- m_httpBody = FormData::create(soupMessage->request_body->data, soupMessage->request_body->length);
+ if (soupMessage->request_body->data)
+ m_httpBody = FormData::create(soupMessage->request_body->data, soupMessage->request_body->length);
- // FIXME: m_allowHTTPCookies and m_firstPartyForCookies should
+ // FIXME: m_allowCookies and m_firstPartyForCookies should
// probably be handled here and on doUpdatePlatformRequest
// somehow.
}
+unsigned initializeMaximumHTTPConnectionCountPerHost()
+{
+ // Soup has its own queue control; it wants to have all requests
+ // given to it, so that it is able to look ahead, and schedule
+ // them in a good way.
+ return 10000;
+}
+
}
diff --git a/WebCore/platform/network/soup/ResourceResponse.h b/WebCore/platform/network/soup/ResourceResponse.h
index b8cb586..5fa31a0 100644
--- a/WebCore/platform/network/soup/ResourceResponse.h
+++ b/WebCore/platform/network/soup/ResourceResponse.h
@@ -28,6 +28,8 @@
#include "ResourceResponseBase.h"
+#include <libsoup/soup.h>
+
namespace WebCore {
class ResourceResponse : public ResourceResponseBase {
@@ -42,6 +44,8 @@ public:
{
}
+ SoupMessage* toSoupMessage() const;
+
private:
friend class ResourceResponseBase;
diff --git a/WebCore/platform/network/soup/ResourceResponseSoup.cpp b/WebCore/platform/network/soup/ResourceResponseSoup.cpp
new file mode 100644
index 0000000..293577f
--- /dev/null
+++ b/WebCore/platform/network/soup/ResourceResponseSoup.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2009 Gustavo Noronha Silva
+ * Copyright (C) 2009 Collabora Ltd.
+ *
+ * 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; 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 "ResourceResponse.h"
+
+#include "CString.h"
+#include "PlatformString.h"
+
+using namespace std;
+
+namespace WebCore {
+
+SoupMessage* ResourceResponse::toSoupMessage() const
+{
+ // This GET here is just because SoupMessage wants it, we dn't really know.
+ SoupMessage* soupMessage = soup_message_new("GET", url().string().utf8().data());
+ if (!soupMessage)
+ return 0;
+
+ soupMessage->status_code = httpStatusCode();
+
+ HTTPHeaderMap headers = httpHeaderFields();
+ SoupMessageHeaders* soupHeaders = soupMessage->response_headers;
+ if (!headers.isEmpty()) {
+ HTTPHeaderMap::const_iterator end = headers.end();
+ for (HTTPHeaderMap::const_iterator it = headers.begin(); it != end; ++it)
+ soup_message_headers_append(soupHeaders, it->first.string().utf8().data(), it->second.utf8().data());
+ }
+
+ // Body data is not in the message.
+ return soupMessage;
+}
+
+}
diff --git a/WebCore/platform/network/soup/SocketStreamError.h b/WebCore/platform/network/soup/SocketStreamError.h
new file mode 100644
index 0000000..f9641ad
--- /dev/null
+++ b/WebCore/platform/network/soup/SocketStreamError.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SocketStreamError_h
+#define SocketStreamError_h
+
+#include "SocketStreamErrorBase.h"
+
+namespace WebCore {
+
+ class SocketStreamError : public SocketStreamErrorBase {
+ public:
+ SocketStreamError() { }
+ explicit SocketStreamError(int errorCode)
+ : SocketStreamErrorBase(errorCode)
+ {
+ }
+
+ };
+
+} // namespace WebCore
+
+#endif // SocketStreamError_h
diff --git a/WebCore/platform/network/soup/SocketStreamHandle.h b/WebCore/platform/network/soup/SocketStreamHandle.h
new file mode 100644
index 0000000..64139e5
--- /dev/null
+++ b/WebCore/platform/network/soup/SocketStreamHandle.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SocketStreamHandle_h
+#define SocketStreamHandle_h
+
+#include "SocketStreamHandleBase.h"
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+ class AuthenticationChallenge;
+ class Credential;
+ class SocketStreamHandleClient;
+
+ class SocketStreamHandle : public RefCounted<SocketStreamHandle>, public SocketStreamHandleBase {
+ public:
+ static PassRefPtr<SocketStreamHandle> create(const KURL& url, SocketStreamHandleClient* client) { return adoptRef(new SocketStreamHandle(url, client)); }
+
+ virtual ~SocketStreamHandle();
+
+ protected:
+ virtual int platformSend(const char* data, int length);
+ virtual void platformClose();
+
+ private:
+ SocketStreamHandle(const KURL&, SocketStreamHandleClient*);
+
+ // No authentication for streams per se, but proxy may ask for credentials.
+ void didReceiveAuthenticationChallenge(const AuthenticationChallenge&);
+ void receivedCredential(const AuthenticationChallenge&, const Credential&);
+ void receivedRequestToContinueWithoutCredential(const AuthenticationChallenge&);
+ void receivedCancellation(const AuthenticationChallenge&);
+ };
+
+} // namespace WebCore
+
+#endif // SocketStreamHandle_h
diff --git a/WebCore/platform/network/soup/SocketStreamHandleSoup.cpp b/WebCore/platform/network/soup/SocketStreamHandleSoup.cpp
new file mode 100644
index 0000000..6aa33fc
--- /dev/null
+++ b/WebCore/platform/network/soup/SocketStreamHandleSoup.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "SocketStreamHandle.h"
+
+#include "KURL.h"
+#include "Logging.h"
+#include "NotImplemented.h"
+#include "SocketStreamHandleClient.h"
+
+namespace WebCore {
+
+SocketStreamHandle::SocketStreamHandle(const KURL& url, SocketStreamHandleClient* client)
+ : SocketStreamHandleBase(url, client)
+{
+ LOG(Network, "SocketStreamHandle %p new client %p", this, m_client);
+ notImplemented();
+}
+
+SocketStreamHandle::~SocketStreamHandle()
+{
+ LOG(Network, "SocketStreamHandle %p delete", this);
+ setClient(0);
+ notImplemented();
+}
+
+int SocketStreamHandle::platformSend(const char*, int)
+{
+ LOG(Network, "SocketStreamHandle %p platformSend", this);
+ notImplemented();
+ return 0;
+}
+
+void SocketStreamHandle::platformClose()
+{
+ LOG(Network, "SocketStreamHandle %p platformClose", this);
+ notImplemented();
+}
+
+void SocketStreamHandle::didReceiveAuthenticationChallenge(const AuthenticationChallenge&)
+{
+ notImplemented();
+}
+
+void SocketStreamHandle::receivedCredential(const AuthenticationChallenge&, const Credential&)
+{
+ notImplemented();
+}
+
+void SocketStreamHandle::receivedRequestToContinueWithoutCredential(const AuthenticationChallenge&)
+{
+ notImplemented();
+}
+
+void SocketStreamHandle::receivedCancellation(const AuthenticationChallenge&)
+{
+ notImplemented();
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/network/win/CookieJarCFNetWin.cpp b/WebCore/platform/network/win/CookieJarCFNetWin.cpp
index af9e3f3..33b795a 100644
--- a/WebCore/platform/network/win/CookieJarCFNetWin.cpp
+++ b/WebCore/platform/network/win/CookieJarCFNetWin.cpp
@@ -26,6 +26,7 @@
#include "config.h"
#include "CookieJar.h"
+#include "Cookie.h"
#include "CookieStorageWin.h"
#include "Document.h"
#include "KURL.h"
@@ -113,4 +114,60 @@ bool cookiesEnabled(const Document* /*document*/)
return policy == CFHTTPCookieStorageAcceptPolicyOnlyFromMainDocumentDomain || policy == CFHTTPCookieStorageAcceptPolicyAlways;
}
+bool getRawCookies(const Document*, const KURL& url, Vector<Cookie>& rawCookies)
+{
+ rawCookies.clear();
+ CFHTTPCookieStorageRef cookieStorage = currentCookieStorage();
+ if (!cookieStorage)
+ return false;
+
+ RetainPtr<CFURLRef> urlCF(AdoptCF, url.createCFURL());
+
+ bool sendSecureCookies = url.protocolIs("https");
+ RetainPtr<CFArrayRef> cookiesCF(AdoptCF, CFHTTPCookieStorageCopyCookiesForURL(cookieStorage, urlCF.get(), sendSecureCookies));
+
+ CFIndex count = CFArrayGetCount(cookiesCF.get());
+ rawCookies.reserveCapacity(count);
+
+ for (CFIndex i = 0; i < count; i++) {
+ CFHTTPCookieRef cookie = (CFHTTPCookieRef)CFArrayGetValueAtIndex(cookiesCF.get(), i);
+ String name = CFHTTPCookieGetName(cookie);
+ String value = CFHTTPCookieGetValue(cookie);
+ String domain = CFHTTPCookieGetDomain(cookie);
+ String path = CFHTTPCookieGetPath(cookie);
+
+ double expires = (CFDateGetAbsoluteTime(CFHTTPCookieGetExpiratonDate(cookie)) + kCFAbsoluteTimeIntervalSince1970) * 1000;
+
+ bool httpOnly = CFHTTPCookieIsHTTPOnly(cookie);
+ bool secure = CFHTTPCookieIsSecure(cookie);
+ bool session = false; // FIXME: Need API for if a cookie is a session cookie.
+
+ rawCookies.uncheckedAppend(Cookie(name, value, domain, path, expires, httpOnly, secure, session));
+ }
+
+ return true;
+}
+
+void deleteCookie(const Document*, const KURL& url, const String& name)
+{
+ CFHTTPCookieStorageRef cookieStorage = currentCookieStorage();
+ if (!cookieStorage)
+ return;
+
+ RetainPtr<CFURLRef> urlCF(AdoptCF, url.createCFURL());
+
+ bool sendSecureCookies = url.protocolIs("https");
+ RetainPtr<CFArrayRef> cookiesCF(AdoptCF, CFHTTPCookieStorageCopyCookiesForURL(cookieStorage, urlCF.get(), sendSecureCookies));
+
+ CFIndex count = CFArrayGetCount(cookiesCF.get());
+ for (CFIndex i = 0; i < count; i++) {
+ CFHTTPCookieRef cookie = (CFHTTPCookieRef)CFArrayGetValueAtIndex(cookiesCF.get(), i);
+ String cookieName = CFHTTPCookieGetName(cookie);
+ if (cookieName == name) {
+ CFHTTPCookieStorageDeleteCookie(cookieStorage, cookie);
+ break;
+ }
+ }
+}
+
}
diff --git a/WebCore/platform/network/win/CookieJarWin.cpp b/WebCore/platform/network/win/CookieJarWin.cpp
index 41d12d9..6576e07 100644
--- a/WebCore/platform/network/win/CookieJarWin.cpp
+++ b/WebCore/platform/network/win/CookieJarWin.cpp
@@ -26,6 +26,7 @@
#include "config.h"
#include "CookieJar.h"
+#include "Cookie.h"
#include "KURL.h"
#include "PlatformString.h"
#include "Document.h"
@@ -35,7 +36,6 @@
namespace WebCore {
-
void setCookies(Document* /*document*/, const KURL& url, const String& value)
{
// FIXME: Deal with document->firstPartyForCookies().
@@ -64,4 +64,16 @@ bool cookiesEnabled(const Document* /*document*/)
return true;
}
+bool getRawCookies(const Document*, const KURL&, Vector<Cookie>& rawCookies)
+{
+ // FIXME: Not yet implemented
+ rawCookies.clear();
+ return false; // return true when implemented
+}
+
+void deleteCookie(const Document*, const KURL&, const String&)
+{
+ // FIXME: Not yet implemented
+}
+
}
diff --git a/WebCore/platform/qt/ClipboardQt.cpp b/WebCore/platform/qt/ClipboardQt.cpp
index 666ad18..9d2c452 100644
--- a/WebCore/platform/qt/ClipboardQt.cpp
+++ b/WebCore/platform/qt/ClipboardQt.cpp
@@ -239,8 +239,6 @@ static CachedImage* getCachedImage(Element* element)
void ClipboardQt::declareAndWriteDragImage(Element* element, const KURL& url, const String& title, Frame* frame)
{
ASSERT(frame);
- Q_UNUSED(url);
- Q_UNUSED(title);
//WebCore::writeURL(m_writableDataObject.get(), url, title, true, false);
if (!m_writableData)
@@ -262,8 +260,10 @@ void ClipboardQt::declareAndWriteDragImage(Element* element, const KURL& url, co
return;
QList<QUrl> urls;
+ urls.append(url);
urls.append(fullURL);
+ m_writableData->setText(title);
m_writableData->setUrls(urls);
#ifndef QT_NO_CLIPBOARD
if (!isForDragging())
diff --git a/WebCore/platform/qt/ContextMenuQt.cpp b/WebCore/platform/qt/ContextMenuQt.cpp
index 063a46b..9b1a054 100644
--- a/WebCore/platform/qt/ContextMenuQt.cpp
+++ b/WebCore/platform/qt/ContextMenuQt.cpp
@@ -61,7 +61,7 @@ void ContextMenu::insertItem(unsigned position, ContextMenuItem& item)
m_items.insert(position, item);
}
-void ContextMenu::setPlatformDescription(PlatformMenuDescription menu)
+void ContextMenu::setPlatformDescription(PlatformMenuDescription)
{
// doesn't make sense
}
diff --git a/WebCore/platform/qt/CookieJarQt.cpp b/WebCore/platform/qt/CookieJarQt.cpp
index 40d9309..a27a06e 100644
--- a/WebCore/platform/qt/CookieJarQt.cpp
+++ b/WebCore/platform/qt/CookieJarQt.cpp
@@ -28,6 +28,7 @@
#include "config.h"
#include "CookieJar.h"
+#include "Cookie.h"
#include "Document.h"
#include "KURL.h"
#include "PlatformString.h"
@@ -47,6 +48,8 @@ namespace WebCore {
#if QT_VERSION >= 0x040400
static QNetworkCookieJar *cookieJar(const Document *document)
{
+ if (!document)
+ return 0;
Frame *frame = document->frame();
if (!frame)
return 0;
@@ -128,6 +131,18 @@ bool cookiesEnabled(const Document* document)
#endif
}
+bool getRawCookies(const Document*, const KURL&, Vector<Cookie>& rawCookies)
+{
+ // FIXME: Not yet implemented
+ rawCookies.clear();
+ return false; // return true when implemented
+}
+
+void deleteCookie(const Document*, const KURL&, const String&)
+{
+ // FIXME: Not yet implemented
+}
+
}
// vim: ts=4 sw=4 et
diff --git a/WebCore/platform/qt/DragDataQt.cpp b/WebCore/platform/qt/DragDataQt.cpp
index 7b1eff8..b0611e6 100644
--- a/WebCore/platform/qt/DragDataQt.cpp
+++ b/WebCore/platform/qt/DragDataQt.cpp
@@ -119,7 +119,7 @@ bool DragData::containsURL() const
return m_platformDragData->hasUrls();
}
-String DragData::asURL(String* title) const
+String DragData::asURL(String*) const
{
if (!m_platformDragData)
return String();
@@ -128,7 +128,7 @@ String DragData::asURL(String* title) const
if (urls.isEmpty())
return String();
- return urls.first().toString();
+ return encodeWithURLEscapeSequences(urls.first().toString());
}
PassRefPtr<DocumentFragment> DragData::asFragment(Document* doc) const
diff --git a/WebCore/platform/qt/FileSystemQt.cpp b/WebCore/platform/qt/FileSystemQt.cpp
index 28d3ca7..4093fad 100644
--- a/WebCore/platform/qt/FileSystemQt.cpp
+++ b/WebCore/platform/qt/FileSystemQt.cpp
@@ -81,7 +81,7 @@ bool makeAllDirectories(const String& path)
String pathByAppendingComponent(const String& path, const String& component)
{
- return QDir(path).filePath(component);
+ return QDir::toNativeSeparators(QDir(path).filePath(component));
}
String homeDirectoryPath()
@@ -117,7 +117,9 @@ Vector<String> listDirectory(const String& path, const String& filter)
CString openTemporaryFile(const char* prefix, PlatformFileHandle& handle)
{
- QFile *temp = new QTemporaryFile(QLatin1String(prefix));
+ QTemporaryFile* tempFile = new QTemporaryFile(QLatin1String(prefix));
+ tempFile->setAutoRemove(false);
+ QFile* temp = tempFile;
if (temp->open(QIODevice::ReadWrite)) {
handle = temp;
return String(temp->fileName()).utf8();
diff --git a/WebCore/platform/qt/Localizations.cpp b/WebCore/platform/qt/Localizations.cpp
index d1853fc..77cac57 100644
--- a/WebCore/platform/qt/Localizations.cpp
+++ b/WebCore/platform/qt/Localizations.cpp
@@ -362,5 +362,111 @@ String mediaElementLiveBroadcastStateText()
return QCoreApplication::translate("QWebPage", "Live Broadcast", "Media controller status message when watching a live broadcast");
}
+#if ENABLE(VIDEO)
+
+String localizedMediaControlElementString(const String& name)
+{
+ if (name == "AudioElement")
+ return QCoreApplication::translate("QWebPage", "Audio Element", "Media controller element");
+ if (name == "VideoElement")
+ return QCoreApplication::translate("QWebPage", "Video Element", "Media controller element");
+ if (name == "MuteButton")
+ return QCoreApplication::translate("QWebPage", "Mute Button", "Media controller element");
+ if (name == "UnMuteButton")
+ return QCoreApplication::translate("QWebPage", "Unmute Button", "Media controller element");
+ if (name == "PlayButton")
+ return QCoreApplication::translate("QWebPage", "Play Button", "Media controller element");
+ if (name == "PauseButton")
+ return QCoreApplication::translate("QWebPage", "Pause Button", "Media controller element");
+ if (name == "Slider")
+ return QCoreApplication::translate("QWebPage", "Slider", "Media controller element");
+ if (name == "SliderThumb")
+ return QCoreApplication::translate("QWebPage", "Slider Thumb", "Media controller element");
+ if (name == "RewindButton")
+ return QCoreApplication::translate("QWebPage", "Rewind Button", "Media controller element");
+ if (name == "ReturnToRealtimeButton")
+ return QCoreApplication::translate("QWebPage", "Return to Real-time Button", "Media controller element");
+ if (name == "CurrentTimeDisplay")
+ return QCoreApplication::translate("QWebPage", "Elapsed Time", "Media controller element");
+ if (name == "TimeRemainingDisplay")
+ return QCoreApplication::translate("QWebPage", "Remaining Time", "Media controller element");
+ if (name == "StatusDisplay")
+ return QCoreApplication::translate("QWebPage", "Status Display", "Media controller element");
+ if (name == "FullscreenButton")
+ return QCoreApplication::translate("QWebPage", "Fullscreen Button", "Media controller element");
+ if (name == "SeekForwardButton")
+ return QCoreApplication::translate("QWebPage", "Seek Forward Button", "Media controller element");
+ if (name == "SeekBackButton")
+ return QCoreApplication::translate("QWebPage", "Seek Back Button", "Media controller element");
+
+ return String();
+}
+
+String localizedMediaControlElementHelpText(const String& name)
+{
+ if (name == "AudioElement")
+ return QCoreApplication::translate("QWebPage", "Audio element playback controls and status display", "Media controller element");
+ if (name == "VideoElement")
+ return QCoreApplication::translate("QWebPage", "Video element playback controls and status display", "Media controller element");
+ if (name == "MuteButton")
+ return QCoreApplication::translate("QWebPage", "Mute audio tracks", "Media controller element");
+ if (name == "UnMuteButton")
+ return QCoreApplication::translate("QWebPage", "Unmute audio tracks", "Media controller element");
+ if (name == "PlayButton")
+ return QCoreApplication::translate("QWebPage", "Begin playback", "Media controller element");
+ if (name == "PauseButton")
+ return QCoreApplication::translate("QWebPage", "Pause playback", "Media controller element");
+ if (name == "Slider")
+ return QCoreApplication::translate("QWebPage", "Movie time scrubber", "Media controller element");
+ if (name == "SliderThumb")
+ return QCoreApplication::translate("QWebPage", "Movie time scrubber thumb", "Media controller element");
+ if (name == "RewindButton")
+ return QCoreApplication::translate("QWebPage", "Rewind movie", "Media controller element");
+ if (name == "ReturnToRealtimeButton")
+ return QCoreApplication::translate("QWebPage", "Return streaming movie to real-time", "Media controller element");
+ if (name == "CurrentTimeDisplay")
+ return QCoreApplication::translate("QWebPage", "Current movie time", "Media controller element");
+ if (name == "TimeRemainingDisplay")
+ return QCoreApplication::translate("QWebPage", "Remaining movie time", "Media controller element");
+ if (name == "StatusDisplay")
+ return QCoreApplication::translate("QWebPage", "Current movie status", "Media controller element");
+ if (name == "FullscreenButton")
+ return QCoreApplication::translate("QWebPage", "Play movie in full-screen mode", "Media controller element");
+ if (name == "SeekForwardButton")
+ return QCoreApplication::translate("QWebPage", "Seek quickly back", "Media controller element");
+ if (name == "SeekBackButton")
+ return QCoreApplication::translate("QWebPage", "Seek quickly forward", "Media controller element");
+
+ ASSERT_NOT_REACHED();
+ return String();
+}
+
+String localizedMediaTimeDescription(float time)
+{
+ if (!isfinite(time))
+ return QCoreApplication::translate("QWebPage", "Indefinite time", "Media time description");
+
+ int seconds = (int)fabsf(time);
+ int days = seconds / (60 * 60 * 24);
+ int hours = seconds / (60 * 60);
+ int minutes = (seconds / 60) % 60;
+ seconds %= 60;
+
+ if (days) {
+ return QCoreApplication::translate("QWebPage", "%1 days %2 hours %3 minutes %4 seconds", "Media time description").arg(days).arg(hours).arg(minutes).arg(seconds);
+ }
+
+ if (hours) {
+ return QCoreApplication::translate("QWebPage", "%1 hours %2 minutes %3 seconds", "Media time description").arg(hours).arg(minutes).arg(seconds);
+ }
+
+ if (minutes) {
+ return QCoreApplication::translate("QWebPage", "%1 minutes %2 seconds", "Media time description").arg(minutes).arg(seconds);
+ }
+
+ return QCoreApplication::translate("QWebPage", "%1 seconds", "Media time description").arg(seconds);
+}
+#endif // ENABLE(VIDEO)
+
}
// vim: ts=4 sw=4 et
diff --git a/WebCore/platform/qt/PasteboardQt.cpp b/WebCore/platform/qt/PasteboardQt.cpp
index 969de62..209a573 100644
--- a/WebCore/platform/qt/PasteboardQt.cpp
+++ b/WebCore/platform/qt/PasteboardQt.cpp
@@ -119,6 +119,18 @@ PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefP
return 0;
}
+void Pasteboard::writePlainText(const String& text)
+{
+#ifndef QT_NO_CLIPBOARD
+ QMimeData* md = new QMimeData;
+ QString qtext = text;
+ qtext.replace(QChar(0xa0), QLatin1Char(' '));
+ md->setText(qtext);
+ QApplication::clipboard()->setMimeData(md, m_selectionMode ?
+ QClipboard::Selection : QClipboard::Clipboard);
+#endif
+}
+
void Pasteboard::writeURL(const KURL& _url, const String&, Frame*)
{
ASSERT(!_url.isEmpty());
diff --git a/WebCore/platform/qt/PlatformKeyboardEventQt.cpp b/WebCore/platform/qt/PlatformKeyboardEventQt.cpp
index 935882a..37ea681 100644
--- a/WebCore/platform/qt/PlatformKeyboardEventQt.cpp
+++ b/WebCore/platform/qt/PlatformKeyboardEventQt.cpp
@@ -217,7 +217,7 @@ static int windowsKeyCodeForKeyEvent(unsigned int keycode, bool isKeypad = false
case Qt::Key_F9:
return VK_F9;
case Qt::Key_F10:
- return VK_F11;
+ return VK_F10;
case Qt::Key_F11:
return VK_F11;
case Qt::Key_F12:
diff --git a/WebCore/platform/qt/PlatformMouseEventQt.cpp b/WebCore/platform/qt/PlatformMouseEventQt.cpp
index 6c1d82d..e486e68 100644
--- a/WebCore/platform/qt/PlatformMouseEventQt.cpp
+++ b/WebCore/platform/qt/PlatformMouseEventQt.cpp
@@ -31,9 +31,46 @@
#include <wtf/CurrentTime.h>
#include <QMouseEvent>
+#include <QGraphicsSceneMouseEvent>
namespace WebCore {
+PlatformMouseEvent::PlatformMouseEvent(QGraphicsSceneMouseEvent* event, int clickCount)
+{
+ m_timestamp = WTF::currentTime();
+
+ switch (event->type()) {
+ case QEvent::GraphicsSceneMouseDoubleClick:
+ case QEvent::GraphicsSceneMousePress:
+ m_eventType = MouseEventPressed;
+ break;
+ case QEvent::GraphicsSceneMouseRelease:
+ m_eventType = MouseEventReleased;
+ break;
+ case QEvent::GraphicsSceneMouseMove:
+ default:
+ m_eventType = MouseEventMoved;
+ }
+
+ m_position = IntPoint(event->pos().toPoint());
+ m_globalPosition = IntPoint(event->screenPos());
+
+ if (event->button() == Qt::LeftButton || (event->buttons() & Qt::LeftButton))
+ m_button = LeftButton;
+ else if (event->button() == Qt::RightButton || (event->buttons() & Qt::RightButton))
+ m_button = RightButton;
+ else if (event->button() == Qt::MidButton || (event->buttons() & Qt::MidButton))
+ m_button = MiddleButton;
+ else
+ m_button = NoButton;
+
+ m_clickCount = clickCount;
+ m_shiftKey = (event->modifiers() & Qt::ShiftModifier) != 0;
+ m_ctrlKey = (event->modifiers() & Qt::ControlModifier) != 0;
+ m_altKey = (event->modifiers() & Qt::AltModifier) != 0;
+ m_metaKey = (event->modifiers() & Qt::MetaModifier) != 0;
+}
+
PlatformMouseEvent::PlatformMouseEvent(QInputEvent* event, int clickCount)
{
m_timestamp = WTF::currentTime();
diff --git a/WebCore/platform/qt/PlatformScreenQt.cpp b/WebCore/platform/qt/PlatformScreenQt.cpp
index 5dc0963..7ba8350 100644
--- a/WebCore/platform/qt/PlatformScreenQt.cpp
+++ b/WebCore/platform/qt/PlatformScreenQt.cpp
@@ -36,42 +36,54 @@
#include "FrameView.h"
#include "HostWindow.h"
#include "Widget.h"
+#include "QWebPageClient.h"
#include <QApplication>
#include <QDesktopWidget>
namespace WebCore {
+static int screenNumber(Widget* w)
+{
+ if (!w)
+ return 0;
+
+ QWebPageClient* client = w->root()->hostWindow()->platformPageClient();
+ return client ? client->screenNumber() : 0;
+}
+
int screenDepth(Widget* w)
{
- QDesktopWidget* d = QApplication::desktop();
- QWidget *view = w ? w->root()->hostWindow()->platformWindow() : 0;
- int screenNumber = view ? d->screenNumber(view) : 0;
- return d->screen(screenNumber)->depth();
+ return QApplication::desktop()->screen(screenNumber(w))->depth();
}
int screenDepthPerComponent(Widget* w)
{
- QWidget *view = w ? w->root()->hostWindow()->platformWindow() : 0;
- return view ? view->depth() : QApplication::desktop()->screen(0)->depth();
+ if (w) {
+ QWebPageClient* client = w->root()->hostWindow()->platformPageClient();
+
+ if (client) {
+ QWidget* view = QWidget::find(client->winId());
+ if (view)
+ return view->depth();
+ }
+ }
+ return QApplication::desktop()->screen(0)->depth();
}
bool screenIsMonochrome(Widget* w)
{
- QDesktopWidget* d = QApplication::desktop();
- QWidget *view = w ? w->root()->hostWindow()->platformWindow(): 0;
- int screenNumber = view ? d->screenNumber(view) : 0;
- return d->screen(screenNumber)->numColors() < 2;
+ return QApplication::desktop()->screen(screenNumber(w))->numColors() < 2;
}
FloatRect screenRect(Widget* w)
{
- QRect r = QApplication::desktop()->screenGeometry(w ? w->root()->hostWindow()->platformWindow(): 0);
+ QRect r = QApplication::desktop()->screenGeometry(screenNumber(w));
return FloatRect(r.x(), r.y(), r.width(), r.height());
}
FloatRect screenAvailableRect(Widget* w)
{
- QRect r = QApplication::desktop()->availableGeometry(w ? w->root()->hostWindow()->platformWindow(): 0);
+ QRect r = QApplication::desktop()->availableGeometry(screenNumber(w));
return FloatRect(r.x(), r.y(), r.width(), r.height());
}
diff --git a/WebCore/platform/qt/PopupMenuQt.cpp b/WebCore/platform/qt/PopupMenuQt.cpp
index 11dfe41..b44f2ec 100644
--- a/WebCore/platform/qt/PopupMenuQt.cpp
+++ b/WebCore/platform/qt/PopupMenuQt.cpp
@@ -30,6 +30,7 @@
#include "FrameView.h"
#include "HostWindow.h"
#include "PopupMenuClient.h"
+#include "QWebPageClient.h"
#include "QWebPopup.h"
#include <QAction>
@@ -59,7 +60,7 @@ void PopupMenu::clear()
m_popup->clear();
}
-void PopupMenu::populate(const IntRect& r)
+void PopupMenu::populate(const IntRect&)
{
clear();
Q_ASSERT(client());
@@ -85,13 +86,13 @@ void PopupMenu::populate(const IntRect& r)
void PopupMenu::show(const IntRect& r, FrameView* v, int index)
{
- QWidget* window = v->hostWindow()->platformWindow();
+ QWebPageClient* client = v->hostWindow()->platformPageClient();
populate(r);
QRect rect = r;
rect.moveTopLeft(v->contentsToWindow(r.topLeft()));
rect.setHeight(m_popup->sizeHint().height());
- m_popup->setParent(window);
+ m_popup->setParent(QWidget::find(client->winId()));
m_popup->setGeometry(rect);
m_popup->setCurrentIndex(index);
m_popup->exec();
diff --git a/WebCore/platform/qt/QWebPageClient.h b/WebCore/platform/qt/QWebPageClient.h
new file mode 100644
index 0000000..09f7886
--- /dev/null
+++ b/WebCore/platform/qt/QWebPageClient.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * 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 QWebPageClient_h
+#define QWebPageClient_h
+
+#include <QRect>
+
+class QWebPageClient {
+public:
+ virtual void scroll(int dx, int dy, const QRect&) = 0;
+ virtual void update(const QRect&) = 0;
+
+ inline void resetCursor()
+ {
+#ifndef QT_NO_CURSOR
+ if (!cursor().bitmap() && cursor().shape() == m_lastCursor.shape())
+ return;
+ updateCursor(m_lastCursor);
+#endif
+ }
+
+ inline void setCursor(const QCursor& cursor)
+ {
+#ifndef QT_NO_CURSOR
+ m_lastCursor = cursor;
+ if (!cursor.bitmap() && cursor.shape() == this->cursor().shape())
+ return;
+ updateCursor(cursor);
+#endif
+ }
+
+ virtual int screenNumber() const = 0;
+ virtual WId winId() const = 0;
+
+ virtual QObject* pluginParent() const = 0;
+
+protected:
+#ifndef QT_NO_CURSOR
+ virtual QCursor cursor() const = 0;
+ virtual void updateCursor(const QCursor& cursor) = 0;
+#endif
+
+private:
+#ifndef QT_NO_CURSOR
+ QCursor m_lastCursor;
+#endif
+};
+
+#endif
diff --git a/WebCore/platform/qt/QWebPopup.cpp b/WebCore/platform/qt/QWebPopup.cpp
index f437c27..d077079 100644
--- a/WebCore/platform/qt/QWebPopup.cpp
+++ b/WebCore/platform/qt/QWebPopup.cpp
@@ -71,7 +71,7 @@ void QWebPopup::hidePopup()
return;
m_popupVisible = false;
- m_client->hidePopup();
+ m_client->popupDidHide();
}
void QWebPopup::activeChanged(int index)
diff --git a/WebCore/platform/qt/RenderThemeQt.cpp b/WebCore/platform/qt/RenderThemeQt.cpp
index 3fe67b2..b61d356 100644
--- a/WebCore/platform/qt/RenderThemeQt.cpp
+++ b/WebCore/platform/qt/RenderThemeQt.cpp
@@ -44,6 +44,7 @@
#include "Page.h"
#include "RenderBox.h"
#include "RenderTheme.h"
+#include "UserAgentStyleSheets.h"
#include "qwebpage.h"
#include <QApplication>
@@ -172,7 +173,7 @@ bool RenderThemeQt::supportsHover(const RenderStyle*) const
return true;
}
-bool RenderThemeQt::supportsFocusRing(const RenderStyle* style) const
+bool RenderThemeQt::supportsFocusRing(const RenderStyle*) const
{
return true; // Qt provides this through the style
}
@@ -274,7 +275,7 @@ Color RenderThemeQt::platformInactiveSelectionForegroundColor() const
return pal.brush(QPalette::Inactive, QPalette::HighlightedText).color();
}
-void RenderThemeQt::systemFont(int propId, FontDescription& fontDescription) const
+void RenderThemeQt::systemFont(int, FontDescription&) const
{
// no-op
}
@@ -387,7 +388,7 @@ bool RenderThemeQt::paintRadio(RenderObject* o, const RenderObject::PaintInfo& i
return paintButton(o, i, r);
}
-void RenderThemeQt::adjustButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
+void RenderThemeQt::adjustButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element*) const
{
// Ditch the border.
style->resetBorder();
@@ -572,7 +573,7 @@ bool RenderThemeQt::paintMenuList(RenderObject* o, const RenderObject::PaintInfo
QStyleOptionComboBox opt;
if (p.widget)
opt.initFrom(p.widget);
- ControlPart appearance = applyTheme(opt, o);
+ applyTheme(opt, o);
const QPoint topLeft = r.topLeft();
p.painter->translate(topLeft);
@@ -584,8 +585,7 @@ bool RenderThemeQt::paintMenuList(RenderObject* o, const RenderObject::PaintInfo
return false;
}
-void RenderThemeQt::adjustMenuListButtonStyle(CSSStyleSelector* selector, RenderStyle* style,
- Element* e) const
+void RenderThemeQt::adjustMenuListButtonStyle(CSSStyleSelector*, RenderStyle* style, Element*) const
{
// WORKAROUND because html.css specifies -webkit-border-radius for <select> so we override it here
// see also http://bugs.webkit.org/show_bug.cgi?id=18399
@@ -772,13 +772,7 @@ ControlPart RenderThemeQt::applyTheme(QStyleOption& option, RenderObject* o) con
String RenderThemeQt::extraMediaControlsStyleSheet()
{
- QFile platformStyleSheet(QLatin1String(":/webcore/css/mediaControls-extras.css"));
- if (platformStyleSheet.open(QFile::ReadOnly)) {
- QByteArray sheetData = platformStyleSheet.readAll();
- return QString::fromUtf8(sheetData.constData(), sheetData.length());
- }
-
- return String();
+ return String(mediaControlsQtUserAgentStyleSheet, sizeof(mediaControlsQtUserAgentStyleSheet));
}
// Helper class to transform the painter's world matrix to the object's content area, scaled to 0,0,100,100
@@ -887,13 +881,13 @@ bool RenderThemeQt::paintMediaPlayButton(RenderObject* o, const RenderObject::Pa
return false;
}
-bool RenderThemeQt::paintMediaSeekBackButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
+bool RenderThemeQt::paintMediaSeekBackButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&)
{
// We don't want to paint this at the moment.
return false;
}
-bool RenderThemeQt::paintMediaSeekForwardButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
+bool RenderThemeQt::paintMediaSeekForwardButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&)
{
// We don't want to paint this at the moment.
return false;
diff --git a/WebCore/platform/qt/ScrollViewQt.cpp b/WebCore/platform/qt/ScrollViewQt.cpp
index 48885d3..ccbd751 100644
--- a/WebCore/platform/qt/ScrollViewQt.cpp
+++ b/WebCore/platform/qt/ScrollViewQt.cpp
@@ -53,7 +53,7 @@ void ScrollView::adjustWidgetsPreventingBlittingCount(int delta)
parent()->adjustWidgetsPreventingBlittingCount(delta);
}
-void ScrollView::platformAddChild(Widget* child)
+void ScrollView::platformAddChild(Widget*)
{
adjustWidgetsPreventingBlittingCount(1);
}
diff --git a/WebCore/platform/qt/SearchPopupMenuQt.cpp b/WebCore/platform/qt/SearchPopupMenuQt.cpp
index 7822b2c..187a5de 100644
--- a/WebCore/platform/qt/SearchPopupMenuQt.cpp
+++ b/WebCore/platform/qt/SearchPopupMenuQt.cpp
@@ -29,11 +29,11 @@ SearchPopupMenu::SearchPopupMenu(PopupMenuClient* client)
{
}
-void SearchPopupMenu::saveRecentSearches(const AtomicString& name, const Vector<String>& searchItems)
+void SearchPopupMenu::saveRecentSearches(const AtomicString&, const Vector<String>&)
{
}
-void SearchPopupMenu::loadRecentSearches(const AtomicString& name, Vector<String>& searchItems)
+void SearchPopupMenu::loadRecentSearches(const AtomicString&, Vector<String>&)
{
}
diff --git a/WebCore/platform/qt/TemporaryLinkStubs.cpp b/WebCore/platform/qt/TemporaryLinkStubs.cpp
index 8ef598f..814f961 100644
--- a/WebCore/platform/qt/TemporaryLinkStubs.cpp
+++ b/WebCore/platform/qt/TemporaryLinkStubs.cpp
@@ -100,7 +100,7 @@ void getSupportedKeySizes(Vector<String>&)
notImplemented();
}
-String signedPublicKeyAndChallengeString(unsigned keySizeIndex, const String &challengeString, const KURL &url)
+String signedPublicKeyAndChallengeString(unsigned, const String&, const KURL&)
{
return String();
}
@@ -114,11 +114,6 @@ float userIdleTime()
}
#endif
-void prefetchDNS(const String& hostname)
-{
- notImplemented();
-}
-
}
// vim: ts=4 sw=4 et
diff --git a/WebCore/platform/qt/WheelEventQt.cpp b/WebCore/platform/qt/WheelEventQt.cpp
index 9534f20..66118e1 100644
--- a/WebCore/platform/qt/WheelEventQt.cpp
+++ b/WebCore/platform/qt/WheelEventQt.cpp
@@ -25,9 +25,48 @@
#include <qapplication.h>
#include <QWheelEvent>
+#include <QGraphicsSceneWheelEvent>
namespace WebCore {
+void PlatformWheelEvent::applyDelta(int delta, Qt::Orientation orientation)
+{
+ if (orientation == Qt::Horizontal) {
+ m_deltaX = (delta / 120);
+ m_deltaY = 0;
+ } else {
+ m_deltaX = 0;
+ m_deltaY = (delta / 120);
+ }
+
+ m_wheelTicksX = m_deltaX;
+ m_wheelTicksY = m_deltaY;
+
+ // Use the same single scroll step as QTextEdit
+ // (in QTextEditPrivate::init [h,v]bar->setSingleStep)
+ static const float cDefaultQtScrollStep = 20.f;
+ m_deltaX *= QApplication::wheelScrollLines() * cDefaultQtScrollStep;
+ m_deltaY *= QApplication::wheelScrollLines() * cDefaultQtScrollStep;
+}
+
+PlatformWheelEvent::PlatformWheelEvent(QGraphicsSceneWheelEvent* e)
+#ifdef QT_NO_WHEELEVENT
+{
+ Q_UNUSED(e);
+}
+#else
+ : m_position(e->pos().toPoint())
+ , m_globalPosition(e->screenPos())
+ , m_granularity(ScrollByPixelWheelEvent)
+ , m_isAccepted(false)
+ , m_shiftKey(e->modifiers() & Qt::ShiftModifier)
+ , m_ctrlKey(e->modifiers() & Qt::ControlModifier)
+ , m_altKey(e->modifiers() & Qt::AltModifier)
+ , m_metaKey(e->modifiers() & Qt::MetaModifier)
+{
+ applyDelta(e->delta(), e->orientation());
+}
+#endif // QT_NO_WHEELEVENT
PlatformWheelEvent::PlatformWheelEvent(QWheelEvent* e)
#ifdef QT_NO_WHEELEVENT
@@ -44,21 +83,7 @@ PlatformWheelEvent::PlatformWheelEvent(QWheelEvent* e)
, m_altKey(e->modifiers() & Qt::AltModifier)
, m_metaKey(e->modifiers() & Qt::MetaModifier)
{
- if (e->orientation() == Qt::Horizontal) {
- m_deltaX = (e->delta() / 120);
- m_deltaY = 0;
- } else {
- m_deltaX = 0;
- m_deltaY = (e->delta() / 120);
- }
- m_wheelTicksX = m_deltaX;
- m_wheelTicksY = m_deltaY;
-
- // use the same single scroll step as QTextEdit (in
- // QTextEditPrivate::init [h,v]bar->setSingleStep )
- static const float cDefaultQtScrollStep = 20.f;
- m_deltaX *= QApplication::wheelScrollLines() * cDefaultQtScrollStep;
- m_deltaY *= QApplication::wheelScrollLines() * cDefaultQtScrollStep;
+ applyDelta(e->delta(), e->orientation());
}
#endif // QT_NO_WHEELEVENT
diff --git a/WebCore/platform/qt/WidgetQt.cpp b/WebCore/platform/qt/WidgetQt.cpp
index 0fb6c37..e9c99a4 100644
--- a/WebCore/platform/qt/WidgetQt.cpp
+++ b/WebCore/platform/qt/WidgetQt.cpp
@@ -30,6 +30,7 @@
*/
#include "config.h"
+#include "Widget.h"
#include "Cursor.h"
#include "Font.h"
@@ -37,8 +38,8 @@
#include "HostWindow.h"
#include "IntRect.h"
#include "ScrollView.h"
-#include "Widget.h"
#include "NotImplemented.h"
+#include "QWebPageClient.h"
#include "qwebframe.h"
#include "qwebframe_p.h"
@@ -81,15 +82,10 @@ void Widget::setFocus()
void Widget::setCursor(const Cursor& cursor)
{
#ifndef QT_NO_CURSOR
- QWidget* widget = root()->hostWindow()->platformWindow();
-
- if (!widget)
- return;
-
- if (!cursor.impl().bitmap() && widget->cursor().shape() == cursor.impl().shape())
- return;
+ QWebPageClient* pageClient = root()->hostWindow()->platformPageClient();
- QCoreApplication::postEvent(widget, new SetCursorEvent(cursor.impl()));
+ if (pageClient)
+ pageClient->setCursor(cursor.impl());
#endif
}
@@ -105,7 +101,7 @@ void Widget::hide()
platformWidget()->hide();
}
-void Widget::paint(GraphicsContext *, const IntRect &rect)
+void Widget::paint(GraphicsContext*, const IntRect&)
{
}
diff --git a/WebCore/platform/sql/SQLValue.cpp b/WebCore/platform/sql/SQLValue.cpp
index 7e178f9..0ad643e 100644
--- a/WebCore/platform/sql/SQLValue.cpp
+++ b/WebCore/platform/sql/SQLValue.cpp
@@ -32,10 +32,10 @@
namespace WebCore {
SQLValue::SQLValue(const SQLValue& val)
+ : m_type(val.m_type)
+ , m_number(val.m_number)
+ , m_string(val.m_string.threadsafeCopy())
{
- m_number = val.m_number;
- m_string = val.m_string.copy();
- m_type = val.m_type;
}
String SQLValue::string() const
@@ -43,7 +43,7 @@ String SQLValue::string() const
ASSERT(m_type == StringValue);
// Must return a copy since ref-shared Strings are not thread safe
- return m_string.copy();
+ return m_string.threadsafeCopy();
}
double SQLValue::number() const
diff --git a/WebCore/platform/sql/SQLValue.h b/WebCore/platform/sql/SQLValue.h
index 7d85051..0f854fc 100644
--- a/WebCore/platform/sql/SQLValue.h
+++ b/WebCore/platform/sql/SQLValue.h
@@ -38,9 +38,9 @@ namespace WebCore {
public:
enum Type { NullValue, NumberValue, StringValue };
- SQLValue() : m_type(NullValue) { }
+ SQLValue() : m_type(NullValue), m_number(0.0) { }
SQLValue(double number) : m_type(NumberValue), m_number(number) { }
- SQLValue(const String& s) : m_type(StringValue), m_string(s) { }
+ SQLValue(const String& s) : m_type(StringValue), m_number(0.0), m_string(s) { }
SQLValue(const SQLValue&);
Type type() const { return m_type; }
diff --git a/WebCore/platform/sql/SQLiteTransaction.cpp b/WebCore/platform/sql/SQLiteTransaction.cpp
index 0a236be..a4b2ac8 100644
--- a/WebCore/platform/sql/SQLiteTransaction.cpp
+++ b/WebCore/platform/sql/SQLiteTransaction.cpp
@@ -30,9 +30,10 @@
namespace WebCore {
-SQLiteTransaction::SQLiteTransaction(SQLiteDatabase& db)
+SQLiteTransaction::SQLiteTransaction(SQLiteDatabase& db, bool readOnly)
: m_db(db)
, m_inProgress(false)
+ , m_readOnly(readOnly)
{
}
@@ -46,7 +47,17 @@ void SQLiteTransaction::begin()
{
if (!m_inProgress) {
ASSERT(!m_db.m_transactionInProgress);
- m_inProgress = m_db.executeCommand("BEGIN;");
+ // Call BEGIN IMMEDIATE for a write transaction to acquire
+ // a RESERVED lock on the DB file. Otherwise, another write
+ // transaction (on another connection) could make changes
+ // to the same DB file before this transaction gets to execute
+ // any statements. If that happens, this transaction will fail.
+ // http://www.sqlite.org/lang_transaction.html
+ // http://www.sqlite.org/lockingv3.html#locking
+ if (m_readOnly)
+ m_inProgress = m_db.executeCommand("BEGIN;");
+ else
+ m_inProgress = m_db.executeCommand("BEGIN IMMEDIATE;");
m_db.m_transactionInProgress = m_inProgress;
}
}
diff --git a/WebCore/platform/sql/SQLiteTransaction.h b/WebCore/platform/sql/SQLiteTransaction.h
index cf5a180..557d81c 100644
--- a/WebCore/platform/sql/SQLiteTransaction.h
+++ b/WebCore/platform/sql/SQLiteTransaction.h
@@ -35,7 +35,7 @@ class SQLiteDatabase;
class SQLiteTransaction : public Noncopyable
{
public:
- SQLiteTransaction(SQLiteDatabase& db);
+ SQLiteTransaction(SQLiteDatabase& db, bool readOnly = false);
~SQLiteTransaction();
void begin();
@@ -47,10 +47,9 @@ public:
private:
SQLiteDatabase& m_db;
bool m_inProgress;
-
+ bool m_readOnly;
};
} // namespace WebCore
#endif // SQLiteTransation_H
-
diff --git a/WebCore/platform/sql/chromium/SQLiteFileSystemChromium.cpp b/WebCore/platform/sql/chromium/SQLiteFileSystemChromium.cpp
index dc79fd0..3cf961f 100644
--- a/WebCore/platform/sql/chromium/SQLiteFileSystemChromium.cpp
+++ b/WebCore/platform/sql/chromium/SQLiteFileSystemChromium.cpp
@@ -55,10 +55,10 @@ int SQLiteFileSystem::openDatabase(const String& fileName, sqlite3** database)
return sqlite3_open16(path.charactersWithNullTermination(), database);
}
- // open databases using Chromium's VFS
+ // open databases using the default VFS
+ // in renderers, it should be Chromium's VFS; in the browser process it should be SQLite's default VFS
return sqlite3_open_v2(fileName.utf8().data(), database,
- SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX,
- "chromium_vfs");
+ SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX, 0);
}
String SQLiteFileSystem::getFileNameForNewDatabase(
@@ -99,9 +99,7 @@ bool SQLiteFileSystem::deleteEmptyDatabaseDirectory(const String&)
bool SQLiteFileSystem::deleteDatabaseFile(const String& fileName)
{
- // return true if and only if the error code returned by
- // ChromiumBridge::deleteDatabase() is 0
- return (!ChromiumBridge::databaseDeleteFile(fileName));
+ return (ChromiumBridge::databaseDeleteFile(fileName) == SQLITE_OK);
}
long long SQLiteFileSystem::getDatabaseFileSize(const String& fileName)
diff --git a/WebCore/platform/sql/chromium/SQLiteFileSystemChromiumPosix.cpp b/WebCore/platform/sql/chromium/SQLiteFileSystemChromiumPosix.cpp
new file mode 100644
index 0000000..2960a5f
--- /dev/null
+++ b/WebCore/platform/sql/chromium/SQLiteFileSystemChromiumPosix.cpp
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "SQLiteFileSystem.h"
+
+#include "ChromiumBridge.h"
+#include <sqlite3.h>
+
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+
+using namespace WebCore;
+
+// Defined in Chromium's codebase in third_party/sqlite/src/os_unix.c
+extern "C" {
+void initUnixFile(sqlite3_file* file);
+int fillInUnixFile(sqlite3_vfs* vfs, int fd, int dirfd, sqlite3_file* file, const char* fileName, int noLock);
+}
+
+// Chromium's Posix implementation of SQLite VFS
+namespace {
+
+// Opens a file.
+//
+// vfs - pointer to the sqlite3_vfs object.
+// fileName - the name of the file.
+// id - the structure that will manipulate the newly opened file.
+// desiredFlags - the desired open mode flags.
+// usedFlags - the actual open mode flags that were used.
+int chromiumOpen(sqlite3_vfs* vfs, const char* fileName,
+ sqlite3_file* id, int desiredFlags, int* usedFlags)
+{
+ initUnixFile(id);
+ int dirfd = -1;
+ int fd = ChromiumBridge::databaseOpenFile(fileName, desiredFlags, &dirfd);
+ if (fd < 0) {
+ if (desiredFlags & SQLITE_OPEN_READWRITE) {
+ int newFlags = (desiredFlags & ~(SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE)) | SQLITE_OPEN_READONLY;
+ return chromiumOpen(vfs, fileName, id, newFlags, usedFlags);
+ } else
+ return SQLITE_CANTOPEN;
+ }
+ if (usedFlags)
+ *usedFlags = desiredFlags;
+
+ fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
+ if (dirfd >= 0)
+ fcntl(dirfd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
+
+ // The mask 0x00007F00 gives us the 7 bits that determine the type of the file SQLite is trying to open.
+ int fileType = desiredFlags & 0x00007F00;
+ int noLock = (fileType != SQLITE_OPEN_MAIN_DB);
+ return fillInUnixFile(vfs, fd, dirfd, id, fileName, noLock);
+}
+
+// Deletes the given file.
+//
+// vfs - pointer to the sqlite3_vfs object.
+// fileName - the name of the file.
+// syncDir - determines if the directory to which this file belongs
+// should be synched after the file is deleted.
+int chromiumDelete(sqlite3_vfs*, const char* fileName, int syncDir)
+{
+ return ChromiumBridge::databaseDeleteFile(fileName, syncDir);
+}
+
+// Check the existance and status of the given file.
+//
+// vfs - pointer to the sqlite3_vfs object.
+// fileName - the name of the file.
+// flag - the type of test to make on this file.
+// res - the result.
+int chromiumAccess(sqlite3_vfs*, const char* fileName, int flag, int* res)
+{
+ int attr = static_cast<int>(ChromiumBridge::databaseGetFileAttributes(fileName));
+ if (attr < 0) {
+ *res = 0;
+ return SQLITE_OK;
+ }
+
+ switch (flag) {
+ case SQLITE_ACCESS_EXISTS:
+ *res = 1; // if the file doesn't exist, attr < 0
+ break;
+ case SQLITE_ACCESS_READWRITE:
+ *res = (attr & W_OK) && (attr & R_OK);
+ break;
+ case SQLITE_ACCESS_READ:
+ *res = (attr & R_OK);
+ break;
+ default:
+ return SQLITE_ERROR;
+ }
+
+ return SQLITE_OK;
+}
+
+// Turns a relative pathname into a full pathname.
+//
+// vfs - pointer to the sqlite3_vfs object.
+// relativePath - the relative path.
+// bufSize - the size of the output buffer in bytes.
+// absolutePath - the output buffer where the absolute path will be stored.
+int chromiumFullPathname(sqlite3_vfs* vfs, const char* relativePath,
+ int, char* absolutePath)
+{
+ // The renderer process doesn't need to know the absolute path of the file
+ sqlite3_snprintf(vfs->mxPathname, absolutePath, "%s", relativePath);
+ return SQLITE_OK;
+}
+
+#ifndef SQLITE_OMIT_LOAD_EXTENSION
+// Returns NULL, thus disallowing loading libraries in the renderer process.
+//
+// vfs - pointer to the sqlite3_vfs object.
+// fileName - the name of the shared library file.
+void* chromiumDlOpen(sqlite3_vfs*, const char*)
+{
+ return 0;
+}
+#else
+#define chromiumDlOpen 0
+#endif // SQLITE_OMIT_LOAD_EXTENSION
+
+} // namespace
+
+namespace WebCore {
+
+void SQLiteFileSystem::registerSQLiteVFS()
+{
+ // FIXME: Make sure there aren't any unintended consequences when VFS code is called in the browser process.
+ if (!ChromiumBridge::sandboxEnabled()) {
+ ASSERT_NOT_REACHED();
+ return;
+ }
+
+ sqlite3_vfs* unix_vfs = sqlite3_vfs_find("unix");
+ static sqlite3_vfs chromium_vfs = {
+ 1,
+ unix_vfs->szOsFile,
+ unix_vfs->mxPathname,
+ 0,
+ "chromium_vfs",
+ unix_vfs->pAppData,
+ chromiumOpen,
+ chromiumDelete,
+ chromiumAccess,
+ chromiumFullPathname,
+ chromiumDlOpen,
+ unix_vfs->xDlError,
+ unix_vfs->xDlSym,
+ unix_vfs->xDlClose,
+ unix_vfs->xRandomness,
+ unix_vfs->xSleep,
+ unix_vfs->xCurrentTime,
+ unix_vfs->xGetLastError
+ };
+ sqlite3_vfs_register(&chromium_vfs, 1);
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/sql/chromium/SQLiteFileSystemChromiumWin.cpp b/WebCore/platform/sql/chromium/SQLiteFileSystemChromiumWin.cpp
index b357d4a..153793b 100644
--- a/WebCore/platform/sql/chromium/SQLiteFileSystemChromiumWin.cpp
+++ b/WebCore/platform/sql/chromium/SQLiteFileSystemChromiumWin.cpp
@@ -35,6 +35,8 @@
#include <sqlite3.h>
#include <windows.h>
+using namespace WebCore;
+
// Defined in Chromium's codebase in third_party/sqlite/src/os_win.c
extern "C" {
int chromium_sqlite3_initialize_win_sqlite3_file(sqlite3_file* file, HANDLE handle);
@@ -53,7 +55,7 @@ namespace {
int chromiumOpen(sqlite3_vfs*, const char* fileName,
sqlite3_file* id, int desiredFlags, int* usedFlags)
{
- HANDLE h = WebCore::ChromiumBridge::databaseOpenFile(fileName, desiredFlags);
+ HANDLE h = ChromiumBridge::databaseOpenFile(fileName, desiredFlags);
if (h == INVALID_HANDLE_VALUE) {
if (desiredFlags & SQLITE_OPEN_READWRITE) {
int newFlags = (desiredFlags | SQLITE_OPEN_READONLY) & ~SQLITE_OPEN_READWRITE;
@@ -80,10 +82,7 @@ int chromiumOpen(sqlite3_vfs*, const char* fileName,
// should be synched after the file is deleted.
int chromiumDelete(sqlite3_vfs*, const char* fileName, int)
{
- bool deleted = WebCore::ChromiumBridge::databaseDeleteFile(fileName);
- DWORD rc = WebCore::ChromiumBridge::databaseGetFileAttributes(fileName);
- return ((rc == INVALID_FILE_ATTRIBUTES) && deleted ?
- SQLITE_OK : SQLITE_IOERR_DELETE);
+ return ChromiumBridge::databaseDeleteFile(fileName);
}
// Check the existance and status of the given file.
@@ -94,7 +93,7 @@ int chromiumDelete(sqlite3_vfs*, const char* fileName, int)
// res - the result.
int chromiumAccess(sqlite3_vfs*, const char* fileName, int flag, int* res)
{
- DWORD attr = WebCore::ChromiumBridge::databaseGetFileAttributes(fileName);
+ DWORD attr = ChromiumBridge::databaseGetFileAttributes(fileName);
switch (flag) {
case SQLITE_ACCESS_READ:
case SQLITE_ACCESS_EXISTS:
@@ -156,7 +155,7 @@ void SQLiteFileSystem::registerSQLiteVFS()
win32_vfs->mxPathname,
0,
"chromium_vfs",
- 0,
+ win32_vfs->pAppData,
chromiumOpen,
chromiumDelete,
chromiumAccess,
diff --git a/WebCore/platform/text/CString.cpp b/WebCore/platform/text/CString.cpp
index 90990f8..25f5fa1 100644
--- a/WebCore/platform/text/CString.cpp
+++ b/WebCore/platform/text/CString.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003, 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2006, 2008, 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
diff --git a/WebCore/platform/text/CString.h b/WebCore/platform/text/CString.h
index f084ddf..b9030d6 100644
--- a/WebCore/platform/text/CString.h
+++ b/WebCore/platform/text/CString.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003, 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2006, 2008, 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
diff --git a/WebCore/platform/text/PlatformString.h b/WebCore/platform/text/PlatformString.h
index 6d5384f..8d19c17 100644
--- a/WebCore/platform/text/PlatformString.h
+++ b/WebCore/platform/text/PlatformString.h
@@ -56,6 +56,10 @@ QT_END_NAMESPACE
class wxString;
#endif
+#if PLATFORM(HAIKU)
+class BString;
+#endif
+
namespace WebCore {
class CString;
@@ -189,16 +193,13 @@ public:
bool percentage(int& percentage) const;
- // Makes a deep copy. Helpful only if you need to use a String on another thread.
+ // Returns a StringImpl suitable for use on another thread.
+ String crossThreadString() const;
+ // Makes a deep copy. Helpful only if you need to use a String on another thread
+ // (use crossThreadString if the method call doesn't need to be threadsafe).
// Since the underlying StringImpl objects are immutable, there's no other reason
// to ever prefer copy() over plain old assignment.
- String copy() const;
-
- // Makes a deep copy like copy() but only for a substring.
- // (This ensures that you always get something suitable for a thread while subtring
- // may not. For example, in the empty string case, StringImpl::substring returns
- // empty() which is not safe for another thread.)
- String substringCopy(unsigned pos, unsigned len = UINT_MAX) const;
+ String threadsafeCopy() const;
bool isNull() const { return !m_impl; }
bool isEmpty() const;
@@ -229,6 +230,11 @@ public:
operator wxString() const;
#endif
+#if PLATFORM(HAIKU)
+ String(const BString&);
+ operator BString() const;
+#endif
+
#ifndef NDEBUG
Vector<char> ascii() const;
#endif
@@ -245,6 +251,14 @@ public:
// Determines the writing direction using the Unicode Bidi Algorithm rules P2 and P3.
WTF::Unicode::Direction defaultWritingDirection() const { return m_impl ? m_impl->defaultWritingDirection() : WTF::Unicode::LeftToRight; }
+ // Counts the number of grapheme clusters. A surrogate pair or a sequence
+ // of a non-combining character and following combining characters is
+ // counted as 1 grapheme cluster.
+ unsigned numGraphemeClusters() const;
+ // Returns the number of characters which will be less than or equal to
+ // the specified grapheme cluster length.
+ unsigned numCharactersInGraphemeClusters(unsigned) const;
+
private:
RefPtr<StringImpl> m_impl;
};
diff --git a/WebCore/platform/text/RegularExpression.cpp b/WebCore/platform/text/RegularExpression.cpp
index 6329b3b..9b063c9 100644
--- a/WebCore/platform/text/RegularExpression.cpp
+++ b/WebCore/platform/text/RegularExpression.cpp
@@ -32,7 +32,7 @@
namespace WebCore {
-class RegularExpression::Private : public RefCounted<Private> {
+class RegularExpression::Private : public RefCounted<RegularExpression::Private> {
public:
static PassRefPtr<Private> create(const String& pattern, TextCaseSensitivity);
~Private();
diff --git a/WebCore/platform/text/String.cpp b/WebCore/platform/text/String.cpp
index 2730939..bef2674 100644
--- a/WebCore/platform/text/String.cpp
+++ b/WebCore/platform/text/String.cpp
@@ -25,6 +25,7 @@
#include "CString.h"
#include "FloatConversion.h"
#include "StringBuffer.h"
+#include "TextBreakIterator.h"
#include "TextEncoding.h"
#include <wtf/dtoa.h>
#include <limits>
@@ -262,13 +263,6 @@ String String::substring(unsigned pos, unsigned len) const
return m_impl->substring(pos, len);
}
-String String::substringCopy(unsigned pos, unsigned len) const
-{
- if (!m_impl)
- return String();
- return m_impl->substringCopy(pos, len);
-}
-
String String::lower() const
{
if (!m_impl)
@@ -589,11 +583,18 @@ float String::toFloat(bool* ok) const
return m_impl->toFloat(ok);
}
-String String::copy() const
+String String::threadsafeCopy() const
+{
+ if (!m_impl)
+ return String();
+ return m_impl->threadsafeCopy();
+}
+
+String String::crossThreadString() const
{
if (!m_impl)
return String();
- return m_impl->copy();
+ return m_impl->crossThreadString();
}
bool String::isEmpty() const
@@ -921,6 +922,31 @@ PassRefPtr<SharedBuffer> utf8Buffer(const String& string)
return SharedBuffer::adoptVector(buffer);
}
+unsigned String::numGraphemeClusters() const
+{
+ TextBreakIterator* it = characterBreakIterator(characters(), length());
+ if (!it)
+ return length();
+
+ unsigned num = 0;
+ while (textBreakNext(it) != TextBreakDone)
+ ++num;
+ return num;
+}
+
+unsigned String::numCharactersInGraphemeClusters(unsigned numGraphemeClusters) const
+{
+ TextBreakIterator* it = characterBreakIterator(characters(), length());
+ if (!it)
+ return min(length(), numGraphemeClusters);
+
+ for (unsigned i = 0; i < numGraphemeClusters; ++i) {
+ if (textBreakNext(it) == TextBreakDone)
+ return length();
+ }
+ return textBreakCurrent(it);
+}
+
} // namespace WebCore
#ifndef NDEBUG
diff --git a/WebCore/platform/text/StringImpl.cpp b/WebCore/platform/text/StringImpl.cpp
index 8b749c7..c3ab4be 100644
--- a/WebCore/platform/text/StringImpl.cpp
+++ b/WebCore/platform/text/StringImpl.cpp
@@ -57,7 +57,7 @@ static inline void deleteUCharVector(const UChar* p)
}
// Some of the factory methods create buffers using fastMalloc.
-// We must ensure that ll allocations of StringImpl are allocated using
+// We must ensure that all allocations of StringImpl are allocated using
// fastMalloc so that we don't have mis-matched frees. We accomplish
// this by overriding the new and delete operators.
void* StringImpl::operator new(size_t size, void* address)
@@ -79,10 +79,9 @@ void StringImpl::operator delete(void* address)
// This constructor is used only to create the empty string.
StringImpl::StringImpl()
- : m_length(0)
- , m_data(0)
+ : m_data(0)
+ , m_length(0)
, m_hash(0)
- , m_bufferIsInternal(false)
{
// Ensure that the hash is computed so that AtomicStringHash can call existingHash()
// with impunity. The empty string is special because it is never entered into
@@ -90,52 +89,10 @@ StringImpl::StringImpl()
hash();
}
-// This is one of the most common constructors, but it's also used for the copy()
-// operation. Because of that, it's the one constructor that doesn't assert the
-// length is non-zero, since we support copying the empty string.
-inline StringImpl::StringImpl(const UChar* characters, unsigned length)
- : m_length(length)
- , m_hash(0)
- , m_bufferIsInternal(false)
-{
- UChar* data = newUCharVector(length);
- memcpy(data, characters, length * sizeof(UChar));
- m_data = data;
-}
-
-inline StringImpl::StringImpl(const StringImpl& str, WithTerminatingNullCharacter)
- : m_length(str.m_length)
- , m_hash(str.m_hash)
- , m_bufferIsInternal(false)
-{
- m_sharedBufferAndFlags.setFlag(HasTerminatingNullCharacter);
- UChar* data = newUCharVector(str.m_length + 1);
- memcpy(data, str.m_data, str.m_length * sizeof(UChar));
- data[str.m_length] = 0;
- m_data = data;
-}
-
-inline StringImpl::StringImpl(const char* characters, unsigned length)
- : m_length(length)
- , m_hash(0)
- , m_bufferIsInternal(false)
-{
- ASSERT(characters);
- ASSERT(length);
-
- UChar* data = newUCharVector(length);
- for (unsigned i = 0; i != length; ++i) {
- unsigned char c = characters[i];
- data[i] = c;
- }
- m_data = data;
-}
-
inline StringImpl::StringImpl(UChar* characters, unsigned length, AdoptBuffer)
- : m_length(length)
- , m_data(characters)
+ : m_data(characters)
+ , m_length(length)
, m_hash(0)
- , m_bufferIsInternal(false)
{
ASSERT(characters);
ASSERT(length);
@@ -143,9 +100,9 @@ inline StringImpl::StringImpl(UChar* characters, unsigned length, AdoptBuffer)
// This constructor is only for use by AtomicString.
StringImpl::StringImpl(const UChar* characters, unsigned length, unsigned hash)
- : m_length(length)
+ : m_data(0)
+ , m_length(length)
, m_hash(hash)
- , m_bufferIsInternal(false)
{
ASSERT(hash);
ASSERT(characters);
@@ -159,9 +116,9 @@ StringImpl::StringImpl(const UChar* characters, unsigned length, unsigned hash)
// This constructor is only for use by AtomicString.
StringImpl::StringImpl(const char* characters, unsigned length, unsigned hash)
- : m_length(length)
+ : m_data(0)
+ , m_length(length)
, m_hash(hash)
- , m_bufferIsInternal(false)
{
ASSERT(hash);
ASSERT(characters);
@@ -180,7 +137,7 @@ StringImpl::~StringImpl()
{
if (inTable())
AtomicString::remove(this);
- if (!m_bufferIsInternal) {
+ if (!bufferIsInternal()) {
SharedUChar* sharedBuffer = m_sharedBufferAndFlags.get();
if (sharedBuffer)
sharedBuffer->deref();
@@ -218,15 +175,6 @@ PassRefPtr<StringImpl> StringImpl::substring(unsigned start, unsigned length)
return create(m_data + start, length);
}
-PassRefPtr<StringImpl> StringImpl::substringCopy(unsigned start, unsigned length)
-{
- start = min(start, m_length);
- length = min(length, m_length - start);
- if (!length)
- return adoptRef(new StringImpl);
- return create(m_data + start, length);
-}
-
UChar32 StringImpl::characterStartingAt(unsigned i)
{
if (U16_IS_SINGLE(m_data[i]))
@@ -1007,10 +955,9 @@ PassRefPtr<StringImpl> StringImpl::createUninitialized(unsigned length, UChar*&
// struct as well as the data which it contains. This removes one
// heap allocation from this call.
size_t size = sizeof(StringImpl) + length * sizeof(UChar);
- char* buffer = static_cast<char*>(fastMalloc(size));
- data = reinterpret_cast<UChar*>(buffer + sizeof(StringImpl));
- StringImpl* string = new (buffer) StringImpl(data, length, AdoptBuffer());
- string->m_bufferIsInternal = true;
+ StringImpl* string = static_cast<StringImpl*>(fastMalloc(size));
+ data = reinterpret_cast<UChar*>(string + 1);
+ string = new (string) StringImpl(data, length, AdoptBuffer());
return adoptRef(string);
}
@@ -1071,18 +1018,43 @@ JSC::UString StringImpl::ustring()
PassRefPtr<StringImpl> StringImpl::createWithTerminatingNullCharacter(const StringImpl& string)
{
- return adoptRef(new StringImpl(string, WithTerminatingNullCharacter()));
+ // Use createUninitialized instead of 'new StringImpl' so that the string and its buffer
+ // get allocated in a single malloc block.
+ UChar* data;
+ int length = string.m_length;
+ RefPtr<StringImpl> terminatedString = createUninitialized(length + 1, data);
+ memcpy(data, string.m_data, length * sizeof(UChar));
+ data[length] = 0;
+ terminatedString->m_length--;
+ terminatedString->m_hash = string.m_hash;
+ terminatedString->m_sharedBufferAndFlags.setFlag(HasTerminatingNullCharacter);
+ return terminatedString.release();
}
-PassRefPtr<StringImpl> StringImpl::copy()
+PassRefPtr<StringImpl> StringImpl::threadsafeCopy() const
{
- // Using the constructor directly to make sure that per-thread empty string instance isn't returned.
- return adoptRef(new StringImpl(m_data, m_length));
+ // Special-case empty strings to make sure that per-thread empty string instance isn't returned.
+ if (m_length == 0)
+ return adoptRef(new StringImpl);
+ return create(m_data, m_length);
+}
+
+PassRefPtr<StringImpl> StringImpl::crossThreadString()
+{
+ SharedUChar* shared = sharedBuffer();
+ if (shared) {
+ RefPtr<StringImpl> impl = adoptRef(new StringImpl(const_cast<UChar*>(m_data), m_length, AdoptBuffer()));
+ impl->m_sharedBufferAndFlags.set(shared->crossThreadCopy().releaseRef());
+ return impl.release();
+ }
+
+ // If no shared buffer is available, create a copy.
+ return threadsafeCopy();
}
StringImpl::SharedUChar* StringImpl::sharedBuffer()
{
- if (m_length < minLengthToShare || m_bufferIsInternal)
+ if (m_length < minLengthToShare || bufferIsInternal())
return 0;
if (!m_sharedBufferAndFlags.get())
diff --git a/WebCore/platform/text/StringImpl.h b/WebCore/platform/text/StringImpl.h
index 8b4e82d..f3256cc 100644
--- a/WebCore/platform/text/StringImpl.h
+++ b/WebCore/platform/text/StringImpl.h
@@ -67,15 +67,10 @@ class StringImpl : public RefCounted<StringImpl> {
private:
friend class ThreadGlobalData;
StringImpl();
- StringImpl(const UChar*, unsigned length);
- StringImpl(const char*, unsigned length);
struct AdoptBuffer { };
StringImpl(UChar*, unsigned length, AdoptBuffer);
- struct WithTerminatingNullCharacter { };
- StringImpl(const StringImpl&, WithTerminatingNullCharacter);
-
// For AtomicString.
StringImpl(const UChar*, unsigned length, unsigned hash);
StringImpl(const char*, unsigned length, unsigned hash);
@@ -114,15 +109,12 @@ public:
static unsigned computeHash(const UChar*, unsigned len);
static unsigned computeHash(const char*);
- // Makes a deep copy. Helpful only if you need to use a String on another thread.
+ // Returns a StringImpl suitable for use on another thread.
+ PassRefPtr<StringImpl> crossThreadString();
+ // Makes a deep copy. Helpful only if you need to use a String on another thread
+ // (use crossThreadString if the method call doesn't need to be threadsafe).
// Since StringImpl objects are immutable, there's no other reason to make a copy.
- PassRefPtr<StringImpl> copy();
-
- // Makes a deep copy like copy() but only for a substring.
- // (This ensures that you always get something suitable for a thread while subtring
- // may not. For example, in the empty string case, substring returns empty() which
- // is not safe for another thread.)
- PassRefPtr<StringImpl> substringCopy(unsigned pos, unsigned len = UINT_MAX);
+ PassRefPtr<StringImpl> threadsafeCopy() const;
PassRefPtr<StringImpl> substring(unsigned pos, unsigned len = UINT_MAX);
@@ -166,7 +158,7 @@ public:
int reverseFind(UChar, int index);
int reverseFind(StringImpl*, int index, bool caseSensitive = true);
- bool startsWith(StringImpl* m_data, bool caseSensitive = true) { return reverseFind(m_data, 0, caseSensitive) == 0; }
+ bool startsWith(StringImpl* str, bool caseSensitive = true) { return reverseFind(str, 0, caseSensitive) == 0; }
bool endsWith(StringImpl*, bool caseSensitive = true);
PassRefPtr<StringImpl> replace(UChar, UChar);
@@ -196,21 +188,22 @@ private:
void* operator new(size_t size, void* address);
static PassRefPtr<StringImpl> createStrippingNullCharactersSlowCase(const UChar*, unsigned length);
+
+ // The StringImpl struct and its data may be allocated within a single heap block.
+ // In this case, the m_data pointer is an "internal buffer", and does not need to be deallocated.
+ bool bufferIsInternal() { return m_data == reinterpret_cast<const UChar*>(this + 1); }
enum StringImplFlags {
HasTerminatingNullCharacter,
InTable,
};
- unsigned m_length;
const UChar* m_data;
+ unsigned m_length;
mutable unsigned m_hash;
PtrAndFlags<SharedUChar, StringImplFlags> m_sharedBufferAndFlags;
-
- // In some cases, we allocate the StringImpl struct and its data
- // within a single heap buffer. In this case, the m_data pointer
- // is an "internal buffer", and does not need to be deallocated.
- bool m_bufferIsInternal;
+ // There is a fictitious variable-length UChar array at the end, which is used
+ // as the internal buffer by the createUninitialized and create methods.
};
bool equal(StringImpl*, StringImpl*);
diff --git a/WebCore/platform/text/TextEncoding.cpp b/WebCore/platform/text/TextEncoding.cpp
index b76f739..c5c8cfd 100644
--- a/WebCore/platform/text/TextEncoding.cpp
+++ b/WebCore/platform/text/TextEncoding.cpp
@@ -264,6 +264,7 @@ const TextEncoding& UTF32LittleEndianEncoding()
const TextEncoding& UTF8Encoding()
{
static TextEncoding globalUTF8Encoding("UTF-8");
+ ASSERT(globalUTF8Encoding.isValid());
return globalUTF8Encoding;
}
diff --git a/WebCore/platform/text/TextEncodingRegistry.cpp b/WebCore/platform/text/TextEncodingRegistry.cpp
index 5ab1c87..5d82511 100644
--- a/WebCore/platform/text/TextEncodingRegistry.cpp
+++ b/WebCore/platform/text/TextEncodingRegistry.cpp
@@ -48,7 +48,7 @@
#if PLATFORM(QT)
#include "qt/TextCodecQt.h"
#endif
-#if PLATFORM(WINCE)
+#if PLATFORM(WINCE) && !PLATFORM(QT)
#include "TextCodecWince.h"
#endif
@@ -194,7 +194,7 @@ static void buildBaseTextCodecMaps()
TextCodecICU::registerBaseCodecs(addToTextCodecMap);
#endif
-#if PLATFORM(WINCE)
+#if PLATFORM(WINCE) && !PLATFORM(QT)
TextCodecWince::registerBaseEncodingNames(addToTextEncodingNameMap);
TextCodecWince::registerBaseCodecs(addToTextCodecMap);
#endif
@@ -217,7 +217,7 @@ static void extendTextCodecMaps()
TextCodecMac::registerCodecs(addToTextCodecMap);
#endif
-#if PLATFORM(WINCE)
+#if PLATFORM(WINCE) && !PLATFORM(QT)
TextCodecWince::registerExtendedEncodingNames(addToTextEncodingNameMap);
TextCodecWince::registerExtendedCodecs(addToTextCodecMap);
#endif
diff --git a/WebCore/platform/text/UnicodeRange.h b/WebCore/platform/text/UnicodeRange.h
index 7ecf03f..2278a0e 100644
--- a/WebCore/platform/text/UnicodeRange.h
+++ b/WebCore/platform/text/UnicodeRange.h
@@ -35,6 +35,10 @@
#ifndef UnicodeRange_H
#define UnicodeRange_H
+#if PLATFORM(HAIKU)
+#include "stdint.h"
+#endif
+
#include <wtf/unicode/Unicode.h>
namespace WebCore {
diff --git a/WebCore/platform/text/cf/StringCF.cpp b/WebCore/platform/text/cf/StringCF.cpp
index 5e12ba9..b770d0e 100644
--- a/WebCore/platform/text/cf/StringCF.cpp
+++ b/WebCore/platform/text/cf/StringCF.cpp
@@ -45,7 +45,7 @@ String::String(CFStringRef str)
CFStringRef String::createCFString() const
{
if (!m_impl)
- return CFSTR("");
+ return static_cast<CFStringRef>(CFRetain(CFSTR("")));
return m_impl->createCFString();
}
diff --git a/WebCore/platform/text/haiku/TextBreakIteratorInternalICUHaiku.cpp b/WebCore/platform/text/haiku/TextBreakIteratorInternalICUHaiku.cpp
index 2c732d6..8bb8c70 100644
--- a/WebCore/platform/text/haiku/TextBreakIteratorInternalICUHaiku.cpp
+++ b/WebCore/platform/text/haiku/TextBreakIteratorInternalICUHaiku.cpp
@@ -26,6 +26,12 @@
namespace WebCore {
+const char* currentSearchLocaleID()
+{
+ notImplemented();
+ return "";
+}
+
const char* currentTextBreakLocaleID()
{
notImplemented();
diff --git a/WebCore/platform/text/mac/TextCodecMac.cpp b/WebCore/platform/text/mac/TextCodecMac.cpp
index 93b9da2..a1750c9 100644
--- a/WebCore/platform/text/mac/TextCodecMac.cpp
+++ b/WebCore/platform/text/mac/TextCodecMac.cpp
@@ -36,7 +36,7 @@
#include <wtf/PassOwnPtr.h>
#include <wtf/Threading.h>
-using std::min;
+using namespace std;
namespace WebCore {
@@ -141,7 +141,7 @@ OSStatus TextCodecMac::decode(const unsigned char* inputBuffer, int inputBufferL
// First, fill the partial character buffer with as many bytes as are available.
ASSERT(m_numBufferedBytes < sizeof(m_bufferedBytes));
const int spaceInBuffer = sizeof(m_bufferedBytes) - m_numBufferedBytes;
- const int bytesToPutInBuffer = MIN(spaceInBuffer, inputBufferLength);
+ const int bytesToPutInBuffer = min(spaceInBuffer, inputBufferLength);
ASSERT(bytesToPutInBuffer != 0);
memcpy(m_bufferedBytes + m_numBufferedBytes, inputBuffer, bytesToPutInBuffer);
@@ -283,28 +283,28 @@ CString TextCodecMac::encode(const UChar* characters, size_t length, Unencodable
// Encoding will change the yen sign back into a backslash.
String copy(characters, length);
copy.replace('\\', m_backslashAsCurrencySymbol);
- CFStringRef cfs = copy.createCFString();
+ RetainPtr<CFStringRef> cfs(AdoptCF, copy.createCFString());
CFIndex startPos = 0;
- CFIndex charactersLeft = CFStringGetLength(cfs);
+ CFIndex charactersLeft = CFStringGetLength(cfs.get());
Vector<char> result;
size_t size = 0;
UInt8 lossByte = handling == QuestionMarksForUnencodables ? '?' : 0;
while (charactersLeft > 0) {
CFRange range = CFRangeMake(startPos, charactersLeft);
CFIndex bufferLength;
- CFStringGetBytes(cfs, range, m_encoding, lossByte, false, NULL, 0x7FFFFFFF, &bufferLength);
+ CFStringGetBytes(cfs.get(), range, m_encoding, lossByte, false, NULL, 0x7FFFFFFF, &bufferLength);
result.grow(size + bufferLength);
unsigned char* buffer = reinterpret_cast<unsigned char*>(result.data() + size);
- CFIndex charactersConverted = CFStringGetBytes(cfs, range, m_encoding, lossByte, false, buffer, bufferLength, &bufferLength);
+ CFIndex charactersConverted = CFStringGetBytes(cfs.get(), range, m_encoding, lossByte, false, buffer, bufferLength, &bufferLength);
size += bufferLength;
if (charactersConverted != charactersLeft) {
- unsigned badChar = CFStringGetCharacterAtIndex(cfs, startPos + charactersConverted);
+ unsigned badChar = CFStringGetCharacterAtIndex(cfs.get(), startPos + charactersConverted);
++charactersConverted;
if ((badChar & 0xFC00) == 0xD800 && charactersConverted != charactersLeft) { // is high surrogate
- UniChar low = CFStringGetCharacterAtIndex(cfs, startPos + charactersConverted);
+ UniChar low = CFStringGetCharacterAtIndex(cfs.get(), startPos + charactersConverted);
if ((low & 0xFC00) == 0xDC00) { // is low surrogate
badChar <<= 10;
badChar += low;
@@ -322,7 +322,6 @@ CString TextCodecMac::encode(const UChar* characters, size_t length, Unencodable
startPos += charactersConverted;
charactersLeft -= charactersConverted;
}
- CFRelease(cfs);
return CString(result.data(), size);
}
diff --git a/WebCore/platform/text/qt/TextCodecQt.cpp b/WebCore/platform/text/qt/TextCodecQt.cpp
index c6c02cf..b3f75cc 100644
--- a/WebCore/platform/text/qt/TextCodecQt.cpp
+++ b/WebCore/platform/text/qt/TextCodecQt.cpp
@@ -94,7 +94,26 @@ TextCodecQt::~TextCodecQt()
String TextCodecQt::decode(const char* bytes, size_t length, bool flush, bool /*stopOnError*/, bool& sawError)
{
- QString unicode = m_codec->toUnicode(bytes, length, &m_state);
+ // We chop input buffer to smaller buffers to avoid excessive memory consumption
+ // when the input buffer is big. This helps reduce peak memory consumption in
+ // mobile devices where system RAM is limited.
+#if PLATFORM(SYMBIAN)
+ static const int MaxInputChunkSize = 32 * 1024;
+#else
+ static const int MaxInputChunkSize = 1024 * 1024;
+#endif
+ const char* buf = bytes;
+ const char* end = buf + length;
+ String unicode(""); // a non-null string is expected
+
+ while (buf < end) {
+ int size = end - buf;
+ size = qMin(size, MaxInputChunkSize);
+ QString decoded = m_codec->toUnicode(buf, size, &m_state);
+ unicode.append(decoded);
+ buf += size;
+ }
+
sawError = m_state.invalidChars != 0;
if (flush) {
diff --git a/WebCore/platform/win/ClipboardWin.cpp b/WebCore/platform/win/ClipboardWin.cpp
index 65741e4..b2e8e3e 100644
--- a/WebCore/platform/win/ClipboardWin.cpp
+++ b/WebCore/platform/win/ClipboardWin.cpp
@@ -117,56 +117,49 @@ static inline void pathRemoveBadFSCharacters(PWSTR psz, size_t length)
static String filesystemPathFromUrlOrTitle(const String& url, const String& title, TCHAR* extension, bool isLink)
{
+ static const size_t fsPathMaxLengthExcludingNullTerminator = MAX_PATH - 1;
bool usedURL = false;
- WCHAR fsPathBuffer[MAX_PATH + 1];
+ WCHAR fsPathBuffer[MAX_PATH];
fsPathBuffer[0] = 0;
int extensionLen = extension ? lstrlen(extension) : 0;
+ int fsPathMaxLengthExcludingExtension = fsPathMaxLengthExcludingNullTerminator - extensionLen;
if (!title.isEmpty()) {
- size_t len = min<size_t>(title.length(), MAX_PATH - extensionLen);
+ size_t len = min<size_t>(title.length(), fsPathMaxLengthExcludingExtension);
CopyMemory(fsPathBuffer, title.characters(), len * sizeof(UChar));
fsPathBuffer[len] = 0;
pathRemoveBadFSCharacters(fsPathBuffer, len);
}
if (!lstrlen(fsPathBuffer)) {
- DWORD len = MAX_PATH;
- String nullTermURL = url;
+ KURL kurl(ParsedURLString, url);
usedURL = true;
- if (UrlIsFileUrl((LPCWSTR)nullTermURL.charactersWithNullTermination())
- && SUCCEEDED(PathCreateFromUrl((LPCWSTR)nullTermURL.charactersWithNullTermination(), fsPathBuffer, &len, 0))) {
- // When linking to a file URL we can trivially find the file name
- PWSTR fn = PathFindFileName(fsPathBuffer);
- if (fn && fn != fsPathBuffer)
- lstrcpyn(fsPathBuffer, fn, lstrlen(fn) + 1);
+ // The filename for any content based drag or file url should be the last element of
+ // the path. If we can't find it, or we're coming up with the name for a link
+ // we just use the entire url.
+ DWORD len = fsPathMaxLengthExcludingExtension;
+ String lastComponent = kurl.lastPathComponent();
+ if (kurl.isLocalFile() || (!isLink && !lastComponent.isEmpty())) {
+ len = min<DWORD>(fsPathMaxLengthExcludingExtension, lastComponent.length());
+ CopyMemory(fsPathBuffer, lastComponent.characters(), len * sizeof(UChar));
} else {
- // The filename for any content based drag should be the last element of
- // the path. If we can't find it, or we're coming up with the name for a link
- // we just use the entire url.
- KURL kurl(url);
- String lastComponent;
- if (!isLink && !(lastComponent = kurl.lastPathComponent()).isEmpty()) {
- len = min<DWORD>(MAX_PATH, lastComponent.length());
- CopyMemory(fsPathBuffer, lastComponent.characters(), len * sizeof(UChar));
- } else {
- len = min<DWORD>(MAX_PATH, nullTermURL.length());
- CopyMemory(fsPathBuffer, nullTermURL.characters(), len * sizeof(UChar));
- }
- fsPathBuffer[len] = 0;
- pathRemoveBadFSCharacters(fsPathBuffer, len);
+ len = min<DWORD>(fsPathMaxLengthExcludingExtension, url.length());
+ CopyMemory(fsPathBuffer, url.characters(), len * sizeof(UChar));
}
+ fsPathBuffer[len] = 0;
+ pathRemoveBadFSCharacters(fsPathBuffer, len);
}
if (!extension)
- return String((UChar*)fsPathBuffer);
+ return String(static_cast<UChar*>(fsPathBuffer));
if (!isLink && usedURL) {
PathRenameExtension(fsPathBuffer, extension);
- return String((UChar*)fsPathBuffer);
+ return String(static_cast<UChar*>(fsPathBuffer));
}
- String result((UChar*)fsPathBuffer);
- result += String((UChar*)extension);
+ String result(static_cast<UChar*>(fsPathBuffer));
+ result += String(static_cast<UChar*>(extension));
return result;
}
@@ -522,7 +515,7 @@ bool ClipboardWin::setData(const String& type, const String& data)
ClipboardDataType winType = clipboardTypeFromMIMEType(type);
if (winType == ClipboardDataTypeURL)
- return WebCore::writeURL(m_writableDataObject.get(), KURL(data), String(), false, true);
+ return WebCore::writeURL(m_writableDataObject.get(), KURL(ParsedURLString, data), String(), false, true);
if (winType == ClipboardDataTypeText) {
STGMEDIUM medium = {0};
diff --git a/WebCore/platform/win/CursorWin.cpp b/WebCore/platform/win/CursorWin.cpp
index 2bfe7a8..5afb1ae9 100644
--- a/WebCore/platform/win/CursorWin.cpp
+++ b/WebCore/platform/win/CursorWin.cpp
@@ -279,7 +279,7 @@ const Cursor& rowResizeCursor()
const Cursor& middlePanningCursor()
{
- static const Cursor c = loadCursorByName("panIcon", 7, 7);
+ static const Cursor c = loadCursorByName("panIcon", 8, 8);
return c;
}
diff --git a/WebCore/platform/win/PasteboardWin.cpp b/WebCore/platform/win/PasteboardWin.cpp
index 188630f..d09769a 100644
--- a/WebCore/platform/win/PasteboardWin.cpp
+++ b/WebCore/platform/win/PasteboardWin.cpp
@@ -111,7 +111,7 @@ void Pasteboard::clear()
void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete, Frame* frame)
{
clear();
-
+
// Put CF_HTML format on the pasteboard
if (::OpenClipboard(m_owner)) {
ExceptionCode ec = 0;
@@ -145,6 +145,21 @@ void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete,
}
}
+void Pasteboard::writePlainText(const String& text)
+{
+ clear();
+
+ // Put plain string on the pasteboard. CF_UNICODETEXT covers CF_TEXT as well
+ String str = text;
+ replaceNewlinesWithWindowsStyleNewlines(str);
+ if (::OpenClipboard(m_owner)) {
+ HGLOBAL cbData = createGlobalData(str);
+ if (!::SetClipboardData(CF_UNICODETEXT, cbData))
+ ::GlobalFree(cbData);
+ ::CloseClipboard();
+ }
+}
+
void Pasteboard::writeURL(const KURL& url, const String& titleStr, Frame* frame)
{
ASSERT(!url.isEmpty());
diff --git a/WebCore/platform/win/PlatformScreenWin.cpp b/WebCore/platform/win/PlatformScreenWin.cpp
index 7ac4706..6e0f861 100644
--- a/WebCore/platform/win/PlatformScreenWin.cpp
+++ b/WebCore/platform/win/PlatformScreenWin.cpp
@@ -39,7 +39,7 @@ namespace WebCore {
// Returns info for the default monitor if widget is NULL
static MONITORINFOEX monitorInfoForWidget(Widget* widget)
{
- HWND window = widget ? widget->root()->hostWindow()->platformWindow() : 0;
+ HWND window = widget ? widget->root()->hostWindow()->platformPageClient() : 0;
HMONITOR monitor = MonitorFromWindow(window, MONITOR_DEFAULTTOPRIMARY);
MONITORINFOEX monitorInfo;
diff --git a/WebCore/platform/win/PopupMenuWin.cpp b/WebCore/platform/win/PopupMenuWin.cpp
index e53053f..1d9eb71 100644
--- a/WebCore/platform/win/PopupMenuWin.cpp
+++ b/WebCore/platform/win/PopupMenuWin.cpp
@@ -40,6 +40,7 @@
#include "SimpleFontData.h"
#include <tchar.h>
#include <windows.h>
+#include <windowsx.h>
#if PLATFORM(WINCE)
#include <ResDefCE.h>
#define MAKEPOINTS(l) (*((POINTS FAR *)&(l)))
@@ -60,8 +61,13 @@ const int optionSpacingMiddle = 1;
const int popupWindowBorderWidth = 1;
static LPCTSTR kPopupWindowClassName = _T("PopupWindowClass");
-static ATOM registerPopup();
-static LRESULT CALLBACK PopupWndProc(HWND, UINT, WPARAM, LPARAM);
+
+// This is used from within our custom message pump when we want to send a
+// message to the web view and not have our message stolen and sent to
+// the popup window.
+static const UINT WM_HOST_WINDOW_FIRST = WM_USER;
+static const UINT WM_HOST_WINDOW_CHAR = WM_USER + WM_CHAR;
+static const UINT WM_HOST_WINDOW_MOUSEMOVE = WM_USER + WM_MOUSEMOVE;
// FIXME: Remove this as soon as practical.
static inline bool isASCIIPrintable(unsigned c)
@@ -69,6 +75,15 @@ static inline bool isASCIIPrintable(unsigned c)
return c >= 0x20 && c <= 0x7E;
}
+static void translatePoint(LPARAM& lParam, HWND from, HWND to)
+{
+ POINT pt;
+ pt.x = (short)GET_X_LPARAM(lParam);
+ pt.y = (short)GET_Y_LPARAM(lParam);
+ ::MapWindowPoints(from, to, &pt, 1);
+ lParam = MAKELPARAM(pt.x, pt.y);
+}
+
PopupMenu::PopupMenu(PopupMenuClient* client)
: m_popupClient(client)
, m_scrollbar(0)
@@ -81,6 +96,7 @@ PopupMenu::PopupMenu(PopupMenuClient* client)
, m_wheelDelta(0)
, m_focusedIndex(0)
, m_scrollbarCapturingMouse(false)
+ , m_showPopup(false)
{
}
@@ -92,44 +108,46 @@ PopupMenu::~PopupMenu()
::DeleteDC(m_DC);
if (m_popup)
::DestroyWindow(m_popup);
+ if (m_scrollbar)
+ m_scrollbar->setParent(0);
+}
+
+LPCTSTR PopupMenu::popupClassName()
+{
+ return kPopupWindowClassName;
}
-void PopupMenu::show(const IntRect& r, FrameView* v, int index)
+void PopupMenu::show(const IntRect& r, FrameView* view, int index)
{
- calculatePositionAndSize(r, v);
+ calculatePositionAndSize(r, view);
if (clientRect().isEmpty())
return;
+ HWND hostWindow = view->hostWindow()->platformPageClient();
+
+ if (!m_scrollbar && visibleItems() < client()->listSize()) {
+ // We need a scroll bar
+ m_scrollbar = client()->createScrollbar(this, VerticalScrollbar, SmallScrollbar);
+ m_scrollbar->styleChanged();
+ }
+
if (!m_popup) {
- registerPopup();
+ registerClass();
DWORD exStyle = WS_EX_LTRREADING;
- // Even though we already know our size and location at this point, we pass (0,0,0,0) as our size/location here.
- // We need to wait until after the call to ::SetWindowLongPtr to set our size so that in our WM_SIZE handler we can get access to the PopupMenu object
m_popup = ::CreateWindowEx(exStyle, kPopupWindowClassName, _T("PopupMenu"),
WS_POPUP | WS_BORDER,
- 0, 0, 0, 0,
- v->hostWindow()->platformWindow(), 0, 0, 0);
+ m_windowRect.x(), m_windowRect.y(), m_windowRect.width(), m_windowRect.height(),
+ hostWindow, 0, Page::instanceHandle(), this);
if (!m_popup)
return;
-
-#if PLATFORM(WINCE)
- ::SetWindowLong(m_popup, 0, (LONG)this);
-#else
- ::SetWindowLongPtr(m_popup, 0, (LONG_PTR)this);
-#endif
+ } else {
+ // We need to reposition the popup window.
+ ::MoveWindow(m_popup, m_windowRect.x(), m_windowRect.y(), m_windowRect.width(), m_windowRect.height(), false);
}
- if (!m_scrollbar)
- if (visibleItems() < client()->listSize()) {
- // We need a scroll bar
- m_scrollbar = client()->createScrollbar(this, VerticalScrollbar, SmallScrollbar);
- }
-
- ::SetWindowPos(m_popup, HWND_TOP, m_windowRect.x(), m_windowRect.y(), m_windowRect.width(), m_windowRect.height(), 0);
-
// Determine whether we should animate our popups
// Note: Must use 'BOOL' and 'FALSE' instead of 'bool' and 'false' to avoid stack corruption with SystemParametersInfo
BOOL shouldAnimate = FALSE;
@@ -138,30 +156,127 @@ void PopupMenu::show(const IntRect& r, FrameView* v, int index)
if (shouldAnimate) {
RECT viewRect = {0};
- ::GetWindowRect(v->hostWindow()->platformWindow(), &viewRect);
+ ::GetWindowRect(hostWindow, &viewRect);
if (!::IsRectEmpty(&viewRect)) {
// Popups should slide into view away from the <select> box
// NOTE: This may have to change for Vista
- DWORD slideDirection = (m_windowRect.y() < viewRect.top + v->contentsToWindow(r.location()).y()) ? AW_VER_NEGATIVE : AW_VER_POSITIVE;
+ DWORD slideDirection = (m_windowRect.y() < viewRect.top + view->contentsToWindow(r.location()).y()) ? AW_VER_NEGATIVE : AW_VER_POSITIVE;
- ::AnimateWindow(m_popup, defaultAnimationDuration, AW_SLIDE | slideDirection | AW_ACTIVATE);
+ ::AnimateWindow(m_popup, defaultAnimationDuration, AW_SLIDE | slideDirection);
}
} else
#endif
- ::ShowWindow(m_popup, SW_SHOWNORMAL);
- ::SetCapture(m_popup);
+ ::ShowWindow(m_popup, SW_SHOWNOACTIVATE);
if (client()) {
int index = client()->selectedIndex();
if (index >= 0)
setFocusedIndex(index);
}
+
+ m_showPopup = true;
+
+ // Protect the popup menu in case its owner is destroyed while we're running the message pump.
+ RefPtr<PopupMenu> protect(this);
+
+ ::SetCapture(hostWindow);
+
+ MSG msg;
+ HWND activeWindow;
+
+ while (::GetMessage(&msg, 0, 0, 0)) {
+ switch (msg.message) {
+ case WM_HOST_WINDOW_MOUSEMOVE:
+ case WM_HOST_WINDOW_CHAR:
+ if (msg.hwnd == m_popup) {
+ // This message should be sent to the host window.
+ msg.hwnd = hostWindow;
+ msg.message -= WM_HOST_WINDOW_FIRST;
+ }
+ break;
+
+ // Steal mouse messages.
+ case WM_NCMOUSEMOVE:
+ case WM_NCLBUTTONDOWN:
+ case WM_NCLBUTTONUP:
+ case WM_NCLBUTTONDBLCLK:
+ case WM_NCRBUTTONDOWN:
+ case WM_NCRBUTTONUP:
+ case WM_NCRBUTTONDBLCLK:
+ case WM_NCMBUTTONDOWN:
+ case WM_NCMBUTTONUP:
+ case WM_NCMBUTTONDBLCLK:
+ case WM_MOUSEWHEEL:
+ msg.hwnd = m_popup;
+ break;
+
+ // These mouse messages use client coordinates so we need to convert them.
+ case WM_MOUSEMOVE:
+ case WM_LBUTTONDOWN:
+ case WM_LBUTTONUP:
+ case WM_LBUTTONDBLCLK:
+ case WM_RBUTTONDOWN:
+ case WM_RBUTTONUP:
+ case WM_RBUTTONDBLCLK:
+ case WM_MBUTTONDOWN:
+ case WM_MBUTTONUP:
+ case WM_MBUTTONDBLCLK: {
+ // Translate the coordinate.
+ translatePoint(msg.lParam, msg.hwnd, m_popup);
+
+ msg.hwnd = m_popup;
+ break;
+ }
+
+ // Steal all keyboard messages.
+ case WM_KEYDOWN:
+ case WM_KEYUP:
+ case WM_CHAR:
+ case WM_DEADCHAR:
+ case WM_SYSKEYUP:
+ case WM_SYSCHAR:
+ case WM_SYSDEADCHAR:
+ msg.hwnd = m_popup;
+ break;
+ }
+
+ ::TranslateMessage(&msg);
+ ::DispatchMessage(&msg);
+
+ if (!m_popupClient)
+ break;
+
+ if (!m_showPopup)
+ break;
+ activeWindow = ::GetActiveWindow();
+ if (activeWindow != hostWindow && !::IsChild(activeWindow, hostWindow))
+ break;
+ if (::GetCapture() != hostWindow)
+ break;
+ }
+
+ if (::GetCapture() == hostWindow)
+ ::ReleaseCapture();
+
+ // We're done, hide the popup if necessary.
+ hide();
}
void PopupMenu::hide()
{
+ if (!m_showPopup)
+ return;
+
+ m_showPopup = false;
+
::ShowWindow(m_popup, SW_HIDE);
+
+ if (client())
+ client()->popupDidHide();
+
+ // Post a WM_NULL message to wake up the message pump if necessary.
+ ::PostMessage(m_popup, WM_NULL, 0, 0);
}
const int endOfLinePadding = 2;
@@ -174,7 +289,7 @@ void PopupMenu::calculatePositionAndSize(const IntRect& r, FrameView* v)
// Then, translate to screen coordinates
POINT location(rScreenCoords.location());
- if (!::ClientToScreen(v->hostWindow()->platformWindow(), &location))
+ if (!::ClientToScreen(v->hostWindow()->platformPageClient(), &location))
return;
rScreenCoords.setLocation(location);
@@ -591,12 +706,12 @@ void PopupMenu::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rec
::InvalidateRect(m_popup, &r, false);
}
-static ATOM registerPopup()
+void PopupMenu::registerClass()
{
static bool haveRegisteredWindowClass = false;
if (haveRegisteredWindowClass)
- return true;
+ return;
#if PLATFORM(WINCE)
WNDCLASS wcex;
@@ -607,7 +722,7 @@ static ATOM registerPopup()
wcex.style = CS_DROPSHADOW;
#endif
- wcex.lpfnWndProc = PopupWndProc;
+ wcex.lpfnWndProc = PopupMenuWndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = sizeof(PopupMenu*); // For the PopupMenu pointer
wcex.hInstance = Page::instanceHandle();
@@ -620,228 +735,262 @@ static ATOM registerPopup()
haveRegisteredWindowClass = true;
#if PLATFORM(WINCE)
- return ::RegisterClass(&wcex);
+ RegisterClass(&wcex);
#else
- return ::RegisterClassEx(&wcex);
+ RegisterClassEx(&wcex);
#endif
}
-const int smoothScrollAnimationDuration = 5000;
-static LRESULT CALLBACK PopupWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+
+LRESULT CALLBACK PopupMenu::PopupMenuWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
- LRESULT lResult = 0;
#if PLATFORM(WINCE)
LONG longPtr = GetWindowLong(hWnd, 0);
#else
LONG_PTR longPtr = GetWindowLongPtr(hWnd, 0);
#endif
- PopupMenu* popup = reinterpret_cast<PopupMenu*>(longPtr);
+
+ if (PopupMenu* popup = reinterpret_cast<PopupMenu*>(longPtr))
+ return popup->wndProc(hWnd, message, wParam, lParam);
+
+ if (message == WM_CREATE) {
+ LPCREATESTRUCT createStruct = reinterpret_cast<LPCREATESTRUCT>(lParam);
+
+ // Associate the PopupMenu with the window.
+#if PLATFORM(WINCE)
+ ::SetWindowLong(hWnd, 0, (LONG)createStruct->lpCreateParams);
+#else
+ ::SetWindowLongPtr(hWnd, 0, (LONG_PTR)createStruct->lpCreateParams);
+#endif
+ return 0;
+ }
+
+ return ::DefWindowProc(hWnd, message, wParam, lParam);
+}
+
+const int smoothScrollAnimationDuration = 5000;
+
+LRESULT PopupMenu::wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ LRESULT lResult = 0;
switch (message) {
- case WM_SIZE:
- if (popup && popup->scrollbar()) {
- IntSize size(LOWORD(lParam), HIWORD(lParam));
- popup->scrollbar()->setFrameRect(IntRect(size.width() - popup->scrollbar()->width(), 0, popup->scrollbar()->width(), size.height()));
-
- int visibleItems = popup->visibleItems();
- popup->scrollbar()->setEnabled(visibleItems < popup->client()->listSize());
- popup->scrollbar()->setSteps(1, max(1, visibleItems - 1));
- popup->scrollbar()->setProportion(visibleItems, popup->client()->listSize());
- }
- break;
- case WM_ACTIVATE:
- if (popup && popup->client() && wParam == WA_INACTIVE)
- popup->client()->hidePopup();
- break;
- case WM_KILLFOCUS:
- if (popup && popup->client() && (HWND)wParam != popup->popupHandle())
- // Focus is going elsewhere, so hide
- popup->client()->hidePopup();
+ case WM_MOUSEACTIVATE:
+ return MA_NOACTIVATE;
+
+ case WM_SIZE: {
+ if (!scrollbar())
+ break;
+
+ IntSize size(LOWORD(lParam), HIWORD(lParam));
+ scrollbar()->setFrameRect(IntRect(size.width() - scrollbar()->width(), 0, scrollbar()->width(), size.height()));
+
+ int visibleItems = this->visibleItems();
+ scrollbar()->setEnabled(visibleItems < client()->listSize());
+ scrollbar()->setSteps(1, max(1, visibleItems - 1));
+ scrollbar()->setProportion(visibleItems, client()->listSize());
+
break;
+ }
case WM_KEYDOWN:
- if (popup && popup->client()) {
- lResult = 0;
- switch (LOWORD(wParam)) {
- case VK_DOWN:
- case VK_RIGHT:
- popup->down();
- break;
- case VK_UP:
- case VK_LEFT:
- popup->up();
- break;
- case VK_HOME:
- popup->focusFirst();
- break;
- case VK_END:
- popup->focusLast();
- break;
- case VK_PRIOR:
- if (popup->focusedIndex() != popup->scrollOffset()) {
- // Set the selection to the first visible item
- int firstVisibleItem = popup->scrollOffset();
- popup->up(popup->focusedIndex() - firstVisibleItem);
- } else
- // The first visible item is selected, so move the selection back one page
- popup->up(popup->visibleItems());
- break;
- case VK_NEXT:
- if (popup) {
- int lastVisibleItem = popup->scrollOffset() + popup->visibleItems() - 1;
- if (popup->focusedIndex() != lastVisibleItem) {
- // Set the selection to the last visible item
- popup->down(lastVisibleItem - popup->focusedIndex());
- } else
- // The last visible item is selected, so move the selection forward one page
- popup->down(popup->visibleItems());
- }
- break;
- case VK_TAB:
- ::SendMessage(popup->client()->hostWindow()->platformWindow(), message, wParam, lParam);
- popup->client()->hidePopup();
- break;
- case VK_ESCAPE:
- popup->client()->hidePopup();
- break;
- default:
- if (isASCIIPrintable(wParam))
- // Send the keydown to the WebView so it can be used for type-to-select.
- ::PostMessage(popup->client()->hostWindow()->platformWindow(), message, wParam, lParam);
- else
- lResult = 1;
- break;
+ if (!client())
+ break;
+
+ lResult = 0;
+ switch (LOWORD(wParam)) {
+ case VK_DOWN:
+ case VK_RIGHT:
+ down();
+ break;
+ case VK_UP:
+ case VK_LEFT:
+ up();
+ break;
+ case VK_HOME:
+ focusFirst();
+ break;
+ case VK_END:
+ focusLast();
+ break;
+ case VK_PRIOR:
+ if (focusedIndex() != scrollOffset()) {
+ // Set the selection to the first visible item
+ int firstVisibleItem = scrollOffset();
+ up(focusedIndex() - firstVisibleItem);
+ } else {
+ // The first visible item is selected, so move the selection back one page
+ up(visibleItems());
+ }
+ break;
+ case VK_NEXT: {
+ int lastVisibleItem = scrollOffset() + visibleItems() - 1;
+ if (focusedIndex() != lastVisibleItem) {
+ // Set the selection to the last visible item
+ down(lastVisibleItem - focusedIndex());
+ } else {
+ // The last visible item is selected, so move the selection forward one page
+ down(visibleItems());
+ }
+ break;
}
+ case VK_TAB:
+ ::SendMessage(client()->hostWindow()->platformPageClient(), message, wParam, lParam);
+ hide();
+ break;
+ case VK_ESCAPE:
+ hide();
+ break;
+ default:
+ if (isASCIIPrintable(wParam))
+ // Send the keydown to the WebView so it can be used for type-to-select.
+ // Since we know that the virtual key is ASCII printable, it's OK to convert this to
+ // a WM_CHAR message. (We don't want to call TranslateMessage because that will post a
+ // WM_CHAR message that will be stolen and redirected to the popup HWND.
+ ::PostMessage(m_popup, WM_HOST_WINDOW_CHAR, wParam, lParam);
+ else
+ lResult = 1;
+ break;
}
break;
- case WM_CHAR:
- if (popup && popup->client()) {
- lResult = 0;
- int index;
- switch (wParam) {
- case 0x0D: // Enter/Return
- popup->client()->hidePopup();
- index = popup->focusedIndex();
- ASSERT(index >= 0);
- popup->client()->valueChanged(index);
- break;
- case 0x1B: // Escape
- popup->client()->hidePopup();
- break;
- case 0x09: // TAB
- case 0x08: // Backspace
- case 0x0A: // Linefeed
- default: // Character
- lResult = 1;
- break;
- }
+ case WM_CHAR: {
+ if (!client())
+ break;
+
+ lResult = 0;
+ int index;
+ switch (wParam) {
+ case 0x0D: // Enter/Return
+ hide();
+ index = focusedIndex();
+ ASSERT(index >= 0);
+ client()->valueChanged(index);
+ break;
+ case 0x1B: // Escape
+ hide();
+ break;
+ case 0x09: // TAB
+ case 0x08: // Backspace
+ case 0x0A: // Linefeed
+ default: // Character
+ lResult = 1;
+ break;
}
break;
- case WM_MOUSEMOVE:
- if (popup) {
- IntPoint mousePoint(MAKEPOINTS(lParam));
- if (popup->scrollbar()) {
- IntRect scrollBarRect = popup->scrollbar()->frameRect();
- if (popup->scrollbarCapturingMouse() || scrollBarRect.contains(mousePoint)) {
- // Put the point into coordinates relative to the scroll bar
- mousePoint.move(-scrollBarRect.x(), -scrollBarRect.y());
- PlatformMouseEvent event(hWnd, message, wParam, MAKELPARAM(mousePoint.x(), mousePoint.y()));
- popup->scrollbar()->mouseMoved(event);
- break;
- }
+ }
+ case WM_MOUSEMOVE: {
+ IntPoint mousePoint(MAKEPOINTS(lParam));
+ if (scrollbar()) {
+ IntRect scrollBarRect = scrollbar()->frameRect();
+ if (scrollbarCapturingMouse() || scrollBarRect.contains(mousePoint)) {
+ // Put the point into coordinates relative to the scroll bar
+ mousePoint.move(-scrollBarRect.x(), -scrollBarRect.y());
+ PlatformMouseEvent event(hWnd, message, wParam, MAKELPARAM(mousePoint.x(), mousePoint.y()));
+ scrollbar()->mouseMoved(event);
+ break;
}
+ }
- BOOL shouldHotTrack = FALSE;
+ BOOL shouldHotTrack = FALSE;
#if !PLATFORM(WINCE)
- ::SystemParametersInfo(SPI_GETHOTTRACKING, 0, &shouldHotTrack, 0);
+ ::SystemParametersInfo(SPI_GETHOTTRACKING, 0, &shouldHotTrack, 0);
#endif
- RECT bounds;
- GetClientRect(popup->popupHandle(), &bounds);
- if ((shouldHotTrack || wParam & MK_LBUTTON) && ::PtInRect(&bounds, mousePoint))
- popup->setFocusedIndex(popup->listIndexAtPoint(mousePoint), true);
+ RECT bounds;
+ GetClientRect(popupHandle(), &bounds);
+ if (!::PtInRect(&bounds, mousePoint) && !(wParam & MK_LBUTTON) && client()) {
+ // When the mouse is not inside the popup menu and the left button isn't down, just
+ // repost the message to the web view.
- // Release capture if the left button isn't down, and the mousePoint is outside the popup window.
- // This way, the WebView will get future mouse events in the rest of the window.
- if (!(wParam & MK_LBUTTON) && !::PtInRect(&bounds, mousePoint)) {
- ::ReleaseCapture();
- break;
- }
+ // Translate the coordinate.
+ translatePoint(lParam, m_popup, client()->hostWindow()->platformPageClient());
+
+ ::PostMessage(m_popup, WM_HOST_WINDOW_MOUSEMOVE, wParam, lParam);
+ break;
}
+
+ if ((shouldHotTrack || wParam & MK_LBUTTON) && ::PtInRect(&bounds, mousePoint))
+ setFocusedIndex(listIndexAtPoint(mousePoint), true);
+
break;
- case WM_LBUTTONDOWN:
- if (popup) {
- ::SetCapture(popup->popupHandle());
- IntPoint mousePoint(MAKEPOINTS(lParam));
- if (popup->scrollbar()) {
- IntRect scrollBarRect = popup->scrollbar()->frameRect();
- if (scrollBarRect.contains(mousePoint)) {
- // Put the point into coordinates relative to the scroll bar
- mousePoint.move(-scrollBarRect.x(), -scrollBarRect.y());
- PlatformMouseEvent event(hWnd, message, wParam, MAKELPARAM(mousePoint.x(), mousePoint.y()));
- popup->scrollbar()->mouseDown(event);
- popup->setScrollbarCapturingMouse(true);
- break;
- }
+ }
+ case WM_LBUTTONDOWN: {
+ IntPoint mousePoint(MAKEPOINTS(lParam));
+ if (scrollbar()) {
+ IntRect scrollBarRect = scrollbar()->frameRect();
+ if (scrollBarRect.contains(mousePoint)) {
+ // Put the point into coordinates relative to the scroll bar
+ mousePoint.move(-scrollBarRect.x(), -scrollBarRect.y());
+ PlatformMouseEvent event(hWnd, message, wParam, MAKELPARAM(mousePoint.x(), mousePoint.y()));
+ scrollbar()->mouseDown(event);
+ setScrollbarCapturingMouse(true);
+ break;
}
-
- popup->setFocusedIndex(popup->listIndexAtPoint(mousePoint), true);
}
+
+ // If the mouse is inside the window, update the focused index. Otherwise,
+ // hide the popup.
+ RECT bounds;
+ GetClientRect(m_popup, &bounds);
+ if (::PtInRect(&bounds, mousePoint))
+ setFocusedIndex(listIndexAtPoint(mousePoint), true);
+ else
+ hide();
break;
- case WM_LBUTTONUP:
- if (popup) {
- IntPoint mousePoint(MAKEPOINTS(lParam));
- if (popup->scrollbar()) {
- ::ReleaseCapture();
- IntRect scrollBarRect = popup->scrollbar()->frameRect();
- if (popup->scrollbarCapturingMouse() || scrollBarRect.contains(mousePoint)) {
- popup->setScrollbarCapturingMouse(false);
- // Put the point into coordinates relative to the scroll bar
- mousePoint.move(-scrollBarRect.x(), -scrollBarRect.y());
- PlatformMouseEvent event(hWnd, message, wParam, MAKELPARAM(mousePoint.x(), mousePoint.y()));
- popup->scrollbar()->mouseUp();
- // FIXME: This is a hack to work around Scrollbar not invalidating correctly when it doesn't have a parent widget
- RECT r = scrollBarRect;
- ::InvalidateRect(popup->popupHandle(), &r, TRUE);
- break;
- }
- }
- // Only release capture and hide the popup if the mouse is inside the popup window.
- RECT bounds;
- GetClientRect(popup->popupHandle(), &bounds);
- if (popup->client() && ::PtInRect(&bounds, mousePoint)) {
- ::ReleaseCapture();
- popup->client()->hidePopup();
- int index = popup->focusedIndex();
- if (index >= 0)
- popup->client()->valueChanged(index);
+ }
+ case WM_LBUTTONUP: {
+ IntPoint mousePoint(MAKEPOINTS(lParam));
+ if (scrollbar()) {
+ IntRect scrollBarRect = scrollbar()->frameRect();
+ if (scrollbarCapturingMouse() || scrollBarRect.contains(mousePoint)) {
+ setScrollbarCapturingMouse(false);
+ // Put the point into coordinates relative to the scroll bar
+ mousePoint.move(-scrollBarRect.x(), -scrollBarRect.y());
+ PlatformMouseEvent event(hWnd, message, wParam, MAKELPARAM(mousePoint.x(), mousePoint.y()));
+ scrollbar()->mouseUp();
+ // FIXME: This is a hack to work around Scrollbar not invalidating correctly when it doesn't have a parent widget
+ RECT r = scrollBarRect;
+ ::InvalidateRect(popupHandle(), &r, TRUE);
+ break;
}
}
+ // Only hide the popup if the mouse is inside the popup window.
+ RECT bounds;
+ GetClientRect(popupHandle(), &bounds);
+ if (client() && ::PtInRect(&bounds, mousePoint)) {
+ hide();
+ int index = focusedIndex();
+ if (index >= 0)
+ client()->valueChanged(index);
+ }
break;
- case WM_MOUSEWHEEL:
- if (popup && popup->scrollbar()) {
- int i = 0;
- for (popup->incrementWheelDelta(GET_WHEEL_DELTA_WPARAM(wParam)); abs(popup->wheelDelta()) >= WHEEL_DELTA; popup->reduceWheelDelta(WHEEL_DELTA))
- if (popup->wheelDelta() > 0)
- ++i;
- else
- --i;
+ }
+
+ case WM_MOUSEWHEEL: {
+ if (!scrollbar())
+ break;
- popup->scrollbar()->scroll(i > 0 ? ScrollUp : ScrollDown, ScrollByLine, abs(i));
+ int i = 0;
+ for (incrementWheelDelta(GET_WHEEL_DELTA_WPARAM(wParam)); abs(wheelDelta()) >= WHEEL_DELTA; reduceWheelDelta(WHEEL_DELTA)) {
+ if (wheelDelta() > 0)
+ ++i;
+ else
+ --i;
}
+ scrollbar()->scroll(i > 0 ? ScrollUp : ScrollDown, ScrollByLine, abs(i));
break;
- case WM_PAINT:
- if (popup) {
- PAINTSTRUCT paintInfo;
- ::BeginPaint(popup->popupHandle(), &paintInfo);
- popup->paint(paintInfo.rcPaint, paintInfo.hdc);
- ::EndPaint(popup->popupHandle(), &paintInfo);
- lResult = 0;
- }
+ }
+
+ case WM_PAINT: {
+ PAINTSTRUCT paintInfo;
+ ::BeginPaint(popupHandle(), &paintInfo);
+ paint(paintInfo.rcPaint, paintInfo.hdc);
+ ::EndPaint(popupHandle(), &paintInfo);
+ lResult = 0;
break;
+ }
#if !PLATFORM(WINCE)
case WM_PRINTCLIENT:
- if (popup)
- popup->paint(popup->clientRect(), (HDC)wParam);
+ paint(clientRect(), (HDC)wParam);
break;
#endif
default:
diff --git a/WebCore/platform/win/SharedBufferWin.cpp b/WebCore/platform/win/SharedBufferWin.cpp
index ce93402..1839c99 100644
--- a/WebCore/platform/win/SharedBufferWin.cpp
+++ b/WebCore/platform/win/SharedBufferWin.cpp
@@ -38,8 +38,8 @@ PassRefPtr<SharedBuffer> SharedBuffer::createWithContentsOfFile(const String& fi
String nullifiedPath = filePath;
FILE* fileDescriptor = 0;
- if (_wfopen_s(&fileDescriptor, nullifiedPath.charactersWithNullTermination(), TEXT("r+b")) || !fileDescriptor) {
- LOG_ERROR("Failed to open file %s to create shared buffer", filePath.ascii().data());
+ if (_wfopen_s(&fileDescriptor, nullifiedPath.charactersWithNullTermination(), TEXT("rb")) || !fileDescriptor) {
+ LOG_ERROR("Failed to open file %s to create shared buffer, errno(%i)", filePath.ascii().data(), errno);
return 0;
}
diff --git a/WebCore/platform/win/SharedTimerWin.cpp b/WebCore/platform/win/SharedTimerWin.cpp
index da27a53..bc634f9 100644
--- a/WebCore/platform/win/SharedTimerWin.cpp
+++ b/WebCore/platform/win/SharedTimerWin.cpp
@@ -27,6 +27,7 @@
#include "SharedTimer.h"
#include "Page.h"
+#include "Settings.h"
#include "Widget.h"
#include <wtf/Assertions.h>
#include <wtf/CurrentTime.h>
@@ -160,35 +161,38 @@ void setSharedTimerFireTime(double fireTime)
intervalInMS = (unsigned)interval;
}
- if (interval < highResolutionThresholdMsec) {
- if (!highResTimerActive) {
- highResTimerActive = true;
- timeBeginPeriod(timerResolution);
- }
- SetTimer(timerWindowHandle, endHighResTimerID, stopHighResTimerInMsec, 0);
- }
-
initializeOffScreenTimerWindow();
bool timerSet = false;
- DWORD queueStatus = LOWORD(GetQueueStatus(QS_PAINT | QS_MOUSEBUTTON | QS_KEY | QS_RAWINPUT));
-
- // Win32 has a tri-level queue with application messages > user input > WM_PAINT/WM_TIMER.
-
- // If the queue doesn't contains input events, we use a higher priorty timer event posting mechanism.
- if (!(queueStatus & (QS_MOUSEBUTTON | QS_KEY | QS_RAWINPUT))) {
- if (intervalInMS < USER_TIMER_MINIMUM && !processingCustomTimerMessage && !(queueStatus & QS_PAINT)) {
- // Call PostMessage immediately if the timer is already expired, unless a paint is pending.
- // (we prioritize paints over timers)
- if (InterlockedIncrement(&pendingTimers) == 1)
- PostMessage(timerWindowHandle, timerFiredMessage, 0, 0);
- timerSet = true;
- } else {
- // Otherwise, delay the PostMessage via a CreateTimerQueueTimer
- if (!timerQueue)
- timerQueue = CreateTimerQueue();
- if (timer)
- DeleteTimerQueueTimer(timerQueue, timer, 0);
- timerSet = CreateTimerQueueTimer(&timer, timerQueue, queueTimerProc, 0, intervalInMS, 0, WT_EXECUTEINTIMERTHREAD | WT_EXECUTEONLYONCE);
+
+ if (Settings::shouldUseHighResolutionTimers()) {
+ if (interval < highResolutionThresholdMsec) {
+ if (!highResTimerActive) {
+ highResTimerActive = true;
+ timeBeginPeriod(timerResolution);
+ }
+ SetTimer(timerWindowHandle, endHighResTimerID, stopHighResTimerInMsec, 0);
+ }
+
+ DWORD queueStatus = LOWORD(GetQueueStatus(QS_PAINT | QS_MOUSEBUTTON | QS_KEY | QS_RAWINPUT));
+
+ // Win32 has a tri-level queue with application messages > user input > WM_PAINT/WM_TIMER.
+
+ // If the queue doesn't contains input events, we use a higher priorty timer event posting mechanism.
+ if (!(queueStatus & (QS_MOUSEBUTTON | QS_KEY | QS_RAWINPUT))) {
+ if (intervalInMS < USER_TIMER_MINIMUM && !processingCustomTimerMessage && !(queueStatus & QS_PAINT)) {
+ // Call PostMessage immediately if the timer is already expired, unless a paint is pending.
+ // (we prioritize paints over timers)
+ if (InterlockedIncrement(&pendingTimers) == 1)
+ PostMessage(timerWindowHandle, timerFiredMessage, 0, 0);
+ timerSet = true;
+ } else {
+ // Otherwise, delay the PostMessage via a CreateTimerQueueTimer
+ if (!timerQueue)
+ timerQueue = CreateTimerQueue();
+ if (timer)
+ DeleteTimerQueueTimer(timerQueue, timer, 0);
+ timerSet = CreateTimerQueueTimer(&timer, timerQueue, queueTimerProc, 0, intervalInMS, 0, WT_EXECUTEINTIMERTHREAD | WT_EXECUTEONLYONCE);
+ }
}
}
diff --git a/WebCore/platform/wince/CursorWince.cpp b/WebCore/platform/wince/CursorWince.cpp
new file mode 100644
index 0000000..e35f1f9
--- /dev/null
+++ b/WebCore/platform/wince/CursorWince.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2008-2009 Torch Mobile Inc.
+ *
+ * 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 "Cursor.h"
+
+namespace WebCore {
+
+struct AllCursors {
+ AllCursors()
+ {
+ for (int i = 0; i < NumCursorTypes; ++i)
+ m_cursors[i] = (CursorType) i;
+ }
+ Cursor m_cursors[NumCursorTypes];
+};
+
+static const Cursor& getCursor(CursorType type)
+{
+ static AllCursors allCursors;
+ return allCursors.m_cursors[type];
+}
+
+Cursor::Cursor(const Cursor& other)
+: m_impl(other.m_impl)
+{
+}
+
+Cursor::Cursor(Image* img, const IntPoint& hotspot)
+: m_impl(CursorNone)
+{
+}
+
+Cursor::~Cursor()
+{
+}
+
+Cursor& Cursor::operator=(const Cursor& other)
+{
+ m_impl = other.m_impl;
+ return *this;
+}
+
+Cursor::Cursor(PlatformCursor c)
+: m_impl(c)
+{
+}
+
+const Cursor& noneCursor() { return getCursor(CursorNone); }
+const Cursor& pointerCursor() { return getCursor(CursorPointer); }
+const Cursor& crossCursor() { return getCursor(CursorCross); }
+const Cursor& handCursor() { return getCursor(CursorHand); }
+const Cursor& iBeamCursor() { return getCursor(CursorBeam); }
+const Cursor& waitCursor() { return getCursor(CursorWait); }
+const Cursor& helpCursor() { return getCursor(CursorHelp); }
+const Cursor& moveCursor() { return getCursor(CursorMove); }
+const Cursor& eastResizeCursor() { return getCursor(CursorEastResize); }
+const Cursor& northResizeCursor() { return getCursor(CursorNorthResize); }
+const Cursor& northEastResizeCursor() { return getCursor(CursorNorthEastResize); }
+const Cursor& northWestResizeCursor() { return getCursor(CursorNorthWestResize); }
+const Cursor& southResizeCursor() { return getCursor(CursorSouthResize); }
+const Cursor& southEastResizeCursor() { return getCursor(CursorSouthEastResize); }
+const Cursor& southWestResizeCursor() { return getCursor(CursorSouthWestResize); }
+const Cursor& westResizeCursor() { return getCursor(CursorWestResize); }
+const Cursor& northSouthResizeCursor() { return getCursor(CursorNorthSouthResize); }
+const Cursor& eastWestResizeCursor() { return getCursor(CursorEastWestResize); }
+const Cursor& northEastSouthWestResizeCursor() { return getCursor(CursorNorthEastSouthWestResize); }
+const Cursor& northWestSouthEastResizeCursor() { return getCursor(CursorNorthWestSouthEastResize); }
+const Cursor& columnResizeCursor() { return getCursor(CursorColumnResize); }
+const Cursor& rowResizeCursor() { return getCursor(CursorRowResize); }
+const Cursor& verticalTextCursor() { return getCursor(CursorVerticalText); }
+const Cursor& cellCursor() { return getCursor(CursorCell); }
+const Cursor& contextMenuCursor() { return getCursor(CursorContextMenu); }
+const Cursor& noDropCursor() { return getCursor(CursorNoDrop); }
+const Cursor& notAllowedCursor() { return getCursor(CursorNotAllowed); }
+const Cursor& progressCursor() { return getCursor(CursorProgress); }
+const Cursor& aliasCursor() { return getCursor(CursorAlias); }
+const Cursor& zoomInCursor() { return getCursor(CursorZoomIn); }
+const Cursor& zoomOutCursor() { return getCursor(CursorZoomOut); }
+const Cursor& copyCursor() { return getCursor(CursorCopy); }
+const Cursor& middlePanningCursor() { return crossCursor(); }
+const Cursor& eastPanningCursor() { return crossCursor(); }
+const Cursor& northPanningCursor() { return crossCursor(); }
+const Cursor& northEastPanningCursor() { return crossCursor(); }
+const Cursor& northWestPanningCursor() { return crossCursor(); }
+const Cursor& southPanningCursor() { return crossCursor(); }
+const Cursor& southEastPanningCursor() { return crossCursor(); }
+const Cursor& southWestPanningCursor() { return crossCursor(); }
+const Cursor& westPanningCursor() { return crossCursor(); }
+const Cursor& grabbingCursor() { return moveCursor(); }
+const Cursor& grabCursor() { return moveCursor(); }
+
+}
diff --git a/WebCore/platform/wince/DragDataWince.cpp b/WebCore/platform/wince/DragDataWince.cpp
new file mode 100644
index 0000000..881d7d4
--- /dev/null
+++ b/WebCore/platform/wince/DragDataWince.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2007-2008 Torch Mobile, Inc.
+ *
+ * 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 "DragData.h"
+
+#include "Clipboard.h"
+#include "DocumentFragment.h"
+#include "PlatformString.h"
+
+namespace WebCore {
+
+PassRefPtr<Clipboard> DragData::createClipboard(ClipboardAccessPolicy policy) const
+{
+ return 0;
+}
+
+bool DragData::containsURL() const
+{
+ return false;
+}
+
+String DragData::asURL(String* title) const
+{
+ return String();
+}
+
+bool DragData::containsFiles() const
+{
+ return false;
+}
+
+void DragData::asFilenames(Vector<String>&) const
+{
+}
+
+bool DragData::containsPlainText() const
+{
+ return false;
+}
+
+String DragData::asPlainText() const
+{
+ return String();
+}
+
+bool DragData::containsColor() const
+{
+ return false;
+}
+
+bool DragData::canSmartReplace() const
+{
+ return false;
+}
+
+bool DragData::containsCompatibleContent() const
+{
+ return false;
+}
+
+PassRefPtr<DocumentFragment> DragData::asFragment(Document* doc) const
+{
+ return 0;
+}
+
+Color DragData::asColor() const
+{
+ return Color();
+}
+
+}
+
diff --git a/WebCore/platform/wince/DragImageWince.cpp b/WebCore/platform/wince/DragImageWince.cpp
new file mode 100644
index 0000000..4d60f80
--- /dev/null
+++ b/WebCore/platform/wince/DragImageWince.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2007-2008 Torch Mobile, Inc.
+ *
+ * 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 "DragImage.h"
+
+#include "CachedImage.h"
+#include "GraphicsContext.h"
+#include "Image.h"
+
+#include <windows.h>
+
+namespace WebCore {
+
+IntSize dragImageSize(DragImageRef)
+{
+ return IntSize(0, 0);
+}
+
+void deleteDragImage(DragImageRef image)
+{
+ if (image)
+ ::DeleteObject(image);
+}
+
+DragImageRef scaleDragImage(DragImageRef, FloatSize)
+{
+ return 0;
+}
+
+DragImageRef dissolveDragImageToFraction(DragImageRef image, float)
+{
+ return image;
+}
+
+DragImageRef createDragImageFromImage(Image*)
+{
+ return 0;
+}
+
+DragImageRef createDragImageIconForCachedImage(CachedImage*)
+{
+ return 0;
+}
+
+}
diff --git a/WebCore/platform/wince/EditorWince.cpp b/WebCore/platform/wince/EditorWince.cpp
new file mode 100644
index 0000000..02af780
--- /dev/null
+++ b/WebCore/platform/wince/EditorWince.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2007-2008 Torch Mobile, Inc.
+ *
+ * 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 "Editor.h"
+
+#include "ClipboardWince.h"
+#include "Document.h"
+#include "EditorClient.h"
+#include "Element.h"
+#include "HtmlEditing.h"
+#include "TextIterator.h"
+#include "visible_units.h"
+
+#include <windows.h>
+#define _SYS_GUID_OPERATORS_
+
+namespace WebCore {
+
+PassRefPtr<Clipboard> Editor::newGeneralClipboard(ClipboardAccessPolicy policy)
+{
+ return adoptRef(new ClipboardWince(policy, false));
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/wince/FileChooserWince.cpp b/WebCore/platform/wince/FileChooserWince.cpp
new file mode 100644
index 0000000..07c99b1
--- /dev/null
+++ b/WebCore/platform/wince/FileChooserWince.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007-2009 Torch Mobile, Inc.
+ *
+ * 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 "FileChooser.h"
+
+#include "Chrome.h"
+#include "ChromeClient.h"
+#include "Document.h"
+#include "Frame.h"
+#include "Icon.h"
+#include "LocalizedStrings.h"
+#include "Page.h"
+#include "StringTruncator.h"
+
+namespace WebCore {
+
+String pathGetFileName(const String& path);
+
+String FileChooser::basenameForWidth(const Font& font, int width) const
+{
+ if (width <= 0)
+ return String();
+
+ String string;
+ if (m_filenames.isEmpty())
+ string = fileButtonNoFileSelectedLabel();
+ else if (m_filenames.size() == 1) {
+ String tmpFilename = m_filenames[0];
+ string = pathGetFileName(tmpFilename);
+ } else
+ return StringTruncator::rightTruncate(String::number(m_filenames.size()) + " files", width, font, false);
+
+ return StringTruncator::centerTruncate(string, width, font, false);
+}
+
+}
diff --git a/WebCore/platform/wince/FileSystemWince.cpp b/WebCore/platform/wince/FileSystemWince.cpp
new file mode 100644
index 0000000..2bb4dd5
--- /dev/null
+++ b/WebCore/platform/wince/FileSystemWince.cpp
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Collabora, Ltd. All rights reserved.
+ * Copyright (C) 2007-2009 Torch Mobile, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "FileSystem.h"
+
+#include "CString.h"
+#include "PlatformString.h"
+
+#include <windows.h>
+#include <wincrypt.h>
+
+namespace WebCore {
+
+static bool getFileInfo(const String& path, BY_HANDLE_FILE_INFORMATION& fileInfo)
+{
+ String filename = path;
+ HANDLE hFile = CreateFile(filename.charactersWithNullTermination(), GENERIC_READ, FILE_SHARE_READ, 0
+ , OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, 0);
+
+ if (hFile == INVALID_HANDLE_VALUE)
+ return false;
+
+ bool rtn = GetFileInformationByHandle(hFile, &fileInfo) ? true : false;
+
+ CloseHandle(hFile);
+ return rtn;
+}
+
+bool getFileSize(const String& path, long long& result)
+{
+ BY_HANDLE_FILE_INFORMATION fileInformation;
+ if (!getFileInfo(path, fileInformation))
+ return false;
+
+ ULARGE_INTEGER fileSize;
+ fileSize.LowPart = fileInformation.nFileSizeLow;
+ fileSize.HighPart = fileInformation.nFileSizeHigh;
+
+ result = fileSize.QuadPart;
+
+ return true;
+}
+
+bool getFileModificationTime(const String& path, time_t& result)
+{
+ BY_HANDLE_FILE_INFORMATION fileInformation;
+ if (!getFileInfo(path, fileInformation))
+ return false;
+
+ ULARGE_INTEGER t;
+ memcpy(&t, &fileInformation.ftLastWriteTime, sizeof(t));
+
+ result = t.QuadPart * 0.0000001 - 11644473600.0;
+
+ return true;
+}
+
+bool fileExists(const String& path)
+{
+ String filename = path;
+ HANDLE hFile = CreateFile(filename.charactersWithNullTermination(), 0, FILE_SHARE_READ | FILE_SHARE_WRITE
+ , 0, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, 0);
+
+ CloseHandle(hFile);
+
+ return hFile != INVALID_HANDLE_VALUE;
+}
+
+bool deleteFile(const String& path)
+{
+ String filename = path;
+ return !!DeleteFileW(filename.charactersWithNullTermination());
+}
+
+
+bool deleteEmptyDirectory(const String& path)
+{
+ String filename = path;
+ return !!RemoveDirectoryW(filename.charactersWithNullTermination());
+}
+
+String pathByAppendingComponent(const String& path, const String& component)
+{
+ if (component.isEmpty())
+ return path;
+
+ Vector<UChar, MAX_PATH> buffer;
+
+ buffer.append(path.characters(), path.length());
+
+ if (buffer.last() != L'\\' && buffer.last() != L'/'
+ && component[0] != L'\\' && component[0] != L'/')
+ buffer.append(L'\\');
+
+ buffer.append(component.characters(), component.length());
+
+ return String(buffer.data(), buffer.size());
+}
+
+CString fileSystemRepresentation(const String&)
+{
+ return "";
+}
+
+bool makeAllDirectories(const String& path)
+{
+ int lastDivPos = max(path.reverseFind('/'), path.reverseFind('\\'));
+ int endPos = path.length();
+ if (lastDivPos == path.length() - 1) {
+ endPos -= 1;
+ lastDivPos = max(path.reverseFind('/', lastDivPos), path.reverseFind('\\', lastDivPos));
+ }
+
+ if (lastDivPos > 0) {
+ if (!makeAllDirectories(path.substring(0, lastDivPos)))
+ return false;
+ }
+
+ String folder(path.substring(0, endPos));
+ CreateDirectory(folder.charactersWithNullTermination(), 0);
+
+ DWORD fileAttr = GetFileAttributes(folder.charactersWithNullTermination());
+ return fileAttr != 0xFFFFFFFF && (fileAttr & FILE_ATTRIBUTE_DIRECTORY);
+}
+
+String homeDirectoryPath()
+{
+ notImplemented();
+ return "";
+}
+
+String pathGetFileName(const String& path)
+{
+ return path.substring(max(path.reverseFind('/'), path.reverseFind('\\')) + 1);
+}
+
+String directoryName(const String& path)
+{
+ notImplemented();
+ return String();
+}
+
+CString openTemporaryFile(const char*, PlatformFileHandle& handle)
+{
+ handle = INVALID_HANDLE_VALUE;
+
+ wchar_t tempPath[MAX_PATH];
+ int tempPathLength = ::GetTempPath(_countof(tempPath), tempPath);
+ if (tempPathLength <= 0 || tempPathLength > _countof(tempPath))
+ return CString();
+
+ HCRYPTPROV hCryptProv = 0;
+ if (!CryptAcquireContext(&hCryptProv, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
+ return CString();
+
+ String proposedPath;
+ while (1) {
+
+ wchar_t tempFile[] = L"XXXXXXXX.tmp"; // Use 8.3 style name (more characters aren't helpful due to 8.3 short file names)
+ const int randomPartLength = 8;
+ if (!CryptGenRandom(hCryptProv, randomPartLength * 2, reinterpret_cast<BYTE*>(tempFile)))
+ break;
+
+ // Limit to valid filesystem characters, also excluding others that could be problematic, like punctuation.
+ // don't include both upper and lowercase since Windows file systems are typically not case sensitive.
+ const char validChars[] = "0123456789abcdefghijklmnopqrstuvwxyz";
+ for (int i = 0; i < randomPartLength; ++i)
+ tempFile[i] = validChars[tempFile[i] % (sizeof(validChars) - 1)];
+
+ ASSERT(wcslen(tempFile) * 2 == sizeof(tempFile) - 2);
+
+ proposedPath = pathByAppendingComponent(String(tempPath), String(tempFile));
+
+ // use CREATE_NEW to avoid overwriting an existing file with the same name
+ handle = CreateFile(proposedPath.charactersWithNullTermination(), GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0);
+ if (!isHandleValid(handle) && GetLastError() == ERROR_ALREADY_EXISTS)
+ continue;
+
+ break;
+ }
+
+ CryptReleaseContext(hCryptProv, 0);
+
+ if (!isHandleValid(handle))
+ return CString();
+
+ return proposedPath.latin1();
+}
+
+void closeFile(PlatformFileHandle& handle)
+{
+ if (isHandleValid(handle)) {
+ ::CloseHandle(handle);
+ handle = invalidPlatformFileHandle;
+ }
+}
+
+int writeToFile(PlatformFileHandle handle, const char* data, int length)
+{
+ if (!isHandleValid(handle))
+ return -1;
+
+ DWORD bytesWritten;
+ bool success = WriteFile(handle, data, length, &bytesWritten, 0);
+
+ if (!success)
+ return -1;
+ return static_cast<int>(bytesWritten);
+}
+
+bool unloadModule(PlatformModule module)
+{
+ return ::FreeLibrary(module);
+}
+
+String localUserSpecificStorageDirectory()
+{
+ return String(L"\\");
+}
+
+String roamingUserSpecificStorageDirectory()
+{
+ return String(L"\\");
+}
+
+Vector<String> listDirectory(const String& path, const String& filter)
+{
+ Vector<String> entries;
+
+ Vector<UChar, 256> pattern;
+ pattern.append(path.characters(), path.length());
+ if (pattern.last() != L'/' && pattern.last() != L'\\')
+ pattern.append(L'\\');
+
+ String root(pattern.data(), pattern.size());
+ pattern.append(filter.characters(), filter.length());
+ pattern.append(0);
+
+ WIN32_FIND_DATA findData;
+ HANDLE hFind = FindFirstFile(pattern.data(), &findData);
+ if (INVALID_HANDLE_VALUE != hFind) {
+ do {
+ // FIXEME: should we also add the folders? This function
+ // is so far only called by PluginDatabase.cpp to list
+ // all plugins in a folder, where it's not supposed to list sub-folders.
+ if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
+ entries.append(root + findData.cFileName);
+ } while (FindNextFile(hFind, &findData));
+ FindClose(hFind);
+ }
+
+ return entries;
+}
+
+}
diff --git a/WebCore/platform/wince/KURLWince.cpp b/WebCore/platform/wince/KURLWince.cpp
new file mode 100644
index 0000000..5ca1e4b
--- /dev/null
+++ b/WebCore/platform/wince/KURLWince.cpp
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2009 Torch Mobile Inc.
+ *
+ * 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 "KURL.h"
+
+namespace WebCore {
+
+String KURL::fileSystemPath() const
+{
+ return path();
+}
+
+}
diff --git a/WebCore/platform/wince/KeygenWince.cpp b/WebCore/platform/wince/KeygenWince.cpp
new file mode 100644
index 0000000..b0f4d63
--- /dev/null
+++ b/WebCore/platform/wince/KeygenWince.cpp
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2008-2009 Torch Mobile Inc.
+ *
+ * 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 "SSLKeyGenerator.h"
+
+#include "Base64.h"
+#include "CString.h"
+
+#include <windows.h>
+#include <wincrypt.h>
+
+namespace WebCore {
+
+void WebCore::getSupportedKeySizes(Vector<String>& v)
+{
+ v.append("High Grade");
+ v.append("Medium Grade");
+}
+
+String WebCore::signedPublicKeyAndChallengeString(unsigned index, const String& challenge, const KURL& url)
+{
+ String keyString;
+
+ HCRYPTPROV hContext = 0;
+ HCRYPTKEY hKey = 0;
+ PCERT_PUBLIC_KEY_INFO pPubInfo = 0;
+
+ // Try to delete it if it exists already
+ CryptAcquireContext(&hContext, _T("keygen_container"), MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
+
+ do {
+ if (!CryptAcquireContext(&hContext, _T("keygen_container"), MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET))
+ break;
+
+ DWORD dwPubInfoLength = 0;
+ if (!CryptGenKey(hContext, AT_KEYEXCHANGE, 0, &hKey) || !CryptExportPublicKeyInfo(hContext, AT_KEYEXCHANGE, X509_ASN_ENCODING, 0, &dwPubInfoLength))
+ break;
+
+ // Use malloc instead of new, because malloc guarantees to return a pointer aligned for all data types.
+ pPubInfo = reinterpret_cast<PCERT_PUBLIC_KEY_INFO>(fastMalloc(dwPubInfoLength));
+
+ if (!CryptExportPublicKeyInfo(hContext, AT_KEYEXCHANGE, X509_ASN_ENCODING, pPubInfo, &dwPubInfoLength))
+ break;
+
+ CERT_KEYGEN_REQUEST_INFO requestInfo = { 0 };
+ requestInfo.dwVersion = CERT_KEYGEN_REQUEST_V1;
+ requestInfo.pwszChallengeString = L"";
+ requestInfo.SubjectPublicKeyInfo = *pPubInfo;
+
+ String localChallenge = challenge;
+
+ // Windows API won't write to our buffer, although it's not declared with const.
+ requestInfo.pwszChallengeString = const_cast<wchar_t*>(localChallenge.charactersWithNullTermination());
+
+ CRYPT_ALGORITHM_IDENTIFIER signAlgo = { 0 };
+ signAlgo.pszObjId = szOID_RSA_SHA1RSA;
+
+ DWORD dwEncodedLength;
+ if (!CryptSignAndEncodeCertificate(hContext, AT_KEYEXCHANGE, X509_ASN_ENCODING, X509_KEYGEN_REQUEST_TO_BE_SIGNED, &requestInfo, &signAlgo, 0, 0, &dwEncodedLength))
+ break;
+
+ Vector<char> binary(dwEncodedLength);
+ if (!CryptSignAndEncodeCertificate(hContext, AT_KEYEXCHANGE, X509_ASN_ENCODING, X509_KEYGEN_REQUEST_TO_BE_SIGNED, &requestInfo, &signAlgo, 0, reinterpret_cast<LPBYTE>(binary.data()), &dwEncodedLength))
+ break;
+
+ Vector<char> base64;
+ base64Encode(binary, base64);
+ keyString = String(base64.data(), base64.size());
+
+ } while(0);
+
+ if (pPubInfo)
+ fastFree(pPubInfo);
+
+ if (hKey)
+ CryptDestroyKey(hKey);
+
+ if (hContext)
+ CryptReleaseContext(hContext, 0);
+
+ return keyString;
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/wince/MIMETypeRegistryWince.cpp b/WebCore/platform/wince/MIMETypeRegistryWince.cpp
new file mode 100644
index 0000000..2ecde48
--- /dev/null
+++ b/WebCore/platform/wince/MIMETypeRegistryWince.cpp
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007-2009 Torch Mobile, Inc.
+ *
+ * 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 "MIMETypeRegistry.h"
+
+#include <windows.h>
+#include <winreg.h>
+
+namespace WebCore {
+
+static String mimeTypeForExtension(const String& extension)
+{
+ String ext = "." + extension;
+ WCHAR contentTypeStr[256];
+ DWORD contentTypeStrLen = sizeof(contentTypeStr);
+ DWORD valueType;
+
+ HKEY key;
+ String result;
+ if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_CLASSES_ROOT, ext.charactersWithNullTermination(), 0, 0, &key))
+ return result;
+
+ if (ERROR_SUCCESS == RegQueryValueEx(key, L"Content Type", 0, &valueType, (LPBYTE)contentTypeStr, &contentTypeStrLen) && valueType == REG_SZ)
+ result = String(contentTypeStr, contentTypeStrLen / sizeof(contentTypeStr[0]) - 1);
+
+ RegCloseKey(key);
+
+ return result;
+}
+
+static HashMap<String, String> mimetypeMap;
+
+static void initMIMETypeEntensionMap()
+{
+ if (mimetypeMap.isEmpty()) {
+ //fill with initial values
+ mimetypeMap.add("txt", "text/plain");
+ mimetypeMap.add("pdf", "application/pdf");
+ mimetypeMap.add("ps", "application/postscript");
+ mimetypeMap.add("html", "text/html");
+ mimetypeMap.add("htm", "text/html");
+ mimetypeMap.add("xml", "text/xml");
+ mimetypeMap.add("xsl", "text/xsl");
+ mimetypeMap.add("js", "application/x-javascript");
+ mimetypeMap.add("xhtml", "application/xhtml+xml");
+ mimetypeMap.add("rss", "application/rss+xml");
+ mimetypeMap.add("webarchive", "application/x-webarchive");
+ mimetypeMap.add("svg", "image/svg+xml");
+ mimetypeMap.add("svgz", "image/svg+xml");
+ mimetypeMap.add("jpg", "image/jpeg");
+ mimetypeMap.add("jpeg", "image/jpeg");
+ mimetypeMap.add("png", "image/png");
+ mimetypeMap.add("tif", "image/tiff");
+ mimetypeMap.add("tiff", "image/tiff");
+ mimetypeMap.add("ico", "image/ico");
+ mimetypeMap.add("cur", "image/ico");
+ mimetypeMap.add("bmp", "image/bmp");
+ mimetypeMap.add("css", "text/css");
+ // FIXME: Custom font works only when MIME is "text/plain"
+ mimetypeMap.add("ttf", "text/plain"); // "font/ttf"
+ mimetypeMap.add("otf", "text/plain"); // "font/otf"
+#if ENABLE(WML)
+ mimetypeMap.add("wml", "text/vnd.wap.wml");
+#endif
+#if ENABLE(WBXML)
+ mimetypeMap.add("wbxml", "application/vnd.wap.wmlc");
+#endif
+ }
+}
+
+String MIMETypeRegistry::getPreferredExtensionForMIMEType(const String& type)
+{
+ if (type.isEmpty())
+ return String();
+
+ // Avoid conflicts with "ttf" and "otf"
+ if (equalIgnoringCase(type, "text/plain"))
+ return "txt";
+
+ initMIMETypeEntensionMap();
+
+ for (HashMap<String, String>::iterator i = mimetypeMap.begin(); i != mimetypeMap.end(); ++i) {
+ if (equalIgnoringCase(i->second, type))
+ return i->first;
+ }
+
+#if ENABLE(XHTMLMP)
+ if (equalIgnoringCase("application/vnd.wap.xhtml+xml", type))
+ return String("xml");
+#endif
+
+ return String();
+}
+
+String MIMETypeRegistry::getMIMETypeForExtension(const String &ext)
+{
+ if (ext.isEmpty())
+ return String();
+
+ initMIMETypeEntensionMap();
+
+ String result = mimetypeMap.get(ext.lower());
+ if (result.isEmpty()) {
+ result = mimeTypeForExtension(ext);
+ if (!result.isEmpty())
+ mimetypeMap.add(ext, result);
+ }
+ return result.isEmpty() ? "unknown/unknown" : result;
+}
+
+}
diff --git a/WebCore/platform/wince/PasteboardWince.cpp b/WebCore/platform/wince/PasteboardWince.cpp
new file mode 100644
index 0000000..16f4968
--- /dev/null
+++ b/WebCore/platform/wince/PasteboardWince.cpp
@@ -0,0 +1,330 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007-2009 Torch Mobile, Inc.
+ *
+ * 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 "Pasteboard.h"
+
+#include "CString.h"
+#include "ClipboardUtilitiesWin.h"
+#include "Document.h"
+#include "DocumentFragment.h"
+#include "Element.h"
+#include "Frame.h"
+#include "HitTestResult.h"
+#include "Image.h"
+#include "KURL.h"
+#include "Page.h"
+#include "Range.h"
+#include "RenderImage.h"
+#include "TextEncoding.h"
+#include "markup.h"
+
+namespace WebCore {
+
+static UINT HTMLClipboardFormat = 0;
+static UINT BookmarkClipboardFormat = 0;
+static UINT WebSmartPasteFormat = 0;
+
+extern HDC hScreenDC;
+
+static LRESULT CALLBACK PasteboardOwnerWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ LRESULT lresult = 0;
+ LONG longPtr = GetWindowLong(hWnd, 0);
+
+ switch (message) {
+ case WM_RENDERFORMAT:
+ // This message comes when SetClipboardData was sent a null data handle
+ // and now it's come time to put the data on the clipboard.
+ break;
+ case WM_RENDERALLFORMATS:
+ // This message comes when SetClipboardData was sent a null data handle
+ // and now this application is about to quit, so it must put data on
+ // the clipboard before it exits.
+ break;
+ case WM_DESTROY:
+ break;
+ default:
+ lresult = DefWindowProc(hWnd, message, wParam, lParam);
+ break;
+ }
+ return lresult;
+}
+
+Pasteboard* Pasteboard::generalPasteboard()
+{
+ static Pasteboard* pasteboard = new Pasteboard;
+ return pasteboard;
+}
+
+Pasteboard::Pasteboard()
+{
+ // make a dummy HWND to be the Windows clipboard's owner
+ WNDCLASS wc = {0};
+ memset(&wc, 0, sizeof(wc));
+ wc.lpfnWndProc = PasteboardOwnerWndProc;
+ wc.hInstance = Page::instanceHandle();
+ wc.lpszClassName = L"PasteboardOwnerWindowClass";
+ ::RegisterClass(&wc);
+
+ m_owner = ::CreateWindow(L"PasteboardOwnerWindowClass", L"PasteboardOwnerWindow", 0, 0, 0, 0, 0,
+ HWND_MESSAGE, 0, 0, 0);
+
+ HTMLClipboardFormat = ::RegisterClipboardFormat(L"HTML Format");
+ BookmarkClipboardFormat = ::RegisterClipboardFormat(L"UniformResourceLocatorW");
+ WebSmartPasteFormat = ::RegisterClipboardFormat(L"WebKit Smart Paste Format");
+}
+
+void Pasteboard::clear()
+{
+ if (::OpenClipboard(m_owner)) {
+ ::EmptyClipboard();
+ ::CloseClipboard();
+ }
+}
+
+void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete, Frame* frame)
+{
+ clear();
+
+ // Put CF_HTML format on the pasteboard
+ if (::OpenClipboard(m_owner)) {
+ ExceptionCode ec = 0;
+ Vector<char> data;
+ markupToCF_HTML(createMarkup(selectedRange, 0, AnnotateForInterchange), selectedRange->startContainer(ec)->document()->url(), data);
+ HGLOBAL cbData = createGlobalData(data);
+ if (!::SetClipboardData(HTMLClipboardFormat, cbData))
+ ::GlobalFree(cbData);
+ ::CloseClipboard();
+ }
+
+ // Put plain string on the pasteboard. CF_UNICODETEXT covers CF_TEXT as well
+ String str = frame->selectedText();
+ replaceNewlinesWithWindowsStyleNewlines(str);
+ replaceNBSPWithSpace(str);
+ if (::OpenClipboard(m_owner)) {
+ HGLOBAL cbData = createGlobalData(str);
+ if (!::SetClipboardData(CF_UNICODETEXT, cbData))
+ ::GlobalFree(cbData);
+ ::CloseClipboard();
+ }
+
+ // enable smart-replacing later on by putting dummy data on the pasteboard
+ if (canSmartCopyOrDelete) {
+ if (::OpenClipboard(m_owner)) {
+ ::SetClipboardData(WebSmartPasteFormat, 0);
+ ::CloseClipboard();
+ }
+ }
+}
+
+void Pasteboard::writePlainText(const String& text)
+{
+ clear();
+
+ // Put plain string on the pasteboard. CF_UNICODETEXT covers CF_TEXT as well
+ String str = text;
+ replaceNewlinesWithWindowsStyleNewlines(str);
+ if (::OpenClipboard(m_owner)) {
+ HGLOBAL cbData = createGlobalData(str);
+ if (!::SetClipboardData(CF_UNICODETEXT, cbData))
+ ::GlobalFree(cbData);
+ ::CloseClipboard();
+ }
+}
+
+void Pasteboard::writeURL(const KURL& url, const String& titleStr, Frame* frame)
+{
+ ASSERT(!url.isEmpty());
+
+ clear();
+
+ String title(titleStr);
+ if (title.isEmpty()) {
+ title = url.lastPathComponent();
+ if (title.isEmpty())
+ title = url.host();
+ }
+
+ // write to clipboard in format com.apple.safari.bookmarkdata to be able to paste into the bookmarks view with appropriate title
+ if (::OpenClipboard(m_owner)) {
+ HGLOBAL cbData = createGlobalData(url, title);
+ if (!::SetClipboardData(BookmarkClipboardFormat, cbData))
+ ::GlobalFree(cbData);
+ ::CloseClipboard();
+ }
+
+ // write to clipboard in format CF_HTML to be able to paste into contenteditable areas as a link
+ if (::OpenClipboard(m_owner)) {
+ Vector<char> data;
+ markupToCF_HTML(urlToMarkup(url, title), "", data);
+ HGLOBAL cbData = createGlobalData(data);
+ if (!::SetClipboardData(HTMLClipboardFormat, cbData))
+ ::GlobalFree(cbData);
+ ::CloseClipboard();
+ }
+
+ // bare-bones CF_UNICODETEXT support
+ if (::OpenClipboard(m_owner)) {
+ HGLOBAL cbData = createGlobalData(url.string());
+ if (!::SetClipboardData(CF_UNICODETEXT, cbData))
+ ::GlobalFree(cbData);
+ ::CloseClipboard();
+ }
+}
+
+void Pasteboard::writeImage(Node* node, const KURL&, const String&)
+{
+ ASSERT(node && node->renderer() && node->renderer()->isImage());
+ RenderImage* renderer = static_cast<RenderImage*>(node->renderer());
+ CachedImage* cachedImage = static_cast<CachedImage*>(renderer->cachedImage());
+ ASSERT(cachedImage);
+ Image* image = cachedImage->image();
+ ASSERT(image);
+
+ clear();
+
+ RefPtr<SharedBitmap> sourceBmp = image->nativeImageForCurrentFrame();
+ if (!sourceBmp)
+ return;
+
+ IntRect rect(0, 0, sourceBmp->width(), sourceBmp->height());
+ BitmapInfo bmpInfo;
+ void* pixels;
+ HBITMAP resultBitmap = sourceBmp->clipBitmap(rect, true, bmpInfo, pixels);
+ if (!resultBitmap)
+ return;
+
+ if (::OpenClipboard(m_owner)) {
+ ::SetClipboardData(CF_BITMAP, resultBitmap);
+ ::CloseClipboard();
+ } else
+ DeleteObject(resultBitmap);
+}
+
+bool Pasteboard::canSmartReplace()
+{
+ return ::IsClipboardFormatAvailable(WebSmartPasteFormat);
+}
+
+String Pasteboard::plainText(Frame* frame)
+{
+ if (::IsClipboardFormatAvailable(CF_UNICODETEXT) && ::OpenClipboard(m_owner)) {
+ HANDLE cbData = ::GetClipboardData(CF_UNICODETEXT);
+ if (cbData) {
+ UChar* buffer = (UChar*)GlobalLock(cbData);
+ String fromClipboard(buffer);
+ GlobalUnlock(cbData);
+ CloseClipboard();
+ return fromClipboard;
+ } else
+ CloseClipboard();
+ }
+
+ if (::IsClipboardFormatAvailable(CF_TEXT) && ::OpenClipboard(m_owner)) {
+ HANDLE cbData = ::GetClipboardData(CF_TEXT);
+ if (cbData) {
+ char* buffer = (char*)GlobalLock(cbData);
+ String fromClipboard(buffer);
+ GlobalUnlock(cbData);
+ CloseClipboard();
+ return fromClipboard;
+ } else
+ CloseClipboard();
+ }
+
+ return String();
+}
+
+PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefPtr<Range> context, bool allowPlainText, bool& chosePlainText)
+{
+ chosePlainText = false;
+
+ if (::IsClipboardFormatAvailable(HTMLClipboardFormat) && ::OpenClipboard(m_owner)) {
+ // get data off of clipboard
+ HANDLE cbData = ::GetClipboardData(HTMLClipboardFormat);
+ if (cbData) {
+ SIZE_T dataSize = ::GlobalSize(cbData);
+ String cf_html(UTF8Encoding().decode((char*)GlobalLock(cbData), dataSize));
+ GlobalUnlock(cbData);
+ CloseClipboard();
+
+ PassRefPtr<DocumentFragment> fragment = fragmentFromCF_HTML(frame->document(), cf_html);
+ if (fragment)
+ return fragment;
+ } else
+ CloseClipboard();
+ }
+
+ if (allowPlainText && IsClipboardFormatAvailable(CF_UNICODETEXT)) {
+ chosePlainText = true;
+ if (OpenClipboard(m_owner)) {
+ HANDLE cbData = GetClipboardData(CF_UNICODETEXT);
+ if (cbData) {
+ UChar* buffer = (UChar*)GlobalLock(cbData);
+ String str(buffer);
+ GlobalUnlock(cbData);
+ CloseClipboard();
+ RefPtr<DocumentFragment> fragment = createFragmentFromText(context.get(), str);
+ if (fragment)
+ return fragment.release();
+ } else
+ CloseClipboard();
+ }
+ }
+
+ if (allowPlainText && ::IsClipboardFormatAvailable(CF_TEXT)) {
+ chosePlainText = true;
+ if (::OpenClipboard(m_owner)) {
+ HANDLE cbData = ::GetClipboardData(CF_TEXT);
+ if (cbData) {
+ char* buffer = (char*)GlobalLock(cbData);
+ String str(buffer);
+ GlobalUnlock(cbData);
+ CloseClipboard();
+ RefPtr<DocumentFragment> fragment = createFragmentFromText(context.get(), str);
+ if (fragment)
+ return fragment.release();
+ } else
+ CloseClipboard();
+ }
+ }
+
+ return 0;
+}
+
+bool Pasteboard::hasData()
+{
+ return hasDataInFormat(CF_UNICODETEXT) || hasDataInFormat(CF_TEXT);
+}
+
+bool Pasteboard::hasDataInFormat(unsigned int format)
+{
+ return ::IsClipboardFormatAvailable(format);
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/wince/SearchPopupMenuWince.cpp b/WebCore/platform/wince/SearchPopupMenuWince.cpp
new file mode 100644
index 0000000..ca11292
--- /dev/null
+++ b/WebCore/platform/wince/SearchPopupMenuWince.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2009 Torch Mobile Inc.
+ *
+ * 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 "SearchPopupMenu.h"
+
+#include "AtomicString.h"
+
+namespace WebCore {
+
+SearchPopupMenu::SearchPopupMenu(PopupMenuClient* client)
+: PopupMenu(client)
+{
+}
+
+bool SearchPopupMenu::enabled()
+{
+ return false;
+}
+
+void SearchPopupMenu::saveRecentSearches(const AtomicString& name, const Vector<String>& searchItems)
+{
+ if (name.isEmpty())
+ return;
+
+ notImplemented();
+}
+
+void SearchPopupMenu::loadRecentSearches(const AtomicString& name, Vector<String>& searchItems)
+{
+ if (name.isEmpty())
+ return;
+
+ notImplemented();
+}
+
+}
diff --git a/WebCore/platform/wince/SharedTimerWince.cpp b/WebCore/platform/wince/SharedTimerWince.cpp
new file mode 100644
index 0000000..ca2f104
--- /dev/null
+++ b/WebCore/platform/wince/SharedTimerWince.cpp
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2007-2008 Torch Mobile, Inc.
+ *
+ * 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 "SharedTimer.h"
+
+#include "Page.h"
+#include "SystemTime.h"
+#include "Widget.h"
+#include <wtf/Assertions.h>
+#include <wtf/CurrentTime.h>
+#include <windows.h>
+
+namespace JSC {
+extern void* g_stackBase;
+}
+
+namespace WebCore {
+
+enum {
+ TimerIdNone = 0,
+ TimerIdAuto,
+ TimerIdManual,
+};
+static UINT timerID = TimerIdNone;
+
+static void (*sharedTimerFiredFunction)();
+
+static HWND timerWindowHandle = 0;
+const LPCWSTR kTimerWindowClassName = L"TimerWindowClass";
+
+LRESULT CALLBACK TimerWindowWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ int dummy;
+ JSC::g_stackBase = &dummy;
+
+ if (message == WM_TIMER) {
+ if (timerID != TimerIdNone)
+ sharedTimerFiredFunction();
+ } else if (message == WM_USER) {
+ if (timerID = TimerIdManual) {
+ sharedTimerFiredFunction();
+ PostMessage(hWnd, WM_USER, 0, 0);
+ }
+ } else {
+ JSC::g_stackBase = 0;
+ return DefWindowProc(hWnd, message, wParam, lParam);
+ }
+ JSC::g_stackBase = 0;
+ return 0;
+}
+
+static void initializeOffScreenTimerWindow()
+{
+ if (timerWindowHandle)
+ return;
+
+ WNDCLASS wcex = {0};
+ wcex.lpfnWndProc = TimerWindowWndProc;
+ wcex.hInstance = Page::instanceHandle();
+ wcex.lpszClassName = kTimerWindowClassName;
+ RegisterClass(&wcex);
+
+ timerWindowHandle = CreateWindow(kTimerWindowClassName, 0, 0,
+ CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, HWND_MESSAGE, 0, Page::instanceHandle(), 0);
+}
+
+void setSharedTimerFiredFunction(void (*f)())
+{
+ sharedTimerFiredFunction = f;
+}
+
+#define USER_TIMER_MAXIMUM 0x7FFFFFFF
+#define USER_TIMER_MINIMUM 0x0000000A
+
+void setSharedTimerFireTime(double fireTime)
+{
+ ASSERT(sharedTimerFiredFunction);
+
+ double interval = (fireTime - currentTime()) * 1000.;
+ unsigned intervalInMS = interval < USER_TIMER_MINIMUM
+ ? USER_TIMER_MINIMUM
+ : interval > USER_TIMER_MAXIMUM
+ ? USER_TIMER_MAXIMUM
+ : static_cast<unsigned>(interval);
+
+ if (timerID == TimerIdAuto) {
+ KillTimer(timerWindowHandle, TimerIdAuto);
+ timerID = TimerIdNone;
+ }
+
+ initializeOffScreenTimerWindow();
+ if (SetTimer(timerWindowHandle, TimerIdAuto, intervalInMS, 0))
+ timerID = TimerIdAuto;
+ else if (timerID != TimerIdManual)
+ PostMessage(timerWindowHandle, WM_USER, 0, 0);
+}
+
+void stopSharedTimer()
+{
+ if (timerID == TimerIdAuto)
+ KillTimer(timerWindowHandle, TimerIdAuto);
+
+ timerID = TimerIdNone;
+}
+
+}
diff --git a/WebCore/platform/wince/SystemTimeWince.cpp b/WebCore/platform/wince/SystemTimeWince.cpp
new file mode 100644
index 0000000..70b705b
--- /dev/null
+++ b/WebCore/platform/wince/SystemTimeWince.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2007-2008 Torch Mobile, Inc.
+ *
+ * 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 "SystemTime.h"
+
+#include <windows.h>
+
+namespace WebCore {
+
+float userIdleTime()
+{
+ return FLT_MAX;
+}
+
+}
diff --git a/WebCore/platform/wx/CursorWx.cpp b/WebCore/platform/wx/CursorWx.cpp
index 7175b01..ed7f86b 100644
--- a/WebCore/platform/wx/CursorWx.cpp
+++ b/WebCore/platform/wx/CursorWx.cpp
@@ -298,4 +298,10 @@ const Cursor& grabbingCursor()
return pointerCursor();
}
+const Cursor& moveCursor()
+{
+ static Cursor c = new wxCursor(wxCURSOR_SIZING);
+ return c;
+}
+
}
diff --git a/WebCore/platform/wx/FileChooserWx.cpp b/WebCore/platform/wx/FileChooserWx.cpp
new file mode 100644
index 0000000..34065f3
--- /dev/null
+++ b/WebCore/platform/wx/FileChooserWx.cpp
@@ -0,0 +1,40 @@
+/*
+ * 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 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 "FileChooser.h"
+
+#include "NotImplemented.h"
+
+namespace WebCore {
+
+String FileChooser::basenameForWidth(const Font&, int width) const
+{
+ notImplemented();
+ return String();
+}
+
+}
+
diff --git a/WebCore/platform/wx/FileSystemWx.cpp b/WebCore/platform/wx/FileSystemWx.cpp
index 7de425e..109278f 100644
--- a/WebCore/platform/wx/FileSystemWx.cpp
+++ b/WebCore/platform/wx/FileSystemWx.cpp
@@ -40,50 +40,50 @@ namespace WebCore {
bool fileExists(const String& path)
{
- notImplemented();
- return true;
+ return wxFileName::FileExists(path);
}
bool deleteFile(const String& path)
{
- notImplemented();
- return false;
+ return wxRemoveFile(path);
}
bool deleteEmptyDirectory(const String& path)
{
- notImplemented();
- return false;
+ return wxFileName::Rmdir(path);
}
bool getFileSize(const String& path, long long& resultSize)
{
- notImplemented();
+ wxULongLong size = wxFileName::GetSize(path);
+ if (wxInvalidSize != size) {
+ // TODO: why is FileSystem::getFileSize signed?
+ resultSize = (long long)size.GetValue();
+ return true;
+ }
+
return false;
}
-bool getFileModificationTime(const String&, time_t&)
+bool getFileModificationTime(const String& path, time_t& t)
{
- notImplemented();
- return false;
+ t = wxFileName(path).GetModificationTime().GetTicks();
+ return true;
}
bool makeAllDirectories(const String& path)
{
- notImplemented();
- return false;
+ return wxFileName::Mkdir(path, 0777, wxPATH_MKDIR_FULL);
}
String pathByAppendingComponent(const String& path, const String& component)
{
- notImplemented();
- return String();
+ return wxFileName(path, component).GetFullPath();
}
String homeDirectoryPath()
{
- notImplemented();
- return String();
+ return wxFileName::GetHomeDir();
}
String pathGetFileName(const String& path)
@@ -93,8 +93,7 @@ String pathGetFileName(const String& path)
String directoryName(const String& path)
{
- notImplemented();
- return String();
+ return wxFileName(path).GetPath();
}
CString openTemporaryFile(const char* prefix, PlatformFileHandle& handle)
diff --git a/WebCore/platform/wx/KURLWx.cpp b/WebCore/platform/wx/KURLWx.cpp
new file mode 100644
index 0000000..a2be103
--- /dev/null
+++ b/WebCore/platform/wx/KURLWx.cpp
@@ -0,0 +1,40 @@
+/*
+ * 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 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 "KURL.h"
+
+#include "NotImplemented.h"
+
+namespace WebCore {
+
+String KURL::fileSystemPath() const
+{
+ notImplemented();
+ return String();
+}
+
+}
+
diff --git a/WebCore/platform/wx/PasteboardWx.cpp b/WebCore/platform/wx/PasteboardWx.cpp
index 67697de..207c63c 100644
--- a/WebCore/platform/wx/PasteboardWx.cpp
+++ b/WebCore/platform/wx/PasteboardWx.cpp
@@ -52,13 +52,20 @@ Pasteboard* Pasteboard::generalPasteboard()
void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete, Frame* frame)
{
- if (wxTheClipboard->Open())
- {
+ if (wxTheClipboard->Open()) {
wxTheClipboard->SetData( new wxTextDataObject(frame->selectedText()) );
wxTheClipboard->Close();
}
}
+void Pasteboard::writePlainText(const String& text)
+{
+ if (wxTheClipboard->Open()) {
+ wxTheClipboard->SetData( new wxTextDataObject(text) );
+ wxTheClipboard->Close();
+ }
+}
+
bool Pasteboard::canSmartReplace()
{
notImplemented();
@@ -92,8 +99,7 @@ PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefP
void Pasteboard::writeURL(const KURL& url, const String&, Frame*)
{
- if (wxTheClipboard->Open())
- {
+ if (wxTheClipboard->Open()) {
wxTheClipboard->SetData( new wxTextDataObject( url.string() ) );
wxTheClipboard->Close();
}
diff --git a/WebCore/platform/wx/PopupMenuWx.cpp b/WebCore/platform/wx/PopupMenuWx.cpp
index 660282c..9b0deba 100644
--- a/WebCore/platform/wx/PopupMenuWx.cpp
+++ b/WebCore/platform/wx/PopupMenuWx.cpp
@@ -88,7 +88,7 @@ void PopupMenu::OnMenuItemSelected(wxCommandEvent& event)
{
if (client()) {
client()->valueChanged(event.GetId() - s_menuStartId);
- client()->hidePopup();
+ client()->popupDidHide();
}
// TODO: Do we need to call Disconnect here? Do we have a ref to the native window still?
}
diff --git a/WebCore/platform/wx/RenderThemeWx.cpp b/WebCore/platform/wx/RenderThemeWx.cpp
index f2ced9e..c66ff87 100644
--- a/WebCore/platform/wx/RenderThemeWx.cpp
+++ b/WebCore/platform/wx/RenderThemeWx.cpp
@@ -29,6 +29,7 @@
#include "Document.h"
#include "FrameView.h"
#include "GraphicsContext.h"
+#include "HostWindow.h"
#include "NotImplemented.h"
#include "RenderView.h"
@@ -138,6 +139,15 @@ PassRefPtr<RenderTheme> RenderTheme::themeForPage(Page* page)
return rt;
}
+wxWindow* nativeWindowForRenderObject(RenderObject* o)
+{
+ FrameView* frameView = o->view()->frameView();
+ ASSERT(frameView);
+ ASSERT(frameView->hostWindow());
+ return frameView->hostWindow()->platformPageClient();
+}
+
+
bool RenderThemeWx::isControlStyled(const RenderStyle* style, const BorderData& border,
const FillLayer& background, const Color& backgroundColor) const
{
@@ -251,10 +261,23 @@ void RenderThemeWx::adjustButtonStyle(CSSStyleSelector* selector, RenderStyle* s
bool RenderThemeWx::paintButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
{
- wxWindow* window = o->view()->frameView()->platformWidget();
+ wxWindow* window = nativeWindowForRenderObject(o);
wxDC* dc = static_cast<wxDC*>(i.context->platformContext());
int flags = 0;
+ IntRect rect = r;
+
+#if USE(WXGC)
+ double xtrans = 0;
+ double ytrans = 0;
+
+ wxGCDC* gcdc = static_cast<wxGCDC*>(dc);
+ wxGraphicsContext* gc = gcdc->GetGraphicsContext();
+ gc->GetTransform().TransformPoint(&xtrans, &ytrans);
+ rect.setX(r.x() + (int)xtrans);
+ rect.setY(r.y() + (int)ytrans);
+#endif
+
if (!isEnabled(o))
flags |= wxCONTROL_DISABLED;
@@ -266,20 +289,22 @@ bool RenderThemeWx::paintButton(RenderObject* o, const RenderObject::PaintInfo&
flags |= wxCONTROL_PRESSED;
if (part == PushButtonPart || part == ButtonPart)
- wxRendererNative::Get().DrawPushButton(window, *dc, r, flags);
+ wxRendererNative::Get().DrawPushButton(window, *dc, rect, flags);
else if(part == RadioPart) {
if (isChecked(o))
flags |= wxCONTROL_CHECKED;
-#if wxCHECK_VERSION(2,9,0)
- wxRendererNative::Get().DrawRadioButton(window, *dc, r, flags);
+#if wxCHECK_VERSION(2,9,1)
+ wxRendererNative::Get().DrawRadioBitmap(window, *dc, r, flags);
+#elif wxCHECK_VERSION(2,9,0)
+ wxRendererNative::Get().DrawRadioButton(window, *dc, rect, flags);
#else
- wxRenderer_DrawRadioButton(window, *dc, r, flags);
+ wxRenderer_DrawRadioButton(window, *dc, rect, flags);
#endif
}
else if(part == CheckboxPart) {
if (isChecked(o))
flags |= wxCONTROL_CHECKED;
- wxRendererNative::Get().DrawCheckBox(window, *dc, r, flags);
+ wxRendererNative::Get().DrawCheckBox(window, *dc, rect, flags);
}
return false;
}
@@ -291,7 +316,7 @@ void RenderThemeWx::adjustTextFieldStyle(CSSStyleSelector*, RenderStyle* style,
bool RenderThemeWx::paintTextField(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
{
- wxWindow* window = o->view()->frameView()->platformWidget();
+ wxWindow* window = nativeWindowForRenderObject(o);
wxDC* dc = static_cast<wxDC*>(i.context->platformContext());
#if wxCHECK_VERSION(2,9,0)
wxRendererNative::Get().DrawTextCtrl(window, *dc, r, 0);
@@ -313,7 +338,7 @@ void RenderThemeWx::adjustMenuListStyle(CSSStyleSelector*, RenderStyle* style, E
bool RenderThemeWx::paintMenuList(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
{
- wxWindow* window = o->view()->frameView()->platformWidget();
+ wxWindow* window = nativeWindowForRenderObject(o);
wxDC* dc = static_cast<wxDC*>(i.context->platformContext());
int flags = 0;
@@ -342,7 +367,7 @@ void RenderThemeWx::adjustMenuListButtonStyle(CSSStyleSelector*, RenderStyle*, E
bool RenderThemeWx::paintMenuListButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
{
- wxWindow* window = o->view()->frameView()->platformWidget();
+ wxWindow* window = nativeWindowForRenderObject(o);
wxDC* dc = static_cast<wxDC*>(i.context->platformContext());
int flags = 0;
diff --git a/WebCore/platform/wx/SSLKeyGeneratorWx.cpp b/WebCore/platform/wx/SSLKeyGeneratorWx.cpp
new file mode 100644
index 0000000..7d076e7
--- /dev/null
+++ b/WebCore/platform/wx/SSLKeyGeneratorWx.cpp
@@ -0,0 +1,44 @@
+/*
+ * 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 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 "SSLKeyGenerator.h"
+
+#include "NotImplemented.h"
+
+namespace WebCore {
+
+void getSupportedKeySizes(Vector<String>&)
+{
+ notImplemented();
+}
+
+String signedPublicKeyAndChallengeString(unsigned keySizeIndex, const String &challengeString, const KURL &url)
+{
+ return String();
+}
+
+}
+
diff --git a/WebCore/platform/wx/ScrollbarThemeWx.cpp b/WebCore/platform/wx/ScrollbarThemeWx.cpp
new file mode 100644
index 0000000..6904f41
--- /dev/null
+++ b/WebCore/platform/wx/ScrollbarThemeWx.cpp
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2008 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 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 "ScrollbarThemeWx.h"
+
+#include "HostWindow.h"
+#include "NotImplemented.h"
+#include "Scrollbar.h"
+#include "ScrollbarClient.h"
+#include "scrollbar_render.h"
+#include "ScrollbarThemeComposite.h"
+#include "ScrollView.h"
+
+#include <wx/defs.h>
+#include <wx/dcgraph.h>
+#include <wx/settings.h>
+
+const int cMacButtonOverlap = 4;
+
+namespace WebCore {
+
+ScrollbarTheme* ScrollbarTheme::nativeTheme()
+{
+ static ScrollbarThemeWx theme;
+ return &theme;
+}
+
+ScrollbarThemeWx::~ScrollbarThemeWx()
+{
+}
+
+int ScrollbarThemeWx::scrollbarThickness(ScrollbarControlSize size)
+{
+ int thickness = wxSystemSettings::GetMetric(wxSYS_VSCROLL_X);
+
+ // fallback for when a platform doesn't define this metric
+ if (thickness <= 0)
+ thickness = 20;
+
+ return thickness;
+}
+
+bool ScrollbarThemeWx::hasThumb(Scrollbar* scrollbar)
+{
+ // This method is just called as a paint-time optimization to see if
+ // painting the thumb can be skipped. We don't have to be exact here.
+ return thumbLength(scrollbar) > 0;
+}
+
+IntSize ScrollbarThemeWx::buttonSize(Scrollbar*)
+{
+#ifdef __WXMAC__
+ return IntSize(20,20);
+#else
+ return IntSize(16,16);
+#endif
+}
+
+
+IntRect ScrollbarThemeWx::backButtonRect(Scrollbar* scrollbar, ScrollbarPart part, bool)
+{
+ // FIXME: Handling this case is needed when there are two sets of arrow buttons
+ // on Mac, one at the top and one at the bottom.
+ if (part == BackButtonEndPart)
+ return IntRect();
+
+ IntSize size = buttonSize(scrollbar);
+ int x = scrollbar->x();
+ int y = scrollbar->y();
+
+#if __WXMAC__
+ if (scrollbar->orientation() == HorizontalScrollbar)
+ x += scrollbar->width() - (size.width() * 2) + cMacButtonOverlap;
+ else
+ y += scrollbar->height() - (size.height() * 2) + cMacButtonOverlap;
+#endif
+
+ return IntRect(x, y, size.width(), size.height());
+}
+
+IntRect ScrollbarThemeWx::forwardButtonRect(Scrollbar* scrollbar, ScrollbarPart part, bool)
+{
+ // FIXME: Handling this case is needed when there are two sets of arrow buttons
+ // on Mac, one at the top and one at the bottom.
+ if (part == ForwardButtonStartPart)
+ return IntRect();
+
+ IntSize size = buttonSize(scrollbar);
+ int x, y;
+ if (scrollbar->orientation() == HorizontalScrollbar) {
+ x = scrollbar->x() + scrollbar->width() - size.width();
+ y = scrollbar->y();
+ } else {
+ x = scrollbar->x();
+ y = scrollbar->y() + scrollbar->height() - size.height();
+ }
+ return IntRect(x, y, size.width(), size.height());
+}
+
+IntRect ScrollbarThemeWx::trackRect(Scrollbar* scrollbar, bool)
+{
+ IntSize bs = buttonSize(scrollbar);
+ int trackStart = 0;
+ if (scrollbar->orientation() == HorizontalScrollbar)
+ trackStart = bs.width();
+ else
+ trackStart = bs.height();
+
+#if __WXMAC__
+ trackStart = 0;
+#endif
+
+ int thickness = scrollbarThickness(scrollbar->controlSize());
+ if (scrollbar->orientation() == HorizontalScrollbar) {
+ if (scrollbar->width() < 2 * thickness)
+ return IntRect();
+ return IntRect(scrollbar->x() + trackStart, scrollbar->y(), scrollbar->width() - 2 * bs.width(), thickness);
+ }
+ if (scrollbar->height() < 2 * thickness)
+ return IntRect();
+ return IntRect(scrollbar->x(), scrollbar->y() + trackStart, thickness, scrollbar->height() - 2 * bs.height());
+}
+
+void ScrollbarThemeWx::paintScrollCorner(ScrollView* view, GraphicsContext* context, const IntRect& cornerRect)
+{
+ // ScrollbarThemeComposite::paintScrollCorner incorrectly assumes that the
+ // ScrollView is a FrameView (see FramelessScrollView), so we cannot let
+ // that code run. For FrameView's this is correct since we don't do custom
+ // scrollbar corner rendering, which ScrollbarThemeComposite supports.
+ ScrollbarTheme::paintScrollCorner(view, context, cornerRect);
+}
+
+bool ScrollbarThemeWx::paint(Scrollbar* scrollbar, GraphicsContext* context, const IntRect& rect)
+{
+ wxOrientation orientation = (scrollbar->orientation() == HorizontalScrollbar) ? wxHORIZONTAL : wxVERTICAL;
+ int flags = 0;
+ if (scrollbar->client()->isActive())
+ flags |= wxCONTROL_FOCUSED;
+
+ if (!scrollbar->enabled())
+ flags |= wxCONTROL_DISABLED;
+
+ wxDC* dc = static_cast<wxDC*>(context->platformContext());
+
+ context->save();
+ ScrollView* root = scrollbar->root();
+ ASSERT(root);
+ if (!root)
+ return false;
+
+ wxWindow* webview = root->hostWindow()->platformPageClient();
+
+ wxRenderer_DrawScrollbar(webview, *dc, scrollbar->frameRect(), orientation, scrollbar->currentPos(), static_cast<wxScrollbarPart>(scrollbar->pressedPart()),
+ static_cast<wxScrollbarPart>(scrollbar->hoveredPart()), scrollbar->maximum(), scrollbar->pageStep(), flags);
+
+ context->restore();
+ return true;
+}
+
+}
+
diff --git a/WebCore/platform/wx/ScrollbarThemeWx.h b/WebCore/platform/wx/ScrollbarThemeWx.h
new file mode 100644
index 0000000..2b3bff0
--- /dev/null
+++ b/WebCore/platform/wx/ScrollbarThemeWx.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2008 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 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 ScrollbarThemeWx_h
+#define ScrollbarThemeWx_h
+
+#include "ScrollbarTheme.h"
+#include "ScrollbarThemeComposite.h"
+
+namespace WebCore {
+
+class ScrollbarThemeWx : public ScrollbarThemeComposite {
+public:
+ virtual ~ScrollbarThemeWx();
+ virtual int scrollbarThickness(ScrollbarControlSize = RegularScrollbar);
+ virtual bool paint(Scrollbar*, GraphicsContext*, const IntRect&);
+
+ virtual void paintScrollCorner(ScrollView*, GraphicsContext*, const IntRect& cornerRect);
+
+protected:
+ virtual bool hasButtons(Scrollbar*) { return true; }
+ virtual bool hasThumb(Scrollbar*);
+
+ virtual IntSize buttonSize(Scrollbar*);
+
+ virtual IntRect backButtonRect(Scrollbar*, ScrollbarPart, bool painting = false);
+ virtual IntRect forwardButtonRect(Scrollbar*, ScrollbarPart, bool painting = false);
+ virtual IntRect trackRect(Scrollbar*, bool painting = false);
+};
+
+}
+#endif
diff --git a/WebCore/platform/wx/SearchPopupMenuWx.cpp b/WebCore/platform/wx/SearchPopupMenuWx.cpp
new file mode 100644
index 0000000..dbbe339
--- /dev/null
+++ b/WebCore/platform/wx/SearchPopupMenuWx.cpp
@@ -0,0 +1,55 @@
+/*
+ * 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 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 "SearchPopupMenu.h"
+
+#include "NotImplemented.h"
+
+namespace WebCore {
+
+SearchPopupMenu::SearchPopupMenu(PopupMenuClient* client)
+ : PopupMenu(client)
+{
+ notImplemented();
+}
+
+void SearchPopupMenu::saveRecentSearches(const AtomicString& name, const Vector<String>& searchItems)
+{
+ notImplemented();
+}
+
+void SearchPopupMenu::loadRecentSearches(const AtomicString& name, Vector<String>& searchItems)
+{
+ notImplemented();
+}
+
+bool SearchPopupMenu::enabled()
+{
+ return true;
+}
+
+}
+
diff --git a/WebCore/platform/wx/SharedBufferWx.cpp b/WebCore/platform/wx/SharedBufferWx.cpp
new file mode 100644
index 0000000..a9203ba
--- /dev/null
+++ b/WebCore/platform/wx/SharedBufferWx.cpp
@@ -0,0 +1,40 @@
+/*
+ * 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 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 "SharedBuffer.h"
+
+#include "NotImplemented.h"
+
+namespace WebCore {
+
+PassRefPtr<SharedBuffer> SharedBuffer::createWithContentsOfFile(const String&)
+{
+ notImplemented();
+ return 0;
+}
+
+}
+
diff --git a/WebCore/platform/wx/SystemTimeWx.cpp b/WebCore/platform/wx/SystemTimeWx.cpp
new file mode 100644
index 0000000..f607cba
--- /dev/null
+++ b/WebCore/platform/wx/SystemTimeWx.cpp
@@ -0,0 +1,43 @@
+/*
+ * 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 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 "SystemTime.h"
+
+#include <float.h>
+
+#include "NotImplemented.h"
+
+namespace WebCore {
+
+float userIdleTime()
+{
+ notImplemented();
+ // return an arbitrarily high userIdleTime so that releasing pages from the page cache isn't postponed
+ return FLT_MAX;
+}
+
+}
+
diff --git a/WebCore/platform/wx/TemporaryLinkStubs.cpp b/WebCore/platform/wx/TemporaryLinkStubs.cpp
index 2403527..5aa6e2c 100644
--- a/WebCore/platform/wx/TemporaryLinkStubs.cpp
+++ b/WebCore/platform/wx/TemporaryLinkStubs.cpp
@@ -1,3 +1,4 @@
+<<<<<<< HEAD:WebCore/platform/wx/TemporaryLinkStubs.cpp
/*
* Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
* Copyright (C) 2008 Collabora, Ltd. All rights reserved.
@@ -178,3 +179,5 @@ PassRefPtr<SharedBuffer> SharedBuffer::createWithContentsOfFile(const String&) {
void prefetchDNS(const String& hostname) { notImplemented(); }
}
+=======
+>>>>>>> webkit.org at 49305:WebCore/platform/wx/TemporaryLinkStubs.cpp
diff --git a/WebCore/platform/wx/TextBreakIteratorInternalICUWx.cpp b/WebCore/platform/wx/TextBreakIteratorInternalICUWx.cpp
new file mode 100644
index 0000000..f840e13
--- /dev/null
+++ b/WebCore/platform/wx/TextBreakIteratorInternalICUWx.cpp
@@ -0,0 +1,42 @@
+/*
+ * 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 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 "TextBreakIteratorInternalICU.h"
+
+namespace WebCore {
+
+const char* currentSearchLocaleID()
+{
+ return "";
+}
+
+const char* currentTextBreakLocaleID()
+{
+ return "en_us";
+}
+
+}
+
diff --git a/WebCore/platform/wx/WidgetWx.cpp b/WebCore/platform/wx/WidgetWx.cpp
index bb4fd2a..a384914 100644
--- a/WebCore/platform/wx/WidgetWx.cpp
+++ b/WebCore/platform/wx/WidgetWx.cpp
@@ -28,6 +28,7 @@
#include "Cursor.h"
#include "GraphicsContext.h"
#include "IntRect.h"
+#include "NotImplemented.h"
#include <wx/defs.h>
#include <wx/scrolwin.h>
@@ -96,4 +97,9 @@ void Widget::paint(GraphicsContext*,const IntRect& r)
widget->Update();
}
+void Widget::setIsSelected(bool)
+{
+ notImplemented();
+}
+
}
diff --git a/WebCore/platform/wx/wxcode/gtk/scrollbar_render.cpp b/WebCore/platform/wx/wxcode/gtk/scrollbar_render.cpp
new file mode 100644
index 0000000..f74b076
--- /dev/null
+++ b/WebCore/platform/wx/wxcode/gtk/scrollbar_render.cpp
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2009 Kevin Ollivier 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 "scrollbar_render.h"
+
+#include <wx/defs.h>
+#include <wx/dc.h>
+#include <wx/dcgraph.h>
+#include <wx/renderer.h>
+#include <wx/settings.h>
+#include <wx/window.h>
+
+#include <gtk/gtk.h>
+
+#if wxCHECK_VERSION(2, 9, 0)
+ #include <wx/gtk/dc.h>
+#else
+ #include "wx/gtk/win_gtk.h"
+#endif
+
+int wxStyleForPart(wxScrollbarPart part, wxScrollbarPart focusPart, wxScrollbarPart hoverPart, int flags)
+{
+ int style = 0;
+ if (flags == wxCONTROL_DISABLED)
+ style = wxCONTROL_DISABLED;
+ else if (part == focusPart)
+ style = wxCONTROL_PRESSED;
+ else if (part == hoverPart)
+ style = wxCONTROL_CURRENT;
+
+ return style;
+}
+
+GtkWidget* GetButtonWidget()
+{
+ static GtkWidget *s_button = NULL;
+ static GtkWidget *s_window = NULL;
+
+ if ( !s_button )
+ {
+ s_window = gtk_window_new( GTK_WINDOW_POPUP );
+ gtk_widget_realize( s_window );
+ s_button = gtk_button_new();
+ gtk_container_add( GTK_CONTAINER(s_window), s_button );
+ gtk_widget_realize( s_button );
+ }
+
+ return s_button;
+}
+
+
+GdkWindow* wxGetGdkWindowForDC(wxWindow* win, wxDC& dc)
+{
+ GdkWindow* gdk_window = NULL;
+#if wxCHECK_VERSION(2, 9, 0)
+ if ( dc.IsKindOf( CLASSINFO(wxGCDC) ) )
+ gdk_window = win->GTKGetDrawingWindow();
+ else
+ {
+ wxGTKDCImpl *impl = wxDynamicCast(dc.GetImpl(), wxGTKDCImpl);
+ if ( impl )
+ gdk_window = impl->GetGDKWindow();
+ }
+#else // wx < 2.9
+ // The way to get a GdkWindow* from a wxWindow is to use
+ // GTK_PIZZA(win->m_wxwindow)->bin_window, but this approach
+ // won't work when drawing to a wxMemoryDC as it has its own
+ // GdkWindow* for its bitmap. wxWindowDC's GetGDKWindow() was
+ // designed to create a solution for all DCs, but we can't
+ // implement it with wxGCDC since it doesn't retain its wxWindow.
+ // So, to work around this, we use GetGDKWindow whenever possible
+ // and use bin_window for wxGCDC.
+#if wxUSE_GRAPHICS_CONTEXT
+ if ( dc.IsKindOf( CLASSINFO(wxGCDC) ) )
+ gdk_window = GTK_PIZZA(win->m_wxwindow)->bin_window;
+ else
+#endif
+ gdk_window = dc.GetGDKWindow();
+ wxASSERT_MSG( gdk_window,
+ wxT("cannot use wxRendererNative on wxDC of this type") );
+#endif // wx 2.9/2.8
+
+ return gdk_window;
+}
+
+void wxRenderer_DrawScrollbar(wxWindow* window, wxDC& dc, const wxRect& rect, wxOrientation orient,
+ int current, wxScrollbarPart focusPart, wxScrollbarPart hoverPart, int max, int step, int flags)
+{
+ bool horiz = orient == wxHORIZONTAL;
+ wxColour scrollbar_colour = wxSystemSettings::GetColour(wxSYS_COLOUR_SCROLLBAR);
+ dc.SetBrush(wxBrush(scrollbar_colour));
+ dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW)));
+ dc.DrawRectangle(rect.x, rect.y, rect.width, rect.height);
+
+ wxRendererNative& renderer = wxRendererNative::Get();
+ int x = rect.x;
+ int y = rect.y;
+
+ int buttonLength = 16;
+
+ renderer.DrawPushButton(window, dc, wxRect(x,y,buttonLength,buttonLength), wxStyleForPart(wxSCROLLPART_BACKBTNSTART, focusPart, hoverPart, flags));
+
+ GtkWidget* button = GetButtonWidget();
+ GdkWindow* gdk_window = wxGetGdkWindowForDC(window, dc);
+
+ GtkArrowType arrowType = GTK_ARROW_UP;
+ if (horiz)
+ arrowType = GTK_ARROW_LEFT;
+
+ gtk_paint_arrow( button->style, gdk_window, GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL, button, "arrow", arrowType, false, x + 4, y + 4, 8, 8);
+
+ wxRect buttonRect = rect;
+ int physicalLength = horiz ? rect.width : rect.height;
+ physicalLength -= buttonLength*2;
+ int thumbStart = 0;
+ int thumbLength = 0;
+ calcThumbStartAndLength(physicalLength, max + step, current, step, &thumbStart, &thumbLength);
+
+ if (horiz) {
+ buttonRect.x = thumbStart + buttonLength;
+ buttonRect.width = thumbLength;
+ } else {
+ buttonRect.y = thumbStart + buttonLength;
+ buttonRect.height = thumbLength;
+ }
+
+ renderer.DrawPushButton(window, dc, buttonRect, wxStyleForPart(wxSCROLLPART_THUMB, focusPart, hoverPart, flags));
+
+ if (horiz)
+ x += rect.width - buttonLength;
+ else
+ y += rect.height - buttonLength;
+
+ renderer.DrawPushButton(window, dc, wxRect(x,y,buttonLength,buttonLength), wxStyleForPart(wxSCROLLPART_FWDBTNEND, focusPart, hoverPart, flags));
+
+ if (horiz)
+ arrowType = GTK_ARROW_RIGHT;
+ else
+ arrowType = GTK_ARROW_DOWN;
+
+ gtk_paint_arrow( button->style, gdk_window, GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL, button, "arrow", arrowType, false, x + 4, y + 4, 8, 8);
+}
diff --git a/WebCore/platform/wx/wxcode/mac/carbon/non-kerned-drawing.cpp b/WebCore/platform/wx/wxcode/mac/carbon/non-kerned-drawing.cpp
index e5c60d6..c4c4d48 100644
--- a/WebCore/platform/wx/wxcode/mac/carbon/non-kerned-drawing.cpp
+++ b/WebCore/platform/wx/wxcode/mac/carbon/non-kerned-drawing.cpp
@@ -63,7 +63,7 @@ void drawTextWithSpacing(GraphicsContext* graphicsContext, const SimpleFontData*
CGFontRef cgFont;
#ifdef wxOSX_USE_CORE_TEXT && wxOSX_USE_CORE_TEXT
- cgFont = CTFontCopyGraphicsFont((CTFontRef)font->OSXGetCTFont(), NULL);
+ cgFont = CTFontCopyGraphicsFont((CTFontRef)wxfont->OSXGetCTFont(), NULL);
#else
ATSFontRef fontRef;
diff --git a/WebCore/platform/wx/wxcode/mac/carbon/scrollbar_render.cpp b/WebCore/platform/wx/wxcode/mac/carbon/scrollbar_render.cpp
new file mode 100644
index 0000000..5169601
--- /dev/null
+++ b/WebCore/platform/wx/wxcode/mac/carbon/scrollbar_render.cpp
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2009 Kevin Ollivier 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 "scrollbar_render.h"
+
+#include <wx/defs.h>
+#include <wx/dc.h>
+#include <wx/dcgraph.h>
+#include <wx/renderer.h>
+
+#include <Carbon/Carbon.h>
+
+static int wxScrollbarPartToHIPressedState(wxScrollbarPart part)
+{
+ switch (part) {
+ case wxSCROLLPART_BACKBTNSTART:
+ return kThemeTopOutsideArrowPressed;
+ case wxSCROLLPART_BACKBTNEND:
+ return kThemeTopOutsideArrowPressed; // This does not make much sense. For some reason the outside constant is required.
+ case wxSCROLLPART_FWDBTNSTART:
+ return kThemeTopInsideArrowPressed;
+ case wxSCROLLPART_FWDBTNEND:
+ return kThemeBottomOutsideArrowPressed;
+ case wxSCROLLPART_THUMB:
+ return kThemeThumbPressed;
+ default:
+ return 0;
+ }
+}
+
+void wxRenderer_DrawScrollbar(wxWindow* WXUNUSED(window), wxDC& dc,
+ const wxRect& rect, wxOrientation orient, int current,
+ wxScrollbarPart focusPart, wxScrollbarPart hoverPart, int max, int step, int flags)
+{
+ const wxCoord x = rect.x;
+ const wxCoord y = rect.y;
+ const wxCoord w = rect.width;
+ const wxCoord h = rect.height;
+
+ dc.SetBrush( *wxWHITE_BRUSH );
+ dc.SetPen( *wxTRANSPARENT_PEN );
+ dc.DrawRectangle(rect);
+
+ dc.SetBrush( *wxTRANSPARENT_BRUSH );
+
+ HIRect hiRect = CGRectMake( x, y, w, h );
+
+ CGContextRef cgContext = NULL;
+ wxGraphicsContext* gc = NULL;
+#if wxCHECK_VERSION(2,9,0)
+ wxGCDCImpl *impl = dynamic_cast<wxGCDCImpl*> (dc.GetImpl());
+ if (impl)
+ gc = impl->GetGraphicsContext();
+#else
+ gc = dc.GetGraphicsContext();
+#endif
+ if (gc)
+ cgContext = (CGContextRef) gc->GetNativeContext();
+
+ if (cgContext)
+ {
+ HIThemeTrackDrawInfo trackInfo;
+ trackInfo.version = 0;
+ trackInfo.kind = kThemeMediumScrollBar;
+ trackInfo.bounds = hiRect;
+ trackInfo.min = 0;
+ trackInfo.max = max;
+ trackInfo.value = current;
+ trackInfo.trackInfo.scrollbar.viewsize = step;
+ trackInfo.attributes = 0;
+ if (orient == wxHORIZONTAL)
+ trackInfo.attributes |= kThemeTrackHorizontal;
+ trackInfo.enableState = (flags & wxCONTROL_FOCUSED) ? kThemeTrackActive : kThemeTrackInactive;
+ trackInfo.trackInfo.scrollbar.pressState = wxScrollbarPartToHIPressedState(focusPart);
+ trackInfo.attributes |= kThemeTrackShowThumb;
+
+ if (flags & wxCONTROL_DISABLED)
+ trackInfo.enableState = kThemeTrackDisabled;
+
+ HIThemeDrawTrack(&trackInfo, 0, cgContext, kHIThemeOrientationNormal);
+ }
+}
diff --git a/WebCore/platform/wx/wxcode/scrollbar_render.h b/WebCore/platform/wx/wxcode/scrollbar_render.h
new file mode 100644
index 0000000..7a0ba1c
--- /dev/null
+++ b/WebCore/platform/wx/wxcode/scrollbar_render.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2009 Kevin Ollivier 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 scrollbar_render_h
+#define scrollbar_render_h
+
+#include <wx/defs.h>
+#include <wx/dc.h>
+#include <wx/renderer.h>
+
+enum wxScrollbarPart {
+ wxSCROLLPART_NONE = 0,
+ wxSCROLLPART_BACKBTNSTART = 1,
+ wxSCROLLPART_FWDBTNSTART = 1 << 1,
+ wxSCROLLPART_BACKTRACK = 1 << 2,
+ wxSCROLLPART_THUMB = 1 << 3,
+ wxSCROLLPART_FWDTRACK = 1 << 4,
+ wxSCROLLPART_BACKBTNEND = 1 << 5,
+ wxSCROLLPART_FWDBTNEND = 1 << 6,
+ wxSCROLLPART_SCROLLBARBG = 1 << 7,
+ wxSCROLLPART_TRACKBG = 1 << 8,
+ wxSCROLLPART_ALL = 0xffffffff,
+};
+
+void wxRenderer_DrawScrollbar(wxWindow* window, wxDC& dc,
+ const wxRect& rect,
+ wxOrientation orientation,
+ int current, wxScrollbarPart focusPart, wxScrollbarPart hoverPart,
+ int max, int step, int flags=0);
+
+inline void calcThumbStartAndLength(int physicalLength, int virtualLength, int current,
+ int step, int *thumbStart, int *thumbLength)
+{
+ float proportion = (float)physicalLength / virtualLength;
+ float scale = (float)virtualLength / physicalLength;
+ int thumbSize = proportion * physicalLength;
+ int currentPos = current / scale;
+
+ if (thumbStart)
+ *thumbStart = currentPos;
+
+ if (thumbLength)
+ *thumbLength = thumbSize;
+}
+#endif
diff --git a/WebCore/platform/wx/wxcode/win/non-kerned-drawing.cpp b/WebCore/platform/wx/wxcode/win/non-kerned-drawing.cpp
index d2513d7..72fcc54 100644
--- a/WebCore/platform/wx/wxcode/win/non-kerned-drawing.cpp
+++ b/WebCore/platform/wx/wxcode/win/non-kerned-drawing.cpp
@@ -79,13 +79,24 @@ void drawTextWithSpacing(GraphicsContext* graphicsContext, const SimpleFontData*
// get the native HDC handle to draw using native APIs
HDC hdc = 0;
+ float y = point.y() - font->ascent();
+ float x = point.x();
+
#if USE(WXGC)
+ // when going from GdiPlus -> Gdi, any GdiPlus transformations are lost
+ // so we need to alter the coordinates to reflect their transformed point.
+ double xtrans = 0;
+ double ytrans = 0;
+
wxGraphicsContext* gc = dc->GetGraphicsContext();
+ gc->GetTransform().TransformPoint(&xtrans, &ytrans);
Gdiplus::Graphics* g;
if (gc) {
g = (Gdiplus::Graphics*)gc->GetNativeContext();
hdc = g->GetHDC();
}
+ x += (int)xtrans;
+ y += (int)ytrans;
#else
hdc = static_cast<HDC>(dc->GetHDC());
#endif
@@ -95,9 +106,6 @@ void drawTextWithSpacing(GraphicsContext* graphicsContext, const SimpleFontData*
const GlyphBufferGlyph* glyphs = glyphBuffer.glyphs(from);
const GlyphBufferAdvance* advances = glyphBuffer.advances(from);
- float y = point.y() - font->ascent();
- float x = point.x();
-
int* spacing = new int[numGlyphs - from];
for (unsigned i = 0; i < numGlyphs; ++i)
spacing[i] = advances[i].width();
diff --git a/WebCore/platform/wx/wxcode/win/scrollbar_render.cpp b/WebCore/platform/wx/wxcode/win/scrollbar_render.cpp
new file mode 100644
index 0000000..4d6bbc0
--- /dev/null
+++ b/WebCore/platform/wx/wxcode/win/scrollbar_render.cpp
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2009 Kevin Ollivier 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 "scrollbar_render.h"
+
+#include <wx/defs.h>
+
+#include <wx/dc.h>
+#include <wx/renderer.h>
+#include <wx/window.h>
+
+#include <wx/msw/private.h>
+#include <wx/msw/uxtheme.h>
+
+// constants
+#define SP_BUTTON 1
+#define SP_THUMBHOR 2
+#define SP_THUMBVERT 3
+#define SP_TRACKENDHOR 4
+#define SP_TRACKENDVERT 7
+#define SP_GRIPPERHOR 8
+#define SP_GRIPPERVERT 9
+
+#define TS_NORMAL 1
+#define TS_HOVER 2
+#define TS_ACTIVE 3
+#define TS_DISABLED 4
+
+#define TS_UP_BUTTON 0
+#define TS_DOWN_BUTTON 4
+#define TS_LEFT_BUTTON 8
+#define TS_RIGHT_BUTTON 12
+
+#if wxUSE_GRAPHICS_CONTEXT
+// TODO remove this dependency (gdiplus needs the macros)
+// we need to undef because the macros are being defined in WebCorePrefix.h
+// but GdiPlus.h is not accepting them
+#undef max
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+
+#undef min
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+
+#include <wx/dcgraph.h>
+#include "gdiplus.h"
+using namespace Gdiplus;
+#endif // wxUSE_GRAPHICS_CONTEXT
+
+class GraphicsHDC
+{
+public:
+ GraphicsHDC(wxDC* dc)
+ {
+#if wxUSE_GRAPHICS_CONTEXT
+ m_graphics = NULL;
+ wxGCDC* gcdc = wxDynamicCast(dc, wxGCDC);
+ if (gcdc) {
+ m_graphics = (Graphics*)gcdc->GetGraphicsContext()->GetNativeContext();
+ m_hdc = m_graphics->GetHDC();
+ }
+ else
+#endif
+ m_hdc = GetHdcOf(*dc);
+ }
+
+ ~GraphicsHDC()
+ {
+#if wxUSE_GRAPHICS_CONTEXT
+ if (m_graphics)
+ m_graphics->ReleaseHDC(m_hdc);
+#endif
+ }
+
+ operator HDC() const { return m_hdc; }
+
+private:
+ HDC m_hdc;
+#if wxUSE_GRAPHICS_CONTEXT
+ Graphics* m_graphics;
+#endif
+};
+
+int getTSStateForPart(wxScrollbarPart part, wxScrollbarPart focusPart, wxScrollbarPart hoverPart, int flags = 0)
+{
+ int xpState = TS_NORMAL;
+ if (flags & wxCONTROL_DISABLED)
+ xpState = TS_DISABLED;
+ else if (part == focusPart)
+ xpState = TS_ACTIVE;
+ else if (part == hoverPart)
+ xpState = TS_HOVER;
+
+ return xpState;
+}
+
+void wxRenderer_DrawScrollbar(wxWindow* window, wxDC& dc,
+ const wxRect& rect, wxOrientation orient, int current, wxScrollbarPart focusPart, wxScrollbarPart hoverPart, int max, int step, int flags)
+{
+ wxUxThemeEngine *engine = wxUxThemeEngine::Get();
+ HTHEME hTheme = (HTHEME)engine->OpenThemeData(0, L"SCROLLBAR");
+
+ bool horiz = orient == wxHORIZONTAL;
+ int part = 0;
+ if (horiz)
+ part = SP_TRACKENDHOR;
+ else
+ part = SP_TRACKENDVERT;
+
+ int xpState = TS_NORMAL;
+ RECT r;
+ wxCopyRectToRECT(rect, r);
+
+ // Unlike Mac, on MSW you draw the scrollbar piece by piece.
+ // so we draw the track first, then the buttons
+ if (hTheme)
+ {
+ engine->DrawThemeBackground(hTheme, GraphicsHDC(&dc), part, xpState, &r, 0);
+
+ int buttonSize = 16;
+
+ part = SP_BUTTON;
+ xpState = getTSStateForPart(wxSCROLLPART_BACKBTNSTART, focusPart, hoverPart, flags);
+ xpState += horiz ? TS_LEFT_BUTTON : TS_UP_BUTTON;
+ RECT buttonRect = r;
+ buttonRect.bottom = buttonRect.top + buttonSize;
+ buttonRect.right = buttonRect.left + buttonSize;
+ engine->DrawThemeBackground(hTheme, GraphicsHDC(&dc), part, xpState, &buttonRect, 0);
+
+ xpState = getTSStateForPart(wxSCROLLPART_FWDBTNEND, focusPart, hoverPart, flags);
+ xpState += horiz ? TS_RIGHT_BUTTON : TS_DOWN_BUTTON;
+ buttonRect = r;
+ buttonRect.top = buttonRect.bottom - buttonSize;
+ buttonRect.left = buttonRect.right - buttonSize;
+ engine->DrawThemeBackground(hTheme, GraphicsHDC(&dc), part, xpState, &buttonRect, 0);
+
+ part = horiz ? SP_THUMBHOR : SP_THUMBVERT;
+
+ int physicalLength = horiz ? rect.width : rect.height;
+ physicalLength -= buttonSize*2;
+ int thumbStart = 0;
+ int thumbLength = 0;
+ calcThumbStartAndLength(physicalLength, max + step,
+ current, step, &thumbStart, &thumbLength);
+ buttonRect = r;
+ if (horiz) {
+ buttonRect.left = thumbStart + buttonSize;
+ buttonRect.right = buttonRect.left + thumbLength;
+ } else {
+ buttonRect.top = thumbStart + buttonSize;
+ buttonRect.bottom = buttonRect.top + thumbLength;
+ }
+
+ xpState = getTSStateForPart(wxSCROLLPART_THUMB, focusPart, hoverPart, flags);
+ engine->DrawThemeBackground(hTheme, GraphicsHDC(&dc), part, xpState, &buttonRect, 0);
+
+ // draw the gripper
+ int thickness = ::GetSystemMetrics(SM_CXVSCROLL) / 2;
+
+ buttonRect.left += ((buttonRect.right - buttonRect.left) - thickness) / 2;
+ buttonRect.top += ((buttonRect.bottom - buttonRect.top) - thickness) / 2;
+ buttonRect.right = buttonRect.left + thickness;
+ buttonRect.bottom = buttonRect.top + thickness;
+
+ if (horiz)
+ part = SP_GRIPPERHOR;
+ else
+ part = SP_GRIPPERVERT;
+
+ engine->DrawThemeBackground(hTheme, GraphicsHDC(&dc), part, xpState, &buttonRect, 0);
+ }
+}