OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
4 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights
reserved. | 4 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights
reserved. |
5 * | 5 * |
6 * This library is free software; you can redistribute it and/or | 6 * This library is free software; you can redistribute it and/or |
7 * modify it under the terms of the GNU Library General Public | 7 * modify it under the terms of the GNU Library General Public |
8 * License as published by the Free Software Foundation; either | 8 * License as published by the Free Software Foundation; either |
9 * version 2 of the License, or (at your option) any later version. | 9 * version 2 of the License, or (at your option) any later version. |
10 * | 10 * |
(...skipping 1030 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1041 | 1041 |
1042 LayoutRect LayoutInline::clippedOverflowRect(const LayoutBoxModelObject* paintIn
validationContainer, const PaintInvalidationState* paintInvalidationState) const | 1042 LayoutRect LayoutInline::clippedOverflowRect(const LayoutBoxModelObject* paintIn
validationContainer, const PaintInvalidationState* paintInvalidationState) const |
1043 { | 1043 { |
1044 if (style()->visibility() != VISIBLE) | 1044 if (style()->visibility() != VISIBLE) |
1045 return LayoutRect(); | 1045 return LayoutRect(); |
1046 | 1046 |
1047 LayoutRect overflowRect(visualOverflowRect()); | 1047 LayoutRect overflowRect(visualOverflowRect()); |
1048 if (overflowRect.isEmpty()) | 1048 if (overflowRect.isEmpty()) |
1049 return overflowRect; | 1049 return overflowRect; |
1050 | 1050 |
1051 mapToVisibleRectInContainerSpace(paintInvalidationContainer, overflowRect, p
aintInvalidationState); | 1051 mapToVisibleRectInAncestorSpace(paintInvalidationContainer, overflowRect, pa
intInvalidationState); |
1052 return overflowRect; | 1052 return overflowRect; |
1053 } | 1053 } |
1054 | 1054 |
1055 LayoutRect LayoutInline::visualOverflowRect() const | 1055 LayoutRect LayoutInline::visualOverflowRect() const |
1056 { | 1056 { |
1057 LayoutRect overflowRect = linesVisualOverflowBoundingBox(); | 1057 LayoutRect overflowRect = linesVisualOverflowBoundingBox(); |
1058 LayoutUnit outlineOutset = style()->outlineOutsetExtent(); | 1058 LayoutUnit outlineOutset = style()->outlineOutsetExtent(); |
1059 if (outlineOutset) { | 1059 if (outlineOutset) { |
1060 Vector<LayoutRect> rects; | 1060 Vector<LayoutRect> rects; |
1061 // We have already included outline extents of line boxes in linesVisual
OverflowBoundingBox(), | 1061 // We have already included outline extents of line boxes in linesVisual
OverflowBoundingBox(), |
1062 // so the following just add outline rects for children and continuation
s. | 1062 // so the following just add outline rects for children and continuation
s. |
1063 addOutlineRectsForChildrenAndContinuations(rects, LayoutPoint(), outline
RectsShouldIncludeBlockVisualOverflow()); | 1063 addOutlineRectsForChildrenAndContinuations(rects, LayoutPoint(), outline
RectsShouldIncludeBlockVisualOverflow()); |
1064 if (!rects.isEmpty()) { | 1064 if (!rects.isEmpty()) { |
1065 LayoutRect outlineRect = unionRectEvenIfEmpty(rects); | 1065 LayoutRect outlineRect = unionRectEvenIfEmpty(rects); |
1066 outlineRect.inflate(outlineOutset); | 1066 outlineRect.inflate(outlineOutset); |
1067 overflowRect.unite(outlineRect); | 1067 overflowRect.unite(outlineRect); |
1068 } | 1068 } |
1069 } | 1069 } |
1070 return overflowRect; | 1070 return overflowRect; |
1071 } | 1071 } |
1072 | 1072 |
1073 void LayoutInline::mapToVisibleRectInContainerSpace(const LayoutBoxModelObject*
paintInvalidationContainer, LayoutRect& rect, const PaintInvalidationState* pain
tInvalidationState) const | 1073 void LayoutInline::mapToVisibleRectInAncestorSpace(const LayoutBoxModelObject* a
ncestor, LayoutRect& rect, const PaintInvalidationState* paintInvalidationState)
const |
1074 { | 1074 { |
1075 if (paintInvalidationState && paintInvalidationState->canMapToContainer(pain
tInvalidationContainer)) { | 1075 if (paintInvalidationState && paintInvalidationState->canMapToContainer(ance
stor)) { |
1076 if (style()->hasInFlowPosition() && layer()) | 1076 if (style()->hasInFlowPosition() && layer()) |
1077 rect.move(layer()->offsetForInFlowPosition()); | 1077 rect.move(layer()->offsetForInFlowPosition()); |
1078 rect.move(paintInvalidationState->paintOffset()); | 1078 rect.move(paintInvalidationState->paintOffset()); |
1079 if (paintInvalidationState->isClipped()) | 1079 if (paintInvalidationState->isClipped()) |
1080 rect.intersect(paintInvalidationState->clipRect()); | 1080 rect.intersect(paintInvalidationState->clipRect()); |
1081 return; | 1081 return; |
1082 } | 1082 } |
1083 | 1083 |
1084 if (paintInvalidationContainer == this) | 1084 if (ancestor == this) |
1085 return; | 1085 return; |
1086 | 1086 |
1087 bool containerSkipped; | 1087 bool ancestorSkipped; |
1088 LayoutObject* o = container(paintInvalidationContainer, &containerSkipped); | 1088 LayoutObject* container = this->container(ancestor, &ancestorSkipped); |
1089 if (!o) | 1089 if (!container) |
1090 return; | 1090 return; |
1091 | 1091 |
1092 LayoutPoint topLeft = rect.location(); | 1092 LayoutPoint topLeft = rect.location(); |
1093 | 1093 |
1094 if (style()->hasInFlowPosition() && layer()) { | 1094 if (style()->hasInFlowPosition() && layer()) { |
1095 // Apply the in-flow position offset when invalidating a rectangle. The
layer | 1095 // Apply the in-flow position offset when invalidating a rectangle. The
layer |
1096 // is translated, but the layout box isn't, so we need to do this to get
the | 1096 // is translated, but the layout box isn't, so we need to do this to get
the |
1097 // right dirty rect. Since this is called from LayoutObject::setStyle, t
he relative position | 1097 // right dirty rect. Since this is called from LayoutObject::setStyle, t
he relative position |
1098 // flag on the LayoutObject has been cleared, so use the one on the styl
e(). | 1098 // flag on the LayoutObject has been cleared, so use the one on the styl
e(). |
1099 topLeft += layer()->offsetForInFlowPosition(); | 1099 topLeft += layer()->offsetForInFlowPosition(); |
1100 } | 1100 } |
1101 | 1101 |
1102 // FIXME: We ignore the lightweight clipping rect that controls use, since i
f |o| is in mid-layout, | 1102 // FIXME: We ignore the lightweight clipping rect that controls use, since i
f |o| is in mid-layout, |
1103 // its controlClipRect will be wrong. For overflow clip we use the values ca
ched by the layer. | 1103 // its controlClipRect will be wrong. For overflow clip we use the values ca
ched by the layer. |
1104 rect.setLocation(topLeft); | 1104 rect.setLocation(topLeft); |
1105 if (o->hasOverflowClip()) { | 1105 if (container->hasOverflowClip()) { |
1106 LayoutBox* containerBox = toLayoutBox(o); | 1106 LayoutBox* containerBox = toLayoutBox(container); |
1107 if (o == paintInvalidationContainer) | 1107 containerBox->mapScrollingContentsRectToBoxSpace(rect); |
1108 containerBox->applyCachedScrollOffsetForPaintInvalidation(rect); | 1108 if (container != ancestor) |
1109 else | 1109 containerBox->applyOverflowClip(rect); |
1110 containerBox->applyCachedClipAndScrollOffsetForPaintInvalidation(rec
t); | |
1111 if (rect.isEmpty()) | 1110 if (rect.isEmpty()) |
1112 return; | 1111 return; |
1113 } | 1112 } |
1114 | 1113 |
1115 if (containerSkipped) { | 1114 if (ancestorSkipped) { |
1116 // If the paintInvalidationContainer is below o, then we need to map the
rect into paintInvalidationContainer's coordinates. | 1115 // If the paintInvalidationContainer is below o, then we need to map the
rect into paintInvalidationContainer's coordinates. |
1117 LayoutSize containerOffset = paintInvalidationContainer->offsetFromAnces
torContainer(o); | 1116 LayoutSize containerOffset = ancestor->offsetFromAncestorContainer(conta
iner); |
1118 rect.move(-containerOffset); | 1117 rect.move(-containerOffset); |
1119 return; | 1118 return; |
1120 } | 1119 } |
1121 | 1120 |
1122 o->mapToVisibleRectInContainerSpace(paintInvalidationContainer, rect, paintI
nvalidationState); | 1121 container->mapToVisibleRectInAncestorSpace(ancestor, rect, paintInvalidation
State); |
1123 } | 1122 } |
1124 | 1123 |
1125 LayoutSize LayoutInline::offsetFromContainer(const LayoutObject* container, cons
t LayoutPoint& point, bool* offsetDependsOnPoint) const | 1124 LayoutSize LayoutInline::offsetFromContainer(const LayoutObject* container, cons
t LayoutPoint& point, bool* offsetDependsOnPoint) const |
1126 { | 1125 { |
1127 ASSERT(container == this->container()); | 1126 ASSERT(container == this->container()); |
1128 | 1127 |
1129 LayoutSize offset; | 1128 LayoutSize offset; |
1130 if (isInFlowPositioned()) | 1129 if (isInFlowPositioned()) |
1131 offset += offsetForInFlowPosition(); | 1130 offset += offsetForInFlowPosition(); |
1132 | 1131 |
1133 offset += container->columnOffset(point); | 1132 offset += container->columnOffset(point); |
1134 | 1133 |
1135 if (container->hasOverflowClip()) | 1134 if (container->hasOverflowClip()) |
1136 offset -= toLayoutBox(container)->scrolledContentOffset(); | 1135 offset -= toLayoutBox(container)->scrolledContentOffset(); |
1137 | 1136 |
1138 if (offsetDependsOnPoint) | 1137 if (offsetDependsOnPoint) |
1139 *offsetDependsOnPoint = (container->isBox() && container->style()->isFli
ppedBlocksWritingMode()) || container->isLayoutFlowThread(); | 1138 *offsetDependsOnPoint = (container->isBox() && container->style()->isFli
ppedBlocksWritingMode()) || container->isLayoutFlowThread(); |
1140 | 1139 |
1141 return offset; | 1140 return offset; |
1142 } | 1141 } |
1143 | 1142 |
1144 PaintLayerType LayoutInline::layerTypeRequired() const | 1143 PaintLayerType LayoutInline::layerTypeRequired() const |
1145 { | 1144 { |
1146 return isInFlowPositioned() || createsGroup() || hasClipPath() || style()->s
houldCompositeForCurrentAnimations() | 1145 return isInFlowPositioned() || createsGroup() || hasClipPath() || style()->s
houldCompositeForCurrentAnimations() |
1147 || style()->hasCompositorProxy() || style()->containsPaint() ? NormalPa
intLayer : NoPaintLayer; | 1146 || style()->hasCompositorProxy() || style()->containsPaint() ? NormalPa
intLayer : NoPaintLayer; |
1148 } | 1147 } |
1149 | 1148 |
1150 void LayoutInline::mapLocalToContainer(const LayoutBoxModelObject* paintInvalida
tionContainer, TransformState& transformState, MapCoordinatesFlags mode, bool* w
asFixed, const PaintInvalidationState* paintInvalidationState) const | 1149 void LayoutInline::mapLocalToAncestor(const LayoutBoxModelObject* ancestor, Tran
sformState& transformState, MapCoordinatesFlags mode, bool* wasFixed, const Pain
tInvalidationState* paintInvalidationState) const |
1151 { | 1150 { |
1152 if (paintInvalidationContainer == this) | 1151 if (ancestor == this) |
1153 return; | 1152 return; |
1154 | 1153 |
1155 if (paintInvalidationState && paintInvalidationState->canMapToContainer(pain
tInvalidationContainer)) { | 1154 if (paintInvalidationState && paintInvalidationState->canMapToContainer(ance
stor)) { |
1156 LayoutSize offset = paintInvalidationState->paintOffset(); | 1155 LayoutSize offset = paintInvalidationState->paintOffset(); |
1157 if (style()->hasInFlowPosition() && layer()) | 1156 if (style()->hasInFlowPosition() && layer()) |
1158 offset += layer()->offsetForInFlowPosition(); | 1157 offset += layer()->offsetForInFlowPosition(); |
1159 transformState.move(offset); | 1158 transformState.move(offset); |
1160 return; | 1159 return; |
1161 } | 1160 } |
1162 | 1161 |
1163 bool containerSkipped; | 1162 bool containerSkipped; |
1164 LayoutObject* o = container(paintInvalidationContainer, &containerSkipped); | 1163 LayoutObject* o = container(ancestor, &containerSkipped); |
1165 if (!o) | 1164 if (!o) |
1166 return; | 1165 return; |
1167 | 1166 |
1168 if (mode & ApplyContainerFlip && o->isBox()) { | 1167 if (mode & ApplyContainerFlip && o->isBox()) { |
1169 if (o->style()->isFlippedBlocksWritingMode()) { | 1168 if (o->style()->isFlippedBlocksWritingMode()) { |
1170 IntPoint centerPoint = roundedIntPoint(transformState.mappedPoint())
; | 1169 IntPoint centerPoint = roundedIntPoint(transformState.mappedPoint())
; |
1171 transformState.move(toLayoutBox(o)->flipForWritingMode(LayoutPoint(c
enterPoint)) - centerPoint); | 1170 transformState.move(toLayoutBox(o)->flipForWritingMode(LayoutPoint(c
enterPoint)) - centerPoint); |
1172 } | 1171 } |
1173 mode &= ~ApplyContainerFlip; | 1172 mode &= ~ApplyContainerFlip; |
1174 } | 1173 } |
1175 | 1174 |
1176 LayoutSize containerOffset = offsetFromContainer(o, roundedLayoutPoint(trans
formState.mappedPoint())); | 1175 LayoutSize containerOffset = offsetFromContainer(o, roundedLayoutPoint(trans
formState.mappedPoint())); |
1177 | 1176 |
1178 bool preserve3D = mode & UseTransforms && (o->style()->preserves3D() || styl
e()->preserves3D()); | 1177 bool preserve3D = mode & UseTransforms && (o->style()->preserves3D() || styl
e()->preserves3D()); |
1179 if (mode & UseTransforms && shouldUseTransformFromContainer(o)) { | 1178 if (mode & UseTransforms && shouldUseTransformFromContainer(o)) { |
1180 TransformationMatrix t; | 1179 TransformationMatrix t; |
1181 getTransformFromContainer(o, containerOffset, t); | 1180 getTransformFromContainer(o, containerOffset, t); |
1182 transformState.applyTransform(t, preserve3D ? TransformState::Accumulate
Transform : TransformState::FlattenTransform); | 1181 transformState.applyTransform(t, preserve3D ? TransformState::Accumulate
Transform : TransformState::FlattenTransform); |
1183 } else { | 1182 } else { |
1184 transformState.move(containerOffset.width(), containerOffset.height(), p
reserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransfo
rm); | 1183 transformState.move(containerOffset.width(), containerOffset.height(), p
reserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransfo
rm); |
1185 } | 1184 } |
1186 | 1185 |
1187 if (containerSkipped) { | 1186 if (containerSkipped) { |
1188 // There can't be a transform between paintInvalidationContainer and o,
because transforms create containers, so it should be safe | 1187 // There can't be a transform between paintInvalidationContainer and o,
because transforms create containers, so it should be safe |
1189 // to just subtract the delta between the paintInvalidationContainer and
o. | 1188 // to just subtract the delta between the paintInvalidationContainer and
o. |
1190 LayoutSize containerOffset = paintInvalidationContainer->offsetFromAnces
torContainer(o); | 1189 LayoutSize containerOffset = ancestor->offsetFromAncestorContainer(o); |
1191 transformState.move(-containerOffset.width(), -containerOffset.height(),
preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTrans
form); | 1190 transformState.move(-containerOffset.width(), -containerOffset.height(),
preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTrans
form); |
1192 return; | 1191 return; |
1193 } | 1192 } |
1194 | 1193 |
1195 o->mapLocalToContainer(paintInvalidationContainer, transformState, mode, was
Fixed, paintInvalidationState); | 1194 o->mapLocalToAncestor(ancestor, transformState, mode, wasFixed, paintInvalid
ationState); |
1196 } | 1195 } |
1197 | 1196 |
1198 void LayoutInline::updateDragState(bool dragOn) | 1197 void LayoutInline::updateDragState(bool dragOn) |
1199 { | 1198 { |
1200 LayoutBoxModelObject::updateDragState(dragOn); | 1199 LayoutBoxModelObject::updateDragState(dragOn); |
1201 if (LayoutBoxModelObject* continuation = this->continuation()) | 1200 if (LayoutBoxModelObject* continuation = this->continuation()) |
1202 continuation->updateDragState(dragOn); | 1201 continuation->updateDragState(dragOn); |
1203 } | 1202 } |
1204 | 1203 |
1205 void LayoutInline::childBecameNonInline(LayoutObject* child) | 1204 void LayoutInline::childBecameNonInline(LayoutObject* child) |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1428 { | 1427 { |
1429 LayoutBoxModelObject::invalidateDisplayItemClients(paintInvalidationContaine
r, invalidationReason, paintInvalidationRect); | 1428 LayoutBoxModelObject::invalidateDisplayItemClients(paintInvalidationContaine
r, invalidationReason, paintInvalidationRect); |
1430 | 1429 |
1431 // Use the paintInvalidationRect of LayoutInline for inline boxes, which sav
es the cost to calculate paint invalidation rect | 1430 // Use the paintInvalidationRect of LayoutInline for inline boxes, which sav
es the cost to calculate paint invalidation rect |
1432 // for every inline box. This won't cause more rasterization invalidations b
ecause the whole LayoutInline is being invalidated. | 1431 // for every inline box. This won't cause more rasterization invalidations b
ecause the whole LayoutInline is being invalidated. |
1433 for (InlineFlowBox* box = firstLineBox(); box; box = box->nextLineBox()) | 1432 for (InlineFlowBox* box = firstLineBox(); box; box = box->nextLineBox()) |
1434 paintInvalidationContainer.invalidateDisplayItemClientOnBacking(*box, in
validationReason, paintInvalidationRect); | 1433 paintInvalidationContainer.invalidateDisplayItemClientOnBacking(*box, in
validationReason, paintInvalidationRect); |
1435 } | 1434 } |
1436 | 1435 |
1437 } // namespace blink | 1436 } // namespace blink |
OLD | NEW |