diff options
Diffstat (limited to 'Source/WebCore/rendering')
143 files changed, 2682 insertions, 1385 deletions
diff --git a/Source/WebCore/rendering/AutoTableLayout.cpp b/Source/WebCore/rendering/AutoTableLayout.cpp index 36ba164dc..dae5a15ea 100644 --- a/Source/WebCore/rendering/AutoTableLayout.cpp +++ b/Source/WebCore/rendering/AutoTableLayout.cpp @@ -49,7 +49,7 @@ void AutoTableLayout::recalcColumn(unsigned effCol) RenderTableCell* fixedContributor = 0; RenderTableCell* maxContributor = 0; - for (RenderObject* child = m_table->firstChild(); child; child = child->nextSibling()) { + for (RenderObject* child = m_table->children()->firstChild(); child; child = child->nextSibling()) { if (child->isRenderTableCol()) toRenderTableCol(child)->computePreferredLogicalWidths(); else if (child->isTableSection()) { @@ -62,7 +62,7 @@ void AutoTableLayout::recalcColumn(unsigned effCol) if (current.inColSpan || !cell) continue; - bool cellHasContent = cell->firstChild() || cell->style()->hasBorder() || cell->style()->hasPadding(); + bool cellHasContent = cell->children()->firstChild() || cell->style()->hasBorder() || cell->style()->hasPadding(); if (cellHasContent) columnLayout.emptyCellsOnly = false; diff --git a/Source/WebCore/rendering/ClipPathOperation.h b/Source/WebCore/rendering/ClipPathOperation.h index c469d6df8..a1f77e243 100644 --- a/Source/WebCore/rendering/ClipPathOperation.h +++ b/Source/WebCore/rendering/ClipPathOperation.h @@ -42,7 +42,7 @@ namespace WebCore { class ClipPathOperation : public RefCounted<ClipPathOperation> { public: enum OperationType { - // FIXME: Add referencing for IRI https://bugs.webkit.org/show_bug.cgi?id=96381 + REFERENCE, SHAPE }; @@ -63,6 +63,36 @@ protected: OperationType m_type; }; +class ReferenceClipPathOperation : public ClipPathOperation { +public: + static PassRefPtr<ReferenceClipPathOperation> create(const String& url, const String& fragment) + { + return adoptRef(new ReferenceClipPathOperation(url, fragment)); + } + + const String& url() const { return m_url; } + const String& fragment() const { return m_fragment; } + +private: + virtual bool operator==(const ClipPathOperation& o) const + { + if (!isSameType(o)) + return false; + const ReferenceClipPathOperation* other = static_cast<const ReferenceClipPathOperation*>(&o); + return m_url == other->m_url; + } + + ReferenceClipPathOperation(const String& url, const String& fragment) + : ClipPathOperation(REFERENCE) + , m_url(url) + , m_fragment(fragment) + { + } + + String m_url; + String m_fragment; +}; + class ShapeClipPathOperation : public ClipPathOperation { public: static PassRefPtr<ShapeClipPathOperation> create(PassRefPtr<BasicShape> shape) diff --git a/Source/WebCore/rendering/ExclusionPolygon.cpp b/Source/WebCore/rendering/ExclusionPolygon.cpp new file mode 100644 index 000000000..e704abfce --- /dev/null +++ b/Source/WebCore/rendering/ExclusionPolygon.cpp @@ -0,0 +1,306 @@ +/* + * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER 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 "ExclusionPolygon.h" + +#include <wtf/MathExtras.h> + +namespace WebCore { + +enum EdgeIntersectionType { + Normal, + VertexMinY, + VertexMaxY, + VertexYBoth +}; + +struct EdgeIntersection { + const ExclusionPolygonEdge* edge; + FloatPoint point; + EdgeIntersectionType type; +}; + +static bool compareEdgeMinY(const ExclusionPolygonEdge* e1, const ExclusionPolygonEdge* e2) +{ + return e1->minY() < e2->minY(); +} + +ExclusionPolygon::ExclusionPolygon(PassOwnPtr<Vector<FloatPoint> > vertices, WindRule fillRule) + : ExclusionShape() + , m_vertices(vertices) + , m_fillRule(fillRule) +{ + // FIXME: Handle polygons defined with less than 3 non-colinear vertices. + + unsigned nVertices = numberOfVertices(); + m_edges.resize(nVertices); + Vector<ExclusionPolygonEdge*> sortedEdgesMinY(nVertices); + + const FloatPoint& vertex0 = vertexAt(0); + float minX = vertex0.x(); + float minY = vertex0.y(); + float maxX = minX; + float maxY = minY; + + for (unsigned i = 0; i < nVertices; i++) { + const FloatPoint& vertex = vertexAt(i); + + minX = std::min(vertex.x(), minX); + maxX = std::max(vertex.x(), maxX); + minY = std::min(vertex.y(), minY); + maxY = std::max(vertex.y(), maxY); + + m_edges[i].polygon = this; + m_edges[i].index1 = i; + m_edges[i].index2 = (i + 1) % nVertices; + + sortedEdgesMinY[i] = &m_edges[i]; + } + + m_boundingBox.setX(minX); + m_boundingBox.setY(minY); + m_boundingBox.setWidth(maxX - minX); + m_boundingBox.setHeight(maxY - minY); + + std::sort(sortedEdgesMinY.begin(), sortedEdgesMinY.end(), WebCore::compareEdgeMinY); + + for (unsigned i = 0; i < m_edges.size(); i++) { + ExclusionPolygonEdge* edge = &m_edges[i]; + m_edgeTree.add(EdgeInterval(edge->minY(), edge->maxY(), edge)); + } +} + +static bool computeXIntersection(const ExclusionPolygonEdge* edgePointer, float y, EdgeIntersection& result) +{ + const ExclusionPolygonEdge& edge = *edgePointer; + + if (edge.minY() > y || edge.maxY() < y) + return false; + + const FloatPoint& vertex1 = edge.vertex1(); + const FloatPoint& vertex2 = edge.vertex2(); + float dy = vertex2.y() - vertex1.y(); + + float intersectionX; + EdgeIntersectionType intersectionType; + + if (!dy) { + intersectionType = VertexYBoth; + intersectionX = edge.minX(); + } else if (y == edge.minY()) { + intersectionType = VertexMinY; + intersectionX = (vertex1.y() < vertex2.y()) ? vertex1.x() : vertex2.x(); + } else if (y == edge.maxY()) { + intersectionType = VertexMaxY; + intersectionX = (vertex1.y() > vertex2.y()) ? vertex1.x() : vertex2.x(); + } else { + intersectionType = Normal; + intersectionX = ((y - vertex1.y()) * (vertex2.x() - vertex1.x()) / dy) + vertex1.x(); + } + + result.edge = edgePointer; + result.type = intersectionType; + result.point.set(intersectionX, y); + + return true; +} + +float ExclusionPolygon::rightVertexY(unsigned index) const +{ + unsigned nVertices = numberOfVertices(); + const FloatPoint& vertex1 = vertexAt((index + 1) % nVertices); + const FloatPoint& vertex2 = vertexAt((index - 1) % nVertices); + + if (vertex1.x() == vertex2.x()) + return vertex1.y() > vertex2.y() ? vertex1.y() : vertex2.y(); + return vertex1.x() > vertex2.x() ? vertex1.y() : vertex2.y(); +} + +static bool appendIntervalX(float x, bool inside, Vector<ExclusionInterval>& result) +{ + if (!inside) + result.append(ExclusionInterval(x)); + else + result[result.size() - 1].x2 = x; + + return !inside; +} + +static bool compareEdgeIntersectionX(const EdgeIntersection& intersection1, const EdgeIntersection& intersection2) +{ + float x1 = intersection1.point.x(); + float x2 = intersection2.point.x(); + return (x1 == x2) ? intersection1.type < intersection2.type : x1 < x2; +} + +void ExclusionPolygon::computeXIntersections(float y, Vector<ExclusionInterval>& result) const +{ + Vector<ExclusionPolygon::EdgeInterval> overlappingEdges; + m_edgeTree.allOverlaps(ExclusionPolygon::EdgeInterval(y, y, 0), overlappingEdges); + + Vector<EdgeIntersection> intersections; + EdgeIntersection intersection; + for (unsigned i = 0; i < overlappingEdges.size(); i++) { + ExclusionPolygonEdge* edge = static_cast<ExclusionPolygonEdge*>(overlappingEdges[i].data()); + if (computeXIntersection(edge, y, intersection)) + intersections.append(intersection); + } + if (intersections.size() < 2) + return; + + std::sort(intersections.begin(), intersections.end(), WebCore::compareEdgeIntersectionX); + + unsigned index = 0; + int windCount = 0; + bool inside = false; + + while (index < intersections.size()) { + const EdgeIntersection& thisIntersection = intersections[index]; + + if (index + 1 < intersections.size()) { + const EdgeIntersection& nextIntersection = intersections[index + 1]; + if ((thisIntersection.point.x() == nextIntersection.point.x()) && (thisIntersection.type == VertexMinY || thisIntersection.type == VertexMaxY)) { + if (thisIntersection.type == nextIntersection.type) { + // Skip pairs of intersections whose types are VertexMaxY,VertexMaxY and VertexMinY,VertexMinY. + index += 2; + } else { + // Replace pairs of intersections whose types are VertexMinY,VertexMaxY or VertexMaxY,VertexMinY with one VertexMinY intersection. + if (nextIntersection.type == VertexMaxY) + intersections[index + 1] = thisIntersection; + index++; + } + continue; + } + } + + const ExclusionPolygonEdge& thisEdge = *thisIntersection.edge; + bool crossing = !windCount; + + if (fillRule() == RULE_EVENODD) { + windCount += (thisEdge.vertex2().y() > thisEdge.vertex1().y()) ? 1 : -1; + crossing = crossing || !windCount; + } + + if ((thisIntersection.type == Normal) || (thisIntersection.type == VertexMinY)) { + if (crossing) + inside = appendIntervalX(thisIntersection.point.x(), inside, result); + } else if (thisIntersection.type == VertexMaxY) { + int vertexIndex = (thisEdge.vertex2().y() > thisEdge.vertex1().y()) ? thisEdge.index2 : thisEdge.index1; + if (crossing && rightVertexY(vertexIndex) > y) + inside = appendIntervalX(thisEdge.maxX(), inside, result); + } else if (thisIntersection.type == VertexYBoth) + result.append(ExclusionInterval(thisEdge.minX(), thisEdge.maxX())); + + index++; + } +} + +// Return the X projections of the edges that overlap y1,y2. +void ExclusionPolygon::computeEdgeIntersections(float y1, float y2, Vector<ExclusionInterval>& result) const +{ + Vector<ExclusionPolygon::EdgeInterval> overlappingEdges; + m_edgeTree.allOverlaps(ExclusionPolygon::EdgeInterval(y1, y2, 0), overlappingEdges); + + EdgeIntersection intersection; + for (unsigned i = 0; i < overlappingEdges.size(); i++) { + const ExclusionPolygonEdge *edge = static_cast<ExclusionPolygonEdge*>(overlappingEdges[i].data()); + float x1; + float x2; + + if (edge->minY() < y1) { + computeXIntersection(edge, y1, intersection); + x1 = intersection.point.x(); + } else + x1 = (edge->vertex1().y() < edge->vertex2().y()) ? edge->vertex1().x() : edge->vertex2().x(); + + if (edge->maxY() > y2) { + computeXIntersection(edge, y2, intersection); + x2 = intersection.point.x(); + } else + x2 = (edge->vertex1().y() > edge->vertex2().y()) ? edge->vertex1().x() : edge->vertex2().x(); + + if (x1 > x2) + std::swap(x1, x2); + + result.append(ExclusionInterval(x1, x2)); + } + + sortExclusionIntervals(result); +} + +void ExclusionPolygon::getExcludedIntervals(float logicalTop, float logicalBottom, SegmentList& result) const +{ + float y1 = minYForLogicalLine(logicalTop, logicalBottom); + float y2 = maxYForLogicalLine(logicalTop, logicalBottom); + + Vector<ExclusionInterval> y1XIntervals, y2XIntervals; + computeXIntersections(y1, y1XIntervals); + computeXIntersections(y2, y2XIntervals); + + Vector<ExclusionInterval> mergedIntervals; + mergeExclusionIntervals(y1XIntervals, y2XIntervals, mergedIntervals); + + Vector<ExclusionInterval> edgeIntervals; + computeEdgeIntersections(y1, y2, edgeIntervals); + + Vector<ExclusionInterval> excludedIntervals; + mergeExclusionIntervals(mergedIntervals, edgeIntervals, excludedIntervals); + + for (unsigned i = 0; i < excludedIntervals.size(); i++) { + ExclusionInterval interval = excludedIntervals[i]; + result.append(LineSegment(interval.x1, interval.x2)); + } +} + +void ExclusionPolygon::getIncludedIntervals(float logicalTop, float logicalBottom, SegmentList& result) const +{ + float y1 = minYForLogicalLine(logicalTop, logicalBottom); + float y2 = maxYForLogicalLine(logicalTop, logicalBottom); + + Vector<ExclusionInterval> y1XIntervals, y2XIntervals; + computeXIntersections(y1, y1XIntervals); + computeXIntersections(y2, y2XIntervals); + + Vector<ExclusionInterval> commonIntervals; + intersectExclusionIntervals(y1XIntervals, y2XIntervals, commonIntervals); + + Vector<ExclusionInterval> edgeIntervals; + computeEdgeIntersections(y1, y2, edgeIntervals); + + Vector<ExclusionInterval> includedIntervals; + subtractExclusionIntervals(commonIntervals, edgeIntervals, includedIntervals); + + for (unsigned i = 0; i < includedIntervals.size(); i++) { + ExclusionInterval interval = includedIntervals[i]; + result.append(LineSegment(interval.x1, interval.x2)); + } +} + +} // namespace WebCore diff --git a/Source/WebCore/rendering/ExclusionPolygon.h b/Source/WebCore/rendering/ExclusionPolygon.h new file mode 100644 index 000000000..6397d0ee7 --- /dev/null +++ b/Source/WebCore/rendering/ExclusionPolygon.h @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ExclusionPolygon_h +#define ExclusionPolygon_h + +#include "ExclusionInterval.h" +#include "ExclusionShape.h" +#include "FloatPoint.h" +#include "FloatRect.h" +#include "PODIntervalTree.h" +#include "WindRule.h" +#include <wtf/MathExtras.h> +#include <wtf/OwnPtr.h> +#include <wtf/PassOwnPtr.h> +#include <wtf/Vector.h> + +namespace WebCore { + +struct ExclusionPolygonEdge; + +// This class is used by PODIntervalTree for debugging. +#ifndef NDEBUG +template <class> struct ValueToString; +#endif + +class ExclusionPolygon : public ExclusionShape { + WTF_MAKE_NONCOPYABLE(ExclusionPolygon); +public: + ExclusionPolygon(PassOwnPtr<Vector<FloatPoint> > vertices, WindRule fillRule); + + const FloatPoint& vertexAt(unsigned index) const { return (*m_vertices)[index]; } + unsigned numberOfVertices() const { return m_vertices->size(); } + WindRule fillRule() const { return m_fillRule; } + + virtual FloatRect shapeLogicalBoundingBox() const OVERRIDE { return internalToLogicalBoundingBox(m_boundingBox); } + virtual void getExcludedIntervals(float logicalTop, float logicalBottom, SegmentList&) const OVERRIDE; + virtual void getIncludedIntervals(float logicalTop, float logicalBottom, SegmentList&) const OVERRIDE; + +private: + float rightVertexY(unsigned) const; + void computeXIntersections(float y, Vector<ExclusionInterval>&) const; + void computeEdgeIntersections(float minY, float maxY, Vector<ExclusionInterval>&) const; + + typedef PODInterval<float, ExclusionPolygonEdge*> EdgeInterval; + typedef PODIntervalTree<float, ExclusionPolygonEdge*> EdgeIntervalTree; + + OwnPtr<Vector<FloatPoint> > m_vertices; + WindRule m_fillRule; + FloatRect m_boundingBox; + Vector<ExclusionPolygonEdge> m_edges; + EdgeIntervalTree m_edgeTree; +}; + +// EdgeIntervalTree nodes store minY, maxY, and a ("UserData") pointer to an ExclusionPolygonEdge. Edge vertex +// index1 is less than index2, except the last edge, where index2 is 0. When a polygon edge is defined by 3 +// or more colinear vertices, index2 can be the the index of the last colinear vertex. +struct ExclusionPolygonEdge { + const FloatPoint& vertex1() const + { + ASSERT(polygon); + return polygon->vertexAt(index1); + } + + const FloatPoint& vertex2() const + { + ASSERT(polygon); + return polygon->vertexAt(index2); + } + + float minX() const { return std::min(vertex1().x(), vertex2().x()); } + float minY() const { return std::min(vertex1().y(), vertex2().y()); } + float maxX() const { return std::max(vertex1().x(), vertex2().x()); } + float maxY() const { return std::max(vertex1().y(), vertex2().y()); } + + const ExclusionPolygon* polygon; + unsigned index1; + unsigned index2; +}; + +// These structures are used by PODIntervalTree for debugging.1 +#ifndef NDEBUG +template <> struct ValueToString<float> { + static String string(const float value) { return String::number(value); } +}; + +template<> struct ValueToString<ExclusionPolygonEdge*> { + static String string(const ExclusionPolygonEdge* edge) { return String::format("%p (%f,%f %f,%f)", edge, edge->vertex1().x(), edge->vertex1().y(), edge->vertex2().x(), edge->vertex2().y()); } +}; +#endif + +} // namespace WebCore + +#endif // ExclusionPolygon_h diff --git a/Source/WebCore/rendering/ExclusionShape.cpp b/Source/WebCore/rendering/ExclusionShape.cpp index 0f430ef04..c3ec8acaa 100644 --- a/Source/WebCore/rendering/ExclusionShape.cpp +++ b/Source/WebCore/rendering/ExclusionShape.cpp @@ -31,10 +31,10 @@ #include "ExclusionShape.h" #include "BasicShapeFunctions.h" +#include "ExclusionPolygon.h" #include "ExclusionRectangle.h" #include "FloatSize.h" #include "LengthFunctions.h" -#include "NotImplemented.h" #include "WindRule.h" #include <wtf/MathExtras.h> #include <wtf/OwnPtr.h> @@ -60,6 +60,11 @@ static PassOwnPtr<ExclusionShape> createExclusionEllipse(const FloatPoint& cente return adoptPtr(new ExclusionRectangle(FloatRect(center.x() - radii.width(), center.y() - radii.height(), radii.width()*2, radii.height()*2), radii)); } +static PassOwnPtr<ExclusionShape> createExclusionPolygon(PassOwnPtr<Vector<FloatPoint> > vertices, WindRule fillRule) +{ + return adoptPtr(new ExclusionPolygon(vertices, fillRule)); +} + // If the writingMode is vertical, then the BasicShape's (physical) x and y coordinates are swapped, so that // line segments are parallel to the internal coordinate system's X axis. @@ -87,8 +92,8 @@ PassOwnPtr<ExclusionShape> ExclusionShape::createExclusionShape(const BasicShape float radiusY = radiusYLength.isUndefined() ? 0 : floatValueForLength(radiusYLength, boxHeight); exclusionShape = horizontalWritingMode - ? createExclusionRectangle(FloatRect(x, y, width, height), FloatSize(radiusX, radiusY)) - : createExclusionRectangle(FloatRect(y, x, height, width), FloatSize(radiusY, radiusX)); + ? createExclusionRectangle(FloatRect(x, y, width, height), FloatSize(radiusX, radiusY)) + : createExclusionRectangle(FloatRect(y, x, height, width), FloatSize(radiusY, radiusX)); break; } @@ -99,8 +104,8 @@ PassOwnPtr<ExclusionShape> ExclusionShape::createExclusionShape(const BasicShape float radius = floatValueForLength(circle->radius(), std::max(boxHeight, boxWidth)); exclusionShape = horizontalWritingMode - ? createExclusionCircle(FloatPoint(centerX, centerY), radius) - : createExclusionCircle(FloatPoint(centerY, centerX), radius); + ? createExclusionCircle(FloatPoint(centerX, centerY), radius) + : createExclusionCircle(FloatPoint(centerY, centerX), radius); break; } @@ -112,13 +117,26 @@ PassOwnPtr<ExclusionShape> ExclusionShape::createExclusionShape(const BasicShape float radiusY = floatValueForLength(ellipse->radiusY(), boxHeight); exclusionShape = horizontalWritingMode - ? createExclusionEllipse(FloatPoint(centerX, centerY), FloatSize(radiusX, radiusY)) - : createExclusionEllipse(FloatPoint(centerY, centerX), FloatSize(radiusY, radiusX)); + ? createExclusionEllipse(FloatPoint(centerX, centerY), FloatSize(radiusX, radiusY)) + : createExclusionEllipse(FloatPoint(centerY, centerX), FloatSize(radiusY, radiusX)); break; } - case BasicShape::BASIC_SHAPE_POLYGON: - notImplemented(); + case BasicShape::BASIC_SHAPE_POLYGON: { + const BasicShapePolygon* polygon = static_cast<const BasicShapePolygon*>(basicShape); + const Vector<Length>& values = polygon->values(); + size_t valuesSize = values.size(); + ASSERT(!(valuesSize % 2)); + Vector<FloatPoint>* vertices = new Vector<FloatPoint>(valuesSize / 2); + for (unsigned i = 0; i < valuesSize; i += 2) { + FloatPoint vertex( + floatValueForLength(values.at(i), boxWidth), + floatValueForLength(values.at(i + 1), boxHeight)); + (*vertices)[i / 2] = horizontalWritingMode ? vertex : vertex.transposedPoint(); + } + exclusionShape = createExclusionPolygon(adoptPtr(vertices), polygon->windRule()); + break; + } default: ASSERT_NOT_REACHED(); diff --git a/Source/WebCore/rendering/WrapShapeInfo.cpp b/Source/WebCore/rendering/ExclusionShapeInsideInfo.cpp index 40c07c15f..bf7f30dfd 100644 --- a/Source/WebCore/rendering/WrapShapeInfo.cpp +++ b/Source/WebCore/rendering/ExclusionShapeInsideInfo.cpp @@ -28,7 +28,7 @@ */ #include "config.h" -#include "WrapShapeInfo.h" +#include "ExclusionShapeInsideInfo.h" #if ENABLE(CSS_EXCLUSIONS) @@ -39,68 +39,68 @@ namespace WebCore { -typedef HashMap<const RenderBlock*, OwnPtr<WrapShapeInfo> > WrapShapeInfoMap; +typedef HashMap<const RenderBlock*, OwnPtr<ExclusionShapeInsideInfo> > ExclusionShapeInsideInfoMap; -static WrapShapeInfoMap& wrapShapeInfoMap() +static ExclusionShapeInsideInfoMap& exclusionShapeInsideInfoMap() { - DEFINE_STATIC_LOCAL(WrapShapeInfoMap, staticWrapShapeInfoMap, ()); - return staticWrapShapeInfoMap; + DEFINE_STATIC_LOCAL(ExclusionShapeInsideInfoMap, staticExclusionShapeInsideInfoMap, ()); + return staticExclusionShapeInsideInfoMap; } -WrapShapeInfo::WrapShapeInfo(RenderBlock* block) +ExclusionShapeInsideInfo::ExclusionShapeInsideInfo(RenderBlock* block) : m_block(block) - , m_wrapShapeSizeDirty(true) + , m_shapeSizeDirty(true) { } -WrapShapeInfo::~WrapShapeInfo() +ExclusionShapeInsideInfo::~ExclusionShapeInsideInfo() { } -WrapShapeInfo* WrapShapeInfo::ensureWrapShapeInfoForRenderBlock(RenderBlock* block) +ExclusionShapeInsideInfo* ExclusionShapeInsideInfo::ensureExclusionShapeInsideInfoForRenderBlock(RenderBlock* block) { - WrapShapeInfoMap::AddResult result = wrapShapeInfoMap().add(block, create(block)); - return result.iterator->second.get(); + ExclusionShapeInsideInfoMap::AddResult result = exclusionShapeInsideInfoMap().add(block, create(block)); + return result.iterator->value.get(); } -WrapShapeInfo* WrapShapeInfo::wrapShapeInfoForRenderBlock(const RenderBlock* block) +ExclusionShapeInsideInfo* ExclusionShapeInsideInfo::exclusionShapeInsideInfoForRenderBlock(const RenderBlock* block) { - ASSERT(block->style()->wrapShapeInside()); - return wrapShapeInfoMap().get(block); + ASSERT(block->style()->shapeInside()); + return exclusionShapeInsideInfoMap().get(block); } -bool WrapShapeInfo::isWrapShapeInfoEnabledForRenderBlock(const RenderBlock* block) +bool ExclusionShapeInsideInfo::isExclusionShapeInsideInfoEnabledForRenderBlock(const RenderBlock* block) { // FIXME: Bug 89707: Enable shape inside for non-rectangular shapes - BasicShape* shape = block->style()->wrapShapeInside(); - return (shape && shape->type() == BasicShape::BASIC_SHAPE_RECTANGLE); + BasicShape* shape = block->style()->shapeInside(); + return shape && (shape->type() == BasicShape::BASIC_SHAPE_RECTANGLE || shape->type() == BasicShape::BASIC_SHAPE_POLYGON); } -void WrapShapeInfo::removeWrapShapeInfoForRenderBlock(const RenderBlock* block) +void ExclusionShapeInsideInfo::removeExclusionShapeInsideInfoForRenderBlock(const RenderBlock* block) { - if (!block->style() || !block->style()->wrapShapeInside()) + if (!block->style() || !block->style()->shapeInside()) return; - wrapShapeInfoMap().remove(block); + exclusionShapeInsideInfoMap().remove(block); } -void WrapShapeInfo::computeShapeSize(LayoutUnit logicalWidth, LayoutUnit logicalHeight) +void ExclusionShapeInsideInfo::computeShapeSize(LayoutUnit logicalWidth, LayoutUnit logicalHeight) { - if (!m_wrapShapeSizeDirty && logicalWidth == m_logicalWidth && logicalHeight == m_logicalHeight) + if (!m_shapeSizeDirty && logicalWidth == m_logicalWidth && logicalHeight == m_logicalHeight) return; - m_wrapShapeSizeDirty = false; + m_shapeSizeDirty = false; m_logicalWidth = logicalWidth; m_logicalHeight = logicalHeight; // FIXME: Bug 89993: The wrap shape may come from the parent object - BasicShape* shape = m_block->style()->wrapShapeInside(); + BasicShape* shape = m_block->style()->shapeInside(); ASSERT(shape); m_shape = ExclusionShape::createExclusionShape(shape, logicalWidth, logicalHeight, m_block->style()->writingMode()); ASSERT(m_shape); } -bool WrapShapeInfo::computeSegmentsForLine(LayoutUnit lineTop, LayoutUnit lineBottom) +bool ExclusionShapeInsideInfo::computeSegmentsForLine(LayoutUnit lineTop, LayoutUnit lineBottom) { ASSERT(lineTop <= lineBottom); m_lineTop = lineTop; diff --git a/Source/WebCore/rendering/WrapShapeInfo.h b/Source/WebCore/rendering/ExclusionShapeInsideInfo.h index cd9717a72..9db1b101e 100644 --- a/Source/WebCore/rendering/WrapShapeInfo.h +++ b/Source/WebCore/rendering/ExclusionShapeInsideInfo.h @@ -27,8 +27,8 @@ * SUCH DAMAGE. */ -#ifndef WrapShapeInfo_h -#define WrapShapeInfo_h +#ifndef ExclusionShapeInsideInfo_h +#define ExclusionShapeInsideInfo_h #if ENABLE(CSS_EXCLUSIONS) @@ -43,16 +43,16 @@ namespace WebCore { class RenderBlock; -class WrapShapeInfo { +class ExclusionShapeInsideInfo { WTF_MAKE_FAST_ALLOCATED; public: - ~WrapShapeInfo(); + ~ExclusionShapeInsideInfo(); - static PassOwnPtr<WrapShapeInfo> create(RenderBlock* block) { return adoptPtr(new WrapShapeInfo(block)); } - static WrapShapeInfo* wrapShapeInfoForRenderBlock(const RenderBlock*); - static WrapShapeInfo* ensureWrapShapeInfoForRenderBlock(RenderBlock*); - static void removeWrapShapeInfoForRenderBlock(const RenderBlock*); - static bool isWrapShapeInfoEnabledForRenderBlock(const RenderBlock*); + static PassOwnPtr<ExclusionShapeInsideInfo> create(RenderBlock* block) { return adoptPtr(new ExclusionShapeInsideInfo(block)); } + static ExclusionShapeInsideInfo* exclusionShapeInsideInfoForRenderBlock(const RenderBlock*); + static ExclusionShapeInsideInfo* ensureExclusionShapeInsideInfoForRenderBlock(RenderBlock*); + static void removeExclusionShapeInsideInfoForRenderBlock(const RenderBlock*); + static bool isExclusionShapeInsideInfoEnabledForRenderBlock(const RenderBlock*); LayoutUnit shapeLogicalTop() const { @@ -76,10 +76,10 @@ public: bool computeSegmentsForLine(LayoutUnit lineTop, LayoutUnit lineBottom); bool lineOverlapsShapeBounds() const; void computeShapeSize(LayoutUnit logicalWidth, LayoutUnit logicalHeight); - void dirtyWrapShapeSize() { m_wrapShapeSizeDirty = true; } + void dirtyShapeSize() { m_shapeSizeDirty = true; } private: - WrapShapeInfo(RenderBlock*); + ExclusionShapeInsideInfo(RenderBlock*); RenderBlock* m_block; OwnPtr<ExclusionShape> m_shape; @@ -90,10 +90,10 @@ private: LayoutUnit m_logicalHeight; SegmentList m_segments; - bool m_wrapShapeSizeDirty; + bool m_shapeSizeDirty; }; -inline bool WrapShapeInfo::lineOverlapsShapeBounds() const +inline bool ExclusionShapeInsideInfo::lineOverlapsShapeBounds() const { ASSERT(m_shape); FloatRect shapeBounds = m_shape->shapeLogicalBoundingBox(); diff --git a/Source/WebCore/rendering/FlowThreadController.cpp b/Source/WebCore/rendering/FlowThreadController.cpp index cb4bdb1f2..e7cec40a2 100644 --- a/Source/WebCore/rendering/FlowThreadController.cpp +++ b/Source/WebCore/rendering/FlowThreadController.cpp @@ -153,9 +153,9 @@ void FlowThreadController::unregisterNamedFlowContentNode(Node* contentNode) ASSERT(contentNode && contentNode->isElementNode()); HashMap<Node*, RenderNamedFlowThread*>::iterator it = m_mapNamedFlowContentNodes.find(contentNode); ASSERT(it != m_mapNamedFlowContentNodes.end()); - ASSERT(it->second); - ASSERT(it->second->hasContentNode(contentNode)); - it->second->unregisterNamedFlowContentNode(contentNode); + ASSERT(it->value); + ASSERT(it->value->hasContentNode(contentNode)); + it->value->unregisterNamedFlowContentNode(contentNode); m_mapNamedFlowContentNodes.remove(contentNode); } diff --git a/Source/WebCore/rendering/InlineFlowBox.cpp b/Source/WebCore/rendering/InlineFlowBox.cpp index 9ad0fcfa1..0aa8d5687 100644 --- a/Source/WebCore/rendering/InlineFlowBox.cpp +++ b/Source/WebCore/rendering/InlineFlowBox.cpp @@ -460,7 +460,7 @@ bool InlineFlowBox::requiresIdeographicBaseline(const GlyphOverflowAndFallbackFo const Vector<const SimpleFontData*>* usedFonts = 0; if (curr->isInlineTextBox()) { GlyphOverflowAndFallbackFontsMap::const_iterator it = textBoxDataMap.find(toInlineTextBox(curr)); - usedFonts = it == textBoxDataMap.end() ? 0 : &it->second.first; + usedFonts = it == textBoxDataMap.end() ? 0 : &it->value.first; } if (usedFonts) { @@ -625,6 +625,10 @@ void InlineFlowBox::placeBoxesInBlockDirection(LayoutUnit top, LayoutUnit maxHei curr->adjustBlockDirectionPosition(adjustmentForChildrenWithSameLineHeightAndBaseline); continue; } + + LayoutUnit baselinePosition = curr->baselinePosition(baselineType); + if (curr->renderer()->isReplaced()) + baselinePosition = baselinePosition.floor(); InlineFlowBox* inlineFlowBox = curr->isInlineFlowBox() ? toInlineFlowBox(curr) : 0; bool childAffectsTopBottomPos = true; @@ -636,7 +640,7 @@ void InlineFlowBox::placeBoxesInBlockDirection(LayoutUnit top, LayoutUnit maxHei if (!strictMode && inlineFlowBox && !inlineFlowBox->hasTextChildren() && !curr->boxModelObject()->hasInlineDirectionBordersOrPadding() && !(inlineFlowBox->descendantsHaveSameLineHeightAndBaseline() && inlineFlowBox->hasTextDescendants())) childAffectsTopBottomPos = false; - LayoutUnit posAdjust = maxAscent - curr->baselinePosition(baselineType); + LayoutUnit posAdjust = maxAscent - baselinePosition; curr->setLogicalTop(curr->logicalTop() + top + posAdjust); } @@ -647,7 +651,7 @@ void InlineFlowBox::placeBoxesInBlockDirection(LayoutUnit top, LayoutUnit maxHei if (curr->isText() || curr->isInlineFlowBox()) { const FontMetrics& fontMetrics = curr->renderer()->style(isFirstLineStyle())->fontMetrics(); - newLogicalTop += curr->baselinePosition(baselineType) - fontMetrics.ascent(baselineType); + newLogicalTop += baselinePosition - fontMetrics.ascent(baselineType); if (curr->isInlineFlowBox()) { RenderBoxModelObject* boxObject = toRenderBoxModelObject(curr->renderer()); newLogicalTop -= boxObject->style(isFirstLineStyle())->isHorizontalWritingMode() ? boxObject->borderTop() + boxObject->paddingTop() : @@ -824,7 +828,7 @@ inline void InlineFlowBox::addTextBoxVisualOverflow(InlineTextBox* textBox, Glyp RenderStyle* style = textBox->renderer()->style(isFirstLineStyle()); GlyphOverflowAndFallbackFontsMap::iterator it = textBoxDataMap.find(textBox); - GlyphOverflow* glyphOverflow = it == textBoxDataMap.end() ? 0 : &it->second.second; + GlyphOverflow* glyphOverflow = it == textBoxDataMap.end() ? 0 : &it->value.second; bool isFlippedLine = style->isFlippedLinesWritingMode(); int topGlyphEdge = glyphOverflow ? (isFlippedLine ? glyphOverflow->bottom : glyphOverflow->top) : 0; diff --git a/Source/WebCore/rendering/InlineTextBox.cpp b/Source/WebCore/rendering/InlineTextBox.cpp index 95a6f0239..86b568401 100644 --- a/Source/WebCore/rendering/InlineTextBox.cpp +++ b/Source/WebCore/rendering/InlineTextBox.cpp @@ -932,7 +932,9 @@ void InlineTextBox::paintDecoration(GraphicsContext* context, const FloatPoint& // Get the text decoration colors. Color underline, overline, linethrough; - renderer()->getTextDecorationColors(deco, underline, overline, linethrough, true, isFirstLineStyle()); + renderer()->getTextDecorationColors(deco, underline, overline, linethrough, true); + if (isFirstLineStyle()) + renderer()->getTextDecorationColors(deco, underline, overline, linethrough, true, true); // Use a special function for underlines to get the positioning exactly right. bool isPrinting = textRenderer()->document()->printing(); @@ -1065,7 +1067,7 @@ void InlineTextBox::paintDocumentMarker(GraphicsContext* pt, const FloatPoint& b // display a toolTip. We don't do this for misspelling markers. if (grammar || isDictationMarker) { markerRect.move(-boxOrigin.x(), -boxOrigin.y()); - markerRect = renderer()->localToAbsoluteQuad(FloatRect(markerRect)).enclosingBoundingBox(); + markerRect = renderer()->localToAbsoluteQuad(FloatRect(markerRect), SnapOffsetForTransforms).enclosingBoundingBox(); toRenderedDocumentMarker(marker)->setRenderedRect(markerRect); } } @@ -1103,7 +1105,7 @@ void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, const FloatPoint& // Always compute and store the rect associated with this marker. The computed rect is in absolute coordinates. IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, IntPoint(x(), selectionTop()), selHeight, sPos, ePos)); - markerRect = renderer()->localToAbsoluteQuad(FloatRect(markerRect)).enclosingBoundingBox(); + markerRect = renderer()->localToAbsoluteQuad(FloatRect(markerRect), SnapOffsetForTransforms).enclosingBoundingBox(); toRenderedDocumentMarker(marker)->setRenderedRect(markerRect); // Optionally highlight the text @@ -1131,7 +1133,7 @@ void InlineTextBox::computeRectForReplacementMarker(DocumentMarker* marker, Rend // Compute and store the rect associated with this marker. IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, startPoint, h, sPos, ePos)); - markerRect = renderer()->localToAbsoluteQuad(FloatRect(markerRect)).enclosingBoundingBox(); + markerRect = renderer()->localToAbsoluteQuad(FloatRect(markerRect), SnapOffsetForTransforms).enclosingBoundingBox(); toRenderedDocumentMarker(marker)->setRenderedRect(markerRect); } diff --git a/Source/WebCore/rendering/LayoutRepainter.h b/Source/WebCore/rendering/LayoutRepainter.h index 6f63e82d3..d074b84bb 100644 --- a/Source/WebCore/rendering/LayoutRepainter.h +++ b/Source/WebCore/rendering/LayoutRepainter.h @@ -30,8 +30,8 @@ namespace WebCore { +class RenderLayerModelObject; class RenderObject; -class RenderBoxModelObject; class LayoutRepainter { public: @@ -44,7 +44,7 @@ public: private: RenderObject& m_object; - RenderBoxModelObject* m_repaintContainer; + RenderLayerModelObject* m_repaintContainer; // We store these values as LayoutRects, but the final invalidations will be pixel snapped LayoutRect m_oldBounds; LayoutRect m_oldOutlineBox; diff --git a/Source/WebCore/rendering/LayoutState.cpp b/Source/WebCore/rendering/LayoutState.cpp index b429bd976..fac96e648 100644 --- a/Source/WebCore/rendering/LayoutState.cpp +++ b/Source/WebCore/rendering/LayoutState.cpp @@ -43,7 +43,7 @@ LayoutState::LayoutState(LayoutState* prev, RenderBox* renderer, const LayoutSiz , m_renderer(renderer) #endif #if ENABLE(CSS_EXCLUSIONS) - , m_wrapShapeInfo(0) + , m_exclusionShapeInsideInfo(0) #endif { ASSERT(m_next); @@ -51,7 +51,7 @@ LayoutState::LayoutState(LayoutState* prev, RenderBox* renderer, const LayoutSiz bool fixed = renderer->isOutOfFlowPositioned() && renderer->style()->position() == FixedPosition; if (fixed) { // FIXME: This doesn't work correctly with transforms. - FloatPoint fixedOffset = renderer->view()->localToAbsolute(FloatPoint(), true); + FloatPoint fixedOffset = renderer->view()->localToAbsolute(FloatPoint(), IsFixed); m_paintOffset = LayoutSize(fixedOffset.x(), fixedOffset.y()) + offset; } else m_paintOffset = prev->m_paintOffset + offset; @@ -112,9 +112,9 @@ LayoutState::LayoutState(LayoutState* prev, RenderBox* renderer, const LayoutSiz #if ENABLE(CSS_EXCLUSIONS) if (renderer->isRenderBlock()) { - m_wrapShapeInfo = toRenderBlock(renderer)->wrapShapeInfo(); - if (!m_wrapShapeInfo) - m_wrapShapeInfo = m_next->m_wrapShapeInfo; + m_exclusionShapeInsideInfo = toRenderBlock(renderer)->exclusionShapeInsideInfo(); + if (!m_exclusionShapeInsideInfo) + m_exclusionShapeInsideInfo = m_next->m_exclusionShapeInsideInfo; } #endif @@ -144,11 +144,11 @@ LayoutState::LayoutState(RenderObject* root) , m_renderer(root) #endif #if ENABLE(CSS_EXCLUSIONS) - , m_wrapShapeInfo(0) + , m_exclusionShapeInsideInfo(0) #endif { RenderObject* container = root->container(); - FloatPoint absContentPoint = container->localToAbsolute(FloatPoint(), false, true); + FloatPoint absContentPoint = container->localToAbsolute(FloatPoint(), UseTransforms | SnapOffsetForTransforms); m_paintOffset = LayoutSize(absContentPoint.x(), absContentPoint.y()); if (container->hasOverflowClip()) { diff --git a/Source/WebCore/rendering/LayoutState.h b/Source/WebCore/rendering/LayoutState.h index a41a22677..5450df9cb 100644 --- a/Source/WebCore/rendering/LayoutState.h +++ b/Source/WebCore/rendering/LayoutState.h @@ -39,7 +39,7 @@ class RenderBox; class RenderObject; class RenderFlowThread; #if ENABLE(CSS_EXCLUSIONS) -class WrapShapeInfo; +class ExclusionShapeInsideInfo; #endif class LayoutState { @@ -57,7 +57,7 @@ public: , m_renderer(0) #endif #if ENABLE(CSS_EXCLUSIONS) - , m_wrapShapeInfo(0) + , m_exclusionShapeInsideInfo(0) #endif { } @@ -95,7 +95,7 @@ public: bool needsBlockDirectionLocationSetBeforeLayout() const { return m_lineGrid || (m_isPaginated && m_pageLogicalHeight); } #if ENABLE(CSS_EXCLUSIONS) - WrapShapeInfo* wrapShapeInfo() const { return m_wrapShapeInfo; } + ExclusionShapeInsideInfo* exclusionShapeInsideInfo() const { return m_exclusionShapeInsideInfo; } #endif private: // The normal operator new is disallowed. @@ -139,7 +139,7 @@ public: RenderObject* m_renderer; #endif #if ENABLE(CSS_EXCLUSIONS) - WrapShapeInfo* m_wrapShapeInfo; + ExclusionShapeInsideInfo* m_exclusionShapeInsideInfo; #endif }; diff --git a/Source/WebCore/rendering/RenderBR.cpp b/Source/WebCore/rendering/RenderBR.cpp index 304a27945..eabd4127a 100644 --- a/Source/WebCore/rendering/RenderBR.cpp +++ b/Source/WebCore/rendering/RenderBR.cpp @@ -28,8 +28,14 @@ namespace WebCore { +static PassRefPtr<StringImpl> newlineString() +{ + DEFINE_STATIC_LOCAL(const String, string, (ASCIILiteral("\n"))); + return string.impl(); +} + RenderBR::RenderBR(Node* node) - : RenderText(node, StringImpl::create("\n")) + : RenderText(node, newlineString()) , m_lineHeight(-1) { } diff --git a/Source/WebCore/rendering/RenderBR.h b/Source/WebCore/rendering/RenderBR.h index 49f9b5e6c..0ebaa2fa2 100644 --- a/Source/WebCore/rendering/RenderBR.h +++ b/Source/WebCore/rendering/RenderBR.h @@ -38,7 +38,7 @@ public: virtual const char* renderName() const { return "RenderBR"; } - virtual LayoutRect selectionRectForRepaint(RenderBoxModelObject* /*repaintContainer*/, bool /*clipToVisibleContent*/) { return LayoutRect(); } + virtual LayoutRect selectionRectForRepaint(RenderLayerModelObject* /*repaintContainer*/, bool /*clipToVisibleContent*/) OVERRIDE { return LayoutRect(); } virtual float width(unsigned /*from*/, unsigned /*len*/, const Font&, float /*xPos*/, HashSet<const SimpleFontData*>* = 0 /*fallbackFonts*/ , GlyphOverflow* = 0) const { return 0; } virtual float width(unsigned /*from*/, unsigned /*len*/, float /*xpos*/, bool = false /*firstLine*/, HashSet<const SimpleFontData*>* = 0 /*fallbackFonts*/, GlyphOverflow* = 0) const { return 0; } diff --git a/Source/WebCore/rendering/RenderBlock.cpp b/Source/WebCore/rendering/RenderBlock.cpp index 31e640796..07afe74b0 100755 --- a/Source/WebCore/rendering/RenderBlock.cpp +++ b/Source/WebCore/rendering/RenderBlock.cpp @@ -62,7 +62,7 @@ #include "TransformState.h" #include <wtf/StdLibExtras.h> #if ENABLE(CSS_EXCLUSIONS) -#include "WrapShapeInfo.h" +#include "ExclusionShapeInsideInfo.h" #endif using namespace std; @@ -279,7 +279,7 @@ void RenderBlock::willBeDestroyed() lineGridBox()->destroy(renderArena()); #if ENABLE(CSS_EXCLUSIONS) - WrapShapeInfo::removeWrapShapeInfoForRenderBlock(this); + ExclusionShapeInsideInfo::removeExclusionShapeInsideInfoForRenderBlock(this); #endif if (UNLIKELY(gDelayedUpdateScrollInfoSet != 0)) @@ -328,9 +328,9 @@ void RenderBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldSty RenderBox::styleDidChange(diff, oldStyle); #if ENABLE(CSS_EXCLUSIONS) - // FIXME: Bug 89993: Style changes should affect the WrapShapeInfos for other render blocks that - // share the same WrapShapeInfo - updateWrapShapeInfoAfterStyleChange(style()->wrapShapeInside(), oldStyle ? oldStyle->wrapShapeInside() : 0); + // FIXME: Bug 89993: Style changes should affect the ExclusionShapeInsideInfos for other render blocks that + // share the same ExclusionShapeInsideInfo + updateExclusionShapeInsideInfoAfterStyleChange(style()->shapeInside(), oldStyle ? oldStyle->shapeInside() : 0); #endif if (!isAnonymousBlock()) { @@ -1355,6 +1355,15 @@ void RenderBlock::finishDelayUpdateScrollInfo() void RenderBlock::updateScrollInfoAfterLayout() { if (hasOverflowClip()) { + if (style()->isFlippedBlocksWritingMode()) { + // FIXME: https://bugs.webkit.org/show_bug.cgi?id=97937 + // Workaround for now. We cannot delay the scroll info for overflow + // for items with opposite writing directions, as the contents needs + // to overflow in that direction + layer()->updateScrollInfoAfterLayout(); + return; + } + if (gDelayUpdateScrollInfo) gDelayedUpdateScrollInfoSet->add(this); else @@ -1380,24 +1389,24 @@ void RenderBlock::layout() } #if ENABLE(CSS_EXCLUSIONS) -void RenderBlock::updateWrapShapeInfoAfterStyleChange(const BasicShape* wrapShape, const BasicShape* oldWrapShape) +void RenderBlock::updateExclusionShapeInsideInfoAfterStyleChange(const BasicShape* shapeInside, const BasicShape* oldShapeInside) { // FIXME: A future optimization would do a deep comparison for equality. - if (wrapShape == oldWrapShape) + if (shapeInside == oldShapeInside) return; - if (wrapShape) { - WrapShapeInfo* wrapShapeInfo = WrapShapeInfo::ensureWrapShapeInfoForRenderBlock(this); - wrapShapeInfo->dirtyWrapShapeSize(); + if (shapeInside) { + ExclusionShapeInsideInfo* exclusionShapeInsideInfo = ExclusionShapeInsideInfo::ensureExclusionShapeInsideInfoForRenderBlock(this); + exclusionShapeInsideInfo->dirtyShapeSize(); } else - WrapShapeInfo::removeWrapShapeInfoForRenderBlock(this); + ExclusionShapeInsideInfo::removeExclusionShapeInsideInfoForRenderBlock(this); } #endif void RenderBlock::updateRegionsAndExclusionsLogicalSize() { #if ENABLE(CSS_EXCLUSIONS) - if (!inRenderFlowThread() && !wrapShapeInfo()) + if (!inRenderFlowThread() && !exclusionShapeInsideInfo()) #else if (!inRenderFlowThread()) #endif @@ -1426,10 +1435,10 @@ void RenderBlock::updateRegionsAndExclusionsLogicalSize() #if ENABLE(CSS_EXCLUSIONS) void RenderBlock::computeExclusionShapeSize() { - WrapShapeInfo* wrapShapeInfo = this->wrapShapeInfo(); - if (wrapShapeInfo) { + ExclusionShapeInsideInfo* exclusionShapeInsideInfo = this->exclusionShapeInsideInfo(); + if (exclusionShapeInsideInfo) { bool percentageLogicalHeightResolvable = percentageLogicalHeightIsResolvableFromBlock(this, false); - wrapShapeInfo->computeShapeSize(logicalWidth(), percentageLogicalHeightResolvable ? logicalHeight() : ZERO_LAYOUT_UNIT); + exclusionShapeInsideInfo->computeShapeSize(logicalWidth(), percentageLogicalHeightResolvable ? logicalHeight() : ZERO_LAYOUT_UNIT); } } #endif @@ -1534,14 +1543,6 @@ void RenderBlock::layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeigh setMarginBeforeQuirk(styleToUse->marginBefore().quirk()); setMarginAfterQuirk(styleToUse->marginAfter().quirk()); - - Node* n = node(); - if (n && n->hasTagName(formTag) && static_cast<HTMLFormElement*>(n)->isMalformed()) { - // See if this form is malformed (i.e., unclosed). If so, don't give the form - // a bottom margin. - setMaxMarginAfterValues(0, 0); - } - setPaginationStrut(0); } @@ -3249,7 +3250,7 @@ bool RenderBlock::isSelectionRoot() const return false; } -GapRects RenderBlock::selectionGapRectsForRepaint(RenderBoxModelObject* repaintContainer) +GapRects RenderBlock::selectionGapRectsForRepaint(RenderLayerModelObject* repaintContainer) { ASSERT(!needsLayout()); @@ -4428,7 +4429,7 @@ void RenderBlock::clearFloats() RendererToFloatInfoMap::iterator end = floatMap.end(); for (RendererToFloatInfoMap::iterator it = floatMap.begin(); it != end; ++it) { - FloatingObject* floatingObject = (*it).second; + FloatingObject* floatingObject = (*it).value; if (!floatingObject->isDescendant()) { changeLogicalTop = 0; changeLogicalBottom = max(changeLogicalBottom, logicalBottomForFloat(floatingObject)); @@ -5784,6 +5785,7 @@ void RenderBlock::computeInlinePreferredLogicalWidths() bool addedTextIndent = false; // Only gets added in once. LayoutUnit textIndent = minimumValueForLength(styleToUse->textIndent(), cw, view()); RenderObject* prevFloat = 0; + bool isPrevChildInlineFlow = false; while (RenderObject* child = childIterator.next()) { autoWrap = child->isReplaced() ? child->parent()->style()->autoWrap() : child->style()->autoWrap(); @@ -5872,7 +5874,7 @@ void RenderBlock::computeInlinePreferredLogicalWidths() clearPreviousFloat = false; bool canBreakReplacedElement = !child->isImage() || allowImagesToBreak; - if ((canBreakReplacedElement && (autoWrap || oldAutoWrap)) || clearPreviousFloat) { + if ((canBreakReplacedElement && (autoWrap || oldAutoWrap) && !isPrevChildInlineFlow) || clearPreviousFloat) { updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin); inlineMin = 0; } @@ -5899,7 +5901,7 @@ void RenderBlock::computeInlinePreferredLogicalWidths() // Add our width to the max. inlineMax += max<float>(0, childMax); - if (!autoWrap || !canBreakReplacedElement) { + if (!autoWrap || !canBreakReplacedElement || isPrevChildInlineFlow) { if (child->isFloating()) updatePreferredWidth(m_minPreferredLogicalWidth, childMin); else @@ -6026,6 +6028,11 @@ void RenderBlock::computeInlinePreferredLogicalWidths() addedTextIndent = true; } + if (!child->isText() && child->isRenderInline()) + isPrevChildInlineFlow = true; + else + isPrevChildInlineFlow = false; + oldAutoWrap = autoWrap; } @@ -6763,13 +6770,13 @@ void RenderBlock::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const // https://bugs.webkit.org/show_bug.cgi?id=46781 FloatRect localRect(0, -collapsedMarginBefore(), width(), height() + collapsedMarginBefore() + collapsedMarginAfter()); - quads.append(localToAbsoluteQuad(localRect, false, wasFixed)); + quads.append(localToAbsoluteQuad(localRect, 0 /* mode */, wasFixed)); continuation()->absoluteQuads(quads, wasFixed); } else - quads.append(RenderBox::localToAbsoluteQuad(FloatRect(0, 0, width(), height()), false, wasFixed)); + quads.append(RenderBox::localToAbsoluteQuad(FloatRect(0, 0, width(), height()), 0 /* mode */, wasFixed)); } -LayoutRect RenderBlock::rectWithOutlineForRepaint(RenderBoxModelObject* repaintContainer, LayoutUnit outlineWidth) const +LayoutRect RenderBlock::rectWithOutlineForRepaint(RenderLayerModelObject* repaintContainer, LayoutUnit outlineWidth) const { LayoutRect r(RenderBox::rectWithOutlineForRepaint(repaintContainer, outlineWidth)); if (isAnonymousBlockContinuation()) diff --git a/Source/WebCore/rendering/RenderBlock.h b/Source/WebCore/rendering/RenderBlock.h index e3ed210de..6e7ee635c 100644 --- a/Source/WebCore/rendering/RenderBlock.h +++ b/Source/WebCore/rendering/RenderBlock.h @@ -35,7 +35,7 @@ #include <wtf/ListHashSet.h> #if ENABLE(CSS_EXCLUSIONS) -#include "WrapShapeInfo.h" +#include "ExclusionShapeInsideInfo.h" #endif namespace WebCore { @@ -53,15 +53,17 @@ struct PaintInfo; class LineInfo; class RenderRubyRun; class TextLayout; +class WordMeasurement; template <class Iterator, class Run> class BidiResolver; template <class Run> class BidiRunList; template <class Iterator> struct MidpointState; typedef BidiResolver<InlineIterator, BidiRun> InlineBidiResolver; typedef MidpointState<InlineIterator> LineMidpointState; -typedef WTF::ListHashSet<RenderBox*> TrackedRendererListHashSet; +typedef WTF::ListHashSet<RenderBox*, 16> TrackedRendererListHashSet; typedef WTF::HashMap<const RenderBlock*, TrackedRendererListHashSet*> TrackedDescendantsMap; typedef WTF::HashMap<const RenderBox*, HashSet<RenderBlock*>*> TrackedContainerMap; +typedef Vector<WordMeasurement, 64> WordMeasurements; enum CaretType { CursorCaret, DragCaret }; @@ -216,7 +218,7 @@ public: bool containsNonZeroBidiLevel() const; - GapRects selectionGapRectsForRepaint(RenderBoxModelObject* repaintContainer); + GapRects selectionGapRectsForRepaint(RenderLayerModelObject* repaintContainer); LayoutRect logicalLeftSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, RenderObject* selObj, LayoutUnit logicalLeft, LayoutUnit logicalTop, LayoutUnit logicalHeight, const PaintInfo*); LayoutRect logicalRightSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, @@ -402,9 +404,9 @@ public: #endif #if ENABLE(CSS_EXCLUSIONS) - WrapShapeInfo* wrapShapeInfo() const + ExclusionShapeInsideInfo* exclusionShapeInsideInfo() const { - return style()->wrapShapeInside() && WrapShapeInfo::isWrapShapeInfoEnabledForRenderBlock(this) ? WrapShapeInfo::wrapShapeInfoForRenderBlock(this) : 0; + return style()->shapeInside() && ExclusionShapeInsideInfo::isExclusionShapeInsideInfoEnabledForRenderBlock(this) ? ExclusionShapeInsideInfo::exclusionShapeInsideInfoForRenderBlock(this) : 0; } #endif @@ -460,6 +462,8 @@ protected: static void startDelayUpdateScrollInfo(); static void finishDelayUpdateScrollInfo(); + void updateScrollInfoAfterLayout(); + virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle); virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle); @@ -499,7 +503,7 @@ protected: private: #if ENABLE(CSS_EXCLUSIONS) void computeExclusionShapeSize(); - void updateWrapShapeInfoAfterStyleChange(const BasicShape*, const BasicShape* oldWrapShape); + void updateExclusionShapeInsideInfoAfterStyleChange(const BasicShape*, const BasicShape* oldWrapShape); #endif virtual RenderObjectChildList* virtualChildren() { return children(); } virtual const RenderObjectChildList* virtualChildren() const { return children(); } @@ -727,7 +731,7 @@ private: reset(); } - InlineIterator nextLineBreak(InlineBidiResolver&, LineInfo&, RenderTextInfo&, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines); + InlineIterator nextLineBreak(InlineBidiResolver&, LineInfo&, RenderTextInfo&, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines, WordMeasurements&); bool lineWasHyphenated() { return m_hyphenated; } const Vector<RenderBox*>& positionedObjects() { return m_positionedObjects; } @@ -755,7 +759,7 @@ private: void setMarginsForRubyRun(BidiRun*, RenderRubyRun*, RenderObject*, const LineInfo&); - void computeInlineDirectionPositionsForLine(RootInlineBox*, const LineInfo&, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&); + void computeInlineDirectionPositionsForLine(RootInlineBox*, const LineInfo&, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&, WordMeasurements&); void computeBlockDirectionPositionsForLine(RootInlineBox*, BidiRun*, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&); void deleteEllipsisLineBoxes(); void checkLinesForTextOverflow(); @@ -809,14 +813,14 @@ private: // children. virtual RenderBlock* firstLineBlock() const; - virtual LayoutRect rectWithOutlineForRepaint(RenderBoxModelObject* repaintContainer, LayoutUnit outlineWidth) const; + virtual LayoutRect rectWithOutlineForRepaint(RenderLayerModelObject* repaintContainer, LayoutUnit outlineWidth) const OVERRIDE; virtual RenderStyle* outlineStyleForRepaint() const; virtual RenderObject* hoverAncestor() const; virtual void updateDragState(bool dragOn); virtual void childBecameNonInline(RenderObject* child); - virtual LayoutRect selectionRectForRepaint(RenderBoxModelObject* repaintContainer, bool /*clipToVisibleContent*/) + virtual LayoutRect selectionRectForRepaint(RenderLayerModelObject* repaintContainer, bool /*clipToVisibleContent*/) OVERRIDE { return selectionGapRectsForRepaint(repaintContainer); } @@ -858,8 +862,6 @@ private: bool expandsToEncloseOverhangingFloats() const; - void updateScrollInfoAfterLayout(); - void splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock, RenderBlock* middleBlock, RenderObject* beforeChild, RenderBoxModelObject* oldCont); void splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox, @@ -963,7 +965,7 @@ private: // End helper functions and structs used by layoutBlockChildren. // Helper function for layoutInlineChildren() - RootInlineBox* createLineBoxesFromBidiRuns(BidiRunList<BidiRun>&, const InlineIterator& end, LineInfo&, VerticalPositionCache&, BidiRun* trailingSpaceRun); + RootInlineBox* createLineBoxesFromBidiRuns(BidiRunList<BidiRun>&, const InlineIterator& end, LineInfo&, VerticalPositionCache&, BidiRun* trailingSpaceRun, WordMeasurements&); void layoutRunsAndFloats(LineLayoutState&, bool hasInlineChild); void layoutRunsAndFloatsInRange(LineLayoutState&, InlineBidiResolver&, const InlineIterator& cleanLineStart, const BidiStatus& cleanLineBidiStatus, unsigned consecutiveHyphenatedLines); void linkToEndLineIfNeeded(LineLayoutState&); diff --git a/Source/WebCore/rendering/RenderBlockLineLayout.cpp b/Source/WebCore/rendering/RenderBlockLineLayout.cpp index 77994804b..d61361b1f 100755 --- a/Source/WebCore/rendering/RenderBlockLineLayout.cpp +++ b/Source/WebCore/rendering/RenderBlockLineLayout.cpp @@ -46,7 +46,7 @@ #include <wtf/unicode/CharacterNames.h> #if ENABLE(CSS_EXCLUSIONS) -#include "WrapShapeInfo.h" +#include "ExclusionShapeInsideInfo.h" #endif #if ENABLE(SVG) @@ -64,9 +64,9 @@ namespace WebCore { const unsigned cMaxLineDepth = 200; #if ENABLE(CSS_EXCLUSIONS) -static inline WrapShapeInfo* layoutWrapShapeInfo(const RenderBlock* block) +static inline ExclusionShapeInsideInfo* layoutExclusionShapeInsideInfo(const RenderBlock* block) { - return block->view()->layoutState()->wrapShapeInfo(); + return block->view()->layoutState()->exclusionShapeInsideInfo(); } #endif @@ -87,16 +87,16 @@ public: { ASSERT(block); #if ENABLE(CSS_EXCLUSIONS) - WrapShapeInfo* wrapShapeInfo = layoutWrapShapeInfo(m_block); + ExclusionShapeInsideInfo* exclusionShapeInsideInfo = layoutExclusionShapeInsideInfo(m_block); // FIXME: Bug 91878: Add support for multiple segments, currently we only support one - if (wrapShapeInfo && wrapShapeInfo->hasSegments()) - m_segment = &wrapShapeInfo->segments()[0]; + if (exclusionShapeInsideInfo && exclusionShapeInsideInfo->hasSegments()) + m_segment = &exclusionShapeInsideInfo->segments()[0]; #endif updateAvailableWidth(); } #if ENABLE(SUBPIXEL_LAYOUT) - bool fitsOnLine() const { return currentWidth() <= m_availableWidth + LayoutUnit::epsilon(); } - bool fitsOnLine(float extra) const { return currentWidth() + extra <= m_availableWidth + LayoutUnit::epsilon(); } + bool fitsOnLine() const { return currentWidth() <= m_availableWidth; } + bool fitsOnLine(float extra) const { return currentWidth() + extra <= m_availableWidth; } #else bool fitsOnLine() const { return currentWidth() <= m_availableWidth; } bool fitsOnLine(float extra) const { return currentWidth() + extra <= m_availableWidth; } @@ -290,6 +290,14 @@ static inline LayoutUnit borderPaddingMarginEnd(RenderInline* child) return child->marginEnd() + child->paddingEnd() + child->borderEnd(); } +static bool shouldAddBorderPaddingMargin(RenderObject* child, bool &checkSide) +{ + if (!child || (child->isText() && !toRenderText(child)->textLength())) + return true; + checkSide = false; + return checkSide; +} + static LayoutUnit inlineLogicalWidth(RenderObject* child, bool start = true, bool end = true) { unsigned lineDepth = 1; @@ -297,10 +305,12 @@ static LayoutUnit inlineLogicalWidth(RenderObject* child, bool start = true, boo RenderObject* parent = child->parent(); while (parent->isRenderInline() && lineDepth++ < cMaxLineDepth) { RenderInline* parentAsRenderInline = toRenderInline(parent); - if (start && !child->previousSibling()) + if (start && shouldAddBorderPaddingMargin(child->previousSibling(), start)) extraWidth += borderPaddingMarginStart(parentAsRenderInline); - if (end && !child->nextSibling()) + if (end && shouldAddBorderPaddingMargin(child->nextSibling(), end)) extraWidth += borderPaddingMarginEnd(parentAsRenderInline); + if (!start && !end) + return extraWidth; child = parent; parent = child->parent(); } @@ -682,22 +692,43 @@ static inline float measureHyphenWidth(RenderText* renderer, const Font& font) return font.width(RenderBlock::constructTextRun(renderer, font, style->hyphenString().string(), style)); } +class WordMeasurement { +public: + WordMeasurement() + : renderer(0) + , width(0) + , startOffset(0) + , endOffset(0) + { + } + + RenderText* renderer; + float width; + int startOffset; + int endOffset; + HashSet<const SimpleFontData*> fallbackFonts; +}; + static inline void setLogicalWidthForTextRun(RootInlineBox* lineBox, BidiRun* run, RenderText* renderer, float xPos, const LineInfo& lineInfo, - GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& verticalPositionCache) + GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& verticalPositionCache, WordMeasurements& wordMeasurements) { +#if !(PLATFORM(CHROMIUM) && OS(DARWIN)) + UNUSED_PARAM(wordMeasurements); +#endif HashSet<const SimpleFontData*> fallbackFonts; GlyphOverflow glyphOverflow; + const Font& font = renderer->style(lineInfo.isFirstLine())->font(); // Always compute glyph overflow if the block's line-box-contain value is "glyphs". if (lineBox->fitsToGlyphs()) { // If we don't stick out of the root line's font box, then don't bother computing our glyph overflow. This optimization // will keep us from computing glyph bounds in nearly all cases. bool includeRootLine = lineBox->includesRootLineBoxFontOrLeading(); int baselineShift = lineBox->verticalPositionForBox(run->m_box, verticalPositionCache); - int rootDescent = includeRootLine ? lineBox->renderer()->style(lineInfo.isFirstLine())->font().fontMetrics().descent() : 0; - int rootAscent = includeRootLine ? lineBox->renderer()->style(lineInfo.isFirstLine())->font().fontMetrics().ascent() : 0; - int boxAscent = renderer->style(lineInfo.isFirstLine())->font().fontMetrics().ascent() - baselineShift; - int boxDescent = renderer->style(lineInfo.isFirstLine())->font().fontMetrics().descent() + baselineShift; + int rootDescent = includeRootLine ? font.fontMetrics().descent() : 0; + int rootAscent = includeRootLine ? font.fontMetrics().ascent() : 0; + int boxAscent = font.fontMetrics().ascent() - baselineShift; + int boxDescent = font.fontMetrics().descent() + baselineShift; if (boxAscent > rootDescent || boxDescent > rootAscent) glyphOverflow.computeBounds = true; } @@ -707,18 +738,59 @@ static inline void setLogicalWidthForTextRun(RootInlineBox* lineBox, BidiRun* ru const Font& font = renderer->style(lineInfo.isFirstLine())->font(); hyphenWidth = measureHyphenWidth(renderer, font); } - run->m_box->setLogicalWidth(renderer->width(run->m_start, run->m_stop - run->m_start, xPos, lineInfo.isFirstLine(), &fallbackFonts, &glyphOverflow) + hyphenWidth); + float measuredWidth = 0; + +#if !(PLATFORM(CHROMIUM) && OS(DARWIN)) + bool kerningIsEnabled = font.typesettingFeatures() & Kerning; + + // Since we don't cache glyph overflows, we need to re-measure the run if + // the style is linebox-contain: glyph. + + if (!lineBox->fitsToGlyphs() && renderer->canUseSimpleFontCodePath()) { + int lastEndOffset = run->m_start; + for (size_t i = 0, size = wordMeasurements.size(); i < size && lastEndOffset < run->m_stop; ++i) { + const WordMeasurement& wordMeasurement = wordMeasurements[i]; + if (wordMeasurement.width <=0 || wordMeasurement.startOffset == wordMeasurement.endOffset) + continue; + if (wordMeasurement.renderer != renderer || wordMeasurement.startOffset != lastEndOffset || wordMeasurement.endOffset > run->m_stop) + continue; + + lastEndOffset = wordMeasurement.endOffset; + if (kerningIsEnabled && lastEndOffset == run->m_stop) { + measuredWidth += renderer->width(wordMeasurement.startOffset, lastEndOffset - wordMeasurement.startOffset, xPos, lineInfo.isFirstLine()); + if (i > 0) + measuredWidth += renderer->style()->wordSpacing(); + } else + measuredWidth += wordMeasurement.width; + if (!wordMeasurement.fallbackFonts.isEmpty()) { + HashSet<const SimpleFontData*>::const_iterator end = wordMeasurement.fallbackFonts.end(); + for (HashSet<const SimpleFontData*>::const_iterator it = wordMeasurement.fallbackFonts.begin(); it != end; ++it) + fallbackFonts.add(*it); + } + } + if (measuredWidth && lastEndOffset != run->m_stop) { + // If we don't have enough cached data, we'll measure the run again. + measuredWidth = 0; + fallbackFonts.clear(); + } + } +#endif + + if (!measuredWidth) + measuredWidth = renderer->width(run->m_start, run->m_stop - run->m_start, xPos, lineInfo.isFirstLine(), &fallbackFonts, &glyphOverflow); + + run->m_box->setLogicalWidth(measuredWidth + hyphenWidth); if (!fallbackFonts.isEmpty()) { ASSERT(run->m_box->isText()); GlyphOverflowAndFallbackFontsMap::iterator it = textBoxDataMap.add(toInlineTextBox(run->m_box), make_pair(Vector<const SimpleFontData*>(), GlyphOverflow())).iterator; - ASSERT(it->second.first.isEmpty()); - copyToVector(fallbackFonts, it->second.first); + ASSERT(it->value.first.isEmpty()); + copyToVector(fallbackFonts, it->value.first); run->m_box->parent()->clearDescendantsHaveSameLineHeightAndBaseline(); } if ((glyphOverflow.top || glyphOverflow.bottom || glyphOverflow.left || glyphOverflow.right)) { ASSERT(run->m_box->isText()); GlyphOverflowAndFallbackFontsMap::iterator it = textBoxDataMap.add(toInlineTextBox(run->m_box), make_pair(Vector<const SimpleFontData*>(), GlyphOverflow())).iterator; - it->second.second = glyphOverflow; + it->value.second = glyphOverflow; run->m_box->clearKnownToHaveNoOverflow(); } } @@ -797,7 +869,7 @@ void RenderBlock::updateLogicalWidthForAlignment(const ETextAlign& textAlign, Bi } void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox, const LineInfo& lineInfo, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd, - GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& verticalPositionCache) + GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& verticalPositionCache, WordMeasurements& wordMeasurements) { ETextAlign textAlign = textAlignmentForLine(!reachedEnd && !lineBox->endsWithBreak()); @@ -808,10 +880,10 @@ void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox, float logicalLeft = pixelSnappedLogicalLeftOffsetForLine(logicalHeight(), firstLine, lineLogicalHeight); float logicalRight = pixelSnappedLogicalRightOffsetForLine(logicalHeight(), firstLine, lineLogicalHeight); #if ENABLE(CSS_EXCLUSIONS) - WrapShapeInfo* wrapShapeInfo = layoutWrapShapeInfo(this); - if (wrapShapeInfo && wrapShapeInfo->hasSegments()) { - logicalLeft = max<float>(roundToInt(wrapShapeInfo->segments()[0].logicalLeft), logicalLeft); - logicalRight = min<float>(floorToInt(wrapShapeInfo->segments()[0].logicalRight), logicalRight); + ExclusionShapeInsideInfo* exclusionShapeInsideInfo = layoutExclusionShapeInsideInfo(this); + if (exclusionShapeInsideInfo && exclusionShapeInsideInfo->hasSegments()) { + logicalLeft = max<float>(roundToInt(exclusionShapeInsideInfo->segments()[0].logicalLeft), logicalLeft); + logicalRight = min<float>(floorToInt(exclusionShapeInsideInfo->segments()[0].logicalRight), logicalRight); } #endif float availableLogicalWidth = logicalRight - logicalLeft; @@ -844,7 +916,7 @@ void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox, needsWordSpacing = !isSpaceOrNewline(rt->characters()[r->m_stop - 1]) && r->m_stop == length; } - setLogicalWidthForTextRun(lineBox, r, rt, totalLogicalWidth, lineInfo, textBoxDataMap, verticalPositionCache); + setLogicalWidthForTextRun(lineBox, r, rt, totalLogicalWidth, lineInfo, textBoxDataMap, verticalPositionCache, wordMeasurements); } else { isAfterExpansion = false; if (!r->m_object->isRenderInline()) { @@ -1071,7 +1143,7 @@ static inline void constructBidiRuns(InlineBidiResolver& topResolver, BidiRunLis } // This function constructs line boxes for all of the text runs in the resolver and computes their position. -RootInlineBox* RenderBlock::createLineBoxesFromBidiRuns(BidiRunList<BidiRun>& bidiRuns, const InlineIterator& end, LineInfo& lineInfo, VerticalPositionCache& verticalPositionCache, BidiRun* trailingSpaceRun) +RootInlineBox* RenderBlock::createLineBoxesFromBidiRuns(BidiRunList<BidiRun>& bidiRuns, const InlineIterator& end, LineInfo& lineInfo, VerticalPositionCache& verticalPositionCache, BidiRun* trailingSpaceRun, WordMeasurements& wordMeasurements) { if (!bidiRuns.runCount()) return 0; @@ -1095,7 +1167,7 @@ RootInlineBox* RenderBlock::createLineBoxesFromBidiRuns(BidiRunList<BidiRun>& bi // Now we position all of our text runs horizontally. if (!isSVGRootInlineBox) - computeInlineDirectionPositionsForLine(lineBox, lineInfo, bidiRuns.firstRun(), trailingSpaceRun, end.atEnd(), textBoxDataMap, verticalPositionCache); + computeInlineDirectionPositionsForLine(lineBox, lineInfo, bidiRuns.firstRun(), trailingSpaceRun, end.atEnd(), textBoxDataMap, verticalPositionCache, wordMeasurements); // Now position our text runs vertically. computeBlockDirectionPositionsForLine(lineBox, bidiRuns.firstRun(), textBoxDataMap, verticalPositionCache); @@ -1301,16 +1373,16 @@ void RenderBlock::layoutRunsAndFloatsInRange(LineLayoutState& layoutState, Inlin #if ENABLE(CSS_EXCLUSIONS) LayoutUnit absoluteLogicalTop; - WrapShapeInfo* wrapShapeInfo = layoutWrapShapeInfo(this); - if (wrapShapeInfo) { - if (wrapShapeInfo != this->wrapShapeInfo()) { + ExclusionShapeInsideInfo* exclusionShapeInsideInfo = layoutExclusionShapeInsideInfo(this); + if (exclusionShapeInsideInfo) { + if (exclusionShapeInsideInfo != this->exclusionShapeInsideInfo()) { // FIXME: If layout state is disabled, the offset will be incorrect. LayoutSize layoutOffset = view()->layoutState()->layoutOffset(); absoluteLogicalTop = logicalTop() + (isHorizontalWritingMode() ? layoutOffset.height() : layoutOffset.width()); } // Begin layout at the logical top of our shape inside. - if (logicalHeight() + absoluteLogicalTop < wrapShapeInfo->shapeLogicalTop()) - setLogicalHeight(wrapShapeInfo->shapeLogicalTop() - absoluteLogicalTop); + if (logicalHeight() + absoluteLogicalTop < exclusionShapeInsideInfo->shapeLogicalTop()) + setLogicalHeight(exclusionShapeInsideInfo->shapeLogicalTop() - absoluteLogicalTop); } #endif @@ -1335,13 +1407,14 @@ void RenderBlock::layoutRunsAndFloatsInRange(LineLayoutState& layoutState, Inlin #if ENABLE(CSS_EXCLUSIONS) // FIXME: Bug 95361: It is possible for a line to grow beyond lineHeight, in which // case these segments may be incorrect. - if (wrapShapeInfo) { + if (exclusionShapeInsideInfo) { LayoutUnit lineTop = logicalHeight() + absoluteLogicalTop; LayoutUnit lineBottom = lineTop + lineHeight(layoutState.lineInfo().isFirstLine(), isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes); - wrapShapeInfo->computeSegmentsForLine(lineTop, lineBottom); + exclusionShapeInsideInfo->computeSegmentsForLine(lineTop, lineBottom); } #endif - end = lineBreaker.nextLineBreak(resolver, layoutState.lineInfo(), renderTextInfo, lastFloatFromPreviousLine, consecutiveHyphenatedLines); + WordMeasurements wordMeasurements; + end = lineBreaker.nextLineBreak(resolver, layoutState.lineInfo(), renderTextInfo, lastFloatFromPreviousLine, consecutiveHyphenatedLines, wordMeasurements); if (resolver.position().atEnd()) { // FIXME: We shouldn't be creating any runs in nextLineBreak to begin with! // Once BidiRunList is separated from BidiResolver this will not be needed. @@ -1383,7 +1456,7 @@ void RenderBlock::layoutRunsAndFloatsInRange(LineLayoutState& layoutState, Inlin // inline flow boxes. LayoutUnit oldLogicalHeight = logicalHeight(); - RootInlineBox* lineBox = createLineBoxesFromBidiRuns(bidiRuns, end, layoutState.lineInfo(), verticalPositionCache, trailingSpaceRun); + RootInlineBox* lineBox = createLineBoxesFromBidiRuns(bidiRuns, end, layoutState.lineInfo(), verticalPositionCache, trailingSpaceRun, wordMeasurements); bidiRuns.deleteRuns(); resolver.markCurrentRunEmpty(); // FIXME: This can probably be replaced by an ASSERT (or just removed). @@ -2041,13 +2114,14 @@ static bool shouldSkipWhitespaceAfterStartObject(RenderBlock* block, RenderObjec return false; } -static inline float textWidth(RenderText* text, unsigned from, unsigned len, const Font& font, float xPos, bool isFixedPitch, bool collapseWhiteSpace, TextLayout* layout = 0) +static ALWAYS_INLINE float textWidth(RenderText* text, unsigned from, unsigned len, const Font& font, float xPos, bool isFixedPitch, bool collapseWhiteSpace, HashSet<const SimpleFontData*>* fallbackFonts = 0, TextLayout* layout = 0) { + GlyphOverflow glyphOverflow; if (isFixedPitch || (!from && len == text->textLength()) || text->style()->hasTextCombine()) - return text->width(from, len, font, xPos); + return text->width(from, len, font, xPos, fallbackFonts, &glyphOverflow); if (layout) - return Font::width(*layout, from, len); + return Font::width(*layout, from, len, fallbackFonts); TextRun run = RenderBlock::constructTextRun(text, font, text->characters() + from, len, text->style()); run.setCharactersLength(text->textLength() - from); @@ -2056,7 +2130,7 @@ static inline float textWidth(RenderText* text, unsigned from, unsigned len, con run.setCharacterScanForCodePath(!text->canUseSimpleFontCodePath()); run.setTabSize(!collapseWhiteSpace, text->style()->tabSize()); run.setXPos(xPos); - return font.width(run); + return font.width(run, fallbackFonts, &glyphOverflow); } static void tryHyphenating(RenderText* text, const Font& font, const AtomicString& localeIdentifier, unsigned consecutiveHyphenatedLines, int consecutiveHyphenatedLinesLimit, int minimumPrefixLength, int minimumSuffixLength, int lastSpace, int pos, float xPos, int availableWidth, bool isFixedPitch, bool collapseWhiteSpace, int lastSpaceWordSpacing, InlineIterator& lineBreak, int nextBreakable, bool& hyphenated) @@ -2210,7 +2284,7 @@ void RenderBlock::LineBreaker::reset() m_clear = CNONE; } -InlineIterator RenderBlock::LineBreaker::nextLineBreak(InlineBidiResolver& resolver, LineInfo& lineInfo, RenderTextInfo& renderTextInfo, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines) +InlineIterator RenderBlock::LineBreaker::nextLineBreak(InlineBidiResolver& resolver, LineInfo& lineInfo, RenderTextInfo& renderTextInfo, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines, WordMeasurements& wordMeasurements) { reset(); @@ -2428,6 +2502,7 @@ InlineIterator RenderBlock::LineBreaker::nextLineBreak(InlineBidiResolver& resol int lastSpace = current.m_pos; float wordSpacing = currentStyle->wordSpacing(); float lastSpaceWordSpacing = 0; + float wordSpacingForWordMeasurement = 0; float wrapW = width.uncommittedWidth() + inlineLogicalWidth(current.m_obj, !appliedStartWidth, true); float charWidth = 0; @@ -2450,7 +2525,7 @@ InlineIterator RenderBlock::LineBreaker::nextLineBreak(InlineBidiResolver& resol renderTextInfo.m_text = t; renderTextInfo.m_font = &f; renderTextInfo.m_layout = f.createLayout(t, width.currentWidth(), collapseWhiteSpace); - renderTextInfo.m_lineBreakIterator.reset(t->characters(), t->textLength(), style->locale()); + renderTextInfo.m_lineBreakIterator.reset(t->text(), style->locale()); } else if (renderTextInfo.m_layout && renderTextInfo.m_font != &f) { renderTextInfo.m_font = &f; renderTextInfo.m_layout = f.createLayout(t, width.currentWidth(), collapseWhiteSpace); @@ -2483,7 +2558,7 @@ InlineIterator RenderBlock::LineBreaker::nextLineBreak(InlineBidiResolver& resol if ((breakAll || breakWords) && !midWordBreak) { wrapW += charWidth; bool midWordBreakIsBeforeSurrogatePair = U16_IS_LEAD(c) && current.m_pos + 1 < t->textLength() && U16_IS_TRAIL(t->characters()[current.m_pos + 1]); - charWidth = textWidth(t, current.m_pos, midWordBreakIsBeforeSurrogatePair ? 2 : 1, f, width.committedWidth() + wrapW, isFixedPitch, collapseWhiteSpace, textLayout); + charWidth = textWidth(t, current.m_pos, midWordBreakIsBeforeSurrogatePair ? 2 : 1, f, width.committedWidth() + wrapW, isFixedPitch, collapseWhiteSpace, 0, textLayout); midWordBreak = width.committedWidth() + wrapW + charWidth > width.availableWidth(); } @@ -2498,6 +2573,7 @@ InlineIterator RenderBlock::LineBreaker::nextLineBreak(InlineBidiResolver& resol // new point. ignoringSpaces = false; lastSpaceWordSpacing = 0; + wordSpacingForWordMeasurement = 0; lastSpace = current.m_pos; // e.g., "Foo goo", don't add in any of the ignored spaces. addMidpoint(lineMidpointState, InlineIterator(0, current.m_obj, current.m_pos)); stoppedIgnoringSpaces = true; @@ -2507,18 +2583,28 @@ InlineIterator RenderBlock::LineBreaker::nextLineBreak(InlineBidiResolver& resol } } + wordMeasurements.grow(wordMeasurements.size() + 1); + WordMeasurement& wordMeasurement = wordMeasurements.last(); + + wordMeasurement.renderer = t; + wordMeasurement.endOffset = current.m_pos; + wordMeasurement.startOffset = lastSpace; + float additionalTmpW; if (wordTrailingSpaceWidth && currentCharacterIsSpace) - additionalTmpW = textWidth(t, lastSpace, current.m_pos + 1 - lastSpace, f, width.currentWidth(), isFixedPitch, collapseWhiteSpace, textLayout) - wordTrailingSpaceWidth + lastSpaceWordSpacing; + additionalTmpW = textWidth(t, lastSpace, current.m_pos + 1 - lastSpace, f, width.currentWidth(), isFixedPitch, collapseWhiteSpace, &wordMeasurement.fallbackFonts, textLayout) - wordTrailingSpaceWidth; else - additionalTmpW = textWidth(t, lastSpace, current.m_pos - lastSpace, f, width.currentWidth(), isFixedPitch, collapseWhiteSpace, textLayout) + lastSpaceWordSpacing; + additionalTmpW = textWidth(t, lastSpace, current.m_pos - lastSpace, f, width.currentWidth(), isFixedPitch, collapseWhiteSpace, &wordMeasurement.fallbackFonts, textLayout); + + wordMeasurement.width = additionalTmpW + wordSpacingForWordMeasurement; + additionalTmpW += lastSpaceWordSpacing; width.addUncommittedWidth(additionalTmpW); if (!appliedStartWidth) { width.addUncommittedWidth(inlineLogicalWidth(current.m_obj, true, false)); appliedStartWidth = true; } - applyWordSpacing = wordSpacing && currentCharacterIsSpace; + applyWordSpacing = wordSpacing && currentCharacterIsSpace; if (!width.committedWidth() && autoWrap && !width.fitsOnLine()) width.fitBelowFloats(); @@ -2528,7 +2614,7 @@ InlineIterator RenderBlock::LineBreaker::nextLineBreak(InlineBidiResolver& resol // as candidate width for this line. bool lineWasTooWide = false; if (width.fitsOnLine() && currentCharacterIsWS && currentStyle->breakOnlyAfterWhiteSpace() && !midWordBreak) { - float charWidth = textWidth(t, current.m_pos, 1, f, width.currentWidth(), isFixedPitch, collapseWhiteSpace, textLayout) + (applyWordSpacing ? wordSpacing : 0); + float charWidth = textWidth(t, current.m_pos, 1, f, width.currentWidth(), isFixedPitch, collapseWhiteSpace, &wordMeasurement.fallbackFonts, textLayout) + (applyWordSpacing ? wordSpacing : 0); // Check if line is too big even without the extra space // at the end of the line. If it is not, do nothing. // If the line needs the extra whitespace to be too long, @@ -2554,9 +2640,16 @@ InlineIterator RenderBlock::LineBreaker::nextLineBreak(InlineBidiResolver& resol } lBreak.increment(); lineInfo.setPreviousLineBrokeCleanly(true); + wordMeasurement.endOffset = lBreak.m_pos; } if (lBreak.m_obj && lBreak.m_pos && lBreak.m_obj->isText() && toRenderText(lBreak.m_obj)->textLength() && toRenderText(lBreak.m_obj)->characters()[lBreak.m_pos - 1] == softHyphen && style->hyphens() != HyphensNone) m_hyphenated = true; + if (lBreak.m_pos && lBreak.m_pos != (unsigned)wordMeasurement.endOffset && !wordMeasurement.width) { + if (charWidth) { + wordMeasurement.endOffset = lBreak.m_pos; + wordMeasurement.width = charWidth; + } + } goto end; // Didn't fit. Jump to the end. } else { if (!betweenWords || (midWordBreak && !autoWrap)) @@ -2599,6 +2692,7 @@ InlineIterator RenderBlock::LineBreaker::nextLineBreak(InlineBidiResolver& resol if (betweenWords) { lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0; + wordSpacingForWordMeasurement = (applyWordSpacing && wordMeasurement.width) ? wordSpacing : 0; lastSpace = current.m_pos; } @@ -2621,6 +2715,7 @@ InlineIterator RenderBlock::LineBreaker::nextLineBreak(InlineBidiResolver& resol // new point. ignoringSpaces = false; lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0; + wordSpacingForWordMeasurement = (applyWordSpacing && wordMeasurements.last().width) ? wordSpacing : 0; lastSpace = current.m_pos; // e.g., "Foo goo", don't add in any of the ignored spaces. addMidpoint(lineMidpointState, InlineIterator(0, current.m_obj, current.m_pos)); } @@ -2653,8 +2748,16 @@ InlineIterator RenderBlock::LineBreaker::nextLineBreak(InlineBidiResolver& resol atStart = false; } + wordMeasurements.grow(wordMeasurements.size() + 1); + WordMeasurement& wordMeasurement = wordMeasurements.last(); + wordMeasurement.renderer = t; + // IMPORTANT: current.m_pos is > length here! - float additionalTmpW = ignoringSpaces ? 0 : textWidth(t, lastSpace, current.m_pos - lastSpace, f, width.currentWidth(), isFixedPitch, collapseWhiteSpace, textLayout) + lastSpaceWordSpacing; + float additionalTmpW = ignoringSpaces ? 0 : textWidth(t, lastSpace, current.m_pos - lastSpace, f, width.currentWidth(), isFixedPitch, collapseWhiteSpace, &wordMeasurement.fallbackFonts, textLayout); + wordMeasurement.startOffset = lastSpace; + wordMeasurement.endOffset = current.m_pos; + wordMeasurement.width = ignoringSpaces ? 0 : additionalTmpW + wordSpacingForWordMeasurement; + additionalTmpW += lastSpaceWordSpacing; width.addUncommittedWidth(additionalTmpW + inlineLogicalWidth(current.m_obj, !appliedStartWidth, includeEndWidth)); includeEndWidth = false; diff --git a/Source/WebCore/rendering/RenderBox.cpp b/Source/WebCore/rendering/RenderBox.cpp index a1a3c9922..750ec704a 100644 --- a/Source/WebCore/rendering/RenderBox.cpp +++ b/Source/WebCore/rendering/RenderBox.cpp @@ -201,7 +201,7 @@ void RenderBox::styleWillChange(StyleDifference diff, const RenderStyle* newStyl void RenderBox::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) { - // Horizontal writing mode definition is updated in RenderBoxModelObject::updateBoxModelInfoFromStyle, + // Horizontal writing mode definition is updated in RenderBoxModelObject::updateFromStyle, // (as part of the RenderBoxModelObject::styleDidChange call below). So, we can safely cache the horizontal // writing mode value before style change here. bool oldHorizontalWritingMode = isHorizontalWritingMode(); @@ -269,9 +269,9 @@ void RenderBox::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle } } -void RenderBox::updateBoxModelInfoFromStyle() +void RenderBox::updateFromStyle() { - RenderBoxModelObject::updateBoxModelInfoFromStyle(); + RenderBoxModelObject::updateFromStyle(); RenderStyle* styleToUse = style(); bool isRootObject = isRoot(); @@ -403,7 +403,7 @@ void RenderBox::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumul void RenderBox::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const { - quads.append(localToAbsoluteQuad(FloatRect(0, 0, width(), height()), false, wasFixed)); + quads.append(localToAbsoluteQuad(FloatRect(0, 0, width(), height()), 0 /* mode */, wasFixed)); } void RenderBox::updateLayerTransform() @@ -436,7 +436,7 @@ IntRect RenderBox::absoluteContentBox() const { // This is wrong with transforms and flipped writing modes. IntRect rect = pixelSnappedIntRect(contentBoxRect()); - FloatPoint absPos = localToAbsolute(FloatPoint()); + FloatPoint absPos = localToAbsolute(); rect.move(absPos.x(), absPos.y()); return rect; } @@ -447,7 +447,7 @@ FloatQuad RenderBox::absoluteContentQuad() const return localToAbsoluteQuad(FloatRect(rect)); } -LayoutRect RenderBox::outlineBoundsForRepaint(RenderBoxModelObject* repaintContainer, LayoutPoint* cachedOffsetToRepaintContainer) const +LayoutRect RenderBox::outlineBoundsForRepaint(RenderLayerModelObject* repaintContainer, LayoutPoint* cachedOffsetToRepaintContainer) const { LayoutRect box = borderBoundingBox(); adjustRectForOutlineAndShadow(box); @@ -708,14 +708,14 @@ void RenderBox::clearOverrideSize() LayoutUnit RenderBox::overrideLogicalContentWidth() const { - // FIXME: This should probably be returning contentLogicalWidth instead of contentWidth. - return hasOverrideWidth() ? gOverrideWidthMap->get(this) : contentWidth(); + ASSERT(hasOverrideWidth()); + return gOverrideWidthMap->get(this); } LayoutUnit RenderBox::overrideLogicalContentHeight() const { - // FIXME: This should probably be returning contentLogicalHeight instead of contentHeight. - return hasOverrideHeight() ? gOverrideHeightMap->get(this) : contentHeight(); + ASSERT(hasOverrideHeight()); + return gOverrideHeightMap->get(this); } LayoutUnit RenderBox::adjustBorderBoxLogicalWidthForBoxSizing(LayoutUnit width) const @@ -1258,7 +1258,7 @@ LayoutUnit RenderBox::perpendicularContainingBlockLogicalHeight() const return cb->adjustContentBoxLogicalHeightForBoxSizing(logicalHeightLength.value()); } -void RenderBox::mapLocalToContainer(RenderBoxModelObject* repaintContainer, TransformState& transformState, MapLocalToContainerFlags mode, bool* wasFixed) const +void RenderBox::mapLocalToContainer(RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags mode, bool* wasFixed) const { if (repaintContainer == this) return; @@ -1323,7 +1323,7 @@ void RenderBox::mapLocalToContainer(RenderBoxModelObject* repaintContainer, Tran o->mapLocalToContainer(repaintContainer, transformState, mode, wasFixed); } -const RenderObject* RenderBox::pushMappingToContainer(const RenderBoxModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const +const RenderObject* RenderBox::pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const { ASSERT(ancestorToStopAt != this); @@ -1363,18 +1363,18 @@ const RenderObject* RenderBox::pushMappingToContainer(const RenderBoxModelObject return ancestorSkipped ? ancestorToStopAt : container; } -void RenderBox::mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState& transformState) const +void RenderBox::mapAbsoluteToLocalPoint(MapCoordinatesFlags mode, TransformState& transformState) const { bool isFixedPos = style()->position() == FixedPosition; bool hasTransform = hasLayer() && layer()->transform(); - if (hasTransform) { + if (hasTransform && !isFixedPos) { // If this box has a transform, it acts as a fixed position container for fixed descendants, // and may itself also be fixed position. So propagate 'fixed' up only if this box is fixed position. - fixed &= isFixedPos; - } else - fixed |= isFixedPos; + mode &= ~IsFixed; + } else if (isFixedPos) + mode |= IsFixed; - RenderBoxModelObject::mapAbsoluteToLocalPoint(fixed, useTransforms, transformState); + RenderBoxModelObject::mapAbsoluteToLocalPoint(mode, transformState); } LayoutSize RenderBox::offsetFromContainer(RenderObject* o, const LayoutPoint& point, bool* offsetDependsOnPoint) const @@ -1473,7 +1473,7 @@ void RenderBox::deleteLineBoxWrapper() } } -LayoutRect RenderBox::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) const +LayoutRect RenderBox::clippedOverflowRectForRepaint(RenderLayerModelObject* repaintContainer) const { if (style()->visibility() != VISIBLE && !enclosingLayer()->hasVisibleContent()) return LayoutRect(); @@ -1500,7 +1500,7 @@ LayoutRect RenderBox::clippedOverflowRectForRepaint(RenderBoxModelObject* repain return r; } -void RenderBox::computeRectForRepaint(RenderBoxModelObject* repaintContainer, LayoutRect& rect, bool fixed) const +void RenderBox::computeRectForRepaint(RenderLayerModelObject* repaintContainer, LayoutRect& rect, bool fixed) const { // The rect we compute at each step is shifted by our x/y offset in the parent container's coordinate space. // Only when we cross a writing mode boundary will we have to possibly flipForWritingMode (to convert into a more appropriate @@ -2341,8 +2341,11 @@ LayoutUnit RenderBox::availableLogicalHeightUsing(const Length& h) const // We need to stop here, since we don't want to increase the height of the table // artificially. We're going to rely on this cell getting expanded to some new // height, and then when we lay out again we'll use the calculation below. - if (isTableCell() && (h.isAuto() || h.isPercent())) - return overrideLogicalContentHeight(); + if (isTableCell() && (h.isAuto() || h.isPercent())) { + if (hasOverrideHeight()) + return overrideLogicalContentHeight(); + return logicalHeight() - borderAndPaddingLogicalHeight(); + } if (h.isPercent() && isOutOfFlowPositioned()) { // FIXME: This is wrong if the containingBlock has a perpendicular writing mode. @@ -3315,7 +3318,7 @@ void RenderBox::computePositionedLogicalWidthReplaced(LogicalExtentComputedValue LayoutUnit logicalLeftPos = logicalLeftValue + marginLogicalLeftAlias; computeLogicalLeftPositionedOffset(logicalLeftPos, this, computedValues.m_extent, containerBlock, containerLogicalWidth); - computedValues.m_position = logicalLeftPos.round(); + computedValues.m_position = logicalLeftPos; } void RenderBox::computePositionedLogicalHeightReplaced(LogicalExtentComputedValues& computedValues) const @@ -3444,7 +3447,7 @@ void RenderBox::computePositionedLogicalHeightReplaced(LogicalExtentComputedValu // Use computed values to calculate the vertical position. LayoutUnit logicalTopPos = logicalTopValue + marginBeforeAlias; computeLogicalTopPositionedOffset(logicalTopPos, this, computedValues.m_extent, containerBlock, containerLogicalHeight); - computedValues.m_position = logicalTopPos.round(); + computedValues.m_position = logicalTopPos; } LayoutRect RenderBox::localCaretRect(InlineBox* box, int caretOffset, LayoutUnit* extraWidthToEndOfLine) @@ -3820,7 +3823,7 @@ RenderLayer* RenderBox::enclosingFloatPaintingLayer() const { const RenderObject* curr = this; while (curr) { - RenderLayer* layer = curr->hasLayer() && curr->isBox() ? toRenderBoxModelObject(curr)->layer() : 0; + RenderLayer* layer = curr->hasLayer() && curr->isBox() ? toRenderBox(curr)->layer() : 0; if (layer && layer->isSelfPaintingLayer()) return layer; curr = curr->parent(); diff --git a/Source/WebCore/rendering/RenderBox.h b/Source/WebCore/rendering/RenderBox.h index db274fb84..563bbefdc 100644 --- a/Source/WebCore/rendering/RenderBox.h +++ b/Source/WebCore/rendering/RenderBox.h @@ -154,7 +154,7 @@ public: LayoutRect computedCSSContentBoxRect() const { return LayoutRect(borderLeft() + computedCSSPaddingLeft(), borderTop() + computedCSSPaddingTop(), clientWidth() - computedCSSPaddingLeft() - computedCSSPaddingRight(), clientHeight() - computedCSSPaddingTop() - computedCSSPaddingBottom()); } // Bounds of the outline box in absolute coords. Respects transforms - virtual LayoutRect outlineBoundsForRepaint(RenderBoxModelObject* /*repaintContainer*/, LayoutPoint* cachedOffsetToRepaintContainer) const; + virtual LayoutRect outlineBoundsForRepaint(RenderLayerModelObject* /*repaintContainer*/, LayoutPoint* cachedOffsetToRepaintContainer) const OVERRIDE; virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint&); // Use this with caution! No type checking is done! @@ -289,6 +289,10 @@ public: virtual LayoutUnit minPreferredLogicalWidth() const; virtual LayoutUnit maxPreferredLogicalWidth() const; + // FIXME: We should rename these back to overrideLogicalHeight/Width and have them store + // the border-box height/width like the regular height/width accessors on RenderBox. + // Right now, these are different than contentHeight/contentWidth because they still + // include the scrollbar height/width. LayoutUnit overrideLogicalContentWidth() const; LayoutUnit overrideLogicalContentHeight() const; bool hasOverrideHeight() const; @@ -354,8 +358,8 @@ public: void setInlineBoxWrapper(InlineBox* boxWrapper) { m_inlineBoxWrapper = boxWrapper; } void deleteLineBoxWrapper(); - virtual LayoutRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) const; - virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, LayoutRect&, bool fixed = false) const; + virtual LayoutRect clippedOverflowRectForRepaint(RenderLayerModelObject* repaintContainer) const OVERRIDE; + virtual void computeRectForRepaint(RenderLayerModelObject* repaintContainer, LayoutRect&, bool fixed = false) const OVERRIDE; virtual void repaintDuringLayoutIfMoved(const LayoutRect&); @@ -550,7 +554,7 @@ protected: virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle); virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle); - virtual void updateBoxModelInfoFromStyle(); + virtual void updateFromStyle() OVERRIDE; virtual bool backgroundIsObscured() const { return false; } void paintBackground(const PaintInfo&, const LayoutRect&, BackgroundBleedAvoidance = BackgroundBleedNone); @@ -570,9 +574,9 @@ protected: virtual bool shouldComputeSizeAsReplaced() const { return isReplaced() && !isInlineBlockOrInlineTable(); } - virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, TransformState&, MapLocalToContainerFlags mode = ApplyContainerFlip | SnapOffsetForTransforms, bool* wasFixed = 0) const OVERRIDE; - virtual const RenderObject* pushMappingToContainer(const RenderBoxModelObject*, RenderGeometryMap&) const; - virtual void mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState&) const; + virtual void mapLocalToContainer(RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip | SnapOffsetForTransforms, bool* wasFixed = 0) const OVERRIDE; + virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject*, RenderGeometryMap&) const OVERRIDE; + virtual void mapAbsoluteToLocalPoint(MapCoordinatesFlags, TransformState&) const; void paintRootBoxFillLayers(const PaintInfo&); diff --git a/Source/WebCore/rendering/RenderBoxModelObject.cpp b/Source/WebCore/rendering/RenderBoxModelObject.cpp index 8deeddf38..31af0f576 100644 --- a/Source/WebCore/rendering/RenderBoxModelObject.cpp +++ b/Source/WebCore/rendering/RenderBoxModelObject.cpp @@ -53,11 +53,6 @@ namespace WebCore { using namespace HTMLNames; -bool RenderBoxModelObject::s_wasFloating = false; -bool RenderBoxModelObject::s_hadLayer = false; -bool RenderBoxModelObject::s_hadTransform = false; -bool RenderBoxModelObject::s_layerWasSelfPainting = false; - static const double cInterpolationCutoff = 800. * 800.; static const double cLowQualityTimeThreshold = 0.500; // 500 ms @@ -138,7 +133,7 @@ void ImageQualityController::highQualityRepaintTimerFired(Timer<ImageQualityCont if (m_animatedResizeIsActive) { m_animatedResizeIsActive = false; for (ObjectLayerSizeMap::iterator it = m_objectLayerSizeMap.begin(); it != m_objectLayerSizeMap.end(); ++it) - it->first->repaint(); + it->key->repaint(); } } @@ -163,14 +158,14 @@ bool ImageQualityController::shouldPaintAtLowQuality(GraphicsContext* context, R // Look ourselves up in the hashtables. ObjectLayerSizeMap::iterator i = m_objectLayerSizeMap.find(object); - LayerSizeMap* innerMap = i != m_objectLayerSizeMap.end() ? &i->second : 0; + LayerSizeMap* innerMap = i != m_objectLayerSizeMap.end() ? &i->value : 0; LayoutSize oldSize; bool isFirstResize = true; if (innerMap) { LayerSizeMap::iterator j = innerMap->find(layer); if (j != innerMap->end()) { isFirstResize = false; - oldSize = j->second; + oldSize = j->value; } } @@ -317,16 +312,12 @@ bool RenderBoxModelObject::shouldPaintAtLowQuality(GraphicsContext* context, Ima } RenderBoxModelObject::RenderBoxModelObject(Node* node) - : RenderObject(node) - , m_layer(0) + : RenderLayerModelObject(node) { } RenderBoxModelObject::~RenderBoxModelObject() { - // Our layer should have been destroyed and cleared by now - ASSERT(!hasLayer()); - ASSERT(!m_layer); if (gImageQualityController) { gImageQualityController->objectDestroyed(this); if (gImageQualityController->isEmpty()) { @@ -336,14 +327,6 @@ RenderBoxModelObject::~RenderBoxModelObject() } } -void RenderBoxModelObject::destroyLayer() -{ - ASSERT(!hasLayer()); // Callers should have already called setHasLayer(false) - ASSERT(m_layer); - m_layer->destroy(renderArena()); - m_layer = 0; -} - void RenderBoxModelObject::willBeDestroyed() { // A continuation of this RenderObject should be destroyed at subclasses. @@ -363,114 +346,13 @@ void RenderBoxModelObject::willBeDestroyed() if (firstLetterRemainingText()) setFirstLetterRemainingText(0); - // RenderObject::willBeDestroyed calls back to destroyLayer() for layer destruction - RenderObject::willBeDestroyed(); -} - -bool RenderBoxModelObject::hasSelfPaintingLayer() const -{ - return m_layer && m_layer->isSelfPaintingLayer(); -} - -void RenderBoxModelObject::styleWillChange(StyleDifference diff, const RenderStyle* newStyle) -{ - s_wasFloating = isFloating(); - s_hadLayer = hasLayer(); - s_hadTransform = hasTransform(); - if (s_hadLayer) - s_layerWasSelfPainting = layer()->isSelfPaintingLayer(); - - // If our z-index changes value or our visibility changes, - // we need to dirty our stacking context's z-order list. - RenderStyle* oldStyle = style(); - if (oldStyle && newStyle) { - if (parent()) { - // Do a repaint with the old style first, e.g., for example if we go from - // having an outline to not having an outline. - if (diff == StyleDifferenceRepaintLayer) { - layer()->repaintIncludingDescendants(); - if (!(oldStyle->clip() == newStyle->clip())) - layer()->clearClipRectsIncludingDescendants(); - } else if (diff == StyleDifferenceRepaint || newStyle->outlineSize() < oldStyle->outlineSize()) - repaint(); - } - - if (diff == StyleDifferenceLayout || diff == StyleDifferenceSimplifiedLayout) { - // When a layout hint happens, we go ahead and do a repaint of the layer, since the layer could - // end up being destroyed. - if (hasLayer()) { - if (oldStyle->position() != newStyle->position() - || oldStyle->zIndex() != newStyle->zIndex() - || oldStyle->hasAutoZIndex() != newStyle->hasAutoZIndex() - || !(oldStyle->clip() == newStyle->clip()) - || oldStyle->hasClip() != newStyle->hasClip() - || oldStyle->opacity() != newStyle->opacity() - || oldStyle->transform() != newStyle->transform() -#if ENABLE(CSS_FILTERS) - || oldStyle->filter() != newStyle->filter() -#endif - ) - layer()->repaintIncludingDescendants(); - } else if (newStyle->hasTransform() || newStyle->opacity() < 1 || newStyle->hasFilter()) { - // If we don't have a layer yet, but we are going to get one because of transform or opacity, - // then we need to repaint the old position of the object. - repaint(); - } - } - } - - RenderObject::styleWillChange(diff, newStyle); + RenderLayerModelObject::willBeDestroyed(); } -void RenderBoxModelObject::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) +void RenderBoxModelObject::updateFromStyle() { - RenderObject::styleDidChange(diff, oldStyle); - updateBoxModelInfoFromStyle(); - - if (requiresLayer()) { - if (!layer() && layerCreationAllowedForSubtree()) { - if (s_wasFloating && isFloating()) - setChildNeedsLayout(true); - m_layer = new (renderArena()) RenderLayer(this); - setHasLayer(true); - m_layer->insertOnlyThisLayer(); - if (parent() && !needsLayout() && containingBlock()) { - m_layer->setRepaintStatus(NeedsFullRepaint); - // There is only one layer to update, it is not worth using |cachedOffset| since - // we are not sure the value will be used. - m_layer->updateLayerPositions(0); - } - } - } else if (layer() && layer()->parent()) { - setHasTransform(false); // Either a transform wasn't specified or the object doesn't support transforms, so just null out the bit. - setHasReflection(false); - m_layer->removeOnlyThisLayer(); // calls destroyLayer() which clears m_layer - if (s_wasFloating && isFloating()) - setChildNeedsLayout(true); - if (s_hadTransform) - setNeedsLayoutAndPrefWidthsRecalc(); - } - - if (layer()) { - layer()->styleChanged(diff, oldStyle); - if (s_hadLayer && layer()->isSelfPaintingLayer() != s_layerWasSelfPainting) - setChildNeedsLayout(true); - } - - if (FrameView *frameView = view()->frameView()) { - bool newStyleIsViewportConstained = style()->hasViewportConstrainedPosition(); - bool oldStyleIsViewportConstrained = oldStyle && oldStyle->hasViewportConstrainedPosition(); - if (newStyleIsViewportConstained != oldStyleIsViewportConstrained) { - if (newStyleIsViewportConstained && layer()) - frameView->addViewportConstrainedObject(this); - else - frameView->removeViewportConstrainedObject(this); - } - } -} + RenderLayerModelObject::updateFromStyle(); -void RenderBoxModelObject::updateBoxModelInfoFromStyle() -{ // Set the appropriate bits for a box model object. Since all bits are cleared in styleWillChange, // we only check for bits that could possibly be set to true. RenderStyle* styleToUse = style(); @@ -588,7 +470,7 @@ void RenderBoxModelObject::computeStickyPositionConstraints(StickyPositionViewpo // Compute the container-relative area within which the sticky element is allowed to move. containerContentRect.move(minLeftMargin, minTopMargin); containerContentRect.contract(minLeftMargin + minRightMargin, minTopMargin + minBottomMargin); - constraints.setAbsoluteContainingBlockRect(containingBlock->localToAbsoluteQuad(FloatRect(containerContentRect)).boundingBox()); + constraints.setAbsoluteContainingBlockRect(containingBlock->localToAbsoluteQuad(FloatRect(containerContentRect), SnapOffsetForTransforms).boundingBox()); LayoutRect stickyBoxRect = frameRectForStickyPositioning(); LayoutRect flippedStickyBoxRect = stickyBoxRect; @@ -596,7 +478,7 @@ void RenderBoxModelObject::computeStickyPositionConstraints(StickyPositionViewpo LayoutPoint stickyLocation = flippedStickyBoxRect.location(); // FIXME: sucks to call localToAbsolute again, but we can't just offset from the previously computed rect if there are transforms. - FloatRect absContainerFrame = containingBlock->localToAbsoluteQuad(FloatRect(FloatPoint(), containingBlock->size())).boundingBox(); + FloatRect absContainerFrame = containingBlock->localToAbsoluteQuad(FloatRect(FloatPoint(), containingBlock->size()), SnapOffsetForTransforms).boundingBox(); // We can't call localToAbsolute on |this| because that will recur. FIXME: For now, assume that |this| is not transformed. FloatRect absoluteStickyBoxRect(absContainerFrame.location() + stickyLocation, flippedStickyBoxRect.size()); constraints.setAbsoluteStickyBoxRect(absoluteStickyBoxRect); @@ -2814,13 +2696,13 @@ bool RenderBoxModelObject::shouldAntialiasLines(GraphicsContext* context) return !context->getCTM().isIdentityOrTranslationOrFlipped(); } -void RenderBoxModelObject::mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState& transformState) const +void RenderBoxModelObject::mapAbsoluteToLocalPoint(MapCoordinatesFlags mode, TransformState& transformState) const { RenderObject* o = container(); if (!o) return; - o->mapAbsoluteToLocalPoint(fixed, useTransforms, transformState); + o->mapAbsoluteToLocalPoint(mode, transformState); LayoutSize containerOffset = offsetFromContainer(o, LayoutPoint()); @@ -2831,8 +2713,8 @@ void RenderBoxModelObject::mapAbsoluteToLocalPoint(bool fixed, bool useTransform block->adjustForColumnRect(containerOffset, point); } - bool preserve3D = useTransforms && (o->style()->preserves3D() || style()->preserves3D()); - if (useTransforms && shouldUseTransformFromContainer(o)) { + bool preserve3D = mode & UseTransforms && (o->style()->preserves3D() || style()->preserves3D()); + if (mode & UseTransforms && shouldUseTransformFromContainer(o)) { TransformationMatrix t; getTransformFromContainer(o, containerOffset, t); transformState.applyTransform(t, preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform); diff --git a/Source/WebCore/rendering/RenderBoxModelObject.h b/Source/WebCore/rendering/RenderBoxModelObject.h index 6ee354c9a..6dfd52161 100644 --- a/Source/WebCore/rendering/RenderBoxModelObject.h +++ b/Source/WebCore/rendering/RenderBoxModelObject.h @@ -25,7 +25,7 @@ #define RenderBoxModelObject_h #include "LayoutTypesInlineMethods.h" -#include "RenderObject.h" +#include "RenderLayerModelObject.h" #include "ShadowData.h" namespace WebCore { @@ -56,7 +56,7 @@ class StickyPositionViewportConstraints; // This class is the base for all objects that adhere to the CSS box model as described // at http://www.w3.org/TR/CSS21/box.html -class RenderBoxModelObject : public RenderObject { +class RenderBoxModelObject : public RenderLayerModelObject { public: RenderBoxModelObject(Node*); virtual ~RenderBoxModelObject(); @@ -82,14 +82,9 @@ public: int pixelSnappedOffsetWidth() const; int pixelSnappedOffsetHeight() const; - virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle) OVERRIDE; - virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE; - virtual void updateBoxModelInfoFromStyle(); + virtual void updateFromStyle() OVERRIDE; - bool hasSelfPaintingLayer() const; - RenderLayer* layer() const { return m_layer; } - - virtual bool requiresLayer() const { return isRoot() || isPositioned() || createsGroup() || hasClipPath() || hasTransform() || hasHiddenBackface() || hasReflection() || style()->specifiesColumns(); } + virtual bool requiresLayer() const OVERRIDE { return isRoot() || isPositioned() || createsGroup() || hasClipPath() || hasTransform() || hasHiddenBackface() || hasReflection() || style()->specifiesColumns(); } // This will work on inlines to return the bounding box of all of the lines' border boxes. virtual IntRect borderBoundingBox() const = 0; @@ -163,10 +158,7 @@ public: virtual LayoutUnit lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const = 0; virtual LayoutUnit baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const = 0; - virtual void mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState&) const OVERRIDE; - - // Called by RenderObject::willBeDestroyed() and is the only way layers should ever be destroyed - void destroyLayer(); + virtual void mapAbsoluteToLocalPoint(MapCoordinatesFlags, TransformState&) const OVERRIDE; void highQualityRepaintTimerFired(Timer<RenderBoxModelObject>*); @@ -307,16 +299,6 @@ private: void drawBoxSideFromPath(GraphicsContext*, const LayoutRect&, const Path&, const class BorderEdge[], float thickness, float drawThickness, BoxSide, const RenderStyle*, Color, EBorderStyle, BackgroundBleedAvoidance, bool includeLogicalLeftEdge, bool includeLogicalRightEdge); - - friend class RenderView; - - RenderLayer* m_layer; - - // Used to store state between styleWillChange and styleDidChange - static bool s_wasFloating; - static bool s_hadLayer; - static bool s_hadTransform; - static bool s_layerWasSelfPainting; }; inline RenderBoxModelObject* toRenderBoxModelObject(RenderObject* object) diff --git a/Source/WebCore/rendering/RenderCombineText.cpp b/Source/WebCore/rendering/RenderCombineText.cpp index 123661e4d..c9f09e538 100644 --- a/Source/WebCore/rendering/RenderCombineText.cpp +++ b/Source/WebCore/rendering/RenderCombineText.cpp @@ -41,8 +41,10 @@ void RenderCombineText::styleDidChange(StyleDifference diff, const RenderStyle* setStyleInternal(RenderStyle::clone(style())); RenderText::styleDidChange(diff, oldStyle); - if (m_isCombined) + if (m_isCombined) { RenderText::setTextInternal(originalText()); // This RenderCombineText has been combined once. Restore the original text for the next combineText(). + m_isCombined = false; + } m_needsFontUpdate = true; } @@ -103,6 +105,8 @@ void RenderCombineText::combineText() m_combinedTextWidth = originalFont().width(run); m_isCombined = m_combinedTextWidth <= emWidth; + FontSelector* fontSelector = style()->font().fontSelector(); + if (m_isCombined) shouldUpdateFont = style()->setFontDescription(description); // Need to change font orientation to horizontal. else { @@ -111,7 +115,7 @@ void RenderCombineText::combineText() for (size_t i = 0 ; i < WTF_ARRAY_LENGTH(widthVariants) ; ++i) { description.setWidthVariant(widthVariants[i]); Font compressedFont = Font(description, style()->font().letterSpacing(), style()->font().wordSpacing()); - compressedFont.update(style()->font().fontSelector()); + compressedFont.update(fontSelector); float runWidth = compressedFont.width(run); if (runWidth <= emWidth) { m_combinedTextWidth = runWidth; @@ -128,7 +132,7 @@ void RenderCombineText::combineText() shouldUpdateFont = style()->setFontDescription(originalFont().fontDescription()); if (shouldUpdateFont) - style()->font().update(style()->font().fontSelector()); + style()->font().update(fontSelector); if (m_isCombined) { DEFINE_STATIC_LOCAL(String, objectReplacementCharacterString, (&objectReplacementCharacter, 1)); diff --git a/Source/WebCore/rendering/RenderCounter.cpp b/Source/WebCore/rendering/RenderCounter.cpp index e3496b136..24c863304 100644 --- a/Source/WebCore/rendering/RenderCounter.cpp +++ b/Source/WebCore/rendering/RenderCounter.cpp @@ -568,10 +568,10 @@ void RenderCounter::destroyCounterNodes(RenderObject* owner) CounterMaps::iterator mapsIterator = maps.find(owner); if (mapsIterator == maps.end()) return; - CounterMap* map = mapsIterator->second.get(); + CounterMap* map = mapsIterator->value.get(); CounterMap::const_iterator end = map->end(); for (CounterMap::const_iterator it = map->begin(); it != end; ++it) { - destroyCounterNodeWithoutMapRemoval(it->first, it->second.get()); + destroyCounterNodeWithoutMapRemoval(it->key, it->value.get()); } maps.remove(mapsIterator); owner->setHasCounterNodeMap(false); @@ -585,7 +585,7 @@ void RenderCounter::destroyCounterNode(RenderObject* owner, const AtomicString& CounterMap::iterator mapIterator = map->find(identifier); if (mapIterator == map->end()) return; - destroyCounterNodeWithoutMapRemoval(identifier, mapIterator->second.get()); + destroyCounterNodeWithoutMapRemoval(identifier, mapIterator->value.get()); map->remove(mapIterator); // We do not delete "map" here even if empty because we expect to reuse // it soon. In order for a renderer to lose all its counters permanently, @@ -625,22 +625,22 @@ static void updateCounters(RenderObject* renderer) CounterDirectiveMap::const_iterator end = directiveMap->end(); if (!renderer->hasCounterNodeMap()) { for (CounterDirectiveMap::const_iterator it = directiveMap->begin(); it != end; ++it) - makeCounterNode(renderer, it->first, false); + makeCounterNode(renderer, it->key, false); return; } CounterMap* counterMap = counterMaps().get(renderer); ASSERT(counterMap); for (CounterDirectiveMap::const_iterator it = directiveMap->begin(); it != end; ++it) { - RefPtr<CounterNode> node = counterMap->get(it->first); + RefPtr<CounterNode> node = counterMap->get(it->key); if (!node) { - makeCounterNode(renderer, it->first, false); + makeCounterNode(renderer, it->key, false); continue; } RefPtr<CounterNode> newParent = 0; RefPtr<CounterNode> newPreviousSibling = 0; - findPlaceForCounter(renderer, it->first, node->hasResetType(), newParent, newPreviousSibling); - if (node != counterMap->get(it->first)) + findPlaceForCounter(renderer, it->key, node->hasResetType(), newParent, newPreviousSibling); + if (node != counterMap->get(it->key)) continue; CounterNode* parent = node->parent(); if (newParent == parent && newPreviousSibling == node->previousSibling()) @@ -648,7 +648,7 @@ static void updateCounters(RenderObject* renderer) if (parent) parent->removeChild(node.get()); if (newParent) - newParent->insertAfter(node.get(), newPreviousSibling.get(), it->first); + newParent->insertAfter(node.get(), newPreviousSibling.get(), it->key); } } @@ -680,21 +680,21 @@ void RenderCounter::rendererStyleChanged(RenderObject* renderer, const RenderSty CounterDirectiveMap::const_iterator newMapEnd = newCounterDirectives->end(); CounterDirectiveMap::const_iterator oldMapEnd = oldCounterDirectives->end(); for (CounterDirectiveMap::const_iterator it = newCounterDirectives->begin(); it != newMapEnd; ++it) { - CounterDirectiveMap::const_iterator oldMapIt = oldCounterDirectives->find(it->first); + CounterDirectiveMap::const_iterator oldMapIt = oldCounterDirectives->find(it->key); if (oldMapIt != oldMapEnd) { - if (oldMapIt->second == it->second) + if (oldMapIt->value == it->value) continue; - RenderCounter::destroyCounterNode(renderer, it->first); + RenderCounter::destroyCounterNode(renderer, it->key); } // We must create this node here, because the changed node may be a node with no display such as // as those created by the increment or reset directives and the re-layout that will happen will // not catch the change if the node had no children. - makeCounterNode(renderer, it->first, false); + makeCounterNode(renderer, it->key, false); } // Destroying old counters that do not exist in the new counterDirective map. for (CounterDirectiveMap::const_iterator it = oldCounterDirectives->begin(); it !=oldMapEnd; ++it) { - if (!newCounterDirectives->contains(it->first)) - RenderCounter::destroyCounterNode(renderer, it->first); + if (!newCounterDirectives->contains(it->key)) + RenderCounter::destroyCounterNode(renderer, it->key); } } else { if (renderer->hasCounterNodeMap()) @@ -706,7 +706,7 @@ void RenderCounter::rendererStyleChanged(RenderObject* renderer, const RenderSty // We must create this node here, because the added node may be a node with no display such as // as those created by the increment or reset directives and the re-layout that will happen will // not catch the change if the node had no children. - makeCounterNode(renderer, it->first, false); + makeCounterNode(renderer, it->key, false); } } } diff --git a/Source/WebCore/rendering/RenderDeprecatedFlexibleBox.cpp b/Source/WebCore/rendering/RenderDeprecatedFlexibleBox.cpp index 8f7151a47..05aecae03 100644 --- a/Source/WebCore/rendering/RenderDeprecatedFlexibleBox.cpp +++ b/Source/WebCore/rendering/RenderDeprecatedFlexibleBox.cpp @@ -151,6 +151,20 @@ static bool childDoesNotAffectWidthOrFlexing(RenderObject* child) return child->isOutOfFlowPositioned() || child->style()->visibility() == COLLAPSE; } +static LayoutUnit contentWidthForChild(RenderBox* child) +{ + if (child->hasOverrideWidth()) + return child->overrideLogicalContentWidth(); + return child->logicalWidth() - child->borderAndPaddingLogicalWidth(); +} + +static LayoutUnit contentHeightForChild(RenderBox* child) +{ + if (child->hasOverrideHeight()) + return child->overrideLogicalContentHeight(); + return child->logicalHeight() - child->borderAndPaddingLogicalHeight(); +} + void RenderDeprecatedFlexibleBox::styleWillChange(StyleDifference diff, const RenderStyle* newStyle) { RenderStyle* oldStyle = style(); @@ -538,7 +552,7 @@ void RenderDeprecatedFlexibleBox::layoutHorizontalBox(bool relayoutChildren) if (allowedChildFlex(child, expanding, i)) { LayoutUnit spaceAdd = LayoutUnit(spaceAvailableThisPass * (child->style()->boxFlex() / totalFlex)); if (spaceAdd) { - child->setOverrideLogicalContentWidth(child->overrideLogicalContentWidth() + spaceAdd); + child->setOverrideLogicalContentWidth(contentWidthForChild(child) + spaceAdd); flexingChildren = true; relayoutChildren = true; } @@ -555,7 +569,7 @@ void RenderDeprecatedFlexibleBox::layoutHorizontalBox(bool relayoutChildren) LayoutUnit spaceAdd = groupRemainingSpace > 0 ? 1 : -1; for (RenderBox* child = iterator.first(); child && groupRemainingSpace; child = iterator.next()) { if (allowedChildFlex(child, expanding, i)) { - child->setOverrideLogicalContentWidth(child->overrideLogicalContentWidth() + spaceAdd); + child->setOverrideLogicalContentWidth(contentWidthForChild(child) + spaceAdd); flexingChildren = true; relayoutChildren = true; remainingSpace -= spaceAdd; @@ -789,7 +803,7 @@ void RenderDeprecatedFlexibleBox::layoutVerticalBox(bool relayoutChildren) if (allowedChildFlex(child, expanding, i)) { LayoutUnit spaceAdd = static_cast<LayoutUnit>(spaceAvailableThisPass * (child->style()->boxFlex() / totalFlex)); if (spaceAdd) { - child->setOverrideLogicalContentHeight(child->overrideLogicalContentHeight() + spaceAdd); + child->setOverrideLogicalContentHeight(contentHeightForChild(child) + spaceAdd); flexingChildren = true; relayoutChildren = true; } @@ -806,7 +820,7 @@ void RenderDeprecatedFlexibleBox::layoutVerticalBox(bool relayoutChildren) LayoutUnit spaceAdd = groupRemainingSpace > 0 ? 1 : -1; for (RenderBox* child = iterator.first(); child && groupRemainingSpace; child = iterator.next()) { if (allowedChildFlex(child, expanding, i)) { - child->setOverrideLogicalContentHeight(child->overrideLogicalContentHeight() + spaceAdd); + child->setOverrideLogicalContentHeight(contentHeightForChild(child) + spaceAdd); flexingChildren = true; relayoutChildren = true; remainingSpace -= spaceAdd; @@ -1019,7 +1033,7 @@ LayoutUnit RenderDeprecatedFlexibleBox::allowedChildFlex(RenderBox* child, bool if (isHorizontal()) { // FIXME: For now just handle fixed values. LayoutUnit maxWidth = MAX_LAYOUT_UNIT; - LayoutUnit width = child->overrideLogicalContentWidth(); + LayoutUnit width = contentWidthForChild(child); if (!child->style()->maxWidth().isUndefined() && child->style()->maxWidth().isFixed()) maxWidth = child->style()->maxWidth().value(); else if (child->style()->maxWidth().type() == Intrinsic) @@ -1032,7 +1046,7 @@ LayoutUnit RenderDeprecatedFlexibleBox::allowedChildFlex(RenderBox* child, bool } else { // FIXME: For now just handle fixed values. LayoutUnit maxHeight = MAX_LAYOUT_UNIT; - LayoutUnit height = child->overrideLogicalContentHeight(); + LayoutUnit height = contentHeightForChild(child); if (!child->style()->maxHeight().isUndefined() && child->style()->maxHeight().isFixed()) maxHeight = child->style()->maxHeight().value(); if (maxHeight == MAX_LAYOUT_UNIT) @@ -1044,7 +1058,7 @@ LayoutUnit RenderDeprecatedFlexibleBox::allowedChildFlex(RenderBox* child, bool // FIXME: For now just handle fixed values. if (isHorizontal()) { LayoutUnit minWidth = child->minPreferredLogicalWidth(); - LayoutUnit width = child->overrideLogicalContentWidth(); + LayoutUnit width = contentWidthForChild(child); if (child->style()->minWidth().isFixed()) minWidth = child->style()->minWidth().value(); else if (child->style()->minWidth().type() == Intrinsic) @@ -1060,7 +1074,7 @@ LayoutUnit RenderDeprecatedFlexibleBox::allowedChildFlex(RenderBox* child, bool Length minHeight = child->style()->minHeight(); if (minHeight.isFixed() || minHeight.isAuto()) { LayoutUnit minHeight = child->style()->minHeight().value(); - LayoutUnit height = child->overrideLogicalContentHeight(); + LayoutUnit height = contentHeightForChild(child); LayoutUnit allowedShrinkage = min<LayoutUnit>(0, minHeight - height); return allowedShrinkage; } diff --git a/Source/WebCore/rendering/RenderEmbeddedObject.cpp b/Source/WebCore/rendering/RenderEmbeddedObject.cpp index 1111e299e..1007dfb39 100644 --- a/Source/WebCore/rendering/RenderEmbeddedObject.cpp +++ b/Source/WebCore/rendering/RenderEmbeddedObject.cpp @@ -322,7 +322,7 @@ bool RenderEmbeddedObject::isInUnavailablePluginIndicator(const LayoutPoint& poi bool RenderEmbeddedObject::isInUnavailablePluginIndicator(MouseEvent* event) const { - return isInUnavailablePluginIndicator(roundedLayoutPoint(absoluteToLocal(event->absoluteLocation(), false, true))); + return isInUnavailablePluginIndicator(roundedLayoutPoint(absoluteToLocal(event->absoluteLocation(), UseTransforms | SnapOffsetForTransforms))); } static bool shouldUnavailablePluginMessageBeButton(Document* document, RenderEmbeddedObject::PluginUnavailabilityReason pluginUnavailabilityReason) diff --git a/Source/WebCore/rendering/RenderEmbeddedObject.h b/Source/WebCore/rendering/RenderEmbeddedObject.h index 3f318b167..95d131756 100644 --- a/Source/WebCore/rendering/RenderEmbeddedObject.h +++ b/Source/WebCore/rendering/RenderEmbeddedObject.h @@ -1,7 +1,7 @@ /* * Copyright (C) 1999 Lars Knoll (knoll@kde.org) * (C) 2000 Simon Hausmann <hausmann@kde.org> - * Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010, 2012 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -56,14 +56,16 @@ public: virtual bool allowsAcceleratedCompositing() const; #endif -private: - virtual const char* renderName() const { return "RenderEmbeddedObject"; } - virtual bool isEmbeddedObject() const { return true; } - +protected: virtual void paintReplaced(PaintInfo&, const LayoutPoint&); virtual void paint(PaintInfo&, const LayoutPoint&); + virtual CursorDirective getCursor(const LayoutPoint&, Cursor&) const; +private: + virtual const char* renderName() const { return "RenderEmbeddedObject"; } + virtual bool isEmbeddedObject() const { return true; } + #if USE(ACCELERATED_COMPOSITING) virtual bool requiresLayer() const; #endif diff --git a/Source/WebCore/rendering/RenderFlexibleBox.cpp b/Source/WebCore/rendering/RenderFlexibleBox.cpp index abc73dd83..279c29862 100644 --- a/Source/WebCore/rendering/RenderFlexibleBox.cpp +++ b/Source/WebCore/rendering/RenderFlexibleBox.cpp @@ -132,6 +132,7 @@ struct RenderFlexibleBox::Violation { RenderFlexibleBox::RenderFlexibleBox(Node* node) : RenderBlock(node) + , m_numberOfChildrenOnFirstLine(0) { setChildrenInline(false); // All of our children must be block-level. } @@ -234,6 +235,51 @@ void RenderFlexibleBox::computePreferredLogicalWidths() setPreferredLogicalWidthsDirty(false); } +LayoutUnit RenderFlexibleBox::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const +{ + LayoutUnit baseline = firstLineBoxBaseline(); + if (baseline != -1) { + LayoutUnit marginAscent = direction == HorizontalLine ? marginTop() : marginRight(); + return baseline + marginAscent; + } + + return RenderBox::baselinePosition(baselineType, firstLine, direction, linePositionMode); +} + +LayoutUnit RenderFlexibleBox::firstLineBoxBaseline() const +{ + ASSERT(m_orderIterator); + + if (isWritingModeRoot() || !m_numberOfChildrenOnFirstLine) + return -1; + RenderBox* baselineChild = 0; + RenderBox* child = m_orderIterator->first(); + for (size_t childNumber = 0; childNumber < m_numberOfChildrenOnFirstLine; ++childNumber, child = m_orderIterator->next()) { + if (child->isOutOfFlowPositioned()) + continue; + if (alignmentForChild(child) == AlignBaseline && !hasAutoMarginsInCrossAxis(child)) { + baselineChild = child; + break; + } + if (!baselineChild) + baselineChild = child; + } + + if (!baselineChild) + return -1; + + if (!isColumnFlow() && hasOrthogonalFlow(baselineChild)) + return crossAxisExtentForChild(baselineChild) + baselineChild->logicalTop(); + if (isColumnFlow() && !hasOrthogonalFlow(baselineChild)) + return mainAxisExtentForChild(baselineChild) + baselineChild->logicalTop(); + + LayoutUnit baseline = baselineChild->firstLineBoxBaseline(); + if (baseline == -1) + return -1; + + return baseline + baselineChild->logicalTop(); +} + void RenderFlexibleBox::layoutBlock(bool relayoutChildren, LayoutUnit) { ASSERT(needsLayout()); @@ -258,6 +304,8 @@ void RenderFlexibleBox::layoutBlock(bool relayoutChildren, LayoutUnit) m_overflow.clear(); + RenderBlock::startDelayUpdateScrollInfo(); + WTF::Vector<LineContext> lineContexts; OrderHashSet orderValues; computeMainAxisPreferredSizes(relayoutChildren, orderValues); @@ -268,12 +316,15 @@ void RenderFlexibleBox::layoutBlock(bool relayoutChildren, LayoutUnit) updateLogicalHeight(); repositionLogicalHeightDependentFlexItems(*m_orderIterator, lineContexts, oldClientAfterEdge); + RenderBlock::finishDelayUpdateScrollInfo(); + if (size() != previousSize) relayoutChildren = true; layoutPositionedObjects(relayoutChildren || isRoot()); computeRegionRangeForBlock(); + clearChildOverrideSizes(); // FIXME: css3/flexbox/repaint-rtl-column.html seems to repaint more overflow than it needs to. computeOverflow(oldClientAfterEdge); @@ -283,8 +334,7 @@ void RenderFlexibleBox::layoutBlock(bool relayoutChildren, LayoutUnit) // Update our scroll information if we're overflow:auto/scroll/hidden now that we know if // we overflow or not. - if (hasOverflowClip()) - layer()->updateScrollInfoAfterLayout(); + updateScrollInfoAfterLayout(); repainter.repaintAfterLayout(); @@ -318,10 +368,18 @@ void RenderFlexibleBox::repositionLogicalHeightDependentFlexItems(OrderIterator& flipForWrapReverse(iterator, lineContexts, crossAxisStartEdge); } + m_numberOfChildrenOnFirstLine = lineContexts.isEmpty() ? 0 : lineContexts[0].numberOfChildren; + // direction:rtl + flex-direction:column means the cross-axis direction is flipped. flipForRightToLeftColumn(iterator); } +void RenderFlexibleBox::clearChildOverrideSizes() +{ + for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) + child->clearOverrideSize(); +} + bool RenderFlexibleBox::hasOrthogonalFlow(RenderBox* child) const { // FIXME: If the child is a flexbox, then we need to check isHorizontalFlow. @@ -368,12 +426,12 @@ void RenderFlexibleBox::setCrossAxisExtent(LayoutUnit extent) setWidth(extent); } -LayoutUnit RenderFlexibleBox::crossAxisExtentForChild(RenderBox* child) +LayoutUnit RenderFlexibleBox::crossAxisExtentForChild(RenderBox* child) const { return isHorizontalFlow() ? child->height() : child->width(); } -LayoutUnit RenderFlexibleBox::mainAxisExtentForChild(RenderBox* child) +LayoutUnit RenderFlexibleBox::mainAxisExtentForChild(RenderBox* child) const { return isHorizontalFlow() ? child->width() : child->height(); } @@ -615,8 +673,8 @@ void RenderFlexibleBox::layoutFlexItems(OrderIterator& iterator, WTF::Vector<Lin { OrderedFlexItemList orderedChildren; LayoutUnit preferredMainAxisExtent; - float totalFlexGrow; - float totalWeightedFlexShrink; + double totalFlexGrow; + double totalWeightedFlexShrink; LayoutUnit minMaxAppliedMainAxisExtent; LayoutUnit crossAxisOffset = flowAwareBorderBefore() + flowAwarePaddingBefore(); @@ -680,7 +738,7 @@ void RenderFlexibleBox::updateAutoMarginsInMainAxis(RenderBox* child, LayoutUnit } } -bool RenderFlexibleBox::hasAutoMarginsInCrossAxis(RenderBox* child) +bool RenderFlexibleBox::hasAutoMarginsInCrossAxis(RenderBox* child) const { if (isHorizontalFlow()) return child->style()->marginTop().isAuto() || child->style()->marginBottom().isAuto(); @@ -734,7 +792,7 @@ LayoutUnit RenderFlexibleBox::marginBoxAscentForChild(RenderBox* child) { LayoutUnit ascent = child->firstLineBoxBaseline(); if (ascent == -1) - ascent = crossAxisExtentForChild(child) + flowAwareMarginAfterForChild(child); + ascent = crossAxisExtentForChild(child); return ascent + flowAwareMarginBeforeForChild(child); } @@ -755,7 +813,6 @@ void RenderFlexibleBox::computeMainAxisPreferredSizes(bool relayoutChildren, Ord if (child->isOutOfFlowPositioned()) continue; - child->clearOverrideSize(); // Only need to layout here if we will need to get the logicalHeight of the child in computeNextFlexLine. Length childMainAxisMin = isHorizontalFlow() ? child->style()->minWidth() : child->style()->minHeight(); if (hasOrthogonalFlow(child) && (flexBasisForChild(child).isAuto() || childMainAxisMin.isAuto())) { @@ -797,7 +854,7 @@ LayoutUnit RenderFlexibleBox::adjustChildSizeForMinAndMax(RenderBox* child, Layo return std::max(childSize, minExtent); } -bool RenderFlexibleBox::computeNextFlexLine(OrderIterator& iterator, OrderedFlexItemList& orderedChildren, LayoutUnit& preferredMainAxisExtent, float& totalFlexGrow, float& totalWeightedFlexShrink, LayoutUnit& minMaxAppliedMainAxisExtent) +bool RenderFlexibleBox::computeNextFlexLine(OrderIterator& iterator, OrderedFlexItemList& orderedChildren, LayoutUnit& preferredMainAxisExtent, double& totalFlexGrow, double& totalWeightedFlexShrink, LayoutUnit& minMaxAppliedMainAxisExtent) { orderedChildren.clear(); preferredMainAxisExtent = 0; @@ -832,7 +889,7 @@ bool RenderFlexibleBox::computeNextFlexLine(OrderIterator& iterator, OrderedFlex return true; } -void RenderFlexibleBox::freezeViolations(const WTF::Vector<Violation>& violations, LayoutUnit& availableFreeSpace, float& totalFlexGrow, float& totalWeightedFlexShrink, InflexibleFlexItemSize& inflexibleItems) +void RenderFlexibleBox::freezeViolations(const WTF::Vector<Violation>& violations, LayoutUnit& availableFreeSpace, double& totalFlexGrow, double& totalWeightedFlexShrink, InflexibleFlexItemSize& inflexibleItems) { for (size_t i = 0; i < violations.size(); ++i) { RenderBox* child = violations[i].child; @@ -846,7 +903,7 @@ void RenderFlexibleBox::freezeViolations(const WTF::Vector<Violation>& violation } // Returns true if we successfully ran the algorithm and sized the flex items. -bool RenderFlexibleBox::resolveFlexibleLengths(FlexSign flexSign, const OrderedFlexItemList& children, LayoutUnit& availableFreeSpace, float& totalFlexGrow, float& totalWeightedFlexShrink, InflexibleFlexItemSize& inflexibleItems, WTF::Vector<LayoutUnit>& childSizes) +bool RenderFlexibleBox::resolveFlexibleLengths(FlexSign flexSign, const OrderedFlexItemList& children, LayoutUnit& availableFreeSpace, double& totalFlexGrow, double& totalWeightedFlexShrink, InflexibleFlexItemSize& inflexibleItems, WTF::Vector<LayoutUnit>& childSizes) { childSizes.clear(); LayoutUnit totalViolation = 0; @@ -943,13 +1000,16 @@ void RenderFlexibleBox::prepareChildForPositionedLayout(RenderBox* child, Layout } } -static EAlignItems alignmentForChild(RenderBox* child) +EAlignItems RenderFlexibleBox::alignmentForChild(RenderBox* child) const { EAlignItems align = child->style()->alignSelf(); if (align == AlignAuto) - align = child->parent()->style()->alignItems(); + align = style()->alignItems(); + + if (align == AlignBaseline && hasOrthogonalFlow(child)) + align = AlignFlexStart; - if (child->parent()->style()->flexWrap() == FlexWrapReverse) { + if (style()->flexWrap() == FlexWrapReverse) { if (align == AlignFlexStart) align = AlignFlexEnd; else if (align == AlignFlexEnd) @@ -1189,6 +1249,8 @@ void RenderFlexibleBox::alignChildren(OrderIterator& iterator, const WTF::Vector adjustAlignmentForChild(child, availableAlignmentSpaceForChild(lineCrossAxisExtent, child) / 2); break; case AlignBaseline: { + // FIXME: If we get here in columns, we want the use the descent, except we currently can't get the ascent/descent of orthogonal children. + // https://bugs.webkit.org/show_bug.cgi?id=98076 LayoutUnit ascent = marginBoxAscentForChild(child); LayoutUnit startOffset = maxAscent - ascent; adjustAlignmentForChild(child, startOffset); diff --git a/Source/WebCore/rendering/RenderFlexibleBox.h b/Source/WebCore/rendering/RenderFlexibleBox.h index fafa8be51..495179659 100644 --- a/Source/WebCore/rendering/RenderFlexibleBox.h +++ b/Source/WebCore/rendering/RenderFlexibleBox.h @@ -49,6 +49,9 @@ public: virtual void computePreferredLogicalWidths() OVERRIDE; virtual void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0) OVERRIDE; + virtual LayoutUnit baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const OVERRIDE; + virtual LayoutUnit firstLineBoxBaseline() const OVERRIDE; + virtual void paintChildren(PaintInfo& forSelf, const LayoutPoint&, PaintInfo& forChild, bool usePrintRect) OVERRIDE; bool isHorizontalFlow() const; @@ -80,8 +83,8 @@ private: bool isMultiline() const; Length flexBasisForChild(RenderBox* child) const; void setCrossAxisExtent(LayoutUnit); - LayoutUnit crossAxisExtentForChild(RenderBox* child); - LayoutUnit mainAxisExtentForChild(RenderBox* child); + LayoutUnit crossAxisExtentForChild(RenderBox* child) const; + LayoutUnit mainAxisExtentForChild(RenderBox* child) const; LayoutUnit crossAxisExtent() const; LayoutUnit mainAxisExtent() const; LayoutUnit crossAxisContentExtent() const; @@ -106,6 +109,7 @@ private: // FIXME: Supporting layout deltas. void setFlowAwareLocationForChild(RenderBox* child, const LayoutPoint&); void adjustAlignmentForChild(RenderBox* child, LayoutUnit); + EAlignItems alignmentForChild(RenderBox* child) const; LayoutUnit mainAxisBorderAndPaddingExtentForChild(RenderBox* child) const; LayoutUnit mainAxisScrollbarExtentForChild(RenderBox* child) const; LayoutUnit preferredMainAxisContentExtentForChild(RenderBox* child); @@ -113,9 +117,10 @@ private: void layoutFlexItems(OrderIterator&, WTF::Vector<LineContext>&); LayoutUnit autoMarginOffsetInMainAxis(const OrderedFlexItemList&, LayoutUnit& availableFreeSpace); void updateAutoMarginsInMainAxis(RenderBox* child, LayoutUnit autoMarginOffset); - bool hasAutoMarginsInCrossAxis(RenderBox* child); + bool hasAutoMarginsInCrossAxis(RenderBox* child) const; bool updateAutoMarginsInCrossAxis(RenderBox* child, LayoutUnit availableAlignmentSpace); void repositionLogicalHeightDependentFlexItems(OrderIterator&, WTF::Vector<LineContext>&, LayoutUnit& oldClientAfterEdge); + void clearChildOverrideSizes(); LayoutUnit availableAlignmentSpaceForChild(LayoutUnit lineCrossAxisExtent, RenderBox*); LayoutUnit marginBoxAscentForChild(RenderBox*); @@ -123,10 +128,10 @@ private: LayoutUnit computeChildMarginValue(Length margin, RenderView*); void computeMainAxisPreferredSizes(bool relayoutChildren, OrderHashSet&); LayoutUnit adjustChildSizeForMinAndMax(RenderBox*, LayoutUnit childSize); - bool computeNextFlexLine(OrderIterator&, OrderedFlexItemList& orderedChildren, LayoutUnit& preferredMainAxisExtent, float& totalFlexGrow, float& totalWeightedFlexShrink, LayoutUnit& minMaxAppliedMainAxisExtent); + bool computeNextFlexLine(OrderIterator&, OrderedFlexItemList& orderedChildren, LayoutUnit& preferredMainAxisExtent, double& totalFlexGrow, double& totalWeightedFlexShrink, LayoutUnit& minMaxAppliedMainAxisExtent); - bool resolveFlexibleLengths(FlexSign, const OrderedFlexItemList&, LayoutUnit& availableFreeSpace, float& totalFlexGrow, float& totalWeightedFlexShrink, InflexibleFlexItemSize&, WTF::Vector<LayoutUnit>& childSizes); - void freezeViolations(const WTF::Vector<Violation>&, LayoutUnit& availableFreeSpace, float& totalFlexGrow, float& totalWeightedFlexShrink, InflexibleFlexItemSize&); + bool resolveFlexibleLengths(FlexSign, const OrderedFlexItemList&, LayoutUnit& availableFreeSpace, double& totalFlexGrow, double& totalWeightedFlexShrink, InflexibleFlexItemSize&, WTF::Vector<LayoutUnit>& childSizes); + void freezeViolations(const WTF::Vector<Violation>&, LayoutUnit& availableFreeSpace, double& totalFlexGrow, double& totalWeightedFlexShrink, InflexibleFlexItemSize&); void setLogicalOverrideSize(RenderBox* child, LayoutUnit childPreferredSize); void prepareChildForPositionedLayout(RenderBox* child, LayoutUnit mainAxisOffset, LayoutUnit crossAxisOffset, PositionedLayoutMode); @@ -140,6 +145,7 @@ private: void flipForWrapReverse(OrderIterator&, const WTF::Vector<LineContext>&, LayoutUnit crossAxisStartEdge); OwnPtr<OrderIterator> m_orderIterator; + size_t m_numberOfChildrenOnFirstLine; }; } // namespace WebCore diff --git a/Source/WebCore/rendering/RenderFlowThread.cpp b/Source/WebCore/rendering/RenderFlowThread.cpp index d5a99b7bb..379443b4a 100644 --- a/Source/WebCore/rendering/RenderFlowThread.cpp +++ b/Source/WebCore/rendering/RenderFlowThread.cpp @@ -47,7 +47,6 @@ namespace WebCore { RenderFlowThread::RenderFlowThread(Node* node) : RenderBlock(node) - , m_hasValidRegions(false) , m_regionsInvalidated(false) , m_regionsHaveUniformLogicalWidth(true) , m_regionsHaveUniformLogicalHeight(true) @@ -136,17 +135,15 @@ void RenderFlowThread::layout() m_pageLogicalHeightChanged = m_regionsInvalidated && everHadLayout(); if (m_regionsInvalidated) { m_regionsInvalidated = false; - m_hasValidRegions = false; m_regionsHaveUniformLogicalWidth = true; m_regionsHaveUniformLogicalHeight = true; m_regionRangeMap.clear(); LayoutUnit previousRegionLogicalWidth = 0; LayoutUnit previousRegionLogicalHeight = 0; + bool firstRegionVisited = false; if (hasRegions()) { for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { RenderRegion* region = *iter; - if (!region->isValid()) - continue; ASSERT(!region->needsLayout()); region->deleteAllRenderBoxRegionInfo(); @@ -154,8 +151,8 @@ void RenderFlowThread::layout() LayoutUnit regionLogicalWidth = region->pageLogicalWidth(); LayoutUnit regionLogicalHeight = region->pageLogicalHeight(); - if (!m_hasValidRegions) - m_hasValidRegions = true; + if (!firstRegionVisited) + firstRegionVisited = true; else { if (m_regionsHaveUniformLogicalWidth && previousRegionLogicalWidth != regionLogicalWidth) m_regionsHaveUniformLogicalWidth = false; @@ -171,8 +168,6 @@ void RenderFlowThread::layout() LayoutUnit logicalHeight = 0; for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { RenderRegion* region = *iter; - if (!region->isValid()) - continue; LayoutUnit regionLogicalWidth = region->pageLogicalWidth(); LayoutUnit regionLogicalHeight = region->logicalHeightOfAllFlowThreadContent(); @@ -201,8 +196,6 @@ void RenderFlowThread::updateLogicalWidth() LayoutUnit logicalWidth = 0; for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { RenderRegion* region = *iter; - if (!region->isValid()) - continue; ASSERT(!region->needsLayout()); logicalWidth = max(region->pageLogicalWidth(), logicalWidth); } @@ -211,9 +204,6 @@ void RenderFlowThread::updateLogicalWidth() // If the regions have non-uniform logical widths, then insert inset information for the RenderFlowThread. for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { RenderRegion* region = *iter; - if (!region->isValid()) - continue; - LayoutUnit regionLogicalWidth = region->pageLogicalWidth(); if (regionLogicalWidth != logicalWidth) { LayoutUnit logicalLeft = style()->direction() == LTR ? ZERO_LAYOUT_UNIT : logicalWidth - regionLogicalWidth; @@ -229,8 +219,6 @@ void RenderFlowThread::computeLogicalHeight(LayoutUnit, LayoutUnit logicalTop, L for (RenderRegionList::const_iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { RenderRegion* region = *iter; - if (!region->isValid()) - continue; ASSERT(!region->needsLayout()); computedValues.m_extent += region->logicalHeightOfAllFlowThreadContent(); } @@ -324,8 +312,6 @@ void RenderFlowThread::repaintRectangleInRegions(const LayoutRect& repaintRect, for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { RenderRegion* region = *iter; - if (!region->isValid()) - continue; region->repaintFlowThreadContent(repaintRect, immediate); } @@ -343,8 +329,6 @@ RenderRegion* RenderFlowThread::regionAtBlockOffset(LayoutUnit offset, bool exte bool useHorizontalWritingMode = isHorizontalWritingMode(); for (RenderRegionList::const_iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { RenderRegion* region = *iter; - if (!region->isValid()) - continue; if (offset <= 0) return region; @@ -432,8 +416,6 @@ void RenderFlowThread::removeRenderBoxRegionInfo(RenderBox* box) for (RenderRegionList::iterator iter = m_regionList.find(startRegion); iter != m_regionList.end(); ++iter) { RenderRegion* region = *iter; - if (!region->isValid()) - continue; region->removeRenderBoxRegionInfo(box); if (region == endRegion) break; @@ -443,8 +425,6 @@ void RenderFlowThread::removeRenderBoxRegionInfo(RenderBox* box) // We have to make sure we did not leave any RenderBoxRegionInfo attached. for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { RenderRegion* region = *iter; - if (!region->isValid()) - continue; ASSERT(!region->renderBoxRegionInfo(box)); } #endif @@ -463,10 +443,6 @@ bool RenderFlowThread::logicalWidthChangedInRegions(const RenderBlock* block, La for (RenderRegionList::iterator iter = m_regionList.find(startRegion); iter != m_regionList.end(); ++iter) { RenderRegion* region = *iter; - - if (!region->isValid()) - continue; - ASSERT(!region->needsLayout()); OwnPtr<RenderBoxRegionInfo> oldInfo = region->takeRenderBoxRegionInfo(block); @@ -487,70 +463,40 @@ bool RenderFlowThread::logicalWidthChangedInRegions(const RenderBlock* block, La LayoutUnit RenderFlowThread::contentLogicalWidthOfFirstRegion() const { - if (!hasValidRegionInfo()) - return 0; - for (RenderRegionList::const_iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { - RenderRegion* region = *iter; - if (!region->isValid()) - continue; - return isHorizontalWritingMode() ? region->contentWidth() : region->contentHeight(); - } - ASSERT_NOT_REACHED(); - return 0; + RenderRegion* firstValidRegionInFlow = firstRegion(); + if (!firstValidRegionInFlow) + return ZERO_LAYOUT_UNIT; + return isHorizontalWritingMode() ? firstValidRegionInFlow->contentWidth() : firstValidRegionInFlow->contentHeight(); } LayoutUnit RenderFlowThread::contentLogicalHeightOfFirstRegion() const { - if (!hasValidRegionInfo()) - return 0; - for (RenderRegionList::const_iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { - RenderRegion* region = *iter; - if (!region->isValid()) - continue; - return isHorizontalWritingMode() ? region->contentHeight() : region->contentWidth(); - } - ASSERT_NOT_REACHED(); - return 0; + RenderRegion* firstValidRegionInFlow = firstRegion(); + if (!firstValidRegionInFlow) + return ZERO_LAYOUT_UNIT; + return isHorizontalWritingMode() ? firstValidRegionInFlow->contentHeight() : firstValidRegionInFlow->contentWidth(); } - + LayoutUnit RenderFlowThread::contentLogicalLeftOfFirstRegion() const { - if (!hasValidRegionInfo()) - return 0; - for (RenderRegionList::const_iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { - RenderRegion* region = *iter; - if (!region->isValid()) - continue; - return isHorizontalWritingMode() ? region->flowThreadPortionRect().x() : region->flowThreadPortionRect().y(); - } - ASSERT_NOT_REACHED(); - return 0; + RenderRegion* firstValidRegionInFlow = firstRegion(); + if (!firstValidRegionInFlow) + return ZERO_LAYOUT_UNIT; + return isHorizontalWritingMode() ? firstValidRegionInFlow->flowThreadPortionRect().x() : firstValidRegionInFlow->flowThreadPortionRect().y(); } RenderRegion* RenderFlowThread::firstRegion() const { if (!hasValidRegionInfo()) return 0; - for (RenderRegionList::const_iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { - RenderRegion* region = *iter; - if (!region->isValid()) - continue; - return region; - } - return 0; + return m_regionList.first(); } RenderRegion* RenderFlowThread::lastRegion() const { if (!hasValidRegionInfo()) return 0; - for (RenderRegionList::const_reverse_iterator iter = m_regionList.rbegin(); iter != m_regionList.rend(); ++iter) { - RenderRegion* region = *iter; - if (!region->isValid()) - continue; - return region; - } - return 0; + return m_regionList.last(); } void RenderFlowThread::clearRenderObjectCustomStyle(const RenderObject* object, @@ -595,7 +541,7 @@ void RenderFlowThread::setRegionRangeForBox(const RenderBox* box, LayoutUnit off } // If nothing changed, just bail. - RenderRegionRange& range = it->second; + RenderRegionRange& range = it->value; if (range.startRegion() == startRegion && range.endRegion() == endRegion) return; @@ -625,7 +571,7 @@ void RenderFlowThread::getRegionRangeForBox(const RenderBox* box, RenderRegion*& if (it == m_regionRangeMap.end()) return; - const RenderRegionRange& range = it->second; + const RenderRegionRange& range = it->value; startRegion = range.startRegion(); endRegion = range.endRegion(); ASSERT(m_regionList.contains(startRegion) && m_regionList.contains(endRegion)); @@ -638,17 +584,14 @@ void RenderFlowThread::computeOverflowStateForRegions(LayoutUnit oldClientAfterE // might not be taken into account because the render flow thread height is greater that that regions height + its visual overflow // because of how computeLogicalHeight is implemented for RenderFlowThread (as a sum of all regions height). // This means that the middle region will be marked as fit (even if it has visual overflow flowing into the next region) - if (hasRenderOverflow() && ( (isHorizontalWritingMode() && visualOverflowRect().maxY() > clientBoxRect().maxY()) - || (!isHorizontalWritingMode() && visualOverflowRect().maxX() > clientBoxRect().maxX()))) + if (hasRenderOverflow() + && ( (isHorizontalWritingMode() && visualOverflowRect().maxY() > clientBoxRect().maxY()) + || (!isHorizontalWritingMode() && visualOverflowRect().maxX() > clientBoxRect().maxX()))) height = isHorizontalWritingMode() ? visualOverflowRect().maxY() : visualOverflowRect().maxX(); RenderRegion* lastReg = lastRegion(); for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { RenderRegion* region = *iter; - if (!region->isValid()) { - region->setRegionState(RenderRegion::RegionUndefined); - continue; - } LayoutUnit flowMin = height - (isHorizontalWritingMode() ? region->flowThreadPortionRect().y() : region->flowThreadPortionRect().x()); LayoutUnit flowMax = height - (isHorizontalWritingMode() ? region->flowThreadPortionRect().maxY() : region->flowThreadPortionRect().maxX()); RenderRegion::RegionState previousState = region->regionState(); @@ -678,8 +621,6 @@ bool RenderFlowThread::regionInRange(const RenderRegion* targetRegion, const Ren for (RenderRegionList::const_iterator it = m_regionList.find(const_cast<RenderRegion*>(startRegion)); it != m_regionList.end(); ++it) { const RenderRegion* currRegion = *it; - if (!currRegion->isValid()) - continue; if (targetRegion == currRegion) return true; if (currRegion == endRegion) @@ -695,8 +636,6 @@ void RenderFlowThread::checkRegionsWithStyling() bool hasRegionsWithStyling = false; for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { RenderRegion* region = *iter; - if (!region->isValid()) - continue; if (region->hasCustomRegionStyle()) { hasRegionsWithStyling = true; break; @@ -722,7 +661,7 @@ bool RenderFlowThread::objectInFlowRegion(const RenderObject* object, const Rend RenderRegion* enclosingBoxEndRegion = 0; getRegionRangeForBox(enclosingBox, enclosingBoxStartRegion, enclosingBoxEndRegion); if (!regionInRange(region, enclosingBoxStartRegion, enclosingBoxEndRegion)) - return false; + return false; if (object->isBox()) return true; @@ -740,8 +679,6 @@ bool RenderFlowThread::objectInFlowRegion(const RenderObject* object, const Rend // then the object is in last region. for (RenderRegionList::const_iterator it = m_regionList.find(enclosingBoxStartRegion); it != m_regionList.end(); ++it) { const RenderRegion* currRegion = *it; - if (!region->isValid()) - continue; if (currRegion == region) break; if (objectABBRect.intersects(currRegion->absoluteBoundingBoxRect(true))) @@ -759,11 +696,6 @@ unsigned RenderFlowThread::autoLogicalHeightRegionsCount() const unsigned autoLogicalHeightRegions = 0; for (RenderRegionList::const_iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { const RenderRegion* region = *iter; - if (!region->isValid()) { - ASSERT(!region->hasAutoLogicalHeight()); - continue; - } - if (region->hasAutoLogicalHeight()) autoLogicalHeightRegions++; } @@ -773,7 +705,7 @@ unsigned RenderFlowThread::autoLogicalHeightRegionsCount() const #endif CurrentRenderFlowThreadMaintainer::CurrentRenderFlowThreadMaintainer(RenderFlowThread* renderFlowThread) - : m_renderFlowThread(renderFlowThread) + : m_renderFlowThread(renderFlowThread) { if (!m_renderFlowThread) return; diff --git a/Source/WebCore/rendering/RenderFlowThread.h b/Source/WebCore/rendering/RenderFlowThread.h index b942eee57..93e9137f0 100644 --- a/Source/WebCore/rendering/RenderFlowThread.h +++ b/Source/WebCore/rendering/RenderFlowThread.h @@ -80,13 +80,12 @@ public: bool hitTestFlowThreadPortionInRegion(RenderRegion*, LayoutRect flowThreadPortionRect, LayoutRect flowThreadPortionOverflowRect, const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset) const; bool hasRegions() const { return m_regionList.size(); } - bool hasValidRegions() const { ASSERT(!m_regionsInvalidated); return m_hasValidRegions; } // Check if the content is flown into at least a region with region styling rules. bool hasRegionsWithStyling() const { return m_hasRegionsWithStyling; } void checkRegionsWithStyling(); void invalidateRegions() { m_regionsInvalidated = true; setNeedsLayout(true); } - bool hasValidRegionInfo() const { return !m_regionsInvalidated && hasValidRegions(); } + bool hasValidRegionInfo() const { return !m_regionsInvalidated && !m_regionList.isEmpty(); } static PassRefPtr<RenderStyle> createFlowThreadStyle(RenderStyle* parentStyle); @@ -179,7 +178,6 @@ protected: typedef HashMap<const RenderBox*, RenderRegionRange> RenderRegionRangeMap; RenderRegionRangeMap m_regionRangeMap; - bool m_hasValidRegions : 1; bool m_regionsInvalidated : 1; bool m_regionsHaveUniformLogicalWidth : 1; bool m_regionsHaveUniformLogicalHeight : 1; diff --git a/Source/WebCore/rendering/RenderFrameSet.cpp b/Source/WebCore/rendering/RenderFrameSet.cpp index e6df40b9a..4086cdc67 100644 --- a/Source/WebCore/rendering/RenderFrameSet.cpp +++ b/Source/WebCore/rendering/RenderFrameSet.cpp @@ -699,7 +699,7 @@ bool RenderFrameSet::userResize(MouseEvent* evt) if (needsLayout()) return false; if (evt->type() == eventNames().mousedownEvent && evt->button() == LeftButton) { - FloatPoint localPos = absoluteToLocal(evt->absoluteLocation(), false, true); + FloatPoint localPos = absoluteToLocal(evt->absoluteLocation(), UseTransforms | SnapOffsetForTransforms); startResizing(m_cols, localPos.x()); startResizing(m_rows, localPos.y()); if (m_cols.m_splitBeingResized != noSplit || m_rows.m_splitBeingResized != noSplit) { @@ -709,7 +709,7 @@ bool RenderFrameSet::userResize(MouseEvent* evt) } } else { if (evt->type() == eventNames().mousemoveEvent || (evt->type() == eventNames().mouseupEvent && evt->button() == LeftButton)) { - FloatPoint localPos = absoluteToLocal(evt->absoluteLocation(), false, true); + FloatPoint localPos = absoluteToLocal(evt->absoluteLocation(), UseTransforms | SnapOffsetForTransforms); continueResizing(m_cols, localPos.x()); continueResizing(m_rows, localPos.y()); if (evt->type() == eventNames().mouseupEvent && evt->button() == LeftButton) { diff --git a/Source/WebCore/rendering/RenderGeometryMap.cpp b/Source/WebCore/rendering/RenderGeometryMap.cpp index fe16b9b8e..46d210da5 100644 --- a/Source/WebCore/rendering/RenderGeometryMap.cpp +++ b/Source/WebCore/rendering/RenderGeometryMap.cpp @@ -58,7 +58,7 @@ FloatPoint RenderGeometryMap::absolutePoint(const FloatPoint& p) const } #if !ASSERT_DISABLED - FloatPoint rendererMappedResult = m_mapping.last().m_renderer->localToAbsolute(p, false, true); + FloatPoint rendererMappedResult = m_mapping.last().m_renderer->localToAbsolute(p, UseTransforms | SnapOffsetForTransforms); ASSERT(rendererMappedResult == result); #endif @@ -128,7 +128,7 @@ void RenderGeometryMap::mapToAbsolute(TransformState& transformState) const transformState.flatten(); } -void RenderGeometryMap::pushMappingsToAncestor(const RenderObject* renderer, const RenderBoxModelObject* ancestorRenderer) +void RenderGeometryMap::pushMappingsToAncestor(const RenderObject* renderer, const RenderLayerModelObject* ancestorRenderer) { // We need to push mappings in reverse order here, so do insertions rather than appends. TemporaryChange<size_t> positionChange(m_insertionPosition, m_mapping.size()); @@ -172,7 +172,7 @@ void RenderGeometryMap::pushMappingsToAncestor(const RenderLayer* layer, const R push(renderer, toLayoutSize(layerOffset), /*accumulatingTransform*/ true, /*isNonUniform*/ false, /*isFixedPosition*/ false, /*hasTransform*/ false); return; } - const RenderBoxModelObject* ancestorRenderer = ancestorLayer ? ancestorLayer->renderer() : 0; + const RenderLayerModelObject* ancestorRenderer = ancestorLayer ? ancestorLayer->renderer() : 0; pushMappingsToAncestor(renderer, ancestorRenderer); } @@ -218,7 +218,7 @@ void RenderGeometryMap::pushView(const RenderView* view, const LayoutSize& scrol stepInserted(step); } -void RenderGeometryMap::popMappingsToAncestor(const RenderBoxModelObject* ancestorRenderer) +void RenderGeometryMap::popMappingsToAncestor(const RenderLayerModelObject* ancestorRenderer) { ASSERT(m_mapping.size()); @@ -230,7 +230,7 @@ void RenderGeometryMap::popMappingsToAncestor(const RenderBoxModelObject* ancest void RenderGeometryMap::popMappingsToAncestor(const RenderLayer* ancestorLayer) { - const RenderBoxModelObject* ancestorRenderer = ancestorLayer ? ancestorLayer->renderer() : 0; + const RenderLayerModelObject* ancestorRenderer = ancestorLayer ? ancestorLayer->renderer() : 0; popMappingsToAncestor(ancestorRenderer); } diff --git a/Source/WebCore/rendering/RenderGeometryMap.h b/Source/WebCore/rendering/RenderGeometryMap.h index 495d0bf22..dffc5026f 100644 --- a/Source/WebCore/rendering/RenderGeometryMap.h +++ b/Source/WebCore/rendering/RenderGeometryMap.h @@ -35,8 +35,8 @@ namespace WebCore { -class RenderBoxModelObject; class RenderLayer; +class RenderLayerModelObject; class RenderObject; class RenderView; class TransformState; @@ -83,8 +83,8 @@ public: // Called by code walking the renderer or layer trees. void pushMappingsToAncestor(const RenderLayer*, const RenderLayer* ancestorLayer); void popMappingsToAncestor(const RenderLayer*); - void pushMappingsToAncestor(const RenderObject*, const RenderBoxModelObject* ancestorRenderer); - void popMappingsToAncestor(const RenderBoxModelObject*); + void pushMappingsToAncestor(const RenderObject*, const RenderLayerModelObject* ancestorRenderer); + void popMappingsToAncestor(const RenderLayerModelObject*); // The following methods should only be called by renderers inside a call to pushMappingsToAncestor(). diff --git a/Source/WebCore/rendering/RenderImage.cpp b/Source/WebCore/rendering/RenderImage.cpp index 404025f6e..e94fa3ebd 100644 --- a/Source/WebCore/rendering/RenderImage.cpp +++ b/Source/WebCore/rendering/RenderImage.cpp @@ -173,7 +173,7 @@ void RenderImage::imageChanged(WrappedImagePtr newImage, const IntRect* rect) // Set image dimensions, taking into account the size of the alt text. if (m_imageResource->errorOccurred()) { - if (!m_altText.isEmpty() && document()->isPendingStyleRecalc()) { + if (!m_altText.isEmpty() && document()->hasPendingStyleRecalc()) { ASSERT(node()); if (node()) { m_needsToSetSizeForAltText = true; @@ -219,22 +219,19 @@ void RenderImage::imageDimensionsChanged(bool imageSizeChanged, const IntRect* r bool shouldRepaint = true; if (intrinsicSizeChanged) { - // lets see if we need to relayout at all.. - LayoutUnit oldwidth = width(); - LayoutUnit oldheight = height(); if (!preferredLogicalWidthsDirty()) setPreferredLogicalWidthsDirty(true); - updateLogicalWidth(); - updateLogicalHeight(); + LogicalExtentComputedValues computedValues; + computeLogicalWidthInRegion(computedValues); + LayoutUnit newWidth = computedValues.m_extent; + computeLogicalHeight(height(), 0, computedValues); + LayoutUnit newHeight = computedValues.m_extent; - if (imageSizeChanged || width() != oldwidth || height() != oldheight) { + if (imageSizeChanged || width() != newWidth || height() != newHeight) { shouldRepaint = false; if (!selfNeedsLayout()) setNeedsLayout(true); } - - setWidth(oldwidth); - setHeight(oldheight); } if (shouldRepaint) { diff --git a/Source/WebCore/rendering/RenderInline.cpp b/Source/WebCore/rendering/RenderInline.cpp index 239aba370..2e2c8276f 100644 --- a/Source/WebCore/rendering/RenderInline.cpp +++ b/Source/WebCore/rendering/RenderInline.cpp @@ -40,6 +40,8 @@ #include "TransformState.h" #include "VisiblePosition.h" +#include <wtf/TemporaryChange.h> + #if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) #include "Frame.h" #endif @@ -118,9 +120,9 @@ RenderInline* RenderInline::inlineElementContinuation() const return toRenderBlock(continuation)->inlineElementContinuation(); } -void RenderInline::updateBoxModelInfoFromStyle() +void RenderInline::updateFromStyle() { - RenderBoxModelObject::updateBoxModelInfoFromStyle(); + RenderBoxModelObject::updateFromStyle(); setInline(true); // Needed for run-ins, since run-in is considered a block display type. @@ -167,11 +169,18 @@ void RenderInline::styleDidChange(StyleDifference diff, const RenderStyle* oldSt // need to pass its style on to anyone else. RenderStyle* newStyle = style(); RenderInline* continuation = inlineElementContinuation(); - for (RenderInline* currCont = continuation; currCont; currCont = currCont->inlineElementContinuation()) { - RenderBoxModelObject* nextCont = currCont->continuation(); - currCont->setContinuation(0); - currCont->setStyle(newStyle); - currCont->setContinuation(nextCont); + { + TemporaryChange<bool> enableAfter(RenderObjectChildList::s_enableUpdateBeforeAfterContent, false); + RenderInline* nextInlineElementCont = 0; + for (RenderInline* currCont = continuation; currCont; currCont = nextInlineElementCont) { + nextInlineElementCont = currCont->inlineElementContinuation(); + // We need to update :after content for the last continuation in the chain. + RenderObjectChildList::s_enableUpdateBeforeAfterContent = !nextInlineElementCont; + RenderBoxModelObject* nextCont = currCont->continuation(); + currCont->setContinuation(0); + currCont->setStyle(newStyle); + currCont->setContinuation(nextCont); + } } // If an inline's in-flow positioning has changed then any descendant blocks will need to change their in-flow positioning accordingly. @@ -960,7 +969,7 @@ LayoutRect RenderInline::linesVisualOverflowBoundingBox() const return rect; } -LayoutRect RenderInline::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) const +LayoutRect RenderInline::clippedOverflowRectForRepaint(RenderLayerModelObject* repaintContainer) const { // Only run-ins are allowed in here during layout. ASSERT(!view() || !view()->layoutStateEnabled() || isRunIn()); @@ -1011,7 +1020,7 @@ LayoutRect RenderInline::clippedOverflowRectForRepaint(RenderBoxModelObject* rep return repaintRect; } -LayoutRect RenderInline::rectWithOutlineForRepaint(RenderBoxModelObject* repaintContainer, LayoutUnit outlineWidth) const +LayoutRect RenderInline::rectWithOutlineForRepaint(RenderLayerModelObject* repaintContainer, LayoutUnit outlineWidth) const { LayoutRect r(RenderBoxModelObject::rectWithOutlineForRepaint(repaintContainer, outlineWidth)); for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) { @@ -1021,7 +1030,7 @@ LayoutRect RenderInline::rectWithOutlineForRepaint(RenderBoxModelObject* repaint return r; } -void RenderInline::computeRectForRepaint(RenderBoxModelObject* repaintContainer, LayoutRect& rect, bool fixed) const +void RenderInline::computeRectForRepaint(RenderLayerModelObject* repaintContainer, LayoutRect& rect, bool fixed) const { if (RenderView* v = view()) { // LayoutState is only valid for root-relative repainting @@ -1103,7 +1112,7 @@ LayoutSize RenderInline::offsetFromContainer(RenderObject* container, const Layo return offset; } -void RenderInline::mapLocalToContainer(RenderBoxModelObject* repaintContainer, TransformState& transformState, MapLocalToContainerFlags mode, bool* wasFixed) const +void RenderInline::mapLocalToContainer(RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags mode, bool* wasFixed) const { if (repaintContainer == this) return; @@ -1155,7 +1164,7 @@ void RenderInline::mapLocalToContainer(RenderBoxModelObject* repaintContainer, T o->mapLocalToContainer(repaintContainer, transformState, mode, wasFixed); } -const RenderObject* RenderInline::pushMappingToContainer(const RenderBoxModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const +const RenderObject* RenderInline::pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const { ASSERT(ancestorToStopAt != this); @@ -1526,12 +1535,13 @@ void RenderInline::paintOutlineForLine(GraphicsContext* graphicsContext, const L } #if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) -void RenderInline::addDashboardRegions(Vector<DashboardRegionValue>& regions) +void RenderInline::addAnnotatedRegions(Vector<AnnotatedRegionValue>& regions) { // Convert the style regions to absolute coordinates. if (style()->visibility() != VISIBLE) return; +#if ENABLE(DASHBOARD_SUPPORT) const Vector<StyleDashboardRegion>& styleRegions = style()->dashboardRegions(); unsigned i, count = styleRegions.size(); for (i = 0; i < count; i++) { @@ -1541,7 +1551,7 @@ void RenderInline::addDashboardRegions(Vector<DashboardRegionValue>& regions) LayoutUnit w = linesBoundingBox.width(); LayoutUnit h = linesBoundingBox.height(); - DashboardRegionValue region; + AnnotatedRegionValue region; region.label = styleRegion.label; region.bounds = LayoutRect(linesBoundingBox.x() + styleRegion.offset.left().value(), linesBoundingBox.y() + styleRegion.offset.top().value(), @@ -1566,6 +1576,24 @@ void RenderInline::addDashboardRegions(Vector<DashboardRegionValue>& regions) regions.append(region); } +#else // ENABLE(WIDGET_REGION) + if (style()->getDraggableRegionMode() == DraggableRegionNone) + return; + + AnnotatedRegionValue region; + region.draggable = style()->getDraggableRegionMode() == DraggableRegionDrag; + region.bounds = linesBoundingBox(); + + RenderObject* container = containingBlock(); + if (!container) + container = this; + + FloatPoint absPos = container->localToAbsolute(); + region.bounds.setX(absPos.x() + region.bounds.x()); + region.bounds.setY(absPos.y() + region.bounds.y()); + + regions.append(region); +#endif } #endif diff --git a/Source/WebCore/rendering/RenderInline.h b/Source/WebCore/rendering/RenderInline.h index 4a5bb09dc..4df2ad7f5 100644 --- a/Source/WebCore/rendering/RenderInline.h +++ b/Source/WebCore/rendering/RenderInline.h @@ -131,12 +131,12 @@ private: virtual LayoutUnit offsetWidth() const { return linesBoundingBox().width(); } virtual LayoutUnit offsetHeight() const { return linesBoundingBox().height(); } - virtual LayoutRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) const; - virtual LayoutRect rectWithOutlineForRepaint(RenderBoxModelObject* repaintContainer, LayoutUnit outlineWidth) const; - virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, LayoutRect&, bool fixed) const; + virtual LayoutRect clippedOverflowRectForRepaint(RenderLayerModelObject* repaintContainer) const OVERRIDE; + virtual LayoutRect rectWithOutlineForRepaint(RenderLayerModelObject* repaintContainer, LayoutUnit outlineWidth) const OVERRIDE; + virtual void computeRectForRepaint(RenderLayerModelObject* repaintContainer, LayoutRect&, bool fixed) const OVERRIDE; - virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, TransformState&, MapLocalToContainerFlags mode = ApplyContainerFlip | SnapOffsetForTransforms, bool* wasFixed = 0) const OVERRIDE; - virtual const RenderObject* pushMappingToContainer(const RenderBoxModelObject* ancestorToStopAt, RenderGeometryMap&) const; + virtual void mapLocalToContainer(RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip | SnapOffsetForTransforms, bool* wasFixed = 0) const OVERRIDE; + virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const OVERRIDE; virtual VisiblePosition positionForPoint(const LayoutPoint&); @@ -162,10 +162,10 @@ private: virtual void imageChanged(WrappedImagePtr, const IntRect* = 0); #if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) - virtual void addDashboardRegions(Vector<DashboardRegionValue>&); + virtual void addAnnotatedRegions(Vector<AnnotatedRegionValue>&); #endif - virtual void updateBoxModelInfoFromStyle(); + virtual void updateFromStyle() OVERRIDE; RenderInline* clone() const; diff --git a/Source/WebCore/rendering/RenderLayer.cpp b/Source/WebCore/rendering/RenderLayer.cpp index 75986335e..1e6a37995 100644 --- a/Source/WebCore/rendering/RenderLayer.cpp +++ b/Source/WebCore/rendering/RenderLayer.cpp @@ -80,6 +80,7 @@ #include "RenderInline.h" #include "RenderMarquee.h" #include "RenderReplica.h" +#include "RenderSVGResourceClipper.h" #include "RenderScrollbar.h" #include "RenderScrollbarPart.h" #include "RenderTheme.h" @@ -109,9 +110,7 @@ #include "SVGNames.h" #endif -#if PLATFORM(CHROMIUM) || PLATFORM(BLACKBERRY) -// FIXME: border radius clipping triggers too-slow path on Chromium -// https://bugs.webkit.org/show_bug.cgi?id=69866 +#if PLATFORM(BLACKBERRY) #define DISABLE_ROUNDED_CORNER_CLIPPING #endif @@ -131,7 +130,7 @@ bool ClipRect::intersects(const HitTestLocation& hitTestLocation) return hitTestLocation.intersects(m_rect); } -RenderLayer::RenderLayer(RenderBoxModelObject* renderer) +RenderLayer::RenderLayer(RenderLayerModelObject* renderer) : m_inResizeMode(false) , m_scrollDimensionsDirty(true) , m_normalFlowListDirty(true) @@ -392,7 +391,7 @@ void RenderLayer::updateLayerPositions(LayoutPoint* offsetFromRoot, UpdateLayerP // LayoutState outside the layout() phase and use it here. ASSERT(!view->layoutStateEnabled()); - RenderBoxModelObject* repaintContainer = renderer()->containerForRepaint(); + RenderLayerModelObject* repaintContainer = renderer()->containerForRepaint(); LayoutRect oldRepaintRect = m_repaintRect; LayoutRect oldOutlineBox = m_outlineBox; computeRepaintRects(offsetFromRoot); @@ -489,7 +488,7 @@ void RenderLayer::computeRepaintRects(LayoutPoint* offsetFromRoot) { ASSERT(!m_visibleContentStatusDirty); - RenderBoxModelObject* repaintContainer = renderer()->containerForRepaint(); + RenderLayerModelObject* repaintContainer = renderer()->containerForRepaint(); m_repaintRect = renderer()->clippedOverflowRectForRepaint(repaintContainer); m_outlineBox = renderer()->outlineBoundsForRepaint(repaintContainer, offsetFromRoot); } @@ -630,10 +629,10 @@ TransformationMatrix RenderLayer::renderableTransform(PaintBehavior paintBehavio return *m_transform; } -static bool checkContainingBlockChainForPagination(RenderBoxModelObject* renderer, RenderBox* ancestorColumnsRenderer) +static bool checkContainingBlockChainForPagination(RenderLayerModelObject* renderer, RenderBox* ancestorColumnsRenderer) { RenderView* view = renderer->view(); - RenderBoxModelObject* prevBlock = renderer; + RenderLayerModelObject* prevBlock = renderer; RenderBlock* containingBlock; for (containingBlock = renderer->containingBlock(); containingBlock && containingBlock != view && containingBlock != ancestorColumnsRenderer; @@ -894,7 +893,7 @@ void RenderLayer::updateLayerPosition() } if (renderer()->isInFlowPositioned()) { - m_offsetForInFlowPosition = renderer()->offsetForInFlowPosition(); + m_offsetForInFlowPosition = toRenderBoxModelObject(renderer())->offsetForInFlowPosition(); localPoint.move(m_offsetForInFlowPosition); } else { m_offsetForInFlowPosition = LayoutSize(); @@ -957,7 +956,7 @@ RenderLayer* RenderLayer::stackingContext() const static inline bool isPositionedContainer(RenderLayer* layer) { - RenderBoxModelObject* layerRenderer = layer->renderer(); + RenderLayerModelObject* layerRenderer = layer->renderer(); return layer->isRootLayer() || layerRenderer->isPositioned() || layer->hasTransform(); } @@ -1135,7 +1134,7 @@ void RenderLayer::setFilterBackendNeedsRepaintingInRect(const LayoutRect& rect, bool RenderLayer::hasAncestorWithFilterOutsets() const { for (const RenderLayer* curr = this; curr; curr = curr->parent()) { - RenderBoxModelObject* renderer = curr->renderer(); + RenderLayerModelObject* renderer = curr->renderer(); if (renderer->style()->hasFilterOutsets()) return true; } @@ -1172,7 +1171,7 @@ RenderLayer* RenderLayer::clippingRootForPainting() const LayoutPoint RenderLayer::absoluteToContents(const LayoutPoint& absolutePoint) const { // We don't use convertToLayerCoords because it doesn't know about transforms - return roundedLayoutPoint(renderer()->absoluteToLocal(absolutePoint, false, true)); + return roundedLayoutPoint(renderer()->absoluteToLocal(absolutePoint, UseTransforms | SnapOffsetForTransforms)); } bool RenderLayer::cannotBlitToWindow() const @@ -1481,7 +1480,7 @@ void RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutP if (position == FixedPosition && !renderer()->inRenderFlowThread() && (!ancestorLayer || ancestorLayer == renderer()->view()->layer())) { // If the fixed layer's container is the root, just add in the offset of the view. We can obtain this by calling // localToAbsolute() on the RenderView. - FloatPoint absPos = renderer()->localToAbsolute(FloatPoint(), true); + FloatPoint absPos = renderer()->localToAbsolute(FloatPoint(), IsFixed); location += LayoutSize(absPos.x(), absPos.y()); return; } @@ -1718,10 +1717,9 @@ void RenderLayer::scrollTo(int x, int y) // We should have a RenderView if we're trying to scroll. ASSERT(view); if (view) { + // Update regions, scrolling may change the clip of a particular region. #if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) - // Update dashboard regions, scrolling may change the clip of a - // particular region. - view->frameView()->updateDashboardRegions(); + view->frameView()->updateAnnotatedRegions(); #endif view->updateWidgetPositions(); @@ -1735,7 +1733,7 @@ void RenderLayer::scrollTo(int x, int y) updateCompositingLayersAfterScroll(); } - RenderBoxModelObject* repaintContainer = renderer()->containerForRepaint(); + RenderLayerModelObject* repaintContainer = renderer()->containerForRepaint(); Frame* frame = renderer()->frame(); if (frame) { // The caret rect needs to be invalidated after scrolling @@ -1743,7 +1741,7 @@ void RenderLayer::scrollTo(int x, int y) FloatQuad quadForFakeMouseMoveEvent = FloatQuad(m_repaintRect); if (repaintContainer) - quadForFakeMouseMoveEvent = repaintContainer->localToAbsoluteQuad(quadForFakeMouseMoveEvent); + quadForFakeMouseMoveEvent = repaintContainer->localToAbsoluteQuad(quadForFakeMouseMoveEvent, SnapOffsetForTransforms); frame->eventHandler()->dispatchFakeMouseMoveEventSoonInQuad(quadForFakeMouseMoveEvent); } @@ -1756,6 +1754,21 @@ void RenderLayer::scrollTo(int x, int y) renderer()->node()->document()->eventQueue()->enqueueOrDispatchScrollEvent(renderer()->node(), DocumentEventQueue::ScrollEventElementTarget); } +static inline bool frameElementAndViewPermitScroll(HTMLFrameElement* frameElement, FrameView* frameView) +{ + // If scrollbars aren't explicitly forbidden, permit scrolling. + if (frameElement && frameElement->scrollingMode() != ScrollbarAlwaysOff) + return true; + + // If scrollbars are forbidden, user initiated scrolls should obviously be ignored. + if (frameView->wasScrolledByUser()) + return false; + + // Forbid autoscrolls when scrollbars are off, but permits other programmatic scrolls, + // like navigation to an anchor. + return !frameView->frame()->eventHandler()->autoscrollInProgress(); +} + void RenderLayer::scrollRectToVisible(const LayoutRect& rect, const ScrollAlignment& alignX, const ScrollAlignment& alignY) { RenderLayer* parentLayer = 0; @@ -1806,7 +1819,7 @@ void RenderLayer::scrollRectToVisible(const LayoutRect& rect, const ScrollAlignm if (ownerElement->hasTagName(frameTag) || ownerElement->hasTagName(iframeTag)) frameElement = static_cast<HTMLFrameElement*>(ownerElement); - if (frameElement && frameElement->scrollingMode() != ScrollbarAlwaysOff) { + if (frameElementAndViewPermitScroll(frameElement, frameView)) { LayoutRect viewRect = frameView->visibleContentRect(); LayoutRect exposeRect = getRectToExpose(viewRect, rect, alignX, alignY); @@ -2378,10 +2391,10 @@ void RenderLayer::setHasHorizontalScrollbar(bool hasScrollbar) if (m_vBar) m_vBar->styleChanged(); -#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) // Force an update since we know the scrollbars have changed things. - if (renderer()->document()->hasDashboardRegions()) - renderer()->document()->setDashboardRegionsDirty(true); +#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) + if (renderer()->document()->hasAnnotatedRegions()) + renderer()->document()->setAnnotatedRegionsDirty(true); #endif } @@ -2401,10 +2414,10 @@ void RenderLayer::setHasVerticalScrollbar(bool hasScrollbar) if (m_vBar) m_vBar->styleChanged(); -#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) // Force an update since we know the scrollbars have changed things. - if (renderer()->document()->hasDashboardRegions()) - renderer()->document()->setDashboardRegionsDirty(true); +#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) + if (renderer()->document()->hasAnnotatedRegions()) + renderer()->document()->setAnnotatedRegionsDirty(true); #endif } @@ -2591,10 +2604,10 @@ void RenderLayer::updateScrollbarsAfterLayout() updateSelfPaintingLayer(); -#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) // Force an update since we know the scrollbars have changed things. - if (renderer()->document()->hasDashboardRegions()) - renderer()->document()->setDashboardRegionsDirty(true); +#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) + if (renderer()->document()->hasAnnotatedRegions()) + renderer()->document()->setAnnotatedRegionsDirty(true); #endif renderer()->repaint(); @@ -2629,7 +2642,7 @@ void RenderLayer::updateScrollbarsAfterLayout() m_vBar->setProportion(clientHeight, m_scrollSize.height()); } - updateScrollableAreaSet((hasHorizontalOverflow || hasVerticalOverflow) && scrollsOverflow()); + updateScrollableAreaSet((hasHorizontalOverflow || hasVerticalOverflow) && scrollsOverflow() && allowsScrolling()); } void RenderLayer::updateScrollInfoAfterLayout() @@ -2890,7 +2903,7 @@ void RenderLayer::paint(GraphicsContext* context, const LayoutRect& damageRect, paintLayer(this, context, enclosingIntRect(damageRect), LayoutSize(), paintBehavior, paintingRoot, region, &overlapTestRequests, paintFlags); OverlapTestRequestMap::iterator end = overlapTestRequests.end(); for (OverlapTestRequestMap::iterator it = overlapTestRequests.begin(); it != end; ++it) - it->first->setOverlapTestResult(false); + it->key->setOverlapTestResult(false); } void RenderLayer::paintOverlayScrollbars(GraphicsContext* context, const LayoutRect& damageRect, PaintBehavior paintBehavior, RenderObject* paintingRoot) @@ -2959,11 +2972,11 @@ static void performOverlapTests(OverlapTestRequestMap& overlapTestRequests, cons OverlapTestRequestMap::iterator end = overlapTestRequests.end(); LayoutRect boundingBox = layer->boundingBox(rootLayer); for (OverlapTestRequestMap::iterator it = overlapTestRequests.begin(); it != end; ++it) { - if (!boundingBox.intersects(it->second)) + if (!boundingBox.intersects(it->value)) continue; - it->first->setOverlapTestResult(true); - overlappedRequestClients.append(it->first); + it->key->setOverlapTestResult(true); + overlappedRequestClients.append(it->key); } for (size_t i = 0; i < overlappedRequestClients.size(); ++i) overlapTestRequests.remove(overlappedRequestClients[i]); @@ -3140,6 +3153,16 @@ void RenderLayer::paintLayerContents(RenderLayer* rootLayer, GraphicsContext* co ShapeClipPathOperation* clipPath = static_cast<ShapeClipPathOperation*>(style->clipPath()); context->clipPath(clipPath->path(calculateLayerBounds(this, rootLayer, 0)), clipPath->windRule()); } +#if ENABLE(SVG) + else if (style->clipPath()->getOperationType() == ClipPathOperation::REFERENCE) { + ReferenceClipPathOperation* referenceClipPathOperation = static_cast<ReferenceClipPathOperation*>(style->clipPath()); + Document* document = renderer()->document(); + // FIXME: It doesn't work with forward or external SVG references (https://bugs.webkit.org/show_bug.cgi?id=90405) + Element* clipPath = document ? document->getElementById(referenceClipPathOperation->fragment()) : 0; + if (clipPath && clipPath->renderer() && clipPath->renderer()->isSVGResourceContainer()) + static_cast<RenderSVGResourceClipper*>(clipPath->renderer())->applyClippingToContext(renderer(), calculateLayerBounds(this, rootLayer, 0), paintDirtyRect, context); + } +#endif } #if ENABLE(CSS_FILTERS) @@ -3177,6 +3200,8 @@ void RenderLayer::paintLayerContents(RenderLayer* rootLayer, GraphicsContext* co calculateRects(rootLayer, region, (localPaintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects, paintDirtyRect, layerBounds, damageRect, clipRectToApply, outlineRect, IgnoreOverlayScrollbarSize, localPaintFlags & PaintLayerPaintingOverflowContents ? IgnoreOverflowClip : RespectOverflowClip); paintOffset = toPoint(layerBounds.location() - renderBoxLocation() + subPixelAccumulation); + if (this == rootLayer) + paintOffset = roundedIntPoint(paintOffset); } bool forceBlackText = paintBehavior & PaintBehaviorForceBlackText; @@ -4017,7 +4042,7 @@ void RenderLayer::calculateClipRects(const RenderLayer* rootLayer, RenderRegion* // some transformed layer boundary, for example, in the RenderLayerCompositor overlapMap, where // clipRects are needed in view space. LayoutPoint offset; - offset = roundedLayoutPoint(renderer()->localToContainerPoint(FloatPoint(), rootLayer->renderer(), false, false, 0)); + offset = roundedLayoutPoint(renderer()->localToContainerPoint(FloatPoint(), rootLayer->renderer())); RenderView* view = renderer()->view(); ASSERT(view); if (view && clipRects.fixed() && rootLayer->renderer() == view) { @@ -4144,7 +4169,7 @@ LayoutRect RenderLayer::childrenClipRect() const ClipRect backgroundRect, foregroundRect, outlineRect; // Need to use temporary clip rects, because the value of 'dontClipToOverflow' may be different from the painting path (<rdar://problem/11844909>). calculateRects(clippingRootLayer, 0, TemporaryClipRects, renderView->unscaledDocumentRect(), layerBounds, backgroundRect, foregroundRect, outlineRect); - return clippingRootLayer->renderer()->localToAbsoluteQuad(FloatQuad(foregroundRect.rect())).enclosingBoundingBox(); + return clippingRootLayer->renderer()->localToAbsoluteQuad(FloatQuad(foregroundRect.rect()), SnapOffsetForTransforms).enclosingBoundingBox(); } LayoutRect RenderLayer::selfClipRect() const @@ -4156,7 +4181,7 @@ LayoutRect RenderLayer::selfClipRect() const LayoutRect layerBounds; ClipRect backgroundRect, foregroundRect, outlineRect; calculateRects(clippingRootLayer, 0, PaintingClipRects, renderView->documentRect(), layerBounds, backgroundRect, foregroundRect, outlineRect); - return clippingRootLayer->renderer()->localToAbsoluteQuad(FloatQuad(backgroundRect.rect())).enclosingBoundingBox(); + return clippingRootLayer->renderer()->localToAbsoluteQuad(FloatQuad(backgroundRect.rect()), SnapOffsetForTransforms).enclosingBoundingBox(); } LayoutRect RenderLayer::localClipRect() const @@ -4704,7 +4729,7 @@ void RenderLayer::setBackingNeedsRepaintInRect(const LayoutRect& r) } // Since we're only painting non-composited layers, we know that they all share the same repaintContainer. -void RenderLayer::repaintIncludingNonCompositingDescendants(RenderBoxModelObject* repaintContainer) +void RenderLayer::repaintIncludingNonCompositingDescendants(RenderLayerModelObject* repaintContainer) { renderer()->repaintUsingContainer(repaintContainer, pixelSnappedIntRect(renderer()->clippedOverflowRectForRepaint(repaintContainer))); @@ -4835,7 +4860,7 @@ void RenderLayer::updateScrollbarsAfterStyleChange(const RenderStyle* oldStyle) } if (!m_scrollDimensionsDirty) - updateScrollableAreaSet((hasHorizontalOverflow() || hasVerticalOverflow()) && scrollsOverflow()); + updateScrollableAreaSet((hasHorizontalOverflow() || hasVerticalOverflow()) && scrollsOverflow() && allowsScrolling()); } void RenderLayer::styleChanged(StyleDifference, const RenderStyle* oldStyle) @@ -4882,10 +4907,6 @@ void RenderLayer::styleChanged(StyleDifference, const RenderStyle* oldStyle) updateScrollCornerStyle(); updateResizerStyle(); -#if ENABLE(CSS_FILTERS) - bool backingDidCompositeLayers = isComposited() && backing()->canCompositeFilters(); -#endif - updateDescendantDependentFlags(); updateTransform(); #if ENABLE(CSS_COMPOSITING) @@ -4907,12 +4928,15 @@ void RenderLayer::styleChanged(StyleDifference, const RenderStyle* oldStyle) #if ENABLE(CSS_FILTERS) updateOrRemoveFilterEffect(); +#if USE(ACCELERATED_COMPOSITING) + bool backingDidCompositeLayers = isComposited() && backing()->canCompositeFilters(); if (isComposited() && backingDidCompositeLayers && !backing()->canCompositeFilters()) { // The filters used to be drawn by platform code, but now the platform cannot draw them anymore. // Fallback to drawing them in software. setBackingNeedsRepaint(); } #endif +#endif } void RenderLayer::updateScrollableAreaSet(bool hasOverflow) diff --git a/Source/WebCore/rendering/RenderLayer.h b/Source/WebCore/rendering/RenderLayer.h index 970b1643e..c3db96d1d 100644 --- a/Source/WebCore/rendering/RenderLayer.h +++ b/Source/WebCore/rendering/RenderLayer.h @@ -251,10 +251,10 @@ class RenderLayer : public ScrollableArea { public: friend class RenderReplica; - RenderLayer(RenderBoxModelObject*); + RenderLayer(RenderLayerModelObject*); ~RenderLayer(); - RenderBoxModelObject* renderer() const { return m_renderer; } + RenderLayerModelObject* renderer() const { return m_renderer; } RenderBox* renderBox() const { return m_renderer && m_renderer->isBox() ? toRenderBox(m_renderer) : 0; } RenderLayer* parent() const { return m_parent; } RenderLayer* previousSibling() const { return m_previous; } @@ -275,7 +275,7 @@ public: // if layer compositing is being used, void setBackingNeedsRepaint(); void setBackingNeedsRepaintInRect(const LayoutRect&); // r is in the coordinate space of the layer's render object - void repaintIncludingNonCompositingDescendants(RenderBoxModelObject* repaintContainer); + void repaintIncludingNonCompositingDescendants(RenderLayerModelObject* repaintContainer); #endif void styleChanged(StyleDifference, const RenderStyle* oldStyle); @@ -882,7 +882,7 @@ private: friend class RenderLayerBacking; friend class RenderLayerCompositor; - friend class RenderBoxModelObject; + friend class RenderLayerModelObject; // Only safe to call from RenderBoxModelObject::destroyLayer(RenderArena*) void destroy(RenderArena*); @@ -956,7 +956,7 @@ protected: BlendMode m_blendMode; #endif - RenderBoxModelObject* m_renderer; + RenderLayerModelObject* m_renderer; RenderLayer* m_parent; RenderLayer* m_previous; diff --git a/Source/WebCore/rendering/RenderLayerBacking.cpp b/Source/WebCore/rendering/RenderLayerBacking.cpp index 459e95148..173d4c6dc 100644 --- a/Source/WebCore/rendering/RenderLayerBacking.cpp +++ b/Source/WebCore/rendering/RenderLayerBacking.cpp @@ -95,6 +95,7 @@ bool RenderLayerBacking::m_creatingPrimaryGraphicsLayer = false; RenderLayerBacking::RenderLayerBacking(RenderLayer* layer) : m_owningLayer(layer) + , m_scrollLayerID(0) , m_artificiallyInflatedBounds(false) , m_isMainFrameRenderViewLayer(false) , m_usingTiledCacheLayer(false) @@ -123,9 +124,8 @@ RenderLayerBacking::RenderLayerBacking(RenderLayer* layer) if (Page* page = renderer()->frame()->page()) { if (TiledBacking* tiledBacking = m_graphicsLayer->tiledBacking()) { Frame* frame = renderer()->frame(); - tiledBacking->setIsInWindow(page->isOnscreen()); - tiledBacking->setCanHaveScrollbars(frame->view()->canHaveScrollbars()); + tiledBacking->setTileCoverage(frame->view()->canHaveScrollbars() ? TiledBacking::CoverageForScrolling : TiledBacking::CoverageForVisibleArea); tiledBacking->setScrollingPerformanceLoggingEnabled(frame->settings() && frame->settings()->scrollingPerformanceLoggingEnabled()); } } @@ -139,12 +139,18 @@ RenderLayerBacking::~RenderLayerBacking() updateForegroundLayer(false); updateMaskLayer(false); updateScrollingLayers(false); + detachFromScrollingCoordinator(); destroyGraphicsLayers(); } PassOwnPtr<GraphicsLayer> RenderLayerBacking::createGraphicsLayer(const String& name) { - OwnPtr<GraphicsLayer> graphicsLayer = GraphicsLayer::create(this); + GraphicsLayerFactory* graphicsLayerFactory = 0; + if (Page* page = renderer()->frame()->page()) + graphicsLayerFactory = page->chrome()->client()->graphicsLayerFactory(); + + OwnPtr<GraphicsLayer> graphicsLayer = GraphicsLayer::create(graphicsLayerFactory, this); + #ifndef NDEBUG graphicsLayer->setName(name); #else @@ -959,6 +965,41 @@ bool RenderLayerBacking::updateScrollingLayers(bool needsScrollingLayers) return layerChanged; } +void RenderLayerBacking::attachToScrollingCoordinator() +{ + // If m_scrollLayerID non-zero, then this backing is already attached to the ScrollingCoordinator. + if (m_scrollLayerID) + return; + + Page* page = renderer()->frame()->page(); + if (!page) + return; + + ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator(); + if (!scrollingCoordinator) + return; + + m_scrollLayerID = scrollingCoordinator->attachToStateTree(scrollingCoordinator->uniqueScrollLayerID()); +} + +void RenderLayerBacking::detachFromScrollingCoordinator() +{ + // If m_scrollLayerID is 0, then this backing is not attached to the ScrollingCoordinator. + if (!m_scrollLayerID) + return; + + Page* page = renderer()->frame()->page(); + if (!page) + return; + + ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator(); + if (!scrollingCoordinator) + return; + + scrollingCoordinator->detachFromStateTree(m_scrollLayerID); + m_scrollLayerID = 0; +} + GraphicsLayerPaintingPhase RenderLayerBacking::paintingPhaseForPrimaryLayer() const { unsigned phase = GraphicsLayerPaintBackground; @@ -1672,7 +1713,7 @@ void RenderLayerBacking::notifyAnimationStarted(const GraphicsLayer*, double tim renderer()->animation()->notifyAnimationStarted(renderer(), time); } -void RenderLayerBacking::notifySyncRequired(const GraphicsLayer*) +void RenderLayerBacking::notifyFlushRequired(const GraphicsLayer*) { if (!renderer()->documentBeingDestroyed()) compositor()->scheduleLayerFlush(); @@ -1824,7 +1865,7 @@ bool RenderLayerBacking::contentsVisible(const GraphicsLayer*, const IntRect& lo return false; IntRect visibleContentRect(view->visibleContentRect()); - FloatQuad absoluteContentQuad = renderer()->localToAbsoluteQuad(FloatRect(localContentRect)); + FloatQuad absoluteContentQuad = renderer()->localToAbsoluteQuad(FloatRect(localContentRect), SnapOffsetForTransforms); return absoluteContentQuad.enclosingBoundingBox().intersects(visibleContentRect); } #endif diff --git a/Source/WebCore/rendering/RenderLayerBacking.h b/Source/WebCore/rendering/RenderLayerBacking.h index 78232709f..c04146551 100644 --- a/Source/WebCore/rendering/RenderLayerBacking.h +++ b/Source/WebCore/rendering/RenderLayerBacking.h @@ -87,6 +87,9 @@ public: bool hasScrollingLayer() const { return m_scrollingLayer; } GraphicsLayer* scrollingLayer() const { return m_scrollingLayer.get(); } GraphicsLayer* scrollingContentsLayer() const { return m_scrollingContentsLayer.get(); } + + void attachToScrollingCoordinator(); + uint64_t scrollLayerID() const { return m_scrollLayerID; } bool hasMaskLayer() const { return m_maskLayer != 0; } @@ -133,11 +136,12 @@ public: void updateAfterWidgetResize(); void positionOverflowControlsLayers(const IntSize& offsetFromRoot); + bool usingTileCache() const { return m_usingTiledCacheLayer; } + // GraphicsLayerClient interface virtual bool shouldUseTileCache(const GraphicsLayer*) const; - virtual bool usingTileCache(const GraphicsLayer*) const { return m_usingTiledCacheLayer; } virtual void notifyAnimationStarted(const GraphicsLayer*, double startTime); - virtual void notifySyncRequired(const GraphicsLayer*); + virtual void notifyFlushRequired(const GraphicsLayer*); virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect& clip); @@ -180,7 +184,7 @@ private: PassOwnPtr<GraphicsLayer> createGraphicsLayer(const String&); - RenderBoxModelObject* renderer() const { return m_owningLayer->renderer(); } + RenderLayerModelObject* renderer() const { return m_owningLayer->renderer(); } RenderLayerCompositor* compositor() const { return m_owningLayer->compositor(); } void updateInternalHierarchy(); @@ -193,6 +197,8 @@ private: bool requiresScrollCornerLayer() const; bool updateScrollingLayers(bool scrollingLayers); + void detachFromScrollingCoordinator(); + GraphicsLayerPaintingPhase paintingPhaseForPrimaryLayer() const; IntSize contentOffsetInCompostingLayer() const; @@ -256,6 +262,8 @@ private: OwnPtr<GraphicsLayer> m_scrollingLayer; // only used if the layer is using composited scrolling. OwnPtr<GraphicsLayer> m_scrollingContentsLayer; // only used if the layer is using composited scrolling. + uint64_t m_scrollLayerID; + IntRect m_compositedBounds; bool m_artificiallyInflatedBounds; // bounds had to be made non-zero to make transform-origin work diff --git a/Source/WebCore/rendering/RenderLayerCompositor.cpp b/Source/WebCore/rendering/RenderLayerCompositor.cpp index f967233ef..8ac3736f4 100644 --- a/Source/WebCore/rendering/RenderLayerCompositor.cpp +++ b/Source/WebCore/rendering/RenderLayerCompositor.cpp @@ -277,13 +277,13 @@ void RenderLayerCompositor::scheduleLayerFlush() if (!page) return; - page->chrome()->client()->scheduleCompositingLayerSync(); + page->chrome()->client()->scheduleCompositingLayerFlush(); } void RenderLayerCompositor::flushPendingLayerChanges(bool isFlushRoot) { - // FrameView::syncCompositingStateIncludingSubframes() flushes each subframe, - // but GraphicsLayer::syncCompositingState() will cross frame boundaries + // FrameView::flushCompositingStateIncludingSubframes() flushes each subframe, + // but GraphicsLayer::flushCompositingState() will cross frame boundaries // if the GraphicsLayers are connected (the RootLayerAttachedViaEnclosingFrame case). // As long as we're not the root of the flush, we can bail. if (!isFlushRoot && rootLayerAttachment() == RootLayerAttachedViaEnclosingFrame) @@ -297,7 +297,7 @@ void RenderLayerCompositor::flushPendingLayerChanges(bool isFlushRoot) if (frameView) { // FIXME: Passing frameRect() is correct only when RenderLayerCompositor uses a ScrollLayer (as in WebKit2) // otherwise, the passed clip rect needs to take scrolling into account - rootLayer->syncCompositingState(frameView->frameRect()); + rootLayer->flushCompositingState(frameView->frameRect()); } } @@ -494,6 +494,13 @@ bool RenderLayerCompositor::updateBacking(RenderLayer* layer, CompositingChangeR layer->ensureBacking(); + // At this time, the ScrollingCooridnator only supports the top-level frame. + if (layer->isRootLayer() && !m_renderView->document()->ownerElement()) { + layer->backing()->attachToScrollingCoordinator(); + if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) + scrollingCoordinator->frameViewRootLayerDidChange(m_renderView->frameView()); + } + // This layer and all of its descendants have cached repaints rects that are relative to // the repaint container, so change when compositing changes; we need to update them here. if (layer->parent()) @@ -507,7 +514,7 @@ bool RenderLayerCompositor::updateBacking(RenderLayer* layer, CompositingChangeR // its replica GraphicsLayer. In practice this should never happen because reflectee and reflection // are both either composited, or not composited. if (layer->isReflection()) { - RenderLayer* sourceLayer = toRenderBoxModelObject(layer->renderer()->parent())->layer(); + RenderLayer* sourceLayer = toRenderLayerModelObject(layer->renderer()->parent())->layer(); if (RenderLayerBacking* backing = sourceLayer->backing()) { ASSERT(backing->graphicsLayer()->replicaLayer() == layer->backing()->graphicsLayer()); backing->graphicsLayer()->setReplicatedByLayer(0); @@ -570,7 +577,7 @@ void RenderLayerCompositor::repaintOnCompositingChange(RenderLayer* layer) if (layer->renderer() != m_renderView && !layer->renderer()->parent()) return; - RenderBoxModelObject* repaintContainer = layer->renderer()->containerForRepaint(); + RenderLayerModelObject* repaintContainer = layer->renderer()->containerForRepaint(); if (!repaintContainer) repaintContainer = m_renderView; @@ -1099,16 +1106,24 @@ void RenderLayerCompositor::scrollingLayerDidChange(RenderLayer* layer) scrollingCoordinator->scrollableAreaScrollLayerDidChange(layer, backing ? backing->scrollingContentsLayer() : 0); } -String RenderLayerCompositor::layerTreeAsText(bool showDebugInfo) +String RenderLayerCompositor::layerTreeAsText(LayerTreeFlags flags) { updateCompositingLayers(CompositingUpdateAfterLayout); if (!m_rootContentLayer) return String(); + flushPendingLayerChanges(true); + + LayerTreeAsTextBehavior layerTreeBehavior = LayerTreeAsTextBehaviorNormal; + if (flags & LayerTreeFlagsIncludeDebugInfo) + layerTreeBehavior |= LayerTreeAsTextDebug; + if (flags & LayerTreeFlagsIncludeVisibleRects) + layerTreeBehavior |= LayerTreeAsTextIncludeVisibleRects; + // We skip dumping the scroll and clip layers to keep layerTreeAsText output // similar between platforms. - return m_rootContentLayer->layerTreeAsText(showDebugInfo ? LayerTreeAsTextDebug : LayerTreeAsTextBehaviorNormal); + return m_rootContentLayer->layerTreeAsText(layerTreeBehavior); } RenderLayerCompositor* RenderLayerCompositor::frameContentsCompositor(RenderPart* renderer) @@ -1439,7 +1454,7 @@ bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer* layer) c // The compositing state of a reflection should match that of its reflected layer. if (layer->isReflection()) { renderer = renderer->parent(); // The RenderReplica's parent is the object being reflected. - layer = toRenderBoxModelObject(renderer)->layer(); + layer = toRenderLayerModelObject(renderer)->layer(); } // The root layer always has a compositing layer, but it may not have backing. return requiresCompositingForTransform(renderer) @@ -1508,7 +1523,7 @@ const char* RenderLayerCompositor::reasonForCompositing(const RenderLayer* layer RenderObject* renderer = layer->renderer(); if (layer->isReflection()) { renderer = renderer->parent(); - layer = toRenderBoxModelObject(renderer)->layer(); + layer = toRenderLayerModelObject(renderer)->layer(); } if (requiresCompositingForTransform(renderer)) @@ -1935,13 +1950,10 @@ void RenderLayerCompositor::paintContents(const GraphicsLayer* graphicsLayer, Gr void RenderLayerCompositor::documentBackgroundColorDidChange() { RenderLayerBacking* backing = rootRenderLayer()->backing(); - if (!backing) + if (!backing || !backing->usingTileCache()) return; GraphicsLayer* graphicsLayer = backing->graphicsLayer(); - if (!graphicsLayer->client()->usingTileCache(graphicsLayer)) - return; - Color backgroundColor = m_renderView->frameView()->documentBackgroundColor(); if (!backgroundColor.isValid() || backgroundColor.hasAlpha()) backgroundColor = Color::white; @@ -2074,7 +2086,7 @@ void RenderLayerCompositor::updateOverflowControlsLayers() #if ENABLE(RUBBER_BANDING) if (requiresOverhangAreasLayer()) { if (!m_layerForOverhangAreas) { - m_layerForOverhangAreas = GraphicsLayer::create(this); + m_layerForOverhangAreas = GraphicsLayer::create(graphicsLayerFactory(), this); #ifndef NDEBUG m_layerForOverhangAreas->setName("overhang areas"); #endif @@ -2094,7 +2106,7 @@ void RenderLayerCompositor::updateOverflowControlsLayers() if (requiresContentShadowLayer()) { if (!m_contentShadowLayer) { - m_contentShadowLayer = GraphicsLayer::create(this); + m_contentShadowLayer = GraphicsLayer::create(graphicsLayerFactory(), this); #ifndef NDEBUG m_contentShadowLayer->setName("content shadow"); #endif @@ -2112,7 +2124,7 @@ void RenderLayerCompositor::updateOverflowControlsLayers() if (requiresHorizontalScrollbarLayer()) { if (!m_layerForHorizontalScrollbar) { - m_layerForHorizontalScrollbar = GraphicsLayer::create(this); + m_layerForHorizontalScrollbar = GraphicsLayer::create(graphicsLayerFactory(), this); #ifndef NDEBUG m_layerForHorizontalScrollbar->setName("horizontal scrollbar"); #endif @@ -2134,7 +2146,7 @@ void RenderLayerCompositor::updateOverflowControlsLayers() if (requiresVerticalScrollbarLayer()) { if (!m_layerForVerticalScrollbar) { - m_layerForVerticalScrollbar = GraphicsLayer::create(this); + m_layerForVerticalScrollbar = GraphicsLayer::create(graphicsLayerFactory(), this); #ifndef NDEBUG m_layerForVerticalScrollbar->setName("vertical scrollbar"); #endif @@ -2156,7 +2168,7 @@ void RenderLayerCompositor::updateOverflowControlsLayers() if (requiresScrollCornerLayer()) { if (!m_layerForScrollCorner) { - m_layerForScrollCorner = GraphicsLayer::create(this); + m_layerForScrollCorner = GraphicsLayer::create(graphicsLayerFactory(), this); #ifndef NDEBUG m_layerForScrollCorner->setName("scroll corner"); #endif @@ -2180,7 +2192,7 @@ void RenderLayerCompositor::ensureRootLayer() return; if (!m_rootContentLayer) { - m_rootContentLayer = GraphicsLayer::create(this); + m_rootContentLayer = GraphicsLayer::create(graphicsLayerFactory(), this); #ifndef NDEBUG m_rootContentLayer->setName("content root"); #endif @@ -2198,19 +2210,19 @@ void RenderLayerCompositor::ensureRootLayer() ASSERT(!m_clipLayer); // Create a layer to host the clipping layer and the overflow controls layers. - m_overflowControlsHostLayer = GraphicsLayer::create(this); + m_overflowControlsHostLayer = GraphicsLayer::create(graphicsLayerFactory(), this); #ifndef NDEBUG m_overflowControlsHostLayer->setName("overflow controls host"); #endif // Create a clipping layer if this is an iframe - m_clipLayer = GraphicsLayer::create(this); + m_clipLayer = GraphicsLayer::create(graphicsLayerFactory(), this); #ifndef NDEBUG m_clipLayer->setName("frame clipping"); #endif m_clipLayer->setMasksToBounds(true); - m_scrollLayer = GraphicsLayer::create(this); + m_scrollLayer = GraphicsLayer::create(graphicsLayerFactory(), this); #ifndef NDEBUG m_scrollLayer->setName("frame scrolling"); #endif @@ -2308,9 +2320,6 @@ void RenderLayerCompositor::attachRootLayer(RootLayerAttachment attachment) } } - if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) - scrollingCoordinator->frameViewRootLayerDidChange(m_renderView->frameView()); - m_rootLayerAttachment = attachment; rootLayerAttachmentChanged(); } @@ -2452,6 +2461,16 @@ ScrollingCoordinator* RenderLayerCompositor::scrollingCoordinator() const return 0; } +GraphicsLayerFactory* RenderLayerCompositor::graphicsLayerFactory() const +{ + if (Frame* frame = m_renderView->frameView()->frame()) { + if (Page* page = frame->page()) + return page->chrome()->client()->graphicsLayerFactory(); + } + + return 0; +} + } // namespace WebCore #endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/rendering/RenderLayerCompositor.h b/Source/WebCore/rendering/RenderLayerCompositor.h index 2a7cdd071..386119947 100644 --- a/Source/WebCore/rendering/RenderLayerCompositor.h +++ b/Source/WebCore/rendering/RenderLayerCompositor.h @@ -27,6 +27,7 @@ #define RenderLayerCompositor_h #include "ChromeClient.h" +#include "Frame.h" #include "RenderLayer.h" #include "RenderLayerBacking.h" @@ -195,7 +196,7 @@ public: void scrollingLayerDidChange(RenderLayer*); - String layerTreeAsText(bool showDebugInfo = false); + String layerTreeAsText(LayerTreeFlags); // These are named to avoid conflicts with the functions in GraphicsLayerClient // These return the actual internal variables. @@ -225,7 +226,7 @@ private: // GraphicsLayerClient Implementation virtual void notifyAnimationStarted(const GraphicsLayer*, double) { } - virtual void notifySyncRequired(const GraphicsLayer*) { scheduleLayerFlush(); } + virtual void notifyFlushRequired(const GraphicsLayer*) { scheduleLayerFlush(); } virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect&); virtual bool showDebugBorders(const GraphicsLayer*) const; @@ -283,6 +284,7 @@ private: bool isFlushingLayers() const { return m_flushingLayers; } + GraphicsLayerFactory* graphicsLayerFactory() const; ScrollingCoordinator* scrollingCoordinator() const; // Whether a running transition or animation enforces the need for a compositing layer. diff --git a/Source/WebCore/rendering/RenderLayerFilterInfo.cpp b/Source/WebCore/rendering/RenderLayerFilterInfo.cpp index acbf07d9d..cb4c5d661 100644 --- a/Source/WebCore/rendering/RenderLayerFilterInfo.cpp +++ b/Source/WebCore/rendering/RenderLayerFilterInfo.cpp @@ -56,7 +56,7 @@ RenderLayerFilterInfo* RenderLayerFilterInfo::filterInfoForRenderLayer(const Ren if (!s_filterMap) return 0; RenderLayerFilterInfoMap::iterator iter = s_filterMap->find(layer); - return (iter != s_filterMap->end()) ? iter->second : 0; + return (iter != s_filterMap->end()) ? iter->value : 0; } RenderLayerFilterInfo* RenderLayerFilterInfo::createFilterInfoForRenderLayerIfNeeded(RenderLayer* layer) @@ -67,7 +67,7 @@ RenderLayerFilterInfo* RenderLayerFilterInfo::createFilterInfoForRenderLayerIfNe RenderLayerFilterInfoMap::iterator iter = s_filterMap->find(layer); if (iter != s_filterMap->end()) { ASSERT(layer->hasFilterInfo()); - return iter->second; + return iter->value; } RenderLayerFilterInfo* filter = new RenderLayerFilterInfo(layer); diff --git a/Source/WebCore/rendering/RenderLayerModelObject.cpp b/Source/WebCore/rendering/RenderLayerModelObject.cpp new file mode 100644 index 000000000..aeb32b7a2 --- /dev/null +++ b/Source/WebCore/rendering/RenderLayerModelObject.cpp @@ -0,0 +1,178 @@ +/* + * Copyright (C) 1999 Lars Knoll (knoll@kde.org) + * (C) 1999 Antti Koivisto (koivisto@kde.org) + * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) + * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com) + * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2010, 2012 Google Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "RenderLayerModelObject.h" + +#include "RenderLayer.h" +#include "RenderView.h" + +using namespace std; + +namespace WebCore { + +bool RenderLayerModelObject::s_wasFloating = false; +bool RenderLayerModelObject::s_hadLayer = false; +bool RenderLayerModelObject::s_hadTransform = false; +bool RenderLayerModelObject::s_layerWasSelfPainting = false; + +RenderLayerModelObject::RenderLayerModelObject(Node* node) + : RenderObject(node) + , m_layer(0) +{ +} + +RenderLayerModelObject::~RenderLayerModelObject() +{ + // Our layer should have been destroyed and cleared by now + ASSERT(!hasLayer()); + ASSERT(!m_layer); +} + +void RenderLayerModelObject::destroyLayer() +{ + ASSERT(!hasLayer()); // Callers should have already called setHasLayer(false) + ASSERT(m_layer); + m_layer->destroy(renderArena()); + m_layer = 0; +} + +void RenderLayerModelObject::ensureLayer() +{ + if (m_layer) + return; + + m_layer = new (renderArena()) RenderLayer(this); + setHasLayer(true); + m_layer->insertOnlyThisLayer(); +} + +bool RenderLayerModelObject::hasSelfPaintingLayer() const +{ + return m_layer && m_layer->isSelfPaintingLayer(); +} + +void RenderLayerModelObject::willBeDestroyed() +{ + // RenderObject::willBeDestroyed calls back to destroyLayer() for layer destruction + RenderObject::willBeDestroyed(); +} + +void RenderLayerModelObject::styleWillChange(StyleDifference diff, const RenderStyle* newStyle) +{ + s_wasFloating = isFloating(); + s_hadLayer = hasLayer(); + s_hadTransform = hasTransform(); + if (s_hadLayer) + s_layerWasSelfPainting = layer()->isSelfPaintingLayer(); + + // If our z-index changes value or our visibility changes, + // we need to dirty our stacking context's z-order list. + RenderStyle* oldStyle = style(); + if (oldStyle && newStyle) { + if (parent()) { + // Do a repaint with the old style first, e.g., for example if we go from + // having an outline to not having an outline. + if (diff == StyleDifferenceRepaintLayer) { + layer()->repaintIncludingDescendants(); + if (!(oldStyle->clip() == newStyle->clip())) + layer()->clearClipRectsIncludingDescendants(); + } else if (diff == StyleDifferenceRepaint || newStyle->outlineSize() < oldStyle->outlineSize()) + repaint(); + } + + if (diff == StyleDifferenceLayout || diff == StyleDifferenceSimplifiedLayout) { + // When a layout hint happens, we go ahead and do a repaint of the layer, since the layer could + // end up being destroyed. + if (hasLayer()) { + if (oldStyle->position() != newStyle->position() + || oldStyle->zIndex() != newStyle->zIndex() + || oldStyle->hasAutoZIndex() != newStyle->hasAutoZIndex() + || !(oldStyle->clip() == newStyle->clip()) + || oldStyle->hasClip() != newStyle->hasClip() + || oldStyle->opacity() != newStyle->opacity() + || oldStyle->transform() != newStyle->transform() +#if ENABLE(CSS_FILTERS) + || oldStyle->filter() != newStyle->filter() +#endif + ) + layer()->repaintIncludingDescendants(); + } else if (newStyle->hasTransform() || newStyle->opacity() < 1 || newStyle->hasFilter()) { + // If we don't have a layer yet, but we are going to get one because of transform or opacity, + // then we need to repaint the old position of the object. + repaint(); + } + } + } + + RenderObject::styleWillChange(diff, newStyle); +} + +void RenderLayerModelObject::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) +{ + RenderObject::styleDidChange(diff, oldStyle); + updateFromStyle(); + + if (requiresLayer()) { + if (!layer() && layerCreationAllowedForSubtree()) { + if (s_wasFloating && isFloating()) + setChildNeedsLayout(true); + ensureLayer(); + if (parent() && !needsLayout() && containingBlock()) { + layer()->setRepaintStatus(NeedsFullRepaint); + // There is only one layer to update, it is not worth using |cachedOffset| since + // we are not sure the value will be used. + layer()->updateLayerPositions(0); + } + } + } else if (layer() && layer()->parent()) { + setHasTransform(false); // Either a transform wasn't specified or the object doesn't support transforms, so just null out the bit. + setHasReflection(false); + layer()->removeOnlyThisLayer(); // calls destroyLayer() which clears m_layer + if (s_wasFloating && isFloating()) + setChildNeedsLayout(true); + if (s_hadTransform) + setNeedsLayoutAndPrefWidthsRecalc(); + } + + if (layer()) { + layer()->styleChanged(diff, oldStyle); + if (s_hadLayer && layer()->isSelfPaintingLayer() != s_layerWasSelfPainting) + setChildNeedsLayout(true); + } + + if (FrameView *frameView = view()->frameView()) { + bool newStyleIsViewportConstained = style()->hasViewportConstrainedPosition(); + bool oldStyleIsViewportConstrained = oldStyle && oldStyle->hasViewportConstrainedPosition(); + if (newStyleIsViewportConstained != oldStyleIsViewportConstrained) { + if (newStyleIsViewportConstained && layer()) + frameView->addViewportConstrainedObject(this); + else + frameView->removeViewportConstrainedObject(this); + } + } +} + +} // namespace WebCore + diff --git a/Source/WebCore/rendering/RenderLayerModelObject.h b/Source/WebCore/rendering/RenderLayerModelObject.h new file mode 100644 index 000000000..c6241d377 --- /dev/null +++ b/Source/WebCore/rendering/RenderLayerModelObject.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 1999 Lars Knoll (knoll@kde.org) + * (C) 1999 Antti Koivisto (koivisto@kde.org) + * Copyright (C) 2003, 2006, 2007, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2010, 2012 Google Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef RenderLayerModelObject_h +#define RenderLayerModelObject_h + +#include "RenderObject.h" + +namespace WebCore { + +class RenderLayer; + +class RenderLayerModelObject : public RenderObject { +public: + RenderLayerModelObject(Node*); + virtual ~RenderLayerModelObject(); + + // Called by RenderObject::willBeDestroyed() and is the only way layers should ever be destroyed + void destroyLayer(); + + bool hasSelfPaintingLayer() const; + RenderLayer* layer() const { return m_layer; } + + virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle) OVERRIDE; + virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE; + virtual void updateFromStyle() { } + + virtual bool requiresLayer() const = 0; + +protected: + void ensureLayer(); + + virtual void willBeDestroyed() OVERRIDE; + +private: + virtual bool isLayerModelObject() const OVERRIDE { return true; } + + RenderLayer* m_layer; + + // Used to store state between styleWillChange and styleDidChange + static bool s_wasFloating; + static bool s_hadLayer; + static bool s_hadTransform; + static bool s_layerWasSelfPainting; +}; + +inline RenderLayerModelObject* toRenderLayerModelObject(RenderObject* object) +{ + ASSERT(!object || object->isLayerModelObject()); + return static_cast<RenderLayerModelObject*>(object); +} + +inline const RenderLayerModelObject* toRenderLayerModelObject(const RenderObject* object) +{ + ASSERT(!object || object->isLayerModelObject()); + return static_cast<const RenderLayerModelObject*>(object); +} + +// This will catch anyone doing an unnecessary cast. +void toRenderLayerModelObject(const RenderLayerModelObject*); + +} // namespace WebCore + +#endif // RenderLayerModelObject_h diff --git a/Source/WebCore/rendering/RenderListBox.cpp b/Source/WebCore/rendering/RenderListBox.cpp index 079ce429c..67e2275cb 100644 --- a/Source/WebCore/rendering/RenderListBox.cpp +++ b/Source/WebCore/rendering/RenderListBox.cpp @@ -876,10 +876,10 @@ void RenderListBox::setHasVerticalScrollbar(bool hasScrollbar) if (m_vBar) m_vBar->styleChanged(); -#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) // Force an update since we know the scrollbars have changed things. - if (document()->hasDashboardRegions()) - document()->setDashboardRegionsDirty(true); +#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) + if (document()->hasAnnotatedRegions()) + document()->setAnnotatedRegionsDirty(true); #endif } diff --git a/Source/WebCore/rendering/RenderListMarker.cpp b/Source/WebCore/rendering/RenderListMarker.cpp index b4bc59e9f..a5b0e4cdb 100644 --- a/Source/WebCore/rendering/RenderListMarker.cpp +++ b/Source/WebCore/rendering/RenderListMarker.cpp @@ -1702,7 +1702,7 @@ void RenderListMarker::setSelectionState(SelectionState state) root->setHasSelectedChildren(state != SelectionNone); } -LayoutRect RenderListMarker::selectionRectForRepaint(RenderBoxModelObject* repaintContainer, bool clipToVisibleContent) +LayoutRect RenderListMarker::selectionRectForRepaint(RenderLayerModelObject* repaintContainer, bool clipToVisibleContent) { ASSERT(!needsLayout()); diff --git a/Source/WebCore/rendering/RenderListMarker.h b/Source/WebCore/rendering/RenderListMarker.h index d88d922b0..c1f1d676e 100644 --- a/Source/WebCore/rendering/RenderListMarker.h +++ b/Source/WebCore/rendering/RenderListMarker.h @@ -65,7 +65,7 @@ private: bool isText() const { return !isImage(); } virtual void setSelectionState(SelectionState); - virtual LayoutRect selectionRectForRepaint(RenderBoxModelObject* repaintContainer, bool clipToVisibleContent = true); + virtual LayoutRect selectionRectForRepaint(RenderLayerModelObject* repaintContainer, bool clipToVisibleContent = true) OVERRIDE; virtual bool canBeSelectionLeaf() const { return true; } void updateMargins(); diff --git a/Source/WebCore/rendering/RenderMarquee.cpp b/Source/WebCore/rendering/RenderMarquee.cpp index 0dc0eed39..77bf34aba 100644 --- a/Source/WebCore/rendering/RenderMarquee.cpp +++ b/Source/WebCore/rendering/RenderMarquee.cpp @@ -234,13 +234,8 @@ void RenderMarquee::updateMarqueeStyle() } } - // Marquee height hack!! Make sure that, if it is a horizontal marquee, the height attribute is overridden - // if it is smaller than the font size. If it is a vertical marquee and height is not specified, we default - // to a marquee of 200px. - if (isHorizontal()) { - if (s->height().isFixed() && s->height().value() < s->fontSize()) - s->setHeight(Length(s->fontSize(), Fixed)); - } else if (s->height().isAuto()) //vertical marquee with no specified height + // Legacy hack - multiple browsers default vertical marquees to 200px tall. + if (!isHorizontal() && s->height().isAuto()) s->setHeight(Length(200, Fixed)); if (speed() != marqueeSpeed()) { diff --git a/Source/WebCore/rendering/RenderMediaControls.cpp b/Source/WebCore/rendering/RenderMediaControls.cpp index 3ecd86748..cfaed5e79 100644 --- a/Source/WebCore/rendering/RenderMediaControls.cpp +++ b/Source/WebCore/rendering/RenderMediaControls.cpp @@ -213,7 +213,7 @@ IntPoint RenderMediaControls::volumeSliderOffsetFromMuteButton(RenderBox* muteBu float zoomLevel = muteButtonBox->style()->effectiveZoom(); int y = yOffset * zoomLevel + muteButtonBox->pixelSnappedOffsetHeight() - size.height(); - FloatPoint absPoint = muteButtonBox->localToAbsolute(FloatPoint(muteButtonBox->pixelSnappedOffsetLeft(), y), true, true); + FloatPoint absPoint = muteButtonBox->localToAbsolute(FloatPoint(muteButtonBox->pixelSnappedOffsetLeft(), y), IsFixed | UseTransforms | SnapOffsetForTransforms); if (absPoint.y() < 0) y = muteButtonBox->pixelSnappedHeight(); return IntPoint(xOffset * zoomLevel, y); diff --git a/Source/WebCore/rendering/RenderMenuList.cpp b/Source/WebCore/rendering/RenderMenuList.cpp index 1ab55a602..b721742e1 100644 --- a/Source/WebCore/rendering/RenderMenuList.cpp +++ b/Source/WebCore/rendering/RenderMenuList.cpp @@ -320,7 +320,7 @@ void RenderMenuList::showPopup() // Compute the top left taking transforms into account, but use // the actual width of the element to size the popup. - FloatPoint absTopLeft = localToAbsolute(FloatPoint(), false, true); + FloatPoint absTopLeft = localToAbsolute(FloatPoint(), UseTransforms | SnapOffsetForTransforms); IntRect absBounds = absoluteBoundingBoxRectIgnoringTransforms(); absBounds.setLocation(roundedIntPoint(absTopLeft)); HTMLSelectElement* select = selectElement(); diff --git a/Source/WebCore/rendering/RenderNamedFlowThread.cpp b/Source/WebCore/rendering/RenderNamedFlowThread.cpp index 264aeb497..56247c8f8 100644 --- a/Source/WebCore/rendering/RenderNamedFlowThread.cpp +++ b/Source/WebCore/rendering/RenderNamedFlowThread.cpp @@ -142,7 +142,7 @@ bool RenderNamedFlowThread::dependsOn(RenderNamedFlowThread* otherRenderFlowThre RenderNamedFlowThreadCountedSet::const_iterator iterator = m_layoutBeforeThreadsSet.begin(); RenderNamedFlowThreadCountedSet::const_iterator end = m_layoutBeforeThreadsSet.end(); for (; iterator != end; ++iterator) { - const RenderNamedFlowThread* beforeFlowThread = (*iterator).first; + const RenderNamedFlowThread* beforeFlowThread = (*iterator).key; if (beforeFlowThread->dependsOn(otherRenderFlowThread)) return true; } @@ -201,24 +201,31 @@ static bool compareRenderRegions(const RenderRegion* firstRegion, const RenderRe return true; } -void RenderNamedFlowThread::addRegionToThread(RenderRegion* renderRegion) +// This helper function adds a region to a list preserving the order property of the list. +static void addRegionToList(RenderRegionList& regionList, RenderRegion* renderRegion) { - ASSERT(renderRegion); - if (m_regionList.isEmpty()) - m_regionList.add(renderRegion); + if (regionList.isEmpty()) + regionList.add(renderRegion); else { // Find the first region "greater" than renderRegion. - RenderRegionList::iterator it = m_regionList.begin(); - while (it != m_regionList.end() && !compareRenderRegions(renderRegion, *it)) + RenderRegionList::iterator it = regionList.begin(); + while (it != regionList.end() && !compareRenderRegions(renderRegion, *it)) ++it; - m_regionList.insertBefore(it, renderRegion); + regionList.insertBefore(it, renderRegion); } +} + +void RenderNamedFlowThread::addRegionToThread(RenderRegion* renderRegion) +{ + ASSERT(renderRegion); resetMarkForDestruction(); ASSERT(!renderRegion->isValid()); if (renderRegion->parentNamedFlowThread()) { if (renderRegion->parentNamedFlowThread()->dependsOn(this)) { + // The order of invalid regions is irrelevant. + m_invalidRegionList.add(renderRegion); // Register ourself to get a notification when the state changes. renderRegion->parentNamedFlowThread()->m_observerThreadsSet.add(this); return; @@ -228,6 +235,7 @@ void RenderNamedFlowThread::addRegionToThread(RenderRegion* renderRegion) } renderRegion->setIsValid(true); + addRegionToList(m_regionList, renderRegion); invalidateRegions(); } @@ -236,10 +244,11 @@ void RenderNamedFlowThread::removeRegionFromThread(RenderRegion* renderRegion) { ASSERT(renderRegion); m_regionRangeMap.clear(); - m_regionList.remove(renderRegion); if (renderRegion->parentNamedFlowThread()) { if (!renderRegion->isValid()) { + ASSERT(m_invalidRegionList.contains(renderRegion)); + m_invalidRegionList.remove(renderRegion); renderRegion->parentNamedFlowThread()->m_observerThreadsSet.remove(this); // No need to invalidate the regions rectangles. The removed region // was not taken into account. Just return here. @@ -248,6 +257,9 @@ void RenderNamedFlowThread::removeRegionFromThread(RenderRegion* renderRegion) removeDependencyOnFlowThread(renderRegion->parentNamedFlowThread()); } + ASSERT(m_regionList.contains(renderRegion)); + m_regionList.remove(renderRegion); + if (canBeDestroyed()) setMarkForDestruction(); @@ -260,19 +272,29 @@ void RenderNamedFlowThread::removeRegionFromThread(RenderRegion* renderRegion) void RenderNamedFlowThread::checkInvalidRegions() { - for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { + Vector<RenderRegion*> newValidRegions; + for (RenderRegionList::iterator iter = m_invalidRegionList.begin(); iter != m_invalidRegionList.end(); ++iter) { RenderRegion* region = *iter; // The only reason a region would be invalid is because it has a parent flow thread. - ASSERT(region->isValid() || region->parentNamedFlowThread()); - if (region->isValid() || region->parentNamedFlowThread()->dependsOn(this)) + ASSERT(!region->isValid() && region->parentNamedFlowThread()); + if (region->parentNamedFlowThread()->dependsOn(this)) continue; + newValidRegions.append(region); + } + + for (Vector<RenderRegion*>::iterator iter = newValidRegions.begin(); iter != newValidRegions.end(); ++iter) { + RenderRegion* region = *iter; + m_invalidRegionList.remove(region); region->parentNamedFlowThread()->m_observerThreadsSet.remove(this); - addDependencyOnFlowThread(region->parentNamedFlowThread()); region->setIsValid(true); - invalidateRegions(); + addDependencyOnFlowThread(region->parentNamedFlowThread()); + addRegionToList(m_regionList, region); } + if (!newValidRegions.isEmpty()) + invalidateRegions(); + if (m_observerThreadsSet.isEmpty()) return; @@ -309,7 +331,7 @@ void RenderNamedFlowThread::removeDependencyOnFlowThread(RenderNamedFlowThread* void RenderNamedFlowThread::pushDependencies(RenderNamedFlowThreadList& list) { for (RenderNamedFlowThreadCountedSet::iterator iter = m_layoutBeforeThreadsSet.begin(); iter != m_layoutBeforeThreadsSet.end(); ++iter) { - RenderNamedFlowThread* flowThread = (*iter).first; + RenderNamedFlowThread* flowThread = (*iter).key; if (list.contains(flowThread)) continue; flowThread->pushDependencies(list); diff --git a/Source/WebCore/rendering/RenderNamedFlowThread.h b/Source/WebCore/rendering/RenderNamedFlowThread.h index 3199307cf..a833151bf 100644 --- a/Source/WebCore/rendering/RenderNamedFlowThread.h +++ b/Source/WebCore/rendering/RenderNamedFlowThread.h @@ -50,6 +50,8 @@ public: const AtomicString& flowThreadName() const; + const RenderRegionList& invalidRenderRegionList() const { return m_invalidRegionList; } + RenderObject* nextRendererForNode(Node*) const; RenderObject* previousRendererForNode(Node*) const; @@ -86,7 +88,7 @@ private: void addDependencyOnFlowThread(RenderNamedFlowThread*); void removeDependencyOnFlowThread(RenderNamedFlowThread*); void checkInvalidRegions(); - bool canBeDestroyed() const { return m_regionList.isEmpty() && m_contentNodes.isEmpty(); } + bool canBeDestroyed() const { return m_invalidRegionList.isEmpty() && m_regionList.isEmpty() && m_contentNodes.isEmpty(); } void regionLayoutUpdateEventTimerFired(Timer<RenderNamedFlowThread>*); void clearContentNodes(); @@ -107,6 +109,8 @@ private: NamedFlowContentNodes m_contentNodes; + RenderRegionList m_invalidRegionList; + // The DOM Object that represents a named flow. RefPtr<WebKitNamedFlow> m_namedFlow; diff --git a/Source/WebCore/rendering/RenderObject.cpp b/Source/WebCore/rendering/RenderObject.cpp index c523d26b6..7fee05442 100755 --- a/Source/WebCore/rendering/RenderObject.cpp +++ b/Source/WebCore/rendering/RenderObject.cpp @@ -132,12 +132,16 @@ RenderObject* RenderObject::createObject(Node* node, RenderStyle* style) const ContentData* contentData = style->contentData(); if (contentData && !contentData->next() && contentData->isImage() && doc != node) { RenderImage* image = new (arena) RenderImage(node); - image->setStyle(style); + // RenderImageResourceStyleImage requires a style being present on the image but we don't want to + // trigger a style change now as the node is not fully attached. Moving this code to style change + // doesn't make sense as it should be run once at renderer creation. + image->m_style = style; if (const StyleImage* styleImage = static_cast<const ImageContentData*>(contentData)->image()) { image->setImageResource(RenderImageResourceStyleImage::create(const_cast<StyleImage*>(styleImage))); image->setIsGeneratedContent(); } else image->setImageResource(RenderImageResource::create()); + image->m_style = 0; return image; } @@ -308,7 +312,7 @@ void RenderObject::addChild(RenderObject* newChild, RenderObject* beforeChild) // To avoid the problem alltogether, detect early if we're inside a hidden SVG subtree // and stop creating layers at all for these cases - they're not used anyways. if (newChild->hasLayer() && !layerCreationAllowedForSubtree()) - toRenderBoxModelObject(newChild)->layer()->removeOnlyThisLayer(); + toRenderLayerModelObject(newChild)->layer()->removeOnlyThisLayer(); } void RenderObject::removeChild(RenderObject* oldChild) @@ -430,7 +434,7 @@ static void addLayers(RenderObject* obj, RenderLayer* parentLayer, RenderObject* beforeChild = newObject->parent()->findNextLayer(parentLayer, newObject); newObject = 0; } - parentLayer->addChild(toRenderBoxModelObject(obj)->layer(), beforeChild); + parentLayer->addChild(toRenderLayerModelObject(obj)->layer(), beforeChild); return; } @@ -454,7 +458,7 @@ void RenderObject::removeLayers(RenderLayer* parentLayer) return; if (hasLayer()) { - parentLayer->removeChild(toRenderBoxModelObject(this)->layer()); + parentLayer->removeChild(toRenderLayerModelObject(this)->layer()); return; } @@ -468,7 +472,7 @@ void RenderObject::moveLayers(RenderLayer* oldParent, RenderLayer* newParent) return; if (hasLayer()) { - RenderLayer* layer = toRenderBoxModelObject(this)->layer(); + RenderLayer* layer = toRenderLayerModelObject(this)->layer(); ASSERT(oldParent == layer->parent()); if (oldParent) oldParent->removeChild(layer); @@ -488,7 +492,7 @@ RenderLayer* RenderObject::findNextLayer(RenderLayer* parentLayer, RenderObject* return 0; // Step 1: If our layer is a child of the desired parent, then return our layer. - RenderLayer* ourLayer = hasLayer() ? toRenderBoxModelObject(this)->layer() : 0; + RenderLayer* ourLayer = hasLayer() ? toRenderLayerModelObject(this)->layer() : 0; if (ourLayer && ourLayer->parent() == parentLayer) return ourLayer; @@ -520,7 +524,7 @@ RenderLayer* RenderObject::enclosingLayer() const { const RenderObject* curr = this; while (curr) { - RenderLayer* layer = curr->hasLayer() ? toRenderBoxModelObject(curr)->layer() : 0; + RenderLayer* layer = curr->hasLayer() ? toRenderLayerModelObject(curr)->layer() : 0; if (layer) return layer; curr = curr->parent(); @@ -716,13 +720,13 @@ void RenderObject::invalidateContainerPreferredLogicalWidths() void RenderObject::setLayerNeedsFullRepaint() { ASSERT(hasLayer()); - toRenderBoxModelObject(this)->layer()->setRepaintStatus(NeedsFullRepaint); + toRenderLayerModelObject(this)->layer()->setRepaintStatus(NeedsFullRepaint); } void RenderObject::setLayerNeedsFullRepaintForPositionedMovementLayout() { ASSERT(hasLayer()); - toRenderBoxModelObject(this)->layer()->setRepaintStatus(NeedsFullRepaintForPositionedMovementLayout); + toRenderLayerModelObject(this)->layer()->setRepaintStatus(NeedsFullRepaintForPositionedMovementLayout); } RenderBlock* RenderObject::containingBlock() const @@ -1198,7 +1202,7 @@ void RenderObject::absoluteFocusRingQuads(Vector<FloatQuad>& quads) for (size_t i = 0; i < count; ++i) { IntRect rect = rects[i]; rect.move(-absolutePoint.x(), -absolutePoint.y()); - quads.append(localToAbsoluteQuad(FloatQuad(rect))); + quads.append(localToAbsoluteQuad(FloatQuad(rect), SnapOffsetForTransforms)); } } @@ -1241,13 +1245,13 @@ void RenderObject::paint(PaintInfo&, const LayoutPoint&) { } -RenderBoxModelObject* RenderObject::containerForRepaint() const +RenderLayerModelObject* RenderObject::containerForRepaint() const { RenderView* v = view(); if (!v) return 0; - RenderBoxModelObject* repaintContainer = 0; + RenderLayerModelObject* repaintContainer = 0; #if USE(ACCELERATED_COMPOSITING) if (v->usesCompositing()) { @@ -1277,7 +1281,7 @@ RenderBoxModelObject* RenderObject::containerForRepaint() const return repaintContainer; } -void RenderObject::repaintUsingContainer(RenderBoxModelObject* repaintContainer, const IntRect& r, bool immediate) const +void RenderObject::repaintUsingContainer(RenderLayerModelObject* repaintContainer, const IntRect& r, bool immediate) const { if (!repaintContainer) { view()->repaintViewRectangle(r, immediate); @@ -1330,7 +1334,7 @@ void RenderObject::repaint(bool immediate) const if (view->printing()) return; // Don't repaint if we're printing. - RenderBoxModelObject* repaintContainer = containerForRepaint(); + RenderLayerModelObject* repaintContainer = containerForRepaint(); repaintUsingContainer(repaintContainer ? repaintContainer : view, pixelSnappedIntRect(clippedOverflowRectForRepaint(repaintContainer)), immediate); } @@ -1350,7 +1354,7 @@ void RenderObject::repaintRectangle(const LayoutRect& r, bool immediate) const // repaint containers. https://bugs.webkit.org/show_bug.cgi?id=23308 dirtyRect.move(view->layoutDelta()); - RenderBoxModelObject* repaintContainer = containerForRepaint(); + RenderLayerModelObject* repaintContainer = containerForRepaint(); computeRectForRepaint(repaintContainer, dirtyRect); repaintUsingContainer(repaintContainer ? repaintContainer : view, pixelSnappedIntRect(dirtyRect), immediate); } @@ -1360,7 +1364,7 @@ IntRect RenderObject::pixelSnappedAbsoluteClippedOverflowRect() const return pixelSnappedIntRect(absoluteClippedOverflowRect()); } -bool RenderObject::repaintAfterLayoutIfNeeded(RenderBoxModelObject* repaintContainer, const LayoutRect& oldBounds, const LayoutRect& oldOutlineBox, const LayoutRect* newBoundsPtr, const LayoutRect* newOutlineBoxRectPtr) +bool RenderObject::repaintAfterLayoutIfNeeded(RenderLayerModelObject* repaintContainer, const LayoutRect& oldBounds, const LayoutRect& oldOutlineBox, const LayoutRect* newBoundsPtr, const LayoutRect* newOutlineBoxRectPtr) { RenderView* v = view(); if (v->printing()) @@ -1423,22 +1427,24 @@ bool RenderObject::repaintAfterLayoutIfNeeded(RenderBoxModelObject* repaintConta if (newOutlineBox == oldOutlineBox) return false; - // We didn't move, but we did change size. Invalidate the delta, which will consist of possibly + // We didn't move, but we did change size. Invalidate the delta, which will consist of possibly // two rectangles (but typically only one). RenderStyle* outlineStyle = outlineStyleForRepaint(); - LayoutUnit ow = outlineStyle->outlineSize(); + LayoutUnit outlineWidth = outlineStyle->outlineSize(); + LayoutBoxExtent insetShadowExtent = style()->getBoxShadowInsetExtent(); LayoutUnit width = absoluteValue(newOutlineBox.width() - oldOutlineBox.width()); if (width) { LayoutUnit shadowLeft; LayoutUnit shadowRight; style()->getBoxShadowHorizontalExtent(shadowLeft, shadowRight); - int borderRight = isBox() ? toRenderBox(this)->borderRight() : 0; LayoutUnit boxWidth = isBox() ? toRenderBox(this)->width() : ZERO_LAYOUT_UNIT; - LayoutUnit borderWidth = max<LayoutUnit>(-outlineStyle->outlineOffset(), max<LayoutUnit>(borderRight, max<LayoutUnit>(valueForLength(style()->borderTopRightRadius().width(), boxWidth, v), valueForLength(style()->borderBottomRightRadius().width(), boxWidth, v)))) + max<LayoutUnit>(ow, shadowRight); - LayoutRect rightRect(newOutlineBox.x() + min(newOutlineBox.width(), oldOutlineBox.width()) - borderWidth, + LayoutUnit minInsetRightShadowExtent = min<LayoutUnit>(-insetShadowExtent.right(), min<LayoutUnit>(newBounds.width(), oldBounds.width())); + LayoutUnit borderWidth = max<LayoutUnit>(borderRight, max<LayoutUnit>(valueForLength(style()->borderTopRightRadius().width(), boxWidth, v), valueForLength(style()->borderBottomRightRadius().width(), boxWidth, v))); + LayoutUnit decorationsWidth = max<LayoutUnit>(-outlineStyle->outlineOffset(), borderWidth + minInsetRightShadowExtent) + max<LayoutUnit>(outlineWidth, shadowRight); + LayoutRect rightRect(newOutlineBox.x() + min(newOutlineBox.width(), oldOutlineBox.width()) - decorationsWidth, newOutlineBox.y(), - width + borderWidth, + width + decorationsWidth, max(newOutlineBox.height(), oldOutlineBox.height())); LayoutUnit right = min<LayoutUnit>(newBounds.maxX(), oldBounds.maxX()); if (rightRect.x() < right) { @@ -1451,14 +1457,15 @@ bool RenderObject::repaintAfterLayoutIfNeeded(RenderBoxModelObject* repaintConta LayoutUnit shadowTop; LayoutUnit shadowBottom; style()->getBoxShadowVerticalExtent(shadowTop, shadowBottom); - int borderBottom = isBox() ? toRenderBox(this)->borderBottom() : 0; LayoutUnit boxHeight = isBox() ? toRenderBox(this)->height() : ZERO_LAYOUT_UNIT; - LayoutUnit borderHeight = max<LayoutUnit>(-outlineStyle->outlineOffset(), max<LayoutUnit>(borderBottom, max<LayoutUnit>(valueForLength(style()->borderBottomLeftRadius().height(), boxHeight, v), valueForLength(style()->borderBottomRightRadius().height(), boxHeight, v)))) + max<LayoutUnit>(ow, shadowBottom); + LayoutUnit minInsetBottomShadowExtent = min<LayoutUnit>(-insetShadowExtent.bottom(), min<LayoutUnit>(newBounds.height(), oldBounds.height())); + LayoutUnit borderHeight = max<LayoutUnit>(borderBottom, max<LayoutUnit>(valueForLength(style()->borderBottomLeftRadius().height(), boxHeight, v), valueForLength(style()->borderBottomRightRadius().height(), boxHeight, v))); + LayoutUnit decorationsHeight = max<LayoutUnit>(-outlineStyle->outlineOffset(), borderHeight + minInsetBottomShadowExtent) + max<LayoutUnit>(outlineWidth, shadowBottom); LayoutRect bottomRect(newOutlineBox.x(), - min(newOutlineBox.maxY(), oldOutlineBox.maxY()) - borderHeight, + min(newOutlineBox.maxY(), oldOutlineBox.maxY()) - decorationsHeight, max(newOutlineBox.width(), oldOutlineBox.width()), - height + borderHeight); + height + decorationsHeight); LayoutUnit bottom = min(newBounds.maxY(), oldBounds.maxY()); if (bottomRect.y() < bottom) { bottomRect.setHeight(min(bottomRect.height(), bottom - bottomRect.y())); @@ -1481,20 +1488,20 @@ bool RenderObject::checkForRepaintDuringLayout() const return !document()->view()->needsFullRepaint() && !hasLayer() && everHadLayout(); } -LayoutRect RenderObject::rectWithOutlineForRepaint(RenderBoxModelObject* repaintContainer, LayoutUnit outlineWidth) const +LayoutRect RenderObject::rectWithOutlineForRepaint(RenderLayerModelObject* repaintContainer, LayoutUnit outlineWidth) const { LayoutRect r(clippedOverflowRectForRepaint(repaintContainer)); r.inflate(outlineWidth); return r; } -LayoutRect RenderObject::clippedOverflowRectForRepaint(RenderBoxModelObject*) const +LayoutRect RenderObject::clippedOverflowRectForRepaint(RenderLayerModelObject*) const { ASSERT_NOT_REACHED(); return LayoutRect(); } -void RenderObject::computeRectForRepaint(RenderBoxModelObject* repaintContainer, LayoutRect& rect, bool fixed) const +void RenderObject::computeRectForRepaint(RenderLayerModelObject* repaintContainer, LayoutRect& rect, bool fixed) const { if (repaintContainer == this) return; @@ -1517,7 +1524,7 @@ void RenderObject::computeRectForRepaint(RenderBoxModelObject* repaintContainer, } } -void RenderObject::computeFloatRectForRepaint(RenderBoxModelObject*, FloatRect&, bool) const +void RenderObject::computeFloatRectForRepaint(RenderLayerModelObject*, FloatRect&, bool) const { ASSERT_NOT_REACHED(); } @@ -1678,7 +1685,7 @@ StyleDifference RenderObject::adjustStyleDifference(StyleDifference diff, unsign // Text nodes share style with their parents but transforms don't apply to them, // hence the !isText() check. // FIXME: when transforms are taken into account for overflow, we will need to do a layout. - if (!isText() && (!hasLayer() || !toRenderBoxModelObject(this)->layer()->isComposited())) { + if (!isText() && (!hasLayer() || !toRenderLayerModelObject(this)->layer()->isComposited())) { // We need to set at least SimplifiedLayout, but if PositionedMovementOnly is already set // then we actually need SimplifiedLayoutAndPositionedMovement. if (!hasLayer()) @@ -1694,7 +1701,7 @@ StyleDifference RenderObject::adjustStyleDifference(StyleDifference diff, unsign // If opacity changed, and we are not composited, need to repaint (also // ignoring text nodes) if (contextSensitiveProperties & ContextSensitivePropertyOpacity) { - if (!isText() && (!hasLayer() || !toRenderBoxModelObject(this)->layer()->isComposited())) + if (!isText() && (!hasLayer() || !toRenderLayerModelObject(this)->layer()->isComposited())) diff = StyleDifferenceRepaintLayer; else if (diff < StyleDifferenceRecompositeLayer) diff = StyleDifferenceRecompositeLayer; @@ -1702,7 +1709,7 @@ StyleDifference RenderObject::adjustStyleDifference(StyleDifference diff, unsign #if ENABLE(CSS_FILTERS) if ((contextSensitiveProperties & ContextSensitivePropertyFilter) && hasLayer()) { - RenderLayer* layer = toRenderBoxModelObject(this)->layer(); + RenderLayer* layer = toRenderLayerModelObject(this)->layer(); if (!layer->isComposited() || layer->paintsWithFilters()) diff = StyleDifferenceRepaintLayer; else if (diff < StyleDifferenceRecompositeLayer) @@ -1710,11 +1717,11 @@ StyleDifference RenderObject::adjustStyleDifference(StyleDifference diff, unsign } #endif - // The answer to requiresLayer() for plugins and iframes can change outside of the style system, - // since it depends on whether we decide to composite these elements. When the layer status of - // one of these elements changes, we need to force a layout. - if (diff == StyleDifferenceEqual && style() && isBoxModelObject()) { - if (hasLayer() != toRenderBoxModelObject(this)->requiresLayer()) + // The answer to requiresLayer() for plugins, iframes, and canvas can change without the actual + // style changing, since it depends on whether we decide to composite these elements. When the + // layer status of one of these elements changes, we need to force a layout. + if (diff == StyleDifferenceEqual && style() && isLayerModelObject()) { + if (hasLayer() != toRenderLayerModelObject(this)->requiresLayer()) diff = StyleDifferenceLayout; } #else @@ -1732,9 +1739,9 @@ void RenderObject::setStyle(PassRefPtr<RenderStyle> style) { if (m_style == style) { #if USE(ACCELERATED_COMPOSITING) - // We need to run through adjustStyleDifference() for iframes and plugins, so + // We need to run through adjustStyleDifference() for iframes, plugins, and canvas so // style sharing is disabled for them. That should ensure that we never hit this code path. - ASSERT(!isRenderIFrame() && !isEmbeddedObject()); + ASSERT(!isRenderIFrame() && !isEmbeddedObject() && !isCanvas()); #endif return; } @@ -1812,7 +1819,7 @@ void RenderObject::styleWillChange(StyleDifference diff, const RenderStyle* newS || m_style->hasAutoZIndex() != newStyle->hasAutoZIndex(); #if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) if (visibilityChanged) - document()->setDashboardRegionsDirty(true); + document()->setAnnotatedRegionsDirty(true); #endif if (visibilityChanged && AXObjectCache::accessibilityEnabled()) document()->axObjectCache()->childrenChanged(this); @@ -1999,30 +2006,25 @@ LayoutRect RenderObject::viewRect() const return view()->viewRect(); } -FloatPoint RenderObject::localToAbsolute(const FloatPoint& localPoint, bool fixed, bool useTransforms) const +FloatPoint RenderObject::localToAbsolute(const FloatPoint& localPoint, MapCoordinatesFlags mode) const { TransformState transformState(TransformState::ApplyTransformDirection, localPoint); - MapLocalToContainerFlags mode = ApplyContainerFlip; - if (fixed) - mode |= IsFixed; - if (useTransforms) - mode |= UseTransforms; - mapLocalToContainer(0, transformState, mode); + mapLocalToContainer(0, transformState, mode | ApplyContainerFlip); transformState.flatten(); return transformState.lastPlanarPoint(); } -FloatPoint RenderObject::absoluteToLocal(const FloatPoint& containerPoint, bool fixed, bool useTransforms) const +FloatPoint RenderObject::absoluteToLocal(const FloatPoint& containerPoint, MapCoordinatesFlags mode) const { TransformState transformState(TransformState::UnapplyInverseTransformDirection, containerPoint); - mapAbsoluteToLocalPoint(fixed, useTransforms, transformState); + mapAbsoluteToLocalPoint(mode, transformState); transformState.flatten(); return transformState.lastPlanarPoint(); } -void RenderObject::mapLocalToContainer(RenderBoxModelObject* repaintContainer, TransformState& transformState, MapLocalToContainerFlags mode, bool* wasFixed) const +void RenderObject::mapLocalToContainer(RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags mode, bool* wasFixed) const { if (repaintContainer == this) return; @@ -2050,7 +2052,7 @@ void RenderObject::mapLocalToContainer(RenderBoxModelObject* repaintContainer, T o->mapLocalToContainer(repaintContainer, transformState, mode, wasFixed); } -const RenderObject* RenderObject::pushMappingToContainer(const RenderBoxModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const +const RenderObject* RenderObject::pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const { ASSERT_UNUSED(ancestorToStopAt, ancestorToStopAt != this); @@ -2068,11 +2070,11 @@ const RenderObject* RenderObject::pushMappingToContainer(const RenderBoxModelObj return container; } -void RenderObject::mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState& transformState) const +void RenderObject::mapAbsoluteToLocalPoint(MapCoordinatesFlags mode, TransformState& transformState) const { RenderObject* o = parent(); if (o) { - o->mapAbsoluteToLocalPoint(fixed, useTransforms, transformState); + o->mapAbsoluteToLocalPoint(mode, transformState); if (o->hasOverflowClip()) transformState.move(toRenderBox(o)->scrolledContentOffset()); } @@ -2083,7 +2085,7 @@ bool RenderObject::shouldUseTransformFromContainer(const RenderObject* container #if ENABLE(3D_RENDERING) // hasTransform() indicates whether the object has transform, transform-style or perspective. We just care about transform, // so check the layer's transform directly. - return (hasLayer() && toRenderBoxModelObject(this)->layer()->transform()) || (containerObject && containerObject->style()->hasPerspective()); + return (hasLayer() && toRenderLayerModelObject(this)->layer()->transform()) || (containerObject && containerObject->style()->hasPerspective()); #else UNUSED_PARAM(containerObject); return hasTransform(); @@ -2095,14 +2097,14 @@ void RenderObject::getTransformFromContainer(const RenderObject* containerObject transform.makeIdentity(); transform.translate(offsetInContainer.width(), offsetInContainer.height()); RenderLayer* layer; - if (hasLayer() && (layer = toRenderBoxModelObject(this)->layer()) && layer->transform()) + if (hasLayer() && (layer = toRenderLayerModelObject(this)->layer()) && layer->transform()) transform.multiply(layer->currentTransform()); #if ENABLE(3D_RENDERING) if (containerObject && containerObject->hasLayer() && containerObject->style()->hasPerspective()) { // Perpsective on the container affects us, so we have to factor it in here. ASSERT(containerObject->hasLayer()); - FloatPoint perspectiveOrigin = toRenderBoxModelObject(containerObject)->layer()->perspectiveOrigin(); + FloatPoint perspectiveOrigin = toRenderLayerModelObject(containerObject)->layer()->perspectiveOrigin(); TransformationMatrix perspectiveMatrix; perspectiveMatrix.applyPerspective(containerObject->style()->perspective()); @@ -2116,31 +2118,21 @@ void RenderObject::getTransformFromContainer(const RenderObject* containerObject #endif } -FloatQuad RenderObject::localToContainerQuad(const FloatQuad& localQuad, RenderBoxModelObject* repaintContainer, bool snapOffsetForTransforms, bool fixed, bool* wasFixed) const +FloatQuad RenderObject::localToContainerQuad(const FloatQuad& localQuad, RenderLayerModelObject* repaintContainer, MapCoordinatesFlags mode, bool* wasFixed) const { // Track the point at the center of the quad's bounding box. As mapLocalToContainer() calls offsetFromContainer(), // it will use that point as the reference point to decide which column's transform to apply in multiple-column blocks. TransformState transformState(TransformState::ApplyTransformDirection, localQuad.boundingBox().center(), localQuad); - MapLocalToContainerFlags mode = ApplyContainerFlip | UseTransforms; - if (fixed) - mode |= IsFixed; - if (snapOffsetForTransforms) - mode |= SnapOffsetForTransforms; - mapLocalToContainer(repaintContainer, transformState, mode, wasFixed); + mapLocalToContainer(repaintContainer, transformState, mode | ApplyContainerFlip | UseTransforms, wasFixed); transformState.flatten(); return transformState.lastPlanarQuad(); } -FloatPoint RenderObject::localToContainerPoint(const FloatPoint& localPoint, RenderBoxModelObject* repaintContainer, bool snapOffsetForTransforms, bool fixed, bool* wasFixed) const +FloatPoint RenderObject::localToContainerPoint(const FloatPoint& localPoint, RenderLayerModelObject* repaintContainer, MapCoordinatesFlags mode, bool* wasFixed) const { TransformState transformState(TransformState::ApplyTransformDirection, localPoint); - MapLocalToContainerFlags mode = ApplyContainerFlip | UseTransforms; - if (fixed) - mode |= IsFixed; - if (snapOffsetForTransforms) - mode |= SnapOffsetForTransforms; - mapLocalToContainer(repaintContainer, transformState, mode, wasFixed); + mapLocalToContainer(repaintContainer, transformState, mode | ApplyContainerFlip | UseTransforms, wasFixed); transformState.flatten(); return transformState.lastPlanarPoint(); @@ -2235,7 +2227,7 @@ bool RenderObject::hasOutlineAnnotation() const return node() && node()->isLink() && document()->printing(); } -RenderObject* RenderObject::container(const RenderBoxModelObject* repaintContainer, bool* repaintContainerSkipped) const +RenderObject* RenderObject::container(const RenderLayerModelObject* repaintContainer, bool* repaintContainerSkipped) const { if (repaintContainerSkipped) *repaintContainerSkipped = false; @@ -2368,7 +2360,7 @@ void RenderObject::willBeDestroyed() // be moved into RenderBoxModelObject::destroy. if (hasLayer()) { setHasLayer(false); - toRenderBoxModelObject(this)->destroyLayer(); + toRenderLayerModelObject(this)->destroyLayer(); } setAncestorLineBoxDirty(false); @@ -2522,7 +2514,7 @@ void RenderObject::updateDragState(bool dragOn) bool RenderObject::isComposited() const { - return hasLayer() && toRenderBoxModelObject(this)->layer()->isComposited(); + return hasLayer() && toRenderLayerModelObject(this)->layer()->isComposited(); } bool RenderObject::hitTest(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestFilter hitTestFilter) @@ -2595,6 +2587,37 @@ void RenderObject::layout() setNeedsLayout(false); } +enum StyleCacheState { + Cached, + Uncached +}; + +static PassRefPtr<RenderStyle> firstLineStyleForCachedUncachedType(StyleCacheState type, const RenderObject* renderer, RenderStyle* style) +{ + const RenderObject* rendererForFirstLineStyle = renderer; + if (renderer->isBeforeOrAfterContent()) + rendererForFirstLineStyle = renderer->parent(); + + if (rendererForFirstLineStyle->isBlockFlow()) { + if (RenderBlock* firstLineBlock = rendererForFirstLineStyle->firstLineBlock()) { + if (type == Cached) + return firstLineBlock->getCachedPseudoStyle(FIRST_LINE, style); + return firstLineBlock->getUncachedPseudoStyle(FIRST_LINE, style, firstLineBlock == renderer ? style : 0); + } + } else if (!rendererForFirstLineStyle->isAnonymous() && rendererForFirstLineStyle->isRenderInline()) { + RenderStyle* parentStyle = rendererForFirstLineStyle->parent()->firstLineStyle(); + if (parentStyle != rendererForFirstLineStyle->parent()->style()) { + if (type == Cached) { + // A first-line style is in effect. Cache a first-line style for ourselves. + rendererForFirstLineStyle->style()->setHasPseudoStyle(FIRST_LINE_INHERITED); + return rendererForFirstLineStyle->getCachedPseudoStyle(FIRST_LINE_INHERITED, parentStyle); + } + return rendererForFirstLineStyle->getUncachedPseudoStyle(FIRST_LINE_INHERITED, parentStyle, style); + } + } + return 0; +} + PassRefPtr<RenderStyle> RenderObject::uncachedFirstLineStyle(RenderStyle* style) const { if (!document()->styleSheetCollection()->usesFirstLineRules()) @@ -2602,39 +2625,17 @@ PassRefPtr<RenderStyle> RenderObject::uncachedFirstLineStyle(RenderStyle* style) ASSERT(!isText()); - RefPtr<RenderStyle> result; - - if (isBlockFlow()) { - if (RenderBlock* firstLineBlock = this->firstLineBlock()) - result = firstLineBlock->getUncachedPseudoStyle(FIRST_LINE, style, firstLineBlock == this ? style : 0); - } else if (!isAnonymous() && isRenderInline()) { - RenderStyle* parentStyle = parent()->firstLineStyle(); - if (parentStyle != parent()->style()) - result = getUncachedPseudoStyle(FIRST_LINE_INHERITED, parentStyle, style); - } - - return result.release(); + return firstLineStyleForCachedUncachedType(Uncached, this, style); } -RenderStyle* RenderObject::firstLineStyleSlowCase() const +RenderStyle* RenderObject::cachedFirstLineStyle() const { ASSERT(document()->styleSheetCollection()->usesFirstLineRules()); - RenderStyle* style = m_style.get(); - const RenderObject* renderer = isText() ? parent() : this; - if (renderer->isBlockFlow()) { - if (RenderBlock* firstLineBlock = renderer->firstLineBlock()) - style = firstLineBlock->getCachedPseudoStyle(FIRST_LINE, style); - } else if (!renderer->isAnonymous() && renderer->isRenderInline()) { - RenderStyle* parentStyle = renderer->parent()->firstLineStyle(); - if (parentStyle != renderer->parent()->style()) { - // A first-line style is in effect. Cache a first-line style for ourselves. - renderer->style()->setHasPseudoStyle(FIRST_LINE_INHERITED); - style = renderer->getCachedPseudoStyle(FIRST_LINE_INHERITED, parentStyle); - } - } + if (RefPtr<RenderStyle> style = firstLineStyleForCachedUncachedType(Cached, isText() ? parent() : this, m_style.get())) + return style.get(); - return style; + return m_style.get(); } RenderStyle* RenderObject::getCachedPseudoStyle(PseudoId pseudo, RenderStyle* parentStyle) const @@ -2735,14 +2736,16 @@ void RenderObject::getTextDecorationColors(int decorations, Color& underline, Co } #if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) -void RenderObject::addDashboardRegions(Vector<DashboardRegionValue>& regions) +void RenderObject::addAnnotatedRegions(Vector<AnnotatedRegionValue>& regions) { // Convert the style regions to absolute coordinates. if (style()->visibility() != VISIBLE || !isBox()) return; RenderBox* box = toRenderBox(this); + FloatPoint absPos = localToAbsolute(); +#if ENABLE(DASHBOARD_SUPPORT) const Vector<StyleDashboardRegion>& styleRegions = style()->dashboardRegions(); unsigned i, count = styleRegions.size(); for (i = 0; i < count; i++) { @@ -2751,7 +2754,7 @@ void RenderObject::addDashboardRegions(Vector<DashboardRegionValue>& regions) LayoutUnit w = box->width(); LayoutUnit h = box->height(); - DashboardRegionValue region; + AnnotatedRegionValue region; region.label = styleRegion.label; region.bounds = LayoutRect(styleRegion.offset.left().value(), styleRegion.offset.top().value(), @@ -2766,24 +2769,31 @@ void RenderObject::addDashboardRegions(Vector<DashboardRegionValue>& regions) region.clip.setWidth(0); } - FloatPoint absPos = localToAbsolute(); region.bounds.setX(absPos.x() + styleRegion.offset.left().value()); region.bounds.setY(absPos.y() + styleRegion.offset.top().value()); regions.append(region); } +#else // ENABLE(WIDGET_REGION) + if (style()->getDraggableRegionMode() == DraggableRegionNone) + return; + AnnotatedRegionValue region; + region.draggable = style()->getDraggableRegionMode() == DraggableRegionDrag; + region.bounds = LayoutRect(absPos.x(), absPos.y(), box->width(), box->height()); + regions.append(region); +#endif } -void RenderObject::collectDashboardRegions(Vector<DashboardRegionValue>& regions) +void RenderObject::collectAnnotatedRegions(Vector<AnnotatedRegionValue>& regions) { // RenderTexts don't have their own style, they just use their parent's style, // so we don't want to include them. if (isText()) return; - addDashboardRegions(regions); + addAnnotatedRegions(regions); for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) - curr->collectDashboardRegions(regions); + curr->collectAnnotatedRegions(regions); } #endif @@ -2799,16 +2809,7 @@ bool RenderObject::willRenderImage(CachedImage*) // If we're not in a window (i.e., we're dormant from being put in the b/f cache or in a background tab) // then we don't want to render either. - if (document()->inPageCache() || document()->view()->isOffscreen()) - return false; - - // If the document is being destroyed or has not been attached, then this - // RenderObject will not be rendered. - if (!view()) - return false; - - // If a renderer is outside the viewport, we won't render. - return viewRect().intersects(absoluteClippedOverflowRect()); + return !document()->inPageCache() && !document()->view()->isOffscreen(); } int RenderObject::maximalOutlineSize(PaintPhase p) const diff --git a/Source/WebCore/rendering/RenderObject.h b/Source/WebCore/rendering/RenderObject.h index 28cda3ad7..e2e35c93e 100644 --- a/Source/WebCore/rendering/RenderObject.h +++ b/Source/WebCore/rendering/RenderObject.h @@ -3,7 +3,7 @@ * (C) 2000 Antti Koivisto (koivisto@kde.org) * (C) 2000 Dirk Mueller (mueller@kde.org) * (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com) - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012 Apple Inc. All rights reserved. * Copyright (C) 2009 Google Inc. All rights reserved. * * This library is free software; you can redistribute it and/or @@ -60,6 +60,7 @@ class RenderBlock; class RenderFlowThread; class RenderGeometryMap; class RenderLayer; +class RenderLayerModelObject; class RenderNamedFlowThread; class RenderTable; class RenderTheme; @@ -109,31 +110,39 @@ enum PlaceGeneratedRunInFlag { DoNotPlaceGeneratedRunIn }; -enum MapLocalToContainerMode { +enum MapCoordinatesMode { IsFixed = 1 << 0, UseTransforms = 1 << 1, ApplyContainerFlip = 1 << 2, SnapOffsetForTransforms = 1 << 3 }; -typedef unsigned MapLocalToContainerFlags; +typedef unsigned MapCoordinatesFlags; const int caretWidth = 1; #if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) -struct DashboardRegionValue { - bool operator==(const DashboardRegionValue& o) const +struct AnnotatedRegionValue { + bool operator==(const AnnotatedRegionValue& o) const { +#if ENABLE(DASHBOARD_SUPPORT) return type == o.type && bounds == o.bounds && clip == o.clip && label == o.label; +#else // ENABLE(WIDGET_REGION) + return draggable == o.draggable && bounds == o.bounds; +#endif } - bool operator!=(const DashboardRegionValue& o) const + bool operator!=(const AnnotatedRegionValue& o) const { return !(*this == o); } - String label; LayoutRect bounds; +#if ENABLE(DASHBOARD_SUPPORT) + String label; LayoutRect clip; int type; +#else // ENABLE(WIDGET_REGION) + bool draggable; +#endif }; #endif @@ -327,6 +336,7 @@ public: virtual bool isFrameSet() const { return false; } virtual bool isImage() const { return false; } virtual bool isInlineBlockOrInlineTable() const { return false; } + virtual bool isLayerModelObject() const { return false; } virtual bool isListBox() const { return false; } virtual bool isListItem() const { return false; } virtual bool isListMarker() const { return false; } @@ -335,6 +345,7 @@ public: #if ENABLE(METER_ELEMENT) virtual bool isMeter() const { return false; } #endif + virtual bool isSnapshottedPlugIn() const { return false; } #if ENABLE(PROGRESS_ELEMENT) virtual bool isProgress() const { return false; } #endif @@ -610,7 +621,7 @@ public: // Returns the object containing this one. Can be different from parent for positioned elements. // If repaintContainer and repaintContainerSkipped are not null, on return *repaintContainerSkipped // is true if the renderer returned is an ancestor of repaintContainer. - RenderObject* container(const RenderBoxModelObject* repaintContainer = 0, bool* repaintContainerSkipped = 0) const; + RenderObject* container(const RenderLayerModelObject* repaintContainer = 0, bool* repaintContainerSkipped = 0) const; virtual RenderObject* hoverAncestor() const { return parent(); } @@ -664,8 +675,8 @@ public: virtual void updateFromElement() { } #if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) - virtual void addDashboardRegions(Vector<DashboardRegionValue>&); - void collectDashboardRegions(Vector<DashboardRegionValue>&); + virtual void addAnnotatedRegions(Vector<AnnotatedRegionValue>&); + void collectAnnotatedRegions(Vector<AnnotatedRegionValue>&); #endif bool isComposited() const; @@ -696,19 +707,19 @@ public: RenderBlock* containingBlock() const; // Convert the given local point to absolute coordinates - // FIXME: Temporary. If useTransforms is true, take transforms into account. Eventually localToAbsolute() will always be transform-aware. - FloatPoint localToAbsolute(const FloatPoint& localPoint = FloatPoint(), bool fixed = false, bool useTransforms = false) const; - FloatPoint absoluteToLocal(const FloatPoint&, bool fixed = false, bool useTransforms = false) const; + // FIXME: Temporary. If UseTransforms is true, take transforms into account. Eventually localToAbsolute() will always be transform-aware. + FloatPoint localToAbsolute(const FloatPoint& localPoint = FloatPoint(), MapCoordinatesFlags = 0) const; + FloatPoint absoluteToLocal(const FloatPoint&, MapCoordinatesFlags = 0) const; // Convert a local quad to absolute coordinates, taking transforms into account. - FloatQuad localToAbsoluteQuad(const FloatQuad& quad, bool fixed = false, bool* wasFixed = 0) const + FloatQuad localToAbsoluteQuad(const FloatQuad& quad, MapCoordinatesFlags mode = 0, bool* wasFixed = 0) const { - return localToContainerQuad(quad, 0, false, fixed, wasFixed); + return localToContainerQuad(quad, 0, mode, wasFixed); } // Convert a local quad into the coordinate system of container, taking transforms into account. - FloatQuad localToContainerQuad(const FloatQuad&, RenderBoxModelObject* repaintContainer, bool snapOffsetForTransforms = true, bool fixed = false, bool* wasFixed = 0) const; - FloatPoint localToContainerPoint(const FloatPoint&, RenderBoxModelObject* repaintContainer, bool snapOffsetForTransforms = true, bool fixed = false, bool* wasFixed = 0) const; + FloatQuad localToContainerQuad(const FloatQuad&, RenderLayerModelObject* repaintContainer, MapCoordinatesFlags = 0, bool* wasFixed = 0) const; + FloatPoint localToContainerPoint(const FloatPoint&, RenderLayerModelObject* repaintContainer, MapCoordinatesFlags = 0, bool* wasFixed = 0) const; // Return the offset from the container() renderer (excluding transforms). In multi-column layout, // different offsets apply at different points, so return the offset that applies to the given point. @@ -736,7 +747,7 @@ public: virtual LayoutUnit maxPreferredLogicalWidth() const { return 0; } RenderStyle* style() const { return m_style.get(); } - RenderStyle* firstLineStyle() const { return document()->styleSheetCollection()->usesFirstLineRules() ? firstLineStyleSlowCase() : style(); } + RenderStyle* firstLineStyle() const { return document()->styleSheetCollection()->usesFirstLineRules() ? cachedFirstLineStyle() : style(); } RenderStyle* style(bool firstLine) const { return firstLine ? firstLineStyle() : style(); } // Used only by Element::pseudoStyleCacheIsInvalid to get a first line style based off of a @@ -751,13 +762,13 @@ public: void getTextDecorationColors(int decorations, Color& underline, Color& overline, Color& linethrough, bool quirksMode = false, bool firstlineStyle = false); - // Return the RenderBox in the container chain which is responsible for painting this object, or 0 + // Return the RenderLayerModelObject in the container chain which is responsible for painting this object, or 0 // if painting is root-relative. This is the container that should be passed to the 'forRepaint' // methods. - RenderBoxModelObject* containerForRepaint() const; + RenderLayerModelObject* containerForRepaint() const; // Actually do the repaint of rect r for this object which has been computed in the coordinate space // of repaintContainer. If repaintContainer is 0, repaint via the view. - void repaintUsingContainer(RenderBoxModelObject* repaintContainer, const IntRect&, bool immediate = false) const; + void repaintUsingContainer(RenderLayerModelObject* repaintContainer, const IntRect&, bool immediate = false) const; // Repaint the entire object. Called when, e.g., the color of a border changes, or when a border // style changes. @@ -767,7 +778,7 @@ public: void repaintRectangle(const LayoutRect&, bool immediate = false) const; // Repaint only if our old bounds and new bounds are different. The caller may pass in newBounds and newOutlineBox if they are known. - bool repaintAfterLayoutIfNeeded(RenderBoxModelObject* repaintContainer, const LayoutRect& oldBounds, const LayoutRect& oldOutlineBox, const LayoutRect* newBoundsPtr = 0, const LayoutRect* newOutlineBoxPtr = 0); + bool repaintAfterLayoutIfNeeded(RenderLayerModelObject* repaintContainer, const LayoutRect& oldBounds, const LayoutRect& oldOutlineBox, const LayoutRect* newBoundsPtr = 0, const LayoutRect* newOutlineBoxPtr = 0); // Repaint only if the object moved. virtual void repaintDuringLayoutIfMoved(const LayoutRect&); @@ -784,8 +795,8 @@ public: return clippedOverflowRectForRepaint(0); } IntRect pixelSnappedAbsoluteClippedOverflowRect() const; - virtual LayoutRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) const; - virtual LayoutRect rectWithOutlineForRepaint(RenderBoxModelObject* repaintContainer, LayoutUnit outlineWidth) const; + virtual LayoutRect clippedOverflowRectForRepaint(RenderLayerModelObject* repaintContainer) const; + virtual LayoutRect rectWithOutlineForRepaint(RenderLayerModelObject* repaintContainer, LayoutUnit outlineWidth) const; // Given a rect in the object's coordinate space, compute a rect suitable for repainting // that rect in view coordinates. @@ -795,8 +806,8 @@ public: } // Given a rect in the object's coordinate space, compute a rect suitable for repainting // that rect in the coordinate space of repaintContainer. - virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, LayoutRect&, bool fixed = false) const; - virtual void computeFloatRectForRepaint(RenderBoxModelObject* repaintContainer, FloatRect& repaintRect, bool fixed = false) const; + virtual void computeRectForRepaint(RenderLayerModelObject* repaintContainer, LayoutRect&, bool fixed = false) const; + virtual void computeFloatRectForRepaint(RenderLayerModelObject* repaintContainer, FloatRect& repaintRect, bool fixed = false) const; // If multiple-column layout results in applying an offset to the given point, add the same // offset to the given size. @@ -838,7 +849,7 @@ public: // A single rectangle that encompasses all of the selected objects within this object. Used to determine the tightest // possible bounding box for the selection. LayoutRect selectionRect(bool clipToVisibleContent = true) { return selectionRectForRepaint(0, clipToVisibleContent); } - virtual LayoutRect selectionRectForRepaint(RenderBoxModelObject* /*repaintContainer*/, bool /*clipToVisibleContent*/ = true) { return LayoutRect(); } + virtual LayoutRect selectionRectForRepaint(RenderLayerModelObject* /*repaintContainer*/, bool /*clipToVisibleContent*/ = true) { return LayoutRect(); } virtual bool canBeSelectionLeaf() const { return false; } bool hasSelectedChildren() const { return selectionState() != SelectionNone; } @@ -906,12 +917,12 @@ public: // Map points and quads through elements, potentially via 3d transforms. You should never need to call these directly; use // localToAbsolute/absoluteToLocal methods instead. - virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, TransformState&, MapLocalToContainerFlags mode = ApplyContainerFlip, bool* wasFixed = 0) const; - virtual void mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState&) const; + virtual void mapLocalToContainer(RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = 0) const; + virtual void mapAbsoluteToLocalPoint(MapCoordinatesFlags, TransformState&) const; // Pushes state onto RenderGeometryMap about how to map coordinates from this renderer to its container, or ancestorToStopAt (whichever is encountered first). // Returns the renderer which was mapped to (container or ancestorToStopAt). - virtual const RenderObject* pushMappingToContainer(const RenderBoxModelObject* ancestorToStopAt, RenderGeometryMap&) const; + virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const; bool shouldUseTransformFromContainer(const RenderObject* container) const; void getTransformFromContainer(const RenderObject* container, const LayoutSize& offsetInContainer, TransformationMatrix&) const; @@ -955,7 +966,7 @@ protected: virtual void willBeDestroyed(); void arenaDelete(RenderArena*, void* objectBase); - virtual LayoutRect outlineBoundsForRepaint(RenderBoxModelObject* /*repaintContainer*/, LayoutPoint* /*cachedOffsetToRepaintContainer*/ = 0) const { return LayoutRect(); } + virtual LayoutRect outlineBoundsForRepaint(RenderLayerModelObject* /*repaintContainer*/, LayoutPoint* /*cachedOffsetToRepaintContainer*/ = 0) const { return LayoutRect(); } virtual bool canBeReplacedWithInlineRunIn() const; @@ -963,7 +974,7 @@ protected: virtual void willBeRemovedFromTree(); private: - RenderStyle* firstLineStyleSlowCase() const; + RenderStyle* cachedFirstLineStyle() const; StyleDifference adjustStyleDifference(StyleDifference, unsigned contextSensitiveProperties) const; Color selectionColor(int colorProperty) const; diff --git a/Source/WebCore/rendering/RenderObjectChildList.cpp b/Source/WebCore/rendering/RenderObjectChildList.cpp index c3b4d4831..fec10c1ed 100644 --- a/Source/WebCore/rendering/RenderObjectChildList.cpp +++ b/Source/WebCore/rendering/RenderObjectChildList.cpp @@ -45,6 +45,8 @@ namespace WebCore { +bool RenderObjectChildList::s_enableUpdateBeforeAfterContent = true; + void RenderObjectChildList::destroyLeftoverChildren() { while (firstChild()) { @@ -374,6 +376,8 @@ void RenderObjectChildList::updateBeforeAfterContent(RenderObject* owner, Pseudo // In CSS2, before/after pseudo-content cannot nest. Check this first. if (owner->style()->styleType() == BEFORE || owner->style()->styleType() == AFTER) return; + if (!s_enableUpdateBeforeAfterContent) + return; if (!styledObject) styledObject = owner; diff --git a/Source/WebCore/rendering/RenderObjectChildList.h b/Source/WebCore/rendering/RenderObjectChildList.h index 63b733de0..3f606db8d 100644 --- a/Source/WebCore/rendering/RenderObjectChildList.h +++ b/Source/WebCore/rendering/RenderObjectChildList.h @@ -60,6 +60,9 @@ public: RenderObject* beforePseudoElementRenderer(const RenderObject* owner) const; RenderObject* afterPseudoElementRenderer(const RenderObject* owner) const; +public: + static bool s_enableUpdateBeforeAfterContent; + private: void updateBeforeAfterStyle(RenderObject* child, PseudoId type, RenderStyle* pseudoElementStyle); diff --git a/Source/WebCore/rendering/RenderRegion.cpp b/Source/WebCore/rendering/RenderRegion.cpp index 8a7487d7c..1c5ddbeeb 100644 --- a/Source/WebCore/rendering/RenderRegion.cpp +++ b/Source/WebCore/rendering/RenderRegion.cpp @@ -336,7 +336,7 @@ RenderBoxRegionInfo* RenderRegion::setRenderBoxRegionInfo(const RenderBox* box, if (!m_isValid || !m_flowThread) return 0; - OwnPtr<RenderBoxRegionInfo>& boxInfo = m_renderBoxRegionInfo.add(box, nullptr).iterator->second; + OwnPtr<RenderBoxRegionInfo>& boxInfo = m_renderBoxRegionInfo.add(box, nullptr).iterator->value; if (boxInfo) *boxInfo = RenderBoxRegionInfo(logicalLeftInset, logicalRightInset, containingBlockChainIsInset); else @@ -401,8 +401,8 @@ void RenderRegion::setRegionObjectsRegionStyle() RefPtr<RenderStyle> objectStyleInRegion; bool objectRegionStyleCached = false; if (it != m_renderObjectRegionStyle.end()) { - objectStyleInRegion = it->second.style; - ASSERT(it->second.cached); + objectStyleInRegion = it->value.style; + ASSERT(it->value.cached); objectRegionStyleCached = true; } else objectStyleInRegion = computeStyleInRegion(object); @@ -420,12 +420,12 @@ void RenderRegion::restoreRegionObjectsOriginalStyle() RenderObjectRegionStyleMap temp; for (RenderObjectRegionStyleMap::iterator iter = m_renderObjectRegionStyle.begin(), end = m_renderObjectRegionStyle.end(); iter != end; ++iter) { - RenderObject* object = const_cast<RenderObject*>(iter->first); + RenderObject* object = const_cast<RenderObject*>(iter->key); RefPtr<RenderStyle> objectRegionStyle = object->style(); - RefPtr<RenderStyle> objectOriginalStyle = iter->second.style; + RefPtr<RenderStyle> objectOriginalStyle = iter->value.style; object->setStyleInternal(objectOriginalStyle); - bool shouldCacheRegionStyle = iter->second.cached; + bool shouldCacheRegionStyle = iter->value.cached; if (!shouldCacheRegionStyle) { // Check whether we should cache the computed style in region. unsigned changedContextSensitiveProperties = ContextSensitivePropertyNone; @@ -482,7 +482,7 @@ void RenderRegion::computeChildrenStyleInRegion(const RenderObject* object) RefPtr<RenderStyle> childStyleInRegion; bool objectRegionStyleCached = false; if (it != m_renderObjectRegionStyle.end()) { - childStyleInRegion = it->second.style; + childStyleInRegion = it->value.style; objectRegionStyleCached = true; } else { if (child->isAnonymous()) diff --git a/Source/WebCore/rendering/RenderReplaced.cpp b/Source/WebCore/rendering/RenderReplaced.cpp index 1ebb1526e..c2fff626c 100644 --- a/Source/WebCore/rendering/RenderReplaced.cpp +++ b/Source/WebCore/rendering/RenderReplaced.cpp @@ -496,7 +496,7 @@ VisiblePosition RenderReplaced::positionForPoint(const LayoutPoint& point) return RenderBox::positionForPoint(point); } -LayoutRect RenderReplaced::selectionRectForRepaint(RenderBoxModelObject* repaintContainer, bool clipToVisibleContent) +LayoutRect RenderReplaced::selectionRectForRepaint(RenderLayerModelObject* repaintContainer, bool clipToVisibleContent) { ASSERT(!needsLayout()); @@ -561,7 +561,7 @@ bool RenderReplaced::isSelected() const return false; } -LayoutRect RenderReplaced::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) const +LayoutRect RenderReplaced::clippedOverflowRectForRepaint(RenderLayerModelObject* repaintContainer) const { if (style()->visibility() != VISIBLE && !enclosingLayer()->hasVisibleContent()) return LayoutRect(); diff --git a/Source/WebCore/rendering/RenderReplaced.h b/Source/WebCore/rendering/RenderReplaced.h index 7826ceba3..6a242157f 100644 --- a/Source/WebCore/rendering/RenderReplaced.h +++ b/Source/WebCore/rendering/RenderReplaced.h @@ -71,13 +71,13 @@ private: virtual void computePreferredLogicalWidths(); virtual void paintReplaced(PaintInfo&, const LayoutPoint&) { } - virtual LayoutRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) const; + virtual LayoutRect clippedOverflowRectForRepaint(RenderLayerModelObject* repaintContainer) const OVERRIDE; virtual VisiblePosition positionForPoint(const LayoutPoint&); virtual bool canBeSelectionLeaf() const { return true; } - virtual LayoutRect selectionRectForRepaint(RenderBoxModelObject* repaintContainer, bool clipToVisibleContent = true); + virtual LayoutRect selectionRectForRepaint(RenderLayerModelObject* repaintContainer, bool clipToVisibleContent = true) OVERRIDE; void computeAspectRatioInformationForRenderBox(RenderBox*, FloatSize& constrainedSize, double& intrinsicRatio, bool& isPercentageIntrinsicSize) const; mutable IntSize m_intrinsicSize; diff --git a/Source/WebCore/rendering/RenderSelectionInfo.h b/Source/WebCore/rendering/RenderSelectionInfo.h index a513372df..50dff70aa 100644 --- a/Source/WebCore/rendering/RenderSelectionInfo.h +++ b/Source/WebCore/rendering/RenderSelectionInfo.h @@ -48,12 +48,12 @@ public: } RenderObject* object() const { return m_object; } - RenderBoxModelObject* repaintContainer() const { return m_repaintContainer; } + RenderLayerModelObject* repaintContainer() const { return m_repaintContainer; } RenderObject::SelectionState state() const { return m_state; } protected: RenderObject* m_object; - RenderBoxModelObject* m_repaintContainer; + RenderLayerModelObject* m_repaintContainer; RenderObject::SelectionState m_state; }; diff --git a/Source/WebCore/rendering/RenderSnapshottedPlugIn.cpp b/Source/WebCore/rendering/RenderSnapshottedPlugIn.cpp new file mode 100644 index 000000000..a7a9f4aee --- /dev/null +++ b/Source/WebCore/rendering/RenderSnapshottedPlugIn.cpp @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "RenderSnapshottedPlugIn.h" + +#include "Cursor.h" +#include "FrameLoaderClient.h" +#include "FrameView.h" +#include "Gradient.h" +#include "HTMLPlugInImageElement.h" +#include "MouseEvent.h" +#include "PaintInfo.h" +#include "Path.h" + +namespace WebCore { + +RenderSnapshottedPlugIn::RenderSnapshottedPlugIn(HTMLPlugInImageElement* element) + : RenderEmbeddedObject(element) + , m_snapshotResource(RenderImageResource::create()) +{ + m_snapshotResource->initialize(this); +} + +RenderSnapshottedPlugIn::~RenderSnapshottedPlugIn() +{ + ASSERT(m_snapshotResource); + m_snapshotResource->shutdown(); +} + +HTMLPlugInImageElement* RenderSnapshottedPlugIn::plugInImageElement() const +{ + return static_cast<HTMLPlugInImageElement*>(node()); +} + +void RenderSnapshottedPlugIn::updateSnapshot(PassRefPtr<Image> image) +{ + // Zero-size plugins will have no image. + if (!image) + return; + + m_snapshotResource->setCachedImage(new CachedImage(image.get())); + repaint(); +} + +void RenderSnapshottedPlugIn::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset) +{ + if (plugInImageElement()->displayState() < HTMLPlugInElement::Playing) { + RenderReplaced::paint(paintInfo, paintOffset); + return; + } + + RenderEmbeddedObject::paint(paintInfo, paintOffset); +} + +void RenderSnapshottedPlugIn::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOffset) +{ + if (plugInImageElement()->displayState() < HTMLPlugInElement::Playing) { + paintReplacedSnapshot(paintInfo, paintOffset); + theme()->paintPlugInSnapshotOverlay(this, paintInfo, paintOffset); + return; + } + + RenderEmbeddedObject::paintReplaced(paintInfo, paintOffset); +} + +void RenderSnapshottedPlugIn::paintReplacedSnapshot(PaintInfo& paintInfo, const LayoutPoint& paintOffset) +{ + // This code should be similar to RenderImage::paintReplaced() and RenderImage::paintIntoRect(). + LayoutUnit cWidth = contentWidth(); + LayoutUnit cHeight = contentHeight(); + if (!cWidth || !cHeight) + return; + + RefPtr<Image> image = m_snapshotResource->image(); + if (!image || image->isNull()) + return; + + GraphicsContext* context = paintInfo.context; +#if PLATFORM(MAC) + if (style()->highlight() != nullAtom && !context->paintingDisabled()) + paintCustomHighlight(toPoint(paintOffset - location()), style()->highlight(), true); +#endif + + LayoutSize contentSize(cWidth, cHeight); + LayoutPoint contentLocation = paintOffset; + contentLocation.move(borderLeft() + paddingLeft(), borderTop() + paddingTop()); + + LayoutRect rect(contentLocation, contentSize); + IntRect alignedRect = pixelSnappedIntRect(rect); + if (alignedRect.width() <= 0 || alignedRect.height() <= 0) + return; + + bool useLowQualityScaling = shouldPaintAtLowQuality(context, image.get(), image.get(), alignedRect.size()); + context->drawImage(image.get(), style()->colorSpace(), alignedRect, CompositeSourceOver, shouldRespectImageOrientation(), useLowQualityScaling); +} + +CursorDirective RenderSnapshottedPlugIn::getCursor(const LayoutPoint& point, Cursor& overrideCursor) const +{ + if (plugInImageElement()->displayState() < HTMLPlugInElement::Playing) { + overrideCursor = handCursor(); + return SetCursor; + } + return RenderEmbeddedObject::getCursor(point, overrideCursor); +} + +void RenderSnapshottedPlugIn::handleEvent(Event* event) +{ + if (!event->isMouseEvent()) + return; + + MouseEvent* mouseEvent = static_cast<MouseEvent*>(event); + if (event->type() == eventNames().clickEvent && mouseEvent->button() == LeftButton) { + plugInImageElement()->setDisplayState(HTMLPlugInElement::Playing); + if (widget()) { + if (Frame* frame = document()->frame()) + frame->loader()->client()->recreatePlugin(widget()); + repaint(); + } + event->setDefaultHandled(); + } +} + +} // namespace WebCore diff --git a/Source/WebCore/rendering/RenderSnapshottedPlugIn.h b/Source/WebCore/rendering/RenderSnapshottedPlugIn.h new file mode 100644 index 000000000..6a13a3a3f --- /dev/null +++ b/Source/WebCore/rendering/RenderSnapshottedPlugIn.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef RenderSnapshottedPlugIn_h +#define RenderSnapshottedPlugIn_h + +#include "RenderEmbeddedObject.h" + +#include "RenderImageResource.h" +#include "RenderTheme.h" + +namespace WebCore { + +class HTMLPlugInImageElement; + +class RenderSnapshottedPlugIn : public RenderEmbeddedObject { +public: + RenderSnapshottedPlugIn(HTMLPlugInImageElement*); + virtual ~RenderSnapshottedPlugIn(); + + void updateSnapshot(PassRefPtr<Image>); + + void handleEvent(Event*); + +private: + HTMLPlugInImageElement* plugInImageElement() const; + virtual const char* renderName() const { return "RenderSnapshottedPlugIn"; } + + virtual CursorDirective getCursor(const LayoutPoint&, Cursor&) const OVERRIDE; + virtual bool isSnapshottedPlugIn() const OVERRIDE { return true; } + virtual void paint(PaintInfo&, const LayoutPoint&) OVERRIDE; + virtual void paintReplaced(PaintInfo&, const LayoutPoint&) OVERRIDE; + void paintReplacedSnapshot(PaintInfo&, const LayoutPoint&); + + OwnPtr<RenderImageResource> m_snapshotResource; +}; + +inline RenderSnapshottedPlugIn* toRenderSnapshottedPlugIn(RenderObject* object) +{ + ASSERT(!object || object->isSnapshottedPlugIn()); + return static_cast<RenderSnapshottedPlugIn*>(object); +} + +// This will catch anyone doing an unnecessary cast. +void toRenderSnapshottedPlugIn(const RenderSnapshottedPlugIn*); + +} // namespace WebCore + +#endif // RenderSnapshottedPlugIn_h diff --git a/Source/WebCore/rendering/RenderTable.cpp b/Source/WebCore/rendering/RenderTable.cpp index be0046611..1caffb954 100644 --- a/Source/WebCore/rendering/RenderTable.cpp +++ b/Source/WebCore/rendering/RenderTable.cpp @@ -255,10 +255,20 @@ void RenderTable::updateLogicalWidth() // Ensure we aren't smaller than our min preferred width. setLogicalWidth(max<int>(logicalWidth(), minPreferredLogicalWidth())); + + // Ensure we aren't bigger than our max-width style. + Length styleMaxLogicalWidth = style()->logicalMaxWidth(); + if (styleMaxLogicalWidth.isSpecified() && !styleMaxLogicalWidth.isNegative()) { + LayoutUnit computedMaxLogicalWidth = convertStyleLogicalWidthToComputedWidth(styleMaxLogicalWidth, availableLogicalWidth); + setLogicalWidth(min<int>(logicalWidth(), computedMaxLogicalWidth)); + } + // Ensure we aren't smaller than our min-width style. Length styleMinLogicalWidth = style()->logicalMinWidth(); - if (styleMinLogicalWidth.isSpecified() && styleMinLogicalWidth.isPositive()) - setLogicalWidth(max<int>(logicalWidth(), convertStyleLogicalWidthToComputedWidth(styleMinLogicalWidth, availableLogicalWidth))); + if (styleMinLogicalWidth.isSpecified() && !styleMinLogicalWidth.isNegative()) { + LayoutUnit computedMinLogicalWidth = convertStyleLogicalWidthToComputedWidth(styleMinLogicalWidth, availableLogicalWidth); + setLogicalWidth(max<int>(logicalWidth(), computedMinLogicalWidth)); + } // Finally, with our true width determined, compute our margins for real. setMarginStart(0); @@ -754,10 +764,9 @@ RenderTableCol* RenderTable::firstColumn() const return 0; } -RenderTableCol* RenderTable::colElement(unsigned col, bool* startEdge, bool* endEdge) const +RenderTableCol* RenderTable::slowColElement(unsigned col, bool* startEdge, bool* endEdge) const { - if (!m_hasColElements) - return 0; + ASSERT(m_hasColElements); unsigned columnCount = 0; for (RenderTableCol* columnRenderer = firstColumn(); columnRenderer; columnRenderer = columnRenderer->nextColumn()) { diff --git a/Source/WebCore/rendering/RenderTable.h b/Source/WebCore/rendering/RenderTable.h index 5878017db..f58f1cb63 100644 --- a/Source/WebCore/rendering/RenderTable.h +++ b/Source/WebCore/rendering/RenderTable.h @@ -198,7 +198,13 @@ public: // Return the first column or column-group. RenderTableCol* firstColumn() const; - RenderTableCol* colElement(unsigned col, bool* startEdge = 0, bool* endEdge = 0) const; + RenderTableCol* colElement(unsigned col, bool* startEdge = 0, bool* endEdge = 0) const + { + // The common case is to not have columns, make that case fast. + if (!m_hasColElements) + return 0; + return slowColElement(col, startEdge, endEdge); + } bool needsSectionRecalc() const { return m_needsSectionRecalc; } void setNeedsSectionRecalc() @@ -267,6 +273,8 @@ private: virtual LayoutUnit firstLineBoxBaseline() const OVERRIDE; virtual LayoutUnit lastLineBoxBaseline() const OVERRIDE; + RenderTableCol* slowColElement(unsigned col, bool* startEdge, bool* endEdge) const; + virtual RenderBlock* firstLineBlock() const; virtual void updateFirstLetter(); diff --git a/Source/WebCore/rendering/RenderTableCell.cpp b/Source/WebCore/rendering/RenderTableCell.cpp index 3c0e3e3bd..f53fb070a 100644 --- a/Source/WebCore/rendering/RenderTableCell.cpp +++ b/Source/WebCore/rendering/RenderTableCell.cpp @@ -36,20 +36,35 @@ #include "StyleInheritedData.h" #include "TransformState.h" +#if ENABLE(MATHML) +#include "MathMLElement.h" +#include "MathMLNames.h" +#endif + using namespace std; namespace WebCore { using namespace HTMLNames; +struct SameSizeAsRenderTableCell : public RenderBlock { + unsigned bitfields; + int paddings[2]; +}; + +COMPILE_ASSERT(sizeof(RenderTableCell) == sizeof(SameSizeAsRenderTableCell), RenderTableCell_should_stay_small); +COMPILE_ASSERT(sizeof(CollapsedBorderValue) == 8, CollapsedBorderValue_should_stay_small); + RenderTableCell::RenderTableCell(Node* node) : RenderBlock(node) , m_column(unsetColumnIndex) , m_cellWidthChanged(false) - , m_hasAssociatedTableCellElement(node && (node->hasTagName(tdTag) || node->hasTagName(thTag))) , m_intrinsicPaddingBefore(0) , m_intrinsicPaddingAfter(0) { + // We only update the flags when notified of DOM changes in colSpanOrRowSpanChanged() + // so we need to set their initial values here in case something asks for colSpan()/rowSpan() before then. + updateColAndRowSpanFlags(); } void RenderTableCell::willBeRemovedFromTree() @@ -60,90 +75,86 @@ void RenderTableCell::willBeRemovedFromTree() section()->removeCachedCollapsedBorders(this); } -unsigned RenderTableCell::colSpan() const +unsigned RenderTableCell::parseColSpanFromDOM() const { - if (UNLIKELY(!m_hasAssociatedTableCellElement)) - return 1; - - return toHTMLTableCellElement(node())->colSpan(); + ASSERT(node()); + if (node()->hasTagName(tdTag) || node()->hasTagName(thTag)) + return toHTMLTableCellElement(node())->colSpan(); +#if ENABLE(MATHML) + if (node()->hasTagName(MathMLNames::mtdTag)) + return toMathMLElement(node())->colSpan(); +#endif + return 1; } -unsigned RenderTableCell::rowSpan() const +unsigned RenderTableCell::parseRowSpanFromDOM() const { - if (UNLIKELY(!m_hasAssociatedTableCellElement)) - return 1; + ASSERT(node()); + if (node()->hasTagName(tdTag) || node()->hasTagName(thTag)) + return toHTMLTableCellElement(node())->rowSpan(); +#if ENABLE(MATHML) + if (node()->hasTagName(MathMLNames::mtdTag)) + return toMathMLElement(node())->rowSpan(); +#endif + return 1; +} - return toHTMLTableCellElement(node())->rowSpan(); +void RenderTableCell::updateColAndRowSpanFlags() +{ + // The vast majority of table cells do not have a colspan or rowspan, + // so we keep a bool to know if we need to bother reading from the DOM. + m_hasColSpan = node() && parseColSpanFromDOM() != 1; + m_hasRowSpan = node() && parseRowSpanFromDOM() != 1; } void RenderTableCell::colSpanOrRowSpanChanged() { - ASSERT(m_hasAssociatedTableCellElement); ASSERT(node()); +#if ENABLE(MATHML) + ASSERT(node()->hasTagName(tdTag) || node()->hasTagName(thTag) || node()->hasTagName(MathMLNames::mtdTag)); +#else ASSERT(node()->hasTagName(tdTag) || node()->hasTagName(thTag)); +#endif + + updateColAndRowSpanFlags(); + + // FIXME: I suspect that we could return early here if !m_hasColSpan && !m_hasRowSpan. setNeedsLayoutAndPrefWidthsRecalc(); if (parent() && section()) section()->setNeedsCellRecalc(); } -LayoutUnit RenderTableCell::logicalHeightForRowSizing() const -{ - LayoutUnit adjustedLogicalHeight = logicalHeight() - (intrinsicPaddingBefore() + intrinsicPaddingAfter()); - - LayoutUnit styleLogicalHeight = valueForLength(style()->logicalHeight(), 0, view()); - if (document()->inQuirksMode() || style()->boxSizing() == BORDER_BOX) { - // Explicit heights use the border box in quirks mode. - // Don't adjust height. - } else { - // In strict mode, box-sizing: content-box do the right - // thing and actually add in the border and padding. - LayoutUnit adjustedPaddingBefore = paddingBefore() - intrinsicPaddingBefore(); - LayoutUnit adjustedPaddingAfter = paddingAfter() - intrinsicPaddingAfter(); - styleLogicalHeight += adjustedPaddingBefore + adjustedPaddingAfter + borderBefore() + borderAfter(); - } - - return max(styleLogicalHeight, adjustedLogicalHeight); -} - -Length RenderTableCell::styleOrColLogicalWidth() const +Length RenderTableCell::logicalWidthFromColumns(RenderTableCol* firstColForThisCell, Length widthFromStyle) const { - Length w = style()->logicalWidth(); - if (!w.isAuto()) - return w; - - if (RenderTableCol* tableCol = table()->colElement(col())) { - unsigned colSpanCount = colSpan(); + ASSERT(firstColForThisCell && firstColForThisCell == table()->colElement(col())); + RenderTableCol* tableCol = firstColForThisCell; - Length colWidthSum = Length(0, Fixed); - for (unsigned i = 1; i <= colSpanCount; i++) { - Length colWidth = tableCol->style()->logicalWidth(); - - // Percentage value should be returned only for colSpan == 1. - // Otherwise we return original width for the cell. - if (!colWidth.isFixed()) { - if (colSpanCount > 1) - return w; - return colWidth; - } + unsigned colSpanCount = colSpan(); + int colWidthSum = 0; + for (unsigned i = 1; i <= colSpanCount; i++) { + Length colWidth = tableCol->style()->logicalWidth(); - colWidthSum = Length(colWidthSum.value() + colWidth.value(), Fixed); - - tableCol = tableCol->nextColumn(); - // If no next <col> tag found for the span we just return what we have for now. - if (!tableCol) - break; + // Percentage value should be returned only for colSpan == 1. + // Otherwise we return original width for the cell. + if (!colWidth.isFixed()) { + if (colSpanCount > 1) + return widthFromStyle; + return colWidth; } - // Column widths specified on <col> apply to the border box of the cell. - // Percentages don't need to be handled since they're always treated this way (even when specified on the cells). - // See Bugzilla bug 8126 for details. - if (colWidthSum.isFixed() && colWidthSum.value() > 0) - colWidthSum = Length(max(0.0f, colWidthSum.value() - borderAndPaddingLogicalWidth()), Fixed); - return colWidthSum; + colWidthSum += colWidth.value(); + tableCol = tableCol->nextColumn(); + // If no next <col> tag found for the span we just return what we have for now. + if (!tableCol) + break; } - return w; + // Column widths specified on <col> apply to the border box of the cell, see bug 8126. + // FIXME: Why is border/padding ignored in the negative width case? + if (colWidthSum > 0) + return Length(max(0, colWidthSum - borderAndPaddingLogicalWidth().ceil()), Fixed); + return Length(colWidthSum, Fixed); } void RenderTableCell::computePreferredLogicalWidths() @@ -168,6 +179,47 @@ void RenderTableCell::computePreferredLogicalWidths() } } +void RenderTableCell::computeIntrinsicPadding(int rowHeight) +{ + int oldIntrinsicPaddingBefore = intrinsicPaddingBefore(); + int oldIntrinsicPaddingAfter = intrinsicPaddingAfter(); + int logicalHeightWithoutIntrinsicPadding = pixelSnappedLogicalHeight() - oldIntrinsicPaddingBefore - oldIntrinsicPaddingAfter; + + int intrinsicPaddingBefore = 0; + switch (style()->verticalAlign()) { + case SUB: + case SUPER: + case TEXT_TOP: + case TEXT_BOTTOM: + case LENGTH: + case BASELINE: { + LayoutUnit baseline = cellBaselinePosition(); + if (baseline > borderBefore() + paddingBefore()) + intrinsicPaddingBefore = section()->rowBaseline(rowIndex()) - (baseline - oldIntrinsicPaddingBefore); + break; + } + case TOP: + break; + case MIDDLE: + intrinsicPaddingBefore = (rowHeight - logicalHeightWithoutIntrinsicPadding) / 2; + break; + case BOTTOM: + intrinsicPaddingBefore = rowHeight - logicalHeightWithoutIntrinsicPadding; + break; + case BASELINE_MIDDLE: + break; + } + + int intrinsicPaddingAfter = rowHeight - logicalHeightWithoutIntrinsicPadding - intrinsicPaddingBefore; + setIntrinsicPaddingBefore(intrinsicPaddingBefore); + setIntrinsicPaddingAfter(intrinsicPaddingAfter); + + // FIXME: Changing an intrinsic padding shouldn't trigger a relayout as it only shifts the cell inside the row but + // doesn't change the logical height. + if (intrinsicPaddingBefore != oldIntrinsicPaddingBefore || intrinsicPaddingAfter != oldIntrinsicPaddingAfter) + setNeedsLayout(true, MarkOnlyThis); +} + void RenderTableCell::updateLogicalWidth() { } @@ -247,7 +299,7 @@ LayoutSize RenderTableCell::offsetFromContainer(RenderObject* o, const LayoutPoi return offset; } -LayoutRect RenderTableCell::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) const +LayoutRect RenderTableCell::clippedOverflowRectForRepaint(RenderLayerModelObject* repaintContainer) const { // If the table grid is dirty, we cannot get reliable information about adjoining cells, // so we ignore outside borders. This should not be a problem because it means that @@ -298,7 +350,7 @@ LayoutRect RenderTableCell::clippedOverflowRectForRepaint(RenderBoxModelObject* return r; } -void RenderTableCell::computeRectForRepaint(RenderBoxModelObject* repaintContainer, LayoutRect& r, bool fixed) const +void RenderTableCell::computeRectForRepaint(RenderLayerModelObject* repaintContainer, LayoutRect& r, bool fixed) const { if (repaintContainer == this) return; diff --git a/Source/WebCore/rendering/RenderTableCell.h b/Source/WebCore/rendering/RenderTableCell.h index 713f2c0aa..a873a5197 100644 --- a/Source/WebCore/rendering/RenderTableCell.h +++ b/Source/WebCore/rendering/RenderTableCell.h @@ -30,8 +30,8 @@ namespace WebCore { -static const unsigned unsetColumnIndex = 0x3FFFFFFF; -static const unsigned maxColumnIndex = 0x3FFFFFFE; // 1,073,741,823 +static const unsigned unsetColumnIndex = 0x1FFFFFFF; +static const unsigned maxColumnIndex = 0x1FFFFFFE; // 536,870,910 enum IncludeBorderColorOrNot { DoNotIncludeBorderColor, IncludeBorderColor }; @@ -39,8 +39,18 @@ class RenderTableCell : public RenderBlock { public: explicit RenderTableCell(Node*); - unsigned colSpan() const; - unsigned rowSpan() const; + unsigned colSpan() const + { + if (!m_hasColSpan) + return 1; + return parseColSpanFromDOM(); + } + unsigned rowSpan() const + { + if (!m_hasRowSpan) + return 1; + return parseRowSpanFromDOM(); + } // Called from HTMLTableCellElement. void colSpanOrRowSpanChanged(); @@ -70,9 +80,27 @@ public: return row()->rowIndex(); } - Length styleOrColLogicalWidth() const; + Length styleOrColLogicalWidth() const + { + Length styleWidth = style()->logicalWidth(); + if (!styleWidth.isAuto()) + return styleWidth; + if (RenderTableCol* firstColumn = table()->colElement(col())) + return logicalWidthFromColumns(firstColumn, styleWidth); + return styleWidth; + } - LayoutUnit logicalHeightForRowSizing() const; + LayoutUnit logicalHeightForRowSizing() const + { + // FIXME: This function does too much work, and is very hot during table layout! + LayoutUnit adjustedLogicalHeight = logicalHeight() - (intrinsicPaddingBefore() + intrinsicPaddingAfter()); + LayoutUnit styleLogicalHeight = valueForLength(style()->logicalHeight(), 0, view()); + // In strict mode, box-sizing: content-box do the right thing and actually add in the border and padding. + // Call computedCSSPadding* directly to avoid including implicitPadding. + if (!document()->inQuirksMode() && style()->boxSizing() != BORDER_BOX) + styleLogicalHeight += computedCSSPaddingBefore() + computedCSSPaddingAfter() + borderBefore() + borderAfter(); + return max(styleLogicalHeight, adjustedLogicalHeight); + } virtual void computePreferredLogicalWidths(); @@ -99,9 +127,7 @@ public: LayoutUnit cellBaselinePosition() const; - void setIntrinsicPaddingBefore(int p) { m_intrinsicPaddingBefore = p; } - void setIntrinsicPaddingAfter(int p) { m_intrinsicPaddingAfter = p; } - void setIntrinsicPadding(int before, int after) { setIntrinsicPaddingBefore(before); setIntrinsicPaddingAfter(after); } + void computeIntrinsicPadding(int rowHeight); void clearIntrinsicPadding() { setIntrinsicPadding(0, 0); } int intrinsicPaddingBefore() const { return m_intrinsicPaddingBefore; } @@ -197,8 +223,8 @@ private: virtual bool boxShadowShouldBeAppliedToBackground(BackgroundBleedAvoidance, InlineFlowBox*) const OVERRIDE; virtual LayoutSize offsetFromContainer(RenderObject*, const LayoutPoint&, bool* offsetDependsOnPoint = 0) const; - virtual LayoutRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) const; - virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, LayoutRect&, bool fixed = false) const; + virtual LayoutRect clippedOverflowRectForRepaint(RenderLayerModelObject* repaintContainer) const OVERRIDE; + virtual void computeRectForRepaint(RenderLayerModelObject* repaintContainer, LayoutRect&, bool fixed = false) const OVERRIDE; int borderHalfLeft(bool outer) const; int borderHalfRight(bool outer) const; @@ -210,6 +236,10 @@ private: int borderHalfBefore(bool outer) const; int borderHalfAfter(bool outer) const; + void setIntrinsicPaddingBefore(int p) { m_intrinsicPaddingBefore = p; } + void setIntrinsicPaddingAfter(int p) { m_intrinsicPaddingAfter = p; } + void setIntrinsicPadding(int before, int after) { setIntrinsicPaddingBefore(before); setIntrinsicPaddingAfter(after); } + CollapsedBorderValue collapsedStartBorder(IncludeBorderColorOrNot = IncludeBorderColor) const; CollapsedBorderValue collapsedEndBorder(IncludeBorderColorOrNot = IncludeBorderColor) const; CollapsedBorderValue collapsedBeforeBorder(IncludeBorderColorOrNot = IncludeBorderColor) const; @@ -225,9 +255,18 @@ private: CollapsedBorderValue computeCollapsedBeforeBorder(IncludeBorderColorOrNot = IncludeBorderColor) const; CollapsedBorderValue computeCollapsedAfterBorder(IncludeBorderColorOrNot = IncludeBorderColor) const; - unsigned m_column : 30; - bool m_cellWidthChanged : 1; - bool m_hasAssociatedTableCellElement : 1; + Length logicalWidthFromColumns(RenderTableCol* firstColForThisCell, Length widthFromStyle) const; + + void updateColAndRowSpanFlags(); + + unsigned parseRowSpanFromDOM() const; + unsigned parseColSpanFromDOM() const; + + // Note MSVC will only pack members if they have identical types, hence we use unsigned instead of bool here. + unsigned m_column : 29; + unsigned m_cellWidthChanged : 1; + unsigned m_hasColSpan: 1; + unsigned m_hasRowSpan: 1; int m_intrinsicPaddingBefore; int m_intrinsicPaddingAfter; }; diff --git a/Source/WebCore/rendering/RenderTableCol.cpp b/Source/WebCore/rendering/RenderTableCol.cpp index baf191431..7aa8341a7 100644 --- a/Source/WebCore/rendering/RenderTableCol.cpp +++ b/Source/WebCore/rendering/RenderTableCol.cpp @@ -93,7 +93,7 @@ bool RenderTableCol::canHaveChildren() const return isTableColumnGroup(); } -LayoutRect RenderTableCol::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) const +LayoutRect RenderTableCol::clippedOverflowRectForRepaint(RenderLayerModelObject* repaintContainer) const { // For now, just repaint the whole table. // FIXME: Find a better way to do this, e.g., need to repaint all the cells that we diff --git a/Source/WebCore/rendering/RenderTableCol.h b/Source/WebCore/rendering/RenderTableCol.h index 61f8fa346..1a9fac6ec 100644 --- a/Source/WebCore/rendering/RenderTableCol.h +++ b/Source/WebCore/rendering/RenderTableCol.h @@ -87,7 +87,7 @@ private: virtual bool canHaveChildren() const; virtual bool requiresLayer() const { return false; } - virtual LayoutRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) const; + virtual LayoutRect clippedOverflowRectForRepaint(RenderLayerModelObject* repaintContainer) const OVERRIDE; virtual void imageChanged(WrappedImagePtr, const IntRect* = 0); virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle); diff --git a/Source/WebCore/rendering/RenderTableRow.cpp b/Source/WebCore/rendering/RenderTableRow.cpp index b102f0842..c86f14c2c 100644 --- a/Source/WebCore/rendering/RenderTableRow.cpp +++ b/Source/WebCore/rendering/RenderTableRow.cpp @@ -188,7 +188,7 @@ void RenderTableRow::layout() setNeedsLayout(false); } -LayoutRect RenderTableRow::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) const +LayoutRect RenderTableRow::clippedOverflowRectForRepaint(RenderLayerModelObject* repaintContainer) const { ASSERT(parent()); diff --git a/Source/WebCore/rendering/RenderTableRow.h b/Source/WebCore/rendering/RenderTableRow.h index 12f833baf..80d4c17e6 100644 --- a/Source/WebCore/rendering/RenderTableRow.h +++ b/Source/WebCore/rendering/RenderTableRow.h @@ -97,7 +97,7 @@ private: virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0); virtual void layout(); - virtual LayoutRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) const; + virtual LayoutRect clippedOverflowRectForRepaint(RenderLayerModelObject* repaintContainer) const; virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE; virtual bool requiresLayer() const OVERRIDE { return hasOverflowClip() || hasTransform() || hasHiddenBackface() || hasClipPath() || createsGroup(); } diff --git a/Source/WebCore/rendering/RenderTableSection.cpp b/Source/WebCore/rendering/RenderTableSection.cpp index eb6948921..a9e16675a 100644 --- a/Source/WebCore/rendering/RenderTableSection.cpp +++ b/Source/WebCore/rendering/RenderTableSection.cpp @@ -516,8 +516,6 @@ void RenderTableSection::layoutRows() ASSERT(!needsLayout()); - int rHeight; - unsigned rindx; unsigned totalRows = m_grid.size(); // Set the width of our section now. The rows will also be this width. @@ -549,9 +547,9 @@ void RenderTableSection::layoutRows() if (!cell || cs.inColSpan) continue; - rindx = cell->rowIndex(); - rHeight = m_rowPos[rindx + cell->rowSpan()] - m_rowPos[rindx] - vspacing; - + int rowIndex = cell->rowIndex(); + int rHeight = m_rowPos[rowIndex + cell->rowSpan()] - m_rowPos[rowIndex] - vspacing; + // Force percent height children to lay themselves out again. // This will cause these children to grow to fill the cell. // FIXME: There is still more work to do here to fully match WinIE (should @@ -616,46 +614,12 @@ void RenderTableSection::layoutRows() } } - int oldIntrinsicPaddingBefore = cell->intrinsicPaddingBefore(); - int oldIntrinsicPaddingAfter = cell->intrinsicPaddingAfter(); - int logicalHeightWithoutIntrinsicPadding = cell->pixelSnappedLogicalHeight() - oldIntrinsicPaddingBefore - oldIntrinsicPaddingAfter; - - int intrinsicPaddingBefore = 0; - switch (cell->style()->verticalAlign()) { - case SUB: - case SUPER: - case TEXT_TOP: - case TEXT_BOTTOM: - case LENGTH: - case BASELINE: { - LayoutUnit baseline = cell->cellBaselinePosition(); - if (baseline > cell->borderBefore() + cell->paddingBefore()) - intrinsicPaddingBefore = getBaseline(cell->rowIndex()) - (baseline - oldIntrinsicPaddingBefore); - break; - } - case TOP: - break; - case MIDDLE: - intrinsicPaddingBefore = (rHeight - logicalHeightWithoutIntrinsicPadding) / 2; - break; - case BOTTOM: - intrinsicPaddingBefore = rHeight - logicalHeightWithoutIntrinsicPadding; - break; - default: - break; - } - - int intrinsicPaddingAfter = rHeight - logicalHeightWithoutIntrinsicPadding - intrinsicPaddingBefore; - cell->setIntrinsicPaddingBefore(intrinsicPaddingBefore); - cell->setIntrinsicPaddingAfter(intrinsicPaddingAfter); + cell->computeIntrinsicPadding(rHeight); LayoutRect oldCellRect = cell->frameRect(); setLogicalPositionForCell(cell, c); - if (intrinsicPaddingBefore != oldIntrinsicPaddingBefore || intrinsicPaddingAfter != oldIntrinsicPaddingAfter) - cell->setNeedsLayout(true, MarkOnlyThis); - if (!cell->needsLayout() && view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(cell, cell->logicalTop()) != cell->pageLogicalOffset()) cell->setChildNeedsLayout(true, MarkOnlyThis); @@ -1464,7 +1428,7 @@ CollapsedBorderValue& RenderTableSection::cachedCollapsedBorder(const RenderTabl ASSERT(table()->collapseBorders()); HashMap<pair<const RenderTableCell*, int>, CollapsedBorderValue>::iterator it = m_cellsCollapsedBorders.find(make_pair(cell, side)); ASSERT(it != m_cellsCollapsedBorders.end()); - return it->second; + return it->value; } RenderTableSection* RenderTableSection::createAnonymousWithParentRenderer(const RenderObject* parent) diff --git a/Source/WebCore/rendering/RenderTableSection.h b/Source/WebCore/rendering/RenderTableSection.h index ce21a9ef1..02a529994 100644 --- a/Source/WebCore/rendering/RenderTableSection.h +++ b/Source/WebCore/rendering/RenderTableSection.h @@ -173,7 +173,7 @@ public: bool needsCellRecalc() const { return m_needsCellRecalc; } void setNeedsCellRecalc(); - LayoutUnit getBaseline(unsigned row) { return m_grid[row].baseline; } + LayoutUnit rowBaseline(unsigned row) { return m_grid[row].baseline; } void rowLogicalHeightChanged(unsigned rowIndex); diff --git a/Source/WebCore/rendering/RenderText.cpp b/Source/WebCore/rendering/RenderText.cpp index 6aeb4d92d..c4e4a3f7a 100644 --- a/Source/WebCore/rendering/RenderText.cpp +++ b/Source/WebCore/rendering/RenderText.cpp @@ -365,12 +365,12 @@ void RenderText::absoluteRectsForRange(Vector<IntRect>& rects, unsigned start, u r.setX(selectionRect.x()); } } - rects.append(localToAbsoluteQuad(r, false, wasFixed).enclosingBoundingBox()); + rects.append(localToAbsoluteQuad(r, SnapOffsetForTransforms, wasFixed).enclosingBoundingBox()); } else { // FIXME: This code is wrong. It's converting local to absolute twice. http://webkit.org/b/65722 FloatRect rect = localQuadForTextBox(box, start, end, useSelectionHeight); if (!rect.isZero()) - rects.append(localToAbsoluteQuad(rect, false, wasFixed).enclosingBoundingBox()); + rects.append(localToAbsoluteQuad(rect, SnapOffsetForTransforms, wasFixed).enclosingBoundingBox()); } } } @@ -413,7 +413,7 @@ void RenderText::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed, Clippin else boundaries.setHeight(ellipsisRect.maxY() - boundaries.y()); } - quads.append(localToAbsoluteQuad(boundaries, false, wasFixed)); + quads.append(localToAbsoluteQuad(boundaries, SnapOffsetForTransforms, wasFixed)); } } @@ -448,11 +448,11 @@ void RenderText::absoluteQuadsForRange(Vector<FloatQuad>& quads, unsigned start, r.setX(selectionRect.x()); } } - quads.append(localToAbsoluteQuad(r, false, wasFixed)); + quads.append(localToAbsoluteQuad(r, SnapOffsetForTransforms, wasFixed)); } else { FloatRect rect = localQuadForTextBox(box, start, end, useSelectionHeight); if (!rect.isZero()) - quads.append(localToAbsoluteQuad(rect, false, wasFixed)); + quads.append(localToAbsoluteQuad(rect, SnapOffsetForTransforms, wasFixed)); } } } @@ -955,7 +955,7 @@ void RenderText::computePreferredLogicalWidths(float leadWidth, HashSet<const Si float wordSpacing = styleToUse->wordSpacing(); int len = textLength(); const UChar* txt = characters(); - LazyLineBreakIterator breakIterator(txt, len, styleToUse->locale()); + LazyLineBreakIterator breakIterator(m_text, styleToUse->locale()); bool needsWordSpacing = false; bool ignoringSpaces = false; bool isSpace = false; @@ -1256,6 +1256,9 @@ void RenderText::setSelectionState(SelectionState state) void RenderText::setTextWithOffset(PassRefPtr<StringImpl> text, unsigned offset, unsigned len, bool force) { + if (!force && equal(m_text.impl(), text.get())) + return; + unsigned oldLen = textLength(); unsigned newLen = text->length(); int delta = newLen - oldLen; @@ -1328,7 +1331,7 @@ void RenderText::setTextWithOffset(PassRefPtr<StringImpl> text, unsigned offset, } m_linesDirty = dirtiedLines; - setText(text, force); + setText(text, force || dirtiedLines); } void RenderText::transformText() @@ -1620,7 +1623,7 @@ LayoutRect RenderText::linesVisualOverflowBoundingBox() const return rect; } -LayoutRect RenderText::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) const +LayoutRect RenderText::clippedOverflowRectForRepaint(RenderLayerModelObject* repaintContainer) const { RenderObject* rendererToRepaint = containingBlock(); @@ -1636,7 +1639,7 @@ LayoutRect RenderText::clippedOverflowRectForRepaint(RenderBoxModelObject* repai return rendererToRepaint->clippedOverflowRectForRepaint(repaintContainer); } -LayoutRect RenderText::selectionRectForRepaint(RenderBoxModelObject* repaintContainer, bool clipToVisibleContent) +LayoutRect RenderText::selectionRectForRepaint(RenderLayerModelObject* repaintContainer, bool clipToVisibleContent) { ASSERT(!needsLayout()); diff --git a/Source/WebCore/rendering/RenderText.h b/Source/WebCore/rendering/RenderText.h index 6fc4c67a7..4cf9c4e2a 100644 --- a/Source/WebCore/rendering/RenderText.h +++ b/Source/WebCore/rendering/RenderText.h @@ -103,13 +103,13 @@ public: virtual bool canBeSelectionLeaf() const { return true; } virtual void setSelectionState(SelectionState s); - virtual LayoutRect selectionRectForRepaint(RenderBoxModelObject* repaintContainer, bool clipToVisibleContent = true); + virtual LayoutRect selectionRectForRepaint(RenderLayerModelObject* repaintContainer, bool clipToVisibleContent = true) OVERRIDE; virtual LayoutRect localCaretRect(InlineBox*, int caretOffset, LayoutUnit* extraWidthToEndOfLine = 0); virtual LayoutUnit marginLeft() const { return minimumValueForLength(style()->marginLeft(), 0, view()); } virtual LayoutUnit marginRight() const { return minimumValueForLength(style()->marginRight(), 0, view()); } - virtual LayoutRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) const; + virtual LayoutRect clippedOverflowRectForRepaint(RenderLayerModelObject* repaintContainer) const OVERRIDE; InlineTextBox* firstTextBox() const { return m_firstTextBox; } InlineTextBox* lastTextBox() const { return m_lastTextBox; } diff --git a/Source/WebCore/rendering/RenderTextControl.cpp b/Source/WebCore/rendering/RenderTextControl.cpp index c0d72cda9..35da70455 100644 --- a/Source/WebCore/rendering/RenderTextControl.cpp +++ b/Source/WebCore/rendering/RenderTextControl.cpp @@ -144,20 +144,20 @@ int RenderTextControl::scrollbarThickness() const return ScrollbarTheme::theme()->scrollbarThickness(); } -void RenderTextControl::updateLogicalHeight() +void RenderTextControl::computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues& computedValues) const { HTMLElement* innerText = innerTextElement(); ASSERT(innerText); if (RenderBox* innerTextBox = innerText->renderBox()) { LayoutUnit nonContentHeight = innerTextBox->borderAndPaddingHeight() + innerTextBox->marginHeight(); - setHeight(computeControlHeight(innerTextBox->lineHeight(true, HorizontalLine, PositionOfInteriorLineBoxes), nonContentHeight) + borderAndPaddingHeight()); + logicalHeight = computeControlHeight(innerTextBox->lineHeight(true, HorizontalLine, PositionOfInteriorLineBoxes), nonContentHeight) + borderAndPaddingHeight(); // We are able to have a horizontal scrollbar if the overflow style is scroll, or if its auto and there's no word wrap. if (style()->overflowX() == OSCROLL || (style()->overflowX() == OAUTO && innerText->renderer()->style()->overflowWrap() == NormalOverflowWrap)) - setHeight(height() + scrollbarThickness()); + logicalHeight += scrollbarThickness(); } - RenderBlock::updateLogicalHeight(); + RenderBox::computeLogicalHeight(logicalHeight, logicalTop, computedValues); } void RenderTextControl::hitInnerTextElement(HitTestResult& result, const LayoutPoint& pointInContainer, const LayoutPoint& accumulatedOffset) diff --git a/Source/WebCore/rendering/RenderTextControl.h b/Source/WebCore/rendering/RenderTextControl.h index 4fe4da571..62cf5af5f 100644 --- a/Source/WebCore/rendering/RenderTextControl.h +++ b/Source/WebCore/rendering/RenderTextControl.h @@ -62,7 +62,7 @@ protected: virtual RenderStyle* textBaseStyle() const = 0; virtual void updateFromElement(); - virtual void updateLogicalHeight() OVERRIDE; + virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues&) const OVERRIDE; virtual RenderObject* layoutSpecialExcludedChild(bool relayoutChildren); private: diff --git a/Source/WebCore/rendering/RenderTheme.cpp b/Source/WebCore/rendering/RenderTheme.cpp index e4259c4f7..ed425758d 100644 --- a/Source/WebCore/rendering/RenderTheme.cpp +++ b/Source/WebCore/rendering/RenderTheme.cpp @@ -523,7 +523,7 @@ String RenderTheme::formatMediaControlsRemainingTime(float currentTime, float du IntPoint RenderTheme::volumeSliderOffsetFromMuteButton(RenderBox* muteButtonBox, const IntSize& size) const { int y = -size.height(); - FloatPoint absPoint = muteButtonBox->localToAbsolute(FloatPoint(muteButtonBox->pixelSnappedOffsetLeft(), y), true, true); + FloatPoint absPoint = muteButtonBox->localToAbsolute(FloatPoint(muteButtonBox->pixelSnappedOffsetLeft(), y), IsFixed | UseTransforms | SnapOffsetForTransforms); if (absPoint.y() < 0) y = muteButtonBox->height(); return IntPoint(0, y); @@ -1274,4 +1274,9 @@ String RenderTheme::fileListNameForWidth(const FileList* fileList, const Font& f return StringTruncator::centerTruncate(string, width, font, StringTruncator::EnableRoundingHacks); } +bool RenderTheme::shouldOpenPickerWithF4Key() const +{ + return false; +} + } // namespace WebCore diff --git a/Source/WebCore/rendering/RenderTheme.h b/Source/WebCore/rendering/RenderTheme.h index 6026b6017..5db283605 100644 --- a/Source/WebCore/rendering/RenderTheme.h +++ b/Source/WebCore/rendering/RenderTheme.h @@ -35,6 +35,7 @@ namespace WebCore { +class CSSStyleSheet; class Element; class FileList; class HTMLInputElement; @@ -46,7 +47,7 @@ class RenderMeter; #if ENABLE(PROGRESS_ELEMENT) class RenderProgress; #endif -class CSSStyleSheet; +class RenderSnapshottedPlugIn; class RenderTheme : public RefCounted<RenderTheme> { protected: @@ -137,6 +138,11 @@ public: // A method asking if the platform is able to show datalist suggestions for a given input type. virtual bool supportsDataListUI(const AtomicString&) const { return false; } +#if ENABLE(INPUT_MULTIPLE_FIELDS_UI) && ENABLE(CALENDAR_PICKER) + // A method asking if the platform is able to show a calendar picker for a given input type. + virtual bool supportsCalendarPicker(const AtomicString&) const { return false; } +#endif + // Text selection colors. Color activeSelectionBackgroundColor() const; Color inactiveSelectionBackgroundColor() const; @@ -236,6 +242,10 @@ public: virtual String fileListDefaultLabel(bool multipleFilesAllowed) const; virtual String fileListNameForWidth(const FileList*, const Font&, int width, bool multipleFilesAllowed) const; + virtual void paintPlugInSnapshotOverlay(RenderSnapshottedPlugIn*, const PaintInfo&, const LayoutPoint&) const { } + + virtual bool shouldOpenPickerWithF4Key() const; + protected: // The platform selection color. virtual Color platformActiveSelectionBackgroundColor() const; diff --git a/Source/WebCore/rendering/RenderThemeChromiumAndroid.cpp b/Source/WebCore/rendering/RenderThemeChromiumAndroid.cpp index be3701913..d25a80444 100644 --- a/Source/WebCore/rendering/RenderThemeChromiumAndroid.cpp +++ b/Source/WebCore/rendering/RenderThemeChromiumAndroid.cpp @@ -30,7 +30,6 @@ #include "Color.h" #include "LayoutTestSupport.h" #include "PaintInfo.h" -#include "PlatformSupport.h" #include "RenderMediaControlsChromium.h" #include "RenderObject.h" #include "RenderProgress.h" @@ -38,6 +37,9 @@ #include "ScrollbarTheme.h" #include "UserAgentStyleSheets.h" +#include <public/Platform.h> +#include <public/android/WebThemeEngine.h> + namespace WebCore { PassRefPtr<RenderTheme> RenderThemeChromiumAndroid::create() @@ -81,7 +83,7 @@ void RenderThemeChromiumAndroid::adjustInnerSpinButtonStyle(StyleResolver*, Rend if (isRunningLayoutTest()) { // Match Chromium Linux spin button style in layout tests. // FIXME: Consider removing the conditional if a future Android theme matches this. - IntSize size = PlatformSupport::getThemePartSize(PlatformSupport::PartInnerSpinButton); + IntSize size = WebKit::Platform::current()->themeEngine()->getSize(WebKit::WebThemeEngine::PartInnerSpinButton); style->setWidth(Length(size.width(), Fixed)); style->setMinWidth(Length(size.width(), Fixed)); @@ -104,7 +106,7 @@ int RenderThemeChromiumAndroid::menuListArrowPadding() const { // We cannot use the scrollbar thickness here, as it's width is 0 on Android. // Instead, use the width of the scrollbar down arrow. - IntSize scrollbarSize = PlatformSupport::getThemePartSize(PlatformSupport::PartScrollbarDownArrow); + IntSize scrollbarSize = WebKit::Platform::current()->themeEngine()->getSize(WebKit::WebThemeEngine::PartScrollbarDownArrow); return scrollbarSize.width(); } diff --git a/Source/WebCore/rendering/RenderThemeChromiumCommon.cpp b/Source/WebCore/rendering/RenderThemeChromiumCommon.cpp index a89d4e6e8..359577ab4 100644 --- a/Source/WebCore/rendering/RenderThemeChromiumCommon.cpp +++ b/Source/WebCore/rendering/RenderThemeChromiumCommon.cpp @@ -42,9 +42,18 @@ bool RenderThemeChromiumCommon::supportsDataListUI(const AtomicString& type) #if ENABLE(CALENDAR_PICKER) || type == InputTypeNames::date() #endif + || type == InputTypeNames::time() || type == InputTypeNames::range(); } +#if ENABLE(INPUT_MULTIPLE_FIELDS_UI) && ENABLE(CALENDAR_PICKER) +bool RenderThemeChromiumCommon::supportsCalendarPicker(const AtomicString& type) +{ + // FIXME: We'd like to support datetime, datetime-local, month, and week too. + return type == InputTypeNames::date(); +} +#endif + LayoutUnit RenderThemeChromiumCommon::sliderTickSnappingThreshold() { return 5; diff --git a/Source/WebCore/rendering/RenderThemeChromiumCommon.h b/Source/WebCore/rendering/RenderThemeChromiumCommon.h index 80aeca952..8c05acf60 100644 --- a/Source/WebCore/rendering/RenderThemeChromiumCommon.h +++ b/Source/WebCore/rendering/RenderThemeChromiumCommon.h @@ -35,6 +35,9 @@ namespace WebCore { class RenderThemeChromiumCommon { public: static bool supportsDataListUI(const AtomicString& type); +#if ENABLE(INPUT_MULTIPLE_FIELDS_UI) && ENABLE(CALENDAR_PICKER) + static bool supportsCalendarPicker(const AtomicString& type); +#endif static LayoutUnit sliderTickSnappingThreshold(); }; diff --git a/Source/WebCore/rendering/RenderThemeChromiumLinux.cpp b/Source/WebCore/rendering/RenderThemeChromiumLinux.cpp index 3dae06e07..8af4fc782 100644 --- a/Source/WebCore/rendering/RenderThemeChromiumLinux.cpp +++ b/Source/WebCore/rendering/RenderThemeChromiumLinux.cpp @@ -28,12 +28,15 @@ #include "CSSValueKeywords.h" #include "Color.h" #include "PaintInfo.h" -#include "PlatformSupport.h" +#include "PlatformContextSkia.h" #include "RenderObject.h" #include "RenderProgress.h" #include "RenderSlider.h" #include "ScrollbarTheme.h" #include "UserAgentStyleSheets.h" +#include <public/Platform.h> +#include <public/WebRect.h> +#include <public/linux/WebThemeEngine.h> namespace WebCore { @@ -50,19 +53,18 @@ double RenderThemeChromiumLinux::m_caretBlinkInterval; static const unsigned defaultButtonBackgroundColor = 0xffdddddd; -static PlatformSupport::ThemePaintState getWebThemeState(const RenderTheme* theme, const RenderObject* o) +static WebKit::WebThemeEngine::State getWebThemeState(const RenderTheme* theme, const RenderObject* o) { if (!theme->isEnabled(o)) - return PlatformSupport::StateDisabled; + return WebKit::WebThemeEngine::StateDisabled; if (theme->isPressed(o)) - return PlatformSupport::StatePressed; + return WebKit::WebThemeEngine::StatePressed; if (theme->isHovered(o)) - return PlatformSupport::StateHover; + return WebKit::WebThemeEngine::StateHover; - return PlatformSupport::StateNormal; + return WebKit::WebThemeEngine::StateNormal; } - PassRefPtr<RenderTheme> RenderThemeChromiumLinux::create() { return adoptRef(new RenderThemeChromiumLinux()); @@ -160,7 +162,7 @@ int RenderThemeChromiumLinux::sliderTickOffsetFromTrackCenter() const void RenderThemeChromiumLinux::adjustSliderThumbSize(RenderStyle* style, Element* element) const { - IntSize size = PlatformSupport::getThemePartSize(PlatformSupport::PartSliderThumb); + IntSize size = WebKit::Platform::current()->themeEngine()->getSize(WebKit::WebThemeEngine::PartSliderThumb); if (style->appearance() == SliderThumbHorizontalPart) { style->setWidth(Length(size.width(), Fixed)); @@ -201,11 +203,12 @@ void RenderThemeChromiumLinux::setSelectionColors( bool RenderThemeChromiumLinux::paintCheckbox(RenderObject* o, const PaintInfo& i, const IntRect& rect) { - PlatformSupport::ThemePaintExtraParams extraParams; + WebKit::WebThemeEngine::ExtraParams extraParams; + WebKit::WebCanvas* canvas = i.context->platformContext()->canvas(); extraParams.button.checked = isChecked(o); extraParams.button.indeterminate = isIndeterminate(o); - PlatformSupport::paintThemePart(i.context, PlatformSupport::PartCheckbox, getWebThemeState(this, o), rect, &extraParams); + WebKit::Platform::current()->themeEngine()->paint(canvas, WebKit::WebThemeEngine::PartCheckbox, getWebThemeState(this, o), WebKit::WebRect(rect), &extraParams); return false; } @@ -215,16 +218,17 @@ void RenderThemeChromiumLinux::setCheckboxSize(RenderStyle* style) const if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto()) return; - IntSize size = PlatformSupport::getThemePartSize(PlatformSupport::PartCheckbox); + IntSize size = WebKit::Platform::current()->themeEngine()->getSize(WebKit::WebThemeEngine::PartCheckbox); setSizeIfAuto(style, size); } bool RenderThemeChromiumLinux::paintRadio(RenderObject* o, const PaintInfo& i, const IntRect& rect) { - PlatformSupport::ThemePaintExtraParams extraParams; + WebKit::WebThemeEngine::ExtraParams extraParams; + WebKit::WebCanvas* canvas = i.context->platformContext()->canvas(); extraParams.button.checked = isChecked(o); - PlatformSupport::paintThemePart(i.context, PlatformSupport::PartRadio, getWebThemeState(this, o), rect, &extraParams); + WebKit::Platform::current()->themeEngine()->paint(canvas, WebKit::WebThemeEngine::PartRadio, getWebThemeState(this, o), WebKit::WebRect(rect), &extraParams); return false; } @@ -234,20 +238,21 @@ void RenderThemeChromiumLinux::setRadioSize(RenderStyle* style) const if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto()) return; - IntSize size = PlatformSupport::getThemePartSize(PlatformSupport::PartRadio); + IntSize size = WebKit::Platform::current()->themeEngine()->getSize(WebKit::WebThemeEngine::PartRadio); setSizeIfAuto(style, size); } bool RenderThemeChromiumLinux::paintButton(RenderObject* o, const PaintInfo& i, const IntRect& rect) { - PlatformSupport::ThemePaintExtraParams extraParams; + WebKit::WebThemeEngine::ExtraParams extraParams; + WebKit::WebCanvas* canvas = i.context->platformContext()->canvas(); extraParams.button.isDefault = isDefault(o); extraParams.button.hasBorder = true; extraParams.button.backgroundColor = defaultButtonBackgroundColor; if (o->hasBackground()) extraParams.button.backgroundColor = o->style()->visitedDependentColor(CSSPropertyBackgroundColor).rgb(); - PlatformSupport::paintThemePart(i.context, PlatformSupport::PartButton, getWebThemeState(this, o), rect, &extraParams); + WebKit::Platform::current()->themeEngine()->paint(canvas, WebKit::WebThemeEngine::PartButton, getWebThemeState(this, o), WebKit::WebRect(rect), &extraParams); return false; } @@ -260,17 +265,19 @@ bool RenderThemeChromiumLinux::paintTextField(RenderObject* o, const PaintInfo& ControlPart part = o->style()->appearance(); - PlatformSupport::ThemePaintExtraParams extraParams; + WebKit::WebThemeEngine::ExtraParams extraParams; extraParams.textField.isTextArea = part == TextAreaPart; extraParams.textField.isListbox = part == ListboxPart; + WebKit::WebCanvas* canvas = i.context->platformContext()->canvas(); + // Fallback to white if the specified color object is invalid. Color backgroundColor(Color::white); if (o->style()->visitedDependentColor(CSSPropertyBackgroundColor).isValid()) backgroundColor = o->style()->visitedDependentColor(CSSPropertyBackgroundColor); extraParams.textField.backgroundColor = backgroundColor.rgb(); - PlatformSupport::paintThemePart(i.context, PlatformSupport::PartTextField, getWebThemeState(this, o), rect, &extraParams); + WebKit::Platform::current()->themeEngine()->paint(canvas, WebKit::WebThemeEngine::PartTextField, getWebThemeState(this, o), WebKit::WebRect(rect), &extraParams); return false; } @@ -282,7 +289,7 @@ bool RenderThemeChromiumLinux::paintMenuList(RenderObject* o, const PaintInfo& i const int right = rect.x() + rect.width(); const int middle = rect.y() + rect.height() / 2; - PlatformSupport::ThemePaintExtraParams extraParams; + WebKit::WebThemeEngine::ExtraParams extraParams; extraParams.menuList.arrowX = (o->style()->direction() == RTL) ? rect.x() + 7 : right - 13; extraParams.menuList.arrowY = middle; const RenderBox* box = toRenderBox(o); @@ -294,16 +301,19 @@ bool RenderThemeChromiumLinux::paintMenuList(RenderObject* o, const PaintInfo& i if (o->hasBackground()) extraParams.menuList.backgroundColor = o->style()->visitedDependentColor(CSSPropertyBackgroundColor).rgb(); - PlatformSupport::paintThemePart(i.context, PlatformSupport::PartMenuList, getWebThemeState(this, o), rect, &extraParams); + WebKit::WebCanvas* canvas = i.context->platformContext()->canvas(); + + WebKit::Platform::current()->themeEngine()->paint(canvas, WebKit::WebThemeEngine::PartMenuList, getWebThemeState(this, o), WebKit::WebRect(rect), &extraParams); return false; } bool RenderThemeChromiumLinux::paintSliderTrack(RenderObject* o, const PaintInfo& i, const IntRect& rect) { - PlatformSupport::ThemePaintExtraParams extraParams; + WebKit::WebThemeEngine::ExtraParams extraParams; + WebKit::WebCanvas* canvas = i.context->platformContext()->canvas(); extraParams.slider.vertical = o->style()->appearance() == SliderVerticalPart; - PlatformSupport::paintThemePart(i.context, PlatformSupport::PartSliderTrack, getWebThemeState(this, o), rect, &extraParams); + WebKit::Platform::current()->themeEngine()->paint(canvas, WebKit::WebThemeEngine::PartSliderTrack, getWebThemeState(this, o), WebKit::WebRect(rect), &extraParams); #if ENABLE(DATALIST_ELEMENT) paintSliderTicks(o, i, rect); @@ -314,17 +324,18 @@ bool RenderThemeChromiumLinux::paintSliderTrack(RenderObject* o, const PaintInfo bool RenderThemeChromiumLinux::paintSliderThumb(RenderObject* o, const PaintInfo& i, const IntRect& rect) { - PlatformSupport::ThemePaintExtraParams extraParams; + WebKit::WebThemeEngine::ExtraParams extraParams; + WebKit::WebCanvas* canvas = i.context->platformContext()->canvas(); extraParams.slider.vertical = o->style()->appearance() == SliderThumbVerticalPart; extraParams.slider.inDrag = isPressed(o); - PlatformSupport::paintThemePart(i.context, PlatformSupport::PartSliderThumb, getWebThemeState(this, o), rect, &extraParams); + WebKit::Platform::current()->themeEngine()->paint(canvas, WebKit::WebThemeEngine::PartSliderThumb, getWebThemeState(this, o), WebKit::WebRect(rect), &extraParams); return false; } void RenderThemeChromiumLinux::adjustInnerSpinButtonStyle(StyleResolver*, RenderStyle* style, Element*) const { - IntSize size = PlatformSupport::getThemePartSize(PlatformSupport::PartInnerSpinButton); + IntSize size = WebKit::Platform::current()->themeEngine()->getSize(WebKit::WebThemeEngine::PartInnerSpinButton); style->setWidth(Length(size.width(), Fixed)); style->setMinWidth(Length(size.width(), Fixed)); @@ -332,11 +343,12 @@ void RenderThemeChromiumLinux::adjustInnerSpinButtonStyle(StyleResolver*, Render bool RenderThemeChromiumLinux::paintInnerSpinButton(RenderObject* o, const PaintInfo& i, const IntRect& rect) { - PlatformSupport::ThemePaintExtraParams extraParams; + WebKit::WebThemeEngine::ExtraParams extraParams; + WebKit::WebCanvas* canvas = i.context->platformContext()->canvas(); extraParams.innerSpin.spinUp = (controlStatesForRenderer(o) & SpinUpState); extraParams.innerSpin.readOnly = isReadOnlyControl(o); - PlatformSupport::paintThemePart(i.context, PlatformSupport::PartInnerSpinButton, getWebThemeState(this, o), rect, &extraParams); + WebKit::Platform::current()->themeEngine()->paint(canvas, WebKit::WebThemeEngine::PartInnerSpinButton, getWebThemeState(this, o), WebKit::WebRect(rect), &extraParams); return false; } @@ -350,7 +362,7 @@ bool RenderThemeChromiumLinux::paintProgressBar(RenderObject* o, const PaintInfo RenderProgress* renderProgress = toRenderProgress(o); IntRect valueRect = progressValueRectFor(renderProgress, rect); - PlatformSupport::ThemePaintExtraParams extraParams; + WebKit::WebThemeEngine::ExtraParams extraParams; extraParams.progressBar.determinate = renderProgress->isDeterminate(); extraParams.progressBar.valueRectX = valueRect.x(); extraParams.progressBar.valueRectY = valueRect.y(); @@ -358,10 +370,16 @@ bool RenderThemeChromiumLinux::paintProgressBar(RenderObject* o, const PaintInfo extraParams.progressBar.valueRectHeight = valueRect.height(); DirectionFlippingScope scope(o, i, rect); - PlatformSupport::paintThemePart(i.context, PlatformSupport::PartProgressBar, getWebThemeState(this, o), rect, &extraParams); + WebKit::WebCanvas* canvas = i.context->platformContext()->canvas(); + WebKit::Platform::current()->themeEngine()->paint(canvas, WebKit::WebThemeEngine::PartProgressBar, getWebThemeState(this, o), WebKit::WebRect(rect), &extraParams); return false; } #endif +bool RenderThemeChromiumLinux::shouldOpenPickerWithF4Key() const +{ + return true; +} + } // namespace WebCore diff --git a/Source/WebCore/rendering/RenderThemeChromiumLinux.h b/Source/WebCore/rendering/RenderThemeChromiumLinux.h index 3e23f5b83..5fc4b35db 100644 --- a/Source/WebCore/rendering/RenderThemeChromiumLinux.h +++ b/Source/WebCore/rendering/RenderThemeChromiumLinux.h @@ -84,6 +84,8 @@ namespace WebCore { virtual bool paintProgressBar(RenderObject*, const PaintInfo&, const IntRect&); #endif + virtual bool shouldOpenPickerWithF4Key() const OVERRIDE; + static void setSelectionColors(unsigned activeBackgroundColor, unsigned activeForegroundColor, unsigned inactiveBackgroundColor, diff --git a/Source/WebCore/rendering/RenderThemeChromiumMac.h b/Source/WebCore/rendering/RenderThemeChromiumMac.h index cfd13df60..240dcf9c0 100644 --- a/Source/WebCore/rendering/RenderThemeChromiumMac.h +++ b/Source/WebCore/rendering/RenderThemeChromiumMac.h @@ -77,6 +77,9 @@ private: #if ENABLE(CALENDAR_PICKER) virtual CString extraCalendarPickerStyleSheet() OVERRIDE; #endif +#if ENABLE(INPUT_MULTIPLE_FIELDS_UI) && ENABLE(CALENDAR_PICKER) + virtual bool supportsCalendarPicker(const AtomicString& type) const OVERRIDE; +#endif virtual bool shouldShowPlaceholderWhenFocused() const OVERRIDE; }; diff --git a/Source/WebCore/rendering/RenderThemeChromiumMac.mm b/Source/WebCore/rendering/RenderThemeChromiumMac.mm index efb6174ec..56d9ea607 100644 --- a/Source/WebCore/rendering/RenderThemeChromiumMac.mm +++ b/Source/WebCore/rendering/RenderThemeChromiumMac.mm @@ -189,6 +189,13 @@ CString RenderThemeChromiumMac::extraCalendarPickerStyleSheet() } #endif +#if ENABLE(INPUT_MULTIPLE_FIELDS_UI) && ENABLE(CALENDAR_PICKER) +bool RenderThemeChromiumMac::supportsCalendarPicker(const AtomicString& type) const +{ + return RenderThemeChromiumCommon::supportsCalendarPicker(type); +} +#endif + bool RenderThemeChromiumMac::paintMediaVolumeSliderContainer(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect) { return true; diff --git a/Source/WebCore/rendering/RenderThemeChromiumSkia.cpp b/Source/WebCore/rendering/RenderThemeChromiumSkia.cpp index a38cf1be9..4e504cab4 100644 --- a/Source/WebCore/rendering/RenderThemeChromiumSkia.cpp +++ b/Source/WebCore/rendering/RenderThemeChromiumSkia.cpp @@ -131,6 +131,13 @@ bool RenderThemeChromiumSkia::supportsDataListUI(const AtomicString& type) const return RenderThemeChromiumCommon::supportsDataListUI(type); } +#if ENABLE(INPUT_MULTIPLE_FIELDS_UI) && ENABLE(CALENDAR_PICKER) +bool RenderThemeChromiumSkia::supportsCalendarPicker(const AtomicString& type) const +{ + return RenderThemeChromiumCommon::supportsCalendarPicker(type); +} +#endif + #if ENABLE(VIDEO_TRACK) bool RenderThemeChromiumSkia::supportsClosedCaptioning() const { diff --git a/Source/WebCore/rendering/RenderThemeChromiumSkia.h b/Source/WebCore/rendering/RenderThemeChromiumSkia.h index 10dc70b41..b9da522e1 100644 --- a/Source/WebCore/rendering/RenderThemeChromiumSkia.h +++ b/Source/WebCore/rendering/RenderThemeChromiumSkia.h @@ -181,6 +181,9 @@ private: #if ENABLE(DATALIST_ELEMENT) virtual LayoutUnit sliderTickSnappingThreshold() const OVERRIDE; #endif +#if ENABLE(INPUT_MULTIPLE_FIELDS_UI) && ENABLE(CALENDAR_PICKER) + virtual bool supportsCalendarPicker(const AtomicString& type) const OVERRIDE; +#endif int menuListInternalPadding(RenderStyle*, int paddingType) const; bool paintMediaButtonInternal(GraphicsContext*, const IntRect&, Image*); diff --git a/Source/WebCore/rendering/RenderThemeChromiumWin.cpp b/Source/WebCore/rendering/RenderThemeChromiumWin.cpp index 9f30a26d2..04e893f81 100644 --- a/Source/WebCore/rendering/RenderThemeChromiumWin.cpp +++ b/Source/WebCore/rendering/RenderThemeChromiumWin.cpp @@ -809,4 +809,9 @@ bool RenderThemeChromiumWin::paintProgressBar(RenderObject* o, const PaintInfo& #endif +bool RenderThemeChromiumWin::shouldOpenPickerWithF4Key() const +{ + return true; +} + } // namespace WebCore diff --git a/Source/WebCore/rendering/RenderThemeChromiumWin.h b/Source/WebCore/rendering/RenderThemeChromiumWin.h index 14134c560..85cca45ff 100644 --- a/Source/WebCore/rendering/RenderThemeChromiumWin.h +++ b/Source/WebCore/rendering/RenderThemeChromiumWin.h @@ -100,6 +100,8 @@ namespace WebCore { virtual bool paintProgressBar(RenderObject*, const PaintInfo&, const IntRect&); #endif + virtual bool shouldOpenPickerWithF4Key() const OVERRIDE; + protected: virtual double caretBlinkIntervalInternal() const; diff --git a/Source/WebCore/rendering/RenderThemeMac.h b/Source/WebCore/rendering/RenderThemeMac.h index 7ad49bd34..3288471ad 100644 --- a/Source/WebCore/rendering/RenderThemeMac.h +++ b/Source/WebCore/rendering/RenderThemeMac.h @@ -101,6 +101,9 @@ public: virtual bool usesTestModeFocusRingColor() const; // A view associated to the contained document. Subclasses may not have such a view and return a fake. virtual NSView* documentViewFor(RenderObject*) const; + + virtual void paintPlugInSnapshotOverlay(RenderSnapshottedPlugIn*, const PaintInfo&, const LayoutPoint&) const OVERRIDE; + protected: RenderThemeMac(); virtual ~RenderThemeMac(); diff --git a/Source/WebCore/rendering/RenderThemeMac.mm b/Source/WebCore/rendering/RenderThemeMac.mm index 0bc9804fb..e0837fdc5 100644 --- a/Source/WebCore/rendering/RenderThemeMac.mm +++ b/Source/WebCore/rendering/RenderThemeMac.mm @@ -41,6 +41,7 @@ #import "RenderMedia.h" #import "RenderMediaControls.h" #import "RenderSlider.h" +#import "RenderSnapshottedPlugIn.h" #import "RenderView.h" #import "SharedBuffer.h" #import "StringTruncator.h" @@ -380,7 +381,7 @@ Color RenderThemeMac::systemColor(int cssValueId) const { HashMap<int, RGBA32>::iterator it = m_systemColorCache.find(cssValueId); if (it != m_systemColorCache.end()) - return it->second; + return it->value; } Color color; @@ -2175,7 +2176,6 @@ NSSliderCell* RenderThemeMac::sliderThumbHorizontal() const { if (!m_sliderThumbHorizontal) { m_sliderThumbHorizontal.adoptNS([[NSSliderCell alloc] init]); - [m_sliderThumbHorizontal.get() setTitle:nil]; [m_sliderThumbHorizontal.get() setSliderType:NSLinearSlider]; [m_sliderThumbHorizontal.get() setControlSize:NSSmallControlSize]; [m_sliderThumbHorizontal.get() setFocusRingType:NSFocusRingTypeExterior]; @@ -2188,7 +2188,6 @@ NSSliderCell* RenderThemeMac::sliderThumbVertical() const { if (!m_sliderThumbVertical) { m_sliderThumbVertical.adoptNS([[NSSliderCell alloc] init]); - [m_sliderThumbVertical.get() setTitle:nil]; [m_sliderThumbVertical.get() setSliderType:NSLinearSlider]; [m_sliderThumbVertical.get() setControlSize:NSSmallControlSize]; [m_sliderThumbVertical.get() setFocusRingType:NSFocusRingTypeExterior]; @@ -2234,4 +2233,43 @@ String RenderThemeMac::fileListNameForWidth(const FileList* fileList, const Font return StringTruncator::centerTruncate(strToTruncate, width, font, StringTruncator::EnableRoundingHacks); } +void RenderThemeMac::paintPlugInSnapshotOverlay(RenderSnapshottedPlugIn* renderer, const PaintInfo& paintInfo, const LayoutPoint& paintOffset) const +{ + LayoutUnit cWidth = renderer->contentWidth(); + LayoutUnit cHeight = renderer->contentHeight(); + if (!cWidth || !cHeight) + return; + + GraphicsContext* context = paintInfo.context; + GraphicsContextStateSaver saver(*context); + + LayoutSize borderAndPadding(renderer->borderLeft() + renderer->paddingLeft(), renderer->borderTop() + renderer->paddingTop()); + + LayoutSize contentSize(cWidth, cHeight); + LayoutPoint contentLocation = paintOffset; + contentLocation.move(borderAndPadding); + + RefPtr<Gradient> g = Gradient::create(contentLocation, FloatPoint(contentLocation.x(), contentLocation.y() + cHeight)); + g->addColorStop(0, Color(.5f, .5, .5, .7)); + g->addColorStop(.2, Color(.54f, .54, .54, .3)); + g->addColorStop(.6, Color(.62f, .62, .62, .3)); + g->addColorStop(1, Color(.7f, .7, .7, .95)); + context->setFillGradient(g.release()); + context->fillRect(pixelSnappedIntRect(LayoutRect(contentLocation, contentSize))); + + static const float diameter = 50, triangleRadius = 12; + LayoutPoint center = contentLocation; + center.move(cWidth / 2, cHeight / 2); + context->setFillColor(Color(.4f, .4, .4, .7), ColorSpaceSRGB); + context->fillEllipse(FloatRect(center.x() - diameter / 2, center.y() - diameter / 2, diameter, diameter)); + + Path p; + p.moveTo(FloatPoint(center.x() - triangleRadius * 3 / 4, center.y() - triangleRadius)); + p.addLineTo(FloatPoint(center.x() + triangleRadius * 5 / 4, center.y())); + p.addLineTo(FloatPoint(center.x() - triangleRadius * 3 / 4, center.y() + triangleRadius)); + p.closeSubpath(); + context->setFillColor(Color(1.f, 1.f, 1.f, .9f), ColorSpaceSRGB); + context->fillPath(p); +} + } // namespace WebCore diff --git a/Source/WebCore/rendering/RenderTreeAsText.cpp b/Source/WebCore/rendering/RenderTreeAsText.cpp index 813cf7e0c..ac6bd3452 100644 --- a/Source/WebCore/rendering/RenderTreeAsText.cpp +++ b/Source/WebCore/rendering/RenderTreeAsText.cpp @@ -655,6 +655,31 @@ static void write(TextStream& ts, RenderLayer& l, write(ts, *l.renderer(), indent + 1, behavior); } +static void writeRenderRegionList(const RenderRegionList& flowThreadRegionList, TextStream& ts, int indent) +{ + for (RenderRegionList::const_iterator itRR = flowThreadRegionList.begin(); itRR != flowThreadRegionList.end(); ++itRR) { + RenderRegion* renderRegion = *itRR; + writeIndent(ts, indent + 2); + ts << "RenderRegion"; + if (renderRegion->generatingNode()) { + String tagName = getTagName(renderRegion->generatingNode()); + if (!tagName.isEmpty()) + ts << " {" << tagName << "}"; + if (renderRegion->generatingNode()->isElementNode() && renderRegion->generatingNode()->hasID()) { + Element* element = static_cast<Element*>(renderRegion->generatingNode()); + ts << " #" << element->idForStyleResolution(); + } + if (renderRegion->hasCustomRegionStyle()) + ts << " region style: 1"; + if (renderRegion->hasAutoLogicalHeight()) + ts << " hasAutoLogicalHeight"; + } + if (!renderRegion->isValid()) + ts << " invalid"; + ts << "\n"; + } +} + static void writeRenderNamedFlowThreads(TextStream& ts, RenderView* renderView, const RenderLayer* rootLayer, const LayoutRect& paintRect, int indent, RenderAsTextBehavior behavior) { @@ -675,32 +700,14 @@ static void writeRenderNamedFlowThreads(TextStream& ts, RenderView* renderView, RenderLayer* layer = renderFlowThread->layer(); writeLayers(ts, rootLayer, layer, paintRect, indent + 2, behavior); - // Display the render regions attached to this flow thread - const RenderRegionList& flowThreadRegionList = renderFlowThread->renderRegionList(); - if (!flowThreadRegionList.isEmpty()) { + // Display the valid and invalid render regions attached to this flow thread. + const RenderRegionList& validRegionsList = renderFlowThread->renderRegionList(); + const RenderRegionList& invalidRegionsList = renderFlowThread->invalidRenderRegionList(); + if (!validRegionsList.isEmpty() || !invalidRegionsList.isEmpty()) { writeIndent(ts, indent + 1); ts << "Regions for flow '"<< renderFlowThread->flowThreadName() << "'\n"; - for (RenderRegionList::const_iterator itRR = flowThreadRegionList.begin(); itRR != flowThreadRegionList.end(); ++itRR) { - RenderRegion* renderRegion = *itRR; - writeIndent(ts, indent + 2); - ts << "RenderRegion"; - if (renderRegion->generatingNode()) { - String tagName = getTagName(renderRegion->generatingNode()); - if (!tagName.isEmpty()) - ts << " {" << tagName << "}"; - if (renderRegion->generatingNode()->isElementNode() && renderRegion->generatingNode()->hasID()) { - Element* element = static_cast<Element*>(renderRegion->generatingNode()); - ts << " #" << element->idForStyleResolution(); - } - if (renderRegion->hasCustomRegionStyle()) - ts << " region style: 1"; - if (renderRegion->hasAutoLogicalHeight()) - ts << " hasAutoLogicalHeight"; - } - if (!renderRegion->isValid()) - ts << " invalid"; - ts << "\n"; - } + writeRenderRegionList(validRegionsList, ts, indent); + writeRenderRegionList(invalidRegionsList, ts, indent); } } } diff --git a/Source/WebCore/rendering/RenderView.cpp b/Source/WebCore/rendering/RenderView.cpp index 94da27703..27bc14abd 100644 --- a/Source/WebCore/rendering/RenderView.cpp +++ b/Source/WebCore/rendering/RenderView.cpp @@ -176,7 +176,7 @@ void RenderView::layout() setNeedsLayout(false); } -void RenderView::mapLocalToContainer(RenderBoxModelObject* repaintContainer, TransformState& transformState, MapLocalToContainerFlags mode, bool* wasFixed) const +void RenderView::mapLocalToContainer(RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags mode, bool* wasFixed) const { // If a container was specified, and was not 0 or the RenderView, // then we should have found it by now. @@ -193,7 +193,7 @@ void RenderView::mapLocalToContainer(RenderBoxModelObject* repaintContainer, Tra transformState.move(m_frameView->scrollOffsetForFixedPosition()); } -const RenderObject* RenderView::pushMappingToContainer(const RenderBoxModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const +const RenderObject* RenderView::pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const { // If a container was specified, and was not 0 or the RenderView, // then we should have found it by now. @@ -214,12 +214,12 @@ const RenderObject* RenderView::pushMappingToContainer(const RenderBoxModelObjec return 0; } -void RenderView::mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState& transformState) const +void RenderView::mapAbsoluteToLocalPoint(MapCoordinatesFlags mode, TransformState& transformState) const { - if (fixed && m_frameView) + if (mode & IsFixed && m_frameView) transformState.move(m_frameView->scrollOffsetForFixedPosition()); - if (useTransforms && shouldUseTransformFromContainer(0)) { + if (mode & UseTransforms && shouldUseTransformFromContainer(0)) { TransformationMatrix t; getTransformFromContainer(0, LayoutSize(), t); transformState.applyTransform(t); @@ -268,7 +268,7 @@ void RenderView::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset) static inline bool isComposited(RenderObject* object) { - return object->hasLayer() && toRenderBoxModelObject(object)->layer()->isComposited(); + return object->hasLayer() && toRenderLayerModelObject(object)->layer()->isComposited(); } static inline bool rendererObscuresBackground(RenderObject* object) @@ -391,7 +391,7 @@ void RenderView::repaintRectangleInViewAndCompositedLayers(const LayoutRect& ur, #endif } -void RenderView::computeRectForRepaint(RenderBoxModelObject* repaintContainer, LayoutRect& rect, bool fixed) const +void RenderView::computeRectForRepaint(RenderLayerModelObject* repaintContainer, LayoutRect& rect, bool fixed) const { // If a container was specified, and was not 0 or the RenderView, // then we should have found it by now. @@ -413,20 +413,20 @@ void RenderView::computeRectForRepaint(RenderBoxModelObject* repaintContainer, L rect.move(m_frameView->scrollOffsetForFixedPosition()); // Apply our transform if we have one (because of full page zooming). - if (!repaintContainer && m_layer && m_layer->transform()) - rect = m_layer->transform()->mapRect(rect); + if (!repaintContainer && layer() && layer()->transform()) + rect = layer()->transform()->mapRect(rect); } void RenderView::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumulatedOffset) const { - rects.append(pixelSnappedIntRect(accumulatedOffset, m_layer->size())); + rects.append(pixelSnappedIntRect(accumulatedOffset, layer()->size())); } void RenderView::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const { if (wasFixed) *wasFixed = false; - quads.append(FloatRect(FloatPoint(), m_layer->size())); + quads.append(FloatRect(FloatPoint(), layer()->size())); } static RenderObject* rendererAfterPosition(RenderObject* object, unsigned offset) @@ -453,7 +453,7 @@ IntRect RenderView::selectionBounds(bool clipToVisibleContent) const selectedObjects.set(os, adoptPtr(new RenderSelectionInfo(os, clipToVisibleContent))); RenderBlock* cb = os->containingBlock(); while (cb && !cb->isRenderView()) { - OwnPtr<RenderSelectionInfo>& blockInfo = selectedObjects.add(cb, nullptr).iterator->second; + OwnPtr<RenderSelectionInfo>& blockInfo = selectedObjects.add(cb, nullptr).iterator->value; if (blockInfo) break; blockInfo = adoptPtr(new RenderSelectionInfo(cb, clipToVisibleContent)); @@ -468,11 +468,11 @@ IntRect RenderView::selectionBounds(bool clipToVisibleContent) const LayoutRect selRect; SelectionMap::iterator end = selectedObjects.end(); for (SelectionMap::iterator i = selectedObjects.begin(); i != end; ++i) { - RenderSelectionInfo* info = i->second.get(); + RenderSelectionInfo* info = i->value.get(); // RenderSelectionInfo::rect() is in the coordinates of the repaintContainer, so map to page coordinates. LayoutRect currRect = info->rect(); - if (RenderBoxModelObject* repaintContainer = info->repaintContainer()) { - FloatQuad absQuad = repaintContainer->localToAbsoluteQuad(FloatRect(currRect)); + if (RenderLayerModelObject* repaintContainer = info->repaintContainer()) { + FloatQuad absQuad = repaintContainer->localToAbsoluteQuad(FloatRect(currRect), SnapOffsetForTransforms); currRect = absQuad.enclosingBoundingBox(); } selRect.unite(currRect); @@ -533,7 +533,7 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e if (blockRepaintMode == RepaintNewXOROld) { RenderBlock* cb = os->containingBlock(); while (cb && !cb->isRenderView()) { - OwnPtr<RenderBlockSelectionInfo>& blockInfo = oldSelectedBlocks.add(cb, nullptr).iterator->second; + OwnPtr<RenderBlockSelectionInfo>& blockInfo = oldSelectedBlocks.add(cb, nullptr).iterator->value; if (blockInfo) break; blockInfo = adoptPtr(new RenderBlockSelectionInfo(cb)); @@ -548,7 +548,7 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e // Now clear the selection. SelectedObjectMap::iterator oldObjectsEnd = oldSelectedObjects.end(); for (SelectedObjectMap::iterator i = oldSelectedObjects.begin(); i != oldObjectsEnd; ++i) - i->first->setSelectionStateIfNeeded(SelectionNone); + i->key->setSelectionStateIfNeeded(SelectionNone); // set selection start and end m_selectionStart = start; @@ -576,7 +576,7 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e } if (blockRepaintMode != RepaintNothing) - m_layer->clearBlockSelectionGapsBounds(); + layer()->clearBlockSelectionGapsBounds(); // Now that the selection state has been updated for the new objects, walk them again and // put them in the new objects list. @@ -586,7 +586,7 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e newSelectedObjects.set(o, adoptPtr(new RenderSelectionInfo(o, true))); RenderBlock* cb = o->containingBlock(); while (cb && !cb->isRenderView()) { - OwnPtr<RenderBlockSelectionInfo>& blockInfo = newSelectedBlocks.add(cb, nullptr).iterator->second; + OwnPtr<RenderBlockSelectionInfo>& blockInfo = newSelectedBlocks.add(cb, nullptr).iterator->value; if (blockInfo) break; blockInfo = adoptPtr(new RenderBlockSelectionInfo(cb)); @@ -604,9 +604,9 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e // Have any of the old selected objects changed compared to the new selection? for (SelectedObjectMap::iterator i = oldSelectedObjects.begin(); i != oldObjectsEnd; ++i) { - RenderObject* obj = i->first; + RenderObject* obj = i->key; RenderSelectionInfo* newInfo = newSelectedObjects.get(obj); - RenderSelectionInfo* oldInfo = i->second.get(); + RenderSelectionInfo* oldInfo = i->value.get(); if (!newInfo || oldInfo->rect() != newInfo->rect() || oldInfo->state() != newInfo->state() || (m_selectionStart == obj && oldStartPos != m_selectionStartPos) || (m_selectionEnd == obj && oldEndPos != m_selectionEndPos)) { @@ -621,14 +621,14 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e // Any new objects that remain were not found in the old objects dict, and so they need to be updated. SelectedObjectMap::iterator newObjectsEnd = newSelectedObjects.end(); for (SelectedObjectMap::iterator i = newSelectedObjects.begin(); i != newObjectsEnd; ++i) - i->second->repaint(); + i->value->repaint(); // Have any of the old blocks changed? SelectedBlockMap::iterator oldBlocksEnd = oldSelectedBlocks.end(); for (SelectedBlockMap::iterator i = oldSelectedBlocks.begin(); i != oldBlocksEnd; ++i) { - RenderBlock* block = i->first; + RenderBlock* block = i->key; RenderBlockSelectionInfo* newInfo = newSelectedBlocks.get(block); - RenderBlockSelectionInfo* oldInfo = i->second.get(); + RenderBlockSelectionInfo* oldInfo = i->value.get(); if (!newInfo || oldInfo->rects() != newInfo->rects() || oldInfo->state() != newInfo->state()) { oldInfo->repaint(); if (newInfo) { @@ -641,7 +641,7 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e // Any new blocks that remain were not found in the old blocks dict, and so they need to be updated. SelectedBlockMap::iterator newBlocksEnd = newSelectedBlocks.end(); for (SelectedBlockMap::iterator i = newSelectedBlocks.begin(); i != newBlocksEnd; ++i) - i->second->repaint(); + i->value->repaint(); m_frameView->endDeferredRepaints(); } @@ -656,7 +656,7 @@ void RenderView::getSelection(RenderObject*& startRenderer, int& startOffset, Re void RenderView::clearSelection() { - m_layer->repaintBlockSelectionGaps(); + layer()->repaintBlockSelectionGaps(); setSelection(0, -1, 0, -1, RepaintNewMinusOld); } diff --git a/Source/WebCore/rendering/RenderView.h b/Source/WebCore/rendering/RenderView.h index 7e9757951..5af17a116 100644 --- a/Source/WebCore/rendering/RenderView.h +++ b/Source/WebCore/rendering/RenderView.h @@ -77,7 +77,7 @@ public: FrameView* frameView() const { return m_frameView; } - virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, LayoutRect&, bool fixed = false) const; + virtual void computeRectForRepaint(RenderLayerModelObject* repaintContainer, LayoutRect&, bool fixed = false) const OVERRIDE; virtual void repaintViewRectangle(const LayoutRect&, bool immediate = false); // Repaint the view, and all composited layers that intersect the given absolute rectangle. // FIXME: ideally we'd never have to do this, if all repaints are container-relative. @@ -206,9 +206,9 @@ public: bool hasRenderCounters() { return m_renderCounterCount; } protected: - virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, TransformState&, MapLocalToContainerFlags mode = ApplyContainerFlip | SnapOffsetForTransforms, bool* wasFixed = 0) const OVERRIDE; - virtual const RenderObject* pushMappingToContainer(const RenderBoxModelObject* ancestorToStopAt, RenderGeometryMap&) const; - virtual void mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState&) const; + virtual void mapLocalToContainer(RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip | SnapOffsetForTransforms, bool* wasFixed = 0) const OVERRIDE; + virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const OVERRIDE; + virtual void mapAbsoluteToLocalPoint(MapCoordinatesFlags, TransformState&) const; virtual bool requiresColumns(int desiredColumnCount) const OVERRIDE; private: @@ -225,7 +225,7 @@ private: if (!doingFullRepaint() || m_layoutState->isPaginated() || renderer->hasColumns() || renderer->inRenderFlowThread() || m_layoutState->lineGrid() || (renderer->style()->lineGrid() != RenderStyle::initialLineGrid() && renderer->isBlockFlow()) #if ENABLE(CSS_EXCLUSIONS) - || (renderer->isRenderBlock() && toRenderBlock(renderer)->wrapShapeInfo()) + || (renderer->isRenderBlock() && toRenderBlock(renderer)->exclusionShapeInsideInfo()) #endif ) { m_layoutState = new (renderArena()) LayoutState(m_layoutState, renderer, offset, pageHeight, pageHeightChanged, colInfo); diff --git a/Source/WebCore/rendering/RenderWidget.cpp b/Source/WebCore/rendering/RenderWidget.cpp index 21d0c3ad6..c5d0856f3 100644 --- a/Source/WebCore/rendering/RenderWidget.cpp +++ b/Source/WebCore/rendering/RenderWidget.cpp @@ -61,9 +61,9 @@ void WidgetHierarchyUpdatesSuspensionScope::moveWidgets() widgetNewParentMap().clear(); WidgetToParentMap::iterator end = map.end(); for (WidgetToParentMap::iterator it = map.begin(); it != end; ++it) { - Widget* child = it->first.get(); + Widget* child = it->key.get(); ScrollView* currentParent = child->parent(); - FrameView* newParent = it->second; + FrameView* newParent = it->value; if (newParent != currentParent) { if (currentParent) currentParent->removeChild(child); @@ -169,7 +169,7 @@ bool RenderWidget::updateWidgetGeometry() if (!m_widget->transformsAffectFrameRect()) return setWidgetGeometry(absoluteContentBox()); - LayoutRect absoluteContentBox(localToAbsoluteQuad(FloatQuad(contentBox)).boundingBox()); + LayoutRect absoluteContentBox(localToAbsoluteQuad(FloatQuad(contentBox), SnapOffsetForTransforms).boundingBox()); if (m_widget->isFrameView()) { contentBox.setLocation(absoluteContentBox.location()); return setWidgetGeometry(contentBox); diff --git a/Source/WebCore/rendering/RenderingAllInOne.cpp b/Source/WebCore/rendering/RenderingAllInOne.cpp index 03bdd3f8b..766fac334 100644 --- a/Source/WebCore/rendering/RenderingAllInOne.cpp +++ b/Source/WebCore/rendering/RenderingAllInOne.cpp @@ -66,6 +66,7 @@ #include "RenderInline.cpp" #include "RenderLayer.cpp" #include "RenderLayerCompositor.cpp" +#include "RenderLayerModelObject.cpp" #include "RenderLineBoxList.cpp" #include "RenderListBox.cpp" #include "RenderListItem.cpp" @@ -94,6 +95,7 @@ #include "RenderScrollbarTheme.cpp" #include "RenderSearchField.cpp" #include "RenderSlider.cpp" +#include "RenderSnapshottedPlugin.cpp" #include "RenderTable.cpp" #include "RenderTableCaption.cpp" #include "RenderTableCell.cpp" diff --git a/Source/WebCore/rendering/RootInlineBox.cpp b/Source/WebCore/rendering/RootInlineBox.cpp index 1f4206700..f932e6f21 100644 --- a/Source/WebCore/rendering/RootInlineBox.cpp +++ b/Source/WebCore/rendering/RootInlineBox.cpp @@ -755,8 +755,8 @@ void RootInlineBox::ascentAndDescentForBox(InlineBox* box, GlyphOverflowAndFallb GlyphOverflow* glyphOverflow = 0; if (box->isText()) { GlyphOverflowAndFallbackFontsMap::iterator it = textBoxDataMap.find(toInlineTextBox(box)); - usedFonts = it == textBoxDataMap.end() ? 0 : &it->second.first; - glyphOverflow = it == textBoxDataMap.end() ? 0 : &it->second.second; + usedFonts = it == textBoxDataMap.end() ? 0 : &it->value.first; + glyphOverflow = it == textBoxDataMap.end() ? 0 : &it->value.second; } bool includeLeading = includeLeadingForBox(box); diff --git a/Source/WebCore/rendering/TextAutosizer.cpp b/Source/WebCore/rendering/TextAutosizer.cpp index 304bdb31c..0a0791498 100644 --- a/Source/WebCore/rendering/TextAutosizer.cpp +++ b/Source/WebCore/rendering/TextAutosizer.cpp @@ -64,7 +64,9 @@ bool TextAutosizer::processSubtree(RenderObject* layoutRoot) windowInfo.windowSize = m_document->settings()->textAutosizingWindowSizeOverride(); if (windowInfo.windowSize.isEmpty()) { bool includeScrollbars = !InspectorInstrumentation::shouldApplyScreenWidthOverride(mainFrame); - windowInfo.windowSize = mainFrame->view()->visibleContentRect(includeScrollbars).size(); // FIXME: Check that this is always in logical (density-independent) pixels (see wkbug.com/87440). + windowInfo.windowSize = mainFrame->view()->visibleContentRect(includeScrollbars).size(); + if (!m_document->settings()->applyPageScaleFactorInCompositor()) + windowInfo.windowSize.scale(1 / m_document->page()->deviceScaleFactor()); } // Largest area of block that can be visible at once (assuming the main diff --git a/Source/WebCore/rendering/VerticalPositionCache.h b/Source/WebCore/rendering/VerticalPositionCache.h index bb3987772..b7cd7e085 100644 --- a/Source/WebCore/rendering/VerticalPositionCache.h +++ b/Source/WebCore/rendering/VerticalPositionCache.h @@ -48,7 +48,7 @@ public: const HashMap<RenderObject*, int>::const_iterator it = mapToCheck.find(renderer); if (it == mapToCheck.end()) return PositionUndefined; - return it->second; + return it->value; } void set(RenderObject* renderer, FontBaseline baselineType, int position) diff --git a/Source/WebCore/rendering/break_lines.cpp b/Source/WebCore/rendering/break_lines.cpp index f1b5ca18f..10f8b2be2 100644 --- a/Source/WebCore/rendering/break_lines.cpp +++ b/Source/WebCore/rendering/break_lines.cpp @@ -147,17 +147,16 @@ inline bool needsLineBreakIterator(UChar ch) return ch > asciiLineBreakTableLastChar && ch != noBreakSpace; } -template<bool treatNoBreakSpaceAsBreak> -static inline int nextBreakablePosition(LazyLineBreakIterator& lazyBreakIterator, int pos) +template<typename CharacterType, bool treatNoBreakSpaceAsBreak> +static inline int nextBreakablePosition(LazyLineBreakIterator& lazyBreakIterator, const CharacterType* str, unsigned length, int pos) { - const UChar* str = lazyBreakIterator.string(); - int len = lazyBreakIterator.length(); + int len = static_cast<int>(length); int nextBreak = -1; - UChar lastLastCh = pos > 1 ? str[pos - 2] : 0; - UChar lastCh = pos > 0 ? str[pos - 1] : 0; + CharacterType lastLastCh = pos > 1 ? str[pos - 2] : 0; + CharacterType lastCh = pos > 0 ? str[pos - 1] : 0; for (int i = pos; i < len; i++) { - UChar ch = str[i]; + CharacterType ch = str[i]; if (isBreakableSpace<treatNoBreakSpaceAsBreak>(ch) || shouldBreakAfter(lastLastCh, lastCh, ch)) return i; @@ -181,12 +180,18 @@ static inline int nextBreakablePosition(LazyLineBreakIterator& lazyBreakIterator int nextBreakablePositionIgnoringNBSP(LazyLineBreakIterator& lazyBreakIterator, int pos) { - return nextBreakablePosition<false>(lazyBreakIterator, pos); + String string = lazyBreakIterator.string(); + if (string.is8Bit()) + return nextBreakablePosition<LChar, false>(lazyBreakIterator, string.characters8(), string.length(), pos); + return nextBreakablePosition<UChar, false>(lazyBreakIterator, string.characters16(), string.length(), pos); } int nextBreakablePosition(LazyLineBreakIterator& lazyBreakIterator, int pos) { - return nextBreakablePosition<true>(lazyBreakIterator, pos); + String string = lazyBreakIterator.string(); + if (string.is8Bit()) + return nextBreakablePosition<LChar, true>(lazyBreakIterator, string.characters8(), string.length(), pos); + return nextBreakablePosition<UChar, true>(lazyBreakIterator, string.characters16(), string.length(), pos); } } // namespace WebCore diff --git a/Source/WebCore/rendering/mathml/RenderMathMLFraction.cpp b/Source/WebCore/rendering/mathml/RenderMathMLFraction.cpp index 4f1008ff2..a08680bfd 100644 --- a/Source/WebCore/rendering/mathml/RenderMathMLFraction.cpp +++ b/Source/WebCore/rendering/mathml/RenderMathMLFraction.cpp @@ -33,13 +33,11 @@ #include "GraphicsContext.h" #include "MathMLNames.h" #include "PaintInfo.h" -#include "RenderText.h" namespace WebCore { using namespace MathMLNames; -static const float gHorizontalPad = 0.2f; static const float gLineThin = 0.33f; static const float gLineMedium = 1.f; static const float gLineThick = 3.f; @@ -55,9 +53,6 @@ void RenderMathMLFraction::fixChildStyle(RenderObject* child) { ASSERT(child->isAnonymous() && child->style()->refCount() == 1); child->style()->setFlexDirection(FlowColumn); - Length pad(static_cast<int>(style()->fontSize() * gHorizontalPad), Fixed); - child->style()->setPaddingLeft(pad); - child->style()->setPaddingRight(pad); } // FIXME: It's cleaner to only call updateFromElement when an attribute has changed. Move parts @@ -139,25 +134,11 @@ void RenderMathMLFraction::paint(PaintInfo& info, const LayoutPoint& paintOffset if (info.context->paintingDisabled() || info.phase != PaintPhaseForeground) return; - if (!firstChild() ||!m_lineThickness) + RenderBox* denominatorWrapper = lastChildBox(); + if (!denominatorWrapper || !m_lineThickness) return; - int verticalOffset = 0; - // The children are always RenderMathMLBlock instances - if (firstChild()->isRenderMathMLBlock()) { - int adjustForThickness = m_lineThickness > 1 ? int(m_lineThickness / 2) : 1; - if (int(m_lineThickness) % 2 == 1) - adjustForThickness++; - // FIXME: This is numeratorWrapper, not numerator. - RenderMathMLBlock* numerator = toRenderMathMLBlock(firstChild()); - if (numerator->isRenderMathMLRow()) - verticalOffset = numerator->pixelSnappedOffsetHeight() + adjustForThickness; - else - verticalOffset = numerator->pixelSnappedOffsetHeight(); - } - - IntPoint adjustedPaintOffset = roundedIntPoint(paintOffset + location()); - adjustedPaintOffset.setY(adjustedPaintOffset.y() + verticalOffset); + IntPoint adjustedPaintOffset = roundedIntPoint(paintOffset + location() + denominatorWrapper->location() + LayoutPoint(0, m_lineThickness / 2)); GraphicsContextStateSaver stateSaver(*info.context); @@ -165,21 +146,13 @@ void RenderMathMLFraction::paint(PaintInfo& info, const LayoutPoint& paintOffset info.context->setStrokeStyle(SolidStroke); info.context->setStrokeColor(style()->visitedDependentColor(CSSPropertyColor), ColorSpaceSRGB); - info.context->drawLine(adjustedPaintOffset, IntPoint(adjustedPaintOffset.x() + pixelSnappedOffsetWidth(), adjustedPaintOffset.y())); + info.context->drawLine(adjustedPaintOffset, IntPoint(adjustedPaintOffset.x() + denominatorWrapper->pixelSnappedOffsetWidth(), adjustedPaintOffset.y())); } LayoutUnit RenderMathMLFraction::firstLineBoxBaseline() const { - if (firstChild() && firstChild()->isRenderMathMLBlock()) { - RenderMathMLBlock* numeratorWrapper = toRenderMathMLBlock(firstChild()); - RenderStyle* refStyle = style(); - if (previousSibling()) - refStyle = previousSibling()->style(); - else if (nextSibling()) - refStyle = nextSibling()->style(); - int shift = int(ceil((refStyle->fontMetrics().xHeight() + 1) / 2)); - return numeratorWrapper->pixelSnappedOffsetHeight() + shift; - } + if (RenderBox* denominatorWrapper = lastChildBox()) + return denominatorWrapper->logicalTop() + static_cast<int>(lroundf((m_lineThickness + style()->fontMetrics().xHeight()) / 2)); return RenderMathMLBlock::firstLineBoxBaseline(); } diff --git a/Source/WebCore/rendering/mathml/RenderMathMLUnderOver.cpp b/Source/WebCore/rendering/mathml/RenderMathMLUnderOver.cpp index c0128f483..93c59a894 100644 --- a/Source/WebCore/rendering/mathml/RenderMathMLUnderOver.cpp +++ b/Source/WebCore/rendering/mathml/RenderMathMLUnderOver.cpp @@ -59,11 +59,12 @@ RenderMathMLOperator* RenderMathMLUnderOver::unembellishedOperator() LayoutUnit RenderMathMLUnderOver::firstLineBoxBaseline() const { - if (!firstChildBox()) + RenderBox* base = firstChildBox(); + if (!base) return -1; - LayoutUnit baseline = firstChildBox()->firstLineBoxBaseline(); - if (baseline != -1 && m_kind != Under) - baseline += lastChildBox()->pixelSnappedOffsetHeight(); // Add in the overscript's height. + LayoutUnit baseline = base->firstLineBoxBaseline(); + if (baseline != -1) + baseline += base->logicalTop(); return baseline; } diff --git a/Source/WebCore/rendering/style/CollapsedBorderValue.h b/Source/WebCore/rendering/style/CollapsedBorderValue.h index 049a4ac68..98cee1b07 100644 --- a/Source/WebCore/rendering/style/CollapsedBorderValue.h +++ b/Source/WebCore/rendering/style/CollapsedBorderValue.h @@ -32,42 +32,44 @@ namespace WebCore { class CollapsedBorderValue { public: CollapsedBorderValue() - : m_precedence(BOFF) + : m_color(0) + , m_colorIsValid(false) + , m_width(0) + , m_style(BNONE) + , m_precedence(BOFF) + , m_transparent(false) { } - // This copy constructor is for preventing GCC (x86) from creating an - // unexpected one as written in <http://webkit.org/b/81502>. - CollapsedBorderValue(const CollapsedBorderValue& other) - : m_border(other.m_border) - , m_borderColor(other.m_borderColor) - , m_precedence(other.m_precedence) + CollapsedBorderValue(const BorderValue& border, const Color& color, EBorderPrecedence precedence) + : m_color(color.rgb()) + , m_colorIsValid(color.isValid()) + , m_width(border.nonZero() ? border.width() : 0) + , m_style(border.style()) + , m_precedence(precedence) + , m_transparent(border.isTransparent()) { } - CollapsedBorderValue(const BorderValue& b, Color c, EBorderPrecedence p) - : m_border(b) - , m_borderColor(c) - , m_precedence(p) - { - } - - int width() const { return m_border.nonZero() ? m_border.width() : 0; } - EBorderStyle style() const { return m_border.style(); } + unsigned width() const { return m_width; } + EBorderStyle style() const { return static_cast<EBorderStyle>(m_style); } bool exists() const { return m_precedence != BOFF; } - const Color& color() const { return m_borderColor; } - bool isTransparent() const { return m_border.isTransparent(); } - EBorderPrecedence precedence() const { return m_precedence; } + Color color() const { return Color(m_color, m_colorIsValid); } + bool isTransparent() const { return m_transparent; } + EBorderPrecedence precedence() const { return static_cast<EBorderPrecedence>(m_precedence); } bool isSameIgnoringColor(const CollapsedBorderValue& o) const { - return m_border.width() == o.m_border.width() && m_border.style() == o.m_border.style() && m_precedence == o.m_precedence; + return width() == o.width() && style() == o.style() && precedence() == o.precedence(); } private: - BorderValue m_border; - Color m_borderColor; - EBorderPrecedence m_precedence; + RGBA32 m_color; + unsigned m_colorIsValid : 1; + unsigned m_width : 23; + unsigned m_style : 4; // EBorderStyle + unsigned m_precedence : 3; // EBorderPrecedence + unsigned m_transparent : 1; }; } // namespace WebCore diff --git a/Source/WebCore/rendering/style/RenderStyle.cpp b/Source/WebCore/rendering/style/RenderStyle.cpp index 63d5e0550..387fd20cb 100644 --- a/Source/WebCore/rendering/style/RenderStyle.cpp +++ b/Source/WebCore/rendering/style/RenderStyle.cpp @@ -451,14 +451,14 @@ StyleDifference RenderStyle::diff(const RenderStyle* other, unsigned& changedCon } #endif -#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) +#if ENABLE(DASHBOARD_SUPPORT) // If regions change, trigger a relayout to re-calc regions. if (rareNonInheritedData->m_dashboardRegions != other->rareNonInheritedData->m_dashboardRegions) return StyleDifferenceLayout; #endif #if ENABLE(CSS_EXCLUSIONS) - if (rareNonInheritedData->m_wrapShapeInside != other->rareNonInheritedData->m_wrapShapeInside) + if (rareNonInheritedData->m_shapeInside != other->rareNonInheritedData->m_shapeInside) return StyleDifferenceLayout; #endif } @@ -679,7 +679,7 @@ StyleDifference RenderStyle::diff(const RenderStyle* other, unsigned& changedCon // the parent container. For sure, I will have to revisit this code, but for now I've added this in order // to avoid having diff() == StyleDifferenceEqual where wrap-shapes actually differ. // Tracking bug: https://bugs.webkit.org/show_bug.cgi?id=62991 - if (rareNonInheritedData->m_wrapShapeOutside != other->rareNonInheritedData->m_wrapShapeOutside) + if (rareNonInheritedData->m_shapeOutside != other->rareNonInheritedData->m_shapeOutside) return StyleDifferenceRepaint; if (rareNonInheritedData->m_clipPath != other->rareNonInheritedData->m_clipPath) @@ -1099,7 +1099,7 @@ const AtomicString& RenderStyle::textEmphasisMarkString() const return nullAtom; } -#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) +#if ENABLE(DASHBOARD_SUPPORT) const Vector<StyleDashboardRegion>& RenderStyle::initialDashboardRegions() { DEFINE_STATIC_LOCAL(Vector<StyleDashboardRegion>, emptyList, ()); @@ -1307,6 +1307,26 @@ void RenderStyle::getShadowExtent(const ShadowData* shadow, LayoutUnit &top, Lay } } +LayoutBoxExtent RenderStyle::getShadowInsetExtent(const ShadowData* shadow) const +{ + LayoutUnit top = 0; + LayoutUnit right = 0; + LayoutUnit bottom = 0; + LayoutUnit left = 0; + + for ( ; shadow; shadow = shadow->next()) { + if (shadow->style() == Normal) + continue; + int blurAndSpread = shadow->blur() + shadow->spread(); + top = max<LayoutUnit>(top, shadow->y() + blurAndSpread); + right = min<LayoutUnit>(right, shadow->x() - blurAndSpread); + bottom = min<LayoutUnit>(bottom, shadow->y() - blurAndSpread); + left = max<LayoutUnit>(left, shadow->x() + blurAndSpread); + } + + return LayoutBoxExtent(top, right, bottom, left); +} + void RenderStyle::getShadowHorizontalExtent(const ShadowData* shadow, LayoutUnit &left, LayoutUnit &right) const { left = 0; @@ -1412,48 +1432,6 @@ Color RenderStyle::visitedDependentColor(int colorProperty) const return Color(visitedColor.red(), visitedColor.green(), visitedColor.blue(), unvisitedColor.alpha()); } -Length RenderStyle::logicalWidth() const -{ - if (isHorizontalWritingMode()) - return width(); - return height(); -} - -Length RenderStyle::logicalHeight() const -{ - if (isHorizontalWritingMode()) - return height(); - return width(); -} - -Length RenderStyle::logicalMinWidth() const -{ - if (isHorizontalWritingMode()) - return minWidth(); - return minHeight(); -} - -Length RenderStyle::logicalMaxWidth() const -{ - if (isHorizontalWritingMode()) - return maxWidth(); - return maxHeight(); -} - -Length RenderStyle::logicalMinHeight() const -{ - if (isHorizontalWritingMode()) - return minHeight(); - return minWidth(); -} - -Length RenderStyle::logicalMaxHeight() const -{ - if (isHorizontalWritingMode()) - return maxHeight(); - return maxWidth(); -} - const BorderValue& RenderStyle::borderBefore() const { switch (writingMode()) { diff --git a/Source/WebCore/rendering/style/RenderStyle.h b/Source/WebCore/rendering/style/RenderStyle.h index 7bcb38eb4..e9709474f 100644 --- a/Source/WebCore/rendering/style/RenderStyle.h +++ b/Source/WebCore/rendering/style/RenderStyle.h @@ -77,7 +77,7 @@ #include "StyleFilterData.h" #endif -#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) +#if ENABLE(DASHBOARD_SUPPORT) #include "StyleDashboardRegion.h" #endif @@ -523,12 +523,12 @@ public: Length minHeight() const { return m_box->minHeight(); } Length maxHeight() const { return m_box->maxHeight(); } - Length logicalWidth() const; - Length logicalHeight() const; - Length logicalMinWidth() const; - Length logicalMaxWidth() const; - Length logicalMinHeight() const; - Length logicalMaxHeight() const; + Length logicalWidth() const { return isHorizontalWritingMode() ? width() : height(); } + Length logicalHeight() const { return isHorizontalWritingMode() ? height() : width(); } + Length logicalMinWidth() const { return isHorizontalWritingMode() ? minWidth() : minHeight(); } + Length logicalMaxWidth() const { return isHorizontalWritingMode() ? maxWidth() : maxHeight(); } + Length logicalMinHeight() const { return isHorizontalWritingMode() ? minHeight() : minWidth(); } + Length logicalMaxHeight() const { return isHorizontalWritingMode() ? maxHeight() : maxWidth(); } const BorderData& border() const { return surround->border; } const BorderValue& borderLeft() const { return surround->border.left(); } @@ -819,6 +819,7 @@ public: const ShadowData* boxShadow() const { return rareNonInheritedData->m_boxShadow.get(); } void getBoxShadowExtent(LayoutUnit& top, LayoutUnit& right, LayoutUnit& bottom, LayoutUnit& left) const { getShadowExtent(boxShadow(), top, right, bottom, left); } + LayoutBoxExtent getBoxShadowInsetExtent() const { return getShadowInsetExtent(boxShadow()); } void getBoxShadowHorizontalExtent(LayoutUnit& left, LayoutUnit& right) const { getShadowHorizontalExtent(boxShadow(), left, right); } void getBoxShadowVerticalExtent(LayoutUnit& top, LayoutUnit& bottom) const { getShadowVerticalExtent(boxShadow(), top, bottom); } void getBoxShadowInlineDirectionExtent(LayoutUnit& logicalLeft, LayoutUnit& logicalRight) { getShadowInlineDirectionExtent(boxShadow(), logicalLeft, logicalRight); } @@ -1019,7 +1020,7 @@ public: void setMinHeight(Length v) { SET_VAR(m_box, m_minHeight, v) } void setMaxHeight(Length v) { SET_VAR(m_box, m_maxHeight, v) } -#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) +#if ENABLE(DASHBOARD_SUPPORT) Vector<StyleDashboardRegion> dashboardRegions() const { return rareNonInheritedData->m_dashboardRegions; } void setDashboardRegions(Vector<StyleDashboardRegion> regions) { SET_VAR(rareNonInheritedData, m_dashboardRegions, regions); } @@ -1038,6 +1039,11 @@ public: } #endif +#if ENABLE(WIDGET_REGION) + DraggableRegionMode getDraggableRegionMode() const { return rareNonInheritedData->m_draggableRegionMode; } + void setDraggableRegionMode(DraggableRegionMode v) { SET_VAR(rareNonInheritedData, m_draggableRegionMode, v); } +#endif + void resetBorder() { resetBorderImage(); resetBorderTop(); resetBorderRight(); resetBorderBottom(); resetBorderLeft(); resetBorderRadius(); } void resetBorderTop() { SET_VAR(surround, border.m_top, BorderValue()) } void resetBorderRight() { SET_VAR(surround, border.m_right, BorderValue()) } @@ -1445,22 +1451,22 @@ public: void setKerning(SVGLength k) { accessSVGStyle()->setKerning(k); } #endif - void setWrapShapeInside(PassRefPtr<BasicShape> shape) + void setShapeInside(PassRefPtr<BasicShape> shape) { - if (rareNonInheritedData->m_wrapShapeInside != shape) - rareNonInheritedData.access()->m_wrapShapeInside = shape; + if (rareNonInheritedData->m_shapeInside != shape) + rareNonInheritedData.access()->m_shapeInside = shape; } - BasicShape* wrapShapeInside() const { return rareNonInheritedData->m_wrapShapeInside.get(); } + BasicShape* shapeInside() const { return rareNonInheritedData->m_shapeInside.get(); } - void setWrapShapeOutside(PassRefPtr<BasicShape> shape) + void setShapeOutside(PassRefPtr<BasicShape> shape) { - if (rareNonInheritedData->m_wrapShapeOutside != shape) - rareNonInheritedData.access()->m_wrapShapeOutside = shape; + if (rareNonInheritedData->m_shapeOutside != shape) + rareNonInheritedData.access()->m_shapeOutside = shape; } - BasicShape* wrapShapeOutside() const { return rareNonInheritedData->m_wrapShapeOutside.get(); } + BasicShape* shapeOutside() const { return rareNonInheritedData->m_shapeOutside.get(); } - static BasicShape* initialWrapShapeInside() { return 0; } - static BasicShape* initialWrapShapeOutside() { return 0; } + static BasicShape* initialShapeInside() { return 0; } + static BasicShape* initialShapeOutside() { return 0; } void setClipPath(PassRefPtr<ClipPathOperation> operation) { @@ -1726,7 +1732,7 @@ public: #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING) static bool initialUseTouchOverflowScrolling() { return false; } #endif -#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) +#if ENABLE(DASHBOARD_SUPPORT) static const Vector<StyleDashboardRegion>& initialDashboardRegions(); static const Vector<StyleDashboardRegion>& noneDashboardRegions(); #endif @@ -1751,6 +1757,7 @@ private: void inheritUnicodeBidiFrom(const RenderStyle* parent) { noninherited_flags._unicodeBidi = parent->noninherited_flags._unicodeBidi; } void getShadowExtent(const ShadowData*, LayoutUnit& top, LayoutUnit& right, LayoutUnit& bottom, LayoutUnit& left) const; + LayoutBoxExtent getShadowInsetExtent(const ShadowData*) const; void getShadowHorizontalExtent(const ShadowData*, LayoutUnit& left, LayoutUnit& right) const; void getShadowVerticalExtent(const ShadowData*, LayoutUnit& top, LayoutUnit& bottom) const; void getShadowInlineDirectionExtent(const ShadowData* shadow, LayoutUnit& logicalLeft, LayoutUnit& logicalRight) const diff --git a/Source/WebCore/rendering/style/RenderStyleConstants.h b/Source/WebCore/rendering/style/RenderStyleConstants.h index 3cdfd59d0..251f68328 100644 --- a/Source/WebCore/rendering/style/RenderStyleConstants.h +++ b/Source/WebCore/rendering/style/RenderStyleConstants.h @@ -473,6 +473,10 @@ enum WrapFlow { WrapFlowAuto, WrapFlowBoth, WrapFlowStart, WrapFlowEnd, WrapFlow enum WrapThrough { WrapThroughWrap, WrapThroughNone }; +#if ENABLE(WIDGET_REGION) +enum DraggableRegionMode { DraggableRegionNone, DraggableRegionDrag, DraggableRegionNoDrag }; +#endif + } // namespace WebCore #endif // RenderStyleConstants_h diff --git a/Source/WebCore/rendering/style/StyleDashboardRegion.h b/Source/WebCore/rendering/style/StyleDashboardRegion.h index e591154e6..62992cb8a 100644 --- a/Source/WebCore/rendering/style/StyleDashboardRegion.h +++ b/Source/WebCore/rendering/style/StyleDashboardRegion.h @@ -24,7 +24,7 @@ #ifndef StyleDashboardRegion_h #define StyleDashboardRegion_h -#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) +#if ENABLE(DASHBOARD_SUPPORT) #include "LengthBox.h" #include <wtf/text/WTFString.h> @@ -57,5 +57,5 @@ struct StyleDashboardRegion { } // namespace WebCore -#endif // ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) +#endif // ENABLE(DASHBOARD_SUPPORT) #endif // StyleDashboardRegion_h diff --git a/Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp b/Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp index ff5c28d9c..1285bf6df 100644 --- a/Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp +++ b/Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp @@ -31,6 +31,7 @@ #include "StyleImage.h" #include "StyleResolver.h" #include "WebCoreMemoryInstrumentation.h" +#include <wtf/MemoryInstrumentationHashMap.h> #include <wtf/MemoryInstrumentationVector.h> namespace WebCore { @@ -43,10 +44,13 @@ StyleRareNonInheritedData::StyleRareNonInheritedData() , m_perspectiveOriginX(RenderStyle::initialPerspectiveOriginX()) , m_perspectiveOriginY(RenderStyle::initialPerspectiveOriginY()) , lineClamp(RenderStyle::initialLineClamp()) +#if ENABLE(WIDGET_REGION) + , m_draggableRegionMode(DraggableRegionNone) +#endif , m_mask(FillLayer(MaskFillLayer)) , m_pageSize() - , m_wrapShapeInside(RenderStyle::initialWrapShapeInside()) - , m_wrapShapeOutside(RenderStyle::initialWrapShapeOutside()) + , m_shapeInside(RenderStyle::initialShapeInside()) + , m_shapeOutside(RenderStyle::initialShapeOutside()) , m_wrapMargin(RenderStyle::initialWrapMargin()) , m_wrapPadding(RenderStyle::initialWrapPadding()) , m_clipPath(RenderStyle::initialClipPath()) @@ -97,6 +101,9 @@ StyleRareNonInheritedData::StyleRareNonInheritedData(const StyleRareNonInherited , m_perspectiveOriginX(o.m_perspectiveOriginX) , m_perspectiveOriginY(o.m_perspectiveOriginY) , lineClamp(o.lineClamp) +#if ENABLE(WIDGET_REGION) + , m_draggableRegionMode(o.m_draggableRegionMode) +#endif , m_deprecatedFlexibleBox(o.m_deprecatedFlexibleBox) , m_flexibleBox(o.m_flexibleBox) , m_marquee(o.m_marquee) @@ -116,8 +123,8 @@ StyleRareNonInheritedData::StyleRareNonInheritedData(const StyleRareNonInherited , m_mask(o.m_mask) , m_maskBoxImage(o.m_maskBoxImage) , m_pageSize(o.m_pageSize) - , m_wrapShapeInside(o.m_wrapShapeInside) - , m_wrapShapeOutside(o.m_wrapShapeOutside) + , m_shapeInside(o.m_shapeInside) + , m_shapeOutside(o.m_shapeOutside) , m_wrapMargin(o.m_wrapMargin) , m_wrapPadding(o.m_wrapPadding) , m_clipPath(o.m_clipPath) @@ -158,7 +165,7 @@ StyleRareNonInheritedData::StyleRareNonInheritedData(const StyleRareNonInherited #endif , m_hasAspectRatio(o.m_hasAspectRatio) #if ENABLE(CSS_COMPOSITING) - , m_effectiveBlendMode(RenderStyle::initialBlendMode()) + , m_effectiveBlendMode(o.m_effectiveBlendMode) #endif { } @@ -176,9 +183,12 @@ bool StyleRareNonInheritedData::operator==(const StyleRareNonInheritedData& o) c && m_perspectiveOriginX == o.m_perspectiveOriginX && m_perspectiveOriginY == o.m_perspectiveOriginY && lineClamp == o.lineClamp -#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) +#if ENABLE(DASHBOARD_SUPPORT) && m_dashboardRegions == o.m_dashboardRegions #endif +#if ENABLE(WIDGET_REGION) + && m_draggableRegionMode == o.m_draggableRegionMode +#endif && m_deprecatedFlexibleBox == o.m_deprecatedFlexibleBox && m_flexibleBox == o.m_flexibleBox && m_marquee == o.m_marquee @@ -198,8 +208,8 @@ bool StyleRareNonInheritedData::operator==(const StyleRareNonInheritedData& o) c && m_mask == o.m_mask && m_maskBoxImage == o.m_maskBoxImage && m_pageSize == o.m_pageSize - && m_wrapShapeInside == o.m_wrapShapeInside - && m_wrapShapeOutside == o.m_wrapShapeOutside + && m_shapeInside == o.m_shapeInside + && m_shapeOutside == o.m_shapeOutside && m_wrapMargin == o.m_wrapMargin && m_wrapPadding == o.m_wrapPadding && m_clipPath == o.m_clipPath @@ -325,8 +335,8 @@ void StyleRareNonInheritedData::reportMemoryUsage(MemoryObjectInfo* memoryObject info.addMember(m_boxReflect); info.addMember(m_animations); info.addMember(m_transitions); - info.addMember(m_wrapShapeInside); - info.addMember(m_wrapShapeOutside); + info.addMember(m_shapeInside); + info.addMember(m_shapeOutside); info.addMember(m_clipPath); info.addMember(m_flowThread); info.addMember(m_regionThread); diff --git a/Source/WebCore/rendering/style/StyleRareNonInheritedData.h b/Source/WebCore/rendering/style/StyleRareNonInheritedData.h index 41b8407e0..42924944a 100644 --- a/Source/WebCore/rendering/style/StyleRareNonInheritedData.h +++ b/Source/WebCore/rendering/style/StyleRareNonInheritedData.h @@ -57,7 +57,7 @@ class StyleTransformData; class ContentData; struct LengthSize; -#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) +#if ENABLE(DASHBOARD_SUPPORT) struct StyleDashboardRegion; #endif @@ -102,9 +102,12 @@ public: Length m_perspectiveOriginY; LineClampValue lineClamp; // An Apple extension. -#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) +#if ENABLE(DASHBOARD_SUPPORT) Vector<StyleDashboardRegion> m_dashboardRegions; #endif +#if ENABLE(WIDGET_REGION) + DraggableRegionMode m_draggableRegionMode; +#endif DataRef<StyleDeprecatedFlexibleBoxData> m_deprecatedFlexibleBox; // Flexible box properties DataRef<StyleFlexibleBoxData> m_flexibleBox; @@ -134,8 +137,8 @@ public: LengthSize m_pageSize; - RefPtr<BasicShape> m_wrapShapeInside; - RefPtr<BasicShape> m_wrapShapeOutside; + RefPtr<BasicShape> m_shapeInside; + RefPtr<BasicShape> m_shapeOutside; Length m_wrapMargin; Length m_wrapPadding; diff --git a/Source/WebCore/rendering/svg/RenderSVGBlock.cpp b/Source/WebCore/rendering/svg/RenderSVGBlock.cpp index 361279415..9f39357c1 100644 --- a/Source/WebCore/rendering/svg/RenderSVGBlock.cpp +++ b/Source/WebCore/rendering/svg/RenderSVGBlock.cpp @@ -61,9 +61,9 @@ void RenderSVGBlock::setStyle(PassRefPtr<RenderStyle> style) RenderBlock::setStyle(useStyle.release()); } -void RenderSVGBlock::updateBoxModelInfoFromStyle() +void RenderSVGBlock::updateFromStyle() { - RenderBlock::updateBoxModelInfoFromStyle(); + RenderBlock::updateFromStyle(); // RenderSVGlock, used by Render(SVGText|ForeignObject), is not allowed to call setHasOverflowClip(true). // RenderBlock assumes a layer to be present when the overflow clip functionality is requested. Both diff --git a/Source/WebCore/rendering/svg/RenderSVGBlock.h b/Source/WebCore/rendering/svg/RenderSVGBlock.h index 7f5b78532..222d5ee20 100644 --- a/Source/WebCore/rendering/svg/RenderSVGBlock.h +++ b/Source/WebCore/rendering/svg/RenderSVGBlock.h @@ -39,7 +39,7 @@ protected: private: virtual void setStyle(PassRefPtr<RenderStyle>); - virtual void updateBoxModelInfoFromStyle(); + virtual void updateFromStyle() OVERRIDE; virtual void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const; diff --git a/Source/WebCore/rendering/svg/RenderSVGForeignObject.cpp b/Source/WebCore/rendering/svg/RenderSVGForeignObject.cpp index fe0d9a12b..3b39a8335 100644 --- a/Source/WebCore/rendering/svg/RenderSVGForeignObject.cpp +++ b/Source/WebCore/rendering/svg/RenderSVGForeignObject.cpp @@ -88,12 +88,12 @@ void RenderSVGForeignObject::paint(PaintInfo& paintInfo, const LayoutPoint&) } } -LayoutRect RenderSVGForeignObject::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) const +LayoutRect RenderSVGForeignObject::clippedOverflowRectForRepaint(RenderLayerModelObject* repaintContainer) const { return SVGRenderSupport::clippedOverflowRectForRepaint(this, repaintContainer); } -void RenderSVGForeignObject::computeFloatRectForRepaint(RenderBoxModelObject* repaintContainer, FloatRect& repaintRect, bool fixed) const +void RenderSVGForeignObject::computeFloatRectForRepaint(RenderLayerModelObject* repaintContainer, FloatRect& repaintRect, bool fixed) const { SVGRenderSupport::computeFloatRectForRepaint(this, repaintContainer, repaintRect, fixed); } @@ -112,11 +112,13 @@ void RenderSVGForeignObject::updateLogicalWidth() setWidth(static_cast<int>(roundf(m_viewport.width()))); } -void RenderSVGForeignObject::updateLogicalHeight() +void RenderSVGForeignObject::computeLogicalHeight(LayoutUnit, LayoutUnit logicalTop, LogicalExtentComputedValues& computedValues) const { // FIXME: Investigate in size rounding issues // FIXME: Remove unnecessary rounding when layout is off ints: webkit.org/b/63656 - setHeight(static_cast<int>(roundf(m_viewport.height()))); + // FIXME: Is this correct for vertical writing mode? + computedValues.m_extent = static_cast<int>(roundf(m_viewport.height())); + computedValues.m_position = logicalTop; } void RenderSVGForeignObject::layout() @@ -190,12 +192,12 @@ bool RenderSVGForeignObject::nodeAtPoint(const HitTestRequest&, HitTestResult&, return false; } -void RenderSVGForeignObject::mapLocalToContainer(RenderBoxModelObject* repaintContainer, TransformState& transformState, MapLocalToContainerFlags mode, bool* wasFixed) const +void RenderSVGForeignObject::mapLocalToContainer(RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags mode, bool* wasFixed) const { SVGRenderSupport::mapLocalToContainer(this, repaintContainer, transformState, mode & SnapOffsetForTransforms, wasFixed); } -const RenderObject* RenderSVGForeignObject::pushMappingToContainer(const RenderBoxModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const +const RenderObject* RenderSVGForeignObject::pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const { return SVGRenderSupport::pushMappingToContainer(this, ancestorToStopAt, geometryMap); } diff --git a/Source/WebCore/rendering/svg/RenderSVGForeignObject.h b/Source/WebCore/rendering/svg/RenderSVGForeignObject.h index 1f37a3fcf..e20ab47c5 100644 --- a/Source/WebCore/rendering/svg/RenderSVGForeignObject.h +++ b/Source/WebCore/rendering/svg/RenderSVGForeignObject.h @@ -40,8 +40,8 @@ public: virtual void paint(PaintInfo&, const LayoutPoint&); - virtual LayoutRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) const; - virtual void computeFloatRectForRepaint(RenderBoxModelObject* repaintContainer, FloatRect&, bool fixed = false) const; + virtual LayoutRect clippedOverflowRectForRepaint(RenderLayerModelObject* repaintContainer) const OVERRIDE; + virtual void computeFloatRectForRepaint(RenderLayerModelObject* repaintContainer, FloatRect&, bool fixed = false) const OVERRIDE; virtual bool requiresLayer() const { return false; } virtual void layout(); @@ -54,13 +54,13 @@ public: virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE; virtual bool isSVGForeignObject() const { return true; } - virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, TransformState&, MapLocalToContainerFlags mode = ApplyContainerFlip | SnapOffsetForTransforms, bool* wasFixed = 0) const OVERRIDE; - virtual const RenderObject* pushMappingToContainer(const RenderBoxModelObject* ancestorToStopAt, RenderGeometryMap&) const; + virtual void mapLocalToContainer(RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip | SnapOffsetForTransforms, bool* wasFixed = 0) const OVERRIDE; + virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const OVERRIDE; virtual void setNeedsTransformUpdate() { m_needsTransformUpdate = true; } private: virtual void updateLogicalWidth() OVERRIDE; - virtual void updateLogicalHeight() OVERRIDE; + virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues&) const OVERRIDE; virtual const AffineTransform& localToParentTransform() const; virtual AffineTransform localTransform() const { return m_localTransform; } diff --git a/Source/WebCore/rendering/svg/RenderSVGGradientStop.h b/Source/WebCore/rendering/svg/RenderSVGGradientStop.h index b90ab5081..af8b89891 100644 --- a/Source/WebCore/rendering/svg/RenderSVGGradientStop.h +++ b/Source/WebCore/rendering/svg/RenderSVGGradientStop.h @@ -43,7 +43,7 @@ public: // This overrides are needed to prevent ASSERTs on <svg><stop /></svg> // RenderObject's default implementations ASSERT_NOT_REACHED() // https://bugs.webkit.org/show_bug.cgi?id=20400 - virtual LayoutRect clippedOverflowRectForRepaint(RenderBoxModelObject*) const { return LayoutRect(); } + virtual LayoutRect clippedOverflowRectForRepaint(RenderLayerModelObject*) const OVERRIDE { return LayoutRect(); } virtual FloatRect objectBoundingBox() const { return FloatRect(); } virtual FloatRect strokeBoundingBox() const { return FloatRect(); } virtual FloatRect repaintRectInLocalCoordinates() const { return FloatRect(); } diff --git a/Source/WebCore/rendering/svg/RenderSVGHiddenContainer.h b/Source/WebCore/rendering/svg/RenderSVGHiddenContainer.h index f26c5fc61..b301ea23e 100644 --- a/Source/WebCore/rendering/svg/RenderSVGHiddenContainer.h +++ b/Source/WebCore/rendering/svg/RenderSVGHiddenContainer.h @@ -43,7 +43,7 @@ private: virtual void paint(PaintInfo&, const LayoutPoint&); - virtual LayoutRect clippedOverflowRectForRepaint(RenderBoxModelObject*) const { return LayoutRect(); } + virtual LayoutRect clippedOverflowRectForRepaint(RenderLayerModelObject*) const OVERRIDE { return LayoutRect(); } virtual void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const; virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction); diff --git a/Source/WebCore/rendering/svg/RenderSVGInline.cpp b/Source/WebCore/rendering/svg/RenderSVGInline.cpp index 21bed4a15..df0b2dce5 100644 --- a/Source/WebCore/rendering/svg/RenderSVGInline.cpp +++ b/Source/WebCore/rendering/svg/RenderSVGInline.cpp @@ -69,22 +69,22 @@ FloatRect RenderSVGInline::repaintRectInLocalCoordinates() const return FloatRect(); } -LayoutRect RenderSVGInline::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) const +LayoutRect RenderSVGInline::clippedOverflowRectForRepaint(RenderLayerModelObject* repaintContainer) const { return SVGRenderSupport::clippedOverflowRectForRepaint(this, repaintContainer); } -void RenderSVGInline::computeFloatRectForRepaint(RenderBoxModelObject* repaintContainer, FloatRect& repaintRect, bool fixed) const +void RenderSVGInline::computeFloatRectForRepaint(RenderLayerModelObject* repaintContainer, FloatRect& repaintRect, bool fixed) const { SVGRenderSupport::computeFloatRectForRepaint(this, repaintContainer, repaintRect, fixed); } -void RenderSVGInline::mapLocalToContainer(RenderBoxModelObject* repaintContainer, TransformState& transformState, MapLocalToContainerFlags mode, bool* wasFixed) const +void RenderSVGInline::mapLocalToContainer(RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags mode, bool* wasFixed) const { SVGRenderSupport::mapLocalToContainer(this, repaintContainer, transformState, mode & SnapOffsetForTransforms, wasFixed); } -const RenderObject* RenderSVGInline::pushMappingToContainer(const RenderBoxModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const +const RenderObject* RenderSVGInline::pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const { return SVGRenderSupport::pushMappingToContainer(this, ancestorToStopAt, geometryMap); } diff --git a/Source/WebCore/rendering/svg/RenderSVGInline.h b/Source/WebCore/rendering/svg/RenderSVGInline.h index 8ef9ced7a..ea47a3652 100644 --- a/Source/WebCore/rendering/svg/RenderSVGInline.h +++ b/Source/WebCore/rendering/svg/RenderSVGInline.h @@ -45,10 +45,10 @@ public: virtual FloatRect strokeBoundingBox() const; virtual FloatRect repaintRectInLocalCoordinates() const; - virtual LayoutRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) const; - virtual void computeFloatRectForRepaint(RenderBoxModelObject* repaintContainer, FloatRect&, bool fixed = false) const; - virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, TransformState&, MapLocalToContainerFlags mode = ApplyContainerFlip | SnapOffsetForTransforms, bool* wasFixed = 0) const OVERRIDE; - virtual const RenderObject* pushMappingToContainer(const RenderBoxModelObject* ancestorToStopAt, RenderGeometryMap&) const; + virtual LayoutRect clippedOverflowRectForRepaint(RenderLayerModelObject* repaintContainer) const OVERRIDE; + virtual void computeFloatRectForRepaint(RenderLayerModelObject* repaintContainer, FloatRect&, bool fixed = false) const OVERRIDE; + virtual void mapLocalToContainer(RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip | SnapOffsetForTransforms, bool* wasFixed = 0) const OVERRIDE; + virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const OVERRIDE; virtual void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const; private: diff --git a/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp b/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp index 454f7aa6d..2371d1abf 100644 --- a/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp +++ b/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp @@ -158,7 +158,7 @@ bool RenderSVGInlineText::characterStartsNewTextChunk(int position) const if (it == m_layoutAttributes.characterDataMap().end()) return false; - return it->second.x != SVGTextLayoutAttributes::emptyValue() || it->second.y != SVGTextLayoutAttributes::emptyValue(); + return it->value.x != SVGTextLayoutAttributes::emptyValue() || it->value.y != SVGTextLayoutAttributes::emptyValue(); } VisiblePosition RenderSVGInlineText::positionForPoint(const LayoutPoint& point) diff --git a/Source/WebCore/rendering/svg/RenderSVGModelObject.cpp b/Source/WebCore/rendering/svg/RenderSVGModelObject.cpp index 56372b49f..7bdcd7466 100644 --- a/Source/WebCore/rendering/svg/RenderSVGModelObject.cpp +++ b/Source/WebCore/rendering/svg/RenderSVGModelObject.cpp @@ -33,6 +33,7 @@ #if ENABLE(SVG) #include "RenderSVGModelObject.h" +#include "RenderLayerModelObject.h" #include "RenderSVGResource.h" #include "SVGNames.h" #include "SVGResourcesCache.h" @@ -45,22 +46,22 @@ RenderSVGModelObject::RenderSVGModelObject(SVGStyledElement* node) { } -LayoutRect RenderSVGModelObject::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) const +LayoutRect RenderSVGModelObject::clippedOverflowRectForRepaint(RenderLayerModelObject* repaintContainer) const { return SVGRenderSupport::clippedOverflowRectForRepaint(this, repaintContainer); } -void RenderSVGModelObject::computeFloatRectForRepaint(RenderBoxModelObject* repaintContainer, FloatRect& repaintRect, bool fixed) const +void RenderSVGModelObject::computeFloatRectForRepaint(RenderLayerModelObject* repaintContainer, FloatRect& repaintRect, bool fixed) const { SVGRenderSupport::computeFloatRectForRepaint(this, repaintContainer, repaintRect, fixed); } -void RenderSVGModelObject::mapLocalToContainer(RenderBoxModelObject* repaintContainer, TransformState& transformState, MapLocalToContainerFlags mode, bool* wasFixed) const +void RenderSVGModelObject::mapLocalToContainer(RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags mode, bool* wasFixed) const { SVGRenderSupport::mapLocalToContainer(this, repaintContainer, transformState, mode & SnapOffsetForTransforms, wasFixed); } -const RenderObject* RenderSVGModelObject::pushMappingToContainer(const RenderBoxModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const +const RenderObject* RenderSVGModelObject::pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const { return SVGRenderSupport::pushMappingToContainer(this, ancestorToStopAt, geometryMap); } @@ -68,7 +69,7 @@ const RenderObject* RenderSVGModelObject::pushMappingToContainer(const RenderBox // Copied from RenderBox, this method likely requires further refactoring to work easily for both SVG and CSS Box Model content. // FIXME: This may also need to move into SVGRenderSupport as the RenderBox version depends // on borderBoundingBox() which SVG RenderBox subclases (like SVGRenderBlock) do not implement. -LayoutRect RenderSVGModelObject::outlineBoundsForRepaint(RenderBoxModelObject* repaintContainer, LayoutPoint*) const +LayoutRect RenderSVGModelObject::outlineBoundsForRepaint(RenderLayerModelObject* repaintContainer, LayoutPoint*) const { LayoutRect box = enclosingLayoutRect(repaintRectInLocalCoordinates()); adjustRectForOutlineAndShadow(box); @@ -86,7 +87,7 @@ void RenderSVGModelObject::absoluteRects(Vector<IntRect>& rects, const LayoutPoi void RenderSVGModelObject::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const { - quads.append(localToAbsoluteQuad(strokeBoundingBox(), false, wasFixed)); + quads.append(localToAbsoluteQuad(strokeBoundingBox(), 0 /* mode */, wasFixed)); } void RenderSVGModelObject::willBeDestroyed() diff --git a/Source/WebCore/rendering/svg/RenderSVGModelObject.h b/Source/WebCore/rendering/svg/RenderSVGModelObject.h index b83ca0fcb..0c4ec5b90 100644 --- a/Source/WebCore/rendering/svg/RenderSVGModelObject.h +++ b/Source/WebCore/rendering/svg/RenderSVGModelObject.h @@ -51,15 +51,15 @@ public: virtual bool requiresLayer() const { return false; } - virtual LayoutRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) const; - virtual void computeFloatRectForRepaint(RenderBoxModelObject* repaintContainer, FloatRect&, bool fixed = false) const; - virtual LayoutRect outlineBoundsForRepaint(RenderBoxModelObject* repaintContainer, LayoutPoint*) const; + virtual LayoutRect clippedOverflowRectForRepaint(RenderLayerModelObject* repaintContainer) const OVERRIDE; + virtual void computeFloatRectForRepaint(RenderLayerModelObject* repaintContainer, FloatRect&, bool fixed = false) const OVERRIDE; + virtual LayoutRect outlineBoundsForRepaint(RenderLayerModelObject* repaintContainer, LayoutPoint*) const OVERRIDE; virtual void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const; virtual void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const; - virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, TransformState&, MapLocalToContainerFlags mode = ApplyContainerFlip | SnapOffsetForTransforms, bool* wasFixed = 0) const OVERRIDE; - virtual const RenderObject* pushMappingToContainer(const RenderBoxModelObject* ancestorToStopAt, RenderGeometryMap&) const; + virtual void mapLocalToContainer(RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip | SnapOffsetForTransforms, bool* wasFixed = 0) const OVERRIDE; + virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const OVERRIDE; virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle); virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle); diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceClipper.h b/Source/WebCore/rendering/svg/RenderSVGResourceClipper.h index f2f4b0543..59157fa46 100644 --- a/Source/WebCore/rendering/svg/RenderSVGResourceClipper.h +++ b/Source/WebCore/rendering/svg/RenderSVGResourceClipper.h @@ -52,6 +52,10 @@ public: virtual void removeClientFromCache(RenderObject*, bool markForInvalidation = true); virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode); + // clipPath can be clipped too, but don't have a boundingBox or repaintRect. So we can't call + // applyResource directly and use the rects from the object, since they are empty for RenderSVGResources + // FIXME: We made applyClippingToContext public because we cannot call applyResource on HTML elements (it asserts on RenderObject::objectBoundingBox) + bool applyClippingToContext(RenderObject*, const FloatRect&, const FloatRect&, GraphicsContext*); virtual FloatRect resourceBoundingBox(RenderObject*); virtual RenderSVGResourceType resourceType() const { return ClipperResourceType; } @@ -62,9 +66,6 @@ public: static RenderSVGResourceType s_resourceType; private: - // clipPath can be clipped too, but don't have a boundingBox or repaintRect. So we can't call - // applyResource directly and use the rects from the object, since they are empty for RenderSVGResources - bool applyClippingToContext(RenderObject*, const FloatRect&, const FloatRect&, GraphicsContext*); bool pathOnlyClipping(GraphicsContext*, const AffineTransform&, const FloatRect&); bool drawContentIntoMaskImage(ClipperData*, const FloatRect& objectBoundingBox); void calculateClipContentRepaintRect(); diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp index ee6a49db8..3832b2b01 100644 --- a/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp +++ b/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp @@ -338,7 +338,7 @@ void RenderSVGResourceFilter::primitiveAttributeChanged(RenderObject* object, co SVGFilterPrimitiveStandardAttributes* primitve = static_cast<SVGFilterPrimitiveStandardAttributes*>(object->node()); for (; it != end; ++it) { - FilterData* filterData = it->second; + FilterData* filterData = it->value; if (!filterData->builded) continue; @@ -353,7 +353,7 @@ void RenderSVGResourceFilter::primitiveAttributeChanged(RenderObject* object, co builder->clearResultsRecursive(effect); // Repaint the image on the screen. - markClientForInvalidation(it->first, RepaintInvalidation); + markClientForInvalidation(it->key, RepaintInvalidation); } } diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp index 58e0079b2..30ce1b8cb 100644 --- a/Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp +++ b/Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp @@ -140,7 +140,7 @@ bool RenderSVGResourceGradient::applyResource(RenderObject* object, RenderStyle* if (gradientUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX && objectBoundingBox.isEmpty()) return false; - OwnPtr<GradientData>& gradientData = m_gradientMap.add(object, nullptr).iterator->second; + OwnPtr<GradientData>& gradientData = m_gradientMap.add(object, nullptr).iterator->value; if (!gradientData) gradientData = adoptPtr(new GradientData); diff --git a/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp b/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp index b4af99918..3a1882acf 100644 --- a/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp +++ b/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp @@ -84,7 +84,7 @@ bool RenderSVGResourcePattern::applyResource(RenderObject* object, RenderStyle* if (m_attributes.patternUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX && objectBoundingBox.isEmpty()) return false; - OwnPtr<PatternData>& patternData = m_patternMap.add(object, nullptr).iterator->second; + OwnPtr<PatternData>& patternData = m_patternMap.add(object, nullptr).iterator->value; if (!patternData) patternData = adoptPtr(new PatternData); diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceRadialGradient.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceRadialGradient.cpp index b4adeced4..bc216bbd8 100644 --- a/Source/WebCore/rendering/svg/RenderSVGResourceRadialGradient.cpp +++ b/Source/WebCore/rendering/svg/RenderSVGResourceRadialGradient.cpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> * Copyright (C) Research In Motion Limited 2010. All rights reserved. + * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -60,37 +61,17 @@ float RenderSVGResourceRadialGradient::radius(const RadialGradientAttributes& at return SVGLengthContext::resolveLength(static_cast<const SVGElement*>(node()), attributes.gradientUnits(), attributes.r()); } -void RenderSVGResourceRadialGradient::adjustFocalPointIfNeeded(float radius, const FloatPoint& centerPoint, FloatPoint& focalPoint) const +float RenderSVGResourceRadialGradient::focalRadius(const RadialGradientAttributes& attributes) const { - // Eventually adjust focal points, as described below. - float deltaX = focalPoint.x() - centerPoint.x(); - float deltaY = focalPoint.y() - centerPoint.y(); - float radiusMax = 0.99f * radius; - - // Spec: If (fx, fy) lies outside the circle defined by (cx, cy) and r, set - // (fx, fy) to the point of intersection of the line through (fx, fy) and the circle. - // We scale the radius by 0.99 to match the behavior of FireFox. - if (sqrt(deltaX * deltaX + deltaY * deltaY) <= radiusMax) - return; - - float angle = atan2f(deltaY, deltaX); - deltaX = cosf(angle) * radiusMax; - deltaY = sinf(angle) * radiusMax; - focalPoint = FloatPoint(deltaX + centerPoint.x(), deltaY + centerPoint.y()); + return SVGLengthContext::resolveLength(static_cast<const SVGElement*>(node()), attributes.gradientUnits(), attributes.fr()); } void RenderSVGResourceRadialGradient::buildGradient(GradientData* gradientData) const { - // Determine gradient focal/center points and radius - float radius = this->radius(m_attributes); - FloatPoint centerPoint = this->centerPoint(m_attributes); - FloatPoint focalPoint = this->focalPoint(m_attributes); - adjustFocalPointIfNeeded(radius, centerPoint, focalPoint); - - gradientData->gradient = Gradient::create(focalPoint, - 0, // SVG does not support a "focus radius" - centerPoint, - radius); + gradientData->gradient = Gradient::create(this->focalPoint(m_attributes), + this->focalRadius(m_attributes), + this->centerPoint(m_attributes), + this->radius(m_attributes)); gradientData->gradient->setSpreadMethod(platformSpreadMethodFromSVGType(m_attributes.spreadMethod())); diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceRadialGradient.h b/Source/WebCore/rendering/svg/RenderSVGResourceRadialGradient.h index 2a5e8cbda..6a76e80aa 100644 --- a/Source/WebCore/rendering/svg/RenderSVGResourceRadialGradient.h +++ b/Source/WebCore/rendering/svg/RenderSVGResourceRadialGradient.h @@ -47,7 +47,7 @@ public: FloatPoint centerPoint(const RadialGradientAttributes&) const; FloatPoint focalPoint(const RadialGradientAttributes&) const; float radius(const RadialGradientAttributes&) const; - void adjustFocalPointIfNeeded(float radius, const FloatPoint& centerPoint, FloatPoint& focalPoint) const; + float focalRadius(const RadialGradientAttributes&) const; private: RadialGradientAttributes m_attributes; diff --git a/Source/WebCore/rendering/svg/RenderSVGRoot.cpp b/Source/WebCore/rendering/svg/RenderSVGRoot.cpp index 747679266..c47a7bb4e 100644 --- a/Source/WebCore/rendering/svg/RenderSVGRoot.cpp +++ b/Source/WebCore/rendering/svg/RenderSVGRoot.cpp @@ -369,12 +369,12 @@ const AffineTransform& RenderSVGRoot::localToParentTransform() const return m_localToParentTransform; } -LayoutRect RenderSVGRoot::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) const +LayoutRect RenderSVGRoot::clippedOverflowRectForRepaint(RenderLayerModelObject* repaintContainer) const { return SVGRenderSupport::clippedOverflowRectForRepaint(this, repaintContainer); } -void RenderSVGRoot::computeFloatRectForRepaint(RenderBoxModelObject* repaintContainer, FloatRect& repaintRect, bool fixed) const +void RenderSVGRoot::computeFloatRectForRepaint(RenderLayerModelObject* repaintContainer, FloatRect& repaintRect, bool fixed) const { // Apply our local transforms (except for x/y translation), then our shadow, // and then call RenderBox's method to handle all the normal CSS Box model bits @@ -395,7 +395,7 @@ void RenderSVGRoot::computeFloatRectForRepaint(RenderBoxModelObject* repaintCont // This method expects local CSS box coordinates. // Callers with local SVG viewport coordinates should first apply the localToBorderBoxTransform // to convert from SVG viewport coordinates to local CSS box coordinates. -void RenderSVGRoot::mapLocalToContainer(RenderBoxModelObject* repaintContainer, TransformState& transformState, MapLocalToContainerFlags mode, bool* wasFixed) const +void RenderSVGRoot::mapLocalToContainer(RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags mode, bool* wasFixed) const { ASSERT(mode & ~IsFixed); // We should have no fixed content in the SVG rendering tree. ASSERT(mode & UseTransforms); // mapping a point through SVG w/o respecting trasnforms is useless. @@ -403,7 +403,7 @@ void RenderSVGRoot::mapLocalToContainer(RenderBoxModelObject* repaintContainer, RenderReplaced::mapLocalToContainer(repaintContainer, transformState, mode | ApplyContainerFlip, wasFixed); } -const RenderObject* RenderSVGRoot::pushMappingToContainer(const RenderBoxModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const +const RenderObject* RenderSVGRoot::pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const { return RenderReplaced::pushMappingToContainer(ancestorToStopAt, geometryMap); } diff --git a/Source/WebCore/rendering/svg/RenderSVGRoot.h b/Source/WebCore/rendering/svg/RenderSVGRoot.h index cddd311fd..3fadc910b 100644 --- a/Source/WebCore/rendering/svg/RenderSVGRoot.h +++ b/Source/WebCore/rendering/svg/RenderSVGRoot.h @@ -92,11 +92,11 @@ private: virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE; - virtual LayoutRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) const; - virtual void computeFloatRectForRepaint(RenderBoxModelObject* repaintContainer, FloatRect& repaintRect, bool fixed) const; + virtual LayoutRect clippedOverflowRectForRepaint(RenderLayerModelObject* repaintContainer) const OVERRIDE; + virtual void computeFloatRectForRepaint(RenderLayerModelObject* repaintContainer, FloatRect& repaintRect, bool fixed) const OVERRIDE; - virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, TransformState&, MapLocalToContainerFlags mode = ApplyContainerFlip | SnapOffsetForTransforms, bool* wasFixed = 0) const OVERRIDE; - virtual const RenderObject* pushMappingToContainer(const RenderBoxModelObject* ancestorToStopAt, RenderGeometryMap&) const; + virtual void mapLocalToContainer(RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip | SnapOffsetForTransforms, bool* wasFixed = 0) const OVERRIDE; + virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const OVERRIDE; virtual bool canBeSelectionLeaf() const { return false; } virtual bool canHaveChildren() const { return true; } diff --git a/Source/WebCore/rendering/svg/RenderSVGText.cpp b/Source/WebCore/rendering/svg/RenderSVGText.cpp index 2945fe48b..fd8bea043 100644 --- a/Source/WebCore/rendering/svg/RenderSVGText.cpp +++ b/Source/WebCore/rendering/svg/RenderSVGText.cpp @@ -94,29 +94,29 @@ const RenderSVGText* RenderSVGText::locateRenderSVGTextAncestor(const RenderObje return toRenderSVGText(start); } -LayoutRect RenderSVGText::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) const +LayoutRect RenderSVGText::clippedOverflowRectForRepaint(RenderLayerModelObject* repaintContainer) const { return SVGRenderSupport::clippedOverflowRectForRepaint(this, repaintContainer); } -void RenderSVGText::computeRectForRepaint(RenderBoxModelObject* repaintContainer, LayoutRect& rect, bool fixed) const +void RenderSVGText::computeRectForRepaint(RenderLayerModelObject* repaintContainer, LayoutRect& rect, bool fixed) const { FloatRect repaintRect = rect; computeFloatRectForRepaint(repaintContainer, repaintRect, fixed); rect = enclosingLayoutRect(repaintRect); } -void RenderSVGText::computeFloatRectForRepaint(RenderBoxModelObject* repaintContainer, FloatRect& repaintRect, bool fixed) const +void RenderSVGText::computeFloatRectForRepaint(RenderLayerModelObject* repaintContainer, FloatRect& repaintRect, bool fixed) const { SVGRenderSupport::computeFloatRectForRepaint(this, repaintContainer, repaintRect, fixed); } -void RenderSVGText::mapLocalToContainer(RenderBoxModelObject* repaintContainer, TransformState& transformState, MapLocalToContainerFlags mode, bool* wasFixed) const +void RenderSVGText::mapLocalToContainer(RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags mode, bool* wasFixed) const { SVGRenderSupport::mapLocalToContainer(this, repaintContainer, transformState, mode & SnapOffsetForTransforms, wasFixed); } -const RenderObject* RenderSVGText::pushMappingToContainer(const RenderBoxModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const +const RenderObject* RenderSVGText::pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const { return SVGRenderSupport::pushMappingToContainer(this, ancestorToStopAt, geometryMap); } @@ -484,7 +484,7 @@ VisiblePosition RenderSVGText::positionForPoint(const LayoutPoint& pointInConten void RenderSVGText::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const { - quads.append(localToAbsoluteQuad(strokeBoundingBox(), false, wasFixed)); + quads.append(localToAbsoluteQuad(strokeBoundingBox(), 0 /* mode */, wasFixed)); } void RenderSVGText::paint(PaintInfo& paintInfo, const LayoutPoint&) diff --git a/Source/WebCore/rendering/svg/RenderSVGText.h b/Source/WebCore/rendering/svg/RenderSVGText.h index cd2e38f79..976a6a186 100644 --- a/Source/WebCore/rendering/svg/RenderSVGText.h +++ b/Source/WebCore/rendering/svg/RenderSVGText.h @@ -71,12 +71,12 @@ private: virtual void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const; - virtual LayoutRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) const; - virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, LayoutRect&, bool fixed = false) const; - virtual void computeFloatRectForRepaint(RenderBoxModelObject* repaintContainer, FloatRect&, bool fixed = false) const; + virtual LayoutRect clippedOverflowRectForRepaint(RenderLayerModelObject* repaintContainer) const OVERRIDE; + virtual void computeRectForRepaint(RenderLayerModelObject* repaintContainer, LayoutRect&, bool fixed = false) const OVERRIDE; + virtual void computeFloatRectForRepaint(RenderLayerModelObject* repaintContainer, FloatRect&, bool fixed = false) const OVERRIDE; - virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, TransformState&, MapLocalToContainerFlags mode = ApplyContainerFlip | SnapOffsetForTransforms, bool* wasFixed = 0) const OVERRIDE; - virtual const RenderObject* pushMappingToContainer(const RenderBoxModelObject* ancestorToStopAt, RenderGeometryMap&) const; + virtual void mapLocalToContainer(RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip | SnapOffsetForTransforms, bool* wasFixed = 0) const OVERRIDE; + virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const OVERRIDE; virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0); virtual void removeChild(RenderObject*) OVERRIDE; virtual void willBeDestroyed() OVERRIDE; diff --git a/Source/WebCore/rendering/svg/SVGRenderSupport.cpp b/Source/WebCore/rendering/svg/SVGRenderSupport.cpp index fc572ad6f..697a4395c 100644 --- a/Source/WebCore/rendering/svg/SVGRenderSupport.cpp +++ b/Source/WebCore/rendering/svg/SVGRenderSupport.cpp @@ -46,7 +46,7 @@ namespace WebCore { -LayoutRect SVGRenderSupport::clippedOverflowRectForRepaint(const RenderObject* object, RenderBoxModelObject* repaintContainer) +LayoutRect SVGRenderSupport::clippedOverflowRectForRepaint(const RenderObject* object, RenderLayerModelObject* repaintContainer) { // Return early for any cases where we don't actually paint if (object->style()->visibility() != VISIBLE && !object->enclosingLayer()->hasVisibleContent()) @@ -59,7 +59,7 @@ LayoutRect SVGRenderSupport::clippedOverflowRectForRepaint(const RenderObject* o return enclosingLayoutRect(repaintRect); } -void SVGRenderSupport::computeFloatRectForRepaint(const RenderObject* object, RenderBoxModelObject* repaintContainer, FloatRect& repaintRect, bool fixed) +void SVGRenderSupport::computeFloatRectForRepaint(const RenderObject* object, RenderLayerModelObject* repaintContainer, FloatRect& repaintRect, bool fixed) { const SVGRenderStyle* svgStyle = object->style()->svgStyle(); if (const ShadowData* shadow = svgStyle->shadow()) @@ -71,7 +71,7 @@ void SVGRenderSupport::computeFloatRectForRepaint(const RenderObject* object, Re object->parent()->computeFloatRectForRepaint(repaintContainer, repaintRect, fixed); } -void SVGRenderSupport::mapLocalToContainer(const RenderObject* object, RenderBoxModelObject* repaintContainer, TransformState& transformState, bool snapOffsetForTransforms, bool* wasFixed) +void SVGRenderSupport::mapLocalToContainer(const RenderObject* object, RenderLayerModelObject* repaintContainer, TransformState& transformState, bool snapOffsetForTransforms, bool* wasFixed) { transformState.applyTransform(object->localToParentTransform()); @@ -83,13 +83,13 @@ void SVGRenderSupport::mapLocalToContainer(const RenderObject* object, RenderBox if (parent->isSVGRoot()) transformState.applyTransform(toRenderSVGRoot(parent)->localToBorderBoxTransform()); - MapLocalToContainerFlags mode = UseTransforms; + MapCoordinatesFlags mode = UseTransforms; if (snapOffsetForTransforms) mode |= SnapOffsetForTransforms; parent->mapLocalToContainer(repaintContainer, transformState, mode, wasFixed); } -const RenderObject* SVGRenderSupport::pushMappingToContainer(const RenderObject* object, const RenderBoxModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) +const RenderObject* SVGRenderSupport::pushMappingToContainer(const RenderObject* object, const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) { ASSERT_UNUSED(ancestorToStopAt, ancestorToStopAt != object); diff --git a/Source/WebCore/rendering/svg/SVGRenderSupport.h b/Source/WebCore/rendering/svg/SVGRenderSupport.h index b62ccfb2f..3286f8fe8 100644 --- a/Source/WebCore/rendering/svg/SVGRenderSupport.h +++ b/Source/WebCore/rendering/svg/SVGRenderSupport.h @@ -35,6 +35,7 @@ class FloatRect; class ImageBuffer; class RenderBoxModelObject; class RenderGeometryMap; +class RenderLayerModelObject; class RenderObject; class RenderStyle; class RenderSVGRoot; @@ -62,10 +63,10 @@ public: static bool paintInfoIntersectsRepaintRect(const FloatRect& localRepaintRect, const AffineTransform& localTransform, const PaintInfo&); // Important functions used by nearly all SVG renderers centralizing coordinate transformations / repaint rect calculations - static LayoutRect clippedOverflowRectForRepaint(const RenderObject*, RenderBoxModelObject* repaintContainer); - static void computeFloatRectForRepaint(const RenderObject*, RenderBoxModelObject* repaintContainer, FloatRect&, bool fixed); - static void mapLocalToContainer(const RenderObject*, RenderBoxModelObject* repaintContainer, TransformState&, bool snapOffsetForTransforms = true, bool* wasFixed = 0); - static const RenderObject* pushMappingToContainer(const RenderObject*, const RenderBoxModelObject* ancestorToStopAt, RenderGeometryMap&); + static LayoutRect clippedOverflowRectForRepaint(const RenderObject*, RenderLayerModelObject* repaintContainer); + static void computeFloatRectForRepaint(const RenderObject*, RenderLayerModelObject* repaintContainer, FloatRect&, bool fixed); + static void mapLocalToContainer(const RenderObject*, RenderLayerModelObject* repaintContainer, TransformState&, bool snapOffsetForTransforms = true, bool* wasFixed = 0); + static const RenderObject* pushMappingToContainer(const RenderObject*, const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&); // Shared between SVG renderers and resources. static void applyStrokeStyleToContext(GraphicsContext*, const RenderStyle*, const RenderObject*); diff --git a/Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp b/Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp index 838d8a150..12352ae72 100755 --- a/Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp +++ b/Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp @@ -573,9 +573,9 @@ void writeSVGResourceContainer(TextStream& ts, const RenderObject& object, int i FloatPoint focalPoint = gradient->focalPoint(attributes); FloatPoint centerPoint = gradient->centerPoint(attributes); float radius = gradient->radius(attributes); - gradient->adjustFocalPointIfNeeded(radius, centerPoint, focalPoint); + float focalRadius = gradient->focalRadius(attributes); - ts << " [center=" << centerPoint << "] [focal=" << focalPoint << "] [radius=" << radius << "]\n"; + ts << " [center=" << centerPoint << "] [focal=" << focalPoint << "] [radius=" << radius << "] [focalRadius=" << focalRadius << "]\n"; } else ts << "\n"; writeChildren(ts, object, indent); diff --git a/Source/WebCore/rendering/svg/SVGResources.cpp b/Source/WebCore/rendering/svg/SVGResources.cpp index 27120dc88..d9097409d 100644 --- a/Source/WebCore/rendering/svg/SVGResources.cpp +++ b/Source/WebCore/rendering/svg/SVGResources.cpp @@ -44,46 +44,46 @@ SVGResources::SVGResources() { } -static HashSet<AtomicStringImpl*>& clipperFilterMaskerTags() +static HashSet<AtomicString>& clipperFilterMaskerTags() { - DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, s_tagList, ()); + DEFINE_STATIC_LOCAL(HashSet<AtomicString>, s_tagList, ()); if (s_tagList.isEmpty()) { // "container elements": http://www.w3.org/TR/SVG11/intro.html#TermContainerElement // "graphics elements" : http://www.w3.org/TR/SVG11/intro.html#TermGraphicsElement - s_tagList.add(SVGNames::aTag.localName().impl()); - s_tagList.add(SVGNames::circleTag.localName().impl()); - s_tagList.add(SVGNames::ellipseTag.localName().impl()); - s_tagList.add(SVGNames::glyphTag.localName().impl()); - s_tagList.add(SVGNames::gTag.localName().impl()); - s_tagList.add(SVGNames::imageTag.localName().impl()); - s_tagList.add(SVGNames::lineTag.localName().impl()); - s_tagList.add(SVGNames::markerTag.localName().impl()); - s_tagList.add(SVGNames::maskTag.localName().impl()); - s_tagList.add(SVGNames::missing_glyphTag.localName().impl()); - s_tagList.add(SVGNames::pathTag.localName().impl()); - s_tagList.add(SVGNames::polygonTag.localName().impl()); - s_tagList.add(SVGNames::polylineTag.localName().impl()); - s_tagList.add(SVGNames::rectTag.localName().impl()); - s_tagList.add(SVGNames::svgTag.localName().impl()); - s_tagList.add(SVGNames::textTag.localName().impl()); - s_tagList.add(SVGNames::useTag.localName().impl()); + s_tagList.add(SVGNames::aTag.localName()); + s_tagList.add(SVGNames::circleTag.localName()); + s_tagList.add(SVGNames::ellipseTag.localName()); + s_tagList.add(SVGNames::glyphTag.localName()); + s_tagList.add(SVGNames::gTag.localName()); + s_tagList.add(SVGNames::imageTag.localName()); + s_tagList.add(SVGNames::lineTag.localName()); + s_tagList.add(SVGNames::markerTag.localName()); + s_tagList.add(SVGNames::maskTag.localName()); + s_tagList.add(SVGNames::missing_glyphTag.localName()); + s_tagList.add(SVGNames::pathTag.localName()); + s_tagList.add(SVGNames::polygonTag.localName()); + s_tagList.add(SVGNames::polylineTag.localName()); + s_tagList.add(SVGNames::rectTag.localName()); + s_tagList.add(SVGNames::svgTag.localName()); + s_tagList.add(SVGNames::textTag.localName()); + s_tagList.add(SVGNames::useTag.localName()); // Not listed in the definitions is the clipPath element, the SVG spec says though: // The "clipPath" element or any of its children can specify property "clip-path". // So we have to add clipPathTag here, otherwhise clip-path on clipPath will fail. // (Already mailed SVG WG, waiting for a solution) - s_tagList.add(SVGNames::clipPathTag.localName().impl()); + s_tagList.add(SVGNames::clipPathTag.localName()); // Not listed in the definitions are the text content elements, though filter/clipper/masker on tspan/text/.. is allowed. // (Already mailed SVG WG, waiting for a solution) - s_tagList.add(SVGNames::altGlyphTag.localName().impl()); - s_tagList.add(SVGNames::textPathTag.localName().impl()); - s_tagList.add(SVGNames::trefTag.localName().impl()); - s_tagList.add(SVGNames::tspanTag.localName().impl()); + s_tagList.add(SVGNames::altGlyphTag.localName()); + s_tagList.add(SVGNames::textPathTag.localName()); + s_tagList.add(SVGNames::trefTag.localName()); + s_tagList.add(SVGNames::tspanTag.localName()); // Not listed in the definitions is the foreignObject element, but clip-path // is a supported attribute. - s_tagList.add(SVGNames::foreignObjectTag.localName().impl()); + s_tagList.add(SVGNames::foreignObjectTag.localName()); // Elements that we ignore, as it doesn't make any sense. // defs, pattern, switch (FIXME: Mail SVG WG about these) @@ -93,48 +93,48 @@ static HashSet<AtomicStringImpl*>& clipperFilterMaskerTags() return s_tagList; } -static HashSet<AtomicStringImpl*>& markerTags() +static HashSet<AtomicString>& markerTags() { - DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, s_tagList, ()); + DEFINE_STATIC_LOCAL(HashSet<AtomicString>, s_tagList, ()); if (s_tagList.isEmpty()) { - s_tagList.add(SVGNames::lineTag.localName().impl()); - s_tagList.add(SVGNames::pathTag.localName().impl()); - s_tagList.add(SVGNames::polygonTag.localName().impl()); - s_tagList.add(SVGNames::polylineTag.localName().impl()); + s_tagList.add(SVGNames::lineTag.localName()); + s_tagList.add(SVGNames::pathTag.localName()); + s_tagList.add(SVGNames::polygonTag.localName()); + s_tagList.add(SVGNames::polylineTag.localName()); } return s_tagList; } -static HashSet<AtomicStringImpl*>& fillAndStrokeTags() +static HashSet<AtomicString>& fillAndStrokeTags() { - DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, s_tagList, ()); + DEFINE_STATIC_LOCAL(HashSet<AtomicString>, s_tagList, ()); if (s_tagList.isEmpty()) { - s_tagList.add(SVGNames::altGlyphTag.localName().impl()); - s_tagList.add(SVGNames::circleTag.localName().impl()); - s_tagList.add(SVGNames::ellipseTag.localName().impl()); - s_tagList.add(SVGNames::lineTag.localName().impl()); - s_tagList.add(SVGNames::pathTag.localName().impl()); - s_tagList.add(SVGNames::polygonTag.localName().impl()); - s_tagList.add(SVGNames::polylineTag.localName().impl()); - s_tagList.add(SVGNames::rectTag.localName().impl()); - s_tagList.add(SVGNames::textTag.localName().impl()); - s_tagList.add(SVGNames::textPathTag.localName().impl()); - s_tagList.add(SVGNames::trefTag.localName().impl()); - s_tagList.add(SVGNames::tspanTag.localName().impl()); + s_tagList.add(SVGNames::altGlyphTag.localName()); + s_tagList.add(SVGNames::circleTag.localName()); + s_tagList.add(SVGNames::ellipseTag.localName()); + s_tagList.add(SVGNames::lineTag.localName()); + s_tagList.add(SVGNames::pathTag.localName()); + s_tagList.add(SVGNames::polygonTag.localName()); + s_tagList.add(SVGNames::polylineTag.localName()); + s_tagList.add(SVGNames::rectTag.localName()); + s_tagList.add(SVGNames::textTag.localName()); + s_tagList.add(SVGNames::textPathTag.localName()); + s_tagList.add(SVGNames::trefTag.localName()); + s_tagList.add(SVGNames::tspanTag.localName()); } return s_tagList; } -static HashSet<AtomicStringImpl*>& chainableResourceTags() +static HashSet<AtomicString>& chainableResourceTags() { - DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, s_tagList, ()); + DEFINE_STATIC_LOCAL(HashSet<AtomicString>, s_tagList, ()); if (s_tagList.isEmpty()) { - s_tagList.add(SVGNames::linearGradientTag.localName().impl()); - s_tagList.add(SVGNames::filterTag.localName().impl()); - s_tagList.add(SVGNames::patternTag.localName().impl()); - s_tagList.add(SVGNames::radialGradientTag.localName().impl()); + s_tagList.add(SVGNames::linearGradientTag.localName()); + s_tagList.add(SVGNames::filterTag.localName()); + s_tagList.add(SVGNames::patternTag.localName()); + s_tagList.add(SVGNames::radialGradientTag.localName()); } return s_tagList; @@ -202,12 +202,12 @@ bool SVGResources::buildCachedResources(const RenderObject* object, const SVGRen SVGDocumentExtensions* extensions = document->accessSVGExtensions(); ASSERT(extensions); - AtomicStringImpl* tagNameImpl = element->tagQName().localName().impl(); - if (!tagNameImpl) + const AtomicString& tagName = element->localName(); + if (tagName.isNull()) return false; bool foundResources = false; - if (clipperFilterMaskerTags().contains(tagNameImpl)) { + if (clipperFilterMaskerTags().contains(tagName)) { if (style->hasClipper()) { AtomicString id(style->clipperResource()); if (setClipper(getRenderSVGResourceById<RenderSVGResourceClipper>(document, id))) @@ -235,7 +235,7 @@ bool SVGResources::buildCachedResources(const RenderObject* object, const SVGRen } } - if (markerTags().contains(tagNameImpl) && style->hasMarkers()) { + if (markerTags().contains(tagName) && style->hasMarkers()) { AtomicString markerStartId(style->markerStartResource()); if (setMarkerStart(getRenderSVGResourceById<RenderSVGResourceMarker>(document, markerStartId))) foundResources = true; @@ -255,7 +255,7 @@ bool SVGResources::buildCachedResources(const RenderObject* object, const SVGRen registerPendingResource(extensions, markerEndId, element); } - if (fillAndStrokeTags().contains(tagNameImpl)) { + if (fillAndStrokeTags().contains(tagName)) { if (style->hasFill()) { bool hasPendingResource = false; AtomicString id; @@ -275,7 +275,7 @@ bool SVGResources::buildCachedResources(const RenderObject* object, const SVGRen } } - if (chainableResourceTags().contains(tagNameImpl)) { + if (chainableResourceTags().contains(tagName)) { AtomicString id(targetReferenceFromResource(element)); if (setLinkedResource(getRenderSVGResourceContainerById(document, id))) foundResources = true; diff --git a/Source/WebCore/rendering/svg/SVGResourcesCache.cpp b/Source/WebCore/rendering/svg/SVGResourcesCache.cpp index 297c07b6a..8b48cf53e 100644 --- a/Source/WebCore/rendering/svg/SVGResourcesCache.cpp +++ b/Source/WebCore/rendering/svg/SVGResourcesCache.cpp @@ -198,11 +198,11 @@ void SVGResourcesCache::resourceDestroyed(RenderSVGResourceContainer* resource) HashMap<const RenderObject*, SVGResources*>::iterator end = cache->m_cache.end(); for (HashMap<const RenderObject*, SVGResources*>::iterator it = cache->m_cache.begin(); it != end; ++it) { - it->second->resourceDestroyed(resource); + it->value->resourceDestroyed(resource); // Mark users of destroyed resources as pending resolution based on the id of the old resource. Element* resourceElement = toElement(resource->node()); - SVGStyledElement* clientElement = toSVGStyledElement(it->first->node()); + SVGStyledElement* clientElement = toSVGStyledElement(it->key->node()); SVGDocumentExtensions* extensions = clientElement->document()->accessSVGExtensions(); extensions->addPendingResource(resourceElement->fastGetAttribute(HTMLNames::idAttr), clientElement); diff --git a/Source/WebCore/rendering/svg/SVGRootInlineBox.cpp b/Source/WebCore/rendering/svg/SVGRootInlineBox.cpp index 34e93a02e..546fec26c 100644 --- a/Source/WebCore/rendering/svg/SVGRootInlineBox.cpp +++ b/Source/WebCore/rendering/svg/SVGRootInlineBox.cpp @@ -226,17 +226,17 @@ static inline void swapItemsInLayoutAttributes(SVGTextLayoutAttributes* firstAtt return; if (firstPresent && lastPresent) { - std::swap(itFirst->second, itLast->second); + std::swap(itFirst->value, itLast->value); return; } if (firstPresent && !lastPresent) { - lastAttributes->characterDataMap().set(lastPosition + 1, itFirst->second); + lastAttributes->characterDataMap().set(lastPosition + 1, itFirst->value); return; } // !firstPresent && lastPresent - firstAttributes->characterDataMap().set(firstPosition + 1, itLast->second); + firstAttributes->characterDataMap().set(firstPosition + 1, itLast->value); } static inline void findFirstAndLastAttributesInVector(Vector<SVGTextLayoutAttributes*>& attributes, RenderSVGInlineText* firstContext, RenderSVGInlineText* lastContext, diff --git a/Source/WebCore/rendering/svg/SVGTextLayoutAttributes.cpp b/Source/WebCore/rendering/svg/SVGTextLayoutAttributes.cpp index a92596cee..67fa0fa98 100644 --- a/Source/WebCore/rendering/svg/SVGTextLayoutAttributes.cpp +++ b/Source/WebCore/rendering/svg/SVGTextLayoutAttributes.cpp @@ -62,8 +62,8 @@ void SVGTextLayoutAttributes::dump() const fprintf(stderr, "context: %p\n", m_context); const SVGCharacterDataMap::const_iterator end = m_characterDataMap.end(); for (SVGCharacterDataMap::const_iterator it = m_characterDataMap.begin(); it != end; ++it) { - const SVGCharacterData& data = it->second; - fprintf(stderr, " ---> pos=%i, data={", it->first); + const SVGCharacterData& data = it->value; + fprintf(stderr, " ---> pos=%i, data={", it->key); dumpSVGCharacterDataMapValue("x", data.x); dumpSVGCharacterDataMapValue("y", data.y); dumpSVGCharacterDataMapValue("dx", data.dx); diff --git a/Source/WebCore/rendering/svg/SVGTextLayoutAttributesBuilder.cpp b/Source/WebCore/rendering/svg/SVGTextLayoutAttributesBuilder.cpp index be2a12fe9..b969a5319 100644 --- a/Source/WebCore/rendering/svg/SVGTextLayoutAttributesBuilder.cpp +++ b/Source/WebCore/rendering/svg/SVGTextLayoutAttributesBuilder.cpp @@ -149,7 +149,7 @@ void SVGTextLayoutAttributesBuilder::buildCharacterDataMap(RenderSVGText* textRo data.y = 0; m_characterDataMap.set(1, data); } else { - SVGCharacterData& data = it->second; + SVGCharacterData& data = it->value; if (data.x == SVGTextLayoutAttributes::emptyValue()) data.x = 0; if (data.y == SVGTextLayoutAttributes::emptyValue()) @@ -213,7 +213,7 @@ void SVGTextLayoutAttributesBuilder::fillCharacterDataMap(const TextPosition& po continue; } - updateCharacterData(i, lastRotation, it->second, lengthContext, xListPtr, yListPtr, dxListPtr, dyListPtr, rotateListPtr); + updateCharacterData(i, lastRotation, it->value, lengthContext, xListPtr, yListPtr, dxListPtr, dyListPtr, rotateListPtr); } // The last rotation value always spans the whole scope. @@ -229,7 +229,7 @@ void SVGTextLayoutAttributesBuilder::fillCharacterDataMap(const TextPosition& po continue; } - it->second.rotate = lastRotation; + it->value.rotate = lastRotation; } } diff --git a/Source/WebCore/rendering/svg/SVGTextLayoutEngine.cpp b/Source/WebCore/rendering/svg/SVGTextLayoutEngine.cpp index 5c549b21c..ba2b7639d 100644 --- a/Source/WebCore/rendering/svg/SVGTextLayoutEngine.cpp +++ b/Source/WebCore/rendering/svg/SVGTextLayoutEngine.cpp @@ -475,7 +475,7 @@ void SVGTextLayoutEngine::layoutTextOnLineOrPath(SVGInlineTextBox* textBox, Rend SVGCharacterData data; SVGCharacterDataMap::iterator it = characterDataMap.find(m_logicalCharacterOffset + 1); if (it != characterDataMap.end()) - data = it->second; + data = it->value; float x = data.x; float y = data.y; diff --git a/Source/WebCore/rendering/svg/SVGTextMetricsBuilder.cpp b/Source/WebCore/rendering/svg/SVGTextMetricsBuilder.cpp index ff9ca3073..ca7481f39 100644 --- a/Source/WebCore/rendering/svg/SVGTextMetricsBuilder.cpp +++ b/Source/WebCore/rendering/svg/SVGTextMetricsBuilder.cpp @@ -161,7 +161,7 @@ void SVGTextMetricsBuilder::measureTextRenderer(RenderSVGInlineText* text, Measu if (data->allCharactersMap) { const SVGCharacterDataMap::const_iterator it = data->allCharactersMap->find(data->valueListPosition + m_textPosition - data->skippedCharacters - surrogatePairCharacters + 1); if (it != data->allCharactersMap->end()) - attributes->characterDataMap().set(m_textPosition + 1, it->second); + attributes->characterDataMap().set(m_textPosition + 1, it->value); } textMetricsValues->append(m_currentMetrics); } diff --git a/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp b/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp index 0124eda32..05b88a975 100644 --- a/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp +++ b/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp @@ -188,6 +188,7 @@ GlyphData SVGTextRunRenderingContext::glyphDataForCharacter(const Font& font, co } // Characters enclosed by an <altGlyph> element, may not be registered in the GlyphPage. + const SimpleFontData* originalFontData = glyphData.fontData; if (glyphData.fontData && !glyphData.fontData->isSVGFont()) { if (TextRun::RenderingContext* renderingContext = run.renderingContext()) { RenderObject* renderObject = static_cast<SVGTextRunRenderingContext*>(renderingContext)->renderer(); @@ -239,7 +240,7 @@ GlyphData SVGTextRunRenderingContext::glyphDataForCharacter(const Font& font, co // Restore original state of the SVG Font glyph table and the current font fallback list, // to assure the next lookup of the same glyph won't immediately return the fallback glyph. - page->setGlyphDataForCharacter(character, glyphData.glyph, fontData); + page->setGlyphDataForCharacter(character, glyphData.glyph, originalFontData); fontList->setGlyphPageZero(originalGlyphPageZero); fontList->setGlyphPages(originalGlyphPages); ASSERT(fallbackGlyphData.fontData); |