diff options
Diffstat (limited to 'Source/WebCore')
82 files changed, 796 insertions, 786 deletions
diff --git a/Source/WebCore/Android.derived.v8bindings.mk b/Source/WebCore/Android.derived.v8bindings.mk index 546cefe..509d21e 100644 --- a/Source/WebCore/Android.derived.v8bindings.mk +++ b/Source/WebCore/Android.derived.v8bindings.mk @@ -31,7 +31,7 @@ js_binding_scripts := \ $(LOCAL_PATH)/bindings/scripts/generate-bindings.pl # Add ACCELERATED_COMPOSITING=1 and ENABLE_3D_RENDERING=1 for layers support -FEATURE_DEFINES := ENABLE_ORIENTATION_EVENTS=1 ENABLE_TOUCH_EVENTS=1 ENABLE_DATABASE=1 ENABLE_OFFLINE_WEB_APPLICATIONS=1 ENABLE_DOM_STORAGE=1 ENABLE_VIDEO=1 ENABLE_GEOLOCATION=1 ENABLE_CONNECTION=1 ENABLE_APPLICATION_INSTALLED=1 ENABLE_XPATH=1 ENABLE_XSLT=1 ENABLE_DEVICE_ORIENTATION=1 ENABLE_FILE_READER=1 ENABLE_BLOB=1 ENABLE_WEB_TIMING=1 +FEATURE_DEFINES := ENABLE_ORIENTATION_EVENTS=1 ENABLE_TOUCH_EVENTS=1 ENABLE_DATABASE=1 ENABLE_OFFLINE_WEB_APPLICATIONS=1 ENABLE_DOM_STORAGE=1 ENABLE_VIDEO=1 ENABLE_GEOLOCATION=1 ENABLE_CONNECTION=1 ENABLE_APPLICATION_INSTALLED=1 ENABLE_XPATH=1 ENABLE_XSLT=1 ENABLE_DEVICE_ORIENTATION=1 ENABLE_FILE_READER=1 ENABLE_BLOB=1 ENABLE_WEB_TIMING=1 ENABLE_MEDIA_CAPTURE=1 # The defines above should be identical to those for JSC. FEATURE_DEFINES += V8_BINDING diff --git a/Source/WebCore/Android.mk b/Source/WebCore/Android.mk index 3cf8d54..794a4a8 100644 --- a/Source/WebCore/Android.mk +++ b/Source/WebCore/Android.mk @@ -634,7 +634,6 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ platform/graphics/WidthIterator.cpp \ \ platform/graphics/android/BitmapAllocatorAndroid.cpp \ - platform/graphics/android/GradientAndroid.cpp \ platform/graphics/android/GraphicsLayerAndroid.cpp \ platform/graphics/android/GLWebViewState.cpp \ platform/graphics/android/ImageAndroid.cpp \ @@ -728,6 +727,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ platform/graphics/skia/FloatPointSkia.cpp \ platform/graphics/skia/FloatRectSkia.cpp \ platform/graphics/skia/GlyphPageTreeNodeSkia.cpp \ + platform/graphics/skia/GradientSkia.cpp \ platform/graphics/skia/IntPointSkia.cpp \ platform/graphics/skia/IntRectSkia.cpp \ platform/graphics/skia/NativeImageSkia.cpp \ diff --git a/Source/WebCore/WebCore.exp.in b/Source/WebCore/WebCore.exp.in index f110846..c6c76bf 100644 --- a/Source/WebCore/WebCore.exp.in +++ b/Source/WebCore/WebCore.exp.in @@ -1595,7 +1595,6 @@ __ZN7WebCore17HTMLPlugInElement11getNPObjectEv __ZNK7WebCore14SecurityOrigin9canAccessEPKS0_ __ZNK7WebCore4KURL10protocolIsEPKc __ZNK7WebCore4KURL7hasPathEv -__ZNK7WebCore4KURL9prettyURLEv #endif #if ENABLE(ORIENTATION_EVENTS) diff --git a/Source/WebCore/css/CSSParser.cpp b/Source/WebCore/css/CSSParser.cpp index b78a6d0..06e895d 100644 --- a/Source/WebCore/css/CSSParser.cpp +++ b/Source/WebCore/css/CSSParser.cpp @@ -5383,6 +5383,8 @@ bool CSSParser::parseRadialGradient(RefPtr<CSSValue>& gradient, CSSGradientRepea // parseFillPosition advances the args next pointer. parseFillPosition(args, centerX, centerY); a = args->current(); + if (!a) + return false; if (centerX || centerY) { // Comma diff --git a/Source/WebCore/css/CSSPrimitiveValue.cpp b/Source/WebCore/css/CSSPrimitiveValue.cpp index 04f1089..237844e 100644 --- a/Source/WebCore/css/CSSPrimitiveValue.cpp +++ b/Source/WebCore/css/CSSPrimitiveValue.cpp @@ -316,7 +316,8 @@ double CSSPrimitiveValue::computeLengthDouble(RenderStyle* style, RenderStyle* r break; case CSS_REMS: applyZoomMultiplier = false; - factor = computingFontSize ? rootStyle->fontDescription().specifiedSize() : rootStyle->fontDescription().computedSize(); + if (rootStyle) + factor = computingFontSize ? rootStyle->fontDescription().specifiedSize() : rootStyle->fontDescription().computedSize(); break; case CSS_PX: break; diff --git a/Source/WebCore/css/CSSStyleSelector.cpp b/Source/WebCore/css/CSSStyleSelector.cpp index 0b6fd35..e49ad2a 100644 --- a/Source/WebCore/css/CSSStyleSelector.cpp +++ b/Source/WebCore/css/CSSStyleSelector.cpp @@ -1194,7 +1194,8 @@ PassRefPtr<RenderStyle> CSSStyleSelector::styleForDocument(Document* document) documentStyle->setVisuallyOrdered(document->visuallyOrdered()); documentStyle->setZoom(frame ? frame->pageZoomFactor() : 1); documentStyle->setPageScaleTransform(frame ? frame->pageScaleFactor() : 1); - + documentStyle->setUserModify(document->inDesignMode() ? READ_WRITE : READ_ONLY); + Element* docElement = document->documentElement(); RenderObject* docElementRenderer = docElement ? docElement->renderer() : 0; if (docElementRenderer) { @@ -1236,6 +1237,15 @@ PassRefPtr<RenderStyle> CSSStyleSelector::styleForDocument(Document* document) return documentStyle.release(); } +static inline bool isAtShadowBoundary(Element* element) +{ + if (!element) + return false; + + ContainerNode* parentNode = element->parentNode(); + return parentNode && parentNode->isShadowBoundary(); +} + // If resolveForRootDefault is true, style based on user agent style sheet only. This is used in media queries, where // relative units are interpreted according to document root element style, styled only with UA stylesheet @@ -1278,6 +1288,10 @@ PassRefPtr<RenderStyle> CSSStyleSelector::styleForElement(Element* e, RenderStyl initForStyleResolve(e, defaultParent); } + // Don't propagate user-modify into shadow DOM + if (isAtShadowBoundary(e)) + m_style->setUserModify(RenderStyle::initialUserModify()); + m_checker.m_matchVisitedPseudoClass = matchVisitedPseudoClass; m_style = RenderStyle::create(); @@ -1772,15 +1786,6 @@ static void addIntrinsicMargins(RenderStyle* style) } } -static inline bool isAtShadowBoundary(Element* element) -{ - if (!element) - return false; - - ContainerNode* parentNode = element->parentNode(); - return parentNode && parentNode->isShadowBoundary(); -} - void CSSStyleSelector::adjustRenderStyle(RenderStyle* style, RenderStyle* parentStyle, Element *e) { // Cache our original display. @@ -4966,6 +4971,11 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value) applyProperty(CSSPropertyFontStyle, font->style.get()); applyProperty(CSSPropertyFontVariant, font->variant.get()); applyProperty(CSSPropertyFontWeight, font->weight.get()); + // The previous properties can dirty our font but they don't try to read the font's + // properties back, which is safe. However if font-size is using the 'ex' unit, it will + // need query the dirtied font's x-height to get the computed size. To be safe in this + // case, let's just update the font now. + updateFont(); applyProperty(CSSPropertyFontSize, font->size.get()); m_lineHeightValue = font->lineHeight.get(); diff --git a/Source/WebCore/css/WebKitCSSKeyframesRule.cpp b/Source/WebCore/css/WebKitCSSKeyframesRule.cpp index 3b41f43..497bd19 100644 --- a/Source/WebCore/css/WebKitCSSKeyframesRule.cpp +++ b/Source/WebCore/css/WebKitCSSKeyframesRule.cpp @@ -66,7 +66,8 @@ void WebKitCSSKeyframesRule::setName(const String& name) // Since the name is used in the keyframe map list in CSSStyleSelector, we need // to recompute the style sheet to get the updated name. - stylesheet()->styleSheetChanged(); + if (stylesheet()) + stylesheet()->styleSheetChanged(); } unsigned WebKitCSSKeyframesRule::length() const diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp index 1b5f55b..7fc628c 100644 --- a/Source/WebCore/dom/Document.cpp +++ b/Source/WebCore/dom/Document.cpp @@ -4083,6 +4083,8 @@ void Document::setTransformSource(PassOwnPtr<TransformSource> source) void Document::setDesignMode(InheritedBool value) { m_designMode = value; + for (Frame* frame = m_frame; frame && frame->document(); frame = frame->tree()->traverseNext(m_frame)) + frame->document()->scheduleForcedStyleRecalc(); } Document::InheritedBool Document::getDesignMode() const diff --git a/Source/WebCore/dom/Node.cpp b/Source/WebCore/dom/Node.cpp index 0967ef5..ec5c423 100644 --- a/Source/WebCore/dom/Node.cpp +++ b/Source/WebCore/dom/Node.cpp @@ -770,7 +770,7 @@ bool Node::isContentEditable() const bool Node::rendererIsEditable(EditableLevel editableLevel) const { - if (document()->inDesignMode() || (document()->frame() && document()->frame()->page() && document()->frame()->page()->isEditable())) + if (document()->frame() && document()->frame()->page() && document()->frame()->page()->isEditable() && !shadowTreeRootNode()) return true; // Ideally we'd call ASSERT(!needsStyleRecalc()) here, but @@ -1614,7 +1614,7 @@ SVGUseElement* Node::svgShadowHost() const } #endif -Node* Node::shadowAncestorNode() +Node* Node::shadowAncestorNode() const { #if ENABLE(SVG) // SVG elements living in a shadow tree only occur when <use> created them. @@ -1622,18 +1622,18 @@ Node* Node::shadowAncestorNode() // but the actual shadow tree element - as main difference to the HTML forms // shadow tree concept. (This function _could_ be made virtual - opinions?) if (isSVGElement()) - return this; + return const_cast<Node*>(this); #endif Node* root = shadowTreeRootNode(); if (root) return root->shadowHost(); - return this; + return const_cast<Node*>(this); } -Node* Node::shadowTreeRootNode() +Node* Node::shadowTreeRootNode() const { - Node* root = this; + Node* root = const_cast<Node*>(this); while (root) { if (root->isShadowRoot() || root->isSVGShadowRoot()) return root; diff --git a/Source/WebCore/dom/Node.h b/Source/WebCore/dom/Node.h index 08b1921..76355c3 100644 --- a/Source/WebCore/dom/Node.h +++ b/Source/WebCore/dom/Node.h @@ -218,8 +218,8 @@ public: virtual bool isShadowBoundary() const { return false; } virtual bool canHaveLightChildRendererWithShadow() const { return false; } - Node* shadowAncestorNode(); - Node* shadowTreeRootNode(); + Node* shadowAncestorNode() const; + Node* shadowTreeRootNode() const; bool isInShadowTree(); // Node's parent, shadow tree host, or SVG use. ContainerNode* parentOrHostNode() const; diff --git a/Source/WebCore/dom/Range.cpp b/Source/WebCore/dom/Range.cpp index 469a94a..268687f 100644 --- a/Source/WebCore/dom/Range.cpp +++ b/Source/WebCore/dom/Range.cpp @@ -51,6 +51,8 @@ using namespace std; static WTF::RefCountedLeakCounter rangeCounter("Range"); #endif +typedef Vector<RefPtr<Node> > NodeVector; + inline Range::Range(PassRefPtr<Document> ownerDocument) : m_ownerDocument(ownerDocument) , m_start(m_ownerDocument) @@ -662,8 +664,6 @@ static inline unsigned lengthOfContentsInNode(Node* node) PassRefPtr<DocumentFragment> Range::processContents(ActionType action, ExceptionCode& ec) { - typedef Vector<RefPtr<Node> > NodeVector; - RefPtr<DocumentFragment> fragment; if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) fragment = DocumentFragment::create(m_ownerDocument.get()); @@ -873,9 +873,14 @@ PassRefPtr<Node> Range::processAncestorsAndTheirSiblings(ActionType action, Node // FIXME: This assertion may fail if DOM is modified during mutation event // FIXME: Share code with Range::processNodes ASSERT(!firstChildInAncestorToProcess || firstChildInAncestorToProcess->parentNode() == ancestor); - RefPtr<Node> next; - for (Node* child = firstChildInAncestorToProcess.get(); child; child = next.get()) { - next = direction == ProcessContentsForward ? child->nextSibling() : child->previousSibling(); + + NodeVector nodes; + for (Node* child = firstChildInAncestorToProcess.get(); child; + child = (direction == ProcessContentsForward) ? child->nextSibling() : child->previousSibling()) + nodes.append(child); + + for (NodeVector::const_iterator it = nodes.begin(); it != nodes.end(); it++) { + Node* child = it->get(); switch (action) { case DELETE_CONTENTS: ancestor->removeChild(child, ec); diff --git a/Source/WebCore/editing/ApplyStyleCommand.cpp b/Source/WebCore/editing/ApplyStyleCommand.cpp index c9649d0..4f1bc93 100644 --- a/Source/WebCore/editing/ApplyStyleCommand.cpp +++ b/Source/WebCore/editing/ApplyStyleCommand.cpp @@ -1316,8 +1316,10 @@ void ApplyStyleCommand::surroundNodeRangeWithElement(PassRefPtr<Node> passedStar RefPtr<Node> node = startNode; while (node) { RefPtr<Node> next = node->nextSibling(); - removeNode(node); - appendNode(node, element); + if (node->isContentEditable()) { + removeNode(node); + appendNode(node, element); + } if (node == endNode) break; node = next; diff --git a/Source/WebCore/editing/CompositeEditCommand.cpp b/Source/WebCore/editing/CompositeEditCommand.cpp index cf2959a..bf515d7 100644 --- a/Source/WebCore/editing/CompositeEditCommand.cpp +++ b/Source/WebCore/editing/CompositeEditCommand.cpp @@ -781,7 +781,7 @@ void CompositeEditCommand::cloneParagraphUnderNewElement(Position& start, Positi appendNode(topNode, blockElement); RefPtr<Node> lastNode = topNode; - if (start.deprecatedNode() != outerNode) { + if (start.deprecatedNode() != outerNode && lastNode->isElementNode()) { Vector<RefPtr<Node> > ancestors; // Insert each node from innerNode to outerNode (excluded) in a list. diff --git a/Source/WebCore/fileapi/DOMFileSystemBase.cpp b/Source/WebCore/fileapi/DOMFileSystemBase.cpp index eafb815..5a2627f 100644 --- a/Source/WebCore/fileapi/DOMFileSystemBase.cpp +++ b/Source/WebCore/fileapi/DOMFileSystemBase.cpp @@ -63,7 +63,7 @@ bool DOMFileSystemBase::crackFileSystemURL(const KURL& url, AsyncFileSystem::Typ return false; KURL originURL(ParsedURLString, url.path()); - String path = originURL.path(); + String path = decodeURLEscapeSequences(originURL.path()); if (path.isEmpty() || path[0] != '/') return false; path = path.substring(1); diff --git a/Source/WebCore/html/HTMLAnchorElement.cpp b/Source/WebCore/html/HTMLAnchorElement.cpp index 4636f20..b05e7f5 100644 --- a/Source/WebCore/html/HTMLAnchorElement.cpp +++ b/Source/WebCore/html/HTMLAnchorElement.cpp @@ -405,7 +405,10 @@ void HTMLAnchorElement::setPathname(const String& value) String HTMLAnchorElement::port() const { - return String::number(href().port()); + if (href().hasPort()) + return String::number(href().port()); + + return ""; } void HTMLAnchorElement::setPort(const String& value) diff --git a/Source/WebCore/html/HTMLAttributeNames.in b/Source/WebCore/html/HTMLAttributeNames.in index 5e0fe7b..578f717 100644 --- a/Source/WebCore/html/HTMLAttributeNames.in +++ b/Source/WebCore/html/HTMLAttributeNames.in @@ -58,6 +58,7 @@ bgcolor bgproperties border bordercolor +capture cellpadding cellspacing char diff --git a/Source/WebCore/html/HTMLElement.cpp b/Source/WebCore/html/HTMLElement.cpp index b2b57a2..82e33d1 100644 --- a/Source/WebCore/html/HTMLElement.cpp +++ b/Source/WebCore/html/HTMLElement.cpp @@ -682,11 +682,6 @@ void HTMLElement::setContentEditable(Attribute* attr) attr->decl()->removeProperty(CSSPropertyWordWrap, false); attr->decl()->removeProperty(CSSPropertyWebkitNbspMode, false); attr->decl()->removeProperty(CSSPropertyWebkitLineBreak, false); - } else if (equalIgnoringCase(enabled, "inherit")) { - addCSSProperty(attr, CSSPropertyWebkitUserModify, CSSValueInherit); - attr->decl()->removeProperty(CSSPropertyWordWrap, false); - attr->decl()->removeProperty(CSSPropertyWebkitNbspMode, false); - attr->decl()->removeProperty(CSSPropertyWebkitLineBreak, false); } else if (equalIgnoringCase(enabled, "plaintext-only")) { addCSSProperty(attr, CSSPropertyWebkitUserModify, CSSValueReadWritePlaintextOnly); addCSSProperty(attr, CSSPropertyWordWrap, CSSValueBreakWord); diff --git a/Source/WebCore/html/HTMLInputElement.cpp b/Source/WebCore/html/HTMLInputElement.cpp index 2b262e4..36cdf51 100644 --- a/Source/WebCore/html/HTMLInputElement.cpp +++ b/Source/WebCore/html/HTMLInputElement.cpp @@ -1588,4 +1588,24 @@ void HTMLInputElement::handleBeforeTextInsertedEvent(Event* event) InputElement::handleBeforeTextInsertedEvent(m_data, this, this, event); } +#if PLATFORM(ANDROID) && ENABLE(MEDIA_CAPTURE) +String HTMLInputElement::capture() const +{ + if (!isFileUpload()) { + // capture has no meaning on anything other than file pickers. + return String(); + } + + String capture = fastGetAttribute(captureAttr).lower(); + if (capture == "camera" + || capture == "camcorder" + || capture == "microphone" + || capture == "filesystem") + return capture; + // According to the HTML Media Capture specification, the invalid and + // missing default value is filesystem. + return "filesystem"; +} +#endif + } // namespace diff --git a/Source/WebCore/html/HTMLInputElement.h b/Source/WebCore/html/HTMLInputElement.h index 2a98b13..58d86ac 100644 --- a/Source/WebCore/html/HTMLInputElement.h +++ b/Source/WebCore/html/HTMLInputElement.h @@ -200,6 +200,10 @@ public: void updateCheckedRadioButtons(); bool lastChangeWasUserEdit() const; + +#if PLATFORM(ANDROID) && ENABLE(MEDIA_CAPTURE) + String capture() const; +#endif protected: HTMLInputElement(const QualifiedName&, Document*, HTMLFormElement*, bool createdByParser); diff --git a/Source/WebCore/html/HTMLInputElement.idl b/Source/WebCore/html/HTMLInputElement.idl index f346e10..e1937e4 100644 --- a/Source/WebCore/html/HTMLInputElement.idl +++ b/Source/WebCore/html/HTMLInputElement.idl @@ -107,6 +107,9 @@ module html { attribute [Reflect, EnabledAtRuntime] boolean webkitGrammar; attribute [DontEnum] EventListener onwebkitspeechchange; #endif +#if defined(WTF_PLATFORM_ANDROID) && defined(ENABLE_MEDIA_CAPTURE) && ENABLE_MEDIA_CAPTURE + attribute [Reflect] DOMString capture; +#endif }; } diff --git a/Source/WebCore/html/HTMLMediaElement.cpp b/Source/WebCore/html/HTMLMediaElement.cpp index 5cd2ddd..46e8a12 100644 --- a/Source/WebCore/html/HTMLMediaElement.cpp +++ b/Source/WebCore/html/HTMLMediaElement.cpp @@ -238,7 +238,9 @@ void HTMLMediaElement::attributeChanged(Attribute* attr, bool preserveDecls) #if !ENABLE(PLUGIN_PROXY_FOR_VIDEO) if (controls()) { if (!hasMediaControls()) { - ensureMediaControls(); + if (!createMediaControls()) + return; + mediaControls()->reset(); } mediaControls()->show(); @@ -2739,13 +2741,18 @@ bool HTMLMediaElement::hasMediaControls() return node && node->isMediaControls(); } -void HTMLMediaElement::ensureMediaControls() +bool HTMLMediaElement::createMediaControls() { if (hasMediaControls()) - return; + return true; ExceptionCode ec; - ensureShadowRoot()->appendChild(MediaControls::create(this), ec); + RefPtr<MediaControls> controls = MediaControls::create(this); + if (!controls) + return false; + + ensureShadowRoot()->appendChild(controls, ec); + return true; } void* HTMLMediaElement::preDispatchEventHandler(Event* event) @@ -2753,7 +2760,9 @@ void* HTMLMediaElement::preDispatchEventHandler(Event* event) if (event && event->type() == eventNames().webkitfullscreenchangeEvent) { if (controls()) { if (!hasMediaControls()) { - ensureMediaControls(); + if (!createMediaControls()) + return 0; + mediaControls()->reset(); } mediaControls()->show(); diff --git a/Source/WebCore/html/HTMLMediaElement.h b/Source/WebCore/html/HTMLMediaElement.h index 2144ea1..0b11861 100644 --- a/Source/WebCore/html/HTMLMediaElement.h +++ b/Source/WebCore/html/HTMLMediaElement.h @@ -325,7 +325,7 @@ private: void refreshCachedTime() const; bool hasMediaControls(); - void ensureMediaControls(); + bool createMediaControls(); virtual void* preDispatchEventHandler(Event*); diff --git a/Source/WebCore/html/shadow/TextControlInnerElements.h b/Source/WebCore/html/shadow/TextControlInnerElements.h index 2340970..886fbf8 100644 --- a/Source/WebCore/html/shadow/TextControlInnerElements.h +++ b/Source/WebCore/html/shadow/TextControlInnerElements.h @@ -101,9 +101,8 @@ private: virtual void detach(); virtual bool isSpinButtonElement() const { return true; } - // FIXME: shadowAncestorNode() should be const. - virtual bool isEnabledFormControl() const { return static_cast<Element*>(const_cast<SpinButtonElement*>(this)->shadowAncestorNode())->isEnabledFormControl(); } - virtual bool isReadOnlyFormControl() const { return static_cast<Element*>(const_cast<SpinButtonElement*>(this)->shadowAncestorNode())->isReadOnlyFormControl(); } + virtual bool isEnabledFormControl() const { return static_cast<Element*>(shadowAncestorNode())->isEnabledFormControl(); } + virtual bool isReadOnlyFormControl() const { return static_cast<Element*>(shadowAncestorNode())->isReadOnlyFormControl(); } virtual void defaultEventHandler(Event*); void startRepeatingTimer(); void stopRepeatingTimer(); diff --git a/Source/WebCore/loader/FrameLoader.cpp b/Source/WebCore/loader/FrameLoader.cpp index f999fdb..670cf1f 100644 --- a/Source/WebCore/loader/FrameLoader.cpp +++ b/Source/WebCore/loader/FrameLoader.cpp @@ -993,7 +993,8 @@ void FrameLoader::loadArchive(PassRefPtr<Archive> prpArchive) ObjectContentType FrameLoader::defaultObjectContentType(const KURL& url, const String& mimeTypeIn, bool shouldPreferPlugInsForImages) { String mimeType = mimeTypeIn; - String extension = url.path().substring(url.path().reverseFind('.') + 1); + String decodedPath = decodeURLEscapeSequences(url.path()); + String extension = decodedPath.substring(decodedPath.reverseFind('.') + 1); // We don't use MIMETypeRegistry::getMIMETypeForPath() because it returns "application/octet-stream" upon failure if (mimeType.isEmpty()) diff --git a/Source/WebCore/page/EventHandler.cpp b/Source/WebCore/page/EventHandler.cpp index a737754..45450b5 100644 --- a/Source/WebCore/page/EventHandler.cpp +++ b/Source/WebCore/page/EventHandler.cpp @@ -3224,15 +3224,7 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event) // When sending a touch cancel event, use empty touches and targetTouches lists. bool isTouchCancelEvent = (state == PlatformTouchPoint::TouchCancelled); RefPtr<TouchList>& effectiveTouches(isTouchCancelEvent ? emptyList : touches); -#if PLATFORM(ANDROID) - AtomicString stateName(eventNameForTouchPointState(static_cast<PlatformTouchPoint::State>(state))); - if (event.type() == TouchLongPress) - stateName = eventNames().touchlongpressEvent; - else if (event.type() == TouchDoubleTap) - stateName = eventNames().touchdoubletapEvent; -#else const AtomicString& stateName(eventNameForTouchPointState(static_cast<PlatformTouchPoint::State>(state))); -#endif const EventTargetSet& targetsForState = changedTouches[state].m_targets; for (EventTargetSet::const_iterator it = targetsForState.begin(); it != targetsForState.end(); ++it) { diff --git a/Source/WebCore/page/Location.cpp b/Source/WebCore/page/Location.cpp index 4835a83..fb68a09 100644 --- a/Source/WebCore/page/Location.cpp +++ b/Source/WebCore/page/Location.cpp @@ -63,8 +63,7 @@ String Location::href() const if (!m_frame) return String(); - const KURL& url = this->url(); - return url.hasPath() ? url.prettyURL() : url.prettyURL() + "/"; + return url().string(); } String Location::protocol() const @@ -83,7 +82,7 @@ String Location::host() const // Note: this is the IE spec. The NS spec swaps the two, it says // "The hostname property is the concatenation of the host and port properties, separated by a colon." const KURL& url = this->url(); - return url.port() ? url.host() + ":" + String::number(url.port()) : url.host(); + return url.hasPort() ? url.host() + ":" + String::number(url.port()) : url.host(); } String Location::hostname() const @@ -100,7 +99,7 @@ String Location::port() const return String(); const KURL& url = this->url(); - return url.port() ? String::number(url.port()) : ""; + return url.hasPort() ? String::number(url.port()) : ""; } String Location::pathname() const @@ -147,15 +146,6 @@ String Location::getParameter(const String& name) const return parameters.get(name); } -String Location::toString() const -{ - if (!m_frame) - return String(); - - const KURL& url = this->url(); - return url.hasPath() ? url.prettyURL() : url.prettyURL() + "/"; -} - void Location::setHref(const String& urlString, DOMWindow* activeWindow, DOMWindow* firstWindow) { if (!m_frame) @@ -199,7 +189,7 @@ void Location::setPort(const String& portString, DOMWindow* activeWindow, DOMWin return; KURL url = m_frame->document()->url(); int port = portString.toInt(); - if (port < 0 || port > 0xFFFF) + if (port < 0 || port > 0xFFFF || portString.isEmpty()) url.removePort(); else url.setPort(port); diff --git a/Source/WebCore/page/Location.h b/Source/WebCore/page/Location.h index 1b68cee..0e89ecf 100644 --- a/Source/WebCore/page/Location.h +++ b/Source/WebCore/page/Location.h @@ -29,9 +29,9 @@ #ifndef Location_h #define Location_h -#include <wtf/Forward.h> #include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> +#include <wtf/text/WTFString.h> namespace WebCore { @@ -71,7 +71,7 @@ public: String hash() const; String origin() const; - String toString() const; + String toString() const { return href(); } String getParameter(const String&) const; diff --git a/Source/WebCore/platform/FileChooser.h b/Source/WebCore/platform/FileChooser.h index ac5e0e6..6c382d1 100644 --- a/Source/WebCore/platform/FileChooser.h +++ b/Source/WebCore/platform/FileChooser.h @@ -50,6 +50,9 @@ public: virtual String acceptTypes() = 0; virtual void chooseIconForFiles(FileChooser*, const Vector<String>&) = 0; virtual ~FileChooserClient(); +#if PLATFORM(ANDROID) && ENABLE(MEDIA_CAPTURE) + virtual String capture() = 0; +#endif }; class FileChooser : public RefCounted<FileChooser> { @@ -79,6 +82,10 @@ public: // Acceptable MIME types. It's an 'accept' attribute value of the corresponding INPUT element. String acceptTypes() const { return m_client ? m_client->acceptTypes() : String(); } +#if PLATFORM(ANDROID) && ENABLE(MEDIA_CAPTURE) + String capture() const { return m_client ? m_client->capture() : String(); } +#endif + private: FileChooser(FileChooserClient*, const Vector<String>& initialFilenames); void initialize(); diff --git a/Source/WebCore/platform/KURL.cpp b/Source/WebCore/platform/KURL.cpp index 88ad3d9..234d749 100644 --- a/Source/WebCore/platform/KURL.cpp +++ b/Source/WebCore/platform/KURL.cpp @@ -708,7 +708,7 @@ String KURL::query() const String KURL::path() const { - return decodeURLEscapeSequences(m_string.substring(m_portEnd, m_pathEnd - m_portEnd)); + return m_string.substring(m_portEnd, m_pathEnd - m_portEnd); } bool KURL::setProtocol(const String& s) @@ -866,7 +866,7 @@ void KURL::setPath(const String& s) parse(m_string.left(m_portEnd) + encodeWithURLEscapeSequences(path) + m_string.substring(m_pathEnd)); } -String KURL::prettyURL() const +String KURL::deprecatedString() const { if (!m_isValid) return m_string; @@ -996,7 +996,7 @@ static void appendEscapingBadChars(char*& buffer, const char* strStart, size_t l buffer = p; } -static void escapeAndAppendFragment(char*& buffer, const char* strStart, size_t length) +static void escapeAndAppendNonHierarchicalPart(char*& buffer, const char* strStart, size_t length) { char* p = buffer; @@ -1137,6 +1137,23 @@ static inline bool hostPortIsEmptyButCredentialsArePresent(int hostStart, int po return userEndChar == '@' && hostStart == portEnd; } +static bool isNonFileHierarchicalScheme(const char* scheme, size_t schemeLength) +{ + switch (schemeLength) { + case 2: + return equal("ws", 2, scheme, schemeLength); + case 3: + return equal("ftp", 3, scheme, schemeLength) || equal("wss", 3, scheme, schemeLength); + case 4: + return equal("http", 4, scheme, schemeLength); + case 5: + return equal("https", 5, scheme, schemeLength); + case 6: + return equal("gopher", 6, scheme, schemeLength); + } + return false; +} + void KURL::parse(const char* url, const String* originalString) { if (!url || url[0] == '\0') { @@ -1173,6 +1190,7 @@ void KURL::parse(const char* url, const String* originalString) int portEnd; bool hierarchical = url[schemeEnd + 1] == '/'; + bool hasSecondSlash = hierarchical && url[schemeEnd + 2] == '/'; bool isFile = schemeEnd == 4 && matchLetter(url[0], 'f') @@ -1186,12 +1204,15 @@ void KURL::parse(const char* url, const String* originalString) && matchLetter(url[3], 'p') && (url[4] == ':' || (matchLetter(url[4], 's') && url[5] == ':')); - if (hierarchical && url[schemeEnd + 2] == '/') { + if ((hierarchical && hasSecondSlash) || isNonFileHierarchicalScheme(url, schemeEnd)) { // The part after the scheme is either a net_path or an abs_path whose first path segment is empty. // Attempt to find an authority. - // FIXME: Authority characters may be scanned twice, and it would be nice to be faster. - userStart += 2; + + if (hierarchical) + userStart++; + if (hasSecondSlash) + userStart++; userEnd = userStart; int colonPos = 0; @@ -1394,12 +1415,14 @@ void KURL::parse(const char* url, const String* originalString) m_userStart = m_userEnd = m_passwordEnd = m_hostEnd = m_portEnd = p - buffer.data(); // For canonicalization, ensure we have a '/' for no path. - // Do this only for hierarchical URL with protocol http or https. - if (m_protocolInHTTPFamily && hierarchical && pathEnd == pathStart) + // Do this only for URL with protocol http or https. + if (m_protocolInHTTPFamily && pathEnd == pathStart) *p++ = '/'; // add path, escaping bad characters - if (!hierarchical || !hasSlashDotOrDotDot(url)) + if (!hierarchical) + escapeAndAppendNonHierarchicalPart(p, url + pathStart, pathEnd - pathStart); + else if (!hasSlashDotOrDotDot(url)) appendEscapingBadChars(p, url + pathStart, pathEnd - pathStart); else { CharBuffer pathBuffer(pathEnd - pathStart + 1); @@ -1425,7 +1448,7 @@ void KURL::parse(const char* url, const String* originalString) // add fragment, escaping bad characters if (fragmentEnd != queryEnd) { *p++ = '#'; - escapeAndAppendFragment(p, url + fragmentStart, fragmentEnd - fragmentStart); + escapeAndAppendNonHierarchicalPart(p, url + fragmentStart, fragmentEnd - fragmentStart); } m_fragmentEnd = p - buffer.data(); diff --git a/Source/WebCore/platform/KURL.h b/Source/WebCore/platform/KURL.h index db2dd42..192c10b 100644 --- a/Source/WebCore/platform/KURL.h +++ b/Source/WebCore/platform/KURL.h @@ -152,7 +152,9 @@ public: String baseAsString() const; - String prettyURL() const; + // This function is only used by location.href. It's likely we shouldn't + // use it for that purpose, but more study is necessary before we remove it. + String deprecatedString() const; String fileSystemPath() const; // Returns true if the current URL's protocol is the same as the null- diff --git a/Source/WebCore/platform/KURLGoogle.cpp b/Source/WebCore/platform/KURLGoogle.cpp index 0d11b99..54bcf16 100644 --- a/Source/WebCore/platform/KURLGoogle.cpp +++ b/Source/WebCore/platform/KURLGoogle.cpp @@ -593,7 +593,6 @@ String KURL::query() const String KURL::path() const { - // Note: KURL.cpp unescapes here. return m_url.componentString(m_url.m_parsed.path); } @@ -670,16 +669,12 @@ void KURL::setPort(unsigned short i) { KURLGooglePrivate::Replacements replacements; String portStr; - if (i) { - portStr = String::number(i); - replacements.SetPort( - reinterpret_cast<const url_parse::UTF16Char*>(portStr.characters()), - url_parse::Component(0, portStr.length())); - } else { - // Clear any existing port when it is set to 0. - replacements.ClearPort(); - } + portStr = String::number(i); + replacements.SetPort( + reinterpret_cast<const url_parse::UTF16Char*>(portStr.characters()), + url_parse::Component(0, portStr.length())); + m_url.replaceComponents(replacements); } @@ -772,7 +767,7 @@ void KURL::setPath(const String& path) // On Mac, this just seems to return the same URL, but with "/foo/bar" for // file: URLs instead of file:///foo/bar. We don't bother with any of this, // at least for now. -String KURL::prettyURL() const +String KURL::deprecatedString() const { if (!m_url.m_isValid) return String(); diff --git a/Source/WebCore/platform/PlatformTouchEvent.h b/Source/WebCore/platform/PlatformTouchEvent.h index 2ca7c99..f7524b4 100644 --- a/Source/WebCore/platform/PlatformTouchEvent.h +++ b/Source/WebCore/platform/PlatformTouchEvent.h @@ -52,10 +52,6 @@ enum TouchEventType { , TouchMove , TouchEnd , TouchCancel -#if PLATFORM(ANDROID) - , TouchLongPress - , TouchDoubleTap -#endif }; class PlatformTouchEvent { diff --git a/Source/WebCore/platform/graphics/Gradient.cpp b/Source/WebCore/platform/graphics/Gradient.cpp index 7541646..7e3984f 100644 --- a/Source/WebCore/platform/graphics/Gradient.cpp +++ b/Source/WebCore/platform/graphics/Gradient.cpp @@ -221,7 +221,7 @@ void Gradient::setGradientSpaceTransform(const AffineTransform& gradientSpaceTra setPlatformGradientSpaceTransform(gradientSpaceTransformation); } -#if !(USE(SKIA) && !PLATFORM(ANDROID)) && !USE(CAIRO) +#if !USE(SKIA) && !USE(CAIRO) void Gradient::setPlatformGradientSpaceTransform(const AffineTransform&) { } diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp index 99eb1c6..8581a8e 100644 --- a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp +++ b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp @@ -70,7 +70,7 @@ GLWebViewState::GLWebViewState() , m_goingLeft(false) , m_scale(1) , m_layersRenderingMode(kAllTextures) - , m_surfaceCollectionManager(this) + , m_surfaceCollectionManager() { m_viewport.setEmpty(); @@ -132,10 +132,10 @@ void GLWebViewState::setViewport(const SkRect& viewport, float scale) int viewMaxTileX = static_cast<int>(ceilf((viewport.width()-1) * invTileContentWidth)) + 1; int viewMaxTileY = static_cast<int>(ceilf((viewport.height()-1) * invTileContentHeight)) + 1; - TilesManager* manager = TilesManager::instance(); - int maxTextureCount = viewMaxTileX * viewMaxTileY * (manager->highEndGfx() ? 4 : 2); + TilesManager* tilesManager = TilesManager::instance(); + int maxTextureCount = viewMaxTileX * viewMaxTileY * (tilesManager->highEndGfx() ? 4 : 2); - manager->setMaxTextureCount(maxTextureCount); + tilesManager->setMaxTextureCount(maxTextureCount); // TODO: investigate whether we can move this return earlier. if ((m_viewport == viewport) @@ -196,10 +196,6 @@ double GLWebViewState::setupDrawing(const IntRect& viewRect, const SkRect& visib const IntRect& webViewRect, int titleBarHeight, const IntRect& screenClip, float scale) { - int left = viewRect.x(); - int top = viewRect.y(); - int width = viewRect.width(); - int height = viewRect.height(); TilesManager* tilesManager = TilesManager::instance(); // Make sure GL resources are created on the UI thread. @@ -216,15 +212,8 @@ double GLWebViewState::setupDrawing(const IntRect& viewRect, const SkRect& visib transferQueue->initGLResources(TilesManager::tileWidth(), TilesManager::tileHeight()); } - // TODO: Add the video GL resource re-initialization code here. - shader->setupDrawing(viewRect, visibleRect, webViewRect, titleBarHeight, screenClip, scale); - shader->calculateAnimationDelta(); - - glViewport(left + shader->getAnimationDeltaX(), - top - shader->getAnimationDeltaY(), - width, height); double currentTime = WTF::currentTime(); @@ -298,6 +287,14 @@ bool GLWebViewState::setLayersRenderingMode(TexturesResult& nbTexturesNeeded) return (m_layersRenderingMode != layersRenderingMode && invalBase); } +// -rect(viewRect) is the webViewRect with inverted Y, in screen coordinate. +// -viewport(visibleRect) is the visible area in document coordinate. +// They are both based on webViewRect and calculated in Java side. +// +// -clip is the final glViewport value in screen coordinate, and it contains the +// animation translation/scale and FBO offset. +// +// TODO: Try to decrease the number of parameters as some info is redundant. int GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, IntRect& webViewRect, int titleBarHeight, IntRect& clip, float scale, @@ -305,20 +302,21 @@ int GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, bool shouldDraw) { TilesManager* tilesManager = TilesManager::instance(); - tilesManager->getProfiler()->nextFrame(viewport.fLeft, viewport.fTop, - viewport.fRight, viewport.fBottom, - scale); + if (shouldDraw) + tilesManager->getProfiler()->nextFrame(viewport.fLeft, viewport.fTop, + viewport.fRight, viewport.fBottom, + scale); tilesManager->incDrawGLCount(); - ALOGV("drawGL, rect(%d, %d, %d, %d), viewport(%.2f, %.2f, %.2f, %.2f)", + ALOGV("drawGL, rect/viewRect(%d, %d, %d, %d), viewport/visibleRect(%.2f, %.2f, %.2f, %.2f)", rect.x(), rect.y(), rect.width(), rect.height(), viewport.fLeft, viewport.fTop, viewport.fRight, viewport.fBottom); ALOGV("drawGL, invalRect(%d, %d, %d, %d), webViewRect(%d, %d, %d, %d)" - "clip (%d, %d, %d, %d), scale %f", + "clip/glViewport (%d, %d, %d, %d), scale %f titleBarHeight %d", invalRect->x(), invalRect->y(), invalRect->width(), invalRect->height(), webViewRect.x(), webViewRect.y(), webViewRect.width(), webViewRect.height(), - clip.x(), clip.y(), clip.width(), clip.height(), scale); + clip.x(), clip.y(), clip.width(), clip.height(), scale, titleBarHeight); resetLayersDirtyArea(); diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.h b/Source/WebCore/platform/graphics/android/GLWebViewState.h index 6d969dd..2b28619 100644 --- a/Source/WebCore/platform/graphics/android/GLWebViewState.h +++ b/Source/WebCore/platform/graphics/android/GLWebViewState.h @@ -192,10 +192,6 @@ public: bool goingDown() { return m_goingDown; } bool goingLeft() { return m_goingLeft; } - void setDirection(bool goingDown, bool goingLeft) { - m_goingDown = goingDown; - m_goingLeft = goingLeft; - } float scale() { return m_scale; } diff --git a/Source/WebCore/platform/graphics/android/GradientAndroid.cpp b/Source/WebCore/platform/graphics/android/GradientAndroid.cpp deleted file mode 100644 index 7bc69c5..0000000 --- a/Source/WebCore/platform/graphics/android/GradientAndroid.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2006, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "Gradient.h" - -#include "CSSParser.h" -#include "GraphicsContext.h" -#include "NotImplemented.h" -#include "SkCanvas.h" -#include "SkColorShader.h" -#include "SkGradientShader.h" -#include "SkPaint.h" - -namespace WebCore { - -void Gradient::platformDestroy() -{ - delete m_gradient; - m_gradient = 0; -} - -static U8CPU F2B(float x) -{ - return (int)(x * 255); -} - -SkShader* Gradient::platformGradient() -{ - if (m_gradient) - return m_gradient; - - // need to ensure that the m_stops array is sorted. We call getColor() - // which, as a side effect, does the sort. - // TODO: refactor Gradient.h to formally expose a sort method - { - float r, g, b, a; - this->getColor(0, &r, &g, &b, &a); - } - - SkShader::TileMode mode = SkShader::kClamp_TileMode; - switch (m_spreadMethod) { - case SpreadMethodReflect: - mode = SkShader::kMirror_TileMode; - break; - case SpreadMethodRepeat: - mode = SkShader::kRepeat_TileMode; - break; - case SpreadMethodPad: - mode = SkShader::kClamp_TileMode; - break; - } - - SkPoint pts[2] = { m_p0, m_p1 }; // convert to SkPoint - - const size_t count = m_stops.size(); - SkAutoMalloc storage(count * (sizeof(SkColor) + sizeof(SkScalar))); - SkColor* colors = (SkColor*)storage.get(); - SkScalar* pos = (SkScalar*)(colors + count); - - Vector<ColorStop>::iterator iter = m_stops.begin(); - for (int i = 0; iter != m_stops.end(); i++) { - pos[i] = SkFloatToScalar(iter->stop); - colors[i] = SkColorSetARGB(F2B(iter->alpha), F2B(iter->red), - F2B(iter->green), F2B(iter->blue)); - ++iter; - } - - if (m_radial) { - m_gradient = SkGradientShader::CreateTwoPointRadial(pts[0], - SkFloatToScalar(m_r0), - pts[1], - SkFloatToScalar(m_r1), - colors, pos, count, mode); - } else - m_gradient = SkGradientShader::CreateLinear(pts, colors, pos, count, mode); - - if (!m_gradient) - m_gradient = new SkColorShader(0); - - SkMatrix matrix = m_gradientSpaceTransformation; - m_gradient->setLocalMatrix(matrix); - - return m_gradient; -} - -void Gradient::fill(GraphicsContext* context, const FloatRect& rect) -{ - context->setFillGradient(this); - context->fillRect(rect); -} - - -} //namespace diff --git a/Source/WebCore/platform/graphics/android/context/GraphicsContextAndroid.cpp b/Source/WebCore/platform/graphics/android/context/GraphicsContextAndroid.cpp index 12b53a3..f2d1400 100644 --- a/Source/WebCore/platform/graphics/android/context/GraphicsContextAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/context/GraphicsContextAndroid.cpp @@ -66,13 +66,31 @@ private: PlatformGraphicsContext* m_context; }; -static SkShader* extractShader(Pattern* pat, Gradient* grad) +static void syncPlatformContext(GraphicsContext* gc) { - if (pat) - return pat->platformPattern(AffineTransform()); - else if (grad) - return grad->platformGradient(); - return 0; + // Stroke and fill sometimes reference each other, so always + // sync them both to make sure our state is consistent. + + PlatformGraphicsContext* pgc = gc->platformContext(); + Gradient* grad = gc->state().fillGradient.get(); + Pattern* pat = gc->state().fillPattern.get(); + + if (grad) + pgc->setFillShader(grad->platformGradient()); + else if (pat) + pgc->setFillShader(pat->platformPattern(AffineTransform())); + else + pgc->setFillColor(gc->state().fillColor); + + grad = gc->state().strokeGradient.get(); + pat = gc->state().strokePattern.get(); + + if (grad) + pgc->setStrokeShader(grad->platformGradient()); + else if (pat) + pgc->setStrokeShader(pat->platformPattern(AffineTransform())); + else + pgc->setStrokeColor(gc->state().strokeColor); } //////////////////////////////////////////////////////////////////////////////////////////////// @@ -137,6 +155,7 @@ void GraphicsContext::drawRect(const IntRect& rect) if (paintingDisabled()) return; + syncPlatformContext(this); platformContext()->drawRect(rect); } @@ -146,6 +165,7 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2) if (paintingDisabled()) return; + syncPlatformContext(this); platformContext()->drawLine(point1, point2); } @@ -154,6 +174,7 @@ void GraphicsContext::drawLineForText(const FloatPoint& pt, float width, bool /* if (paintingDisabled()) return; + syncPlatformContext(this); platformContext()->drawLineForText(pt, width); } @@ -163,6 +184,7 @@ void GraphicsContext::drawLineForTextChecking(const FloatPoint& pt, float width, if (paintingDisabled()) return; + syncPlatformContext(this); platformContext()->drawLineForTextChecking(pt, width, style); } @@ -172,6 +194,7 @@ void GraphicsContext::drawEllipse(const IntRect& rect) if (paintingDisabled()) return; + syncPlatformContext(this); platformContext()->drawEllipse(rect); } @@ -180,6 +203,7 @@ void GraphicsContext::strokeArc(const IntRect& r, int startAngle, int angleSpan) if (paintingDisabled()) return; + syncPlatformContext(this); platformContext()->strokeArc(r, startAngle, angleSpan); } @@ -189,6 +213,7 @@ void GraphicsContext::drawConvexPolygon(size_t numPoints, const FloatPoint* poin if (paintingDisabled()) return; + syncPlatformContext(this); platformContext()->drawConvexPolygon(numPoints, points, shouldAntialias); } @@ -199,6 +224,7 @@ void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLef if (paintingDisabled()) return; + syncPlatformContext(this); platformContext()->fillRoundedRect(rect, topLeft, topRight, bottomLeft, bottomRight, color, colorSpace); } @@ -208,6 +234,7 @@ void GraphicsContext::fillRect(const FloatRect& rect) if (paintingDisabled()) return; + syncPlatformContext(this); platformContext()->fillRect(rect); } @@ -216,6 +243,7 @@ void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorS if (paintingDisabled()) return; + syncPlatformContext(this); platformContext()->fillRect(rect, color, colorSpace); } @@ -308,6 +336,7 @@ void GraphicsContext::setupFillPaint(SkPaint* paint) { if (paintingDisabled()) return; + syncPlatformContext(this); platformContext()->setupPaintFill(paint); } @@ -315,6 +344,7 @@ void GraphicsContext::setupStrokePaint(SkPaint* paint) { if (paintingDisabled()) return; + syncPlatformContext(this); platformContext()->setupPaintStroke(paint, 0); } @@ -322,14 +352,12 @@ bool GraphicsContext::setupShadowPaint(SkPaint* paint, SkPoint* offset) { if (paintingDisabled()) return false; + syncPlatformContext(this); return platformContext()->setupPaintShadow(paint, offset); } void GraphicsContext::setPlatformStrokeColor(const Color& c, ColorSpace) { - if (paintingDisabled()) - return; - platformContext()->setStrokeColor(c); } void GraphicsContext::setPlatformStrokeThickness(float f) @@ -348,9 +376,6 @@ void GraphicsContext::setPlatformStrokeStyle(StrokeStyle style) void GraphicsContext::setPlatformFillColor(const Color& c, ColorSpace) { - if (paintingDisabled()) - return; - platformContext()->setFillColor(c); } void GraphicsContext::setPlatformShadow(const FloatSize& size, float blur, const Color& color, ColorSpace) @@ -384,6 +409,7 @@ void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int if (paintingDisabled()) return; + syncPlatformContext(this); platformContext()->drawFocusRing(rects, width, offset, color); } @@ -424,6 +450,7 @@ void GraphicsContext::clearRect(const FloatRect& rect) if (paintingDisabled()) return; + syncPlatformContext(this); platformContext()->clearRect(rect); } @@ -432,6 +459,7 @@ void GraphicsContext::strokeRect(const FloatRect& rect, float lineWidth) if (paintingDisabled()) return; + syncPlatformContext(this); platformContext()->strokeRect(rect, lineWidth); } @@ -520,34 +548,18 @@ void GraphicsContext::setPlatformShouldAntialias(bool useAA) void GraphicsContext::setPlatformFillGradient(Gradient* fillGradient) { - if (paintingDisabled()) - return; - SkShader* shader = extractShader(0, fillGradient); - platformContext()->setFillShader(shader); } void GraphicsContext::setPlatformFillPattern(Pattern* fillPattern) { - if (paintingDisabled()) - return; - SkShader* shader = extractShader(fillPattern, 0); - platformContext()->setFillShader(shader); } void GraphicsContext::setPlatformStrokeGradient(Gradient* strokeGradient) { - if (paintingDisabled()) - return; - SkShader* shader = extractShader(0, strokeGradient); - platformContext()->setStrokeShader(shader); } void GraphicsContext::setPlatformStrokePattern(Pattern* strokePattern) { - if (paintingDisabled()) - return; - SkShader* shader = extractShader(strokePattern, 0); - platformContext()->setStrokeShader(shader); } AffineTransform GraphicsContext::getCTM() const @@ -579,6 +591,7 @@ void GraphicsContext::fillPath(const Path& pathToFill) if (paintingDisabled()) return; + syncPlatformContext(this); platformContext()->fillPath(pathToFill, fillRule()); } @@ -587,6 +600,7 @@ void GraphicsContext::strokePath(const Path& pathToStroke) if (paintingDisabled()) return; + syncPlatformContext(this); platformContext()->strokePath(pathToStroke); } @@ -634,6 +648,7 @@ void GraphicsContext::drawHighlightForText(const Font& font, const TextRun& run, if (paintingDisabled()) return; + syncPlatformContext(this); platformContext()->drawHighlightForText(font, run, point, h, backgroundColor, colorSpace, from, to, isActive); } diff --git a/Source/WebCore/platform/graphics/android/fonts/GlyphMapAndroid.cpp b/Source/WebCore/platform/graphics/android/fonts/GlyphMapAndroid.cpp index a327b79..b9798e6 100644 --- a/Source/WebCore/platform/graphics/android/fonts/GlyphMapAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/fonts/GlyphMapAndroid.cpp @@ -44,12 +44,12 @@ namespace WebCore { #define NO_BREAK_SPACE_UNICHAR 0xA0 -static int substituteWithVerticalGlyphs(const FontPlatformData& platformData, uint16_t* glyphs, unsigned bufferLength) +static HB_Error substituteWithVerticalGlyphs(const FontPlatformData& platformData, uint16_t* glyphs, unsigned bufferLength) { HB_FaceRec_* hbFace = platformData.harfbuzzFace(); if (!hbFace->gsub) { // if there is no GSUB table, treat it as not covered - return 0Xffff; + return static_cast<HB_Error>(0Xffff); } HB_Buffer buffer; @@ -60,13 +60,19 @@ static int substituteWithVerticalGlyphs(const FontPlatformData& platformData, ui HB_UShort scriptIndex; HB_UShort featureIndex; - HB_GSUB_Select_Script(hbFace->gsub, HB_MAKE_TAG('D', 'F', 'L', 'T'), &scriptIndex); + HB_Error error = HB_GSUB_Select_Script(hbFace->gsub, HB_MAKE_TAG('D', 'F', 'L', 'T'), &scriptIndex); + if (error) { + if (error != HB_Err_Not_Covered) + return error; + scriptIndex = HB_Script_Common; // Set script to common script. + } + HB_GSUB_Select_Feature(hbFace->gsub, HB_MAKE_TAG('v', 'e', 'r', 't'), scriptIndex, 0xffff, &featureIndex); HB_GSUB_Add_Feature(hbFace->gsub, featureIndex, 1); HB_GSUB_Select_Feature(hbFace->gsub, HB_MAKE_TAG('v', 'r', 't', '2'), scriptIndex, 0xffff, &featureIndex); HB_GSUB_Add_Feature(hbFace->gsub, featureIndex, 1); - int error = HB_GSUB_Apply_String(hbFace->gsub, buffer); + error = HB_GSUB_Apply_String(hbFace->gsub, buffer); if (!error) { for (unsigned i = 0; i < bufferLength; ++i) glyphs[i] = static_cast<Glyph>(buffer->out_string[i].gindex); @@ -74,6 +80,14 @@ static int substituteWithVerticalGlyphs(const FontPlatformData& platformData, ui return error; } +static void convertToVerticalForms(UChar* src, UChar* dest, unsigned bufferLength) { + for (unsigned i = 0; i < bufferLength; ++i) { + dest[i] = VerticalTextMap::getVerticalForm(src[i]); + if (!dest[i]) + dest[i] = src[i]; + } +} + bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned bufferLength, const SimpleFontData* fontData) { if (SkUTF16_IsHighSurrogate(buffer[bufferLength-1])) { @@ -92,11 +106,7 @@ bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned b if (fontData->platformData().orientation() == Vertical && !fontData->hasVerticalGlyphs()) { // Convert to vertical form if there is no vertical glyphs. - for (unsigned i = 0; i < bufferLength; ++i) { - vTextBuffer[i] = VerticalTextMap::getVerticalForm(buffer[i]); - if (!vTextBuffer[i]) - vTextBuffer[i] = buffer[i]; - } + convertToVerticalForms(buffer, vTextBuffer, bufferLength); textBuffer = vTextBuffer; } @@ -111,11 +121,22 @@ bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned b for (unsigned i = 0; i < bufferLength; ++i) { if (!Font::isCJKIdeograph(textBuffer[i])) { lookVariants = true; - continue; + break; + } + } + if (lookVariants) { + if (substituteWithVerticalGlyphs(fontData->platformData(), glyphs, bufferLength)) { + // Convert text to vertical forms if substituteWithVerticalGlyphs() fails to access vert tables. + convertToVerticalForms(buffer, vTextBuffer, bufferLength); + textBuffer = vTextBuffer; + + unsigned count = paint.textToGlyphs(textBuffer, bufferLength << 1, glyphs); + if (count != length) { + SkDebugf("%s count != length\n", __FUNCTION__); + return false; + } } } - if (lookVariants) - substituteWithVerticalGlyphs(fontData->platformData(), glyphs, bufferLength); } unsigned allGlyphs = 0; // track if any of the glyphIDs are non-zero diff --git a/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp index 1de5ae7..ce520b4 100644 --- a/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp @@ -53,4 +53,17 @@ void BaseLayerAndroid::getLocalTransform(SkMatrix* matrix) const matrix->preConcat(getMatrix()); } +IFrameLayerAndroid* BaseLayerAndroid::updatePosition(SkRect viewport, + IFrameLayerAndroid* parentIframeLayer) +{ + if (viewport.fRight > getWidth() || viewport.fBottom > getHeight()) { + // To handle the viewport expanding past the layer's size with HW accel, + // expand the size of the layer, so that tiles will cover the viewport. + setSize(std::max(viewport.fRight, getWidth()), + std::max(viewport.fBottom, getHeight())); + } + + return LayerAndroid::updatePosition(viewport, parentIframeLayer); +} + } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.h b/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.h index 0ef39c8..f4cf9f3 100644 --- a/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.h +++ b/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.h @@ -49,6 +49,8 @@ public: virtual void getLocalTransform(SkMatrix* matrix) const; virtual const TransformationMatrix* drawTransform() const { return 0; } + virtual IFrameLayerAndroid* updatePosition(SkRect viewport, + IFrameLayerAndroid* parentIframeLayer); private: // TODO: move to SurfaceCollection. Color m_color; diff --git a/Source/WebCore/platform/graphics/android/layers/Layer.h b/Source/WebCore/platform/graphics/android/layers/Layer.h index 996547b..d87c699 100644 --- a/Source/WebCore/platform/graphics/android/layers/Layer.h +++ b/Source/WebCore/platform/graphics/android/layers/Layer.h @@ -157,6 +157,9 @@ protected: bool m_hasOverflowChildren; + // invalidation region + SkRegion m_dirtyRegion; +private: bool isAncestor(const Layer*) const; Layer* fParent; @@ -173,9 +176,6 @@ protected: SkTDArray<Layer*> m_children; - // invalidation region - SkRegion m_dirtyRegion; - WebCore::GLWebViewState* m_state; typedef SkRefCnt INHERITED; diff --git a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp index df3fa42..a02759d 100644 --- a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp @@ -254,7 +254,7 @@ void LayerAndroid::addDirtyArea() area.intersect(clip); IntRect dirtyArea(area.x(), area.y(), area.width(), area.height()); - m_state->addDirtyArea(dirtyArea); + state()->addDirtyArea(dirtyArea); } void LayerAndroid::addAnimation(PassRefPtr<AndroidAnimation> prpAnim) @@ -411,7 +411,6 @@ void LayerAndroid::updatePositions() void LayerAndroid::updateGLPositionsAndScale(const TransformationMatrix& parentMatrix, const FloatRect& clipping, float opacity, float scale) { - m_atomicSync.lock(); IntSize layerSize(getSize().width(), getSize().height()); FloatPoint anchorPoint(getAnchorPoint().fX, getAnchorPoint().fY); FloatPoint position(getPosition().fX - m_offset.x(), getPosition().fY - m_offset.y()); @@ -428,7 +427,6 @@ void LayerAndroid::updateGLPositionsAndScale(const TransformationMatrix& parentM -originY, -anchorPointZ()); - m_atomicSync.unlock(); setDrawTransform(localMatrix); if (m_drawTransform.isIdentityOrTranslation()) { // adjust the translation coordinates of the draw transform matrix so @@ -610,50 +608,6 @@ void LayerAndroid::mergeInvalsInto(LayerAndroid* replacementTree) replacementLayer->markAsDirty(m_dirtyRegion); } -bool LayerAndroid::updateWithTree(LayerAndroid* newTree) -{ -// Disable fast update for now -#if (0) - bool needsRepaint = false; - int count = this->countChildren(); - for (int i = 0; i < count; i++) - needsRepaint |= this->getChild(i)->updateWithTree(newTree); - - if (newTree) { - LayerAndroid* newLayer = newTree->findById(uniqueId()); - needsRepaint |= updateWithLayer(newLayer); - } - return needsRepaint; -#else - return true; -#endif -} - -// Return true to indicate to WebViewCore that the updates -// are too complicated to be fully handled and we need a full -// call to webkit (e.g. handle repaints) -bool LayerAndroid::updateWithLayer(LayerAndroid* layer) -{ - if (!layer) - return true; - - android::AutoMutex lock(m_atomicSync); - m_position = layer->m_position; - m_anchorPoint = layer->m_anchorPoint; - m_size = layer->m_size; - m_opacity = layer->m_opacity; - m_transform = layer->m_transform; - - if (m_imageCRC != layer->m_imageCRC) - m_visible = false; - - if ((m_content != layer->m_content) - || (m_imageCRC != layer->m_imageCRC)) - return true; - - return false; -} - static inline bool compareLayerZ(const LayerAndroid* a, const LayerAndroid* b) { return a->zValue() > b->zValue(); @@ -857,7 +811,7 @@ bool LayerAndroid::drawGL(bool layerTilesDisabled) ImagesManager::instance()->releaseImage(m_imageCRC); } - m_state->glExtras()->drawGL(this); + state()->glExtras()->drawGL(this); bool askScreenUpdate = false; m_atomicSync.lock(); @@ -930,7 +884,8 @@ void LayerAndroid::onDraw(SkCanvas* canvas, SkScalar opacity, return; } - if (masksToBounds() || !m_content) + // only continue drawing if layer is drawable + if (!m_content && !m_imageCRC) return; // we just have this save/restore for opacity... diff --git a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h index 6239418..9a803a9 100644 --- a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h +++ b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h @@ -257,12 +257,6 @@ public: friend LayerAndroid* android::deserializeLayer(int version, SkStream* stream); friend void android::cleanupImageRefs(LayerAndroid* layer); - // Update layers using another tree. Only works for basic properties - // such as the position, the transform. Return true if anything more - // complex is needed. - bool updateWithTree(LayerAndroid*); - virtual bool updateWithLayer(LayerAndroid*); - LayerType type() { return m_type; } virtual SubclassType subclassType() { return LayerAndroid::StandardLayer; } diff --git a/Source/WebCore/platform/graphics/android/layers/ScrollableLayerAndroid.h b/Source/WebCore/platform/graphics/android/layers/ScrollableLayerAndroid.h index 1f289e6..52f5e7e 100644 --- a/Source/WebCore/platform/graphics/android/layers/ScrollableLayerAndroid.h +++ b/Source/WebCore/platform/graphics/android/layers/ScrollableLayerAndroid.h @@ -43,8 +43,6 @@ public: virtual LayerAndroid* copy() const { return new ScrollableLayerAndroid(*this); } virtual SubclassType subclassType() { return LayerAndroid::ScrollableLayer; } - virtual bool updateWithLayer(LayerAndroid*) { return true; } - // Scrolls to the given position in the layer. // Returns whether or not any scrolling was required. virtual bool scrollTo(int x, int y); diff --git a/Source/WebCore/platform/graphics/android/rendering/BaseRenderer.cpp b/Source/WebCore/platform/graphics/android/rendering/BaseRenderer.cpp index 833aea9..8bb1755 100644 --- a/Source/WebCore/platform/graphics/android/rendering/BaseRenderer.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/BaseRenderer.cpp @@ -112,7 +112,7 @@ void BaseRenderer::renderTiledContent(TileRenderInfo& renderInfo) setupPartialInval(renderInfo, &canvas); canvas.translate(-renderInfo.x * tileSize.width(), -renderInfo.y * tileSize.height()); canvas.scale(renderInfo.scale, renderInfo.scale); - renderInfo.tilePainter->paint(renderInfo.baseTile, &canvas); + renderInfo.tilePainter->paint(&canvas); if (renderInfo.baseTile && renderInfo.baseTile->backTexture()) checkForPureColor(renderInfo, &canvas); else diff --git a/Source/WebCore/platform/graphics/android/rendering/GLUtils.cpp b/Source/WebCore/platform/graphics/android/rendering/GLUtils.cpp index 26bd55d..9435065 100644 --- a/Source/WebCore/platform/graphics/android/rendering/GLUtils.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/GLUtils.cpp @@ -578,16 +578,6 @@ void GLUtils::createTextureWithBitmap(GLuint texture, const SkBitmap& bitmap, GL } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); - - // The following is a workaround -- remove when EGLImage texture upload is fixed. - GLuint fboID; - glGenFramebuffers(1, &fboID); - glBindFramebuffer(GL_FRAMEBUFFER, fboID); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); - glCheckFramebufferStatus(GL_FRAMEBUFFER); // should return GL_FRAMEBUFFER_COMPLETE - - glBindFramebuffer(GL_FRAMEBUFFER, 0); // rebind the standard FBO - glDeleteFramebuffers(1, &fboID); } void GLUtils::updateTextureWithBitmap(GLuint texture, const SkBitmap& bitmap, diff --git a/Source/WebCore/platform/graphics/android/rendering/ImageTexture.cpp b/Source/WebCore/platform/graphics/android/rendering/ImageTexture.cpp index b2ead6a..cd43c03 100644 --- a/Source/WebCore/platform/graphics/android/rendering/ImageTexture.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/ImageTexture.cpp @@ -174,8 +174,8 @@ bool ImageTexture::prepareGL(GLWebViewState* state) return false; if (!m_texture && m_picture) { - bool isLayerTile = true; - m_texture = new TileGrid(isLayerTile); + bool isBaseSurface = false; + m_texture = new TileGrid(isBaseSurface); SkRegion region; region.setRect(0, 0, m_image->width(), m_image->height()); m_texture->markAsDirty(region); @@ -198,8 +198,6 @@ const TransformationMatrix* ImageTexture::transform() if (!m_layer) return 0; - FloatPoint p(0, 0); - p = m_layer->drawTransform()->mapPoint(p); IntRect layerArea = m_layer->unclippedArea(); float scaleW = static_cast<float>(layerArea.width()) / static_cast<float>(m_image->width()); float scaleH = static_cast<float>(layerArea.height()) / static_cast<float>(m_image->height()); @@ -217,14 +215,14 @@ float ImageTexture::opacity() return m_layer->drawOpacity(); } -bool ImageTexture::paint(Tile* tile, SkCanvas* canvas) +bool ImageTexture::paint(SkCanvas* canvas) { if (!m_picture) { ALOGV("IT %p COULDNT PAINT, NO PICTURE", this); return false; } - ALOGV("IT %p painting tile %d, %d with picture %p", this, tile->x(), tile->y(), m_picture); + ALOGV("IT %p painting with picture %p", this, m_picture); canvas->drawPicture(*m_picture); return true; diff --git a/Source/WebCore/platform/graphics/android/rendering/ImageTexture.h b/Source/WebCore/platform/graphics/android/rendering/ImageTexture.h index 34430f1..9e1de32 100644 --- a/Source/WebCore/platform/graphics/android/rendering/ImageTexture.h +++ b/Source/WebCore/platform/graphics/android/rendering/ImageTexture.h @@ -86,7 +86,7 @@ public: bool equalsCRC(unsigned crc); // methods used by TileGrid - virtual bool paint(Tile* tile, SkCanvas* canvas); + virtual bool paint(SkCanvas* canvas); virtual float opacity(); int nbTextures(); diff --git a/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp index a0d9e56..40bf0be 100644 --- a/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp @@ -385,7 +385,22 @@ void ShaderProgram::setupDrawing(const IntRect& viewRect, const SkRect& visibleR TransformationMatrix orthoScale; orthoScale.scale3d(orthoScaleX, orthoScaleY, 1.0); - m_projectionMatrix = ortho * orthoScale; + m_visibleRectProjectionMatrix = ortho * orthoScale; + + ALOGV("set m_clipProjectionMatrix, %d, %d, %d, %d", + screenClip.x(), screenClip.y(), screenClip.x() + screenClip.width(), + screenClip.y() + screenClip.height()); + + // In order to incorporate the animation delta X and Y, using the clip as + // the GL viewport can save all the trouble of re-position from webViewRect + // to final position. + GLUtils::setOrthographicMatrix(m_clipProjectionMatrix, screenClip.x(), screenClip.y(), + screenClip.x() + screenClip.width(), + screenClip.y() + screenClip.height(), -1000, 1000); + + glViewport(screenClip.x(), m_targetHeight - screenClip.y() - screenClip.height() , + screenClip.width(), screenClip.height()); + m_viewport = visibleRect; m_currentScale = scale; @@ -402,10 +417,10 @@ void ShaderProgram::setupDrawing(const IntRect& viewRect, const SkRect& visibleR TransformationMatrix viewScale; viewScale.scale3d(m_viewRect.width() * 0.5f, m_viewRect.height() * 0.5f, 1); - m_documentToScreenMatrix = viewScale * viewTranslate * m_projectionMatrix; + m_documentToScreenMatrix = viewScale * viewTranslate * m_visibleRectProjectionMatrix; viewTranslate.scale3d(1, -1, 1); - m_documentToInvScreenMatrix = viewScale * viewTranslate * m_projectionMatrix; + m_documentToInvScreenMatrix = viewScale * viewTranslate * m_visibleRectProjectionMatrix; IntRect rect(0, 0, m_webViewRect.width(), m_webViewRect.height()); m_documentViewport = m_documentToScreenMatrix.inverse().mapRect(rect); @@ -422,6 +437,10 @@ void ShaderProgram::setupDrawing(const IntRect& viewRect, const SkRect& visibleR m_screenClip.setSize(IntSize(ceilf(tclip.width()), ceilf(tclip.height()))); resetBlending(); + + // Set up m_clipProjectionMatrix, m_currentScale and m_webViewMatrix before + // calling this function. + setupSurfaceProjectionMatrix(); } // Calculate the right color value sent into the shader considering the (0,1) @@ -559,7 +578,7 @@ float ShaderProgram::zValue(const TransformationMatrix& drawMatrix, float w, flo { TransformationMatrix modifiedDrawMatrix = drawMatrix; modifiedDrawMatrix.scale3d(w, h, 1); - TransformationMatrix renderMatrix = m_projectionMatrix * modifiedDrawMatrix; + TransformationMatrix renderMatrix = m_visibleRectProjectionMatrix * modifiedDrawMatrix; FloatPoint3D point(0.5, 0.5, 0.0); FloatPoint3D result = renderMatrix.mapPoint(point); return result.z(); @@ -598,27 +617,47 @@ void ShaderProgram::drawQuadInternal(ShaderType type, const GLfloat* matrix, glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } +// Put the common matrix computation at higher level to avoid redundancy. +void ShaderProgram::setupSurfaceProjectionMatrix() +{ + TransformationMatrix scaleMatrix; + scaleMatrix.scale3d(m_currentScale, m_currentScale, 1); + m_surfaceProjectionMatrix = m_clipProjectionMatrix * m_webViewMatrix * scaleMatrix; +} + // Calculate the matrix given the geometry. -GLfloat* ShaderProgram::getProjectionMatrix(const DrawQuadData* data) +GLfloat* ShaderProgram::getTileProjectionMatrix(const DrawQuadData* data) { DrawQuadType type = data->type(); - const TransformationMatrix* matrix = data->drawMatrix(); - const SkRect* geometry = data->geometry(); if (type == Blit) return m_transferProjMtx; + + const TransformationMatrix* matrix = data->drawMatrix(); + const SkRect* geometry = data->geometry(); + + // This modifiedDrawMatrix tranform (0,0)(1x1) to the final rect in screen + // coordinate, before applying the m_webViewMatrix. + // It first scale and translate the vertex array from (0,0)(1x1) to real + // tile position and size. Then apply the transform from the layer's. + // Finally scale to the currentScale to support zooming. + // Note the geometry contains the tile zoom scale, so visually we will see + // the tiles scale at a ratio as (m_currentScale/tile's scale). TransformationMatrix modifiedDrawMatrix; if (type == LayerQuad) modifiedDrawMatrix = *matrix; - // move the drawing depending on where the texture is on the layer modifiedDrawMatrix.translate(geometry->fLeft, geometry->fTop); modifiedDrawMatrix.scale3d(geometry->width(), geometry->height(), 1); + // Even when we are on a alpha layer or not, we need to respect the + // m_webViewMatrix, it may contain the layout offset. Normally it is + // identity. TransformationMatrix renderMatrix; - if (!m_alphaLayer) - renderMatrix = m_projectionMatrix * m_repositionMatrix - * m_webViewMatrix * modifiedDrawMatrix; - else - renderMatrix = m_projectionMatrix * modifiedDrawMatrix; + renderMatrix = m_surfaceProjectionMatrix * modifiedDrawMatrix; + +#if DEBUG_MATRIX + debugMatrixInfo(m_currentScale, m_clipProjectionMatrix, m_webViewMatrix, + modifiedDrawMatrix, matrix); +#endif GLUtils::toGLMatrix(m_tileProjMatrix, renderMatrix); return m_tileProjMatrix; @@ -626,7 +665,7 @@ GLfloat* ShaderProgram::getProjectionMatrix(const DrawQuadData* data) void ShaderProgram::drawQuad(const DrawQuadData* data) { - GLfloat* matrix = getProjectionMatrix(data); + GLfloat* matrix = getTileProjectionMatrix(data); float opacity = data->opacity(); bool forceBlending = data->forceBlending(); @@ -661,11 +700,14 @@ void ShaderProgram::drawVideoLayerQuad(const TransformationMatrix& drawMatrix, { // switch to our custom yuv video rendering program glUseProgram(m_handleArray[Video].programHandle); - - TransformationMatrix modifiedDrawMatrix = drawMatrix; + // TODO: Merge drawVideoLayerQuad into drawQuad. + TransformationMatrix modifiedDrawMatrix; + modifiedDrawMatrix.scale3d(m_currentScale, m_currentScale, 1); + modifiedDrawMatrix.multiply(drawMatrix); modifiedDrawMatrix.translate(geometry.fLeft, geometry.fTop); modifiedDrawMatrix.scale3d(geometry.width(), geometry.height(), 1); - TransformationMatrix renderMatrix = m_projectionMatrix * modifiedDrawMatrix; + TransformationMatrix renderMatrix = + m_clipProjectionMatrix * m_webViewMatrix * modifiedDrawMatrix; GLfloat projectionMatrix[16]; GLUtils::toGLMatrix(projectionMatrix, renderMatrix); @@ -687,44 +729,61 @@ void ShaderProgram::drawVideoLayerQuad(const TransformationMatrix& drawMatrix, glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } -void ShaderProgram::setWebViewMatrix(const float* matrix, bool alphaLayer) +void ShaderProgram::setGLDrawInfo(const android::uirenderer::DrawGlInfo* info) { - GLUtils::convertToTransformationMatrix(matrix, m_webViewMatrix); - m_alphaLayer = alphaLayer; + GLUtils::convertToTransformationMatrix(info->transform, m_webViewMatrix); + m_alphaLayer = info->isLayer; + m_targetHeight = info->height; } -void ShaderProgram::calculateAnimationDelta() +#if DEBUG_MATRIX +FloatRect ShaderProgram::debugMatrixTransform(const TransformationMatrix& matrix, + const char* matrixName) { - // The matrix contains the scrolling info, so this rect is starting from - // the m_viewport. - // So we just need to map the webview's visible rect using the matrix, - // calculate the difference b/t transformed rect and the webViewRect, - // then we can get the delta x , y caused by the animation. - // Note that the Y is for reporting back to GL viewport, so it is inverted. - // When it is alpha animation, then we rely on the framework implementation - // such that there is no matrix applied in native webkit. - if (!m_alphaLayer) { - FloatRect rect(m_viewport.fLeft * m_currentScale, - m_viewport.fTop * m_currentScale, - m_webViewRect.width(), - m_webViewRect.height()); - rect = m_webViewMatrix.mapRect(rect); - m_animationDelta.setX(rect.x() - m_webViewRect.x() ); - m_animationDelta.setY(rect.y() + rect.height() - m_webViewRect.y() - - m_webViewRect.height() - m_titleBarHeight); - - m_repositionMatrix.makeIdentity(); - m_repositionMatrix.translate3d(-m_webViewRect.x(), -m_webViewRect.y() - m_titleBarHeight, 0); - m_repositionMatrix.translate3d(m_viewport.fLeft * m_currentScale, m_viewport.fTop * m_currentScale, 0); - m_repositionMatrix.translate3d(-m_animationDelta.x(), -m_animationDelta.y(), 0); - } else { - m_animationDelta.setX(0); - m_animationDelta.setY(0); - m_repositionMatrix.makeIdentity(); - } + FloatRect rect(0.0, 0.0, 1.0, 1.0); + rect = matrix.mapRect(rect); + ALOGV("After %s matrix:\n %f, %f rect.width() %f rect.height() %f", + matrixName, rect.x(), rect.y(), rect.width(), rect.height()); + return rect; } -} // namespace WebCore +void ShaderProgram::debugMatrixInfo(float currentScale, + const TransformationMatrix& clipProjectionMatrix, + const TransformationMatrix& webViewMatrix, + const TransformationMatrix& modifiedDrawMatrix, + const TransformationMatrix* layerMatrix) +{ + int viewport[4]; + glGetIntegerv(GL_VIEWPORT, viewport); + ALOGV("viewport %d, %d, %d, %d , currentScale %f", + viewport[0], viewport[1], viewport[2], viewport[3], currentScale); + IntRect currentGLViewport(viewport[0], viewport[1], viewport[2], viewport[3]); + + TransformationMatrix scaleMatrix; + scaleMatrix.scale3d(currentScale, currentScale, 1.0); + + if (layerMatrix) + debugMatrixTransform(*layerMatrix, "layerMatrix"); + + TransformationMatrix debugMatrix = scaleMatrix * modifiedDrawMatrix; + debugMatrixTransform(debugMatrix, "scaleMatrix * modifiedDrawMatrix"); + + debugMatrix = webViewMatrix * debugMatrix; + debugMatrixTransform(debugMatrix, "webViewMatrix * scaleMatrix * modifiedDrawMatrix"); + + debugMatrix = clipProjectionMatrix * debugMatrix; + FloatRect finalRect = + debugMatrixTransform(debugMatrix, "all Matrix"); + // After projection, we will be in a (-1, 1) range and now we can map it back + // to the (x,y) -> (x+width, y+height) + ALOGV("final convert to screen coord x, y %f, %f width %f height %f , ", + (finalRect.x() + 1) / 2 * currentGLViewport.width() + currentGLViewport.x(), + (finalRect.y() + 1) / 2 * currentGLViewport.height() + currentGLViewport.y(), + finalRect.width() * currentGLViewport.width() / 2, + finalRect.height() * currentGLViewport.height() / 2); +} +#endif // DEBUG_MATRIX +} // namespace WebCore #endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h index b233f2b..b44c563 100644 --- a/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h +++ b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h @@ -24,9 +24,11 @@ #include "IntRect.h" #include "SkRect.h" #include "TransformationMatrix.h" +#include "private/hwui/DrawGlInfo.h" #include <GLES2/gl2.h> #define MAX_CONTRAST 5 +#define DEBUG_MATRIX 0 namespace WebCore { @@ -150,24 +152,14 @@ public: contrast = MAX_CONTRAST; m_contrast = contrast; } - void setWebViewMatrix(const float* matrix, bool alphaLayer); - - // This delta is the delta from the layout pos and the current animation pos. - // Basically, in terms of layout, the webview is still in the original layout - // pos, as without animation. Such that the viewport and visible rect etc are - // still in that pos, too, except the clipping info. - // Our rendering approach is after applying all the matrix, webView is - // rendered as if it was at the original layout pos, but then offset the - // glViewport to match the animation. - void calculateAnimationDelta(); - int getAnimationDeltaX() { return m_animationDelta.x(); } - int getAnimationDeltaY() { return m_animationDelta.y(); } + void setGLDrawInfo(const android::uirenderer::DrawGlInfo* info); + bool needsInit() { return m_needsInit; } private: GLuint loadShader(GLenum shaderType, const char* pSource); GLint createProgram(const char* vertexSource, const char* fragmentSource); - GLfloat* getProjectionMatrix(const DrawQuadData* data); + GLfloat* getTileProjectionMatrix(const DrawQuadData* data); void setBlendingState(bool enableBlending); void drawQuadInternal(ShaderType type, const GLfloat* matrix, int textureId, float opacity, GLenum textureTarget, GLenum filter, @@ -175,10 +167,21 @@ private: Color shaderColor(Color pureColor, float opacity); ShaderType getTextureShaderType(GLenum textureTarget); void resetBlending(); + void setupSurfaceProjectionMatrix(); +#if DEBUG_MATRIX + FloatRect debugMatrixTransform(const TransformationMatrix& matrix, const char* matrixName); + void debugMatrixInfo(float currentScale, + const TransformationMatrix& clipProjectionMatrix, + const TransformationMatrix& webViewMatrix, + const TransformationMatrix& modifiedDrawMatrix, + const TransformationMatrix* layerMatrix); +#endif // DEBUG_MATRIX bool m_blendingEnabled; - TransformationMatrix m_projectionMatrix; + TransformationMatrix m_surfaceProjectionMatrix; + TransformationMatrix m_clipProjectionMatrix; + TransformationMatrix m_visibleRectProjectionMatrix; GLuint m_textureBuffer[1]; TransformationMatrix m_documentToScreenMatrix; @@ -188,28 +191,20 @@ private: FloatRect m_clipRect; IntRect m_screenClip; int m_titleBarHeight; + // This is the layout position in screen coordinate and didn't contain the + // animation offset. IntRect m_webViewRect; FloatRect m_documentViewport; float m_contrast; + // The height of the render target, either FBO or screen. + int m_targetHeight; bool m_alphaLayer; TransformationMatrix m_webViewMatrix; float m_currentScale; - // After the webViewTranform, we need to reposition the rect to match our viewport. - // Basically, the webViewTransformMatrix should apply on the screen resolution. - // So we start by doing the scale and translate to get each tile into screen coordinates. - // After applying the webViewTransformMatrix, b/c the way it currently set up - // for scroll and titlebar, we need to offset both of them. - // Finally, map everything back to (-1, 1) by using the m_projectionMatrix. - // TODO: Given that m_webViewMatrix contains most of the tranformation - // information, we should be able to get rid of some parameter we got from - // Java side and simplify our code. - TransformationMatrix m_repositionMatrix; - IntPoint m_animationDelta; - // Put all the uniform location (handle) info into an array, and group them // by the shader's type, this can help to clean up the interface. // TODO: use the type and data comparison to skip GL call if possible. diff --git a/Source/WebCore/platform/graphics/android/rendering/Surface.cpp b/Source/WebCore/platform/graphics/android/rendering/Surface.cpp index 3ed3aad..a9ebd1e 100644 --- a/Source/WebCore/platform/graphics/android/rendering/Surface.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/Surface.cpp @@ -30,6 +30,7 @@ #include "Surface.h" #include "AndroidLog.h" +#include "BaseLayerAndroid.h" #include "ClassTracker.h" #include "LayerAndroid.h" #include "GLWebViewState.h" @@ -140,6 +141,9 @@ void Surface::addLayer(LayerAndroid* layer, const TransformationMatrix& transfor m_unclippedArea.x(), m_unclippedArea.y(), m_unclippedArea.width(), m_unclippedArea.height()); } + + if (isBase()) + m_background = static_cast<BaseLayerAndroid*>(layer)->getBackgroundColor(); } IntRect Surface::visibleArea() @@ -224,7 +228,7 @@ bool Surface::drawGL(bool layerTilesDisabled) // TODO: why this visibleArea is different from visibleRect at zooming for base? IntRect drawArea = visibleArea(); m_surfaceBacking->drawGL(drawArea, opacity(), drawTransform(), - useAggressiveRendering(), background()); + useAggressiveRendering(), background()); } // draw member layers (draws image textures, glextras) @@ -250,6 +254,14 @@ bool Surface::isReady() return m_surfaceBacking->isReady(); } +bool Surface::isMissingContent() +{ + if (!m_surfaceBacking) + return true; + + return m_surfaceBacking->isMissingContent(); +} + IntRect Surface::computePrepareArea() { IntRect area; @@ -286,7 +298,7 @@ bool Surface::isBase() return getFirstLayer()->subclassType() == LayerAndroid::BaseLayer; } -bool Surface::paint(Tile* tile, SkCanvas* canvas) +bool Surface::paint(SkCanvas* canvas) { if (singleLayer()) { getFirstLayer()->contentDraw(canvas, Layer::UnmergedLayers); diff --git a/Source/WebCore/platform/graphics/android/rendering/Surface.h b/Source/WebCore/platform/graphics/android/rendering/Surface.h index 27c997e..0fced47 100644 --- a/Source/WebCore/platform/graphics/android/rendering/Surface.h +++ b/Source/WebCore/platform/graphics/android/rendering/Surface.h @@ -53,17 +53,17 @@ public: bool drawGL(bool layerTilesDisabled); void swapTiles(); bool isReady(); + bool isMissingContent(); void computeTexturesAmount(TexturesResult* result); - LayerAndroid* getFirstLayer() { return m_layers[0]; } + LayerAndroid* getFirstLayer() const { return m_layers[0]; } bool needsTexture() { return m_needsTexture; } bool hasText() { return m_hasText; } bool isBase(); - void setBackground(Color background) { m_background = background; } // TilePainter methods - virtual bool paint(Tile* tile, SkCanvas* canvas); + virtual bool paint(SkCanvas* canvas); virtual float opacity(); virtual Color* background(); @@ -72,7 +72,6 @@ private: IntRect visibleArea(); IntRect unclippedArea(); bool singleLayer() { return m_layers.size() == 1; } - void updateBackground(const Color& background); bool useAggressiveRendering(); const TransformationMatrix* drawTransform(); diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.cpp b/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.cpp index 7c8f570..b8d751c 100644 --- a/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.cpp @@ -42,6 +42,7 @@ SurfaceBacking::SurfaceBacking(bool isBaseSurface) { m_frontTexture = new TileGrid(isBaseSurface); m_backTexture = new TileGrid(isBaseSurface); + m_lowResTexture = new TileGrid(isBaseSurface); m_scale = -1; m_futureScale = -1; m_zooming = false; @@ -51,6 +52,7 @@ SurfaceBacking::~SurfaceBacking() { delete m_frontTexture; delete m_backTexture; + delete m_lowResTexture; } void SurfaceBacking::prepareGL(GLWebViewState* state, bool allowZoom, @@ -70,6 +72,9 @@ void SurfaceBacking::prepareGL(GLWebViewState* state, bool allowZoom, m_futureScale = scale; m_zoomUpdateTime = WTF::currentTime() + SurfaceBacking::s_zoomUpdateDelay; m_zooming = true; + + // release back texture's TileTextures, so they can be reused immediately + m_backTexture->discardTextures(); } bool useExpandPrefetch = aggressiveRendering; @@ -77,39 +82,43 @@ void SurfaceBacking::prepareGL(GLWebViewState* state, bool allowZoom, this, scale, m_scale, m_futureScale, m_zooming, m_frontTexture, m_backTexture); - if (!m_zooming) { - m_frontTexture->prepareGL(state, m_scale, - prepareArea, unclippedArea, painter, false, useExpandPrefetch); - if (aggressiveRendering) { - // prepare the back tiled texture to render content in low res - float lowResPrefetchScale = m_scale * LOW_RES_PREFETCH_SCALE_MODIFIER; - m_backTexture->prepareGL(state, lowResPrefetchScale, - prepareArea, unclippedArea, painter, true, useExpandPrefetch); - m_backTexture->swapTiles(); - } - } else if (m_zoomUpdateTime < WTF::currentTime()) { + if (m_zooming && (m_zoomUpdateTime < WTF::currentTime())) { m_backTexture->prepareGL(state, m_futureScale, - prepareArea, unclippedArea, painter, false, useExpandPrefetch); + prepareArea, unclippedArea, painter, false, false); if (m_backTexture->isReady()) { // zooming completed, swap the textures and new front tiles swapTileGrids(); m_frontTexture->swapTiles(); m_backTexture->discardTextures(); + m_lowResTexture->discardTextures(); m_scale = m_futureScale; m_zooming = false; } } + + if (!m_zooming) { + m_frontTexture->prepareGL(state, m_scale, + prepareArea, unclippedArea, painter, false, useExpandPrefetch); + if (aggressiveRendering) { + // prepare low res content + float lowResPrefetchScale = m_scale * LOW_RES_PREFETCH_SCALE_MODIFIER; + m_lowResTexture->prepareGL(state, lowResPrefetchScale, + prepareArea, unclippedArea, painter, + true, useExpandPrefetch); + m_lowResTexture->swapTiles(); + } + } } void SurfaceBacking::drawGL(const IntRect& visibleArea, float opacity, const TransformationMatrix* transform, bool aggressiveRendering, const Color* background) { - // draw low res prefetch page, if needed - if (aggressiveRendering && !m_zooming && m_frontTexture->isMissingContent()) - m_backTexture->drawGL(visibleArea, opacity, transform); + // draw low res prefetch page if zooming or front texture missing content + if (aggressiveRendering && isMissingContent()) + m_lowResTexture->drawGL(visibleArea, opacity, transform); m_frontTexture->drawGL(visibleArea, opacity, transform, background); } @@ -118,12 +127,14 @@ void SurfaceBacking::markAsDirty(const SkRegion& dirtyArea) { m_backTexture->markAsDirty(dirtyArea); m_frontTexture->markAsDirty(dirtyArea); + m_lowResTexture->markAsDirty(dirtyArea); } void SurfaceBacking::swapTiles() { m_backTexture->swapTiles(); m_frontTexture->swapTiles(); + m_lowResTexture->swapTiles(); } void SurfaceBacking::computeTexturesAmount(TexturesResult* result, LayerAndroid* layer) diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.h b/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.h index b04e462..bbac9b5 100644 --- a/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.h +++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.h @@ -59,6 +59,11 @@ public: return !m_zooming && m_frontTexture->isReady() && m_scale > 0; } + bool isMissingContent() + { + return m_zooming || m_frontTexture->isMissingContent(); + } + int nbTextures(IntRect& area, float scale) { // TODO: consider the zooming case for the backTexture @@ -75,6 +80,8 @@ private: TileGrid* m_frontTexture; TileGrid* m_backTexture; + TileGrid* m_lowResTexture; + float m_scale; float m_futureScale; double m_zoomUpdateTime; diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.cpp b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.cpp index 0bbaf91..24e196b 100644 --- a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.cpp @@ -63,11 +63,8 @@ SurfaceCollection::SurfaceCollection(LayerAndroid* layer) // set the layersurfaces' update count, to be drawn on painted tiles unsigned int updateCount = TilesManager::instance()->incWebkitContentUpdates(); - for (unsigned int i = 0; i < m_surfaces.size(); i++) { + for (unsigned int i = 0; i < m_surfaces.size(); i++) m_surfaces[i]->setUpdateCount(updateCount); - if (m_surfaces[i]->isBase()) - m_surfaces[i]->setBackground(getBackground()); - } #ifdef DEBUG_COUNT ClassTracker::instance()->increment("SurfaceCollection"); @@ -95,6 +92,15 @@ void SurfaceCollection::prepareGL(const SkRect& visibleRect) m_surfaces[i]->prepareGL(layerTilesDisabled); } +static inline bool compareSurfaceZ(const Surface* a, const Surface* b) +{ + const LayerAndroid* la = a->getFirstLayer(); + const LayerAndroid* lb = b->getFirstLayer(); + + // swap drawing order if zValue suggests it AND the layers are in the same stacking context + return (la->zValue() > lb->zValue()) && (la->getParent() == lb->getParent()); +} + bool SurfaceCollection::drawGL(const SkRect& visibleRect) { #ifdef DEBUG_COUNT @@ -105,13 +111,21 @@ bool SurfaceCollection::drawGL(const SkRect& visibleRect) updateLayerPositions(visibleRect); bool layerTilesDisabled = m_compositedRoot->state()->layersRenderingMode() > GLWebViewState::kClippedTextures; + + // create a duplicate vector of surfaces, sorted by z value + Vector <Surface*> surfaces; for (unsigned int i = 0; i < m_surfaces.size(); i++) - needsRedraw |= m_surfaces[i]->drawGL(layerTilesDisabled); + surfaces.append(m_surfaces[i]); + std::stable_sort(surfaces.begin()+1, surfaces.end(), compareSurfaceZ); + + // draw the sorted vector + for (unsigned int i = 0; i < m_surfaces.size(); i++) + needsRedraw |= surfaces[i]->drawGL(layerTilesDisabled); return needsRedraw; } -Color SurfaceCollection::getBackground() +Color SurfaceCollection::getBackgroundColor() { return static_cast<BaseLayerAndroid*>(m_compositedRoot)->getBackgroundColor(); } @@ -139,6 +153,16 @@ bool SurfaceCollection::isReady() return true; } +bool SurfaceCollection::isMissingBackgroundContent() +{ + if (!m_compositedRoot) + return true; + + // return true when the first surface is missing content (indicating the + // entire viewport isn't covered) + return m_surfaces[0]->isMissingContent(); +} + void SurfaceCollection::computeTexturesAmount(TexturesResult* result) { for (unsigned int i = 0; i < m_surfaces.size(); i++) diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.h b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.h index 6450c9c..7dfe140 100644 --- a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.h +++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.h @@ -50,9 +50,10 @@ public: // Tiled painting methods (executed on groups) void prepareGL(const SkRect& visibleRect); bool drawGL(const SkRect& visibleRect); - Color getBackground(); + Color getBackgroundColor(); void swapTiles(); bool isReady(); + bool isMissingBackgroundContent(); void computeTexturesAmount(TexturesResult* result); // Recursive tree methods (animations, invals, etc) diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp index 8fb4d4b..52a8e44 100644 --- a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp @@ -36,9 +36,8 @@ namespace WebCore { -SurfaceCollectionManager::SurfaceCollectionManager(GLWebViewState* state) - : m_state(state) - , m_drawingCollection(0) +SurfaceCollectionManager::SurfaceCollectionManager() + : m_drawingCollection(0) , m_paintingCollection(0) , m_queuedCollection(0) , m_fastSwapMode(false) @@ -59,8 +58,6 @@ void SurfaceCollectionManager::swap() // swap can't be called unless painting just finished ASSERT(m_paintingCollection); - android::Mutex::Autolock lock(m_paintSwapLock); - ALOGV("SWAPPING, D %p, P %p, Q %p", m_drawingCollection, m_paintingCollection, m_queuedCollection); @@ -90,8 +87,6 @@ void SurfaceCollectionManager::swap() // clear all of the content in the three collections held by the collection manager void SurfaceCollectionManager::clearCollections() { - ALOGV("SurfaceCollectionManager %p removing PS from state %p", this, m_state); - SkSafeUnref(m_drawingCollection); m_drawingCollection = 0; SkSafeUnref(m_paintingCollection); @@ -109,8 +104,6 @@ bool SurfaceCollectionManager::updateWithSurfaceCollection(SurfaceCollection* ne // can't have a queued collection unless have a painting collection too ASSERT(m_paintingCollection || !m_queuedCollection); - android::Mutex::Autolock lock(m_paintSwapLock); - if (!newCollection || brandNew) { clearCollections(); if (brandNew) { @@ -205,9 +198,17 @@ int SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect, returnFlags |= uirenderer::DrawGlInfo::kStatusInvoke; if (!shouldDraw) { - if (didCollectionSwap) { + if (didCollectionSwap + || (!m_paintingCollection + && m_drawingCollection + && m_drawingCollection->isReady())) { + // either a swap just occurred, or there is no more work to be done: do a full draw m_drawingCollection->swapTiles(); returnFlags |= uirenderer::DrawGlInfo::kStatusDraw; + } else { + // current collection not ready - invoke functor in process mode + // until either drawing or painting collection is ready + returnFlags |= uirenderer::DrawGlInfo::kStatusInvoke; } return returnFlags; @@ -216,6 +217,7 @@ int SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect, // =========================================================================== // Don't have a drawing collection, draw white background Color background = Color::white; + bool drawBackground = true; if (m_drawingCollection) { bool drawingReady = didCollectionSwap || m_drawingCollection->isReady(); @@ -237,17 +239,21 @@ int SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect, m_drawingCollection->evaluateAnimations(currentTime); ALOGV("drawing collection %p", m_drawingCollection); - background = m_drawingCollection->getBackground(); + background = m_drawingCollection->getBackgroundColor(); + drawBackground = m_drawingCollection->isMissingBackgroundContent(); } else if (m_paintingCollection) { // Use paintingCollection background color while tiles are not done painting. - background = m_paintingCollection->getBackground(); + background = m_paintingCollection->getBackgroundColor(); } // Start doing the actual GL drawing. - ALOGV("background is %x", background.rgb()); - // If background is opaque, we can safely and efficiently clear it here. - // Otherwise, we have to calculate all the missing tiles and blend the background. - GLUtils::clearBackgroundIfOpaque(&background); + if (drawBackground) { + ALOGV("background is %x", background.rgb()); + // If background is opaque, we can safely and efficiently clear it here. + // Otherwise, we have to calculate all the missing tiles and blend the background. + GLUtils::clearBackgroundIfOpaque(&background); + } + if (m_drawingCollection && m_drawingCollection->drawGL(visibleRect)) returnFlags |= uirenderer::DrawGlInfo::kStatusDraw; diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.h b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.h index cc98899..125bf02 100644 --- a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.h +++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.h @@ -41,7 +41,7 @@ class SurfaceCollection; class TEST_EXPORT SurfaceCollectionManager { public: - SurfaceCollectionManager(GLWebViewState* state); + SurfaceCollectionManager(); ~SurfaceCollectionManager(); @@ -58,10 +58,6 @@ private: void swap(); void clearCollections(); - android::Mutex m_paintSwapLock; - - GLWebViewState* m_state; - SurfaceCollection* m_drawingCollection; SurfaceCollection* m_paintingCollection; SurfaceCollection* m_queuedCollection; diff --git a/Source/WebCore/platform/graphics/android/rendering/Tile.cpp b/Source/WebCore/platform/graphics/android/rendering/Tile.cpp index 35fded1..178958d 100644 --- a/Source/WebCore/platform/graphics/android/rendering/Tile.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/Tile.cpp @@ -511,11 +511,6 @@ void Tile::validatePaint() { // paintBitmap() may have cleared m_dirty) m_dirty = true; } - - if (m_deferredDirty) { - ALOGV("Note: deferred dirty flag set, possibly a missed paint on tile %p", this); - m_deferredDirty = false; - } } else { ALOGV("Note: paint was unsuccessful."); m_state = Unpainted; diff --git a/Source/WebCore/platform/graphics/android/rendering/Tile.h b/Source/WebCore/platform/graphics/android/rendering/Tile.h index 7010301..cc10799 100644 --- a/Source/WebCore/platform/graphics/android/rendering/Tile.h +++ b/Source/WebCore/platform/graphics/android/rendering/Tile.h @@ -151,9 +151,6 @@ private: // redrawn in the backTexture bool m_dirty; - // currently only for debugging, to be used for tracking down dropped repaints - bool m_deferredDirty; - // used to signal that a repaint is pending bool m_repaintPending; diff --git a/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp b/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp index 0e900a9..00cc656 100644 --- a/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp @@ -80,7 +80,7 @@ bool TileGrid::isReady() // in order to unblock the zooming process. // FIXME: have a better system -- maybe keeping the last scale factor // able to fully render everything - ALOGV("TT %p, ready %d, visible %d, texturesRemain %d", + ALOGV("TG %p, ready %d, visible %d, texturesRemain %d", this, tilesAllReady, tilesVisible, TilesManager::instance()->layerTexturesRemain()); @@ -102,7 +102,7 @@ void TileGrid::swapTiles() for (unsigned int i = 0; i < m_tiles.size(); i++) if (m_tiles[i]->swapTexturesIfNeeded()) swaps++; - ALOGV("TT %p swapping, swaps = %d", this, swaps); + ALOGV("TG %p swapping, swaps = %d", this, swaps); } IntRect TileGrid::computeTilesArea(const IntRect& contentArea, float scale) @@ -113,7 +113,7 @@ IntRect TileGrid::computeTilesArea(const IntRect& contentArea, float scale) ceilf(contentArea.width() * scale), ceilf(contentArea.height() * scale)); - ALOGV("TT %p prepare, scale %f, area %d x %d", this, scale, area.width(), area.height()); + ALOGV("TG %p prepare, scale %f, area %d x %d", this, scale, area.width(), area.height()); if (area.width() == 0 && area.height() == 0) { computedArea.setWidth(0); @@ -153,8 +153,9 @@ void TileGrid::prepareGL(GLWebViewState* state, float scale, bool goingDown = m_prevTileY < m_area.y(); m_prevTileY = m_area.y(); + TilesManager* tilesManager = TilesManager::instance(); if (scale != m_scale) - TilesManager::instance()->removeOperationsForFilter(new ScaleFilter(painter, m_scale)); + tilesManager->removeOperationsForFilter(new ScaleFilter(painter, m_scale)); m_scale = scale; @@ -164,11 +165,11 @@ void TileGrid::prepareGL(GLWebViewState* state, float scale, m_tiles[i]->markAsDirty(m_dirtyRegion); // log inval region for the base surface - if (m_isBaseSurface && TilesManager::instance()->getProfiler()->enabled()) { + if (m_isBaseSurface && tilesManager->getProfiler()->enabled()) { SkRegion::Iterator iterator(m_dirtyRegion); while (!iterator.done()) { SkIRect r = iterator.rect(); - TilesManager::instance()->getProfiler()->nextInval(r, scale); + tilesManager->getProfiler()->nextInval(r, scale); iterator.next(); } } @@ -192,10 +193,13 @@ void TileGrid::prepareGL(GLWebViewState* state, float scale, if (useExpandPrefetch) { IntRect fullArea = computeTilesArea(unclippedArea, scale); IntRect expandedArea = m_area; - expandedArea.inflate(EXPANDED_BOUNDS_INFLATE); + + // on systems reporting highEndGfx=true and useMinimalMemory not set, use expanded bounds + if (tilesManager->highEndGfx() && !tilesManager->useMinimalMemory()) + expandedArea.inflate(EXPANDED_BOUNDS_INFLATE); if (isLowResPrefetch) - expandedArea.inflate(EXPANDED_PREFETCH_BOUNDS_Y_INFLATE); + expandedArea.inflateY(EXPANDED_PREFETCH_BOUNDS_Y_INFLATE); // clip painting area to content expandedArea.intersect(fullArea); @@ -209,7 +213,7 @@ void TileGrid::prepareGL(GLWebViewState* state, float scale, void TileGrid::markAsDirty(const SkRegion& invalRegion) { - ALOGV("TT %p markAsDirty, current region empty %d, new empty %d", + ALOGV("TG %p markAsDirty, current region empty %d, new empty %d", this, m_dirtyRegion.isEmpty(), invalRegion.isEmpty()); m_dirtyRegion.op(invalRegion, SkRegion::kUnion_Op); } @@ -235,7 +239,7 @@ void TileGrid::prepareTile(int x, int y, TilePainter* painter, tile->reserveTexture(); if (tile->backTexture() && tile->isDirty() && !tile->isRepaintPending()) { - ALOGV("painting TT %p's tile %d %d for LG %p", this, x, y, painter); + ALOGV("painting TG %p's tile %d %d for LG %p", this, x, y, painter); PaintTileOperation *operation = new PaintTileOperation(tile, painter, state, isLowResPrefetch); TilesManager::instance()->scheduleOperation(operation); @@ -270,14 +274,14 @@ int TileGrid::nbTextures(IntRect& area, float scale) } void TileGrid::drawGL(const IntRect& visibleArea, float opacity, - const TransformationMatrix* transform, - const Color* background) + const TransformationMatrix* transform, + const Color* background) { m_area = computeTilesArea(visibleArea, m_scale); if (m_area.width() == 0 || m_area.height() == 0) return; - float invScale = 1 / m_scale; + float invScale = 1.0 / m_scale; const float tileWidth = TilesManager::tileWidth() * invScale; const float tileHeight = TilesManager::tileHeight() * invScale; @@ -318,7 +322,8 @@ void TileGrid::drawGL(const IntRect& visibleArea, float opacity, drawn++; } - if (semiOpaqueBaseSurface) + // log tile information for base, high res tiles + if (m_isBaseSurface && background) TilesManager::instance()->getProfiler()->nextTile(tile, invScale, tileInView); } @@ -326,7 +331,7 @@ void TileGrid::drawGL(const IntRect& visibleArea, float opacity, if (semiOpaqueBaseSurface) drawMissingRegion(missingRegion, opacity, background); - ALOGV("TT %p drew %d tiles, scale %f", + ALOGV("TG %p drew %d tiles, scale %f", this, drawn, m_scale); } @@ -336,7 +341,6 @@ void TileGrid::drawMissingRegion(const SkRegion& region, float opacity, SkRegion::Iterator iterator(region); const float tileWidth = TilesManager::tileWidth() / m_scale; const float tileHeight = TilesManager::tileHeight() / m_scale; - ShaderProgram* shader = TilesManager::instance()->shader(); while (!iterator.done()) { SkIRect r = iterator.rect(); SkRect rect; @@ -368,7 +372,7 @@ void TileGrid::removeTiles() void TileGrid::discardTextures() { - ALOGV("TT %p discarding textures", this); + ALOGV("TG %p discarding textures", this); for (unsigned int i = 0; i < m_tiles.size(); i++) m_tiles[i]->discardTextures(); } diff --git a/Source/WebCore/platform/graphics/android/rendering/TilePainter.h b/Source/WebCore/platform/graphics/android/rendering/TilePainter.h index d992aee..53dfadc 100644 --- a/Source/WebCore/platform/graphics/android/rendering/TilePainter.h +++ b/Source/WebCore/platform/graphics/android/rendering/TilePainter.h @@ -33,14 +33,13 @@ class SkCanvas; namespace WebCore { -class Tile; class Color; class TilePainter : public SkRefCnt { // TODO: investigate webkit threadsafe ref counting public: virtual ~TilePainter() { } - virtual bool paint(Tile* tile, SkCanvas* canvas) = 0; + virtual bool paint(SkCanvas* canvas) = 0; virtual float opacity() { return 1.0; } enum SurfaceType { Painted, Image }; virtual SurfaceType type() { return Painted; } diff --git a/Source/WebCore/platform/graphics/android/rendering/TileTexture.cpp b/Source/WebCore/platform/graphics/android/rendering/TileTexture.cpp index 39effd7..126a7ac 100644 --- a/Source/WebCore/platform/graphics/android/rendering/TileTexture.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/TileTexture.cpp @@ -77,15 +77,15 @@ void TileTexture::discardGLTexture() } } -bool TileTexture::acquire(TextureOwner* owner, bool force) +bool TileTexture::acquire(TextureOwner* owner) { if (m_owner == owner) return true; - return setOwner(owner, force); + return setOwner(owner); } -bool TileTexture::setOwner(TextureOwner* owner, bool force) +bool TileTexture::setOwner(TextureOwner* owner) { bool proceed = true; if (m_owner && m_owner != owner) diff --git a/Source/WebCore/platform/graphics/android/rendering/TileTexture.h b/Source/WebCore/platform/graphics/android/rendering/TileTexture.h index 5fe43b0..b008b7d 100644 --- a/Source/WebCore/platform/graphics/android/rendering/TileTexture.h +++ b/Source/WebCore/platform/graphics/android/rendering/TileTexture.h @@ -51,11 +51,11 @@ public: // allows consumer thread to assign ownership of the texture to the tile. It // returns false if ownership cannot be transferred because the tile is busy - bool acquire(TextureOwner* owner, bool force = false); + bool acquire(TextureOwner* owner); bool release(TextureOwner* owner); // set the texture owner if not busy. Return false if busy, true otherwise. - bool setOwner(TextureOwner* owner, bool force = false); + bool setOwner(TextureOwner* owner); // private member accessor functions TextureOwner* owner() { return m_owner; } // only used by the consumer thread diff --git a/Source/WebCore/platform/graphics/android/rendering/TransferQueue.cpp b/Source/WebCore/platform/graphics/android/rendering/TransferQueue.cpp index ec0d9e7..5ede167 100644 --- a/Source/WebCore/platform/graphics/android/rendering/TransferQueue.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/TransferQueue.cpp @@ -203,7 +203,6 @@ void TransferQueue::blitTileFromQueue(GLuint fboID, TileTexture* destTex, GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) { ALOGV("Error: glCheckFramebufferStatus failed"); - glBindFramebuffer(GL_FRAMEBUFFER, 0); return; } @@ -426,7 +425,6 @@ void TransferQueue::updateDirtyTiles() // dynamic switch possible. Moving this out from the loop can save some // milli-seconds. if (usedFboForUpload) { - glBindFramebuffer(GL_FRAMEBUFFER, 0); // rebind the standard FBO restoreGLState(); GLUtils::checkGlError("updateDirtyTiles"); } @@ -593,6 +591,7 @@ void TransferQueue::cleanupPendingDiscard() void TransferQueue::saveGLState() { + glGetIntegerv(GL_FRAMEBUFFER_BINDING, m_GLStateBeforeBlit.bufferId); glGetIntegerv(GL_VIEWPORT, m_GLStateBeforeBlit.viewport); glGetBooleanv(GL_SCISSOR_TEST, m_GLStateBeforeBlit.scissor); glGetBooleanv(GL_DEPTH_TEST, m_GLStateBeforeBlit.depth); @@ -616,6 +615,7 @@ void TransferQueue::setGLStateForCopy(int width, int height) void TransferQueue::restoreGLState() { + glBindFramebuffer(GL_FRAMEBUFFER, m_GLStateBeforeBlit.bufferId[0]); glViewport(m_GLStateBeforeBlit.viewport[0], m_GLStateBeforeBlit.viewport[1], m_GLStateBeforeBlit.viewport[2], diff --git a/Source/WebCore/platform/graphics/android/rendering/TransferQueue.h b/Source/WebCore/platform/graphics/android/rendering/TransferQueue.h index 65ff116..d1024a4 100644 --- a/Source/WebCore/platform/graphics/android/rendering/TransferQueue.h +++ b/Source/WebCore/platform/graphics/android/rendering/TransferQueue.h @@ -40,6 +40,7 @@ class Tile; class TileTexture; struct GLState { + GLint bufferId[1]; GLint viewport[4]; GLboolean scissor[1]; GLboolean depth[1]; diff --git a/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp b/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp index dc22fca..ec04035 100644 --- a/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp +++ b/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp @@ -180,9 +180,9 @@ static void ensureSessionIsInitialized(SoupSession* session) g_object_set_data(G_OBJECT(session), "webkit-init", reinterpret_cast<void*>(0xdeadbeef)); } -void ResourceHandle::prepareForURL(const KURL &url) +void ResourceHandle::prepareForURL(const KURL& url) { - GOwnPtr<SoupURI> soupURI(soup_uri_new(url.prettyURL().utf8().data())); + GOwnPtr<SoupURI> soupURI(soup_uri_new(url.string().utf8().data())); if (!soupURI) return; soup_session_prepare_for_uri(ResourceHandle::defaultSession(), soupURI.get()); diff --git a/Source/WebCore/platform/qt/KURLQt.cpp b/Source/WebCore/platform/qt/KURLQt.cpp index f6d2a86..674a933 100644 --- a/Source/WebCore/platform/qt/KURLQt.cpp +++ b/Source/WebCore/platform/qt/KURLQt.cpp @@ -50,4 +50,3 @@ String KURL::fileSystemPath() const } } - diff --git a/Source/WebCore/platform/win/ClipboardWin.cpp b/Source/WebCore/platform/win/ClipboardWin.cpp index 0b5a3d3..2e56cbc 100644 --- a/Source/WebCore/platform/win/ClipboardWin.cpp +++ b/Source/WebCore/platform/win/ClipboardWin.cpp @@ -191,7 +191,7 @@ static HGLOBAL createGlobalHDropContent(const KURL& url, String& fileName, Share WCHAR filePath[MAX_PATH]; if (url.isLocalFile()) { - String localPath = url.path(); + String localPath = decodeURLEscapeSequences(url.path()); // windows does not enjoy a leading slash on paths if (localPath[0] == '/') localPath = localPath.substring(1); diff --git a/Source/WebCore/rendering/RenderBlock.cpp b/Source/WebCore/rendering/RenderBlock.cpp index a90bf69..a3bd41a 100644 --- a/Source/WebCore/rendering/RenderBlock.cpp +++ b/Source/WebCore/rendering/RenderBlock.cpp @@ -191,7 +191,7 @@ void RenderBlock::destroy() childBox->remove(); } } - } else if (isInline() && parent()) + } else if (parent()) parent()->dirtyLinesFromChangedChild(this); } @@ -420,14 +420,18 @@ void RenderBlock::addChildToAnonymousColumnBlocks(RenderObject* newChild, Render RenderBlock* RenderBlock::containingColumnsBlock(bool allowAnonymousColumnBlock) { + RenderBlock* firstChildIgnoringAnonymousWrappers = 0; for (RenderObject* curr = this; curr; curr = curr->parent()) { if (!curr->isRenderBlock() || curr->isFloatingOrPositioned() || curr->isTableCell() || curr->isRoot() || curr->isRenderView() || curr->hasOverflowClip() || curr->isInlineBlockOrInlineTable()) return 0; RenderBlock* currBlock = toRenderBlock(curr); + if (!currBlock->createsAnonymousWrapper()) + firstChildIgnoringAnonymousWrappers = currBlock; + if (currBlock->style()->specifiesColumns() && (allowAnonymousColumnBlock || !currBlock->isAnonymousColumnsBlock())) - return currBlock; + return firstChildIgnoringAnonymousWrappers; if (currBlock->isAnonymousColumnSpanBlock()) return 0; @@ -443,6 +447,8 @@ RenderBlock* RenderBlock::clone() const else { cloneBlock = new (renderArena()) RenderBlock(node()); cloneBlock->setStyle(style()); + if (!childrenInline() && cloneBlock->firstChild() && cloneBlock->firstChild()->isInline()) + cloneBlock->makeChildrenNonInline(); } cloneBlock->setChildrenInline(childrenInline()); return cloneBlock; @@ -657,12 +663,21 @@ RenderBlock* RenderBlock::columnsBlockForSpanningElement(RenderObject* newChild) // cross the streams and have to cope with both types of continuations mixed together). // This function currently supports (1) and (2). RenderBlock* columnsBlockAncestor = 0; - if (!newChild->isText() && newChild->style()->columnSpan() && !newChild->isFloatingOrPositioned() - && !newChild->isInline() && !isAnonymousColumnSpanBlock()) { - if (style()->specifiesColumns()) - columnsBlockAncestor = this; - else if (parent() && parent()->isRenderBlock()) - columnsBlockAncestor = toRenderBlock(parent())->containingColumnsBlock(false); + if (!newChild->isText() && newChild->style()->columnSpan() && !newChild->isBeforeOrAfterContent() + && !newChild->isFloatingOrPositioned() && !newChild->isInline() && !isAnonymousColumnSpanBlock()) { + columnsBlockAncestor = containingColumnsBlock(false); + if (columnsBlockAncestor) { + // Make sure that none of the parent ancestors have a continuation. + // If yes, we do not want split the block into continuations. + RenderObject* curr = this; + while (curr && curr != columnsBlockAncestor) { + if (curr->isRenderBlock() && toRenderBlock(curr)->continuation()) { + columnsBlockAncestor = 0; + break; + } + curr = curr->parent(); + } + } } return columnsBlockAncestor; } diff --git a/Source/WebCore/rendering/RenderBox.cpp b/Source/WebCore/rendering/RenderBox.cpp index fb1dd2c..9c40d5b 100644 --- a/Source/WebCore/rendering/RenderBox.cpp +++ b/Source/WebCore/rendering/RenderBox.cpp @@ -3260,7 +3260,7 @@ bool RenderBox::shrinkToAvoidFloats() const bool RenderBox::avoidsFloats() const { - return isReplaced() || hasOverflowClip() || isHR() || isLegend() || isWritingModeRoot(); + return isReplaced() || hasOverflowClip() || isHR() || isLegend() || isWritingModeRoot() || isDeprecatedFlexItem(); } void RenderBox::addShadowOverflow() diff --git a/Source/WebCore/rendering/RenderBox.h b/Source/WebCore/rendering/RenderBox.h index 1bee989..a5dc1b2 100644 --- a/Source/WebCore/rendering/RenderBox.h +++ b/Source/WebCore/rendering/RenderBox.h @@ -378,6 +378,8 @@ public: virtual void markForPaginationRelayoutIfNeeded() { } bool isWritingModeRoot() const { return !parent() || parent()->style()->writingMode() != style()->writingMode(); } + + bool isDeprecatedFlexItem() const { return !isInline() && !isFloatingOrPositioned() && parent() && parent()->isFlexibleBox(); } virtual int lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const; virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const; diff --git a/Source/WebCore/rendering/RenderFileUploadControl.cpp b/Source/WebCore/rendering/RenderFileUploadControl.cpp index 8056662..109d219 100644 --- a/Source/WebCore/rendering/RenderFileUploadControl.cpp +++ b/Source/WebCore/rendering/RenderFileUploadControl.cpp @@ -122,6 +122,13 @@ String RenderFileUploadControl::acceptTypes() return static_cast<HTMLInputElement*>(node())->accept(); } +#if ENABLE(MEDIA_CAPTURE) +String RenderFileUploadControl::capture() +{ + return static_cast<HTMLInputElement*>(node())->capture(); +} +#endif + void RenderFileUploadControl::chooseIconForFiles(FileChooser* chooser, const Vector<String>& filenames) { if (Chrome* chromePointer = chrome()) diff --git a/Source/WebCore/rendering/RenderFileUploadControl.h b/Source/WebCore/rendering/RenderFileUploadControl.h index e9fb7f0..b57260d 100644 --- a/Source/WebCore/rendering/RenderFileUploadControl.h +++ b/Source/WebCore/rendering/RenderFileUploadControl.h @@ -68,6 +68,9 @@ private: #endif String acceptTypes(); void chooseIconForFiles(FileChooser*, const Vector<String>&); +#if ENABLE(MEDIA_CAPTURE) + String capture(); +#endif Chrome* chrome() const; int maxFilenameWidth() const; diff --git a/Source/WebCore/rendering/RenderFlexibleBox.cpp b/Source/WebCore/rendering/RenderFlexibleBox.cpp index dc5c171..99c7e0b 100644 --- a/Source/WebCore/rendering/RenderFlexibleBox.cpp +++ b/Source/WebCore/rendering/RenderFlexibleBox.cpp @@ -43,30 +43,30 @@ namespace WebCore { class FlexBoxIterator { public: FlexBoxIterator(RenderFlexibleBox* parent) + : m_box(parent) + , m_lastOrdinal(1) { - box = parent; - if (box->style()->boxOrient() == HORIZONTAL && !box->style()->isLeftToRightDirection()) - forward = box->style()->boxDirection() != BNORMAL; + if (m_box->style()->boxOrient() == HORIZONTAL && !m_box->style()->isLeftToRightDirection()) + m_forward = m_box->style()->boxDirection() != BNORMAL; else - forward = box->style()->boxDirection() == BNORMAL; - lastOrdinal = 1; - if (!forward) { + m_forward = m_box->style()->boxDirection() == BNORMAL; + if (!m_forward) { // No choice, since we're going backwards, we have to find out the highest ordinal up front. - RenderBox* child = box->firstChildBox(); + RenderBox* child = m_box->firstChildBox(); while (child) { - if (child->style()->boxOrdinalGroup() > lastOrdinal) - lastOrdinal = child->style()->boxOrdinalGroup(); + if (child->style()->boxOrdinalGroup() > m_lastOrdinal) + m_lastOrdinal = child->style()->boxOrdinalGroup(); child = child->nextSiblingBox(); } } - + reset(); } void reset() { - current = 0; - currentOrdinal = forward ? 0 : lastOrdinal+1; + m_currentChild = 0; + m_currentOrdinal = m_forward ? 0 : m_lastOrdinal + 1; } RenderBox* first() @@ -74,42 +74,42 @@ public: reset(); return next(); } - + RenderBox* next() { - do { - if (!current) { - if (forward) { - currentOrdinal++; - if (currentOrdinal > lastOrdinal) + do { + if (!m_currentChild) { + if (m_forward) { + ++m_currentOrdinal; + if (m_currentOrdinal > m_lastOrdinal) return 0; - current = box->firstChildBox(); + m_currentChild = m_box->firstChildBox(); } else { - currentOrdinal--; - if (currentOrdinal == 0) + --m_currentOrdinal; + if (!m_currentOrdinal) return 0; - current = box->lastChildBox(); + m_currentChild = m_box->lastChildBox(); } } else - current = forward ? current->nextSiblingBox() : current->previousSiblingBox(); - if (current && current->style()->boxOrdinalGroup() > lastOrdinal) - lastOrdinal = current->style()->boxOrdinalGroup(); - } while (!current || current->style()->boxOrdinalGroup() != currentOrdinal || - current->style()->visibility() == COLLAPSE); - return current; + m_currentChild = m_forward ? m_currentChild->nextSiblingBox() : m_currentChild->previousSiblingBox(); + if (m_currentChild && m_currentChild->style()->boxOrdinalGroup() > m_lastOrdinal) + m_lastOrdinal = m_currentChild->style()->boxOrdinalGroup(); + } while (!m_currentChild || (!m_currentChild->isAnonymous() + && (m_currentChild->style()->boxOrdinalGroup() != m_currentOrdinal || m_currentChild->style()->visibility() == COLLAPSE))); + return m_currentChild; } private: - RenderFlexibleBox* box; - RenderBox* current; - bool forward; - unsigned int currentOrdinal; - unsigned int lastOrdinal; + RenderFlexibleBox* m_box; + RenderBox* m_currentChild; + bool m_forward; + unsigned int m_currentOrdinal; + unsigned int m_lastOrdinal; }; - + RenderFlexibleBox::RenderFlexibleBox(Node* node) -:RenderBlock(node) + : RenderBlock(node) { setChildrenInline(false); // All of our children must be block-level m_flexingChildren = m_stretchingChildren = false; @@ -119,54 +119,48 @@ RenderFlexibleBox::~RenderFlexibleBox() { } +static int marginWidthForChild(RenderBox* child) +{ + // A margin basically has three types: fixed, percentage, and auto (variable). + // Auto and percentage margins simply become 0 when computing min/max width. + // Fixed margins can be added in as is. + Length marginLeft = child->style()->marginLeft(); + Length marginRight = child->style()->marginRight(); + int margin = 0; + if (marginLeft.isFixed()) + margin += marginLeft.value(); + if (marginRight.isFixed()) + margin += marginRight.value(); + return margin; +} + void RenderFlexibleBox::calcHorizontalPrefWidths() { for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) { - // positioned children don't affect the minmaxwidth + // Positioned children and collapsed children don't affect the min/max width. if (child->isPositioned() || child->style()->visibility() == COLLAPSE) continue; - // A margin basically has three types: fixed, percentage, and auto (variable). - // Auto and percentage margins simply become 0 when computing min/max width. - // Fixed margins can be added in as is. - Length ml = child->style()->marginLeft(); - Length mr = child->style()->marginRight(); - int margin = 0, marginLeft = 0, marginRight = 0; - if (ml.isFixed()) - marginLeft += ml.value(); - if (mr.isFixed()) - marginRight += mr.value(); - margin = marginLeft + marginRight; - + int margin = marginWidthForChild(child); m_minPreferredLogicalWidth += child->minPreferredLogicalWidth() + margin; m_maxPreferredLogicalWidth += child->maxPreferredLogicalWidth() + margin; - } + } } void RenderFlexibleBox::calcVerticalPrefWidths() { for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) { - // Positioned children and collapsed children don't affect the min/max width + // Positioned children and collapsed children don't affect the min/max width. if (child->isPositioned() || child->style()->visibility() == COLLAPSE) continue; - // A margin basically has three types: fixed, percentage, and auto (variable). - // Auto/percentage margins simply become 0 when computing min/max width. - // Fixed margins can be added in as is. - Length ml = child->style()->marginLeft(); - Length mr = child->style()->marginRight(); - int margin = 0; - if (ml.isFixed()) - margin += ml.value(); - if (mr.isFixed()) - margin += mr.value(); - - int w = child->minPreferredLogicalWidth() + margin; - m_minPreferredLogicalWidth = max(w, m_minPreferredLogicalWidth); - - w = child->maxPreferredLogicalWidth() + margin; - m_maxPreferredLogicalWidth = max(w, m_maxPreferredLogicalWidth); - } + int margin = marginWidthForChild(child); + int width = child->minPreferredLogicalWidth() + margin; + m_minPreferredLogicalWidth = max(width, m_minPreferredLogicalWidth); + + width = child->maxPreferredLogicalWidth() + margin; + m_maxPreferredLogicalWidth = max(width, m_maxPreferredLogicalWidth); + } } void RenderFlexibleBox::computePreferredLogicalWidths() @@ -197,7 +191,7 @@ void RenderFlexibleBox::computePreferredLogicalWidths() m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->minWidth().value())); m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->minWidth().value())); } - + if (style()->maxWidth().isFixed() && style()->maxWidth().value() != undefinedLength) { m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->maxWidth().value())); m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->maxWidth().value())); @@ -222,10 +216,10 @@ void RenderFlexibleBox::layoutBlock(bool relayoutChildren, int /*pageHeight FIXM int previousWidth = width(); int previousHeight = height(); - + computeLogicalWidth(); computeLogicalHeight(); - + m_overflow.clear(); if (previousWidth != width() || previousHeight != height() || @@ -280,7 +274,7 @@ void RenderFlexibleBox::layoutBlock(bool relayoutChildren, int /*pageHeight FIXM setMaxMarginBeforeValues(pos, neg); setMaxMarginAfterValues(0, 0); } - + computeOverflow(oldClientAfterEdge); statePusher.pop(); @@ -297,15 +291,14 @@ void RenderFlexibleBox::layoutBlock(bool relayoutChildren, int /*pageHeight FIXM // Repaint with our new bounds if they are different from our old bounds. repainter.repaintAfterLayout(); - + setNeedsLayout(false); } // The first walk over our kids is to find out if we have any flexible children. static void gatherFlexChildrenInfo(FlexBoxIterator& iterator, bool relayoutChildren, unsigned int& highestFlexGroup, unsigned int& lowestFlexGroup, bool& haveFlex) { - RenderBox* child = iterator.first(); - while (child) { + for (RenderBox* child = iterator.first(); child; child = iterator.next()) { // Check to see if this child flexes. if (!child->isPositioned() && child->style()->boxFlex() > 0.0f) { // We always have to lay out flexible objects again, since the flex distribution @@ -322,7 +315,6 @@ static void gatherFlexChildrenInfo(FlexBoxIterator& iterator, bool relayoutChild if (flexGroup > highestFlexGroup) highestFlexGroup = flexGroup; } - child = iterator.next(); } } @@ -343,8 +335,6 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren) bool haveFlex = false; gatherFlexChildrenInfo(iterator, relayoutChildren, highestFlexGroup, lowestFlexGroup, haveFlex); - RenderBox* child; - RenderBlock::startDelayUpdateScrollInfo(); // We do 2 passes. The first pass is simply to lay everyone out at @@ -354,31 +344,28 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren) setHeight(yPos); xPos = borderLeft() + paddingLeft(); - + // Our first pass is done without flexing. We simply lay the children // out within the box. We have to do a layout first in order to determine // our box's intrinsic height. int maxAscent = 0, maxDescent = 0; - child = iterator.first(); - while (child) { + for (RenderBox* child = iterator.first(); child; child = iterator.next()) { // make sure we relayout children if we need it. if (relayoutChildren || (child->isReplaced() && (child->style()->width().isPercent() || child->style()->height().isPercent()))) child->setChildNeedsLayout(true, false); - - if (child->isPositioned()) { - child = iterator.next(); + + if (child->isPositioned()) continue; - } - + // Compute the child's vertical margins. child->computeBlockDirectionMargins(this); - + if (!child->needsLayout()) child->markForPaginationRelayoutIfNeeded(); // Now do the layout. child->layoutIfNeeded(); - + // Update our height and overflow height. if (style()->boxAlign() == BBASELINE) { int ascent = child->firstLineBoxBaseline(); @@ -386,38 +373,35 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren) ascent = child->height() + child->marginBottom(); ascent += child->marginTop(); int descent = (child->marginTop() + child->height() + child->marginBottom()) - ascent; - + // Update our maximum ascent. maxAscent = max(maxAscent, ascent); - + // Update our maximum descent. maxDescent = max(maxDescent, descent); - + // Now update our height. setHeight(max(yPos + maxAscent + maxDescent, height())); } else setHeight(max(height(), yPos + child->marginTop() + child->height() + child->marginBottom())); - - child = iterator.next(); } - + if (!iterator.first() && hasLineIfEmpty()) setHeight(height() + lineHeight(true, style()->isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes)); - + setHeight(height() + toAdd); - + oldHeight = height(); computeLogicalHeight(); relayoutChildren = false; if (oldHeight != height()) heightSpecified = true; - + // Now that our height is actually known, we can place our boxes. m_stretchingChildren = (style()->boxAlign() == BSTRETCH); - child = iterator.first(); - while (child) { + for (RenderBox* child = iterator.first(); child; child = iterator.next()) { if (child->isPositioned()) { child->containingBlock()->insertPositionedObject(child); RenderLayer* childLayer = child->layer(); @@ -427,10 +411,9 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren) if (child->style()->hasStaticBlockPosition(style()->isHorizontalWritingMode())) child->setChildNeedsLayout(true, false); } - child = iterator.next(); continue; } - + // We need to see if this child's height has changed, since we make block elements // fill the height of a containing box by default. // Now do a layout. @@ -438,18 +421,18 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren) child->computeLogicalHeight(); if (oldChildHeight != child->height()) child->setChildNeedsLayout(true, false); - + if (!child->needsLayout()) child->markForPaginationRelayoutIfNeeded(); child->layoutIfNeeded(); - + // We can place the child now, using our value of box-align. xPos += child->marginLeft(); int childY = yPos; switch (style()->boxAlign()) { case BCENTER: - childY += child->marginTop() + max(0, (contentHeight() - (child->height() + child->marginTop() + child->marginBottom()))/2); + childY += child->marginTop() + max(0, (contentHeight() - (child->height() + child->marginTop() + child->marginBottom())) / 2); break; case BBASELINE: { int ascent = child->firstLineBoxBaseline(); @@ -468,14 +451,12 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren) } placeChild(child, xPos, childY); - + xPos += child->width() + child->marginRight(); - - child = iterator.next(); } remainingSpace = borderLeft() + paddingLeft() + contentWidth() - xPos; - + m_stretchingChildren = false; if (m_flexingChildren) haveFlex = false; // We're done. @@ -500,24 +481,20 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren) // forces a totalFlex recomputation). int groupRemainingSpaceAtBeginning = groupRemainingSpace; float totalFlex = 0.0f; - child = iterator.first(); - while (child) { + for (RenderBox* child = iterator.first(); child; child = iterator.next()) { if (allowedChildFlex(child, expanding, i)) totalFlex += child->style()->boxFlex(); - child = iterator.next(); } - child = iterator.first(); int spaceAvailableThisPass = groupRemainingSpace; - while (child) { + for (RenderBox* child = iterator.first(); child; child = iterator.next()) { int allowedFlex = allowedChildFlex(child, expanding, i); if (allowedFlex) { int projectedFlex = (allowedFlex == INT_MAX) ? allowedFlex : (int)(allowedFlex * (totalFlex / child->style()->boxFlex())); spaceAvailableThisPass = expanding ? min(spaceAvailableThisPass, projectedFlex) : max(spaceAvailableThisPass, projectedFlex); } - child = iterator.next(); } - // The flex groups may not have any flexible objects this time around. + // The flex groups may not have any flexible objects this time around. if (!spaceAvailableThisPass || totalFlex == 0.0f) { // If we just couldn't grow/shrink any more, then it's time to transition to the next flex group. groupRemainingSpace = 0; @@ -525,8 +502,7 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren) } // Now distribute the space to objects. - child = iterator.first(); - while (child && spaceAvailableThisPass && totalFlex) { + for (RenderBox* child = iterator.first(); child && spaceAvailableThisPass && totalFlex; child = iterator.next()) { if (allowedChildFlex(child, expanding, i)) { int spaceAdd = (int)(spaceAvailableThisPass * (child->style()->boxFlex()/totalFlex)); if (spaceAdd) { @@ -538,16 +514,14 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren) spaceAvailableThisPass -= spaceAdd; remainingSpace -= spaceAdd; groupRemainingSpace -= spaceAdd; - + totalFlex -= child->style()->boxFlex(); } - child = iterator.next(); } if (groupRemainingSpace == groupRemainingSpaceAtBeginning) { - // this is not advancing, avoid getting stuck by distributing the remaining pixels - child = iterator.first(); + // This is not advancing, avoid getting stuck by distributing the remaining pixels. int spaceAdd = groupRemainingSpace > 0 ? 1 : -1; - while (child && groupRemainingSpace) { + for (RenderBox* child = iterator.first(); child && groupRemainingSpace; child = iterator.next()) { if (allowedChildFlex(child, expanding, i)) { child->setOverrideSize(child->overrideWidth() + spaceAdd); m_flexingChildren = true; @@ -555,7 +529,6 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren) remainingSpace -= spaceAdd; groupRemainingSpace -= spaceAdd; } - child = iterator.next(); } } } while (groupRemainingSpace); @@ -578,59 +551,47 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren) if (style()->boxPack() == BJUSTIFY) { // Determine the total number of children. int totalChildren = 0; - child = iterator.first(); - while (child) { - if (child->isPositioned()) { - child = iterator.next(); + for (RenderBox* child = iterator.first(); child; child = iterator.next()) { + if (child->isPositioned()) continue; - } - totalChildren++; - child = iterator.next(); + ++totalChildren; } // Iterate over the children and space them out according to the // justification level. if (totalChildren > 1) { - totalChildren--; + --totalChildren; bool firstChild = true; - child = iterator.first(); - while (child) { - if (child->isPositioned()) { - child = iterator.next(); + for (RenderBox* child = iterator.first(); child; child = iterator.next()) { + if (child->isPositioned()) continue; - } if (firstChild) { firstChild = false; - child = iterator.next(); continue; } offset += remainingSpace/totalChildren; remainingSpace -= (remainingSpace/totalChildren); - totalChildren--; + --totalChildren; - placeChild(child, child->x()+offset, child->y()); - child = iterator.next(); + placeChild(child, child->x() + offset, child->y()); } } } else { if (style()->boxPack() == BCENTER) - offset += remainingSpace/2; + offset += remainingSpace / 2; else // END for LTR, START for RTL offset += remainingSpace; - child = iterator.first(); - while (child) { - if (child->isPositioned()) { - child = iterator.next(); + for (RenderBox* child = iterator.first(); child; child = iterator.next()) { + if (child->isPositioned()) continue; - } - placeChild(child, child->x()+offset, child->y()); - child = iterator.next(); + + placeChild(child, child->x() + offset, child->y()); } } } - + // So that the computeLogicalHeight in layoutBlock() knows to relayout positioned objects because of // a height change, we revert our height back to the intrinsic height before returning. if (heightSpecified) @@ -655,8 +616,6 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren) bool haveFlex = false; gatherFlexChildrenInfo(iterator, relayoutChildren, highestFlexGroup, lowestFlexGroup, haveFlex); - RenderBox* child; - // We confine the line clamp ugliness to vertical flexible boxes (thus keeping it out of // mainstream block layout); this is not really part of the XUL box model. bool haveLineClamp = !style()->lineClamp().isNone(); @@ -673,12 +632,11 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren) setHeight(borderTop() + paddingTop()); int minHeight = height() + toAdd; - child = iterator.first(); - while (child) { - // make sure we relayout children if we need it. + for (RenderBox* child = iterator.first(); child; child = iterator.next()) { + // Make sure we relayout children if we need it. if (!haveLineClamp && (relayoutChildren || (child->isReplaced() && (child->style()->width().isPercent() || child->style()->height().isPercent())))) child->setChildNeedsLayout(true, false); - + if (child->isPositioned()) { child->containingBlock()->insertPositionedObject(child); RenderLayer* childLayer = child->layer(); @@ -688,28 +646,27 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren) if (child->style()->hasStaticBlockPosition(style()->isHorizontalWritingMode())) child->setChildNeedsLayout(true, false); } - child = iterator.next(); continue; - } - + } + // Compute the child's vertical margins. child->computeBlockDirectionMargins(this); - + // Add in the child's marginTop to our height. setHeight(height() + child->marginTop()); - + if (!child->needsLayout()) child->markForPaginationRelayoutIfNeeded(); // Now do a layout. child->layoutIfNeeded(); - + // We can place the child now, using our value of box-align. int childX = borderLeft() + paddingLeft(); switch (style()->boxAlign()) { case BCENTER: case BBASELINE: // Baseline just maps to center for vertical boxes - childX += child->marginLeft() + max(0, (contentWidth() - (child->width() + child->marginLeft() + child->marginRight()))/2); + childX += child->marginLeft() + max(0, (contentWidth() - (child->width() + child->marginLeft() + child->marginRight())) / 2); break; case BEND: if (!style()->isLeftToRightDirection()) @@ -724,19 +681,17 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren) childX += contentWidth() - child->marginRight() - child->width(); break; } - + // Place the child. placeChild(child, childX, height()); setHeight(height() + child->height() + child->marginBottom()); - - child = iterator.next(); } yPos = height(); - + if (!iterator.first() && hasLineIfEmpty()) setHeight(height() + lineHeight(true, style()->isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes)); - + setHeight(height() + toAdd); // Negative margins can cause our height to shrink below our minimal height (border/padding). @@ -751,7 +706,7 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren) heightSpecified = true; remainingSpace = borderTop() + paddingTop() + contentHeight() - yPos; - + if (m_flexingChildren) haveFlex = false; // We're done. else if (haveFlex) { @@ -775,33 +730,28 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren) // forces a totalFlex recomputation). int groupRemainingSpaceAtBeginning = groupRemainingSpace; float totalFlex = 0.0f; - child = iterator.first(); - while (child) { + for (RenderBox* child = iterator.first(); child; child = iterator.next()) { if (allowedChildFlex(child, expanding, i)) totalFlex += child->style()->boxFlex(); - child = iterator.next(); } - child = iterator.first(); int spaceAvailableThisPass = groupRemainingSpace; - while (child) { + for (RenderBox* child = iterator.first(); child; child = iterator.next()) { int allowedFlex = allowedChildFlex(child, expanding, i); if (allowedFlex) { int projectedFlex = (allowedFlex == INT_MAX) ? allowedFlex : (int)(allowedFlex * (totalFlex / child->style()->boxFlex())); spaceAvailableThisPass = expanding ? min(spaceAvailableThisPass, projectedFlex) : max(spaceAvailableThisPass, projectedFlex); } - child = iterator.next(); } - // The flex groups may not have any flexible objects this time around. + // The flex groups may not have any flexible objects this time around. if (!spaceAvailableThisPass || totalFlex == 0.0f) { // If we just couldn't grow/shrink any more, then it's time to transition to the next flex group. groupRemainingSpace = 0; continue; } - + // Now distribute the space to objects. - child = iterator.first(); - while (child && spaceAvailableThisPass && totalFlex) { + for (RenderBox* child = iterator.first(); child && spaceAvailableThisPass && totalFlex; child = iterator.next()) { if (allowedChildFlex(child, expanding, i)) { int spaceAdd = (int)(spaceAvailableThisPass * (child->style()->boxFlex()/totalFlex)); if (spaceAdd) { @@ -813,16 +763,14 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren) spaceAvailableThisPass -= spaceAdd; remainingSpace -= spaceAdd; groupRemainingSpace -= spaceAdd; - + totalFlex -= child->style()->boxFlex(); } - child = iterator.next(); } if (groupRemainingSpace == groupRemainingSpaceAtBeginning) { - // this is not advancing, avoid getting stuck by distributing the remaining pixels - child = iterator.first(); + // This is not advancing, avoid getting stuck by distributing the remaining pixels. int spaceAdd = groupRemainingSpace > 0 ? 1 : -1; - while (child && groupRemainingSpace) { + for (RenderBox* child = iterator.first(); child && groupRemainingSpace; child = iterator.next()) { if (allowedChildFlex(child, expanding, i)) { child->setOverrideSize(child->overrideHeight() + spaceAdd); m_flexingChildren = true; @@ -830,7 +778,6 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren) remainingSpace -= spaceAdd; groupRemainingSpace -= spaceAdd; } - child = iterator.next(); } } } while (groupRemainingSpace); @@ -839,7 +786,7 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren) // We didn't find any children that could grow. if (haveFlex && !m_flexingChildren) haveFlex = false; - } + } } while (haveFlex); RenderBlock::finishDelayUpdateScrollInfo(); @@ -850,54 +797,42 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren) if (style()->boxPack() == BJUSTIFY) { // Determine the total number of children. int totalChildren = 0; - child = iterator.first(); - while (child) { - if (child->isPositioned()) { - child = iterator.next(); + for (RenderBox* child = iterator.first(); child; child = iterator.next()) { + if (child->isPositioned()) continue; - } - totalChildren++; - child = iterator.next(); + + ++totalChildren; } - + // Iterate over the children and space them out according to the // justification level. if (totalChildren > 1) { - totalChildren--; + --totalChildren; bool firstChild = true; - child = iterator.first(); - while (child) { - if (child->isPositioned()) { - child = iterator.next(); + for (RenderBox* child = iterator.first(); child; child = iterator.next()) { + if (child->isPositioned()) continue; - } - + if (firstChild) { firstChild = false; - child = iterator.next(); continue; } offset += remainingSpace/totalChildren; remainingSpace -= (remainingSpace/totalChildren); - totalChildren--; - placeChild(child, child->x(), child->y()+offset); - child = iterator.next(); + --totalChildren; + placeChild(child, child->x(), child->y() + offset); } } } else { if (style()->boxPack() == BCENTER) - offset += remainingSpace/2; + offset += remainingSpace / 2; else // END offset += remainingSpace; - child = iterator.first(); - while (child) { - if (child->isPositioned()) { - child = iterator.next(); + for (RenderBox* child = iterator.first(); child; child = iterator.next()) { + if (child->isPositioned()) continue; - } - placeChild(child, child->x(), child->y()+offset); - child = iterator.next(); + placeChild(child, child->x(), child->y() + offset); } } } @@ -905,7 +840,7 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren) // So that the computeLogicalHeight in layoutBlock() knows to relayout positioned objects because of // a height change, we revert our height back to the intrinsic height before returning. if (heightSpecified) - setHeight(oldHeight); + setHeight(oldHeight); } void RenderFlexibleBox::applyLineClamp(FlexBoxIterator& iterator, bool relayoutChildren) @@ -940,16 +875,16 @@ void RenderFlexibleBox::applyLineClamp(FlexBoxIterator& iterator, bool relayoutC for (RenderBox* child = iterator.first(); child; child = iterator.next()) { if (child->isPositioned() || !child->style()->height().isAuto() || !child->isBlockFlow()) continue; - + RenderBlock* blockChild = toRenderBlock(child); int lineCount = blockChild->lineCount(); if (lineCount <= numVisibleLines) continue; - + int newHeight = blockChild->heightForLineCount(numVisibleLines); if (newHeight == child->height()) continue; - + child->setChildNeedsLayout(true, false); child->setOverrideSize(newHeight); m_flexingChildren = true; @@ -962,11 +897,11 @@ void RenderFlexibleBox::applyLineClamp(FlexBoxIterator& iterator, bool relayoutC continue; // Get the last line - RootInlineBox* lastLine = blockChild->lineAtIndex(lineCount-1); + RootInlineBox* lastLine = blockChild->lineAtIndex(lineCount - 1); if (!lastLine) continue; - RootInlineBox* lastVisibleLine = blockChild->lineAtIndex(numVisibleLines-1); + RootInlineBox* lastVisibleLine = blockChild->lineAtIndex(numVisibleLines - 1); if (!lastVisibleLine) continue; @@ -975,7 +910,7 @@ void RenderFlexibleBox::applyLineClamp(FlexBoxIterator& iterator, bool relayoutC DEFINE_STATIC_LOCAL(AtomicString, ellipsisStr, (&horizontalEllipsis, 1)); const Font& font = style(numVisibleLines == 1)->font(); - // Get ellipsis width, and if the last child is an anchor, it will go after the ellipsis, so add in a space and the anchor width too + // Get ellipsis width, and if the last child is an anchor, it will go after the ellipsis, so add in a space and the anchor width too int totalWidth; InlineBox* anchorBox = lastLine->lastChild(); if (anchorBox && anchorBox->renderer()->style()->isLink()) @@ -988,7 +923,7 @@ void RenderFlexibleBox::applyLineClamp(FlexBoxIterator& iterator, bool relayoutC // See if this width can be accommodated on the last visible line RenderBlock* destBlock = toRenderBlock(lastVisibleLine->renderer()); RenderBlock* srcBlock = toRenderBlock(lastLine->renderer()); - + // FIXME: Directions of src/destBlock could be different from our direction and from one another. if (!srcBlock->style()->isLeftToRightDirection()) continue; @@ -1028,57 +963,55 @@ int RenderFlexibleBox::allowedChildFlex(RenderBox* child, bool expanding, unsign { if (child->isPositioned() || child->style()->boxFlex() == 0.0f || child->style()->boxFlexGroup() != group) return 0; - + if (expanding) { if (isHorizontal()) { // FIXME: For now just handle fixed values. - int maxW = INT_MAX; - int w = child->overrideWidth() - child->borderAndPaddingWidth(); - if (!child->style()->maxWidth().isUndefined() && - child->style()->maxWidth().isFixed()) - maxW = child->style()->maxWidth().value(); + int maxWidth = INT_MAX; + int width = child->overrideWidth() - child->borderAndPaddingWidth(); + if (!child->style()->maxWidth().isUndefined() && child->style()->maxWidth().isFixed()) + maxWidth = child->style()->maxWidth().value(); else if (child->style()->maxWidth().type() == Intrinsic) - maxW = child->maxPreferredLogicalWidth(); + maxWidth = child->maxPreferredLogicalWidth(); else if (child->style()->maxWidth().type() == MinIntrinsic) - maxW = child->minPreferredLogicalWidth(); - if (maxW == INT_MAX) - return maxW; - return max(0, maxW - w); + maxWidth = child->minPreferredLogicalWidth(); + if (maxWidth == INT_MAX) + return maxWidth; + return max(0, maxWidth - width); } else { // FIXME: For now just handle fixed values. - int maxH = INT_MAX; - int h = child->overrideHeight() - child->borderAndPaddingHeight(); - if (!child->style()->maxHeight().isUndefined() && - child->style()->maxHeight().isFixed()) - maxH = child->style()->maxHeight().value(); - if (maxH == INT_MAX) - return maxH; - return max(0, maxH - h); + int maxHeight = INT_MAX; + int height = child->overrideHeight() - child->borderAndPaddingHeight(); + if (!child->style()->maxHeight().isUndefined() && child->style()->maxHeight().isFixed()) + maxHeight = child->style()->maxHeight().value(); + if (maxHeight == INT_MAX) + return maxHeight; + return max(0, maxHeight - height); } } // FIXME: For now just handle fixed values. if (isHorizontal()) { - int minW = child->minPreferredLogicalWidth(); - int w = child->overrideWidth() - child->borderAndPaddingWidth(); + int minWidth = child->minPreferredLogicalWidth(); + int width = child->overrideWidth() - child->borderAndPaddingWidth(); if (child->style()->minWidth().isFixed()) - minW = child->style()->minWidth().value(); + minWidth = child->style()->minWidth().value(); else if (child->style()->minWidth().type() == Intrinsic) - minW = child->maxPreferredLogicalWidth(); + minWidth = child->maxPreferredLogicalWidth(); else if (child->style()->minWidth().type() == MinIntrinsic) - minW = child->minPreferredLogicalWidth(); - - int allowedShrinkage = min(0, minW - w); + minWidth = child->minPreferredLogicalWidth(); + + int allowedShrinkage = min(0, minWidth - width); return allowedShrinkage; } else { if (child->style()->minHeight().isFixed()) { - int minH = child->style()->minHeight().value(); - int h = child->overrideHeight() - child->borderAndPaddingHeight(); - int allowedShrinkage = min(0, minH - h); + int minHeight = child->style()->minHeight().value(); + int height = child->overrideHeight() - child->borderAndPaddingHeight(); + int allowedShrinkage = min(0, minHeight - height); return allowedShrinkage; } } - + return 0; } diff --git a/Source/WebCore/rendering/RenderObject.cpp b/Source/WebCore/rendering/RenderObject.cpp index 8caef04..f37753e 100644 --- a/Source/WebCore/rendering/RenderObject.cpp +++ b/Source/WebCore/rendering/RenderObject.cpp @@ -2029,6 +2029,10 @@ RenderObject* RenderObject::container(RenderBoxModelObject* repaintContainer, bo while (o && o->style()->position() == StaticPosition && !o->isRenderView() && !(o->hasTransform() && o->isRenderBlock())) { if (repaintContainerSkipped && o == repaintContainer) *repaintContainerSkipped = true; +#if ENABLE(SVG) + if (o->isSVGForeignObject()) // foreignObject is the containing block for contents inside it + break; +#endif o = o->parent(); } } diff --git a/Source/WebCore/rendering/RenderObject.h b/Source/WebCore/rendering/RenderObject.h index 005c453..f5fe562 100644 --- a/Source/WebCore/rendering/RenderObject.h +++ b/Source/WebCore/rendering/RenderObject.h @@ -312,6 +312,7 @@ public: inline bool isBeforeContent() const; inline bool isAfterContent() const; + inline bool isBeforeOrAfterContent() const; static inline bool isBeforeContent(const RenderObject* obj) { return obj && obj->isBeforeContent(); } static inline bool isAfterContent(const RenderObject* obj) { return obj && obj->isAfterContent(); } @@ -917,6 +918,11 @@ inline bool RenderObject::isAfterContent() const return true; } +inline bool RenderObject::isBeforeOrAfterContent() const +{ + return isBeforeContent() || isAfterContent(); +} + inline void RenderObject::setNeedsLayout(bool b, bool markParents) { bool alreadyNeededLayout = m_needsLayout; diff --git a/Source/WebCore/rendering/RenderReplaced.cpp b/Source/WebCore/rendering/RenderReplaced.cpp index c27d336..09a7944 100644 --- a/Source/WebCore/rendering/RenderReplaced.cpp +++ b/Source/WebCore/rendering/RenderReplaced.cpp @@ -57,6 +57,14 @@ RenderReplaced::~RenderReplaced() { } +void RenderReplaced::destroy() +{ + if (!documentBeingDestroyed() && parent()) + parent()->dirtyLinesFromChangedChild(this); + + RenderBox::destroy(); +} + void RenderReplaced::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) { RenderBox::styleDidChange(diff, oldStyle); diff --git a/Source/WebCore/rendering/RenderReplaced.h b/Source/WebCore/rendering/RenderReplaced.h index d6ebba6..29fc71c 100644 --- a/Source/WebCore/rendering/RenderReplaced.h +++ b/Source/WebCore/rendering/RenderReplaced.h @@ -32,6 +32,8 @@ public: RenderReplaced(Node*, const IntSize& intrinsicSize); virtual ~RenderReplaced(); + virtual void destroy(); + protected: virtual void layout(); diff --git a/Source/WebCore/rendering/RenderWidget.cpp b/Source/WebCore/rendering/RenderWidget.cpp index 894d689..97444cd 100644 --- a/Source/WebCore/rendering/RenderWidget.cpp +++ b/Source/WebCore/rendering/RenderWidget.cpp @@ -125,6 +125,10 @@ void RenderWidget::destroy() document()->axObjectCache()->childrenChanged(this->parent()); document()->axObjectCache()->remove(this); } + + if (!documentBeingDestroyed() && parent()) + parent()->dirtyLinesFromChangedChild(this); + remove(); if (m_hasCounterNodeMap) diff --git a/Source/WebCore/workers/WorkerLocation.cpp b/Source/WebCore/workers/WorkerLocation.cpp index b934abd..319a528 100644 --- a/Source/WebCore/workers/WorkerLocation.cpp +++ b/Source/WebCore/workers/WorkerLocation.cpp @@ -36,7 +36,7 @@ namespace WebCore { String WorkerLocation::href() const { - return m_url.hasPath() ? m_url.prettyURL() : m_url.prettyURL() + "/"; + return m_url.string(); } String WorkerLocation::protocol() const @@ -74,11 +74,6 @@ String WorkerLocation::hash() const return m_url.fragmentIdentifier().isEmpty() ? "" : "#" + m_url.fragmentIdentifier(); } -String WorkerLocation::toString() const -{ - return m_url.hasPath() ? m_url.prettyURL() : m_url.prettyURL() + "/"; -} - } // namespace WebCore diff --git a/Source/WebCore/workers/WorkerLocation.h b/Source/WebCore/workers/WorkerLocation.h index 5200e35..692c0e3 100644 --- a/Source/WebCore/workers/WorkerLocation.h +++ b/Source/WebCore/workers/WorkerLocation.h @@ -30,10 +30,10 @@ #if ENABLE(WORKERS) #include "KURL.h" -#include <wtf/Forward.h> #include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> #include <wtf/RefPtr.h> +#include <wtf/text/WTFString.h> namespace WebCore { @@ -57,7 +57,7 @@ namespace WebCore { String search() const; String hash() const; - String toString() const; + String toString() const { return href(); } private: WorkerLocation(const KURL& url) : m_url(url) { } |