diff options
Diffstat (limited to 'WebCore/platform')
122 files changed, 6620 insertions, 1241 deletions
diff --git a/WebCore/platform/ContextMenuItem.h b/WebCore/platform/ContextMenuItem.h index 3a4cdfa..d6ab519 100644 --- a/WebCore/platform/ContextMenuItem.h +++ b/WebCore/platform/ContextMenuItem.h @@ -46,6 +46,8 @@ typedef struct _GtkMenuItem GtkMenuItem; #include <QAction> #elif PLATFORM(WX) class wxMenuItem; +#elif PLATFORM(HAIKU) +class BMenuItem; #endif namespace WebCore { @@ -204,6 +206,8 @@ namespace WebCore { bool checked; bool enabled; }; +#elif PLATFORM(HAIKU) + typedef BMenuItem* PlatformMenuItemDescription; #else typedef void* PlatformMenuItemDescription; #endif diff --git a/WebCore/platform/Cookie.h b/WebCore/platform/Cookie.h new file mode 100644 index 0000000..f646d3a --- /dev/null +++ b/WebCore/platform/Cookie.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2009 Joseph Pecoraro. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef Cookie_h +#define Cookie_h + +#include "PlatformString.h" + +namespace WebCore { + + struct Cookie { + Cookie(const String& name, const String& value, const String& domain, + const String& path, double expires, bool httpOnly, bool secure, + bool session) + : name(name) + , value(value) + , domain(domain) + , path(path) + , expires(expires) + , httpOnly(httpOnly) + , secure(secure) + , session(session) + { + } + + String name; + String value; + String domain; + String path; + double expires; + bool httpOnly; + bool secure; + bool session; + }; + +} + +#endif diff --git a/WebCore/platform/CookieJar.h b/WebCore/platform/CookieJar.h index 6159386..987543e 100644 --- a/WebCore/platform/CookieJar.h +++ b/WebCore/platform/CookieJar.h @@ -26,15 +26,21 @@ #ifndef CookieJar_h #define CookieJar_h +#include <wtf/Vector.h> + namespace WebCore { + class Document; class KURL; class String; - class Document; + + struct Cookie; String cookies(const Document*, const KURL&); void setCookies(Document*, const KURL&, const String&); bool cookiesEnabled(const Document*); + bool getRawCookies(const Document*, const KURL&, Vector<Cookie>&); + void deleteCookie(const Document*, const KURL&, const String&); } diff --git a/WebCore/platform/CrossThreadCopier.h b/WebCore/platform/CrossThreadCopier.h index d12d72d..178e056 100644 --- a/WebCore/platform/CrossThreadCopier.h +++ b/WebCore/platform/CrossThreadCopier.h @@ -46,6 +46,7 @@ namespace WebCore { class String; struct CrossThreadResourceResponseData; struct CrossThreadResourceRequestData; + struct ThreadableLoaderOptions; template<typename T> struct CrossThreadCopierPassThrough { typedef T Type; @@ -65,6 +66,9 @@ namespace WebCore { template<typename T> struct CrossThreadCopierBase<false, T*> : public CrossThreadCopierPassThrough<T*> { }; + template<> struct CrossThreadCopierBase<false, ThreadableLoaderOptions> : public CrossThreadCopierPassThrough<ThreadableLoaderOptions> { + }; + // Custom copy methods. template<typename T> struct CrossThreadCopierBase<false, RefPtr<ThreadSafeShared<T> > > { typedef PassRefPtr<T> Type; diff --git a/WebCore/platform/Cursor.h b/WebCore/platform/Cursor.h index ea75191..2d041d2 100644 --- a/WebCore/platform/Cursor.h +++ b/WebCore/platform/Cursor.h @@ -40,6 +40,8 @@ typedef struct _GdkCursor GdkCursor; #include <QCursor> #elif PLATFORM(CHROMIUM) #include "PlatformCursor.h" +#elif PLATFORM(HAIKU) +#include <app/Cursor.h> #endif #if PLATFORM(MAC) @@ -86,6 +88,9 @@ namespace WebCore { #elif PLATFORM(CHROMIUM) // See PlatformCursor.h typedef void* PlatformCursorHandle; +#elif PLATFORM(HAIKU) + typedef BCursor* PlatformCursor; + typedef BCursor* PlatformCursorHandle; #else typedef void* PlatformCursor; typedef void* PlatformCursorHandle; diff --git a/WebCore/platform/DragData.h b/WebCore/platform/DragData.h index a1555e3..116ffdd 100644 --- a/WebCore/platform/DragData.h +++ b/WebCore/platform/DragData.h @@ -58,6 +58,9 @@ typedef void* DragDataRef; typedef void* DragDataRef; #elif PLATFORM(CHROMIUM) #include "DragDataRef.h" +#elif PLATFORM(HAIKU) +class BMessage; +typedef class BMessage* DragDataRef; #endif diff --git a/WebCore/platform/DragImage.h b/WebCore/platform/DragImage.h index 0196971..611eb8a 100644 --- a/WebCore/platform/DragImage.h +++ b/WebCore/platform/DragImage.h @@ -48,6 +48,8 @@ class wxDragImage; #include "DragImageRef.h" #elif PLATFORM(GTK) typedef struct _GdkPixbuf GdkPixbuf; +#elif PLATFORM(HAIKU) +class BBitmap; #endif //We need to #define YOffset as it needs to be shared with WebKit @@ -72,6 +74,8 @@ namespace WebCore { typedef wxDragImage* DragImageRef; #elif PLATFORM(GTK) typedef GdkPixBuf* DragImageRef; +#elif PLATFORM(HAIKU) + typedef BBitmap* DragImageRef; #elif PLATFORM(ANDROID) typedef void* DragImageRef; #endif diff --git a/WebCore/platform/Pasteboard.h b/WebCore/platform/Pasteboard.h index 883364a..5d63254 100644 --- a/WebCore/platform/Pasteboard.h +++ b/WebCore/platform/Pasteboard.h @@ -102,6 +102,7 @@ public: #if PLATFORM(GTK) void setHelper(PasteboardHelper*); + PasteboardHelper* m_helper; #endif private: @@ -117,10 +118,6 @@ private: HWND m_owner; #endif -#if PLATFORM(GTK) - PasteboardHelper* m_helper; -#endif - #if PLATFORM(QT) bool m_selectionMode; #endif diff --git a/WebCore/platform/PlatformKeyboardEvent.h b/WebCore/platform/PlatformKeyboardEvent.h index 1499ac5..b5c2e95 100644 --- a/WebCore/platform/PlatformKeyboardEvent.h +++ b/WebCore/platform/PlatformKeyboardEvent.h @@ -59,6 +59,10 @@ QT_END_NAMESPACE class wxKeyEvent; #endif +#if PLATFORM(HAIKU) +class BMessage; +#endif + namespace WebCore { class PlatformKeyboardEvent { @@ -155,6 +159,10 @@ namespace WebCore { PlatformKeyboardEvent(wxKeyEvent&); #endif +#if PLATFORM(HAIKU) + PlatformKeyboardEvent(BMessage*); +#endif + #if PLATFORM(WIN) || PLATFORM(CHROMIUM) bool isSystemKey() const { return m_isSystemKey; } #endif diff --git a/WebCore/platform/PlatformMenuDescription.h b/WebCore/platform/PlatformMenuDescription.h index ab71710..c986207 100644 --- a/WebCore/platform/PlatformMenuDescription.h +++ b/WebCore/platform/PlatformMenuDescription.h @@ -40,6 +40,8 @@ typedef struct HMENU__* HMENU; typedef struct _GtkMenu GtkMenu; #elif PLATFORM(WX) class wxMenu; +#elif PLATFORM(HAIKU) +class BMenu; #endif namespace WebCore { @@ -58,6 +60,8 @@ namespace WebCore { typedef void* PlatformMenuDescription; #elif PLATFORM(WX) typedef wxMenu* PlatformMenuDescription; +#elif PLATFORM(HAIKU) + typedef BMenu* PlatformMenuDescription; #else typedef void* PlatformMenuDescription; #endif diff --git a/WebCore/platform/PlatformMouseEvent.h b/WebCore/platform/PlatformMouseEvent.h index 2543d40..d01636e 100644 --- a/WebCore/platform/PlatformMouseEvent.h +++ b/WebCore/platform/PlatformMouseEvent.h @@ -50,6 +50,10 @@ typedef long LPARAM; class wxMouseEvent; #endif +#if PLATFORM(HAIKU) +class BMessage; +#endif + namespace WebCore { // These button numbers match the ones used in the DOM API, 0 through 2, except for NoButton which isn't specified. @@ -128,6 +132,10 @@ namespace WebCore { PlatformMouseEvent(const wxMouseEvent&, const wxPoint& globalPoint, int clickCount); #endif +#if PLATFORM(HAIKU) + PlatformMouseEvent(const BMessage*); +#endif + protected: IntPoint m_position; IntPoint m_globalPosition; diff --git a/WebCore/platform/PlatformWheelEvent.h b/WebCore/platform/PlatformWheelEvent.h index ae8df4e..1978438 100644 --- a/WebCore/platform/PlatformWheelEvent.h +++ b/WebCore/platform/PlatformWheelEvent.h @@ -49,6 +49,10 @@ class wxMouseEvent; class wxPoint; #endif +#if PLATFORM(HAIKU) +class BMessage; +#endif + namespace WebCore { class FloatPoint; @@ -109,6 +113,10 @@ namespace WebCore { PlatformWheelEvent(const wxMouseEvent&, const wxPoint&); #endif +#if PLATFORM(HAIKU) + PlatformWheelEvent(BMessage*); +#endif + protected: IntPoint m_position; IntPoint m_globalPosition; diff --git a/WebCore/platform/PopupMenu.h b/WebCore/platform/PopupMenu.h index fc85d60..04b5a68 100644 --- a/WebCore/platform/PopupMenu.h +++ b/WebCore/platform/PopupMenu.h @@ -59,6 +59,8 @@ class wxMenu; #include <wx/event.h> #elif PLATFORM(CHROMIUM) #include "PopupMenuPrivate.h" +#elif PLATFORM(HAIKU) +class BMenu; #endif namespace WebCore { @@ -92,6 +94,8 @@ public: #if PLATFORM(WIN) Scrollbar* scrollbar() const { return m_scrollbar.get(); } + static LPCTSTR popupClassName(); + bool up(unsigned lines = 1); bool down(unsigned lines = 1); @@ -177,6 +181,8 @@ private: void OnMenuItemSelected(wxCommandEvent&); #elif PLATFORM(CHROMIUM) PopupMenuPrivate p; +#elif PLATFORM(HAIKU) + BMenu* m_menu; #endif }; diff --git a/WebCore/platform/TreeShared.h b/WebCore/platform/TreeShared.h index 1ac1b33..02728ff 100644 --- a/WebCore/platform/TreeShared.h +++ b/WebCore/platform/TreeShared.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -28,17 +28,8 @@ namespace WebCore { template<class T> class TreeShared : public Noncopyable { public: - TreeShared() - : m_refCount(0) - , m_parent(0) - { -#ifndef NDEBUG - m_deletionHasBegun = false; - m_inRemovedLastRefFunction = false; -#endif - } - TreeShared(T* parent) - : m_refCount(0) + TreeShared(int initialRefCount = 1) + : m_refCount(initialRefCount) , m_parent(0) { #ifndef NDEBUG diff --git a/WebCore/platform/Widget.h b/WebCore/platform/Widget.h index 4534d58..798ab9e 100644 --- a/WebCore/platform/Widget.h +++ b/WebCore/platform/Widget.h @@ -70,6 +70,11 @@ class wxWindow; typedef wxWindow* PlatformWidget; #endif +#if PLATFORM(HAIKU) +class BView; +typedef BView* PlatformWidget; +#endif + #if PLATFORM(CHROMIUM) #include "PlatformWidget.h" #endif diff --git a/WebCore/platform/chromium/PopupMenuChromium.cpp b/WebCore/platform/chromium/PopupMenuChromium.cpp index 51ed6ce..20e0901 100644 --- a/WebCore/platform/chromium/PopupMenuChromium.cpp +++ b/WebCore/platform/chromium/PopupMenuChromium.cpp @@ -601,6 +601,22 @@ bool PopupListBox::isInterestedInEventForKey(int keyCode) } } +static bool isCharacterTypeEvent(const PlatformKeyboardEvent& event) +{ + // Check whether the event is a character-typed event or not. + // In Windows, PlatformKeyboardEvent::Char (not RawKeyDown) type event + // is considered as character type event. In Mac OS, KeyDown (not + // KeyUp) is considered as character type event. +#if PLATFORM(WIN_OS) + if (event.type() == PlatformKeyboardEvent::Char) + return true; +#else + if (event.type() == PlatformKeyboardEvent::KeyDown) + return true; +#endif + return false; +} + bool PopupListBox::handleKeyEvent(const PlatformKeyboardEvent& event) { if (event.type() == PlatformKeyboardEvent::KeyUp) @@ -641,7 +657,8 @@ bool PopupListBox::handleKeyEvent(const PlatformKeyboardEvent& event) break; default: if (!event.ctrlKey() && !event.altKey() && !event.metaKey() - && isPrintableChar(event.windowsVirtualKeyCode())) + && isPrintableChar(event.windowsVirtualKeyCode()) + && isCharacterTypeEvent(event)) typeAheadFind(event); break; } @@ -690,21 +707,6 @@ static String stripLeadingWhiteSpace(const String& string) return string.substring(i, length - i); } -static bool isCharacterTypeEvent(const PlatformKeyboardEvent& event) { - // Check whether the event is a character-typed event or not. - // In Windows, PlatformKeyboardEvent::Char (not RawKeyDown) type event - // is considered as character type event. In Mac OS, KeyDown (not - // KeyUp) is considered as character type event. -#if PLATFORM(WIN_OS) - if (event.type() == PlatformKeyboardEvent::Char) - return true; -#else - if (event.type() == PlatformKeyboardEvent::KeyDown) - return true; -#endif - return false; -} - // From HTMLSelectElement.cpp, with modifications void PopupListBox::typeAheadFind(const PlatformKeyboardEvent& event) { @@ -714,8 +716,7 @@ void PopupListBox::typeAheadFind(const PlatformKeyboardEvent& event) // Reset the time when user types in a character. The time gap between // last character and the current character is used to indicate whether // user typed in a string or just a character as the search prefix. - if (isCharacterTypeEvent(event)) - m_lastCharTime = now; + m_lastCharTime = now; UChar c = event.windowsVirtualKeyCode(); diff --git a/WebCore/platform/graphics/BitmapImage.h b/WebCore/platform/graphics/BitmapImage.h index 807c11b..6a7c02c 100644 --- a/WebCore/platform/graphics/BitmapImage.h +++ b/WebCore/platform/graphics/BitmapImage.h @@ -45,6 +45,10 @@ class NSImage; typedef struct HBITMAP__ *HBITMAP; #endif +#if PLATFORM(HAIKU) +class BBitmap; +#endif + namespace WebCore { struct FrameData; } @@ -165,10 +169,16 @@ protected: virtual void drawFrameMatchingSourceSize(GraphicsContext*, const FloatRect& dstRect, const IntSize& srcSize, CompositeOperator); #endif virtual void draw(GraphicsContext*, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator); + #if PLATFORM(WX) || PLATFORM(WINCE) virtual void drawPattern(GraphicsContext*, const FloatRect& srcRect, const TransformationMatrix& patternTransform, const FloatPoint& phase, CompositeOperator, const FloatRect& destRect); -#endif +#endif + +#if PLATFORM(HAIKU) + virtual BBitmap* getBBitmap() const; +#endif + size_t currentFrame() const { return m_currentFrame; } size_t frameCount(); NativeImagePtr frameAtIndex(size_t); diff --git a/WebCore/platform/graphics/Color.h b/WebCore/platform/graphics/Color.h index 5baa56e..8e51b95 100644 --- a/WebCore/platform/graphics/Color.h +++ b/WebCore/platform/graphics/Color.h @@ -47,6 +47,10 @@ typedef struct _GdkColor GdkColor; class wxColour; #endif +#if PLATFORM(HAIKU) +struct rgb_color; +#endif + namespace WebCore { class String; @@ -121,6 +125,11 @@ public: Color(CGColorRef); #endif +#if PLATFORM(HAIKU) + Color(const rgb_color&); + operator rgb_color() const; +#endif + static bool parseHexColor(const String& name, RGBA32& rgb); static const RGBA32 black = 0xFF000000; diff --git a/WebCore/platform/graphics/FloatPoint.h b/WebCore/platform/graphics/FloatPoint.h index 0c97c49..a239173 100644 --- a/WebCore/platform/graphics/FloatPoint.h +++ b/WebCore/platform/graphics/FloatPoint.h @@ -51,6 +51,10 @@ class QPointF; QT_END_NAMESPACE #endif +#if PLATFORM(HAIKU) +class BPoint; +#endif + #if PLATFORM(SKIA) struct SkPoint; #endif @@ -90,6 +94,11 @@ public: operator QPointF() const; #endif +#if PLATFORM(HAIKU) + FloatPoint(const BPoint&); + operator BPoint() const; +#endif + #if (PLATFORM(SKIA) || PLATFORM(SGL)) operator SkPoint() const; FloatPoint(const SkPoint&); diff --git a/WebCore/platform/graphics/FloatRect.h b/WebCore/platform/graphics/FloatRect.h index e906812..7c7d32a 100644 --- a/WebCore/platform/graphics/FloatRect.h +++ b/WebCore/platform/graphics/FloatRect.h @@ -51,6 +51,10 @@ QT_END_NAMESPACE class wxRect2DDouble; #endif +#if PLATFORM(HAIKU) +class BRect; +#endif + #if (PLATFORM(SKIA) || PLATFORM(SGL)) struct SkRect; #endif @@ -138,6 +142,11 @@ public: operator wxRect2DDouble() const; #endif +#if PLATFORM(HAIKU) + FloatRect(const BRect&); + operator BRect() const; +#endif + #if (PLATFORM(SKIA) || PLATFORM(SGL)) FloatRect(const SkRect&); operator SkRect() const; diff --git a/WebCore/platform/graphics/FontDescription.h b/WebCore/platform/graphics/FontDescription.h index c893b8a..e5c52bf 100644 --- a/WebCore/platform/graphics/FontDescription.h +++ b/WebCore/platform/graphics/FontDescription.h @@ -80,6 +80,8 @@ public: FontWeight bolderWeight() const; GenericFamilyType genericFamily() const { return static_cast<GenericFamilyType>(m_genericFamily); } bool usePrinterFont() const { return m_usePrinterFont; } + // only use fixed default size when there is only one font family, and that family is "monospace" + bool useFixedDefaultSize() const { return genericFamily() == MonospaceFamily && !family().next() && family().family() == "-webkit-monospace"; } FontRenderingMode renderingMode() const { return static_cast<FontRenderingMode>(m_renderingMode); } unsigned keywordSize() const { return m_keywordSize; } diff --git a/WebCore/platform/graphics/GraphicsContext.cpp b/WebCore/platform/graphics/GraphicsContext.cpp index a4e8408..ccdce08 100644 --- a/WebCore/platform/graphics/GraphicsContext.cpp +++ b/WebCore/platform/graphics/GraphicsContext.cpp @@ -27,9 +27,9 @@ #include "GraphicsContext.h" #include "BidiResolver.h" +#include "Font.h" #include "Generator.h" #include "GraphicsContextPrivate.h" -#include "Font.h" using namespace std; @@ -89,7 +89,7 @@ void GraphicsContext::save() return; m_common->stack.append(m_common->state); - + savePlatformState(); } @@ -104,7 +104,7 @@ void GraphicsContext::restore() } m_common->state = m_common->stack.last(); m_common->stack.removeLast(); - + restorePlatformState(); } @@ -305,7 +305,7 @@ bool GraphicsContext::paintingDisabled() const } void GraphicsContext::drawImage(Image* image, const IntPoint& p, CompositeOperator op) -{ +{ drawImage(image, p, IntRect(0, 0, -1, -1), op); } @@ -329,7 +329,7 @@ void GraphicsContext::drawText(const Font& font, const TextRun& run, const IntPo { if (paintingDisabled()) return; - + font.drawText(this, run, point, from, to); } #endif @@ -383,7 +383,7 @@ void GraphicsContext::initFocusRing(int width, int offset) if (paintingDisabled()) return; clearFocusRing(); - + m_common->m_focusRingWidth = width; m_common->m_focusRingOffset = offset; } @@ -396,12 +396,12 @@ void GraphicsContext::clearFocusRing() IntRect GraphicsContext::focusRingBoundingRect() { IntRect result = IntRect(0, 0, 0, 0); - + const Vector<IntRect>& rects = focusRingRects(); unsigned rectCount = rects.size(); for (unsigned i = 0; i < rectCount; i++) result.unite(rects[i]); - + return result; } @@ -436,7 +436,7 @@ void GraphicsContext::drawImage(Image* image, const FloatRect& dest, const Float float tsh = src.height(); float tw = dest.width(); float th = dest.height(); - + if (tsw == -1) tsw = image->width(); if (tsh == -1) @@ -540,10 +540,39 @@ void GraphicsContext::setPlatformTextDrawingMode(int mode) } #endif -#if !PLATFORM(QT) && !PLATFORM(CAIRO) && !PLATFORM(SKIA) +#if !PLATFORM(QT) && !PLATFORM(CAIRO) && !PLATFORM(SKIA) && !PLATFORM(HAIKU) void GraphicsContext::setPlatformStrokeStyle(const StrokeStyle&) { } #endif +void GraphicsContext::adjustLineToPixelBoundaries(FloatPoint& p1, FloatPoint& p2, float strokeWidth, const StrokeStyle& penStyle) +{ + // For odd widths, we add in 0.5 to the appropriate x/y so that the float arithmetic + // works out. For example, with a border width of 3, WebKit will pass us (y1+y2)/2, e.g., + // (50+53)/2 = 103/2 = 51 when we want 51.5. It is always true that an even width gave + // us a perfect position, but an odd width gave us a position that is off by exactly 0.5. + if (penStyle == DottedStroke || penStyle == DashedStroke) { + if (p1.x() == p2.x()) { + p1.setY(p1.y() + strokeWidth); + p2.setY(p2.y() - strokeWidth); + } else { + p1.setX(p1.x() + strokeWidth); + p2.setX(p2.x() - strokeWidth); + } + } + + if (static_cast<int>(strokeWidth) % 2) { //odd + if (p1.x() == p2.x()) { + // We're a vertical line. Adjust our x. + p1.setX(p1.x() + 0.5f); + p2.setX(p2.x() + 0.5f); + } else { + // We're a horizontal line. Adjust our y. + p1.setY(p1.y() + 0.5f); + p2.setY(p2.y() + 0.5f); + } + } +} + } diff --git a/WebCore/platform/graphics/GraphicsContext.h b/WebCore/platform/graphics/GraphicsContext.h index b52344d..02914b0 100644 --- a/WebCore/platform/graphics/GraphicsContext.h +++ b/WebCore/platform/graphics/GraphicsContext.h @@ -55,8 +55,8 @@ struct SkPoint; class wxGCDC; class wxWindowDC; -// wxGraphicsContext allows us to support Path, etc. -// but on some platforms, e.g. Linux, it requires fairly +// wxGraphicsContext allows us to support Path, etc. +// but on some platforms, e.g. Linux, it requires fairly // new software. #if USE(WXGC) // On OS X, wxGCDC is just a typedef for wxDC, so use wxDC explicitly to make @@ -72,6 +72,10 @@ class wxWindowDC; #endif #elif PLATFORM(SKIA) typedef class PlatformContextSkia PlatformGraphicsContext; +#elif PLATFORM(HAIKU) +class BView; +typedef BView PlatformGraphicsContext; +struct pattern; #elif PLATFORM(WINCE) typedef struct HDC__ PlatformGraphicsContext; #else @@ -124,7 +128,7 @@ namespace WebCore { const int cTextFill = 1; const int cTextStroke = 2; const int cTextClip = 4; - + enum StrokeStyle { NoStroke, SolidStroke, @@ -132,12 +136,12 @@ namespace WebCore { DashedStroke }; -// FIXME: This is a place-holder until we decide to add -// real color space support to WebCore. At that time, ColorSpace will be a -// class and instances will be held off of Colors. There will be -// special singleton Gradient and Pattern color spaces to mark when -// a fill or stroke is using a gradient or pattern instead of a solid color. -// https://bugs.webkit.org/show_bug.cgi?id=20558 + // FIXME: This is a place-holder until we decide to add + // real color space support to WebCore. At that time, ColorSpace will be a + // class and instances will be held off of Colors. There will be + // special singleton Gradient and Pattern color spaces to mark when + // a fill or stroke is using a gradient or pattern instead of a solid color. + // https://bugs.webkit.org/show_bug.cgi?id=20558 enum ColorSpace { SolidColorSpace, PatternColorSpace, @@ -156,11 +160,11 @@ namespace WebCore { public: GraphicsContext(PlatformGraphicsContext*); ~GraphicsContext(); - + #if !PLATFORM(WINCE) || PLATFORM(QT) PlatformGraphicsContext* platformContext() const; #endif - + float strokeThickness() const; void setStrokeThickness(float); StrokeStyle strokeStyle() const; @@ -265,7 +269,7 @@ namespace WebCore { CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false); void drawTiledImage(Image*, const IntRect& destRect, const IntPoint& srcPoint, const IntSize& tileSize, CompositeOperator = CompositeSourceOver); - void drawTiledImage(Image*, const IntRect& destRect, const IntRect& srcRect, + void drawTiledImage(Image*, const IntRect& destRect, const IntRect& srcRect, Image::TileRule hRule = Image::StretchTile, Image::TileRule vRule = Image::StretchTile, CompositeOperator = CompositeSourceOver); @@ -289,13 +293,13 @@ namespace WebCore { void drawHighlightForText(const Font&, const TextRun&, const IntPoint&, int h, const Color& backgroundColor, int from = 0, int to = -1); FloatRect roundToDevicePixels(const FloatRect&); - + void drawLineForText(const IntPoint&, int width, bool printing); void drawLineForMisspellingOrBadGrammar(const IntPoint&, int width, bool grammar); - + bool paintingDisabled() const; void setPaintingDisabled(bool); - + bool updatingControlTints() const; void setUpdatingControlTints(bool); @@ -334,7 +338,7 @@ namespace WebCore { void rotate(float angleInRadians); void translate(float x, float y); IntPoint origin(); - + void setURLForRect(const KURL&, const IntRect&); void concatCTM(const TransformationMatrix&); @@ -416,6 +420,10 @@ namespace WebCore { GdkEventExpose* gdkExposeEvent() const; #endif +#if PLATFORM(HAIKU) + pattern getHaikuStrokeStyle(); +#endif + private: void savePlatformState(); void restorePlatformState(); @@ -438,6 +446,8 @@ namespace WebCore { void setPlatformShadow(const IntSize&, int blur, const Color&); void clearPlatformShadow(); + static void adjustLineToPixelBoundaries(FloatPoint& p1, FloatPoint& p2, float strokeWidth, const StrokeStyle&); + int focusRingWidth() const; int focusRingOffset() const; const Vector<IntRect>& focusRingRects() const; diff --git a/WebCore/platform/graphics/GraphicsLayer.cpp b/WebCore/platform/graphics/GraphicsLayer.cpp index 7d43832..b375bd3 100644 --- a/WebCore/platform/graphics/GraphicsLayer.cpp +++ b/WebCore/platform/graphics/GraphicsLayer.cpp @@ -69,10 +69,11 @@ GraphicsLayer::GraphicsLayer(GraphicsLayerClient* client) , m_usingTiledLayer(false) , m_masksToBounds(false) , m_drawsContent(false) - , m_paintingPhase(GraphicsLayerPaintAllMask) + , m_paintingPhase(GraphicsLayerPaintAll) , m_geometryOrientation(CompositingCoordinatesTopDown) , m_contentsOrientation(CompositingCoordinatesTopDown) , m_parent(0) + , m_maskLayer(0) #ifndef NDEBUG , m_repaintCount(0) #endif diff --git a/WebCore/platform/graphics/GraphicsLayer.h b/WebCore/platform/graphics/GraphicsLayer.h index 4d7668a..d3e5fb1 100644 --- a/WebCore/platform/graphics/GraphicsLayer.h +++ b/WebCore/platform/graphics/GraphicsLayer.h @@ -38,6 +38,7 @@ #include "TransformationMatrix.h" #include "TransformOperations.h" #include <wtf/OwnPtr.h> +#include <wtf/PassOwnPtr.h> #if PLATFORM(MAC) #ifdef __OBJC__ @@ -152,7 +153,7 @@ protected: class GraphicsLayer { public: - static GraphicsLayer* createGraphicsLayer(GraphicsLayerClient*); + static PassOwnPtr<GraphicsLayer> create(GraphicsLayerClient*); virtual ~GraphicsLayer(); @@ -180,6 +181,9 @@ public: void removeAllChildren(); virtual void removeFromParent(); + GraphicsLayer* maskLayer() const { return m_maskLayer; } + virtual void setMaskLayer(GraphicsLayer* layer) { m_maskLayer = layer; } + // Offset is origin of the renderer minus origin of the graphics layer (so either zero or negative). IntSize offsetFromRenderer() const { return m_offsetFromRenderer; } void setOffsetFromRenderer(const IntSize& offset) { m_offsetFromRenderer = offset; } @@ -229,8 +233,8 @@ public: virtual void setOpacity(float opacity) { m_opacity = opacity; } // Some GraphicsLayers paint only the foreground or the background content - GraphicsLayerPaintingPhase drawingPhase() const { return m_paintingPhase; } - void setDrawingPhase(GraphicsLayerPaintingPhase phase) { m_paintingPhase = phase; } + GraphicsLayerPaintingPhase paintingPhase() const { return m_paintingPhase; } + void setPaintingPhase(GraphicsLayerPaintingPhase phase) { m_paintingPhase = phase; } virtual void setNeedsDisplay() = 0; // mark the given rect (in layer coords) as needing dispay. Never goes deep. @@ -347,6 +351,8 @@ protected: Vector<GraphicsLayer*> m_children; GraphicsLayer* m_parent; + GraphicsLayer* m_maskLayer; // Reference to mask layer. We don't own this. + IntRect m_contentsRect; #ifndef NDEBUG diff --git a/WebCore/platform/graphics/GraphicsLayerClient.h b/WebCore/platform/graphics/GraphicsLayerClient.h index 8c0b7ed..5facc94 100644 --- a/WebCore/platform/graphics/GraphicsLayerClient.h +++ b/WebCore/platform/graphics/GraphicsLayerClient.h @@ -37,9 +37,10 @@ class IntRect; class FloatPoint; enum GraphicsLayerPaintingPhase { - GraphicsLayerPaintBackgroundMask = (1 << 0), - GraphicsLayerPaintForegroundMask = (1 << 1), - GraphicsLayerPaintAllMask = (GraphicsLayerPaintBackgroundMask | GraphicsLayerPaintForegroundMask) + GraphicsLayerPaintBackground = (1 << 0), + GraphicsLayerPaintForeground = (1 << 1), + GraphicsLayerPaintMask = (1 << 2), + GraphicsLayerPaintAll = (GraphicsLayerPaintBackground | GraphicsLayerPaintForeground | GraphicsLayerPaintMask) }; enum AnimatedPropertyID { diff --git a/WebCore/platform/graphics/Icon.h b/WebCore/platform/graphics/Icon.h index 444c67c..8650130 100644 --- a/WebCore/platform/graphics/Icon.h +++ b/WebCore/platform/graphics/Icon.h @@ -78,6 +78,8 @@ private: #elif PLATFORM(CHROMIUM) Icon(const PlatformIcon&); PlatformIcon m_icon; +#elif PLATFORM(HAIKU) + Icon(); #endif }; diff --git a/WebCore/platform/graphics/ImageBuffer.h b/WebCore/platform/graphics/ImageBuffer.h index 2a96d3b..9432058 100644 --- a/WebCore/platform/graphics/ImageBuffer.h +++ b/WebCore/platform/graphics/ImageBuffer.h @@ -50,6 +50,11 @@ namespace WebCore { LinearRGB }; + enum Multiply { + Premultiplied, + Unmultiplied + }; + class ImageBuffer : public Noncopyable { public: // Will return a null pointer on allocation failure. @@ -71,8 +76,11 @@ namespace WebCore { void clearImage() { m_image.clear(); } - PassRefPtr<ImageData> getImageData(const IntRect& rect) const; - void putImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint); + PassRefPtr<ImageData> getUnmultipliedImageData(const IntRect&) const; + PassRefPtr<ImageData> getPremultipliedImageData(const IntRect&) const; + + void putUnmultipliedImageData(ImageData*, const IntRect& sourceRect, const IntPoint& destPoint); + void putPremultipliedImageData(ImageData*, const IntRect& sourceRect, const IntPoint& destPoint); String toDataURL(const String& mimeType) const; #if !PLATFORM(CG) diff --git a/WebCore/platform/graphics/cairo/ImageSourceCairo.cpp b/WebCore/platform/graphics/ImageSource.cpp index df62618..3bea57f 100644 --- a/WebCore/platform/graphics/cairo/ImageSourceCairo.cpp +++ b/WebCore/platform/graphics/ImageSource.cpp @@ -1,6 +1,8 @@ /* * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. * Copyright (C) 2007 Alp Toker <alp.toker@collabora.co.uk> + * Copyright (C) 2008, Google Inc. All rights reserved. + * Copyright (C) 2007-2009 Torch Mobile, Inc * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,16 +29,19 @@ #include "config.h" #include "ImageSource.h" -#if PLATFORM(CAIRO) - #include "BMPImageDecoder.h" #include "GIFImageDecoder.h" #include "ICOImageDecoder.h" #include "JPEGImageDecoder.h" #include "PNGImageDecoder.h" -#include "XBMImageDecoder.h" #include "SharedBuffer.h" -#include <cairo.h> +#include "XBMImageDecoder.h" + +#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) +#ifndef IMAGE_DECODER_DOWN_SAMPLING_MAX_NUMBER_OF_PIXELS +#define IMAGE_DECODER_DOWN_SAMPLING_MAX_NUMBER_OF_PIXELS (1024 * 1024) +#endif +#endif namespace WebCore { @@ -120,21 +125,21 @@ void ImageSource::setData(SharedBuffer* data, bool allDataReceived) // This method will examine the data and instantiate an instance of the appropriate decoder plugin. // If insufficient bytes are available to determine the image type, no decoder plugin will be // made. - if (!m_decoder) + if (!m_decoder) { m_decoder = createDecoder(data->buffer()); +#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) + if (m_decoder) + m_decoder->setMaxNumPixels(IMAGE_DECODER_DOWN_SAMPLING_MAX_NUMBER_OF_PIXELS); +#endif + } - if (!m_decoder) - return; - - m_decoder->setData(data, allDataReceived); + if (m_decoder) + m_decoder->setData(data, allDataReceived); } String ImageSource::filenameExtension() const { - if (!m_decoder) - return String(); - - return m_decoder->filenameExtension(); + return m_decoder ? m_decoder->filenameExtension() : String(); } bool ImageSource::isSizeAvailable() @@ -176,9 +181,6 @@ size_t ImageSource::frameCount() const NativeImagePtr ImageSource::createFrameAtIndex(size_t index) { - if (!initialized()) - return 0; - if (!m_decoder) return 0; @@ -186,11 +188,13 @@ NativeImagePtr ImageSource::createFrameAtIndex(size_t index) if (!buffer || buffer->status() == RGBA32Buffer::FrameEmpty) return 0; - // Cairo does not like zero height images. - // If we have a zero height image, just pretend we don't have enough data yet. - if (!size().height()) + // Zero-height images can cause problems for some ports. If we have an + // empty image dimension, just bail. + if (size().isEmpty()) return 0; + // Return the buffer contents as a native image. For some ports, the data + // is already in a native container, and this just increments its refcount. return buffer->asNewNativeImage(); } @@ -223,17 +227,14 @@ float ImageSource::frameDurationAtIndex(size_t index) bool ImageSource::frameHasAlphaAtIndex(size_t index) { - // When a frame has not finished decoding, always mark it as having alpha, - // so we don't get a black background for the undecoded sections. - // TODO: A better solution is probably to have the underlying buffer's - // hasAlpha() return true in these cases, since it is, in fact, technically - // true. - if (!frameIsCompleteAtIndex(index)) - return true; - - return m_decoder->frameBufferAtIndex(index)->hasAlpha(); + // When a frame has not finished decoding, always mark it as having alpha. + // Ports that check the result of this function to determine their + // compositing op need this in order to not draw the undecoded portion as + // black. + // TODO: Perhaps we should ensure that each individual decoder returns true + // in this case. + return frameIsCompleteAtIndex(index) ? + m_decoder->frameBufferAtIndex(index)->hasAlpha() : true; } } - -#endif // PLATFORM(CAIRO) diff --git a/WebCore/platform/graphics/ImageSource.h b/WebCore/platform/graphics/ImageSource.h index 173d50b..dee3eda 100644 --- a/WebCore/platform/graphics/ImageSource.h +++ b/WebCore/platform/graphics/ImageSource.h @@ -51,6 +51,8 @@ class SkBitmapRef; class PrivateAndroidImageSourceRec; #elif PLATFORM(SKIA) class NativeImageSkia; +#elif PLATFORM(HAIKU) +class BBitmap; #elif PLATFORM(WINCE) #include "SharedBitmap.h" #endif @@ -105,6 +107,10 @@ typedef cairo_surface_t* NativeImagePtr; class ImageDecoder; typedef ImageDecoder* NativeImageSourcePtr; typedef NativeImageSkia* NativeImagePtr; +#elif PLATFORM(HAIKU) +class ImageDecoder; +typedef ImageDecoder* NativeImageSourcePtr; +typedef BBitmap* NativeImagePtr; #elif PLATFORM(WINCE) class ImageDecoder; typedef ImageDecoder* NativeImageSourcePtr; diff --git a/WebCore/platform/graphics/IntPoint.h b/WebCore/platform/graphics/IntPoint.h index e6d4816..afbfb46 100644 --- a/WebCore/platform/graphics/IntPoint.h +++ b/WebCore/platform/graphics/IntPoint.h @@ -55,6 +55,8 @@ class QPoint; QT_END_NAMESPACE #elif PLATFORM(GTK) typedef struct _GdkPoint GdkPoint; +#elif PLATFORM(HAIKU) +class BPoint; #endif #if PLATFORM(WX) @@ -121,6 +123,9 @@ public: #elif PLATFORM(GTK) IntPoint(const GdkPoint&); operator GdkPoint() const; +#elif PLATFORM(HAIKU) + explicit IntPoint(const BPoint&); + operator BPoint() const; #endif #if PLATFORM(WX) diff --git a/WebCore/platform/graphics/IntRect.h b/WebCore/platform/graphics/IntRect.h index 0b607f5..c5a12cb 100644 --- a/WebCore/platform/graphics/IntRect.h +++ b/WebCore/platform/graphics/IntRect.h @@ -49,6 +49,8 @@ class QRect; QT_END_NAMESPACE #elif PLATFORM(GTK) typedef struct _GdkRectangle GdkRectangle; +#elif PLATFORM(HAIKU) +class BRect; #endif #if PLATFORM(WX) @@ -144,6 +146,9 @@ public: #elif PLATFORM(GTK) IntRect(const GdkRectangle&); operator GdkRectangle() const; +#elif PLATFORM(HAIKU) + explicit IntRect(const BRect&); + operator BRect() const; #endif #if PLATFORM(CG) diff --git a/WebCore/platform/graphics/IntSize.h b/WebCore/platform/graphics/IntSize.h index dc7a85d..e80b0fa 100644 --- a/WebCore/platform/graphics/IntSize.h +++ b/WebCore/platform/graphics/IntSize.h @@ -47,6 +47,8 @@ typedef struct tagSIZE SIZE; QT_BEGIN_NAMESPACE class QSize; QT_END_NAMESPACE +#elif PLATFORM(HAIKU) +class BSize; #endif namespace WebCore { @@ -113,6 +115,11 @@ public: operator QSize() const; #endif +#if PLATFORM(HAIKU) + explicit IntSize(const BSize&); + operator BSize() const; +#endif + private: int m_width, m_height; diff --git a/WebCore/platform/graphics/Path.h b/WebCore/platform/graphics/Path.h index da324bc..6b617a0 100644 --- a/WebCore/platform/graphics/Path.h +++ b/WebCore/platform/graphics/Path.h @@ -52,6 +52,9 @@ typedef WebCore::CairoPath PlatformPath; #elif PLATFORM(SKIA) class SkPath; typedef SkPath PlatformPath; +#elif PLATFORM(HAIKU) +class BRegion; +typedef BRegion PlatformPath; #elif PLATFORM(WINCE) namespace WebCore { class PlatformPath; diff --git a/WebCore/platform/graphics/Pattern.h b/WebCore/platform/graphics/Pattern.h index 02ad3ec..2f1192c 100644 --- a/WebCore/platform/graphics/Pattern.h +++ b/WebCore/platform/graphics/Pattern.h @@ -53,6 +53,9 @@ typedef wxGraphicsBrush* PlatformPatternPtr; class wxBrush; typedef wxBrush* PlatformPatternPtr; #endif // USE(WXGC) +#elif PLATFORM(HAIKU) +#include <interface/GraphicsDefs.h> +typedef pattern* PlatformPatternPtr; #elif PLATFORM(WINCE) typedef void* PlatformPatternPtr; #endif diff --git a/WebCore/platform/graphics/SimpleFontData.h b/WebCore/platform/graphics/SimpleFontData.h index cb472b0..8cb8268 100644 --- a/WebCore/platform/graphics/SimpleFontData.h +++ b/WebCore/platform/graphics/SimpleFontData.h @@ -45,6 +45,10 @@ typedef struct OpaqueATSUStyle* ATSUStyle; #include <QFont> #endif +#if PLATFORM(HAIKU) +#include <Font.h> +#endif + namespace WebCore { class FontDescription; diff --git a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp index 5765546..de8afb3 100644 --- a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp +++ b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp @@ -31,7 +31,6 @@ #if PLATFORM(CAIRO) -#include "TransformationMatrix.h" #include "CairoPath.h" #include "FloatRect.h" #include "Font.h" @@ -41,6 +40,7 @@ #include "Path.h" #include "Pattern.h" #include "SimpleFontData.h" +#include "TransformationMatrix.h" #include <cairo.h> #include <math.h> @@ -53,8 +53,8 @@ #elif PLATFORM(WIN) #include <cairo-win32.h> #endif -#include "GraphicsContextPrivate.h" #include "GraphicsContextPlatformPrivateCairo.h" +#include "GraphicsContextPrivate.h" #ifndef M_PI #define M_PI 3.14159265358979323846 @@ -142,38 +142,6 @@ void GraphicsContext::drawRect(const IntRect& rect) cairo_restore(cr); } -// FIXME: Now that this is refactored, it should be shared by all contexts. -static void adjustLineToPixelBoundaries(FloatPoint& p1, FloatPoint& p2, float strokeWidth, StrokeStyle style) -{ - // For odd widths, we add in 0.5 to the appropriate x/y so that the float arithmetic - // works out. For example, with a border width of 3, KHTML will pass us (y1+y2)/2, e.g., - // (50+53)/2 = 103/2 = 51 when we want 51.5. It is always true that an even width gave - // us a perfect position, but an odd width gave us a position that is off by exactly 0.5. - if (style == DottedStroke || style == DashedStroke) { - if (p1.x() == p2.x()) { - p1.setY(p1.y() + strokeWidth); - p2.setY(p2.y() - strokeWidth); - } - else { - p1.setX(p1.x() + strokeWidth); - p2.setX(p2.x() - strokeWidth); - } - } - - if (static_cast<int>(strokeWidth) % 2) { - if (p1.x() == p2.x()) { - // We're a vertical line. Adjust our x. - p1.setX(p1.x() + 0.5); - p2.setX(p2.x() + 0.5); - } - else { - // We're a horizontal line. Adjust our y. - p1.setY(p1.y() + 0.5); - p2.setY(p2.y() + 0.5); - } - } -} - // This is only used to draw borders. void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2) { @@ -239,20 +207,18 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2) if (patWidth == 1) patternOffset = 1.0; else { - bool evenNumberOfSegments = numSegments%2 == 0; + bool evenNumberOfSegments = !(numSegments % 2); if (remainder) evenNumberOfSegments = !evenNumberOfSegments; if (evenNumberOfSegments) { if (remainder) { patternOffset += patWidth - remainder; - patternOffset += remainder/2; - } - else - patternOffset = patWidth/2; - } - else if (!evenNumberOfSegments) { + patternOffset += remainder / 2; + } else + patternOffset = patWidth / 2; + } else if (!evenNumberOfSegments) { if (remainder) - patternOffset = (patWidth - remainder)/2; + patternOffset = (patWidth - remainder) / 2; } } @@ -318,7 +284,7 @@ void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSp if (w != h) cairo_scale(cr, 1., scaleFactor); - + cairo_arc_negative(cr, x + hRadius, (y + vRadius) * reverseScaleFactor, hRadius, -fa * M_PI/180, -falen * M_PI/180); if (w != h) @@ -326,16 +292,16 @@ void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSp float width = strokeThickness(); int patWidth = 0; - + switch (strokeStyle()) { - case DottedStroke: - patWidth = static_cast<int>(width / 2); - break; - case DashedStroke: - patWidth = 3 * static_cast<int>(width / 2); - break; - default: - break; + case DottedStroke: + patWidth = static_cast<int>(width / 2); + break; + case DashedStroke: + patWidth = 3 * static_cast<int>(width / 2); + break; + default: + break; } setColor(cr, strokeColor()); @@ -349,7 +315,7 @@ void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSp distance = static_cast<int>((M_PI * hRadius) / 2.0); else // We are elliptical and will have to estimate the distance distance = static_cast<int>((M_PI * sqrtf((hRadius * hRadius + vRadius * vRadius) / 2.0)) / 2.0); - + int remainder = distance % patWidth; int coverage = distance - remainder; int numSegments = coverage / patWidth; @@ -359,7 +325,7 @@ void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSp if (patWidth == 1) patternOffset = 1.0; else { - bool evenNumberOfSegments = numSegments % 2 == 0; + bool evenNumberOfSegments = !(numSegments % 2); if (remainder) evenNumberOfSegments = !evenNumberOfSegments; if (evenNumberOfSegments) { @@ -828,15 +794,15 @@ void GraphicsContext::setLineCap(LineCap lineCap) cairo_line_cap_t cairoCap = CAIRO_LINE_CAP_BUTT; switch (lineCap) { - case ButtCap: - // no-op - break; - case RoundCap: - cairoCap = CAIRO_LINE_CAP_ROUND; - break; - case SquareCap: - cairoCap = CAIRO_LINE_CAP_SQUARE; - break; + case ButtCap: + // no-op + break; + case RoundCap: + cairoCap = CAIRO_LINE_CAP_ROUND; + break; + case SquareCap: + cairoCap = CAIRO_LINE_CAP_SQUARE; + break; } cairo_set_line_cap(m_data->cr, cairoCap); } @@ -853,15 +819,15 @@ void GraphicsContext::setLineJoin(LineJoin lineJoin) cairo_line_join_t cairoJoin = CAIRO_LINE_JOIN_MITER; switch (lineJoin) { - case MiterJoin: - // no-op - break; - case RoundJoin: - cairoJoin = CAIRO_LINE_JOIN_ROUND; - break; - case BevelJoin: - cairoJoin = CAIRO_LINE_JOIN_BEVEL; - break; + case MiterJoin: + // no-op + break; + case RoundJoin: + cairoJoin = CAIRO_LINE_JOIN_ROUND; + break; + case BevelJoin: + cairoJoin = CAIRO_LINE_JOIN_BEVEL; + break; } cairo_set_line_join(m_data->cr, cairoJoin); } @@ -887,37 +853,37 @@ float GraphicsContext::getAlpha() static inline cairo_operator_t toCairoOperator(CompositeOperator op) { switch (op) { - case CompositeClear: - return CAIRO_OPERATOR_CLEAR; - case CompositeCopy: - return CAIRO_OPERATOR_SOURCE; - case CompositeSourceOver: - return CAIRO_OPERATOR_OVER; - case CompositeSourceIn: - return CAIRO_OPERATOR_IN; - case CompositeSourceOut: - return CAIRO_OPERATOR_OUT; - case CompositeSourceAtop: - return CAIRO_OPERATOR_ATOP; - case CompositeDestinationOver: - return CAIRO_OPERATOR_DEST_OVER; - case CompositeDestinationIn: - return CAIRO_OPERATOR_DEST_IN; - case CompositeDestinationOut: - return CAIRO_OPERATOR_DEST_OUT; - case CompositeDestinationAtop: - return CAIRO_OPERATOR_DEST_ATOP; - case CompositeXOR: - return CAIRO_OPERATOR_XOR; - case CompositePlusDarker: - return CAIRO_OPERATOR_SATURATE; - case CompositeHighlight: - // There is no Cairo equivalent for CompositeHighlight. - return CAIRO_OPERATOR_OVER; - case CompositePlusLighter: - return CAIRO_OPERATOR_ADD; - default: - return CAIRO_OPERATOR_SOURCE; + case CompositeClear: + return CAIRO_OPERATOR_CLEAR; + case CompositeCopy: + return CAIRO_OPERATOR_SOURCE; + case CompositeSourceOver: + return CAIRO_OPERATOR_OVER; + case CompositeSourceIn: + return CAIRO_OPERATOR_IN; + case CompositeSourceOut: + return CAIRO_OPERATOR_OUT; + case CompositeSourceAtop: + return CAIRO_OPERATOR_ATOP; + case CompositeDestinationOver: + return CAIRO_OPERATOR_DEST_OVER; + case CompositeDestinationIn: + return CAIRO_OPERATOR_DEST_IN; + case CompositeDestinationOut: + return CAIRO_OPERATOR_DEST_OUT; + case CompositeDestinationAtop: + return CAIRO_OPERATOR_DEST_ATOP; + case CompositeXOR: + return CAIRO_OPERATOR_XOR; + case CompositePlusDarker: + return CAIRO_OPERATOR_SATURATE; + case CompositeHighlight: + // There is no Cairo equivalent for CompositeHighlight. + return CAIRO_OPERATOR_OVER; + case CompositePlusLighter: + return CAIRO_OPERATOR_ADD; + default: + return CAIRO_OPERATOR_SOURCE; } } diff --git a/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp b/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp index c905ee8..0213944 100644 --- a/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp +++ b/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp @@ -138,16 +138,17 @@ void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookUpTable) } } -PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const +template <Multiply multiplied> +PassRefPtr<ImageData> getImageData(const IntRect& rect, const ImageBufferData& data, const IntSize& size) { - ASSERT(cairo_surface_get_type(m_data.m_surface) == CAIRO_SURFACE_TYPE_IMAGE); + ASSERT(cairo_surface_get_type(data.m_surface) == CAIRO_SURFACE_TYPE_IMAGE); PassRefPtr<ImageData> result = ImageData::create(rect.width(), rect.height()); - unsigned char* dataSrc = cairo_image_surface_get_data(m_data.m_surface); + unsigned char* dataSrc = cairo_image_surface_get_data(data.m_surface); unsigned char* dataDst = result->data()->data()->data(); - if (rect.x() < 0 || rect.y() < 0 || (rect.x() + rect.width()) > m_size.width() || (rect.y() + rect.height()) > m_size.height()) - memset(dataSrc, 0, result->data()->length()); + if (rect.x() < 0 || rect.y() < 0 || (rect.x() + rect.width()) > size.width() || (rect.y() + rect.height()) > size.height()) + memset(dataDst, 0, result->data()->length()); int originx = rect.x(); int destx = 0; @@ -156,8 +157,8 @@ PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const originx = 0; } int endx = rect.x() + rect.width(); - if (endx > m_size.width()) - endx = m_size.width(); + if (endx > size.width()) + endx = size.width(); int numColumns = endx - originx; int originy = rect.y(); @@ -167,11 +168,11 @@ PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const originy = 0; } int endy = rect.y() + rect.height(); - if (endy > m_size.height()) - endy = m_size.height(); + if (endy > size.height()) + endy = size.height(); int numRows = endy - originy; - int stride = cairo_image_surface_get_stride(m_data.m_surface); + int stride = cairo_image_surface_get_stride(data.m_surface); unsigned destBytesPerRow = 4 * rect.width(); unsigned char* destRows = dataDst + desty * destBytesPerRow + destx * 4; @@ -180,7 +181,11 @@ PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const for (int x = 0; x < numColumns; x++) { int basex = x * 4; unsigned* pixel = row + x + originx; - Color pixelColor = colorFromPremultipliedARGB(*pixel); + Color pixelColor; + if (multiplied == Unmultiplied) + pixelColor = colorFromPremultipliedARGB(*pixel); + else + pixelColor = Color(*pixel); destRows[basex] = pixelColor.red(); destRows[basex + 1] = pixelColor.green(); destRows[basex + 2] = pixelColor.blue(); @@ -192,11 +197,22 @@ PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const return result; } -void ImageBuffer::putImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint) +PassRefPtr<ImageData> ImageBuffer::getUnmultipliedImageData(const IntRect& rect) const { - ASSERT(cairo_surface_get_type(m_data.m_surface) == CAIRO_SURFACE_TYPE_IMAGE); + return getImageData<Unmultiplied>(rect, m_data, m_size); +} - unsigned char* dataDst = cairo_image_surface_get_data(m_data.m_surface); +PassRefPtr<ImageData> ImageBuffer::getPremultipliedImageData(const IntRect& rect) const +{ + return getImageData<Premultiplied>(rect, m_data, m_size); +} + +template <Multiply multiplied> +void putImageData(ImageData*& source, const IntRect& sourceRect, const IntPoint& destPoint, ImageBufferData& data, const IntSize& size) +{ + ASSERT(cairo_surface_get_type(data.m_surface) == CAIRO_SURFACE_TYPE_IMAGE); + + unsigned char* dataDst = cairo_image_surface_get_data(data.m_surface); ASSERT(sourceRect.width() > 0); ASSERT(sourceRect.height() > 0); @@ -204,28 +220,28 @@ void ImageBuffer::putImageData(ImageData* source, const IntRect& sourceRect, con int originx = sourceRect.x(); int destx = destPoint.x() + sourceRect.x(); ASSERT(destx >= 0); - ASSERT(destx < m_size.width()); + ASSERT(destx < size.width()); ASSERT(originx >= 0); ASSERT(originx <= sourceRect.right()); int endx = destPoint.x() + sourceRect.right(); - ASSERT(endx <= m_size.width()); + ASSERT(endx <= size.width()); int numColumns = endx - destx; int originy = sourceRect.y(); int desty = destPoint.y() + sourceRect.y(); ASSERT(desty >= 0); - ASSERT(desty < m_size.height()); + ASSERT(desty < size.height()); ASSERT(originy >= 0); ASSERT(originy <= sourceRect.bottom()); int endy = destPoint.y() + sourceRect.bottom(); - ASSERT(endy <= m_size.height()); + ASSERT(endy <= size.height()); int numRows = endy - desty; unsigned srcBytesPerRow = 4 * source->width(); - int stride = cairo_image_surface_get_stride(m_data.m_surface); + int stride = cairo_image_surface_get_stride(data.m_surface); unsigned char* srcRows = source->data()->data()->data() + originy * srcBytesPerRow + originx * 4; for (int y = 0; y < numRows; ++y) { @@ -237,12 +253,25 @@ void ImageBuffer::putImageData(ImageData* source, const IntRect& sourceRect, con srcRows[basex + 1], srcRows[basex + 2], srcRows[basex + 3]); - *pixel = premultipliedARGBFromColor(pixelColor); + if (multiplied == Unmultiplied) + *pixel = premultipliedARGBFromColor(pixelColor); + else + *pixel = pixelColor.rgb(); } srcRows += srcBytesPerRow; } } +void ImageBuffer::putUnmultipliedImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint) +{ + putImageData<Unmultiplied>(source, sourceRect, destPoint, m_data, m_size); +} + +void ImageBuffer::putPremultipliedImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint) +{ + putImageData<Premultiplied>(source, sourceRect, destPoint, m_data, m_size); +} + static cairo_status_t writeFunction(void* closure, const unsigned char* data, unsigned int length) { Vector<char>* in = reinterpret_cast<Vector<char>*>(closure); diff --git a/WebCore/platform/graphics/cg/GraphicsContextCG.cpp b/WebCore/platform/graphics/cg/GraphicsContextCG.cpp index ab8eb3c..f1e6a1f 100644 --- a/WebCore/platform/graphics/cg/GraphicsContextCG.cpp +++ b/WebCore/platform/graphics/cg/GraphicsContextCG.cpp @@ -28,14 +28,15 @@ #include "config.h" #include "GraphicsContext.h" -#include "TransformationMatrix.h" #include "FloatConversion.h" -#include "GraphicsContextPrivate.h" #include "GraphicsContextPlatformPrivateCG.h" +#include "GraphicsContextPrivate.h" #include "ImageBuffer.h" #include "KURL.h" #include "Path.h" #include "Pattern.h" +#include "TransformationMatrix.h" + #include <CoreGraphics/CGBitmapContext.h> #include <CoreGraphics/CGPDFContext.h> #include <wtf/MathExtras.h> @@ -178,19 +179,19 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2) int patWidth = 0; switch (strokeStyle()) { - case NoStroke: - case SolidStroke: - break; - case DottedStroke: - patWidth = (int)width; - break; - case DashedStroke: - patWidth = 3 * (int)width; - break; + case NoStroke: + case SolidStroke: + break; + case DottedStroke: + patWidth = (int)width; + break; + case DashedStroke: + patWidth = 3 * (int)width; + break; } CGContextRef context = platformContext(); - + if (shouldAntialias()) CGContextSetShouldAntialias(context, false); @@ -221,7 +222,7 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2) if (patWidth == 1) patternOffset = 1.0f; else { - bool evenNumberOfSegments = numSegments % 2 == 0; + bool evenNumberOfSegments = !(numSegments % 2); if (remainder) evenNumberOfSegments = !evenNumberOfSegments; if (evenNumberOfSegments) { @@ -235,7 +236,7 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2) patternOffset = (patWidth - remainder)/2; } } - + const CGFloat dottedLine[2] = { patWidth, patWidth }; CGContextSetLineDash(context, patternOffset, dottedLine, 2); } @@ -248,7 +249,7 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2) if (patWidth) CGContextRestoreGState(context); - + if (shouldAntialias()) CGContextSetShouldAntialias(context, true); } @@ -263,7 +264,7 @@ void GraphicsContext::drawEllipse(const IntRect& rect) if (paintingDisabled()) return; - + CGContextRef context = platformContext(); CGContextBeginPath(context); float r = (float)rect.width() / 2; @@ -275,25 +276,25 @@ void GraphicsContext::drawEllipse(const IntRect& rect) void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSpan) -{ +{ if (paintingDisabled() || strokeStyle() == NoStroke || strokeThickness() <= 0.0f) return; - + CGContextRef context = platformContext(); CGContextSaveGState(context); CGContextBeginPath(context); CGContextSetShouldAntialias(context, false); - + int x = rect.x(); int y = rect.y(); float w = (float)rect.width(); float h = (float)rect.height(); float scaleFactor = h / w; float reverseScaleFactor = w / h; - + if (w != h) scale(FloatSize(1, scaleFactor)); - + float hRadius = w / 2; float vRadius = h / 2; float fa = startAngle; @@ -304,22 +305,21 @@ void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSp if (w != h) scale(FloatSize(1, reverseScaleFactor)); - - + float width = strokeThickness(); int patWidth = 0; - + switch (strokeStyle()) { - case DottedStroke: - patWidth = (int)(width / 2); - break; - case DashedStroke: - patWidth = 3 * (int)(width / 2); - break; - default: - break; + case DottedStroke: + patWidth = (int)(width / 2); + break; + case DashedStroke: + patWidth = 3 * (int)(width / 2); + break; + default: + break; } - + if (patWidth) { // Example: 80 pixels with a width of 30 pixels. // Remainder is 20. The maximum pixels of line we could paint @@ -329,7 +329,7 @@ void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSp distance = static_cast<int>((piFloat * hRadius) / 2.0f); else // We are elliptical and will have to estimate the distance distance = static_cast<int>((piFloat * sqrtf((hRadius * hRadius + vRadius * vRadius) / 2.0f)) / 2.0f); - + int remainder = distance % patWidth; int coverage = distance - remainder; int numSegments = coverage / patWidth; @@ -339,7 +339,7 @@ void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSp if (patWidth == 1) patternOffset = 1.0f; else { - bool evenNumberOfSegments = numSegments % 2 == 0; + bool evenNumberOfSegments = !(numSegments % 2); if (remainder) evenNumberOfSegments = !evenNumberOfSegments; if (evenNumberOfSegments) { @@ -353,13 +353,13 @@ void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSp patternOffset = (patWidth - remainder) / 2.0f; } } - + const CGFloat dottedLine[2] = { patWidth, patWidth }; CGContextSetLineDash(context, patternOffset, dottedLine, 2); } CGContextStrokePath(context); - + CGContextRestoreGState(context); } @@ -375,7 +375,7 @@ void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points if (antialiased != shouldAntialias()) CGContextSetShouldAntialias(context, antialiased); - + CGContextBeginPath(context); CGContextMoveToPoint(context, points[0].x(), points[0].y()); for (size_t i = 1; i < npoints; i++) @@ -383,7 +383,7 @@ void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points CGContextClosePath(context); drawPath(); - + if (antialiased != shouldAntialias()) CGContextSetShouldAntialias(context, shouldAntialias()); } @@ -391,7 +391,7 @@ void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points void GraphicsContext::applyStrokePattern() { CGContextRef cgContext = platformContext(); - + CGPatternRef platformPattern = m_common->state.strokePattern.get()->createPlatformPattern(getCTM()); if (!platformPattern) return; @@ -463,7 +463,7 @@ void GraphicsContext::drawPath() strokePath(); return; } - + if (state.fillColorSpace == PatternColorSpace) applyFillPattern(); if (state.strokeColorSpace == PatternColorSpace) @@ -599,7 +599,7 @@ void GraphicsContext::clipOut(const IntRect& rect) { if (paintingDisabled()) return; - + CGRect rects[2] = { CGContextGetClipBoundingBox(platformContext()), rect }; CGContextBeginPath(platformContext()); CGContextAddRects(platformContext(), rects, 2); @@ -610,7 +610,7 @@ void GraphicsContext::clipOutEllipseInRect(const IntRect& rect) { if (paintingDisabled()) return; - + CGContextBeginPath(platformContext()); CGContextAddRect(platformContext(), CGContextGetClipBoundingBox(platformContext())); CGContextAddEllipseInRect(platformContext(), rect); @@ -639,13 +639,13 @@ void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness clip(rect); CGContextRef context = platformContext(); - + // Add outer ellipse CGContextAddEllipseInRect(context, CGRectMake(rect.x(), rect.y(), rect.width(), rect.height())); // Add inner ellipse. CGContextAddEllipseInRect(context, CGRectMake(rect.x() + thickness, rect.y() + thickness, rect.width() - (thickness * 2), rect.height() - (thickness * 2))); - + CGContextEOClip(context); } @@ -653,7 +653,7 @@ void GraphicsContext::clipToImageBuffer(const FloatRect& rect, const ImageBuffer { if (paintingDisabled()) return; - + CGContextTranslateCTM(platformContext(), rect.x(), rect.y() + rect.height()); CGContextScaleCTM(platformContext(), 1, -1); CGContextClipToMask(platformContext(), FloatRect(FloatPoint(), rect.size()), imageBuffer->image()->getCGImageRef()); @@ -734,7 +734,7 @@ void GraphicsContext::setPlatformShadow(const IntSize& size, int blur, const Col CGColorRef colorCG = createCGColor(color); CGContextSetShadowWithColor(context, CGSizeMake(width, height), - blurRadius, + blurRadius, colorCG); CGColorRelease(colorCG); } @@ -799,15 +799,15 @@ void GraphicsContext::setLineCap(LineCap cap) if (paintingDisabled()) return; switch (cap) { - case ButtCap: - CGContextSetLineCap(platformContext(), kCGLineCapButt); - break; - case RoundCap: - CGContextSetLineCap(platformContext(), kCGLineCapRound); - break; - case SquareCap: - CGContextSetLineCap(platformContext(), kCGLineCapSquare); - break; + case ButtCap: + CGContextSetLineCap(platformContext(), kCGLineCapButt); + break; + case RoundCap: + CGContextSetLineCap(platformContext(), kCGLineCapRound); + break; + case SquareCap: + CGContextSetLineCap(platformContext(), kCGLineCapSquare); + break; } } @@ -821,15 +821,15 @@ void GraphicsContext::setLineJoin(LineJoin join) if (paintingDisabled()) return; switch (join) { - case MiterJoin: - CGContextSetLineJoin(platformContext(), kCGLineJoinMiter); - break; - case RoundJoin: - CGContextSetLineJoin(platformContext(), kCGLineJoinRound); - break; - case BevelJoin: - CGContextSetLineJoin(platformContext(), kCGLineJoinBevel); - break; + case MiterJoin: + CGContextSetLineJoin(platformContext(), kCGLineJoinMiter); + break; + case RoundJoin: + CGContextSetLineJoin(platformContext(), kCGLineJoinRound); + break; + case BevelJoin: + CGContextSetLineJoin(platformContext(), kCGLineJoinBevel); + break; } } @@ -858,7 +858,7 @@ void GraphicsContext::clipOut(const Path& path) { if (paintingDisabled()) return; - + CGContextBeginPath(platformContext()); CGContextAddRect(platformContext(), CGContextGetClipBoundingBox(platformContext())); CGContextAddPath(platformContext(), path.platformPath()); @@ -909,9 +909,9 @@ TransformationMatrix GraphicsContext::getCTM() const FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect) { - // It is not enough just to round to pixels in device space. The rotation part of the + // It is not enough just to round to pixels in device space. The rotation part of the // affine transform matrix to device space can mess with this conversion if we have a - // rotating image like the hands of the world clock widget. We just need the scale, so + // rotating image like the hands of the world clock widget. We just need the scale, so // we get the affine transform matrix and extract the scale. if (m_data->m_userToDeviceTransformKnownToBeIdentity) @@ -934,11 +934,11 @@ FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect) deviceOrigin.y = roundf(deviceOrigin.y); deviceLowerRight.x = roundf(deviceLowerRight.x); deviceLowerRight.y = roundf(deviceLowerRight.y); - + // Don't let the height or width round to 0 unless either was originally 0 - if (deviceOrigin.y == deviceLowerRight.y && rect.height() != 0) + if (deviceOrigin.y == deviceLowerRight.y && rect.height()) deviceLowerRight.y += 1; - if (deviceOrigin.x == deviceLowerRight.x && rect.width() != 0) + if (deviceOrigin.x == deviceLowerRight.x && rect.width()) deviceLowerRight.x += 1; FloatPoint roundedOrigin = FloatPoint(deviceOrigin.x / deviceScaleX, deviceOrigin.y / deviceScaleY); @@ -984,13 +984,13 @@ void GraphicsContext::drawLineForText(const IntPoint& point, int width, bool pri } } } - + if (fillColor() != strokeColor()) setCGFillColor(platformContext(), strokeColor()); CGContextFillRect(platformContext(), CGRectMake(x, y, lineLength, thickness)); if (fillColor() != strokeColor()) setCGFillColor(platformContext(), fillColor()); - + if (restoreAntialiasMode) CGContextSetShouldAntialias(platformContext(), true); } @@ -999,11 +999,11 @@ void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect) { if (paintingDisabled()) return; - + CFURLRef urlRef = link.createCFURL(); if (urlRef) { CGContextRef context = platformContext(); - + // Get the bounding box to handle clipping. CGRect box = CGContextGetClipBoundingBox(context); @@ -1022,28 +1022,28 @@ void GraphicsContext::setImageInterpolationQuality(InterpolationQuality mode) { if (paintingDisabled()) return; - + CGInterpolationQuality quality = kCGInterpolationDefault; switch (mode) { - case InterpolationDefault: - quality = kCGInterpolationDefault; - break; - case InterpolationNone: - quality = kCGInterpolationNone; - break; - case InterpolationLow: - quality = kCGInterpolationLow; - break; - - // Fall through to InterpolationHigh if kCGInterpolationMedium is not available - case InterpolationMedium: + case InterpolationDefault: + quality = kCGInterpolationDefault; + break; + case InterpolationNone: + quality = kCGInterpolationNone; + break; + case InterpolationLow: + quality = kCGInterpolationLow; + break; + + // Fall through to InterpolationHigh if kCGInterpolationMedium is not available + case InterpolationMedium: #if HAVE(CG_INTERPOLATION_MEDIUM) - quality = kCGInterpolationMedium; - break; + quality = kCGInterpolationMedium; + break; #endif - case InterpolationHigh: - quality = kCGInterpolationHigh; - break; + case InterpolationHigh: + quality = kCGInterpolationHigh; + break; } CGContextSetInterpolationQuality(platformContext(), quality); } @@ -1055,18 +1055,18 @@ InterpolationQuality GraphicsContext::imageInterpolationQuality() const CGInterpolationQuality quality = CGContextGetInterpolationQuality(platformContext()); switch (quality) { - case kCGInterpolationDefault: - return InterpolationDefault; - case kCGInterpolationNone: - return InterpolationNone; - case kCGInterpolationLow: - return InterpolationLow; + case kCGInterpolationDefault: + return InterpolationDefault; + case kCGInterpolationNone: + return InterpolationNone; + case kCGInterpolationLow: + return InterpolationLow; #if HAVE(CG_INTERPOLATION_MEDIUM) - case kCGInterpolationMedium: - return InterpolationMedium; + case kCGInterpolationMedium: + return InterpolationMedium; #endif - case kCGInterpolationHigh: - return InterpolationHigh; + case kCGInterpolationHigh: + return InterpolationHigh; } return InterpolationDefault; } @@ -1079,32 +1079,32 @@ void GraphicsContext::setPlatformTextDrawingMode(int mode) // Wow, wish CG had used bits here. CGContextRef context = platformContext(); switch (mode) { - case cTextInvisible: // Invisible - CGContextSetTextDrawingMode(context, kCGTextInvisible); - break; - case cTextFill: // Fill - CGContextSetTextDrawingMode(context, kCGTextFill); - break; - case cTextStroke: // Stroke - CGContextSetTextDrawingMode(context, kCGTextStroke); - break; - case 3: // Fill | Stroke - CGContextSetTextDrawingMode(context, kCGTextFillStroke); - break; - case cTextClip: // Clip - CGContextSetTextDrawingMode(context, kCGTextClip); - break; - case 5: // Fill | Clip - CGContextSetTextDrawingMode(context, kCGTextFillClip); - break; - case 6: // Stroke | Clip - CGContextSetTextDrawingMode(context, kCGTextStrokeClip); - break; - case 7: // Fill | Stroke | Clip - CGContextSetTextDrawingMode(context, kCGTextFillStrokeClip); - break; - default: - break; + case cTextInvisible: // Invisible + CGContextSetTextDrawingMode(context, kCGTextInvisible); + break; + case cTextFill: // Fill + CGContextSetTextDrawingMode(context, kCGTextFill); + break; + case cTextStroke: // Stroke + CGContextSetTextDrawingMode(context, kCGTextStroke); + break; + case 3: // Fill | Stroke + CGContextSetTextDrawingMode(context, kCGTextFillStroke); + break; + case cTextClip: // Clip + CGContextSetTextDrawingMode(context, kCGTextClip); + break; + case 5: // Fill | Clip + CGContextSetTextDrawingMode(context, kCGTextFillClip); + break; + case 6: // Stroke | Clip + CGContextSetTextDrawingMode(context, kCGTextStrokeClip); + break; + case 7: // Fill | Stroke | Clip + CGContextSetTextDrawingMode(context, kCGTextFillStrokeClip); + break; + default: + break; } } @@ -1138,54 +1138,54 @@ void GraphicsContext::setPlatformShouldAntialias(bool enable) #ifndef BUILDING_ON_TIGER // Tiger's setCompositeOperation() is defined in GraphicsContextMac.mm. void GraphicsContext::setCompositeOperation(CompositeOperator mode) -{ +{ if (paintingDisabled()) return; - CGBlendMode target = kCGBlendModeNormal; + CGBlendMode target = kCGBlendModeNormal; switch (mode) { - case CompositeClear: - target = kCGBlendModeClear; - break; - case CompositeCopy: - target = kCGBlendModeCopy; - break; - case CompositeSourceOver: - //kCGBlendModeNormal - break; - case CompositeSourceIn: - target = kCGBlendModeSourceIn; - break; - case CompositeSourceOut: - target = kCGBlendModeSourceOut; - break; - case CompositeSourceAtop: - target = kCGBlendModeSourceAtop; - break; - case CompositeDestinationOver: - target = kCGBlendModeDestinationOver; - break; - case CompositeDestinationIn: - target = kCGBlendModeDestinationIn; - break; - case CompositeDestinationOut: - target = kCGBlendModeDestinationOut; - break; - case CompositeDestinationAtop: - target = kCGBlendModeDestinationAtop; - break; - case CompositeXOR: - target = kCGBlendModeXOR; - break; - case CompositePlusDarker: - target = kCGBlendModePlusDarker; - break; - case CompositeHighlight: - // currently unsupported - break; - case CompositePlusLighter: - target = kCGBlendModePlusLighter; - break; + case CompositeClear: + target = kCGBlendModeClear; + break; + case CompositeCopy: + target = kCGBlendModeCopy; + break; + case CompositeSourceOver: + //kCGBlendModeNormal + break; + case CompositeSourceIn: + target = kCGBlendModeSourceIn; + break; + case CompositeSourceOut: + target = kCGBlendModeSourceOut; + break; + case CompositeSourceAtop: + target = kCGBlendModeSourceAtop; + break; + case CompositeDestinationOver: + target = kCGBlendModeDestinationOver; + break; + case CompositeDestinationIn: + target = kCGBlendModeDestinationIn; + break; + case CompositeDestinationOut: + target = kCGBlendModeDestinationOut; + break; + case CompositeDestinationAtop: + target = kCGBlendModeDestinationAtop; + break; + case CompositeXOR: + target = kCGBlendModeXOR; + break; + case CompositePlusDarker: + target = kCGBlendModePlusDarker; + break; + case CompositeHighlight: + // currently unsupported + break; + case CompositePlusLighter: + target = kCGBlendModePlusLighter; + break; } CGContextSetBlendMode(platformContext(), target); } diff --git a/WebCore/platform/graphics/cg/ImageBufferCG.cpp b/WebCore/platform/graphics/cg/ImageBufferCG.cpp index 6db7e88..97bcba5 100644 --- a/WebCore/platform/graphics/cg/ImageBufferCG.cpp +++ b/WebCore/platform/graphics/cg/ImageBufferCG.cpp @@ -65,7 +65,9 @@ ImageBuffer::ImageBuffer(const IntSize& size, ImageColorSpace imageColorSpace, b bytesPerRow *= 4; } - m_data.m_data = tryFastCalloc(size.height(), bytesPerRow); + if (!tryFastCalloc(size.height(), bytesPerRow).getValue(m_data.m_data)) + return; + ASSERT((reinterpret_cast<size_t>(m_data.m_data) & 2) == 0); CGColorSpaceRef colorSpace; @@ -122,12 +124,13 @@ Image* ImageBuffer::image() const return m_image.get(); } -PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const +template <Multiply multiplied> +PassRefPtr<ImageData> getImageData(const IntRect& rect, const ImageBufferData& imageData, const IntSize& size) { PassRefPtr<ImageData> result = ImageData::create(rect.width(), rect.height()); unsigned char* data = result->data()->data()->data(); - if (rect.x() < 0 || rect.y() < 0 || (rect.x() + rect.width()) > m_size.width() || (rect.y() + rect.height()) > m_size.height()) + if (rect.x() < 0 || rect.y() < 0 || (rect.x() + rect.width()) > size.width() || (rect.y() + rect.height()) > size.height()) memset(data, 0, result->data()->length()); int originx = rect.x(); @@ -137,8 +140,8 @@ PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const originx = 0; } int endx = rect.x() + rect.width(); - if (endx > m_size.width()) - endx = m_size.width(); + if (endx > size.width()) + endx = size.width(); int numColumns = endx - originx; int originy = rect.y(); @@ -148,20 +151,21 @@ PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const originy = 0; } int endy = rect.y() + rect.height(); - if (endy > m_size.height()) - endy = m_size.height(); + if (endy > size.height()) + endy = size.height(); int numRows = endy - originy; - unsigned srcBytesPerRow = 4 * m_size.width(); + unsigned srcBytesPerRow = 4 * size.width(); unsigned destBytesPerRow = 4 * rect.width(); // ::create ensures that all ImageBuffers have valid data, so we don't need to check it here. - unsigned char* srcRows = reinterpret_cast<unsigned char*>(m_data.m_data) + originy * srcBytesPerRow + originx * 4; + unsigned char* srcRows = reinterpret_cast<unsigned char*>(imageData.m_data) + originy * srcBytesPerRow + originx * 4; unsigned char* destRows = data + desty * destBytesPerRow + destx * 4; for (int y = 0; y < numRows; ++y) { for (int x = 0; x < numColumns; x++) { int basex = x * 4; - if (unsigned char alpha = srcRows[basex + 3]) { + unsigned char alpha = srcRows[basex + 3]; + if (multiplied == Unmultiplied && alpha) { destRows[basex] = (srcRows[basex] * 255) / alpha; destRows[basex + 1] = (srcRows[basex + 1] * 255) / alpha; destRows[basex + 2] = (srcRows[basex + 2] * 255) / alpha; @@ -175,7 +179,18 @@ PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const return result; } -void ImageBuffer::putImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint) +PassRefPtr<ImageData> ImageBuffer::getUnmultipliedImageData(const IntRect& rect) const +{ + return getImageData<Unmultiplied>(rect, m_data, m_size); +} + +PassRefPtr<ImageData> ImageBuffer::getPremultipliedImageData(const IntRect& rect) const +{ + return getImageData<Premultiplied>(rect, m_data, m_size); +} + +template <Multiply multiplied> +void putImageData(ImageData*& source, const IntRect& sourceRect, const IntPoint& destPoint, ImageBufferData& imageData, const IntSize& size) { ASSERT(sourceRect.width() > 0); ASSERT(sourceRect.height() > 0); @@ -183,36 +198,36 @@ void ImageBuffer::putImageData(ImageData* source, const IntRect& sourceRect, con int originx = sourceRect.x(); int destx = destPoint.x() + sourceRect.x(); ASSERT(destx >= 0); - ASSERT(destx < m_size.width()); + ASSERT(destx < size.width()); ASSERT(originx >= 0); ASSERT(originx <= sourceRect.right()); int endx = destPoint.x() + sourceRect.right(); - ASSERT(endx <= m_size.width()); + ASSERT(endx <= size.width()); int numColumns = endx - destx; int originy = sourceRect.y(); int desty = destPoint.y() + sourceRect.y(); ASSERT(desty >= 0); - ASSERT(desty < m_size.height()); + ASSERT(desty < size.height()); ASSERT(originy >= 0); ASSERT(originy <= sourceRect.bottom()); int endy = destPoint.y() + sourceRect.bottom(); - ASSERT(endy <= m_size.height()); + ASSERT(endy <= size.height()); int numRows = endy - desty; unsigned srcBytesPerRow = 4 * source->width(); - unsigned destBytesPerRow = 4 * m_size.width(); + unsigned destBytesPerRow = 4 * size.width(); unsigned char* srcRows = source->data()->data()->data() + originy * srcBytesPerRow + originx * 4; - unsigned char* destRows = reinterpret_cast<unsigned char*>(m_data.m_data) + desty * destBytesPerRow + destx * 4; + unsigned char* destRows = reinterpret_cast<unsigned char*>(imageData.m_data) + desty * destBytesPerRow + destx * 4; for (int y = 0; y < numRows; ++y) { for (int x = 0; x < numColumns; x++) { int basex = x * 4; unsigned char alpha = srcRows[basex + 3]; - if (alpha != 255) { + if (multiplied == Unmultiplied && alpha != 255) { destRows[basex] = (srcRows[basex] * alpha + 254) / 255; destRows[basex + 1] = (srcRows[basex + 1] * alpha + 254) / 255; destRows[basex + 2] = (srcRows[basex + 2] * alpha + 254) / 255; @@ -225,6 +240,16 @@ void ImageBuffer::putImageData(ImageData* source, const IntRect& sourceRect, con } } +void ImageBuffer::putUnmultipliedImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint) +{ + putImageData<Unmultiplied>(source, sourceRect, destPoint, m_data, m_size); +} + +void ImageBuffer::putPremultipliedImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint) +{ + putImageData<Premultiplied>(source, sourceRect, destPoint, m_data, m_size); +} + static RetainPtr<CFStringRef> utiFromMIMEType(const String& mimeType) { #if PLATFORM(MAC) diff --git a/WebCore/platform/graphics/filters/FEColorMatrix.cpp b/WebCore/platform/graphics/filters/FEColorMatrix.cpp index fb0a194..1e2e552 100644 --- a/WebCore/platform/graphics/filters/FEColorMatrix.cpp +++ b/WebCore/platform/graphics/filters/FEColorMatrix.cpp @@ -166,7 +166,7 @@ void FEColorMatrix::apply(Filter* filter) filterContext->drawImage(m_in->resultImage()->image(), calculateDrawingRect(m_in->subRegion())); IntRect imageRect(IntPoint(), resultImage()->size()); - PassRefPtr<ImageData> imageData(resultImage()->getImageData(imageRect)); + PassRefPtr<ImageData> imageData(resultImage()->getUnmultipliedImageData(imageRect)); PassRefPtr<CanvasPixelArray> srcPixelArray(imageData->data()); switch (m_type) { @@ -186,7 +186,7 @@ void FEColorMatrix::apply(Filter* filter) break; } - resultImage()->putImageData(imageData.get(), imageRect, IntPoint()); + resultImage()->putUnmultipliedImageData(imageData.get(), imageRect, IntPoint()); } void FEColorMatrix::dump() diff --git a/WebCore/platform/graphics/haiku/ColorHaiku.cpp b/WebCore/platform/graphics/haiku/ColorHaiku.cpp new file mode 100644 index 0000000..a9ac186 --- /dev/null +++ b/WebCore/platform/graphics/haiku/ColorHaiku.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2007 Ryan Leavengood <leavengood@gmail.com> + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "Color.h" + +#include <InterfaceDefs.h> + + +namespace WebCore { + +Color::Color(const rgb_color& color) + : m_color(makeRGBA(color.red, color.green, color.blue, color.alpha)) + , m_valid(true) +{ +} + +Color::operator rgb_color() const +{ + return make_color(red(), green(), blue(), alpha()); +} + + +Color focusRingColor() +{ + return Color(keyboard_navigation_color()); +} + +} // namespace WebCore + diff --git a/WebCore/platform/graphics/haiku/FloatPointHaiku.cpp b/WebCore/platform/graphics/haiku/FloatPointHaiku.cpp new file mode 100644 index 0000000..0f50898 --- /dev/null +++ b/WebCore/platform/graphics/haiku/FloatPointHaiku.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2007 Ryan Leavengood <leavengood@gmail.com> + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "FloatPoint.h" + +#include <Point.h> + + +namespace WebCore { + +FloatPoint::FloatPoint(const BPoint& point) + : m_x(point.x) + , m_y(point.y) +{ +} + +FloatPoint::operator BPoint() const +{ + return BPoint(m_x, m_y); +} + +} // namespace WebCore + diff --git a/WebCore/platform/graphics/haiku/FloatRectHaiku.cpp b/WebCore/platform/graphics/haiku/FloatRectHaiku.cpp new file mode 100644 index 0000000..67af3af --- /dev/null +++ b/WebCore/platform/graphics/haiku/FloatRectHaiku.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2007 Ryan Leavengood <leavengood@gmail.com> + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "FloatRect.h" + +#include <Rect.h> + + +namespace WebCore { + +FloatRect::FloatRect(const BRect& rect) + : m_location(rect.LeftTop()) + , m_size(rect.Width(), rect.Height()) +{ +} + +FloatRect::operator BRect() const +{ + return BRect(BPoint(x(), y()), BSize(width(), height())); +} + +} // namespace WebCore + diff --git a/WebCore/platform/graphics/haiku/GradientHaiku.cpp b/WebCore/platform/graphics/haiku/GradientHaiku.cpp new file mode 100644 index 0000000..469a17f --- /dev/null +++ b/WebCore/platform/graphics/haiku/GradientHaiku.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2008 Kevin Ollivier <kevino@theolliviers.com> All rights reserved. + * Copyright (C) 2009 Maxime Simon <simon.maxime@theolliviers.com> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "Gradient.h" + +#include "CSSParser.h" +#include "NotImplemented.h" + + +namespace WebCore { + +void Gradient::platformDestroy() +{ + notImplemented(); +} + +PlatformGradient Gradient::platformGradient() +{ + notImplemented(); + return 0; +} + +void Gradient::fill(GraphicsContext*, const FloatRect&) +{ + notImplemented(); +} + +} // namespace WebCore + diff --git a/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp b/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp new file mode 100644 index 0000000..d785ef4 --- /dev/null +++ b/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp @@ -0,0 +1,536 @@ +/* + * Copyright (C) 2007 Ryan Leavengood <leavengood@gmail.com> + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "GraphicsContext.h" + +#include "CString.h" +#include "Color.h" +#include "Font.h" +#include "FontData.h" +#include "NotImplemented.h" +#include "Path.h" +#include "Pen.h" +#include "TransformationMatrix.h" +#include <GraphicsDefs.h> +#include <Region.h> +#include <View.h> +#include <Window.h> +#include <stdio.h> + + +namespace WebCore { + +class GraphicsContextPlatformPrivate { +public: + GraphicsContextPlatformPrivate(BView* view); + ~GraphicsContextPlatformPrivate(); + + BView* m_view; +}; + +GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate(BView* view) + : m_view(view) +{ +} + +GraphicsContextPlatformPrivate::~GraphicsContextPlatformPrivate() +{ +} + +GraphicsContext::GraphicsContext(PlatformGraphicsContext* context) + : m_common(createGraphicsContextPrivate()) + , m_data(new GraphicsContextPlatformPrivate(context)) +{ + setPaintingDisabled(!context); +} + +GraphicsContext::~GraphicsContext() +{ + destroyGraphicsContextPrivate(m_common); + delete m_data; +} + +PlatformGraphicsContext* GraphicsContext::platformContext() const +{ + return m_data->m_view; +} + +void GraphicsContext::savePlatformState() +{ + m_data->m_view->PushState(); +} + +void GraphicsContext::restorePlatformState() +{ + m_data->m_view->PopState(); +} + +// Draws a filled rectangle with a stroked border. +void GraphicsContext::drawRect(const IntRect& rect) +{ + if (paintingDisabled()) + return; + + m_data->m_view->FillRect(rect); + if (strokeStyle() != NoStroke) + m_data->m_view->StrokeRect(rect, getHaikuStrokeStyle()); +} + +// This is only used to draw borders. +void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2) +{ + if (paintingDisabled()) + return; + + if (strokeStyle() == NoStroke) + return; + + m_data->m_view->StrokeLine(point1, point2, getHaikuStrokeStyle()); +} + +// This method is only used to draw the little circles used in lists. +void GraphicsContext::drawEllipse(const IntRect& rect) +{ + if (paintingDisabled()) + return; + + m_data->m_view->FillEllipse(rect); + if (strokeStyle() != NoStroke) + m_data->m_view->StrokeEllipse(rect, getHaikuStrokeStyle()); +} + +void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSpan) +{ + if (paintingDisabled()) + return; + + m_data->m_view->StrokeArc(rect, startAngle, angleSpan, getHaikuStrokeStyle()); +} + +void GraphicsContext::strokePath() +{ + notImplemented(); +} + +void GraphicsContext::drawConvexPolygon(size_t pointsLength, const FloatPoint* points, bool shouldAntialias) +{ + if (paintingDisabled()) + return; + + BPoint bPoints[pointsLength]; + for (size_t i = 0; i < pointsLength; i++) + bPoints[i] = points[i]; + + m_data->m_view->FillPolygon(bPoints, pointsLength); + if (strokeStyle() != NoStroke) + // Stroke with low color + m_data->m_view->StrokePolygon(bPoints, pointsLength, true, getHaikuStrokeStyle()); +} + +void GraphicsContext::fillRect(const FloatRect& rect, const Color& color) +{ + if (paintingDisabled()) + return; + + rgb_color oldColor = m_data->m_view->HighColor(); + m_data->m_view->SetHighColor(color); + m_data->m_view->FillRect(rect); + m_data->m_view->SetHighColor(oldColor); +} + +void GraphicsContext::fillRect(const FloatRect& rect) +{ + if (paintingDisabled()) + return; +} + +void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color) +{ + if (paintingDisabled() || !color.alpha()) + return; + + notImplemented(); + // FIXME: A simple implementation could just use FillRoundRect if all + // the sizes are the same, or even if they are not. Otherwise several + // FillRect and FillArc calls are needed. +} + +void GraphicsContext::fillPath() +{ + notImplemented(); +} + +void GraphicsContext::beginPath() +{ + notImplemented(); +} + +void GraphicsContext::addPath(const Path& path) +{ + notImplemented(); +} + +void GraphicsContext::clip(const FloatRect& rect) +{ + if (paintingDisabled()) + return; + + BRegion region(rect); + m_data->m_view->ConstrainClippingRegion(®ion); +} + +void GraphicsContext::drawFocusRing(const Color& color) +{ + if (paintingDisabled()) + return; + + const Vector<IntRect>& rects = focusRingRects(); + unsigned rectCount = rects.size(); + + // FIXME: maybe we should implement this with BShape? + + if (rects.size() > 1) { + BRegion region; + for (int i = 0; i < rectCount; ++i) + region.Include(BRect(rects[i])); + + m_data->m_view->SetHighColor(color); + m_data->m_view->StrokeRect(region.Frame(), B_MIXED_COLORS); + } +} + +void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool printing) +{ + if (paintingDisabled()) + return; + + IntPoint endPoint = origin + IntSize(width, 0); + drawLine(origin, endPoint); +} + +void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint&, int width, bool grammar) +{ + if (paintingDisabled()) + return; + + notImplemented(); +} + +FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect) +{ + notImplemented(); + return rect; +} + +void GraphicsContext::beginTransparencyLayer(float opacity) +{ + if (paintingDisabled()) + return; + + notImplemented(); +} + +void GraphicsContext::endTransparencyLayer() +{ + if (paintingDisabled()) + return; + + notImplemented(); +} + +void GraphicsContext::clearRect(const FloatRect& rect) +{ + if (paintingDisabled()) + return; + + notImplemented(); +} + +void GraphicsContext::strokeRect(const FloatRect& rect, float width) +{ + if (paintingDisabled()) + return; + + float oldSize = m_data->m_view->PenSize(); + m_data->m_view->SetPenSize(width); + m_data->m_view->StrokeRect(rect, getHaikuStrokeStyle()); + m_data->m_view->SetPenSize(oldSize); +} + +void GraphicsContext::setLineCap(LineCap lineCap) +{ + if (paintingDisabled()) + return; + + cap_mode mode = B_BUTT_CAP; + switch (lineCap) { + case RoundCap: + mode = B_ROUND_CAP; + break; + case SquareCap: + mode = B_SQUARE_CAP; + break; + case ButtCap: + default: + break; + } + + m_data->m_view->SetLineMode(mode, m_data->m_view->LineJoinMode(), m_data->m_view->LineMiterLimit()); +} + +void GraphicsContext::setLineJoin(LineJoin lineJoin) +{ + if (paintingDisabled()) + return; + + join_mode mode = B_MITER_JOIN; + switch (lineJoin) { + case RoundJoin: + mode = B_ROUND_JOIN; + break; + case BevelJoin: + mode = B_BEVEL_JOIN; + break; + case MiterJoin: + default: + break; + } + + m_data->m_view->SetLineMode(m_data->m_view->LineCapMode(), mode, m_data->m_view->LineMiterLimit()); +} + +void GraphicsContext::setMiterLimit(float limit) +{ + if (paintingDisabled()) + return; + + m_data->m_view->SetLineMode(m_data->m_view->LineCapMode(), m_data->m_view->LineJoinMode(), limit); +} + +void GraphicsContext::setAlpha(float opacity) +{ + if (paintingDisabled()) + return; + + notImplemented(); +} + +void GraphicsContext::setCompositeOperation(CompositeOperator op) +{ + if (paintingDisabled()) + return; + + drawing_mode mode = B_OP_COPY; + switch (op) { + case CompositeClear: + case CompositeCopy: + // Use the default above + break; + case CompositeSourceOver: + mode = B_OP_OVER; + break; + default: + printf("GraphicsContext::setCompositeOperation: Unsupported composite operation %s\n", + compositeOperatorName(op).utf8().data()); + } + m_data->m_view->SetDrawingMode(mode); +} + +void GraphicsContext::clip(const Path& path) +{ + if (paintingDisabled()) + return; + + m_data->m_view->ConstrainClippingRegion(path.platformPath()); +} + +void GraphicsContext::clipOut(const Path& path) +{ + if (paintingDisabled()) + return; + + notImplemented(); +} + +void GraphicsContext::clipToImageBuffer(const FloatRect&, const ImageBuffer*) +{ + notImplemented(); +} + +TransformationMatrix GraphicsContext::getCTM() const +{ + notImplemented(); + return TransformationMatrix(); +} + +void GraphicsContext::translate(float x, float y) +{ + if (paintingDisabled()) + return; + + notImplemented(); +} + +IntPoint GraphicsContext::origin() +{ + notImplemented(); + return IntPoint(0, 0); +} + +void GraphicsContext::rotate(float radians) +{ + if (paintingDisabled()) + return; + + notImplemented(); +} + +void GraphicsContext::scale(const FloatSize& size) +{ + if (paintingDisabled()) + return; + + notImplemented(); +} + +void GraphicsContext::clipOut(const IntRect& rect) +{ + if (paintingDisabled()) + return; + + notImplemented(); +} + +void GraphicsContext::clipOutEllipseInRect(const IntRect& rect) +{ + if (paintingDisabled()) + return; + + notImplemented(); +} + +void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness) +{ + if (paintingDisabled()) + return; + + notImplemented(); +} + +void GraphicsContext::concatCTM(const TransformationMatrix& transform) +{ + if (paintingDisabled()) + return; + + notImplemented(); +} + +void GraphicsContext::setPlatformShouldAntialias(bool enable) +{ + if (paintingDisabled()) + return; + + notImplemented(); +} + +void GraphicsContext::setImageInterpolationQuality(InterpolationQuality) +{ +} + +void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect) +{ + notImplemented(); +} + +void GraphicsContext::setPlatformFont(const Font& font) +{ + m_data->m_view->SetFont(font.primaryFont()->platformData().font()); +} + +void GraphicsContext::setPlatformStrokeColor(const Color& color) +{ + if (paintingDisabled()) + return; + + m_data->m_view->SetHighColor(color); +} + +pattern GraphicsContext::getHaikuStrokeStyle() +{ + switch (strokeStyle()) { + case SolidStroke: + return B_SOLID_HIGH; + break; + case DottedStroke: + return B_MIXED_COLORS; + break; + case DashedStroke: + // FIXME: use a better dashed stroke! + notImplemented(); + return B_MIXED_COLORS; + break; + default: + return B_SOLID_LOW; + break; + } +} + +void GraphicsContext::setPlatformStrokeStyle(const StrokeStyle& strokeStyle) +{ + // FIXME: see getHaikuStrokeStyle. + notImplemented(); +} + +void GraphicsContext::setPlatformStrokeThickness(float thickness) +{ + if (paintingDisabled()) + return; + + m_data->m_view->SetPenSize(thickness); +} + +void GraphicsContext::setPlatformFillColor(const Color& color) +{ + if (paintingDisabled()) + return; + + m_data->m_view->SetHighColor(color); +} + +void GraphicsContext::clearPlatformShadow() +{ + notImplemented(); +} + +void GraphicsContext::setPlatformShadow(IntSize const&, int, Color const&) +{ + notImplemented(); +} + +} // namespace WebCore + diff --git a/WebCore/platform/graphics/haiku/IntPointHaiku.cpp b/WebCore/platform/graphics/haiku/IntPointHaiku.cpp new file mode 100644 index 0000000..327e503 --- /dev/null +++ b/WebCore/platform/graphics/haiku/IntPointHaiku.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2007 Ryan Leavengood <leavengood@gmail.com> + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "IntPoint.h" + +#include <Point.h> + + +namespace WebCore { + +IntPoint::IntPoint(const BPoint& point) + : m_x(static_cast<int>(point.x)) + , m_y(static_cast<int>(point.y)) +{ +} + +IntPoint::operator BPoint() const +{ + return BPoint(m_x, m_y); +} + +} // namespace WebCore + diff --git a/WebCore/platform/graphics/haiku/IntRectHaiku.cpp b/WebCore/platform/graphics/haiku/IntRectHaiku.cpp new file mode 100644 index 0000000..74a0b9d --- /dev/null +++ b/WebCore/platform/graphics/haiku/IntRectHaiku.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2007 Ryan Leavengood <leavengood@gmail.com> + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "IntRect.h" + +#include <Rect.h> + + +namespace WebCore { + +IntRect::IntRect(const BRect& rect) + : m_location(rect.LeftTop()) + , m_size(rect.IntegerWidth(), rect.IntegerHeight()) +{ +} + +IntRect::operator BRect() const +{ + return BRect(BPoint(x(), y()), BSize(width(), height())); +} + +} // namespace WebCore + diff --git a/WebCore/platform/graphics/haiku/IntSizeHaiku.cpp b/WebCore/platform/graphics/haiku/IntSizeHaiku.cpp new file mode 100644 index 0000000..08c3a9d --- /dev/null +++ b/WebCore/platform/graphics/haiku/IntSizeHaiku.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2007 Ryan Leavengood <leavengood@gmail.com> + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "IntSize.h" + +#include <Size.h> + + +namespace WebCore { + +IntSize::IntSize(const BSize& size) + : m_width(size.IntegerWidth()) + , m_height(size.IntegerHeight()) +{ +} + +IntSize::operator BSize() const +{ + return BSize(width(), height()); +} + +} // namespace WebCore + diff --git a/WebCore/platform/graphics/haiku/PathHaiku.cpp b/WebCore/platform/graphics/haiku/PathHaiku.cpp new file mode 100644 index 0000000..d0da025 --- /dev/null +++ b/WebCore/platform/graphics/haiku/PathHaiku.cpp @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2007 Ryan Leavengood <leavengood@gmail.com> + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "Path.h" + +#include "FloatRect.h" +#include "NotImplemented.h" +#include "PlatformString.h" +#include <Region.h> + + +namespace WebCore { + +Path::Path() + : m_path(new BRegion()) +{ +} + +Path::~Path() +{ + delete m_path; +} + +Path::Path(const Path& other) + : m_path(new BRegion(*other.platformPath())) +{ +} + +Path& Path::operator=(const Path& other) +{ + if (&other != this) + m_path = other.platformPath(); + + return *this; +} + +bool Path::hasCurrentPoint() const +{ + return !isEmpty(); +} + +bool Path::contains(const FloatPoint& point, WindRule rule) const +{ + return m_path->Contains(point); +} + +void Path::translate(const FloatSize& size) +{ + notImplemented(); +} + +FloatRect Path::boundingRect() const +{ + return m_path->Frame(); +} + +void Path::moveTo(const FloatPoint& point) +{ + // FIXME: Use OffsetBy? + notImplemented(); +} + +void Path::addLineTo(const FloatPoint& p) +{ + notImplemented(); +} + +void Path::addQuadCurveTo(const FloatPoint& cp, const FloatPoint& p) +{ + notImplemented(); +} + +void Path::addBezierCurveTo(const FloatPoint& cp1, const FloatPoint& cp2, const FloatPoint& p) +{ + notImplemented(); +} + +void Path::addArcTo(const FloatPoint& p1, const FloatPoint& p2, float radius) +{ + notImplemented(); +} + +void Path::closeSubpath() +{ + notImplemented(); +} + +void Path::addArc(const FloatPoint& p, float r, float sar, float ear, bool anticlockwise) +{ + notImplemented(); +} + +void Path::addRect(const FloatRect& r) +{ + m_path->Include(r); +} + +void Path::addEllipse(const FloatRect& r) +{ + notImplemented(); +} + +void Path::clear() +{ + m_path->MakeEmpty(); +} + +bool Path::isEmpty() const +{ + return !m_path->Frame().IsValid(); +} + +String Path::debugString() const +{ + notImplemented(); + return String(); +} + +void Path::apply(void* info, PathApplierFunction function) const +{ + notImplemented(); +} + +void Path::transform(const TransformationMatrix& transform) +{ + notImplemented(); +} + +FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier) +{ + notImplemented(); + return FloatRect(); +} + +} // namespace WebCore + diff --git a/WebCore/platform/graphics/mac/FontMacATSUI.mm b/WebCore/platform/graphics/mac/FontMacATSUI.mm index 051abb7..35c40bf 100644 --- a/WebCore/platform/graphics/mac/FontMacATSUI.mm +++ b/WebCore/platform/graphics/mac/FontMacATSUI.mm @@ -504,8 +504,8 @@ FloatRect Font::selectionRectForComplexText(const TextRun& run, const IntPoint& firstGlyphBounds = zeroTrapezoid; } - float beforeWidth = MIN(FixedToFloat(firstGlyphBounds.lowerLeft.x), FixedToFloat(firstGlyphBounds.upperLeft.x)); - float afterWidth = MAX(FixedToFloat(firstGlyphBounds.lowerRight.x), FixedToFloat(firstGlyphBounds.upperRight.x)); + float beforeWidth = min(FixedToFloat(firstGlyphBounds.lowerLeft.x), FixedToFloat(firstGlyphBounds.upperLeft.x)); + float afterWidth = max(FixedToFloat(firstGlyphBounds.lowerRight.x), FixedToFloat(firstGlyphBounds.upperRight.x)); FloatRect rect(point.x() + floorf(beforeWidth), point.y(), roundf(afterWidth) - floorf(beforeWidth), h); @@ -591,8 +591,8 @@ float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFon if (actualNumBounds != 1) LOG_ERROR("unexpected result from ATSUGetGlyphBounds(): actualNumBounds(%d) != 1", actualNumBounds); - return MAX(FixedToFloat(firstGlyphBounds.upperRight.x), FixedToFloat(firstGlyphBounds.lowerRight.x)) - - MIN(FixedToFloat(firstGlyphBounds.upperLeft.x), FixedToFloat(firstGlyphBounds.lowerLeft.x)); + return max(FixedToFloat(firstGlyphBounds.upperRight.x), FixedToFloat(firstGlyphBounds.lowerRight.x)) - + min(FixedToFloat(firstGlyphBounds.upperLeft.x), FixedToFloat(firstGlyphBounds.lowerLeft.x)); } int Font::offsetForPositionForComplexText(const TextRun& run, int x, bool /*includePartialGlyphs*/) const diff --git a/WebCore/platform/graphics/mac/GraphicsLayerCA.h b/WebCore/platform/graphics/mac/GraphicsLayerCA.h index ebdc6ac..d1bdb7e 100644 --- a/WebCore/platform/graphics/mac/GraphicsLayerCA.h +++ b/WebCore/platform/graphics/mac/GraphicsLayerCA.h @@ -62,6 +62,8 @@ public: virtual void removeFromParent(); + virtual void setMaskLayer(GraphicsLayer*); + virtual void setPosition(const FloatPoint&); virtual void setAnchorPoint(const FloatPoint3D&); virtual void setSize(const FloatSize&); @@ -172,6 +174,7 @@ private: void updateContentsVideo(); void updateContentsRect(); void updateGeometryOrientation(); + void updateMaskLayer(); void updateLayerAnimations(); @@ -200,7 +203,8 @@ private: ContentsImageChanged = 1 << 17, ContentsVideoChanged = 1 << 18, ContentsRectChanged = 1 << 19, - GeometryOrientationChanged = 1 << 20 + GeometryOrientationChanged = 1 << 20, + MaskLayerChanged = 1 << 21 }; typedef unsigned LayerChangeFlags; void noteLayerPropertyChanged(LayerChangeFlags flags); diff --git a/WebCore/platform/graphics/mac/GraphicsLayerCA.mm b/WebCore/platform/graphics/mac/GraphicsLayerCA.mm index e5b9035..abb310a 100644 --- a/WebCore/platform/graphics/mac/GraphicsLayerCA.mm +++ b/WebCore/platform/graphics/mac/GraphicsLayerCA.mm @@ -331,7 +331,7 @@ static NSDictionary* nullActionsDictionary() return actions; } -GraphicsLayer* GraphicsLayer::createGraphicsLayer(GraphicsLayerClient* client) +PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerClient* client) { return new GraphicsLayerCA(client); } @@ -432,6 +432,15 @@ void GraphicsLayerCA::removeFromParent() GraphicsLayer::removeFromParent(); } +void GraphicsLayerCA::setMaskLayer(GraphicsLayer* layer) +{ + if (layer == m_maskLayer) + return; + + GraphicsLayer::setMaskLayer(layer); + noteLayerPropertyChanged(MaskLayerChanged); +} + void GraphicsLayerCA::setPosition(const FloatPoint& point) { if (point == m_position) @@ -733,6 +742,9 @@ void GraphicsLayerCA::recursiveCommitChanges() { commitLayerChanges(); + if (m_maskLayer) + static_cast<GraphicsLayerCA*>(m_maskLayer)->commitLayerChanges(); + const Vector<GraphicsLayer*>& childLayers = children(); size_t numChildren = childLayers.size(); for (size_t i = 0; i < numChildren; ++i) { @@ -812,6 +824,9 @@ void GraphicsLayerCA::commitLayerChanges() if (m_uncommittedChanges & GeometryOrientationChanged) updateGeometryOrientation(); + if (m_uncommittedChanges & MaskLayerChanged) + updateMaskLayer(); + m_uncommittedChanges = NoChange; END_BLOCK_OBJC_EXCEPTIONS } @@ -821,10 +836,12 @@ void GraphicsLayerCA::updateSublayerList() NSMutableArray* newSublayers = nil; if (m_transformLayer) { - // FIXME: add the primary layer in the correct order with negative z-order children. + // Add the primary layer first. Even if we have negative z-order children, the primary layer always comes behind. newSublayers = [[NSMutableArray alloc] initWithObjects:m_layer.get(), nil]; } else if (m_contentsLayer) { // FIXME: add the contents layer in the correct order with negative z-order children. + // This does not cause visible rendering issues because currently contents layers are only used + // for replaced elements that don't have children. newSublayers = [[NSMutableArray alloc] initWithObjects:m_contentsLayer.get(), nil]; } @@ -1094,6 +1111,12 @@ void GraphicsLayerCA::updateGeometryOrientation() #endif } +void GraphicsLayerCA::updateMaskLayer() +{ + CALayer* maskCALayer = m_maskLayer ? m_maskLayer->platformLayer() : 0; + [m_layer.get() setMask:maskCALayer]; +} + void GraphicsLayerCA::updateLayerAnimations() { if (m_transitionPropertiesToRemove.size()) { diff --git a/WebCore/platform/graphics/mac/SimpleFontDataMac.mm b/WebCore/platform/graphics/mac/SimpleFontDataMac.mm index cdde7cf..acb97a7 100644 --- a/WebCore/platform/graphics/mac/SimpleFontDataMac.mm +++ b/WebCore/platform/graphics/mac/SimpleFontDataMac.mm @@ -50,6 +50,8 @@ - (BOOL)_isFakeFixedPitch; @end +using namespace std; + namespace WebCore { const float smallCapsFontSizeMultiplier = 0.7f; @@ -269,7 +271,7 @@ void SimpleFontData::platformInit() // and web pages that foolishly use this metric for width will be laid out // poorly if we return an accurate height. Classic case is Times 13 point, // which has an "x" that is 7x6 pixels. - m_xHeight = MAX(NSMaxX(xBox), NSMaxY(xBox)); + m_xHeight = max(NSMaxX(xBox), NSMaxY(xBox)); } else m_xHeight = [m_platformData.font() xHeight]; } diff --git a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp index e259a4e..5e04b85 100644 --- a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp +++ b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp @@ -34,29 +34,29 @@ */ #include "config.h" +#include "GraphicsContext.h" #ifdef Q_WS_WIN #include <windows.h> #endif -#include "TransformationMatrix.h" #include "Color.h" #include "FloatConversion.h" #include "Font.h" -#include "GraphicsContext.h" #include "GraphicsContextPrivate.h" #include "ImageBuffer.h" +#include "NotImplemented.h" #include "Path.h" #include "Pattern.h" #include "Pen.h" -#include "NotImplemented.h" +#include "TransformationMatrix.h" #include <QBrush> #include <QDebug> #include <QGradient> -#include <QPainter> #include <QPaintDevice> #include <QPaintEngine> +#include <QPainter> #include <QPainterPath> #include <QPixmap> #include <QPolygonF> @@ -72,35 +72,35 @@ namespace WebCore { static inline QPainter::CompositionMode toQtCompositionMode(CompositeOperator op) { switch (op) { - case CompositeClear: - return QPainter::CompositionMode_Clear; - case CompositeCopy: - return QPainter::CompositionMode_Source; - case CompositeSourceOver: - return QPainter::CompositionMode_SourceOver; - case CompositeSourceIn: - return QPainter::CompositionMode_SourceIn; - case CompositeSourceOut: - return QPainter::CompositionMode_SourceOut; - case CompositeSourceAtop: - return QPainter::CompositionMode_SourceAtop; - case CompositeDestinationOver: - return QPainter::CompositionMode_DestinationOver; - case CompositeDestinationIn: - return QPainter::CompositionMode_DestinationIn; - case CompositeDestinationOut: - return QPainter::CompositionMode_DestinationOut; - case CompositeDestinationAtop: - return QPainter::CompositionMode_DestinationAtop; - case CompositeXOR: - return QPainter::CompositionMode_Xor; - case CompositePlusDarker: - // there is no exact match, but this is the closest - return QPainter::CompositionMode_Darken; - case CompositeHighlight: - return QPainter::CompositionMode_SourceOver; - case CompositePlusLighter: - return QPainter::CompositionMode_Plus; + case CompositeClear: + return QPainter::CompositionMode_Clear; + case CompositeCopy: + return QPainter::CompositionMode_Source; + case CompositeSourceOver: + return QPainter::CompositionMode_SourceOver; + case CompositeSourceIn: + return QPainter::CompositionMode_SourceIn; + case CompositeSourceOut: + return QPainter::CompositionMode_SourceOut; + case CompositeSourceAtop: + return QPainter::CompositionMode_SourceAtop; + case CompositeDestinationOver: + return QPainter::CompositionMode_DestinationOver; + case CompositeDestinationIn: + return QPainter::CompositionMode_DestinationIn; + case CompositeDestinationOut: + return QPainter::CompositionMode_DestinationOut; + case CompositeDestinationAtop: + return QPainter::CompositionMode_DestinationAtop; + case CompositeXOR: + return QPainter::CompositionMode_Xor; + case CompositePlusDarker: + // there is no exact match, but this is the closest + return QPainter::CompositionMode_Darken; + case CompositeHighlight: + return QPainter::CompositionMode_SourceOver; + case CompositePlusLighter: + return QPainter::CompositionMode_Plus; } return QPainter::CompositionMode_SourceOver; @@ -109,12 +109,12 @@ static inline QPainter::CompositionMode toQtCompositionMode(CompositeOperator op static inline Qt::PenCapStyle toQtLineCap(LineCap lc) { switch (lc) { - case ButtCap: - return Qt::FlatCap; - case RoundCap: - return Qt::RoundCap; - case SquareCap: - return Qt::SquareCap; + case ButtCap: + return Qt::FlatCap; + case RoundCap: + return Qt::RoundCap; + case SquareCap: + return Qt::SquareCap; } return Qt::FlatCap; @@ -123,12 +123,12 @@ static inline Qt::PenCapStyle toQtLineCap(LineCap lc) static inline Qt::PenJoinStyle toQtLineJoin(LineJoin lj) { switch (lj) { - case MiterJoin: - return Qt::SvgMiterJoin; - case RoundJoin: - return Qt::RoundJoin; - case BevelJoin: - return Qt::BevelJoin; + case MiterJoin: + return Qt::SvgMiterJoin; + case RoundJoin: + return Qt::RoundJoin; + case BevelJoin: + return Qt::BevelJoin; } return Qt::MiterJoin; @@ -210,8 +210,8 @@ public: return redirect; return painter; - } else - return &layers.top()->painter; + } + return &layers.top()->painter; } bool antiAliasingForRectsAndLines; @@ -411,46 +411,25 @@ void GraphicsContext::drawRect(const IntRect& rect) if (paintingDisabled()) return; - QPainter *p = m_data->p(); + QPainter* p = m_data->p(); const bool antiAlias = p->testRenderHint(QPainter::Antialiasing); p->setRenderHint(QPainter::Antialiasing, m_data->antiAliasingForRectsAndLines); + IntSize shadowSize; + int shadowBlur; + Color shadowColor; + if (textDrawingMode() == cTextFill && getShadow(shadowSize, shadowBlur, shadowColor)) { + IntRect shadowRect = rect; + shadowRect.move(shadowSize.width(), shadowSize.height()); + shadowRect.inflate(p->pen().widthF()); + p->fillRect(shadowRect, QColor(shadowColor)); + } + p->drawRect(rect); p->setRenderHint(QPainter::Antialiasing, antiAlias); } -// FIXME: Now that this is refactored, it should be shared by all contexts. -static void adjustLineToPixelBoundaries(FloatPoint& p1, FloatPoint& p2, float strokeWidth, - const StrokeStyle& penStyle) -{ - // For odd widths, we add in 0.5 to the appropriate x/y so that the float arithmetic - // works out. For example, with a border width of 3, KHTML will pass us (y1+y2)/2, e.g., - // (50+53)/2 = 103/2 = 51 when we want 51.5. It is always true that an even width gave - // us a perfect position, but an odd width gave us a position that is off by exactly 0.5. - if (penStyle == DottedStroke || penStyle == DashedStroke) { - if (p1.x() == p2.x()) { - p1.setY(p1.y() + strokeWidth); - p2.setY(p2.y() - strokeWidth); - } else { - p1.setX(p1.x() + strokeWidth); - p2.setX(p2.x() - strokeWidth); - } - } - - if (((int) strokeWidth) % 2) { - if (p1.x() == p2.x()) { - // We're a vertical line. Adjust our x. - p1.setX(p1.x() + 0.5); - p2.setX(p2.x() + 0.5); - } else { - // We're a horizontal line. Adjust our y. - p1.setY(p1.y() + 0.5); - p2.setY(p2.y() + 0.5); - } - } -} - // This is only used to draw borders. void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2) { @@ -468,7 +447,7 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2) FloatPoint p2 = point2; bool isVerticalLine = (p1.x() == p2.x()); - QPainter *p = m_data->p(); + QPainter* p = m_data->p(); const bool antiAlias = p->testRenderHint(QPainter::Antialiasing); p->setRenderHint(QPainter::Antialiasing, m_data->antiAliasingForRectsAndLines); adjustLineToPixelBoundaries(p1, p2, width, style); @@ -486,15 +465,15 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2) int patWidth = 0; switch (style) { - case NoStroke: - case SolidStroke: - break; - case DottedStroke: - patWidth = (int)width; - break; - case DashedStroke: - patWidth = 3 * (int)width; - break; + case NoStroke: + case SolidStroke: + break; + case DottedStroke: + patWidth = static_cast<int>(width); + break; + case DashedStroke: + patWidth = 3 * static_cast<int>(width); + break; } if (patWidth) { @@ -523,7 +502,7 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2) if (patWidth == 1) patternOffset = 1.0f; else { - bool evenNumberOfSegments = numSegments % 2 == 0; + bool evenNumberOfSegments = !(numSegments % 2); if (remainder) evenNumberOfSegments = !evenNumberOfSegments; if (evenNumberOfSegments) { @@ -571,7 +550,7 @@ void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSp if (paintingDisabled() || strokeStyle() == NoStroke || strokeThickness() <= 0.0f || !strokeColor().alpha()) return; - QPainter *p = m_data->p(); + QPainter* p = m_data->p(); const bool antiAlias = p->testRenderHint(QPainter::Antialiasing); p->setRenderHint(QPainter::Antialiasing, true); @@ -593,7 +572,7 @@ void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points for (size_t i = 0; i < npoints; i++) polygon[i] = points[i]; - QPainter *p = m_data->p(); + QPainter* p = m_data->p(); p->save(); p->setRenderHint(QPainter::Antialiasing, shouldAntialias); p->drawConvexPolygon(polygon); @@ -605,7 +584,7 @@ QPen GraphicsContext::pen() if (paintingDisabled()) return QPen(); - QPainter *p = m_data->p(); + QPainter* p = m_data->p(); return p->pen(); } @@ -614,7 +593,7 @@ void GraphicsContext::fillPath() if (paintingDisabled()) return; - QPainter *p = m_data->p(); + QPainter* p = m_data->p(); QPainterPath path = m_data->currentPath; path.setFillRule(toQtFillRule(fillRule())); @@ -642,7 +621,7 @@ void GraphicsContext::strokePath() if (paintingDisabled()) return; - QPainter *p = m_data->p(); + QPainter* p = m_data->p(); QPen pen = p->pen(); QPainterPath path = m_data->currentPath; path.setFillRule(toQtFillRule(fillRule())); @@ -676,7 +655,16 @@ void GraphicsContext::fillRect(const FloatRect& rect) if (paintingDisabled()) return; - QPainter *p = m_data->p(); + QPainter* p = m_data->p(); + + IntSize shadowSize; + int shadowBlur; + Color shadowColor; + if (getShadow(shadowSize, shadowBlur, shadowColor)) { + FloatRect shadowRect = rect; + shadowRect.move(shadowSize.width(), shadowSize.height()); + p->fillRect(shadowRect, QColor(shadowColor)); + } switch (m_common->state.fillColorSpace) { case SolidColorSpace: @@ -703,7 +691,17 @@ void GraphicsContext::fillRect(const FloatRect& rect, const Color& c) return; m_data->solidColor.setColor(QColor(c)); - m_data->p()->fillRect(rect, m_data->solidColor); + IntSize shadowSize; + int shadowBlur; + Color shadowColor; + QPainter* p = m_data->p(); + if (textDrawingMode() == cTextFill && getShadow(shadowSize, shadowBlur, shadowColor)) { + FloatRect shadowRect = rect; + shadowRect.move(shadowSize.width(), shadowSize.height()); + shadowRect.inflate(p->pen().widthF()); + p->fillRect(shadowRect, QColor(shadowColor)); + } + p->fillRect(rect, m_data->solidColor); } void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color) @@ -750,7 +748,7 @@ void GraphicsContext::clipPath(WindRule clipRule) if (paintingDisabled()) return; - QPainter *p = m_data->p(); + QPainter* p = m_data->p(); QPainterPath newPath = m_data->currentPath; newPath.setFillRule(clipRule == RULE_EVENODD ? Qt::OddEvenFill : Qt::WindingFill); p->setClipPath(newPath); @@ -769,10 +767,10 @@ void GraphicsContext::drawFocusRing(const Color& color) const Vector<IntRect>& rects = focusRingRects(); unsigned rectCount = rects.size(); - if (rects.size() == 0) + if (!rects.size()) return; - QPainter *p = m_data->p(); + QPainter* p = m_data->p(); const bool antiAlias = p->testRenderHint(QPainter::Antialiasing); p->setRenderHint(QPainter::Antialiasing, m_data->antiAliasingForRectsAndLines); @@ -829,10 +827,16 @@ FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& frect) return FloatRect(QRectF(result)); } -void GraphicsContext::setPlatformShadow(const IntSize& pos, int blur, const Color &color) +void GraphicsContext::setPlatformShadow(const IntSize& size, int blur, const Color &color) { // Qt doesn't support shadows natively, they are drawn manually in the draw* // functions + + if (m_common->state.shadowsIgnoreTransforms) { + // Meaning that this graphics context is associated with a CanvasRenderingContext + // We flip the height since CG and HTML5 Canvas have opposite Y axis + m_common->state.shadowSize = IntSize(size.width(), -size.height()); + } } void GraphicsContext::clearPlatformShadow() @@ -848,8 +852,8 @@ void GraphicsContext::beginTransparencyLayer(float opacity) int x, y, w, h; x = y = 0; - QPainter *p = m_data->p(); - const QPaintDevice *device = p->device(); + QPainter* p = m_data->p(); + const QPaintDevice* device = p->device(); w = device->width(); h = device->height(); @@ -871,10 +875,10 @@ void GraphicsContext::endTransparencyLayer() if (paintingDisabled()) return; - TransparencyLayer *layer = m_data->layers.pop(); + TransparencyLayer* layer = m_data->layers.pop(); layer->painter.end(); - QPainter *p = m_data->p(); + QPainter* p = m_data->p(); p->save(); p->resetTransform(); p->setOpacity(layer->opacity); @@ -889,7 +893,7 @@ void GraphicsContext::clearRect(const FloatRect& rect) if (paintingDisabled()) return; - QPainter *p = m_data->p(); + QPainter* p = m_data->p(); QPainter::CompositionMode currentCompositionMode = p->compositionMode(); if (p->paintEngine()->hasFeature(QPaintEngine::PorterDuff)) p->setCompositionMode(QPainter::CompositionMode_Source); @@ -916,7 +920,7 @@ void GraphicsContext::setLineCap(LineCap lc) if (paintingDisabled()) return; - QPainter *p = m_data->p(); + QPainter* p = m_data->p(); QPen nPen = p->pen(); nPen.setCapStyle(toQtLineCap(lc)); p->setPen(nPen); @@ -948,7 +952,7 @@ void GraphicsContext::setLineJoin(LineJoin lj) if (paintingDisabled()) return; - QPainter *p = m_data->p(); + QPainter* p = m_data->p(); QPen nPen = p->pen(); nPen.setJoinStyle(toQtLineJoin(lj)); p->setPen(nPen); @@ -959,7 +963,7 @@ void GraphicsContext::setMiterLimit(float limit) if (paintingDisabled()) return; - QPainter *p = m_data->p(); + QPainter* p = m_data->p(); QPen nPen = p->pen(); nPen.setMiterLimit(limit); p->setPen(nPen); @@ -969,7 +973,7 @@ void GraphicsContext::setAlpha(float opacity) { if (paintingDisabled()) return; - QPainter *p = m_data->p(); + QPainter* p = m_data->p(); p->setOpacity(opacity); } @@ -995,7 +999,7 @@ void GraphicsContext::clipOut(const Path& path) if (paintingDisabled()) return; - QPainter *p = m_data->p(); + QPainter* p = m_data->p(); QRectF clipBounds = p->clipPath().boundingRect(); QPainterPath clippedOut = *path.platformPath(); QPainterPath newClip; @@ -1061,7 +1065,7 @@ void GraphicsContext::clipOut(const IntRect& rect) if (paintingDisabled()) return; - QPainter *p = m_data->p(); + QPainter* p = m_data->p(); QRectF clipBounds = p->clipPath().boundingRect(); QPainterPath newClip; newClip.setFillRule(Qt::OddEvenFill); @@ -1076,7 +1080,7 @@ void GraphicsContext::clipOutEllipseInRect(const IntRect& rect) if (paintingDisabled()) return; - QPainter *p = m_data->p(); + QPainter* p = m_data->p(); QRectF clipBounds = p->clipPath().boundingRect(); QPainterPath newClip; newClip.setFillRule(Qt::OddEvenFill); @@ -1109,7 +1113,7 @@ void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, path.setFillRule(Qt::OddEvenFill); - QPainter *p = m_data->p(); + QPainter* p = m_data->p(); const bool antiAlias = p->testRenderHint(QPainter::Antialiasing); p->setRenderHint(QPainter::Antialiasing, true); @@ -1143,7 +1147,7 @@ void GraphicsContext::setPlatformStrokeColor(const Color& color) { if (paintingDisabled()) return; - QPainter *p = m_data->p(); + QPainter* p = m_data->p(); QPen newPen(p->pen()); newPen.setColor(color); p->setPen(newPen); @@ -1153,7 +1157,7 @@ void GraphicsContext::setPlatformStrokeStyle(const StrokeStyle& strokeStyle) { if (paintingDisabled()) return; - QPainter *p = m_data->p(); + QPainter* p = m_data->p(); QPen newPen(p->pen()); newPen.setStyle(toQPenStyle(strokeStyle)); p->setPen(newPen); @@ -1163,7 +1167,7 @@ void GraphicsContext::setPlatformStrokeThickness(float thickness) { if (paintingDisabled()) return; - QPainter *p = m_data->p(); + QPainter* p = m_data->p(); QPen newPen(p->pen()); newPen.setWidthF(thickness); p->setPen(newPen); @@ -1184,7 +1188,6 @@ void GraphicsContext::setPlatformShouldAntialias(bool enable) } #ifdef Q_WS_WIN -#include <windows.h> HDC GraphicsContext::getWindowsContext(const IntRect& dstRect, bool supportAlphaBlend, bool mayCreateBitmap) { diff --git a/WebCore/platform/graphics/qt/ImageBufferQt.cpp b/WebCore/platform/graphics/qt/ImageBufferQt.cpp index 22a5a43..6637092 100644 --- a/WebCore/platform/graphics/qt/ImageBufferQt.cpp +++ b/WebCore/platform/graphics/qt/ImageBufferQt.cpp @@ -125,12 +125,13 @@ void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookUpTable) m_data.m_painter->begin(&m_data.m_pixmap); } -PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const +template <Multiply multiplied> +PassRefPtr<ImageData> getImageData(const IntRect& rect, const ImageBufferData& imageData, const IntSize& size) { PassRefPtr<ImageData> result = ImageData::create(rect.width(), rect.height()); unsigned char* data = result->data()->data()->data(); - if (rect.x() < 0 || rect.y() < 0 || (rect.x() + rect.width()) > m_size.width() || (rect.y() + rect.height()) > m_size.height()) + if (rect.x() < 0 || rect.y() < 0 || (rect.x() + rect.width()) > size.width() || (rect.y() + rect.height()) > size.height()) memset(data, 0, result->data()->length()); int originx = rect.x(); @@ -140,8 +141,8 @@ PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const originx = 0; } int endx = rect.x() + rect.width(); - if (endx > m_size.width()) - endx = m_size.width(); + if (endx > size.width()) + endx = size.width(); int numColumns = endx - originx; int originy = rect.y(); @@ -151,11 +152,16 @@ PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const originy = 0; } int endy = rect.y() + rect.height(); - if (endy > m_size.height()) - endy = m_size.height(); + if (endy > size.height()) + endy = size.height(); int numRows = endy - originy; - QImage image = m_data.m_pixmap.toImage().convertToFormat(QImage::Format_ARGB32); + QImage image = imageData.m_pixmap.toImage(); + if (multiplied == Unmultiplied) + image = image.convertToFormat(QImage::Format_ARGB32); + else + image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); + ASSERT(!image.isNull()); unsigned destBytesPerRow = 4 * rect.width(); @@ -176,7 +182,18 @@ PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const return result; } -void ImageBuffer::putImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint) +PassRefPtr<ImageData> ImageBuffer::getUnmultipliedImageData(const IntRect& rect) const +{ + return getImageData<Unmultiplied>(rect, m_data, m_size); +} + +PassRefPtr<ImageData> ImageBuffer::getPremultipliedImageData(const IntRect& rect) const +{ + return getImageData<Premultiplied>(rect, m_data, m_size); +} + +template <Multiply multiplied> +void putImageData(ImageData*& source, const IntRect& sourceRect, const IntPoint& destPoint, ImageBufferData& data, const IntSize& size) { ASSERT(sourceRect.width() > 0); ASSERT(sourceRect.height() > 0); @@ -184,33 +201,37 @@ void ImageBuffer::putImageData(ImageData* source, const IntRect& sourceRect, con int originx = sourceRect.x(); int destx = destPoint.x() + sourceRect.x(); ASSERT(destx >= 0); - ASSERT(destx < m_size.width()); + ASSERT(destx < size.width()); ASSERT(originx >= 0); ASSERT(originx <= sourceRect.right()); int endx = destPoint.x() + sourceRect.right(); - ASSERT(endx <= m_size.width()); + ASSERT(endx <= size.width()); int numColumns = endx - destx; int originy = sourceRect.y(); int desty = destPoint.y() + sourceRect.y(); ASSERT(desty >= 0); - ASSERT(desty < m_size.height()); + ASSERT(desty < size.height()); ASSERT(originy >= 0); ASSERT(originy <= sourceRect.bottom()); int endy = destPoint.y() + sourceRect.bottom(); - ASSERT(endy <= m_size.height()); + ASSERT(endy <= size.height()); int numRows = endy - desty; unsigned srcBytesPerRow = 4 * source->width(); - bool isPainting = m_data.m_painter->isActive(); + bool isPainting = data.m_painter->isActive(); if (isPainting) - m_data.m_painter->end(); + data.m_painter->end(); - QImage image = m_data.m_pixmap.toImage().convertToFormat(QImage::Format_ARGB32); + QImage image = data.m_pixmap.toImage(); + if (multiplied == Unmultiplied) + image = image.convertToFormat(QImage::Format_ARGB32); + else + image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); unsigned char* srcRows = source->data()->data()->data() + originy * srcBytesPerRow + originx * 4; for (int y = 0; y < numRows; ++y) { @@ -223,10 +244,20 @@ void ImageBuffer::putImageData(ImageData* source, const IntRect& sourceRect, con srcRows += srcBytesPerRow; } - m_data.m_pixmap = QPixmap::fromImage(image); + data.m_pixmap = QPixmap::fromImage(image); if (isPainting) - m_data.m_painter->begin(&m_data.m_pixmap); + data.m_painter->begin(&data.m_pixmap); +} + +void ImageBuffer::putUnmultipliedImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint) +{ + putImageData<Unmultiplied>(source, sourceRect, destPoint, m_data, m_size); +} + +void ImageBuffer::putPremultipliedImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint) +{ + putImageData<Premultiplied>(source, sourceRect, destPoint, m_data, m_size); } // We get a mimeType here but QImageWriter does not support mimetypes but diff --git a/WebCore/platform/graphics/skia/ImageBufferSkia.cpp b/WebCore/platform/graphics/skia/ImageBufferSkia.cpp index 7935ff1..c429bcf 100644 --- a/WebCore/platform/graphics/skia/ImageBufferSkia.cpp +++ b/WebCore/platform/graphics/skia/ImageBufferSkia.cpp @@ -118,16 +118,16 @@ void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookUpTable) } } -PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const +template <Multiply multiplied> +PassRefPtr<ImageData> getImageData(const IntRect& rect, const SkBitmap& bitmap, + const IntSize& size) { - ASSERT(context()); - RefPtr<ImageData> result = ImageData::create(rect.width(), rect.height()); unsigned char* data = result->data()->data()->data(); if (rect.x() < 0 || rect.y() < 0 || - (rect.x() + rect.width()) > m_size.width() || - (rect.y() + rect.height()) > m_size.height()) + (rect.x() + rect.width()) > size.width() || + (rect.y() + rect.height()) > size.height()) memset(data, 0, result->data()->length()); int originX = rect.x(); @@ -137,8 +137,8 @@ PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const originX = 0; } int endX = rect.x() + rect.width(); - if (endX > m_size.width()) - endX = m_size.width(); + if (endX > size.width()) + endX = size.width(); int numColumns = endX - originX; int originY = rect.y(); @@ -148,11 +148,10 @@ PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const originY = 0; } int endY = rect.y() + rect.height(); - if (endY > m_size.height()) - endY = m_size.height(); + if (endY > size.height()) + endY = size.height(); int numRows = endY - originY; - const SkBitmap& bitmap = *context()->platformContext()->bitmap(); ASSERT(bitmap.config() == SkBitmap::kARGB_8888_Config); SkAutoLockPixels bitmapLock(bitmap); @@ -162,6 +161,7 @@ PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const for (int y = 0; y < numRows; ++y) { uint32_t* srcRow = bitmap.getAddr32(originX, originY + y); for (int x = 0; x < numColumns; ++x) { + // TODO: Support for premultiplied colors SkColor color = SkPMColorToColor(srcRow[x]); unsigned char* destPixel = &destRow[x * 4]; destPixel[0] = SkColorGetR(color); @@ -175,8 +175,19 @@ PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const return result; } -void ImageBuffer::putImageData(ImageData* source, const IntRect& sourceRect, - const IntPoint& destPoint) +PassRefPtr<ImageData> ImageBuffer::getUnmultipliedImageData(const IntRect& rect) const +{ + return getImageData<Unmultiplied>(rect, *context()->platformContext()->bitmap(), m_size); +} + +PassRefPtr<ImageData> ImageBuffer::getPremultipliedImageData(const IntRect& rect) const +{ + return getImageData<Premultiplied>(rect, *context()->platformContext()->bitmap(), m_size); +} + +template <Multiply multiplied> +void putImageData(ImageData*& source, const IntRect& sourceRect, const IntPoint& destPoint, + const SkBitmap& bitmap, const IntSize& size) { ASSERT(sourceRect.width() > 0); ASSERT(sourceRect.height() > 0); @@ -184,27 +195,26 @@ void ImageBuffer::putImageData(ImageData* source, const IntRect& sourceRect, int originX = sourceRect.x(); int destX = destPoint.x() + sourceRect.x(); ASSERT(destX >= 0); - ASSERT(destX < m_size.width()); + ASSERT(destX < size.width()); ASSERT(originX >= 0); ASSERT(originX < sourceRect.right()); int endX = destPoint.x() + sourceRect.right(); - ASSERT(endX <= m_size.width()); + ASSERT(endX <= size.width()); int numColumns = endX - destX; int originY = sourceRect.y(); int destY = destPoint.y() + sourceRect.y(); ASSERT(destY >= 0); - ASSERT(destY < m_size.height()); + ASSERT(destY < size.height()); ASSERT(originY >= 0); ASSERT(originY < sourceRect.bottom()); int endY = destPoint.y() + sourceRect.bottom(); - ASSERT(endY <= m_size.height()); + ASSERT(endY <= size.height()); int numRows = endY - destY; - const SkBitmap& bitmap = *context()->platformContext()->bitmap(); ASSERT(bitmap.config() == SkBitmap::kARGB_8888_Config); SkAutoLockPixels bitmapLock(bitmap); @@ -215,6 +225,7 @@ void ImageBuffer::putImageData(ImageData* source, const IntRect& sourceRect, for (int y = 0; y < numRows; ++y) { uint32_t* destRow = bitmap.getAddr32(destX, destY + y); for (int x = 0; x < numColumns; ++x) { + // TODO: Support for premultiplied colors const unsigned char* srcPixel = &srcRow[x * 4]; destRow[x] = SkPreMultiplyARGB(srcPixel[3], srcPixel[0], srcPixel[1], srcPixel[2]); @@ -223,6 +234,16 @@ void ImageBuffer::putImageData(ImageData* source, const IntRect& sourceRect, } } +void ImageBuffer::putUnmultipliedImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint) +{ + putImageData<Unmultiplied>(source, sourceRect, destPoint, *context()->platformContext()->bitmap(), m_size); +} + +void ImageBuffer::putPremultipliedImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint) +{ + putImageData<Premultiplied>(source, sourceRect, destPoint, *context()->platformContext()->bitmap(), m_size); +} + String ImageBuffer::toDataURL(const String&) const { // Encode the image into a vector. diff --git a/WebCore/platform/graphics/skia/ImageSourceSkia.cpp b/WebCore/platform/graphics/skia/ImageSourceSkia.cpp deleted file mode 100644 index 1647b86..0000000 --- a/WebCore/platform/graphics/skia/ImageSourceSkia.cpp +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright (c) 2008, Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -#include "config.h" -#include "ImageSource.h" -#include "SharedBuffer.h" - -#include "GIFImageDecoder.h" -#include "ICOImageDecoder.h" -#include "JPEGImageDecoder.h" -#include "PNGImageDecoder.h" -#include "BMPImageDecoder.h" -#include "XBMImageDecoder.h" - -#include "SkBitmap.h" - -namespace WebCore { - -ImageDecoder* createDecoder(const Vector<char>& data) -{ - // We need at least 4 bytes to figure out what kind of image we're dealing with. - int length = data.size(); - if (length < 4) - return 0; - - const unsigned char* uContents = (const unsigned char*)data.data(); - const char* contents = data.data(); - - // GIFs begin with GIF8(7 or 9). - if (strncmp(contents, "GIF8", 4) == 0) - return new GIFImageDecoder(); - - // Test for PNG. - if (uContents[0]==0x89 && - uContents[1]==0x50 && - uContents[2]==0x4E && - uContents[3]==0x47) - return new PNGImageDecoder(); - - // JPEG - if (uContents[0]==0xFF && - uContents[1]==0xD8 && - uContents[2]==0xFF) - return new JPEGImageDecoder(); - - // BMP - if (strncmp(contents, "BM", 2) == 0) - return new BMPImageDecoder(); - - // ICOs always begin with a 2-byte 0 followed by a 2-byte 1. - // CURs begin with 2-byte 0 followed by 2-byte 2. - if (!memcmp(contents, "\000\000\001\000", 4) || - !memcmp(contents, "\000\000\002\000", 4)) - return new ICOImageDecoder(); - - // XBMs require 8 bytes of info. - if (length >= 8 && strncmp(contents, "#define ", 8) == 0) - return new XBMImageDecoder(); - - // Give up. We don't know what the heck this is. - return 0; -} - -ImageSource::ImageSource() - : m_decoder(0) -{} - -ImageSource::~ImageSource() -{ - clear(true); -} - -void ImageSource::clear(bool destroyAll, size_t clearBeforeFrame, SharedBuffer* data, bool allDataReceived) -{ - if (!destroyAll) { - if (m_decoder) - m_decoder->clearFrameBufferCache(clearBeforeFrame); - return; - } - - delete m_decoder; - m_decoder = 0; - if (data) - setData(data, allDataReceived); -} - -bool ImageSource::initialized() const -{ - return m_decoder; -} - -void ImageSource::setData(SharedBuffer* data, bool allDataReceived) -{ - // Make the decoder by sniffing the bytes. - // This method will examine the data and instantiate an instance of the appropriate decoder plugin. - // If insufficient bytes are available to determine the image type, no decoder plugin will be - // made. - if (!m_decoder) - m_decoder = createDecoder(data->buffer()); - - // CreateDecoder will return NULL if the decoder could not be created. Plus, - // we should not send more data to a decoder which has already decided it - // has failed. - if (!m_decoder || m_decoder->failed()) - return; - m_decoder->setData(data, allDataReceived); -} - -bool ImageSource::isSizeAvailable() -{ - if (!m_decoder) - return false; - - return m_decoder->isSizeAvailable(); -} - -IntSize ImageSource::size() const -{ - if (!m_decoder) - return IntSize(); - - return m_decoder->size(); -} - -IntSize ImageSource::frameSizeAtIndex(size_t index) const -{ - if (!m_decoder) - return IntSize(); - - return m_decoder->frameSizeAtIndex(index); -} - -int ImageSource::repetitionCount() -{ - if (!m_decoder) - return cAnimationNone; - - return m_decoder->repetitionCount(); -} - -size_t ImageSource::frameCount() const -{ - if (!m_decoder) - return 0; - return m_decoder->failed() ? 0 : m_decoder->frameCount(); -} - -NativeImagePtr ImageSource::createFrameAtIndex(size_t index) -{ - if (!m_decoder) - return 0; - - // Note that the buffer can have NULL bytes even when it is marked as - // non-empty. It seems "FrameEmpty" is only set before the frame has been - // initialized. If it is decoded and it happens to be empty, it will be - // marked as "FrameComplete" but will still have NULL bytes. - RGBA32Buffer* buffer = m_decoder->frameBufferAtIndex(index); - if (!buffer || buffer->status() == RGBA32Buffer::FrameEmpty) - return 0; - - // Copy the bitmap. The pixel data is refcounted internally by SkBitmap, so - // this doesn't cost much. - return buffer->asNewNativeImage(); -} - -bool ImageSource::frameIsCompleteAtIndex(size_t index) -{ - if (!m_decoder) - return false; - - RGBA32Buffer* buffer = m_decoder->frameBufferAtIndex(index); - return buffer && buffer->status() == RGBA32Buffer::FrameComplete; -} - -float ImageSource::frameDurationAtIndex(size_t index) -{ - if (!m_decoder) - return 0; - - RGBA32Buffer* buffer = m_decoder->frameBufferAtIndex(index); - if (!buffer || buffer->status() == RGBA32Buffer::FrameEmpty) - return 0; - - // Many annoying ads specify a 0 duration to make an image flash as quickly - // as possible. We follow WinIE's behavior and use a duration of 100 ms - // for any frames that specify a duration of <= 50 ms. See - // <http://bugs.webkit.org/show_bug.cgi?id=14413> or Radar 4051389 for - // more. - const float duration = buffer->duration() / 1000.0f; - return (duration < 0.051f) ? 0.100f : duration; -} - -bool ImageSource::frameHasAlphaAtIndex(size_t index) -{ - if (!m_decoder || !m_decoder->supportsAlpha()) - return false; - - RGBA32Buffer* buffer = m_decoder->frameBufferAtIndex(index); - if (!buffer || buffer->status() == RGBA32Buffer::FrameEmpty) - return false; - - return buffer->hasAlpha(); -} - -String ImageSource::filenameExtension() const -{ - return m_decoder ? m_decoder->filenameExtension() : String(); -} - -} diff --git a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp index e0a292c..bf6bae2 100644 --- a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp +++ b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp @@ -295,7 +295,7 @@ void PlatformContextSkia::drawRect(SkRect rect) void PlatformContextSkia::setupPaintCommon(SkPaint* paint) const { -#ifdef SK_DEBUGx +#ifdef SK_DEBUG { SkPaint defaultPaint; SkASSERT(*paint == defaultPaint); diff --git a/WebCore/platform/graphics/wince/ColorWince.cpp b/WebCore/platform/graphics/wince/ColorWince.cpp new file mode 100644 index 0000000..820b9d2 --- /dev/null +++ b/WebCore/platform/graphics/wince/ColorWince.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2007-2008 Torch Mobile, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#include "config.h" +#include "Color.h" + +#include "NotImplemented.h" + +namespace WebCore { + +Color focusRingColor() +{ + return Color(0, 0, 0); +} + +void setFocusRingColorChangeFunction(void (*)()) +{ + notImplemented(); +} + +} // namespace WebCore diff --git a/WebCore/platform/graphics/wince/GradientWince.cpp b/WebCore/platform/graphics/wince/GradientWince.cpp new file mode 100644 index 0000000..49fa970 --- /dev/null +++ b/WebCore/platform/graphics/wince/GradientWince.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2009 Torch Mobile, Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + + +#include "config.h" +#include "Gradient.h" + +#include "GraphicsContext.h" + +namespace WebCore { + +void Gradient::platformDestroy() +{ +} + +static inline bool compareStops(const Gradient::ColorStop& a, const Gradient::ColorStop& b) +{ + return a.stop < b.stop; +} + +const Vector<Gradient::ColorStop>& Gradient::getStops() const +{ + if (!m_stopsSorted) { + if (m_stops.size()) + std::stable_sort(m_stops.begin(), m_stops.end(), compareStops); + m_stopsSorted = true; + } + return m_stops; +} + +void Gradient::fill(GraphicsContext* c, const FloatRect& r) +{ + c->fillRect(r, this); +} + +} diff --git a/WebCore/platform/graphics/wince/MediaPlayerPrivateWince.h b/WebCore/platform/graphics/wince/MediaPlayerPrivateWince.h new file mode 100644 index 0000000..ff38ada --- /dev/null +++ b/WebCore/platform/graphics/wince/MediaPlayerPrivateWince.h @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef MediaPlayerPrivateWince_h +#define MediaPlayerPrivateWince_h + +#if ENABLE(VIDEO) + +#include "MediaPlayerPrivate.h" +#include "Timer.h" +#include <wtf/OwnPtr.h> + +namespace WebCore { + + class GraphicsContext; + class IntSize; + class IntRect; + class String; + + class MediaPlayerPrivate : public MediaPlayerPrivateInterface { + public: + static void registerMediaEngine(MediaEngineRegistrar); + + ~MediaPlayerPrivate(); + + IntSize naturalSize() const; + bool hasVideo() const; + + void load(const String& url); + void cancelLoad(); + + void play(); + void pause(); + + bool paused() const; + bool seeking() const; + + float duration() const; + float currentTime() const; + void seek(float time); + void setEndTime(float); + + void setRate(float); + void setVolume(float); + + int dataRate() const; + + MediaPlayer::NetworkState networkState() const { return m_networkState; } + MediaPlayer::ReadyState readyState() const { return m_readyState; } + + float maxTimeBuffered() const; + float maxTimeSeekable() const; + unsigned bytesLoaded() const; + bool totalBytesKnown() const; + unsigned totalBytes() const; + + void setVisible(bool); + void setSize(const IntSize&); + + void loadStateChanged(); + void didEnd(); + + void paint(GraphicsContext*, const IntRect&); + + private: + MediaPlayerPrivate(MediaPlayer*); + + void updateStates(); + void doSeek(); + void cancelSeek(); + void seekTimerFired(Timer<MediaPlayerPrivate>*); + float maxTimeLoaded() const; + void sawUnsupportedTracks(); +#if ENABLE(PLUGIN_PROXY_FOR_VIDEO) + void setMediaPlayerProxy(WebMediaPlayerProxy*); + void setPoster(const String& url); + void deliverNotification(MediaPlayerProxyNotificationType); +#endif + + // engine support + static MediaPlayerPrivateInterface* create(MediaPlayer*); + static void getSupportedTypes(HashSet<String>& types); + static MediaPlayer::SupportsType supportsType(const String& type, const String& codecs); + static bool isAvailable(); + + MediaPlayer* m_player; + float m_seekTo; + float m_endTime; + Timer<MediaPlayerPrivate> m_seekTimer; + MediaPlayer::NetworkState m_networkState; + MediaPlayer::ReadyState m_readyState; + unsigned m_enabledTrackCount; + unsigned m_totalTrackCount; + bool m_hasUnsupportedTracks; + bool m_startedPlaying; + bool m_isStreaming; +#if ENABLE(PLUGIN_PROXY_FOR_VIDEO) + WebMediaPlayerProxy* m_proxy; +#endif + }; + +} + +#endif + +#endif diff --git a/WebCore/platform/graphics/wince/MediaPlayerProxy.cpp b/WebCore/platform/graphics/wince/MediaPlayerProxy.cpp new file mode 100644 index 0000000..9673d18 --- /dev/null +++ b/WebCore/platform/graphics/wince/MediaPlayerProxy.cpp @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2009 Torch Mobile, Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#if ENABLE(VIDEO) + +#include "config.h" +#include "MediaPlayerProxy.h" + +#include "c_class.h" +#include "c_instance.h" +#include "c_runtime.h" +#include "DocumentLoader.h" +#include "HTMLPlugInElement.h" +#include "HTMLVideoElement.h" +#include "JSDOMBinding.h" +#include "JSPluginElementFunctions.h" +#include "MediaPlayer.h" +#include "Node.h" +#include "npruntime_impl.h" +#include "PlatformString.h" +#include "PluginView.h" +#include "RenderPartObject.h" +#include "RenderWidget.h" +#include "runtime.h" +#include <runtime/Identifier.h> +#include "Widget.h" + +using namespace JSC; + +namespace WebCore { + +using namespace Bindings; +using namespace HTMLNames; + +WebMediaPlayerProxy::WebMediaPlayerProxy(MediaPlayer* player) + : m_mediaPlayer(player) + , m_init(false) + , m_hasSentResponseToPlugin(false) +{ + if (!m_init) + initEngine(); +} + +WebMediaPlayerProxy::~WebMediaPlayerProxy() +{ + m_instance.release(); +} + +ScriptInstance WebMediaPlayerProxy::pluginInstance() +{ + if (!m_instance) { + RenderObject* r = element()->renderer(); + if (!r || !r->isWidget()) + return 0; + + Frame* frame = element()->document()->frame(); + + RenderWidget* renderWidget = static_cast<RenderWidget*>(element()->renderer()); + if (renderWidget && renderWidget->widget()) + m_instance = frame->script()->createScriptInstanceForWidget(renderWidget->widget()); + } + + return m_instance; +} + +void WebMediaPlayerProxy::load(const String& url) +{ + if (!m_init) + initEngine(); + if (m_init) + invokeMethod("play"); +} + +void WebMediaPlayerProxy::initEngine() +{ + HTMLMediaElement* element = static_cast<HTMLMediaElement*>(m_mediaPlayer->mediaPlayerClient()); + String url = element->initialURL(); + + if (url.isEmpty()) + return; + + Frame* frame = element->document()->frame(); + Vector<String> paramNames; + Vector<String> paramValues; + String serviceType; + + // add all attributes set on the embed object + if (NamedNodeMap* attributes = element->attributes()) { + for (unsigned i = 0; i < attributes->length(); ++i) { + Attribute* it = attributes->attributeItem(i); + paramNames.append(it->name().localName().string()); + paramValues.append(it->value().string()); + } + } + serviceType = "application/x-mplayer2"; + frame->loader()->requestObject(static_cast<RenderPartObject*>(element->renderer()), url, nullAtom, serviceType, paramNames, paramValues); + m_init = true; + +} + +HTMLMediaElement* WebMediaPlayerProxy::element() +{ + return static_cast<HTMLMediaElement*>(m_mediaPlayer->mediaPlayerClient()); + +} + +void WebMediaPlayerProxy::invokeMethod(const String& methodName) +{ + Frame* frame = element()->document()->frame(); + RootObject *root = frame->script()->bindingRootObject(); + if (!root) + return; + ExecState *exec = root->globalObject()->globalExec(); + Instance* instance = pluginInstance().get(); + if (!instance) + return; + + instance->begin(); + Class *aClass = instance->getClass(); + Identifier iden(exec, methodName); + MethodList methodList = aClass->methodsNamed(iden, instance); + ArgList args; + instance->invokeMethod(exec, methodList , args); + instance->end(); +} + +} + +#endif diff --git a/WebCore/platform/graphics/wince/MediaPlayerProxy.h b/WebCore/platform/graphics/wince/MediaPlayerProxy.h new file mode 100644 index 0000000..05f9b21 --- /dev/null +++ b/WebCore/platform/graphics/wince/MediaPlayerProxy.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2009 Torch Mobile, Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + + +#ifndef MediaPlayerProxy_h +#define MediaPlayerProxy_h + +#if ENABLE(VIDEO) + +#include "ScriptInstance.h" + +namespace WebCore { + + class IntRect; + class IntSize; + class String; + class MediaPlayer; + class PluginView; + class HTMLMediaElement; + + enum MediaPlayerProxyNotificationType { + MediaPlayerNotificationPlayPauseButtonPressed, + Idle, + Loading, + Loaded, + FormatError, + NetworkError, + DecodeError + }; + + class WebMediaPlayerProxy { + public: + WebMediaPlayerProxy(MediaPlayer* player); + ~WebMediaPlayerProxy(); + + MediaPlayer* mediaPlayer() {return m_mediaPlayer;} + void initEngine(); + void load(const String& url); + HTMLMediaElement* element(); + void invokeMethod(const String& methodName); + ScriptInstance pluginInstance(); + + private: + MediaPlayer* m_mediaPlayer; + bool m_init; + WebCore::PluginView* m_pluginView; + bool m_hasSentResponseToPlugin; + ScriptInstance m_instance; + }; + +} +#endif // ENABLE(VIDEO) + +#endif diff --git a/WebCore/platform/graphics/wince/PathWince.cpp b/WebCore/platform/graphics/wince/PathWince.cpp new file mode 100644 index 0000000..7589ccb --- /dev/null +++ b/WebCore/platform/graphics/wince/PathWince.cpp @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2007-2009 Torch Mobile, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "Path.h" + +#include "FloatRect.h" +#include "NotImplemented.h" +#include "PlatformPathWince.h" +#include "PlatformString.h" +#include "TransformationMatrix.h" +#include <wtf/OwnPtr.h> + +namespace WebCore { + +Path::Path() + : m_path(new PlatformPath()) +{ +} + +Path::Path(const Path& other) + : m_path(new PlatformPath(*other.m_path)) +{ +} + +Path::~Path() +{ + delete m_path; +} + +Path& Path::operator=(const Path& other) +{ + if (&other != this) { + delete m_path; + m_path = new PlatformPath(*other.m_path); + } + return *this; +} + +bool Path::contains(const FloatPoint& point, WindRule rule) const +{ + return m_path->contains(point, rule); +} + +void Path::translate(const FloatSize& size) +{ + m_path->translate(size); +} + +FloatRect Path::boundingRect() const +{ + return m_path->boundingRect(); +} + +void Path::moveTo(const FloatPoint& point) +{ + m_path->moveTo(point); +} + +void Path::addLineTo(const FloatPoint& point) +{ + m_path->addLineTo(point); +} + +void Path::addQuadCurveTo(const FloatPoint& cp, const FloatPoint& p) +{ + m_path->addQuadCurveTo(cp, p); +} + +void Path::addBezierCurveTo(const FloatPoint& cp1, const FloatPoint& cp2, const FloatPoint& p) +{ + m_path->addBezierCurveTo(cp1, cp2, p); +} + +void Path::addArcTo(const FloatPoint& p1, const FloatPoint& p2, float radius) +{ + m_path->addArcTo(p1, p2, radius); +} + +void Path::closeSubpath() +{ + m_path->closeSubpath(); +} + +void Path::addArc(const FloatPoint& p, float r, float sar, float ear, bool anticlockwise) +{ + m_path->addEllipse(p, r, r, sar, ear, anticlockwise); +} + +void Path::addRect(const FloatRect& r) +{ + m_path->addRect(r); +} + +void Path::addEllipse(const FloatRect& r) +{ + m_path->addEllipse(r); +} + +void Path::clear() +{ + m_path->clear(); +} + +bool Path::isEmpty() const +{ + return m_path->isEmpty(); +} + +String Path::debugString() const +{ + return m_path->debugString(); +} + +void Path::apply(void* info, PathApplierFunction function) const +{ + m_path->apply(info, function); +} + +void Path::transform(const TransformationMatrix& t) +{ + m_path->transform(t); +} + +FloatRect Path::strokeBoundingRect(StrokeStyleApplier *) +{ + notImplemented(); + return FloatRect(); +} + +bool Path::strokeContains(StrokeStyleApplier*, const FloatPoint&) const +{ + notImplemented(); + return false; +} + +bool Path::hasCurrentPoint() const +{ + // Not sure if this is correct. At the meantime, we do what other ports + // do. + // See https://bugs.webkit.org/show_bug.cgi?id=27266, + // https://bugs.webkit.org/show_bug.cgi?id=27187, and + // http://trac.webkit.org/changeset/45873 + return !isEmpty(); +} + +} diff --git a/WebCore/platform/graphics/wince/PlatformPathWince.cpp b/WebCore/platform/graphics/wince/PlatformPathWince.cpp new file mode 100644 index 0000000..66fad50 --- /dev/null +++ b/WebCore/platform/graphics/wince/PlatformPathWince.cpp @@ -0,0 +1,810 @@ +/* + * Copyright (C) 2007-2009 Torch Mobile, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "PlatformPathWince.h" + +#include "FloatRect.h" +#include "GraphicsContext.h" +#include "Path.h" +#include "PlatformString.h" +#include "TransformationMatrix.h" +#include "WinceGraphicsExtras.h" +#include <wtf/MathExtras.h> +#include <wtf/OwnPtr.h> + +#include <windows.h> + +namespace WebCore { + +// Implemented in GraphicsContextWince.cpp +void getEllipsePointByAngle(double angle, double a, double b, float& x, float& y); + +static void quadCurve(int segments, Vector<PathPoint>& pts, const PathPoint* control) +{ + const float step = 1.0 / segments; + register float tA = 0.0; + register float tB = 1.0; + + float c1x = control[0].x(); + float c1y = control[0].y(); + float c2x = control[1].x(); + float c2y = control[1].y(); + float c3x = control[2].x(); + float c3y = control[2].y(); + + const int offset = pts.size(); + pts.resize(offset + segments); + PathPoint pp; + pp.m_x = c1x; + pp.m_y = c1y; + + for (int i = 1; i < segments; ++i) { + tA += step; + tB -= step; + + const float a = tB * tB; + const float b = 2.0 * tA * tB; + const float c = tA * tA; + + pp.m_x = c1x * a + c2x * b + c3x * c; + pp.m_y = c1y * a + c2y * b + c3y * c; + + pts[offset + i - 1] = pp; + } + + pp.m_x = c3x; + pp.m_y = c3y; + pts[offset + segments - 1] = pp; +} + +static inline void bezier(int segments, Vector<PathPoint>& pts, const PathPoint* control) +{ + const float step = 1.0 / segments; + register float tA = 0.0; + register float tB = 1.0; + + float c1x = control[0].x(); + float c1y = control[0].y(); + float c2x = control[1].x(); + float c2y = control[1].y(); + float c3x = control[2].x(); + float c3y = control[2].y(); + float c4x = control[3].x(); + float c4y = control[3].y(); + + const int offset = pts.size(); + pts.resize(offset + segments); + PathPoint pp; + pp.m_x = c1x; + pp.m_y = c1y; + + for (int i = 1; i < segments; ++i) { + tA += step; + tB -= step; + const float tAsq = tA * tA; + const float tBsq = tB * tB; + + const float a = tBsq * tB; + const float b = 3.0 * tA * tBsq; + const float c = 3.0 * tB * tAsq; + const float d = tAsq * tA; + + pp.m_x = c1x * a + c2x * b + c3x * c + c4x * d; + pp.m_y = c1y * a + c2y * b + c3y * c + c4y * d; + + pts[offset + i - 1] = pp; + } + + pp.m_x = c4x; + pp.m_y = c4y; + pts[offset + segments - 1] = pp; +} + +static bool containsPoint(const FloatRect& r, const FloatPoint& p) +{ + return p.x() >= r.x() && p.y() >= r.y() && p.x() < r.right() && p.y() < r.bottom(); +} + +static void normalizeAngle(float& angle) +{ + angle = fmod(angle, 2 * piFloat); + if (angle < 0) + angle += 2 * piFloat; + if (angle < 0.00001f) + angle = 0; +} + +static void transformArcPoint(float& x, float& y, const FloatPoint& c) +{ + x += c.x(); + y += c.y(); +} + +static void inflateRectToContainPoint(FloatRect& r, float x, float y) +{ + if (r.isEmpty()) { + r.setX(x); + r.setY(y); + r.setSize(FloatSize(1, 1)); + return; + } + if (x < r.x()) { + r.setWidth(r.right() - x); + r.setX(x); + } else { + float w = x - r.x() + 1; + if (w > r.width()) + r.setWidth(w); + } + if (y < r.y()) { + r.setHeight(r.bottom() - y); + r.setY(y); + } else { + float h = y - r.y() + 1; + if (h > r.height()) + r.setHeight(h); + } +} + +// return 0-based value: 0 - first Quadrant ( 0 - 90 degree) +static inline int quadrant(const PathPoint& point, const PathPoint& origin) +{ + return point.m_x < origin.m_x ? + (point.m_y < origin.m_y ? 2 : 1) + : (point.m_y < origin.m_y ? 3 : 0); +} + +static inline bool isQuadrantOnLeft(int q) { return q == 1 || q == 2; } +static inline bool isQuadrantOnRight(int q) { return q == 0 || q == 3; } +static inline bool isQuadrantOnTop(int q) { return q == 2 || q == 3; } +static inline bool isQuadrantOnBottom(int q) { return q == 0 || q == 1; } + +static inline int nextQuadrant(int q) { return q == 3 ? 0 : q + 1; } +static inline int quadrantDiff(int q1, int q2) +{ + int d = q1 - q2; + while (d < 0) + d += 4; + return d; +} + +struct PathVector { + float m_x; + float m_y; + + PathVector() : m_x(0), m_y(0) {} + PathVector(float x, float y) : m_x(x), m_y(y) {} + double angle() const { return atan2(m_y, m_x); } + operator double () const { return angle(); } + double length() const { return _hypot(m_x, m_y); } +}; + +PathVector operator-(const PathPoint& p1, const PathPoint& p2) +{ + return PathVector(p1.m_x - p2.m_x, p1.m_y - p2.m_y); +} + +static void addArcPoint(PathPolygon& poly, const PathPoint& center, const PathPoint& radius, double angle) +{ + PathPoint p; + getEllipsePointByAngle(angle, radius.m_x, radius.m_y, p.m_x, p.m_y); + transformArcPoint(p.m_x, p.m_y, center); + if (poly.isEmpty() || poly.last() != p) + poly.append(p); +} + +static void addArcPoints(PathPolygon& poly, const PlatformPathElement::ArcTo& data) +{ + const PathPoint& startPoint = poly.last(); + double curAngle = startPoint - data.m_center; + double endAngle = data.m_end - data.m_center; + double angleStep = 2. / std::max(data.m_radius.m_x, data.m_radius.m_y); + if (data.m_clockwise) { + if (endAngle <= curAngle || startPoint == data.m_end) + endAngle += 2 * piDouble; + } else { + angleStep = -angleStep; + if (endAngle >= curAngle || startPoint == data.m_end) + endAngle -= 2 * piDouble; + } + + for (curAngle += angleStep; data.m_clockwise ? curAngle < endAngle : curAngle > endAngle; curAngle += angleStep) + addArcPoint(poly, data.m_center, data.m_radius, curAngle); + + if (poly.isEmpty() || poly.last() != data.m_end) + poly.append(data.m_end); +} + +static void drawPolygons(HDC dc, const Vector<PathPolygon>& polygons, bool fill, const TransformationMatrix* transformation) +{ + MemoryAllocationCanFail canFail; + for (Vector<PathPolygon>::const_iterator i = polygons.begin(); i != polygons.end(); ++i) { + int npoints = i->size(); + if (!npoints) + continue; + + POINT* winPoints = 0; + if (fill) { + if (npoints > 2) + winPoints = new POINT[npoints + 1]; + } else + winPoints = new POINT[npoints]; + + if (winPoints) { + if (transformation) { + for (int i2 = 0; i2 < npoints; ++i2) { + FloatPoint trPoint = transformation->mapPoint(i->at(i2)); + winPoints[i2].x = stableRound(trPoint.x()); + winPoints[i2].y = stableRound(trPoint.y()); + } + } else { + for (int i2 = 0; i2 < npoints; ++i2) { + winPoints[i2].x = stableRound(i->at(i2).x()); + winPoints[i2].y = stableRound(i->at(i2).y()); + } + } + + if (fill && winPoints[npoints - 1] != winPoints[0]) { + winPoints[npoints].x = winPoints[0].x; + winPoints[npoints].y = winPoints[0].y; + ++npoints; + } + + if (fill) + ::Polygon(dc, winPoints, npoints); + else + ::Polyline(dc, winPoints, npoints); + delete[] winPoints; + } + } +} + + +int PlatformPathElement::numControlPoints() const +{ + switch (m_type) { + case PathMoveTo: + case PathLineTo: + return 1; + case PathQuadCurveTo: + case PathArcTo: + return 2; + case PathBezierCurveTo: + return 3; + default: + ASSERT(m_type == PathCloseSubpath); + return 0; + } +} + +int PlatformPathElement::numPoints() const +{ + switch (m_type) { + case PathMoveTo: + case PathLineTo: + case PathArcTo: + return 1; + case PathQuadCurveTo: + return 2; + case PathBezierCurveTo: + return 3; + default: + ASSERT(m_type == PathCloseSubpath); + return 0; + } +} + +void PathPolygon::move(const FloatSize& offset) +{ + for (Vector<PathPoint>::iterator i = begin(); i < end(); ++i) + i->move(offset); +} + +void PathPolygon::transform(const TransformationMatrix& t) +{ + for (Vector<PathPoint>::iterator i = begin(); i < end(); ++i) + *i = t.mapPoint(*i); +} + +bool PathPolygon::contains(const FloatPoint& point) const +{ + if (size() < 3) + return false; + + // Test intersections between the polygon and the vertical line: x = point.x() + + int intersected = 0; + const PathPoint* point1 = &last(); + Vector<PathPoint>::const_iterator last = end(); + // wasNegative: -1 means unknown, 0 means false, 1 means true. + int wasNegative = -1; + for (Vector<PathPoint>::const_iterator i = begin(); i != last; ++i) { + const PathPoint& point2 = *i; + if (point1->x() != point.x()) { + if (point2.x() == point.x()) { + // We are getting on the vertical line + wasNegative = point1->x() < point.x() ? 1 : 0; + } else if (point2.x() < point.x() != point1->x() < point.x()) { + float y = (point2.y() - point1->y()) / (point2.x() - point1->x()) * (point.x() - point1->x()) + point1->y(); + if (y >= point.y()) + ++intersected; + } + } else { + // We were on the vertical line + + // handle special case + if (point1->y() == point.y()) + return true; + + if (point1->y() > point.y()) { + if (point2.x() == point.x()) { + // see if the point is on this segment + if (point2.y() <= point.y()) + return true; + + // We are still on the line + } else { + // We are leaving the line now. + // We have to get back to see which side we come from. If we come from + // the same side we are leaving, no intersection should be counted + if (wasNegative < 0) { + Vector<PathPoint>::const_iterator jLast = i; + Vector<PathPoint>::const_iterator j = i; + do { + if (j == begin()) + j = last; + else + --j; + if (j->x() != point.x()) { + if (j->x() > point.x()) + wasNegative = 0; + else + wasNegative = 1; + break; + } + } while (j != jLast); + + if (wasNegative < 0) + return false; + } + if (wasNegative ? point2.x() > point.x() : point2.x() < point.x()) + ++intersected; + } + } else if (point2.x() == point.x() && point2.y() >= point.y()) + return true; + } + point1 = &point2; + } + + return intersected & 1; +} + +void PlatformPathElement::move(const FloatSize& offset) +{ + int n = numControlPoints(); + for (int i = 0; i < n; ++i) + m_data.m_points[i].move(offset); +} + +void PlatformPathElement::transform(const TransformationMatrix& t) +{ + int n = numControlPoints(); + for (int i = 0; i < n; ++i) { + FloatPoint p = t.mapPoint(m_data.m_points[i]); + m_data.m_points[i].set(p.x(), p.y()); + } +} + +void PlatformPathElement::inflateRectToContainMe(FloatRect& r, const FloatPoint& lastPoint) const +{ + if (m_type == PathArcTo) { + const ArcTo& data = m_data.m_arcToData; + PathPoint startPoint; + startPoint = lastPoint; + PathPoint endPoint = data.m_end; + if (!data.m_clockwise) + std::swap(startPoint, endPoint); + + int q0 = quadrant(startPoint, data.m_center); + int q1 = quadrant(endPoint, data.m_center); + bool containsExtremes[4] = { false }; // bottom, left, top, right + static const PathPoint extremeVectors[4] = { { 0, 1 }, { -1, 0 }, { 0, -1 }, { 1, 0 } }; + if (q0 == q1) { + if (startPoint.m_x == endPoint.m_x || isQuadrantOnBottom(q0) != startPoint.m_x > endPoint.m_x) { + for (int i = 0; i < 4; ++i) + containsExtremes[i] = true; + } + } else { + int extreme = q0; + int diff = quadrantDiff(q1, q0); + for (int i = 0; i < diff; ++i) { + containsExtremes[extreme] = true; + extreme = nextQuadrant(extreme); + } + } + + inflateRectToContainPoint(r, startPoint.m_x, startPoint.m_y); + inflateRectToContainPoint(r, endPoint.m_x, endPoint.m_y); + for (int i = 0; i < 4; ++i) { + if (containsExtremes[i]) + inflateRectToContainPoint(r, data.m_center.m_x + data.m_radius.m_x * extremeVectors[i].m_x, data.m_center.m_y + data.m_radius.m_y * extremeVectors[i].m_y); + } + } else { + int n = numPoints(); + for (int i = 0; i < n; ++i) + inflateRectToContainPoint(r, m_data.m_points[i].m_x, m_data.m_points[i].m_y); + } +} + +PathElementType PlatformPathElement::type() const +{ + switch (m_type) { + case PathMoveTo: + return PathElementMoveToPoint; + case PathLineTo: + return PathElementAddLineToPoint; + case PathArcTo: + // FIXME: there's no arcTo type for PathElement + return PathElementAddLineToPoint; + // return PathElementAddQuadCurveToPoint; + case PathQuadCurveTo: + return PathElementAddQuadCurveToPoint; + case PathBezierCurveTo: + return PathElementAddCurveToPoint; + default: + ASSERT(m_type == PathCloseSubpath); + return PathElementCloseSubpath; + } +} + +PlatformPath::PlatformPath() + : m_penLifted(true) +{ + m_currentPoint.clear(); +} + +void PlatformPath::ensureSubpath() +{ + if (m_penLifted) { + m_penLifted = false; + m_subpaths.append(PathPolygon()); + m_subpaths.last().append(m_currentPoint); + } else + ASSERT(!m_subpaths.isEmpty()); +} + +void PlatformPath::addToSubpath(const PlatformPathElement& e) +{ + if (e.platformType() == PlatformPathElement::PathMoveTo) { + m_penLifted = true; + m_currentPoint = e.pointAt(0); + } else if (e.platformType() == PlatformPathElement::PathCloseSubpath) { + m_penLifted = true; + if (!m_subpaths.isEmpty()) { + if (m_currentPoint != m_subpaths.last()[0]) { + // According to W3C, we have to draw a line from current point to the initial point + m_subpaths.last().append(m_subpaths.last()[0]); + m_currentPoint = m_subpaths.last()[0]; + } + } else + m_currentPoint.clear(); + } else { + ensureSubpath(); + switch (e.platformType()) { + case PlatformPathElement::PathLineTo: + m_subpaths.last().append(e.pointAt(0)); + break; + case PlatformPathElement::PathArcTo: + addArcPoints(m_subpaths.last(), e.arcTo()); + break; + case PlatformPathElement::PathQuadCurveTo: + { + PathPoint control[] = { + m_currentPoint, + e.pointAt(0), + e.pointAt(1), + }; + // FIXME: magic number? + quadCurve(50, m_subpaths.last(), control); + } + break; + case PlatformPathElement::PathBezierCurveTo: + { + PathPoint control[] = { + m_currentPoint, + e.pointAt(0), + e.pointAt(1), + e.pointAt(2), + }; + // FIXME: magic number? + bezier(100, m_subpaths.last(), control); + } + break; + default: + ASSERT_NOT_REACHED(); + break; + } + m_currentPoint = m_subpaths.last().last(); + } +} + +void PlatformPath::append(const PlatformPathElement& e) +{ + e.inflateRectToContainMe(m_boundingRect, lastPoint()); + addToSubpath(e); + m_elements.append(e); +} + +void PlatformPath::append(const PlatformPath& p) +{ + const PlatformPathElements& e = p.elements(); + for (PlatformPathElements::const_iterator it(e.begin()); it != e.end(); ++it) { + addToSubpath(*it); + it->inflateRectToContainMe(m_boundingRect, lastPoint()); + m_elements.append(*it); + } +} + +void PlatformPath::clear() +{ + m_elements.clear(); + m_boundingRect = FloatRect(); + m_subpaths.clear(); + m_currentPoint.clear(); + m_penLifted = true; +} + +void PlatformPath::strokePath(HDC dc, const TransformationMatrix* transformation) const +{ + drawPolygons(dc, m_subpaths, false, transformation); +} + +void PlatformPath::fillPath(HDC dc, const TransformationMatrix* transformation) const +{ + HGDIOBJ oldPen = SelectObject(dc, GetStockObject(NULL_PEN)); + drawPolygons(dc, m_subpaths, true, transformation); + SelectObject(dc, oldPen); +} + +void PlatformPath::translate(const FloatSize& size) +{ + for (PlatformPathElements::iterator it(m_elements.begin()); it != m_elements.end(); ++it) + it->move(size); + + m_boundingRect.move(size); + for (Vector<PathPolygon>::iterator it = m_subpaths.begin(); it != m_subpaths.end(); ++it) + it->move(size); +} + +void PlatformPath::transform(const TransformationMatrix& t) +{ + for (PlatformPathElements::iterator it(m_elements.begin()); it != m_elements.end(); ++it) + it->transform(t); + + m_boundingRect = t.mapRect(m_boundingRect); + for (Vector<PathPolygon>::iterator it = m_subpaths.begin(); it != m_subpaths.end(); ++it) + it->transform(t); +} + +bool PlatformPath::contains(const FloatPoint& point, WindRule rule) const +{ + // optimization: check the bounding rect first + if (!containsPoint(m_boundingRect, point)) + return false; + + for (Vector<PathPolygon>::const_iterator i = m_subpaths.begin(); i != m_subpaths.end(); ++i) { + if (i->contains(point)) + return true; + } + + return false; +} + +void PlatformPath::moveTo(const FloatPoint& point) +{ + PlatformPathElement::MoveTo data = { { point.x(), point.y() } }; + PlatformPathElement pe(data); + append(pe); +} + +void PlatformPath::addLineTo(const FloatPoint& point) +{ + PlatformPathElement::LineTo data = { { point.x(), point.y() } }; + PlatformPathElement pe(data); + append(pe); +} + +void PlatformPath::addQuadCurveTo(const FloatPoint& cp, const FloatPoint& p) +{ + PlatformPathElement::QuadCurveTo data = { { cp.x(), cp.y() }, { p.x(), p.y() } }; + PlatformPathElement pe(data); + append(pe); +} + +void PlatformPath::addBezierCurveTo(const FloatPoint& cp1, const FloatPoint& cp2, const FloatPoint& p) +{ + PlatformPathElement::BezierCurveTo data = { { cp1.x(), cp1.y() }, { cp2.x(), cp2.y() }, { p.x(), p.y() } }; + PlatformPathElement pe(data); + append(pe); +} + +void PlatformPath::addArcTo(const FloatPoint& fp1, const FloatPoint& fp2, float radius) +{ + const PathPoint& p0 = m_currentPoint; + PathPoint p1; + p1 = fp1; + PathPoint p2; + p2 = fp2; + if (!radius || p0 == p1 || p1 == p2) { + addLineTo(p1); + return; + } + + PathVector v01 = p0 - p1; + PathVector v21 = p2 - p1; + + // sin(A - B) = sin(A) * cos(B) - sin(B) * cos(A) + double cross = v01.m_x * v21.m_y - v01.m_y * v21.m_x; + + if (fabs(cross) < 1E-10) { + // on one line + addLineTo(p1); + return; + } + + double d01 = v01.length(); + double d21 = v21.length(); + double angle = (piDouble - abs(asin(cross / (d01 * d21)))) * 0.5; + double span = radius * tan(angle); + double rate = span / d01; + PathPoint startPoint; + startPoint.m_x = p1.m_x + v01.m_x * rate; + startPoint.m_y = p1.m_y + v01.m_y * rate; + + addLineTo(startPoint); + + PathPoint endPoint; + rate = span / d21; + endPoint.m_x = p1.m_x + v21.m_x * rate; + endPoint.m_y = p1.m_y + v21.m_y * rate; + + PathPoint midPoint; + midPoint.m_x = (startPoint.m_x + endPoint.m_x) * 0.5; + midPoint.m_y = (startPoint.m_y + endPoint.m_y) * 0.5; + + PathVector vm1 = midPoint - p1; + double dm1 = vm1.length(); + double d = _hypot(radius, span); + + PathPoint centerPoint; + rate = d / dm1; + centerPoint.m_x = p1.m_x + vm1.m_x * rate; + centerPoint.m_y = p1.m_y + vm1.m_y * rate; + + PlatformPathElement::ArcTo data = { + endPoint, + centerPoint, + { radius, radius }, + cross < 0 + }; + PlatformPathElement pe(data); + append(pe); +} + +void PlatformPath::closeSubpath() +{ + PlatformPathElement pe; + append(pe); +} + +// add a circular arc centred at p with radius r from start angle sar (radians) to end angle ear +void PlatformPath::addEllipse(const FloatPoint& p, float a, float b, float sar, float ear, bool anticlockwise) +{ + float startX, startY, endX, endY; + + normalizeAngle(sar); + normalizeAngle(ear); + + getEllipsePointByAngle(sar, a, b, startX, startY); + getEllipsePointByAngle(ear, a, b, endX, endY); + + transformArcPoint(startX, startY, p); + transformArcPoint(endX, endY, p); + + FloatPoint start(startX, startY); + moveTo(start); + + PlatformPathElement::ArcTo data = { { endX, endY }, { p.x(), p.y() }, { a, b }, !anticlockwise }; + PlatformPathElement pe(data); + append(pe); +} + + +void PlatformPath::addRect(const FloatRect& r) +{ + moveTo(r.location()); + + float right = r.right() - 1; + float bottom = r.bottom() - 1; + addLineTo(FloatPoint(right, r.y())); + addLineTo(FloatPoint(right, bottom)); + addLineTo(FloatPoint(r.x(), bottom)); + addLineTo(r.location()); +} + +void PlatformPath::addEllipse(const FloatRect& r) +{ + FloatSize radius(r.width() * 0.5, r.height() * 0.5); + addEllipse(r.location() + radius, radius.width(), radius.height(), 0, 0, true); +} + +String PlatformPath::debugString() const +{ + String ret; + for (PlatformPathElements::const_iterator i(m_elements.begin()); i != m_elements.end(); ++i) { + switch (i->platformType()) { + case PlatformPathElement::PathMoveTo: + case PlatformPathElement::PathLineTo: + ret += String::format("M %f %f\n", i->pointAt(0).m_x, i->pointAt(0).m_y); + break; + case PlatformPathElement::PathArcTo: + ret += String::format("A %f %f %f %f %f %f %c\n" + , i->arcTo().m_end.m_x, i->arcTo().m_end.m_y + , i->arcTo().m_center.m_x, i->arcTo().m_center.m_y + , i->arcTo().m_radius.m_x, i->arcTo().m_radius.m_y + , i->arcTo().m_clockwise? 'Y' : 'N'); + break; + case PlatformPathElement::PathQuadCurveTo: + ret += String::format("Q %f %f %f %f\n" + , i->pointAt(0).m_x, i->pointAt(0).m_y + , i->pointAt(1).m_x, i->pointAt(1).m_y); + break; + case PlatformPathElement::PathBezierCurveTo: + ret += String::format("B %f %f %f %f %f %f\n" + , i->pointAt(0).m_x, i->pointAt(0).m_y + , i->pointAt(1).m_x, i->pointAt(1).m_y + , i->pointAt(2).m_x, i->pointAt(2).m_y); + break; + default: + ASSERT(i->platformType() == PlatformPathElement::PathCloseSubpath); + ret += "S\n"; + break; + } + } + + return ret; +} + +void PlatformPath::apply(void* info, PathApplierFunction function) const +{ + PathElement pelement; + FloatPoint points[3]; + pelement.points = points; + + for (PlatformPathElements::const_iterator it(m_elements.begin()); it != m_elements.end(); ++it) { + pelement.type = it->type(); + int n = it->numPoints(); + for (int i = 0; i < n; ++i) + points[i] = it->pointAt(i); + function(info, &pelement); + } +} + +} // namespace Webcore diff --git a/WebCore/platform/graphics/wince/PlatformPathWince.h b/WebCore/platform/graphics/wince/PlatformPathWince.h new file mode 100644 index 0000000..fca00a7 --- /dev/null +++ b/WebCore/platform/graphics/wince/PlatformPathWince.h @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2007-2009 Torch Mobile, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef PlatformPathWince_h +#define PlatformPathWince_h + +namespace WebCore { + + class GraphicsContext; + + struct PathPoint { + float m_x; + float m_y; + const float& x() const { return m_x; } + const float& y() const { return m_y; } + void set(float x, float y) + { + m_x = x; + m_y = y; + }; + operator FloatPoint() const { return FloatPoint(m_x, m_y); } + void move(const FloatSize& offset) + { + m_x += offset.width(); + m_y += offset.height(); + } + PathPoint& operator=(const FloatPoint& p) + { + m_x = p.x(); + m_y = p.y(); + return *this; + } + void clear() { m_x = m_y = 0; } + }; + + struct PathPolygon: public Vector<PathPoint> { + void move(const FloatSize& offset); + void transform(const TransformationMatrix& t); + bool contains(const FloatPoint& point) const; + }; + + class PlatformPathElement { + public: + enum PlaformPathElementType { + PathMoveTo, + PathLineTo, + PathArcTo, + PathQuadCurveTo, + PathBezierCurveTo, + PathCloseSubpath, + }; + + struct MoveTo { + PathPoint m_end; + }; + + struct LineTo { + PathPoint m_end; + }; + + struct ArcTo { + PathPoint m_end; + PathPoint m_center; + PathPoint m_radius; + bool m_clockwise; + }; + + struct QuadCurveTo { + PathPoint m_point0; + PathPoint m_point1; + }; + + struct BezierCurveTo { + PathPoint m_point0; + PathPoint m_point1; + PathPoint m_point2; + }; + + PlatformPathElement(): m_type(PathCloseSubpath) { m_data.m_points[0].set(0, 0); } + PlatformPathElement(const MoveTo& data): m_type(PathMoveTo) { m_data.m_moveToData = data; } + PlatformPathElement(const LineTo& data): m_type(PathLineTo) { m_data.m_lineToData = data; } + PlatformPathElement(const ArcTo& data): m_type(PathArcTo) { m_data.m_arcToData = data; } + PlatformPathElement(const QuadCurveTo& data): m_type(PathQuadCurveTo) { m_data.m_quadCurveToData = data; } + PlatformPathElement(const BezierCurveTo& data): m_type(PathBezierCurveTo) { m_data.m_bezierCurveToData = data; } + + const MoveTo& moveTo() const { return m_data.m_moveToData; } + const LineTo& lineTo() const { return m_data.m_lineToData; } + const ArcTo& arcTo() const { return m_data.m_arcToData; } + const QuadCurveTo& quadCurveTo() const { return m_data.m_quadCurveToData; } + const BezierCurveTo& bezierCurveTo() const { return m_data.m_bezierCurveToData; } + const PathPoint& lastPoint() const + { + int n = numPoints(); + return n > 1 ? m_data.m_points[n - 1] : m_data.m_points[0]; + } + const PathPoint& pointAt(int index) const { return m_data.m_points[index]; } + int numPoints() const; + int numControlPoints() const; + void move(const FloatSize& offset); + void transform(const TransformationMatrix& t); + PathElementType type() const; + PlaformPathElementType platformType() const { return m_type; } + void inflateRectToContainMe(FloatRect& r, const FloatPoint& lastPoint) const; + + private: + PlaformPathElementType m_type; + union { + MoveTo m_moveToData; + LineTo m_lineToData; + ArcTo m_arcToData; + QuadCurveTo m_quadCurveToData; + BezierCurveTo m_bezierCurveToData; + PathPoint m_points[4]; + } m_data; + }; + + typedef Vector<PlatformPathElement> PlatformPathElements; + + class PlatformPath { + public: + PlatformPath(); + const PlatformPathElements& elements() const { return m_elements; } + void append(const PlatformPathElement& e); + void append(const PlatformPath& p); + void clear(); + bool isEmpty() const { return m_elements.isEmpty(); } + + void strokePath(HDC, const TransformationMatrix* tr) const; + void fillPath(HDC, const TransformationMatrix* tr) const; + FloatPoint lastPoint() const { return m_elements.isEmpty() ? FloatPoint(0, 0) : m_elements.last().lastPoint(); } + + const FloatRect& boundingRect() const { return m_boundingRect; } + bool contains(const FloatPoint& point, WindRule rule) const; + void translate(const FloatSize& size); + void transform(const TransformationMatrix& t); + + void moveTo(const FloatPoint&); + void addLineTo(const FloatPoint&); + void addQuadCurveTo(const FloatPoint& controlPoint, const FloatPoint& point); + void addBezierCurveTo(const FloatPoint& controlPoint1, const FloatPoint& controlPoint2, const FloatPoint&); + void addArcTo(const FloatPoint&, const FloatPoint&, float radius); + void closeSubpath(); + void addEllipse(const FloatPoint& p, float a, float b, float sar, float ear, bool anticlockwise); + void addRect(const FloatRect& r); + void addEllipse(const FloatRect& r); + String debugString() const; + void apply(void* info, PathApplierFunction function) const; + + private: + void ensureSubpath(); + void addToSubpath(const PlatformPathElement& e); + + PlatformPathElements m_elements; + FloatRect m_boundingRect; + Vector<PathPolygon> m_subpaths; + PathPoint m_currentPoint; + bool m_penLifted; + }; + +} + +#endif // PlatformPathWince_h diff --git a/WebCore/platform/graphics/wince/WinceGraphicsExtras.h b/WebCore/platform/graphics/wince/WinceGraphicsExtras.h new file mode 100644 index 0000000..2a6fae1 --- /dev/null +++ b/WebCore/platform/graphics/wince/WinceGraphicsExtras.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2007-2009 Torch Mobile, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef WinceGraphicsExtras_h +#define WinceGraphicsExtras_h + +// This file is used to contain small utilities used by WINCE graphics code. + +namespace WebCore { + // Always round to same direction. 0.5 is rounded to 1, + // and -0.5 (0.5 - 1) is rounded to 0 (1 - 1), so that it + // is consistent when transformation shifts. + static inline int stableRound(double d) + { + if (d > 0) + return static_cast<int>(d + 0.5); + + int i = static_cast<int>(d); + return i - d > 0.5 ? i - 1 : i; + } +} + +#endif WinceGraphicsExtras_h diff --git a/WebCore/platform/graphics/wx/ImageBufferWx.cpp b/WebCore/platform/graphics/wx/ImageBufferWx.cpp index e71dbde..49f3f3b 100644 --- a/WebCore/platform/graphics/wx/ImageBufferWx.cpp +++ b/WebCore/platform/graphics/wx/ImageBufferWx.cpp @@ -53,13 +53,24 @@ GraphicsContext* ImageBuffer::context() const return 0; } -PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect&) const +PassRefPtr<ImageData> ImageBuffer::getUnmultipliedImageData(const IntRect& rect) const { notImplemented(); return 0; } -void ImageBuffer::putImageData(ImageData*, const IntRect&, const IntPoint&) +PassRefPtr<ImageData> ImageBuffer::getPremultipliedImageData(const IntRect& rect) const +{ + notImplemented(); + return 0; +} + +void ImageBuffer::putUnmultipliedImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint) +{ + notImplemented(); +} + +void ImageBuffer::putPremultipliedImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint) { notImplemented(); } diff --git a/WebCore/platform/graphics/wx/ImageSourceWx.cpp b/WebCore/platform/graphics/wx/ImageSourceWx.cpp deleted file mode 100644 index 06c165d..0000000 --- a/WebCore/platform/graphics/wx/ImageSourceWx.cpp +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright (C) 2006, 2007 Apple Computer, Kevin Ollivier. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "ImageSource.h" - -#include "BMPImageDecoder.h" -#include "GIFImageDecoder.h" -#include "ICOImageDecoder.h" -#include "JPEGImageDecoder.h" -#include "NotImplemented.h" -#include "PNGImageDecoder.h" -#include "SharedBuffer.h" -#include "XBMImageDecoder.h" - -#include <wx/defs.h> -#include <wx/bitmap.h> -#if USE(WXGC) -#include <wx/graphics.h> -#endif -#include <wx/image.h> -#include <wx/rawbmp.h> - -namespace WebCore { - -ImageDecoder* createDecoder(const SharedBuffer& data) -{ - // We need at least 4 bytes to figure out what kind of image we're dealing with. - int length = data.size(); - if (length < 4) - return 0; - - const unsigned char* uContents = (const unsigned char*)data.data(); - const char* contents = data.data(); - - // GIFs begin with GIF8(7 or 9). - if (strncmp(contents, "GIF8", 4) == 0) - return new GIFImageDecoder(); - - // Test for PNG. - if (uContents[0]==0x89 && - uContents[1]==0x50 && - uContents[2]==0x4E && - uContents[3]==0x47) - return new PNGImageDecoder(); - - // JPEG - if (uContents[0]==0xFF && - uContents[1]==0xD8 && - uContents[2]==0xFF) - return new JPEGImageDecoder(); - - // BMP - if (strncmp(contents, "BM", 2) == 0) - return new BMPImageDecoder(); - - // ICOs always begin with a 2-byte 0 followed by a 2-byte 1. - // CURs begin with 2-byte 0 followed by 2-byte 2. - if (!memcmp(contents, "\000\000\001\000", 4) || - !memcmp(contents, "\000\000\002\000", 4)) - return new ICOImageDecoder(); - - // XBMs require 8 bytes of info. - if (length >= 8 && strncmp(contents, "#define ", 8) == 0) - return new XBMImageDecoder(); - - // Give up. We don't know what the heck this is. - return 0; -} - -ImageSource::ImageSource() - : m_decoder(0) -{} - -ImageSource::~ImageSource() -{ - clear(true); -} - -bool ImageSource::initialized() const -{ - return m_decoder; -} - -void ImageSource::setData(SharedBuffer* data, bool allDataReceived) -{ - // Make the decoder by sniffing the bytes. - // This method will examine the data and instantiate an instance of the appropriate decoder plugin. - // If insufficient bytes are available to determine the image type, no decoder plugin will be - // made. - if (m_decoder) - delete m_decoder; - m_decoder = createDecoder(*data); - if (!m_decoder) - return; - m_decoder->setData(data, allDataReceived); -} - -bool ImageSource::isSizeAvailable() -{ - if (!m_decoder) - return false; - - return m_decoder->isSizeAvailable(); -} - -IntSize ImageSource::size() const -{ - if (!m_decoder) - return IntSize(); - - return m_decoder->size(); -} - -IntSize ImageSource::frameSizeAtIndex(size_t index) const -{ - if (!m_decoder) - return IntSize(); - - return m_decoder->frameSizeAtIndex(index); -} - -int ImageSource::repetitionCount() -{ - if (!m_decoder) - return cAnimationNone; - - return m_decoder->repetitionCount(); -} - -String ImageSource::filenameExtension() const -{ - notImplemented(); - return String(); -} - -size_t ImageSource::frameCount() const -{ - return m_decoder ? m_decoder->frameCount() : 0; -} - -bool ImageSource::frameIsCompleteAtIndex(size_t index) -{ - // FIXME: should we be testing the RGBA32Buffer's status as well? - return (m_decoder && m_decoder->frameBufferAtIndex(index) != 0); -} - -void ImageSource::clear(bool destroyAll, size_t clearBeforeFrame, SharedBuffer* data, bool allDataReceived) -{ - if (!destroyAll) { - if (m_decoder) - m_decoder->clearFrameBufferCache(clearBeforeFrame); - return; - } - - delete m_decoder; - m_decoder = 0; - if (data) - setData(data, allDataReceived); -} - -NativeImagePtr ImageSource::createFrameAtIndex(size_t index) -{ - if (!m_decoder) - return 0; - - RGBA32Buffer* buffer = m_decoder->frameBufferAtIndex(index); - if (!buffer || buffer->status() == RGBA32Buffer::FrameEmpty) - return 0; - - return buffer->asNewNativeImage(); -} - -float ImageSource::frameDurationAtIndex(size_t index) -{ - if (!m_decoder) - return 0; - - RGBA32Buffer* buffer = m_decoder->frameBufferAtIndex(index); - if (!buffer || buffer->status() == RGBA32Buffer::FrameEmpty) - return 0; - - float duration = buffer->duration() / 1000.0f; - - // Follow other ports (and WinIE's) behavior to slow annoying ads that - // specify a 0 duration. - if (duration < 0.051f) - return 0.100f; - return duration; -} - -bool ImageSource::frameHasAlphaAtIndex(size_t index) -{ - if (!m_decoder || !m_decoder->supportsAlpha()) - return false; - - RGBA32Buffer* buffer = m_decoder->frameBufferAtIndex(index); - if (!buffer || buffer->status() == RGBA32Buffer::FrameEmpty) - return false; - - return buffer->hasAlpha(); -} - -} diff --git a/WebCore/platform/gtk/ClipboardGtk.cpp b/WebCore/platform/gtk/ClipboardGtk.cpp index 8cbf590..450966e 100644 --- a/WebCore/platform/gtk/ClipboardGtk.cpp +++ b/WebCore/platform/gtk/ClipboardGtk.cpp @@ -17,11 +17,18 @@ #include "config.h" #include "ClipboardGtk.h" +#include "CachedImage.h" +#include "CString.h" +#include "Editor.h" +#include "Element.h" #include "FileList.h" +#include "Frame.h" +#include "markup.h" #include "NotImplemented.h" +#include "RenderImage.h" #include "StringHash.h" -#include "Editor.h" +#include <gtk/gtk.h> namespace WebCore { @@ -33,12 +40,10 @@ PassRefPtr<Clipboard> Editor::newGeneralClipboard(ClipboardAccessPolicy policy) ClipboardGtk::ClipboardGtk(ClipboardAccessPolicy policy, bool forDragging) : Clipboard(policy, forDragging) { - notImplemented(); } ClipboardGtk::~ClipboardGtk() { - notImplemented(); } void ClipboardGtk::clearData(const String&) @@ -110,19 +115,65 @@ DragImageRef ClipboardGtk::createDragImage(IntPoint&) const return 0; } -void ClipboardGtk::declareAndWriteDragImage(Element*, const KURL&, const String&, Frame*) +static CachedImage* getCachedImage(Element* element) { - notImplemented(); + // Attempt to pull CachedImage from element + ASSERT(element); + RenderObject* renderer = element->renderer(); + if (!renderer || !renderer->isImage()) + return 0; + + RenderImage* image = static_cast<RenderImage*>(renderer); + if (image->cachedImage() && !image->cachedImage()->errorOccurred()) + return image->cachedImage(); + + return 0; } -void ClipboardGtk::writeURL(const KURL&, const String&, Frame*) +void ClipboardGtk::declareAndWriteDragImage(Element* element, const KURL& url, const String& label, Frame*) { - notImplemented(); + CachedImage* cachedImage = getCachedImage(element); + if (!cachedImage || !cachedImage->isLoaded()) + return; + + GdkPixbuf* pixbuf = cachedImage->image()->getGdkPixbuf(); + if (!pixbuf) + return; + + GtkClipboard* imageClipboard = gtk_clipboard_get(gdk_atom_intern_static_string("WebKitClipboardImage")); + gtk_clipboard_clear(imageClipboard); + + gtk_clipboard_set_image(imageClipboard, pixbuf); + g_object_unref(pixbuf); + + writeURL(url, label, 0); } -void ClipboardGtk::writeRange(Range*, Frame*) +void ClipboardGtk::writeURL(const KURL& url, const String& label, Frame*) { - notImplemented(); + GtkClipboard* textClipboard = gtk_clipboard_get(gdk_atom_intern_static_string("WebKitClipboardText")); + GtkClipboard* urlClipboard = gtk_clipboard_get(gdk_atom_intern_static_string("WebKitClipboardUrl")); + GtkClipboard* urlLabelClipboard = gtk_clipboard_get(gdk_atom_intern_static_string("WebKitClipboardUrlLabel")); + + gtk_clipboard_clear(textClipboard); + gtk_clipboard_clear(urlClipboard); + gtk_clipboard_clear(urlLabelClipboard); + + gtk_clipboard_set_text(textClipboard, url.string().utf8().data(), -1); + gtk_clipboard_set_text(urlClipboard, url.string().utf8().data(), -1); + gtk_clipboard_set_text(urlLabelClipboard, label.utf8().data(), -1); +} + +void ClipboardGtk::writeRange(Range* range, Frame* frame) +{ + GtkClipboard* textClipboard = gtk_clipboard_get(gdk_atom_intern_static_string("WebKitClipboardText")); + GtkClipboard* htmlClipboard = gtk_clipboard_get(gdk_atom_intern_static_string("WebKitClipboardHtml")); + + gtk_clipboard_clear(textClipboard); + gtk_clipboard_clear(htmlClipboard); + + gtk_clipboard_set_text(textClipboard, frame->selectedText().utf8().data(), -1); + gtk_clipboard_set_text(htmlClipboard, createMarkup(range, 0, AnnotateForInterchange).utf8().data(), -1); } bool ClipboardGtk::hasData() diff --git a/WebCore/platform/gtk/ClipboardGtk.h b/WebCore/platform/gtk/ClipboardGtk.h index 7314ae4..bb21d92 100644 --- a/WebCore/platform/gtk/ClipboardGtk.h +++ b/WebCore/platform/gtk/ClipboardGtk.h @@ -24,8 +24,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef ClipboardGdk_h -#define ClipboardGdk_h +#ifndef ClipboardGtk_h +#define ClipboardGtk_h #include "Clipboard.h" diff --git a/WebCore/platform/gtk/PasteboardGtk.cpp b/WebCore/platform/gtk/PasteboardGtk.cpp index 9f72923..6949b0a 100644 --- a/WebCore/platform/gtk/PasteboardGtk.cpp +++ b/WebCore/platform/gtk/PasteboardGtk.cpp @@ -35,13 +35,6 @@ namespace WebCore { -/* FIXME: we must get rid of this and use the enum in webkitwebview.h someway */ -typedef enum -{ - WEBKIT_WEB_VIEW_TARGET_INFO_HTML = - 1, - WEBKIT_WEB_VIEW_TARGET_INFO_TEXT = - 2 -} WebKitWebViewTargetInfo; - class PasteboardSelectionData { public: PasteboardSelectionData(gchar* text, gchar* markup) @@ -65,11 +58,11 @@ static void clipboard_get_contents_cb(GtkClipboard *clipboard, GtkSelectionData guint info, gpointer data) { PasteboardSelectionData* clipboardData = reinterpret_cast<PasteboardSelectionData*>(data); ASSERT(clipboardData); - if ((gint)info == WEBKIT_WEB_VIEW_TARGET_INFO_HTML) { + if ((gint)info == Pasteboard::generalPasteboard()->m_helper->getWebViewTargetInfoHtml()) gtk_selection_data_set(selection_data, selection_data->target, 8, reinterpret_cast<const guchar*>(clipboardData->markup()), g_utf8_strlen(clipboardData->markup(), -1)); - } else + else gtk_selection_data_set_text(selection_data, clipboardData->text(), -1); } diff --git a/WebCore/platform/gtk/PasteboardHelper.h b/WebCore/platform/gtk/PasteboardHelper.h index 9943a2d..8e67127 100644 --- a/WebCore/platform/gtk/PasteboardHelper.h +++ b/WebCore/platform/gtk/PasteboardHelper.h @@ -43,6 +43,7 @@ public: virtual GtkClipboard* getPrimary(Frame*) const = 0; virtual GtkTargetList* getCopyTargetList(Frame*) const = 0; virtual GtkTargetList* getPasteTargetList(Frame*) const = 0; + virtual gint getWebViewTargetInfoHtml() const = 0; }; } diff --git a/WebCore/platform/haiku/ClipboardHaiku.cpp b/WebCore/platform/haiku/ClipboardHaiku.cpp index 845c08c..a62c30c 100644 --- a/WebCore/platform/haiku/ClipboardHaiku.cpp +++ b/WebCore/platform/haiku/ClipboardHaiku.cpp @@ -27,8 +27,8 @@ #include "config.h" #include "ClipboardHaiku.h" -#include "IntPoint.h" #include "FileList.h" +#include "IntPoint.h" #include "NotImplemented.h" #include "PlatformString.h" #include "StringHash.h" @@ -42,7 +42,7 @@ namespace WebCore { -ClipboardHaiku::ClipboardHaiku(ClipboardAccessPolicy policy, bool forDragging) +ClipboardHaiku::ClipboardHaiku(ClipboardAccessPolicy policy, bool forDragging) : Clipboard(policy, forDragging) { } @@ -61,7 +61,7 @@ void ClipboardHaiku::clearData(const String& type) } } -void ClipboardHaiku::clearAllData() +void ClipboardHaiku::clearAllData() { if (be_clipboard->Lock()) { be_clipboard->Clear(); @@ -70,7 +70,7 @@ void ClipboardHaiku::clearAllData() } } -String ClipboardHaiku::getData(const String& type, bool& success) const +String ClipboardHaiku::getData(const String& type, bool& success) const { BString result; success = false; @@ -88,7 +88,7 @@ String ClipboardHaiku::getData(const String& type, bool& success) const return result; } -bool ClipboardHaiku::setData(const String& type, const String& data) +bool ClipboardHaiku::setData(const String& type, const String& data) { bool result = false; @@ -110,7 +110,7 @@ bool ClipboardHaiku::setData(const String& type, const String& data) } // Extensions beyond IE's API. -HashSet<String> ClipboardHaiku::types() const +HashSet<String> ClipboardHaiku::types() const { HashSet<String> result; @@ -138,27 +138,27 @@ PassRefPtr<FileList> ClipboardHaiku::files() const return 0; } -IntPoint ClipboardHaiku::dragLocation() const -{ +IntPoint ClipboardHaiku::dragLocation() const +{ notImplemented(); return IntPoint(0, 0); } -CachedImage* ClipboardHaiku::dragImage() const +CachedImage* ClipboardHaiku::dragImage() const { notImplemented(); - return 0; + return 0; } -void ClipboardHaiku::setDragImage(CachedImage*, const IntPoint&) +void ClipboardHaiku::setDragImage(CachedImage*, const IntPoint&) { notImplemented(); } -Node* ClipboardHaiku::dragImageElement() +Node* ClipboardHaiku::dragImageElement() { notImplemented(); - return 0; + return 0; } void ClipboardHaiku::setDragImageElement(Node*, const IntPoint&) @@ -167,27 +167,27 @@ void ClipboardHaiku::setDragImageElement(Node*, const IntPoint&) } DragImageRef ClipboardHaiku::createDragImage(IntPoint& dragLocation) const -{ +{ notImplemented(); return 0; } -void ClipboardHaiku::declareAndWriteDragImage(Element*, const KURL&, const String&, Frame*) +void ClipboardHaiku::declareAndWriteDragImage(Element*, const KURL&, const String&, Frame*) { notImplemented(); } -void ClipboardHaiku::writeURL(const KURL&, const String&, Frame*) +void ClipboardHaiku::writeURL(const KURL&, const String&, Frame*) { notImplemented(); } -void ClipboardHaiku::writeRange(Range*, Frame*) +void ClipboardHaiku::writeRange(Range*, Frame*) { notImplemented(); } -bool ClipboardHaiku::hasData() +bool ClipboardHaiku::hasData() { bool result = false; diff --git a/WebCore/platform/haiku/ContextMenuHaiku.cpp b/WebCore/platform/haiku/ContextMenuHaiku.cpp index 03b8978..b978433 100644 --- a/WebCore/platform/haiku/ContextMenuHaiku.cpp +++ b/WebCore/platform/haiku/ContextMenuHaiku.cpp @@ -27,30 +27,27 @@ #include "config.h" #include "ContextMenu.h" -#include "ContextMenuItem.h" #include "ContextMenuController.h" +#include "ContextMenuItem.h" +#include "Document.h" #include "Frame.h" #include "FrameView.h" -#include "Document.h" - -#include <wtf/Assertions.h> - #include <Looper.h> #include <Menu.h> #include <Message.h> +#include <wtf/Assertions.h> namespace WebCore { // FIXME: This class isn't used yet -class ContextMenuReceiver : public BLooper -{ +class ContextMenuReceiver : public BLooper { public: ContextMenuReceiver(ContextMenu* menu) : BLooper("context_menu_receiver") , m_menu(menu) + , m_result(-1) { - m_result = -1; } void HandleMessage(BMessage* msg) @@ -80,21 +77,8 @@ private: ContextMenu::ContextMenu(const HitTestResult& result) : m_hitTestResult(result) - , m_platformDescription(NULL) + , m_platformDescription(new BMenu("context_menu")) { - /* Get position */ - if (result.innerNode() && result.innerNode()->document()) { - BView* view = result.innerNode()->document()->frame()->view()->platformWidget(); - int child = 0; - while (view->ChildAt(child)) { - if (view->ChildAt(child)->Name() == "scroll_view_canvas") { - m_point = view->ChildAt(child)->ConvertToScreen(BPoint(result.point().x(), result.point().y())); - break; - } - child++; - } - } - m_platformDescription = new BMenu("context_menu"); } ContextMenu::~ContextMenu() @@ -106,9 +90,9 @@ void ContextMenu::appendItem(ContextMenuItem& item) { checkOrEnableIfNeeded(item); - BMenuItem* bItem = item.releasePlatformDescription(); - if (bItem) - m_platformDescription->AddItem(bItem); + BMenuItem* menuItem = item.releasePlatformDescription(); + if (menuItem) + m_platformDescription->AddItem(menuItem); } unsigned ContextMenu::itemCount() const @@ -120,9 +104,9 @@ void ContextMenu::insertItem(unsigned position, ContextMenuItem& item) { checkOrEnableIfNeeded(item); - BMenuItem* bItem = item.releasePlatformDescription(); - if (bItem) - m_platformDescription->AddItem(bItem, position); + BMenuItem* menuItem = item.releasePlatformDescription(); + if (menuItem) + m_platformDescription->AddItem(menuItem, position); } PlatformMenuDescription ContextMenu::platformDescription() const diff --git a/WebCore/platform/haiku/CookieJarHaiku.cpp b/WebCore/platform/haiku/CookieJarHaiku.cpp index 73519d7..831b379 100644 --- a/WebCore/platform/haiku/CookieJarHaiku.cpp +++ b/WebCore/platform/haiku/CookieJarHaiku.cpp @@ -29,6 +29,7 @@ #include "config.h" #include "CookieJar.h" +#include "Cookie.h" #include "KURL.h" #include "PlatformString.h" #include "StringHash.h" @@ -41,21 +42,33 @@ namespace WebCore { // FIXME: Shouldn't this be saved to and restored from disk too? static HashMap<String, String> cookieJar; -void setCookies(const KURL& url, const KURL& /*policyURL*/, const String& value) +void setCookies(Document*, const KURL& url, const String& value) { cookieJar.set(url.string(), value); } -String cookies(const KURL& url) +String cookies(const Document*, const KURL& url) { return cookieJar.get(url.string()); } -bool cookiesEnabled() +bool cookiesEnabled(const Document*) { // FIXME: This should probably be a setting return true; } +bool getRawCookies(const Document*, const KURL&, Vector<Cookie>& rawCookies) +{ + // FIXME: Not yet implemented + rawCookies.clear(); + return false; // return true when implemented +} + +void deleteCookie(const Document*, const KURL&, const String&) +{ + // FIXME: Not yet implemented +} + } // namespace WebCore diff --git a/WebCore/platform/haiku/DragDataHaiku.cpp b/WebCore/platform/haiku/DragDataHaiku.cpp index b42b311..4a20147 100644 --- a/WebCore/platform/haiku/DragDataHaiku.cpp +++ b/WebCore/platform/haiku/DragDataHaiku.cpp @@ -27,10 +27,9 @@ #include "config.h" #include "DragData.h" +#include "ClipboardHaiku.h" #include "Document.h" #include "DocumentFragment.h" -#include "ClipboardHaiku.h" - #include "NotImplemented.h" @@ -79,7 +78,7 @@ Color DragData::asColor() const WTF::PassRefPtr<Clipboard> DragData::createClipboard(ClipboardAccessPolicy policy) const { - return new ClipboardHaiku(policy, true); + return ClipboardHaiku::create(policy, true); } bool DragData::containsCompatibleContent() const @@ -104,6 +103,6 @@ PassRefPtr<DocumentFragment> DragData::asFragment(Document*) const notImplemented(); return 0; } - + } // namespace WebCore diff --git a/WebCore/platform/haiku/LocalizedStringsHaiku.cpp b/WebCore/platform/haiku/LocalizedStringsHaiku.cpp new file mode 100644 index 0000000..a37ffcc --- /dev/null +++ b/WebCore/platform/haiku/LocalizedStringsHaiku.cpp @@ -0,0 +1,346 @@ +/* + * Copyright (C) 2009 Maxime Simon <simon.maxime@gmail.com> + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "LocalizedStrings.h" + +#include "PlatformString.h" + + +namespace WebCore { +String submitButtonDefaultLabel() +{ + return "Submit"; +} + +String inputElementAltText() +{ + return String(); +} + +String resetButtonDefaultLabel() +{ + return "Reset"; +} + +String defaultLanguage() +{ + return "en"; +} + +String searchableIndexIntroduction() +{ + return "Searchable Index"; +} + +String fileButtonChooseFileLabel() +{ + return "Choose File"; +} + +String fileButtonNoFileSelectedLabel() +{ + return "No file selected"; +} + +String contextMenuItemTagOpenLinkInNewWindow() +{ + return "Open in new tab"; +} + +String contextMenuItemTagDownloadLinkToDisk() +{ + return "Download link to disk"; +} + +String contextMenuItemTagCopyLinkToClipboard() +{ + return "Copy link to clipboard"; +} + +String contextMenuItemTagOpenImageInNewWindow() +{ + return "Open image in new window"; +} + +String contextMenuItemTagDownloadImageToDisk() +{ + return "Download image to disk"; +} + +String contextMenuItemTagCopyImageToClipboard() +{ + return "Copy image to clipboard"; +} + +String contextMenuItemTagOpenFrameInNewWindow() +{ + return "Open frame in new window"; +} + +String contextMenuItemTagCopy() +{ + return "Copy"; +} + +String contextMenuItemTagGoBack() +{ + return "Go back"; +} + +String contextMenuItemTagGoForward() +{ + return "Go forward"; +} + +String contextMenuItemTagStop() +{ + return "Stop"; +} + +String contextMenuItemTagReload() +{ + return "Reload"; +} + +String contextMenuItemTagCut() +{ + return "Cut"; +} + +String contextMenuItemTagPaste() +{ + return "Paste"; +} + +String contextMenuItemTagNoGuessesFound() +{ + return "No guesses found"; +} + +String contextMenuItemTagIgnoreSpelling() +{ + return "Ignore spelling"; +} + +String contextMenuItemTagLearnSpelling() +{ + return "Learn spelling"; +} + +String contextMenuItemTagSearchWeb() +{ + return "Search web"; +} + +String contextMenuItemTagLookUpInDictionary() +{ + return "Lookup in dictionary"; +} + +String contextMenuItemTagOpenLink() +{ + return "Open link"; +} + +String contextMenuItemTagIgnoreGrammar() +{ + return "Ignore grammar"; +} + +String contextMenuItemTagSpellingMenu() +{ + return "Spelling menu"; +} + +String contextMenuItemTagShowSpellingPanel(bool show) +{ + return "Show spelling panel"; +} + +String contextMenuItemTagCheckSpelling() +{ + return "Check spelling"; +} + +String contextMenuItemTagCheckSpellingWhileTyping() +{ + return "Check spelling while typing"; +} + +String contextMenuItemTagCheckGrammarWithSpelling() +{ + return "Check for grammar with spelling"; +} + +String contextMenuItemTagFontMenu() +{ + return "Font menu"; +} + +String contextMenuItemTagBold() +{ + return "Bold"; +} + +String contextMenuItemTagItalic() +{ + return "Italic"; +} + +String contextMenuItemTagUnderline() +{ + return "Underline"; +} + +String contextMenuItemTagOutline() +{ + return "Outline"; +} + +String contextMenuItemTagWritingDirectionMenu() +{ + return "Writing direction menu"; +} + +String contextMenuItemTagDefaultDirection() +{ + return "Default direction"; +} + +String contextMenuItemTagLeftToRight() +{ + return "Left to right"; +} + +String contextMenuItemTagRightToLeft() +{ + return "Right to left"; +} + +String contextMenuItemTagInspectElement() +{ + return "Inspect"; +} + +String searchMenuNoRecentSearchesText() +{ + return "No recent text searches"; +} + +String searchMenuRecentSearchesText() +{ + return "Recent text searches"; +} + +String searchMenuClearRecentSearchesText() +{ + return "Clear recent text searches"; +} + +String unknownFileSizeText() +{ + return "Unknown"; +} + +String AXWebAreaText() +{ + return String(); +} + +String AXLinkText() +{ + return String(); +} + +String AXListMarkerText() +{ + return String(); +} + +String AXImageMapText() +{ + return String(); +} + +String AXHeadingText() +{ + return String(); +} + +String imageTitle(const String& filename, const IntSize& size) +{ + return String(filename); +} + +String contextMenuItemTagTextDirectionMenu() +{ + return String(); +} + +String AXButtonActionVerb() +{ + return String(); +} + +String AXTextFieldActionVerb() +{ + return String(); +} + +String AXRadioButtonActionVerb() +{ + return String(); +} + +String AXCheckedCheckBoxActionVerb() +{ + return String(); +} + +String AXUncheckedCheckBoxActionVerb() +{ + return String(); +} + +String AXLinkActionVerb() +{ + return String(); +} + +String AXDefinitionListTermText() +{ + return String(); +} + +String AXDefinitionListDefinitionText() +{ + return String(); +} + +} // namespace WebCore + diff --git a/WebCore/platform/haiku/LoggingHaiku.cpp b/WebCore/platform/haiku/LoggingHaiku.cpp new file mode 100644 index 0000000..f09c483 --- /dev/null +++ b/WebCore/platform/haiku/LoggingHaiku.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2009 Maxime Simon <simon.maxime@gmail.com> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "Logging.h" + + +namespace WebCore { + +void InitializeLoggingChannelsIfNecessary() +{ + // FIXME: Should read the logging channels from a file. + static bool haveInitializedLoggingChannels = false; + if (haveInitializedLoggingChannels) + return; + + haveInitializedLoggingChannels = true; + + LogEvents.state = WTFLogChannelOn; + LogFrames.state = WTFLogChannelOn; + LogLoading.state = WTFLogChannelOn; + LogPlatformLeaks.state = WTFLogChannelOn; +} + +} // namespace WebCore + diff --git a/WebCore/platform/haiku/RenderThemeHaiku.cpp b/WebCore/platform/haiku/RenderThemeHaiku.cpp new file mode 100644 index 0000000..4327795 --- /dev/null +++ b/WebCore/platform/haiku/RenderThemeHaiku.cpp @@ -0,0 +1,178 @@ +/* + * This file is part of the WebKit project. + * + * Copyright (C) 2006 Dirk Mueller <mueller@kde.org> + * 2006 Nikolas Zimmermann <zimmermann@kde.org> + * Copyright (C) 2007 Ryan Leavengood <leavengood@gmail.com> + * Copyright (C) 2009 Maxime Simon <simon.maxime@gmail.com> + * + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "config.h" +#include "RenderThemeHaiku.h" + +#include "GraphicsContext.h" +#include "NotImplemented.h" +#include <ControlLook.h> +#include <View.h> + + +namespace WebCore { + +PassRefPtr<RenderTheme> RenderThemeHaiku::create() +{ + return adoptRef(new RenderThemeHaiku()); +} + +PassRefPtr<RenderTheme> RenderTheme::themeForPage(Page*) +{ + static RenderTheme* renderTheme = RenderThemeHaiku::create().releaseRef(); + return renderTheme; +} + +RenderThemeHaiku::RenderThemeHaiku() +{ +} + +RenderThemeHaiku::~RenderThemeHaiku() +{ +} + +static bool supportsFocus(ControlPart appearance) +{ + switch (appearance) { + case PushButtonPart: + case ButtonPart: + case TextFieldPart: + case TextAreaPart: + case SearchFieldPart: + case MenulistPart: + case RadioPart: + case CheckboxPart: + return true; + default: + return false; + } +} + +bool RenderThemeHaiku::supportsFocusRing(const RenderStyle* style) const +{ + return supportsFocus(style->appearance()); +} + +Color RenderThemeHaiku::platformActiveSelectionBackgroundColor() const +{ + return Color(ui_color(B_CONTROL_HIGHLIGHT_COLOR)); +} + +Color RenderThemeHaiku::platformInactiveSelectionBackgroundColor() const +{ + return Color(ui_color(B_CONTROL_HIGHLIGHT_COLOR)); +} + +Color RenderThemeHaiku::platformActiveSelectionForegroundColor() const +{ + return Color(ui_color(B_CONTROL_TEXT_COLOR)); +} + +Color RenderThemeHaiku::platformInactiveSelectionForegroundColor() const +{ + return Color(ui_color(B_CONTROL_TEXT_COLOR)); +} + +Color RenderThemeHaiku::platformTextSearchHighlightColor() const +{ + return Color(ui_color(B_MENU_SELECTED_BACKGROUND_COLOR)); +} + +void RenderThemeHaiku::systemFont(int propId, FontDescription&) const +{ + notImplemented(); +} + +bool RenderThemeHaiku::paintCheckbox(RenderObject*, const RenderObject::PaintInfo& info, const IntRect& intRect) +{ + if (info.context->paintingDisabled()) + return false; + + rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); + BRect rect = intRect; + BView* view = info.context->platformContext(); + + if (!be_control_look) + return false; + + be_control_look->DrawCheckBox(view, rect, rect, base); + return true; +} + +void RenderThemeHaiku::setCheckboxSize(RenderStyle* style) const +{ + int size = 10; + + // If the width and height are both specified, then we have nothing to do. + if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto()) + return; + + // FIXME: A hard-coded size of 'size' is used. This is wrong but necessary for now. + if (style->width().isIntrinsicOrAuto()) + style->setWidth(Length(size, Fixed)); + + if (style->height().isAuto()) + style->setHeight(Length(size, Fixed)); +} + +bool RenderThemeHaiku::paintRadio(RenderObject*, const RenderObject::PaintInfo& info, const IntRect& intRect) +{ + if (info.context->paintingDisabled()) + return false; + + rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); + BRect rect = intRect; + BView* view = info.context->platformContext(); + + if (!be_control_look) + return false; + + be_control_look->DrawRadioButton(view, rect, rect, base); + return true; +} + +void RenderThemeHaiku::setRadioSize(RenderStyle* style) const +{ + // This is the same as checkboxes. + setCheckboxSize(style); +} + +void RenderThemeHaiku::adjustMenuListStyle(CSSStyleSelector*, RenderStyle* style, Element*) const +{ + // Leave some space for the arrow. + style->setPaddingRight(Length(22, Fixed)); + const int minHeight = 20; + style->setMinHeight(Length(minHeight, Fixed)); +} + +bool RenderThemeHaiku::paintMenuList(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) +{ + notImplemented(); + return false; +} + +} // namespace WebCore diff --git a/WebCore/platform/haiku/RenderThemeHaiku.h b/WebCore/platform/haiku/RenderThemeHaiku.h new file mode 100644 index 0000000..7daebc4 --- /dev/null +++ b/WebCore/platform/haiku/RenderThemeHaiku.h @@ -0,0 +1,70 @@ +/* + * This file is part of the WebKit project. + * + * Copyright (C) 2009 Maxime Simon <simon.maxime@gmail.com> + * + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef RenderThemeHaiku_h +#define RenderThemeHaiku_h + +#include "RenderTheme.h" + +namespace WebCore { + + class RenderThemeHaiku : public RenderTheme { + private: + RenderThemeHaiku(); + virtual ~RenderThemeHaiku(); + + public: + static PassRefPtr<RenderTheme> create(); + + // A method asking if the theme's controls actually care about redrawing when hovered. + virtual bool supportsHover(const RenderStyle* style) const { return false; } + + // A method asking if the theme is able to draw the focus ring. + virtual bool supportsFocusRing(const RenderStyle*) const; + + // The platform selection color. + virtual Color platformActiveSelectionBackgroundColor() const; + virtual Color platformInactiveSelectionBackgroundColor() const; + virtual Color platformActiveSelectionForegroundColor() const; + virtual Color platformInactiveSelectionForegroundColor() const; + + virtual Color platformTextSearchHighlightColor() const; + + // System fonts. + virtual void systemFont(int propId, FontDescription&) const; + + protected: + virtual bool paintCheckbox(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual void setCheckboxSize(RenderStyle*) const; + + virtual bool paintRadio(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual void setRadioSize(RenderStyle*) const; + + virtual void adjustMenuListStyle(CSSStyleSelector*, RenderStyle*, Element*) const; + virtual bool paintMenuList(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + }; + +} // namespace WebCore + +#endif // RenderThemeHaiku_h diff --git a/WebCore/platform/haiku/ScrollbarThemeHaiku.cpp b/WebCore/platform/haiku/ScrollbarThemeHaiku.cpp new file mode 100644 index 0000000..8adab3d --- /dev/null +++ b/WebCore/platform/haiku/ScrollbarThemeHaiku.cpp @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * Copyright 2009 Maxime Simon <simon.maxime@gmail.com> All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "ScrollbarThemeHaiku.h" + +#include "GraphicsContext.h" +#include "Scrollbar.h" +#include <ControlLook.h> +#include <InterfaceDefs.h> + + +int buttonWidth(int scrollbarWidth, int thickness) +{ + return scrollbarWidth < 2 * thickness ? scrollbarWidth / 2 : thickness; +} + +namespace WebCore { + +ScrollbarTheme* ScrollbarTheme::nativeTheme() +{ + static ScrollbarThemeHaiku theme; + return &theme; +} + +ScrollbarThemeHaiku::ScrollbarThemeHaiku() +{ +} + +ScrollbarThemeHaiku::~ScrollbarThemeHaiku() +{ +} + +int ScrollbarThemeHaiku::scrollbarThickness(ScrollbarControlSize controlSize) +{ + // FIXME: Should we make a distinction between a Small and a Regular Scrollbar? + return 16; +} + +bool ScrollbarThemeHaiku::hasButtons(Scrollbar* scrollbar) +{ + return scrollbar->enabled(); +} + +bool ScrollbarThemeHaiku::hasThumb(Scrollbar* scrollbar) +{ + return scrollbar->enabled() && thumbLength(scrollbar) > 0; +} + +IntRect ScrollbarThemeHaiku::backButtonRect(Scrollbar* scrollbar, ScrollbarPart part, bool) +{ + if (part == BackButtonEndPart) + return IntRect(); + + int thickness = scrollbarThickness(); + IntPoint buttonOrigin(scrollbar->x(), scrollbar->y()); + IntSize buttonSize = scrollbar->orientation() == HorizontalScrollbar + ? IntSize(buttonWidth(scrollbar->width(), thickness), thickness) + : IntSize(thickness, buttonWidth(scrollbar->height(), thickness)); + IntRect buttonRect(buttonOrigin, buttonSize); + + return buttonRect; +} + +IntRect ScrollbarThemeHaiku::forwardButtonRect(Scrollbar* scrollbar, ScrollbarPart part, bool) +{ + if (part == BackButtonStartPart) + return IntRect(); + + int thickness = scrollbarThickness(); + if (scrollbar->orientation() == HorizontalScrollbar) { + int width = buttonWidth(scrollbar->width(), thickness); + return IntRect(scrollbar->x() + scrollbar->width() - width, scrollbar->y(), width, thickness); + } + + int height = buttonWidth(scrollbar->height(), thickness); + return IntRect(scrollbar->x(), scrollbar->y() + scrollbar->height() - height, thickness, height); +} + +IntRect ScrollbarThemeHaiku::trackRect(Scrollbar* scrollbar, bool) +{ + int thickness = scrollbarThickness(); + if (scrollbar->orientation() == HorizontalScrollbar) { + if (scrollbar->width() < 2 * thickness) + return IntRect(); + return IntRect(scrollbar->x() + thickness, scrollbar->y(), scrollbar->width() - 2 * thickness, thickness); + } + if (scrollbar->height() < 2 * thickness) + return IntRect(); + return IntRect(scrollbar->x(), scrollbar->y() + thickness, thickness, scrollbar->height() - 2 * thickness); +} + +void ScrollbarThemeHaiku::paintScrollbarBackground(GraphicsContext* context, Scrollbar* scrollbar) +{ + if (!be_control_look) + return; + + BRect rect = trackRect(scrollbar, false); + orientation scrollbarOrientation = scrollbar->orientation() == HorizontalScrollbar ? B_HORIZONTAL : B_VERTICAL; + + be_control_look->DrawScrollBarBackground(context->platformContext(), rect, rect, ui_color(B_PANEL_BACKGROUND_COLOR), 0, scrollbarOrientation); +} + +void ScrollbarThemeHaiku::paintButton(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& rect, ScrollbarPart part) +{ + if (!be_control_look) + return; + + BRect drawRect = BRect(rect); + BView* view = context->platformContext(); + rgb_color panelBgColor = ui_color(B_PANEL_BACKGROUND_COLOR); + rgb_color buttonBgColor = tint_color(panelBgColor, B_LIGHTEN_1_TINT); + + be_control_look->DrawButtonFrame(view, drawRect, drawRect, buttonBgColor, panelBgColor); + be_control_look->DrawButtonBackground(view, drawRect, drawRect, buttonBgColor); + + int arrowDirection; + if (scrollbar->orientation() == VerticalScrollbar) + arrowDirection = part == BackButtonStartPart ? BControlLook::B_UP_ARROW : BControlLook::B_DOWN_ARROW; + else + arrowDirection = part == BackButtonStartPart ? BControlLook::B_LEFT_ARROW : BControlLook::B_RIGHT_ARROW; + + be_control_look->DrawArrowShape(view, drawRect, drawRect, ui_color(B_CONTROL_TEXT_COLOR), arrowDirection); +} + +void ScrollbarThemeHaiku::paintThumb(GraphicsContext* context, Scrollbar*, const IntRect& rect) +{ + if (!be_control_look) + return; + + BRect drawRect = BRect(rect); + BView* view = context->platformContext(); + rgb_color panelBgColor = ui_color(B_PANEL_BACKGROUND_COLOR); + rgb_color buttonBgColor = tint_color(panelBgColor, B_LIGHTEN_1_TINT); + + be_control_look->DrawButtonFrame(view, drawRect, drawRect, buttonBgColor, panelBgColor); + be_control_look->DrawButtonBackground(view, drawRect, drawRect, buttonBgColor); +} + +} + diff --git a/WebCore/platform/haiku/ScrollbarThemeHaiku.h b/WebCore/platform/haiku/ScrollbarThemeHaiku.h new file mode 100644 index 0000000..18e2cc0 --- /dev/null +++ b/WebCore/platform/haiku/ScrollbarThemeHaiku.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * Copyright 2009 Maxime Simon <simon.maxime@gmail.com> All Rights Reserved + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ScrollbarThemeHaiku_h +#define ScrollbarThemeHaiku_h + +#include "ScrollbarThemeComposite.h" + +namespace WebCore { + class Scrollbar; + + class ScrollbarThemeHaiku : public ScrollbarThemeComposite { + public: + ScrollbarThemeHaiku(); + virtual ~ScrollbarThemeHaiku(); + + virtual int scrollbarThickness(ScrollbarControlSize = RegularScrollbar); + + virtual bool hasButtons(Scrollbar*); + virtual bool hasThumb(Scrollbar*); + + virtual IntRect backButtonRect(Scrollbar*, ScrollbarPart, bool painting); + virtual IntRect forwardButtonRect(Scrollbar*, ScrollbarPart, bool painting); + virtual IntRect trackRect(Scrollbar*, bool painting); + + virtual void paintScrollbarBackground(GraphicsContext*, Scrollbar*); + virtual void paintButton(GraphicsContext*, Scrollbar*, const IntRect&, ScrollbarPart); + virtual void paintThumb(GraphicsContext*, Scrollbar*, const IntRect&); + }; + +} +#endif diff --git a/WebCore/platform/haiku/SharedBufferHaiku.cpp b/WebCore/platform/haiku/SharedBufferHaiku.cpp new file mode 100644 index 0000000..113cd2e --- /dev/null +++ b/WebCore/platform/haiku/SharedBufferHaiku.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2009 Maxime Simon <simon.maxime@gmail.com> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "SharedBuffer.h" + +#include <File.h> +#include <String.h> + +namespace WebCore { + +PassRefPtr<SharedBuffer> SharedBuffer::createWithContentsOfFile(const String& fileName) +{ + if (fileName.isEmpty()) + return 0; + + BFile file(BString(fileName).String(), B_READ_ONLY); + if (file.InitCheck() != B_OK) + return 0; + + RefPtr<SharedBuffer> result = SharedBuffer::create(); + + off_t size; + file.GetSize(&size); + result->m_buffer.resize(size); + if (result->m_buffer.size() != size) + return 0; + + file.Read(result->m_buffer.data(), result->m_buffer.size()); + return result.release(); +} + +} // namespace WebCore diff --git a/WebCore/platform/haiku/TemporaryLinkStubs.cpp b/WebCore/platform/haiku/TemporaryLinkStubs.cpp index 48380fc..aa3d538 100644 --- a/WebCore/platform/haiku/TemporaryLinkStubs.cpp +++ b/WebCore/platform/haiku/TemporaryLinkStubs.cpp @@ -33,40 +33,11 @@ #include "config.h" -#include "AXObjectCache.h" -#include "CachedResource.h" -#include "CookieJar.h" -#include "Cursor.h" -#include "DataGridColumnList.h" -#include "FileSystem.h" -#include "Font.h" -#include "Frame.h" -#include "FrameView.h" -#include "GraphicsContext.h" -#include "History.h" -#include "IconLoader.h" -#include "InspectorController.h" -#include "IntPoint.h" #include "KURL.h" -#include "Language.h" -#include "Node.h" #include "NotImplemented.h" -#include "Path.h" -#include "PlatformMouseEvent.h" -#include "PlatformScrollBar.h" -#include "PluginInfoStore.h" -#include "RenderTheme.h" -#include "Screen.h" -#include "Scrollbar.h" -#include "ScrollbarTheme.h" -#include "SharedBuffer.h" -#include "TextBoundaries.h" -#include "Threading.h" -#include "Widget.h" -#include "loader.h" -#include <runtime/JSValue.h> -#include <stdio.h> -#include <stdlib.h> +#include "PlatformString.h" +#include "SSLKeyGenerator.h" +#include "SystemTime.h" using namespace WebCore; @@ -78,20 +49,14 @@ Vector<char> loadResourceIntoArray(const char*) namespace WebCore { -bool historyContains(String const&) +String signedPublicKeyAndChallengeString(unsigned keySizeIndex, const String &challengeString, const KURL &url) { - return false; + return String(); } -Vector<String> supportedKeySizes() +void getSupportedKeySizes(Vector<String>&) { notImplemented(); - return Vector<String>(); -} - -String signedPublicKeyAndChallengeString(unsigned keySizeIndex, const String &challengeString, const KURL &url) -{ - return String(); } float userIdleTime() @@ -105,22 +70,11 @@ void callOnMainThread(void (*)()) notImplemented(); } -PassRefPtr<SharedBuffer> SharedBuffer::createWithContentsOfFile(const String&) -{ - notImplemented(); - return 0; -} - String KURL::fileSystemPath() const { notImplemented(); return String(); } -void getSupportedKeySizes(Vector<String>&) -{ - notImplemented(); -} - } // namespace WebCore diff --git a/WebCore/platform/image-decoders/ImageDecoder.cpp b/WebCore/platform/image-decoders/ImageDecoder.cpp new file mode 100644 index 0000000..9c723cc --- /dev/null +++ b/WebCore/platform/image-decoders/ImageDecoder.cpp @@ -0,0 +1,103 @@ +/*
+ * Copyright (C) 2008-2009 Torch Mobile, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
+
+#include "config.h"
+#include "ImageDecoder.h"
+
+#include <algorithm>
+
+namespace WebCore {
+
+namespace {
+
+enum MatchType {
+ Exact,
+ UpperBound,
+ LowerBound
+};
+
+}
+
+template <MatchType type> static int getScaledValue(const Vector<int>& scaledValues, int valueToMatch, int searchStart)
+{
+ const int* dataStart = scaledValues.data();
+ const int* dataEnd = dataStart + scaledValues.size();
+ const int* matched = std::lower_bound(dataStart + searchStart, dataEnd, valueToMatch);
+ switch (type) {
+ case Exact:
+ return matched != dataEnd && *matched == valueToMatch ? matched - dataStart : -1;
+ case LowerBound:
+ return matched != dataEnd && *matched == valueToMatch ? matched - dataStart : matched - dataStart - 1;
+ case UpperBound:
+ default:
+ return matched != dataEnd ? matched - dataStart : -1;
+ }
+}
+
+int ImageDecoder::upperBoundScaledX(int origX, int searchStart)
+{
+ return getScaledValue<UpperBound>(m_scaledColumns, origX, searchStart);
+}
+
+int ImageDecoder::lowerBoundScaledX(int origX, int searchStart)
+{
+ return getScaledValue<LowerBound>(m_scaledColumns, origX, searchStart);
+}
+
+int ImageDecoder::scaledY(int origY, int searchStart)
+{
+ return getScaledValue<Exact>(m_scaledRows, origY, searchStart);
+}
+
+static inline void fillScaledValues(Vector<int>& scaledValues, double scaleRate, int length)
+{
+ double inflateRate = 1. / scaleRate;
+ scaledValues.reserveCapacity(static_cast<int>(length * scaleRate + 0.5));
+ for (int scaledIndex = 0;;) {
+ int index = static_cast<int>(scaledIndex * inflateRate + 0.5);
+ if (index < length) {
+ scaledValues.append(index);
+ ++scaledIndex;
+ } else
+ break;
+ }
+}
+
+void ImageDecoder::prepareScaleDataIfNecessary()
+{
+ int width = m_size.width();
+ int height = m_size.height();
+ int numPixels = height * width;
+ if (m_maxNumPixels <= 0 || numPixels <= m_maxNumPixels) {
+ m_scaled = false;
+ return;
+ }
+
+ m_scaled = true;
+ double scale = sqrt(m_maxNumPixels / (double)numPixels);
+ fillScaledValues(m_scaledColumns, scale, width);
+ fillScaledValues(m_scaledRows, scale, height);
+}
+
+}
+
+#endif // ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
diff --git a/WebCore/platform/image-decoders/ImageDecoder.h b/WebCore/platform/image-decoders/ImageDecoder.h index 57f8735..9256afe 100644 --- a/WebCore/platform/image-decoders/ImageDecoder.h +++ b/WebCore/platform/image-decoders/ImageDecoder.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2008-2009 Torch Mobile, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -140,7 +141,7 @@ namespace WebCore { inline PixelData* getAddr(int x, int y) { -#if PLATFORM(CAIRO) || PLATFORM(WX) +#if PLATFORM(CAIRO) || PLATFORM(WX) || PLATFORM(HAIKU) return m_bytes.data() + (y * width()) + x; #elif (PLATFORM(SKIA) || PLATFORM(SGL)) return m_bitmap.getAddr32(x, y); @@ -166,7 +167,7 @@ namespace WebCore { } } -#if PLATFORM(CAIRO) || PLATFORM(WX) +#if PLATFORM(CAIRO) || PLATFORM(WX) || PLATFORM(HAIKU) Vector<PixelData> m_bytes; IntSize m_size; // The size of the buffer. This should be the // same as ImageDecoder::m_size. @@ -188,9 +189,17 @@ namespace WebCore { // and the base class manages the RGBA32 frame cache. class ImageDecoder { public: + // ENABLE(IMAGE_DECODER_DOWN_SAMPLING) allows image decoders to write directly to + // scaled output buffers by down sampling. Call setMaxNumPixels() to specify the + // biggest size that decoded images can have. Image decoders will deflate those + // images that are bigger than m_maxNumPixels. (Not supported by all image decoders yet) ImageDecoder() : m_failed(false) , m_sizeAvailable(false) +#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) + , m_maxNumPixels(-1) + , m_scaled(false) +#endif { } @@ -272,8 +281,25 @@ namespace WebCore { // since in practice only GIFs will ever use this. virtual void clearFrameBufferCache(size_t clearBeforeFrame) { } +#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) + void setMaxNumPixels(int m) { m_maxNumPixels = m; } +#endif + protected: +#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) + void prepareScaleDataIfNecessary(); + int upperBoundScaledX(int origX, int searchStart = 0); + int lowerBoundScaledX(int origX, int searchStart = 0); + int scaledY(int origY, int searchStart = 0); +#endif + RefPtr<SharedBuffer> m_data; // The encoded data. +#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) + int m_maxNumPixels; + Vector<int> m_scaledColumns; + Vector<int> m_scaledRows; + bool m_scaled; +#endif Vector<RGBA32Buffer> m_frameBufferCache; bool m_failed; diff --git a/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp b/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp index e9296ad..bc4f357 100644 --- a/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp +++ b/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp @@ -249,7 +249,7 @@ bool ICOImageDecoder::processDirectory() ICON = 1, CURSOR = 2, }; - if (((fileType != ICON) && (fileType != CURSOR)) || (idCount == 0)) { + if (((fileType != ICON) && (fileType != CURSOR)) || (!idCount)) { setFailed(); return false; } @@ -303,10 +303,10 @@ ICOImageDecoder::IconDirectoryEntry ICOImageDecoder::readDirectoryEntry() // matching uint8_ts) is so we can record dimensions of size 256 (which is // what a zero byte really means). int width = static_cast<uint8_t>(m_data->data()[m_decodedOffset]); - if (width == 0) + if (!width) width = 256; int height = static_cast<uint8_t>(m_data->data()[m_decodedOffset + 1]); - if (height == 0) + if (!height) height = 256; IconDirectoryEntry entry; entry.m_size = IntSize(width, height); @@ -318,11 +318,12 @@ ICOImageDecoder::IconDirectoryEntry ICOImageDecoder::readDirectoryEntry() // this isn't quite what the bitmap info header says later, as we only use // this value to determine which icon entry is best. if (!entry.m_bitCount) { - uint8_t colorCount = m_data->data()[m_decodedOffset + 2]; - if (colorCount) { - for (--colorCount; colorCount; colorCount >>= 1) - ++entry.m_bitCount; - } + int colorCount = + static_cast<uint8_t>(m_data->data()[m_decodedOffset + 2]); + if (!colorCount) + colorCount = 256; // Vague in the spec, needed by real-world icons. + for (--colorCount; colorCount; colorCount >>= 1) + ++entry.m_bitCount; } m_decodedOffset += sizeOfDirEntry; diff --git a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp index ae09586..2565ea6 100644 --- a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp +++ b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp @@ -461,11 +461,27 @@ void JPEGImageDecoder::decode(bool sizeOnly) } } -static void convertCMYKToRGBA(RGBA32Buffer& dest, JSAMPROW src, jpeg_decompress_struct* info) +static void convertCMYKToRGBA(RGBA32Buffer& dest, int destY, JSAMPROW src, int srcWidth +#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) + , bool scaled, const Vector<int>& scaledColumns +#endif + ) { - ASSERT(info->out_color_space == JCS_CMYK); - - for (unsigned x = 0; x < info->output_width; ++x) { +#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) + if (scaled) { + int numColumns = scaledColumns.size(); + for (int x = 0; x < numColumns; ++x) { + JSAMPLE* jsample = src + scaledColumns[x] * 3; + unsigned c = jsample[0]; + unsigned m = jsample[1]; + unsigned y = jsample[2]; + unsigned k = jsample[3]; + dest.setRGBA(x, destY, c * k / 255, m * k / 255, y * k / 255, 0xFF); + } + return; + } +#endif + for (unsigned x = 0; x < srcWidth; ++x) { unsigned c = *src++; unsigned m = *src++; unsigned y = *src++; @@ -489,23 +505,31 @@ static void convertCMYKToRGBA(RGBA32Buffer& dest, JSAMPROW src, jpeg_decompress_ // G = 1 - M => 1 - (1 - iM*iK) => iM*iK // B = 1 - Y => 1 - (1 - iY*iK) => iY*iK - // read_scanlines has increased the scanline counter, so we - // actually mean the previous one. - dest.setRGBA(x, info->output_scanline - 1, c * k / 255, m * k / 255, y * k / 255, 0xFF); + dest.setRGBA(x, destY, c * k / 255, m * k / 255, y * k / 255, 0xFF); } } -static void convertRGBToRGBA(RGBA32Buffer& dest, JSAMPROW src, jpeg_decompress_struct* info) +static void convertRGBToRGBA(RGBA32Buffer& dest, int destY, JSAMPROW src, int srcWidth +#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) + , bool scaled, const Vector<int>& scaledColumns +#endif + ) { - ASSERT(info->out_color_space == JCS_RGB); - - for (unsigned x = 0; x < info->output_width; ++x) { +#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) + if (scaled) { + int numColumns = scaledColumns.size(); + for (int x = 0; x < numColumns; ++x) { + JSAMPLE* jsample = src + scaledColumns[x] * 3; + dest.setRGBA(x, destY, jsample[0], jsample[1], jsample[2], 0xFF); + } + return; + } +#endif + for (unsigned x = 0; x < srcWidth; ++x) { unsigned r = *src++; unsigned g = *src++; unsigned b = *src++; - // read_scanlines has increased the scanline counter, so we - // actually mean the previous one. - dest.setRGBA(x, info->output_scanline - 1, r, g, b, 0xFF); + dest.setRGBA(x, destY, r, g, b, 0xFF); } } @@ -517,7 +541,17 @@ bool JPEGImageDecoder::outputScanlines() // Initialize the framebuffer if needed. RGBA32Buffer& buffer = m_frameBufferCache[0]; if (buffer.status() == RGBA32Buffer::FrameEmpty) { - if (!buffer.setSize(size().width(), size().height())) { + int bufferWidth = size().width(); + int bufferHeight = size().height(); +#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) + // Let's resize our buffer now to the correct width/height. + if (m_scaled) { + bufferWidth = m_scaledColumns.size(); + bufferHeight = m_scaledRows.size(); + } +#endif + + if (!buffer.setSize(bufferWidth, bufferHeight)) { m_failed = true; return false; } @@ -532,16 +566,34 @@ bool JPEGImageDecoder::outputScanlines() JSAMPARRAY samples = m_reader->samples(); while (info->output_scanline < info->output_height) { + // jpeg_read_scanlines will increase the scanline counter, so we + // save the scanline before calling it. + int sourceY = info->output_scanline; /* Request one scanline. Returns 0 or 1 scanlines. */ if (jpeg_read_scanlines(info, samples, 1) != 1) return false; + int destY = sourceY; +#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) + if (m_scaled) { + destY = scaledY(sourceY); + if (destY < 0) + continue; + } if (info->out_color_space == JCS_RGB) - convertRGBToRGBA(buffer, *samples, info); + convertRGBToRGBA(buffer, destY, *samples, info->output_width, m_scaled, m_scaledColumns); else if (info->out_color_space == JCS_CMYK) - convertCMYKToRGBA(buffer, *samples, info); + convertCMYKToRGBA(buffer, destY, *samples, info->output_width, m_scaled, m_scaledColumns); else return false; +#else + if (info->out_color_space == JCS_RGB) + convertRGBToRGBA(buffer, destY, *samples, info->output_width); + else if (info->out_color_space == JCS_CMYK) + convertCMYKToRGBA(buffer, destY, *samples, info->output_width); + else + return false; +#endif } return true; diff --git a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h index 56e007d..4a822d7 100644 --- a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h +++ b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2008-2009 Torch Mobile, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -57,6 +58,16 @@ namespace WebCore { bool outputScanlines(); void jpegComplete(); +#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) + bool setSize(int width, int height) + { + if (!ImageDecoder::setSize(width, height)) + return false; + prepareScaleDataIfNecessary(); + return true; + } +#endif + private: JPEGImageReader* m_reader; }; diff --git a/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp b/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp index d14333f..ad79fc8 100644 --- a/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp +++ b/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2006 Apple Computer, Inc. + * Copyright (C) 2007-2009 Torch Mobile, Inc. * * Portions are Copyright (C) 2001 mozilla.org * @@ -242,6 +243,9 @@ void PNGImageDecoder::headerAvailable() longjmp(png->jmpbuf, 1); return; } +#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) + prepareScaleDataIfNecessary(); +#endif } int bitDepth, colorType, interlaceType, compressionType, filterType, channels; @@ -313,7 +317,14 @@ void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex, // Initialize the framebuffer if needed. RGBA32Buffer& buffer = m_frameBufferCache[0]; if (buffer.status() == RGBA32Buffer::FrameEmpty) { - if (!buffer.setSize(size().width(), size().height())) { +#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) + int width = m_scaled ? m_scaledColumns.size() : size().width(); + int height = m_scaled ? m_scaledRows.size() : size().height(); +#else + int width = size().width(); + int height = size().height(); +#endif + if (!buffer.setSize(width, height)) { static_cast<PNGImageDecoder*>(png_get_progressive_ptr(reader()->pngPtr()))->decodingFailed(); longjmp(reader()->pngPtr()->jmpbuf, 1); return; @@ -358,7 +369,7 @@ void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex, * to pass the current row, and the function will combine the * old row and the new row. */ - + png_structp png = reader()->pngPtr(); bool hasAlpha = reader()->hasAlpha(); unsigned colorChannels = hasAlpha ? 4 : 3; @@ -372,8 +383,27 @@ void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex, row = rowBuffer; // Copy the data into our buffer. +#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) + if (m_scaled) { + int destY = scaledY(rowIndex); + if (destY < 0) + return; + int columns = m_scaledColumns.size(); + bool sawAlpha = buffer.hasAlpha(); + for (int x = 0; x < columns; ++x) { + png_bytep pixel = row + m_scaledColumns[x] * 4; + unsigned alpha = pixel[3]; + buffer.setRGBA(x, destY, pixel[0], pixel[1], pixel[2], alpha); + if (!sawAlpha && alpha < 255) { + sawAlpha = true; + buffer.setHasAlpha(true); + } + } + return; + } +#endif int width = size().width(); - bool sawAlpha = false; + bool sawAlpha = buffer.hasAlpha(); for (int x = 0; x < width; x++) { unsigned red = *row++; unsigned green = *row++; diff --git a/WebCore/platform/mac/CookieJar.mm b/WebCore/platform/mac/CookieJar.mm index d8df601..e1d3e5a 100644 --- a/WebCore/platform/mac/CookieJar.mm +++ b/WebCore/platform/mac/CookieJar.mm @@ -27,6 +27,7 @@ #import "CookieJar.h" #import "BlockExceptions.h" +#import "Cookie.h" #import "Document.h" #import "KURL.h" #import <wtf/RetainPtr.h> @@ -116,4 +117,52 @@ bool cookiesEnabled(const Document*) return false; } +bool getRawCookies(const Document*, const KURL& url, Vector<Cookie>& rawCookies) +{ + rawCookies.clear(); + BEGIN_BLOCK_OBJC_EXCEPTIONS; + + NSURL *cookieURL = url; + NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:cookieURL]; + + NSUInteger count = [cookies count]; + rawCookies.reserveCapacity(count); + for (NSUInteger i = 0; i < count; ++i) { + NSHTTPCookie *cookie = (NSHTTPCookie *)[cookies objectAtIndex:i]; + NSString *name = [cookie name]; + NSString *value = [cookie value]; + NSString *domain = [cookie domain]; + NSString *path = [cookie path]; + NSTimeInterval expires = [[cookie expiresDate] timeIntervalSince1970] * 1000; + bool httpOnly = [cookie isHTTPOnly]; + bool secure = [cookie isSecure]; + bool session = [cookie isSessionOnly]; + rawCookies.uncheckedAppend(Cookie(name, value, domain, path, expires, httpOnly, secure, session)); + } + + END_BLOCK_OBJC_EXCEPTIONS; + return true; +} + +void deleteCookie(const Document*, const KURL& url, const String& cookieName) +{ + BEGIN_BLOCK_OBJC_EXCEPTIONS; + + NSURL *cookieURL = url; + NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; + NSArray *cookies = [cookieStorage cookiesForURL:cookieURL]; + NSString *cookieNameString = (NSString *) cookieName; + + NSUInteger count = [cookies count]; + for (NSUInteger i = 0; i < count; ++i) { + NSHTTPCookie *cookie = (NSHTTPCookie *)[cookies objectAtIndex:i]; + if ([[cookie name] isEqualToString:cookieNameString]) { + [cookieStorage deleteCookie:cookie]; + break; + } + } + + END_BLOCK_OBJC_EXCEPTIONS; +} + } diff --git a/WebCore/platform/network/cf/DNSCFNet.cpp b/WebCore/platform/network/cf/DNSCFNet.cpp index bf21ab1..9ae15cb 100644 --- a/WebCore/platform/network/cf/DNSCFNet.cpp +++ b/WebCore/platform/network/cf/DNSCFNet.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2008 Collin Jackson <collinj@webkit.org> + * Copyright (C) 2009 Apple Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,13 +27,33 @@ #include "config.h" #include "DNS.h" -#include "NotImplemented.h" +#include "PlatformString.h" +#include <wtf/RetainPtr.h> + +#ifdef BUILDING_ON_TIGER +// This function is available on Tiger, but not declared in the CFRunLoop.h header on Tiger. +extern "C" CFRunLoopRef CFRunLoopGetMain(); +#endif namespace WebCore { -void prefetchDNS(const String&) +static void clientCallback(CFHostRef theHost, CFHostInfoType, const CFStreamError*, void*) +{ + CFRelease(theHost); +} + +void prefetchDNS(const String& hostname) { - notImplemented(); + RetainPtr<CFStringRef> hostnameCF(AdoptCF, hostname.createCFString()); + RetainPtr<CFHostRef> host(AdoptCF, CFHostCreateWithName(0, hostnameCF.get())); + if (!host) + return; + CFHostClientContext context = { 0, 0, 0, 0, 0 }; + Boolean result = CFHostSetClient(host.get(), clientCallback, &context); + ASSERT_UNUSED(result, result); + CFHostScheduleWithRunLoop(host.get(), CFRunLoopGetMain(), kCFRunLoopCommonModes); + CFHostStartInfoResolution(host.get(), kCFHostAddresses, 0); + host.releaseRef(); // The host will be released from clientCallback(). } } diff --git a/WebCore/platform/network/chromium/CookieJarChromium.cpp b/WebCore/platform/network/chromium/CookieJarChromium.cpp index 65be451..7862cc3 100644 --- a/WebCore/platform/network/chromium/CookieJarChromium.cpp +++ b/WebCore/platform/network/chromium/CookieJarChromium.cpp @@ -31,6 +31,7 @@ #include "config.h" #include "CookieJar.h" +#include "Cookie.h" #include "ChromiumBridge.h" #include "Document.h" @@ -52,4 +53,16 @@ bool cookiesEnabled(const Document*) return true; } +bool getRawCookies(const Document*, const KURL&, Vector<Cookie>& rawCookies) +{ + // FIXME: Not yet implemented + rawCookies.clear(); + return false; // return true when implemented +} + +void deleteCookie(const Document*, const KURL&, const String&) +{ + // FIXME: Not yet implemented +} + } // namespace WebCore diff --git a/WebCore/platform/network/curl/CookieJarCurl.cpp b/WebCore/platform/network/curl/CookieJarCurl.cpp index 5ac0f9c..3bad4e4 100644 --- a/WebCore/platform/network/curl/CookieJarCurl.cpp +++ b/WebCore/platform/network/curl/CookieJarCurl.cpp @@ -17,6 +17,7 @@ #include "config.h" #include "CookieJar.h" +#include "Cookie.h" #include "Document.h" #include "KURL.h" #include "PlatformString.h" @@ -43,4 +44,16 @@ bool cookiesEnabled(const Document* /*document*/) return true; } +bool getRawCookies(const Document*, const KURL&, Vector<Cookie>& rawCookies) +{ + // FIXME: Not yet implemented + rawCookies.clear(); + return false; // return true when implemented +} + +void deleteCookie(const Document*, const KURL&, const String&) +{ + // FIXME: Not yet implemented +} + } diff --git a/WebCore/platform/network/curl/ResourceHandleManager.cpp b/WebCore/platform/network/curl/ResourceHandleManager.cpp index 2aa286a..baca717 100644 --- a/WebCore/platform/network/curl/ResourceHandleManager.cpp +++ b/WebCore/platform/network/curl/ResourceHandleManager.cpp @@ -5,6 +5,8 @@ * Copyright (C) 2007 Holger Hans Peter Freyther * Copyright (C) 2008 Collabora Ltd. * Copyright (C) 2008 Nuanti Ltd. + * Copyright (C) 2009 Appcelerator Inc. + * Copyright (C) 2009 Brent Fulgham <bfulgham@webkit.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -54,10 +56,29 @@ const int maxRunningJobs = 5; static const bool ignoreSSLErrors = getenv("WEBKIT_IGNORE_SSL_ERRORS"); +static CString certificatePath() +{ +#if PLATFORM(CF) + CFBundleRef webKitBundle = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.WebKit")); + RetainPtr<CFURLRef> certURLRef(AdoptCF, CFBundleCopyResourceURL(webKitBundle, CFSTR("cacert"), CFSTR("pem"), CFSTR("certificates"))); + if (certURLRef) { + char path[MAX_PATH]; + CFURLGetFileSystemRepresentation(certURLRef.get(), false, reinterpret_cast<UInt8*>(path), MAX_PATH); + return path; + } +#endif + char* envPath = getenv("CURL_CA_BUNDLE_PATH"); + if (envPath) + return envPath; + + return CString(); +} + ResourceHandleManager::ResourceHandleManager() : m_downloadTimer(this, &ResourceHandleManager::downloadTimerCallback) , m_cookieJarFileName(0) , m_runningJobs(0) + , m_certificatePath (certificatePath()) { curl_global_init(CURL_GLOBAL_ALL); m_curlMultiHandle = curl_multi_init(); @@ -88,6 +109,23 @@ ResourceHandleManager* ResourceHandleManager::sharedInstance() return sharedInstance; } +static void handleLocalReceiveResponse (CURL* handle, ResourceHandle* job, ResourceHandleInternal* d) +{ + // since the code in headerCallback will not have run for local files + // the code to set the URL and fire didReceiveResponse is never run, + // which means the ResourceLoader's response does not contain the URL. + // Run the code here for local files to resolve the issue. + // TODO: See if there is a better approach for handling this. + const char* hdr; + CURLcode err = curl_easy_getinfo(handle, CURLINFO_EFFECTIVE_URL, &hdr); + ASSERT(CURLE_OK == err); + d->m_response.setURL(KURL(hdr)); + if (d->client()) + d->client()->didReceiveResponse(job, d->m_response); + d->m_response.setResponseFired(true); +} + + // called with data after all headers have been processed via headerCallback static size_t writeCallback(void* ptr, size_t size, size_t nmemb, void* data) { @@ -112,18 +150,10 @@ static size_t writeCallback(void* ptr, size_t size, size_t nmemb, void* data) if (CURLE_OK == err && httpCode >= 300 && httpCode < 400) return totalSize; - // since the code in headerCallback will not have run for local files - // the code to set the URL and fire didReceiveResponse is never run, - // which means the ResourceLoader's response does not contain the URL. - // Run the code here for local files to resolve the issue. - // TODO: See if there is a better approach for handling this. if (!d->m_response.responseFired()) { - const char* hdr; - err = curl_easy_getinfo(h, CURLINFO_EFFECTIVE_URL, &hdr); - d->m_response.setURL(KURL(hdr)); - if (d->client()) - d->client()->didReceiveResponse(job, d->m_response); - d->m_response.setResponseFired(true); + handleLocalReceiveResponse(h, job, d); + if (d->m_cancelled) + return 0; } if (d->client()) @@ -222,6 +252,7 @@ size_t readCallback(void* ptr, size_t size, size_t nmemb, void* data) { ResourceHandle* job = static_cast<ResourceHandle*>(data); ResourceHandleInternal* d = job->getInternal(); + if (d->m_cancelled) return 0; @@ -311,6 +342,14 @@ void ResourceHandleManager::downloadTimerCallback(Timer<ResourceHandleManager>* continue; if (CURLE_OK == msg->data.result) { + if (!d->m_response.responseFired()) { + handleLocalReceiveResponse(d->m_handle, job, d); + if (d->m_cancelled) { + removeFromCurl(job); + continue; + } + } + if (d->client()) d->client()->didFinishLoading(job); } else { @@ -629,6 +668,10 @@ void ResourceHandleManager::initializeHandle(ResourceHandle* job) // and/or reporting SSL errors to the user. if (ignoreSSLErrors) curl_easy_setopt(d->m_handle, CURLOPT_SSL_VERIFYPEER, false); + + if (!m_certificatePath.isNull()) + curl_easy_setopt(d->m_handle, CURLOPT_CAINFO, m_certificatePath.data()); + // enable gzip and deflate through Accept-Encoding: curl_easy_setopt(d->m_handle, CURLOPT_ENCODING, ""); diff --git a/WebCore/platform/network/curl/ResourceHandleManager.h b/WebCore/platform/network/curl/ResourceHandleManager.h index d38e577..89b27d7 100644 --- a/WebCore/platform/network/curl/ResourceHandleManager.h +++ b/WebCore/platform/network/curl/ResourceHandleManager.h @@ -29,6 +29,7 @@ #define ResourceHandleManager_h #include "Frame.h" +#include "CString.h" #include "Timer.h" #include "ResourceHandleClient.h" @@ -71,6 +72,7 @@ private: char* m_cookieJarFileName; char m_curlErrorBuffer[CURL_ERROR_SIZE]; Vector<ResourceHandle*> m_resourceHandleList; + const CString m_certificatePath; int m_runningJobs; }; diff --git a/WebCore/platform/network/soup/CookieJarSoup.cpp b/WebCore/platform/network/soup/CookieJarSoup.cpp index 705fdf2..3eb578a 100644 --- a/WebCore/platform/network/soup/CookieJarSoup.cpp +++ b/WebCore/platform/network/soup/CookieJarSoup.cpp @@ -21,6 +21,7 @@ #include "config.h" #include "CookieJarSoup.h" +#include "Cookie.h" #include "CString.h" #include "Document.h" #include "KURL.h" @@ -86,4 +87,16 @@ bool cookiesEnabled(const Document* /*document*/) return defaultCookieJar(); } +bool getRawCookies(const Document*, const KURL&, Vector<Cookie>& rawCookies) +{ + // FIXME: Not yet implemented + rawCookies.clear(); + return false; // return true when implemented +} + +void deleteCookie(const Document*, const KURL&, const String&) +{ + // FIXME: Not yet implemented +} + } diff --git a/WebCore/platform/network/soup/ResourceHandleSoup.cpp b/WebCore/platform/network/soup/ResourceHandleSoup.cpp index 4a22d8a..280fc38 100644 --- a/WebCore/platform/network/soup/ResourceHandleSoup.cpp +++ b/WebCore/platform/network/soup/ResourceHandleSoup.cpp @@ -118,7 +118,7 @@ void WebCoreSynchronousLoader::run() g_main_loop_run(m_mainLoop); } -static void cleanupGioOperation(ResourceHandleInternal* handle); +static void cleanupGioOperation(ResourceHandle* handle, bool isDestroying); static bool startData(ResourceHandle* handle, String urlString); static bool startGio(ResourceHandle* handle, KURL url); @@ -129,8 +129,6 @@ ResourceHandleInternal::~ResourceHandleInternal() m_msg = 0; } - cleanupGioOperation(this); - if (m_idleHandler) { g_source_remove(m_idleHandler); m_idleHandler = 0; @@ -142,6 +140,8 @@ ResourceHandle::~ResourceHandle() if (d->m_msg) g_signal_handlers_disconnect_matched(d->m_msg, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this); + + cleanupGioOperation(this, true); } static void fillResponseFromMessage(SoupMessage* msg, ResourceResponse* response) @@ -276,7 +276,7 @@ static void gotChunkCallback(SoupMessage* msg, SoupBuffer* chunk, gpointer data) // Doesn't get called for redirects. static void finishedCallback(SoupSession *session, SoupMessage* msg, gpointer data) { - RefPtr<ResourceHandle>handle = adoptRef(static_cast<ResourceHandle*>(data)); + RefPtr<ResourceHandle> handle = adoptRef(static_cast<ResourceHandle*>(data)); // TODO: maybe we should run this code even if there's no client? if (!handle) return; @@ -625,8 +625,10 @@ void ResourceHandle::loadResourceSynchronously(const ResourceRequest& request, S // GIO-based loader -static void cleanupGioOperation(ResourceHandleInternal* d) +static void cleanupGioOperation(ResourceHandle* handle, bool isDestroying = false) { + ResourceHandleInternal* d = handle->getInternal(); + if (d->m_gfile) { g_object_set_data(G_OBJECT(d->m_gfile), "webkit-resource", 0); g_object_unref(d->m_gfile); @@ -648,11 +650,14 @@ static void cleanupGioOperation(ResourceHandleInternal* d) g_free(d->m_buffer); d->m_buffer = 0; } + + if (!isDestroying) + handle->deref(); } static void closeCallback(GObject* source, GAsyncResult* res, gpointer) { - ResourceHandle* handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource")); + RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource")); if (!handle) return; @@ -660,13 +665,12 @@ static void closeCallback(GObject* source, GAsyncResult* res, gpointer) ResourceHandleClient* client = handle->client(); g_input_stream_close_finish(d->m_inputStream, res, 0); - cleanupGioOperation(d); - client->didFinishLoading(handle); + cleanupGioOperation(handle.get()); + client->didFinishLoading(handle.get()); } static void readCallback(GObject* source, GAsyncResult* res, gpointer) { - // didReceiveData may cancel the load, which may release the last reference. RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource")); if (!handle) return; @@ -675,7 +679,7 @@ static void readCallback(GObject* source, GAsyncResult* res, gpointer) ResourceHandleClient* client = handle->client(); if (d->m_cancelled || !client) { - cleanupGioOperation(d); + cleanupGioOperation(handle.get()); return; } @@ -690,7 +694,7 @@ static void readCallback(GObject* source, GAsyncResult* res, gpointer) error ? String::fromUTF8(error->message) : String()); g_free(uri); g_error_free(error); - cleanupGioOperation(d); + cleanupGioOperation(handle.get()); client->didFail(handle.get(), resourceError); return; } @@ -704,8 +708,9 @@ static void readCallback(GObject* source, GAsyncResult* res, gpointer) d->m_total += bytesRead; client->didReceiveData(handle.get(), d->m_buffer, bytesRead, d->m_total); + // didReceiveData may cancel the load, which may release the last reference. if (d->m_cancelled) { - cleanupGioOperation(d); + cleanupGioOperation(handle.get()); return; } @@ -716,7 +721,7 @@ static void readCallback(GObject* source, GAsyncResult* res, gpointer) static void openCallback(GObject* source, GAsyncResult* res, gpointer) { - ResourceHandle* handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource")); + RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource")); if (!handle) return; @@ -724,7 +729,7 @@ static void openCallback(GObject* source, GAsyncResult* res, gpointer) ResourceHandleClient* client = handle->client(); if (d->m_cancelled || !client) { - cleanupGioOperation(d); + cleanupGioOperation(handle.get()); return; } @@ -738,8 +743,8 @@ static void openCallback(GObject* source, GAsyncResult* res, gpointer) error ? String::fromUTF8(error->message) : String()); g_free(uri); g_error_free(error); - cleanupGioOperation(d); - client->didFail(handle, resourceError); + cleanupGioOperation(handle.get()); + client->didFail(handle.get(), resourceError); return; } @@ -747,7 +752,8 @@ static void openCallback(GObject* source, GAsyncResult* res, gpointer) d->m_bufferSize = 8192; d->m_buffer = static_cast<char*>(g_malloc(d->m_bufferSize)); d->m_total = 0; - g_object_set_data(G_OBJECT(d->m_inputStream), "webkit-resource", handle); + + g_object_set_data(G_OBJECT(d->m_inputStream), "webkit-resource", handle.get()); g_input_stream_read_async(d->m_inputStream, d->m_buffer, d->m_bufferSize, G_PRIORITY_DEFAULT, d->m_cancellable, readCallback, 0); @@ -755,7 +761,7 @@ static void openCallback(GObject* source, GAsyncResult* res, gpointer) static void queryInfoCallback(GObject* source, GAsyncResult* res, gpointer) { - ResourceHandle* handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource")); + RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource")); if (!handle) return; @@ -763,7 +769,7 @@ static void queryInfoCallback(GObject* source, GAsyncResult* res, gpointer) ResourceHandleClient* client = handle->client(); if (d->m_cancelled) { - cleanupGioOperation(d); + cleanupGioOperation(handle.get()); return; } @@ -790,8 +796,8 @@ static void queryInfoCallback(GObject* source, GAsyncResult* res, gpointer) error ? String::fromUTF8(error->message) : String()); g_free(uri); g_error_free(error); - cleanupGioOperation(d); - client->didFail(handle, resourceError); + cleanupGioOperation(handle.get()); + client->didFail(handle.get(), resourceError); return; } @@ -804,8 +810,8 @@ static void queryInfoCallback(GObject* source, GAsyncResult* res, gpointer) uri, String()); g_free(uri); - cleanupGioOperation(d); - client->didFail(handle, resourceError); + cleanupGioOperation(handle.get()); + client->didFail(handle.get(), resourceError); return; } @@ -816,7 +822,12 @@ static void queryInfoCallback(GObject* source, GAsyncResult* res, gpointer) g_file_info_get_modification_time(info, &tv); response.setLastModifiedDate(tv.tv_sec); - client->didReceiveResponse(handle, response); + client->didReceiveResponse(handle.get(), response); + + if (d->m_cancelled) { + cleanupGioOperation(handle.get()); + return; + } g_file_read_async(d->m_gfile, G_PRIORITY_DEFAULT, d->m_cancellable, openCallback, 0); @@ -852,6 +863,10 @@ static bool startGio(ResourceHandle* handle, KURL url) #endif d->m_gfile = g_file_new_for_uri(url.string().utf8().data()); g_object_set_data(G_OBJECT(d->m_gfile), "webkit-resource", handle); + + // balanced by a deref() in cleanupGioOperation, which should always run + handle->ref(); + d->m_cancellable = g_cancellable_new(); g_file_query_info_async(d->m_gfile, G_FILE_ATTRIBUTE_STANDARD_TYPE "," diff --git a/WebCore/platform/network/win/CookieJarCFNetWin.cpp b/WebCore/platform/network/win/CookieJarCFNetWin.cpp index af9e3f3..519a1b9 100644 --- a/WebCore/platform/network/win/CookieJarCFNetWin.cpp +++ b/WebCore/platform/network/win/CookieJarCFNetWin.cpp @@ -26,6 +26,7 @@ #include "config.h" #include "CookieJar.h" +#include "Cookie.h" #include "CookieStorageWin.h" #include "Document.h" #include "KURL.h" @@ -113,4 +114,16 @@ bool cookiesEnabled(const Document* /*document*/) return policy == CFHTTPCookieStorageAcceptPolicyOnlyFromMainDocumentDomain || policy == CFHTTPCookieStorageAcceptPolicyAlways; } +bool getRawCookies(const Document*, const KURL&, Vector<Cookie>& rawCookies) +{ + // FIXME: Not yet implemented + rawCookies.clear(); + return false; // return true when implemented +} + +void deleteCookie(const Document*, const KURL&, const String&) +{ + // FIXME: Not yet implemented +} + } diff --git a/WebCore/platform/network/win/CookieJarWin.cpp b/WebCore/platform/network/win/CookieJarWin.cpp index 41d12d9..6576e07 100644 --- a/WebCore/platform/network/win/CookieJarWin.cpp +++ b/WebCore/platform/network/win/CookieJarWin.cpp @@ -26,6 +26,7 @@ #include "config.h" #include "CookieJar.h" +#include "Cookie.h" #include "KURL.h" #include "PlatformString.h" #include "Document.h" @@ -35,7 +36,6 @@ namespace WebCore { - void setCookies(Document* /*document*/, const KURL& url, const String& value) { // FIXME: Deal with document->firstPartyForCookies(). @@ -64,4 +64,16 @@ bool cookiesEnabled(const Document* /*document*/) return true; } +bool getRawCookies(const Document*, const KURL&, Vector<Cookie>& rawCookies) +{ + // FIXME: Not yet implemented + rawCookies.clear(); + return false; // return true when implemented +} + +void deleteCookie(const Document*, const KURL&, const String&) +{ + // FIXME: Not yet implemented +} + } diff --git a/WebCore/platform/qt/CookieJarQt.cpp b/WebCore/platform/qt/CookieJarQt.cpp index 40d9309..56d3372 100644 --- a/WebCore/platform/qt/CookieJarQt.cpp +++ b/WebCore/platform/qt/CookieJarQt.cpp @@ -28,6 +28,7 @@ #include "config.h" #include "CookieJar.h" +#include "Cookie.h" #include "Document.h" #include "KURL.h" #include "PlatformString.h" @@ -128,6 +129,18 @@ bool cookiesEnabled(const Document* document) #endif } +bool getRawCookies(const Document*, const KURL&, Vector<Cookie>& rawCookies) +{ + // FIXME: Not yet implemented + rawCookies.clear(); + return false; // return true when implemented +} + +void deleteCookie(const Document*, const KURL&, const String&) +{ + // FIXME: Not yet implemented +} + } // vim: ts=4 sw=4 et diff --git a/WebCore/platform/qt/FileSystemQt.cpp b/WebCore/platform/qt/FileSystemQt.cpp index 28d3ca7..02bc678 100644 --- a/WebCore/platform/qt/FileSystemQt.cpp +++ b/WebCore/platform/qt/FileSystemQt.cpp @@ -81,7 +81,7 @@ bool makeAllDirectories(const String& path) String pathByAppendingComponent(const String& path, const String& component) { - return QDir(path).filePath(component); + return QDir::toNativeSeparators(QDir(path).filePath(component)); } String homeDirectoryPath() diff --git a/WebCore/platform/text/PlatformString.h b/WebCore/platform/text/PlatformString.h index 6d5384f..258b28d 100644 --- a/WebCore/platform/text/PlatformString.h +++ b/WebCore/platform/text/PlatformString.h @@ -56,6 +56,10 @@ QT_END_NAMESPACE class wxString; #endif +#if PLATFORM(HAIKU) +class BString; +#endif + namespace WebCore { class CString; @@ -229,6 +233,11 @@ public: operator wxString() const; #endif +#if PLATFORM(HAIKU) + String(const BString&); + operator BString() const; +#endif + #ifndef NDEBUG Vector<char> ascii() const; #endif diff --git a/WebCore/platform/text/UnicodeRange.h b/WebCore/platform/text/UnicodeRange.h index 7ecf03f..2278a0e 100644 --- a/WebCore/platform/text/UnicodeRange.h +++ b/WebCore/platform/text/UnicodeRange.h @@ -35,6 +35,10 @@ #ifndef UnicodeRange_H #define UnicodeRange_H +#if PLATFORM(HAIKU) +#include "stdint.h" +#endif + #include <wtf/unicode/Unicode.h> namespace WebCore { diff --git a/WebCore/platform/text/haiku/TextBreakIteratorInternalICUHaiku.cpp b/WebCore/platform/text/haiku/TextBreakIteratorInternalICUHaiku.cpp index 2c732d6..8bb8c70 100644 --- a/WebCore/platform/text/haiku/TextBreakIteratorInternalICUHaiku.cpp +++ b/WebCore/platform/text/haiku/TextBreakIteratorInternalICUHaiku.cpp @@ -26,6 +26,12 @@ namespace WebCore { +const char* currentSearchLocaleID() +{ + notImplemented(); + return ""; +} + const char* currentTextBreakLocaleID() { notImplemented(); diff --git a/WebCore/platform/text/mac/TextCodecMac.cpp b/WebCore/platform/text/mac/TextCodecMac.cpp index 93b9da2..1152cc2 100644 --- a/WebCore/platform/text/mac/TextCodecMac.cpp +++ b/WebCore/platform/text/mac/TextCodecMac.cpp @@ -36,7 +36,7 @@ #include <wtf/PassOwnPtr.h> #include <wtf/Threading.h> -using std::min; +using namespace std; namespace WebCore { @@ -141,7 +141,7 @@ OSStatus TextCodecMac::decode(const unsigned char* inputBuffer, int inputBufferL // First, fill the partial character buffer with as many bytes as are available. ASSERT(m_numBufferedBytes < sizeof(m_bufferedBytes)); const int spaceInBuffer = sizeof(m_bufferedBytes) - m_numBufferedBytes; - const int bytesToPutInBuffer = MIN(spaceInBuffer, inputBufferLength); + const int bytesToPutInBuffer = min(spaceInBuffer, inputBufferLength); ASSERT(bytesToPutInBuffer != 0); memcpy(m_bufferedBytes + m_numBufferedBytes, inputBuffer, bytesToPutInBuffer); diff --git a/WebCore/platform/win/PopupMenuWin.cpp b/WebCore/platform/win/PopupMenuWin.cpp index e53053f..216c7c5 100644 --- a/WebCore/platform/win/PopupMenuWin.cpp +++ b/WebCore/platform/win/PopupMenuWin.cpp @@ -94,6 +94,11 @@ PopupMenu::~PopupMenu() ::DestroyWindow(m_popup); } +LPCTSTR PopupMenu::popupClassName() +{ + return kPopupWindowClassName; +} + void PopupMenu::show(const IntRect& r, FrameView* v, int index) { calculatePositionAndSize(r, v); diff --git a/WebCore/platform/wince/CursorWince.cpp b/WebCore/platform/wince/CursorWince.cpp new file mode 100644 index 0000000..e35f1f9 --- /dev/null +++ b/WebCore/platform/wince/CursorWince.cpp @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2008-2009 Torch Mobile Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "Cursor.h" + +namespace WebCore { + +struct AllCursors { + AllCursors() + { + for (int i = 0; i < NumCursorTypes; ++i) + m_cursors[i] = (CursorType) i; + } + Cursor m_cursors[NumCursorTypes]; +}; + +static const Cursor& getCursor(CursorType type) +{ + static AllCursors allCursors; + return allCursors.m_cursors[type]; +} + +Cursor::Cursor(const Cursor& other) +: m_impl(other.m_impl) +{ +} + +Cursor::Cursor(Image* img, const IntPoint& hotspot) +: m_impl(CursorNone) +{ +} + +Cursor::~Cursor() +{ +} + +Cursor& Cursor::operator=(const Cursor& other) +{ + m_impl = other.m_impl; + return *this; +} + +Cursor::Cursor(PlatformCursor c) +: m_impl(c) +{ +} + +const Cursor& noneCursor() { return getCursor(CursorNone); } +const Cursor& pointerCursor() { return getCursor(CursorPointer); } +const Cursor& crossCursor() { return getCursor(CursorCross); } +const Cursor& handCursor() { return getCursor(CursorHand); } +const Cursor& iBeamCursor() { return getCursor(CursorBeam); } +const Cursor& waitCursor() { return getCursor(CursorWait); } +const Cursor& helpCursor() { return getCursor(CursorHelp); } +const Cursor& moveCursor() { return getCursor(CursorMove); } +const Cursor& eastResizeCursor() { return getCursor(CursorEastResize); } +const Cursor& northResizeCursor() { return getCursor(CursorNorthResize); } +const Cursor& northEastResizeCursor() { return getCursor(CursorNorthEastResize); } +const Cursor& northWestResizeCursor() { return getCursor(CursorNorthWestResize); } +const Cursor& southResizeCursor() { return getCursor(CursorSouthResize); } +const Cursor& southEastResizeCursor() { return getCursor(CursorSouthEastResize); } +const Cursor& southWestResizeCursor() { return getCursor(CursorSouthWestResize); } +const Cursor& westResizeCursor() { return getCursor(CursorWestResize); } +const Cursor& northSouthResizeCursor() { return getCursor(CursorNorthSouthResize); } +const Cursor& eastWestResizeCursor() { return getCursor(CursorEastWestResize); } +const Cursor& northEastSouthWestResizeCursor() { return getCursor(CursorNorthEastSouthWestResize); } +const Cursor& northWestSouthEastResizeCursor() { return getCursor(CursorNorthWestSouthEastResize); } +const Cursor& columnResizeCursor() { return getCursor(CursorColumnResize); } +const Cursor& rowResizeCursor() { return getCursor(CursorRowResize); } +const Cursor& verticalTextCursor() { return getCursor(CursorVerticalText); } +const Cursor& cellCursor() { return getCursor(CursorCell); } +const Cursor& contextMenuCursor() { return getCursor(CursorContextMenu); } +const Cursor& noDropCursor() { return getCursor(CursorNoDrop); } +const Cursor& notAllowedCursor() { return getCursor(CursorNotAllowed); } +const Cursor& progressCursor() { return getCursor(CursorProgress); } +const Cursor& aliasCursor() { return getCursor(CursorAlias); } +const Cursor& zoomInCursor() { return getCursor(CursorZoomIn); } +const Cursor& zoomOutCursor() { return getCursor(CursorZoomOut); } +const Cursor& copyCursor() { return getCursor(CursorCopy); } +const Cursor& middlePanningCursor() { return crossCursor(); } +const Cursor& eastPanningCursor() { return crossCursor(); } +const Cursor& northPanningCursor() { return crossCursor(); } +const Cursor& northEastPanningCursor() { return crossCursor(); } +const Cursor& northWestPanningCursor() { return crossCursor(); } +const Cursor& southPanningCursor() { return crossCursor(); } +const Cursor& southEastPanningCursor() { return crossCursor(); } +const Cursor& southWestPanningCursor() { return crossCursor(); } +const Cursor& westPanningCursor() { return crossCursor(); } +const Cursor& grabbingCursor() { return moveCursor(); } +const Cursor& grabCursor() { return moveCursor(); } + +} diff --git a/WebCore/platform/wince/DragDataWince.cpp b/WebCore/platform/wince/DragDataWince.cpp new file mode 100644 index 0000000..881d7d4 --- /dev/null +++ b/WebCore/platform/wince/DragDataWince.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2007-2008 Torch Mobile, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#include "config.h" +#include "DragData.h" + +#include "Clipboard.h" +#include "DocumentFragment.h" +#include "PlatformString.h" + +namespace WebCore { + +PassRefPtr<Clipboard> DragData::createClipboard(ClipboardAccessPolicy policy) const +{ + return 0; +} + +bool DragData::containsURL() const +{ + return false; +} + +String DragData::asURL(String* title) const +{ + return String(); +} + +bool DragData::containsFiles() const +{ + return false; +} + +void DragData::asFilenames(Vector<String>&) const +{ +} + +bool DragData::containsPlainText() const +{ + return false; +} + +String DragData::asPlainText() const +{ + return String(); +} + +bool DragData::containsColor() const +{ + return false; +} + +bool DragData::canSmartReplace() const +{ + return false; +} + +bool DragData::containsCompatibleContent() const +{ + return false; +} + +PassRefPtr<DocumentFragment> DragData::asFragment(Document* doc) const +{ + return 0; +} + +Color DragData::asColor() const +{ + return Color(); +} + +} + diff --git a/WebCore/platform/wince/DragImageWince.cpp b/WebCore/platform/wince/DragImageWince.cpp new file mode 100644 index 0000000..4d60f80 --- /dev/null +++ b/WebCore/platform/wince/DragImageWince.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2007-2008 Torch Mobile, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#include "config.h" +#include "DragImage.h" + +#include "CachedImage.h" +#include "GraphicsContext.h" +#include "Image.h" + +#include <windows.h> + +namespace WebCore { + +IntSize dragImageSize(DragImageRef) +{ + return IntSize(0, 0); +} + +void deleteDragImage(DragImageRef image) +{ + if (image) + ::DeleteObject(image); +} + +DragImageRef scaleDragImage(DragImageRef, FloatSize) +{ + return 0; +} + +DragImageRef dissolveDragImageToFraction(DragImageRef image, float) +{ + return image; +} + +DragImageRef createDragImageFromImage(Image*) +{ + return 0; +} + +DragImageRef createDragImageIconForCachedImage(CachedImage*) +{ + return 0; +} + +} diff --git a/WebCore/platform/wince/EditorWince.cpp b/WebCore/platform/wince/EditorWince.cpp new file mode 100644 index 0000000..02af780 --- /dev/null +++ b/WebCore/platform/wince/EditorWince.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2007-2008 Torch Mobile, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#include "config.h" + +#include "Editor.h" + +#include "ClipboardWince.h" +#include "Document.h" +#include "EditorClient.h" +#include "Element.h" +#include "HtmlEditing.h" +#include "TextIterator.h" +#include "visible_units.h" + +#include <windows.h> +#define _SYS_GUID_OPERATORS_ + +namespace WebCore { + +PassRefPtr<Clipboard> Editor::newGeneralClipboard(ClipboardAccessPolicy policy) +{ + return adoptRef(new ClipboardWince(policy, false)); +} + +} // namespace WebCore diff --git a/WebCore/platform/wince/FileChooserWince.cpp b/WebCore/platform/wince/FileChooserWince.cpp new file mode 100644 index 0000000..07c99b1 --- /dev/null +++ b/WebCore/platform/wince/FileChooserWince.cpp @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2007-2009 Torch Mobile, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "FileChooser.h" + +#include "Chrome.h" +#include "ChromeClient.h" +#include "Document.h" +#include "Frame.h" +#include "Icon.h" +#include "LocalizedStrings.h" +#include "Page.h" +#include "StringTruncator.h" + +namespace WebCore { + +String pathGetFileName(const String& path); + +String FileChooser::basenameForWidth(const Font& font, int width) const +{ + if (width <= 0) + return String(); + + String string; + if (m_filenames.isEmpty()) + string = fileButtonNoFileSelectedLabel(); + else if (m_filenames.size() == 1) { + String tmpFilename = m_filenames[0]; + string = pathGetFileName(tmpFilename); + } else + return StringTruncator::rightTruncate(String::number(m_filenames.size()) + " files", width, font, false); + + return StringTruncator::centerTruncate(string, width, font, false); +} + +} diff --git a/WebCore/platform/wince/FileSystemWince.cpp b/WebCore/platform/wince/FileSystemWince.cpp new file mode 100644 index 0000000..2bb4dd5 --- /dev/null +++ b/WebCore/platform/wince/FileSystemWince.cpp @@ -0,0 +1,283 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * Copyright (C) 2008 Collabora, Ltd. All rights reserved. + * Copyright (C) 2007-2009 Torch Mobile, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "FileSystem.h" + +#include "CString.h" +#include "PlatformString.h" + +#include <windows.h> +#include <wincrypt.h> + +namespace WebCore { + +static bool getFileInfo(const String& path, BY_HANDLE_FILE_INFORMATION& fileInfo) +{ + String filename = path; + HANDLE hFile = CreateFile(filename.charactersWithNullTermination(), GENERIC_READ, FILE_SHARE_READ, 0 + , OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, 0); + + if (hFile == INVALID_HANDLE_VALUE) + return false; + + bool rtn = GetFileInformationByHandle(hFile, &fileInfo) ? true : false; + + CloseHandle(hFile); + return rtn; +} + +bool getFileSize(const String& path, long long& result) +{ + BY_HANDLE_FILE_INFORMATION fileInformation; + if (!getFileInfo(path, fileInformation)) + return false; + + ULARGE_INTEGER fileSize; + fileSize.LowPart = fileInformation.nFileSizeLow; + fileSize.HighPart = fileInformation.nFileSizeHigh; + + result = fileSize.QuadPart; + + return true; +} + +bool getFileModificationTime(const String& path, time_t& result) +{ + BY_HANDLE_FILE_INFORMATION fileInformation; + if (!getFileInfo(path, fileInformation)) + return false; + + ULARGE_INTEGER t; + memcpy(&t, &fileInformation.ftLastWriteTime, sizeof(t)); + + result = t.QuadPart * 0.0000001 - 11644473600.0; + + return true; +} + +bool fileExists(const String& path) +{ + String filename = path; + HANDLE hFile = CreateFile(filename.charactersWithNullTermination(), 0, FILE_SHARE_READ | FILE_SHARE_WRITE + , 0, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, 0); + + CloseHandle(hFile); + + return hFile != INVALID_HANDLE_VALUE; +} + +bool deleteFile(const String& path) +{ + String filename = path; + return !!DeleteFileW(filename.charactersWithNullTermination()); +} + + +bool deleteEmptyDirectory(const String& path) +{ + String filename = path; + return !!RemoveDirectoryW(filename.charactersWithNullTermination()); +} + +String pathByAppendingComponent(const String& path, const String& component) +{ + if (component.isEmpty()) + return path; + + Vector<UChar, MAX_PATH> buffer; + + buffer.append(path.characters(), path.length()); + + if (buffer.last() != L'\\' && buffer.last() != L'/' + && component[0] != L'\\' && component[0] != L'/') + buffer.append(L'\\'); + + buffer.append(component.characters(), component.length()); + + return String(buffer.data(), buffer.size()); +} + +CString fileSystemRepresentation(const String&) +{ + return ""; +} + +bool makeAllDirectories(const String& path) +{ + int lastDivPos = max(path.reverseFind('/'), path.reverseFind('\\')); + int endPos = path.length(); + if (lastDivPos == path.length() - 1) { + endPos -= 1; + lastDivPos = max(path.reverseFind('/', lastDivPos), path.reverseFind('\\', lastDivPos)); + } + + if (lastDivPos > 0) { + if (!makeAllDirectories(path.substring(0, lastDivPos))) + return false; + } + + String folder(path.substring(0, endPos)); + CreateDirectory(folder.charactersWithNullTermination(), 0); + + DWORD fileAttr = GetFileAttributes(folder.charactersWithNullTermination()); + return fileAttr != 0xFFFFFFFF && (fileAttr & FILE_ATTRIBUTE_DIRECTORY); +} + +String homeDirectoryPath() +{ + notImplemented(); + return ""; +} + +String pathGetFileName(const String& path) +{ + return path.substring(max(path.reverseFind('/'), path.reverseFind('\\')) + 1); +} + +String directoryName(const String& path) +{ + notImplemented(); + return String(); +} + +CString openTemporaryFile(const char*, PlatformFileHandle& handle) +{ + handle = INVALID_HANDLE_VALUE; + + wchar_t tempPath[MAX_PATH]; + int tempPathLength = ::GetTempPath(_countof(tempPath), tempPath); + if (tempPathLength <= 0 || tempPathLength > _countof(tempPath)) + return CString(); + + HCRYPTPROV hCryptProv = 0; + if (!CryptAcquireContext(&hCryptProv, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) + return CString(); + + String proposedPath; + while (1) { + + wchar_t tempFile[] = L"XXXXXXXX.tmp"; // Use 8.3 style name (more characters aren't helpful due to 8.3 short file names) + const int randomPartLength = 8; + if (!CryptGenRandom(hCryptProv, randomPartLength * 2, reinterpret_cast<BYTE*>(tempFile))) + break; + + // Limit to valid filesystem characters, also excluding others that could be problematic, like punctuation. + // don't include both upper and lowercase since Windows file systems are typically not case sensitive. + const char validChars[] = "0123456789abcdefghijklmnopqrstuvwxyz"; + for (int i = 0; i < randomPartLength; ++i) + tempFile[i] = validChars[tempFile[i] % (sizeof(validChars) - 1)]; + + ASSERT(wcslen(tempFile) * 2 == sizeof(tempFile) - 2); + + proposedPath = pathByAppendingComponent(String(tempPath), String(tempFile)); + + // use CREATE_NEW to avoid overwriting an existing file with the same name + handle = CreateFile(proposedPath.charactersWithNullTermination(), GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0); + if (!isHandleValid(handle) && GetLastError() == ERROR_ALREADY_EXISTS) + continue; + + break; + } + + CryptReleaseContext(hCryptProv, 0); + + if (!isHandleValid(handle)) + return CString(); + + return proposedPath.latin1(); +} + +void closeFile(PlatformFileHandle& handle) +{ + if (isHandleValid(handle)) { + ::CloseHandle(handle); + handle = invalidPlatformFileHandle; + } +} + +int writeToFile(PlatformFileHandle handle, const char* data, int length) +{ + if (!isHandleValid(handle)) + return -1; + + DWORD bytesWritten; + bool success = WriteFile(handle, data, length, &bytesWritten, 0); + + if (!success) + return -1; + return static_cast<int>(bytesWritten); +} + +bool unloadModule(PlatformModule module) +{ + return ::FreeLibrary(module); +} + +String localUserSpecificStorageDirectory() +{ + return String(L"\\"); +} + +String roamingUserSpecificStorageDirectory() +{ + return String(L"\\"); +} + +Vector<String> listDirectory(const String& path, const String& filter) +{ + Vector<String> entries; + + Vector<UChar, 256> pattern; + pattern.append(path.characters(), path.length()); + if (pattern.last() != L'/' && pattern.last() != L'\\') + pattern.append(L'\\'); + + String root(pattern.data(), pattern.size()); + pattern.append(filter.characters(), filter.length()); + pattern.append(0); + + WIN32_FIND_DATA findData; + HANDLE hFind = FindFirstFile(pattern.data(), &findData); + if (INVALID_HANDLE_VALUE != hFind) { + do { + // FIXEME: should we also add the folders? This function + // is so far only called by PluginDatabase.cpp to list + // all plugins in a folder, where it's not supposed to list sub-folders. + if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + entries.append(root + findData.cFileName); + } while (FindNextFile(hFind, &findData)); + FindClose(hFind); + } + + return entries; +} + +} diff --git a/WebCore/platform/wince/KURLWince.cpp b/WebCore/platform/wince/KURLWince.cpp new file mode 100644 index 0000000..5ca1e4b --- /dev/null +++ b/WebCore/platform/wince/KURLWince.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2009 Torch Mobile Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "KURL.h" + +namespace WebCore { + +String KURL::fileSystemPath() const +{ + return path(); +} + +} diff --git a/WebCore/platform/wince/KeygenWince.cpp b/WebCore/platform/wince/KeygenWince.cpp new file mode 100644 index 0000000..b0f4d63 --- /dev/null +++ b/WebCore/platform/wince/KeygenWince.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2008-2009 Torch Mobile Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "SSLKeyGenerator.h" + +#include "Base64.h" +#include "CString.h" + +#include <windows.h> +#include <wincrypt.h> + +namespace WebCore { + +void WebCore::getSupportedKeySizes(Vector<String>& v) +{ + v.append("High Grade"); + v.append("Medium Grade"); +} + +String WebCore::signedPublicKeyAndChallengeString(unsigned index, const String& challenge, const KURL& url) +{ + String keyString; + + HCRYPTPROV hContext = 0; + HCRYPTKEY hKey = 0; + PCERT_PUBLIC_KEY_INFO pPubInfo = 0; + + // Try to delete it if it exists already + CryptAcquireContext(&hContext, _T("keygen_container"), MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET); + + do { + if (!CryptAcquireContext(&hContext, _T("keygen_container"), MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET)) + break; + + DWORD dwPubInfoLength = 0; + if (!CryptGenKey(hContext, AT_KEYEXCHANGE, 0, &hKey) || !CryptExportPublicKeyInfo(hContext, AT_KEYEXCHANGE, X509_ASN_ENCODING, 0, &dwPubInfoLength)) + break; + + // Use malloc instead of new, because malloc guarantees to return a pointer aligned for all data types. + pPubInfo = reinterpret_cast<PCERT_PUBLIC_KEY_INFO>(fastMalloc(dwPubInfoLength)); + + if (!CryptExportPublicKeyInfo(hContext, AT_KEYEXCHANGE, X509_ASN_ENCODING, pPubInfo, &dwPubInfoLength)) + break; + + CERT_KEYGEN_REQUEST_INFO requestInfo = { 0 }; + requestInfo.dwVersion = CERT_KEYGEN_REQUEST_V1; + requestInfo.pwszChallengeString = L""; + requestInfo.SubjectPublicKeyInfo = *pPubInfo; + + String localChallenge = challenge; + + // Windows API won't write to our buffer, although it's not declared with const. + requestInfo.pwszChallengeString = const_cast<wchar_t*>(localChallenge.charactersWithNullTermination()); + + CRYPT_ALGORITHM_IDENTIFIER signAlgo = { 0 }; + signAlgo.pszObjId = szOID_RSA_SHA1RSA; + + DWORD dwEncodedLength; + if (!CryptSignAndEncodeCertificate(hContext, AT_KEYEXCHANGE, X509_ASN_ENCODING, X509_KEYGEN_REQUEST_TO_BE_SIGNED, &requestInfo, &signAlgo, 0, 0, &dwEncodedLength)) + break; + + Vector<char> binary(dwEncodedLength); + if (!CryptSignAndEncodeCertificate(hContext, AT_KEYEXCHANGE, X509_ASN_ENCODING, X509_KEYGEN_REQUEST_TO_BE_SIGNED, &requestInfo, &signAlgo, 0, reinterpret_cast<LPBYTE>(binary.data()), &dwEncodedLength)) + break; + + Vector<char> base64; + base64Encode(binary, base64); + keyString = String(base64.data(), base64.size()); + + } while(0); + + if (pPubInfo) + fastFree(pPubInfo); + + if (hKey) + CryptDestroyKey(hKey); + + if (hContext) + CryptReleaseContext(hContext, 0); + + return keyString; +} + +} // namespace WebCore diff --git a/WebCore/platform/wince/MIMETypeRegistryWince.cpp b/WebCore/platform/wince/MIMETypeRegistryWince.cpp new file mode 100644 index 0000000..2ecde48 --- /dev/null +++ b/WebCore/platform/wince/MIMETypeRegistryWince.cpp @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2007-2009 Torch Mobile, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "MIMETypeRegistry.h" + +#include <windows.h> +#include <winreg.h> + +namespace WebCore { + +static String mimeTypeForExtension(const String& extension) +{ + String ext = "." + extension; + WCHAR contentTypeStr[256]; + DWORD contentTypeStrLen = sizeof(contentTypeStr); + DWORD valueType; + + HKEY key; + String result; + if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_CLASSES_ROOT, ext.charactersWithNullTermination(), 0, 0, &key)) + return result; + + if (ERROR_SUCCESS == RegQueryValueEx(key, L"Content Type", 0, &valueType, (LPBYTE)contentTypeStr, &contentTypeStrLen) && valueType == REG_SZ) + result = String(contentTypeStr, contentTypeStrLen / sizeof(contentTypeStr[0]) - 1); + + RegCloseKey(key); + + return result; +} + +static HashMap<String, String> mimetypeMap; + +static void initMIMETypeEntensionMap() +{ + if (mimetypeMap.isEmpty()) { + //fill with initial values + mimetypeMap.add("txt", "text/plain"); + mimetypeMap.add("pdf", "application/pdf"); + mimetypeMap.add("ps", "application/postscript"); + mimetypeMap.add("html", "text/html"); + mimetypeMap.add("htm", "text/html"); + mimetypeMap.add("xml", "text/xml"); + mimetypeMap.add("xsl", "text/xsl"); + mimetypeMap.add("js", "application/x-javascript"); + mimetypeMap.add("xhtml", "application/xhtml+xml"); + mimetypeMap.add("rss", "application/rss+xml"); + mimetypeMap.add("webarchive", "application/x-webarchive"); + mimetypeMap.add("svg", "image/svg+xml"); + mimetypeMap.add("svgz", "image/svg+xml"); + mimetypeMap.add("jpg", "image/jpeg"); + mimetypeMap.add("jpeg", "image/jpeg"); + mimetypeMap.add("png", "image/png"); + mimetypeMap.add("tif", "image/tiff"); + mimetypeMap.add("tiff", "image/tiff"); + mimetypeMap.add("ico", "image/ico"); + mimetypeMap.add("cur", "image/ico"); + mimetypeMap.add("bmp", "image/bmp"); + mimetypeMap.add("css", "text/css"); + // FIXME: Custom font works only when MIME is "text/plain" + mimetypeMap.add("ttf", "text/plain"); // "font/ttf" + mimetypeMap.add("otf", "text/plain"); // "font/otf" +#if ENABLE(WML) + mimetypeMap.add("wml", "text/vnd.wap.wml"); +#endif +#if ENABLE(WBXML) + mimetypeMap.add("wbxml", "application/vnd.wap.wmlc"); +#endif + } +} + +String MIMETypeRegistry::getPreferredExtensionForMIMEType(const String& type) +{ + if (type.isEmpty()) + return String(); + + // Avoid conflicts with "ttf" and "otf" + if (equalIgnoringCase(type, "text/plain")) + return "txt"; + + initMIMETypeEntensionMap(); + + for (HashMap<String, String>::iterator i = mimetypeMap.begin(); i != mimetypeMap.end(); ++i) { + if (equalIgnoringCase(i->second, type)) + return i->first; + } + +#if ENABLE(XHTMLMP) + if (equalIgnoringCase("application/vnd.wap.xhtml+xml", type)) + return String("xml"); +#endif + + return String(); +} + +String MIMETypeRegistry::getMIMETypeForExtension(const String &ext) +{ + if (ext.isEmpty()) + return String(); + + initMIMETypeEntensionMap(); + + String result = mimetypeMap.get(ext.lower()); + if (result.isEmpty()) { + result = mimeTypeForExtension(ext); + if (!result.isEmpty()) + mimetypeMap.add(ext, result); + } + return result.isEmpty() ? "unknown/unknown" : result; +} + +} diff --git a/WebCore/platform/wince/PasteboardWince.cpp b/WebCore/platform/wince/PasteboardWince.cpp new file mode 100644 index 0000000..cba85b8 --- /dev/null +++ b/WebCore/platform/wince/PasteboardWince.cpp @@ -0,0 +1,315 @@ +/* + * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2007-2009 Torch Mobile, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "config.h" +#include "Pasteboard.h" + +#include "CString.h" +#include "ClipboardUtilitiesWin.h" +#include "Document.h" +#include "DocumentFragment.h" +#include "Element.h" +#include "Frame.h" +#include "HitTestResult.h" +#include "Image.h" +#include "KURL.h" +#include "Page.h" +#include "Range.h" +#include "RenderImage.h" +#include "TextEncoding.h" +#include "markup.h" + +namespace WebCore { + +static UINT HTMLClipboardFormat = 0; +static UINT BookmarkClipboardFormat = 0; +static UINT WebSmartPasteFormat = 0; + +extern HDC hScreenDC; + +static LRESULT CALLBACK PasteboardOwnerWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + LRESULT lresult = 0; + LONG longPtr = GetWindowLong(hWnd, 0); + + switch (message) { + case WM_RENDERFORMAT: + // This message comes when SetClipboardData was sent a null data handle + // and now it's come time to put the data on the clipboard. + break; + case WM_RENDERALLFORMATS: + // This message comes when SetClipboardData was sent a null data handle + // and now this application is about to quit, so it must put data on + // the clipboard before it exits. + break; + case WM_DESTROY: + break; + default: + lresult = DefWindowProc(hWnd, message, wParam, lParam); + break; + } + return lresult; +} + +Pasteboard* Pasteboard::generalPasteboard() +{ + static Pasteboard* pasteboard = new Pasteboard; + return pasteboard; +} + +Pasteboard::Pasteboard() +{ + // make a dummy HWND to be the Windows clipboard's owner + WNDCLASS wc = {0}; + memset(&wc, 0, sizeof(wc)); + wc.lpfnWndProc = PasteboardOwnerWndProc; + wc.hInstance = Page::instanceHandle(); + wc.lpszClassName = L"PasteboardOwnerWindowClass"; + ::RegisterClass(&wc); + + m_owner = ::CreateWindow(L"PasteboardOwnerWindowClass", L"PasteboardOwnerWindow", 0, 0, 0, 0, 0, + HWND_MESSAGE, 0, 0, 0); + + HTMLClipboardFormat = ::RegisterClipboardFormat(L"HTML Format"); + BookmarkClipboardFormat = ::RegisterClipboardFormat(L"UniformResourceLocatorW"); + WebSmartPasteFormat = ::RegisterClipboardFormat(L"WebKit Smart Paste Format"); +} + +void Pasteboard::clear() +{ + if (::OpenClipboard(m_owner)) { + ::EmptyClipboard(); + ::CloseClipboard(); + } +} + +void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete, Frame* frame) +{ + clear(); + + // Put CF_HTML format on the pasteboard + if (::OpenClipboard(m_owner)) { + ExceptionCode ec = 0; + Vector<char> data; + markupToCF_HTML(createMarkup(selectedRange, 0, AnnotateForInterchange), selectedRange->startContainer(ec)->document()->url(), data); + HGLOBAL cbData = createGlobalData(data); + if (!::SetClipboardData(HTMLClipboardFormat, cbData)) + ::GlobalFree(cbData); + ::CloseClipboard(); + } + + // Put plain string on the pasteboard. CF_UNICODETEXT covers CF_TEXT as well + String str = frame->selectedText(); + replaceNewlinesWithWindowsStyleNewlines(str); + replaceNBSPWithSpace(str); + if (::OpenClipboard(m_owner)) { + HGLOBAL cbData = createGlobalData(str); + if (!::SetClipboardData(CF_UNICODETEXT, cbData)) + ::GlobalFree(cbData); + ::CloseClipboard(); + } + + // enable smart-replacing later on by putting dummy data on the pasteboard + if (canSmartCopyOrDelete) { + if (::OpenClipboard(m_owner)) { + ::SetClipboardData(WebSmartPasteFormat, 0); + ::CloseClipboard(); + } + } +} + +void Pasteboard::writeURL(const KURL& url, const String& titleStr, Frame* frame) +{ + ASSERT(!url.isEmpty()); + + clear(); + + String title(titleStr); + if (title.isEmpty()) { + title = url.lastPathComponent(); + if (title.isEmpty()) + title = url.host(); + } + + // write to clipboard in format com.apple.safari.bookmarkdata to be able to paste into the bookmarks view with appropriate title + if (::OpenClipboard(m_owner)) { + HGLOBAL cbData = createGlobalData(url, title); + if (!::SetClipboardData(BookmarkClipboardFormat, cbData)) + ::GlobalFree(cbData); + ::CloseClipboard(); + } + + // write to clipboard in format CF_HTML to be able to paste into contenteditable areas as a link + if (::OpenClipboard(m_owner)) { + Vector<char> data; + markupToCF_HTML(urlToMarkup(url, title), "", data); + HGLOBAL cbData = createGlobalData(data); + if (!::SetClipboardData(HTMLClipboardFormat, cbData)) + ::GlobalFree(cbData); + ::CloseClipboard(); + } + + // bare-bones CF_UNICODETEXT support + if (::OpenClipboard(m_owner)) { + HGLOBAL cbData = createGlobalData(url.string()); + if (!::SetClipboardData(CF_UNICODETEXT, cbData)) + ::GlobalFree(cbData); + ::CloseClipboard(); + } +} + +void Pasteboard::writeImage(Node* node, const KURL&, const String&) +{ + ASSERT(node && node->renderer() && node->renderer()->isImage()); + RenderImage* renderer = static_cast<RenderImage*>(node->renderer()); + CachedImage* cachedImage = static_cast<CachedImage*>(renderer->cachedImage()); + ASSERT(cachedImage); + Image* image = cachedImage->image(); + ASSERT(image); + + clear(); + + RefPtr<SharedBitmap> sourceBmp = image->nativeImageForCurrentFrame(); + if (!sourceBmp) + return; + + IntRect rect(0, 0, sourceBmp->width(), sourceBmp->height()); + BitmapInfo bmpInfo; + void* pixels; + HBITMAP resultBitmap = sourceBmp->clipBitmap(rect, true, bmpInfo, pixels); + if (!resultBitmap) + return; + + if (::OpenClipboard(m_owner)) { + ::SetClipboardData(CF_BITMAP, resultBitmap); + ::CloseClipboard(); + } else + DeleteObject(resultBitmap); +} + +bool Pasteboard::canSmartReplace() +{ + return ::IsClipboardFormatAvailable(WebSmartPasteFormat); +} + +String Pasteboard::plainText(Frame* frame) +{ + if (::IsClipboardFormatAvailable(CF_UNICODETEXT) && ::OpenClipboard(m_owner)) { + HANDLE cbData = ::GetClipboardData(CF_UNICODETEXT); + if (cbData) { + UChar* buffer = (UChar*)GlobalLock(cbData); + String fromClipboard(buffer); + GlobalUnlock(cbData); + CloseClipboard(); + return fromClipboard; + } else + CloseClipboard(); + } + + if (::IsClipboardFormatAvailable(CF_TEXT) && ::OpenClipboard(m_owner)) { + HANDLE cbData = ::GetClipboardData(CF_TEXT); + if (cbData) { + char* buffer = (char*)GlobalLock(cbData); + String fromClipboard(buffer); + GlobalUnlock(cbData); + CloseClipboard(); + return fromClipboard; + } else + CloseClipboard(); + } + + return String(); +} + +PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefPtr<Range> context, bool allowPlainText, bool& chosePlainText) +{ + chosePlainText = false; + + if (::IsClipboardFormatAvailable(HTMLClipboardFormat) && ::OpenClipboard(m_owner)) { + // get data off of clipboard + HANDLE cbData = ::GetClipboardData(HTMLClipboardFormat); + if (cbData) { + SIZE_T dataSize = ::GlobalSize(cbData); + String cf_html(UTF8Encoding().decode((char*)GlobalLock(cbData), dataSize)); + GlobalUnlock(cbData); + CloseClipboard(); + + PassRefPtr<DocumentFragment> fragment = fragmentFromCF_HTML(frame->document(), cf_html); + if (fragment) + return fragment; + } else + CloseClipboard(); + } + + if (allowPlainText && IsClipboardFormatAvailable(CF_UNICODETEXT)) { + chosePlainText = true; + if (OpenClipboard(m_owner)) { + HANDLE cbData = GetClipboardData(CF_UNICODETEXT); + if (cbData) { + UChar* buffer = (UChar*)GlobalLock(cbData); + String str(buffer); + GlobalUnlock(cbData); + CloseClipboard(); + RefPtr<DocumentFragment> fragment = createFragmentFromText(context.get(), str); + if (fragment) + return fragment.release(); + } else + CloseClipboard(); + } + } + + if (allowPlainText && ::IsClipboardFormatAvailable(CF_TEXT)) { + chosePlainText = true; + if (::OpenClipboard(m_owner)) { + HANDLE cbData = ::GetClipboardData(CF_TEXT); + if (cbData) { + char* buffer = (char*)GlobalLock(cbData); + String str(buffer); + GlobalUnlock(cbData); + CloseClipboard(); + RefPtr<DocumentFragment> fragment = createFragmentFromText(context.get(), str); + if (fragment) + return fragment.release(); + } else + CloseClipboard(); + } + } + + return 0; +} + +bool Pasteboard::hasData() +{ + return hasDataInFormat(CF_UNICODETEXT) || hasDataInFormat(CF_TEXT); +} + +bool Pasteboard::hasDataInFormat(unsigned int format) +{ + return ::IsClipboardFormatAvailable(format); +} + +} // namespace WebCore diff --git a/WebCore/platform/wince/SearchPopupMenuWince.cpp b/WebCore/platform/wince/SearchPopupMenuWince.cpp new file mode 100644 index 0000000..ca11292 --- /dev/null +++ b/WebCore/platform/wince/SearchPopupMenuWince.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2009 Torch Mobile Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "SearchPopupMenu.h" + +#include "AtomicString.h" + +namespace WebCore { + +SearchPopupMenu::SearchPopupMenu(PopupMenuClient* client) +: PopupMenu(client) +{ +} + +bool SearchPopupMenu::enabled() +{ + return false; +} + +void SearchPopupMenu::saveRecentSearches(const AtomicString& name, const Vector<String>& searchItems) +{ + if (name.isEmpty()) + return; + + notImplemented(); +} + +void SearchPopupMenu::loadRecentSearches(const AtomicString& name, Vector<String>& searchItems) +{ + if (name.isEmpty()) + return; + + notImplemented(); +} + +} diff --git a/WebCore/platform/wince/SharedTimerWince.cpp b/WebCore/platform/wince/SharedTimerWince.cpp new file mode 100644 index 0000000..ca2f104 --- /dev/null +++ b/WebCore/platform/wince/SharedTimerWince.cpp @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2007-2008 Torch Mobile, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "SharedTimer.h" + +#include "Page.h" +#include "SystemTime.h" +#include "Widget.h" +#include <wtf/Assertions.h> +#include <wtf/CurrentTime.h> +#include <windows.h> + +namespace JSC { +extern void* g_stackBase; +} + +namespace WebCore { + +enum { + TimerIdNone = 0, + TimerIdAuto, + TimerIdManual, +}; +static UINT timerID = TimerIdNone; + +static void (*sharedTimerFiredFunction)(); + +static HWND timerWindowHandle = 0; +const LPCWSTR kTimerWindowClassName = L"TimerWindowClass"; + +LRESULT CALLBACK TimerWindowWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + int dummy; + JSC::g_stackBase = &dummy; + + if (message == WM_TIMER) { + if (timerID != TimerIdNone) + sharedTimerFiredFunction(); + } else if (message == WM_USER) { + if (timerID = TimerIdManual) { + sharedTimerFiredFunction(); + PostMessage(hWnd, WM_USER, 0, 0); + } + } else { + JSC::g_stackBase = 0; + return DefWindowProc(hWnd, message, wParam, lParam); + } + JSC::g_stackBase = 0; + return 0; +} + +static void initializeOffScreenTimerWindow() +{ + if (timerWindowHandle) + return; + + WNDCLASS wcex = {0}; + wcex.lpfnWndProc = TimerWindowWndProc; + wcex.hInstance = Page::instanceHandle(); + wcex.lpszClassName = kTimerWindowClassName; + RegisterClass(&wcex); + + timerWindowHandle = CreateWindow(kTimerWindowClassName, 0, 0, + CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, HWND_MESSAGE, 0, Page::instanceHandle(), 0); +} + +void setSharedTimerFiredFunction(void (*f)()) +{ + sharedTimerFiredFunction = f; +} + +#define USER_TIMER_MAXIMUM 0x7FFFFFFF +#define USER_TIMER_MINIMUM 0x0000000A + +void setSharedTimerFireTime(double fireTime) +{ + ASSERT(sharedTimerFiredFunction); + + double interval = (fireTime - currentTime()) * 1000.; + unsigned intervalInMS = interval < USER_TIMER_MINIMUM + ? USER_TIMER_MINIMUM + : interval > USER_TIMER_MAXIMUM + ? USER_TIMER_MAXIMUM + : static_cast<unsigned>(interval); + + if (timerID == TimerIdAuto) { + KillTimer(timerWindowHandle, TimerIdAuto); + timerID = TimerIdNone; + } + + initializeOffScreenTimerWindow(); + if (SetTimer(timerWindowHandle, TimerIdAuto, intervalInMS, 0)) + timerID = TimerIdAuto; + else if (timerID != TimerIdManual) + PostMessage(timerWindowHandle, WM_USER, 0, 0); +} + +void stopSharedTimer() +{ + if (timerID == TimerIdAuto) + KillTimer(timerWindowHandle, TimerIdAuto); + + timerID = TimerIdNone; +} + +} diff --git a/WebCore/platform/wince/SystemTimeWince.cpp b/WebCore/platform/wince/SystemTimeWince.cpp new file mode 100644 index 0000000..70b705b --- /dev/null +++ b/WebCore/platform/wince/SystemTimeWince.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2007-2008 Torch Mobile, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "SystemTime.h" + +#include <windows.h> + +namespace WebCore { + +float userIdleTime() +{ + return FLT_MAX; +} + +} |