diff options
Diffstat (limited to 'WebCore/platform')
91 files changed, 2468 insertions, 586 deletions
diff --git a/WebCore/platform/BlobItem.cpp b/WebCore/platform/BlobItem.cpp index f98e466..a12dd08 100644 --- a/WebCore/platform/BlobItem.cpp +++ b/WebCore/platform/BlobItem.cpp @@ -33,6 +33,7 @@ #include "FileSystem.h" #include "UUID.h" +#include <wtf/Assertions.h> namespace WebCore { @@ -124,67 +125,87 @@ StringBlobItem::StringBlobItem(const CString& text) { } -CString StringBlobItem::convertToCString(const String& text, LineEnding ending, TextEncoding encoding) +// Normalize all line-endings to CRLF. +static CString convertToCRLF(const CString& from) { - CString from = encoding.encode(text.characters(), text.length(), EntitiesForUnencodables); - CString result = from; - - if (ending == EndingTransparent) - return result; - - if (ending == EndingNative) { -#if OS(WINDOWS) - ending = EndingCRLF; -#else - ending = EndingLF; -#endif + unsigned newLen = 0; + const char* p = from.data(); + while (char c = *p++) { + if (c == '\r') { + // Safe to look ahead because of trailing '\0'. + if (*p != '\n') { + // Turn CR into CRLF. + newLen += 2; + } + } else if (c == '\n') { + // Turn LF into CRLF. + newLen += 2; + } else { + // Leave other characters alone. + newLen += 1; + } } + if (newLen == from.length()) + return from; - const char* endingChars = (ending == EndingCRLF) ? "\r\n" : ((ending == EndingCR) ? "\r" : "\n"); - - int endingLength = (ending == EndingCRLF) ? 2 : 1; - int needFix = 0; - - // Calculate the final length. - int calculatedLength = from.length(); - const char* p = from.data(); + // Make a copy of the string. + p = from.data(); + char* q; + CString result = CString::newUninitialized(newLen, q); while (char c = *p++) { if (c == '\r') { // Safe to look ahead because of trailing '\0'. - if (*p == '\n' && ending != EndingCRLF) { - p++; - calculatedLength += (endingLength - 2); - ++needFix; - } else if (ending != EndingCR) { - calculatedLength += (endingLength - 1); - ++needFix; + if (*p != '\n') { + // Turn CR into CRLF. + *q++ = '\r'; + *q++ = '\n'; } - } else if (c == '\n' && ending != EndingLF) { - calculatedLength += (endingLength - 1); - ++needFix; + } else if (c == '\n') { + // Turn LF into CRLF. + *q++ = '\r'; + *q++ = '\n'; + } else { + // Leave other characters alone. + *q++ = c; } } + return result; +} +// Normalize all line-endings to CR or LF. +static CString convertToCROrLF(const CString& from, bool toCR) +{ + unsigned newLen = 0; + bool needFix = false; + const char* p = from.data(); + char fromEndingChar = toCR ? '\n' : '\r'; + char toEndingChar = toCR ? '\r' : '\n'; + while (char c = *p++) { + if (c == '\r' && *p == '\n') { + // Turn CRLF into CR or LF. + p++; + needFix = true; + } else if (c == fromEndingChar) { + // Turn CR/LF into LF/CR. + needFix = true; + } + newLen += 1; + } if (!needFix) - return result; + return from; - // Convert the endings and create a data buffer. + // Make a copy of the string. p = from.data(); char* q; - result = CString::newUninitialized(calculatedLength, q); + CString result = CString::newUninitialized(newLen, q); while (char c = *p++) { - if (c == '\r') { - if (*p == '\n' && ending != EndingCRLF) { - p++; - memcpy(q, endingChars, endingLength); - q += endingLength; - } else if (*p != '\n' && ending != EndingCR) { - memcpy(q, endingChars, endingLength); - q += endingLength; - } - } else if (c == '\n' && ending != EndingLF) { - memcpy(q, endingChars, endingLength); - q += endingLength; + if (c == '\r' && *p == '\n') { + // Turn CRLF or CR into CR or LF. + p++; + *q++ = toEndingChar; + } else if (c == fromEndingChar) { + // Turn CR/LF into LF/CR. + *q++ = toEndingChar; } else { // Leave other characters alone. *q++ = c; @@ -193,6 +214,35 @@ CString StringBlobItem::convertToCString(const String& text, LineEnding ending, return result; } +CString StringBlobItem::convertToCString(const String& text, LineEnding ending, TextEncoding encoding) +{ + CString from = encoding.encode(text.characters(), text.length(), EntitiesForUnencodables); + + if (ending == EndingNative) { +#if OS(WINDOWS) + ending = EndingCRLF; +#else + ending = EndingLF; +#endif + } + + switch (ending) { + case EndingTransparent: + return from; + case EndingCRLF: + return convertToCRLF(from); + case EndingCR: + return convertToCROrLF(from, true); + case EndingLF: + return convertToCROrLF(from, false); + default: + ASSERT_NOT_REACHED(); + } + + ASSERT_NOT_REACHED(); + return from; +} + // ByteArrayBlobItem ---------------------------------------------------------- PassRefPtr<BlobItem> ByteArrayBlobItem::create(const char* data, size_t size) diff --git a/WebCore/platform/DragData.h b/WebCore/platform/DragData.h index eda7e7e..9bad699 100644 --- a/WebCore/platform/DragData.h +++ b/WebCore/platform/DragData.h @@ -52,10 +52,17 @@ typedef struct IDataObject* DragDataRef; #elif PLATFORM(WX) typedef class wxDataObject* DragDataRef; #elif PLATFORM(GTK) +<<<<<<< HEAD // FIXME: this should probably be something gdk-specific typedef void* DragDataRef; #elif defined ANDROID typedef void* DragDataRef; +======= +namespace WebCore { +class DataObjectGtk; +} +typedef WebCore::DataObjectGtk* DragDataRef; +>>>>>>> webkit.org at r62496 #elif PLATFORM(CHROMIUM) #include "DragDataRef.h" #elif PLATFORM(HAIKU) diff --git a/WebCore/platform/Scrollbar.cpp b/WebCore/platform/Scrollbar.cpp index fc4b2f1..119a9dc 100644 --- a/WebCore/platform/Scrollbar.cpp +++ b/WebCore/platform/Scrollbar.cpp @@ -40,6 +40,12 @@ using namespace std; +#if PLATFORM(CHROMIUM) && OS(LINUX) +// The position of the scrollbar thumb affects the appearance of the steppers, so +// when the thumb moves, we have to invalidate them for painting. +#define THUMB_POSITION_AFFECTS_BUTTONS +#endif + namespace WebCore { #if !PLATFORM(GTK) && !PLATFORM(EFL) @@ -139,9 +145,9 @@ bool Scrollbar::scroll(ScrollDirection direction, ScrollGranularity granularity, float step = 0; if ((direction == ScrollUp && m_orientation == VerticalScrollbar) || (direction == ScrollLeft && m_orientation == HorizontalScrollbar)) step = -1; - else if ((direction == ScrollDown && m_orientation == VerticalScrollbar) || (direction == ScrollRight && m_orientation == HorizontalScrollbar)) + else if ((direction == ScrollDown && m_orientation == VerticalScrollbar) || (direction == ScrollRight && m_orientation == HorizontalScrollbar)) step = 1; - + if (granularity == ScrollByLine) step *= m_lineStep; else if (granularity == ScrollByPage) @@ -150,20 +156,29 @@ bool Scrollbar::scroll(ScrollDirection direction, ScrollGranularity granularity, step *= m_totalSize; else if (granularity == ScrollByPixel) step *= m_pixelStep; - + float newPos = m_currentPos + step * multiplier; float maxPos = m_totalSize - m_visibleSize; return setCurrentPos(max(min(newPos, maxPos), 0.0f)); } -void Scrollbar::updateThumbPosition() +void Scrollbar::updateThumb() { +#ifdef THUMB_POSITION_AFFECTS_BUTTONS + invalidate(); +#else theme()->invalidateParts(this, ForwardTrackPart | BackTrackPart | ThumbPart); +#endif +} + +void Scrollbar::updateThumbPosition() +{ + updateThumb(); } void Scrollbar::updateThumbProportion() { - theme()->invalidateParts(this, ForwardTrackPart | BackTrackPart | ThumbPart); + updateThumb(); } void Scrollbar::paint(GraphicsContext* context, const IntRect& damageRect) @@ -172,7 +187,7 @@ void Scrollbar::paint(GraphicsContext* context, const IntRect& damageRect) invalidate(); return; } - + if (context->paintingDisabled() || !frameRect().intersects(damageRect)) return; diff --git a/WebCore/platform/Scrollbar.h b/WebCore/platform/Scrollbar.h index 87310c3..6b3cd0d 100644 --- a/WebCore/platform/Scrollbar.h +++ b/WebCore/platform/Scrollbar.h @@ -130,6 +130,7 @@ private: protected: Scrollbar(ScrollbarClient*, ScrollbarOrientation, ScrollbarControlSize, ScrollbarTheme* = 0); + void updateThumb(); virtual void updateThumbPosition(); virtual void updateThumbProportion(); diff --git a/WebCore/platform/TreeShared.h b/WebCore/platform/TreeShared.h index b844e5f..6e60656 100644 --- a/WebCore/platform/TreeShared.h +++ b/WebCore/platform/TreeShared.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2006, 2007, 2009, 2010 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 @@ -23,17 +23,23 @@ #include <wtf/Assertions.h> #include <wtf/Noncopyable.h> -#ifndef NDEBUG #include <wtf/Threading.h> -#endif namespace WebCore { -template<class T> class TreeShared : public Noncopyable { +#ifndef NDEBUG +template<typename T> class TreeShared; +template<typename T> void adopted(TreeShared<T>*); +#endif + +template<typename T> class TreeShared : public Noncopyable { public: TreeShared(int initialRefCount = 1) : m_refCount(initialRefCount) , m_parent(0) +#ifndef NDEBUG + , m_adoptionIsRequired(initialRefCount == 1) +#endif { ASSERT(isMainThread()); #ifndef NDEBUG @@ -46,6 +52,7 @@ public: ASSERT(isMainThread()); ASSERT(!m_refCount); ASSERT(m_deletionHasBegun); + ASSERT(!m_adoptionIsRequired); } void ref() @@ -53,6 +60,7 @@ public: ASSERT(isMainThread()); ASSERT(!m_deletionHasBegun); ASSERT(!m_inRemovedLastRefFunction); + ASSERT(!m_adoptionIsRequired); ++m_refCount; } @@ -62,6 +70,7 @@ public: ASSERT(m_refCount >= 0); ASSERT(!m_deletionHasBegun); ASSERT(!m_inRemovedLastRefFunction); + ASSERT(!m_adoptionIsRequired); if (--m_refCount <= 0 && !m_parent) { #ifndef NDEBUG m_inRemovedLastRefFunction = true; @@ -100,6 +109,10 @@ public: #endif private: +#ifndef NDEBUG + friend void adopted<>(TreeShared<T>*); +#endif + virtual void removedLastRef() { #ifndef NDEBUG @@ -110,8 +123,24 @@ private: int m_refCount; T* m_parent; +#ifndef NDEBUG + bool m_adoptionIsRequired; +#endif }; +#ifndef NDEBUG + +template<typename T> inline void adopted(TreeShared<T>* object) +{ + if (!object) + return; + ASSERT(!object->m_deletionHasBegun); + ASSERT(!object->m_inRemovedLastRefFunction); + object->m_adoptionIsRequired = false; +} + +#endif + } #endif // TreeShared.h diff --git a/WebCore/platform/Widget.h b/WebCore/platform/Widget.h index d6ff597..45da67a 100644 --- a/WebCore/platform/Widget.h +++ b/WebCore/platform/Widget.h @@ -73,6 +73,10 @@ class BView; typedef BView* PlatformWidget; #endif +#if PLATFORM(BREWMP) +typedef void* PlatformWidget; +#endif + #if PLATFORM(CHROMIUM) #include "PlatformWidget.h" #endif diff --git a/WebCore/platform/android/RenderThemeAndroid.cpp b/WebCore/platform/android/RenderThemeAndroid.cpp index d20df98..7249507 100644 --- a/WebCore/platform/android/RenderThemeAndroid.cpp +++ b/WebCore/platform/android/RenderThemeAndroid.cpp @@ -61,7 +61,7 @@ const int listboxPadding = 5; // the color of selection in TextViews in the system. const RGBA32 selectionColor = makeRGB(255, 146, 0); -static SkCanvas* getCanvasFromInfo(const RenderObject::PaintInfo& info) +static SkCanvas* getCanvasFromInfo(const PaintInfo& info) { return info.context->platformContext()->mCanvas; } @@ -209,13 +209,13 @@ void RenderThemeAndroid::adjustButtonStyle(CSSStyleSelector*, RenderStyle* style style->setMinHeight(Length(style->fontSize() + buttonPadding, Fixed)); } -bool RenderThemeAndroid::paintCheckbox(RenderObject* obj, const RenderObject::PaintInfo& info, const IntRect& rect) +bool RenderThemeAndroid::paintCheckbox(RenderObject* obj, const PaintInfo& info, const IntRect& rect) { RenderSkinRadio::Draw(getCanvasFromInfo(info), obj->node(), rect, true); return false; } -bool RenderThemeAndroid::paintButton(RenderObject* obj, const RenderObject::PaintInfo& info, const IntRect& rect) +bool RenderThemeAndroid::paintButton(RenderObject* obj, const PaintInfo& info, const IntRect& rect) { // If it is a disabled button, simply paint it to the master picture. Node* node = obj->node(); @@ -230,6 +230,7 @@ bool RenderThemeAndroid::paintButton(RenderObject* obj, const RenderObject::Pain return false; } +<<<<<<< HEAD #if ENABLE(VIDEO) String RenderThemeAndroid::extraMediaControlsStyleSheet() @@ -320,6 +321,9 @@ void RenderThemeAndroid::adjustSliderThumbSize(RenderObject* o) const #endif bool RenderThemeAndroid::paintRadio(RenderObject* obj, const RenderObject::PaintInfo& info, const IntRect& rect) +======= +bool RenderThemeAndroid::paintRadio(RenderObject* obj, const PaintInfo& info, const IntRect& rect) +>>>>>>> webkit.org at r62496 { RenderSkinRadio::Draw(getCanvasFromInfo(info), obj->node(), rect, false); return false; @@ -342,7 +346,7 @@ void RenderThemeAndroid::adjustTextFieldStyle(CSSStyleSelector*, RenderStyle* st addIntrinsicMargins(style); } -bool RenderThemeAndroid::paintTextField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) +bool RenderThemeAndroid::paintTextField(RenderObject*, const PaintInfo&, const IntRect&) { return true; } @@ -352,7 +356,7 @@ void RenderThemeAndroid::adjustTextAreaStyle(CSSStyleSelector*, RenderStyle* sty addIntrinsicMargins(style); } -bool RenderThemeAndroid::paintTextArea(RenderObject* obj, const RenderObject::PaintInfo& info, const IntRect& rect) +bool RenderThemeAndroid::paintTextArea(RenderObject* obj, const PaintInfo& info, const IntRect& rect) { if (!obj->isListBox()) return true; @@ -412,7 +416,7 @@ void RenderThemeAndroid::adjustSearchFieldStyle(CSSStyleSelector*, RenderStyle* addIntrinsicMargins(style); } -bool RenderThemeAndroid::paintSearchField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) +bool RenderThemeAndroid::paintSearchField(RenderObject*, const PaintInfo&, const IntRect&) { return true; } @@ -441,14 +445,14 @@ void RenderThemeAndroid::adjustMenuListStyle(CSSStyleSelector*, RenderStyle* sty addIntrinsicMargins(style); } -bool RenderThemeAndroid::paintCombo(RenderObject* obj, const RenderObject::PaintInfo& info, const IntRect& rect) +bool RenderThemeAndroid::paintCombo(RenderObject* obj, const PaintInfo& info, const IntRect& rect) { if (obj->style() && !obj->style()->visitedDependentColor(CSSPropertyBackgroundColor).alpha()) return true; return RenderSkinCombo::Draw(getCanvasFromInfo(info), obj->node(), rect.x(), rect.y(), rect.width(), rect.height()); } -bool RenderThemeAndroid::paintMenuList(RenderObject* obj, const RenderObject::PaintInfo& info, const IntRect& rect) +bool RenderThemeAndroid::paintMenuList(RenderObject* obj, const PaintInfo& info, const IntRect& rect) { return paintCombo(obj, info, rect); } @@ -474,7 +478,7 @@ void RenderThemeAndroid::adjustMenuListButtonStyle(CSSStyleSelector*, RenderStyl adjustMenuListStyleCommon(style, e); } -bool RenderThemeAndroid::paintMenuListButton(RenderObject* obj, const RenderObject::PaintInfo& info, const IntRect& rect) +bool RenderThemeAndroid::paintMenuListButton(RenderObject* obj, const PaintInfo& info, const IntRect& rect) { return paintCombo(obj, info, rect); } diff --git a/WebCore/platform/android/RenderThemeAndroid.h b/WebCore/platform/android/RenderThemeAndroid.h index 3d7ac77..26047be 100644 --- a/WebCore/platform/android/RenderThemeAndroid.h +++ b/WebCore/platform/android/RenderThemeAndroid.h @@ -74,9 +74,10 @@ public: virtual int minimumMenuListSize(RenderStyle*) const { return 0; } protected: - virtual bool paintCheckbox(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintCheckbox(RenderObject*, const PaintInfo&, const IntRect&); virtual void setCheckboxSize(RenderStyle*) const; +<<<<<<< HEAD #if ENABLE(VIDEO) virtual String extraMediaControlsStyleSheet(); virtual void adjustSliderThumbSize(RenderObject* o) const; @@ -91,28 +92,31 @@ protected: #endif virtual bool paintRadio(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); +======= + virtual bool paintRadio(RenderObject*, const PaintInfo&, const IntRect&); +>>>>>>> webkit.org at r62496 virtual void setRadioSize(RenderStyle*) const; virtual void adjustButtonStyle(CSSStyleSelector*, RenderStyle*, WebCore::Element*) const; - virtual bool paintButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintButton(RenderObject*, const PaintInfo&, const IntRect&); virtual void adjustTextFieldStyle(CSSStyleSelector*, RenderStyle*, WebCore::Element*) const; - virtual bool paintTextField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintTextField(RenderObject*, const PaintInfo&, const IntRect&); virtual void adjustTextAreaStyle(CSSStyleSelector*, RenderStyle*, WebCore::Element*) const; - virtual bool paintTextArea(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintTextArea(RenderObject*, const PaintInfo&, const IntRect&); - bool paintCombo(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + bool paintCombo(RenderObject*, const PaintInfo&, const IntRect&); virtual void adjustListboxStyle(CSSStyleSelector*, RenderStyle*, Element*) const; virtual void adjustMenuListStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintMenuList(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintMenuList(RenderObject*, const PaintInfo&, const IntRect&); virtual void adjustMenuListButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintMenuListButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintMenuListButton(RenderObject*, const PaintInfo&, const IntRect&); virtual void adjustSearchFieldStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintSearchField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintSearchField(RenderObject*, const PaintInfo&, const IntRect&); private: RenderThemeAndroid(); diff --git a/WebCore/platform/brew/WidgetBrew.cpp b/WebCore/platform/brew/WidgetBrew.cpp new file mode 100644 index 0000000..5aff731 --- /dev/null +++ b/WebCore/platform/brew/WidgetBrew.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2009 Company 100, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "Widget.h" + +#include "Cursor.h" +#include "GraphicsContext.h" +#include "IntRect.h" +#include "NotImplemented.h" + +namespace WebCore { + +Widget::Widget(PlatformWidget widget) +{ + init(widget); +} + +Widget::~Widget() +{ +} + +IntRect Widget::frameRect() const +{ + return m_frame; +} + +void Widget::setFrameRect(const IntRect& rect) +{ + m_frame = rect; +} + +void Widget::setFocus(bool) +{ +} + +void Widget::setCursor(const Cursor& cursor) +{ +} + +void Widget::show() +{ +} + +void Widget::hide() +{ +} + +void Widget::paint(GraphicsContext* p, IntRect const& r) +{ + notImplemented(); +} + +void Widget::setIsSelected(bool) +{ + notImplemented(); +} + +} // namespace WebCore + diff --git a/WebCore/platform/chromium/ChromiumBridge.h b/WebCore/platform/chromium/ChromiumBridge.h index 3e9406d..3284aae 100644 --- a/WebCore/platform/chromium/ChromiumBridge.h +++ b/WebCore/platform/chromium/ChromiumBridge.h @@ -1,10 +1,10 @@ /* * Copyright (c) 2010, Google Inc. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: - * + * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above @@ -14,7 +14,7 @@ * * 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 @@ -38,6 +38,7 @@ #include "PasteboardPrivate.h" #include "PluginData.h" +#include <wtf/HashSet.h> #include <wtf/Vector.h> typedef struct NPObject NPObject; @@ -60,6 +61,7 @@ typedef struct HFONT__* HFONT; namespace WebCore { + class ClipboardData; class Color; class Cursor; class Document; @@ -91,13 +93,19 @@ namespace WebCore { static String clipboardReadPlainText(PasteboardPrivate::ClipboardBuffer); static void clipboardReadHTML(PasteboardPrivate::ClipboardBuffer, String*, KURL*); - // Only the clipboardRead functions take a buffer argument because + // Only the clipboardRead functions take a buffer argument because // Chromium currently uses a different technique to write to alternate // clipboard buffers. static void clipboardWriteSelection(const String&, const KURL&, const String&, bool); static void clipboardWritePlainText(const String&); static void clipboardWriteURL(const KURL&, const String&); static void clipboardWriteImage(NativeImagePtr, const KURL&, const String&); + static void clipboardWriteData(ClipboardData*); + + // Interface for handling copy and paste, drag and drop, and selection copy. + static HashSet<String> clipboardReadAvailableTypes(PasteboardPrivate::ClipboardBuffer, bool* containsFilenames); + static bool clipboardReadData(PasteboardPrivate::ClipboardBuffer, const String& type, String& data, String& metadata); + static Vector<String> clipboardReadFilenames(PasteboardPrivate::ClipboardBuffer); // Cookies ------------------------------------------------------------ static void setCookies(const Document*, const KURL&, const String& value); diff --git a/WebCore/platform/chromium/ClipboardChromium.cpp b/WebCore/platform/chromium/ClipboardChromium.cpp index 29f9620..8aad8aa 100644 --- a/WebCore/platform/chromium/ClipboardChromium.cpp +++ b/WebCore/platform/chromium/ClipboardChromium.cpp @@ -495,8 +495,11 @@ void ClipboardChromium::writeURL(const KURL& url, const String& title, Frame*) { if (!m_dataObject) return; + ASSERT(!url.isEmpty()); m_dataObject->url = url; m_dataObject->urlTitle = title; + m_dataObject->uriList.clear(); + m_dataObject->uriList.append(url); // The URL can also be used as plain text. m_dataObject->plainText = url.string(); diff --git a/WebCore/platform/chromium/PasteboardPrivate.h b/WebCore/platform/chromium/PasteboardPrivate.h index 95cc697..1de7fe3 100644 --- a/WebCore/platform/chromium/PasteboardPrivate.h +++ b/WebCore/platform/chromium/PasteboardPrivate.h @@ -33,8 +33,7 @@ namespace WebCore { - class PasteboardPrivate - { + class PasteboardPrivate { public: enum ClipboardFormat { HTMLFormat, @@ -44,6 +43,7 @@ namespace WebCore { enum ClipboardBuffer { StandardBuffer, SelectionBuffer, + DragBuffer, }; }; diff --git a/WebCore/platform/chromium/PopupMenuChromium.cpp b/WebCore/platform/chromium/PopupMenuChromium.cpp index e8ab333..7e3a2a0 100644 --- a/WebCore/platform/chromium/PopupMenuChromium.cpp +++ b/WebCore/platform/chromium/PopupMenuChromium.cpp @@ -53,6 +53,7 @@ #include "ScrollbarTheme.h" #include "StringTruncator.h" #include "SystemTime.h" +#include "UserGestureIndicator.h" #include <wtf/CurrentTime.h> @@ -451,30 +452,35 @@ void PopupContainer::layout() bool PopupContainer::handleMouseDownEvent(const PlatformMouseEvent& event) { + UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture); return m_listBox->handleMouseDownEvent( constructRelativeMouseEvent(event, this, m_listBox.get())); } bool PopupContainer::handleMouseMoveEvent(const PlatformMouseEvent& event) { + UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture); return m_listBox->handleMouseMoveEvent( constructRelativeMouseEvent(event, this, m_listBox.get())); } bool PopupContainer::handleMouseReleaseEvent(const PlatformMouseEvent& event) { + UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture); return m_listBox->handleMouseReleaseEvent( constructRelativeMouseEvent(event, this, m_listBox.get())); } bool PopupContainer::handleWheelEvent(const PlatformWheelEvent& event) { + UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture); return m_listBox->handleWheelEvent( constructRelativeWheelEvent(event, this, m_listBox.get())); } bool PopupContainer::handleKeyEvent(const PlatformKeyboardEvent& event) { + UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture); return m_listBox->handleKeyEvent(event); } diff --git a/WebCore/platform/chromium/ScrollbarThemeChromium.cpp b/WebCore/platform/chromium/ScrollbarThemeChromium.cpp index a6720a1..cf3ca6f 100644 --- a/WebCore/platform/chromium/ScrollbarThemeChromium.cpp +++ b/WebCore/platform/chromium/ScrollbarThemeChromium.cpp @@ -75,6 +75,24 @@ IntRect ScrollbarThemeChromium::forwardButtonRect(Scrollbar* scrollbar, Scrollba return IntRect(x, y, size.width(), size.height()); } +IntRect ScrollbarThemeChromium::trackRect(Scrollbar* scrollbar, bool) +{ + IntSize bs = buttonSize(scrollbar); + // The buttons at the top and bottom of the scrollbar are square, so the + // thickness of the scrollbar is also their height. + int thickness = scrollbarThickness(scrollbar->controlSize()); + if (scrollbar->orientation() == HorizontalScrollbar) { + // Once the scrollbar becomes smaller than the natural size of the + // two buttons, the track disappears. + if (scrollbar->width() < 2 * thickness) + return IntRect(); + return IntRect(scrollbar->x() + bs.width(), scrollbar->y(), scrollbar->width() - 2 * bs.width(), thickness); + } + if (scrollbar->height() < 2 * thickness) + return IntRect(); + return IntRect(scrollbar->x(), scrollbar->y() + bs.height(), thickness, scrollbar->height() - 2 * bs.height()); +} + void ScrollbarThemeChromium::paintTrackBackground(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& rect) { // Just assume a forward track part. We only paint the track as a single piece when there is no thumb. diff --git a/WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp b/WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp index 3a1a652..a9cff9f 100644 --- a/WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp +++ b/WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp @@ -40,6 +40,9 @@ namespace WebCore { +static const int scrollbarThicknessValue = 15; +static const int buttonLength = 14; + ScrollbarTheme* ScrollbarTheme::nativeTheme() { static ScrollbarThemeChromiumLinux theme; @@ -48,7 +51,7 @@ ScrollbarTheme* ScrollbarTheme::nativeTheme() int ScrollbarThemeChromiumLinux::scrollbarThickness(ScrollbarControlSize controlSize) { - return 15; + return scrollbarThicknessValue; } static void drawVertLine(SkCanvas* canvas, int x, int y1, int y2, const SkPaint& paint) @@ -120,7 +123,7 @@ static SkColor outlineColor(SkScalar* hsv1, SkScalar* hsv2) // // The following code has been tested to look OK with all of the // default GTK themes. - SkScalar minDiff = clamp((hsv1[1] + hsv2[1]) * 1.2, 0.2, 0.5); + SkScalar minDiff = clamp((hsv1[1] + hsv2[1]) * 1.2, 0.28, 0.5); SkScalar diff = clamp(fabs(hsv1[2] - hsv2[2]) / 2, minDiff, 0.5); if (hsv1[2] + hsv2[2] > 1.0) @@ -129,15 +132,6 @@ static SkColor outlineColor(SkScalar* hsv1, SkScalar* hsv2) return saturateAndBrighten(hsv2, -0.2, diff); } -IntRect ScrollbarThemeChromium::trackRect(Scrollbar* scrollbar, bool) -{ - IntSize bs = buttonSize(scrollbar); - int thickness = scrollbarThickness(scrollbar->controlSize()); - if (scrollbar->orientation() == HorizontalScrollbar) - return IntRect(scrollbar->x() + bs.width(), scrollbar->y(), scrollbar->width(), thickness); - return IntRect(scrollbar->x(), scrollbar->y() + bs.height(), thickness, scrollbar->height()); -} - void ScrollbarThemeChromiumLinux::paintTrackPiece(GraphicsContext* gc, Scrollbar* scrollbar, const IntRect& rect, ScrollbarPart partType) { SkCanvas* const canvas = gc->platformContext()->canvas(); @@ -145,22 +139,155 @@ void ScrollbarThemeChromiumLinux::paintTrackPiece(GraphicsContext* gc, Scrollbar SkIRect skrect; skrect.set(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height()); - SkScalar track_hsv[3]; - SkColorToHSV(RenderThemeChromiumLinux::trackColor(), track_hsv); - paint.setColor(saturateAndBrighten(track_hsv, 0, 0)); + SkScalar trackHSV[3]; + SkColorToHSV(RenderThemeChromiumLinux::trackColor(), trackHSV); + paint.setColor(saturateAndBrighten(trackHSV, 0, 0)); canvas->drawIRect(skrect, paint); - SkScalar thumb_hsv[3]; + SkScalar thumbHSV[3]; SkColorToHSV(RenderThemeChromiumLinux::thumbInactiveColor(), - thumb_hsv); + thumbHSV); - paint.setColor(outlineColor(track_hsv, thumb_hsv)); + paint.setColor(outlineColor(trackHSV, thumbHSV)); drawBox(canvas, rect, paint); } void ScrollbarThemeChromiumLinux::paintButton(GraphicsContext* gc, Scrollbar* scrollbar, const IntRect& rect, ScrollbarPart part) { - // We don't use buttons + SkCanvas* const canvas = gc->platformContext()->canvas(); + static const int widthMiddle = scrollbarThicknessValue / 2 + 1; + static const int lengthMiddle = buttonLength / 2 + 1; + SkPaint paint; + enum { + North, + East, + South, + West, + } direction; + + if (scrollbar->orientation() == HorizontalScrollbar) { + if (part == BackButtonStartPart) + direction = West; + else + direction = East; + } else { + if (part == BackButtonStartPart) + direction = North; + else + direction = South; + } + + // Determine if the button can be pressed. + bool enabled = false; + if (((direction == West || direction == North) && scrollbar->currentPos()) + || (direction == East || direction == South) && scrollbar->currentPos() != scrollbar->maximum()) + enabled = true; + + // Calculate button color. + SkScalar trackHSV[3]; + SkColorToHSV(RenderThemeChromiumLinux::trackColor(), trackHSV); + SkColor buttonColor = saturateAndBrighten(trackHSV, 0, 0.2); + SkColor backgroundColor = buttonColor; + if (part == scrollbar->pressedPart()) { + SkScalar buttonHSV[3]; + SkColorToHSV(buttonColor, buttonHSV); + buttonColor = saturateAndBrighten(buttonHSV, 0, -0.1); + } else if (part == scrollbar->hoveredPart() && enabled) { + SkScalar buttonHSV[3]; + SkColorToHSV(buttonColor, buttonHSV); + buttonColor = saturateAndBrighten(buttonHSV, 0, 0.05); + } + + SkIRect skrect; + skrect.set(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height()); + // Paint the background (the area visible behind the rounded corners). + paint.setColor(backgroundColor); + canvas->drawIRect(skrect, paint); + + // Paint the button's outline and fill the middle + SkPath outline; + switch (direction) { + case North: + outline.moveTo(rect.x() + 0.5, rect.y() + rect.height() + 0.5); + outline.rLineTo(0, -(rect.height() - 2)); + outline.rLineTo(2, -2); + outline.rLineTo(rect.width() - 5, 0); + outline.rLineTo(2, 2); + outline.rLineTo(0, rect.height() - 2); + break; + case South: + outline.moveTo(rect.x() + 0.5, rect.y() - 0.5); + outline.rLineTo(0, rect.height() - 2); + outline.rLineTo(2, 2); + outline.rLineTo(rect.width() - 5, 0); + outline.rLineTo(2, -2); + outline.rLineTo(0, -(rect.height() - 2)); + break; + case East: + outline.moveTo(rect.x() - 0.5, rect.y() + 0.5); + outline.rLineTo(rect.width() - 2, 0); + outline.rLineTo(2, 2); + outline.rLineTo(0, rect.height() - 5); + outline.rLineTo(-2, 2); + outline.rLineTo(-(rect.width() - 2), 0); + break; + case West: + outline.moveTo(rect.x() + rect.width() + 0.5, rect.y() + 0.5); + outline.rLineTo(-(rect.width() - 2), 0); + outline.rLineTo(-2, 2); + outline.rLineTo(0, rect.height() - 5); + outline.rLineTo(2, 2); + outline.rLineTo(rect.width() - 2, 0); + break; + } + outline.close(); + + paint.setStyle(SkPaint::kFill_Style); + paint.setColor(buttonColor); + canvas->drawPath(outline, paint); + + paint.setAntiAlias(true); + paint.setStyle(SkPaint::kStroke_Style); + SkScalar thumbHSV[3]; + SkColorToHSV(RenderThemeChromiumLinux::thumbInactiveColor(), thumbHSV); + paint.setColor(outlineColor(trackHSV, thumbHSV)); + canvas->drawPath(outline, paint); + + // If the button is disabled, the arrow is drawn with the outline color. + if (enabled) + paint.setColor(SK_ColorBLACK); + + paint.setAntiAlias(false); + paint.setStyle(SkPaint::kFill_Style); + + SkPath path; + // The constants in this block of code are hand-tailored to produce good + // looking arrows without anti-aliasing. + switch (direction) { + case North: + path.moveTo(rect.x() + widthMiddle - 4, rect.y() + lengthMiddle + 2); + path.rLineTo(7, 0); + path.rLineTo(-4, -4); + break; + case South: + path.moveTo(rect.x() + widthMiddle - 4, rect.y() + lengthMiddle - 3); + path.rLineTo(7, 0); + path.rLineTo(-4, 4); + break; + case East: + path.moveTo(rect.x() + lengthMiddle - 3, rect.y() + widthMiddle - 4); + path.rLineTo(0, 7); + path.rLineTo(4, -4); + break; + case West: + path.moveTo(rect.x() + lengthMiddle + 1, rect.y() + widthMiddle - 5); + path.rLineTo(0, 9); + path.rLineTo(-4, -4); + break; + } + path.close(); + + canvas->drawPath(path, paint); } void ScrollbarThemeChromiumLinux::paintThumb(GraphicsContext* gc, Scrollbar* scrollbar, const IntRect& rect) @@ -224,8 +351,11 @@ bool ScrollbarThemeChromiumLinux::shouldCenterOnThumb(Scrollbar*, const Platform IntSize ScrollbarThemeChromiumLinux::buttonSize(Scrollbar* scrollbar) { - // On Linux, we don't use buttons - return IntSize(0, 0); + if (scrollbar->orientation() == VerticalScrollbar) + return IntSize(scrollbarThicknessValue, buttonLength); + + // HorizontalScrollbar + return IntSize(buttonLength, scrollbarThicknessValue); } int ScrollbarThemeChromiumLinux::minimumThumbLength(Scrollbar* scrollbar) diff --git a/WebCore/platform/chromium/ScrollbarThemeChromiumWin.cpp b/WebCore/platform/chromium/ScrollbarThemeChromiumWin.cpp index d84ad5e..ba7e97b 100644 --- a/WebCore/platform/chromium/ScrollbarThemeChromiumWin.cpp +++ b/WebCore/platform/chromium/ScrollbarThemeChromiumWin.cpp @@ -57,24 +57,6 @@ static const int kMacScrollbarSize[3] = { 15, 11, 15 }; static const int kOffEndMultiplier = 3; static const int kOffSideMultiplier = 8; -IntRect ScrollbarThemeChromium::trackRect(Scrollbar* scrollbar, bool) -{ - IntSize bs = buttonSize(scrollbar); - // The buttons at the top and bottom of the scrollbar are square, so the - // thickness of the scrollbar is also their height. - int thickness = scrollbarThickness(scrollbar->controlSize()); - if (scrollbar->orientation() == HorizontalScrollbar) { - // Once the scrollbar becomes smaller than the natural size of the - // two buttons, the track disappears. - if (scrollbar->width() < 2 * thickness) - return IntRect(); - return IntRect(scrollbar->x() + bs.width(), scrollbar->y(), scrollbar->width() - 2 * bs.width(), thickness); - } - if (scrollbar->height() < 2 * thickness) - return IntRect(); - return IntRect(scrollbar->x(), scrollbar->y() + bs.height(), thickness, scrollbar->height() - 2 * bs.height()); -} - int ScrollbarThemeChromiumWin::scrollbarThickness(ScrollbarControlSize controlSize) { static int thickness; diff --git a/WebCore/platform/efl/RenderThemeEfl.cpp b/WebCore/platform/efl/RenderThemeEfl.cpp index 6ed7599..d5a5365 100644 --- a/WebCore/platform/efl/RenderThemeEfl.cpp +++ b/WebCore/platform/efl/RenderThemeEfl.cpp @@ -254,7 +254,7 @@ void RenderThemeEfl::applyEdjeStateFromForm(Evas_Object* o, ControlStates states } } -bool RenderThemeEfl::paintThemePart(RenderObject* o, FormType type, const RenderObject::PaintInfo& i, const IntRect& rect) +bool RenderThemeEfl::paintThemePart(RenderObject* o, FormType type, const PaintInfo& i, const IntRect& rect) { struct ThemePartCacheEntry* ce; Eina_List* updates; @@ -746,7 +746,7 @@ void RenderThemeEfl::adjustCheckboxStyle(CSSStyleSelector* selector, RenderStyle style->setHeight(desc->min.height()); } -bool RenderThemeEfl::paintCheckbox(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect) +bool RenderThemeEfl::paintCheckbox(RenderObject* o, const PaintInfo& i, const IntRect& rect) { return paintThemePart(o, CheckBox, i, rect); } @@ -767,7 +767,7 @@ void RenderThemeEfl::adjustRadioStyle(CSSStyleSelector* selector, RenderStyle* s style->setHeight(desc->min.height()); } -bool RenderThemeEfl::paintRadio(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect) +bool RenderThemeEfl::paintRadio(RenderObject* o, const PaintInfo& i, const IntRect& rect) { return paintThemePart(o, RadioButton, i, rect); } @@ -790,7 +790,7 @@ void RenderThemeEfl::adjustButtonStyle(CSSStyleSelector* selector, RenderStyle* } } -bool RenderThemeEfl::paintButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect) +bool RenderThemeEfl::paintButton(RenderObject* o, const PaintInfo& i, const IntRect& rect) { return paintThemePart(o, Button, i, rect); } @@ -808,7 +808,7 @@ void RenderThemeEfl::adjustMenuListStyle(CSSStyleSelector* selector, RenderStyle style->setBackgroundColor(m_comboTextBackgroundColor); } -bool RenderThemeEfl::paintMenuList(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect) +bool RenderThemeEfl::paintMenuList(RenderObject* o, const PaintInfo& i, const IntRect& rect) { return paintThemePart(o, ComboBox, i, rect); } @@ -826,7 +826,7 @@ void RenderThemeEfl::adjustTextFieldStyle(CSSStyleSelector* selector, RenderStyl style->setBackgroundColor(m_entryTextBackgroundColor); } -bool RenderThemeEfl::paintTextField(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect) +bool RenderThemeEfl::paintTextField(RenderObject* o, const PaintInfo& i, const IntRect& rect) { return paintThemePart(o, TextField, i, rect); } @@ -836,7 +836,7 @@ void RenderThemeEfl::adjustTextAreaStyle(CSSStyleSelector* selector, RenderStyle adjustTextFieldStyle(selector, style, e); } -bool RenderThemeEfl::paintTextArea(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) +bool RenderThemeEfl::paintTextArea(RenderObject* o, const PaintInfo& i, const IntRect& r) { return paintTextField(o, i, r); } @@ -852,7 +852,7 @@ void RenderThemeEfl::adjustSearchFieldDecorationStyle(CSSStyleSelector* selector style->setWhiteSpace(PRE); } -bool RenderThemeEfl::paintSearchFieldDecoration(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect) +bool RenderThemeEfl::paintSearchFieldDecoration(RenderObject* o, const PaintInfo& i, const IntRect& rect) { return paintThemePart(o, SearchFieldDecoration, i, rect); } @@ -868,7 +868,7 @@ void RenderThemeEfl::adjustSearchFieldResultsButtonStyle(CSSStyleSelector* selec style->setWhiteSpace(PRE); } -bool RenderThemeEfl::paintSearchFieldResultsButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect) +bool RenderThemeEfl::paintSearchFieldResultsButton(RenderObject* o, const PaintInfo& i, const IntRect& rect) { return paintThemePart(o, SearchFieldResultsButton, i, rect); } @@ -884,7 +884,7 @@ void RenderThemeEfl::adjustSearchFieldResultsDecorationStyle(CSSStyleSelector* s style->setWhiteSpace(PRE); } -bool RenderThemeEfl::paintSearchFieldResultsDecoration(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect) +bool RenderThemeEfl::paintSearchFieldResultsDecoration(RenderObject* o, const PaintInfo& i, const IntRect& rect) { return paintThemePart(o, SearchFieldResultsDecoration, i, rect); } @@ -900,7 +900,7 @@ void RenderThemeEfl::adjustSearchFieldCancelButtonStyle(CSSStyleSelector* select style->setWhiteSpace(PRE); } -bool RenderThemeEfl::paintSearchFieldCancelButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect) +bool RenderThemeEfl::paintSearchFieldCancelButton(RenderObject* o, const PaintInfo& i, const IntRect& rect) { return paintThemePart(o, SearchFieldCancelButton, i, rect); } @@ -918,7 +918,7 @@ void RenderThemeEfl::adjustSearchFieldStyle(CSSStyleSelector* selector, RenderSt style->setBackgroundColor(m_searchTextBackgroundColor); } -bool RenderThemeEfl::paintSearchField(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect) +bool RenderThemeEfl::paintSearchField(RenderObject* o, const PaintInfo& i, const IntRect& rect) { return paintThemePart(o, SearchField, i, rect); } diff --git a/WebCore/platform/efl/RenderThemeEfl.h b/WebCore/platform/efl/RenderThemeEfl.h index 22e0608..9753a76 100644 --- a/WebCore/platform/efl/RenderThemeEfl.h +++ b/WebCore/platform/efl/RenderThemeEfl.h @@ -103,37 +103,37 @@ public: virtual void systemFont(int propId, FontDescription&) const; virtual void adjustCheckboxStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintCheckbox(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintCheckbox(RenderObject*, const PaintInfo&, const IntRect&); virtual void adjustRadioStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintRadio(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintRadio(RenderObject*, const PaintInfo&, const IntRect&); virtual void adjustButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintButton(RenderObject*, const PaintInfo&, const IntRect&); virtual void adjustTextFieldStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintTextField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintTextField(RenderObject*, const PaintInfo&, const IntRect&); virtual void adjustTextAreaStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintTextArea(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintTextArea(RenderObject*, const PaintInfo&, const IntRect&); virtual void adjustMenuListStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintMenuList(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintMenuList(RenderObject*, const PaintInfo&, const IntRect&); virtual void adjustSearchFieldResultsDecorationStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintSearchFieldResultsDecoration(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintSearchFieldResultsDecoration(RenderObject*, const PaintInfo&, const IntRect&); virtual void adjustSearchFieldDecorationStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintSearchFieldDecoration(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintSearchFieldDecoration(RenderObject*, const PaintInfo&, const IntRect&); virtual void adjustSearchFieldStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintSearchField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintSearchField(RenderObject*, const PaintInfo&, const IntRect&); virtual void adjustSearchFieldResultsButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintSearchFieldResultsButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintSearchFieldResultsButton(RenderObject*, const PaintInfo&, const IntRect&); virtual void adjustSearchFieldCancelButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintSearchFieldCancelButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintSearchFieldCancelButton(RenderObject*, const PaintInfo&, const IntRect&); private: void createCanvas(); @@ -142,7 +142,7 @@ private: void applyPartDescriptions(); const char* edjeGroupFromFormType(FormType type) const; void applyEdjeStateFromForm(Evas_Object* o, ControlStates states); - bool paintThemePart(RenderObject* o, FormType type, const RenderObject::PaintInfo& i, const IntRect& rect); + bool paintThemePart(RenderObject* o, FormType type, const PaintInfo& i, const IntRect& rect); Page* m_page; Color m_activeSelectionBackgroundColor; diff --git a/WebCore/platform/efl/SharedTimerEfl.cpp b/WebCore/platform/efl/SharedTimerEfl.cpp index 122c8c3..437de64 100644 --- a/WebCore/platform/efl/SharedTimerEfl.cpp +++ b/WebCore/platform/efl/SharedTimerEfl.cpp @@ -45,7 +45,7 @@ void setSharedTimerFiredFunction(void (*func)()) g_timerFunction = func; } -static int timerEvent(void*) +static Eina_Bool timerEvent(void*) { if (g_timerFunction) g_timerFunction(); diff --git a/WebCore/platform/graphics/FloatRect.h b/WebCore/platform/graphics/FloatRect.h index b265121..2b23576 100644 --- a/WebCore/platform/graphics/FloatRect.h +++ b/WebCore/platform/graphics/FloatRect.h @@ -143,6 +143,7 @@ public: #if PLATFORM(QT) FloatRect(const QRectF&); operator QRectF() const; + FloatRect normalized() const; #endif #if PLATFORM(WX) && USE(WXGC) diff --git a/WebCore/platform/graphics/GlyphMetricsMap.h b/WebCore/platform/graphics/GlyphMetricsMap.h index 5e13afe..82e234b 100644 --- a/WebCore/platform/graphics/GlyphMetricsMap.h +++ b/WebCore/platform/graphics/GlyphMetricsMap.h @@ -29,6 +29,7 @@ #ifndef GlyphMetricsMap_h #define GlyphMetricsMap_h +#include <wtf/FixedArray.h> #include <wtf/HashMap.h> #include <wtf/OwnPtr.h> #include <wtf/unicode/Unicode.h> @@ -61,7 +62,7 @@ public: private: struct GlyphMetricsPage { static const size_t size = 256; // Usually covers Latin-1 in a single page. - T m_metrics[size]; + FixedArray<T, size> m_metrics; T metricsForGlyph(Glyph glyph) const { return m_metrics[glyph % size]; } void setMetricsForGlyph(Glyph glyph, const T& metrics) diff --git a/WebCore/platform/graphics/Gradient.h b/WebCore/platform/graphics/Gradient.h index b526e51..c4ac01b 100644 --- a/WebCore/platform/graphics/Gradient.h +++ b/WebCore/platform/graphics/Gradient.h @@ -94,7 +94,7 @@ namespace WebCore { void getColor(float value, float* r, float* g, float* b, float* a) const; bool isRadial() const { return m_radial; } - bool isZeroSize() const { return m_p0.x() == m_p1.x() && m_p0.y() == m_p1.y(); } + bool isZeroSize() const { return m_p0.x() == m_p1.x() && m_p0.y() == m_p1.y() && (!m_radial || m_r0 == m_r1); } #if OS(WINCE) && !PLATFORM(QT) const FloatPoint& p0() const { return m_p0; } diff --git a/WebCore/platform/graphics/GraphicsContext.h b/WebCore/platform/graphics/GraphicsContext.h index 8bcfc06..457368b 100644 --- a/WebCore/platform/graphics/GraphicsContext.h +++ b/WebCore/platform/graphics/GraphicsContext.h @@ -274,6 +274,7 @@ namespace WebCore { void clipOutRoundedRect(const IntRect&, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight); void clipPath(WindRule); void clipToImageBuffer(const FloatRect&, const ImageBuffer*); + void clipConvexPolygon(size_t numPoints, const FloatPoint*); int textDrawingMode(); void setTextDrawingMode(int); diff --git a/WebCore/platform/graphics/GraphicsContext3D.cpp b/WebCore/platform/graphics/GraphicsContext3D.cpp index dc70734..79f6ecf 100644 --- a/WebCore/platform/graphics/GraphicsContext3D.cpp +++ b/WebCore/platform/graphics/GraphicsContext3D.cpp @@ -30,6 +30,7 @@ #include "GraphicsContext3D.h" +#include "ArrayBufferView.h" #include "Image.h" #include "ImageData.h" @@ -118,6 +119,7 @@ bool GraphicsContext3D::extractImageData(ImageData* imageData, kSourceFormatRGBA8, width, height, + 0, format, type, premultiplyAlpha ? kAlphaDoPremultiply : kAlphaDoNothing, @@ -138,6 +140,72 @@ bool GraphicsContext3D::extractImageData(ImageData* imageData, return true; } +bool GraphicsContext3D::extractTextureData(unsigned int width, unsigned int height, + unsigned int format, unsigned int type, + unsigned int unpackAlignment, + bool flipY, bool premultiplyAlpha, + ArrayBufferView* pixels, + Vector<uint8_t>& data) +{ + // Assumes format, type, etc. have already been validated. + SourceDataFormat sourceDataFormat = kSourceFormatRGBA8; + switch (type) { + case UNSIGNED_BYTE: + switch (format) { + case RGBA: + sourceDataFormat = kSourceFormatRGBA8; + break; + case RGB: + sourceDataFormat = kSourceFormatRGB8; + break; + case ALPHA: + sourceDataFormat = kSourceFormatA8; + break; + case LUMINANCE: + sourceDataFormat = kSourceFormatR8; + break; + case LUMINANCE_ALPHA: + sourceDataFormat = kSourceFormatRA8; + break; + default: + ASSERT_NOT_REACHED(); + } + break; + case UNSIGNED_SHORT_5_5_5_1: + sourceDataFormat = kSourceFormatRGBA5551; + break; + case UNSIGNED_SHORT_4_4_4_4: + sourceDataFormat = kSourceFormatRGBA4444; + break; + case UNSIGNED_SHORT_5_6_5: + sourceDataFormat = kSourceFormatRGB565; + break; + default: + ASSERT_NOT_REACHED(); + } + + // Resize the output buffer. + unsigned long componentsPerPixel, bytesPerComponent; + if (!computeFormatAndTypeParameters(format, type, + &componentsPerPixel, + &bytesPerComponent)) + return false; + unsigned long bytesPerPixel = componentsPerPixel * bytesPerComponent; + data.resize(width * height * bytesPerPixel); + + if (!packPixels(static_cast<uint8_t*>(pixels->baseAddress()), + sourceDataFormat, + width, height, unpackAlignment, + format, type, + (premultiplyAlpha ? kAlphaDoPremultiply : kAlphaDoNothing), + data.data())) + return false; + // The pixel data is now tightly packed. + if (flipY) + flipVertically(data.data(), width, height, bytesPerPixel, 1); + return true; +} + void GraphicsContext3D::flipVertically(void* imageData, unsigned int width, unsigned int height, @@ -150,7 +218,7 @@ void GraphicsContext3D::flipVertically(void* imageData, unsigned int totalRowBytes = validRowBytes; unsigned int remainder = validRowBytes % unpackAlignment; if (remainder) - totalRowBytes += remainder; + totalRowBytes += (unpackAlignment - remainder); uint8_t* tempRow = new uint8_t[validRowBytes]; uint8_t* data = static_cast<uint8_t*>(imageData); for (unsigned i = 0; i < height / 2; i++) { @@ -171,6 +239,14 @@ namespace { //---------------------------------------------------------------------- // Pixel unpacking routines. +void unpackRGBA8ToRGBA8(const uint8_t* source, uint8_t* destination) +{ + destination[0] = source[0]; + destination[1] = source[1]; + destination[2] = source[2]; + destination[3] = source[3]; +} + void unpackRGB8ToRGBA8(const uint8_t* source, uint8_t* destination) { destination[0] = source[0]; @@ -187,6 +263,67 @@ void unpackBGRA8ToRGBA8(const uint8_t* source, uint8_t* destination) destination[3] = source[3]; } +void unpackRGBA5551ToRGBA8(const uint16_t* source, uint8_t* destination) +{ + uint16_t packedValue = source[0]; + uint8_t r = packedValue >> 11; + uint8_t g = (packedValue >> 6) & 0x1F; + uint8_t b = (packedValue >> 1) & 0x1F; + destination[0] = (r << 3) | (r & 0x7); + destination[1] = (g << 3) | (g & 0x7); + destination[2] = (b << 3) | (b & 0x7); + destination[3] = (packedValue & 0x1) ? 0xFF : 0x0; +} + +void unpackRGBA4444ToRGBA8(const uint16_t* source, uint8_t* destination) +{ + uint16_t packedValue = source[0]; + uint8_t r = packedValue >> 12; + uint8_t g = (packedValue >> 8) & 0x0F; + uint8_t b = (packedValue >> 4) & 0x0F; + uint8_t a = packedValue & 0x0F; + destination[0] = r << 4 | r; + destination[1] = g << 4 | g; + destination[2] = b << 4 | b; + destination[3] = a << 4 | a; +} + +void unpackRGB565ToRGBA8(const uint16_t* source, uint8_t* destination) +{ + uint16_t packedValue = source[0]; + uint8_t r = packedValue >> 11; + uint8_t g = (packedValue >> 5) & 0x3F; + uint8_t b = packedValue & 0x1F; + destination[0] = (r << 3) | (r & 0x7); + destination[1] = (g << 2) | (g & 0x3); + destination[2] = (b << 3) | (b & 0x7); + destination[3] = 0xFF; +} + +void unpackR8ToRGBA8(const uint8_t* source, uint8_t* destination) +{ + destination[0] = source[0]; + destination[1] = source[0]; + destination[2] = source[0]; + destination[3] = 0xFF; +} + +void unpackRA8ToRGBA8(const uint8_t* source, uint8_t* destination) +{ + destination[0] = source[0]; + destination[1] = source[0]; + destination[2] = source[0]; + destination[3] = source[1]; +} + +void unpackA8ToRGBA8(const uint8_t* source, uint8_t* destination) +{ + destination[0] = 0x0; + destination[1] = 0x0; + destination[2] = 0x0; + destination[3] = source[0]; +} + //---------------------------------------------------------------------- // Pixel packing routines. // @@ -401,51 +538,141 @@ void packRGBA8ToUnsignedShort565Unmultiply(const uint8_t* source, uint16_t* dest } // anonymous namespace // This is used whenever unpacking is necessary; i.e., the source data -// is not in RGBA8 format. +// is not in RGBA8 format, or the unpack alignment specifies that rows +// are not tightly packed. template<typename SourceType, typename DestType, void unpackingFunc(const SourceType*, uint8_t*), void packingFunc(const uint8_t*, DestType*)> static void doUnpackingAndPacking(const SourceType* sourceData, - unsigned int numElements, + unsigned int width, + unsigned int height, unsigned int sourceElementsPerPixel, + unsigned int sourceElementsPerRow, DestType* destinationData, unsigned int destinationElementsPerPixel) { - const SourceType* endPointer = sourceData + numElements; - uint8_t temporaryRGBAData[4]; - while (sourceData < endPointer) { - unpackingFunc(sourceData, temporaryRGBAData); - packingFunc(temporaryRGBAData, destinationData); - sourceData += sourceElementsPerPixel; - destinationData += destinationElementsPerPixel; + if (!sourceElementsPerRow) { + unsigned int numElements = width * height * sourceElementsPerPixel; + const SourceType* endPointer = sourceData + numElements; + uint8_t temporaryRGBAData[4]; + while (sourceData < endPointer) { + unpackingFunc(sourceData, temporaryRGBAData); + packingFunc(temporaryRGBAData, destinationData); + sourceData += sourceElementsPerPixel; + destinationData += destinationElementsPerPixel; + } + } else { + uint8_t temporaryRGBAData[4]; + for (unsigned int y = 0; y < height; ++y) { + const SourceType* currentSource = sourceData; + for (unsigned int x = 0; x < width; ++x) { + unpackingFunc(currentSource, temporaryRGBAData); + packingFunc(temporaryRGBAData, destinationData); + currentSource += sourceElementsPerPixel; + destinationData += destinationElementsPerPixel; + } + sourceData += sourceElementsPerRow; + } + } +} + +template<typename SourceType> +static void computeIncrementParameters(unsigned int width, + unsigned int bytesPerPixel, + unsigned int unpackAlignment, + unsigned int* sourceElementsPerPixel, + unsigned int* sourceElementsPerRow) +{ + unsigned int elementSizeInBytes = sizeof(SourceType); + ASSERT(elementSizeInBytes <= bytesPerPixel); + unsigned int validRowBytes = width * bytesPerPixel; + unsigned int totalRowBytes = validRowBytes; + if (unpackAlignment) { + unsigned int remainder = validRowBytes % unpackAlignment; + if (remainder) + totalRowBytes += (unpackAlignment - remainder); } + *sourceElementsPerPixel = bytesPerPixel / elementSizeInBytes; + if (validRowBytes == totalRowBytes) + *sourceElementsPerRow = 0; + else + *sourceElementsPerRow = totalRowBytes / elementSizeInBytes; } -// This handles all conversions with a faster path for RGBA8 source data. -template<typename SourceType, typename DestType, void packingFunc(const SourceType*, DestType*)> -static void doPacking(const SourceType* sourceData, +// This handles all conversions with a faster path for tightly packed RGBA8 source data. +template<typename DestType, void packingFunc(const uint8_t*, DestType*)> +static void doPacking(const void* sourceData, GraphicsContext3D::SourceDataFormat sourceDataFormat, - unsigned int numElements, - unsigned int sourceElementsPerPixel, + unsigned int width, + unsigned int height, + unsigned int sourceUnpackAlignment, DestType* destinationData, unsigned int destinationElementsPerPixel) { switch (sourceDataFormat) { case GraphicsContext3D::kSourceFormatRGBA8: { - const SourceType* endPointer = sourceData + numElements; - while (sourceData < endPointer) { - packingFunc(sourceData, destinationData); - sourceData += sourceElementsPerPixel; - destinationData += destinationElementsPerPixel; + unsigned int sourceElementsPerPixel, sourceElementsPerRow; + computeIncrementParameters<uint8_t>(width, 4, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); + if (!sourceElementsPerRow) { + const uint8_t* source = static_cast<const uint8_t*>(sourceData); + unsigned int numElements = width * height * 4; + const uint8_t* endPointer = source + numElements; + while (source < endPointer) { + packingFunc(source, destinationData); + source += sourceElementsPerPixel; + destinationData += destinationElementsPerPixel; + } + } else { + doUnpackingAndPacking<uint8_t, DestType, unpackRGBA8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); } break; } case GraphicsContext3D::kSourceFormatRGB8: { - doUnpackingAndPacking<SourceType, DestType, unpackRGB8ToRGBA8, packingFunc>(sourceData, numElements, sourceElementsPerPixel, destinationData, destinationElementsPerPixel); + unsigned int sourceElementsPerPixel, sourceElementsPerRow; + computeIncrementParameters<uint8_t>(width, 3, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); + doUnpackingAndPacking<uint8_t, DestType, unpackRGB8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); break; } case GraphicsContext3D::kSourceFormatBGRA8: { - doUnpackingAndPacking<SourceType, DestType, unpackBGRA8ToRGBA8, packingFunc>(sourceData, numElements, sourceElementsPerPixel, destinationData, destinationElementsPerPixel); + unsigned int sourceElementsPerPixel, sourceElementsPerRow; + computeIncrementParameters<uint8_t>(width, 4, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); + doUnpackingAndPacking<uint8_t, DestType, unpackBGRA8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); + break; + } + case GraphicsContext3D::kSourceFormatRGBA5551: { + unsigned int sourceElementsPerPixel, sourceElementsPerRow; + computeIncrementParameters<uint16_t>(width, 2, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); + doUnpackingAndPacking<uint16_t, DestType, unpackRGBA5551ToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); + break; + } + case GraphicsContext3D::kSourceFormatRGBA4444: { + unsigned int sourceElementsPerPixel, sourceElementsPerRow; + computeIncrementParameters<uint16_t>(width, 2, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); + doUnpackingAndPacking<uint16_t, DestType, unpackRGBA4444ToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); + break; + } + case GraphicsContext3D::kSourceFormatRGB565: { + unsigned int sourceElementsPerPixel, sourceElementsPerRow; + computeIncrementParameters<uint16_t>(width, 2, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); + doUnpackingAndPacking<uint16_t, DestType, unpackRGB565ToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); + break; + } + case GraphicsContext3D::kSourceFormatR8: { + unsigned int sourceElementsPerPixel, sourceElementsPerRow; + computeIncrementParameters<uint8_t>(width, 1, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); + doUnpackingAndPacking<uint8_t, DestType, unpackR8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); + break; + } + case GraphicsContext3D::kSourceFormatRA8: { + unsigned int sourceElementsPerPixel, sourceElementsPerRow; + computeIncrementParameters<uint8_t>(width, 2, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); + doUnpackingAndPacking<uint8_t, DestType, unpackRA8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); + break; + } + case GraphicsContext3D::kSourceFormatA8: { + unsigned int sourceElementsPerPixel, sourceElementsPerRow; + computeIncrementParameters<uint8_t>(width, 1, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow); + doUnpackingAndPacking<uint8_t, DestType, unpackA8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel); break; } } @@ -455,46 +682,45 @@ bool GraphicsContext3D::packPixels(const uint8_t* sourceData, GraphicsContext3D::SourceDataFormat sourceDataFormat, unsigned int width, unsigned int height, + unsigned int sourceUnpackAlignment, unsigned int destinationFormat, unsigned int destinationType, AlphaOp alphaOp, void* destinationData) { - unsigned int sourceElementsPerPixel = 4; - unsigned int numElements = width * height * sourceElementsPerPixel; switch (destinationType) { case UNSIGNED_BYTE: { uint8_t* destination = static_cast<uint8_t*>(destinationData); - if (sourceDataFormat == kSourceFormatRGBA8 && destinationFormat == RGBA && alphaOp == kAlphaDoNothing) { + if (sourceDataFormat == kSourceFormatRGBA8 && destinationFormat == RGBA && sourceUnpackAlignment <= 4 && alphaOp == kAlphaDoNothing) { // No conversion necessary. - memcpy(destinationData, sourceData, numElements); + memcpy(destinationData, sourceData, width * height * 4); break; } switch (destinationFormat) { case RGB: switch (alphaOp) { case kAlphaDoNothing: - doPacking<uint8_t, uint8_t, packRGBA8ToRGB8>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 3); + doPacking<uint8_t, packRGBA8ToRGB8>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 3); break; case kAlphaDoPremultiply: - doPacking<uint8_t, uint8_t, packRGBA8ToRGB8Premultiply>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 3); + doPacking<uint8_t, packRGBA8ToRGB8Premultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 3); break; case kAlphaDoUnmultiply: - doPacking<uint8_t, uint8_t, packRGBA8ToRGB8Unmultiply>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 3); + doPacking<uint8_t, packRGBA8ToRGB8Unmultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 3); break; } break; case RGBA: switch (alphaOp) { case kAlphaDoNothing: - ASSERT(sourceDataFormat != kSourceFormatRGBA8); // Handled above with fast case. - doPacking<uint8_t, uint8_t, packRGBA8ToRGBA8>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 4); + ASSERT(sourceDataFormat != kSourceFormatRGBA8 || sourceUnpackAlignment > 4); // Handled above with fast case. + doPacking<uint8_t, packRGBA8ToRGBA8>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 4); break; case kAlphaDoPremultiply: - doPacking<uint8_t, uint8_t, packRGBA8ToRGBA8Premultiply>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 4); + doPacking<uint8_t, packRGBA8ToRGBA8Premultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 4); break; case kAlphaDoUnmultiply: - doPacking<uint8_t, uint8_t, packRGBA8ToRGBA8Unmultiply>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 4); + doPacking<uint8_t, packRGBA8ToRGBA8Unmultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 4); break; default: ASSERT_NOT_REACHED(); @@ -504,7 +730,7 @@ bool GraphicsContext3D::packPixels(const uint8_t* sourceData, // From the desktop OpenGL conversion rules (OpenGL 2.1 // specification, Table 3.15), the alpha channel is chosen // from the RGBA data. - doPacking<uint8_t, uint8_t, packRGBA8ToA8>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 1); + doPacking<uint8_t, packRGBA8ToA8>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1); break; case LUMINANCE: // From the desktop OpenGL conversion rules (OpenGL 2.1 @@ -512,13 +738,13 @@ bool GraphicsContext3D::packPixels(const uint8_t* sourceData, // from the RGBA data. switch (alphaOp) { case kAlphaDoNothing: - doPacking<uint8_t, uint8_t, packRGBA8ToR8>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 1); + doPacking<uint8_t, packRGBA8ToR8>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1); break; case kAlphaDoPremultiply: - doPacking<uint8_t, uint8_t, packRGBA8ToR8Premultiply>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 1); + doPacking<uint8_t, packRGBA8ToR8Premultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1); break; case kAlphaDoUnmultiply: - doPacking<uint8_t, uint8_t, packRGBA8ToR8Unmultiply>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 1); + doPacking<uint8_t, packRGBA8ToR8Unmultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1); break; } break; @@ -528,13 +754,13 @@ bool GraphicsContext3D::packPixels(const uint8_t* sourceData, // are chosen from the RGBA data. switch (alphaOp) { case kAlphaDoNothing: - doPacking<uint8_t, uint8_t, packRGBA8ToRA8>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 2); + doPacking<uint8_t, packRGBA8ToRA8>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 2); break; case kAlphaDoPremultiply: - doPacking<uint8_t, uint8_t, packRGBA8ToRA8Premultiply>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 2); + doPacking<uint8_t, packRGBA8ToRA8Premultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 2); break; case kAlphaDoUnmultiply: - doPacking<uint8_t, uint8_t, packRGBA8ToRA8Unmultiply>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 2); + doPacking<uint8_t, packRGBA8ToRA8Unmultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 2); break; } break; @@ -545,13 +771,13 @@ bool GraphicsContext3D::packPixels(const uint8_t* sourceData, uint16_t* destination = static_cast<uint16_t*>(destinationData); switch (alphaOp) { case kAlphaDoNothing: - doPacking<uint8_t, uint16_t, packRGBA8ToUnsignedShort4444>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 1); + doPacking<uint16_t, packRGBA8ToUnsignedShort4444>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1); break; case kAlphaDoPremultiply: - doPacking<uint8_t, uint16_t, packRGBA8ToUnsignedShort4444Premultiply>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 1); + doPacking<uint16_t, packRGBA8ToUnsignedShort4444Premultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1); break; case kAlphaDoUnmultiply: - doPacking<uint8_t, uint16_t, packRGBA8ToUnsignedShort4444Unmultiply>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 1); + doPacking<uint16_t, packRGBA8ToUnsignedShort4444Unmultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1); break; } break; @@ -560,13 +786,13 @@ bool GraphicsContext3D::packPixels(const uint8_t* sourceData, uint16_t* destination = static_cast<uint16_t*>(destinationData); switch (alphaOp) { case kAlphaDoNothing: - doPacking<uint8_t, uint16_t, packRGBA8ToUnsignedShort5551>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 1); + doPacking<uint16_t, packRGBA8ToUnsignedShort5551>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1); break; case kAlphaDoPremultiply: - doPacking<uint8_t, uint16_t, packRGBA8ToUnsignedShort5551Premultiply>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 1); + doPacking<uint16_t, packRGBA8ToUnsignedShort5551Premultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1); break; case kAlphaDoUnmultiply: - doPacking<uint8_t, uint16_t, packRGBA8ToUnsignedShort5551Unmultiply>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 1); + doPacking<uint16_t, packRGBA8ToUnsignedShort5551Unmultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1); break; } break; @@ -575,13 +801,13 @@ bool GraphicsContext3D::packPixels(const uint8_t* sourceData, uint16_t* destination = static_cast<uint16_t*>(destinationData); switch (alphaOp) { case kAlphaDoNothing: - doPacking<uint8_t, uint16_t, packRGBA8ToUnsignedShort565>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 1); + doPacking<uint16_t, packRGBA8ToUnsignedShort565>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1); break; case kAlphaDoPremultiply: - doPacking<uint8_t, uint16_t, packRGBA8ToUnsignedShort565Premultiply>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 1); + doPacking<uint16_t, packRGBA8ToUnsignedShort565Premultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1); break; case kAlphaDoUnmultiply: - doPacking<uint8_t, uint16_t, packRGBA8ToUnsignedShort565Unmultiply>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 1); + doPacking<uint16_t, packRGBA8ToUnsignedShort565Unmultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1); break; } break; diff --git a/WebCore/platform/graphics/GraphicsContext3D.h b/WebCore/platform/graphics/GraphicsContext3D.h index 981459f..882362f 100644 --- a/WebCore/platform/graphics/GraphicsContext3D.h +++ b/WebCore/platform/graphics/GraphicsContext3D.h @@ -436,9 +436,7 @@ namespace WebCore { PlatformGraphicsContext3D platformGraphicsContext3D() const; Platform3DObject platformTexture() const; #if USE(ACCELERATED_COMPOSITING) - // FIXME: Stubbed out for now. Must be implemented to get WebGL working with - // accelerated compositing. - PlatformLayer* platformLayer() const { return 0; } + PlatformLayer* platformLayer() const; #endif #elif PLATFORM(QT) PlatformGraphicsContext3D platformGraphicsContext3D(); @@ -455,7 +453,7 @@ namespace WebCore { #endif void makeContextCurrent(); -#if PLATFORM(MAC) +#if PLATFORM(MAC) || PLATFORM(CHROMIUM) // With multisampling on, blit from multisampleFBO to regular FBO. void prepareTexture(); #endif @@ -500,6 +498,18 @@ namespace WebCore { bool premultiplyAlpha, Vector<uint8_t>& data); + // Helper function which extracts the user-supplied texture + // data, applying the flipY and premultiplyAlpha parameters. + // If the data is not tightly packed according to the passed + // unpackAlignment, the output data will be tightly packed. + // Returns true if successful, false if any error occurred. + bool extractTextureData(unsigned int width, unsigned int height, + unsigned int format, unsigned int type, + unsigned int unpackAlignment, + bool flipY, bool premultiplyAlpha, + ArrayBufferView* pixels, + Vector<uint8_t>& data); + // Flips the given image data vertically, in-place. void flipVertically(void* imageData, unsigned int width, @@ -514,7 +524,13 @@ namespace WebCore { enum SourceDataFormat { kSourceFormatRGBA8, kSourceFormatRGB8, - kSourceFormatBGRA8 + kSourceFormatBGRA8, + kSourceFormatRGBA5551, + kSourceFormatRGBA4444, + kSourceFormatRGB565, + kSourceFormatR8, + kSourceFormatRA8, + kSourceFormatA8 }; //---------------------------------------------------------------------- @@ -573,6 +589,8 @@ namespace WebCore { bool getActiveAttrib(WebGLProgram* program, unsigned long index, ActiveInfo&); bool getActiveUniform(WebGLProgram* program, unsigned long index, ActiveInfo&); + void getAttachedShaders(WebGLProgram* program, int maxCount, int* count, unsigned int* shaders); + int getAttribLocation(WebGLProgram*, const String& name); void getBooleanv(unsigned long pname, unsigned char* value); @@ -758,12 +776,14 @@ namespace WebCore { // Helper for getImageData which implements packing of pixel // data into the specified OpenGL destination format and type. - // Source data must be in RGBA format with no gaps between - // rows. Destination data will have no gaps between rows. + // A sourceUnpackAlignment of zero indicates that the source + // data is tightly packed. Non-zero values may take a slow path. + // Destination data will have no gaps between rows. bool packPixels(const uint8_t* sourceData, SourceDataFormat sourceDataFormat, unsigned int width, unsigned int height, + unsigned int sourceUnpackAlignment, unsigned int destinationFormat, unsigned int destinationType, AlphaOp alphaOp, diff --git a/WebCore/platform/graphics/GraphicsLayer.h b/WebCore/platform/graphics/GraphicsLayer.h index 4338d89..b5797fd 100644 --- a/WebCore/platform/graphics/GraphicsLayer.h +++ b/WebCore/platform/graphics/GraphicsLayer.h @@ -343,8 +343,10 @@ public: virtual float accumulatedOpacity() const; // Some compositing systems may do internal batching to synchronize compositing updates - // with updates drawn into the window. This is a signal to flush any internal batched state. + // with updates drawn into the window. These methods flush internal batched state on this layer + // and descendant layers, and this layer only. virtual void syncCompositingState() { } + virtual void syncCompositingStateForThisLayerOnly() { } // Return a string with a human readable form of the layer tree, If debug is true // pointers for the layers and timing data will be included in the returned string. diff --git a/WebCore/platform/graphics/IntRect.h b/WebCore/platform/graphics/IntRect.h index ad90dd9..c5990ef 100644 --- a/WebCore/platform/graphics/IntRect.h +++ b/WebCore/platform/graphics/IntRect.h @@ -48,7 +48,12 @@ QT_BEGIN_NAMESPACE class QRect; QT_END_NAMESPACE #elif PLATFORM(GTK) +#ifdef GTK_API_VERSION_2 typedef struct _GdkRectangle GdkRectangle; +#else +typedef struct _cairo_rectangle_int cairo_rectangle_int_t; +typedef cairo_rectangle_int_t GdkRectangle; +#endif #elif PLATFORM(HAIKU) class BRect; #endif diff --git a/WebCore/platform/graphics/TextRun.h b/WebCore/platform/graphics/TextRun.h index b5cd42a..79b6cb3 100644 --- a/WebCore/platform/graphics/TextRun.h +++ b/WebCore/platform/graphics/TextRun.h @@ -39,7 +39,9 @@ public: , m_len(len) , m_xpos(xpos) , m_padding(padding) - , m_glyphScale(1.0f) +#if ENABLE(SVG) + , m_horizontalGlyphStretch(1) +#endif , m_allowTabs(allowTabs) , m_rtl(rtl) , m_directionalOverride(directionalOverride) @@ -59,7 +61,9 @@ public: , m_len(s.length()) , m_xpos(xpos) , m_padding(padding) - , m_glyphScale(1.0f) +#if ENABLE(SVG) + , m_horizontalGlyphStretch(1) +#endif , m_allowTabs(allowTabs) , m_rtl(rtl) , m_directionalOverride(directionalOverride) @@ -81,8 +85,10 @@ public: void setText(const UChar* c, int len) { m_characters = c; m_len = len; } - float glyphScale() const { return m_glyphScale; } - void setGlyphScale(float scale) { m_glyphScale = scale; } +#if ENABLE(SVG) + float horizontalGlyphStretch() const { return m_horizontalGlyphStretch; } + void setHorizontalGlyphStretch(float scale) { m_horizontalGlyphStretch = scale; } +#endif bool allowTabs() const { return m_allowTabs; } int xPos() const { return m_xpos; } @@ -93,7 +99,6 @@ public: bool applyRunRounding() const { return m_applyRunRounding; } bool applyWordRounding() const { return m_applyWordRounding; } bool spacingDisabled() const { return m_disableSpacing; } - bool applyGlyphScaling() const { return m_glyphScale != 1.0f; } void disableSpacing() { m_disableSpacing = true; } void disableRoundingHacks() { m_applyRunRounding = m_applyWordRounding = false; } @@ -114,7 +119,9 @@ private: int m_xpos; int m_padding; - float m_glyphScale; +#if ENABLE(SVG) + float m_horizontalGlyphStretch; +#endif bool m_allowTabs; bool m_rtl; bool m_directionalOverride; diff --git a/WebCore/platform/graphics/WidthIterator.cpp b/WebCore/platform/graphics/WidthIterator.cpp index 0814d48..827cd10 100644 --- a/WebCore/platform/graphics/WidthIterator.cpp +++ b/WebCore/platform/graphics/WidthIterator.cpp @@ -135,9 +135,10 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer) } else { width = fontData->widthForGlyph(glyph); - // SVG uses glyphScale(), when textLength is used to stretch/squeeze text. - if (m_run.applyGlyphScaling()) - width *= m_run.glyphScale(); +#if ENABLE(SVG) + // SVG uses horizontalGlyphStretch(), when textLength is used to stretch/squeeze text. + width *= m_run.horizontalGlyphStretch(); +#endif // We special case spaces in two ways when applying word rounding. // First, we round spaces to an adjusted width in all fonts. diff --git a/WebCore/platform/graphics/cairo/DrawErrorUnderline.h b/WebCore/platform/graphics/cairo/DrawErrorUnderline.h new file mode 100644 index 0000000..9776853 --- /dev/null +++ b/WebCore/platform/graphics/cairo/DrawErrorUnderline.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2004 Red Hat, Inc. + * Copyright (C) 2010 Brent Fulgham <bfulgham@webkit.org> + * + * Based on Pango sources (see pangocairo-render.c) + * + * 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; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#if PLATFORM(CAIRO) + +#include <cairo.h> + +// +// Draws an error underline that looks like one of: +// +// H E H +// /\ /\ /\ /\ /\ - +// A/ \ / \ / \ A/ \ / \ | +// \ \ / \ / /D \ \ / \ | +// \ \/ C \/ / \ \/ C \ | height = heightSquares * square +// \ /\ F / \ F /\ \ | +// \ / \ / \ / \ \G | +// \ / \ / \ / \ / | +// \/ \/ \/ \/ - +// B B +// |---| +// unitWidth = (heightSquares - 1) * square +// +// The x, y, width, height passed in give the desired bounding box; +// x/width are adjusted to make the underline a integer number of units +// wide. +// +static inline void drawErrorUnderline(cairo_t* cr, double x, double y, double width, double height) +{ + static const double heightSquares = 2.5; + + double square = height / heightSquares; + double halfSquare = 0.5 * square; + + double unitWidth = (heightSquares - 1.0) * square; + int widthUnits = static_cast<int>(0.5 * (width + unitWidth) / unitWidth); + + x += 0.5 * (width - widthUnits * unitWidth); + width = widthUnits * unitWidth; + + double bottom = y + height; + double top = y; + + // Bottom of squiggle + cairo_move_to(cr, x - halfSquare, top + halfSquare); // A + + int i = 0; + for (i = 0; i < widthUnits; i += 2) { + double middle = x + (i + 1) * unitWidth; + double right = x + (i + 2) * unitWidth; + + cairo_line_to(cr, middle, bottom); // B + + if (i + 2 == widthUnits) + cairo_line_to(cr, right + halfSquare, top + halfSquare); // D + else if (i + 1 != widthUnits) + cairo_line_to(cr, right, top + square); // C + } + + // Top of squiggle + for (i -= 2; i >= 0; i -= 2) { + double left = x + i * unitWidth; + double middle = x + (i + 1) * unitWidth; + double right = x + (i + 2) * unitWidth; + + if (i + 1 == widthUnits) + cairo_line_to(cr, middle + halfSquare, bottom - halfSquare); // G + else { + if (i + 2 == widthUnits) + cairo_line_to(cr, right, top); // E + + cairo_line_to(cr, middle, bottom - halfSquare); // F + } + + cairo_line_to(cr, left, top); // H + } +} + +#endif diff --git a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp index 50564c5..e8324a3 100644 --- a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp +++ b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp @@ -504,6 +504,17 @@ void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points cairo_restore(cr); } +void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint* points) +{ + if (paintingDisabled()) + return; + + if (numPoints <= 1) + return; + + // FIXME: IMPLEMENT! +} + void GraphicsContext::fillPath() { if (paintingDisabled()) @@ -632,13 +643,27 @@ void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int cairo_new_path(cr); #if PLATFORM(GTK) +#ifdef GTK_API_VERSION_2 GdkRegion* reg = gdk_region_new(); +#else + cairo_region_t* reg = cairo_region_create(); +#endif + for (unsigned i = 0; i < rectCount; i++) { +#ifdef GTK_API_VERSION_2 GdkRectangle rect = rects[i]; gdk_region_union_with_rect(reg, &rect); +#else + cairo_rectangle_int_t rect = rects[i]; + cairo_region_union_rectangle(reg, &rect); +#endif } gdk_cairo_region(cr, reg); +#ifdef GTK_API_VERSION_2 gdk_region_destroy(reg); +#else + cairo_region_destroy(reg); +#endif setColor(cr, color); cairo_set_line_width(cr, 2.0f); @@ -683,6 +708,10 @@ void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool pr setStrokeStyle(savedStrokeStyle); } +#if !PLATFORM(GTK) +#include "DrawErrorUnderline.h" +#endif + void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint& origin, int width, bool grammar) { if (paintingDisabled()) @@ -702,7 +731,7 @@ void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint& origin, // We ignore most of the provided constants in favour of the platform style pango_cairo_show_error_underline(cr, origin.x(), origin.y(), width, cMisspellingLineThickness); #else - notImplemented(); + drawErrorUnderline(cr, origin.x(), origin.y(), width, cMisspellingLineThickness); #endif cairo_restore(cr); diff --git a/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp b/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp index 5c03a86..9f0f353 100644 --- a/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp +++ b/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp @@ -100,7 +100,7 @@ bool GraphicsContext3D::getImageData(Image* image, if (!premultiplyAlpha && hasAlphaChannel) // FIXME: must fetch the image data before the premultiplication step. neededAlphaOp = kAlphaDoUnmultiply; - return packPixels(tempVector.data(), kSourceFormatRGBA8, width, height, + return packPixels(tempVector.data(), kSourceFormatRGBA8, width, height, 0, format, type, neededAlphaOp, outputVector.data()); } diff --git a/WebCore/platform/graphics/cg/GraphicsContextCG.cpp b/WebCore/platform/graphics/cg/GraphicsContextCG.cpp index 5a903dc..a65874c 100644 --- a/WebCore/platform/graphics/cg/GraphicsContextCG.cpp +++ b/WebCore/platform/graphics/cg/GraphicsContextCG.cpp @@ -440,6 +440,15 @@ void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSp CGContextRestoreGState(context); } +static void addConvexPolygonToContext(CGContextRef context, size_t numPoints, const FloatPoint* points) +{ + CGContextBeginPath(context); + CGContextMoveToPoint(context, points[0].x(), points[0].y()); + for (size_t i = 1; i < numPoints; i++) + CGContextAddLineToPoint(context, points[i].x(), points[i].y()); + CGContextClosePath(context); +} + void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points, bool antialiased) { if (paintingDisabled()) @@ -453,18 +462,25 @@ 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++) - CGContextAddLineToPoint(context, points[i].x(), points[i].y()); - CGContextClosePath(context); - + addConvexPolygonToContext(context, npoints, points); drawPath(); if (antialiased != shouldAntialias()) CGContextSetShouldAntialias(context, shouldAntialias()); } +void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint* points) +{ + if (paintingDisabled()) + return; + + if (numPoints <= 1) + return; + + addConvexPolygonToContext(platformContext(), numPoints, points); + clipPath(RULE_NONZERO); +} + void GraphicsContext::applyStrokePattern() { CGContextRef cgContext = platformContext(); diff --git a/WebCore/platform/graphics/chromium/FontPlatformDataChromiumMac.mm b/WebCore/platform/graphics/chromium/FontPlatformDataChromiumMac.mm new file mode 100644 index 0000000..41f684e --- /dev/null +++ b/WebCore/platform/graphics/chromium/FontPlatformDataChromiumMac.mm @@ -0,0 +1,447 @@ +/* + * This file is part of the internal font implementation. + * + * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. + * Copyright (c) 2010 Google Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +// This file is a clone of platform/graphics/mac/FontPlatformDataMac.mm. +// Because we want to support loading fonts between processes in the face of +// font loading being blocked by the sandbox, we must maintain a fork. +// Please maintain this file by performing parallel changes to it. +// +// The only changes from FontPlatformDataMac should be: +// - The functions at the top of this file for loading and caching fonts +// cross-process. +// - Changes to FontPlatformData::FontPlatformData(NSFont,bool,bool) +// - Changes to FontPlatformData::setFont() +// - Changes to FontPlatformData::~FontPlatformData() +// - Calls to refMemoryFont() in FontPlatformData::operator= and copy +// constructor. +// +// All changes are marked with "Start/End Chromium Change" +// +// For all other differences, if it was introduced in this file, then the +// maintainer forgot to include it in the list; otherwise it is an update that +// should have been applied to this file but was not. + + +// Start Chromium Change +#import "config.h" +#import "../graphics/mac/FontPlatformData.h" + +#import "ChromiumBridge.h" +#import "PlatformString.h" +#import "WebCoreSystemInterface.h" +#import <AppKit/NSFont.h> +#import <wtf/HashMap.h> +#import <wtf/RefCounted.h> +#import <wtf/RetainPtr.h> +#import <wtf/Vector.h> + +namespace WebCore { + +namespace { + +class MemoryActivatedFont; +typedef HashMap<ATSFontRef, MemoryActivatedFont*> FontRefMemoryFontHash; +typedef HashMap<ATSFontContainerRef, MemoryActivatedFont*> FontContainerRefMemoryFontHash; + +// On 10.5, font loading is not blocked by the sandbox and thus there is no +// need for the cross-process font loading mechanim. +// On system versions >=10.6 cross-process font loading is required. +bool OutOfProcessFontLoadingEnabled() +{ + static SInt32 systemVersion = 0; + if (!systemVersion) { + if (Gestalt(gestaltSystemVersion, &systemVersion) != noErr) + return false; + } + + return systemVersion >= 0x1060; +} + +FontContainerRefMemoryFontHash& fontCacheBySrcFontContainerRef() +{ + DEFINE_STATIC_LOCAL(FontContainerRefMemoryFontHash, srcFontRefCache, ()); + return srcFontRefCache; +} + +FontRefMemoryFontHash& fontCacheByActualFontRef() +{ + DEFINE_STATIC_LOCAL(FontRefMemoryFontHash, realFontRefCache, ()); + return realFontRefCache; +} + +ATSFontContainerRef fontContainerRefFromNSFont(NSFont* srcFont) +{ + ATSFontRef fontRef = CTFontGetPlatformFont(toCTFontRef(srcFont), 0); + if (!fontRef) + return kATSFontContainerRefUnspecified; + ATSFontContainerRef fontContainer = kATSFontContainerRefUnspecified; + if (ATSFontGetContainer(fontRef, 0, &fontContainer) != noErr) + return kATSFontContainerRefUnspecified; + return fontContainer; +} + +// MemoryActivatedFont encapsulates a font loaded from another process and +// activated from memory. +// +// Responsibilities: +// * Holder for the CGFontRef & ATSFontRef belonging to the activated font. +// * Responsible for unloading the font container when done. +// +// Memory Management: +// The class is reference counted, with each instance of FontPlatformData that +// uses this class holding a reference to it. +// Entries in 2 hashes are maintained internally to allow quick lookup +// of existing instances for reuse: +// - fontCacheBySrcFontContainerRef() - key is the ATSFontContainerRef +// corresponding to the *original in-process NSFont* whose loading was blocked +// by the sandbox. +// This is needed to allow lookup of a pre-existing MemoryActivatedFont when +// creating a new FontPlatformData object. +// - fontCacheByActualFontRef() - key is the ATSFontRef corresponding to the +// *new in-memory font* that we got from the browser process. +// This is needed so that a FontPlatformData object can refer back to the +// MemoryActivatedFont it's using. Currently this is only needed to release +// the font on FontPlatformData destruction. +// +// Assumptions: +// This code assumes that an ATSFontRef is a unique identifier tied to an +// activated font. i.e. After we activate a font, its ATSFontRef doesn't +// change. +// It also assumes that the ATSFoncontainerRef for two in-memory NSFonts that +// correspond to the same on-disk font file are always the same and don't change +// with time. +// +// Flushing caches: +// When the system notifies us of a system font cache flush, all FontDataCache +// objects are destroyed. This should in turn dereference all +// MemoryActivatedFonts and thus unload all in-memory fonts. +class MemoryActivatedFont : public RefCounted<MemoryActivatedFont> { +public: + // srcFontRef - ATSFontRef belonging to the NSFont object that failed to + // load in-process. + // container - a font container corresponding to an identical font that + // we loaded cross-process. + MemoryActivatedFont(ATSFontContainerRef srcFontContainerRef, ATSFontContainerRef container) + : m_fontContainer(container) + , m_atsFontRef(kATSFontRefUnspecified) + , m_srcFontContainerRef(srcFontContainerRef) + { + if (!container) + return; + + // Count the number of fonts in the container. + ItemCount fontCount = 0; + OSStatus err = ATSFontFindFromContainer(container, kATSOptionFlagsDefault, 0, 0, &fontCount); + if (err != noErr || fontCount < 1) + return; + + // For now always assume that we want the first font in the container. + ATSFontFindFromContainer(container, kATSOptionFlagsDefault, 1, &m_atsFontRef, 0); + + if (!m_atsFontRef) + return; + + // Cache CGFont representation of the font. + m_cgFont.adoptCF(CGFontCreateWithPlatformFont(&m_atsFontRef)); + + if (!m_cgFont.get()) + return; + + // Add ourselves to caches. + fontCacheBySrcFontContainerRef().add(m_srcFontContainerRef, this); + fontCacheByActualFontRef().add(m_atsFontRef, this); + } + + // Get cached CGFontRef corresponding to the in-memory font. + CGFontRef cgFont() + { + return m_cgFont.get(); + } + + // Get cached ATSFontRef corresponding to the in-memory font. + ATSFontRef atsFontRef() + { + return m_atsFontRef; + } + + // Destructor - Unload font container from memory and remove ourselves + // from hashes. + ~MemoryActivatedFont() + { + if (m_cgFont.get()) { // Object construction succeeded. + // First remove ourselves from the caches. + ASSERT(fontCacheBySrcFontContainerRef().contains(m_srcFontContainerRef)); + ASSERT(fontCacheByActualFontRef().contains(m_atsFontRef)); + + fontCacheBySrcFontContainerRef().remove(m_srcFontContainerRef); + fontCacheByActualFontRef().remove(m_atsFontRef); + + // Make sure the CGFont is destroyed before its font container. + m_cgFont.releaseRef(); + } + + if (m_fontContainer != kATSFontContainerRefUnspecified) + ATSFontDeactivate(m_fontContainer, 0, kATSOptionFlagsDefault); + } + +private: + ATSFontContainerRef m_fontContainer; + WTF::RetainPtr<CGFontRef> m_cgFont; + ATSFontRef m_atsFontRef; + ATSFontContainerRef m_srcFontContainerRef; +}; + +// The only way we can tell that an in-process font has failed to load +// is if CTFontCopyGraphicsFont() returns the LastResort font. +bool isLastResortFont(CGFontRef cgFont) +{ + NSString* fontName = (NSString*)CGFontCopyPostScriptName(cgFont); + return [fontName isEqualToString:@"LastResort"]; +} + +// Given an in-process font which has failed to load, return a +// MemoryActivatedFont* corresponding to an in-memory representation of the +// same font loaded from the browser process. +// The caller is responsbile for calling derefMemoryFont() on the ATSFontRef +// of the returned font. +// On failure this function returns 0, in which case the caller doesn't need +// to perform any additional cleanup. +MemoryActivatedFont* loadFontFromBrowserProcess(NSFont* nsFont) +{ + ATSFontContainerRef container; + // Send cross-process request to load font. + if (!ChromiumBridge::loadFont(nsFont, &container)) + return 0; + + ATSFontContainerRef srcFontContainerRef = fontContainerRefFromNSFont(nsFont); + if (!srcFontContainerRef) { + ATSFontDeactivate(container, 0, kATSOptionFlagsDefault); + return 0; + } + + MemoryActivatedFont* font = fontCacheBySrcFontContainerRef().get(srcFontContainerRef); + if (!font) { + font = new MemoryActivatedFont(srcFontContainerRef, container); + if (!font->cgFont()) { + delete font; + return 0; + } + } else { + font->ref(); + } + + return font; +} + +// deref() the MemoryActivatedFont corresponding to the given ATSFontRef. If no +// corresponding MemoryActivatedFont object exists, no action is performed. +void derefMemoryFont(ATSFontRef fontRef) +{ + if (fontRef == kATSFontRefUnspecified) + return; + MemoryActivatedFont* font = fontCacheByActualFontRef().get(fontRef); + if (font) + font->deref(); +} + +// ref() the MemoryActivatedFont corresponding to the given ATSFontRef. If no +// corresponding MemoryActivatedFont object exists, no action is performed. +void refMemoryFont(ATSFontRef fontRef) +{ + if (fontRef == kATSFontRefUnspecified) + return; + MemoryActivatedFont* font = fontCacheByActualFontRef().get(fontRef); + if (font) + font->ref(); +} + +// Given an NSFont, try to load a representation of that font into the cgFont +// parameter. If loading is blocked by the sandbox, the font may be loaded +// cross-process. +// If sandbox loading also fails, a fallback font is loaded. +// +// Considerations: +// * cgFont must be CFReleas()ed by the caller when done. +// +// Parameters: +// * nsFont - The font we wish to load. +// * fontSize - point size of the font we wish to load. +// * outNSFont - The font that was actually loaded, may be different from nsFont +// if a fallback font was used. +// * cgFont - on output this contains the CGFontRef corresponding to the NSFont +// that was picked in the end. The caller is responsible for calling +// CFRelease() on this parameter when done with it. +// * fontID - on output, the ID corresponding to nsFont. +void loadFont(NSFont* nsFont, float fontSize, NSFont*& outNSFont, CGFontRef& cgFont, ATSUFontID& fontID) +{ + outNSFont = nsFont; + cgFont = CTFontCopyGraphicsFont(toCTFontRef(outNSFont), 0); + MemoryActivatedFont* memFont = 0; + if (OutOfProcessFontLoadingEnabled() && outNSFont && cgFont && isLastResortFont(cgFont)) { + // Release old CGFontRef since it points at the LastResort font which we don't want. + CFRelease(cgFont); + cgFont = 0; + + // Font loading was blocked by the Sandbox. + memFont = loadFontFromBrowserProcess(outNSFont); + if (memFont) { + cgFont = memFont->cgFont(); + + // Need to add an extra retain so output semantics of this function + // are consistent. + CFRetain(cgFont); + } else { + // If we still can't load the font, then return Times, + // rather than the LastResort font. + outNSFont = [NSFont fontWithName:@"Times" size:fontSize]; + cgFont = CTFontCopyGraphicsFont(toCTFontRef(outNSFont), 0); + } + } + + if (memFont) { + fontID = memFont->atsFontRef(); + } else { + fontID = CTFontGetPlatformFont(toCTFontRef(outNSFont), 0); + } +} + +} // namespace +// End Chromium Change + +FontPlatformData::FontPlatformData(NSFont *nsFont, bool syntheticBold, bool syntheticOblique) + : m_syntheticBold(syntheticBold) + , m_syntheticOblique(syntheticOblique) + , m_font(nsFont) +#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) + , m_isColorBitmapFont(CTFontGetSymbolicTraits(toCTFontRef(nsFont)) & kCTFontColorGlyphsTrait) +#else + , m_isColorBitmapFont(false) +#endif +{ +// Start Chromium Change + m_size = nsFont ? [nsFont pointSize] : 0.0f; + CGFontRef cgFont = 0; + NSFont* loadedFont = 0; + loadFont(nsFont, m_size, loadedFont, cgFont, m_atsuFontID); + m_font = loadedFont; + if (m_font) + CFRetain(m_font); + m_cgFont.adoptCF(cgFont); +// End Chromium Change +} + +FontPlatformData::FontPlatformData(const FontPlatformData& f) +{ + m_font = f.m_font && f.m_font != reinterpret_cast<NSFont *>(-1) ? const_cast<NSFont *>(static_cast<const NSFont *>(CFRetain(f.m_font))) : f.m_font; + + m_syntheticBold = f.m_syntheticBold; + m_syntheticOblique = f.m_syntheticOblique; + m_size = f.m_size; + m_cgFont = f.m_cgFont; + m_atsuFontID = f.m_atsuFontID; + m_isColorBitmapFont = f.m_isColorBitmapFont; + // Start Chromium Change + refMemoryFont(m_atsuFontID); + // End Chromium Change +} + +FontPlatformData::~FontPlatformData() +{ + if (m_font && m_font != reinterpret_cast<NSFont *>(-1)) + CFRelease(m_font); + + // Start Chromium Change + derefMemoryFont(m_atsuFontID); + // End Chromium Change +} + +const FontPlatformData& FontPlatformData::operator=(const FontPlatformData& f) +{ + m_syntheticBold = f.m_syntheticBold; + m_syntheticOblique = f.m_syntheticOblique; + m_size = f.m_size; + m_cgFont = f.m_cgFont; + m_atsuFontID = f.m_atsuFontID; + if (m_font == f.m_font) + return *this; + if (f.m_font && f.m_font != reinterpret_cast<NSFont *>(-1)) + CFRetain(f.m_font); + if (m_font && m_font != reinterpret_cast<NSFont *>(-1)) + CFRelease(m_font); + m_font = f.m_font; + m_isColorBitmapFont = f.m_isColorBitmapFont; + // Start Chromium Change + refMemoryFont(m_atsuFontID); + // End Chromium Change + return *this; +} + +void FontPlatformData::setFont(NSFont *font) +{ + if (m_font == font) + return; + if (font) + CFRetain(font); + if (m_font && m_font != reinterpret_cast<NSFont *>(-1)) + CFRelease(m_font); + m_font = font; + m_size = font ? [font pointSize] : 0.0f; + + // Start Chromium Change + CGFontRef cgFont = 0; + NSFont* loadedFont = 0; + loadFont(m_font, m_size, loadedFont, cgFont, m_atsuFontID); + + // If loadFont replaced m_font with a fallback font, then release the + // previous font to counter the retain above. Then retain the new font. + if (loadedFont != m_font) { + CFRelease(m_font); + m_font = loadedFont; + CFRetain(m_font); + } + m_cgFont.adoptCF(cgFont); +#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) + m_isColorBitmapFont = CTFontGetSymbolicTraits(toCTFontRef(m_font)) & kCTFontColorGlyphsTrait; +#endif + // End Chromium Change +} + +bool FontPlatformData::roundsGlyphAdvances() const +{ + return [m_font renderingMode] == NSFontAntialiasedIntegerAdvancementsRenderingMode; +} + +bool FontPlatformData::allowsLigatures() const +{ + return ![[m_font coveredCharacterSet] characterIsMember:'a']; +} + +#ifndef NDEBUG +String FontPlatformData::description() const +{ + RetainPtr<CFStringRef> cgFontDescription(AdoptCF, CFCopyDescription(cgFont())); + return String(cgFontDescription.get()) + " " + String::number(m_size) + (m_syntheticBold ? " synthetic bold" : "") + (m_syntheticOblique ? " synthetic oblique" : ""); +} +#endif + +} // namespace WebCore diff --git a/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp b/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp index 0a5aec5..dda10b7 100644 --- a/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp +++ b/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp @@ -148,6 +148,7 @@ void FontPlatformData::setupPaint(SkPaint* paint) const paint->setTypeface(m_typeface); paint->setFakeBoldText(m_fakeBold); paint->setTextSkewX(m_fakeItalic ? -SK_Scalar1 / 4 : 0); + paint->setAutohinted(m_style.useAutoHint); if (m_style.useAntiAlias == 1 || (m_style.useAntiAlias == FontRenderStyle::NoPreference && isSkiaAntiAlias)) paint->setLCDRenderText(m_style.useSubpixel == FontRenderStyle::NoPreference ? isSkiaSubpixelGlyphs : m_style.useSubpixel); @@ -175,7 +176,8 @@ bool FontPlatformData::operator==(const FontPlatformData& a) const return typefacesEqual && m_textSize == a.m_textSize && m_fakeBold == a.m_fakeBold - && m_fakeItalic == a.m_fakeItalic; + && m_fakeItalic == a.m_fakeItalic + && m_style == a.m_style; } unsigned FontPlatformData::hash() const diff --git a/WebCore/platform/graphics/chromium/FontRenderStyle.h b/WebCore/platform/graphics/chromium/FontRenderStyle.h index 1a3c736..6e2ae54 100644 --- a/WebCore/platform/graphics/chromium/FontRenderStyle.h +++ b/WebCore/platform/graphics/chromium/FontRenderStyle.h @@ -39,6 +39,24 @@ struct FontRenderStyle { NoPreference = 2, }; + FontRenderStyle() + : useBitmaps(0), + useAutoHint(0), + useHinting(0), + hintStyle(0), + useAntiAlias(0), + useSubpixel(0) { } + + bool operator==(const FontRenderStyle& a) const + { + return useBitmaps == a.useBitmaps + && useAutoHint == a.useAutoHint + && useHinting == a.useHinting + && hintStyle == a.hintStyle + && useAntiAlias == a.useAntiAlias + && useSubpixel == a.useSubpixel; + } + // Each of the use* members below can take one of three values: // 0: off // 1: on diff --git a/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp b/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp index b26565c..9b65346 100644 --- a/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp +++ b/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp @@ -53,6 +53,7 @@ #include "PlatformString.h" #include "SystemTime.h" #include "TransformLayerChromium.h" +#include "WebGLLayerChromium.h" #include <wtf/CurrentTime.h> #include <wtf/StringExtras.h> #include <wtf/text/CString.h> @@ -333,6 +334,35 @@ void GraphicsLayerChromium::setContentsToImage(Image* image) updateSublayerList(); } +#if ENABLE(3D_CANVAS) +void GraphicsLayerChromium::setContentsToWebGL(PlatformLayer* platformLayer) +{ + bool childrenChanged = false; + if (platformLayer) { + if (!m_contentsLayer.get() || m_contentsLayerPurpose != ContentsLayerForWebGL) { + WebGLLayerChromium* webGLLayer = static_cast<WebGLLayerChromium*>(platformLayer); + setupContentsLayer(webGLLayer); + m_contentsLayer = webGLLayer; + m_contentsLayerPurpose = ContentsLayerForWebGL; + childrenChanged = true; + } + platformLayer->setOwner(this); + platformLayer->setNeedsDisplay(); + updateContentsRect(); + } else { + if (m_contentsLayer) { + childrenChanged = true; + + // The old contents layer will be removed via updateSublayerList. + m_contentsLayer = 0; + } + } + + if (childrenChanged) + updateSublayerList(); +} +#endif + void GraphicsLayerChromium::setContentsToVideo(PlatformLayer* videoLayer) { // FIXME: Implement diff --git a/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h b/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h index 0c84c80..ccd02eb 100644 --- a/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h +++ b/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h @@ -86,6 +86,7 @@ public: virtual void setContentsToImage(Image*); virtual void setContentsToVideo(PlatformLayer*); + virtual void setContentsToWebGL(PlatformLayer*); virtual PlatformLayer* platformLayer() const; diff --git a/WebCore/platform/graphics/chromium/LayerChromium.cpp b/WebCore/platform/graphics/chromium/LayerChromium.cpp index e3209a7..3119dd6 100644 --- a/WebCore/platform/graphics/chromium/LayerChromium.cpp +++ b/WebCore/platform/graphics/chromium/LayerChromium.cpp @@ -136,11 +136,14 @@ void LayerChromium::updateTextureContents(unsigned textureId) canvas.set(new skia::PlatformCanvas(dirtyRect.width(), dirtyRect.height(), false)); skiaContext.set(new PlatformContextSkia(canvas.get())); +#if OS(WINDOWS) // This is needed to get text to show up correctly. Without it, // GDI renders with zero alpha and the text becomes invisible. // Unfortunately, setting this to true disables cleartype. // FIXME: Does this take us down a very slow text rendering path? + // FIXME: why is this is a windows-only call ? skiaContext->setDrawingToImageBuffer(true); +#endif graphicsContext.set(new GraphicsContext(reinterpret_cast<PlatformGraphicsContext*>(skiaContext.get()))); @@ -296,7 +299,6 @@ void LayerChromium::removeAllSublayers() ASSERT(layer->superlayer()); layer->removeFromSuperlayer(); } - setNeedsCommit(); } void LayerChromium::setSublayers(const Vector<RefPtr<LayerChromium> >& sublayers) diff --git a/WebCore/platform/graphics/chromium/LayerChromium.h b/WebCore/platform/graphics/chromium/LayerChromium.h index f19baea..ebb4504 100644 --- a/WebCore/platform/graphics/chromium/LayerChromium.h +++ b/WebCore/platform/graphics/chromium/LayerChromium.h @@ -172,6 +172,8 @@ public: static void setShaderProgramId(unsigned shaderProgramId) { m_shaderProgramId = shaderProgramId; } virtual unsigned shaderProgramId() { return m_shaderProgramId; } + void setOwner(GraphicsLayerChromium* owner) { m_owner = owner; } + protected: GraphicsLayerChromium* m_owner; LayerChromium(GraphicsLayerChromium* owner); diff --git a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp index dc587dd..59da9ae 100644 --- a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp +++ b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp @@ -241,7 +241,10 @@ void LayerRendererChromium::setRootLayerCanvasSize(const IntSize& size) // the old ones. m_rootLayerCanvas = new skia::PlatformCanvas(size.width(), size.height(), false); m_rootLayerSkiaContext = new PlatformContextSkia(m_rootLayerCanvas.get()); +#if OS(WINDOWS) + // FIXME: why is this is a windows-only call ? m_rootLayerSkiaContext->setDrawingToImageBuffer(true); +#endif m_rootLayerGraphicsContext = new GraphicsContext(reinterpret_cast<PlatformGraphicsContext*>(m_rootLayerSkiaContext.get())); #else #error "Need to implement for your platform." @@ -623,11 +626,6 @@ void LayerRendererChromium::drawLayer(LayerChromium* layer) layer->updateTextureContents(textureId); } - // FIXME: This is temporary until WebGL layers stop changing the current - // context. - if (layer->ownsTexture()) - makeContextCurrent(); - if (layer->doubleSided()) glDisable(GL_CULL_FACE); else diff --git a/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp b/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp index 6b49b9a..ebd9ebe 100644 --- a/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp +++ b/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp @@ -34,10 +34,18 @@ #include "WebGLLayerChromium.h" +#include "GraphicsContext3D.h" +#include <GLES2/gl2.h> + namespace WebCore { unsigned WebGLLayerChromium::m_shaderProgramId = 0; +PassRefPtr<WebGLLayerChromium> WebGLLayerChromium::create(GraphicsLayerChromium* owner) +{ + return adoptRef(new WebGLLayerChromium(owner)); +} + WebGLLayerChromium::WebGLLayerChromium(GraphicsLayerChromium* owner) : LayerChromium(owner) , m_context(0) @@ -53,12 +61,33 @@ unsigned WebGLLayerChromium::textureId() void WebGLLayerChromium::updateTextureContents(unsigned textureId) { - // FIXME: Implement + ASSERT(textureId == m_textureId); + ASSERT(m_context); + if (m_textureChanged) { + glBindTexture(GL_TEXTURE_2D, m_textureId); + // Set the min-mag filters to linear and wrap modes to GL_CLAMP_TO_EDGE + // to get around NPOT texture limitations of GLES. + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + m_textureChanged = false; + } + // Update the contents of the texture used by the compositor. + if (m_contentsDirty) { + m_context->prepareTexture(); + m_contentsDirty = false; + } } void WebGLLayerChromium::setContext(const GraphicsContext3D* context) { - // FIXME: Implement + m_context = const_cast<GraphicsContext3D*>(context); + + unsigned int textureId = m_context->platformTexture(); + if (textureId != m_textureId) + m_textureChanged = true; + m_textureId = textureId; } } diff --git a/WebCore/platform/graphics/gtk/FontGtk.cpp b/WebCore/platform/graphics/gtk/FontGtk.cpp index fae84cb..92f8816 100644 --- a/WebCore/platform/graphics/gtk/FontGtk.cpp +++ b/WebCore/platform/graphics/gtk/FontGtk.cpp @@ -181,6 +181,29 @@ bool Font::canReturnFallbackFontsForComplexText() return false; } +#ifndef GTK_API_VERSION_2 +static void cairo_region_shrink(cairo_region_t* region, int dx, int dy) +{ + int nRects = cairo_region_num_rectangles(region); + // Clear region. + cairo_region_subtract(region, region); + + for (int i = 0; i < nRects; i++) { + cairo_rectangle_int_t rect; + cairo_region_get_rectangle(region, i, &rect); + + if (rect.width <= 2 * dx || rect.height <= 2 * dy) + continue; + + rect.x += dx; + rect.y += dy; + rect.width -= 2 * dx; + rect.height -= 2 * dy; + cairo_region_union_rectangle(region, &rect); + } +} +#endif + void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const { cairo_t* cr = context->platformContext(); @@ -196,14 +219,22 @@ void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const F // Our layouts are single line PangoLayoutLine* layoutLine = pango_layout_get_line_readonly(layout, 0); - GdkRegion* partialRegion = NULL; +#ifdef GTK_API_VERSION_2 + GdkRegion* partialRegion = 0; +#else + cairo_region_t* partialRegion = 0; +#endif if (to - from != run.length()) { // Clip the region of the run to be rendered char* start = g_utf8_offset_to_pointer(utf8, from); char* end = g_utf8_offset_to_pointer(start, to - from); int ranges[] = {start - utf8, end - utf8}; partialRegion = gdk_pango_layout_line_get_clip_region(layoutLine, 0, 0, ranges, 1); +#ifdef GTK_API_VERSION_2 gdk_region_shrink(partialRegion, 0, -pixelSize()); +#else + cairo_region_shrink(partialRegion, 0, -pixelSize()); +#endif } Color fillColor = context->fillColor(); @@ -265,7 +296,11 @@ void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const F cairo_new_path(cr); if (partialRegion) +#ifdef GTK_API_VERSION_2 gdk_region_destroy(partialRegion); +#else + cairo_region_destroy(partialRegion); +#endif g_free(utf8); g_object_unref(layout); diff --git a/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp b/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp index 2f02f31..f9e1980 100644 --- a/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp +++ b/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp @@ -152,6 +152,17 @@ void GraphicsContext::drawConvexPolygon(size_t pointsLength, const FloatPoint* p m_data->m_view->StrokePolygon(bPoints, pointsLength, true, getHaikuStrokeStyle()); } +void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint* points) +{ + if (paintingDisabled()) + return; + + if (numPoints <= 1) + return; + + // FIXME: IMPLEMENT!! +} + void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorSpace colorSpace) { if (paintingDisabled()) diff --git a/WebCore/platform/graphics/mac/FontPlatformDataMac.mm b/WebCore/platform/graphics/mac/FontPlatformDataMac.mm index e2ab405..aebd9f7 100644 --- a/WebCore/platform/graphics/mac/FontPlatformDataMac.mm +++ b/WebCore/platform/graphics/mac/FontPlatformDataMac.mm @@ -123,7 +123,7 @@ bool FontPlatformData::allowsLigatures() const String FontPlatformData::description() const { RetainPtr<CFStringRef> cgFontDescription(AdoptCF, CFCopyDescription(cgFont())); - return String(cgFontDescription.get()) + " " + String::number(m_size) + (m_syntheticBold ? " synthetic bold" : "") + (m_syntheticOblique ? " syntheitic oblique" : ""); + return String(cgFontDescription.get()) + " " + String::number(m_size) + (m_syntheticBold ? " synthetic bold" : "") + (m_syntheticOblique ? " synthetic oblique" : ""); } #endif diff --git a/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm b/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm index 6457e4f..961ec45 100644 --- a/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm +++ b/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm @@ -736,6 +736,16 @@ bool GraphicsContext3D::getActiveUniform(WebGLProgram* program, unsigned long in return true; } +void GraphicsContext3D::getAttachedShaders(WebGLProgram* program, int maxCount, int* count, unsigned int* shaders) +{ + if (!program || !program->object()) { + synthesizeGLError(INVALID_VALUE); + return; + } + ensureContext(m_contextObj); + ::glGetAttachedShaders(static_cast<GLuint>(program->object()), maxCount, count, shaders); +} + int GraphicsContext3D::getAttribLocation(WebGLProgram* program, const String& name) { if (!program) @@ -1103,10 +1113,8 @@ void GraphicsContext3D::uniformMatrix4fv(long location, bool transpose, float* a void GraphicsContext3D::useProgram(WebGLProgram* program) { - ASSERT(program); - ensureContext(m_contextObj); - ::glUseProgram((GLuint) program->object()); + ::glUseProgram(program ? ((GLuint) program->object()) : 0); } void GraphicsContext3D::validateProgram(WebGLProgram* program) diff --git a/WebCore/platform/graphics/mac/GraphicsLayerCA.h b/WebCore/platform/graphics/mac/GraphicsLayerCA.h index c17204f..7d78dee 100644 --- a/WebCore/platform/graphics/mac/GraphicsLayerCA.h +++ b/WebCore/platform/graphics/mac/GraphicsLayerCA.h @@ -119,6 +119,7 @@ public: void recursiveCommitChanges(); virtual void syncCompositingState(); + virtual void syncCompositingStateForThisLayerOnly(); protected: virtual void setOpacityInternal(float); diff --git a/WebCore/platform/graphics/mac/GraphicsLayerCA.mm b/WebCore/platform/graphics/mac/GraphicsLayerCA.mm index 355c023..852bdb0 100644 --- a/WebCore/platform/graphics/mac/GraphicsLayerCA.mm +++ b/WebCore/platform/graphics/mac/GraphicsLayerCA.mm @@ -868,6 +868,12 @@ void GraphicsLayerCA::syncCompositingState() recursiveCommitChanges(); } +void GraphicsLayerCA::syncCompositingStateForThisLayerOnly() +{ + commitLayerChangesBeforeSublayers(); + commitLayerChangesAfterSublayers(); +} + void GraphicsLayerCA::recursiveCommitChanges() { commitLayerChangesBeforeSublayers(); diff --git a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm index c73eeea..5c327f9 100644 --- a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm +++ b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm @@ -1299,11 +1299,17 @@ static HashSet<String> mimeModernTypesCache() return cache; } -void MediaPlayerPrivate::getSupportedTypes(HashSet<String>& types) +void MediaPlayerPrivate::getSupportedTypes(HashSet<String>& supportedTypes) { + supportedTypes = mimeModernTypesCache(); + // Note: this method starts QTKitServer if it isn't already running when in 64-bit because it has to return the list // of every MIME type supported by QTKit. - types = mimeCommonTypesCache(); + HashSet<String> commonTypes = mimeCommonTypesCache(); + HashSet<String>::const_iterator it = commonTypes.begin(); + HashSet<String>::const_iterator end = commonTypes.end(); + for (; it != end; ++it) + supportedTypes.add(*it); } MediaPlayer::SupportsType MediaPlayerPrivate::supportsType(const String& type, const String& codecs) diff --git a/WebCore/platform/graphics/mac/SimpleFontDataMac.mm b/WebCore/platform/graphics/mac/SimpleFontDataMac.mm index bddb2ad..126ef2d 100644 --- a/WebCore/platform/graphics/mac/SimpleFontDataMac.mm +++ b/WebCore/platform/graphics/mac/SimpleFontDataMac.mm @@ -280,7 +280,7 @@ void SimpleFontData::platformInit() } } -static CFDataRef copyFontTableForTag(FontPlatformData platformData, FourCharCode tableName) +static CFDataRef copyFontTableForTag(FontPlatformData& platformData, FourCharCode tableName) { #ifdef BUILDING_ON_TIGER ATSFontRef atsFont = FMGetATSFontRefFromFont(platformData.m_atsuFontID); diff --git a/WebCore/platform/graphics/qt/FloatRectQt.cpp b/WebCore/platform/graphics/qt/FloatRectQt.cpp index 1c918e3..063876b 100644 --- a/WebCore/platform/graphics/qt/FloatRectQt.cpp +++ b/WebCore/platform/graphics/qt/FloatRectQt.cpp @@ -44,6 +44,21 @@ FloatRect::operator QRectF() const return QRectF(x(), y(), width(), height()); } +FloatRect FloatRect::normalized() const +{ + FloatRect normalizedRect = *this; + + if (width() < 0) { + normalizedRect.setX(x() + width()); + normalizedRect.setWidth(-width()); + } + if (height() < 0) { + normalizedRect.setY(y() + height()); + normalizedRect.setHeight(-height()); + } + return normalizedRect; +} + } // vim: ts=4 sw=4 et diff --git a/WebCore/platform/graphics/qt/FontQt.cpp b/WebCore/platform/graphics/qt/FontQt.cpp index 0c1d271..59320cb 100644 --- a/WebCore/platform/graphics/qt/FontQt.cpp +++ b/WebCore/platform/graphics/qt/FontQt.cpp @@ -234,7 +234,7 @@ float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFon return 0; if (run.length() == 1 && treatAsSpace(run[0])) - return QFontMetrics(font()).width(run[0]) + run.padding(); + return QFontMetrics(font()).width(space) + run.padding(); String sanitized = Font::normalizeSpaces(String(run.characters(), run.length())); QString string = fromRawDataWithoutRef(sanitized); diff --git a/WebCore/platform/graphics/qt/GradientQt.cpp b/WebCore/platform/graphics/qt/GradientQt.cpp index 8b9e2d7..1f05a15 100644 --- a/WebCore/platform/graphics/qt/GradientQt.cpp +++ b/WebCore/platform/graphics/qt/GradientQt.cpp @@ -51,6 +51,8 @@ QGradient* Gradient::platformGradient() else m_gradient = new QLinearGradient(m_p0.x(), m_p0.y(), m_p1.x(), m_p1.y()); + m_gradient->setInterpolationMode(QGradient::ComponentInterpolation); + sortStopsIfNecessary(); QColor stopColor; @@ -65,7 +67,7 @@ QGradient* Gradient::platformGradient() lastStop = stopIterator->stop; if (m_radial && m_r0) lastStop = m_r0 / m_r1 + lastStop * (1.0f - m_r0 / m_r1); - m_gradient->setColorAt(lastStop, stopColor); + m_gradient->setColorAt(qMin(lastStop, qreal(1.0f)), stopColor); // Keep the lastStop as orginal value, since the following stopColor depend it lastStop = stopIterator->stop; ++stopIterator; diff --git a/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp b/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp index 1a51910..002765f 100644 --- a/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp +++ b/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp @@ -1637,7 +1637,7 @@ bool GraphicsContext3D::getImageData(Image* image, neededAlphaOp = kAlphaDoUnmultiply; QImage nativeImage = nativePixmap->toImage().convertToFormat(QImage::Format_ARGB32); outputVector.resize(nativeImage.byteCount()); - return packPixels(nativeImage.rgbSwapped().bits(), kSourceFormatRGBA8, image->width(), image->height(), + return packPixels(nativeImage.rgbSwapped().bits(), kSourceFormatRGBA8, image->width(), image->height(), 0, format, type, neededAlphaOp, outputVector.data()); } diff --git a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp index 13608b2..9d23340 100644 --- a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp +++ b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp @@ -528,6 +528,17 @@ void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points p->restore(); } +void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint* points) +{ + if (paintingDisabled()) + return; + + if (numPoints <= 1) + return; + + // FIXME: IMPLEMENT!! +} + QPen GraphicsContext::pen() { if (paintingDisabled()) @@ -1056,7 +1067,12 @@ void GraphicsContext::clip(const Path& path) void GraphicsContext::canvasClip(const Path& path) { - clip(path); + if (paintingDisabled()) + return; + + QPainterPath clipPath = path.platformPath(); + clipPath.setFillRule(Qt::WindingFill); + m_data->p()->setClipPath(clipPath, Qt::IntersectClip); } void GraphicsContext::clipOut(const Path& path) diff --git a/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp b/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp index 8ed0d89..226f1fb 100644 --- a/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp +++ b/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp @@ -41,6 +41,10 @@ #include <QtGui/qpixmapcache.h> #include <QtGui/qstyleoption.h> + +#define QT_DEBUG_RECACHE 0 +#define QT_DEBUG_CACHEDUMP 0 + namespace WebCore { #ifndef QT_NO_GRAPHICSEFFECT @@ -225,7 +229,10 @@ public: int m_changeMask; QSizeF m_size; - QPixmapCache::Key m_backingStoreKey; + struct { + QPixmapCache::Key key; + QSizeF size; + } m_backingStore; #ifndef QT_NO_ANIMATION QList<QWeakPointer<QAbstractAnimation> > m_animations; #endif @@ -283,7 +290,6 @@ inline GraphicsLayerQtImpl* toGraphicsLayerQtImpl(QGraphicsItem* item) inline GraphicsLayerQtImpl* toGraphicsLayerQtImpl(QGraphicsObject* item) { - ASSERT(item); return qobject_cast<GraphicsLayerQtImpl*>(item); } @@ -339,36 +345,109 @@ const GraphicsLayerQtImpl* GraphicsLayerQtImpl::rootLayer() const QPixmap GraphicsLayerQtImpl::recache(const QRegion& regionToUpdate) { - if (!m_layer->drawsContent() || m_size.isEmpty() ||!m_size.isValid()) + if (!m_layer->drawsContent() || m_size.isEmpty() || !m_size.isValid()) return QPixmap(); - QRegion region = regionToUpdate; QPixmap pixmap; + QRegion region = regionToUpdate; + if (QPixmapCache::find(m_backingStore.key, &pixmap)) { + if (region.isEmpty()) + return pixmap; + QPixmapCache::remove(m_backingStore.key); // Remove the reference to the pixmap in the cache to avoid a detach. + } - // We might be drawing into an existing cache. - if (!QPixmapCache::find(m_backingStoreKey, &pixmap)) - region = QRegion(QRect(0, 0, m_size.width(), m_size.height())); + { + bool erased = false; - if (m_size != pixmap.size()) { - pixmap = QPixmap(m_size.toSize()); - if (!m_layer->contentsOpaque()) - pixmap.fill(Qt::transparent); - m_pendingContent.regionToUpdate = QRegion(QRect(QPoint(0, 0), m_size.toSize())); - } + // If the pixmap is not in the cache or the view has grown since last cached. + if (pixmap.isNull() || m_size != m_backingStore.size) { +#if QT_DEBUG_RECACHE + if (pixmap.isNull()) + qDebug() << "CacheMiss" << this << m_size; +#endif + bool fill = true; + QRegion newRegion; + QPixmap oldPixmap = pixmap; + + // If the pixmap is two small to hold the view contents we enlarge, otherwise just use the old (large) pixmap. + if (pixmap.width() < m_size.width() || pixmap.height() < m_size.height()) { +#if QT_DEBUG_RECACHE + qDebug() << "CacheGrow" << this << m_size; +#endif + pixmap = QPixmap(m_size.toSize()); + pixmap.fill(Qt::transparent); + newRegion = QRegion(0, 0, m_size.width(), m_size.height()); + } + +#if 1 + // Blit the contents of oldPixmap back into the cached pixmap as we are just adding new pixels. + if (!oldPixmap.isNull()) { + const QRegion cleanRegion = (QRegion(0, 0, m_size.width(), m_size.height()) + & QRegion(0, 0, m_backingStore.size.width(), m_backingStore.size.height())) - regionToUpdate; + if (!cleanRegion.isEmpty()) { +#if QT_DEBUG_RECACHE + qDebug() << "CacheBlit" << this << cleanRegion; +#endif + const QRect cleanBounds(cleanRegion.boundingRect()); + QPainter painter(&pixmap); + painter.setCompositionMode(QPainter::CompositionMode_Source); + painter.drawPixmap(cleanBounds.topLeft(), oldPixmap, cleanBounds); + newRegion -= cleanRegion; + fill = false; // We cannot just fill the pixmap. + } + oldPixmap = QPixmap(); + } +#endif + region += newRegion; + if (fill && !region.isEmpty()) { // Clear the entire pixmap with the background. +#if QT_DEBUG_RECACHE + qDebug() << "CacheErase" << this << m_size << background; +#endif + erased = true; + pixmap.fill(Qt::transparent); + } + } + region &= QRegion(0, 0, m_size.width(), m_size.height()); + + // If we have something to draw its time to erase it and render the contents. + if (!region.isEmpty()) { +#if QT_DEBUG_CACHEDUMP + static int recacheCount = 0; + ++recacheCount; + qDebug() << "**** CACHEDUMP" << recacheCount << this << m_layer << region << m_size; + pixmap.save(QString().sprintf("/tmp/%05d_A.png", recacheCount), "PNG"); +#endif + + QPainter painter(&pixmap); + GraphicsContext gc(&painter); - QPainter painter(&pixmap); - GraphicsContext gc(&painter); + painter.setClipRegion(region); - // Clear the area in cache that we're drawing into - painter.setCompositionMode(QPainter::CompositionMode_Clear); - painter.fillRect(region.boundingRect(), Qt::transparent); + if (!erased) { // Erase the area in cache that we're drawing into. + painter.setCompositionMode(QPainter::CompositionMode_Clear); + painter.fillRect(region.boundingRect(), Qt::transparent); - // Render the actual contents into the cache - painter.setCompositionMode(QPainter::CompositionMode_SourceOver); - m_layer->paintGraphicsLayerContents(gc, region.boundingRect()); - painter.end(); +#if QT_DEBUG_CACHEDUMP + qDebug() << "**** CACHEDUMP" << recacheCount << this << m_layer << region << m_size; + pixmap.save(QString().sprintf("/tmp/%05d_B.png", recacheCount), "PNG"); +#endif + } - m_backingStoreKey = QPixmapCache::insert(pixmap); + // Render the actual contents into the cache. + painter.setCompositionMode(QPainter::CompositionMode_SourceOver); + m_layer->paintGraphicsLayerContents(gc, region.boundingRect()); + painter.end(); + +#if QT_DEBUG_CACHEDUMP + qDebug() << "**** CACHEDUMP" << recacheCount << this << m_layer << region << m_size; + pixmap.save(QString().sprintf("/tmp/%05d_C.png", recacheCount), "PNG"); +#endif + } + m_backingStore.size = m_size; // Store the used size of the pixmap. + } + + // Finally insert into the cache and allow a reference there. + m_backingStore.key = QPixmapCache::insert(pixmap); return pixmap; } @@ -487,8 +566,9 @@ void GraphicsLayerQtImpl::paint(QPainter* painter, const QStyleOptionGraphicsIte if (m_state.drawsContent) { QPixmap backingStore; // We might need to recache, in case we try to paint and the cache was purged (e.g. if it was full). - if (!QPixmapCache::find(m_backingStoreKey, &backingStore) || backingStore.size() != m_size.toSize()) + if (!QPixmapCache::find(m_backingStore.key, &backingStore) || backingStore.size() != m_size.toSize()) backingStore = recache(QRegion(m_state.contentsRect)); + const QRectF bounds(0, 0, m_backingStore.size.width(), m_backingStore.size.height()); painter->drawPixmap(0, 0, backingStore); } break; @@ -674,11 +754,13 @@ void GraphicsLayerQtImpl::flushChanges(bool recursive, bool forceUpdateTransform else #endif if (m_changeMask & DisplayChange) { +#ifndef QT_GRAPHICS_LAYER_NO_RECACHE_ON_DISPLAY_CHANGE // Recache now: all the content is ready and we don't want to wait until the paint event. // We only need to do this for HTML content, there's no point in caching directly composited // content like images or solid rectangles. if (m_pendingContent.contentType == HTMLContentType) recache(m_pendingContent.regionToUpdate); +#endif update(m_pendingContent.regionToUpdate.boundingRect()); m_pendingContent.regionToUpdate = QRegion(); } @@ -1441,10 +1523,7 @@ bool GraphicsLayerQt::addAnimation(const KeyframeValueList& values, const IntSiz if (anim->fillsBackwards()) newAnim->setCurrentTime(0); - if (anim->delay()) - QTimer::singleShot(anim->delay() * 1000, newAnim, SLOT(start())); - else - newAnim->start(); + newAnim->start(); // We synchronize the animation's clock to WebCore's timeOffset. newAnim->setCurrentTime(timeOffset * 1000); diff --git a/WebCore/platform/graphics/qt/ImageQt.cpp b/WebCore/platform/graphics/qt/ImageQt.cpp index af94f55..dd97873 100644 --- a/WebCore/platform/graphics/qt/ImageQt.cpp +++ b/WebCore/platform/graphics/qt/ImageQt.cpp @@ -64,6 +64,8 @@ static QPixmap loadResourcePixmap(const char *name) pixmap = QWebSettings::webGraphic(QWebSettings::TextAreaSizeGripCornerGraphic); else if (qstrcmp(name, "deleteButton") == 0) pixmap = QWebSettings::webGraphic(QWebSettings::DeleteButtonGraphic); + else if (!qstrcmp(name, "inputSpeech")) + pixmap = QWebSettings::webGraphic(QWebSettings::InputSpeechButtonGraphic); return pixmap; } @@ -164,6 +166,9 @@ void BitmapImage::invalidatePlatformData() void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst, const FloatRect& src, ColorSpace styleColorSpace, CompositeOperator op) { + FloatRect normalizedDst = dst.normalized(); + FloatRect normalizedSrc = src.normalized(); + startAnimation(); QPixmap* image = nativeImageForCurrentFrame(); @@ -171,7 +176,7 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst, return; if (mayFillWithSolidColor()) { - fillWithSolidColor(ctxt, dst, solidColor(), styleColorSpace, op); + fillWithSolidColor(ctxt, normalizedDst, solidColor(), styleColorSpace, op); return; } @@ -191,22 +196,22 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst, float shadowBlur; Color shadowColor; if (ctxt->getShadow(shadowSize, shadowBlur, shadowColor)) { - FloatRect shadowImageRect(dst); + FloatRect shadowImageRect(normalizedDst); shadowImageRect.move(shadowSize.width(), shadowSize.height()); - QImage shadowImage(QSize(static_cast<int>(src.width()), static_cast<int>(src.height())), QImage::Format_ARGB32_Premultiplied); + QImage shadowImage(QSize(static_cast<int>(normalizedSrc.width()), static_cast<int>(normalizedSrc.height())), QImage::Format_ARGB32_Premultiplied); QPainter p(&shadowImage); p.setCompositionMode(QPainter::CompositionMode_Source); p.fillRect(shadowImage.rect(), shadowColor); p.setCompositionMode(QPainter::CompositionMode_DestinationIn); - p.drawPixmap(dst, *image, src); + p.drawPixmap(normalizedDst, *image, normalizedSrc); p.end(); - painter->drawImage(shadowImageRect, shadowImage, src); + painter->drawImage(shadowImageRect, shadowImage, normalizedSrc); } // Test using example site at // http://www.meyerweb.com/eric/css/edge/complexspiral/demo.html - painter->drawPixmap(dst, *image, src); + painter->drawPixmap(normalizedDst, *image, normalizedSrc); painter->setCompositionMode(lastCompositionMode); diff --git a/WebCore/platform/graphics/qt/PathQt.cpp b/WebCore/platform/graphics/qt/PathQt.cpp index 8f1f912..a367212 100644 --- a/WebCore/platform/graphics/qt/PathQt.cpp +++ b/WebCore/platform/graphics/qt/PathQt.cpp @@ -69,8 +69,19 @@ Path& Path::operator=(const Path& other) return *this; } +static inline bool areCollinear(const QPointF& a, const QPointF& b, const QPointF& c) +{ + // Solved from comparing the slopes of a to b and b to c: (ay-by)/(ax-bx) == (cy-by)/(cx-bx) + return qFuzzyCompare((c.y() - b.y()) * (a.x() - b.x()), (a.y() - b.y()) * (c.x() - b.x())); +} + +static inline bool withinRange(qreal p, qreal a, qreal b) +{ + return (p >= a && p <= b) || (p >= b && p <= a); +} + // Check whether a point is on the border -bool isPointOnPathBorder(const QPolygonF& border, const QPointF& p) +static bool isPointOnPathBorder(const QPolygonF& border, const QPointF& p) { // null border doesn't contain points if (border.isEmpty()) @@ -81,15 +92,12 @@ bool isPointOnPathBorder(const QPolygonF& border, const QPointF& p) for (int i = 1; i < border.size(); ++i) { p2 = border.at(i); - // (x1<=x<=x2||x1=>x>=x2) && (y1<=y<=y2||y1=>y>=y2) && (y2-y1)(x-x1) == (y-y1)(x2-x1) - // In which, (y2-y1)(x-x1) == (y-y1)(x2-x1) is from (y2-y1)/(x2-x1) == (y-y1)/(x-x1) - // it want to check the slope between p1 and p2 is same with slope between p and p1, - // if so then the three points lie on the same line. - // In which, (x1<=x<=x2||x1=>x>=x2) && (y1<=y<=y2||y1=>y>=y2) want to make sure p is - // between p1 and p2, not outside. - if (((p.x() <= p1.x() && p.x() >= p2.x()) || (p.x() >= p1.x() && p.x() <= p2.x())) - && ((p.y() <= p1.y() && p.y() >= p2.y()) || (p.y() >= p1.y() && p.y() <= p2.y())) - && (p2.y() - p1.y()) * (p.x() - p1.x()) == (p.y() - p1.y()) * (p2.x() - p1.x())) { + if (areCollinear(p, p1, p2) + // Once we know that the points are collinear we + // only need to check one of the coordinates + && (qAbs(p2.x() - p1.x()) > qAbs(p2.y() - p1.y()) ? + withinRange(p.x(), p1.x(), p2.x()) : + withinRange(p.y(), p1.y(), p2.y()))) { return true; } p1 = p2; @@ -212,19 +220,14 @@ void Path::addArcTo(const FloatPoint& p1, const FloatPoint& p2, float radius) float p1p2_length = sqrtf(p1p2.x() * p1p2.x() + p1p2.y() * p1p2.y()); double cos_phi = (p1p0.x() * p1p2.x() + p1p0.y() * p1p2.y()) / (p1p0_length * p1p2_length); - // all points on a line logic - if (cos_phi == -1) { + + // The points p0, p1, and p2 are on the same straight line (HTML5, 4.8.11.1.8) + // We could have used areCollinear() here, but since we're reusing + // the variables computed above later on we keep this logic. + if (qFuzzyCompare(qAbs(cos_phi), 1.0)) { m_path.lineTo(p1); return; } - if (cos_phi == 1) { - // add infinite far away point - unsigned int max_length = 65535; - double factor_max = max_length / p1p0_length; - FloatPoint ep((p0.x() + factor_max * p1p0.x()), (p0.y() + factor_max * p1p0.y())); - m_path.lineTo(ep); - return; - } float tangent = radius / tan(acos(cos_phi) / 2); float factor_p1p0 = tangent / p1p0_length; diff --git a/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp b/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp index 62e2f17..ee0a874 100644 --- a/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp +++ b/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp @@ -63,7 +63,7 @@ bool GraphicsContext3D::getImageData(Image* image, if (!premultiplyAlpha) // FIXME: must fetch the image data before the premultiplication step neededAlphaOp = kAlphaDoUnmultiply; - return packPixels(pixels, kSourceFormatBGRA8, skiaImage->width(), height, + return packPixels(pixels, kSourceFormatBGRA8, skiaImage->width(), height, 0, format, type, neededAlphaOp, outputVector.data()); } diff --git a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp index 74d0c6e..793fe72 100644 --- a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp +++ b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp @@ -478,6 +478,17 @@ void GraphicsContext::drawConvexPolygon(size_t numPoints, } } +void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint* points) +{ + if (paintingDisabled()) + return; + + if (numPoints <= 1) + return; + + // FIXME: IMPLEMENT!! +} + // This method is only used to draw the little circles used in lists. void GraphicsContext::drawEllipse(const IntRect& elipseRect) { diff --git a/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp b/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp index 7387a14..94df6ae 100644 --- a/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp +++ b/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp @@ -84,6 +84,12 @@ GraphicsContext::GraphicsContext(HDC dc, bool hasAlpha) } } +static void setRGBABitmapAlpha(unsigned char* bytes, size_t length, unsigned char level) +{ + for (size_t i = 0; i < length; i += 4) + bytes[i + 3] = level; +} + void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect& dstRect, bool supportAlphaBlend, bool mayCreateBitmap) { if (!mayCreateBitmap || !hdc || !inTransparencyLayer()) { @@ -100,9 +106,16 @@ void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect& dstRect, boo GetObject(bitmap, sizeof(info), &info); ASSERT(info.bmBitsPixel == 32); + // If this context does not support alpha blending, then it may have + // been drawn with GDI functions which always set the alpha channel + // to zero. We need to manually set the bitmap to be fully opaque. + unsigned char* bytes = reinterpret_cast<unsigned char*>(info.bmBits); + if (!supportAlphaBlend) + setRGBABitmapAlpha(bytes, info.bmHeight * info.bmWidthBytes, 255); + // Need to make a cairo_surface_t out of the bitmap's pixel buffer and then draw // it into our context. - cairo_surface_t* image = cairo_image_surface_create_for_data((unsigned char*)info.bmBits, + cairo_surface_t* image = cairo_image_surface_create_for_data(bytes, CAIRO_FORMAT_ARGB32, info.bmWidth, info.bmHeight, @@ -111,9 +124,10 @@ void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect& dstRect, boo // Scale the target surface to the new image size, and flip it // so that when we set the srcImage as the surface it will draw // right-side-up. - cairo_translate(m_data->cr, 0, dstRect.height()); - cairo_scale(m_data->cr, dstRect.width(), -dstRect.height()); - cairo_set_source_surface (m_data->cr, image, dstRect.x(), dstRect.y()); + cairo_save(m_data->cr); + cairo_translate(m_data->cr, dstRect.x(), dstRect.height() + dstRect.y()); + cairo_scale(m_data->cr, 1.0, -1.0); + cairo_set_source_surface(m_data->cr, image, 0, 0); if (m_data->layers.size()) cairo_paint_with_alpha(m_data->cr, m_data->layers.last()); @@ -124,6 +138,7 @@ void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect& dstRect, boo cairo_surface_destroy(image); ::DeleteDC(hdc); ::DeleteObject(bitmap); + cairo_restore(m_data->cr); } void GraphicsContextPlatformPrivate::syncContext(PlatformGraphicsContext* cr) diff --git a/WebCore/platform/graphics/win/MediaPlayerPrivateFullscreenWindow.cpp b/WebCore/platform/graphics/win/MediaPlayerPrivateFullscreenWindow.cpp index 2ca1a96..e664f2a 100644 --- a/WebCore/platform/graphics/win/MediaPlayerPrivateFullscreenWindow.cpp +++ b/WebCore/platform/graphics/win/MediaPlayerPrivateFullscreenWindow.cpp @@ -28,9 +28,12 @@ #include "IntRect.h" #include "WebCoreInstanceHandle.h" -#include <CoreGraphics/CGColor.h> #include <windows.h> +#if PLATFORM(CG) +#include <CoreGraphics/CGColor.h> +#endif + namespace WebCore { MediaPlayerPrivateFullscreenWindow::MediaPlayerPrivateFullscreenWindow(MediaPlayerPrivateFullscreenClient* client) diff --git a/WebCore/platform/graphics/win/UniscribeController.cpp b/WebCore/platform/graphics/win/UniscribeController.cpp index afea10a..bceec2d 100644 --- a/WebCore/platform/graphics/win/UniscribeController.cpp +++ b/WebCore/platform/graphics/win/UniscribeController.cpp @@ -287,9 +287,16 @@ bool UniscribeController::shapeAndPlaceItem(const UChar* cp, unsigned i, const S roundingHackCharacters[clusters[k]] = m_currentCharacter + k + item.iCharPos; int boundary = k + m_currentCharacter + item.iCharPos; - if (boundary < m_run.length() && - Font::isRoundingHackCharacter(*(str + k + 1))) - roundingHackWordBoundaries[clusters[k]] = boundary; + if (boundary < m_run.length()) { + // When at the last character in the str, don't look one past the end for a rounding hack character. + // Instead look ahead to the first character of next item, if there is a next one. + if (k + 1 == len) { + if (i + 2 < m_items.size() // Check for at least 2 items remaining. The last item is a terminating item containing no characters. + && Font::isRoundingHackCharacter(*(cp + m_items[i + 1].iCharPos))) + roundingHackWordBoundaries[clusters[k]] = boundary; + } else if (Font::isRoundingHackCharacter(*(str + k + 1))) + roundingHackWordBoundaries[clusters[k]] = boundary; + } } // Populate our glyph buffer with this information. diff --git a/WebCore/platform/graphics/wince/GraphicsContextWince.cpp b/WebCore/platform/graphics/wince/GraphicsContextWince.cpp index c2c29c7..7bc6a27 100644 --- a/WebCore/platform/graphics/wince/GraphicsContextWince.cpp +++ b/WebCore/platform/graphics/wince/GraphicsContextWince.cpp @@ -948,6 +948,17 @@ void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points } } +void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint* points) +{ + if (paintingDisabled()) + return; + + if (numPoints <= 1) + return; + + // FIXME: IMPLEMENT!! +} + void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorSpace colorSpace) { if (paintingDisabled() || !m_data->m_opacity) diff --git a/WebCore/platform/graphics/wx/GraphicsContextWx.cpp b/WebCore/platform/graphics/wx/GraphicsContextWx.cpp index 0b6c81b..5968ef3 100644 --- a/WebCore/platform/graphics/wx/GraphicsContextWx.cpp +++ b/WebCore/platform/graphics/wx/GraphicsContextWx.cpp @@ -256,6 +256,17 @@ void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points delete [] polygon; } +void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint* points) +{ + if (paintingDisabled()) + return; + + if (numPoints <= 1) + return; + + // FIXME: IMPLEMENT!! +} + void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorSpace colorSpace) { if (paintingDisabled()) diff --git a/WebCore/platform/gtk/DragDataGtk.cpp b/WebCore/platform/gtk/DragDataGtk.cpp index 4ed3bc1..68f7ffc 100644 --- a/WebCore/platform/gtk/DragDataGtk.cpp +++ b/WebCore/platform/gtk/DragDataGtk.cpp @@ -18,8 +18,10 @@ #include "DragData.h" #include "Clipboard.h" +#include "ClipboardGtk.h" #include "Document.h" #include "DocumentFragment.h" +#include "markup.h" namespace WebCore { @@ -35,21 +37,24 @@ bool DragData::containsColor() const bool DragData::containsFiles() const { - return false; + return !m_platformDragData->files().isEmpty(); } void DragData::asFilenames(Vector<String>& result) const { + Vector<String> files(m_platformDragData->files()); + for (size_t i = 0; i < files.size(); i++) + result.append(files[i]); } bool DragData::containsPlainText() const { - return false; + return m_platformDragData->hasText(); } String DragData::asPlainText() const { - return String(); + return m_platformDragData->text(); } Color DragData::asColor() const @@ -57,30 +62,36 @@ Color DragData::asColor() const return Color(); } -PassRefPtr<Clipboard> DragData::createClipboard(ClipboardAccessPolicy) const +PassRefPtr<Clipboard> DragData::createClipboard(ClipboardAccessPolicy policy) const { - return 0; + return ClipboardGtk::create(policy, m_platformDragData, true); } bool DragData::containsCompatibleContent() const { - return false; + return containsPlainText() || containsURL() || m_platformDragData->hasMarkup() || containsColor() || containsFiles(); } bool DragData::containsURL(FilenameConversionPolicy filenamePolicy) const { - return false; + return m_platformDragData->hasURL(); } String DragData::asURL(FilenameConversionPolicy filenamePolicy, String* title) const { - return String(); + String url(m_platformDragData->url()); + if (title) + *title = m_platformDragData->urlLabel(); + return url; } -PassRefPtr<DocumentFragment> DragData::asFragment(Document*) const +PassRefPtr<DocumentFragment> DragData::asFragment(Document* document) const { - return 0; + if (!m_platformDragData->hasMarkup()) + return 0; + + return createFragmentFromMarkup(document, m_platformDragData->markup(), ""); } } diff --git a/WebCore/platform/gtk/GtkPluginWidget.cpp b/WebCore/platform/gtk/GtkPluginWidget.cpp index 94382f1..331f60f 100644 --- a/WebCore/platform/gtk/GtkPluginWidget.cpp +++ b/WebCore/platform/gtk/GtkPluginWidget.cpp @@ -87,7 +87,11 @@ void GtkPluginWidget::paint(GraphicsContext* context, const IntRect& rect) event->expose.area.x = loc.x(); event->expose.area.y = loc.y(); +#ifdef GTK_API_VERSION_2 event->expose.region = gdk_region_rectangle(&event->expose.area); +#else + event->expose.region = cairo_region_create_rectangle(&event->expose.area); +#endif /* * This will be unref'ed by gdk_event_free. @@ -97,7 +101,11 @@ void GtkPluginWidget::paint(GraphicsContext* context, const IntRect& rect) /* * If we are going to paint do the translation and GtkAllocation manipulation. */ +#ifdef GTK_API_VERSION_2 if (!gdk_region_empty(event->expose.region)) +#else + if (!cairo_region_is_empty(event->expose.region)) +#endif gtk_widget_send_expose(widget, event); gdk_event_free(event); diff --git a/WebCore/platform/gtk/GtkVersioning.h b/WebCore/platform/gtk/GtkVersioning.h index 3ee6763..885d69f 100644 --- a/WebCore/platform/gtk/GtkVersioning.h +++ b/WebCore/platform/gtk/GtkVersioning.h @@ -31,6 +31,7 @@ #if !GTK_CHECK_VERSION(2, 20, 0) #define gtk_widget_set_realized(widget, TRUE) GTK_WIDGET_SET_FLAGS((widget), GTK_REALIZED) +#define gtk_range_get_min_slider_size(range) (range)->min_slider_size #endif // GTK_CHECK_VERSION(2, 20, 0) #if !GTK_CHECK_VERSION(2, 19, 0) @@ -51,8 +52,10 @@ #define gtk_widget_get_window(widget) (widget)->window #define gtk_adjustment_get_value(adj) (adj)->value #define gtk_dialog_get_content_area(dialog) (dialog)->vbox +#define gtk_dialog_get_action_area(dialog) (dialog)->action_area #define gtk_selection_data_get_length(data) (data)->length #define gtk_selection_data_get_data(data) (data)->data +#define gtk_adjustment_set_page_size(adj, value) (adj)->page_size = value #endif // GTK_CHECK_VERSION(2, 14, 0) #endif // GtkVersioning_h diff --git a/WebCore/platform/gtk/PasteboardHelper.cpp b/WebCore/platform/gtk/PasteboardHelper.cpp index 141488f..98cbe42 100644 --- a/WebCore/platform/gtk/PasteboardHelper.cpp +++ b/WebCore/platform/gtk/PasteboardHelper.cpp @@ -114,13 +114,12 @@ void PasteboardHelper::getClipboardContents(GtkClipboard* clipboard) } if (gtk_clipboard_wait_is_target_available(clipboard, gdkMarkupAtom)) { - if (GtkSelectionData* data = gtk_clipboard_wait_for_contents(clipboard, gdkMarkupAtom)) { - RefPtr<TextResourceDecoder> decoder(TextResourceDecoder::create("text/plain", "UTF-8", true)); - String markup(decoder->decode(reinterpret_cast<const char*>(gtk_selection_data_get_data(data)), gtk_selection_data_get_length(data))); - markup += decoder->flush(); - dataObject->setMarkup(markup); - gtk_selection_data_free(data); - } + if (GtkSelectionData* data = gtk_clipboard_wait_for_contents(clipboard, gdkMarkupAtom)) { + // g_strndup guards against selection data that is not null-terminated. + GOwnPtr<gchar> markupString(g_strndup(reinterpret_cast<const char*>(gtk_selection_data_get_data(data)), gtk_selection_data_get_length(data))); + dataObject->setMarkup(String::fromUTF8(markupString.get())); + gtk_selection_data_free(data); + } } if (gtk_clipboard_wait_is_target_available(clipboard, uriListAtom)) { @@ -143,7 +142,7 @@ void PasteboardHelper::fillSelectionData(GtkSelectionData* selectionData, guint else if (info == getIdForTargetType(TargetTypeMarkup)) { GOwnPtr<gchar> markup(g_strdup(dataObject->markup().utf8().data())); gtk_selection_data_set(selectionData, gdkMarkupAtom, 8, - reinterpret_cast<const guchar*>(markup.get()), strlen(markup.get())); + reinterpret_cast<const guchar*>(markup.get()), strlen(markup.get()) + 1); } else if (info == getIdForTargetType(TargetTypeURIList)) { Vector<KURL> uriList(dataObject->uriList()); @@ -166,7 +165,7 @@ void PasteboardHelper::fillSelectionData(GtkSelectionData* selectionData, guint GOwnPtr<gchar> resultData(g_strdup(result.utf8().data())); gtk_selection_data_set(selectionData, netscapeURLAtom, 8, - reinterpret_cast<const guchar*>(resultData.get()), strlen(resultData.get())); + reinterpret_cast<const guchar*>(resultData.get()), strlen(resultData.get()) + 1); } else if (info == getIdForTargetType(TargetTypeImage)) gtk_selection_data_set_pixbuf(selectionData, dataObject->image()); diff --git a/WebCore/platform/gtk/RenderThemeGtk.cpp b/WebCore/platform/gtk/RenderThemeGtk.cpp index 75fb946..b70773e 100644 --- a/WebCore/platform/gtk/RenderThemeGtk.cpp +++ b/WebCore/platform/gtk/RenderThemeGtk.cpp @@ -29,6 +29,7 @@ #include "GOwnPtr.h" #include "Gradient.h" #include "GraphicsContext.h" +#include "GtkVersioning.h" #include "HTMLMediaElement.h" #include "HTMLNames.h" #include "MediaControlElements.h" @@ -37,10 +38,13 @@ #include "RenderObject.h" #include "UserAgentStyleSheets.h" #include "gtkdrawing.h" -#include <wtf/text/CString.h> - #include <gdk/gdk.h> #include <gtk/gtk.h> +#include <wtf/text/CString.h> + +#if ENABLE(PROGRESS_TAG) +#include "RenderProgress.h" +#endif namespace WebCore { @@ -297,7 +301,7 @@ static void setMozillaState(const RenderTheme* theme, GtkThemeWidgetType type, R state->depressed = false; } -static bool paintMozillaGtkWidget(const RenderThemeGtk* theme, GtkThemeWidgetType type, RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect) +static bool paintMozillaGtkWidget(const RenderThemeGtk* theme, GtkThemeWidgetType type, RenderObject* o, const PaintInfo& i, const IntRect& rect) { // Painting is disabled so just claim to have succeeded if (i.context->paintingDisabled()) @@ -338,7 +342,7 @@ static bool paintMozillaGtkWidget(const RenderThemeGtk* theme, GtkThemeWidgetTyp // In some situations, like during print previews, this GraphicsContext is not // backed by a GdkDrawable. In those situations, we render onto a pixmap and then // copy the rendered data back to the GraphicsContext via Cairo. - drawable = adoptGRef(gdk_pixmap_new(0, rect.width(), rect.height(), gdk_visual_get_system()->depth)); + drawable = adoptGRef(gdk_pixmap_new(0, rect.width(), rect.height(), gdk_visual_get_depth(gdk_visual_get_system()))); paintRect = clipRect = IntRect(0, 0, rect.width(), rect.height()); } @@ -405,7 +409,7 @@ void RenderThemeGtk::setCheckboxSize(RenderStyle* style) const setToggleSize(this, style, RadioPart); } -bool RenderThemeGtk::paintCheckbox(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect) +bool RenderThemeGtk::paintCheckbox(RenderObject* o, const PaintInfo& i, const IntRect& rect) { return paintMozillaGtkWidget(this, MOZ_GTK_CHECKBUTTON, o, i, rect); } @@ -415,7 +419,7 @@ void RenderThemeGtk::setRadioSize(RenderStyle* style) const setToggleSize(this, style, RadioPart); } -bool RenderThemeGtk::paintRadio(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect) +bool RenderThemeGtk::paintRadio(RenderObject* o, const PaintInfo& i, const IntRect& rect) { return paintMozillaGtkWidget(this, MOZ_GTK_RADIOBUTTON, o, i, rect); } @@ -436,7 +440,7 @@ void RenderThemeGtk::adjustButtonStyle(CSSStyleSelector* selector, RenderStyle* } } -bool RenderThemeGtk::paintButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect) +bool RenderThemeGtk::paintButton(RenderObject* o, const PaintInfo& i, const IntRect& rect) { return paintMozillaGtkWidget(this, MOZ_GTK_BUTTON, o, i, rect); } @@ -450,7 +454,7 @@ void RenderThemeGtk::adjustMenuListStyle(CSSStyleSelector* selector, RenderStyle adjustMozillaStyle(this, style, MOZ_GTK_DROPDOWN); } -bool RenderThemeGtk::paintMenuList(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect) +bool RenderThemeGtk::paintMenuList(RenderObject* o, const PaintInfo& i, const IntRect& rect) { return paintMozillaGtkWidget(this, MOZ_GTK_DROPDOWN, o, i, rect); } @@ -464,12 +468,12 @@ void RenderThemeGtk::adjustTextFieldStyle(CSSStyleSelector* selector, RenderStyl adjustMozillaStyle(this, style, MOZ_GTK_ENTRY); } -bool RenderThemeGtk::paintTextField(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect) +bool RenderThemeGtk::paintTextField(RenderObject* o, const PaintInfo& i, const IntRect& rect) { return paintMozillaGtkWidget(this, MOZ_GTK_ENTRY, o, i, rect); } -bool RenderThemeGtk::paintTextArea(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) +bool RenderThemeGtk::paintTextArea(RenderObject* o, const PaintInfo& i, const IntRect& r) { return paintTextField(o, i, r); } @@ -479,7 +483,7 @@ void RenderThemeGtk::adjustSearchFieldResultsButtonStyle(CSSStyleSelector* selec adjustSearchFieldCancelButtonStyle(selector, style, e); } -bool RenderThemeGtk::paintSearchFieldResultsButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect) +bool RenderThemeGtk::paintSearchFieldResultsButton(RenderObject* o, const PaintInfo& i, const IntRect& rect) { return paintMozillaGtkWidget(this, MOZ_GTK_DROPDOWN_ARROW, o, i, rect); } @@ -495,7 +499,7 @@ void RenderThemeGtk::adjustSearchFieldResultsDecorationStyle(CSSStyleSelector* s style->setHeight(Length(size.height(), Fixed)); } -bool RenderThemeGtk::paintSearchFieldResultsDecoration(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect) +bool RenderThemeGtk::paintSearchFieldResultsDecoration(RenderObject* o, const PaintInfo& i, const IntRect& rect) { return paintMozillaGtkWidget(this, MOZ_GTK_CHECKMENUITEM, o, i, rect); } @@ -511,7 +515,7 @@ void RenderThemeGtk::adjustSearchFieldCancelButtonStyle(CSSStyleSelector* select style->setHeight(Length(size.height(), Fixed)); } -bool RenderThemeGtk::paintSearchFieldCancelButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect) +bool RenderThemeGtk::paintSearchFieldCancelButton(RenderObject* o, const PaintInfo& i, const IntRect& rect) { return paintMozillaGtkWidget(this, MOZ_GTK_CHECKMENUITEM, o, i, rect); } @@ -521,12 +525,12 @@ void RenderThemeGtk::adjustSearchFieldStyle(CSSStyleSelector* selector, RenderSt adjustTextFieldStyle(selector, style, e); } -bool RenderThemeGtk::paintSearchField(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect) +bool RenderThemeGtk::paintSearchField(RenderObject* o, const PaintInfo& i, const IntRect& rect) { return paintTextField(o, i, rect); } -bool RenderThemeGtk::paintSliderTrack(RenderObject* object, const RenderObject::PaintInfo& info, const IntRect& rect) +bool RenderThemeGtk::paintSliderTrack(RenderObject* object, const PaintInfo& info, const IntRect& rect) { ControlPart part = object->style()->appearance(); ASSERT(part == SliderHorizontalPart || part == SliderVerticalPart); @@ -543,7 +547,7 @@ void RenderThemeGtk::adjustSliderTrackStyle(CSSStyleSelector*, RenderStyle* styl style->setBoxShadow(0); } -bool RenderThemeGtk::paintSliderThumb(RenderObject* object, const RenderObject::PaintInfo& info, const IntRect& rect) +bool RenderThemeGtk::paintSliderThumb(RenderObject* object, const PaintInfo& info, const IntRect& rect) { ControlPart part = object->style()->appearance(); ASSERT(part == SliderThumbHorizontalPart || part == SliderThumbVerticalPart); @@ -580,49 +584,49 @@ void RenderThemeGtk::adjustSliderThumbSize(RenderObject* o) const Color RenderThemeGtk::platformActiveSelectionBackgroundColor() const { GtkWidget* widget = gtkEntry(); - return widget->style->base[GTK_STATE_SELECTED]; + return gtk_widget_get_style(widget)->base[GTK_STATE_SELECTED]; } Color RenderThemeGtk::platformInactiveSelectionBackgroundColor() const { GtkWidget* widget = gtkEntry(); - return widget->style->base[GTK_STATE_ACTIVE]; + return gtk_widget_get_style(widget)->base[GTK_STATE_ACTIVE]; } Color RenderThemeGtk::platformActiveSelectionForegroundColor() const { GtkWidget* widget = gtkEntry(); - return widget->style->text[GTK_STATE_SELECTED]; + return gtk_widget_get_style(widget)->text[GTK_STATE_SELECTED]; } Color RenderThemeGtk::platformInactiveSelectionForegroundColor() const { GtkWidget* widget = gtkEntry(); - return widget->style->text[GTK_STATE_ACTIVE]; + return gtk_widget_get_style(widget)->text[GTK_STATE_ACTIVE]; } Color RenderThemeGtk::activeListBoxSelectionBackgroundColor() const { GtkWidget* widget = gtkTreeView(); - return widget->style->base[GTK_STATE_SELECTED]; + return gtk_widget_get_style(widget)->base[GTK_STATE_SELECTED]; } Color RenderThemeGtk::inactiveListBoxSelectionBackgroundColor() const { GtkWidget* widget = gtkTreeView(); - return widget->style->base[GTK_STATE_ACTIVE]; + return gtk_widget_get_style(widget)->base[GTK_STATE_ACTIVE]; } Color RenderThemeGtk::activeListBoxSelectionForegroundColor() const { GtkWidget* widget = gtkTreeView(); - return widget->style->text[GTK_STATE_SELECTED]; + return gtk_widget_get_style(widget)->text[GTK_STATE_SELECTED]; } Color RenderThemeGtk::inactiveListBoxSelectionForegroundColor() const { GtkWidget* widget = gtkTreeView(); - return widget->style->text[GTK_STATE_ACTIVE]; + return gtk_widget_get_style(widget)->text[GTK_STATE_ACTIVE]; } double RenderThemeGtk::caretBlinkInterval() const @@ -650,9 +654,9 @@ Color RenderThemeGtk::systemColor(int cssValueId) const { switch (cssValueId) { case CSSValueButtontext: - return Color(gtkButton()->style->fg[GTK_STATE_NORMAL]); + return Color(gtk_widget_get_style(gtkButton())->fg[GTK_STATE_NORMAL]); case CSSValueCaptiontext: - return Color(gtkEntry()->style->fg[GTK_STATE_NORMAL]); + return Color(gtk_widget_get_style(gtkEntry())->fg[GTK_STATE_NORMAL]); default: return RenderTheme::systemColor(cssValueId); } @@ -742,12 +746,12 @@ static inline bool paintMediaButton(GraphicsContext* context, const IntRect& r, return false; } -bool RenderThemeGtk::paintMediaFullscreenButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeGtk::paintMediaFullscreenButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) { return paintMediaButton(paintInfo.context, r, m_fullscreenButton.get(), m_panelColor, m_mediaIconSize); } -bool RenderThemeGtk::paintMediaMuteButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeGtk::paintMediaMuteButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) { HTMLMediaElement* mediaElement = getMediaElementFromRenderObject(o); if (!mediaElement) @@ -756,7 +760,7 @@ bool RenderThemeGtk::paintMediaMuteButton(RenderObject* o, const RenderObject::P return paintMediaButton(paintInfo.context, r, mediaElement->muted() ? m_unmuteButton.get() : m_muteButton.get(), m_panelColor, m_mediaIconSize); } -bool RenderThemeGtk::paintMediaPlayButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeGtk::paintMediaPlayButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) { HTMLMediaElement* mediaElement = getMediaElementFromRenderObject(o); if (!mediaElement) @@ -765,17 +769,17 @@ bool RenderThemeGtk::paintMediaPlayButton(RenderObject* o, const RenderObject::P return paintMediaButton(paintInfo.context, r, mediaElement->canPlay() ? m_playButton.get() : m_pauseButton.get(), m_panelColor, m_mediaIconSize); } -bool RenderThemeGtk::paintMediaSeekBackButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeGtk::paintMediaSeekBackButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) { return paintMediaButton(paintInfo.context, r, m_seekBackButton.get(), m_panelColor, m_mediaIconSize); } -bool RenderThemeGtk::paintMediaSeekForwardButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeGtk::paintMediaSeekForwardButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) { return paintMediaButton(paintInfo.context, r, m_seekForwardButton.get(), m_panelColor, m_mediaIconSize); } -bool RenderThemeGtk::paintMediaSliderTrack(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeGtk::paintMediaSliderTrack(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) { GraphicsContext* context = paintInfo.context; @@ -820,7 +824,7 @@ bool RenderThemeGtk::paintMediaSliderTrack(RenderObject* o, const RenderObject:: return false; } -bool RenderThemeGtk::paintMediaSliderThumb(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeGtk::paintMediaSliderThumb(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) { // Make the thumb nicer with rounded corners. paintInfo.context->fillRoundedRect(r, IntSize(3, 3), IntSize(3, 3), IntSize(3, 3), IntSize(3, 3), m_sliderThumbColor, DeviceColorSpace); @@ -828,4 +832,52 @@ bool RenderThemeGtk::paintMediaSliderThumb(RenderObject* o, const RenderObject:: } #endif +#if ENABLE(PROGRESS_TAG) +double RenderThemeGtk::animationRepeatIntervalForProgressBar(RenderProgress*) const +{ + // FIXME: It doesn't look like there is a good way yet to support animated + // progress bars with the Mozilla theme drawing code. + return 0; +} + +double RenderThemeGtk::animationDurationForProgressBar(RenderProgress*) const +{ + // FIXME: It doesn't look like there is a good way yet to support animated + // progress bars with the Mozilla theme drawing code. + return 0; +} + +void RenderThemeGtk::adjustProgressBarStyle(CSSStyleSelector*, RenderStyle* style, Element*) const +{ + style->setBoxShadow(0); +} + +bool RenderThemeGtk::paintProgressBar(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect) +{ + if (!renderObject->isProgress()) + return true; + + GtkWidget* progressBarWidget = moz_gtk_get_progress_widget(); + if (!progressBarWidget) + return true; + + if (paintMozillaGtkWidget(this, MOZ_GTK_PROGRESSBAR, renderObject, paintInfo, rect)) + return true; + + IntRect chunkRect(rect); + RenderProgress* renderProgress = toRenderProgress(renderObject); + + GtkStyle* style = gtk_widget_get_style(progressBarWidget); + chunkRect.setHeight(chunkRect.height() - (2 * style->ythickness)); + chunkRect.setY(chunkRect.y() + style->ythickness); + chunkRect.setWidth((chunkRect.width() - (2 * style->xthickness)) * renderProgress->position()); + if (renderObject->style()->direction() == RTL) + chunkRect.setX(rect.x() + rect.width() - chunkRect.width() - style->xthickness); + else + chunkRect.setX(chunkRect.x() + style->xthickness); + + return paintMozillaGtkWidget(this, MOZ_GTK_PROGRESS_CHUNK, renderObject, paintInfo, chunkRect); +} +#endif + } diff --git a/WebCore/platform/gtk/RenderThemeGtk.h b/WebCore/platform/gtk/RenderThemeGtk.h index 41b518e..71338d4 100644 --- a/WebCore/platform/gtk/RenderThemeGtk.h +++ b/WebCore/platform/gtk/RenderThemeGtk.h @@ -34,7 +34,12 @@ typedef struct _GtkWidget GtkWidget; typedef struct _GtkStyle GtkStyle; typedef struct _GtkContainer GtkContainer; +#ifdef GTK_API_VERSION_2 typedef struct _GdkRectangle GdkRectangle; +#else +typedef struct _cairo_rectangle_int cairo_rectangle_int_t; +typedef cairo_rectangle_int_t GdkRectangle; +#endif typedef struct _GdkDrawable GdkDrawable; typedef struct _GtkBorder GtkBorder; typedef struct _GtkThemeParts GtkThemeParts; @@ -93,52 +98,59 @@ public: GtkThemeParts* partsForDrawable(GdkDrawable*) const; protected: - virtual bool paintCheckbox(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r); + virtual bool paintCheckbox(RenderObject* o, const PaintInfo& i, const IntRect& r); virtual void setCheckboxSize(RenderStyle* style) const; - virtual bool paintRadio(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r); + virtual bool paintRadio(RenderObject* o, const PaintInfo& i, const IntRect& r); virtual void setRadioSize(RenderStyle* style) const; virtual void adjustButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintButton(RenderObject*, const PaintInfo&, const IntRect&); virtual void adjustTextFieldStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintTextField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintTextField(RenderObject*, const PaintInfo&, const IntRect&); - virtual bool paintTextArea(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintTextArea(RenderObject*, const PaintInfo&, const IntRect&); virtual void adjustMenuListStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintMenuList(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintMenuList(RenderObject*, const PaintInfo&, const IntRect&); virtual void adjustSearchFieldResultsDecorationStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintSearchFieldResultsDecoration(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintSearchFieldResultsDecoration(RenderObject*, const PaintInfo&, const IntRect&); virtual void adjustSearchFieldStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintSearchField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintSearchField(RenderObject*, const PaintInfo&, const IntRect&); virtual void adjustSearchFieldResultsButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintSearchFieldResultsButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintSearchFieldResultsButton(RenderObject*, const PaintInfo&, const IntRect&); virtual void adjustSearchFieldCancelButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintSearchFieldCancelButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintSearchFieldCancelButton(RenderObject*, const PaintInfo&, const IntRect&); - virtual bool paintSliderTrack(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintSliderTrack(RenderObject*, const PaintInfo&, const IntRect&); virtual void adjustSliderTrackStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintSliderThumb(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintSliderThumb(RenderObject*, const PaintInfo&, const IntRect&); virtual void adjustSliderThumbStyle(CSSStyleSelector*, RenderStyle*, Element*) const; virtual void adjustSliderThumbSize(RenderObject* object) const; #if ENABLE(VIDEO) virtual void initMediaStyling(GtkStyle* style, bool force); - virtual bool paintMediaFullscreenButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual bool paintMediaPlayButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual bool paintMediaMuteButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual bool paintMediaSeekBackButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual bool paintMediaSeekForwardButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual bool paintMediaSliderTrack(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual bool paintMediaSliderThumb(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintMediaFullscreenButton(RenderObject*, const PaintInfo&, const IntRect&); + virtual bool paintMediaPlayButton(RenderObject*, const PaintInfo&, const IntRect&); + virtual bool paintMediaMuteButton(RenderObject*, const PaintInfo&, const IntRect&); + virtual bool paintMediaSeekBackButton(RenderObject*, const PaintInfo&, const IntRect&); + virtual bool paintMediaSeekForwardButton(RenderObject*, const PaintInfo&, const IntRect&); + virtual bool paintMediaSliderTrack(RenderObject*, const PaintInfo&, const IntRect&); + virtual bool paintMediaSliderThumb(RenderObject*, const PaintInfo&, const IntRect&); +#endif + +#if ENABLE(PROGRESS_TAG) + virtual double animationRepeatIntervalForProgressBar(RenderProgress*) const; + virtual double animationDurationForProgressBar(RenderProgress*) const; + virtual void adjustProgressBarStyle(CSSStyleSelector*, RenderStyle*, Element*) const; + virtual bool paintProgressBar(RenderObject*, const PaintInfo&, const IntRect&); #endif private: diff --git a/WebCore/platform/gtk/ScrollViewGtk.cpp b/WebCore/platform/gtk/ScrollViewGtk.cpp index 5c258ad..3edc7b0 100644 --- a/WebCore/platform/gtk/ScrollViewGtk.cpp +++ b/WebCore/platform/gtk/ScrollViewGtk.cpp @@ -169,9 +169,9 @@ void ScrollView::platformRemoveChild(Widget* child) if (hostWindow()) parent = GTK_WIDGET(hostWindow()->platformPageClient()); else - parent = GTK_WIDGET(child->platformWidget()->parent); + parent = GTK_WIDGET(gtk_widget_get_parent(child->platformWidget())); - if (GTK_IS_CONTAINER(parent) && parent == child->platformWidget()->parent) + if (GTK_IS_CONTAINER(parent) && parent == gtk_widget_get_parent(child->platformWidget())) gtk_container_remove(GTK_CONTAINER(parent), child->platformWidget()); } @@ -191,9 +191,14 @@ IntRect ScrollView::visibleContentRect(bool includeScrollbars) const if (parent && includeScrollbars) measuredWidget = parent; + GtkAllocation allocation; +#if GTK_CHECK_VERSION(2, 18, 0) + gtk_widget_get_allocation(measuredWidget, &allocation); +#else + allocation = measuredWidget->allocation; +#endif return IntRect(IntPoint(m_scrollOffset.width(), m_scrollOffset.height()), - IntSize(measuredWidget->allocation.width, - measuredWidget->allocation.height)); + IntSize(allocation.width, allocation.height)); } void ScrollView::setScrollbarModes(ScrollbarMode horizontalMode, ScrollbarMode verticalMode, bool, bool) diff --git a/WebCore/platform/gtk/ScrollbarGtk.cpp b/WebCore/platform/gtk/ScrollbarGtk.cpp index 5dc4dd6..8081fb8 100644 --- a/WebCore/platform/gtk/ScrollbarGtk.cpp +++ b/WebCore/platform/gtk/ScrollbarGtk.cpp @@ -238,7 +238,11 @@ void ScrollbarGtk::paint(GraphicsContext* context, const IntRect& rect) event->expose.area.x = loc.x(); event->expose.area.y = loc.y(); +#ifdef GTK_API_VERSION_2 event->expose.region = gdk_region_rectangle(&event->expose.area); +#else + event->expose.region = cairo_region_create_rectangle(&event->expose.area); +#endif /* * This will be unref'ed by gdk_event_free. @@ -248,7 +252,11 @@ void ScrollbarGtk::paint(GraphicsContext* context, const IntRect& rect) /* * If we are going to paint do the translation and GtkAllocation manipulation. */ +#ifdef GTK_API_VERSION_2 if (!gdk_region_empty(event->expose.region)) +#else + if (!cairo_region_is_empty(event->expose.region)) +#endif gtk_widget_send_expose(widget, event); gdk_event_free(event); diff --git a/WebCore/platform/gtk/gtk2drawing.c b/WebCore/platform/gtk/gtk2drawing.c index 6a8af57..80e2c2a 100644 --- a/WebCore/platform/gtk/gtk2drawing.c +++ b/WebCore/platform/gtk/gtk2drawing.c @@ -48,6 +48,7 @@ #include "gtkdrawing.h" #include "Assertions.h" +#include "GtkVersioning.h" #include <math.h> #include <string.h> @@ -150,7 +151,7 @@ ensure_toggle_button_widget() gParts->toggleButtonWidget = gtk_toggle_button_new(); setup_widget_prototype(gParts->toggleButtonWidget); /* toggle button must be set active to get the right style on hover. */ - GTK_TOGGLE_BUTTON(gParts->toggleButtonWidget)->active = TRUE; + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gParts->toggleButtonWidget), TRUE); } return MOZ_GTK_SUCCESS; } @@ -297,7 +298,7 @@ ensure_combo_box_widgets() if (gParts->comboBoxButtonWidget) { /* Get the widgets inside the Button */ - buttonChild = GTK_BIN(gParts->comboBoxButtonWidget)->child; + buttonChild = gtk_bin_get_child(GTK_BIN(gParts->comboBoxButtonWidget)); if (GTK_IS_HBOX(buttonChild)) { /* appears-as-list = FALSE, cell-view = TRUE; the button * contains an hbox. This hbox is there because the ComboBox @@ -407,7 +408,7 @@ ensure_combo_box_entry_widgets() if (gParts->comboBoxEntryButtonWidget) { /* Get the Arrow inside the Button */ - buttonChild = GTK_BIN(gParts->comboBoxEntryButtonWidget)->child; + buttonChild = gtk_bin_get_child(GTK_BIN(gParts->comboBoxEntryButtonWidget)); if (GTK_IS_HBOX(buttonChild)) { /* appears-as-list = FALSE, cell-view = TRUE; the button * contains an hbox. This hbox is there because ComboBoxEntry @@ -682,9 +683,14 @@ ensure_tree_header_cell_widget() gtk_tree_view_column_set_title(lastTreeViewColumn, "M"); gtk_tree_view_append_column(GTK_TREE_VIEW(gParts->treeViewWidget), lastTreeViewColumn); +#ifdef GTK_API_VERSION_2 /* Use the middle column's header for our button */ gParts->treeHeaderCellWidget = gParts->middleTreeViewColumn->button; gParts->treeHeaderSortArrowWidget = gParts->middleTreeViewColumn->arrow; +#else + gParts->treeHeaderCellWidget = gtk_button_new(); + gParts->treeHeaderSortArrowWidget = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_NONE); +#endif g_object_set_data(G_OBJECT(gParts->treeHeaderCellWidget), "transparent-bg-hint", GINT_TO_POINTER(TRUE)); g_object_set_data(G_OBJECT(gParts->treeHeaderSortArrowWidget), @@ -758,7 +764,7 @@ moz_gtk_button_paint(GdkDrawable* drawable, GdkRectangle* rect, GtkTextDirection direction) { GtkShadowType shadow_type; - GtkStyle* style = widget->style; + GtkStyle* style = gtk_widget_get_style(widget); GtkStateType button_state = ConvertGtkState(state); gint x = rect->x, y=rect->y, width=rect->width, height=rect->height; @@ -776,15 +782,19 @@ moz_gtk_button_paint(GdkDrawable* drawable, GdkRectangle* rect, gtk_widget_set_state(widget, button_state); gtk_widget_set_direction(widget, direction); +#ifdef GTK_API_VERSION_2 if (state->isDefault) GTK_WIDGET_SET_FLAGS(widget, GTK_HAS_DEFAULT); +#endif - GTK_BUTTON(widget)->relief = relief; + gtk_button_set_relief(GTK_BUTTON(widget), relief); /* Some theme engines love to cause us pain in that gtk_paint_focus is a no-op on buttons and button-like widgets. They only listen to this flag. */ +#ifdef GTK_API_VERSION_2 if (state->focused && !state->disabled) GTK_WIDGET_SET_FLAGS(widget, GTK_HAS_FOCUS); +#endif if (!interior_focus && state->focused) { x += focus_width + focus_pad; @@ -814,10 +824,11 @@ moz_gtk_button_paint(GdkDrawable* drawable, GdkRectangle* rect, if (state->focused) { if (interior_focus) { - x += widget->style->xthickness + focus_pad; - y += widget->style->ythickness + focus_pad; - width -= 2 * (widget->style->xthickness + focus_pad); - height -= 2 * (widget->style->ythickness + focus_pad); + GtkStyle* style = gtk_widget_get_style(widget); + x += style->xthickness + focus_pad; + y += style->ythickness + focus_pad; + width -= 2 * (style->xthickness + focus_pad); + height -= 2 * (style->ythickness + focus_pad); } else { x -= focus_width + focus_pad; y -= focus_width + focus_pad; @@ -830,8 +841,10 @@ moz_gtk_button_paint(GdkDrawable* drawable, GdkRectangle* rect, widget, "button", x, y, width, height); } +#ifdef GTK_API_VERSION_2 GTK_WIDGET_UNSET_FLAGS(widget, GTK_HAS_DEFAULT); GTK_WIDGET_UNSET_FLAGS(widget, GTK_HAS_FOCUS); +#endif return MOZ_GTK_SUCCESS; } @@ -970,12 +983,12 @@ moz_gtk_toggle_paint(GdkDrawable* drawable, GdkRectangle* rect, focus_width = width + 2 * indicator_spacing; focus_height = height + 2 * indicator_spacing; - style = w->style; + style = gtk_widget_get_style(w); TSOffsetStyleGCs(style, x, y); gtk_widget_set_sensitive(w, !state->disabled); gtk_widget_set_direction(w, direction); - GTK_TOGGLE_BUTTON(w)->active = selected; + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), selected); if (isradio) { gtk_paint_option(style, drawable, state_type, shadow_type, cliprect, @@ -1022,7 +1035,7 @@ calculate_button_inner_rect(GtkWidget* button, GdkRectangle* rect, gint focus_width, focus_pad; GtkStyle* style; - style = button->style; + style = gtk_widget_get_style(button); /* This mirrors gtkbutton's child positioning */ moz_gtk_button_get_inner_border(button, &inner_border); @@ -1055,20 +1068,25 @@ calculate_arrow_rect(GtkWidget* arrow, GdkRectangle* rect, gfloat xalign, xpad; gint extent; GtkMisc* misc = GTK_MISC(arrow); + gfloat misc_xalign, misc_yalign; + gint misc_xpad, misc_ypad; if (have_arrow_scaling) gtk_widget_style_get(arrow, "arrow_scaling", &arrow_scaling, NULL); - extent = MIN((rect->width - misc->xpad * 2), - (rect->height - misc->ypad * 2)) * arrow_scaling; + gtk_misc_get_padding(misc, &misc_xpad, &misc_ypad); + gtk_misc_get_alignment(misc, &misc_xalign, &misc_yalign); - xalign = direction == GTK_TEXT_DIR_LTR ? misc->xalign : 1.0 - misc->xalign; - xpad = misc->xpad + (rect->width - extent) * xalign; + extent = MIN((rect->width - misc_xpad * 2), + (rect->height - misc_ypad * 2)) * arrow_scaling; + + xalign = direction == GTK_TEXT_DIR_LTR ? misc_xalign : 1.0 - misc_xalign; + xpad = misc_xpad + (rect->width - extent) * xalign; arrow_rect->x = direction == GTK_TEXT_DIR_LTR ? floor(rect->x + xpad) : ceil(rect->x + xpad); - arrow_rect->y = floor(rect->y + misc->ypad + - ((rect->height - extent) * misc->yalign)); + arrow_rect->y = floor(rect->y + misc_ypad + + ((rect->height - extent) * misc_yalign)); arrow_rect->width = arrow_rect->height = extent; @@ -1087,6 +1105,7 @@ moz_gtk_scrollbar_button_paint(GdkDrawable* drawable, GdkRectangle* rect, GdkRectangle arrow_rect; GtkStyle* style; GtkWidget *scrollbar; + GtkAllocation allocation; GtkArrowType arrow_type; gint arrow_displacement_x, arrow_displacement_y; const char* detail = (flags & MOZ_GTK_STEPPER_VERTICAL) ? @@ -1105,41 +1124,46 @@ moz_gtk_scrollbar_button_paint(GdkDrawable* drawable, GdkRectangle* rect, to determine where it should paint rounded corners on the buttons. We need to trick them into drawing the buttons the way we want them. */ - scrollbar->allocation.x = rect->x; - scrollbar->allocation.y = rect->y; - scrollbar->allocation.width = rect->width; - scrollbar->allocation.height = rect->height; +#if GTK_CHECK_VERSION(2, 18, 0) + gtk_widget_get_allocation(scrollbar, &allocation); +#else + allocation = scrollbar->allocation; +#endif + allocation.x = rect->x; + allocation.y = rect->y; + allocation.width = rect->width; + allocation.height = rect->height; if (flags & MOZ_GTK_STEPPER_VERTICAL) { - scrollbar->allocation.height *= 5; + allocation.height *= 5; if (flags & MOZ_GTK_STEPPER_DOWN) { arrow_type = GTK_ARROW_DOWN; if (flags & MOZ_GTK_STEPPER_BOTTOM) - scrollbar->allocation.y -= 4 * rect->height; + allocation.y -= 4 * rect->height; else - scrollbar->allocation.y -= rect->height; + allocation.y -= rect->height; } else { arrow_type = GTK_ARROW_UP; if (flags & MOZ_GTK_STEPPER_BOTTOM) - scrollbar->allocation.y -= 3 * rect->height; + allocation.y -= 3 * rect->height; } } else { - scrollbar->allocation.width *= 5; + allocation.width *= 5; if (flags & MOZ_GTK_STEPPER_DOWN) { arrow_type = GTK_ARROW_RIGHT; if (flags & MOZ_GTK_STEPPER_BOTTOM) - scrollbar->allocation.x -= 4 * rect->width; + allocation.x -= 4 * rect->width; else - scrollbar->allocation.x -= rect->width; + allocation.x -= rect->width; } else { arrow_type = GTK_ARROW_LEFT; if (flags & MOZ_GTK_STEPPER_BOTTOM) - scrollbar->allocation.x -= 3 * rect->width; + allocation.x -= 3 * rect->width; } } - style = scrollbar->style; + style = gtk_widget_get_style(scrollbar); TSOffsetStyleGCs(style, rect->x, rect->y); @@ -1187,7 +1211,7 @@ moz_gtk_scrollbar_trough_paint(GtkThemeWidgetType widget, gtk_widget_set_direction(GTK_WIDGET(scrollbar), direction); - style = GTK_WIDGET(scrollbar)->style; + style = gtk_widget_get_style(GTK_WIDGET(scrollbar)); TSOffsetStyleGCs(style, rect->x, rect->y); gtk_style_apply_default_background(style, drawable, TRUE, GTK_STATE_ACTIVE, @@ -1246,20 +1270,30 @@ moz_gtk_scrollbar_thumb_paint(GtkThemeWidgetType widget, if (widget == MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL) { cliprect->x -= 1; cliprect->width += 2; - adj->page_size = rect->width; + gtk_adjustment_set_page_size(adj, rect->width); } else { cliprect->y -= 1; cliprect->height += 2; - adj->page_size = rect->height; - } - + gtk_adjustment_set_page_size(adj, rect->height); + } + +#if GTK_CHECK_VERSION(2, 14, 0) + gtk_adjustment_configure(adj, + state->curpos, + 0, + state->maxpos, + gtk_adjustment_get_step_increment(adj), + gtk_adjustment_get_page_increment(adj), + gtk_adjustment_get_page_size(adj)); +#else adj->lower = 0; adj->value = state->curpos; adj->upper = state->maxpos; gtk_adjustment_changed(adj); +#endif - style = GTK_WIDGET(scrollbar)->style; + style = gtk_widget_get_style(GTK_WIDGET(scrollbar)); gtk_widget_style_get(GTK_WIDGET(scrollbar), "activate-slider", &activate_slider, NULL); @@ -1288,7 +1322,7 @@ moz_gtk_spin_paint(GdkDrawable* drawable, GdkRectangle* rect, ensure_spin_widget(); gtk_widget_set_direction(gParts->spinWidget, direction); - style = gParts->spinWidget->style; + style = gtk_widget_get_style(gParts->spinWidget); TSOffsetStyleGCs(style, rect->x, rect->y); gtk_paint_box(style, drawable, GTK_STATE_NORMAL, GTK_SHADOW_IN, NULL, @@ -1309,7 +1343,7 @@ moz_gtk_spin_updown_paint(GdkDrawable* drawable, GdkRectangle* rect, GtkStyle* style; ensure_spin_widget(); - style = gParts->spinWidget->style; + style = gtk_widget_get_style(gParts->spinWidget); gtk_widget_set_direction(gParts->spinWidget, direction); TSOffsetStyleGCs(style, rect->x, rect->y); @@ -1347,7 +1381,7 @@ moz_gtk_scale_paint(GdkDrawable* drawable, GdkRectangle* rect, widget = ((flags == GTK_ORIENTATION_HORIZONTAL) ? gParts->hScaleWidget : gParts->vScaleWidget); gtk_widget_set_direction(widget, direction); - style = widget->style; + style = gtk_widget_get_style(widget); if (flags == GTK_ORIENTATION_HORIZONTAL) { x = XTHICKNESS(style); @@ -1388,7 +1422,7 @@ moz_gtk_scale_thumb_paint(GdkDrawable* drawable, GdkRectangle* rect, widget = ((flags == GTK_ORIENTATION_HORIZONTAL) ? gParts->hScaleWidget : gParts->vScaleWidget); gtk_widget_set_direction(widget, direction); - style = widget->style; + style = gtk_widget_get_style(widget); /* determine the thumb size, and position the thumb in the center in the opposite axis */ if (flags == GTK_ORIENTATION_HORIZONTAL) { @@ -1422,8 +1456,8 @@ moz_gtk_gripper_paint(GdkDrawable* drawable, GdkRectangle* rect, ensure_handlebox_widget(); gtk_widget_set_direction(gParts->handleBoxWidget, direction); - style = gParts->handleBoxWidget->style; - shadow_type = GTK_HANDLE_BOX(gParts->handleBoxWidget)->shadow_type; + style = gtk_widget_get_style(gParts->handleBoxWidget); + shadow_type = gtk_handle_box_get_shadow_type(GTK_HANDLE_BOX(gParts->handleBoxWidget)); TSOffsetStyleGCs(style, rect->x, rect->y); gtk_paint_box(style, drawable, state_type, shadow_type, cliprect, @@ -1440,7 +1474,7 @@ moz_gtk_hpaned_paint(GdkDrawable* drawable, GdkRectangle* rect, GtkStateType hpaned_state = ConvertGtkState(state); ensure_hpaned_widget(); - gtk_paint_handle(gParts->hpanedWidget->style, drawable, hpaned_state, + gtk_paint_handle(gtk_widget_get_style(gParts->hpanedWidget), drawable, hpaned_state, GTK_SHADOW_NONE, cliprect, gParts->hpanedWidget, "paned", rect->x, rect->y, rect->width, rect->height, GTK_ORIENTATION_VERTICAL); @@ -1455,7 +1489,7 @@ moz_gtk_vpaned_paint(GdkDrawable* drawable, GdkRectangle* rect, GtkStateType vpaned_state = ConvertGtkState(state); ensure_vpaned_widget(); - gtk_paint_handle(gParts->vpanedWidget->style, drawable, vpaned_state, + gtk_paint_handle(gtk_widget_get_style(gParts->vpanedWidget), drawable, vpaned_state, GTK_SHADOW_NONE, cliprect, gParts->vpanedWidget, "paned", rect->x, rect->y, rect->width, rect->height, GTK_ORIENTATION_HORIZONTAL); @@ -1495,7 +1529,7 @@ moz_gtk_entry_paint(GdkDrawable* drawable, GdkRectangle* rect, gtk_widget_set_direction(widget, direction); - style = widget->style; + style = gtk_widget_get_style(widget); gtk_widget_style_get(widget, "interior-focus", &interior_focus, @@ -1551,7 +1585,9 @@ moz_gtk_entry_paint(GdkDrawable* drawable, GdkRectangle* rect, if (state->focused && !state->disabled) { /* This will get us the lit borders that focused textboxes enjoy on * some themes. */ +#ifdef GTK_API_VERSION_2 GTK_WIDGET_SET_FLAGS(widget, GTK_HAS_FOCUS); +#endif if (!interior_focus) { /* Indent the border a little bit if we have exterior focus @@ -1575,7 +1611,9 @@ moz_gtk_entry_paint(GdkDrawable* drawable, GdkRectangle* rect, /* Now unset the focus flag. We don't want other entries to look * like they're focused too! */ +#ifdef GTK_API_VERSION_2 GTK_WIDGET_UNSET_FLAGS(widget, GTK_HAS_FOCUS); +#endif } return MOZ_GTK_SUCCESS; @@ -1588,7 +1626,7 @@ moz_gtk_treeview_paint(GdkDrawable* drawable, GdkRectangle* rect, { gint xthickness, ythickness; - GtkStyle *style; + GtkStyle *style, *treeview_style; GtkStateType state_type; ensure_tree_view_widget(); @@ -1605,16 +1643,17 @@ moz_gtk_treeview_paint(GdkDrawable* drawable, GdkRectangle* rect, * which contains the cells to the treeview base color. * If we don't set it here the background color will not be correct.*/ gtk_widget_modify_bg(gParts->treeViewWidget, state_type, - &gParts->treeViewWidget->style->base[state_type]); + >k_widget_get_style(gParts->treeViewWidget)->base[state_type]); - style = gParts->scrolledWindowWidget->style; + style = gtk_widget_get_style(gParts->scrolledWindowWidget); xthickness = XTHICKNESS(style); ythickness = YTHICKNESS(style); - TSOffsetStyleGCs(gParts->treeViewWidget->style, rect->x, rect->y); + treeview_style = gtk_widget_get_style(gParts->treeViewWidget); + TSOffsetStyleGCs(treeview_style, rect->x, rect->y); TSOffsetStyleGCs(style, rect->x, rect->y); - gtk_paint_flat_box(gParts->treeViewWidget->style, drawable, state_type, + gtk_paint_flat_box(treeview_style, drawable, state_type, GTK_SHADOW_NONE, cliprect, gParts->treeViewWidget, "treeview", rect->x + xthickness, rect->y + ythickness, rect->width - 2 * xthickness, @@ -1661,7 +1700,7 @@ moz_gtk_tree_header_sort_arrow_paint(GdkDrawable* drawable, GdkRectangle* rect, arrow_rect.x = rect->x + (rect->width - arrow_rect.width) / 2; arrow_rect.y = rect->y + (rect->height - arrow_rect.height) / 2; - style = gParts->treeHeaderSortArrowWidget->style; + style = gtk_widget_get_style(gParts->treeHeaderSortArrowWidget); TSOffsetStyleGCs(style, arrow_rect.x, arrow_rect.y); gtk_paint_arrow(style, drawable, state_type, shadow_type, cliprect, @@ -1684,7 +1723,7 @@ moz_gtk_treeview_expander_paint(GdkDrawable* drawable, GdkRectangle* rect, ensure_tree_view_widget(); gtk_widget_set_direction(gParts->treeViewWidget, direction); - style = gParts->treeViewWidget->style; + style = gtk_widget_get_style(gParts->treeViewWidget); /* Because the frame we get is of the entire treeview, we can't get the precise * event state of one expander, thus rendering hover and active feedback useless. */ @@ -1709,7 +1748,7 @@ moz_gtk_expander_paint(GdkDrawable* drawable, GdkRectangle* rect, ensure_expander_widget(); gtk_widget_set_direction(gParts->expanderWidget, direction); - style = gParts->expanderWidget->style; + style = gtk_widget_get_style(gParts->expanderWidget); TSOffsetStyleGCs(style, rect->x, rect->y); gtk_paint_expander(style, drawable, state_type, cliprect, gParts->expanderWidget, "expander", @@ -1750,7 +1789,7 @@ moz_gtk_combo_box_paint(GdkDrawable* drawable, GdkRectangle* rect, calculate_arrow_rect(gParts->comboBoxArrowWidget, &arrow_rect, &real_arrow_rect, direction); - style = gParts->comboBoxArrowWidget->style; + style = gtk_widget_get_style(gParts->comboBoxArrowWidget); TSOffsetStyleGCs(style, rect->x, rect->y); gtk_widget_size_allocate(gParts->comboBoxWidget, rect); @@ -1765,7 +1804,7 @@ moz_gtk_combo_box_paint(GdkDrawable* drawable, GdkRectangle* rect, if (!gParts->comboBoxSeparatorWidget) return MOZ_GTK_SUCCESS; - style = gParts->comboBoxSeparatorWidget->style; + style = gtk_widget_get_style(gParts->comboBoxSeparatorWidget); TSOffsetStyleGCs(style, rect->x, rect->y); gtk_widget_style_get(gParts->comboBoxSeparatorWidget, @@ -1809,7 +1848,7 @@ moz_gtk_downarrow_paint(GdkDrawable* drawable, GdkRectangle* rect, GdkRectangle arrow_rect; ensure_button_arrow_widget(); - style = gParts->buttonArrowWidget->style; + style = gtk_widget_get_style(gParts->buttonArrowWidget); calculate_arrow_rect(gParts->buttonArrowWidget, rect, &arrow_rect, GTK_TEXT_DIR_LTR); @@ -1840,14 +1879,18 @@ moz_gtk_combo_box_entry_button_paint(GdkDrawable* drawable, GdkRectangle* rect, if (input_focus) { /* Some themes draw a complementary focus ring for the dropdown button * when the dropdown entry has focus */ +#ifdef GTK_API_VERSION_2 GTK_WIDGET_SET_FLAGS(gParts->comboBoxEntryTextareaWidget, GTK_HAS_FOCUS); +#endif } moz_gtk_button_paint(drawable, rect, cliprect, state, GTK_RELIEF_NORMAL, gParts->comboBoxEntryButtonWidget, direction); +#ifdef GTK_API_VERSION_2 if (input_focus) GTK_WIDGET_UNSET_FLAGS(gParts->comboBoxEntryTextareaWidget, GTK_HAS_FOCUS); +#endif calculate_button_inner_rect(gParts->comboBoxEntryButtonWidget, rect, &arrow_rect, direction, FALSE); @@ -1863,7 +1906,7 @@ moz_gtk_combo_box_entry_button_paint(GdkDrawable* drawable, GdkRectangle* rect, calculate_arrow_rect(gParts->comboBoxEntryArrowWidget, &arrow_rect, &real_arrow_rect, direction); - style = gParts->comboBoxEntryArrowWidget->style; + style = gtk_widget_get_style(gParts->comboBoxEntryArrowWidget); TSOffsetStyleGCs(style, real_arrow_rect.x, real_arrow_rect.y); gtk_paint_arrow(style, drawable, state_type, shadow_type, cliprect, @@ -1894,7 +1937,7 @@ moz_gtk_container_paint(GdkDrawable* drawable, GdkRectangle* rect, } gtk_widget_set_direction(widget, direction); - style = widget->style; + style = gtk_widget_get_style(widget); moz_gtk_widget_get_focus(widget, &interior_focus, &focus_width, &focus_pad); @@ -1951,7 +1994,7 @@ moz_gtk_toggle_label_paint(GdkDrawable* drawable, GdkRectangle* rect, state_type = ConvertGtkState(state); - style = widget->style; + style = gtk_widget_get_style(widget); TSOffsetStyleGCs(style, rect->x, rect->y); /* Always "checkbutton" to match gtkcheckbutton.c */ @@ -1972,7 +2015,7 @@ moz_gtk_toolbar_paint(GdkDrawable* drawable, GdkRectangle* rect, ensure_toolbar_widget(); gtk_widget_set_direction(gParts->toolbarWidget, direction); - style = gParts->toolbarWidget->style; + style = gtk_widget_get_style(gParts->toolbarWidget); TSOffsetStyleGCs(style, rect->x, rect->y); @@ -2007,7 +2050,7 @@ moz_gtk_toolbar_separator_paint(GdkDrawable* drawable, GdkRectangle* rect, ensure_toolbar_separator_widget(); gtk_widget_set_direction(gParts->toolbarSeparatorWidget, direction); - style = gParts->toolbarSeparatorWidget->style; + style = gtk_widget_get_style(gParts->toolbarSeparatorWidget); gtk_widget_style_get(gParts->toolbarWidget, "wide-separators", &wide_separators, @@ -2058,7 +2101,7 @@ moz_gtk_tooltip_paint(GdkDrawable* drawable, GdkRectangle* rect, "gtk-tooltips", "GtkWindow", GTK_TYPE_WINDOW); - style = gtk_style_attach(style, gParts->tooltipWidget->window); + style = gtk_style_attach(style, gtk_widget_get_window(gParts->tooltipWidget)); TSOffsetStyleGCs(style, rect->x, rect->y); gtk_paint_flat_box(style, drawable, GTK_STATE_NORMAL, GTK_SHADOW_OUT, cliprect, gParts->tooltipWidget, "tooltip", @@ -2078,7 +2121,7 @@ moz_gtk_resizer_paint(GdkDrawable* drawable, GdkRectangle* rect, ensure_window_widget(); gtk_widget_set_direction(gParts->protoWindow, direction); - style = gParts->protoWindow->style; + style = gtk_widget_get_style(gParts->protoWindow); TSOffsetStyleGCs(style, rect->x, rect->y); @@ -2100,7 +2143,7 @@ moz_gtk_frame_paint(GdkDrawable* drawable, GdkRectangle* rect, ensure_frame_widget(); gtk_widget_set_direction(gParts->frameWidget, direction); - style = gParts->frameWidget->style; + style = gtk_widget_get_style(gParts->frameWidget); gtk_widget_style_get(gParts->statusbarWidget, "shadow-type", &shadow_type, NULL); @@ -2121,7 +2164,7 @@ moz_gtk_progressbar_paint(GdkDrawable* drawable, GdkRectangle* rect, ensure_progress_widget(); gtk_widget_set_direction(gParts->progresWidget, direction); - style = gParts->progresWidget->style; + style = gtk_widget_get_style(gParts->progresWidget); TSOffsetStyleGCs(style, rect->x, rect->y); gtk_paint_box(style, drawable, GTK_STATE_NORMAL, GTK_SHADOW_IN, @@ -2140,7 +2183,7 @@ moz_gtk_progress_chunk_paint(GdkDrawable* drawable, GdkRectangle* rect, ensure_progress_widget(); gtk_widget_set_direction(gParts->progresWidget, direction); - style = gParts->progresWidget->style; + style = gtk_widget_get_style(gParts->progresWidget); TSOffsetStyleGCs(style, rect->x, rect->y); gtk_paint_box(style, drawable, GTK_STATE_PRELIGHT, GTK_SHADOW_OUT, @@ -2153,11 +2196,14 @@ moz_gtk_progress_chunk_paint(GdkDrawable* drawable, GdkRectangle* rect, gint moz_gtk_get_tab_thickness(void) { + GtkStyle* style; + ensure_tab_widget(); - if (YTHICKNESS(gParts->tabWidget->style) < 2) + style = gtk_widget_get_style(gParts->tabWidget); + if (YTHICKNESS(style) < 2) return 2; /* some themes don't set ythickness correctly */ - return YTHICKNESS(gParts->tabWidget->style); + return YTHICKNESS(style); } static gint @@ -2175,7 +2221,7 @@ moz_gtk_tab_paint(GdkDrawable* drawable, GdkRectangle* rect, ensure_tab_widget(); gtk_widget_set_direction(gParts->tabWidget, direction); - style = gParts->tabWidget->style; + style = gtk_widget_get_style(gParts->tabWidget); TSOffsetStyleGCs(style, rect->x, rect->y); if ((flags & MOZ_GTK_TAB_SELECTED) == 0) { @@ -2312,7 +2358,7 @@ moz_gtk_tabpanels_paint(GdkDrawable* drawable, GdkRectangle* rect, ensure_tab_widget(); gtk_widget_set_direction(gParts->tabWidget, direction); - style = gParts->tabWidget->style; + style = gtk_widget_get_style(gParts->tabWidget); TSOffsetStyleGCs(style, rect->x, rect->y); gtk_paint_box_gap(style, drawable, GTK_STATE_NORMAL, GTK_SHADOW_OUT, @@ -2338,7 +2384,7 @@ moz_gtk_tab_scroll_arrow_paint(GdkDrawable* drawable, GdkRectangle* rect, ensure_tab_widget(); - style = gParts->tabWidget->style; + style = gtk_widget_get_style(gParts->tabWidget); TSOffsetStyleGCs(style, rect->x, rect->y); if (direction == GTK_TEXT_DIR_RTL) { @@ -2364,7 +2410,7 @@ moz_gtk_menu_bar_paint(GdkDrawable* drawable, GdkRectangle* rect, gtk_widget_style_get(gParts->menuBarWidget, "shadow-type", &shadow_type, NULL); - style = gParts->menuBarWidget->style; + style = gtk_widget_get_style(gParts->menuBarWidget); TSOffsetStyleGCs(style, rect->x, rect->y); gtk_style_apply_default_background(style, drawable, TRUE, GTK_STATE_NORMAL, @@ -2385,7 +2431,7 @@ moz_gtk_menu_popup_paint(GdkDrawable* drawable, GdkRectangle* rect, ensure_menu_popup_widget(); gtk_widget_set_direction(gParts->menuPopupWidget, direction); - style = gParts->menuPopupWidget->style; + style = gtk_widget_get_style(gParts->menuPopupWidget); TSOffsetStyleGCs(style, rect->x, rect->y); gtk_style_apply_default_background(style, drawable, TRUE, GTK_STATE_NORMAL, @@ -2411,7 +2457,7 @@ moz_gtk_menu_separator_paint(GdkDrawable* drawable, GdkRectangle* rect, ensure_menu_separator_widget(); gtk_widget_set_direction(gParts->menuSeparatorWidget, direction); - style = gParts->menuSeparatorWidget->style; + style = gtk_widget_get_style(gParts->menuSeparatorWidget); gtk_widget_style_get(gParts->menuSeparatorWidget, "wide-separators", &wide_separators, @@ -2467,7 +2513,7 @@ moz_gtk_menu_item_paint(GdkDrawable* drawable, GdkRectangle* rect, } gtk_widget_set_direction(item_widget, direction); - style = item_widget->style; + style = gtk_widget_get_style(item_widget); TSOffsetStyleGCs(style, rect->x, rect->y); gtk_widget_style_get(item_widget, "selected-shadow-type", @@ -2492,7 +2538,7 @@ moz_gtk_menu_arrow_paint(GdkDrawable* drawable, GdkRectangle* rect, ensure_menu_item_widget(); gtk_widget_set_direction(gParts->menuItemWidget, direction); - style = gParts->menuItemWidget->style; + style = gtk_widget_get_style(gParts->menuItemWidget); TSOffsetStyleGCs(style, rect->x, rect->y); gtk_paint_arrow(style, drawable, state_type, @@ -2526,11 +2572,14 @@ moz_gtk_check_menu_item_paint(GdkDrawable* drawable, GdkRectangle* rect, "indicator-size", &indicator_size, NULL); +#ifdef GTK_API_VERSION_2 if (checked || GTK_CHECK_MENU_ITEM(gParts->checkMenuItemWidget)->always_show_toggle) { - style = gParts->checkMenuItemWidget->style; +#else + if (checked || FALSE) { +#endif + style = gtk_widget_get_style(gParts->checkMenuItemWidget); - offset = GTK_CONTAINER(gParts->checkMenuItemWidget)->border_width + - gParts->checkMenuItemWidget->style->xthickness + 2; + offset = gtk_container_get_border_width(GTK_CONTAINER(gParts->checkMenuItemWidget)) + style->xthickness + 2; /* while normally this "3" would be the horizontal-padding style value, passing it to Gecko as the value of menuitem padding causes problems with dropdowns (bug 406129), so in the menu.css @@ -2566,7 +2615,7 @@ moz_gtk_window_paint(GdkDrawable* drawable, GdkRectangle* rect, ensure_window_widget(); gtk_widget_set_direction(gParts->protoWindow, direction); - style = gParts->protoWindow->style; + style = gtk_widget_get_style(gParts->protoWindow); TSOffsetStyleGCs(style, rect->x, rect->y); gtk_style_apply_default_background(style, drawable, TRUE, @@ -2582,6 +2631,7 @@ moz_gtk_get_widget_border(GtkThemeWidgetType widget, gint* left, gint* top, gboolean inhtml) { GtkWidget* w; + GtkStyle *style; switch (widget) { case MOZ_GTK_BUTTON: @@ -2589,9 +2639,10 @@ moz_gtk_get_widget_border(GtkThemeWidgetType widget, gint* left, gint* top, GtkBorder inner_border; gboolean interior_focus; gint focus_width, focus_pad; + GtkStyle *style; ensure_button_widget(); - *left = *top = *right = *bottom = GTK_CONTAINER(gParts->buttonWidget)->border_width; + *left = *top = *right = *bottom = gtk_container_get_border_width(GTK_CONTAINER(gParts->buttonWidget)); /* Don't add this padding in HTML, otherwise the buttons will become too big and stuff the layout. */ @@ -2604,10 +2655,11 @@ moz_gtk_get_widget_border(GtkThemeWidgetType widget, gint* left, gint* top, *bottom += focus_width + focus_pad + inner_border.bottom; } - *left += gParts->buttonWidget->style->xthickness; - *right += gParts->buttonWidget->style->xthickness; - *top += gParts->buttonWidget->style->ythickness; - *bottom += gParts->buttonWidget->style->ythickness; + style = gtk_widget_get_style(gParts->buttonWidget); + *left += style->xthickness; + *right += style->xthickness; + *top += style->ythickness; + *bottom += style->ythickness; return MOZ_GTK_SUCCESS; } case MOZ_GTK_ENTRY: @@ -2629,9 +2681,10 @@ moz_gtk_get_widget_border(GtkThemeWidgetType widget, gint* left, gint* top, GtkBorder inner_border; gboolean interior_focus; gint focus_width, focus_pad; + GtkStyle* style; ensure_tree_header_cell_widget(); - *left = *top = *right = *bottom = GTK_CONTAINER(gParts->treeHeaderCellWidget)->border_width; + *left = *top = *right = *bottom = gtk_container_get_border_width(GTK_CONTAINER(gParts->treeHeaderCellWidget)); moz_gtk_widget_get_focus(gParts->treeHeaderCellWidget, &interior_focus, &focus_width, &focus_pad); moz_gtk_button_get_inner_border(gParts->treeHeaderCellWidget, &inner_border); @@ -2640,10 +2693,11 @@ moz_gtk_get_widget_border(GtkThemeWidgetType widget, gint* left, gint* top, *top += focus_width + focus_pad + inner_border.top; *bottom += focus_width + focus_pad + inner_border.bottom; - *left += gParts->treeHeaderCellWidget->style->xthickness; - *right += gParts->treeHeaderCellWidget->style->xthickness; - *top += gParts->treeHeaderCellWidget->style->ythickness; - *bottom += gParts->treeHeaderCellWidget->style->ythickness; + style = gtk_widget_get_style(gParts->treeHeaderCellWidget); + *left += style->xthickness; + *right += style->xthickness; + *top += style->ythickness; + *bottom += style->ythickness; return MOZ_GTK_SUCCESS; } case MOZ_GTK_TREE_HEADER_SORTARROW: @@ -2666,10 +2720,11 @@ moz_gtk_get_widget_border(GtkThemeWidgetType widget, gint* left, gint* top, gboolean ignored_interior_focus, wide_separators; gint focus_width, focus_pad, separator_width; GtkRequisition arrow_req; + GtkStyle* style; ensure_combo_box_widgets(); - *left = GTK_CONTAINER(gParts->comboBoxButtonWidget)->border_width; + *left = gtk_container_get_border_width(GTK_CONTAINER(gParts->comboBoxButtonWidget)); if (!inhtml) { moz_gtk_widget_get_focus(gParts->comboBoxButtonWidget, @@ -2678,8 +2733,9 @@ moz_gtk_get_widget_border(GtkThemeWidgetType widget, gint* left, gint* top, *left += focus_width + focus_pad; } - *top = *left + gParts->comboBoxButtonWidget->style->ythickness; - *left += gParts->comboBoxButtonWidget->style->xthickness; + style = gtk_widget_get_style(gParts->comboBoxButtonWidget); + *top = *left + style->ythickness; + *left += style->xthickness; *right = *left; *bottom = *top; @@ -2693,7 +2749,7 @@ moz_gtk_get_widget_border(GtkThemeWidgetType widget, gint* left, gint* top, if (!wide_separators) separator_width = - XTHICKNESS(gParts->comboBoxSeparatorWidget->style); + XTHICKNESS(style); } gtk_widget_size_request(gParts->comboBoxArrowWidget, &arrow_req); @@ -2778,7 +2834,7 @@ moz_gtk_get_widget_border(GtkThemeWidgetType widget, gint* left, gint* top, w = gParts->radiobuttonWidget; } - *left = *top = *right = *bottom = GTK_CONTAINER(w)->border_width; + *left = *top = *right = *bottom = gtk_container_get_border_width(GTK_CONTAINER(w)); if (!interior_focus) { *left += (focus_width + focus_pad); @@ -2843,8 +2899,9 @@ moz_gtk_get_widget_border(GtkThemeWidgetType widget, gint* left, gint* top, return MOZ_GTK_UNKNOWN_WIDGET; } - *right = *left = XTHICKNESS(w->style); - *bottom = *top = YTHICKNESS(w->style); + style = gtk_widget_get_style(w); + *right = *left = XTHICKNESS(style); + *bottom = *top = YTHICKNESS(style); return MOZ_GTK_SUCCESS; } @@ -2904,7 +2961,7 @@ moz_gtk_get_toolbar_separator_width(gint* size) ensure_toolbar_widget(); - style = gParts->toolbarWidget->style; + style = gtk_widget_get_style(gParts->toolbarWidget); gtk_widget_style_get(gParts->toolbarWidget, "space-size", size, @@ -2945,6 +3002,7 @@ moz_gtk_get_menu_separator_height(gint *size) { gboolean wide_separators; gint separator_height; + GtkStyle *style; ensure_menu_separator_widget(); @@ -2953,10 +3011,12 @@ moz_gtk_get_menu_separator_height(gint *size) "separator-height", &separator_height, NULL); + style = gtk_widget_get_style(gParts->menuSeparatorWidget); + if (wide_separators) - *size = separator_height + gParts->menuSeparatorWidget->style->ythickness; + *size = separator_height + style->ythickness; else - *size = gParts->menuSeparatorWidget->style->ythickness * 2; + *size = style->ythickness * 2; return MOZ_GTK_SUCCESS; } @@ -2989,8 +3049,7 @@ moz_gtk_get_scrollbar_metrics(MozGtkScrollbarMetrics *metrics) "stepper_spacing", &metrics->stepper_spacing, NULL); - metrics->min_slider_size = - GTK_RANGE(gParts->horizScrollbarWidget)->min_slider_size; + metrics->min_slider_size = gtk_range_get_min_slider_size(GTK_RANGE(gParts->horizScrollbarWidget)); return MOZ_GTK_SUCCESS; } @@ -3247,3 +3306,11 @@ void moz_gtk_destroy_theme_parts_widgets(GtkThemeParts* parts) parts->protoWindow = NULL; } } + +GtkWidget* moz_gtk_get_progress_widget() +{ + if (!is_initialized) + return NULL; + ensure_progress_widget(); + return gParts->progresWidget; +} diff --git a/WebCore/platform/gtk/gtkdrawing.h b/WebCore/platform/gtk/gtkdrawing.h index 1e9023f..b5a7feb 100644 --- a/WebCore/platform/gtk/gtkdrawing.h +++ b/WebCore/platform/gtk/gtkdrawing.h @@ -485,6 +485,12 @@ gint moz_gtk_get_tab_thickness(void); */ gboolean moz_gtk_images_in_menus(void); +/** + * Retrieve an actual GTK progress bar widget for style analysis. It will not + * be modified. + */ +GtkWidget* moz_gtk_get_progress_widget(void); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/WebCore/platform/haiku/RenderThemeHaiku.cpp b/WebCore/platform/haiku/RenderThemeHaiku.cpp index 4327795..78dfa9e 100644 --- a/WebCore/platform/haiku/RenderThemeHaiku.cpp +++ b/WebCore/platform/haiku/RenderThemeHaiku.cpp @@ -107,7 +107,7 @@ void RenderThemeHaiku::systemFont(int propId, FontDescription&) const notImplemented(); } -bool RenderThemeHaiku::paintCheckbox(RenderObject*, const RenderObject::PaintInfo& info, const IntRect& intRect) +bool RenderThemeHaiku::paintCheckbox(RenderObject*, const PaintInfo& info, const IntRect& intRect) { if (info.context->paintingDisabled()) return false; @@ -139,7 +139,7 @@ void RenderThemeHaiku::setCheckboxSize(RenderStyle* style) const style->setHeight(Length(size, Fixed)); } -bool RenderThemeHaiku::paintRadio(RenderObject*, const RenderObject::PaintInfo& info, const IntRect& intRect) +bool RenderThemeHaiku::paintRadio(RenderObject*, const PaintInfo& info, const IntRect& intRect) { if (info.context->paintingDisabled()) return false; @@ -169,7 +169,7 @@ void RenderThemeHaiku::adjustMenuListStyle(CSSStyleSelector*, RenderStyle* style style->setMinHeight(Length(minHeight, Fixed)); } -bool RenderThemeHaiku::paintMenuList(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) +bool RenderThemeHaiku::paintMenuList(RenderObject*, const PaintInfo&, const IntRect&) { notImplemented(); return false; diff --git a/WebCore/platform/haiku/RenderThemeHaiku.h b/WebCore/platform/haiku/RenderThemeHaiku.h index 7daebc4..06b7bdf 100644 --- a/WebCore/platform/haiku/RenderThemeHaiku.h +++ b/WebCore/platform/haiku/RenderThemeHaiku.h @@ -55,14 +55,14 @@ namespace WebCore { virtual void systemFont(int propId, FontDescription&) const; protected: - virtual bool paintCheckbox(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintCheckbox(RenderObject*, const PaintInfo&, const IntRect&); virtual void setCheckboxSize(RenderStyle*) const; - virtual bool paintRadio(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintRadio(RenderObject*, const PaintInfo&, const IntRect&); virtual void setRadioSize(RenderStyle*) const; virtual void adjustMenuListStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintMenuList(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintMenuList(RenderObject*, const PaintInfo&, const IntRect&); }; } // namespace WebCore diff --git a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp index cce4f64..4911bc9 100644 --- a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp +++ b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp @@ -210,7 +210,7 @@ public: // We can fill in the size now that the header is available. if (!m_decoder->setSize(m_info.image_width, m_info.image_height)) - return m_decoder->setFailed(); + return false; if (m_decodingSizeOnly) { // We can stop here. Reduce our buffer length and available diff --git a/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp b/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp index 56cf05f..8186f33 100644 --- a/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp +++ b/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp @@ -41,6 +41,12 @@ #include "PNGImageDecoder.h" #include "png.h" +#if defined(PNG_LIBPNG_VER_MAJOR) && defined(PNG_LIBPNG_VER_MINOR) && (PNG_LIBPNG_VER_MAJOR > 1 || (PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MINOR >= 4)) +#define JMPBUF(png_ptr) png_jmpbuf(png_ptr) +#else +#define JMPBUF(png_ptr) png_ptr->jmpbuf +#endif + namespace WebCore { // Gamma constants. @@ -54,7 +60,7 @@ const unsigned long cMaxPNGSize = 1000000UL; // Called if the decoding of the image fails. static void PNGAPI decodingFailed(png_structp png, png_const_charp) { - longjmp(png->jmpbuf, 1); + longjmp(JMPBUF(png), 1); } // Callbacks given to the read struct. The first is for warnings (we want to @@ -125,7 +131,7 @@ public: PNGImageDecoder* decoder = static_cast<PNGImageDecoder*>(png_get_progressive_ptr(m_png)); // We need to do the setjmp here. Otherwise bad things will happen. - if (setjmp(m_png->jmpbuf)) + if (setjmp(JMPBUF(m_png))) return decoder->setFailed(); const char* segment; @@ -220,7 +226,7 @@ void PNGImageDecoder::headerAvailable() // Protect against large images. if (png->width > cMaxPNGSize || png->height > cMaxPNGSize) { - longjmp(png->jmpbuf, 1); + longjmp(JMPBUF(png), 1); return; } @@ -233,7 +239,7 @@ void PNGImageDecoder::headerAvailable() bool result = setSize(width, height); m_doNothingOnFailure = false; if (!result) { - longjmp(png->jmpbuf, 1); + longjmp(JMPBUF(png), 1); return; } @@ -297,7 +303,7 @@ void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex, RGBA32Buffer& buffer = m_frameBufferCache[0]; if (buffer.status() == RGBA32Buffer::FrameEmpty) { if (!buffer.setSize(scaledSize().width(), scaledSize().height())) { - longjmp(m_reader->pngPtr()->jmpbuf, 1); + longjmp(JMPBUF(m_reader->pngPtr()), 1); return; } buffer.setStatus(RGBA32Buffer::FramePartial); diff --git a/WebCore/platform/network/ResourceLoadTiming.h b/WebCore/platform/network/ResourceLoadTiming.h new file mode 100644 index 0000000..55ff181 --- /dev/null +++ b/WebCore/platform/network/ResourceLoadTiming.h @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2010 Google, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 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 ResourceLoadTiming_h +#define ResourceLoadTiming_h + +#include <wtf/PassRefPtr.h> +#include <wtf/RefCounted.h> +#include <wtf/RefPtr.h> + +namespace WebCore { + +class ResourceLoadTiming : public RefCounted<ResourceLoadTiming> { +public: + PassRefPtr<ResourceLoadTiming> create() + { + return adoptRef(new ResourceLoadTiming); + } + + PassRefPtr<ResourceLoadTiming> deepCopy() + { + RefPtr<ResourceLoadTiming> timing = create(); + timing->redirectStart = redirectStart; + timing->redirectEnd = redirectEnd; + timing->redirectCount = redirectCount; + timing->domainLookupStart = domainLookupStart; + timing->domainLookupEnd = domainLookupEnd; + timing->connectStart = connectStart; + timing->connectEnd = connectEnd; + timing->requestStart = requestStart; + timing->requestEnd = requestEnd; + timing->responseStart = responseStart; + timing->responseEnd = responseEnd; + return timing.release(); + } + + bool operator==(const ResourceLoadTiming& other) const + { + return redirectStart == other.redirectStart + && redirectEnd == other.redirectEnd + && redirectCount == other.redirectCount + && domainLookupStart == other.domainLookupStart + && domainLookupEnd == other.domainLookupEnd + && connectStart == other.connectStart + && connectEnd == other.connectEnd + && requestStart == other.requestStart + && requestEnd == other.requestEnd + && responseStart == other.responseStart + && responseEnd == other.responseEnd; + } + + bool operator!=(const ResourceLoadTiming& other) const + { + return !(*this == other); + } + + double redirectStart; + double redirectEnd; + unsigned short redirectCount; + double domainLookupStart; + double domainLookupEnd; + double connectStart; + double connectEnd; + double requestStart; + double requestEnd; + double responseStart; + double responseEnd; + +private: + ResourceLoadTiming() + : redirectStart(0.0) + , redirectEnd(0.0) + , redirectCount(0) + , domainLookupStart(0.0) + , domainLookupEnd(0.0) + , connectStart(0.0) + , connectEnd(0.0) + , requestStart(0.0) + , requestEnd(0.0) + , responseStart(0.0) + , responseEnd(0.0) + { + } +}; + +} + +#endif diff --git a/WebCore/platform/network/ResourceResponseBase.cpp b/WebCore/platform/network/ResourceResponseBase.cpp index 3192a18..607cd7f 100644 --- a/WebCore/platform/network/ResourceResponseBase.cpp +++ b/WebCore/platform/network/ResourceResponseBase.cpp @@ -100,6 +100,7 @@ PassOwnPtr<ResourceResponse> ResourceResponseBase::adopt(PassOwnPtr<CrossThreadR response->lazyInit(); response->m_httpHeaderFields.adopt(data->m_httpHeaders.release()); response->setLastModifiedDate(data->m_lastModifiedDate); + response->setResourceLoadTiming(data->m_resourceLoadTiming.release()); return response.release(); } @@ -116,6 +117,8 @@ PassOwnPtr<CrossThreadResourceResponseData> ResourceResponseBase::copyData() con data->m_httpStatusText = httpStatusText().crossThreadString(); data->m_httpHeaders = httpHeaderFields().copyData(); data->m_lastModifiedDate = lastModifiedDate(); + if (m_resourceLoadTiming) + data->m_resourceLoadTiming = m_resourceLoadTiming->deepCopy(); return data.release(); } @@ -452,6 +455,20 @@ time_t ResourceResponseBase::lastModifiedDate() const return m_lastModifiedDate; } +ResourceLoadTiming* ResourceResponseBase::resourceLoadTiming() const +{ + lazyInit(); + + return m_resourceLoadTiming.get(); +} + +void ResourceResponseBase::setResourceLoadTiming(PassRefPtr<ResourceLoadTiming> resourceLoadTiming) +{ + lazyInit(); + + m_resourceLoadTiming = resourceLoadTiming; +} + void ResourceResponseBase::lazyInit() const { const_cast<ResourceResponse*>(static_cast<const ResourceResponse*>(this))->platformLazyInit(); @@ -477,6 +494,10 @@ bool ResourceResponseBase::compare(const ResourceResponse& a, const ResourceResp return false; if (a.httpHeaderFields() != b.httpHeaderFields()) return false; + if (a.resourceLoadTiming() && b.resourceLoadTiming() && *a.resourceLoadTiming() == *b.resourceLoadTiming()) + return ResourceResponse::platformCompare(a, b); + if (a.resourceLoadTiming() != b.resourceLoadTiming()) + return false; return ResourceResponse::platformCompare(a, b); } diff --git a/WebCore/platform/network/ResourceResponseBase.h b/WebCore/platform/network/ResourceResponseBase.h index 74e23a4..697a84c 100644 --- a/WebCore/platform/network/ResourceResponseBase.h +++ b/WebCore/platform/network/ResourceResponseBase.h @@ -29,8 +29,10 @@ #include "HTTPHeaderMap.h" #include "KURL.h" +#include "ResourceLoadTiming.h" #include <wtf/PassOwnPtr.h> +#include <wtf/RefPtr.h> namespace WebCore { @@ -95,6 +97,9 @@ public: double expires() const; double lastModified() const; + ResourceLoadTiming* resourceLoadTiming() const; + void setResourceLoadTiming(PassRefPtr<ResourceLoadTiming>); + // The ResourceResponse subclass may "shadow" this method to provide platform-specific memory usage information unsigned memoryUsage() const { @@ -125,6 +130,7 @@ protected: String m_httpStatusText; HTTPHeaderMap m_httpHeaderFields; time_t m_lastModifiedDate; + RefPtr<ResourceLoadTiming> m_resourceLoadTiming; bool m_isNull : 1; @@ -161,6 +167,7 @@ struct CrossThreadResourceResponseData : Noncopyable { String m_httpStatusText; OwnPtr<CrossThreadHTTPHeaderMapData> m_httpHeaders; time_t m_lastModifiedDate; + RefPtr<ResourceLoadTiming> m_resourceLoadTiming; }; } // namespace WebCore diff --git a/WebCore/platform/network/qt/QNetworkReplyHandler.cpp b/WebCore/platform/network/qt/QNetworkReplyHandler.cpp index e52dd1d..1ae24ff 100644 --- a/WebCore/platform/network/qt/QNetworkReplyHandler.cpp +++ b/WebCore/platform/network/qt/QNetworkReplyHandler.cpp @@ -60,6 +60,9 @@ FormDataIODevice::FormDataIODevice(FormData* data) , m_currentDelta(0) { setOpenMode(FormDataIODevice::ReadOnly); + + if (!m_formElements.isEmpty() && m_formElements[0].m_type == FormDataElement::encodedFile) + openFileForCurrentElement(); } FormDataIODevice::~FormDataIODevice() @@ -78,6 +81,11 @@ void FormDataIODevice::moveToNextElement() if (m_formElements.isEmpty() || m_formElements[0].m_type == FormDataElement::data) return; + openFileForCurrentElement(); +} + +void FormDataIODevice::openFileForCurrentElement() +{ if (!m_currentFile) m_currentFile = new QFile; @@ -353,7 +361,7 @@ void QNetworkReplyHandler::sendResponseIfNeeded() ResourceRequest newRequest = m_resourceHandle->request(); newRequest.setURL(newUrl); - if (((statusCode >= 301 && statusCode <= 303) || statusCode == 307) && m_method == QNetworkAccessManager::PostOperation) { + if (((statusCode >= 301 && statusCode <= 303) || statusCode == 307) && newRequest.httpMethod() == "POST") { m_method = QNetworkAccessManager::GetOperation; newRequest.setHTTPMethod("GET"); } diff --git a/WebCore/platform/network/qt/QNetworkReplyHandler.h b/WebCore/platform/network/qt/QNetworkReplyHandler.h index 9f8217d..f6b2358 100644 --- a/WebCore/platform/network/qt/QNetworkReplyHandler.h +++ b/WebCore/platform/network/qt/QNetworkReplyHandler.h @@ -104,6 +104,7 @@ protected: private: void moveToNextElement(); + void openFileForCurrentElement(); private: Vector<FormDataElement> m_formElements; diff --git a/WebCore/platform/qt/ClipboardQt.cpp b/WebCore/platform/qt/ClipboardQt.cpp index 485d0d1..f478e64 100644 --- a/WebCore/platform/qt/ClipboardQt.cpp +++ b/WebCore/platform/qt/ClipboardQt.cpp @@ -57,6 +57,11 @@ namespace WebCore { +static bool isTextMimeType(const String& type) +{ + return type == "text/plain" || type.startsWith("text/plain;"); +} + ClipboardQt::ClipboardQt(ClipboardAccessPolicy policy, const QMimeData* readableClipboard) : Clipboard(policy, true) , m_readableData(readableClipboard) @@ -130,10 +135,15 @@ String ClipboardQt::getData(const String& type, bool& success) const return String(); } + if (isTextMimeType(type) && m_readableData->hasText()) { + success = true; + return m_readableData->text(); + } + ASSERT(m_readableData); QByteArray data = m_readableData->data(QString(type)); success = !data.isEmpty(); - return String(data.data(), data.size()); + return String(data.constData(), data.size()); } bool ClipboardQt::setData(const String& type, const String& data) @@ -143,9 +153,14 @@ bool ClipboardQt::setData(const String& type, const String& data) if (!m_writableData) m_writableData = new QMimeData; - QByteArray array(reinterpret_cast<const char*>(data.characters()), - data.length()*2); - m_writableData->setData(QString(type), array); + + if (isTextMimeType(type)) + m_writableData->setText(QString(data)); + else { + QByteArray array(reinterpret_cast<const char*>(data.characters()), data.length() * 2); + m_writableData->setData(QString(type), array); + } + #ifndef QT_NO_CLIPBOARD if (!isForDragging()) QApplication::clipboard()->setMimeData(m_writableData); diff --git a/WebCore/platform/qt/RenderThemeQt.cpp b/WebCore/platform/qt/RenderThemeQt.cpp index 9319493..deb9037 100644 --- a/WebCore/platform/qt/RenderThemeQt.cpp +++ b/WebCore/platform/qt/RenderThemeQt.cpp @@ -83,7 +83,7 @@ namespace WebCore { using namespace HTMLNames; -StylePainter::StylePainter(RenderThemeQt* theme, const RenderObject::PaintInfo& paintInfo) +StylePainter::StylePainter(RenderThemeQt* theme, const PaintInfo& paintInfo) { init(paintInfo.context ? paintInfo.context : 0, theme->qStyle()); } @@ -437,7 +437,7 @@ void RenderThemeQt::setCheckboxSize(RenderStyle* style) const computeSizeBasedOnStyle(style); } -bool RenderThemeQt::paintCheckbox(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) +bool RenderThemeQt::paintCheckbox(RenderObject* o, const PaintInfo& i, const IntRect& r) { return paintButton(o, i, r); } @@ -447,7 +447,7 @@ void RenderThemeQt::setRadioSize(RenderStyle* style) const computeSizeBasedOnStyle(style); } -bool RenderThemeQt::paintRadio(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) +bool RenderThemeQt::paintRadio(RenderObject* o, const PaintInfo& i, const IntRect& r) { return paintButton(o, i, r); } @@ -531,7 +531,7 @@ void RenderThemeQt::setButtonPadding(RenderStyle* style) const style->setPaddingBottom(Length(paddingBottom, Fixed)); } -bool RenderThemeQt::paintButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) +bool RenderThemeQt::paintButton(RenderObject* o, const PaintInfo& i, const IntRect& r) { StylePainter p(this, i); if (!p.isValid()) @@ -564,7 +564,7 @@ void RenderThemeQt::adjustTextFieldStyle(CSSStyleSelector*, RenderStyle* style, computeSizeBasedOnStyle(style); } -bool RenderThemeQt::paintTextField(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) +bool RenderThemeQt::paintTextField(RenderObject* o, const PaintInfo& i, const IntRect& r) { StylePainter p(this, i); if (!p.isValid()) @@ -598,7 +598,7 @@ void RenderThemeQt::adjustTextAreaStyle(CSSStyleSelector* selector, RenderStyle* adjustTextFieldStyle(selector, style, element); } -bool RenderThemeQt::paintTextArea(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) +bool RenderThemeQt::paintTextArea(RenderObject* o, const PaintInfo& i, const IntRect& r) { return paintTextField(o, i, r); } @@ -633,7 +633,7 @@ void RenderThemeQt::setPopupPadding(RenderStyle* style) const } -bool RenderThemeQt::paintMenuList(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) +bool RenderThemeQt::paintMenuList(RenderObject* o, const PaintInfo& i, const IntRect& r) { StylePainter p(this, i); if (!p.isValid()) @@ -676,7 +676,7 @@ void RenderThemeQt::adjustMenuListButtonStyle(CSSStyleSelector*, RenderStyle* st setPopupPadding(style); } -bool RenderThemeQt::paintMenuListButton(RenderObject* o, const RenderObject::PaintInfo& i, +bool RenderThemeQt::paintMenuListButton(RenderObject* o, const PaintInfo& i, const IntRect& r) { StylePainter p(this, i); @@ -725,7 +725,7 @@ void RenderThemeQt::adjustProgressBarStyle(CSSStyleSelector*, RenderStyle* style style->setBoxShadow(0); } -bool RenderThemeQt::paintProgressBar(RenderObject* o, const RenderObject::PaintInfo& pi, const IntRect& r) +bool RenderThemeQt::paintProgressBar(RenderObject* o, const PaintInfo& pi, const IntRect& r) { if (!o->isProgress()) return true; @@ -769,7 +769,7 @@ bool RenderThemeQt::paintProgressBar(RenderObject* o, const RenderObject::PaintI } #endif -bool RenderThemeQt::paintSliderTrack(RenderObject* o, const RenderObject::PaintInfo& pi, +bool RenderThemeQt::paintSliderTrack(RenderObject* o, const PaintInfo& pi, const IntRect& r) { StylePainter p(this, pi); @@ -823,7 +823,7 @@ void RenderThemeQt::adjustSliderTrackStyle(CSSStyleSelector*, RenderStyle* style style->setBoxShadow(0); } -bool RenderThemeQt::paintSliderThumb(RenderObject* o, const RenderObject::PaintInfo& pi, +bool RenderThemeQt::paintSliderThumb(RenderObject* o, const PaintInfo& pi, const IntRect& r) { // We've already painted it in paintSliderTrack(), no need to do anything here. @@ -835,7 +835,7 @@ void RenderThemeQt::adjustSliderThumbStyle(CSSStyleSelector*, RenderStyle* style style->setBoxShadow(0); } -bool RenderThemeQt::paintSearchField(RenderObject* o, const RenderObject::PaintInfo& pi, +bool RenderThemeQt::paintSearchField(RenderObject* o, const PaintInfo& pi, const IntRect& r) { return true; @@ -855,7 +855,7 @@ void RenderThemeQt::adjustSearchFieldCancelButtonStyle(CSSStyleSelector* selecto RenderTheme::adjustSearchFieldCancelButtonStyle(selector, style, e); } -bool RenderThemeQt::paintSearchFieldCancelButton(RenderObject* o, const RenderObject::PaintInfo& pi, +bool RenderThemeQt::paintSearchFieldCancelButton(RenderObject* o, const PaintInfo& pi, const IntRect& r) { notImplemented(); @@ -869,7 +869,7 @@ void RenderThemeQt::adjustSearchFieldDecorationStyle(CSSStyleSelector* selector, RenderTheme::adjustSearchFieldDecorationStyle(selector, style, e); } -bool RenderThemeQt::paintSearchFieldDecoration(RenderObject* o, const RenderObject::PaintInfo& pi, +bool RenderThemeQt::paintSearchFieldDecoration(RenderObject* o, const PaintInfo& pi, const IntRect& r) { notImplemented(); @@ -883,7 +883,7 @@ void RenderThemeQt::adjustSearchFieldResultsDecorationStyle(CSSStyleSelector* se RenderTheme::adjustSearchFieldResultsDecorationStyle(selector, style, e); } -bool RenderThemeQt::paintSearchFieldResultsDecoration(RenderObject* o, const RenderObject::PaintInfo& pi, +bool RenderThemeQt::paintSearchFieldResultsDecoration(RenderObject* o, const PaintInfo& pi, const IntRect& r) { notImplemented(); @@ -1042,12 +1042,12 @@ QColor RenderThemeQt::getMediaControlForegroundColor(RenderObject* o) const return fgColor; } -bool RenderThemeQt::paintMediaFullscreenButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeQt::paintMediaFullscreenButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) { return RenderTheme::paintMediaFullscreenButton(o, paintInfo, r); } -bool RenderThemeQt::paintMediaMuteButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeQt::paintMediaMuteButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) { HTMLMediaElement* mediaElement = getMediaElementFromRenderObject(o); if (!mediaElement) @@ -1071,7 +1071,7 @@ bool RenderThemeQt::paintMediaMuteButton(RenderObject* o, const RenderObject::Pa return false; } -bool RenderThemeQt::paintMediaPlayButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeQt::paintMediaPlayButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) { HTMLMediaElement* mediaElement = getMediaElementFromRenderObject(o); if (!mediaElement) @@ -1098,19 +1098,19 @@ bool RenderThemeQt::paintMediaPlayButton(RenderObject* o, const RenderObject::Pa return false; } -bool RenderThemeQt::paintMediaSeekBackButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) +bool RenderThemeQt::paintMediaSeekBackButton(RenderObject*, const PaintInfo&, const IntRect&) { // We don't want to paint this at the moment. return false; } -bool RenderThemeQt::paintMediaSeekForwardButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) +bool RenderThemeQt::paintMediaSeekForwardButton(RenderObject*, const PaintInfo&, const IntRect&) { // We don't want to paint this at the moment. return false; } -bool RenderThemeQt::paintMediaCurrentTime(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeQt::paintMediaCurrentTime(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) { StylePainter p(this, paintInfo); if (!p.isValid()) @@ -1132,7 +1132,7 @@ String RenderThemeQt::formatMediaControlsRemainingTime(float currentTime, float return String(); } -bool RenderThemeQt::paintMediaVolumeSliderTrack(RenderObject *o, const RenderObject::PaintInfo &paintInfo, const IntRect &r) +bool RenderThemeQt::paintMediaVolumeSliderTrack(RenderObject *o, const PaintInfo &paintInfo, const IntRect &r) { StylePainter p(this, paintInfo); if (!p.isValid()) @@ -1180,7 +1180,7 @@ bool RenderThemeQt::paintMediaVolumeSliderTrack(RenderObject *o, const RenderObj return false; } -bool RenderThemeQt::paintMediaVolumeSliderThumb(RenderObject *o, const RenderObject::PaintInfo &paintInfo, const IntRect &r) +bool RenderThemeQt::paintMediaVolumeSliderThumb(RenderObject *o, const PaintInfo &paintInfo, const IntRect &r) { StylePainter p(this, paintInfo); if (!p.isValid()) @@ -1190,7 +1190,7 @@ bool RenderThemeQt::paintMediaVolumeSliderThumb(RenderObject *o, const RenderObj return false; } -bool RenderThemeQt::paintMediaSliderTrack(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeQt::paintMediaSliderTrack(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) { HTMLMediaElement* mediaElement = getMediaElementFromRenderObject(o); if (!mediaElement) @@ -1227,7 +1227,7 @@ bool RenderThemeQt::paintMediaSliderTrack(RenderObject* o, const RenderObject::P return false; } -bool RenderThemeQt::paintMediaSliderThumb(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeQt::paintMediaSliderThumb(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) { StylePainter p(this, paintInfo); if (!p.isValid()) diff --git a/WebCore/platform/qt/RenderThemeQt.h b/WebCore/platform/qt/RenderThemeQt.h index fdd8d6b..7ab6769 100644 --- a/WebCore/platform/qt/RenderThemeQt.h +++ b/WebCore/platform/qt/RenderThemeQt.h @@ -90,50 +90,50 @@ public: QStyle* qStyle() const; protected: - virtual bool paintCheckbox(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r); + virtual bool paintCheckbox(RenderObject* o, const PaintInfo& i, const IntRect& r); virtual void setCheckboxSize(RenderStyle*) const; - virtual bool paintRadio(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r); + virtual bool paintRadio(RenderObject* o, const PaintInfo& i, const IntRect& r); virtual void setRadioSize(RenderStyle*) const; virtual void adjustButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintButton(RenderObject*, const PaintInfo&, const IntRect&); virtual void setButtonSize(RenderStyle*) const; - virtual bool paintTextField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintTextField(RenderObject*, const PaintInfo&, const IntRect&); virtual void adjustTextFieldStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintTextArea(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintTextArea(RenderObject*, const PaintInfo&, const IntRect&); virtual void adjustTextAreaStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintMenuList(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r); + virtual bool paintMenuList(RenderObject* o, const PaintInfo& i, const IntRect& r); virtual void adjustMenuListStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintMenuListButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintMenuListButton(RenderObject*, const PaintInfo&, const IntRect&); virtual void adjustMenuListButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const; #if ENABLE(PROGRESS_TAG) virtual void adjustProgressBarStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintProgressBar(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintProgressBar(RenderObject*, const PaintInfo&, const IntRect&); #endif - virtual bool paintSliderTrack(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintSliderTrack(RenderObject*, const PaintInfo&, const IntRect&); virtual void adjustSliderTrackStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintSliderThumb(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintSliderThumb(RenderObject*, const PaintInfo&, const IntRect&); virtual void adjustSliderThumbStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintSearchField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintSearchField(RenderObject*, const PaintInfo&, const IntRect&); virtual void adjustSearchFieldStyle(CSSStyleSelector*, RenderStyle*, Element*) const; virtual void adjustSearchFieldCancelButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintSearchFieldCancelButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintSearchFieldCancelButton(RenderObject*, const PaintInfo&, const IntRect&); virtual void adjustSearchFieldDecorationStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintSearchFieldDecoration(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintSearchFieldDecoration(RenderObject*, const PaintInfo&, const IntRect&); virtual void adjustSearchFieldResultsDecorationStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintSearchFieldResultsDecoration(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintSearchFieldResultsDecoration(RenderObject*, const PaintInfo&, const IntRect&); #if ENABLE(PROGRESS_TAG) // Returns the repeat interval of the animation for the progress bar. @@ -143,16 +143,16 @@ protected: #endif #if ENABLE(VIDEO) - virtual bool paintMediaFullscreenButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual bool paintMediaPlayButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual bool paintMediaMuteButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual bool paintMediaSeekBackButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual bool paintMediaSeekForwardButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual bool paintMediaSliderTrack(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual bool paintMediaSliderThumb(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual bool paintMediaCurrentTime(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual bool paintMediaVolumeSliderTrack(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); - virtual bool paintMediaVolumeSliderThumb(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintMediaFullscreenButton(RenderObject*, const PaintInfo&, const IntRect&); + virtual bool paintMediaPlayButton(RenderObject*, const PaintInfo&, const IntRect&); + virtual bool paintMediaMuteButton(RenderObject*, const PaintInfo&, const IntRect&); + virtual bool paintMediaSeekBackButton(RenderObject*, const PaintInfo&, const IntRect&); + virtual bool paintMediaSeekForwardButton(RenderObject*, const PaintInfo&, const IntRect&); + virtual bool paintMediaSliderTrack(RenderObject*, const PaintInfo&, const IntRect&); + virtual bool paintMediaSliderThumb(RenderObject*, const PaintInfo&, const IntRect&); + virtual bool paintMediaCurrentTime(RenderObject*, const PaintInfo&, const IntRect&); + virtual bool paintMediaVolumeSliderTrack(RenderObject*, const PaintInfo&, const IntRect&); + virtual bool paintMediaVolumeSliderThumb(RenderObject*, const PaintInfo&, const IntRect&); virtual String formatMediaControlsCurrentTime(float currentTime, float duration) const; virtual String formatMediaControlsRemainingTime(float currentTime, float duration) const; private: @@ -190,7 +190,7 @@ private: class StylePainter { public: - explicit StylePainter(RenderThemeQt*, const RenderObject::PaintInfo&); + explicit StylePainter(RenderThemeQt*, const PaintInfo&); explicit StylePainter(ScrollbarThemeQt*, GraphicsContext*); ~StylePainter(); diff --git a/WebCore/platform/text/BidiResolver.h b/WebCore/platform/text/BidiResolver.h index 286cdcd..a99fd01 100644 --- a/WebCore/platform/text/BidiResolver.h +++ b/WebCore/platform/text/BidiResolver.h @@ -806,35 +806,33 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, boo break; } - if (pastEnd) { - if (eor == current) { - if (!reachedEndOfLine) { - eor = endOfLine; - switch (m_status.eor) { - case LeftToRight: - case RightToLeft: - case ArabicNumber: - m_direction = m_status.eor; - break; - case EuropeanNumber: - m_direction = m_status.lastStrong == LeftToRight ? LeftToRight : EuropeanNumber; - break; - default: - ASSERT(false); - } - appendRun(); + if (pastEnd && eor == current) { + if (!reachedEndOfLine) { + eor = endOfLine; + switch (m_status.eor) { + case LeftToRight: + case RightToLeft: + case ArabicNumber: + m_direction = m_status.eor; + break; + case EuropeanNumber: + m_direction = m_status.lastStrong == LeftToRight ? LeftToRight : EuropeanNumber; + break; + default: + ASSERT(false); } - current = end; - m_status = stateAtEnd.m_status; - sor = stateAtEnd.sor; - eor = stateAtEnd.eor; - last = stateAtEnd.last; - reachedEndOfLine = stateAtEnd.reachedEndOfLine; - lastBeforeET = stateAtEnd.lastBeforeET; - emptyRun = stateAtEnd.emptyRun; - m_direction = OtherNeutral; - break; + appendRun(); } + current = end; + m_status = stateAtEnd.m_status; + sor = stateAtEnd.sor; + eor = stateAtEnd.eor; + last = stateAtEnd.last; + reachedEndOfLine = stateAtEnd.reachedEndOfLine; + lastBeforeET = stateAtEnd.lastBeforeET; + emptyRun = stateAtEnd.emptyRun; + m_direction = OtherNeutral; + break; } // set m_status.last as needed. @@ -887,8 +885,21 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, boo } increment(); - if (!m_currentExplicitEmbeddingSequence.isEmpty()) + if (!m_currentExplicitEmbeddingSequence.isEmpty()) { commitExplicitEmbedding(); + if (pastEnd) { + current = end; + m_status = stateAtEnd.m_status; + sor = stateAtEnd.sor; + eor = stateAtEnd.eor; + last = stateAtEnd.last; + reachedEndOfLine = stateAtEnd.reachedEndOfLine; + lastBeforeET = stateAtEnd.lastBeforeET; + emptyRun = stateAtEnd.emptyRun; + m_direction = OtherNeutral; + break; + } + } if (emptyRun && (dirCurrent == RightToLeftEmbedding || dirCurrent == LeftToRightEmbedding diff --git a/WebCore/platform/text/SegmentedString.cpp b/WebCore/platform/text/SegmentedString.cpp index 9ff1c45..04d6c77 100644 --- a/WebCore/platform/text/SegmentedString.cpp +++ b/WebCore/platform/text/SegmentedString.cpp @@ -122,6 +122,13 @@ void SegmentedString::prepend(const SegmentedSubstring &s) } } +void SegmentedString::close() +{ + // Closing a stream twice is likely a coding mistake. + ASSERT(!m_closed); + m_closed = true; +} + void SegmentedString::append(const SegmentedString &s) { ASSERT(!m_closed); diff --git a/WebCore/platform/text/SegmentedString.h b/WebCore/platform/text/SegmentedString.h index 21eae14..747d426 100644 --- a/WebCore/platform/text/SegmentedString.h +++ b/WebCore/platform/text/SegmentedString.h @@ -82,7 +82,7 @@ public: const SegmentedString& operator=(const SegmentedString&); void clear(); - void close() { m_closed = true; } + void close(); void append(const SegmentedString&); void prepend(const SegmentedString&); diff --git a/WebCore/platform/wx/RenderThemeWx.cpp b/WebCore/platform/wx/RenderThemeWx.cpp index c4d8c35..c68bde9 100644 --- a/WebCore/platform/wx/RenderThemeWx.cpp +++ b/WebCore/platform/wx/RenderThemeWx.cpp @@ -55,14 +55,14 @@ public: // A method asking if the theme's controls actually care about redrawing when hovered. virtual bool supportsHover(const RenderStyle*) const { return true; } - virtual bool paintCheckbox(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) + virtual bool paintCheckbox(RenderObject* o, const PaintInfo& i, const IntRect& r) { return paintButton(o, i, r); } virtual void setCheckboxSize(RenderStyle*) const; - virtual bool paintRadio(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) + virtual bool paintRadio(RenderObject* o, const PaintInfo& i, const IntRect& r) { return paintButton(o, i, r); } @@ -72,18 +72,18 @@ public: virtual void adjustRepaintRect(const RenderObject*, IntRect&); virtual void adjustButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintButton(RenderObject*, const PaintInfo&, const IntRect&); virtual void adjustTextFieldStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintTextField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintTextField(RenderObject*, const PaintInfo&, const IntRect&); virtual int minimumMenuListSize(RenderStyle*) const; virtual void adjustMenuListStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintMenuList(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintMenuList(RenderObject*, const PaintInfo&, const IntRect&); virtual void adjustMenuListButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const; - virtual bool paintMenuListButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&); + virtual bool paintMenuListButton(RenderObject*, const PaintInfo&, const IntRect&); virtual bool isControlStyled(const RenderStyle*, const BorderData&, const FillLayer&, const Color&) const; @@ -259,7 +259,7 @@ void RenderThemeWx::adjustButtonStyle(CSSStyleSelector* selector, RenderStyle* s addIntrinsicMargins(style); } -bool RenderThemeWx::paintButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) +bool RenderThemeWx::paintButton(RenderObject* o, const PaintInfo& i, const IntRect& r) { wxWindow* window = nativeWindowForRenderObject(o); wxDC* dc = static_cast<wxDC*>(i.context->platformContext()); @@ -318,7 +318,7 @@ void RenderThemeWx::adjustTextFieldStyle(CSSStyleSelector*, RenderStyle* style, } -bool RenderThemeWx::paintTextField(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) +bool RenderThemeWx::paintTextField(RenderObject* o, const PaintInfo& i, const IntRect& r) { wxWindow* window = nativeWindowForRenderObject(o); wxDC* dc = static_cast<wxDC*>(i.context->platformContext()); @@ -340,7 +340,7 @@ void RenderThemeWx::adjustMenuListStyle(CSSStyleSelector*, RenderStyle* style, E { } -bool RenderThemeWx::paintMenuList(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) +bool RenderThemeWx::paintMenuList(RenderObject* o, const PaintInfo& i, const IntRect& r) { wxWindow* window = nativeWindowForRenderObject(o); wxDC* dc = static_cast<wxDC*>(i.context->platformContext()); @@ -369,7 +369,7 @@ void RenderThemeWx::adjustMenuListButtonStyle(CSSStyleSelector*, RenderStyle*, E notImplemented(); } -bool RenderThemeWx::paintMenuListButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) +bool RenderThemeWx::paintMenuListButton(RenderObject* o, const PaintInfo& i, const IntRect& r) { wxWindow* window = nativeWindowForRenderObject(o); wxDC* dc = static_cast<wxDC*>(i.context->platformContext()); |