summaryrefslogtreecommitdiffstats
path: root/WebCore/platform
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2010-05-11 18:35:50 +0100
committerBen Murdoch <benm@google.com>2010-05-14 10:23:05 +0100
commit21939df44de1705786c545cd1bf519d47250322d (patch)
treeef56c310f5c0cdc379c2abb2e212308a3281ce20 /WebCore/platform
parent4ff1d8891d520763f17675827154340c7c740f90 (diff)
downloadexternal_webkit-21939df44de1705786c545cd1bf519d47250322d.zip
external_webkit-21939df44de1705786c545cd1bf519d47250322d.tar.gz
external_webkit-21939df44de1705786c545cd1bf519d47250322d.tar.bz2
Merge Webkit at r58956: Initial merge by Git.
Change-Id: I1d9fb60ea2c3f2ddc04c17a871acdb39353be228
Diffstat (limited to 'WebCore/platform')
-rw-r--r--WebCore/platform/Arena.h2
-rw-r--r--WebCore/platform/HostWindow.h4
-rw-r--r--WebCore/platform/KURL.cpp14
-rw-r--r--WebCore/platform/KURLGoogle.cpp8
-rw-r--r--WebCore/platform/LinkHash.cpp18
-rw-r--r--WebCore/platform/ScrollView.cpp4
-rw-r--r--WebCore/platform/ScrollView.h55
-rw-r--r--WebCore/platform/ThemeTypes.h2
-rw-r--r--WebCore/platform/ThreadGlobalData.cpp13
-rw-r--r--WebCore/platform/ThreadGlobalData.h1
-rw-r--r--WebCore/platform/UUID.cpp14
-rw-r--r--WebCore/platform/Widget.cpp6
-rw-r--r--WebCore/platform/Widget.h38
-rw-r--r--WebCore/platform/android/FileSystemAndroid.cpp17
-rw-r--r--WebCore/platform/android/WidgetAndroid.cpp2
-rw-r--r--WebCore/platform/chromium/ChromiumBridge.h6
-rw-r--r--WebCore/platform/chromium/ChromiumDataObject.h2
-rw-r--r--WebCore/platform/chromium/ClipboardChromium.cpp40
-rw-r--r--WebCore/platform/chromium/DragImageChromiumSkia.cpp28
-rw-r--r--WebCore/platform/chromium/FileSystemChromium.cpp30
-rw-r--r--WebCore/platform/chromium/WidgetChromium.cpp5
-rw-r--r--WebCore/platform/efl/WidgetEfl.cpp2
-rw-r--r--WebCore/platform/graphics/FloatSize.h4
-rw-r--r--WebCore/platform/graphics/Font.cpp13
-rw-r--r--WebCore/platform/graphics/Font.h17
-rw-r--r--WebCore/platform/graphics/FontFastPath.cpp51
-rw-r--r--WebCore/platform/graphics/GlyphBuffer.h8
-rw-r--r--WebCore/platform/graphics/GlyphMetricsMap.h61
-rw-r--r--WebCore/platform/graphics/GlyphPageTreeNode.cpp20
-rw-r--r--WebCore/platform/graphics/Gradient.cpp7
-rw-r--r--WebCore/platform/graphics/Gradient.h3
-rw-r--r--WebCore/platform/graphics/GraphicsContext3D.h9
-rw-r--r--WebCore/platform/graphics/MediaPlayer.cpp3
-rw-r--r--WebCore/platform/graphics/SimpleFontData.cpp15
-rw-r--r--WebCore/platform/graphics/SimpleFontData.h58
-rw-r--r--WebCore/platform/graphics/TextRun.h12
-rw-r--r--WebCore/platform/graphics/WidthIterator.cpp21
-rw-r--r--WebCore/platform/graphics/WidthIterator.h13
-rw-r--r--WebCore/platform/graphics/cairo/FontCacheCairo.cpp5
-rw-r--r--WebCore/platform/graphics/cairo/FontPlatformData.h9
-rw-r--r--WebCore/platform/graphics/cairo/SimpleFontDataCairo.cpp19
-rw-r--r--WebCore/platform/graphics/cg/FontPlatformData.h6
-rw-r--r--WebCore/platform/graphics/cg/ImageSourceCG.cpp2
-rw-r--r--WebCore/platform/graphics/chromium/FontLinux.cpp25
-rw-r--r--WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp2
-rw-r--r--WebCore/platform/graphics/chromium/HarfbuzzSkia.cpp2
-rw-r--r--WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp11
-rw-r--r--WebCore/platform/graphics/chromium/SimpleFontDataLinux.cpp11
-rw-r--r--WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp1
-rw-r--r--WebCore/platform/graphics/gtk/SimpleFontDataPango.cpp23
-rw-r--r--WebCore/platform/graphics/haiku/ImageBufferData.h23
-rw-r--r--WebCore/platform/graphics/haiku/ImageBufferHaiku.cpp335
-rw-r--r--WebCore/platform/graphics/haiku/SimpleFontDataHaiku.cpp24
-rw-r--r--WebCore/platform/graphics/mac/ComplexTextController.cpp14
-rw-r--r--WebCore/platform/graphics/mac/ComplexTextController.h1
-rw-r--r--WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp50
-rw-r--r--WebCore/platform/graphics/mac/SimpleFontDataATSUI.mm77
-rw-r--r--WebCore/platform/graphics/mac/SimpleFontDataCoreText.cpp92
-rw-r--r--WebCore/platform/graphics/mac/SimpleFontDataMac.mm114
-rw-r--r--WebCore/platform/graphics/opentype/OpenTypeSanitizer.cpp9
-rw-r--r--WebCore/platform/graphics/qt/FontQt.cpp8
-rw-r--r--WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp93
-rw-r--r--WebCore/platform/graphics/qt/GraphicsContextQt.cpp16
-rw-r--r--WebCore/platform/graphics/qt/GraphicsLayerQt.cpp304
-rw-r--r--WebCore/platform/graphics/qt/GraphicsLayerQt.h4
-rw-r--r--WebCore/platform/graphics/qt/ImageDecoderQt.cpp4
-rw-r--r--WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp6
-rw-r--r--WebCore/platform/graphics/qt/PathQt.cpp29
-rw-r--r--WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp3
-rw-r--r--WebCore/platform/graphics/skia/GraphicsContextSkia.cpp14
-rw-r--r--WebCore/platform/graphics/transforms/TransformationMatrix.cpp16
-rw-r--r--WebCore/platform/graphics/transforms/TransformationMatrix.h2
-rw-r--r--WebCore/platform/graphics/win/FontPlatformDataCGWin.cpp2
-rw-r--r--WebCore/platform/graphics/win/FontPlatformDataWin.cpp2
-rw-r--r--WebCore/platform/graphics/win/GraphicsContextWin.cpp11
-rwxr-xr-xWebCore/platform/graphics/win/RefCountedGDIHandle.h (renamed from WebCore/platform/graphics/win/RefCountedHFONT.h)46
-rw-r--r--WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp33
-rw-r--r--WebCore/platform/graphics/win/SimpleFontDataCairoWin.cpp8
-rw-r--r--WebCore/platform/graphics/win/SimpleFontDataWin.cpp26
-rw-r--r--WebCore/platform/graphics/win/UniscribeController.cpp12
-rw-r--r--WebCore/platform/graphics/win/WKCACFLayerRenderer.cpp7
-rw-r--r--WebCore/platform/graphics/win/WKCACFLayerRenderer.h1
-rw-r--r--WebCore/platform/graphics/wince/FontCustomPlatformData.cpp2
-rw-r--r--WebCore/platform/graphics/wince/SimpleFontDataWince.cpp5
-rw-r--r--WebCore/platform/graphics/wx/FontCacheWx.cpp19
-rw-r--r--WebCore/platform/graphics/wx/FontPlatformData.h47
-rw-r--r--WebCore/platform/graphics/wx/FontPlatformDataWx.cpp25
-rw-r--r--WebCore/platform/graphics/wx/FontPlatformDataWxMac.mm (renamed from WebCore/platform/graphics/GlyphMetricsMap.cpp)40
-rw-r--r--WebCore/platform/graphics/wx/FontWx.cpp36
-rw-r--r--WebCore/platform/graphics/wx/SimpleFontDataWx.cpp44
-rw-r--r--WebCore/platform/gtk/ClipboardGtk.cpp270
-rw-r--r--WebCore/platform/gtk/ClipboardGtk.h23
-rw-r--r--WebCore/platform/gtk/CursorGtk.cpp8
-rw-r--r--WebCore/platform/gtk/DataObjectGtk.cpp22
-rw-r--r--WebCore/platform/gtk/DataObjectGtk.h4
-rw-r--r--WebCore/platform/gtk/PasteboardGtk.cpp2
-rw-r--r--WebCore/platform/gtk/PasteboardHelper.cpp89
-rw-r--r--WebCore/platform/gtk/PasteboardHelper.h6
-rw-r--r--WebCore/platform/gtk/RenderThemeGtk.cpp7
-rw-r--r--WebCore/platform/gtk/ScrollViewGtk.cpp50
-rw-r--r--WebCore/platform/gtk/WidgetGtk.cpp5
-rw-r--r--WebCore/platform/haiku/WidgetHaiku.cpp10
-rw-r--r--WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp10
-rw-r--r--WebCore/platform/image-decoders/gif/GIFImageDecoder.h5
-rw-r--r--WebCore/platform/image-decoders/gif/GIFImageReader.cpp74
-rw-r--r--WebCore/platform/image-decoders/gif/GIFImageReader.h2
-rw-r--r--WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp33
-rw-r--r--WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h3
-rw-r--r--WebCore/platform/image-decoders/png/PNGImageDecoder.cpp15
-rw-r--r--WebCore/platform/image-decoders/png/PNGImageDecoder.h3
-rw-r--r--WebCore/platform/image-encoders/skia/PNGImageEncoder.cpp5
-rw-r--r--WebCore/platform/mac/KeyEventMac.mm9
-rw-r--r--WebCore/platform/mac/PopupMenuMac.mm10
-rw-r--r--WebCore/platform/mac/SharedBufferMac.mm1
-rw-r--r--WebCore/platform/mac/ThemeMac.mm101
-rw-r--r--WebCore/platform/mac/WebCoreObjCExtras.mm7
-rw-r--r--WebCore/platform/mac/WidgetMac.mm5
-rw-r--r--WebCore/platform/network/FormData.cpp7
-rw-r--r--WebCore/platform/network/FormData.h3
-rw-r--r--WebCore/platform/network/FormDataBuilder.cpp2
-rw-r--r--WebCore/platform/network/NetworkStateNotifier.h9
-rw-r--r--WebCore/platform/network/ProtectionSpace.h34
-rw-r--r--WebCore/platform/network/ResourceHandle.h4
-rw-r--r--WebCore/platform/network/ResourceHandleClient.h4
-rw-r--r--WebCore/platform/network/ResourceRequestBase.cpp2
-rw-r--r--WebCore/platform/network/ResourceRequestBase.h5
-rw-r--r--WebCore/platform/network/mac/AuthenticationMac.mm14
-rw-r--r--WebCore/platform/network/mac/ResourceHandleMac.mm33
-rw-r--r--WebCore/platform/network/qt/NetworkStateNotifierQt.cpp4
-rw-r--r--WebCore/platform/network/qt/QNetworkReplyHandler.cpp5
-rw-r--r--WebCore/platform/network/qt/ResourceRequestQt.cpp6
-rw-r--r--WebCore/platform/posix/FileSystemPOSIX.cpp2
-rw-r--r--WebCore/platform/qt/PasteboardQt.cpp6
-rw-r--r--WebCore/platform/qt/QWebPageClient.h7
-rw-r--r--WebCore/platform/qt/RenderThemeQt.cpp28
-rw-r--r--WebCore/platform/qt/RenderThemeQt.h2
-rw-r--r--WebCore/platform/qt/TemporaryLinkStubsQt.cpp (renamed from WebCore/platform/qt/TemporaryLinkStubs.cpp)0
-rw-r--r--WebCore/platform/qt/WidgetQt.cpp2
-rw-r--r--WebCore/platform/sql/SQLiteDatabase.cpp95
-rw-r--r--WebCore/platform/sql/SQLiteDatabase.h14
-rw-r--r--WebCore/platform/sql/SQLiteStatement.cpp10
-rw-r--r--WebCore/platform/text/CharacterNames.h66
-rw-r--r--WebCore/platform/text/TextEncodingRegistry.cpp15
-rw-r--r--WebCore/platform/text/TextEncodingRegistry.h3
-rw-r--r--WebCore/platform/text/TextStream.cpp2
-rw-r--r--WebCore/platform/text/TextStream.h2
-rw-r--r--WebCore/platform/win/WidgetWin.cpp2
-rw-r--r--WebCore/platform/wince/SharedTimerWince.cpp2
-rw-r--r--WebCore/platform/wx/WidgetWx.cpp8
-rw-r--r--WebCore/platform/wx/wxcode/fontprops.h2
-rw-r--r--WebCore/platform/wx/wxcode/mac/carbon/fontprops.mm14
-rw-r--r--WebCore/platform/wx/wxcode/mac/carbon/non-kerned-drawing.cpp42
-rw-r--r--WebCore/platform/wx/wxcode/win/fontprops.cpp4
153 files changed, 2557 insertions, 1028 deletions
diff --git a/WebCore/platform/Arena.h b/WebCore/platform/Arena.h
index 4c9ecf4..b485fc1 100644
--- a/WebCore/platform/Arena.h
+++ b/WebCore/platform/Arena.h
@@ -44,7 +44,7 @@
namespace WebCore {
-typedef unsigned long uword;
+typedef uintptr_t uword;
struct Arena {
Arena* next; // next arena
diff --git a/WebCore/platform/HostWindow.h b/WebCore/platform/HostWindow.h
index dc681a1..e7316a7 100644
--- a/WebCore/platform/HostWindow.h
+++ b/WebCore/platform/HostWindow.h
@@ -54,10 +54,6 @@ public:
// Method for retrieving the native client of the page.
virtual PlatformPageClient platformPageClient() const = 0;
- // For scrolling a rect into view recursively. Useful in the cases where a WebView is embedded inside some containing
- // platform-specific ScrollView.
- virtual void scrollRectIntoView(const IntRect&, const ScrollView*) const = 0;
-
// To notify WebKit of scrollbar mode changes.
virtual void scrollbarsModeDidChange() const = 0;
};
diff --git a/WebCore/platform/KURL.cpp b/WebCore/platform/KURL.cpp
index 12ba4a2..9ed900f 100644
--- a/WebCore/platform/KURL.cpp
+++ b/WebCore/platform/KURL.cpp
@@ -1353,27 +1353,29 @@ bool protocolHostAndPortAreEqual(const KURL& a, const KURL& b)
{
if (a.m_schemeEnd != b.m_schemeEnd)
return false;
+
int hostStartA = a.hostStart();
+ int hostLengthA = a.hostEnd() - hostStartA;
int hostStartB = b.hostStart();
- if (a.m_hostEnd - hostStartA != b.m_hostEnd - hostStartB)
+ int hostLengthB = b.hostEnd() - b.hostStart();
+ if (hostLengthA != hostLengthB)
return false;
// Check the scheme
for (int i = 0; i < a.m_schemeEnd; ++i)
if (a.string()[i] != b.string()[i])
return false;
-
+
// And the host
- for (int i = hostStartA; i < a.m_hostEnd; ++i)
- if (a.string()[i] != b.string()[i])
+ for (int i = 0; i < hostLengthA; ++i)
+ if (a.string()[hostStartA + i] != b.string()[hostStartB + i])
return false;
-
+
if (a.port() != b.port())
return false;
return true;
}
-
String encodeWithURLEscapeSequences(const String& notEncodedString)
{
diff --git a/WebCore/platform/KURLGoogle.cpp b/WebCore/platform/KURLGoogle.cpp
index 97446bd..b4c84a6 100644
--- a/WebCore/platform/KURLGoogle.cpp
+++ b/WebCore/platform/KURLGoogle.cpp
@@ -1144,8 +1144,10 @@ bool protocolHostAndPortAreEqual(const KURL& a, const KURL& b)
return false;
int hostStartA = a.hostStart();
+ int hostLengthA = a.hostEnd() - hostStartA;
int hostStartB = b.hostStart();
- if (a.hostEnd() - hostStartA != b.hostEnd() - hostStartB)
+ int hostLengthB = b.hostEnd() - b.hostStart();
+ if (hostLengthA != hostLengthB)
return false;
// Check the scheme
@@ -1154,8 +1156,8 @@ bool protocolHostAndPortAreEqual(const KURL& a, const KURL& b)
return false;
// And the host
- for (int i = hostStartA; i < static_cast<int>(a.hostEnd()); ++i)
- if (a.string()[i] != b.string()[i])
+ for (int i = 0; i < hostLengthA; ++i)
+ if (a.string()[hostStartA + i] != b.string()[hostStartB + i])
return false;
if (a.port() != b.port())
diff --git a/WebCore/platform/LinkHash.cpp b/WebCore/platform/LinkHash.cpp
index 0bd589c..12437ab 100644
--- a/WebCore/platform/LinkHash.cpp
+++ b/WebCore/platform/LinkHash.cpp
@@ -147,12 +147,17 @@ static inline bool needsTrailingSlash(const UChar* characters, unsigned length)
return pos == length;
}
+static ALWAYS_INLINE LinkHash visitedLinkHashInline(const UChar* url, unsigned length)
+{
+ return AlreadyHashed::avoidDeletedValue(StringImpl::computeHash(url, length));
+}
+
LinkHash visitedLinkHash(const UChar* url, unsigned length)
{
- return AlreadyHashed::avoidDeletedValue(StringImpl::computeHash(url, length));
+ return visitedLinkHashInline(url, length);
}
-void visitedURL(const KURL& base, const AtomicString& attributeURL, Vector<UChar, 512>& buffer)
+static ALWAYS_INLINE void visitedURLInline(const KURL& base, const AtomicString& attributeURL, Vector<UChar, 512>& buffer)
{
if (attributeURL.isNull())
return;
@@ -213,14 +218,19 @@ void visitedURL(const KURL& base, const AtomicString& attributeURL, Vector<UChar
return;
}
+void visitedURL(const KURL& base, const AtomicString& attributeURL, Vector<UChar, 512>& buffer)
+{
+ return visitedURLInline(base, attributeURL, buffer);
+}
+
LinkHash visitedLinkHash(const KURL& base, const AtomicString& attributeURL)
{
Vector<UChar, 512> url;
- visitedURL(base, attributeURL, url);
+ visitedURLInline(base, attributeURL, url);
if (url.isEmpty())
return 0;
- return visitedLinkHash(url.data(), url.size());
+ return visitedLinkHashInline(url.data(), url.size());
}
} // namespace WebCore
diff --git a/WebCore/platform/ScrollView.cpp b/WebCore/platform/ScrollView.cpp
index 28f9c2f..f0e705e 100644
--- a/WebCore/platform/ScrollView.cpp
+++ b/WebCore/platform/ScrollView.cpp
@@ -292,9 +292,11 @@ void ScrollView::valueChanged(Scrollbar* scrollbar)
if (scrollbarsSuppressed())
return;
+ scrollPositionChanged();
scrollContents(scrollDelta);
}
+<<<<<<< HEAD:WebCore/platform/ScrollView.cpp
void ScrollView::scrollRectIntoViewRecursively(const IntRect& r)
{
#if PLATFORM(ANDROID)
@@ -325,6 +327,8 @@ void ScrollView::scrollRectIntoViewRecursively(const IntRect& r)
hostWindow()->scrollRectIntoView(rect, this);
}
+=======
+>>>>>>> webkit.org at r58956:WebCore/platform/ScrollView.cpp
void ScrollView::setScrollPosition(const IntPoint& scrollPoint)
{
if (prohibitsScrolling())
diff --git a/WebCore/platform/ScrollView.h b/WebCore/platform/ScrollView.h
index 52afbf9..b103d22 100644
--- a/WebCore/platform/ScrollView.h
+++ b/WebCore/platform/ScrollView.h
@@ -57,31 +57,31 @@ class ScrollView : public Widget, public ScrollbarClient {
public:
~ScrollView();
- // ScrollbarClient method. FrameView overrides the other two.
+ // ScrollbarClient function. FrameView overrides the other two.
virtual void valueChanged(Scrollbar*);
- // The window thats hosts the ScrollView. The ScrollView will communicate scrolls and repaints to the
+ // The window thats hosts the ScrollView. The ScrollView will communicate scrolls and repaints to the
// host window in the window's coordinate space.
virtual HostWindow* hostWindow() const = 0;
- // Returns a clip rect in host window coordinates. Used to clip the blit on a scroll.
+ // Returns a clip rect in host window coordinates. Used to clip the blit on a scroll.
virtual IntRect windowClipRect(bool clipToContents = true) const = 0;
- // Methods for child manipulation and inspection.
+ // Functions for child manipulation and inspection.
const HashSet<RefPtr<Widget> >* children() const { return &m_children; }
void addChild(PassRefPtr<Widget>);
void removeChild(Widget*);
- // If the scroll view does not use a native widget, then it will have cross-platform Scrollbars. These methods
+ // If the scroll view does not use a native widget, then it will have cross-platform Scrollbars. These functions
// can be used to obtain those scrollbars.
Scrollbar* horizontalScrollbar() const { return m_horizontalScrollbar.get(); }
Scrollbar* verticalScrollbar() const { return m_verticalScrollbar.get(); }
bool isScrollViewScrollbar(const Widget* child) const { return horizontalScrollbar() == child || verticalScrollbar() == child; }
- // Methods for setting and retrieving the scrolling mode in each axis (horizontal/vertical). The mode has values of
- // AlwaysOff, AlwaysOn, and Auto. AlwaysOff means never show a scrollbar, AlwaysOn means always show a scrollbar.
+ // Functions for setting and retrieving the scrolling mode in each axis (horizontal/vertical). The mode has values of
+ // AlwaysOff, AlwaysOn, and Auto. AlwaysOff means never show a scrollbar, AlwaysOn means always show a scrollbar.
// Auto means show a scrollbar only when one is needed.
- // Note that for platforms with native widgets, these modes are considered advisory. In other words the underlying native
+ // Note that for platforms with native widgets, these modes are considered advisory. In other words the underlying native
// widget may choose not to honor the requested modes.
void setScrollbarModes(ScrollbarMode horizontalMode, ScrollbarMode verticalMode, bool horizontalLock = false, bool verticalLock = false);
void setHorizontalScrollbarMode(ScrollbarMode mode, bool lock = false) { setScrollbarModes(mode, verticalScrollbarMode(), lock, verticalScrollbarLock()); }
@@ -103,7 +103,7 @@ public:
virtual bool avoidScrollbarCreation() { return false; }
// By default you only receive paint events for the area that is visible. In the case of using a
- // tiled backing store, this method can be set, so that the view paints the entire contents.
+ // tiled backing store, this function can be set, so that the view paints the entire contents.
bool paintsEntireContents() const { return m_paintsEntireContents; }
void setPaintsEntireContents(bool);
@@ -114,20 +114,20 @@ public:
void setProhibitsScrolling(bool b) { m_prohibitsScrolling = b; }
bool prohibitsScrolling() const { return m_prohibitsScrolling; }
- // Whether or not a scroll view will blit visible contents when it is scrolled. Blitting is disabled in situations
+ // Whether or not a scroll view will blit visible contents when it is scrolled. Blitting is disabled in situations
// where it would cause rendering glitches (such as with fixed backgrounds or when the view is partially transparent).
void setCanBlitOnScroll(bool);
bool canBlitOnScroll() const;
// The visible content rect has a location that is the scrolled offset of the document. The width and height are the viewport width
- // and height. By default the scrollbars themselves are excluded from this rectangle, but an optional boolean argument allows them to be
+ // and height. By default the scrollbars themselves are excluded from this rectangle, but an optional boolean argument allows them to be
// included.
IntRect visibleContentRect(bool includeScrollbars = false) const;
int visibleWidth() const { return visibleContentRect().width(); }
int visibleHeight() const { return visibleContentRect().height(); }
- // Methods for getting/setting the size webkit should use to layout the contents. By default this is the same as the visible
- // content size. Explicitly setting a layout size value will cause webkit to layout the contents using this size instead.
+ // Functions for getting/setting the size webkit should use to layout the contents. By default this is the same as the visible
+ // content size. Explicitly setting a layout size value will cause webkit to layout the contents using this size instead.
int layoutWidth() const;
int layoutHeight() const;
IntSize fixedLayoutSize() const;
@@ -135,27 +135,25 @@ public:
bool useFixedLayout() const;
void setUseFixedLayout(bool enable);
- // Methods for getting/setting the size of the document contained inside the ScrollView (as an IntSize or as individual width and height
+ // Functions for getting/setting the size of the document contained inside the ScrollView (as an IntSize or as individual width and height
// values).
IntSize contentsSize() const; // Always at least as big as the visibleWidth()/visibleHeight().
int contentsWidth() const { return contentsSize().width(); }
int contentsHeight() const { return contentsSize().height(); }
virtual void setContentsSize(const IntSize&);
- // Methods for querying the current scrolled position (both as a point, a size, or as individual X and Y values).
+ // Functions for querying the current scrolled position (both as a point, a size, or as individual X and Y values).
IntPoint scrollPosition() const { return visibleContentRect().location(); }
IntSize scrollOffset() const { return visibleContentRect().location() - IntPoint(); } // Gets the scrolled position as an IntSize. Convenient for adding to other sizes.
IntPoint maximumScrollPosition() const; // The maximum position we can be scrolled to.
int scrollX() const { return scrollPosition().x(); }
int scrollY() const { return scrollPosition().y(); }
- // Methods for scrolling the view. setScrollPosition is the only method that really scrolls the view. The other two methods are helper functions
- // that ultimately end up calling setScrollPosition.
+ // Functions for scrolling the view.
void setScrollPosition(const IntPoint&);
void scrollBy(const IntSize& s) { return setScrollPosition(scrollPosition() + s); }
- void scrollRectIntoViewRecursively(const IntRect&);
-
- // This method scrolls by lines, pages or pixels.
+
+ // This function scrolls by lines, pages or pixels.
bool scroll(ScrollDirection, ScrollGranularity);
// Scroll the actual contents of the view (either blitting or invalidating as needed).
@@ -173,15 +171,15 @@ public:
IntRect windowToContents(const IntRect&) const;
IntRect contentsToWindow(const IntRect&) const;
- // Methods for converting to and from screen coordinates.
+ // Functions for converting to and from screen coordinates.
IntRect contentsToScreen(const IntRect&) const;
IntPoint screenToContents(const IntPoint&) const;
- // The purpose of this method is to answer whether or not the scroll view is currently visible. Animations and painting updates can be suspended if
+ // The purpose of this function is to answer whether or not the scroll view is currently visible. Animations and painting updates can be suspended if
// we know that we are either not in a window right now or if that window is not visible.
bool isOffscreen() const;
- // These methods are used to enable scrollbars to avoid window resizer controls that overlap the scroll view. This happens on Mac
+ // These functions are used to enable scrollbars to avoid window resizer controls that overlap the scroll view. This happens on Mac
// for example.
virtual IntRect windowResizerRect() const { return IntRect(); }
bool containsScrollbarsAvoidingResizer() const;
@@ -197,9 +195,9 @@ public:
// For platforms that need to hit test scrollbars from within the engine's event handlers (like Win32).
Scrollbar* scrollbarAtPoint(const IntPoint& windowPoint);
- // This method exists for scrollviews that need to handle wheel events manually.
+ // This function exists for scrollviews that need to handle wheel events manually.
// On Mac the underlying NSScrollView just does the scrolling, but on other platforms
- // (like Windows), we need this method in order to do the scroll ourselves.
+ // (like Windows), we need this function in order to do the scroll ourselves.
void wheelEvent(PlatformWheelEvent&);
IntPoint convertChildToSelf(const Widget* child, const IntPoint& point) const
@@ -220,7 +218,7 @@ public:
return newPoint;
}
- // Widget override. Handles painting of the contents of the view as well as the scrollbars.
+ // Widget override. Handles painting of the contents of the view as well as the scrollbars.
virtual void paint(GraphicsContext*, const IntRect&);
void paintScrollbars(GraphicsContext*, const IntRect&);
@@ -252,7 +250,7 @@ protected:
virtual void contentsResized() = 0;
virtual void visibleContentsResized() = 0;
- // These methods are used to create/destroy scrollbars.
+ // These functions are used to create/destroy scrollbars.
void setHasHorizontalScrollbar(bool);
void setHasVerticalScrollbar(bool);
@@ -299,6 +297,9 @@ private:
// Called to update the scrollbars to accurately reflect the state of the view.
void updateScrollbars(const IntSize& desiredOffset);
+ // Called when the scroll position within this view changes. FrameView overrides this to generate repaint invalidations.
+ virtual void scrollPositionChanged() {}
+
void platformInit();
void platformDestroy();
void platformAddChild(Widget*);
diff --git a/WebCore/platform/ThemeTypes.h b/WebCore/platform/ThemeTypes.h
index 07a11fb..de71899 100644
--- a/WebCore/platform/ThemeTypes.h
+++ b/WebCore/platform/ThemeTypes.h
@@ -52,7 +52,7 @@ enum ControlPart {
MediaSeekForwardButtonPart, MediaRewindButtonPart, MediaReturnToRealtimeButtonPart, MediaToggleClosedCaptionsButtonPart,
MediaSliderPart, MediaSliderThumbPart, MediaVolumeSliderContainerPart, MediaVolumeSliderPart, MediaVolumeSliderThumbPart,
MediaControlsBackgroundPart, MediaCurrentTimePart, MediaTimeRemainingPart,
- MenulistPart, MenulistButtonPart, MenulistTextPart, MenulistTextFieldPart, OuterSpinButtonPart, ProgressBarPart,
+ MenulistPart, MenulistButtonPart, MenulistTextPart, MenulistTextFieldPart, OuterSpinButtonPart, ProgressBarPart, ProgressBarValuePart,
SliderHorizontalPart, SliderVerticalPart, SliderThumbHorizontalPart,
SliderThumbVerticalPart, CaretPart, SearchFieldPart, SearchFieldDecorationPart,
SearchFieldResultsDecorationPart, SearchFieldResultsButtonPart,
diff --git a/WebCore/platform/ThreadGlobalData.cpp b/WebCore/platform/ThreadGlobalData.cpp
index 434ee5a..99cd44a 100644
--- a/WebCore/platform/ThreadGlobalData.cpp
+++ b/WebCore/platform/ThreadGlobalData.cpp
@@ -69,7 +69,7 @@ ThreadGlobalData::ThreadGlobalData()
#endif
{
// This constructor will have been called on the main thread before being called on
- // any other thread, and is only called once per thread – this makes this a convenient
+ // any other thread, and is only called once per thread - this makes this a convenient
// point to call methods that internally perform a one-time initialization that is not
// threadsafe.
wtfThreadData();
@@ -78,14 +78,25 @@ ThreadGlobalData::ThreadGlobalData()
ThreadGlobalData::~ThreadGlobalData()
{
+ destroy();
+}
+
+void ThreadGlobalData::destroy()
+{
#if PLATFORM(MAC)
delete m_cachedConverterTEC;
+ m_cachedConverterTEC = 0;
#endif
+
#if USE(ICU_UNICODE)
delete m_cachedConverterICU;
+ m_cachedConverterICU = 0;
#endif
+
delete m_eventNames;
+ m_eventNames = 0;
delete m_threadTimers;
+ m_threadTimers = 0;
}
} // namespace WebCore
diff --git a/WebCore/platform/ThreadGlobalData.h b/WebCore/platform/ThreadGlobalData.h
index 3d73932..c17fbeb 100644
--- a/WebCore/platform/ThreadGlobalData.h
+++ b/WebCore/platform/ThreadGlobalData.h
@@ -49,6 +49,7 @@ namespace WebCore {
public:
ThreadGlobalData();
~ThreadGlobalData();
+ void destroy(); // called on workers to clean up the ThreadGlobalData before the thread exits.
EventNames& eventNames() { return *m_eventNames; }
ThreadTimers& threadTimers() { return *m_threadTimers; }
diff --git a/WebCore/platform/UUID.cpp b/WebCore/platform/UUID.cpp
index d8ac749..852e3ae 100644
--- a/WebCore/platform/UUID.cpp
+++ b/WebCore/platform/UUID.cpp
@@ -33,6 +33,10 @@
#include "NotImplemented.h"
+#if PLATFORM(QT)
+#include <QUuid>
+#endif
+
#if OS(WINDOWS)
#include <objbase.h>
#ifndef ARRAYSIZE
@@ -51,7 +55,12 @@ static const int uuidVersionIdentifierIndex = 14;
String createCanonicalUUIDString()
{
-#if OS(WINDOWS)
+#if PLATFORM(QT)
+ QUuid uuid = QUuid::createUuid();
+ String canonicalUuidStr = uuid.toString().mid(1, 36).toLower(); // remove opening and closing bracket and make it lower.
+ ASSERT(canonicalUuidStr[uuidVersionIdentifierIndex] == uuidVersionRequired);
+ return canonicalUuidStr;
+#elif OS(WINDOWS)
GUID uuid = { 0 };
HRESULT hr = CoCreateGuid(&uuid);
if (FAILED(hr))
@@ -76,7 +85,8 @@ String createCanonicalUUIDString()
if (!fptr)
return String();
char uuidStr[37] = {0};
- fgets(uuidStr, sizeof(uuidStr) - 1, fptr);
+ if (!fgets(uuidStr, sizeof(uuidStr) - 1, fptr))
+ return String();
fclose(fptr);
String canonicalUuidStr = String(uuidStr).lower(); // make it lower.
ASSERT(canonicalUuidStr[uuidVersionIdentifierIndex] == uuidVersionRequired);
diff --git a/WebCore/platform/Widget.cpp b/WebCore/platform/Widget.cpp
index 520eb6f..1370863 100644
--- a/WebCore/platform/Widget.cpp
+++ b/WebCore/platform/Widget.cpp
@@ -174,4 +174,10 @@ IntPoint Widget::convertFromContainingView(const IntPoint& parentPoint) const
return parentPoint;
}
+#if !PLATFORM(EFL)
+void Widget::frameRectsChanged()
+{
+}
+#endif
+
} // namespace WebCore
diff --git a/WebCore/platform/Widget.h b/WebCore/platform/Widget.h
index 2fce858..23d228e 100644
--- a/WebCore/platform/Widget.h
+++ b/WebCore/platform/Widget.h
@@ -77,6 +77,12 @@ typedef BView* PlatformWidget;
#include "PlatformWidget.h"
#endif
+#if PLATFORM(EFL)
+#include <Ecore_Evas.h>
+#include <Evas.h>
+typedef Evas_Object* PlatformWidget;
+#endif
+
#if PLATFORM(QT)
class QWebPageClient;
typedef QWebPageClient* PlatformPageClient;
@@ -99,6 +105,9 @@ class GraphicsContext;
class PlatformMouseEvent;
class ScrollView;
class WidgetPrivate;
+#if PLATFORM(EFL)
+class String;
+#endif
// The Widget class serves as a base class for three kinds of objects:
// (1) Scrollable areas (ScrollView)
@@ -157,7 +166,7 @@ public:
void invalidate() { invalidateRect(boundsRect()); }
virtual void invalidateRect(const IntRect&) = 0;
- virtual void setFocus();
+ virtual void setFocus(bool);
void setCursor(const Cursor&);
@@ -194,7 +203,7 @@ public:
IntPoint convertToContainingWindow(const IntPoint&) const;
IntPoint convertFromContainingWindow(const IntPoint&) const;
- virtual void frameRectsChanged() {}
+ virtual void frameRectsChanged();
// Notifies this widget that other widgets on the page have been repositioned.
virtual void widgetPositionsUpdated() {}
@@ -208,6 +217,20 @@ public:
void removeFromSuperview();
#endif
+#if PLATFORM(EFL)
+ // FIXME: These should really go to PlatformWidget. They're here currently since
+ // the EFL port considers that Evas_Object (a C object) is a PlatformWidget, but
+ // encapsulating that into a C++ class will make this header clean as it should be.
+ Evas* evas() const;
+
+ void setEvasObject(Evas_Object*);
+ Evas_Object* evasObject() const;
+
+ const String edjeTheme() const;
+ void setEdjeTheme(const String &);
+ const String edjeThemeRecursive() const;
+#endif
+
// Virtual methods to convert points to/from the containing ScrollView
virtual IntRect convertToContainingView(const IntRect&) const;
virtual IntRect convertFromContainingView(const IntRect&) const;
@@ -236,9 +259,18 @@ private:
IntRect m_frame; // Not used when a native widget exists.
-#if PLATFORM(MAC)
+#if PLATFORM(EFL)
+ // FIXME: Please see the previous #if PLATFORM(EFL) block.
+ Ecore_Evas* ecoreEvas() const;
+
+ void applyFallbackCursor();
+ void applyCursor();
+#endif
+
+#if PLATFORM(MAC) || PLATFORM(EFL)
WidgetPrivate* m_data;
#endif
+
#if PLATFORM(HAIKU)
PlatformWidget m_topLevelPlatformWidget;
#endif
diff --git a/WebCore/platform/android/FileSystemAndroid.cpp b/WebCore/platform/android/FileSystemAndroid.cpp
index 3d841d7..520bc7d 100644
--- a/WebCore/platform/android/FileSystemAndroid.cpp
+++ b/WebCore/platform/android/FileSystemAndroid.cpp
@@ -75,6 +75,23 @@ bool unloadModule(PlatformModule module)
return !dlclose(module);
}
+<<<<<<< HEAD:WebCore/platform/android/FileSystemAndroid.cpp
+=======
+int writeToFile(PlatformFileHandle handle, const char* data, int length)
+{
+ int totalBytesWritten = 0;
+ while (totalBytesWritten < length) {
+ int bytesWritten = write(handle, data, (size_t)(length - totalBytesWritten));
+ if (bytesWritten < 0 && errno != EINTR)
+ return -1;
+ if (bytesWritten > 0)
+ totalBytesWritten += bytesWritten;
+ }
+
+ return totalBytesWritten;
+}
+
+>>>>>>> webkit.org at r58956:WebCore/platform/android/FileSystemAndroid.cpp
String homeDirectoryPath()
{
return sPluginPath;
diff --git a/WebCore/platform/android/WidgetAndroid.cpp b/WebCore/platform/android/WidgetAndroid.cpp
index 9ab0b2c..14da0ca 100644
--- a/WebCore/platform/android/WidgetAndroid.cpp
+++ b/WebCore/platform/android/WidgetAndroid.cpp
@@ -54,7 +54,7 @@ IntRect Widget::frameRect() const
return platformWidget()->getBounds();
}
-void Widget::setFocus()
+void Widget::setFocus(bool focused)
{
notImplemented();
}
diff --git a/WebCore/platform/chromium/ChromiumBridge.h b/WebCore/platform/chromium/ChromiumBridge.h
index e582241..6eca3eb 100644
--- a/WebCore/platform/chromium/ChromiumBridge.h
+++ b/WebCore/platform/chromium/ChromiumBridge.h
@@ -109,6 +109,12 @@ namespace WebCore {
static String getAbsolutePath(const String&);
static bool isDirectory(const String&);
static KURL filePathToURL(const String&);
+ static PlatformFileHandle openFile(const String& path, FileOpenMode);
+ static void closeFile(PlatformFileHandle&);
+ static long long seekFile(PlatformFileHandle, long long offset, FileSeekOrigin);
+ static bool truncateFile(PlatformFileHandle, long long offset);
+ static int readFromFile(PlatformFileHandle, char* data, int length);
+ static int writeToFile(PlatformFileHandle, const char* data, int length);
// Font ---------------------------------------------------------------
#if OS(WINDOWS)
diff --git a/WebCore/platform/chromium/ChromiumDataObject.h b/WebCore/platform/chromium/ChromiumDataObject.h
index 625cb8c..af0a3fa 100644
--- a/WebCore/platform/chromium/ChromiumDataObject.h
+++ b/WebCore/platform/chromium/ChromiumDataObject.h
@@ -79,6 +79,8 @@ namespace WebCore {
{
url = newURL;
uriList.clear();
+ if (newURL.isEmpty())
+ return;
uriList.append(newURL.string());
}
diff --git a/WebCore/platform/chromium/ClipboardChromium.cpp b/WebCore/platform/chromium/ClipboardChromium.cpp
index 21d7edf..ab9f3c9 100644
--- a/WebCore/platform/chromium/ClipboardChromium.cpp
+++ b/WebCore/platform/chromium/ClipboardChromium.cpp
@@ -162,25 +162,21 @@ String ClipboardChromium::getData(const String& type, bool& success) const
case ClipboardDataTypeNone:
return String();
+ // Hack for URLs. file URLs are used internally for drop's default action, but we don't want
+ // to expose them to the page, so we filter them out here.
case ClipboardDataTypeURIList:
{
String text;
for (size_t i = 0; i < m_dataObject->uriList.size(); ++i) {
const String& uri = m_dataObject->uriList[i];
+ if (protocolIs(uri, "file"))
+ continue;
ASSERT(!uri.isEmpty());
if (!text.isEmpty())
text.append(textMIMETypeLineSeparator);
// URIs have already been canonicalized, so copy everything verbatim.
text.append(uri);
}
- // Also create file:// URLs out of the entries in the file list.
- for (size_t i = 0; i < m_dataObject->filenames.size(); ++i) {
- String fileURL = ChromiumBridge::filePathToURL(m_dataObject->filenames[i]);
- ASSERT(!fileURL.isEmpty());
- if (!text.isEmpty())
- text.append(textMIMETypeLineSeparator);
- text.append(fileURL);
- }
success = !text.isEmpty();
return text;
}
@@ -188,15 +184,10 @@ String ClipboardChromium::getData(const String& type, bool& success) const
case ClipboardDataTypeURL:
// In case of a previous setData('text/uri-list'), setData() has already
// prepared the 'url' member, so we can just retrieve it here.
- if (!m_dataObject->url.isEmpty()) {
+ if (!m_dataObject->url.isEmpty() && !m_dataObject->url.isLocalFile()) {
success = true;
return m_dataObject->url.string();
}
- // Otherwise check if we have a file that we could convert to a file:// URL.
- if (!m_dataObject->filenames.isEmpty()) {
- success = true;
- return ChromiumBridge::filePathToURL(m_dataObject->filenames[0]);
- }
return String();
case ClipboardDataTypeDownloadURL:
@@ -326,20 +317,27 @@ HashSet<String> ClipboardChromium::types() const
if (!m_dataObject)
return results;
- if (!m_dataObject->filenames.isEmpty()) {
- results.add("text/uri-list");
+ if (!m_dataObject->filenames.isEmpty())
results.add("Files");
- }
- if (m_dataObject->url.isValid()) {
+ // Hack for URLs. file URLs are used internally for drop's default action, but we don't want
+ // to expose them to the page, so we filter them out here.
+ if (m_dataObject->url.isValid() && !m_dataObject->url.isLocalFile()) {
ASSERT(!m_dataObject->uriList.isEmpty());
results.add("URL");
}
if (!m_dataObject->uriList.isEmpty()) {
- // Note that even if the URI list is not empty, it may not actually
- // contain a valid URL, so we can't return "URL" here.
- results.add("text/uri-list");
+ // Verify that the URI list contains at least one non-file URL.
+ for (Vector<String>::const_iterator it = m_dataObject->uriList.begin();
+ it != m_dataObject->uriList.end(); ++it) {
+ if (!protocolIs(*it, "file")) {
+ // Note that even if the URI list is not empty, it may not actually
+ // contain a valid URL, so we can't return "URL" here.
+ results.add("text/uri-list");
+ break;
+ }
+ }
}
if (!m_dataObject->plainText.isEmpty()) {
diff --git a/WebCore/platform/chromium/DragImageChromiumSkia.cpp b/WebCore/platform/chromium/DragImageChromiumSkia.cpp
index 24bd8fd..e5c1cee 100644
--- a/WebCore/platform/chromium/DragImageChromiumSkia.cpp
+++ b/WebCore/platform/chromium/DragImageChromiumSkia.cpp
@@ -68,9 +68,26 @@ DragImageRef scaleDragImage(DragImageRef image, FloatSize scale)
return scaledImage;
}
-DragImageRef dissolveDragImageToFraction(DragImageRef image, float)
+DragImageRef dissolveDragImageToFraction(DragImageRef image, float fraction)
{
- notImplemented();
+ if (!image)
+ return 0;
+
+ image->setIsOpaque(false);
+ image->lockPixels();
+
+ for (int row = 0; row < image->height(); ++row) {
+ for (int column = 0; column < image->width(); ++column) {
+ uint32_t* pixel = image->getAddr32(column, row);
+ *pixel = SkPreMultiplyARGB(SkColorGetA(*pixel) * fraction,
+ SkColorGetR(*pixel),
+ SkColorGetG(*pixel),
+ SkColorGetB(*pixel));
+ }
+ }
+
+ image->unlockPixels();
+
return image;
}
@@ -80,7 +97,12 @@ DragImageRef createDragImageFromImage(Image* image)
return 0;
NativeImageSkia* bitmap = image->nativeImageForCurrentFrame();
- return bitmap ? new SkBitmap(*bitmap) : 0;
+ if (!bitmap)
+ return 0;
+
+ SkBitmap* dragImage = new SkBitmap();
+ bitmap->copyTo(dragImage, SkBitmap::kARGB_8888_Config);
+ return dragImage;
}
DragImageRef createDragImageIconForCachedImage(CachedImage*)
diff --git a/WebCore/platform/chromium/FileSystemChromium.cpp b/WebCore/platform/chromium/FileSystemChromium.cpp
index 30674d9..975caf6 100644
--- a/WebCore/platform/chromium/FileSystemChromium.cpp
+++ b/WebCore/platform/chromium/FileSystemChromium.cpp
@@ -77,4 +77,34 @@ bool fileExists(const String& path)
return ChromiumBridge::fileExists(path);
}
+PlatformFileHandle openFile(const String& path, FileOpenMode mode)
+{
+ return ChromiumBridge::openFile(path, mode);
+}
+
+void closeFile(PlatformFileHandle& handle)
+{
+ return ChromiumBridge::closeFile(handle);
+}
+
+long long seekFile(PlatformFileHandle handle, long long offset, FileSeekOrigin origin)
+{
+ return ChromiumBridge::seekFile(handle, offset, origin);
+}
+
+bool truncateFile(PlatformFileHandle handle, long long offset)
+{
+ return ChromiumBridge::truncateFile(handle, offset);
+}
+
+int readFromFile(PlatformFileHandle handle, char* data, int length)
+{
+ return ChromiumBridge::readFromFile(handle, data, length);
+}
+
+int writeToFile(PlatformFileHandle handle, const char* data, int length)
+{
+ return ChromiumBridge::writeToFile(handle, data, length);
+}
+
} // namespace WebCore
diff --git a/WebCore/platform/chromium/WidgetChromium.cpp b/WebCore/platform/chromium/WidgetChromium.cpp
index 4e16e68..94afa0d 100644
--- a/WebCore/platform/chromium/WidgetChromium.cpp
+++ b/WebCore/platform/chromium/WidgetChromium.cpp
@@ -63,9 +63,10 @@ void Widget::paint(GraphicsContext*, const IntRect&)
{
}
-void Widget::setFocus()
+void Widget::setFocus(bool focused)
{
- ChromiumBridge::widgetSetFocus(this);
+ if (focused)
+ ChromiumBridge::widgetSetFocus(this);
}
void Widget::setIsSelected(bool)
diff --git a/WebCore/platform/efl/WidgetEfl.cpp b/WebCore/platform/efl/WidgetEfl.cpp
index 168477a..c07c8c4 100644
--- a/WebCore/platform/efl/WidgetEfl.cpp
+++ b/WebCore/platform/efl/WidgetEfl.cpp
@@ -199,7 +199,7 @@ void Widget::frameRectsChanged()
evas_object_resize(o, rect.width(), rect.height());
}
-void Widget::setFocus()
+void Widget::setFocus(bool focused)
{
}
diff --git a/WebCore/platform/graphics/FloatSize.h b/WebCore/platform/graphics/FloatSize.h
index 97ee00d..53a0071 100644
--- a/WebCore/platform/graphics/FloatSize.h
+++ b/WebCore/platform/graphics/FloatSize.h
@@ -31,7 +31,7 @@
#include "IntSize.h"
#include <wtf/MathExtras.h>
-#if PLATFORM(CG)
+#if PLATFORM(CG) || (PLATFORM(WX) && OS(DARWIN))
typedef struct CGSize CGSize;
#endif
@@ -75,7 +75,7 @@ public:
m_height < other.m_height ? m_height : other.m_height);
}
-#if PLATFORM(CG)
+#if PLATFORM(CG) || (PLATFORM(WX) && OS(DARWIN))
explicit FloatSize(const CGSize&); // don't do this implicitly since it's lossy
operator CGSize() const;
#endif
diff --git a/WebCore/platform/graphics/Font.cpp b/WebCore/platform/graphics/Font.cpp
index 7bdefba..21380be 100644
--- a/WebCore/platform/graphics/Font.cpp
+++ b/WebCore/platform/graphics/Font.cpp
@@ -175,7 +175,7 @@ void Font::drawText(GraphicsContext* context, const TextRun& run, const FloatPoi
#endif
#if USE(FONT_FAST_PATH)
- if (canUseGlyphCache(run))
+ if (codePath(run) != Complex)
return drawSimpleText(context, run, point, from, to);
#endif
@@ -190,11 +190,12 @@ float Font::floatWidth(const TextRun& run, HashSet<const SimpleFontData*>* fallb
#endif
#if USE(FONT_FAST_PATH)
- if (canUseGlyphCache(run)) {
+ CodePath codePathToUse = codePath(run);
+ if (codePathToUse != Complex) {
// If the complex text implementation cannot return fallback fonts, avoid
// returning them for simple text as well.
static bool returnFallbackFonts = canReturnFallbackFontsForComplexText();
- return floatWidthForSimpleText(run, 0, returnFallbackFonts ? fallbackFonts : 0);
+ return floatWidthForSimpleText(run, 0, returnFallbackFonts ? fallbackFonts : 0, codePathToUse == SimpleWithGlyphOverflow ? glyphOverflow : 0);
}
#endif
@@ -214,7 +215,7 @@ float Font::floatWidth(const TextRun& run, int extraCharsAvailable, int& charsCo
glyphName = "";
#if USE(FONT_FAST_PATH)
- if (canUseGlyphCache(run))
+ if (codePath(run) != Complex)
return floatWidthForSimpleText(run, 0);
#endif
@@ -231,7 +232,7 @@ FloatRect Font::selectionRectForText(const TextRun& run, const IntPoint& point,
to = (to == -1 ? run.length() : to);
#if USE(FONT_FAST_PATH)
- if (canUseGlyphCache(run))
+ if (codePath(run) != Complex)
return selectionRectForSimpleText(run, point, h, from, to);
#endif
@@ -246,7 +247,7 @@ int Font::offsetForPosition(const TextRun& run, int x, bool includePartialGlyphs
#endif
#if USE(FONT_FAST_PATH)
- if (canUseGlyphCache(run))
+ if (codePath(run) != Complex)
return offsetForPositionForSimpleText(run, x, includePartialGlyphs);
#endif
diff --git a/WebCore/platform/graphics/Font.h b/WebCore/platform/graphics/Font.h
index 62525b0..da546f0 100644
--- a/WebCore/platform/graphics/Font.h
+++ b/WebCore/platform/graphics/Font.h
@@ -26,9 +26,9 @@
#define Font_h
#include "CharacterNames.h"
-#include "TextRun.h"
#include "FontDescription.h"
#include "SimpleFontData.h"
+#include "TextRun.h"
#include "TypesettingFeatures.h"
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
@@ -83,9 +83,7 @@ public:
Font& operator=(const Font&);
bool operator==(const Font& other) const;
- bool operator!=(const Font& other) const {
- return !(*this == other);
- }
+ bool operator!=(const Font& other) const { return !(*this == other); }
const FontDescription& fontDescription() const { return m_fontDescription; }
@@ -152,6 +150,10 @@ public:
static void setShouldUseSmoothing(bool);
static bool shouldUseSmoothing();
+#if USE(FONT_FAST_PATH)
+ enum CodePath { Auto, Simple, Complex, SimpleWithGlyphOverflow };
+#endif
+
private:
#if ENABLE(SVG_FONTS)
void drawTextUsingSVGFont(GraphicsContext*, const TextRun&, const FloatPoint&, int from, int to) const;
@@ -162,11 +164,11 @@ private:
#endif
#if USE(FONT_FAST_PATH)
- bool canUseGlyphCache(const TextRun&) const;
+ CodePath codePath(const TextRun&) const;
void drawSimpleText(GraphicsContext*, const TextRun&, const FloatPoint&, int from, int to) const;
void drawGlyphs(GraphicsContext*, const SimpleFontData*, const GlyphBuffer&, int from, int to, const FloatPoint&) const;
void drawGlyphBuffer(GraphicsContext*, const GlyphBuffer&, const TextRun&, const FloatPoint&) const;
- float floatWidthForSimpleText(const TextRun&, GlyphBuffer*, HashSet<const SimpleFontData*>* fallbackFonts = 0) const;
+ float floatWidthForSimpleText(const TextRun&, GlyphBuffer*, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
int offsetForPositionForSimpleText(const TextRun&, int position, bool includePartialGlyphs) const;
FloatRect selectionRectForSimpleText(const TextRun&, const IntPoint&, int h, int from, int to) const;
@@ -183,7 +185,6 @@ private:
public:
// Useful for debugging the different font rendering code paths.
#if USE(FONT_FAST_PATH)
- enum CodePath { Auto, Simple, Complex };
static void setCodePath(CodePath);
static CodePath codePath();
static CodePath s_codePath;
@@ -197,7 +198,7 @@ public:
FontSelector* fontSelector() const;
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 bool treatAsZeroWidthSpace(UChar c) { return c < 0x20 || (c >= 0x7F && c < 0xA0) || (c >= 0x200c && c <= 0x200f) || (c >= 0x202a && c <= 0x202e) || c == 0xFFFC; }
static inline UChar normalizeSpaces(UChar character)
{
diff --git a/WebCore/platform/graphics/FontFastPath.cpp b/WebCore/platform/graphics/FontFastPath.cpp
index 6e2a744..f57ae5b 100644
--- a/WebCore/platform/graphics/FontFastPath.cpp
+++ b/WebCore/platform/graphics/FontFastPath.cpp
@@ -190,73 +190,64 @@ Font::CodePath Font::codePath()
return s_codePath;
}
-bool Font::canUseGlyphCache(const TextRun& run) const
+Font::CodePath Font::codePath(const TextRun& run) const
{
- switch (s_codePath) {
- case Auto:
- break;
- case Simple:
- return true;
- case Complex:
- return false;
- }
-
+ if (s_codePath != Auto)
+ return s_codePath;
+
// Start from 0 since drawing and highlighting also measure the characters before run->from
for (int i = 0; i < run.length(); i++) {
const UChar c = run[i];
if (c < 0x300) // U+0300 through U+036F Combining diacritical marks
continue;
if (c <= 0x36F)
- return false;
+ return Complex;
if (c < 0x0591 || c == 0x05BE) // U+0591 through U+05CF excluding U+05BE Hebrew combining marks, Hebrew punctuation Paseq, Sof Pasuq and Nun Hafukha
continue;
if (c <= 0x05CF)
- return false;
+ return Complex;
if (c < 0x0600) // U+0600 through U+1059 Arabic, Syriac, Thaana, Devanagari, Bengali, Gurmukhi, Gujarati, Oriya, Tamil, Telugu, Kannada, Malayalam, Sinhala, Thai, Lao, Tibetan, Myanmar
continue;
if (c <= 0x1059)
- return false;
+ return Complex;
if (c < 0x1100) // U+1100 through U+11FF Hangul Jamo (only Ancient Korean should be left here if you precompose; Modern Korean will be precomposed as a result of step A)
continue;
if (c <= 0x11FF)
- return false;
+ return Complex;
if (c < 0x1780) // U+1780 through U+18AF Khmer, Mongolian
continue;
if (c <= 0x18AF)
- return false;
+ return Complex;
if (c < 0x1900) // U+1900 through U+194F Limbu (Unicode 4.0)
continue;
if (c <= 0x194F)
- return false;
+ return Complex;
- // FIXME: we should not use complex text path for these characters.
-
if (c < 0x1E00) // U+1E00 through U+2000 characters with diacritics and stacked diacritics
continue;
if (c <= 0x2000)
- return false;
+ return SimpleWithGlyphOverflow;
if (c < 0x20D0) // U+20D0 through U+20FF Combining marks for symbols
continue;
if (c <= 0x20FF)
- return false;
+ return Complex;
if (c < 0xFE20) // U+FE20 through U+FE2F Combining half marks
continue;
if (c <= 0xFE2F)
- return false;
+ return Complex;
}
if (typesettingFeatures())
- return false;
-
- return true;
+ return Complex;
+ return Simple;
}
void Font::drawSimpleText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const
@@ -321,10 +312,18 @@ void Font::drawGlyphBuffer(GraphicsContext* context, const GlyphBuffer& glyphBuf
drawGlyphs(context, fontData, glyphBuffer, lastFrom, nextGlyph - lastFrom, startPoint);
}
-float Font::floatWidthForSimpleText(const TextRun& run, GlyphBuffer* glyphBuffer, HashSet<const SimpleFontData*>* fallbackFonts) const
+float Font::floatWidthForSimpleText(const TextRun& run, GlyphBuffer* glyphBuffer, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
{
- WidthIterator it(this, run, fallbackFonts);
+ WidthIterator it(this, run, fallbackFonts, glyphOverflow);
it.advance(run.length(), glyphBuffer);
+
+ if (glyphOverflow) {
+ glyphOverflow->top = max<int>(glyphOverflow->top, ceilf(-it.minGlyphBoundingBoxY()) - ascent());
+ glyphOverflow->bottom = max<int>(glyphOverflow->bottom, ceilf(it.maxGlyphBoundingBoxY()) - descent());
+ glyphOverflow->left = ceilf(it.firstGlyphOverflow());
+ glyphOverflow->right = ceilf(it.lastGlyphOverflow());
+ }
+
return it.m_runWidthSoFar;
}
diff --git a/WebCore/platform/graphics/GlyphBuffer.h b/WebCore/platform/graphics/GlyphBuffer.h
index edb804c..6f1fe7b 100644
--- a/WebCore/platform/graphics/GlyphBuffer.h
+++ b/WebCore/platform/graphics/GlyphBuffer.h
@@ -34,7 +34,7 @@
#include <wtf/UnusedParam.h>
#include <wtf/Vector.h>
-#if PLATFORM(CG)
+#if PLATFORM(CG) || (PLATFORM(WX) && OS(DARWIN))
#include <ApplicationServices/ApplicationServices.h>
#endif
@@ -58,7 +58,7 @@ typedef Glyph GlyphBufferGlyph;
// CG uses CGSize instead of FloatSize so that the result of advances()
// can be passed directly to CGContextShowGlyphsWithAdvances in FontMac.mm
-#if PLATFORM(CG)
+#if PLATFORM(CG) || (PLATFORM(WX) && OS(DARWIN))
typedef CGSize GlyphBufferAdvance;
#elif OS(WINCE)
// There is no cross-platform code that uses the height of GlyphBufferAdvance,
@@ -122,7 +122,7 @@ public:
float advanceAt(int index) const
{
-#if PLATFORM(CG)
+#if PLATFORM(CG) || (PLATFORM(WX) && OS(DARWIN))
return m_advances[index].width;
#elif OS(WINCE)
return m_advances[index];
@@ -153,7 +153,7 @@ public:
m_glyphs.append(glyph);
#endif
-#if PLATFORM(CG)
+#if PLATFORM(CG) || (PLATFORM(WX) && OS(DARWIN))
CGSize advance = { width, 0 };
m_advances.append(advance);
#elif OS(WINCE)
diff --git a/WebCore/platform/graphics/GlyphMetricsMap.h b/WebCore/platform/graphics/GlyphMetricsMap.h
index 49854be..5e13afe 100644
--- a/WebCore/platform/graphics/GlyphMetricsMap.h
+++ b/WebCore/platform/graphics/GlyphMetricsMap.h
@@ -29,7 +29,6 @@
#ifndef GlyphMetricsMap_h
#define GlyphMetricsMap_h
-#include "FloatRect.h"
#include <wtf/HashMap.h>
#include <wtf/OwnPtr.h>
#include <wtf/unicode/Unicode.h>
@@ -40,12 +39,7 @@ typedef unsigned short Glyph;
const float cGlyphSizeUnknown = -1;
-struct GlyphMetrics {
- float horizontalAdvance;
- FloatRect boundingBox;
-};
-
-class GlyphMetricsMap : public Noncopyable {
+template<class T> class GlyphMetricsMap : public Noncopyable {
public:
GlyphMetricsMap() : m_filledPrimaryPage(false) { }
~GlyphMetricsMap()
@@ -54,17 +48,12 @@ public:
deleteAllValues(*m_pages);
}
- GlyphMetrics metricsForGlyph(Glyph glyph)
+ T metricsForGlyph(Glyph glyph)
{
return locatePage(glyph / GlyphMetricsPage::size)->metricsForGlyph(glyph);
}
- float widthForGlyph(Glyph glyph)
- {
- return locatePage(glyph / GlyphMetricsPage::size)->metricsForGlyph(glyph).horizontalAdvance;
- }
-
- void setMetricsForGlyph(Glyph glyph, const GlyphMetrics& metrics)
+ void setMetricsForGlyph(Glyph glyph, const T& metrics)
{
locatePage(glyph / GlyphMetricsPage::size)->setMetricsForGlyph(glyph, metrics);
}
@@ -72,14 +61,14 @@ public:
private:
struct GlyphMetricsPage {
static const size_t size = 256; // Usually covers Latin-1 in a single page.
- GlyphMetrics m_metrics[size];
+ T m_metrics[size];
- GlyphMetrics metricsForGlyph(Glyph glyph) const { return m_metrics[glyph % size]; }
- void setMetricsForGlyph(Glyph glyph, const GlyphMetrics& metrics)
+ T metricsForGlyph(Glyph glyph) const { return m_metrics[glyph % size]; }
+ void setMetricsForGlyph(Glyph glyph, const T& metrics)
{
setMetricsForIndex(glyph % size, metrics);
}
- void setMetricsForIndex(unsigned index, const GlyphMetrics& metrics)
+ void setMetricsForIndex(unsigned index, const T& metrics)
{
m_metrics[index] = metrics;
}
@@ -94,11 +83,47 @@ private:
GlyphMetricsPage* locatePageSlowCase(unsigned pageNumber);
+ static T unknownMetrics();
+
bool m_filledPrimaryPage;
GlyphMetricsPage m_primaryPage; // We optimize for the page that contains glyph indices 0-255.
OwnPtr<HashMap<int, GlyphMetricsPage*> > m_pages;
};
+template<> inline float GlyphMetricsMap<float>::unknownMetrics()
+{
+ return cGlyphSizeUnknown;
+}
+
+template<> inline FloatRect GlyphMetricsMap<FloatRect>::unknownMetrics()
+{
+ return FloatRect(0, 0, cGlyphSizeUnknown, cGlyphSizeUnknown);
+}
+
+template<class T> typename GlyphMetricsMap<T>::GlyphMetricsPage* GlyphMetricsMap<T>::locatePageSlowCase(unsigned pageNumber)
+{
+ GlyphMetricsPage* page;
+ if (!pageNumber) {
+ ASSERT(!m_filledPrimaryPage);
+ page = &m_primaryPage;
+ m_filledPrimaryPage = true;
+ } else {
+ if (m_pages) {
+ if ((page = m_pages->get(pageNumber)))
+ return page;
+ } else
+ m_pages.set(new HashMap<int, GlyphMetricsPage*>);
+ page = new GlyphMetricsPage;
+ m_pages->set(pageNumber, page);
+ }
+
+ // Fill in the whole page with the unknown glyph information.
+ for (unsigned i = 0; i < GlyphMetricsPage::size; i++)
+ page->setMetricsForIndex(i, unknownMetrics());
+
+ return page;
+}
+
} // namespace WebCore
#endif
diff --git a/WebCore/platform/graphics/GlyphPageTreeNode.cpp b/WebCore/platform/graphics/GlyphPageTreeNode.cpp
index 59a5efb..dac26b3 100644
--- a/WebCore/platform/graphics/GlyphPageTreeNode.cpp
+++ b/WebCore/platform/graphics/GlyphPageTreeNode.cpp
@@ -124,6 +124,18 @@ GlyphPageTreeNode::~GlyphPageTreeNode()
delete m_systemFallbackChild;
}
+static bool fill(GlyphPage* pageToFill, unsigned offset, unsigned length, UChar* buffer, unsigned bufferLength, const SimpleFontData* fontData)
+{
+ if (!fontData->isSVGFont())
+ return pageToFill->fill(offset, length, buffer, bufferLength, fontData);
+
+ // SVG Fonts do not use the glyph page cache. Zero fill the glyph
+ // positions and return false to indicate the glyphs were not found.
+ for (unsigned i = 0; i < length; ++i)
+ pageToFill->setGlyphDataForIndex(offset + i, 0, 0);
+ return false;
+}
+
void GlyphPageTreeNode::initializePage(const FontData* fontData, unsigned pageNumber)
{
ASSERT(!m_page);
@@ -165,13 +177,15 @@ void GlyphPageTreeNode::initializePage(const FontData* fontData, unsigned pageNu
buffer[(int)'\t'] = ' ';
buffer[noBreakSpace] = ' ';
} else if (start == (leftToRightMark & ~(GlyphPage::size - 1))) {
- // LRM, RLM, LRE, RLE and PDF must not render at all.
+ // LRM, RLM, LRE, RLE, ZWNJ, ZWJ, and PDF must not render at all.
buffer[leftToRightMark - start] = zeroWidthSpace;
buffer[rightToLeftMark - start] = zeroWidthSpace;
buffer[leftToRightEmbed - start] = zeroWidthSpace;
buffer[rightToLeftEmbed - start] = zeroWidthSpace;
buffer[leftToRightOverride - start] = zeroWidthSpace;
buffer[rightToLeftOverride - start] = zeroWidthSpace;
+ buffer[zeroWidthNonJoiner - start] = zeroWidthSpace;
+ buffer[zeroWidthJoiner - start] = zeroWidthSpace;
buffer[popDirectionalFormatting - start] = zeroWidthSpace;
} else if (start == (objectReplacementCharacter & ~(GlyphPage::size - 1))) {
// Object replacement character must not render at all.
@@ -221,7 +235,7 @@ void GlyphPageTreeNode::initializePage(const FontData* fontData, unsigned pageNu
}
zeroFilled = true;
}
- haveGlyphs |= pageToFill->fill(from, to - from, buffer + from * (start < 0x10000 ? 1 : 2), (to - from) * (start < 0x10000 ? 1 : 2), range.fontData());
+ haveGlyphs |= fill(pageToFill, from, to - from, buffer + from * (start < 0x10000 ? 1 : 2), (to - from) * (start < 0x10000 ? 1 : 2), range.fontData());
if (scratchPage) {
ASSERT(to <= static_cast<int>(GlyphPage::size));
for (int j = from; j < to; j++) {
@@ -232,7 +246,7 @@ void GlyphPageTreeNode::initializePage(const FontData* fontData, unsigned pageNu
}
}
} else
- haveGlyphs = m_page->fill(0, GlyphPage::size, buffer, bufferLength, static_cast<const SimpleFontData*>(fontData));
+ haveGlyphs = fill(m_page.get(), 0, GlyphPage::size, buffer, bufferLength, static_cast<const SimpleFontData*>(fontData));
if (!haveGlyphs)
m_page = 0;
diff --git a/WebCore/platform/graphics/Gradient.cpp b/WebCore/platform/graphics/Gradient.cpp
index daf4754..0e961ad 100644
--- a/WebCore/platform/graphics/Gradient.cpp
+++ b/WebCore/platform/graphics/Gradient.cpp
@@ -96,7 +96,14 @@ void Gradient::addColorStop(float value, const Color& color)
m_stops.append(ColorStop(value, r, g, b, a));
m_stopsSorted = false;
+ platformDestroy();
+}
+void Gradient::addColorStop(const Gradient::ColorStop& stop)
+{
+ m_stops.append(stop);
+
+ m_stopsSorted = false;
platformDestroy();
}
diff --git a/WebCore/platform/graphics/Gradient.h b/WebCore/platform/graphics/Gradient.h
index b6911f3..2c877af 100644
--- a/WebCore/platform/graphics/Gradient.h
+++ b/WebCore/platform/graphics/Gradient.h
@@ -87,6 +87,8 @@ namespace WebCore {
}
virtual ~Gradient();
+ struct ColorStop;
+ void addColorStop(const ColorStop&);
void addColorStop(float, const Color&);
void getColor(float value, float* r, float* g, float* b, float* a) const;
@@ -97,7 +99,6 @@ namespace WebCore {
float r0() const { return m_r0; }
float r1() const { return m_r1; }
bool isRadial() const { return m_radial; }
- struct ColorStop;
const Vector<ColorStop>& getStops() const;
#else
#if PLATFORM(ANDROID)
diff --git a/WebCore/platform/graphics/GraphicsContext3D.h b/WebCore/platform/graphics/GraphicsContext3D.h
index 45f6f06..b64e9d3 100644
--- a/WebCore/platform/graphics/GraphicsContext3D.h
+++ b/WebCore/platform/graphics/GraphicsContext3D.h
@@ -479,6 +479,8 @@ namespace WebCore {
bool flipVertically,
AlphaOp alphaOp);
+ bool isGLES2Compliant() const;
+
//----------------------------------------------------------------------
// Entry points for WebGL.
//
@@ -607,16 +609,12 @@ namespace WebCore {
void stencilOp(unsigned long fail, unsigned long zfail, unsigned long zpass);
void stencilOpSeparate(unsigned long face, unsigned long fail, unsigned long zfail, unsigned long zpass);
- // These next several functions return an error code (0 if no errors) rather than using an ExceptionCode.
- // Currently they return -1 on any error.
int texImage2D(unsigned target, unsigned level, unsigned internalformat, unsigned width, unsigned height, unsigned border, unsigned format, unsigned type, 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, 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);
@@ -659,6 +657,9 @@ namespace WebCore {
// Helpers for notification about paint events
void beginPaint(WebGLRenderingContext* context);
void endPaint();
+#if PLATFORM(QT)
+ void paint(QPainter* painter, const QRect& rect) const;
+#endif
// Support for buffer creation and deletion
unsigned createBuffer();
diff --git a/WebCore/platform/graphics/MediaPlayer.cpp b/WebCore/platform/graphics/MediaPlayer.cpp
index 55fa900..ee82083 100644
--- a/WebCore/platform/graphics/MediaPlayer.cpp
+++ b/WebCore/platform/graphics/MediaPlayer.cpp
@@ -50,7 +50,8 @@
#elif PLATFORM(GTK)
#include "MediaPlayerPrivateGStreamer.h"
#elif PLATFORM(QT)
-#if QT_VERSION < 0x040700
+// QtMultimedia support is disabled currently.
+#if 1 || (QT_VERSION < 0x040700)
#include "MediaPlayerPrivatePhonon.h"
#else
#include "MediaPlayerPrivateQt.h"
diff --git a/WebCore/platform/graphics/SimpleFontData.cpp b/WebCore/platform/graphics/SimpleFontData.cpp
index 04b6ab1..1cc3b4c 100644
--- a/WebCore/platform/graphics/SimpleFontData.cpp
+++ b/WebCore/platform/graphics/SimpleFontData.cpp
@@ -92,6 +92,7 @@ SimpleFontData::SimpleFontData(const FontPlatformData& f, bool customFont, bool
// FIXME: is there a way we can get the space glyph from the SVGGlyphIdentifier above?
m_spaceGlyph = 0;
+ m_zeroWidthSpaceGlyph = 0;
determinePitch();
m_adjustedSpaceWidth = roundf(m_spaceWidth);
m_missingGlyphData.fontData = this;
@@ -136,11 +137,14 @@ void SimpleFontData::platformGlyphInit()
m_spaceWidth = 0;
m_adjustedSpaceWidth = 0;
determinePitch();
+ m_zeroWidthSpaceGlyph = 0;
m_missingGlyphData.fontData = this;
m_missingGlyphData.glyph = 0;
return;
}
+ m_zeroWidthSpaceGlyph = glyphPageZero->glyphDataForCharacter(0).glyph;
+
// Nasty hack to determine if we should round or ceil space widths.
// If the font is monospace or fake monospace we ceil to ensure that
// every character and the space are the same width. Otherwise we round.
@@ -155,14 +159,9 @@ void SimpleFontData::platformGlyphInit()
// See <http://bugs.webkit.org/show_bug.cgi?id=13178>
// Ask for the glyph for 0 to avoid paging in ZERO WIDTH SPACE. Control characters, including 0,
// are mapped to the ZERO WIDTH SPACE glyph.
- Glyph zeroWidthSpaceGlyph = glyphPageZero->glyphDataForCharacter(0).glyph;
- if (zeroWidthSpaceGlyph) {
- if (zeroWidthSpaceGlyph != m_spaceGlyph) {
- GlyphMetrics metrics;
- metrics.horizontalAdvance = 0;
- m_glyphToMetricsMap.setMetricsForGlyph(zeroWidthSpaceGlyph, metrics);
- } else
- LOG_ERROR("Font maps SPACE and ZERO WIDTH SPACE to the same glyph. Glyph width not overridden.");
+ if (m_zeroWidthSpaceGlyph == m_spaceGlyph) {
+ m_zeroWidthSpaceGlyph = 0;
+ LOG_ERROR("Font maps SPACE and ZERO WIDTH SPACE to the same glyph. Glyph width will not be overridden.");
}
m_missingGlyphData.fontData = this;
diff --git a/WebCore/platform/graphics/SimpleFontData.h b/WebCore/platform/graphics/SimpleFontData.h
index efdbba4..4c34f2b 100644
--- a/WebCore/platform/graphics/SimpleFontData.h
+++ b/WebCore/platform/graphics/SimpleFontData.h
@@ -26,6 +26,7 @@
#include "FontData.h"
#include "FontPlatformData.h"
+#include "FloatRect.h"
#include "GlyphMetricsMap.h"
#include "GlyphPageTreeNode.h"
#include "TypesettingFeatures.h"
@@ -35,6 +36,11 @@
typedef struct OpaqueATSUStyle* ATSUStyle;
#endif
+#if USE(CORE_TEXT)
+#include <ApplicationServices/ApplicationServices.h>
+#include <wtf/RetainPtr.h>
+#endif
+
#if (PLATFORM(WIN) && !OS(WINCE)) \
|| (OS(WINDOWS) && PLATFORM(WX))
#include <usp10.h>
@@ -60,7 +66,6 @@ class SharedBuffer;
class SVGFontData;
enum Pitch { UnknownPitch, FixedPitch, VariablePitch };
-enum GlyphMetricsMode { GlyphBoundingBox, GlyphWidthOnly };
class SimpleFontData : public FontData {
public:
@@ -81,14 +86,15 @@ public:
float xHeight() const { return m_xHeight; }
unsigned unitsPerEm() const { return m_unitsPerEm; }
- float widthForGlyph(Glyph glyph) const { return metricsForGlyph(glyph, GlyphWidthOnly).horizontalAdvance; }
- GlyphMetrics metricsForGlyph(Glyph, GlyphMetricsMode = GlyphBoundingBox) const;
- GlyphMetrics platformMetricsForGlyph(Glyph, GlyphMetricsMode) const;
+ FloatRect boundsForGlyph(Glyph) const;
+ float widthForGlyph(Glyph glyph) const;
+ FloatRect platformBoundsForGlyph(Glyph) const;
+ float platformWidthForGlyph(Glyph) const;
float spaceWidth() const { return m_spaceWidth; }
float adjustedSpaceWidth() const { return m_adjustedSpaceWidth; }
-#if PLATFORM(CG) || PLATFORM(CAIRO) || (OS(WINDOWS) && PLATFORM(WX))
+#if PLATFORM(CG) || PLATFORM(CAIRO) || PLATFORM(WX)
float syntheticBoldOffset() const { return m_syntheticBoldOffset; }
#endif
@@ -119,6 +125,8 @@ public:
#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN))
NSFont* getNSFont() const { return m_platformData.font(); }
+#elif (PLATFORM(WX) && OS(DARWIN))
+ NSFont* getNSFont() const { return m_platformData.nsFont(); }
#endif
#if USE(CORE_TEXT)
@@ -168,7 +176,8 @@ private:
|| (OS(WINDOWS) && PLATFORM(WX))
void initGDIFont();
void platformCommonDestroy();
- GlyphMetrics metricsForGDIGlyph(Glyph glyph) const;
+ FloatRect boundsForGDIGlyph(Glyph glyph) const;
+ float widthForGDIGlyph(Glyph glyph) const;
#endif
int m_ascent;
@@ -182,7 +191,8 @@ private:
FontPlatformData m_platformData;
- mutable GlyphMetricsMap m_glyphToMetricsMap;
+ mutable GlyphMetricsMap<FloatRect> m_glyphToBoundsMap;
+ mutable GlyphMetricsMap<float> m_glyphToWidthMap;
bool m_treatAsFixedPitch;
@@ -197,11 +207,13 @@ private:
float m_spaceWidth;
float m_adjustedSpaceWidth;
+ Glyph m_zeroWidthSpaceGlyph;
+
GlyphData m_missingGlyphData;
mutable SimpleFontData* m_smallCapsFontData;
-#if PLATFORM(CG) || PLATFORM(CAIRO) || (OS(WINDOWS) && PLATFORM(WX))
+#if PLATFORM(CG) || PLATFORM(CAIRO) || PLATFORM(WX)
float m_syntheticBoldOffset;
#endif
@@ -238,16 +250,32 @@ private:
#if !PLATFORM(QT)
-ALWAYS_INLINE GlyphMetrics SimpleFontData::metricsForGlyph(Glyph glyph, GlyphMetricsMode metricsMode) const
+ALWAYS_INLINE FloatRect SimpleFontData::boundsForGlyph(Glyph glyph) const
+{
+ if (glyph == m_zeroWidthSpaceGlyph && glyph)
+ return FloatRect();
+
+ FloatRect bounds = m_glyphToBoundsMap.metricsForGlyph(glyph);
+ if (bounds.width() != cGlyphSizeUnknown)
+ return bounds;
+
+ bounds = platformBoundsForGlyph(glyph);
+ m_glyphToBoundsMap.setMetricsForGlyph(glyph, bounds);
+ return bounds;
+}
+
+ALWAYS_INLINE float SimpleFontData::widthForGlyph(Glyph glyph) const
{
- GlyphMetrics metrics = m_glyphToMetricsMap.metricsForGlyph(glyph);
- if ((metricsMode == GlyphWidthOnly && metrics.horizontalAdvance != cGlyphSizeUnknown) || (metricsMode == GlyphBoundingBox && metrics.boundingBox.width() != cGlyphSizeUnknown))
- return metrics;
+ if (glyph == m_zeroWidthSpaceGlyph && glyph)
+ return 0;
- metrics = platformMetricsForGlyph(glyph, metricsMode);
- m_glyphToMetricsMap.setMetricsForGlyph(glyph, metrics);
+ float width = m_glyphToWidthMap.metricsForGlyph(glyph);
+ if (width != cGlyphSizeUnknown)
+ return width;
- return metrics;
+ width = platformWidthForGlyph(glyph);
+ m_glyphToWidthMap.setMetricsForGlyph(glyph, width);
+ return width;
}
#endif
diff --git a/WebCore/platform/graphics/TextRun.h b/WebCore/platform/graphics/TextRun.h
index 166b047..03d7b9f 100644
--- a/WebCore/platform/graphics/TextRun.h
+++ b/WebCore/platform/graphics/TextRun.h
@@ -29,7 +29,7 @@
namespace WebCore {
class RenderObject;
-class SVGPaintServer;
+class RenderSVGResource;
class TextRun {
public:
@@ -47,7 +47,7 @@ public:
, m_disableSpacing(false)
#if ENABLE(SVG_FONTS)
, m_referencingRenderObject(0)
- , m_activePaintServer(0)
+ , m_activePaintingResource(0)
#endif
{
}
@@ -66,7 +66,7 @@ public:
, m_disableSpacing(false)
#if ENABLE(SVG_FONTS)
, m_referencingRenderObject(0)
- , m_activePaintServer(0)
+ , m_activePaintingResource(0)
#endif
{
}
@@ -98,8 +98,8 @@ public:
RenderObject* referencingRenderObject() const { return m_referencingRenderObject; }
void setReferencingRenderObject(RenderObject* object) { m_referencingRenderObject = object; }
- SVGPaintServer* activePaintServer() const { return m_activePaintServer; }
- void setActivePaintServer(SVGPaintServer* object) { m_activePaintServer = object; }
+ RenderSVGResource* activePaintingResource() const { return m_activePaintingResource; }
+ void setActivePaintingResource(RenderSVGResource* object) { m_activePaintingResource = object; }
#endif
private:
@@ -117,7 +117,7 @@ private:
#if ENABLE(SVG_FONTS)
RenderObject* m_referencingRenderObject;
- SVGPaintServer* m_activePaintServer;
+ RenderSVGResource* m_activePaintingResource;
#endif
};
diff --git a/WebCore/platform/graphics/WidthIterator.cpp b/WebCore/platform/graphics/WidthIterator.cpp
index 9157310..996ce40 100644
--- a/WebCore/platform/graphics/WidthIterator.cpp
+++ b/WebCore/platform/graphics/WidthIterator.cpp
@@ -33,13 +33,14 @@
using namespace WTF;
using namespace Unicode;
+using namespace std;
namespace WebCore {
// According to http://www.unicode.org/Public/UNIDATA/UCD.html#Canonical_Combining_Class_Values
static const uint8_t hiraganaKatakanaVoicingMarksCombiningClass = 8;
-WidthIterator::WidthIterator(const Font* font, const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts)
+WidthIterator::WidthIterator(const Font* font, const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, bool accountForGlyphBounds)
: m_font(font)
, m_run(run)
, m_end(run.length())
@@ -47,6 +48,11 @@ WidthIterator::WidthIterator(const Font* font, const TextRun& run, HashSet<const
, m_runWidthSoFar(0)
, m_finalRoundingWidth(0)
, m_fallbackFonts(fallbackFonts)
+ , m_accountForGlyphBounds(accountForGlyphBounds)
+ , m_maxGlyphBoundingBoxY(numeric_limits<float>::min())
+ , m_minGlyphBoundingBoxY(numeric_limits<float>::max())
+ , m_firstGlyphOverflow(0)
+ , m_lastGlyphOverflow(0)
{
// If the padding is non-zero, count the number of spaces in the run
// and divide that by the padding for per space addition.
@@ -79,6 +85,7 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer)
float runWidthSoFar = m_runWidthSoFar;
float lastRoundingWidth = m_finalRoundingWidth;
+ FloatRect bounds;
const SimpleFontData* primaryFont = m_font->primaryFont();
const SimpleFontData* lastFontData = primaryFont;
@@ -175,6 +182,12 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer)
}
}
+ if (m_accountForGlyphBounds) {
+ bounds = fontData->boundsForGlyph(glyph);
+ if (!currentCharacter)
+ m_firstGlyphOverflow = max<float>(0, -bounds.x());
+ }
+
// Advance past the character we just dealt with.
cp += clusterLength;
currentCharacter += clusterLength;
@@ -205,6 +218,12 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer)
glyphBuffer->add(glyph, fontData, (rtl ? oldWidth + lastRoundingWidth : width));
lastRoundingWidth = width - oldWidth;
+
+ if (m_accountForGlyphBounds) {
+ m_maxGlyphBoundingBoxY = max(m_maxGlyphBoundingBoxY, bounds.bottom());
+ m_minGlyphBoundingBoxY = min(m_minGlyphBoundingBoxY, bounds.y());
+ m_lastGlyphOverflow = max<float>(0, bounds.right() - width);
+ }
}
m_currentCharacter = currentCharacter;
diff --git a/WebCore/platform/graphics/WidthIterator.h b/WebCore/platform/graphics/WidthIterator.h
index 7ca4198..d42a0c5 100644
--- a/WebCore/platform/graphics/WidthIterator.h
+++ b/WebCore/platform/graphics/WidthIterator.h
@@ -33,11 +33,16 @@ class SimpleFontData;
class TextRun;
struct WidthIterator {
- WidthIterator(const Font*, const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0);
+ WidthIterator(const Font*, const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0, bool accountForGlyphBounds = false);
void advance(int to, GlyphBuffer* = 0);
bool advanceOneCharacter(float& width, GlyphBuffer* = 0);
+ float maxGlyphBoundingBoxY() const { ASSERT(m_accountForGlyphBounds); return m_maxGlyphBoundingBoxY; }
+ float minGlyphBoundingBoxY() const { ASSERT(m_accountForGlyphBounds); return m_minGlyphBoundingBoxY; }
+ float firstGlyphOverflow() const { ASSERT(m_accountForGlyphBounds); return m_firstGlyphOverflow; }
+ float lastGlyphOverflow() const { ASSERT(m_accountForGlyphBounds); return m_lastGlyphOverflow; }
+
const Font* m_font;
const TextRun& m_run;
@@ -51,7 +56,13 @@ struct WidthIterator {
private:
UChar32 normalizeVoicingMarks(int currentCharacter);
+
HashSet<const SimpleFontData*>* m_fallbackFonts;
+ bool m_accountForGlyphBounds;
+ float m_maxGlyphBoundingBoxY;
+ float m_minGlyphBoundingBoxY;
+ float m_firstGlyphOverflow;
+ float m_lastGlyphOverflow;
};
}
diff --git a/WebCore/platform/graphics/cairo/FontCacheCairo.cpp b/WebCore/platform/graphics/cairo/FontCacheCairo.cpp
index d2b2f39..79b32b4 100644
--- a/WebCore/platform/graphics/cairo/FontCacheCairo.cpp
+++ b/WebCore/platform/graphics/cairo/FontCacheCairo.cpp
@@ -39,6 +39,11 @@ const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, cons
FcResult fresult;
FontPlatformData* prim = const_cast<FontPlatformData*>(&font.primaryFont()->platformData());
+ // FIXME: This should not happen, apparently. We are null-checking
+ // for now just to avoid crashing.
+ if (!prim || !prim->m_pattern)
+ return 0;
+
if (!prim->m_fallbacks)
prim->m_fallbacks = FcFontSort(NULL, prim->m_pattern, FcTrue, NULL, &fresult);
diff --git a/WebCore/platform/graphics/cairo/FontPlatformData.h b/WebCore/platform/graphics/cairo/FontPlatformData.h
index 3c926fe..d271f5b 100644
--- a/WebCore/platform/graphics/cairo/FontPlatformData.h
+++ b/WebCore/platform/graphics/cairo/FontPlatformData.h
@@ -28,9 +28,10 @@
#ifndef FontPlatformData_h
#define FontPlatformData_h
+#include <cairo.h>
#include "FontDescription.h"
#include "GlyphBuffer.h"
-#include <cairo.h>
+
#if defined(USE_FREETYPE)
#include <cairo-ft.h>
#include <fontconfig/fcfreetype.h>
@@ -38,7 +39,7 @@
#include <pango/pangocairo.h>
#elif PLATFORM(WIN)
#include <cairo-win32.h>
-#include "RefCountedHFONT.h"
+#include "RefCountedGDIHandle.h"
#include "StringImpl.h"
#else
#error "Must defined a font backend"
@@ -107,7 +108,7 @@ public:
#if !PLATFORM(WIN)
static bool init();
#else
- HFONT hfont() const { return m_font->hfont(); }
+ HFONT hfont() const { return m_font->handle(); }
bool useGDI() const { return m_useGDI; }
cairo_font_face_t* fontFace() const { return m_fontFace; }
#endif
@@ -164,7 +165,7 @@ public:
private:
void platformDataInit(HFONT, float size, HDC, WCHAR* faceName);
- RefPtr<RefCountedHFONT> m_font;
+ RefPtr<RefCountedGDIHandle<HFONT> > m_font;
cairo_font_face_t* m_fontFace;
bool m_useGDI;
#else
diff --git a/WebCore/platform/graphics/cairo/SimpleFontDataCairo.cpp b/WebCore/platform/graphics/cairo/SimpleFontDataCairo.cpp
index 0be45f6..0055078 100644
--- a/WebCore/platform/graphics/cairo/SimpleFontDataCairo.cpp
+++ b/WebCore/platform/graphics/cairo/SimpleFontDataCairo.cpp
@@ -83,9 +83,9 @@ SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDes
{
if (!m_smallCapsFontData) {
FontDescription desc = FontDescription(fontDescription);
- desc.setComputedSize(0.70f*fontDescription.computedSize());
- const FontPlatformData* pdata = new FontPlatformData(desc, desc.family().family());
- m_smallCapsFontData = new SimpleFontData(*pdata);
+ desc.setComputedSize(0.70f * fontDescription.computedSize());
+ FontPlatformData platformData(desc, desc.family().family());
+ m_smallCapsFontData = new SimpleFontData(platformData);
}
return m_smallCapsFontData;
}
@@ -114,7 +114,12 @@ void SimpleFontData::determinePitch()
m_treatAsFixedPitch = m_platformData.isFixedPitch();
}
-GlyphMetrics SimpleFontData::platformMetricsForGlyph(Glyph glyph, GlyphMetricsMode) const
+FloatRect SimpleFontData::platformBoundsForGlyph(Glyph) const
+{
+ return FloatRect();
+}
+
+float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
{
ASSERT(m_platformData.m_scaledFont);
@@ -125,10 +130,8 @@ GlyphMetrics SimpleFontData::platformMetricsForGlyph(Glyph glyph, GlyphMetricsMo
float w = (float)m_spaceWidth;
if (cairo_scaled_font_status(m_platformData.m_scaledFont) == CAIRO_STATUS_SUCCESS && extents.x_advance != 0)
w = (float)extents.x_advance;
-
- GlyphMetrics metrics;
- metrics.horizontalAdvance = w;
- return metrics;
+
+ return w;
}
}
diff --git a/WebCore/platform/graphics/cg/FontPlatformData.h b/WebCore/platform/graphics/cg/FontPlatformData.h
index da2b7e3..1da8916 100644
--- a/WebCore/platform/graphics/cg/FontPlatformData.h
+++ b/WebCore/platform/graphics/cg/FontPlatformData.h
@@ -24,7 +24,7 @@
#ifndef FontPlatformData_h
#define FontPlatformData_h
-#include "RefCountedHFONT.h"
+#include "RefCountedGDIHandle.h"
#include "StringImpl.h"
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
@@ -57,7 +57,7 @@ public:
FontPlatformData(WTF::HashTableDeletedValueType) : m_font(WTF::HashTableDeletedValue) { }
bool isHashTableDeletedValue() const { return m_font.isHashTableDeletedValue(); }
- HFONT hfont() const { return m_font->hfont(); }
+ HFONT hfont() const { return m_font->handle(); }
CGFontRef cgFont() const { return m_cgFont.get(); }
float size() const { return m_size; }
@@ -88,7 +88,7 @@ public:
private:
void platformDataInit(HFONT, float size, HDC, WCHAR* faceName);
- RefPtr<RefCountedHFONT> m_font;
+ RefPtr<RefCountedGDIHandle<HFONT> > m_font;
RetainPtr<CGFontRef> m_cgFont;
float m_size;
diff --git a/WebCore/platform/graphics/cg/ImageSourceCG.cpp b/WebCore/platform/graphics/cg/ImageSourceCG.cpp
index b4e1ca9..0b5f0b0 100644
--- a/WebCore/platform/graphics/cg/ImageSourceCG.cpp
+++ b/WebCore/platform/graphics/cg/ImageSourceCG.cpp
@@ -130,10 +130,12 @@ void ImageSource::setData(SharedBuffer* data, bool allDataReceived)
if (!m_decoder) {
m_decoder = CGImageSourceCreateIncremental(0);
} else if (allDataReceived) {
+#if !PLATFORM(WIN)
// 10.6 bug workaround: image sources with final=false fail to draw into PDF contexts, so re-create image source
// when data is complete. <rdar://problem/7874035> (<http://openradar.appspot.com/7874035>)
CFRelease(m_decoder);
m_decoder = CGImageSourceCreateIncremental(0);
+#endif
}
// Create a CGDataProvider to wrap the SharedBuffer.
data->ref();
diff --git a/WebCore/platform/graphics/chromium/FontLinux.cpp b/WebCore/platform/graphics/chromium/FontLinux.cpp
index fa549cd..700b3ed 100644
--- a/WebCore/platform/graphics/chromium/FontLinux.cpp
+++ b/WebCore/platform/graphics/chromium/FontLinux.cpp
@@ -64,7 +64,7 @@ static bool isCanvasMultiLayered(SkCanvas* canvas)
return !layerIterator.done();
}
-static bool adjustTextRenderMode(SkPaint* paint, bool isCanvasMultiLayered)
+static void adjustTextRenderMode(SkPaint* paint, bool isCanvasMultiLayered)
{
// Our layers only have a single alpha channel. This means that subpixel
// rendered text cannot be compositied correctly when the layer is
@@ -238,6 +238,23 @@ public:
} else {
if (!hb_utf16_script_run_next(&m_numCodePoints, &m_item.item, m_run.characters(), m_run.length(), &m_indexOfNextScriptRun))
return false;
+
+ // It is actually wrong to consider script runs at all in this code.
+ // Other WebKit code (e.g. Mac) segments complex text just by finding
+ // the longest span of text covered by a single font.
+ // But we currently need to call hb_utf16_script_run_next anyway to fill
+ // in the harfbuzz data structures to e.g. pick the correct script's shaper.
+ // So we allow that to run first, then do a second pass over the range it
+ // found and take the largest subregion that stays within a single font.
+ const FontData* glyphData = m_font->glyphDataForCharacter(m_item.string[m_item.item.pos], false, false).fontData;
+ int endOfRun;
+ for (endOfRun = 1; endOfRun < m_item.item.length; ++endOfRun) {
+ const FontData* nextGlyphData = m_font->glyphDataForCharacter(m_item.string[m_item.item.pos + endOfRun], false, false).fontData;
+ if (nextGlyphData != glyphData)
+ break;
+ }
+ m_item.item.length = endOfRun;
+ m_indexOfNextScriptRun = m_item.item.pos + endOfRun;
}
setupFontForScriptRun();
@@ -358,9 +375,7 @@ private:
void setupFontForScriptRun()
{
- const FontData* fontData = m_font->fontDataAt(0);
- if (!fontData->containsCharacters(m_item.string + m_item.item.pos, m_item.item.length))
- fontData = m_font->fontDataForCharacters(m_item.string + m_item.item.pos, m_item.item.length);
+ const FontData* fontData = m_font->glyphDataForCharacter(m_item.string[m_item.item.pos], false, false).fontData;
const FontPlatformData& platformData = fontData->fontDataForCharacter(' ')->platformData();
m_item.face = platformData.harfbuzzFace();
void* opaquePlatformData = const_cast<FontPlatformData*>(&platformData);
@@ -590,7 +605,7 @@ int Font::offsetForPositionForComplexText(const TextRun& run, int x,
if (walker.rtl())
basePosition -= walker.numCodePoints();
- if (x < walker.width()) {
+ if (x >= 0 && x < walker.width()) {
// The x value in question is within this script run. We consider
// each glyph in presentation order and stop when we find the one
// covering this position.
diff --git a/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp b/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp
index 2475e65..7b22bad 100644
--- a/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp
+++ b/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp
@@ -148,7 +148,7 @@ void FontPlatformData::setupPaint(SkPaint* paint) const
paint->setFakeBoldText(m_fakeBold);
paint->setTextSkewX(m_fakeItalic ? -SK_Scalar1 / 4 : 0);
- if (m_style.useAntiAlias == 1 || m_style.useAntiAlias == FontRenderStyle::NoPreference && isSkiaAntiAlias)
+ if (m_style.useAntiAlias == 1 || (m_style.useAntiAlias == FontRenderStyle::NoPreference && isSkiaAntiAlias))
paint->setLCDRenderText(m_style.useSubpixel == FontRenderStyle::NoPreference ? isSkiaSubpixelGlyphs : m_style.useSubpixel);
}
diff --git a/WebCore/platform/graphics/chromium/HarfbuzzSkia.cpp b/WebCore/platform/graphics/chromium/HarfbuzzSkia.cpp
index be3b0d0..4fd3ba0 100644
--- a/WebCore/platform/graphics/chromium/HarfbuzzSkia.cpp
+++ b/WebCore/platform/graphics/chromium/HarfbuzzSkia.cpp
@@ -139,7 +139,7 @@ static HB_Error getOutlinePoint(HB_Font hbFont, HB_Glyph glyph, int flags, hb_ui
uint16_t glyph16 = glyph;
SkPath path;
paint.getTextPath(&glyph16, sizeof(glyph16), 0, 0, &path);
- int numPoints = path.getPoints(NULL, 0);
+ int numPoints = path.getPoints(0, 0);
if (point >= numPoints)
return HB_Err_Invalid_SubTable;
SkPoint* points = reinterpret_cast<SkPoint*>(fastMalloc(sizeof(SkPoint) * (point + 1)));
diff --git a/WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp b/WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp
index 72bbfb4..f3d8b86 100644
--- a/WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp
+++ b/WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp
@@ -151,7 +151,12 @@ void SimpleFontData::determinePitch()
ReleaseDC(0, dc);
}
-GlyphMetrics SimpleFontData::platformMetricsForGlyph(Glyph glyph, GlyphMetricsMode) const
+FloatRect SimpleFontData::platformBoundsForGlyph(Glyph) const
+{
+ return FloatRect();
+}
+
+float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
{
HDC dc = GetDC(0);
HGDIOBJ oldFont = SelectObject(dc, m_platformData.hfont());
@@ -170,9 +175,7 @@ GlyphMetrics SimpleFontData::platformMetricsForGlyph(Glyph glyph, GlyphMetricsMo
SelectObject(dc, oldFont);
ReleaseDC(0, dc);
- GlyphMetrics metrics;
- metrics.horizontalAdvance = static_cast<float>(width);
- return metrics;
+ return static_cast<float>(width);
}
} // namespace WebCore
diff --git a/WebCore/platform/graphics/chromium/SimpleFontDataLinux.cpp b/WebCore/platform/graphics/chromium/SimpleFontDataLinux.cpp
index 8c639aa..d03c615 100644
--- a/WebCore/platform/graphics/chromium/SimpleFontDataLinux.cpp
+++ b/WebCore/platform/graphics/chromium/SimpleFontDataLinux.cpp
@@ -172,7 +172,12 @@ void SimpleFontData::determinePitch()
m_treatAsFixedPitch = platformData().isFixedPitch();
}
-GlyphMetrics SimpleFontData::platformMetricsForGlyph(Glyph glyph, GlyphMetricsMode /* metricsMode */) const
+FloatRect SimpleFontData::platformBoundsForGlyph(Glyph) const
+{
+ return FloatRect();
+}
+
+float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
{
SkASSERT(sizeof(glyph) == 2); // compile-time assert
@@ -186,9 +191,7 @@ GlyphMetrics SimpleFontData::platformMetricsForGlyph(Glyph glyph, GlyphMetricsMo
// Though WebKit supports non-integral advances, Skia only supports them
// for "subpixel" (distinct from LCD subpixel antialiasing) text, which
// we don't use.
- GlyphMetrics metrics;
- metrics.horizontalAdvance = round(SkScalarToFloat(width));
- return metrics;
+ return round(SkScalarToFloat(width));
}
} // namespace WebCore
diff --git a/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp b/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
index 0afb971..8f6c9e0 100644
--- a/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
+++ b/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
@@ -1111,6 +1111,7 @@ void MediaPlayerPrivateGStreamer::didEnd()
float now = currentTime();
if (now > 0) {
m_mediaDuration = now;
+ m_mediaDurationKnown = true;
m_player->durationChanged();
}
diff --git a/WebCore/platform/graphics/gtk/SimpleFontDataPango.cpp b/WebCore/platform/graphics/gtk/SimpleFontDataPango.cpp
index 0ed5393..bdfe237 100644
--- a/WebCore/platform/graphics/gtk/SimpleFontDataPango.cpp
+++ b/WebCore/platform/graphics/gtk/SimpleFontDataPango.cpp
@@ -84,9 +84,9 @@ SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDes
{
if (!m_smallCapsFontData) {
FontDescription desc = FontDescription(fontDescription);
- desc.setSpecifiedSize(0.70f*fontDescription.computedSize());
- const FontPlatformData* pdata = new FontPlatformData(desc, desc.family().family());
- m_smallCapsFontData = new SimpleFontData(*pdata);
+ desc.setSpecifiedSize(0.70f * fontDescription.computedSize());
+ FontPlatformData platformData(desc, desc.family().family());
+ m_smallCapsFontData = new SimpleFontData(platformData);
}
return m_smallCapsFontData;
}
@@ -119,7 +119,12 @@ void SimpleFontData::determinePitch()
m_treatAsFixedPitch = m_platformData.isFixedPitch();
}
-GlyphMetrics SimpleFontData::platformMetricsForGlyph(Glyph glyph, GlyphMetricsMode) const
+FloatRect SimpleFontData::platformBoundsForGlyph(Glyph) const
+{
+ return FloatRect();
+}
+
+float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
{
ASSERT(m_platformData.m_scaledFont);
@@ -127,13 +132,11 @@ GlyphMetrics SimpleFontData::platformMetricsForGlyph(Glyph glyph, GlyphMetricsMo
cairo_text_extents_t extents;
cairo_scaled_font_glyph_extents(m_platformData.m_scaledFont, &cglyph, 1, &extents);
- float w = (float)m_spaceWidth;
+ float width = (float)m_spaceWidth;
if (cairo_scaled_font_status(m_platformData.m_scaledFont) == CAIRO_STATUS_SUCCESS && extents.x_advance != 0)
- w = (float)extents.x_advance;
-
- GlyphMetrics metrics;
- metrics.horizontalAdvance = w;
- return metrics;
+ width = (float)extents.x_advance;
+
+ return width;
}
}
diff --git a/WebCore/platform/graphics/haiku/ImageBufferData.h b/WebCore/platform/graphics/haiku/ImageBufferData.h
index f978c34..7c676cd 100644
--- a/WebCore/platform/graphics/haiku/ImageBufferData.h
+++ b/WebCore/platform/graphics/haiku/ImageBufferData.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Maxime Simon <simon.maxime@gmail.com>
+ * Copyright (C) 2010 Stephan Aßmus <superstippi@gmx.de>
*
* All rights reserved.
*
@@ -28,16 +28,23 @@
#ifndef ImageBufferData_h
#define ImageBufferData_h
+#include <Bitmap.h>
+#include <View.h>
+
namespace WebCore {
- class IntSize;
+class IntSize;
+
+class ImageBufferData {
+public:
+ ImageBufferData(const IntSize&);
+ ~ImageBufferData();
- class ImageBufferData {
- public:
- ImageBufferData(const IntSize&);
- };
+ BBitmap m_bitmap;
+ BView m_view;
+};
-} // namespace WebCore
+} // namespace WebCore
-#endif // ImageBufferData_h
+#endif // ImageBufferData_h
diff --git a/WebCore/platform/graphics/haiku/ImageBufferHaiku.cpp b/WebCore/platform/graphics/haiku/ImageBufferHaiku.cpp
index 276c968..44943d7 100644
--- a/WebCore/platform/graphics/haiku/ImageBufferHaiku.cpp
+++ b/WebCore/platform/graphics/haiku/ImageBufferHaiku.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Maxime Simon <simon.maxime@gmail.com>
+ * Copyright (C) 2010 Stephan Aßmus <superstippi@gmx.de>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -20,28 +20,56 @@
* 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.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "ImageBuffer.h"
+#include "Base64.h"
#include "GraphicsContext.h"
#include "ImageData.h"
-#include "NotImplemented.h"
-
+#include "MIMETypeRegistry.h"
+#include "StillImageHaiku.h"
+#include <wtf/text/CString.h>
+#include <BitmapStream.h>
+#include <String.h>
+#include <TranslatorRoster.h>
namespace WebCore {
-ImageBufferData::ImageBufferData(const IntSize&)
+ImageBufferData::ImageBufferData(const IntSize& size)
+ : m_bitmap(BRect(0, 0, size.width() - 1, size.height() - 1), B_RGBA32, true)
+ , m_view(m_bitmap.Bounds(), "WebKit ImageBufferData", 0, 0)
{
+ // Always keep the bitmap locked, we are the only client.
+ m_bitmap.Lock();
+ m_bitmap.AddChild(&m_view);
+
+ // Fill with completely transparent color.
+ memset(m_bitmap.Bits(), 0, m_bitmap.BitsLength());
+
+ // Since ImageBuffer is used mainly for Canvas, explicitly initialize
+ // its view's graphics state with the corresponding canvas defaults
+ // NOTE: keep in sync with CanvasRenderingContext2D::State
+ m_view.SetLineMode(B_BUTT_CAP, B_MITER_JOIN, 10);
+ m_view.SetDrawingMode(B_OP_ALPHA);
+ m_view.SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_COMPOSITE);
}
-ImageBuffer::ImageBuffer(const IntSize&, ImageColorSpace imageColorSpace, bool& success)
- : m_data(IntSize())
+ImageBufferData::~ImageBufferData()
{
- notImplemented();
- success = false;
+ // Remove the view from the bitmap, keeping it from being free'd twice.
+ m_view.RemoveSelf();
+ m_bitmap.Unlock();
+}
+
+ImageBuffer::ImageBuffer(const IntSize& size, ImageColorSpace imageColorSpace, bool& success)
+ : m_data(size)
+ , m_size(size)
+{
+ m_context.set(new GraphicsContext(&m_data.m_view));
+ success = true;
}
ImageBuffer::~ImageBuffer()
@@ -50,47 +78,296 @@ ImageBuffer::~ImageBuffer()
GraphicsContext* ImageBuffer::context() const
{
- notImplemented();
- return 0;
+ ASSERT(m_data.m_view.Window());
+
+ return m_context.get();
}
-PassRefPtr<ImageData> ImageBuffer::getUnmultipliedImageData(const IntRect& rect) const
+Image* ImageBuffer::image() const
{
- notImplemented();
- return 0;
+ if (!m_image) {
+ // It's assumed that if image() is called, the actual rendering to the
+ // GraphicsContext must be done.
+ ASSERT(context());
+ m_data.m_view.Sync();
+ m_image = StillImage::create(m_data.m_bitmap);
+ }
+
+ return m_image.get();
}
-PassRefPtr<ImageData> ImageBuffer::getPremultipliedImageData(const IntRect& rect) const
+void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookUpTable)
{
- notImplemented();
- return 0;
+ uint8* rowData = reinterpret_cast<uint8*>(m_data.m_bitmap.Bits());
+ unsigned bytesPerRow = m_data.m_bitmap.BytesPerRow();
+ unsigned rows = m_size.height();
+ unsigned columns = m_size.width();
+ for (unsigned y = 0; y < rows; y++) {
+ uint8* pixel = rowData;
+ for (unsigned x = 0; x < columns; x++) {
+ // lookUpTable doesn't seem to support a LUT for each color channel
+ // separately (judging from the other ports). We don't need to
+ // convert from/to pre-multiplied color space since BBitmap storage
+ // is not pre-multiplied.
+ pixel[0] = lookUpTable[pixel[0]];
+ pixel[1] = lookUpTable[pixel[1]];
+ pixel[2] = lookUpTable[pixel[2]];
+ // alpha stays unmodified.
+ pixel += 4;
+ }
+ rowData += bytesPerRow;
+ }
}
-void ImageBuffer::putUnmultipliedImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint)
+static inline void convertFromData(const uint8* sourceRows, unsigned sourceBytesPerRow,
+ uint8* destRows, unsigned destBytesPerRow,
+ unsigned rows, unsigned columns)
{
- notImplemented();
+ for (unsigned y = 0; y < rows; y++) {
+ const uint8* sourcePixel = sourceRows;
+ uint8* destPixel = destRows;
+ for (unsigned x = 0; x < columns; x++) {
+ // RGBA -> BGRA or BGRA -> RGBA
+ destPixel[0] = sourcePixel[2];
+ destPixel[1] = sourcePixel[1];
+ destPixel[2] = sourcePixel[0];
+ destPixel[3] = sourcePixel[3];
+ destPixel += 4;
+ sourcePixel += 4;
+ }
+ sourceRows += sourceBytesPerRow;
+ destRows += destBytesPerRow;
+ }
}
-void ImageBuffer::putPremultipliedImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint)
+static inline void convertFromInternalData(const uint8* sourceRows, unsigned sourceBytesPerRow,
+ uint8* destRows, unsigned destBytesPerRow,
+ unsigned rows, unsigned columns,
+ bool premultiplied)
{
- notImplemented();
+ if (premultiplied) {
+ // Internal storage is not pre-multiplied, pre-multiply on the fly.
+ for (unsigned y = 0; y < rows; y++) {
+ const uint8* sourcePixel = sourceRows;
+ uint8* destPixel = destRows;
+ for (unsigned x = 0; x < columns; x++) {
+ // RGBA -> BGRA or BGRA -> RGBA
+ destPixel[0] = static_cast<uint16>(sourcePixel[2]) * sourcePixel[3] / 255;
+ destPixel[1] = static_cast<uint16>(sourcePixel[1]) * sourcePixel[3] / 255;
+ destPixel[2] = static_cast<uint16>(sourcePixel[0]) * sourcePixel[3] / 255;
+ destPixel[3] = sourcePixel[3];
+ destPixel += 4;
+ sourcePixel += 4;
+ }
+ sourceRows += sourceBytesPerRow;
+ destRows += destBytesPerRow;
+ }
+ } else {
+ convertFromData(sourceRows, sourceBytesPerRow,
+ destRows, destBytesPerRow,
+ rows, columns);
+ }
}
-String ImageBuffer::toDataURL(const String&) const
+static inline void convertToInternalData(const uint8* sourceRows, unsigned sourceBytesPerRow,
+ uint8* destRows, unsigned destBytesPerRow,
+ unsigned rows, unsigned columns,
+ bool premultiplied)
{
- notImplemented();
- return String();
+ if (premultiplied) {
+ // Internal storage is not pre-multiplied, de-multiply source data.
+ for (unsigned y = 0; y < rows; y++) {
+ const uint8* sourcePixel = sourceRows;
+ uint8* destPixel = destRows;
+ for (unsigned x = 0; x < columns; x++) {
+ // RGBA -> BGRA or BGRA -> RGBA
+ if (sourcePixel[3]) {
+ destPixel[0] = static_cast<uint16>(sourcePixel[2]) * 255 / sourcePixel[3];
+ destPixel[1] = static_cast<uint16>(sourcePixel[1]) * 255 / sourcePixel[3];
+ destPixel[2] = static_cast<uint16>(sourcePixel[0]) * 255 / sourcePixel[3];
+ destPixel[3] = sourcePixel[3];
+ } else {
+ destPixel[0] = 0;
+ destPixel[1] = 0;
+ destPixel[2] = 0;
+ destPixel[3] = 0;
+ }
+ destPixel += 4;
+ sourcePixel += 4;
+ }
+ sourceRows += sourceBytesPerRow;
+ destRows += destBytesPerRow;
+ }
+ } else {
+ convertFromData(sourceRows, sourceBytesPerRow,
+ destRows, destBytesPerRow,
+ rows, columns);
+ }
}
-Image* ImageBuffer::image() const
+static PassRefPtr<ImageData> getImageData(const IntRect& rect, const ImageBufferData& imageData, const IntSize& size, bool premultiplied)
+{
+ PassRefPtr<ImageData> result = ImageData::create(rect.width(), rect.height());
+ unsigned char* data = result->data()->data()->data();
+
+ // If the destination image is larger than the source image, the outside
+ // regions need to be transparent. This way is simply, although with a
+ // a slight overhead for the inside region.
+ if (rect.x() < 0 || rect.y() < 0 || (rect.x() + rect.width()) > size.width() || (rect.y() + rect.height()) > size.height())
+ memset(data, 0, result->data()->length());
+
+ // If the requested image is outside the source image, we can return at
+ // this point.
+ if (rect.x() > size.width() || rect.y() > size.height() || rect.right() < 0 || rect.bottom() < 0)
+ return result;
+
+ // Now we know there must be an intersection rect which we need to extract.
+ BRect sourceRect(0, 0, size.width() - 1, size.height() - 1);
+ sourceRect = BRect(rect) & sourceRect;
+
+ unsigned destBytesPerRow = 4 * rect.width();
+ unsigned char* destRows = data;
+ // Offset the destination pointer to point at the first pixel of the
+ // intersection rect.
+ destRows += (rect.x() - static_cast<int>(sourceRect.left)) * 4
+ + (rect.y() - static_cast<int>(sourceRect.top)) * destBytesPerRow;
+
+ const uint8* sourceRows = reinterpret_cast<const uint8*>(imageData.m_bitmap.Bits());
+ uint32 sourceBytesPerRow = imageData.m_bitmap.BytesPerRow();
+ // Offset the source pointer to point at the first pixel of the
+ // intersection rect.
+ sourceRows += static_cast<int>(sourceRect.left) * 4
+ + static_cast<int>(sourceRect.top) * sourceBytesPerRow;
+
+ unsigned rows = sourceRect.IntegerHeight() + 1;
+ unsigned columns = sourceRect.IntegerWidth() + 1;
+ convertFromInternalData(sourceRows, sourceBytesPerRow, destRows, destBytesPerRow,
+ rows, columns, premultiplied);
+
+ return result;
+}
+
+
+PassRefPtr<ImageData> ImageBuffer::getUnmultipliedImageData(const IntRect& rect) const
{
- notImplemented();
- return 0;
+ // Make sure all asynchronous drawing has finished
+ m_data.m_view.Sync();
+ return getImageData(rect, m_data, m_size, false);
}
-void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookUpTable)
+PassRefPtr<ImageData> ImageBuffer::getPremultipliedImageData(const IntRect& rect) const
+{
+ // Make sure all asynchronous drawing has finished
+ m_data.m_view.Sync();
+ return getImageData(rect, m_data, m_size, true);
+}
+
+static void putImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint, ImageBufferData& imageData, const IntSize& size, bool premultiplied)
+{
+ // If the source image is outside the destination image, we can return at
+ // this point.
+ // FIXME: Check if this isn't already done in WebCore.
+ if (destPoint.x() > size.width() || destPoint.y() > size.height()
+ || destPoint.x() + sourceRect.width() < 0
+ || destPoint.y() + sourceRect.height() < 0) {
+ return;
+ }
+
+ const unsigned char* sourceRows = source->data()->data()->data();
+ unsigned sourceBytesPerRow = 4 * source->width();
+ // Offset the source pointer to the first pixel of the source rect.
+ sourceRows += sourceRect.x() * 4 + sourceRect.y() * sourceBytesPerRow;
+
+ // We know there must be an intersection rect.
+ BRect destRect(destPoint.x(), destPoint.y(), sourceRect.width() - 1, sourceRect.height() - 1);
+ destRect = destRect & BRect(0, 0, size.width() - 1, size.height() - 1);
+
+ unsigned char* destRows = reinterpret_cast<unsigned char*>(imageData.m_bitmap.Bits());
+ uint32 destBytesPerRow = imageData.m_bitmap.BytesPerRow();
+ // Offset the source pointer to point at the first pixel of the
+ // intersection rect.
+ destRows += static_cast<int>(destRect.left) * 4
+ + static_cast<int>(destRect.top) * destBytesPerRow;
+
+ unsigned rows = sourceRect.height();
+ unsigned columns = sourceRect.width();
+ convertToInternalData(sourceRows, sourceBytesPerRow, destRows, destBytesPerRow,
+ rows, columns, premultiplied);
+}
+
+void ImageBuffer::putUnmultipliedImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint)
+{
+ // Make sure all asynchronous drawing has finished
+ m_data.m_view.Sync();
+ putImageData(source, sourceRect, destPoint, m_data, m_size, false);
+}
+
+void ImageBuffer::putPremultipliedImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint)
{
- notImplemented();
+ // Make sure all asynchronous drawing has finished
+ m_data.m_view.Sync();
+ putImageData(source, sourceRect, destPoint, m_data, m_size, true);
+}
+
+String ImageBuffer::toDataURL(const String& mimeType) const
+{
+ if (!MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType))
+ return "data:,";
+
+ BString mimeTypeString(mimeType);
+
+ uint32 translatorType = 0;
+
+ BTranslatorRoster* roster = BTranslatorRoster::Default();
+ translator_id* translators;
+ int32 translatorCount;
+ roster->GetAllTranslators(&translators, &translatorCount);
+ for (int32 i = 0; i < translatorCount; i++) {
+ // Skip translators that don't support archived BBitmaps as input data.
+ const translation_format* inputFormats;
+ int32 formatCount;
+ roster->GetInputFormats(translators[i], &inputFormats, &formatCount);
+ bool supportsBitmaps = false;
+ for (int32 j = 0; j < formatCount; j++) {
+ if (inputFormats[j].type == B_TRANSLATOR_BITMAP) {
+ supportsBitmaps = true;
+ break;
+ }
+ }
+ if (!supportsBitmaps)
+ continue;
+
+ const translation_format* outputFormats;
+ roster->GetOutputFormats(translators[i], &outputFormats, &formatCount);
+ for (int32 j = 0; j < formatCount; j++) {
+ if (outputFormats[j].group == B_TRANSLATOR_BITMAP
+ && mimeTypeString == outputFormats[j].MIME) {
+ translatorType = outputFormats[j].type;
+ }
+ }
+ if (translatorType)
+ break;
+ }
+
+
+ BMallocIO translatedStream;
+ BBitmap* bitmap = const_cast<BBitmap*>(&m_data.m_bitmap);
+ // BBitmapStream doesn't take "const Bitmap*"...
+ BBitmapStream bitmapStream(bitmap);
+ if (roster->Translate(&bitmapStream, 0, 0, &translatedStream, translatorType,
+ B_TRANSLATOR_BITMAP, mimeType.utf8().data()) != B_OK) {
+ bitmapStream.DetachBitmap(&bitmap);
+ return "data:,";
+ }
+
+ bitmapStream.DetachBitmap(&bitmap);
+
+ Vector<char> encodedBuffer;
+ base64Encode(reinterpret_cast<const char*>(translatedStream.Buffer()),
+ translatedStream.BufferLength(), encodedBuffer);
+
+ return String::format("data:%s;base64,%s", mimeType.utf8().data(),
+ encodedBuffer.data());
}
} // namespace WebCore
diff --git a/WebCore/platform/graphics/haiku/SimpleFontDataHaiku.cpp b/WebCore/platform/graphics/haiku/SimpleFontDataHaiku.cpp
index f429ab5..96027cc 100644
--- a/WebCore/platform/graphics/haiku/SimpleFontDataHaiku.cpp
+++ b/WebCore/platform/graphics/haiku/SimpleFontDataHaiku.cpp
@@ -34,18 +34,15 @@
#include "FontCache.h"
#include "FontDescription.h"
#include "NotImplemented.h"
-#include <Rect.h>
-#include <unicode/uchar.h>
-#include <unicode/unorm.h>
+#include "TextEncoding.h"
+#include <wtf/text/CString.h>
-extern int charUnicodeToUTF8HACK(unsigned short, char*);
-
namespace WebCore {
void SimpleFontData::platformInit()
{
- BFont* font = m_platformData.font();
+ const BFont* font = m_platformData.font();
if (!font)
return;
@@ -76,8 +73,8 @@ SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDes
if (!m_smallCapsFontData) {
FontDescription desc = FontDescription(fontDescription);
desc.setSpecifiedSize(0.70f * fontDescription.computedSize());
- const FontPlatformData* fontPlatformData = new FontPlatformData(desc, desc.family().family());
- m_smallCapsFontData = new SimpleFontData(*fontPlatformData);
+ FontPlatformData fontPlatformData(desc, desc.family().family());
+ m_smallCapsFontData = new SimpleFontData(fontPlatformData);
}
return m_smallCapsFontData;
}
@@ -95,15 +92,14 @@ void SimpleFontData::determinePitch()
GlyphMetrics SimpleFontData::platformMetricsForGlyph(Glyph glyph, GlyphMetricsMode) const
{
+ GlyphMetrics metrics;
if (!m_platformData.font())
- return 0;
+ return metrics;
- char charArray[4];
+ CString encoded = UTF8Encoding().encode(static_cast<UChar*>(&glyph), 1,
+ URLEncodedEntitiesForUnencodables);
float escapements[1];
-
- charUnicodeToUTF8HACK(glyph, charArray);
- m_platformData.font()->GetEscapements(charArray, 1, escapements);
- GlyphMetrics metrics;
+ m_platformData.font()->GetEscapements(encoded.data(), 1, escapements);
metrics.horizontalAdvance = escapements[0] * m_platformData.font()->Size();
return metrics;
}
diff --git a/WebCore/platform/graphics/mac/ComplexTextController.cpp b/WebCore/platform/graphics/mac/ComplexTextController.cpp
index b501293..efb92f8 100644
--- a/WebCore/platform/graphics/mac/ComplexTextController.cpp
+++ b/WebCore/platform/graphics/mac/ComplexTextController.cpp
@@ -25,7 +25,9 @@
#include "config.h"
#include "ComplexTextController.h"
+#include <ApplicationServices/ApplicationServices.h>
#include "CharacterNames.h"
+#include "FloatSize.h"
#include "Font.h"
#include "TextBreakIterator.h"
@@ -547,12 +549,12 @@ void ComplexTextController::adjustGlyphsAndAdvances()
m_adjustedAdvances.append(advance);
m_adjustedGlyphs.append(glyph);
- GlyphMetrics glyphMetrics = fontData->metricsForGlyph(glyph);
- glyphMetrics.boundingBox.move(glyphOrigin.x, glyphOrigin.y);
- m_minGlyphBoundingBoxX = min(m_minGlyphBoundingBoxX, glyphMetrics.boundingBox.x());
- m_maxGlyphBoundingBoxX = max(m_maxGlyphBoundingBoxX, glyphMetrics.boundingBox.right());
- m_minGlyphBoundingBoxY = min(m_minGlyphBoundingBoxY, glyphMetrics.boundingBox.y());
- m_maxGlyphBoundingBoxY = max(m_maxGlyphBoundingBoxY, glyphMetrics.boundingBox.bottom());
+ FloatRect glyphBounds = fontData->boundsForGlyph(glyph);
+ glyphBounds.move(glyphOrigin.x, glyphOrigin.y);
+ m_minGlyphBoundingBoxX = min(m_minGlyphBoundingBoxX, glyphBounds.x());
+ m_maxGlyphBoundingBoxX = max(m_maxGlyphBoundingBoxX, glyphBounds.right());
+ m_minGlyphBoundingBoxY = min(m_minGlyphBoundingBoxY, glyphBounds.y());
+ m_maxGlyphBoundingBoxY = max(m_maxGlyphBoundingBoxY, glyphBounds.bottom());
glyphOrigin.x += advance.width;
glyphOrigin.y += advance.height;
diff --git a/WebCore/platform/graphics/mac/ComplexTextController.h b/WebCore/platform/graphics/mac/ComplexTextController.h
index 280327f..55cde29 100644
--- a/WebCore/platform/graphics/mac/ComplexTextController.h
+++ b/WebCore/platform/graphics/mac/ComplexTextController.h
@@ -25,6 +25,7 @@
#ifndef ComplexTextController_h
#define ComplexTextController_h
+#include <ApplicationServices/ApplicationServices.h>
#include "GlyphBuffer.h"
#include <wtf/HashSet.h>
#include <wtf/PassRefPtr.h>
diff --git a/WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp b/WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp
index 82c314e..af210df 100644
--- a/WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp
+++ b/WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp
@@ -235,6 +235,11 @@ void GraphicsContext3D::endPaint()
{
}
+bool GraphicsContext3D::isGLES2Compliant() const
+{
+ return false;
+}
+
void GraphicsContext3D::reshape(int width, int height)
{
if (width == m_currentWidth && height == m_currentHeight || !m_contextObj)
@@ -1141,8 +1146,20 @@ void GraphicsContext3D::getFramebufferAttachmentParameteriv(unsigned long target
void GraphicsContext3D::getIntegerv(unsigned long pname, int* value)
{
- ensureContext(m_contextObj);
- ::glGetIntegerv(pname, value);
+ // Need to emulate IMPLEMENTATION_COLOR_READ_FORMAT/TYPE for GL. Any valid
+ // combination should work, but GL_RGB/GL_UNSIGNED_BYTE might be the most
+ // useful for desktop WebGL users.
+ ensureContext(m_contextObj);
+ switch (pname) {
+ case IMPLEMENTATION_COLOR_READ_FORMAT:
+ *value = GL_RGB;
+ break;
+ case IMPLEMENTATION_COLOR_READ_TYPE:
+ *value = GL_UNSIGNED_BYTE;
+ break;
+ default:
+ ::glGetIntegerv(pname, value);
+ }
}
void GraphicsContext3D::getProgramiv(WebGLProgram* program, unsigned long pname, int* value)
@@ -1278,39 +1295,18 @@ long GraphicsContext3D::getVertexAttribOffset(unsigned long index, unsigned long
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.
+ ensureContext(m_contextObj);
+
::glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
return 0;
}
-int GraphicsContext3D::texImage2D(unsigned target, unsigned level, Image* image, bool flipY, bool premultiplyAlpha)
-{
- ensureContext(m_contextObj);
- Vector<uint8_t> imageData;
- unsigned int format, internalFormat;
- if (!extractImageData(image, flipY, premultiplyAlpha, imageData, &format, &internalFormat))
- return -1;
- ::glTexImage2D(target, level, internalFormat, image->width(), image->height(), 0, format, GL_UNSIGNED_BYTE, imageData.data());
- return 0;
-}
-
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
- // FIXME: Need to do bounds checking on the buffer here.
- ::glTexSubImage2D(target, level, xoff, yoff, width, height, format, type, pixels);
- return 0;
-}
+ ensureContext(m_contextObj);
-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
- ensureContext(m_contextObj);
- Vector<uint8_t> imageData;
- unsigned int format, internalFormat;
- if (!extractImageData(image, flipY, premultiplyAlpha, imageData, &format, &internalFormat))
- return -1;
- ::glTexSubImage2D(target, level, xoff, yoff, image->width(), image->height(), format, GL_UNSIGNED_BYTE, imageData.data());
+ ::glTexSubImage2D(target, level, xoff, yoff, width, height, format, type, pixels);
return 0;
}
diff --git a/WebCore/platform/graphics/mac/SimpleFontDataATSUI.mm b/WebCore/platform/graphics/mac/SimpleFontDataATSUI.mm
new file mode 100644
index 0000000..beea018
--- /dev/null
+++ b/WebCore/platform/graphics/mac/SimpleFontDataATSUI.mm
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2005, 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Alexey Proskuryakov
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "SimpleFontData.h"
+
+#if USE(ATSUI)
+
+#import "Font.h"
+#import "FontCache.h"
+#import "FontDescription.h"
+#import <ApplicationServices/ApplicationServices.h>
+#import <AppKit/AppKit.h>
+#import <wtf/Assertions.h>
+
+using namespace std;
+
+namespace WebCore {
+
+void SimpleFontData::checkShapesArabic() const
+{
+ ASSERT(!m_checkedShapesArabic);
+
+ m_checkedShapesArabic = true;
+
+ ATSUFontID fontID = m_platformData.m_atsuFontID;
+ if (!fontID) {
+ LOG_ERROR("unable to get ATSUFontID for %@", m_platformData.font());
+ return;
+ }
+
+ // This function is called only on fonts that contain Arabic glyphs. Our
+ // heuristic is that if such a font has a glyph metamorphosis table, then
+ // it includes shaping information for Arabic.
+ FourCharCode tables[] = { 'morx', 'mort' };
+ for (unsigned i = 0; i < sizeof(tables) / sizeof(tables[0]); ++i) {
+ ByteCount tableSize;
+ OSStatus status = ATSFontGetTable(fontID, tables[i], 0, 0, 0, &tableSize);
+ if (status == noErr) {
+ m_shapesArabic = true;
+ return;
+ }
+
+ if (status != kATSInvalidFontTableAccess)
+ LOG_ERROR("ATSFontGetTable failed (%d)", status);
+ }
+}
+
+} // namespace WebCore
+
+#endif
diff --git a/WebCore/platform/graphics/mac/SimpleFontDataCoreText.cpp b/WebCore/platform/graphics/mac/SimpleFontDataCoreText.cpp
new file mode 100644
index 0000000..fc67a19
--- /dev/null
+++ b/WebCore/platform/graphics/mac/SimpleFontDataCoreText.cpp
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2005, 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Alexey Proskuryakov
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "SimpleFontData.h"
+
+#if USE(CORE_TEXT)
+
+#import "Font.h"
+#import "FontCache.h"
+#import "FontDescription.h"
+#import <ApplicationServices/ApplicationServices.h>
+
+using namespace std;
+
+namespace WebCore {
+
+CTFontRef SimpleFontData::getCTFont() const
+{
+ if (getNSFont())
+ return toCTFontRef(getNSFont());
+ if (!m_CTFont)
+ m_CTFont.adoptCF(CTFontCreateWithGraphicsFont(m_platformData.cgFont(), m_platformData.size(), 0, 0));
+ return m_CTFont.get();
+}
+
+CFDictionaryRef SimpleFontData::getCFStringAttributes(TypesettingFeatures typesettingFeatures) const
+{
+ 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 allowLigatures = platformData().allowsLigatures() || (typesettingFeatures & Ligatures);
+
+ static const int ligaturesNotAllowedValue = 0;
+ static CFNumberRef ligaturesNotAllowed = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &ligaturesNotAllowedValue);
+
+ static const int ligaturesAllowedValue = 1;
+ static CFNumberRef ligaturesAllowed = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &ligaturesAllowedValue);
+
+ 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 };
+ attributesDictionary.adoptCF(CFDictionaryCreate(0, 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 };
+ attributesDictionary.adoptCF(CFDictionaryCreate(0, keysWithKerningEnabled, valuesWithKerningEnabled,
+ sizeof(keysWithKerningEnabled) / sizeof(*keysWithKerningEnabled),
+ &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+ }
+
+ return attributesDictionary.get();
+}
+
+} // namespace WebCore
+
+#endif
diff --git a/WebCore/platform/graphics/mac/SimpleFontDataMac.mm b/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
index 562f56e..7f1a72e 100644
--- a/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
+++ b/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
@@ -45,6 +45,7 @@
#import <wtf/Assertions.h>
#import <wtf/StdLibExtras.h>
#import <wtf/RetainPtr.h>
+#import <wtf/UnusedParam.h>
@interface NSFont (WebAppKitSecretAPI)
- (BOOL)_isFakeFixedPitch;
@@ -407,7 +408,24 @@ void SimpleFontData::determinePitch()
[name caseInsensitiveCompare:@"MonotypeCorsiva"] != NSOrderedSame;
}
-GlyphMetrics SimpleFontData::platformMetricsForGlyph(Glyph glyph, GlyphMetricsMode metricsMode) const
+FloatRect SimpleFontData::platformBoundsForGlyph(Glyph glyph) const
+{
+ FloatRect boundingBox;
+#ifndef BUILDING_ON_TIGER
+ CGRect box;
+ CGFontGetGlyphBBoxes(platformData().cgFont(), &glyph, 1, &box);
+ float pointSize = platformData().m_size;
+ CGFloat scale = pointSize / unitsPerEm();
+ boundingBox = CGRectApplyAffineTransform(box, CGAffineTransformMakeScale(scale, -scale));
+ if (m_syntheticBoldOffset)
+ boundingBox.setWidth(boundingBox.width() + m_syntheticBoldOffset);
+#else
+ UNUSED_PARAM(glyph);
+#endif
+ return boundingBox;
+}
+
+float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
{
NSFont* font = platformData().font();
float pointSize = platformData().m_size;
@@ -417,99 +435,7 @@ GlyphMetrics SimpleFontData::platformMetricsForGlyph(Glyph glyph, GlyphMetricsMo
LOG_ERROR("Unable to cache glyph widths for %@ %f", [font displayName], pointSize);
advance.width = 0;
}
- GlyphMetrics metrics;
- metrics.horizontalAdvance = advance.width + m_syntheticBoldOffset;
- if (metricsMode == GlyphBoundingBox) {
-#ifndef BUILDING_ON_TIGER
- CGRect boundingBox;
- CGFontGetGlyphBBoxes(platformData().cgFont(), &glyph, 1, &boundingBox);
- CGFloat scale = pointSize / unitsPerEm();
- metrics.boundingBox = CGRectApplyAffineTransform(boundingBox, CGAffineTransformMakeScale(scale, -scale));
- if (m_syntheticBoldOffset)
- metrics.boundingBox.setWidth(metrics.boundingBox.width() + m_syntheticBoldOffset);
-#endif
- }
- return metrics;
-}
-
-#if USE(ATSUI)
-void SimpleFontData::checkShapesArabic() const
-{
- ASSERT(!m_checkedShapesArabic);
-
- m_checkedShapesArabic = true;
-
- ATSUFontID fontID = m_platformData.m_atsuFontID;
- if (!fontID) {
- LOG_ERROR("unable to get ATSUFontID for %@", m_platformData.font());
- return;
- }
-
- // This function is called only on fonts that contain Arabic glyphs. Our
- // heuristic is that if such a font has a glyph metamorphosis table, then
- // it includes shaping information for Arabic.
- FourCharCode tables[] = { 'morx', 'mort' };
- for (unsigned i = 0; i < sizeof(tables) / sizeof(tables[0]); ++i) {
- ByteCount tableSize;
- OSStatus status = ATSFontGetTable(fontID, tables[i], 0, 0, 0, &tableSize);
- if (status == noErr) {
- m_shapesArabic = true;
- return;
- }
-
- if (status != kATSInvalidFontTableAccess)
- LOG_ERROR("ATSFontGetTable failed (%d)", status);
- }
-}
-#endif
-
-#if USE(CORE_TEXT)
-CTFontRef SimpleFontData::getCTFont() const
-{
- if (getNSFont())
- return toCTFontRef(getNSFont());
- if (!m_CTFont)
- m_CTFont.adoptCF(CTFontCreateWithGraphicsFont(m_platformData.cgFont(), m_platformData.size(), NULL, NULL));
- return m_CTFont.get();
-}
-
-CFDictionaryRef SimpleFontData::getCFStringAttributes(TypesettingFeatures typesettingFeatures) const
-{
- 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 allowLigatures = platformData().allowsLigatures() || (typesettingFeatures & Ligatures);
-
- static const int ligaturesNotAllowedValue = 0;
- static CFNumberRef ligaturesNotAllowed = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &ligaturesNotAllowedValue);
-
- static const int ligaturesAllowedValue = 1;
- static CFNumberRef ligaturesAllowed = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &ligaturesAllowedValue);
-
- 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 };
- 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 };
- attributesDictionary.adoptCF(CFDictionaryCreate(NULL, keysWithKerningEnabled, valuesWithKerningEnabled,
- sizeof(keysWithKerningEnabled) / sizeof(*keysWithKerningEnabled),
- &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
- }
-
- return attributesDictionary.get();
+ return advance.width + m_syntheticBoldOffset;
}
-#endif
-
} // namespace WebCore
diff --git a/WebCore/platform/graphics/opentype/OpenTypeSanitizer.cpp b/WebCore/platform/graphics/opentype/OpenTypeSanitizer.cpp
index b4cdb09..14aed0d 100644
--- a/WebCore/platform/graphics/opentype/OpenTypeSanitizer.cpp
+++ b/WebCore/platform/graphics/opentype/OpenTypeSanitizer.cpp
@@ -52,15 +52,16 @@ PassRefPtr<SharedBuffer> OpenTypeSanitizer::sanitize()
// A transcoded font is usually smaller than an original font.
// However, it can be slightly bigger than the original one due to
// name table replacement and/or padding for glyf table.
- static const size_t padLen = 20 * 1024; // 20 kB
+ //
+ // With WOFF fonts, however, we'll be decompressing, so the result can be
+ // much larger than the original.
- OwnArrayPtr<unsigned char> transcodeRawBuffer(new unsigned char[m_buffer->size() + padLen]);
- ots::MemoryStream output(transcodeRawBuffer.get(), m_buffer->size() + padLen);
+ ots::ExpandingMemoryStream output(m_buffer->size(), maxWebFontSize);
if (!ots::Process(&output, reinterpret_cast<const uint8_t*>(m_buffer->data()), m_buffer->size()))
return 0;
const size_t transcodeLen = output.Tell();
- return SharedBuffer::create(transcodeRawBuffer.get(), transcodeLen);
+ return SharedBuffer::create(static_cast<unsigned char*>(output.get()), transcodeLen);
}
} // namespace WebCore
diff --git a/WebCore/platform/graphics/qt/FontQt.cpp b/WebCore/platform/graphics/qt/FontQt.cpp
index 974c179..946faeb 100644
--- a/WebCore/platform/graphics/qt/FontQt.cpp
+++ b/WebCore/platform/graphics/qt/FontQt.cpp
@@ -180,13 +180,7 @@ float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFon
String sanitized = Font::normalizeSpaces(String(run.characters(), run.length()));
QString string = fromRawDataWithoutRef(sanitized);
- QTextLayout layout(string, font());
- QTextLine line = setupLayout(&layout, run);
-#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)
- int w = int(line.horizontalAdvance());
-#else
- int w = int(line.naturalTextWidth());
-#endif
+ int w = QFontMetrics(font()).width(string);
// WebKit expects us to ignore word spacing on the first character (as opposed to what Qt does)
if (treatAsSpace(run[0]))
w -= m_wordSpacing;
diff --git a/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp b/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
index b0dd289..8dfb967 100644
--- a/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
+++ b/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
@@ -154,8 +154,7 @@ public:
~GraphicsContext3DInternal();
bool isContextValid() { return m_contextValid; }
-
-
+ QGLWidget* getOwnerGLWidget(QWebPageClient* webPageClient);
glActiveTextureType activeTexture;
glAttachShaderType attachShader;
@@ -248,6 +247,7 @@ public:
glVertexAttribPointerType vertexAttribPointer;
GraphicsContext3D::Attributes m_attrs;
+ HostWindow* m_hostWindow;
QGLWidget* m_glWidget;
GLuint m_texture;
GLuint m_mainFbo;
@@ -258,7 +258,6 @@ public:
private:
- QGLWidget* getOwnerGLWidget(QWebPageClient* webPageClient);
void* getProcAddress(const String& proc);
bool m_contextValid;
};
@@ -268,9 +267,20 @@ private:
#else
#define GET_PROC_ADDRESS(Proc) reinterpret_cast<Proc##Type>(getProcAddress(#Proc));
#endif
+
+bool GraphicsContext3D::isGLES2Compliant() const
+{
+#if defined (QT_OPENGL_ES_2)
+ return true;
+#else
+ return false;
+#endif
+}
+
GraphicsContext3DInternal::GraphicsContext3DInternal(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow)
: m_attrs(attrs)
+ , m_hostWindow(hostWindow)
, m_glWidget(0)
, m_texture(0)
, m_mainFbo(0)
@@ -515,7 +525,7 @@ void GraphicsContext3D::beginPaint(WebGLRenderingContext* context)
glReadPixels(/* x */ 0, /* y */ 0, m_currentWidth, m_currentHeight, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, m_internal->m_pixels.bits());
QPainter* p = imageBuffer->context()->platformContext();
- p->drawImage(/* x */ 0, /* y */ 0, m_internal->m_pixels.transformed(QMatrix().rotate(180)));
+ p->drawImage(/* x */ 0, /* y */ 0, m_internal->m_pixels.rgbSwapped().transformed(QMatrix().rotate(180)));
m_internal->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_internal->m_currentFbo);
}
@@ -524,6 +534,23 @@ void GraphicsContext3D::endPaint()
{
}
+void GraphicsContext3D::paint(QPainter* painter, const QRect& rect) const
+{
+#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)
+ QWebPageClient* webPageClient = m_internal->m_hostWindow->platformPageClient();
+ QGLWidget* ownerGLWidget = m_internal->getOwnerGLWidget(webPageClient);
+ if (ownerGLWidget) {
+ ownerGLWidget->drawTexture(QPointF(0, 0), m_internal->m_texture);
+ return;
+ }
+#endif
+ m_internal->m_glWidget->makeCurrent();
+ m_internal->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_internal->m_mainFbo);
+ glReadPixels(/* x */ 0, /* y */ 0, m_currentWidth, m_currentHeight, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, m_internal->m_pixels.bits());
+ painter->drawImage(/* x */ 0, /* y */ 0, m_internal->m_pixels.rgbSwapped().transformed(QMatrix().rotate(180)));
+ m_internal->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_internal->m_currentFbo);
+}
+
void GraphicsContext3D::reshape(int width, int height)
{
if (((width == m_currentWidth) && (height == m_currentHeight)) || (!m_internal))
@@ -1466,56 +1493,19 @@ long GraphicsContext3D::getVertexAttribOffset(unsigned long index, unsigned long
int GraphicsContext3D::texImage2D(unsigned target, unsigned level, unsigned internalformat, unsigned width, unsigned height, unsigned border, unsigned format, unsigned type, void* pixels)
{
+ m_internal->m_glWidget->makeCurrent();
glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
return 0;
}
-int GraphicsContext3D::texImage2D(unsigned target, unsigned level, Image* image, bool flipY, bool premultiplyAlpha)
-{
- ASSERT(image);
-
- m_internal->m_glWidget->makeCurrent();
-
- Vector<uint8_t> imageData;
- GLuint format;
- GLuint internalFormat;
-
- if (!extractImageData(image, flipY, premultiplyAlpha, imageData, &format, &internalFormat)) {
- LOG_ERROR("GraphicsContext3D::texImage2D: could not extract Image data");
- return -1;
- }
-
- glTexImage2D(target, level, internalFormat, image->width(), image->height(),
- /* border */ 0, format, GraphicsContext3D::UNSIGNED_BYTE, imageData.data());
-
- return 0;
-}
-
+
int GraphicsContext3D::texSubImage2D(unsigned target, unsigned level, unsigned xoff, unsigned yoff, unsigned width, unsigned height, unsigned format, unsigned type, void* pixels)
{
+ m_internal->m_glWidget->makeCurrent();
glTexSubImage2D(target, level, xoff, yoff, width, height, format, type, pixels);
return 0;
}
-int GraphicsContext3D::texSubImage2D(unsigned target, unsigned level, unsigned xoff, unsigned yoff, Image* image, bool flipY, bool premultiplyAlpha)
-{
- ASSERT(image);
-
- Vector<uint8_t> imageData;
- GLuint format;
- GLuint internalFormat;
-
- if (!extractImageData(image, flipY, premultiplyAlpha, imageData, &format, &internalFormat)) {
- LOG_ERROR("GraphicsContext3D::texSubImage2D: could not extract Image data");
- return -1;
- }
-
- glTexSubImage2D(target, level, xoff, yoff, image->width(), image->height(),
- format, GraphicsContext3D::UNSIGNED_BYTE, imageData.data());
-
- return 0;
-}
-
unsigned GraphicsContext3D::createBuffer()
{
m_internal->m_glWidget->makeCurrent();
@@ -1630,18 +1620,17 @@ bool GraphicsContext3D::getImageData(Image* image,
AlphaOp* neededAlphaOp,
unsigned int* format)
{
- QImage::Format imageFormat = (!premultiplyAlpha) ?
- QImage::Format_ARGB32 :
- QImage::Format_ARGB32_Premultiplied;
-
- QPixmap* nativePixmap = image->nativeImageForCurrentFrame();
*hasAlphaChannel = true;
- *neededAlphaOp = kAlphaDoNothing;
*format = GraphicsContext3D::RGBA;
- QImage nativeImage = nativePixmap->toImage().convertToFormat(imageFormat);
- outputVector.append(nativeImage.bits(), nativeImage.byteCount());
+ *neededAlphaOp = kAlphaDoNothing;
+ if (!premultiplyAlpha && *hasAlphaChannel)
+ *neededAlphaOp = kAlphaDoUnmultiply;
+
+ QPixmap* nativePixmap = image->nativeImageForCurrentFrame();
+ QImage nativeImage = nativePixmap->toImage().convertToFormat(QImage::Format_ARGB32);
+ outputVector.append(nativeImage.rgbSwapped().bits(), nativeImage.byteCount());
return true;
}
diff --git a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
index edac268..0100b72 100644
--- a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
+++ b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
@@ -641,12 +641,12 @@ void GraphicsContext::fillRect(const FloatRect& rect)
}
}
-void GraphicsContext::fillRect(const FloatRect& rect, const Color& c, ColorSpace colorSpace)
+void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorSpace colorSpace)
{
- if (paintingDisabled())
+ if (paintingDisabled() || !color.isValid())
return;
- m_data->solidColor.setColor(c);
+ m_data->solidColor.setColor(color);
QPainter* p = m_data->p();
if (m_common->state.shadowColor.isValid())
drawBorderlessRectShadow(this, p, rect);
@@ -655,7 +655,7 @@ void GraphicsContext::fillRect(const FloatRect& rect, const Color& c, ColorSpace
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() || !color.alpha())
+ if (paintingDisabled() || !color.isValid() || !color.alpha())
return;
Path path = Path::createRoundedRectangle(rect, topLeft, topRight, bottomLeft, bottomRight);
@@ -717,7 +717,7 @@ void GraphicsContext::drawFocusRing(const Vector<Path>& paths, int width, int of
*/
void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int /* width */, int /* offset */, const Color& color)
{
- if (paintingDisabled())
+ if (paintingDisabled() || !color.isValid())
return;
unsigned rectCount = rects.size();
@@ -1141,8 +1141,9 @@ void GraphicsContext::setURLForRect(const KURL&, const IntRect&)
void GraphicsContext::setPlatformStrokeColor(const Color& color, ColorSpace colorSpace)
{
- if (paintingDisabled())
+ if (paintingDisabled() || !color.isValid())
return;
+
QPainter* p = m_data->p();
QPen newPen(p->pen());
m_data->solidColor.setColor(color);
@@ -1172,8 +1173,9 @@ void GraphicsContext::setPlatformStrokeThickness(float thickness)
void GraphicsContext::setPlatformFillColor(const Color& color, ColorSpace colorSpace)
{
- if (paintingDisabled())
+ if (paintingDisabled() || !color.isValid())
return;
+
m_data->solidColor.setColor(color);
m_data->p()->setBrush(m_data->solidColor);
}
diff --git a/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp b/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp
index 834cd4f..86c01de 100644
--- a/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp
+++ b/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp
@@ -32,15 +32,13 @@
#include <QtCore/qmetaobject.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/qpixmapcache.h>
#include <QtGui/qstyleoption.h>
namespace WebCore {
@@ -132,7 +130,9 @@ public:
};
// the compositor lets us special-case images and colors, so we try to do so
- enum StaticContentType { HTMLContentType, PixmapContentType, ColorContentType, MediaContentType};
+ enum StaticContentType { HTMLContentType, PixmapContentType, ColorContentType, MediaContentType, Canvas3DContentType};
+
+ const GraphicsLayerQtImpl* rootLayer() const;
GraphicsLayerQtImpl(GraphicsLayerQt* newLayer);
virtual ~GraphicsLayerQtImpl();
@@ -142,24 +142,25 @@ public:
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
+ // We manage transforms ourselves because transform-origin acts differently in webkit and in Qt, and we need it as a fallback in case we encounter an un-invertible matrix
void setBaseTransform(const TransformationMatrix&);
- QTransform computeTransform(const TransformationMatrix& baseTransform) const;
void updateTransform();
// let the compositor-API tell us which properties were changed
void notifyChange(ChangeMask);
+ // actual rendering of the web-content into a QPixmap
+ // We prefer to use our own caching because it gives us a higher level of granularity than QGraphicsItem cache modes -
+ // sometimes we need to cache the contents even `though the item needs to be updated, e.g. when the background-color is changed.
+ // TODO: investigate if QGraphicsItem caching can be improved to support that out of the box.
+ QPixmap recache(const QRegion&);
+
// 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, bool forceTransformUpdate = false);
- // optimization: returns true if this or an ancestor has a transform animation running.
- // this enables us to use ItemCoordinatesCache while the animation is running, otherwise we have to recache for every frame
- bool isTransformAnimationRunning() const;
-
public slots:
// we need to notify the client (aka the layer compositor) when the animation actually starts
void notifyAnimationStarted();
@@ -175,6 +176,7 @@ public:
GraphicsLayerQt* m_layer;
TransformationMatrix m_baseTransform;
+ TransformationMatrix m_transformRelativeToRootLayer;
bool m_transformAnimationRunning;
bool m_opacityAnimationRunning;
QWeakPointer<MaskEffectQt> m_maskEffect;
@@ -203,6 +205,7 @@ public:
int m_changeMask;
QSizeF m_size;
+ QPixmapCache::Key m_backingStoreKey;
#ifndef QT_NO_ANIMATION
QList<QWeakPointer<QAbstractAnimation> > m_animations;
#endif
@@ -236,6 +239,10 @@ public:
}
} m_state;
+#if ENABLE(3D_CANVAS)
+ const GraphicsContext3D* m_gc3D;
+#endif
+
#ifndef QT_NO_ANIMATION
friend class AnimationQtBase;
#endif
@@ -247,6 +254,9 @@ GraphicsLayerQtImpl::GraphicsLayerQtImpl(GraphicsLayerQt* newLayer)
, m_transformAnimationRunning(false)
, m_opacityAnimationRunning(false)
, m_changeMask(NoChanges)
+#if ENABLE(3D_CANVAS)
+ , m_gc3D(0)
+#endif
{
// we use graphics-view for compositing, not for interactivity
setAcceptedMouseButtons(Qt::NoButton);
@@ -255,9 +265,6 @@ GraphicsLayerQtImpl::GraphicsLayerQtImpl(GraphicsLayerQt* newLayer)
// they are ignored and passed to the item below.
setEnabled(true);
- // we'll set the cache when we know what's going on
- setCacheMode(ItemCoordinateCache);
-
connect(this, SIGNAL(notifyAnimationStartedAsync()), this, SLOT(notifyAnimationStarted()), Qt::QueuedConnection);
}
@@ -283,65 +290,138 @@ GraphicsLayerQtImpl::~GraphicsLayerQtImpl()
#endif
}
-void GraphicsLayerQtImpl::updateTransform()
+const GraphicsLayerQtImpl* GraphicsLayerQtImpl::rootLayer() const
{
- setBaseTransform(isTransformAnimationRunning() ? m_baseTransform : m_layer->transform());
+ if (const GraphicsLayerQtImpl* parent = qobject_cast<const GraphicsLayerQtImpl*>(parentObject()))
+ return parent->rootLayer();
+ return this;
}
-void GraphicsLayerQtImpl::setBaseTransform(const TransformationMatrix& baseTransform)
-{
- m_baseTransform = baseTransform;
- setTransform(computeTransform(baseTransform));
-}
-QTransform GraphicsLayerQtImpl::computeTransform(const TransformationMatrix& baseTransform) const
+
+QPixmap GraphicsLayerQtImpl::recache(const QRegion& regionToUpdate)
{
- if (!m_layer)
- return baseTransform;
+ if (!m_layer->drawsContent())
+ return QPixmap();
- TransformationMatrix computedTransform;
+ QRegion region = regionToUpdate;
+ QPixmap pixmap;
- // The origin for childrenTransform is always the center of the ancestor which contains the childrenTransform.
- // this has to do with how WebCore implements -webkit-perspective and -webkit-perspective-origin, which are the CSS
- // attribute that call setChildrenTransform
- QPointF offset = -pos() - boundingRect().bottomRight() / 2;
+ // We might be drawing into an existing cache.
+ if (!QPixmapCache::find(m_backingStoreKey, &pixmap))
+ region = QRegion(QRect(0, 0, m_size.width(), m_size.height()));
- for (const GraphicsLayerQtImpl* ancestor = this; (ancestor = qobject_cast<GraphicsLayerQtImpl*>(ancestor->parentObject())); ) {
- if (!ancestor->m_state.childrenTransform.isIdentity()) {
- const QPointF offset = mapFromItem(ancestor, QPointF(ancestor->m_size.width() / 2, ancestor->m_size.height() / 2));
- computedTransform
- .translate(offset.x(), offset.y())
- .multLeft(ancestor->m_state.childrenTransform)
- .translate(-offset.x(), -offset.y());
- break;
- }
+ if (m_size != pixmap.size()) {
+ pixmap = QPixmap(m_size.toSize());
+ if (!m_layer->contentsOpaque())
+ pixmap.fill(Qt::transparent);
+ m_pendingContent.regionToUpdate = QRegion(QRect(QPoint(0, 0), m_size.toSize()));
}
+ QPainter painter(&pixmap);
+ GraphicsContext gc(&painter);
+
+ // Clear the area in cache that we're drawing into
+ painter.setCompositionMode(QPainter::CompositionMode_Clear);
+ painter.fillRect(region.boundingRect(), Qt::transparent);
+
+ // Render the actual contents into the cache
+ painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
+ m_layer->paintGraphicsLayerContents(gc, region.boundingRect());
+
+ m_backingStoreKey = QPixmapCache::insert(pixmap);
+ return pixmap;
+}
+
+void GraphicsLayerQtImpl::updateTransform()
+{
+ if (!m_transformAnimationRunning)
+ m_baseTransform = m_layer->transform();
+
+ TransformationMatrix localTransform;
+
+ GraphicsLayerQtImpl* parent = qobject_cast<GraphicsLayerQtImpl*>(parentObject());
+
// webkit has relative-to-size originPoint, graphics-view has a pixel originPoint, here we convert
// we have to manage this ourselves because QGraphicsView's transformOrigin is incompatible
const qreal originX = m_state.anchorPoint.x() * m_size.width();
const qreal originY = m_state.anchorPoint.y() * m_size.height();
- computedTransform
- .translate3d(originX, originY, m_state.anchorPoint.z())
- .multLeft(baseTransform)
+
+ // We ignore QGraphicsItem::pos completely, and use only transforms - because we have to maintain that ourselves for 3D.
+ localTransform
+ .translate3d(originX + m_state.pos.x(), originY + m_state.pos.y(), m_state.anchorPoint.z())
+ .multLeft(m_baseTransform)
.translate3d(-originX, -originY, -m_state.anchorPoint.z());
- // now we project to 2D
- return QTransform(computedTransform);
+ // This is the actual 3D transform of this item, with the ancestors' transform baked in.
+ m_transformRelativeToRootLayer = TransformationMatrix(parent ? parent->m_transformRelativeToRootLayer : TransformationMatrix())
+ .multLeft(localTransform);
+
+ // Now we have enough information to determine if the layer is facing backwards.
+ if (!m_state.backfaceVisibility && m_transformRelativeToRootLayer.inverse().m33() < 0) {
+ setVisible(false);
+ // No point in making extra calculations for invisible elements.
+ return;
+ }
+
+ // Simplistic depth test - we stack the item behind its parent if its computed z is lower than the parent's computed z at the item's center point.
+ if (parent) {
+ const QPointF centerPointMappedToRoot = rootLayer()->mapFromItem(this, m_size.width() / 2, m_size.height() / 2);
+ setFlag(ItemStacksBehindParent,
+ m_transformRelativeToRootLayer.mapPoint(FloatPoint3D(centerPointMappedToRoot.x(), centerPointMappedToRoot.y(), 0)).z() <
+ parent->m_transformRelativeToRootLayer.mapPoint(FloatPoint3D(centerPointMappedToRoot.x(), centerPointMappedToRoot.y(), 0)).z());
+ }
+
+ // The item is front-facing or backface-visibility is on.
+ setVisible(true);
+
+ // Flatten to 2D-space of this item if it doesn't preserve 3D.
+ if (!m_state.preserves3D) {
+ m_transformRelativeToRootLayer.setM13(0);
+ m_transformRelativeToRootLayer.setM23(0);
+ m_transformRelativeToRootLayer.setM31(0);
+ m_transformRelativeToRootLayer.setM32(0);
+ m_transformRelativeToRootLayer.setM33(1);
+ m_transformRelativeToRootLayer.setM34(0);
+ m_transformRelativeToRootLayer.setM43(0);
+ }
+
+ // Apply perspective for the use of this item's children. Perspective is always applied from the item's center.
+ if (!m_state.childrenTransform.isIdentity())
+ m_transformRelativeToRootLayer
+ .translate(m_size.width() / 2, m_size.height() /2)
+ .multLeft(m_state.childrenTransform)
+ .translate(-m_size.width() / 2, -m_size.height() /2);
+
+ bool inverseOk = true;
+ // Use QTransform::inverse to extrapolate the relative transform of this item, based on the parent's transform relative to
+ // the root layer and the desired transform for this item relative to the root layer.
+ const QTransform parentTransform = parent ? parent->itemTransform(rootLayer()) : QTransform();
+ const QTransform transform2D = QTransform(m_transformRelativeToRootLayer) * parentTransform.inverted(&inverseOk);
+
+ // In rare cases the transformation cannot be inversed - in that case we don't apply the transformation at all, otherwise we'd flicker.
+ // FIXME: This should be amended when Qt moves to a real 3D scene-graph.
+ if (!inverseOk)
+ return;
+
+ setTransform(transform2D);
+
+ const QList<QGraphicsItem*> children = childItems();
+ for (QList<QGraphicsItem*>::const_iterator it = children.begin(); it != children.end(); ++it)
+ if (GraphicsLayerQtImpl* layer= qobject_cast<GraphicsLayerQtImpl*>((*it)->toGraphicsObject()))
+ layer->updateTransform();
}
-bool GraphicsLayerQtImpl::isTransformAnimationRunning() const
+void GraphicsLayerQtImpl::setBaseTransform(const TransformationMatrix& baseTransform)
{
- if (m_transformAnimationRunning)
- return true;
- if (GraphicsLayerQtImpl* parent = qobject_cast<GraphicsLayerQtImpl*>(parentObject()))
- return parent->isTransformAnimationRunning();
- return false;
+ m_baseTransform = baseTransform;
+ updateTransform();
}
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());
@@ -370,9 +450,11 @@ void GraphicsLayerQtImpl::paint(QPainter* painter, const QStyleOptionGraphicsIte
switch (m_currentContent.contentType) {
case HTMLContentType:
if (m_state.drawsContent) {
- // this is the expensive bit. we try to minimize calls to this area by proper caching
- GraphicsContext gc(painter);
- m_layer->paintGraphicsLayerContents(gc, option->rect);
+ QPixmap backingStore;
+ // We might need to recache, in case we try to paint and the cache was purged (e.g. if it was full).
+ if (!QPixmapCache::find(m_backingStoreKey, &backingStore) || backingStore.size() != m_size.toSize())
+ backingStore = recache(QRegion(m_state.contentsRect));
+ painter->drawPixmap(0, 0, backingStore);
}
break;
case PixmapContentType:
@@ -384,6 +466,11 @@ void GraphicsLayerQtImpl::paint(QPainter* painter, const QStyleOptionGraphicsIte
case MediaContentType:
// we don't need to paint anything: we have a QGraphicsItem from the media element
break;
+#if ENABLE(3D_CANVAS)
+ case Canvas3DContentType:
+ m_gc3D->paint(painter, option->rect);
+ break;
+#endif
}
}
@@ -457,9 +544,6 @@ void GraphicsLayerQtImpl::flushChanges(bool recursive, bool forceUpdateTransform
}
}
- 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();
@@ -472,7 +556,7 @@ void GraphicsLayerQtImpl::flushChanges(bool recursive, bool forceUpdateTransform
if (scene())
scene()->update();
- if (m_changeMask & (ChildrenTransformChange | Preserves3DChange | TransformChange | AnchorPointChange | SizeChange)) {
+ if (m_changeMask & (ChildrenTransformChange | Preserves3DChange | TransformChange | AnchorPointChange | SizeChange | BackfaceVisibilityChange | PositionChange)) {
// due to the differences between the way WebCore handles transforms and the way Qt handles transforms,
// all these elements affect the transforms of all the descendants.
forceUpdateTransform = true;
@@ -484,19 +568,13 @@ void GraphicsLayerQtImpl::flushChanges(bool recursive, bool forceUpdateTransform
update();
setFlag(ItemHasNoContents, false);
- // no point in caching a directly composited pixmap into another pixmap
- setCacheMode(NoCache);
-
break;
case MediaContentType:
setFlag(ItemHasNoContents, true);
- setCacheMode(NoCache);
m_pendingContent.mediaLayer.data()->setParentItem(this);
break;
case ColorContentType:
- // no point in caching a solid-color rectangle
- setCacheMode(NoCache);
if (m_pendingContent.contentType != m_currentContent.contentType || m_pendingContent.contentsBackgroundColor != m_currentContent.contentsBackgroundColor)
update();
m_state.drawsContent = false;
@@ -509,15 +587,21 @@ void GraphicsLayerQtImpl::flushChanges(bool recursive, bool forceUpdateTransform
case HTMLContentType:
if (m_pendingContent.contentType != m_currentContent.contentType)
update();
- if (!m_state.drawsContent && m_layer->drawsContent()) {
+ if (!m_state.drawsContent && m_layer->drawsContent())
update();
- if (m_layer->drawsContent() && !m_maskEffect)
- setCacheMode(ItemCoordinateCache);
- } else if (!m_layer->drawsContent())
- setCacheMode(NoCache);
setFlag(ItemHasNoContents, !m_layer->drawsContent());
break;
+
+#if ENABLE(3D_CANVAS)
+ case Canvas3DContentType:
+ if (m_pendingContent.contentType != m_currentContent.contentType)
+ update();
+
+ setCacheMode(NoCache);
+ setFlag(ItemHasNoContents, false);
+ break;
+#endif
}
}
@@ -544,15 +628,16 @@ void GraphicsLayerQtImpl::flushChanges(bool recursive, bool forceUpdateTransform
if (m_maskEffect)
m_maskEffect.data()->update();
- else if (m_changeMask & DisplayChange)
+ else if (m_changeMask & DisplayChange) {
+ // Recache now: all the content is ready and we don't want to wait until the paint event.
+ recache(m_pendingContent.regionToUpdate);
update(m_pendingContent.regionToUpdate.boundingRect());
+ m_pendingContent.regionToUpdate = QRegion();
+ }
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, Preserves3DChange
-
m_state.maskLayer = m_layer->maskLayer();
m_state.pos = m_layer->position();
m_state.anchorPoint = m_layer->anchorPoint();
@@ -572,7 +657,6 @@ void GraphicsLayerQtImpl::flushChanges(bool recursive, bool forceUpdateTransform
m_currentContent.contentType = m_pendingContent.contentType;
m_currentContent.mediaLayer = m_pendingContent.mediaLayer;
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;
@@ -871,6 +955,23 @@ void GraphicsLayerQt::setContentsBackgroundColor(const Color& color)
GraphicsLayer::setContentsBackgroundColor(color);
}
+#if ENABLE(3D_CANVAS)
+void GraphicsLayerQt::setContentsToGraphicsContext3D(const GraphicsContext3D* ctx)
+{
+ if (ctx == m_impl->m_gc3D)
+ return;
+
+ m_impl->m_pendingContent.contentType = GraphicsLayerQtImpl::Canvas3DContentType;
+ m_impl->m_gc3D = ctx;
+ m_impl->notifyChange(GraphicsLayerQtImpl::ContentChange);
+}
+
+void GraphicsLayerQt::setGraphicsContext3DNeedsDisplay()
+{
+ setNeedsDisplay();
+}
+#endif
+
void GraphicsLayerQt::setContentsToMedia(PlatformLayer* media)
{
if (media) {
@@ -1106,8 +1207,6 @@ public:
{
if (m_fillsForwards)
setCurrentTime(1);
- else if (m_layer && m_layer.data()->m_layer)
- m_layer.data()->setBaseTransform(m_layer.data()->m_layer->transform());
}
// the idea is that we let WebCore manage the transform-operations
@@ -1118,33 +1217,25 @@ public:
{
TransformationMatrix transformMatrix;
- // sometimes the animation values from WebCore are misleading and we have to use the actual matrix as source
- // The Mac implementation simply doesn't try to accelerate those (e.g. 360deg rotation), but we do.
- if (progress == 1 || !targetOperations.size() || sourceOperations == targetOperations) {
- TransformationMatrix sourceMatrix;
- sourceOperations.apply(m_boxSize, sourceMatrix);
- transformMatrix = m_sourceMatrix;
- transformMatrix.blend(sourceMatrix, 1 - progress);
- } else {
- bool validTransformLists = true;
- const int sourceOperationCount = sourceOperations.size();
- if (sourceOperationCount) {
- if (targetOperations.size() != sourceOperationCount)
- validTransformLists = false;
- else
- for (size_t j = 0; j < sourceOperationCount && validTransformLists; ++j)
- if (!sourceOperations.operations()[j]->isSameType(*targetOperations.operations()[j]))
- validTransformLists = false;
- }
+ bool validTransformLists = true;
+ const int sourceOperationCount = sourceOperations.size();
+ if (sourceOperationCount) {
+ if (targetOperations.size() != sourceOperationCount)
+ validTransformLists = false;
+ else
+ for (size_t j = 0; j < sourceOperationCount && validTransformLists; ++j)
+ if (!sourceOperations.operations()[j]->isSameType(*targetOperations.operations()[j]))
+ validTransformLists = false;
+ }
- if (validTransformLists) {
- for (size_t i = 0; i < targetOperations.size(); ++i)
- targetOperations.operations()[i]->blend(sourceOperations.at(i), progress)->apply(transformMatrix, m_boxSize);
- } else {
- targetOperations.apply(m_boxSize, transformMatrix);
- transformMatrix.blend(m_sourceMatrix, progress);
- }
+ if (validTransformLists) {
+ for (size_t i = 0; i < targetOperations.size(); ++i)
+ targetOperations.operations()[i]->blend(sourceOperations.at(i), progress)->apply(transformMatrix, m_boxSize);
+ } else {
+ targetOperations.apply(m_boxSize, transformMatrix);
+ transformMatrix.blend(m_sourceMatrix, progress);
}
+
m_layer.data()->setBaseTransform(transformMatrix);
if (m_fillsForwards)
m_layer.data()->m_layer->setTransform(m_layer.data()->m_baseTransform);
@@ -1163,7 +1254,10 @@ public:
m_sourceMatrix = m_layer.data()->m_layer->transform();
m_layer.data()->m_transformAnimationRunning = true;
} else if (newState == QAbstractAnimation::Stopped) {
+ // We update the transform back to the default. This already takes fill-modes into account.
m_layer.data()->m_transformAnimationRunning = false;
+ if (m_layer && m_layer.data()->m_layer)
+ m_layer.data()->setBaseTransform(m_layer.data()->m_layer->transform());
}
}
@@ -1181,8 +1275,6 @@ public:
{
if (m_fillsForwards)
setCurrentTime(1);
- else if (m_layer && m_layer.data()->m_layer)
- m_layer.data()->setOpacity(m_layer.data()->m_layer->opacity());
}
virtual void applyFrame(const qreal& fromValue, const qreal& toValue, qreal progress)
{
@@ -1204,6 +1296,12 @@ public:
if (m_layer)
m_layer.data()->m_opacityAnimationRunning = (newState == QAbstractAnimation::Running);
+
+ // If stopped, we update the opacity back to the default. This already takes fill-modes into account.
+ if (newState == Stopped)
+ if (m_layer && m_layer.data()->m_layer)
+ m_layer.data()->setOpacity(m_layer.data()->m_layer->opacity());
+
}
};
@@ -1269,6 +1367,8 @@ void GraphicsLayerQt::removeAnimationsForProperty(AnimatedPropertyID id)
if (*it) {
AnimationQtBase* anim = static_cast<AnimationQtBase*>(it->data());
if (anim && anim->m_webkitPropertyID == id) {
+ // We need to stop the animation right away, or it might flicker before it's deleted.
+ anim->stop();
anim->deleteLater();
it = m_impl->m_animations.erase(it);
--it;
@@ -1283,7 +1383,9 @@ void GraphicsLayerQt::removeAnimationsForKeyframes(const String& name)
if (*it) {
AnimationQtBase* anim = static_cast<AnimationQtBase*>((*it).data());
if (anim && anim->m_keyframesName == QString(name)) {
- (*it).data()->deleteLater();
+ // We need to stop the animation right away, or it might flicker before it's deleted.
+ anim->stop();
+ anim->deleteLater();
it = m_impl->m_animations.erase(it);
--it;
}
diff --git a/WebCore/platform/graphics/qt/GraphicsLayerQt.h b/WebCore/platform/graphics/qt/GraphicsLayerQt.h
index 9e5832f..6de5a6e 100644
--- a/WebCore/platform/graphics/qt/GraphicsLayerQt.h
+++ b/WebCore/platform/graphics/qt/GraphicsLayerQt.h
@@ -74,6 +74,10 @@ public:
virtual void setContentsToImage(Image*);
virtual void setContentsToMedia(PlatformLayer*);
virtual void setContentsBackgroundColor(const Color&);
+#if ENABLE(3D_CANVAS)
+ virtual void setContentsToGraphicsContext3D(const GraphicsContext3D*);
+ virtual void setGraphicsContext3DNeedsDisplay();
+#endif
virtual void setGeometryOrientation(CompositingCoordinatesOrientation orientation);
virtual void setContentsOrientation(CompositingCoordinatesOrientation orientation);
virtual void distributeOpacity(float);
diff --git a/WebCore/platform/graphics/qt/ImageDecoderQt.cpp b/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
index b48b278..a8110ca 100644
--- a/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
+++ b/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
@@ -123,12 +123,14 @@ int ImageDecoderQt::repetitionCount() const
// Qt | WebCore | description
// -1 | 0 | infinite animation
// 0 | cAnimationLoopOnce | show every frame once
- // n | n | no idea if that is supported
+ // n | n+1 | Qt returns the # of iterations - 1
// n/a | cAnimationNone | show only the first frame
if (m_repetitionCount == -1)
m_repetitionCount = 0;
else if (m_repetitionCount == 0)
m_repetitionCount = cAnimationLoopOnce;
+ else
+ ++m_repetitionCount;
}
return m_repetitionCount;
diff --git a/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp b/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp
index bdac2a4..4d7b7b0 100644
--- a/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp
+++ b/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp
@@ -77,7 +77,7 @@ MediaPlayer::SupportsType MediaPlayerPrivate::supportsType(const String& mime, c
if (!mime.startsWith("audio/") && !mime.startsWith("video/"))
return MediaPlayer::IsNotSupported;
- if (QMediaPlayer::hasSupport(mime, QStringList(codec)) >= QtMultimedia::ProbablySupported)
+ if (QMediaPlayer::hasSupport(mime, QStringList(codec)) >= QtMediaServices::ProbablySupported)
return MediaPlayer::IsSupported;
return MediaPlayer::MayBeSupported;
@@ -344,8 +344,8 @@ unsigned MediaPlayerPrivate::bytesLoaded() const
unsigned MediaPlayerPrivate::totalBytes() const
{
- if (m_mediaPlayer->availableMetaData().contains(QtMultimedia::Size))
- return m_mediaPlayer->metaData(QtMultimedia::Size).toInt();
+ if (m_mediaPlayer->availableMetaData().contains(QtMediaServices::Size))
+ return m_mediaPlayer->metaData(QtMediaServices::Size).toInt();
return 100;
}
diff --git a/WebCore/platform/graphics/qt/PathQt.cpp b/WebCore/platform/graphics/qt/PathQt.cpp
index ee4af7f..4b0c21f 100644
--- a/WebCore/platform/graphics/qt/PathQt.cpp
+++ b/WebCore/platform/graphics/qt/PathQt.cpp
@@ -69,12 +69,41 @@ Path& Path::operator=(const Path& other)
return *this;
}
+// Check whether a point is on the border
+bool isPointOnPathBorder(const QPolygonF& border, const QPointF& p)
+{
+ QPointF p1 = border.at(0);
+ QPointF p2;
+
+ for (int i = 1; i < border.size(); ++i) {
+ p2 = border.at(i);
+ // (x1<=x<=x2||x1=>x>=x2) && (y1<=y<=y2||y1=>y>=y2) && (y2-y1)(x-x1) == (y-y1)(x2-x1)
+ // In which, (y2-y1)(x-x1) == (y-y1)(x2-x1) is from (y2-y1)/(x2-x1) == (y-y1)/(x-x1)
+ // it want to check the slope between p1 and p2 is same with slope between p and p1,
+ // if so then the three points lie on the same line.
+ // In which, (x1<=x<=x2||x1=>x>=x2) && (y1<=y<=y2||y1=>y>=y2) want to make sure p is
+ // between p1 and p2, not outside.
+ if (((p.x() <= p1.x() && p.x() >= p2.x()) || (p.x() >= p1.x() && p.x() <= p2.x()))
+ && ((p.y() <= p1.y() && p.y() >= p2.y()) || (p.y() >= p1.y() && p.y() <= p2.y()))
+ && (p2.y() - p1.y()) * (p.x() - p1.x()) == (p.y() - p1.y()) * (p2.x() - p1.x())) {
+ return true;
+ }
+ p1 = p2;
+ }
+ return false;
+}
+
bool Path::contains(const FloatPoint& point, WindRule rule) const
{
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);
+
+ if (!contains) {
+ // check whether the point is on the border
+ contains = isPointOnPathBorder(m_path.toFillPolygon(), point);
+ }
const_cast<QPainterPath*>(&m_path)->setFillRule(savedRule);
return contains;
diff --git a/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp b/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp
index cc4ca2e..e76ed7b 100644
--- a/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp
+++ b/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp
@@ -55,10 +55,9 @@ bool GraphicsContext3D::getImageData(Image* image,
return false;
SkBitmap& skiaImageRef = *skiaImage;
SkAutoLockPixels lock(skiaImageRef);
- int width = skiaImage->width();
int height = skiaImage->height();
int rowBytes = skiaImage->rowBytes();
- ASSERT(rowBytes == width * 4);
+ ASSERT(rowBytes == skiaImage->width() * 4);
uint8_t* pixels = reinterpret_cast<uint8_t*>(skiaImage->getPixels());
outputVector.resize(rowBytes * height);
int size = rowBytes * height;
diff --git a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
index 8986685..e16b373 100644
--- a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
+++ b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
@@ -91,9 +91,9 @@ inline float square(float n)
// bugs. Leaving the code in for now, so we can revert easily if necessary.
// #define ENSURE_VALUE_SAFETY_FOR_SKIA
+#ifdef ENSURE_VALUE_SAFETY_FOR_SKIA
static bool isCoordinateSkiaSafe(float coord)
{
-#ifdef ENSURE_VALUE_SAFETY_FOR_SKIA
// First check for valid floats.
#if defined(_MSC_VER)
if (!_finite(coord))
@@ -110,10 +110,8 @@ static bool isCoordinateSkiaSafe(float coord)
return false;
return true;
-#else
- return true;
-#endif
}
+#endif
static bool isPointSkiaSafe(const SkMatrix& transform, const SkPoint& pt)
{
@@ -734,8 +732,6 @@ void GraphicsContext::fillRect(const FloatRect& rect)
ClipRectToCanvas(*platformContext()->canvas(), r, &r);
}
- const GraphicsContextState& state = m_common->state;
-
SkPaint paint;
platformContext()->setupPaintForFilling(&paint);
platformContext()->canvas()->drawRect(r, paint);
@@ -1122,11 +1118,8 @@ void GraphicsContext::strokePath()
if (!isPathSkiaSafe(getCTM(), path))
return;
- const GraphicsContextState& state = m_common->state;
-
SkPaint paint;
platformContext()->setupPaintForStroking(&paint, 0, 0);
-
platformContext()->canvas()->drawPath(path, paint);
}
@@ -1138,12 +1131,9 @@ void GraphicsContext::strokeRect(const FloatRect& rect, float lineWidth)
if (!isRectSkiaSafe(getCTM(), rect))
return;
- const GraphicsContextState& state = m_common->state;
-
SkPaint paint;
platformContext()->setupPaintForStroking(&paint, 0, 0);
paint.setStrokeWidth(WebCoreFloatToSkScalar(lineWidth));
-
platformContext()->canvas()->drawRect(rect, paint);
}
diff --git a/WebCore/platform/graphics/transforms/TransformationMatrix.cpp b/WebCore/platform/graphics/transforms/TransformationMatrix.cpp
index 0400d40..10c7f70 100644
--- a/WebCore/platform/graphics/transforms/TransformationMatrix.cpp
+++ b/WebCore/platform/graphics/transforms/TransformationMatrix.cpp
@@ -54,6 +54,22 @@ namespace WebCore {
// webmasters - are to be held responsible. Basically, don't be a jerk, and remember that anything free comes
// with no guarantee.
+// A Note About row-major vs. column major matrixes
+//
+// The clients of this class (CSSMatrix and SVGMatrix) assume a column-major ordering.
+// That means that when the matrix is initialized with 16 values, the first 4 values
+// go in the 4 rows of the first column, etc. And in the dereferencing calls, the first
+// digit is the column (e.g., m23() is column 2 row 3). Because C++ uses row-major arrays
+// the internal matrix is stored in row-major order, so m[2][0] means row 2, column 0. This
+// has no bearing on how the matrix is viewed on the outside, since all access is done
+// with function calls. But it does help make the code more clear if you know that.
+//
+// FIXME: Multiply calls are named for what they do in the internal, row-major world.
+// multLeft is actually a multRight in a column-major world, and multiply is a multLeft
+// in a column-major world. For now I've left it that way to avoid too many confusing
+// changes to the code. In particular AffineTransform uses these same terms for the
+// opposite operations. So we have to be VERY careful when we change them.
+
typedef double Vector4[4];
typedef double Vector3[3];
diff --git a/WebCore/platform/graphics/transforms/TransformationMatrix.h b/WebCore/platform/graphics/transforms/TransformationMatrix.h
index cdf101d..96b4baa 100644
--- a/WebCore/platform/graphics/transforms/TransformationMatrix.h
+++ b/WebCore/platform/graphics/transforms/TransformationMatrix.h
@@ -47,7 +47,7 @@
#endif
#if PLATFORM(WIN) || (PLATFORM(QT) && OS(WINDOWS)) || (PLATFORM(WX) && OS(WINDOWS))
-#if COMPILER(MINGW)
+#if COMPILER(MINGW) && !COMPILER(MINGW64)
typedef struct _XFORM XFORM;
#else
typedef struct tagXFORM XFORM;
diff --git a/WebCore/platform/graphics/win/FontPlatformDataCGWin.cpp b/WebCore/platform/graphics/win/FontPlatformDataCGWin.cpp
index ed9073f..a804432 100644
--- a/WebCore/platform/graphics/win/FontPlatformDataCGWin.cpp
+++ b/WebCore/platform/graphics/win/FontPlatformDataCGWin.cpp
@@ -115,7 +115,7 @@ void FontPlatformData::platformDataInit(HFONT font, float size, HDC hdc, WCHAR*
}
FontPlatformData::FontPlatformData(HFONT hfont, CGFontRef font, float size, bool bold, bool oblique, bool useGDI)
- : m_font(RefCountedHFONT::create(hfont))
+ : m_font(RefCountedGDIHandle<HFONT>::create(hfont))
, m_size(size)
, m_cgFont(font)
, m_syntheticBold(bold)
diff --git a/WebCore/platform/graphics/win/FontPlatformDataWin.cpp b/WebCore/platform/graphics/win/FontPlatformDataWin.cpp
index cc02c4c..99f364c 100644
--- a/WebCore/platform/graphics/win/FontPlatformDataWin.cpp
+++ b/WebCore/platform/graphics/win/FontPlatformDataWin.cpp
@@ -36,7 +36,7 @@ using std::min;
namespace WebCore {
FontPlatformData::FontPlatformData(HFONT font, float size, bool bold, bool oblique, bool useGDI)
- : m_font(RefCountedHFONT::create(font))
+ : m_font(RefCountedGDIHandle<HFONT>::create(font))
, m_size(size)
#if PLATFORM(CG)
, m_cgFont(0)
diff --git a/WebCore/platform/graphics/win/GraphicsContextWin.cpp b/WebCore/platform/graphics/win/GraphicsContextWin.cpp
index b110145..161b9c6 100644
--- a/WebCore/platform/graphics/win/GraphicsContextWin.cpp
+++ b/WebCore/platform/graphics/win/GraphicsContextWin.cpp
@@ -43,8 +43,6 @@ using namespace std;
namespace WebCore {
-class SVGResourceImage;
-
static void fillWithClearColor(HBITMAP bitmap)
{
BITMAP bmpInfo;
@@ -199,13 +197,4 @@ void GraphicsContextPlatformPrivate::concatCTM(const AffineTransform& transform)
ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY);
}
-#if ENABLE(SVG)
-GraphicsContext* contextForImage(SVGResourceImage*)
-{
- // FIXME: This should go in GraphicsContextCG.cpp
- notImplemented();
- return 0;
-}
-#endif
-
}
diff --git a/WebCore/platform/graphics/win/RefCountedHFONT.h b/WebCore/platform/graphics/win/RefCountedGDIHandle.h
index b1b691b..65f66f1 100755
--- a/WebCore/platform/graphics/win/RefCountedHFONT.h
+++ b/WebCore/platform/graphics/win/RefCountedGDIHandle.h
@@ -17,40 +17,54 @@
* Boston, MA 02110-1301, USA.
*
*/
-#ifndef RefCountedHFONT_h
-#define RefCountedHFONT_h
-#include "StringImpl.h"
+#ifndef RefCountedGDIHandle_h
+#define RefCountedGDIHandle_h
+
+#include <windows.h>
+#include <wtf/HashFunctions.h>
+#include <wtf/OwnPtr.h>
#include <wtf/RefCounted.h>
namespace WebCore {
-class RefCountedHFONT : public RefCounted<RefCountedHFONT> {
+template <typename T> class RefCountedGDIHandle : public RefCounted<RefCountedGDIHandle<T> > {
public:
- static PassRefPtr<RefCountedHFONT> create(HFONT hfont) { return adoptRef(new RefCountedHFONT(hfont)); }
- static PassRefPtr<RefCountedHFONT> createDeleted() { return adoptRef(new RefCountedHFONT(reinterpret_cast<HFONT>(-1))); }
+ static PassRefPtr<RefCountedGDIHandle> create(T handle)
+ {
+ return adoptRef(new RefCountedGDIHandle<T>(handle));
+ }
+
+ static PassRefPtr<RefCountedGDIHandle<T> > createDeleted()
+ {
+ return adoptRef(new RefCountedGDIHandle<T>(reinterpret_cast<T>(-1)));
+ }
+
+ ~RefCountedGDIHandle()
+ {
+ if (m_handle != reinterpret_cast<T>(-1))
+ WTF::deleteOwnedPtr(m_handle);
+ }
- ~RefCountedHFONT()
+ T handle() const
{
- if (m_hfont != reinterpret_cast<HFONT>(-1))
- DeleteObject(m_hfont);
+ return m_handle;
}
- HFONT hfont() const { return m_hfont; }
unsigned hash() const
{
- return StringImpl::computeHash(reinterpret_cast<const UChar*>(&m_hfont), sizeof(HFONT) / sizeof(UChar));
+ return WTF::PtrHash<T>::hash(m_handle);
}
private:
- RefCountedHFONT(HFONT hfont)
- : m_hfont(hfont)
+ RefCountedGDIHandle(T handle)
+ : m_handle(handle)
{
}
- HFONT m_hfont;
+ T m_handle;
};
-}
+} // namespace WebCore
-#endif
+#endif // RefCountedGDIHandle_h
diff --git a/WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp b/WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp
index ee3a980..20d42ff 100644
--- a/WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp
+++ b/WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp
@@ -125,11 +125,26 @@ void SimpleFontData::platformCharWidthInit()
initCharWidths();
}
}
+FloatRect SimpleFontData::platformBoundsForGlyph(Glyph glyph) const
+{
+ if (m_platformData.useGDI())
+ return boundsForGDIGlyph(glyph);
+
+ CGRect box;
+ CGFontGetGlyphBBoxes(m_platformData.cgFont(), &glyph, 1, &box);
+ float pointSize = m_platformData.size();
+ CGFloat scale = pointSize / unitsPerEm();
+ FloatRect boundingBox = CGRectApplyAffineTransform(box, CGAffineTransformMakeScale(scale, -scale));
+ if (m_syntheticBoldOffset)
+ boundingBox.setWidth(boundingBox.width() + m_syntheticBoldOffset);
-GlyphMetrics SimpleFontData::platformMetricsForGlyph(Glyph glyph, GlyphMetricsMode metricsMode) const
+ return boundingBox;
+}
+
+float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
{
if (m_platformData.useGDI())
- return metricsForGDIGlyph(glyph);
+ return widthForGDIGlyph(glyph);
CGFontRef font = m_platformData.cgFont();
float pointSize = m_platformData.size();
@@ -139,18 +154,8 @@ GlyphMetrics SimpleFontData::platformMetricsForGlyph(Glyph glyph, GlyphMetricsMo
// FIXME: Need to add real support for printer fonts.
bool isPrinterFont = false;
wkGetGlyphAdvances(font, m, m_isSystemFont, isPrinterFont, glyph, advance);
- GlyphMetrics metrics;
- metrics.horizontalAdvance = advance.width + m_syntheticBoldOffset;
-
- if (metricsMode == GlyphBoundingBox) {
- CGRect boundingBox;
- CGFontGetGlyphBBoxes(font, &glyph, 1, &boundingBox);
- CGFloat scale = pointSize / unitsPerEm();
- metrics.boundingBox = CGRectApplyAffineTransform(boundingBox, CGAffineTransformMakeScale(scale, -scale));
- if (m_syntheticBoldOffset)
- metrics.boundingBox.setWidth(metrics.boundingBox.width() + m_syntheticBoldOffset);
- }
- return metrics;
+
+ return advance.width + m_syntheticBoldOffset;
}
}
diff --git a/WebCore/platform/graphics/win/SimpleFontDataCairoWin.cpp b/WebCore/platform/graphics/win/SimpleFontDataCairoWin.cpp
index e845d85..62ea060 100644
--- a/WebCore/platform/graphics/win/SimpleFontDataCairoWin.cpp
+++ b/WebCore/platform/graphics/win/SimpleFontDataCairoWin.cpp
@@ -96,6 +96,14 @@ void SimpleFontData::platformCharWidthInit()
// charwidths are set in platformInit.
}
+FloatRect SimpleFontData::platformBoundsForGlyph(Glyph glyph) const
+{
+ if (m_platformData.useGDI())
+ return boundsForGDIGlyph(glyph);
+ //FIXME: Implement this
+ return FloatRect();
+}
+
float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
{
if (m_platformData.useGDI())
diff --git a/WebCore/platform/graphics/win/SimpleFontDataWin.cpp b/WebCore/platform/graphics/win/SimpleFontDataWin.cpp
index f85f9ba..7010c8a 100644
--- a/WebCore/platform/graphics/win/SimpleFontDataWin.cpp
+++ b/WebCore/platform/graphics/win/SimpleFontDataWin.cpp
@@ -179,7 +179,24 @@ void SimpleFontData::determinePitch()
ReleaseDC(0, dc);
}
-GlyphMetrics SimpleFontData::metricsForGDIGlyph(Glyph glyph) const
+FloatRect SimpleFontData::boundsForGDIGlyph(Glyph glyph) const
+{
+ HDC hdc = GetDC(0);
+ SetGraphicsMode(hdc, GM_ADVANCED);
+ HGDIOBJ oldFont = SelectObject(hdc, m_platformData.hfont());
+
+ GLYPHMETRICS gdiMetrics;
+ static const MAT2 identity = { 0, 1, 0, 0, 0, 0, 0, 1 };
+ GetGlyphOutline(hdc, glyph, GGO_METRICS | GGO_GLYPH_INDEX, &gdiMetrics, 0, 0, &identity);
+
+ SelectObject(hdc, oldFont);
+ ReleaseDC(0, hdc);
+
+ return FloatRect(gdiMetrics.gmptGlyphOrigin.x, -gdiMetrics.gmptGlyphOrigin.y,
+ gdiMetrics.gmBlackBoxX + m_syntheticBoldOffset, gdiMetrics.gmBlackBoxY);
+}
+
+float SimpleFontData::widthForGDIGlyph(Glyph glyph) const
{
HDC hdc = GetDC(0);
SetGraphicsMode(hdc, GM_ADVANCED);
@@ -192,12 +209,7 @@ GlyphMetrics SimpleFontData::metricsForGDIGlyph(Glyph glyph) const
SelectObject(hdc, oldFont);
ReleaseDC(0, hdc);
- GlyphMetrics glyphMetrics;
- glyphMetrics.horizontalAdvance = gdiMetrics.gmCellIncX + m_syntheticBoldOffset;
- glyphMetrics.boundingBox = FloatRect(gdiMetrics.gmptGlyphOrigin.x, -gdiMetrics.gmptGlyphOrigin.y,
- gdiMetrics.gmBlackBoxX + m_syntheticBoldOffset, gdiMetrics.gmBlackBoxY);
-
- return glyphMetrics;
+ return gdiMetrics.gmCellIncX + m_syntheticBoldOffset;
}
SCRIPT_FONTPROPERTIES* SimpleFontData::scriptFontProperties() const
diff --git a/WebCore/platform/graphics/win/UniscribeController.cpp b/WebCore/platform/graphics/win/UniscribeController.cpp
index cfa15a2..bcf7578 100644
--- a/WebCore/platform/graphics/win/UniscribeController.cpp
+++ b/WebCore/platform/graphics/win/UniscribeController.cpp
@@ -380,12 +380,12 @@ bool UniscribeController::shapeAndPlaceItem(const UChar* cp, unsigned i, const S
glyphBuffer->add(glyph, fontData, advance, &size);
}
- GlyphMetrics glyphMetrics = fontData->metricsForGlyph(glyph);
- glyphMetrics.boundingBox.move(m_glyphOrigin.x(), m_glyphOrigin.y());
- m_minGlyphBoundingBoxX = min(m_minGlyphBoundingBoxX, glyphMetrics.boundingBox.x());
- m_maxGlyphBoundingBoxX = max(m_maxGlyphBoundingBoxX, glyphMetrics.boundingBox.right());
- m_minGlyphBoundingBoxY = min(m_minGlyphBoundingBoxY, glyphMetrics.boundingBox.y());
- m_maxGlyphBoundingBoxY = max(m_maxGlyphBoundingBoxY, glyphMetrics.boundingBox.bottom());
+ FloatRect glyphBounds = fontData->boundsForGlyph(glyph);
+ glyphBounds.move(m_glyphOrigin.x(), m_glyphOrigin.y());
+ m_minGlyphBoundingBoxX = min(m_minGlyphBoundingBoxX, glyphBounds.x());
+ m_maxGlyphBoundingBoxX = max(m_maxGlyphBoundingBoxX, glyphBounds.right());
+ m_minGlyphBoundingBoxY = min(m_minGlyphBoundingBoxY, glyphBounds.y());
+ m_maxGlyphBoundingBoxY = max(m_maxGlyphBoundingBoxY, glyphBounds.bottom());
m_glyphOrigin.move(advance + offsetX, -offsetY);
// Mutate the glyph array to contain our altered advances.
diff --git a/WebCore/platform/graphics/win/WKCACFLayerRenderer.cpp b/WebCore/platform/graphics/win/WKCACFLayerRenderer.cpp
index 1b14846..714a4ac 100644
--- a/WebCore/platform/graphics/win/WKCACFLayerRenderer.cpp
+++ b/WebCore/platform/graphics/win/WKCACFLayerRenderer.cpp
@@ -275,6 +275,13 @@ void WKCACFLayerRenderer::setRootContents(CGImageRef image)
renderSoon();
}
+void WKCACFLayerRenderer::setRootContentsAndDisplay(CGImageRef image)
+{
+ ASSERT(m_rootLayer);
+ m_rootLayer->setContents(image);
+ paint();
+}
+
void WKCACFLayerRenderer::setRootChildLayer(WKCACFLayer* layer)
{
if (!m_scrollLayer)
diff --git a/WebCore/platform/graphics/win/WKCACFLayerRenderer.h b/WebCore/platform/graphics/win/WKCACFLayerRenderer.h
index ea710b6..b708464 100644
--- a/WebCore/platform/graphics/win/WKCACFLayerRenderer.h
+++ b/WebCore/platform/graphics/win/WKCACFLayerRenderer.h
@@ -62,6 +62,7 @@ public:
void setScrollFrame(const IntPoint&, const IntSize&);
void setRootContents(CGImageRef);
+ void setRootContentsAndDisplay(CGImageRef);
void setRootChildLayer(WKCACFLayer* layer);
void setNeedsDisplay();
void setHostWindow(HWND window) { m_hostWindow = window; }
diff --git a/WebCore/platform/graphics/wince/FontCustomPlatformData.cpp b/WebCore/platform/graphics/wince/FontCustomPlatformData.cpp
index d5f8a5a..f8a1e26 100644
--- a/WebCore/platform/graphics/wince/FontCustomPlatformData.cpp
+++ b/WebCore/platform/graphics/wince/FontCustomPlatformData.cpp
@@ -63,7 +63,7 @@ static String createUniqueFontName()
unsigned int* ptr = reinterpret_cast<unsigned int*>(fontUuid.data());
for (int i = 0; i < sizeof(GUID) / sizeof(int) ; ++i)
- *(ptr + i) = static_cast<unsigned int>(WTF::randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0));
+ *(ptr + i) = static_cast<unsigned int>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0));
Vector<char> fontNameVector;
base64Encode(fontUuid, fontNameVector);
diff --git a/WebCore/platform/graphics/wince/SimpleFontDataWince.cpp b/WebCore/platform/graphics/wince/SimpleFontDataWince.cpp
index 1195294..6c815fc 100644
--- a/WebCore/platform/graphics/wince/SimpleFontDataWince.cpp
+++ b/WebCore/platform/graphics/wince/SimpleFontDataWince.cpp
@@ -131,6 +131,11 @@ void SimpleFontData::determinePitch()
m_treatAsFixedPitch = !(tm.tmPitchAndFamily & TMPF_FIXED_PITCH);
}
+FloatRect SimpleFontData::platformBoundsForGlyph(Glyph) const
+{
+ return FloatRect();
+}
+
float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
{
if (m_platformData.isDisabled())
diff --git a/WebCore/platform/graphics/wx/FontCacheWx.cpp b/WebCore/platform/graphics/wx/FontCacheWx.cpp
index b2dea2e..5b02bdb 100644
--- a/WebCore/platform/graphics/wx/FontCacheWx.cpp
+++ b/WebCore/platform/graphics/wx/FontCacheWx.cpp
@@ -42,7 +42,13 @@ void FontCache::platformInit()
const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length)
{
SimpleFontData* fontData = 0;
- fontData = new SimpleFontData(FontPlatformData(font.fontDescription(), font.family().family()));
+ fontData = getCachedFontData(font.fontDescription(), font.family().family());
+ if (!fontData->containsCharacters(characters, length))
+ fontData = getSimilarFontPlatformData(font);
+ if (!fontData->containsCharacters(characters, length))
+ fontData = getLastResortFallbackFont(font.fontDescription());
+
+ ASSERT(fontData->containsCharacters(characters, length));
return fontData;
}
@@ -55,8 +61,15 @@ SimpleFontData* FontCache::getLastResortFallbackFont(const FontDescription& font
{
// FIXME: Would be even better to somehow get the user's default font here. For now we'll pick
// the default that the user would get without changing any prefs.
- static AtomicString timesStr("systemfont");
- return getCachedFontData(fontDescription, timesStr);
+ SimpleFontData* fallback = 0;
+#if OS(WINDOWS) || (OS(DARWIN) && !defined(BUILDING_ON_TIGER))
+ static AtomicString fallbackName("Arial Unicode MS");
+#else
+ static AtomicString fallbackName("Times New Roman");
+#endif
+ fallback = getCachedFontData(fontDescription, fallbackName);
+
+ return fallback;
}
FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family)
diff --git a/WebCore/platform/graphics/wx/FontPlatformData.h b/WebCore/platform/graphics/wx/FontPlatformData.h
index ecb957e..94585e6 100644
--- a/WebCore/platform/graphics/wx/FontPlatformData.h
+++ b/WebCore/platform/graphics/wx/FontPlatformData.h
@@ -37,6 +37,22 @@
#include <wx/defs.h>
#include <wx/font.h>
+#include <wx/gdicmn.h>
+
+#if OS(DARWIN)
+#include <ApplicationServices/ApplicationServices.h>
+
+#if __OBJC__
+@class NSFont;
+#else
+class NSFont;
+#endif
+
+#ifndef BUILDING_ON_TIGER
+inline CTFontRef toCTFontRef(NSFont *nsFont) { return reinterpret_cast<CTFontRef>(nsFont); }
+#endif
+
+#endif
namespace WebCore {
@@ -64,9 +80,12 @@ public:
enum FontState { UNINITIALIZED, DELETED, VALID };
FontPlatformData(WTF::HashTableDeletedValueType)
- : m_fontState(DELETED),
- m_font(0),
- m_size(0)
+ : m_fontState(DELETED)
+ , m_font(0)
+ , m_size(0)
+#if OS(DARWIN)
+ , m_atsuFontID(0)
+#endif
{ }
~FontPlatformData();
@@ -77,6 +96,9 @@ public:
: m_fontState(UNINITIALIZED)
, m_font(0)
, m_size(size)
+#if OS(DARWIN)
+ , m_atsuFontID(0)
+#endif
{
}
@@ -84,6 +106,9 @@ public:
: m_fontState(UNINITIALIZED)
, m_font(0)
, m_size(0)
+#if OS(DARWIN)
+ , m_atsuFontID(0)
+#endif
{
}
@@ -121,11 +146,23 @@ public:
bool roundsGlyphAdvances() const { return false; }
+ bool allowsLigatures() const { return false; }
+
#if OS(WINDOWS)
bool useGDI() const;
HFONT hfont() const;
#endif
+#if OS(DARWIN)
+ ATSUFontID m_atsuFontID;
+ CGFontRef cgFont() const;
+ NSFont* nsFont() const;
+ void cacheNSFont();
+
+#endif
+
+ float m_size;
+
#ifndef NDEBUG
String description() const;
#endif
@@ -133,7 +170,9 @@ public:
private:
WTF::RefPtr<FontHolder> m_font;
FontState m_fontState;
- float m_size;
+#if OS(DARWIN)
+ NSFont* m_nsFont;
+#endif
};
}
diff --git a/WebCore/platform/graphics/wx/FontPlatformDataWx.cpp b/WebCore/platform/graphics/wx/FontPlatformDataWx.cpp
index a75d244..601d6b4 100644
--- a/WebCore/platform/graphics/wx/FontPlatformDataWx.cpp
+++ b/WebCore/platform/graphics/wx/FontPlatformDataWx.cpp
@@ -99,6 +99,11 @@ FontPlatformData::FontPlatformData(const FontDescription& desc, const AtomicStri
)
);
#endif
+#if OS(DARWIN)
+ m_atsuFontID = m_font->font()->MacGetATSUFontID();
+ cacheNSFont();
+#endif
+ m_size = desc.computedPixelSize();
m_fontState = VALID;
m_size = desc.computedPixelSize();
@@ -142,4 +147,24 @@ HFONT FontPlatformData::hfont() const
}
#endif
+#if OS(DARWIN)
+CGFontRef FontPlatformData::cgFont() const
+{
+ CGFontRef cgFont = 0;
+#ifdef wxOSX_USE_CORE_TEXT && wxOSX_USE_CORE_TEXT
+ cgFont = CTFontCopyGraphicsFont((CTFontRef)m_font->font()->OSXGetCTFont(), 0);
+#else
+ ATSFontRef fontRef;
+
+ fontRef = FMGetATSFontRefFromFont(m_atsuFontID);
+
+ if (fontRef)
+ cgFont = CGFontCreateWithPlatformFont((void*)&fontRef);
+#endif
+ return cgFont;
+}
+#endif
+
+
+
}
diff --git a/WebCore/platform/graphics/GlyphMetricsMap.cpp b/WebCore/platform/graphics/wx/FontPlatformDataWxMac.mm
index d3c3180..b719656 100644
--- a/WebCore/platform/graphics/GlyphMetricsMap.cpp
+++ b/WebCore/platform/graphics/wx/FontPlatformDataWxMac.mm
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Kevin Ollivier All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -25,38 +25,26 @@
* (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 "GlyphMetricsMap.h"
+#include "FontPlatformData.h"
+
+#include <wx/defs.h>
+#include <wx/font.h>
namespace WebCore {
-GlyphMetricsMap::GlyphMetricsPage* GlyphMetricsMap::locatePageSlowCase(unsigned pageNumber)
+NSFont* FontPlatformData::nsFont() const
{
- GlyphMetricsPage* page;
- if (!pageNumber) {
- ASSERT(!m_filledPrimaryPage);
- page = &m_primaryPage;
- m_filledPrimaryPage = true;
- } else {
- if (m_pages) {
- if ((page = m_pages->get(pageNumber)))
- return page;
- } else
- m_pages.set(new HashMap<int, GlyphMetricsPage*>);
- page = new GlyphMetricsPage;
- m_pages->set(pageNumber, page);
- }
+#if wxCHECK_VERSION(2,9,1) && wxOSX_USE_COCOA
+ if (m_font && m_font->font())
+ return (NSFont*)m_font->font()->OSXGetNSFont();
+#endif
+}
- GlyphMetrics unknownMetrics;
- unknownMetrics.horizontalAdvance = cGlyphSizeUnknown;
- unknownMetrics.boundingBox.setWidth(cGlyphSizeUnknown);
- unknownMetrics.boundingBox.setHeight(cGlyphSizeUnknown);
- // Fill in the whole page with the unknown glyph information.
- for (unsigned i = 0; i < GlyphMetricsPage::size; i++)
- page->setMetricsForIndex(i, unknownMetrics);
+void FontPlatformData::cacheNSFont()
+{
- return page;
}
}
diff --git a/WebCore/platform/graphics/wx/FontWx.cpp b/WebCore/platform/graphics/wx/FontWx.cpp
index dce3841..c00c622 100644
--- a/WebCore/platform/graphics/wx/FontWx.cpp
+++ b/WebCore/platform/graphics/wx/FontWx.cpp
@@ -35,6 +35,11 @@
#if OS(WINDOWS)
#include "UniscribeController.h"
+typedef UniscribeController ComplexTextController
+#endif
+
+#if OS(DARWIN)
+#include "mac/ComplexTextController.h"
#endif
#include <wx/dcclient.h>
@@ -45,7 +50,7 @@ namespace WebCore {
bool Font::canReturnFallbackFontsForComplexText()
{
-#if OS(WINDOWS)
+#if OS(WINDOWS) || OS(DARWIN)
return true;
#else
return false;
@@ -67,8 +72,8 @@ void Font::drawGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* fo
FloatRect Font::selectionRectForComplexText(const TextRun& run, const IntPoint& point, int h, int from, int to) const
{
-#if OS(WINDOWS)
- UniscribeController it(this, run);
+#if OS(WINDOWS) || OS(DARWIN)
+ ComplexTextController it(this, run);
it.advance(from);
float beforeWidth = it.runWidthSoFar();
it.advance(to);
@@ -76,9 +81,14 @@ FloatRect Font::selectionRectForComplexText(const TextRun& run, const IntPoint&
// Using roundf() rather than ceilf() for the right edge as a compromise to ensure correct caret positioning
if (run.rtl()) {
+#if OS(WINDOWS)
it.advance(run.length());
float totalWidth = it.runWidthSoFar();
return FloatRect(point.x() + floorf(totalWidth - afterWidth), point.y(), roundf(totalWidth - beforeWidth) - floorf(totalWidth - afterWidth), h);
+#else
+ float totalWidth = it.totalWidth();
+ return FloatRect(point.x() + floorf(totalWidth - afterWidth), point.y(), roundf(totalWidth - beforeWidth) - floorf(totalWidth - afterWidth), h);
+#endif
}
return FloatRect(point.x() + floorf(beforeWidth), point.y(), roundf(afterWidth) - floorf(beforeWidth), h);
@@ -90,12 +100,12 @@ FloatRect Font::selectionRectForComplexText(const TextRun& run, const IntPoint&
void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const
{
-#if OS(WINDOWS)
+#if OS(WINDOWS) || OS(DARWIN)
// This glyph buffer holds our glyphs + advances + font data for each glyph.
GlyphBuffer glyphBuffer;
float startX = point.x();
- UniscribeController controller(this, run);
+ ComplexTextController controller(this, run);
controller.advance(from);
float beforeWidth = controller.runWidthSoFar();
controller.advance(to, &glyphBuffer);
@@ -107,8 +117,14 @@ void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const F
float afterWidth = controller.runWidthSoFar();
if (run.rtl()) {
+#if OS(WINDOWS)
controller.advance(run.length());
startX += controller.runWidthSoFar() - afterWidth;
+#else
+ startX += controller.totalWidth() + controller.finalRoundingWidth() - afterWidth;
+ for (int i = 0, end = glyphBuffer.size() - 1; i < glyphBuffer.size() / 2; ++i, --end)
+ glyphBuffer.swap(i, end);
+#endif
} else
startX += beforeWidth;
@@ -123,11 +139,15 @@ void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const F
float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow*) const
{
+#if OS(WINDOWS) || OS(DARWIN)
+ ComplexTextController controller(this, run, fallbackFonts);
#if OS(WINDOWS)
- UniscribeController controller(this, run, fallbackFonts);
controller.advance(run.length());
return controller.runWidthSoFar();
#else
+ return controller.totalWidth();
+#endif
+#else
notImplemented();
return 0;
#endif
@@ -135,8 +155,8 @@ float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFon
int Font::offsetForPositionForComplexText(const TextRun& run, int x, bool includePartialGlyphs) const
{
-#if OS(WINDOWS)
- UniscribeController controller(this, run);
+#if OS(WINDOWS) || OS(DARWIN)
+ ComplexTextController controller(this, run);
return controller.offsetForPosition(x, includePartialGlyphs);
#else
notImplemented();
diff --git a/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp b/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp
index 3c8a1da..e899715 100644
--- a/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp
+++ b/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp
@@ -36,8 +36,13 @@
#include <unicode/uchar.h>
#include <unicode/unorm.h>
+#if OS(DARWIN)
+#include "WebCoreSystemInterface.h"
+#endif
+
#include <wx/defs.h>
#include <wx/dcscreen.h>
+#include <wx/string.h>
#include "fontprops.h"
namespace WebCore
@@ -56,11 +61,12 @@ void SimpleFontData::platformInit()
m_lineGap = props.GetLineGap();
}
+ m_syntheticBoldOffset = 0.0f;
+
#if OS(WINDOWS)
m_scriptCache = 0;
m_scriptFontProperties = 0;
m_isSystemFont = false;
- m_syntheticBoldOffset = 0.0f;
#endif
}
@@ -91,9 +97,9 @@ SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDes
{
if (!m_smallCapsFontData){
FontDescription desc = FontDescription(fontDescription);
- desc.setSpecifiedSize(0.70f*fontDescription.computedSize());
- const FontPlatformData* pdata = new FontPlatformData(desc, desc.family().family());
- m_smallCapsFontData = new SimpleFontData(*pdata);
+ desc.setSpecifiedSize(0.70f * fontDescription.computedSize());
+ FontPlatformData platformData(desc, desc.family().family());
+ m_smallCapsFontData = new SimpleFontData(platformData);
}
return m_smallCapsFontData;
}
@@ -101,7 +107,12 @@ SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDes
bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
{
// FIXME: We will need to implement this to load non-ASCII encoding sites
- return wxFontContainsCharacters(*m_platformData.font(), characters, length);
+#if OS(WINDOWS)
+ return wxFontContainsCharacters(m_platformData.hfont(), characters, length);
+#elif OS(DARWIN)
+ return wxFontContainsCharacters(m_platformData.nsFont(), characters, length);
+#endif
+ return true;
}
void SimpleFontData::determinePitch()
@@ -112,19 +123,32 @@ void SimpleFontData::determinePitch()
m_treatAsFixedPitch = false;
}
-GlyphMetrics SimpleFontData::platformMetricsForGlyph(Glyph glyph, GlyphMetricsMode) const
+FloatRect SimpleFontData::platformBoundsForGlyph(Glyph) const
+{
+ return FloatRect();
+}
+
+float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
{
- GlyphMetrics metrics;
#if __WXMSW__
// under Windows / wxMSW we currently always use GDI fonts.
- metrics.horizontalAdvance = widthForGDIGlyph(glyph);
+ return widthForGDIGlyph(glyph);
+#elif OS(DARWIN)
+ float pointSize = m_platformData.size();
+ CGAffineTransform m = CGAffineTransformMakeScale(pointSize, pointSize);
+ CGSize advance;
+ NSFont* nsfont = (NSFont*)m_platformData.nsFont();
+ if (!wkGetGlyphTransformedAdvances(m_platformData.cgFont(), nsfont, &m, &glyph, &advance)) {
+ // LOG_ERROR("Unable to cache glyph widths for %@ %f", [nsfont displayName], pointSize);
+ advance.width = 0;
+ }
+ return advance.width + m_syntheticBoldOffset;
#else
// TODO: fix this! Make GetTextExtents a method of wxFont in 2.9
int width = 10;
GetTextExtent(*m_platformData.font(), (wxChar)glyph, &width, NULL);
- metrics.horizontalAdvance = width;
+ return width;
#endif
- return metrics;
}
#if OS(WINDOWS)
diff --git a/WebCore/platform/gtk/ClipboardGtk.cpp b/WebCore/platform/gtk/ClipboardGtk.cpp
index 93a21e2..9bee55a 100644
--- a/WebCore/platform/gtk/ClipboardGtk.cpp
+++ b/WebCore/platform/gtk/ClipboardGtk.cpp
@@ -24,6 +24,8 @@
#include "Frame.h"
#include "Image.h"
#include "NotImplemented.h"
+#include "Pasteboard.h"
+#include "PasteboardHelper.h"
#include "RenderImage.h"
#include "StringHash.h"
#include "markup.h"
@@ -32,13 +34,33 @@
namespace WebCore {
+enum ClipboardType {
+ ClipboardTypeText,
+ ClipboardTypeMarkup,
+ ClipboardTypeURIList,
+ ClipboardTypeURL,
+ ClipboardTypeImage,
+ ClipboardTypeUnknown
+};
+
PassRefPtr<Clipboard> Editor::newGeneralClipboard(ClipboardAccessPolicy policy)
{
- return ClipboardGtk::create(policy, false);
+ return ClipboardGtk::create(policy, gtk_clipboard_get_for_display(gdk_display_get_default(), GDK_SELECTION_CLIPBOARD), false);
+}
+
+ClipboardGtk::ClipboardGtk(ClipboardAccessPolicy policy, GtkClipboard* clipboard)
+ : Clipboard(policy, false)
+ , m_dataObject(DataObjectGtk::forClipboard(clipboard))
+ , m_clipboard(clipboard)
+ , m_helper(Pasteboard::generalPasteboard()->helper())
+{
}
-ClipboardGtk::ClipboardGtk(ClipboardAccessPolicy policy, bool forDragging)
+ClipboardGtk::ClipboardGtk(ClipboardAccessPolicy policy, PassRefPtr<DataObjectGtk> dataObject, bool forDragging)
: Clipboard(policy, forDragging)
+ , m_dataObject(dataObject)
+ , m_clipboard(0)
+ , m_helper(Pasteboard::generalPasteboard()->helper())
{
}
@@ -46,39 +68,197 @@ ClipboardGtk::~ClipboardGtk()
{
}
-void ClipboardGtk::clearData(const String&)
+static ClipboardType dataObjectTypeFromHTMLClipboardType(const String& rawType)
{
- notImplemented();
+ String type(rawType.stripWhiteSpace());
+
+ // Two special cases for IE compatibility
+ if (type == "Text")
+ return ClipboardTypeText;
+ if (type == "URL")
+ return ClipboardTypeURL;
+
+ // From the Mac port: Ignore any trailing charset - JS strings are
+ // Unicode, which encapsulates the charset issue.
+ if (type == "text/plain" || type.startsWith("text/plain;"))
+ return ClipboardTypeText;
+ if (type == "text/html" || type.startsWith("text/html;"))
+ return ClipboardTypeMarkup;
+ if (type == "Files" || type == "text/uri-list" || type.startsWith("text/uri-list;"))
+ return ClipboardTypeURIList;
+
+ // Not a known type, so just default to using the text portion.
+ return ClipboardTypeUnknown;
}
+void ClipboardGtk::clearData(const String& typeString)
+{
+ if (policy() != ClipboardWritable)
+ return;
+
+ ClipboardType type = dataObjectTypeFromHTMLClipboardType(typeString);
+ switch (type) {
+ case ClipboardTypeURIList:
+ case ClipboardTypeURL:
+ m_dataObject->clearURIList();
+ break;
+ case ClipboardTypeMarkup:
+ m_dataObject->clearMarkup();
+ break;
+ case ClipboardTypeText:
+ m_dataObject->clearText();
+ break;
+ case ClipboardTypeUnknown:
+ default:
+ m_dataObject->clear();
+ }
+
+ if (m_clipboard)
+ m_helper->writeClipboardContents(m_clipboard);
+}
+
+
void ClipboardGtk::clearAllData()
{
- notImplemented();
+ if (policy() != ClipboardWritable)
+ return;
+
+ m_dataObject->clear();
+
+ if (m_clipboard)
+ m_helper->writeClipboardContents(m_clipboard);
}
-String ClipboardGtk::getData(const String&, bool &success) const
+static String joinURIList(Vector<KURL> uriList)
{
- notImplemented();
- success = false;
+ if (uriList.isEmpty())
+ return String();
+
+ String joined(uriList[0].string());
+ for (size_t i = 1; i < uriList.size(); i++) {
+ joined.append("\r\n");
+ joined.append(uriList[i].string());
+ }
+
+ return joined;
+}
+
+String ClipboardGtk::getData(const String& typeString, bool& success) const
+{
+ success = false; // Pessimism.
+ if (policy() != ClipboardReadable || !m_dataObject)
+ return String();
+
+ if (m_clipboard)
+ m_helper->getClipboardContents(m_clipboard);
+
+ ClipboardType type = dataObjectTypeFromHTMLClipboardType(typeString);
+ if (type == ClipboardTypeURIList) {
+ if (!m_dataObject->hasURIList())
+ return String();
+ success = true;
+ return joinURIList(m_dataObject->uriList());
+ }
+
+ if (type == ClipboardTypeURL) {
+ if (!m_dataObject->hasURL())
+ return String();
+ success = true;
+ return m_dataObject->url();
+ }
+
+ if (type == ClipboardTypeMarkup) {
+ if (!m_dataObject->hasMarkup())
+ return String();
+ success = true;
+ return m_dataObject->markup();
+ }
+
+ if (type == ClipboardTypeText) {
+ if (!m_dataObject->hasText())
+ return String();
+ success = true;
+ return m_dataObject->text();
+ }
+
return String();
}
-bool ClipboardGtk::setData(const String&, const String&)
+bool ClipboardGtk::setData(const String& typeString, const String& data)
{
- notImplemented();
- return false;
+ if (policy() != ClipboardWritable)
+ return false;
+
+ bool success = false;
+ ClipboardType type = dataObjectTypeFromHTMLClipboardType(typeString);
+ if (type == ClipboardTypeURIList || type == ClipboardTypeURL) {
+ Vector<KURL> uriList;
+ gchar** uris = g_uri_list_extract_uris(data.utf8().data());
+ if (uris) {
+ gchar** currentURI = uris;
+ while (*currentURI) {
+ uriList.append(KURL(KURL(), *currentURI));
+ currentURI++;
+ }
+ g_strfreev(uris);
+ m_dataObject->setURIList(uriList);
+ success = true;
+ }
+ } else if (type == ClipboardTypeMarkup) {
+ m_dataObject->setMarkup(data);
+ success = true;
+ } else if (type == ClipboardTypeText) {
+ m_dataObject->setText(data);
+ success = true;
+ }
+
+ if (success && m_clipboard)
+ m_helper->writeClipboardContents(m_clipboard);
+
+ return success;
}
HashSet<String> ClipboardGtk::types() const
{
- notImplemented();
- return HashSet<String>();
+ if (policy() != ClipboardReadable && policy() != ClipboardTypesReadable)
+ return HashSet<String>();
+
+ if (m_clipboard)
+ m_helper->getClipboardContents(m_clipboard);
+
+ HashSet<String> types;
+ if (m_dataObject->hasText()) {
+ types.add("text/plain");
+ types.add("Text");
+ }
+
+ if (m_dataObject->hasMarkup())
+ types.add("text/html");
+
+ if (m_dataObject->hasURIList()) {
+ types.add("text/uri-list");
+ types.add("URL");
+ types.add("Files");
+ }
+
+ return types;
}
PassRefPtr<FileList> ClipboardGtk::files() const
{
- notImplemented();
- return 0;
+ if (policy() != ClipboardReadable)
+ return FileList::create();
+
+ if (m_clipboard)
+ m_helper->getClipboardContents(m_clipboard);
+
+ RefPtr<FileList> fileList = FileList::create();
+ Vector<String> fileVector(m_dataObject->files());
+
+ for (size_t i = 0; i < fileVector.size(); i++)
+ fileList->append(File::create(fileVector[i]));
+
+ return fileList.release();
}
IntPoint ClipboardGtk::dragLocation() const
@@ -151,44 +331,54 @@ void ClipboardGtk::declareAndWriteDragImage(Element* element, const KURL& url, c
void ClipboardGtk::writeURL(const KURL& url, const String& label, Frame*)
{
- GtkClipboard* textClipboard = gtk_clipboard_get(gdk_atom_intern_static_string("WebKitClipboardText"));
- GtkClipboard* urlClipboard = gtk_clipboard_get(gdk_atom_intern_static_string("WebKitClipboardUrl"));
- GtkClipboard* urlLabelClipboard = gtk_clipboard_get(gdk_atom_intern_static_string("WebKitClipboardUrlLabel"));
-
- gtk_clipboard_clear(textClipboard);
- gtk_clipboard_clear(urlClipboard);
- gtk_clipboard_clear(urlLabelClipboard);
-
- gtk_clipboard_set_text(textClipboard, url.string().utf8().data(), -1);
- gtk_clipboard_set_text(urlClipboard, url.string().utf8().data(), -1);
- gtk_clipboard_set_text(urlLabelClipboard, label.utf8().data(), -1);
+ String actualLabel(label);
+ if (actualLabel.isEmpty())
+ actualLabel = url;
+
+ m_dataObject->setText(url.string());
+
+ Vector<UChar> markup;
+ append(markup, "<a href=\"");
+ append(markup, url.string());
+ append(markup, "\">");
+ append(markup, label);
+ append(markup, "</a>");
+ m_dataObject->setMarkup(String::adopt(markup));
+
+ Vector<KURL> uriList;
+ uriList.append(url);
+ m_dataObject->setURIList(uriList);
+
+ if (m_clipboard)
+ m_helper->writeClipboardContents(m_clipboard);
}
void ClipboardGtk::writeRange(Range* range, Frame* frame)
{
- GtkClipboard* textClipboard = gtk_clipboard_get(gdk_atom_intern_static_string("WebKitClipboardText"));
- GtkClipboard* htmlClipboard = gtk_clipboard_get(gdk_atom_intern_static_string("WebKitClipboardHtml"));
+ ASSERT(range);
- gtk_clipboard_clear(textClipboard);
- gtk_clipboard_clear(htmlClipboard);
+ m_dataObject->setText(frame->selectedText());
+ m_dataObject->setMarkup(createMarkup(range, 0, AnnotateForInterchange));
- gtk_clipboard_set_text(textClipboard, frame->selectedText().utf8().data(), -1);
- gtk_clipboard_set_text(htmlClipboard, createMarkup(range, 0, AnnotateForInterchange).utf8().data(), -1);
+ if (m_clipboard)
+ m_helper->writeClipboardContents(m_clipboard);
}
void ClipboardGtk::writePlainText(const String& text)
{
- GtkClipboard* textClipboard = gtk_clipboard_get(gdk_atom_intern_static_string("WebKitClipboardText"));
-
- gtk_clipboard_clear(textClipboard);
-
- gtk_clipboard_set_text(textClipboard, text.utf8().data(), -1);
+ m_dataObject->setText(text);
+
+ if (m_clipboard)
+ m_helper->writeClipboardContents(m_clipboard);
}
-
+
bool ClipboardGtk::hasData()
{
- notImplemented();
- return false;
+ if (m_clipboard)
+ m_helper->getClipboardContents(m_clipboard);
+
+ return m_dataObject->hasText() || m_dataObject->hasMarkup()
+ || m_dataObject->hasURIList() || m_dataObject->hasImage();
}
}
diff --git a/WebCore/platform/gtk/ClipboardGtk.h b/WebCore/platform/gtk/ClipboardGtk.h
index 74e36b1..c3438c4 100644
--- a/WebCore/platform/gtk/ClipboardGtk.h
+++ b/WebCore/platform/gtk/ClipboardGtk.h
@@ -28,17 +28,26 @@
#define ClipboardGtk_h
#include "Clipboard.h"
+#include "DataObjectGtk.h"
+
+typedef struct _GtkClipboard GtkClipboard;
namespace WebCore {
class CachedImage;
+ class PasteboardHelper;
// State available during IE's events for drag and drop and copy/paste
// Created from the EventHandlerGtk to be used by the dom
class ClipboardGtk : public Clipboard {
public:
- static PassRefPtr<ClipboardGtk> create(ClipboardAccessPolicy policy, bool isForDragging)
+ static PassRefPtr<ClipboardGtk> create(ClipboardAccessPolicy policy, GtkClipboard* clipboard, bool isForDragging)
+ {
+ return adoptRef(new ClipboardGtk(policy, clipboard));
+ }
+
+ static PassRefPtr<ClipboardGtk> create(ClipboardAccessPolicy policy, PassRefPtr<DataObjectGtk> dataObject, bool isForDragging)
{
- return adoptRef(new ClipboardGtk(policy, isForDragging));
+ return adoptRef(new ClipboardGtk(policy, dataObject, isForDragging));
}
virtual ~ClipboardGtk();
@@ -64,8 +73,16 @@ namespace WebCore {
virtual bool hasData();
+ PasteboardHelper* helper() { return m_helper; }
+ PassRefPtr<DataObjectGtk> dataObject() { return m_dataObject; }
+
private:
- ClipboardGtk(ClipboardAccessPolicy, bool);
+ ClipboardGtk(ClipboardAccessPolicy, GtkClipboard*);
+ ClipboardGtk(ClipboardAccessPolicy, PassRefPtr<DataObjectGtk>, bool);
+
+ RefPtr<DataObjectGtk> m_dataObject;
+ GtkClipboard* m_clipboard;
+ PasteboardHelper* m_helper;
};
}
diff --git a/WebCore/platform/gtk/CursorGtk.cpp b/WebCore/platform/gtk/CursorGtk.cpp
index 1c669f3..705c2ae 100644
--- a/WebCore/platform/gtk/CursorGtk.cpp
+++ b/WebCore/platform/gtk/CursorGtk.cpp
@@ -88,13 +88,15 @@ Cursor::Cursor(GdkCursor* c)
: m_impl(c)
{
m_impl = c;
- ASSERT(c);
- gdk_cursor_ref(c);
+
+ // The GdkCursor may be NULL - the default cursor for the window.
+ if (c)
+ gdk_cursor_ref(c);
}
const Cursor& pointerCursor()
{
- static Cursor c = gdk_cursor_new(GDK_LEFT_PTR);
+ static Cursor c = 0;
return c;
}
diff --git a/WebCore/platform/gtk/DataObjectGtk.cpp b/WebCore/platform/gtk/DataObjectGtk.cpp
index 900fe8e..57d920c 100644
--- a/WebCore/platform/gtk/DataObjectGtk.cpp
+++ b/WebCore/platform/gtk/DataObjectGtk.cpp
@@ -24,6 +24,13 @@
namespace WebCore {
+static void replaceNonBreakingSpaceWithSpace(String& str)
+{
+ static const UChar NonBreakingSpaceCharacter = 0xA0;
+ static const UChar SpaceCharacter = ' ';
+ str.replace(NonBreakingSpaceCharacter, SpaceCharacter);
+}
+
String DataObjectGtk::text()
{
if (m_range)
@@ -34,7 +41,7 @@ String DataObjectGtk::text()
String DataObjectGtk::markup()
{
if (m_range)
- createMarkup(m_range.get(), 0, AnnotateForInterchange);
+ return createMarkup(m_range.get(), 0, AnnotateForInterchange);
return m_markup;
}
@@ -42,6 +49,7 @@ void DataObjectGtk::setText(const String& newText)
{
m_range = 0;
m_text = newText;
+ replaceNonBreakingSpaceWithSpace(m_text);
}
void DataObjectGtk::setMarkup(const String& newMarkup)
@@ -50,6 +58,18 @@ void DataObjectGtk::setMarkup(const String& newMarkup)
m_markup = newMarkup;
}
+void DataObjectGtk::clearText()
+{
+ m_range = 0;
+ m_text = "";
+}
+
+void DataObjectGtk::clearMarkup()
+{
+ m_range = 0;
+ m_markup = "";
+}
+
Vector<String> DataObjectGtk::files()
{
Vector<KURL> uris(uriList());
diff --git a/WebCore/platform/gtk/DataObjectGtk.h b/WebCore/platform/gtk/DataObjectGtk.h
index 22158d4..41f8f49 100644
--- a/WebCore/platform/gtk/DataObjectGtk.h
+++ b/WebCore/platform/gtk/DataObjectGtk.h
@@ -50,6 +50,8 @@ public:
bool hasMarkup() { return m_range || !m_markup.isEmpty(); }
bool hasURIList() { return !m_uriList.isEmpty(); }
bool hasImage() { return m_image; }
+ void clearURIList() { m_uriList.clear(); }
+ void clearImage() { m_image = 0; }
GdkDragContext* dragContext() { return m_dragContext.get(); }
String text();
@@ -61,6 +63,8 @@ public:
String url();
String urlLabel();
void clear();
+ void clearText();
+ void clearMarkup();
static DataObjectGtk* forClipboard(GtkClipboard*);
diff --git a/WebCore/platform/gtk/PasteboardGtk.cpp b/WebCore/platform/gtk/PasteboardGtk.cpp
index 907a55e..9e7b23a 100644
--- a/WebCore/platform/gtk/PasteboardGtk.cpp
+++ b/WebCore/platform/gtk/PasteboardGtk.cpp
@@ -61,7 +61,7 @@ static void clipboard_get_contents_cb(GtkClipboard *clipboard, GtkSelectionData
if (info == Pasteboard::generalPasteboard()->helper()->getIdForTargetType(PasteboardHelper::TargetTypeMarkup))
gtk_selection_data_set(selection_data, selection_data->target, 8,
reinterpret_cast<const guchar*>(clipboardData->markup()),
- g_utf8_strlen(clipboardData->markup(), -1));
+ strlen(clipboardData->markup()));
else
gtk_selection_data_set_text(selection_data, clipboardData->text(), -1);
}
diff --git a/WebCore/platform/gtk/PasteboardHelper.cpp b/WebCore/platform/gtk/PasteboardHelper.cpp
index be32ea5..3dc4cc0 100644
--- a/WebCore/platform/gtk/PasteboardHelper.cpp
+++ b/WebCore/platform/gtk/PasteboardHelper.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Martin Robinson <mrobinson@webkit.org>
+ * Copyright (C) Igalia S.L.
* All rights reserved.
*
* This library is free software; you can redistribute it and/or
@@ -26,12 +27,15 @@
#include "Frame.h"
#include "Page.h"
#include "Pasteboard.h"
+#include "TextResourceDecoder.h"
#include <gtk/gtk.h>
#include <wtf/gobject/GOwnPtr.h>
namespace WebCore {
static GdkAtom gdkMarkupAtom = gdk_atom_intern("text/html", FALSE);
+static GdkAtom netscapeURLAtom = gdk_atom_intern("_NETSCAPE_URL", FALSE);
+static GdkAtom uriListAtom = gdk_atom_intern("text/uri-list", FALSE);
PasteboardHelper::PasteboardHelper()
: m_targetList(gtk_target_list_new(0, 0))
@@ -48,6 +52,8 @@ void PasteboardHelper::initializeTargetList()
{
gtk_target_list_add_text_targets(m_targetList, getIdForTargetType(TargetTypeText));
gtk_target_list_add(m_targetList, gdkMarkupAtom, 0, getIdForTargetType(TargetTypeMarkup));
+ gtk_target_list_add_uri_targets(m_targetList, getIdForTargetType(TargetTypeURIList));
+ gtk_target_list_add(m_targetList, netscapeURLAtom, 0, getIdForTargetType(TargetTypeNetscapeURL));
}
static inline GtkWidget* widgetFromFrame(Frame* frame)
@@ -84,16 +90,85 @@ GtkTargetList* PasteboardHelper::targetList() const
return m_targetList;
}
+static Vector<KURL> urisToKURLVector(gchar** uris)
+{
+ ASSERT(uris);
+
+ Vector<KURL> uriList;
+ for (int i = 0; *(uris + i); i++)
+ uriList.append(KURL(KURL(), *(uris + i)));
+
+ return uriList;
+}
+
+void PasteboardHelper::getClipboardContents(GtkClipboard* clipboard)
+{
+ DataObjectGtk* dataObject = DataObjectGtk::forClipboard(clipboard);
+ ASSERT(dataObject);
+
+ if (gtk_clipboard_wait_is_text_available(clipboard)) {
+ GOwnPtr<gchar> textData(gtk_clipboard_wait_for_text(clipboard));
+ if (textData)
+ dataObject->setText(String::fromUTF8(textData.get()));
+ }
+
+ if (gtk_clipboard_wait_is_target_available(clipboard, gdkMarkupAtom)) {
+ if (GtkSelectionData* data = gtk_clipboard_wait_for_contents(clipboard, gdkMarkupAtom)) {
+ RefPtr<TextResourceDecoder> decoder(TextResourceDecoder::create("text/plain", "UTF-8", true));
+ String markup(decoder->decode(reinterpret_cast<char*>(data->data), data->length));
+ markup += decoder->flush();
+ dataObject->setMarkup(markup);
+ gtk_selection_data_free(data);
+ }
+ }
+
+ if (gtk_clipboard_wait_is_target_available(clipboard, uriListAtom)) {
+ if (GtkSelectionData* data = gtk_clipboard_wait_for_contents(clipboard, uriListAtom)) {
+ gchar** uris = gtk_selection_data_get_uris(data);
+ if (uris) {
+ dataObject->setURIList(urisToKURLVector(uris));
+ g_strfreev(uris);
+ }
+ gtk_selection_data_free(data);
+ }
+ }
+}
+
void PasteboardHelper::fillSelectionData(GtkSelectionData* selectionData, guint info, DataObjectGtk* dataObject)
{
if (info == getIdForTargetType(TargetTypeText))
gtk_selection_data_set_text(selectionData, dataObject->text().utf8().data(), -1);
+
else if (info == getIdForTargetType(TargetTypeMarkup)) {
GOwnPtr<gchar> markup(g_strdup(dataObject->markup().utf8().data()));
gtk_selection_data_set(selectionData, selectionData->target, 8,
- reinterpret_cast<const guchar*>(markup.get()),
- strlen(markup.get()));
- }
+ reinterpret_cast<const guchar*>(markup.get()), strlen(markup.get()));
+
+ } else if (info == getIdForTargetType(TargetTypeURIList)) {
+ Vector<KURL> uriList(dataObject->uriList());
+ gchar** uris = g_new0(gchar*, uriList.size() + 1);
+ for (size_t i = 0; i < uriList.size(); i++)
+ uris[i] = g_strdup(uriList[i].string().utf8().data());
+
+ gtk_selection_data_set_uris(selectionData, uris);
+ g_strfreev(uris);
+
+ } else if (info == getIdForTargetType(TargetTypeNetscapeURL) && dataObject->hasURL()) {
+ String url(dataObject->url());
+ String result(url);
+ result.append("\n");
+
+ if (dataObject->hasText())
+ result.append(dataObject->text());
+ else
+ result.append(url);
+
+ GOwnPtr<gchar> resultData(g_strdup(result.utf8().data()));
+ gtk_selection_data_set(selectionData, selectionData->target, 8,
+ reinterpret_cast<const guchar*>(resultData.get()), strlen(resultData.get()));
+
+ } else if (info == getIdForTargetType(TargetTypeImage))
+ gtk_selection_data_set_pixbuf(selectionData, dataObject->image());
}
GtkTargetList* PasteboardHelper::targetListForDataObject(DataObjectGtk* dataObject)
@@ -106,6 +181,14 @@ GtkTargetList* PasteboardHelper::targetListForDataObject(DataObjectGtk* dataObje
if (dataObject->hasMarkup())
gtk_target_list_add(list, gdkMarkupAtom, 0, getIdForTargetType(TargetTypeMarkup));
+ if (dataObject->hasURIList()) {
+ gtk_target_list_add_uri_targets(list, getIdForTargetType(TargetTypeURIList));
+ gtk_target_list_add(list, netscapeURLAtom, 0, getIdForTargetType(TargetTypeNetscapeURL));
+ }
+
+ if (dataObject->hasImage())
+ gtk_target_list_add_image_targets(list, getIdForTargetType(TargetTypeImage), TRUE);
+
return list;
}
diff --git a/WebCore/platform/gtk/PasteboardHelper.h b/WebCore/platform/gtk/PasteboardHelper.h
index 6e5d366..2d46adc 100644
--- a/WebCore/platform/gtk/PasteboardHelper.h
+++ b/WebCore/platform/gtk/PasteboardHelper.h
@@ -2,6 +2,7 @@
* Copyright (C) 2007 Luca Bruno <lethalman88@gmail.com>
* Copyright (C) 2009 Holger Hans Peter Freyther
* Copyright (C) 2010 Martin Robinson <mrobinson@webkit.org>
+ * Copyright (C) 2010 Igalia S.L.
* All rights reserved.
*
* This library is free software; you can redistribute it and/or
@@ -49,8 +50,10 @@ public:
GtkClipboard* getClipboard(Frame*) const;
GtkClipboard* getPrimarySelectionClipboard(Frame*) const;
GtkTargetList* targetList() const;
+ GtkTargetList* targetListForDataObject(DataObjectGtk*);
void fillSelectionData(GtkSelectionData*, guint, DataObjectGtk*);
- void writeClipboardContents(GtkClipboard*, GClosure*);
+ void writeClipboardContents(GtkClipboard*, GClosure* closure = 0);
+ void getClipboardContents(GtkClipboard*);
enum PasteboardTargetType { TargetTypeText, TargetTypeMarkup, TargetTypeURIList, TargetTypeNetscapeURL, TargetTypeImage, TargetTypeUnknown };
virtual guint getIdForTargetType(PasteboardTargetType) = 0;
@@ -61,7 +64,6 @@ protected:
private:
GtkTargetList* m_targetList;
- GtkTargetList* targetListForDataObject(DataObjectGtk*);
};
}
diff --git a/WebCore/platform/gtk/RenderThemeGtk.cpp b/WebCore/platform/gtk/RenderThemeGtk.cpp
index 93794ff..31af1a9 100644
--- a/WebCore/platform/gtk/RenderThemeGtk.cpp
+++ b/WebCore/platform/gtk/RenderThemeGtk.cpp
@@ -92,8 +92,11 @@ void RenderThemeGtk::initMediaStyling(GtkStyle* style, bool force)
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);
+ // Note that the muteButton and unmuteButton take icons reflecting
+ // the *current* state. Hence, the unmuteButton represents the *muted*
+ // status, the muteButton represents the then current *unmuted* status.
+ m_muteButton = Image::loadPlatformThemeIcon("audio-volume-high", m_mediaIconSize);
+ m_unmuteButton = Image::loadPlatformThemeIcon("audio-volume-muted", 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);
diff --git a/WebCore/platform/gtk/ScrollViewGtk.cpp b/WebCore/platform/gtk/ScrollViewGtk.cpp
index 3df3cb5..5c258ad 100644
--- a/WebCore/platform/gtk/ScrollViewGtk.cpp
+++ b/WebCore/platform/gtk/ScrollViewGtk.cpp
@@ -72,6 +72,29 @@ PassRefPtr<Scrollbar> ScrollView::createScrollbar(ScrollbarOrientation orientati
return Scrollbar::createNativeScrollbar(this, orientation, RegularScrollbar);
}
+#if !GTK_CHECK_VERSION(2, 14, 0)
+#define gtk_adjustment_configure AdjustmentConfigure
+
+static void AdjustmentConfigure(GtkAdjustment* adjustment, gdouble value, gdouble lower, gdouble upper,
+ gdouble stepIncrement, gdouble pageIncrement, gdouble pageSize)
+{
+ g_object_freeze_notify(G_OBJECT(adjustment));
+
+ g_object_set(adjustment,
+ "lower", lower,
+ "upper", upper,
+ "step-increment", stepIncrement,
+ "page-increment", pageIncrement,
+ "page-size", pageSize,
+ NULL);
+
+ g_object_thaw_notify(G_OBJECT(adjustment));
+
+ gtk_adjustment_changed(adjustment);
+ gtk_adjustment_value_changed(adjustment);
+}
+#endif
+
/*
* The following is assumed:
* (hadj && vadj) || (!hadj && !vadj)
@@ -100,17 +123,22 @@ void ScrollView::setGtkAdjustments(GtkAdjustment* hadj, GtkAdjustment* vadj, boo
// set in the normal case), we make sure they are up-to-date
// here. This is needed for the parent scrolling widget to be
// able to report correct values.
- m_horizontalAdjustment->lower = 0;
- m_horizontalAdjustment->upper = resetValues ? 0 : frameRect().width();
- m_horizontalAdjustment->value = resetValues ? 0 : scrollOffset().width();
- gtk_adjustment_changed(m_horizontalAdjustment);
- gtk_adjustment_value_changed(m_horizontalAdjustment);
-
- m_verticalAdjustment->lower = 0;
- m_verticalAdjustment->upper = resetValues ? 0 : frameRect().height();
- m_verticalAdjustment->value = resetValues ? 0 : scrollOffset().height();
- gtk_adjustment_changed(m_verticalAdjustment);
- gtk_adjustment_value_changed(m_verticalAdjustment);
+
+ int horizontalPageStep = max(max<int>(frameRect().width() * Scrollbar::minFractionToStepWhenPaging(), frameRect().width() - Scrollbar::maxOverlapBetweenPages()), 1);
+ gtk_adjustment_configure(m_horizontalAdjustment,
+ resetValues ? 0 : scrollOffset().width(), 0,
+ resetValues ? 0 : contentsSize().width(),
+ resetValues ? 0 : Scrollbar::pixelsPerLineStep(),
+ resetValues ? 0 : horizontalPageStep,
+ resetValues ? 0 : frameRect().width());
+
+ int verticalPageStep = max(max<int>(frameRect().height() * Scrollbar::minFractionToStepWhenPaging(), frameRect().height() - Scrollbar::maxOverlapBetweenPages()), 1);
+ gtk_adjustment_configure(m_verticalAdjustment,
+ resetValues ? 0 : scrollOffset().height(), 0,
+ resetValues ? 0 : contentsSize().height(),
+ resetValues ? 0 : Scrollbar::pixelsPerLineStep(),
+ resetValues ? 0 : verticalPageStep,
+ resetValues ? 0 : frameRect().height());
} else {
ScrollbarGtk* hScrollbar = reinterpret_cast<ScrollbarGtk*>(horizontalScrollbar());
if (hScrollbar)
diff --git a/WebCore/platform/gtk/WidgetGtk.cpp b/WebCore/platform/gtk/WidgetGtk.cpp
index 834c21a..71addfd 100644
--- a/WebCore/platform/gtk/WidgetGtk.cpp
+++ b/WebCore/platform/gtk/WidgetGtk.cpp
@@ -53,9 +53,10 @@ Widget::~Widget()
releasePlatformWidget();
}
-void Widget::setFocus()
+void Widget::setFocus(bool focused)
{
- gtk_widget_grab_focus(platformWidget() ? platformWidget() : GTK_WIDGET(root()->hostWindow()->platformPageClient()));
+ if (focused)
+ gtk_widget_grab_focus(platformWidget() ? platformWidget() : GTK_WIDGET(root()->hostWindow()->platformPageClient()));
}
static GdkDrawable* gdkDrawable(PlatformWidget widget)
diff --git a/WebCore/platform/haiku/WidgetHaiku.cpp b/WebCore/platform/haiku/WidgetHaiku.cpp
index 5ff504f..3663d67 100644
--- a/WebCore/platform/haiku/WidgetHaiku.cpp
+++ b/WebCore/platform/haiku/WidgetHaiku.cpp
@@ -80,11 +80,13 @@ void Widget::setFrameRect(const IntRect& rect)
m_frame = rect;
}
-void Widget::setFocus()
+void Widget::setFocus(bool focused)
{
- AutoPlatformWidgetLocker locker(topLevelPlatformWidget());
- if (locker.isLocked())
- topLevelPlatformWidget()->MakeFocus();
+ if (focused) {
+ AutoPlatformWidgetLocker locker(topLevelPlatformWidget());
+ if (locker.isLocked())
+ topLevelPlatformWidget()->MakeFocus();
+ }
}
void Widget::setCursor(const Cursor& cursor)
diff --git a/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp b/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp
index 5965ae4..147085f 100644
--- a/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp
+++ b/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp
@@ -235,13 +235,13 @@ bool GIFImageDecoder::haveDecodedRow(unsigned frameIndex, unsigned char* rowBuff
return true;
}
-void GIFImageDecoder::frameComplete(unsigned frameIndex, unsigned frameDuration, RGBA32Buffer::FrameDisposalMethod disposalMethod)
+bool GIFImageDecoder::frameComplete(unsigned frameIndex, unsigned frameDuration, RGBA32Buffer::FrameDisposalMethod disposalMethod)
{
// Initialize the frame if necessary. Some GIFs insert do-nothing frames,
// in which case we never reach haveDecodedRow() before getting here.
RGBA32Buffer& buffer = m_frameBufferCache[frameIndex];
if ((buffer.status() == RGBA32Buffer::FrameEmpty) && !initFrameBuffer(frameIndex))
- return;
+ return false; // initFrameBuffer() has already called setFailed().
buffer.setStatus(RGBA32Buffer::FrameComplete);
buffer.setDuration(frameDuration);
@@ -277,6 +277,8 @@ void GIFImageDecoder::frameComplete(unsigned frameIndex, unsigned frameDuration,
buffer.setHasAlpha(false);
}
}
+
+ return true;
}
void GIFImageDecoder::gifComplete()
@@ -294,7 +296,9 @@ void GIFImageDecoder::decode(unsigned haltAtFrame, GIFQuery query)
if (!m_reader)
m_reader.set(new GIFImageReader(this));
- if (!m_reader->read((const unsigned char*)m_data->data() + m_readOffset, m_data->size() - m_readOffset, query, haltAtFrame))
+ // If we couldn't decode the image but we've received all the data, decoding
+ // has failed.
+ if (!m_reader->read((const unsigned char*)m_data->data() + m_readOffset, m_data->size() - m_readOffset, query, haltAtFrame) && isAllDataReceived())
setFailed();
if (failed())
diff --git a/WebCore/platform/image-decoders/gif/GIFImageDecoder.h b/WebCore/platform/image-decoders/gif/GIFImageDecoder.h
index 28a9a59..1c3378c 100644
--- a/WebCore/platform/image-decoders/gif/GIFImageDecoder.h
+++ b/WebCore/platform/image-decoders/gif/GIFImageDecoder.h
@@ -54,13 +54,14 @@ namespace WebCore {
// Callbacks from the GIF reader.
void decodingHalted(unsigned bytesLeft);
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);
+ bool frameComplete(unsigned frameIndex, unsigned frameDuration, RGBA32Buffer::FrameDisposalMethod disposalMethod);
void gifComplete();
private:
// If the query is GIFFullQuery, decodes the image up to (but not
// including) |haltAtFrame|. Otherwise, decodes as much as is needed to
- // answer the query, ignoring bitmap data.
+ // answer the query, ignoring bitmap data. If decoding fails but there
+ // is no more data coming, sets the "decode failure" flag.
void decode(unsigned haltAtFrame, GIFQuery);
// Called to initialize the frame buffer with the given index, based on
diff --git a/WebCore/platform/image-decoders/gif/GIFImageReader.cpp b/WebCore/platform/image-decoders/gif/GIFImageReader.cpp
index 677853e..be77426 100644
--- a/WebCore/platform/image-decoders/gif/GIFImageReader.cpp
+++ b/WebCore/platform/image-decoders/gif/GIFImageReader.cpp
@@ -290,7 +290,9 @@ bool 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 */
- return !rows_remaining;
+ if (!rows_remaining)
+ return true;
+ return clientptr ? clientptr->setFailed() : false;
}
if (oldcode == -1) {
@@ -308,13 +310,13 @@ bool GIFImageReader::do_lzw(const unsigned char *q)
code = oldcode;
if (stackp == stack + MAX_BITS)
- return false;
+ return clientptr ? clientptr->setFailed() : false;
}
while (code >= clear_code)
{
if (code >= MAX_BITS || code == prefix[code])
- return false;
+ return clientptr ? clientptr->setFailed() : false;
// Even though suffix[] only holds characters through suffix[avail - 1],
// allowing code >= avail here lets us be more tolerant of malformed
@@ -324,7 +326,7 @@ bool GIFImageReader::do_lzw(const unsigned char *q)
code = prefix[code];
if (stackp == stack + MAX_BITS)
- return false;
+ return clientptr ? clientptr->setFailed() : false;
}
*stackp++ = firstchar = suffix[code];
@@ -415,7 +417,7 @@ bool GIFImageReader::read(const unsigned char *buf, unsigned len,
bytes_to_consume -= l;
if (clientptr)
clientptr->decodingHalted(0);
- return true;
+ return false;
}
// Reset hold buffer count
bytes_in_hold = 0;
@@ -440,10 +442,9 @@ bool GIFImageReader::read(const unsigned char *buf, unsigned len,
switch (state)
{
case gif_lzw:
- if (!do_lzw(q)) {
- state = gif_error;
- break;
- }
+ if (!do_lzw(q))
+ return false; // If do_lzw() encountered an error, it has already called
+ // clientptr->setFailed().
GETN(1, gif_sub_block);
break;
@@ -454,15 +455,11 @@ bool GIFImageReader::read(const unsigned char *buf, unsigned len,
// Since we use a codesize of 1 more than the datasize, we need to ensure
// that our datasize is strictly less than the MAX_LZW_BITS value (12).
// This sets the largest possible codemask correctly at 4095.
- if (datasize >= MAX_LZW_BITS) {
- state = gif_error;
- break;
- }
+ if (datasize >= MAX_LZW_BITS)
+ return clientptr ? clientptr->setFailed() : false;
int clear_code = 1 << datasize;
- if (clear_code >= MAX_BITS) {
- state = gif_error;
- break;
- }
+ if (clear_code >= MAX_BITS)
+ return clientptr ? clientptr->setFailed() : false;
if (frame_reader) {
frame_reader->datasize = datasize;
@@ -498,10 +495,8 @@ bool GIFImageReader::read(const unsigned char *buf, unsigned len,
version = 89;
else if (!strncmp((char*)q, "GIF87a", 6))
version = 87;
- else {
- state = gif_error;
- break;
- }
+ else
+ return clientptr ? clientptr->setFailed() : false;
GETN(7, gif_global_header);
}
break;
@@ -586,7 +581,7 @@ bool GIFImageReader::read(const unsigned char *buf, unsigned len,
state = gif_done;
} else {
/* No images decoded, there is nothing to display. */
- state = gif_error;
+ return clientptr ? clientptr->setFailed() : false;
}
break;
} else
@@ -714,7 +709,7 @@ bool GIFImageReader::read(const unsigned char *buf, unsigned len,
GETN(1, gif_netscape_extension_block);
} else {
// 0,3-7 are yet to be defined netscape extension codes
- state = gif_error;
+ return clientptr ? clientptr->setFailed() : false;
}
break;
@@ -755,10 +750,8 @@ bool GIFImageReader::read(const unsigned char *buf, unsigned len,
if (!height || !width) {
height = screen_height;
width = screen_width;
- if (!height || !width) {
- state = gif_error;
- break;
- }
+ if (!height || !width)
+ return clientptr ? clientptr->setFailed() : false;
}
if (query == GIFImageDecoder::GIFSizeQuery || haltAtFrame == images_decoded) {
@@ -794,10 +787,8 @@ bool GIFImageReader::read(const unsigned char *buf, unsigned len,
frame_reader->rowbuf = new unsigned char[screen_width];
}
- if (!frame_reader->rowbuf) {
- state = gif_oom;
- break;
- }
+ if (!frame_reader->rowbuf)
+ return clientptr ? clientptr->setFailed() : false;
if (screen_height < height)
screen_height = height;
@@ -838,10 +829,8 @@ bool GIFImageReader::read(const unsigned char *buf, unsigned len,
if (frame_reader && (!map || (num_colors > frame_reader->local_colormap_size))) {
delete []map;
map = new unsigned char[size];
- if (!map) {
- state = gif_oom;
- break;
- }
+ if (!map)
+ return clientptr ? clientptr->setFailed() : false;
}
/* Switch to the new local palette after it loads */
@@ -893,8 +882,9 @@ bool GIFImageReader::read(const unsigned char *buf, unsigned len,
images_decoded++;
// CALLBACK: The frame is now complete.
- if (clientptr && frame_reader)
- clientptr->frameComplete(images_decoded - 1, frame_reader->delay_time, frame_reader->disposal_method);
+ if (clientptr && frame_reader && !clientptr->frameComplete(images_decoded - 1, frame_reader->delay_time, frame_reader->disposal_method))
+ return false; // frameComplete() has already called
+ // clientptr->setFailed().
/* Clear state from this image */
if (frame_reader) {
@@ -913,14 +903,6 @@ bool GIFImageReader::read(const unsigned char *buf, unsigned len,
clientptr->gifComplete();
return true;
- // Handle out of memory errors
- case gif_oom:
- return false;
-
- // Handle general errors
- case gif_error:
- return false;
-
// We shouldn't ever get here.
default:
break;
@@ -945,5 +927,5 @@ bool GIFImageReader::read(const unsigned char *buf, unsigned len,
if (clientptr)
clientptr->decodingHalted(0);
- return true;
+ return false;
}
diff --git a/WebCore/platform/image-decoders/gif/GIFImageReader.h b/WebCore/platform/image-decoders/gif/GIFImageReader.h
index 5982827..be5be19 100644
--- a/WebCore/platform/image-decoders/gif/GIFImageReader.h
+++ b/WebCore/platform/image-decoders/gif/GIFImageReader.h
@@ -69,8 +69,6 @@ typedef enum {
gif_consume_block,
gif_skip_block,
gif_done,
- gif_oom,
- gif_error,
gif_comment_extension,
gif_application_extension,
gif_netscape_extension_block,
diff --git a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
index 3d9fb8e..8375693 100644
--- a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
+++ b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
@@ -69,7 +69,6 @@ enum jstate {
JPEG_DECOMPRESS_PROGRESSIVE, // Output progressive pixels
JPEG_DECOMPRESS_SEQUENTIAL, // Output sequential pixels
JPEG_DONE,
- JPEG_SINK_NON_JPEG_TRAILER, // Some image files have a non-JPEG trailer
JPEG_ERROR
};
@@ -169,16 +168,15 @@ public:
// We need to do the setjmp here. Otherwise bad things will happen
if (setjmp(m_err.setjmp_buffer)) {
- m_state = JPEG_SINK_NON_JPEG_TRAILER;
close();
- return false;
+ return m_decoder->setFailed();
}
switch (m_state) {
case JPEG_HEADER:
// Read file parameters with jpeg_read_header().
if (jpeg_read_header(&m_info, true) == JPEG_SUSPENDED)
- return true; // I/O suspension.
+ return false; // I/O suspension.
// Let libjpeg take care of gray->RGB and YCbCr->RGB conversions.
switch (m_info.jpeg_color_space) {
@@ -194,7 +192,7 @@ public:
m_info.out_color_space = JCS_CMYK;
break;
default:
- return false;
+ return m_decoder->setFailed();
}
// Don't allocate a giant and superfluous memory buffer when the
@@ -214,7 +212,7 @@ public:
// We can fill in the size now that the header is available.
if (!m_decoder->setSize(m_info.image_width, m_info.image_height))
- return false;
+ return m_decoder->setFailed();
if (m_decodingSizeOnly) {
// We can stop here. Reduce our buffer length and available
@@ -237,7 +235,7 @@ public:
// Start decompressor.
if (!jpeg_start_decompress(&m_info))
- return true; // I/O suspension.
+ return false; // I/O suspension.
// If this is a progressive JPEG ...
m_state = (m_info.buffered_image) ? JPEG_DECOMPRESS_PROGRESSIVE : JPEG_DECOMPRESS_SEQUENTIAL;
@@ -247,7 +245,7 @@ public:
if (m_state == JPEG_DECOMPRESS_SEQUENTIAL) {
if (!m_decoder->outputScanlines())
- return true; // I/O suspension.
+ return false; // I/O suspension.
// If we've completed image output...
ASSERT(m_info.output_scanline == m_info.output_height);
@@ -273,7 +271,7 @@ public:
--scan;
if (!jpeg_start_output(&m_info, scan))
- return true; // I/O suspension.
+ return false; // I/O suspension.
}
if (m_info.output_scanline == 0xffffff)
@@ -285,12 +283,12 @@ public:
// don't call jpeg_start_output() multiple times for
// the same scan.
m_info.output_scanline = 0xffffff;
- return true; // I/O suspension.
+ return false; // I/O suspension.
}
if (m_info.output_scanline == m_info.output_height) {
if (!jpeg_finish_output(&m_info))
- return true; // I/O suspension.
+ return false; // I/O suspension.
if (jpeg_input_complete(&m_info) && (m_info.input_scan_number == m_info.output_scan_number))
break;
@@ -305,15 +303,8 @@ public:
case JPEG_DONE:
// Finish decompression.
- if (!jpeg_finish_decompress(&m_info))
- return true; // I/O suspension.
-
- m_state = JPEG_SINK_NON_JPEG_TRAILER;
- break;
+ return jpeg_finish_decompress(&m_info);
- case JPEG_SINK_NON_JPEG_TRAILER:
- break;
-
case JPEG_ERROR:
// We can get here if the constructor failed.
return m_decoder->setFailed();
@@ -487,7 +478,9 @@ void JPEGImageDecoder::decode(bool onlySize)
if (!m_reader)
m_reader.set(new JPEGImageReader(this));
- if (!m_reader->decode(m_data->buffer(), onlySize))
+ // If we couldn't decode the image but we've received all the data, decoding
+ // has failed.
+ if (!m_reader->decode(m_data->buffer(), onlySize) && isAllDataReceived())
setFailed();
if (failed() || (!m_frameBufferCache.isEmpty() && m_frameBufferCache[0].status() == RGBA32Buffer::FrameComplete))
diff --git a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h
index 45e14bc..79bad47 100644
--- a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h
+++ b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h
@@ -52,7 +52,8 @@ namespace WebCore {
private:
// Decodes the image. If |onlySize| is true, stops decoding after
- // calculating the image size.
+ // calculating the image size. If decoding fails but there is no more
+ // data coming, sets the "decode failure" flag.
void decode(bool onlySize);
OwnPtr<JPEGImageReader> m_reader;
diff --git a/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp b/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp
index de01d55..1dcf6c7 100644
--- a/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp
+++ b/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp
@@ -119,7 +119,7 @@ public:
unsigned currentBufferSize() const { return m_currentBufferSize; }
- void decode(const SharedBuffer& data, bool sizeOnly)
+ bool decode(const SharedBuffer& data, bool sizeOnly)
{
m_decodingSizeOnly = sizeOnly;
PNGImageDecoder* decoder = static_cast<PNGImageDecoder*>(png_get_progressive_ptr(m_png));
@@ -127,8 +127,7 @@ public:
// We need to do the setjmp here. Otherwise bad things will happen.
if (setjmp(m_png->jmpbuf)) {
close();
- decoder->setFailed();
- return;
+ return decoder->setFailed();
}
const char* segment;
@@ -140,10 +139,9 @@ public:
// merely want to check if we've managed to set the size, not
// (recursively) trigger additional decoding if we haven't.
if (sizeOnly ? decoder->ImageDecoder::isSizeAvailable() : decoder->isComplete())
- return;
+ return true;
}
- if (!decoder->isComplete() && decoder->isAllDataReceived())
- decoder->pngComplete();
+ return false;
}
bool decodingSizeOnly() const { return m_decodingSizeOnly; }
@@ -371,7 +369,10 @@ void PNGImageDecoder::decode(bool onlySize)
if (!m_reader)
m_reader.set(new PNGImageReader(this));
- m_reader->decode(*m_data, onlySize);
+ // If we couldn't decode the image but we've received all the data, decoding
+ // has failed.
+ if (!m_reader->decode(*m_data, onlySize) && isAllDataReceived())
+ setFailed();
if (failed() || isComplete())
m_reader.clear();
diff --git a/WebCore/platform/image-decoders/png/PNGImageDecoder.h b/WebCore/platform/image-decoders/png/PNGImageDecoder.h
index 3f0602c..287a794 100644
--- a/WebCore/platform/image-decoders/png/PNGImageDecoder.h
+++ b/WebCore/platform/image-decoders/png/PNGImageDecoder.h
@@ -57,7 +57,8 @@ namespace WebCore {
private:
// Decodes the image. If |onlySize| is true, stops decoding after
- // calculating the image size.
+ // calculating the image size. If decoding fails but there is no more
+ // data coming, sets the "decode failure" flag.
void decode(bool onlySize);
OwnPtr<PNGImageReader> m_reader;
diff --git a/WebCore/platform/image-encoders/skia/PNGImageEncoder.cpp b/WebCore/platform/image-encoders/skia/PNGImageEncoder.cpp
index aa20c62..19363c8 100644
--- a/WebCore/platform/image-encoders/skia/PNGImageEncoder.cpp
+++ b/WebCore/platform/image-encoders/skia/PNGImageEncoder.cpp
@@ -129,10 +129,7 @@ bool PNGImageEncoder::encode(const unsigned char* input, const IntSize& size,
return false;
}
- png_struct* pngPtr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
- png_voidp_NULL,
- png_error_ptr_NULL,
- png_error_ptr_NULL);
+ png_struct* pngPtr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
if (!pngPtr)
return false;
diff --git a/WebCore/platform/mac/KeyEventMac.mm b/WebCore/platform/mac/KeyEventMac.mm
index b8bf500..7b8b2ce 100644
--- a/WebCore/platform/mac/KeyEventMac.mm
+++ b/WebCore/platform/mac/KeyEventMac.mm
@@ -169,7 +169,14 @@ static int windowsKeyCodeForKeyEvent(NSEvent *event)
// 3. Certain punctuation keys. On Windows, these are also remapped depending on current keyboard layout,
// but see comment in windowsKeyCodeForCharCode().
if ([event type] == NSKeyDown || [event type] == NSKeyUp) {
- NSString* s = [event characters]; // Cannot use charactersIgnoringModifiers, because Cmd switches Roman letters for Dvorak-QWERTY layout.
+ // Cmd switches Roman letters for Dvorak-QWERTY layout, so try modified characters first.
+ NSString* s = [event characters];
+ code = [s length] > 0 ? windowsKeyCodeForCharCode([s characterAtIndex:0]) : 0;
+ if (code)
+ return code;
+
+ // Ctrl+A on an AZERTY keyboard would get VK_Q keyCode if we relied on -[NSEvent keyCode] below.
+ s = [event charactersIgnoringModifiers];
code = [s length] > 0 ? windowsKeyCodeForCharCode([s characterAtIndex:0]) : 0;
if (code)
return code;
diff --git a/WebCore/platform/mac/PopupMenuMac.mm b/WebCore/platform/mac/PopupMenuMac.mm
index 0ecaa13..6c067b9 100644
--- a/WebCore/platform/mac/PopupMenuMac.mm
+++ b/WebCore/platform/mac/PopupMenuMac.mm
@@ -114,8 +114,6 @@ 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();
@@ -196,14 +194,6 @@ 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/SharedBufferMac.mm b/WebCore/platform/mac/SharedBufferMac.mm
index c4e7528..3f5e5d4 100644
--- a/WebCore/platform/mac/SharedBufferMac.mm
+++ b/WebCore/platform/mac/SharedBufferMac.mm
@@ -50,6 +50,7 @@ using namespace WebCore;
+ (void)initialize
{
JSC::initializeThreading();
+ WTF::initializeMainThreadToProcessMainThread();
#ifndef BUILDING_ON_TIGER
WebCoreObjCFinalizeOnMainThread(self);
#endif
diff --git a/WebCore/platform/mac/ThemeMac.mm b/WebCore/platform/mac/ThemeMac.mm
index bbc6d6b..7cc913f 100644
--- a/WebCore/platform/mac/ThemeMac.mm
+++ b/WebCore/platform/mac/ThemeMac.mm
@@ -46,6 +46,11 @@ using namespace std;
return YES;
}
+- (NSText *)currentEditor
+{
+ return nil;
+}
+
@end
// FIXME: Default buttons really should be more like push buttons and not like buttons.
@@ -77,9 +82,9 @@ static NSControlSize controlSizeForFont(const Font& font)
return NSMiniControlSize;
}
-static LengthSize sizeFromFont(const Font& font, const LengthSize& zoomedSize, float zoomFactor, const IntSize* sizes)
+static LengthSize sizeFromNSControlSize(NSControlSize nsControlSize, const LengthSize& zoomedSize, float zoomFactor, const IntSize* sizes)
{
- IntSize controlSize = sizes[controlSizeForFont(font)];
+ IntSize controlSize = sizes[nsControlSize];
if (zoomFactor != 1.0f)
controlSize = IntSize(controlSize.width() * zoomFactor, controlSize.height() * zoomFactor);
LengthSize result = zoomedSize;
@@ -90,6 +95,11 @@ static LengthSize sizeFromFont(const Font& font, const LengthSize& zoomedSize, f
return result;
}
+static LengthSize sizeFromFont(const Font& font, const LengthSize& zoomedSize, float zoomFactor, const IntSize* sizes)
+{
+ return sizeFromNSControlSize(controlSizeForFont(font), zoomedSize, zoomFactor, sizes);
+}
+
static void setControlSize(NSCell* cell, const IntSize* sizes, const IntSize& minZoomedSize, float zoomFactor)
{
NSControlSize size;
@@ -439,6 +449,65 @@ static void paintButton(ControlPart part, ControlStates states, GraphicsContext*
END_BLOCK_OBJC_EXCEPTIONS
}
+// Stepper
+
+static const IntSize* stepperSizes()
+{
+ static const IntSize sizes[3] = { IntSize(19, 27), IntSize(15, 22), IntSize(13, 15) };
+ return sizes;
+}
+
+// We don't use controlSizeForFont() for steppers because the stepper height
+// should be equal to or less than the corresponding text field height,
+static NSControlSize stepperControlSizeForFont(const Font& font)
+{
+ int fontSize = font.pixelSize();
+ if (fontSize >= 18)
+ return NSRegularControlSize;
+ if (fontSize >= 13)
+ return NSSmallControlSize;
+ return NSMiniControlSize;
+}
+
+static NSStepperCell* stepper(ControlStates states, const IntRect& zoomedRect, float zoomFactor)
+{
+ static NSStepperCell* cell = [[NSStepperCell alloc] init];
+ setControlSize(cell, stepperSizes(), zoomedRect.size(), zoomFactor);
+
+ updateStates(cell, states);
+ if (states & PressedState && states & SpinUpState) {
+ // FIXME: There is no way to draw a NSSteperCell with the up button hilighted.
+ // Disables the hilight of the down button if the up button is pressed.
+ [cell setHighlighted:NO];
+ }
+ return cell;
+}
+
+static void paintStepper(ControlStates states, GraphicsContext* context, const IntRect& zoomedRect, float zoomFactor, ScrollView* scrollView)
+{
+ NSStepperCell* cell = stepper(states, zoomedRect, zoomFactor);
+
+ context->save();
+ NSControlSize controlSize = [cell controlSize];
+ IntSize zoomedSize = stepperSizes()[controlSize];
+ IntRect rect(zoomedRect);
+
+ if (zoomFactor != 1.0f) {
+ rect.setWidth(rect.width() / zoomFactor);
+ rect.setHeight(rect.height() / zoomFactor);
+ context->translate(rect.x(), rect.y());
+ context->scale(FloatSize(zoomFactor, zoomFactor));
+ context->translate(-rect.x(), -rect.y());
+ }
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+ [cell drawWithFrame:NSRect(rect) inView:ThemeMac::ensuredView(scrollView)];
+ [cell setControlView:nil];
+ END_BLOCK_OBJC_EXCEPTIONS
+
+ context->restore();
+}
+
// This will ensure that we always return a valid NSView, even if ScrollView doesn't have an associated document NSView.
// If the ScrollView doesn't have an NSView, we will return a fake NSView whose sole purpose is to tell AppKit that it's flipped.
NSView *ThemeMac::ensuredView(ScrollView* scrollView)
@@ -494,6 +563,13 @@ LengthSize ThemeMac::controlSize(ControlPart part, const Font& font, const Lengt
case ListButtonPart:
return sizeFromFont(font, LengthSize(zoomedSize.width(), Length()), zoomFactor, listButtonSizes());
#endif
+ case InnerSpinButtonPart:
+ // We don't use inner spin buttons on Mac.
+ return LengthSize(Length(Fixed), Length(Fixed));
+ case OuterSpinButtonPart:
+ if (!zoomedSize.width().isIntrinsicOrAuto() && !zoomedSize.height().isIntrinsicOrAuto())
+ return zoomedSize;
+ return sizeFromNSControlSize(stepperControlSizeForFont(font), zoomedSize, zoomFactor, stepperSizes());
default:
return zoomedSize;
}
@@ -507,6 +583,14 @@ LengthSize ThemeMac::minimumControlSize(ControlPart part, const Font& font, floa
case ButtonPart:
case ListButtonPart:
return LengthSize(Length(0, Fixed), Length(static_cast<int>(15 * zoomFactor), Fixed));
+ case InnerSpinButtonPart:
+ // We don't use inner spin buttons on Mac.
+ return LengthSize(Length(Fixed), Length(Fixed));
+ case OuterSpinButtonPart: {
+ IntSize base = stepperSizes()[NSMiniControlSize];
+ return LengthSize(Length(static_cast<int>(base.width() * zoomFactor), Fixed),
+ Length(static_cast<int>(base.height() * zoomFactor), Fixed));
+ }
default:
return Theme::minimumControlSize(part, font, zoomFactor);
}
@@ -583,6 +667,16 @@ void ThemeMac::inflateControlPaintRect(ControlPart part, ControlStates states, I
}
break;
}
+ case OuterSpinButtonPart: {
+ static const int stepperMargin[4] = { 0, 0, 0, 0};
+ NSCell *cell = stepper(states, zoomedRect, zoomFactor);
+ NSControlSize controlSize = [cell controlSize];
+ IntSize zoomedSize = stepperSizes()[controlSize];
+ zoomedSize.setHeight(zoomedSize.height() * zoomFactor);
+ zoomedSize.setWidth(zoomedSize.width() * zoomFactor);
+ zoomedRect = inflateRect(zoomedRect, zoomedSize, stepperMargin, zoomFactor);
+ break;
+ }
default:
break;
}
@@ -605,6 +699,9 @@ void ThemeMac::paint(ControlPart part, ControlStates states, GraphicsContext* co
case ListButtonPart:
paintButton(part, states, context, zoomedRect, zoomFactor, scrollView);
break;
+ case OuterSpinButtonPart:
+ paintStepper(states, context, zoomedRect, zoomFactor, scrollView);
+ break;
default:
break;
}
diff --git a/WebCore/platform/mac/WebCoreObjCExtras.mm b/WebCore/platform/mac/WebCoreObjCExtras.mm
index 4fc757c..05d3e01 100644
--- a/WebCore/platform/mac/WebCoreObjCExtras.mm
+++ b/WebCore/platform/mac/WebCoreObjCExtras.mm
@@ -71,14 +71,9 @@ static void deallocCallback(void* context)
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/WidgetMac.mm b/WebCore/platform/mac/WidgetMac.mm
index 1aad76f..37c9e9f 100644
--- a/WebCore/platform/mac/WidgetMac.mm
+++ b/WebCore/platform/mac/WidgetMac.mm
@@ -105,8 +105,11 @@ Widget::~Widget()
}
// FIXME: Should move this to Chrome; bad layering that this knows about Frame.
-void Widget::setFocus()
+void Widget::setFocus(bool focused)
{
+ if (!focused)
+ return;
+
Frame* frame = Frame::frameForWidget(this);
if (!frame)
return;
diff --git a/WebCore/platform/network/FormData.cpp b/WebCore/platform/network/FormData.cpp
index 4ad82fb..918002a 100644
--- a/WebCore/platform/network/FormData.cpp
+++ b/WebCore/platform/network/FormData.cpp
@@ -286,13 +286,18 @@ String FormData::flattenToString() const
return Latin1Encoding().decode(bytes.data(), bytes.size());
}
-void FormData::generateFiles(ChromeClient* client)
+void FormData::generateFiles(Document* document)
{
ASSERT(!m_hasGeneratedFiles);
if (m_hasGeneratedFiles)
return;
+ Page* page = document->page();
+ if (!page)
+ return;
+ ChromeClient* client = page->chrome()->client();
+
size_t n = m_elements.size();
for (size_t i = 0; i < n; ++i) {
FormDataElement& e = m_elements[i];
diff --git a/WebCore/platform/network/FormData.h b/WebCore/platform/network/FormData.h
index f89dad7..a439023 100644
--- a/WebCore/platform/network/FormData.h
+++ b/WebCore/platform/network/FormData.h
@@ -26,7 +26,6 @@
namespace WebCore {
-class ChromeClient;
class DOMFormData;
class Document;
@@ -101,7 +100,7 @@ public:
const Vector<FormDataElement>& elements() const { return m_elements; }
const Vector<char>& boundary() const { return m_boundary; }
- void generateFiles(ChromeClient*);
+ void generateFiles(Document*);
void removeGeneratedFilesIfNeeded();
bool alwaysStream() const { return m_alwaysStream; }
diff --git a/WebCore/platform/network/FormDataBuilder.cpp b/WebCore/platform/network/FormDataBuilder.cpp
index 436dc8b..13a457b 100644
--- a/WebCore/platform/network/FormDataBuilder.cpp
+++ b/WebCore/platform/network/FormDataBuilder.cpp
@@ -162,7 +162,7 @@ Vector<char> FormDataBuilder::generateUniqueBoundaryString()
Vector<char> randomBytes;
for (unsigned i = 0; i < 4; ++i) {
- unsigned randomness = static_cast<unsigned>(WTF::randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0));
+ unsigned randomness = static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0));
randomBytes.append(alphaNumericEncodingMap[(randomness >> 24) & 0x3F]);
randomBytes.append(alphaNumericEncodingMap[(randomness >> 16) & 0x3F]);
randomBytes.append(alphaNumericEncodingMap[(randomness >> 8) & 0x3F]);
diff --git a/WebCore/platform/network/NetworkStateNotifier.h b/WebCore/platform/network/NetworkStateNotifier.h
index 7b94ac8..ade27fd 100644
--- a/WebCore/platform/network/NetworkStateNotifier.h
+++ b/WebCore/platform/network/NetworkStateNotifier.h
@@ -48,6 +48,15 @@ typedef const struct __SCDynamicStore * SCDynamicStoreRef;
#include <windows.h>
+#elif PLATFORM(QT)
+
+#include <QtCore/qglobal.h>
+
+#ifdef QT_NO_BEARERMANAGEMENT
+#undef ENABLE_QT_BEARER
+#define ENABLE_QT_BEARER 0
+#endif
+
#endif
namespace WebCore {
diff --git a/WebCore/platform/network/ProtectionSpace.h b/WebCore/platform/network/ProtectionSpace.h
index 42cbc8a..deb59d2 100644
--- a/WebCore/platform/network/ProtectionSpace.h
+++ b/WebCore/platform/network/ProtectionSpace.h
@@ -30,26 +30,28 @@
namespace WebCore {
enum ProtectionSpaceServerType {
- ProtectionSpaceServerHTTP = 1,
- ProtectionSpaceServerHTTPS = 2,
- ProtectionSpaceServerFTP = 3,
- ProtectionSpaceServerFTPS = 4,
- ProtectionSpaceProxyHTTP = 5,
- ProtectionSpaceProxyHTTPS = 6,
- ProtectionSpaceProxyFTP = 7,
- ProtectionSpaceProxySOCKS = 8
+ ProtectionSpaceServerHTTP = 1,
+ ProtectionSpaceServerHTTPS = 2,
+ ProtectionSpaceServerFTP = 3,
+ ProtectionSpaceServerFTPS = 4,
+ ProtectionSpaceProxyHTTP = 5,
+ ProtectionSpaceProxyHTTPS = 6,
+ ProtectionSpaceProxyFTP = 7,
+ ProtectionSpaceProxySOCKS = 8
};
enum ProtectionSpaceAuthenticationScheme {
- ProtectionSpaceAuthenticationSchemeDefault = 1,
- ProtectionSpaceAuthenticationSchemeHTTPBasic = 2,
- ProtectionSpaceAuthenticationSchemeHTTPDigest = 3,
- ProtectionSpaceAuthenticationSchemeHTMLForm = 4,
- ProtectionSpaceAuthenticationSchemeNTLM = 5,
- ProtectionSpaceAuthenticationSchemeNegotiate = 6,
- ProtectionSpaceAuthenticationSchemeUnknown = 100,
+ ProtectionSpaceAuthenticationSchemeDefault = 1,
+ ProtectionSpaceAuthenticationSchemeHTTPBasic = 2,
+ ProtectionSpaceAuthenticationSchemeHTTPDigest = 3,
+ ProtectionSpaceAuthenticationSchemeHTMLForm = 4,
+ ProtectionSpaceAuthenticationSchemeNTLM = 5,
+ ProtectionSpaceAuthenticationSchemeNegotiate = 6,
+ ProtectionSpaceAuthenticationSchemeClientCertificateRequested = 7,
+ ProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested = 8,
+ ProtectionSpaceAuthenticationSchemeUnknown = 100,
};
-
+
class ProtectionSpace {
public:
diff --git a/WebCore/platform/network/ResourceHandle.h b/WebCore/platform/network/ResourceHandle.h
index 24decd5..b86c922 100644
--- a/WebCore/platform/network/ResourceHandle.h
+++ b/WebCore/platform/network/ResourceHandle.h
@@ -82,6 +82,7 @@ class Credential;
class FormData;
class Frame;
class KURL;
+class ProtectionSpace;
class ResourceError;
class ResourceHandleClient;
class ResourceHandleInternal;
@@ -131,6 +132,9 @@ public:
#if PLATFORM(MAC)
void didCancelAuthenticationChallenge(const AuthenticationChallenge&);
+#if USE(PROTECTION_SPACE_AUTH_CALLBACK)
+ bool canAuthenticateAgainstProtectionSpace(const ProtectionSpace&);
+#endif
NSURLConnection *connection() const;
WebCoreResourceHandleAsDelegate *delegate();
void releaseDelegate();
diff --git a/WebCore/platform/network/ResourceHandleClient.h b/WebCore/platform/network/ResourceHandleClient.h
index 0fe77a1..bbc3cf8 100644
--- a/WebCore/platform/network/ResourceHandleClient.h
+++ b/WebCore/platform/network/ResourceHandleClient.h
@@ -47,6 +47,7 @@ namespace WebCore {
class AuthenticationChallenge;
class Credential;
class KURL;
+ class ProtectionSpace;
class ResourceHandle;
class ResourceError;
class ResourceRequest;
@@ -78,6 +79,9 @@ namespace WebCore {
virtual bool shouldUseCredentialStorage(ResourceHandle*) { return false; }
virtual void didReceiveAuthenticationChallenge(ResourceHandle*, const AuthenticationChallenge&) { }
virtual void didCancelAuthenticationChallenge(ResourceHandle*, const AuthenticationChallenge&) { }
+#if USE(PROTECTION_SPACE_AUTH_CALLBACK)
+ virtual bool canAuthenticateAgainstProtectionSpace(ResourceHandle*, const ProtectionSpace&) { return false; }
+#endif
virtual void receivedCancellation(ResourceHandle*, const AuthenticationChallenge&) { }
#if PLATFORM(MAC)
diff --git a/WebCore/platform/network/ResourceRequestBase.cpp b/WebCore/platform/network/ResourceRequestBase.cpp
index 42c1c6e..fd8832f 100644
--- a/WebCore/platform/network/ResourceRequestBase.cpp
+++ b/WebCore/platform/network/ResourceRequestBase.cpp
@@ -45,6 +45,7 @@ PassOwnPtr<ResourceRequest> ResourceRequestBase::adopt(PassOwnPtr<CrossThreadRes
request->setTimeoutInterval(data->m_timeoutInterval);
request->setFirstPartyForCookies(data->m_firstPartyForCookies);
request->setHTTPMethod(data->m_httpMethod);
+ request->setTargetType(data->m_targetType);
request->updateResourceRequest();
request->m_httpHeaderFields.adopt(data->m_httpHeaders.release());
@@ -76,6 +77,7 @@ PassOwnPtr<CrossThreadResourceRequestData> ResourceRequestBase::copyData() const
data->m_firstPartyForCookies = firstPartyForCookies().copy();
data->m_httpMethod = httpMethod().crossThreadString();
data->m_httpHeaders = httpHeaderFields().copyData();
+ data->m_targetType = m_targetType;
data->m_responseContentDispositionEncodingFallbackArray.reserveInitialCapacity(m_responseContentDispositionEncodingFallbackArray.size());
size_t encodingArraySize = m_responseContentDispositionEncodingFallbackArray.size();
diff --git a/WebCore/platform/network/ResourceRequestBase.h b/WebCore/platform/network/ResourceRequestBase.h
index 2ca5d7d..0b634cb 100644
--- a/WebCore/platform/network/ResourceRequestBase.h
+++ b/WebCore/platform/network/ResourceRequestBase.h
@@ -61,7 +61,9 @@ namespace WebCore {
TargetIsFontResource,
TargetIsImage,
TargetIsObject,
- TargetIsMedia
+ TargetIsMedia,
+ TargetIsWorker,
+ TargetIsSharedWorker
};
static PassOwnPtr<ResourceRequest> adopt(PassOwnPtr<CrossThreadResourceRequestData>);
@@ -195,6 +197,7 @@ namespace WebCore {
Vector<String> m_responseContentDispositionEncodingFallbackArray;
RefPtr<FormData> m_httpBody;
bool m_allowCookies;
+ ResourceRequestBase::TargetType m_targetType;
};
unsigned initializeMaximumHTTPConnectionCountPerHost();
diff --git a/WebCore/platform/network/mac/AuthenticationMac.mm b/WebCore/platform/network/mac/AuthenticationMac.mm
index 077a53d..1c05917 100644
--- a/WebCore/platform/network/mac/AuthenticationMac.mm
+++ b/WebCore/platform/network/mac/AuthenticationMac.mm
@@ -197,6 +197,14 @@ NSURLProtectionSpace *mac(const ProtectionSpace& coreSpace)
case ProtectionSpaceAuthenticationSchemeNTLM:
method = NSURLAuthenticationMethodNTLM;
break;
+#if USE(PROTECTION_SPACE_AUTH_CALLBACK)
+ case ProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested:
+ method = NSURLAuthenticationMethodServerTrust;
+ break;
+ case ProtectionSpaceAuthenticationSchemeClientCertificateRequested:
+ method = NSURLAuthenticationMethodClientCertificate;
+ break;
+#endif
default:
ASSERT_NOT_REACHED();
}
@@ -295,6 +303,12 @@ ProtectionSpace core(NSURLProtectionSpace *macSpace)
scheme = ProtectionSpaceAuthenticationSchemeHTMLForm;
else if ([method isEqualToString:NSURLAuthenticationMethodNTLM])
scheme = ProtectionSpaceAuthenticationSchemeNTLM;
+#if USE(PROTECTION_SPACE_AUTH_CALLBACK)
+ else if ([method isEqualToString:NSURLAuthenticationMethodClientCertificate])
+ scheme = ProtectionSpaceAuthenticationSchemeClientCertificateRequested;
+ else if ([method isEqualToString:NSURLAuthenticationMethodServerTrust])
+ scheme = ProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested;
+#endif
else {
scheme = ProtectionSpaceAuthenticationSchemeUnknown;
ASSERT_NOT_REACHED();
diff --git a/WebCore/platform/network/mac/ResourceHandleMac.mm b/WebCore/platform/network/mac/ResourceHandleMac.mm
index 3ea29c5..a70da68 100644
--- a/WebCore/platform/network/mac/ResourceHandleMac.mm
+++ b/WebCore/platform/network/mac/ResourceHandleMac.mm
@@ -567,11 +567,26 @@ void ResourceHandle::didCancelAuthenticationChallenge(const AuthenticationChalle
client()->didCancelAuthenticationChallenge(this, challenge);
}
+#if USE(PROTECTION_SPACE_AUTH_CALLBACK)
+bool ResourceHandle::canAuthenticateAgainstProtectionSpace(const ProtectionSpace& protectionSpace)
+{
+ if (client())
+ return client()->canAuthenticateAgainstProtectionSpace(this, protectionSpace);
+
+ return false;
+}
+#endif
+
void ResourceHandle::receivedCredential(const AuthenticationChallenge& challenge, const Credential& credential)
{
ASSERT(!challenge.isNull());
if (challenge != d->m_currentWebChallenge)
return;
+
+ if (credential.isEmpty()) {
+ receivedRequestToContinueWithoutCredential(challenge);
+ return;
+ }
#ifdef BUILDING_ON_TIGER
if (credential.persistence() == CredentialPersistenceNone) {
@@ -734,6 +749,19 @@ void ResourceHandle::receivedCancellation(const AuthenticationChallenge& challen
m_handle->didCancelAuthenticationChallenge(core(challenge));
}
+#if USE(PROTECTION_SPACE_AUTH_CALLBACK)
+- (BOOL)connection:(NSURLConnection *)unusedConnection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
+{
+ UNUSED_PARAM(unusedConnection);
+
+ if (!m_handle)
+ return NO;
+
+ CallbackGuard guard;
+ return m_handle->canAuthenticateAgainstProtectionSpace(core(protectionSpace));
+}
+#endif
+
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)r
{
UNUSED_PARAM(connection);
@@ -744,7 +772,10 @@ void ResourceHandle::receivedCancellation(const AuthenticationChallenge& challen
return;
CallbackGuard guard;
- [r adjustMIMETypeIfNecessary];
+ // Avoid MIME type sniffing if the response comes back as 304 Not Modified.
+ int statusCode = [r respondsToSelector:@selector(statusCode)] ? [(id)r statusCode] : 0;
+ if (statusCode != 304)
+ [r adjustMIMETypeIfNecessary];
if ([m_handle->request().nsURLRequest() _propertyForKey:@"ForceHTMLMIMEType"])
[r _setMIMEType:@"text/html"];
diff --git a/WebCore/platform/network/qt/NetworkStateNotifierQt.cpp b/WebCore/platform/network/qt/NetworkStateNotifierQt.cpp
index 52512aa..3aae92a 100644
--- a/WebCore/platform/network/qt/NetworkStateNotifierQt.cpp
+++ b/WebCore/platform/network/qt/NetworkStateNotifierQt.cpp
@@ -20,6 +20,8 @@
#include "config.h"
#include "NetworkStateNotifier.h"
+#if PLATFORM(QT) && ENABLE(QT_BEARER)
+
#include "NetworkStateNotifierPrivate.h"
#include "qnetworkconfigmanager.h"
@@ -89,4 +91,6 @@ void NetworkStateNotifier::setNetworkAccessAllowed(bool isAllowed)
} // namespace WebCore
+#endif
+
#include "moc_NetworkStateNotifierPrivate.cpp"
diff --git a/WebCore/platform/network/qt/QNetworkReplyHandler.cpp b/WebCore/platform/network/qt/QNetworkReplyHandler.cpp
index 27b57b7..e52dd1d 100644
--- a/WebCore/platform/network/qt/QNetworkReplyHandler.cpp
+++ b/WebCore/platform/network/qt/QNetworkReplyHandler.cpp
@@ -41,8 +41,9 @@
// 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)
+// It is fixed in Qt 4.6.3. See https://bugs.webkit.org/show_bug.cgi?id=32113
+// and https://bugs.webkit.org/show_bug.cgi?id=36755
+#if QT_VERSION > QT_VERSION_CHECK(4, 6, 2)
#define SIGNAL_CONN Qt::DirectConnection
#else
#define SIGNAL_CONN Qt::QueuedConnection
diff --git a/WebCore/platform/network/qt/ResourceRequestQt.cpp b/WebCore/platform/network/qt/ResourceRequestQt.cpp
index 341e6ae..fea64a0 100644
--- a/WebCore/platform/network/qt/ResourceRequestQt.cpp
+++ b/WebCore/platform/network/qt/ResourceRequestQt.cpp
@@ -32,12 +32,14 @@ namespace WebCore {
// 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.
+// Per TCP connection there is 1 current processed, 3 possibly pipelined
+// and 2 ready to re-fill the pipeline.
unsigned initializeMaximumHTTPConnectionCountPerHost()
{
#ifdef Q_OS_SYMBIAN
- return 3 + 2;
+ return 3 * (1 + 3 + 2);
#else
- return 6 + 2;
+ return 6 * (1 + 3 + 2);
#endif
}
diff --git a/WebCore/platform/posix/FileSystemPOSIX.cpp b/WebCore/platform/posix/FileSystemPOSIX.cpp
index ac8c7fa..ba17d39 100644
--- a/WebCore/platform/posix/FileSystemPOSIX.cpp
+++ b/WebCore/platform/posix/FileSystemPOSIX.cpp
@@ -116,6 +116,7 @@ bool truncateFile(PlatformFileHandle handle, long long offset)
return !ftruncate(handle, offset);
}
+#if !PLATFORM(ANDROID)
int writeToFile(PlatformFileHandle handle, const char* data, int length)
{
do {
@@ -125,6 +126,7 @@ int writeToFile(PlatformFileHandle handle, const char* data, int length)
} while (errno == EINTR);
return -1;
}
+#endif
int readFromFile(PlatformFileHandle handle, char* data, int length)
{
diff --git a/WebCore/platform/qt/PasteboardQt.cpp b/WebCore/platform/qt/PasteboardQt.cpp
index 70ec546..484fa60 100644
--- a/WebCore/platform/qt/PasteboardQt.cpp
+++ b/WebCore/platform/qt/PasteboardQt.cpp
@@ -58,7 +58,7 @@ Pasteboard* Pasteboard::generalPasteboard()
return pasteboard;
}
-void Pasteboard::writeSelection(Range* selectedRange, bool, Frame* frame)
+void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete, Frame* frame)
{
QMimeData* md = new QMimeData;
QString text = frame->selectedText();
@@ -74,10 +74,14 @@ void Pasteboard::writeSelection(Range* selectedRange, bool, Frame* frame)
QApplication::clipboard()->setMimeData(md, m_selectionMode ?
QClipboard::Selection : QClipboard::Clipboard);
#endif
+ if (canSmartCopyOrDelete)
+ md->setData("application/vnd.qtwebkit.smartpaste", QByteArray());
}
bool Pasteboard::canSmartReplace()
{
+ if (QApplication::clipboard()->mimeData()->hasFormat((QLatin1String("application/vnd.qtwebkit.smartpaste"))))
+ return true;
return false;
}
diff --git a/WebCore/platform/qt/QWebPageClient.h b/WebCore/platform/qt/QWebPageClient.h
index 467941f..a9a81eb 100644
--- a/WebCore/platform/qt/QWebPageClient.h
+++ b/WebCore/platform/qt/QWebPageClient.h
@@ -61,24 +61,23 @@ public:
#if QT_VERSION >= 0x040600
virtual void setInputMethodHint(Qt::InputMethodHint hint, bool enable) = 0;
#endif
+
+#ifndef QT_NO_CURSOR
inline void resetCursor()
{
-#ifndef QT_NO_CURSOR
if (!cursor().bitmap() && cursor().shape() == m_lastCursor.shape())
return;
updateCursor(m_lastCursor);
-#endif
}
inline void setCursor(const QCursor& cursor)
{
-#ifndef QT_NO_CURSOR
m_lastCursor = cursor;
if (!cursor.bitmap() && cursor.shape() == this->cursor().shape())
return;
updateCursor(cursor);
-#endif
}
+#endif
virtual QPalette palette() const = 0;
virtual int screenNumber() const = 0;
diff --git a/WebCore/platform/qt/RenderThemeQt.cpp b/WebCore/platform/qt/RenderThemeQt.cpp
index 9cc32ad..ee66a35 100644
--- a/WebCore/platform/qt/RenderThemeQt.cpp
+++ b/WebCore/platform/qt/RenderThemeQt.cpp
@@ -42,7 +42,7 @@
#include "HTMLInputElement.h"
#include "HTMLMediaElement.h"
#include "HTMLNames.h"
-#ifdef Q_WS_MAEMO_5
+#if USE(QT_MOBILE_THEME)
#include "Maemo5Webstyle.h"
#endif
#include "NotImplemented.h"
@@ -153,7 +153,7 @@ RenderThemeQt::RenderThemeQt(Page* page)
m_buttonFontPixelSize = fontInfo.pixelSize();
#endif
-#ifdef Q_WS_MAEMO_5
+#if USE(QT_MOBILE_THEME)
m_fallbackStyle = new Maemo5WebStyle;
#else
m_fallbackStyle = QStyleFactory::create(QLatin1String("windows"));
@@ -163,10 +163,12 @@ RenderThemeQt::RenderThemeQt(Page* page)
RenderThemeQt::~RenderThemeQt()
{
delete m_fallbackStyle;
+#ifndef QT_NO_LINEEDIT
delete m_lineEdit;
+#endif
}
-#ifdef Q_WS_MAEMO_5
+#if USE(QT_MOBILE_THEME)
bool RenderThemeQt::isControlStyled(const RenderStyle* style, const BorderData& border, const FillLayer& fill, const Color& backgroundColor) const
{
switch (style->appearance()) {
@@ -198,7 +200,7 @@ QStyle* RenderThemeQt::fallbackStyle() const
QStyle* RenderThemeQt::qStyle() const
{
-#ifdef Q_WS_MAEMO_5
+#if USE(QT_MOBILE_THEME)
return fallbackStyle();
#endif
@@ -218,7 +220,7 @@ String RenderThemeQt::extraDefaultStyleSheet()
#if ENABLE(NO_LISTBOX_RENDERING)
result += String(themeQtNoListboxesUserAgentStyleSheet, sizeof(themeQtNoListboxesUserAgentStyleSheet));
#endif
-#ifdef Q_WS_MAEMO_5
+#if USE(QT_MOBILE_THEME)
result += String(themeQtMaemo5UserAgentStyleSheet, sizeof(themeQtMaemo5UserAgentStyleSheet));
#endif
return result;
@@ -264,11 +266,17 @@ bool RenderThemeQt::supportsControlTints() const
int RenderThemeQt::findFrameLineWidth(QStyle* style) const
{
+#ifndef QT_NO_LINEEDIT
if (!m_lineEdit)
m_lineEdit = new QLineEdit();
+#endif
QStyleOptionFrameV2 opt;
- return style->pixelMetric(QStyle::PM_DefaultFrameWidth, &opt, m_lineEdit);
+ QWidget* widget = 0;
+#ifndef QT_NO_LINEEDIT
+ widget = m_lineEdit;
+#endif
+ return style->pixelMetric(QStyle::PM_DefaultFrameWidth, &opt, widget);
}
static QRect inflateButtonRect(const QRect& originalRect, QStyle* style)
@@ -648,7 +656,9 @@ bool RenderThemeQt::paintMenuList(RenderObject* o, const RenderObject::PaintInfo
void RenderThemeQt::adjustMenuListButtonStyle(CSSStyleSelector*, RenderStyle* style, Element*) const
{
-#ifndef Q_WS_MAEMO_5
+#if USE(QT_MOBILE_THEME)
+ // Mobile theme uses border radius.
+#else
// WORKAROUND because html.css specifies -webkit-border-radius for <select> so we override it here
// see also http://bugs.webkit.org/show_bug.cgi?id=18399
style->resetBorderRadius();
@@ -898,7 +908,7 @@ bool RenderThemeQt::supportsFocus(ControlPart appearance) const
void RenderThemeQt::setPaletteFromPageClientIfExists(QPalette& palette) const
{
-#ifdef Q_WS_MAEMO_5
+#if USE(QT_MOBILE_THEME)
static QPalette lightGrayPalette(Qt::lightGray);
palette = lightGrayPalette;
return;
@@ -960,7 +970,7 @@ ControlPart RenderThemeQt::initializeCommonQStyleOptions(QStyleOption& option, R
case SearchFieldCancelButtonPart: {
if (isPressed(o))
option.state |= QStyle::State_Sunken;
- else if (result == PushButtonPart)
+ else if (result == PushButtonPart || result == ButtonPart)
option.state |= QStyle::State_Raised;
break;
}
diff --git a/WebCore/platform/qt/RenderThemeQt.h b/WebCore/platform/qt/RenderThemeQt.h
index c10659a..fdd8d6b 100644
--- a/WebCore/platform/qt/RenderThemeQt.h
+++ b/WebCore/platform/qt/RenderThemeQt.h
@@ -78,7 +78,7 @@ public:
virtual double caretBlinkInterval() const;
-#ifdef Q_WS_MAEMO_5
+#if USE(QT_MOBILE_THEME)
virtual bool isControlStyled(const RenderStyle*, const BorderData&, const FillLayer&, const Color& backgroundColor) const;
virtual int popupInternalPaddingBottom(RenderStyle*) const;
#endif
diff --git a/WebCore/platform/qt/TemporaryLinkStubs.cpp b/WebCore/platform/qt/TemporaryLinkStubsQt.cpp
index 432bd2b..432bd2b 100644
--- a/WebCore/platform/qt/TemporaryLinkStubs.cpp
+++ b/WebCore/platform/qt/TemporaryLinkStubsQt.cpp
diff --git a/WebCore/platform/qt/WidgetQt.cpp b/WebCore/platform/qt/WidgetQt.cpp
index 252bdb4..43252a8 100644
--- a/WebCore/platform/qt/WidgetQt.cpp
+++ b/WebCore/platform/qt/WidgetQt.cpp
@@ -75,7 +75,7 @@ void Widget::setFrameRect(const IntRect& rect)
frameRectsChanged();
}
-void Widget::setFocus()
+void Widget::setFocus(bool focused)
{
}
diff --git a/WebCore/platform/sql/SQLiteDatabase.cpp b/WebCore/platform/sql/SQLiteDatabase.cpp
index 58fdc7c..75fc032 100644
--- a/WebCore/platform/sql/SQLiteDatabase.cpp
+++ b/WebCore/platform/sql/SQLiteDatabase.cpp
@@ -102,14 +102,17 @@ void SQLiteDatabase::setFullsync(bool fsync)
int64_t SQLiteDatabase::maximumSize()
{
- MutexLocker locker(m_authorizerLock);
- enableAuthorizer(false);
-
- SQLiteStatement statement(*this, "PRAGMA max_page_count");
- int64_t size = statement.getColumnInt64(0) * pageSize();
-
- enableAuthorizer(true);
- return size;
+ int64_t maxPageCount = 0;
+
+ {
+ MutexLocker locker(m_authorizerLock);
+ enableAuthorizer(false);
+ SQLiteStatement statement(*this, "PRAGMA max_page_count");
+ maxPageCount = statement.getColumnInt64(0);
+ enableAuthorizer(true);
+ }
+
+ return maxPageCount * pageSize();
}
void SQLiteDatabase::setMaximumSize(int64_t size)
@@ -128,7 +131,7 @@ void SQLiteDatabase::setMaximumSize(int64_t size)
SQLiteStatement statement(*this, "PRAGMA max_page_count = " + String::number(newMaxPageCount));
statement.prepare();
if (statement.step() != SQLResultRow)
- LOG_ERROR("Failed to set maximum size of database to %lli bytes", size);
+ LOG_ERROR("Failed to set maximum size of database to %lli bytes", static_cast<long long>(size));
enableAuthorizer(true);
@@ -153,14 +156,33 @@ int SQLiteDatabase::pageSize()
int64_t SQLiteDatabase::freeSpaceSize()
{
- MutexLocker locker(m_authorizerLock);
- enableAuthorizer(false);
- // Note: freelist_count was added in SQLite 3.4.1.
- SQLiteStatement statement(*this, "PRAGMA freelist_count");
- int64_t size = statement.getColumnInt64(0) * pageSize();
+ int64_t freelistCount = 0;
- enableAuthorizer(true);
- return size;
+ {
+ MutexLocker locker(m_authorizerLock);
+ enableAuthorizer(false);
+ // Note: freelist_count was added in SQLite 3.4.1.
+ SQLiteStatement statement(*this, "PRAGMA freelist_count");
+ freelistCount = statement.getColumnInt64(0);
+ enableAuthorizer(true);
+ }
+
+ return freelistCount * pageSize();
+}
+
+int64_t SQLiteDatabase::totalSize()
+{
+ int64_t pageCount = 0;
+
+ {
+ MutexLocker locker(m_authorizerLock);
+ enableAuthorizer(false);
+ SQLiteStatement statement(*this, "PRAGMA page_count");
+ pageCount = statement.getColumnInt64(0);
+ enableAuthorizer(true);
+ }
+
+ return pageCount * pageSize();
}
void SQLiteDatabase::setSynchronous(SynchronousPragma sync)
@@ -229,6 +251,17 @@ void SQLiteDatabase::runVacuumCommand()
LOG(SQLDatabase, "Unable to vacuum database - %s", lastErrorMsg());
}
+void SQLiteDatabase::runIncrementalVacuumCommand()
+{
+ MutexLocker locker(m_authorizerLock);
+ enableAuthorizer(false);
+
+ if (!executeCommand("PRAGMA incremental_vacuum"))
+ LOG(SQLDatabase, "Unable to run incremental vacuum - %s", lastErrorMsg());
+
+ enableAuthorizer(true);
+}
+
int64_t SQLiteDatabase::lastInsertRowID()
{
if (!m_db)
@@ -379,4 +412,34 @@ bool SQLiteDatabase::isAutoCommitOn() const
return sqlite3_get_autocommit(m_db);
}
+bool SQLiteDatabase::turnOnIncrementalAutoVacuum()
+{
+ SQLiteStatement statement(*this, "PRAGMA auto_vacuum");
+ int autoVacuumMode = statement.getColumnInt(0);
+ int error = lastError();
+
+ // Check if we got an error while trying to get the value of the auto_vacuum flag.
+ // If we got a SQLITE_BUSY error, then there's probably another transaction in
+ // progress on this database. In this case, keep the current value of the
+ // auto_vacuum flag and try to set it to INCREMENTAL the next time we open this
+ // database. If the error is not SQLITE_BUSY, then we probably ran into a more
+ // serious problem and should return false (to log an error message).
+ if (error != SQLITE_ROW)
+ return false;
+
+ switch (autoVacuumMode) {
+ case AutoVacuumIncremental:
+ return true;
+ case AutoVacuumFull:
+ return executeCommand("PRAGMA auto_vacuum = 2");
+ case AutoVacuumNone:
+ default:
+ if (!executeCommand("PRAGMA auto_vacuum = 2"))
+ return false;
+ runVacuumCommand();
+ error = lastError();
+ return (error == SQLITE_OK);
+ }
+}
+
} // namespace WebCore
diff --git a/WebCore/platform/sql/SQLiteDatabase.h b/WebCore/platform/sql/SQLiteDatabase.h
index bc58a32..c5924c0 100644
--- a/WebCore/platform/sql/SQLiteDatabase.h
+++ b/WebCore/platform/sql/SQLiteDatabase.h
@@ -65,6 +65,7 @@ public:
bool tableExists(const String&);
void clearAllTables();
void runVacuumCommand();
+ void runIncrementalVacuumCommand();
bool transactionInProgress() const { return m_transactionInProgress; }
@@ -85,6 +86,7 @@ public:
// Gets the number of unused bytes in the database file.
int64_t freeSpaceSize();
+ int64_t totalSize();
// The SQLite SYNCHRONOUS pragma can be either FULL, NORMAL, or OFF
// FULL - Any writing calls to the DB block until the data is actually on the disk surface
@@ -108,6 +110,18 @@ public:
void unlock();
bool isAutoCommitOn() const;
+ // The SQLite AUTO_VACUUM pragma can be either NONE, FULL, or INCREMENTAL.
+ // NONE - SQLite does not do any vacuuming
+ // FULL - SQLite moves all empty pages to the end of the DB file and truncates
+ // the file to remove those pages after every transaction. This option
+ // requires SQLite to store additional information about each page in
+ // the database file.
+ // INCREMENTAL - SQLite stores extra information for each page in the database
+ // file, but removes the empty pages only when PRAGMA INCREMANTAL_VACUUM
+ // is called.
+ enum AutoVacuumPragma { AutoVacuumNone = 0, AutoVacuumFull = 1, AutoVacuumIncremental = 2 };
+ bool turnOnIncrementalAutoVacuum();
+
// Set this flag to allow access from multiple threads. Not all multi-threaded accesses are safe!
// See http://www.sqlite.org/cvstrac/wiki?p=MultiThreading for more info.
#ifndef NDEBUG
diff --git a/WebCore/platform/sql/SQLiteStatement.cpp b/WebCore/platform/sql/SQLiteStatement.cpp
index 8963adb..cd2a467 100644
--- a/WebCore/platform/sql/SQLiteStatement.cpp
+++ b/WebCore/platform/sql/SQLiteStatement.cpp
@@ -65,6 +65,15 @@ int SQLiteStatement::prepare()
LOG(SQLDatabase, "SQL - prepare - %s", m_query.ascii().data());
String strippedQuery = m_query.stripWhiteSpace();
int error = sqlite3_prepare16_v2(m_database.sqlite3Handle(), strippedQuery.charactersWithNullTermination(), -1, &m_statement, &tail);
+
+ // Starting with version 3.6.16, sqlite has a patch (http://www.sqlite.org/src/ci/256ec3c6af)
+ // that should make sure sqlite3_prepare16_v2 doesn't return a SQLITE_SCHEMA error.
+ // If we're using an older sqlite version, try to emulate the patch.
+ if (error == SQLITE_SCHEMA) {
+ sqlite3_finalize(m_statement);
+ error = sqlite3_prepare16_v2(m_database.sqlite3Handle(), m_query.charactersWithNullTermination(), -1, &m_statement, &tail);
+ }
+
if (error != SQLITE_OK)
LOG(SQLDatabase, "sqlite3_prepare16 failed (%i)\n%s\n%s", error, m_query.ascii().data(), sqlite3_errmsg(m_database.sqlite3Handle()));
const UChar* ch = static_cast<const UChar*>(tail);
@@ -87,6 +96,7 @@ int SQLiteStatement::step()
LOG(SQLDatabase, "sqlite3_step failed (%i)\nQuery - %s\nError - %s",
error, m_query.ascii().data(), sqlite3_errmsg(m_database.sqlite3Handle()));
}
+
return error;
}
diff --git a/WebCore/platform/text/CharacterNames.h b/WebCore/platform/text/CharacterNames.h
index c0b1750..fbb9466 100644
--- a/WebCore/platform/text/CharacterNames.h
+++ b/WebCore/platform/text/CharacterNames.h
@@ -30,40 +30,42 @@
namespace WebCore {
- // Names here are taken from the Unicode standard.
+// Names here are taken from the Unicode standard.
- // Note, these are UChar constants, not UChar32, which makes them
- // more convenient for WebCore code that mostly uses UTF-16.
+// Note, these are UChar constants, not UChar32, which makes them
+// more convenient for WebCore code that mostly uses UTF-16.
- const UChar blackSquare = 0x25A0;
- const UChar bullet = 0x2022;
- const UChar ethiopicPrefaceColon = 0x1366;
- const UChar hebrewPunctuationGeresh = 0x05F3;
- const UChar hebrewPunctuationGershayim = 0x05F4;
- const UChar horizontalEllipsis = 0x2026;
- const UChar hyphenMinus = 0x002D;
- const UChar ideographicComma = 0x3001;
- const UChar ideographicFullStop = 0x3002;
- const UChar ideographicSpace = 0x3000;
- const UChar leftDoubleQuotationMark = 0x201C;
- const UChar leftSingleQuotationMark = 0x2018;
- const UChar leftToRightEmbed = 0x202A;
- const UChar leftToRightMark = 0x200E;
- const UChar leftToRightOverride = 0x202D;
- const UChar newlineCharacter = 0x000A;
- const UChar noBreakSpace = 0x00A0;
- const UChar objectReplacementCharacter = 0xFFFC;
- const UChar popDirectionalFormatting = 0x202C;
- const UChar replacementCharacter = 0xFFFD;
- const UChar rightDoubleQuotationMark = 0x201D;
- const UChar rightSingleQuotationMark = 0x2019;
- const UChar rightToLeftEmbed = 0x202B;
- const UChar rightToLeftMark = 0x200F;
- const UChar rightToLeftOverride = 0x202E;
- const UChar softHyphen = 0x00AD;
- const UChar space = 0x0020;
- const UChar whiteBullet = 0x25E6;
- const UChar zeroWidthSpace = 0x200B;
+const UChar blackSquare = 0x25A0;
+const UChar bullet = 0x2022;
+const UChar ethiopicPrefaceColon = 0x1366;
+const UChar hebrewPunctuationGeresh = 0x05F3;
+const UChar hebrewPunctuationGershayim = 0x05F4;
+const UChar horizontalEllipsis = 0x2026;
+const UChar hyphenMinus = 0x002D;
+const UChar ideographicComma = 0x3001;
+const UChar ideographicFullStop = 0x3002;
+const UChar ideographicSpace = 0x3000;
+const UChar leftDoubleQuotationMark = 0x201C;
+const UChar leftSingleQuotationMark = 0x2018;
+const UChar leftToRightEmbed = 0x202A;
+const UChar leftToRightMark = 0x200E;
+const UChar leftToRightOverride = 0x202D;
+const UChar newlineCharacter = 0x000A;
+const UChar noBreakSpace = 0x00A0;
+const UChar objectReplacementCharacter = 0xFFFC;
+const UChar popDirectionalFormatting = 0x202C;
+const UChar replacementCharacter = 0xFFFD;
+const UChar rightDoubleQuotationMark = 0x201D;
+const UChar rightSingleQuotationMark = 0x2019;
+const UChar rightToLeftEmbed = 0x202B;
+const UChar rightToLeftMark = 0x200F;
+const UChar rightToLeftOverride = 0x202E;
+const UChar softHyphen = 0x00AD;
+const UChar space = 0x0020;
+const UChar whiteBullet = 0x25E6;
+const UChar zeroWidthJoiner = 0x200D;
+const UChar zeroWidthNonJoiner = 0x200C;
+const UChar zeroWidthSpace = 0x200B;
}
diff --git a/WebCore/platform/text/TextEncodingRegistry.cpp b/WebCore/platform/text/TextEncodingRegistry.cpp
index 00ad2c9..dad0f39 100644
--- a/WebCore/platform/text/TextEncodingRegistry.cpp
+++ b/WebCore/platform/text/TextEncodingRegistry.cpp
@@ -316,4 +316,19 @@ bool noExtendedTextEncodingNameUsed()
return !didExtendTextCodecMaps;
}
+#ifndef NDEBUG
+void dumpTextEncodingNameMap()
+{
+ unsigned size = textEncodingNameMap->size();
+ fprintf(stderr, "Dumping %u entries in WebCore::textEncodingNameMap...\n", size);
+
+ MutexLocker lock(encodingRegistryMutex());
+
+ TextEncodingNameMap::const_iterator it = textEncodingNameMap->begin();
+ TextEncodingNameMap::const_iterator end = textEncodingNameMap->end();
+ for (; it != end; ++it)
+ fprintf(stderr, "'%s' => '%s'\n", it->first, it->second);
+}
+#endif
+
} // namespace WebCore
diff --git a/WebCore/platform/text/TextEncodingRegistry.h b/WebCore/platform/text/TextEncodingRegistry.h
index e6950cf..81b7c4c 100644
--- a/WebCore/platform/text/TextEncodingRegistry.h
+++ b/WebCore/platform/text/TextEncodingRegistry.h
@@ -46,6 +46,9 @@ namespace WebCore {
// Only TextEncoding should use this function directly.
bool noExtendedTextEncodingNameUsed();
+#ifndef NDEBUG
+ void dumpTextEncodingNameMap();
+#endif
}
#endif // TextEncodingRegistry_h
diff --git a/WebCore/platform/text/TextStream.cpp b/WebCore/platform/text/TextStream.cpp
index 4386059..646de3f 100644
--- a/WebCore/platform/text/TextStream.cpp
+++ b/WebCore/platform/text/TextStream.cpp
@@ -108,7 +108,7 @@ String TextStream::release()
return String::adopt(m_text);
}
-#if OS(WINDOWS) && PLATFORM(X86_64) && COMPILER(MSVC)
+#if OS(WINDOWS) && CPU(X86_64)
TextStream& TextStream::operator<<(__int64 i)
{
char buffer[printBufferSize];
diff --git a/WebCore/platform/text/TextStream.h b/WebCore/platform/text/TextStream.h
index d69e34b..f5e512c 100644
--- a/WebCore/platform/text/TextStream.h
+++ b/WebCore/platform/text/TextStream.h
@@ -45,7 +45,7 @@ public:
TextStream& operator<<(const char*);
TextStream& operator<<(const void*);
TextStream& operator<<(const String&);
-#if OS(WINDOWS) && PLATFORM(X86_64) && COMPILER(MSVC)
+#if OS(WINDOWS) && CPU(X86_64)
TextStream& operator<<(unsigned __int64);
TextStream& operator<<(__int64);
#endif
diff --git a/WebCore/platform/win/WidgetWin.cpp b/WebCore/platform/win/WidgetWin.cpp
index 74a22f6..607c0d8 100644
--- a/WebCore/platform/win/WidgetWin.cpp
+++ b/WebCore/platform/win/WidgetWin.cpp
@@ -101,7 +101,7 @@ void Widget::paint(GraphicsContext*, const IntRect&)
{
}
-void Widget::setFocus()
+void Widget::setFocus(bool focused)
{
}
diff --git a/WebCore/platform/wince/SharedTimerWince.cpp b/WebCore/platform/wince/SharedTimerWince.cpp
index 5f6a386..2328017 100644
--- a/WebCore/platform/wince/SharedTimerWince.cpp
+++ b/WebCore/platform/wince/SharedTimerWince.cpp
@@ -36,7 +36,7 @@
#include <windows.h>
namespace JSC {
-extern void* g_stackBase;
+JS_EXPORTDATA extern void* g_stackBase;
}
namespace WebCore {
diff --git a/WebCore/platform/wx/WidgetWx.cpp b/WebCore/platform/wx/WidgetWx.cpp
index a384914..9de4c3d 100644
--- a/WebCore/platform/wx/WidgetWx.cpp
+++ b/WebCore/platform/wx/WidgetWx.cpp
@@ -44,10 +44,12 @@ Widget::~Widget()
{
}
-void Widget::setFocus()
+void Widget::setFocus(bool focused)
{
- if (PlatformWidget widget = platformWidget())
- widget->SetFocus();
+ if (focused) {
+ if (PlatformWidget widget = platformWidget())
+ widget->SetFocus();
+ }
}
void Widget::setCursor(const Cursor& cursor)
diff --git a/WebCore/platform/wx/wxcode/fontprops.h b/WebCore/platform/wx/wxcode/fontprops.h
index 3f99462..7702db2 100644
--- a/WebCore/platform/wx/wxcode/fontprops.h
+++ b/WebCore/platform/wx/wxcode/fontprops.h
@@ -48,4 +48,4 @@ private:
};
-bool wxFontContainsCharacters(const wxFont& font, const UChar* characters, int length);
+bool wxFontContainsCharacters(void* font, const UChar* characters, int length);
diff --git a/WebCore/platform/wx/wxcode/mac/carbon/fontprops.mm b/WebCore/platform/wx/wxcode/mac/carbon/fontprops.mm
index ff4c18a..9da47fd 100644
--- a/WebCore/platform/wx/wxcode/mac/carbon/fontprops.mm
+++ b/WebCore/platform/wx/wxcode/mac/carbon/fontprops.mm
@@ -28,6 +28,7 @@
#include <wtf/unicode/Unicode.h>
#include "fontprops.h"
+#include "WebCoreSystemInterface.h"
#include <ApplicationServices/ApplicationServices.h>
@@ -35,10 +36,6 @@
#include <wx/gdicmn.h>
#include <wx/graphics.h>
-#ifdef BUILDING_ON_TIGER
-void (*wkGetFontMetrics)(CGFontRef, int* ascent, int* descent, int* lineGap, unsigned* unitsPerEm);
-#endif
-
const float smallCapsFontSizeMultiplier = 0.7f;
const float contextDPI = 72.0f;
static inline float scaleEmToUnits(float x, unsigned unitsPerEm) { return x * (contextDPI / (contextDPI * unitsPerEm)); }
@@ -92,23 +89,20 @@ m_ascent(0), m_descent(0), m_lineGap(0), m_lineSpacing(0), m_xHeight(0)
}
-bool wxFontContainsCharacters(const wxFont& font, const UChar* characters, int length)
+bool wxFontContainsCharacters(void* font, const UChar* characters, int length)
{
-#if wxOSX_USE_COCOA
NSString* string = [[NSString alloc] initWithCharactersNoCopy:const_cast<unichar*>(characters) length:length freeWhenDone:NO];
- NSCharacterSet* set = [[font.OSXGetNSFont() coveredCharacterSet] invertedSet];
+ NSCharacterSet* set = [[(NSFont*)font coveredCharacterSet] invertedSet];
bool result = set && [string rangeOfCharacterFromSet:set].location == NSNotFound;
[string release];
return result;
-#else
- return true;
-#endif
}
void GetTextExtent( const wxFont& font, const wxString& str, wxCoord *width, wxCoord *height,
wxCoord *descent, wxCoord *externalLeading )
{
wxGraphicsContext * const gc = wxGraphicsContext::Create();
+
gc->SetFont(font, *wxBLACK); // colour doesn't matter but must be specified
struct GCTextExtent
{
diff --git a/WebCore/platform/wx/wxcode/mac/carbon/non-kerned-drawing.cpp b/WebCore/platform/wx/wxcode/mac/carbon/non-kerned-drawing.cpp
index 47eb1f8..82259f4 100644
--- a/WebCore/platform/wx/wxcode/mac/carbon/non-kerned-drawing.cpp
+++ b/WebCore/platform/wx/wxcode/mac/carbon/non-kerned-drawing.cpp
@@ -39,14 +39,6 @@
#include <wx/dcgraph.h>
#include <wx/gdicmn.h>
-
-// Unfortunately we need access to a private function to get the character -> glyph conversion needed to
-// allow us to use CGContextShowGlyphsWithAdvances
-// Note that on < 10.5, the function is called CGFontGetGlyphsForUnicodes, so we need to detect and deal
-// with this.
-typedef void (*CGFontGetGlyphsForUnicharsPtr)(CGFontRef, const UniChar[], const CGGlyph[], size_t);
-static CGFontGetGlyphsForUnicharsPtr CGFontGetGlyphsForUnichars = (CGFontGetGlyphsForUnicharsPtr)dlsym(RTLD_DEFAULT, "CGFontGetGlyphsForUnichars");
-
namespace WebCore {
void drawTextWithSpacing(GraphicsContext* graphicsContext, const SimpleFontData* font, const wxColour& color, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point)
@@ -60,18 +52,7 @@ void drawTextWithSpacing(GraphicsContext* graphicsContext, const SimpleFontData*
CGContextRef cgContext = static_cast<CGContextRef>(dc->GetGraphicsContext()->GetNativeContext());
- CGFontRef cgFont;
-
-#ifdef wxOSX_USE_CORE_TEXT && wxOSX_USE_CORE_TEXT
- cgFont = CTFontCopyGraphicsFont((CTFontRef)wxfont->OSXGetCTFont(), NULL);
-#else
- ATSFontRef fontRef;
-
- fontRef = FMGetATSFontRefFromFont(wxfont->MacGetATSUFontID());
-
- if (fontRef)
- cgFont = CGFontCreateWithPlatformFont((void*)&fontRef);
-#endif
+ CGFontRef cgFont = font->platformData().cgFont();
CGContextSetFont(cgContext, cgFont);
@@ -89,26 +70,7 @@ void drawTextWithSpacing(GraphicsContext* graphicsContext, const SimpleFontData*
CGContextSetTextPosition(cgContext, point.x(), point.y());
- const FloatSize* advanceSizes = static_cast<const FloatSize*>(glyphBuffer.advances(from));
- int size = glyphBuffer.size() - from;
- CGSize sizes[size];
- CGGlyph glyphs[numGlyphs];
-
- // if the function doesn't exist, we're probably on tiger and need to grab the
- // function under its old name, CGFontGetGlyphsForUnicodes
- if (!CGFontGetGlyphsForUnichars)
- CGFontGetGlyphsForUnichars = (CGFontGetGlyphsForUnicharsPtr)dlsym(RTLD_DEFAULT, "CGFontGetGlyphsForUnicodes");
-
- // Let's make sure we got the function under one name or another!
- ASSERT(CGFontGetGlyphsForUnichars);
- CGFontGetGlyphsForUnichars(cgFont, glyphBuffer.glyphs(from), glyphs, numGlyphs);
-
- for (int i = 0; i < size; i++) {
- FloatSize fsize = advanceSizes[i];
- sizes[i] = CGSizeMake(fsize.width(), fsize.height());
- }
-
- CGContextShowGlyphsWithAdvances(cgContext, glyphs, sizes, numGlyphs);
+ CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
if (cgFont)
CGFontRelease(cgFont);
diff --git a/WebCore/platform/wx/wxcode/win/fontprops.cpp b/WebCore/platform/wx/wxcode/win/fontprops.cpp
index d6ba964..f3e4fda 100644
--- a/WebCore/platform/wx/wxcode/win/fontprops.cpp
+++ b/WebCore/platform/wx/wxcode/win/fontprops.cpp
@@ -66,7 +66,7 @@ m_ascent(0), m_descent(0), m_lineGap(0), m_lineSpacing(0), m_xHeight(0)
ReleaseDC(0, dc);
}
-bool wxFontContainsCharacters(const wxFont& font, const UChar* characters, int length)
+bool wxFontContainsCharacters(void* font, const UChar* characters, int length)
{
// FIXME: Microsoft documentation seems to imply that characters can be output using a given font and DC
// merely by testing code page intersection. This seems suspect though. Can't a font only partially
@@ -89,7 +89,7 @@ bool wxFontContainsCharacters(const wxFont& font, const UChar* characters, int l
langFontLink->CodePageToCodePages(CP_ACP, &acpCodePages);
DWORD fontCodePages;
- langFontLink->GetFontCodePages(dc, static_cast<HFONT>(font.GetHFONT()), &fontCodePages);
+ langFontLink->GetFontCodePages(dc, (HFONT)font, &fontCodePages);
DWORD actualCodePages;
long numCharactersProcessed;