summaryrefslogtreecommitdiffstats
path: root/WebCore/platform
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/platform')
-rw-r--r--WebCore/platform/ContextMenu.cpp23
-rw-r--r--WebCore/platform/CrossThreadCopier.cpp14
-rw-r--r--WebCore/platform/CrossThreadCopier.h41
-rw-r--r--WebCore/platform/Cursor.h7
-rw-r--r--WebCore/platform/FileChooser.h3
-rw-r--r--WebCore/platform/FileSystem.h8
-rw-r--r--WebCore/platform/GeolocationService.cpp2
-rw-r--r--WebCore/platform/KURL.cpp38
-rw-r--r--WebCore/platform/KURL.h7
-rw-r--r--WebCore/platform/KURLGoogle.cpp16
-rw-r--r--WebCore/platform/KeyboardCodes.h18
-rw-r--r--WebCore/platform/LinkHash.cpp6
-rw-r--r--WebCore/platform/LocalizedStrings.h2
-rw-r--r--WebCore/platform/PlatformKeyboardEvent.h1
-rw-r--r--WebCore/platform/PlatformMouseEvent.h7
-rw-r--r--WebCore/platform/PlatformTouchEvent.h13
-rw-r--r--WebCore/platform/PlatformWheelEvent.h14
-rw-r--r--WebCore/platform/PopupMenu.h9
-rw-r--r--WebCore/platform/PurgeableBuffer.h2
-rw-r--r--WebCore/platform/ScrollView.cpp26
-rw-r--r--WebCore/platform/ScrollView.h10
-rw-r--r--WebCore/platform/Scrollbar.cpp14
-rw-r--r--WebCore/platform/Scrollbar.h3
-rw-r--r--WebCore/platform/ScrollbarThemeComposite.cpp1
-rw-r--r--WebCore/platform/SharedBuffer.cpp139
-rw-r--r--WebCore/platform/SharedBuffer.h41
-rw-r--r--WebCore/platform/ThemeTypes.h5
-rw-r--r--WebCore/platform/ThreadGlobalData.cpp18
-rw-r--r--WebCore/platform/ThreadGlobalData.h34
-rw-r--r--WebCore/platform/Timer.cpp7
-rw-r--r--WebCore/platform/Timer.h6
-rw-r--r--WebCore/platform/TreeShared.h2
-rw-r--r--WebCore/platform/Widget.cpp6
-rw-r--r--WebCore/platform/Widget.h6
-rw-r--r--WebCore/platform/android/PlatformBridge.h8
-rw-r--r--WebCore/platform/android/PlatformTouchEventAndroid.cpp7
-rw-r--r--WebCore/platform/cf/BinaryPropertyList.cpp1
-rw-r--r--WebCore/platform/cf/SharedBufferCF.cpp9
-rw-r--r--WebCore/platform/chromium/ChromiumBridge.h9
-rw-r--r--WebCore/platform/chromium/ChromiumDataObject.cpp3
-rw-r--r--WebCore/platform/chromium/ChromiumDataObject.h2
-rw-r--r--WebCore/platform/chromium/ClipboardChromium.cpp16
-rw-r--r--WebCore/platform/chromium/ClipboardUtilitiesChromium.cpp2
-rw-r--r--WebCore/platform/chromium/ClipboardUtilitiesChromium.h2
-rw-r--r--WebCore/platform/chromium/DragDataChromium.cpp2
-rw-r--r--WebCore/platform/chromium/KeyCodeConversionGtk.cpp17
-rw-r--r--WebCore/platform/chromium/PasteboardChromium.cpp10
-rw-r--r--WebCore/platform/chromium/PlatformBridge.h47
-rw-r--r--WebCore/platform/chromium/PlatformKeyboardEventChromium.cpp12
-rw-r--r--WebCore/platform/chromium/PopupMenuChromium.cpp35
-rw-r--r--WebCore/platform/chromium/ScrollbarThemeChromiumMac.mm2
-rw-r--r--WebCore/platform/graphics/BitmapImage.h6
-rw-r--r--WebCore/platform/graphics/FloatPoint.h4
-rw-r--r--WebCore/platform/graphics/FloatQuad.cpp6
-rw-r--r--WebCore/platform/graphics/FloatQuad.h6
-rw-r--r--WebCore/platform/graphics/FloatRect.h12
-rw-r--r--WebCore/platform/graphics/FloatSize.h4
-rw-r--r--WebCore/platform/graphics/Font.cpp17
-rw-r--r--WebCore/platform/graphics/Font.h22
-rw-r--r--WebCore/platform/graphics/FontCache.cpp6
-rw-r--r--WebCore/platform/graphics/FontCache.h2
-rw-r--r--WebCore/platform/graphics/FontFastPath.cpp15
-rw-r--r--WebCore/platform/graphics/GeneratedImage.cpp41
-rw-r--r--WebCore/platform/graphics/Generator.h1
-rw-r--r--WebCore/platform/graphics/GlyphBuffer.h10
-rw-r--r--WebCore/platform/graphics/Gradient.cpp36
-rw-r--r--WebCore/platform/graphics/Gradient.h17
-rw-r--r--WebCore/platform/graphics/GraphicsContext.cpp102
-rw-r--r--WebCore/platform/graphics/GraphicsContext.h31
-rw-r--r--WebCore/platform/graphics/GraphicsContext3D.h56
-rw-r--r--WebCore/platform/graphics/GraphicsContextPrivate.h9
-rw-r--r--WebCore/platform/graphics/GraphicsLayer.cpp37
-rw-r--r--WebCore/platform/graphics/GraphicsLayer.h31
-rw-r--r--WebCore/platform/graphics/Image.h1
-rw-r--r--WebCore/platform/graphics/ImageSource.cpp9
-rw-r--r--WebCore/platform/graphics/ImageSource.h4
-rw-r--r--WebCore/platform/graphics/IntRect.cpp35
-rw-r--r--WebCore/platform/graphics/IntRect.h33
-rw-r--r--WebCore/platform/graphics/IntSize.h3
-rw-r--r--WebCore/platform/graphics/MediaPlayer.cpp37
-rw-r--r--WebCore/platform/graphics/MediaPlayer.h10
-rw-r--r--WebCore/platform/graphics/MediaPlayerPrivate.h10
-rw-r--r--WebCore/platform/graphics/Path.h18
-rw-r--r--WebCore/platform/graphics/Pattern.h2
-rw-r--r--WebCore/platform/graphics/SimpleFontData.h19
-rw-r--r--WebCore/platform/graphics/TypesettingFeatures.h38
-rw-r--r--WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp12
-rw-r--r--WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h2
-rw-r--r--WebCore/platform/graphics/cairo/ImageBufferCairo.cpp2
-rw-r--r--WebCore/platform/graphics/cg/ColorCG.cpp4
-rw-r--r--WebCore/platform/graphics/cg/GradientCG.cpp49
-rw-r--r--WebCore/platform/graphics/cg/GraphicsContextCG.cpp61
-rw-r--r--WebCore/platform/graphics/cg/PatternCG.cpp2
-rw-r--r--WebCore/platform/graphics/chromium/FontCustomPlatformData.cpp28
-rw-r--r--WebCore/platform/graphics/chromium/FontCustomPlatformData.h12
-rw-r--r--WebCore/platform/graphics/chromium/FontLinux.cpp36
-rw-r--r--WebCore/platform/graphics/chromium/FontPlatformData.h4
-rw-r--r--WebCore/platform/graphics/chromium/HarfbuzzSkia.cpp34
-rw-r--r--WebCore/platform/graphics/chromium/TransparencyWin.cpp5
-rw-r--r--WebCore/platform/graphics/filters/FEColorMatrix.cpp1
-rw-r--r--WebCore/platform/graphics/filters/FEComponentTransfer.cpp4
-rw-r--r--WebCore/platform/graphics/filters/FEComponentTransfer.h1
-rw-r--r--WebCore/platform/graphics/filters/FEComposite.cpp4
-rw-r--r--WebCore/platform/graphics/gtk/ImageGtk.cpp57
-rw-r--r--WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp385
-rw-r--r--WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h37
-rw-r--r--WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp8
-rw-r--r--WebCore/platform/graphics/mac/Canvas3DLayer.mm10
-rw-r--r--WebCore/platform/graphics/mac/ComplexTextController.cpp65
-rw-r--r--WebCore/platform/graphics/mac/ComplexTextController.h31
-rw-r--r--WebCore/platform/graphics/mac/ComplexTextControllerATSUI.cpp67
-rw-r--r--WebCore/platform/graphics/mac/ComplexTextControllerCoreText.cpp59
-rw-r--r--WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp181
-rw-r--r--WebCore/platform/graphics/mac/GraphicsContextMac.mm52
-rw-r--r--WebCore/platform/graphics/mac/GraphicsLayerCA.h161
-rw-r--r--WebCore/platform/graphics/mac/GraphicsLayerCA.mm956
-rw-r--r--WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h18
-rw-r--r--WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm74
-rw-r--r--WebCore/platform/graphics/mac/SimpleFontDataMac.mm29
-rw-r--r--WebCore/platform/graphics/mac/WebLayer.mm7
-rw-r--r--WebCore/platform/graphics/mac/WebTiledLayer.mm7
-rw-r--r--WebCore/platform/graphics/opentype/OpenTypeUtilities.cpp2
-rw-r--r--WebCore/platform/graphics/opentype/OpenTypeUtilities.h2
-rw-r--r--WebCore/platform/graphics/openvg/EGLDisplayOpenVG.cpp431
-rw-r--r--WebCore/platform/graphics/openvg/EGLDisplayOpenVG.h89
-rw-r--r--WebCore/platform/graphics/openvg/EGLUtils.h71
-rw-r--r--WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp566
-rw-r--r--WebCore/platform/graphics/openvg/PainterOpenVG.cpp957
-rw-r--r--WebCore/platform/graphics/openvg/PainterOpenVG.h121
-rw-r--r--WebCore/platform/graphics/openvg/SurfaceOpenVG.cpp243
-rw-r--r--WebCore/platform/graphics/openvg/SurfaceOpenVG.h137
-rw-r--r--WebCore/platform/graphics/openvg/VGUtils.cpp100
-rw-r--r--WebCore/platform/graphics/openvg/VGUtils.h87
-rw-r--r--WebCore/platform/graphics/qt/FontCacheQt.cpp2
-rw-r--r--WebCore/platform/graphics/qt/FontPlatformData.h2
-rw-r--r--WebCore/platform/graphics/qt/FontPlatformDataQt.cpp11
-rw-r--r--WebCore/platform/graphics/qt/FontQt.cpp37
-rw-r--r--WebCore/platform/graphics/qt/GraphicsContextQt.cpp30
-rw-r--r--WebCore/platform/graphics/qt/GraphicsLayerQt.cpp1118
-rw-r--r--WebCore/platform/graphics/qt/GraphicsLayerQt.h85
-rw-r--r--WebCore/platform/graphics/qt/ImageBufferQt.cpp2
-rw-r--r--WebCore/platform/graphics/qt/ImageDecoderQt.cpp29
-rw-r--r--WebCore/platform/graphics/qt/ImageDecoderQt.h5
-rw-r--r--WebCore/platform/graphics/qt/ImageQt.cpp2
-rw-r--r--WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp32
-rw-r--r--WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.h4
-rw-r--r--WebCore/platform/graphics/qt/PathQt.cpp81
-rw-r--r--WebCore/platform/graphics/skia/GraphicsContextSkia.cpp15
-rw-r--r--WebCore/platform/graphics/skia/ImageBufferSkia.cpp2
-rw-r--r--WebCore/platform/graphics/skia/PlatformContextSkia.cpp19
-rw-r--r--WebCore/platform/graphics/skia/PlatformContextSkia.h8
-rw-r--r--WebCore/platform/graphics/transforms/TransformationMatrix.h36
-rw-r--r--WebCore/platform/graphics/win/FontCGWin.cpp3
-rw-r--r--WebCore/platform/graphics/win/FontCacheWin.cpp13
-rw-r--r--WebCore/platform/graphics/win/FontCustomPlatformData.cpp33
-rw-r--r--WebCore/platform/graphics/win/FontDatabase.cpp3
-rw-r--r--WebCore/platform/graphics/win/FontPlatformDataCGWin.cpp7
-rw-r--r--WebCore/platform/graphics/win/GraphicsContextCGWin.cpp12
-rw-r--r--WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp17
-rw-r--r--WebCore/platform/graphics/win/GraphicsLayerCACF.cpp11
-rw-r--r--WebCore/platform/graphics/win/IconWin.cpp6
-rw-r--r--WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp325
-rw-r--r--WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h65
-rw-r--r--WebCore/platform/graphics/win/QTMovieWin.cpp132
-rw-r--r--WebCore/platform/graphics/win/QTMovieWin.h14
-rw-r--r--WebCore/platform/graphics/win/TransformationMatrixWin.cpp2
-rw-r--r--WebCore/platform/graphics/win/WKCACFLayer.cpp170
-rw-r--r--WebCore/platform/graphics/win/WKCACFLayer.h23
-rw-r--r--WebCore/platform/graphics/win/WKCACFLayerRenderer.cpp98
-rw-r--r--WebCore/platform/graphics/win/WKCACFLayerRenderer.h4
-rw-r--r--WebCore/platform/graphics/wince/GraphicsContextWince.cpp12
-rw-r--r--WebCore/platform/graphics/wince/MediaPlayerPrivateWince.h4
-rw-r--r--WebCore/platform/graphics/wx/GraphicsContextWx.cpp9
-rw-r--r--WebCore/platform/gtk/ContextMenuItemGtk.cpp15
-rw-r--r--WebCore/platform/gtk/DataObjectGtk.cpp120
-rw-r--r--WebCore/platform/gtk/DataObjectGtk.h78
-rw-r--r--WebCore/platform/gtk/FileSystemGtk.cpp6
-rw-r--r--WebCore/platform/gtk/GRefPtrGtk.cpp54
-rw-r--r--WebCore/platform/gtk/GRefPtrGtk.h39
-rw-r--r--WebCore/platform/gtk/KeyEventGtk.cpp17
-rw-r--r--WebCore/platform/gtk/LocalizedStringsGtk.cpp11
-rw-r--r--WebCore/platform/gtk/PasteboardGtk.cpp2
-rw-r--r--WebCore/platform/gtk/PasteboardHelper.h3
-rw-r--r--WebCore/platform/gtk/PlatformScreenGtk.cpp8
-rw-r--r--WebCore/platform/gtk/PopupMenuGtk.cpp34
-rw-r--r--WebCore/platform/gtk/RenderThemeGtk.cpp325
-rw-r--r--WebCore/platform/gtk/RenderThemeGtk.h56
-rw-r--r--WebCore/platform/gtk/ScrollViewGtk.cpp1
-rw-r--r--WebCore/platform/gtk/ScrollbarGtk.cpp1
-rw-r--r--WebCore/platform/gtk/ScrollbarThemeGtk.h5
-rw-r--r--WebCore/platform/gtk/gtk2drawing.c927
-rw-r--r--WebCore/platform/gtk/gtkdrawing.h62
-rw-r--r--WebCore/platform/haiku/LocalizedStringsHaiku.cpp10
-rw-r--r--WebCore/platform/haiku/SharedBufferHaiku.cpp1
-rw-r--r--WebCore/platform/image-decoders/ImageDecoder.cpp71
-rw-r--r--WebCore/platform/image-decoders/ImageDecoder.h31
-rw-r--r--WebCore/platform/image-decoders/bmp/BMPImageReader.h6
-rw-r--r--WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp165
-rw-r--r--WebCore/platform/image-decoders/gif/GIFImageDecoder.h10
-rw-r--r--WebCore/platform/image-decoders/gif/GIFImageReader.cpp38
-rw-r--r--WebCore/platform/image-decoders/gif/GIFImageReader.h4
-rw-r--r--WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp155
-rw-r--r--WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h17
-rw-r--r--WebCore/platform/image-decoders/png/PNGImageDecoder.cpp112
-rw-r--r--WebCore/platform/image-decoders/png/PNGImageDecoder.h5
-rw-r--r--WebCore/platform/image-decoders/qt/RGBA32BufferQt.cpp5
-rw-r--r--WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp5
-rw-r--r--WebCore/platform/image-decoders/xbm/XBMImageDecoder.cpp278
-rw-r--r--WebCore/platform/image-decoders/xbm/XBMImageDecoder.h83
-rw-r--r--WebCore/platform/image-decoders/zlib/adler32.c149
-rw-r--r--WebCore/platform/image-decoders/zlib/compress.c79
-rw-r--r--WebCore/platform/image-decoders/zlib/crc32.c423
-rw-r--r--WebCore/platform/image-decoders/zlib/crc32.h441
-rw-r--r--WebCore/platform/image-decoders/zlib/deflate.c1736
-rw-r--r--WebCore/platform/image-decoders/zlib/deflate.h331
-rw-r--r--WebCore/platform/image-decoders/zlib/gzio.c1026
-rw-r--r--WebCore/platform/image-decoders/zlib/infback.c623
-rw-r--r--WebCore/platform/image-decoders/zlib/inffast.c318
-rw-r--r--WebCore/platform/image-decoders/zlib/inffast.h11
-rw-r--r--WebCore/platform/image-decoders/zlib/inffixed.h94
-rw-r--r--WebCore/platform/image-decoders/zlib/inflate.c1368
-rw-r--r--WebCore/platform/image-decoders/zlib/inflate.h115
-rw-r--r--WebCore/platform/image-decoders/zlib/inftrees.c329
-rw-r--r--WebCore/platform/image-decoders/zlib/inftrees.h55
-rw-r--r--WebCore/platform/image-decoders/zlib/mozzconf.h130
-rw-r--r--WebCore/platform/image-decoders/zlib/trees.c1219
-rw-r--r--WebCore/platform/image-decoders/zlib/trees.h128
-rw-r--r--WebCore/platform/image-decoders/zlib/uncompr.c61
-rw-r--r--WebCore/platform/image-decoders/zlib/zconf.h335
-rw-r--r--WebCore/platform/image-decoders/zlib/zlib.h1357
-rw-r--r--WebCore/platform/image-decoders/zlib/zutil.c318
-rw-r--r--WebCore/platform/image-decoders/zlib/zutil.h269
-rw-r--r--WebCore/platform/mac/GeolocationServiceMac.mm2
-rw-r--r--WebCore/platform/mac/KeyEventMac.mm16
-rw-r--r--WebCore/platform/mac/LocalizedStringsMac.mm17
-rw-r--r--WebCore/platform/mac/PasteboardMac.mm8
-rw-r--r--WebCore/platform/mac/PlatformMouseEventMac.mm18
-rw-r--r--WebCore/platform/mac/PopupMenuMac.mm21
-rw-r--r--WebCore/platform/mac/RuntimeApplicationChecks.h1
-rw-r--r--WebCore/platform/mac/RuntimeApplicationChecks.mm6
-rw-r--r--WebCore/platform/mac/ScrollViewMac.mm17
-rw-r--r--WebCore/platform/mac/ScrollbarThemeMac.mm2
-rw-r--r--WebCore/platform/mac/ThemeMac.mm2
-rw-r--r--WebCore/platform/mac/WebCoreObjCExtras.mm5
-rw-r--r--WebCore/platform/mac/WebCoreSystemInterface.h9
-rw-r--r--WebCore/platform/mac/WebCoreSystemInterface.mm7
-rw-r--r--WebCore/platform/mac/WidgetMac.mm62
-rw-r--r--WebCore/platform/network/CredentialStorage.cpp3
-rw-r--r--WebCore/platform/network/NetworkStateNotifier.h21
-rw-r--r--WebCore/platform/network/ProtectionSpaceHash.h1
-rw-r--r--WebCore/platform/network/ResourceRequestBase.cpp4
-rw-r--r--WebCore/platform/network/ResourceRequestBase.h2
-rw-r--r--WebCore/platform/network/ResourceResponseBase.h4
-rw-r--r--WebCore/platform/network/android/NetworkStateNotifierAndroid.cpp3
-rw-r--r--WebCore/platform/network/cf/DNSCFNet.cpp1
-rw-r--r--WebCore/platform/network/chromium/CookieJarChromium.cpp5
-rw-r--r--WebCore/platform/network/chromium/ResourceRequest.h20
-rw-r--r--WebCore/platform/network/chromium/ResourceResponse.h10
-rw-r--r--WebCore/platform/network/curl/ResourceHandleCurl.cpp6
-rw-r--r--WebCore/platform/network/curl/ResourceHandleManager.cpp4
-rw-r--r--WebCore/platform/network/mac/ResourceHandleMac.mm11
-rw-r--r--WebCore/platform/network/qt/NetworkStateNotifierPrivate.h51
-rw-r--r--WebCore/platform/network/qt/NetworkStateNotifierQt.cpp90
-rw-r--r--WebCore/platform/network/qt/QNetworkReplyHandler.cpp43
-rw-r--r--WebCore/platform/network/qt/QNetworkReplyHandler.h1
-rw-r--r--WebCore/platform/network/qt/ResourceRequestQt.cpp16
-rw-r--r--WebCore/platform/network/qt/SocketStreamHandle.h4
-rw-r--r--WebCore/platform/network/qt/SocketStreamHandlePrivate.h (renamed from WebCore/platform/network/qt/SocketStreamHandleSoup.cpp)82
-rw-r--r--WebCore/platform/network/qt/SocketStreamHandleQt.cpp196
-rw-r--r--WebCore/platform/network/soup/ResourceHandleSoup.cpp8
-rw-r--r--WebCore/platform/qt/DragDataQt.cpp2
-rw-r--r--WebCore/platform/qt/KURLQt.cpp9
-rw-r--r--WebCore/platform/qt/Localizations.cpp11
-rw-r--r--WebCore/platform/qt/PasteboardQt.cpp2
-rw-r--r--WebCore/platform/qt/PlatformKeyboardEventQt.cpp16
-rw-r--r--WebCore/platform/qt/PlatformTouchEventQt.cpp49
-rw-r--r--WebCore/platform/qt/PlatformTouchPointQt.cpp (renamed from WebCore/platform/qt/QWebPopup.h)38
-rw-r--r--WebCore/platform/qt/PopupMenuQt.cpp75
-rw-r--r--WebCore/platform/qt/QWebPageClient.h18
-rw-r--r--WebCore/platform/qt/QWebPopup.cpp87
-rw-r--r--WebCore/platform/qt/QtAbstractWebPopup.cpp60
-rw-r--r--WebCore/platform/qt/QtAbstractWebPopup.h69
-rw-r--r--WebCore/platform/qt/RenderThemeQt.cpp203
-rw-r--r--WebCore/platform/qt/RenderThemeQt.h23
-rw-r--r--WebCore/platform/qt/ScrollViewQt.cpp13
-rw-r--r--WebCore/platform/qt/ScrollbarThemeQt.cpp26
-rw-r--r--WebCore/platform/qt/ScrollbarThemeQt.h8
-rw-r--r--WebCore/platform/qt/SharedBufferQt.cpp2
-rw-r--r--WebCore/platform/sql/SQLiteDatabase.cpp2
-rw-r--r--WebCore/platform/text/AtomicString.cpp12
-rw-r--r--WebCore/platform/text/AtomicString.h2
-rw-r--r--WebCore/platform/text/CharacterNames.h2
-rw-r--r--WebCore/platform/text/PlatformString.h17
-rw-r--r--WebCore/platform/text/String.cpp8
-rw-r--r--WebCore/platform/text/StringBuilder.cpp13
-rw-r--r--WebCore/platform/text/StringBuilder.h3
-rw-r--r--WebCore/platform/text/StringHash.h6
-rw-r--r--WebCore/platform/text/StringImpl.cpp3
-rw-r--r--WebCore/platform/text/StringImpl.h99
-rw-r--r--WebCore/platform/text/TextCodecICU.cpp2
-rw-r--r--WebCore/platform/text/TextEncoding.cpp2
-rw-r--r--WebCore/platform/text/TextEncodingDetectorICU.cpp2
-rw-r--r--WebCore/platform/text/TextEncodingRegistry.cpp6
-rw-r--r--WebCore/platform/text/TextStream.cpp9
-rw-r--r--WebCore/platform/text/TextStream.h3
-rw-r--r--WebCore/platform/text/chromium/TextBreakIteratorInternalICUChromium.cpp19
-rw-r--r--WebCore/platform/text/qt/TextCodecQt.cpp2
-rw-r--r--WebCore/platform/text/wince/TextBreakIteratorWince.cpp3
-rw-r--r--WebCore/platform/win/ClipboardUtilitiesWin.cpp4
-rw-r--r--WebCore/platform/win/ClipboardWin.cpp12
-rw-r--r--WebCore/platform/win/CursorWin.cpp5
-rw-r--r--WebCore/platform/win/EventLoopWin.cpp2
-rw-r--r--WebCore/platform/win/FileSystemWin.cpp1
-rw-r--r--WebCore/platform/win/PlatformMouseEventWin.cpp4
-rw-r--r--WebCore/platform/win/PlatformScreenWin.cpp5
-rw-r--r--WebCore/platform/win/PopupMenuWin.cpp24
-rw-r--r--WebCore/platform/win/SharedBufferWin.cpp2
-rw-r--r--WebCore/platform/win/SystemInfo.cpp2
-rw-r--r--WebCore/platform/win/SystemTimeWin.cpp2
-rw-r--r--WebCore/platform/win/WidgetWin.cpp1
-rw-r--r--WebCore/platform/wince/MIMETypeRegistryWince.cpp1
-rw-r--r--WebCore/platform/wince/SearchPopupMenuWince.cpp1
-rw-r--r--WebCore/platform/wince/SharedTimerWince.cpp2
-rw-r--r--WebCore/platform/wx/ContextMenuWx.cpp2
-rw-r--r--WebCore/platform/wx/FileSystemWx.cpp6
-rw-r--r--WebCore/platform/wx/LocalizedStringsWx.cpp10
-rw-r--r--WebCore/platform/wx/RenderThemeWx.cpp8
-rw-r--r--WebCore/platform/wx/ScrollViewWx.cpp8
328 files changed, 10356 insertions, 14303 deletions
diff --git a/WebCore/platform/ContextMenu.cpp b/WebCore/platform/ContextMenu.cpp
index 771798a..236279e 100644
--- a/WebCore/platform/ContextMenu.cpp
+++ b/WebCore/platform/ContextMenu.cpp
@@ -276,7 +276,9 @@ void ContextMenu::populate()
ContextMenuItem LookInDictionaryItem(ActionType, ContextMenuItemTagLookUpInDictionary,
contextMenuItemTagLookUpInDictionary());
#endif
+#if !PLATFORM(GTK)
ContextMenuItem SearchWebItem(ActionType, ContextMenuItemTagSearchWeb, contextMenuItemTagSearchWeb());
+#endif
ContextMenuItem CopyItem(ActionType, ContextMenuItemTagCopy, contextMenuItemTagCopy());
ContextMenuItem BackItem(ActionType, ContextMenuItemTagGoBack, contextMenuItemTagGoBack());
ContextMenuItem ForwardItem(ActionType, ContextMenuItemTagGoForward, contextMenuItemTagGoForward());
@@ -341,8 +343,10 @@ void ContextMenu::populate()
#if PLATFORM(MAC)
appendItem(SearchSpotlightItem);
#endif
+#if !PLATFORM(GTK)
appendItem(SearchWebItem);
appendItem(*separatorItem());
+#endif
#if PLATFORM(MAC)
appendItem(LookInDictionaryItem);
appendItem(*separatorItem());
@@ -445,8 +449,10 @@ void ContextMenu::populate()
#if PLATFORM(MAC)
appendItem(SearchSpotlightItem);
#endif
+#if !PLATFORM(GTK)
appendItem(SearchWebItem);
appendItem(*separatorItem());
+#endif
#if PLATFORM(MAC)
appendItem(LookInDictionaryItem);
@@ -466,10 +472,12 @@ void ContextMenu::populate()
if (!inPasswordField) {
appendItem(*separatorItem());
#ifndef BUILDING_ON_TIGER
+#if !PLATFORM(GTK)
ContextMenuItem SpellingAndGrammarMenuItem(SubmenuType, ContextMenuItemTagSpellingMenu,
contextMenuItemTagSpellingMenu());
createAndAppendSpellingAndGrammarSubMenu(m_hitTestResult, SpellingAndGrammarMenuItem);
appendItem(SpellingAndGrammarMenuItem);
+#endif
#else
ContextMenuItem SpellingMenuItem(SubmenuType, ContextMenuItemTagSpellingMenu,
contextMenuItemTagSpellingMenu());
@@ -486,10 +494,17 @@ void ContextMenu::populate()
createAndAppendTransformationsSubMenu(m_hitTestResult, transformationsMenuItem);
appendItem(transformationsMenuItem);
#endif
- ContextMenuItem FontMenuItem(SubmenuType, ContextMenuItemTagFontMenu,
- contextMenuItemTagFontMenu());
- createAndAppendFontSubMenu(m_hitTestResult, FontMenuItem);
- appendItem(FontMenuItem);
+#if PLATFORM(GTK)
+ bool shouldShowFontMenu = frame->editor()->canEditRichly();
+#else
+ bool shouldShowFontMenu = true;
+#endif
+ if (shouldShowFontMenu) {
+ ContextMenuItem FontMenuItem(SubmenuType, ContextMenuItemTagFontMenu,
+ contextMenuItemTagFontMenu());
+ createAndAppendFontSubMenu(m_hitTestResult, FontMenuItem);
+ appendItem(FontMenuItem);
+ }
#if PLATFORM(MAC)
ContextMenuItem SpeechMenuItem(SubmenuType, ContextMenuItemTagSpeechMenu, contextMenuItemTagSpeechMenu());
createAndAppendSpeechSubMenu(m_hitTestResult, SpeechMenuItem);
diff --git a/WebCore/platform/CrossThreadCopier.cpp b/WebCore/platform/CrossThreadCopier.cpp
index d02da6c..683ba54 100644
--- a/WebCore/platform/CrossThreadCopier.cpp
+++ b/WebCore/platform/CrossThreadCopier.cpp
@@ -32,6 +32,7 @@
#include "CrossThreadCopier.h"
+#include "KURL.h"
#include "PlatformString.h"
#include "ResourceError.h"
#include "ResourceRequest.h"
@@ -39,22 +40,27 @@
namespace WebCore {
-CrossThreadCopierBase<false, String>::Type CrossThreadCopierBase<false, String>::copy(const String& str)
+CrossThreadCopierBase<false, false, KURL>::Type CrossThreadCopierBase<false, false, KURL>::copy(const KURL& url)
+{
+ return url.copy();
+}
+
+CrossThreadCopierBase<false, false, String>::Type CrossThreadCopierBase<false, false, String>::copy(const String& str)
{
return str.crossThreadString();
}
-CrossThreadCopierBase<false, ResourceError>::Type CrossThreadCopierBase<false, ResourceError>::copy(const ResourceError& error)
+CrossThreadCopierBase<false, false, ResourceError>::Type CrossThreadCopierBase<false, false, ResourceError>::copy(const ResourceError& error)
{
return error.copy();
}
-CrossThreadCopierBase<false, ResourceRequest>::Type CrossThreadCopierBase<false, ResourceRequest>::copy(const ResourceRequest& request)
+CrossThreadCopierBase<false, false, ResourceRequest>::Type CrossThreadCopierBase<false, false, ResourceRequest>::copy(const ResourceRequest& request)
{
return request.copyData();
}
-CrossThreadCopierBase<false, ResourceResponse>::Type CrossThreadCopierBase<false, ResourceResponse>::copy(const ResourceResponse& response)
+CrossThreadCopierBase<false, false, ResourceResponse>::Type CrossThreadCopierBase<false, false, ResourceResponse>::copy(const ResourceResponse& response)
{
return response.copyData();
}
diff --git a/WebCore/platform/CrossThreadCopier.h b/WebCore/platform/CrossThreadCopier.h
index 2bdf57d..0a9aeeb 100644
--- a/WebCore/platform/CrossThreadCopier.h
+++ b/WebCore/platform/CrossThreadCopier.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2009, 2010 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -40,6 +40,7 @@
namespace WebCore {
+ class KURL;
class ResourceError;
class ResourceRequest;
class ResourceResponse;
@@ -56,29 +57,30 @@ namespace WebCore {
}
};
- template<bool isConvertibleToInteger, typename T> struct CrossThreadCopierBase;
+ template<bool isConvertibleToInteger, bool isThreadsafeShared, typename T> struct CrossThreadCopierBase;
// Integers get passed through without any changes.
- template<typename T> struct CrossThreadCopierBase<true, T> : public CrossThreadCopierPassThrough<T> {
+ template<typename T> struct CrossThreadCopierBase<true, false, T> : public CrossThreadCopierPassThrough<T> {
};
// Pointers get passed through without any significant changes.
- template<typename T> struct CrossThreadCopierBase<false, T*> : public CrossThreadCopierPassThrough<T*> {
+ template<typename T> struct CrossThreadCopierBase<false, false, T*> : public CrossThreadCopierPassThrough<T*> {
};
- template<> struct CrossThreadCopierBase<false, ThreadableLoaderOptions> : public CrossThreadCopierPassThrough<ThreadableLoaderOptions> {
+ template<> struct CrossThreadCopierBase<false, false, ThreadableLoaderOptions> : public CrossThreadCopierPassThrough<ThreadableLoaderOptions> {
};
// Custom copy methods.
- template<typename T> struct CrossThreadCopierBase<false, RefPtr<ThreadSafeShared<T> > > {
- typedef PassRefPtr<T> Type;
- static Type copy(const RefPtr<ThreadSafeShared<T> >& refPtr)
+ template<typename T> struct CrossThreadCopierBase<false, true, T> {
+ typedef typename WTF::RemoveTemplate<T, RefPtr>::Type RefCountedType;
+ typedef PassRefPtr<RefCountedType> Type;
+ static Type copy(const T& refPtr)
{
- return PassRefPtr<T>(static_cast<T*>(refPtr.get()));
+ return refPtr.get();
}
};
- template<typename T> struct CrossThreadCopierBase<false, PassOwnPtr<T> > {
+ template<typename T> struct CrossThreadCopierBase<false, false, PassOwnPtr<T> > {
typedef PassOwnPtr<T> Type;
static Type copy(const PassOwnPtr<T>& ownPtr)
{
@@ -86,7 +88,7 @@ namespace WebCore {
}
};
- template<typename T> struct CrossThreadCopierBase<false, std::auto_ptr<T> > {
+ template<typename T> struct CrossThreadCopierBase<false, false, std::auto_ptr<T> > {
typedef std::auto_ptr<T> Type;
static Type copy(const std::auto_ptr<T>& autoPtr)
{
@@ -94,27 +96,34 @@ namespace WebCore {
}
};
- template<> struct CrossThreadCopierBase<false, String> {
+ template<> struct CrossThreadCopierBase<false, false, KURL> {
+ typedef KURL Type;
+ static Type copy(const KURL&);
+ };
+
+ template<> struct CrossThreadCopierBase<false, false, String> {
typedef String Type;
static Type copy(const String&);
};
- template<> struct CrossThreadCopierBase<false, ResourceError> {
+ template<> struct CrossThreadCopierBase<false, false, ResourceError> {
typedef ResourceError Type;
static Type copy(const ResourceError&);
};
- template<> struct CrossThreadCopierBase<false, ResourceRequest> {
+ template<> struct CrossThreadCopierBase<false, false, ResourceRequest> {
typedef std::auto_ptr<CrossThreadResourceRequestData> Type;
static Type copy(const ResourceRequest&);
};
- template<> struct CrossThreadCopierBase<false, ResourceResponse> {
+ template<> struct CrossThreadCopierBase<false, false, ResourceResponse> {
typedef std::auto_ptr<CrossThreadResourceResponseData> Type;
static Type copy(const ResourceResponse&);
};
- template<typename T> struct CrossThreadCopier : public CrossThreadCopierBase<WTF::IsConvertibleToInteger<T>::value, T> {
+ template<typename T> struct CrossThreadCopier : public CrossThreadCopierBase<WTF::IsConvertibleToInteger<T>::value,
+ WTF::IsSubclassOfTemplate<typename WTF::RemoveTemplate<T, RefPtr>::Type, ThreadSafeShared>::value,
+ T> {
};
} // namespace WebCore
diff --git a/WebCore/platform/Cursor.h b/WebCore/platform/Cursor.h
index 2d041d2..ae8043e 100644
--- a/WebCore/platform/Cursor.h
+++ b/WebCore/platform/Cursor.h
@@ -56,6 +56,11 @@ class NSCursor;
class wxCursor;
#endif
+#if PLATFORM(WIN)
+typedef struct HICON__ *HICON;
+typedef HICON HCURSOR;
+#endif
+
namespace WebCore {
class Image;
@@ -65,7 +70,7 @@ namespace WebCore {
class SharedCursor : public RefCounted<SharedCursor> {
public:
static PassRefPtr<SharedCursor> create(HCURSOR nativeCursor) { return adoptRef(new SharedCursor(nativeCursor)); }
- ~SharedCursor() { DestroyIcon(m_nativeCursor); }
+ ~SharedCursor();
HCURSOR nativeCursor() const { return m_nativeCursor; }
private:
SharedCursor(HCURSOR nativeCursor) : m_nativeCursor(nativeCursor) { }
diff --git a/WebCore/platform/FileChooser.h b/WebCore/platform/FileChooser.h
index 1d4e970..0764a6a 100644
--- a/WebCore/platform/FileChooser.h
+++ b/WebCore/platform/FileChooser.h
@@ -42,6 +42,7 @@ class FileChooserClient {
public:
virtual void valueChanged() = 0;
virtual bool allowsMultipleFiles() = 0;
+ virtual String acceptTypes() = 0;
virtual ~FileChooserClient();
};
@@ -64,6 +65,8 @@ public:
void chooseFiles(const Vector<String>& paths);
bool allowsMultipleFiles() const { return m_client ? m_client->allowsMultipleFiles() : false; }
+ // Acceptable MIME types. It's an 'accept' attribute value of the corresponding INPUT element.
+ String acceptTypes() const { return m_client ? m_client->acceptTypes() : String(); }
private:
FileChooser(FileChooserClient*, const Vector<String>& initialFilenames);
diff --git a/WebCore/platform/FileSystem.h b/WebCore/platform/FileSystem.h
index 3220d51..c5395a9 100644
--- a/WebCore/platform/FileSystem.h
+++ b/WebCore/platform/FileSystem.h
@@ -54,7 +54,7 @@
typedef const struct __CFData* CFDataRef;
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
// These are to avoid including <winbase.h> in a header for Chromium
typedef void *HANDLE;
// Assuming STRICT
@@ -67,7 +67,7 @@ namespace WebCore {
class CString;
// PlatformModule
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
typedef HMODULE PlatformModule;
#elif PLATFORM(QT)
#if defined(Q_WS_MAC)
@@ -84,7 +84,7 @@ typedef void* PlatformModule;
#endif
// PlatformModuleVersion
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
struct PlatformModuleVersion {
unsigned leastSig;
unsigned mostSig;
@@ -110,7 +110,7 @@ typedef unsigned PlatformModuleVersion;
#if PLATFORM(QT)
typedef QFile* PlatformFileHandle;
const PlatformFileHandle invalidPlatformFileHandle = 0;
-#elif PLATFORM(WIN_OS)
+#elif OS(WINDOWS)
typedef HANDLE PlatformFileHandle;
// FIXME: -1 is INVALID_HANDLE_VALUE, defined in <winbase.h>. Chromium tries to
// avoid using Windows headers in headers. We'd rather move this into the .cpp.
diff --git a/WebCore/platform/GeolocationService.cpp b/WebCore/platform/GeolocationService.cpp
index e60ef00..be9553b 100644
--- a/WebCore/platform/GeolocationService.cpp
+++ b/WebCore/platform/GeolocationService.cpp
@@ -34,7 +34,7 @@
namespace WebCore {
-#if !ENABLE(GEOLOCATION)
+#if !ENABLE(GEOLOCATION) || ENABLE(CLIENT_BASED_GEOLOCATION)
static GeolocationService* createGeolocationServiceNull(GeolocationServiceClient*)
{
return 0;
diff --git a/WebCore/platform/KURL.cpp b/WebCore/platform/KURL.cpp
index a8f7969..9783bd8 100644
--- a/WebCore/platform/KURL.cpp
+++ b/WebCore/platform/KURL.cpp
@@ -32,12 +32,16 @@
#include "CString.h"
#include "StringHash.h"
#include "TextEncoding.h"
+#include <wtf/HashMap.h>
#include <wtf/StdLibExtras.h>
#if USE(ICU_UNICODE)
#include <unicode/uidna.h>
#elif USE(QT4_UNICODE)
#include <QUrl>
+#elif USE(GLIB_UNICODE)
+#include <glib.h>
+#include <wtf/gtk/GOwnPtr.h>
#endif
#include <stdio.h>
@@ -214,6 +218,7 @@ static const unsigned char characterClassTable[256] = {
static int copyPathRemovingDots(char* dst, const char* src, int srcStart, int srcEnd);
static void encodeRelativeString(const String& rel, const TextEncoding&, CharBuffer& ouput);
static String substituteBackslashes(const String&);
+static bool isValidProtocol(const String&);
static inline bool isSchemeFirstChar(char c) { return characterClassTable[static_cast<unsigned char>(c)] & SchemeFirstChar; }
static inline bool isSchemeFirstChar(UChar c) { return c <= 0xff && (characterClassTable[c] & SchemeFirstChar); }
@@ -659,17 +664,22 @@ String KURL::path() const
return decodeURLEscapeSequences(m_string.substring(m_portEnd, m_pathEnd - m_portEnd));
}
-void KURL::setProtocol(const String& s)
+bool KURL::setProtocol(const String& s)
{
- // FIXME: Non-ASCII characters must be encoded and escaped to match parse() expectations,
- // and to avoid changing more than just the protocol.
+ // Firefox and IE remove everything after the first ':'.
+ int separatorPosition = s.find(':');
+ String newProtocol = s.substring(0, separatorPosition);
+
+ if (!isValidProtocol(newProtocol))
+ return false;
if (!m_isValid) {
- parse(s + ":" + m_string);
- return;
+ parse(newProtocol + ":" + m_string);
+ return true;
}
- parse(s + m_string.substring(m_schemeEnd));
+ parse(newProtocol + m_string.substring(m_schemeEnd));
+ return true;
}
void KURL::setHost(const String& s)
@@ -1404,6 +1414,19 @@ static void appendEncodedHostname(UCharBuffer& buffer, const UChar* str, unsigne
#elif USE(QT4_UNICODE)
QByteArray result = QUrl::toAce(String(str, strLen));
buffer.append(result.constData(), result.length());
+#elif USE(GLIB_UNICODE)
+ GOwnPtr<gchar> utf8Hostname;
+ GOwnPtr<GError> utf8Err;
+ utf8Hostname.set(g_utf16_to_utf8(str, strLen, 0, 0, &utf8Err.outPtr()));
+ if (utf8Err)
+ return;
+
+ GOwnPtr<gchar> encodedHostname;
+ encodedHostname.set(g_hostname_to_ascii(utf8Hostname.get()));
+ if (!encodedHostname)
+ return;
+
+ buffer.append(encodedHostname.get(), strlen(encodedHostname.get()));
#endif
}
@@ -1630,6 +1653,9 @@ bool protocolIsJavaScript(const String& url)
bool isValidProtocol(const String& protocol)
{
+ // RFC3986: ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
+ if (protocol.isEmpty())
+ return false;
if (!isSchemeFirstChar(protocol[0]))
return false;
unsigned protocolLength = protocol.length();
diff --git a/WebCore/platform/KURL.h b/WebCore/platform/KURL.h
index 647330d..6cd8f96 100644
--- a/WebCore/platform/KURL.h
+++ b/WebCore/platform/KURL.h
@@ -50,6 +50,10 @@ QT_END_NAMESPACE
#include "KURLGooglePrivate.h"
#endif
+#if USE(JSC)
+#include <runtime/UString.h>
+#endif
+
namespace WebCore {
class TextEncoding;
@@ -140,7 +144,7 @@ public:
bool protocolInHTTPFamily() const;
bool isLocalFile() const;
- void setProtocol(const String&);
+ bool setProtocol(const String&);
void setHost(const String&);
void removePort();
@@ -262,7 +266,6 @@ const KURL& blankURL();
bool protocolIs(const String& url, const char* protocol);
bool protocolIsJavaScript(const String& url);
-bool isValidProtocol(const String& protocol);
bool isDefaultPortForProtocol(unsigned short port, const String& protocol);
bool portAllowed(const KURL&); // Blacklist ports that should never be used for Web resources.
diff --git a/WebCore/platform/KURLGoogle.cpp b/WebCore/platform/KURLGoogle.cpp
index 76b5612..65ca346 100644
--- a/WebCore/platform/KURLGoogle.cpp
+++ b/WebCore/platform/KURLGoogle.cpp
@@ -44,6 +44,7 @@
#include "StringHash.h"
#include "NotImplemented.h"
#include "TextEncoding.h"
+#include <wtf/HashMap.h>
#include <wtf/Vector.h>
#include <wtf/StdLibExtras.h>
@@ -569,12 +570,13 @@ String KURL::path() const
return m_url.componentString(m_url.m_parsed.path);
}
-void KURL::setProtocol(const String& protocol)
+bool KURL::setProtocol(const String& protocol)
{
KURLGooglePrivate::Replacements replacements;
replacements.SetScheme(CharactersOrEmpty(protocol),
url_parse::Component(0, protocol.length()));
m_url.replaceComponents(replacements);
+ return true;
}
void KURL::setHost(const String& host)
@@ -733,18 +735,6 @@ bool protocolIsJavaScript(const String& url)
return protocolIs(url, "javascript");
}
-bool isValidProtocol(const String& protocol)
-{
- if (!isSchemeFirstChar(protocol[0]))
- return false;
- unsigned protocolLength = protocol.length();
- for (unsigned i = 1; i < protocolLength; i++) {
- if (!isSchemeChar(protocol[i]))
- return false;
- }
- return true;
-}
-
// We copied the KURL version here on Dec 4, 2009 while doing a WebKit
// merge.
//
diff --git a/WebCore/platform/KeyboardCodes.h b/WebCore/platform/KeyboardCodes.h
index 48582a8..04ee071 100644
--- a/WebCore/platform/KeyboardCodes.h
+++ b/WebCore/platform/KeyboardCodes.h
@@ -33,7 +33,7 @@
// FIXME: We should get rid of these Chromium-related ifdefs.
#if PLATFORM(CHROMIUM)
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
#include "KeyboardCodesWin.h"
#else
#include "KeyboardCodesPosix.h"
@@ -43,7 +43,7 @@
namespace WebCore {
-#if !PLATFORM(WIN_OS)
+#if !OS(WINDOWS)
// VK_LBUTTON (01) Left mouse button
// VK_RBUTTON (02) Right mouse button
// VK_CANCEL (03) Control-break processing
@@ -160,7 +160,7 @@ const int VK_DELETE = 0x2E;
// VK_HELP (2F) HELP key
const int VK_HELP = 0x2F;
-#endif // PLATFORM(WIN_OS)
+#endif // OS(WINDOWS)
// (30) 0 key
const int VK_0 = 0x30;
@@ -271,7 +271,7 @@ const int VK_Y = 0x59;
// (5A) Z key
const int VK_Z = 0x5A;
-#if !PLATFORM(WIN_OS)
+#if !OS(WINDOWS)
// VK_LWIN (5B) Left Windows key (Microsoft Natural keyboard)
const int VK_LWIN = 0x5B;
@@ -483,9 +483,9 @@ const int VK_MEDIA_LAUNCH_APP1 = 0xB6;
// VK_LAUNCH_APP2 (B7) Windows 2000/XP: Start Application 2 key
const int VK_MEDIA_LAUNCH_APP2 = 0xB7;
-#endif // !PLATFORM(WIN_OS)
+#endif // !OS(WINDOWS)
-#if !PLATFORM(WIN_OS) || PLATFORM(WINCE)
+#if !OS(WINDOWS) || OS(WINCE)
// VK_OEM_1 (BA) Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US standard keyboard, the ';:' key
const int VK_OEM_1 = 0xBA;
@@ -523,9 +523,9 @@ const int VK_OEM_7 = 0xDE;
// VK_OEM_8 (DF) Used for miscellaneous characters; it can vary by keyboard.
const int VK_OEM_8 = 0xDF;
-#endif // !PLATFORM(WIN_OS) || PLATFORM(WINCE)
+#endif // !OS(WINDOWS) || OS(WINCE)
-#if !PLATFORM(WIN_OS)
+#if !OS(WINDOWS)
// VK_OEM_102 (E2) Windows 2000/XP: Either the angle bracket key or the backslash key on the RT 102-key keyboard
const int VK_OEM_102 = 0xE2;
@@ -565,7 +565,7 @@ const int VK_OEM_CLEAR = 0xFE;
const int VK_UNKNOWN = 0;
-#endif // PLATFORM(WIN_OS)
+#endif // OS(WINDOWS)
}
diff --git a/WebCore/platform/LinkHash.cpp b/WebCore/platform/LinkHash.cpp
index 878933a..c399aa2 100644
--- a/WebCore/platform/LinkHash.cpp
+++ b/WebCore/platform/LinkHash.cpp
@@ -81,7 +81,7 @@ static inline bool containsColonSlashSlash(const UChar* characters, unsigned len
static inline void cleanPath(Vector<UChar, 512>& path)
{
- // FIXME: Shold not do this in the query or anchor part.
+ // FIXME: Should not do this in the query or anchor part.
int pos;
while ((pos = findSlashDotDotSlash(path.data(), path.size())) != -1) {
int prev = reverseFind(path.data(), path.size(), '/', pos - 1);
@@ -92,7 +92,7 @@ static inline void cleanPath(Vector<UChar, 512>& path)
path.remove(prev, pos - prev + 3);
}
- // FIXME: Shold not do this in the query part.
+ // FIXME: Should not do this in the query part.
// Set refPos to -2 to mean "I haven't looked for the anchor yet".
// We don't want to waste a function call on the search for the the anchor
// in the vast majority of cases where there is no "//" in the path.
@@ -110,7 +110,7 @@ static inline void cleanPath(Vector<UChar, 512>& path)
pos += 2;
}
- // FIXME: Shold not do this in the query or anchor part.
+ // FIXME: Should not do this in the query or anchor part.
while ((pos = findSlashDotSlash(path.data(), path.size())) != -1)
path.remove(pos, 2);
}
diff --git a/WebCore/platform/LocalizedStrings.h b/WebCore/platform/LocalizedStrings.h
index f7a6fa6..6ca5773 100644
--- a/WebCore/platform/LocalizedStrings.h
+++ b/WebCore/platform/LocalizedStrings.h
@@ -124,6 +124,8 @@ namespace WebCore {
String AXTextFieldActionVerb();
String AXCheckedCheckBoxActionVerb();
String AXUncheckedCheckBoxActionVerb();
+ String AXMenuListActionVerb();
+ String AXMenuListPopupActionVerb();
String AXLinkActionVerb();
String multipleFileUploadText(unsigned numberOfFiles);
diff --git a/WebCore/platform/PlatformKeyboardEvent.h b/WebCore/platform/PlatformKeyboardEvent.h
index cbbb48d..2b94cce 100644
--- a/WebCore/platform/PlatformKeyboardEvent.h
+++ b/WebCore/platform/PlatformKeyboardEvent.h
@@ -130,6 +130,7 @@ namespace WebCore {
static bool currentCapsLockState();
#if PLATFORM(MAC)
+ PlatformKeyboardEvent();
PlatformKeyboardEvent(NSEvent*);
NSEvent* macEvent() const { return m_macEvent.get(); }
#endif
diff --git a/WebCore/platform/PlatformMouseEvent.h b/WebCore/platform/PlatformMouseEvent.h
index 99acc63..436a902 100644
--- a/WebCore/platform/PlatformMouseEvent.h
+++ b/WebCore/platform/PlatformMouseEvent.h
@@ -114,8 +114,13 @@ namespace WebCore {
PlatformMouseEvent(GdkEventMotion*);
#endif
-#if PLATFORM(MAC) && defined(__OBJC__)
+#if PLATFORM(MAC)
+#if defined(__OBJC__)
PlatformMouseEvent(NSEvent *, NSView *windowView);
+#endif
+ PlatformMouseEvent(int x, int y, int globalX, int globalY, MouseButton button, MouseEventType eventType,
+ int clickCount, bool shiftKey, bool ctrlKey, bool altKey, bool metaKey, double timestamp,
+ unsigned modifierFlags, int eventNumber);
int eventNumber() const { return m_eventNumber; }
#endif
diff --git a/WebCore/platform/PlatformTouchEvent.h b/WebCore/platform/PlatformTouchEvent.h
index 854db3c..263dee0 100644
--- a/WebCore/platform/PlatformTouchEvent.h
+++ b/WebCore/platform/PlatformTouchEvent.h
@@ -42,10 +42,13 @@ enum TouchEventType {
, TouchMove
, TouchEnd
, TouchCancel
+<<<<<<< HEAD
#if PLATFORM(ANDROID)
, TouchLongPress
, TouchDoubleTap
#endif
+=======
+>>>>>>> webkit.org at r54127
};
class PlatformTouchEvent {
@@ -60,8 +63,12 @@ public:
#if PLATFORM(QT)
PlatformTouchEvent(QTouchEvent*);
#elif PLATFORM(ANDROID)
+<<<<<<< HEAD
// TODO (benm): eventTime is new and needs to be upstream
PlatformTouchEvent(const IntPoint& windowPos, TouchEventType, PlatformTouchPoint::State, long eventTime);
+=======
+ PlatformTouchEvent(const IntPoint& windowPos, TouchEventType, PlatformTouchPoint::State);
+>>>>>>> webkit.org at r54127
#endif
TouchEventType type() const { return m_type; }
@@ -72,8 +79,11 @@ public:
bool shiftKey() const { return m_shiftKey; }
bool metaKey() const { return m_metaKey; }
+<<<<<<< HEAD
long eventTime() const { return m_eventTime; }
+=======
+>>>>>>> webkit.org at r54127
private:
TouchEventType m_type;
Vector<PlatformTouchPoint> m_touchPoints;
@@ -81,7 +91,10 @@ private:
bool m_altKey;
bool m_shiftKey;
bool m_metaKey;
+<<<<<<< HEAD
long m_eventTime;
+=======
+>>>>>>> webkit.org at r54127
};
}
diff --git a/WebCore/platform/PlatformWheelEvent.h b/WebCore/platform/PlatformWheelEvent.h
index 9a4a0cb..b8e0bb4 100644
--- a/WebCore/platform/PlatformWheelEvent.h
+++ b/WebCore/platform/PlatformWheelEvent.h
@@ -68,6 +68,20 @@ namespace WebCore {
class PlatformWheelEvent {
public:
+ PlatformWheelEvent()
+ : m_deltaX(0)
+ , m_deltaY(0)
+ , m_wheelTicksX(0)
+ , m_wheelTicksY(0)
+ , m_granularity(ScrollByPixelWheelEvent)
+ , m_isAccepted(false)
+ , m_shiftKey(false)
+ , m_ctrlKey(false)
+ , m_altKey(false)
+ , m_metaKey(false)
+ {
+ }
+
const IntPoint& pos() const { return m_position; } // PlatformWindow coordinates.
const IntPoint& globalPos() const { return m_globalPosition; } // Screen coordinates.
diff --git a/WebCore/platform/PopupMenu.h b/WebCore/platform/PopupMenu.h
index 2315f02..449d475 100644
--- a/WebCore/platform/PopupMenu.h
+++ b/WebCore/platform/PopupMenu.h
@@ -42,12 +42,13 @@ typedef struct HDC__* HDC;
typedef struct HBITMAP__* HBITMAP;
#elif PLATFORM(QT)
namespace WebCore {
- class QWebPopup;
+class QtAbstractWebPopup;
}
#elif PLATFORM(GTK)
typedef struct _GtkMenu GtkMenu;
typedef struct _GtkMenuItem GtkMenuItem;
typedef struct _GtkWidget GtkWidget;
+#include "GRefPtrGtk.h"
#include <wtf/HashMap.h>
#include <glib.h>
#elif PLATFORM(WX)
@@ -144,9 +145,7 @@ private:
RetainPtr<NSPopUpButtonCell> m_popup;
#elif PLATFORM(QT)
- void clear();
- void populate(const IntRect&);
- QWebPopup* m_popup;
+ QtAbstractWebPopup* m_popup;
#elif PLATFORM(WIN)
// ScrollBarClient
virtual void valueChanged(Scrollbar*);
@@ -175,7 +174,7 @@ private:
bool m_showPopup;
#elif PLATFORM(GTK)
IntPoint m_menuPosition;
- GtkMenu* m_popup;
+ GRefPtr<GtkMenu> m_popup;
HashMap<GtkWidget*, int> m_indexMap;
static void menuItemActivated(GtkMenuItem* item, PopupMenu*);
static void menuUnmapped(GtkWidget*, PopupMenu*);
diff --git a/WebCore/platform/PurgeableBuffer.h b/WebCore/platform/PurgeableBuffer.h
index c487eb9..94e58da 100644
--- a/WebCore/platform/PurgeableBuffer.h
+++ b/WebCore/platform/PurgeableBuffer.h
@@ -62,7 +62,7 @@ namespace WebCore {
mutable State m_state;
};
-#if !PLATFORM(DARWIN) || defined(BUILDING_ON_TIGER) || PLATFORM(QT) || PLATFORM(GTK)
+#if !OS(DARWIN) || defined(BUILDING_ON_TIGER) || PLATFORM(QT) || PLATFORM(GTK)
inline PurgeableBuffer* PurgeableBuffer::create(const char*, size_t) { return 0; }
inline PurgeableBuffer::~PurgeableBuffer() { }
inline const char* PurgeableBuffer::data() const { return 0; }
diff --git a/WebCore/platform/ScrollView.cpp b/WebCore/platform/ScrollView.cpp
index 19a1dca..c8230a6 100644
--- a/WebCore/platform/ScrollView.cpp
+++ b/WebCore/platform/ScrollView.cpp
@@ -429,9 +429,7 @@ void ScrollView::updateScrollbars(const IntSize& desiredOffset)
if (m_horizontalScrollbar) {
int clientWidth = visibleWidth();
m_horizontalScrollbar->setEnabled(contentsWidth() > clientWidth);
- int pageStep = (clientWidth - cAmountToKeepWhenPaging);
- if (pageStep < 0)
- pageStep = clientWidth;
+ int pageStep = max(clientWidth * cFractionToStepWhenPaging, 1.f);
IntRect oldRect(m_horizontalScrollbar->frameRect());
IntRect hBarRect = IntRect(0,
height() - m_horizontalScrollbar->height(),
@@ -453,7 +451,7 @@ void ScrollView::updateScrollbars(const IntSize& desiredOffset)
if (m_verticalScrollbar) {
int clientHeight = visibleHeight();
m_verticalScrollbar->setEnabled(contentsHeight() > clientHeight);
- int pageStep = (clientHeight - cAmountToKeepWhenPaging);
+ int pageStep = max(clientHeight * cFractionToStepWhenPaging, 1.f);
if (pageStep < 0)
pageStep = clientHeight;
IntRect oldRect(m_verticalScrollbar->frameRect());
@@ -517,7 +515,7 @@ void ScrollView::scrollContents(const IntSize& scrollDelta)
hostWindow()->repaint(panScrollIconDirtyRect, true);
}
- if (canBlitOnScroll() && !rootPreventsBlitting()) { // The main frame can just blit the WebView window
+ if (canBlitOnScroll()) { // The main frame can just blit the WebView window
// FIXME: Find a way to blit subframes without blitting overlapping content
hostWindow()->scroll(-scrollDelta, scrollViewRect, clipRect);
} else {
@@ -607,14 +605,6 @@ void ScrollView::setParent(ScrollView* parentView)
if (m_scrollbarsAvoidingResizer && parent())
parent()->adjustScrollbarsAvoidingResizerCount(-m_scrollbarsAvoidingResizer);
-#if PLATFORM(QT)
- if (m_widgetsPreventingBlitting && parent())
- parent()->adjustWidgetsPreventingBlittingCount(-m_widgetsPreventingBlitting);
-
- if (m_widgetsPreventingBlitting && parentView)
- parentView->adjustWidgetsPreventingBlittingCount(m_widgetsPreventingBlitting);
-#endif
-
Widget::setParent(parentView);
if (m_scrollbarsAvoidingResizer && parent())
@@ -677,7 +667,7 @@ void ScrollView::wheelEvent(PlatformWheelEvent& e)
if (e.granularity() == ScrollByPageWheelEvent) {
ASSERT(deltaX == 0);
bool negative = deltaY < 0;
- deltaY = max(0, visibleHeight() - cAmountToKeepWhenPaging);
+ deltaY = max(visibleHeight() * cFractionToStepWhenPaging, 1.f);
if (negative)
deltaY = -deltaY;
}
@@ -973,7 +963,7 @@ void ScrollView::platformDestroy()
#endif
-#if (!PLATFORM(WX) && !PLATFORM(GTK) && !PLATFORM(QT) && !PLATFORM(MAC)) || ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE)
+#if !PLATFORM(WX) && !PLATFORM(GTK) && !PLATFORM(QT) && !PLATFORM(MAC)
void ScrollView::platformAddChild(Widget*)
{
@@ -985,15 +975,15 @@ void ScrollView::platformRemoveChild(Widget*)
#endif
-#if !PLATFORM(MAC) || ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE)
+#if !PLATFORM(MAC)
-void ScrollView::platformSetScrollbarsSuppressed(bool repaintOnUnsuppress)
+void ScrollView::platformSetScrollbarsSuppressed(bool)
{
}
#endif
-#if (!PLATFORM(MAC) && !PLATFORM(WX)) || ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE)
+#if !PLATFORM(MAC) && !PLATFORM(WX)
void ScrollView::platformSetScrollbarModes()
{
diff --git a/WebCore/platform/ScrollView.h b/WebCore/platform/ScrollView.h
index ac0e42f..88c78ec 100644
--- a/WebCore/platform/ScrollView.h
+++ b/WebCore/platform/ScrollView.h
@@ -312,16 +312,6 @@ private:
NSScrollView<WebCoreFrameScrollView>* scrollView() const;
#endif
-#if PLATFORM(QT)
-public:
- void adjustWidgetsPreventingBlittingCount(int delta);
-private:
- bool rootPreventsBlitting() const { return root()->m_widgetsPreventingBlitting > 0; }
- unsigned m_widgetsPreventingBlitting;
-#else
- bool rootPreventsBlitting() const { return false; }
-#endif
-
#if PLATFORM(GTK)
public:
void setGtkAdjustments(GtkAdjustment* hadj, GtkAdjustment* vadj);
diff --git a/WebCore/platform/Scrollbar.cpp b/WebCore/platform/Scrollbar.cpp
index 4eb2c4a..95f198e 100644
--- a/WebCore/platform/Scrollbar.cpp
+++ b/WebCore/platform/Scrollbar.cpp
@@ -26,6 +26,8 @@
#include "config.h"
#include "Scrollbar.h"
+#include "AccessibilityScrollbar.h"
+#include "AXObjectCache.h"
#include "EventHandler.h"
#include "Frame.h"
#include "FrameView.h"
@@ -117,6 +119,18 @@ void Scrollbar::setSteps(int lineStep, int pageStep, int pixelsPerStep)
bool Scrollbar::scroll(ScrollDirection direction, ScrollGranularity granularity, float multiplier)
{
+#if HAVE(ACCESSIBILITY)
+ if (AXObjectCache::accessibilityEnabled()) {
+ if (parent() && parent()->isFrameView()) {
+ Document* document = static_cast<FrameView*>(parent())->frame()->document();
+ AXObjectCache* cache = document->axObjectCache();
+ AccessibilityScrollbar* axObject = static_cast<AccessibilityScrollbar*>(cache->getOrCreate(ScrollBarRole));
+ axObject->setScrollbar(this);
+ cache->postNotification(axObject, document, AXObjectCache::AXValueChanged, true);
+ }
+ }
+#endif
+
float step = 0;
if ((direction == ScrollUp && m_orientation == VerticalScrollbar) || (direction == ScrollLeft && m_orientation == HorizontalScrollbar))
step = -1;
diff --git a/WebCore/platform/Scrollbar.h b/WebCore/platform/Scrollbar.h
index 67496f2..49907ba 100644
--- a/WebCore/platform/Scrollbar.h
+++ b/WebCore/platform/Scrollbar.h
@@ -40,9 +40,8 @@ class ScrollbarClient;
class ScrollbarTheme;
class PlatformMouseEvent;
-// These match the numbers we use over in WebKit (WebFrameView.m).
const int cScrollbarPixelsPerLineStep = 40;
-const int cAmountToKeepWhenPaging = 40;
+const float cFractionToStepWhenPaging = 0.875f;
class Scrollbar : public Widget {
protected:
diff --git a/WebCore/platform/ScrollbarThemeComposite.cpp b/WebCore/platform/ScrollbarThemeComposite.cpp
index 74bfae3..d28e1c3 100644
--- a/WebCore/platform/ScrollbarThemeComposite.cpp
+++ b/WebCore/platform/ScrollbarThemeComposite.cpp
@@ -26,6 +26,7 @@
#include "config.h"
#include "ScrollbarThemeComposite.h"
+#include "Chrome.h"
#include "ChromeClient.h"
#include "Frame.h"
#include "FrameView.h"
diff --git a/WebCore/platform/SharedBuffer.cpp b/WebCore/platform/SharedBuffer.cpp
index 4a0d0f3..4a46c2c 100644
--- a/WebCore/platform/SharedBuffer.cpp
+++ b/WebCore/platform/SharedBuffer.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,30 +29,60 @@
#include "PurgeableBuffer.h"
+using namespace std;
+
namespace WebCore {
+static const unsigned segmentSize = 0x1000;
+static const unsigned segmentPositionMask = 0x0FFF;
+
+static inline unsigned segmentIndex(unsigned position)
+{
+ return position / segmentSize;
+}
+
+static inline unsigned offsetInSegment(unsigned position)
+{
+ return position & segmentPositionMask;
+}
+
+static inline char* allocateSegment()
+{
+ return static_cast<char*>(fastMalloc(segmentSize));
+}
+
+static inline void freeSegment(char* p)
+{
+ fastFree(p);
+}
+
SharedBuffer::SharedBuffer()
+ : m_size(0)
{
}
SharedBuffer::SharedBuffer(const char* data, int size)
+ : m_size(0)
{
- m_buffer.append(data, size);
+ append(data, size);
}
SharedBuffer::SharedBuffer(const unsigned char* data, int size)
+ : m_size(0)
{
- m_buffer.append(data, size);
+ append(reinterpret_cast<const char*>(data), size);
}
SharedBuffer::~SharedBuffer()
{
+ clear();
}
PassRefPtr<SharedBuffer> SharedBuffer::adoptVector(Vector<char>& vector)
{
RefPtr<SharedBuffer> buffer = create();
buffer->m_buffer.swap(vector);
+ buffer->m_size = buffer->m_buffer.size();
return buffer.release();
}
@@ -71,7 +102,7 @@ unsigned SharedBuffer::size() const
if (m_purgeableBuffer)
return m_purgeableBuffer->size();
- return m_buffer.size();
+ return m_size;
}
const char* SharedBuffer::data() const
@@ -82,29 +113,75 @@ const char* SharedBuffer::data() const
if (m_purgeableBuffer)
return m_purgeableBuffer->data();
- return m_buffer.data();
+ return buffer().data();
}
-void SharedBuffer::append(const char* data, int len)
+void SharedBuffer::append(const char* data, unsigned length)
{
ASSERT(!m_purgeableBuffer);
maybeTransferPlatformData();
- m_buffer.append(data, len);
+ unsigned positionInSegment = offsetInSegment(m_size - m_buffer.size());
+ m_size += length;
+
+ if (m_size <= segmentSize) {
+ // No need to use segments for small resource data
+ m_buffer.append(data, length);
+ return;
+ }
+
+ char* segment;
+ if (!positionInSegment) {
+ segment = allocateSegment();
+ m_segments.append(segment);
+ } else
+ segment = m_segments.last() + positionInSegment;
+
+ unsigned segmentFreeSpace = segmentSize - positionInSegment;
+ unsigned bytesToCopy = min(length, segmentFreeSpace);
+
+ for (;;) {
+ memcpy(segment, data, bytesToCopy);
+ if (static_cast<unsigned>(length) == bytesToCopy)
+ break;
+
+ length -= bytesToCopy;
+ data += bytesToCopy;
+ segment = allocateSegment();
+ m_segments.append(segment);
+ bytesToCopy = min(length, segmentSize);
+ }
}
void SharedBuffer::clear()
{
clearPlatformData();
+ for (unsigned i = 0; i < m_segments.size(); ++i)
+ freeSegment(m_segments[i]);
+
+ m_segments.clear();
+ m_size = 0;
+
m_buffer.clear();
m_purgeableBuffer.clear();
}
PassRefPtr<SharedBuffer> SharedBuffer::copy() const
{
- return SharedBuffer::create(data(), size());
+ RefPtr<SharedBuffer> clone(adoptRef(new SharedBuffer));
+ if (m_purgeableBuffer || hasPlatformData()) {
+ clone->append(data(), size());
+ return clone;
+ }
+
+ clone->m_size = m_size;
+ clone->m_buffer.reserveCapacity(m_size);
+ clone->m_buffer.append(m_buffer.data(), m_buffer.size());
+ for (unsigned i = 0; i < m_segments.size(); ++i)
+ clone->m_buffer.append(m_segments[i], segmentSize);
+ return clone;
}
PurgeableBuffer* SharedBuffer::releasePurgeableBuffer()
@@ -113,6 +190,54 @@ PurgeableBuffer* SharedBuffer::releasePurgeableBuffer()
return m_purgeableBuffer.release();
}
+const Vector<char>& SharedBuffer::buffer() const
+{
+ unsigned bufferSize = m_buffer.size();
+ if (m_size > bufferSize) {
+ m_buffer.resize(m_size);
+ char* destination = m_buffer.data() + bufferSize;
+ unsigned bytesLeft = m_size - bufferSize;
+ for (unsigned i = 0; i < m_segments.size(); ++i) {
+ unsigned bytesToCopy = min(bytesLeft, segmentSize);
+ memcpy(destination, m_segments[i], bytesToCopy);
+ destination += bytesToCopy;
+ bytesLeft -= bytesToCopy;
+ freeSegment(m_segments[i]);
+ }
+ m_segments.clear();
+ }
+ return m_buffer;
+}
+
+unsigned SharedBuffer::getSomeData(const char*& someData, unsigned position) const
+{
+ if (hasPlatformData() || m_purgeableBuffer) {
+ someData = data() + position;
+ return size() - position;
+ }
+
+ if (position >= m_size) {
+ someData = 0;
+ return 0;
+ }
+
+ unsigned consecutiveSize = m_buffer.size();
+ if (position < consecutiveSize) {
+ someData = m_buffer.data() + position;
+ return consecutiveSize - position;
+ }
+
+ position -= consecutiveSize;
+ unsigned segmentedSize = m_size - consecutiveSize;
+ unsigned segments = m_segments.size();
+ unsigned segment = segmentIndex(position);
+ ASSERT(segment < segments);
+
+ unsigned positionInSegment = offsetInSegment(position);
+ someData = m_segments[segment] + positionInSegment;
+ return segment == segments - 1 ? segmentedSize - position : segmentSize - positionInSegment;
+}
+
#if !PLATFORM(CF)
inline void SharedBuffer::clearPlatformData()
diff --git a/WebCore/platform/SharedBuffer.h b/WebCore/platform/SharedBuffer.h
index 256d490..4937c73 100644
--- a/WebCore/platform/SharedBuffer.h
+++ b/WebCore/platform/SharedBuffer.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -76,6 +77,7 @@ public:
static PassRefPtr<SharedBuffer> wrapCFData(CFDataRef);
#endif
+<<<<<<< HEAD
#if PLATFORM(ANDROID)
virtual
#endif
@@ -83,12 +85,23 @@ public:
#if PLATFORM(ANDROID)
virtual
#endif
+=======
+ // Calling this function will force internal segmented buffers
+ // to be merged into a flat buffer. Use getSomeData() whenever possible
+ // for better performance.
+ const char* data() const;
+
+>>>>>>> webkit.org at r54127
unsigned size() const;
- const Vector<char> &buffer() { return m_buffer; }
- bool isEmpty() const { return size() == 0; }
+ // Calling this function will force internal segmented buffers
+ // to be merged into a flat buffer. Use getSomeData() whenever possible
+ // for better performance.
+ const Vector<char>& buffer() const;
- void append(const char*, int);
+ bool isEmpty() const { return !size(); }
+
+ void append(const char*, unsigned);
void clear();
const char* platformData() const;
unsigned platformDataSize() const;
@@ -99,7 +112,21 @@ public:
// Ensure this buffer has no other clients before calling this.
PurgeableBuffer* releasePurgeableBuffer();
-
+
+ // Return the number of consecutive bytes after "position". "data"
+ // points to the first byte.
+ // Return 0 when no more data left.
+ // When extracting all data with getSomeData(), the caller should
+ // repeat calling it until it returns 0.
+ // Usage:
+ // const char* segment;
+ // unsigned pos = 0;
+ // while (unsigned length = sharedBuffer->getSomeData(segment, pos)) {
+ // // Use the data. for example: decoder->decode(segment, length);
+ // pos += length;
+ // }
+ unsigned getSomeData(const char*& data, unsigned position = 0) const;
+
private:
SharedBuffer();
SharedBuffer(const char*, int);
@@ -109,7 +136,9 @@ private:
void maybeTransferPlatformData();
bool hasPlatformData() const;
- Vector<char> m_buffer;
+ unsigned m_size;
+ mutable Vector<char> m_buffer;
+ mutable Vector<char*> m_segments;
OwnPtr<PurgeableBuffer> m_purgeableBuffer;
#if PLATFORM(CF)
SharedBuffer(CFDataRef);
@@ -119,4 +148,4 @@ private:
}
-#endif
+#endif // SharedBuffer_h
diff --git a/WebCore/platform/ThemeTypes.h b/WebCore/platform/ThemeTypes.h
index 439a3b1..9c2366e 100644
--- a/WebCore/platform/ThemeTypes.h
+++ b/WebCore/platform/ThemeTypes.h
@@ -38,6 +38,7 @@ enum ControlState {
DefaultState = 1 << 6,
WindowInactiveState = 1 << 7,
IndeterminateState = 1 << 8,
+ SpinUpState = 1 << 9, // Sub-state for HoverState and PressedState.
AllStates = 0xffffffff
};
@@ -46,12 +47,12 @@ typedef unsigned ControlStates;
// Must follow CSSValueKeywords.in order
enum ControlPart {
NoControlPart, CheckboxPart, RadioPart, PushButtonPart, SquareButtonPart, ButtonPart,
- ButtonBevelPart, DefaultButtonPart, ListButtonPart, ListboxPart, ListItemPart,
+ ButtonBevelPart, DefaultButtonPart, InnerSpinButtonPart, ListButtonPart, ListboxPart, ListItemPart,
MediaFullscreenButtonPart, MediaMuteButtonPart, MediaPlayButtonPart, MediaSeekBackButtonPart,
MediaSeekForwardButtonPart, MediaRewindButtonPart, MediaReturnToRealtimeButtonPart, MediaToggleClosedCaptionsButtonPart,
MediaSliderPart, MediaSliderThumbPart, MediaVolumeSliderContainerPart, MediaVolumeSliderPart, MediaVolumeSliderThumbPart,
MediaControlsBackgroundPart, MediaCurrentTimePart, MediaTimeRemainingPart,
- MenulistPart, MenulistButtonPart, MenulistTextPart, MenulistTextFieldPart,
+ MenulistPart, MenulistButtonPart, MenulistTextPart, MenulistTextFieldPart, OuterSpinButtonPart,
SliderHorizontalPart, SliderVerticalPart, SliderThumbHorizontalPart,
SliderThumbVerticalPart, CaretPart, SearchFieldPart, SearchFieldDecorationPart,
SearchFieldResultsDecorationPart, SearchFieldResultsButtonPart,
diff --git a/WebCore/platform/ThreadGlobalData.cpp b/WebCore/platform/ThreadGlobalData.cpp
index 26a9728..5c3c294 100644
--- a/WebCore/platform/ThreadGlobalData.cpp
+++ b/WebCore/platform/ThreadGlobalData.cpp
@@ -48,24 +48,11 @@ using namespace WTF;
namespace WebCore {
-ThreadGlobalData& threadGlobalData()
-{
- // FIXME: Workers are not necessarily the only feature that make per-thread global data necessary.
- // We need to check for e.g. database objects manipulating strings on secondary threads.
#if ENABLE(WORKERS)
- // ThreadGlobalData is used on main thread before it could possibly be used on secondary ones, so there is no need for synchronization here.
- static ThreadSpecific<ThreadGlobalData>* threadGlobalData = new ThreadSpecific<ThreadGlobalData>;
- return **threadGlobalData;
+ThreadSpecific<ThreadGlobalData>* ThreadGlobalData::staticData;
#else
- static ThreadGlobalData* staticData;
- if (!staticData) {
- staticData = static_cast<ThreadGlobalData*>(fastMalloc(sizeof(ThreadGlobalData)));
- // ThreadGlobalData constructor indirectly uses staticData, so we need to set up the memory before invoking it.
- new (staticData) ThreadGlobalData;
- }
- return *staticData;
+ThreadGlobalData* ThreadGlobalData::staticData;
#endif
-}
ThreadGlobalData::ThreadGlobalData()
: m_emptyString(new StringImpl)
@@ -92,7 +79,6 @@ ThreadGlobalData::~ThreadGlobalData()
#if USE(ICU_UNICODE)
delete m_cachedConverterICU;
#endif
-
delete m_eventNames;
delete m_atomicStringTable;
delete m_threadTimers;
diff --git a/WebCore/platform/ThreadGlobalData.h b/WebCore/platform/ThreadGlobalData.h
index 68f5ec0..9f7865d 100644
--- a/WebCore/platform/ThreadGlobalData.h
+++ b/WebCore/platform/ThreadGlobalData.h
@@ -28,9 +28,16 @@
#define ThreadGlobalData_h
#include "StringHash.h"
+#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
#include <wtf/Noncopyable.h>
+#if ENABLE(WORKERS)
+#include <wtf/ThreadSpecific.h>
+#include <wtf/Threading.h>
+using WTF::ThreadSpecific;
+#endif
+
namespace WebCore {
class EventNames;
@@ -73,10 +80,35 @@ namespace WebCore {
#if PLATFORM(MAC)
TECConverterWrapper* m_cachedConverterTEC;
#endif
+
+#if ENABLE(WORKERS)
+ static ThreadSpecific<ThreadGlobalData>* staticData;
+#else
+ static ThreadGlobalData* staticData;
+#endif
+ friend ThreadGlobalData& threadGlobalData();
};
- ThreadGlobalData& threadGlobalData();
+inline ThreadGlobalData& threadGlobalData()
+{
+ // FIXME: Workers are not necessarily the only feature that make per-thread global data necessary.
+ // We need to check for e.g. database objects manipulating strings on secondary threads.
+#if ENABLE(WORKERS)
+ // ThreadGlobalData is used on main thread before it could possibly be used on secondary ones, so there is no need for synchronization here.
+ if (!ThreadGlobalData::staticData)
+ ThreadGlobalData::staticData = new ThreadSpecific<ThreadGlobalData>;
+ return **ThreadGlobalData::staticData;
+#else
+ if (!ThreadGlobalData::staticData) {
+ ThreadGlobalData::staticData = static_cast<ThreadGlobalData*>(fastMalloc(sizeof(ThreadGlobalData)));
+ // ThreadGlobalData constructor indirectly uses staticData, so we need to set up the memory before invoking it.
+ new (ThreadGlobalData::staticData) ThreadGlobalData;
+ }
+ return *ThreadGlobalData::staticData;
+#endif
+}
+
} // namespace WebCore
#endif // ThreadGlobalData_h
diff --git a/WebCore/platform/Timer.cpp b/WebCore/platform/Timer.cpp
index ea3effd..5f9fe27 100644
--- a/WebCore/platform/Timer.cpp
+++ b/WebCore/platform/Timer.cpp
@@ -196,13 +196,6 @@ void TimerBase::stop()
ASSERT(!inHeap());
}
-bool TimerBase::isActive() const
-{
- ASSERT(m_thread == currentThread());
-
- return m_nextFireTime;
-}
-
double TimerBase::nextFireInterval() const
{
ASSERT(isActive());
diff --git a/WebCore/platform/Timer.h b/WebCore/platform/Timer.h
index 9221df0..c4443da 100644
--- a/WebCore/platform/Timer.h
+++ b/WebCore/platform/Timer.h
@@ -101,6 +101,12 @@ private:
TimerFiredFunction m_function;
};
+inline bool TimerBase::isActive() const
+{
+ ASSERT(m_thread == currentThread());
+ return m_nextFireTime;
+}
+
}
#endif
diff --git a/WebCore/platform/TreeShared.h b/WebCore/platform/TreeShared.h
index a60ad0d..b844e5f 100644
--- a/WebCore/platform/TreeShared.h
+++ b/WebCore/platform/TreeShared.h
@@ -44,6 +44,7 @@ public:
virtual ~TreeShared()
{
ASSERT(isMainThread());
+ ASSERT(!m_refCount);
ASSERT(m_deletionHasBegun);
}
@@ -58,6 +59,7 @@ public:
void deref()
{
ASSERT(isMainThread());
+ ASSERT(m_refCount >= 0);
ASSERT(!m_deletionHasBegun);
ASSERT(!m_inRemovedLastRefFunction);
if (--m_refCount <= 0 && !m_parent) {
diff --git a/WebCore/platform/Widget.cpp b/WebCore/platform/Widget.cpp
index 6196548..1a8f7f8 100644
--- a/WebCore/platform/Widget.cpp
+++ b/WebCore/platform/Widget.cpp
@@ -105,7 +105,7 @@ IntPoint Widget::convertToContainingWindow(const IntPoint& localPoint) const
return convertFromRootToContainingWindow(this, localPoint);
}
-#if !PLATFORM(MAC) || ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE)
+#if !PLATFORM(MAC)
IntRect Widget::convertFromRootToContainingWindow(const Widget*, const IntRect& rect)
{
return rect;
@@ -127,7 +127,11 @@ IntPoint Widget::convertFromContainingWindowToRoot(const Widget*, const IntPoint
}
#endif
+<<<<<<< HEAD
#if (!PLATFORM(MAC) && !PLATFORM(GTK) && !PLATFORM(ANDROID)) || ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE)
+=======
+#if !PLATFORM(MAC) && !PLATFORM(GTK)
+>>>>>>> webkit.org at r54127
void Widget::releasePlatformWidget()
{
}
diff --git a/WebCore/platform/Widget.h b/WebCore/platform/Widget.h
index a449d58..803bf3b 100644
--- a/WebCore/platform/Widget.h
+++ b/WebCore/platform/Widget.h
@@ -168,6 +168,8 @@ public:
virtual bool isFrameView() const { return false; }
virtual bool isPluginView() const { return false; }
+ // FIXME: The Mac plug-in code should inherit from PluginView. When this happens PluginWidget and PluginView can become one class.
+ virtual bool isPluginWidget() const { return false; }
virtual bool isScrollbar() const { return false; }
void removeFromParent();
@@ -189,7 +191,7 @@ public:
virtual void frameRectsChanged() {}
-#if PLATFORM(MAC) && !ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE)
+#if PLATFORM(MAC)
NSView* getOuterView() const;
static void beforeMouseDown(NSView*, Widget*);
@@ -226,7 +228,7 @@ private:
IntRect m_frame; // Not used when a native widget exists.
-#if PLATFORM(MAC) && !ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE)
+#if PLATFORM(MAC)
WidgetPrivate* m_data;
#endif
#if PLATFORM(ANDROID)
diff --git a/WebCore/platform/android/PlatformBridge.h b/WebCore/platform/android/PlatformBridge.h
index cf9f561..644b504 100644
--- a/WebCore/platform/android/PlatformBridge.h
+++ b/WebCore/platform/android/PlatformBridge.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2009, The Android Open Source Project
+ * Copyright 2009, 2010, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -81,7 +81,10 @@ class NPObject;
namespace WebCore {
+<<<<<<< HEAD
class FrameView;
+=======
+>>>>>>> webkit.org at r54127
class Widget;
// An interface to the embedding layer, which has the ability to answer
@@ -105,6 +108,7 @@ public:
static bool cookiesEnabled();
// Plugin
static NPObject* pluginScriptableObject(Widget*);
+<<<<<<< HEAD
// Popups
static bool popupsAllowed(NPP);
@@ -127,6 +131,8 @@ public:
// Whether the WebView is paused.
static bool isWebViewPaused();
+=======
+>>>>>>> webkit.org at r54127
};
}
diff --git a/WebCore/platform/android/PlatformTouchEventAndroid.cpp b/WebCore/platform/android/PlatformTouchEventAndroid.cpp
index d2fcebb..1ff87c3 100644
--- a/WebCore/platform/android/PlatformTouchEventAndroid.cpp
+++ b/WebCore/platform/android/PlatformTouchEventAndroid.cpp
@@ -30,14 +30,21 @@
namespace WebCore {
+<<<<<<< HEAD
// TODO (benm): eventTime is new and needs to be upstream
PlatformTouchEvent::PlatformTouchEvent(const IntPoint& windowPos, TouchEventType type, PlatformTouchPoint::State state, long eventTime)
+=======
+PlatformTouchEvent::PlatformTouchEvent(const IntPoint& windowPos, TouchEventType type, PlatformTouchPoint::State state)
+>>>>>>> webkit.org at r54127
: m_type(type)
, m_ctrlKey(false)
, m_altKey(false)
, m_shiftKey(false)
, m_metaKey(false)
+<<<<<<< HEAD
, m_eventTime(eventTime)
+=======
+>>>>>>> webkit.org at r54127
{
m_touchPoints.append(PlatformTouchPoint(windowPos, state));
}
diff --git a/WebCore/platform/cf/BinaryPropertyList.cpp b/WebCore/platform/cf/BinaryPropertyList.cpp
index c0fda3d..f0facae 100644
--- a/WebCore/platform/cf/BinaryPropertyList.cpp
+++ b/WebCore/platform/cf/BinaryPropertyList.cpp
@@ -27,6 +27,7 @@
#include "BinaryPropertyList.h"
#include "StringHash.h"
+#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
#include <limits>
diff --git a/WebCore/platform/cf/SharedBufferCF.cpp b/WebCore/platform/cf/SharedBufferCF.cpp
index 26fc07f..33e25ae 100644
--- a/WebCore/platform/cf/SharedBufferCF.cpp
+++ b/WebCore/platform/cf/SharedBufferCF.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2010 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -33,7 +33,8 @@
namespace WebCore {
SharedBuffer::SharedBuffer(CFDataRef cfData)
- : m_cfData(cfData)
+ : m_size(0)
+ , m_cfData(cfData)
{
}
@@ -76,9 +77,9 @@ void SharedBuffer::maybeTransferPlatformData()
if (!m_cfData)
return;
- ASSERT(m_buffer.size() == 0);
+ ASSERT(!m_size);
- m_buffer.append((const char*)CFDataGetBytePtr(m_cfData.get()), CFDataGetLength(m_cfData.get()));
+ append((const char*)CFDataGetBytePtr(m_cfData.get()), CFDataGetLength(m_cfData.get()));
m_cfData = 0;
}
diff --git a/WebCore/platform/chromium/ChromiumBridge.h b/WebCore/platform/chromium/ChromiumBridge.h
index 3709f7c..92b4c13 100644
--- a/WebCore/platform/chromium/ChromiumBridge.h
+++ b/WebCore/platform/chromium/ChromiumBridge.h
@@ -43,7 +43,7 @@ typedef struct NPObject NPObject;
typedef struct _NPP NPP_t;
typedef NPP_t* NPP;
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
typedef struct HFONT__* HFONT;
#endif
@@ -87,6 +87,7 @@ namespace WebCore {
static String cookies(const KURL& url, const KURL& firstPartyForCookies);
static bool rawCookies(const KURL& url, const KURL& firstPartyForCookies, Vector<Cookie>*);
static void deleteCookie(const KURL& url, const String& cookieName);
+ static bool cookiesEnabled(const KURL& url, const KURL& firstPartyForCookies);
// DNS ----------------------------------------------------------------
static void prefetchDNS(const String& hostname);
@@ -105,10 +106,10 @@ namespace WebCore {
static KURL filePathToURL(const String&);
// Font ---------------------------------------------------------------
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
static bool ensureFontLoaded(HFONT font);
#endif
-#if PLATFORM(LINUX)
+#if OS(LINUX)
static String getFontFamilyForCharacters(const UChar*, size_t numCharacters);
#endif
@@ -187,7 +188,7 @@ namespace WebCore {
static double currentTime();
// Theming ------------------------------------------------------------
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
static void paintButton(
GraphicsContext*, int part, int state, int classicState, const IntRect&);
static void paintMenuList(
diff --git a/WebCore/platform/chromium/ChromiumDataObject.cpp b/WebCore/platform/chromium/ChromiumDataObject.cpp
index 683c2e6..df0849c 100644
--- a/WebCore/platform/chromium/ChromiumDataObject.cpp
+++ b/WebCore/platform/chromium/ChromiumDataObject.cpp
@@ -37,6 +37,7 @@ void ChromiumDataObject::clear()
{
url = KURL();
urlTitle = "";
+ downloadURL = KURL();
fileExtension = "";
filenames.clear();
plainText = "";
@@ -50,6 +51,7 @@ void ChromiumDataObject::clear()
bool ChromiumDataObject::hasData() const
{
return !url.isEmpty()
+ || !downloadURL.isEmpty()
|| !fileExtension.isEmpty()
|| !filenames.isEmpty()
|| !plainText.isEmpty()
@@ -60,6 +62,7 @@ bool ChromiumDataObject::hasData() const
ChromiumDataObject::ChromiumDataObject(const ChromiumDataObject& other)
: url(other.url)
, urlTitle(other.urlTitle)
+ , downloadURL(other.downloadURL)
, fileExtension(other.fileExtension)
, filenames(other.filenames)
, plainText(other.plainText)
diff --git a/WebCore/platform/chromium/ChromiumDataObject.h b/WebCore/platform/chromium/ChromiumDataObject.h
index 3e8675e..15eb911 100644
--- a/WebCore/platform/chromium/ChromiumDataObject.h
+++ b/WebCore/platform/chromium/ChromiumDataObject.h
@@ -59,6 +59,8 @@ namespace WebCore {
KURL url;
String urlTitle;
+ KURL downloadURL;
+
String fileExtension;
Vector<String> filenames;
diff --git a/WebCore/platform/chromium/ClipboardChromium.cpp b/WebCore/platform/chromium/ClipboardChromium.cpp
index 1a2caa4..32f7d50 100644
--- a/WebCore/platform/chromium/ClipboardChromium.cpp
+++ b/WebCore/platform/chromium/ClipboardChromium.cpp
@@ -53,7 +53,7 @@ using namespace HTMLNames;
// We provide the IE clipboard types (URL and Text), and the clipboard types specified in the WHATWG Web Applications 1.0 draft
// see http://www.whatwg.org/specs/web-apps/current-work/ Section 6.3.5.3
-enum ClipboardDataType { ClipboardDataTypeNone, ClipboardDataTypeURL, ClipboardDataTypeText };
+enum ClipboardDataType { ClipboardDataTypeNone, ClipboardDataTypeURL, ClipboardDataTypeText, ClipboardDataTypeDownloadURL };
static ClipboardDataType clipboardTypeFromMIMEType(const String& type)
{
@@ -64,6 +64,8 @@ static ClipboardDataType clipboardTypeFromMIMEType(const String& type)
return ClipboardDataTypeText;
if (cleanType == "url" || cleanType == "text/uri-list")
return ClipboardDataTypeURL;
+ if (cleanType == "downloadurl")
+ return ClipboardDataTypeDownloadURL;
return ClipboardDataTypeNone;
}
@@ -157,6 +159,14 @@ bool ClipboardChromium::setData(const String& type, const String& data)
return true;
}
+ if (winType == ClipboardDataTypeDownloadURL) {
+ KURL url = KURL(ParsedURLString, data);
+ if (url.isValid()) {
+ m_dataObject->downloadURL = url;
+ return true;
+ }
+ }
+
return false;
}
@@ -353,13 +363,13 @@ void ClipboardChromium::writeRange(Range* selectedRange, Frame* frame)
m_dataObject->textHtml = createMarkup(selectedRange, 0,
AnnotateForInterchange);
-#if PLATFORM(DARWIN)
+#if OS(DARWIN)
m_dataObject->textHtml = String("<meta charset='utf-8' id='webkit-interchange-charset'>") + m_dataObject->textHtml;
#endif
m_dataObject->htmlBaseUrl = frame->document()->url();
String str = frame->selectedText();
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
replaceNewlinesWithWindowsStyleNewlines(str);
#endif
replaceNBSPWithSpace(str);
diff --git a/WebCore/platform/chromium/ClipboardUtilitiesChromium.cpp b/WebCore/platform/chromium/ClipboardUtilitiesChromium.cpp
index 7efcb3c..5d9ed05 100644
--- a/WebCore/platform/chromium/ClipboardUtilitiesChromium.cpp
+++ b/WebCore/platform/chromium/ClipboardUtilitiesChromium.cpp
@@ -36,7 +36,7 @@
namespace WebCore {
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
void replaceNewlinesWithWindowsStyleNewlines(String& str)
{
static const UChar Newline = '\n';
diff --git a/WebCore/platform/chromium/ClipboardUtilitiesChromium.h b/WebCore/platform/chromium/ClipboardUtilitiesChromium.h
index c597089..23fd29c 100644
--- a/WebCore/platform/chromium/ClipboardUtilitiesChromium.h
+++ b/WebCore/platform/chromium/ClipboardUtilitiesChromium.h
@@ -33,7 +33,7 @@ namespace WebCore {
class KURL;
class String;
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
void replaceNewlinesWithWindowsStyleNewlines(String&);
#endif
void replaceNBSPWithSpace(String&);
diff --git a/WebCore/platform/chromium/DragDataChromium.cpp b/WebCore/platform/chromium/DragDataChromium.cpp
index 133ba24..9b67fc0 100644
--- a/WebCore/platform/chromium/DragDataChromium.cpp
+++ b/WebCore/platform/chromium/DragDataChromium.cpp
@@ -147,7 +147,7 @@ PassRefPtr<DocumentFragment> DragData::asFragment(Document* doc) const
if (!m_platformDragData->textHtml.isEmpty()) {
RefPtr<DocumentFragment> fragment = createFragmentFromMarkup(doc,
- m_platformDragData->textHtml, m_platformDragData->htmlBaseUrl);
+ m_platformDragData->textHtml, m_platformDragData->htmlBaseUrl, FragmentScriptingNotAllowed);
return fragment.release();
}
diff --git a/WebCore/platform/chromium/KeyCodeConversionGtk.cpp b/WebCore/platform/chromium/KeyCodeConversionGtk.cpp
index e3d5f61..a709f3e 100644
--- a/WebCore/platform/chromium/KeyCodeConversionGtk.cpp
+++ b/WebCore/platform/chromium/KeyCodeConversionGtk.cpp
@@ -72,6 +72,23 @@ int windowsKeyCodeForKeyEvent(unsigned keycode)
case GDK_KP_Divide:
return VKEY_DIVIDE; // (6F) Divide key
+ case GDK_KP_Page_Up:
+ return VKEY_PRIOR; // (21) PAGE UP key
+ case GDK_KP_Page_Down:
+ return VKEY_NEXT; // (22) PAGE DOWN key
+ case GDK_KP_End:
+ return VKEY_END; // (23) END key
+ case GDK_KP_Home:
+ return VKEY_HOME; // (24) HOME key
+ case GDK_KP_Left:
+ return VKEY_LEFT; // (25) LEFT ARROW key
+ case GDK_KP_Up:
+ return VKEY_UP; // (26) UP ARROW key
+ case GDK_KP_Right:
+ return VKEY_RIGHT; // (27) RIGHT ARROW key
+ case GDK_KP_Down:
+ return VKEY_DOWN; // (28) DOWN ARROW key
+
case GDK_BackSpace:
return VKEY_BACK; // (08) BACKSPACE key
case GDK_ISO_Left_Tab:
diff --git a/WebCore/platform/chromium/PasteboardChromium.cpp b/WebCore/platform/chromium/PasteboardChromium.cpp
index ce06e55..3b3aea6 100644
--- a/WebCore/platform/chromium/PasteboardChromium.cpp
+++ b/WebCore/platform/chromium/PasteboardChromium.cpp
@@ -82,13 +82,13 @@ void Pasteboard::setSelectionMode(bool selectionMode)
void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete, Frame* frame)
{
String html = createMarkup(selectedRange, 0, AnnotateForInterchange);
-#if PLATFORM(DARWIN)
+#if OS(DARWIN)
html = String("<meta charset='utf-8' id='webkit-interchange-charset'>") + html;
#endif
ExceptionCode ec = 0;
KURL url = selectedRange->startContainer(ec)->document()->url();
String plainText = frame->selectedText();
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
replaceNewlinesWithWindowsStyleNewlines(plainText);
#endif
replaceNBSPWithSpace(plainText);
@@ -98,7 +98,7 @@ void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete,
void Pasteboard::writePlainText(const String& text)
{
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
String plainText(text);
replaceNewlinesWithWindowsStyleNewlines(plainText);
ChromiumBridge::clipboardWritePlainText(plainText);
@@ -170,14 +170,14 @@ PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefP
String markup;
KURL srcURL;
ChromiumBridge::clipboardReadHTML(buffer, &markup, &srcURL);
-#if PLATFORM(DARWIN)
+#if OS(DARWIN)
DEFINE_STATIC_LOCAL(const String, forceUtf8String, ("<meta charset='utf-8' id='webkit-interchange-charset'>"));
if (markup.startsWith(forceUtf8String))
markup = markup.substring(forceUtf8String.length());
#endif
RefPtr<DocumentFragment> fragment =
- createFragmentFromMarkup(frame->document(), markup, srcURL);
+ createFragmentFromMarkup(frame->document(), markup, srcURL, FragmentScriptingNotAllowed);
if (fragment)
return fragment.release();
}
diff --git a/WebCore/platform/chromium/PlatformBridge.h b/WebCore/platform/chromium/PlatformBridge.h
new file mode 100644
index 0000000..ecb7b45
--- /dev/null
+++ b/WebCore/platform/chromium/PlatformBridge.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * 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 PlatformBridge_h
+#define PlatformBridge_h
+
+#include "ChromiumBridge.h"
+
+namespace WebCore {
+
+// FIXME: A better name for ChromiumBridge is PlatformBridge. Android already
+// uses PlatformBridge so the code that is shared among the Android and Chromium
+// ports is gradually moving towards using PlatformBridge. Once the Android
+// unforking is done, we will change the name of ChromiumBridge to PlatformBridge
+// and merge the two classes into one that will be shared by both ports.
+typedef ChromiumBridge PlatformBridge;
+
+} // namespace WebCore
+
+#endif // PlatformBridge_h
diff --git a/WebCore/platform/chromium/PlatformKeyboardEventChromium.cpp b/WebCore/platform/chromium/PlatformKeyboardEventChromium.cpp
index ae55afe..74643f7 100644
--- a/WebCore/platform/chromium/PlatformKeyboardEventChromium.cpp
+++ b/WebCore/platform/chromium/PlatformKeyboardEventChromium.cpp
@@ -27,9 +27,9 @@
#include "config.h"
#include "PlatformKeyboardEvent.h"
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
#include <windows.h>
-#elif PLATFORM(DARWIN)
+#elif OS(DARWIN)
#import <Carbon/Carbon.h>
#else
#include "NotImplemented.h"
@@ -39,7 +39,7 @@ namespace WebCore {
void PlatformKeyboardEvent::disambiguateKeyDownEvent(Type type, bool backwardCompatibilityMode)
{
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
// No KeyDown events on Windows to disambiguate.
ASSERT_NOT_REACHED();
#else
@@ -56,7 +56,7 @@ void PlatformKeyboardEvent::disambiguateKeyDownEvent(Type type, bool backwardCom
} else {
m_keyIdentifier = String();
m_windowsVirtualKeyCode = 0;
-#if PLATFORM(DARWIN)
+#if OS(DARWIN)
if (m_text.length() == 1 && (m_text[0U] >= 0xF700 && m_text[0U] <= 0xF7FF)) {
// According to NSEvents.h, OpenStep reserves the range 0xF700-0xF8FF for function keys. However, some actual private use characters
// happen to be in this range, e.g. the Apple logo (Option+Shift+K).
@@ -71,10 +71,10 @@ void PlatformKeyboardEvent::disambiguateKeyDownEvent(Type type, bool backwardCom
bool PlatformKeyboardEvent::currentCapsLockState()
{
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
// FIXME: Does this even work inside the sandbox?
return GetKeyState(VK_CAPITAL) & 1;
-#elif PLATFORM(DARWIN)
+#elif OS(DARWIN)
return GetCurrentKeyModifiers() & alphaLock;
#else
notImplemented();
diff --git a/WebCore/platform/chromium/PopupMenuChromium.cpp b/WebCore/platform/chromium/PopupMenuChromium.cpp
index 5abd364..cab7ced 100644
--- a/WebCore/platform/chromium/PopupMenuChromium.cpp
+++ b/WebCore/platform/chromium/PopupMenuChromium.cpp
@@ -32,6 +32,7 @@
#include "PopupMenuChromium.h"
#include "CharacterNames.h"
+#include "Chrome.h"
#include "ChromeClientChromium.h"
#include "Font.h"
#include "FontSelector.h"
@@ -610,17 +611,10 @@ 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;
+ // We use RawKeyDown/Char/KeyUp event scheme on all platforms,
+ // so PlatformKeyboardEvent::Char (not RawKeyDown) type event
+ // is considered as character type event.
+ return event.type() == PlatformKeyboardEvent::Char;
}
bool PopupListBox::handleKeyEvent(const PlatformKeyboardEvent& event)
@@ -744,13 +738,18 @@ void PopupListBox::typeAheadFind(const PlatformKeyboardEvent& event)
}
}
+ // Compute a case-folded copy of the prefix string before beginning the search for
+ // a matching element. This code uses foldCase to work around the fact that
+ // String::startWith does not fold non-ASCII characters. This code can be changed
+ // to use startWith once that is fixed.
+ String prefixWithCaseFolded(prefix.foldCase());
int itemCount = numItems();
int index = (max(0, m_selectedIndex) + searchStartOffset) % itemCount;
for (int i = 0; i < itemCount; i++, index = (index + 1) % itemCount) {
if (!isSelectableItem(index))
continue;
- if (stripLeadingWhiteSpace(m_items[index]->label).startsWith(prefix, false)) {
+ if (stripLeadingWhiteSpace(m_items[index]->label).foldCase().startsWith(prefixWithCaseFolded)) {
selectIndex(index);
return;
}
@@ -912,6 +911,10 @@ int PopupListBox::pointToRowIndex(const IntPoint& point)
void PopupListBox::acceptIndex(int index)
{
+ // Clear m_acceptedIndexOnAbandon once user accepts the selected index.
+ if (m_acceptedIndexOnAbandon >= 0)
+ m_acceptedIndexOnAbandon = -1;
+
if (index >= numItems())
return;
@@ -1134,7 +1137,7 @@ void PopupListBox::layout()
// Calculate scroll bar width.
int windowHeight = 0;
-#if PLATFORM(DARWIN)
+#if OS(DARWIN)
// Set the popup's window to contain all available items on Mac only, which
// uses native controls that manage their own scrolling. This allows hit
// testing to work when selecting items in popups that have more menu entries
@@ -1146,7 +1149,7 @@ void PopupListBox::layout()
for (int i = 0; i < m_visibleRows; ++i) {
int rowHeight = getRowHeight(i);
-#if !PLATFORM(DARWIN)
+#if !OS(DARWIN)
// Only clip the window height for non-Mac platforms.
if (windowHeight + rowHeight > kMaxHeight) {
m_visibleRows = i;
@@ -1224,7 +1227,7 @@ void PopupMenu::show(const IntRect& r, FrameView* v, int index)
{
if (!p.popup)
p.popup = PopupContainer::create(client(), dropDownSettings);
-#if PLATFORM(DARWIN)
+#if OS(DARWIN)
p.popup->showExternal(r, v, index);
#else
p.popup->show(r, v, index);
@@ -1234,7 +1237,7 @@ void PopupMenu::show(const IntRect& r, FrameView* v, int index)
void PopupMenu::hide()
{
if (p.popup)
- p.popup->hidePopup();
+ p.popup->hide();
}
void PopupMenu::updateFromElement()
diff --git a/WebCore/platform/chromium/ScrollbarThemeChromiumMac.mm b/WebCore/platform/chromium/ScrollbarThemeChromiumMac.mm
index b4ebaf6..e532d57 100644
--- a/WebCore/platform/chromium/ScrollbarThemeChromiumMac.mm
+++ b/WebCore/platform/chromium/ScrollbarThemeChromiumMac.mm
@@ -375,7 +375,7 @@ bool ScrollbarThemeChromiumMac::paint(Scrollbar* scrollbar, GraphicsContext* con
trackInfo.min = 0;
trackInfo.max = scrollbar->maximum();
trackInfo.value = scrollbar->currentPos();
- trackInfo.trackInfo.scrollbar.viewsize = scrollbar->pageStep();
+ trackInfo.trackInfo.scrollbar.viewsize = scrollbar->visibleSize();
trackInfo.attributes = 0;
if (scrollbar->orientation() == HorizontalScrollbar)
trackInfo.attributes |= kThemeTrackHorizontal;
diff --git a/WebCore/platform/graphics/BitmapImage.h b/WebCore/platform/graphics/BitmapImage.h
index 0031df6..485bb02 100644
--- a/WebCore/platform/graphics/BitmapImage.h
+++ b/WebCore/platform/graphics/BitmapImage.h
@@ -140,7 +140,7 @@ public:
virtual CGImageRef getCGImageRef();
#endif
-#if PLATFORM(WIN) || (PLATFORM(QT) && PLATFORM(WIN_OS))
+#if PLATFORM(WIN) || (PLATFORM(QT) && OS(WINDOWS))
static PassRefPtr<BitmapImage> create(HBITMAP);
#endif
#if PLATFORM(WIN)
@@ -173,7 +173,7 @@ protected:
#endif
virtual void draw(GraphicsContext*, const FloatRect& dstRect, const FloatRect& srcRect, ColorSpace styleColorSpace, CompositeOperator);
-#if PLATFORM(WX) || (PLATFORM(WINCE) && !PLATFORM(QT))
+#if PLATFORM(WX) || (OS(WINCE) && !PLATFORM(QT))
virtual void drawPattern(GraphicsContext*, const FloatRect& srcRect, const TransformationMatrix& patternTransform,
const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator, const FloatRect& destRect);
#endif
@@ -240,7 +240,7 @@ protected:
checkForSolidColor();
// WINCE PORT: checkForSolidColor() doesn't set m_checkedForSolidColor until
// it gets enough information to make final decision.
-#if !PLATFORM(WINCE)
+#if !OS(WINCE)
ASSERT(m_checkedForSolidColor);
#endif
}
diff --git a/WebCore/platform/graphics/FloatPoint.h b/WebCore/platform/graphics/FloatPoint.h
index 45a1e83..6b037ff 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) || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN))
+#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN))
#ifdef NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES
typedef struct CGPoint NSPoint;
#else
@@ -85,7 +85,7 @@ public:
#endif
#if (PLATFORM(MAC) && !defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES)) \
- || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN))
+ || (PLATFORM(CHROMIUM) && OS(DARWIN))
FloatPoint(const NSPoint&);
operator NSPoint() const;
#endif
diff --git a/WebCore/platform/graphics/FloatQuad.cpp b/WebCore/platform/graphics/FloatQuad.cpp
index 427230d..d1069fb 100644
--- a/WebCore/platform/graphics/FloatQuad.cpp
+++ b/WebCore/platform/graphics/FloatQuad.cpp
@@ -85,6 +85,12 @@ FloatRect FloatQuad::boundingBox() const
return FloatRect(left, top, right - left, bottom - top);
}
+bool FloatQuad::isRectilinear() const
+{
+ return (m_p1.x() == m_p2.x() && m_p2.y() == m_p3.y() && m_p3.x() == m_p4.x() && m_p4.y() == m_p1.y())
+ || (m_p1.y() == m_p2.y() && m_p2.x() == m_p3.x() && m_p3.y() == m_p4.y() && m_p4.x() == m_p1.x());
+}
+
bool FloatQuad::containsPoint(const FloatPoint& p) const
{
return isPointInTriangle(p, m_p1, m_p2, m_p3) || isPointInTriangle(p, m_p1, m_p3, m_p4);
diff --git a/WebCore/platform/graphics/FloatQuad.h b/WebCore/platform/graphics/FloatQuad.h
index 5982967..6cd86f6 100644
--- a/WebCore/platform/graphics/FloatQuad.h
+++ b/WebCore/platform/graphics/FloatQuad.h
@@ -74,6 +74,12 @@ public:
// "slanted" empty quads.
bool isEmpty() const { return boundingBox().isEmpty(); }
+ // Tests whether this quad can be losslessly represented by a FloatRect,
+ // that is, if two edges are parallel to the x-axis and the other two
+ // are parallel to the y-axis. If this method returns true, the
+ // corresponding FloatRect can be retrieved with boundingBox().
+ bool isRectilinear() const;
+
// Tests whether the given point is inside, or on an edge or corner of this quad.
bool containsPoint(const FloatPoint&) const;
diff --git a/WebCore/platform/graphics/FloatRect.h b/WebCore/platform/graphics/FloatRect.h
index 2dc854d..74a6293 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) || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN))
+#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN))
#ifdef NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES
typedef struct CGRect NSRect;
#else
@@ -61,6 +61,10 @@ struct SkRect;
namespace WebCore {
+#if PLATFORM(OPENVG)
+class VGRect;
+#endif
+
class IntRect;
class FloatRect {
@@ -129,7 +133,7 @@ public:
#endif
#if (PLATFORM(MAC) && !defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES)) \
- || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN))
+ || (PLATFORM(CHROMIUM) && OS(DARWIN))
FloatRect(const NSRect&);
operator NSRect() const;
#endif
@@ -154,6 +158,10 @@ public:
operator SkRect() const;
#endif
+#if PLATFORM(OPENVG)
+ operator VGRect() const;
+#endif
+
private:
FloatPoint m_location;
FloatSize m_size;
diff --git a/WebCore/platform/graphics/FloatSize.h b/WebCore/platform/graphics/FloatSize.h
index 5a84fd1..1bc3423 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) || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN))
+#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN))
#ifdef NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES
typedef struct CGSize NSSize;
#else
@@ -80,7 +80,7 @@ public:
#endif
#if (PLATFORM(MAC) && !defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES)) \
- || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN))
+ || (PLATFORM(CHROMIUM) && OS(DARWIN))
explicit FloatSize(const NSSize &); // don't do this implicitly since it's lossy
operator NSSize() const;
#endif
diff --git a/WebCore/platform/graphics/Font.cpp b/WebCore/platform/graphics/Font.cpp
index 88774cb..7d0e5a9 100644
--- a/WebCore/platform/graphics/Font.cpp
+++ b/WebCore/platform/graphics/Font.cpp
@@ -24,7 +24,6 @@
#include "config.h"
#include "Font.h"
-#include "CharacterNames.h"
#include "FloatRect.h"
#include "FontCache.h"
#include "FontFallbackList.h"
@@ -266,6 +265,22 @@ FontSelector* Font::fontSelector() const
return m_fontList ? m_fontList->fontSelector() : 0;
}
+String Font::normalizeSpaces(const String& string)
+{
+ unsigned length = string.length();
+ Vector<UChar, 256> buffer(length);
+ bool didReplacement = false;
+
+ for (unsigned i = 0; i < length; ++i) {
+ UChar originalCharacter = string[i];
+ buffer[i] = normalizeSpaces(originalCharacter);
+ if (buffer[i] != originalCharacter)
+ didReplacement = true;
+ }
+
+ return didReplacement ? String(buffer.data(), length) : string;
+}
+
static bool shouldUseFontSmoothing = true;
void Font::setShouldUseSmoothing(bool shouldUseSmoothing)
diff --git a/WebCore/platform/graphics/Font.h b/WebCore/platform/graphics/Font.h
index c067071..3c07be7 100644
--- a/WebCore/platform/graphics/Font.h
+++ b/WebCore/platform/graphics/Font.h
@@ -25,10 +25,13 @@
#ifndef Font_h
#define Font_h
+#include "CharacterNames.h"
#include "TextRun.h"
#include "FontDescription.h"
#include "SimpleFontData.h"
+#include "TypesettingFeatures.h"
#include <wtf/HashMap.h>
+#include <wtf/HashSet.h>
#include <wtf/MathExtras.h>
#if PLATFORM(QT)
@@ -96,6 +99,12 @@ public:
FontRenderingMode renderingMode() const { return m_fontDescription.renderingMode(); }
+ TypesettingFeatures typesettingFeatures() const
+ {
+ TextRenderingMode textRenderingMode = m_fontDescription.textRenderingMode();
+ return textRenderingMode == OptimizeLegibility || textRenderingMode == GeometricPrecision ? Kerning | Ligatures : 0;
+ }
+
FontFamily& firstFamily() { return m_fontDescription.firstFamily(); }
const FontFamily& family() const { return m_fontDescription.family(); }
@@ -175,6 +184,19 @@ public:
static bool treatAsSpace(UChar c) { return c == ' ' || c == '\t' || c == '\n' || c == 0x00A0; }
static bool treatAsZeroWidthSpace(UChar c) { return c < 0x20 || (c >= 0x7F && c < 0xA0) || c == 0x200e || c == 0x200f || (c >= 0x202a && c <= 0x202e) || c == 0xFFFC; }
+ static inline UChar normalizeSpaces(UChar character)
+ {
+ if (treatAsSpace(character))
+ return space;
+
+ if (treatAsZeroWidthSpace(character))
+ return zeroWidthSpace;
+
+ return character;
+ }
+
+ static String normalizeSpaces(const String&);
+
#if ENABLE(SVG_FONTS)
bool isSVGFont() const;
SVGFontElement* svgFont() const;
diff --git a/WebCore/platform/graphics/FontCache.cpp b/WebCore/platform/graphics/FontCache.cpp
index 06ea56b..2aa68f1 100644
--- a/WebCore/platform/graphics/FontCache.cpp
+++ b/WebCore/platform/graphics/FontCache.cpp
@@ -53,7 +53,7 @@ FontCache::FontCache()
{
}
-struct FontPlatformDataCacheKey {
+struct FontPlatformDataCacheKey : FastAllocBase {
FontPlatformDataCacheKey(const AtomicString& family = AtomicString(), unsigned size = 0, unsigned weight = 0, bool italic = false,
bool isPrinterFont = false, FontRenderingMode renderingMode = NormalRenderingMode)
: m_family(family)
@@ -139,7 +139,7 @@ static const AtomicString& alternateFamilyName(const AtomicString& familyName)
DEFINE_STATIC_LOCAL(AtomicString, courierNew, ("Courier New"));
if (equalIgnoringCase(familyName, courier))
return courierNew;
-#if !PLATFORM(WIN_OS)
+#if !OS(WINDOWS)
// On Windows, Courier New (truetype font) is always present and
// Courier is a bitmap font. So, we don't want to map Courier New to
// Courier.
@@ -163,7 +163,7 @@ static const AtomicString& alternateFamilyName(const AtomicString& familyName)
if (equalIgnoringCase(familyName, helvetica))
return arial;
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
// On Windows, bitmap fonts are blocked altogether so that we have to
// alias MS Sans Serif (bitmap font) -> Microsoft Sans Serif (truetype font)
DEFINE_STATIC_LOCAL(AtomicString, msSans, ("MS Sans Serif"));
diff --git a/WebCore/platform/graphics/FontCache.h b/WebCore/platform/graphics/FontCache.h
index 4a6222b..9b41e38 100644
--- a/WebCore/platform/graphics/FontCache.h
+++ b/WebCore/platform/graphics/FontCache.h
@@ -64,7 +64,7 @@ public:
// Also implemented by the platform.
void platformInit();
-#if PLATFORM(WINCE) && !PLATFORM(QT)
+#if OS(WINCE) && !PLATFORM(QT)
#if defined(IMLANG_FONT_LINK) && (IMLANG_FONT_LINK == 2)
IMLangFontLink2* getFontLinkInterface();
#else
diff --git a/WebCore/platform/graphics/FontFastPath.cpp b/WebCore/platform/graphics/FontFastPath.cpp
index 5246593..428e85e 100644
--- a/WebCore/platform/graphics/FontFastPath.cpp
+++ b/WebCore/platform/graphics/FontFastPath.cpp
@@ -135,13 +135,7 @@ GlyphData Font::glyphDataForCharacter(UChar32 c, bool mirror, bool forceSmallCap
UChar codeUnits[2];
int codeUnitsLength;
if (c <= 0xFFFF) {
- UChar c16 = c;
- if (Font::treatAsSpace(c16))
- codeUnits[0] = ' ';
- else if (Font::treatAsZeroWidthSpace(c16))
- codeUnits[0] = zeroWidthSpace;
- else
- codeUnits[0] = c16;
+ codeUnits[0] = Font::normalizeSpaces(c);
codeUnitsLength = 1;
} else {
codeUnits[0] = U16_LEAD(c);
@@ -157,7 +151,7 @@ GlyphData Font::glyphDataForCharacter(UChar32 c, bool mirror, bool forceSmallCap
GlyphData data = fallbackPage && fallbackPage->fontDataForCharacter(c) ? fallbackPage->glyphDataForCharacter(c) : characterFontData->missingGlyphData();
// Cache it so we don't have to do system fallback again next time.
if (!useSmallCapsFont) {
-#if PLATFORM(WINCE)
+#if OS(WINCE)
// missingGlyphData returns a null character, which is not suitable for GDI to display.
// Also, sometimes we cannot map a font for the character on WINCE, but GDI can still
// display the character, probably because the font package is not installed correctly.
@@ -175,7 +169,7 @@ GlyphData Font::glyphDataForCharacter(UChar32 c, bool mirror, bool forceSmallCap
// FIXME: It would be nicer to use the missing glyph from the last resort font instead.
GlyphData data = primaryFont()->missingGlyphData();
if (!useSmallCapsFont) {
-#if PLATFORM(WINCE)
+#if OS(WINCE)
// See comment about WINCE GDI handling near setGlyphDataForCharacter above.
page->setGlyphDataForCharacter(c, c, data.fontData);
return page->glyphDataForCharacter(c);
@@ -251,8 +245,7 @@ bool Font::canUseGlyphCache(const TextRun& run) const
return false;
}
- TextRenderingMode textMode = m_fontDescription.textRenderingMode();
- if (textMode == OptimizeLegibility || textMode == GeometricPrecision)
+ if (typesettingFeatures())
return false;
return true;
diff --git a/WebCore/platform/graphics/GeneratedImage.cpp b/WebCore/platform/graphics/GeneratedImage.cpp
index eec7ffb..8395aff 100644
--- a/WebCore/platform/graphics/GeneratedImage.cpp
+++ b/WebCore/platform/graphics/GeneratedImage.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2010 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,17 +10,17 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
@@ -50,19 +50,24 @@ void GeneratedImage::draw(GraphicsContext* context, const FloatRect& dstRect, co
void GeneratedImage::drawPattern(GraphicsContext* context, const FloatRect& srcRect, const TransformationMatrix& patternTransform,
const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator compositeOp, const FloatRect& destRect)
{
+ // Allow the generator to provide visually-equivalent tiling parameters for better performance.
+ IntSize adjustedSize = m_size;
+ FloatRect adjustedSrcRect = srcRect;
+ m_generator->adjustParametersForTiledDrawing(adjustedSize, adjustedSrcRect);
+
// Create a BitmapImage and call drawPattern on it.
- OwnPtr<ImageBuffer> imageBuffer = ImageBuffer::create(m_size);
+ OwnPtr<ImageBuffer> imageBuffer = ImageBuffer::create(adjustedSize);
ASSERT(imageBuffer.get());
-
+
// Fill with the gradient.
GraphicsContext* graphicsContext = imageBuffer->context();
- graphicsContext->fillRect(FloatRect(FloatPoint(), m_size), *m_generator.get());
-
+ graphicsContext->fillRect(FloatRect(FloatPoint(), adjustedSize), *m_generator.get());
+
// Grab the final image from the image buffer.
Image* bitmap = imageBuffer->image();
-
+
// Now just call drawTiled on that image.
- bitmap->drawPattern(context, srcRect, patternTransform, phase, styleColorSpace, compositeOp, destRect);
+ bitmap->drawPattern(context, adjustedSrcRect, patternTransform, phase, styleColorSpace, compositeOp, destRect);
}
}
diff --git a/WebCore/platform/graphics/Generator.h b/WebCore/platform/graphics/Generator.h
index a0af689..b64d051 100644
--- a/WebCore/platform/graphics/Generator.h
+++ b/WebCore/platform/graphics/Generator.h
@@ -38,6 +38,7 @@ public:
virtual ~Generator() {};
virtual void fill(GraphicsContext*, const FloatRect&) = 0;
+ virtual void adjustParametersForTiledDrawing(IntSize& /* size */, FloatRect& /* srcRect */) { }
};
} //namespace
diff --git a/WebCore/platform/graphics/GlyphBuffer.h b/WebCore/platform/graphics/GlyphBuffer.h
index 04491a7..edb804c 100644
--- a/WebCore/platform/graphics/GlyphBuffer.h
+++ b/WebCore/platform/graphics/GlyphBuffer.h
@@ -50,7 +50,7 @@ class SimpleFontData;
#if PLATFORM(CAIRO)
// FIXME: Why does Cairo use such a huge struct instead of just an offset into an array?
typedef cairo_glyph_t GlyphBufferGlyph;
-#elif PLATFORM(WINCE)
+#elif OS(WINCE)
typedef wchar_t GlyphBufferGlyph;
#else
typedef Glyph GlyphBufferGlyph;
@@ -60,7 +60,7 @@ typedef Glyph GlyphBufferGlyph;
// can be passed directly to CGContextShowGlyphsWithAdvances in FontMac.mm
#if PLATFORM(CG)
typedef CGSize GlyphBufferAdvance;
-#elif PLATFORM(WINCE)
+#elif OS(WINCE)
// There is no cross-platform code that uses the height of GlyphBufferAdvance,
// so we can save memory space on embedded devices by storing only the width
typedef float GlyphBufferAdvance;
@@ -124,7 +124,7 @@ public:
{
#if PLATFORM(CG)
return m_advances[index].width;
-#elif PLATFORM(WINCE)
+#elif OS(WINCE)
return m_advances[index];
#else
return m_advances[index].width();
@@ -156,7 +156,7 @@ public:
#if PLATFORM(CG)
CGSize advance = { width, 0 };
m_advances.append(advance);
-#elif PLATFORM(WINCE)
+#elif OS(WINCE)
m_advances.append(width);
#else
m_advances.append(FloatSize(width, 0));
@@ -172,7 +172,7 @@ public:
#endif
}
-#if !PLATFORM(WINCE)
+#if !OS(WINCE)
void add(Glyph glyph, const SimpleFontData* font, GlyphBufferAdvance advance)
{
m_fontData.append(font);
diff --git a/WebCore/platform/graphics/Gradient.cpp b/WebCore/platform/graphics/Gradient.cpp
index 204a2b6..17d461f 100644
--- a/WebCore/platform/graphics/Gradient.cpp
+++ b/WebCore/platform/graphics/Gradient.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2010 Apple Inc. All rights reserved.
* Copyright (C) 2007 Alp Toker <alp@atoker.com>
*
* Redistribution and use in source and binary forms, with or without
@@ -28,6 +28,8 @@
#include "Gradient.h"
#include "Color.h"
+#include "FloatRect.h"
+#include <wtf/UnusedParam.h>
namespace WebCore {
@@ -62,6 +64,28 @@ Gradient::~Gradient()
platformDestroy();
}
+void Gradient::adjustParametersForTiledDrawing(IntSize& size, FloatRect& srcRect)
+{
+ if (m_radial)
+ return;
+
+ if (srcRect.isEmpty())
+ return;
+
+ if (m_p0.x() == m_p1.x()) {
+ size.setWidth(1);
+ srcRect.setWidth(1);
+ srcRect.setX(0);
+ return;
+ }
+ if (m_p0.y() != m_p1.y())
+ return;
+
+ size.setHeight(1);
+ srcRect.setHeight(1);
+ srcRect.setY(0);
+}
+
void Gradient::addColorStop(float value, const Color& color)
{
float r;
@@ -81,6 +105,16 @@ static inline bool compareStops(const Gradient::ColorStop& a, const Gradient::Co
return a.stop < b.stop;
}
+void Gradient::sortStopsIfNecessary()
+{
+ if (m_stopsSorted)
+ return;
+
+ if (m_stops.size())
+ std::stable_sort(m_stops.begin(), m_stops.end(), compareStops);
+ m_stopsSorted = true;
+}
+
void Gradient::getColor(float value, float* r, float* g, float* b, float* a) const
{
ASSERT(value >= 0);
diff --git a/WebCore/platform/graphics/Gradient.h b/WebCore/platform/graphics/Gradient.h
index 011a2cd..b65550d 100644
--- a/WebCore/platform/graphics/Gradient.h
+++ b/WebCore/platform/graphics/Gradient.h
@@ -36,8 +36,15 @@
#include <wtf/Vector.h>
#if PLATFORM(CG)
+
+#ifdef BUILDING_ON_TIGER
typedef struct CGShading* CGShadingRef;
typedef CGShadingRef PlatformGradient;
+#else
+typedef struct CGGradient* CGGradientRef;
+typedef CGGradientRef PlatformGradient;
+#endif
+
#elif PLATFORM(QT)
QT_BEGIN_NAMESPACE
class QGradient;
@@ -79,7 +86,7 @@ namespace WebCore {
void getColor(float value, float* r, float* g, float* b, float* a) const;
-#if PLATFORM(WINCE) && !PLATFORM(QT)
+#if OS(WINCE) && !PLATFORM(QT)
const FloatPoint& p0() const { return m_p0; }
const FloatPoint& p1() const { return m_p1; }
float r0() const { return m_r0; }
@@ -105,7 +112,7 @@ namespace WebCore {
};
void setStopsSorted(bool s) { m_stopsSorted = s; }
-
+
void setSpreadMethod(GradientSpreadMethod);
GradientSpreadMethod spreadMethod() { return m_spreadMethod; }
void setGradientSpaceTransform(const TransformationMatrix& gradientSpaceTransformation);
@@ -113,8 +120,13 @@ namespace WebCore {
TransformationMatrix gradientSpaceTransform() { return m_gradientSpaceTransformation; }
virtual void fill(GraphicsContext*, const FloatRect&);
+ virtual void adjustParametersForTiledDrawing(IntSize& size, FloatRect& srcRect);
+
void setPlatformGradientSpaceTransform(const TransformationMatrix& gradientSpaceTransformation);
+#if PLATFORM(CG)
+ void paint(GraphicsContext*);
+#endif
private:
Gradient(const FloatPoint& p0, const FloatPoint& p1);
Gradient(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1);
@@ -123,6 +135,7 @@ namespace WebCore {
void platformDestroy();
int findStop(float value) const;
+ void sortStopsIfNecessary();
bool m_radial;
FloatPoint m_p0;
diff --git a/WebCore/platform/graphics/GraphicsContext.cpp b/WebCore/platform/graphics/GraphicsContext.cpp
index e80004f..eac8bcd 100644
--- a/WebCore/platform/graphics/GraphicsContext.cpp
+++ b/WebCore/platform/graphics/GraphicsContext.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 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
@@ -10,17 +10,17 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
@@ -328,7 +328,7 @@ void GraphicsContext::drawImage(Image* image, ColorSpace styleColorSpace, const
drawImage(image, styleColorSpace, FloatRect(dest), srcRect, op, useLowQualityScale);
}
-#if !PLATFORM(WINCE) || PLATFORM(QT)
+#if !OS(WINCE) || PLATFORM(QT)
void GraphicsContext::drawText(const Font& font, const TextRun& run, const IntPoint& point, int from, int to)
{
if (paintingDisabled())
@@ -382,55 +382,6 @@ void GraphicsContext::drawHighlightForText(const Font& font, const TextRun& run,
fillRect(font.selectionRectForText(run, point, h, from, to), backgroundColor, colorSpace);
}
-void GraphicsContext::initFocusRing(int width, int offset)
-{
- if (paintingDisabled())
- return;
- clearFocusRing();
-
- m_common->m_focusRingWidth = width;
- m_common->m_focusRingOffset = offset;
-}
-
-void GraphicsContext::clearFocusRing()
-{
- m_common->m_focusRingRects.clear();
-}
-
-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;
-}
-
-void GraphicsContext::addFocusRingRect(const IntRect& rect)
-{
- if (paintingDisabled() || rect.isEmpty())
- return;
- m_common->m_focusRingRects.append(rect);
-}
-
-int GraphicsContext::focusRingWidth() const
-{
- return m_common->m_focusRingWidth;
-}
-
-int GraphicsContext::focusRingOffset() const
-{
- return m_common->m_focusRingOffset;
-}
-
-const Vector<IntRect>& GraphicsContext::focusRingRects() const
-{
- return m_common->m_focusRingRects;
-}
-
void GraphicsContext::drawImage(Image* image, ColorSpace styleColorSpace, const FloatRect& dest, const FloatRect& src, CompositeOperator op, bool useLowQualityScale)
{
if (paintingDisabled() || !image)
@@ -460,24 +411,35 @@ void GraphicsContext::drawImage(Image* image, ColorSpace styleColorSpace, const
restore();
}
-void GraphicsContext::drawTiledImage(Image* image, ColorSpace styleColorSpace, const IntRect& rect, const IntPoint& srcPoint, const IntSize& tileSize, CompositeOperator op)
+void GraphicsContext::drawTiledImage(Image* image, ColorSpace styleColorSpace, const IntRect& rect, const IntPoint& srcPoint, const IntSize& tileSize, CompositeOperator op, bool useLowQualityScale)
{
if (paintingDisabled() || !image)
return;
-
+ if (useLowQualityScale) {
+ save();
+ setImageInterpolationQuality(InterpolationLow);
+ }
image->drawTiled(this, rect, srcPoint, tileSize, styleColorSpace, op);
+ if (useLowQualityScale)
+ restore();
}
-void GraphicsContext::drawTiledImage(Image* image, ColorSpace styleColorSpace, const IntRect& dest, const IntRect& srcRect, Image::TileRule hRule, Image::TileRule vRule, CompositeOperator op)
+void GraphicsContext::drawTiledImage(Image* image, ColorSpace styleColorSpace, const IntRect& dest, const IntRect& srcRect, Image::TileRule hRule, Image::TileRule vRule, CompositeOperator op, bool useLowQualityScale)
{
if (paintingDisabled() || !image)
return;
+ if (useLowQualityScale) {
+ save();
+ setImageInterpolationQuality(InterpolationLow);
+ }
if (hRule == Image::StretchTile && vRule == Image::StretchTile)
// Just do a scale.
- return drawImage(image, styleColorSpace, dest, srcRect, op);
-
- image->drawTiled(this, dest, srcRect, hRule, vRule, styleColorSpace, op);
+ drawImage(image, styleColorSpace, dest, srcRect, op);
+ else
+ image->drawTiled(this, dest, srcRect, hRule, vRule, styleColorSpace, op);
+ if (useLowQualityScale)
+ restore();
}
void GraphicsContext::addRoundedRectClip(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight,
@@ -544,7 +506,11 @@ void GraphicsContext::setPlatformTextDrawingMode(int mode)
}
#endif
+<<<<<<< HEAD
#if !PLATFORM(QT) && !PLATFORM(CAIRO) && !(PLATFORM(SKIA) && !PLATFORM(ANDROID)) && !PLATFORM(HAIKU)
+=======
+#if !PLATFORM(QT) && !PLATFORM(CAIRO) && !PLATFORM(SKIA) && !PLATFORM(HAIKU) && !PLATFORM(OPENVG)
+>>>>>>> webkit.org at r54127
void GraphicsContext::setPlatformStrokeStyle(const StrokeStyle&)
{
}
diff --git a/WebCore/platform/graphics/GraphicsContext.h b/WebCore/platform/graphics/GraphicsContext.h
index ecf2101..063c490 100644
--- a/WebCore/platform/graphics/GraphicsContext.h
+++ b/WebCore/platform/graphics/GraphicsContext.h
@@ -41,6 +41,11 @@
typedef struct CGContext PlatformGraphicsContext;
#elif PLATFORM(CAIRO)
typedef struct _cairo PlatformGraphicsContext;
+#elif PLATFORM(OPENVG)
+namespace WebCore {
+class SurfaceOpenVG;
+}
+typedef class WebCore::SurfaceOpenVG PlatformGraphicsContext;
#elif PLATFORM(QT)
QT_BEGIN_NAMESPACE
class QPainter;
@@ -79,7 +84,7 @@ typedef class PlatformContextSkia PlatformGraphicsContext;
class BView;
typedef BView PlatformGraphicsContext;
struct pattern;
-#elif PLATFORM(WINCE)
+#elif OS(WINCE)
typedef struct HDC__ PlatformGraphicsContext;
#else
typedef void PlatformGraphicsContext;
@@ -104,7 +109,7 @@ typedef unsigned char UInt8;
namespace WebCore {
-#if PLATFORM(WINCE) && !PLATFORM(QT)
+#if OS(WINCE) && !PLATFORM(QT)
class SharedBitmap;
class SimpleFontData;
class GlyphBuffer;
@@ -152,7 +157,7 @@ namespace WebCore {
GraphicsContext(PlatformGraphicsContext*);
~GraphicsContext();
-#if !PLATFORM(WINCE) || PLATFORM(QT)
+#if !OS(WINCE) || PLATFORM(QT)
PlatformGraphicsContext* platformContext() const;
#endif
@@ -255,10 +260,10 @@ namespace WebCore {
void drawImage(Image*, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect = FloatRect(0, 0, -1, -1),
CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false);
void drawTiledImage(Image*, ColorSpace styleColorSpace, const IntRect& destRect, const IntPoint& srcPoint, const IntSize& tileSize,
- CompositeOperator = CompositeSourceOver);
+ CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false);
void drawTiledImage(Image*, ColorSpace styleColorSpace, const IntRect& destRect, const IntRect& srcRect,
Image::TileRule hRule = Image::StretchTile, Image::TileRule vRule = Image::StretchTile,
- CompositeOperator = CompositeSourceOver);
+ CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false);
void setImageInterpolationQuality(InterpolationQuality);
InterpolationQuality imageInterpolationQuality() const;
@@ -297,11 +302,8 @@ namespace WebCore {
bool getShadow(IntSize&, int&, Color&) const;
void clearShadow();
- void initFocusRing(int width, int offset);
- void addFocusRingRect(const IntRect&);
- void drawFocusRing(const Color&);
- void clearFocusRing();
- IntRect focusRingBoundingRect();
+ void drawFocusRing(const Vector<IntRect>&, int width, int offset, const Color&);
+ void drawFocusRing(const Vector<Path>&, int width, int offset, const Color&);
void setLineCap(LineCap);
void setLineDash(const DashArray&, float dashOffset);
@@ -330,6 +332,7 @@ namespace WebCore {
void scale(const FloatSize&);
void rotate(float angleInRadians);
+ void translate(const FloatSize& size) { translate(size.width(), size.height()); }
void translate(float x, float y);
IntPoint origin();
@@ -338,7 +341,7 @@ namespace WebCore {
void concatCTM(const TransformationMatrix&);
TransformationMatrix getCTM() const;
-#if PLATFORM(WINCE) && !PLATFORM(QT)
+#if OS(WINCE) && !PLATFORM(QT)
void setBitmap(PassRefPtr<SharedBitmap>);
const TransformationMatrix& affineTransform() const;
TransformationMatrix& affineTransform();
@@ -396,7 +399,7 @@ namespace WebCore {
void drawWindowsBitmap(WindowsBitmap*, const IntPoint&);
#endif
-#if (PLATFORM(QT) && defined(Q_WS_WIN)) || (PLATFORM(WX) && PLATFORM(WIN_OS))
+#if (PLATFORM(QT) && defined(Q_WS_WIN)) || (PLATFORM(WX) && OS(WINDOWS))
HDC getWindowsContext(const IntRect&, bool supportAlphaBlend = true, bool mayCreateBitmap = true);
void releaseWindowsContext(HDC, const IntRect&, bool supportAlphaBlend = true, bool mayCreateBitmap = true);
bool shouldIncludeChildWindows() const { return false; }
@@ -446,10 +449,6 @@ namespace WebCore {
static void adjustLineToPixelBoundaries(FloatPoint& p1, FloatPoint& p2, float strokeWidth, const StrokeStyle&);
- int focusRingWidth() const;
- int focusRingOffset() const;
- const Vector<IntRect>& focusRingRects() const;
-
static GraphicsContextPrivate* createGraphicsContextPrivate();
static void destroyGraphicsContextPrivate(GraphicsContextPrivate*);
diff --git a/WebCore/platform/graphics/GraphicsContext3D.h b/WebCore/platform/graphics/GraphicsContext3D.h
index aad8dd4..d7406c9 100644
--- a/WebCore/platform/graphics/GraphicsContext3D.h
+++ b/WebCore/platform/graphics/GraphicsContext3D.h
@@ -33,7 +33,7 @@
#include <wtf/PassOwnPtr.h>
// FIXME: Find a better way to avoid the name confliction for NO_ERROR.
-#if PLATFORM(CHROMIUM) && PLATFORM(WIN_OS)
+#if PLATFORM(CHROMIUM) && OS(WINDOWS)
#undef NO_ERROR
#endif
@@ -65,9 +65,6 @@ namespace WebCore {
class WebGLShader;
class WebGLTexture;
class Image;
- class HTMLVideoElement;
- class ImageData;
- class WebKitCSSMatrix;
struct ActiveInfo {
String name;
@@ -385,7 +382,25 @@ namespace WebCore {
INVALID_FRAMEBUFFER_OPERATION = 0x0506
};
- static PassOwnPtr<GraphicsContext3D> create();
+ // Context creation attributes.
+ struct Attributes {
+ Attributes()
+ : alpha(true)
+ , depth(true)
+ , stencil(true)
+ , antialias(true)
+ , premultipliedAlpha(true)
+ {
+ }
+
+ bool alpha;
+ bool depth;
+ bool stencil;
+ bool antialias;
+ bool premultipliedAlpha;
+ };
+
+ static PassOwnPtr<GraphicsContext3D> create(Attributes attrs);
virtual ~GraphicsContext3D();
#if PLATFORM(MAC)
@@ -462,6 +477,8 @@ namespace WebCore {
void getBufferParameteriv(unsigned long target, unsigned long pname, int* value);
+ Attributes getContextAttributes();
+
unsigned long getError();
void getFloatv(unsigned long pname, float* value);
@@ -528,32 +545,14 @@ namespace WebCore {
// 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, WebGLArray* 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, Image* image,
- bool flipY, bool premultiplyAlpha);
- int texImage2D(unsigned target, unsigned level, HTMLVideoElement* video,
- bool flipY, bool premultiplyAlpha);
+ int texImage2D(unsigned target, unsigned level, unsigned internalformat, unsigned width, unsigned height, unsigned border, unsigned format, unsigned type, void* pixels);
+ int texImage2D(unsigned target, unsigned level, Image* image, 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, WebGLArray* 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, Image* image,
- bool flipY, bool premultiplyAlpha);
- int texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset,
- unsigned width, unsigned height, HTMLVideoElement* video,
- bool flipY, bool premultiplyAlpha);
+ int texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, unsigned width, unsigned height, unsigned format, unsigned type, void* pixels);
+ int texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, Image* image, bool flipY, bool premultiplyAlpha);
void uniform1f(long location, float x);
void uniform1fv(long location, float* v, int size);
@@ -623,11 +622,12 @@ namespace WebCore {
void synthesizeGLError(unsigned long error);
private:
- GraphicsContext3D();
+ GraphicsContext3D(Attributes attrs);
int m_currentWidth, m_currentHeight;
#if PLATFORM(MAC)
+ Attributes m_attrs;
Vector<Vector<float> > m_vertexArray;
CGLContextObj m_contextObj;
diff --git a/WebCore/platform/graphics/GraphicsContextPrivate.h b/WebCore/platform/graphics/GraphicsContextPrivate.h
index c532162..1980337 100644
--- a/WebCore/platform/graphics/GraphicsContextPrivate.h
+++ b/WebCore/platform/graphics/GraphicsContextPrivate.h
@@ -48,7 +48,7 @@ namespace WebCore {
, shadowBlur(0)
, shadowsIgnoreTransforms(false)
#if PLATFORM(CAIRO)
- , globalAlpha(1.0f)
+ , globalAlpha(1)
#endif
{
}
@@ -87,17 +87,12 @@ namespace WebCore {
class GraphicsContextPrivate : public Noncopyable {
public:
GraphicsContextPrivate()
- : m_focusRingWidth(0)
- , m_focusRingOffset(0)
- , m_updatingControlTints(false)
+ : m_updatingControlTints(false)
{
}
GraphicsContextState state;
Vector<GraphicsContextState> stack;
- Vector<IntRect> m_focusRingRects;
- int m_focusRingWidth;
- int m_focusRingOffset;
bool m_updatingControlTints;
};
diff --git a/WebCore/platform/graphics/GraphicsLayer.cpp b/WebCore/platform/graphics/GraphicsLayer.cpp
index e215097..2336d0b 100644
--- a/WebCore/platform/graphics/GraphicsLayer.cpp
+++ b/WebCore/platform/graphics/GraphicsLayer.cpp
@@ -72,6 +72,8 @@ GraphicsLayer::GraphicsLayer(GraphicsLayerClient* client)
, m_contentsOrientation(CompositingCoordinatesTopDown)
, m_parent(0)
, m_maskLayer(0)
+ , m_replicaLayer(0)
+ , m_replicatedLayer(0)
, m_repaintCount(0)
{
}
@@ -214,6 +216,14 @@ void GraphicsLayer::removeFromParent()
}
}
+void GraphicsLayer::setReplicatedByLayer(GraphicsLayer* layer)
+{
+ if (layer)
+ layer->setReplicatedLayer(this);
+
+ m_replicaLayer = layer;
+}
+
void GraphicsLayer::setBackgroundColor(const Color& color)
{
m_backgroundColor = color;
@@ -454,14 +464,27 @@ void GraphicsLayer::dumpProperties(TextStream& ts, int indent) const
}
ts << ")\n";
- writeIndent(ts, indent + 1);
- ts << "(children " << m_children.size() << "\n";
+ if (m_replicaLayer) {
+ writeIndent(ts, indent + 1);
+ ts << "(replica layer " << m_replicaLayer << ")\n";
+ m_replicaLayer->dumpLayer(ts, indent+2);
+ }
+
+ if (m_replicatedLayer) {
+ writeIndent(ts, indent + 1);
+ ts << "(replicated layer " << m_replicatedLayer << ")\n";
+ }
- unsigned i;
- for (i = 0; i < m_children.size(); i++)
- m_children[i]->dumpLayer(ts, indent+2);
- writeIndent(ts, indent + 1);
- ts << ")\n";
+ if (m_children.size()) {
+ writeIndent(ts, indent + 1);
+ ts << "(children " << m_children.size() << "\n";
+
+ unsigned i;
+ for (i = 0; i < m_children.size(); i++)
+ m_children[i]->dumpLayer(ts, indent+2);
+ writeIndent(ts, indent + 1);
+ ts << ")\n";
+ }
}
} // namespace WebCore
diff --git a/WebCore/platform/graphics/GraphicsLayer.h b/WebCore/platform/graphics/GraphicsLayer.h
index 0456bad..844301e 100644
--- a/WebCore/platform/graphics/GraphicsLayer.h
+++ b/WebCore/platform/graphics/GraphicsLayer.h
@@ -59,6 +59,10 @@ class WKCACFLayer;
typedef WKCACFLayer PlatformLayer;
typedef void* NativeLayer;
}
+#elif PLATFORM(QT)
+class QGraphicsItem;
+typedef QGraphicsItem PlatformLayer;
+typedef QGraphicsItem* NativeLayer;
#else
typedef void* PlatformLayer;
typedef void* NativeLayer;
@@ -198,6 +202,16 @@ public:
GraphicsLayer* maskLayer() const { return m_maskLayer; }
virtual void setMaskLayer(GraphicsLayer* layer) { m_maskLayer = layer; }
+ // The given layer will replicate this layer and its children; the replica renders behind this layer.
+ virtual void setReplicatedByLayer(GraphicsLayer*);
+ // Whether this layer is being replicated by another layer.
+ bool isReplicated() const { return m_replicaLayer; }
+ // The layer that replicates this layer (if any).
+ GraphicsLayer* replicaLayer() const { return m_replicaLayer; }
+
+ const FloatPoint& replicatedLayerPosition() const { return m_replicatedLayerPosition; }
+ void setReplicatedLayerPosition(const FloatPoint& p) { m_replicatedLayerPosition = p; }
+
// 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; }
@@ -260,17 +274,17 @@ public:
// Return true if the animation is handled by the compositing system. If this returns
// false, the animation will be run by AnimationController.
- virtual bool addAnimation(const KeyframeValueList&, const IntSize& /*boxSize*/, const Animation*, const String& /*keyframesName*/, double /*beginTime*/) { return false; }
+ virtual bool addAnimation(const KeyframeValueList&, const IntSize& /*boxSize*/, const Animation*, const String& /*keyframesName*/, double /*timeOffset*/) { return false; }
virtual void removeAnimationsForProperty(AnimatedPropertyID) { }
virtual void removeAnimationsForKeyframes(const String& /* keyframesName */) { }
- virtual void pauseAnimation(const String& /* keyframesName */) { }
+ virtual void pauseAnimation(const String& /* keyframesName */, double /*timeOffset*/) { }
virtual void suspendAnimations(double time);
virtual void resumeAnimations();
// Layer contents
virtual void setContentsToImage(Image*) { }
- virtual void setContentsToVideo(PlatformLayer*) { }
+ virtual void setContentsToMedia(PlatformLayer*) { } // video or plug-in
virtual void setContentsBackgroundColor(const Color&) { }
#if ENABLE(3D_CANVAS)
@@ -279,6 +293,8 @@ public:
#endif
// Callback from the underlying graphics system to draw layer contents.
void paintGraphicsLayerContents(GraphicsContext&, const IntRect& clip);
+ // Callback from the underlying graphics system when the layer has been displayed
+ virtual void didDisplay(PlatformLayer*) { }
virtual PlatformLayer* platformLayer() const { return 0; }
@@ -327,6 +343,10 @@ protected:
virtual void setOpacityInternal(float) { }
+ // The layer being replicated.
+ GraphicsLayer* replicatedLayer() const { return m_replicatedLayer; }
+ virtual void setReplicatedLayer(GraphicsLayer* layer) { m_replicatedLayer = layer; }
+
GraphicsLayer(GraphicsLayerClient*);
void dumpProperties(TextStream&, int indent) const;
@@ -365,6 +385,11 @@ protected:
GraphicsLayer* m_maskLayer; // Reference to mask layer. We don't own this.
+ GraphicsLayer* m_replicaLayer; // A layer that replicates this layer. We only allow one, for now.
+ // The replica is not parented; this is the primary reference to it.
+ GraphicsLayer* m_replicatedLayer; // For a replica layer, a reference to the original layer.
+ FloatPoint m_replicatedLayerPosition; // For a replica layer, the position of the replica.
+
IntRect m_contentsRect;
int m_repaintCount;
diff --git a/WebCore/platform/graphics/Image.h b/WebCore/platform/graphics/Image.h
index f25169b..234104a 100644
--- a/WebCore/platform/graphics/Image.h
+++ b/WebCore/platform/graphics/Image.h
@@ -154,6 +154,7 @@ public:
#if PLATFORM(GTK)
virtual GdkPixbuf* getGdkPixbuf() { return 0; }
+ static PassRefPtr<Image> loadPlatformThemeIcon(const char* name, int size);
#endif
protected:
diff --git a/WebCore/platform/graphics/ImageSource.cpp b/WebCore/platform/graphics/ImageSource.cpp
index bf7ae21..c2366c1 100644
--- a/WebCore/platform/graphics/ImageSource.cpp
+++ b/WebCore/platform/graphics/ImageSource.cpp
@@ -35,12 +35,6 @@
#include "ImageDecoder.h"
#endif
-#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 {
ImageSource::ImageSource()
@@ -81,6 +75,9 @@ void ImageSource::setData(SharedBuffer* data, bool allDataReceived)
if (!m_decoder) {
m_decoder = static_cast<NativeImageSourcePtr>(ImageDecoder::create(*data));
#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
if (m_decoder)
m_decoder->setMaxNumPixels(IMAGE_DECODER_DOWN_SAMPLING_MAX_NUMBER_OF_PIXELS);
#endif
diff --git a/WebCore/platform/graphics/ImageSource.h b/WebCore/platform/graphics/ImageSource.h
index 083c7b0..cc40f5e 100644
--- a/WebCore/platform/graphics/ImageSource.h
+++ b/WebCore/platform/graphics/ImageSource.h
@@ -55,7 +55,7 @@ class NativeImageSkia;
#endif
#elif PLATFORM(HAIKU)
class BBitmap;
-#elif PLATFORM(WINCE)
+#elif OS(WINCE)
#include "SharedBitmap.h"
#endif
@@ -105,7 +105,7 @@ typedef wxBitmap* NativeImagePtr;
typedef cairo_surface_t* NativeImagePtr;
#elif PLATFORM(HAIKU)
typedef BBitmap* NativeImagePtr;
-#elif PLATFORM(WINCE)
+#elif OS(WINCE)
typedef RefPtr<SharedBitmap> NativeImagePtr;
#endif
#endif
diff --git a/WebCore/platform/graphics/IntRect.cpp b/WebCore/platform/graphics/IntRect.cpp
index 622e525..188b5f9 100644
--- a/WebCore/platform/graphics/IntRect.cpp
+++ b/WebCore/platform/graphics/IntRect.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003, 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2003, 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
@@ -10,17 +10,17 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
@@ -104,4 +104,15 @@ void IntRect::scale(float s)
m_size.setHeight((int)(height() * s));
}
+IntRect unionRect(const Vector<IntRect>& rects)
+{
+ IntRect result;
+
+ size_t count = rects.size();
+ for (size_t i = 0; i < count; ++i)
+ result.unite(rects[i]);
+
+ return result;
}
+
+} // namespace WebCore
diff --git a/WebCore/platform/graphics/IntRect.h b/WebCore/platform/graphics/IntRect.h
index 97b21bc..e3633df 100644
--- a/WebCore/platform/graphics/IntRect.h
+++ b/WebCore/platform/graphics/IntRect.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003, 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2003, 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
@@ -10,17 +10,17 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef IntRect_h
@@ -28,12 +28,13 @@
#include "IntPoint.h"
#include <wtf/Platform.h>
+#include <wtf/Vector.h>
#if PLATFORM(CG)
typedef struct CGRect CGRect;
#endif
-#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN))
+#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN))
#ifdef NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES
typedef struct CGRect NSRect;
#else
@@ -162,7 +163,7 @@ public:
#endif
#if (PLATFORM(MAC) && !defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES)) \
- || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN))
+ || (PLATFORM(CHROMIUM) && OS(DARWIN))
operator NSRect() const;
#endif
@@ -185,6 +186,8 @@ inline IntRect unionRect(const IntRect& a, const IntRect& b)
return c;
}
+IntRect unionRect(const Vector<IntRect>&);
+
inline bool operator==(const IntRect& a, const IntRect& b)
{
return a.location() == b.location() && a.size() == b.size();
@@ -200,7 +203,7 @@ IntRect enclosingIntRect(const CGRect&);
#endif
#if (PLATFORM(MAC) && !defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES)) \
- || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN))
+ || (PLATFORM(CHROMIUM) && OS(DARWIN))
IntRect enclosingIntRect(const NSRect&);
#endif
diff --git a/WebCore/platform/graphics/IntSize.h b/WebCore/platform/graphics/IntSize.h
index b242784..13d9e22 100644
--- a/WebCore/platform/graphics/IntSize.h
+++ b/WebCore/platform/graphics/IntSize.h
@@ -69,7 +69,8 @@ public:
void setHeight(int height) { m_height = height; }
bool isEmpty() const { return m_width <= 0 || m_height <= 0; }
-
+ bool isZero() const { return !m_width && !m_height; }
+
void expand(int width, int height)
{
m_width += width;
diff --git a/WebCore/platform/graphics/MediaPlayer.cpp b/WebCore/platform/graphics/MediaPlayer.cpp
index 4c66c50..aed9c95 100644
--- a/WebCore/platform/graphics/MediaPlayer.cpp
+++ b/WebCore/platform/graphics/MediaPlayer.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -39,7 +39,7 @@
#if PLATFORM(MAC)
#include "MediaPlayerPrivateQTKit.h"
-#elif PLATFORM(WINCE) && !PLATFORM(QT)
+#elif OS(WINCE) && !PLATFORM(QT)
#include "MediaPlayerPrivateWince.h"
#elif PLATFORM(WIN)
#include "MediaPlayerPrivateQuickTimeWin.h"
@@ -83,8 +83,6 @@ public:
virtual void seek(float) { }
virtual bool seeking() const { return false; }
- virtual void setEndTime(float) { }
-
virtual void setRate(float) { }
virtual void setPreservesPitch(bool) { }
virtual bool paused() const { return false; }
@@ -100,9 +98,6 @@ public:
virtual float maxTimeSeekable() const { return 0; }
virtual PassRefPtr<TimeRanges> buffered() const { return TimeRanges::create(); }
- virtual int dataRate() const { return 0; }
-
- virtual bool totalBytesKnown() const { return false; }
virtual unsigned totalBytes() const { return 0; }
virtual unsigned bytesLoaded() const { return 0; }
@@ -252,7 +247,8 @@ void MediaPlayer::load(const String& url, const ContentType& contentType)
#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
m_private->setMediaPlayerProxy(m_playerProxy);
#endif
-
+ m_private->setAutobuffer(autobuffer());
+ m_private->setPreservesPitch(preservesPitch());
}
if (m_private)
@@ -261,6 +257,11 @@ void MediaPlayer::load(const String& url, const ContentType& contentType)
m_private.set(createNullMediaPlayer(this));
}
+bool MediaPlayer::hasAvailableVideoFrame() const
+{
+ return m_private->hasAvailableVideoFrame();
+}
+
bool MediaPlayer::canLoadPoster() const
{
return m_private->canLoadPoster();
@@ -412,16 +413,6 @@ void MediaPlayer::setPreservesPitch(bool preservesPitch)
m_private->setPreservesPitch(preservesPitch);
}
-int MediaPlayer::dataRate() const
-{
- return m_private->dataRate();
-}
-
-void MediaPlayer::setEndTime(float time)
-{
- m_private->setEndTime(time);
-}
-
PassRefPtr<TimeRanges> MediaPlayer::buffered()
{
return m_private->buffered();
@@ -437,16 +428,6 @@ unsigned MediaPlayer::bytesLoaded()
return m_private->bytesLoaded();
}
-bool MediaPlayer::totalBytesKnown()
-{
- return m_private->totalBytesKnown();
-}
-
-unsigned MediaPlayer::totalBytes()
-{
- return m_private->totalBytes();
-}
-
void MediaPlayer::setSize(const IntSize& size)
{
m_size = size;
diff --git a/WebCore/platform/graphics/MediaPlayer.h b/WebCore/platform/graphics/MediaPlayer.h
index ec8ac33..fa85cfd 100644
--- a/WebCore/platform/graphics/MediaPlayer.h
+++ b/WebCore/platform/graphics/MediaPlayer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -163,8 +163,6 @@ public:
float startTime() const;
- void setEndTime(float time);
-
float rate() const;
void setRate(float);
@@ -175,8 +173,6 @@ public:
float maxTimeSeekable();
unsigned bytesLoaded();
- bool totalBytesKnown();
- unsigned totalBytes();
float volume() const;
void setVolume(float);
@@ -184,8 +180,6 @@ public:
bool hasClosedCaptions() const;
void setClosedCaptionsVisible(bool closedCaptionsVisible);
- int dataRate() const;
-
bool autobuffer() const;
void setAutobuffer(bool);
@@ -213,6 +207,8 @@ public:
MediaPlayerClient* mediaPlayerClient() const { return m_mediaPlayerClient; }
+ bool hasAvailableVideoFrame() const;
+
bool canLoadPoster() const;
void setPoster(const String&);
diff --git a/WebCore/platform/graphics/MediaPlayerPrivate.h b/WebCore/platform/graphics/MediaPlayerPrivate.h
index 03906bd..6cf12ba 100644
--- a/WebCore/platform/graphics/MediaPlayerPrivate.h
+++ b/WebCore/platform/graphics/MediaPlayerPrivate.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -67,8 +67,6 @@ public:
virtual float startTime() const { return 0; }
- virtual void setEndTime(float) = 0;
-
virtual void setRate(float) = 0;
virtual void setPreservesPitch(bool) { }
@@ -85,10 +83,6 @@ public:
virtual float maxTimeSeekable() const = 0;
virtual PassRefPtr<TimeRanges> buffered() const = 0;
- virtual int dataRate() const = 0;
-
- virtual bool totalBytesKnown() const { return totalBytes() > 0; }
- virtual unsigned totalBytes() const = 0;
virtual unsigned bytesLoaded() const = 0;
virtual void setSize(const IntSize&) = 0;
@@ -99,6 +93,8 @@ public:
virtual void setAutobuffer(bool) { };
+ virtual bool hasAvailableVideoFrame() const { return readyState() >= MediaPlayer::HaveCurrentData; }
+
virtual bool canLoadPoster() const { return false; }
virtual void setPoster(const String&) { }
diff --git a/WebCore/platform/graphics/Path.h b/WebCore/platform/graphics/Path.h
index 6618fb7..79d6cc4 100644
--- a/WebCore/platform/graphics/Path.h
+++ b/WebCore/platform/graphics/Path.h
@@ -34,10 +34,7 @@
#if PLATFORM(CG)
typedef struct CGPath PlatformPath;
#elif PLATFORM(QT)
-#include <qglobal.h>
-QT_BEGIN_NAMESPACE
-class QPainterPath;
-QT_END_NAMESPACE
+#include <qpainterpath.h>
typedef QPainterPath PlatformPath;
#elif PLATFORM(WX) && USE(WXGC)
class wxGraphicsPath;
@@ -53,7 +50,7 @@ typedef SkPath PlatformPath;
#elif PLATFORM(HAIKU)
class BRegion;
typedef BRegion PlatformPath;
-#elif PLATFORM(WINCE)
+#elif OS(WINCE)
namespace WebCore {
class PlatformPath;
}
@@ -61,6 +58,13 @@ namespace WebCore {
typedef void PlatformPath;
#endif
+#if PLATFORM(QT)
+/* QPainterPath is valued based */
+typedef PlatformPath PlatformPathPtr;
+#else
+typedef PlatformPath* PlatformPathPtr;
+#endif
+
namespace WebCore {
class FloatPoint;
@@ -131,7 +135,7 @@ namespace WebCore {
String debugString() const;
- PlatformPath* platformPath() const { return m_path; }
+ PlatformPathPtr platformPath() const { return m_path; }
static Path createRoundedRectangle(const FloatRect&, const FloatSize& roundingRadii);
static Path createRoundedRectangle(const FloatRect&, const FloatSize& topLeftRadius, const FloatSize& topRightRadius, const FloatSize& bottomLeftRadius, const FloatSize& bottomRightRadius);
@@ -144,7 +148,7 @@ namespace WebCore {
void transform(const TransformationMatrix&);
private:
- PlatformPath* m_path;
+ PlatformPathPtr m_path;
};
}
diff --git a/WebCore/platform/graphics/Pattern.h b/WebCore/platform/graphics/Pattern.h
index aa0a357..f7f612a 100644
--- a/WebCore/platform/graphics/Pattern.h
+++ b/WebCore/platform/graphics/Pattern.h
@@ -56,7 +56,7 @@ typedef wxBrush* PlatformPatternPtr;
#elif PLATFORM(HAIKU)
#include <interface/GraphicsDefs.h>
typedef pattern* PlatformPatternPtr;
-#elif PLATFORM(WINCE)
+#elif OS(WINCE)
typedef void* PlatformPatternPtr;
#endif
diff --git a/WebCore/platform/graphics/SimpleFontData.h b/WebCore/platform/graphics/SimpleFontData.h
index 387a5c7..09ed0fc 100644
--- a/WebCore/platform/graphics/SimpleFontData.h
+++ b/WebCore/platform/graphics/SimpleFontData.h
@@ -28,14 +28,14 @@
#include "FontPlatformData.h"
#include "GlyphPageTreeNode.h"
#include "GlyphWidthMap.h"
-#include "TextRenderingMode.h"
+#include "TypesettingFeatures.h"
#include <wtf/OwnPtr.h>
#if USE(ATSUI)
typedef struct OpaqueATSUStyle* ATSUStyle;
#endif
-#if PLATFORM(WIN) && !PLATFORM(WINCE)
+#if PLATFORM(WIN) && !OS(WINCE)
#include <usp10.h>
#endif
@@ -115,13 +115,13 @@ public:
virtual String description() const;
#endif
-#if PLATFORM(MAC)
+#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN))
NSFont* getNSFont() const { return m_platformData.font(); }
#endif
#if USE(CORE_TEXT)
CTFontRef getCTFont() const;
- CFDictionaryRef getCFStringAttributes(TextRenderingMode) const;
+ CFDictionaryRef getCFStringAttributes(TypesettingFeatures) const;
#endif
#if USE(ATSUI)
@@ -140,7 +140,7 @@ public:
#if PLATFORM(WIN)
bool isSystemFont() const { return m_isSystemFont; }
-#if !PLATFORM(WINCE) // disable unused members to save space
+#if !OS(WINCE) // disable unused members to save space
SCRIPT_FONTPROPERTIES* scriptFontProperties() const;
SCRIPT_CACHE* scriptCache() const { return &m_scriptCache; }
#endif
@@ -162,7 +162,7 @@ private:
void commonInit();
-#if PLATFORM(WIN) && !PLATFORM(WINCE)
+#if PLATFORM(WIN) && !OS(WINCE)
void initGDIFont();
void platformCommonDestroy();
float widthForGDIGlyph(Glyph glyph) const;
@@ -211,8 +211,7 @@ private:
#if USE(ATSUI)
public:
- mutable ATSUStyle m_ATSUStyle;
- mutable bool m_ATSUStyleInitialized;
+ mutable HashMap<unsigned, ATSUStyle> m_ATSUStyleMap;
mutable bool m_ATSUMirrors;
mutable bool m_checkedShapesArabic;
mutable bool m_shapesArabic;
@@ -222,12 +221,12 @@ private:
#if USE(CORE_TEXT)
mutable RetainPtr<CTFontRef> m_CTFont;
- mutable RetainPtr<CFDictionaryRef> m_CFStringAttributes;
+ mutable HashMap<unsigned, RetainPtr<CFDictionaryRef> > m_CFStringAttributes;
#endif
#if PLATFORM(WIN)
bool m_isSystemFont;
-#if !PLATFORM(WINCE) // disable unused members to save space
+#if !OS(WINCE) // disable unused members to save space
mutable SCRIPT_CACHE m_scriptCache;
mutable SCRIPT_FONTPROPERTIES* m_scriptFontProperties;
#endif
diff --git a/WebCore/platform/graphics/TypesettingFeatures.h b/WebCore/platform/graphics/TypesettingFeatures.h
new file mode 100644
index 0000000..aa46beb
--- /dev/null
+++ b/WebCore/platform/graphics/TypesettingFeatures.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TypesettingFeatures_h
+#define TypesettingFeatures_h
+
+namespace WebCore {
+ enum TypesettingFeature {
+ Kerning = 1 << 0,
+ Ligatures = 1 << 1,
+ };
+
+ typedef unsigned TypesettingFeatures;
+} // namespace WebCore
+
+#endif // TypesettingFeatures_h
diff --git a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
index 14034fd..d866b6c 100644
--- a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
+++ b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
@@ -606,12 +606,16 @@ void GraphicsContext::clipPath(WindRule clipRule)
cairo_clip(cr);
}
-void GraphicsContext::drawFocusRing(const Color& color)
+void GraphicsContext::drawFocusRing(const Vector<Path>& paths, int width, int offset, const Color& color)
+{
+ // FIXME: implement
+}
+
+void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int /* offset */, const Color& color)
{
if (paintingDisabled())
return;
- const Vector<IntRect>& rects = focusRingRects();
unsigned rectCount = rects.size();
cairo_t* cr = m_data->cr;
@@ -632,14 +636,14 @@ void GraphicsContext::drawFocusRing(const Color& color)
cairo_set_line_width(cr, 2.0f);
setPlatformStrokeStyle(DottedStroke);
#else
- int radius = (focusRingWidth() - 1) / 2;
+ int radius = (width - 1) / 2;
for (unsigned i = 0; i < rectCount; i++)
addPath(Path::createRoundedRectangle(rects[i], FloatSize(radius, radius)));
// Force the alpha to 50%. This matches what the Mac does with outline rings.
Color ringColor(color.red(), color.green(), color.blue(), 127);
setColor(cr, ringColor);
- cairo_set_line_width(cr, focusRingWidth());
+ cairo_set_line_width(cr, width);
setPlatformStrokeStyle(SolidStroke);
#endif
diff --git a/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h b/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h
index 54e1217..cedc684 100644
--- a/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h
+++ b/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h
@@ -33,8 +33,8 @@
#include <wtf/MathExtras.h>
#if PLATFORM(GTK)
-#include <gdk/gdk.h>
#include <pango/pango.h>
+typedef struct _GdkExposeEvent GdkExposeEvent;
#elif PLATFORM(WIN)
#include <cairo-win32.h>
#endif
diff --git a/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp b/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
index d991c80..124c7cf 100644
--- a/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
+++ b/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
@@ -132,7 +132,7 @@ void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookUpTable)
pixelColor = Color(lookUpTable[pixelColor.red()],
lookUpTable[pixelColor.green()],
lookUpTable[pixelColor.blue()],
- lookUpTable[pixelColor.alpha()]);
+ pixelColor.alpha());
*pixel = premultipliedARGBFromColor(pixelColor);
}
}
diff --git a/WebCore/platform/graphics/cg/ColorCG.cpp b/WebCore/platform/graphics/cg/ColorCG.cpp
index 40aacc5..e514fa3 100644
--- a/WebCore/platform/graphics/cg/ColorCG.cpp
+++ b/WebCore/platform/graphics/cg/ColorCG.cpp
@@ -68,7 +68,7 @@ Color::Color(CGColorRef color)
m_color = makeRGBA(r * 255, g * 255, b * 255, a * 255);
}
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
CGColorRef createCGColor(const Color& c)
{
@@ -89,7 +89,7 @@ CGColorRef createCGColor(const Color& c)
return color;
}
-#endif // PLATFORM(WIN_OS)
+#endif // OS(WINDOWS)
}
diff --git a/WebCore/platform/graphics/cg/GradientCG.cpp b/WebCore/platform/graphics/cg/GradientCG.cpp
index 05a0aad..e9b5de7 100644
--- a/WebCore/platform/graphics/cg/GradientCG.cpp
+++ b/WebCore/platform/graphics/cg/GradientCG.cpp
@@ -36,10 +36,15 @@ namespace WebCore {
void Gradient::platformDestroy()
{
+#ifdef BUILDING_ON_TIGER
CGShadingRelease(m_gradient);
+#else
+ CGGradientRelease(m_gradient);
+#endif
m_gradient = 0;
}
+#ifdef BUILDING_ON_TIGER
static void gradientCallback(void* info, const CGFloat* in, CGFloat* out)
{
float r, g, b, a;
@@ -69,11 +74,55 @@ CGShadingRef Gradient::platformGradient()
return m_gradient;
}
+#else
+CGGradientRef Gradient::platformGradient()
+{
+ if (m_gradient)
+ return m_gradient;
+
+ static CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+
+ sortStopsIfNecessary();
+
+ const int cReservedStops = 3;
+ Vector<CGFloat, 4 * cReservedStops> colorComponents;
+ colorComponents.reserveCapacity(m_stops.size() * 4); // RGBA components per stop
+
+ Vector<CGFloat, cReservedStops> locations;
+ locations.reserveCapacity(m_stops.size());
+
+ for (size_t i = 0; i < m_stops.size(); ++i) {
+ colorComponents.uncheckedAppend(m_stops[i].red);
+ colorComponents.uncheckedAppend(m_stops[i].green);
+ colorComponents.uncheckedAppend(m_stops[i].blue);
+ colorComponents.uncheckedAppend(m_stops[i].alpha);
+
+ locations.uncheckedAppend(m_stops[i].stop);
+ }
+
+ m_gradient = CGGradientCreateWithColorComponents(colorSpace, colorComponents.data(), locations.data(), m_stops.size());
+
+ return m_gradient;
+}
+#endif
void Gradient::fill(GraphicsContext* context, const FloatRect& rect)
{
context->clip(rect);
+ paint(context);
+}
+
+void Gradient::paint(GraphicsContext* context)
+{
+#ifdef BUILDING_ON_TIGER
CGContextDrawShading(context->platformContext(), platformGradient());
+#else
+ CGGradientDrawingOptions extendOptions = kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation;
+ if (m_radial)
+ CGContextDrawRadialGradient(context->platformContext(), platformGradient(), m_p0, m_r0, m_p1, m_r1, extendOptions);
+ else
+ CGContextDrawLinearGradient(context->platformContext(), platformGradient(), m_p0, m_p1, extendOptions);
+#endif
}
} //namespace
diff --git a/WebCore/platform/graphics/cg/GraphicsContextCG.cpp b/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
index 39f06a6..b11ba66 100644
--- a/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
+++ b/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
@@ -43,7 +43,15 @@
#include <wtf/OwnArrayPtr.h>
#include <wtf/RetainPtr.h>
-#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN))
+#if PLATFORM(MAC) || PLATFORM(CHROMIUM)
+#include "WebCoreSystemInterface.h"
+#endif
+
+#if PLATFORM(WIN)
+#include <WebKitSystemInterface/WebKitSystemInterface.h>
+#endif
+
+#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN))
#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
// Building on 10.6 or later: kCGInterpolationMedium is defined in the CGInterpolationQuality enum.
@@ -490,7 +498,7 @@ static inline bool calculateDrawingMode(const GraphicsContextState& state, CGPat
}
} else {
// Setting mode to kCGPathStroke even if shouldStroke is false. In that case, we return false and mode will not be used,
- // but the compiler will not compain about an uninitialized variable.
+ // but the compiler will not complain about an uninitialized variable.
mode = kCGPathStroke;
}
@@ -547,7 +555,7 @@ void GraphicsContext::fillPath()
else
CGContextClip(context);
CGContextConcatCTM(context, m_common->state.fillGradient->gradientSpaceTransform());
- CGContextDrawShading(context, m_common->state.fillGradient->platformGradient());
+ m_common->state.fillGradient->paint(this);
CGContextRestoreGState(context);
return;
}
@@ -572,7 +580,7 @@ void GraphicsContext::strokePath()
CGContextReplacePathWithStrokedPath(context);
CGContextClip(context);
CGContextConcatCTM(context, m_common->state.strokeGradient->gradientSpaceTransform());
- CGContextDrawShading(context, m_common->state.strokeGradient->platformGradient());
+ m_common->state.strokeGradient->paint(this);
CGContextRestoreGState(context);
return;
}
@@ -596,7 +604,7 @@ void GraphicsContext::fillRect(const FloatRect& rect)
CGContextSaveGState(context);
CGContextClipToRect(context, rect);
CGContextConcatCTM(context, m_common->state.fillGradient->gradientSpaceTransform());
- CGContextDrawShading(context, m_common->state.fillGradient->platformGradient());
+ m_common->state.fillGradient->paint(this);
CGContextRestoreGState(context);
return;
}
@@ -739,56 +747,55 @@ void GraphicsContext::endTransparencyLayer()
m_data->m_userToDeviceTransformKnownToBeIdentity = false;
}
-void GraphicsContext::setPlatformShadow(const IntSize& size, int blur, const Color& color, ColorSpace colorSpace)
+void GraphicsContext::setPlatformShadow(const IntSize& offset, int blur, const Color& color, ColorSpace colorSpace)
{
if (paintingDisabled())
return;
- CGFloat width = size.width();
- CGFloat height = size.height();
+ CGFloat xOffset = offset.width();
+ CGFloat yOffset = offset.height();
CGFloat blurRadius = blur;
CGContextRef context = platformContext();
if (!m_common->state.shadowsIgnoreTransforms) {
- CGAffineTransform transform = CGContextGetCTM(context);
+ CGAffineTransform userToBaseCTM = wkGetUserToBaseCTM(context);
- CGFloat A = transform.a * transform.a + transform.b * transform.b;
- CGFloat B = transform.a * transform.c + transform.b * transform.d;
+ CGFloat A = userToBaseCTM.a * userToBaseCTM.a + userToBaseCTM.b * userToBaseCTM.b;
+ CGFloat B = userToBaseCTM.a * userToBaseCTM.c + userToBaseCTM.b * userToBaseCTM.d;
CGFloat C = B;
- CGFloat D = transform.c * transform.c + transform.d * transform.d;
+ CGFloat D = userToBaseCTM.c * userToBaseCTM.c + userToBaseCTM.d * userToBaseCTM.d;
CGFloat smallEigenvalue = narrowPrecisionToCGFloat(sqrt(0.5 * ((A + D) - sqrt(4 * B * C + (A - D) * (A - D)))));
// Extreme "blur" values can make text drawing crash or take crazy long times, so clamp
blurRadius = min(blur * smallEigenvalue, narrowPrecisionToCGFloat(1000.0));
- CGSize sizeInDeviceSpace = CGSizeApplyAffineTransform(size, transform);
-
- width = sizeInDeviceSpace.width;
- height = sizeInDeviceSpace.height;
+ CGSize offsetInBaseSpace = CGSizeApplyAffineTransform(offset, userToBaseCTM);
+ xOffset = offsetInBaseSpace.width;
+ yOffset = offsetInBaseSpace.height;
}
// Work around <rdar://problem/5539388> by ensuring that the offsets will get truncated
// to the desired integer.
static const CGFloat extraShadowOffset = narrowPrecisionToCGFloat(1.0 / 128);
- if (width > 0)
- width += extraShadowOffset;
- else if (width < 0)
- width -= extraShadowOffset;
+ if (xOffset > 0)
+ xOffset += extraShadowOffset;
+ else if (xOffset < 0)
+ xOffset -= extraShadowOffset;
- if (height > 0)
- height += extraShadowOffset;
- else if (height < 0)
- height -= extraShadowOffset;
+ if (yOffset > 0)
+ yOffset += extraShadowOffset;
+ else if (yOffset < 0)
+ yOffset -= extraShadowOffset;
// Check for an invalid color, as this means that the color was not set for the shadow
// and we should therefore just use the default shadow color.
if (!color.isValid())
- CGContextSetShadow(context, CGSizeMake(width, height), blurRadius);
+ CGContextSetShadow(context, CGSizeMake(xOffset, yOffset), blurRadius);
else {
RetainPtr<CGColorRef> colorCG(AdoptCF, createCGColorWithColorSpace(color, colorSpace));
CGContextSetShadowWithColor(context,
- CGSizeMake(width, height),
+ CGSizeMake(xOffset, yOffset),
blurRadius,
colorCG.get());
}
@@ -838,7 +845,7 @@ void GraphicsContext::strokeRect(const FloatRect& r, float lineWidth)
CGContextAddRect(context, r);
CGContextReplacePathWithStrokedPath(context);
CGContextClip(context);
- CGContextDrawShading(context, m_common->state.strokeGradient->platformGradient());
+ m_common->state.strokeGradient->paint(this);
CGContextRestoreGState(context);
return;
}
diff --git a/WebCore/platform/graphics/cg/PatternCG.cpp b/WebCore/platform/graphics/cg/PatternCG.cpp
index 63628f4..26f402b 100644
--- a/WebCore/platform/graphics/cg/PatternCG.cpp
+++ b/WebCore/platform/graphics/cg/PatternCG.cpp
@@ -61,7 +61,7 @@ CGPatternRef Pattern::createPlatformPattern(const TransformationMatrix& userSpac
// If FLT_MAX should also be used for xStep or yStep, nothing is rendered. Using fractions of FLT_MAX also
// result in nothing being rendered.
- // INT_MAX is almost correct, but there seems to be some number wrapping occuring making the fill
+ // INT_MAX is almost correct, but there seems to be some number wrapping occurring making the fill
// pattern is not filled correctly.
// To make error of floating point less than 0.5, we use the half of the number of mantissa of float (1 << 22).
CGFloat xStep = m_repeatX ? tileRect.width() : (1 << 22);
diff --git a/WebCore/platform/graphics/chromium/FontCustomPlatformData.cpp b/WebCore/platform/graphics/chromium/FontCustomPlatformData.cpp
index 6bd7d7c..6432e17 100644
--- a/WebCore/platform/graphics/chromium/FontCustomPlatformData.cpp
+++ b/WebCore/platform/graphics/chromium/FontCustomPlatformData.cpp
@@ -32,11 +32,11 @@
#include "config.h"
#include "FontCustomPlatformData.h"
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
#include "Base64.h"
#include "ChromiumBridge.h"
#include "OpenTypeUtilities.h"
-#elif PLATFORM(LINUX)
+#elif OS(LINUX)
#include "SkStream.h"
#endif
@@ -45,9 +45,9 @@
#include "OpenTypeSanitizer.h"
#include "SharedBuffer.h"
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
#include <objbase.h>
-#elif PLATFORM(LINUX)
+#elif OS(LINUX)
#include <cstring>
#endif
@@ -55,10 +55,10 @@ namespace WebCore {
FontCustomPlatformData::~FontCustomPlatformData()
{
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
if (m_fontReference)
RemoveFontMemResourceEx(m_fontReference);
-#elif PLATFORM(LINUX)
+#elif OS(LINUX)
if (m_fontReference)
m_fontReference->unref();
#endif
@@ -66,7 +66,7 @@ FontCustomPlatformData::~FontCustomPlatformData()
FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontRenderingMode mode)
{
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
ASSERT(m_fontReference);
LOGFONT logFont;
@@ -99,7 +99,7 @@ FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, b
HFONT hfont = CreateFontIndirect(&logFont);
return FontPlatformData(hfont, size);
-#elif PLATFORM(LINUX)
+#elif OS(LINUX)
ASSERT(m_fontReference);
return FontPlatformData(m_fontReference, size, bold && !m_fontReference->isBold(), italic && !m_fontReference->isItalic());
#else
@@ -108,7 +108,7 @@ FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, b
#endif
}
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
// Creates a unique and unpredictable font name, in order to avoid collisions and to
// not allow access from CSS.
static String createUniqueFontName()
@@ -123,7 +123,7 @@ static String createUniqueFontName()
}
#endif
-#if PLATFORM(LINUX)
+#if OS(LINUX)
class RemoteFontStream : public SkStream {
public:
explicit RemoteFontStream(PassRefPtr<SharedBuffer> buffer)
@@ -180,7 +180,7 @@ FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
buffer = transcodeBuffer.get();
#endif
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
// Introduce the font to GDI. AddFontMemResourceEx should be used with care, because it will pollute the process's
// font namespace (Windows has no API for creating an HFONT from data without exposing the font to the
// entire process first).
@@ -189,9 +189,9 @@ FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
if (!fontReference)
return 0;
return new FontCustomPlatformData(fontReference, fontName);
-#elif PLATFORM(LINUX)
- RemoteFontStream stream(buffer);
- SkTypeface* typeface = SkTypeface::CreateFromStream(&stream);
+#elif OS(LINUX)
+ RemoteFontStream* stream = new RemoteFontStream(buffer);
+ SkTypeface* typeface = SkTypeface::CreateFromStream(stream);
if (!typeface)
return 0;
return new FontCustomPlatformData(typeface);
diff --git a/WebCore/platform/graphics/chromium/FontCustomPlatformData.h b/WebCore/platform/graphics/chromium/FontCustomPlatformData.h
index a42f1ec..e1fbd48 100644
--- a/WebCore/platform/graphics/chromium/FontCustomPlatformData.h
+++ b/WebCore/platform/graphics/chromium/FontCustomPlatformData.h
@@ -35,10 +35,10 @@
#include "FontRenderingMode.h"
#include <wtf/Noncopyable.h>
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
#include "PlatformString.h"
#include <windows.h>
-#elif PLATFORM(LINUX)
+#elif OS(LINUX)
#include "SkTypeface.h"
#endif
@@ -48,12 +48,12 @@ class FontPlatformData;
class SharedBuffer;
struct FontCustomPlatformData : Noncopyable {
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
FontCustomPlatformData(HANDLE fontReference, const String& name)
: m_fontReference(fontReference)
, m_name(name)
{}
-#elif PLATFORM(LINUX)
+#elif OS(LINUX)
explicit FontCustomPlatformData(SkTypeface* typeface)
: m_fontReference(typeface)
{}
@@ -64,10 +64,10 @@ struct FontCustomPlatformData : Noncopyable {
FontPlatformData fontPlatformData(int size, bool bold, bool italic,
FontRenderingMode = NormalRenderingMode);
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
HANDLE m_fontReference;
String m_name;
-#elif PLATFORM(LINUX)
+#elif OS(LINUX)
SkTypeface* m_fontReference;
#endif
};
diff --git a/WebCore/platform/graphics/chromium/FontLinux.cpp b/WebCore/platform/graphics/chromium/FontLinux.cpp
index a4526a8..e76eca8 100644
--- a/WebCore/platform/graphics/chromium/FontLinux.cpp
+++ b/WebCore/platform/graphics/chromium/FontLinux.cpp
@@ -312,7 +312,8 @@ public:
private:
const TextRun& getTextRun(const TextRun& originalRun)
{
- // Convert the |originalRun| to NFC normalized form if combining diacritical marks
+ // Normalize the text run in two ways:
+ // 1) Convert the |originalRun| to NFC normalized form if combining diacritical marks
// (U+0300..) are used in the run. This conversion is necessary since most OpenType
// fonts (e.g., Arial) don't have substitution rules for the diacritical marks in
// their GSUB tables.
@@ -321,9 +322,12 @@ private:
// the API returns FALSE (= not normalized) for complex runs that don't require NFC
// normalization (e.g., Arabic text). Unless the run contains the diacritical marks,
// Harfbuzz will do the same thing for us using the GSUB table.
+ // 2) Convert spacing characters into plain spaces, as some fonts will provide glyphs
+ // for characters like '\n' otherwise.
for (unsigned i = 0; i < originalRun.length(); ++i) {
- UBlockCode block = ::ublock_getCode(originalRun[i]);
- if (block == UBLOCK_COMBINING_DIACRITICAL_MARKS) {
+ UChar ch = originalRun[i];
+ UBlockCode block = ::ublock_getCode(ch);
+ if (block == UBLOCK_COMBINING_DIACRITICAL_MARKS || (Font::treatAsSpace(ch) && ch != ' ')) {
return getNormalizedTextRun(originalRun);
}
}
@@ -342,6 +346,11 @@ private:
normalizedString.extract(m_normalizedBuffer.get(), normalizedString.length() + 1, error);
ASSERT(U_SUCCESS(error));
+ for (unsigned i = 0; i < normalizedString.length(); ++i) {
+ if (Font::treatAsSpace(m_normalizedBuffer[i]))
+ m_normalizedBuffer[i] = ' ';
+ }
+
m_normalizedRun.set(new TextRun(originalRun));
m_normalizedRun->setText(m_normalizedBuffer.get(), normalizedString.length());
return *m_normalizedRun;
@@ -391,6 +400,8 @@ private:
m_item.attributes = new HB_GlyphAttributes[m_maxGlyphs];
m_item.advances = new HB_Fixed[m_maxGlyphs];
m_item.offsets = new HB_FixedPoint[m_maxGlyphs];
+ // HB_FixedPoint is a struct, so we must use memset to clear it.
+ memset(m_item.offsets, 0, m_maxGlyphs * sizeof(HB_FixedPoint));
m_glyphs16 = new uint16_t[m_maxGlyphs];
m_xPositions = new SkScalar[m_maxGlyphs];
@@ -427,18 +438,19 @@ private:
void setGlyphXPositions(bool isRTL)
{
- m_pixelWidth = 0;
- for (unsigned i = 0; i < m_item.num_glyphs; ++i) {
- int index;
- if (isRTL)
- index = m_item.num_glyphs - (i + 1);
- else
- index = i;
+ double position = 0;
+ for (int iter = 0; iter < m_item.num_glyphs; ++iter) {
+ // Glyphs are stored in logical order, but for layout purposes we always go left to right.
+ int i = isRTL ? m_item.num_glyphs - iter - 1 : iter;
m_glyphs16[i] = m_item.glyphs[i];
- m_xPositions[index] = m_offsetX + m_pixelWidth;
- m_pixelWidth += truncateFixedPointToInteger(m_item.advances[index]);
+ double offsetX = truncateFixedPointToInteger(m_item.offsets[i].x);
+ m_xPositions[i] = m_offsetX + position + offsetX;
+
+ double advance = truncateFixedPointToInteger(m_item.advances[i]);
+ position += advance;
}
+ m_pixelWidth = position;
m_offsetX += m_pixelWidth;
}
diff --git a/WebCore/platform/graphics/chromium/FontPlatformData.h b/WebCore/platform/graphics/chromium/FontPlatformData.h
index c6f1912..871fec8 100644
--- a/WebCore/platform/graphics/chromium/FontPlatformData.h
+++ b/WebCore/platform/graphics/chromium/FontPlatformData.h
@@ -31,9 +31,9 @@
#ifndef FontPlatformData_h
#define FontPlatformData_h
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
#include "FontPlatformDataChromiumWin.h"
-#elif defined(__linux__)
+#elif OS(LINUX)
#include "FontPlatformDataLinux.h"
#endif
diff --git a/WebCore/platform/graphics/chromium/HarfbuzzSkia.cpp b/WebCore/platform/graphics/chromium/HarfbuzzSkia.cpp
index 621d674..be3b0d0 100644
--- a/WebCore/platform/graphics/chromium/HarfbuzzSkia.cpp
+++ b/WebCore/platform/graphics/chromium/HarfbuzzSkia.cpp
@@ -30,7 +30,6 @@
#include "config.h"
-#include "Font.h"
#include "FontPlatformData.h"
#include "wtf/OwnArrayPtr.h"
@@ -42,7 +41,6 @@
extern "C" {
#include "harfbuzz-shaper.h"
-#include "harfbuzz-unicode.h"
}
// This file implements the callbacks which Harfbuzz requires by using Skia
@@ -67,29 +65,10 @@ static HB_Bool stringToGlyphs(HB_Font hbFont, const HB_UChar16* characters, hb_u
// HB_Glyph is 32-bit, but Skia outputs only 16-bit numbers. So our
// |glyphs| array needs to be converted.
- // Additionally, if the CSS white-space property is inhibiting line
- // breaking, we might find end-of-line charactors rendered via the complex
- // text path. Fonts don't provide glyphs for these code points so, if we
- // find one, we simulate the space glyph being interposed in this case.
- // Because the input is variable-length per code point, we walk the input
- // in step with the output.
- // FIXME: it seems that this logic is duplicated in CoreTextController and UniscribeController
- ssize_t indexOfNextCodePoint = 0;
- uint16_t spaceGlyphNumber = 0;
for (int i = numGlyphs - 1; i >= 0; --i) {
- const uint32_t currentCodePoint = utf16_to_code_point(characters, length, &indexOfNextCodePoint);
-
uint16_t value;
// We use a memcpy to avoid breaking strict aliasing rules.
memcpy(&value, reinterpret_cast<char*>(glyphs) + sizeof(uint16_t) * i, sizeof(uint16_t));
-
- if (!value && Font::treatAsSpace(currentCodePoint)) {
- static const uint16_t spaceUTF16 = ' ';
- if (!spaceGlyphNumber)
- paint.textToGlyphs(&spaceUTF16, sizeof(spaceUTF16), &spaceGlyphNumber);
- value = spaceGlyphNumber;
- }
-
glyphs[i] = value;
}
@@ -188,15 +167,16 @@ static void getGlyphMetrics(HB_Font hbFont, HB_Glyph glyph, HB_GlyphMetrics* met
SkRect bounds;
paint.getTextWidths(&glyph16, sizeof(glyph16), &width, &bounds);
- metrics->x = SkiaScalarToHarfbuzzFixed(width);
+ metrics->x = SkiaScalarToHarfbuzzFixed(bounds.fLeft);
+ metrics->y = SkiaScalarToHarfbuzzFixed(bounds.fTop);
+ metrics->width = SkiaScalarToHarfbuzzFixed(bounds.width());
+ metrics->height = SkiaScalarToHarfbuzzFixed(bounds.height());
+
+ metrics->xOffset = SkiaScalarToHarfbuzzFixed(width);
// We can't actually get the |y| correct because Skia doesn't export
// the vertical advance. However, nor we do ever render vertical text at
// the moment so it's unimportant.
- metrics->y = 0;
- metrics->width = SkiaScalarToHarfbuzzFixed(bounds.width());
- metrics->height = SkiaScalarToHarfbuzzFixed(bounds.height());
- metrics->xOffset = SkiaScalarToHarfbuzzFixed(bounds.fLeft);
- metrics->yOffset = SkiaScalarToHarfbuzzFixed(bounds.fTop);
+ metrics->yOffset = 0;
}
static HB_Fixed getFontMetric(HB_Font hbFont, HB_FontMetric metric)
diff --git a/WebCore/platform/graphics/chromium/TransparencyWin.cpp b/WebCore/platform/graphics/chromium/TransparencyWin.cpp
index 6dcd595..80df2ec 100644
--- a/WebCore/platform/graphics/chromium/TransparencyWin.cpp
+++ b/WebCore/platform/graphics/chromium/TransparencyWin.cpp
@@ -371,8 +371,11 @@ void TransparencyWin::initializeNewContext()
return;
m_drawContext = m_layerBuffer->context();
- if (needReferenceBitmap)
+ if (needReferenceBitmap) {
m_referenceBitmap = m_ownedBuffers->referenceBitmap();
+ if (!m_referenceBitmap || !m_referenceBitmap->getPixels())
+ return;
+ }
m_validLayer = true;
return;
}
diff --git a/WebCore/platform/graphics/filters/FEColorMatrix.cpp b/WebCore/platform/graphics/filters/FEColorMatrix.cpp
index f422157..bd19d14 100644
--- a/WebCore/platform/graphics/filters/FEColorMatrix.cpp
+++ b/WebCore/platform/graphics/filters/FEColorMatrix.cpp
@@ -184,6 +184,7 @@ void FEColorMatrix::apply(Filter* filter)
break;
case FECOLORMATRIX_TYPE_LUMINANCETOALPHA:
effectType<FECOLORMATRIX_TYPE_LUMINANCETOALPHA>(srcPixelArray, imageData, m_values);
+ setIsAlphaImage(true);
break;
}
diff --git a/WebCore/platform/graphics/filters/FEComponentTransfer.cpp b/WebCore/platform/graphics/filters/FEComponentTransfer.cpp
index 1d9cfff..f9aa011 100644
--- a/WebCore/platform/graphics/filters/FEComponentTransfer.cpp
+++ b/WebCore/platform/graphics/filters/FEComponentTransfer.cpp
@@ -3,6 +3,7 @@
2004, 2005 Rob Buis <buis@kde.org>
2005 Eric Seidel <eric@webkit.org>
2009 Dirk Schulze <krit@webkit.org>
+ Copyright (C) Research In Motion Limited 2010. 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
@@ -140,7 +141,8 @@ static void linear(unsigned char* values, const ComponentTransferFunction& trans
static 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);
+ double exponent = transferFunction.exponent; // RCVT doesn't like passing a double and a float to pow, so promote this to double
+ double val = 255.0 * (transferFunction.amplitude * pow((i / 255.0), exponent) + transferFunction.offset);
val = std::max(0.0, std::min(255.0, val));
values[i] = static_cast<unsigned char>(val);
}
diff --git a/WebCore/platform/graphics/filters/FEComponentTransfer.h b/WebCore/platform/graphics/filters/FEComponentTransfer.h
index 773aba7..ab84cf0 100644
--- a/WebCore/platform/graphics/filters/FEComponentTransfer.h
+++ b/WebCore/platform/graphics/filters/FEComponentTransfer.h
@@ -25,7 +25,6 @@
#if ENABLE(FILTERS)
#include "FilterEffect.h"
-#include "SVGFEDisplacementMap.h"
#include "Filter.h"
#include <wtf/Vector.h>
diff --git a/WebCore/platform/graphics/filters/FEComposite.cpp b/WebCore/platform/graphics/filters/FEComposite.cpp
index c540cb7..67d3d27 100644
--- a/WebCore/platform/graphics/filters/FEComposite.cpp
+++ b/WebCore/platform/graphics/filters/FEComposite.cpp
@@ -111,9 +111,7 @@ inline void arithmetic(const RefPtr<CanvasPixelArray>& srcPixelArrayA, CanvasPix
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;
+ double result = scaledK1 * i1 * i2 + k2 * i1 + k3 * i2 + scaledK4;
srcPixelArrayB->set(pixelOffset + channel, result);
}
}
diff --git a/WebCore/platform/graphics/gtk/ImageGtk.cpp b/WebCore/platform/graphics/gtk/ImageGtk.cpp
index 38da70d..c62d988 100644
--- a/WebCore/platform/graphics/gtk/ImageGtk.cpp
+++ b/WebCore/platform/graphics/gtk/ImageGtk.cpp
@@ -44,29 +44,30 @@ template <> void freeOwnedGPtr<GtkIconInfo>(GtkIconInfo* info)
namespace WebCore {
-static CString getIconFileNameOrFallback(const char* name, const char* fallback)
+static CString getThemeIconFileName(const char* name, int size)
{
- GOwnPtr<GtkIconInfo> info(gtk_icon_theme_lookup_icon(gtk_icon_theme_get_default(),
- name, 16, GTK_ICON_LOOKUP_NO_SVG));
- if (!info)
- return String::format("%s/webkit-1.0/images/%s.png", DATA_DIR, fallback).utf8();
+ GtkIconInfo* iconInfo = gtk_icon_theme_lookup_icon(gtk_icon_theme_get_default(),
+ name, size, GTK_ICON_LOOKUP_NO_SVG);
+ // Try to fallback on MISSING_IMAGE.
+ if (!iconInfo)
+ iconInfo = gtk_icon_theme_lookup_icon(gtk_icon_theme_get_default(),
+ GTK_STOCK_MISSING_IMAGE, size,
+ GTK_ICON_LOOKUP_NO_SVG);
+ if (iconInfo) {
+ GOwnPtr<GtkIconInfo> info(iconInfo);
+ return CString(gtk_icon_info_get_filename(info.get()));
+ }
- return CString(gtk_icon_info_get_filename(info.get()));
+ // No icon was found, this can happen if not GTK theme is set. In
+ // that case an empty Image will be created.
+ return CString();
}
-static PassRefPtr<SharedBuffer> loadResourceSharedBuffer(const char* name)
+static PassRefPtr<SharedBuffer> loadResourceSharedBuffer(CString name)
{
- CString fileName;
-
- // Find the path for the image
- if (strcmp("missingImage", name) == 0)
- fileName = getIconFileNameOrFallback(GTK_STOCK_MISSING_IMAGE, "missingImage");
- else
- fileName = String::format("%s/webkit-1.0/images/%s.png", DATA_DIR, name).utf8();
-
GOwnPtr<gchar> content;
gsize length;
- if (!g_file_get_contents(fileName.data(), &content.outPtr(), &length, 0))
+ if (!g_file_get_contents(name.data(), &content.outPtr(), &length, 0))
return SharedBuffer::create();
return SharedBuffer::create(content.get(), length);
@@ -80,14 +81,32 @@ void BitmapImage::invalidatePlatformData()
{
}
-PassRefPtr<Image> Image::loadPlatformResource(const char* name)
+PassRefPtr<Image> loadImageFromFile(CString fileName)
{
RefPtr<BitmapImage> img = BitmapImage::create();
- RefPtr<SharedBuffer> buffer = loadResourceSharedBuffer(name);
- img->setData(buffer.release(), true);
+ if (!fileName.isNull()) {
+ RefPtr<SharedBuffer> buffer = loadResourceSharedBuffer(fileName);
+ img->setData(buffer.release(), true);
+ }
return img.release();
}
+PassRefPtr<Image> Image::loadPlatformResource(const char* name)
+{
+ CString fileName;
+ if (!strcmp("missingImage", name))
+ fileName = getThemeIconFileName(GTK_STOCK_MISSING_IMAGE, 16);
+ if (fileName.isNull())
+ fileName = String::format("%s/webkit-1.0/images/%s.png", DATA_DIR, name).utf8();
+
+ return loadImageFromFile(fileName);
+}
+
+PassRefPtr<Image> Image::loadPlatformThemeIcon(const char* name, int size)
+{
+ return loadImageFromFile(getThemeIconFileName(name, size));
+}
+
static inline unsigned char* getCairoSurfacePixel(unsigned char* data, uint x, uint y, uint rowStride)
{
return data + (y * rowStride) + x * 4;
diff --git a/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp b/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp
index a023dae..41f90f0 100644
--- a/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp
+++ b/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp
@@ -29,6 +29,9 @@
#include "CString.h"
#include "DataSourceGStreamer.h"
+#include "Document.h"
+#include "Frame.h"
+#include "FrameView.h"
#include "GraphicsContext.h"
#include "IntRect.h"
#include "KURL.h"
@@ -36,6 +39,7 @@
#include "MediaPlayer.h"
#include "NotImplemented.h"
#include "ScrollView.h"
+#include "SecurityOrigin.h"
#include "TimeRanges.h"
#include "VideoSinkGStreamer.h"
#include "Widget.h"
@@ -46,6 +50,7 @@
#include <gst/video/video.h>
#include <limits>
#include <math.h>
+#include <webkit/webkitwebview.h>
#include <wtf/gtk/GOwnPtr.h>
using namespace std;
@@ -59,9 +64,24 @@ gboolean mediaPlayerPrivateMessageCallback(GstBus* bus, GstMessage* message, gpo
MediaPlayer::NetworkState error;
MediaPlayerPrivate* mp = reinterpret_cast<MediaPlayerPrivate*>(data);
gint percent = 0;
+ bool issueError = true;
+ bool attemptNextLocation = false;
+
+ if (message->structure) {
+ const gchar* messageTypeName = gst_structure_get_name(message->structure);
+
+ // Redirect messages are sent from elements, like qtdemux, to
+ // notify of the new location(s) of the media.
+ if (!g_strcmp0(messageTypeName, "redirect")) {
+ mp->mediaLocationChanged(message);
+ return true;
+ }
+ }
switch (GST_MESSAGE_TYPE(message)) {
case GST_MESSAGE_ERROR:
+ if (mp && mp->pipelineReset())
+ break;
gst_message_parse_error(message, &err.outPtr(), &debug.outPtr());
LOG_VERBOSE(Media, "Error: %d, %s", err->code, err->message);
@@ -72,13 +92,18 @@ gboolean mediaPlayerPrivateMessageCallback(GstBus* bus, GstMessage* message, gpo
|| err->code == GST_CORE_ERROR_MISSING_PLUGIN
|| err->code == GST_RESOURCE_ERROR_NOT_FOUND)
error = MediaPlayer::FormatError;
- else if (err->domain == GST_STREAM_ERROR)
+ else if (err->domain == GST_STREAM_ERROR) {
error = MediaPlayer::DecodeError;
- else if (err->domain == GST_RESOURCE_ERROR)
+ attemptNextLocation = true;
+ } else if (err->domain == GST_RESOURCE_ERROR)
error = MediaPlayer::NetworkError;
- if (mp)
- mp->loadingFailed(error);
+ if (mp) {
+ if (attemptNextLocation)
+ issueError = !mp->loadNextLocation();
+ if (issueError)
+ mp->loadingFailed(error);
+ }
break;
case GST_MESSAGE_EOS:
LOG_VERBOSE(Media, "End of Stream");
@@ -91,6 +116,10 @@ gboolean mediaPlayerPrivateMessageCallback(GstBus* bus, GstMessage* message, gpo
gst_message_parse_buffering(message, &percent);
LOG_VERBOSE(Media, "Buffering %d", percent);
break;
+ case GST_MESSAGE_DURATION:
+ LOG_VERBOSE(Media, "Duration changed");
+ mp->durationChanged();
+ break;
default:
LOG_VERBOSE(Media, "Unhandled GStreamer message type: %s",
GST_MESSAGE_TYPE_NAME(message));
@@ -99,6 +128,69 @@ gboolean mediaPlayerPrivateMessageCallback(GstBus* bus, GstMessage* message, gpo
return true;
}
+void mediaPlayerPrivateSourceChangedCallback(GObject *object, GParamSpec *pspec, gpointer data)
+{
+ MediaPlayerPrivate* mp = reinterpret_cast<MediaPlayerPrivate*>(data);
+ GstElement* element;
+
+ g_object_get(mp->m_playBin, "source", &element, NULL);
+ gst_object_replace((GstObject**) &mp->m_source, (GstObject*) element);
+
+ if (element) {
+ GParamSpec* pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(element), "cookies");
+
+ // First check if the source element has a cookies property
+ // of the format we expect
+ if (!pspec || pspec->value_type != G_TYPE_STRV)
+ return;
+
+ // Then get the cookies for the URI and set them
+ SoupSession* session = webkit_get_default_session();
+ SoupCookieJar* cookieJar = SOUP_COOKIE_JAR(soup_session_get_feature(session, SOUP_TYPE_COOKIE_JAR));
+
+ char* location;
+ g_object_get(element, "location", &location, NULL);
+
+ SoupURI* uri = soup_uri_new(location);
+ g_free(location);
+
+ // Let Apple web servers know we want to access their nice movie trailers.
+ if (g_str_equal(uri->host, "movies.apple.com"))
+ g_object_set(element, "user-agent", "Quicktime/7.2.0", NULL);
+
+ char* cookies = soup_cookie_jar_get_cookies(cookieJar, uri, FALSE);
+ soup_uri_free(uri);
+
+ char* cookiesStrv[] = {cookies, NULL};
+ g_object_set(element, "cookies", cookiesStrv, NULL);
+ g_free(cookies);
+
+ Frame* frame = mp->m_player->frameView() ? mp->m_player->frameView()->frame() : 0;
+ Document* document = frame ? frame->document() : 0;
+ if (document) {
+ GstStructure* extraHeaders = gst_structure_new("extra-headers",
+ "Referer", G_TYPE_STRING,
+ document->documentURI().utf8().data(), 0);
+ g_object_set(element, "extra-headers", extraHeaders, NULL);
+ gst_structure_free(extraHeaders);
+ }
+ }
+
+ gst_object_unref(element);
+}
+
+void mediaPlayerPrivateVolumeChangedCallback(GObject *element, GParamSpec *pspec, gpointer data)
+{
+ MediaPlayerPrivate* mp = reinterpret_cast<MediaPlayerPrivate*>(data);
+ mp->volumeChanged();
+}
+
+gboolean notifyVolumeIdleCallback(MediaPlayer* mp)
+{
+ mp->volumeChanged();
+ return FALSE;
+}
+
static float playbackPosition(GstElement* playbin)
{
@@ -114,8 +206,8 @@ static float playbackPosition(GstElement* playbin)
gint64 position;
gst_query_parse_position(query, 0, &position);
- // Position is available only if the pipeline is not in NULL or
- // READY state.
+ // Position is available only if the pipeline is not in GST_STATE_NULL or
+ // GST_STATE_READY state.
if (position != static_cast<gint64>(GST_CLOCK_TIME_NONE))
ret = static_cast<float>(position) / static_cast<float>(GST_SECOND);
@@ -126,6 +218,7 @@ static float playbackPosition(GstElement* playbin)
return ret;
}
+
void mediaPlayerPrivateRepaintCallback(WebKitVideoSink*, GstBuffer *buffer, MediaPlayerPrivate* playerPrivate)
{
g_return_if_fail(GST_IS_BUFFER(buffer));
@@ -146,7 +239,7 @@ void MediaPlayerPrivate::registerMediaEngine(MediaEngineRegistrar registrar)
static bool gstInitialized = false;
-static bool do_gst_init()
+static bool doGstInit()
{
// FIXME: We should pass the arguments from the command line
if (!gstInitialized) {
@@ -165,7 +258,7 @@ static bool do_gst_init()
bool MediaPlayerPrivate::isAvailable()
{
- if (!do_gst_init())
+ if (!doGstInit())
return false;
GstElementFactory* factory = gst_element_factory_find("playbin2");
@@ -180,6 +273,7 @@ MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
: m_player(player)
, m_playBin(0)
, m_videoSink(0)
+ , m_fpsSink(0)
, m_source(0)
, m_seekTime(0)
, m_changingRate(false)
@@ -190,19 +284,40 @@ MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
, m_isStreaming(false)
, m_size(IntSize())
, m_buffer(0)
+ , m_mediaLocations(0)
+ , m_mediaLocationCurrentIndex(0)
+ , m_resetPipeline(false)
, m_paused(true)
, m_seeking(false)
+ , m_playbackRate(1)
, m_errorOccured(false)
+ , m_volumeIdleId(-1)
+ , m_mediaDuration(0.0)
{
- do_gst_init();
+ doGstInit();
}
MediaPlayerPrivate::~MediaPlayerPrivate()
{
+ if (m_volumeIdleId) {
+ g_source_remove(m_volumeIdleId);
+ m_volumeIdleId = -1;
+ }
+
if (m_buffer)
gst_buffer_unref(m_buffer);
m_buffer = 0;
+ if (m_mediaLocations) {
+ gst_structure_free(m_mediaLocations);
+ m_mediaLocations = 0;
+ }
+
+ if (m_source) {
+ gst_object_unref(m_source);
+ m_source = 0;
+ }
+
if (m_playBin) {
gst_element_set_state(m_playBin, GST_STATE_NULL);
gst_object_unref(GST_OBJECT(m_playBin));
@@ -212,6 +327,11 @@ MediaPlayerPrivate::~MediaPlayerPrivate()
g_object_unref(m_videoSink);
m_videoSink = 0;
}
+
+ if (m_fpsSink) {
+ g_object_unref(m_fpsSink);
+ m_fpsSink = 0;
+ }
}
void MediaPlayerPrivate::load(const String& url)
@@ -230,28 +350,35 @@ void MediaPlayerPrivate::load(const String& url)
pause();
}
-void MediaPlayerPrivate::play()
+bool MediaPlayerPrivate::changePipelineState(GstState newState)
{
- GstState state;
+ ASSERT(newState == GST_STATE_PLAYING || newState == GST_STATE_PAUSED);
+
+ GstState currentState;
GstState pending;
- gst_element_get_state(m_playBin, &state, &pending, 0);
- if (state != GST_STATE_PLAYING && pending != GST_STATE_PLAYING) {
- LOG_VERBOSE(Media, "Play");
- gst_element_set_state(m_playBin, GST_STATE_PLAYING);
+ gst_element_get_state(m_playBin, &currentState, &pending, 0);
+ if (currentState != newState && pending != newState) {
+ GstStateChangeReturn ret = gst_element_set_state(m_playBin, newState);
+ GstState pausedOrPlaying = newState == GST_STATE_PLAYING ? GST_STATE_PAUSED : GST_STATE_PLAYING;
+ if (currentState != pausedOrPlaying && ret == GST_STATE_CHANGE_FAILURE) {
+ loadingFailed(MediaPlayer::Empty);
+ return false;
+ }
}
+ return true;
}
-void MediaPlayerPrivate::pause()
+void MediaPlayerPrivate::play()
{
- GstState state;
- GstState pending;
+ if (changePipelineState(GST_STATE_PLAYING))
+ LOG_VERBOSE(Media, "Play");
+}
- gst_element_get_state(m_playBin, &state, &pending, 0);
- if (state != GST_STATE_PAUSED && pending != GST_STATE_PAUSED) {
+void MediaPlayerPrivate::pause()
+{
+ if (changePipelineState(GST_STATE_PAUSED))
LOG_VERBOSE(Media, "Pause");
- gst_element_set_state(m_playBin, GST_STATE_PAUSED);
- }
}
float MediaPlayerPrivate::duration() const
@@ -262,6 +389,9 @@ float MediaPlayerPrivate::duration() const
if (m_errorOccured)
return 0.0;
+ if (m_mediaDuration)
+ return m_mediaDuration;
+
GstFormat timeFormat = GST_FORMAT_TIME;
gint64 timeLength = 0;
@@ -293,7 +423,9 @@ float MediaPlayerPrivate::currentTime() const
void MediaPlayerPrivate::seek(float time)
{
- GstClockTime sec = (GstClockTime)(time * GST_SECOND);
+ // Avoid useless seeking.
+ if (time == playbackPosition(m_playBin))
+ return;
if (!m_playBin)
return;
@@ -304,6 +436,7 @@ void MediaPlayerPrivate::seek(float time)
if (m_errorOccured)
return;
+ GstClockTime sec = (GstClockTime)(time * GST_SECOND);
LOG_VERBOSE(Media, "Seek: %" GST_TIME_FORMAT, GST_TIME_ARGS(sec));
if (!gst_element_seek(m_playBin, m_player->rate(),
GST_FORMAT_TIME,
@@ -317,11 +450,6 @@ void MediaPlayerPrivate::seek(float time)
}
}
-void MediaPlayerPrivate::setEndTime(float time)
-{
- notImplemented();
-}
-
void MediaPlayerPrivate::startEndPointTimerIfNeeded()
{
notImplemented();
@@ -384,7 +512,7 @@ bool MediaPlayerPrivate::hasVideo() const
{
gint currentVideo = -1;
if (m_playBin)
- g_object_get(G_OBJECT(m_playBin), "current-video", &currentVideo, NULL);
+ g_object_get(m_playBin, "current-video", &currentVideo, NULL);
return currentVideo > -1;
}
@@ -392,7 +520,7 @@ bool MediaPlayerPrivate::hasAudio() const
{
gint currentAudio = -1;
if (m_playBin)
- g_object_get(G_OBJECT(m_playBin), "current-audio", &currentAudio, NULL);
+ g_object_get(m_playBin, "current-audio", &currentAudio, NULL);
return currentAudio > -1;
}
@@ -401,11 +529,25 @@ void MediaPlayerPrivate::setVolume(float volume)
if (!m_playBin)
return;
- g_object_set(G_OBJECT(m_playBin), "volume", static_cast<double>(volume), NULL);
+ g_object_set(m_playBin, "volume", static_cast<double>(volume), NULL);
}
+void MediaPlayerPrivate::volumeChanged()
+{
+ if (m_volumeIdleId) {
+ g_source_remove(m_volumeIdleId);
+ m_volumeIdleId = -1;
+ }
+ m_volumeIdleId = g_idle_add((GSourceFunc) notifyVolumeIdleCallback, m_player);
+}
+
+
void MediaPlayerPrivate::setRate(float rate)
{
+ // Avoid useless playback rate update.
+ if (m_playbackRate == rate)
+ return;
+
GstState state;
GstState pending;
@@ -417,6 +559,7 @@ void MediaPlayerPrivate::setRate(float rate)
if (m_isStreaming)
return;
+ m_playbackRate = rate;
m_changingRate = true;
float currentPosition = playbackPosition(m_playBin) * GST_SECOND;
GstSeekFlags flags = (GstSeekFlags)(GST_SEEK_FLAG_FLUSH);
@@ -452,12 +595,6 @@ void MediaPlayerPrivate::setRate(float rate)
g_object_set(m_playBin, "mute", mute, NULL);
}
-int MediaPlayerPrivate::dataRate() const
-{
- notImplemented();
- return 1;
-}
-
MediaPlayer::NetworkState MediaPlayerPrivate::networkState() const
{
return m_networkState;
@@ -512,13 +649,7 @@ unsigned MediaPlayerPrivate::bytesLoaded() const
if (!dur)
return 0;*/
- return 1;//totalBytes() * maxTime / dur;
-}
-
-bool MediaPlayerPrivate::totalBytesKnown() const
-{
- LOG_VERBOSE(Media, "totalBytesKnown");
- return totalBytes() > 0;
+ return 1; // totalBytes() * maxTime / dur;
}
unsigned MediaPlayerPrivate::totalBytes() const
@@ -573,6 +704,8 @@ void MediaPlayerPrivate::updateStates()
gst_element_state_get_name(state),
gst_element_state_get_name(pending));
+ m_resetPipeline = state <= GST_STATE_READY;
+
if (state == GST_STATE_READY)
m_readyState = MediaPlayer::HaveNothing;
else if (state == GST_STATE_PAUSED)
@@ -581,6 +714,11 @@ void MediaPlayerPrivate::updateStates()
if (state == GST_STATE_PLAYING) {
m_readyState = MediaPlayer::HaveEnoughData;
m_paused = false;
+ if (!m_mediaDuration) {
+ float newDuration = duration();
+ if (!isinf(newDuration))
+ m_mediaDuration = newDuration;
+ }
} else
m_paused = true;
@@ -595,10 +733,6 @@ void MediaPlayerPrivate::updateStates()
}
m_networkState = MediaPlayer::Loaded;
-
- g_object_get(m_playBin, "source", &m_source, NULL);
- if (!m_source)
- LOG_VERBOSE(Media, "m_source is 0");
break;
case GST_STATE_CHANGE_ASYNC:
LOG_VERBOSE(Media, "Async: State: %s, pending: %s",
@@ -647,6 +781,105 @@ void MediaPlayerPrivate::updateStates()
}
}
+void MediaPlayerPrivate::mediaLocationChanged(GstMessage* message)
+{
+ if (m_mediaLocations)
+ gst_structure_free(m_mediaLocations);
+
+ if (message->structure) {
+ // This structure can contain:
+ // - both a new-location string and embedded locations structure
+ // - or only a new-location string.
+ m_mediaLocations = gst_structure_copy(message->structure);
+ const GValue* locations = gst_structure_get_value(m_mediaLocations, "locations");
+
+ if (locations)
+ m_mediaLocationCurrentIndex = gst_value_list_get_size(locations) -1;
+
+ loadNextLocation();
+ }
+}
+
+bool MediaPlayerPrivate::loadNextLocation()
+{
+ if (!m_mediaLocations)
+ return false;
+
+ const GValue* locations = gst_structure_get_value(m_mediaLocations, "locations");
+ const gchar* newLocation = 0;
+
+ if (!locations) {
+ // Fallback on new-location string.
+ newLocation = gst_structure_get_string(m_mediaLocations, "new-location");
+ if (!newLocation)
+ return false;
+ }
+
+ if (!newLocation) {
+ if (m_mediaLocationCurrentIndex < 0) {
+ m_mediaLocations = 0;
+ return false;
+ }
+
+ const GValue* location = gst_value_list_get_value(locations,
+ m_mediaLocationCurrentIndex);
+ const GstStructure* structure = gst_value_get_structure(location);
+
+ if (!structure) {
+ m_mediaLocationCurrentIndex--;
+ return false;
+ }
+
+ newLocation = gst_structure_get_string(structure, "new-location");
+ }
+
+ if (newLocation) {
+ // Found a candidate. new-location is not always an absolute url
+ // though. We need to take the base of the current url and
+ // append the value of new-location to it.
+
+ gchar* currentLocation = 0;
+ g_object_get(m_playBin, "uri", &currentLocation, NULL);
+
+ KURL currentUrl(KURL(), currentLocation);
+ g_free(currentLocation);
+
+ KURL newUrl;
+
+ if (gst_uri_is_valid(newLocation))
+ newUrl = KURL(KURL(), newLocation);
+ else
+ newUrl = KURL(KURL(), currentUrl.baseAsString() + newLocation);
+
+ RefPtr<SecurityOrigin> securityOrigin = SecurityOrigin::create(currentUrl);
+ if (securityOrigin->canRequest(newUrl)) {
+ LOG_VERBOSE(Media, "New media url: %s", newUrl.string().utf8().data());
+
+ // Reset player states.
+ m_networkState = MediaPlayer::Loading;
+ m_player->networkStateChanged();
+ m_readyState = MediaPlayer::HaveNothing;
+ m_player->readyStateChanged();
+
+ // Reset pipeline state.
+ m_resetPipeline = true;
+ gst_element_set_state(m_playBin, GST_STATE_READY);
+
+ GstState state;
+ gst_element_get_state(m_playBin, &state, 0, 0);
+ if (state <= GST_STATE_READY) {
+ // Set the new uri and start playing.
+ g_object_set(m_playBin, "uri", newUrl.string().utf8().data(), NULL);
+ gst_element_set_state(m_playBin, GST_STATE_PLAYING);
+ return true;
+ }
+ }
+ }
+ m_mediaLocationCurrentIndex--;
+ return false;
+
+}
+
void MediaPlayerPrivate::loadStateChanged()
{
updateStates();
@@ -663,14 +896,30 @@ void MediaPlayerPrivate::timeChanged()
m_player->timeChanged();
}
-void MediaPlayerPrivate::volumeChanged()
+void MediaPlayerPrivate::didEnd()
{
- m_player->volumeChanged();
+ // EOS was reached but in case of reverse playback the position is
+ // not always 0. So to not confuse the HTMLMediaElement we
+ // synchronize position and duration values.
+ float now = currentTime();
+ if (now > 0)
+ m_mediaDuration = now;
+ gst_element_set_state(m_playBin, GST_STATE_PAUSED);
+
+ timeChanged();
}
-void MediaPlayerPrivate::didEnd()
+void MediaPlayerPrivate::durationChanged()
{
- timeChanged();
+ // Reset cached media duration
+ m_mediaDuration = 0;
+
+ // And re-cache it if possible.
+ float newDuration = duration();
+ if (!isinf(newDuration))
+ m_mediaDuration = newDuration;
+
+ m_player->durationChanged();
}
void MediaPlayerPrivate::loadingFailed(MediaPlayer::NetworkState error)
@@ -711,7 +960,7 @@ void MediaPlayerPrivate::paint(GraphicsContext* context, const IntRect& rect)
return;
int width = 0, height = 0;
- GstCaps *caps = gst_buffer_get_caps(m_buffer);
+ GstCaps* caps = gst_buffer_get_caps(m_buffer);
GstVideoFormat format;
if (!gst_video_format_parse_caps(caps, &format, &width, &height)) {
@@ -751,7 +1000,7 @@ void MediaPlayerPrivate::paint(GraphicsContext* context, const IntRect& rect)
static HashSet<String> mimeTypeCache()
{
- do_gst_init();
+ doGstInit();
static HashSet<String> cache;
static bool typeListInitialized = false;
@@ -814,11 +1063,11 @@ static HashSet<String> mimeTypeCache()
if (G_VALUE_TYPE(layer) == GST_TYPE_INT_RANGE) {
gint minLayer = gst_value_get_int_range_min(layer);
gint maxLayer = gst_value_get_int_range_max(layer);
- if (minLayer <= 1 <= maxLayer)
+ if (minLayer <= 1 && 1 <= maxLayer)
cache.add(String("audio/mp1"));
- if (minLayer <= 2 <= maxLayer)
+ if (minLayer <= 2 && 2 <= maxLayer)
cache.add(String("audio/mp2"));
- if (minLayer <= 3 <= maxLayer)
+ if (minLayer <= 3 && 3 <= maxLayer)
cache.add(String("audio/mp3"));
}
}
@@ -887,13 +1136,29 @@ void MediaPlayerPrivate::createGSTPlayBin(String url)
g_signal_connect(bus, "message", G_CALLBACK(mediaPlayerPrivateMessageCallback), this);
gst_object_unref(bus);
- g_object_set(G_OBJECT(m_playBin), "uri", url.utf8().data(),
- "volume", static_cast<double>(m_player->volume()), NULL);
+ g_object_set(m_playBin, "uri", url.utf8().data(), NULL);
+
+ g_signal_connect(m_playBin, "notify::volume", G_CALLBACK(mediaPlayerPrivateVolumeChangedCallback), this);
+ g_signal_connect(m_playBin, "notify::source", G_CALLBACK(mediaPlayerPrivateSourceChangedCallback), this);
m_videoSink = webkit_video_sink_new();
g_object_ref_sink(m_videoSink);
- g_object_set(m_playBin, "video-sink", m_videoSink, NULL);
+
+ WTFLogChannel* channel = getChannelFromName("Media");
+ if (channel->state == WTFLogChannelOn) {
+ m_fpsSink = gst_element_factory_make("fpsdisplaysink", "sink");
+ if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_fpsSink), "video-sink")) {
+ g_object_set(m_fpsSink, "video-sink", m_videoSink, NULL);
+ g_object_ref_sink(m_fpsSink);
+ g_object_set(m_playBin, "video-sink", m_fpsSink, NULL);
+ } else {
+ m_fpsSink = 0;
+ g_object_set(m_playBin, "video-sink", m_videoSink, NULL);
+ LOG(Media, "Can't display FPS statistics, you need gst-plugins-bad >= 0.10.18");
+ }
+ } else
+ g_object_set(m_playBin, "video-sink", m_videoSink, NULL);
g_signal_connect(m_videoSink, "repaint-requested", G_CALLBACK(mediaPlayerPrivateRepaintCallback), this);
}
diff --git a/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h b/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h
index 6ab8edb..ec55b29 100644
--- a/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h
+++ b/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h
@@ -39,16 +39,19 @@ typedef struct _GstBus GstBus;
namespace WebCore {
- class GraphicsContext;
- class IntSize;
- class IntRect;
- class String;
+class GraphicsContext;
+class IntSize;
+class IntRect;
+class String;
- gboolean mediaPlayerPrivateMessageCallback(GstBus* bus, GstMessage* message, gpointer data);
+gboolean mediaPlayerPrivateMessageCallback(GstBus* bus, GstMessage* message, gpointer data);
+void mediaPlayerPrivateVolumeChangedCallback(GObject* element, GParamSpec* pspec, gpointer data);
+void mediaPlayerPrivateSourceChangedCallback(GObject* element, GParamSpec* pspec, gpointer data);
- class MediaPlayerPrivate : public MediaPlayerPrivateInterface {
+class MediaPlayerPrivate : public MediaPlayerPrivateInterface {
friend gboolean mediaPlayerPrivateMessageCallback(GstBus* bus, GstMessage* message, gpointer data);
- friend void mediaPlayerPrivateRepaintCallback(WebKitVideoSink*, GstBuffer *buffer, MediaPlayerPrivate* playerPrivate);
+ friend void mediaPlayerPrivateRepaintCallback(WebKitVideoSink*, GstBuffer* buffer, MediaPlayerPrivate* playerPrivate);
+ friend void mediaPlayerPrivateSourceChangedCallback(GObject* element, GParamSpec* pspec, gpointer data);
public:
static void registerMediaEngine(MediaEngineRegistrar);
@@ -60,6 +63,7 @@ namespace WebCore {
void load(const String &url);
void cancelLoad();
+ bool loadNextLocation();
void play();
void pause();
@@ -70,12 +74,10 @@ namespace WebCore {
float duration() const;
float currentTime() const;
void seek(float);
- void setEndTime(float);
void setRate(float);
void setVolume(float);
-
- int dataRate() const;
+ void volumeChanged();
MediaPlayer::NetworkState networkState() const;
MediaPlayer::ReadyState readyState() const;
@@ -83,17 +85,17 @@ namespace WebCore {
PassRefPtr<TimeRanges> buffered() const;
float maxTimeSeekable() const;
unsigned bytesLoaded() const;
- bool totalBytesKnown() const;
unsigned totalBytes() const;
void setVisible(bool);
void setSize(const IntSize&);
+ void mediaLocationChanged(GstMessage*);
void loadStateChanged();
void sizeChanged();
void timeChanged();
- void volumeChanged();
void didEnd();
+ void durationChanged();
void loadingFailed(MediaPlayer::NetworkState);
void repaint();
@@ -103,6 +105,8 @@ namespace WebCore {
bool supportsFullscreen() const;
+ bool pipelineReset() const { return m_resetPipeline; }
+
private:
MediaPlayerPrivate(MediaPlayer*);
static MediaPlayerPrivateInterface* create(MediaPlayer* player);
@@ -118,11 +122,13 @@ namespace WebCore {
void startEndPointTimerIfNeeded();
void createGSTPlayBin(String url);
+ bool changePipelineState(GstState state);
private:
MediaPlayer* m_player;
GstElement* m_playBin;
GstElement* m_videoSink;
+ GstElement* m_fpsSink;
GstElement* m_source;
GstClockTime m_seekTime;
bool m_changingRate;
@@ -134,10 +140,15 @@ namespace WebCore {
mutable bool m_isStreaming;
IntSize m_size;
GstBuffer* m_buffer;
-
+ GstStructure* m_mediaLocations;
+ gint m_mediaLocationCurrentIndex;
+ bool m_resetPipeline;
bool m_paused;
bool m_seeking;
+ float m_playbackRate;
bool m_errorOccured;
+ guint m_volumeIdleId;
+ gfloat m_mediaDuration;
};
}
diff --git a/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp b/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp
index 4728d56..6038c6a 100644
--- a/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp
+++ b/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp
@@ -204,12 +204,16 @@ void GraphicsContext::clip(const FloatRect& rect)
m_data->m_view->ConstrainClippingRegion(&region);
}
-void GraphicsContext::drawFocusRing(const Color& color)
+void GraphicsContext::drawFocusRing(const Vector<Path>& paths, int width, int offset, const Color& color)
+{
+ // FIXME: implement
+}
+
+void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int /* width */, int /* offset */, const Color& color)
{
if (paintingDisabled())
return;
- const Vector<IntRect>& rects = focusRingRects();
unsigned rectCount = rects.size();
// FIXME: maybe we should implement this with BShape?
diff --git a/WebCore/platform/graphics/mac/Canvas3DLayer.mm b/WebCore/platform/graphics/mac/Canvas3DLayer.mm
index 94819d4..59a7384 100644
--- a/WebCore/platform/graphics/mac/Canvas3DLayer.mm
+++ b/WebCore/platform/graphics/mac/Canvas3DLayer.mm
@@ -33,8 +33,9 @@
#import "GraphicsLayer.h"
#import <QuartzCore/QuartzCore.h>
#import <OpenGL/OpenGL.h>
+#import <wtf/FastMalloc.h>
#import <wtf/RetainPtr.h>
-#include <wtf/FastMalloc.h>
+#import <wtf/UnusedParam.h>
using namespace WebCore;
@@ -140,6 +141,13 @@ static void freeData(void *, const void *data, size_t /* size */)
return image;
}
+- (void)display
+{
+ [super display];
+ if (m_layerOwner)
+ m_layerOwner->didDisplay(self);
+}
+
@end
@implementation Canvas3DLayer(WebLayerAdditions)
diff --git a/WebCore/platform/graphics/mac/ComplexTextController.cpp b/WebCore/platform/graphics/mac/ComplexTextController.cpp
index 265b2c3..7d12b61 100644
--- a/WebCore/platform/graphics/mac/ComplexTextController.cpp
+++ b/WebCore/platform/graphics/mac/ComplexTextController.cpp
@@ -29,6 +29,13 @@
#include "Font.h"
#include "TextBreakIterator.h"
+#include <wtf/StdLibExtras.h>
+
+#if defined(BUILDING_ON_LEOPARD)
+// Undefined when compiling agains the 10.5 SDK.
+#define kCTVersionNumber10_6 0x00030000
+#endif
+
using namespace std;
namespace WebCore {
@@ -106,7 +113,7 @@ int ComplexTextController::offsetForPosition(int h, bool includePartialGlyphs)
else
hitGlyphEnd = max<CFIndex>(hitGlyphStart, j > 0 ? complexTextRun.indexAt(j - 1) : complexTextRun.stringLength());
- // FIXME: Instead of dividing the glyph's advance equially between the characters, this
+ // FIXME: Instead of dividing the glyph's advance equally between the characters, this
// could use the glyph's "ligature carets". However, there is no Core Text API to get the
// ligature carets.
CFIndex hitIndex = hitGlyphStart + (hitGlyphEnd - hitGlyphStart) * (m_run.ltr() ? x / adjustedAdvance : 1 - x / adjustedAdvance);
@@ -263,6 +270,62 @@ void ComplexTextController::collectComplexTextRuns()
collectComplexTextRunsForCharacters(&hyphen, 1, m_end - 1, m_font.glyphDataForCharacter(hyphen, false).fontData);
}
+#if USE(CORE_TEXT) && USE(ATSUI)
+static inline bool shouldUseATSUIAPI()
+{
+ enum TypeRenderingAPIToUse { UnInitialized, UseATSUI, UseCoreText };
+ DEFINE_STATIC_LOCAL(TypeRenderingAPIToUse, apiToUse, (UnInitialized));
+
+ if (UNLIKELY(apiToUse == UnInitialized)) {
+ if (&CTGetCoreTextVersion != 0 && CTGetCoreTextVersion() >= kCTVersionNumber10_6)
+ apiToUse = UseCoreText;
+ else
+ apiToUse = UseATSUI;
+ }
+
+ return apiToUse == UseATSUI;
+}
+#endif
+
+CFIndex ComplexTextController::ComplexTextRun::indexAt(size_t i) const
+{
+#if USE(CORE_TEXT) && USE(ATSUI)
+ return shouldUseATSUIAPI() ? m_atsuiIndices[i] : m_coreTextIndices[i];
+#elif USE(ATSUI)
+ return m_atsuiIndices[i];
+#elif USE(CORE_TEXT)
+ return m_coreTextIndices[i];
+#endif
+}
+
+void ComplexTextController::collectComplexTextRunsForCharacters(const UChar* cp, unsigned length, unsigned stringLocation, const SimpleFontData* fontData)
+{
+#if USE(CORE_TEXT) && USE(ATSUI)
+ if (shouldUseATSUIAPI())
+ return collectComplexTextRunsForCharactersATSUI(cp, length, stringLocation, fontData);
+ return collectComplexTextRunsForCharactersCoreText(cp, length, stringLocation, fontData);
+#elif USE(ATSUI)
+ return collectComplexTextRunsForCharactersATSUI(cp, length, stringLocation, fontData);
+#elif USE(CORE_TEXT)
+ return collectComplexTextRunsForCharactersCoreText(cp, length, stringLocation, fontData);
+#endif
+}
+
+ComplexTextController::ComplexTextRun::ComplexTextRun(const SimpleFontData* fontData, const UChar* characters, unsigned stringLocation, size_t stringLength, bool ltr)
+ : m_fontData(fontData)
+ , m_characters(characters)
+ , m_stringLocation(stringLocation)
+ , m_stringLength(stringLength)
+{
+#if USE(CORE_TEXT) && USE(ATSUI)
+ shouldUseATSUIAPI() ? createTextRunFromFontDataATSUI(ltr) : createTextRunFromFontDataCoreText(ltr);
+#elif USE(ATSUI)
+ createTextRunFromFontDataATSUI(ltr);
+#elif USE(CORE_TEXT)
+ createTextRunFromFontDataCoreText(ltr);
+#endif
+}
+
void ComplexTextController::advance(unsigned offset, GlyphBuffer* glyphBuffer)
{
if (static_cast<int>(offset) > m_end)
diff --git a/WebCore/platform/graphics/mac/ComplexTextController.h b/WebCore/platform/graphics/mac/ComplexTextController.h
index 7a915e2..3fec18a 100644
--- a/WebCore/platform/graphics/mac/ComplexTextController.h
+++ b/WebCore/platform/graphics/mac/ComplexTextController.h
@@ -39,6 +39,11 @@ class Font;
class SimpleFontData;
class TextRun;
+// ComplexTextController is responsible for rendering and measuring glyphs for
+// complex scripts on OS X.
+// The underlying API can be selected at compile time based on USE(ATSUI) and
+// USE(CORE_TEXT). If both are defined then the Core Text APIs are used for
+// OS Versions >= 10.6, ATSUI is used otherwise.
class ComplexTextController {
public:
ComplexTextController(const Font*, const TextRun&, bool mayUseNaturalWritingDirection = false, HashSet<const SimpleFontData*>* fallbackFonts = 0);
@@ -65,7 +70,8 @@ private:
{
return adoptRef(new ComplexTextRun(ctRun, fontData, characters, stringLocation, stringLength));
}
-#elif USE(ATSUI)
+#endif
+#if USE(ATSUI)
static PassRefPtr<ComplexTextRun> create(ATSUTextLayout atsuTextLayout, const SimpleFontData* fontData, const UChar* characters, unsigned stringLocation, size_t stringLength, bool ltr, bool directionalOverride)
{
return adoptRef(new ComplexTextRun(atsuTextLayout, fontData, characters, stringLocation, stringLength, ltr, directionalOverride));
@@ -81,15 +87,18 @@ private:
const UChar* characters() const { return m_characters; }
unsigned stringLocation() const { return m_stringLocation; }
size_t stringLength() const { return m_stringLength; }
- CFIndex indexAt(size_t i) const { return m_indices[i]; }
+ ALWAYS_INLINE CFIndex indexAt(size_t i) const;
const CGGlyph* glyphs() const { return m_glyphs; }
const CGSize* advances() const { return m_advances; }
private:
#if USE(CORE_TEXT)
ComplexTextRun(CTRunRef, const SimpleFontData*, const UChar* characters, unsigned stringLocation, size_t stringLength);
-#elif USE(ATSUI)
+ void createTextRunFromFontDataCoreText(bool ltr);
+#endif
+#if USE(ATSUI)
ComplexTextRun(ATSUTextLayout, const SimpleFontData*, const UChar* characters, unsigned stringLocation, size_t stringLength, bool ltr, bool directionalOverride);
+ void createTextRunFromFontDataATSUI(bool ltr);
#endif
ComplexTextRun(const SimpleFontData*, const UChar* characters, unsigned stringLocation, size_t stringLength, bool ltr);
@@ -101,7 +110,7 @@ private:
#endif
#if USE(CORE_TEXT)
- RetainPtr<CTRunRef> m_CTRun;
+ RetainPtr<CTRunRef> m_coreTextRun;
#endif
unsigned m_glyphCount;
const SimpleFontData* m_fontData;
@@ -109,10 +118,11 @@ private:
unsigned m_stringLocation;
size_t m_stringLength;
#if USE(CORE_TEXT)
- RetainPtr<CFMutableDataRef> m_indicesData;
- const CFIndex* m_indices;
-#elif USE(ATSUI)
- Vector<CFIndex, 64> m_indices;
+ RetainPtr<CFMutableDataRef> m_coreTextIndicesData;
+ const CFIndex* m_coreTextIndices;
+#endif
+#if USE(ATSUI)
+ Vector<CFIndex, 64> m_atsuiIndices;
#endif
Vector<CGGlyph, 64> m_glyphsVector;
const CGGlyph* m_glyphs;
@@ -125,7 +135,12 @@ private:
};
void collectComplexTextRuns();
+
+ // collectComplexTextRunsForCharacters() is a stub function that calls through to the ATSUI or Core Text variants based
+ // on the API in use.
void collectComplexTextRunsForCharacters(const UChar*, unsigned length, unsigned stringLocation, const SimpleFontData*);
+ void collectComplexTextRunsForCharactersATSUI(const UChar*, unsigned length, unsigned stringLocation, const SimpleFontData*);
+ void collectComplexTextRunsForCharactersCoreText(const UChar*, unsigned length, unsigned stringLocation, const SimpleFontData*);
void adjustGlyphsAndAdvances();
const Font& m_font;
diff --git a/WebCore/platform/graphics/mac/ComplexTextControllerATSUI.cpp b/WebCore/platform/graphics/mac/ComplexTextControllerATSUI.cpp
index 78c588f..48aa174 100644
--- a/WebCore/platform/graphics/mac/ComplexTextControllerATSUI.cpp
+++ b/WebCore/platform/graphics/mac/ComplexTextControllerATSUI.cpp
@@ -45,7 +45,7 @@ OSStatus ComplexTextController::ComplexTextRun::overrideLayoutOperation(ATSULayo
ComplexTextRun* complexTextRun = reinterpret_cast<ComplexTextRun*>(refCon);
OSStatus status;
ItemCount count;
- ATSLayoutRecord *layoutRecords;
+ ATSLayoutRecord* layoutRecords;
status = ATSUDirectGetLayoutDataArrayPtrFromLineRef(atsuLineRef, kATSUDirectDataLayoutRecordATSLayoutRecordCurrent, true, reinterpret_cast<void**>(&layoutRecords), &count);
if (status != noErr) {
@@ -66,7 +66,7 @@ OSStatus ComplexTextController::ComplexTextRun::overrideLayoutOperation(ATSULayo
complexTextRun->m_glyphCount = count;
complexTextRun->m_glyphsVector.reserveCapacity(count);
complexTextRun->m_advancesVector.reserveCapacity(count);
- complexTextRun->m_indices.reserveCapacity(count);
+ complexTextRun->m_atsuiIndices.reserveCapacity(count);
bool atBeginning = true;
CGFloat lastX = 0;
@@ -77,7 +77,7 @@ OSStatus ComplexTextController::ComplexTextRun::overrideLayoutOperation(ATSULayo
continue;
}
complexTextRun->m_glyphsVector.uncheckedAppend(layoutRecords[j].glyphID);
- complexTextRun->m_indices.uncheckedAppend(layoutRecords[j].originalOffset / 2 + indexOffset);
+ complexTextRun->m_atsuiIndices.uncheckedAppend(layoutRecords[j].originalOffset / 2 + indexOffset);
CGFloat x = FixedToFloat(layoutRecords[j].realPos);
if (!atBeginning)
complexTextRun->m_advancesVector.uncheckedAppend(CGSizeMake(x - lastX, 0));
@@ -219,33 +219,29 @@ ComplexTextController::ComplexTextRun::ComplexTextRun(ATSUTextLayout atsuTextLay
status = ATSUDisposeTextLayout(atsuTextLayout);
}
-ComplexTextController::ComplexTextRun::ComplexTextRun(const SimpleFontData* fontData, const UChar* characters, unsigned stringLocation, size_t stringLength, bool ltr)
- : m_fontData(fontData)
- , m_characters(characters)
- , m_stringLocation(stringLocation)
- , m_stringLength(stringLength)
+void ComplexTextController::ComplexTextRun::createTextRunFromFontDataATSUI(bool ltr)
{
- m_indices.reserveCapacity(stringLength);
+ m_atsuiIndices.reserveCapacity(m_stringLength);
unsigned r = 0;
- while (r < stringLength) {
- m_indices.uncheckedAppend(r);
- if (U_IS_SURROGATE(characters[r])) {
- ASSERT(r + 1 < stringLength);
- ASSERT(U_IS_SURROGATE_LEAD(characters[r]));
- ASSERT(U_IS_TRAIL(characters[r + 1]));
+ while (r < m_stringLength) {
+ m_atsuiIndices.uncheckedAppend(r);
+ if (U_IS_SURROGATE(m_characters[r])) {
+ ASSERT(r + 1 < m_stringLength);
+ ASSERT(U_IS_SURROGATE_LEAD(m_characters[r]));
+ ASSERT(U_IS_TRAIL(m_characters[r + 1]));
r += 2;
} else
r++;
}
- m_glyphCount = m_indices.size();
+ m_glyphCount = m_atsuiIndices.size();
if (!ltr) {
for (unsigned r = 0, end = m_glyphCount - 1; r < m_glyphCount / 2; ++r, --end)
- std::swap(m_indices[r], m_indices[end]);
+ std::swap(m_atsuiIndices[r], m_atsuiIndices[end]);
}
m_glyphsVector.fill(0, m_glyphCount);
m_glyphs = m_glyphsVector.data();
- m_advancesVector.fill(CGSizeMake(fontData->widthForGlyph(0), 0), m_glyphCount);
+ m_advancesVector.fill(CGSizeMake(m_fontData->widthForGlyph(0), 0), m_glyphCount);
m_advances = m_advancesVector.data();
}
@@ -261,33 +257,37 @@ static bool fontHasMirroringInfo(ATSUFontID fontID)
return false;
}
-static void disableLigatures(const SimpleFontData* fontData, TextRenderingMode textMode)
+static void disableLigatures(const SimpleFontData* fontData, ATSUStyle atsuStyle, TypesettingFeatures typesettingFeatures)
{
// 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 (textMode == OptimizeLegibility || textMode == GeometricPrecision || fontData->platformData().allowsLigatures())
+ if ((typesettingFeatures & Ligatures) || fontData->platformData().allowsLigatures())
return;
ATSUFontFeatureType featureTypes[] = { kLigaturesType };
ATSUFontFeatureSelector featureSelectors[] = { kCommonLigaturesOffSelector };
- OSStatus status = ATSUSetFontFeatures(fontData->m_ATSUStyle, 1, featureTypes, featureSelectors);
+ OSStatus status = ATSUSetFontFeatures(atsuStyle, 1, featureTypes, featureSelectors);
if (status != noErr)
LOG_ERROR("ATSUSetFontFeatures failed (%d) -- ligatures remain enabled", static_cast<int>(status));
}
-static void initializeATSUStyle(const SimpleFontData* fontData, TextRenderingMode textMode)
+static ATSUStyle initializeATSUStyle(const SimpleFontData* fontData, TypesettingFeatures typesettingFeatures)
{
- if (fontData->m_ATSUStyleInitialized)
- return;
+ unsigned key = typesettingFeatures + 1;
+ pair<HashMap<unsigned, ATSUStyle>::iterator, bool> addResult = fontData->m_ATSUStyleMap.add(key, 0);
+ ATSUStyle& atsuStyle = addResult.first->second;
+ if (!addResult.second)
+ return atsuStyle;
ATSUFontID fontID = fontData->platformData().m_atsuFontID;
if (!fontID) {
LOG_ERROR("unable to get ATSUFontID for %p", fontData->platformData().font());
- return;
+ fontData->m_ATSUStyleMap.remove(addResult.first);
+ return 0;
}
- OSStatus status = ATSUCreateStyle(&fontData->m_ATSUStyle);
+ OSStatus status = ATSUCreateStyle(&atsuStyle);
if (status != noErr)
LOG_ERROR("ATSUCreateStyle failed (%d)", static_cast<int>(status));
@@ -299,19 +299,18 @@ static void initializeATSUStyle(const SimpleFontData* fontData, TextRenderingMod
ATSUAttributeTag styleTags[4] = { kATSUSizeTag, kATSUFontTag, kATSUFontMatrixTag, kATSUKerningInhibitFactorTag };
ATSUAttributeValuePtr styleValues[4] = { &fontSize, &fontID, &verticalFlip, &kerningInhibitFactor };
- bool allowKerning = textMode == OptimizeLegibility || textMode == GeometricPrecision;
- status = ATSUSetAttributes(fontData->m_ATSUStyle, allowKerning ? 3 : 4, styleTags, styleSizes, styleValues);
+ bool allowKerning = typesettingFeatures & Kerning;
+ status = ATSUSetAttributes(atsuStyle, allowKerning ? 3 : 4, styleTags, styleSizes, styleValues);
if (status != noErr)
LOG_ERROR("ATSUSetAttributes failed (%d)", static_cast<int>(status));
fontData->m_ATSUMirrors = fontHasMirroringInfo(fontID);
- disableLigatures(fontData, textMode);
-
- fontData->m_ATSUStyleInitialized = true;
+ disableLigatures(fontData, atsuStyle, typesettingFeatures);
+ return atsuStyle;
}
-void ComplexTextController::collectComplexTextRunsForCharacters(const UChar* cp, unsigned length, unsigned stringLocation, const SimpleFontData* fontData)
+void ComplexTextController::collectComplexTextRunsForCharactersATSUI(const UChar* cp, unsigned length, unsigned stringLocation, const SimpleFontData* fontData)
{
if (!fontData) {
// Create a run of missing glyphs from the primary font.
@@ -322,13 +321,13 @@ void ComplexTextController::collectComplexTextRunsForCharacters(const UChar* cp,
if (m_fallbackFonts && fontData != m_font.primaryFont())
m_fallbackFonts->add(fontData);
- initializeATSUStyle(fontData, m_font.fontDescription().textRenderingMode());
+ ATSUStyle atsuStyle = initializeATSUStyle(fontData, m_font.typesettingFeatures());
OSStatus status;
ATSUTextLayout atsuTextLayout;
UniCharCount runLength = length;
- status = ATSUCreateTextLayoutWithTextPtr(cp, 0, length, length, 1, &runLength, &fontData->m_ATSUStyle, &atsuTextLayout);
+ status = ATSUCreateTextLayoutWithTextPtr(cp, 0, length, length, 1, &runLength, &atsuStyle, &atsuTextLayout);
if (status != noErr) {
LOG_ERROR("ATSUCreateTextLayoutWithTextPtr failed with error %d", static_cast<int>(status));
return;
diff --git a/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.cpp b/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.cpp
index c9daf84..dd5e96a 100644
--- a/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.cpp
+++ b/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.cpp
@@ -29,35 +29,44 @@
#include "Font.h"
+#if defined(BUILDING_ON_LEOPARD)
+// The following symbols are SPI in 10.5.
+extern "C" {
+void CTRunGetAdvances(CTRunRef run, CFRange range, CGSize buffer[]);
+const CGSize* CTRunGetAdvancesPtr(CTRunRef run);
+extern const CFStringRef kCTTypesetterOptionForcedEmbeddingLevel;
+}
+#endif
+
namespace WebCore {
ComplexTextController::ComplexTextRun::ComplexTextRun(CTRunRef ctRun, const SimpleFontData* fontData, const UChar* characters, unsigned stringLocation, size_t stringLength)
- : m_CTRun(ctRun)
+ : m_coreTextRun(ctRun)
, m_fontData(fontData)
, m_characters(characters)
, m_stringLocation(stringLocation)
, m_stringLength(stringLength)
{
- m_glyphCount = CTRunGetGlyphCount(m_CTRun.get());
- m_indices = CTRunGetStringIndicesPtr(m_CTRun.get());
- if (!m_indices) {
- m_indicesData.adoptCF(CFDataCreateMutable(kCFAllocatorDefault, m_glyphCount * sizeof(CFIndex)));
- CFDataIncreaseLength(m_indicesData.get(), m_glyphCount * sizeof(CFIndex));
- m_indices = reinterpret_cast<const CFIndex*>(CFDataGetMutableBytePtr(m_indicesData.get()));
- CTRunGetStringIndices(m_CTRun.get(), CFRangeMake(0, 0), const_cast<CFIndex*>(m_indices));
+ m_glyphCount = CTRunGetGlyphCount(m_coreTextRun.get());
+ m_coreTextIndices = CTRunGetStringIndicesPtr(m_coreTextRun.get());
+ if (!m_coreTextIndices) {
+ m_coreTextIndicesData.adoptCF(CFDataCreateMutable(kCFAllocatorDefault, m_glyphCount * sizeof(CFIndex)));
+ CFDataIncreaseLength(m_coreTextIndicesData.get(), m_glyphCount * sizeof(CFIndex));
+ m_coreTextIndices = reinterpret_cast<const CFIndex*>(CFDataGetMutableBytePtr(m_coreTextIndicesData.get()));
+ CTRunGetStringIndices(m_coreTextRun.get(), CFRangeMake(0, 0), const_cast<CFIndex*>(m_coreTextIndices));
}
- m_glyphs = CTRunGetGlyphsPtr(m_CTRun.get());
+ m_glyphs = CTRunGetGlyphsPtr(m_coreTextRun.get());
if (!m_glyphs) {
m_glyphsVector.grow(m_glyphCount);
- CTRunGetGlyphs(m_CTRun.get(), CFRangeMake(0, 0), m_glyphsVector.data());
+ CTRunGetGlyphs(m_coreTextRun.get(), CFRangeMake(0, 0), m_glyphsVector.data());
m_glyphs = m_glyphsVector.data();
}
- m_advances = CTRunGetAdvancesPtr(m_CTRun.get());
+ m_advances = CTRunGetAdvancesPtr(m_coreTextRun.get());
if (!m_advances) {
m_advancesVector.grow(m_glyphCount);
- CTRunGetAdvances(m_CTRun.get(), CFRangeMake(0, 0), m_advancesVector.data());
+ CTRunGetAdvances(m_coreTextRun.get(), CFRangeMake(0, 0), m_advancesVector.data());
m_advances = m_advancesVector.data();
}
@@ -65,20 +74,16 @@ ComplexTextController::ComplexTextRun::ComplexTextRun(CTRunRef ctRun, const Simp
// Missing glyphs run constructor. Core Text will not generate a run of missing glyphs, instead falling back on
// glyphs from LastResort. We want to use the primary font's missing glyph in order to match the fast text code path.
-ComplexTextController::ComplexTextRun::ComplexTextRun(const SimpleFontData* fontData, const UChar* characters, unsigned stringLocation, size_t stringLength, bool ltr)
- : m_fontData(fontData)
- , m_characters(characters)
- , m_stringLocation(stringLocation)
- , m_stringLength(stringLength)
+void ComplexTextController::ComplexTextRun::createTextRunFromFontDataCoreText(bool ltr)
{
Vector<CFIndex, 16> indices;
unsigned r = 0;
- while (r < stringLength) {
+ while (r < m_stringLength) {
indices.append(r);
- if (U_IS_SURROGATE(characters[r])) {
- ASSERT(r + 1 < stringLength);
- ASSERT(U_IS_SURROGATE_LEAD(characters[r]));
- ASSERT(U_IS_TRAIL(characters[r + 1]));
+ if (U_IS_SURROGATE(m_characters[r])) {
+ ASSERT(r + 1 < m_stringLength);
+ ASSERT(U_IS_SURROGATE_LEAD(m_characters[r]));
+ ASSERT(U_IS_TRAIL(m_characters[r + 1]));
r += 2;
} else
r++;
@@ -88,9 +93,9 @@ ComplexTextController::ComplexTextRun::ComplexTextRun(const SimpleFontData* font
for (unsigned r = 0, end = m_glyphCount - 1; r < m_glyphCount / 2; ++r, --end)
std::swap(indices[r], indices[end]);
}
- m_indicesData.adoptCF(CFDataCreateMutable(kCFAllocatorDefault, m_glyphCount * sizeof(CFIndex)));
- CFDataAppendBytes(m_indicesData.get(), reinterpret_cast<const UInt8*>(indices.data()), m_glyphCount * sizeof(CFIndex));
- m_indices = reinterpret_cast<const CFIndex*>(CFDataGetBytePtr(m_indicesData.get()));
+ m_coreTextIndicesData.adoptCF(CFDataCreateMutable(kCFAllocatorDefault, m_glyphCount * sizeof(CFIndex)));
+ CFDataAppendBytes(m_coreTextIndicesData.get(), reinterpret_cast<const UInt8*>(indices.data()), m_glyphCount * sizeof(CFIndex));
+ m_coreTextIndices = reinterpret_cast<const CFIndex*>(CFDataGetBytePtr(m_coreTextIndicesData.get()));
// Synthesize a run of missing glyphs.
m_glyphsVector.fill(0, m_glyphCount);
@@ -99,7 +104,7 @@ ComplexTextController::ComplexTextRun::ComplexTextRun(const SimpleFontData* font
m_advances = m_advancesVector.data();
}
-void ComplexTextController::collectComplexTextRunsForCharacters(const UChar* cp, unsigned length, unsigned stringLocation, const SimpleFontData* fontData)
+void ComplexTextController::collectComplexTextRunsForCharactersCoreText(const UChar* cp, unsigned length, unsigned stringLocation, const SimpleFontData* fontData)
{
if (!fontData) {
// Create a run of missing glyphs from the primary font.
@@ -112,7 +117,7 @@ void ComplexTextController::collectComplexTextRunsForCharacters(const UChar* cp,
RetainPtr<CFStringRef> string(AdoptCF, CFStringCreateWithCharactersNoCopy(NULL, cp, length, kCFAllocatorNull));
- RetainPtr<CFAttributedStringRef> attributedString(AdoptCF, CFAttributedStringCreate(NULL, string.get(), fontData->getCFStringAttributes(m_font.fontDescription().textRenderingMode())));
+ RetainPtr<CFAttributedStringRef> attributedString(AdoptCF, CFAttributedStringCreate(NULL, string.get(), fontData->getCFStringAttributes(m_font.typesettingFeatures())));
RetainPtr<CTTypesetterRef> typesetter;
diff --git a/WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp b/WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp
index 41f63a9..5e5e1f4 100644
--- a/WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp
+++ b/WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp
@@ -29,28 +29,24 @@
#include "GraphicsContext3D.h"
-#include "CachedImage.h"
+#include "CanvasObject.h"
+#include "CString.h"
+#include "ImageBuffer.h"
+#include "NotImplemented.h"
#include "WebGLActiveInfo.h"
#include "WebGLArray.h"
#include "WebGLBuffer.h"
#include "WebGLFramebuffer.h"
#include "WebGLFloatArray.h"
#include "WebGLIntArray.h"
-#include "CanvasObject.h"
#include "WebGLProgram.h"
#include "WebGLRenderbuffer.h"
#include "WebGLShader.h"
#include "WebGLTexture.h"
#include "WebGLUnsignedByteArray.h"
-#include "CString.h"
-#include "HTMLCanvasElement.h"
-#include "HTMLImageElement.h"
-#include "ImageBuffer.h"
-#include "NotImplemented.h"
-#include "WebKitCSSMatrix.h"
-
#include <CoreGraphics/CGBitmapContext.h>
#include <OpenGL/CGLRenderers.h>
+#include <wtf/UnusedParam.h>
namespace WebCore {
@@ -79,18 +75,29 @@ static void setPixelFormat(Vector<CGLPixelFormatAttribute>& attribs, int colorBi
attribs.append(static_cast<CGLPixelFormatAttribute>(0));
}
-PassOwnPtr<GraphicsContext3D> GraphicsContext3D::create()
+PassOwnPtr<GraphicsContext3D> GraphicsContext3D::create(GraphicsContext3D::Attributes attrs)
{
- OwnPtr<GraphicsContext3D> context(new GraphicsContext3D());
+ OwnPtr<GraphicsContext3D> context(new GraphicsContext3D(attrs));
return context->m_contextObj ? context.release() : 0;
}
-GraphicsContext3D::GraphicsContext3D()
- : m_contextObj(0)
+GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs)
+ : m_attrs(attrs)
+ , m_contextObj(0)
, m_texture(0)
, m_fbo(0)
, m_depthBuffer(0)
{
+ // FIXME: we need to take into account the user's requested
+ // context creation attributes, in particular stencil and
+ // antialias, and determine which could and could not be honored
+ // based on the capabilities of the OpenGL implementation.
+ m_attrs.alpha = true;
+ m_attrs.depth = true;
+ m_attrs.stencil = false;
+ m_attrs.antialias = false;
+ m_attrs.premultipliedAlpha = true;
+
Vector<CGLPixelFormatAttribute> attribs;
CGLPixelFormatObj pixelFormatObj = 0;
GLint numPixelFormats = 0;
@@ -262,7 +269,7 @@ void GraphicsContext3D::bindBuffer(unsigned long target, WebGLBuffer* buffer)
void GraphicsContext3D::bindFramebuffer(unsigned long target, WebGLFramebuffer* buffer)
{
ensureContext(m_contextObj);
- ::glBindFramebufferEXT(target, buffer ? (GLuint) buffer->object() : m_fbo);
+ ::glBindFramebufferEXT(target, (buffer && buffer->object()) ? (GLuint) buffer->object() : m_fbo);
}
void GraphicsContext3D::bindRenderbuffer(unsigned long target, WebGLRenderbuffer* renderbuffer)
@@ -544,6 +551,11 @@ int GraphicsContext3D::getAttribLocation(WebGLProgram* program, const String& na
return ::glGetAttribLocation((GLuint) program->object(), name.utf8().data());
}
+GraphicsContext3D::Attributes GraphicsContext3D::getContextAttributes()
+{
+ return m_attrs;
+}
+
unsigned long GraphicsContext3D::getError()
{
if (m_syntheticErrors.size() > 0) {
@@ -1115,55 +1127,38 @@ long GraphicsContext3D::getVertexAttribOffset(unsigned long index, unsigned long
return reinterpret_cast<long>(pointer);
}
-// Assumes the texture you want to go into is bound
-static void imageToTexture(Image* image, unsigned target, unsigned level)
+// Returned pointer must be freed by fastFree()
+static bool imageToTexture(Image* image, GLubyte*& buffer, size_t& width, size_t& height)
{
if (!image)
- return;
+ return false;
CGImageRef textureImage = image->getCGImageRef();
if (!textureImage)
- return;
+ return false;
- size_t textureWidth = CGImageGetWidth(textureImage);
- size_t textureHeight = CGImageGetHeight(textureImage);
+ width = CGImageGetWidth(textureImage);
+ height = CGImageGetHeight(textureImage);
- GLubyte* textureData = (GLubyte*) fastMalloc(textureWidth * textureHeight * 4);
- if (!textureData)
- return;
+ buffer = (GLubyte*) fastMalloc(width * height * 4);
+ if (!buffer)
+ return false;
- CGContextRef textureContext = CGBitmapContextCreate(textureData, textureWidth, textureHeight, 8, textureWidth * 4,
+ CGContextRef textureContext = CGBitmapContextCreate(buffer, width, height, 8, width * 4,
CGImageGetColorSpace(textureImage), kCGImageAlphaPremultipliedLast);
CGContextSetBlendMode(textureContext, kCGBlendModeCopy);
- CGContextDrawImage(textureContext, CGRectMake(0, 0, (CGFloat)textureWidth, (CGFloat)textureHeight), textureImage);
+ CGContextDrawImage(textureContext, CGRectMake(0, 0, (CGFloat)width, (CGFloat)height), textureImage);
CGContextRelease(textureContext);
-
- ::glTexImage2D(target, level, GL_RGBA, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData);
- fastFree(textureData);
+ return true;
}
-int GraphicsContext3D::texImage2D(unsigned target, unsigned level, unsigned internalformat, unsigned width, unsigned height, unsigned border, unsigned format, unsigned type, WebGLArray* pixels)
+int GraphicsContext3D::texImage2D(unsigned target, unsigned level, unsigned internalformat, unsigned width, unsigned height, unsigned border, unsigned format, unsigned type, void* pixels)
{
// FIXME: Need to do bounds checking on the buffer here.
- ::glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels->baseAddress());
+ ::glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
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, Image* image, bool flipY, bool premultiplyAlpha)
{
// FIXME: need to support flipY and premultiplyAlpha
@@ -1172,85 +1167,43 @@ int GraphicsContext3D::texImage2D(unsigned target, unsigned level, Image* image,
ASSERT(image);
ensureContext(m_contextObj);
- imageToTexture(image, target, level);
+ GLubyte* buffer;
+ size_t width;
+ size_t height;
+ if (!imageToTexture(image, buffer, width, height))
+ return -1;
+
+ ::glTexImage2D(target, level, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
+ fastFree(buffer);
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, WebGLArray* 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, Image* image, bool flipY, bool premultiplyAlpha)
+
+int GraphicsContext3D::texSubImage2D(unsigned target, unsigned level, unsigned xoff, unsigned yoff, unsigned width, unsigned height, unsigned format, unsigned type, void* 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(image);
-
- // FIXME: need to support flipY and premultiplyAlpha
- UNUSED_PARAM(flipY);
- UNUSED_PARAM(premultiplyAlpha);
- return -1;
+ // FIXME: Need to do bounds checking on the buffer here.
+ ::glTexSubImage2D(target, level, xoff, yoff, width, height, format, type, pixels);
+ return 0;
}
-int GraphicsContext3D::texSubImage2D(unsigned target, unsigned level, unsigned xoff, unsigned yoff, unsigned width, unsigned height, HTMLVideoElement* video, bool flipY, bool premultiplyAlpha)
+int GraphicsContext3D::texSubImage2D(unsigned target, unsigned level, unsigned xoff, unsigned yoff, Image* 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(video);
-
- // FIXME: need to support flipY and premultiplyAlpha
+ // FIXME: need to support flipY and premultiplyAlpha
UNUSED_PARAM(flipY);
UNUSED_PARAM(premultiplyAlpha);
- return -1;
+ ASSERT(image);
+
+ ensureContext(m_contextObj);
+ GLubyte* buffer;
+ size_t width;
+ size_t height;
+ if (!imageToTexture(image, buffer, width, height))
+ return -1;
+
+ ::glTexSubImage2D(target, level, xoff, yoff, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
+ fastFree(buffer);
+ return 0;
}
unsigned GraphicsContext3D::createBuffer()
diff --git a/WebCore/platform/graphics/mac/GraphicsContextMac.mm b/WebCore/platform/graphics/mac/GraphicsContextMac.mm
index 6c9b872..5f111f6 100644
--- a/WebCore/platform/graphics/mac/GraphicsContextMac.mm
+++ b/WebCore/platform/graphics/mac/GraphicsContextMac.mm
@@ -26,7 +26,7 @@
#import "config.h"
#import "GraphicsContext.h"
-#import "../cg/GraphicsContextPlatformPrivateCG.h"
+#import "GraphicsContextPlatformPrivateCG.h"
#import <AppKit/AppKit.h>
#import <wtf/StdLibExtras.h>
@@ -43,33 +43,55 @@ namespace WebCore {
// calls in this file are all exception-safe, so we don't block
// exceptions for those.
-void GraphicsContext::drawFocusRing(const Color& color)
+static void drawFocusRingToContext(CGContextRef context, RetainPtr<CGPathRef> focusRingPath, RetainPtr<CGColorRef> colorRef, int radius)
+{
+#ifdef BUILDING_ON_TIGER
+ CGContextBeginTransparencyLayer(context, 0);
+#endif
+ CGContextBeginPath(context);
+ CGContextAddPath(context, focusRingPath.get());
+ wkDrawFocusRing(context, colorRef.get(), radius);
+#ifdef BUILDING_ON_TIGER
+ CGContextEndTransparencyLayer(context);
+#endif
+}
+
+void GraphicsContext::drawFocusRing(const Vector<Path>& paths, int width, int offset, const Color& color)
+{
+ if (paintingDisabled())
+ return;
+
+ int radius = (width - 1) / 2;
+ offset += radius;
+ RetainPtr<CGColorRef> colorRef;
+ if (color.isValid())
+ colorRef.adoptCF(createCGColor(color));
+
+ RetainPtr<CGMutablePathRef> focusRingPath(AdoptCF, CGPathCreateMutable());
+ unsigned pathCount = paths.size();
+ for (unsigned i = 0; i < pathCount; i++)
+ CGPathAddPath(focusRingPath.get(), 0, paths[i].platformPath());
+
+ drawFocusRingToContext(platformContext(), focusRingPath, colorRef, radius);
+}
+
+void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int offset, const Color& color)
{
if (paintingDisabled())
return;
- int radius = (focusRingWidth() - 1) / 2;
- int offset = radius + focusRingOffset();
+ int radius = (width - 1) / 2;
+ offset += radius;
RetainPtr<CGColorRef> colorRef;
if (color.isValid())
colorRef.adoptCF(createCGColor(color));
RetainPtr<CGMutablePathRef> focusRingPath(AdoptCF, CGPathCreateMutable());
- const Vector<IntRect>& rects = focusRingRects();
unsigned rectCount = rects.size();
for (unsigned i = 0; i < rectCount; i++)
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.get());
- wkDrawFocusRing(context, colorRef.get(), radius);
-#ifdef BUILDING_ON_TIGER
- CGContextEndTransparencyLayer(context);
-#endif
+ drawFocusRingToContext(platformContext(), focusRingPath, colorRef, radius);
}
#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 8024091..5362562 100644
--- a/WebCore/platform/graphics/mac/GraphicsLayerCA.h
+++ b/WebCore/platform/graphics/mac/GraphicsLayerCA.h
@@ -30,16 +30,16 @@
#include "GraphicsLayer.h"
#include "StringHash.h"
+#include "WebLayer.h"
+#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
#include <wtf/RetainPtr.h>
@class CABasicAnimation;
@class CAKeyframeAnimation;
-@class CALayer;
@class CAMediaTimingFunction;
@class CAPropertyAnimation;
@class WebAnimationDelegate;
-@class WebLayer;
namespace WebCore {
@@ -64,6 +64,7 @@ public:
virtual void removeFromParent();
virtual void setMaskLayer(GraphicsLayer*);
+ virtual void setReplicatedLayer(GraphicsLayer*);
virtual void setPosition(const FloatPoint&);
virtual void setAnchorPoint(const FloatPoint3D&);
@@ -98,13 +99,13 @@ public:
virtual void suspendAnimations(double time);
virtual void resumeAnimations();
- virtual bool addAnimation(const KeyframeValueList&, const IntSize& boxSize, const Animation*, const String& keyframesName, double beginTime);
+ virtual bool addAnimation(const KeyframeValueList&, const IntSize& boxSize, const Animation*, const String& keyframesName, double timeOffset);
virtual void removeAnimationsForProperty(AnimatedPropertyID);
virtual void removeAnimationsForKeyframes(const String& keyframesName);
- virtual void pauseAnimation(const String& keyframesName);
+ virtual void pauseAnimation(const String& keyframesName, double timeOffset);
virtual void setContentsToImage(Image*);
- virtual void setContentsToVideo(PlatformLayer*);
+ virtual void setContentsToMedia(PlatformLayer*);
#if ENABLE(3D_CANVAS)
virtual void setContentsToGraphicsContext3D(const GraphicsContext3D*);
#endif
@@ -116,8 +117,9 @@ public:
virtual void setGeometryOrientation(CompositingCoordinatesOrientation);
+ virtual void didDisplay(PlatformLayer*);
+
void recursiveCommitChanges();
- void commitLayerChanges();
virtual void syncCompositingState();
@@ -127,13 +129,20 @@ protected:
private:
void updateOpacityOnLayer();
- WebLayer* primaryLayer() const { return m_transformLayer.get() ? m_transformLayer.get() : m_layer.get(); }
- WebLayer* hostLayerForSublayers() const;
- WebLayer* layerForSuperlayer() const;
+ CALayer* primaryLayer() const { return m_structuralLayer.get() ? m_structuralLayer.get() : m_layer.get(); }
+ CALayer* hostLayerForSublayers() const;
+ CALayer* layerForSuperlayer() const;
CALayer* animatedLayer(AnimatedPropertyID property) const;
- bool createAnimationFromKeyframes(const KeyframeValueList&, const Animation*, const String& keyframesName, double beginTime);
- bool createTransformAnimationsFromKeyframes(const KeyframeValueList&, const Animation*, const String& keyframesName, double beginTime, const IntSize& boxSize);
+ typedef String CloneID; // Identifier for a given clone, based on original/replica branching down the tree.
+ static bool isReplicatedRootClone(const CloneID& cloneID) { return cloneID[0U] & 1; }
+
+ typedef HashMap<CloneID, RetainPtr<CALayer> > LayerMap;
+ LayerMap* primaryLayerClones() const { return m_structuralLayer.get() ? m_structuralLayerClones.get() : m_layerClones.get(); }
+ LayerMap* animatedLayerClones(AnimatedPropertyID property) const;
+
+ bool createAnimationFromKeyframes(const KeyframeValueList&, const Animation*, const String& keyframesName, double timeOffset);
+ bool createTransformAnimationsFromKeyframes(const KeyframeValueList&, const Animation*, const String& keyframesName, double timeOffset, const IntSize& boxSize);
// Return autoreleased animation (use RetainPtr?)
CABasicAnimation* createBasicAnimation(const Animation*, AnimatedPropertyID, bool additive);
@@ -153,6 +162,9 @@ private:
return m_runningKeyframeAnimations.find(keyframesName) != m_runningKeyframeAnimations.end();
}
+ void commitLayerChangesBeforeSublayers();
+ void commitLayerChangesAfterSublayers();
+
bool requiresTiledLayer(const FloatSize&) const;
void swapFromOrToTiledLayer(bool useTiledLayer);
@@ -161,8 +173,75 @@ private:
void setupContentsLayer(CALayer*);
CALayer* contentsLayer() const { return m_contentsLayer.get(); }
+
+ virtual void setReplicatedByLayer(GraphicsLayer*);
+
+ // Used to track the path down the tree for replica layers.
+ struct ReplicaState {
+ static const size_t maxReplicaDepth = 16;
+ enum ReplicaBranchType { ChildBranch = 0, ReplicaBranch = 1 };
+ ReplicaState(ReplicaBranchType firstBranch)
+ : m_replicaDepth(0)
+ {
+ push(firstBranch);
+ }
+
+ // Called as we walk down the tree to build replicas.
+ void push(ReplicaBranchType branchType)
+ {
+ m_replicaBranches.append(branchType);
+ if (branchType == ReplicaBranch)
+ ++m_replicaDepth;
+ }
+
+ void setBranchType(ReplicaBranchType branchType)
+ {
+ ASSERT(!m_replicaBranches.isEmpty());
+
+ if (m_replicaBranches.last() != branchType) {
+ if (branchType == ReplicaBranch)
+ ++m_replicaDepth;
+ else
+ --m_replicaDepth;
+ }
+
+ m_replicaBranches.last() = branchType;
+ }
+
+ void pop()
+ {
+ if (m_replicaBranches.last() == ReplicaBranch)
+ --m_replicaDepth;
+ m_replicaBranches.removeLast();
+ }
+
+ size_t depth() const { return m_replicaBranches.size(); }
+ size_t replicaDepth() const { return m_replicaDepth; }
+
+ CloneID cloneID() const;
+
+ private:
+ Vector<ReplicaBranchType> m_replicaBranches;
+ size_t m_replicaDepth;
+ };
+ CALayer *replicatedLayerRoot(ReplicaState&);
+
+ enum CloneLevel { RootCloneLevel, IntermediateCloneLevel };
+ CALayer *fetchCloneLayers(GraphicsLayer* replicaRoot, ReplicaState&, CloneLevel);
+
+ CALayer *cloneLayer(CALayer *, CloneLevel);
+ CALayer *findOrMakeClone(CloneID, CALayer *, LayerMap*, CloneLevel);
+
+ void ensureCloneLayers(CloneID index, CALayer *& primaryLayer, CALayer *& structuralLayer, CALayer *& contentsLayer, CloneLevel);
+
+ bool hasCloneLayers() const { return m_layerClones; }
+ void removeCloneLayers();
+ FloatPoint positionForCloneRootLayer() const;
+
+ void propagateLayerChangeToReplicas();
// All these "update" methods will be called inside a BEGIN_BLOCK_OBJC_EXCEPTIONS/END_BLOCK_OBJC_EXCEPTIONS block.
+ void updateLayerNames();
void updateSublayerList();
void updateLayerPosition();
void updateLayerSize();
@@ -172,25 +251,38 @@ private:
void updateMasksToBounds();
void updateContentsOpaque();
void updateBackfaceVisibility();
- void updateLayerPreserves3D();
+ void updateStructuralLayer();
void updateLayerDrawsContent();
void updateLayerBackgroundColor();
void updateContentsImage();
- void updateContentsVideo();
+ void updateContentsMediaLayer();
#if ENABLE(3D_CANVAS)
void updateContentsGraphicsContext3D();
#endif
void updateContentsRect();
void updateGeometryOrientation();
void updateMaskLayer();
+ void updateReplicatedLayers();
void updateLayerAnimations();
+
+ enum StructuralLayerPurpose {
+ NoStructuralLayer = 0,
+ StructuralLayerForPreserves3D,
+ StructuralLayerForReplicaFlattening
+ };
+ void ensureStructuralLayer(StructuralLayerPurpose);
+ StructuralLayerPurpose structuralLayerPurpose() const;
- void setAnimationOnLayer(CAPropertyAnimation*, AnimatedPropertyID, int index, double beginTime);
- bool removeAnimationFromLayer(AnimatedPropertyID, int index);
- void pauseAnimationOnLayer(AnimatedPropertyID, int index);
+ void setAnimationOnLayer(CAPropertyAnimation*, AnimatedPropertyID, const String& keyframesName, int index, double timeOffset);
+ bool removeAnimationFromLayer(AnimatedPropertyID, const String& keyframesName, int index);
+ void pauseAnimationOnLayer(AnimatedPropertyID, const String& keyframesName, int index, double timeOffset);
+ enum MoveOrCopy { Move, Copy };
+ void moveOrCopyAnimationsForProperty(MoveOrCopy, AnimatedPropertyID property, CALayer * fromLayer, CALayer * toLayer);
+ static void moveOrCopyAllAnimationsForProperty(MoveOrCopy operation, AnimatedPropertyID property, const String& keyframesName, CALayer * fromLayer, CALayer * toLayer);
+
enum LayerChange {
NoChange = 0,
NameChanged = 1 << 1,
@@ -210,27 +302,34 @@ private:
AnimationChanged = 1 << 15,
DirtyRectsChanged = 1 << 16,
ContentsImageChanged = 1 << 17,
- ContentsVideoChanged = 1 << 18,
+ ContentsMediaLayerChanged = 1 << 18,
#if ENABLE(3D_CANVAS)
ContentsGraphicsContext3DChanged = 1 << 19,
#endif
ContentsRectChanged = 1 << 20,
GeometryOrientationChanged = 1 << 21,
- MaskLayerChanged = 1 << 22
+ MaskLayerChanged = 1 << 22,
+ ReplicatedLayerChanged = 1 << 23
};
typedef unsigned LayerChangeFlags;
void noteLayerPropertyChanged(LayerChangeFlags flags);
+ void noteSublayersChanged();
void repaintLayerDirtyRects();
- RetainPtr<WebLayer> m_layer;
- RetainPtr<WebLayer> m_transformLayer;
- RetainPtr<CALayer> m_contentsLayer;
+ RetainPtr<WebLayer> m_layer; // The main layer
+ RetainPtr<CALayer> m_structuralLayer; // A layer used for structural reasons, like preserves-3d or replica-flattening. Is the parent of m_layer.
+ RetainPtr<CALayer> m_contentsLayer; // A layer used for inner content, like image and video
+
+ // References to clones of our layers, for replicated layers.
+ OwnPtr<LayerMap> m_layerClones;
+ OwnPtr<LayerMap> m_structuralLayerClones;
+ OwnPtr<LayerMap> m_contentsLayerClones;
enum ContentsLayerPurpose {
NoContentsLayer = 0,
ContentsLayerForImage,
- ContentsLayerForVideo
+ ContentsLayerForMedia
#if ENABLE(3D_CANVAS)
,ContentsLayerForGraphicsLayer3D
#endif
@@ -244,19 +343,19 @@ private:
RetainPtr<CGImageRef> m_pendingContentsImage;
struct LayerAnimation {
- LayerAnimation(CAPropertyAnimation* caAnim, const String& keyframesName, AnimatedPropertyID property, int index, double beginTime)
+ LayerAnimation(CAPropertyAnimation* caAnim, const String& keyframesName, AnimatedPropertyID property, int index, double timeOffset)
: m_animation(caAnim)
, m_keyframesName(keyframesName)
, m_property(property)
, m_index(index)
- , m_beginTime(beginTime)
+ , m_timeOffset(timeOffset)
{ }
RetainPtr<CAPropertyAnimation*> m_animation;
String m_keyframesName;
AnimatedPropertyID m_property;
int m_index;
- double m_beginTime;
+ double m_timeOffset;
};
Vector<LayerAnimation> m_uncomittedAnimations;
@@ -267,8 +366,16 @@ private:
HashSet<AnimatedProperty> m_transitionPropertiesToRemove;
- enum { Remove, Pause };
- typedef int AnimationProcessingAction;
+ enum Action { Remove, Pause };
+ struct AnimationProcessingAction {
+ AnimationProcessingAction(Action action = Remove, double timeOffset = 0)
+ : action(action)
+ , timeOffset(timeOffset)
+ {
+ }
+ Action action;
+ double timeOffset; // only used for pause
+ };
typedef HashMap<String, AnimationProcessingAction> AnimationsToProcessMap;
AnimationsToProcessMap m_keyframeAnimationsToProcess;
diff --git a/WebCore/platform/graphics/mac/GraphicsLayerCA.mm b/WebCore/platform/graphics/mac/GraphicsLayerCA.mm
index dea6bfc..22e39f5 100644
--- a/WebCore/platform/graphics/mac/GraphicsLayerCA.mm
+++ b/WebCore/platform/graphics/mac/GraphicsLayerCA.mm
@@ -42,6 +42,7 @@
#import <QuartzCore/QuartzCore.h>
#import "RotateTransformOperation.h"
#import "ScaleTransformOperation.h"
+#import "StringBuilder.h"
#import "SystemTime.h"
#import "TranslateTransformOperation.h"
#import "WebLayer.h"
@@ -86,6 +87,10 @@ static double mediaTimeToCurrentTime(CFTimeInterval t)
} // namespace WebCore
+@interface CALayer(Private)
+- (void)setContentsChanged;
+@end
+
@interface WebAnimationDelegate : NSObject {
WebCore::GraphicsLayerCA* m_graphicsLayer;
}
@@ -246,12 +251,20 @@ static String propertyIdToString(AnimatedPropertyID property)
return "";
}
-static String animationIdentifier(AnimatedPropertyID property, int index)
+static String animationIdentifier(AnimatedPropertyID property, const String& keyframesName, int index)
{
- String animationId = propertyIdToString(property);
- animationId.append("_");
- animationId.append(String::number(index));
- return animationId;
+ StringBuilder builder;
+
+ builder.append(propertyIdToString(property));
+ builder.append("_");
+
+ if (!keyframesName.isEmpty()) {
+ builder.append(keyframesName);
+ builder.append("_");
+ }
+ builder.append("_");
+ builder.append(String::number(index));
+ return builder.toString();
}
#if !HAVE_MODERN_QUARTZCORE
@@ -392,9 +405,17 @@ GraphicsLayerCA::~GraphicsLayerCA()
[layer setLayerOwner:nil];
}
+ if (m_contentsLayer) {
+ if ([m_contentsLayer.get() respondsToSelector:@selector(setLayerOwner:)])
+ [(id)m_contentsLayer.get() setLayerOwner:nil];
+ }
+
// animationDidStart: can fire after this, so we need to clear out the layer on the delegate.
[m_animationDelegate.get() setLayer:0];
+ // Release the clone layers inside the exception-handling block.
+ removeCloneLayers();
+
END_BLOCK_OBJC_EXCEPTIONS
}
@@ -414,7 +435,7 @@ bool GraphicsLayerCA::setChildren(const Vector<GraphicsLayer*>& children)
{
bool childrenChanged = GraphicsLayer::setChildren(children);
if (childrenChanged)
- noteLayerPropertyChanged(ChildrenChanged);
+ noteSublayersChanged();
return childrenChanged;
}
@@ -422,31 +443,31 @@ bool GraphicsLayerCA::setChildren(const Vector<GraphicsLayer*>& children)
void GraphicsLayerCA::addChild(GraphicsLayer* childLayer)
{
GraphicsLayer::addChild(childLayer);
- noteLayerPropertyChanged(ChildrenChanged);
+ noteSublayersChanged();
}
void GraphicsLayerCA::addChildAtIndex(GraphicsLayer* childLayer, int index)
{
GraphicsLayer::addChildAtIndex(childLayer, index);
- noteLayerPropertyChanged(ChildrenChanged);
+ noteSublayersChanged();
}
void GraphicsLayerCA::addChildBelow(GraphicsLayer* childLayer, GraphicsLayer* sibling)
{
GraphicsLayer::addChildBelow(childLayer, sibling);
- noteLayerPropertyChanged(ChildrenChanged);
+ noteSublayersChanged();
}
void GraphicsLayerCA::addChildAbove(GraphicsLayer* childLayer, GraphicsLayer* sibling)
{
GraphicsLayer::addChildAbove(childLayer, sibling);
- noteLayerPropertyChanged(ChildrenChanged);
+ noteSublayersChanged();
}
bool GraphicsLayerCA::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild)
{
if (GraphicsLayer::replaceChild(oldChild, newChild)) {
- noteLayerPropertyChanged(ChildrenChanged);
+ noteSublayersChanged();
return true;
}
return false;
@@ -455,7 +476,7 @@ bool GraphicsLayerCA::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newCh
void GraphicsLayerCA::removeFromParent()
{
if (m_parent)
- static_cast<GraphicsLayerCA*>(m_parent)->noteLayerPropertyChanged(ChildrenChanged);
+ static_cast<GraphicsLayerCA*>(m_parent)->noteSublayersChanged();
GraphicsLayer::removeFromParent();
}
@@ -466,6 +487,30 @@ void GraphicsLayerCA::setMaskLayer(GraphicsLayer* layer)
GraphicsLayer::setMaskLayer(layer);
noteLayerPropertyChanged(MaskLayerChanged);
+
+ propagateLayerChangeToReplicas();
+
+ if (m_replicatedLayer)
+ static_cast<GraphicsLayerCA*>(m_replicatedLayer)->propagateLayerChangeToReplicas();
+}
+
+void GraphicsLayerCA::setReplicatedLayer(GraphicsLayer* layer)
+{
+ if (layer == m_replicatedLayer)
+ return;
+
+ GraphicsLayer::setReplicatedLayer(layer);
+ noteLayerPropertyChanged(ReplicatedLayerChanged);
+}
+
+void GraphicsLayerCA::setReplicatedByLayer(GraphicsLayer* layer)
+{
+ if (layer == m_replicaLayer)
+ return;
+
+ GraphicsLayer::setReplicatedByLayer(layer);
+ noteSublayersChanged();
+ noteLayerPropertyChanged(ReplicatedLayerChanged);
}
void GraphicsLayerCA::setPosition(const FloatPoint& point)
@@ -513,22 +558,41 @@ void GraphicsLayerCA::setChildrenTransform(const TransformationMatrix& t)
noteLayerPropertyChanged(ChildrenTransformChanged);
}
-static void moveAnimation(AnimatedPropertyID property, CALayer* fromLayer, CALayer* toLayer)
+void GraphicsLayerCA::moveOrCopyAllAnimationsForProperty(MoveOrCopy operation, AnimatedPropertyID property, const String& keyframesName, CALayer *fromLayer, CALayer *toLayer)
{
for (int index = 0; ; ++index) {
- String animName = animationIdentifier(property, index);
+ String animName = animationIdentifier(property, keyframesName, index);
CAAnimation* anim = [fromLayer animationForKey:animName];
if (!anim)
break;
- [anim retain];
- [fromLayer removeAnimationForKey:animName];
- [toLayer addAnimation:anim forKey:animName];
- [anim release];
+ switch (operation) {
+ case Move:
+ [anim retain];
+ [fromLayer removeAnimationForKey:animName];
+ [toLayer addAnimation:anim forKey:animName];
+ [anim release];
+ break;
+
+ case Copy:
+ [toLayer addAnimation:anim forKey:animName];
+ break;
+ }
}
}
+void GraphicsLayerCA::moveOrCopyAnimationsForProperty(MoveOrCopy operation, AnimatedPropertyID property, CALayer *fromLayer, CALayer *toLayer)
+{
+ // Move transitions for this property.
+ moveOrCopyAllAnimationsForProperty(operation, property, "", fromLayer, toLayer);
+
+ // Look for running animations affecting this property.
+ KeyframeAnimationsMap::const_iterator end = m_runningKeyframeAnimations.end();
+ for (KeyframeAnimationsMap::const_iterator it = m_runningKeyframeAnimations.begin(); it != end; ++it)
+ moveOrCopyAllAnimationsForProperty(operation, property, it->first, fromLayer, toLayer);
+}
+
void GraphicsLayerCA::setPreserves3D(bool preserves3D)
{
if (preserves3D == m_preserves3D)
@@ -643,7 +707,7 @@ void GraphicsLayerCA::setContentsRect(const IntRect& rect)
noteLayerPropertyChanged(ContentsRectChanged);
}
-bool GraphicsLayerCA::addAnimation(const KeyframeValueList& valueList, const IntSize& boxSize, const Animation* anim, const String& keyframesName, double beginTime)
+bool GraphicsLayerCA::addAnimation(const KeyframeValueList& valueList, const IntSize& boxSize, const Animation* anim, const String& keyframesName, double timeOffset)
{
if (forceSoftwareAnimation() || !anim || anim->isEmptyOrZeroDuration() || valueList.size() < 2)
return false;
@@ -657,9 +721,9 @@ bool GraphicsLayerCA::addAnimation(const KeyframeValueList& valueList, const Int
bool createdAnimations = false;
if (valueList.property() == AnimatedPropertyWebkitTransform)
- createdAnimations = createTransformAnimationsFromKeyframes(valueList, anim, keyframesName, beginTime, boxSize);
+ createdAnimations = createTransformAnimationsFromKeyframes(valueList, anim, keyframesName, timeOffset, boxSize);
else
- createdAnimations = createAnimationFromKeyframes(valueList, anim, keyframesName, beginTime);
+ createdAnimations = createAnimationFromKeyframes(valueList, anim, keyframesName, timeOffset);
if (createdAnimations)
noteLayerPropertyChanged(AnimationChanged);
@@ -681,22 +745,23 @@ void GraphicsLayerCA::removeAnimationsForKeyframes(const String& animationName)
if (!animationIsRunning(animationName))
return;
- m_keyframeAnimationsToProcess.add(animationName, Remove);
+ m_keyframeAnimationsToProcess.add(animationName, AnimationProcessingAction(Remove));
noteLayerPropertyChanged(AnimationChanged);
}
-void GraphicsLayerCA::pauseAnimation(const String& keyframesName)
+void GraphicsLayerCA::pauseAnimation(const String& keyframesName, double timeOffset)
{
if (!animationIsRunning(keyframesName))
return;
AnimationsToProcessMap::iterator it = m_keyframeAnimationsToProcess.find(keyframesName);
if (it != m_keyframeAnimationsToProcess.end()) {
+ AnimationProcessingAction& processingInfo = it->second;
// If an animation is scheduled to be removed, don't change the remove to a pause.
- if (it->second != Remove)
- it->second = Pause;
+ if (processingInfo.action != Remove)
+ processingInfo.action = Pause;
} else
- m_keyframeAnimationsToProcess.add(keyframesName, Pause);
+ m_keyframeAnimationsToProcess.add(keyframesName, AnimationProcessingAction(Pause, timeOffset));
noteLayerPropertyChanged(AnimationChanged);
}
@@ -716,26 +781,27 @@ void GraphicsLayerCA::setContentsToImage(Image* image)
}
m_contentsLayerPurpose = ContentsLayerForImage;
if (!m_contentsLayer)
- noteLayerPropertyChanged(ChildrenChanged);
+ noteSublayersChanged();
} else {
m_pendingContentsImage = 0;
m_contentsLayerPurpose = NoContentsLayer;
if (m_contentsLayer)
- noteLayerPropertyChanged(ChildrenChanged);
+ noteSublayersChanged();
}
noteLayerPropertyChanged(ContentsImageChanged);
}
-void GraphicsLayerCA::setContentsToVideo(PlatformLayer* videoLayer)
+void GraphicsLayerCA::setContentsToMedia(PlatformLayer* mediaLayer)
{
- if (videoLayer != m_contentsLayer.get())
- noteLayerPropertyChanged(ChildrenChanged);
+ if (mediaLayer == m_contentsLayer)
+ return;
- m_contentsLayer = videoLayer;
- noteLayerPropertyChanged(ContentsVideoChanged);
+ m_contentsLayer = mediaLayer;
+ m_contentsLayerPurpose = mediaLayer ? ContentsLayerForMedia : NoContentsLayer;
- m_contentsLayerPurpose = videoLayer ? ContentsLayerForVideo : NoContentsLayer;
+ noteSublayersChanged();
+ noteLayerPropertyChanged(ContentsMediaLayerChanged);
}
void GraphicsLayerCA::setGeometryOrientation(CompositingCoordinatesOrientation orientation)
@@ -760,6 +826,35 @@ void GraphicsLayerCA::setGeometryOrientation(CompositingCoordinatesOrientation o
#endif
}
+void GraphicsLayerCA::didDisplay(PlatformLayer* layer)
+{
+ CALayer* sourceLayer;
+ LayerMap* layerCloneMap;
+
+ if (layer == m_layer) {
+ sourceLayer = m_layer.get();
+ layerCloneMap = m_layerClones.get();
+ } else if (layer == m_contentsLayer) {
+ sourceLayer = m_contentsLayer.get();
+ layerCloneMap = m_contentsLayerClones.get();
+ } else
+ return;
+
+ if (layerCloneMap) {
+ LayerMap::const_iterator end = layerCloneMap->end();
+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
+ CALayer *currClone = it->second.get();
+ if (!currClone)
+ continue;
+
+ if ([currClone contents] != [sourceLayer contents])
+ [currClone setContents:[sourceLayer contents]];
+ else
+ [currClone setContentsChanged];
+ }
+ }
+}
+
void GraphicsLayerCA::syncCompositingState()
{
recursiveCommitChanges();
@@ -767,10 +862,10 @@ void GraphicsLayerCA::syncCompositingState()
void GraphicsLayerCA::recursiveCommitChanges()
{
- commitLayerChanges();
+ commitLayerChangesBeforeSublayers();
if (m_maskLayer)
- static_cast<GraphicsLayerCA*>(m_maskLayer)->commitLayerChanges();
+ static_cast<GraphicsLayerCA*>(m_maskLayer)->commitLayerChangesBeforeSublayers();
const Vector<GraphicsLayer*>& childLayers = children();
size_t numChildren = childLayers.size();
@@ -778,9 +873,17 @@ void GraphicsLayerCA::recursiveCommitChanges()
GraphicsLayerCA* curChild = static_cast<GraphicsLayerCA*>(childLayers[i]);
curChild->recursiveCommitChanges();
}
+
+ if (m_replicaLayer)
+ static_cast<GraphicsLayerCA*>(m_replicaLayer)->recursiveCommitChanges();
+
+ if (m_maskLayer)
+ static_cast<GraphicsLayerCA*>(m_maskLayer)->commitLayerChangesAfterSublayers();
+
+ commitLayerChangesAfterSublayers();
}
-void GraphicsLayerCA::commitLayerChanges()
+void GraphicsLayerCA::commitLayerChangesBeforeSublayers()
{
if (!m_uncommittedChanges)
return;
@@ -788,20 +891,17 @@ void GraphicsLayerCA::commitLayerChanges()
BEGIN_BLOCK_OBJC_EXCEPTIONS
// Need to handle Preserves3DChanged first, because it affects which layers subsequent properties are applied to
- if (m_uncommittedChanges & Preserves3DChanged)
- updateLayerPreserves3D();
+ if (m_uncommittedChanges & (Preserves3DChanged | ReplicatedLayerChanged))
+ updateStructuralLayer();
- if (m_uncommittedChanges & NameChanged) {
- if (m_transformLayer)
- [m_transformLayer.get() setName:("Transform layer " + name())];
- [m_layer.get() setName:name()];
- }
+ if (m_uncommittedChanges & NameChanged)
+ updateLayerNames();
if (m_uncommittedChanges & ContentsImageChanged) // Needs to happen before ChildrenChanged
updateContentsImage();
- if (m_uncommittedChanges & ContentsVideoChanged) // Needs to happen before ChildrenChanged
- updateContentsVideo();
+ if (m_uncommittedChanges & ContentsMediaLayerChanged) // Needs to happen before ChildrenChanged
+ updateContentsMediaLayer();
#if ENABLE(3D_CANVAS)
if (m_uncommittedChanges & ContentsGraphicsContext3DChanged) // Needs to happen before ChildrenChanged
@@ -859,40 +959,72 @@ void GraphicsLayerCA::commitLayerChanges()
if (m_uncommittedChanges & MaskLayerChanged)
updateMaskLayer();
+ END_BLOCK_OBJC_EXCEPTIONS
+}
+
+void GraphicsLayerCA::commitLayerChangesAfterSublayers()
+{
+ if (!m_uncommittedChanges)
+ return;
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+
+ if (m_uncommittedChanges & ReplicatedLayerChanged)
+ updateReplicatedLayers();
+
m_uncommittedChanges = NoChange;
END_BLOCK_OBJC_EXCEPTIONS
}
+void GraphicsLayerCA::updateLayerNames()
+{
+ switch (structuralLayerPurpose()) {
+ case StructuralLayerForPreserves3D:
+ [m_structuralLayer.get() setName:("Transform layer " + name())];
+ break;
+ case StructuralLayerForReplicaFlattening:
+ [m_structuralLayer.get() setName:("Replica flattening layer " + name())];
+ break;
+ case NoStructuralLayer:
+ break;
+ }
+ [m_layer.get() setName:name()];
+}
+
void GraphicsLayerCA::updateSublayerList()
{
NSMutableArray* newSublayers = nil;
- if (m_transformLayer) {
- // 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];
- }
-
const Vector<GraphicsLayer*>& childLayers = children();
- size_t numChildren = childLayers.size();
- for (size_t i = 0; i < numChildren; ++i) {
- GraphicsLayerCA* curChild = static_cast<GraphicsLayerCA*>(childLayers[i]);
-
- CALayer* childLayer = curChild->layerForSuperlayer();
- if (!newSublayers)
- newSublayers = [[NSMutableArray alloc] initWithObjects:childLayer, nil];
- else
+
+ if (m_structuralLayer || m_contentsLayer || childLayers.size() > 0) {
+ newSublayers = [[NSMutableArray alloc] init];
+
+ if (m_structuralLayer) {
+ // Add the replica layer first.
+ if (m_replicaLayer)
+ [newSublayers addObject:static_cast<GraphicsLayerCA*>(m_replicaLayer)->primaryLayer()];
+ // Add the primary layer. Even if we have negative z-order children, the primary layer always comes behind.
+ [newSublayers addObject:m_layer.get()];
+ } 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 addObject:m_contentsLayer.get()];
+ }
+
+ size_t numChildren = childLayers.size();
+ for (size_t i = 0; i < numChildren; ++i) {
+ GraphicsLayerCA* curChild = static_cast<GraphicsLayerCA*>(childLayers[i]);
+ CALayer *childLayer = curChild->layerForSuperlayer();
[newSublayers addObject:childLayer];
- }
+ }
- [newSublayers makeObjectsPerformSelector:@selector(removeFromSuperlayer)];
+ [newSublayers makeObjectsPerformSelector:@selector(removeFromSuperlayer)];
+ }
- if (m_transformLayer) {
- safeSetSublayers(m_transformLayer.get(), newSublayers);
+ if (m_structuralLayer) {
+ safeSetSublayers(m_structuralLayer.get(), newSublayers);
if (m_contentsLayer) {
// If we have a transform layer, then the contents layer is parented in the
@@ -913,16 +1045,43 @@ void GraphicsLayerCA::updateLayerPosition()
m_position.y() + m_anchorPoint.y() * m_size.height());
[primaryLayer() setPosition:posPoint];
+
+ if (LayerMap* layerCloneMap = primaryLayerClones()) {
+ LayerMap::const_iterator end = layerCloneMap->end();
+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
+ CGPoint clonePosition = posPoint;
+ if (m_replicaLayer && isReplicatedRootClone(it->first)) {
+ // Maintain the special-case position for the root of a clone subtree,
+ // which we set up in replicatedLayerRoot().
+ clonePosition = positionForCloneRootLayer();
+ }
+ CALayer *currLayer = it->second.get();
+ [currLayer setPosition:clonePosition];
+ }
+ }
}
void GraphicsLayerCA::updateLayerSize()
{
CGRect rect = CGRectMake(0, 0, m_size.width(), m_size.height());
- if (m_transformLayer) {
- [m_transformLayer.get() setBounds:rect];
+ if (m_structuralLayer) {
+ [m_structuralLayer.get() setBounds:rect];
+
+ if (LayerMap* layerCloneMap = m_structuralLayerClones.get()) {
+ LayerMap::const_iterator end = layerCloneMap->end();
+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
+ [it->second.get() setBounds:rect];
+ }
+
// The anchor of the contents layer is always at 0.5, 0.5, so the position is center-relative.
CGPoint centerPoint = CGPointMake(m_size.width() / 2.0f, m_size.height() / 2.0f);
[m_layer.get() setPosition:centerPoint];
+
+ if (LayerMap* layerCloneMap = m_layerClones.get()) {
+ LayerMap::const_iterator end = layerCloneMap->end();
+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
+ [it->second.get() setPosition:centerPoint];
+ }
}
bool needTiledLayer = requiresTiledLayer(m_size);
@@ -930,6 +1089,11 @@ void GraphicsLayerCA::updateLayerSize()
swapFromOrToTiledLayer(needTiledLayer);
[m_layer.get() setBounds:rect];
+ if (LayerMap* layerCloneMap = m_layerClones.get()) {
+ LayerMap::const_iterator end = layerCloneMap->end();
+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
+ [it->second.get() setBounds:rect];
+ }
// Contents transform may depend on height.
updateContentsTransform();
@@ -947,6 +1111,18 @@ void GraphicsLayerCA::updateAnchorPoint()
#if HAVE_MODERN_QUARTZCORE
[primaryLayer() setAnchorPointZ:m_anchorPoint.z()];
#endif
+
+ if (LayerMap* layerCloneMap = primaryLayerClones()) {
+ LayerMap::const_iterator end = layerCloneMap->end();
+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
+ CALayer *currLayer = it->second.get();
+ [currLayer setAnchorPoint:FloatPoint(m_anchorPoint.x(), m_anchorPoint.y())];
+#if HAVE_MODERN_QUARTZCORE
+ [currLayer setAnchorPointZ:m_anchorPoint.z()];
+#endif
+ }
+ }
+
updateLayerPosition();
}
@@ -955,6 +1131,19 @@ void GraphicsLayerCA::updateTransform()
CATransform3D transform;
copyTransform(transform, m_transform);
[primaryLayer() setTransform:transform];
+
+ if (LayerMap* layerCloneMap = primaryLayerClones()) {
+ LayerMap::const_iterator end = layerCloneMap->end();
+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
+ CALayer *currLayer = it->second.get();
+ if (m_replicaLayer && isReplicatedRootClone(it->first)) {
+ // Maintain the special-case transform for the root of a clone subtree,
+ // which we set up in replicatedLayerRoot().
+ [currLayer setTransform:CATransform3DIdentity];
+ } else
+ [currLayer setTransform:transform];
+ }
+ }
}
void GraphicsLayerCA::updateChildrenTransform()
@@ -962,85 +1151,157 @@ void GraphicsLayerCA::updateChildrenTransform()
CATransform3D transform;
copyTransform(transform, m_childrenTransform);
[primaryLayer() setSublayerTransform:transform];
+
+ if (LayerMap* layerCloneMap = primaryLayerClones()) {
+ LayerMap::const_iterator end = layerCloneMap->end();
+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
+ CALayer *currLayer = it->second.get();
+ [currLayer setSublayerTransform:transform];
+ }
+ }
}
void GraphicsLayerCA::updateMasksToBounds()
{
[m_layer.get() setMasksToBounds:m_masksToBounds];
+
+ if (LayerMap* layerCloneMap = m_layerClones.get()) {
+ LayerMap::const_iterator end = layerCloneMap->end();
+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
+ CALayer *currLayer = it->second.get();
+ [currLayer setMasksToBounds:m_masksToBounds];
+ }
+ }
+
updateDebugIndicators();
}
void GraphicsLayerCA::updateContentsOpaque()
{
[m_layer.get() setOpaque:m_contentsOpaque];
+
+ if (LayerMap* layerCloneMap = m_layerClones.get()) {
+ LayerMap::const_iterator end = layerCloneMap->end();
+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
+ CALayer *currLayer = it->second.get();
+ [currLayer setOpaque:m_contentsOpaque];
+ }
+ }
}
void GraphicsLayerCA::updateBackfaceVisibility()
{
[m_layer.get() setDoubleSided:m_backfaceVisibility];
+
+ if (LayerMap* layerCloneMap = m_layerClones.get()) {
+ LayerMap::const_iterator end = layerCloneMap->end();
+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
+ CALayer *currLayer = it->second.get();
+ [currLayer setDoubleSided:m_backfaceVisibility];
+ }
+ }
}
-void GraphicsLayerCA::updateLayerPreserves3D()
+void GraphicsLayerCA::updateStructuralLayer()
{
- Class transformLayerClass = NSClassFromString(@"CATransformLayer");
- if (!transformLayerClass)
- return;
+ ensureStructuralLayer(structuralLayerPurpose());
+}
- if (m_preserves3D && !m_transformLayer) {
- // Create the transform layer.
- m_transformLayer.adoptNS([[transformLayerClass alloc] init]);
+void GraphicsLayerCA::ensureStructuralLayer(StructuralLayerPurpose purpose)
+{
+ if (purpose == NoStructuralLayer) {
+ if (m_structuralLayer) {
+ // Replace the transformLayer in the parent with this layer.
+ [m_layer.get() removeFromSuperlayer];
+ [[m_structuralLayer.get() superlayer] replaceSublayer:m_structuralLayer.get() with:m_layer.get()];
- // Turn off default animations.
- [m_transformLayer.get() setStyle:[NSDictionary dictionaryWithObject:nullActionsDictionary() forKey:@"actions"]];
+ moveOrCopyAnimationsForProperty(Move, AnimatedPropertyWebkitTransform, m_structuralLayer.get(), m_layer.get());
+ moveOrCopyAnimationsForProperty(Move, AnimatedPropertyOpacity, m_structuralLayer.get(), m_layer.get());
-#ifndef NDEBUG
- [m_transformLayer.get() setName:[NSString stringWithFormat:@"Transform Layer CATransformLayer(%p) GraphicsLayer(%p)", m_transformLayer.get(), this]];
-#endif
- // Copy the position from this layer.
- updateLayerPosition();
- updateLayerSize();
- updateAnchorPoint();
- updateTransform();
- updateChildrenTransform();
-
- CGPoint point = CGPointMake(m_size.width() / 2.0f, m_size.height() / 2.0f);
- [m_layer.get() setPosition:point];
+ // Release the structural layer.
+ m_structuralLayer = 0;
- [m_layer.get() setAnchorPoint:CGPointMake(0.5f, 0.5f)];
- [m_layer.get() setTransform:CATransform3DIdentity];
-
- // Set the old layer to opacity of 1. Further down we will set the opacity on the transform layer.
- [m_layer.get() setOpacity:1];
+ // Update the properties of m_layer now that we no loner have a structural layer.
+ updateLayerPosition();
+ updateLayerSize();
+ updateAnchorPoint();
+ updateTransform();
+ updateChildrenTransform();
- // Move this layer to be a child of the transform layer.
- [[m_layer.get() superlayer] replaceSublayer:m_layer.get() with:m_transformLayer.get()];
- [m_transformLayer.get() addSublayer:m_layer.get()];
+ updateSublayerList();
+ updateOpacityOnLayer();
+ }
+ return;
+ }
+
+ bool structuralLayerChanged = false;
+
+ if (purpose == StructuralLayerForPreserves3D) {
+ Class transformLayerClass = NSClassFromString(@"CATransformLayer");
+ if (!transformLayerClass)
+ return;
- moveAnimation(AnimatedPropertyWebkitTransform, m_layer.get(), m_transformLayer.get());
+ if (m_structuralLayer && ![m_structuralLayer.get() isKindOfClass:transformLayerClass])
+ m_structuralLayer = 0;
- updateSublayerList();
- } else if (!m_preserves3D && m_transformLayer) {
- // Relace the transformLayer in the parent with this layer.
- [m_layer.get() removeFromSuperlayer];
- [[m_transformLayer.get() superlayer] replaceSublayer:m_transformLayer.get() with:m_layer.get()];
-
- moveAnimation(AnimatedPropertyWebkitTransform, m_transformLayer.get(), m_layer.get());
-
- // Release the transform layer.
- m_transformLayer = 0;
-
- updateLayerPosition();
- updateLayerSize();
- updateAnchorPoint();
- updateTransform();
- updateChildrenTransform();
+ if (!m_structuralLayer) {
+ m_structuralLayer.adoptNS([[transformLayerClass alloc] init]);
+ structuralLayerChanged = true;
+ }
+ } else {
+ if (m_structuralLayer && ![m_structuralLayer.get() isMemberOfClass:[CALayer self]])
+ m_structuralLayer = 0;
- updateSublayerList();
+ if (!m_structuralLayer) {
+ m_structuralLayer.adoptNS([[CALayer alloc] init]);
+ structuralLayerChanged = true;
+ }
}
+
+ if (!structuralLayerChanged)
+ return;
+
+ // Turn off default animations.
+ [m_structuralLayer.get() setStyle:[NSDictionary dictionaryWithObject:nullActionsDictionary() forKey:@"actions"]];
+
+ updateLayerNames();
+ // Update the properties of the structural layer.
+ updateLayerPosition();
+ updateLayerSize();
+ updateAnchorPoint();
+ updateTransform();
+ updateChildrenTransform();
+
+ // Set properties of m_layer to their default values, since these are expressed on on the structural layer.
+ CGPoint point = CGPointMake(m_size.width() / 2.0f, m_size.height() / 2.0f);
+ [m_layer.get() setPosition:point];
+ [m_layer.get() setAnchorPoint:CGPointMake(0.5f, 0.5f)];
+ [m_layer.get() setTransform:CATransform3DIdentity];
+ [m_layer.get() setOpacity:1];
+
+ // Move this layer to be a child of the transform layer.
+ [[m_layer.get() superlayer] replaceSublayer:m_layer.get() with:m_structuralLayer.get()];
+ [m_structuralLayer.get() addSublayer:m_layer.get()];
+
+ moveOrCopyAnimationsForProperty(Move, AnimatedPropertyWebkitTransform, m_layer.get(), m_structuralLayer.get());
+ moveOrCopyAnimationsForProperty(Move, AnimatedPropertyOpacity, m_layer.get(), m_structuralLayer.get());
+
+ updateSublayerList();
updateOpacityOnLayer();
}
+GraphicsLayerCA::StructuralLayerPurpose GraphicsLayerCA::structuralLayerPurpose() const
+{
+ if (preserves3D())
+ return StructuralLayerForPreserves3D;
+
+ if (isReplicated())
+ return StructuralLayerForReplicaFlattening;
+
+ return NoStructuralLayer;
+}
+
void GraphicsLayerCA::updateLayerDrawsContent()
{
bool needTiledLayer = requiresTiledLayer(m_size);
@@ -1087,6 +1348,12 @@ void GraphicsLayerCA::updateContentsImage()
#endif
[m_contentsLayer.get() setContents:(id)m_pendingContentsImage.get()];
m_pendingContentsImage = 0;
+
+ if (m_contentsLayerClones) {
+ LayerMap::const_iterator end = m_contentsLayerClones->end();
+ for (LayerMap::const_iterator it = m_contentsLayerClones->begin(); it != end; ++it)
+ [it->second.get() setContents:[m_contentsLayer.get() contents]];
+ }
updateContentsRect();
} else {
@@ -1096,7 +1363,7 @@ void GraphicsLayerCA::updateContentsImage()
}
}
-void GraphicsLayerCA::updateContentsVideo()
+void GraphicsLayerCA::updateContentsMediaLayer()
{
// Video layer was set as m_contentsLayer, and will get parented in updateSublayerList().
if (m_contentsLayer) {
@@ -1131,6 +1398,15 @@ void GraphicsLayerCA::updateContentsRect()
[m_contentsLayer.get() setPosition:point];
[m_contentsLayer.get() setBounds:rect];
+
+ if (m_contentsLayerClones) {
+ LayerMap::const_iterator end = m_contentsLayerClones->end();
+ for (LayerMap::const_iterator it = m_contentsLayerClones->begin(); it != end; ++it) {
+ CALayer *currLayer = it->second.get();
+ [currLayer setPosition:point];
+ [currLayer setBounds:rect];
+ }
+ }
}
void GraphicsLayerCA::updateGeometryOrientation()
@@ -1152,8 +1428,74 @@ void GraphicsLayerCA::updateGeometryOrientation()
void GraphicsLayerCA::updateMaskLayer()
{
- CALayer* maskCALayer = m_maskLayer ? m_maskLayer->platformLayer() : 0;
+ CALayer *maskCALayer = m_maskLayer ? m_maskLayer->platformLayer() : 0;
[m_layer.get() setMask:maskCALayer];
+
+ LayerMap* maskLayerCloneMap = m_maskLayer ? static_cast<GraphicsLayerCA*>(m_maskLayer)->primaryLayerClones() : 0;
+
+ if (LayerMap* layerCloneMap = m_layerClones.get()) {
+ LayerMap::const_iterator end = layerCloneMap->end();
+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
+ CALayer *currLayer = it->second.get();
+
+ CALayer *maskClone = maskLayerCloneMap ? maskLayerCloneMap->get(it->first).get() : 0;
+ [currLayer setMask:maskClone];
+ }
+ }
+}
+
+void GraphicsLayerCA::updateReplicatedLayers()
+{
+ // Clone the descendants of the replicated layer, and parent under us.
+ ReplicaState replicaState(ReplicaState::ReplicaBranch);
+
+ CALayer *replicaRoot = replicatedLayerRoot(replicaState);
+ if (!replicaRoot)
+ return;
+
+ if (m_structuralLayer)
+ [m_structuralLayer.get() insertSublayer:replicaRoot atIndex:0];
+ else
+ [m_layer.get() insertSublayer:replicaRoot atIndex:0];
+}
+
+// For now, this assumes that layers only ever have one replica, so replicaIndices contains only 0 and 1.
+GraphicsLayerCA::CloneID GraphicsLayerCA::ReplicaState::cloneID() const
+{
+ size_t depth = m_replicaBranches.size();
+
+ const size_t bitsPerUChar = sizeof(UChar) * 8;
+ size_t vectorSize = (depth + bitsPerUChar - 1) / bitsPerUChar;
+
+ Vector<UChar> result(vectorSize);
+ result.fill(0);
+
+ // Create a string from the bit sequence which we can use to identify the clone.
+ // Note that the string may contain embedded nulls, but that's OK.
+ for (size_t i = 0; i < depth; ++i) {
+ UChar& currChar = result[i / bitsPerUChar];
+ currChar = (currChar << 1) | m_replicaBranches[i];
+ }
+
+ return String::adopt(result);
+}
+
+CALayer *GraphicsLayerCA::replicatedLayerRoot(ReplicaState& replicaState)
+{
+ // Limit replica nesting, to avoid 2^N explosion of replica layers.
+ if (!m_replicatedLayer || replicaState.replicaDepth() == ReplicaState::maxReplicaDepth)
+ return nil;
+
+ GraphicsLayerCA* replicatedLayer = static_cast<GraphicsLayerCA*>(m_replicatedLayer);
+
+ CALayer *clonedLayerRoot = replicatedLayer->fetchCloneLayers(this, replicaState, RootCloneLevel);
+ FloatPoint cloneRootPosition = replicatedLayer->positionForCloneRootLayer();
+
+ // Replica root has no offset or transform
+ [clonedLayerRoot setPosition:cloneRootPosition];
+ [clonedLayerRoot setTransform:CATransform3DIdentity];
+
+ return clonedLayerRoot;
}
void GraphicsLayerCA::updateLayerAnimations()
@@ -1163,10 +1505,8 @@ void GraphicsLayerCA::updateLayerAnimations()
for (HashSet<AnimatedProperty>::const_iterator it = m_transitionPropertiesToRemove.begin(); it != end; ++it) {
AnimatedPropertyID currProperty = static_cast<AnimatedPropertyID>(*it);
// Remove all animations with this property in the key.
- // We can't tell if this property is animating via a transition or animation here, but
- // that's OK because the style system never sends both transitions and animations for the same property.
for (int index = 0; ; ++index) {
- if (!removeAnimationFromLayer(currProperty, index))
+ if (!removeAnimationFromLayer(currProperty, "", index))
break;
}
}
@@ -1182,21 +1522,21 @@ void GraphicsLayerCA::updateLayerAnimations()
if (animationIt == m_runningKeyframeAnimations.end())
continue;
- AnimationProcessingAction action = it->second;
+ const AnimationProcessingAction& processingInfo = it->second;
const Vector<AnimationPair>& animations = animationIt->second;
for (size_t i = 0; i < animations.size(); ++i) {
const AnimationPair& currPair = animations[i];
- switch (action) {
+ switch (processingInfo.action) {
case Remove:
- removeAnimationFromLayer(static_cast<AnimatedPropertyID>(currPair.first), currPair.second);
+ removeAnimationFromLayer(static_cast<AnimatedPropertyID>(currPair.first), currKeyframeName, currPair.second);
break;
case Pause:
- pauseAnimationOnLayer(static_cast<AnimatedPropertyID>(currPair.first), currPair.second);
+ pauseAnimationOnLayer(static_cast<AnimatedPropertyID>(currPair.first), currKeyframeName, currPair.second, processingInfo.timeOffset);
break;
}
}
- if (action == Remove)
+ if (processingInfo.action == Remove)
m_runningKeyframeAnimations.remove(currKeyframeName);
}
@@ -1207,7 +1547,7 @@ void GraphicsLayerCA::updateLayerAnimations()
if ((numAnimations = m_uncomittedAnimations.size())) {
for (size_t i = 0; i < numAnimations; ++i) {
const LayerAnimation& pendingAnimation = m_uncomittedAnimations[i];
- setAnimationOnLayer(pendingAnimation.m_animation.get(), pendingAnimation.m_property, pendingAnimation.m_index, pendingAnimation.m_beginTime);
+ setAnimationOnLayer(pendingAnimation.m_animation.get(), pendingAnimation.m_property, pendingAnimation.m_keyframesName, pendingAnimation.m_index, pendingAnimation.m_timeOffset);
if (!pendingAnimation.m_keyframesName.isEmpty()) {
// If this is a keyframe anim, we have to remember the association of keyframes name to property/index pairs,
@@ -1229,19 +1569,28 @@ void GraphicsLayerCA::updateLayerAnimations()
}
}
-void GraphicsLayerCA::setAnimationOnLayer(CAPropertyAnimation* caAnim, AnimatedPropertyID property, int index, double beginTime)
+void GraphicsLayerCA::setAnimationOnLayer(CAPropertyAnimation* caAnim, AnimatedPropertyID property, const String& keyframesName, int index, double timeOffset)
{
PlatformLayer* layer = animatedLayer(property);
- if (beginTime) {
- NSTimeInterval time = [layer convertTime:currentTimeToMediaTime(beginTime) fromLayer:nil];
- [caAnim setBeginTime:time];
- }
+ [caAnim setTimeOffset:timeOffset];
- String animationName = animationIdentifier(property, index);
+ String animationName = animationIdentifier(property, keyframesName, index);
[layer removeAnimationForKey:animationName];
[layer addAnimation:caAnim forKey:animationName];
+
+ if (LayerMap* layerCloneMap = animatedLayerClones(property)) {
+ LayerMap::const_iterator end = layerCloneMap->end();
+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
+ // Skip immediate replicas, since they move with the original.
+ if (m_replicaLayer && isReplicatedRootClone(it->first))
+ continue;
+ CALayer *currLayer = it->second.get();
+ [currLayer removeAnimationForKey:animationName];
+ [currLayer addAnimation:caAnim forKey:animationName];
+ }
+ }
}
// Workaround for <rdar://problem/7311367>
@@ -1259,18 +1608,29 @@ static void bug7311367Workaround(CALayer* transformLayer, const TransformationMa
[transformLayer setTransform:caTransform];
}
-bool GraphicsLayerCA::removeAnimationFromLayer(AnimatedPropertyID property, int index)
+bool GraphicsLayerCA::removeAnimationFromLayer(AnimatedPropertyID property, const String& keyframesName, int index)
{
PlatformLayer* layer = animatedLayer(property);
- String animationName = animationIdentifier(property, index);
+ String animationName = animationIdentifier(property, keyframesName, index);
if (![layer animationForKey:animationName])
return false;
[layer removeAnimationForKey:animationName];
-
- bug7311367Workaround(m_transformLayer.get(), m_transform);
+ bug7311367Workaround(m_structuralLayer.get(), m_transform);
+
+ if (LayerMap* layerCloneMap = animatedLayerClones(property)) {
+ LayerMap::const_iterator end = layerCloneMap->end();
+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
+ // Skip immediate replicas, since they move with the original.
+ if (m_replicaLayer && isReplicatedRootClone(it->first))
+ continue;
+
+ CALayer *currLayer = it->second.get();
+ [currLayer removeAnimationForKey:animationName];
+ }
+ }
return true;
}
@@ -1290,11 +1650,11 @@ static void copyAnimationProperties(CAPropertyAnimation* from, CAPropertyAnimati
#endif
}
-void GraphicsLayerCA::pauseAnimationOnLayer(AnimatedPropertyID property, int index)
+void GraphicsLayerCA::pauseAnimationOnLayer(AnimatedPropertyID property, const String& keyframesName, int index, double timeOffset)
{
PlatformLayer* layer = animatedLayer(property);
- String animationName = animationIdentifier(property, index);
+ String animationName = animationIdentifier(property, keyframesName, index);
CAAnimation* caAnim = [layer animationForKey:animationName];
if (!caAnim)
@@ -1319,10 +1679,23 @@ void GraphicsLayerCA::pauseAnimationOnLayer(AnimatedPropertyID property, int ind
pausedAnim = newAnim;
}
- double t = [layer convertTime:currentTimeToMediaTime(currentTime()) fromLayer:nil];
+ // pausedAnim has the beginTime of caAnim already.
[pausedAnim setSpeed:0];
- [pausedAnim setTimeOffset:t - [caAnim beginTime]];
+ [pausedAnim setTimeOffset:timeOffset];
+
[layer addAnimation:pausedAnim forKey:animationName]; // This will replace the running animation.
+
+ // Pause the animations on the clones too.
+ if (LayerMap* layerCloneMap = animatedLayerClones(property)) {
+ LayerMap::const_iterator end = layerCloneMap->end();
+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
+ // Skip immediate replicas, since they move with the original.
+ if (m_replicaLayer && isReplicatedRootClone(it->first))
+ continue;
+ CALayer *currLayer = it->second.get();
+ [currLayer addAnimation:pausedAnim forKey:animationName];
+ }
+ }
}
#if ENABLE(3D_CANVAS)
@@ -1337,7 +1710,7 @@ void GraphicsLayerCA::setContentsToGraphicsContext3D(const GraphicsContext3D* gr
m_platformGraphicsContext3D = context;
m_platformTexture = texture;
- noteLayerPropertyChanged(ChildrenChanged);
+ noteSublayersChanged();
BEGIN_BLOCK_OBJC_EXCEPTIONS
@@ -1346,9 +1719,11 @@ void GraphicsLayerCA::setContentsToGraphicsContext3D(const GraphicsContext3D* gr
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
+#endif
+ [m_contentsLayer.get() setLayerOwner:this];
} else {
// remove the inner layer
+ [m_contentsLayer.get() setLayerOwner:0];
m_contentsLayer = 0;
}
@@ -1370,7 +1745,7 @@ void GraphicsLayerCA::repaintLayerDirtyRects()
m_dirtyRects.clear();
}
-bool GraphicsLayerCA::createAnimationFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& keyframesName, double beginTime)
+bool GraphicsLayerCA::createAnimationFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& keyframesName, double timeOffset)
{
ASSERT(valueList.property() != AnimatedPropertyWebkitTransform);
@@ -1396,14 +1771,14 @@ bool GraphicsLayerCA::createAnimationFromKeyframes(const KeyframeValueList& valu
if (!valuesOK)
return false;
- m_uncomittedAnimations.append(LayerAnimation(caAnimation, keyframesName, valueList.property(), animationIndex, beginTime));
+ m_uncomittedAnimations.append(LayerAnimation(caAnimation, keyframesName, valueList.property(), animationIndex, timeOffset));
END_BLOCK_OBJC_EXCEPTIONS;
return true;
}
-bool GraphicsLayerCA::createTransformAnimationsFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& keyframesName, double beginTime, const IntSize& boxSize)
+bool GraphicsLayerCA::createTransformAnimationsFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& keyframesName, double timeOffset, const IntSize& boxSize)
{
ASSERT(valueList.property() == AnimatedPropertyWebkitTransform);
@@ -1450,7 +1825,7 @@ bool GraphicsLayerCA::createTransformAnimationsFromKeyframes(const KeyframeValue
if (!validMatrices)
break;
- m_uncomittedAnimations.append(LayerAnimation(caAnimation, keyframesName, valueList.property(), animationIndex, beginTime));
+ m_uncomittedAnimations.append(LayerAnimation(caAnimation, keyframesName, valueList.property(), animationIndex, timeOffset));
}
END_BLOCK_OBJC_EXCEPTIONS;
@@ -1663,25 +2038,42 @@ void GraphicsLayerCA::suspendAnimations(double time)
double t = currentTimeToMediaTime(time ? time : currentTime());
[primaryLayer() setSpeed:0];
[primaryLayer() setTimeOffset:t];
+
+ // Suspend the animations on the clones too.
+ if (LayerMap* layerCloneMap = primaryLayerClones()) {
+ LayerMap::const_iterator end = layerCloneMap->end();
+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
+ CALayer *currLayer = it->second.get();
+ [currLayer setSpeed:0 ];
+ [currLayer setTimeOffset:t];
+ }
+ }
}
void GraphicsLayerCA::resumeAnimations()
{
[primaryLayer() setSpeed:1];
[primaryLayer() setTimeOffset:0];
+
+ // Resume the animations on the clones too.
+ if (LayerMap* layerCloneMap = primaryLayerClones()) {
+ LayerMap::const_iterator end = layerCloneMap->end();
+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
+ CALayer *currLayer = it->second.get();
+ [currLayer setSpeed:1];
+ [currLayer setTimeOffset:0];
+ }
+ }
}
-WebLayer* GraphicsLayerCA::hostLayerForSublayers() const
+CALayer* GraphicsLayerCA::hostLayerForSublayers() const
{
- return m_transformLayer ? m_transformLayer.get() : m_layer.get();
+ return m_structuralLayer.get() ? m_structuralLayer.get() : m_layer.get();
}
-WebLayer* GraphicsLayerCA::layerForSuperlayer() const
+CALayer* GraphicsLayerCA::layerForSuperlayer() const
{
- if (m_transformLayer)
- return m_transformLayer.get();
-
- return m_layer.get();
+ return m_structuralLayer ? m_structuralLayer.get() : m_layer.get();
}
CALayer* GraphicsLayerCA::animatedLayer(AnimatedPropertyID property) const
@@ -1689,6 +2081,11 @@ CALayer* GraphicsLayerCA::animatedLayer(AnimatedPropertyID property) const
return (property == AnimatedPropertyBackgroundColor) ? m_contentsLayer.get() : primaryLayer();
}
+GraphicsLayerCA::LayerMap* GraphicsLayerCA::animatedLayerClones(AnimatedPropertyID property) const
+{
+ return (property == AnimatedPropertyBackgroundColor) ? m_contentsLayerClones.get() : primaryLayerClones();
+}
+
PlatformLayer* GraphicsLayerCA::platformLayer() const
{
return primaryLayer();
@@ -1790,9 +2187,9 @@ void GraphicsLayerCA::swapFromOrToTiledLayer(bool useTiledLayer)
#endif
// move over animations
- moveAnimation(AnimatedPropertyWebkitTransform, oldLayer.get(), m_layer.get());
- moveAnimation(AnimatedPropertyOpacity, oldLayer.get(), m_layer.get());
- moveAnimation(AnimatedPropertyBackgroundColor, oldLayer.get(), m_layer.get());
+ moveOrCopyAnimationsForProperty(Move, AnimatedPropertyWebkitTransform, oldLayer.get(), m_layer.get());
+ moveOrCopyAnimationsForProperty(Move, AnimatedPropertyOpacity, oldLayer.get(), m_layer.get());
+ moveOrCopyAnimationsForProperty(Move, AnimatedPropertyBackgroundColor, oldLayer.get(), m_layer.get());
// need to tell new layer to draw itself
setNeedsDisplay();
@@ -1847,9 +2244,232 @@ void GraphicsLayerCA::setupContentsLayer(CALayer* contentsLayer)
}
}
+CALayer *GraphicsLayerCA::findOrMakeClone(CloneID cloneID, CALayer *sourceLayer, LayerMap* clones, CloneLevel cloneLevel)
+{
+ if (!sourceLayer)
+ return 0;
+
+ CALayer *resultLayer;
+
+ // Add with a dummy value to get an iterator for the insertion position, and a boolean that tells
+ // us whether there's an item there. This technique avoids two hash lookups.
+ RetainPtr<CALayer> dummy;
+ pair<LayerMap::iterator, bool> addResult = clones->add(cloneID, dummy);
+ if (!addResult.second) {
+ // Value was not added, so it exists already.
+ resultLayer = addResult.first->second.get();
+ } else {
+ resultLayer = cloneLayer(sourceLayer, cloneLevel);
+#ifndef NDEBUG
+ [resultLayer setName:[NSString stringWithFormat:@"Clone %d of layer %@", cloneID[0U], sourceLayer]];
+#endif
+ addResult.first->second = resultLayer;
+ }
+
+ return resultLayer;
+}
+
+void GraphicsLayerCA::ensureCloneLayers(CloneID cloneID, CALayer *& primaryLayer, CALayer *& structuralLayer, CALayer *& contentsLayer, CloneLevel cloneLevel)
+{
+ structuralLayer = nil;
+ contentsLayer = nil;
+
+ if (!m_layerClones)
+ m_layerClones = new LayerMap;
+
+ if (!m_structuralLayerClones && m_structuralLayer)
+ m_structuralLayerClones = new LayerMap;
+
+ if (!m_contentsLayerClones && m_contentsLayer)
+ m_contentsLayerClones = new LayerMap;
+
+ primaryLayer = findOrMakeClone(cloneID, m_layer.get(), m_layerClones.get(), cloneLevel);
+ structuralLayer = findOrMakeClone(cloneID, m_structuralLayer.get(), m_structuralLayerClones.get(), cloneLevel);
+ contentsLayer = findOrMakeClone(cloneID, m_contentsLayer.get(), m_contentsLayerClones.get(), cloneLevel);
+}
+
+void GraphicsLayerCA::removeCloneLayers()
+{
+ m_layerClones = 0;
+ m_structuralLayerClones = 0;
+ m_contentsLayerClones = 0;
+}
+
+FloatPoint GraphicsLayerCA::positionForCloneRootLayer() const
+{
+ // This can get called during a sync when we've just removed the m_replicaLayer.
+ if (!m_replicaLayer)
+ return FloatPoint();
+
+ FloatPoint replicaPosition = m_replicaLayer->replicatedLayerPosition();
+ return FloatPoint(replicaPosition.x() + m_anchorPoint.x() * m_size.width(),
+ replicaPosition.y() + m_anchorPoint.y() * m_size.height());
+}
+
+void GraphicsLayerCA::propagateLayerChangeToReplicas()
+{
+ for (GraphicsLayer* currLayer = this; currLayer; currLayer = currLayer->parent()) {
+ GraphicsLayerCA* currLayerCA = static_cast<GraphicsLayerCA*>(currLayer);
+ if (!currLayerCA->hasCloneLayers())
+ break;
+
+ if (currLayerCA->replicaLayer())
+ static_cast<GraphicsLayerCA*>(currLayerCA->replicaLayer())->noteLayerPropertyChanged(ReplicatedLayerChanged);
+ }
+}
+
+CALayer *GraphicsLayerCA::fetchCloneLayers(GraphicsLayer* replicaRoot, ReplicaState& replicaState, CloneLevel cloneLevel)
+{
+ CALayer *primaryLayer;
+ CALayer *structuralLayer;
+ CALayer *contentsLayer;
+ ensureCloneLayers(replicaState.cloneID(), primaryLayer, structuralLayer, contentsLayer, cloneLevel);
+
+ if (m_maskLayer) {
+ CALayer *maskClone = static_cast<GraphicsLayerCA*>(m_maskLayer)->fetchCloneLayers(replicaRoot, replicaState, IntermediateCloneLevel);
+ [primaryLayer setMask:maskClone];
+ }
+
+ if (m_replicatedLayer) {
+ // We are a replica being asked for clones of our layers.
+ CALayer *replicaRoot = replicatedLayerRoot(replicaState);
+ if (!replicaRoot)
+ return nil;
+
+ if (structuralLayer) {
+ [structuralLayer insertSublayer:replicaRoot atIndex:0];
+ return structuralLayer;
+ }
+
+ [primaryLayer insertSublayer:replicaRoot atIndex:0];
+ return primaryLayer;
+ }
+
+ const Vector<GraphicsLayer*>& childLayers = children();
+ NSMutableArray* clonalSublayers = nil;
+
+ CALayer *replicaLayer = nil;
+ if (m_replicaLayer && m_replicaLayer != replicaRoot) {
+ // We have nested replicas. Ask the replica layer for a clone of its contents.
+ replicaState.setBranchType(ReplicaState::ReplicaBranch);
+ replicaLayer = static_cast<GraphicsLayerCA*>(m_replicaLayer)->fetchCloneLayers(replicaRoot, replicaState, RootCloneLevel);
+ replicaState.setBranchType(ReplicaState::ChildBranch);
+ }
+
+ if (replicaLayer || structuralLayer || contentsLayer || childLayers.size() > 0) {
+ clonalSublayers = [[NSMutableArray alloc] init];
+
+ if (structuralLayer) {
+ // Replicas render behind the actual layer content.
+ if (replicaLayer)
+ [clonalSublayers addObject:replicaLayer];
+
+ // Add the primary layer next. Even if we have negative z-order children, the primary layer always comes behind.
+ [clonalSublayers addObject:primaryLayer];
+ } else if (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.
+ [clonalSublayers addObject:contentsLayer];
+ }
+
+ replicaState.push(ReplicaState::ChildBranch);
+
+ size_t numChildren = childLayers.size();
+ for (size_t i = 0; i < numChildren; ++i) {
+ GraphicsLayerCA* curChild = static_cast<GraphicsLayerCA*>(childLayers[i]);
+
+ CALayer *childLayer = curChild->fetchCloneLayers(replicaRoot, replicaState, IntermediateCloneLevel);
+ if (childLayer)
+ [clonalSublayers addObject:childLayer];
+ }
+
+ replicaState.pop();
+
+ [clonalSublayers makeObjectsPerformSelector:@selector(removeFromSuperlayer)];
+ }
+
+ CALayer *result;
+ if (structuralLayer) {
+ [structuralLayer setSublayers:clonalSublayers];
+
+ if (contentsLayer) {
+ // If we have a transform layer, then the contents layer is parented in the
+ // primary layer (which is itself a child of the transform layer).
+ [primaryLayer setSublayers:nil];
+ [primaryLayer addSublayer:contentsLayer];
+ }
+
+ result = structuralLayer;
+ } else {
+ [primaryLayer setSublayers:clonalSublayers];
+ result = primaryLayer;
+ }
+
+ [clonalSublayers release];
+ return result;
+}
+
+CALayer *GraphicsLayerCA::cloneLayer(CALayer *layer, CloneLevel cloneLevel)
+{
+ static Class transformLayerClass = NSClassFromString(@"CATransformLayer");
+ CALayer *newLayer = nil;
+ if ([layer isKindOfClass:transformLayerClass])
+ newLayer = [transformLayerClass layer];
+ else
+ newLayer = [CALayer layer];
+
+ [newLayer setStyle:[NSDictionary dictionaryWithObject:nullActionsDictionary() forKey:@"actions"]];
+
+ [newLayer setPosition:[layer position]];
+ [newLayer setBounds:[layer bounds]];
+ [newLayer setAnchorPoint:[layer anchorPoint]];
+#if HAVE_MODERN_QUARTZCORE
+ [newLayer setAnchorPointZ:[layer anchorPointZ]];
+#endif
+ [newLayer setTransform:[layer transform]];
+ [newLayer setSublayerTransform:[layer sublayerTransform]];
+ [newLayer setContents:[layer contents]];
+ [newLayer setMasksToBounds:[layer masksToBounds]];
+ [newLayer setDoubleSided:[layer isDoubleSided]];
+ [newLayer setOpaque:[layer isOpaque]];
+ [newLayer setBackgroundColor:[layer backgroundColor]];
+
+ if (cloneLevel == IntermediateCloneLevel) {
+ [newLayer setOpacity:[layer opacity]];
+ moveOrCopyAnimationsForProperty(Copy, AnimatedPropertyWebkitTransform, layer, newLayer);
+ moveOrCopyAnimationsForProperty(Copy, AnimatedPropertyOpacity, layer, newLayer);
+ }
+
+ if (showDebugBorders()) {
+ setLayerBorderColor(newLayer, Color(255, 122, 251));
+ [newLayer setBorderWidth:2];
+ }
+
+ return newLayer;
+}
+
void GraphicsLayerCA::setOpacityInternal(float accumulatedOpacity)
{
- [(preserves3D() ? m_layer.get() : primaryLayer()) setOpacity:accumulatedOpacity];
+ LayerMap* layerCloneMap = 0;
+
+ if (preserves3D()) {
+ [m_layer.get() setOpacity:accumulatedOpacity];
+ layerCloneMap = m_layerClones.get();
+ } else {
+ [primaryLayer() setOpacity:accumulatedOpacity];
+ layerCloneMap = primaryLayerClones();
+ }
+
+ if (layerCloneMap) {
+ LayerMap::const_iterator end = layerCloneMap->end();
+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
+ if (m_replicaLayer && isReplicatedRootClone(it->first))
+ continue;
+ CALayer *currLayer = it->second.get();
+ [currLayer setOpacity:m_opacity];
+ }
+ }
}
void GraphicsLayerCA::updateOpacityOnLayer()
@@ -1860,9 +2480,27 @@ void GraphicsLayerCA::updateOpacityOnLayer()
distributeOpacity(parent() ? parent()->accumulatedOpacity() : 1);
#else
[primaryLayer() setOpacity:m_opacity];
+
+ if (LayerMap* layerCloneMap = primaryLayerClones()) {
+ LayerMap::const_iterator end = layerCloneMap->end();
+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
+ if (m_replicaLayer && isReplicatedRootClone(it->first))
+ continue;
+
+ CALayer *currLayer = it->second.get();
+ [currLayer setOpacity:m_opacity];
+ }
+
+ }
#endif
}
+void GraphicsLayerCA::noteSublayersChanged()
+{
+ noteLayerPropertyChanged(ChildrenChanged);
+ propagateLayerChangeToReplicas();
+}
+
void GraphicsLayerCA::noteLayerPropertyChanged(LayerChangeFlags flags)
{
if (!m_uncommittedChanges && m_client)
diff --git a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h
index 7aaf95d..e9f64be 100644
--- a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h
+++ b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -104,22 +104,19 @@ private:
bool hasClosedCaptions() const;
void setClosedCaptionsVisible(bool);
- void setEndTime(float time);
-
- 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&);
+ virtual bool hasAvailableVideoFrame() const;
+
void paint(GraphicsContext*, const IntRect&);
void paintCurrentFrameInContext(GraphicsContext*, const IntRect&);
@@ -176,18 +173,19 @@ private:
Timer<MediaPlayerPrivate> m_seekTimer;
MediaPlayer::NetworkState m_networkState;
MediaPlayer::ReadyState m_readyState;
- bool m_startedPlaying;
- bool m_isStreaming;
- bool m_visible;
IntRect m_rect;
FloatSize m_scaleFactor;
unsigned m_enabledTrackCount;
unsigned m_totalTrackCount;
- bool m_hasUnsupportedTracks;
float m_reportedDuration;
float m_cachedDuration;
float m_timeToRestore;
RetainPtr<QTMovieLayer> m_qtVideoLayer;
+ bool m_startedPlaying;
+ bool m_isStreaming;
+ bool m_visible;
+ bool m_hasUnsupportedTracks;
+ bool m_videoFrameHasDrawn;
#if DRAW_FRAME_RATE
int m_frameCountWhilePlaying;
double m_timeStartedPlaying;
diff --git a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
index dfb5958..dd87bb5 100644
--- a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
+++ b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -204,17 +204,18 @@ MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
, m_seekTimer(this, &MediaPlayerPrivate::seekTimerFired)
, m_networkState(MediaPlayer::Empty)
, m_readyState(MediaPlayer::HaveNothing)
- , m_startedPlaying(false)
- , m_isStreaming(false)
- , m_visible(false)
, m_rect()
, m_scaleFactor(1, 1)
, m_enabledTrackCount(0)
, m_totalTrackCount(0)
+ , m_reportedDuration(-1)
+ , m_cachedDuration(-1)
+ , m_timeToRestore(-1)
+ , m_startedPlaying(false)
+ , m_isStreaming(false)
+ , m_visible(false)
, m_hasUnsupportedTracks(false)
- , m_reportedDuration(-1.0f)
- , m_cachedDuration(-1.0f)
- , m_timeToRestore(-1.0f)
+ , m_videoFrameHasDrawn(false)
#if DRAW_FRAME_RATE
, m_frameCountWhilePlaying(0)
, m_timeStartedPlaying(0)
@@ -449,7 +450,7 @@ void MediaPlayerPrivate::createQTMovieLayer()
// later via acceleratedRenderingStateChanged().
GraphicsLayer* videoGraphicsLayer = m_player->mediaPlayerClient()->mediaPlayerGraphicsLayer(m_player);
if (videoGraphicsLayer)
- videoGraphicsLayer->setContentsToVideo((PlatformLayer *)m_qtVideoLayer.get());
+ videoGraphicsLayer->setContentsToMedia(m_qtVideoLayer.get());
}
#endif
}
@@ -498,6 +499,9 @@ MediaPlayerPrivate::MediaRenderingMode MediaPlayerPrivate::preferredRenderingMod
void MediaPlayerPrivate::setUpVideoRendering()
{
+ if (!isReadyForRendering())
+ return;
+
MediaRenderingMode currentMode = currentRenderingMode();
MediaRenderingMode preferredMode = preferredRenderingMode();
if (currentMode == preferredMode && currentMode != MediaRenderingNone)
@@ -556,6 +560,7 @@ void MediaPlayerPrivate::load(const String& url)
m_player->readyStateChanged();
}
cancelSeek();
+ m_videoFrameHasDrawn = false;
[m_objcObserver.get() setDelayCallbacks:YES];
@@ -651,7 +656,7 @@ void MediaPlayerPrivate::doSeek()
[m_qtMovie.get() setRate:0];
[m_qtMovie.get() setCurrentTime:qttime];
- // restore playback only if not at end, othewise QTMovie will loop
+ // restore playback only if not at end, otherwise QTMovie will loop
float timeAfterSeek = currentTime();
if (oldRate && timeAfterSeek < duration())
[m_qtMovie.get() setRate:oldRate];
@@ -687,10 +692,6 @@ void MediaPlayerPrivate::seekTimerFired(Timer<MediaPlayerPrivate>*)
}
}
-void MediaPlayerPrivate::setEndTime(float)
-{
-}
-
bool MediaPlayerPrivate::paused() const
{
if (!metaDataAvailable())
@@ -765,7 +766,7 @@ void MediaPlayerPrivate::setClosedCaptionsVisible(bool closedCaptionsVisible)
#if USE(ACCELERATED_COMPOSITING) && (!defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD))
if (closedCaptionsVisible && m_qtVideoLayer) {
- // Captions will be rendered upsided down unless we flag the movie as flipped (again). See <rdar://7408440>.
+ // Captions will be rendered upside down unless we flag the movie as flipped (again). See <rdar://7408440>.
[m_qtVideoLayer.get() setGeometryFlipped:YES];
}
#endif
@@ -796,13 +797,6 @@ void MediaPlayerPrivate::setPreservesPitch(bool preservesPitch)
createQTMovie([movieAttributes valueForKey:QTMovieURLAttribute], movieAttributes);
}
-int MediaPlayerPrivate::dataRate() const
-{
- if (!metaDataAvailable())
- return 0;
- return wkQTMovieDataRate(m_qtMovie.get());
-}
-
PassRefPtr<TimeRanges> MediaPlayerPrivate::buffered() const
{
RefPtr<TimeRanges> timeRanges = TimeRanges::create();
@@ -839,11 +833,6 @@ unsigned MediaPlayerPrivate::bytesLoaded() const
return totalBytes() * maxTimeLoaded() / dur;
}
-bool MediaPlayerPrivate::totalBytesKnown() const
-{
- return totalBytes() > 0;
-}
-
unsigned MediaPlayerPrivate::totalBytes() const
{
if (!metaDataAvailable())
@@ -981,7 +970,7 @@ void MediaPlayerPrivate::updateStates()
}
}
- if (isReadyForRendering() && !hasSetUpVideoRendering())
+ if (!hasSetUpVideoRendering())
setUpVideoRendering();
if (seeking())
@@ -1056,8 +1045,11 @@ void MediaPlayerPrivate::didEnd()
// Hang onto the current time and use it as duration from now on since QuickTime is telling us we
// are at the end. Do this because QuickTime sometimes reports one time for duration and stops
- // playback at another time, which causes problems in HTMLMediaElement.
- m_cachedDuration = currentTime();
+ // playback at another time, which causes problems in HTMLMediaElement. QTKit's 'ended' event
+ // fires when playing in reverse so don't update duration when at time zero!
+ float now = currentTime();
+ if (now > 0)
+ m_cachedDuration = now;
updateStates();
m_player->timeChanged();
@@ -1078,14 +1070,27 @@ void MediaPlayerPrivate::setVisible(bool b)
{
if (m_visible != b) {
m_visible = b;
- if (b) {
- if (m_readyState >= MediaPlayer::HaveMetadata)
- setUpVideoRendering();
- } else
+ if (b)
+ setUpVideoRendering();
+ else
tearDownVideoRendering();
}
}
+bool MediaPlayerPrivate::hasAvailableVideoFrame() const
+{
+ // When using a QTMovieLayer return true as soon as the movie reaches QTMovieLoadStatePlayable
+ // because although we don't *know* when the first frame has decoded, by the time we get and
+ // process the notification a frame should have propagated the VisualContext and been set on
+ // the layer.
+ if (currentRenderingMode() == MediaRenderingMovieLayer)
+ return m_readyState >= MediaPlayer::HaveCurrentData;
+
+ // When using the software renderer QuickTime signals that a frame is available so we might as well
+ // wait until we know that a frame has been drawn.
+ return m_videoFrameHasDrawn;
+}
+
void MediaPlayerPrivate::repaint()
{
if (m_hasUnsupportedTracks)
@@ -1100,6 +1105,7 @@ void MediaPlayerPrivate::repaint()
m_timeStartedPlaying = [NSDate timeIntervalSinceReferenceDate];
}
#endif
+ m_videoFrameHasDrawn = true;
m_player->repaint();
}
@@ -1404,7 +1410,7 @@ void MediaPlayerPrivate::acceleratedRenderingStateChanged()
if (currentRenderingMode() == MediaRenderingMovieLayer) {
GraphicsLayer* videoGraphicsLayer = m_player->mediaPlayerClient()->mediaPlayerGraphicsLayer(m_player);
if (videoGraphicsLayer)
- videoGraphicsLayer->setContentsToVideo((PlatformLayer *)m_qtVideoLayer.get());
+ videoGraphicsLayer->setContentsToMedia(m_qtVideoLayer.get());
}
}
#endif
diff --git a/WebCore/platform/graphics/mac/SimpleFontDataMac.mm b/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
index 97a7251..ef7c58f 100644
--- a/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
+++ b/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
@@ -55,8 +55,7 @@ using namespace std;
namespace WebCore {
const float smallCapsFontSizeMultiplier = 0.7f;
-const float contextDPI = 72.0f;
-static inline float scaleEmToUnits(float x, unsigned unitsPerEm) { return x * (contextDPI / (contextDPI * unitsPerEm)); }
+static inline float scaleEmToUnits(float x, unsigned unitsPerEm) { return x / unitsPerEm; }
static bool initFontData(SimpleFontData* fontData)
{
@@ -149,7 +148,6 @@ void SimpleFontData::platformInit()
m_styleGroup = 0;
#endif
#if USE(ATSUI)
- m_ATSUStyleInitialized = false;
m_ATSUMirrors = false;
m_checkedShapesArabic = false;
m_shapesArabic = false;
@@ -318,8 +316,9 @@ void SimpleFontData::platformDestroy()
wkReleaseStyleGroup(m_styleGroup);
#endif
#if USE(ATSUI)
- if (m_ATSUStyleInitialized)
- ATSUDisposeStyle(m_ATSUStyle);
+ HashMap<unsigned, ATSUStyle>::iterator end = m_ATSUStyleMap.end();
+ for (HashMap<unsigned, ATSUStyle>::iterator it = m_ATSUStyleMap.begin(); it != end; ++it)
+ ATSUDisposeStyle(it->second);
#endif
}
@@ -445,13 +444,15 @@ CTFontRef SimpleFontData::getCTFont() const
return m_CTFont.get();
}
-CFDictionaryRef SimpleFontData::getCFStringAttributes(TextRenderingMode textMode) const
+CFDictionaryRef SimpleFontData::getCFStringAttributes(TypesettingFeatures typesettingFeatures) const
{
- if (m_CFStringAttributes)
- return m_CFStringAttributes.get();
+ unsigned key = typesettingFeatures + 1;
+ pair<HashMap<unsigned, RetainPtr<CFDictionaryRef> >::iterator, bool> addResult = m_CFStringAttributes.add(key, RetainPtr<CFDictionaryRef>());
+ RetainPtr<CFDictionaryRef>& attributesDictionary = addResult.first->second;
+ if (!addResult.second)
+ return attributesDictionary.get();
- bool allowKerning = textMode == OptimizeLegibility || textMode == GeometricPrecision;
- bool allowLigatures = platformData().allowsLigatures() || allowKerning;
+ bool allowLigatures = platformData().allowsLigatures() || (typesettingFeatures & Ligatures);
static const int ligaturesNotAllowedValue = 0;
static CFNumberRef ligaturesNotAllowed = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &ligaturesNotAllowedValue);
@@ -459,25 +460,25 @@ CFDictionaryRef SimpleFontData::getCFStringAttributes(TextRenderingMode textMode
static const int ligaturesAllowedValue = 1;
static CFNumberRef ligaturesAllowed = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &ligaturesAllowedValue);
- if (!allowKerning) {
+ if (!(typesettingFeatures & Kerning)) {
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,
+ attributesDictionary.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,
+ attributesDictionary.adoptCF(CFDictionaryCreate(NULL, keysWithKerningEnabled, valuesWithKerningEnabled,
sizeof(keysWithKerningEnabled) / sizeof(*keysWithKerningEnabled),
&kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
}
- return m_CFStringAttributes.get();
+ return attributesDictionary.get();
}
#endif
diff --git a/WebCore/platform/graphics/mac/WebLayer.mm b/WebCore/platform/graphics/mac/WebLayer.mm
index 56b28e6..641d421 100644
--- a/WebCore/platform/graphics/mac/WebLayer.mm
+++ b/WebCore/platform/graphics/mac/WebLayer.mm
@@ -153,6 +153,13 @@ using namespace WebCore;
}
}
+- (void)display
+{
+ [super display];
+ if (m_layerOwner)
+ m_layerOwner->didDisplay(self);
+}
+
- (void)drawInContext:(CGContextRef)context
{
[WebLayer drawContents:m_layerOwner ofLayer:self intoContext:context];
diff --git a/WebCore/platform/graphics/mac/WebTiledLayer.mm b/WebCore/platform/graphics/mac/WebTiledLayer.mm
index a1f5693..97ba233 100644
--- a/WebCore/platform/graphics/mac/WebTiledLayer.mm
+++ b/WebCore/platform/graphics/mac/WebTiledLayer.mm
@@ -92,6 +92,13 @@ using namespace WebCore;
}
}
+- (void)display
+{
+ [super display];
+ if (m_layerOwner)
+ m_layerOwner->didDisplay(self);
+}
+
- (void)drawInContext:(CGContextRef)ctx
{
[WebLayer drawContents:m_layerOwner ofLayer:self intoContext:ctx];
diff --git a/WebCore/platform/graphics/opentype/OpenTypeUtilities.cpp b/WebCore/platform/graphics/opentype/OpenTypeUtilities.cpp
index 3a60160..12ae09d 100644
--- a/WebCore/platform/graphics/opentype/OpenTypeUtilities.cpp
+++ b/WebCore/platform/graphics/opentype/OpenTypeUtilities.cpp
@@ -401,7 +401,7 @@ static size_t renameFontInternal(SharedBuffer* fontData, const String& fontName,
return nameTableSize;
}
-#if PLATFORM(WINCE)
+#if OS(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)
diff --git a/WebCore/platform/graphics/opentype/OpenTypeUtilities.h b/WebCore/platform/graphics/opentype/OpenTypeUtilities.h
index 4c75314..0ef1b2b 100644
--- a/WebCore/platform/graphics/opentype/OpenTypeUtilities.h
+++ b/WebCore/platform/graphics/opentype/OpenTypeUtilities.h
@@ -36,7 +36,7 @@ struct BigEndianUShort;
struct EOTPrefix;
class SharedBuffer;
-#if PLATFORM(WINCE)
+#if OS(WINCE)
typedef unsigned __int8 UInt8;
#endif
diff --git a/WebCore/platform/graphics/openvg/EGLDisplayOpenVG.cpp b/WebCore/platform/graphics/openvg/EGLDisplayOpenVG.cpp
new file mode 100644
index 0000000..3c7eaf2
--- /dev/null
+++ b/WebCore/platform/graphics/openvg/EGLDisplayOpenVG.cpp
@@ -0,0 +1,431 @@
+/*
+ * Copyright (C) Research In Motion Limited 2009-2010. 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 "EGLDisplayOpenVG.h"
+
+#include "EGLUtils.h"
+#include "IntSize.h"
+#include "SurfaceOpenVG.h"
+
+#include <wtf/Assertions.h>
+#include <wtf/StdLibExtras.h>
+
+namespace WebCore {
+
+// Need to typedef this, otherwise DEFINE_STATIC_LOCAL() doesn't swallow it.
+typedef HashMap<EGLDisplay, EGLDisplayOpenVG*> EGLDisplayManagerMap;
+
+// File-static variables.
+static EGLDisplayManagerMap& displayManagers()
+{
+ DEFINE_STATIC_LOCAL(EGLDisplayManagerMap, managers, ());
+ return managers;
+}
+
+static EGLDisplayOpenVG* s_current = 0;
+
+// Static class members.
+
+SurfaceOpenVG* EGLDisplayOpenVG::currentSurface()
+{
+ EGLDisplayManagerMap& managers = displayManagers();
+ EGLDisplay currentDisplay = eglGetCurrentDisplay();
+
+ if (currentDisplay == EGL_NO_DISPLAY || !managers.contains(currentDisplay))
+ return 0;
+
+ EGLDisplayOpenVG* displayManager = managers.get(currentDisplay);
+ EGLSurface currentSurface = eglGetCurrentSurface(EGL_DRAW);
+
+ if (currentSurface == EGL_NO_SURFACE || !displayManager->m_platformSurfaces.contains(currentSurface))
+ return 0;
+
+ return displayManager->m_platformSurfaces.get(currentSurface);
+}
+
+void EGLDisplayOpenVG::registerPlatformSurface(SurfaceOpenVG* platformSurface)
+{
+ EGLDisplayOpenVG* displayManager = EGLDisplayOpenVG::forDisplay(platformSurface->eglDisplay());
+ displayManager->m_platformSurfaces.set(platformSurface->eglSurface(), platformSurface);
+}
+
+void EGLDisplayOpenVG::unregisterPlatformSurface(SurfaceOpenVG* platformSurface)
+{
+ EGLDisplayOpenVG* displayManager = EGLDisplayOpenVG::forDisplay(platformSurface->eglDisplay());
+ displayManager->m_platformSurfaces.remove(platformSurface->eglSurface());
+}
+
+void EGLDisplayOpenVG::setCurrentDisplay(const EGLDisplay& display)
+{
+ s_current = EGLDisplayOpenVG::forDisplay(display);
+}
+
+EGLDisplayOpenVG* EGLDisplayOpenVG::current()
+{
+ if (!s_current) {
+ EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ eglInitialize(display, 0, 0);
+ ASSERT_EGL_NO_ERROR();
+
+ s_current = EGLDisplayOpenVG::forDisplay(display);
+ }
+ return s_current;
+}
+
+EGLDisplayOpenVG* EGLDisplayOpenVG::forDisplay(const EGLDisplay& display)
+{
+ EGLDisplayManagerMap& managers = displayManagers();
+
+ if (!managers.contains(display))
+ managers.set(display, new EGLDisplayOpenVG(display));
+
+ return managers.get(display);
+}
+
+
+// Object/instance members.
+
+EGLDisplayOpenVG::EGLDisplayOpenVG(const EGLDisplay& display)
+ : m_display(display)
+ , m_sharedPlatformSurface(0)
+ , m_pbufferConfigId(0)
+ , m_windowConfigId(0)
+{
+ eglBindAPI(EGL_OPENVG_API);
+ ASSERT_EGL_NO_ERROR();
+}
+
+EGLDisplayOpenVG::~EGLDisplayOpenVG()
+{
+ eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ ASSERT_EGL_NO_ERROR();
+
+ delete m_sharedPlatformSurface;
+
+ HashMap<EGLSurface, EGLint>::const_iterator end = m_surfaceConfigIds.end();
+ for (HashMap<EGLSurface, EGLint>::const_iterator it = m_surfaceConfigIds.begin(); it != end; ++it)
+ destroySurface((*it).first);
+
+ eglTerminate(m_display);
+ ASSERT_EGL_NO_ERROR();
+}
+
+void EGLDisplayOpenVG::setDefaultPbufferConfig(const EGLConfig& config)
+{
+ EGLint configId;
+ EGLBoolean success = eglGetConfigAttrib(m_display, config, EGL_CONFIG_ID, &configId);
+ ASSERT(success == EGL_TRUE);
+ ASSERT(configId != EGL_BAD_ATTRIBUTE);
+
+ m_pbufferConfigId = configId;
+}
+
+EGLConfig EGLDisplayOpenVG::defaultPbufferConfig()
+{
+ EGLConfig config;
+ EGLint numConfigs;
+
+ // Hopefully the client will have set the pbuffer config of its choice
+ // by now - if not, use a 32-bit generic one as default.
+ if (!m_pbufferConfigId) {
+ static const EGLint configAttribs[] = {
+ EGL_RED_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_ALPHA_SIZE, 8,
+ EGL_ALPHA_MASK_SIZE, 1,
+ EGL_LUMINANCE_SIZE, EGL_DONT_CARE,
+ EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
+ EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT,
+ EGL_NONE
+ };
+ eglChooseConfig(m_display, configAttribs, &config, 1, &numConfigs);
+ } else {
+ const EGLint configAttribs[] = {
+ EGL_CONFIG_ID, m_pbufferConfigId,
+ EGL_NONE
+ };
+ eglChooseConfig(m_display, configAttribs, &config, 1, &numConfigs);
+ }
+
+ ASSERT_EGL_NO_ERROR();
+ ASSERT(numConfigs == 1);
+ return config;
+}
+
+void EGLDisplayOpenVG::setDefaultWindowConfig(const EGLConfig& config)
+{
+ EGLint configId;
+ EGLBoolean success = eglGetConfigAttrib(m_display, config, EGL_CONFIG_ID, &configId);
+ ASSERT(success == EGL_TRUE);
+ ASSERT(configId != EGL_BAD_ATTRIBUTE);
+
+ m_windowConfigId = configId;
+}
+
+EGLConfig EGLDisplayOpenVG::defaultWindowConfig()
+{
+ EGLConfig config;
+ EGLint numConfigs;
+
+ // Hopefully the client will have set the window config of its choice
+ // by now - if not, use a 32-bit generic one as default.
+ if (!m_windowConfigId) {
+ static const EGLint configAttribs[] = {
+ EGL_RED_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_ALPHA_SIZE, 8,
+ EGL_ALPHA_MASK_SIZE, 1,
+ EGL_LUMINANCE_SIZE, EGL_DONT_CARE,
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+ EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT,
+ EGL_NONE
+ };
+ eglChooseConfig(m_display, configAttribs, &config, 1, &numConfigs);
+ } else {
+ const EGLint configAttribs[] = {
+ EGL_CONFIG_ID, m_windowConfigId,
+ EGL_NONE
+ };
+ eglChooseConfig(m_display, configAttribs, &config, 1, &numConfigs);
+ }
+
+ ASSERT_EGL_NO_ERROR();
+ ASSERT(numConfigs == 1);
+ return config;
+}
+
+SurfaceOpenVG* EGLDisplayOpenVG::sharedPlatformSurface()
+{
+ if (!m_sharedPlatformSurface) {
+ // The shared surface doesn't need to be drawn on, it just exists so
+ // that we can always make the shared context current (which in turn is
+ // the owner of long-living resources such as images, paths and fonts).
+ // We'll just make the shared surface as small as possible: 1x1 pixel.
+ EGLConfig config = defaultPbufferConfig();
+ EGLSurface surface = createPbufferSurface(IntSize(1, 1), config);
+
+ EGLContext context = eglCreateContext(m_display, config, EGL_NO_CONTEXT, 0);
+ ASSERT_EGL_NO_ERROR();
+ m_contexts.set(m_surfaceConfigIds.get(surface), context);
+
+ m_sharedPlatformSurface = new SurfaceOpenVG;
+ m_sharedPlatformSurface->m_eglDisplay = m_display;
+ m_sharedPlatformSurface->m_eglSurface = surface;
+ m_sharedPlatformSurface->m_eglContext = context;
+ m_platformSurfaces.set(surface, m_sharedPlatformSurface); // a.k.a. registerPlatformSurface()
+ }
+ return m_sharedPlatformSurface;
+}
+
+EGLSurface EGLDisplayOpenVG::createPbufferSurface(const IntSize& size, const EGLConfig& config, EGLint* errorCode)
+{
+ const EGLint attribList[] = {
+ EGL_WIDTH, size.width(),
+ EGL_HEIGHT, size.height(),
+ EGL_NONE
+ };
+ EGLSurface surface = eglCreatePbufferSurface(m_display, config, attribList);
+
+ if (errorCode)
+ *errorCode = eglGetError();
+ else
+ ASSERT_EGL_NO_ERROR();
+
+ if (surface == EGL_NO_SURFACE)
+ return EGL_NO_SURFACE;
+
+ EGLint surfaceConfigId;
+ EGLBoolean success = eglGetConfigAttrib(m_display, config, EGL_CONFIG_ID, &surfaceConfigId);
+ ASSERT(success == EGL_TRUE);
+ ASSERT(surfaceConfigId != EGL_BAD_ATTRIBUTE);
+
+ ASSERT(!m_surfaceConfigIds.contains(surface));
+ m_surfaceConfigIds.set(surface, surfaceConfigId);
+ return surface;
+}
+
+EGLSurface EGLDisplayOpenVG::surfaceForWindow(EGLNativeWindowType wId, const EGLConfig& config)
+{
+ if (m_windowSurfaces.contains(wId))
+ return m_windowSurfaces.get(wId);
+
+ EGLSurface surface = eglCreateWindowSurface(m_display, config, wId, 0);
+ ASSERT_EGL_NO_ERROR();
+
+ EGLint surfaceConfigId;
+ EGLBoolean success = eglGetConfigAttrib(m_display, config, EGL_CONFIG_ID, &surfaceConfigId);
+ ASSERT(success == EGL_TRUE);
+ ASSERT(surfaceConfigId != EGL_BAD_ATTRIBUTE);
+
+ ASSERT(!m_surfaceConfigIds.contains(surface));
+ m_surfaceConfigIds.set(surface, surfaceConfigId);
+ return surface;
+}
+
+bool EGLDisplayOpenVG::surfacesCompatible(const EGLSurface& surface, const EGLSurface& otherSurface)
+{
+ if (surface == EGL_NO_SURFACE || otherSurface == EGL_NO_SURFACE)
+ return false;
+
+ // Currently, we assume that all surfaces known to this object are
+ // context-compatible to each other (which is reasonable to assume,
+ // otherwise eglCreateContext() would fail with EGL_BAD_MATCH for shared
+ // context compatibility anyways.
+ return m_surfaceConfigIds.contains(surface) && m_surfaceConfigIds.contains(otherSurface);
+}
+
+void EGLDisplayOpenVG::destroySurface(const EGLSurface& surface)
+{
+ ASSERT(surface != EGL_NO_SURFACE);
+
+ if (eglGetCurrentSurface(EGL_DRAW) == surface) {
+ eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ ASSERT_EGL_NO_ERROR();
+ }
+
+ // Destroy the context associated to the surface, if we already created one.
+ if (m_surfaceConfigIds.contains(surface)) {
+ EGLint surfaceConfigId = m_surfaceConfigIds.take(surface); // take = get and remove
+ bool isContextReferenced = false;
+
+ if (m_compatibleConfigIds.contains(surfaceConfigId))
+ surfaceConfigId = m_compatibleConfigIds.get(surfaceConfigId);
+
+ HashMap<EGLSurface, EGLint>::iterator end = m_surfaceConfigIds.end();
+
+ // ...but only if there's no other surfaces associated to that context.
+ for (HashMap<EGLSurface, EGLint>::iterator it = m_surfaceConfigIds.begin(); it != end; ++it) {
+ if ((*it).second == surfaceConfigId) {
+ isContextReferenced = true;
+ break;
+ }
+ }
+ if (!isContextReferenced && m_contexts.contains(surfaceConfigId)) {
+ EGLContext context = m_contexts.take(surfaceConfigId);
+ eglDestroyContext(m_display, context);
+ ASSERT_EGL_NO_ERROR();
+ }
+ }
+
+ m_platformSurfaces.remove(surface);
+
+ HashMap<EGLNativeWindowType, EGLSurface>::iterator end = m_windowSurfaces.end();
+ for (HashMap<EGLNativeWindowType, EGLSurface>::iterator it = m_windowSurfaces.begin(); it != end; ++it) {
+ if ((*it).second == surface) {
+ m_windowSurfaces.remove(it);
+ break;
+ }
+ }
+
+ eglDestroySurface(m_display, surface);
+ ASSERT_EGL_NO_ERROR();
+}
+
+EGLContext EGLDisplayOpenVG::contextForSurface(const EGLSurface& surface)
+{
+ ASSERT(surface != EGL_NO_SURFACE);
+
+ if (m_platformSurfaces.contains(surface))
+ return m_platformSurfaces.get(surface)->eglContext();
+
+ eglBindAPI(EGL_OPENVG_API);
+ ASSERT_EGL_NO_ERROR();
+
+ EGLint surfaceConfigId;
+
+ if (m_surfaceConfigIds.contains(surface))
+ surfaceConfigId = m_surfaceConfigIds.get(surface);
+ else {
+ // Retrieve the same EGL config for context creation that was used to
+ // create the the EGL surface.
+ EGLBoolean success = eglQuerySurface(m_display, surface, EGL_CONFIG_ID, &surfaceConfigId);
+ ASSERT(success == EGL_TRUE);
+ ASSERT(surfaceConfigId != EGL_BAD_ATTRIBUTE);
+
+ m_surfaceConfigIds.set(surface, surfaceConfigId);
+ }
+
+ if (m_compatibleConfigIds.contains(surfaceConfigId))
+ surfaceConfigId = m_compatibleConfigIds.get(surfaceConfigId);
+
+ if (m_contexts.contains(surfaceConfigId))
+ return m_contexts.get(surfaceConfigId);
+
+ if (!m_sharedPlatformSurface) // shared context has not been created yet
+ sharedPlatformSurface(); // creates the shared surface & context
+
+ EGLDisplay currentDisplay = eglGetCurrentDisplay();
+ EGLSurface currentReadSurface = eglGetCurrentSurface(EGL_READ);
+ EGLSurface currentDrawSurface = eglGetCurrentSurface(EGL_DRAW);
+ EGLContext currentContext = eglGetCurrentContext();
+
+ // Before creating a new context, let's try whether an existing one
+ // is compatible with the surface. EGL doesn't give us a different way
+ // to check context/surface compatibility than trying it out, so let's
+ // do just that.
+ HashMap<EGLint, EGLContext>::iterator end = m_contexts.end();
+
+ for (HashMap<EGLint, EGLContext>::iterator it = m_contexts.begin(); it != end; ++it) {
+ eglMakeCurrent(m_display, surface, surface, (*it).second);
+ if (eglGetError() == EGL_SUCCESS) {
+ // Restore previous surface/context.
+ if (currentContext != EGL_NO_CONTEXT) {
+ eglMakeCurrent(currentDisplay, currentReadSurface, currentDrawSurface, currentContext);
+ ASSERT_EGL_NO_ERROR();
+ }
+ // Cool, surface is compatible to one of our existing contexts.
+ m_compatibleConfigIds.set(surfaceConfigId, (*it).first);
+ return (*it).second;
+ }
+ }
+ // Restore previous surface/context.
+ if (currentContext != EGL_NO_CONTEXT) {
+ eglMakeCurrent(currentDisplay, currentReadSurface, currentDrawSurface, currentContext);
+ ASSERT_EGL_NO_ERROR();
+ }
+
+ EGLConfig config;
+ EGLint numConfigs;
+
+ const EGLint configAttribs[] = {
+ EGL_CONFIG_ID, surfaceConfigId,
+ EGL_NONE
+ };
+
+ eglChooseConfig(m_display, configAttribs, &config, 1, &numConfigs);
+ ASSERT_EGL_NO_ERROR();
+ ASSERT(numConfigs == 1);
+
+ // We share all of the images and paths amongst the different contexts,
+ // so that they can be used in all of them. Resources that are created
+ // while m_sharedPlatformSurface->context() is current will be
+ // accessible from all other contexts, but are not restricted to the
+ // lifetime of those contexts.
+ EGLContext context = eglCreateContext(m_display, config, m_sharedPlatformSurface->eglContext(), 0);
+ ASSERT_EGL_NO_ERROR();
+
+ ASSERT(!m_contexts.contains(surfaceConfigId));
+ m_contexts.set(surfaceConfigId, context);
+ return context;
+}
+
+}
diff --git a/WebCore/platform/graphics/openvg/EGLDisplayOpenVG.h b/WebCore/platform/graphics/openvg/EGLDisplayOpenVG.h
new file mode 100644
index 0000000..fd8353d
--- /dev/null
+++ b/WebCore/platform/graphics/openvg/EGLDisplayOpenVG.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) Research In Motion Limited 2009-2010. 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 EGLDisplayOpenVG_h
+#define EGLDisplayOpenVG_h
+
+#include <egl.h>
+#include <wtf/HashMap.h>
+
+namespace WebCore {
+
+class IntSize;
+class SurfaceOpenVG;
+
+class EGLDisplayOpenVG {
+public:
+ friend class SurfaceOpenVG;
+
+ static SurfaceOpenVG* currentSurface();
+ static void setCurrentDisplay(const EGLDisplay&);
+ static EGLDisplayOpenVG* current();
+ static EGLDisplayOpenVG* forDisplay(const EGLDisplay&);
+
+ void setDefaultPbufferConfig(const EGLConfig&);
+ EGLConfig defaultPbufferConfig();
+ void setDefaultWindowConfig(const EGLConfig&);
+ EGLConfig defaultWindowConfig();
+
+ EGLDisplay display() const { return m_display; }
+ SurfaceOpenVG* sharedPlatformSurface();
+
+ /** Creates a pbuffer surface using the given config. If no surface
+ * could be created, EGL_NO_SURFACE is returned and errors can be
+ * checked with the value that is written to the errorCode parameter
+ * If no surface could be created and errorCode is zero, this method
+ * will trigger an assertion by itself. */
+ EGLSurface createPbufferSurface(const IntSize&, const EGLConfig&, EGLint* errorCode = 0);
+
+ EGLSurface surfaceForWindow(EGLNativeWindowType, const EGLConfig&);
+
+ bool surfacesCompatible(const EGLSurface&, const EGLSurface&);
+
+ /** Destroy the surface and its corresponding context (unless another
+ * surface is still using the same context, in which case the context
+ * is not destroyed). */
+ void destroySurface(const EGLSurface&);
+
+ /** Return the context corresponding to the surface.
+ * If no corresponding context exists, one is created automatically. */
+ EGLContext contextForSurface(const EGLSurface&);
+
+private:
+ static void registerPlatformSurface(SurfaceOpenVG*);
+ static void unregisterPlatformSurface(SurfaceOpenVG*);
+
+ EGLDisplayOpenVG(const EGLDisplay& display);
+ ~EGLDisplayOpenVG();
+
+ EGLDisplay m_display;
+ SurfaceOpenVG* m_sharedPlatformSurface;
+ EGLint m_pbufferConfigId;
+ EGLint m_windowConfigId;
+
+ HashMap<EGLSurface, SurfaceOpenVG*> m_platformSurfaces;
+ HashMap<EGLNativeWindowType, EGLSurface> m_windowSurfaces;
+ HashMap<EGLSurface, EGLint> m_surfaceConfigIds;
+ HashMap<EGLint, EGLint> m_compatibleConfigIds;
+ HashMap<EGLint, EGLContext> m_contexts;
+};
+
+}
+
+#endif
diff --git a/WebCore/platform/graphics/openvg/EGLUtils.h b/WebCore/platform/graphics/openvg/EGLUtils.h
new file mode 100644
index 0000000..6f5d793
--- /dev/null
+++ b/WebCore/platform/graphics/openvg/EGLUtils.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) Research In Motion Limited 2009-2010. 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 EGLUtils_h
+#define EGLUtils_h
+
+#include <egl.h>
+#include <wtf/Assertions.h>
+
+static inline const char* toEGLErrorConstant(EGLint error)
+{
+ switch (error) {
+ case EGL_NOT_INITIALIZED:
+ return "EGL_NOT_INITIALIZED";
+ case EGL_BAD_ACCESS:
+ return "EGL_BAD_ACCESS";
+ case EGL_BAD_ALLOC:
+ return "EGL_BAD_ALLOC";
+ case EGL_BAD_ATTRIBUTE:
+ return "EGL_BAD_ATTRIBUTE";
+ case EGL_BAD_CONTEXT:
+ return "EGL_BAD_CONTEXT";
+ case EGL_BAD_CONFIG:
+ return "EGL_BAD_CONFIG";
+ case EGL_BAD_CURRENT_SURFACE:
+ return "EGL_BAD_CURRENT_SURFACE";
+ case EGL_BAD_DISPLAY:
+ return "EGL_BAD_DISPLAY";
+ case EGL_BAD_SURFACE:
+ return "EGL_BAD_SURFACE";
+ case EGL_BAD_MATCH:
+ return "EGL_BAD_MATCH";
+ case EGL_BAD_PARAMETER:
+ return "EGL_BAD_PARAMETER";
+ case EGL_BAD_NATIVE_PIXMAP:
+ return "EGL_BAD_NATIVE_PIXMAP";
+ case EGL_BAD_NATIVE_WINDOW:
+ return "EGL_BAD_NATIVE_WINDOW";
+ case EGL_CONTEXT_LOST:
+ return "EGL_CONTEXT_LOST";
+ default:
+ return "UNKNOWN_ERROR";
+ }
+}
+
+#if ASSERT_DISABLED
+#define ASSERT_EGL_NO_ERROR() ((void)0)
+#else
+#define ASSERT_EGL_NO_ERROR() do { \
+ EGLint eglErrorCode = eglGetError(); \
+ ASSERT_WITH_MESSAGE(eglErrorCode == EGL_SUCCESS, "Found %s", toEGLErrorConstant(eglErrorCode)); \
+} while (0)
+#endif
+
+#endif
diff --git a/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp b/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp
new file mode 100644
index 0000000..5ed892c
--- /dev/null
+++ b/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp
@@ -0,0 +1,566 @@
+/*
+ * Copyright (C) Research In Motion Limited 2009-2010. 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 "GraphicsContext.h"
+
+#include "GraphicsContextPrivate.h"
+#include "NotImplemented.h"
+#include "PainterOpenVG.h"
+#include "SurfaceOpenVG.h"
+#include "TransformationMatrix.h"
+
+#include <wtf/Assertions.h>
+#include <wtf/MathExtras.h>
+#include <wtf/UnusedParam.h>
+#include <wtf/Vector.h>
+
+#if PLATFORM(EGL)
+#include "EGLDisplayOpenVG.h"
+#include "EGLUtils.h"
+#include <egl.h>
+#endif
+
+namespace WebCore {
+
+// typedef'ing doesn't work, let's inherit from PainterOpenVG instead
+class GraphicsContextPlatformPrivate : public PainterOpenVG {
+public:
+ GraphicsContextPlatformPrivate(SurfaceOpenVG* surface)
+ : PainterOpenVG(surface)
+ {
+ }
+};
+
+GraphicsContext::GraphicsContext(SurfaceOpenVG* surface)
+ : m_common(createGraphicsContextPrivate())
+ , m_data(surface ? new GraphicsContextPlatformPrivate(surface) : 0)
+{
+ setPaintingDisabled(!surface);
+}
+
+GraphicsContext::~GraphicsContext()
+{
+ destroyGraphicsContextPrivate(m_common);
+ delete m_data;
+}
+
+PlatformGraphicsContext* GraphicsContext::platformContext() const
+{
+ if (paintingDisabled())
+ return 0;
+
+ return m_data->baseSurface();
+}
+
+TransformationMatrix GraphicsContext::getCTM() const
+{
+ if (paintingDisabled())
+ return TransformationMatrix();
+
+ return m_data->transformationMatrix();
+}
+
+void GraphicsContext::savePlatformState()
+{
+ if (paintingDisabled())
+ return;
+
+ m_data->save();
+}
+
+void GraphicsContext::restorePlatformState()
+{
+ if (paintingDisabled())
+ return;
+
+ m_data->restore();
+}
+
+void GraphicsContext::drawRect(const IntRect& rect)
+{
+ if (paintingDisabled())
+ return;
+
+ m_data->drawRect(rect);
+}
+
+void GraphicsContext::drawLine(const IntPoint& from, const IntPoint& to)
+{
+ if (paintingDisabled())
+ return;
+
+ m_data->drawLine(from, to);
+}
+
+/**
+ * Draw the largest ellipse that fits into the given rectangle.
+ */
+void GraphicsContext::drawEllipse(const IntRect& rect)
+{
+ if (paintingDisabled())
+ return;
+
+ m_data->drawEllipse(rect);
+}
+
+void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSpan)
+{
+ if (paintingDisabled())
+ return;
+
+ m_data->drawArc(rect, startAngle, angleSpan, VG_STROKE_PATH);
+}
+
+void GraphicsContext::drawConvexPolygon(size_t numPoints, const FloatPoint* points, bool shouldAntialias)
+{
+ if (paintingDisabled())
+ return;
+
+ m_data->drawPolygon(numPoints, points);
+
+ UNUSED_PARAM(shouldAntialias); // FIXME
+}
+
+void GraphicsContext::fillPath()
+{
+ if (paintingDisabled())
+ return;
+
+ notImplemented();
+}
+
+void GraphicsContext::strokePath()
+{
+ if (paintingDisabled())
+ return;
+
+ notImplemented();
+}
+
+void GraphicsContext::fillRect(const FloatRect& rect)
+{
+ if (paintingDisabled())
+ return;
+
+ m_data->drawRect(rect, VG_FILL_PATH);
+}
+
+void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorSpace colorSpace)
+{
+ if (paintingDisabled())
+ return;
+
+ Color oldColor = m_data->fillColor();
+ m_data->setFillColor(color);
+ m_data->drawRect(rect, VG_FILL_PATH);
+ m_data->setFillColor(oldColor);
+
+ UNUSED_PARAM(colorSpace); // FIXME
+}
+
+void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color, ColorSpace colorSpace)
+{
+ if (paintingDisabled())
+ return;
+
+ Color oldColor = m_data->fillColor();
+ m_data->setFillColor(color);
+ m_data->drawRoundedRect(rect, topLeft, topRight, bottomLeft, bottomRight, VG_FILL_PATH);
+ m_data->setFillColor(oldColor);
+
+ UNUSED_PARAM(colorSpace); // FIXME
+}
+
+void GraphicsContext::beginPath()
+{
+ if (paintingDisabled())
+ return;
+
+ notImplemented();
+}
+
+void GraphicsContext::addPath(const Path& path)
+{
+ if (paintingDisabled())
+ return;
+
+ notImplemented();
+}
+
+void GraphicsContext::clip(const FloatRect& rect)
+{
+ if (paintingDisabled())
+ return;
+
+ m_data->intersectClipRect(rect);
+}
+
+void GraphicsContext::clipPath(WindRule clipRule)
+{
+ if (paintingDisabled())
+ return;
+
+ notImplemented();
+ UNUSED_PARAM(clipRule);
+}
+
+void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int offset, const Color& color)
+{
+ if (paintingDisabled())
+ return;
+
+ if (rects.isEmpty())
+ return;
+
+ // FIXME: We just unite all focus ring rects into one for now.
+ // We should outline the edge of the full region.
+ offset += (width - 1) / 2;
+ IntRect finalFocusRect;
+
+ for (unsigned i = 0; i < rects.size(); i++) {
+ IntRect focusRect = rects[i];
+ focusRect.inflate(offset);
+ finalFocusRect.unite(focusRect);
+ }
+
+ StrokeStyle oldStyle = m_data->strokeStyle();
+ Color oldStrokeColor = m_data->strokeColor();
+ m_data->setStrokeStyle(DashedStroke);
+ m_data->setStrokeColor(color);
+ strokeRect(FloatRect(finalFocusRect), 1.f);
+ m_data->setStrokeStyle(oldStyle);
+ m_data->setStrokeColor(oldStrokeColor);
+}
+
+void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool printing)
+{
+ if (paintingDisabled())
+ return;
+
+ if (width <= 0)
+ return;
+
+ StrokeStyle oldStyle = m_data->strokeStyle();
+ m_data->setStrokeStyle(SolidStroke);
+ drawLine(origin, origin + IntSize(width, 0));
+ m_data->setStrokeStyle(oldStyle);
+
+ UNUSED_PARAM(printing);
+}
+
+void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint& origin, int width, bool grammar)
+{
+ if (paintingDisabled())
+ return;
+
+ notImplemented();
+ UNUSED_PARAM(origin);
+ UNUSED_PARAM(width);
+ UNUSED_PARAM(grammar);
+}
+
+FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect)
+{
+ if (paintingDisabled())
+ return FloatRect();
+
+ return FloatRect(enclosingIntRect(m_data->transformationMatrix().mapRect(rect)));
+}
+
+void GraphicsContext::setPlatformShadow(const IntSize& size, int blur, const Color& color, ColorSpace colorSpace)
+{
+ if (paintingDisabled())
+ return;
+
+ notImplemented();
+ UNUSED_PARAM(size);
+ UNUSED_PARAM(blur);
+ UNUSED_PARAM(color);
+ UNUSED_PARAM(colorSpace);
+}
+
+void GraphicsContext::clearPlatformShadow()
+{
+ if (paintingDisabled())
+ return;
+
+ notImplemented();
+}
+
+void GraphicsContext::beginTransparencyLayer(float opacity)
+{
+ if (paintingDisabled())
+ return;
+
+ notImplemented();
+ UNUSED_PARAM(opacity);
+}
+
+void GraphicsContext::endTransparencyLayer()
+{
+ if (paintingDisabled())
+ return;
+
+ notImplemented();
+}
+
+void GraphicsContext::clearRect(const FloatRect& rect)
+{
+ if (paintingDisabled())
+ return;
+
+ CompositeOperator op = m_data->compositeOperation();
+ m_data->setCompositeOperation(CompositeClear);
+ m_data->drawRect(rect, VG_FILL_PATH);
+ m_data->setCompositeOperation(op);
+}
+
+void GraphicsContext::strokeRect(const FloatRect& rect)
+{
+ if (paintingDisabled())
+ return;
+
+ m_data->drawRect(rect, VG_STROKE_PATH);
+}
+
+void GraphicsContext::strokeRect(const FloatRect& rect, float lineWidth)
+{
+ if (paintingDisabled())
+ return;
+
+ float oldThickness = m_data->strokeThickness();
+ m_data->setStrokeThickness(lineWidth);
+ m_data->drawRect(rect, VG_STROKE_PATH);
+ m_data->setStrokeThickness(oldThickness);
+}
+
+void GraphicsContext::setLineCap(LineCap lc)
+{
+ if (paintingDisabled())
+ return;
+
+ m_data->setLineCap(lc);
+}
+
+void GraphicsContext::setLineDash(const DashArray& dashes, float dashOffset)
+{
+ if (paintingDisabled())
+ return;
+
+ m_data->setLineDash(dashes, dashOffset);
+}
+
+void GraphicsContext::setLineJoin(LineJoin lj)
+{
+ if (paintingDisabled())
+ return;
+
+ m_data->setLineJoin(lj);
+}
+
+void GraphicsContext::setMiterLimit(float limit)
+{
+ if (paintingDisabled())
+ return;
+
+ m_data->setMiterLimit(limit);
+}
+
+void GraphicsContext::setAlpha(float opacity)
+{
+ if (paintingDisabled())
+ return;
+
+ m_data->setOpacity(opacity);
+}
+
+void GraphicsContext::setCompositeOperation(CompositeOperator op)
+{
+ if (paintingDisabled())
+ return;
+
+ m_data->setCompositeOperation(op);
+}
+
+void GraphicsContext::clip(const Path& path)
+{
+ if (paintingDisabled())
+ return;
+
+ notImplemented();
+ UNUSED_PARAM(path);
+}
+
+void GraphicsContext::canvasClip(const Path& path)
+{
+ clip(path);
+}
+
+void GraphicsContext::clipOut(const Path& path)
+{
+ if (paintingDisabled())
+ return;
+
+ notImplemented();
+ UNUSED_PARAM(path);
+}
+
+void GraphicsContext::scale(const FloatSize& scaleFactors)
+{
+ if (paintingDisabled())
+ return;
+
+ m_data->scale(scaleFactors);
+}
+
+void GraphicsContext::rotate(float radians)
+{
+ if (paintingDisabled())
+ return;
+
+ m_data->rotate(radians);
+}
+
+void GraphicsContext::translate(float dx, float dy)
+{
+ if (paintingDisabled())
+ return;
+
+ m_data->translate(dx, dy);
+}
+
+IntPoint GraphicsContext::origin()
+{
+ if (paintingDisabled())
+ return IntPoint();
+
+ TransformationMatrix matrix = m_data->transformationMatrix();
+ return IntPoint(roundf(matrix.m41()), roundf(matrix.m42()));
+}
+
+void GraphicsContext::clipOut(const IntRect& rect)
+{
+ if (paintingDisabled())
+ return;
+
+ notImplemented();
+ UNUSED_PARAM(rect);
+}
+
+void GraphicsContext::clipOutEllipseInRect(const IntRect& rect)
+{
+ if (paintingDisabled())
+ return;
+
+ notImplemented();
+ UNUSED_PARAM(rect);
+}
+
+void GraphicsContext::clipToImageBuffer(const FloatRect& rect, const ImageBuffer* imageBuffer)
+{
+ if (paintingDisabled())
+ return;
+
+ notImplemented();
+ UNUSED_PARAM(rect);
+ UNUSED_PARAM(imageBuffer);
+}
+
+void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness)
+{
+ if (paintingDisabled())
+ return;
+
+ notImplemented();
+ UNUSED_PARAM(rect);
+ UNUSED_PARAM(thickness);
+}
+
+void GraphicsContext::concatCTM(const TransformationMatrix& transform)
+{
+ if (paintingDisabled())
+ return;
+
+ m_data->concatTransformationMatrix(transform);
+}
+
+void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect)
+{
+ notImplemented();
+ UNUSED_PARAM(link);
+ UNUSED_PARAM(destRect);
+}
+
+void GraphicsContext::setPlatformStrokeColor(const Color& color, ColorSpace colorSpace)
+{
+ if (paintingDisabled())
+ return;
+
+ m_data->setStrokeColor(color);
+
+ UNUSED_PARAM(colorSpace); // FIXME
+}
+
+void GraphicsContext::setPlatformStrokeStyle(const StrokeStyle& strokeStyle)
+{
+ if (paintingDisabled())
+ return;
+
+ m_data->setStrokeStyle(strokeStyle);
+}
+
+void GraphicsContext::setPlatformStrokeThickness(float thickness)
+{
+ if (paintingDisabled())
+ return;
+
+ m_data->setStrokeThickness(thickness);
+}
+
+void GraphicsContext::setPlatformFillColor(const Color& color, ColorSpace colorSpace)
+{
+ if (paintingDisabled())
+ return;
+
+ m_data->setFillColor(color);
+
+ UNUSED_PARAM(colorSpace); // FIXME
+}
+
+void GraphicsContext::setPlatformShouldAntialias(bool enable)
+{
+ if (paintingDisabled())
+ return;
+
+ m_data->setAntialiasingEnabled(enable);
+}
+
+void GraphicsContext::setImageInterpolationQuality(InterpolationQuality)
+{
+ notImplemented();
+}
+
+InterpolationQuality GraphicsContext::imageInterpolationQuality() const
+{
+ notImplemented();
+ return InterpolationDefault;
+}
+
+}
diff --git a/WebCore/platform/graphics/openvg/PainterOpenVG.cpp b/WebCore/platform/graphics/openvg/PainterOpenVG.cpp
new file mode 100644
index 0000000..3b7cf85
--- /dev/null
+++ b/WebCore/platform/graphics/openvg/PainterOpenVG.cpp
@@ -0,0 +1,957 @@
+/*
+ * Copyright (C) Research In Motion Limited 2009-2010. 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 "PainterOpenVG.h"
+
+#include "Color.h"
+#include "DashArray.h"
+#include "FloatPoint.h"
+#include "FloatQuad.h"
+#include "FloatRect.h"
+#include "IntRect.h"
+#include "IntSize.h"
+#include "NotImplemented.h"
+#include "SurfaceOpenVG.h"
+#include "TransformationMatrix.h"
+#include "VGUtils.h"
+
+#if PLATFORM(EGL)
+#include "EGLUtils.h"
+#endif
+
+#include <vgu.h>
+
+#include <wtf/Assertions.h>
+#include <wtf/MathExtras.h>
+
+namespace WebCore {
+
+static bool isNonRotatedAffineTransformation(const TransformationMatrix& matrix)
+{
+ return matrix.m12() <= FLT_EPSILON && matrix.m13() <= FLT_EPSILON && matrix.m14() <= FLT_EPSILON
+ && matrix.m21() <= FLT_EPSILON && matrix.m23() <= FLT_EPSILON && matrix.m24() <= FLT_EPSILON
+ && matrix.m31() <= FLT_EPSILON && matrix.m32() <= FLT_EPSILON && matrix.m34() <= FLT_EPSILON
+ && matrix.m44() >= 1 - FLT_EPSILON;
+}
+
+static VGCapStyle toVGCapStyle(LineCap lineCap)
+{
+ switch (lineCap) {
+ case RoundCap:
+ return VG_CAP_ROUND;
+ case SquareCap:
+ return VG_CAP_SQUARE;
+ case ButtCap:
+ default:
+ return VG_CAP_BUTT;
+ }
+}
+
+static VGJoinStyle toVGJoinStyle(LineJoin lineJoin)
+{
+ switch (lineJoin) {
+ case RoundJoin:
+ return VG_JOIN_ROUND;
+ case BevelJoin:
+ return VG_JOIN_BEVEL;
+ case MiterJoin:
+ default:
+ return VG_JOIN_MITER;
+ }
+}
+
+static VGFillRule toVGFillRule(WindRule fillRule)
+{
+ return fillRule == RULE_EVENODD ? VG_EVEN_ODD : VG_NON_ZERO;
+}
+
+static VGuint colorToVGColor(const Color& color)
+{
+ VGuint vgColor = color.red();
+ vgColor = (vgColor << 8) | color.green();
+ vgColor = (vgColor << 8) | color.blue();
+ vgColor = (vgColor << 8) | color.alpha();
+ return vgColor;
+}
+
+static void setVGSolidColor(VGPaintMode paintMode, const Color& color)
+{
+ VGPaint paint = vgCreatePaint();
+ vgSetParameteri(paint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
+ vgSetColor(paint, colorToVGColor(color));
+ vgSetPaint(paint, paintMode);
+ vgDestroyPaint(paint);
+ ASSERT_VG_NO_ERROR();
+}
+
+
+struct PlatformPainterState {
+ TransformationMatrix surfaceTransformationMatrix;
+ CompositeOperator compositeOperation;
+ float opacity;
+
+ bool scissoringEnabled;
+ FloatRect scissorRect;
+
+ Color fillColor;
+ StrokeStyle strokeStyle;
+ Color strokeColor;
+ float strokeThickness;
+ LineCap strokeLineCap;
+ LineJoin strokeLineJoin;
+ float strokeMiterLimit;
+ DashArray strokeDashArray;
+ float strokeDashOffset;
+
+ bool antialiasingEnabled;
+
+ PlatformPainterState()
+ : compositeOperation(CompositeSourceOver)
+ , opacity(1.0)
+ , scissoringEnabled(false)
+ , fillColor(Color::black)
+ , strokeStyle(NoStroke)
+ , strokeThickness(0.0)
+ , strokeLineCap(ButtCap)
+ , strokeLineJoin(MiterJoin)
+ , strokeMiterLimit(4.0)
+ , strokeDashOffset(0.0)
+ , antialiasingEnabled(true)
+ {
+ }
+
+ PlatformPainterState(const PlatformPainterState& state)
+ {
+ surfaceTransformationMatrix = state.surfaceTransformationMatrix;
+
+ scissoringEnabled = state.scissoringEnabled;
+ scissorRect = state.scissorRect;
+ copyPaintState(&state);
+ }
+
+ void copyPaintState(const PlatformPainterState* other)
+ {
+ compositeOperation = other->compositeOperation;
+ opacity = other->opacity;
+
+ fillColor = other->fillColor;
+ strokeStyle = other->strokeStyle;
+ strokeColor = other->strokeColor;
+ strokeThickness = other->strokeThickness;
+ strokeLineCap = other->strokeLineCap;
+ strokeLineJoin = other->strokeLineJoin;
+ strokeMiterLimit = other->strokeMiterLimit;
+ strokeDashArray = other->strokeDashArray;
+ strokeDashOffset = other->strokeDashOffset;
+
+ antialiasingEnabled = other->antialiasingEnabled;
+ }
+
+ void applyState(PainterOpenVG* painter)
+ {
+ ASSERT(painter);
+
+ setVGSolidColor(VG_FILL_PATH, fillColor);
+ setVGSolidColor(VG_STROKE_PATH, strokeColor);
+
+ vgSetf(VG_STROKE_LINE_WIDTH, strokeThickness);
+ vgSeti(VG_STROKE_CAP_STYLE, toVGCapStyle(strokeLineCap));
+ vgSeti(VG_STROKE_JOIN_STYLE, toVGJoinStyle(strokeLineJoin));
+ vgSetf(VG_STROKE_MITER_LIMIT, strokeMiterLimit);
+
+ if (antialiasingEnabled)
+ vgSeti(VG_RENDERING_QUALITY, VG_RENDERING_QUALITY_FASTER);
+ else
+ vgSeti(VG_RENDERING_QUALITY, VG_RENDERING_QUALITY_NONANTIALIASED);
+
+ applyBlending(painter);
+ applyStrokeStyle();
+
+ applyTransformationMatrix(painter);
+ applyScissorRect();
+ }
+
+ void applyBlending(PainterOpenVG* painter)
+ {
+ VGBlendMode blendMode = VG_BLEND_SRC_OVER;
+
+ switch (compositeOperation) {
+ case CompositeClear: {
+ // Clear means "set to fully transparent regardless of SRC".
+ // We implement that by multiplying DST with white color
+ // (= no changes) and an alpha of 1.0 - opacity, so the destination
+ // pixels will be fully transparent when opacity == 1.0 and
+ // unchanged when opacity == 0.0.
+ blendMode = VG_BLEND_DST_IN;
+ const VGfloat values[] = { 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0 - opacity };
+ vgSetfv(VG_COLOR_TRANSFORM_VALUES, 8, values);
+ vgSeti(VG_COLOR_TRANSFORM, VG_TRUE);
+ ASSERT_VG_NO_ERROR();
+ break;
+ }
+ case CompositeCopy:
+ blendMode = VG_BLEND_SRC;
+ break;
+ case CompositeSourceOver:
+ blendMode = VG_BLEND_SRC_OVER;
+ break;
+ case CompositeSourceIn:
+ blendMode = VG_BLEND_SRC_IN;
+ break;
+ case CompositeSourceOut:
+ notImplemented();
+ break;
+ case CompositeSourceAtop:
+ notImplemented();
+ break;
+ case CompositeDestinationOver:
+ blendMode = VG_BLEND_DST_OVER;
+ break;
+ case CompositeDestinationIn:
+ blendMode = VG_BLEND_DST_IN;
+ break;
+ case CompositeDestinationOut:
+ notImplemented();
+ break;
+ case CompositeDestinationAtop:
+ notImplemented();
+ break;
+ case CompositeXOR:
+ notImplemented();
+ break;
+ case CompositePlusDarker:
+ blendMode = VG_BLEND_DARKEN;
+ break;
+ case CompositeHighlight:
+ notImplemented();
+ break;
+ case CompositePlusLighter:
+ blendMode = VG_BLEND_LIGHTEN;
+ break;
+ }
+
+ if (compositeOperation != CompositeClear) {
+ if (opacity >= (1.0 - FLT_EPSILON))
+ vgSeti(VG_COLOR_TRANSFORM, VG_FALSE);
+ else if (blendMode == VG_BLEND_SRC) {
+ blendMode = VG_BLEND_SRC_OVER;
+ VGfloat values[] = { 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, opacity };
+ vgSetfv(VG_COLOR_TRANSFORM_VALUES, 8, values);
+ vgSeti(VG_COLOR_TRANSFORM, VG_TRUE);
+ } else {
+ VGfloat values[] = { 1.0, 1.0, 1.0, opacity, 0.0, 0.0, 0.0, 0.0 };
+ vgSetfv(VG_COLOR_TRANSFORM_VALUES, 8, values);
+ vgSeti(VG_COLOR_TRANSFORM, VG_TRUE);
+ }
+ ASSERT_VG_NO_ERROR();
+ }
+
+ vgSeti(VG_BLEND_MODE, blendMode);
+ ASSERT_VG_NO_ERROR();
+ }
+
+ void applyTransformationMatrix(PainterOpenVG* painter)
+ {
+ // There are *five* separate transforms that can be applied to OpenVG as of 1.1
+ // but it is not clear that we need to set them separately. Instead we set them
+ // all right here and let this be a call to essentially set the world transformation!
+ VGMatrix vgMatrix(surfaceTransformationMatrix);
+ const VGfloat* vgFloatArray = vgMatrix.toVGfloat();
+
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
+ vgLoadMatrix(vgFloatArray);
+ ASSERT_VG_NO_ERROR();
+
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
+ vgLoadMatrix(vgFloatArray);
+ ASSERT_VG_NO_ERROR();
+
+#ifdef OPENVG_VERSION_1_1
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_GLYPH_USER_TO_SURFACE);
+ vgLoadMatrix(vgFloatArray);
+ ASSERT_VG_NO_ERROR();
+#endif
+ }
+
+ void applyScissorRect()
+ {
+ if (scissoringEnabled) {
+ vgSeti(VG_SCISSORING, VG_TRUE);
+ vgSetfv(VG_SCISSOR_RECTS, 4, VGRect(scissorRect).toVGfloat());
+ } else
+ vgSeti(VG_SCISSORING, VG_FALSE);
+
+ ASSERT_VG_NO_ERROR();
+ }
+
+ void applyStrokeStyle()
+ {
+ if (strokeStyle == DottedStroke) {
+ VGfloat vgFloatArray[2] = { 1.0, 1.0 };
+ vgSetfv(VG_STROKE_DASH_PATTERN, 2, vgFloatArray);
+ vgSetf(VG_STROKE_DASH_PHASE, 0.0);
+ } else if (strokeStyle == DashedStroke) {
+ if (!strokeDashArray.size()) {
+ VGfloat vgFloatArray[2] = { 4.0, 3.0 };
+ vgSetfv(VG_STROKE_DASH_PATTERN, 2, vgFloatArray);
+ } else {
+ Vector<VGfloat> vgFloatArray(strokeDashArray.size());
+ for (int i = 0; i < strokeDashArray.size(); ++i)
+ vgFloatArray[i] = strokeDashArray[i];
+
+ vgSetfv(VG_STROKE_DASH_PATTERN, vgFloatArray.size(), vgFloatArray.data());
+ }
+ vgSetf(VG_STROKE_DASH_PHASE, strokeDashOffset);
+ } else {
+ vgSetfv(VG_STROKE_DASH_PATTERN, 0, 0);
+ vgSetf(VG_STROKE_DASH_PHASE, 0.0);
+ }
+
+ ASSERT_VG_NO_ERROR();
+ }
+
+ inline bool strokeDisabled() const
+ {
+ return (compositeOperation == CompositeSourceOver
+ && (strokeStyle == NoStroke || !strokeColor.alpha()));
+ }
+
+ inline bool fillDisabled() const
+ {
+ return (compositeOperation == CompositeSourceOver && !fillColor.alpha());
+ }
+};
+
+
+PainterOpenVG::PainterOpenVG()
+ : m_state(0)
+ , m_surface(0)
+{
+}
+
+PainterOpenVG::PainterOpenVG(SurfaceOpenVG* surface)
+ : m_state(0)
+ , m_surface(0)
+{
+ ASSERT(surface);
+ begin(surface);
+}
+
+PainterOpenVG::~PainterOpenVG()
+{
+ end();
+}
+
+void PainterOpenVG::begin(SurfaceOpenVG* surface)
+{
+ if (surface == m_surface)
+ return;
+
+ ASSERT(surface);
+ ASSERT(!m_state);
+
+ m_surface = surface;
+
+ m_stateStack.append(new PlatformPainterState());
+ m_state = m_stateStack.last();
+
+ m_surface->setActivePainter(this);
+ m_surface->makeCurrent();
+}
+
+void PainterOpenVG::end()
+{
+ if (!m_surface)
+ return;
+
+ m_surface->setActivePainter(0);
+ m_surface = 0;
+
+ destroyPainterStates();
+}
+
+void PainterOpenVG::destroyPainterStates()
+{
+ PlatformPainterState* state = 0;
+ while (!m_stateStack.isEmpty()) {
+ state = m_stateStack.last();
+ m_stateStack.removeLast();
+ delete state;
+ }
+ m_state = 0;
+}
+
+// Called by friend SurfaceOpenVG, private otherwise.
+void PainterOpenVG::applyState()
+{
+ ASSERT(m_state);
+ m_state->applyState(this);
+}
+
+/**
+ * Copy the current back buffer image onto the surface.
+ *
+ * Call this method when all painting operations have been completed,
+ * otherwise the surface won't visibly change.
+ */
+void PainterOpenVG::blitToSurface()
+{
+ ASSERT(m_state); // implies m_surface
+ m_surface->flush();
+}
+
+TransformationMatrix PainterOpenVG::transformationMatrix() const
+{
+ ASSERT(m_state);
+ return m_state->surfaceTransformationMatrix;
+}
+
+void PainterOpenVG::concatTransformationMatrix(const TransformationMatrix& matrix)
+{
+ ASSERT(m_state);
+ m_surface->makeCurrent();
+
+ // We do the multiplication ourself using WebCore's TransformationMatrix rather than
+ // offloading this to VG via vgMultMatrix to keep things simple and so we can maintain
+ // state ourselves.
+ m_state->surfaceTransformationMatrix.multLeft(matrix);
+ m_state->applyTransformationMatrix(this);
+}
+
+void PainterOpenVG::setTransformationMatrix(const TransformationMatrix& matrix)
+{
+ ASSERT(m_state);
+ m_surface->makeCurrent();
+
+ m_state->surfaceTransformationMatrix = matrix;
+ m_state->applyTransformationMatrix(this);
+}
+
+CompositeOperator PainterOpenVG::compositeOperation() const
+{
+ ASSERT(m_state);
+ return m_state->compositeOperation;
+}
+
+void PainterOpenVG::setCompositeOperation(CompositeOperator op)
+{
+ ASSERT(m_state);
+ m_surface->makeCurrent();
+
+ m_state->compositeOperation = op;
+ m_state->applyBlending(this);
+}
+
+float PainterOpenVG::opacity() const
+{
+ ASSERT(m_state);
+ return m_state->opacity;
+}
+
+void PainterOpenVG::setOpacity(float opacity)
+{
+ ASSERT(m_state);
+ m_surface->makeCurrent();
+
+ m_state->opacity = opacity;
+ m_state->applyBlending(this);
+}
+
+float PainterOpenVG::strokeThickness() const
+{
+ ASSERT(m_state);
+ return m_state->strokeThickness;
+}
+
+void PainterOpenVG::setStrokeThickness(float thickness)
+{
+ ASSERT(m_state);
+ m_surface->makeCurrent();
+
+ m_state->strokeThickness = thickness;
+ vgSetf(VG_STROKE_LINE_WIDTH, thickness);
+ ASSERT_VG_NO_ERROR();
+}
+
+StrokeStyle PainterOpenVG::strokeStyle() const
+{
+ ASSERT(m_state);
+ return m_state->strokeStyle;
+}
+
+void PainterOpenVG::setStrokeStyle(const StrokeStyle& style)
+{
+ ASSERT(m_state);
+ m_surface->makeCurrent();
+
+ m_state->strokeStyle = style;
+ m_state->applyStrokeStyle();
+}
+
+void PainterOpenVG::setLineDash(const DashArray& dashArray, float dashOffset)
+{
+ ASSERT(m_state);
+ m_surface->makeCurrent();
+
+ m_state->strokeDashArray = dashArray;
+ m_state->strokeDashOffset = dashOffset;
+ m_state->applyStrokeStyle();
+}
+
+void PainterOpenVG::setLineCap(LineCap lineCap)
+{
+ ASSERT(m_state);
+ m_surface->makeCurrent();
+
+ m_state->strokeLineCap = lineCap;
+ vgSeti(VG_STROKE_CAP_STYLE, toVGCapStyle(lineCap));
+ ASSERT_VG_NO_ERROR();
+}
+
+void PainterOpenVG::setLineJoin(LineJoin lineJoin)
+{
+ ASSERT(m_state);
+ m_surface->makeCurrent();
+
+ m_state->strokeLineJoin = lineJoin;
+ vgSeti(VG_STROKE_JOIN_STYLE, toVGJoinStyle(lineJoin));
+ ASSERT_VG_NO_ERROR();
+}
+
+void PainterOpenVG::setMiterLimit(float miterLimit)
+{
+ ASSERT(m_state);
+ m_surface->makeCurrent();
+
+ m_state->strokeMiterLimit = miterLimit;
+ vgSetf(VG_STROKE_MITER_LIMIT, miterLimit);
+ ASSERT_VG_NO_ERROR();
+}
+
+Color PainterOpenVG::strokeColor() const
+{
+ ASSERT(m_state);
+ return m_state->strokeColor;
+}
+
+void PainterOpenVG::setStrokeColor(const Color& color)
+{
+ ASSERT(m_state);
+ m_surface->makeCurrent();
+
+ m_state->strokeColor = color;
+ setVGSolidColor(VG_STROKE_PATH, color);
+}
+
+Color PainterOpenVG::fillColor() const
+{
+ ASSERT(m_state);
+ return m_state->fillColor;
+}
+
+void PainterOpenVG::setFillColor(const Color& color)
+{
+ ASSERT(m_state);
+ m_surface->makeCurrent();
+
+ m_state->fillColor = color;
+ setVGSolidColor(VG_FILL_PATH, color);
+}
+
+bool PainterOpenVG::antialiasingEnabled() const
+{
+ ASSERT(m_state);
+ return m_state->antialiasingEnabled;
+}
+
+void PainterOpenVG::setAntialiasingEnabled(bool enabled)
+{
+ ASSERT(m_state);
+ m_surface->makeCurrent();
+
+ m_state->antialiasingEnabled = enabled;
+
+ if (enabled)
+ vgSeti(VG_RENDERING_QUALITY, VG_RENDERING_QUALITY_FASTER);
+ else
+ vgSeti(VG_RENDERING_QUALITY, VG_RENDERING_QUALITY_NONANTIALIASED);
+}
+
+void PainterOpenVG::scale(const FloatSize& scaleFactors)
+{
+ ASSERT(m_state);
+ m_surface->makeCurrent();
+
+ TransformationMatrix matrix = m_state->surfaceTransformationMatrix;
+ matrix.scaleNonUniform(scaleFactors.width(), scaleFactors.height());
+ setTransformationMatrix(matrix);
+}
+
+void PainterOpenVG::rotate(float radians)
+{
+ ASSERT(m_state);
+ m_surface->makeCurrent();
+
+ TransformationMatrix matrix = m_state->surfaceTransformationMatrix;
+ matrix.rotate(rad2deg(radians));
+ setTransformationMatrix(matrix);
+}
+
+void PainterOpenVG::translate(float dx, float dy)
+{
+ ASSERT(m_state);
+ m_surface->makeCurrent();
+
+ TransformationMatrix matrix = m_state->surfaceTransformationMatrix;
+ matrix.translate(dx, dy);
+ setTransformationMatrix(matrix);
+}
+
+void PainterOpenVG::intersectScissorRect(const FloatRect& rect)
+{
+ // Scissor rectangles are defined by float values, but e.g. painting
+ // something red to a float-clipped rectangle and then painting something
+ // white to the same rectangle will leave some red remnants as it is
+ // rendered to full pixels in between. Also, some OpenVG implementations
+ // are likely to clip to integer coordinates anyways because of the above
+ // effect. So considering the above (and confirming through tests) the
+ // visual result is better if we clip to the enclosing integer rectangle
+ // rather than the exact float rectangle for scissoring.
+ if (m_state->scissoringEnabled)
+ m_state->scissorRect.intersect(FloatRect(enclosingIntRect(rect)));
+ else {
+ m_state->scissoringEnabled = true;
+ m_state->scissorRect = FloatRect(enclosingIntRect(rect));
+ }
+
+ m_state->applyScissorRect();
+}
+
+void PainterOpenVG::intersectClipRect(const FloatRect& rect)
+{
+ ASSERT(m_state);
+ m_surface->makeCurrent();
+
+ if (m_state->surfaceTransformationMatrix.isIdentity()) {
+ // No transformation required, skip all the complex stuff.
+ intersectScissorRect(rect);
+ return;
+ }
+
+ // Check if the actual destination rectangle is still rectilinear (can be
+ // represented as FloatRect) so we could apply scissoring instead of
+ // (potentially more expensive) path clipping. Note that scissoring is not
+ // subject to transformations, so we need to do the transformation to
+ // surface coordinates by ourselves.
+ FloatQuad effectiveScissorQuad =
+ m_state->surfaceTransformationMatrix.mapQuad(FloatQuad(rect));
+
+ if (effectiveScissorQuad.isRectilinear())
+ intersectScissorRect(effectiveScissorQuad.boundingBox());
+ else {
+ // The transformed scissorRect cannot be represented as FloatRect
+ // anymore, so we need to perform masking instead. Not yet implemented.
+ notImplemented();
+ }
+}
+
+void PainterOpenVG::drawRect(const FloatRect& rect, VGbitfield specifiedPaintModes)
+{
+ ASSERT(m_state);
+
+ VGbitfield paintModes = 0;
+ if (!m_state->strokeDisabled())
+ paintModes |= VG_STROKE_PATH;
+ if (!m_state->fillDisabled())
+ paintModes |= VG_FILL_PATH;
+
+ paintModes &= specifiedPaintModes;
+
+ if (!paintModes)
+ return;
+
+ m_surface->makeCurrent();
+
+ VGPath path = vgCreatePath(
+ VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F,
+ 1.0 /* scale */, 0.0 /* bias */,
+ 5 /* expected number of segments */,
+ 5 /* expected number of total coordinates */,
+ VG_PATH_CAPABILITY_APPEND_TO);
+ ASSERT_VG_NO_ERROR();
+
+ if (vguRect(path, rect.x(), rect.y(), rect.width(), rect.height()) == VGU_NO_ERROR) {
+ vgDrawPath(path, paintModes);
+ ASSERT_VG_NO_ERROR();
+ }
+
+ vgDestroyPath(path);
+ ASSERT_VG_NO_ERROR();
+}
+
+void PainterOpenVG::drawRoundedRect(const FloatRect& rect, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, VGbitfield specifiedPaintModes)
+{
+ ASSERT(m_state);
+
+ VGbitfield paintModes = 0;
+ if (!m_state->strokeDisabled())
+ paintModes |= VG_STROKE_PATH;
+ if (!m_state->fillDisabled())
+ paintModes |= VG_FILL_PATH;
+
+ paintModes &= specifiedPaintModes;
+
+ if (!paintModes)
+ return;
+
+ m_surface->makeCurrent();
+
+ VGPath path = vgCreatePath(
+ VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F,
+ 1.0 /* scale */, 0.0 /* bias */,
+ 10 /* expected number of segments */,
+ 25 /* expected number of total coordinates */,
+ VG_PATH_CAPABILITY_APPEND_TO);
+ ASSERT_VG_NO_ERROR();
+
+ // clamp corner arc sizes
+ FloatSize clampedTopLeft = FloatSize(topLeft).shrunkTo(rect.size()).expandedTo(FloatSize());
+ FloatSize clampedTopRight = FloatSize(topRight).shrunkTo(rect.size()).expandedTo(FloatSize());
+ FloatSize clampedBottomLeft = FloatSize(bottomLeft).shrunkTo(rect.size()).expandedTo(FloatSize());
+ FloatSize clampedBottomRight = FloatSize(bottomRight).shrunkTo(rect.size()).expandedTo(FloatSize());
+
+ // As OpenVG's coordinate system is flipped in comparison to WebKit's,
+ // we have to specify the opposite value for the "clockwise" value.
+ static const VGubyte pathSegments[] = {
+ VG_MOVE_TO_ABS,
+ VG_HLINE_TO_REL,
+ VG_SCCWARC_TO_REL,
+ VG_VLINE_TO_REL,
+ VG_SCCWARC_TO_REL,
+ VG_HLINE_TO_REL,
+ VG_SCCWARC_TO_REL,
+ VG_VLINE_TO_REL,
+ VG_SCCWARC_TO_REL,
+ VG_CLOSE_PATH
+ };
+ // Also, the rounded rectangle path proceeds from the top to the bottom,
+ // requiring height distances and clamped radius sizes to be flipped.
+ const VGfloat pathData[] = {
+ rect.x() + clampedTopLeft.width(), rect.y(),
+ rect.width() - clampedTopLeft.width() - clampedTopRight.width(),
+ clampedTopRight.width(), clampedTopRight.height(), 0, clampedTopRight.width(), clampedTopRight.height(),
+ rect.height() - clampedTopRight.height() - clampedBottomRight.height(),
+ clampedBottomRight.width(), clampedBottomRight.height(), 0, -clampedBottomRight.width(), clampedBottomRight.height(),
+ -(rect.width() - clampedBottomLeft.width() - clampedBottomRight.width()),
+ clampedBottomLeft.width(), clampedBottomLeft.height(), 0, -clampedBottomLeft.width(), -clampedBottomLeft.height(),
+ -(rect.height() - clampedTopLeft.height() - clampedBottomLeft.height()),
+ clampedTopLeft.width(), clampedTopLeft.height(), 0, clampedTopLeft.width(), -clampedTopLeft.height(),
+ };
+
+ vgAppendPathData(path, 10, pathSegments, pathData);
+ vgDrawPath(path, paintModes);
+ vgDestroyPath(path);
+ ASSERT_VG_NO_ERROR();
+}
+
+void PainterOpenVG::drawLine(const IntPoint& from, const IntPoint& to)
+{
+ ASSERT(m_state);
+
+ if (m_state->strokeDisabled())
+ return;
+
+ m_surface->makeCurrent();
+
+ VGPath path = vgCreatePath(
+ VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F,
+ 1.0 /* scale */, 0.0 /* bias */,
+ 2 /* expected number of segments */,
+ 4 /* expected number of total coordinates */,
+ VG_PATH_CAPABILITY_APPEND_TO);
+ ASSERT_VG_NO_ERROR();
+
+ VGUErrorCode errorCode;
+
+ // Try to align lines to pixels, centering them between pixels for odd thickness values.
+ if (fmod(m_state->strokeThickness + 0.5, 2.0) < 1.0)
+ errorCode = vguLine(path, from.x(), from.y(), to.x(), to.y());
+ else if ((to.y() - from.y()) > (to.x() - from.x())) // more vertical than horizontal
+ errorCode = vguLine(path, from.x() + 0.5, from.y(), to.x() + 0.5, to.y());
+ else
+ errorCode = vguLine(path, from.x(), from.y() + 0.5, to.x(), to.y() + 0.5);
+
+ if (errorCode == VGU_NO_ERROR) {
+ vgDrawPath(path, VG_STROKE_PATH);
+ ASSERT_VG_NO_ERROR();
+ }
+
+ vgDestroyPath(path);
+ ASSERT_VG_NO_ERROR();
+}
+
+void PainterOpenVG::drawArc(const IntRect& rect, int startAngle, int angleSpan, VGbitfield specifiedPaintModes)
+{
+ ASSERT(m_state);
+
+ VGbitfield paintModes = 0;
+ if (!m_state->strokeDisabled())
+ paintModes |= VG_STROKE_PATH;
+ if (!m_state->fillDisabled())
+ paintModes |= VG_FILL_PATH;
+
+ paintModes &= specifiedPaintModes;
+
+ if (!paintModes)
+ return;
+
+ m_surface->makeCurrent();
+
+ VGPath path = vgCreatePath(
+ VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F,
+ 1.0 /* scale */, 0.0 /* bias */,
+ 2 /* expected number of segments */,
+ 4 /* expected number of total coordinates */,
+ VG_PATH_CAPABILITY_APPEND_TO);
+ ASSERT_VG_NO_ERROR();
+
+ if (vguArc(path, rect.x() + rect.width() / 2.0, rect.y() + rect.height() / 2.0, rect.width(), rect.height(), -startAngle, -angleSpan, VGU_ARC_OPEN) == VGU_NO_ERROR) {
+ vgDrawPath(path, VG_STROKE_PATH);
+ ASSERT_VG_NO_ERROR();
+ }
+
+ vgDestroyPath(path);
+ ASSERT_VG_NO_ERROR();
+}
+
+void PainterOpenVG::drawEllipse(const IntRect& rect, VGbitfield specifiedPaintModes)
+{
+ ASSERT(m_state);
+
+ VGbitfield paintModes = 0;
+ if (!m_state->strokeDisabled())
+ paintModes |= VG_STROKE_PATH;
+ if (!m_state->fillDisabled())
+ paintModes |= VG_FILL_PATH;
+
+ paintModes &= specifiedPaintModes;
+
+ if (!paintModes)
+ return;
+
+ m_surface->makeCurrent();
+
+ VGPath path = vgCreatePath(
+ VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F,
+ 1.0 /* scale */, 0.0 /* bias */,
+ 4 /* expected number of segments */,
+ 12 /* expected number of total coordinates */,
+ VG_PATH_CAPABILITY_APPEND_TO);
+ ASSERT_VG_NO_ERROR();
+
+ if (vguEllipse(path, rect.x() + rect.width() / 2.0, rect.y() + rect.height() / 2.0, rect.width(), rect.height()) == VGU_NO_ERROR) {
+ vgDrawPath(path, paintModes);
+ ASSERT_VG_NO_ERROR();
+ }
+
+ vgDestroyPath(path);
+ ASSERT_VG_NO_ERROR();
+}
+
+void PainterOpenVG::drawPolygon(size_t numPoints, const FloatPoint* points, VGbitfield specifiedPaintModes)
+{
+ ASSERT(m_state);
+
+ VGbitfield paintModes = 0;
+ if (!m_state->strokeDisabled())
+ paintModes |= VG_STROKE_PATH;
+ if (!m_state->fillDisabled())
+ paintModes |= VG_FILL_PATH;
+
+ paintModes &= specifiedPaintModes;
+
+ if (!paintModes)
+ return;
+
+ m_surface->makeCurrent();
+
+ // Path segments: all points + "close path".
+ const VGint numSegments = numPoints + 1;
+ const VGint numCoordinates = numPoints * 2;
+
+ VGPath path = vgCreatePath(
+ VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F,
+ 1.0 /* scale */, 0.0 /* bias */,
+ numSegments /* expected number of segments */,
+ numCoordinates /* expected number of total coordinates */,
+ VG_PATH_CAPABILITY_APPEND_TO);
+ ASSERT_VG_NO_ERROR();
+
+ Vector<VGfloat> vgPoints(numCoordinates);
+ for (int i = 0; i < numPoints; ++i) {
+ vgPoints[i*2] = points[i].x();
+ vgPoints[i*2 + 1] = points[i].y();
+ }
+
+ if (vguPolygon(path, vgPoints.data(), numPoints, VG_TRUE /* closed */) == VGU_NO_ERROR) {
+ vgDrawPath(path, paintModes);
+ ASSERT_VG_NO_ERROR();
+ }
+
+ vgDestroyPath(path);
+ ASSERT_VG_NO_ERROR();
+}
+
+void PainterOpenVG::save(PainterOpenVG::SaveMode saveMode)
+{
+ ASSERT(m_state);
+
+ // If the underlying context/surface was switched away by someone without
+ // telling us, it might not correspond to the one assigned to this painter.
+ // Switch back so we can save the state properly. (Should happen rarely.)
+ // Use DontSaveOrApplyPainterState mode in order to avoid recursion.
+ m_surface->makeCurrent(SurfaceOpenVG::DontSaveOrApplyPainterState);
+
+ if (saveMode == PainterOpenVG::CreateNewState) {
+ PlatformPainterState* state = new PlatformPainterState(*m_state);
+ m_stateStack.append(state);
+ m_state = m_stateStack.last();
+ } else { // if (saveMode == PainterOpenVG::CreateNewStateWithPaintStateOnly) {
+ PlatformPainterState* state = new PlatformPainterState();
+ state->copyPaintState(m_state);
+ m_stateStack.append(state);
+ m_state = m_stateStack.last();
+ }
+}
+
+void PainterOpenVG::restore()
+{
+ ASSERT(m_stateStack.size() >= 2);
+ m_surface->makeCurrent(SurfaceOpenVG::DontApplyPainterState);
+
+ PlatformPainterState* state = m_stateStack.last();
+ m_stateStack.removeLast();
+ delete state;
+
+ m_state = m_stateStack.last();
+ m_state->applyState(this);
+}
+
+}
diff --git a/WebCore/platform/graphics/openvg/PainterOpenVG.h b/WebCore/platform/graphics/openvg/PainterOpenVG.h
new file mode 100644
index 0000000..6936eee
--- /dev/null
+++ b/WebCore/platform/graphics/openvg/PainterOpenVG.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) Research In Motion Limited 2009-2010. 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 PainterOpenVG_h
+#define PainterOpenVG_h
+
+#include "Color.h"
+#include "GraphicsContext.h"
+
+#include <openvg.h>
+
+#include <wtf/Noncopyable.h>
+#include <wtf/Platform.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class FloatPoint;
+class FloatRect;
+class IntRect;
+class IntSize;
+class SurfaceOpenVG;
+class TransformationMatrix;
+
+struct PlatformPainterState;
+
+class PainterOpenVG : public Noncopyable {
+public:
+ friend class SurfaceOpenVG;
+ friend struct PlatformPainterState;
+
+ enum SaveMode {
+ CreateNewState,
+ CreateNewStateWithPaintStateOnly // internal usage only, do not use outside PainterOpenVG
+ };
+
+ PainterOpenVG();
+ PainterOpenVG(SurfaceOpenVG*);
+ ~PainterOpenVG();
+
+ void begin(SurfaceOpenVG*);
+ void end();
+
+ TransformationMatrix transformationMatrix() const;
+ void setTransformationMatrix(const TransformationMatrix&);
+ void concatTransformationMatrix(const TransformationMatrix&);
+
+ CompositeOperator compositeOperation() const;
+ void setCompositeOperation(CompositeOperator);
+ float opacity() const;
+ void setOpacity(float);
+
+ float strokeThickness() const;
+ void setStrokeThickness(float);
+ StrokeStyle strokeStyle() const;
+ void setStrokeStyle(const StrokeStyle&);
+
+ void setLineDash(const DashArray&, float dashOffset);
+ void setLineCap(LineCap);
+ void setLineJoin(LineJoin);
+ void setMiterLimit(float);
+
+ Color strokeColor() const;
+ void setStrokeColor(const Color&);
+
+ Color fillColor() const;
+ void setFillColor(const Color&);
+
+ bool antialiasingEnabled() const;
+ void setAntialiasingEnabled(bool);
+
+ void drawRect(const FloatRect&, VGbitfield paintModes = (VG_STROKE_PATH | VG_FILL_PATH));
+ void drawRoundedRect(const FloatRect&, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, VGbitfield paintModes = (VG_STROKE_PATH | VG_FILL_PATH));
+ void drawLine(const IntPoint& from, const IntPoint& to);
+ void drawArc(const IntRect& ellipseBounds, int startAngle, int angleSpan, VGbitfield paintModes = (VG_STROKE_PATH | VG_FILL_PATH));
+ void drawEllipse(const IntRect& bounds, VGbitfield paintModes = (VG_STROKE_PATH | VG_FILL_PATH));
+ void drawPolygon(size_t numPoints, const FloatPoint* points, VGbitfield paintModes = (VG_STROKE_PATH | VG_FILL_PATH));
+
+ void scale(const FloatSize& scaleFactors);
+ void rotate(float radians);
+ void translate(float dx, float dy);
+
+ void intersectClipRect(const FloatRect&);
+
+ void save(PainterOpenVG::SaveMode saveMode = CreateNewState);
+ void restore();
+
+ SurfaceOpenVG* surface() { return m_surface; }
+ void blitToSurface();
+
+private:
+ void destroyPainterStates();
+ void applyState();
+
+ void intersectScissorRect(const FloatRect&);
+
+private:
+ Vector<PlatformPainterState*> m_stateStack;
+ PlatformPainterState* m_state;
+ SurfaceOpenVG* m_surface;
+};
+
+}
+
+#endif
diff --git a/WebCore/platform/graphics/openvg/SurfaceOpenVG.cpp b/WebCore/platform/graphics/openvg/SurfaceOpenVG.cpp
new file mode 100644
index 0000000..9539f2c
--- /dev/null
+++ b/WebCore/platform/graphics/openvg/SurfaceOpenVG.cpp
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) Research In Motion Limited 2009-2010. 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 "SurfaceOpenVG.h"
+
+#include "IntSize.h"
+#include "PainterOpenVG.h"
+
+#if PLATFORM(EGL)
+#include "EGLDisplayOpenVG.h"
+#include "EGLUtils.h"
+#endif
+
+#include <wtf/Assertions.h>
+
+namespace WebCore {
+
+PainterOpenVG* SurfaceOpenVG::s_currentPainter = 0;
+
+SurfaceOpenVG* SurfaceOpenVG::currentSurface()
+{
+#if PLATFORM(EGL)
+ return EGLDisplayOpenVG::currentSurface();
+#else
+ ASSERT_NOT_REACHED();
+ return 0;
+#endif
+}
+
+#if PLATFORM(EGL)
+SurfaceOpenVG::SurfaceOpenVG(const IntSize& size, const EGLDisplay& display, EGLConfig* confPtr, EGLint* errorCode)
+ : m_activePainter(0)
+ , m_eglDisplay(display)
+ , m_eglSurface(EGL_NO_SURFACE)
+ , m_eglContext(EGL_NO_CONTEXT)
+{
+ ASSERT(m_eglDisplay != EGL_NO_DISPLAY);
+
+ EGLDisplayOpenVG* displayManager = EGLDisplayOpenVG::forDisplay(m_eglDisplay);
+ EGLConfig config = confPtr ? (*confPtr) : displayManager->defaultPbufferConfig();
+ m_eglSurface = displayManager->createPbufferSurface(size, config, errorCode);
+
+ if (m_eglSurface == EGL_NO_SURFACE)
+ return;
+
+ m_eglContext = displayManager->contextForSurface(m_eglSurface);
+ EGLDisplayOpenVG::registerPlatformSurface(this);
+}
+
+SurfaceOpenVG::SurfaceOpenVG(EGLNativeWindowType window, const EGLDisplay& display, EGLConfig* confPtr)
+ : m_activePainter(0)
+ , m_eglDisplay(display)
+ , m_eglSurface(EGL_NO_SURFACE)
+ , m_eglContext(EGL_NO_CONTEXT)
+{
+ ASSERT(m_eglDisplay != EGL_NO_DISPLAY);
+
+ EGLDisplayOpenVG* displayManager = EGLDisplayOpenVG::forDisplay(m_eglDisplay);
+ EGLConfig config = confPtr ? (*confPtr) : displayManager->defaultWindowConfig();
+ m_eglSurface = displayManager->surfaceForWindow(window, config);
+ ASSERT(m_eglSurface != EGL_NO_SURFACE);
+
+ m_eglContext = displayManager->contextForSurface(m_eglSurface);
+ EGLDisplayOpenVG::registerPlatformSurface(this);
+}
+
+// Constructor only accessible to EGLDisplayOpenVG for shared context
+// initialization. The parameter types might define to void* like in the
+// window surface constructor, so it can't be overloaded with all the required
+// arguments and EGLDisplayOpenVG basically implements the constructor
+// by itself.
+SurfaceOpenVG::SurfaceOpenVG()
+ : m_activePainter(0)
+ , m_eglDisplay(EGL_NO_DISPLAY)
+ , m_eglSurface(EGL_NO_SURFACE)
+ , m_eglContext(EGL_NO_CONTEXT)
+{
+}
+#endif
+
+SurfaceOpenVG::~SurfaceOpenVG()
+{
+ if (!isValid())
+ return;
+
+ if (m_activePainter && this == m_activePainter->baseSurface())
+ m_activePainter->end();
+
+#if PLATFORM(EGL)
+ EGLDisplayOpenVG::forDisplay(m_eglDisplay)->destroySurface(m_eglSurface);
+ EGLDisplayOpenVG::unregisterPlatformSurface(this);
+#else
+ ASSERT_NOT_REACHED();
+#endif
+}
+
+bool SurfaceOpenVG::isValid() const
+{
+#if PLATFORM(EGL)
+ return (m_eglSurface != EGL_NO_SURFACE);
+#else
+ ASSERT_NOT_REACHED();
+ return false;
+#endif
+}
+
+int SurfaceOpenVG::width() const
+{
+#if PLATFORM(EGL)
+ ASSERT(m_eglSurface != EGL_NO_SURFACE);
+
+ EGLint width;
+ eglQuerySurface(m_eglDisplay, m_eglSurface, EGL_WIDTH, &width);
+ ASSERT_EGL_NO_ERROR();
+ return width;
+#else
+ ASSERT_NOT_REACHED();
+ return 0;
+#endif
+}
+
+int SurfaceOpenVG::height() const
+{
+#if PLATFORM(EGL)
+ ASSERT(m_eglSurface != EGL_NO_SURFACE);
+
+ EGLint height;
+ eglQuerySurface(m_eglDisplay, m_eglSurface, EGL_HEIGHT, &height);
+ ASSERT_EGL_NO_ERROR();
+ return height;
+#else
+ ASSERT_NOT_REACHED();
+ return 0;
+#endif
+}
+
+SurfaceOpenVG* SurfaceOpenVG::sharedSurface() const
+{
+#if PLATFORM(EGL)
+ ASSERT(m_eglSurface != EGL_NO_SURFACE);
+ return EGLDisplayOpenVG::forDisplay(m_eglDisplay)->sharedPlatformSurface();
+#else
+ ASSERT_NOT_REACHED();
+ return 0;
+#endif
+}
+
+void SurfaceOpenVG::makeCurrent(MakeCurrentMode mode)
+{
+#if PLATFORM(EGL)
+ ASSERT(m_eglSurface != EGL_NO_SURFACE);
+
+ eglBindAPI(EGL_OPENVG_API);
+ ASSERT_EGL_NO_ERROR();
+ EGLSurface currentSurface = eglGetCurrentSurface(EGL_DRAW);
+ ASSERT_EGL_NO_ERROR();
+
+ if (currentSurface != m_eglSurface) {
+ eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext);
+ ASSERT_EGL_NO_ERROR();
+ s_currentPainter = 0;
+ }
+#endif
+
+ if (m_activePainter && mode == ApplyPainterStateOnSurfaceSwitch
+ && s_currentPainter != m_activePainter) {
+ m_activePainter->applyState();
+ s_currentPainter = m_activePainter;
+ }
+}
+
+void SurfaceOpenVG::makeCompatibleCurrent()
+{
+#if PLATFORM(EGL)
+ ASSERT(m_eglSurface != EGL_NO_SURFACE);
+
+ eglBindAPI(EGL_OPENVG_API);
+ ASSERT_EGL_NO_ERROR();
+ EGLSurface currentSurface = eglGetCurrentSurface(EGL_DRAW);
+ ASSERT_EGL_NO_ERROR();
+
+ if (currentSurface == m_eglSurface) {
+ if (m_activePainter && s_currentPainter != m_activePainter) {
+ m_activePainter->applyState();
+ s_currentPainter = m_activePainter;
+ }
+ } else if (!EGLDisplayOpenVG::forDisplay(m_eglDisplay)->surfacesCompatible(currentSurface, m_eglSurface)) {
+ eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext);
+ ASSERT_EGL_NO_ERROR();
+ s_currentPainter = 0;
+ }
+ // else: surfaces compatible, no need to switch contexts
+#endif
+}
+
+void SurfaceOpenVG::flush()
+{
+#if PLATFORM(EGL)
+ ASSERT(m_eglSurface != EGL_NO_SURFACE);
+
+ eglSwapBuffers(m_eglDisplay, m_eglSurface);
+ ASSERT_EGL_NO_ERROR();
+#endif
+}
+
+void SurfaceOpenVG::setActivePainter(PainterOpenVG* painter)
+{
+ ASSERT(isValid());
+
+ // If painter is non-zero, we want to make sure there was no previous painter set.
+ ASSERT(!painter || !m_activePainter);
+
+ // Make sure a disabled painter isn't marked as global current painter anymore.
+ if (!painter && s_currentPainter == m_activePainter)
+ s_currentPainter = 0;
+
+ m_activePainter = painter;
+}
+
+PainterOpenVG* SurfaceOpenVG::activePainter()
+{
+ ASSERT(isValid());
+ return m_activePainter;
+}
+
+}
diff --git a/WebCore/platform/graphics/openvg/SurfaceOpenVG.h b/WebCore/platform/graphics/openvg/SurfaceOpenVG.h
new file mode 100644
index 0000000..dc288dd
--- /dev/null
+++ b/WebCore/platform/graphics/openvg/SurfaceOpenVG.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) Research In Motion Limited 2009-2010. 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 SurfaceOpenVG_h
+#define SurfaceOpenVG_h
+
+#if PLATFORM(EGL)
+#include <egl.h>
+#endif
+
+#include <wtf/Noncopyable.h>
+#include <wtf/Platform.h>
+
+namespace WebCore {
+
+#if PLATFORM(EGL)
+class EGLDisplayOpenVG;
+#endif
+class PainterOpenVG;
+class IntSize;
+
+/**
+ * SurfaceOpenVG provides the functionality of surfaces and contexts that are
+ * underlying the OpenVG implementation. In the vast majority of cases, that
+ * underlying technology is EGL, but OpenVG doesn't depend on EGL per se.
+ * Wrapping surface/context functionality into a separate class avoids lots
+ * of #ifdefs and should make it easy to add different surface/context
+ * implementations than EGL.
+ */
+class SurfaceOpenVG : public Noncopyable {
+public:
+ enum MakeCurrentMode {
+ ApplyPainterStateOnSurfaceSwitch,
+ DontApplyPainterState,
+ };
+
+ static SurfaceOpenVG* currentSurface();
+
+#if PLATFORM(EGL)
+ friend class EGLDisplayOpenVG;
+
+ /**
+ * Create a new EGL pbuffer surface with the specified size and config on
+ * the given display. If config is not specified, the display's default
+ * pbuffer config is used.
+ *
+ * This constructor will trigger an assertion if creation of the surface
+ * fails, unless you pledge to manually process the error code by passing
+ * a non-zero pointer as errorCode parameter. The error code returned by
+ * eglGetError() will be written to that variable.
+ */
+ SurfaceOpenVG(const IntSize& size, const EGLDisplay& display, EGLConfig* config = 0, EGLint* errorCode = 0);
+
+ /**
+ * Create a new EGL window surface with the specified native window handle
+ * and config on the given display. If config is not specified, the
+ * display's default window config is used.
+ */
+ SurfaceOpenVG(EGLNativeWindowType window, const EGLDisplay& display, EGLConfig* config = 0);
+
+ EGLDisplay eglDisplay() const { return m_eglDisplay; }
+ EGLSurface eglSurface() const { return m_eglSurface; }
+ EGLContext eglContext() const { return m_eglContext; }
+#endif
+
+ ~SurfaceOpenVG();
+
+ /**
+ * If a surface is invalid (could not be created), all method calls will
+ * crash horribly.
+ */
+ bool isValid() const;
+
+ int width() const;
+ int height() const;
+
+ SurfaceOpenVG* sharedSurface() const;
+
+ /**
+ * Make the associated GL/EGL context the current one, so that subsequent
+ * OpenVG commands apply to it.
+ */
+ void makeCurrent(MakeCurrentMode mode = ApplyPainterStateOnSurfaceSwitch);
+
+ /**
+ * Make a surface/context combination current that is "compatible"
+ * (i.e. can access its shared resources) to the given one. If no
+ * surface/context is current, the given one is made current.
+ *
+ * This method is meant to avoid context changes if they're not
+ * necessary, particularly tailored for the case where something
+ * compatible to the shared surface is requested while actual painting
+ * happens on another surface.
+ */
+ void makeCompatibleCurrent();
+
+ /**
+ * Empty the OpenVG pipeline and make sure all the performed paint
+ * operations show up on the surface as actual drawn pixels.
+ */
+ void flush();
+
+ void setActivePainter(PainterOpenVG*);
+ PainterOpenVG* activePainter();
+
+private:
+ PainterOpenVG* m_activePainter;
+ static PainterOpenVG* s_currentPainter; // global currently active painter
+
+#if PLATFORM(EGL)
+ SurfaceOpenVG(); // for EGLDisplayOpenVG
+
+ EGLDisplay m_eglDisplay;
+ EGLSurface m_eglSurface;
+ EGLContext m_eglContext;
+#endif
+};
+
+}
+
+#endif
diff --git a/WebCore/platform/graphics/openvg/VGUtils.cpp b/WebCore/platform/graphics/openvg/VGUtils.cpp
new file mode 100644
index 0000000..72ba5b2
--- /dev/null
+++ b/WebCore/platform/graphics/openvg/VGUtils.cpp
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) Research In Motion Limited 2009. 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 "VGUtils.h"
+
+#include "FloatRect.h"
+#include "TransformationMatrix.h"
+
+namespace WebCore {
+
+VGMatrix::VGMatrix(const VGfloat data[9])
+{
+ m_data[0] = data[0];
+ m_data[1] = data[1];
+ m_data[2] = data[2];
+ m_data[3] = data[3];
+ m_data[4] = data[4];
+ m_data[5] = data[5];
+ m_data[6] = data[6];
+ m_data[7] = data[7];
+ m_data[8] = data[8];
+}
+
+VGMatrix::VGMatrix(const TransformationMatrix& matrix)
+{
+ m_data[0] = matrix.m11();
+ m_data[1] = matrix.m12();
+ m_data[2] = matrix.m14();
+ m_data[3] = matrix.m21();
+ m_data[4] = matrix.m22();
+ m_data[5] = matrix.m24();
+ m_data[6] = matrix.m41();
+ m_data[7] = matrix.m42();
+ m_data[8] = matrix.m44();
+}
+
+VGMatrix::operator TransformationMatrix() const
+{
+ TransformationMatrix matrix;
+ matrix.setM11(m_data[0]);
+ matrix.setM12(m_data[1]);
+ matrix.setM14(m_data[2]);
+ matrix.setM21(m_data[3]);
+ matrix.setM22(m_data[4]);
+ matrix.setM24(m_data[5]);
+ matrix.setM41(m_data[6]);
+ matrix.setM42(m_data[7]);
+ matrix.setM44(m_data[8]);
+ return matrix;
+}
+
+TransformationMatrix::operator VGMatrix() const
+{
+ return VGMatrix(*this);
+}
+
+VGRect::VGRect(const VGfloat data[4])
+{
+ m_data[0] = data[0];
+ m_data[1] = data[1];
+ m_data[2] = data[2];
+ m_data[3] = data[3];
+}
+
+VGRect::VGRect(const FloatRect& rect)
+{
+ m_data[0] = rect.x();
+ m_data[1] = rect.y();
+ m_data[2] = rect.width();
+ m_data[3] = rect.height();
+}
+
+VGRect::operator FloatRect() const
+{
+ return FloatRect(m_data[0], m_data[1], m_data[2], m_data[3]);
+}
+
+FloatRect::operator VGRect() const
+{
+ return VGRect(*this);
+}
+
+}
diff --git a/WebCore/platform/graphics/openvg/VGUtils.h b/WebCore/platform/graphics/openvg/VGUtils.h
new file mode 100644
index 0000000..083c15a
--- /dev/null
+++ b/WebCore/platform/graphics/openvg/VGUtils.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) Research In Motion Limited 2009-2010. 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 VGUtils_h
+#define VGUtils_h
+
+#include <openvg.h>
+#include <wtf/Assertions.h>
+
+static inline const char* toVGErrorConstant(VGErrorCode error)
+{
+ switch (error) {
+ case VG_BAD_HANDLE_ERROR:
+ return "VG_BAD_HANDLE_ERROR";
+ case VG_ILLEGAL_ARGUMENT_ERROR:
+ return "VG_ILLEGAL_ARGUMENT_ERROR";
+ case VG_OUT_OF_MEMORY_ERROR:
+ return "VG_OUT_OF_MEMORY_ERROR";
+ case VG_PATH_CAPABILITY_ERROR:
+ return "VG_PATH_CAPABILITY_ERROR";
+ case VG_UNSUPPORTED_IMAGE_FORMAT_ERROR:
+ return "VG_UNSUPPORTED_IMAGE_FORMAT_ERROR";
+ case VG_UNSUPPORTED_PATH_FORMAT_ERROR:
+ return "VG_UNSUPPORTED_PATH_FORMAT_ERROR";
+ case VG_IMAGE_IN_USE_ERROR:
+ return "VG_IMAGE_IN_USE_ERROR";
+ case VG_NO_CONTEXT_ERROR:
+ return "VG_NO_CONTEXT_ERROR";
+ default:
+ return "UNKNOWN_ERROR";
+ }
+}
+
+#if ASSERT_DISABLED
+#define ASSERT_VG_NO_ERROR() ((void)0)
+#else
+#define ASSERT_VG_NO_ERROR() do { \
+ VGErrorCode vgErrorCode = vgGetError(); \
+ ASSERT_WITH_MESSAGE(vgErrorCode == VG_NO_ERROR, "Found %s", toVGErrorConstant(vgErrorCode)); \
+} while (0)
+#endif
+
+
+namespace WebCore {
+
+class FloatRect;
+class TransformationMatrix;
+
+class VGMatrix {
+public:
+ VGMatrix(const VGfloat data[9]);
+ VGMatrix(const TransformationMatrix&);
+ const VGfloat* toVGfloat() const { return m_data; }
+ operator TransformationMatrix() const;
+private:
+ VGfloat m_data[9];
+};
+
+class VGRect {
+public:
+ VGRect(const VGfloat data[4]);
+ VGRect(const FloatRect&);
+ const VGfloat* toVGfloat() const { return m_data; }
+ operator FloatRect() const;
+private:
+ VGfloat m_data[4];
+};
+
+}
+
+#endif
diff --git a/WebCore/platform/graphics/qt/FontCacheQt.cpp b/WebCore/platform/graphics/qt/FontCacheQt.cpp
index 82fb709..83df0f3 100644
--- a/WebCore/platform/graphics/qt/FontCacheQt.cpp
+++ b/WebCore/platform/graphics/qt/FontCacheQt.cpp
@@ -56,7 +56,7 @@ FontPlatformData* FontCache::getSimilarFontPlatformData(const Font& font)
FontPlatformData* FontCache::getLastResortFallbackFont(const FontDescription& fontDescription)
{
- const AtomicString fallbackFamily = QFont(fontDescription.family().family()).lastResortFont();
+ const AtomicString fallbackFamily = QFont(fontDescription.family().family()).lastResortFamily();
return new FontPlatformData(fontDescription, fallbackFamily);
}
diff --git a/WebCore/platform/graphics/qt/FontPlatformData.h b/WebCore/platform/graphics/qt/FontPlatformData.h
index 4a3f8bc..9355142 100644
--- a/WebCore/platform/graphics/qt/FontPlatformData.h
+++ b/WebCore/platform/graphics/qt/FontPlatformData.h
@@ -31,7 +31,7 @@
namespace WebCore {
class String;
-class FontPlatformDataPrivate {
+class FontPlatformDataPrivate : public Noncopyable {
public:
FontPlatformDataPrivate()
: refCount(1)
diff --git a/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp b/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp
index 2cc2fc6..0a1075f 100644
--- a/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp
+++ b/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp
@@ -49,17 +49,6 @@ FontPlatformData::FontPlatformData(const FontPlatformData &other) : m_data(other
FontPlatformData::FontPlatformData(const FontDescription& description, const AtomicString& familyName, int wordSpacing, int letterSpacing)
: m_data(new FontPlatformDataPrivate())
{
- QString familyNames(familyName);
- if (!familyName.isEmpty())
- familyNames += QLatin1Char(',');
-
- const FontFamily* family = &description.family();
- while (family) {
- familyNames += family->family();
- family = family->next();
- if (family)
- familyNames += QLatin1Char(',');
- }
QFont& font = m_data->font;
font.setFamily(familyName);
font.setPixelSize(qRound(description.computedSize()));
diff --git a/WebCore/platform/graphics/qt/FontQt.cpp b/WebCore/platform/graphics/qt/FontQt.cpp
index 1e44626..0196ab2 100644
--- a/WebCore/platform/graphics/qt/FontQt.cpp
+++ b/WebCore/platform/graphics/qt/FontQt.cpp
@@ -44,24 +44,11 @@
namespace WebCore {
-static const QString qstring(const TextRun& run)
+static const QString fromRawDataWithoutRef(const String& string)
{
- // We don't detach
- return QString::fromRawData(reinterpret_cast<const QChar*>(run.characters()), run.length());
-}
-
-static const QString fixSpacing(const QString &string)
-{
- //Only detach if we're actually changing something
- QString possiblyDetached = string;
- for (int i = 0; i < string.length(); ++i) {
- const QChar c = string.at(i);
- if (c.unicode() != 0x20 && Font::treatAsSpace(c.unicode()))
- possiblyDetached[i] = 0x20; // detach
- else if (c.unicode() != 0x200c && Font::treatAsZeroWidthSpace(c.unicode()))
- possiblyDetached[i] = 0x200c; // detach
- }
- return possiblyDetached;
+ // We don't detach. This assumes the WebCore string data will stay valid for the
+ // lifetime of the QString we pass back, since we don't ref the WebCore string.
+ return QString::fromRawData(reinterpret_cast<const QChar*>(string.characters()), string.length());
}
static QTextLine setupLayout(QTextLayout* layout, const TextRun& style)
@@ -110,7 +97,8 @@ void Font::drawComplexText(GraphicsContext* ctx, const TextRun& run, const Float
p->setPen(QPen(QColor(ctx->strokeColor()), ctx->strokeThickness()));
}
- const QString string = fixSpacing(qstring(run));
+ String sanitized = Font::normalizeSpaces(String(run.characters(), run.length()));
+ QString string = fromRawDataWithoutRef(sanitized);
// text shadow
IntSize shadowSize;
@@ -185,7 +173,10 @@ float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFon
{
if (!run.length())
return 0;
- const QString string = fixSpacing(qstring(run));
+
+ String sanitized = Font::normalizeSpaces(String(run.characters(), run.length()));
+ QString string = fromRawDataWithoutRef(sanitized);
+
QTextLayout layout(string, font());
QTextLine line = setupLayout(&layout, run);
int w = int(line.naturalTextWidth());
@@ -198,7 +189,9 @@ float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFon
int Font::offsetForPositionForComplexText(const TextRun& run, int position, bool) const
{
- const QString string = fixSpacing(qstring(run));
+ String sanitized = Font::normalizeSpaces(String(run.characters(), run.length()));
+ QString string = fromRawDataWithoutRef(sanitized);
+
QTextLayout layout(string, font());
QTextLine line = setupLayout(&layout, run);
return line.xToCursor(position);
@@ -206,7 +199,9 @@ int Font::offsetForPositionForComplexText(const TextRun& run, int position, bool
FloatRect Font::selectionRectForComplexText(const TextRun& run, const IntPoint& pt, int h, int from, int to) const
{
- const QString string = fixSpacing(qstring(run));
+ String sanitized = Font::normalizeSpaces(String(run.characters(), run.length()));
+ QString string = fromRawDataWithoutRef(sanitized);
+
QTextLayout layout(string, font());
QTextLine line = setupLayout(&layout, run);
diff --git a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
index a095476..b78a6e8 100644
--- a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
+++ b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
@@ -166,7 +166,7 @@ static inline Qt::FillRule toQtFillRule(WindRule rule)
return Qt::OddEvenFill;
}
-struct TransparencyLayer {
+struct TransparencyLayer : FastAllocBase {
TransparencyLayer(const QPainter* p, const QRect &rect)
: pixmap(rect.width(), rect.height())
{
@@ -198,7 +198,7 @@ private:
TransparencyLayer & operator=(const TransparencyLayer &) { return *this; }
};
-class GraphicsContextPlatformPrivate {
+class GraphicsContextPlatformPrivate : public Noncopyable {
public:
GraphicsContextPlatformPrivate(QPainter* painter);
~GraphicsContextPlatformPrivate();
@@ -618,14 +618,14 @@ QPen GraphicsContext::pen()
return p->pen();
}
-static void inline drawFilledShadowPath(GraphicsContext* context, QPainter* p, const QPainterPath *path)
+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->fillPath(path, QBrush(shadowColor));
p->translate(-shadowSize.width(), -shadowSize.height());
}
}
@@ -640,7 +640,7 @@ void GraphicsContext::fillPath()
path.setFillRule(toQtFillRule(fillRule()));
if (m_common->state.fillPattern || m_common->state.fillGradient || fillColor().alpha()) {
- drawFilledShadowPath(this, p, &path);
+ drawFilledShadowPath(this, p, path);
if (m_common->state.fillPattern) {
TransformationMatrix affine;
p->fillPath(path, QBrush(m_common->state.fillPattern->createPlatformPattern(affine)));
@@ -751,7 +751,7 @@ void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLef
Path path = Path::createRoundedRectangle(rect, topLeft, topRight, bottomLeft, bottomRight);
QPainter* p = m_data->p();
drawFilledShadowPath(this, p, path.platformPath());
- p->fillPath(*path.platformPath(), QColor(color));
+ p->fillPath(path.platformPath(), QColor(color));
}
void GraphicsContext::beginPath()
@@ -762,7 +762,7 @@ void GraphicsContext::beginPath()
void GraphicsContext::addPath(const Path& path)
{
QPainterPath newPath = m_data->currentPath;
- newPath.addPath(*(path.platformPath()));
+ newPath.addPath(path.platformPath());
m_data->currentPath = newPath;
}
@@ -795,17 +795,21 @@ void GraphicsContext::clipPath(WindRule clipRule)
p->setClipPath(newPath);
}
+void GraphicsContext::drawFocusRing(const Vector<Path>& paths, int width, int offset, const Color& color)
+{
+ // FIXME: implement
+}
+
/**
* Focus ring handling is not handled here. Qt style in
* RenderTheme handles drawing focus on widgets which
* need it.
*/
-void GraphicsContext::drawFocusRing(const Color& color)
+void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int /* width */, int /* offset */, const Color& color)
{
if (paintingDisabled())
return;
- const Vector<IntRect>& rects = focusRingRects();
unsigned rectCount = rects.size();
if (!rects.size())
@@ -1031,7 +1035,7 @@ void GraphicsContext::clip(const Path& path)
if (paintingDisabled())
return;
- m_data->p()->setClipPath(*path.platformPath(), Qt::IntersectClip);
+ m_data->p()->setClipPath(path.platformPath(), Qt::IntersectClip);
}
void GraphicsContext::canvasClip(const Path& path)
@@ -1045,7 +1049,7 @@ void GraphicsContext::clipOut(const Path& path)
return;
QPainter* p = m_data->p();
- QPainterPath clippedOut = *path.platformPath();
+ QPainterPath clippedOut = path.platformPath();
QPainterPath newClip;
newClip.setFillRule(Qt::OddEvenFill);
if (p->hasClipping()) {
@@ -1054,7 +1058,7 @@ void GraphicsContext::clipOut(const Path& path)
p->setClipPath(newClip, Qt::IntersectClip);
} else {
newClip.addRect(p->window());
- newClip.addPath(clippedOut & newClip);
+ newClip.addPath(clippedOut.intersected(newClip));
p->setClipPath(newClip);
}
}
@@ -1293,7 +1297,7 @@ HDC GraphicsContext::getWindowsContext(const IntRect& dstRect, bool supportAlpha
memset(bmpInfo.bmBits, 0, bufferSize);
}
-#if !PLATFORM(WINCE)
+#if !OS(WINCE)
// Make sure we can do world transforms.
SetGraphicsMode(bitmapDC, GM_ADVANCED);
diff --git a/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp b/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp
new file mode 100644
index 0000000..5712eee
--- /dev/null
+++ b/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp
@@ -0,0 +1,1118 @@
+/*
+ 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 "GraphicsLayerQt.h"
+
+#include "CurrentTime.h"
+#include "FloatRect.h"
+#include "GraphicsContext.h"
+#include "Image.h"
+#include "RefCounted.h"
+#include "TranslateTransformOperation.h"
+#include "UnitBezier.h"
+#include <QtCore/qabstractanimation.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qset.h>
+#include <QtCore/qtimer.h>
+#include <QtGui/qbitmap.h>
+#include <QtGui/qcolor.h>
+#include <QtGui/qgraphicseffect.h>
+#include <QtGui/qgraphicsitem.h>
+#include <QtGui/qgraphicsscene.h>
+#include <QtGui/qmatrix4x4.h>
+#include <QtGui/qpainter.h>
+#include <QtGui/qpalette.h>
+#include <QtGui/qpixmap.h>
+#include <QtGui/qstyleoption.h>
+
+namespace WebCore {
+
+class GraphicsLayerQtImpl : public QGraphicsObject {
+ Q_OBJECT
+
+public:
+ // this set of flags help us defer which properties of the layer have been
+ // modified by the compositor, so we can know what to look for in the next flush
+ enum ChangeMask {
+ NoChanges = 0,
+ ChildrenChange = (1L << 1),
+ MaskLayerChange = (1L << 2),
+ PositionChange = (1L << 3),
+ AnchorPointChange = (1L << 4),
+ SizeChange = (1L << 5),
+ TransformChange = (1L << 6),
+ ContentChange = (1L << 7),
+ GeometryOrientationChange = (1L << 8),
+ ContentsOrientationChange = (1L << 9),
+ OpacityChange = (1L << 10),
+ ContentsRectChange = (1L << 11),
+ Preserves3DChange = (1L << 12),
+ MasksToBoundsChange = (1L << 13),
+ DrawsContentChange = (1L << 14),
+ ContentsOpaqueChange = (1L << 15),
+ BackfaceVisibilityChange = (1L << 16),
+ ChildrenTransformChange = (1L << 17),
+ DisplayChange = (1L << 18),
+ BackgroundColorChange = (1L << 19),
+ ParentChange = (1L << 20),
+ DistributesOpacityChange = (1L << 21)
+ };
+
+ // the compositor lets us special-case images and colors, so we try to do so
+ enum StaticContentType { HTMLContentType, PixmapContentType, ColorContentType};
+
+ GraphicsLayerQtImpl(GraphicsLayerQt* newLayer);
+ virtual ~GraphicsLayerQtImpl();
+
+ // reimps from QGraphicsItem
+ virtual QPainterPath opaqueArea() const;
+ virtual QRectF boundingRect() const;
+ virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*);
+
+ // we manage transforms ourselves because transform-origin acts differently in webkit and in Qt
+ void setBaseTransform(const QTransform&);
+ void drawContents(QPainter*, const QRectF&, bool mask = false);
+
+ // let the compositor-API tell us which properties were changed
+ void notifyChange(ChangeMask);
+
+ // called when the compositor is ready for us to show the changes on screen
+ // this is called indirectly from ChromeClientQt::setNeedsOneShotDrawingSynchronization
+ // (meaning the sync would happen together with the next draw)
+ // or ChromeClientQt::scheduleCompositingLayerSync (meaning the sync will happen ASAP)
+ void flushChanges(bool recursive = true);
+
+public slots:
+ // we need to notify the client (aka the layer compositor) when the animation actually starts
+ void notifyAnimationStarted();
+
+public:
+ GraphicsLayerQt* m_layer;
+
+ QTransform m_baseTransfom;
+ bool m_transformAnimationRunning;
+ bool m_opacityAnimationRunning;
+
+ struct ContentData {
+ QPixmap pixmap;
+ QRegion regionToUpdate;
+ bool updateAll;
+ QColor contentsBackgroundColor;
+ QColor backgroundColor;
+ StaticContentType contentType;
+ float opacity;
+ ContentData()
+ : updateAll(false)
+ , contentType(HTMLContentType)
+ , opacity(1.f)
+ {
+ }
+
+ };
+
+ ContentData m_pendingContent;
+ ContentData m_currentContent;
+
+ int m_changeMask;
+
+ QSizeF m_size;
+ QList<QWeakPointer<QAbstractAnimation> > m_animations;
+ QTimer m_suspendTimer;
+
+ struct State {
+ GraphicsLayer* maskLayer;
+ FloatPoint pos;
+ FloatPoint3D anchorPoint;
+ FloatSize size;
+ TransformationMatrix transform;
+ TransformationMatrix childrenTransform;
+ Color backgroundColor;
+ Color currentColor;
+ GraphicsLayer::CompositingCoordinatesOrientation geoOrientation;
+ GraphicsLayer::CompositingCoordinatesOrientation contentsOrientation;
+ float opacity;
+ QRect contentsRect;
+
+ bool preserves3D: 1;
+ bool masksToBounds: 1;
+ bool drawsContent: 1;
+ bool contentsOpaque: 1;
+ bool backfaceVisibility: 1;
+ bool distributeOpacity: 1;
+ bool align: 2;
+ State(): maskLayer(0), opacity(1), preserves3D(false), masksToBounds(false),
+ drawsContent(false), contentsOpaque(false), backfaceVisibility(false),
+ distributeOpacity(false)
+ {
+ }
+ } m_state;
+};
+
+GraphicsLayerQtImpl::GraphicsLayerQtImpl(GraphicsLayerQt* newLayer)
+ : QGraphicsObject(0)
+ , m_layer(newLayer)
+ , m_transformAnimationRunning(false)
+ , m_changeMask(NoChanges)
+{
+ // better to calculate the exposed rect in QGraphicsView than over-render in WebCore
+ // FIXME: test different approaches
+ setFlag(QGraphicsItem::ItemUsesExtendedStyleOption, true);
+
+ // we use graphics-view for compositing, not for interactivity
+ setAcceptedMouseButtons(Qt::NoButton);
+ setEnabled(false);
+
+ // we'll set the cache when we know what's going on
+ setCacheMode(NoCache);
+}
+
+GraphicsLayerQtImpl::~GraphicsLayerQtImpl()
+{
+ // the compositor manages item lifecycle - we don't want the graphics-view
+ // system to automatically delete our items
+
+ const QList<QGraphicsItem*> children = childItems();
+ for (QList<QGraphicsItem*>::const_iterator it = children.begin(); it != children.end(); ++it) {
+ if (QGraphicsItem* item = *it) {
+ if (scene())
+ scene()->removeItem(item);
+ item->setParentItem(0);
+ }
+ }
+
+ // we do, however, own the animations...
+ for (QList<QWeakPointer<QAbstractAnimation> >::iterator it = m_animations.begin(); it != m_animations.end(); ++it)
+ if (QAbstractAnimation* anim = it->data())
+ delete anim;
+}
+
+void GraphicsLayerQtImpl::setBaseTransform(const QTransform& transform)
+{
+ if (!m_layer)
+ return;
+ // webkit has relative-to-size originPoint, graphics-view has a pixel originPoint
+ // here we convert
+ QPointF originTranslate(
+ m_layer->anchorPoint().x() * m_layer->size().width(), m_layer->anchorPoint().y() * m_layer->size().height());
+
+ resetTransform();
+
+ // we have to manage this ourselves because QGraphicsView's transformOrigin is incomplete
+ translate(originTranslate.x(), originTranslate.y());
+ setTransform(transform, true);
+ translate(-originTranslate.x(), -originTranslate.y());
+ m_baseTransfom = transform;
+}
+
+QPainterPath GraphicsLayerQtImpl::opaqueArea() const
+{
+ QPainterPath painterPath;
+ // we try out best to return the opaque area, maybe it will help graphics-view render less items
+ if (m_currentContent.backgroundColor.isValid() && m_currentContent.backgroundColor.alpha() == 0xff)
+ painterPath.addRect(boundingRect());
+ else {
+ if (m_state.contentsOpaque
+ || (m_currentContent.contentType == ColorContentType && m_currentContent.contentsBackgroundColor.alpha() == 0xff)
+ || (m_currentContent.contentType == PixmapContentType && !m_currentContent.pixmap.hasAlpha())) {
+
+ painterPath.addRect(m_state.contentsRect);
+ }
+ }
+ return painterPath;
+}
+
+QRectF GraphicsLayerQtImpl::boundingRect() const
+{
+ return QRectF(QPointF(0, 0), QSizeF(m_size));
+}
+
+void GraphicsLayerQtImpl::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
+{
+ if (m_state.maskLayer && m_state.maskLayer->platformLayer()) {
+ // FIXME: see if this is better done somewhere else
+ GraphicsLayerQtImpl* otherMask = static_cast<GraphicsLayerQtImpl*>(m_state.maskLayer->platformLayer());
+ otherMask->flushChanges(true);
+
+ // CSS3 mask and QGraphicsOpacityEffect are the same thing! we just need to convert...
+ // The conversion is as fast as we can make it - we render the layer once and send it to the QGraphicsOpacityEffect
+ if (!graphicsEffect()) {
+ QPixmap mask(QSize(m_state.maskLayer->size().width(), m_state.maskLayer->size().height()));
+ mask.fill(Qt::transparent);
+ {
+ QPainter p(&mask);
+ p.setRenderHints(painter->renderHints(), true);
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ static_cast<GraphicsLayerQtImpl*>(m_state.maskLayer->platformLayer())->drawContents(&p, option->exposedRect, true);
+ }
+ QGraphicsOpacityEffect* opacityEffect = new QGraphicsOpacityEffect(this);
+ opacityEffect->setOpacity(1);
+ opacityEffect->setOpacityMask(QBrush(mask));
+ setGraphicsEffect(opacityEffect);
+ }
+ }
+ drawContents(painter, option->exposedRect);
+}
+
+void GraphicsLayerQtImpl::drawContents(QPainter* painter, const QRectF& r, bool mask)
+{
+ QRect rect = r.toAlignedRect();
+
+ if (m_currentContent.contentType != HTMLContentType && !m_state.contentsRect.isEmpty())
+ rect = rect.intersected(m_state.contentsRect);
+
+ if (m_currentContent.backgroundColor.isValid())
+ painter->fillRect(r, QColor(m_currentContent.backgroundColor));
+
+ if (!rect.isEmpty()) {
+ switch (m_currentContent.contentType) {
+ case PixmapContentType:
+ // we have to scale the image to the contentsRect
+ // FIXME: a better way would probably be drawPixmap with a src/target rect
+ painter->drawPixmap(rect.topLeft(), m_currentContent.pixmap.scaled(m_state.contentsRect.size()), r);
+ break;
+ case ColorContentType:
+ painter->fillRect(rect, m_currentContent.contentsBackgroundColor);
+ break;
+ default:
+ if (m_state.drawsContent) {
+ // this is the "expensive" bit. we try to minimize calls to this
+ // neck of the woods by proper caching
+ GraphicsContext gc(painter);
+ m_layer->paintGraphicsLayerContents(gc, rect);
+ }
+ break;
+ }
+ }
+}
+
+void GraphicsLayerQtImpl::notifyChange(ChangeMask changeMask)
+{
+ if (!this)
+ return;
+
+ m_changeMask |= changeMask;
+
+ if (m_layer->client())
+ m_layer->client()->notifySyncRequired(m_layer);
+}
+
+void GraphicsLayerQtImpl::flushChanges(bool recursive)
+{
+ // this is the bulk of the work. understanding what the compositor is trying to achieve,
+ // what graphics-view can do, and trying to find a sane common-grounds
+ if (!m_layer || m_changeMask == NoChanges)
+ goto afterLayerChanges;
+
+ if (m_currentContent.contentType == HTMLContentType && (m_changeMask & ParentChange)) {
+ // the WebCore compositor manages item ownership. We have to make sure
+ // graphics-view doesn't try to snatch that ownership...
+ if (!m_layer->parent() && !parentItem())
+ setParentItem(0);
+ else if (m_layer && m_layer->parent() && m_layer->parent()->nativeLayer() != parentItem())
+ setParentItem(m_layer->parent()->nativeLayer());
+ }
+
+ if (m_changeMask & ChildrenChange) {
+ // we basically do an XOR operation on the list of current children
+ // and the list of wanted children, and remove/add
+ QSet<QGraphicsItem*> newChildren;
+ const Vector<GraphicsLayer*> newChildrenVector = (m_layer->children());
+ newChildren.reserve(newChildrenVector.size());
+
+ for (size_t i = 0; i < newChildrenVector.size(); ++i)
+ newChildren.insert(newChildrenVector[i]->platformLayer());
+
+ const QSet<QGraphicsItem*> currentChildren = childItems().toSet();
+ const QSet<QGraphicsItem*> childrenToAdd = newChildren - currentChildren;
+ const QSet<QGraphicsItem*> childrenToRemove = currentChildren - newChildren;
+ for (QSet<QGraphicsItem*>::const_iterator it = childrenToAdd.begin(); it != childrenToAdd.end(); ++it) {
+ if (QGraphicsItem* w = *it)
+ w->setParentItem(this);
+ }
+ for (QSet<QGraphicsItem*>::const_iterator it = childrenToRemove.begin(); it != childrenToRemove.end(); ++it) {
+ if (QGraphicsItem* w = *it)
+ w->setParentItem(0);
+ }
+
+ // children are ordered by z-value, let graphics-view know.
+ for (size_t i = 0; i < newChildrenVector.size(); ++i)
+ if (newChildrenVector[i]->platformLayer())
+ newChildrenVector[i]->platformLayer()->setZValue(i);
+ }
+
+ if (m_changeMask & MaskLayerChange) {
+ // we can't paint here, because we don't know if the mask layer
+ // itself is ready... we'll have to wait till this layer tries to paint
+ setGraphicsEffect(0);
+ if (m_layer->maskLayer())
+ setFlag(ItemClipsChildrenToShape, true);
+ else
+ setFlag(ItemClipsChildrenToShape, m_layer->masksToBounds());
+ update();
+ }
+
+ if ((m_changeMask & PositionChange) && (m_layer->position() != m_state.pos))
+ setPos(m_layer->position().x(), m_layer->position().y());
+
+ if (m_changeMask & SizeChange) {
+ if (m_layer->size() != m_state.size) {
+ prepareGeometryChange();
+ m_size = QSizeF(m_layer->size().width(), m_layer->size().height());
+ }
+ }
+
+ if (m_changeMask & (TransformChange | AnchorPointChange | SizeChange)) {
+ // since we convert a percentage-based origin-point to a pixel-based one,
+ // the anchor-point, transform and size from WebCore all affect the one
+ // that we give Qt
+ if (m_state.transform != m_layer->transform() || m_state.anchorPoint != m_layer->anchorPoint() || m_state.size != m_layer->size())
+ setBaseTransform(QTransform(m_layer->transform()));
+ }
+
+ if (m_changeMask & (ContentChange | DrawsContentChange)) {
+ switch (m_pendingContent.contentType) {
+ case PixmapContentType:
+ // we need cache even for images, because they need to be resized
+ // to the contents rect. maybe this can be optimized though
+ setCacheMode(m_transformAnimationRunning ? ItemCoordinateCache : DeviceCoordinateCache);
+ update();
+ setFlag(ItemHasNoContents, false);
+ break;
+
+ case ColorContentType:
+ // no point in caching a solid-color rectangle
+ setCacheMode(QGraphicsItem::NoCache);
+ if (m_pendingContent.contentType != m_currentContent.contentType || m_pendingContent.contentsBackgroundColor != m_currentContent.contentsBackgroundColor)
+ update();
+ m_state.drawsContent = false;
+ setFlag(ItemHasNoContents, false);
+ break;
+
+ case HTMLContentType:
+ if (m_pendingContent.contentType != m_currentContent.contentType)
+ update();
+ if (!m_state.drawsContent && m_layer->drawsContent())
+ update();
+ if (m_layer->drawsContent())
+ setCacheMode(m_transformAnimationRunning ? ItemCoordinateCache : DeviceCoordinateCache);
+ else
+ setCacheMode(NoCache);
+
+ setFlag(ItemHasNoContents, !m_layer->drawsContent());
+ break;
+ }
+ }
+
+ if ((m_changeMask & OpacityChange) && m_state.opacity != m_layer->opacity())
+ setOpacity(m_layer->opacity());
+
+ if (m_changeMask & ContentsRectChange) {
+ const QRect rect(m_layer->contentsRect());
+ if (m_state.contentsRect != rect) {
+ m_state.contentsRect = rect;
+ update();
+ }
+ }
+
+ if ((m_changeMask & MasksToBoundsChange)
+ && m_state.masksToBounds != m_layer->masksToBounds()) {
+
+ setFlag(QGraphicsItem::ItemClipsToShape, m_layer->masksToBounds());
+ setFlag(QGraphicsItem::ItemClipsChildrenToShape, m_layer->masksToBounds());
+ }
+
+ if ((m_changeMask & ContentsOpaqueChange) && m_state.contentsOpaque != m_layer->contentsOpaque())
+ prepareGeometryChange();
+
+ if (m_changeMask & DisplayChange)
+ update(m_pendingContent.regionToUpdate.boundingRect());
+
+ if ((m_changeMask & BackgroundColorChange) && (m_pendingContent.backgroundColor != m_currentContent.backgroundColor))
+ update();
+
+ // FIXME: the following flags are currently not handled, as they don't have a clear test or are in low priority
+ // GeometryOrientationChange, ContentsOrientationChange, BackfaceVisibilityChange, ChildrenTransformChange
+
+ m_state.maskLayer = m_layer->maskLayer();
+ m_state.pos = m_layer->position();
+ m_state.anchorPoint = m_layer->anchorPoint();
+ m_state.size = m_layer->size();
+ m_state.transform = m_layer->transform();
+ m_state.geoOrientation = m_layer->geometryOrientation();
+ m_state.contentsOrientation =m_layer->contentsOrientation();
+ m_state.opacity = m_layer->opacity();
+ m_state.contentsRect = m_layer->contentsRect();
+ m_state.preserves3D = m_layer->preserves3D();
+ m_state.masksToBounds = m_layer->masksToBounds();
+ m_state.drawsContent = m_layer->drawsContent();
+ m_state.contentsOpaque = m_layer->contentsOpaque();
+ m_state.backfaceVisibility = m_layer->backfaceVisibility();
+ m_currentContent.pixmap = m_pendingContent.pixmap;
+ m_currentContent.contentType = m_pendingContent.contentType;
+ m_currentContent.backgroundColor = m_pendingContent.backgroundColor;
+ m_currentContent.regionToUpdate |= m_pendingContent.regionToUpdate;
+ m_currentContent.contentsBackgroundColor = m_pendingContent.contentsBackgroundColor;
+ m_pendingContent.regionToUpdate = QRegion();
+ m_changeMask = NoChanges;
+
+
+afterLayerChanges:
+ if (!recursive)
+ return;
+
+ const QList<QGraphicsItem*> children = childItems();
+
+ for (QList<QGraphicsItem*>::const_iterator it = children.begin(); it != children.end(); ++it) {
+ if (QGraphicsItem* item = *it)
+ if (GraphicsLayerQtImpl* layer = qobject_cast<GraphicsLayerQtImpl*>(item->toGraphicsObject()))
+ layer->flushChanges(true);
+ }
+}
+
+void GraphicsLayerQtImpl::notifyAnimationStarted()
+{
+ // WebCore notifies javascript when the animation starts
+ // here we're letting it know
+ m_layer->client()->notifyAnimationStarted(m_layer, WTF::currentTime());
+}
+
+GraphicsLayerQt::GraphicsLayerQt(GraphicsLayerClient* client)
+ : GraphicsLayer(client)
+ , m_impl(PassOwnPtr<GraphicsLayerQtImpl>(new GraphicsLayerQtImpl(this)))
+{
+}
+
+GraphicsLayerQt::~GraphicsLayerQt()
+{
+}
+
+// this is the hook for WebCore compositor to know that Qt implements compositing with GraphicsLayerQt
+PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerClient* client)
+{
+ return new GraphicsLayerQt(client);
+}
+
+// reimp from GraphicsLayer.h: Qt is top-down
+GraphicsLayer::CompositingCoordinatesOrientation GraphicsLayer::compositingCoordinatesOrientation()
+{
+ return CompositingCoordinatesTopDown;
+}
+
+// reimp from GraphicsLayer.h: we'll need to update the whole display, and we can't count on the current size because it might change
+void GraphicsLayerQt::setNeedsDisplay()
+{
+ m_impl->m_pendingContent.regionToUpdate = QRegion(QRect(QPoint(0, 0), QSize(size().width(), size().height())));
+ m_impl->notifyChange(GraphicsLayerQtImpl::DisplayChange);
+}
+
+// reimp from GraphicsLayer.h
+void GraphicsLayerQt::setNeedsDisplayInRect(const FloatRect& r)
+{
+ m_impl->m_pendingContent.regionToUpdate|= QRectF(r).toAlignedRect();
+ m_impl->notifyChange(GraphicsLayerQtImpl::DisplayChange);
+}
+
+// reimp from GraphicsLayer.h
+void GraphicsLayerQt::setName(const String& name)
+{
+ m_impl->setObjectName(name);
+ GraphicsLayer::setName(name);
+}
+
+// reimp from GraphicsLayer.h
+void GraphicsLayerQt::setParent(GraphicsLayer* layer)
+{
+ m_impl->notifyChange(GraphicsLayerQtImpl::ParentChange);
+ GraphicsLayer::setParent(layer);
+}
+
+// reimp from GraphicsLayer.h
+bool GraphicsLayerQt::setChildren(const Vector<GraphicsLayer*>& children)
+{
+ m_impl->notifyChange(GraphicsLayerQtImpl::ChildrenChange);
+ return GraphicsLayer::setChildren(children);
+}
+
+// reimp from GraphicsLayer.h
+void GraphicsLayerQt::addChild(GraphicsLayer* layer)
+{
+ m_impl->notifyChange(GraphicsLayerQtImpl::ChildrenChange);
+ GraphicsLayer::addChild(layer);
+}
+
+// reimp from GraphicsLayer.h
+void GraphicsLayerQt::addChildAtIndex(GraphicsLayer* layer, int index)
+{
+ GraphicsLayer::addChildAtIndex(layer, index);
+ m_impl->notifyChange(GraphicsLayerQtImpl::ChildrenChange);
+}
+
+// reimp from GraphicsLayer.h
+void GraphicsLayerQt::addChildAbove(GraphicsLayer* layer, GraphicsLayer* sibling)
+{
+ GraphicsLayer::addChildAbove(layer, sibling);
+ m_impl->notifyChange(GraphicsLayerQtImpl::ChildrenChange);
+}
+
+// reimp from GraphicsLayer.h
+void GraphicsLayerQt::addChildBelow(GraphicsLayer* layer, GraphicsLayer* sibling)
+{
+
+ GraphicsLayer::addChildBelow(layer, sibling);
+ m_impl->notifyChange(GraphicsLayerQtImpl::ChildrenChange);
+}
+
+// reimp from GraphicsLayer.h
+bool GraphicsLayerQt::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild)
+{
+ if (GraphicsLayer::replaceChild(oldChild, newChild)) {
+ m_impl->notifyChange(GraphicsLayerQtImpl::ChildrenChange);
+ return true;
+ }
+
+ return false;
+}
+
+// reimp from GraphicsLayer.h
+void GraphicsLayerQt::removeFromParent()
+{
+ if (parent())
+ m_impl->notifyChange(GraphicsLayerQtImpl::ParentChange);
+ GraphicsLayer::removeFromParent();
+}
+
+// reimp from GraphicsLayer.h
+void GraphicsLayerQt::setMaskLayer(GraphicsLayer* layer)
+{
+ GraphicsLayer::setMaskLayer(layer);
+ m_impl->notifyChange(GraphicsLayerQtImpl::MaskLayerChange);
+}
+
+// reimp from GraphicsLayer.h
+void GraphicsLayerQt::setPosition(const FloatPoint& p)
+{
+ if (position() != p)
+ m_impl->notifyChange(GraphicsLayerQtImpl::PositionChange);
+ GraphicsLayer::setPosition(p);
+}
+
+// reimp from GraphicsLayer.h
+void GraphicsLayerQt::setAnchorPoint(const FloatPoint3D& p)
+{
+ if (anchorPoint() != p)
+ m_impl->notifyChange(GraphicsLayerQtImpl::AnchorPointChange);
+ GraphicsLayer::setAnchorPoint(p);
+}
+
+// reimp from GraphicsLayer.h
+void GraphicsLayerQt::setSize(const FloatSize& size)
+{
+ if (this->size() != size)
+ m_impl->notifyChange(GraphicsLayerQtImpl::SizeChange);
+ GraphicsLayer::setSize(size);
+}
+
+// reimp from GraphicsLayer.h
+void GraphicsLayerQt::setTransform(const TransformationMatrix& t)
+{
+ if (!m_impl->m_transformAnimationRunning && transform() != t)
+ m_impl->notifyChange(GraphicsLayerQtImpl::TransformChange);
+ GraphicsLayer::setTransform(t);
+}
+
+// reimp from GraphicsLayer.h
+void GraphicsLayerQt::setChildrenTransform(const TransformationMatrix& t)
+{
+ GraphicsLayer::setChildrenTransform(t);
+ m_impl->notifyChange(GraphicsLayerQtImpl::ChildrenTransformChange);
+}
+
+// reimp from GraphicsLayer.h
+void GraphicsLayerQt::setPreserves3D(bool b)
+{
+ if (b != preserves3D());
+ m_impl->notifyChange(GraphicsLayerQtImpl::Preserves3DChange);
+ GraphicsLayer::setPreserves3D(b);
+}
+
+// reimp from GraphicsLayer.h
+void GraphicsLayerQt::setMasksToBounds(bool b)
+{
+ GraphicsLayer::setMasksToBounds(b);
+ m_impl->notifyChange(GraphicsLayerQtImpl::MasksToBoundsChange);
+}
+
+// reimp from GraphicsLayer.h
+void GraphicsLayerQt::setDrawsContent(bool b)
+{
+ m_impl->notifyChange(GraphicsLayerQtImpl::DrawsContentChange);
+ GraphicsLayer::setDrawsContent(b);
+}
+
+// reimp from GraphicsLayer.h
+void GraphicsLayerQt::setBackgroundColor(const Color& c)
+{
+ m_impl->notifyChange(GraphicsLayerQtImpl::BackgroundColorChange);
+ m_impl->m_pendingContent.backgroundColor = c;
+ GraphicsLayer::setBackgroundColor(c);
+}
+
+// reimp from GraphicsLayer.h
+void GraphicsLayerQt::clearBackgroundColor()
+{
+ m_impl->m_pendingContent.backgroundColor = QColor();
+ m_impl->notifyChange(GraphicsLayerQtImpl::BackgroundColorChange);
+ GraphicsLayer::clearBackgroundColor();
+}
+
+// reimp from GraphicsLayer.h
+void GraphicsLayerQt::setContentsOpaque(bool b)
+{
+ m_impl->notifyChange(GraphicsLayerQtImpl::ContentsOpaqueChange);
+ GraphicsLayer::setContentsOpaque(b);
+}
+
+// reimp from GraphicsLayer.h
+void GraphicsLayerQt::setBackfaceVisibility(bool b)
+{
+ m_impl->notifyChange(GraphicsLayerQtImpl::BackfaceVisibilityChange);
+ GraphicsLayer::setBackfaceVisibility(b);
+}
+
+// reimp from GraphicsLayer.h
+void GraphicsLayerQt::setOpacity(float o)
+{
+ if (!m_impl->m_opacityAnimationRunning && opacity() != o)
+ m_impl->notifyChange(GraphicsLayerQtImpl::OpacityChange);
+ GraphicsLayer::setOpacity(o);
+}
+
+// reimp from GraphicsLayer.h
+void GraphicsLayerQt::setContentsRect(const IntRect& r)
+{
+ m_impl->notifyChange(GraphicsLayerQtImpl::ContentsRectChange);
+ GraphicsLayer::setContentsRect(r);
+}
+
+// reimp from GraphicsLayer.h
+void GraphicsLayerQt::setContentsToImage(Image* image)
+{
+ m_impl->notifyChange(GraphicsLayerQtImpl::ContentChange);
+ m_impl->m_pendingContent.contentType = GraphicsLayerQtImpl::HTMLContentType;
+ GraphicsLayer::setContentsToImage(image);
+ if (image) {
+ QPixmap* pxm = image->nativeImageForCurrentFrame();
+ if (pxm) {
+ m_impl->m_pendingContent.pixmap = *pxm;
+ m_impl->m_pendingContent.contentType = GraphicsLayerQtImpl::PixmapContentType;
+ return;
+ }
+ }
+ m_impl->m_pendingContent.pixmap = QPixmap();
+}
+
+// reimp from GraphicsLayer.h
+void GraphicsLayerQt::setContentsBackgroundColor(const Color& color)
+{
+ m_impl->notifyChange(GraphicsLayerQtImpl::ContentChange);
+ m_impl->m_pendingContent.contentType = GraphicsLayerQtImpl::ColorContentType;
+ m_impl->m_pendingContent.contentsBackgroundColor = QColor(color);
+ GraphicsLayer::setContentsBackgroundColor(color);
+}
+
+// reimp from GraphicsLayer.h
+void GraphicsLayerQt::setGeometryOrientation(CompositingCoordinatesOrientation orientation)
+{
+ m_impl->notifyChange(GraphicsLayerQtImpl::GeometryOrientationChange);
+ GraphicsLayer::setGeometryOrientation(orientation);
+}
+
+// reimp from GraphicsLayer.h
+void GraphicsLayerQt::setContentsOrientation(CompositingCoordinatesOrientation orientation)
+{
+ m_impl->notifyChange(GraphicsLayerQtImpl::ContentsOrientationChange);
+ GraphicsLayer::setContentsOrientation(orientation);
+}
+
+// reimp from GraphicsLayer.h
+void GraphicsLayerQt::distributeOpacity(float o)
+{
+ m_impl->notifyChange(GraphicsLayerQtImpl::OpacityChange);
+ m_impl->m_state.distributeOpacity = true;
+}
+
+// reimp from GraphicsLayer.h
+float GraphicsLayerQt::accumulatedOpacity() const
+{
+ return m_impl->effectiveOpacity();
+}
+
+// reimp from GraphicsLayer.h
+void GraphicsLayerQt::syncCompositingState()
+{
+ m_impl->flushChanges();
+ GraphicsLayer::syncCompositingState();
+}
+
+// reimp from GraphicsLayer.h
+NativeLayer GraphicsLayerQt::nativeLayer() const
+{
+ return m_impl.get();
+}
+
+// reimp from GraphicsLayer.h
+PlatformLayer* GraphicsLayerQt::platformLayer() const
+{
+ return m_impl.get();
+}
+
+// now we start dealing with WebCore animations translated to Qt animations
+
+template <typename T>
+struct KeyframeValueQt {
+ TimingFunction timingFunction;
+ T value;
+};
+
+// we copy this from the AnimationBase.cpp
+static inline double solveEpsilon(double duration)
+{
+ return 1.0 / (200.0 * duration);
+}
+
+static inline double solveCubicBezierFunction(qreal p1x, qreal p1y, qreal p2x, qreal p2y, double t, double duration)
+{
+ UnitBezier bezier(p1x, p1y, p2x, p2y);
+ return bezier.solve(t, solveEpsilon(duration));
+}
+
+// we want the timing function to be as close as possible to what the web-developer intended, so we're using the same function used by WebCore when compositing is disabled
+// Using easing-curves would probably work for some of the cases, but wouldn't really buy us anything as we'd have to convert the bezier function back to an easing curve
+static inline qreal applyTimingFunction(const TimingFunction& timingFunction, qreal progress, int duration)
+{
+ if (timingFunction.type() == LinearTimingFunction)
+ return progress;
+ if (timingFunction.type() == CubicBezierTimingFunction) {
+ return solveCubicBezierFunction(timingFunction.x1(),
+ timingFunction.y1(),
+ timingFunction.x2(),
+ timingFunction.y2(),
+ double(progress), double(duration) / 1000);
+ }
+ return progress;
+}
+
+// helper functions to safely get a value out of WebCore's AnimationValue*
+static void webkitAnimationToQtAnimationValue(const AnimationValue* animationValue, TransformOperations& transformOperations)
+{
+ transformOperations = TransformOperations();
+ if (!animationValue)
+ return;
+
+ const TransformOperations* ops = static_cast<const TransformAnimationValue*>(animationValue)->value();
+
+ if (ops)
+ transformOperations = *ops;
+}
+
+static void webkitAnimationToQtAnimationValue(const AnimationValue* animationValue, qreal& realValue)
+{
+ realValue = animationValue ? static_cast<const FloatAnimationValue*>(animationValue)->value() : 0;
+}
+
+// we put a bit of the functionality in a base class to allow casting and to save some code size
+class AnimationQtBase : public QAbstractAnimation {
+public:
+ AnimationQtBase(GraphicsLayerQtImpl* layer, const KeyframeValueList& values, const IntSize& boxSize, const Animation* anim, const QString & name)
+ : QAbstractAnimation(0)
+ , m_layer(layer)
+ , m_boxSize(boxSize)
+ , m_duration(anim->duration() * 1000)
+ , m_isAlternate(anim->direction() == Animation::AnimationDirectionAlternate)
+ , m_webkitPropertyID(values.property())
+ , m_keyframesName(name)
+ {
+ }
+
+ virtual void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState)
+ {
+ QAbstractAnimation::updateState(newState, oldState);
+
+ // for some reason I have do this asynchronously - or the animation won't work
+ if (newState == Running && oldState == Stopped)
+ QTimer::singleShot(0, m_layer.data(), SLOT(notifyAnimationStarted()));
+ }
+
+ virtual int duration() const { return m_duration; }
+
+ QWeakPointer<GraphicsLayerQtImpl> m_layer;
+ IntSize m_boxSize;
+ int m_duration;
+ bool m_isAlternate;
+ AnimatedPropertyID m_webkitPropertyID;
+ QString m_keyframesName;
+};
+
+// we'd rather have a templatized QAbstractAnimation than QPropertyAnimation / QVariantAnimation;
+// Since we know the types that we're dealing with, the QObject/QProperty/QVariant abstraction
+// buys us very little in this case, for too much overhead
+template <typename T>
+class AnimationQt : public AnimationQtBase {
+
+public:
+ AnimationQt(GraphicsLayerQtImpl* layer, const KeyframeValueList& values, const IntSize& boxSize, const Animation* anim, const QString & name)
+ :AnimationQtBase(layer, values, boxSize, anim, name)
+ {
+ // copying those WebCore structures is not trivial, we have to do it like this
+ for (size_t i = 0; i < values.size(); ++i) {
+ const AnimationValue* animationValue = values.at(i);
+ KeyframeValueQt<T> keyframeValue;
+ if (animationValue->timingFunction())
+ keyframeValue.timingFunction = *animationValue->timingFunction();
+ webkitAnimationToQtAnimationValue(animationValue, keyframeValue.value);
+ m_keyframeValues[animationValue->keyTime()] = keyframeValue;
+ }
+ }
+
+protected:
+
+ // this is the part that differs between animated properties
+ virtual void applyFrame(const T& fromValue, const T& toValue, qreal progress) = 0;
+
+ virtual void updateCurrentTime(int currentTime)
+ {
+ if (!m_layer)
+ return;
+
+ qreal progress = qreal(currentLoopTime()) / duration();
+
+ if (m_isAlternate && currentLoop()%2)
+ progress = 1-progress;
+
+ if (m_keyframeValues.isEmpty())
+ return;
+
+ // we find the current from-to keyframes in our little map
+ typename QMap<qreal, KeyframeValueQt<T> >::iterator it = m_keyframeValues.find(progress);
+
+ // we didn't find an exact match, we try the closest match (lower bound)
+ if (it == m_keyframeValues.end())
+ it = m_keyframeValues.lowerBound(progress)-1;
+
+ // we didn't find any match - we use the first keyframe
+ if (it == m_keyframeValues.end())
+ it = m_keyframeValues.begin();
+
+ typename QMap<qreal, KeyframeValueQt<T> >::iterator it2 = it+1;
+ if (it2 == m_keyframeValues.end())
+ it2 = m_keyframeValues.begin();
+ const KeyframeValueQt<T>& fromKeyframe = it.value();
+ const KeyframeValueQt<T>& toKeyframe = it2.value();
+
+ const TimingFunction& timingFunc = fromKeyframe.timingFunction;
+ const T& fromValue = fromKeyframe.value;
+ const T& toValue = toKeyframe.value;
+
+ // now we have a source keyframe, origin keyframe and a timing function
+ // we can now process the progress and apply the frame
+ qreal normalizedProgress = (it.key() == it2.key()) ? 0 : (progress - it.key()) / (it2.key() - it.key());
+ normalizedProgress = applyTimingFunction(timingFunc, normalizedProgress, duration() / 1000);
+ applyFrame(fromValue, toValue, normalizedProgress);
+ }
+
+ QMap<qreal, KeyframeValueQt<T> > m_keyframeValues;
+};
+
+class TransformAnimationQt : public AnimationQt<TransformOperations> {
+public:
+ TransformAnimationQt(GraphicsLayerQtImpl* layer, const KeyframeValueList& values, const IntSize& boxSize, const Animation* anim, const QString & name)
+ : AnimationQt<TransformOperations>(layer, values, boxSize, anim, name)
+ {
+ }
+
+ ~TransformAnimationQt()
+ {
+ // this came up during the compositing/animation LayoutTests
+ // when the animation dies, the transform has to go back to default
+ if (m_layer)
+ m_layer.data()->setBaseTransform(QTransform(m_layer.data()->m_layer->transform()));
+ }
+
+ // the idea is that we let WebCore manage the transform-operations
+ // and Qt just manages the animation heartbeat and the bottom-line QTransform
+ // we get the performance not by using QTransform instead of TransformationMatrix, but by proper caching of
+ // items that are expensive for WebCore to render. We want the rest to be as close to WebCore's idea as possible.
+ virtual void applyFrame(const TransformOperations& sourceOperations, const TransformOperations& targetOperations, qreal progress)
+ {
+ TransformationMatrix transformMatrix;
+
+ // this looks simple but is really tricky to get right. Use caution.
+ for (size_t i = 0; i < targetOperations.size(); ++i)
+ targetOperations.operations()[i]->blend(sourceOperations.at(i), progress)->apply(transformMatrix, m_boxSize);
+
+ m_layer.data()->setBaseTransform(QTransform(transformMatrix));
+ }
+
+ virtual void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState)
+ {
+ AnimationQtBase::updateState(newState, oldState);
+ if (!m_layer)
+ return;
+ m_layer.data()->flushChanges(true);
+
+ // to increase FPS, we use a less accurate caching mechanism while animation is going on
+ // this is a UX choice that should probably be customizable
+ if (newState == QAbstractAnimation::Running) {
+ m_layer.data()->m_transformAnimationRunning = true;
+ if (m_layer.data()->cacheMode() == QGraphicsItem::DeviceCoordinateCache)
+ m_layer.data()->setCacheMode(QGraphicsItem::ItemCoordinateCache);
+ } else {
+ m_layer.data()->m_transformAnimationRunning = false;
+ if (m_layer.data()->cacheMode() == QGraphicsItem::ItemCoordinateCache)
+ m_layer.data()->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
+ }
+ }
+};
+
+class OpacityAnimationQt : public AnimationQt<qreal> {
+public:
+ OpacityAnimationQt(GraphicsLayerQtImpl* layer, const KeyframeValueList& values, const IntSize& boxSize, const Animation* anim, const QString & name)
+ : AnimationQt<qreal>(layer, values, boxSize, anim, name)
+ {
+ }
+
+ virtual void applyFrame(const qreal& fromValue, const qreal& toValue, qreal progress)
+ {
+ m_layer.data()->setOpacity(qMin<qreal>(qMax<qreal>(fromValue + (toValue-fromValue)*progress, 0), 1));
+ }
+
+ virtual void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState)
+ {
+ QAbstractAnimation::updateState(newState, oldState);
+ if (m_layer)
+ m_layer.data()->m_opacityAnimationRunning = (newState == QAbstractAnimation::Running);
+ }
+};
+
+bool GraphicsLayerQt::addAnimation(const KeyframeValueList& values, const IntSize& boxSize, const Animation* anim, const String& keyframesName, double timeOffset)
+{
+ if (!anim->duration() || !anim->iterationCount())
+ return false;
+
+ QAbstractAnimation* newAnim;
+
+ switch (values.property()) {
+ case AnimatedPropertyOpacity:
+ newAnim = new OpacityAnimationQt(m_impl.get(), values, boxSize, anim, keyframesName);
+ break;
+ case AnimatedPropertyWebkitTransform:
+ newAnim = new TransformAnimationQt(m_impl.get(), values, boxSize, anim, keyframesName);
+ break;
+ default:
+ return false;
+ }
+
+ // we make sure WebCore::Animation and QAnimation are on the same terms
+ newAnim->setLoopCount(anim->iterationCount());
+ m_impl->m_animations.append(QWeakPointer<QAbstractAnimation>(newAnim));
+ QObject::connect(&m_impl->m_suspendTimer, SIGNAL(timeout()), newAnim, SLOT(resume()));
+ timeOffset += anim->delay();
+
+ // flush now or flicker...
+ m_impl->flushChanges(false);
+
+ if (timeOffset)
+ QTimer::singleShot(timeOffset * 1000, newAnim, SLOT(start()));
+ else
+ newAnim->start();
+
+ QObject::connect(newAnim, SIGNAL(finished()), newAnim, SLOT(deleteLater()));
+
+ return true;
+}
+
+void GraphicsLayerQt::removeAnimationsForProperty(AnimatedPropertyID id)
+{
+ for (QList<QWeakPointer<QAbstractAnimation> >::iterator it = m_impl->m_animations.begin(); it != m_impl->m_animations.end(); ++it) {
+ if (*it) {
+ AnimationQtBase* anim = static_cast<AnimationQtBase*>(it->data());
+ if (anim && anim->m_webkitPropertyID == id) {
+ delete anim;
+ it = m_impl->m_animations.erase(it);
+ --it;
+ }
+ }
+ }
+}
+
+void GraphicsLayerQt::removeAnimationsForKeyframes(const String& name)
+{
+ for (QList<QWeakPointer<QAbstractAnimation> >::iterator it = m_impl->m_animations.begin(); it != m_impl->m_animations.end(); ++it) {
+ if (*it) {
+ AnimationQtBase* anim = static_cast<AnimationQtBase*>((*it).data());
+ if (anim && anim->m_keyframesName == QString(name)) {
+ (*it).data()->deleteLater();
+ it = m_impl->m_animations.erase(it);
+ --it;
+ }
+ }
+ }
+}
+
+void GraphicsLayerQt::pauseAnimation(const String& name, double timeOffset)
+{
+ for (QList<QWeakPointer<QAbstractAnimation> >::iterator it = m_impl->m_animations.begin(); it != m_impl->m_animations.end(); ++it) {
+ if (*it) {
+ AnimationQtBase* anim = static_cast<AnimationQtBase*>((*it).data());
+ if (anim && anim->m_keyframesName == QString(name))
+ QTimer::singleShot(timeOffset * 1000, anim, SLOT(pause()));
+ }
+ }
+}
+
+void GraphicsLayerQt::suspendAnimations(double time)
+{
+ if (m_impl->m_suspendTimer.isActive()) {
+ m_impl->m_suspendTimer.stop();
+ m_impl->m_suspendTimer.start(time * 1000);
+ } else {
+ for (QList<QWeakPointer<QAbstractAnimation> >::iterator it = m_impl->m_animations.begin(); it != m_impl->m_animations.end(); ++it) {
+ QAbstractAnimation* anim = it->data();
+ if (anim)
+ anim->pause();
+ }
+ }
+}
+
+void GraphicsLayerQt::resumeAnimations()
+{
+ if (m_impl->m_suspendTimer.isActive()) {
+ m_impl->m_suspendTimer.stop();
+ for (QList<QWeakPointer<QAbstractAnimation> >::iterator it = m_impl->m_animations.begin(); it != m_impl->m_animations.end(); ++it) {
+ QAbstractAnimation* anim = (*it).data();
+ if (anim)
+ anim->resume();
+ }
+ }
+}
+
+}
+
+#include <GraphicsLayerQt.moc>
diff --git a/WebCore/platform/graphics/qt/GraphicsLayerQt.h b/WebCore/platform/graphics/qt/GraphicsLayerQt.h
new file mode 100644
index 0000000..3a53bd9
--- /dev/null
+++ b/WebCore/platform/graphics/qt/GraphicsLayerQt.h
@@ -0,0 +1,85 @@
+/*
+ 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 GraphicsLayerQt_h
+#define GraphicsLayerQt_h
+
+#include "GraphicsLayer.h"
+#include "GraphicsLayerClient.h"
+
+namespace WebCore {
+
+class GraphicsLayerQtImpl;
+
+class GraphicsLayerQt : public GraphicsLayer {
+ friend class GraphicsLayerQtImpl;
+
+public:
+ GraphicsLayerQt(GraphicsLayerClient*);
+ virtual ~GraphicsLayerQt();
+
+ // reimps from GraphicsLayer.h
+ virtual NativeLayer nativeLayer() const;
+ virtual PlatformLayer* platformLayer() const;
+ virtual void setNeedsDisplay();
+ virtual void setNeedsDisplayInRect(const FloatRect&);
+ virtual void setParent(GraphicsLayer* layer);
+ virtual void setName(const String& name);
+ virtual bool setChildren(const Vector<GraphicsLayer*>&);
+ virtual void addChild(GraphicsLayer*);
+ virtual void addChildAtIndex(GraphicsLayer*, int index);
+ virtual void addChildAbove(GraphicsLayer* layer, GraphicsLayer* sibling);
+ virtual void addChildBelow(GraphicsLayer* layer, GraphicsLayer* sibling);
+ virtual bool replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild);
+ virtual void removeFromParent();
+ virtual void setMaskLayer(GraphicsLayer* layer);
+ virtual void setPosition(const FloatPoint& p);
+ virtual void setAnchorPoint(const FloatPoint3D& p);
+ virtual void setSize(const FloatSize& size);
+ virtual void setTransform(const TransformationMatrix& t);
+ virtual void setChildrenTransform(const TransformationMatrix& t);
+ virtual void setPreserves3D(bool b);
+ virtual void setMasksToBounds(bool b);
+ virtual void setDrawsContent(bool b);
+ virtual void setBackgroundColor(const Color&);
+ virtual void clearBackgroundColor();
+ virtual void setContentsOpaque(bool b);
+ virtual void setBackfaceVisibility(bool b);
+ virtual void setOpacity(float opacity);
+ virtual void setContentsRect(const IntRect& r);
+ virtual bool addAnimation(const KeyframeValueList&, const IntSize& boxSize, const Animation*, const String& keyframesName, double timeOffset);
+ virtual void removeAnimationsForProperty(AnimatedPropertyID);
+ virtual void removeAnimationsForKeyframes(const String& keyframesName);
+ virtual void pauseAnimation(const String& keyframesName, double timeOffset);
+ virtual void suspendAnimations(double time);
+ virtual void resumeAnimations();
+ virtual void setContentsToImage(Image*);
+ virtual void setContentsBackgroundColor(const Color&);
+ virtual void setGeometryOrientation(CompositingCoordinatesOrientation orientation);
+ virtual void setContentsOrientation(CompositingCoordinatesOrientation orientation);
+ virtual void distributeOpacity(float);
+ virtual float accumulatedOpacity() const;
+ virtual void syncCompositingState();
+
+private:
+ OwnPtr<GraphicsLayerQtImpl> m_impl;
+};
+
+}
+#endif // GraphicsLayerQt_h
diff --git a/WebCore/platform/graphics/qt/ImageBufferQt.cpp b/WebCore/platform/graphics/qt/ImageBufferQt.cpp
index 5255428..d831566 100644
--- a/WebCore/platform/graphics/qt/ImageBufferQt.cpp
+++ b/WebCore/platform/graphics/qt/ImageBufferQt.cpp
@@ -114,7 +114,7 @@ void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookUpTable)
value = qRgba(lookUpTable[qRed(value)],
lookUpTable[qGreen(value)],
lookUpTable[qBlue(value)],
- lookUpTable[qAlpha(value)]);
+ qAlpha(value));
image.setPixel(x, y, value);
}
}
diff --git a/WebCore/platform/graphics/qt/ImageDecoderQt.cpp b/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
index b6823dd..234f78b 100644
--- a/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
+++ b/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
@@ -47,16 +47,12 @@ ImageDecoder* ImageDecoder::create(const SharedBuffer& data)
}
ImageDecoderQt::ImageDecoderQt()
- : m_buffer(0)
- , m_reader(0)
- , m_repetitionCount(cAnimationNone)
+ : m_repetitionCount(cAnimationNone)
{
}
ImageDecoderQt::~ImageDecoderQt()
{
- delete m_reader;
- delete m_buffer;
}
void ImageDecoderQt::setData(SharedBuffer* data, bool allDataReceived)
@@ -77,10 +73,16 @@ void ImageDecoderQt::setData(SharedBuffer* data, bool allDataReceived)
// Attempt to load the data
QByteArray imageData = QByteArray::fromRawData(m_data->data(), m_data->size());
- m_buffer = new QBuffer;
+ m_buffer.set(new QBuffer);
m_buffer->setData(imageData);
m_buffer->open(QBuffer::ReadOnly);
- m_reader = new QImageReader(m_buffer, m_format);
+ m_reader.set(new QImageReader(m_buffer.get(), m_format));
+
+ // This will force the JPEG decoder to use JDCT_IFAST
+ m_reader->setQuality(49);
+
+ // QImageReader only allows retrieving the format before reading the image
+ m_format = m_reader->format();
}
bool ImageDecoderQt::isSizeAvailable()
@@ -158,7 +160,6 @@ void ImageDecoderQt::internalDecodeSize()
if (size.isEmpty())
return failRead();
- m_format = m_reader->format();
setSize(size.width(), size.height());
}
@@ -178,10 +179,8 @@ void ImageDecoderQt::internalReadImage(size_t frameIndex)
if (m_frameBufferCache[i].status() != RGBA32Buffer::FrameComplete)
return;
- delete m_reader;
- delete m_buffer;
- m_buffer = 0;
- m_reader = 0;
+ m_reader.clear();
+ m_buffer.clear();
}
void ImageDecoderQt::internalHandleCurrentImage(size_t frameIndex)
@@ -229,10 +228,8 @@ void ImageDecoderQt::forceLoadEverything()
void ImageDecoderQt::failRead()
{
setFailed();
- delete m_reader;
- delete m_buffer;
- m_reader = 0;
- m_buffer = 0;
+ m_reader.clear();
+ m_buffer.clear();
}
}
diff --git a/WebCore/platform/graphics/qt/ImageDecoderQt.h b/WebCore/platform/graphics/qt/ImageDecoderQt.h
index d11b938..be9a9b0 100644
--- a/WebCore/platform/graphics/qt/ImageDecoderQt.h
+++ b/WebCore/platform/graphics/qt/ImageDecoderQt.h
@@ -33,6 +33,7 @@
#include <QtCore/QList>
#include <QtCore/QHash>
#include <QtCore/QBuffer>
+#include <wtf/OwnPtr.h>
namespace WebCore {
@@ -66,8 +67,8 @@ private:
private:
QByteArray m_format;
- QBuffer* m_buffer;
- QImageReader* m_reader;
+ OwnPtr<QBuffer> m_buffer;
+ OwnPtr<QImageReader> m_reader;
mutable int m_repetitionCount;
};
diff --git a/WebCore/platform/graphics/qt/ImageQt.cpp b/WebCore/platform/graphics/qt/ImageQt.cpp
index 9a82911..fea1448 100644
--- a/WebCore/platform/graphics/qt/ImageQt.cpp
+++ b/WebCore/platform/graphics/qt/ImageQt.cpp
@@ -213,7 +213,7 @@ void BitmapImage::checkForSolidColor()
m_solidColor = QColor::fromRgba(framePixmap->toImage().pixel(0, 0));
}
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
PassRefPtr<BitmapImage> BitmapImage::create(HBITMAP hBitmap)
{
return BitmapImage::create(new QPixmap(QPixmap::fromWinHBITMAP(hBitmap)));
diff --git a/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp b/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp
index f446755..3274db5 100644
--- a/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp
+++ b/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp
@@ -38,14 +38,16 @@
#include <QUrl>
#include <QEvent>
-#include <audiooutput.h>
-#include <mediaobject.h>
-#include <videowidget.h>
+#include <phonon/path.h>
+#include <phonon/audiooutput.h>
+#include <phonon/mediaobject.h>
+#include <phonon/videowidget.h>
using namespace Phonon;
#define LOG_MEDIAOBJECT() (LOG(Media, "%s", debugMediaObject(this, *m_mediaObject).constData()))
+#if !LOG_DISABLED
static QByteArray debugMediaObject(WebCore::MediaPlayerPrivate* mediaPlayer, const MediaObject& mediaObject)
{
QByteArray byteArray;
@@ -73,6 +75,7 @@ static QByteArray debugMediaObject(WebCore::MediaPlayerPrivate* mediaPlayer, con
return byteArray;
}
+#endif
using namespace WTF;
@@ -89,9 +92,7 @@ MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
{
// Hint to Phonon to disable overlay painting
m_videoWidget->setAttribute(Qt::WA_DontShowOnScreen);
-#if QT_VERSION < 0x040500
m_videoWidget->setAttribute(Qt::WA_QuitOnClose, false);
-#endif
createPath(m_mediaObject, m_videoWidget);
createPath(m_mediaObject, m_audioOutput);
@@ -256,11 +257,6 @@ float MediaPlayerPrivate::currentTime() const
return currentTime;
}
-void MediaPlayerPrivate::setEndTime(float)
-{
- notImplemented();
-}
-
PassRefPtr<TimeRanges> MediaPlayerPrivate::buffered() const
{
notImplemented();
@@ -279,12 +275,6 @@ unsigned MediaPlayerPrivate::bytesLoaded() const
return 0;
}
-bool MediaPlayerPrivate::totalBytesKnown() const
-{
- //notImplemented();
- return false;
-}
-
unsigned MediaPlayerPrivate::totalBytes() const
{
//notImplemented();
@@ -308,14 +298,6 @@ void MediaPlayerPrivate::setMuted(bool muted)
m_audioOutput->setMuted(muted);
}
-
-int MediaPlayerPrivate::dataRate() const
-{
- // This is not used at the moment
- return 0;
-}
-
-
MediaPlayer::NetworkState MediaPlayerPrivate::networkState() const
{
const QMetaObject* metaObj = this->metaObject();
@@ -502,7 +484,7 @@ void MediaPlayerPrivate::aboutToFinish()
void MediaPlayerPrivate::totalTimeChanged(qint64 totalTime)
{
- LOG(Media, "MediaPlayerPrivatePhonon::totalTimeChanged(%d)", totalTime);
+ LOG(Media, "MediaPlayerPrivatePhonon::totalTimeChanged(%lld)", totalTime);
LOG_MEDIAOBJECT();
}
diff --git a/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.h b/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.h
index e1193b6..e7630a1 100644
--- a/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.h
+++ b/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.h
@@ -94,21 +94,17 @@ namespace WebCore {
float duration() const;
float currentTime() const;
void seek(float);
- void setEndTime(float);
void setRate(float);
void setVolume(float);
void setMuted(bool);
- int dataRate() const;
-
MediaPlayer::NetworkState networkState() const;
MediaPlayer::ReadyState readyState() const;
PassRefPtr<TimeRanges> buffered() const;
float maxTimeSeekable() const;
unsigned bytesLoaded() const;
- bool totalBytesKnown() const;
unsigned totalBytes() const;
void setVisible(bool);
diff --git a/WebCore/platform/graphics/qt/PathQt.cpp b/WebCore/platform/graphics/qt/PathQt.cpp
index e5cecc8..4716d32 100644
--- a/WebCore/platform/graphics/qt/PathQt.cpp
+++ b/WebCore/platform/graphics/qt/PathQt.cpp
@@ -51,38 +51,32 @@
namespace WebCore {
Path::Path()
- : m_path(new QPainterPath())
{
}
Path::~Path()
{
- delete m_path;
}
Path::Path(const Path& other)
- : m_path(new QPainterPath(*other.platformPath()))
+ : m_path(other.m_path)
{
}
Path& Path::operator=(const Path& other)
{
- if (&other != this) {
- delete m_path;
- m_path = new QPainterPath(*other.platformPath());
- }
-
+ m_path = other.m_path;
return *this;
}
bool Path::contains(const FloatPoint& point, WindRule rule) const
{
- Qt::FillRule savedRule = m_path->fillRule();
- m_path->setFillRule(rule == RULE_EVENODD ? Qt::OddEvenFill : Qt::WindingFill);
+ Qt::FillRule savedRule = m_path.fillRule();
+ const_cast<QPainterPath*>(&m_path)->setFillRule(rule == RULE_EVENODD ? Qt::OddEvenFill : Qt::WindingFill);
- bool contains = m_path->contains(point);
+ bool contains = m_path.contains(point);
- m_path->setFillRule(savedRule);
+ const_cast<QPainterPath*>(&m_path)->setFillRule(savedRule);
return contains;
}
@@ -105,19 +99,19 @@ bool Path::strokeContains(StrokeStyleApplier* applier, const FloatPoint& point)
stroke.setDashPattern(pen.dashPattern());
stroke.setDashOffset(pen.dashOffset());
- return (stroke.createStroke(*platformPath())).contains(point);
+ return stroke.createStroke(m_path).contains(point);
}
void Path::translate(const FloatSize& size)
{
QTransform matrix;
matrix.translate(size.width(), size.height());
- *m_path = (*m_path) * matrix;
+ m_path = m_path * matrix;
}
FloatRect Path::boundingRect() const
{
- return m_path->boundingRect();
+ return m_path.boundingRect();
}
FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier)
@@ -138,35 +132,35 @@ FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier)
stroke.setDashPattern(pen.dashPattern());
stroke.setDashOffset(pen.dashOffset());
}
- return (stroke.createStroke(*platformPath())).boundingRect();
+ return stroke.createStroke(m_path).boundingRect();
}
void Path::moveTo(const FloatPoint& point)
{
- m_path->moveTo(point);
+ m_path.moveTo(point);
}
void Path::addLineTo(const FloatPoint& p)
{
- m_path->lineTo(p);
+ m_path.lineTo(p);
}
void Path::addQuadCurveTo(const FloatPoint& cp, const FloatPoint& p)
{
- m_path->quadTo(cp, p);
+ m_path.quadTo(cp, p);
}
void Path::addBezierCurveTo(const FloatPoint& cp1, const FloatPoint& cp2, const FloatPoint& p)
{
- m_path->cubicTo(cp1, cp2, p);
+ m_path.cubicTo(cp1, cp2, p);
}
void Path::addArcTo(const FloatPoint& p1, const FloatPoint& p2, float radius)
{
- FloatPoint p0(m_path->currentPosition());
+ FloatPoint p0(m_path.currentPosition());
if ((p1.x() == p0.x() && p1.y() == p0.y()) || (p1.x() == p2.x() && p1.y() == p2.y()) || radius == 0.f) {
- m_path->lineTo(p1);
+ m_path.lineTo(p1);
return;
}
@@ -178,7 +172,7 @@ void Path::addArcTo(const FloatPoint& p1, const FloatPoint& p2, float radius)
double cos_phi = (p1p0.x() * p1p2.x() + p1p0.y() * p1p2.y()) / (p1p0_length * p1p2_length);
// all points on a line logic
if (cos_phi == -1) {
- m_path->lineTo(p1);
+ m_path.lineTo(p1);
return;
}
if (cos_phi == 1) {
@@ -186,7 +180,7 @@ void Path::addArcTo(const FloatPoint& p1, const FloatPoint& p2, float radius)
unsigned int max_length = 65535;
double factor_max = max_length / p1p0_length;
FloatPoint ep((p0.x() + factor_max * p1p0.x()), (p0.y() + factor_max * p1p0.y()));
- m_path->lineTo(ep);
+ m_path.lineTo(ep);
return;
}
@@ -226,14 +220,14 @@ void Path::addArcTo(const FloatPoint& p1, const FloatPoint& p2, float radius)
if ((sa < ea) && ((ea - sa) > piDouble))
anticlockwise = true;
- m_path->lineTo(t_p1p0);
+ m_path.lineTo(t_p1p0);
addArc(p, radius, sa, ea, anticlockwise);
}
void Path::closeSubpath()
{
- m_path->closeSubpath();
+ m_path.closeSubpath();
}
#define DEGREES(t) ((t) * 180.0 / M_PI)
@@ -275,32 +269,32 @@ void Path::addArc(const FloatPoint& p, float r, float sar, float ear, bool antic
span += ea - sa;
}
- m_path->moveTo(QPointF(xc + radius * cos(sar),
+ m_path.moveTo(QPointF(xc + radius * cos(sar),
yc - radius * sin(sar)));
- m_path->arcTo(xs, ys, width, height, sa, span);
+ m_path.arcTo(xs, ys, width, height, sa, span);
}
void Path::addRect(const FloatRect& r)
{
- m_path->addRect(r.x(), r.y(), r.width(), r.height());
+ m_path.addRect(r.x(), r.y(), r.width(), r.height());
}
void Path::addEllipse(const FloatRect& r)
{
- m_path->addEllipse(r.x(), r.y(), r.width(), r.height());
+ m_path.addEllipse(r.x(), r.y(), r.width(), r.height());
}
void Path::clear()
{
- *m_path = QPainterPath();
+ m_path = QPainterPath();
}
bool Path::isEmpty() const
{
// Don't use QPainterPath::isEmpty(), as that also returns true if there's only
// one initial MoveTo element in the path.
- return !m_path->elementCount();
+ return !m_path.elementCount();
}
bool Path::hasCurrentPoint() const
@@ -311,8 +305,8 @@ bool Path::hasCurrentPoint() const
String Path::debugString() const
{
QString ret;
- for (int i = 0; i < m_path->elementCount(); ++i) {
- const QPainterPath::Element &cur = m_path->elementAt(i);
+ for (int i = 0; i < m_path.elementCount(); ++i) {
+ const QPainterPath::Element &cur = m_path.elementAt(i);
switch (cur.type) {
case QPainterPath::MoveToElement:
@@ -323,8 +317,8 @@ String Path::debugString() const
break;
case QPainterPath::CurveToElement:
{
- const QPainterPath::Element &c1 = m_path->elementAt(i + 1);
- const QPainterPath::Element &c2 = m_path->elementAt(i + 2);
+ const QPainterPath::Element &c1 = m_path.elementAt(i + 1);
+ const QPainterPath::Element &c2 = m_path.elementAt(i + 2);
Q_ASSERT(c1.type == QPainterPath::CurveToDataElement);
Q_ASSERT(c2.type == QPainterPath::CurveToDataElement);
@@ -348,8 +342,8 @@ void Path::apply(void* info, PathApplierFunction function) const
PathElement pelement;
FloatPoint points[3];
pelement.points = points;
- for (int i = 0; i < m_path->elementCount(); ++i) {
- const QPainterPath::Element& cur = m_path->elementAt(i);
+ for (int i = 0; i < m_path.elementCount(); ++i) {
+ const QPainterPath::Element& cur = m_path.elementAt(i);
switch (cur.type) {
case QPainterPath::MoveToElement:
@@ -364,8 +358,8 @@ void Path::apply(void* info, PathApplierFunction function) const
break;
case QPainterPath::CurveToElement:
{
- const QPainterPath::Element& c1 = m_path->elementAt(i + 1);
- const QPainterPath::Element& c2 = m_path->elementAt(i + 2);
+ const QPainterPath::Element& c1 = m_path.elementAt(i + 1);
+ const QPainterPath::Element& c2 = m_path.elementAt(i + 2);
Q_ASSERT(c1.type == QPainterPath::CurveToDataElement);
Q_ASSERT(c2.type == QPainterPath::CurveToDataElement);
@@ -387,12 +381,7 @@ void Path::apply(void* info, PathApplierFunction function) const
void Path::transform(const TransformationMatrix& transform)
{
- if (m_path) {
- QTransform mat = transform;
- QPainterPath temp = mat.map(*m_path);
- delete m_path;
- m_path = new QPainterPath(temp);
- }
+ m_path = QTransform(transform).map(m_path);
}
}
diff --git a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
index f1536a6..985442c 100644
--- a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
+++ b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
@@ -86,7 +86,10 @@ inline float square(float n)
// Ideally, all of these would be fixed in the graphics layer and we would not
// have to do any checking. You can uncomment the ENSURE_VALUE_SAFETY_FOR_SKIA
// flag to check the graphics layer.
-#define ENSURE_VALUE_SAFETY_FOR_SKIA
+
+// Disabling these checks (20/01/2010), since we think we've fixed all the Skia
+// bugs. Leaving the code in for now, so we can revert easily if necessary.
+// #define ENSURE_VALUE_SAFETY_FOR_SKIA
static bool isCoordinateSkiaSafe(float coord)
{
@@ -431,7 +434,7 @@ void GraphicsContext::clipToImageBuffer(const FloatRect& rect,
if (paintingDisabled())
return;
-#if defined(__linux__) || PLATFORM(WIN_OS)
+#if OS(LINUX) || OS(WINDOWS)
platformContext()->beginLayerClippedToImage(rect, imageBuffer);
#endif
}
@@ -498,12 +501,16 @@ void GraphicsContext::drawEllipse(const IntRect& elipseRect)
}
}
-void GraphicsContext::drawFocusRing(const Color& color)
+void GraphicsContext::drawFocusRing(const Vector<Path>& paths, int width, int offset, const Color& color)
+{
+ // FIXME: implement
+}
+
+void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int /* width */, int /* offset */, const Color& color)
{
if (paintingDisabled())
return;
- const Vector<IntRect>& rects = focusRingRects();
unsigned rectCount = rects.size();
if (!rectCount)
return;
diff --git a/WebCore/platform/graphics/skia/ImageBufferSkia.cpp b/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
index c36f1ce..4ea3d7a 100644
--- a/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
+++ b/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
@@ -66,7 +66,7 @@ ImageBuffer::ImageBuffer(const IntSize& size, ImageColorSpace imageColorSpace, b
m_data.m_platformContext.setCanvas(&m_data.m_canvas);
m_context.set(new GraphicsContext(&m_data.m_platformContext));
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
m_context->platformContext()->setDrawingToImageBuffer(true);
#endif
diff --git a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
index dfffa0d..92a1870 100644
--- a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
+++ b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
@@ -89,7 +89,7 @@ struct PlatformContextSkia::State {
// color to produce a new output color.
SkColor applyAlpha(SkColor) const;
-#if defined(__linux__) || PLATFORM(WIN_OS)
+#if OS(LINUX) || OS(WINDOWS)
// If non-empty, the current State is clipped to this image.
SkBitmap m_imageBufferClip;
// If m_imageBufferClip is non-empty, this is the region the image is clipped to.
@@ -143,7 +143,7 @@ PlatformContextSkia::State::State(const State& other)
, m_lineJoin(other.m_lineJoin)
, m_dash(other.m_dash)
, m_textDrawingMode(other.m_textDrawingMode)
-#if defined(__linux__) || PLATFORM(WIN_OS)
+#if OS(LINUX) || OS(WINDOWS)
, m_imageBufferClip(other.m_imageBufferClip)
, m_clip(other.m_clip)
#endif
@@ -180,7 +180,7 @@ SkColor PlatformContextSkia::State::applyAlpha(SkColor c) const
// Danger: canvas can be NULL.
PlatformContextSkia::PlatformContextSkia(skia::PlatformCanvas* canvas)
: m_canvas(canvas)
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
, m_drawingToImageBuffer(false)
#endif
{
@@ -197,7 +197,7 @@ void PlatformContextSkia::setCanvas(skia::PlatformCanvas* canvas)
m_canvas = canvas;
}
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
void PlatformContextSkia::setDrawingToImageBuffer(bool value)
{
m_drawingToImageBuffer = value;
@@ -214,7 +214,7 @@ void PlatformContextSkia::save()
m_stateStack.append(*m_state);
m_state = &m_stateStack.last();
-#if defined(__linux__) || PLATFORM(WIN_OS)
+#if OS(LINUX) || OS(WINDOWS)
// The clip image only needs to be applied once. Reset the image so that we
// don't attempt to clip multiple times.
m_state->m_imageBufferClip.reset();
@@ -224,7 +224,7 @@ void PlatformContextSkia::save()
canvas()->save();
}
-#if defined(__linux__) || PLATFORM(WIN_OS)
+#if OS(LINUX) || OS(WINDOWS)
void PlatformContextSkia::beginLayerClippedToImage(const WebCore::FloatRect& rect,
const WebCore::ImageBuffer* imageBuffer)
{
@@ -234,7 +234,8 @@ void PlatformContextSkia::beginLayerClippedToImage(const WebCore::FloatRect& rec
m_state->m_clip = rect;
SkRect bounds = { SkFloatToScalar(rect.x()), SkFloatToScalar(rect.y()),
SkFloatToScalar(rect.right()), SkFloatToScalar(rect.bottom()) };
-
+
+ canvas()->clipRect(bounds);
canvas()->saveLayerAlpha(&bounds, 255,
static_cast<SkCanvas::SaveFlags>(SkCanvas::kHasAlphaLayer_SaveFlag | SkCanvas::kFullColorLayer_SaveFlag));
// Copy off the image as |imageBuffer| may be deleted before restore is invoked.
@@ -271,7 +272,7 @@ void PlatformContextSkia::clipPathAntiAliased(const SkPath& clipPath)
void PlatformContextSkia::restore()
{
-#if defined(__linux__) || PLATFORM(WIN_OS)
+#if OS(LINUX) || OS(WINDOWS)
if (!m_state->m_imageBufferClip.empty()) {
applyClipFromImage(m_state->m_clip, m_state->m_imageBufferClip);
canvas()->restore();
@@ -574,7 +575,7 @@ bool PlatformContextSkia::isPrinting()
return m_canvas->getTopPlatformDevice().IsVectorial();
}
-#if defined(__linux__) || PLATFORM(WIN_OS)
+#if OS(LINUX) || OS(WINDOWS)
void PlatformContextSkia::applyClipFromImage(const WebCore::FloatRect& rect, const SkBitmap& imageBuffer)
{
// NOTE: this assumes the image mask contains opaque black for the portions that are to be shown, as such we
diff --git a/WebCore/platform/graphics/skia/PlatformContextSkia.h b/WebCore/platform/graphics/skia/PlatformContextSkia.h
index 53590bf..e445262 100644
--- a/WebCore/platform/graphics/skia/PlatformContextSkia.h
+++ b/WebCore/platform/graphics/skia/PlatformContextSkia.h
@@ -71,7 +71,7 @@ public:
// to the constructor.
void setCanvas(skia::PlatformCanvas*);
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
// If false we're rendering to a GraphicsContext for a web page, if false
// we're not (as is the case when rendering to a canvas object).
// If this is true the contents have not been marked up with the magic
@@ -88,7 +88,7 @@ public:
// |rect|. This layer is implicitly restored when the next restore is
// invoked.
// NOTE: |imageBuffer| may be deleted before the |restore| is invoked.
-#if defined(__linux__) || PLATFORM(WIN_OS)
+#if OS(LINUX) || OS(WINDOWS)
void beginLayerClippedToImage(const WebCore::FloatRect&,
const WebCore::ImageBuffer*);
#endif
@@ -168,7 +168,7 @@ public:
bool isPrinting();
private:
-#if defined(__linux__) || PLATFORM(WIN_OS)
+#if OS(LINUX) || OS(WINDOWS)
// Used when restoring and the state has an image clip. Only shows the pixels in
// m_canvas that are also in imageBuffer.
void applyClipFromImage(const WebCore::FloatRect&, const SkBitmap&);
@@ -191,7 +191,7 @@ private:
// Current path in global coordinates.
SkPath m_path;
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
bool m_drawingToImageBuffer;
#endif
};
diff --git a/WebCore/platform/graphics/transforms/TransformationMatrix.h b/WebCore/platform/graphics/transforms/TransformationMatrix.h
index 802ad3c..9e724d5 100644
--- a/WebCore/platform/graphics/transforms/TransformationMatrix.h
+++ b/WebCore/platform/graphics/transforms/TransformationMatrix.h
@@ -35,6 +35,8 @@
#include <CoreGraphics/CGAffineTransform.h>
#elif PLATFORM(CAIRO)
#include <cairo.h>
+#elif PLATFORM(OPENVG)
+#include "VGUtils.h"
#elif PLATFORM(QT)
#include <QTransform>
#elif PLATFORM(SKIA)
@@ -43,6 +45,14 @@
#include <wx/graphics.h>
#endif
+#if PLATFORM(WIN) || (PLATFORM(QT) && OS(WINDOWS)) || (PLATFORM(WX) && OS(WINDOWS))
+#if COMPILER(MINGW)
+typedef struct _XFORM XFORM;
+#else
+typedef struct tagXFORM XFORM;
+#endif
+#endif
+
namespace WebCore {
class IntRect;
@@ -299,6 +309,8 @@ public:
operator CGAffineTransform() const;
#elif PLATFORM(CAIRO)
operator cairo_matrix_t() const;
+#elif PLATFORM(OPENVG)
+ operator VGMatrix() const;
#elif PLATFORM(QT)
operator QTransform() const;
#elif PLATFORM(SKIA)
@@ -307,31 +319,31 @@ public:
operator wxGraphicsMatrix() const;
#endif
-#if PLATFORM(WIN)
+#if PLATFORM(WIN) || (PLATFORM(QT) && OS(WINDOWS)) || (PLATFORM(WX) && OS(WINDOWS))
operator XFORM() const;
#endif
+ bool isIdentityOrTranslation() const
+ {
+ return m_matrix[0][0] == 1 && m_matrix[0][1] == 0 && m_matrix[0][2] == 0 && m_matrix[0][3] == 0
+ && m_matrix[1][0] == 0 && m_matrix[1][1] == 1 && m_matrix[1][2] == 0 && m_matrix[1][3] == 0
+ && m_matrix[2][0] == 0 && m_matrix[2][1] == 0 && m_matrix[2][2] == 1 && m_matrix[2][3] == 0
+ && m_matrix[3][3] == 1;
+ }
+
private:
// multiply passed 2D point by matrix (assume z=0)
void multVecMatrix(double x, double y, double& dstX, double& dstY) const;
-
+
// multiply passed 3D point by matrix
void multVecMatrix(double x, double y, double z, double& dstX, double& dstY, double& dstZ) const;
-
+
void setMatrix(const Matrix4 m)
{
if (m && m != m_matrix)
memcpy(m_matrix, m, sizeof(Matrix4));
}
-
- bool isIdentityOrTranslation() const
- {
- return m_matrix[0][0] == 1 && m_matrix[0][1] == 0 && m_matrix[0][2] == 0 && m_matrix[0][3] == 0 &&
- m_matrix[1][0] == 0 && m_matrix[1][1] == 1 && m_matrix[1][2] == 0 && m_matrix[1][3] == 0 &&
- m_matrix[2][0] == 0 && m_matrix[2][1] == 0 && m_matrix[2][2] == 1 && m_matrix[2][3] == 0 &&
- m_matrix[3][3] == 1;
- }
-
+
Matrix4 m_matrix;
};
diff --git a/WebCore/platform/graphics/win/FontCGWin.cpp b/WebCore/platform/graphics/win/FontCGWin.cpp
index e901669..653b573 100644
--- a/WebCore/platform/graphics/win/FontCGWin.cpp
+++ b/WebCore/platform/graphics/win/FontCGWin.cpp
@@ -322,7 +322,8 @@ void Font::drawGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* fo
}
if (font->platformData().useGDI()) {
- if (!shouldUseFontSmoothing || (graphicsContext->textDrawingMode() & cTextStroke)) {
+ static bool canCreateCGFontWithLOGFONT = wkCanCreateCGFontWithLOGFONT();
+ if (!shouldUseFontSmoothing || !canCreateCGFontWithLOGFONT && (graphicsContext->textDrawingMode() & cTextStroke)) {
drawGDIGlyphs(graphicsContext, font, glyphBuffer, from, numGlyphs, point);
return;
}
diff --git a/WebCore/platform/graphics/win/FontCacheWin.cpp b/WebCore/platform/graphics/win/FontCacheWin.cpp
index 8663623..5e61ef3 100644
--- a/WebCore/platform/graphics/win/FontCacheWin.cpp
+++ b/WebCore/platform/graphics/win/FontCacheWin.cpp
@@ -399,7 +399,7 @@ static int CALLBACK matchImprovingEnumProc(CONST LOGFONT* candidate, CONST TEXTM
return 1;
}
-static HFONT createGDIFont(const AtomicString& family, LONG desiredWeight, bool desiredItalic, int size)
+static HFONT createGDIFont(const AtomicString& family, LONG desiredWeight, bool desiredItalic, int size, bool synthesizeItalic)
{
HDC hdc = GetDC(0);
@@ -433,6 +433,9 @@ static HFONT createGDIFont(const AtomicString& family, LONG desiredWeight, bool
matchData.m_chosen.lfQuality = DEFAULT_QUALITY;
matchData.m_chosen.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
+ if (desiredItalic && !matchData.m_chosen.lfItalic && synthesizeItalic)
+ matchData.m_chosen.lfItalic = 1;
+
HFONT result = CreateFontIndirect(&matchData.m_chosen);
if (!result)
return 0;
@@ -514,8 +517,14 @@ FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontD
// This masks rounding errors related to the HFONT metrics being different from the CGFont metrics.
// FIXME: We will eventually want subpixel precision for GDI mode, but the scaled rendering doesn't
// look as nice. That may be solvable though.
+#if PLATFORM(CG)
+ bool canCreateCGFontWithLOGFONT = wkCanCreateCGFontWithLOGFONT();
+#else
+ bool canCreateCGFontWithLOGFONT = true;
+#endif
LONG weight = adjustedGDIFontWeight(toGDIFontWeight(fontDescription.weight()), family);
- HFONT hfont = createGDIFont(family, weight, fontDescription.italic(), fontDescription.computedPixelSize() * (useGDI ? 1 : 32));
+ HFONT hfont = createGDIFont(family, weight, fontDescription.italic(),
+ fontDescription.computedPixelSize() * (useGDI ? 1 : 32), useGDI && canCreateCGFontWithLOGFONT);
if (!hfont)
return 0;
diff --git a/WebCore/platform/graphics/win/FontCustomPlatformData.cpp b/WebCore/platform/graphics/win/FontCustomPlatformData.cpp
index 24db173..b2d1b32 100644
--- a/WebCore/platform/graphics/win/FontCustomPlatformData.cpp
+++ b/WebCore/platform/graphics/win/FontCustomPlatformData.cpp
@@ -61,7 +61,7 @@ FontCustomPlatformData::~FontCustomPlatformData()
FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontRenderingMode renderingMode)
{
- ASSERT(m_cgFont);
+ ASSERT(wkCanCreateCGFontWithLOGFONT() || m_cgFont);
ASSERT(m_fontReference);
ASSERT(T2embedLibrary());
@@ -87,6 +87,12 @@ FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, b
logFont.lfWeight = bold ? 700 : 400;
HFONT hfont = CreateFontIndirect(&logFont);
+
+ if (wkCanCreateCGFontWithLOGFONT()) {
+ RetainPtr<CGFontRef> cgFont(AdoptCF, CGFontCreateWithPlatformFont(&logFont));
+ return FontPlatformData(hfont, cgFont.get(), size, bold, italic, renderingMode == AlternateRenderingMode);
+ }
+
wkSetFontPlatformInfo(m_cgFont, &logFont, free);
return FontPlatformData(hfont, m_cgFont, size, bold, italic, renderingMode == AlternateRenderingMode);
}
@@ -190,12 +196,15 @@ FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
ASSERT_ARG(buffer, buffer);
ASSERT(T2embedLibrary());
- // Get CG to create the font.
- CGDataProviderDirectAccessCallbacks callbacks = { &getData, &releaseData, &getBytesWithOffset, NULL };
- RetainPtr<CGDataProviderRef> dataProvider(AdoptCF, CGDataProviderCreateDirectAccess(buffer, buffer->size(), &callbacks));
- CGFontRef cgFont = CGFontCreateWithDataProvider(dataProvider.get());
- if (!cgFont)
- return 0;
+ RetainPtr<CGFontRef> cgFont;
+ if (!wkCanCreateCGFontWithLOGFONT()) {
+ // Get CG to create the font.
+ CGDataProviderDirectAccessCallbacks callbacks = { &getData, &releaseData, &getBytesWithOffset, NULL };
+ RetainPtr<CGDataProviderRef> dataProvider(AdoptCF, CGDataProviderCreateDirectAccess(buffer, buffer->size(), &callbacks));
+ cgFont.adoptCF(CGFontCreateWithDataProvider(dataProvider.get()));
+ if (!cgFont)
+ return 0;
+ }
// Introduce the font to GDI. AddFontMemResourceEx cannot be used, because it will pollute the process's
// font namespace (Windows has no API for creating an HFONT from data without exposing the font to the
@@ -210,10 +219,8 @@ FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
size_t overlayDst;
size_t overlaySrc;
size_t overlayLength;
- if (!getEOTHeader(buffer, eotHeader, overlayDst, overlaySrc, overlayLength)) {
- CGFontRelease(cgFont);
+ if (!getEOTHeader(buffer, eotHeader, overlayDst, overlaySrc, overlayLength))
return 0;
- }
HANDLE fontReference;
ULONG privStatus;
@@ -225,13 +232,11 @@ FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
fontName = String();
else {
fontReference = renameAndActivateFont(buffer, fontName);
- if (!fontReference) {
- CGFontRelease(cgFont);
+ if (!fontReference)
return 0;
- }
}
- return new FontCustomPlatformData(cgFont, fontReference, fontName);
+ return new FontCustomPlatformData(cgFont.releaseRef(), fontReference, fontName);
}
}
diff --git a/WebCore/platform/graphics/win/FontDatabase.cpp b/WebCore/platform/graphics/win/FontDatabase.cpp
index d0773ea..22ad4a6 100644
--- a/WebCore/platform/graphics/win/FontDatabase.cpp
+++ b/WebCore/platform/graphics/win/FontDatabase.cpp
@@ -188,6 +188,9 @@ void populateFontDatabase()
return;
initialized = true;
+ if (wkCanCreateCGFontWithLOGFONT())
+ return;
+
RetainPtr<CFPropertyListRef> propertyList = readFontPlist();
RetainPtr<CFArrayRef> lastFilenamesFromRegistry;
if (propertyList && CFGetTypeID(propertyList.get()) == CFDictionaryGetTypeID()) {
diff --git a/WebCore/platform/graphics/win/FontPlatformDataCGWin.cpp b/WebCore/platform/graphics/win/FontPlatformDataCGWin.cpp
index a92e367..d605cf9 100644
--- a/WebCore/platform/graphics/win/FontPlatformDataCGWin.cpp
+++ b/WebCore/platform/graphics/win/FontPlatformDataCGWin.cpp
@@ -109,6 +109,13 @@ static CFStringRef getPostScriptName(CFStringRef faceName, HDC dc)
void FontPlatformData::platformDataInit(HFONT font, float size, HDC hdc, WCHAR* faceName)
{
+ if (wkCanCreateCGFontWithLOGFONT()) {
+ LOGFONT logfont;
+ GetObject(font, sizeof(logfont), &logfont);
+ m_cgFont.adoptCF(CGFontCreateWithPlatformFont(&logfont));
+ return;
+ }
+
// Try the face name first. Windows may end up localizing this name, and CG doesn't know about
// the localization. If the create fails, we'll try the PostScript name.
RetainPtr<CFStringRef> fullName(AdoptCF, CFStringCreateWithCharacters(NULL, (const UniChar*)faceName, wcslen(faceName)));
diff --git a/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp b/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp
index 137b914..47a51de 100644
--- a/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp
+++ b/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp
@@ -124,17 +124,21 @@ void GraphicsContext::drawWindowsBitmap(WindowsBitmap* image, const IntPoint& po
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)
+void GraphicsContext::drawFocusRing(const Vector<Path>& paths, int width, int offset, const Color& color)
+{
+ // FIXME: implement
+}
+
+void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int offset, const Color& color)
{
if (paintingDisabled())
return;
- float radius = (focusRingWidth() - 1) / 2.0f;
- int offset = radius + focusRingOffset();
+ float radius = (width - 1) / 2.0f;
+ offset += radius;
CGColorRef colorRef = color.isValid() ? createCGColor(color) : 0;
CGMutablePathRef focusRingPath = 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));
diff --git a/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp b/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp
index 61ae76c..43d92fb 100644
--- a/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp
+++ b/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp
@@ -40,21 +40,26 @@ static cairo_t* createCairoContextWithHDC(HDC hdc, bool hasAlpha)
{
// Put the HDC In advanced mode so it will honor affine transforms.
SetGraphicsMode(hdc, GM_ADVANCED);
-
+
+ cairo_surface_t* surface = 0;
+
HBITMAP bitmap = static_cast<HBITMAP>(GetCurrentObject(hdc, OBJ_BITMAP));
BITMAP info;
- GetObject(bitmap, sizeof(info), &info);
- ASSERT(info.bmBitsPixel == 32);
+ if (!GetObject(bitmap, sizeof(info), &info))
+ surface = cairo_win32_surface_create(hdc);
+ else {
+ ASSERT(info.bmBitsPixel == 32);
- cairo_surface_t* image = cairo_image_surface_create_for_data((unsigned char*)info.bmBits,
+ surface = cairo_image_surface_create_for_data((unsigned char*)info.bmBits,
CAIRO_FORMAT_ARGB32,
info.bmWidth,
info.bmHeight,
info.bmWidthBytes);
+ }
- cairo_t* context = cairo_create(image);
- cairo_surface_destroy(image);
+ cairo_t* context = cairo_create(surface);
+ cairo_surface_destroy(surface);
return context;
}
diff --git a/WebCore/platform/graphics/win/GraphicsLayerCACF.cpp b/WebCore/platform/graphics/win/GraphicsLayerCACF.cpp
index 22faeb8..5ec90b8 100644
--- a/WebCore/platform/graphics/win/GraphicsLayerCACF.cpp
+++ b/WebCore/platform/graphics/win/GraphicsLayerCACF.cpp
@@ -36,6 +36,7 @@
#include "PlatformString.h"
#include "SystemTime.h"
#include "WKCACFLayer.h"
+#include <QuartzCoreInterface/QuartzCoreInterface.h>
#include <wtf/CurrentTime.h>
#include <wtf/StringExtras.h>
@@ -123,7 +124,7 @@ GraphicsLayerCACF::GraphicsLayerCACF(GraphicsLayerClient* client)
, m_contentsLayerPurpose(NoContentsLayer)
, m_contentsLayerHasBackgroundColor(false)
{
- m_layer = WKCACFLayer::create(kCACFLayer, this);
+ m_layer = WKCACFLayer::create(WKCACFLayer::Layer, this);
updateDebugIndicators();
}
@@ -536,7 +537,7 @@ void GraphicsLayerCACF::updateLayerPreserves3D()
{
if (m_preserves3D && !m_transformLayer) {
// Create the transform layer.
- m_transformLayer = WKCACFLayer::create(kCACFTransformLayer, this);
+ m_transformLayer = WKCACFLayer::create(WKCACFLayer::TransformLayer, this);
#ifndef NDEBUG
m_transformLayer->setName(String().format("Transform Layer CATransformLayer(%p) GraphicsLayer(%p)", m_transformLayer.get(), this));
@@ -552,7 +553,7 @@ void GraphicsLayerCACF::updateLayerPreserves3D()
m_layer->setPosition(point);
m_layer->setAnchorPoint(CGPointMake(0.5f, 0.5f));
- m_layer->setTransform(CATransform3DIdentity);
+ m_layer->setTransform(wkqcCATransform3DIdentity());
// Set the old layer to opacity of 1. Further down we will set the opacity on the transform layer.
m_layer->setOpacity(1);
@@ -609,7 +610,7 @@ void GraphicsLayerCACF::updateContentsImage()
{
if (m_pendingContentsImage) {
if (!m_contentsLayer.get()) {
- RefPtr<WKCACFLayer> imageLayer = WKCACFLayer::create(kCACFLayer, this);
+ RefPtr<WKCACFLayer> imageLayer = WKCACFLayer::create(WKCACFLayer::Layer, this);
#ifndef NDEBUG
imageLayer->setName("Image Layer");
#endif
@@ -620,7 +621,7 @@ void GraphicsLayerCACF::updateContentsImage()
// FIXME: maybe only do trilinear if the image is being scaled down,
// but then what if the layer size changes?
- m_contentsLayer->setMinificationFilter(kCACFFilterTrilinear);
+ m_contentsLayer->setMinificationFilter(WKCACFLayer::Trilinear);
m_contentsLayer->setContents(m_pendingContentsImage.get());
m_pendingContentsImage = 0;
diff --git a/WebCore/platform/graphics/win/IconWin.cpp b/WebCore/platform/graphics/win/IconWin.cpp
index d71ca00..56b46de 100644
--- a/WebCore/platform/graphics/win/IconWin.cpp
+++ b/WebCore/platform/graphics/win/IconWin.cpp
@@ -27,7 +27,7 @@
#include <tchar.h>
#include <windows.h>
-#if PLATFORM(WINCE)
+#if OS(WINCE)
// SHGFI_SHELLICONSIZE is not available on WINCE
#define SHGFI_SHELLICONSIZE 0
#endif
@@ -63,7 +63,7 @@ PassRefPtr<Icon> Icon::createIconForFiles(const Vector<String>& filenames)
return adoptRef(new Icon(sfi.hIcon));
}
-#if PLATFORM(WINCE)
+#if OS(WINCE)
return 0;
#else
TCHAR buffer[MAX_PATH];
@@ -86,7 +86,7 @@ void Icon::paint(GraphicsContext* context, const IntRect& r)
if (context->paintingDisabled())
return;
-#if PLATFORM(WINCE)
+#if OS(WINCE)
context->drawIcon(m_hIcon, r, DI_NORMAL);
#else
HDC hdc = context->getWindowsContext(r);
diff --git a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp
index a5beea1..b2fe069 100644
--- a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp
+++ b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2008, 2009 Apple, Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2009, 2010 Apple, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -35,10 +35,16 @@
#include "StringHash.h"
#include "TimeRanges.h"
#include "Timer.h"
+#include <wtf/CurrentTime.h>
#include <wtf/HashSet.h>
#include <wtf/MathExtras.h>
#include <wtf/StdLibExtras.h>
+#if USE(ACCELERATED_COMPOSITING)
+#include "GraphicsLayerCACF.h"
+#include "WKCACFLayer.h"
+#endif
+
#if DRAW_FRAME_RATE
#include "Font.h"
#include "FrameView.h"
@@ -67,7 +73,6 @@ void MediaPlayerPrivate::registerMediaEngine(MediaEngineRegistrar registrar)
MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
: m_player(player)
, m_seekTo(-1)
- , m_endTime(numeric_limits<float>::infinity())
, m_seekTimer(this, &MediaPlayerPrivate::seekTimerFired)
, m_networkState(MediaPlayer::Empty)
, m_readyState(MediaPlayer::HaveNothing)
@@ -76,6 +81,8 @@ MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
, m_hasUnsupportedTracks(false)
, m_startedPlaying(false)
, m_isStreaming(false)
+ , m_visible(false)
+ , m_newFrameAvailable(false)
#if DRAW_FRAME_RATE
, m_frameCountWhilePlaying(0)
, m_timeStartedPlaying(0)
@@ -86,6 +93,19 @@ MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
MediaPlayerPrivate::~MediaPlayerPrivate()
{
+ tearDownVideoRendering();
+}
+
+bool MediaPlayerPrivate::supportsFullscreen() const
+{
+ return true;
+}
+
+PlatformMedia MediaPlayerPrivate::platformMedia() const
+{
+ PlatformMedia p;
+ p.qtMovie = reinterpret_cast<QTMovie*>(m_qtMovie.get());
+ return p;
}
class TaskTimer : TimerBase {
@@ -178,7 +198,7 @@ void MediaPlayerPrivate::pause()
return;
m_startedPlaying = false;
#if DRAW_FRAME_RATE
- m_timeStoppedPlaying = GetTickCount();
+ m_timeStoppedPlaying = WTF::currentTime();
#endif
m_qtMovie->pause();
}
@@ -194,7 +214,7 @@ float MediaPlayerPrivate::currentTime() const
{
if (!m_qtMovie)
return 0;
- return min(m_qtMovie->currentTime(), m_endTime);
+ return m_qtMovie->currentTime();
}
void MediaPlayerPrivate::seek(float time)
@@ -222,7 +242,7 @@ void MediaPlayerPrivate::doSeek()
m_qtMovie->setCurrentTime(m_seekTo);
float timeAfterSeek = currentTime();
// restore playback only if not at end, othewise QTMovie will loop
- if (oldRate && timeAfterSeek < duration() && timeAfterSeek < m_endTime)
+ if (oldRate && timeAfterSeek < duration())
m_qtMovie->setRate(oldRate);
cancelSeek();
}
@@ -254,11 +274,6 @@ void MediaPlayerPrivate::seekTimerFired(Timer<MediaPlayerPrivate>*)
}
}
-void MediaPlayerPrivate::setEndTime(float time)
-{
- m_endTime = time;
-}
-
bool MediaPlayerPrivate::paused() const
{
if (!m_qtMovie)
@@ -332,12 +347,6 @@ void MediaPlayerPrivate::setClosedCaptionsVisible(bool visible)
m_qtMovie->setClosedCaptionsVisible(visible);
}
-int MediaPlayerPrivate::dataRate() const
-{
- // This is not used at the moment
- return 0;
-}
-
PassRefPtr<TimeRanges> MediaPlayerPrivate::buffered() const
{
RefPtr<TimeRanges> timeRanges = TimeRanges::create();
@@ -372,11 +381,6 @@ unsigned MediaPlayerPrivate::bytesLoaded() const
return totalBytes() * maxTime / dur;
}
-bool MediaPlayerPrivate::totalBytesKnown() const
-{
- return totalBytes() > 0;
-}
-
unsigned MediaPlayerPrivate::totalBytes() const
{
if (!m_qtMovie)
@@ -389,9 +393,11 @@ void MediaPlayerPrivate::cancelLoad()
if (m_networkState < MediaPlayer::Loading || m_networkState == MediaPlayer::Loaded)
return;
+ tearDownVideoRendering();
+
// Cancel the load by destroying the movie.
m_qtMovie.clear();
-
+
updateStates();
}
@@ -454,6 +460,9 @@ void MediaPlayerPrivate::updateStates()
}
}
+ if (isReadyForRendering() && !hasSetUpVideoRendering())
+ setUpVideoRendering();
+
if (seeking())
m_readyState = MediaPlayer::HaveNothing;
@@ -463,6 +472,11 @@ void MediaPlayerPrivate::updateStates()
m_player->readyStateChanged();
}
+bool MediaPlayerPrivate::isReadyForRendering() const
+{
+ return m_readyState >= MediaPlayer::HaveMetadata && m_player->visible();
+}
+
void MediaPlayerPrivate::sawUnsupportedTracks()
{
m_qtMovie->setDisabled(true);
@@ -477,7 +491,7 @@ void MediaPlayerPrivate::didEnd()
m_startedPlaying = false;
#if DRAW_FRAME_RATE
- m_timeStoppedPlaying = GetTickCount();
+ m_timeStoppedPlaying = WTF::currentTime();
#endif
updateStates();
m_player->timeChanged();
@@ -485,20 +499,32 @@ void MediaPlayerPrivate::didEnd()
void MediaPlayerPrivate::setSize(const IntSize& size)
{
- if (m_hasUnsupportedTracks || !m_qtMovie)
+ if (m_hasUnsupportedTracks || !m_qtMovie || m_size == size)
return;
+ m_size = size;
m_qtMovie->setSize(size.width(), size.height());
}
-void MediaPlayerPrivate::setVisible(bool b)
+void MediaPlayerPrivate::setVisible(bool visible)
{
- if (m_hasUnsupportedTracks || !m_qtMovie)
+ if (m_hasUnsupportedTracks || !m_qtMovie || m_visible == visible)
return;
- m_qtMovie->setVisible(b);
+
+ m_qtMovie->setVisible(visible);
+ m_visible = visible;
+ if (m_visible) {
+ if (isReadyForRendering())
+ setUpVideoRendering();
+ } else
+ tearDownVideoRendering();
}
void MediaPlayerPrivate::paint(GraphicsContext* p, const IntRect& r)
{
+#if USE(ACCELERATED_COMPOSITING)
+ if (m_qtVideoLayer)
+ return;
+#endif
if (p->paintingDisabled() || !m_qtMovie || m_hasUnsupportedTracks)
return;
@@ -529,28 +555,50 @@ void MediaPlayerPrivate::paint(GraphicsContext* p, const IntRect& r)
else
p->releaseWindowsContext(hdc, r);
+ paintCompleted(*p, r);
+}
+
+void MediaPlayerPrivate::paintCompleted(GraphicsContext& context, const IntRect& rect)
+{
+ m_newFrameAvailable = false;
+
#if DRAW_FRAME_RATE
if (m_frameCountWhilePlaying > 10) {
- Frame* frame = m_player->frameView() ? m_player->frameView()->frame() : NULL;
- Document* document = frame ? frame->document() : NULL;
- RenderObject* renderer = document ? document->renderer() : NULL;
- RenderStyle* styleToUse = renderer ? renderer->style() : NULL;
- if (styleToUse) {
- double frameRate = (m_frameCountWhilePlaying - 1) / (0.001 * ( m_startedPlaying ? (GetTickCount() - m_timeStartedPlaying) :
- (m_timeStoppedPlaying - m_timeStartedPlaying) ));
- String text = String::format("%1.2f", frameRate);
- TextRun textRun(text.characters(), text.length());
- const Color color(255, 0, 0);
- p->save();
- p->translate(r.x(), r.y() + r.height());
- p->setFont(styleToUse->font());
- p->setStrokeColor(color);
- p->setStrokeStyle(SolidStroke);
- p->setStrokeThickness(1.0f);
- p->setFillColor(color);
- p->drawText(textRun, IntPoint(2, -3));
- p->restore();
- }
+ double interval = m_startedPlaying ? WTF::currentTime() - m_timeStartedPlaying : m_timeStoppedPlaying - m_timeStartedPlaying;
+ double frameRate = (m_frameCountWhilePlaying - 1) / interval;
+ CGContextRef cgContext = context.platformContext();
+ CGRect drawRect = rect;
+
+ char text[8];
+ _snprintf(text, sizeof(text), "%1.2f", frameRate);
+
+ static const int fontSize = 25;
+ static const int fontCharWidth = 12;
+ static const int boxHeight = 25;
+ static const int boxBorderWidth = 4;
+ drawRect.size.width = boxBorderWidth * 2 + fontCharWidth * strlen(text);
+ drawRect.size.height = boxHeight;
+
+ CGContextSaveGState(cgContext);
+#if USE(ACCELERATED_COMPOSITING)
+ if (m_qtVideoLayer)
+ CGContextScaleCTM(cgContext, 1, -1);
+ CGContextTranslateCTM(cgContext, rect.width() - drawRect.size.width, m_qtVideoLayer ? -rect.height() : 0);
+#else
+ CGContextTranslateCTM(cgContext, rect.width() - drawRect.size.width, 0);
+#endif
+ static const CGFloat backgroundColor[4] = { 0.98, 0.98, 0.82, 0.8 };
+ CGContextSetFillColor(cgContext, backgroundColor);
+ CGContextFillRect(cgContext, drawRect);
+
+ static const CGFloat textColor[4] = { 0, 0, 0, 1 };
+ CGContextSetFillColor(cgContext, textColor);
+ CGContextSetTextMatrix(cgContext, CGAffineTransformMakeScale(1, -1));
+ CGContextSelectFont(cgContext, "Helvetica", fontSize, kCGEncodingMacRoman);
+
+ CGContextShowTextAtPoint(cgContext, drawRect.origin.x + boxBorderWidth, drawRect.origin.y + boxHeight - boxBorderWidth, text, strlen(text));
+
+ CGContextRestoreGState(cgContext);
}
#endif
}
@@ -630,13 +678,21 @@ void MediaPlayerPrivate::movieNewImageAvailable(QTMovieWin* movie)
#if DRAW_FRAME_RATE
if (m_startedPlaying) {
m_frameCountWhilePlaying++;
- // to eliminate preroll costs from our calculation,
- // our frame rate calculation excludes the first frame drawn after playback starts
- if (1==m_frameCountWhilePlaying)
- m_timeStartedPlaying = GetTickCount();
+ // To eliminate preroll costs from our calculation, our frame rate calculation excludes
+ // the first frame drawn after playback starts.
+ if (m_frameCountWhilePlaying == 1)
+ m_timeStartedPlaying = WTF::currentTime();
}
#endif
- m_player->repaint();
+
+ m_newFrameAvailable = true;
+
+#if USE(ACCELERATED_COMPOSITING)
+ if (m_qtVideoLayer)
+ m_qtVideoLayer->platformLayer()->setNeedsDisplay();
+ else
+#endif
+ m_player->repaint();
}
bool MediaPlayerPrivate::hasSingleSecurityOrigin() const
@@ -646,6 +702,171 @@ bool MediaPlayerPrivate::hasSingleSecurityOrigin() const
return true;
}
+MediaPlayerPrivate::MediaRenderingMode MediaPlayerPrivate::currentRenderingMode() const
+{
+ if (!m_qtMovie)
+ return MediaRenderingNone;
+
+#if USE(ACCELERATED_COMPOSITING)
+ if (m_qtVideoLayer)
+ return MediaRenderingMovieLayer;
+#endif
+
+ return MediaRenderingSoftwareRenderer;
+}
+
+MediaPlayerPrivate::MediaRenderingMode MediaPlayerPrivate::preferredRenderingMode() const
+{
+ if (!m_player->frameView() || !m_qtMovie)
+ return MediaRenderingNone;
+
+#if USE(ACCELERATED_COMPOSITING)
+ if (supportsAcceleratedRendering() && m_player->mediaPlayerClient()->mediaPlayerRenderingCanBeAccelerated(m_player))
+ return MediaRenderingMovieLayer;
+#endif
+
+ return MediaRenderingSoftwareRenderer;
+}
+
+void MediaPlayerPrivate::setUpVideoRendering()
+{
+ MediaRenderingMode currentMode = currentRenderingMode();
+ MediaRenderingMode preferredMode = preferredRenderingMode();
+
+#if !USE(ACCELERATED_COMPOSITING)
+ ASSERT(preferredMode != MediaRenderingMovieLayer);
+#endif
+
+ if (currentMode == preferredMode && currentMode != MediaRenderingNone)
+ return;
+
+ if (currentMode != MediaRenderingNone)
+ tearDownVideoRendering();
+
+ if (preferredMode == MediaRenderingMovieLayer)
+ createLayerForMovie();
+}
+
+void MediaPlayerPrivate::tearDownVideoRendering()
+{
+#if USE(ACCELERATED_COMPOSITING)
+ if (m_qtVideoLayer)
+ destroyLayerForMovie();
+#endif
+}
+
+bool MediaPlayerPrivate::hasSetUpVideoRendering() const
+{
+#if USE(ACCELERATED_COMPOSITING)
+ return m_qtVideoLayer || currentRenderingMode() != MediaRenderingMovieLayer;
+#else
+ return true;
+#endif
+}
+
+#if USE(ACCELERATED_COMPOSITING)
+
+// Up-call from compositing layer drawing callback.
+void MediaPlayerPrivate::paintContents(const GraphicsLayer*, GraphicsContext& context, GraphicsLayerPaintingPhase, const IntRect&)
+{
+ if (m_hasUnsupportedTracks)
+ return;
+
+ ASSERT(supportsAcceleratedRendering());
+
+ // No reason to replace the current layer image unless we have something new to show.
+ if (!m_newFrameAvailable)
+ return;
+
+ static CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+ void* buffer;
+ unsigned bitsPerPixel;
+ unsigned rowBytes;
+ unsigned width;
+ unsigned height;
+
+ m_qtMovie->getCurrentFrameInfo(buffer, bitsPerPixel, rowBytes, width, height);
+ if (!buffer)
+ return ;
+
+ RetainPtr<CFDataRef> data(AdoptCF, CFDataCreateWithBytesNoCopy(0, static_cast<UInt8*>(buffer), rowBytes * height, kCFAllocatorNull));
+ RetainPtr<CGDataProviderRef> provider(AdoptCF, CGDataProviderCreateWithCFData(data.get()));
+ RetainPtr<CGImageRef> frameImage(AdoptCF, CGImageCreate(width, height, 8, bitsPerPixel, rowBytes, colorSpace,
+ kCGBitmapByteOrder32Little | kCGImageAlphaFirst, provider.get(), 0, false, kCGRenderingIntentDefault));
+ if (!frameImage)
+ return;
+
+ IntRect rect(0, 0, m_size.width(), m_size.height());
+ CGContextDrawImage(context.platformContext(), rect, frameImage.get());
+ paintCompleted(context, rect);
+}
+#endif
+
+void MediaPlayerPrivate::createLayerForMovie()
+{
+#if USE(ACCELERATED_COMPOSITING)
+ ASSERT(supportsAcceleratedRendering());
+
+ if (!m_qtMovie || m_qtVideoLayer)
+ return;
+
+ // Do nothing if the parent layer hasn't been set up yet.
+ GraphicsLayer* videoGraphicsLayer = m_player->mediaPlayerClient()->mediaPlayerGraphicsLayer(m_player);
+ if (!videoGraphicsLayer)
+ return;
+
+ // Create a GraphicsLayer that won't be inserted directly into the render tree, but will used
+ // as a wrapper for a WKCACFLayer which gets inserted as the content layer of the video
+ // renderer's GraphicsLayer.
+ m_qtVideoLayer.set(new GraphicsLayerCACF(this));
+ if (!m_qtVideoLayer)
+ return;
+
+ // Mark the layer as drawing itself, anchored in the top left, and bottom-up.
+ m_qtVideoLayer->setDrawsContent(true);
+ m_qtVideoLayer->setAnchorPoint(FloatPoint3D());
+ m_qtVideoLayer->setContentsOrientation(GraphicsLayer::CompositingCoordinatesBottomUp);
+#ifndef NDEBUG
+ m_qtVideoLayer->setName("Video layer");
+#endif
+
+ // Hang the video layer from the render layer.
+ videoGraphicsLayer->setContentsToMedia(m_qtVideoLayer->platformLayer());
+#endif
+}
+
+void MediaPlayerPrivate::destroyLayerForMovie()
+{
+#if USE(ACCELERATED_COMPOSITING)
+ if (!m_qtVideoLayer)
+ return;
+ m_qtVideoLayer = 0;
+#endif
+}
+
+#if USE(ACCELERATED_COMPOSITING)
+bool MediaPlayerPrivate::supportsAcceleratedRendering() const
+{
+ return isReadyForRendering();
+}
+
+void MediaPlayerPrivate::acceleratedRenderingStateChanged()
+{
+ // Set up or change the rendering path if necessary.
+ setUpVideoRendering();
+}
+
+void MediaPlayerPrivate::notifySyncRequired(const GraphicsLayer*)
+{
+ GraphicsLayerCACF* videoGraphicsLayer = static_cast<GraphicsLayerCACF*>(m_player->mediaPlayerClient()->mediaPlayerGraphicsLayer(m_player));
+ if (videoGraphicsLayer)
+ videoGraphicsLayer->notifySyncRequired();
+ }
+
+
+#endif
+
+
}
#endif
diff --git a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h
index 2bccbbf..d58f44f 100644
--- a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h
+++ b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -32,11 +32,18 @@
#include "Timer.h"
#include <QTMovieWin.h>
#include <wtf/OwnPtr.h>
+#include <wtf/RetainPtr.h>
+
+#if USE(ACCELERATED_COMPOSITING)
+#include "GraphicsLayerClient.h"
+#endif
#ifndef DRAW_FRAME_RATE
#define DRAW_FRAME_RATE 0
#endif
+typedef struct CGImage *CGImageRef;
+
namespace WebCore {
class GraphicsContext;
@@ -44,15 +51,32 @@ class IntSize;
class IntRect;
class String;
-class MediaPlayerPrivate : public MediaPlayerPrivateInterface, public QTMovieWinClient {
+class MediaPlayerPrivate : public MediaPlayerPrivateInterface, public QTMovieWinClient
+#if USE(ACCELERATED_COMPOSITING)
+ , public GraphicsLayerClient
+#endif
+{
public:
static void registerMediaEngine(MediaEngineRegistrar);
~MediaPlayerPrivate();
private:
+
+#if USE(ACCELERATED_COMPOSITING)
+ // GraphicsLayerClient methods
+ virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect& inClip);
+ virtual void notifyAnimationStarted(const GraphicsLayer*, double time) { }
+ virtual void notifySyncRequired(const GraphicsLayer*);
+ virtual bool showDebugBorders() const { return false; }
+ virtual bool showRepaintCounter() const { return false; }
+#endif
+
MediaPlayerPrivate(MediaPlayer*);
+ virtual bool supportsFullscreen() const;
+ virtual PlatformMedia platformMedia() const;
+
IntSize naturalSize() const;
bool hasVideo() const;
bool hasAudio() const;
@@ -69,21 +93,17 @@ private:
float duration() const;
float currentTime() const;
void seek(float time);
- void setEndTime(float);
void setRate(float);
void setVolume(float);
void setPreservesPitch(bool);
- 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);
@@ -93,7 +113,8 @@ private:
void didEnd();
void paint(GraphicsContext*, const IntRect&);
-
+ void paintCompleted(GraphicsContext&, const IntRect&);
+
bool hasSingleSecurityOrigin() const;
bool hasClosedCaptions() const;
@@ -117,11 +138,31 @@ private:
static MediaPlayer::SupportsType supportsType(const String& type, const String& codecs);
static bool isAvailable();
+#if USE(ACCELERATED_COMPOSITING)
+ virtual bool supportsAcceleratedRendering() const;
+ virtual void acceleratedRenderingStateChanged();
+#endif
+
+ enum MediaRenderingMode { MediaRenderingNone, MediaRenderingSoftwareRenderer, MediaRenderingMovieLayer };
+ MediaRenderingMode currentRenderingMode() const;
+ MediaRenderingMode preferredRenderingMode() const;
+ bool isReadyForRendering() const;
+
+ void setUpVideoRendering();
+ void tearDownVideoRendering();
+ bool hasSetUpVideoRendering() const;
+
+ void createLayerForMovie();
+ void destroyLayerForMovie();
+
MediaPlayer* m_player;
OwnPtr<QTMovieWin> m_qtMovie;
+#if USE(ACCELERATED_COMPOSITING)
+ OwnPtr<GraphicsLayer> m_qtVideoLayer;
+#endif
float m_seekTo;
- float m_endTime;
Timer<MediaPlayerPrivate> m_seekTimer;
+ IntSize m_size;
MediaPlayer::NetworkState m_networkState;
MediaPlayer::ReadyState m_readyState;
unsigned m_enabledTrackCount;
@@ -129,10 +170,12 @@ private:
bool m_hasUnsupportedTracks;
bool m_startedPlaying;
bool m_isStreaming;
+ bool m_visible;
+ bool m_newFrameAvailable;
#if DRAW_FRAME_RATE
- int m_frameCountWhilePlaying;
- int m_timeStartedPlaying;
- int m_timeStoppedPlaying;
+ double m_frameCountWhilePlaying;
+ double m_timeStartedPlaying;
+ double m_timeStoppedPlaying;
#endif
};
diff --git a/WebCore/platform/graphics/win/QTMovieWin.cpp b/WebCore/platform/graphics/win/QTMovieWin.cpp
index 2d4c2ea..8fd6c71 100644
--- a/WebCore/platform/graphics/win/QTMovieWin.cpp
+++ b/WebCore/platform/graphics/win/QTMovieWin.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2008, 2009 Apple, Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2009, 2010 Apple, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -24,18 +24,15 @@
*/
#include "config.h"
-#include <windows.h>
-
#include "QTMovieWin.h"
// Put Movies.h first so build failures here point clearly to QuickTime
#include <Movies.h>
-#include <QuickTimeComponents.h>
-#include <GXMath.h>
-#include <QTML.h>
#include "QTMovieWinTimer.h"
-
+#include <GXMath.h>
+#include <QTML.h>
+#include <QuickTimeComponents.h>
#include <wtf/Assertions.h>
#include <wtf/HashSet.h>
#include <wtf/Noncopyable.h>
@@ -50,6 +47,7 @@ static const long subTitleTrackType = 'sbtl';
static const long mpeg4ObjectDescriptionTrackType = 'odsm';
static const long mpeg4SceneDescriptionTrackType = 'sdsm';
static const long closedCaptionDisplayPropertyID = 'disp';
+static LPCTSTR fullscreenQTMovieWinPointerProp = TEXT("fullscreenQTMovieWinPointer");
// Resizing GWorlds is slow, give them a minimum size so size of small
// videos can be animated smoothly
@@ -130,6 +128,11 @@ public:
#if !ASSERT_DISABLED
bool m_scaleCached;
#endif
+ WindowPtr m_fullscreenWindow;
+ GWorldPtr m_fullscreenOrigGWorld;
+ Rect m_fullscreenRect;
+ QTMovieWinFullscreenClient* m_fullscreenClient;
+ char* m_fullscreenRestoreState;
};
QTMovieWinPrivate::QTMovieWinPrivate()
@@ -159,11 +162,19 @@ QTMovieWinPrivate::QTMovieWinPrivate()
#if !ASSERT_DISABLED
, m_scaleCached(false)
#endif
+ , m_fullscreenWindow(0)
+ , m_fullscreenOrigGWorld(0)
+ , m_fullscreenClient(0)
+ , m_fullscreenRestoreState(0)
{
+ Rect rect = { 0, 0, 0, 0 };
+ m_fullscreenRect = rect;
}
QTMovieWinPrivate::~QTMovieWinPrivate()
{
+ ASSERT(!m_fullscreenWindow);
+
endTask();
if (m_gWorld)
deleteGWorld();
@@ -359,7 +370,7 @@ void QTMovieWinPrivate::createGWorld()
bounds.left = 0;
bounds.right = m_gWorldWidth;
bounds.bottom = m_gWorldHeight;
- OSErr err = QTNewGWorld(&m_gWorld, k32BGRAPixelFormat, &bounds, NULL, NULL, NULL);
+ OSErr err = QTNewGWorld(&m_gWorld, k32BGRAPixelFormat, &bounds, 0, 0, 0);
if (err)
return;
GetMovieGWorld(m_movie, &m_savedGWorld, 0);
@@ -597,6 +608,24 @@ void QTMovieWin::setVisible(bool b)
m_private->updateGWorld();
}
+void QTMovieWin::getCurrentFrameInfo(void*& buffer, unsigned& bitsPerPixel, unsigned& rowBytes, unsigned& width, unsigned& height)
+{
+ if (!m_private->m_gWorld) {
+ buffer = 0;
+ bitsPerPixel = 0;
+ rowBytes = 0;
+ width = 0;
+ height = 0;
+ return;
+ }
+ PixMapHandle offscreenPixMap = GetGWorldPixMap(m_private->m_gWorld);
+ buffer = (*offscreenPixMap)->baseAddr;
+ bitsPerPixel = (*offscreenPixMap)->pixelSize;
+ rowBytes = (*offscreenPixMap)->rowBytes & 0x3FFF;
+ width = m_private->m_width;
+ height = m_private->m_height;
+}
+
void QTMovieWin::paint(HDC hdc, int x, int y)
{
if (!m_private->m_gWorld)
@@ -729,7 +758,7 @@ void QTMovieWin::load(CFURLRef url, bool preservesPitch)
moviePropCount++;
ASSERT(moviePropCount <= sizeof(movieProps)/sizeof(movieProps[0]));
- m_private->m_loadError = NewMovieFromProperties(moviePropCount, movieProps, 0, NULL, &m_private->m_movie);
+ m_private->m_loadError = NewMovieFromProperties(moviePropCount, movieProps, 0, 0, &m_private->m_movie);
end:
m_private->startTask();
@@ -953,7 +982,7 @@ static void initializeSupportedTypes()
continue;
if (!(infoCD.componentFlags & hasMovieImportMIMEList))
continue;
- QTAtomContainer mimeList = NULL;
+ QTAtomContainer mimeList = 0;
err = MovieImportGetMIMETypeList((ComponentInstance)comp, &mimeList);
if (err || !mimeList)
continue;
@@ -962,7 +991,7 @@ static void initializeSupportedTypes()
QTLockContainer(mimeList);
int typeCount = QTCountChildrenOfType(mimeList, kParentAtomIsContainer, kMimeInfoMimeTypeTag);
for (int typeIndex = 1; typeIndex <= typeCount; typeIndex++) {
- QTAtom mimeTag = QTFindChildByIndex(mimeList, 0, kMimeInfoMimeTypeTag, typeIndex, NULL);
+ QTAtom mimeTag = QTFindChildByIndex(mimeList, 0, kMimeInfoMimeTypeTag, typeIndex, 0);
if (!mimeTag)
continue;
char* atomData;
@@ -980,7 +1009,7 @@ static void initializeSupportedTypes()
if (strncmp(typeBuffer, "audio/", 6) && strncmp(typeBuffer, "video/", 6))
continue;
- CFStringRef cfMimeType = CFStringCreateWithCString(NULL, typeBuffer, kCFStringEncodingUTF8);
+ CFStringRef cfMimeType = CFStringCreateWithCString(0, typeBuffer, kCFStringEncodingUTF8);
if (!cfMimeType)
continue;
@@ -1040,7 +1069,7 @@ bool QTMovieWin::initializeQuickTime()
if (!initialized) {
initialized = true;
// Initialize and check QuickTime version
- OSErr result = InitializeQTML(0);
+ OSErr result = InitializeQTML(kInitializeQTMLEnableDoubleBufferedSurface);
if (result == noErr)
result = Gestalt(gestaltQuickTime, &quickTimeVersion);
if (result != noErr) {
@@ -1058,15 +1087,80 @@ bool QTMovieWin::initializeQuickTime()
return initializationSucceeded;
}
+LRESULT QTMovieWin::fullscreenWndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ QTMovieWin* movie = static_cast<QTMovieWin*>(GetProp(wnd, fullscreenQTMovieWinPointerProp));
+
+ if (message == WM_DESTROY)
+ RemoveProp(wnd, fullscreenQTMovieWinPointerProp);
+
+ if (!movie)
+ return DefWindowProc(wnd, message, wParam, lParam);
+
+ return movie->m_private->m_fullscreenClient->fullscreenClientWndProc(wnd, message, wParam, lParam);
+}
+
+HWND QTMovieWin::enterFullscreen(QTMovieWinFullscreenClient* client)
+{
+ m_private->m_fullscreenClient = client;
+
+ BeginFullScreen(&m_private->m_fullscreenRestoreState, 0, 0, 0, &m_private->m_fullscreenWindow, 0, fullScreenAllowEvents);
+ QTMLSetWindowWndProc(m_private->m_fullscreenWindow, fullscreenWndProc);
+ CreatePortAssociation(GetPortNativeWindow(m_private->m_fullscreenWindow), 0, 0);
+
+ GetMovieBox(m_private->m_movie, &m_private->m_fullscreenRect);
+ GetMovieGWorld(m_private->m_movie, &m_private->m_fullscreenOrigGWorld, 0);
+ SetMovieGWorld(m_private->m_movie, reinterpret_cast<CGrafPtr>(m_private->m_fullscreenWindow), GetGWorldDevice(reinterpret_cast<CGrafPtr>(m_private->m_fullscreenWindow)));
+
+ // Set the size of the box to preserve aspect ratio
+ Rect rect = m_private->m_fullscreenWindow->portRect;
+
+ float movieRatio = static_cast<float>(m_private->m_width) / m_private->m_height;
+ int windowWidth = rect.right - rect.left;
+ int windowHeight = rect.bottom - rect.top;
+ float windowRatio = static_cast<float>(windowWidth) / windowHeight;
+ int actualWidth = (windowRatio > movieRatio) ? (windowHeight * movieRatio) : windowWidth;
+ int actualHeight = (windowRatio < movieRatio) ? (windowWidth / movieRatio) : windowHeight;
+ int offsetX = (windowWidth - actualWidth) / 2;
+ int offsetY = (windowHeight - actualHeight) / 2;
+
+ rect.left = offsetX;
+ rect.right = offsetX + actualWidth;
+ rect.top = offsetY;
+ rect.bottom = offsetY + actualHeight;
+
+ SetMovieBox(m_private->m_movie, &rect);
+ ShowHideTaskBar(true);
+
+ // Set the 'this' pointer on the HWND
+ HWND wnd = static_cast<HWND>(GetPortNativeWindow(m_private->m_fullscreenWindow));
+ SetProp(wnd, fullscreenQTMovieWinPointerProp, static_cast<HANDLE>(this));
+
+ return wnd;
+}
+
+void QTMovieWin::exitFullscreen()
+{
+ if (!m_private->m_fullscreenWindow)
+ return;
+
+ HWND wnd = static_cast<HWND>(GetPortNativeWindow(m_private->m_fullscreenWindow));
+ DestroyPortAssociation(reinterpret_cast<CGrafPtr>(m_private->m_fullscreenWindow));
+ SetMovieGWorld(m_private->m_movie, m_private->m_fullscreenOrigGWorld, 0);
+ EndFullScreen(m_private->m_fullscreenRestoreState, 0L);
+ SetMovieBox(m_private->m_movie, &m_private->m_fullscreenRect);
+ m_private->m_fullscreenWindow = 0;
+}
+
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason) {
- case DLL_PROCESS_ATTACH:
- return TRUE;
- case DLL_PROCESS_DETACH:
- case DLL_THREAD_ATTACH:
- case DLL_THREAD_DETACH:
- return FALSE;
+ case DLL_PROCESS_ATTACH:
+ return TRUE;
+ case DLL_PROCESS_DETACH:
+ case DLL_THREAD_ATTACH:
+ case DLL_THREAD_DETACH:
+ return FALSE;
}
ASSERT_NOT_REACHED();
return FALSE;
diff --git a/WebCore/platform/graphics/win/QTMovieWin.h b/WebCore/platform/graphics/win/QTMovieWin.h
index 778f9aa..d2a7ed0 100644
--- a/WebCore/platform/graphics/win/QTMovieWin.h
+++ b/WebCore/platform/graphics/win/QTMovieWin.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2008, 2009 Apple, Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2009, 2010 Apple, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,6 +27,7 @@
#define QTMovieWin_h
#include <Unicode.h>
+#include <windows.h>
#ifdef QTMOVIEWIN_EXPORTS
#define QTMOVIEWIN_API __declspec(dllexport)
@@ -45,6 +46,11 @@ public:
virtual void movieNewImageAvailable(QTMovieWin*) = 0;
};
+class QTMovieWinFullscreenClient {
+public:
+ virtual LRESULT fullscreenClientWndProc(HWND, UINT message, WPARAM, LPARAM) = 0;
+};
+
enum {
QTMovieLoadStateError = -1L,
QTMovieLoadStateLoaded = 2000L,
@@ -91,6 +97,7 @@ public:
void setVisible(bool);
void paint(HDC, int x, int y);
+ void getCurrentFrameInfo(void*& buffer, unsigned& bitsPerPixel, unsigned& rowBytes, unsigned& width, unsigned& height);
void disableUnsupportedTracks(unsigned& enabledTrackCount, unsigned& totalTrackCount);
void setDisabled(bool);
@@ -104,8 +111,13 @@ public:
static unsigned countSupportedTypes();
static void getSupportedType(unsigned index, const UChar*& str, unsigned& len);
+ // Returns the full-screen window created
+ HWND enterFullscreen(QTMovieWinFullscreenClient*);
+ void exitFullscreen();
+
private:
void load(CFURLRef, bool preservesPitch);
+ static LRESULT fullscreenWndProc(HWND, UINT message, WPARAM, LPARAM);
QTMovieWinPrivate* m_private;
bool m_disabled;
diff --git a/WebCore/platform/graphics/win/TransformationMatrixWin.cpp b/WebCore/platform/graphics/win/TransformationMatrixWin.cpp
index 38dbfbf..47806a2 100644
--- a/WebCore/platform/graphics/win/TransformationMatrixWin.cpp
+++ b/WebCore/platform/graphics/win/TransformationMatrixWin.cpp
@@ -26,6 +26,8 @@
#include "config.h"
#include "TransformationMatrix.h"
+#include <windows.h>
+
namespace WebCore {
TransformationMatrix::operator XFORM() const
diff --git a/WebCore/platform/graphics/win/WKCACFLayer.cpp b/WebCore/platform/graphics/win/WKCACFLayer.cpp
index 21e010d..ad1fc85 100644
--- a/WebCore/platform/graphics/win/WKCACFLayer.cpp
+++ b/WebCore/platform/graphics/win/WKCACFLayer.cpp
@@ -30,12 +30,19 @@
#include "WKCACFLayer.h"
#include "WKCACFContextFlusher.h"
+#include "WKCACFLayerRenderer.h"
#include <stdio.h>
#include <QuartzCore/CACFContext.h>
#include <QuartzCore/CARender.h>
+#include <QuartzCoreInterface/QuartzCoreInterface.h>
-#pragma comment(lib, "QuartzCore")
+#ifdef DEBUG_ALL
+#pragma comment(lib, "QuartzCore_debug")
+#else
+#pragma comment(lib, "QuartzCore")
+#endif
+#pragma comment(lib, "QuartzCoreInterface")
namespace WebCore {
@@ -47,11 +54,135 @@ static void displayInContext(CACFLayerRef layer, CGContextRef context)
WKCACFLayer::layer(layer)->display(context);
}
+#define STATIC_CACF_STRING(name) \
+ static CFStringRef name() \
+ { \
+ static CFStringRef name = wkqcCFStringRef(wkqc##name); \
+ return name; \
+ }
+
+STATIC_CACF_STRING(kCACFLayer)
+STATIC_CACF_STRING(kCACFTransformLayer)
+STATIC_CACF_STRING(kCACFGravityCenter)
+STATIC_CACF_STRING(kCACFGravityTop)
+STATIC_CACF_STRING(kCACFGravityBottom)
+STATIC_CACF_STRING(kCACFGravityLeft)
+STATIC_CACF_STRING(kCACFGravityRight)
+STATIC_CACF_STRING(kCACFGravityTopLeft)
+STATIC_CACF_STRING(kCACFGravityTopRight)
+STATIC_CACF_STRING(kCACFGravityBottomLeft)
+STATIC_CACF_STRING(kCACFGravityBottomRight)
+STATIC_CACF_STRING(kCACFGravityResize)
+STATIC_CACF_STRING(kCACFGravityResizeAspect)
+STATIC_CACF_STRING(kCACFGravityResizeAspectFill)
+STATIC_CACF_STRING(kCACFFilterLinear)
+STATIC_CACF_STRING(kCACFFilterNearest)
+STATIC_CACF_STRING(kCACFFilterTrilinear)
+STATIC_CACF_STRING(kCACFFilterLanczos)
+
+static CFStringRef toCACFLayerType(WKCACFLayer::LayerType type)
+{
+ switch (type) {
+ case WKCACFLayer::Layer: return kCACFLayer();
+ case WKCACFLayer::TransformLayer: return kCACFTransformLayer();
+ default: return 0;
+ }
+}
+
+static CFStringRef toCACFContentsGravityType(WKCACFLayer::ContentsGravityType type)
+{
+ switch (type) {
+ case WKCACFLayer::Center: return kCACFGravityCenter();
+ case WKCACFLayer::Top: return kCACFGravityTop();
+ case WKCACFLayer::Bottom: return kCACFGravityBottom();
+ case WKCACFLayer::Left: return kCACFGravityLeft();
+ case WKCACFLayer::Right: return kCACFGravityRight();
+ case WKCACFLayer::TopLeft: return kCACFGravityTopLeft();
+ case WKCACFLayer::TopRight: return kCACFGravityTopRight();
+ case WKCACFLayer::BottomLeft: return kCACFGravityBottomLeft();
+ case WKCACFLayer::BottomRight: return kCACFGravityBottomRight();
+ case WKCACFLayer::Resize: return kCACFGravityResize();
+ case WKCACFLayer::ResizeAspect: return kCACFGravityResizeAspect();
+ case WKCACFLayer::ResizeAspectFill: return kCACFGravityResizeAspectFill();
+ default: return 0;
+ }
+}
+
+static WKCACFLayer::ContentsGravityType fromCACFContentsGravityType(CFStringRef string)
+{
+ if (CFEqual(string, kCACFGravityTop()))
+ return WKCACFLayer::Top;
+
+ if (CFEqual(string, kCACFGravityBottom()))
+ return WKCACFLayer::Bottom;
+
+ if (CFEqual(string, kCACFGravityLeft()))
+ return WKCACFLayer::Left;
+
+ if (CFEqual(string, kCACFGravityRight()))
+ return WKCACFLayer::Right;
+
+ if (CFEqual(string, kCACFGravityTopLeft()))
+ return WKCACFLayer::TopLeft;
+
+ if (CFEqual(string, kCACFGravityTopRight()))
+ return WKCACFLayer::TopRight;
+
+ if (CFEqual(string, kCACFGravityBottomLeft()))
+ return WKCACFLayer::BottomLeft;
+
+ if (CFEqual(string, kCACFGravityBottomRight()))
+ return WKCACFLayer::BottomRight;
+
+ if (CFEqual(string, kCACFGravityResize()))
+ return WKCACFLayer::Resize;
+
+ if (CFEqual(string, kCACFGravityResizeAspect()))
+ return WKCACFLayer::ResizeAspect;
+
+ if (CFEqual(string, kCACFGravityResizeAspectFill()))
+ return WKCACFLayer::ResizeAspectFill;
+
+ return WKCACFLayer::Center;
+}
+
+static CFStringRef toCACFFilterType(WKCACFLayer::FilterType type)
+{
+ switch (type) {
+ case WKCACFLayer::Linear: return kCACFFilterLinear();
+ case WKCACFLayer::Nearest: return kCACFFilterNearest();
+ case WKCACFLayer::Trilinear: return kCACFFilterTrilinear();
+ case WKCACFLayer::Lanczos: return kCACFFilterLanczos();
+ default: return 0;
+ }
+}
+
+static WKCACFLayer::FilterType fromCACFFilterType(CFStringRef string)
+{
+ if (CFEqual(string, kCACFFilterNearest()))
+ return WKCACFLayer::Nearest;
+
+ if (CFEqual(string, kCACFFilterTrilinear()))
+ return WKCACFLayer::Trilinear;
+
+ if (CFEqual(string, kCACFFilterLanczos()))
+ return WKCACFLayer::Lanczos;
+
+ return WKCACFLayer::Linear;
+}
+
+PassRefPtr<WKCACFLayer> WKCACFLayer::create(LayerType type, GraphicsLayerCACF* owner)
+{
+ if (!WKCACFLayerRenderer::acceleratedCompositingAvailable())
+ return 0;
+ return adoptRef(new WKCACFLayer(type, owner));
+}
+
// FIXME: It might be good to have a way of ensuring that all WKCACFLayers eventually
// get destroyed in debug builds. A static counter could accomplish this pretty easily.
-WKCACFLayer::WKCACFLayer(CFStringRef className, GraphicsLayerCACF* owner)
- : m_layer(AdoptCF, CACFLayerCreate(className))
+WKCACFLayer::WKCACFLayer(LayerType type, GraphicsLayerCACF* owner)
+ : m_layer(AdoptCF, CACFLayerCreate(toCACFLayerType(type)))
, m_needsDisplayOnBoundsChange(false)
, m_owner(owner)
{
@@ -291,6 +422,39 @@ void WKCACFLayer::setFrame(const CGRect& rect)
setNeedsDisplay();
}
+void WKCACFLayer::setContentsGravity(ContentsGravityType type)
+{
+ CACFLayerSetContentsGravity(layer(), toCACFContentsGravityType(type));
+ setNeedsCommit();
+}
+
+WKCACFLayer::ContentsGravityType WKCACFLayer::contentsGravity() const
+{
+ return fromCACFContentsGravityType(CACFLayerGetContentsGravity(layer()));
+}
+
+void WKCACFLayer::setMagnificationFilter(FilterType type)
+{
+ CACFLayerSetMagnificationFilter(layer(), toCACFFilterType(type));
+ setNeedsCommit();
+}
+
+WKCACFLayer::FilterType WKCACFLayer::magnificationFilter() const
+{
+ return fromCACFFilterType(CACFLayerGetMagnificationFilter(layer()));
+}
+
+void WKCACFLayer::setMinificationFilter(FilterType type)
+{
+ CACFLayerSetMinificationFilter(layer(), toCACFFilterType(type));
+ setNeedsCommit();
+}
+
+WKCACFLayer::FilterType WKCACFLayer::minificationFilter() const
+{
+ return fromCACFFilterType(CACFLayerGetMinificationFilter(layer()));
+}
+
WKCACFLayer* WKCACFLayer::rootLayer() const
{
WKCACFLayer* layer = const_cast<WKCACFLayer*>(this);
diff --git a/WebCore/platform/graphics/win/WKCACFLayer.h b/WebCore/platform/graphics/win/WKCACFLayer.h
index 6655f7a..6892c6e 100644
--- a/WebCore/platform/graphics/win/WKCACFLayer.h
+++ b/WebCore/platform/graphics/win/WKCACFLayer.h
@@ -50,7 +50,12 @@ class WKCACFTimingFunction;
class WKCACFLayer : public RefCounted<WKCACFLayer> {
public:
- static PassRefPtr<WKCACFLayer> create(CFStringRef className, GraphicsLayerCACF* owner = 0) { return adoptRef(new WKCACFLayer(className, owner)); }
+ enum LayerType { Layer, TransformLayer };
+ enum FilterType { Linear, Nearest, Trilinear, Lanczos };
+ enum ContentsGravityType { Center, Top, Bottom, Left, Right, TopLeft, TopRight,
+ BottomLeft, BottomRight, Resize, ResizeAspect, ResizeAspectFill };
+
+ static PassRefPtr<WKCACFLayer> create(LayerType, GraphicsLayerCACF* owner = 0);
static WKCACFLayer* layer(CACFLayerRef layer) { return static_cast<WKCACFLayer*>(CACFLayerGetUserData(layer)); }
~WKCACFLayer();
@@ -142,8 +147,8 @@ public:
void setContentsRect(const CGRect& contentsRect) { CACFLayerSetContentsRect(layer(), contentsRect); setNeedsCommit(); }
CGRect contentsRect() const { return CACFLayerGetContentsRect(layer()); }
- void setContentsGravity(CFStringRef str) { CACFLayerSetContentsGravity(layer(), str); setNeedsCommit(); }
- CFStringRef contentsGravity() const { return CACFLayerGetContentsGravity(layer()); }
+ void setContentsGravity(ContentsGravityType);
+ ContentsGravityType contentsGravity() const;
void setDoubleSided(bool b) { CACFLayerSetDoubleSided(layer(), b); setNeedsCommit(); }
bool doubleSided() const { return CACFLayerIsDoubleSided(layer()); }
@@ -163,11 +168,11 @@ public:
void setMasksToBounds(bool b) { CACFLayerSetMasksToBounds(layer(), b); }
bool masksToBounds() const { return CACFLayerGetMasksToBounds(layer()); }
- void setMagnificationFilter(const String& string) { CACFLayerSetMagnificationFilter(layer(), RetainPtr<CFStringRef>(AdoptCF, string.createCFString()).get()); }
- String magnificationFilter() const { return CACFLayerGetMagnificationFilter(layer()); }
+ void setMagnificationFilter(FilterType);
+ FilterType magnificationFilter() const;
- void setMinificationFilter(const String& string) { CACFLayerSetMinificationFilter(layer(), RetainPtr<CFStringRef>(AdoptCF, string.createCFString()).get()); }
- String minificationFilter() const { return CACFLayerGetMinificationFilter(layer()); }
+ void setMinificationFilter(FilterType);
+ FilterType minificationFilter() const;
void setMinificationFilterBias(float bias) { CACFLayerSetMinificationFilterBias(layer(), bias); }
float minificationFilterBias() const { return CACFLayerGetMinificationFilterBias(layer()); }
@@ -218,9 +223,9 @@ public:
void setGeometryFlipped(bool flipped) { CACFLayerSetGeometryFlipped(layer(), flipped); setNeedsCommit(); }
bool geometryFlipped() const { return CACFLayerIsGeometryFlipped(layer()); }
- WKCACFLayer(CFStringRef className, GraphicsLayerCACF* owner);
-
private:
+ WKCACFLayer(LayerType, GraphicsLayerCACF* owner);
+
void setNeedsCommit();
CACFLayerRef layer() const { return m_layer.get(); }
size_t numSublayers() const
diff --git a/WebCore/platform/graphics/win/WKCACFLayerRenderer.cpp b/WebCore/platform/graphics/win/WKCACFLayerRenderer.cpp
index 9fbd0fc..3bbd4f8 100644
--- a/WebCore/platform/graphics/win/WKCACFLayerRenderer.cpp
+++ b/WebCore/platform/graphics/win/WKCACFLayerRenderer.cpp
@@ -34,15 +34,20 @@
#include <CoreGraphics/CGSRegion.h>
#include <QuartzCore/CACFContext.h>
#include <QuartzCore/CARenderOGL.h>
+#include <QuartzCoreInterface/QuartzCoreInterface.h>
#include <wtf/HashMap.h>
#include <wtf/OwnArrayPtr.h>
+#include <wtf/StdLibExtras.h>
#include <d3d9.h>
#include <d3dx9.h>
-#include <dxerr9.h>
-#pragma comment(lib, "d3d9")
-#pragma comment(lib, "d3dx9")
-#pragma comment(lib, "QuartzCore")
+#pragma comment(lib, "d3d9")
+#pragma comment(lib, "d3dx9")
+#ifdef DEBUG_ALL
+#pragma comment(lib, "QuartzCore_debug")
+#else
+#pragma comment(lib, "QuartzCore")
+#endif
static IDirect3D9* s_d3d = 0;
static IDirect3D9* d3d()
@@ -90,29 +95,29 @@ static D3DPRESENT_PARAMETERS initialPresentationParameters()
return parameters;
}
-bool WKCACFLayerRenderer::acceleratedCompositingAvailable()
-{
- static bool available;
- static bool tested;
-
- if (tested)
- return available;
-
- tested = true;
- HMODULE library = LoadLibrary(TEXT("d3d9.dll"));
- if (!library)
- return false;
-
- FreeLibrary(library);
- library = LoadLibrary(TEXT("QuartzCore.dll"));
- if (!library)
- return false;
-
- FreeLibrary(library);
- available = true;
- return available;
-}
-
+bool WKCACFLayerRenderer::acceleratedCompositingAvailable()
+{
+ static bool available;
+ static bool tested;
+
+ if (tested)
+ return available;
+
+ tested = true;
+ HMODULE library = LoadLibrary(TEXT("d3d9.dll"));
+ if (!library)
+ return false;
+
+ FreeLibrary(library);
+ library = LoadLibrary(TEXT("QuartzCore.dll"));
+ if (!library)
+ return false;
+
+ FreeLibrary(library);
+ available = true;
+ return available;
+}
+
void WKCACFLayerRenderer::didFlushContext(CACFContextRef context)
{
WKCACFLayerRenderer* window = windowsForContexts().get(context);
@@ -135,8 +140,7 @@ WKCACFLayerRenderer::WKCACFLayerRenderer()
, m_renderer(0)
, m_hostWindow(0)
, m_renderTimer(this, &WKCACFLayerRenderer::renderTimerFired)
- , m_scrollFrameWidth(1) // Default to 1 to avoid 0 size frames
- , m_scrollFrameHeight(1) // Default to 1 to avoid 0 size frames
+ , m_scrollFrame(0, 0, 1, 1) // Default to 1 to avoid 0 size frames
{
}
@@ -145,19 +149,15 @@ WKCACFLayerRenderer::~WKCACFLayerRenderer()
destroyRenderer();
}
-void WKCACFLayerRenderer::setScrollFrame(int width, int height, int scrollX, int scrollY)
+void WKCACFLayerRenderer::setScrollFrame(const IntRect& scrollFrame)
{
- m_scrollFrameWidth = width;
- m_scrollFrameHeight = height;
-
- CGRect contentsRect = CGRectMake(scrollX, scrollY, width, height);
- m_scrollLayer->setFrame(contentsRect);
+ m_scrollFrame = scrollFrame;
+ CGRect frameBounds = bounds();
+ m_scrollLayer->setBounds(CGRectMake(0, 0, m_scrollFrame.width(), m_scrollFrame.height()));
+ m_scrollLayer->setPosition(CGPointMake(0, frameBounds.size.height));
- if (m_rootChildLayer) {
- contentsRect.origin.x = 0;
- contentsRect.origin.y = 0;
- m_rootChildLayer->setFrame(contentsRect);
- }
+ if (m_rootChildLayer)
+ m_rootChildLayer->setPosition(CGPointMake(m_scrollFrame.x(), m_scrollFrame.height() + m_scrollFrame.y()));
}
void WKCACFLayerRenderer::setRootContents(CGImageRef image)
@@ -177,7 +177,8 @@ void WKCACFLayerRenderer::setRootChildLayer(WebCore::PlatformLayer* layer)
m_scrollLayer->addSublayer(layer);
// Set the frame
- layer->setFrame(CGRectMake(0, 0, m_scrollFrameWidth, m_scrollFrameHeight));
+ layer->setAnchorPoint(CGPointMake(0, 1));
+ setScrollFrame(m_scrollFrame);
}
m_rootChildLayer = layer;
@@ -225,14 +226,15 @@ void WKCACFLayerRenderer::createRenderer()
windowsForContexts().set(m_context.get(), this);
m_renderContext = static_cast<CARenderContext*>(CACFContextGetRenderContext(m_context.get()));
- m_renderer = CARenderOGLNew(&kCARenderDX9Callbacks, m_d3dDevice.get(), 0);
+ m_renderer = CARenderOGLNew(wkqcCARenderOGLCallbacks(wkqckCARenderDX9Callbacks), m_d3dDevice.get(), 0);
// Create the root hierarchy
- m_rootLayer = WKCACFLayer::create(kCACFLayer);
- m_scrollLayer = WKCACFLayer::create(kCACFLayer);
+ m_rootLayer = WKCACFLayer::create(WKCACFLayer::Layer);
+ m_scrollLayer = WKCACFLayer::create(WKCACFLayer::Layer);
m_rootLayer->addSublayer(m_scrollLayer);
m_scrollLayer->setMasksToBounds(true);
+ m_scrollLayer->setAnchorPoint(CGPointMake(0, 1));
#ifndef NDEBUG
CGColorRef debugColor = createCGColor(Color(255, 0, 0, 204));
@@ -240,14 +242,9 @@ void WKCACFLayerRenderer::createRenderer()
CGColorRelease(debugColor);
#endif
- if (IsWindow(m_hostWindow)) {
+ if (IsWindow(m_hostWindow))
m_rootLayer->setFrame(bounds());
- // For now this will include the scroll bars. Later in the setScrollFrame
- // we will fix it
- m_scrollLayer->setFrame(bounds());
- }
-
if (m_context)
m_rootLayer->becomeRootLayerForContext(m_context.get());
}
@@ -284,6 +281,7 @@ void WKCACFLayerRenderer::resize()
if (m_rootLayer) {
m_rootLayer->setFrame(bounds());
WKCACFContextFlusher::shared().flushAllContexts();
+ setScrollFrame(m_scrollFrame);
}
}
diff --git a/WebCore/platform/graphics/win/WKCACFLayerRenderer.h b/WebCore/platform/graphics/win/WKCACFLayerRenderer.h
index 12cde48..cb9f04f 100644
--- a/WebCore/platform/graphics/win/WKCACFLayerRenderer.h
+++ b/WebCore/platform/graphics/win/WKCACFLayerRenderer.h
@@ -58,7 +58,7 @@ public:
static bool acceleratedCompositingAvailable();
static void didFlushContext(CACFContextRef);
- void setScrollFrame(int width, int height, int scrollX, int scrollY);
+ void setScrollFrame(const IntRect&);
void setRootContents(CGImageRef);
void setRootChildLayer(WebCore::PlatformLayer* layer);
void setNeedsDisplay();
@@ -96,7 +96,7 @@ private:
CARenderOGLContext* m_renderer;
HWND m_hostWindow;
Timer<WKCACFLayerRenderer> m_renderTimer;
- int m_scrollFrameWidth, m_scrollFrameHeight;
+ IntRect m_scrollFrame;
};
}
diff --git a/WebCore/platform/graphics/wince/GraphicsContextWince.cpp b/WebCore/platform/graphics/wince/GraphicsContextWince.cpp
index f22e6c9..0e387f5 100644
--- a/WebCore/platform/graphics/wince/GraphicsContextWince.cpp
+++ b/WebCore/platform/graphics/wince/GraphicsContextWince.cpp
@@ -1002,7 +1002,12 @@ void GraphicsContext::clipOut(const IntRect& rect)
ExcludeClipRect(m_data->m_dc, trRect.x(), trRect.y(), trRect.right(), trRect.bottom());
}
-void GraphicsContext::drawFocusRing(const Color& color)
+void GraphicsContext::drawFocusRing(const Vector<Path>& paths, int width, int offset, const Color& color)
+{
+ // FIXME: implement
+}
+
+void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int offset, const Color& color)
{
if (!m_data->m_opacity || paintingDisabled())
return;
@@ -1011,10 +1016,9 @@ void GraphicsContext::drawFocusRing(const Color& color)
if (!m_data->m_dc)
return;
- int radius = (focusRingWidth() - 1) / 2;
- int offset = radius + focusRingOffset();
+ int radius = (width - 1) / 2;
+ offset += radius;
- const Vector<IntRect>& rects = focusRingRects();
unsigned rectCount = rects.size();
IntRect finalFocusRect;
for (unsigned i = 0; i < rectCount; i++) {
diff --git a/WebCore/platform/graphics/wince/MediaPlayerPrivateWince.h b/WebCore/platform/graphics/wince/MediaPlayerPrivateWince.h
index 2d6c358..a657e3e 100644
--- a/WebCore/platform/graphics/wince/MediaPlayerPrivateWince.h
+++ b/WebCore/platform/graphics/wince/MediaPlayerPrivateWince.h
@@ -61,20 +61,16 @@ namespace WebCore {
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);
diff --git a/WebCore/platform/graphics/wx/GraphicsContextWx.cpp b/WebCore/platform/graphics/wx/GraphicsContextWx.cpp
index 9c05ce5..839bc59 100644
--- a/WebCore/platform/graphics/wx/GraphicsContextWx.cpp
+++ b/WebCore/platform/graphics/wx/GraphicsContextWx.cpp
@@ -270,7 +270,12 @@ void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLef
notImplemented();
}
-void GraphicsContext::drawFocusRing(const Color& color)
+void GraphicsContext::drawFocusRing(const Vector<Path>& paths, int width, int offset, const Color& color)
+{
+ // FIXME: implement
+}
+
+void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int offset, const Color& color)
{
if (paintingDisabled())
return;
@@ -566,7 +571,7 @@ void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness
notImplemented();
}
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
HDC GraphicsContext::getWindowsContext(const IntRect& dstRect, bool supportAlphaBlend, bool mayCreateBitmap)
{
if (dstRect.isEmpty())
diff --git a/WebCore/platform/gtk/ContextMenuItemGtk.cpp b/WebCore/platform/gtk/ContextMenuItemGtk.cpp
index aaec206..b2fa853 100644
--- a/WebCore/platform/gtk/ContextMenuItemGtk.cpp
+++ b/WebCore/platform/gtk/ContextMenuItemGtk.cpp
@@ -59,7 +59,7 @@ static const char* gtkStockIDFromContextMenuAction(const ContextMenuAction& acti
case ContextMenuItemTagSelectAll:
return GTK_STOCK_SELECT_ALL;
case ContextMenuItemTagSpellingGuess:
- return GTK_STOCK_INFO;
+ return NULL;
case ContextMenuItemTagIgnoreSpelling:
return GTK_STOCK_NO;
case ContextMenuItemTagLearnSpelling:
@@ -117,6 +117,12 @@ ContextMenuItem::ContextMenuItem(GtkMenuItem* item)
m_platformDescription.checked = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item));
} else
m_platformDescription.type = ActionType;
+#if GTK_CHECK_VERSION (2, 16, 0)
+ m_platformDescription.title = String::fromUTF8(gtk_menu_item_get_label(GTK_MENU_ITEM(item)));
+#else
+ GtkWidget* label = gtk_bin_get_child(GTK_BIN(item));
+ m_platformDescription.title = String::fromUTF8(gtk_label_get_label(GTK_LABEL(label)));
+#endif
m_platformDescription.action = *static_cast<ContextMenuAction*>(g_object_get_data(G_OBJECT(item), WEBKIT_CONTEXT_MENU_ACTION));
@@ -205,13 +211,12 @@ void ContextMenuItem::setAction(ContextMenuAction action)
String ContextMenuItem::title() const
{
- notImplemented();
- return String();
+ return m_platformDescription.title;
}
-void ContextMenuItem::setTitle(const String&)
+void ContextMenuItem::setTitle(const String& title)
{
- notImplemented();
+ m_platformDescription.title = title;
}
PlatformMenuDescription ContextMenuItem::platformSubMenu() const
diff --git a/WebCore/platform/gtk/DataObjectGtk.cpp b/WebCore/platform/gtk/DataObjectGtk.cpp
new file mode 100644
index 0000000..900fe8e
--- /dev/null
+++ b/WebCore/platform/gtk/DataObjectGtk.cpp
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2009, Martin Robinson
+ *
+ * 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 "DataObjectGtk.h"
+
+#include "markup.h"
+#include <gtk/gtk.h>
+
+namespace WebCore {
+
+String DataObjectGtk::text()
+{
+ if (m_range)
+ return m_range->text();
+ return m_text;
+}
+
+String DataObjectGtk::markup()
+{
+ if (m_range)
+ createMarkup(m_range.get(), 0, AnnotateForInterchange);
+ return m_markup;
+}
+
+void DataObjectGtk::setText(const String& newText)
+{
+ m_range = 0;
+ m_text = newText;
+}
+
+void DataObjectGtk::setMarkup(const String& newMarkup)
+{
+ m_range = 0;
+ m_markup = newMarkup;
+}
+
+Vector<String> DataObjectGtk::files()
+{
+ Vector<KURL> uris(uriList());
+ Vector<String> files;
+
+ for (size_t i = 0; i < uris.size(); i++) {
+ KURL& uri = uris[0];
+ if (!uri.isValid() || !uri.isLocalFile())
+ continue;
+
+ files.append(uri.string());
+ }
+
+ return files;
+}
+
+String DataObjectGtk::url()
+{
+ Vector<KURL> uris(uriList());
+ for (size_t i = 0; i < uris.size(); i++) {
+ KURL& uri = uris[0];
+ if (uri.isValid())
+ return uri;
+ }
+
+ return String();
+}
+
+String DataObjectGtk::urlLabel()
+{
+ if (hasText())
+ return text();
+
+ if (hasURL())
+ return url();
+
+ return String();
+}
+
+bool DataObjectGtk::hasURL()
+{
+ return !url().isEmpty();
+}
+
+void DataObjectGtk::clear()
+{
+ m_text = "";
+ m_markup = "";
+ m_uriList.clear();
+ m_image = 0;
+ m_range = 0;
+}
+
+DataObjectGtk* DataObjectGtk::forClipboard(GtkClipboard* clipboard)
+{
+ static HashMap<GtkClipboard*, RefPtr<DataObjectGtk> > objectMap;
+
+ if (!objectMap.contains(clipboard)) {
+ RefPtr<DataObjectGtk> dataObject = DataObjectGtk::create();
+ objectMap.set(clipboard, dataObject);
+ return dataObject.get();
+ }
+
+ HashMap<GtkClipboard*, RefPtr<DataObjectGtk> >::iterator it = objectMap.find(clipboard);
+ return it->second.get();
+}
+
+}
diff --git a/WebCore/platform/gtk/DataObjectGtk.h b/WebCore/platform/gtk/DataObjectGtk.h
new file mode 100644
index 0000000..f1a2647
--- /dev/null
+++ b/WebCore/platform/gtk/DataObjectGtk.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2009, Martin Robinson
+ *
+ * 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 DataObjectGtk_h
+#define DataObjectGtk_h
+
+#include "CString.h"
+#include "FileList.h"
+#include "KURL.h"
+#include "Range.h"
+#include "StringHash.h"
+#include <wtf/RefCounted.h>
+#include <wtf/gtk/GRefPtr.h>
+
+typedef struct _GdkPixbuf GdkPixbuf;
+typedef struct _GdkDragContext GdkDragContext;
+typedef struct _GtkClipboard GtkClipboard;
+
+namespace WebCore {
+
+class DataObjectGtk : public RefCounted<DataObjectGtk> {
+public:
+ static PassRefPtr<DataObjectGtk> create()
+ {
+ return adoptRef(new DataObjectGtk());
+ }
+
+ Vector<KURL> uriList() { return m_uriList; }
+ GdkPixbuf* image() { return m_image.get(); }
+ void setRange(PassRefPtr<Range> newRange) { m_range = newRange; }
+ void setURIList(const Vector<KURL>& newURIList) { m_uriList = newURIList; }
+ void setImage(GdkPixbuf* newImage) { m_image = newImage; }
+ void setDragContext(GdkDragContext* newDragContext) { m_dragContext = newDragContext; }
+ bool hasText() { return m_range || !m_text.isEmpty(); }
+ bool hasMarkup() { return m_range || !m_markup.isEmpty(); }
+ bool hasURIList() { return !m_uriList.isEmpty(); }
+ bool hasImage() { return m_image; }
+ GdkDragContext* dragContext() { return m_dragContext.get(); }
+
+ String text();
+ String markup();
+ Vector<String> files();
+ void setText(const String& newText);
+ void setMarkup(const String& newMarkup);
+ bool hasURL();
+ String url();
+ String urlLabel();
+ void clear();
+
+ static DataObjectGtk* forClipboard(GtkClipboard*);
+
+private:
+ String m_text;
+ String m_markup;
+ Vector<KURL> m_uriList;
+ GRefPtr<GdkPixbuf> m_image;
+ GRefPtr<GdkDragContext> m_dragContext;
+ RefPtr<Range> m_range;
+};
+
+}
+
+#endif // DataObjectGtk_h
diff --git a/WebCore/platform/gtk/FileSystemGtk.cpp b/WebCore/platform/gtk/FileSystemGtk.cpp
index fcdc863..b8bbd60 100644
--- a/WebCore/platform/gtk/FileSystemGtk.cpp
+++ b/WebCore/platform/gtk/FileSystemGtk.cpp
@@ -42,7 +42,7 @@ String filenameToString(const char* filename)
if (!filename)
return String();
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
return String::fromUTF8(filename);
#else
gchar* escapedString = g_uri_escape_string(filename, "/:", false);
@@ -54,7 +54,7 @@ String filenameToString(const char* filename)
char* filenameFromString(const String& string)
{
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
return g_strdup(string.utf8().data());
#else
return g_uri_unescape_string(string.utf8().data(), 0);
@@ -64,7 +64,7 @@ char* filenameFromString(const String& string)
// Converts a string to something suitable to be displayed to the user.
String filenameForDisplay(const String& string)
{
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
return string;
#else
gchar* filename = filenameFromString(string);
diff --git a/WebCore/platform/gtk/GRefPtrGtk.cpp b/WebCore/platform/gtk/GRefPtrGtk.cpp
new file mode 100644
index 0000000..6647b99
--- /dev/null
+++ b/WebCore/platform/gtk/GRefPtrGtk.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2008 Collabora Ltd.
+ * Copyright (C) 2009 Martin Robinson
+ *
+ * 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 "GRefPtrGtk.h"
+
+#include <glib.h>
+#include <gtk/gtk.h>
+
+namespace WTF {
+
+template <> GtkTargetList* refGPtr(GtkTargetList* ptr)
+{
+ if (ptr)
+ gtk_target_list_ref(ptr);
+ return ptr;
+}
+
+template <> void derefGPtr(GtkTargetList* ptr)
+{
+ if (ptr)
+ gtk_target_list_unref(ptr);
+}
+
+template <> GdkCursor* refGPtr(GdkCursor* ptr)
+{
+ if (ptr)
+ gdk_cursor_ref(ptr);
+ return ptr;
+}
+
+template <> void derefGPtr(GdkCursor* ptr)
+{
+ if (ptr)
+ gdk_cursor_unref(ptr);
+}
+
+}
diff --git a/WebCore/platform/gtk/GRefPtrGtk.h b/WebCore/platform/gtk/GRefPtrGtk.h
new file mode 100644
index 0000000..77941f5
--- /dev/null
+++ b/WebCore/platform/gtk/GRefPtrGtk.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2008 Collabora Ltd.
+ * Copyright (C) 2009 Martin Robinson
+ *
+ * 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 GRefPtrGtk_h
+#define GRefPtrGtk_h
+
+#include "GRefPtr.h"
+
+typedef struct _GtkTargetList GtkTargetList;
+typedef struct _GdkCursor GdkCursor;
+
+namespace WTF {
+
+template <> GtkTargetList* refGPtr(GtkTargetList* ptr);
+template <> void derefGPtr(GtkTargetList* ptr);
+
+template <> GdkCursor* refGPtr(GdkCursor* ptr);
+template <> void derefGPtr(GdkCursor* ptr);
+
+}
+
+#endif
diff --git a/WebCore/platform/gtk/KeyEventGtk.cpp b/WebCore/platform/gtk/KeyEventGtk.cpp
index 11ea956..e00ea43 100644
--- a/WebCore/platform/gtk/KeyEventGtk.cpp
+++ b/WebCore/platform/gtk/KeyEventGtk.cpp
@@ -181,6 +181,23 @@ static int windowsKeyCodeForKeyEvent(unsigned int keycode)
case GDK_KP_Divide:
return VK_DIVIDE; // (6F) Divide key
+ case GDK_KP_Page_Up:
+ return VK_PRIOR; // (21) PAGE UP key
+ case GDK_KP_Page_Down:
+ return VK_NEXT; // (22) PAGE DOWN key
+ case GDK_KP_End:
+ return VK_END; // (23) END key
+ case GDK_KP_Home:
+ return VK_HOME; // (24) HOME key
+ case GDK_KP_Left:
+ return VK_LEFT; // (25) LEFT ARROW key
+ case GDK_KP_Up:
+ return VK_UP; // (26) UP ARROW key
+ case GDK_KP_Right:
+ return VK_RIGHT; // (27) RIGHT ARROW key
+ case GDK_KP_Down:
+ return VK_DOWN; // (28) DOWN ARROW key
+
case GDK_BackSpace:
return VK_BACK; // (08) BACKSPACE key
case GDK_ISO_Left_Tab:
diff --git a/WebCore/platform/gtk/LocalizedStringsGtk.cpp b/WebCore/platform/gtk/LocalizedStringsGtk.cpp
index 5809e47..e0ec3ab 100644
--- a/WebCore/platform/gtk/LocalizedStringsGtk.cpp
+++ b/WebCore/platform/gtk/LocalizedStringsGtk.cpp
@@ -38,6 +38,7 @@
#include <glib/gi18n-lib.h>
#include <gtk/gtk.h>
+#include <math.h>
namespace WebCore {
@@ -325,6 +326,16 @@ String AXLinkActionVerb()
return String::fromUTF8(_("jump"));
}
+String AXMenuListPopupActionVerb()
+{
+ return String();
+}
+
+String AXMenuListActionVerb()
+{
+ return String();
+}
+
String multipleFileUploadText(unsigned numberOfFiles)
{
// FIXME: If this file gets localized, this should really be localized as one string with a wildcard for the number.
diff --git a/WebCore/platform/gtk/PasteboardGtk.cpp b/WebCore/platform/gtk/PasteboardGtk.cpp
index ee95a38..0b4d356 100644
--- a/WebCore/platform/gtk/PasteboardGtk.cpp
+++ b/WebCore/platform/gtk/PasteboardGtk.cpp
@@ -171,7 +171,7 @@ PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefP
gtk_selection_data_free(data);
if (!html.isEmpty()) {
- RefPtr<DocumentFragment> fragment = createFragmentFromMarkup(frame->document(), html, "");
+ RefPtr<DocumentFragment> fragment = createFragmentFromMarkup(frame->document(), html, "", FragmentScriptingNotAllowed);
if (fragment)
return fragment.release();
}
diff --git a/WebCore/platform/gtk/PasteboardHelper.h b/WebCore/platform/gtk/PasteboardHelper.h
index e589f24..fff9a9b 100644
--- a/WebCore/platform/gtk/PasteboardHelper.h
+++ b/WebCore/platform/gtk/PasteboardHelper.h
@@ -30,7 +30,8 @@
#include "Frame.h"
-#include <gtk/gtk.h>
+typedef struct _GtkClipboard GtkClipboard;
+typedef struct _GtkTargetList GtkTargetList;
namespace WebCore {
diff --git a/WebCore/platform/gtk/PlatformScreenGtk.cpp b/WebCore/platform/gtk/PlatformScreenGtk.cpp
index a6ff954..92ccff4 100644
--- a/WebCore/platform/gtk/PlatformScreenGtk.cpp
+++ b/WebCore/platform/gtk/PlatformScreenGtk.cpp
@@ -56,7 +56,11 @@ static GdkVisual* getVisual(Widget* widget)
if (!GTK_WIDGET_REALIZED(container)) {
GtkWidget* toplevel = gtk_widget_get_toplevel(container);
+#if GTK_CHECK_VERSION(2, 18, 0)
+ if (gtk_widget_is_toplevel(toplevel))
+#else
if (GTK_WIDGET_TOPLEVEL(toplevel))
+#endif
container = toplevel;
else
return 0;
@@ -94,7 +98,11 @@ FloatRect screenRect(Widget* widget)
return FloatRect();
GtkWidget* container = gtk_widget_get_toplevel(GTK_WIDGET(widget->root()->hostWindow()->platformPageClient()));
+#if GTK_CHECK_VERSION(2, 18, 0)
+ if (!gtk_widget_is_toplevel(container))
+#else
if (!GTK_WIDGET_TOPLEVEL(container))
+#endif
return FloatRect();
GdkScreen* screen = gtk_widget_has_screen(container) ? gtk_widget_get_screen(container) : gdk_screen_get_default();
diff --git a/WebCore/platform/gtk/PopupMenuGtk.cpp b/WebCore/platform/gtk/PopupMenuGtk.cpp
index 3f6b02a..0363ac4 100644
--- a/WebCore/platform/gtk/PopupMenuGtk.cpp
+++ b/WebCore/platform/gtk/PopupMenuGtk.cpp
@@ -35,16 +35,14 @@ namespace WebCore {
PopupMenu::PopupMenu(PopupMenuClient* client)
: m_popupClient(client)
- , m_popup(0)
{
}
PopupMenu::~PopupMenu()
{
if (m_popup) {
- g_signal_handlers_disconnect_matched(m_popup, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this);
+ g_signal_handlers_disconnect_matched(m_popup.get(), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this);
hide();
- g_object_unref(m_popup);
}
}
@@ -54,10 +52,9 @@ void PopupMenu::show(const IntRect& rect, FrameView* view, int index)
if (!m_popup) {
m_popup = GTK_MENU(gtk_menu_new());
- g_object_ref_sink(G_OBJECT(m_popup));
- g_signal_connect(m_popup, "unmap", G_CALLBACK(menuUnmapped), this);
+ g_signal_connect(m_popup.get(), "unmap", G_CALLBACK(menuUnmapped), this);
} else
- gtk_container_foreach(GTK_CONTAINER(m_popup), reinterpret_cast<GtkCallback>(menuRemoveItem), this);
+ gtk_container_foreach(GTK_CONTAINER(m_popup.get()), reinterpret_cast<GtkCallback>(menuRemoveItem), this);
int x, y;
gdk_window_get_origin(GTK_WIDGET(view->hostWindow()->platformPageClient())->window, &x, &y);
@@ -78,20 +75,20 @@ void PopupMenu::show(const IntRect& rect, FrameView* view, int index)
// FIXME: Apply the PopupMenuStyle from client()->itemStyle(i)
gtk_widget_set_sensitive(item, client()->itemIsEnabled(i));
- gtk_menu_shell_append(GTK_MENU_SHELL(m_popup), item);
+ gtk_menu_shell_append(GTK_MENU_SHELL(m_popup.get()), item);
gtk_widget_show(item);
}
- gtk_menu_set_active(m_popup, index);
+ gtk_menu_set_active(m_popup.get(), index);
// The size calls are directly copied from gtkcombobox.c which is LGPL
GtkRequisition requisition;
- gtk_widget_set_size_request(GTK_WIDGET(m_popup), -1, -1);
- gtk_widget_size_request(GTK_WIDGET(m_popup), &requisition);
- gtk_widget_set_size_request(GTK_WIDGET(m_popup), MAX(rect.width(), requisition.width), -1);
+ gtk_widget_set_size_request(GTK_WIDGET(m_popup.get()), -1, -1);
+ gtk_widget_size_request(GTK_WIDGET(m_popup.get()), &requisition);
+ gtk_widget_set_size_request(GTK_WIDGET(m_popup.get()), std::max(rect.width(), requisition.width), -1);
- GList* children = GTK_MENU_SHELL(m_popup)->children;
+ GList* children = GTK_MENU_SHELL(m_popup.get())->children;
if (size)
for (int i = 0; i < size; i++) {
if (i > index)
@@ -103,18 +100,17 @@ void PopupMenu::show(const IntRect& rect, FrameView* view, int index)
m_menuPosition.setY(m_menuPosition.y() - itemRequisition.height);
children = g_list_next(children);
- }
- else
- // Center vertically the empty popup in the combo box area
- m_menuPosition.setY(m_menuPosition.y() - rect.height() / 2);
+ } else
+ // Center vertically the empty popup in the combo box area
+ m_menuPosition.setY(m_menuPosition.y() - rect.height() / 2);
- gtk_menu_popup(m_popup, NULL, NULL, reinterpret_cast<GtkMenuPositionFunc>(menuPositionFunction), this, 0, gtk_get_current_event_time());
+ gtk_menu_popup(m_popup.get(), 0, 0, reinterpret_cast<GtkMenuPositionFunc>(menuPositionFunction), this, 0, gtk_get_current_event_time());
}
void PopupMenu::hide()
{
ASSERT(m_popup);
- gtk_menu_popdown(m_popup);
+ gtk_menu_popdown(m_popup.get());
}
void PopupMenu::updateFromElement()
@@ -150,7 +146,7 @@ void PopupMenu::menuPositionFunction(GtkMenu*, gint* x, gint* y, gboolean* pushI
void PopupMenu::menuRemoveItem(GtkWidget* widget, PopupMenu* that)
{
ASSERT(that->m_popup);
- gtk_container_remove(GTK_CONTAINER(that->m_popup), widget);
+ gtk_container_remove(GTK_CONTAINER(that->m_popup.get()), widget);
}
}
diff --git a/WebCore/platform/gtk/RenderThemeGtk.cpp b/WebCore/platform/gtk/RenderThemeGtk.cpp
index 4842d68..0c157cf 100644
--- a/WebCore/platform/gtk/RenderThemeGtk.cpp
+++ b/WebCore/platform/gtk/RenderThemeGtk.cpp
@@ -24,17 +24,87 @@
#include "config.h"
#include "RenderThemeGtk.h"
-#include "TransformationMatrix.h"
+#include "CString.h"
+#include "GOwnPtr.h"
#include "GraphicsContext.h"
+#include "HTMLMediaElement.h"
+#include "HTMLNames.h"
#include "NotImplemented.h"
#include "RenderBox.h"
#include "RenderObject.h"
+#include "TransformationMatrix.h"
+#include "UserAgentStyleSheets.h"
#include "gtkdrawing.h"
#include <gdk/gdk.h>
+#include <gtk/gtk.h>
namespace WebCore {
+using namespace HTMLNames;
+
+#if ENABLE(VIDEO)
+static HTMLMediaElement* getMediaElementFromRenderObject(RenderObject* o)
+{
+ Node* node = o->node();
+ Node* mediaNode = node ? node->shadowAncestorNode() : 0;
+ if (!mediaNode || (!mediaNode->hasTagName(videoTag) && !mediaNode->hasTagName(audioTag)))
+ return 0;
+
+ return static_cast<HTMLMediaElement*>(mediaNode);
+}
+
+static gchar* getIconNameForTextDirection(const char* baseName)
+{
+ GString* nameWithDirection = g_string_new(baseName);
+ GtkTextDirection textDirection = gtk_widget_get_default_direction();
+
+ if (textDirection == GTK_TEXT_DIR_RTL)
+ g_string_append(nameWithDirection, "-rtl");
+ else if (textDirection == GTK_TEXT_DIR_LTR)
+ g_string_append(nameWithDirection, "-ltr");
+
+ return g_string_free(nameWithDirection, FALSE);
+}
+
+void RenderThemeGtk::initMediaStyling(GtkStyle* style, bool force)
+{
+ static bool stylingInitialized = false;
+
+ if (!stylingInitialized || force) {
+ m_panelColor = style->bg[GTK_STATE_NORMAL];
+ m_sliderColor = style->bg[GTK_STATE_ACTIVE];
+ m_sliderThumbColor = style->bg[GTK_STATE_SELECTED];
+
+ // Names of these icons can vary because of text direction.
+ gchar* playButtonIconName = getIconNameForTextDirection("gtk-media-play");
+ gchar* seekBackButtonIconName = getIconNameForTextDirection("gtk-media-rewind");
+ gchar* seekForwardButtonIconName = getIconNameForTextDirection("gtk-media-forward");
+
+ m_fullscreenButton.clear();
+ m_muteButton.clear();
+ m_unmuteButton.clear();
+ m_playButton.clear();
+ m_pauseButton.clear();
+ m_seekBackButton.clear();
+ m_seekForwardButton.clear();
+
+ m_fullscreenButton = Image::loadPlatformThemeIcon("gtk-fullscreen", m_mediaIconSize);
+ m_muteButton = Image::loadPlatformThemeIcon("audio-volume-muted", m_mediaIconSize);
+ m_unmuteButton = Image::loadPlatformThemeIcon("audio-volume-high", m_mediaIconSize);
+ m_playButton = Image::loadPlatformThemeIcon(reinterpret_cast<const char*>(playButtonIconName), m_mediaIconSize);
+ m_pauseButton = Image::loadPlatformThemeIcon("gtk-media-pause", m_mediaIconSize).releaseRef();
+ m_seekBackButton = Image::loadPlatformThemeIcon(reinterpret_cast<const char*>(seekBackButtonIconName), m_mediaIconSize);
+ m_seekForwardButton = Image::loadPlatformThemeIcon(reinterpret_cast<const char*>(seekForwardButtonIconName), m_mediaIconSize);
+
+ g_free(playButtonIconName);
+ g_free(seekBackButtonIconName);
+ g_free(seekForwardButtonIconName);
+ stylingInitialized = true;
+ }
+}
+#endif
+
PassRefPtr<RenderTheme> RenderThemeGtk::create()
{
return adoptRef(new RenderThemeGtk());
@@ -53,11 +123,34 @@ RenderThemeGtk::RenderThemeGtk()
, m_gtkContainer(0)
, m_gtkEntry(0)
, m_gtkTreeView(0)
-{
- if (!mozGtkRefCount)
+ , m_panelColor(Color::white)
+ , m_sliderColor(Color::white)
+ , m_sliderThumbColor(Color::white)
+ , m_mediaIconSize(16)
+ , m_mediaSliderHeight(14)
+ , m_mediaSliderThumbWidth(12)
+ , m_mediaSliderThumbHeight(12)
+ , m_fullscreenButton(0)
+ , m_muteButton(0)
+ , m_unmuteButton(0)
+ , m_playButton(0)
+ , m_pauseButton(0)
+ , m_seekBackButton(0)
+ , m_seekForwardButton(0)
+ , m_partsTable(adoptGRef(g_hash_table_new_full(0, 0, 0, g_free)))
+{
+ if (!mozGtkRefCount) {
moz_gtk_init();
+ // Use the theme parts for the default drawable.
+ moz_gtk_use_theme_parts(partsForDrawable(0));
+ }
+
++mozGtkRefCount;
+
+#if ENABLE(VIDEO)
+ initMediaStyling(gtk_rc_get_style(GTK_WIDGET(gtkContainer())), false);
+#endif
}
RenderThemeGtk::~RenderThemeGtk()
@@ -66,22 +159,54 @@ RenderThemeGtk::~RenderThemeGtk()
if (!mozGtkRefCount)
moz_gtk_shutdown();
+
+ m_fullscreenButton.clear();
+ m_muteButton.clear();
+ m_unmuteButton.clear();
+ m_playButton.clear();
+ m_pauseButton.clear();
+ m_seekBackButton.clear();
+ m_seekForwardButton.clear();
+
+ GList* values = g_hash_table_get_values(m_partsTable.get());
+ for (guint i = 0; i < g_list_length(values); i++)
+ moz_gtk_destroy_theme_parts_widgets(
+ static_cast<GtkThemeParts*>(g_list_nth_data(values, i)));
+}
+
+GtkThemeParts* RenderThemeGtk::partsForDrawable(GdkDrawable* drawable) const
+{
+ // A null drawable represents the default screen colormap.
+ GdkColormap* colormap = 0;
+ if (!drawable)
+ colormap = gdk_screen_get_default_colormap(gdk_screen_get_default());
+ else
+ colormap = gdk_drawable_get_colormap(drawable);
+
+ GtkThemeParts* parts = static_cast<GtkThemeParts*>(g_hash_table_lookup(m_partsTable.get(), colormap));
+ if (!parts) {
+ parts = g_new0(GtkThemeParts, 1);
+ parts->colormap = colormap;
+ g_hash_table_insert(m_partsTable.get(), colormap, parts);
+ }
+
+ return parts;
}
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;
+ case PushButtonPart:
+ case ButtonPart:
+ case TextFieldPart:
+ case TextAreaPart:
+ case SearchFieldPart:
+ case MenulistPart:
+ case RadioPart:
+ case CheckboxPart:
+ return true;
+ default:
+ return false;
}
}
@@ -101,8 +226,8 @@ int RenderThemeGtk::baselinePosition(const RenderObject* o) const
return 0;
// FIXME: This strategy is possibly incorrect for the GTK+ port.
- if (o->style()->appearance() == CheckboxPart ||
- o->style()->appearance() == RadioPart) {
+ if (o->style()->appearance() == CheckboxPart
+ || o->style()->appearance() == RadioPart) {
const RenderBox* box = toRenderBox(o);
return box->marginTop() + box->height() - 2;
}
@@ -122,7 +247,7 @@ static GtkTextDirection gtkTextDirection(TextDirection direction)
}
}
-static void adjustMozStyle(RenderStyle* style, GtkThemeWidgetType type)
+static void adjustMozillaStyle(const RenderThemeGtk* theme, RenderStyle* style, GtkThemeWidgetType type)
{
gint left, top, right, bottom;
GtkTextDirection direction = gtkTextDirection(style->direction());
@@ -141,7 +266,7 @@ static void adjustMozStyle(RenderStyle* style, GtkThemeWidgetType type)
style->setPaddingBottom(Length(ypadding + bottom, Fixed));
}
-static void setMozState(RenderTheme* theme, GtkWidgetState* state, RenderObject* o)
+static void setMozillaState(const RenderTheme* theme, GtkWidgetState* state, RenderObject* o)
{
state->active = theme->isPressed(o);
state->focused = theme->isFocused(o);
@@ -153,7 +278,7 @@ static void setMozState(RenderTheme* theme, GtkWidgetState* state, RenderObject*
state->depressed = false;
}
-static bool paintMozWidget(RenderTheme* theme, GtkThemeWidgetType type, RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
+static bool paintMozillaGtkWidget(const RenderThemeGtk* theme, GtkThemeWidgetType type, RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
{
// No GdkWindow to render to, so return true to fall back
if (!i.context->gdkDrawable())
@@ -164,22 +289,22 @@ static bool paintMozWidget(RenderTheme* theme, GtkThemeWidgetType type, RenderOb
return false;
GtkWidgetState mozState;
- setMozState(theme, &mozState, o);
+ setMozillaState(theme, &mozState, o);
int flags;
// We might want to make setting flags the caller's job at some point rather than doing it here.
switch (type) {
- case MOZ_GTK_BUTTON:
- flags = GTK_RELIEF_NORMAL;
- break;
- case MOZ_GTK_CHECKBUTTON:
- case MOZ_GTK_RADIOBUTTON:
- flags = theme->isChecked(o);
- break;
- default:
- flags = 0;
- break;
+ case MOZ_GTK_BUTTON:
+ flags = GTK_RELIEF_NORMAL;
+ break;
+ case MOZ_GTK_CHECKBUTTON:
+ case MOZ_GTK_RADIOBUTTON:
+ flags = theme->isChecked(o);
+ break;
+ default:
+ flags = 0;
+ break;
}
TransformationMatrix ctm = i.context->getCTM();
@@ -189,7 +314,7 @@ static bool paintMozWidget(RenderTheme* theme, GtkThemeWidgetType type, RenderOb
GtkTextDirection direction = gtkTextDirection(o->style()->direction());
// Find the clip rectangle
- cairo_t *cr = i.context->platformContext();
+ cairo_t* cr = i.context->platformContext();
double clipX1, clipX2, clipY1, clipY2;
cairo_clip_extents(cr, &clipX1, &clipY1, &clipX2, &clipY2);
@@ -202,6 +327,9 @@ static bool paintMozWidget(RenderTheme* theme, GtkThemeWidgetType type, RenderOb
gdk_rectangle_intersect(&gdkRect, &gdkClipRect, &gdkClipRect);
+ // Since the theme renderer is going to be drawing onto this GdkDrawable,
+ // select the appropriate widgets for the drawable depth.
+ moz_gtk_use_theme_parts(theme->partsForDrawable(i.context->gdkDrawable()));
return moz_gtk_widget_paint(type, i.context->gdkDrawable(), &gdkRect, &gdkClipRect, &mozState, flags, direction) != MOZ_GTK_SUCCESS;
}
@@ -215,31 +343,31 @@ static void setButtonPadding(RenderStyle* style)
style->setPaddingBottom(Length(padding / 2, Fixed));
}
-static void setToggleSize(RenderStyle* style, ControlPart appearance)
+static void setToggleSize(const RenderThemeGtk* theme, RenderStyle* style, ControlPart appearance)
{
// The width and height are both specified, so we shouldn't change them.
if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto())
return;
- // FIXME: This is probably not correct use of indicator_size and indicator_spacing.
- gint indicator_size, indicator_spacing;
+ // FIXME: This is probably not correct use of indicatorSize and indicatorSpacing.
+ gint indicatorSize, indicatorSpacing;
switch (appearance) {
- case CheckboxPart:
- if (moz_gtk_checkbox_get_metrics(&indicator_size, &indicator_spacing) != MOZ_GTK_SUCCESS)
- return;
- break;
- case RadioPart:
- if (moz_gtk_radio_get_metrics(&indicator_size, &indicator_spacing) != MOZ_GTK_SUCCESS)
- return;
- break;
- default:
+ case CheckboxPart:
+ if (moz_gtk_checkbox_get_metrics(&indicatorSize, &indicatorSpacing) != MOZ_GTK_SUCCESS)
return;
+ break;
+ case RadioPart:
+ if (moz_gtk_radio_get_metrics(&indicatorSize, &indicatorSpacing) != MOZ_GTK_SUCCESS)
+ return;
+ break;
+ default:
+ return;
}
// Other ports hard-code this to 13, but GTK+ users tend to demand the native look.
// It could be made a configuration option values other than 13 actually break site compatibility.
- int length = indicator_size + indicator_spacing;
+ int length = indicatorSize + indicatorSpacing;
if (style->width().isIntrinsicOrAuto())
style->setWidth(Length(length, Fixed));
@@ -249,22 +377,22 @@ static void setToggleSize(RenderStyle* style, ControlPart appearance)
void RenderThemeGtk::setCheckboxSize(RenderStyle* style) const
{
- setToggleSize(style, RadioPart);
+ setToggleSize(this, style, RadioPart);
}
bool RenderThemeGtk::paintCheckbox(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
{
- return paintMozWidget(this, MOZ_GTK_CHECKBUTTON, o, i, rect);
+ return paintMozillaGtkWidget(this, MOZ_GTK_CHECKBUTTON, o, i, rect);
}
void RenderThemeGtk::setRadioSize(RenderStyle* style) const
{
- setToggleSize(style, RadioPart);
+ setToggleSize(this, style, RadioPart);
}
bool RenderThemeGtk::paintRadio(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
{
- return paintMozWidget(this, MOZ_GTK_RADIOBUTTON, o, i, rect);
+ return paintMozillaGtkWidget(this, MOZ_GTK_RADIOBUTTON, o, i, rect);
}
void RenderThemeGtk::adjustButtonStyle(CSSStyleSelector* selector, RenderStyle* style, WebCore::Element* e) const
@@ -285,7 +413,7 @@ void RenderThemeGtk::adjustButtonStyle(CSSStyleSelector* selector, RenderStyle*
bool RenderThemeGtk::paintButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
{
- return paintMozWidget(this, MOZ_GTK_BUTTON, o, i, rect);
+ return paintMozillaGtkWidget(this, MOZ_GTK_BUTTON, o, i, rect);
}
void RenderThemeGtk::adjustMenuListStyle(CSSStyleSelector* selector, RenderStyle* style, WebCore::Element* e) const
@@ -294,12 +422,12 @@ void RenderThemeGtk::adjustMenuListStyle(CSSStyleSelector* selector, RenderStyle
style->resetPadding();
style->setHeight(Length(Auto));
style->setWhiteSpace(PRE);
- adjustMozStyle(style, MOZ_GTK_DROPDOWN);
+ adjustMozillaStyle(this, style, MOZ_GTK_DROPDOWN);
}
bool RenderThemeGtk::paintMenuList(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
{
- return paintMozWidget(this, MOZ_GTK_DROPDOWN, o, i, rect);
+ return paintMozillaGtkWidget(this, MOZ_GTK_DROPDOWN, o, i, rect);
}
void RenderThemeGtk::adjustTextFieldStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
@@ -308,12 +436,12 @@ void RenderThemeGtk::adjustTextFieldStyle(CSSStyleSelector* selector, RenderStyl
style->resetPadding();
style->setHeight(Length(Auto));
style->setWhiteSpace(PRE);
- adjustMozStyle(style, MOZ_GTK_ENTRY);
+ adjustMozillaStyle(this, style, MOZ_GTK_ENTRY);
}
bool RenderThemeGtk::paintTextField(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
{
- return paintMozWidget(this, MOZ_GTK_ENTRY, o, i, rect);
+ return paintMozillaGtkWidget(this, MOZ_GTK_ENTRY, o, i, rect);
}
bool RenderThemeGtk::paintTextArea(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
@@ -328,7 +456,7 @@ void RenderThemeGtk::adjustSearchFieldResultsButtonStyle(CSSStyleSelector* selec
bool RenderThemeGtk::paintSearchFieldResultsButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
{
- return paintMozWidget(this, MOZ_GTK_DROPDOWN_ARROW, o, i, rect);
+ return paintMozillaGtkWidget(this, MOZ_GTK_DROPDOWN_ARROW, o, i, rect);
}
void RenderThemeGtk::adjustSearchFieldResultsDecorationStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
@@ -344,7 +472,7 @@ void RenderThemeGtk::adjustSearchFieldResultsDecorationStyle(CSSStyleSelector* s
bool RenderThemeGtk::paintSearchFieldResultsDecoration(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
{
- return paintMozWidget(this, MOZ_GTK_CHECKMENUITEM, o, i, rect);
+ return paintMozillaGtkWidget(this, MOZ_GTK_CHECKMENUITEM, o, i, rect);
}
void RenderThemeGtk::adjustSearchFieldCancelButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
@@ -360,7 +488,7 @@ void RenderThemeGtk::adjustSearchFieldCancelButtonStyle(CSSStyleSelector* select
bool RenderThemeGtk::paintSearchFieldCancelButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
{
- return paintMozWidget(this, MOZ_GTK_CHECKMENUITEM, o, i, rect);
+ return paintMozillaGtkWidget(this, MOZ_GTK_CHECKMENUITEM, o, i, rect);
}
void RenderThemeGtk::adjustSearchFieldStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
@@ -373,6 +501,16 @@ bool RenderThemeGtk::paintSearchField(RenderObject* o, const RenderObject::Paint
return paintTextField(o, i, rect);
}
+void RenderThemeGtk::adjustSliderThumbSize(RenderObject* o) const
+{
+#if ENABLE(VIDEO)
+ if (o->style()->appearance() == MediaSliderThumbPart) {
+ o->style()->setWidth(Length(m_mediaSliderThumbWidth, Fixed));
+ o->style()->setHeight(Length(m_mediaSliderThumbHeight, Fixed));
+ }
+#endif
+}
+
Color RenderThemeGtk::platformActiveSelectionBackgroundColor() const
{
GtkWidget* widget = gtkEntry();
@@ -455,6 +593,7 @@ GtkContainer* RenderThemeGtk::gtkContainer() const
m_gtkWindow = gtk_window_new(GTK_WINDOW_POPUP);
m_gtkContainer = GTK_CONTAINER(gtk_fixed_new());
+ g_signal_connect(m_gtkWindow, "style-set", G_CALLBACK(gtkStyleSetCallback), const_cast<RenderThemeGtk*>(this));
gtk_container_add(GTK_CONTAINER(m_gtkWindow), GTK_WIDGET(m_gtkContainer));
gtk_widget_realize(m_gtkWindow);
@@ -487,4 +626,78 @@ GtkWidget* RenderThemeGtk::gtkTreeView() const
return m_gtkTreeView;
}
+void RenderThemeGtk::platformColorsDidChange()
+{
+#if ENABLE(VIDEO)
+ initMediaStyling(gtk_rc_get_style(GTK_WIDGET(gtkContainer())), true);
+#endif
+ RenderTheme::platformColorsDidChange();
+}
+
+#if ENABLE(VIDEO)
+String RenderThemeGtk::extraMediaControlsStyleSheet()
+{
+ return String(mediaControlsGtkUserAgentStyleSheet, sizeof(mediaControlsGtkUserAgentStyleSheet));
+}
+
+static inline bool paintMediaButton(GraphicsContext* context, const IntRect& r, Image* image, Color panelColor, int mediaIconSize)
+{
+ context->fillRect(FloatRect(r), panelColor, DeviceColorSpace);
+ context->drawImage(image, DeviceColorSpace,
+ IntRect(r.x() + (r.width() - mediaIconSize) / 2,
+ r.y() + (r.height() - mediaIconSize) / 2,
+ mediaIconSize, mediaIconSize));
+
+ return false;
+}
+
+bool RenderThemeGtk::paintMediaFullscreenButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
+{
+ return paintMediaButton(paintInfo.context, r, m_fullscreenButton.get(), m_panelColor, m_mediaIconSize);
+}
+
+bool RenderThemeGtk::paintMediaMuteButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
+{
+ HTMLMediaElement* mediaElement = getMediaElementFromRenderObject(o);
+ if (!mediaElement)
+ return false;
+
+ return paintMediaButton(paintInfo.context, r, mediaElement->muted() ? m_unmuteButton.get() : m_muteButton.get(), m_panelColor, m_mediaIconSize);
+}
+
+bool RenderThemeGtk::paintMediaPlayButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
+{
+ HTMLMediaElement* mediaElement = getMediaElementFromRenderObject(o);
+ if (!mediaElement)
+ return false;
+
+ return paintMediaButton(paintInfo.context, r, mediaElement->canPlay() ? m_playButton.get() : m_pauseButton.get(), m_panelColor, m_mediaIconSize);
+}
+
+bool RenderThemeGtk::paintMediaSeekBackButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
+{
+ return paintMediaButton(paintInfo.context, r, m_seekBackButton.get(), m_panelColor, m_mediaIconSize);
+}
+
+bool RenderThemeGtk::paintMediaSeekForwardButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
+{
+ return paintMediaButton(paintInfo.context, r, m_seekForwardButton.get(), m_panelColor, m_mediaIconSize);
+}
+
+bool RenderThemeGtk::paintMediaSliderTrack(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
+{
+ paintInfo.context->fillRect(FloatRect(r), m_panelColor, DeviceColorSpace);
+ paintInfo.context->fillRect(FloatRect(IntRect(r.x(), r.y() + (r.height() - m_mediaSliderHeight) / 2,
+ r.width(), m_mediaSliderHeight)), m_sliderColor, DeviceColorSpace);
+ return false;
+}
+
+bool RenderThemeGtk::paintMediaSliderThumb(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
+{
+ // Make the thumb nicer with rounded corners.
+ paintInfo.context->fillRoundedRect(r, IntSize(3, 3), IntSize(3, 3), IntSize(3, 3), IntSize(3, 3), m_sliderThumbColor, DeviceColorSpace);
+ return false;
+}
+#endif
+
}
diff --git a/WebCore/platform/gtk/RenderThemeGtk.h b/WebCore/platform/gtk/RenderThemeGtk.h
index 13daaa2..e9185a5 100644
--- a/WebCore/platform/gtk/RenderThemeGtk.h
+++ b/WebCore/platform/gtk/RenderThemeGtk.h
@@ -25,12 +25,19 @@
*
*/
-#ifndef RenderThemeGdk_h
-#define RenderThemeGdk_h
+#ifndef RenderThemeGtk_h
+#define RenderThemeGtk_h
+#include "GRefPtr.h"
#include "RenderTheme.h"
-#include <gtk/gtk.h>
+typedef struct _GtkWidget GtkWidget;
+typedef struct _GtkStyle GtkStyle;
+typedef struct _GtkContainer GtkContainer;
+typedef struct _GdkRectangle GdkRectangle;
+typedef struct _GdkDrawable GdkDrawable;
+typedef struct _GtkBorder GtkBorder;
+typedef struct _GtkThemeParts GtkThemeParts;
namespace WebCore {
@@ -73,9 +80,17 @@ public:
virtual double caretBlinkInterval() const;
+ virtual void platformColorsDidChange();
+
// System fonts.
virtual void systemFont(int propId, FontDescription&) const;
+#if ENABLE(VIDEO)
+ virtual String extraMediaControlsStyleSheet();
+#endif
+
+ GtkThemeParts* partsForDrawable(GdkDrawable*) const;
+
protected:
virtual bool paintCheckbox(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r);
virtual void setCheckboxSize(RenderStyle* style) const;
@@ -106,6 +121,18 @@ protected:
virtual void adjustSearchFieldCancelButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
virtual bool paintSearchFieldCancelButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
+ virtual void adjustSliderThumbSize(RenderObject*) const;
+
+#if ENABLE(VIDEO)
+ virtual void initMediaStyling(GtkStyle* style, bool force);
+ virtual bool paintMediaFullscreenButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
+ virtual bool paintMediaPlayButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
+ virtual bool paintMediaMuteButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
+ virtual bool paintMediaSeekBackButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
+ virtual bool paintMediaSeekForwardButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
+ virtual bool paintMediaSliderTrack(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
+ virtual bool paintMediaSliderThumb(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
+#endif
private:
/*
@@ -120,13 +147,32 @@ private:
*/
GtkContainer* gtkContainer() const;
-private:
mutable GtkWidget* m_gtkWindow;
mutable GtkContainer* m_gtkContainer;
mutable GtkWidget* m_gtkEntry;
mutable GtkWidget* m_gtkTreeView;
+
+ mutable Color m_panelColor;
+ mutable Color m_sliderColor;
+ mutable Color m_sliderThumbColor;
+
+ const int m_mediaIconSize;
+ const int m_mediaSliderHeight;
+ const int m_mediaSliderThumbWidth;
+ const int m_mediaSliderThumbHeight;
+
+ RefPtr<Image> m_fullscreenButton;
+ RefPtr<Image> m_muteButton;
+ RefPtr<Image> m_unmuteButton;
+ RefPtr<Image> m_playButton;
+ RefPtr<Image> m_pauseButton;
+ RefPtr<Image> m_seekBackButton;
+ RefPtr<Image> m_seekForwardButton;
+ Page* m_page;
+ GRefPtr<GHashTable> m_partsTable;
+
};
}
-#endif
+#endif // RenderThemeGtk_h
diff --git a/WebCore/platform/gtk/ScrollViewGtk.cpp b/WebCore/platform/gtk/ScrollViewGtk.cpp
index a1ed8c3..a7e7e15 100644
--- a/WebCore/platform/gtk/ScrollViewGtk.cpp
+++ b/WebCore/platform/gtk/ScrollViewGtk.cpp
@@ -101,7 +101,6 @@ void ScrollView::setGtkAdjustments(GtkAdjustment* hadj, GtkAdjustment* vadj)
/* reconsider having a scrollbar */
setHasVerticalScrollbar(false);
setHasHorizontalScrollbar(false);
- updateScrollbars(m_scrollOffset);
}
void ScrollView::platformAddChild(Widget* child)
diff --git a/WebCore/platform/gtk/ScrollbarGtk.cpp b/WebCore/platform/gtk/ScrollbarGtk.cpp
index d7f6d26..00c6ea0 100644
--- a/WebCore/platform/gtk/ScrollbarGtk.cpp
+++ b/WebCore/platform/gtk/ScrollbarGtk.cpp
@@ -23,7 +23,6 @@
#include "GraphicsContext.h"
#include "FrameView.h"
#include "ScrollbarTheme.h"
-#include "gtkdrawing.h"
#include <gtk/gtk.h>
diff --git a/WebCore/platform/gtk/ScrollbarThemeGtk.h b/WebCore/platform/gtk/ScrollbarThemeGtk.h
index 21ccb43..618da35 100644
--- a/WebCore/platform/gtk/ScrollbarThemeGtk.h
+++ b/WebCore/platform/gtk/ScrollbarThemeGtk.h
@@ -28,6 +28,11 @@
#include "ScrollbarTheme.h"
+typedef struct _GtkWidget GtkWidget;
+typedef struct _GtkStyle GtkStyle;
+typedef struct _GtkContainer GtkContainer;
+typedef struct _GtkBorder GtkBorder;
+
namespace WebCore {
class ScrollbarThemeGtk : public ScrollbarTheme {
diff --git a/WebCore/platform/gtk/gtk2drawing.c b/WebCore/platform/gtk/gtk2drawing.c
index 1f62c96..6a8af57 100644
--- a/WebCore/platform/gtk/gtk2drawing.c
+++ b/WebCore/platform/gtk/gtk2drawing.c
@@ -44,68 +44,29 @@
* Adapted from the gtkdrawing.c, and gtk+2.0 source.
*/
-#include <gtk/gtk.h>
#include <gdk/gdkprivate.h>
-#include <string.h>
#include "gtkdrawing.h"
#include "Assertions.h"
#include <math.h>
+#include <string.h>
#define XTHICKNESS(style) (style->xthickness)
#define YTHICKNESS(style) (style->ythickness)
#define WINDOW_IS_MAPPED(window) ((window) && GDK_IS_WINDOW(window) && gdk_window_is_visible(window))
-static GtkWidget* gProtoWindow;
-static GtkWidget* gProtoLayout;
-static GtkWidget* gButtonWidget;
-static GtkWidget* gToggleButtonWidget;
-static GtkWidget* gButtonArrowWidget;
-static GtkWidget* gCheckboxWidget;
-static GtkWidget* gRadiobuttonWidget;
-static GtkWidget* gHorizScrollbarWidget;
-static GtkWidget* gVertScrollbarWidget;
-static GtkWidget* gSpinWidget;
-static GtkWidget* gHScaleWidget;
-static GtkWidget* gVScaleWidget;
-static GtkWidget* gEntryWidget;
-static GtkWidget* gComboBoxWidget;
-static GtkWidget* gComboBoxButtonWidget;
-static GtkWidget* gComboBoxArrowWidget;
-static GtkWidget* gComboBoxSeparatorWidget;
-static GtkWidget* gComboBoxEntryWidget;
-static GtkWidget* gComboBoxEntryTextareaWidget;
-static GtkWidget* gComboBoxEntryButtonWidget;
-static GtkWidget* gComboBoxEntryArrowWidget;
-static GtkWidget* gHandleBoxWidget;
-static GtkWidget* gToolbarWidget;
-static GtkWidget* gFrameWidget;
-static GtkWidget* gStatusbarWidget;
-static GtkWidget* gProgressWidget;
-static GtkWidget* gTabWidget;
-static GtkWidget* gTooltipWidget;
-static GtkWidget* gMenuBarWidget;
-static GtkWidget* gMenuBarItemWidget;
-static GtkWidget* gMenuPopupWidget;
-static GtkWidget* gMenuItemWidget;
-static GtkWidget* gImageMenuItemWidget;
-static GtkWidget* gCheckMenuItemWidget;
-static GtkWidget* gTreeViewWidget;
-static GtkTreeViewColumn* gMiddleTreeViewColumn;
-static GtkWidget* gTreeHeaderCellWidget;
-static GtkWidget* gTreeHeaderSortArrowWidget;
-static GtkWidget* gExpanderWidget;
-static GtkWidget* gToolbarSeparatorWidget;
-static GtkWidget* gMenuSeparatorWidget;
-static GtkWidget* gHPanedWidget;
-static GtkWidget* gVPanedWidget;
-static GtkWidget* gScrolledWindowWidget;
-
+static GtkThemeParts *gParts = NULL;
static style_prop_t style_prop_func;
static gboolean have_arrow_scaling;
static gboolean is_initialized;
+void
+moz_gtk_use_theme_parts(GtkThemeParts* parts)
+{
+ gParts = parts;
+}
+
/* Because we have such an unconventional way of drawing widgets, signal to the GTK theme engine
that they are drawing for Mozilla instead of a conventional GTK app so they can do any specific
things they may want to do. */
@@ -125,10 +86,14 @@ moz_gtk_enable_style_props(style_prop_t styleGetProp)
static gint
ensure_window_widget()
{
- if (!gProtoWindow) {
- gProtoWindow = gtk_window_new(GTK_WINDOW_POPUP);
- gtk_widget_realize(gProtoWindow);
- moz_gtk_set_widget_name(gProtoWindow);
+ if (!gParts->protoWindow) {
+ gParts->protoWindow = gtk_window_new(GTK_WINDOW_POPUP);
+
+ if (gParts->colormap)
+ gtk_widget_set_colormap(gParts->protoWindow, gParts->colormap);
+
+ gtk_widget_realize(gParts->protoWindow);
+ moz_gtk_set_widget_name(gParts->protoWindow);
}
return MOZ_GTK_SUCCESS;
}
@@ -137,12 +102,12 @@ static gint
setup_widget_prototype(GtkWidget* widget)
{
ensure_window_widget();
- if (!gProtoLayout) {
- gProtoLayout = gtk_fixed_new();
- gtk_container_add(GTK_CONTAINER(gProtoWindow), gProtoLayout);
+ if (!gParts->protoLayout) {
+ gParts->protoLayout = gtk_fixed_new();
+ gtk_container_add(GTK_CONTAINER(gParts->protoWindow), gParts->protoLayout);
}
- gtk_container_add(GTK_CONTAINER(gProtoLayout), widget);
+ gtk_container_add(GTK_CONTAINER(gParts->protoLayout), widget);
gtk_widget_realize(widget);
g_object_set_data(G_OBJECT(widget), "transparent-bg-hint", GINT_TO_POINTER(TRUE));
return MOZ_GTK_SUCCESS;
@@ -151,9 +116,9 @@ setup_widget_prototype(GtkWidget* widget)
static gint
ensure_button_widget()
{
- if (!gButtonWidget) {
- gButtonWidget = gtk_button_new_with_label("M");
- setup_widget_prototype(gButtonWidget);
+ if (!gParts->buttonWidget) {
+ gParts->buttonWidget = gtk_button_new_with_label("M");
+ setup_widget_prototype(gParts->buttonWidget);
}
return MOZ_GTK_SUCCESS;
}
@@ -161,9 +126,9 @@ ensure_button_widget()
static gint
ensure_hpaned_widget()
{
- if (!gHPanedWidget) {
- gHPanedWidget = gtk_hpaned_new();
- setup_widget_prototype(gHPanedWidget);
+ if (!gParts->hpanedWidget) {
+ gParts->hpanedWidget = gtk_hpaned_new();
+ setup_widget_prototype(gParts->hpanedWidget);
}
return MOZ_GTK_SUCCESS;
}
@@ -171,9 +136,9 @@ ensure_hpaned_widget()
static gint
ensure_vpaned_widget()
{
- if (!gVPanedWidget) {
- gVPanedWidget = gtk_vpaned_new();
- setup_widget_prototype(gVPanedWidget);
+ if (!gParts->vpanedWidget) {
+ gParts->vpanedWidget = gtk_vpaned_new();
+ setup_widget_prototype(gParts->vpanedWidget);
}
return MOZ_GTK_SUCCESS;
}
@@ -181,11 +146,11 @@ ensure_vpaned_widget()
static gint
ensure_toggle_button_widget()
{
- if (!gToggleButtonWidget) {
- gToggleButtonWidget = gtk_toggle_button_new();
- setup_widget_prototype(gToggleButtonWidget);
+ if (!gParts->toggleButtonWidget) {
+ gParts->toggleButtonWidget = gtk_toggle_button_new();
+ setup_widget_prototype(gParts->toggleButtonWidget);
/* toggle button must be set active to get the right style on hover. */
- GTK_TOGGLE_BUTTON(gToggleButtonWidget)->active = TRUE;
+ GTK_TOGGLE_BUTTON(gParts->toggleButtonWidget)->active = TRUE;
}
return MOZ_GTK_SUCCESS;
}
@@ -193,12 +158,12 @@ ensure_toggle_button_widget()
static gint
ensure_button_arrow_widget()
{
- if (!gButtonArrowWidget) {
+ if (!gParts->buttonArrowWidget) {
ensure_toggle_button_widget();
- gButtonArrowWidget = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_OUT);
- gtk_container_add(GTK_CONTAINER(gToggleButtonWidget), gButtonArrowWidget);
- gtk_widget_realize(gButtonArrowWidget);
+ gParts->buttonArrowWidget = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_OUT);
+ gtk_container_add(GTK_CONTAINER(gParts->toggleButtonWidget), gParts->buttonArrowWidget);
+ gtk_widget_realize(gParts->buttonArrowWidget);
}
return MOZ_GTK_SUCCESS;
}
@@ -206,9 +171,9 @@ ensure_button_arrow_widget()
static gint
ensure_checkbox_widget()
{
- if (!gCheckboxWidget) {
- gCheckboxWidget = gtk_check_button_new_with_label("M");
- setup_widget_prototype(gCheckboxWidget);
+ if (!gParts->checkboxWidget) {
+ gParts->checkboxWidget = gtk_check_button_new_with_label("M");
+ setup_widget_prototype(gParts->checkboxWidget);
}
return MOZ_GTK_SUCCESS;
}
@@ -216,9 +181,9 @@ ensure_checkbox_widget()
static gint
ensure_radiobutton_widget()
{
- if (!gRadiobuttonWidget) {
- gRadiobuttonWidget = gtk_radio_button_new_with_label(NULL, "M");
- setup_widget_prototype(gRadiobuttonWidget);
+ if (!gParts->radiobuttonWidget) {
+ gParts->radiobuttonWidget = gtk_radio_button_new_with_label(NULL, "M");
+ setup_widget_prototype(gParts->radiobuttonWidget);
}
return MOZ_GTK_SUCCESS;
}
@@ -226,13 +191,13 @@ ensure_radiobutton_widget()
static gint
ensure_scrollbar_widget()
{
- if (!gVertScrollbarWidget) {
- gVertScrollbarWidget = gtk_vscrollbar_new(NULL);
- setup_widget_prototype(gVertScrollbarWidget);
+ if (!gParts->vertScrollbarWidget) {
+ gParts->vertScrollbarWidget = gtk_vscrollbar_new(NULL);
+ setup_widget_prototype(gParts->vertScrollbarWidget);
}
- if (!gHorizScrollbarWidget) {
- gHorizScrollbarWidget = gtk_hscrollbar_new(NULL);
- setup_widget_prototype(gHorizScrollbarWidget);
+ if (!gParts->horizScrollbarWidget) {
+ gParts->horizScrollbarWidget = gtk_hscrollbar_new(NULL);
+ setup_widget_prototype(gParts->horizScrollbarWidget);
}
return MOZ_GTK_SUCCESS;
}
@@ -240,9 +205,9 @@ ensure_scrollbar_widget()
static gint
ensure_spin_widget()
{
- if (!gSpinWidget) {
- gSpinWidget = gtk_spin_button_new(NULL, 1, 0);
- setup_widget_prototype(gSpinWidget);
+ if (!gParts->spinWidget) {
+ gParts->spinWidget = gtk_spin_button_new(NULL, 1, 0);
+ setup_widget_prototype(gParts->spinWidget);
}
return MOZ_GTK_SUCCESS;
}
@@ -250,13 +215,13 @@ ensure_spin_widget()
static gint
ensure_scale_widget()
{
- if (!gHScaleWidget) {
- gHScaleWidget = gtk_hscale_new(NULL);
- setup_widget_prototype(gHScaleWidget);
+ if (!gParts->hScaleWidget) {
+ gParts->hScaleWidget = gtk_hscale_new(NULL);
+ setup_widget_prototype(gParts->hScaleWidget);
}
- if (!gVScaleWidget) {
- gVScaleWidget = gtk_vscale_new(NULL);
- setup_widget_prototype(gVScaleWidget);
+ if (!gParts->vScaleWidget) {
+ gParts->vScaleWidget = gtk_vscale_new(NULL);
+ setup_widget_prototype(gParts->vScaleWidget);
}
return MOZ_GTK_SUCCESS;
}
@@ -264,9 +229,9 @@ ensure_scale_widget()
static gint
ensure_entry_widget()
{
- if (!gEntryWidget) {
- gEntryWidget = gtk_entry_new();
- setup_widget_prototype(gEntryWidget);
+ if (!gParts->entryWidget) {
+ gParts->entryWidget = gtk_entry_new();
+ setup_widget_prototype(gParts->entryWidget);
}
return MOZ_GTK_SUCCESS;
}
@@ -279,15 +244,15 @@ ensure_entry_widget()
* g_object_add_weak_pointer().
* Note that if we don't find the inner widgets (which shouldn't happen), we
* fallback to use generic "non-inner" widgets, and they don't need that kind
- * of weak pointer since they are explicit children of gProtoWindow and as
+ * of weak pointer since they are explicit children of gParts->protoWindow and as
* such GTK holds a strong reference to them. */
static void
moz_gtk_get_combo_box_inner_button(GtkWidget *widget, gpointer client_data)
{
if (GTK_IS_TOGGLE_BUTTON(widget)) {
- gComboBoxButtonWidget = widget;
+ gParts->comboBoxButtonWidget = widget;
g_object_add_weak_pointer(G_OBJECT(widget),
- (gpointer) &gComboBoxButtonWidget);
+ (gpointer) &gParts->comboBoxButtonWidget);
gtk_widget_realize(widget);
g_object_set_data(G_OBJECT(widget), "transparent-bg-hint", GINT_TO_POINTER(TRUE));
}
@@ -298,13 +263,13 @@ moz_gtk_get_combo_box_button_inner_widgets(GtkWidget *widget,
gpointer client_data)
{
if (GTK_IS_SEPARATOR(widget)) {
- gComboBoxSeparatorWidget = widget;
+ gParts->comboBoxSeparatorWidget = widget;
g_object_add_weak_pointer(G_OBJECT(widget),
- (gpointer) &gComboBoxSeparatorWidget);
+ (gpointer) &gParts->comboBoxSeparatorWidget);
} else if (GTK_IS_ARROW(widget)) {
- gComboBoxArrowWidget = widget;
+ gParts->comboBoxArrowWidget = widget;
g_object_add_weak_pointer(G_OBJECT(widget),
- (gpointer) &gComboBoxArrowWidget);
+ (gpointer) &gParts->comboBoxArrowWidget);
} else
return;
gtk_widget_realize(widget);
@@ -316,23 +281,23 @@ ensure_combo_box_widgets()
{
GtkWidget* buttonChild;
- if (gComboBoxButtonWidget && gComboBoxArrowWidget)
+ if (gParts->comboBoxButtonWidget && gParts->comboBoxArrowWidget)
return MOZ_GTK_SUCCESS;
/* Create a ComboBox if needed */
- if (!gComboBoxWidget) {
- gComboBoxWidget = gtk_combo_box_new();
- setup_widget_prototype(gComboBoxWidget);
+ if (!gParts->comboBoxWidget) {
+ gParts->comboBoxWidget = gtk_combo_box_new();
+ setup_widget_prototype(gParts->comboBoxWidget);
}
/* Get its inner Button */
- gtk_container_forall(GTK_CONTAINER(gComboBoxWidget),
+ gtk_container_forall(GTK_CONTAINER(gParts->comboBoxWidget),
moz_gtk_get_combo_box_inner_button,
NULL);
- if (gComboBoxButtonWidget) {
+ if (gParts->comboBoxButtonWidget) {
/* Get the widgets inside the Button */
- buttonChild = GTK_BIN(gComboBoxButtonWidget)->child;
+ buttonChild = GTK_BIN(gParts->comboBoxButtonWidget)->child;
if (GTK_IS_HBOX(buttonChild)) {
/* appears-as-list = FALSE, cell-view = TRUE; the button
* contains an hbox. This hbox is there because the ComboBox
@@ -344,11 +309,11 @@ ensure_combo_box_widgets()
} else if(GTK_IS_ARROW(buttonChild)) {
/* appears-as-list = TRUE, or cell-view = FALSE;
* the button only contains an arrow */
- gComboBoxArrowWidget = buttonChild;
+ gParts->comboBoxArrowWidget = buttonChild;
g_object_add_weak_pointer(G_OBJECT(buttonChild), (gpointer)
- &gComboBoxArrowWidget);
- gtk_widget_realize(gComboBoxArrowWidget);
- g_object_set_data(G_OBJECT(gComboBoxArrowWidget),
+ &gParts->comboBoxArrowWidget);
+ gtk_widget_realize(gParts->comboBoxArrowWidget);
+ g_object_set_data(G_OBJECT(gParts->comboBoxArrowWidget),
"transparent-bg-hint", GINT_TO_POINTER(TRUE));
}
} else {
@@ -356,18 +321,18 @@ ensure_combo_box_widgets()
* use a generic toggle button as last resort fallback to avoid
* crashing. */
ensure_toggle_button_widget();
- gComboBoxButtonWidget = gToggleButtonWidget;
+ gParts->comboBoxButtonWidget = gParts->toggleButtonWidget;
}
- if (!gComboBoxArrowWidget) {
+ if (!gParts->comboBoxArrowWidget) {
/* Shouldn't be reached with current internal gtk implementation;
- * we gButtonArrowWidget as last resort fallback to avoid
+ * we gParts->buttonArrowWidget as last resort fallback to avoid
* crashing. */
ensure_button_arrow_widget();
- gComboBoxArrowWidget = gButtonArrowWidget;
+ gParts->comboBoxArrowWidget = gParts->buttonArrowWidget;
}
- /* We don't test the validity of gComboBoxSeparatorWidget since there
+ /* We don't test the validity of gParts->comboBoxSeparatorWidget since there
* is none when "appears-as-list" = TRUE or "cell-view" = FALSE; if it
* is invalid we just won't paint it. */
@@ -382,20 +347,20 @@ ensure_combo_box_widgets()
* g_object_add_weak_pointer().
* Note that if we don't find the inner widgets (which shouldn't happen), we
* fallback to use generic "non-inner" widgets, and they don't need that kind
- * of weak pointer since they are explicit children of gProtoWindow and as
+ * of weak pointer since they are explicit children of gParts->protoWindow and as
* such GTK holds a strong reference to them. */
static void
moz_gtk_get_combo_box_entry_inner_widgets(GtkWidget *widget,
gpointer client_data)
{
if (GTK_IS_TOGGLE_BUTTON(widget)) {
- gComboBoxEntryButtonWidget = widget;
+ gParts->comboBoxEntryButtonWidget = widget;
g_object_add_weak_pointer(G_OBJECT(widget),
- (gpointer) &gComboBoxEntryButtonWidget);
+ (gpointer) &gParts->comboBoxEntryButtonWidget);
} else if (GTK_IS_ENTRY(widget)) {
- gComboBoxEntryTextareaWidget = widget;
+ gParts->comboBoxEntryTextareaWidget = widget;
g_object_add_weak_pointer(G_OBJECT(widget),
- (gpointer) &gComboBoxEntryTextareaWidget);
+ (gpointer) &gParts->comboBoxEntryTextareaWidget);
} else
return;
gtk_widget_realize(widget);
@@ -406,9 +371,9 @@ static void
moz_gtk_get_combo_box_entry_arrow(GtkWidget *widget, gpointer client_data)
{
if (GTK_IS_ARROW(widget)) {
- gComboBoxEntryArrowWidget = widget;
+ gParts->comboBoxEntryArrowWidget = widget;
g_object_add_weak_pointer(G_OBJECT(widget),
- (gpointer) &gComboBoxEntryArrowWidget);
+ (gpointer) &gParts->comboBoxEntryArrowWidget);
gtk_widget_realize(widget);
g_object_set_data(G_OBJECT(widget), "transparent-bg-hint", GINT_TO_POINTER(TRUE));
}
@@ -419,30 +384,30 @@ ensure_combo_box_entry_widgets()
{
GtkWidget* buttonChild;
- if (gComboBoxEntryTextareaWidget &&
- gComboBoxEntryButtonWidget &&
- gComboBoxEntryArrowWidget)
+ if (gParts->comboBoxEntryTextareaWidget &&
+ gParts->comboBoxEntryButtonWidget &&
+ gParts->comboBoxEntryArrowWidget)
return MOZ_GTK_SUCCESS;
/* Create a ComboBoxEntry if needed */
- if (!gComboBoxEntryWidget) {
- gComboBoxEntryWidget = gtk_combo_box_entry_new();
- setup_widget_prototype(gComboBoxEntryWidget);
+ if (!gParts->comboBoxEntryWidget) {
+ gParts->comboBoxEntryWidget = gtk_combo_box_entry_new();
+ setup_widget_prototype(gParts->comboBoxEntryWidget);
}
/* Get its inner Entry and Button */
- gtk_container_forall(GTK_CONTAINER(gComboBoxEntryWidget),
+ gtk_container_forall(GTK_CONTAINER(gParts->comboBoxEntryWidget),
moz_gtk_get_combo_box_entry_inner_widgets,
NULL);
- if (!gComboBoxEntryTextareaWidget) {
+ if (!gParts->comboBoxEntryTextareaWidget) {
ensure_entry_widget();
- gComboBoxEntryTextareaWidget = gEntryWidget;
+ gParts->comboBoxEntryTextareaWidget = gParts->entryWidget;
}
- if (gComboBoxEntryButtonWidget) {
+ if (gParts->comboBoxEntryButtonWidget) {
/* Get the Arrow inside the Button */
- buttonChild = GTK_BIN(gComboBoxEntryButtonWidget)->child;
+ buttonChild = GTK_BIN(gParts->comboBoxEntryButtonWidget)->child;
if (GTK_IS_HBOX(buttonChild)) {
/* appears-as-list = FALSE, cell-view = TRUE; the button
* contains an hbox. This hbox is there because ComboBoxEntry
@@ -457,11 +422,11 @@ ensure_combo_box_entry_widgets()
} else if(GTK_IS_ARROW(buttonChild)) {
/* appears-as-list = TRUE, or cell-view = FALSE;
* the button only contains an arrow */
- gComboBoxEntryArrowWidget = buttonChild;
+ gParts->comboBoxEntryArrowWidget = buttonChild;
g_object_add_weak_pointer(G_OBJECT(buttonChild), (gpointer)
- &gComboBoxEntryArrowWidget);
- gtk_widget_realize(gComboBoxEntryArrowWidget);
- g_object_set_data(G_OBJECT(gComboBoxEntryArrowWidget),
+ &gParts->comboBoxEntryArrowWidget);
+ gtk_widget_realize(gParts->comboBoxEntryArrowWidget);
+ g_object_set_data(G_OBJECT(gParts->comboBoxEntryArrowWidget),
"transparent-bg-hint", GINT_TO_POINTER(TRUE));
}
} else {
@@ -469,15 +434,15 @@ ensure_combo_box_entry_widgets()
* we use a generic toggle button as last resort fallback to avoid
* crashing. */
ensure_toggle_button_widget();
- gComboBoxEntryButtonWidget = gToggleButtonWidget;
+ gParts->comboBoxEntryButtonWidget = gParts->toggleButtonWidget;
}
- if (!gComboBoxEntryArrowWidget) {
+ if (!gParts->comboBoxEntryArrowWidget) {
/* Shouldn't be reached with current internal gtk implementation;
- * we gButtonArrowWidget as last resort fallback to avoid
+ * we gParts->buttonArrowWidget as last resort fallback to avoid
* crashing. */
ensure_button_arrow_widget();
- gComboBoxEntryArrowWidget = gButtonArrowWidget;
+ gParts->comboBoxEntryArrowWidget = gParts->buttonArrowWidget;
}
return MOZ_GTK_SUCCESS;
@@ -487,9 +452,9 @@ ensure_combo_box_entry_widgets()
static gint
ensure_handlebox_widget()
{
- if (!gHandleBoxWidget) {
- gHandleBoxWidget = gtk_handle_box_new();
- setup_widget_prototype(gHandleBoxWidget);
+ if (!gParts->handleBoxWidget) {
+ gParts->handleBoxWidget = gtk_handle_box_new();
+ setup_widget_prototype(gParts->handleBoxWidget);
}
return MOZ_GTK_SUCCESS;
}
@@ -497,12 +462,12 @@ ensure_handlebox_widget()
static gint
ensure_toolbar_widget()
{
- if (!gToolbarWidget) {
+ if (!gParts->toolbarWidget) {
ensure_handlebox_widget();
- gToolbarWidget = gtk_toolbar_new();
- gtk_container_add(GTK_CONTAINER(gHandleBoxWidget), gToolbarWidget);
- gtk_widget_realize(gToolbarWidget);
- g_object_set_data(G_OBJECT(gToolbarWidget), "transparent-bg-hint", GINT_TO_POINTER(TRUE));
+ gParts->toolbarWidget = gtk_toolbar_new();
+ gtk_container_add(GTK_CONTAINER(gParts->handleBoxWidget), gParts->toolbarWidget);
+ gtk_widget_realize(gParts->toolbarWidget);
+ g_object_set_data(G_OBJECT(gParts->toolbarWidget), "transparent-bg-hint", GINT_TO_POINTER(TRUE));
}
return MOZ_GTK_SUCCESS;
}
@@ -510,10 +475,10 @@ ensure_toolbar_widget()
static gint
ensure_toolbar_separator_widget()
{
- if (!gToolbarSeparatorWidget) {
+ if (!gParts->toolbarSeparatorWidget) {
ensure_toolbar_widget();
- gToolbarSeparatorWidget = GTK_WIDGET(gtk_separator_tool_item_new());
- setup_widget_prototype(gToolbarSeparatorWidget);
+ gParts->toolbarSeparatorWidget = GTK_WIDGET(gtk_separator_tool_item_new());
+ setup_widget_prototype(gParts->toolbarSeparatorWidget);
}
return MOZ_GTK_SUCCESS;
}
@@ -521,10 +486,10 @@ ensure_toolbar_separator_widget()
static gint
ensure_tooltip_widget()
{
- if (!gTooltipWidget) {
- gTooltipWidget = gtk_window_new(GTK_WINDOW_POPUP);
- gtk_widget_realize(gTooltipWidget);
- moz_gtk_set_widget_name(gTooltipWidget);
+ if (!gParts->tooltipWidget) {
+ gParts->tooltipWidget = gtk_window_new(GTK_WINDOW_POPUP);
+ gtk_widget_realize(gParts->tooltipWidget);
+ moz_gtk_set_widget_name(gParts->tooltipWidget);
}
return MOZ_GTK_SUCCESS;
}
@@ -532,9 +497,9 @@ ensure_tooltip_widget()
static gint
ensure_tab_widget()
{
- if (!gTabWidget) {
- gTabWidget = gtk_notebook_new();
- setup_widget_prototype(gTabWidget);
+ if (!gParts->tabWidget) {
+ gParts->tabWidget = gtk_notebook_new();
+ setup_widget_prototype(gParts->tabWidget);
}
return MOZ_GTK_SUCCESS;
}
@@ -542,9 +507,9 @@ ensure_tab_widget()
static gint
ensure_progress_widget()
{
- if (!gProgressWidget) {
- gProgressWidget = gtk_progress_bar_new();
- setup_widget_prototype(gProgressWidget);
+ if (!gParts->progresWidget) {
+ gParts->progresWidget = gtk_progress_bar_new();
+ setup_widget_prototype(gParts->progresWidget);
}
return MOZ_GTK_SUCCESS;
}
@@ -552,9 +517,9 @@ ensure_progress_widget()
static gint
ensure_statusbar_widget()
{
- if (!gStatusbarWidget) {
- gStatusbarWidget = gtk_statusbar_new();
- setup_widget_prototype(gStatusbarWidget);
+ if (!gParts->statusbarWidget) {
+ gParts->statusbarWidget = gtk_statusbar_new();
+ setup_widget_prototype(gParts->statusbarWidget);
}
return MOZ_GTK_SUCCESS;
}
@@ -562,11 +527,11 @@ ensure_statusbar_widget()
static gint
ensure_frame_widget()
{
- if (!gFrameWidget) {
+ if (!gParts->frameWidget) {
ensure_statusbar_widget();
- gFrameWidget = gtk_frame_new(NULL);
- gtk_container_add(GTK_CONTAINER(gStatusbarWidget), gFrameWidget);
- gtk_widget_realize(gFrameWidget);
+ gParts->frameWidget = gtk_frame_new(NULL);
+ gtk_container_add(GTK_CONTAINER(gParts->statusbarWidget), gParts->frameWidget);
+ gtk_widget_realize(gParts->frameWidget);
}
return MOZ_GTK_SUCCESS;
}
@@ -574,9 +539,9 @@ ensure_frame_widget()
static gint
ensure_menu_bar_widget()
{
- if (!gMenuBarWidget) {
- gMenuBarWidget = gtk_menu_bar_new();
- setup_widget_prototype(gMenuBarWidget);
+ if (!gParts->menuBarWidget) {
+ gParts->menuBarWidget = gtk_menu_bar_new();
+ setup_widget_prototype(gParts->menuBarWidget);
}
return MOZ_GTK_SUCCESS;
}
@@ -584,13 +549,13 @@ ensure_menu_bar_widget()
static gint
ensure_menu_bar_item_widget()
{
- if (!gMenuBarItemWidget) {
+ if (!gParts->menuBarItemWidget) {
ensure_menu_bar_widget();
- gMenuBarItemWidget = gtk_menu_item_new();
- gtk_menu_shell_append(GTK_MENU_SHELL(gMenuBarWidget),
- gMenuBarItemWidget);
- gtk_widget_realize(gMenuBarItemWidget);
- g_object_set_data(G_OBJECT(gMenuBarItemWidget),
+ gParts->menuBarItemWidget = gtk_menu_item_new();
+ gtk_menu_shell_append(GTK_MENU_SHELL(gParts->menuBarWidget),
+ gParts->menuBarItemWidget);
+ gtk_widget_realize(gParts->menuBarItemWidget);
+ g_object_set_data(G_OBJECT(gParts->menuBarItemWidget),
"transparent-bg-hint", GINT_TO_POINTER(TRUE));
}
return MOZ_GTK_SUCCESS;
@@ -599,13 +564,13 @@ ensure_menu_bar_item_widget()
static gint
ensure_menu_popup_widget()
{
- if (!gMenuPopupWidget) {
+ if (!gParts->menuPopupWidget) {
ensure_menu_bar_item_widget();
- gMenuPopupWidget = gtk_menu_new();
- gtk_menu_item_set_submenu(GTK_MENU_ITEM(gMenuBarItemWidget),
- gMenuPopupWidget);
- gtk_widget_realize(gMenuPopupWidget);
- g_object_set_data(G_OBJECT(gMenuPopupWidget),
+ gParts->menuPopupWidget = gtk_menu_new();
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(gParts->menuBarItemWidget),
+ gParts->menuPopupWidget);
+ gtk_widget_realize(gParts->menuPopupWidget);
+ g_object_set_data(G_OBJECT(gParts->menuPopupWidget),
"transparent-bg-hint", GINT_TO_POINTER(TRUE));
}
return MOZ_GTK_SUCCESS;
@@ -614,13 +579,13 @@ ensure_menu_popup_widget()
static gint
ensure_menu_item_widget()
{
- if (!gMenuItemWidget) {
+ if (!gParts->menuItemWidget) {
ensure_menu_popup_widget();
- gMenuItemWidget = gtk_menu_item_new_with_label("M");
- gtk_menu_shell_append(GTK_MENU_SHELL(gMenuPopupWidget),
- gMenuItemWidget);
- gtk_widget_realize(gMenuItemWidget);
- g_object_set_data(G_OBJECT(gMenuItemWidget),
+ gParts->menuItemWidget = gtk_menu_item_new_with_label("M");
+ gtk_menu_shell_append(GTK_MENU_SHELL(gParts->menuPopupWidget),
+ gParts->menuItemWidget);
+ gtk_widget_realize(gParts->menuItemWidget);
+ g_object_set_data(G_OBJECT(gParts->menuItemWidget),
"transparent-bg-hint", GINT_TO_POINTER(TRUE));
}
return MOZ_GTK_SUCCESS;
@@ -629,13 +594,13 @@ ensure_menu_item_widget()
static gint
ensure_image_menu_item_widget()
{
- if (!gImageMenuItemWidget) {
+ if (!gParts->imageMenuItemWidget) {
ensure_menu_popup_widget();
- gImageMenuItemWidget = gtk_image_menu_item_new();
- gtk_menu_shell_append(GTK_MENU_SHELL(gMenuPopupWidget),
- gImageMenuItemWidget);
- gtk_widget_realize(gImageMenuItemWidget);
- g_object_set_data(G_OBJECT(gImageMenuItemWidget),
+ gParts->imageMenuItemWidget = gtk_image_menu_item_new();
+ gtk_menu_shell_append(GTK_MENU_SHELL(gParts->menuPopupWidget),
+ gParts->imageMenuItemWidget);
+ gtk_widget_realize(gParts->imageMenuItemWidget);
+ g_object_set_data(G_OBJECT(gParts->imageMenuItemWidget),
"transparent-bg-hint", GINT_TO_POINTER(TRUE));
}
return MOZ_GTK_SUCCESS;
@@ -644,13 +609,13 @@ ensure_image_menu_item_widget()
static gint
ensure_menu_separator_widget()
{
- if (!gMenuSeparatorWidget) {
+ if (!gParts->menuSeparatorWidget) {
ensure_menu_popup_widget();
- gMenuSeparatorWidget = gtk_separator_menu_item_new();
- gtk_menu_shell_append(GTK_MENU_SHELL(gMenuPopupWidget),
- gMenuSeparatorWidget);
- gtk_widget_realize(gMenuSeparatorWidget);
- g_object_set_data(G_OBJECT(gMenuSeparatorWidget),
+ gParts->menuSeparatorWidget = gtk_separator_menu_item_new();
+ gtk_menu_shell_append(GTK_MENU_SHELL(gParts->menuPopupWidget),
+ gParts->menuSeparatorWidget);
+ gtk_widget_realize(gParts->menuSeparatorWidget);
+ g_object_set_data(G_OBJECT(gParts->menuSeparatorWidget),
"transparent-bg-hint", GINT_TO_POINTER(TRUE));
}
return MOZ_GTK_SUCCESS;
@@ -659,13 +624,13 @@ ensure_menu_separator_widget()
static gint
ensure_check_menu_item_widget()
{
- if (!gCheckMenuItemWidget) {
+ if (!gParts->checkMenuItemWidget) {
ensure_menu_popup_widget();
- gCheckMenuItemWidget = gtk_check_menu_item_new_with_label("M");
- gtk_menu_shell_append(GTK_MENU_SHELL(gMenuPopupWidget),
- gCheckMenuItemWidget);
- gtk_widget_realize(gCheckMenuItemWidget);
- g_object_set_data(G_OBJECT(gCheckMenuItemWidget),
+ gParts->checkMenuItemWidget = gtk_check_menu_item_new_with_label("M");
+ gtk_menu_shell_append(GTK_MENU_SHELL(gParts->menuPopupWidget),
+ gParts->checkMenuItemWidget);
+ gtk_widget_realize(gParts->checkMenuItemWidget);
+ g_object_set_data(G_OBJECT(gParts->checkMenuItemWidget),
"transparent-bg-hint", GINT_TO_POINTER(TRUE));
}
return MOZ_GTK_SUCCESS;
@@ -674,9 +639,9 @@ ensure_check_menu_item_widget()
static gint
ensure_tree_view_widget()
{
- if (!gTreeViewWidget) {
- gTreeViewWidget = gtk_tree_view_new();
- setup_widget_prototype(gTreeViewWidget);
+ if (!gParts->treeViewWidget) {
+ gParts->treeViewWidget = gtk_tree_view_new();
+ setup_widget_prototype(gParts->treeViewWidget);
}
return MOZ_GTK_SUCCESS;
}
@@ -684,7 +649,7 @@ ensure_tree_view_widget()
static gint
ensure_tree_header_cell_widget()
{
- if(!gTreeHeaderCellWidget) {
+ if(!gParts->treeHeaderCellWidget) {
/*
* Some GTK engines paint the first and last cell
* of a TreeView header with a highlight.
@@ -706,23 +671,23 @@ ensure_tree_header_cell_widget()
/* Create and append our three columns */
firstTreeViewColumn = gtk_tree_view_column_new();
gtk_tree_view_column_set_title(firstTreeViewColumn, "M");
- gtk_tree_view_append_column(GTK_TREE_VIEW(gTreeViewWidget), firstTreeViewColumn);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(gParts->treeViewWidget), firstTreeViewColumn);
- gMiddleTreeViewColumn = gtk_tree_view_column_new();
- gtk_tree_view_column_set_title(gMiddleTreeViewColumn, "M");
- gtk_tree_view_append_column(GTK_TREE_VIEW(gTreeViewWidget),
- gMiddleTreeViewColumn);
+ gParts->middleTreeViewColumn = gtk_tree_view_column_new();
+ gtk_tree_view_column_set_title(gParts->middleTreeViewColumn, "M");
+ gtk_tree_view_append_column(GTK_TREE_VIEW(gParts->treeViewWidget),
+ gParts->middleTreeViewColumn);
lastTreeViewColumn = gtk_tree_view_column_new();
gtk_tree_view_column_set_title(lastTreeViewColumn, "M");
- gtk_tree_view_append_column(GTK_TREE_VIEW(gTreeViewWidget), lastTreeViewColumn);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(gParts->treeViewWidget), lastTreeViewColumn);
/* Use the middle column's header for our button */
- gTreeHeaderCellWidget = gMiddleTreeViewColumn->button;
- gTreeHeaderSortArrowWidget = gMiddleTreeViewColumn->arrow;
- g_object_set_data(G_OBJECT(gTreeHeaderCellWidget),
+ gParts->treeHeaderCellWidget = gParts->middleTreeViewColumn->button;
+ gParts->treeHeaderSortArrowWidget = gParts->middleTreeViewColumn->arrow;
+ g_object_set_data(G_OBJECT(gParts->treeHeaderCellWidget),
"transparent-bg-hint", GINT_TO_POINTER(TRUE));
- g_object_set_data(G_OBJECT(gTreeHeaderSortArrowWidget),
+ g_object_set_data(G_OBJECT(gParts->treeHeaderSortArrowWidget),
"transparent-bg-hint", GINT_TO_POINTER(TRUE));
}
return MOZ_GTK_SUCCESS;
@@ -731,9 +696,9 @@ ensure_tree_header_cell_widget()
static gint
ensure_expander_widget()
{
- if (!gExpanderWidget) {
- gExpanderWidget = gtk_expander_new("M");
- setup_widget_prototype(gExpanderWidget);
+ if (!gParts->expanderWidget) {
+ gParts->expanderWidget = gtk_expander_new("M");
+ setup_widget_prototype(gParts->expanderWidget);
}
return MOZ_GTK_SUCCESS;
}
@@ -741,9 +706,9 @@ ensure_expander_widget()
static gint
ensure_scrolled_window_widget()
{
- if (!gScrolledWindowWidget) {
- gScrolledWindowWidget = gtk_scrolled_window_new(NULL, NULL);
- setup_widget_prototype(gScrolledWindowWidget);
+ if (!gParts->scrolledWindowWidget) {
+ gParts->scrolledWindowWidget = gtk_scrolled_window_new(NULL, NULL);
+ setup_widget_prototype(gParts->scrolledWindowWidget);
}
return MOZ_GTK_SUCCESS;
}
@@ -898,7 +863,7 @@ moz_gtk_checkbox_get_metrics(gint* indicator_size, gint* indicator_spacing)
{
ensure_checkbox_widget();
- gtk_widget_style_get (gCheckboxWidget,
+ gtk_widget_style_get (gParts->checkboxWidget,
"indicator_size", indicator_size,
"indicator_spacing", indicator_spacing,
NULL);
@@ -911,7 +876,7 @@ moz_gtk_radio_get_metrics(gint* indicator_size, gint* indicator_spacing)
{
ensure_radiobutton_widget();
- gtk_widget_style_get (gRadiobuttonWidget,
+ gtk_widget_style_get (gParts->radiobuttonWidget,
"indicator_size", indicator_size,
"indicator_spacing", indicator_spacing,
NULL);
@@ -937,10 +902,10 @@ moz_gtk_splitter_get_metrics(gint orientation, gint* size)
{
if (orientation == GTK_ORIENTATION_HORIZONTAL) {
ensure_hpaned_widget();
- gtk_widget_style_get(gHPanedWidget, "handle_size", size, NULL);
+ gtk_widget_style_get(gParts->hpanedWidget, "handle_size", size, NULL);
} else {
ensure_vpaned_widget();
- gtk_widget_style_get(gVPanedWidget, "handle_size", size, NULL);
+ gtk_widget_style_get(gParts->vpanedWidget, "handle_size", size, NULL);
}
return MOZ_GTK_SUCCESS;
}
@@ -979,10 +944,10 @@ moz_gtk_toggle_paint(GdkDrawable* drawable, GdkRectangle* rect,
if (isradio) {
moz_gtk_radio_get_metrics(&indicator_size, &indicator_spacing);
- w = gRadiobuttonWidget;
+ w = gParts->radiobuttonWidget;
} else {
moz_gtk_checkbox_get_metrics(&indicator_size, &indicator_spacing);
- w = gCheckboxWidget;
+ w = gParts->checkboxWidget;
}
// "GetMinimumWidgetSize was ignored"
@@ -1014,11 +979,11 @@ moz_gtk_toggle_paint(GdkDrawable* drawable, GdkRectangle* rect,
if (isradio) {
gtk_paint_option(style, drawable, state_type, shadow_type, cliprect,
- gRadiobuttonWidget, "radiobutton", x, y,
+ gParts->radiobuttonWidget, "radiobutton", x, y,
width, height);
if (state->focused) {
gtk_paint_focus(style, drawable, GTK_STATE_ACTIVE, cliprect,
- gRadiobuttonWidget, "radiobutton", focus_x, focus_y,
+ gParts->radiobuttonWidget, "radiobutton", focus_x, focus_y,
focus_width, focus_height);
}
}
@@ -1028,17 +993,17 @@ moz_gtk_toggle_paint(GdkDrawable* drawable, GdkRectangle* rect,
* must also be changed for the state to be drawn.
*/
if (inconsistent) {
- gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(gCheckboxWidget), TRUE);
+ gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(gParts->checkboxWidget), TRUE);
shadow_type = GTK_SHADOW_ETCHED_IN;
} else {
- gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(gCheckboxWidget), FALSE);
+ gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(gParts->checkboxWidget), FALSE);
}
gtk_paint_check(style, drawable, state_type, shadow_type, cliprect,
- gCheckboxWidget, "checkbutton", x, y, width, height);
+ gParts->checkboxWidget, "checkbutton", x, y, width, height);
if (state->focused) {
gtk_paint_focus(style, drawable, GTK_STATE_ACTIVE, cliprect,
- gCheckboxWidget, "checkbutton", focus_x, focus_y,
+ gParts->checkboxWidget, "checkbutton", focus_x, focus_y,
focus_width, focus_height);
}
}
@@ -1130,9 +1095,9 @@ moz_gtk_scrollbar_button_paint(GdkDrawable* drawable, GdkRectangle* rect,
ensure_scrollbar_widget();
if (flags & MOZ_GTK_STEPPER_VERTICAL)
- scrollbar = gVertScrollbarWidget;
+ scrollbar = gParts->vertScrollbarWidget;
else
- scrollbar = gHorizScrollbarWidget;
+ scrollbar = gParts->horizScrollbarWidget;
gtk_widget_set_direction(scrollbar, direction);
@@ -1216,9 +1181,9 @@ moz_gtk_scrollbar_trough_paint(GtkThemeWidgetType widget,
ensure_scrollbar_widget();
if (widget == MOZ_GTK_SCROLLBAR_TRACK_HORIZONTAL)
- scrollbar = GTK_SCROLLBAR(gHorizScrollbarWidget);
+ scrollbar = GTK_SCROLLBAR(gParts->horizScrollbarWidget);
else
- scrollbar = GTK_SCROLLBAR(gVertScrollbarWidget);
+ scrollbar = GTK_SCROLLBAR(gParts->vertScrollbarWidget);
gtk_widget_set_direction(GTK_WIDGET(scrollbar), direction);
@@ -1259,9 +1224,9 @@ moz_gtk_scrollbar_thumb_paint(GtkThemeWidgetType widget,
ensure_scrollbar_widget();
if (widget == MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL)
- scrollbar = GTK_SCROLLBAR(gHorizScrollbarWidget);
+ scrollbar = GTK_SCROLLBAR(gParts->horizScrollbarWidget);
else
- scrollbar = GTK_SCROLLBAR(gVertScrollbarWidget);
+ scrollbar = GTK_SCROLLBAR(gParts->vertScrollbarWidget);
gtk_widget_set_direction(GTK_WIDGET(scrollbar), direction);
@@ -1322,12 +1287,12 @@ moz_gtk_spin_paint(GdkDrawable* drawable, GdkRectangle* rect,
GtkStyle* style;
ensure_spin_widget();
- gtk_widget_set_direction(gSpinWidget, direction);
- style = gSpinWidget->style;
+ gtk_widget_set_direction(gParts->spinWidget, direction);
+ style = gParts->spinWidget->style;
TSOffsetStyleGCs(style, rect->x, rect->y);
gtk_paint_box(style, drawable, GTK_STATE_NORMAL, GTK_SHADOW_IN, NULL,
- gSpinWidget, "spinbutton",
+ gParts->spinWidget, "spinbutton",
rect->x, rect->y, rect->width, rect->height);
return MOZ_GTK_SUCCESS;
}
@@ -1344,11 +1309,11 @@ moz_gtk_spin_updown_paint(GdkDrawable* drawable, GdkRectangle* rect,
GtkStyle* style;
ensure_spin_widget();
- style = gSpinWidget->style;
- gtk_widget_set_direction(gSpinWidget, direction);
+ style = gParts->spinWidget->style;
+ gtk_widget_set_direction(gParts->spinWidget, direction);
TSOffsetStyleGCs(style, rect->x, rect->y);
- gtk_paint_box(style, drawable, state_type, shadow_type, NULL, gSpinWidget,
+ gtk_paint_box(style, drawable, state_type, shadow_type, NULL, gParts->spinWidget,
isDown ? "spinbutton_down" : "spinbutton_up",
rect->x, rect->y, rect->width, rect->height);
@@ -1360,7 +1325,7 @@ moz_gtk_spin_updown_paint(GdkDrawable* drawable, GdkRectangle* rect,
arrow_rect.y += isDown ? -1 : 1;
gtk_paint_arrow(style, drawable, state_type, shadow_type, NULL,
- gSpinWidget, "spinbutton",
+ gParts->spinWidget, "spinbutton",
isDown ? GTK_ARROW_DOWN : GTK_ARROW_UP, TRUE,
arrow_rect.x, arrow_rect.y,
arrow_rect.width, arrow_rect.height);
@@ -1379,7 +1344,7 @@ moz_gtk_scale_paint(GdkDrawable* drawable, GdkRectangle* rect,
GtkWidget* widget;
ensure_scale_widget();
- widget = ((flags == GTK_ORIENTATION_HORIZONTAL) ? gHScaleWidget : gVScaleWidget);
+ widget = ((flags == GTK_ORIENTATION_HORIZONTAL) ? gParts->hScaleWidget : gParts->vScaleWidget);
gtk_widget_set_direction(widget, direction);
style = widget->style;
@@ -1420,7 +1385,7 @@ moz_gtk_scale_thumb_paint(GdkDrawable* drawable, GdkRectangle* rect,
gint thumb_width, thumb_height, x, y;
ensure_scale_widget();
- widget = ((flags == GTK_ORIENTATION_HORIZONTAL) ? gHScaleWidget : gVScaleWidget);
+ widget = ((flags == GTK_ORIENTATION_HORIZONTAL) ? gParts->hScaleWidget : gParts->vScaleWidget);
gtk_widget_set_direction(widget, direction);
style = widget->style;
@@ -1455,14 +1420,14 @@ moz_gtk_gripper_paint(GdkDrawable* drawable, GdkRectangle* rect,
GtkStyle* style;
ensure_handlebox_widget();
- gtk_widget_set_direction(gHandleBoxWidget, direction);
+ gtk_widget_set_direction(gParts->handleBoxWidget, direction);
- style = gHandleBoxWidget->style;
- shadow_type = GTK_HANDLE_BOX(gHandleBoxWidget)->shadow_type;
+ style = gParts->handleBoxWidget->style;
+ shadow_type = GTK_HANDLE_BOX(gParts->handleBoxWidget)->shadow_type;
TSOffsetStyleGCs(style, rect->x, rect->y);
gtk_paint_box(style, drawable, state_type, shadow_type, cliprect,
- gHandleBoxWidget, "handlebox_bin", rect->x, rect->y,
+ gParts->handleBoxWidget, "handlebox_bin", rect->x, rect->y,
rect->width, rect->height);
return MOZ_GTK_SUCCESS;
@@ -1475,8 +1440,8 @@ moz_gtk_hpaned_paint(GdkDrawable* drawable, GdkRectangle* rect,
GtkStateType hpaned_state = ConvertGtkState(state);
ensure_hpaned_widget();
- gtk_paint_handle(gHPanedWidget->style, drawable, hpaned_state,
- GTK_SHADOW_NONE, cliprect, gHPanedWidget, "paned",
+ gtk_paint_handle(gParts->hpanedWidget->style, drawable, hpaned_state,
+ GTK_SHADOW_NONE, cliprect, gParts->hpanedWidget, "paned",
rect->x, rect->y, rect->width, rect->height,
GTK_ORIENTATION_VERTICAL);
@@ -1490,8 +1455,8 @@ moz_gtk_vpaned_paint(GdkDrawable* drawable, GdkRectangle* rect,
GtkStateType vpaned_state = ConvertGtkState(state);
ensure_vpaned_widget();
- gtk_paint_handle(gVPanedWidget->style, drawable, vpaned_state,
- GTK_SHADOW_NONE, cliprect, gVPanedWidget, "paned",
+ gtk_paint_handle(gParts->vpanedWidget->style, drawable, vpaned_state,
+ GTK_SHADOW_NONE, cliprect, gParts->vpanedWidget, "paned",
rect->x, rect->y, rect->width, rect->height,
GTK_ORIENTATION_HORIZONTAL);
@@ -1509,7 +1474,7 @@ moz_gtk_caret_paint(GdkDrawable* drawable, GdkRectangle* rect,
}
ensure_entry_widget();
- gtk_draw_insertion_cursor(gEntryWidget, drawable, cliprect,
+ gtk_draw_insertion_cursor(gParts->entryWidget, drawable, cliprect,
&location, TRUE, direction, FALSE);
return MOZ_GTK_SUCCESS;
@@ -1629,8 +1594,8 @@ moz_gtk_treeview_paint(GdkDrawable* drawable, GdkRectangle* rect,
ensure_tree_view_widget();
ensure_scrolled_window_widget();
- gtk_widget_set_direction(gTreeViewWidget, direction);
- gtk_widget_set_direction(gScrolledWindowWidget, direction);
+ gtk_widget_set_direction(gParts->treeViewWidget, direction);
+ gtk_widget_set_direction(gParts->scrolledWindowWidget, direction);
/* only handle disabled and normal states, otherwise the whole background
* area will be painted differently with other states */
@@ -1639,24 +1604,24 @@ moz_gtk_treeview_paint(GdkDrawable* drawable, GdkRectangle* rect,
/* In GTK the treeview sets the background of the window
* which contains the cells to the treeview base color.
* If we don't set it here the background color will not be correct.*/
- gtk_widget_modify_bg(gTreeViewWidget, state_type,
- &gTreeViewWidget->style->base[state_type]);
+ gtk_widget_modify_bg(gParts->treeViewWidget, state_type,
+ &gParts->treeViewWidget->style->base[state_type]);
- style = gScrolledWindowWidget->style;
+ style = gParts->scrolledWindowWidget->style;
xthickness = XTHICKNESS(style);
ythickness = YTHICKNESS(style);
- TSOffsetStyleGCs(gTreeViewWidget->style, rect->x, rect->y);
+ TSOffsetStyleGCs(gParts->treeViewWidget->style, rect->x, rect->y);
TSOffsetStyleGCs(style, rect->x, rect->y);
- gtk_paint_flat_box(gTreeViewWidget->style, drawable, state_type,
- GTK_SHADOW_NONE, cliprect, gTreeViewWidget, "treeview",
+ gtk_paint_flat_box(gParts->treeViewWidget->style, drawable, state_type,
+ GTK_SHADOW_NONE, cliprect, gParts->treeViewWidget, "treeview",
rect->x + xthickness, rect->y + ythickness,
rect->width - 2 * xthickness,
rect->height - 2 * ythickness);
gtk_paint_shadow(style, drawable, GTK_STATE_NORMAL, GTK_SHADOW_IN,
- cliprect, gScrolledWindowWidget, "scrolled_window",
+ cliprect, gParts->scrolledWindowWidget, "scrolled_window",
rect->x, rect->y, rect->width, rect->height);
return MOZ_GTK_SUCCESS;
@@ -1667,11 +1632,11 @@ moz_gtk_tree_header_cell_paint(GdkDrawable* drawable, GdkRectangle* rect,
GdkRectangle* cliprect, GtkWidgetState* state,
gboolean isSorted, GtkTextDirection direction)
{
- gtk_tree_view_column_set_sort_indicator(gMiddleTreeViewColumn,
+ gtk_tree_view_column_set_sort_indicator(gParts->middleTreeViewColumn,
isSorted);
moz_gtk_button_paint(drawable, rect, cliprect, state, GTK_RELIEF_NORMAL,
- gTreeHeaderCellWidget, direction);
+ gParts->treeHeaderCellWidget, direction);
return MOZ_GTK_SUCCESS;
}
@@ -1688,7 +1653,7 @@ moz_gtk_tree_header_sort_arrow_paint(GdkDrawable* drawable, GdkRectangle* rect,
GtkStyle* style;
ensure_tree_header_cell_widget();
- gtk_widget_set_direction(gTreeHeaderSortArrowWidget, direction);
+ gtk_widget_set_direction(gParts->treeHeaderSortArrowWidget, direction);
/* hard code these values */
arrow_rect.width = 11;
@@ -1696,11 +1661,11 @@ moz_gtk_tree_header_sort_arrow_paint(GdkDrawable* drawable, GdkRectangle* rect,
arrow_rect.x = rect->x + (rect->width - arrow_rect.width) / 2;
arrow_rect.y = rect->y + (rect->height - arrow_rect.height) / 2;
- style = gTreeHeaderSortArrowWidget->style;
+ style = gParts->treeHeaderSortArrowWidget->style;
TSOffsetStyleGCs(style, arrow_rect.x, arrow_rect.y);
gtk_paint_arrow(style, drawable, state_type, shadow_type, cliprect,
- gTreeHeaderSortArrowWidget, "arrow", arrow_type, TRUE,
+ gParts->treeHeaderSortArrowWidget, "arrow", arrow_type, TRUE,
arrow_rect.x, arrow_rect.y,
arrow_rect.width, arrow_rect.height);
@@ -1717,16 +1682,16 @@ moz_gtk_treeview_expander_paint(GdkDrawable* drawable, GdkRectangle* rect,
GtkStateType state_type;
ensure_tree_view_widget();
- gtk_widget_set_direction(gTreeViewWidget, direction);
+ gtk_widget_set_direction(gParts->treeViewWidget, direction);
- style = gTreeViewWidget->style;
+ style = gParts->treeViewWidget->style;
/* Because the frame we get is of the entire treeview, we can't get the precise
* event state of one expander, thus rendering hover and active feedback useless. */
state_type = state->disabled ? GTK_STATE_INSENSITIVE : GTK_STATE_NORMAL;
TSOffsetStyleGCs(style, rect->x, rect->y);
- gtk_paint_expander(style, drawable, state_type, cliprect, gTreeViewWidget, "treeview",
+ gtk_paint_expander(style, drawable, state_type, cliprect, gParts->treeViewWidget, "treeview",
rect->x + rect->width / 2, rect->y + rect->height / 2, expander_state);
return MOZ_GTK_SUCCESS;
@@ -1742,12 +1707,12 @@ moz_gtk_expander_paint(GdkDrawable* drawable, GdkRectangle* rect,
GtkStateType state_type = ConvertGtkState(state);
ensure_expander_widget();
- gtk_widget_set_direction(gExpanderWidget, direction);
+ gtk_widget_set_direction(gParts->expanderWidget, direction);
- style = gExpanderWidget->style;
+ style = gParts->expanderWidget->style;
TSOffsetStyleGCs(style, rect->x, rect->y);
- gtk_paint_expander(style, drawable, state_type, cliprect, gExpanderWidget, "expander",
+ gtk_paint_expander(style, drawable, state_type, cliprect, gParts->expanderWidget, "expander",
rect->x + rect->width / 2, rect->y + rect->height / 2, expander_state);
return MOZ_GTK_SUCCESS;
@@ -1759,7 +1724,7 @@ moz_gtk_combo_box_paint(GdkDrawable* drawable, GdkRectangle* rect,
gboolean ishtml, GtkTextDirection direction)
{
GdkRectangle arrow_rect, real_arrow_rect;
- gint arrow_size, separator_width;
+ gint /* arrow_size, */ separator_width;
gboolean wide_separators;
GtkStateType state_type = ConvertGtkState(state);
GtkShadowType shadow_type = state->active ? GTK_SHADOW_IN : GTK_SHADOW_OUT;
@@ -1768,42 +1733,42 @@ moz_gtk_combo_box_paint(GdkDrawable* drawable, GdkRectangle* rect,
ensure_combo_box_widgets();
- /* Also sets the direction on gComboBoxButtonWidget, which is then
+ /* Also sets the direction on gParts->comboBoxButtonWidget, which is then
* inherited by the separator and arrow */
moz_gtk_button_paint(drawable, rect, cliprect, state, GTK_RELIEF_NORMAL,
- gComboBoxButtonWidget, direction);
+ gParts->comboBoxButtonWidget, direction);
- calculate_button_inner_rect(gComboBoxButtonWidget,
+ calculate_button_inner_rect(gParts->comboBoxButtonWidget,
rect, &arrow_rect, direction, ishtml);
/* Now arrow_rect contains the inner rect ; we want to correct the width
* to what the arrow needs (see gtk_combo_box_size_allocate) */
- gtk_widget_size_request(gComboBoxArrowWidget, &arrow_req);
+ gtk_widget_size_request(gParts->comboBoxArrowWidget, &arrow_req);
if (direction == GTK_TEXT_DIR_LTR)
arrow_rect.x += arrow_rect.width - arrow_req.width;
arrow_rect.width = arrow_req.width;
- calculate_arrow_rect(gComboBoxArrowWidget,
+ calculate_arrow_rect(gParts->comboBoxArrowWidget,
&arrow_rect, &real_arrow_rect, direction);
- style = gComboBoxArrowWidget->style;
+ style = gParts->comboBoxArrowWidget->style;
TSOffsetStyleGCs(style, rect->x, rect->y);
- gtk_widget_size_allocate(gComboBoxWidget, rect);
+ gtk_widget_size_allocate(gParts->comboBoxWidget, rect);
gtk_paint_arrow(style, drawable, state_type, shadow_type, cliprect,
- gComboBoxArrowWidget, "arrow", GTK_ARROW_DOWN, TRUE,
+ gParts->comboBoxArrowWidget, "arrow", GTK_ARROW_DOWN, TRUE,
real_arrow_rect.x, real_arrow_rect.y,
real_arrow_rect.width, real_arrow_rect.height);
/* If there is no separator in the theme, there's nothing left to do. */
- if (!gComboBoxSeparatorWidget)
+ if (!gParts->comboBoxSeparatorWidget)
return MOZ_GTK_SUCCESS;
- style = gComboBoxSeparatorWidget->style;
+ style = gParts->comboBoxSeparatorWidget->style;
TSOffsetStyleGCs(style, rect->x, rect->y);
- gtk_widget_style_get(gComboBoxSeparatorWidget,
+ gtk_widget_style_get(gParts->comboBoxSeparatorWidget,
"wide-separators", &wide_separators,
"separator-width", &separator_width,
NULL);
@@ -1816,7 +1781,7 @@ moz_gtk_combo_box_paint(GdkDrawable* drawable, GdkRectangle* rect,
gtk_paint_box(style, drawable,
GTK_STATE_NORMAL, GTK_SHADOW_ETCHED_OUT,
- cliprect, gComboBoxSeparatorWidget, "vseparator",
+ cliprect, gParts->comboBoxSeparatorWidget, "vseparator",
arrow_rect.x, arrow_rect.y,
separator_width, arrow_rect.height);
} else {
@@ -1826,7 +1791,7 @@ moz_gtk_combo_box_paint(GdkDrawable* drawable, GdkRectangle* rect,
arrow_rect.x += arrow_rect.width;
gtk_paint_vline(style, drawable, GTK_STATE_NORMAL, cliprect,
- gComboBoxSeparatorWidget, "vseparator",
+ gParts->comboBoxSeparatorWidget, "vseparator",
arrow_rect.y, arrow_rect.y + arrow_rect.height,
arrow_rect.x);
}
@@ -1844,14 +1809,14 @@ moz_gtk_downarrow_paint(GdkDrawable* drawable, GdkRectangle* rect,
GdkRectangle arrow_rect;
ensure_button_arrow_widget();
- style = gButtonArrowWidget->style;
+ style = gParts->buttonArrowWidget->style;
- calculate_arrow_rect(gButtonArrowWidget, rect, &arrow_rect,
+ calculate_arrow_rect(gParts->buttonArrowWidget, rect, &arrow_rect,
GTK_TEXT_DIR_LTR);
TSOffsetStyleGCs(style, arrow_rect.x, arrow_rect.y);
gtk_paint_arrow(style, drawable, state_type, shadow_type, cliprect,
- gButtonArrowWidget, "arrow", GTK_ARROW_DOWN, TRUE,
+ gParts->buttonArrowWidget, "arrow", GTK_ARROW_DOWN, TRUE,
arrow_rect.x, arrow_rect.y, arrow_rect.width, arrow_rect.height);
return MOZ_GTK_SUCCESS;
@@ -1875,19 +1840,19 @@ moz_gtk_combo_box_entry_button_paint(GdkDrawable* drawable, GdkRectangle* rect,
if (input_focus) {
/* Some themes draw a complementary focus ring for the dropdown button
* when the dropdown entry has focus */
- GTK_WIDGET_SET_FLAGS(gComboBoxEntryTextareaWidget, GTK_HAS_FOCUS);
+ GTK_WIDGET_SET_FLAGS(gParts->comboBoxEntryTextareaWidget, GTK_HAS_FOCUS);
}
moz_gtk_button_paint(drawable, rect, cliprect, state, GTK_RELIEF_NORMAL,
- gComboBoxEntryButtonWidget, direction);
+ gParts->comboBoxEntryButtonWidget, direction);
if (input_focus)
- GTK_WIDGET_UNSET_FLAGS(gComboBoxEntryTextareaWidget, GTK_HAS_FOCUS);
+ GTK_WIDGET_UNSET_FLAGS(gParts->comboBoxEntryTextareaWidget, GTK_HAS_FOCUS);
- calculate_button_inner_rect(gComboBoxEntryButtonWidget,
+ calculate_button_inner_rect(gParts->comboBoxEntryButtonWidget,
rect, &arrow_rect, direction, FALSE);
if (state_type == GTK_STATE_ACTIVE) {
- gtk_widget_style_get(gComboBoxEntryButtonWidget,
+ gtk_widget_style_get(gParts->comboBoxEntryButtonWidget,
"child-displacement-x", &x_displacement,
"child-displacement-y", &y_displacement,
NULL);
@@ -1895,14 +1860,14 @@ moz_gtk_combo_box_entry_button_paint(GdkDrawable* drawable, GdkRectangle* rect,
arrow_rect.y += y_displacement;
}
- calculate_arrow_rect(gComboBoxEntryArrowWidget,
+ calculate_arrow_rect(gParts->comboBoxEntryArrowWidget,
&arrow_rect, &real_arrow_rect, direction);
- style = gComboBoxEntryArrowWidget->style;
+ style = gParts->comboBoxEntryArrowWidget->style;
TSOffsetStyleGCs(style, real_arrow_rect.x, real_arrow_rect.y);
gtk_paint_arrow(style, drawable, state_type, shadow_type, cliprect,
- gComboBoxEntryArrowWidget, "arrow", GTK_ARROW_DOWN, TRUE,
+ gParts->comboBoxEntryArrowWidget, "arrow", GTK_ARROW_DOWN, TRUE,
real_arrow_rect.x, real_arrow_rect.y,
real_arrow_rect.width, real_arrow_rect.height);
@@ -1922,10 +1887,10 @@ moz_gtk_container_paint(GdkDrawable* drawable, GdkRectangle* rect,
if (isradio) {
ensure_radiobutton_widget();
- widget = gRadiobuttonWidget;
+ widget = gParts->radiobuttonWidget;
} else {
ensure_checkbox_widget();
- widget = gCheckboxWidget;
+ widget = gParts->checkboxWidget;
}
gtk_widget_set_direction(widget, direction);
@@ -1973,10 +1938,10 @@ moz_gtk_toggle_label_paint(GdkDrawable* drawable, GdkRectangle* rect,
if (isradio) {
ensure_radiobutton_widget();
- widget = gRadiobuttonWidget;
+ widget = gParts->radiobuttonWidget;
} else {
ensure_checkbox_widget();
- widget = gCheckboxWidget;
+ widget = gParts->checkboxWidget;
}
gtk_widget_set_direction(widget, direction);
@@ -2005,9 +1970,9 @@ moz_gtk_toolbar_paint(GdkDrawable* drawable, GdkRectangle* rect,
GtkShadowType shadow_type;
ensure_toolbar_widget();
- gtk_widget_set_direction(gToolbarWidget, direction);
+ gtk_widget_set_direction(gParts->toolbarWidget, direction);
- style = gToolbarWidget->style;
+ style = gParts->toolbarWidget->style;
TSOffsetStyleGCs(style, rect->x, rect->y);
@@ -2016,10 +1981,10 @@ moz_gtk_toolbar_paint(GdkDrawable* drawable, GdkRectangle* rect,
cliprect, rect->x, rect->y,
rect->width, rect->height);
- gtk_widget_style_get(gToolbarWidget, "shadow-type", &shadow_type, NULL);
+ gtk_widget_style_get(gParts->toolbarWidget, "shadow-type", &shadow_type, NULL);
gtk_paint_box (style, drawable, GTK_STATE_NORMAL, shadow_type,
- cliprect, gToolbarWidget, "toolbar",
+ cliprect, gParts->toolbarWidget, "toolbar",
rect->x, rect->y, rect->width, rect->height);
return MOZ_GTK_SUCCESS;
@@ -2040,11 +2005,11 @@ moz_gtk_toolbar_separator_paint(GdkDrawable* drawable, GdkRectangle* rect,
const double end_fraction = 0.8;
ensure_toolbar_separator_widget();
- gtk_widget_set_direction(gToolbarSeparatorWidget, direction);
+ gtk_widget_set_direction(gParts->toolbarSeparatorWidget, direction);
- style = gToolbarSeparatorWidget->style;
+ style = gParts->toolbarSeparatorWidget->style;
- gtk_widget_style_get(gToolbarWidget,
+ gtk_widget_style_get(gParts->toolbarWidget,
"wide-separators", &wide_separators,
"separator-width", &separator_width,
NULL);
@@ -2057,7 +2022,7 @@ moz_gtk_toolbar_separator_paint(GdkDrawable* drawable, GdkRectangle* rect,
gtk_paint_box(style, drawable,
GTK_STATE_NORMAL, GTK_SHADOW_ETCHED_OUT,
- cliprect, gToolbarWidget, "vseparator",
+ cliprect, gParts->toolbarWidget, "vseparator",
rect->x + (rect->width - separator_width) / 2,
rect->y + rect->height * start_fraction,
separator_width,
@@ -2070,7 +2035,7 @@ moz_gtk_toolbar_separator_paint(GdkDrawable* drawable, GdkRectangle* rect,
paint_width = rect->width;
gtk_paint_vline(style, drawable,
- GTK_STATE_NORMAL, cliprect, gToolbarSeparatorWidget,
+ GTK_STATE_NORMAL, cliprect, gParts->toolbarSeparatorWidget,
"toolbar",
rect->y + rect->height * start_fraction,
rect->y + rect->height * end_fraction,
@@ -2087,16 +2052,16 @@ moz_gtk_tooltip_paint(GdkDrawable* drawable, GdkRectangle* rect,
GtkStyle* style;
ensure_tooltip_widget();
- gtk_widget_set_direction(gTooltipWidget, direction);
+ gtk_widget_set_direction(gParts->tooltipWidget, direction);
style = gtk_rc_get_style_by_paths(gtk_settings_get_default(),
"gtk-tooltips", "GtkWindow",
GTK_TYPE_WINDOW);
- style = gtk_style_attach(style, gTooltipWidget->window);
+ style = gtk_style_attach(style, gParts->tooltipWidget->window);
TSOffsetStyleGCs(style, rect->x, rect->y);
gtk_paint_flat_box(style, drawable, GTK_STATE_NORMAL, GTK_SHADOW_OUT,
- cliprect, gTooltipWidget, "tooltip",
+ cliprect, gParts->tooltipWidget, "tooltip",
rect->x, rect->y, rect->width, rect->height);
return MOZ_GTK_SUCCESS;
@@ -2111,13 +2076,13 @@ moz_gtk_resizer_paint(GdkDrawable* drawable, GdkRectangle* rect,
GtkStateType state_type = ConvertGtkState(state);
ensure_window_widget();
- gtk_widget_set_direction(gProtoWindow, direction);
+ gtk_widget_set_direction(gParts->protoWindow, direction);
- style = gProtoWindow->style;
+ style = gParts->protoWindow->style;
TSOffsetStyleGCs(style, rect->x, rect->y);
- gtk_paint_resize_grip(style, drawable, state_type, cliprect, gProtoWindow,
+ gtk_paint_resize_grip(style, drawable, state_type, cliprect, gParts->protoWindow,
NULL, (direction == GTK_TEXT_DIR_LTR) ?
GDK_WINDOW_EDGE_SOUTH_EAST :
GDK_WINDOW_EDGE_SOUTH_WEST,
@@ -2133,15 +2098,15 @@ moz_gtk_frame_paint(GdkDrawable* drawable, GdkRectangle* rect,
GtkShadowType shadow_type;
ensure_frame_widget();
- gtk_widget_set_direction(gFrameWidget, direction);
+ gtk_widget_set_direction(gParts->frameWidget, direction);
- style = gFrameWidget->style;
+ style = gParts->frameWidget->style;
- gtk_widget_style_get(gStatusbarWidget, "shadow-type", &shadow_type, NULL);
+ gtk_widget_style_get(gParts->statusbarWidget, "shadow-type", &shadow_type, NULL);
TSOffsetStyleGCs(style, rect->x, rect->y);
gtk_paint_shadow(style, drawable, GTK_STATE_NORMAL, shadow_type,
- cliprect, gFrameWidget, "frame", rect->x, rect->y,
+ cliprect, gParts->frameWidget, "frame", rect->x, rect->y,
rect->width, rect->height);
return MOZ_GTK_SUCCESS;
@@ -2154,13 +2119,13 @@ moz_gtk_progressbar_paint(GdkDrawable* drawable, GdkRectangle* rect,
GtkStyle* style;
ensure_progress_widget();
- gtk_widget_set_direction(gProgressWidget, direction);
+ gtk_widget_set_direction(gParts->progresWidget, direction);
- style = gProgressWidget->style;
+ style = gParts->progresWidget->style;
TSOffsetStyleGCs(style, rect->x, rect->y);
gtk_paint_box(style, drawable, GTK_STATE_NORMAL, GTK_SHADOW_IN,
- cliprect, gProgressWidget, "trough", rect->x, rect->y,
+ cliprect, gParts->progresWidget, "trough", rect->x, rect->y,
rect->width, rect->height);
return MOZ_GTK_SUCCESS;
@@ -2173,13 +2138,13 @@ moz_gtk_progress_chunk_paint(GdkDrawable* drawable, GdkRectangle* rect,
GtkStyle* style;
ensure_progress_widget();
- gtk_widget_set_direction(gProgressWidget, direction);
+ gtk_widget_set_direction(gParts->progresWidget, direction);
- style = gProgressWidget->style;
+ style = gParts->progresWidget->style;
TSOffsetStyleGCs(style, rect->x, rect->y);
gtk_paint_box(style, drawable, GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
- cliprect, gProgressWidget, "bar", rect->x, rect->y,
+ cliprect, gParts->progresWidget, "bar", rect->x, rect->y,
rect->width, rect->height);
return MOZ_GTK_SUCCESS;
@@ -2189,10 +2154,10 @@ gint
moz_gtk_get_tab_thickness(void)
{
ensure_tab_widget();
- if (YTHICKNESS(gTabWidget->style) < 2)
+ if (YTHICKNESS(gParts->tabWidget->style) < 2)
return 2; /* some themes don't set ythickness correctly */
- return YTHICKNESS(gTabWidget->style);
+ return YTHICKNESS(gParts->tabWidget->style);
}
static gint
@@ -2208,15 +2173,15 @@ moz_gtk_tab_paint(GdkDrawable* drawable, GdkRectangle* rect,
GtkStyle* style;
ensure_tab_widget();
- gtk_widget_set_direction(gTabWidget, direction);
+ gtk_widget_set_direction(gParts->tabWidget, direction);
- style = gTabWidget->style;
+ style = gParts->tabWidget->style;
TSOffsetStyleGCs(style, rect->x, rect->y);
if ((flags & MOZ_GTK_TAB_SELECTED) == 0) {
/* Only draw the tab */
gtk_paint_extension(style, drawable, GTK_STATE_ACTIVE, GTK_SHADOW_OUT,
- cliprect, gTabWidget, "tab",
+ cliprect, gParts->tabWidget, "tab",
rect->x, rect->y, rect->width, rect->height,
(flags & MOZ_GTK_TAB_BOTTOM) ?
GTK_POS_TOP : GTK_POS_BOTTOM );
@@ -2283,7 +2248,7 @@ moz_gtk_tab_paint(GdkDrawable* drawable, GdkRectangle* rect,
/* Draw the tab */
gtk_paint_extension(style, drawable, GTK_STATE_NORMAL,
- GTK_SHADOW_OUT, cliprect, gTabWidget, "tab",
+ GTK_SHADOW_OUT, cliprect, gParts->tabWidget, "tab",
rect->x, rect->y + gap_voffset, rect->width,
rect->height - gap_voffset, GTK_POS_TOP);
@@ -2296,7 +2261,7 @@ moz_gtk_tab_paint(GdkDrawable* drawable, GdkRectangle* rect,
- gap_height,
rect->width, gap_height);
gtk_paint_box_gap(style, drawable, GTK_STATE_NORMAL, GTK_SHADOW_OUT,
- cliprect, gTabWidget, "notebook",
+ cliprect, gParts->tabWidget, "notebook",
rect->x - gap_loffset,
rect->y + gap_voffset - 3 * gap_height,
rect->width + gap_loffset + gap_roffset,
@@ -2308,7 +2273,7 @@ moz_gtk_tab_paint(GdkDrawable* drawable, GdkRectangle* rect,
/* Draw the tab */
gtk_paint_extension(style, drawable, GTK_STATE_NORMAL,
- GTK_SHADOW_OUT, cliprect, gTabWidget, "tab",
+ GTK_SHADOW_OUT, cliprect, gParts->tabWidget, "tab",
rect->x, rect->y, rect->width,
rect->height - gap_voffset, GTK_POS_BOTTOM);
@@ -2321,7 +2286,7 @@ moz_gtk_tab_paint(GdkDrawable* drawable, GdkRectangle* rect,
- gap_voffset,
rect->width, gap_height);
gtk_paint_box_gap(style, drawable, GTK_STATE_NORMAL, GTK_SHADOW_OUT,
- cliprect, gTabWidget, "notebook",
+ cliprect, gParts->tabWidget, "notebook",
rect->x - gap_loffset,
rect->y + rect->height - gap_voffset,
rect->width + gap_loffset + gap_roffset,
@@ -2345,13 +2310,13 @@ moz_gtk_tabpanels_paint(GdkDrawable* drawable, GdkRectangle* rect,
GtkStyle* style;
ensure_tab_widget();
- gtk_widget_set_direction(gTabWidget, direction);
+ gtk_widget_set_direction(gParts->tabWidget, direction);
- style = gTabWidget->style;
+ style = gParts->tabWidget->style;
TSOffsetStyleGCs(style, rect->x, rect->y);
gtk_paint_box_gap(style, drawable, GTK_STATE_NORMAL, GTK_SHADOW_OUT,
- cliprect, gTabWidget, "notebook", rect->x, rect->y,
+ cliprect, gParts->tabWidget, "notebook", rect->x, rect->y,
rect->width, rect->height,
GTK_POS_TOP, -10, 0);
@@ -2373,7 +2338,7 @@ moz_gtk_tab_scroll_arrow_paint(GdkDrawable* drawable, GdkRectangle* rect,
ensure_tab_widget();
- style = gTabWidget->style;
+ style = gParts->tabWidget->style;
TSOffsetStyleGCs(style, rect->x, rect->y);
if (direction == GTK_TEXT_DIR_RTL) {
@@ -2382,7 +2347,7 @@ moz_gtk_tab_scroll_arrow_paint(GdkDrawable* drawable, GdkRectangle* rect,
}
gtk_paint_arrow(style, drawable, state_type, shadow_type, NULL,
- gTabWidget, "notebook", arrow_type, TRUE,
+ gParts->tabWidget, "notebook", arrow_type, TRUE,
x, y, arrow_size, arrow_size);
return MOZ_GTK_SUCCESS;
@@ -2395,11 +2360,11 @@ moz_gtk_menu_bar_paint(GdkDrawable* drawable, GdkRectangle* rect,
GtkStyle* style;
GtkShadowType shadow_type;
ensure_menu_bar_widget();
- gtk_widget_set_direction(gMenuBarWidget, direction);
+ gtk_widget_set_direction(gParts->menuBarWidget, direction);
- gtk_widget_style_get(gMenuBarWidget, "shadow-type", &shadow_type, NULL);
+ gtk_widget_style_get(gParts->menuBarWidget, "shadow-type", &shadow_type, NULL);
- style = gMenuBarWidget->style;
+ style = gParts->menuBarWidget->style;
TSOffsetStyleGCs(style, rect->x, rect->y);
gtk_style_apply_default_background(style, drawable, TRUE, GTK_STATE_NORMAL,
@@ -2407,7 +2372,7 @@ moz_gtk_menu_bar_paint(GdkDrawable* drawable, GdkRectangle* rect,
rect->width, rect->height);
gtk_paint_box(style, drawable, GTK_STATE_NORMAL, shadow_type,
- cliprect, gMenuBarWidget, "menubar", rect->x, rect->y,
+ cliprect, gParts->menuBarWidget, "menubar", rect->x, rect->y,
rect->width, rect->height);
return MOZ_GTK_SUCCESS;
}
@@ -2418,16 +2383,16 @@ moz_gtk_menu_popup_paint(GdkDrawable* drawable, GdkRectangle* rect,
{
GtkStyle* style;
ensure_menu_popup_widget();
- gtk_widget_set_direction(gMenuPopupWidget, direction);
+ gtk_widget_set_direction(gParts->menuPopupWidget, direction);
- style = gMenuPopupWidget->style;
+ style = gParts->menuPopupWidget->style;
TSOffsetStyleGCs(style, rect->x, rect->y);
gtk_style_apply_default_background(style, drawable, TRUE, GTK_STATE_NORMAL,
cliprect, rect->x, rect->y,
rect->width, rect->height);
gtk_paint_box(style, drawable, GTK_STATE_NORMAL, GTK_SHADOW_OUT,
- cliprect, gMenuPopupWidget, "menu",
+ cliprect, gParts->menuPopupWidget, "menu",
rect->x, rect->y, rect->width, rect->height);
return MOZ_GTK_SUCCESS;
@@ -2444,11 +2409,11 @@ moz_gtk_menu_separator_paint(GdkDrawable* drawable, GdkRectangle* rect,
gint paint_height;
ensure_menu_separator_widget();
- gtk_widget_set_direction(gMenuSeparatorWidget, direction);
+ gtk_widget_set_direction(gParts->menuSeparatorWidget, direction);
- style = gMenuSeparatorWidget->style;
+ style = gParts->menuSeparatorWidget->style;
- gtk_widget_style_get(gMenuSeparatorWidget,
+ gtk_widget_style_get(gParts->menuSeparatorWidget,
"wide-separators", &wide_separators,
"separator-height", &separator_height,
"horizontal-padding", &horizontal_padding,
@@ -2462,7 +2427,7 @@ moz_gtk_menu_separator_paint(GdkDrawable* drawable, GdkRectangle* rect,
gtk_paint_box(style, drawable,
GTK_STATE_NORMAL, GTK_SHADOW_ETCHED_OUT,
- cliprect, gMenuSeparatorWidget, "hseparator",
+ cliprect, gParts->menuSeparatorWidget, "hseparator",
rect->x + horizontal_padding + style->xthickness,
rect->y + (rect->height - separator_height - style->ythickness) / 2,
rect->width - 2 * (horizontal_padding + style->xthickness),
@@ -2473,7 +2438,7 @@ moz_gtk_menu_separator_paint(GdkDrawable* drawable, GdkRectangle* rect,
paint_height = rect->height;
gtk_paint_hline(style, drawable,
- GTK_STATE_NORMAL, cliprect, gMenuSeparatorWidget,
+ GTK_STATE_NORMAL, cliprect, gParts->menuSeparatorWidget,
"menuitem",
rect->x + horizontal_padding + style->xthickness,
rect->x + rect->width - horizontal_padding - style->xthickness - 1,
@@ -2495,10 +2460,10 @@ moz_gtk_menu_item_paint(GdkDrawable* drawable, GdkRectangle* rect,
if (state->inHover && !state->disabled) {
if (flags & MOZ_TOPLEVEL_MENU_ITEM) {
ensure_menu_bar_item_widget();
- item_widget = gMenuBarItemWidget;
+ item_widget = gParts->menuBarItemWidget;
} else {
ensure_menu_item_widget();
- item_widget = gMenuItemWidget;
+ item_widget = gParts->menuItemWidget;
}
gtk_widget_set_direction(item_widget, direction);
@@ -2525,14 +2490,14 @@ moz_gtk_menu_arrow_paint(GdkDrawable* drawable, GdkRectangle* rect,
GtkStateType state_type = ConvertGtkState(state);
ensure_menu_item_widget();
- gtk_widget_set_direction(gMenuItemWidget, direction);
+ gtk_widget_set_direction(gParts->menuItemWidget, direction);
- style = gMenuItemWidget->style;
+ style = gParts->menuItemWidget->style;
TSOffsetStyleGCs(style, rect->x, rect->y);
gtk_paint_arrow(style, drawable, state_type,
(state_type == GTK_STATE_PRELIGHT) ? GTK_SHADOW_IN : GTK_SHADOW_OUT,
- cliprect, gMenuItemWidget, "menuitem",
+ cliprect, gParts->menuItemWidget, "menuitem",
(direction == GTK_TEXT_DIR_LTR) ? GTK_ARROW_RIGHT : GTK_ARROW_LEFT,
TRUE, rect->x, rect->y, rect->width, rect->height);
@@ -2555,17 +2520,17 @@ moz_gtk_check_menu_item_paint(GdkDrawable* drawable, GdkRectangle* rect,
moz_gtk_menu_item_paint(drawable, rect, cliprect, state, FALSE, direction);
ensure_check_menu_item_widget();
- gtk_widget_set_direction(gCheckMenuItemWidget, direction);
+ gtk_widget_set_direction(gParts->checkMenuItemWidget, direction);
- gtk_widget_style_get (gCheckMenuItemWidget,
+ gtk_widget_style_get (gParts->checkMenuItemWidget,
"indicator-size", &indicator_size,
NULL);
- if (checked || GTK_CHECK_MENU_ITEM(gCheckMenuItemWidget)->always_show_toggle) {
- style = gCheckMenuItemWidget->style;
+ if (checked || GTK_CHECK_MENU_ITEM(gParts->checkMenuItemWidget)->always_show_toggle) {
+ style = gParts->checkMenuItemWidget->style;
- offset = GTK_CONTAINER(gCheckMenuItemWidget)->border_width +
- gCheckMenuItemWidget->style->xthickness + 2;
+ offset = GTK_CONTAINER(gParts->checkMenuItemWidget)->border_width +
+ gParts->checkMenuItemWidget->style->xthickness + 2;
/* while normally this "3" would be the horizontal-padding style value, passing it to Gecko
as the value of menuitem padding causes problems with dropdowns (bug 406129), so in the menu.css
@@ -2575,16 +2540,16 @@ moz_gtk_check_menu_item_paint(GdkDrawable* drawable, GdkRectangle* rect,
y = rect->y + (rect->height - indicator_size) / 2;
TSOffsetStyleGCs(style, x, y);
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gCheckMenuItemWidget),
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gParts->checkMenuItemWidget),
checked);
if (isradio) {
gtk_paint_option(style, drawable, state_type, shadow_type, cliprect,
- gCheckMenuItemWidget, "option",
+ gParts->checkMenuItemWidget, "option",
x, y, indicator_size, indicator_size);
} else {
gtk_paint_check(style, drawable, state_type, shadow_type, cliprect,
- gCheckMenuItemWidget, "check",
+ gParts->checkMenuItemWidget, "check",
x, y, indicator_size, indicator_size);
}
}
@@ -2599,9 +2564,9 @@ moz_gtk_window_paint(GdkDrawable* drawable, GdkRectangle* rect,
GtkStyle* style;
ensure_window_widget();
- gtk_widget_set_direction(gProtoWindow, direction);
+ gtk_widget_set_direction(gParts->protoWindow, direction);
- style = gProtoWindow->style;
+ style = gParts->protoWindow->style;
TSOffsetStyleGCs(style, rect->x, rect->y);
gtk_style_apply_default_background(style, drawable, TRUE,
@@ -2626,32 +2591,32 @@ moz_gtk_get_widget_border(GtkThemeWidgetType widget, gint* left, gint* top,
gint focus_width, focus_pad;
ensure_button_widget();
- *left = *top = *right = *bottom = GTK_CONTAINER(gButtonWidget)->border_width;
+ *left = *top = *right = *bottom = GTK_CONTAINER(gParts->buttonWidget)->border_width;
/* Don't add this padding in HTML, otherwise the buttons will
become too big and stuff the layout. */
if (!inhtml) {
- moz_gtk_widget_get_focus(gButtonWidget, &interior_focus, &focus_width, &focus_pad);
- moz_gtk_button_get_inner_border(gButtonWidget, &inner_border);
+ moz_gtk_widget_get_focus(gParts->buttonWidget, &interior_focus, &focus_width, &focus_pad);
+ moz_gtk_button_get_inner_border(gParts->buttonWidget, &inner_border);
*left += focus_width + focus_pad + inner_border.left;
*right += focus_width + focus_pad + inner_border.right;
*top += focus_width + focus_pad + inner_border.top;
*bottom += focus_width + focus_pad + inner_border.bottom;
}
- *left += gButtonWidget->style->xthickness;
- *right += gButtonWidget->style->xthickness;
- *top += gButtonWidget->style->ythickness;
- *bottom += gButtonWidget->style->ythickness;
+ *left += gParts->buttonWidget->style->xthickness;
+ *right += gParts->buttonWidget->style->xthickness;
+ *top += gParts->buttonWidget->style->ythickness;
+ *bottom += gParts->buttonWidget->style->ythickness;
return MOZ_GTK_SUCCESS;
}
case MOZ_GTK_ENTRY:
ensure_entry_widget();
- w = gEntryWidget;
+ w = gParts->entryWidget;
break;
case MOZ_GTK_TREEVIEW:
ensure_tree_view_widget();
- w = gTreeViewWidget;
+ w = gParts->treeViewWidget;
break;
case MOZ_GTK_TREE_HEADER_CELL:
{
@@ -2666,32 +2631,32 @@ moz_gtk_get_widget_border(GtkThemeWidgetType widget, gint* left, gint* top,
gint focus_width, focus_pad;
ensure_tree_header_cell_widget();
- *left = *top = *right = *bottom = GTK_CONTAINER(gTreeHeaderCellWidget)->border_width;
+ *left = *top = *right = *bottom = GTK_CONTAINER(gParts->treeHeaderCellWidget)->border_width;
- moz_gtk_widget_get_focus(gTreeHeaderCellWidget, &interior_focus, &focus_width, &focus_pad);
- moz_gtk_button_get_inner_border(gTreeHeaderCellWidget, &inner_border);
+ moz_gtk_widget_get_focus(gParts->treeHeaderCellWidget, &interior_focus, &focus_width, &focus_pad);
+ moz_gtk_button_get_inner_border(gParts->treeHeaderCellWidget, &inner_border);
*left += focus_width + focus_pad + inner_border.left;
*right += focus_width + focus_pad + inner_border.right;
*top += focus_width + focus_pad + inner_border.top;
*bottom += focus_width + focus_pad + inner_border.bottom;
- *left += gTreeHeaderCellWidget->style->xthickness;
- *right += gTreeHeaderCellWidget->style->xthickness;
- *top += gTreeHeaderCellWidget->style->ythickness;
- *bottom += gTreeHeaderCellWidget->style->ythickness;
+ *left += gParts->treeHeaderCellWidget->style->xthickness;
+ *right += gParts->treeHeaderCellWidget->style->xthickness;
+ *top += gParts->treeHeaderCellWidget->style->ythickness;
+ *bottom += gParts->treeHeaderCellWidget->style->ythickness;
return MOZ_GTK_SUCCESS;
}
case MOZ_GTK_TREE_HEADER_SORTARROW:
ensure_tree_header_cell_widget();
- w = gTreeHeaderSortArrowWidget;
+ w = gParts->treeHeaderSortArrowWidget;
break;
case MOZ_GTK_DROPDOWN_ENTRY:
ensure_combo_box_entry_widgets();
- w = gComboBoxEntryTextareaWidget;
+ w = gParts->comboBoxEntryTextareaWidget;
break;
case MOZ_GTK_DROPDOWN_ARROW:
ensure_combo_box_entry_widgets();
- w = gComboBoxEntryButtonWidget;
+ w = gParts->comboBoxEntryButtonWidget;
break;
case MOZ_GTK_DROPDOWN:
{
@@ -2704,34 +2669,34 @@ moz_gtk_get_widget_border(GtkThemeWidgetType widget, gint* left, gint* top,
ensure_combo_box_widgets();
- *left = GTK_CONTAINER(gComboBoxButtonWidget)->border_width;
+ *left = GTK_CONTAINER(gParts->comboBoxButtonWidget)->border_width;
if (!inhtml) {
- moz_gtk_widget_get_focus(gComboBoxButtonWidget,
+ moz_gtk_widget_get_focus(gParts->comboBoxButtonWidget,
&ignored_interior_focus,
&focus_width, &focus_pad);
*left += focus_width + focus_pad;
}
- *top = *left + gComboBoxButtonWidget->style->ythickness;
- *left += gComboBoxButtonWidget->style->xthickness;
+ *top = *left + gParts->comboBoxButtonWidget->style->ythickness;
+ *left += gParts->comboBoxButtonWidget->style->xthickness;
*right = *left; *bottom = *top;
/* If there is no separator, don't try to count its width. */
separator_width = 0;
- if (gComboBoxSeparatorWidget) {
- gtk_widget_style_get(gComboBoxSeparatorWidget,
+ if (gParts->comboBoxSeparatorWidget) {
+ gtk_widget_style_get(gParts->comboBoxSeparatorWidget,
"wide-separators", &wide_separators,
"separator-width", &separator_width,
NULL);
if (!wide_separators)
separator_width =
- XTHICKNESS(gComboBoxSeparatorWidget->style);
+ XTHICKNESS(gParts->comboBoxSeparatorWidget->style);
}
- gtk_widget_size_request(gComboBoxArrowWidget, &arrow_req);
+ gtk_widget_size_request(gParts->comboBoxArrowWidget, &arrow_req);
if (direction == GTK_TEXT_DIR_RTL)
*left += separator_width + arrow_req.width;
@@ -2742,29 +2707,29 @@ moz_gtk_get_widget_border(GtkThemeWidgetType widget, gint* left, gint* top,
}
case MOZ_GTK_TABPANELS:
ensure_tab_widget();
- w = gTabWidget;
+ w = gParts->tabWidget;
break;
case MOZ_GTK_PROGRESSBAR:
ensure_progress_widget();
- w = gProgressWidget;
+ w = gParts->progresWidget;
break;
case MOZ_GTK_SPINBUTTON_ENTRY:
case MOZ_GTK_SPINBUTTON_UP:
case MOZ_GTK_SPINBUTTON_DOWN:
ensure_spin_widget();
- w = gSpinWidget;
+ w = gParts->spinWidget;
break;
case MOZ_GTK_SCALE_HORIZONTAL:
ensure_scale_widget();
- w = gHScaleWidget;
+ w = gParts->hScaleWidget;
break;
case MOZ_GTK_SCALE_VERTICAL:
ensure_scale_widget();
- w = gVScaleWidget;
+ w = gParts->vScaleWidget;
break;
case MOZ_GTK_FRAME:
ensure_frame_widget();
- w = gFrameWidget;
+ w = gParts->frameWidget;
break;
case MOZ_GTK_CHECKBUTTON_LABEL:
case MOZ_GTK_RADIOBUTTON_LABEL:
@@ -2776,12 +2741,12 @@ moz_gtk_get_widget_border(GtkThemeWidgetType widget, gint* left, gint* top,
(focus_width + focus_pad). */
if (widget == MOZ_GTK_CHECKBUTTON_LABEL) {
ensure_checkbox_widget();
- moz_gtk_widget_get_focus(gCheckboxWidget, &interior_focus,
+ moz_gtk_widget_get_focus(gParts->checkboxWidget, &interior_focus,
&focus_width, &focus_pad);
}
else {
ensure_radiobutton_widget();
- moz_gtk_widget_get_focus(gRadiobuttonWidget, &interior_focus,
+ moz_gtk_widget_get_focus(gParts->radiobuttonWidget, &interior_focus,
&focus_width, &focus_pad);
}
@@ -2803,14 +2768,14 @@ moz_gtk_get_widget_border(GtkThemeWidgetType widget, gint* left, gint* top,
of (focus_width + focus_pad). */
if (widget == MOZ_GTK_CHECKBUTTON_CONTAINER) {
ensure_checkbox_widget();
- moz_gtk_widget_get_focus(gCheckboxWidget, &interior_focus,
+ moz_gtk_widget_get_focus(gParts->checkboxWidget, &interior_focus,
&focus_width, &focus_pad);
- w = gCheckboxWidget;
+ w = gParts->checkboxWidget;
} else {
ensure_radiobutton_widget();
- moz_gtk_widget_get_focus(gRadiobuttonWidget, &interior_focus,
+ moz_gtk_widget_get_focus(gParts->radiobuttonWidget, &interior_focus,
&focus_width, &focus_pad);
- w = gRadiobuttonWidget;
+ w = gParts->radiobuttonWidget;
}
*left = *top = *right = *bottom = GTK_CONTAINER(w)->border_width;
@@ -2826,21 +2791,21 @@ moz_gtk_get_widget_border(GtkThemeWidgetType widget, gint* left, gint* top,
}
case MOZ_GTK_MENUPOPUP:
ensure_menu_popup_widget();
- w = gMenuPopupWidget;
+ w = gParts->menuPopupWidget;
break;
case MOZ_GTK_MENUITEM:
ensure_menu_item_widget();
ensure_menu_bar_item_widget();
- w = gMenuItemWidget;
+ w = gParts->menuItemWidget;
break;
case MOZ_GTK_CHECKMENUITEM:
case MOZ_GTK_RADIOMENUITEM:
ensure_check_menu_item_widget();
- w = gCheckMenuItemWidget;
+ w = gParts->checkMenuItemWidget;
break;
case MOZ_GTK_TAB:
ensure_tab_widget();
- w = gTabWidget;
+ w = gParts->tabWidget;
break;
/* These widgets have no borders, since they are not containers. */
case MOZ_GTK_SPLITTER_HORIZONTAL:
@@ -2895,7 +2860,7 @@ moz_gtk_get_combo_box_entry_button_size(gint* width, gint* height)
GtkRequisition requisition;
ensure_combo_box_entry_widgets();
- gtk_widget_size_request(gComboBoxEntryButtonWidget, &requisition);
+ gtk_widget_size_request(gParts->comboBoxEntryButtonWidget, &requisition);
*width = requisition.width;
*height = requisition.height;
@@ -2908,7 +2873,7 @@ moz_gtk_get_tab_scroll_arrow_size(gint* width, gint* height)
gint arrow_size;
ensure_tab_widget();
- gtk_widget_style_get(gTabWidget,
+ gtk_widget_style_get(gParts->tabWidget,
"scroll-arrow-hlength", &arrow_size,
NULL);
@@ -2923,7 +2888,7 @@ moz_gtk_get_downarrow_size(gint* width, gint* height)
GtkRequisition requisition;
ensure_button_arrow_widget();
- gtk_widget_size_request(gButtonArrowWidget, &requisition);
+ gtk_widget_size_request(gParts->buttonArrowWidget, &requisition);
*width = requisition.width;
*height = requisition.height;
@@ -2939,9 +2904,9 @@ moz_gtk_get_toolbar_separator_width(gint* size)
ensure_toolbar_widget();
- style = gToolbarWidget->style;
+ style = gParts->toolbarWidget->style;
- gtk_widget_style_get(gToolbarWidget,
+ gtk_widget_style_get(gParts->toolbarWidget,
"space-size", size,
"wide-separators", &wide_separators,
"separator-width", &separator_width,
@@ -2957,7 +2922,7 @@ gint
moz_gtk_get_expander_size(gint* size)
{
ensure_expander_widget();
- gtk_widget_style_get(gExpanderWidget,
+ gtk_widget_style_get(gParts->expanderWidget,
"expander-size", size,
NULL);
@@ -2968,7 +2933,7 @@ gint
moz_gtk_get_treeview_expander_size(gint* size)
{
ensure_tree_view_widget();
- gtk_widget_style_get(gTreeViewWidget,
+ gtk_widget_style_get(gParts->treeViewWidget,
"expander-size", size,
NULL);
@@ -2983,15 +2948,15 @@ moz_gtk_get_menu_separator_height(gint *size)
ensure_menu_separator_widget();
- gtk_widget_style_get(gMenuSeparatorWidget,
+ gtk_widget_style_get(gParts->menuSeparatorWidget,
"wide-separators", &wide_separators,
"separator-height", &separator_height,
NULL);
if (wide_separators)
- *size = separator_height + gMenuSeparatorWidget->style->ythickness;
+ *size = separator_height + gParts->menuSeparatorWidget->style->ythickness;
else
- *size = gMenuSeparatorWidget->style->ythickness * 2;
+ *size = gParts->menuSeparatorWidget->style->ythickness * 2;
return MOZ_GTK_SUCCESS;
}
@@ -3002,7 +2967,7 @@ moz_gtk_get_scalethumb_metrics(GtkOrientation orient, gint* thumb_length, gint*
GtkWidget* widget;
ensure_scale_widget();
- widget = ((orient == GTK_ORIENTATION_HORIZONTAL) ? gHScaleWidget : gVScaleWidget);
+ widget = ((orient == GTK_ORIENTATION_HORIZONTAL) ? gParts->hScaleWidget : gParts->vScaleWidget);
gtk_widget_style_get (widget,
"slider_length", thumb_length,
@@ -3017,7 +2982,7 @@ moz_gtk_get_scrollbar_metrics(MozGtkScrollbarMetrics *metrics)
{
ensure_scrollbar_widget();
- gtk_widget_style_get (gHorizScrollbarWidget,
+ gtk_widget_style_get (gParts->horizScrollbarWidget,
"slider_width", &metrics->slider_width,
"trough_border", &metrics->trough_border,
"stepper_size", &metrics->stepper_size,
@@ -3025,7 +2990,7 @@ moz_gtk_get_scrollbar_metrics(MozGtkScrollbarMetrics *metrics)
NULL);
metrics->min_slider_size =
- GTK_RANGE(gHorizScrollbarWidget)->min_slider_size;
+ GTK_RANGE(gParts->horizScrollbarWidget)->min_slider_size;
return MOZ_GTK_SUCCESS;
}
@@ -3037,7 +3002,7 @@ moz_gtk_images_in_menus()
GtkSettings* settings;
ensure_image_menu_item_widget();
- settings = gtk_widget_get_settings(gImageMenuItemWidget);
+ settings = gtk_widget_get_settings(gParts->imageMenuItemWidget);
g_object_get(settings, "gtk-menu-images", &result, NULL);
return result;
@@ -3055,11 +3020,11 @@ moz_gtk_widget_paint(GtkThemeWidgetType widget, GdkDrawable* drawable,
ensure_toggle_button_widget();
return moz_gtk_button_paint(drawable, rect, cliprect, state,
(GtkReliefStyle) flags,
- gToggleButtonWidget, direction);
+ gParts->toggleButtonWidget, direction);
}
ensure_button_widget();
return moz_gtk_button_paint(drawable, rect, cliprect, state,
- (GtkReliefStyle) flags, gButtonWidget,
+ (GtkReliefStyle) flags, gParts->buttonWidget,
direction);
break;
case MOZ_GTK_CHECKBUTTON:
@@ -3107,7 +3072,7 @@ moz_gtk_widget_paint(GtkThemeWidgetType widget, GdkDrawable* drawable,
case MOZ_GTK_SPINBUTTON_ENTRY:
ensure_spin_widget();
return moz_gtk_entry_paint(drawable, rect, cliprect, state,
- gSpinWidget, direction);
+ gParts->spinWidget, direction);
break;
case MOZ_GTK_GRIPPER:
return moz_gtk_gripper_paint(drawable, rect, cliprect, state,
@@ -3138,7 +3103,7 @@ moz_gtk_widget_paint(GtkThemeWidgetType widget, GdkDrawable* drawable,
case MOZ_GTK_ENTRY:
ensure_entry_widget();
return moz_gtk_entry_paint(drawable, rect, cliprect, state,
- gEntryWidget, direction);
+ gParts->entryWidget, direction);
break;
case MOZ_GTK_ENTRY_CARET:
return moz_gtk_caret_paint(drawable, rect, cliprect, direction);
@@ -3154,7 +3119,7 @@ moz_gtk_widget_paint(GtkThemeWidgetType widget, GdkDrawable* drawable,
case MOZ_GTK_DROPDOWN_ENTRY:
ensure_combo_box_entry_widgets();
return moz_gtk_entry_paint(drawable, rect, cliprect, state,
- gComboBoxEntryTextareaWidget, direction);
+ gParts->comboBoxEntryTextareaWidget, direction);
break;
case MOZ_GTK_CHECKBUTTON_CONTAINER:
case MOZ_GTK_RADIOBUTTON_CONTAINER:
@@ -3252,65 +3217,13 @@ GtkWidget* moz_gtk_get_scrollbar_widget(void)
if (!is_initialized)
return NULL;
ensure_scrollbar_widget();
- return gHorizScrollbarWidget;
+ return gParts->horizScrollbarWidget;
}
gint
moz_gtk_shutdown()
{
GtkWidgetClass *entry_class;
-
- if (gTooltipWidget)
- gtk_widget_destroy(gTooltipWidget);
- /* This will destroy all of our widgets */
- if (gProtoWindow)
- gtk_widget_destroy(gProtoWindow);
-
- gProtoWindow = NULL;
- gProtoLayout = NULL;
- gButtonWidget = NULL;
- gToggleButtonWidget = NULL;
- gButtonArrowWidget = NULL;
- gCheckboxWidget = NULL;
- gRadiobuttonWidget = NULL;
- gHorizScrollbarWidget = NULL;
- gVertScrollbarWidget = NULL;
- gSpinWidget = NULL;
- gHScaleWidget = NULL;
- gVScaleWidget = NULL;
- gEntryWidget = NULL;
- gComboBoxWidget = NULL;
- gComboBoxButtonWidget = NULL;
- gComboBoxSeparatorWidget = NULL;
- gComboBoxArrowWidget = NULL;
- gComboBoxEntryWidget = NULL;
- gComboBoxEntryButtonWidget = NULL;
- gComboBoxEntryArrowWidget = NULL;
- gComboBoxEntryTextareaWidget = NULL;
- gHandleBoxWidget = NULL;
- gToolbarWidget = NULL;
- gStatusbarWidget = NULL;
- gFrameWidget = NULL;
- gProgressWidget = NULL;
- gTabWidget = NULL;
- gTooltipWidget = NULL;
- gMenuBarWidget = NULL;
- gMenuBarItemWidget = NULL;
- gMenuPopupWidget = NULL;
- gMenuItemWidget = NULL;
- gImageMenuItemWidget = NULL;
- gCheckMenuItemWidget = NULL;
- gTreeViewWidget = NULL;
- gMiddleTreeViewColumn = NULL;
- gTreeHeaderCellWidget = NULL;
- gTreeHeaderSortArrowWidget = NULL;
- gExpanderWidget = NULL;
- gToolbarSeparatorWidget = NULL;
- gMenuSeparatorWidget = NULL;
- gHPanedWidget = NULL;
- gVPanedWidget = NULL;
- gScrolledWindowWidget = NULL;
-
entry_class = g_type_class_peek(GTK_TYPE_ENTRY);
g_type_class_unref(entry_class);
@@ -3318,3 +3231,19 @@ moz_gtk_shutdown()
return MOZ_GTK_SUCCESS;
}
+
+void moz_gtk_destroy_theme_parts_widgets(GtkThemeParts* parts)
+{
+ if (!parts)
+ return;
+
+ if (parts->tooltipWidget) {
+ gtk_widget_destroy(parts->tooltipWidget);
+ parts->tooltipWidget = NULL;
+ }
+
+ if (parts->protoWindow) {
+ gtk_widget_destroy(parts->protoWindow);
+ parts->protoWindow = NULL;
+ }
+}
diff --git a/WebCore/platform/gtk/gtkdrawing.h b/WebCore/platform/gtk/gtkdrawing.h
index 1a33bfb..1e9023f 100644
--- a/WebCore/platform/gtk/gtkdrawing.h
+++ b/WebCore/platform/gtk/gtkdrawing.h
@@ -48,7 +48,6 @@
#ifndef _GTK_DRAWING_H_
#define _GTK_DRAWING_H_
-#include <gdk/gdk.h>
#include <gtk/gtk.h>
#ifdef __cplusplus
@@ -78,6 +77,54 @@ typedef struct {
gint min_slider_size;
} MozGtkScrollbarMetrics;
+typedef struct _GtkThemeParts {
+ GdkColormap* colormap;
+ GtkWidget* protoWindow;
+ GtkWidget* protoLayout;
+ GtkWidget* buttonWidget;
+ GtkWidget* toggleButtonWidget;
+ GtkWidget* buttonArrowWidget;
+ GtkWidget* checkboxWidget;
+ GtkWidget* radiobuttonWidget;
+ GtkWidget* horizScrollbarWidget;
+ GtkWidget* vertScrollbarWidget;
+ GtkWidget* spinWidget;
+ GtkWidget* hScaleWidget;
+ GtkWidget* vScaleWidget;
+ GtkWidget* entryWidget;
+ GtkWidget* comboBoxWidget;
+ GtkWidget* comboBoxButtonWidget;
+ GtkWidget* comboBoxArrowWidget;
+ GtkWidget* comboBoxSeparatorWidget;
+ GtkWidget* comboBoxEntryWidget;
+ GtkWidget* comboBoxEntryTextareaWidget;
+ GtkWidget* comboBoxEntryButtonWidget;
+ GtkWidget* comboBoxEntryArrowWidget;
+ GtkWidget* handleBoxWidget;
+ GtkWidget* toolbarWidget;
+ GtkWidget* frameWidget;
+ GtkWidget* statusbarWidget;
+ GtkWidget* progresWidget;
+ GtkWidget* tabWidget;
+ GtkWidget* tooltipWidget;
+ GtkWidget* menuBarWidget;
+ GtkWidget* menuBarItemWidget;
+ GtkWidget* menuPopupWidget;
+ GtkWidget* menuItemWidget;
+ GtkWidget* imageMenuItemWidget;
+ GtkWidget* checkMenuItemWidget;
+ GtkWidget* treeViewWidget;
+ GtkTreeViewColumn* middleTreeViewColumn;
+ GtkWidget* treeHeaderCellWidget;
+ GtkWidget* treeHeaderSortArrowWidget;
+ GtkWidget* expanderWidget;
+ GtkWidget* toolbarSeparatorWidget;
+ GtkWidget* menuSeparatorWidget;
+ GtkWidget* hpanedWidget;
+ GtkWidget* vpanedWidget;
+ GtkWidget* scrolledWindowWidget;
+} GtkThemeParts;
+
typedef enum {
MOZ_GTK_STEPPER_DOWN = 1 << 0,
MOZ_GTK_STEPPER_BOTTOM = 1 << 1,
@@ -226,6 +273,14 @@ typedef enum {
gint moz_gtk_init();
/**
+ * Instruct the drawing library to do all rendering based on
+ * the given collection of theme parts. If any members of the
+ * GtkThemeParts struct are NULL, they will be created lazily.
+ */
+void
+moz_gtk_use_theme_parts(GtkThemeParts* parts);
+
+/**
* Enable GTK+ 1.2.9+ theme enhancements. You must provide a pointer
* to the GTK+ 1.2.9+ function "gtk_style_get_prop_experimental".
* styleGetProp: pointer to gtk_style_get_prop_experimental
@@ -242,6 +297,11 @@ gint moz_gtk_enable_style_props(style_prop_t styleGetProp);
*/
gint moz_gtk_shutdown();
+/**
+ * Destroy the widgets in the given GtkThemeParts, which should
+ * be destroyed before the GtkThemeParts can be freed.
+ */
+void moz_gtk_destroy_theme_parts_widgets(GtkThemeParts* parts);
/*** Widget drawing ***/
/**
diff --git a/WebCore/platform/haiku/LocalizedStringsHaiku.cpp b/WebCore/platform/haiku/LocalizedStringsHaiku.cpp
index 9bb4c3e..3b94bcb 100644
--- a/WebCore/platform/haiku/LocalizedStringsHaiku.cpp
+++ b/WebCore/platform/haiku/LocalizedStringsHaiku.cpp
@@ -292,6 +292,16 @@ String AXHeadingText()
return String();
}
+String AXMenuListPopupActionVerb()
+{
+ return String();
+}
+
+String AXMenuListActionVerb()
+{
+ return String();
+}
+
String imageTitle(const String& filename, const IntSize& size)
{
return String(filename);
diff --git a/WebCore/platform/haiku/SharedBufferHaiku.cpp b/WebCore/platform/haiku/SharedBufferHaiku.cpp
index 113cd2e..abe9e2d 100644
--- a/WebCore/platform/haiku/SharedBufferHaiku.cpp
+++ b/WebCore/platform/haiku/SharedBufferHaiku.cpp
@@ -47,6 +47,7 @@ PassRefPtr<SharedBuffer> SharedBuffer::createWithContentsOfFile(const String& fi
result->m_buffer.resize(size);
if (result->m_buffer.size() != size)
return 0;
+ result->m_size = size;
file.Read(result->m_buffer.data(), result->m_buffer.size());
return result.release();
diff --git a/WebCore/platform/image-decoders/ImageDecoder.cpp b/WebCore/platform/image-decoders/ImageDecoder.cpp
index a16b940..62f6bec 100644
--- a/WebCore/platform/image-decoders/ImageDecoder.cpp
+++ b/WebCore/platform/image-decoders/ImageDecoder.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008-2009 Torch Mobile, Inc.
+ * Copyright (C) Research In Motion Limited 2009-2010. 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
@@ -22,9 +23,8 @@
#include "ImageDecoder.h"
-#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
#include <algorithm>
-#endif
+#include <cmath>
#include "BMPImageDecoder.h"
#include "GIFImageDecoder.h"
@@ -32,19 +32,36 @@
#include "JPEGImageDecoder.h"
#include "PNGImageDecoder.h"
#include "SharedBuffer.h"
-#include "XBMImageDecoder.h"
+
+using namespace std;
namespace WebCore {
+static unsigned copyFromSharedBuffer(char* buffer, unsigned bufferLength, const SharedBuffer& sharedBuffer, unsigned offset)
+{
+ unsigned bytesExtracted = 0;
+ const char* moreData;
+ while (unsigned moreDataLength = sharedBuffer.getSomeData(moreData, offset)) {
+ unsigned bytesToCopy = min(bufferLength - bytesExtracted, moreDataLength);
+ memcpy(buffer + bytesExtracted, moreData, bytesToCopy);
+ bytesExtracted += bytesToCopy;
+ if (bytesExtracted == bufferLength)
+ break;
+ offset += bytesToCopy;
+ }
+ return bytesExtracted;
+}
+
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)
+ static const unsigned maxMarkerLength = 4;
+ char contents[maxMarkerLength];
+ unsigned length = copyFromSharedBuffer(contents, maxMarkerLength, data, 0);
+ if (length < maxMarkerLength)
return 0;
- const unsigned char* uContents = (const unsigned char*)data.data();
- const char* contents = data.data();
+ const unsigned char* uContents = reinterpret_cast<const unsigned char*>(contents);
// GIFs begin with GIF8(7 or 9).
if (strncmp(contents, "GIF8", 4) == 0)
@@ -73,10 +90,6 @@ ImageDecoder* ImageDecoder::create(const SharedBuffer& data)
!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;
}
@@ -170,8 +183,6 @@ int RGBA32Buffer::height() const
#endif
-#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
-
namespace {
enum MatchType {
@@ -196,6 +207,9 @@ inline void fillScaledValues(Vector<int>& scaledValues, double scaleRate, int le
template <MatchType type> int getScaledValue(const Vector<int>& scaledValues, int valueToMatch, int searchStart)
{
+ if (scaledValues.isEmpty())
+ return valueToMatch;
+
const int* dataStart = scaledValues.data();
const int* dataEnd = dataStart + scaledValues.size();
const int* matched = std::lower_bound(dataStart + searchStart, dataEnd, valueToMatch);
@@ -214,18 +228,19 @@ template <MatchType type> int getScaledValue(const Vector<int>& scaledValues, in
void ImageDecoder::prepareScaleDataIfNecessary()
{
- int width = m_size.width();
- int height = m_size.height();
+ int width = size().width();
+ int height = size().height();
int numPixels = height * width;
- if (m_maxNumPixels <= 0 || numPixels <= m_maxNumPixels) {
+ if (m_maxNumPixels > 0 && numPixels > m_maxNumPixels) {
+ m_scaled = true;
+ double scale = sqrt(m_maxNumPixels / (double)numPixels);
+ fillScaledValues(m_scaledColumns, scale, width);
+ fillScaledValues(m_scaledRows, scale, height);
+ } else if (m_scaled) {
m_scaled = false;
- return;
+ m_scaledColumns.clear();
+ m_scaledRows.clear();
}
-
- 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)
@@ -238,11 +253,19 @@ int ImageDecoder::lowerBoundScaledX(int origX, int searchStart)
return getScaledValue<LowerBound>(m_scaledColumns, origX, searchStart);
}
+int ImageDecoder::upperBoundScaledY(int origY, int searchStart)
+{
+ return getScaledValue<UpperBound>(m_scaledRows, origY, searchStart);
+}
+
+int ImageDecoder::lowerBoundScaledY(int origY, int searchStart)
+{
+ return getScaledValue<LowerBound>(m_scaledRows, origY, 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 535efa1..3ca7abf 100644
--- a/WebCore/platform/image-decoders/ImageDecoder.h
+++ b/WebCore/platform/image-decoders/ImageDecoder.h
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
* Copyright (C) 2008-2009 Torch Mobile, Inc.
+ * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
*
* Redistribution and use in source and binary forms, with or without
@@ -203,12 +204,11 @@ namespace WebCore {
// 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_scaled(false)
+ , m_failed(false)
, m_sizeAvailable(false)
-#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
+ , m_isAllDataReceived(false)
, m_maxNumPixels(-1)
- , m_scaled(false)
-#endif
{
}
@@ -223,7 +223,12 @@ namespace WebCore {
virtual String filenameExtension() const = 0;
// All specific decoder plugins must do something with the data they are given.
- virtual void setData(SharedBuffer* data, bool allDataReceived) { m_data = data; }
+ bool isAllDataReceived() const { return m_isAllDataReceived; }
+ virtual void setData(SharedBuffer* data, bool allDataReceived)
+ {
+ m_data = data;
+ m_isAllDataReceived = allDataReceived;
+ }
// Whether or not the size information has been decoded yet. This default
// implementation just returns true if the size has been set and we have not
@@ -237,11 +242,14 @@ namespace WebCore {
// Returns the size of the image.
virtual IntSize size() const
{
- // Requesting the size of an invalid bitmap is meaningless.
- ASSERT(!m_failed);
return m_size;
}
+ IntSize scaledSize() const
+ {
+ return m_scaled ? IntSize(m_scaledColumns.size(), m_scaledRows.size()) : size();
+ }
+
// Returns the size of frame |index|. This will only differ from size()
// for formats where different frames are different sizes (namely ICO,
// where each frame represents a different icon within the master file).
@@ -300,20 +308,17 @@ namespace WebCore {
#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 upperBoundScaledY(int origY, int searchStart = 0);
+ int lowerBoundScaledY(int origY, 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;
@@ -331,6 +336,8 @@ namespace WebCore {
IntSize m_size;
bool m_sizeAvailable;
+ bool m_isAllDataReceived;
+ int m_maxNumPixels;
};
} // namespace WebCore
diff --git a/WebCore/platform/image-decoders/bmp/BMPImageReader.h b/WebCore/platform/image-decoders/bmp/BMPImageReader.h
index 1271172..3536e3b 100644
--- a/WebCore/platform/image-decoders/bmp/BMPImageReader.h
+++ b/WebCore/platform/image-decoders/bmp/BMPImageReader.h
@@ -46,7 +46,7 @@ namespace WebCore {
{
uint16_t result;
memcpy(&result, &data->data()[offset], 2);
- #if PLATFORM(BIG_ENDIAN)
+ #if CPU(BIG_ENDIAN)
result = ((result & 0xff) << 8) | ((result & 0xff00) >> 8);
#endif
return result;
@@ -56,7 +56,7 @@ namespace WebCore {
{
uint32_t result;
memcpy(&result, &data->data()[offset], 4);
- #if PLATFORM(BIG_ENDIAN)
+ #if CPU(BIG_ENDIAN)
result = ((result & 0xff) << 24) | ((result & 0xff00) << 8) |
((result & 0xff0000) >> 8) | ((result & 0xff000000) >> 24);
#endif
@@ -202,7 +202,7 @@ namespace WebCore {
// won't read it.
uint32_t pixel;
memcpy(&pixel, &m_data->data()[m_decodedOffset + offset], 3);
- #if PLATFORM(BIG_ENDIAN)
+ #if CPU(BIG_ENDIAN)
pixel = ((pixel & 0xff00) << 8) | ((pixel & 0xff0000) >> 8) |
((pixel & 0xff000000) >> 24);
#endif
diff --git a/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp b/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp
index 87036c9..1124bd2 100644
--- a/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp
+++ b/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp
@@ -29,70 +29,15 @@
namespace WebCore {
-class GIFImageDecoderPrivate {
-public:
- GIFImageDecoderPrivate(GIFImageDecoder* decoder = 0)
- : m_reader(decoder)
- , m_readOffset(0)
- {
- }
-
- ~GIFImageDecoderPrivate()
- {
- m_reader.close();
- }
-
- bool decode(SharedBuffer* data,
- GIFImageDecoder::GIFQuery query = GIFImageDecoder::GIFFullQuery,
- unsigned int haltFrame = -1)
- {
- return m_reader.read((const unsigned char*)data->data() + m_readOffset, data->size() - m_readOffset,
- query,
- haltFrame);
- }
-
- unsigned frameCount() const { return m_reader.images_count; }
- int repetitionCount() const { return m_reader.loop_count; }
-
- void setReadOffset(unsigned o) { m_readOffset = o; }
-
- bool isTransparent() const { return m_reader.frame_reader->is_transparent; }
-
- void getColorMap(unsigned char*& map, unsigned& size) const
- {
- if (m_reader.frame_reader->is_local_colormap_defined) {
- map = m_reader.frame_reader->local_colormap;
- size = (unsigned)m_reader.frame_reader->local_colormap_size;
- } else {
- map = m_reader.global_colormap;
- size = m_reader.global_colormap_size;
- }
- }
-
- unsigned frameXOffset() const { return m_reader.frame_reader->x_offset; }
- unsigned frameYOffset() const { return m_reader.frame_reader->y_offset; }
- unsigned frameWidth() const { return m_reader.frame_reader->width; }
- unsigned frameHeight() const { return m_reader.frame_reader->height; }
-
- int transparentPixel() const { return m_reader.frame_reader->tpixel; }
-
- unsigned duration() const { return m_reader.frame_reader->delay_time; }
-
-private:
- GIFImageReader m_reader;
- unsigned m_readOffset;
-};
-
GIFImageDecoder::GIFImageDecoder()
: m_frameCountValid(true)
, m_repetitionCount(cAnimationLoopOnce)
- , m_reader(0)
+ , m_readOffset(0)
{
}
GIFImageDecoder::~GIFImageDecoder()
{
- delete m_reader;
}
// Take the data and store it.
@@ -109,7 +54,7 @@ void GIFImageDecoder::setData(SharedBuffer* data, bool allDataReceived)
// Create the GIF reader.
if (!m_reader && !m_failed)
- m_reader = new GIFImageDecoderPrivate(this);
+ m_reader.set(new GIFImageReader(this));
}
// Whether or not the size information has been decoded yet.
@@ -132,13 +77,13 @@ size_t GIFImageDecoder::frameCount()
// slowly. Might be interesting to try to clone our existing read session to preserve
// state, but for now we just crawl all the data. Note that this is no worse than what
// ImageIO does on Mac right now (it also crawls all the data again).
- GIFImageDecoderPrivate reader;
+ GIFImageReader reader(0);
// This function may fail, but we want to keep any partial data it may
// have decoded, so don't mark it is invalid. If there is an overflow
// or some serious error, m_failed will have gotten set for us.
- reader.decode(m_data.get(), GIFFrameCountQuery);
+ reader.read((const unsigned char*)m_data->data(), m_data->size(), GIFFrameCountQuery, static_cast<unsigned>(-1));
m_frameCountValid = true;
- m_frameBufferCache.resize(reader.frameCount());
+ m_frameBufferCache.resize(reader.images_count);
}
return m_frameBufferCache.size();
@@ -161,7 +106,7 @@ int GIFImageDecoder::repetitionCount() const
// cAnimationLoopOnce (-1) when its current incarnation hasn't actually
// seen a loop count yet; in this case we return our previously-cached
// value.
- const int repetitionCount = m_reader->repetitionCount();
+ const int repetitionCount = m_reader->loop_count;
if (repetitionCount != cLoopCountNotSeen)
m_repetitionCount = repetitionCount;
}
@@ -235,43 +180,48 @@ void GIFImageDecoder::decode(GIFQuery query, unsigned haltAtFrame)
if (m_failed)
return;
- m_failed = !m_reader->decode(m_data.get(), query, haltAtFrame);
+ m_failed = !m_reader->read((const unsigned char*)m_data->data() + m_readOffset, m_data->size() - m_readOffset, query, haltAtFrame);
- if (m_failed) {
- delete m_reader;
- m_reader = 0;
- }
+ if (m_failed)
+ m_reader.clear();
}
// Callbacks from the GIF reader.
bool GIFImageDecoder::sizeNowAvailable(unsigned width, unsigned height)
{
- return setSize(width, height);
+ if (!setSize(width, height))
+ return false;
+ prepareScaleDataIfNecessary();
+ return true;
}
void GIFImageDecoder::decodingHalted(unsigned bytesLeft)
{
- m_reader->setReadOffset(m_data->size() - bytesLeft);
+ m_readOffset = m_data->size() - bytesLeft;
}
bool GIFImageDecoder::initFrameBuffer(unsigned frameIndex)
{
// Initialize the frame rect in our buffer.
- IntRect frameRect(m_reader->frameXOffset(), m_reader->frameYOffset(),
- m_reader->frameWidth(), m_reader->frameHeight());
+ const GIFFrameReader* frameReader = m_reader->frame_reader;
+ IntRect frameRect(frameReader->x_offset, frameReader->y_offset, frameReader->width, frameReader->height);
// Make sure the frameRect doesn't extend past the bottom-right of the buffer.
if (frameRect.right() > size().width())
- frameRect.setWidth(size().width() - m_reader->frameXOffset());
+ frameRect.setWidth(size().width() - frameReader->x_offset);
if (frameRect.bottom() > size().height())
- frameRect.setHeight(size().height() - m_reader->frameYOffset());
+ frameRect.setHeight(size().height() - frameReader->y_offset);
RGBA32Buffer* const buffer = &m_frameBufferCache[frameIndex];
- buffer->setRect(frameRect);
-
+ int left = upperBoundScaledX(frameRect.x());
+ int right = lowerBoundScaledX(frameRect.right(), left);
+ int top = upperBoundScaledY(frameRect.y());
+ int bottom = lowerBoundScaledY(frameRect.bottom(), top);
+ buffer->setRect(IntRect(left, top, right - left, bottom - top));
+
if (frameIndex == 0) {
// This is the first frame, so we're not relying on any previous data.
- if (!buffer->setSize(size().width(), size().height())) {
+ if (!buffer->setSize(scaledSize().width(), scaledSize().height())) {
m_failed = true;
return false;
}
@@ -302,11 +252,12 @@ bool GIFImageDecoder::initFrameBuffer(unsigned frameIndex)
// We want to clear the previous frame to transparent, without
// affecting pixels in the image outside of the frame.
const IntRect& prevRect = prevBuffer->rect();
+ const IntSize& bufferSize = scaledSize();
if ((frameIndex == 0)
- || prevRect.contains(IntRect(IntPoint(), size()))) {
+ || prevRect.contains(IntRect(IntPoint(), bufferSize))) {
// Clearing the first frame, or a frame the size of the whole
// image, results in a completely empty image.
- if (!buffer->setSize(size().width(), size().height())) {
+ if (!buffer->setSize(bufferSize.width(), bufferSize.height())) {
m_failed = true;
return false;
}
@@ -331,44 +282,51 @@ bool GIFImageDecoder::initFrameBuffer(unsigned frameIndex)
return true;
}
-void GIFImageDecoder::haveDecodedRow(unsigned frameIndex,
+bool GIFImageDecoder::haveDecodedRow(unsigned frameIndex,
unsigned char* rowBuffer,
unsigned char* rowEnd,
unsigned rowNumber,
unsigned repeatCount,
bool writeTransparentPixels)
{
+ const GIFFrameReader* frameReader = m_reader->frame_reader;
// The pixel data and coordinates supplied to us are relative to the frame's
// origin within the entire image size, i.e.
- // (m_reader->frameXOffset(), m_reader->frameYOffset()).
- int x = m_reader->frameXOffset();
- const int y = m_reader->frameYOffset() + rowNumber;
-
- // Sanity-check the arguments.
- if ((rowBuffer == 0) || (y >= size().height()))
- return;
+ // (frameReader->x_offset, frameReader->y_offset). There is no guarantee
+ // that (rowEnd - rowBuffer) == (size().width() - frameReader->x_offset), so
+ // we must ensure we don't run off the end of either the source data or the
+ // row's X-coordinates.
+ int xBegin = upperBoundScaledX(frameReader->x_offset);
+ int yBegin = upperBoundScaledY(frameReader->y_offset + rowNumber);
+ int xEnd = lowerBoundScaledX(std::min(xBegin + static_cast<int>(rowEnd - rowBuffer), size().width()) - 1, xBegin + 1) + 1;
+ int yEnd = lowerBoundScaledY(std::min(yBegin + static_cast<int>(repeatCount), size().height()) - 1, yBegin + 1) + 1;
+ if (!rowBuffer || (xBegin < 0) || (yBegin < 0) || (xEnd <= xBegin) || (yEnd <= yBegin))
+ return true;
// Get the colormap.
+ const unsigned char* colorMap;
unsigned colorMapSize;
- unsigned char* colorMap;
- m_reader->getColorMap(colorMap, colorMapSize);
+ if (frameReader->is_local_colormap_defined) {
+ colorMap = frameReader->local_colormap;
+ colorMapSize = (unsigned)frameReader->local_colormap_size;
+ } else {
+ colorMap = m_reader->global_colormap;
+ colorMapSize = m_reader->global_colormap_size;
+ }
if (!colorMap)
- return;
+ return true;
// Initialize the frame if necessary.
RGBA32Buffer& buffer = m_frameBufferCache[frameIndex];
if ((buffer.status() == RGBA32Buffer::FrameEmpty) && !initFrameBuffer(frameIndex))
- return;
+ return false;
- // Write one row's worth of data into the frame. There is no guarantee that
- // (rowEnd - rowBuffer) == (size().width() - m_reader->frameXOffset()), so
- // we must ensure we don't run off the end of either the source data or the
- // row's X-coordinates.
- for (unsigned char* sourceAddr = rowBuffer; (sourceAddr != rowEnd) && (x < size().width()); ++sourceAddr, ++x) {
- const unsigned char sourceValue = *sourceAddr;
- if ((!m_reader->isTransparent() || (sourceValue != m_reader->transparentPixel())) && (sourceValue < colorMapSize)) {
+ // Write one row's worth of data into the frame.
+ for (int x = xBegin; x < xEnd; ++x) {
+ const unsigned char sourceValue = *(rowBuffer + (m_scaled ? m_scaledColumns[x] : x) - frameReader->x_offset);
+ if ((!frameReader->is_transparent || (sourceValue != frameReader->tpixel)) && (sourceValue < colorMapSize)) {
const size_t colorIndex = static_cast<size_t>(sourceValue) * 3;
- buffer.setRGBA(x, y, colorMap[colorIndex], colorMap[colorIndex + 1], colorMap[colorIndex + 2], 255);
+ buffer.setRGBA(x, yBegin, colorMap[colorIndex], colorMap[colorIndex + 1], colorMap[colorIndex + 2], 255);
} else {
m_currentBufferSawAlpha = true;
// We may or may not need to write transparent pixels to the buffer.
@@ -379,13 +337,15 @@ void GIFImageDecoder::haveDecodedRow(unsigned frameIndex,
// beyond the first, or the initial passes will "show through" the
// later ones.
if (writeTransparentPixels)
- buffer.setRGBA(x, y, 0, 0, 0, 0);
+ buffer.setRGBA(x, yBegin, 0, 0, 0, 0);
}
}
// Tell the frame to copy the row data if need be.
if (repeatCount > 1)
- buffer.copyRowNTimes(m_reader->frameXOffset(), x, y, std::min(y + static_cast<int>(repeatCount), size().height()));
+ buffer.copyRowNTimes(xBegin, xEnd, yBegin, yEnd);
+
+ return true;
}
void GIFImageDecoder::frameComplete(unsigned frameIndex, unsigned frameDuration, RGBA32Buffer::FrameDisposalMethod disposalMethod)
@@ -403,7 +363,7 @@ void GIFImageDecoder::frameComplete(unsigned frameIndex, unsigned frameDuration,
if (!m_currentBufferSawAlpha) {
// The whole frame was non-transparent, so it's possible that the entire
// resulting buffer was non-transparent, and we can setHasAlpha(false).
- if (buffer.rect().contains(IntRect(IntPoint(), size())))
+ if (buffer.rect().contains(IntRect(IntPoint(), scaledSize())))
buffer.setHasAlpha(false);
else if (frameIndex > 0) {
// Tricky case. This frame does not have alpha only if everywhere
@@ -437,9 +397,8 @@ void GIFImageDecoder::frameComplete(unsigned frameIndex, unsigned frameDuration,
void GIFImageDecoder::gifComplete()
{
if (m_reader)
- m_repetitionCount = m_reader->repetitionCount();
- delete m_reader;
- m_reader = 0;
+ m_repetitionCount = m_reader->loop_count;
+ m_reader.clear();
}
} // namespace WebCore
diff --git a/WebCore/platform/image-decoders/gif/GIFImageDecoder.h b/WebCore/platform/image-decoders/gif/GIFImageDecoder.h
index 5227ea3..011ca96 100644
--- a/WebCore/platform/image-decoders/gif/GIFImageDecoder.h
+++ b/WebCore/platform/image-decoders/gif/GIFImageDecoder.h
@@ -27,10 +27,11 @@
#define GIFImageDecoder_h
#include "ImageDecoder.h"
+#include <wtf/OwnPtr.h>
-namespace WebCore {
+class GIFImageReader;
- class GIFImageDecoderPrivate;
+namespace WebCore {
// This class decodes the GIF image format.
class GIFImageDecoder : public ImageDecoder {
@@ -66,7 +67,7 @@ namespace WebCore {
// Callbacks from the GIF reader.
bool sizeNowAvailable(unsigned width, unsigned height);
void decodingHalted(unsigned bytesLeft);
- void haveDecodedRow(unsigned frameIndex, unsigned char* rowBuffer, unsigned char* rowEnd, unsigned rowNumber,
+ bool haveDecodedRow(unsigned frameIndex, unsigned char* rowBuffer, unsigned char* rowEnd, unsigned rowNumber,
unsigned repeatCount, bool writeTransparentPixels);
void frameComplete(unsigned frameIndex, unsigned frameDuration, RGBA32Buffer::FrameDisposalMethod disposalMethod);
void gifComplete();
@@ -80,7 +81,8 @@ namespace WebCore {
bool m_frameCountValid;
bool m_currentBufferSawAlpha;
mutable int m_repetitionCount;
- GIFImageDecoderPrivate* m_reader;
+ OwnPtr<GIFImageReader> m_reader;
+ unsigned m_readOffset;
};
} // namespace WebCore
diff --git a/WebCore/platform/image-decoders/gif/GIFImageReader.cpp b/WebCore/platform/image-decoders/gif/GIFImageReader.cpp
index 002f67a..ffb1310 100644
--- a/WebCore/platform/image-decoders/gif/GIFImageReader.cpp
+++ b/WebCore/platform/image-decoders/gif/GIFImageReader.cpp
@@ -104,7 +104,7 @@ using WebCore::GIFImageDecoder;
//******************************************************************************
// Send the data to the display front-end.
-void GIFImageReader::output_row()
+bool GIFImageReader::output_row()
{
GIFFrameReader* gs = frame_reader;
@@ -154,13 +154,14 @@ void GIFImageReader::output_row()
/* Protect against too much image data */
if ((unsigned)drow_start >= gs->height)
- return;
+ return true;
// CALLBACK: Let the client know we have decoded a row.
- if (clientptr && frame_reader)
- clientptr->haveDecodedRow(images_count - 1, frame_reader->rowbuf, frame_reader->rowend,
- drow_start, drow_end - drow_start + 1,
- gs->progressive_display && gs->interlaced && gs->ipass > 1);
+ if (clientptr && frame_reader &&
+ !clientptr->haveDecodedRow(images_count - 1, frame_reader->rowbuf, frame_reader->rowend,
+ drow_start, drow_end - drow_start + 1,
+ gs->progressive_display && gs->interlaced && gs->ipass > 1))
+ return false;
gs->rowp = gs->rowbuf;
@@ -207,15 +208,17 @@ void GIFImageReader::output_row()
}
} while (gs->irow > (gs->height - 1));
}
+
+ return true;
}
//******************************************************************************
/* Perform Lempel-Ziv-Welch decoding */
-int GIFImageReader::do_lzw(const unsigned char *q)
+bool GIFImageReader::do_lzw(const unsigned char *q)
{
GIFFrameReader* gs = frame_reader;
if (!gs)
- return 0;
+ return true;
int code;
int incode;
@@ -249,11 +252,12 @@ int GIFImageReader::do_lzw(const unsigned char *q)
unsigned rows_remaining = gs->rows_remaining;
if (rowp == rowend)
- return 0;
+ return true;
#define OUTPUT_ROW \
PR_BEGIN_MACRO \
- output_row(); \
+ if (!output_row()) \
+ return false; \
rows_remaining--; \
rowp = frame_reader->rowp; \
if (!rows_remaining) \
@@ -286,9 +290,7 @@ int GIFImageReader::do_lzw(const unsigned char *q)
/* Check for explicit end-of-stream code */
if (code == (clear_code + 1)) {
/* end-of-stream should only appear after all image data */
- if (rows_remaining != 0)
- return -1;
- return 0;
+ return rows_remaining == 0;
}
if (oldcode == -1) {
@@ -306,13 +308,13 @@ int GIFImageReader::do_lzw(const unsigned char *q)
code = oldcode;
if (stackp == stack + MAX_BITS)
- return -1;
+ return false;
}
while (code >= clear_code)
{
if (code >= MAX_BITS || code == prefix[code])
- return -1;
+ return false;
// Even though suffix[] only holds characters through suffix[avail - 1],
// allowing code >= avail here lets us be more tolerant of malformed
@@ -322,7 +324,7 @@ int GIFImageReader::do_lzw(const unsigned char *q)
code = prefix[code];
if (stackp == stack + MAX_BITS)
- return -1;
+ return false;
}
*stackp++ = firstchar = suffix[code];
@@ -369,7 +371,7 @@ int GIFImageReader::do_lzw(const unsigned char *q)
gs->rowp = rowp;
gs->rows_remaining = rows_remaining;
- return 0;
+ return true;
}
@@ -438,7 +440,7 @@ bool GIFImageReader::read(const unsigned char *buf, unsigned len,
switch (state)
{
case gif_lzw:
- if (do_lzw(q) < 0) {
+ if (!do_lzw(q)) {
state = gif_error;
break;
}
diff --git a/WebCore/platform/image-decoders/gif/GIFImageReader.h b/WebCore/platform/image-decoders/gif/GIFImageReader.h
index f0d127f..14c2fb4 100644
--- a/WebCore/platform/image-decoders/gif/GIFImageReader.h
+++ b/WebCore/platform/image-decoders/gif/GIFImageReader.h
@@ -208,8 +208,8 @@ struct GIFImageReader {
WebCore::GIFImageDecoder::GIFQuery query = WebCore::GIFImageDecoder::GIFFullQuery, unsigned haltAtFrame = -1);
private:
- void output_row();
- int do_lzw(const unsigned char *q);
+ bool output_row();
+ bool do_lzw(const unsigned char *q);
};
#endif
diff --git a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
index 410ef60..2a2636a 100644
--- a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
+++ b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
@@ -39,10 +39,9 @@
#include "config.h"
#include "JPEGImageDecoder.h"
-#include <assert.h>
#include <stdio.h> // Needed by jpeglib.h for FILE.
-#if PLATFORM(WINCE)
+#if OS(WINCE)
// Remove warning: 'FAR' macro redefinition
#undef FAR
@@ -271,7 +270,7 @@ public:
return true; /* I/O suspension */
/* If we've completed image output ... */
- assert(m_info.output_scanline == m_info.output_height);
+ ASSERT(m_info.output_scanline == m_info.output_height);
m_state = JPEG_DONE;
}
}
@@ -401,12 +400,11 @@ void term_source (j_decompress_ptr jd)
}
JPEGImageDecoder::JPEGImageDecoder()
-: m_reader(0)
-{}
+{
+}
JPEGImageDecoder::~JPEGImageDecoder()
{
- delete m_reader;
}
// Take the data and store it.
@@ -420,7 +418,7 @@ void JPEGImageDecoder::setData(SharedBuffer* data, bool allDataReceived)
// Create the JPEG reader.
if (!m_reader && !m_failed)
- m_reader = new JPEGImageReader(this);
+ m_reader.set(new JPEGImageReader(this));
}
// Whether or not the size information has been decoded yet.
@@ -432,6 +430,14 @@ bool JPEGImageDecoder::isSizeAvailable()
return ImageDecoder::isSizeAvailable();
}
+bool JPEGImageDecoder::setSize(unsigned width, unsigned height)
+{
+ if (!ImageDecoder::setSize(width, height))
+ return false;
+ prepareScaleDataIfNecessary();
+ return true;
+}
+
RGBA32Buffer* JPEGImageDecoder::frameBufferAtIndex(size_t index)
{
if (index)
@@ -455,82 +461,8 @@ void JPEGImageDecoder::decode(bool sizeOnly)
m_failed = !m_reader->decode(m_data->buffer(), sizeOnly);
- if (m_failed || (!m_frameBufferCache.isEmpty() && m_frameBufferCache[0].status() == RGBA32Buffer::FrameComplete)) {
- delete m_reader;
- m_reader = 0;
- }
-}
-
-static void convertCMYKToRGBA(RGBA32Buffer& dest, int destY, JSAMPROW src, JDIMENSION srcWidth
-#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
- , bool scaled, const Vector<int>& scaledColumns
-#endif
- )
-{
-#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++;
- unsigned k = *src++;
-
- // Source is 'Inverted CMYK', output is RGB.
- // See: http://www.easyrgb.com/math.php?MATH=M12#text12
- // Or: http://www.ilkeratalay.com/colorspacesfaq.php#rgb
-
- // From CMYK to CMY
- // C = C * ( 1 - K ) + K
- // M = M * ( 1 - K ) + K
- // Y = Y * ( 1 - K ) + K
-
- // From Inverted CMYK to CMY is thus:
- // C = (1-iC) * (1 - (1-iK)) + (1-iK) => 1 - iC*iK
- // Same for M and Y
-
- // Convert from CMY (0..1) to RGB (0..1)
- // R = 1 - C => 1 - (1 - iC*iK) => iC*iK
- // G = 1 - M => 1 - (1 - iM*iK) => iM*iK
- // B = 1 - Y => 1 - (1 - iY*iK) => iY*iK
-
- dest.setRGBA(x, destY, c * k / 255, m * k / 255, y * k / 255, 0xFF);
- }
-}
-
-static void convertRGBToRGBA(RGBA32Buffer& dest, int destY, JSAMPROW src, JDIMENSION srcWidth
-#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
- , bool scaled, const Vector<int>& scaledColumns
-#endif
- )
-{
-#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++;
- dest.setRGBA(x, destY, r, g, b, 0xFF);
- }
+ if (m_failed || (!m_frameBufferCache.isEmpty() && m_frameBufferCache[0].status() == RGBA32Buffer::FrameComplete))
+ m_reader.clear();
}
bool JPEGImageDecoder::outputScanlines()
@@ -541,17 +473,7 @@ bool JPEGImageDecoder::outputScanlines()
// Initialize the framebuffer if needed.
RGBA32Buffer& buffer = m_frameBufferCache[0];
if (buffer.status() == RGBA32Buffer::FrameEmpty) {
- 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)) {
+ if (!buffer.setSize(scaledSize().width(), scaledSize().height())) {
m_failed = true;
return false;
}
@@ -573,27 +495,32 @@ bool JPEGImageDecoder::outputScanlines()
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;
+ int destY = scaledY(sourceY);
+ if (destY < 0)
+ continue;
+ int width = m_scaled ? m_scaledColumns.size() : info->output_width;
+ for (int x = 0; x < width; ++x) {
+ JSAMPLE* jsample = *samples + (m_scaled ? m_scaledColumns[x] : x) * ((info->out_color_space == JCS_RGB) ? 3 : 4);
+ if (info->out_color_space == JCS_RGB)
+ buffer.setRGBA(x, destY, jsample[0], jsample[1], jsample[2], 0xFF);
+ else if (info->out_color_space == JCS_CMYK) {
+ // Source is 'Inverted CMYK', output is RGB.
+ // See: http://www.easyrgb.com/math.php?MATH=M12#text12
+ // Or: http://www.ilkeratalay.com/colorspacesfaq.php#rgb
+ // From CMYK to CMY:
+ // X = X * (1 - K ) + K [for X = C, M, or Y]
+ // Thus, from Inverted CMYK to CMY is:
+ // X = (1-iX) * (1 - (1-iK)) + (1-iK) => 1 - iX*iK
+ // From CMY (0..1) to RGB (0..1):
+ // R = 1 - C => 1 - (1 - iC*iK) => iC*iK [G and B similar]
+ unsigned k = jsample[3];
+ buffer.setRGBA(x, destY, jsample[0] * k / 255, jsample[1] * k / 255, jsample[2] * k / 255, 0xFF);
+ } else {
+ ASSERT_NOT_REACHED();
+ m_failed = true;
+ return false;
+ }
}
- if (info->out_color_space == JCS_RGB)
- convertRGBToRGBA(buffer, destY, *samples, info->output_width, m_scaled, m_scaledColumns);
- else if (info->out_color_space == JCS_CMYK)
- 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 4a822d7..d8bfd70 100644
--- a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h
+++ b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h
@@ -28,6 +28,7 @@
#define JPEGImageDecoder_h
#include "ImageDecoder.h"
+#include <wtf/OwnPtr.h>
namespace WebCore {
@@ -47,29 +48,19 @@ namespace WebCore {
// Whether or not the size information has been decoded yet.
virtual bool isSizeAvailable();
+ virtual bool setSize(unsigned width, unsigned height);
+
virtual RGBA32Buffer* frameBufferAtIndex(size_t index);
virtual bool supportsAlpha() const { return false; }
void decode(bool sizeOnly = false);
- JPEGImageReader* reader() { return m_reader; }
-
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;
+ OwnPtr<JPEGImageReader> m_reader;
};
} // namespace WebCore
diff --git a/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp b/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp
index ad79fc8..35c8af0 100644
--- a/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp
+++ b/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2006 Apple Computer, Inc.
* Copyright (C) 2007-2009 Torch Mobile, Inc.
+ * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
*
* Portions are Copyright (C) 2001 mozilla.org
*
@@ -39,7 +40,6 @@
#include "config.h"
#include "PNGImageDecoder.h"
#include "png.h"
-#include "assert.h"
namespace WebCore {
@@ -76,6 +76,8 @@ public:
, m_decodingSizeOnly(false)
, m_interlaceBuffer(0)
, m_hasAlpha(0)
+ , m_hasFinishedDecoding(false)
+ , m_currentBufferSize(0)
{
m_png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, decodingFailed, decodingWarning);
m_info = png_create_info_struct(m_png);
@@ -93,9 +95,14 @@ public:
delete []m_interlaceBuffer;
m_interlaceBuffer = 0;
m_readOffset = 0;
+ m_hasFinishedDecoding = false;
}
- void decode(const Vector<char>& data, bool sizeOnly)
+ unsigned currentBufferSize() const { return m_currentBufferSize; }
+
+ void setComplete() { m_hasFinishedDecoding = true; }
+
+ void decode(const SharedBuffer& data, bool sizeOnly)
{
m_decodingSizeOnly = sizeOnly;
@@ -105,13 +112,17 @@ public:
return;
}
- // Go ahead and assume we consumed all the data. If we consume less, the
- // callback will adjust our read offset accordingly. Do not attempt to adjust the
- // offset after png_process_data returns.
- unsigned offset = m_readOffset;
- unsigned remaining = data.size() - m_readOffset;
- m_readOffset = data.size();
- png_process_data(m_png, m_info, (png_bytep)(data.data()) + offset, remaining);
+ PNGImageDecoder* decoder = static_cast<PNGImageDecoder*>(png_get_progressive_ptr(m_png));
+ const char* segment;
+ while (unsigned segmentLength = data.getSomeData(segment, m_readOffset)) {
+ m_readOffset += segmentLength;
+ m_currentBufferSize = m_readOffset;
+ png_process_data(m_png, m_info, reinterpret_cast<png_bytep>(const_cast<char*>(segment)), segmentLength);
+ if ((sizeOnly && decoder->isSizeAvailable()) || m_hasFinishedDecoding)
+ return;
+ }
+ if (!m_hasFinishedDecoding && decoder->isAllDataReceived())
+ decoder->pngComplete();
}
bool decodingSizeOnly() const { return m_decodingSizeOnly; }
@@ -134,16 +145,16 @@ private:
png_infop m_info;
png_bytep m_interlaceBuffer;
bool m_hasAlpha;
+ bool m_hasFinishedDecoding;
+ unsigned m_currentBufferSize;
};
PNGImageDecoder::PNGImageDecoder()
- : m_reader(0)
{
}
PNGImageDecoder::~PNGImageDecoder()
{
- delete m_reader;
}
// Take the data and store it.
@@ -157,7 +168,7 @@ void PNGImageDecoder::setData(SharedBuffer* data, bool allDataReceived)
// Create the PNG reader.
if (!m_reader && !m_failed)
- m_reader = new PNGImageReader(this);
+ m_reader.set(new PNGImageReader(this));
}
// Whether or not the size information has been decoded yet.
@@ -190,12 +201,10 @@ void PNGImageDecoder::decode(bool sizeOnly)
if (m_failed)
return;
- m_reader->decode(m_data->buffer(), sizeOnly);
+ m_reader->decode(*m_data, sizeOnly);
- if (m_failed || (!m_frameBufferCache.isEmpty() && m_frameBufferCache[0].status() == RGBA32Buffer::FrameComplete)) {
- delete m_reader;
- m_reader = 0;
- }
+ if (m_failed || (!m_frameBufferCache.isEmpty() && m_frameBufferCache[0].status() == RGBA32Buffer::FrameComplete))
+ m_reader.clear();
}
void decodingFailed(png_structp png, png_const_charp errorMsg)
@@ -224,8 +233,8 @@ void PNGImageDecoder::decodingFailed()
void PNGImageDecoder::headerAvailable()
{
- png_structp png = reader()->pngPtr();
- png_infop info = reader()->infoPtr();
+ png_structp png = m_reader->pngPtr();
+ png_infop info = m_reader->infoPtr();
png_uint_32 width = png->width;
png_uint_32 height = png->height;
@@ -243,9 +252,7 @@ void PNGImageDecoder::headerAvailable()
longjmp(png->jmpbuf, 1);
return;
}
-#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
prepareScaleDataIfNecessary();
-#endif
}
int bitDepth, colorType, interlaceType, compressionType, filterType, channels;
@@ -292,13 +299,13 @@ void PNGImageDecoder::headerAvailable()
// Update our info now
png_read_update_info(png, info);
channels = png_get_channels(png, info);
- assert(channels == 3 || channels == 4);
+ ASSERT(channels == 3 || channels == 4);
- reader()->setHasAlpha(channels == 4);
+ m_reader->setHasAlpha(channels == 4);
- if (reader()->decodingSizeOnly()) {
+ if (m_reader->decodingSizeOnly()) {
// If we only needed the size, halt the reader.
- reader()->setReadOffset(m_data->size() - png->buffer_size);
+ m_reader->setReadOffset(m_reader->currentBufferSize() - png->buffer_size);
png->buffer_size = 0;
}
}
@@ -317,16 +324,9 @@ void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex,
// Initialize the framebuffer if needed.
RGBA32Buffer& buffer = m_frameBufferCache[0];
if (buffer.status() == RGBA32Buffer::FrameEmpty) {
-#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);
+ if (!buffer.setSize(scaledSize().width(), scaledSize().height())) {
+ static_cast<PNGImageDecoder*>(png_get_progressive_ptr(m_reader->pngPtr()))->decodingFailed();
+ longjmp(m_reader->pngPtr()->jmpbuf, 1);
return;
}
buffer.setStatus(RGBA32Buffer::FramePartial);
@@ -335,8 +335,8 @@ void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex,
// For PNGs, the frame always fills the entire image.
buffer.setRect(IntRect(IntPoint(), size()));
- if (reader()->pngPtr()->interlaced)
- reader()->createInterlaceBuffer((reader()->hasAlpha() ? 4 : 3) * size().width() * size().height());
+ if (m_reader->pngPtr()->interlaced)
+ m_reader->createInterlaceBuffer((m_reader->hasAlpha() ? 4 : 3) * size().width() * size().height());
}
if (rowBuffer == 0)
@@ -370,11 +370,11 @@ void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex,
* old row and the new row.
*/
- png_structp png = reader()->pngPtr();
- bool hasAlpha = reader()->hasAlpha();
+ png_structp png = m_reader->pngPtr();
+ bool hasAlpha = m_reader->hasAlpha();
unsigned colorChannels = hasAlpha ? 4 : 3;
png_bytep row;
- png_bytep interlaceBuffer = reader()->interlaceBuffer();
+ png_bytep interlaceBuffer = m_reader->interlaceBuffer();
if (interlaceBuffer) {
row = interlaceBuffer + (rowIndex * colorChannels * size().width());
png_progressive_combine_row(png, row, rowBuffer);
@@ -383,33 +383,15 @@ 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);
- }
- }
+ int width = scaledSize().width();
+ int destY = scaledY(rowIndex);
+ if (destY < 0)
return;
- }
-#endif
- int width = size().width();
bool sawAlpha = buffer.hasAlpha();
for (int x = 0; x < width; x++) {
- unsigned red = *row++;
- unsigned green = *row++;
- unsigned blue = *row++;
- unsigned alpha = (hasAlpha ? *row++ : 255);
- buffer.setRGBA(x, rowIndex, red, green, blue, alpha);
+ png_bytep pixel = row + (m_scaled ? m_scaledColumns[x] : x) * colorChannels;
+ unsigned alpha = hasAlpha ? pixel[3] : 255;
+ buffer.setRGBA(x, destY, pixel[0], pixel[1], pixel[2], alpha);
if (!sawAlpha && alpha < 255) {
sawAlpha = true;
buffer.setHasAlpha(true);
@@ -424,6 +406,8 @@ void pngComplete(png_structp png, png_infop info)
void PNGImageDecoder::pngComplete()
{
+ m_reader->setComplete();
+
if (m_frameBufferCache.isEmpty())
return;
diff --git a/WebCore/platform/image-decoders/png/PNGImageDecoder.h b/WebCore/platform/image-decoders/png/PNGImageDecoder.h
index 3c0535b..07a0b3a 100644
--- a/WebCore/platform/image-decoders/png/PNGImageDecoder.h
+++ b/WebCore/platform/image-decoders/png/PNGImageDecoder.h
@@ -27,6 +27,7 @@
#define PNGImageDecoder_h
#include "ImageDecoder.h"
+#include <wtf/OwnPtr.h>
namespace WebCore {
@@ -50,8 +51,6 @@ namespace WebCore {
void decode(bool sizeOnly = false);
- PNGImageReader* reader() { return m_reader; }
-
// Callbacks from libpng
void decodingFailed();
void headerAvailable();
@@ -59,7 +58,7 @@ namespace WebCore {
void pngComplete();
private:
- PNGImageReader* m_reader;
+ OwnPtr<PNGImageReader> m_reader;
};
} // namespace WebCore
diff --git a/WebCore/platform/image-decoders/qt/RGBA32BufferQt.cpp b/WebCore/platform/image-decoders/qt/RGBA32BufferQt.cpp
index 5e9b527..d3218cd 100644
--- a/WebCore/platform/image-decoders/qt/RGBA32BufferQt.cpp
+++ b/WebCore/platform/image-decoders/qt/RGBA32BufferQt.cpp
@@ -83,11 +83,8 @@ bool RGBA32Buffer::setSize(int newWidth, int newHeight)
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);
+ if (m_image.isNull())
return false;
- }
// Zero the image.
zeroFill();
diff --git a/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp b/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp
index 96342fa..543eca8 100644
--- a/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp
+++ b/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp
@@ -70,11 +70,8 @@ bool RGBA32Buffer::setSize(int newWidth, int newHeight)
// otherwise.
ASSERT(width() == 0 && height() == 0);
m_bitmap.setConfig(SkBitmap::kARGB_8888_Config, newWidth, newHeight);
- if (!m_bitmap.allocPixels()) {
- // Allocation failure, maybe the bitmap was too big.
- setStatus(FrameComplete);
+ if (!m_bitmap.allocPixels())
return false;
- }
// Zero the image.
zeroFill();
diff --git a/WebCore/platform/image-decoders/xbm/XBMImageDecoder.cpp b/WebCore/platform/image-decoders/xbm/XBMImageDecoder.cpp
deleted file mode 100644
index 332bc72..0000000
--- a/WebCore/platform/image-decoders/xbm/XBMImageDecoder.cpp
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "XBMImageDecoder.h"
-
-#include "ASCIICType.h"
-
-#include <algorithm>
-#include <cstdio>
-
-namespace WebCore {
-
-XBMImageDecoder::XBMImageDecoder()
- : m_decodeOffset(0)
- , m_allDataReceived(false)
- , m_decodedHeader(false)
- , m_dataType(Unknown)
- , m_bitsDecoded(0)
-{
-}
-
-void XBMImageDecoder::setData(SharedBuffer* data, bool allDataReceived)
-{
- ImageDecoder::setData(data, allDataReceived);
- m_xbmString = data->buffer();
- m_xbmString.append('\0');
-
- m_allDataReceived = allDataReceived;
-}
-
-bool XBMImageDecoder::isSizeAvailable()
-{
- if (!ImageDecoder::isSizeAvailable() && !m_failed)
- decode(true);
-
- return ImageDecoder::isSizeAvailable();
-}
-
-RGBA32Buffer* XBMImageDecoder::frameBufferAtIndex(size_t index)
-{
- if (index)
- return 0;
-
- if (m_frameBufferCache.isEmpty())
- m_frameBufferCache.resize(1);
-
- // Attempt to get the size if we don't have it yet.
- if (!ImageDecoder::isSizeAvailable())
- decode(true);
-
- // Initialize the framebuffer if needed.
- RGBA32Buffer& buffer = m_frameBufferCache[0];
- if (!failed() && ImageDecoder::isSizeAvailable()
- && (buffer.status() == RGBA32Buffer::FrameEmpty)) {
- if (!buffer.setSize(size().width(), size().height())) {
- m_failed = true;
- return 0;
- }
- buffer.setStatus(RGBA32Buffer::FramePartial);
-
- // For XBMs, the frame always fills the entire image.
- buffer.setRect(IntRect(IntPoint(), size()));
- }
-
- // Keep trying to decode until we've got the entire image.
- if (buffer.status() == RGBA32Buffer::FramePartial)
- decode(false);
-
- return &buffer;
-}
-
-bool XBMImageDecoder::decodeHeader()
-{
- ASSERT(m_decodeOffset <= m_xbmString.size());
- ASSERT(!m_decodedHeader);
-
- const char* input = m_xbmString.data();
-
- // At least 2 "#define <string> <unsigned>" sequences are required. These
- // specify the width and height of the image.
- int width, height;
- if (!ImageDecoder::isSizeAvailable()) {
- int count;
- if (sscanf(&input[m_decodeOffset], "#define %*s %i #define %*s %i%n",
- &width, &height, &count) != 2)
- return false;
-
- // The width and height need to follow some rules.
- if (width < 0 || width > maxDimension || height < 0 || height > maxDimension) {
- // If this happens, decoding should not continue.
- setFailed();
- return false;
- }
-
- if (!setSize(width, height)) {
- setFailed();
- return false;
- }
- m_decodeOffset += count;
- ASSERT(m_decodeOffset <= m_xbmString.size());
- }
-
- ASSERT(ImageDecoder::isSizeAvailable());
-
- // Now we're looking for something that tells us that we've seen all of the
- // "#define <string> <unsigned>" sequences that we're going to. Mozilla
- // just looks for " char " or " short ". We'll do the same.
- if (m_dataType == Unknown) {
- const char* x11hint = " char ";
- const char* x11HintLocation = strstr(&input[m_decodeOffset], x11hint);
- if (x11HintLocation) {
- m_dataType = X11;
- m_decodeOffset += ((x11HintLocation - &input[m_decodeOffset]) + strlen(x11hint));
- } else {
- const char* x10hint = " short ";
- const char* x10HintLocation = strstr(&input[m_decodeOffset], x10hint);
- if (x10HintLocation) {
- m_dataType = X10;
- m_decodeOffset += ((x10HintLocation - &input[m_decodeOffset]) + strlen(x10hint));
- } else
- return false;
- }
- ASSERT(m_decodeOffset <= m_xbmString.size());
- }
-
- // Find the start of the data. Again, we do what mozilla does and just
- // look for a '{' in the input.
- const char* found = strchr(&input[m_decodeOffset], '{');
- if (!found)
- return false;
-
- // Advance to character after the '{'
- m_decodeOffset += ((found - &input[m_decodeOffset]) + 1);
- ASSERT(m_decodeOffset <= m_xbmString.size());
- m_decodedHeader = true;
-
- return true;
-}
-
-// The data in an XBM file is provided as an array of either "char" or "short"
-// values. These values are decoded one at a time using strtoul() and the bits
-// are used to set the alpha value for the image.
-//
-// The value for the color is always set to RGB(0,0,0), the alpha value takes
-// care of whether or not the pixel shows up.
-//
-// Since the data may arrive in chunks, and many prefixes of valid numbers are
-// themselves valid numbers, this code needs to check to make sure that the
-// value is not truncated. This is done by consuming space after the value
-// read until a ',' or a '}' occurs. In a valid XBM, one of these characters
-// will occur after each value.
-//
-// The checks after strtoul are based on Mozilla's nsXBMDecoder.cpp.
-bool XBMImageDecoder::decodeDatum(uint16_t* result)
-{
- const char* input = m_xbmString.data();
- char* endPtr;
- const uint16_t value = strtoul(&input[m_decodeOffset], &endPtr, 0);
-
- // End of input or couldn't decode anything, can't go any further.
- if (endPtr == &input[m_decodeOffset] || !*endPtr)
- return false;
-
- // Possibly a hex value truncated at "0x". Need more data.
- if (value == 0 && (*endPtr == 'x' || *endPtr == 'X'))
- return false;
-
- // Skip whitespace
- while (*endPtr && isASCIISpace(*endPtr))
- ++endPtr;
-
- // Out of input, don't know what comes next.
- if (!*endPtr)
- return false;
-
- // If the next non-whitespace character is not one of these, it's an error.
- // Every valid entry in the data array needs to be followed by ',' or '}'.
- if (*endPtr != ',' && *endPtr != '}') {
- setFailed();
- return false;
- }
-
- // At this point we have a value.
- *result = value;
-
- // Skip over the decoded value plus the delimiter (',' or '}').
- m_decodeOffset += ((endPtr - &input[m_decodeOffset]) + 1);
- ASSERT(m_decodeOffset <= m_xbmString.size());
-
- return true;
-}
-
-bool XBMImageDecoder::decodeData()
-{
- ASSERT(m_decodeOffset <= m_xbmString.size());
- ASSERT(m_decodedHeader && !m_frameBufferCache.isEmpty());
-
- RGBA32Buffer& frame = m_frameBufferCache[0];
-
- ASSERT(frame.status() == RGBA32Buffer::FramePartial);
-
- const int bitsPerRow = size().width();
-
- ASSERT(m_dataType != Unknown);
-
- while (m_bitsDecoded < (size().width() * size().height())) {
- uint16_t value;
- if (!decodeDatum(&value))
- return false;
-
- int x = m_bitsDecoded % bitsPerRow;
- const int y = m_bitsDecoded / bitsPerRow;
-
- // How many bits will be written?
- const int bits = std::min(bitsPerRow - x, (m_dataType == X11) ? 8 : 16);
-
- // Only the alpha channel matters here, so the color values are always
- // set to 0.
- for (int i = 0; i < bits; ++i)
- frame.setRGBA(x++, y, 0, 0, 0, value & (1 << i) ? 255 : 0);
-
- m_bitsDecoded += bits;
- }
-
- frame.setStatus(RGBA32Buffer::FrameComplete);
-
- return true;
-}
-
-// Decode as much as we can of the XBM file.
-void XBMImageDecoder::decode(bool sizeOnly)
-{
- if (failed())
- return;
-
- bool decodeResult = false;
-
- if (!m_decodedHeader)
- decodeResult = decodeHeader();
-
- if (m_decodedHeader && !sizeOnly)
- decodeResult = decodeData();
-
- // The header or the data could not be decoded, but there is no more
- // data: decoding has failed.
- if (!decodeResult && m_allDataReceived)
- setFailed();
-}
-
-} // namespace WebCore
diff --git a/WebCore/platform/image-decoders/xbm/XBMImageDecoder.h b/WebCore/platform/image-decoders/xbm/XBMImageDecoder.h
deleted file mode 100644
index 00f62ce..0000000
--- a/WebCore/platform/image-decoders/xbm/XBMImageDecoder.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef XBMImageDecoder_h
-#define XBMImageDecoder_h
-
-#include "ImageDecoder.h"
-
-namespace WebCore {
-
- // This class decodes the XBM image format.
- class XBMImageDecoder : public ImageDecoder {
- public:
- XBMImageDecoder();
- virtual ~XBMImageDecoder() {}
-
- virtual String filenameExtension() const { return "xbm"; }
-
- virtual void setData(SharedBuffer* data, bool allDataReceived);
- // Whether or not the size information has been decoded yet.
- virtual bool isSizeAvailable();
- virtual RGBA32Buffer* frameBufferAtIndex(size_t index);
-
- private:
- // Restricts image size to something "reasonable".
- // This protects agains ridiculously large XBMs and prevents bad things
- // like overflow of m_bitsDecoded.
- static const int maxDimension = 65535;
-
- // In X10, an array of type "short" is used to declare the image bits,
- // but in X11, the type is "char".
- enum DataType {
- Unknown,
- X10,
- X11,
- };
-
- bool decodeHeader();
- bool decodeDatum(uint16_t* result);
- bool decodeData();
- void decode(bool sizeOnly);
-
- // FIXME: Copying all the XBM data just so we can NULL-terminate, just
- // so we can use sscanf() and friends, is lame. The decoder should be
- // rewritten to operate on m_data directly.
- Vector<char> m_xbmString; // Null-terminated copy of the XBM data.
- size_t m_decodeOffset; // The current offset in m_xbmString for decoding.
- bool m_allDataReceived;
- bool m_decodedHeader;
- enum DataType m_dataType;
- int m_bitsDecoded;
- };
-
-} // namespace WebCore
-
-#endif
diff --git a/WebCore/platform/image-decoders/zlib/adler32.c b/WebCore/platform/image-decoders/zlib/adler32.c
deleted file mode 100644
index 3c2e944..0000000
--- a/WebCore/platform/image-decoders/zlib/adler32.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/* adler32.c -- compute the Adler-32 checksum of a data stream
- * Copyright (C) 1995-2004 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id: adler32.c,v 3.6 2005/08/04 19:14:14 tor%cs.brown.edu Exp $ */
-
-#define ZLIB_INTERNAL
-#include "zlib.h"
-
-#define BASE 65521UL /* largest prime smaller than 65536 */
-#define NMAX 5552
-/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
-
-#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
-#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
-#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
-#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
-#define DO16(buf) DO8(buf,0); DO8(buf,8);
-
-/* use NO_DIVIDE if your processor does not do division in hardware */
-#ifdef NO_DIVIDE
-# define MOD(a) \
- do { \
- if (a >= (BASE << 16)) a -= (BASE << 16); \
- if (a >= (BASE << 15)) a -= (BASE << 15); \
- if (a >= (BASE << 14)) a -= (BASE << 14); \
- if (a >= (BASE << 13)) a -= (BASE << 13); \
- if (a >= (BASE << 12)) a -= (BASE << 12); \
- if (a >= (BASE << 11)) a -= (BASE << 11); \
- if (a >= (BASE << 10)) a -= (BASE << 10); \
- if (a >= (BASE << 9)) a -= (BASE << 9); \
- if (a >= (BASE << 8)) a -= (BASE << 8); \
- if (a >= (BASE << 7)) a -= (BASE << 7); \
- if (a >= (BASE << 6)) a -= (BASE << 6); \
- if (a >= (BASE << 5)) a -= (BASE << 5); \
- if (a >= (BASE << 4)) a -= (BASE << 4); \
- if (a >= (BASE << 3)) a -= (BASE << 3); \
- if (a >= (BASE << 2)) a -= (BASE << 2); \
- if (a >= (BASE << 1)) a -= (BASE << 1); \
- if (a >= BASE) a -= BASE; \
- } while (0)
-# define MOD4(a) \
- do { \
- if (a >= (BASE << 4)) a -= (BASE << 4); \
- if (a >= (BASE << 3)) a -= (BASE << 3); \
- if (a >= (BASE << 2)) a -= (BASE << 2); \
- if (a >= (BASE << 1)) a -= (BASE << 1); \
- if (a >= BASE) a -= BASE; \
- } while (0)
-#else
-# define MOD(a) a %= BASE
-# define MOD4(a) a %= BASE
-#endif
-
-/* ========================================================================= */
-uLong ZEXPORT adler32(adler, buf, len)
- uLong adler;
- const Bytef *buf;
- uInt len;
-{
- unsigned long sum2;
- unsigned n;
-
- /* split Adler-32 into component sums */
- sum2 = (adler >> 16) & 0xffff;
- adler &= 0xffff;
-
- /* in case user likes doing a byte at a time, keep it fast */
- if (len == 1) {
- adler += buf[0];
- if (adler >= BASE)
- adler -= BASE;
- sum2 += adler;
- if (sum2 >= BASE)
- sum2 -= BASE;
- return adler | (sum2 << 16);
- }
-
- /* initial Adler-32 value (deferred check for len == 1 speed) */
- if (buf == Z_NULL)
- return 1L;
-
- /* in case short lengths are provided, keep it somewhat fast */
- if (len < 16) {
- while (len--) {
- adler += *buf++;
- sum2 += adler;
- }
- if (adler >= BASE)
- adler -= BASE;
- MOD4(sum2); /* only added so many BASE's */
- return adler | (sum2 << 16);
- }
-
- /* do length NMAX blocks -- requires just one modulo operation */
- while (len >= NMAX) {
- len -= NMAX;
- n = NMAX / 16; /* NMAX is divisible by 16 */
- do {
- DO16(buf); /* 16 sums unrolled */
- buf += 16;
- } while (--n);
- MOD(adler);
- MOD(sum2);
- }
-
- /* do remaining bytes (less than NMAX, still just one modulo) */
- if (len) { /* avoid modulos if none remaining */
- while (len >= 16) {
- len -= 16;
- DO16(buf);
- buf += 16;
- }
- while (len--) {
- adler += *buf++;
- sum2 += adler;
- }
- MOD(adler);
- MOD(sum2);
- }
-
- /* return recombined sums */
- return adler | (sum2 << 16);
-}
-
-/* ========================================================================= */
-uLong ZEXPORT adler32_combine(adler1, adler2, len2)
- uLong adler1;
- uLong adler2;
- z_off_t len2;
-{
- unsigned long sum1;
- unsigned long sum2;
- unsigned rem;
-
- /* the derivation of this formula is left as an exercise for the reader */
- rem = (unsigned)(len2 % BASE);
- sum1 = adler1 & 0xffff;
- sum2 = rem * sum1;
- MOD(sum2);
- sum1 += (adler2 & 0xffff) + BASE - 1;
- sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
- if (sum1 > BASE) sum1 -= BASE;
- if (sum1 > BASE) sum1 -= BASE;
- if (sum2 > (BASE << 1)) sum2 -= (BASE << 1);
- if (sum2 > BASE) sum2 -= BASE;
- return sum1 | (sum2 << 16);
-}
diff --git a/WebCore/platform/image-decoders/zlib/compress.c b/WebCore/platform/image-decoders/zlib/compress.c
deleted file mode 100644
index 825cbbc..0000000
--- a/WebCore/platform/image-decoders/zlib/compress.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/* compress.c -- compress a memory buffer
- * Copyright (C) 1995-2003 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id: compress.c,v 3.6 2005/08/04 19:14:14 tor%cs.brown.edu Exp $ */
-
-#define ZLIB_INTERNAL
-#include "zlib.h"
-
-/* ===========================================================================
- Compresses the source buffer into the destination buffer. The level
- parameter has the same meaning as in deflateInit. sourceLen is the byte
- length of the source buffer. Upon entry, destLen is the total size of the
- destination buffer, which must be at least 0.1% larger than sourceLen plus
- 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
-
- compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_BUF_ERROR if there was not enough room in the output buffer,
- Z_STREAM_ERROR if the level parameter is invalid.
-*/
-int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
- Bytef *dest;
- uLongf *destLen;
- const Bytef *source;
- uLong sourceLen;
- int level;
-{
- z_stream stream;
- int err;
-
- stream.next_in = (Bytef*)source;
- stream.avail_in = (uInt)sourceLen;
-#ifdef MAXSEG_64K
- /* Check for source > 64K on 16-bit machine: */
- if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
-#endif
- stream.next_out = dest;
- stream.avail_out = (uInt)*destLen;
- if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
-
- stream.zalloc = (alloc_func)0;
- stream.zfree = (free_func)0;
- stream.opaque = (voidpf)0;
-
- err = deflateInit(&stream, level);
- if (err != Z_OK) return err;
-
- err = deflate(&stream, Z_FINISH);
- if (err != Z_STREAM_END) {
- deflateEnd(&stream);
- return err == Z_OK ? Z_BUF_ERROR : err;
- }
- *destLen = stream.total_out;
-
- err = deflateEnd(&stream);
- return err;
-}
-
-/* ===========================================================================
- */
-int ZEXPORT compress (dest, destLen, source, sourceLen)
- Bytef *dest;
- uLongf *destLen;
- const Bytef *source;
- uLong sourceLen;
-{
- return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
-}
-
-/* ===========================================================================
- If the default memLevel or windowBits for deflateInit() is changed, then
- this function needs to be updated.
- */
-uLong ZEXPORT compressBound (sourceLen)
- uLong sourceLen;
-{
- return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11;
-}
diff --git a/WebCore/platform/image-decoders/zlib/crc32.c b/WebCore/platform/image-decoders/zlib/crc32.c
deleted file mode 100644
index 495863b..0000000
--- a/WebCore/platform/image-decoders/zlib/crc32.c
+++ /dev/null
@@ -1,423 +0,0 @@
-/* crc32.c -- compute the CRC-32 of a data stream
- * Copyright (C) 1995-2005 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- *
- * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
- * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
- * tables for updating the shift register in one step with three exclusive-ors
- * instead of four steps with four exclusive-ors. This results in about a
- * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
- */
-
-/* @(#) $Id: crc32.c,v 3.6 2005/08/04 19:14:14 tor%cs.brown.edu Exp $ */
-
-/*
- Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
- protection on the static variables used to control the first-use generation
- of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
- first call get_crc_table() to initialize the tables before allowing more than
- one thread to use crc32().
- */
-
-#ifdef MAKECRCH
-# include <stdio.h>
-# ifndef DYNAMIC_CRC_TABLE
-# define DYNAMIC_CRC_TABLE
-# endif /* !DYNAMIC_CRC_TABLE */
-#endif /* MAKECRCH */
-
-#include "zutil.h" /* for STDC and FAR definitions */
-
-#define local static
-
-/* Find a four-byte integer type for crc32_little() and crc32_big(). */
-#ifndef NOBYFOUR
-# ifdef STDC /* need ANSI C limits.h to determine sizes */
-# include <limits.h>
-# define BYFOUR
-# if (UINT_MAX == 0xffffffffUL)
- typedef unsigned int u4;
-# else
-# if (ULONG_MAX == 0xffffffffUL)
- typedef unsigned long u4;
-# else
-# if (USHRT_MAX == 0xffffffffUL)
- typedef unsigned short u4;
-# else
-# undef BYFOUR /* can't find a four-byte integer type! */
-# endif
-# endif
-# endif
-# endif /* STDC */
-#endif /* !NOBYFOUR */
-
-/* Definitions for doing the crc four data bytes at a time. */
-#ifdef BYFOUR
-# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \
- (((w)&0xff00)<<8)+(((w)&0xff)<<24))
- local unsigned long crc32_little OF((unsigned long,
- const unsigned char FAR *, unsigned));
- local unsigned long crc32_big OF((unsigned long,
- const unsigned char FAR *, unsigned));
-# define TBLS 8
-#else
-# define TBLS 1
-#endif /* BYFOUR */
-
-/* Local functions for crc concatenation */
-local unsigned long gf2_matrix_times OF((unsigned long *mat,
- unsigned long vec));
-local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
-
-#ifdef DYNAMIC_CRC_TABLE
-
-local volatile int crc_table_empty = 1;
-local unsigned long FAR crc_table[TBLS][256];
-local void make_crc_table OF((void));
-#ifdef MAKECRCH
- local void write_table OF((FILE *, const unsigned long FAR *));
-#endif /* MAKECRCH */
-/*
- Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
- x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
-
- Polynomials over GF(2) are represented in binary, one bit per coefficient,
- with the lowest powers in the most significant bit. Then adding polynomials
- is just exclusive-or, and multiplying a polynomial by x is a right shift by
- one. If we call the above polynomial p, and represent a byte as the
- polynomial q, also with the lowest power in the most significant bit (so the
- byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
- where a mod b means the remainder after dividing a by b.
-
- This calculation is done using the shift-register method of multiplying and
- taking the remainder. The register is initialized to zero, and for each
- incoming bit, x^32 is added mod p to the register if the bit is a one (where
- x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
- x (which is shifting right by one and adding x^32 mod p if the bit shifted
- out is a one). We start with the highest power (least significant bit) of
- q and repeat for all eight bits of q.
-
- The first table is simply the CRC of all possible eight bit values. This is
- all the information needed to generate CRCs on data a byte at a time for all
- combinations of CRC register values and incoming bytes. The remaining tables
- allow for word-at-a-time CRC calculation for both big-endian and little-
- endian machines, where a word is four bytes.
-*/
-local void make_crc_table()
-{
- unsigned long c;
- int n, k;
- unsigned long poly; /* polynomial exclusive-or pattern */
- /* terms of polynomial defining this crc (except x^32): */
- static volatile int first = 1; /* flag to limit concurrent making */
- static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
-
- /* See if another task is already doing this (not thread-safe, but better
- than nothing -- significantly reduces duration of vulnerability in
- case the advice about DYNAMIC_CRC_TABLE is ignored) */
- if (first) {
- first = 0;
-
- /* make exclusive-or pattern from polynomial (0xedb88320UL) */
- poly = 0UL;
- for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
- poly |= 1UL << (31 - p[n]);
-
- /* generate a crc for every 8-bit value */
- for (n = 0; n < 256; n++) {
- c = (unsigned long)n;
- for (k = 0; k < 8; k++)
- c = c & 1 ? poly ^ (c >> 1) : c >> 1;
- crc_table[0][n] = c;
- }
-
-#ifdef BYFOUR
- /* generate crc for each value followed by one, two, and three zeros,
- and then the byte reversal of those as well as the first table */
- for (n = 0; n < 256; n++) {
- c = crc_table[0][n];
- crc_table[4][n] = REV(c);
- for (k = 1; k < 4; k++) {
- c = crc_table[0][c & 0xff] ^ (c >> 8);
- crc_table[k][n] = c;
- crc_table[k + 4][n] = REV(c);
- }
- }
-#endif /* BYFOUR */
-
- crc_table_empty = 0;
- }
- else { /* not first */
- /* wait for the other guy to finish (not efficient, but rare) */
- while (crc_table_empty)
- ;
- }
-
-#ifdef MAKECRCH
- /* write out CRC tables to crc32.h */
- {
- FILE *out;
-
- out = fopen("crc32.h", "w");
- if (out == NULL) return;
- fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
- fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
- fprintf(out, "local const unsigned long FAR ");
- fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
- write_table(out, crc_table[0]);
-# ifdef BYFOUR
- fprintf(out, "#ifdef BYFOUR\n");
- for (k = 1; k < 8; k++) {
- fprintf(out, " },\n {\n");
- write_table(out, crc_table[k]);
- }
- fprintf(out, "#endif\n");
-# endif /* BYFOUR */
- fprintf(out, " }\n};\n");
- fclose(out);
- }
-#endif /* MAKECRCH */
-}
-
-#ifdef MAKECRCH
-local void write_table(out, table)
- FILE *out;
- const unsigned long FAR *table;
-{
- int n;
-
- for (n = 0; n < 256; n++)
- fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n],
- n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
-}
-#endif /* MAKECRCH */
-
-#else /* !DYNAMIC_CRC_TABLE */
-/* ========================================================================
- * Tables of CRC-32s of all single-byte values, made by make_crc_table().
- */
-#include "crc32.h"
-#endif /* DYNAMIC_CRC_TABLE */
-
-/* =========================================================================
- * This function can be used by asm versions of crc32()
- */
-const unsigned long FAR * ZEXPORT get_crc_table()
-{
-#ifdef DYNAMIC_CRC_TABLE
- if (crc_table_empty)
- make_crc_table();
-#endif /* DYNAMIC_CRC_TABLE */
- return (const unsigned long FAR *)crc_table;
-}
-
-/* ========================================================================= */
-#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
-#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
-
-/* ========================================================================= */
-unsigned long ZEXPORT crc32(crc, buf, len)
- unsigned long crc;
- const unsigned char FAR *buf;
- unsigned len;
-{
- if (buf == Z_NULL) return 0UL;
-
-#ifdef DYNAMIC_CRC_TABLE
- if (crc_table_empty)
- make_crc_table();
-#endif /* DYNAMIC_CRC_TABLE */
-
-#ifdef BYFOUR
- if (sizeof(void *) == sizeof(ptrdiff_t)) {
- u4 endian;
-
- endian = 1;
- if (*((unsigned char *)(&endian)))
- return crc32_little(crc, buf, len);
- else
- return crc32_big(crc, buf, len);
- }
-#endif /* BYFOUR */
- crc = crc ^ 0xffffffffUL;
- while (len >= 8) {
- DO8;
- len -= 8;
- }
- if (len) do {
- DO1;
- } while (--len);
- return crc ^ 0xffffffffUL;
-}
-
-#ifdef BYFOUR
-
-/* ========================================================================= */
-#define DOLIT4 c ^= *buf4++; \
- c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
- crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
-#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
-
-/* ========================================================================= */
-local unsigned long crc32_little(crc, buf, len)
- unsigned long crc;
- const unsigned char FAR *buf;
- unsigned len;
-{
- register u4 c;
- register const u4 FAR *buf4;
-
- c = (u4)crc;
- c = ~c;
- while (len && ((ptrdiff_t)buf & 3)) {
- c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
- len--;
- }
-
- buf4 = (const u4 FAR *)(const void FAR *)buf;
- while (len >= 32) {
- DOLIT32;
- len -= 32;
- }
- while (len >= 4) {
- DOLIT4;
- len -= 4;
- }
- buf = (const unsigned char FAR *)buf4;
-
- if (len) do {
- c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
- } while (--len);
- c = ~c;
- return (unsigned long)c;
-}
-
-/* ========================================================================= */
-#define DOBIG4 c ^= *++buf4; \
- c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
- crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
-#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
-
-/* ========================================================================= */
-local unsigned long crc32_big(crc, buf, len)
- unsigned long crc;
- const unsigned char FAR *buf;
- unsigned len;
-{
- register u4 c;
- register const u4 FAR *buf4;
-
- c = REV((u4)crc);
- c = ~c;
- while (len && ((ptrdiff_t)buf & 3)) {
- c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
- len--;
- }
-
- buf4 = (const u4 FAR *)(const void FAR *)buf;
- buf4--;
- while (len >= 32) {
- DOBIG32;
- len -= 32;
- }
- while (len >= 4) {
- DOBIG4;
- len -= 4;
- }
- buf4++;
- buf = (const unsigned char FAR *)buf4;
-
- if (len) do {
- c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
- } while (--len);
- c = ~c;
- return (unsigned long)(REV(c));
-}
-
-#endif /* BYFOUR */
-
-#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */
-
-/* ========================================================================= */
-local unsigned long gf2_matrix_times(mat, vec)
- unsigned long *mat;
- unsigned long vec;
-{
- unsigned long sum;
-
- sum = 0;
- while (vec) {
- if (vec & 1)
- sum ^= *mat;
- vec >>= 1;
- mat++;
- }
- return sum;
-}
-
-/* ========================================================================= */
-local void gf2_matrix_square(square, mat)
- unsigned long *square;
- unsigned long *mat;
-{
- int n;
-
- for (n = 0; n < GF2_DIM; n++)
- square[n] = gf2_matrix_times(mat, mat[n]);
-}
-
-/* ========================================================================= */
-uLong ZEXPORT crc32_combine(crc1, crc2, len2)
- uLong crc1;
- uLong crc2;
- z_off_t len2;
-{
- int n;
- unsigned long row;
- unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */
- unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */
-
- /* degenerate case */
- if (len2 == 0)
- return crc1;
-
- /* put operator for one zero bit in odd */
- odd[0] = 0xedb88320L; /* CRC-32 polynomial */
- row = 1;
- for (n = 1; n < GF2_DIM; n++) {
- odd[n] = row;
- row <<= 1;
- }
-
- /* put operator for two zero bits in even */
- gf2_matrix_square(even, odd);
-
- /* put operator for four zero bits in odd */
- gf2_matrix_square(odd, even);
-
- /* apply len2 zeros to crc1 (first square will put the operator for one
- zero byte, eight zero bits, in even) */
- do {
- /* apply zeros operator for this bit of len2 */
- gf2_matrix_square(even, odd);
- if (len2 & 1)
- crc1 = gf2_matrix_times(even, crc1);
- len2 >>= 1;
-
- /* if no more bits set, then done */
- if (len2 == 0)
- break;
-
- /* another iteration of the loop with odd and even swapped */
- gf2_matrix_square(odd, even);
- if (len2 & 1)
- crc1 = gf2_matrix_times(odd, crc1);
- len2 >>= 1;
-
- /* if no more bits set, then done */
- } while (len2 != 0);
-
- /* return combined crc */
- crc1 ^= crc2;
- return crc1;
-}
diff --git a/WebCore/platform/image-decoders/zlib/crc32.h b/WebCore/platform/image-decoders/zlib/crc32.h
deleted file mode 100644
index 8053b61..0000000
--- a/WebCore/platform/image-decoders/zlib/crc32.h
+++ /dev/null
@@ -1,441 +0,0 @@
-/* crc32.h -- tables for rapid CRC calculation
- * Generated automatically by crc32.c
- */
-
-local const unsigned long FAR crc_table[TBLS][256] =
-{
- {
- 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
- 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
- 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
- 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
- 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
- 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
- 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
- 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
- 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
- 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
- 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
- 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
- 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
- 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
- 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
- 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
- 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
- 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
- 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
- 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
- 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
- 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
- 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
- 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
- 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
- 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
- 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
- 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
- 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
- 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
- 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
- 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
- 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
- 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
- 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
- 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
- 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
- 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
- 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
- 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
- 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
- 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
- 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
- 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
- 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
- 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
- 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
- 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
- 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
- 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
- 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
- 0x2d02ef8dUL
-#ifdef BYFOUR
- },
- {
- 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,
- 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL,
- 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL,
- 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL,
- 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL,
- 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL,
- 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL,
- 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL,
- 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL,
- 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL,
- 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL,
- 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL,
- 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL,
- 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL,
- 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL,
- 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL,
- 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL,
- 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL,
- 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL,
- 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL,
- 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL,
- 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL,
- 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL,
- 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL,
- 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL,
- 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL,
- 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL,
- 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL,
- 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL,
- 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL,
- 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL,
- 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL,
- 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL,
- 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL,
- 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL,
- 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL,
- 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL,
- 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL,
- 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL,
- 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL,
- 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL,
- 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL,
- 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL,
- 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL,
- 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL,
- 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL,
- 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL,
- 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL,
- 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL,
- 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL,
- 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL,
- 0x9324fd72UL
- },
- {
- 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL,
- 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL,
- 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL,
- 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL,
- 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL,
- 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL,
- 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL,
- 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL,
- 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL,
- 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL,
- 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL,
- 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL,
- 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL,
- 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL,
- 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL,
- 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL,
- 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL,
- 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL,
- 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL,
- 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL,
- 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL,
- 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL,
- 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL,
- 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL,
- 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL,
- 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL,
- 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL,
- 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL,
- 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL,
- 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL,
- 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL,
- 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL,
- 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL,
- 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL,
- 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL,
- 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL,
- 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL,
- 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL,
- 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL,
- 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL,
- 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL,
- 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL,
- 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL,
- 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL,
- 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL,
- 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL,
- 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL,
- 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL,
- 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL,
- 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL,
- 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL,
- 0xbe9834edUL
- },
- {
- 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL,
- 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL,
- 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL,
- 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL,
- 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL,
- 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL,
- 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL,
- 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL,
- 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL,
- 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL,
- 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL,
- 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL,
- 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL,
- 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL,
- 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL,
- 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL,
- 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL,
- 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL,
- 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL,
- 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL,
- 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL,
- 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL,
- 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL,
- 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL,
- 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL,
- 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL,
- 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL,
- 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL,
- 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL,
- 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL,
- 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL,
- 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL,
- 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL,
- 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL,
- 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL,
- 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL,
- 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL,
- 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL,
- 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL,
- 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL,
- 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL,
- 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL,
- 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL,
- 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL,
- 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL,
- 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL,
- 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL,
- 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL,
- 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL,
- 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL,
- 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL,
- 0xde0506f1UL
- },
- {
- 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL,
- 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL,
- 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL,
- 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL,
- 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL,
- 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL,
- 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL,
- 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL,
- 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL,
- 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL,
- 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL,
- 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL,
- 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL,
- 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL,
- 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL,
- 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL,
- 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL,
- 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL,
- 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL,
- 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL,
- 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL,
- 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL,
- 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL,
- 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL,
- 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL,
- 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL,
- 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL,
- 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL,
- 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL,
- 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL,
- 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL,
- 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL,
- 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL,
- 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL,
- 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL,
- 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL,
- 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL,
- 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL,
- 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL,
- 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL,
- 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL,
- 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL,
- 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL,
- 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL,
- 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL,
- 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL,
- 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL,
- 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL,
- 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL,
- 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL,
- 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL,
- 0x8def022dUL
- },
- {
- 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL,
- 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL,
- 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL,
- 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL,
- 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL,
- 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL,
- 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL,
- 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL,
- 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL,
- 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL,
- 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL,
- 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL,
- 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL,
- 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL,
- 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL,
- 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL,
- 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL,
- 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL,
- 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL,
- 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL,
- 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL,
- 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL,
- 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL,
- 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL,
- 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL,
- 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL,
- 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL,
- 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL,
- 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL,
- 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL,
- 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL,
- 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL,
- 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL,
- 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL,
- 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL,
- 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL,
- 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL,
- 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL,
- 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL,
- 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL,
- 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL,
- 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL,
- 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL,
- 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL,
- 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL,
- 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL,
- 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL,
- 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL,
- 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL,
- 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL,
- 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL,
- 0x72fd2493UL
- },
- {
- 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL,
- 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL,
- 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL,
- 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL,
- 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL,
- 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL,
- 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL,
- 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL,
- 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL,
- 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL,
- 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL,
- 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL,
- 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL,
- 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL,
- 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL,
- 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL,
- 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL,
- 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL,
- 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL,
- 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL,
- 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL,
- 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL,
- 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL,
- 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL,
- 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL,
- 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL,
- 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL,
- 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL,
- 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL,
- 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL,
- 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL,
- 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL,
- 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL,
- 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL,
- 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL,
- 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL,
- 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL,
- 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL,
- 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL,
- 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL,
- 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL,
- 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL,
- 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL,
- 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL,
- 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL,
- 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL,
- 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL,
- 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL,
- 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL,
- 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL,
- 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL,
- 0xed3498beUL
- },
- {
- 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL,
- 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL,
- 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL,
- 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL,
- 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL,
- 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL,
- 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL,
- 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL,
- 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL,
- 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL,
- 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL,
- 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL,
- 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL,
- 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL,
- 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL,
- 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL,
- 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL,
- 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL,
- 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL,
- 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL,
- 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL,
- 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL,
- 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL,
- 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL,
- 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL,
- 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL,
- 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL,
- 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL,
- 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL,
- 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL,
- 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL,
- 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL,
- 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL,
- 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL,
- 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL,
- 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL,
- 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL,
- 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL,
- 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL,
- 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL,
- 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL,
- 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL,
- 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL,
- 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL,
- 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL,
- 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL,
- 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL,
- 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL,
- 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL,
- 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,
- 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,
- 0xf10605deUL
-#endif
- }
-};
diff --git a/WebCore/platform/image-decoders/zlib/deflate.c b/WebCore/platform/image-decoders/zlib/deflate.c
deleted file mode 100644
index 46a51fe..0000000
--- a/WebCore/platform/image-decoders/zlib/deflate.c
+++ /dev/null
@@ -1,1736 +0,0 @@
-/* deflate.c -- compress data using the deflation algorithm
- * Copyright (C) 1995-2005 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/*
- * ALGORITHM
- *
- * The "deflation" process depends on being able to identify portions
- * of the input text which are identical to earlier input (within a
- * sliding window trailing behind the input currently being processed).
- *
- * The most straightforward technique turns out to be the fastest for
- * most input files: try all possible matches and select the longest.
- * The key feature of this algorithm is that insertions into the string
- * dictionary are very simple and thus fast, and deletions are avoided
- * completely. Insertions are performed at each input character, whereas
- * string matches are performed only when the previous match ends. So it
- * is preferable to spend more time in matches to allow very fast string
- * insertions and avoid deletions. The matching algorithm for small
- * strings is inspired from that of Rabin & Karp. A brute force approach
- * is used to find longer strings when a small match has been found.
- * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
- * (by Leonid Broukhis).
- * A previous version of this file used a more sophisticated algorithm
- * (by Fiala and Greene) which is guaranteed to run in linear amortized
- * time, but has a larger average cost, uses more memory and is patented.
- * However the F&G algorithm may be faster for some highly redundant
- * files if the parameter max_chain_length (described below) is too large.
- *
- * ACKNOWLEDGEMENTS
- *
- * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
- * I found it in 'freeze' written by Leonid Broukhis.
- * Thanks to many people for bug reports and testing.
- *
- * REFERENCES
- *
- * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
- * Available in http://www.ietf.org/rfc/rfc1951.txt
- *
- * A description of the Rabin and Karp algorithm is given in the book
- * "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
- *
- * Fiala,E.R., and Greene,D.H.
- * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
- *
- */
-
-/* @(#) $Id: deflate.c,v 3.6 2005/08/04 19:14:14 tor%cs.brown.edu Exp $ */
-
-#include "deflate.h"
-
-const char deflate_copyright[] =
- " deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly ";
-/*
- If you use the zlib library in a product, an acknowledgment is welcome
- in the documentation of your product. If for some reason you cannot
- include such an acknowledgment, I would appreciate that you keep this
- copyright string in the executable of your product.
- */
-
-/* ===========================================================================
- * Function prototypes.
- */
-typedef enum {
- need_more, /* block not completed, need more input or more output */
- block_done, /* block flush performed */
- finish_started, /* finish started, need only more output at next deflate */
- finish_done /* finish done, accept no more input or output */
-} block_state;
-
-typedef block_state (*compress_func) OF((deflate_state *s, int flush));
-/* Compression function. Returns the block state after the call. */
-
-local void fill_window OF((deflate_state *s));
-local block_state deflate_stored OF((deflate_state *s, int flush));
-local block_state deflate_fast OF((deflate_state *s, int flush));
-#ifndef FASTEST
-local block_state deflate_slow OF((deflate_state *s, int flush));
-#endif
-local void lm_init OF((deflate_state *s));
-local void putShortMSB OF((deflate_state *s, uInt b));
-local void flush_pending OF((z_streamp strm));
-local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
-#ifndef FASTEST
-#ifdef ASMV
- void match_init OF((void)); /* asm code initialization */
- uInt longest_match OF((deflate_state *s, IPos cur_match));
-#else
-local uInt longest_match OF((deflate_state *s, IPos cur_match));
-#endif
-#endif
-local uInt longest_match_fast OF((deflate_state *s, IPos cur_match));
-
-#ifdef DEBUG
-local void check_match OF((deflate_state *s, IPos start, IPos match,
- int length));
-#endif
-
-/* ===========================================================================
- * Local data
- */
-
-#define NIL 0
-/* Tail of hash chains */
-
-#ifndef TOO_FAR
-# define TOO_FAR 4096
-#endif
-/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
-
-#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
-/* Minimum amount of lookahead, except at the end of the input file.
- * See deflate.c for comments about the MIN_MATCH+1.
- */
-
-/* Values for max_lazy_match, good_match and max_chain_length, depending on
- * the desired pack level (0..9). The values given below have been tuned to
- * exclude worst case performance for pathological files. Better values may be
- * found for specific files.
- */
-typedef struct config_s {
- ush good_length; /* reduce lazy search above this match length */
- ush max_lazy; /* do not perform lazy search above this match length */
- ush nice_length; /* quit search above this match length */
- ush max_chain;
- compress_func func;
-} config;
-
-#ifdef FASTEST
-local const config configuration_table[2] = {
-/* good lazy nice chain */
-/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
-/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */
-#else
-local const config configuration_table[10] = {
-/* good lazy nice chain */
-/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
-/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */
-/* 2 */ {4, 5, 16, 8, deflate_fast},
-/* 3 */ {4, 6, 32, 32, deflate_fast},
-
-/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
-/* 5 */ {8, 16, 32, 32, deflate_slow},
-/* 6 */ {8, 16, 128, 128, deflate_slow},
-/* 7 */ {8, 32, 128, 256, deflate_slow},
-/* 8 */ {32, 128, 258, 1024, deflate_slow},
-/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */
-#endif
-
-/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
- * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
- * meaning.
- */
-
-#define EQUAL 0
-/* result of memcmp for equal strings */
-
-#ifndef NO_DUMMY_DECL
-struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
-#endif
-
-/* ===========================================================================
- * Update a hash value with the given input byte
- * IN assertion: all calls to to UPDATE_HASH are made with consecutive
- * input characters, so that a running hash key can be computed from the
- * previous key instead of complete recalculation each time.
- */
-#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
-
-
-/* ===========================================================================
- * Insert string str in the dictionary and set match_head to the previous head
- * of the hash chain (the most recent string with same hash key). Return
- * the previous length of the hash chain.
- * If this file is compiled with -DFASTEST, the compression level is forced
- * to 1, and no hash chains are maintained.
- * IN assertion: all calls to to INSERT_STRING are made with consecutive
- * input characters and the first MIN_MATCH bytes of str are valid
- * (except for the last MIN_MATCH-1 bytes of the input file).
- */
-#ifdef FASTEST
-#define INSERT_STRING(s, str, match_head) \
- (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
- match_head = s->head[s->ins_h], \
- s->head[s->ins_h] = (Pos)(str))
-#else
-#define INSERT_STRING(s, str, match_head) \
- (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
- match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \
- s->head[s->ins_h] = (Pos)(str))
-#endif
-
-/* ===========================================================================
- * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
- * prev[] will be initialized on the fly.
- */
-#define CLEAR_HASH(s) \
- s->head[s->hash_size-1] = NIL; \
- zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
-
-/* ========================================================================= */
-int ZEXPORT deflateInit_(strm, level, version, stream_size)
- z_streamp strm;
- int level;
- const char *version;
- int stream_size;
-{
- return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
- Z_DEFAULT_STRATEGY, version, stream_size);
- /* To do: ignore strm->next_in if we use it as window */
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
- version, stream_size)
- z_streamp strm;
- int level;
- int method;
- int windowBits;
- int memLevel;
- int strategy;
- const char *version;
- int stream_size;
-{
- deflate_state *s;
- int wrap = 1;
- static const char my_version[] = ZLIB_VERSION;
-
- ushf *overlay;
- /* We overlay pending_buf and d_buf+l_buf. This works since the average
- * output size for (length,distance) codes is <= 24 bits.
- */
-
- if (version == Z_NULL || version[0] != my_version[0] ||
- stream_size != sizeof(z_stream)) {
- return Z_VERSION_ERROR;
- }
- if (strm == Z_NULL) return Z_STREAM_ERROR;
-
- strm->msg = Z_NULL;
- if (strm->zalloc == (alloc_func)0) {
- strm->zalloc = zcalloc;
- strm->opaque = (voidpf)0;
- }
- if (strm->zfree == (free_func)0) strm->zfree = zcfree;
-
-#ifdef FASTEST
- if (level != 0) level = 1;
-#else
- if (level == Z_DEFAULT_COMPRESSION) level = 6;
-#endif
-
- if (windowBits < 0) { /* suppress zlib wrapper */
- wrap = 0;
- windowBits = -windowBits;
- }
-#ifdef GZIP
- else if (windowBits > 15) {
- wrap = 2; /* write gzip wrapper instead */
- windowBits -= 16;
- }
-#endif
- if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
- windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
- strategy < 0 || strategy > Z_FIXED) {
- return Z_STREAM_ERROR;
- }
- if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */
- s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
- if (s == Z_NULL) return Z_MEM_ERROR;
- strm->state = (struct internal_state FAR *)s;
- s->strm = strm;
-
- s->wrap = wrap;
- s->gzhead = Z_NULL;
- s->w_bits = windowBits;
- s->w_size = 1 << s->w_bits;
- s->w_mask = s->w_size - 1;
-
- s->hash_bits = memLevel + 7;
- s->hash_size = 1 << s->hash_bits;
- s->hash_mask = s->hash_size - 1;
- s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
-
- s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
- s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
- s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
-
- s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
-
- overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
- s->pending_buf = (uchf *) overlay;
- s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
-
- if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
- s->pending_buf == Z_NULL) {
- s->status = FINISH_STATE;
- strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
- deflateEnd (strm);
- return Z_MEM_ERROR;
- }
- s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
- s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
-
- s->level = level;
- s->strategy = strategy;
- s->method = (Byte)method;
-
- return deflateReset(strm);
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
- z_streamp strm;
- const Bytef *dictionary;
- uInt dictLength;
-{
- deflate_state *s;
- uInt length = dictLength;
- uInt n;
- IPos hash_head = 0;
-
- if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
- strm->state->wrap == 2 ||
- (strm->state->wrap == 1 && strm->state->status != INIT_STATE))
- return Z_STREAM_ERROR;
-
- s = strm->state;
- if (s->wrap)
- strm->adler = adler32(strm->adler, dictionary, dictLength);
-
- if (length < MIN_MATCH) return Z_OK;
- if (length > MAX_DIST(s)) {
- length = MAX_DIST(s);
- dictionary += dictLength - length; /* use the tail of the dictionary */
- }
- zmemcpy(s->window, dictionary, length);
- s->strstart = length;
- s->block_start = (long)length;
-
- /* Insert all strings in the hash table (except for the last two bytes).
- * s->lookahead stays null, so s->ins_h will be recomputed at the next
- * call of fill_window.
- */
- s->ins_h = s->window[0];
- UPDATE_HASH(s, s->ins_h, s->window[1]);
- for (n = 0; n <= length - MIN_MATCH; n++) {
- INSERT_STRING(s, n, hash_head);
- }
- if (hash_head) hash_head = 0; /* to make compiler happy */
- return Z_OK;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateReset (strm)
- z_streamp strm;
-{
- deflate_state *s;
-
- if (strm == Z_NULL || strm->state == Z_NULL ||
- strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) {
- return Z_STREAM_ERROR;
- }
-
- strm->total_in = strm->total_out = 0;
- strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
- strm->data_type = Z_UNKNOWN;
-
- s = (deflate_state *)strm->state;
- s->pending = 0;
- s->pending_out = s->pending_buf;
-
- if (s->wrap < 0) {
- s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
- }
- s->status = s->wrap ? INIT_STATE : BUSY_STATE;
- strm->adler =
-#ifdef GZIP
- s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
-#endif
- adler32(0L, Z_NULL, 0);
- s->last_flush = Z_NO_FLUSH;
-
- _tr_init(s);
- lm_init(s);
-
- return Z_OK;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateSetHeader (strm, head)
- z_streamp strm;
- gz_headerp head;
-{
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- if (strm->state->wrap != 2) return Z_STREAM_ERROR;
- strm->state->gzhead = head;
- return Z_OK;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflatePrime (strm, bits, value)
- z_streamp strm;
- int bits;
- int value;
-{
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- strm->state->bi_valid = bits;
- strm->state->bi_buf = (ush)(value & ((1 << bits) - 1));
- return Z_OK;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateParams(strm, level, strategy)
- z_streamp strm;
- int level;
- int strategy;
-{
- deflate_state *s;
- compress_func func;
- int err = Z_OK;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- s = strm->state;
-
-#ifdef FASTEST
- if (level != 0) level = 1;
-#else
- if (level == Z_DEFAULT_COMPRESSION) level = 6;
-#endif
- if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
- return Z_STREAM_ERROR;
- }
- func = configuration_table[s->level].func;
-
- if (func != configuration_table[level].func && strm->total_in != 0) {
- /* Flush the last buffer: */
- err = deflate(strm, Z_PARTIAL_FLUSH);
- }
- if (s->level != level) {
- s->level = level;
- s->max_lazy_match = configuration_table[level].max_lazy;
- s->good_match = configuration_table[level].good_length;
- s->nice_match = configuration_table[level].nice_length;
- s->max_chain_length = configuration_table[level].max_chain;
- }
- s->strategy = strategy;
- return err;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
- z_streamp strm;
- int good_length;
- int max_lazy;
- int nice_length;
- int max_chain;
-{
- deflate_state *s;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- s = strm->state;
- s->good_match = good_length;
- s->max_lazy_match = max_lazy;
- s->nice_match = nice_length;
- s->max_chain_length = max_chain;
- return Z_OK;
-}
-
-/* =========================================================================
- * For the default windowBits of 15 and memLevel of 8, this function returns
- * a close to exact, as well as small, upper bound on the compressed size.
- * They are coded as constants here for a reason--if the #define's are
- * changed, then this function needs to be changed as well. The return
- * value for 15 and 8 only works for those exact settings.
- *
- * For any setting other than those defaults for windowBits and memLevel,
- * the value returned is a conservative worst case for the maximum expansion
- * resulting from using fixed blocks instead of stored blocks, which deflate
- * can emit on compressed data for some combinations of the parameters.
- *
- * This function could be more sophisticated to provide closer upper bounds
- * for every combination of windowBits and memLevel, as well as wrap.
- * But even the conservative upper bound of about 14% expansion does not
- * seem onerous for output buffer allocation.
- */
-uLong ZEXPORT deflateBound(strm, sourceLen)
- z_streamp strm;
- uLong sourceLen;
-{
- deflate_state *s;
- uLong destLen;
-
- /* conservative upper bound */
- destLen = sourceLen +
- ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11;
-
- /* if can't get parameters, return conservative bound */
- if (strm == Z_NULL || strm->state == Z_NULL)
- return destLen;
-
- /* if not default parameters, return conservative bound */
- s = strm->state;
- if (s->w_bits != 15 || s->hash_bits != 8 + 7)
- return destLen;
-
- /* default settings: return tight bound for that case */
- return compressBound(sourceLen);
-}
-
-/* =========================================================================
- * Put a short in the pending buffer. The 16-bit value is put in MSB order.
- * IN assertion: the stream state is correct and there is enough room in
- * pending_buf.
- */
-local void putShortMSB (s, b)
- deflate_state *s;
- uInt b;
-{
- put_byte(s, (Byte)(b >> 8));
- put_byte(s, (Byte)(b & 0xff));
-}
-
-/* =========================================================================
- * Flush as much pending output as possible. All deflate() output goes
- * through this function so some applications may wish to modify it
- * to avoid allocating a large strm->next_out buffer and copying into it.
- * (See also read_buf()).
- */
-local void flush_pending(strm)
- z_streamp strm;
-{
- unsigned len = strm->state->pending;
-
- if (len > strm->avail_out) len = strm->avail_out;
- if (len == 0) return;
-
- zmemcpy(strm->next_out, strm->state->pending_out, len);
- strm->next_out += len;
- strm->state->pending_out += len;
- strm->total_out += len;
- strm->avail_out -= len;
- strm->state->pending -= len;
- if (strm->state->pending == 0) {
- strm->state->pending_out = strm->state->pending_buf;
- }
-}
-
-/* ========================================================================= */
-int ZEXPORT deflate (strm, flush)
- z_streamp strm;
- int flush;
-{
- int old_flush; /* value of flush param for previous deflate call */
- deflate_state *s;
-
- if (strm == Z_NULL || strm->state == Z_NULL ||
- flush > Z_FINISH || flush < 0) {
- return Z_STREAM_ERROR;
- }
- s = strm->state;
-
- if (strm->next_out == Z_NULL ||
- (strm->next_in == Z_NULL && strm->avail_in != 0) ||
- (s->status == FINISH_STATE && flush != Z_FINISH)) {
- ERR_RETURN(strm, Z_STREAM_ERROR);
- }
- if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
-
- s->strm = strm; /* just in case */
- old_flush = s->last_flush;
- s->last_flush = flush;
-
- /* Write the header */
- if (s->status == INIT_STATE) {
-#ifdef GZIP
- if (s->wrap == 2) {
- strm->adler = crc32(0L, Z_NULL, 0);
- put_byte(s, 31);
- put_byte(s, 139);
- put_byte(s, 8);
- if (s->gzhead == NULL) {
- put_byte(s, 0);
- put_byte(s, 0);
- put_byte(s, 0);
- put_byte(s, 0);
- put_byte(s, 0);
- put_byte(s, s->level == 9 ? 2 :
- (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
- 4 : 0));
- put_byte(s, OS_CODE);
- s->status = BUSY_STATE;
- }
- else {
- put_byte(s, (s->gzhead->text ? 1 : 0) +
- (s->gzhead->hcrc ? 2 : 0) +
- (s->gzhead->extra == Z_NULL ? 0 : 4) +
- (s->gzhead->name == Z_NULL ? 0 : 8) +
- (s->gzhead->comment == Z_NULL ? 0 : 16)
- );
- put_byte(s, (Byte)(s->gzhead->time & 0xff));
- put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff));
- put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff));
- put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff));
- put_byte(s, s->level == 9 ? 2 :
- (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
- 4 : 0));
- put_byte(s, s->gzhead->os & 0xff);
- if (s->gzhead->extra != NULL) {
- put_byte(s, s->gzhead->extra_len & 0xff);
- put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
- }
- if (s->gzhead->hcrc)
- strm->adler = crc32(strm->adler, s->pending_buf,
- s->pending);
- s->gzindex = 0;
- s->status = EXTRA_STATE;
- }
- }
- else
-#endif
- {
- uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
- uInt level_flags;
-
- if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
- level_flags = 0;
- else if (s->level < 6)
- level_flags = 1;
- else if (s->level == 6)
- level_flags = 2;
- else
- level_flags = 3;
- header |= (level_flags << 6);
- if (s->strstart != 0) header |= PRESET_DICT;
- header += 31 - (header % 31);
-
- s->status = BUSY_STATE;
- putShortMSB(s, header);
-
- /* Save the adler32 of the preset dictionary: */
- if (s->strstart != 0) {
- putShortMSB(s, (uInt)(strm->adler >> 16));
- putShortMSB(s, (uInt)(strm->adler & 0xffff));
- }
- strm->adler = adler32(0L, Z_NULL, 0);
- }
- }
-#ifdef GZIP
- if (s->status == EXTRA_STATE) {
- if (s->gzhead->extra != NULL) {
- uInt beg = s->pending; /* start of bytes to update crc */
-
- while (s->gzindex < (s->gzhead->extra_len & 0xffff)) {
- if (s->pending == s->pending_buf_size) {
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- flush_pending(strm);
- beg = s->pending;
- if (s->pending == s->pending_buf_size)
- break;
- }
- put_byte(s, s->gzhead->extra[s->gzindex]);
- s->gzindex++;
- }
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- if (s->gzindex == s->gzhead->extra_len) {
- s->gzindex = 0;
- s->status = NAME_STATE;
- }
- }
- else
- s->status = NAME_STATE;
- }
- if (s->status == NAME_STATE) {
- if (s->gzhead->name != NULL) {
- uInt beg = s->pending; /* start of bytes to update crc */
- int val;
-
- do {
- if (s->pending == s->pending_buf_size) {
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- flush_pending(strm);
- beg = s->pending;
- if (s->pending == s->pending_buf_size) {
- val = 1;
- break;
- }
- }
- val = s->gzhead->name[s->gzindex++];
- put_byte(s, val);
- } while (val != 0);
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- if (val == 0) {
- s->gzindex = 0;
- s->status = COMMENT_STATE;
- }
- }
- else
- s->status = COMMENT_STATE;
- }
- if (s->status == COMMENT_STATE) {
- if (s->gzhead->comment != NULL) {
- uInt beg = s->pending; /* start of bytes to update crc */
- int val;
-
- do {
- if (s->pending == s->pending_buf_size) {
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- flush_pending(strm);
- beg = s->pending;
- if (s->pending == s->pending_buf_size) {
- val = 1;
- break;
- }
- }
- val = s->gzhead->comment[s->gzindex++];
- put_byte(s, val);
- } while (val != 0);
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- if (val == 0)
- s->status = HCRC_STATE;
- }
- else
- s->status = HCRC_STATE;
- }
- if (s->status == HCRC_STATE) {
- if (s->gzhead->hcrc) {
- if (s->pending + 2 > s->pending_buf_size)
- flush_pending(strm);
- if (s->pending + 2 <= s->pending_buf_size) {
- put_byte(s, (Byte)(strm->adler & 0xff));
- put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
- strm->adler = crc32(0L, Z_NULL, 0);
- s->status = BUSY_STATE;
- }
- }
- else
- s->status = BUSY_STATE;
- }
-#endif
-
- /* Flush as much pending output as possible */
- if (s->pending != 0) {
- flush_pending(strm);
- if (strm->avail_out == 0) {
- /* Since avail_out is 0, deflate will be called again with
- * more output space, but possibly with both pending and
- * avail_in equal to zero. There won't be anything to do,
- * but this is not an error situation so make sure we
- * return OK instead of BUF_ERROR at next call of deflate:
- */
- s->last_flush = -1;
- return Z_OK;
- }
-
- /* Make sure there is something to do and avoid duplicate consecutive
- * flushes. For repeated and useless calls with Z_FINISH, we keep
- * returning Z_STREAM_END instead of Z_BUF_ERROR.
- */
- } else if (strm->avail_in == 0 && flush <= old_flush &&
- flush != Z_FINISH) {
- ERR_RETURN(strm, Z_BUF_ERROR);
- }
-
- /* User must not provide more input after the first FINISH: */
- if (s->status == FINISH_STATE && strm->avail_in != 0) {
- ERR_RETURN(strm, Z_BUF_ERROR);
- }
-
- /* Start a new block or continue the current one.
- */
- if (strm->avail_in != 0 || s->lookahead != 0 ||
- (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
- block_state bstate;
-
- bstate = (*(configuration_table[s->level].func))(s, flush);
-
- if (bstate == finish_started || bstate == finish_done) {
- s->status = FINISH_STATE;
- }
- if (bstate == need_more || bstate == finish_started) {
- if (strm->avail_out == 0) {
- s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
- }
- return Z_OK;
- /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
- * of deflate should use the same flush parameter to make sure
- * that the flush is complete. So we don't have to output an
- * empty block here, this will be done at next call. This also
- * ensures that for a very small output buffer, we emit at most
- * one empty block.
- */
- }
- if (bstate == block_done) {
- if (flush == Z_PARTIAL_FLUSH) {
- _tr_align(s);
- } else { /* FULL_FLUSH or SYNC_FLUSH */
- _tr_stored_block(s, (char*)0, 0L, 0);
- /* For a full flush, this empty block will be recognized
- * as a special marker by inflate_sync().
- */
- if (flush == Z_FULL_FLUSH) {
- CLEAR_HASH(s); /* forget history */
- }
- }
- flush_pending(strm);
- if (strm->avail_out == 0) {
- s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
- return Z_OK;
- }
- }
- }
- Assert(strm->avail_out > 0, "bug2");
-
- if (flush != Z_FINISH) return Z_OK;
- if (s->wrap <= 0) return Z_STREAM_END;
-
- /* Write the trailer */
-#ifdef GZIP
- if (s->wrap == 2) {
- put_byte(s, (Byte)(strm->adler & 0xff));
- put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
- put_byte(s, (Byte)((strm->adler >> 16) & 0xff));
- put_byte(s, (Byte)((strm->adler >> 24) & 0xff));
- put_byte(s, (Byte)(strm->total_in & 0xff));
- put_byte(s, (Byte)((strm->total_in >> 8) & 0xff));
- put_byte(s, (Byte)((strm->total_in >> 16) & 0xff));
- put_byte(s, (Byte)((strm->total_in >> 24) & 0xff));
- }
- else
-#endif
- {
- putShortMSB(s, (uInt)(strm->adler >> 16));
- putShortMSB(s, (uInt)(strm->adler & 0xffff));
- }
- flush_pending(strm);
- /* If avail_out is zero, the application will call deflate again
- * to flush the rest.
- */
- if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */
- return s->pending != 0 ? Z_OK : Z_STREAM_END;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateEnd (strm)
- z_streamp strm;
-{
- int status;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
-
- status = strm->state->status;
- if (status != INIT_STATE &&
- status != EXTRA_STATE &&
- status != NAME_STATE &&
- status != COMMENT_STATE &&
- status != HCRC_STATE &&
- status != BUSY_STATE &&
- status != FINISH_STATE) {
- return Z_STREAM_ERROR;
- }
-
- /* Deallocate in reverse order of allocations: */
- TRY_FREE(strm, strm->state->pending_buf);
- TRY_FREE(strm, strm->state->head);
- TRY_FREE(strm, strm->state->prev);
- TRY_FREE(strm, strm->state->window);
-
- ZFREE(strm, strm->state);
- strm->state = Z_NULL;
-
- return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
-}
-
-/* =========================================================================
- * Copy the source state to the destination state.
- * To simplify the source, this is not supported for 16-bit MSDOS (which
- * doesn't have enough memory anyway to duplicate compression states).
- */
-int ZEXPORT deflateCopy (dest, source)
- z_streamp dest;
- z_streamp source;
-{
-#ifdef MAXSEG_64K
- return Z_STREAM_ERROR;
-#else
- deflate_state *ds;
- deflate_state *ss;
- ushf *overlay;
-
-
- if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
- return Z_STREAM_ERROR;
- }
-
- ss = source->state;
-
- zmemcpy(dest, source, sizeof(z_stream));
-
- ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
- if (ds == Z_NULL) return Z_MEM_ERROR;
- dest->state = (struct internal_state FAR *) ds;
- zmemcpy(ds, ss, sizeof(deflate_state));
- ds->strm = dest;
-
- ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
- ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
- ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
- overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
- ds->pending_buf = (uchf *) overlay;
-
- if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
- ds->pending_buf == Z_NULL) {
- deflateEnd (dest);
- return Z_MEM_ERROR;
- }
- /* following zmemcpy do not work for 16-bit MSDOS */
- zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
- zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
- zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
- zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
-
- ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
- ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
- ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
-
- ds->l_desc.dyn_tree = ds->dyn_ltree;
- ds->d_desc.dyn_tree = ds->dyn_dtree;
- ds->bl_desc.dyn_tree = ds->bl_tree;
-
- return Z_OK;
-#endif /* MAXSEG_64K */
-}
-
-/* ===========================================================================
- * Read a new buffer from the current input stream, update the adler32
- * and total number of bytes read. All deflate() input goes through
- * this function so some applications may wish to modify it to avoid
- * allocating a large strm->next_in buffer and copying from it.
- * (See also flush_pending()).
- */
-local int read_buf(strm, buf, size)
- z_streamp strm;
- Bytef *buf;
- unsigned size;
-{
- unsigned len = strm->avail_in;
-
- if (len > size) len = size;
- if (len == 0) return 0;
-
- strm->avail_in -= len;
-
- if (strm->state->wrap == 1) {
- strm->adler = adler32(strm->adler, strm->next_in, len);
- }
-#ifdef GZIP
- else if (strm->state->wrap == 2) {
- strm->adler = crc32(strm->adler, strm->next_in, len);
- }
-#endif
- zmemcpy(buf, strm->next_in, len);
- strm->next_in += len;
- strm->total_in += len;
-
- return (int)len;
-}
-
-/* ===========================================================================
- * Initialize the "longest match" routines for a new zlib stream
- */
-local void lm_init (s)
- deflate_state *s;
-{
- s->window_size = (ulg)2L*s->w_size;
-
- CLEAR_HASH(s);
-
- /* Set the default configuration parameters:
- */
- s->max_lazy_match = configuration_table[s->level].max_lazy;
- s->good_match = configuration_table[s->level].good_length;
- s->nice_match = configuration_table[s->level].nice_length;
- s->max_chain_length = configuration_table[s->level].max_chain;
-
- s->strstart = 0;
- s->block_start = 0L;
- s->lookahead = 0;
- s->match_length = s->prev_length = MIN_MATCH-1;
- s->match_available = 0;
- s->ins_h = 0;
-#ifndef FASTEST
-#ifdef ASMV
- match_init(); /* initialize the asm code */
-#endif
-#endif
-}
-
-#ifndef FASTEST
-/* ===========================================================================
- * Set match_start to the longest match starting at the given string and
- * return its length. Matches shorter or equal to prev_length are discarded,
- * in which case the result is equal to prev_length and match_start is
- * garbage.
- * IN assertions: cur_match is the head of the hash chain for the current
- * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
- * OUT assertion: the match length is not greater than s->lookahead.
- */
-#ifndef ASMV
-/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
- * match.S. The code will be functionally equivalent.
- */
-local uInt longest_match(s, cur_match)
- deflate_state *s;
- IPos cur_match; /* current match */
-{
- unsigned chain_length = s->max_chain_length;/* max hash chain length */
- register Bytef *scan = s->window + s->strstart; /* current string */
- register Bytef *match; /* matched string */
- register int len; /* length of current match */
- int best_len = s->prev_length; /* best match length so far */
- int nice_match = s->nice_match; /* stop if match long enough */
- IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
- s->strstart - (IPos)MAX_DIST(s) : NIL;
- /* Stop when cur_match becomes <= limit. To simplify the code,
- * we prevent matches with the string of window index 0.
- */
- Posf *prev = s->prev;
- uInt wmask = s->w_mask;
-
-#ifdef UNALIGNED_OK
- /* Compare two bytes at a time. Note: this is not always beneficial.
- * Try with and without -DUNALIGNED_OK to check.
- */
- register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
- register ush scan_start = *(ushf*)scan;
- register ush scan_end = *(ushf*)(scan+best_len-1);
-#else
- register Bytef *strend = s->window + s->strstart + MAX_MATCH;
- register Byte scan_end1 = scan[best_len-1];
- register Byte scan_end = scan[best_len];
-#endif
-
- /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
- * It is easy to get rid of this optimization if necessary.
- */
- Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
-
- /* Do not waste too much time if we already have a good match: */
- if (s->prev_length >= s->good_match) {
- chain_length >>= 2;
- }
- /* Do not look for matches beyond the end of the input. This is necessary
- * to make deflate deterministic.
- */
- if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
-
- Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
-
- do {
- Assert(cur_match < s->strstart, "no future");
- match = s->window + cur_match;
-
- /* Skip to next match if the match length cannot increase
- * or if the match length is less than 2. Note that the checks below
- * for insufficient lookahead only occur occasionally for performance
- * reasons. Therefore uninitialized memory will be accessed, and
- * conditional jumps will be made that depend on those values.
- * However the length of the match is limited to the lookahead, so
- * the output of deflate is not affected by the uninitialized values.
- */
-#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
- /* This code assumes sizeof(unsigned short) == 2. Do not use
- * UNALIGNED_OK if your compiler uses a different size.
- */
- if (*(ushf*)(match+best_len-1) != scan_end ||
- *(ushf*)match != scan_start) continue;
-
- /* It is not necessary to compare scan[2] and match[2] since they are
- * always equal when the other bytes match, given that the hash keys
- * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
- * strstart+3, +5, ... up to strstart+257. We check for insufficient
- * lookahead only every 4th comparison; the 128th check will be made
- * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
- * necessary to put more guard bytes at the end of the window, or
- * to check more often for insufficient lookahead.
- */
- Assert(scan[2] == match[2], "scan[2]?");
- scan++, match++;
- do {
- } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- scan < strend);
- /* The funny "do {}" generates better code on most compilers */
-
- /* Here, scan <= window+strstart+257 */
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
- if (*scan == *match) scan++;
-
- len = (MAX_MATCH - 1) - (int)(strend-scan);
- scan = strend - (MAX_MATCH-1);
-
-#else /* UNALIGNED_OK */
-
- if (match[best_len] != scan_end ||
- match[best_len-1] != scan_end1 ||
- *match != *scan ||
- *++match != scan[1]) continue;
-
- /* The check at best_len-1 can be removed because it will be made
- * again later. (This heuristic is not always a win.)
- * It is not necessary to compare scan[2] and match[2] since they
- * are always equal when the other bytes match, given that
- * the hash keys are equal and that HASH_BITS >= 8.
- */
- scan += 2, match++;
- Assert(*scan == *match, "match[2]?");
-
- /* We check for insufficient lookahead only every 8th comparison;
- * the 256th check will be made at strstart+258.
- */
- do {
- } while (*++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- scan < strend);
-
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-
- len = MAX_MATCH - (int)(strend - scan);
- scan = strend - MAX_MATCH;
-
-#endif /* UNALIGNED_OK */
-
- if (len > best_len) {
- s->match_start = cur_match;
- best_len = len;
- if (len >= nice_match) break;
-#ifdef UNALIGNED_OK
- scan_end = *(ushf*)(scan+best_len-1);
-#else
- scan_end1 = scan[best_len-1];
- scan_end = scan[best_len];
-#endif
- }
- } while ((cur_match = prev[cur_match & wmask]) > limit
- && --chain_length != 0);
-
- if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
- return s->lookahead;
-}
-#endif /* ASMV */
-#endif /* FASTEST */
-
-/* ---------------------------------------------------------------------------
- * Optimized version for level == 1 or strategy == Z_RLE only
- */
-local uInt longest_match_fast(s, cur_match)
- deflate_state *s;
- IPos cur_match; /* current match */
-{
- register Bytef *scan = s->window + s->strstart; /* current string */
- register Bytef *match; /* matched string */
- register int len; /* length of current match */
- register Bytef *strend = s->window + s->strstart + MAX_MATCH;
-
- /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
- * It is easy to get rid of this optimization if necessary.
- */
- Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
-
- Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
-
- Assert(cur_match < s->strstart, "no future");
-
- match = s->window + cur_match;
-
- /* Return failure if the match length is less than 2:
- */
- if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
-
- /* The check at best_len-1 can be removed because it will be made
- * again later. (This heuristic is not always a win.)
- * It is not necessary to compare scan[2] and match[2] since they
- * are always equal when the other bytes match, given that
- * the hash keys are equal and that HASH_BITS >= 8.
- */
- scan += 2, match += 2;
- Assert(*scan == *match, "match[2]?");
-
- /* We check for insufficient lookahead only every 8th comparison;
- * the 256th check will be made at strstart+258.
- */
- do {
- } while (*++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- scan < strend);
-
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-
- len = MAX_MATCH - (int)(strend - scan);
-
- if (len < MIN_MATCH) return MIN_MATCH - 1;
-
- s->match_start = cur_match;
- return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;
-}
-
-#ifdef DEBUG
-/* ===========================================================================
- * Check that the match at match_start is indeed a match.
- */
-local void check_match(s, start, match, length)
- deflate_state *s;
- IPos start, match;
- int length;
-{
- /* check that the match is indeed a match */
- if (zmemcmp(s->window + match,
- s->window + start, length) != EQUAL) {
- fprintf(stderr, " start %u, match %u, length %d\n",
- start, match, length);
- do {
- fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
- } while (--length != 0);
- z_error("invalid match");
- }
- if (z_verbose > 1) {
- fprintf(stderr,"\\[%d,%d]", start-match, length);
- do { putc(s->window[start++], stderr); } while (--length != 0);
- }
-}
-#else
-# define check_match(s, start, match, length)
-#endif /* DEBUG */
-
-/* ===========================================================================
- * Fill the window when the lookahead becomes insufficient.
- * Updates strstart and lookahead.
- *
- * IN assertion: lookahead < MIN_LOOKAHEAD
- * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
- * At least one byte has been read, or avail_in == 0; reads are
- * performed for at least two bytes (required for the zip translate_eol
- * option -- not supported here).
- */
-local void fill_window(s)
- deflate_state *s;
-{
- register unsigned n, m;
- register Posf *p;
- unsigned more; /* Amount of free space at the end of the window. */
- uInt wsize = s->w_size;
-
- do {
- more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
-
- /* Deal with !@#$% 64K limit: */
- if (sizeof(int) <= 2) {
- if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
- more = wsize;
-
- } else if (more == (unsigned)(-1)) {
- /* Very unlikely, but possible on 16 bit machine if
- * strstart == 0 && lookahead == 1 (input done a byte at time)
- */
- more--;
- }
- }
-
- /* If the window is almost full and there is insufficient lookahead,
- * move the upper half to the lower one to make room in the upper half.
- */
- if (s->strstart >= wsize+MAX_DIST(s)) {
-
- zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
- s->match_start -= wsize;
- s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
- s->block_start -= (long) wsize;
-
- /* Slide the hash table (could be avoided with 32 bit values
- at the expense of memory usage). We slide even when level == 0
- to keep the hash table consistent if we switch back to level > 0
- later. (Using level 0 permanently is not an optimal usage of
- zlib, so we don't care about this pathological case.)
- */
- /* %%% avoid this when Z_RLE */
- n = s->hash_size;
- p = &s->head[n];
- do {
- m = *--p;
- *p = (Pos)(m >= wsize ? m-wsize : NIL);
- } while (--n);
-
- n = wsize;
-#ifndef FASTEST
- p = &s->prev[n];
- do {
- m = *--p;
- *p = (Pos)(m >= wsize ? m-wsize : NIL);
- /* If n is not on any hash chain, prev[n] is garbage but
- * its value will never be used.
- */
- } while (--n);
-#endif
- more += wsize;
- }
- if (s->strm->avail_in == 0) return;
-
- /* If there was no sliding:
- * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
- * more == window_size - lookahead - strstart
- * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
- * => more >= window_size - 2*WSIZE + 2
- * In the BIG_MEM or MMAP case (not yet supported),
- * window_size == input_size + MIN_LOOKAHEAD &&
- * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
- * Otherwise, window_size == 2*WSIZE so more >= 2.
- * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
- */
- Assert(more >= 2, "more < 2");
-
- n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
- s->lookahead += n;
-
- /* Initialize the hash value now that we have some input: */
- if (s->lookahead >= MIN_MATCH) {
- s->ins_h = s->window[s->strstart];
- UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
-#if MIN_MATCH != 3
- Call UPDATE_HASH() MIN_MATCH-3 more times
-#endif
- }
- /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
- * but this is not important since only literal bytes will be emitted.
- */
-
- } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
-}
-
-/* ===========================================================================
- * Flush the current block, with given end-of-file flag.
- * IN assertion: strstart is set to the end of the current match.
- */
-#define FLUSH_BLOCK_ONLY(s, eof) { \
- _tr_flush_block(s, (s->block_start >= 0L ? \
- (charf *)&s->window[(unsigned)s->block_start] : \
- (charf *)Z_NULL), \
- (ulg)((long)s->strstart - s->block_start), \
- (eof)); \
- s->block_start = s->strstart; \
- flush_pending(s->strm); \
- Tracev((stderr,"[FLUSH]")); \
-}
-
-/* Same but force premature exit if necessary. */
-#define FLUSH_BLOCK(s, eof) { \
- FLUSH_BLOCK_ONLY(s, eof); \
- if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
-}
-
-/* ===========================================================================
- * Copy without compression as much as possible from the input stream, return
- * the current block state.
- * This function does not insert new strings in the dictionary since
- * uncompressible data is probably not useful. This function is used
- * only for the level=0 compression option.
- * NOTE: this function should be optimized to avoid extra copying from
- * window to pending_buf.
- */
-local block_state deflate_stored(s, flush)
- deflate_state *s;
- int flush;
-{
- /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
- * to pending_buf_size, and each stored block has a 5 byte header:
- */
- ulg max_block_size = 0xffff;
- ulg max_start;
-
- if (max_block_size > s->pending_buf_size - 5) {
- max_block_size = s->pending_buf_size - 5;
- }
-
- /* Copy as much as possible from input to output: */
- for (;;) {
- /* Fill the window as much as possible: */
- if (s->lookahead <= 1) {
-
- Assert(s->strstart < s->w_size+MAX_DIST(s) ||
- s->block_start >= (long)s->w_size, "slide too late");
-
- fill_window(s);
- if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
-
- if (s->lookahead == 0) break; /* flush the current block */
- }
- Assert(s->block_start >= 0L, "block gone");
-
- s->strstart += s->lookahead;
- s->lookahead = 0;
-
- /* Emit a stored block if pending_buf will be full: */
- max_start = s->block_start + max_block_size;
- if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
- /* strstart == 0 is possible when wraparound on 16-bit machine */
- s->lookahead = (uInt)(s->strstart - max_start);
- s->strstart = (uInt)max_start;
- FLUSH_BLOCK(s, 0);
- }
- /* Flush if we may have to slide, otherwise block_start may become
- * negative and the data will be gone:
- */
- if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
- FLUSH_BLOCK(s, 0);
- }
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
-}
-
-/* ===========================================================================
- * Compress as much as possible from the input stream, return the current
- * block state.
- * This function does not perform lazy evaluation of matches and inserts
- * new strings in the dictionary only for unmatched strings or for short
- * matches. It is used only for the fast compression options.
- */
-local block_state deflate_fast(s, flush)
- deflate_state *s;
- int flush;
-{
- IPos hash_head = NIL; /* head of the hash chain */
- int bflush; /* set if current block must be flushed */
-
- for (;;) {
- /* Make sure that we always have enough lookahead, except
- * at the end of the input file. We need MAX_MATCH bytes
- * for the next match, plus MIN_MATCH bytes to insert the
- * string following the next match.
- */
- if (s->lookahead < MIN_LOOKAHEAD) {
- fill_window(s);
- if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
- return need_more;
- }
- if (s->lookahead == 0) break; /* flush the current block */
- }
-
- /* Insert the string window[strstart .. strstart+2] in the
- * dictionary, and set hash_head to the head of the hash chain:
- */
- if (s->lookahead >= MIN_MATCH) {
- INSERT_STRING(s, s->strstart, hash_head);
- }
-
- /* Find the longest match, discarding those <= prev_length.
- * At this point we have always match_length < MIN_MATCH
- */
- if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
- /* To simplify the code, we prevent matches with the string
- * of window index 0 (in particular we have to avoid a match
- * of the string with itself at the start of the input file).
- */
-#ifdef FASTEST
- if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) ||
- (s->strategy == Z_RLE && s->strstart - hash_head == 1)) {
- s->match_length = longest_match_fast (s, hash_head);
- }
-#else
- if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
- s->match_length = longest_match (s, hash_head);
- } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
- s->match_length = longest_match_fast (s, hash_head);
- }
-#endif
- /* longest_match() or longest_match_fast() sets match_start */
- }
- if (s->match_length >= MIN_MATCH) {
- check_match(s, s->strstart, s->match_start, s->match_length);
-
- _tr_tally_dist(s, s->strstart - s->match_start,
- s->match_length - MIN_MATCH, bflush);
-
- s->lookahead -= s->match_length;
-
- /* Insert new strings in the hash table only if the match length
- * is not too large. This saves time but degrades compression.
- */
-#ifndef FASTEST
- if (s->match_length <= s->max_insert_length &&
- s->lookahead >= MIN_MATCH) {
- s->match_length--; /* string at strstart already in table */
- do {
- s->strstart++;
- INSERT_STRING(s, s->strstart, hash_head);
- /* strstart never exceeds WSIZE-MAX_MATCH, so there are
- * always MIN_MATCH bytes ahead.
- */
- } while (--s->match_length != 0);
- s->strstart++;
- } else
-#endif
- {
- s->strstart += s->match_length;
- s->match_length = 0;
- s->ins_h = s->window[s->strstart];
- UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
-#if MIN_MATCH != 3
- Call UPDATE_HASH() MIN_MATCH-3 more times
-#endif
- /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
- * matter since it will be recomputed at next deflate call.
- */
- }
- } else {
- /* No match, output a literal byte */
- Tracevv((stderr,"%c", s->window[s->strstart]));
- _tr_tally_lit (s, s->window[s->strstart], bflush);
- s->lookahead--;
- s->strstart++;
- }
- if (bflush) FLUSH_BLOCK(s, 0);
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
-}
-
-#ifndef FASTEST
-/* ===========================================================================
- * Same as above, but achieves better compression. We use a lazy
- * evaluation for matches: a match is finally adopted only if there is
- * no better match at the next window position.
- */
-local block_state deflate_slow(s, flush)
- deflate_state *s;
- int flush;
-{
- IPos hash_head = NIL; /* head of hash chain */
- int bflush; /* set if current block must be flushed */
-
- /* Process the input block. */
- for (;;) {
- /* Make sure that we always have enough lookahead, except
- * at the end of the input file. We need MAX_MATCH bytes
- * for the next match, plus MIN_MATCH bytes to insert the
- * string following the next match.
- */
- if (s->lookahead < MIN_LOOKAHEAD) {
- fill_window(s);
- if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
- return need_more;
- }
- if (s->lookahead == 0) break; /* flush the current block */
- }
-
- /* Insert the string window[strstart .. strstart+2] in the
- * dictionary, and set hash_head to the head of the hash chain:
- */
- if (s->lookahead >= MIN_MATCH) {
- INSERT_STRING(s, s->strstart, hash_head);
- }
-
- /* Find the longest match, discarding those <= prev_length.
- */
- s->prev_length = s->match_length, s->prev_match = s->match_start;
- s->match_length = MIN_MATCH-1;
-
- if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
- s->strstart - hash_head <= MAX_DIST(s)) {
- /* To simplify the code, we prevent matches with the string
- * of window index 0 (in particular we have to avoid a match
- * of the string with itself at the start of the input file).
- */
- if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
- s->match_length = longest_match (s, hash_head);
- } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
- s->match_length = longest_match_fast (s, hash_head);
- }
- /* longest_match() or longest_match_fast() sets match_start */
-
- if (s->match_length <= 5 && (s->strategy == Z_FILTERED
-#if TOO_FAR <= 32767
- || (s->match_length == MIN_MATCH &&
- s->strstart - s->match_start > TOO_FAR)
-#endif
- )) {
-
- /* If prev_match is also MIN_MATCH, match_start is garbage
- * but we will ignore the current match anyway.
- */
- s->match_length = MIN_MATCH-1;
- }
- }
- /* If there was a match at the previous step and the current
- * match is not better, output the previous match:
- */
- if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
- uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
- /* Do not insert strings in hash table beyond this. */
-
- check_match(s, s->strstart-1, s->prev_match, s->prev_length);
-
- _tr_tally_dist(s, s->strstart -1 - s->prev_match,
- s->prev_length - MIN_MATCH, bflush);
-
- /* Insert in hash table all strings up to the end of the match.
- * strstart-1 and strstart are already inserted. If there is not
- * enough lookahead, the last two strings are not inserted in
- * the hash table.
- */
- s->lookahead -= s->prev_length-1;
- s->prev_length -= 2;
- do {
- if (++s->strstart <= max_insert) {
- INSERT_STRING(s, s->strstart, hash_head);
- }
- } while (--s->prev_length != 0);
- s->match_available = 0;
- s->match_length = MIN_MATCH-1;
- s->strstart++;
-
- if (bflush) FLUSH_BLOCK(s, 0);
-
- } else if (s->match_available) {
- /* If there was no match at the previous position, output a
- * single literal. If there was a match but the current match
- * is longer, truncate the previous match to a single literal.
- */
- Tracevv((stderr,"%c", s->window[s->strstart-1]));
- _tr_tally_lit(s, s->window[s->strstart-1], bflush);
- if (bflush) {
- FLUSH_BLOCK_ONLY(s, 0);
- }
- s->strstart++;
- s->lookahead--;
- if (s->strm->avail_out == 0) return need_more;
- } else {
- /* There is no previous match to compare with, wait for
- * the next step to decide.
- */
- s->match_available = 1;
- s->strstart++;
- s->lookahead--;
- }
- }
- Assert (flush != Z_NO_FLUSH, "no flush?");
- if (s->match_available) {
- Tracevv((stderr,"%c", s->window[s->strstart-1]));
- _tr_tally_lit(s, s->window[s->strstart-1], bflush);
- s->match_available = 0;
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
-}
-#endif /* FASTEST */
-
-#if 0
-/* ===========================================================================
- * For Z_RLE, simply look for runs of bytes, generate matches only of distance
- * one. Do not maintain a hash table. (It will be regenerated if this run of
- * deflate switches away from Z_RLE.)
- */
-local block_state deflate_rle(s, flush)
- deflate_state *s;
- int flush;
-{
- int bflush; /* set if current block must be flushed */
- uInt run; /* length of run */
- uInt max; /* maximum length of run */
- uInt prev; /* byte at distance one to match */
- Bytef *scan; /* scan for end of run */
-
- for (;;) {
- /* Make sure that we always have enough lookahead, except
- * at the end of the input file. We need MAX_MATCH bytes
- * for the longest encodable run.
- */
- if (s->lookahead < MAX_MATCH) {
- fill_window(s);
- if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) {
- return need_more;
- }
- if (s->lookahead == 0) break; /* flush the current block */
- }
-
- /* See how many times the previous byte repeats */
- run = 0;
- if (s->strstart > 0) { /* if there is a previous byte, that is */
- max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH;
- scan = s->window + s->strstart - 1;
- prev = *scan++;
- do {
- if (*scan++ != prev)
- break;
- } while (++run < max);
- }
-
- /* Emit match if have run of MIN_MATCH or longer, else emit literal */
- if (run >= MIN_MATCH) {
- check_match(s, s->strstart, s->strstart - 1, run);
- _tr_tally_dist(s, 1, run - MIN_MATCH, bflush);
- s->lookahead -= run;
- s->strstart += run;
- } else {
- /* No match, output a literal byte */
- Tracevv((stderr,"%c", s->window[s->strstart]));
- _tr_tally_lit (s, s->window[s->strstart], bflush);
- s->lookahead--;
- s->strstart++;
- }
- if (bflush) FLUSH_BLOCK(s, 0);
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
-}
-#endif
diff --git a/WebCore/platform/image-decoders/zlib/deflate.h b/WebCore/platform/image-decoders/zlib/deflate.h
deleted file mode 100644
index 942fe26..0000000
--- a/WebCore/platform/image-decoders/zlib/deflate.h
+++ /dev/null
@@ -1,331 +0,0 @@
-/* deflate.h -- internal compression state
- * Copyright (C) 1995-2004 Jean-loup Gailly
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* @(#) $Id: deflate.h,v 3.6 2005/08/04 19:14:14 tor%cs.brown.edu Exp $ */
-
-#ifndef DEFLATE_H
-#define DEFLATE_H
-
-#include "zutil.h"
-
-/* define NO_GZIP when compiling if you want to disable gzip header and
- trailer creation by deflate(). NO_GZIP would be used to avoid linking in
- the crc code when it is not needed. For shared libraries, gzip encoding
- should be left enabled. */
-#ifndef NO_GZIP
-# define GZIP
-#endif
-
-/* ===========================================================================
- * Internal compression state.
- */
-
-#define LENGTH_CODES 29
-/* number of length codes, not counting the special END_BLOCK code */
-
-#define LITERALS 256
-/* number of literal bytes 0..255 */
-
-#define L_CODES (LITERALS+1+LENGTH_CODES)
-/* number of Literal or Length codes, including the END_BLOCK code */
-
-#define D_CODES 30
-/* number of distance codes */
-
-#define BL_CODES 19
-/* number of codes used to transfer the bit lengths */
-
-#define HEAP_SIZE (2*L_CODES+1)
-/* maximum heap size */
-
-#define MAX_BITS 15
-/* All codes must not exceed MAX_BITS bits */
-
-#define INIT_STATE 42
-#define EXTRA_STATE 69
-#define NAME_STATE 73
-#define COMMENT_STATE 91
-#define HCRC_STATE 103
-#define BUSY_STATE 113
-#define FINISH_STATE 666
-/* Stream status */
-
-
-/* Data structure describing a single value and its code string. */
-typedef struct ct_data_s {
- union {
- ush freq; /* frequency count */
- ush code; /* bit string */
- } fc;
- union {
- ush dad; /* father node in Huffman tree */
- ush len; /* length of bit string */
- } dl;
-} FAR ct_data;
-
-#define Freq fc.freq
-#define Code fc.code
-#define Dad dl.dad
-#define Len dl.len
-
-typedef struct static_tree_desc_s static_tree_desc;
-
-typedef struct tree_desc_s {
- ct_data *dyn_tree; /* the dynamic tree */
- int max_code; /* largest code with non zero frequency */
- static_tree_desc *stat_desc; /* the corresponding static tree */
-} FAR tree_desc;
-
-typedef ush Pos;
-typedef Pos FAR Posf;
-typedef unsigned IPos;
-
-/* A Pos is an index in the character window. We use short instead of int to
- * save space in the various tables. IPos is used only for parameter passing.
- */
-
-typedef struct internal_state {
- z_streamp strm; /* pointer back to this zlib stream */
- int status; /* as the name implies */
- Bytef *pending_buf; /* output still pending */
- ulg pending_buf_size; /* size of pending_buf */
- Bytef *pending_out; /* next pending byte to output to the stream */
- uInt pending; /* nb of bytes in the pending buffer */
- int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
- gz_headerp gzhead; /* gzip header information to write */
- uInt gzindex; /* where in extra, name, or comment */
- Byte method; /* STORED (for zip only) or DEFLATED */
- int last_flush; /* value of flush param for previous deflate call */
-
- /* used by deflate.c: */
-
- uInt w_size; /* LZ77 window size (32K by default) */
- uInt w_bits; /* log2(w_size) (8..16) */
- uInt w_mask; /* w_size - 1 */
-
- Bytef *window;
- /* Sliding window. Input bytes are read into the second half of the window,
- * and move to the first half later to keep a dictionary of at least wSize
- * bytes. With this organization, matches are limited to a distance of
- * wSize-MAX_MATCH bytes, but this ensures that IO is always
- * performed with a length multiple of the block size. Also, it limits
- * the window size to 64K, which is quite useful on MSDOS.
- * To do: use the user input buffer as sliding window.
- */
-
- ulg window_size;
- /* Actual size of window: 2*wSize, except when the user input buffer
- * is directly used as sliding window.
- */
-
- Posf *prev;
- /* Link to older string with same hash index. To limit the size of this
- * array to 64K, this link is maintained only for the last 32K strings.
- * An index in this array is thus a window index modulo 32K.
- */
-
- Posf *head; /* Heads of the hash chains or NIL. */
-
- uInt ins_h; /* hash index of string to be inserted */
- uInt hash_size; /* number of elements in hash table */
- uInt hash_bits; /* log2(hash_size) */
- uInt hash_mask; /* hash_size-1 */
-
- uInt hash_shift;
- /* Number of bits by which ins_h must be shifted at each input
- * step. It must be such that after MIN_MATCH steps, the oldest
- * byte no longer takes part in the hash key, that is:
- * hash_shift * MIN_MATCH >= hash_bits
- */
-
- long block_start;
- /* Window position at the beginning of the current output block. Gets
- * negative when the window is moved backwards.
- */
-
- uInt match_length; /* length of best match */
- IPos prev_match; /* previous match */
- int match_available; /* set if previous match exists */
- uInt strstart; /* start of string to insert */
- uInt match_start; /* start of matching string */
- uInt lookahead; /* number of valid bytes ahead in window */
-
- uInt prev_length;
- /* Length of the best match at previous step. Matches not greater than this
- * are discarded. This is used in the lazy match evaluation.
- */
-
- uInt max_chain_length;
- /* To speed up deflation, hash chains are never searched beyond this
- * length. A higher limit improves compression ratio but degrades the
- * speed.
- */
-
- uInt max_lazy_match;
- /* Attempt to find a better match only when the current match is strictly
- * smaller than this value. This mechanism is used only for compression
- * levels >= 4.
- */
-# define max_insert_length max_lazy_match
- /* Insert new strings in the hash table only if the match length is not
- * greater than this length. This saves time but degrades compression.
- * max_insert_length is used only for compression levels <= 3.
- */
-
- int level; /* compression level (1..9) */
- int strategy; /* favor or force Huffman coding*/
-
- uInt good_match;
- /* Use a faster search when the previous match is longer than this */
-
- int nice_match; /* Stop searching when current match exceeds this */
-
- /* used by trees.c: */
- /* Didn't use ct_data typedef below to supress compiler warning */
- struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
- struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
- struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
-
- struct tree_desc_s l_desc; /* desc. for literal tree */
- struct tree_desc_s d_desc; /* desc. for distance tree */
- struct tree_desc_s bl_desc; /* desc. for bit length tree */
-
- ush bl_count[MAX_BITS+1];
- /* number of codes at each bit length for an optimal tree */
-
- int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
- int heap_len; /* number of elements in the heap */
- int heap_max; /* element of largest frequency */
- /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
- * The same heap array is used to build all trees.
- */
-
- uch depth[2*L_CODES+1];
- /* Depth of each subtree used as tie breaker for trees of equal frequency
- */
-
- uchf *l_buf; /* buffer for literals or lengths */
-
- uInt lit_bufsize;
- /* Size of match buffer for literals/lengths. There are 4 reasons for
- * limiting lit_bufsize to 64K:
- * - frequencies can be kept in 16 bit counters
- * - if compression is not successful for the first block, all input
- * data is still in the window so we can still emit a stored block even
- * when input comes from standard input. (This can also be done for
- * all blocks if lit_bufsize is not greater than 32K.)
- * - if compression is not successful for a file smaller than 64K, we can
- * even emit a stored file instead of a stored block (saving 5 bytes).
- * This is applicable only for zip (not gzip or zlib).
- * - creating new Huffman trees less frequently may not provide fast
- * adaptation to changes in the input data statistics. (Take for
- * example a binary file with poorly compressible code followed by
- * a highly compressible string table.) Smaller buffer sizes give
- * fast adaptation but have of course the overhead of transmitting
- * trees more frequently.
- * - I can't count above 4
- */
-
- uInt last_lit; /* running index in l_buf */
-
- ushf *d_buf;
- /* Buffer for distances. To simplify the code, d_buf and l_buf have
- * the same number of elements. To use different lengths, an extra flag
- * array would be necessary.
- */
-
- ulg opt_len; /* bit length of current block with optimal trees */
- ulg static_len; /* bit length of current block with static trees */
- uInt matches; /* number of string matches in current block */
- int last_eob_len; /* bit length of EOB code for last block */
-
-#ifdef DEBUG
- ulg compressed_len; /* total bit length of compressed file mod 2^32 */
- ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
-#endif
-
- ush bi_buf;
- /* Output buffer. bits are inserted starting at the bottom (least
- * significant bits).
- */
- int bi_valid;
- /* Number of valid bits in bi_buf. All bits above the last valid bit
- * are always zero.
- */
-
-} FAR deflate_state;
-
-/* Output a byte on the stream.
- * IN assertion: there is enough room in pending_buf.
- */
-#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
-
-
-#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
-/* Minimum amount of lookahead, except at the end of the input file.
- * See deflate.c for comments about the MIN_MATCH+1.
- */
-
-#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
-/* In order to simplify the code, particularly on 16 bit machines, match
- * distances are limited to MAX_DIST instead of WSIZE.
- */
-
- /* in trees.c */
-void _tr_init OF((deflate_state *s));
-int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
-void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
- int eof));
-void _tr_align OF((deflate_state *s));
-void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
- int eof));
-
-#define d_code(dist) \
- ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
-/* Mapping from a distance to a distance code. dist is the distance - 1 and
- * must not have side effects. _dist_code[256] and _dist_code[257] are never
- * used.
- */
-
-#ifndef DEBUG
-/* Inline versions of _tr_tally for speed: */
-
-#if defined(GEN_TREES_H) || !defined(STDC)
- extern uch _length_code[];
- extern uch _dist_code[];
-#else
- extern const uch _length_code[];
- extern const uch _dist_code[];
-#endif
-
-# define _tr_tally_lit(s, c, flush) \
- { uch cc = (c); \
- s->d_buf[s->last_lit] = 0; \
- s->l_buf[s->last_lit++] = cc; \
- s->dyn_ltree[cc].Freq++; \
- flush = (s->last_lit == s->lit_bufsize-1); \
- }
-# define _tr_tally_dist(s, distance, length, flush) \
- { uch len = (length); \
- ush dist = (distance); \
- s->d_buf[s->last_lit] = dist; \
- s->l_buf[s->last_lit++] = len; \
- dist--; \
- s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
- s->dyn_dtree[d_code(dist)].Freq++; \
- flush = (s->last_lit == s->lit_bufsize-1); \
- }
-#else
-# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
-# define _tr_tally_dist(s, distance, length, flush) \
- flush = _tr_tally(s, distance, length)
-#endif
-
-#endif /* DEFLATE_H */
diff --git a/WebCore/platform/image-decoders/zlib/gzio.c b/WebCore/platform/image-decoders/zlib/gzio.c
deleted file mode 100644
index 2c0c1d7..0000000
--- a/WebCore/platform/image-decoders/zlib/gzio.c
+++ /dev/null
@@ -1,1026 +0,0 @@
-/* gzio.c -- IO on .gz files
- * Copyright (C) 1995-2005 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- *
- * Compile this file with -DNO_GZCOMPRESS to avoid the compression code.
- */
-
-/* @(#) $Id: gzio.c,v 3.7 2005/08/04 19:14:14 tor%cs.brown.edu Exp $ */
-
-#include <stdio.h>
-
-#include "zutil.h"
-
-#ifdef NO_DEFLATE /* for compatibility with old definition */
-# define NO_GZCOMPRESS
-#endif
-
-#ifndef NO_DUMMY_DECL
-struct internal_state {int dummy;}; /* for buggy compilers */
-#endif
-
-#ifndef Z_BUFSIZE
-# ifdef MAXSEG_64K
-# define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */
-# else
-# define Z_BUFSIZE 16384
-# endif
-#endif
-#ifndef Z_PRINTF_BUFSIZE
-# define Z_PRINTF_BUFSIZE 4096
-#endif
-
-#ifdef __MVS__
-# pragma map (fdopen , "\174\174FDOPEN")
- FILE *fdopen(int, const char *);
-#endif
-
-#ifndef STDC
-extern voidp malloc OF((uInt size));
-extern void free OF((voidpf ptr));
-#endif
-
-#define ALLOC(size) malloc(size)
-#define TRYFREE(p) {if (p) free(p);}
-
-static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
-
-/* gzip flag byte */
-#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
-#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
-#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
-#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
-#define COMMENT 0x10 /* bit 4 set: file comment present */
-#define RESERVED 0xE0 /* bits 5..7: reserved */
-
-typedef struct gz_stream {
- z_stream stream;
- int z_err; /* error code for last stream operation */
- int z_eof; /* set if end of input file */
- FILE *file; /* .gz file */
- Byte *inbuf; /* input buffer */
- Byte *outbuf; /* output buffer */
- uLong crc; /* crc32 of uncompressed data */
- char *msg; /* error message */
- char *path; /* path name for debugging only */
- int transparent; /* 1 if input file is not a .gz file */
- char mode; /* 'w' or 'r' */
- z_off_t start; /* start of compressed data in file (header skipped) */
- z_off_t in; /* bytes into deflate or inflate */
- z_off_t out; /* bytes out of deflate or inflate */
- int back; /* one character push-back */
- int last; /* true if push-back is last character */
-} gz_stream;
-
-
-local gzFile gz_open OF((const char *path, const char *mode, int fd));
-local int do_flush OF((gzFile file, int flush));
-local int get_byte OF((gz_stream *s));
-local void check_header OF((gz_stream *s));
-local int destroy OF((gz_stream *s));
-local void putLong OF((FILE *file, uLong x));
-local uLong getLong OF((gz_stream *s));
-
-/* ===========================================================================
- Opens a gzip (.gz) file for reading or writing. The mode parameter
- is as in fopen ("rb" or "wb"). The file is given either by file descriptor
- or path name (if fd == -1).
- gz_open returns NULL if the file could not be opened or if there was
- insufficient memory to allocate the (de)compression state; errno
- can be checked to distinguish the two cases (if errno is zero, the
- zlib error is Z_MEM_ERROR).
-*/
-local gzFile gz_open (path, mode, fd)
- const char *path;
- const char *mode;
- int fd;
-{
- int err;
- int level = Z_DEFAULT_COMPRESSION; /* compression level */
- int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */
- char *p = (char*)mode;
- gz_stream *s;
- char fmode[80]; /* copy of mode, without the compression level */
- char *m = fmode;
-
- if (!path || !mode) return Z_NULL;
-
- s = (gz_stream *)ALLOC(sizeof(gz_stream));
- if (!s) return Z_NULL;
-
- s->stream.zalloc = (alloc_func)0;
- s->stream.zfree = (free_func)0;
- s->stream.opaque = (voidpf)0;
- s->stream.next_in = s->inbuf = Z_NULL;
- s->stream.next_out = s->outbuf = Z_NULL;
- s->stream.avail_in = s->stream.avail_out = 0;
- s->file = NULL;
- s->z_err = Z_OK;
- s->z_eof = 0;
- s->in = 0;
- s->out = 0;
- s->back = EOF;
- s->crc = crc32(0L, Z_NULL, 0);
- s->msg = NULL;
- s->transparent = 0;
-
- s->path = (char*)ALLOC(strlen(path)+1);
- if (s->path == NULL) {
- return destroy(s), (gzFile)Z_NULL;
- }
- strcpy(s->path, path); /* do this early for debugging */
-
- s->mode = '\0';
- do {
- if (*p == 'r') s->mode = 'r';
- if (*p == 'w' || *p == 'a') s->mode = 'w';
- if (*p >= '0' && *p <= '9') {
- level = *p - '0';
- } else if (*p == 'f') {
- strategy = Z_FILTERED;
- } else if (*p == 'h') {
- strategy = Z_HUFFMAN_ONLY;
- } else if (*p == 'R') {
- strategy = Z_RLE;
- } else {
- *m++ = *p; /* copy the mode */
- }
- } while (*p++ && m != fmode + sizeof(fmode));
- if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
-
- if (s->mode == 'w') {
-#ifdef NO_GZCOMPRESS
- err = Z_STREAM_ERROR;
-#else
- err = deflateInit2(&(s->stream), level,
- Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy);
- /* windowBits is passed < 0 to suppress zlib header */
-
- s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
-#endif
- if (err != Z_OK || s->outbuf == Z_NULL) {
- return destroy(s), (gzFile)Z_NULL;
- }
- } else {
- s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE);
-
- err = inflateInit2(&(s->stream), -MAX_WBITS);
- /* windowBits is passed < 0 to tell that there is no zlib header.
- * Note that in this case inflate *requires* an extra "dummy" byte
- * after the compressed stream in order to complete decompression and
- * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are
- * present after the compressed stream.
- */
- if (err != Z_OK || s->inbuf == Z_NULL) {
- return destroy(s), (gzFile)Z_NULL;
- }
- }
- s->stream.avail_out = Z_BUFSIZE;
-
- errno = 0;
- s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode);
-
- if (s->file == NULL) {
- return destroy(s), (gzFile)Z_NULL;
- }
- if (s->mode == 'w') {
- /* Write a very simple .gz header:
- */
- fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
- Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
- s->start = 10L;
- /* We use 10L instead of ftell(s->file) to because ftell causes an
- * fflush on some systems. This version of the library doesn't use
- * start anyway in write mode, so this initialization is not
- * necessary.
- */
- } else {
- check_header(s); /* skip the .gz header */
- s->start = ftell(s->file) - s->stream.avail_in;
- }
-
- return (gzFile)s;
-}
-
-/* ===========================================================================
- Opens a gzip (.gz) file for reading or writing.
-*/
-gzFile ZEXPORT gzopen (path, mode)
- const char *path;
- const char *mode;
-{
- return gz_open (path, mode, -1);
-}
-
-/* ===========================================================================
- Associate a gzFile with the file descriptor fd. fd is not dup'ed here
- to mimic the behavio(u)r of fdopen.
-*/
-gzFile ZEXPORT gzdopen (fd, mode)
- int fd;
- const char *mode;
-{
- char name[46]; /* allow for up to 128-bit integers */
-
- if (fd < 0) return (gzFile)Z_NULL;
- sprintf(name, "<fd:%d>", fd); /* for debugging */
-
- return gz_open (name, mode, fd);
-}
-
-/* ===========================================================================
- * Update the compression level and strategy
- */
-int ZEXPORT gzsetparams (file, level, strategy)
- gzFile file;
- int level;
- int strategy;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
-
- /* Make room to allow flushing */
- if (s->stream.avail_out == 0) {
-
- s->stream.next_out = s->outbuf;
- if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
- s->z_err = Z_ERRNO;
- }
- s->stream.avail_out = Z_BUFSIZE;
- }
-
- return deflateParams (&(s->stream), level, strategy);
-}
-
-/* ===========================================================================
- Read a byte from a gz_stream; update next_in and avail_in. Return EOF
- for end of file.
- IN assertion: the stream s has been sucessfully opened for reading.
-*/
-local int get_byte(s)
- gz_stream *s;
-{
- if (s->z_eof) return EOF;
- if (s->stream.avail_in == 0) {
- errno = 0;
- s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
- if (s->stream.avail_in == 0) {
- s->z_eof = 1;
- if (ferror(s->file)) s->z_err = Z_ERRNO;
- return EOF;
- }
- s->stream.next_in = s->inbuf;
- }
- s->stream.avail_in--;
- return *(s->stream.next_in)++;
-}
-
-/* ===========================================================================
- Check the gzip header of a gz_stream opened for reading. Set the stream
- mode to transparent if the gzip magic header is not present; set s->err
- to Z_DATA_ERROR if the magic header is present but the rest of the header
- is incorrect.
- IN assertion: the stream s has already been created sucessfully;
- s->stream.avail_in is zero for the first time, but may be non-zero
- for concatenated .gz files.
-*/
-local void check_header(s)
- gz_stream *s;
-{
- int method; /* method byte */
- int flags; /* flags byte */
- uInt len;
- int c;
-
- /* Assure two bytes in the buffer so we can peek ahead -- handle case
- where first byte of header is at the end of the buffer after the last
- gzip segment */
- len = s->stream.avail_in;
- if (len < 2) {
- if (len) s->inbuf[0] = s->stream.next_in[0];
- errno = 0;
- len = (uInt)fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file);
- if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO;
- s->stream.avail_in += len;
- s->stream.next_in = s->inbuf;
- if (s->stream.avail_in < 2) {
- s->transparent = s->stream.avail_in;
- return;
- }
- }
-
- /* Peek ahead to check the gzip magic header */
- if (s->stream.next_in[0] != gz_magic[0] ||
- s->stream.next_in[1] != gz_magic[1]) {
- s->transparent = 1;
- return;
- }
- s->stream.avail_in -= 2;
- s->stream.next_in += 2;
-
- /* Check the rest of the gzip header */
- method = get_byte(s);
- flags = get_byte(s);
- if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
- s->z_err = Z_DATA_ERROR;
- return;
- }
-
- /* Discard time, xflags and OS code: */
- for (len = 0; len < 6; len++) (void)get_byte(s);
-
- if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
- len = (uInt)get_byte(s);
- len += ((uInt)get_byte(s))<<8;
- /* len is garbage if EOF but the loop below will quit anyway */
- while (len-- != 0 && get_byte(s) != EOF) ;
- }
- if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
- while ((c = get_byte(s)) != 0 && c != EOF) ;
- }
- if ((flags & COMMENT) != 0) { /* skip the .gz file comment */
- while ((c = get_byte(s)) != 0 && c != EOF) ;
- }
- if ((flags & HEAD_CRC) != 0) { /* skip the header crc */
- for (len = 0; len < 2; len++) (void)get_byte(s);
- }
- s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
-}
-
- /* ===========================================================================
- * Cleanup then free the given gz_stream. Return a zlib error code.
- Try freeing in the reverse order of allocations.
- */
-local int destroy (s)
- gz_stream *s;
-{
- int err = Z_OK;
-
- if (!s) return Z_STREAM_ERROR;
-
- TRYFREE(s->msg);
-
- if (s->stream.state != NULL) {
- if (s->mode == 'w') {
-#ifdef NO_GZCOMPRESS
- err = Z_STREAM_ERROR;
-#else
- err = deflateEnd(&(s->stream));
-#endif
- } else if (s->mode == 'r') {
- err = inflateEnd(&(s->stream));
- }
- }
- if (s->file != NULL && fclose(s->file)) {
-#ifdef ESPIPE
- if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */
-#endif
- err = Z_ERRNO;
- }
- if (s->z_err < 0) err = s->z_err;
-
- TRYFREE(s->inbuf);
- TRYFREE(s->outbuf);
- TRYFREE(s->path);
- TRYFREE(s);
- return err;
-}
-
-/* ===========================================================================
- Reads the given number of uncompressed bytes from the compressed file.
- gzread returns the number of bytes actually read (0 for end of file).
-*/
-int ZEXPORT gzread (file, buf, len)
- gzFile file;
- voidp buf;
- unsigned len;
-{
- gz_stream *s = (gz_stream*)file;
- Bytef *start = (Bytef*)buf; /* starting point for crc computation */
- Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */
-
- if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
-
- if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;
- if (s->z_err == Z_STREAM_END) return 0; /* EOF */
-
- next_out = (Byte*)buf;
- s->stream.next_out = (Bytef*)buf;
- s->stream.avail_out = len;
-
- if (s->stream.avail_out && s->back != EOF) {
- *next_out++ = s->back;
- s->stream.next_out++;
- s->stream.avail_out--;
- s->back = EOF;
- s->out++;
- start++;
- if (s->last) {
- s->z_err = Z_STREAM_END;
- return 1;
- }
- }
-
- while (s->stream.avail_out != 0) {
-
- if (s->transparent) {
- /* Copy first the lookahead bytes: */
- uInt n = s->stream.avail_in;
- if (n > s->stream.avail_out) n = s->stream.avail_out;
- if (n > 0) {
- zmemcpy(s->stream.next_out, s->stream.next_in, n);
- next_out += n;
- s->stream.next_out = next_out;
- s->stream.next_in += n;
- s->stream.avail_out -= n;
- s->stream.avail_in -= n;
- }
- if (s->stream.avail_out > 0) {
- s->stream.avail_out -=
- (uInt)fread(next_out, 1, s->stream.avail_out, s->file);
- }
- len -= s->stream.avail_out;
- s->in += len;
- s->out += len;
- if (len == 0) s->z_eof = 1;
- return (int)len;
- }
- if (s->stream.avail_in == 0 && !s->z_eof) {
-
- errno = 0;
- s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
- if (s->stream.avail_in == 0) {
- s->z_eof = 1;
- if (ferror(s->file)) {
- s->z_err = Z_ERRNO;
- break;
- }
- }
- s->stream.next_in = s->inbuf;
- }
- s->in += s->stream.avail_in;
- s->out += s->stream.avail_out;
- s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
- s->in -= s->stream.avail_in;
- s->out -= s->stream.avail_out;
-
- if (s->z_err == Z_STREAM_END) {
- /* Check CRC and original size */
- s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
- start = s->stream.next_out;
-
- if (getLong(s) != s->crc) {
- s->z_err = Z_DATA_ERROR;
- } else {
- (void)getLong(s);
- /* The uncompressed length returned by above getlong() may be
- * different from s->out in case of concatenated .gz files.
- * Check for such files:
- */
- check_header(s);
- if (s->z_err == Z_OK) {
- inflateReset(&(s->stream));
- s->crc = crc32(0L, Z_NULL, 0);
- }
- }
- }
- if (s->z_err != Z_OK || s->z_eof) break;
- }
- s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
-
- if (len == s->stream.avail_out &&
- (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO))
- return -1;
- return (int)(len - s->stream.avail_out);
-}
-
-
-/* ===========================================================================
- Reads one byte from the compressed file. gzgetc returns this byte
- or -1 in case of end of file or error.
-*/
-int ZEXPORT gzgetc(file)
- gzFile file;
-{
- unsigned char c;
-
- return gzread(file, &c, 1) == 1 ? c : -1;
-}
-
-
-/* ===========================================================================
- Push one byte back onto the stream.
-*/
-int ZEXPORT gzungetc(c, file)
- int c;
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'r' || c == EOF || s->back != EOF) return EOF;
- s->back = c;
- s->out--;
- s->last = (s->z_err == Z_STREAM_END);
- if (s->last) s->z_err = Z_OK;
- s->z_eof = 0;
- return c;
-}
-
-
-/* ===========================================================================
- Reads bytes from the compressed file until len-1 characters are
- read, or a newline character is read and transferred to buf, or an
- end-of-file condition is encountered. The string is then terminated
- with a null character.
- gzgets returns buf, or Z_NULL in case of error.
-
- The current implementation is not optimized at all.
-*/
-char * ZEXPORT gzgets(file, buf, len)
- gzFile file;
- char *buf;
- int len;
-{
- char *b = buf;
- if (buf == Z_NULL || len <= 0) return Z_NULL;
-
- while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ;
- *buf = '\0';
- return b == buf && len > 0 ? Z_NULL : b;
-}
-
-
-#ifndef NO_GZCOMPRESS
-/* ===========================================================================
- Writes the given number of uncompressed bytes into the compressed file.
- gzwrite returns the number of bytes actually written (0 in case of error).
-*/
-int ZEXPORT gzwrite (file, buf, len)
- gzFile file;
- voidpc buf;
- unsigned len;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
-
- s->stream.next_in = (Bytef*)buf;
- s->stream.avail_in = len;
-
- while (s->stream.avail_in != 0) {
-
- if (s->stream.avail_out == 0) {
-
- s->stream.next_out = s->outbuf;
- if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
- s->z_err = Z_ERRNO;
- break;
- }
- s->stream.avail_out = Z_BUFSIZE;
- }
- s->in += s->stream.avail_in;
- s->out += s->stream.avail_out;
- s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
- s->in -= s->stream.avail_in;
- s->out -= s->stream.avail_out;
- if (s->z_err != Z_OK) break;
- }
- s->crc = crc32(s->crc, (const Bytef *)buf, len);
-
- return (int)(len - s->stream.avail_in);
-}
-
-
-/* ===========================================================================
- Converts, formats, and writes the args to the compressed file under
- control of the format string, as in fprintf. gzprintf returns the number of
- uncompressed bytes actually written (0 in case of error).
-*/
-#ifdef STDC
-#include <stdarg.h>
-
-int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...)
-{
- char buf[Z_PRINTF_BUFSIZE];
- va_list va;
- int len;
-
- buf[sizeof(buf) - 1] = 0;
- va_start(va, format);
-#ifdef NO_vsnprintf
-# ifdef HAS_vsprintf_void
- (void)vsprintf(buf, format, va);
- va_end(va);
- for (len = 0; len < sizeof(buf); len++)
- if (buf[len] == 0) break;
-# else
- len = vsprintf(buf, format, va);
- va_end(va);
-# endif
-#else
-# ifdef HAS_vsnprintf_void
- (void)vsnprintf(buf, sizeof(buf), format, va);
- va_end(va);
- len = strlen(buf);
-# else
- len = vsnprintf(buf, sizeof(buf), format, va);
- va_end(va);
-# endif
-#endif
- if (len <= 0 || len >= (int)sizeof(buf) || buf[sizeof(buf) - 1] != 0)
- return 0;
- return gzwrite(file, buf, (unsigned)len);
-}
-#else /* not ANSI C */
-
-int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
- a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
- gzFile file;
- const char *format;
- int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
- a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
-{
- char buf[Z_PRINTF_BUFSIZE];
- int len;
-
- buf[sizeof(buf) - 1] = 0;
-#ifdef NO_snprintf
-# ifdef HAS_sprintf_void
- sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
- a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
- for (len = 0; len < sizeof(buf); len++)
- if (buf[len] == 0) break;
-# else
- len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
- a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
-# endif
-#else
-# ifdef HAS_snprintf_void
- snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
- a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
- len = strlen(buf);
-# else
- len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
- a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
-# endif
-#endif
- if (len <= 0 || len >= sizeof(buf) || buf[sizeof(buf) - 1] != 0)
- return 0;
- return gzwrite(file, buf, len);
-}
-#endif
-
-/* ===========================================================================
- Writes c, converted to an unsigned char, into the compressed file.
- gzputc returns the value that was written, or -1 in case of error.
-*/
-int ZEXPORT gzputc(file, c)
- gzFile file;
- int c;
-{
- unsigned char cc = (unsigned char) c; /* required for big endian systems */
-
- return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1;
-}
-
-
-/* ===========================================================================
- Writes the given null-terminated string to the compressed file, excluding
- the terminating null character.
- gzputs returns the number of characters written, or -1 in case of error.
-*/
-int ZEXPORT gzputs(file, s)
- gzFile file;
- const char *s;
-{
- return gzwrite(file, (char*)s, (unsigned)strlen(s));
-}
-
-
-/* ===========================================================================
- Flushes all pending output into the compressed file. The parameter
- flush is as in the deflate() function.
-*/
-local int do_flush (file, flush)
- gzFile file;
- int flush;
-{
- uInt len;
- int done = 0;
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
-
- s->stream.avail_in = 0; /* should be zero already anyway */
-
- for (;;) {
- len = Z_BUFSIZE - s->stream.avail_out;
-
- if (len != 0) {
- if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
- s->z_err = Z_ERRNO;
- return Z_ERRNO;
- }
- s->stream.next_out = s->outbuf;
- s->stream.avail_out = Z_BUFSIZE;
- }
- if (done) break;
- s->out += s->stream.avail_out;
- s->z_err = deflate(&(s->stream), flush);
- s->out -= s->stream.avail_out;
-
- /* Ignore the second of two consecutive flushes: */
- if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK;
-
- /* deflate has finished flushing only when it hasn't used up
- * all the available space in the output buffer:
- */
- done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
-
- if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break;
- }
- return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
-}
-
-int ZEXPORT gzflush (file, flush)
- gzFile file;
- int flush;
-{
- gz_stream *s = (gz_stream*)file;
- int err = do_flush (file, flush);
-
- if (err) return err;
- fflush(s->file);
- return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
-}
-#endif /* NO_GZCOMPRESS */
-
-/* ===========================================================================
- Sets the starting position for the next gzread or gzwrite on the given
- compressed file. The offset represents a number of bytes in the
- gzseek returns the resulting offset location as measured in bytes from
- the beginning of the uncompressed stream, or -1 in case of error.
- SEEK_END is not implemented, returns error.
- In this version of the library, gzseek can be extremely slow.
-*/
-z_off_t ZEXPORT gzseek (file, offset, whence)
- gzFile file;
- z_off_t offset;
- int whence;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || whence == SEEK_END ||
- s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) {
- return -1L;
- }
-
- if (s->mode == 'w') {
-#ifdef NO_GZCOMPRESS
- return -1L;
-#else
- if (whence == SEEK_SET) {
- offset -= s->in;
- }
- if (offset < 0) return -1L;
-
- /* At this point, offset is the number of zero bytes to write. */
- if (s->inbuf == Z_NULL) {
- s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */
- if (s->inbuf == Z_NULL) return -1L;
- zmemzero(s->inbuf, Z_BUFSIZE);
- }
- while (offset > 0) {
- uInt size = Z_BUFSIZE;
- if (offset < Z_BUFSIZE) size = (uInt)offset;
-
- size = gzwrite(file, s->inbuf, size);
- if (size == 0) return -1L;
-
- offset -= size;
- }
- return s->in;
-#endif
- }
- /* Rest of function is for reading only */
-
- /* compute absolute position */
- if (whence == SEEK_CUR) {
- offset += s->out;
- }
- if (offset < 0) return -1L;
-
- if (s->transparent) {
- /* map to fseek */
- s->back = EOF;
- s->stream.avail_in = 0;
- s->stream.next_in = s->inbuf;
- if (fseek(s->file, offset, SEEK_SET) < 0) return -1L;
-
- s->in = s->out = offset;
- return offset;
- }
-
- /* For a negative seek, rewind and use positive seek */
- if (offset >= s->out) {
- offset -= s->out;
- } else if (gzrewind(file) < 0) {
- return -1L;
- }
- /* offset is now the number of bytes to skip. */
-
- if (offset != 0 && s->outbuf == Z_NULL) {
- s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
- if (s->outbuf == Z_NULL) return -1L;
- }
- if (offset && s->back != EOF) {
- s->back = EOF;
- s->out++;
- offset--;
- if (s->last) s->z_err = Z_STREAM_END;
- }
- while (offset > 0) {
- int size = Z_BUFSIZE;
- if (offset < Z_BUFSIZE) size = (int)offset;
-
- size = gzread(file, s->outbuf, (uInt)size);
- if (size <= 0) return -1L;
- offset -= size;
- }
- return s->out;
-}
-
-/* ===========================================================================
- Rewinds input file.
-*/
-int ZEXPORT gzrewind (file)
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'r') return -1;
-
- s->z_err = Z_OK;
- s->z_eof = 0;
- s->back = EOF;
- s->stream.avail_in = 0;
- s->stream.next_in = s->inbuf;
- s->crc = crc32(0L, Z_NULL, 0);
- if (!s->transparent) (void)inflateReset(&s->stream);
- s->in = 0;
- s->out = 0;
- return fseek(s->file, s->start, SEEK_SET);
-}
-
-/* ===========================================================================
- Returns the starting position for the next gzread or gzwrite on the
- given compressed file. This position represents a number of bytes in the
- uncompressed data stream.
-*/
-z_off_t ZEXPORT gztell (file)
- gzFile file;
-{
- return gzseek(file, 0L, SEEK_CUR);
-}
-
-/* ===========================================================================
- Returns 1 when EOF has previously been detected reading the given
- input stream, otherwise zero.
-*/
-int ZEXPORT gzeof (file)
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- /* With concatenated compressed files that can have embedded
- * crc trailers, z_eof is no longer the only/best indicator of EOF
- * on a gz_stream. Handle end-of-stream error explicitly here.
- */
- if (s == NULL || s->mode != 'r') return 0;
- if (s->z_eof) return 1;
- return s->z_err == Z_STREAM_END;
-}
-
-/* ===========================================================================
- Returns 1 if reading and doing so transparently, otherwise zero.
-*/
-int ZEXPORT gzdirect (file)
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'r') return 0;
- return s->transparent;
-}
-
-/* ===========================================================================
- Outputs a long in LSB order to the given file
-*/
-local void putLong (file, x)
- FILE *file;
- uLong x;
-{
- int n;
- for (n = 0; n < 4; n++) {
- fputc((int)(x & 0xff), file);
- x >>= 8;
- }
-}
-
-/* ===========================================================================
- Reads a long in LSB order from the given gz_stream. Sets z_err in case
- of error.
-*/
-local uLong getLong (s)
- gz_stream *s;
-{
- uLong x = (uLong)get_byte(s);
- int c;
-
- x += ((uLong)get_byte(s))<<8;
- x += ((uLong)get_byte(s))<<16;
- c = get_byte(s);
- if (c == EOF) s->z_err = Z_DATA_ERROR;
- x += ((uLong)c)<<24;
- return x;
-}
-
-/* ===========================================================================
- Flushes all pending output if necessary, closes the compressed file
- and deallocates all the (de)compression state.
-*/
-int ZEXPORT gzclose (file)
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL) return Z_STREAM_ERROR;
-
- if (s->mode == 'w') {
-#ifdef NO_GZCOMPRESS
- return Z_STREAM_ERROR;
-#else
- if (do_flush (file, Z_FINISH) != Z_OK)
- return destroy((gz_stream*)file);
-
- putLong (s->file, s->crc);
- putLong (s->file, (uLong)(s->in & 0xffffffff));
-#endif
- }
- return destroy((gz_stream*)file);
-}
-
-#ifdef STDC
-# define zstrerror(errnum) strerror(errnum)
-#else
-# define zstrerror(errnum) ""
-#endif
-
-/* ===========================================================================
- Returns the error message for the last error which occurred on the
- given compressed file. errnum is set to zlib error number. If an
- error occurred in the file system and not in the compression library,
- errnum is set to Z_ERRNO and the application may consult errno
- to get the exact error code.
-*/
-const char * ZEXPORT gzerror (file, errnum)
- gzFile file;
- int *errnum;
-{
- char *m;
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL) {
- *errnum = Z_STREAM_ERROR;
- return (const char*)ERR_MSG(Z_STREAM_ERROR);
- }
- *errnum = s->z_err;
- if (*errnum == Z_OK) return (const char*)"";
-
- m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg);
-
- if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err);
-
- TRYFREE(s->msg);
- s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
- if (s->msg == Z_NULL) return (const char*)ERR_MSG(Z_MEM_ERROR);
- strcpy(s->msg, s->path);
- strcat(s->msg, ": ");
- strcat(s->msg, m);
- return (const char*)s->msg;
-}
-
-/* ===========================================================================
- Clear the error and end-of-file flags, and do the same for the real file.
-*/
-void ZEXPORT gzclearerr (file)
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL) return;
- if (s->z_err != Z_STREAM_END) s->z_err = Z_OK;
- s->z_eof = 0;
- clearerr(s->file);
-}
diff --git a/WebCore/platform/image-decoders/zlib/infback.c b/WebCore/platform/image-decoders/zlib/infback.c
deleted file mode 100644
index 455dbc9..0000000
--- a/WebCore/platform/image-decoders/zlib/infback.c
+++ /dev/null
@@ -1,623 +0,0 @@
-/* infback.c -- inflate using a call-back interface
- * Copyright (C) 1995-2005 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/*
- This code is largely copied from inflate.c. Normally either infback.o or
- inflate.o would be linked into an application--not both. The interface
- with inffast.c is retained so that optimized assembler-coded versions of
- inflate_fast() can be used with either inflate.c or infback.c.
- */
-
-#include "zutil.h"
-#include "inftrees.h"
-#include "inflate.h"
-#include "inffast.h"
-
-/* function prototypes */
-local void fixedtables OF((struct inflate_state FAR *state));
-
-/*
- strm provides memory allocation functions in zalloc and zfree, or
- Z_NULL to use the library memory allocation functions.
-
- windowBits is in the range 8..15, and window is a user-supplied
- window and output buffer that is 2**windowBits bytes.
- */
-int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size)
-z_streamp strm;
-int windowBits;
-unsigned char FAR *window;
-const char *version;
-int stream_size;
-{
- struct inflate_state FAR *state;
-
- if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
- stream_size != (int)(sizeof(z_stream)))
- return Z_VERSION_ERROR;
- if (strm == Z_NULL || window == Z_NULL ||
- windowBits < 8 || windowBits > 15)
- return Z_STREAM_ERROR;
- strm->msg = Z_NULL; /* in case we return an error */
- if (strm->zalloc == (alloc_func)0) {
- strm->zalloc = zcalloc;
- strm->opaque = (voidpf)0;
- }
- if (strm->zfree == (free_func)0) strm->zfree = zcfree;
- state = (struct inflate_state FAR *)ZALLOC(strm, 1,
- sizeof(struct inflate_state));
- if (state == Z_NULL) return Z_MEM_ERROR;
- Tracev((stderr, "inflate: allocated\n"));
- strm->state = (struct internal_state FAR *)state;
- state->dmax = 32768U;
- state->wbits = windowBits;
- state->wsize = 1U << windowBits;
- state->window = window;
- state->write = 0;
- state->whave = 0;
- return Z_OK;
-}
-
-/*
- Return state with length and distance decoding tables and index sizes set to
- fixed code decoding. Normally this returns fixed tables from inffixed.h.
- If BUILDFIXED is defined, then instead this routine builds the tables the
- first time it's called, and returns those tables the first time and
- thereafter. This reduces the size of the code by about 2K bytes, in
- exchange for a little execution time. However, BUILDFIXED should not be
- used for threaded applications, since the rewriting of the tables and virgin
- may not be thread-safe.
- */
-local void fixedtables(state)
-struct inflate_state FAR *state;
-{
-#ifdef BUILDFIXED
- static int virgin = 1;
- static code *lenfix, *distfix;
- static code fixed[544];
-
- /* build fixed huffman tables if first call (may not be thread safe) */
- if (virgin) {
- unsigned sym, bits;
- static code *next;
-
- /* literal/length table */
- sym = 0;
- while (sym < 144) state->lens[sym++] = 8;
- while (sym < 256) state->lens[sym++] = 9;
- while (sym < 280) state->lens[sym++] = 7;
- while (sym < 288) state->lens[sym++] = 8;
- next = fixed;
- lenfix = next;
- bits = 9;
- inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
-
- /* distance table */
- sym = 0;
- while (sym < 32) state->lens[sym++] = 5;
- distfix = next;
- bits = 5;
- inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
-
- /* do this just once */
- virgin = 0;
- }
-#else /* !BUILDFIXED */
-# include "inffixed.h"
-#endif /* BUILDFIXED */
- state->lencode = lenfix;
- state->lenbits = 9;
- state->distcode = distfix;
- state->distbits = 5;
-}
-
-/* Macros for inflateBack(): */
-
-/* Load returned state from inflate_fast() */
-#define LOAD() \
- do { \
- put = strm->next_out; \
- left = strm->avail_out; \
- next = strm->next_in; \
- have = strm->avail_in; \
- hold = state->hold; \
- bits = state->bits; \
- } while (0)
-
-/* Set state from registers for inflate_fast() */
-#define RESTORE() \
- do { \
- strm->next_out = put; \
- strm->avail_out = left; \
- strm->next_in = next; \
- strm->avail_in = have; \
- state->hold = hold; \
- state->bits = bits; \
- } while (0)
-
-/* Clear the input bit accumulator */
-#define INITBITS() \
- do { \
- hold = 0; \
- bits = 0; \
- } while (0)
-
-/* Assure that some input is available. If input is requested, but denied,
- then return a Z_BUF_ERROR from inflateBack(). */
-#define PULL() \
- do { \
- if (have == 0) { \
- have = in(in_desc, &next); \
- if (have == 0) { \
- next = Z_NULL; \
- ret = Z_BUF_ERROR; \
- goto inf_leave; \
- } \
- } \
- } while (0)
-
-/* Get a byte of input into the bit accumulator, or return from inflateBack()
- with an error if there is no input available. */
-#define PULLBYTE() \
- do { \
- PULL(); \
- have--; \
- hold += (unsigned long)(*next++) << bits; \
- bits += 8; \
- } while (0)
-
-/* Assure that there are at least n bits in the bit accumulator. If there is
- not enough available input to do that, then return from inflateBack() with
- an error. */
-#define NEEDBITS(n) \
- do { \
- while (bits < (unsigned)(n)) \
- PULLBYTE(); \
- } while (0)
-
-/* Return the low n bits of the bit accumulator (n < 16) */
-#define BITS(n) \
- ((unsigned)hold & ((1U << (n)) - 1))
-
-/* Remove n bits from the bit accumulator */
-#define DROPBITS(n) \
- do { \
- hold >>= (n); \
- bits -= (unsigned)(n); \
- } while (0)
-
-/* Remove zero to seven bits as needed to go to a byte boundary */
-#define BYTEBITS() \
- do { \
- hold >>= bits & 7; \
- bits -= bits & 7; \
- } while (0)
-
-/* Assure that some output space is available, by writing out the window
- if it's full. If the write fails, return from inflateBack() with a
- Z_BUF_ERROR. */
-#define ROOM() \
- do { \
- if (left == 0) { \
- put = state->window; \
- left = state->wsize; \
- state->whave = left; \
- if (out(out_desc, put, left)) { \
- ret = Z_BUF_ERROR; \
- goto inf_leave; \
- } \
- } \
- } while (0)
-
-/*
- strm provides the memory allocation functions and window buffer on input,
- and provides information on the unused input on return. For Z_DATA_ERROR
- returns, strm will also provide an error message.
-
- in() and out() are the call-back input and output functions. When
- inflateBack() needs more input, it calls in(). When inflateBack() has
- filled the window with output, or when it completes with data in the
- window, it calls out() to write out the data. The application must not
- change the provided input until in() is called again or inflateBack()
- returns. The application must not change the window/output buffer until
- inflateBack() returns.
-
- in() and out() are called with a descriptor parameter provided in the
- inflateBack() call. This parameter can be a structure that provides the
- information required to do the read or write, as well as accumulated
- information on the input and output such as totals and check values.
-
- in() should return zero on failure. out() should return non-zero on
- failure. If either in() or out() fails, than inflateBack() returns a
- Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it
- was in() or out() that caused in the error. Otherwise, inflateBack()
- returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
- error, or Z_MEM_ERROR if it could not allocate memory for the state.
- inflateBack() can also return Z_STREAM_ERROR if the input parameters
- are not correct, i.e. strm is Z_NULL or the state was not initialized.
- */
-int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)
-z_streamp strm;
-in_func in;
-void FAR *in_desc;
-out_func out;
-void FAR *out_desc;
-{
- struct inflate_state FAR *state;
- unsigned char FAR *next; /* next input */
- unsigned char FAR *put; /* next output */
- unsigned have, left; /* available input and output */
- unsigned long hold; /* bit buffer */
- unsigned bits; /* bits in bit buffer */
- unsigned copy; /* number of stored or match bytes to copy */
- unsigned char FAR *from; /* where to copy match bytes from */
- code this; /* current decoding table entry */
- code last; /* parent table entry */
- unsigned len; /* length to copy for repeats, bits to drop */
- int ret; /* return code */
- static const unsigned short order[19] = /* permutation of code lengths */
- {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
-
- /* Check that the strm exists and that the state was initialized */
- if (strm == Z_NULL || strm->state == Z_NULL)
- return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
-
- /* Reset the state */
- strm->msg = Z_NULL;
- state->mode = TYPE;
- state->last = 0;
- state->whave = 0;
- next = strm->next_in;
- have = next != Z_NULL ? strm->avail_in : 0;
- hold = 0;
- bits = 0;
- put = state->window;
- left = state->wsize;
-
- /* Inflate until end of block marked as last */
- for (;;)
- switch (state->mode) {
- case TYPE:
- /* determine and dispatch block type */
- if (state->last) {
- BYTEBITS();
- state->mode = DONE;
- break;
- }
- NEEDBITS(3);
- state->last = BITS(1);
- DROPBITS(1);
- switch (BITS(2)) {
- case 0: /* stored block */
- Tracev((stderr, "inflate: stored block%s\n",
- state->last ? " (last)" : ""));
- state->mode = STORED;
- break;
- case 1: /* fixed block */
- fixedtables(state);
- Tracev((stderr, "inflate: fixed codes block%s\n",
- state->last ? " (last)" : ""));
- state->mode = LEN; /* decode codes */
- break;
- case 2: /* dynamic block */
- Tracev((stderr, "inflate: dynamic codes block%s\n",
- state->last ? " (last)" : ""));
- state->mode = TABLE;
- break;
- case 3:
- strm->msg = (char *)"invalid block type";
- state->mode = BAD;
- }
- DROPBITS(2);
- break;
-
- case STORED:
- /* get and verify stored block length */
- BYTEBITS(); /* go to byte boundary */
- NEEDBITS(32);
- if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
- strm->msg = (char *)"invalid stored block lengths";
- state->mode = BAD;
- break;
- }
- state->length = (unsigned)hold & 0xffff;
- Tracev((stderr, "inflate: stored length %u\n",
- state->length));
- INITBITS();
-
- /* copy stored block from input to output */
- while (state->length != 0) {
- copy = state->length;
- PULL();
- ROOM();
- if (copy > have) copy = have;
- if (copy > left) copy = left;
- zmemcpy(put, next, copy);
- have -= copy;
- next += copy;
- left -= copy;
- put += copy;
- state->length -= copy;
- }
- Tracev((stderr, "inflate: stored end\n"));
- state->mode = TYPE;
- break;
-
- case TABLE:
- /* get dynamic table entries descriptor */
- NEEDBITS(14);
- state->nlen = BITS(5) + 257;
- DROPBITS(5);
- state->ndist = BITS(5) + 1;
- DROPBITS(5);
- state->ncode = BITS(4) + 4;
- DROPBITS(4);
-#ifndef PKZIP_BUG_WORKAROUND
- if (state->nlen > 286 || state->ndist > 30) {
- strm->msg = (char *)"too many length or distance symbols";
- state->mode = BAD;
- break;
- }
-#endif
- Tracev((stderr, "inflate: table sizes ok\n"));
-
- /* get code length code lengths (not a typo) */
- state->have = 0;
- while (state->have < state->ncode) {
- NEEDBITS(3);
- state->lens[order[state->have++]] = (unsigned short)BITS(3);
- DROPBITS(3);
- }
- while (state->have < 19)
- state->lens[order[state->have++]] = 0;
- state->next = state->codes;
- state->lencode = (code const FAR *)(state->next);
- state->lenbits = 7;
- ret = inflate_table(CODES, state->lens, 19, &(state->next),
- &(state->lenbits), state->work);
- if (ret) {
- strm->msg = (char *)"invalid code lengths set";
- state->mode = BAD;
- break;
- }
- Tracev((stderr, "inflate: code lengths ok\n"));
-
- /* get length and distance code code lengths */
- state->have = 0;
- while (state->have < state->nlen + state->ndist) {
- for (;;) {
- this = state->lencode[BITS(state->lenbits)];
- if ((unsigned)(this.bits) <= bits) break;
- PULLBYTE();
- }
- if (this.val < 16) {
- NEEDBITS(this.bits);
- DROPBITS(this.bits);
- state->lens[state->have++] = this.val;
- }
- else {
- if (this.val == 16) {
- NEEDBITS(this.bits + 2);
- DROPBITS(this.bits);
- if (state->have == 0) {
- strm->msg = (char *)"invalid bit length repeat";
- state->mode = BAD;
- break;
- }
- len = (unsigned)(state->lens[state->have - 1]);
- copy = 3 + BITS(2);
- DROPBITS(2);
- }
- else if (this.val == 17) {
- NEEDBITS(this.bits + 3);
- DROPBITS(this.bits);
- len = 0;
- copy = 3 + BITS(3);
- DROPBITS(3);
- }
- else {
- NEEDBITS(this.bits + 7);
- DROPBITS(this.bits);
- len = 0;
- copy = 11 + BITS(7);
- DROPBITS(7);
- }
- if (state->have + copy > state->nlen + state->ndist) {
- strm->msg = (char *)"invalid bit length repeat";
- state->mode = BAD;
- break;
- }
- while (copy--)
- state->lens[state->have++] = (unsigned short)len;
- }
- }
-
- /* handle error breaks in while */
- if (state->mode == BAD) break;
-
- /* build code tables */
- state->next = state->codes;
- state->lencode = (code const FAR *)(state->next);
- state->lenbits = 9;
- ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
- &(state->lenbits), state->work);
- if (ret) {
- strm->msg = (char *)"invalid literal/lengths set";
- state->mode = BAD;
- break;
- }
- state->distcode = (code const FAR *)(state->next);
- state->distbits = 6;
- ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
- &(state->next), &(state->distbits), state->work);
- if (ret) {
- strm->msg = (char *)"invalid distances set";
- state->mode = BAD;
- break;
- }
- Tracev((stderr, "inflate: codes ok\n"));
- state->mode = LEN;
-
- case LEN:
- /* use inflate_fast() if we have enough input and output */
- if (have >= 6 && left >= 258) {
- RESTORE();
- if (state->whave < state->wsize)
- state->whave = state->wsize - left;
- inflate_fast(strm, state->wsize);
- LOAD();
- break;
- }
-
- /* get a literal, length, or end-of-block code */
- for (;;) {
- this = state->lencode[BITS(state->lenbits)];
- if ((unsigned)(this.bits) <= bits) break;
- PULLBYTE();
- }
- if (this.op && (this.op & 0xf0) == 0) {
- last = this;
- for (;;) {
- this = state->lencode[last.val +
- (BITS(last.bits + last.op) >> last.bits)];
- if ((unsigned)(last.bits + this.bits) <= bits) break;
- PULLBYTE();
- }
- DROPBITS(last.bits);
- }
- DROPBITS(this.bits);
- state->length = (unsigned)this.val;
-
- /* process literal */
- if (this.op == 0) {
- Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
- "inflate: literal '%c'\n" :
- "inflate: literal 0x%02x\n", this.val));
- ROOM();
- *put++ = (unsigned char)(state->length);
- left--;
- state->mode = LEN;
- break;
- }
-
- /* process end of block */
- if (this.op & 32) {
- Tracevv((stderr, "inflate: end of block\n"));
- state->mode = TYPE;
- break;
- }
-
- /* invalid code */
- if (this.op & 64) {
- strm->msg = (char *)"invalid literal/length code";
- state->mode = BAD;
- break;
- }
-
- /* length code -- get extra bits, if any */
- state->extra = (unsigned)(this.op) & 15;
- if (state->extra != 0) {
- NEEDBITS(state->extra);
- state->length += BITS(state->extra);
- DROPBITS(state->extra);
- }
- Tracevv((stderr, "inflate: length %u\n", state->length));
-
- /* get distance code */
- for (;;) {
- this = state->distcode[BITS(state->distbits)];
- if ((unsigned)(this.bits) <= bits) break;
- PULLBYTE();
- }
- if ((this.op & 0xf0) == 0) {
- last = this;
- for (;;) {
- this = state->distcode[last.val +
- (BITS(last.bits + last.op) >> last.bits)];
- if ((unsigned)(last.bits + this.bits) <= bits) break;
- PULLBYTE();
- }
- DROPBITS(last.bits);
- }
- DROPBITS(this.bits);
- if (this.op & 64) {
- strm->msg = (char *)"invalid distance code";
- state->mode = BAD;
- break;
- }
- state->offset = (unsigned)this.val;
-
- /* get distance extra bits, if any */
- state->extra = (unsigned)(this.op) & 15;
- if (state->extra != 0) {
- NEEDBITS(state->extra);
- state->offset += BITS(state->extra);
- DROPBITS(state->extra);
- }
- if (state->offset > state->wsize - (state->whave < state->wsize ?
- left : 0)) {
- strm->msg = (char *)"invalid distance too far back";
- state->mode = BAD;
- break;
- }
- Tracevv((stderr, "inflate: distance %u\n", state->offset));
-
- /* copy match from window to output */
- do {
- ROOM();
- copy = state->wsize - state->offset;
- if (copy < left) {
- from = put + copy;
- copy = left - copy;
- }
- else {
- from = put - state->offset;
- copy = left;
- }
- if (copy > state->length) copy = state->length;
- state->length -= copy;
- left -= copy;
- do {
- *put++ = *from++;
- } while (--copy);
- } while (state->length != 0);
- break;
-
- case DONE:
- /* inflate stream terminated properly -- write leftover output */
- ret = Z_STREAM_END;
- if (left < state->wsize) {
- if (out(out_desc, state->window, state->wsize - left))
- ret = Z_BUF_ERROR;
- }
- goto inf_leave;
-
- case BAD:
- ret = Z_DATA_ERROR;
- goto inf_leave;
-
- default: /* can't happen, but makes compilers happy */
- ret = Z_STREAM_ERROR;
- goto inf_leave;
- }
-
- /* Return unused input */
- inf_leave:
- strm->next_in = next;
- strm->avail_in = have;
- return ret;
-}
-
-int ZEXPORT inflateBackEnd(strm)
-z_streamp strm;
-{
- if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
- return Z_STREAM_ERROR;
- ZFREE(strm, strm->state);
- strm->state = Z_NULL;
- Tracev((stderr, "inflate: end\n"));
- return Z_OK;
-}
diff --git a/WebCore/platform/image-decoders/zlib/inffast.c b/WebCore/platform/image-decoders/zlib/inffast.c
deleted file mode 100644
index bbee92e..0000000
--- a/WebCore/platform/image-decoders/zlib/inffast.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/* inffast.c -- fast decoding
- * Copyright (C) 1995-2004 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "zutil.h"
-#include "inftrees.h"
-#include "inflate.h"
-#include "inffast.h"
-
-#ifndef ASMINF
-
-/* Allow machine dependent optimization for post-increment or pre-increment.
- Based on testing to date,
- Pre-increment preferred for:
- - PowerPC G3 (Adler)
- - MIPS R5000 (Randers-Pehrson)
- Post-increment preferred for:
- - none
- No measurable difference:
- - Pentium III (Anderson)
- - M68060 (Nikl)
- */
-#ifdef POSTINC
-# define OFF 0
-# define PUP(a) *(a)++
-#else
-# define OFF 1
-# define PUP(a) *++(a)
-#endif
-
-/*
- Decode literal, length, and distance codes and write out the resulting
- literal and match bytes until either not enough input or output is
- available, an end-of-block is encountered, or a data error is encountered.
- When large enough input and output buffers are supplied to inflate(), for
- example, a 16K input buffer and a 64K output buffer, more than 95% of the
- inflate execution time is spent in this routine.
-
- Entry assumptions:
-
- state->mode == LEN
- strm->avail_in >= 6
- strm->avail_out >= 258
- start >= strm->avail_out
- state->bits < 8
-
- On return, state->mode is one of:
-
- LEN -- ran out of enough output space or enough available input
- TYPE -- reached end of block code, inflate() to interpret next block
- BAD -- error in block data
-
- Notes:
-
- - The maximum input bits used by a length/distance pair is 15 bits for the
- length code, 5 bits for the length extra, 15 bits for the distance code,
- and 13 bits for the distance extra. This totals 48 bits, or six bytes.
- Therefore if strm->avail_in >= 6, then there is enough input to avoid
- checking for available input while decoding.
-
- - The maximum bytes that a single length/distance pair can output is 258
- bytes, which is the maximum length that can be coded. inflate_fast()
- requires strm->avail_out >= 258 for each loop to avoid checking for
- output space.
- */
-void inflate_fast(strm, start)
-z_streamp strm;
-unsigned start; /* inflate()'s starting value for strm->avail_out */
-{
- struct inflate_state FAR *state;
- unsigned char FAR *in; /* local strm->next_in */
- unsigned char FAR *last; /* while in < last, enough input available */
- unsigned char FAR *out; /* local strm->next_out */
- unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
- unsigned char FAR *end; /* while out < end, enough space available */
-#ifdef INFLATE_STRICT
- unsigned dmax; /* maximum distance from zlib header */
-#endif
- unsigned wsize; /* window size or zero if not using window */
- unsigned whave; /* valid bytes in the window */
- unsigned write; /* window write index */
- unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
- unsigned long hold; /* local strm->hold */
- unsigned bits; /* local strm->bits */
- code const FAR *lcode; /* local strm->lencode */
- code const FAR *dcode; /* local strm->distcode */
- unsigned lmask; /* mask for first level of length codes */
- unsigned dmask; /* mask for first level of distance codes */
- code this; /* retrieved table entry */
- unsigned op; /* code bits, operation, extra bits, or */
- /* window position, window bytes to copy */
- unsigned len; /* match length, unused bytes */
- unsigned dist; /* match distance */
- unsigned char FAR *from; /* where to copy match from */
-
- /* copy state to local variables */
- state = (struct inflate_state FAR *)strm->state;
- in = strm->next_in - OFF;
- last = in + (strm->avail_in - 5);
- out = strm->next_out - OFF;
- beg = out - (start - strm->avail_out);
- end = out + (strm->avail_out - 257);
-#ifdef INFLATE_STRICT
- dmax = state->dmax;
-#endif
- wsize = state->wsize;
- whave = state->whave;
- write = state->write;
- window = state->window;
- hold = state->hold;
- bits = state->bits;
- lcode = state->lencode;
- dcode = state->distcode;
- lmask = (1U << state->lenbits) - 1;
- dmask = (1U << state->distbits) - 1;
-
- /* decode literals and length/distances until end-of-block or not enough
- input data or output space */
- do {
- if (bits < 15) {
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- }
- this = lcode[hold & lmask];
- dolen:
- op = (unsigned)(this.bits);
- hold >>= op;
- bits -= op;
- op = (unsigned)(this.op);
- if (op == 0) { /* literal */
- Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
- "inflate: literal '%c'\n" :
- "inflate: literal 0x%02x\n", this.val));
- PUP(out) = (unsigned char)(this.val);
- }
- else if (op & 16) { /* length base */
- len = (unsigned)(this.val);
- op &= 15; /* number of extra bits */
- if (op) {
- if (bits < op) {
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- }
- len += (unsigned)hold & ((1U << op) - 1);
- hold >>= op;
- bits -= op;
- }
- Tracevv((stderr, "inflate: length %u\n", len));
- if (bits < 15) {
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- }
- this = dcode[hold & dmask];
- dodist:
- op = (unsigned)(this.bits);
- hold >>= op;
- bits -= op;
- op = (unsigned)(this.op);
- if (op & 16) { /* distance base */
- dist = (unsigned)(this.val);
- op &= 15; /* number of extra bits */
- if (bits < op) {
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- if (bits < op) {
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- }
- }
- dist += (unsigned)hold & ((1U << op) - 1);
-#ifdef INFLATE_STRICT
- if (dist > dmax) {
- strm->msg = (char *)"invalid distance too far back";
- state->mode = BAD;
- break;
- }
-#endif
- hold >>= op;
- bits -= op;
- Tracevv((stderr, "inflate: distance %u\n", dist));
- op = (unsigned)(out - beg); /* max distance in output */
- if (dist > op) { /* see if copy from window */
- op = dist - op; /* distance back in window */
- if (op > whave) {
- strm->msg = (char *)"invalid distance too far back";
- state->mode = BAD;
- break;
- }
- from = window - OFF;
- if (write == 0) { /* very common case */
- from += wsize - op;
- if (op < len) { /* some from window */
- len -= op;
- do {
- PUP(out) = PUP(from);
- } while (--op);
- from = out - dist; /* rest from output */
- }
- }
- else if (write < op) { /* wrap around window */
- from += wsize + write - op;
- op -= write;
- if (op < len) { /* some from end of window */
- len -= op;
- do {
- PUP(out) = PUP(from);
- } while (--op);
- from = window - OFF;
- if (write < len) { /* some from start of window */
- op = write;
- len -= op;
- do {
- PUP(out) = PUP(from);
- } while (--op);
- from = out - dist; /* rest from output */
- }
- }
- }
- else { /* contiguous in window */
- from += write - op;
- if (op < len) { /* some from window */
- len -= op;
- do {
- PUP(out) = PUP(from);
- } while (--op);
- from = out - dist; /* rest from output */
- }
- }
- while (len > 2) {
- PUP(out) = PUP(from);
- PUP(out) = PUP(from);
- PUP(out) = PUP(from);
- len -= 3;
- }
- if (len) {
- PUP(out) = PUP(from);
- if (len > 1)
- PUP(out) = PUP(from);
- }
- }
- else {
- from = out - dist; /* copy direct from output */
- do { /* minimum length is three */
- PUP(out) = PUP(from);
- PUP(out) = PUP(from);
- PUP(out) = PUP(from);
- len -= 3;
- } while (len > 2);
- if (len) {
- PUP(out) = PUP(from);
- if (len > 1)
- PUP(out) = PUP(from);
- }
- }
- }
- else if ((op & 64) == 0) { /* 2nd level distance code */
- this = dcode[this.val + (hold & ((1U << op) - 1))];
- goto dodist;
- }
- else {
- strm->msg = (char *)"invalid distance code";
- state->mode = BAD;
- break;
- }
- }
- else if ((op & 64) == 0) { /* 2nd level length code */
- this = lcode[this.val + (hold & ((1U << op) - 1))];
- goto dolen;
- }
- else if (op & 32) { /* end-of-block */
- Tracevv((stderr, "inflate: end of block\n"));
- state->mode = TYPE;
- break;
- }
- else {
- strm->msg = (char *)"invalid literal/length code";
- state->mode = BAD;
- break;
- }
- } while (in < last && out < end);
-
- /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
- len = bits >> 3;
- in -= len;
- bits -= len << 3;
- hold &= (1U << bits) - 1;
-
- /* update state and return */
- strm->next_in = in + OFF;
- strm->next_out = out + OFF;
- strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
- strm->avail_out = (unsigned)(out < end ?
- 257 + (end - out) : 257 - (out - end));
- state->hold = hold;
- state->bits = bits;
- return;
-}
-
-/*
- inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
- - Using bit fields for code structure
- - Different op definition to avoid & for extra bits (do & for table bits)
- - Three separate decoding do-loops for direct, window, and write == 0
- - Special case for distance > 1 copies to do overlapped load and store copy
- - Explicit branch predictions (based on measured branch probabilities)
- - Deferring match copy and interspersed it with decoding subsequent codes
- - Swapping literal/length else
- - Swapping window/direct else
- - Larger unrolled copy loops (three is about right)
- - Moving len -= 3 statement into middle of loop
- */
-
-#endif /* !ASMINF */
diff --git a/WebCore/platform/image-decoders/zlib/inffast.h b/WebCore/platform/image-decoders/zlib/inffast.h
deleted file mode 100644
index 1e88d2d..0000000
--- a/WebCore/platform/image-decoders/zlib/inffast.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/* inffast.h -- header to use inffast.c
- * Copyright (C) 1995-2003 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-void inflate_fast OF((z_streamp strm, unsigned start));
diff --git a/WebCore/platform/image-decoders/zlib/inffixed.h b/WebCore/platform/image-decoders/zlib/inffixed.h
deleted file mode 100644
index 75ed4b5..0000000
--- a/WebCore/platform/image-decoders/zlib/inffixed.h
+++ /dev/null
@@ -1,94 +0,0 @@
- /* inffixed.h -- table for decoding fixed codes
- * Generated automatically by makefixed().
- */
-
- /* WARNING: this file should *not* be used by applications. It
- is part of the implementation of the compression library and
- is subject to change. Applications should only use zlib.h.
- */
-
- static const code lenfix[512] = {
- {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
- {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
- {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
- {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
- {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
- {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
- {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
- {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
- {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
- {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
- {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
- {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
- {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
- {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
- {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
- {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
- {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
- {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
- {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
- {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
- {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
- {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
- {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
- {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
- {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
- {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
- {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
- {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
- {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
- {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
- {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
- {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
- {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
- {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
- {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
- {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
- {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
- {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
- {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
- {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
- {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
- {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
- {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
- {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
- {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
- {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
- {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
- {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
- {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
- {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
- {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
- {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
- {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
- {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
- {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
- {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
- {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
- {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
- {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
- {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
- {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
- {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
- {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
- {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
- {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
- {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
- {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
- {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
- {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
- {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
- {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
- {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
- {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
- {0,9,255}
- };
-
- static const code distfix[32] = {
- {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
- {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
- {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
- {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
- {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
- {22,5,193},{64,5,0}
- };
diff --git a/WebCore/platform/image-decoders/zlib/inflate.c b/WebCore/platform/image-decoders/zlib/inflate.c
deleted file mode 100644
index 792fdee..0000000
--- a/WebCore/platform/image-decoders/zlib/inflate.c
+++ /dev/null
@@ -1,1368 +0,0 @@
-/* inflate.c -- zlib decompression
- * Copyright (C) 1995-2005 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/*
- * Change history:
- *
- * 1.2.beta0 24 Nov 2002
- * - First version -- complete rewrite of inflate to simplify code, avoid
- * creation of window when not needed, minimize use of window when it is
- * needed, make inffast.c even faster, implement gzip decoding, and to
- * improve code readability and style over the previous zlib inflate code
- *
- * 1.2.beta1 25 Nov 2002
- * - Use pointers for available input and output checking in inffast.c
- * - Remove input and output counters in inffast.c
- * - Change inffast.c entry and loop from avail_in >= 7 to >= 6
- * - Remove unnecessary second byte pull from length extra in inffast.c
- * - Unroll direct copy to three copies per loop in inffast.c
- *
- * 1.2.beta2 4 Dec 2002
- * - Change external routine names to reduce potential conflicts
- * - Correct filename to inffixed.h for fixed tables in inflate.c
- * - Make hbuf[] unsigned char to match parameter type in inflate.c
- * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)
- * to avoid negation problem on Alphas (64 bit) in inflate.c
- *
- * 1.2.beta3 22 Dec 2002
- * - Add comments on state->bits assertion in inffast.c
- * - Add comments on op field in inftrees.h
- * - Fix bug in reuse of allocated window after inflateReset()
- * - Remove bit fields--back to byte structure for speed
- * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths
- * - Change post-increments to pre-increments in inflate_fast(), PPC biased?
- * - Add compile time option, POSTINC, to use post-increments instead (Intel?)
- * - Make MATCH copy in inflate() much faster for when inflate_fast() not used
- * - Use local copies of stream next and avail values, as well as local bit
- * buffer and bit count in inflate()--for speed when inflate_fast() not used
- *
- * 1.2.beta4 1 Jan 2003
- * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings
- * - Move a comment on output buffer sizes from inffast.c to inflate.c
- * - Add comments in inffast.c to introduce the inflate_fast() routine
- * - Rearrange window copies in inflate_fast() for speed and simplification
- * - Unroll last copy for window match in inflate_fast()
- * - Use local copies of window variables in inflate_fast() for speed
- * - Pull out common write == 0 case for speed in inflate_fast()
- * - Make op and len in inflate_fast() unsigned for consistency
- * - Add FAR to lcode and dcode declarations in inflate_fast()
- * - Simplified bad distance check in inflate_fast()
- * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new
- * source file infback.c to provide a call-back interface to inflate for
- * programs like gzip and unzip -- uses window as output buffer to avoid
- * window copying
- *
- * 1.2.beta5 1 Jan 2003
- * - Improved inflateBack() interface to allow the caller to provide initial
- * input in strm.
- * - Fixed stored blocks bug in inflateBack()
- *
- * 1.2.beta6 4 Jan 2003
- * - Added comments in inffast.c on effectiveness of POSTINC
- * - Typecasting all around to reduce compiler warnings
- * - Changed loops from while (1) or do {} while (1) to for (;;), again to
- * make compilers happy
- * - Changed type of window in inflateBackInit() to unsigned char *
- *
- * 1.2.beta7 27 Jan 2003
- * - Changed many types to unsigned or unsigned short to avoid warnings
- * - Added inflateCopy() function
- *
- * 1.2.0 9 Mar 2003
- * - Changed inflateBack() interface to provide separate opaque descriptors
- * for the in() and out() functions
- * - Changed inflateBack() argument and in_func typedef to swap the length
- * and buffer address return values for the input function
- * - Check next_in and next_out for Z_NULL on entry to inflate()
- *
- * The history for versions after 1.2.0 are in ChangeLog in zlib distribution.
- */
-
-#include "zutil.h"
-#include "inftrees.h"
-#include "inflate.h"
-#include "inffast.h"
-
-#ifdef MAKEFIXED
-# ifndef BUILDFIXED
-# define BUILDFIXED
-# endif
-#endif
-
-/* function prototypes */
-local void fixedtables OF((struct inflate_state FAR *state));
-local int updatewindow OF((z_streamp strm, unsigned out));
-#ifdef BUILDFIXED
- void makefixed OF((void));
-#endif
-local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf,
- unsigned len));
-
-int ZEXPORT inflateReset(strm)
-z_streamp strm;
-{
- struct inflate_state FAR *state;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- strm->total_in = strm->total_out = state->total = 0;
- strm->msg = Z_NULL;
- strm->adler = 1; /* to support ill-conceived Java test suite */
- state->mode = HEAD;
- state->last = 0;
- state->havedict = 0;
- state->dmax = 32768U;
- state->head = Z_NULL;
- state->wsize = 0;
- state->whave = 0;
- state->write = 0;
- state->hold = 0;
- state->bits = 0;
- state->lencode = state->distcode = state->next = state->codes;
- Tracev((stderr, "inflate: reset\n"));
- return Z_OK;
-}
-
-int ZEXPORT inflatePrime(strm, bits, value)
-z_streamp strm;
-int bits;
-int value;
-{
- struct inflate_state FAR *state;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
- value &= (1L << bits) - 1;
- state->hold += value << state->bits;
- state->bits += bits;
- return Z_OK;
-}
-
-int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
-z_streamp strm;
-int windowBits;
-const char *version;
-int stream_size;
-{
- struct inflate_state FAR *state;
-
- if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
- stream_size != (int)(sizeof(z_stream)))
- return Z_VERSION_ERROR;
- if (strm == Z_NULL) return Z_STREAM_ERROR;
- strm->msg = Z_NULL; /* in case we return an error */
- if (strm->zalloc == (alloc_func)0) {
- strm->zalloc = zcalloc;
- strm->opaque = (voidpf)0;
- }
- if (strm->zfree == (free_func)0) strm->zfree = zcfree;
- state = (struct inflate_state FAR *)
- ZALLOC(strm, 1, sizeof(struct inflate_state));
- if (state == Z_NULL) return Z_MEM_ERROR;
- Tracev((stderr, "inflate: allocated\n"));
- strm->state = (struct internal_state FAR *)state;
- if (windowBits < 0) {
- state->wrap = 0;
- windowBits = -windowBits;
- }
- else {
- state->wrap = (windowBits >> 4) + 1;
-#ifdef GUNZIP
- if (windowBits < 48) windowBits &= 15;
-#endif
- }
- if (windowBits < 8 || windowBits > 15) {
- ZFREE(strm, state);
- strm->state = Z_NULL;
- return Z_STREAM_ERROR;
- }
- state->wbits = (unsigned)windowBits;
- state->window = Z_NULL;
- return inflateReset(strm);
-}
-
-int ZEXPORT inflateInit_(strm, version, stream_size)
-z_streamp strm;
-const char *version;
-int stream_size;
-{
- return inflateInit2_(strm, DEF_WBITS, version, stream_size);
-}
-
-/*
- Return state with length and distance decoding tables and index sizes set to
- fixed code decoding. Normally this returns fixed tables from inffixed.h.
- If BUILDFIXED is defined, then instead this routine builds the tables the
- first time it's called, and returns those tables the first time and
- thereafter. This reduces the size of the code by about 2K bytes, in
- exchange for a little execution time. However, BUILDFIXED should not be
- used for threaded applications, since the rewriting of the tables and virgin
- may not be thread-safe.
- */
-local void fixedtables(state)
-struct inflate_state FAR *state;
-{
-#ifdef BUILDFIXED
- static int virgin = 1;
- static code *lenfix, *distfix;
- static code fixed[544];
-
- /* build fixed huffman tables if first call (may not be thread safe) */
- if (virgin) {
- unsigned sym, bits;
- static code *next;
-
- /* literal/length table */
- sym = 0;
- while (sym < 144) state->lens[sym++] = 8;
- while (sym < 256) state->lens[sym++] = 9;
- while (sym < 280) state->lens[sym++] = 7;
- while (sym < 288) state->lens[sym++] = 8;
- next = fixed;
- lenfix = next;
- bits = 9;
- inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
-
- /* distance table */
- sym = 0;
- while (sym < 32) state->lens[sym++] = 5;
- distfix = next;
- bits = 5;
- inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
-
- /* do this just once */
- virgin = 0;
- }
-#else /* !BUILDFIXED */
-# include "inffixed.h"
-#endif /* BUILDFIXED */
- state->lencode = lenfix;
- state->lenbits = 9;
- state->distcode = distfix;
- state->distbits = 5;
-}
-
-#ifdef MAKEFIXED
-#include <stdio.h>
-
-/*
- Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also
- defines BUILDFIXED, so the tables are built on the fly. makefixed() writes
- those tables to stdout, which would be piped to inffixed.h. A small program
- can simply call makefixed to do this:
-
- void makefixed(void);
-
- int main(void)
- {
- makefixed();
- return 0;
- }
-
- Then that can be linked with zlib built with MAKEFIXED defined and run:
-
- a.out > inffixed.h
- */
-void makefixed()
-{
- unsigned low, size;
- struct inflate_state state;
-
- fixedtables(&state);
- puts(" /* inffixed.h -- table for decoding fixed codes");
- puts(" * Generated automatically by makefixed().");
- puts(" */");
- puts("");
- puts(" /* WARNING: this file should *not* be used by applications.");
- puts(" It is part of the implementation of this library and is");
- puts(" subject to change. Applications should only use zlib.h.");
- puts(" */");
- puts("");
- size = 1U << 9;
- printf(" static const code lenfix[%u] = {", size);
- low = 0;
- for (;;) {
- if ((low % 7) == 0) printf("\n ");
- printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits,
- state.lencode[low].val);
- if (++low == size) break;
- putchar(',');
- }
- puts("\n };");
- size = 1U << 5;
- printf("\n static const code distfix[%u] = {", size);
- low = 0;
- for (;;) {
- if ((low % 6) == 0) printf("\n ");
- printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
- state.distcode[low].val);
- if (++low == size) break;
- putchar(',');
- }
- puts("\n };");
-}
-#endif /* MAKEFIXED */
-
-/*
- Update the window with the last wsize (normally 32K) bytes written before
- returning. If window does not exist yet, create it. This is only called
- when a window is already in use, or when output has been written during this
- inflate call, but the end of the deflate stream has not been reached yet.
- It is also called to create a window for dictionary data when a dictionary
- is loaded.
-
- Providing output buffers larger than 32K to inflate() should provide a speed
- advantage, since only the last 32K of output is copied to the sliding window
- upon return from inflate(), and since all distances after the first 32K of
- output will fall in the output data, making match copies simpler and faster.
- The advantage may be dependent on the size of the processor's data caches.
- */
-local int updatewindow(strm, out)
-z_streamp strm;
-unsigned out;
-{
- struct inflate_state FAR *state;
- unsigned copy, dist;
-
- state = (struct inflate_state FAR *)strm->state;
-
- /* if it hasn't been done already, allocate space for the window */
- if (state->window == Z_NULL) {
- state->window = (unsigned char FAR *)
- ZALLOC(strm, 1U << state->wbits,
- sizeof(unsigned char));
- if (state->window == Z_NULL) return 1;
- }
-
- /* if window not in use yet, initialize */
- if (state->wsize == 0) {
- state->wsize = 1U << state->wbits;
- state->write = 0;
- state->whave = 0;
- }
-
- /* copy state->wsize or less output bytes into the circular window */
- copy = out - strm->avail_out;
- if (copy >= state->wsize) {
- zmemcpy(state->window, strm->next_out - state->wsize, state->wsize);
- state->write = 0;
- state->whave = state->wsize;
- }
- else {
- dist = state->wsize - state->write;
- if (dist > copy) dist = copy;
- zmemcpy(state->window + state->write, strm->next_out - copy, dist);
- copy -= dist;
- if (copy) {
- zmemcpy(state->window, strm->next_out - copy, copy);
- state->write = copy;
- state->whave = state->wsize;
- }
- else {
- state->write += dist;
- if (state->write == state->wsize) state->write = 0;
- if (state->whave < state->wsize) state->whave += dist;
- }
- }
- return 0;
-}
-
-/* Macros for inflate(): */
-
-/* check function to use adler32() for zlib or crc32() for gzip */
-#ifdef GUNZIP
-# define UPDATE(check, buf, len) \
- (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
-#else
-# define UPDATE(check, buf, len) adler32(check, buf, len)
-#endif
-
-/* check macros for header crc */
-#ifdef GUNZIP
-# define CRC2(check, word) \
- do { \
- hbuf[0] = (unsigned char)(word); \
- hbuf[1] = (unsigned char)((word) >> 8); \
- check = crc32(check, hbuf, 2); \
- } while (0)
-
-# define CRC4(check, word) \
- do { \
- hbuf[0] = (unsigned char)(word); \
- hbuf[1] = (unsigned char)((word) >> 8); \
- hbuf[2] = (unsigned char)((word) >> 16); \
- hbuf[3] = (unsigned char)((word) >> 24); \
- check = crc32(check, hbuf, 4); \
- } while (0)
-#endif
-
-/* Load registers with state in inflate() for speed */
-#define LOAD() \
- do { \
- put = strm->next_out; \
- left = strm->avail_out; \
- next = strm->next_in; \
- have = strm->avail_in; \
- hold = state->hold; \
- bits = state->bits; \
- } while (0)
-
-/* Restore state from registers in inflate() */
-#define RESTORE() \
- do { \
- strm->next_out = put; \
- strm->avail_out = left; \
- strm->next_in = next; \
- strm->avail_in = have; \
- state->hold = hold; \
- state->bits = bits; \
- } while (0)
-
-/* Clear the input bit accumulator */
-#define INITBITS() \
- do { \
- hold = 0; \
- bits = 0; \
- } while (0)
-
-/* Get a byte of input into the bit accumulator, or return from inflate()
- if there is no input available. */
-#define PULLBYTE() \
- do { \
- if (have == 0) goto inf_leave; \
- have--; \
- hold += (unsigned long)(*next++) << bits; \
- bits += 8; \
- } while (0)
-
-/* Assure that there are at least n bits in the bit accumulator. If there is
- not enough available input to do that, then return from inflate(). */
-#define NEEDBITS(n) \
- do { \
- while (bits < (unsigned)(n)) \
- PULLBYTE(); \
- } while (0)
-
-/* Return the low n bits of the bit accumulator (n < 16) */
-#define BITS(n) \
- ((unsigned)hold & ((1U << (n)) - 1))
-
-/* Remove n bits from the bit accumulator */
-#define DROPBITS(n) \
- do { \
- hold >>= (n); \
- bits -= (unsigned)(n); \
- } while (0)
-
-/* Remove zero to seven bits as needed to go to a byte boundary */
-#define BYTEBITS() \
- do { \
- hold >>= bits & 7; \
- bits -= bits & 7; \
- } while (0)
-
-/* Reverse the bytes in a 32-bit value */
-#define REVERSE(q) \
- ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
- (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
-
-/*
- inflate() uses a state machine to process as much input data and generate as
- much output data as possible before returning. The state machine is
- structured roughly as follows:
-
- for (;;) switch (state) {
- ...
- case STATEn:
- if (not enough input data or output space to make progress)
- return;
- ... make progress ...
- state = STATEm;
- break;
- ...
- }
-
- so when inflate() is called again, the same case is attempted again, and
- if the appropriate resources are provided, the machine proceeds to the
- next state. The NEEDBITS() macro is usually the way the state evaluates
- whether it can proceed or should return. NEEDBITS() does the return if
- the requested bits are not available. The typical use of the BITS macros
- is:
-
- NEEDBITS(n);
- ... do something with BITS(n) ...
- DROPBITS(n);
-
- where NEEDBITS(n) either returns from inflate() if there isn't enough
- input left to load n bits into the accumulator, or it continues. BITS(n)
- gives the low n bits in the accumulator. When done, DROPBITS(n) drops
- the low n bits off the accumulator. INITBITS() clears the accumulator
- and sets the number of available bits to zero. BYTEBITS() discards just
- enough bits to put the accumulator on a byte boundary. After BYTEBITS()
- and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
-
- NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
- if there is no input available. The decoding of variable length codes uses
- PULLBYTE() directly in order to pull just enough bytes to decode the next
- code, and no more.
-
- Some states loop until they get enough input, making sure that enough
- state information is maintained to continue the loop where it left off
- if NEEDBITS() returns in the loop. For example, want, need, and keep
- would all have to actually be part of the saved state in case NEEDBITS()
- returns:
-
- case STATEw:
- while (want < need) {
- NEEDBITS(n);
- keep[want++] = BITS(n);
- DROPBITS(n);
- }
- state = STATEx;
- case STATEx:
-
- As shown above, if the next state is also the next case, then the break
- is omitted.
-
- A state may also return if there is not enough output space available to
- complete that state. Those states are copying stored data, writing a
- literal byte, and copying a matching string.
-
- When returning, a "goto inf_leave" is used to update the total counters,
- update the check value, and determine whether any progress has been made
- during that inflate() call in order to return the proper return code.
- Progress is defined as a change in either strm->avail_in or strm->avail_out.
- When there is a window, goto inf_leave will update the window with the last
- output written. If a goto inf_leave occurs in the middle of decompression
- and there is no window currently, goto inf_leave will create one and copy
- output to the window for the next call of inflate().
-
- In this implementation, the flush parameter of inflate() only affects the
- return code (per zlib.h). inflate() always writes as much as possible to
- strm->next_out, given the space available and the provided input--the effect
- documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers
- the allocation of and copying into a sliding window until necessary, which
- provides the effect documented in zlib.h for Z_FINISH when the entire input
- stream available. So the only thing the flush parameter actually does is:
- when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it
- will return Z_BUF_ERROR if it has not reached the end of the stream.
- */
-
-int ZEXPORT inflate(strm, flush)
-z_streamp strm;
-int flush;
-{
- struct inflate_state FAR *state;
- unsigned char FAR *next; /* next input */
- unsigned char FAR *put; /* next output */
- unsigned have, left; /* available input and output */
- unsigned long hold; /* bit buffer */
- unsigned bits; /* bits in bit buffer */
- unsigned in, out; /* save starting available input and output */
- unsigned copy; /* number of stored or match bytes to copy */
- unsigned char FAR *from; /* where to copy match bytes from */
- code this; /* current decoding table entry */
- code last; /* parent table entry */
- unsigned len; /* length to copy for repeats, bits to drop */
- int ret; /* return code */
-#ifdef GUNZIP
- unsigned char hbuf[4]; /* buffer for gzip header crc calculation */
-#endif
- static const unsigned short order[19] = /* permutation of code lengths */
- {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
-
- if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL ||
- (strm->next_in == Z_NULL && strm->avail_in != 0))
- return Z_STREAM_ERROR;
-
- state = (struct inflate_state FAR *)strm->state;
- if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */
- LOAD();
- in = have;
- out = left;
- ret = Z_OK;
- for (;;)
- switch (state->mode) {
- case HEAD:
- if (state->wrap == 0) {
- state->mode = TYPEDO;
- break;
- }
- NEEDBITS(16);
-#ifdef GUNZIP
- if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */
- state->check = crc32(0L, Z_NULL, 0);
- CRC2(state->check, hold);
- INITBITS();
- state->mode = FLAGS;
- break;
- }
- state->flags = 0; /* expect zlib header */
- if (state->head != Z_NULL)
- state->head->done = -1;
- if (!(state->wrap & 1) || /* check if zlib header allowed */
-#else
- if (
-#endif
- ((BITS(8) << 8) + (hold >> 8)) % 31) {
- strm->msg = (char *)"incorrect header check";
- state->mode = BAD;
- break;
- }
- if (BITS(4) != Z_DEFLATED) {
- strm->msg = (char *)"unknown compression method";
- state->mode = BAD;
- break;
- }
- DROPBITS(4);
- len = BITS(4) + 8;
- if (len > state->wbits) {
- strm->msg = (char *)"invalid window size";
- state->mode = BAD;
- break;
- }
- state->dmax = 1U << len;
- Tracev((stderr, "inflate: zlib header ok\n"));
- strm->adler = state->check = adler32(0L, Z_NULL, 0);
- state->mode = hold & 0x200 ? DICTID : TYPE;
- INITBITS();
- break;
-#ifdef GUNZIP
- case FLAGS:
- NEEDBITS(16);
- state->flags = (int)(hold);
- if ((state->flags & 0xff) != Z_DEFLATED) {
- strm->msg = (char *)"unknown compression method";
- state->mode = BAD;
- break;
- }
- if (state->flags & 0xe000) {
- strm->msg = (char *)"unknown header flags set";
- state->mode = BAD;
- break;
- }
- if (state->head != Z_NULL)
- state->head->text = (int)((hold >> 8) & 1);
- if (state->flags & 0x0200) CRC2(state->check, hold);
- INITBITS();
- state->mode = TIME;
- case TIME:
- NEEDBITS(32);
- if (state->head != Z_NULL)
- state->head->time = hold;
- if (state->flags & 0x0200) CRC4(state->check, hold);
- INITBITS();
- state->mode = OS;
- case OS:
- NEEDBITS(16);
- if (state->head != Z_NULL) {
- state->head->xflags = (int)(hold & 0xff);
- state->head->os = (int)(hold >> 8);
- }
- if (state->flags & 0x0200) CRC2(state->check, hold);
- INITBITS();
- state->mode = EXLEN;
- case EXLEN:
- if (state->flags & 0x0400) {
- NEEDBITS(16);
- state->length = (unsigned)(hold);
- if (state->head != Z_NULL)
- state->head->extra_len = (unsigned)hold;
- if (state->flags & 0x0200) CRC2(state->check, hold);
- INITBITS();
- }
- else if (state->head != Z_NULL)
- state->head->extra = Z_NULL;
- state->mode = EXTRA;
- case EXTRA:
- if (state->flags & 0x0400) {
- copy = state->length;
- if (copy > have) copy = have;
- if (copy) {
- if (state->head != Z_NULL &&
- state->head->extra != Z_NULL) {
- len = state->head->extra_len - state->length;
- zmemcpy(state->head->extra + len, next,
- len + copy > state->head->extra_max ?
- state->head->extra_max - len : copy);
- }
- if (state->flags & 0x0200)
- state->check = crc32(state->check, next, copy);
- have -= copy;
- next += copy;
- state->length -= copy;
- }
- if (state->length) goto inf_leave;
- }
- state->length = 0;
- state->mode = NAME;
- case NAME:
- if (state->flags & 0x0800) {
- if (have == 0) goto inf_leave;
- copy = 0;
- do {
- len = (unsigned)(next[copy++]);
- if (state->head != Z_NULL &&
- state->head->name != Z_NULL &&
- state->length < state->head->name_max)
- state->head->name[state->length++] = len;
- } while (len && copy < have);
- if (state->flags & 0x0200)
- state->check = crc32(state->check, next, copy);
- have -= copy;
- next += copy;
- if (len) goto inf_leave;
- }
- else if (state->head != Z_NULL)
- state->head->name = Z_NULL;
- state->length = 0;
- state->mode = COMMENT;
- case COMMENT:
- if (state->flags & 0x1000) {
- if (have == 0) goto inf_leave;
- copy = 0;
- do {
- len = (unsigned)(next[copy++]);
- if (state->head != Z_NULL &&
- state->head->comment != Z_NULL &&
- state->length < state->head->comm_max)
- state->head->comment[state->length++] = len;
- } while (len && copy < have);
- if (state->flags & 0x0200)
- state->check = crc32(state->check, next, copy);
- have -= copy;
- next += copy;
- if (len) goto inf_leave;
- }
- else if (state->head != Z_NULL)
- state->head->comment = Z_NULL;
- state->mode = HCRC;
- case HCRC:
- if (state->flags & 0x0200) {
- NEEDBITS(16);
- if (hold != (state->check & 0xffff)) {
- strm->msg = (char *)"header crc mismatch";
- state->mode = BAD;
- break;
- }
- INITBITS();
- }
- if (state->head != Z_NULL) {
- state->head->hcrc = (int)((state->flags >> 9) & 1);
- state->head->done = 1;
- }
- strm->adler = state->check = crc32(0L, Z_NULL, 0);
- state->mode = TYPE;
- break;
-#endif
- case DICTID:
- NEEDBITS(32);
- strm->adler = state->check = REVERSE(hold);
- INITBITS();
- state->mode = DICT;
- case DICT:
- if (state->havedict == 0) {
- RESTORE();
- return Z_NEED_DICT;
- }
- strm->adler = state->check = adler32(0L, Z_NULL, 0);
- state->mode = TYPE;
- case TYPE:
- if (flush == Z_BLOCK) goto inf_leave;
- case TYPEDO:
- if (state->last) {
- BYTEBITS();
- state->mode = CHECK;
- break;
- }
- NEEDBITS(3);
- state->last = BITS(1);
- DROPBITS(1);
- switch (BITS(2)) {
- case 0: /* stored block */
- Tracev((stderr, "inflate: stored block%s\n",
- state->last ? " (last)" : ""));
- state->mode = STORED;
- break;
- case 1: /* fixed block */
- fixedtables(state);
- Tracev((stderr, "inflate: fixed codes block%s\n",
- state->last ? " (last)" : ""));
- state->mode = LEN; /* decode codes */
- break;
- case 2: /* dynamic block */
- Tracev((stderr, "inflate: dynamic codes block%s\n",
- state->last ? " (last)" : ""));
- state->mode = TABLE;
- break;
- case 3:
- strm->msg = (char *)"invalid block type";
- state->mode = BAD;
- }
- DROPBITS(2);
- break;
- case STORED:
- BYTEBITS(); /* go to byte boundary */
- NEEDBITS(32);
- if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
- strm->msg = (char *)"invalid stored block lengths";
- state->mode = BAD;
- break;
- }
- state->length = (unsigned)hold & 0xffff;
- Tracev((stderr, "inflate: stored length %u\n",
- state->length));
- INITBITS();
- state->mode = COPY;
- case COPY:
- copy = state->length;
- if (copy) {
- if (copy > have) copy = have;
- if (copy > left) copy = left;
- if (copy == 0) goto inf_leave;
- zmemcpy(put, next, copy);
- have -= copy;
- next += copy;
- left -= copy;
- put += copy;
- state->length -= copy;
- break;
- }
- Tracev((stderr, "inflate: stored end\n"));
- state->mode = TYPE;
- break;
- case TABLE:
- NEEDBITS(14);
- state->nlen = BITS(5) + 257;
- DROPBITS(5);
- state->ndist = BITS(5) + 1;
- DROPBITS(5);
- state->ncode = BITS(4) + 4;
- DROPBITS(4);
-#ifndef PKZIP_BUG_WORKAROUND
- if (state->nlen > 286 || state->ndist > 30) {
- strm->msg = (char *)"too many length or distance symbols";
- state->mode = BAD;
- break;
- }
-#endif
- Tracev((stderr, "inflate: table sizes ok\n"));
- state->have = 0;
- state->mode = LENLENS;
- case LENLENS:
- while (state->have < state->ncode) {
- NEEDBITS(3);
- state->lens[order[state->have++]] = (unsigned short)BITS(3);
- DROPBITS(3);
- }
- while (state->have < 19)
- state->lens[order[state->have++]] = 0;
- state->next = state->codes;
- state->lencode = (code const FAR *)(state->next);
- state->lenbits = 7;
- ret = inflate_table(CODES, state->lens, 19, &(state->next),
- &(state->lenbits), state->work);
- if (ret) {
- strm->msg = (char *)"invalid code lengths set";
- state->mode = BAD;
- break;
- }
- Tracev((stderr, "inflate: code lengths ok\n"));
- state->have = 0;
- state->mode = CODELENS;
- case CODELENS:
- while (state->have < state->nlen + state->ndist) {
- for (;;) {
- this = state->lencode[BITS(state->lenbits)];
- if ((unsigned)(this.bits) <= bits) break;
- PULLBYTE();
- }
- if (this.val < 16) {
- NEEDBITS(this.bits);
- DROPBITS(this.bits);
- state->lens[state->have++] = this.val;
- }
- else {
- if (this.val == 16) {
- NEEDBITS(this.bits + 2);
- DROPBITS(this.bits);
- if (state->have == 0) {
- strm->msg = (char *)"invalid bit length repeat";
- state->mode = BAD;
- break;
- }
- len = state->lens[state->have - 1];
- copy = 3 + BITS(2);
- DROPBITS(2);
- }
- else if (this.val == 17) {
- NEEDBITS(this.bits + 3);
- DROPBITS(this.bits);
- len = 0;
- copy = 3 + BITS(3);
- DROPBITS(3);
- }
- else {
- NEEDBITS(this.bits + 7);
- DROPBITS(this.bits);
- len = 0;
- copy = 11 + BITS(7);
- DROPBITS(7);
- }
- if (state->have + copy > state->nlen + state->ndist) {
- strm->msg = (char *)"invalid bit length repeat";
- state->mode = BAD;
- break;
- }
- while (copy--)
- state->lens[state->have++] = (unsigned short)len;
- }
- }
-
- /* handle error breaks in while */
- if (state->mode == BAD) break;
-
- /* build code tables */
- state->next = state->codes;
- state->lencode = (code const FAR *)(state->next);
- state->lenbits = 9;
- ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
- &(state->lenbits), state->work);
- if (ret) {
- strm->msg = (char *)"invalid literal/lengths set";
- state->mode = BAD;
- break;
- }
- state->distcode = (code const FAR *)(state->next);
- state->distbits = 6;
- ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
- &(state->next), &(state->distbits), state->work);
- if (ret) {
- strm->msg = (char *)"invalid distances set";
- state->mode = BAD;
- break;
- }
- Tracev((stderr, "inflate: codes ok\n"));
- state->mode = LEN;
- case LEN:
- if (have >= 6 && left >= 258) {
- RESTORE();
- inflate_fast(strm, out);
- LOAD();
- break;
- }
- for (;;) {
- this = state->lencode[BITS(state->lenbits)];
- if ((unsigned)(this.bits) <= bits) break;
- PULLBYTE();
- }
- if (this.op && (this.op & 0xf0) == 0) {
- last = this;
- for (;;) {
- this = state->lencode[last.val +
- (BITS(last.bits + last.op) >> last.bits)];
- if ((unsigned)(last.bits + this.bits) <= bits) break;
- PULLBYTE();
- }
- DROPBITS(last.bits);
- }
- DROPBITS(this.bits);
- state->length = (unsigned)this.val;
- if ((int)(this.op) == 0) {
- Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
- "inflate: literal '%c'\n" :
- "inflate: literal 0x%02x\n", this.val));
- state->mode = LIT;
- break;
- }
- if (this.op & 32) {
- Tracevv((stderr, "inflate: end of block\n"));
- state->mode = TYPE;
- break;
- }
- if (this.op & 64) {
- strm->msg = (char *)"invalid literal/length code";
- state->mode = BAD;
- break;
- }
- state->extra = (unsigned)(this.op) & 15;
- state->mode = LENEXT;
- case LENEXT:
- if (state->extra) {
- NEEDBITS(state->extra);
- state->length += BITS(state->extra);
- DROPBITS(state->extra);
- }
- Tracevv((stderr, "inflate: length %u\n", state->length));
- state->mode = DIST;
- case DIST:
- for (;;) {
- this = state->distcode[BITS(state->distbits)];
- if ((unsigned)(this.bits) <= bits) break;
- PULLBYTE();
- }
- if ((this.op & 0xf0) == 0) {
- last = this;
- for (;;) {
- this = state->distcode[last.val +
- (BITS(last.bits + last.op) >> last.bits)];
- if ((unsigned)(last.bits + this.bits) <= bits) break;
- PULLBYTE();
- }
- DROPBITS(last.bits);
- }
- DROPBITS(this.bits);
- if (this.op & 64) {
- strm->msg = (char *)"invalid distance code";
- state->mode = BAD;
- break;
- }
- state->offset = (unsigned)this.val;
- state->extra = (unsigned)(this.op) & 15;
- state->mode = DISTEXT;
- case DISTEXT:
- if (state->extra) {
- NEEDBITS(state->extra);
- state->offset += BITS(state->extra);
- DROPBITS(state->extra);
- }
-#ifdef INFLATE_STRICT
- if (state->offset > state->dmax) {
- strm->msg = (char *)"invalid distance too far back";
- state->mode = BAD;
- break;
- }
-#endif
- if (state->offset > state->whave + out - left) {
- strm->msg = (char *)"invalid distance too far back";
- state->mode = BAD;
- break;
- }
- Tracevv((stderr, "inflate: distance %u\n", state->offset));
- state->mode = MATCH;
- case MATCH:
- if (left == 0) goto inf_leave;
- copy = out - left;
- if (state->offset > copy) { /* copy from window */
- copy = state->offset - copy;
- if (copy > state->write) {
- copy -= state->write;
- from = state->window + (state->wsize - copy);
- }
- else
- from = state->window + (state->write - copy);
- if (copy > state->length) copy = state->length;
- }
- else { /* copy from output */
- from = put - state->offset;
- copy = state->length;
- }
- if (copy > left) copy = left;
- left -= copy;
- state->length -= copy;
- do {
- *put++ = *from++;
- } while (--copy);
- if (state->length == 0) state->mode = LEN;
- break;
- case LIT:
- if (left == 0) goto inf_leave;
- *put++ = (unsigned char)(state->length);
- left--;
- state->mode = LEN;
- break;
- case CHECK:
- if (state->wrap) {
- NEEDBITS(32);
- out -= left;
- strm->total_out += out;
- state->total += out;
- if (out)
- strm->adler = state->check =
- UPDATE(state->check, put - out, out);
- out = left;
- if ((
-#ifdef GUNZIP
- state->flags ? hold :
-#endif
- REVERSE(hold)) != state->check) {
- strm->msg = (char *)"incorrect data check";
- state->mode = BAD;
- break;
- }
- INITBITS();
- Tracev((stderr, "inflate: check matches trailer\n"));
- }
-#ifdef GUNZIP
- state->mode = LENGTH;
- case LENGTH:
- if (state->wrap && state->flags) {
- NEEDBITS(32);
- if (hold != (state->total & 0xffffffffUL)) {
- strm->msg = (char *)"incorrect length check";
- state->mode = BAD;
- break;
- }
- INITBITS();
- Tracev((stderr, "inflate: length matches trailer\n"));
- }
-#endif
- state->mode = DONE;
- case DONE:
- ret = Z_STREAM_END;
- goto inf_leave;
- case BAD:
- ret = Z_DATA_ERROR;
- goto inf_leave;
- case MEM:
- return Z_MEM_ERROR;
- case SYNC:
- default:
- return Z_STREAM_ERROR;
- }
-
- /*
- Return from inflate(), updating the total counts and the check value.
- If there was no progress during the inflate() call, return a buffer
- error. Call updatewindow() to create and/or update the window state.
- Note: a memory error from inflate() is non-recoverable.
- */
- inf_leave:
- RESTORE();
- if (state->wsize || (state->mode < CHECK && out != strm->avail_out))
- if (updatewindow(strm, out)) {
- state->mode = MEM;
- return Z_MEM_ERROR;
- }
- in -= strm->avail_in;
- out -= strm->avail_out;
- strm->total_in += in;
- strm->total_out += out;
- state->total += out;
- if (state->wrap && out)
- strm->adler = state->check =
- UPDATE(state->check, strm->next_out - out, out);
- strm->data_type = state->bits + (state->last ? 64 : 0) +
- (state->mode == TYPE ? 128 : 0);
- if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
- ret = Z_BUF_ERROR;
- return ret;
-}
-
-int ZEXPORT inflateEnd(strm)
-z_streamp strm;
-{
- struct inflate_state FAR *state;
- if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
- return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- if (state->window != Z_NULL) ZFREE(strm, state->window);
- ZFREE(strm, strm->state);
- strm->state = Z_NULL;
- Tracev((stderr, "inflate: end\n"));
- return Z_OK;
-}
-
-int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
-z_streamp strm;
-const Bytef *dictionary;
-uInt dictLength;
-{
- struct inflate_state FAR *state;
- unsigned long id;
-
- /* check state */
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- if (state->wrap != 0 && state->mode != DICT)
- return Z_STREAM_ERROR;
-
- /* check for correct dictionary id */
- if (state->mode == DICT) {
- id = adler32(0L, Z_NULL, 0);
- id = adler32(id, dictionary, dictLength);
- if (id != state->check)
- return Z_DATA_ERROR;
- }
-
- /* copy dictionary to window */
- if (updatewindow(strm, strm->avail_out)) {
- state->mode = MEM;
- return Z_MEM_ERROR;
- }
- if (dictLength > state->wsize) {
- zmemcpy(state->window, dictionary + dictLength - state->wsize,
- state->wsize);
- state->whave = state->wsize;
- }
- else {
- zmemcpy(state->window + state->wsize - dictLength, dictionary,
- dictLength);
- state->whave = dictLength;
- }
- state->havedict = 1;
- Tracev((stderr, "inflate: dictionary set\n"));
- return Z_OK;
-}
-
-int ZEXPORT inflateGetHeader(strm, head)
-z_streamp strm;
-gz_headerp head;
-{
- struct inflate_state FAR *state;
-
- /* check state */
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
-
- /* save header structure */
- state->head = head;
- head->done = 0;
- return Z_OK;
-}
-
-/*
- Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found
- or when out of input. When called, *have is the number of pattern bytes
- found in order so far, in 0..3. On return *have is updated to the new
- state. If on return *have equals four, then the pattern was found and the
- return value is how many bytes were read including the last byte of the
- pattern. If *have is less than four, then the pattern has not been found
- yet and the return value is len. In the latter case, syncsearch() can be
- called again with more data and the *have state. *have is initialized to
- zero for the first call.
- */
-local unsigned syncsearch(have, buf, len)
-unsigned FAR *have;
-unsigned char FAR *buf;
-unsigned len;
-{
- unsigned got;
- unsigned next;
-
- got = *have;
- next = 0;
- while (next < len && got < 4) {
- if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
- got++;
- else if (buf[next])
- got = 0;
- else
- got = 4 - got;
- next++;
- }
- *have = got;
- return next;
-}
-
-int ZEXPORT inflateSync(strm)
-z_streamp strm;
-{
- unsigned len; /* number of bytes to look at or looked at */
- unsigned long in, out; /* temporary to save total_in and total_out */
- unsigned char buf[4]; /* to restore bit buffer to byte string */
- struct inflate_state FAR *state;
-
- /* check parameters */
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
-
- /* if first time, start search in bit buffer */
- if (state->mode != SYNC) {
- state->mode = SYNC;
- state->hold <<= state->bits & 7;
- state->bits -= state->bits & 7;
- len = 0;
- while (state->bits >= 8) {
- buf[len++] = (unsigned char)(state->hold);
- state->hold >>= 8;
- state->bits -= 8;
- }
- state->have = 0;
- syncsearch(&(state->have), buf, len);
- }
-
- /* search available input */
- len = syncsearch(&(state->have), strm->next_in, strm->avail_in);
- strm->avail_in -= len;
- strm->next_in += len;
- strm->total_in += len;
-
- /* return no joy or set up to restart inflate() on a new block */
- if (state->have != 4) return Z_DATA_ERROR;
- in = strm->total_in; out = strm->total_out;
- inflateReset(strm);
- strm->total_in = in; strm->total_out = out;
- state->mode = TYPE;
- return Z_OK;
-}
-
-/*
- Returns true if inflate is currently at the end of a block generated by
- Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
- implementation to provide an additional safety check. PPP uses
- Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
- block. When decompressing, PPP checks that at the end of input packet,
- inflate is waiting for these length bytes.
- */
-int ZEXPORT inflateSyncPoint(strm)
-z_streamp strm;
-{
- struct inflate_state FAR *state;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- return state->mode == STORED && state->bits == 0;
-}
-
-int ZEXPORT inflateCopy(dest, source)
-z_streamp dest;
-z_streamp source;
-{
- struct inflate_state FAR *state;
- struct inflate_state FAR *copy;
- unsigned char FAR *window;
- unsigned wsize;
-
- /* check input */
- if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL ||
- source->zalloc == (alloc_func)0 || source->zfree == (free_func)0)
- return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)source->state;
-
- /* allocate space */
- copy = (struct inflate_state FAR *)
- ZALLOC(source, 1, sizeof(struct inflate_state));
- if (copy == Z_NULL) return Z_MEM_ERROR;
- window = Z_NULL;
- if (state->window != Z_NULL) {
- window = (unsigned char FAR *)
- ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));
- if (window == Z_NULL) {
- ZFREE(source, copy);
- return Z_MEM_ERROR;
- }
- }
-
- /* copy state */
- zmemcpy(dest, source, sizeof(z_stream));
- zmemcpy(copy, state, sizeof(struct inflate_state));
- if (state->lencode >= state->codes &&
- state->lencode <= state->codes + ENOUGH - 1) {
- copy->lencode = copy->codes + (state->lencode - state->codes);
- copy->distcode = copy->codes + (state->distcode - state->codes);
- }
- copy->next = copy->codes + (state->next - state->codes);
- if (window != Z_NULL) {
- wsize = 1U << state->wbits;
- zmemcpy(window, state->window, wsize);
- }
- copy->window = window;
- dest->state = (struct internal_state FAR *)copy;
- return Z_OK;
-}
diff --git a/WebCore/platform/image-decoders/zlib/inflate.h b/WebCore/platform/image-decoders/zlib/inflate.h
deleted file mode 100644
index 07bd3e7..0000000
--- a/WebCore/platform/image-decoders/zlib/inflate.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/* inflate.h -- internal inflate state definition
- * Copyright (C) 1995-2004 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* define NO_GZIP when compiling if you want to disable gzip header and
- trailer decoding by inflate(). NO_GZIP would be used to avoid linking in
- the crc code when it is not needed. For shared libraries, gzip decoding
- should be left enabled. */
-#ifndef NO_GZIP
-# define GUNZIP
-#endif
-
-/* Possible inflate modes between inflate() calls */
-typedef enum {
- HEAD, /* i: waiting for magic header */
- FLAGS, /* i: waiting for method and flags (gzip) */
- TIME, /* i: waiting for modification time (gzip) */
- OS, /* i: waiting for extra flags and operating system (gzip) */
- EXLEN, /* i: waiting for extra length (gzip) */
- EXTRA, /* i: waiting for extra bytes (gzip) */
- NAME, /* i: waiting for end of file name (gzip) */
- COMMENT, /* i: waiting for end of comment (gzip) */
- HCRC, /* i: waiting for header crc (gzip) */
- DICTID, /* i: waiting for dictionary check value */
- DICT, /* waiting for inflateSetDictionary() call */
- TYPE, /* i: waiting for type bits, including last-flag bit */
- TYPEDO, /* i: same, but skip check to exit inflate on new block */
- STORED, /* i: waiting for stored size (length and complement) */
- COPY, /* i/o: waiting for input or output to copy stored block */
- TABLE, /* i: waiting for dynamic block table lengths */
- LENLENS, /* i: waiting for code length code lengths */
- CODELENS, /* i: waiting for length/lit and distance code lengths */
- LEN, /* i: waiting for length/lit code */
- LENEXT, /* i: waiting for length extra bits */
- DIST, /* i: waiting for distance code */
- DISTEXT, /* i: waiting for distance extra bits */
- MATCH, /* o: waiting for output space to copy string */
- LIT, /* o: waiting for output space to write literal */
- CHECK, /* i: waiting for 32-bit check value */
- LENGTH, /* i: waiting for 32-bit length (gzip) */
- DONE, /* finished check, done -- remain here until reset */
- BAD, /* got a data error -- remain here until reset */
- MEM, /* got an inflate() memory error -- remain here until reset */
- SYNC /* looking for synchronization bytes to restart inflate() */
-} inflate_mode;
-
-/*
- State transitions between above modes -
-
- (most modes can go to the BAD or MEM mode -- not shown for clarity)
-
- Process header:
- HEAD -> (gzip) or (zlib)
- (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME
- NAME -> COMMENT -> HCRC -> TYPE
- (zlib) -> DICTID or TYPE
- DICTID -> DICT -> TYPE
- Read deflate blocks:
- TYPE -> STORED or TABLE or LEN or CHECK
- STORED -> COPY -> TYPE
- TABLE -> LENLENS -> CODELENS -> LEN
- Read deflate codes:
- LEN -> LENEXT or LIT or TYPE
- LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
- LIT -> LEN
- Process trailer:
- CHECK -> LENGTH -> DONE
- */
-
-/* state maintained between inflate() calls. Approximately 7K bytes. */
-struct inflate_state {
- inflate_mode mode; /* current inflate mode */
- int last; /* true if processing last block */
- int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
- int havedict; /* true if dictionary provided */
- int flags; /* gzip header method and flags (0 if zlib) */
- unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
- unsigned long check; /* protected copy of check value */
- unsigned long total; /* protected copy of output count */
- gz_headerp head; /* where to save gzip header information */
- /* sliding window */
- unsigned wbits; /* log base 2 of requested window size */
- unsigned wsize; /* window size or zero if not using window */
- unsigned whave; /* valid bytes in the window */
- unsigned write; /* window write index */
- unsigned char FAR *window; /* allocated sliding window, if needed */
- /* bit accumulator */
- unsigned long hold; /* input bit accumulator */
- unsigned bits; /* number of bits in "in" */
- /* for string and stored block copying */
- unsigned length; /* literal or length of data to copy */
- unsigned offset; /* distance back to copy string from */
- /* for table and code decoding */
- unsigned extra; /* extra bits needed */
- /* fixed and dynamic code tables */
- code const FAR *lencode; /* starting table for length/literal codes */
- code const FAR *distcode; /* starting table for distance codes */
- unsigned lenbits; /* index bits for lencode */
- unsigned distbits; /* index bits for distcode */
- /* dynamic table building */
- unsigned ncode; /* number of code length code lengths */
- unsigned nlen; /* number of length code lengths */
- unsigned ndist; /* number of distance code lengths */
- unsigned have; /* number of code lengths in lens[] */
- code FAR *next; /* next available space in codes[] */
- unsigned short lens[320]; /* temporary storage for code lengths */
- unsigned short work[288]; /* work area for code table building */
- code codes[ENOUGH]; /* space for code tables */
-};
diff --git a/WebCore/platform/image-decoders/zlib/inftrees.c b/WebCore/platform/image-decoders/zlib/inftrees.c
deleted file mode 100644
index 8a9c13f..0000000
--- a/WebCore/platform/image-decoders/zlib/inftrees.c
+++ /dev/null
@@ -1,329 +0,0 @@
-/* inftrees.c -- generate Huffman trees for efficient decoding
- * Copyright (C) 1995-2005 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "zutil.h"
-#include "inftrees.h"
-
-#define MAXBITS 15
-
-const char inflate_copyright[] =
- " inflate 1.2.3 Copyright 1995-2005 Mark Adler ";
-/*
- If you use the zlib library in a product, an acknowledgment is welcome
- in the documentation of your product. If for some reason you cannot
- include such an acknowledgment, I would appreciate that you keep this
- copyright string in the executable of your product.
- */
-
-/*
- Build a set of tables to decode the provided canonical Huffman code.
- The code lengths are lens[0..codes-1]. The result starts at *table,
- whose indices are 0..2^bits-1. work is a writable array of at least
- lens shorts, which is used as a work area. type is the type of code
- to be generated, CODES, LENS, or DISTS. On return, zero is success,
- -1 is an invalid code, and +1 means that ENOUGH isn't enough. table
- on return points to the next available entry's address. bits is the
- requested root table index bits, and on return it is the actual root
- table index bits. It will differ if the request is greater than the
- longest code or if it is less than the shortest code.
- */
-int inflate_table(type, lens, codes, table, bits, work)
-codetype type;
-unsigned short FAR *lens;
-unsigned codes;
-code FAR * FAR *table;
-unsigned FAR *bits;
-unsigned short FAR *work;
-{
- unsigned len; /* a code's length in bits */
- unsigned sym; /* index of code symbols */
- unsigned min, max; /* minimum and maximum code lengths */
- unsigned root; /* number of index bits for root table */
- unsigned curr; /* number of index bits for current table */
- unsigned drop; /* code bits to drop for sub-table */
- int left; /* number of prefix codes available */
- unsigned used; /* code entries in table used */
- unsigned huff; /* Huffman code */
- unsigned incr; /* for incrementing code, index */
- unsigned fill; /* index for replicating entries */
- unsigned low; /* low bits for current root entry */
- unsigned mask; /* mask for low root bits */
- code this; /* table entry for duplication */
- code FAR *next; /* next available space in table */
- const unsigned short FAR *base; /* base value table to use */
- const unsigned short FAR *extra; /* extra bits table to use */
- int end; /* use base and extra for symbol > end */
- unsigned short count[MAXBITS+1]; /* number of codes of each length */
- unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
- static const unsigned short lbase[31] = { /* Length codes 257..285 base */
- 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
- 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
- static const unsigned short lext[31] = { /* Length codes 257..285 extra */
- 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
- 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196};
- static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
- 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
- 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
- 8193, 12289, 16385, 24577, 0, 0};
- static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
- 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
- 23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
- 28, 28, 29, 29, 64, 64};
-
- /*
- Process a set of code lengths to create a canonical Huffman code. The
- code lengths are lens[0..codes-1]. Each length corresponds to the
- symbols 0..codes-1. The Huffman code is generated by first sorting the
- symbols by length from short to long, and retaining the symbol order
- for codes with equal lengths. Then the code starts with all zero bits
- for the first code of the shortest length, and the codes are integer
- increments for the same length, and zeros are appended as the length
- increases. For the deflate format, these bits are stored backwards
- from their more natural integer increment ordering, and so when the
- decoding tables are built in the large loop below, the integer codes
- are incremented backwards.
-
- This routine assumes, but does not check, that all of the entries in
- lens[] are in the range 0..MAXBITS. The caller must assure this.
- 1..MAXBITS is interpreted as that code length. zero means that that
- symbol does not occur in this code.
-
- The codes are sorted by computing a count of codes for each length,
- creating from that a table of starting indices for each length in the
- sorted table, and then entering the symbols in order in the sorted
- table. The sorted table is work[], with that space being provided by
- the caller.
-
- The length counts are used for other purposes as well, i.e. finding
- the minimum and maximum length codes, determining if there are any
- codes at all, checking for a valid set of lengths, and looking ahead
- at length counts to determine sub-table sizes when building the
- decoding tables.
- */
-
- /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
- for (len = 0; len <= MAXBITS; len++)
- count[len] = 0;
- for (sym = 0; sym < codes; sym++)
- count[lens[sym]]++;
-
- /* bound code lengths, force root to be within code lengths */
- root = *bits;
- for (max = MAXBITS; max >= 1; max--)
- if (count[max] != 0) break;
- if (root > max) root = max;
- if (max == 0) { /* no symbols to code at all */
- this.op = (unsigned char)64; /* invalid code marker */
- this.bits = (unsigned char)1;
- this.val = (unsigned short)0;
- *(*table)++ = this; /* make a table to force an error */
- *(*table)++ = this;
- *bits = 1;
- return 0; /* no symbols, but wait for decoding to report error */
- }
- for (min = 1; min <= MAXBITS; min++)
- if (count[min] != 0) break;
- if (root < min) root = min;
-
- /* check for an over-subscribed or incomplete set of lengths */
- left = 1;
- for (len = 1; len <= MAXBITS; len++) {
- left <<= 1;
- left -= count[len];
- if (left < 0) return -1; /* over-subscribed */
- }
- if (left > 0 && (type == CODES || max != 1))
- return -1; /* incomplete set */
-
- /* generate offsets into symbol table for each length for sorting */
- offs[1] = 0;
- for (len = 1; len < MAXBITS; len++)
- offs[len + 1] = offs[len] + count[len];
-
- /* sort symbols by length, by symbol order within each length */
- for (sym = 0; sym < codes; sym++)
- if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
-
- /*
- Create and fill in decoding tables. In this loop, the table being
- filled is at next and has curr index bits. The code being used is huff
- with length len. That code is converted to an index by dropping drop
- bits off of the bottom. For codes where len is less than drop + curr,
- those top drop + curr - len bits are incremented through all values to
- fill the table with replicated entries.
-
- root is the number of index bits for the root table. When len exceeds
- root, sub-tables are created pointed to by the root entry with an index
- of the low root bits of huff. This is saved in low to check for when a
- new sub-table should be started. drop is zero when the root table is
- being filled, and drop is root when sub-tables are being filled.
-
- When a new sub-table is needed, it is necessary to look ahead in the
- code lengths to determine what size sub-table is needed. The length
- counts are used for this, and so count[] is decremented as codes are
- entered in the tables.
-
- used keeps track of how many table entries have been allocated from the
- provided *table space. It is checked when a LENS table is being made
- against the space in *table, ENOUGH, minus the maximum space needed by
- the worst case distance code, MAXD. This should never happen, but the
- sufficiency of ENOUGH has not been proven exhaustively, hence the check.
- This assumes that when type == LENS, bits == 9.
-
- sym increments through all symbols, and the loop terminates when
- all codes of length max, i.e. all codes, have been processed. This
- routine permits incomplete codes, so another loop after this one fills
- in the rest of the decoding tables with invalid code markers.
- */
-
- /* set up for code type */
- switch (type) {
- case CODES:
- base = extra = work; /* dummy value--not used */
- end = 19;
- break;
- case LENS:
- base = lbase;
- base -= 257;
- extra = lext;
- extra -= 257;
- end = 256;
- break;
- default: /* DISTS */
- base = dbase;
- extra = dext;
- end = -1;
- }
-
- /* initialize state for loop */
- huff = 0; /* starting code */
- sym = 0; /* starting code symbol */
- len = min; /* starting code length */
- next = *table; /* current table to fill in */
- curr = root; /* current table index bits */
- drop = 0; /* current bits to drop from code for index */
- low = (unsigned)(-1); /* trigger new sub-table when len > root */
- used = 1U << root; /* use root table entries */
- mask = used - 1; /* mask for comparing low */
-
- /* check available table space */
- if (type == LENS && used >= ENOUGH - MAXD)
- return 1;
-
- /* process all codes and make table entries */
- for (;;) {
- /* create table entry */
- this.bits = (unsigned char)(len - drop);
- if ((int)(work[sym]) < end) {
- this.op = (unsigned char)0;
- this.val = work[sym];
- }
- else if ((int)(work[sym]) > end) {
- this.op = (unsigned char)(extra[work[sym]]);
- this.val = base[work[sym]];
- }
- else {
- this.op = (unsigned char)(32 + 64); /* end of block */
- this.val = 0;
- }
-
- /* replicate for those indices with low len bits equal to huff */
- incr = 1U << (len - drop);
- fill = 1U << curr;
- min = fill; /* save offset to next table */
- do {
- fill -= incr;
- next[(huff >> drop) + fill] = this;
- } while (fill != 0);
-
- /* backwards increment the len-bit code huff */
- incr = 1U << (len - 1);
- while (huff & incr)
- incr >>= 1;
- if (incr != 0) {
- huff &= incr - 1;
- huff += incr;
- }
- else
- huff = 0;
-
- /* go to next symbol, update count, len */
- sym++;
- if (--(count[len]) == 0) {
- if (len == max) break;
- len = lens[work[sym]];
- }
-
- /* create new sub-table if needed */
- if (len > root && (huff & mask) != low) {
- /* if first time, transition to sub-tables */
- if (drop == 0)
- drop = root;
-
- /* increment past last table */
- next += min; /* here min is 1 << curr */
-
- /* determine length of next table */
- curr = len - drop;
- left = (int)(1 << curr);
- while (curr + drop < max) {
- left -= count[curr + drop];
- if (left <= 0) break;
- curr++;
- left <<= 1;
- }
-
- /* check for enough space */
- used += 1U << curr;
- if (type == LENS && used >= ENOUGH - MAXD)
- return 1;
-
- /* point entry in root table to sub-table */
- low = huff & mask;
- (*table)[low].op = (unsigned char)curr;
- (*table)[low].bits = (unsigned char)root;
- (*table)[low].val = (unsigned short)(next - *table);
- }
- }
-
- /*
- Fill in rest of table for incomplete codes. This loop is similar to the
- loop above in incrementing huff for table indices. It is assumed that
- len is equal to curr + drop, so there is no loop needed to increment
- through high index bits. When the current sub-table is filled, the loop
- drops back to the root table to fill in any remaining entries there.
- */
- this.op = (unsigned char)64; /* invalid code marker */
- this.bits = (unsigned char)(len - drop);
- this.val = (unsigned short)0;
- while (huff != 0) {
- /* when done with sub-table, drop back to root table */
- if (drop != 0 && (huff & mask) != low) {
- drop = 0;
- len = root;
- next = *table;
- this.bits = (unsigned char)len;
- }
-
- /* put invalid code marker in table */
- next[huff >> drop] = this;
-
- /* backwards increment the len-bit code huff */
- incr = 1U << (len - 1);
- while (huff & incr)
- incr >>= 1;
- if (incr != 0) {
- huff &= incr - 1;
- huff += incr;
- }
- else
- huff = 0;
- }
-
- /* set return parameters */
- *table += used;
- *bits = root;
- return 0;
-}
diff --git a/WebCore/platform/image-decoders/zlib/inftrees.h b/WebCore/platform/image-decoders/zlib/inftrees.h
deleted file mode 100644
index b1104c8..0000000
--- a/WebCore/platform/image-decoders/zlib/inftrees.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* inftrees.h -- header to use inftrees.c
- * Copyright (C) 1995-2005 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* Structure for decoding tables. Each entry provides either the
- information needed to do the operation requested by the code that
- indexed that table entry, or it provides a pointer to another
- table that indexes more bits of the code. op indicates whether
- the entry is a pointer to another table, a literal, a length or
- distance, an end-of-block, or an invalid code. For a table
- pointer, the low four bits of op is the number of index bits of
- that table. For a length or distance, the low four bits of op
- is the number of extra bits to get after the code. bits is
- the number of bits in this code or part of the code to drop off
- of the bit buffer. val is the actual byte to output in the case
- of a literal, the base length or distance, or the offset from
- the current table to the next table. Each entry is four bytes. */
-typedef struct {
- unsigned char op; /* operation, extra bits, table bits */
- unsigned char bits; /* bits in this part of the code */
- unsigned short val; /* offset in table or code value */
-} code;
-
-/* op values as set by inflate_table():
- 00000000 - literal
- 0000tttt - table link, tttt != 0 is the number of table index bits
- 0001eeee - length or distance, eeee is the number of extra bits
- 01100000 - end of block
- 01000000 - invalid code
- */
-
-/* Maximum size of dynamic tree. The maximum found in a long but non-
- exhaustive search was 1444 code structures (852 for length/literals
- and 592 for distances, the latter actually the result of an
- exhaustive search). The true maximum is not known, but the value
- below is more than safe. */
-#define ENOUGH 2048
-#define MAXD 592
-
-/* Type of code to build for inftable() */
-typedef enum {
- CODES,
- LENS,
- DISTS
-} codetype;
-
-extern int inflate_table OF((codetype type, unsigned short FAR *lens,
- unsigned codes, code FAR * FAR *table,
- unsigned FAR *bits, unsigned short FAR *work));
diff --git a/WebCore/platform/image-decoders/zlib/mozzconf.h b/WebCore/platform/image-decoders/zlib/mozzconf.h
deleted file mode 100644
index 118185c..0000000
--- a/WebCore/platform/image-decoders/zlib/mozzconf.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is the mozilla zlib configuration.
- *
- * The Initial Developer of the Original Code is IBM Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2004
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef MOZZCONF_H
-#define MOZZCONF_H
-
-#if defined(XP_WIN) && defined(ZLIB_DLL) && !defined(MOZ_ENABLE_LIBXUL)
-#undef ZLIB_DLL
-#endif
-
-#ifdef HAVE_VISIBILITY_ATTRIBUTE
-#define ZEXTERN __attribute__((visibility ("default"))) extern
-#endif
-
-/* Exported Symbols */
-#define zlibVersion MOZ_Z_zlibVersion
-#define deflate MOZ_Z_deflate
-#define deflateEnd MOZ_Z_deflateEnd
-#define inflate MOZ_Z_inflate
-#define inflateEnd MOZ_Z_inflateEnd
-#define deflateSetDictionary MOZ_Z_deflateSetDictionary
-#define deflateCopy MOZ_Z_deflateCopy
-#define deflateReset MOZ_Z_deflateReset
-#define deflateParams MOZ_Z_deflateParams
-#define deflateBound MOZ_Z_deflateBound
-#define deflatePrime MOZ_Z_deflatePrime
-#define inflateSetDictionary MOZ_Z_inflateSetDictionary
-#define inflateSync MOZ_Z_inflateSync
-#define inflateCopy MOZ_Z_inflateCopy
-#define inflateReset MOZ_Z_inflateReset
-#define inflateBack MOZ_Z_inflateBack
-#define inflateBackEnd MOZ_Z_inflateBackEnd
-#define zlibCompileFlags MOZ_Z_zlibCompileFlags
-#define compress MOZ_Z_compress
-#define compress2 MOZ_Z_compress2
-#define compressBound MOZ_Z_compressBound
-#define uncompress MOZ_Z_uncompress
-#define gzopen MOZ_Z_gzopen
-#define gzdopen MOZ_Z_gzdopen
-#define gzsetparams MOZ_Z_gzsetparams
-#define gzread MOZ_Z_gzread
-#define gzwrite MOZ_Z_gzwrite
-#define gzprintf MOZ_Z_gzprintf
-#define gzputs MOZ_Z_gzputs
-#define gzgets MOZ_Z_gzgets
-#define gzputc MOZ_Z_gzputc
-#define gzgetc MOZ_Z_gzgetc
-#define gzungetc MOZ_Z_gzungetc
-#define gzflush MOZ_Z_gzflush
-#define gzseek MOZ_Z_gzseek
-#define gzrewind MOZ_Z_gzrewind
-#define gztell MOZ_Z_gztell
-#define gzeof MOZ_Z_gzeof
-#define gzclose MOZ_Z_gzclose
-#define gzerror MOZ_Z_gzerror
-#define gzclearerr MOZ_Z_gzclearerr
-#define adler32 MOZ_Z_adler32
-#define crc32 MOZ_Z_crc32
-#define deflateInit_ MOZ_Z_deflateInit_
-#define deflateInit2_ MOZ_Z_deflateInit2_
-#define inflateInit_ MOZ_Z_inflateInit_
-#define inflateInit2_ MOZ_Z_inflateInit2_
-#define inflateBackInit_ MOZ_Z_inflateBackInit_
-#define inflateSyncPoint MOZ_Z_inflateSyncPoint
-#define get_crc_table MOZ_Z_get_crc_table
-#define zError MOZ_Z_zError
-
-/* Extra global symbols */
-#define _dist_code MOZ_Z__dist_code
-#define _length_code MOZ_Z__length_code
-#define _tr_align MOZ_Z__tr_align
-#define _tr_flush_block MOZ_Z__tr_flush_block
-#define _tr_init MOZ_Z__tr_init
-#define _tr_stored_block MOZ_Z__tr_stored_block
-#define _tr_tally MOZ_Z__tr_tally
-#define deflate_copyright MOZ_Z_deflate_copyright
-#define inflate_copyright MOZ_Z_inflate_copyright
-#define inflate_fast MOZ_Z_inflate_fast
-#define inflate_table MOZ_Z_inflate_table
-#define z_errmsg MOZ_Z_z_errmsg
-#define zcalloc MOZ_Z_zcalloc
-#define zcfree MOZ_Z_zcfree
-#define alloc_func MOZ_Z_alloc_func
-#define free_func MOZ_Z_free_func
-#define in_func MOZ_Z_in_func
-#define out_func MOZ_Z_out_func
-
-/* New as of libpng-1.2.3 */
-#define adler32_combine MOZ_Z_adler32_combine
-#define crc32_combine MOZ_Z_crc32_combine
-#define deflateSetHeader MOZ_Z_deflateSetHeader
-#define deflateTune MOZ_Z_deflateTune
-#define gzdirect MOZ_Z_gzdirect
-#define inflatePrime MOZ_Z_inflatePrime
-#define inflateGetHeader MOZ_Z_inflateGetHeader
-
-#endif
diff --git a/WebCore/platform/image-decoders/zlib/trees.c b/WebCore/platform/image-decoders/zlib/trees.c
deleted file mode 100644
index 0cbfae2..0000000
--- a/WebCore/platform/image-decoders/zlib/trees.c
+++ /dev/null
@@ -1,1219 +0,0 @@
-/* trees.c -- output deflated data using Huffman coding
- * Copyright (C) 1995-2005 Jean-loup Gailly
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/*
- * ALGORITHM
- *
- * The "deflation" process uses several Huffman trees. The more
- * common source values are represented by shorter bit sequences.
- *
- * Each code tree is stored in a compressed form which is itself
- * a Huffman encoding of the lengths of all the code strings (in
- * ascending order by source values). The actual code strings are
- * reconstructed from the lengths in the inflate process, as described
- * in the deflate specification.
- *
- * REFERENCES
- *
- * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
- * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
- *
- * Storer, James A.
- * Data Compression: Methods and Theory, pp. 49-50.
- * Computer Science Press, 1988. ISBN 0-7167-8156-5.
- *
- * Sedgewick, R.
- * Algorithms, p290.
- * Addison-Wesley, 1983. ISBN 0-201-06672-6.
- */
-
-/* @(#) $Id: trees.c,v 3.6 2005/08/04 19:14:14 tor%cs.brown.edu Exp $ */
-
-/* #define GEN_TREES_H */
-
-#include "deflate.h"
-
-#ifdef DEBUG
-# include <ctype.h>
-#endif
-
-/* ===========================================================================
- * Constants
- */
-
-#define MAX_BL_BITS 7
-/* Bit length codes must not exceed MAX_BL_BITS bits */
-
-#define END_BLOCK 256
-/* end of block literal code */
-
-#define REP_3_6 16
-/* repeat previous bit length 3-6 times (2 bits of repeat count) */
-
-#define REPZ_3_10 17
-/* repeat a zero length 3-10 times (3 bits of repeat count) */
-
-#define REPZ_11_138 18
-/* repeat a zero length 11-138 times (7 bits of repeat count) */
-
-local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
- = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
-
-local const int extra_dbits[D_CODES] /* extra bits for each distance code */
- = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
-
-local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
- = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
-
-local const uch bl_order[BL_CODES]
- = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
-/* The lengths of the bit length codes are sent in order of decreasing
- * probability, to avoid transmitting the lengths for unused bit length codes.
- */
-
-#define Buf_size (8 * 2*sizeof(char))
-/* Number of bits used within bi_buf. (bi_buf might be implemented on
- * more than 16 bits on some systems.)
- */
-
-/* ===========================================================================
- * Local data. These are initialized only once.
- */
-
-#define DIST_CODE_LEN 512 /* see definition of array dist_code below */
-
-#if defined(GEN_TREES_H) || !defined(STDC)
-/* non ANSI compilers may not accept trees.h */
-
-local ct_data static_ltree[L_CODES+2];
-/* The static literal tree. Since the bit lengths are imposed, there is no
- * need for the L_CODES extra codes used during heap construction. However
- * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
- * below).
- */
-
-local ct_data static_dtree[D_CODES];
-/* The static distance tree. (Actually a trivial tree since all codes use
- * 5 bits.)
- */
-
-uch _dist_code[DIST_CODE_LEN];
-/* Distance codes. The first 256 values correspond to the distances
- * 3 .. 258, the last 256 values correspond to the top 8 bits of
- * the 15 bit distances.
- */
-
-uch _length_code[MAX_MATCH-MIN_MATCH+1];
-/* length code for each normalized match length (0 == MIN_MATCH) */
-
-local int base_length[LENGTH_CODES];
-/* First normalized length for each code (0 = MIN_MATCH) */
-
-local int base_dist[D_CODES];
-/* First normalized distance for each code (0 = distance of 1) */
-
-#else
-# include "trees.h"
-#endif /* GEN_TREES_H */
-
-struct static_tree_desc_s {
- const ct_data *static_tree; /* static tree or NULL */
- const intf *extra_bits; /* extra bits for each code or NULL */
- int extra_base; /* base index for extra_bits */
- int elems; /* max number of elements in the tree */
- int max_length; /* max bit length for the codes */
-};
-
-local static_tree_desc static_l_desc =
-{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
-
-local static_tree_desc static_d_desc =
-{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
-
-local static_tree_desc static_bl_desc =
-{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
-
-/* ===========================================================================
- * Local (static) routines in this file.
- */
-
-local void tr_static_init OF((void));
-local void init_block OF((deflate_state *s));
-local void pqdownheap OF((deflate_state *s, ct_data *tree, int k));
-local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
-local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count));
-local void build_tree OF((deflate_state *s, tree_desc *desc));
-local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code));
-local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
-local int build_bl_tree OF((deflate_state *s));
-local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
- int blcodes));
-local void compress_block OF((deflate_state *s, ct_data *ltree,
- ct_data *dtree));
-local void set_data_type OF((deflate_state *s));
-local unsigned bi_reverse OF((unsigned value, int length));
-local void bi_windup OF((deflate_state *s));
-local void bi_flush OF((deflate_state *s));
-local void copy_block OF((deflate_state *s, charf *buf, unsigned len,
- int header));
-
-#ifdef GEN_TREES_H
-local void gen_trees_header OF((void));
-#endif
-
-#ifndef DEBUG
-# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
- /* Send a code of the given tree. c and tree must not have side effects */
-
-#else /* DEBUG */
-# define send_code(s, c, tree) \
- { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
- send_bits(s, tree[c].Code, tree[c].Len); }
-#endif
-
-/* ===========================================================================
- * Output a short LSB first on the stream.
- * IN assertion: there is enough room in pendingBuf.
- */
-#define put_short(s, w) { \
- put_byte(s, (uch)((w) & 0xff)); \
- put_byte(s, (uch)((ush)(w) >> 8)); \
-}
-
-/* ===========================================================================
- * Send a value on a given number of bits.
- * IN assertion: length <= 16 and value fits in length bits.
- */
-#ifdef DEBUG
-local void send_bits OF((deflate_state *s, int value, int length));
-
-local void send_bits(s, value, length)
- deflate_state *s;
- int value; /* value to send */
- int length; /* number of bits */
-{
- Tracevv((stderr," l %2d v %4x ", length, value));
- Assert(length > 0 && length <= 15, "invalid length");
- s->bits_sent += (ulg)length;
-
- /* If not enough room in bi_buf, use (valid) bits from bi_buf and
- * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
- * unused bits in value.
- */
- if (s->bi_valid > (int)Buf_size - length) {
- s->bi_buf |= (value << s->bi_valid);
- put_short(s, s->bi_buf);
- s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
- s->bi_valid += length - Buf_size;
- } else {
- s->bi_buf |= value << s->bi_valid;
- s->bi_valid += length;
- }
-}
-#else /* !DEBUG */
-
-#define send_bits(s, value, length) \
-{ int len = length;\
- if (s->bi_valid > (int)Buf_size - len) {\
- int val = value;\
- s->bi_buf |= (val << s->bi_valid);\
- put_short(s, s->bi_buf);\
- s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
- s->bi_valid += len - Buf_size;\
- } else {\
- s->bi_buf |= (value) << s->bi_valid;\
- s->bi_valid += len;\
- }\
-}
-#endif /* DEBUG */
-
-
-/* the arguments must not have side effects */
-
-/* ===========================================================================
- * Initialize the various 'constant' tables.
- */
-local void tr_static_init()
-{
-#if defined(GEN_TREES_H) || !defined(STDC)
- static int static_init_done = 0;
- int n; /* iterates over tree elements */
- int bits; /* bit counter */
- int length; /* length value */
- int code; /* code value */
- int dist; /* distance index */
- ush bl_count[MAX_BITS+1];
- /* number of codes at each bit length for an optimal tree */
-
- if (static_init_done) return;
-
- /* For some embedded targets, global variables are not initialized: */
- static_l_desc.static_tree = static_ltree;
- static_l_desc.extra_bits = extra_lbits;
- static_d_desc.static_tree = static_dtree;
- static_d_desc.extra_bits = extra_dbits;
- static_bl_desc.extra_bits = extra_blbits;
-
- /* Initialize the mapping length (0..255) -> length code (0..28) */
- length = 0;
- for (code = 0; code < LENGTH_CODES-1; code++) {
- base_length[code] = length;
- for (n = 0; n < (1<<extra_lbits[code]); n++) {
- _length_code[length++] = (uch)code;
- }
- }
- Assert (length == 256, "tr_static_init: length != 256");
- /* Note that the length 255 (match length 258) can be represented
- * in two different ways: code 284 + 5 bits or code 285, so we
- * overwrite length_code[255] to use the best encoding:
- */
- _length_code[length-1] = (uch)code;
-
- /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
- dist = 0;
- for (code = 0 ; code < 16; code++) {
- base_dist[code] = dist;
- for (n = 0; n < (1<<extra_dbits[code]); n++) {
- _dist_code[dist++] = (uch)code;
- }
- }
- Assert (dist == 256, "tr_static_init: dist != 256");
- dist >>= 7; /* from now on, all distances are divided by 128 */
- for ( ; code < D_CODES; code++) {
- base_dist[code] = dist << 7;
- for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
- _dist_code[256 + dist++] = (uch)code;
- }
- }
- Assert (dist == 256, "tr_static_init: 256+dist != 512");
-
- /* Construct the codes of the static literal tree */
- for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
- n = 0;
- while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
- while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
- while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
- while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
- /* Codes 286 and 287 do not exist, but we must include them in the
- * tree construction to get a canonical Huffman tree (longest code
- * all ones)
- */
- gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
-
- /* The static distance tree is trivial: */
- for (n = 0; n < D_CODES; n++) {
- static_dtree[n].Len = 5;
- static_dtree[n].Code = bi_reverse((unsigned)n, 5);
- }
- static_init_done = 1;
-
-# ifdef GEN_TREES_H
- gen_trees_header();
-# endif
-#endif /* defined(GEN_TREES_H) || !defined(STDC) */
-}
-
-/* ===========================================================================
- * Genererate the file trees.h describing the static trees.
- */
-#ifdef GEN_TREES_H
-# ifndef DEBUG
-# include <stdio.h>
-# endif
-
-# define SEPARATOR(i, last, width) \
- ((i) == (last)? "\n};\n\n" : \
- ((i) % (width) == (width)-1 ? ",\n" : ", "))
-
-void gen_trees_header()
-{
- FILE *header = fopen("trees.h", "w");
- int i;
-
- Assert (header != NULL, "Can't open trees.h");
- fprintf(header,
- "/* header created automatically with -DGEN_TREES_H */\n\n");
-
- fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
- for (i = 0; i < L_CODES+2; i++) {
- fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
- static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
- }
-
- fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
- for (i = 0; i < D_CODES; i++) {
- fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
- static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
- }
-
- fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
- for (i = 0; i < DIST_CODE_LEN; i++) {
- fprintf(header, "%2u%s", _dist_code[i],
- SEPARATOR(i, DIST_CODE_LEN-1, 20));
- }
-
- fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
- for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
- fprintf(header, "%2u%s", _length_code[i],
- SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
- }
-
- fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
- for (i = 0; i < LENGTH_CODES; i++) {
- fprintf(header, "%1u%s", base_length[i],
- SEPARATOR(i, LENGTH_CODES-1, 20));
- }
-
- fprintf(header, "local const int base_dist[D_CODES] = {\n");
- for (i = 0; i < D_CODES; i++) {
- fprintf(header, "%5u%s", base_dist[i],
- SEPARATOR(i, D_CODES-1, 10));
- }
-
- fclose(header);
-}
-#endif /* GEN_TREES_H */
-
-/* ===========================================================================
- * Initialize the tree data structures for a new zlib stream.
- */
-void _tr_init(s)
- deflate_state *s;
-{
- tr_static_init();
-
- s->l_desc.dyn_tree = s->dyn_ltree;
- s->l_desc.stat_desc = &static_l_desc;
-
- s->d_desc.dyn_tree = s->dyn_dtree;
- s->d_desc.stat_desc = &static_d_desc;
-
- s->bl_desc.dyn_tree = s->bl_tree;
- s->bl_desc.stat_desc = &static_bl_desc;
-
- s->bi_buf = 0;
- s->bi_valid = 0;
- s->last_eob_len = 8; /* enough lookahead for inflate */
-#ifdef DEBUG
- s->compressed_len = 0L;
- s->bits_sent = 0L;
-#endif
-
- /* Initialize the first block of the first file: */
- init_block(s);
-}
-
-/* ===========================================================================
- * Initialize a new block.
- */
-local void init_block(s)
- deflate_state *s;
-{
- int n; /* iterates over tree elements */
-
- /* Initialize the trees. */
- for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0;
- for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0;
- for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
-
- s->dyn_ltree[END_BLOCK].Freq = 1;
- s->opt_len = s->static_len = 0L;
- s->last_lit = s->matches = 0;
-}
-
-#define SMALLEST 1
-/* Index within the heap array of least frequent node in the Huffman tree */
-
-
-/* ===========================================================================
- * Remove the smallest element from the heap and recreate the heap with
- * one less element. Updates heap and heap_len.
- */
-#define pqremove(s, tree, top) \
-{\
- top = s->heap[SMALLEST]; \
- s->heap[SMALLEST] = s->heap[s->heap_len--]; \
- pqdownheap(s, tree, SMALLEST); \
-}
-
-/* ===========================================================================
- * Compares to subtrees, using the tree depth as tie breaker when
- * the subtrees have equal frequency. This minimizes the worst case length.
- */
-#define smaller(tree, n, m, depth) \
- (tree[n].Freq < tree[m].Freq || \
- (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
-
-/* ===========================================================================
- * Restore the heap property by moving down the tree starting at node k,
- * exchanging a node with the smallest of its two sons if necessary, stopping
- * when the heap property is re-established (each father smaller than its
- * two sons).
- */
-local void pqdownheap(s, tree, k)
- deflate_state *s;
- ct_data *tree; /* the tree to restore */
- int k; /* node to move down */
-{
- int v = s->heap[k];
- int j = k << 1; /* left son of k */
- while (j <= s->heap_len) {
- /* Set j to the smallest of the two sons: */
- if (j < s->heap_len &&
- smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
- j++;
- }
- /* Exit if v is smaller than both sons */
- if (smaller(tree, v, s->heap[j], s->depth)) break;
-
- /* Exchange v with the smallest son */
- s->heap[k] = s->heap[j]; k = j;
-
- /* And continue down the tree, setting j to the left son of k */
- j <<= 1;
- }
- s->heap[k] = v;
-}
-
-/* ===========================================================================
- * Compute the optimal bit lengths for a tree and update the total bit length
- * for the current block.
- * IN assertion: the fields freq and dad are set, heap[heap_max] and
- * above are the tree nodes sorted by increasing frequency.
- * OUT assertions: the field len is set to the optimal bit length, the
- * array bl_count contains the frequencies for each bit length.
- * The length opt_len is updated; static_len is also updated if stree is
- * not null.
- */
-local void gen_bitlen(s, desc)
- deflate_state *s;
- tree_desc *desc; /* the tree descriptor */
-{
- ct_data *tree = desc->dyn_tree;
- int max_code = desc->max_code;
- const ct_data *stree = desc->stat_desc->static_tree;
- const intf *extra = desc->stat_desc->extra_bits;
- int base = desc->stat_desc->extra_base;
- int max_length = desc->stat_desc->max_length;
- int h; /* heap index */
- int n, m; /* iterate over the tree elements */
- int bits; /* bit length */
- int xbits; /* extra bits */
- ush f; /* frequency */
- int overflow = 0; /* number of elements with bit length too large */
-
- for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
-
- /* In a first pass, compute the optimal bit lengths (which may
- * overflow in the case of the bit length tree).
- */
- tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
-
- for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
- n = s->heap[h];
- bits = tree[tree[n].Dad].Len + 1;
- if (bits > max_length) bits = max_length, overflow++;
- tree[n].Len = (ush)bits;
- /* We overwrite tree[n].Dad which is no longer needed */
-
- if (n > max_code) continue; /* not a leaf node */
-
- s->bl_count[bits]++;
- xbits = 0;
- if (n >= base) xbits = extra[n-base];
- f = tree[n].Freq;
- s->opt_len += (ulg)f * (bits + xbits);
- if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
- }
- if (overflow == 0) return;
-
- Trace((stderr,"\nbit length overflow\n"));
- /* This happens for example on obj2 and pic of the Calgary corpus */
-
- /* Find the first bit length which could increase: */
- do {
- bits = max_length-1;
- while (s->bl_count[bits] == 0) bits--;
- s->bl_count[bits]--; /* move one leaf down the tree */
- s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
- s->bl_count[max_length]--;
- /* The brother of the overflow item also moves one step up,
- * but this does not affect bl_count[max_length]
- */
- overflow -= 2;
- } while (overflow > 0);
-
- /* Now recompute all bit lengths, scanning in increasing frequency.
- * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
- * lengths instead of fixing only the wrong ones. This idea is taken
- * from 'ar' written by Haruhiko Okumura.)
- */
- for (bits = max_length; bits != 0; bits--) {
- n = s->bl_count[bits];
- while (n != 0) {
- m = s->heap[--h];
- if (m > max_code) continue;
- if ((unsigned) tree[m].Len != (unsigned) bits) {
- Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
- s->opt_len += ((long)bits - (long)tree[m].Len)
- *(long)tree[m].Freq;
- tree[m].Len = (ush)bits;
- }
- n--;
- }
- }
-}
-
-/* ===========================================================================
- * Generate the codes for a given tree and bit counts (which need not be
- * optimal).
- * IN assertion: the array bl_count contains the bit length statistics for
- * the given tree and the field len is set for all tree elements.
- * OUT assertion: the field code is set for all tree elements of non
- * zero code length.
- */
-local void gen_codes (tree, max_code, bl_count)
- ct_data *tree; /* the tree to decorate */
- int max_code; /* largest code with non zero frequency */
- ushf *bl_count; /* number of codes at each bit length */
-{
- ush next_code[MAX_BITS+1]; /* next code value for each bit length */
- ush code = 0; /* running code value */
- int bits; /* bit index */
- int n; /* code index */
-
- /* The distribution counts are first used to generate the code values
- * without bit reversal.
- */
- for (bits = 1; bits <= MAX_BITS; bits++) {
- next_code[bits] = code = (code + bl_count[bits-1]) << 1;
- }
- /* Check that the bit counts in bl_count are consistent. The last code
- * must be all ones.
- */
- Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
- "inconsistent bit counts");
- Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
-
- for (n = 0; n <= max_code; n++) {
- int len = tree[n].Len;
- if (len == 0) continue;
- /* Now reverse the bits */
- tree[n].Code = bi_reverse(next_code[len]++, len);
-
- Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
- n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
- }
-}
-
-/* ===========================================================================
- * Construct one Huffman tree and assigns the code bit strings and lengths.
- * Update the total bit length for the current block.
- * IN assertion: the field freq is set for all tree elements.
- * OUT assertions: the fields len and code are set to the optimal bit length
- * and corresponding code. The length opt_len is updated; static_len is
- * also updated if stree is not null. The field max_code is set.
- */
-local void build_tree(s, desc)
- deflate_state *s;
- tree_desc *desc; /* the tree descriptor */
-{
- ct_data *tree = desc->dyn_tree;
- const ct_data *stree = desc->stat_desc->static_tree;
- int elems = desc->stat_desc->elems;
- int n, m; /* iterate over heap elements */
- int max_code = -1; /* largest code with non zero frequency */
- int node; /* new node being created */
-
- /* Construct the initial heap, with least frequent element in
- * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
- * heap[0] is not used.
- */
- s->heap_len = 0, s->heap_max = HEAP_SIZE;
-
- for (n = 0; n < elems; n++) {
- if (tree[n].Freq != 0) {
- s->heap[++(s->heap_len)] = max_code = n;
- s->depth[n] = 0;
- } else {
- tree[n].Len = 0;
- }
- }
-
- /* The pkzip format requires that at least one distance code exists,
- * and that at least one bit should be sent even if there is only one
- * possible code. So to avoid special checks later on we force at least
- * two codes of non zero frequency.
- */
- while (s->heap_len < 2) {
- node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
- tree[node].Freq = 1;
- s->depth[node] = 0;
- s->opt_len--; if (stree) s->static_len -= stree[node].Len;
- /* node is 0 or 1 so it does not have extra bits */
- }
- desc->max_code = max_code;
-
- /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
- * establish sub-heaps of increasing lengths:
- */
- for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
-
- /* Construct the Huffman tree by repeatedly combining the least two
- * frequent nodes.
- */
- node = elems; /* next internal node of the tree */
- do {
- pqremove(s, tree, n); /* n = node of least frequency */
- m = s->heap[SMALLEST]; /* m = node of next least frequency */
-
- s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
- s->heap[--(s->heap_max)] = m;
-
- /* Create a new node father of n and m */
- tree[node].Freq = tree[n].Freq + tree[m].Freq;
- s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ?
- s->depth[n] : s->depth[m]) + 1);
- tree[n].Dad = tree[m].Dad = (ush)node;
-#ifdef DUMP_BL_TREE
- if (tree == s->bl_tree) {
- fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
- node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
- }
-#endif
- /* and insert the new node in the heap */
- s->heap[SMALLEST] = node++;
- pqdownheap(s, tree, SMALLEST);
-
- } while (s->heap_len >= 2);
-
- s->heap[--(s->heap_max)] = s->heap[SMALLEST];
-
- /* At this point, the fields freq and dad are set. We can now
- * generate the bit lengths.
- */
- gen_bitlen(s, (tree_desc *)desc);
-
- /* The field len is now set, we can generate the bit codes */
- gen_codes ((ct_data *)tree, max_code, s->bl_count);
-}
-
-/* ===========================================================================
- * Scan a literal or distance tree to determine the frequencies of the codes
- * in the bit length tree.
- */
-local void scan_tree (s, tree, max_code)
- deflate_state *s;
- ct_data *tree; /* the tree to be scanned */
- int max_code; /* and its largest code of non zero frequency */
-{
- int n; /* iterates over all tree elements */
- int prevlen = -1; /* last emitted length */
- int curlen; /* length of current code */
- int nextlen = tree[0].Len; /* length of next code */
- int count = 0; /* repeat count of the current code */
- int max_count = 7; /* max repeat count */
- int min_count = 4; /* min repeat count */
-
- if (nextlen == 0) max_count = 138, min_count = 3;
- tree[max_code+1].Len = (ush)0xffff; /* guard */
-
- for (n = 0; n <= max_code; n++) {
- curlen = nextlen; nextlen = tree[n+1].Len;
- if (++count < max_count && curlen == nextlen) {
- continue;
- } else if (count < min_count) {
- s->bl_tree[curlen].Freq += count;
- } else if (curlen != 0) {
- if (curlen != prevlen) s->bl_tree[curlen].Freq++;
- s->bl_tree[REP_3_6].Freq++;
- } else if (count <= 10) {
- s->bl_tree[REPZ_3_10].Freq++;
- } else {
- s->bl_tree[REPZ_11_138].Freq++;
- }
- count = 0; prevlen = curlen;
- if (nextlen == 0) {
- max_count = 138, min_count = 3;
- } else if (curlen == nextlen) {
- max_count = 6, min_count = 3;
- } else {
- max_count = 7, min_count = 4;
- }
- }
-}
-
-/* ===========================================================================
- * Send a literal or distance tree in compressed form, using the codes in
- * bl_tree.
- */
-local void send_tree (s, tree, max_code)
- deflate_state *s;
- ct_data *tree; /* the tree to be scanned */
- int max_code; /* and its largest code of non zero frequency */
-{
- int n; /* iterates over all tree elements */
- int prevlen = -1; /* last emitted length */
- int curlen; /* length of current code */
- int nextlen = tree[0].Len; /* length of next code */
- int count = 0; /* repeat count of the current code */
- int max_count = 7; /* max repeat count */
- int min_count = 4; /* min repeat count */
-
- /* tree[max_code+1].Len = -1; */ /* guard already set */
- if (nextlen == 0) max_count = 138, min_count = 3;
-
- for (n = 0; n <= max_code; n++) {
- curlen = nextlen; nextlen = tree[n+1].Len;
- if (++count < max_count && curlen == nextlen) {
- continue;
- } else if (count < min_count) {
- do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
-
- } else if (curlen != 0) {
- if (curlen != prevlen) {
- send_code(s, curlen, s->bl_tree); count--;
- }
- Assert(count >= 3 && count <= 6, " 3_6?");
- send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
-
- } else if (count <= 10) {
- send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
-
- } else {
- send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
- }
- count = 0; prevlen = curlen;
- if (nextlen == 0) {
- max_count = 138, min_count = 3;
- } else if (curlen == nextlen) {
- max_count = 6, min_count = 3;
- } else {
- max_count = 7, min_count = 4;
- }
- }
-}
-
-/* ===========================================================================
- * Construct the Huffman tree for the bit lengths and return the index in
- * bl_order of the last bit length code to send.
- */
-local int build_bl_tree(s)
- deflate_state *s;
-{
- int max_blindex; /* index of last bit length code of non zero freq */
-
- /* Determine the bit length frequencies for literal and distance trees */
- scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
- scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
-
- /* Build the bit length tree: */
- build_tree(s, (tree_desc *)(&(s->bl_desc)));
- /* opt_len now includes the length of the tree representations, except
- * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
- */
-
- /* Determine the number of bit length codes to send. The pkzip format
- * requires that at least 4 bit length codes be sent. (appnote.txt says
- * 3 but the actual value used is 4.)
- */
- for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
- if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
- }
- /* Update opt_len to include the bit length tree and counts */
- s->opt_len += 3*(max_blindex+1) + 5+5+4;
- Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
- s->opt_len, s->static_len));
-
- return max_blindex;
-}
-
-/* ===========================================================================
- * Send the header for a block using dynamic Huffman trees: the counts, the
- * lengths of the bit length codes, the literal tree and the distance tree.
- * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
- */
-local void send_all_trees(s, lcodes, dcodes, blcodes)
- deflate_state *s;
- int lcodes, dcodes, blcodes; /* number of codes for each tree */
-{
- int rank; /* index in bl_order */
-
- Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
- Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
- "too many codes");
- Tracev((stderr, "\nbl counts: "));
- send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
- send_bits(s, dcodes-1, 5);
- send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */
- for (rank = 0; rank < blcodes; rank++) {
- Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
- send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
- }
- Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
-
- send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
- Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
-
- send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
- Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
-}
-
-/* ===========================================================================
- * Send a stored block
- */
-void _tr_stored_block(s, buf, stored_len, eof)
- deflate_state *s;
- charf *buf; /* input block */
- ulg stored_len; /* length of input block */
- int eof; /* true if this is the last block for a file */
-{
- send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
-#ifdef DEBUG
- s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
- s->compressed_len += (stored_len + 4) << 3;
-#endif
- copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
-}
-
-/* ===========================================================================
- * Send one empty static block to give enough lookahead for inflate.
- * This takes 10 bits, of which 7 may remain in the bit buffer.
- * The current inflate code requires 9 bits of lookahead. If the
- * last two codes for the previous block (real code plus EOB) were coded
- * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
- * the last real code. In this case we send two empty static blocks instead
- * of one. (There are no problems if the previous block is stored or fixed.)
- * To simplify the code, we assume the worst case of last real code encoded
- * on one bit only.
- */
-void _tr_align(s)
- deflate_state *s;
-{
- send_bits(s, STATIC_TREES<<1, 3);
- send_code(s, END_BLOCK, static_ltree);
-#ifdef DEBUG
- s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
-#endif
- bi_flush(s);
- /* Of the 10 bits for the empty block, we have already sent
- * (10 - bi_valid) bits. The lookahead for the last real code (before
- * the EOB of the previous block) was thus at least one plus the length
- * of the EOB plus what we have just sent of the empty static block.
- */
- if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
- send_bits(s, STATIC_TREES<<1, 3);
- send_code(s, END_BLOCK, static_ltree);
-#ifdef DEBUG
- s->compressed_len += 10L;
-#endif
- bi_flush(s);
- }
- s->last_eob_len = 7;
-}
-
-/* ===========================================================================
- * Determine the best encoding for the current block: dynamic trees, static
- * trees or store, and output the encoded block to the zip file.
- */
-void _tr_flush_block(s, buf, stored_len, eof)
- deflate_state *s;
- charf *buf; /* input block, or NULL if too old */
- ulg stored_len; /* length of input block */
- int eof; /* true if this is the last block for a file */
-{
- ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
- int max_blindex = 0; /* index of last bit length code of non zero freq */
-
- /* Build the Huffman trees unless a stored block is forced */
- if (s->level > 0) {
-
- /* Check if the file is binary or text */
- if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN)
- set_data_type(s);
-
- /* Construct the literal and distance trees */
- build_tree(s, (tree_desc *)(&(s->l_desc)));
- Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
- s->static_len));
-
- build_tree(s, (tree_desc *)(&(s->d_desc)));
- Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
- s->static_len));
- /* At this point, opt_len and static_len are the total bit lengths of
- * the compressed block data, excluding the tree representations.
- */
-
- /* Build the bit length tree for the above two trees, and get the index
- * in bl_order of the last bit length code to send.
- */
- max_blindex = build_bl_tree(s);
-
- /* Determine the best encoding. Compute the block lengths in bytes. */
- opt_lenb = (s->opt_len+3+7)>>3;
- static_lenb = (s->static_len+3+7)>>3;
-
- Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
- opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
- s->last_lit));
-
- if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
-
- } else {
- Assert(buf != (char*)0, "lost buf");
- opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
- }
-
-#ifdef FORCE_STORED
- if (buf != (char*)0) { /* force stored block */
-#else
- if (stored_len+4 <= opt_lenb && buf != (char*)0) {
- /* 4: two words for the lengths */
-#endif
- /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
- * Otherwise we can't have processed more than WSIZE input bytes since
- * the last block flush, because compression would have been
- * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
- * transform a block into a stored block.
- */
- _tr_stored_block(s, buf, stored_len, eof);
-
-#ifdef FORCE_STATIC
- } else if (static_lenb >= 0) { /* force static trees */
-#else
- } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
-#endif
- send_bits(s, (STATIC_TREES<<1)+eof, 3);
- compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
-#ifdef DEBUG
- s->compressed_len += 3 + s->static_len;
-#endif
- } else {
- send_bits(s, (DYN_TREES<<1)+eof, 3);
- send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
- max_blindex+1);
- compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
-#ifdef DEBUG
- s->compressed_len += 3 + s->opt_len;
-#endif
- }
- Assert (s->compressed_len == s->bits_sent, "bad compressed size");
- /* The above check is made mod 2^32, for files larger than 512 MB
- * and uLong implemented on 32 bits.
- */
- init_block(s);
-
- if (eof) {
- bi_windup(s);
-#ifdef DEBUG
- s->compressed_len += 7; /* align on byte boundary */
-#endif
- }
- Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
- s->compressed_len-7*eof));
-}
-
-/* ===========================================================================
- * Save the match info and tally the frequency counts. Return true if
- * the current block must be flushed.
- */
-int _tr_tally (s, dist, lc)
- deflate_state *s;
- unsigned dist; /* distance of matched string */
- unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
-{
- s->d_buf[s->last_lit] = (ush)dist;
- s->l_buf[s->last_lit++] = (uch)lc;
- if (dist == 0) {
- /* lc is the unmatched char */
- s->dyn_ltree[lc].Freq++;
- } else {
- s->matches++;
- /* Here, lc is the match length - MIN_MATCH */
- dist--; /* dist = match distance - 1 */
- Assert((ush)dist < (ush)MAX_DIST(s) &&
- (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
- (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
-
- s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
- s->dyn_dtree[d_code(dist)].Freq++;
- }
-
-#ifdef TRUNCATE_BLOCK
- /* Try to guess if it is profitable to stop the current block here */
- if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
- /* Compute an upper bound for the compressed length */
- ulg out_length = (ulg)s->last_lit*8L;
- ulg in_length = (ulg)((long)s->strstart - s->block_start);
- int dcode;
- for (dcode = 0; dcode < D_CODES; dcode++) {
- out_length += (ulg)s->dyn_dtree[dcode].Freq *
- (5L+extra_dbits[dcode]);
- }
- out_length >>= 3;
- Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
- s->last_lit, in_length, out_length,
- 100L - out_length*100L/in_length));
- if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
- }
-#endif
- return (s->last_lit == s->lit_bufsize-1);
- /* We avoid equality with lit_bufsize because of wraparound at 64K
- * on 16 bit machines and because stored blocks are restricted to
- * 64K-1 bytes.
- */
-}
-
-/* ===========================================================================
- * Send the block data compressed using the given Huffman trees
- */
-local void compress_block(s, ltree, dtree)
- deflate_state *s;
- ct_data *ltree; /* literal tree */
- ct_data *dtree; /* distance tree */
-{
- unsigned dist; /* distance of matched string */
- int lc; /* match length or unmatched char (if dist == 0) */
- unsigned lx = 0; /* running index in l_buf */
- unsigned code; /* the code to send */
- int extra; /* number of extra bits to send */
-
- if (s->last_lit != 0) do {
- dist = s->d_buf[lx];
- lc = s->l_buf[lx++];
- if (dist == 0) {
- send_code(s, lc, ltree); /* send a literal byte */
- Tracecv(isgraph(lc), (stderr," '%c' ", lc));
- } else {
- /* Here, lc is the match length - MIN_MATCH */
- code = _length_code[lc];
- send_code(s, code+LITERALS+1, ltree); /* send the length code */
- extra = extra_lbits[code];
- if (extra != 0) {
- lc -= base_length[code];
- send_bits(s, lc, extra); /* send the extra length bits */
- }
- dist--; /* dist is now the match distance - 1 */
- code = d_code(dist);
- Assert (code < D_CODES, "bad d_code");
-
- send_code(s, code, dtree); /* send the distance code */
- extra = extra_dbits[code];
- if (extra != 0) {
- dist -= base_dist[code];
- send_bits(s, dist, extra); /* send the extra distance bits */
- }
- } /* literal or match pair ? */
-
- /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
- Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
- "pendingBuf overflow");
-
- } while (lx < s->last_lit);
-
- send_code(s, END_BLOCK, ltree);
- s->last_eob_len = ltree[END_BLOCK].Len;
-}
-
-/* ===========================================================================
- * Set the data type to BINARY or TEXT, using a crude approximation:
- * set it to Z_TEXT if all symbols are either printable characters (33 to 255)
- * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise.
- * IN assertion: the fields Freq of dyn_ltree are set.
- */
-local void set_data_type(s)
- deflate_state *s;
-{
- int n;
-
- for (n = 0; n < 9; n++)
- if (s->dyn_ltree[n].Freq != 0)
- break;
- if (n == 9)
- for (n = 14; n < 32; n++)
- if (s->dyn_ltree[n].Freq != 0)
- break;
- s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY;
-}
-
-/* ===========================================================================
- * Reverse the first len bits of a code, using straightforward code (a faster
- * method would use a table)
- * IN assertion: 1 <= len <= 15
- */
-local unsigned bi_reverse(code, len)
- unsigned code; /* the value to invert */
- int len; /* its bit length */
-{
- register unsigned res = 0;
- do {
- res |= code & 1;
- code >>= 1, res <<= 1;
- } while (--len > 0);
- return res >> 1;
-}
-
-/* ===========================================================================
- * Flush the bit buffer, keeping at most 7 bits in it.
- */
-local void bi_flush(s)
- deflate_state *s;
-{
- if (s->bi_valid == 16) {
- put_short(s, s->bi_buf);
- s->bi_buf = 0;
- s->bi_valid = 0;
- } else if (s->bi_valid >= 8) {
- put_byte(s, (Byte)s->bi_buf);
- s->bi_buf >>= 8;
- s->bi_valid -= 8;
- }
-}
-
-/* ===========================================================================
- * Flush the bit buffer and align the output on a byte boundary
- */
-local void bi_windup(s)
- deflate_state *s;
-{
- if (s->bi_valid > 8) {
- put_short(s, s->bi_buf);
- } else if (s->bi_valid > 0) {
- put_byte(s, (Byte)s->bi_buf);
- }
- s->bi_buf = 0;
- s->bi_valid = 0;
-#ifdef DEBUG
- s->bits_sent = (s->bits_sent+7) & ~7;
-#endif
-}
-
-/* ===========================================================================
- * Copy a stored block, storing first the length and its
- * one's complement if requested.
- */
-local void copy_block(s, buf, len, header)
- deflate_state *s;
- charf *buf; /* the input data */
- unsigned len; /* its length */
- int header; /* true if block header must be written */
-{
- bi_windup(s); /* align on byte boundary */
- s->last_eob_len = 8; /* enough lookahead for inflate */
-
- if (header) {
- put_short(s, (ush)len);
- put_short(s, (ush)~len);
-#ifdef DEBUG
- s->bits_sent += 2*16;
-#endif
- }
-#ifdef DEBUG
- s->bits_sent += (ulg)len<<3;
-#endif
- while (len--) {
- put_byte(s, *buf++);
- }
-}
diff --git a/WebCore/platform/image-decoders/zlib/trees.h b/WebCore/platform/image-decoders/zlib/trees.h
deleted file mode 100644
index 72facf9..0000000
--- a/WebCore/platform/image-decoders/zlib/trees.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/* header created automatically with -DGEN_TREES_H */
-
-local const ct_data static_ltree[L_CODES+2] = {
-{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}},
-{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}},
-{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}},
-{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}},
-{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}},
-{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}},
-{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}},
-{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}},
-{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}},
-{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}},
-{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}},
-{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}},
-{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}},
-{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}},
-{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}},
-{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}},
-{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}},
-{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}},
-{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}},
-{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}},
-{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}},
-{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}},
-{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}},
-{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}},
-{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}},
-{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}},
-{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}},
-{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}},
-{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}},
-{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}},
-{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}},
-{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}},
-{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}},
-{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}},
-{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}},
-{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}},
-{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}},
-{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}},
-{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}},
-{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}},
-{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}},
-{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}},
-{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}},
-{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}},
-{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}},
-{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}},
-{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}},
-{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}},
-{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}},
-{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}},
-{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}},
-{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}},
-{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}},
-{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}},
-{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}},
-{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}},
-{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}},
-{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}}
-};
-
-local const ct_data static_dtree[D_CODES] = {
-{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
-{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
-{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
-{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
-{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
-{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
-};
-
-const uch _dist_code[DIST_CODE_LEN] = {
- 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
- 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
-10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
-13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
-15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
-18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
-23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
-26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
-26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
-27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
-27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
-28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
-28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
-28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
-29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
-29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
-29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
-};
-
-const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
-13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
-17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
-19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
-21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
-22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
-23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
-25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
-26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
-26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
-27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
-};
-
-local const int base_length[LENGTH_CODES] = {
-0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
-64, 80, 96, 112, 128, 160, 192, 224, 0
-};
-
-local const int base_dist[D_CODES] = {
- 0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
- 32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
- 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
-};
-
diff --git a/WebCore/platform/image-decoders/zlib/uncompr.c b/WebCore/platform/image-decoders/zlib/uncompr.c
deleted file mode 100644
index c3d7716..0000000
--- a/WebCore/platform/image-decoders/zlib/uncompr.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/* uncompr.c -- decompress a memory buffer
- * Copyright (C) 1995-2003 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id: uncompr.c,v 3.6 2005/08/04 19:14:14 tor%cs.brown.edu Exp $ */
-
-#define ZLIB_INTERNAL
-#include "zlib.h"
-
-/* ===========================================================================
- Decompresses the source buffer into the destination buffer. sourceLen is
- the byte length of the source buffer. Upon entry, destLen is the total
- size of the destination buffer, which must be large enough to hold the
- entire uncompressed data. (The size of the uncompressed data must have
- been saved previously by the compressor and transmitted to the decompressor
- by some mechanism outside the scope of this compression library.)
- Upon exit, destLen is the actual size of the compressed buffer.
- This function can be used to decompress a whole file at once if the
- input file is mmap'ed.
-
- uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_BUF_ERROR if there was not enough room in the output
- buffer, or Z_DATA_ERROR if the input data was corrupted.
-*/
-int ZEXPORT uncompress (dest, destLen, source, sourceLen)
- Bytef *dest;
- uLongf *destLen;
- const Bytef *source;
- uLong sourceLen;
-{
- z_stream stream;
- int err;
-
- stream.next_in = (Bytef*)source;
- stream.avail_in = (uInt)sourceLen;
- /* Check for source > 64K on 16-bit machine: */
- if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
-
- stream.next_out = dest;
- stream.avail_out = (uInt)*destLen;
- if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
-
- stream.zalloc = (alloc_func)0;
- stream.zfree = (free_func)0;
-
- err = inflateInit(&stream);
- if (err != Z_OK) return err;
-
- err = inflate(&stream, Z_FINISH);
- if (err != Z_STREAM_END) {
- inflateEnd(&stream);
- if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
- return Z_DATA_ERROR;
- return err;
- }
- *destLen = stream.total_out;
-
- err = inflateEnd(&stream);
- return err;
-}
diff --git a/WebCore/platform/image-decoders/zlib/zconf.h b/WebCore/platform/image-decoders/zlib/zconf.h
deleted file mode 100644
index b0e17bb..0000000
--- a/WebCore/platform/image-decoders/zlib/zconf.h
+++ /dev/null
@@ -1,335 +0,0 @@
-/* zconf.h -- configuration of the zlib compression library
- * Copyright (C) 1995-2005 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id: zconf.h,v 3.9 2005/08/04 19:14:14 tor%cs.brown.edu Exp $ */
-
-#ifndef ZCONF_H
-#define ZCONF_H
-
-/* This include does prefixing as below, but with an updated set of names */
-#include "mozzconf.h"
-
-/*
- * If you *really* need a unique prefix for all types and library functions,
- * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
- */
-#ifdef Z_PREFIX
-# define deflateInit_ z_deflateInit_
-# define deflate z_deflate
-# define deflateEnd z_deflateEnd
-# define inflateInit_ z_inflateInit_
-# define inflate z_inflate
-# define inflateEnd z_inflateEnd
-# define deflateInit2_ z_deflateInit2_
-# define deflateSetDictionary z_deflateSetDictionary
-# define deflateCopy z_deflateCopy
-# define deflateReset z_deflateReset
-# define deflateParams z_deflateParams
-# define deflateBound z_deflateBound
-# define deflatePrime z_deflatePrime
-# define inflateInit2_ z_inflateInit2_
-# define inflateSetDictionary z_inflateSetDictionary
-# define inflateSync z_inflateSync
-# define inflateSyncPoint z_inflateSyncPoint
-# define inflateCopy z_inflateCopy
-# define inflateReset z_inflateReset
-# define inflateBack z_inflateBack
-# define inflateBackEnd z_inflateBackEnd
-# define compress z_compress
-# define compress2 z_compress2
-# define compressBound z_compressBound
-# define uncompress z_uncompress
-# define adler32 z_adler32
-# define crc32 z_crc32
-# define get_crc_table z_get_crc_table
-# define zError z_zError
-
-# define alloc_func z_alloc_func
-# define free_func z_free_func
-# define in_func z_in_func
-# define out_func z_out_func
-# define Byte z_Byte
-# define uInt z_uInt
-# define uLong z_uLong
-# define Bytef z_Bytef
-# define charf z_charf
-# define intf z_intf
-# define uIntf z_uIntf
-# define uLongf z_uLongf
-# define voidpf z_voidpf
-# define voidp z_voidp
-#endif
-
-#if defined(__MSDOS__) && !defined(MSDOS)
-# define MSDOS
-#endif
-#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
-# define OS2
-#endif
-#if defined(_WINDOWS) && !defined(WINDOWS)
-# define WINDOWS
-#endif
-#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
-# ifndef WIN32
-# define WIN32
-# endif
-#endif
-#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
-# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
-# ifndef SYS16BIT
-# define SYS16BIT
-# endif
-# endif
-#endif
-
-/*
- * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
- * than 64k bytes at a time (needed on systems with 16-bit int).
- */
-#ifdef SYS16BIT
-# define MAXSEG_64K
-#endif
-#ifdef MSDOS
-# define UNALIGNED_OK
-#endif
-
-#ifdef __STDC_VERSION__
-# ifndef STDC
-# define STDC
-# endif
-# if __STDC_VERSION__ >= 199901L
-# ifndef STDC99
-# define STDC99
-# endif
-# endif
-#endif
-#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
-# define STDC
-#endif
-#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
-# define STDC
-#endif
-#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
-# define STDC
-#endif
-#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
-# define STDC
-#endif
-
-#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
-# define STDC
-#endif
-
-#ifndef STDC
-# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
-# define const /* note: need a more gentle solution here */
-# endif
-#endif
-
-/* Some Mac compilers merge all .h files incorrectly: */
-#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
-# define NO_DUMMY_DECL
-#endif
-
-/* Maximum value for memLevel in deflateInit2 */
-#ifndef MAX_MEM_LEVEL
-# ifdef MAXSEG_64K
-# define MAX_MEM_LEVEL 8
-# else
-# define MAX_MEM_LEVEL 9
-# endif
-#endif
-
-/* Maximum value for windowBits in deflateInit2 and inflateInit2.
- * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
- * created by gzip. (Files created by minigzip can still be extracted by
- * gzip.)
- */
-#ifndef MAX_WBITS
-# define MAX_WBITS 15 /* 32K LZ77 window */
-#endif
-
-/* The memory requirements for deflate are (in bytes):
- (1 << (windowBits+2)) + (1 << (memLevel+9))
- that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
- plus a few kilobytes for small objects. For example, if you want to reduce
- the default memory requirements from 256K to 128K, compile with
- make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
- Of course this will generally degrade compression (there's no free lunch).
-
- The memory requirements for inflate are (in bytes) 1 << windowBits
- that is, 32K for windowBits=15 (default value) plus a few kilobytes
- for small objects.
-*/
-
- /* Type declarations */
-
-#ifndef OF /* function prototypes */
-# ifdef STDC
-# define OF(args) args
-# else
-# define OF(args) ()
-# endif
-#endif
-
-/* The following definitions for FAR are needed only for MSDOS mixed
- * model programming (small or medium model with some far allocations).
- * This was tested only with MSC; for other MSDOS compilers you may have
- * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
- * just define FAR to be empty.
- */
-#ifdef SYS16BIT
-# if defined(M_I86SM) || defined(M_I86MM)
- /* MSC small or medium model */
-# define SMALL_MEDIUM
-# ifdef _MSC_VER
-# define FAR _far
-# else
-# define FAR far
-# endif
-# endif
-# if (defined(__SMALL__) || defined(__MEDIUM__))
- /* Turbo C small or medium model */
-# define SMALL_MEDIUM
-# ifdef __BORLANDC__
-# define FAR _far
-# else
-# define FAR far
-# endif
-# endif
-#endif
-
-#if defined(WINDOWS) || defined(WIN32)
- /* If building or using zlib as a DLL, define ZLIB_DLL.
- * This is not mandatory, but it offers a little performance increase.
- */
-# ifdef ZLIB_DLL
-# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
-# ifdef ZLIB_INTERNAL
-# define ZEXTERN extern __declspec(dllexport)
-# else
-# define ZEXTERN extern __declspec(dllimport)
-# endif
-# endif
-# endif /* ZLIB_DLL */
- /* If building or using zlib with the WINAPI/WINAPIV calling convention,
- * define ZLIB_WINAPI.
- * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
- */
-# ifdef ZLIB_WINAPI
-# ifdef FAR
-# undef FAR
-# endif
-# include <windows.h>
- /* No need for _export, use ZLIB.DEF instead. */
- /* For complete Windows compatibility, use WINAPI, not __stdcall. */
-# define ZEXPORT WINAPI
-# ifdef WIN32
-# define ZEXPORTVA WINAPIV
-# else
-# define ZEXPORTVA FAR CDECL
-# endif
-# endif
-#endif
-
-#if defined (__BEOS__)
-# ifdef ZLIB_DLL
-# ifdef ZLIB_INTERNAL
-# define ZEXPORT __declspec(dllexport)
-# define ZEXPORTVA __declspec(dllexport)
-# else
-# define ZEXPORT __declspec(dllimport)
-# define ZEXPORTVA __declspec(dllimport)
-# endif
-# endif
-#endif
-
-#ifndef ZEXTERN
-# define ZEXTERN extern
-#endif
-#ifndef ZEXPORT
-# define ZEXPORT
-#endif
-#ifndef ZEXPORTVA
-# define ZEXPORTVA
-#endif
-
-#ifndef FAR
-# define FAR
-#endif
-
-#if !defined(__MACTYPES__)
-typedef unsigned char Byte; /* 8 bits */
-#endif
-typedef unsigned int uInt; /* 16 bits or more */
-typedef unsigned long uLong; /* 32 bits or more */
-
-#ifdef SMALL_MEDIUM
- /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
-# define Bytef Byte FAR
-#else
- typedef Byte FAR Bytef;
-#endif
-typedef char FAR charf;
-typedef int FAR intf;
-typedef uInt FAR uIntf;
-typedef uLong FAR uLongf;
-
-#ifdef STDC
- typedef void const *voidpc;
- typedef void FAR *voidpf;
- typedef void *voidp;
-#else
- typedef Byte const *voidpc;
- typedef Byte FAR *voidpf;
- typedef Byte *voidp;
-#endif
-
-#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
-# include <sys/types.h> /* for off_t */
-# include <unistd.h> /* for SEEK_* and off_t */
-# ifdef VMS
-# include <unixio.h> /* for off_t */
-# endif
-# define z_off_t off_t
-#endif
-#ifndef SEEK_SET
-# define SEEK_SET 0 /* Seek from beginning of file. */
-# define SEEK_CUR 1 /* Seek from current position. */
-# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
-#endif
-#ifndef z_off_t
-# define z_off_t long
-#endif
-
-#if defined(__OS400__)
-# define NO_vsnprintf
-#endif
-
-#if defined(__MVS__)
-# define NO_vsnprintf
-# ifdef FAR
-# undef FAR
-# endif
-#endif
-
-/* MVS linker does not support external names larger than 8 bytes */
-#if defined(__MVS__)
-# pragma map(deflateInit_,"DEIN")
-# pragma map(deflateInit2_,"DEIN2")
-# pragma map(deflateEnd,"DEEND")
-# pragma map(deflateBound,"DEBND")
-# pragma map(inflateInit_,"ININ")
-# pragma map(inflateInit2_,"ININ2")
-# pragma map(inflateEnd,"INEND")
-# pragma map(inflateSync,"INSY")
-# pragma map(inflateSetDictionary,"INSEDI")
-# pragma map(compressBound,"CMBND")
-# pragma map(inflate_table,"INTABL")
-# pragma map(inflate_fast,"INFA")
-# pragma map(inflate_copyright,"INCOPY")
-#endif
-
-#endif /* ZCONF_H */
diff --git a/WebCore/platform/image-decoders/zlib/zlib.h b/WebCore/platform/image-decoders/zlib/zlib.h
deleted file mode 100644
index 0228179..0000000
--- a/WebCore/platform/image-decoders/zlib/zlib.h
+++ /dev/null
@@ -1,1357 +0,0 @@
-/* zlib.h -- interface of the 'zlib' general purpose compression library
- version 1.2.3, July 18th, 2005
-
- Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Jean-loup Gailly Mark Adler
- jloup@gzip.org madler@alumni.caltech.edu
-
-
- The data format used by the zlib library is described by RFCs (Request for
- Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
- (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
-*/
-
-#ifndef ZLIB_H
-#define ZLIB_H
-
-#include "zconf.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define ZLIB_VERSION "1.2.3"
-#define ZLIB_VERNUM 0x1230
-
-/*
- The 'zlib' compression library provides in-memory compression and
- decompression functions, including integrity checks of the uncompressed
- data. This version of the library supports only one compression method
- (deflation) but other algorithms will be added later and will have the same
- stream interface.
-
- Compression can be done in a single step if the buffers are large
- enough (for example if an input file is mmap'ed), or can be done by
- repeated calls of the compression function. In the latter case, the
- application must provide more input and/or consume the output
- (providing more output space) before each call.
-
- The compressed data format used by default by the in-memory functions is
- the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
- around a deflate stream, which is itself documented in RFC 1951.
-
- The library also supports reading and writing files in gzip (.gz) format
- with an interface similar to that of stdio using the functions that start
- with "gz". The gzip format is different from the zlib format. gzip is a
- gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
-
- This library can optionally read and write gzip streams in memory as well.
-
- The zlib format was designed to be compact and fast for use in memory
- and on communications channels. The gzip format was designed for single-
- file compression on file systems, has a larger header than zlib to maintain
- directory information, and uses a different, slower check method than zlib.
-
- The library does not install any signal handler. The decoder checks
- the consistency of the compressed data, so the library should never
- crash even in case of corrupted input.
-*/
-
-typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
-typedef void (*free_func) OF((voidpf opaque, voidpf address));
-
-struct internal_state;
-
-typedef struct z_stream_s {
- Bytef *next_in; /* next input byte */
- uInt avail_in; /* number of bytes available at next_in */
- uLong total_in; /* total nb of input bytes read so far */
-
- Bytef *next_out; /* next output byte should be put there */
- uInt avail_out; /* remaining free space at next_out */
- uLong total_out; /* total nb of bytes output so far */
-
- char *msg; /* last error message, NULL if no error */
- struct internal_state FAR *state; /* not visible by applications */
-
- alloc_func zalloc; /* used to allocate the internal state */
- free_func zfree; /* used to free the internal state */
- voidpf opaque; /* private data object passed to zalloc and zfree */
-
- int data_type; /* best guess about the data type: binary or text */
- uLong adler; /* adler32 value of the uncompressed data */
- uLong reserved; /* reserved for future use */
-} z_stream;
-
-typedef z_stream FAR *z_streamp;
-
-/*
- gzip header information passed to and from zlib routines. See RFC 1952
- for more details on the meanings of these fields.
-*/
-typedef struct gz_header_s {
- int text; /* true if compressed data believed to be text */
- uLong time; /* modification time */
- int xflags; /* extra flags (not used when writing a gzip file) */
- int os; /* operating system */
- Bytef *extra; /* pointer to extra field or Z_NULL if none */
- uInt extra_len; /* extra field length (valid if extra != Z_NULL) */
- uInt extra_max; /* space at extra (only when reading header) */
- Bytef *name; /* pointer to zero-terminated file name or Z_NULL */
- uInt name_max; /* space at name (only when reading header) */
- Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */
- uInt comm_max; /* space at comment (only when reading header) */
- int hcrc; /* true if there was or will be a header crc */
- int done; /* true when done reading gzip header (not used
- when writing a gzip file) */
-} gz_header;
-
-typedef gz_header FAR *gz_headerp;
-
-/*
- The application must update next_in and avail_in when avail_in has
- dropped to zero. It must update next_out and avail_out when avail_out
- has dropped to zero. The application must initialize zalloc, zfree and
- opaque before calling the init function. All other fields are set by the
- compression library and must not be updated by the application.
-
- The opaque value provided by the application will be passed as the first
- parameter for calls of zalloc and zfree. This can be useful for custom
- memory management. The compression library attaches no meaning to the
- opaque value.
-
- zalloc must return Z_NULL if there is not enough memory for the object.
- If zlib is used in a multi-threaded application, zalloc and zfree must be
- thread safe.
-
- On 16-bit systems, the functions zalloc and zfree must be able to allocate
- exactly 65536 bytes, but will not be required to allocate more than this
- if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
- pointers returned by zalloc for objects of exactly 65536 bytes *must*
- have their offset normalized to zero. The default allocation function
- provided by this library ensures this (see zutil.c). To reduce memory
- requirements and avoid any allocation of 64K objects, at the expense of
- compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
-
- The fields total_in and total_out can be used for statistics or
- progress reports. After compression, total_in holds the total size of
- the uncompressed data and may be saved for use in the decompressor
- (particularly if the decompressor wants to decompress everything in
- a single step).
-*/
-
- /* constants */
-
-#define Z_NO_FLUSH 0
-#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
-#define Z_SYNC_FLUSH 2
-#define Z_FULL_FLUSH 3
-#define Z_FINISH 4
-#define Z_BLOCK 5
-/* Allowed flush values; see deflate() and inflate() below for details */
-
-#define Z_OK 0
-#define Z_STREAM_END 1
-#define Z_NEED_DICT 2
-#define Z_ERRNO (-1)
-#define Z_STREAM_ERROR (-2)
-#define Z_DATA_ERROR (-3)
-#define Z_MEM_ERROR (-4)
-#define Z_BUF_ERROR (-5)
-#define Z_VERSION_ERROR (-6)
-/* Return codes for the compression/decompression functions. Negative
- * values are errors, positive values are used for special but normal events.
- */
-
-#define Z_NO_COMPRESSION 0
-#define Z_BEST_SPEED 1
-#define Z_BEST_COMPRESSION 9
-#define Z_DEFAULT_COMPRESSION (-1)
-/* compression levels */
-
-#define Z_FILTERED 1
-#define Z_HUFFMAN_ONLY 2
-#define Z_RLE 3
-#define Z_FIXED 4
-#define Z_DEFAULT_STRATEGY 0
-/* compression strategy; see deflateInit2() below for details */
-
-#define Z_BINARY 0
-#define Z_TEXT 1
-#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */
-#define Z_UNKNOWN 2
-/* Possible values of the data_type field (though see inflate()) */
-
-#define Z_DEFLATED 8
-/* The deflate compression method (the only one supported in this version) */
-
-#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
-
-#define zlib_version zlibVersion()
-/* for compatibility with versions < 1.0.2 */
-
- /* basic functions */
-
-ZEXTERN const char * ZEXPORT zlibVersion OF((void));
-/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
- If the first character differs, the library code actually used is
- not compatible with the zlib.h header file used by the application.
- This check is automatically made by deflateInit and inflateInit.
- */
-
-/*
-ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
-
- Initializes the internal stream state for compression. The fields
- zalloc, zfree and opaque must be initialized before by the caller.
- If zalloc and zfree are set to Z_NULL, deflateInit updates them to
- use default allocation functions.
-
- The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
- 1 gives best speed, 9 gives best compression, 0 gives no compression at
- all (the input data is simply copied a block at a time).
- Z_DEFAULT_COMPRESSION requests a default compromise between speed and
- compression (currently equivalent to level 6).
-
- deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_STREAM_ERROR if level is not a valid compression level,
- Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
- with the version assumed by the caller (ZLIB_VERSION).
- msg is set to null if there is no error message. deflateInit does not
- perform any compression: this will be done by deflate().
-*/
-
-
-ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
-/*
- deflate compresses as much data as possible, and stops when the input
- buffer becomes empty or the output buffer becomes full. It may introduce some
- output latency (reading input without producing any output) except when
- forced to flush.
-
- The detailed semantics are as follows. deflate performs one or both of the
- following actions:
-
- - Compress more input starting at next_in and update next_in and avail_in
- accordingly. If not all input can be processed (because there is not
- enough room in the output buffer), next_in and avail_in are updated and
- processing will resume at this point for the next call of deflate().
-
- - Provide more output starting at next_out and update next_out and avail_out
- accordingly. This action is forced if the parameter flush is non zero.
- Forcing flush frequently degrades the compression ratio, so this parameter
- should be set only when necessary (in interactive applications).
- Some output may be provided even if flush is not set.
-
- Before the call of deflate(), the application should ensure that at least
- one of the actions is possible, by providing more input and/or consuming
- more output, and updating avail_in or avail_out accordingly; avail_out
- should never be zero before the call. The application can consume the
- compressed output when it wants, for example when the output buffer is full
- (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
- and with zero avail_out, it must be called again after making room in the
- output buffer because there might be more output pending.
-
- Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
- decide how much data to accumualte before producing output, in order to
- maximize compression.
-
- If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
- flushed to the output buffer and the output is aligned on a byte boundary, so
- that the decompressor can get all input data available so far. (In particular
- avail_in is zero after the call if enough output space has been provided
- before the call.) Flushing may degrade compression for some compression
- algorithms and so it should be used only when necessary.
-
- If flush is set to Z_FULL_FLUSH, all output is flushed as with
- Z_SYNC_FLUSH, and the compression state is reset so that decompression can
- restart from this point if previous compressed data has been damaged or if
- random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
- compression.
-
- If deflate returns with avail_out == 0, this function must be called again
- with the same value of the flush parameter and more output space (updated
- avail_out), until the flush is complete (deflate returns with non-zero
- avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
- avail_out is greater than six to avoid repeated flush markers due to
- avail_out == 0 on return.
-
- If the parameter flush is set to Z_FINISH, pending input is processed,
- pending output is flushed and deflate returns with Z_STREAM_END if there
- was enough output space; if deflate returns with Z_OK, this function must be
- called again with Z_FINISH and more output space (updated avail_out) but no
- more input data, until it returns with Z_STREAM_END or an error. After
- deflate has returned Z_STREAM_END, the only possible operations on the
- stream are deflateReset or deflateEnd.
-
- Z_FINISH can be used immediately after deflateInit if all the compression
- is to be done in a single step. In this case, avail_out must be at least
- the value returned by deflateBound (see below). If deflate does not return
- Z_STREAM_END, then it must be called again as described above.
-
- deflate() sets strm->adler to the adler32 checksum of all input read
- so far (that is, total_in bytes).
-
- deflate() may update strm->data_type if it can make a good guess about
- the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered
- binary. This field is only for information purposes and does not affect
- the compression algorithm in any manner.
-
- deflate() returns Z_OK if some progress has been made (more input
- processed or more output produced), Z_STREAM_END if all input has been
- consumed and all output has been produced (only when flush is set to
- Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
- if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
- (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not
- fatal, and deflate() can be called again with more input and more output
- space to continue compressing.
-*/
-
-
-ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
-/*
- All dynamically allocated data structures for this stream are freed.
- This function discards any unprocessed input and does not flush any
- pending output.
-
- deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
- stream state was inconsistent, Z_DATA_ERROR if the stream was freed
- prematurely (some input or output was discarded). In the error case,
- msg may be set but then points to a static string (which must not be
- deallocated).
-*/
-
-
-/*
-ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
-
- Initializes the internal stream state for decompression. The fields
- next_in, avail_in, zalloc, zfree and opaque must be initialized before by
- the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
- value depends on the compression method), inflateInit determines the
- compression method from the zlib header and allocates all data structures
- accordingly; otherwise the allocation will be deferred to the first call of
- inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
- use default allocation functions.
-
- inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
- version assumed by the caller. msg is set to null if there is no error
- message. inflateInit does not perform any decompression apart from reading
- the zlib header if present: this will be done by inflate(). (So next_in and
- avail_in may be modified, but next_out and avail_out are unchanged.)
-*/
-
-
-ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
-/*
- inflate decompresses as much data as possible, and stops when the input
- buffer becomes empty or the output buffer becomes full. It may introduce
- some output latency (reading input without producing any output) except when
- forced to flush.
-
- The detailed semantics are as follows. inflate performs one or both of the
- following actions:
-
- - Decompress more input starting at next_in and update next_in and avail_in
- accordingly. If not all input can be processed (because there is not
- enough room in the output buffer), next_in is updated and processing
- will resume at this point for the next call of inflate().
-
- - Provide more output starting at next_out and update next_out and avail_out
- accordingly. inflate() provides as much output as possible, until there
- is no more input data or no more space in the output buffer (see below
- about the flush parameter).
-
- Before the call of inflate(), the application should ensure that at least
- one of the actions is possible, by providing more input and/or consuming
- more output, and updating the next_* and avail_* values accordingly.
- The application can consume the uncompressed output when it wants, for
- example when the output buffer is full (avail_out == 0), or after each
- call of inflate(). If inflate returns Z_OK and with zero avail_out, it
- must be called again after making room in the output buffer because there
- might be more output pending.
-
- The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH,
- Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much
- output as possible to the output buffer. Z_BLOCK requests that inflate() stop
- if and when it gets to the next deflate block boundary. When decoding the
- zlib or gzip format, this will cause inflate() to return immediately after
- the header and before the first block. When doing a raw inflate, inflate()
- will go ahead and process the first block, and will return when it gets to
- the end of that block, or when it runs out of data.
-
- The Z_BLOCK option assists in appending to or combining deflate streams.
- Also to assist in this, on return inflate() will set strm->data_type to the
- number of unused bits in the last byte taken from strm->next_in, plus 64
- if inflate() is currently decoding the last block in the deflate stream,
- plus 128 if inflate() returned immediately after decoding an end-of-block
- code or decoding the complete header up to just before the first byte of the
- deflate stream. The end-of-block will not be indicated until all of the
- uncompressed data from that block has been written to strm->next_out. The
- number of unused bits may in general be greater than seven, except when
- bit 7 of data_type is set, in which case the number of unused bits will be
- less than eight.
-
- inflate() should normally be called until it returns Z_STREAM_END or an
- error. However if all decompression is to be performed in a single step
- (a single call of inflate), the parameter flush should be set to
- Z_FINISH. In this case all pending input is processed and all pending
- output is flushed; avail_out must be large enough to hold all the
- uncompressed data. (The size of the uncompressed data may have been saved
- by the compressor for this purpose.) The next operation on this stream must
- be inflateEnd to deallocate the decompression state. The use of Z_FINISH
- is never required, but can be used to inform inflate that a faster approach
- may be used for the single inflate() call.
-
- In this implementation, inflate() always flushes as much output as
- possible to the output buffer, and always uses the faster approach on the
- first call. So the only effect of the flush parameter in this implementation
- is on the return value of inflate(), as noted below, or when it returns early
- because Z_BLOCK is used.
-
- If a preset dictionary is needed after this call (see inflateSetDictionary
- below), inflate sets strm->adler to the adler32 checksum of the dictionary
- chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
- strm->adler to the adler32 checksum of all output produced so far (that is,
- total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
- below. At the end of the stream, inflate() checks that its computed adler32
- checksum is equal to that saved by the compressor and returns Z_STREAM_END
- only if the checksum is correct.
-
- inflate() will decompress and check either zlib-wrapped or gzip-wrapped
- deflate data. The header type is detected automatically. Any information
- contained in the gzip header is not retained, so applications that need that
- information should instead use raw inflate, see inflateInit2() below, or
- inflateBack() and perform their own processing of the gzip header and
- trailer.
-
- inflate() returns Z_OK if some progress has been made (more input processed
- or more output produced), Z_STREAM_END if the end of the compressed data has
- been reached and all uncompressed output has been produced, Z_NEED_DICT if a
- preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
- corrupted (input stream not conforming to the zlib format or incorrect check
- value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
- if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory,
- Z_BUF_ERROR if no progress is possible or if there was not enough room in the
- output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
- inflate() can be called again with more input and more output space to
- continue decompressing. If Z_DATA_ERROR is returned, the application may then
- call inflateSync() to look for a good compression block if a partial recovery
- of the data is desired.
-*/
-
-
-ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
-/*
- All dynamically allocated data structures for this stream are freed.
- This function discards any unprocessed input and does not flush any
- pending output.
-
- inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
- was inconsistent. In the error case, msg may be set but then points to a
- static string (which must not be deallocated).
-*/
-
- /* Advanced functions */
-
-/*
- The following functions are needed only in some special applications.
-*/
-
-/*
-ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
- int level,
- int method,
- int windowBits,
- int memLevel,
- int strategy));
-
- This is another version of deflateInit with more compression options. The
- fields next_in, zalloc, zfree and opaque must be initialized before by
- the caller.
-
- The method parameter is the compression method. It must be Z_DEFLATED in
- this version of the library.
-
- The windowBits parameter is the base two logarithm of the window size
- (the size of the history buffer). It should be in the range 8..15 for this
- version of the library. Larger values of this parameter result in better
- compression at the expense of memory usage. The default value is 15 if
- deflateInit is used instead.
-
- windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
- determines the window size. deflate() will then generate raw deflate data
- with no zlib header or trailer, and will not compute an adler32 check value.
-
- windowBits can also be greater than 15 for optional gzip encoding. Add
- 16 to windowBits to write a simple gzip header and trailer around the
- compressed data instead of a zlib wrapper. The gzip header will have no
- file name, no extra data, no comment, no modification time (set to zero),
- no header crc, and the operating system will be set to 255 (unknown). If a
- gzip stream is being written, strm->adler is a crc32 instead of an adler32.
-
- The memLevel parameter specifies how much memory should be allocated
- for the internal compression state. memLevel=1 uses minimum memory but
- is slow and reduces compression ratio; memLevel=9 uses maximum memory
- for optimal speed. The default value is 8. See zconf.h for total memory
- usage as a function of windowBits and memLevel.
-
- The strategy parameter is used to tune the compression algorithm. Use the
- value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
- filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
- string match), or Z_RLE to limit match distances to one (run-length
- encoding). Filtered data consists mostly of small values with a somewhat
- random distribution. In this case, the compression algorithm is tuned to
- compress them better. The effect of Z_FILTERED is to force more Huffman
- coding and less string matching; it is somewhat intermediate between
- Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as
- Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy
- parameter only affects the compression ratio but not the correctness of the
- compressed output even if it is not set appropriately. Z_FIXED prevents the
- use of dynamic Huffman codes, allowing for a simpler decoder for special
- applications.
-
- deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
- method). msg is set to null if there is no error message. deflateInit2 does
- not perform any compression: this will be done by deflate().
-*/
-
-ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
- const Bytef *dictionary,
- uInt dictLength));
-/*
- Initializes the compression dictionary from the given byte sequence
- without producing any compressed output. This function must be called
- immediately after deflateInit, deflateInit2 or deflateReset, before any
- call of deflate. The compressor and decompressor must use exactly the same
- dictionary (see inflateSetDictionary).
-
- The dictionary should consist of strings (byte sequences) that are likely
- to be encountered later in the data to be compressed, with the most commonly
- used strings preferably put towards the end of the dictionary. Using a
- dictionary is most useful when the data to be compressed is short and can be
- predicted with good accuracy; the data can then be compressed better than
- with the default empty dictionary.
-
- Depending on the size of the compression data structures selected by
- deflateInit or deflateInit2, a part of the dictionary may in effect be
- discarded, for example if the dictionary is larger than the window size in
- deflate or deflate2. Thus the strings most likely to be useful should be
- put at the end of the dictionary, not at the front. In addition, the
- current implementation of deflate will use at most the window size minus
- 262 bytes of the provided dictionary.
-
- Upon return of this function, strm->adler is set to the adler32 value
- of the dictionary; the decompressor may later use this value to determine
- which dictionary has been used by the compressor. (The adler32 value
- applies to the whole dictionary even if only a subset of the dictionary is
- actually used by the compressor.) If a raw deflate was requested, then the
- adler32 value is not computed and strm->adler is not set.
-
- deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
- parameter is invalid (such as NULL dictionary) or the stream state is
- inconsistent (for example if deflate has already been called for this stream
- or if the compression method is bsort). deflateSetDictionary does not
- perform any compression: this will be done by deflate().
-*/
-
-ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
- z_streamp source));
-/*
- Sets the destination stream as a complete copy of the source stream.
-
- This function can be useful when several compression strategies will be
- tried, for example when there are several ways of pre-processing the input
- data with a filter. The streams that will be discarded should then be freed
- by calling deflateEnd. Note that deflateCopy duplicates the internal
- compression state which can be quite large, so this strategy is slow and
- can consume lots of memory.
-
- deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
- (such as zalloc being NULL). msg is left unchanged in both source and
- destination.
-*/
-
-ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
-/*
- This function is equivalent to deflateEnd followed by deflateInit,
- but does not free and reallocate all the internal compression state.
- The stream will keep the same compression level and any other attributes
- that may have been set by deflateInit2.
-
- deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent (such as zalloc or state being NULL).
-*/
-
-ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
- int level,
- int strategy));
-/*
- Dynamically update the compression level and compression strategy. The
- interpretation of level and strategy is as in deflateInit2. This can be
- used to switch between compression and straight copy of the input data, or
- to switch to a different kind of input data requiring a different
- strategy. If the compression level is changed, the input available so far
- is compressed with the old level (and may be flushed); the new level will
- take effect only at the next call of deflate().
-
- Before the call of deflateParams, the stream state must be set as for
- a call of deflate(), since the currently available input may have to
- be compressed and flushed. In particular, strm->avail_out must be non-zero.
-
- deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
- stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
- if strm->avail_out was zero.
-*/
-
-ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
- int good_length,
- int max_lazy,
- int nice_length,
- int max_chain));
-/*
- Fine tune deflate's internal compression parameters. This should only be
- used by someone who understands the algorithm used by zlib's deflate for
- searching for the best matching string, and even then only by the most
- fanatic optimizer trying to squeeze out the last compressed bit for their
- specific input data. Read the deflate.c source code for the meaning of the
- max_lazy, good_length, nice_length, and max_chain parameters.
-
- deflateTune() can be called after deflateInit() or deflateInit2(), and
- returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
- */
-
-ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
- uLong sourceLen));
-/*
- deflateBound() returns an upper bound on the compressed size after
- deflation of sourceLen bytes. It must be called after deflateInit()
- or deflateInit2(). This would be used to allocate an output buffer
- for deflation in a single pass, and so would be called before deflate().
-*/
-
-ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
- int bits,
- int value));
-/*
- deflatePrime() inserts bits in the deflate output stream. The intent
- is that this function is used to start off the deflate output with the
- bits leftover from a previous deflate stream when appending to it. As such,
- this function can only be used for raw deflate, and must be used before the
- first deflate() call after a deflateInit2() or deflateReset(). bits must be
- less than or equal to 16, and that many of the least significant bits of
- value will be inserted in the output.
-
- deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent.
-*/
-
-ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
- gz_headerp head));
-/*
- deflateSetHeader() provides gzip header information for when a gzip
- stream is requested by deflateInit2(). deflateSetHeader() may be called
- after deflateInit2() or deflateReset() and before the first call of
- deflate(). The text, time, os, extra field, name, and comment information
- in the provided gz_header structure are written to the gzip header (xflag is
- ignored -- the extra flags are set according to the compression level). The
- caller must assure that, if not Z_NULL, name and comment are terminated with
- a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
- available there. If hcrc is true, a gzip header crc is included. Note that
- the current versions of the command-line version of gzip (up through version
- 1.3.x) do not support header crc's, and will report that it is a "multi-part
- gzip file" and give up.
-
- If deflateSetHeader is not used, the default gzip header has text false,
- the time set to zero, and os set to 255, with no extra, name, or comment
- fields. The gzip header is returned to the default state by deflateReset().
-
- deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent.
-*/
-
-/*
-ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
- int windowBits));
-
- This is another version of inflateInit with an extra parameter. The
- fields next_in, avail_in, zalloc, zfree and opaque must be initialized
- before by the caller.
-
- The windowBits parameter is the base two logarithm of the maximum window
- size (the size of the history buffer). It should be in the range 8..15 for
- this version of the library. The default value is 15 if inflateInit is used
- instead. windowBits must be greater than or equal to the windowBits value
- provided to deflateInit2() while compressing, or it must be equal to 15 if
- deflateInit2() was not used. If a compressed stream with a larger window
- size is given as input, inflate() will return with the error code
- Z_DATA_ERROR instead of trying to allocate a larger window.
-
- windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
- determines the window size. inflate() will then process raw deflate data,
- not looking for a zlib or gzip header, not generating a check value, and not
- looking for any check values for comparison at the end of the stream. This
- is for use with other formats that use the deflate compressed data format
- such as zip. Those formats provide their own check values. If a custom
- format is developed using the raw deflate format for compressed data, it is
- recommended that a check value such as an adler32 or a crc32 be applied to
- the uncompressed data as is done in the zlib, gzip, and zip formats. For
- most applications, the zlib format should be used as is. Note that comments
- above on the use in deflateInit2() applies to the magnitude of windowBits.
-
- windowBits can also be greater than 15 for optional gzip decoding. Add
- 32 to windowBits to enable zlib and gzip decoding with automatic header
- detection, or add 16 to decode only the gzip format (the zlib format will
- return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is
- a crc32 instead of an adler32.
-
- inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg
- is set to null if there is no error message. inflateInit2 does not perform
- any decompression apart from reading the zlib header if present: this will
- be done by inflate(). (So next_in and avail_in may be modified, but next_out
- and avail_out are unchanged.)
-*/
-
-ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
- const Bytef *dictionary,
- uInt dictLength));
-/*
- Initializes the decompression dictionary from the given uncompressed byte
- sequence. This function must be called immediately after a call of inflate,
- if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
- can be determined from the adler32 value returned by that call of inflate.
- The compressor and decompressor must use exactly the same dictionary (see
- deflateSetDictionary). For raw inflate, this function can be called
- immediately after inflateInit2() or inflateReset() and before any call of
- inflate() to set the dictionary. The application must insure that the
- dictionary that was used for compression is provided.
-
- inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
- parameter is invalid (such as NULL dictionary) or the stream state is
- inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
- expected one (incorrect adler32 value). inflateSetDictionary does not
- perform any decompression: this will be done by subsequent calls of
- inflate().
-*/
-
-ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
-/*
- Skips invalid compressed data until a full flush point (see above the
- description of deflate with Z_FULL_FLUSH) can be found, or until all
- available input is skipped. No output is provided.
-
- inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
- if no more input was provided, Z_DATA_ERROR if no flush point has been found,
- or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
- case, the application may save the current current value of total_in which
- indicates where valid compressed data was found. In the error case, the
- application may repeatedly call inflateSync, providing more input each time,
- until success or end of the input data.
-*/
-
-ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
- z_streamp source));
-/*
- Sets the destination stream as a complete copy of the source stream.
-
- This function can be useful when randomly accessing a large stream. The
- first pass through the stream can periodically record the inflate state,
- allowing restarting inflate at those points when randomly accessing the
- stream.
-
- inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
- (such as zalloc being NULL). msg is left unchanged in both source and
- destination.
-*/
-
-ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
-/*
- This function is equivalent to inflateEnd followed by inflateInit,
- but does not free and reallocate all the internal decompression state.
- The stream will keep attributes that may have been set by inflateInit2.
-
- inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent (such as zalloc or state being NULL).
-*/
-
-ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
- int bits,
- int value));
-/*
- This function inserts bits in the inflate input stream. The intent is
- that this function is used to start inflating at a bit position in the
- middle of a byte. The provided bits will be used before any bytes are used
- from next_in. This function should only be used with raw inflate, and
- should be used before the first inflate() call after inflateInit2() or
- inflateReset(). bits must be less than or equal to 16, and that many of the
- least significant bits of value will be inserted in the input.
-
- inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent.
-*/
-
-ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
- gz_headerp head));
-/*
- inflateGetHeader() requests that gzip header information be stored in the
- provided gz_header structure. inflateGetHeader() may be called after
- inflateInit2() or inflateReset(), and before the first call of inflate().
- As inflate() processes the gzip stream, head->done is zero until the header
- is completed, at which time head->done is set to one. If a zlib stream is
- being decoded, then head->done is set to -1 to indicate that there will be
- no gzip header information forthcoming. Note that Z_BLOCK can be used to
- force inflate() to return immediately after header processing is complete
- and before any actual data is decompressed.
-
- The text, time, xflags, and os fields are filled in with the gzip header
- contents. hcrc is set to true if there is a header CRC. (The header CRC
- was valid if done is set to one.) If extra is not Z_NULL, then extra_max
- contains the maximum number of bytes to write to extra. Once done is true,
- extra_len contains the actual extra field length, and extra contains the
- extra field, or that field truncated if extra_max is less than extra_len.
- If name is not Z_NULL, then up to name_max characters are written there,
- terminated with a zero unless the length is greater than name_max. If
- comment is not Z_NULL, then up to comm_max characters are written there,
- terminated with a zero unless the length is greater than comm_max. When
- any of extra, name, or comment are not Z_NULL and the respective field is
- not present in the header, then that field is set to Z_NULL to signal its
- absence. This allows the use of deflateSetHeader() with the returned
- structure to duplicate the header. However if those fields are set to
- allocated memory, then the application will need to save those pointers
- elsewhere so that they can be eventually freed.
-
- If inflateGetHeader is not used, then the header information is simply
- discarded. The header is always checked for validity, including the header
- CRC if present. inflateReset() will reset the process to discard the header
- information. The application would need to call inflateGetHeader() again to
- retrieve the header from the next gzip stream.
-
- inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent.
-*/
-
-/*
-ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
- unsigned char FAR *window));
-
- Initialize the internal stream state for decompression using inflateBack()
- calls. The fields zalloc, zfree and opaque in strm must be initialized
- before the call. If zalloc and zfree are Z_NULL, then the default library-
- derived memory allocation routines are used. windowBits is the base two
- logarithm of the window size, in the range 8..15. window is a caller
- supplied buffer of that size. Except for special applications where it is
- assured that deflate was used with small window sizes, windowBits must be 15
- and a 32K byte window must be supplied to be able to decompress general
- deflate streams.
-
- See inflateBack() for the usage of these routines.
-
- inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
- the paramaters are invalid, Z_MEM_ERROR if the internal state could not
- be allocated, or Z_VERSION_ERROR if the version of the library does not
- match the version of the header file.
-*/
-
-typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
-typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
-
-ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
- in_func in, void FAR *in_desc,
- out_func out, void FAR *out_desc));
-/*
- inflateBack() does a raw inflate with a single call using a call-back
- interface for input and output. This is more efficient than inflate() for
- file i/o applications in that it avoids copying between the output and the
- sliding window by simply making the window itself the output buffer. This
- function trusts the application to not change the output buffer passed by
- the output function, at least until inflateBack() returns.
-
- inflateBackInit() must be called first to allocate the internal state
- and to initialize the state with the user-provided window buffer.
- inflateBack() may then be used multiple times to inflate a complete, raw
- deflate stream with each call. inflateBackEnd() is then called to free
- the allocated state.
-
- A raw deflate stream is one with no zlib or gzip header or trailer.
- This routine would normally be used in a utility that reads zip or gzip
- files and writes out uncompressed files. The utility would decode the
- header and process the trailer on its own, hence this routine expects
- only the raw deflate stream to decompress. This is different from the
- normal behavior of inflate(), which expects either a zlib or gzip header and
- trailer around the deflate stream.
-
- inflateBack() uses two subroutines supplied by the caller that are then
- called by inflateBack() for input and output. inflateBack() calls those
- routines until it reads a complete deflate stream and writes out all of the
- uncompressed data, or until it encounters an error. The function's
- parameters and return types are defined above in the in_func and out_func
- typedefs. inflateBack() will call in(in_desc, &buf) which should return the
- number of bytes of provided input, and a pointer to that input in buf. If
- there is no input available, in() must return zero--buf is ignored in that
- case--and inflateBack() will return a buffer error. inflateBack() will call
- out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out()
- should return zero on success, or non-zero on failure. If out() returns
- non-zero, inflateBack() will return with an error. Neither in() nor out()
- are permitted to change the contents of the window provided to
- inflateBackInit(), which is also the buffer that out() uses to write from.
- The length written by out() will be at most the window size. Any non-zero
- amount of input may be provided by in().
-
- For convenience, inflateBack() can be provided input on the first call by
- setting strm->next_in and strm->avail_in. If that input is exhausted, then
- in() will be called. Therefore strm->next_in must be initialized before
- calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called
- immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in
- must also be initialized, and then if strm->avail_in is not zero, input will
- initially be taken from strm->next_in[0 .. strm->avail_in - 1].
-
- The in_desc and out_desc parameters of inflateBack() is passed as the
- first parameter of in() and out() respectively when they are called. These
- descriptors can be optionally used to pass any information that the caller-
- supplied in() and out() functions need to do their job.
-
- On return, inflateBack() will set strm->next_in and strm->avail_in to
- pass back any unused input that was provided by the last in() call. The
- return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
- if in() or out() returned an error, Z_DATA_ERROR if there was a format
- error in the deflate stream (in which case strm->msg is set to indicate the
- nature of the error), or Z_STREAM_ERROR if the stream was not properly
- initialized. In the case of Z_BUF_ERROR, an input or output error can be
- distinguished using strm->next_in which will be Z_NULL only if in() returned
- an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to
- out() returning non-zero. (in() will always be called before out(), so
- strm->next_in is assured to be defined if out() returns non-zero.) Note
- that inflateBack() cannot return Z_OK.
-*/
-
-ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
-/*
- All memory allocated by inflateBackInit() is freed.
-
- inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
- state was inconsistent.
-*/
-
-ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
-/* Return flags indicating compile-time options.
-
- Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
- 1.0: size of uInt
- 3.2: size of uLong
- 5.4: size of voidpf (pointer)
- 7.6: size of z_off_t
-
- Compiler, assembler, and debug options:
- 8: DEBUG
- 9: ASMV or ASMINF -- use ASM code
- 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
- 11: 0 (reserved)
-
- One-time table building (smaller code, but not thread-safe if true):
- 12: BUILDFIXED -- build static block decoding tables when needed
- 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
- 14,15: 0 (reserved)
-
- Library content (indicates missing functionality):
- 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
- deflate code when not needed)
- 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
- and decode gzip streams (to avoid linking crc code)
- 18-19: 0 (reserved)
-
- Operation variations (changes in library functionality):
- 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
- 21: FASTEST -- deflate algorithm with only one, lowest compression level
- 22,23: 0 (reserved)
-
- The sprintf variant used by gzprintf (zero is best):
- 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
- 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
- 26: 0 = returns value, 1 = void -- 1 means inferred string length returned
-
- Remainder:
- 27-31: 0 (reserved)
- */
-
-
- /* utility functions */
-
-/*
- The following utility functions are implemented on top of the
- basic stream-oriented functions. To simplify the interface, some
- default options are assumed (compression level and memory usage,
- standard memory allocation functions). The source code of these
- utility functions can easily be modified if you need special options.
-*/
-
-ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
- const Bytef *source, uLong sourceLen));
-/*
- Compresses the source buffer into the destination buffer. sourceLen is
- the byte length of the source buffer. Upon entry, destLen is the total
- size of the destination buffer, which must be at least the value returned
- by compressBound(sourceLen). Upon exit, destLen is the actual size of the
- compressed buffer.
- This function can be used to compress a whole file at once if the
- input file is mmap'ed.
- compress returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_BUF_ERROR if there was not enough room in the output
- buffer.
-*/
-
-ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
- const Bytef *source, uLong sourceLen,
- int level));
-/*
- Compresses the source buffer into the destination buffer. The level
- parameter has the same meaning as in deflateInit. sourceLen is the byte
- length of the source buffer. Upon entry, destLen is the total size of the
- destination buffer, which must be at least the value returned by
- compressBound(sourceLen). Upon exit, destLen is the actual size of the
- compressed buffer.
-
- compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_BUF_ERROR if there was not enough room in the output buffer,
- Z_STREAM_ERROR if the level parameter is invalid.
-*/
-
-ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
-/*
- compressBound() returns an upper bound on the compressed size after
- compress() or compress2() on sourceLen bytes. It would be used before
- a compress() or compress2() call to allocate the destination buffer.
-*/
-
-ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
- const Bytef *source, uLong sourceLen));
-/*
- Decompresses the source buffer into the destination buffer. sourceLen is
- the byte length of the source buffer. Upon entry, destLen is the total
- size of the destination buffer, which must be large enough to hold the
- entire uncompressed data. (The size of the uncompressed data must have
- been saved previously by the compressor and transmitted to the decompressor
- by some mechanism outside the scope of this compression library.)
- Upon exit, destLen is the actual size of the compressed buffer.
- This function can be used to decompress a whole file at once if the
- input file is mmap'ed.
-
- uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_BUF_ERROR if there was not enough room in the output
- buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.
-*/
-
-
-typedef voidp gzFile;
-
-ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
-/*
- Opens a gzip (.gz) file for reading or writing. The mode parameter
- is as in fopen ("rb" or "wb") but can also include a compression level
- ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
- Huffman only compression as in "wb1h", or 'R' for run-length encoding
- as in "wb1R". (See the description of deflateInit2 for more information
- about the strategy parameter.)
-
- gzopen can be used to read a file which is not in gzip format; in this
- case gzread will directly read from the file without decompression.
-
- gzopen returns NULL if the file could not be opened or if there was
- insufficient memory to allocate the (de)compression state; errno
- can be checked to distinguish the two cases (if errno is zero, the
- zlib error is Z_MEM_ERROR). */
-
-ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
-/*
- gzdopen() associates a gzFile with the file descriptor fd. File
- descriptors are obtained from calls like open, dup, creat, pipe or
- fileno (in the file has been previously opened with fopen).
- The mode parameter is as in gzopen.
- The next call of gzclose on the returned gzFile will also close the
- file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
- descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
- gzdopen returns NULL if there was insufficient memory to allocate
- the (de)compression state.
-*/
-
-ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
-/*
- Dynamically update the compression level or strategy. See the description
- of deflateInit2 for the meaning of these parameters.
- gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
- opened for writing.
-*/
-
-ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
-/*
- Reads the given number of uncompressed bytes from the compressed file.
- If the input file was not in gzip format, gzread copies the given number
- of bytes into the buffer.
- gzread returns the number of uncompressed bytes actually read (0 for
- end of file, -1 for error). */
-
-ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
- voidpc buf, unsigned len));
-/*
- Writes the given number of uncompressed bytes into the compressed file.
- gzwrite returns the number of uncompressed bytes actually written
- (0 in case of error).
-*/
-
-ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
-/*
- Converts, formats, and writes the args to the compressed file under
- control of the format string, as in fprintf. gzprintf returns the number of
- uncompressed bytes actually written (0 in case of error). The number of
- uncompressed bytes written is limited to 4095. The caller should assure that
- this limit is not exceeded. If it is exceeded, then gzprintf() will return
- return an error (0) with nothing written. In this case, there may also be a
- buffer overflow with unpredictable consequences, which is possible only if
- zlib was compiled with the insecure functions sprintf() or vsprintf()
- because the secure snprintf() or vsnprintf() functions were not available.
-*/
-
-ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
-/*
- Writes the given null-terminated string to the compressed file, excluding
- the terminating null character.
- gzputs returns the number of characters written, or -1 in case of error.
-*/
-
-ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
-/*
- Reads bytes from the compressed file until len-1 characters are read, or
- a newline character is read and transferred to buf, or an end-of-file
- condition is encountered. The string is then terminated with a null
- character.
- gzgets returns buf, or Z_NULL in case of error.
-*/
-
-ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
-/*
- Writes c, converted to an unsigned char, into the compressed file.
- gzputc returns the value that was written, or -1 in case of error.
-*/
-
-ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
-/*
- Reads one byte from the compressed file. gzgetc returns this byte
- or -1 in case of end of file or error.
-*/
-
-ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
-/*
- Push one character back onto the stream to be read again later.
- Only one character of push-back is allowed. gzungetc() returns the
- character pushed, or -1 on failure. gzungetc() will fail if a
- character has been pushed but not read yet, or if c is -1. The pushed
- character will be discarded if the stream is repositioned with gzseek()
- or gzrewind().
-*/
-
-ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
-/*
- Flushes all pending output into the compressed file. The parameter
- flush is as in the deflate() function. The return value is the zlib
- error number (see function gzerror below). gzflush returns Z_OK if
- the flush parameter is Z_FINISH and all output could be flushed.
- gzflush should be called only when strictly necessary because it can
- degrade compression.
-*/
-
-ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
- z_off_t offset, int whence));
-/*
- Sets the starting position for the next gzread or gzwrite on the
- given compressed file. The offset represents a number of bytes in the
- uncompressed data stream. The whence parameter is defined as in lseek(2);
- the value SEEK_END is not supported.
- If the file is opened for reading, this function is emulated but can be
- extremely slow. If the file is opened for writing, only forward seeks are
- supported; gzseek then compresses a sequence of zeroes up to the new
- starting position.
-
- gzseek returns the resulting offset location as measured in bytes from
- the beginning of the uncompressed stream, or -1 in case of error, in
- particular if the file is opened for writing and the new starting position
- would be before the current position.
-*/
-
-ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
-/*
- Rewinds the given file. This function is supported only for reading.
-
- gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
-*/
-
-ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
-/*
- Returns the starting position for the next gzread or gzwrite on the
- given compressed file. This position represents a number of bytes in the
- uncompressed data stream.
-
- gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
-*/
-
-ZEXTERN int ZEXPORT gzeof OF((gzFile file));
-/*
- Returns 1 when EOF has previously been detected reading the given
- input stream, otherwise zero.
-*/
-
-ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
-/*
- Returns 1 if file is being read directly without decompression, otherwise
- zero.
-*/
-
-ZEXTERN int ZEXPORT gzclose OF((gzFile file));
-/*
- Flushes all pending output if necessary, closes the compressed file
- and deallocates all the (de)compression state. The return value is the zlib
- error number (see function gzerror below).
-*/
-
-ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
-/*
- Returns the error message for the last error which occurred on the
- given compressed file. errnum is set to zlib error number. If an
- error occurred in the file system and not in the compression library,
- errnum is set to Z_ERRNO and the application may consult errno
- to get the exact error code.
-*/
-
-ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
-/*
- Clears the error and end-of-file flags for file. This is analogous to the
- clearerr() function in stdio. This is useful for continuing to read a gzip
- file that is being written concurrently.
-*/
-
- /* checksum functions */
-
-/*
- These functions are not related to compression but are exported
- anyway because they might be useful in applications using the
- compression library.
-*/
-
-ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
-/*
- Update a running Adler-32 checksum with the bytes buf[0..len-1] and
- return the updated checksum. If buf is NULL, this function returns
- the required initial value for the checksum.
- An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
- much faster. Usage example:
-
- uLong adler = adler32(0L, Z_NULL, 0);
-
- while (read_buffer(buffer, length) != EOF) {
- adler = adler32(adler, buffer, length);
- }
- if (adler != original_adler) error();
-*/
-
-ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
- z_off_t len2));
-/*
- Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
- and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
- each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
- seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.
-*/
-
-ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
-/*
- Update a running CRC-32 with the bytes buf[0..len-1] and return the
- updated CRC-32. If buf is NULL, this function returns the required initial
- value for the for the crc. Pre- and post-conditioning (one's complement) is
- performed within this function so it shouldn't be done by the application.
- Usage example:
-
- uLong crc = crc32(0L, Z_NULL, 0);
-
- while (read_buffer(buffer, length) != EOF) {
- crc = crc32(crc, buffer, length);
- }
- if (crc != original_crc) error();
-*/
-
-ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
-
-/*
- Combine two CRC-32 check values into one. For two sequences of bytes,
- seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
- calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32
- check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
- len2.
-*/
-
-
- /* various hacks, don't look :) */
-
-/* deflateInit and inflateInit are macros to allow checking the zlib version
- * and the compiler's view of z_stream:
- */
-ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
- const char *version, int stream_size));
-ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
- const char *version, int stream_size));
-ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
- int windowBits, int memLevel,
- int strategy, const char *version,
- int stream_size));
-ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
- const char *version, int stream_size));
-ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
- unsigned char FAR *window,
- const char *version,
- int stream_size));
-#define deflateInit(strm, level) \
- deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
-#define inflateInit(strm) \
- inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
-#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
- deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
- (strategy), ZLIB_VERSION, sizeof(z_stream))
-#define inflateInit2(strm, windowBits) \
- inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
-#define inflateBackInit(strm, windowBits, window) \
- inflateBackInit_((strm), (windowBits), (window), \
- ZLIB_VERSION, sizeof(z_stream))
-
-
-#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
- struct internal_state {int dummy;}; /* hack for buggy compilers */
-#endif
-
-ZEXTERN const char * ZEXPORT zError OF((int));
-ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
-ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* ZLIB_H */
diff --git a/WebCore/platform/image-decoders/zlib/zutil.c b/WebCore/platform/image-decoders/zlib/zutil.c
deleted file mode 100644
index 4a51340..0000000
--- a/WebCore/platform/image-decoders/zlib/zutil.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/* zutil.c -- target dependent utility functions for the compression library
- * Copyright (C) 1995-2005 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id: zutil.c,v 3.11 2005/08/04 19:14:14 tor%cs.brown.edu Exp $ */
-
-#include "zutil.h"
-
-#ifndef NO_DUMMY_DECL
-struct internal_state {int dummy;}; /* for buggy compilers */
-#endif
-
-const char * const z_errmsg[10] = {
-"need dictionary", /* Z_NEED_DICT 2 */
-"stream end", /* Z_STREAM_END 1 */
-"", /* Z_OK 0 */
-"file error", /* Z_ERRNO (-1) */
-"stream error", /* Z_STREAM_ERROR (-2) */
-"data error", /* Z_DATA_ERROR (-3) */
-"insufficient memory", /* Z_MEM_ERROR (-4) */
-"buffer error", /* Z_BUF_ERROR (-5) */
-"incompatible version",/* Z_VERSION_ERROR (-6) */
-""};
-
-
-const char * ZEXPORT zlibVersion()
-{
- return ZLIB_VERSION;
-}
-
-uLong ZEXPORT zlibCompileFlags()
-{
- uLong flags;
-
- flags = 0;
- switch (sizeof(uInt)) {
- case 2: break;
- case 4: flags += 1; break;
- case 8: flags += 2; break;
- default: flags += 3;
- }
- switch (sizeof(uLong)) {
- case 2: break;
- case 4: flags += 1 << 2; break;
- case 8: flags += 2 << 2; break;
- default: flags += 3 << 2;
- }
- switch (sizeof(voidpf)) {
- case 2: break;
- case 4: flags += 1 << 4; break;
- case 8: flags += 2 << 4; break;
- default: flags += 3 << 4;
- }
- switch (sizeof(z_off_t)) {
- case 2: break;
- case 4: flags += 1 << 6; break;
- case 8: flags += 2 << 6; break;
- default: flags += 3 << 6;
- }
-#ifdef DEBUG
- flags += 1 << 8;
-#endif
-#if defined(ASMV) || defined(ASMINF)
- flags += 1 << 9;
-#endif
-#ifdef ZLIB_WINAPI
- flags += 1 << 10;
-#endif
-#ifdef BUILDFIXED
- flags += 1 << 12;
-#endif
-#ifdef DYNAMIC_CRC_TABLE
- flags += 1 << 13;
-#endif
-#ifdef NO_GZCOMPRESS
- flags += 1L << 16;
-#endif
-#ifdef NO_GZIP
- flags += 1L << 17;
-#endif
-#ifdef PKZIP_BUG_WORKAROUND
- flags += 1L << 20;
-#endif
-#ifdef FASTEST
- flags += 1L << 21;
-#endif
-#ifdef STDC
-# ifdef NO_vsnprintf
- flags += 1L << 25;
-# ifdef HAS_vsprintf_void
- flags += 1L << 26;
-# endif
-# else
-# ifdef HAS_vsnprintf_void
- flags += 1L << 26;
-# endif
-# endif
-#else
- flags += 1L << 24;
-# ifdef NO_snprintf
- flags += 1L << 25;
-# ifdef HAS_sprintf_void
- flags += 1L << 26;
-# endif
-# else
-# ifdef HAS_snprintf_void
- flags += 1L << 26;
-# endif
-# endif
-#endif
- return flags;
-}
-
-#ifdef DEBUG
-
-# ifndef verbose
-# define verbose 0
-# endif
-int z_verbose = verbose;
-
-void z_error (m)
- char *m;
-{
- fprintf(stderr, "%s\n", m);
- exit(1);
-}
-#endif
-
-/* exported to allow conversion of error code to string for compress() and
- * uncompress()
- */
-const char * ZEXPORT zError(err)
- int err;
-{
- return ERR_MSG(err);
-}
-
-#if defined(_WIN32_WCE)
- /* The Microsoft C Run-Time Library for Windows CE doesn't have
- * errno. We define it as a global variable to simplify porting.
- * Its value is always 0 and should not be used.
- */
- int errno = 0;
-#endif
-
-#ifndef HAVE_MEMCPY
-
-void zmemcpy(dest, source, len)
- Bytef* dest;
- const Bytef* source;
- uInt len;
-{
- if (len == 0) return;
- do {
- *dest++ = *source++; /* ??? to be unrolled */
- } while (--len != 0);
-}
-
-int zmemcmp(s1, s2, len)
- const Bytef* s1;
- const Bytef* s2;
- uInt len;
-{
- uInt j;
-
- for (j = 0; j < len; j++) {
- if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
- }
- return 0;
-}
-
-void zmemzero(dest, len)
- Bytef* dest;
- uInt len;
-{
- if (len == 0) return;
- do {
- *dest++ = 0; /* ??? to be unrolled */
- } while (--len != 0);
-}
-#endif
-
-
-#ifdef SYS16BIT
-
-#ifdef __TURBOC__
-/* Turbo C in 16-bit mode */
-
-# define MY_ZCALLOC
-
-/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
- * and farmalloc(64K) returns a pointer with an offset of 8, so we
- * must fix the pointer. Warning: the pointer must be put back to its
- * original form in order to free it, use zcfree().
- */
-
-#define MAX_PTR 10
-/* 10*64K = 640K */
-
-local int next_ptr = 0;
-
-typedef struct ptr_table_s {
- voidpf org_ptr;
- voidpf new_ptr;
-} ptr_table;
-
-local ptr_table table[MAX_PTR];
-/* This table is used to remember the original form of pointers
- * to large buffers (64K). Such pointers are normalized with a zero offset.
- * Since MSDOS is not a preemptive multitasking OS, this table is not
- * protected from concurrent access. This hack doesn't work anyway on
- * a protected system like OS/2. Use Microsoft C instead.
- */
-
-voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
-{
- voidpf buf = opaque; /* just to make some compilers happy */
- ulg bsize = (ulg)items*size;
-
- /* If we allocate less than 65520 bytes, we assume that farmalloc
- * will return a usable pointer which doesn't have to be normalized.
- */
- if (bsize < 65520L) {
- buf = farmalloc(bsize);
- if (*(ush*)&buf != 0) return buf;
- } else {
- buf = farmalloc(bsize + 16L);
- }
- if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
- table[next_ptr].org_ptr = buf;
-
- /* Normalize the pointer to seg:0 */
- *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
- *(ush*)&buf = 0;
- table[next_ptr++].new_ptr = buf;
- return buf;
-}
-
-void zcfree (voidpf opaque, voidpf ptr)
-{
- int n;
- if (*(ush*)&ptr != 0) { /* object < 64K */
- farfree(ptr);
- return;
- }
- /* Find the original pointer */
- for (n = 0; n < next_ptr; n++) {
- if (ptr != table[n].new_ptr) continue;
-
- farfree(table[n].org_ptr);
- while (++n < next_ptr) {
- table[n-1] = table[n];
- }
- next_ptr--;
- return;
- }
- ptr = opaque; /* just to make some compilers happy */
- Assert(0, "zcfree: ptr not found");
-}
-
-#endif /* __TURBOC__ */
-
-
-#ifdef M_I86
-/* Microsoft C in 16-bit mode */
-
-# define MY_ZCALLOC
-
-#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
-# define _halloc halloc
-# define _hfree hfree
-#endif
-
-voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
-{
- if (opaque) opaque = 0; /* to make compiler happy */
- return _halloc((long)items, size);
-}
-
-void zcfree (voidpf opaque, voidpf ptr)
-{
- if (opaque) opaque = 0; /* to make compiler happy */
- _hfree(ptr);
-}
-
-#endif /* M_I86 */
-
-#endif /* SYS16BIT */
-
-
-#ifndef MY_ZCALLOC /* Any system without a special alloc function */
-
-#ifndef STDC
-extern voidp malloc OF((uInt size));
-extern voidp calloc OF((uInt items, uInt size));
-extern void free OF((voidpf ptr));
-#endif
-
-voidpf zcalloc (opaque, items, size)
- voidpf opaque;
- unsigned items;
- unsigned size;
-{
- if (opaque) items += size - size; /* make compiler happy */
- return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
- (voidpf)calloc(items, size);
-}
-
-void zcfree (opaque, ptr)
- voidpf opaque;
- voidpf ptr;
-{
- free(ptr);
- if (opaque) return; /* make compiler happy */
-}
-
-#endif /* MY_ZCALLOC */
diff --git a/WebCore/platform/image-decoders/zlib/zutil.h b/WebCore/platform/image-decoders/zlib/zutil.h
deleted file mode 100644
index 8b26cef..0000000
--- a/WebCore/platform/image-decoders/zlib/zutil.h
+++ /dev/null
@@ -1,269 +0,0 @@
-/* zutil.h -- internal interface and configuration of the compression library
- * Copyright (C) 1995-2005 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* @(#) $Id: zutil.h,v 3.10 2005/08/04 19:14:14 tor%cs.brown.edu Exp $ */
-
-#ifndef ZUTIL_H
-#define ZUTIL_H
-
-#define ZLIB_INTERNAL
-#include "zlib.h"
-
-#ifdef STDC
-# ifndef _WIN32_WCE
-# include <stddef.h>
-# endif
-# include <string.h>
-# include <stdlib.h>
-#endif
-#ifdef NO_ERRNO_H
-# ifdef _WIN32_WCE
- /* The Microsoft C Run-Time Library for Windows CE doesn't have
- * errno. We define it as a global variable to simplify porting.
- * Its value is always 0 and should not be used. We rename it to
- * avoid conflict with other libraries that use the same workaround.
- */
-# define errno z_errno
-# endif
- extern int errno;
-#else
-# ifndef _WIN32_WCE
-# include <errno.h>
-# endif
-#endif
-
-#ifndef local
-# define local static
-#endif
-/* compile with -Dlocal if your debugger can't find static symbols */
-
-typedef unsigned char uch;
-typedef uch FAR uchf;
-typedef unsigned short ush;
-typedef ush FAR ushf;
-typedef unsigned long ulg;
-
-extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
-/* (size given to avoid silly warnings with Visual C++) */
-
-#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
-
-#define ERR_RETURN(strm,err) \
- return (strm->msg = (char*)ERR_MSG(err), (err))
-/* To be used only when the state is known to be valid */
-
- /* common constants */
-
-#ifndef DEF_WBITS
-# define DEF_WBITS MAX_WBITS
-#endif
-/* default windowBits for decompression. MAX_WBITS is for compression only */
-
-#if MAX_MEM_LEVEL >= 8
-# define DEF_MEM_LEVEL 8
-#else
-# define DEF_MEM_LEVEL MAX_MEM_LEVEL
-#endif
-/* default memLevel */
-
-#define STORED_BLOCK 0
-#define STATIC_TREES 1
-#define DYN_TREES 2
-/* The three kinds of block type */
-
-#define MIN_MATCH 3
-#define MAX_MATCH 258
-/* The minimum and maximum match lengths */
-
-#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
-
- /* target dependencies */
-
-#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
-# define OS_CODE 0x00
-# if defined(__TURBOC__) || defined(__BORLANDC__)
-# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
- /* Allow compilation with ANSI keywords only enabled */
- void _Cdecl farfree( void *block );
- void *_Cdecl farmalloc( unsigned long nbytes );
-# else
-# include <alloc.h>
-# endif
-# else /* MSC or DJGPP */
-# include <malloc.h>
-# endif
-#endif
-
-#ifdef AMIGA
-# define OS_CODE 0x01
-#endif
-
-#if defined(VAXC) || defined(VMS)
-# define OS_CODE 0x02
-# define F_OPEN(name, mode) \
- fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
-#endif
-
-#if defined(ATARI) || defined(atarist)
-# define OS_CODE 0x05
-#endif
-
-#ifdef OS2
-# define OS_CODE 0x06
-# ifdef M_I86
- #include <malloc.h>
-# endif
-#endif
-
-#if defined(MACOS) || defined(TARGET_OS_MAC)
-# define OS_CODE 0x07
-# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
-# include <unix.h> /* for fdopen */
-# else
-# ifndef fdopen
-# define fdopen(fd,mode) NULL /* No fdopen() */
-# endif
-# endif
-#endif
-
-#ifdef TOPS20
-# define OS_CODE 0x0a
-#endif
-
-#ifdef WIN32
-# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */
-# define OS_CODE 0x0b
-# endif
-#endif
-
-#ifdef __50SERIES /* Prime/PRIMOS */
-# define OS_CODE 0x0f
-#endif
-
-#if defined(_BEOS_) || defined(RISCOS)
-# define fdopen(fd,mode) NULL /* No fdopen() */
-#endif
-
-#if (defined(_MSC_VER) && (_MSC_VER > 600))
-# if defined(_WIN32_WCE)
-# define fdopen(fd,mode) NULL /* No fdopen() */
-# ifndef _PTRDIFF_T_DEFINED
- typedef int ptrdiff_t;
-# define _PTRDIFF_T_DEFINED
-# endif
-# else
-# define fdopen(fd,type) _fdopen(fd,type)
-# endif
-#endif
-
- /* common defaults */
-
-#ifndef OS_CODE
-# define OS_CODE 0x03 /* assume Unix */
-#endif
-
-#ifndef F_OPEN
-# define F_OPEN(name, mode) fopen((name), (mode))
-#endif
-
- /* functions */
-
-#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
-# ifndef HAVE_VSNPRINTF
-# define HAVE_VSNPRINTF
-# endif
-#endif
-#if defined(__CYGWIN__)
-# ifndef HAVE_VSNPRINTF
-# define HAVE_VSNPRINTF
-# endif
-#endif
-#ifndef HAVE_VSNPRINTF
-# ifdef MSDOS
- /* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
- but for now we just assume it doesn't. */
-# define NO_vsnprintf
-# endif
-# ifdef __TURBOC__
-# define NO_vsnprintf
-# endif
-# ifdef WIN32
- /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
-# if !defined(vsnprintf) && !defined(NO_vsnprintf)
-# define vsnprintf _vsnprintf
-# endif
-# endif
-# ifdef __SASC
-# define NO_vsnprintf
-# endif
-#endif
-#ifdef VMS
-# define NO_vsnprintf
-#endif
-
-#if defined(pyr)
-# define NO_MEMCPY
-#endif
-#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
- /* Use our own functions for small and medium model with MSC <= 5.0.
- * You may have to use the same strategy for Borland C (untested).
- * The __SC__ check is for Symantec.
- */
-# define NO_MEMCPY
-#endif
-#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
-# define HAVE_MEMCPY
-#endif
-#ifdef HAVE_MEMCPY
-# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
-# define zmemcpy _fmemcpy
-# define zmemcmp _fmemcmp
-# define zmemzero(dest, len) _fmemset(dest, 0, len)
-# else
-# define zmemcpy memcpy
-# define zmemcmp memcmp
-# define zmemzero(dest, len) memset(dest, 0, len)
-# endif
-#else
- extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
- extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
- extern void zmemzero OF((Bytef* dest, uInt len));
-#endif
-
-/* Diagnostic functions */
-#ifdef DEBUG
-# include <stdio.h>
- extern int z_verbose;
- extern void z_error OF((char *m));
-# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
-# define Trace(x) {if (z_verbose>=0) fprintf x ;}
-# define Tracev(x) {if (z_verbose>0) fprintf x ;}
-# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
-# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
-# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
-#else
-# define Assert(cond,msg)
-# define Trace(x)
-# define Tracev(x)
-# define Tracevv(x)
-# define Tracec(c,x)
-# define Tracecv(c,x)
-#endif
-
-
-voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
-void zcfree OF((voidpf opaque, voidpf ptr));
-
-#define ZALLOC(strm, items, size) \
- (*((strm)->zalloc))((strm)->opaque, (items), (size))
-#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
-#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
-
-#endif /* ZUTIL_H */
diff --git a/WebCore/platform/mac/GeolocationServiceMac.mm b/WebCore/platform/mac/GeolocationServiceMac.mm
index 1093e69..9c781ad 100644
--- a/WebCore/platform/mac/GeolocationServiceMac.mm
+++ b/WebCore/platform/mac/GeolocationServiceMac.mm
@@ -25,7 +25,7 @@
#import "config.h"
-#if ENABLE(GEOLOCATION)
+#if ENABLE(GEOLOCATION) && !ENABLE(CLIENT_BASED_GEOLOCATION)
#import "GeolocationServiceMac.h"
diff --git a/WebCore/platform/mac/KeyEventMac.mm b/WebCore/platform/mac/KeyEventMac.mm
index b6c3b21..2e1579b 100644
--- a/WebCore/platform/mac/KeyEventMac.mm
+++ b/WebCore/platform/mac/KeyEventMac.mm
@@ -368,6 +368,9 @@ static bool isKeypadEvent(NSEvent* event)
return false;
}
+ if ([event modifierFlags] & NSNumericPadKeyMask)
+ return true;
+
switch ([event keyCode]) {
case 71: // Clear
case 81: // =
@@ -808,6 +811,19 @@ static inline String unmodifiedTextFromEvent(NSEvent* event)
return [event charactersIgnoringModifiers];
}
+PlatformKeyboardEvent::PlatformKeyboardEvent()
+ : m_type(KeyDown)
+ , m_autoRepeat(false)
+ , m_windowsVirtualKeyCode(0)
+ , m_nativeVirtualKeyCode(0)
+ , m_isKeypad(false)
+ , m_shiftKey(false)
+ , m_ctrlKey(false)
+ , m_altKey(false)
+ , m_metaKey(false)
+{
+}
+
PlatformKeyboardEvent::PlatformKeyboardEvent(NSEvent *event)
: m_type(isKeyUpEvent(event) ? PlatformKeyboardEvent::KeyUp : PlatformKeyboardEvent::KeyDown)
, m_text(textFromEvent(event))
diff --git a/WebCore/platform/mac/LocalizedStringsMac.mm b/WebCore/platform/mac/LocalizedStringsMac.mm
index c438d6b..55fdd21 100644
--- a/WebCore/platform/mac/LocalizedStringsMac.mm
+++ b/WebCore/platform/mac/LocalizedStringsMac.mm
@@ -683,6 +683,23 @@ String AXLinkActionVerb()
return String();
}
+String AXMenuListPopupActionVerb()
+{
+ BEGIN_BLOCK_OBJC_EXCEPTIONS;
+ return [[WebCoreViewFactory sharedFactory] AXMenuListPopupActionVerb];
+ END_BLOCK_OBJC_EXCEPTIONS;
+ return String();
+}
+
+String AXMenuListActionVerb()
+{
+ BEGIN_BLOCK_OBJC_EXCEPTIONS;
+ return [[WebCoreViewFactory sharedFactory] AXMenuListActionVerb];
+ END_BLOCK_OBJC_EXCEPTIONS;
+ return String();
+}
+
+
String multipleFileUploadText(unsigned numberOfFiles)
{
BEGIN_BLOCK_OBJC_EXCEPTIONS;
diff --git a/WebCore/platform/mac/PasteboardMac.mm b/WebCore/platform/mac/PasteboardMac.mm
index f048791..8aa7f2c 100644
--- a/WebCore/platform/mac/PasteboardMac.mm
+++ b/WebCore/platform/mac/PasteboardMac.mm
@@ -136,7 +136,7 @@ static NSAttributedString *stripAttachmentCharacters(NSAttributedString *string)
void Pasteboard::writeSelection(NSPasteboard* pasteboard, Range* selectedRange, bool canSmartCopyOrDelete, Frame* frame)
{
if (!WebArchivePboardType)
- Pasteboard::generalPasteboard(); // Initialises pasteboard types
+ Pasteboard::generalPasteboard(); // Initializes pasteboard types.
ASSERT(selectedRange);
NSAttributedString *attributedString = [[[NSAttributedString alloc] _initWithDOMRange:kit(selectedRange)] autorelease];
@@ -206,7 +206,7 @@ void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete,
void Pasteboard::writePlainText(const String& text)
{
if (!WebArchivePboardType)
- Pasteboard::generalPasteboard(); // Initialises pasteboard types
+ Pasteboard::generalPasteboard(); // Initializes pasteboard types.
NSArray *types = [NSArray arrayWithObject:NSStringPboardType];
NSPasteboard *pasteboard = m_pasteboard.get();
@@ -218,7 +218,7 @@ void Pasteboard::writePlainText(const String& text)
void Pasteboard::writeURL(NSPasteboard* pasteboard, NSArray* types, const KURL& url, const String& titleStr, Frame* frame)
{
if (!WebArchivePboardType)
- Pasteboard::generalPasteboard(); // Initialises pasteboard types
+ Pasteboard::generalPasteboard(); // Initializes pasteboard types.
if (!types) {
types = writableTypesForURL();
@@ -372,7 +372,7 @@ PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefP
}
}
if ([HTMLString length] != 0) {
- RefPtr<DocumentFragment> fragment = createFragmentFromMarkup(frame->document(), HTMLString, "");
+ RefPtr<DocumentFragment> fragment = createFragmentFromMarkup(frame->document(), HTMLString, "", FragmentScriptingNotAllowed);
if (fragment)
return fragment.release();
}
diff --git a/WebCore/platform/mac/PlatformMouseEventMac.mm b/WebCore/platform/mac/PlatformMouseEventMac.mm
index 74f694e..5b84b4f 100644
--- a/WebCore/platform/mac/PlatformMouseEventMac.mm
+++ b/WebCore/platform/mac/PlatformMouseEventMac.mm
@@ -158,4 +158,22 @@ PlatformMouseEvent::PlatformMouseEvent(NSEvent* event, NSView *windowView)
{
}
+PlatformMouseEvent::PlatformMouseEvent(int x, int y, int globalX, int globalY, MouseButton button, MouseEventType eventType,
+ int clickCount, bool shiftKey, bool ctrlKey, bool altKey, bool metaKey, double timestamp,
+ unsigned modifierFlags, int eventNumber)
+ : m_position(IntPoint(x, y))
+ , m_globalPosition(IntPoint(globalX, globalY))
+ , m_button(button)
+ , m_eventType(eventType)
+ , m_clickCount(clickCount)
+ , m_shiftKey(shiftKey)
+ , m_ctrlKey(ctrlKey)
+ , m_altKey(altKey)
+ , m_metaKey(metaKey)
+ , m_timestamp(timestamp)
+ , m_modifierFlags(modifierFlags)
+ , m_eventNumber(eventNumber)
+{
+}
+
}
diff --git a/WebCore/platform/mac/PopupMenuMac.mm b/WebCore/platform/mac/PopupMenuMac.mm
index dfb0fff..22f1e5b 100644
--- a/WebCore/platform/mac/PopupMenuMac.mm
+++ b/WebCore/platform/mac/PopupMenuMac.mm
@@ -20,6 +20,7 @@
#import "config.h"
#import "PopupMenu.h"
+#import "Chrome.h"
#import "ChromeClient.h"
#import "EventHandler.h"
#import "Frame.h"
@@ -80,8 +81,14 @@ void PopupMenu::populate()
else {
PopupMenuStyle style = client()->itemStyle(i);
NSMutableDictionary* attributes = [[NSMutableDictionary alloc] init];
- if (style.font() != Font())
- [attributes setObject:style.font().primaryFont()->getNSFont() forKey:NSFontAttributeName];
+ if (style.font() != Font()) {
+ NSFont *font = style.font().primaryFont()->getNSFont();
+ if (!font) {
+ CGFloat size = style.font().primaryFont()->platformData().size();
+ font = style.font().weight() < FontWeightBold ? [NSFont systemFontOfSize:size] : [NSFont boldSystemFontOfSize:size];
+ }
+ [attributes setObject:font forKey:NSFontAttributeName];
+ }
// FIXME: Add support for styling the foreground and background colors.
// FIXME: Find a way to customize text color when an item is highlighted.
NSAttributedString* string = [[NSAttributedString alloc] initWithString:client()->itemText(i) attributes:attributes];
@@ -99,6 +106,8 @@ void PopupMenu::populate()
[[m_popup.get() menu] setMenuChangedMessagesEnabled:messagesEnabled];
}
+#if !ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE)
+
void PopupMenu::show(const IntRect& r, FrameView* v, int index)
{
populate();
@@ -179,6 +188,14 @@ void PopupMenu::show(const IntRect& r, FrameView* v, int index)
[event release];
}
+#else
+
+void PopupMenu::show(const IntRect&, FrameView*, int)
+{
+}
+
+#endif
+
void PopupMenu::hide()
{
[m_popup.get() dismissPopUp];
diff --git a/WebCore/platform/mac/RuntimeApplicationChecks.h b/WebCore/platform/mac/RuntimeApplicationChecks.h
index f9c7079..24b8ae1 100644
--- a/WebCore/platform/mac/RuntimeApplicationChecks.h
+++ b/WebCore/platform/mac/RuntimeApplicationChecks.h
@@ -31,6 +31,7 @@ namespace WebCore {
bool applicationIsAppleMail();
bool applicationIsSafari();
bool applicationIsMicrosoftMessenger();
+bool applicationIsAdobeInstaller();
} // namespace WebCore
diff --git a/WebCore/platform/mac/RuntimeApplicationChecks.mm b/WebCore/platform/mac/RuntimeApplicationChecks.mm
index a3c4aa5..bcc1dc9 100644
--- a/WebCore/platform/mac/RuntimeApplicationChecks.mm
+++ b/WebCore/platform/mac/RuntimeApplicationChecks.mm
@@ -47,4 +47,10 @@ bool applicationIsMicrosoftMessenger()
return isMicrosoftMessenger;
}
+bool applicationIsAdobeInstaller()
+{
+ static bool isAdobeInstaller = [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.adobe.Installers.Setup"];
+ return isAdobeInstaller;
+}
+
} // namespace WebCore
diff --git a/WebCore/platform/mac/ScrollViewMac.mm b/WebCore/platform/mac/ScrollViewMac.mm
index f31b301..7ef5dc4 100644
--- a/WebCore/platform/mac/ScrollViewMac.mm
+++ b/WebCore/platform/mac/ScrollViewMac.mm
@@ -57,8 +57,6 @@ NSView *ScrollView::documentView() const
return nil;
}
-#if !ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE)
-
void ScrollView::platformAddChild(Widget* child)
{
BEGIN_BLOCK_OBJC_EXCEPTIONS;
@@ -109,13 +107,12 @@ bool ScrollView::platformCanBlitOnScroll() const
IntRect ScrollView::platformVisibleContentRect(bool includeScrollbars) const
{
- BEGIN_BLOCK_OBJC_EXCEPTIONS;
- if (includeScrollbars) {
- if (NSView* documentView = this->documentView())
- return enclosingIntRect([documentView visibleRect]);
- }
- return enclosingIntRect([scrollView() documentVisibleRect]);
- END_BLOCK_OBJC_EXCEPTIONS;
+ BEGIN_BLOCK_OBJC_EXCEPTIONS;
+ IntRect result = enclosingIntRect([scrollView() documentVisibleRect]);
+ if (includeScrollbars)
+ result.setSize(IntSize([scrollView() frame].size));
+ return result;
+ END_BLOCK_OBJC_EXCEPTIONS;
return IntRect();
}
@@ -205,6 +202,4 @@ bool ScrollView::platformIsOffscreen() const
return ![platformWidget() window] || ![[platformWidget() window] isVisible];
}
-#endif // !ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE)
-
} // namespace WebCore
diff --git a/WebCore/platform/mac/ScrollbarThemeMac.mm b/WebCore/platform/mac/ScrollbarThemeMac.mm
index b4b8f62..067f28f 100644
--- a/WebCore/platform/mac/ScrollbarThemeMac.mm
+++ b/WebCore/platform/mac/ScrollbarThemeMac.mm
@@ -362,7 +362,7 @@ bool ScrollbarThemeMac::paint(Scrollbar* scrollbar, GraphicsContext* context, co
trackInfo.min = 0;
trackInfo.max = scrollbar->maximum();
trackInfo.value = scrollbar->currentPos();
- trackInfo.trackInfo.scrollbar.viewsize = scrollbar->pageStep();
+ trackInfo.trackInfo.scrollbar.viewsize = scrollbar->visibleSize();
trackInfo.attributes = 0;
if (scrollbar->orientation() == HorizontalScrollbar)
trackInfo.attributes |= kThemeTrackHorizontal;
diff --git a/WebCore/platform/mac/ThemeMac.mm b/WebCore/platform/mac/ThemeMac.mm
index a95fee4..2812607 100644
--- a/WebCore/platform/mac/ThemeMac.mm
+++ b/WebCore/platform/mac/ThemeMac.mm
@@ -355,7 +355,7 @@ static void setupButtonCell(NSButtonCell *&buttonCell, ControlPart part, Control
} else if ([buttonCell bezelStyle] != NSRoundedBezelStyle)
[buttonCell setBezelStyle:NSRoundedBezelStyle];
- setControlSize(buttonCell, buttonSizes(), zoomedRect.size(), zoomFactor);
+ setControlSize(buttonCell, sizes, zoomedRect.size(), zoomFactor);
// Update the various states we respond to.
updateStates(buttonCell, states);
diff --git a/WebCore/platform/mac/WebCoreObjCExtras.mm b/WebCore/platform/mac/WebCoreObjCExtras.mm
index cb8d504..4fc757c 100644
--- a/WebCore/platform/mac/WebCoreObjCExtras.mm
+++ b/WebCore/platform/mac/WebCoreObjCExtras.mm
@@ -72,8 +72,13 @@ bool WebCoreObjCScheduleDeallocateOnMainThread(Class cls, id object)
{
ASSERT([object isKindOfClass:cls]);
+#if USE(WEB_THREAD)
+ if (isMainThread())
+ return false;
+#else
if (pthread_main_np() != 0)
return false;
+#endif
ClassAndIdPair* pair = new ClassAndIdPair(cls, object);
callOnMainThread(deallocCallback, pair);
diff --git a/WebCore/platform/mac/WebCoreSystemInterface.h b/WebCore/platform/mac/WebCoreSystemInterface.h
index 917ab0b..e7521dc 100644
--- a/WebCore/platform/mac/WebCoreSystemInterface.h
+++ b/WebCore/platform/mac/WebCoreSystemInterface.h
@@ -48,6 +48,7 @@ typedef struct _NSRect NSRect;
@class NSFont;
@class NSImage;
@class NSMenu;
+@class NSMutableArray;
@class NSMutableURLRequest;
@class NSString;
@class NSTextFieldCell;
@@ -66,6 +67,7 @@ typedef struct NSEvent NSEvent;
typedef struct NSFont NSFont;
typedef struct NSImage NSImage;
typedef struct NSMenu NSMenu;
+typedef struct NSMutableArray NSMutableArray;
typedef struct NSMutableURLRequest NSMutableURLRequest;
typedef struct NSURLRequest NSURLRequest;
typedef struct NSString NSString;
@@ -134,6 +136,7 @@ extern void (*wkSetNSURLConnectionDefersCallbacks)(NSURLConnection *, BOOL);
extern void (*wkSetNSURLRequestShouldContentSniff)(NSMutableURLRequest *, BOOL);
extern void (*wkSetPatternBaseCTM)(CGContextRef, CGAffineTransform);
extern void (*wkSetPatternPhaseInUserSpace)(CGContextRef, CGPoint);
+extern CGAffineTransform (*wkGetUserToBaseCTM)(CGContextRef);
extern void (*wkSetUpFontCache)();
extern void (*wkSignalCFReadStreamEnd)(CFReadStreamRef stream);
extern void (*wkSignalCFReadStreamError)(CFReadStreamRef stream, CFStreamError *error);
@@ -166,6 +169,12 @@ extern BOOL (*wkSupportsMultipartXMixedReplace)(NSMutableURLRequest *);
extern BOOL (*wkUseSharedMediaUI)();
+#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
+extern NSMutableArray *(*wkNoteOpenPanelFiles)(NSArray *);
+#else
+extern void* wkNoteOpenPanelFiles;
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/WebCore/platform/mac/WebCoreSystemInterface.mm b/WebCore/platform/mac/WebCoreSystemInterface.mm
index 3a9c011..f3e0e77 100644
--- a/WebCore/platform/mac/WebCoreSystemInterface.mm
+++ b/WebCore/platform/mac/WebCoreSystemInterface.mm
@@ -66,6 +66,7 @@ void (*wkSetCGFontRenderingMode)(CGContextRef, NSFont*);
void (*wkSetDragImage)(NSImage*, NSPoint offset);
void (*wkSetPatternBaseCTM)(CGContextRef, CGAffineTransform);
void (*wkSetPatternPhaseInUserSpace)(CGContextRef, CGPoint point);
+CGAffineTransform (*wkGetUserToBaseCTM)(CGContextRef);
void (*wkSetUpFontCache)();
void (*wkSignalCFReadStreamEnd)(CFReadStreamRef stream);
void (*wkSignalCFReadStreamHasBytes)(CFReadStreamRef stream);
@@ -106,3 +107,9 @@ void (*wkReleaseStyleGroup)(void* group);
ATSUFontID (*wkGetNSFontATSUFontId)(NSFont*);
BOOL (*wkSupportsMultipartXMixedReplace)(NSMutableURLRequest *);
#endif
+
+#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
+NSMutableArray *(*wkNoteOpenPanelFiles)(NSArray *);
+#else
+void* wkNoteOpenPanelFiles;
+#endif
diff --git a/WebCore/platform/mac/WidgetMac.mm b/WebCore/platform/mac/WidgetMac.mm
index ebb47dc..e473053 100644
--- a/WebCore/platform/mac/WidgetMac.mm
+++ b/WebCore/platform/mac/WidgetMac.mm
@@ -31,12 +31,14 @@
#endif
#import "BlockExceptions.h"
+#import "Chrome.h"
#import "Cursor.h"
#import "Document.h"
#import "Font.h"
#import "FoundationExtras.h"
#import "Frame.h"
#import "GraphicsContext.h"
+#import "NotImplemented.h"
#import "Page.h"
#import "PlatformMouseEvent.h"
#import "ScrollView.h"
@@ -44,8 +46,6 @@
#import "WebCoreView.h"
#import <wtf/RetainPtr.h>
-#if !ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE)
-
@interface NSWindow (WebWindowDetails)
- (BOOL)_needsToResetDragMargins;
- (void)_setNeedsToResetDragMargins:(BOOL)needs;
@@ -56,12 +56,8 @@
- (void)webPlugInSetIsSelected:(BOOL)isSelected;
@end
-#endif
-
namespace WebCore {
-#if !ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE)
-
class WidgetPrivate {
public:
bool mustStayInWindow;
@@ -163,6 +159,9 @@ void Widget::setFrameRect(const IntRect& rect)
BEGIN_BLOCK_OBJC_EXCEPTIONS;
NSView *v = getOuterView();
+ if (!v)
+ return;
+
NSRect f = rect;
if (!NSEqualRects(f, [v frame])) {
[v setFrame:f];
@@ -198,7 +197,7 @@ void Widget::paint(GraphicsContext* p, const IntRect& r)
END_BLOCK_OBJC_EXCEPTIONS;
} else {
// This is the case of drawing into a bitmap context other than a window backing store. It gets hit beneath
- // -cacheDisplayInRect:toBitmapImageRep:.
+ // -cacheDisplayInRect:toBitmapImageRep:, and when painting into compositing layers.
// Transparent subframes are in fact implemented with scroll views that return YES from -drawsBackground (whenever the WebView
// itself is in drawsBackground mode). In the normal drawing code path, the scroll views are never asked to draw the background,
@@ -347,54 +346,5 @@ void Widget::retainPlatformWidget()
HardRetain(m_widget);
}
-#else // ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE)
-
-Widget::Widget(PlatformWidget widget)
-{
- init(widget);
-}
-
-Widget::~Widget()
-{
- ASSERT(!parent());
-}
-
-void Widget::show()
-{
-}
-
-void Widget::hide()
-{
-}
-
-void Widget::setCursor(const Cursor&)
-{
- notImplemented();
-}
-
-void Widget::paint(GraphicsContext*, const IntRect&)
-{
-}
-
-void Widget::setFocus()
-{
-}
-
-void Widget::setIsSelected(bool)
-{
-}
-
-IntRect Widget::frameRect() const
-{
- return m_frame;
-}
-
-void Widget::setFrameRect(const IntRect& rect)
-{
- m_frame = rect;
-}
-
-#endif
-
} // namespace WebCore
diff --git a/WebCore/platform/network/CredentialStorage.cpp b/WebCore/platform/network/CredentialStorage.cpp
index a401751..2c78e3c 100644
--- a/WebCore/platform/network/CredentialStorage.cpp
+++ b/WebCore/platform/network/CredentialStorage.cpp
@@ -31,7 +31,8 @@
#include "KURL.h"
#include "ProtectionSpaceHash.h"
#include "StringHash.h"
-
+#include <wtf/HashMap.h>
+#include <wtf/HashSet.h>
#include <wtf/StdLibExtras.h>
namespace WebCore {
diff --git a/WebCore/platform/network/NetworkStateNotifier.h b/WebCore/platform/network/NetworkStateNotifier.h
index d0463d4..77235b8 100644
--- a/WebCore/platform/network/NetworkStateNotifier.h
+++ b/WebCore/platform/network/NetworkStateNotifier.h
@@ -51,16 +51,28 @@ typedef const struct __SCDynamicStore * SCDynamicStoreRef;
namespace WebCore {
+#if (PLATFORM(QT) && ENABLE(QT_BEARER))
+class NetworkStateNotifierPrivate;
+#endif
+
class NetworkStateNotifier : public Noncopyable {
public:
NetworkStateNotifier();
void setNetworkStateChangedFunction(void (*)());
bool onLine() const { return m_isOnLine; }
+<<<<<<< HEAD
#if PLATFORM(ANDROID)
Connection::ConnectionType type() const { return m_type; }
#endif
+=======
+
+#if (PLATFORM(QT) && ENABLE(QT_BEARER))
+ void setNetworkAccessAllowed(bool);
+#endif
+
+>>>>>>> webkit.org at r54127
private:
bool m_isOnLine;
#if PLATFORM(ANDROID)
@@ -93,11 +105,18 @@ private:
#elif PLATFORM(ANDROID)
public:
void networkStateChange(bool online);
+<<<<<<< HEAD
void networkTypeChange(Connection::ConnectionType type);
+=======
+
+#elif PLATFORM(QT) && ENABLE(QT_BEARER)
+ friend class NetworkStateNotifierPrivate;
+ NetworkStateNotifierPrivate* p;
+>>>>>>> webkit.org at r54127
#endif
};
-#if !PLATFORM(MAC) && !PLATFORM(WIN) && !PLATFORM(CHROMIUM)
+#if !PLATFORM(MAC) && !PLATFORM(WIN) && !PLATFORM(CHROMIUM) && !(PLATFORM(QT) && ENABLE(QT_BEARER))
inline NetworkStateNotifier::NetworkStateNotifier()
: m_isOnLine(true)
diff --git a/WebCore/platform/network/ProtectionSpaceHash.h b/WebCore/platform/network/ProtectionSpaceHash.h
index f8c84e8..08716b5 100644
--- a/WebCore/platform/network/ProtectionSpaceHash.h
+++ b/WebCore/platform/network/ProtectionSpaceHash.h
@@ -27,6 +27,7 @@
#define ProtectionSpaceHash_h
#include "ProtectionSpace.h"
+#include <wtf/HashTraits.h>
namespace WebCore {
diff --git a/WebCore/platform/network/ResourceRequestBase.cpp b/WebCore/platform/network/ResourceRequestBase.cpp
index 41afb92..adf635c 100644
--- a/WebCore/platform/network/ResourceRequestBase.cpp
+++ b/WebCore/platform/network/ResourceRequestBase.cpp
@@ -390,7 +390,11 @@ void ResourceRequestBase::updateResourceRequest() const
m_resourceRequestUpdated = true;
}
+<<<<<<< HEAD
#if !PLATFORM(MAC) && !USE(CFNETWORK) && !USE(SOUP) && !PLATFORM(CHROMIUM) && !PLATFORM(ANDROID)
+=======
+#if !PLATFORM(MAC) && !USE(CFNETWORK) && !USE(SOUP) && !PLATFORM(CHROMIUM) && !PLATFORM(ANDROID) && !PLATFORM(QT)
+>>>>>>> webkit.org at r54127
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 931a9de..adf8327 100644
--- a/WebCore/platform/network/ResourceRequestBase.h
+++ b/WebCore/platform/network/ResourceRequestBase.h
@@ -50,7 +50,7 @@ namespace WebCore {
struct CrossThreadResourceRequestData;
// Do not use this type directly. Use ResourceRequest instead.
- class ResourceRequestBase {
+ class ResourceRequestBase : public FastAllocBase {
public:
// The type of this ResourceRequest, based on how the resource will be used.
enum TargetType {
diff --git a/WebCore/platform/network/ResourceResponseBase.h b/WebCore/platform/network/ResourceResponseBase.h
index e06c6f8..bf197a7 100644
--- a/WebCore/platform/network/ResourceResponseBase.h
+++ b/WebCore/platform/network/ResourceResponseBase.h
@@ -38,7 +38,7 @@ class ResourceResponse;
struct CrossThreadResourceResponseData;
// Do not use this class directly, use the class ResponseResponse instead
-class ResourceResponseBase {
+class ResourceResponseBase : public FastAllocBase {
public:
static std::auto_ptr<ResourceResponse> adopt(std::auto_ptr<CrossThreadResourceResponseData>);
@@ -151,7 +151,7 @@ private:
inline bool operator==(const ResourceResponse& a, const ResourceResponse& b) { return ResourceResponseBase::compare(a, b); }
inline bool operator!=(const ResourceResponse& a, const ResourceResponse& b) { return !(a == b); }
-struct CrossThreadResourceResponseData {
+struct CrossThreadResourceResponseData : Noncopyable {
KURL m_url;
String m_mimeType;
long long m_expectedContentLength;
diff --git a/WebCore/platform/network/android/NetworkStateNotifierAndroid.cpp b/WebCore/platform/network/android/NetworkStateNotifierAndroid.cpp
index 3ade2ed..177ba75 100644
--- a/WebCore/platform/network/android/NetworkStateNotifierAndroid.cpp
+++ b/WebCore/platform/network/android/NetworkStateNotifierAndroid.cpp
@@ -39,6 +39,7 @@ void NetworkStateNotifier::networkStateChange(bool online)
m_networkStateChangedFunction();
}
+<<<<<<< HEAD
void NetworkStateNotifier::networkTypeChange(Connection::ConnectionType type)
{
if (m_type == type)
@@ -50,4 +51,6 @@ void NetworkStateNotifier::networkTypeChange(Connection::ConnectionType type)
m_networkStateChangedFunction();
}
+=======
+>>>>>>> webkit.org at r54127
}
diff --git a/WebCore/platform/network/cf/DNSCFNet.cpp b/WebCore/platform/network/cf/DNSCFNet.cpp
index 6311baf..c17b59f 100644
--- a/WebCore/platform/network/cf/DNSCFNet.cpp
+++ b/WebCore/platform/network/cf/DNSCFNet.cpp
@@ -29,6 +29,7 @@
#include "StringHash.h"
#include "Timer.h"
+#include <wtf/HashSet.h>
#include <wtf/RetainPtr.h>
#include <wtf/StdLibExtras.h>
diff --git a/WebCore/platform/network/chromium/CookieJarChromium.cpp b/WebCore/platform/network/chromium/CookieJarChromium.cpp
index 279d9b0..35f1c3f 100644
--- a/WebCore/platform/network/chromium/CookieJarChromium.cpp
+++ b/WebCore/platform/network/chromium/CookieJarChromium.cpp
@@ -47,10 +47,9 @@ String cookies(const Document* document, const KURL& url)
return ChromiumBridge::cookies(url, document->firstPartyForCookies());
}
-bool cookiesEnabled(const Document*)
+bool cookiesEnabled(const Document* document)
{
- // FIXME: For now just assume cookies are always on.
- return true;
+ return ChromiumBridge::cookiesEnabled(document->cookieURL(), document->firstPartyForCookies());
}
bool getRawCookies(const Document* document, const KURL& url, Vector<Cookie>& rawCookies)
diff --git a/WebCore/platform/network/chromium/ResourceRequest.h b/WebCore/platform/network/chromium/ResourceRequest.h
index 176f923..8ef0c5e 100644
--- a/WebCore/platform/network/chromium/ResourceRequest.h
+++ b/WebCore/platform/network/chromium/ResourceRequest.h
@@ -28,7 +28,6 @@
#ifndef ResourceRequest_h
#define ResourceRequest_h
-#include "CString.h"
#include "ResourceRequestBase.h"
namespace WebCore {
@@ -45,15 +44,6 @@ namespace WebCore {
{
}
- ResourceRequest(const KURL& url, const CString& securityInfo)
- : ResourceRequestBase(url, UseProtocolCachePolicy)
- , m_requestorID(0)
- , m_requestorProcessID(0)
- , m_appCacheHostID(0)
- , m_securityInfo(securityInfo)
- {
- }
-
ResourceRequest(const KURL& url)
: ResourceRequestBase(url, UseProtocolCachePolicy)
, m_requestorID(0)
@@ -94,15 +84,6 @@ namespace WebCore {
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
- // resource has been loaded. This is used to simulate secure
- // connection for request (typically when showing error page, so the
- // error page has the errors of the page that actually failed). Empty
- // string if not a secure connection.
- CString securityInfo() const { return m_securityInfo; }
- void setSecurityInfo(const CString& value) { m_securityInfo = value; }
-
private:
friend class ResourceRequestBase;
@@ -112,7 +93,6 @@ namespace WebCore {
int m_requestorID;
int m_requestorProcessID;
int m_appCacheHostID;
- CString m_securityInfo;
};
} // namespace WebCore
diff --git a/WebCore/platform/network/chromium/ResourceResponse.h b/WebCore/platform/network/chromium/ResourceResponse.h
index 0c2b5d9..1b9de04 100644
--- a/WebCore/platform/network/chromium/ResourceResponse.h
+++ b/WebCore/platform/network/chromium/ResourceResponse.h
@@ -38,6 +38,7 @@ namespace WebCore {
ResourceResponse()
: m_isContentFiltered(false)
, m_appCacheID(0)
+ , m_wasFetchedViaSPDY(false)
{
}
@@ -45,6 +46,7 @@ namespace WebCore {
: ResourceResponseBase(url, mimeType, expectedLength, textEncodingName, filename)
, m_isContentFiltered(false)
, m_appCacheID(0)
+ , m_wasFetchedViaSPDY(false)
{
}
@@ -72,6 +74,12 @@ namespace WebCore {
m_appCacheManifestURL = url;
}
+ bool wasFetchedViaSPDY() const { return m_wasFetchedViaSPDY; }
+ void setWasFetchedViaSPDY(bool value)
+ {
+ m_wasFetchedViaSPDY = value;
+ }
+
private:
friend class ResourceResponseBase;
@@ -96,6 +104,8 @@ namespace WebCore {
// The manifest url of the appcache this response was retrieved from, if any.
// Note: only valid for main resource responses.
KURL m_appCacheManifestURL;
+
+ bool m_wasFetchedViaSPDY;
};
} // namespace WebCore
diff --git a/WebCore/platform/network/curl/ResourceHandleCurl.cpp b/WebCore/platform/network/curl/ResourceHandleCurl.cpp
index 5464e07..81ac1a3 100644
--- a/WebCore/platform/network/curl/ResourceHandleCurl.cpp
+++ b/WebCore/platform/network/curl/ResourceHandleCurl.cpp
@@ -156,7 +156,7 @@ void ResourceHandle::setDefersLoading(bool defers)
if (d->m_defersLoading == defers)
return;
-#if LIBCURL_VERSION_NUM > 0x071800
+#if LIBCURL_VERSION_NUM > 0x071200
if (!d->m_handle)
d->m_defersLoading = defers;
else if (defers) {
@@ -179,9 +179,7 @@ void ResourceHandle::setDefersLoading(bool defers)
}
#else
d->m_defersLoading = defers;
-#ifndef NDEBUG
- printf("Deferred loading is implemented if libcURL version is above 7.18.0");
-#endif
+ LOG_ERROR("Deferred loading is implemented if libcURL version is above 7.18.0");
#endif
}
diff --git a/WebCore/platform/network/curl/ResourceHandleManager.cpp b/WebCore/platform/network/curl/ResourceHandleManager.cpp
index a006a14..bcae67f 100644
--- a/WebCore/platform/network/curl/ResourceHandleManager.cpp
+++ b/WebCore/platform/network/curl/ResourceHandleManager.cpp
@@ -49,7 +49,7 @@
#include <wtf/Threading.h>
#include <wtf/Vector.h>
-#if !PLATFORM(WIN_OS)
+#if !OS(WINDOWS)
#include <sys/param.h>
#define MAX_PATH MAXPATHLEN
#endif
@@ -702,7 +702,7 @@ void ResourceHandleManager::initializeHandle(ResourceHandle* job)
d->m_handle = curl_easy_init();
-#if LIBCURL_VERSION_NUM > 0x071800
+#if LIBCURL_VERSION_NUM > 0x071200
if (d->m_defersLoading) {
CURLcode error = curl_easy_pause(d->m_handle, CURLPAUSE_ALL);
// If we did not pause the handle, we would ASSERT in the
diff --git a/WebCore/platform/network/mac/ResourceHandleMac.mm b/WebCore/platform/network/mac/ResourceHandleMac.mm
index 360425e..923a631 100644
--- a/WebCore/platform/network/mac/ResourceHandleMac.mm
+++ b/WebCore/platform/network/mac/ResourceHandleMac.mm
@@ -610,10 +610,15 @@ void ResourceHandle::receivedCancellation(const AuthenticationChallenge& challen
// See <rdar://problem/5380697> . This is a workaround for a behavior change in CFNetwork where willSendRequest gets called more often.
if (!redirectResponse)
return newRequest;
-
- LOG(Network, "Handle %p delegate connection:%p willSendRequest:%@ redirectResponse:%p", m_handle, connection, [newRequest description], redirectResponse);
- if (redirectResponse && [redirectResponse isKindOfClass:[NSHTTPURLResponse class]] && [(NSHTTPURLResponse *)redirectResponse statusCode] == 307) {
+#if !LOG_DISABLED
+ if ([redirectResponse isKindOfClass:[NSHTTPURLResponse class]])
+ LOG(Network, "Handle %p delegate connection:%p willSendRequest:%@ redirectResponse:%d, Location:<%@>", m_handle, connection, [newRequest description], static_cast<int>([(id)redirectResponse statusCode]), [[(id)redirectResponse allHeaderFields] objectForKey:@"Location"]);
+ else
+ LOG(Network, "Handle %p delegate connection:%p willSendRequest:%@ redirectResponse:non-HTTP", m_handle, connection, [newRequest description]);
+#endif
+
+ if ([redirectResponse isKindOfClass:[NSHTTPURLResponse class]] && [(NSHTTPURLResponse *)redirectResponse statusCode] == 307) {
String originalMethod = m_handle->request().httpMethod();
if (!equalIgnoringCase(originalMethod, String([newRequest HTTPMethod]))) {
NSMutableURLRequest *mutableRequest = [newRequest mutableCopy];
diff --git a/WebCore/platform/network/qt/NetworkStateNotifierPrivate.h b/WebCore/platform/network/qt/NetworkStateNotifierPrivate.h
new file mode 100644
index 0000000..536b06a
--- /dev/null
+++ b/WebCore/platform/network/qt/NetworkStateNotifierPrivate.h
@@ -0,0 +1,51 @@
+/*
+ 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 NetworkStateNotifierPrivate_h
+#define NetworkStateNotifierPrivate_h
+
+#include <QObject>
+
+namespace QtMobility {
+class QNetworkConfigurationManager;
+}
+
+namespace WebCore {
+
+class NetworkStateNotifier;
+
+class NetworkStateNotifierPrivate : public QObject {
+ Q_OBJECT
+public:
+ NetworkStateNotifierPrivate(NetworkStateNotifier* notifier);
+ ~NetworkStateNotifierPrivate();
+public slots:
+ void onlineStateChanged(bool);
+ void networkAccessPermissionChanged(bool);
+
+public:
+ QtMobility::QNetworkConfigurationManager* m_configurationManager;
+ bool m_online;
+ bool m_networkAccessAllowed;
+ NetworkStateNotifier* m_notifier;
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/WebCore/platform/network/qt/NetworkStateNotifierQt.cpp b/WebCore/platform/network/qt/NetworkStateNotifierQt.cpp
new file mode 100644
index 0000000..e694264
--- /dev/null
+++ b/WebCore/platform/network/qt/NetworkStateNotifierQt.cpp
@@ -0,0 +1,90 @@
+/*
+ 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 "NetworkStateNotifier.h"
+
+#include "NetworkStateNotifierPrivate.h"
+#include "qnetworkconfigmanager.h"
+
+using namespace QtMobility;
+
+namespace WebCore {
+
+NetworkStateNotifierPrivate::NetworkStateNotifierPrivate(NetworkStateNotifier* notifier)
+ : m_configurationManager(new QNetworkConfigurationManager())
+ , m_online(m_configurationManager->isOnline())
+ , m_networkAccessAllowed(true)
+ , m_notifier(notifier)
+{
+ Q_ASSERT(notifier);
+ connect(m_configurationManager, SIGNAL(onlineStateChanged(bool)), this, SLOT(onlineStateChanged(bool)));
+}
+
+void NetworkStateNotifierPrivate::onlineStateChanged(bool isOnline)
+{
+ if (m_online == isOnline)
+ return;
+
+ m_online = isOnline;
+ if (m_networkAccessAllowed)
+ m_notifier->updateState();
+}
+
+void NetworkStateNotifierPrivate::networkAccessPermissionChanged(bool isAllowed)
+{
+ if (isAllowed == m_networkAccessAllowed)
+ return;
+
+ m_networkAccessAllowed = isAllowed;
+ if (m_online)
+ m_notifier->updateState();
+}
+
+NetworkStateNotifierPrivate::~NetworkStateNotifierPrivate()
+{
+ delete m_configurationManager;
+}
+
+void NetworkStateNotifier::updateState()
+{
+ if (m_isOnLine == (p->m_online && p->m_networkAccessAllowed))
+ return;
+
+ m_isOnLine = p->m_online && p->m_networkAccessAllowed;
+ if (m_networkStateChangedFunction)
+ m_networkStateChangedFunction();
+}
+
+NetworkStateNotifier::NetworkStateNotifier()
+ : m_isOnLine(true)
+ , m_networkStateChangedFunction(0)
+{
+ p = new NetworkStateNotifierPrivate(this);
+ m_isOnLine = p->m_online && p->m_networkAccessAllowed;
+}
+
+void NetworkStateNotifier::setNetworkAccessAllowed(bool isAllowed)
+{
+ p->networkAccessPermissionChanged(isAllowed);
+}
+
+} // namespace WebCore
+
+#include "moc_NetworkStateNotifierPrivate.cpp"
diff --git a/WebCore/platform/network/qt/QNetworkReplyHandler.cpp b/WebCore/platform/network/qt/QNetworkReplyHandler.cpp
index f7bbb9d..559ef84 100644
--- a/WebCore/platform/network/qt/QNetworkReplyHandler.cpp
+++ b/WebCore/platform/network/qt/QNetworkReplyHandler.cpp
@@ -38,6 +38,16 @@
#include <QDebug>
#include <QCoreApplication>
+// What type of connection should be used for the signals of the
+// QNetworkReply? This depends on if Qt has a bugfix for this or not.
+// It is fixed in Qt 4.6.1. See https://bugs.webkit.org/show_bug.cgi?id=32113
+#if QT_VERSION > QT_VERSION_CHECK(4, 6, 0)
+#define SIGNAL_CONN Qt::DirectConnection
+#else
+#define SIGNAL_CONN Qt::QueuedConnection
+#endif
+
+
namespace WebCore {
// Take a deep copy of the FormDataElement
@@ -320,6 +330,8 @@ void QNetworkReplyHandler::sendResponseIfNeeded()
QUrl redirection = m_reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
if (redirection.isValid()) {
+ m_redirected = true;
+
QUrl newUrl = m_reply->url().resolved(redirection);
ResourceRequest newRequest = m_resourceHandle->request();
newRequest.setURL(newUrl);
@@ -334,7 +346,9 @@ void QNetworkReplyHandler::sendResponseIfNeeded()
newRequest.clearHTTPReferrer();
client->willSendRequest(m_resourceHandle, newRequest, response);
- m_redirected = true;
+ if (!m_resourceHandle) // network error did cancel the request
+ return;
+
m_request = newRequest.toNetworkRequest(m_resourceHandle->getInternal()->m_frame);
return;
}
@@ -369,6 +383,18 @@ void QNetworkReplyHandler::forwardData()
}
}
+void QNetworkReplyHandler::uploadProgress(qint64 bytesSent, qint64 bytesTotal)
+{
+ if (!m_resourceHandle)
+ return;
+
+ ResourceHandleClient* client = m_resourceHandle->client();
+ if (!client)
+ return;
+
+ client->didSendData(m_resourceHandle, bytesSent, bytesTotal);
+}
+
void QNetworkReplyHandler::start()
{
m_shouldStart = false;
@@ -427,18 +453,25 @@ void QNetworkReplyHandler::start()
m_reply->setParent(this);
connect(m_reply, SIGNAL(finished()),
- this, SLOT(finish()), Qt::QueuedConnection);
+ this, SLOT(finish()), SIGNAL_CONN);
// For http(s) we know that the headers are complete upon metaDataChanged() emission, so we
// can send the response as early as possible
if (scheme == QLatin1String("http") || scheme == QLatin1String("https"))
connect(m_reply, SIGNAL(metaDataChanged()),
- this, SLOT(sendResponseIfNeeded()), Qt::QueuedConnection);
+ this, SLOT(sendResponseIfNeeded()), SIGNAL_CONN);
connect(m_reply, SIGNAL(readyRead()),
- this, SLOT(forwardData()), Qt::QueuedConnection);
+ this, SLOT(forwardData()), SIGNAL_CONN);
+
+ if (m_resourceHandle->request().reportUploadProgress()) {
+ connect(m_reply, SIGNAL(uploadProgress(qint64, qint64)),
+ this, SLOT(uploadProgress(qint64, qint64)), SIGNAL_CONN);
+ }
+
+ // Make this a direct function call once we require 4.6.1+.
connect(this, SIGNAL(processQueuedItems()),
- this, SLOT(sendQueuedItems()), Qt::QueuedConnection);
+ this, SLOT(sendQueuedItems()), SIGNAL_CONN);
}
void QNetworkReplyHandler::resetState()
diff --git a/WebCore/platform/network/qt/QNetworkReplyHandler.h b/WebCore/platform/network/qt/QNetworkReplyHandler.h
index 2171083..eb5ae3c 100644
--- a/WebCore/platform/network/qt/QNetworkReplyHandler.h
+++ b/WebCore/platform/network/qt/QNetworkReplyHandler.h
@@ -62,6 +62,7 @@ private slots:
void sendResponseIfNeeded();
void forwardData();
void sendQueuedItems();
+ void uploadProgress(qint64 bytesSent, qint64 bytesTotal);
private:
void start();
diff --git a/WebCore/platform/network/qt/ResourceRequestQt.cpp b/WebCore/platform/network/qt/ResourceRequestQt.cpp
index 752abfe..341e6ae 100644
--- a/WebCore/platform/network/qt/ResourceRequestQt.cpp
+++ b/WebCore/platform/network/qt/ResourceRequestQt.cpp
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ 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
@@ -27,6 +27,20 @@
namespace WebCore {
+// Currently Qt allows three connections per host on symbian and six
+// for everyone else. The limit can be found in qhttpnetworkconnection.cpp.
+// To achieve the best result we want WebKit to schedule the jobs so we
+// are using the limit as found in Qt. To allow Qt to fill its queue
+// and prepare jobs we will schedule two more downloads.
+unsigned initializeMaximumHTTPConnectionCountPerHost()
+{
+#ifdef Q_OS_SYMBIAN
+ return 3 + 2;
+#else
+ return 6 + 2;
+#endif
+}
+
QNetworkRequest ResourceRequest::toNetworkRequest(QObject* originatingFrame) const
{
QNetworkRequest request;
diff --git a/WebCore/platform/network/qt/SocketStreamHandle.h b/WebCore/platform/network/qt/SocketStreamHandle.h
index 64139e5..5c55749 100644
--- a/WebCore/platform/network/qt/SocketStreamHandle.h
+++ b/WebCore/platform/network/qt/SocketStreamHandle.h
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2010 Nokia Inc. All rights reserved.
* Copyright (C) 2009 Apple Inc. All rights reserved.
* Copyright (C) 2009 Google Inc. All rights reserved.
*
@@ -42,6 +43,7 @@ namespace WebCore {
class AuthenticationChallenge;
class Credential;
class SocketStreamHandleClient;
+ class SocketStreamHandlePrivate;
class SocketStreamHandle : public RefCounted<SocketStreamHandle>, public SocketStreamHandleBase {
public:
@@ -61,6 +63,8 @@ namespace WebCore {
void receivedCredential(const AuthenticationChallenge&, const Credential&);
void receivedRequestToContinueWithoutCredential(const AuthenticationChallenge&);
void receivedCancellation(const AuthenticationChallenge&);
+ SocketStreamHandlePrivate* m_p;
+ friend class SocketStreamHandlePrivate;
};
} // namespace WebCore
diff --git a/WebCore/platform/network/qt/SocketStreamHandleSoup.cpp b/WebCore/platform/network/qt/SocketStreamHandlePrivate.h
index 6aa33fc..9433d3f 100644
--- a/WebCore/platform/network/qt/SocketStreamHandleSoup.cpp
+++ b/WebCore/platform/network/qt/SocketStreamHandlePrivate.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2010 Nokia Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -28,61 +28,43 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "config.h"
-#include "SocketStreamHandle.h"
+#ifndef SocketStreamHandlePrivate_h
+#define SocketStreamHandlePrivate_h
-#include "KURL.h"
-#include "Logging.h"
-#include "NotImplemented.h"
-#include "SocketStreamHandleClient.h"
+#include "SocketStreamHandleBase.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;
-}
+#include <QSslSocket>
+#include <QTcpSocket>
-void SocketStreamHandle::platformClose()
-{
- LOG(Network, "SocketStreamHandle %p platformClose", this);
- notImplemented();
-}
+namespace WebCore {
-void SocketStreamHandle::didReceiveAuthenticationChallenge(const AuthenticationChallenge&)
-{
- notImplemented();
-}
+class AuthenticationChallenge;
+class Credential;
+class SocketStreamHandleClient;
+class SocketStreamHandlePrivate;
-void SocketStreamHandle::receivedCredential(const AuthenticationChallenge&, const Credential&)
-{
- notImplemented();
-}
+class SocketStreamHandlePrivate : public QObject {
+ Q_OBJECT
+public:
+ SocketStreamHandlePrivate(SocketStreamHandle*, const KURL&);
+ ~SocketStreamHandlePrivate();
-void SocketStreamHandle::receivedRequestToContinueWithoutCredential(const AuthenticationChallenge&)
-{
- notImplemented();
-}
+public slots:
+ void socketConnected();
+ void socketReadyRead();
+ int send(const char* data, int len);
+ void close();
+ void socketSentdata();
+ void socketClosed();
+ void socketError(QAbstractSocket::SocketError);
+ void socketClosedCallback();
+ void socketErrorCallback(int);
+ void socketSslErrors(const QList<QSslError>&);
+public:
+ QTcpSocket* m_socket;
+ SocketStreamHandle* m_streamHandle;
+};
-void SocketStreamHandle::receivedCancellation(const AuthenticationChallenge&)
-{
- notImplemented();
}
-} // namespace WebCore
+#endif
diff --git a/WebCore/platform/network/qt/SocketStreamHandleQt.cpp b/WebCore/platform/network/qt/SocketStreamHandleQt.cpp
new file mode 100644
index 0000000..d61d901
--- /dev/null
+++ b/WebCore/platform/network/qt/SocketStreamHandleQt.cpp
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2010 Nokia 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.
+ */
+
+#include "config.h"
+#include "SocketStreamHandle.h"
+
+#include "KURL.h"
+#include "Logging.h"
+#include "NotImplemented.h"
+#include "SocketStreamHandleClient.h"
+#include "SocketStreamHandlePrivate.h"
+
+namespace WebCore {
+
+SocketStreamHandlePrivate::SocketStreamHandlePrivate(SocketStreamHandle* streamHandle, const KURL& url) : QObject()
+{
+ m_streamHandle = streamHandle;
+ m_socket = 0;
+ bool isSecure = url.protocolIs("wss");
+ if (isSecure)
+ m_socket = new QSslSocket(this);
+ else
+ m_socket = new QTcpSocket(this);
+ connect(m_socket, SIGNAL(connected()), this, SLOT(socketConnected()));
+ connect(m_socket, SIGNAL(readyRead()), this, SLOT(socketReadyRead()));
+ connect(m_socket, SIGNAL(disconnected()), this, SLOT(socketClosed()));
+ connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError)));
+ if (isSecure)
+ connect(m_socket, SIGNAL(sslErrors(const QList<QSslError>&)), this, SLOT(socketSslErrors(const QList<QSslError>&)));
+
+ unsigned int port = url.hasPort() ? url.port() : (isSecure ? 443 : 80);
+
+ QString host = url.host();
+ if (isSecure)
+ static_cast<QSslSocket*>(m_socket)->connectToHostEncrypted(host, port);
+ else
+ m_socket->connectToHost(host, port);
+}
+
+SocketStreamHandlePrivate::~SocketStreamHandlePrivate()
+{
+ Q_ASSERT(!(m_socket && m_socket->state() == QAbstractSocket::ConnectedState));
+}
+
+void SocketStreamHandlePrivate::socketConnected()
+{
+ if (m_streamHandle && m_streamHandle->client()) {
+ m_streamHandle->m_state = SocketStreamHandleBase::Open;
+ m_streamHandle->client()->didOpen(m_streamHandle);
+ }
+}
+
+void SocketStreamHandlePrivate::socketReadyRead()
+{
+ if (m_streamHandle && m_streamHandle->client()) {
+ QByteArray data = m_socket->read(m_socket->bytesAvailable());
+ m_streamHandle->client()->didReceiveData(m_streamHandle, data.constData(), data.size());
+ }
+}
+
+int SocketStreamHandlePrivate::send(const char* data, int len)
+{
+ if (m_socket->state() != QAbstractSocket::ConnectedState)
+ return 0;
+ quint64 sentSize = m_socket->write(data, len);
+ QMetaObject::invokeMethod(this, "socketSentData", Qt::QueuedConnection);
+ return sentSize;
+}
+
+void SocketStreamHandlePrivate::close()
+{
+ if (m_socket && m_socket->state() == QAbstractSocket::ConnectedState)
+ m_socket->close();
+}
+
+void SocketStreamHandlePrivate::socketSentdata()
+{
+ if (m_streamHandle)
+ m_streamHandle->sendPendingData();
+}
+
+void SocketStreamHandlePrivate::socketClosed()
+{
+ QMetaObject::invokeMethod(this, "socketClosedCallback", Qt::QueuedConnection);
+}
+
+void SocketStreamHandlePrivate::socketError(QAbstractSocket::SocketError error)
+{
+ QMetaObject::invokeMethod(this, "socketErrorCallback", Qt::QueuedConnection, Q_ARG(int, error));
+}
+
+void SocketStreamHandlePrivate::socketClosedCallback()
+{
+ if (m_streamHandle && m_streamHandle->client()) {
+ SocketStreamHandle* streamHandle = m_streamHandle;
+ m_streamHandle = 0;
+ // This following call deletes _this_. Nothing should be after it.
+ streamHandle->client()->didClose(streamHandle);
+ }
+}
+
+void SocketStreamHandlePrivate::socketErrorCallback(int error)
+{
+ // FIXME - in the future, we might not want to treat all errors as fatal.
+ if (m_streamHandle && m_streamHandle->client()) {
+ SocketStreamHandle* streamHandle = m_streamHandle;
+ m_streamHandle = 0;
+ // This following call deletes _this_. Nothing should be after it.
+ streamHandle->client()->didClose(streamHandle);
+ }
+}
+
+void SocketStreamHandlePrivate::socketSslErrors(const QList<QSslError>&)
+{
+ // FIXME: based on http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-68#page-15
+ // we should abort on certificate errors.
+ // We don't abort while this is still work in progress.
+ static_cast<QSslSocket*>(m_socket)->ignoreSslErrors();
+}
+SocketStreamHandle::SocketStreamHandle(const KURL& url, SocketStreamHandleClient* client)
+ : SocketStreamHandleBase(url, client)
+{
+ LOG(Network, "SocketStreamHandle %p new client %p", this, m_client);
+ m_p = new SocketStreamHandlePrivate(this, url);
+}
+
+SocketStreamHandle::~SocketStreamHandle()
+{
+ LOG(Network, "SocketStreamHandle %p delete", this);
+ setClient(0);
+ delete m_p;
+}
+
+int SocketStreamHandle::platformSend(const char* data, int len)
+{
+ LOG(Network, "SocketStreamHandle %p platformSend", this);
+ return m_p->send(data, len);
+}
+
+void SocketStreamHandle::platformClose()
+{
+ LOG(Network, "SocketStreamHandle %p platformClose", this);
+ m_p->close();
+}
+
+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
+
+#include "moc_SocketStreamHandlePrivate.cpp"
diff --git a/WebCore/platform/network/soup/ResourceHandleSoup.cpp b/WebCore/platform/network/soup/ResourceHandleSoup.cpp
index 6367a3e..da16f4a 100644
--- a/WebCore/platform/network/soup/ResourceHandleSoup.cpp
+++ b/WebCore/platform/network/soup/ResourceHandleSoup.cpp
@@ -548,12 +548,6 @@ static bool startHttp(ResourceHandle* handle)
// balanced by a deref() in finishedCallback, which should always run
handle->ref();
- // FIXME: For now, we cannot accept content encoded in anything
- // other than identity, so force servers to do it our way. When
- // libsoup gets proper Content-Encoding support we will want to
- // use it here instead.
- soup_message_headers_replace(d->m_msg->request_headers, "Accept-Encoding", "identity");
-
// Balanced in ResourceHandleInternal's destructor; we need to
// keep our own ref, because after queueing the message, the
// session owns the initial reference.
@@ -882,7 +876,7 @@ static bool startGio(ResourceHandle* handle, KURL url)
url.setQuery(String());
url.removePort();
-#if !PLATFORM(WIN_OS)
+#if !OS(WINDOWS)
// we avoid the escaping for local files, because
// g_filename_from_uri (used internally by GFile) has problems
// decoding strings with arbitrary percent signs
diff --git a/WebCore/platform/qt/DragDataQt.cpp b/WebCore/platform/qt/DragDataQt.cpp
index b0611e6..09a797f 100644
--- a/WebCore/platform/qt/DragDataQt.cpp
+++ b/WebCore/platform/qt/DragDataQt.cpp
@@ -134,7 +134,7 @@ String DragData::asURL(String*) const
PassRefPtr<DocumentFragment> DragData::asFragment(Document* doc) const
{
if (m_platformDragData && m_platformDragData->hasHtml())
- return createFragmentFromMarkup(doc, m_platformDragData->html(), "");
+ return createFragmentFromMarkup(doc, m_platformDragData->html(), "", FragmentScriptingNotAllowed);
return 0;
}
diff --git a/WebCore/platform/qt/KURLQt.cpp b/WebCore/platform/qt/KURLQt.cpp
index 0763fe0..3bb3db2 100644
--- a/WebCore/platform/qt/KURLQt.cpp
+++ b/WebCore/platform/qt/KURLQt.cpp
@@ -86,7 +86,8 @@ KURL::operator QUrl() const
#else
// Qt 4.5 or later
// No need for special encoding
- QByteArray ba = m_string.utf8().data();
+ QString str = QString::fromRawData(reinterpret_cast<const QChar*>(m_string.characters()), m_string.length());
+ QByteArray ba = str.toUtf8();
#endif
QUrl url = QUrl::fromEncoded(ba);
@@ -95,8 +96,10 @@ KURL::operator QUrl() const
String KURL::fileSystemPath() const
{
- notImplemented();
- return String();
+ if (!isValid() || !protocolIs("file"))
+ return String();
+
+ return String(path());
}
}
diff --git a/WebCore/platform/qt/Localizations.cpp b/WebCore/platform/qt/Localizations.cpp
index 1768502..c919193 100644
--- a/WebCore/platform/qt/Localizations.cpp
+++ b/WebCore/platform/qt/Localizations.cpp
@@ -32,6 +32,7 @@
#include "LocalizedStrings.h"
#include "NotImplemented.h"
#include "PlatformString.h"
+#include <wtf/MathExtras.h>
#include <QCoreApplication>
#include <QLocale>
@@ -340,6 +341,16 @@ String AXLinkActionVerb()
return String();
}
+String AXMenuListPopupActionVerb()
+{
+ return String();
+}
+
+String AXMenuListActionVerb()
+{
+ return String();
+}
+
String multipleFileUploadText(unsigned)
{
return String();
diff --git a/WebCore/platform/qt/PasteboardQt.cpp b/WebCore/platform/qt/PasteboardQt.cpp
index 209a573..44c9eec 100644
--- a/WebCore/platform/qt/PasteboardQt.cpp
+++ b/WebCore/platform/qt/PasteboardQt.cpp
@@ -103,7 +103,7 @@ PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefP
if (mimeData->hasHtml()) {
QString html = mimeData->html();
if (!html.isEmpty()) {
- RefPtr<DocumentFragment> fragment = createFragmentFromMarkup(frame->document(), html, "");
+ RefPtr<DocumentFragment> fragment = createFragmentFromMarkup(frame->document(), html, "", FragmentScriptingNotAllowed);
if (fragment)
return fragment.release();
}
diff --git a/WebCore/platform/qt/PlatformKeyboardEventQt.cpp b/WebCore/platform/qt/PlatformKeyboardEventQt.cpp
index f78c7d7..12200f4 100644
--- a/WebCore/platform/qt/PlatformKeyboardEventQt.cpp
+++ b/WebCore/platform/qt/PlatformKeyboardEventQt.cpp
@@ -171,6 +171,22 @@ static int windowsKeyCodeForKeyEvent(unsigned int keycode, bool isKeypad = false
return VK_DECIMAL; // (6E) Decimal key
case Qt::Key_Slash:
return VK_DIVIDE; // (6F) Divide key
+ case Qt::Key_PageUp:
+ return VK_PRIOR; // (21) PAGE UP key
+ case Qt::Key_PageDown:
+ return VK_NEXT; // (22) PAGE DOWN key
+ case Qt::Key_End:
+ return VK_END; // (23) END key
+ case Qt::Key_Home:
+ return VK_HOME; // (24) HOME key
+ case Qt::Key_Left:
+ return VK_LEFT; // (25) LEFT ARROW key
+ case Qt::Key_Up:
+ return VK_UP; // (26) UP ARROW key
+ case Qt::Key_Right:
+ return VK_RIGHT; // (27) RIGHT ARROW key
+ case Qt::Key_Down:
+ return VK_DOWN; // (28) DOWN ARROW key
default:
return 0;
}
diff --git a/WebCore/platform/qt/PlatformTouchEventQt.cpp b/WebCore/platform/qt/PlatformTouchEventQt.cpp
new file mode 100644
index 0000000..338e9d4
--- /dev/null
+++ b/WebCore/platform/qt/PlatformTouchEventQt.cpp
@@ -0,0 +1,49 @@
+/*
+ * This file is part of the WebKit project.
+ *
+ * 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 "PlatformTouchEvent.h"
+
+#if ENABLE(TOUCH_EVENTS)
+
+namespace WebCore {
+
+PlatformTouchEvent::PlatformTouchEvent(QTouchEvent* event)
+{
+ switch (event->type()) {
+ case QEvent::TouchBegin: m_type = TouchStart; break;
+ case QEvent::TouchUpdate: m_type = TouchMove; break;
+ case QEvent::TouchEnd: m_type = TouchEnd; break;
+ }
+ const QList<QTouchEvent::TouchPoint>& points = event->touchPoints();
+ for (int i = 0; i < points.count(); ++i)
+ m_touchPoints.append(PlatformTouchPoint(points.at(i)));
+
+ m_ctrlKey = (event->modifiers() & Qt::ControlModifier);
+ m_altKey = (event->modifiers() & Qt::AltModifier);
+ m_shiftKey = (event->modifiers() & Qt::ShiftModifier);
+ m_metaKey = (event->modifiers() & Qt::MetaModifier);
+}
+
+}
+
+#endif
diff --git a/WebCore/platform/qt/QWebPopup.h b/WebCore/platform/qt/PlatformTouchPointQt.cpp
index 36d6781..1788cef 100644
--- a/WebCore/platform/qt/QWebPopup.h
+++ b/WebCore/platform/qt/PlatformTouchPointQt.cpp
@@ -1,6 +1,7 @@
/*
+ * This file is part of the WebKit project.
*
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ * 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
@@ -18,31 +19,26 @@
* Boston, MA 02110-1301, USA.
*
*/
-#ifndef QWebPopup_h
-#define QWebPopup_h
-#include <QComboBox>
+#include "config.h"
+#include "PlatformTouchPoint.h"
-#include "PopupMenuClient.h"
+#if ENABLE(TOUCH_EVENTS)
namespace WebCore {
-class QWebPopup : public QComboBox {
- Q_OBJECT
-public:
- QWebPopup(PopupMenuClient* client);
-
- void exec();
-
- virtual void showPopup();
- virtual void hidePopup();
-
-private slots:
- void activeChanged(int);
-private:
- PopupMenuClient* m_client;
- bool m_popupVisible;
-};
+PlatformTouchPoint::PlatformTouchPoint(const QTouchEvent::TouchPoint& point)
+{
+ m_id = point.id();
+ switch (point.state()) {
+ case Qt::TouchPointReleased: m_state = TouchReleased; break;
+ case Qt::TouchPointMoved: m_state = TouchMoved; break;
+ case Qt::TouchPointPressed: m_state = TouchPressed; break;
+ case Qt::TouchPointStationary: m_state = TouchStationary; break;
+ }
+ m_screenPos = point.screenPos().toPoint();
+ m_pos = point.pos().toPoint();
+}
}
diff --git a/WebCore/platform/qt/PopupMenuQt.cpp b/WebCore/platform/qt/PopupMenuQt.cpp
index f6ec4f7..315b891 100644
--- a/WebCore/platform/qt/PopupMenuQt.cpp
+++ b/WebCore/platform/qt/PopupMenuQt.cpp
@@ -1,7 +1,7 @@
/*
* This file is part of the popup menu implementation for <select> elements in WebCore.
*
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2008, 2009, 2010 Nokia Corporation and/or its subsidiary(-ies)
* Copyright (C) 2006 Apple Computer, Inc.
* Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com
* Coypright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
@@ -26,28 +26,19 @@
#include "config.h"
#include "PopupMenu.h"
-#include "Frame.h"
+#include "Chrome.h"
+#include "ChromeClientQt.h"
#include "FrameView.h"
-#include "HostWindow.h"
#include "PopupMenuClient.h"
#include "QWebPageClient.h"
-#include "QWebPopup.h"
-
-#include <QAction>
-#include <QDebug>
-#include <QListWidget>
-#include <QListWidgetItem>
-#include <QMenu>
-#include <QPoint>
-#include <QStandardItemModel>
-#include <QWidgetAction>
+#include "QtAbstractWebPopup.h"
namespace WebCore {
PopupMenu::PopupMenu(PopupMenuClient* client)
: m_popupClient(client)
+ , m_popup(0)
{
- m_popup = new QWebPopup(client);
}
PopupMenu::~PopupMenu()
@@ -55,52 +46,30 @@ PopupMenu::~PopupMenu()
delete m_popup;
}
-void PopupMenu::clear()
+void PopupMenu::show(const IntRect& rect, FrameView* view, int index)
{
- m_popup->clear();
-}
+ ChromeClientQt* chromeClient = static_cast<ChromeClientQt*>(
+ view->frame()->page()->chrome()->client());
+ ASSERT(chromeClient);
-void PopupMenu::populate(const IntRect&)
-{
- clear();
- Q_ASSERT(client());
-
- QStandardItemModel* model = qobject_cast<QStandardItemModel*>(m_popup->model());
- Q_ASSERT(model);
-
- int size = client()->listSize();
- for (int i = 0; i < size; i++) {
- if (client()->itemIsSeparator(i))
- m_popup->insertSeparator(i);
- else {
- m_popup->insertItem(i, client()->itemText(i));
-
- if (model && !client()->itemIsEnabled(i))
- model->item(i)->setEnabled(false);
-
- if (client()->itemIsSelected(i))
- m_popup->setCurrentIndex(i);
- }
- }
-}
+ if (!m_popup)
+ m_popup = chromeClient->createSelectPopup();
+
+ m_popup->m_popupClient = m_popupClient;
+ m_popup->m_currentIndex = index;
+ m_popup->m_pageClient = chromeClient->platformPageClient();
+
+ QRect geometry(rect);
+ geometry.moveTopLeft(view->contentsToWindow(rect.topLeft()));
+ m_popup->m_geometry = geometry;
+
+ m_popup->show();
-void PopupMenu::show(const IntRect& r, FrameView* v, int index)
-{
- 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(client->ownerWidget());
- m_popup->setGeometry(rect);
- m_popup->setCurrentIndex(index);
- m_popup->exec();
}
void PopupMenu::hide()
{
- m_popup->hidePopup();
+ m_popup->hide();
}
void PopupMenu::updateFromElement()
diff --git a/WebCore/platform/qt/QWebPageClient.h b/WebCore/platform/qt/QWebPageClient.h
index b510736..6d47c29 100644
--- a/WebCore/platform/qt/QWebPageClient.h
+++ b/WebCore/platform/qt/QWebPageClient.h
@@ -29,8 +29,14 @@
#ifndef QT_NO_CURSOR
#include <QCursor>
#endif
+
#include <QRect>
+QT_BEGIN_NAMESPACE
+class QGraphicsItem;
+class QStyle;
+QT_END_NAMESPACE
+
class QWebPageClient {
public:
virtual ~QWebPageClient() { }
@@ -39,6 +45,16 @@ public:
virtual void update(const QRect&) = 0;
virtual void setInputMethodEnabled(bool enable) = 0;
virtual bool inputMethodEnabled() const = 0;
+#if USE(ACCELERATED_COMPOSITING)
+ // this gets called when we start/stop compositing.
+ virtual void setRootGraphicsLayer(QGraphicsItem* layer) {}
+
+ // this gets called when the compositor wants us to sync the layers
+ // if scheduleSync is true, we schedule a sync ourselves. otherwise,
+ // we wait for the next update and sync the layers then.
+ virtual void markForSync(bool scheduleSync = false) {}
+#endif
+
#if QT_VERSION >= 0x040600
virtual void setInputMethodHint(Qt::InputMethodHint hint, bool enable) = 0;
#endif
@@ -67,6 +83,8 @@ public:
virtual QObject* pluginParent() const = 0;
+ virtual QStyle* style() const = 0;
+
protected:
#ifndef QT_NO_CURSOR
virtual QCursor cursor() const = 0;
diff --git a/WebCore/platform/qt/QWebPopup.cpp b/WebCore/platform/qt/QWebPopup.cpp
deleted file mode 100644
index d077079..0000000
--- a/WebCore/platform/qt/QWebPopup.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- *
- * Copyright (C) 2008 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 "QWebPopup.h"
-#include "PopupMenuStyle.h"
-
-#include <QAbstractItemView>
-#include <QApplication>
-#include <QInputContext>
-#include <QMouseEvent>
-
-namespace WebCore {
-
-QWebPopup::QWebPopup(PopupMenuClient* client)
- : m_client(client)
- , m_popupVisible(false)
-{
- Q_ASSERT(m_client);
-
- setFont(m_client->menuStyle().font().font());
- connect(this, SIGNAL(activated(int)),
- SLOT(activeChanged(int)), Qt::QueuedConnection);
-}
-
-
-void QWebPopup::exec()
-{
- QMouseEvent event(QEvent::MouseButtonPress, QCursor::pos(), Qt::LeftButton,
- Qt::LeftButton, Qt::NoModifier);
- QCoreApplication::sendEvent(this, &event);
-}
-
-void QWebPopup::showPopup()
-{
- QComboBox::showPopup();
- m_popupVisible = true;
-}
-
-void QWebPopup::hidePopup()
-{
- QWidget* activeFocus = QApplication::focusWidget();
- if (activeFocus && activeFocus == view()
- && activeFocus->testAttribute(Qt::WA_InputMethodEnabled)) {
- QInputContext* qic = activeFocus->inputContext();
- if (qic) {
- qic->reset();
- qic->setFocusWidget(0);
- }
- }
-
- QComboBox::hidePopup();
- if (!m_popupVisible)
- return;
-
- m_popupVisible = false;
- m_client->popupDidHide();
-}
-
-void QWebPopup::activeChanged(int index)
-{
- if (index < 0)
- return;
-
- m_client->valueChanged(index);
-}
-
-} // namespace WebCore
-
-#include "moc_QWebPopup.cpp"
diff --git a/WebCore/platform/qt/QtAbstractWebPopup.cpp b/WebCore/platform/qt/QtAbstractWebPopup.cpp
new file mode 100644
index 0000000..f64287d
--- /dev/null
+++ b/WebCore/platform/qt/QtAbstractWebPopup.cpp
@@ -0,0 +1,60 @@
+/*
+ * 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 "QtAbstractWebPopup.h"
+
+#include "PopupMenuClient.h"
+
+
+namespace WebCore {
+
+QtAbstractWebPopup::QtAbstractWebPopup()
+ : m_popupClient(0)
+ , m_pageClient(0)
+ , m_currentIndex(-1)
+{
+}
+
+QtAbstractWebPopup::~QtAbstractWebPopup()
+{
+}
+
+void QtAbstractWebPopup::popupDidHide()
+{
+ Q_ASSERT(m_popupClient);
+ m_popupClient->popupDidHide();
+}
+
+void QtAbstractWebPopup::valueChanged(int index)
+{
+ Q_ASSERT(m_popupClient);
+ m_popupClient->valueChanged(index);
+}
+
+QtAbstractWebPopup::ItemType QtAbstractWebPopup::itemType(int idx) const
+{
+ if (m_popupClient->itemIsSeparator(idx))
+ return Separator;
+ if (m_popupClient->itemIsLabel(idx))
+ return Group;
+ return Option;
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/qt/QtAbstractWebPopup.h b/WebCore/platform/qt/QtAbstractWebPopup.h
new file mode 100644
index 0000000..93b4122
--- /dev/null
+++ b/WebCore/platform/qt/QtAbstractWebPopup.h
@@ -0,0 +1,69 @@
+/*
+ * 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 QtAbstractWebPopup_h
+#define QtAbstractWebPopup_h
+
+#include "PopupMenuClient.h"
+
+#include <QFont>
+#include <QList>
+#include <QRect>
+#include <QWidget>
+
+class QWebPageClient;
+
+namespace WebCore {
+
+class QtAbstractWebPopup {
+public:
+ enum ItemType { Option, Group, Separator };
+
+ ItemType itemType(int) const;
+ QString itemText(int idx) const { return m_popupClient->itemText(idx); }
+ QString itemToolTip(int idx) const { return m_popupClient->itemToolTip(idx); }
+ bool itemIsEnabled(int idx) const { return m_popupClient->itemIsEnabled(idx); }
+ int itemCount() const { return m_popupClient->listSize(); }
+
+ QWebPageClient* pageClient() const { return m_pageClient; }
+ QRect geometry() const { return m_geometry; }
+ int currentIndex() const { return m_currentIndex; }
+
+ QtAbstractWebPopup();
+ virtual ~QtAbstractWebPopup();
+
+ virtual void show() = 0;
+ virtual void hide() = 0;
+
+ void popupDidHide();
+ void valueChanged(int index);
+
+ QFont font() { return m_popupClient->menuStyle().font().font(); }
+
+private:
+ friend class PopupMenu;
+ PopupMenuClient* m_popupClient;
+ QWebPageClient* m_pageClient;
+ int m_currentIndex;
+ QRect m_geometry;
+};
+
+}
+
+#endif // QtAbstractWebPopup_h
diff --git a/WebCore/platform/qt/RenderThemeQt.cpp b/WebCore/platform/qt/RenderThemeQt.cpp
index 501a28b..83e3746 100644
--- a/WebCore/platform/qt/RenderThemeQt.cpp
+++ b/WebCore/platform/qt/RenderThemeQt.cpp
@@ -32,6 +32,7 @@
#include "CSSStyleSelector.h"
#include "CSSStyleSheet.h"
+#include "Chrome.h"
#include "ChromeClientQt.h"
#include "Color.h"
#include "Document.h"
@@ -42,10 +43,12 @@
#include "HTMLNames.h"
#include "NotImplemented.h"
#include "Page.h"
+#include "QWebPageClient.h"
#include "RenderBox.h"
+#include "RenderSlider.h"
#include "RenderTheme.h"
+#include "ScrollbarThemeQt.h"
#include "UserAgentStyleSheets.h"
-#include "QWebPageClient.h"
#include "qwebpage.h"
#include <QApplication>
@@ -58,6 +61,7 @@
#include <QStyleFactory>
#include <QStyleOptionButton>
#include <QStyleOptionFrameV2>
+#include <QStyleOptionSlider>
#include <QWidget>
@@ -66,17 +70,17 @@ namespace WebCore {
using namespace HTMLNames;
-StylePainter::StylePainter(const RenderObject::PaintInfo& paintInfo)
+StylePainter::StylePainter(RenderThemeQt* theme, const RenderObject::PaintInfo& paintInfo)
{
- init(paintInfo.context ? paintInfo.context : 0);
+ init(paintInfo.context ? paintInfo.context : 0, theme->qStyle());
}
-StylePainter::StylePainter(GraphicsContext* context)
+StylePainter::StylePainter(ScrollbarThemeQt* theme, GraphicsContext* context)
{
- init(context);
+ init(context, theme->style());
}
-void StylePainter::init(GraphicsContext* context)
+void StylePainter::init(GraphicsContext* context, QStyle* themeStyle)
{
painter = static_cast<QPainter*>(context->platformContext());
widget = 0;
@@ -85,7 +89,7 @@ void StylePainter::init(GraphicsContext* context)
dev = painter->device();
if (dev && dev->devType() == QInternal::Widget)
widget = static_cast<QWidget*>(dev);
- style = (widget ? widget->style() : QApplication::style());
+ style = themeStyle;
if (painter) {
// the styles often assume being called with a pristine painter where no brush is set,
@@ -157,13 +161,10 @@ QStyle* RenderThemeQt::fallbackStyle()
QStyle* RenderThemeQt::qStyle() const
{
if (m_page) {
- ChromeClientQt* client = static_cast<ChromeClientQt*>(m_page->chrome()->client());
-
- if (!client->m_webPage)
- return QApplication::style();
+ QWebPageClient* pageClient = m_page->chrome()->client()->platformPageClient();
- if (QWidget* view = client->m_webPage->view())
- return view->style();
+ if (pageClient)
+ return pageClient->style();
}
return QApplication::style();
@@ -394,8 +395,13 @@ void RenderThemeQt::adjustButtonStyle(CSSStyleSelector* selector, RenderStyle* s
// Ditch the border.
style->resetBorder();
- // Height is locked to auto.
- style->setHeight(Length(Auto));
+#ifdef Q_WS_MAC
+ if (style->appearance() == PushButtonPart) {
+ // The Mac ports ignore the specified height for <input type="button"> elements
+ // unless a border and/or background CSS property is also specified.
+ style->setHeight(Length(Auto));
+ }
+#endif
// White-space is locked to pre
style->setWhiteSpace(PRE);
@@ -465,7 +471,7 @@ void RenderThemeQt::setButtonPadding(RenderStyle* style) const
bool RenderThemeQt::paintButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
{
- StylePainter p(i);
+ StylePainter p(this, i);
if (!p.isValid())
return true;
@@ -476,7 +482,7 @@ bool RenderThemeQt::paintButton(RenderObject* o, const RenderObject::PaintInfo&
option.rect = r;
option.state |= QStyle::State_Small;
- ControlPart appearance = applyTheme(option, o);
+ ControlPart appearance = initializeCommonQStyleOptions(option, o);
if (appearance == PushButtonPart || appearance == ButtonPart) {
option.rect = inflateButtonRect(option.rect, qStyle());
p.drawControl(QStyle::CE_PushButton, option);
@@ -498,7 +504,7 @@ void RenderThemeQt::adjustTextFieldStyle(CSSStyleSelector*, RenderStyle* style,
bool RenderThemeQt::paintTextField(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
{
- StylePainter p(i);
+ StylePainter p(this, i);
if (!p.isValid())
return true;
@@ -512,7 +518,7 @@ bool RenderThemeQt::paintTextField(RenderObject* o, const RenderObject::PaintInf
panel.features = QStyleOptionFrameV2::None;
// Get the correct theme data for a text field
- ControlPart appearance = applyTheme(panel, o);
+ ControlPart appearance = initializeCommonQStyleOptions(panel, o);
if (appearance != TextFieldPart
&& appearance != SearchFieldPart
&& appearance != TextAreaPart
@@ -567,14 +573,14 @@ void RenderThemeQt::setPopupPadding(RenderStyle* style) const
bool RenderThemeQt::paintMenuList(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
{
- StylePainter p(i);
+ StylePainter p(this, i);
if (!p.isValid())
return true;
QStyleOptionComboBox opt;
if (p.widget)
opt.initFrom(p.widget);
- applyTheme(opt, o);
+ initializeCommonQStyleOptions(opt, o);
const QPoint topLeft = r.topLeft();
p.painter->translate(topLeft);
@@ -607,14 +613,14 @@ void RenderThemeQt::adjustMenuListButtonStyle(CSSStyleSelector*, RenderStyle* st
bool RenderThemeQt::paintMenuListButton(RenderObject* o, const RenderObject::PaintInfo& i,
const IntRect& r)
{
- StylePainter p(i);
+ StylePainter p(this, i);
if (!p.isValid())
return true;
QStyleOptionComboBox option;
if (p.widget)
option.initFrom(p.widget);
- applyTheme(option, o);
+ initializeCommonQStyleOptions(option, o);
option.rect = r;
// for drawing the combo box arrow, rely only on the fallback style
@@ -628,22 +634,73 @@ bool RenderThemeQt::paintMenuListButton(RenderObject* o, const RenderObject::Pai
bool RenderThemeQt::paintSliderTrack(RenderObject* o, const RenderObject::PaintInfo& pi,
const IntRect& r)
{
- notImplemented();
- return RenderTheme::paintSliderTrack(o, pi, r);
+ StylePainter p(this, pi);
+ if (!p.isValid())
+ return true;
+
+ QStyleOptionSlider option;
+ if (p.widget)
+ option.initFrom(p.widget);
+ ControlPart appearance = initializeCommonQStyleOptions(option, o);
+
+ RenderSlider* renderSlider = toRenderSlider(o);
+ IntRect thumbRect = renderSlider->thumbRect();
+
+ option.rect = r;
+
+ int value;
+ if (appearance == SliderVerticalPart) {
+ option.maximum = r.height() - thumbRect.height();
+ value = thumbRect.y();
+ } else {
+ option.maximum = r.width() - thumbRect.width();
+ value = thumbRect.x();
+ }
+
+ value = QStyle::sliderValueFromPosition(0, option.maximum, value, option.maximum);
+
+ option.sliderValue = value;
+ option.sliderPosition = value;
+ if (appearance == SliderVerticalPart)
+ option.orientation = Qt::Vertical;
+
+ if (renderSlider->inDragMode()) {
+ option.activeSubControls = QStyle::SC_SliderHandle;
+ option.state |= QStyle::State_Sunken;
+ }
+
+ const QPoint topLeft = r.topLeft();
+ p.painter->translate(topLeft);
+ option.rect.moveTo(QPoint(0, 0));
+ option.rect.setSize(r.size());
+
+ p.drawComplexControl(QStyle::CC_Slider, option);
+ p.painter->translate(-topLeft);
+
+ return false;
+}
+
+void RenderThemeQt::adjustSliderTrackStyle(CSSStyleSelector*, RenderStyle* style, Element*) const
+{
+ style->setBoxShadow(0);
}
bool RenderThemeQt::paintSliderThumb(RenderObject* o, const RenderObject::PaintInfo& pi,
const IntRect& r)
{
- notImplemented();
- return RenderTheme::paintSliderThumb(o, pi, r);
+ // We've already painted it in paintSliderTrack(), no need to do anything here.
+ return false;
+}
+
+void RenderThemeQt::adjustSliderThumbStyle(CSSStyleSelector*, RenderStyle* style, Element*) const
+{
+ style->setBoxShadow(0);
}
bool RenderThemeQt::paintSearchField(RenderObject* o, const RenderObject::PaintInfo& pi,
const IntRect& r)
{
- paintTextField(o, pi, r);
- return false;
+ return true;
}
void RenderThemeQt::adjustSearchFieldStyle(CSSStyleSelector* selector, RenderStyle* style,
@@ -706,13 +763,32 @@ bool RenderThemeQt::supportsFocus(ControlPart appearance) const
case MenulistPart:
case RadioPart:
case CheckboxPart:
+ case SliderHorizontalPart:
+ case SliderVerticalPart:
return true;
default: // No for all others...
return false;
}
}
-ControlPart RenderThemeQt::applyTheme(QStyleOption& option, RenderObject* o) const
+void RenderThemeQt::setPaletteFromPageClientIfExists(QPalette& palette) const
+{
+ // If the webview has a custom palette, use it
+ if (!m_page)
+ return;
+ Chrome* chrome = m_page->chrome();
+ if (!chrome)
+ return;
+ ChromeClient* chromeClient = chrome->client();
+ if (!chromeClient)
+ return;
+ QWebPageClient* pageClient = chromeClient->platformPageClient();
+ if (!pageClient)
+ return;
+ palette = pageClient->palette();
+}
+
+ControlPart RenderThemeQt::initializeCommonQStyleOptions(QStyleOption& option, RenderObject* o) const
{
// Default bits: no focus, no mouse over
option.state &= ~(QStyle::State_HasFocus | QStyle::State_MouseOver);
@@ -724,19 +800,24 @@ ControlPart RenderThemeQt::applyTheme(QStyleOption& option, RenderObject* o) con
// Readonly is supported on textfields.
option.state |= QStyle::State_ReadOnly;
- if (supportsFocus(o->style()->appearance()) && isFocused(o)) {
- option.state |= QStyle::State_HasFocus;
- option.state |= QStyle::State_KeyboardFocusChange;
- }
+ option.direction = Qt::LeftToRight;
if (isHovered(o))
option.state |= QStyle::State_MouseOver;
- option.direction = Qt::LeftToRight;
- if (o->style() && o->style()->direction() == WebCore::RTL)
- option.direction = Qt::RightToLeft;
+ setPaletteFromPageClientIfExists(option.palette);
+ RenderStyle* style = o->style();
+ if (!style)
+ return NoControlPart;
- ControlPart result = o->style()->appearance();
+ ControlPart result = style->appearance();
+ if (supportsFocus(result) && isFocused(o)) {
+ option.state |= QStyle::State_HasFocus;
+ option.state |= QStyle::State_KeyboardFocusChange;
+ }
+
+ if (style->direction() == WebCore::RTL)
+ option.direction = Qt::RightToLeft;
switch (result) {
case PushButtonPart:
@@ -753,18 +834,9 @@ ControlPart RenderThemeQt::applyTheme(QStyleOption& option, RenderObject* o) con
option.state |= QStyle::State_Raised;
break;
}
- }
-
- if (result == RadioPart || result == CheckboxPart)
+ case RadioPart:
+ case CheckboxPart:
option.state |= (isChecked(o) ? QStyle::State_On : QStyle::State_Off);
-
- // If the owner widget has a custom palette, use it
- Page* page = o->document()->page();
- if (page) {
- ChromeClient* client = page->chrome()->client();
- QWebPageClient* pageClient = client->platformPageClient();
- if (pageClient)
- option.palette = pageClient->palette();
}
return result;
@@ -833,7 +905,7 @@ bool RenderThemeQt::paintMediaMuteButton(RenderObject* o, const RenderObject::Pa
if (!mediaElement)
return false;
- StylePainter p(paintInfo);
+ StylePainter p(this, paintInfo);
if (!p.isValid())
return true;
@@ -862,7 +934,7 @@ bool RenderThemeQt::paintMediaPlayButton(RenderObject* o, const RenderObject::Pa
if (!mediaElement)
return false;
- StylePainter p(paintInfo);
+ StylePainter p(this, paintInfo);
if (!p.isValid())
return true;
@@ -901,7 +973,7 @@ bool RenderThemeQt::paintMediaSliderTrack(RenderObject* o, const RenderObject::P
if (!mediaElement)
return false;
- StylePainter p(paintInfo);
+ StylePainter p(this, paintInfo);
if (!p.isValid())
return true;
@@ -909,16 +981,6 @@ bool RenderThemeQt::paintMediaSliderTrack(RenderObject* o, const RenderObject::P
paintMediaBackground(p.painter, r);
- if (MediaPlayer* player = mediaElement->player()) {
- if (player->totalBytesKnown()) {
- float percentLoaded = static_cast<float>(player->bytesLoaded()) / player->totalBytes();
-
- WorldMatrixTransformer transformer(p.painter, o, r);
- p.painter->setBrush(getMediaControlForegroundColor());
- p.painter->drawRect(0, 37, 100 * percentLoaded, 26);
- }
- }
-
return false;
}
@@ -928,7 +990,7 @@ bool RenderThemeQt::paintMediaSliderThumb(RenderObject* o, const RenderObject::P
if (!mediaElement)
return false;
- StylePainter p(paintInfo);
+ StylePainter p(this, paintInfo);
if (!p.isValid())
return true;
@@ -944,13 +1006,26 @@ bool RenderThemeQt::paintMediaSliderThumb(RenderObject* o, const RenderObject::P
void RenderThemeQt::adjustSliderThumbSize(RenderObject* o) const
{
- if (o->style()->appearance() == MediaSliderThumbPart) {
+ ControlPart part = o->style()->appearance();
+
+ if (part == MediaSliderThumbPart) {
RenderStyle* parentStyle = o->parent()->style();
Q_ASSERT(parentStyle);
int parentHeight = parentStyle->height().value();
o->style()->setWidth(Length(parentHeight / 3, Fixed));
o->style()->setHeight(Length(parentHeight, Fixed));
+ } else if (part == SliderThumbHorizontalPart || part == SliderThumbVerticalPart) {
+ QStyleOptionSlider option;
+ if (part == SliderThumbVerticalPart)
+ option.orientation = Qt::Vertical;
+
+ QStyle* style = qStyle();
+
+ int width = style->pixelMetric(QStyle::PM_SliderLength, &option);
+ int height = style->pixelMetric(QStyle::PM_SliderThickness, &option);
+ o->style()->setWidth(Length(width, Fixed));
+ o->style()->setHeight(Length(height, Fixed));
}
}
diff --git a/WebCore/platform/qt/RenderThemeQt.h b/WebCore/platform/qt/RenderThemeQt.h
index 617c875..e6bab7e 100644
--- a/WebCore/platform/qt/RenderThemeQt.h
+++ b/WebCore/platform/qt/RenderThemeQt.h
@@ -19,8 +19,8 @@
* Boston, MA 02110-1301, USA.
*
*/
-#ifndef RenderThemeQt_H
-#define RenderThemeQt_H
+#ifndef RenderThemeQt_h
+#define RenderThemeQt_h
#include "RenderTheme.h"
@@ -35,6 +35,7 @@ namespace WebCore {
class RenderStyle;
class HTMLMediaElement;
+class ScrollbarThemeQt;
class RenderThemeQt : public RenderTheme {
private:
@@ -75,6 +76,8 @@ public:
virtual String extraMediaControlsStyleSheet();
#endif
+ QStyle* qStyle() const;
+
protected:
virtual bool paintCheckbox(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r);
virtual void setCheckboxSize(RenderStyle*) const;
@@ -99,7 +102,10 @@ protected:
virtual void adjustMenuListButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
virtual bool paintSliderTrack(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
+ virtual void adjustSliderTrackStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
+
virtual bool paintSliderThumb(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
+ virtual void adjustSliderThumbStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
virtual bool paintSearchField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
virtual void adjustSearchFieldStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
@@ -132,12 +138,13 @@ private:
private:
bool supportsFocus(ControlPart) const;
- ControlPart applyTheme(QStyleOption&, RenderObject*) const;
+ ControlPart initializeCommonQStyleOptions(QStyleOption&, RenderObject*) const;
void setButtonPadding(RenderStyle*) const;
void setPopupPadding(RenderStyle*) const;
- QStyle* qStyle() const;
+ void setPaletteFromPageClientIfExists(QPalette&) const;
+
QStyle* fallbackStyle();
Page* m_page;
@@ -152,8 +159,8 @@ private:
class StylePainter {
public:
- explicit StylePainter(const RenderObject::PaintInfo& paintInfo);
- explicit StylePainter(GraphicsContext* context);
+ explicit StylePainter(RenderThemeQt*, const RenderObject::PaintInfo&);
+ explicit StylePainter(ScrollbarThemeQt*, GraphicsContext*);
~StylePainter();
bool isValid() const { return painter && style; }
@@ -170,7 +177,7 @@ public:
{ style->drawComplexControl(cc, &opt, painter, widget); }
private:
- void init(GraphicsContext* context);
+ void init(GraphicsContext* context, QStyle*);
QBrush oldBrush;
bool oldAntialiasing;
@@ -180,4 +187,4 @@ private:
}
-#endif
+#endif // RenderThemeQt_h
diff --git a/WebCore/platform/qt/ScrollViewQt.cpp b/WebCore/platform/qt/ScrollViewQt.cpp
index ccbd751..17ad253 100644
--- a/WebCore/platform/qt/ScrollViewQt.cpp
+++ b/WebCore/platform/qt/ScrollViewQt.cpp
@@ -36,32 +36,19 @@ namespace WebCore {
void ScrollView::platformInit()
{
- m_widgetsPreventingBlitting = 0;
}
void ScrollView::platformDestroy()
{
}
-// Windowed plugins are using native windows and are thus preventing
-// us from doing any kind of scrolling optimization.
-
-void ScrollView::adjustWidgetsPreventingBlittingCount(int delta)
-{
- m_widgetsPreventingBlitting += delta;
- if (parent())
- parent()->adjustWidgetsPreventingBlittingCount(delta);
-}
-
void ScrollView::platformAddChild(Widget*)
{
- adjustWidgetsPreventingBlittingCount(1);
}
void ScrollView::platformRemoveChild(Widget* child)
{
child->hide();
- adjustWidgetsPreventingBlittingCount(-1);
}
}
diff --git a/WebCore/platform/qt/ScrollbarThemeQt.cpp b/WebCore/platform/qt/ScrollbarThemeQt.cpp
index 561e55f..c0c80ba 100644
--- a/WebCore/platform/qt/ScrollbarThemeQt.cpp
+++ b/WebCore/platform/qt/ScrollbarThemeQt.cpp
@@ -140,14 +140,14 @@ bool ScrollbarThemeQt::paint(Scrollbar* scrollbar, GraphicsContext* graphicsCont
return false;
}
- StylePainter p(graphicsContext);
+ StylePainter p(this, graphicsContext);
if (!p.isValid())
return true;
p.painter->save();
QStyleOptionSlider* opt = styleOptionSlider(scrollbar, p.widget);
- p.painter->setClipRect(opt->rect.intersected(damageRect));
+ p.painter->setClipRect(opt->rect.intersected(damageRect), Qt::IntersectClip);
#ifdef Q_WS_MAC
p.drawComplexControl(QStyle::CC_ScrollBar, *opt);
@@ -172,14 +172,14 @@ ScrollbarPart ScrollbarThemeQt::hitTest(Scrollbar* scrollbar, const PlatformMous
QStyleOptionSlider* opt = styleOptionSlider(scrollbar);
const QPoint pos = scrollbar->convertFromContainingWindow(evt.pos());
opt->rect.moveTo(QPoint(0, 0));
- QStyle::SubControl sc = QApplication::style()->hitTestComplexControl(QStyle::CC_ScrollBar, opt, pos, 0);
+ QStyle::SubControl sc = style()->hitTestComplexControl(QStyle::CC_ScrollBar, opt, pos, 0);
return scrollbarPart(sc);
}
bool ScrollbarThemeQt::shouldCenterOnThumb(Scrollbar*, const PlatformMouseEvent& evt)
{
// Middle click centers slider thumb (if supported)
- return QApplication::style()->styleHint(QStyle::SH_ScrollBar_MiddleClickAbsolutePosition) && evt.button() == MiddleButton;
+ return style()->styleHint(QStyle::SH_ScrollBar_MiddleClickAbsolutePosition) && evt.button() == MiddleButton;
}
void ScrollbarThemeQt::invalidatePart(Scrollbar* scrollbar, ScrollbarPart)
@@ -190,13 +190,12 @@ void ScrollbarThemeQt::invalidatePart(Scrollbar* scrollbar, ScrollbarPart)
int ScrollbarThemeQt::scrollbarThickness(ScrollbarControlSize controlSize)
{
- QStyle* s = QApplication::style();
QStyleOptionSlider o;
o.orientation = Qt::Vertical;
o.state &= ~QStyle::State_Horizontal;
if (controlSize != RegularScrollbar)
o.state |= QStyle::State_Mini;
- return s->pixelMetric(QStyle::PM_ScrollBarExtent, &o, 0);
+ return style()->pixelMetric(QStyle::PM_ScrollBarExtent, &o, 0);
}
int ScrollbarThemeQt::thumbPosition(Scrollbar* scrollbar)
@@ -209,21 +208,21 @@ int ScrollbarThemeQt::thumbPosition(Scrollbar* scrollbar)
int ScrollbarThemeQt::thumbLength(Scrollbar* scrollbar)
{
QStyleOptionSlider* opt = styleOptionSlider(scrollbar);
- IntRect thumb = QApplication::style()->subControlRect(QStyle::CC_ScrollBar, opt, QStyle::SC_ScrollBarSlider, 0);
+ IntRect thumb = style()->subControlRect(QStyle::CC_ScrollBar, opt, QStyle::SC_ScrollBarSlider, 0);
return scrollbar->orientation() == HorizontalScrollbar ? thumb.width() : thumb.height();
}
int ScrollbarThemeQt::trackPosition(Scrollbar* scrollbar)
{
QStyleOptionSlider* opt = styleOptionSlider(scrollbar);
- IntRect track = QApplication::style()->subControlRect(QStyle::CC_ScrollBar, opt, QStyle::SC_ScrollBarGroove, 0);
+ IntRect track = style()->subControlRect(QStyle::CC_ScrollBar, opt, QStyle::SC_ScrollBarGroove, 0);
return scrollbar->orientation() == HorizontalScrollbar ? track.x() - scrollbar->x() : track.y() - scrollbar->y();
}
int ScrollbarThemeQt::trackLength(Scrollbar* scrollbar)
{
QStyleOptionSlider* opt = styleOptionSlider(scrollbar);
- IntRect track = QApplication::style()->subControlRect(QStyle::CC_ScrollBar, opt, QStyle::SC_ScrollBarGroove, 0);
+ IntRect track = style()->subControlRect(QStyle::CC_ScrollBar, opt, QStyle::SC_ScrollBarGroove, 0);
return scrollbar->orientation() == HorizontalScrollbar ? track.width() : track.height();
}
@@ -235,9 +234,9 @@ void ScrollbarThemeQt::paintScrollCorner(ScrollView* scrollView, GraphicsContext
}
#if QT_VERSION < 0x040500
- context->fillRect(rect, QApplication::palette().color(QPalette::Normal, QPalette::Window));
+ context->fillRect(rect, QApplication::palette().color(QPalette::Normal, QPalette::Window), DeviceColorSpace);
#else
- StylePainter p(context);
+ StylePainter p(this, context);
if (!p.isValid())
return;
@@ -247,5 +246,10 @@ void ScrollbarThemeQt::paintScrollCorner(ScrollView* scrollView, GraphicsContext
#endif
}
+QStyle* ScrollbarThemeQt::style() const
+{
+ return QApplication::style();
+}
+
}
diff --git a/WebCore/platform/qt/ScrollbarThemeQt.h b/WebCore/platform/qt/ScrollbarThemeQt.h
index 6ca44ea..cf4882d 100644
--- a/WebCore/platform/qt/ScrollbarThemeQt.h
+++ b/WebCore/platform/qt/ScrollbarThemeQt.h
@@ -28,6 +28,12 @@
#include "ScrollbarTheme.h"
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_NAMESPACE
+class QStyle;
+QT_END_NAMESPACE
+
namespace WebCore {
class ScrollbarThemeQt : public ScrollbarTheme {
@@ -49,6 +55,8 @@ public:
virtual int trackLength(Scrollbar*);
virtual int scrollbarThickness(ScrollbarControlSize = RegularScrollbar);
+
+ QStyle* style() const;
};
}
diff --git a/WebCore/platform/qt/SharedBufferQt.cpp b/WebCore/platform/qt/SharedBufferQt.cpp
index 8d62226..029d9d6 100644
--- a/WebCore/platform/qt/SharedBufferQt.cpp
+++ b/WebCore/platform/qt/SharedBufferQt.cpp
@@ -45,6 +45,8 @@ PassRefPtr<SharedBuffer> SharedBuffer::createWithContentsOfFile(const String& fi
if (result->m_buffer.size() != file.size())
return 0;
+ result->m_size = result->m_buffer.size();
+
file.read(result->m_buffer.data(), result->m_buffer.size());
return result.release();
}
diff --git a/WebCore/platform/sql/SQLiteDatabase.cpp b/WebCore/platform/sql/SQLiteDatabase.cpp
index 9a4e32a..d170db5 100644
--- a/WebCore/platform/sql/SQLiteDatabase.cpp
+++ b/WebCore/platform/sql/SQLiteDatabase.cpp
@@ -320,7 +320,7 @@ int SQLiteDatabase::authorizerFunction(void* userData, int actionCode, const cha
case SQLITE_DROP_VTABLE:
return auth->dropVTable(parameter1, parameter2);
case SQLITE_FUNCTION:
- return auth->allowFunction(parameter1);
+ return auth->allowFunction(parameter2);
#endif
default:
ASSERT_NOT_REACHED();
diff --git a/WebCore/platform/text/AtomicString.cpp b/WebCore/platform/text/AtomicString.cpp
index 17d7832..64c03cb 100644
--- a/WebCore/platform/text/AtomicString.cpp
+++ b/WebCore/platform/text/AtomicString.cpp
@@ -103,7 +103,9 @@ static inline bool equal(StringImpl* string, const UChar* characters, unsigned l
if (string->length() != length)
return false;
-#if PLATFORM(ARM) || PLATFORM(SH4)
+ // FIXME: perhaps we should have a more abstract macro that indicates when
+ // going 4 bytes at a time is unsafe
+#if CPU(ARM) || CPU(SH4)
const UChar* stringCharacters = string->characters();
for (unsigned i = 0; i != length; ++i) {
if (*stringCharacters++ != *characters++)
@@ -250,7 +252,7 @@ PassRefPtr<StringImpl> AtomicString::add(const JSC::Identifier& identifier)
if (!length)
return StringImpl::empty();
- HashAndCharacters buffer = { string->computedHash(), string->data(), length };
+ HashAndCharacters buffer = { string->existingHash(), string->data(), length };
pair<HashSet<StringImpl*>::iterator, bool> addResult = stringTable().add<HashAndCharacters, HashAndCharactersTranslator>(buffer);
if (!addResult.second)
return *addResult.first;
@@ -284,7 +286,7 @@ AtomicStringImpl* AtomicString::find(const JSC::Identifier& identifier)
if (!length)
return static_cast<AtomicStringImpl*>(StringImpl::empty());
- HashAndCharacters buffer = { string->computedHash(), string->data(), length };
+ HashAndCharacters buffer = { string->existingHash(), string->data(), length };
HashSet<StringImpl*>::iterator iterator = stringTable().find<HashAndCharacters, HashAndCharactersTranslator>(buffer);
if (iterator == stringTable().end())
return 0;
@@ -302,6 +304,8 @@ DEFINE_GLOBAL(AtomicString, emptyAtom, "")
DEFINE_GLOBAL(AtomicString, textAtom, "#text")
DEFINE_GLOBAL(AtomicString, commentAtom, "#comment")
DEFINE_GLOBAL(AtomicString, starAtom, "*")
+DEFINE_GLOBAL(AtomicString, xmlAtom, "xml")
+DEFINE_GLOBAL(AtomicString, xmlnsAtom, "xmlns")
void AtomicString::init()
{
@@ -316,6 +320,8 @@ void AtomicString::init()
new ((void*)&textAtom) AtomicString("#text");
new ((void*)&commentAtom) AtomicString("#comment");
new ((void*)&starAtom) AtomicString("*");
+ new ((void*)&xmlAtom) AtomicString("xml");
+ new ((void*)&xmlnsAtom) AtomicString("xmlns");
initialized = true;
}
diff --git a/WebCore/platform/text/AtomicString.h b/WebCore/platform/text/AtomicString.h
index 47d07c5..64a8bfe 100644
--- a/WebCore/platform/text/AtomicString.h
+++ b/WebCore/platform/text/AtomicString.h
@@ -156,6 +156,8 @@ inline bool equalIgnoringCase(const String& a, const AtomicString& b) { return e
extern const AtomicString textAtom;
extern const AtomicString commentAtom;
extern const AtomicString starAtom;
+ extern const AtomicString xmlAtom;
+ extern const AtomicString xmlnsAtom;
#endif
} // namespace WebCore
diff --git a/WebCore/platform/text/CharacterNames.h b/WebCore/platform/text/CharacterNames.h
index cd09447..ebaa1f1 100644
--- a/WebCore/platform/text/CharacterNames.h
+++ b/WebCore/platform/text/CharacterNames.h
@@ -37,6 +37,7 @@ namespace WebCore {
const UChar blackSquare = 0x25A0;
const UChar bullet = 0x2022;
+ const UChar ethiopicPrefaceColon = 0x1366;
const UChar hebrewPunctuationGeresh = 0x05F3;
const UChar hebrewPunctuationGershayim = 0x05F4;
const UChar horizontalEllipsis = 0x2026;
@@ -59,6 +60,7 @@ namespace WebCore {
const UChar rightToLeftMark = 0x200F;
const UChar rightToLeftOverride = 0x202E;
const UChar softHyphen = 0x00AD;
+ const UChar space = 0x0020;
const UChar whiteBullet = 0x25E6;
const UChar zeroWidthSpace = 0x200B;
diff --git a/WebCore/platform/text/PlatformString.h b/WebCore/platform/text/PlatformString.h
index 247536a..8a379be 100644
--- a/WebCore/platform/text/PlatformString.h
+++ b/WebCore/platform/text/PlatformString.h
@@ -31,16 +31,6 @@
#include <objc/objc.h>
#endif
-#if USE(JSC)
-#include <runtime/Identifier.h>
-#else
-// runtime/Identifier.h brings in a variety of wtf headers. We explicitly
-// include them in the case of non-JSC builds to keep things consistent.
-#include <wtf/HashMap.h>
-#include <wtf/HashSet.h>
-#include <wtf/OwnPtr.h>
-#endif
-
#if PLATFORM(CF)
typedef const struct __CFString * CFStringRef;
#endif
@@ -60,6 +50,13 @@ class wxString;
class BString;
#endif
+#if USE(JSC)
+namespace JSC {
+class Identifier;
+class UString;
+}
+#endif
+
namespace WebCore {
class CString;
diff --git a/WebCore/platform/text/String.cpp b/WebCore/platform/text/String.cpp
index 24659a4..04b04ab 100644
--- a/WebCore/platform/text/String.cpp
+++ b/WebCore/platform/text/String.cpp
@@ -37,6 +37,8 @@
#include <wtf/unicode/UTF8.h>
#if USE(JSC)
+#include <runtime/Identifier.h>
+
using JSC::Identifier;
using JSC::UString;
#endif
@@ -352,7 +354,7 @@ String String::format(const char *format, ...)
return buffer;
-#elif PLATFORM(WINCE)
+#elif OS(WINCE)
va_list args;
va_start(args, format);
@@ -444,7 +446,7 @@ String String::number(unsigned long n)
String String::number(long long n)
{
-#if PLATFORM(WIN_OS) && !PLATFORM(QT)
+#if OS(WINDOWS) && !PLATFORM(QT)
return String::format("%I64i", n);
#else
return String::format("%lli", n);
@@ -453,7 +455,7 @@ String String::number(long long n)
String String::number(unsigned long long n)
{
-#if PLATFORM(WIN_OS) && !PLATFORM(QT)
+#if OS(WINDOWS) && !PLATFORM(QT)
return String::format("%I64u", n);
#else
return String::format("%llu", n);
diff --git a/WebCore/platform/text/StringBuilder.cpp b/WebCore/platform/text/StringBuilder.cpp
index c21e366..3e34981 100644
--- a/WebCore/platform/text/StringBuilder.cpp
+++ b/WebCore/platform/text/StringBuilder.cpp
@@ -95,4 +95,17 @@ String StringBuilder::toString() const
return result;
}
+void StringBuilder::clear()
+{
+ m_totalLength = UINT_MAX;
+ m_strings.clear();
+}
+
+unsigned StringBuilder::length() const
+{
+ if (m_totalLength == UINT_MAX)
+ return 0;
+ return m_totalLength;
+}
+
}
diff --git a/WebCore/platform/text/StringBuilder.h b/WebCore/platform/text/StringBuilder.h
index 8d76b9c..7f72fbf 100644
--- a/WebCore/platform/text/StringBuilder.h
+++ b/WebCore/platform/text/StringBuilder.h
@@ -42,6 +42,9 @@ namespace WebCore {
void append(const String&);
void append(UChar);
void append(char);
+
+ void clear();
+ unsigned length() const;
String toString() const;
diff --git a/WebCore/platform/text/StringHash.h b/WebCore/platform/text/StringHash.h
index 21a478e..e6c548a 100644
--- a/WebCore/platform/text/StringHash.h
+++ b/WebCore/platform/text/StringHash.h
@@ -24,8 +24,8 @@
#include "AtomicString.h"
#include "PlatformString.h"
-#include <wtf/HashFunctions.h>
#include <wtf/HashTraits.h>
+#include <wtf/StringHashFunctions.h>
#include <wtf/unicode/Unicode.h>
namespace WebCore {
@@ -52,7 +52,9 @@ namespace WebCore {
if (aLength != bLength)
return false;
-#if PLATFORM(ARM) || PLATFORM(SH4)
+ // FIXME: perhaps we should have a more abstract macro that indicates when
+ // going 4 bytes at a time is unsafe
+#if CPU(ARM) || CPU(SH4)
const UChar* aChars = a->characters();
const UChar* bChars = b->characters();
for (unsigned i = 0; i != aLength; ++i) {
diff --git a/WebCore/platform/text/StringImpl.cpp b/WebCore/platform/text/StringImpl.cpp
index 5cf4ced..3b61a0b 100644
--- a/WebCore/platform/text/StringImpl.cpp
+++ b/WebCore/platform/text/StringImpl.cpp
@@ -34,6 +34,7 @@
#include "TextBreakIterator.h"
#include "TextEncoding.h"
#include "ThreadGlobalData.h"
+#include <runtime/UString.h>
#include <wtf/dtoa.h>
#include <wtf/Assertions.h>
#include <wtf/Threading.h>
@@ -979,7 +980,7 @@ JSC::UString StringImpl::ustring()
{
SharedUChar* sharedBuffer = this->sharedBuffer();
if (sharedBuffer)
- return JSC::UString::Rep::create(const_cast<UChar*>(m_data), m_length, sharedBuffer);
+ return JSC::UString::Rep::create(sharedBuffer, const_cast<UChar*>(m_data), m_length);
return JSC::UString(m_data, m_length);
}
diff --git a/WebCore/platform/text/StringImpl.h b/WebCore/platform/text/StringImpl.h
index 5155fa5..f7a9d06 100644
--- a/WebCore/platform/text/StringImpl.h
+++ b/WebCore/platform/text/StringImpl.h
@@ -27,16 +27,12 @@
#include <wtf/ASCIICType.h>
#include <wtf/CrossThreadRefCounted.h>
#include <wtf/OwnFastMallocPtr.h>
-#include <wtf/PassRefPtr.h>
#include <wtf/PtrAndFlags.h>
#include <wtf/RefCounted.h>
+#include <wtf/StringHashFunctions.h>
#include <wtf/Vector.h>
#include <wtf/unicode/Unicode.h>
-#if USE(JSC)
-#include <runtime/UString.h>
-#endif
-
#if PLATFORM(CF)
typedef const struct __CFString * CFStringRef;
#endif
@@ -45,6 +41,10 @@ typedef const struct __CFString * CFStringRef;
@class NSString;
#endif
+namespace JSC {
+class UString;
+}
+
namespace WebCore {
class StringBuffer;
@@ -103,8 +103,8 @@ public:
unsigned hash() { if (m_hash == 0) m_hash = computeHash(m_data, m_length); return m_hash; }
unsigned existingHash() const { ASSERT(m_hash); return m_hash; }
- static unsigned computeHash(const UChar*, unsigned len);
- static unsigned computeHash(const char*);
+ inline static unsigned computeHash(const UChar* data, unsigned length) { return WTF::stringHash(data, length); }
+ inline static unsigned computeHash(const char* data) { return WTF::stringHash(data); }
// Returns a StringImpl suitable for use on another thread.
PassRefPtr<StringImpl> crossThreadString();
@@ -214,91 +214,6 @@ inline bool equalIgnoringCase(const char* a, const UChar* b, unsigned length) {
bool equalIgnoringNullity(StringImpl*, StringImpl*);
-// Golden ratio - arbitrary start value to avoid mapping all 0's to all 0's
-// or anything like that.
-const unsigned phi = 0x9e3779b9U;
-
-// Paul Hsieh's SuperFastHash
-// http://www.azillionmonkeys.com/qed/hash.html
-inline unsigned StringImpl::computeHash(const UChar* data, unsigned length)
-{
- unsigned hash = phi;
-
- // Main loop.
- for (unsigned pairCount = length >> 1; pairCount; pairCount--) {
- hash += data[0];
- unsigned tmp = (data[1] << 11) ^ hash;
- hash = (hash << 16) ^ tmp;
- data += 2;
- hash += hash >> 11;
- }
-
- // Handle end case.
- if (length & 1) {
- hash += data[0];
- hash ^= hash << 11;
- hash += hash >> 17;
- }
-
- // Force "avalanching" of final 127 bits.
- hash ^= hash << 3;
- hash += hash >> 5;
- hash ^= hash << 2;
- hash += hash >> 15;
- hash ^= hash << 10;
-
- // This avoids ever returning a hash code of 0, since that is used to
- // signal "hash not computed yet", using a value that is likely to be
- // effectively the same as 0 when the low bits are masked.
- hash |= !hash << 31;
-
- return hash;
-}
-
-// Paul Hsieh's SuperFastHash
-// http://www.azillionmonkeys.com/qed/hash.html
-inline unsigned StringImpl::computeHash(const char* data)
-{
- // This hash is designed to work on 16-bit chunks at a time. But since the normal case
- // (above) is to hash UTF-16 characters, we just treat the 8-bit chars as if they
- // were 16-bit chunks, which should give matching results
-
- unsigned hash = phi;
-
- // Main loop
- for (;;) {
- unsigned char b0 = data[0];
- if (!b0)
- break;
- unsigned char b1 = data[1];
- if (!b1) {
- hash += b0;
- hash ^= hash << 11;
- hash += hash >> 17;
- break;
- }
- hash += b0;
- unsigned tmp = (b1 << 11) ^ hash;
- hash = (hash << 16) ^ tmp;
- data += 2;
- hash += hash >> 11;
- }
-
- // Force "avalanching" of final 127 bits.
- hash ^= hash << 3;
- hash += hash >> 5;
- hash ^= hash << 2;
- hash += hash >> 15;
- hash ^= hash << 10;
-
- // This avoids ever returning a hash code of 0, since that is used to
- // signal "hash not computed yet", using a value that is likely to be
- // effectively the same as 0 when the low bits are masked.
- hash |= !hash << 31;
-
- return hash;
-}
-
static inline bool isSpaceOrNewline(UChar c)
{
// Use isASCIISpace() for basic Latin-1.
diff --git a/WebCore/platform/text/TextCodecICU.cpp b/WebCore/platform/text/TextCodecICU.cpp
index 7ebce2c..a8a817f 100644
--- a/WebCore/platform/text/TextCodecICU.cpp
+++ b/WebCore/platform/text/TextCodecICU.cpp
@@ -87,7 +87,7 @@ void TextCodecICU::registerExtendedEncodingNames(EncodingNameRegistrar registrar
const char* name = ucnv_getAvailableName(i);
UErrorCode error = U_ZERO_ERROR;
// Try MIME before trying IANA to pick up commonly used names like
- // 'EUC-JP' instead of horrendeously long names like
+ // 'EUC-JP' instead of horrendously long names like
// 'Extended_UNIX_Code_Packed_Format_for_Japanese'.
const char* standardName = ucnv_getStandardName(name, "MIME", &error);
if (!U_SUCCESS(error) || !standardName) {
diff --git a/WebCore/platform/text/TextEncoding.cpp b/WebCore/platform/text/TextEncoding.cpp
index ec9a8b0..4a30d62 100644
--- a/WebCore/platform/text/TextEncoding.cpp
+++ b/WebCore/platform/text/TextEncoding.cpp
@@ -129,7 +129,7 @@ CString TextEncoding::encode(const UChar* characters, size_t length, Unencodable
UTF16Normalized.set(g_utf8_to_utf16(UTF8Normalized.get(), -1, 0, &UTF16Length, 0));
return newTextCodec(*this)->encode(UTF16Normalized.get(), UTF16Length, handling);
-#elif PLATFORM(WINCE)
+#elif OS(WINCE)
// normalization will be done by Windows CE API
OwnPtr<TextCodec> textCodec = newTextCodec(*this);
return textCodec.get() ? textCodec->encode(characters, length, handling) : CString();
diff --git a/WebCore/platform/text/TextEncodingDetectorICU.cpp b/WebCore/platform/text/TextEncodingDetectorICU.cpp
index fcb2aa9..c0d11de 100644
--- a/WebCore/platform/text/TextEncodingDetectorICU.cpp
+++ b/WebCore/platform/text/TextEncodingDetectorICU.cpp
@@ -69,7 +69,7 @@ bool detectTextEncoding(const char* data, size_t len,
// "the context" (parent-encoding, referrer encoding, etc).
// 2. 'Emulate' Firefox/IE's non-Universal detectors (e.g.
// Chinese, Japanese, Russian, Korean and Hebrew) by picking the
- // encoding with a highest confidence among the detetctor-specific
+ // encoding with a highest confidence among the detector-specific
// limited set of candidate encodings.
// Below is a partial implementation of the first part of what's outlined
// above.
diff --git a/WebCore/platform/text/TextEncodingRegistry.cpp b/WebCore/platform/text/TextEncodingRegistry.cpp
index a4be520..00ad2c9 100644
--- a/WebCore/platform/text/TextEncodingRegistry.cpp
+++ b/WebCore/platform/text/TextEncodingRegistry.cpp
@@ -51,7 +51,7 @@
#if USE(GLIB_UNICODE)
#include "gtk/TextCodecGtk.h"
#endif
-#if PLATFORM(WINCE) && !PLATFORM(QT)
+#if OS(WINCE) && !PLATFORM(QT)
#include "TextCodecWince.h"
#endif
@@ -230,7 +230,7 @@ static void buildBaseTextCodecMaps()
TextCodecGtk::registerBaseCodecs(addToTextCodecMap);
#endif
-#if PLATFORM(WINCE) && !PLATFORM(QT)
+#if OS(WINCE) && !PLATFORM(QT)
TextCodecWince::registerBaseEncodingNames(addToTextEncodingNameMap);
TextCodecWince::registerBaseCodecs(addToTextCodecMap);
#endif
@@ -258,7 +258,7 @@ static void extendTextCodecMaps()
TextCodecGtk::registerExtendedCodecs(addToTextCodecMap);
#endif
-#if PLATFORM(WINCE) && !PLATFORM(QT)
+#if OS(WINCE) && !PLATFORM(QT)
TextCodecWince::registerExtendedEncodingNames(addToTextEncodingNameMap);
TextCodecWince::registerExtendedCodecs(addToTextCodecMap);
#endif
diff --git a/WebCore/platform/text/TextStream.cpp b/WebCore/platform/text/TextStream.cpp
index eb4bae7..baaa8b9 100644
--- a/WebCore/platform/text/TextStream.cpp
+++ b/WebCore/platform/text/TextStream.cpp
@@ -90,6 +90,13 @@ TextStream& TextStream::operator<<(const char* string)
return *this;
}
+TextStream& TextStream::operator<<(void* p)
+{
+ char buffer[printBufferSize];
+ snprintf(buffer, sizeof(buffer) - 1, "%p", p);
+ return *this << buffer;
+}
+
TextStream& TextStream::operator<<(const String& string)
{
append(m_text, string);
@@ -101,7 +108,7 @@ String TextStream::release()
return String::adopt(m_text);
}
-#if PLATFORM(WIN_OS) && PLATFORM(X86_64) && COMPILER(MSVC)
+#if OS(WINDOWS) && PLATFORM(X86_64) && COMPILER(MSVC)
TextStream& TextStream::operator<<(__int64 i)
{
char buffer[printBufferSize];
diff --git a/WebCore/platform/text/TextStream.h b/WebCore/platform/text/TextStream.h
index 71034f3..dfaa048 100644
--- a/WebCore/platform/text/TextStream.h
+++ b/WebCore/platform/text/TextStream.h
@@ -43,8 +43,9 @@ public:
TextStream& operator<<(float);
TextStream& operator<<(double);
TextStream& operator<<(const char*);
+ TextStream& operator<<(void*);
TextStream& operator<<(const String&);
-#if PLATFORM(WIN_OS) && PLATFORM(X86_64) && COMPILER(MSVC)
+#if OS(WINDOWS) && PLATFORM(X86_64) && COMPILER(MSVC)
TextStream& operator<<(unsigned __int64);
TextStream& operator<<(__int64);
#endif
diff --git a/WebCore/platform/text/chromium/TextBreakIteratorInternalICUChromium.cpp b/WebCore/platform/text/chromium/TextBreakIteratorInternalICUChromium.cpp
index 4e2aceb..9adb999 100644
--- a/WebCore/platform/text/chromium/TextBreakIteratorInternalICUChromium.cpp
+++ b/WebCore/platform/text/chromium/TextBreakIteratorInternalICUChromium.cpp
@@ -22,18 +22,29 @@
#include "config.h"
#include "TextBreakIteratorInternalICU.h"
+#include "CString.h"
+#include "Language.h"
+#include "PlatformString.h"
+#include <wtf/StdLibExtras.h>
+
namespace WebCore {
+static const char* UILanguage()
+{
+ // Chrome's UI language can be different from the OS UI language on Windows.
+ // We want to return Chrome's UI language here.
+ DEFINE_STATIC_LOCAL(CString, locale, (defaultLanguage().latin1()));
+ return locale.data();
+}
+
const char* currentSearchLocaleID()
{
- // FIXME: Should use system locale.
- return "";
+ return UILanguage();
}
const char* currentTextBreakLocaleID()
{
- // FIXME: Should use system locale.
- return "en_us";
+ return UILanguage();
}
} // namespace WebCore
diff --git a/WebCore/platform/text/qt/TextCodecQt.cpp b/WebCore/platform/text/qt/TextCodecQt.cpp
index b3f75cc..21e6e12 100644
--- a/WebCore/platform/text/qt/TextCodecQt.cpp
+++ b/WebCore/platform/text/qt/TextCodecQt.cpp
@@ -97,7 +97,7 @@ String TextCodecQt::decode(const char* bytes, size_t length, bool flush, bool /*
// 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)
+#if OS(SYMBIAN)
static const int MaxInputChunkSize = 32 * 1024;
#else
static const int MaxInputChunkSize = 1024 * 1024;
diff --git a/WebCore/platform/text/wince/TextBreakIteratorWince.cpp b/WebCore/platform/text/wince/TextBreakIteratorWince.cpp
index 26a5be2..7f46e4f 100644
--- a/WebCore/platform/text/wince/TextBreakIteratorWince.cpp
+++ b/WebCore/platform/text/wince/TextBreakIteratorWince.cpp
@@ -23,6 +23,7 @@
#include "TextBreakIterator.h"
#include "PlatformString.h"
+#include <wtf/StdLibExtras.h>
#include <wtf/unicode/Unicode.h>
using namespace WTF::Unicode;
@@ -308,4 +309,4 @@ TextBreakIterator* cursorMovementIterator(const UChar* string, int length)
return characterBreakIterator(string, length);
}
-}
+} // namespace WebCore
diff --git a/WebCore/platform/win/ClipboardUtilitiesWin.cpp b/WebCore/platform/win/ClipboardUtilitiesWin.cpp
index 0358b7a..f22fcdc 100644
--- a/WebCore/platform/win/ClipboardUtilitiesWin.cpp
+++ b/WebCore/platform/win/ClipboardUtilitiesWin.cpp
@@ -415,7 +415,7 @@ PassRefPtr<DocumentFragment> fragmentFromCF_HTML(Document* doc, const String& cf
unsigned fragmentEnd = cf_html.reverseFind('<', tagEnd);
String markup = cf_html.substring(fragmentStart, fragmentEnd - fragmentStart).stripWhiteSpace();
- return createFragmentFromMarkup(doc, markup, srcURL);
+ return createFragmentFromMarkup(doc, markup, srcURL, FragmentScriptingNotAllowed);
}
@@ -443,7 +443,7 @@ PassRefPtr<DocumentFragment> fragmentFromHTML(Document* doc, IDataObject* data)
html = String(data);
GlobalUnlock(store.hGlobal);
ReleaseStgMedium(&store);
- return createFragmentFromMarkup(doc, html, srcURL);
+ return createFragmentFromMarkup(doc, html, srcURL, FragmentScriptingNotAllowed);
}
return 0;
diff --git a/WebCore/platform/win/ClipboardWin.cpp b/WebCore/platform/win/ClipboardWin.cpp
index b75ce46..f83927d 100644
--- a/WebCore/platform/win/ClipboardWin.cpp
+++ b/WebCore/platform/win/ClipboardWin.cpp
@@ -534,7 +534,7 @@ bool ClipboardWin::setData(const String& type, const String& data)
return false;
}
-static void addMimeTypesForFormat(HashSet<String>& results, FORMATETC& format)
+static void addMimeTypesForFormat(HashSet<String>& results, const FORMATETC& format)
{
// URL and Text are provided for compatibility with IE's model
if (format.cfFormat == urlFormat()->cfFormat || format.cfFormat == urlWFormat()->cfFormat) {
@@ -560,7 +560,7 @@ HashSet<String> ClipboardWin::types() const
COMPtr<IEnumFORMATETC> itr;
- if (FAILED(m_dataObject->EnumFormatEtc(0, &itr)))
+ if (FAILED(m_dataObject->EnumFormatEtc(DATADIR_GET, &itr)))
return results;
if (!itr)
@@ -568,7 +568,8 @@ HashSet<String> ClipboardWin::types() const
FORMATETC data;
- while (SUCCEEDED(itr->Next(1, &data, 0))) {
+ // IEnumFORMATETC::Next returns S_FALSE if there are no more items.
+ while (itr->Next(1, &data, 0) == S_OK) {
addMimeTypesForFormat(results, data);
}
@@ -781,7 +782,7 @@ bool ClipboardWin::hasData()
return false;
COMPtr<IEnumFORMATETC> itr;
- if (FAILED(m_dataObject->EnumFormatEtc(0, &itr)))
+ if (FAILED(m_dataObject->EnumFormatEtc(DATADIR_GET, &itr)))
return false;
if (!itr)
@@ -789,7 +790,8 @@ bool ClipboardWin::hasData()
FORMATETC data;
- if (SUCCEEDED(itr->Next(1, &data, 0))) {
+ // IEnumFORMATETC::Next returns S_FALSE if there are no more items.
+ if (itr->Next(1, &data, 0) == S_OK) {
// There is at least one item in the IDataObject
return true;
}
diff --git a/WebCore/platform/win/CursorWin.cpp b/WebCore/platform/win/CursorWin.cpp
index 5afb1ae9..48cf10b 100644
--- a/WebCore/platform/win/CursorWin.cpp
+++ b/WebCore/platform/win/CursorWin.cpp
@@ -408,4 +408,9 @@ const Cursor& grabbingCursor()
return pointerCursor();
}
+SharedCursor::~SharedCursor()
+{
+ DestroyIcon(m_nativeCursor);
+}
+
}
diff --git a/WebCore/platform/win/EventLoopWin.cpp b/WebCore/platform/win/EventLoopWin.cpp
index aae107d..ece320f 100644
--- a/WebCore/platform/win/EventLoopWin.cpp
+++ b/WebCore/platform/win/EventLoopWin.cpp
@@ -26,6 +26,8 @@
#include "config.h"
#include "EventLoop.h"
+#include <windows.h>
+
namespace WebCore {
void EventLoop::cycle()
diff --git a/WebCore/platform/win/FileSystemWin.cpp b/WebCore/platform/win/FileSystemWin.cpp
index a676f87..0592298 100644
--- a/WebCore/platform/win/FileSystemWin.cpp
+++ b/WebCore/platform/win/FileSystemWin.cpp
@@ -33,6 +33,7 @@
#include "CString.h"
#include "NotImplemented.h"
#include "PlatformString.h"
+#include <wtf/HashMap.h>
#include <windows.h>
#include <winbase.h>
diff --git a/WebCore/platform/win/PlatformMouseEventWin.cpp b/WebCore/platform/win/PlatformMouseEventWin.cpp
index dc4dd2f..8b542f9 100644
--- a/WebCore/platform/win/PlatformMouseEventWin.cpp
+++ b/WebCore/platform/win/PlatformMouseEventWin.cpp
@@ -65,7 +65,7 @@ static MouseEventType messageToEventType(UINT message)
case WM_MBUTTONUP:
return MouseEventReleased;
-#if !PLATFORM(WINCE)
+#if !OS(WINCE)
case WM_MOUSELEAVE:
#endif
case WM_MOUSEMOVE:
@@ -108,7 +108,7 @@ PlatformMouseEvent::PlatformMouseEvent(HWND hWnd, UINT message, WPARAM wParam, L
m_button = MiddleButton;
break;
case WM_MOUSEMOVE:
-#if !PLATFORM(WINCE)
+#if !OS(WINCE)
case WM_MOUSELEAVE:
#endif
if (wParam & MK_LBUTTON)
diff --git a/WebCore/platform/win/PlatformScreenWin.cpp b/WebCore/platform/win/PlatformScreenWin.cpp
index 6e0f861..4af9e17 100644
--- a/WebCore/platform/win/PlatformScreenWin.cpp
+++ b/WebCore/platform/win/PlatformScreenWin.cpp
@@ -27,6 +27,7 @@
#include "config.h"
#include "PlatformScreen.h"
+#include "HostWindow.h"
#include "IntRect.h"
#include "FloatRect.h"
#include "Frame.h"
@@ -53,7 +54,7 @@ static DEVMODE deviceInfoForWidget(Widget* widget)
DEVMODE deviceInfo;
deviceInfo.dmSize = sizeof(DEVMODE);
deviceInfo.dmDriverExtra = 0;
-#if PLATFORM(WINCE)
+#if OS(WINCE)
if (!EnumDisplaySettings(0, ENUM_CURRENT_SETTINGS, &deviceInfo))
deviceInfo.dmBitsPerPel = 16;
#else
@@ -79,7 +80,7 @@ int screenDepthPerComponent(Widget* widget)
bool screenIsMonochrome(Widget* widget)
{
-#if PLATFORM(WINCE)
+#if OS(WINCE)
// EnumDisplaySettings doesn't set dmColor in DEVMODE.
return false;
#else
diff --git a/WebCore/platform/win/PopupMenuWin.cpp b/WebCore/platform/win/PopupMenuWin.cpp
index 7d8c8d5..4ba5e30 100644
--- a/WebCore/platform/win/PopupMenuWin.cpp
+++ b/WebCore/platform/win/PopupMenuWin.cpp
@@ -30,6 +30,7 @@
#include "FrameView.h"
#include "GraphicsContext.h"
#include "HTMLNames.h"
+#include "HostWindow.h"
#include "Page.h"
#include "PlatformMouseEvent.h"
#include "PlatformScreen.h"
@@ -41,7 +42,7 @@
#include <tchar.h>
#include <windows.h>
#include <windowsx.h>
-#if PLATFORM(WINCE)
+#if OS(WINCE)
#include <ResDefCE.h>
#define MAKEPOINTS(l) (*((POINTS FAR *)&(l)))
#endif
@@ -151,7 +152,7 @@ void PopupMenu::show(const IntRect& r, FrameView* view, int index)
// 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;
-#if !PLATFORM(WINCE)
+#if !OS(WINCE)
::SystemParametersInfo(SPI_GETCOMBOBOXANIMATION, 0, &shouldAnimate, 0);
if (shouldAnimate) {
@@ -279,7 +280,6 @@ void PopupMenu::hide()
::PostMessage(m_popup, WM_NULL, 0, 0);
}
-const int endOfLinePadding = 2;
void PopupMenu::calculatePositionAndSize(const IntRect& r, FrameView* v)
{
// r is in absolute document coordinates, but we want to be in screen coordinates
@@ -325,9 +325,7 @@ void PopupMenu::calculatePositionAndSize(const IntRect& r, FrameView* v)
popupWidth += ScrollbarTheme::nativeTheme()->scrollbarThickness(SmallScrollbar);
// Add padding to align the popup text with the <select> text
- // Note: We can't add paddingRight() because that value includes the width
- // of the dropdown button, so we must use our own endOfLinePadding constant.
- popupWidth += max(0, endOfLinePadding - client()->clientInsetRight()) + max(0, client()->clientPaddingLeft() - client()->clientInsetLeft());
+ popupWidth += max(0, client()->clientPaddingRight() - client()->clientInsetRight()) + max(0, client()->clientPaddingLeft() - client()->clientInsetLeft());
// Leave room for the border
popupWidth += 2 * popupWindowBorderWidth;
@@ -578,7 +576,7 @@ void PopupMenu::paint(const IntRect& damageRect, HDC hdc)
}
}
if (!m_bmp) {
-#if PLATFORM(WINCE)
+#if OS(WINCE)
BitmapInfo bitmapInfo(true, clientRect().width(), clientRect().height());
#else
BitmapInfo bitmapInfo = BitmapInfo::createBottomUp(clientRect().size());
@@ -713,7 +711,7 @@ void PopupMenu::registerClass()
if (haveRegisteredWindowClass)
return;
-#if PLATFORM(WINCE)
+#if OS(WINCE)
WNDCLASS wcex;
#else
WNDCLASSEX wcex;
@@ -734,7 +732,7 @@ void PopupMenu::registerClass()
haveRegisteredWindowClass = true;
-#if PLATFORM(WINCE)
+#if OS(WINCE)
RegisterClass(&wcex);
#else
RegisterClassEx(&wcex);
@@ -744,7 +742,7 @@ void PopupMenu::registerClass()
LRESULT CALLBACK PopupMenu::PopupMenuWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
-#if PLATFORM(WINCE)
+#if OS(WINCE)
LONG longPtr = GetWindowLong(hWnd, 0);
#else
LONG_PTR longPtr = GetWindowLongPtr(hWnd, 0);
@@ -757,7 +755,7 @@ LRESULT CALLBACK PopupMenu::PopupMenuWndProc(HWND hWnd, UINT message, WPARAM wPa
LPCREATESTRUCT createStruct = reinterpret_cast<LPCREATESTRUCT>(lParam);
// Associate the PopupMenu with the window.
-#if PLATFORM(WINCE)
+#if OS(WINCE)
::SetWindowLong(hWnd, 0, (LONG)createStruct->lpCreateParams);
#else
::SetWindowLongPtr(hWnd, 0, (LONG_PTR)createStruct->lpCreateParams);
@@ -891,7 +889,7 @@ LRESULT PopupMenu::wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam
}
BOOL shouldHotTrack = FALSE;
-#if !PLATFORM(WINCE)
+#if !OS(WINCE)
::SystemParametersInfo(SPI_GETHOTTRACKING, 0, &shouldHotTrack, 0);
#endif
@@ -988,7 +986,7 @@ LRESULT PopupMenu::wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam
lResult = 0;
break;
}
-#if !PLATFORM(WINCE)
+#if !OS(WINCE)
case WM_PRINTCLIENT:
paint(clientRect(), (HDC)wParam);
break;
diff --git a/WebCore/platform/win/SharedBufferWin.cpp b/WebCore/platform/win/SharedBufferWin.cpp
index 1839c99..a95d590 100644
--- a/WebCore/platform/win/SharedBufferWin.cpp
+++ b/WebCore/platform/win/SharedBufferWin.cpp
@@ -57,6 +57,8 @@ PassRefPtr<SharedBuffer> SharedBuffer::createWithContentsOfFile(const String& fi
goto exit;
}
+ result->m_size = result->m_buffer.size();
+
if (fread(result->m_buffer.data(), 1, fileStat.st_size, fileDescriptor) != fileStat.st_size)
LOG_ERROR("Failed to fully read contents of file %s - errno(%i)", filePath.ascii().data(), errno);
diff --git a/WebCore/platform/win/SystemInfo.cpp b/WebCore/platform/win/SystemInfo.cpp
index ba20ddd..f010769 100644
--- a/WebCore/platform/win/SystemInfo.cpp
+++ b/WebCore/platform/win/SystemInfo.cpp
@@ -26,6 +26,8 @@
#include "config.h"
#include "SystemInfo.h"
+#include <windows.h>
+
namespace WebCore {
bool isRunningOnVistaOrLater()
diff --git a/WebCore/platform/win/SystemTimeWin.cpp b/WebCore/platform/win/SystemTimeWin.cpp
index 6ab4c27..8c25c32 100644
--- a/WebCore/platform/win/SystemTimeWin.cpp
+++ b/WebCore/platform/win/SystemTimeWin.cpp
@@ -37,7 +37,7 @@ namespace WebCore {
float userIdleTime()
{
-#if !PLATFORM(WINCE)
+#if !OS(WINCE)
LASTINPUTINFO lastInputInfo = {0};
lastInputInfo.cbSize = sizeof(LASTINPUTINFO);
if (::GetLastInputInfo(&lastInputInfo))
diff --git a/WebCore/platform/win/WidgetWin.cpp b/WebCore/platform/win/WidgetWin.cpp
index 2272027..74a22f6 100644
--- a/WebCore/platform/win/WidgetWin.cpp
+++ b/WebCore/platform/win/WidgetWin.cpp
@@ -26,6 +26,7 @@
#include "config.h"
#include "Widget.h"
+#include "Chrome.h"
#include "Cursor.h"
#include "Document.h"
#include "Element.h"
diff --git a/WebCore/platform/wince/MIMETypeRegistryWince.cpp b/WebCore/platform/wince/MIMETypeRegistryWince.cpp
index 2ecde48..b6ead9b 100644
--- a/WebCore/platform/wince/MIMETypeRegistryWince.cpp
+++ b/WebCore/platform/wince/MIMETypeRegistryWince.cpp
@@ -27,6 +27,7 @@
#include "config.h"
#include "MIMETypeRegistry.h"
+#include <wtf/HashMap.h>
#include <windows.h>
#include <winreg.h>
diff --git a/WebCore/platform/wince/SearchPopupMenuWince.cpp b/WebCore/platform/wince/SearchPopupMenuWince.cpp
index ca11292..756b7cf 100644
--- a/WebCore/platform/wince/SearchPopupMenuWince.cpp
+++ b/WebCore/platform/wince/SearchPopupMenuWince.cpp
@@ -21,6 +21,7 @@
#include "SearchPopupMenu.h"
#include "AtomicString.h"
+#include "NotImplemented.h"
namespace WebCore {
diff --git a/WebCore/platform/wince/SharedTimerWince.cpp b/WebCore/platform/wince/SharedTimerWince.cpp
index ca2f104..a620a10 100644
--- a/WebCore/platform/wince/SharedTimerWince.cpp
+++ b/WebCore/platform/wince/SharedTimerWince.cpp
@@ -85,7 +85,7 @@ static void initializeOffScreenTimerWindow()
RegisterClass(&wcex);
timerWindowHandle = CreateWindow(kTimerWindowClassName, 0, 0,
- CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, HWND_MESSAGE, 0, Page::instanceHandle(), 0);
+ CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, 0, 0, Page::instanceHandle(), 0);
}
void setSharedTimerFiredFunction(void (*f)())
diff --git a/WebCore/platform/wx/ContextMenuWx.cpp b/WebCore/platform/wx/ContextMenuWx.cpp
index 6f1bc9c..b20d29e 100644
--- a/WebCore/platform/wx/ContextMenuWx.cpp
+++ b/WebCore/platform/wx/ContextMenuWx.cpp
@@ -30,6 +30,8 @@
#include "PlatformMenuDescription.h"
#include "wx/menu.h"
+#include <wtf/HashMap.h>
+
using namespace WebCore;
typedef WTF::HashMap<int, ContextMenuAction> ItemActionMap;
diff --git a/WebCore/platform/wx/FileSystemWx.cpp b/WebCore/platform/wx/FileSystemWx.cpp
index 1ee87ae..50ac2ec 100644
--- a/WebCore/platform/wx/FileSystemWx.cpp
+++ b/WebCore/platform/wx/FileSystemWx.cpp
@@ -42,7 +42,7 @@
#include <wx/filefn.h>
#include <wx/filename.h>
-#if PLATFORM(DARWIN)
+#if OS(DARWIN)
#include <CoreFoundation/CoreFoundation.h>
#endif
@@ -127,9 +127,9 @@ int writeToFile(PlatformFileHandle, const char* data, int length)
bool unloadModule(PlatformModule mod)
{
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
return ::FreeLibrary(mod);
-#elif PLATFORM(DARWIN)
+#elif OS(DARWIN)
CFRelease(mod);
return true;
#else
diff --git a/WebCore/platform/wx/LocalizedStringsWx.cpp b/WebCore/platform/wx/LocalizedStringsWx.cpp
index 6a389f2..8573482 100644
--- a/WebCore/platform/wx/LocalizedStringsWx.cpp
+++ b/WebCore/platform/wx/LocalizedStringsWx.cpp
@@ -324,6 +324,16 @@ String AXDefinitionListDefinitionText()
return String();
}
+String AXMenuListPopupActionVerb()
+{
+ return String();
+}
+
+String AXMenuListActionVerb()
+{
+ return String();
+}
+
String validationMessageValueMissingText()
{
notImplemented();
diff --git a/WebCore/platform/wx/RenderThemeWx.cpp b/WebCore/platform/wx/RenderThemeWx.cpp
index c66ff87..c4d8c35 100644
--- a/WebCore/platform/wx/RenderThemeWx.cpp
+++ b/WebCore/platform/wx/RenderThemeWx.cpp
@@ -267,7 +267,11 @@ bool RenderThemeWx::paintButton(RenderObject* o, const RenderObject::PaintInfo&
IntRect rect = r;
-#if USE(WXGC)
+// On Mac, wxGraphicsContext and wxDC share the same native implementation,
+// and so transformations are available.
+// On Win and Linux, however, this is not true and transforms are lost,
+// so we need to restore them here.
+#if USE(WXGC) && !defined(__WXMAC__)
double xtrans = 0;
double ytrans = 0;
@@ -294,7 +298,7 @@ bool RenderThemeWx::paintButton(RenderObject* o, const RenderObject::PaintInfo&
if (isChecked(o))
flags |= wxCONTROL_CHECKED;
#if wxCHECK_VERSION(2,9,1)
- wxRendererNative::Get().DrawRadioBitmap(window, *dc, r, flags);
+ wxRendererNative::Get().DrawRadioBitmap(window, *dc, rect, flags);
#elif wxCHECK_VERSION(2,9,0)
wxRendererNative::Get().DrawRadioButton(window, *dc, rect, flags);
#else
diff --git a/WebCore/platform/wx/ScrollViewWx.cpp b/WebCore/platform/wx/ScrollViewWx.cpp
index f556894..35acf68 100644
--- a/WebCore/platform/wx/ScrollViewWx.cpp
+++ b/WebCore/platform/wx/ScrollViewWx.cpp
@@ -96,15 +96,15 @@ public:
}
else if (scrollType == wxEVT_SCROLLWIN_PAGEUP) {
if (horiz)
- pos.x -= m_scrollView->visibleWidth() - cAmountToKeepWhenPaging;
+ pos.x -= m_scrollView->visibleWidth() * cFractionToStepWhenPaging;
else
- pos.y -= m_scrollView->visibleHeight() - cAmountToKeepWhenPaging;
+ pos.y -= m_scrollView->visibleHeight() * cFractionToStepWhenPaging;
}
else if (scrollType == wxEVT_SCROLLWIN_PAGEDOWN) {
if (horiz)
- pos.x += m_scrollView->visibleWidth() - cAmountToKeepWhenPaging;
+ pos.x += m_scrollView->visibleWidth() * cFractionToStepWhenPaging;
else
- pos.y += m_scrollView->visibleHeight() - cAmountToKeepWhenPaging;
+ pos.y += m_scrollView->visibleHeight() * cFractionToStepWhenPaging;
}
else
return e.Skip();