| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2012 Apple Inc. All rights reserved. | 2 * Copyright (C) 2012 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 #include "core/rendering/RenderView.h" | 31 #include "core/rendering/RenderView.h" |
| 32 #include "platform/geometry/TransformState.h" | 32 #include "platform/geometry/TransformState.h" |
| 33 #include "wtf/TemporaryChange.h" | 33 #include "wtf/TemporaryChange.h" |
| 34 | 34 |
| 35 namespace blink { | 35 namespace blink { |
| 36 | 36 |
| 37 RenderGeometryMap::RenderGeometryMap(MapCoordinatesFlags flags) | 37 RenderGeometryMap::RenderGeometryMap(MapCoordinatesFlags flags) |
| 38 : m_insertionPosition(kNotFound) | 38 : m_insertionPosition(kNotFound) |
| 39 , m_nonUniformStepsCount(0) | 39 , m_nonUniformStepsCount(0) |
| 40 , m_transformedStepsCount(0) | 40 , m_transformedStepsCount(0) |
| 41 , m_fixedStepsCount(0) | |
| 42 , m_mapCoordinatesFlags(flags) | 41 , m_mapCoordinatesFlags(flags) |
| 43 { | 42 { |
| 44 } | 43 } |
| 45 | 44 |
| 46 RenderGeometryMap::~RenderGeometryMap() | 45 RenderGeometryMap::~RenderGeometryMap() |
| 47 { | 46 { |
| 48 } | 47 } |
| 49 | 48 |
| 50 void RenderGeometryMap::mapToContainer(TransformState& transformState, const Ren
derLayerModelObject* container) const | 49 void RenderGeometryMap::mapToContainer(TransformState& transformState, const Ren
derLayerModelObject* container) const |
| 51 { | 50 { |
| 52 // If the mapping includes something like columns, we have to go via rendere
rs. | 51 // If the mapping includes something like columns, we have to go via rendere
rs. |
| 53 if (hasNonUniformStep()) { | 52 if (hasNonUniformStep()) { |
| 54 m_mapping.last().m_renderer->mapLocalToContainer(container, transformSta
te, ApplyContainerFlip | m_mapCoordinatesFlags); | 53 m_mapping.last().m_renderer->mapLocalToContainer(container, transformSta
te, ApplyContainerFlip | m_mapCoordinatesFlags); |
| 55 transformState.flatten(); | 54 transformState.flatten(); |
| 56 return; | 55 return; |
| 57 } | 56 } |
| 58 | 57 |
| 59 bool inFixed = false; | |
| 60 #if ENABLE(ASSERT) | 58 #if ENABLE(ASSERT) |
| 61 bool foundContainer = !container || (m_mapping.size() && m_mapping[0].m_rend
erer == container); | 59 bool foundContainer = !container || (m_mapping.size() && m_mapping[0].m_rend
erer == container); |
| 62 #endif | 60 #endif |
| 63 | 61 |
| 64 for (int i = m_mapping.size() - 1; i >= 0; --i) { | 62 for (int i = m_mapping.size() - 1; i >= 0; --i) { |
| 65 const RenderGeometryMapStep& currentStep = m_mapping[i]; | 63 const RenderGeometryMapStep& currentStep = m_mapping[i]; |
| 66 | 64 |
| 67 // If container is the root RenderView (step 0) we want to apply its fix
ed position offset. | 65 // If container is the root RenderView (step 0) we want to apply its fix
ed position offset. |
| 68 if (i > 0 && currentStep.m_renderer == container) { | 66 if (i > 0 && currentStep.m_renderer == container) { |
| 69 #if ENABLE(ASSERT) | 67 #if ENABLE(ASSERT) |
| 70 foundContainer = true; | 68 foundContainer = true; |
| 71 #endif | 69 #endif |
| 72 break; | 70 break; |
| 73 } | 71 } |
| 74 | 72 |
| 75 // If this box has a transform, it acts as a fixed position container | |
| 76 // for fixed descendants, which prevents the propagation of 'fixed' | |
| 77 // unless the layer itself is also fixed position. | |
| 78 if (i && currentStep.m_hasTransform && !currentStep.m_isFixedPosition) | |
| 79 inFixed = false; | |
| 80 else if (currentStep.m_isFixedPosition) | |
| 81 inFixed = true; | |
| 82 | |
| 83 ASSERT(!i == isTopmostRenderView(currentStep.m_renderer)); | 73 ASSERT(!i == isTopmostRenderView(currentStep.m_renderer)); |
| 84 | 74 |
| 85 if (!i) { | 75 if (!i) { |
| 86 // A null container indicates mapping through the root RenderView, s
o including its transform (the page scale). | 76 // A null container indicates mapping through the root RenderView, s
o including its transform (the page scale). |
| 87 if (!container && currentStep.m_transform) | 77 if (!container && currentStep.m_transform) |
| 88 transformState.applyTransform(*currentStep.m_transform.get()); | 78 transformState.applyTransform(*currentStep.m_transform.get()); |
| 89 } else { | 79 } else { |
| 90 TransformState::TransformAccumulation accumulate = currentStep.m_acc
umulatingTransform ? TransformState::AccumulateTransform : TransformState::Flatt
enTransform; | 80 TransformState::TransformAccumulation accumulate = currentStep.m_acc
umulatingTransform ? TransformState::AccumulateTransform : TransformState::Flatt
enTransform; |
| 91 if (currentStep.m_transform) | 81 if (currentStep.m_transform) |
| 92 transformState.applyTransform(*currentStep.m_transform.get(), ac
cumulate); | 82 transformState.applyTransform(*currentStep.m_transform.get(), ac
cumulate); |
| 93 else | 83 else |
| 94 transformState.move(currentStep.m_offset.width(), currentStep.m_
offset.height(), accumulate); | 84 transformState.move(currentStep.m_offset.width(), currentStep.m_
offset.height(), accumulate); |
| 95 } | 85 } |
| 96 | |
| 97 if (inFixed && !currentStep.m_offsetForFixedPosition.isZero()) { | |
| 98 ASSERT(currentStep.m_renderer->isRenderView()); | |
| 99 transformState.move(currentStep.m_offsetForFixedPosition); | |
| 100 } | |
| 101 } | 86 } |
| 102 | 87 |
| 103 ASSERT(foundContainer); | 88 ASSERT(foundContainer); |
| 104 transformState.flatten(); | 89 transformState.flatten(); |
| 105 } | 90 } |
| 106 | 91 |
| 107 FloatPoint RenderGeometryMap::mapToContainer(const FloatPoint& p, const RenderLa
yerModelObject* container) const | 92 FloatPoint RenderGeometryMap::mapToContainer(const FloatPoint& p, const RenderLa
yerModelObject* container) const |
| 108 { | 93 { |
| 109 FloatPoint result; | 94 FloatPoint result; |
| 110 | 95 |
| 111 if (!hasFixedPositionStep() && !hasTransformStep() && !hasNonUniformStep() &
& (!container || (m_mapping.size() && container == m_mapping[0].m_renderer))) | 96 if (!hasTransformStep() && !hasNonUniformStep() && (!container || (m_mapping
.size() && container == m_mapping[0].m_renderer))) |
| 112 result = p + m_accumulatedOffset; | 97 result = p + m_accumulatedOffset; |
| 113 else { | 98 else { |
| 114 TransformState transformState(TransformState::ApplyTransformDirection, p
); | 99 TransformState transformState(TransformState::ApplyTransformDirection, p
); |
| 115 mapToContainer(transformState, container); | 100 mapToContainer(transformState, container); |
| 116 result = transformState.lastPlanarPoint(); | 101 result = transformState.lastPlanarPoint(); |
| 117 } | 102 } |
| 118 | 103 |
| 119 #if ENABLE(ASSERT) | 104 #if ENABLE(ASSERT) |
| 120 if (m_mapping.size() > 0) { | 105 if (m_mapping.size() > 0) { |
| 121 const RenderObject* lastRenderer = m_mapping.last().m_renderer; | 106 const RenderObject* lastRenderer = m_mapping.last().m_renderer; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 146 fprintf(stderr, " hasTransform"); | 131 fprintf(stderr, " hasTransform"); |
| 147 fprintf(stderr, "\n"); | 132 fprintf(stderr, "\n"); |
| 148 } | 133 } |
| 149 } | 134 } |
| 150 #endif | 135 #endif |
| 151 | 136 |
| 152 FloatQuad RenderGeometryMap::mapToContainer(const FloatRect& rect, const RenderL
ayerModelObject* container) const | 137 FloatQuad RenderGeometryMap::mapToContainer(const FloatRect& rect, const RenderL
ayerModelObject* container) const |
| 153 { | 138 { |
| 154 FloatRect result; | 139 FloatRect result; |
| 155 | 140 |
| 156 if (!hasFixedPositionStep() && !hasTransformStep() && !hasNonUniformStep() &
& (!container || (m_mapping.size() && container == m_mapping[0].m_renderer))) { | 141 if (!hasTransformStep() && !hasNonUniformStep() && (!container || (m_mapping
.size() && container == m_mapping[0].m_renderer))) { |
| 157 result = rect; | 142 result = rect; |
| 158 result.move(m_accumulatedOffset); | 143 result.move(m_accumulatedOffset); |
| 159 } else { | 144 } else { |
| 160 TransformState transformState(TransformState::ApplyTransformDirection, r
ect.center(), rect); | 145 TransformState transformState(TransformState::ApplyTransformDirection, r
ect.center(), rect); |
| 161 mapToContainer(transformState, container); | 146 mapToContainer(transformState, container); |
| 162 result = transformState.lastPlanarQuad().boundingBox(); | 147 result = transformState.lastPlanarQuad().boundingBox(); |
| 163 } | 148 } |
| 164 | 149 |
| 165 #if ENABLE(ASSERT) | 150 #if ENABLE(ASSERT) |
| 166 if (m_mapping.size() > 0) { | 151 if (m_mapping.size() > 0) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 188 renderer = renderer->pushMappingToContainer(ancestorRenderer, *this); | 173 renderer = renderer->pushMappingToContainer(ancestorRenderer, *this); |
| 189 } while (renderer && renderer != ancestorRenderer); | 174 } while (renderer && renderer != ancestorRenderer); |
| 190 | 175 |
| 191 ASSERT(m_mapping.isEmpty() || isTopmostRenderView(m_mapping[0].m_renderer)); | 176 ASSERT(m_mapping.isEmpty() || isTopmostRenderView(m_mapping[0].m_renderer)); |
| 192 } | 177 } |
| 193 | 178 |
| 194 static bool canMapBetweenRenderers(const RenderObject* renderer, const RenderObj
ect* ancestor) | 179 static bool canMapBetweenRenderers(const RenderObject* renderer, const RenderObj
ect* ancestor) |
| 195 { | 180 { |
| 196 for (const RenderObject* current = renderer; ; current = current->parent())
{ | 181 for (const RenderObject* current = renderer; ; current = current->parent())
{ |
| 197 const RenderStyle* style = current->style(); | 182 const RenderStyle* style = current->style(); |
| 198 if (style->position() == FixedPosition || style->isFlippedBlocksWritingM
ode()) | 183 if (style->isFlippedBlocksWritingMode()) |
| 199 return false; | 184 return false; |
| 200 | 185 |
| 201 if (current->hasTransform()) | 186 if (current->hasTransform()) |
| 202 return false; | 187 return false; |
| 203 | 188 |
| 204 if (current == ancestor) | 189 if (current == ancestor) |
| 205 break; | 190 break; |
| 206 } | 191 } |
| 207 | 192 |
| 208 return true; | 193 return true; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 226 layer->convertToLayerCoords(ancestorLayer, layerOffset); | 211 layer->convertToLayerCoords(ancestorLayer, layerOffset); |
| 227 | 212 |
| 228 // The RenderView must be pushed first. | 213 // The RenderView must be pushed first. |
| 229 if (!m_mapping.size()) { | 214 if (!m_mapping.size()) { |
| 230 ASSERT(ancestorLayer->renderer()->isRenderView()); | 215 ASSERT(ancestorLayer->renderer()->isRenderView()); |
| 231 pushMappingsToAncestor(ancestorLayer->renderer(), 0); | 216 pushMappingsToAncestor(ancestorLayer->renderer(), 0); |
| 232 } | 217 } |
| 233 | 218 |
| 234 TemporaryChange<size_t> positionChange(m_insertionPosition, m_mapping.si
ze()); | 219 TemporaryChange<size_t> positionChange(m_insertionPosition, m_mapping.si
ze()); |
| 235 bool accumulatingTransform = layer->renderer()->style()->preserves3D() |
| ancestorLayer->renderer()->style()->preserves3D(); | 220 bool accumulatingTransform = layer->renderer()->style()->preserves3D() |
| ancestorLayer->renderer()->style()->preserves3D(); |
| 236 push(renderer, toLayoutSize(layerOffset), accumulatingTransform, /*isNon
Uniform*/ false, /*isFixedPosition*/ false, /*hasTransform*/ false); | 221 push(renderer, toLayoutSize(layerOffset), accumulatingTransform, /*isNon
Uniform*/ false, /*hasTransform*/ false); |
| 237 return; | 222 return; |
| 238 } | 223 } |
| 239 const RenderLayerModelObject* ancestorRenderer = ancestorLayer ? ancestorLay
er->renderer() : 0; | 224 const RenderLayerModelObject* ancestorRenderer = ancestorLayer ? ancestorLay
er->renderer() : 0; |
| 240 pushMappingsToAncestor(renderer, ancestorRenderer); | 225 pushMappingsToAncestor(renderer, ancestorRenderer); |
| 241 } | 226 } |
| 242 | 227 |
| 243 void RenderGeometryMap::push(const RenderObject* renderer, const LayoutSize& off
setFromContainer, bool accumulatingTransform, bool isNonUniform, bool isFixedPos
ition, bool hasTransform, LayoutSize offsetForFixedPosition) | 228 void RenderGeometryMap::push(const RenderObject* renderer, const LayoutSize& off
setFromContainer, bool accumulatingTransform, bool isNonUniform, bool hasTransfo
rm) |
| 244 { | 229 { |
| 245 // fprintf(stderr, "RenderGeometryMap::push %p %d,%d isNonUniform=%d\n", rend
erer, offsetFromContainer.width().toInt(), offsetFromContainer.height().toInt(),
isNonUniform); | 230 // fprintf(stderr, "RenderGeometryMap::push %p %d,%d isNonUniform=%d\n", rend
erer, offsetFromContainer.width().toInt(), offsetFromContainer.height().toInt(),
isNonUniform); |
| 246 | 231 |
| 247 ASSERT(m_insertionPosition != kNotFound); | 232 ASSERT(m_insertionPosition != kNotFound); |
| 248 ASSERT(!renderer->isRenderView() || !m_insertionPosition || m_mapCoordinates
Flags & TraverseDocumentBoundaries); | 233 ASSERT(!renderer->isRenderView() || !m_insertionPosition || m_mapCoordinates
Flags & TraverseDocumentBoundaries); |
| 249 ASSERT(offsetForFixedPosition.isZero() || renderer->isRenderView()); | |
| 250 | 234 |
| 251 m_mapping.insert(m_insertionPosition, RenderGeometryMapStep(renderer, accumu
latingTransform, isNonUniform, isFixedPosition, hasTransform)); | 235 m_mapping.insert(m_insertionPosition, RenderGeometryMapStep(renderer, accumu
latingTransform, isNonUniform, hasTransform)); |
| 252 | 236 |
| 253 RenderGeometryMapStep& step = m_mapping[m_insertionPosition]; | 237 RenderGeometryMapStep& step = m_mapping[m_insertionPosition]; |
| 254 step.m_offset = offsetFromContainer; | 238 step.m_offset = offsetFromContainer; |
| 255 step.m_offsetForFixedPosition = offsetForFixedPosition; | |
| 256 | 239 |
| 257 stepInserted(step); | 240 stepInserted(step); |
| 258 } | 241 } |
| 259 | 242 |
| 260 void RenderGeometryMap::push(const RenderObject* renderer, const TransformationM
atrix& t, bool accumulatingTransform, bool isNonUniform, bool isFixedPosition, b
ool hasTransform, LayoutSize offsetForFixedPosition) | 243 void RenderGeometryMap::push(const RenderObject* renderer, const TransformationM
atrix& t, bool accumulatingTransform, bool isNonUniform, bool hasTransform) |
| 261 { | 244 { |
| 262 ASSERT(m_insertionPosition != kNotFound); | 245 ASSERT(m_insertionPosition != kNotFound); |
| 263 ASSERT(!renderer->isRenderView() || !m_insertionPosition || m_mapCoordinates
Flags & TraverseDocumentBoundaries); | 246 ASSERT(!renderer->isRenderView() || !m_insertionPosition || m_mapCoordinates
Flags & TraverseDocumentBoundaries); |
| 264 ASSERT(offsetForFixedPosition.isZero() || renderer->isRenderView()); | |
| 265 | 247 |
| 266 m_mapping.insert(m_insertionPosition, RenderGeometryMapStep(renderer, accumu
latingTransform, isNonUniform, isFixedPosition, hasTransform)); | 248 m_mapping.insert(m_insertionPosition, RenderGeometryMapStep(renderer, accumu
latingTransform, isNonUniform, hasTransform)); |
| 267 | 249 |
| 268 RenderGeometryMapStep& step = m_mapping[m_insertionPosition]; | 250 RenderGeometryMapStep& step = m_mapping[m_insertionPosition]; |
| 269 step.m_offsetForFixedPosition = offsetForFixedPosition; | |
| 270 | 251 |
| 271 if (!t.isIntegerTranslation()) | 252 if (!t.isIntegerTranslation()) |
| 272 step.m_transform = adoptPtr(new TransformationMatrix(t)); | 253 step.m_transform = adoptPtr(new TransformationMatrix(t)); |
| 273 else | 254 else |
| 274 step.m_offset = LayoutSize(t.e(), t.f()); | 255 step.m_offset = LayoutSize(t.e(), t.f()); |
| 275 | 256 |
| 276 stepInserted(step); | 257 stepInserted(step); |
| 277 } | 258 } |
| 278 | 259 |
| 279 void RenderGeometryMap::popMappingsToAncestor(const RenderLayerModelObject* ance
storRenderer) | 260 void RenderGeometryMap::popMappingsToAncestor(const RenderLayerModelObject* ance
storRenderer) |
| (...skipping 14 matching lines...) Expand all Loading... |
| 294 | 275 |
| 295 void RenderGeometryMap::stepInserted(const RenderGeometryMapStep& step) | 276 void RenderGeometryMap::stepInserted(const RenderGeometryMapStep& step) |
| 296 { | 277 { |
| 297 m_accumulatedOffset += step.m_offset; | 278 m_accumulatedOffset += step.m_offset; |
| 298 | 279 |
| 299 if (step.m_isNonUniform) | 280 if (step.m_isNonUniform) |
| 300 ++m_nonUniformStepsCount; | 281 ++m_nonUniformStepsCount; |
| 301 | 282 |
| 302 if (step.m_transform) | 283 if (step.m_transform) |
| 303 ++m_transformedStepsCount; | 284 ++m_transformedStepsCount; |
| 304 | |
| 305 if (step.m_isFixedPosition) | |
| 306 ++m_fixedStepsCount; | |
| 307 } | 285 } |
| 308 | 286 |
| 309 void RenderGeometryMap::stepRemoved(const RenderGeometryMapStep& step) | 287 void RenderGeometryMap::stepRemoved(const RenderGeometryMapStep& step) |
| 310 { | 288 { |
| 311 m_accumulatedOffset -= step.m_offset; | 289 m_accumulatedOffset -= step.m_offset; |
| 312 | 290 |
| 313 if (step.m_isNonUniform) { | 291 if (step.m_isNonUniform) { |
| 314 ASSERT(m_nonUniformStepsCount); | 292 ASSERT(m_nonUniformStepsCount); |
| 315 --m_nonUniformStepsCount; | 293 --m_nonUniformStepsCount; |
| 316 } | 294 } |
| 317 | 295 |
| 318 if (step.m_transform) { | 296 if (step.m_transform) { |
| 319 ASSERT(m_transformedStepsCount); | 297 ASSERT(m_transformedStepsCount); |
| 320 --m_transformedStepsCount; | 298 --m_transformedStepsCount; |
| 321 } | 299 } |
| 322 | |
| 323 if (step.m_isFixedPosition) { | |
| 324 ASSERT(m_fixedStepsCount); | |
| 325 --m_fixedStepsCount; | |
| 326 } | |
| 327 } | 300 } |
| 328 | 301 |
| 329 #if ENABLE(ASSERT) | 302 #if ENABLE(ASSERT) |
| 330 bool RenderGeometryMap::isTopmostRenderView(const RenderObject* renderer) const | 303 bool RenderGeometryMap::isTopmostRenderView(const RenderObject* renderer) const |
| 331 { | 304 { |
| 332 if (!renderer->isRenderView()) | 305 if (!renderer->isRenderView()) |
| 333 return false; | 306 return false; |
| 334 | 307 |
| 335 // If we're not working with multiple RenderViews, then any view is consider
ed | 308 // If we're not working with multiple RenderViews, then any view is consider
ed |
| 336 // "topmost" (to preserve original behavior). | 309 // "topmost" (to preserve original behavior). |
| 337 return !(m_mapCoordinatesFlags & TraverseDocumentBoundaries); | 310 return !(m_mapCoordinatesFlags & TraverseDocumentBoundaries); |
| 338 } | 311 } |
| 339 #endif | 312 #endif |
| 340 | 313 |
| 341 } // namespace blink | 314 } // namespace blink |
| OLD | NEW |