Chromium Code Reviews| 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/paint/DeprecatedPaintLayer.h" | 31 #include "core/paint/DeprecatedPaintLayer.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 LayoutGeometryMap::LayoutGeometryMap(MapCoordinatesFlags flags) | 37 LayoutGeometryMap::LayoutGeometryMap(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) | 41 , m_viewportConstrainedStepsCount(0) |
| 42 , m_mapCoordinatesFlags(flags) | 42 , m_mapCoordinatesFlags(flags) |
| 43 { | 43 { |
| 44 } | 44 } |
| 45 | 45 |
| 46 LayoutGeometryMap::~LayoutGeometryMap() | 46 LayoutGeometryMap::~LayoutGeometryMap() |
| 47 { | 47 { |
| 48 } | 48 } |
| 49 | 49 |
| 50 void LayoutGeometryMap::mapToContainer(TransformState& transformState, const Lay outBoxModelObject* container) const | 50 void LayoutGeometryMap::mapToContainer(TransformState& transformState, const Lay outBoxModelObject* container) const |
| 51 { | 51 { |
| 52 // If the mapping includes something like columns, we have to go via layoutO bjects. | 52 // If the mapping includes something like columns, we have to go via layoutO bjects. |
| 53 if (hasNonUniformStep()) { | 53 if (hasNonUniformStep()) { |
| 54 m_mapping.last().m_layoutObject->mapLocalToContainer(container, transfor mState, ApplyContainerFlip | m_mapCoordinatesFlags); | 54 m_mapping.last().m_layoutObject->mapLocalToContainer(container, transfor mState, ApplyContainerFlip | m_mapCoordinatesFlags); |
| 55 transformState.flatten(); | 55 transformState.flatten(); |
| 56 return; | 56 return; |
| 57 } | 57 } |
| 58 | 58 |
| 59 bool inFixed = false; | 59 bool inFixed = false; |
| 60 #if ENABLE(ASSERT) | 60 #if ENABLE(ASSERT) |
| 61 bool foundContainer = !container || (m_mapping.size() && m_mapping[0].m_layo utObject == container); | 61 bool foundContainer = !container || (m_mapping.size() && m_mapping[0].m_layo utObject == container); |
| 62 #endif | 62 #endif |
| 63 | 63 |
| 64 for (int i = m_mapping.size() - 1; i >= 0; --i) { | 64 for (int i = m_mapping.size() - 1; i >= 0; --i) { |
| 65 const LayoutGeometryMapStep& currentStep = m_mapping[i]; | 65 const LayoutGeometryMapStep& currentStep = m_mapping[i]; |
| 66 | 66 |
| 67 // If container is the root LayoutView (step 0) we want to apply its fix ed position offset. | 67 // If container is the root LayoutView (step 0) we want to apply its vie wport constrained position offset. |
| 68 if (i > 0 && currentStep.m_layoutObject == container) { | 68 if (i > 0 && currentStep.m_layoutObject == container) { |
| 69 #if ENABLE(ASSERT) | 69 #if ENABLE(ASSERT) |
| 70 foundContainer = true; | 70 foundContainer = true; |
| 71 #endif | 71 #endif |
| 72 break; | 72 break; |
| 73 } | 73 } |
| 74 | 74 |
| 75 // If this box has a transform, it acts as a fixed position container | 75 // If this box has a transform, it acts as a viewport constrained positi on container |
| 76 // for fixed descendants, which prevents the propagation of 'fixed' | 76 // for viewport constrained descendants, which prevents the propagation of viewport constrained |
| 77 // unless the layer itself is also fixed position. | 77 // unless the layer itself is also a viewport constrained position. |
| 78 if (i && currentStep.m_hasTransform && !currentStep.m_isFixedPosition) | 78 // TODO(flackr): Verify how fixed and sticky elements should interact wi th each other. |
|
flackr
2015/09/15 21:13:11
My assumption is that this code should only apply
| |
| 79 if (i && currentStep.m_hasTransform && !currentStep.m_isViewportConstrai ned) | |
| 79 inFixed = false; | 80 inFixed = false; |
| 80 else if (currentStep.m_isFixedPosition) | 81 else if (currentStep.m_isViewportConstrained) |
| 81 inFixed = true; | 82 inFixed = true; |
| 82 | 83 |
| 83 ASSERT(!i == isTopmostLayoutView(currentStep.m_layoutObject)); | 84 ASSERT(!i == isTopmostLayoutView(currentStep.m_layoutObject)); |
| 84 | 85 |
| 85 if (!i) { | 86 if (!i) { |
| 86 // A null container indicates mapping through the root LayoutView, s o including its transform (the page scale). | 87 // A null container indicates mapping through the root LayoutView, s o including its transform (the page scale). |
| 87 if (!container && currentStep.m_transform) | 88 if (!container && currentStep.m_transform) |
| 88 transformState.applyTransform(*currentStep.m_transform.get()); | 89 transformState.applyTransform(*currentStep.m_transform.get()); |
| 89 } else { | 90 } else { |
| 90 TransformState::TransformAccumulation accumulate = currentStep.m_acc umulatingTransform ? TransformState::AccumulateTransform : TransformState::Flatt enTransform; | 91 TransformState::TransformAccumulation accumulate = currentStep.m_acc umulatingTransform ? TransformState::AccumulateTransform : TransformState::Flatt enTransform; |
| 91 if (currentStep.m_transform) | 92 if (currentStep.m_transform) |
| 92 transformState.applyTransform(*currentStep.m_transform.get(), ac cumulate); | 93 transformState.applyTransform(*currentStep.m_transform.get(), ac cumulate); |
| 93 else | 94 else |
| 94 transformState.move(currentStep.m_offset.width(), currentStep.m_ offset.height(), accumulate); | 95 transformState.move(currentStep.m_offset.width(), currentStep.m_ offset.height(), accumulate); |
| 95 } | 96 } |
| 96 | 97 |
| 97 if (inFixed && !currentStep.m_offsetForFixedPosition.isZero()) { | 98 if (inFixed && !currentStep.m_offsetForViewportConstrained.isZero()) { |
| 98 ASSERT(currentStep.m_layoutObject->isLayoutView()); | 99 ASSERT(currentStep.m_layoutObject->isLayoutView()); |
| 99 transformState.move(currentStep.m_offsetForFixedPosition); | 100 transformState.move(currentStep.m_offsetForViewportConstrained); |
| 100 } | 101 } |
| 101 } | 102 } |
| 102 | 103 |
| 103 ASSERT(foundContainer); | 104 ASSERT(foundContainer); |
| 104 transformState.flatten(); | 105 transformState.flatten(); |
| 105 } | 106 } |
| 106 | 107 |
| 107 FloatPoint LayoutGeometryMap::mapToContainer(const FloatPoint& p, const LayoutBo xModelObject* container) const | 108 FloatPoint LayoutGeometryMap::mapToContainer(const FloatPoint& p, const LayoutBo xModelObject* container) const |
| 108 { | 109 { |
| 109 FloatPoint result; | 110 FloatPoint result; |
| 110 | 111 |
| 111 if (!hasFixedPositionStep() && !hasTransformStep() && !hasNonUniformStep() & & (!container || (m_mapping.size() && container == m_mapping[0].m_layoutObject)) ) { | 112 if (!hasViewportConstrainedStep() && !hasTransformStep() && !hasNonUniformSt ep() && (!container || (m_mapping.size() && container == m_mapping[0].m_layoutOb ject))) { |
| 112 result = p + m_accumulatedOffset; | 113 result = p + m_accumulatedOffset; |
| 113 } else { | 114 } else { |
| 114 TransformState transformState(TransformState::ApplyTransformDirection, p ); | 115 TransformState transformState(TransformState::ApplyTransformDirection, p ); |
| 115 mapToContainer(transformState, container); | 116 mapToContainer(transformState, container); |
| 116 result = transformState.lastPlanarPoint(); | 117 result = transformState.lastPlanarPoint(); |
| 117 } | 118 } |
| 118 | 119 |
| 119 #if ENABLE(ASSERT) | 120 #if ENABLE(ASSERT) |
| 120 if (m_mapping.size() > 0) { | 121 if (m_mapping.size() > 0) { |
| 121 const LayoutObject* lastLayoutObject = m_mapping.last().m_layoutObject; | 122 const LayoutObject* lastLayoutObject = m_mapping.last().m_layoutObject; |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 149 fprintf(stderr, " hasTransform"); | 150 fprintf(stderr, " hasTransform"); |
| 150 fprintf(stderr, "\n"); | 151 fprintf(stderr, "\n"); |
| 151 } | 152 } |
| 152 } | 153 } |
| 153 #endif | 154 #endif |
| 154 | 155 |
| 155 FloatQuad LayoutGeometryMap::mapToContainer(const FloatRect& rect, const LayoutB oxModelObject* container) const | 156 FloatQuad LayoutGeometryMap::mapToContainer(const FloatRect& rect, const LayoutB oxModelObject* container) const |
| 156 { | 157 { |
| 157 FloatQuad result; | 158 FloatQuad result; |
| 158 | 159 |
| 159 if (!hasFixedPositionStep() && !hasTransformStep() && !hasNonUniformStep() & & (!container || (m_mapping.size() && container == m_mapping[0].m_layoutObject)) ) { | 160 if (!hasViewportConstrainedStep() && !hasTransformStep() && !hasNonUniformSt ep() && (!container || (m_mapping.size() && container == m_mapping[0].m_layoutOb ject))) { |
| 160 result = rect; | 161 result = rect; |
| 161 result.move(m_accumulatedOffset); | 162 result.move(m_accumulatedOffset); |
| 162 } else { | 163 } else { |
| 163 TransformState transformState(TransformState::ApplyTransformDirection, r ect.center(), rect); | 164 TransformState transformState(TransformState::ApplyTransformDirection, r ect.center(), rect); |
| 164 mapToContainer(transformState, container); | 165 mapToContainer(transformState, container); |
| 165 result = transformState.lastPlanarQuad(); | 166 result = transformState.lastPlanarQuad(); |
| 166 } | 167 } |
| 167 | 168 |
| 168 #if ENABLE(ASSERT) | 169 #if ENABLE(ASSERT) |
| 169 if (m_mapping.size() > 0) { | 170 if (m_mapping.size() > 0) { |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 232 layer->convertToLayerCoords(ancestorLayer, layerOffset); | 233 layer->convertToLayerCoords(ancestorLayer, layerOffset); |
| 233 | 234 |
| 234 // The LayoutView must be pushed first. | 235 // The LayoutView must be pushed first. |
| 235 if (!m_mapping.size()) { | 236 if (!m_mapping.size()) { |
| 236 ASSERT(ancestorLayer->layoutObject()->isLayoutView()); | 237 ASSERT(ancestorLayer->layoutObject()->isLayoutView()); |
| 237 pushMappingsToAncestor(ancestorLayer->layoutObject(), 0); | 238 pushMappingsToAncestor(ancestorLayer->layoutObject(), 0); |
| 238 } | 239 } |
| 239 | 240 |
| 240 TemporaryChange<size_t> positionChange(m_insertionPosition, m_mapping.si ze()); | 241 TemporaryChange<size_t> positionChange(m_insertionPosition, m_mapping.si ze()); |
| 241 bool accumulatingTransform = layer->layoutObject()->style()->preserves3D () || ancestorLayer->layoutObject()->style()->preserves3D(); | 242 bool accumulatingTransform = layer->layoutObject()->style()->preserves3D () || ancestorLayer->layoutObject()->style()->preserves3D(); |
| 242 push(layoutObject, toLayoutSize(layerOffset), accumulatingTransform, /*i sNonUniform*/ false, /*isFixedPosition*/ false, /*hasTransform*/ false); | 243 push(layoutObject, toLayoutSize(layerOffset), accumulatingTransform, /*i sNonUniform*/ false, /*isViewportConstrained*/ false, /*hasTransform*/ false); |
| 243 return; | 244 return; |
| 244 } | 245 } |
| 245 const LayoutBoxModelObject* ancestorLayoutObject = ancestorLayer ? ancestorL ayer->layoutObject() : 0; | 246 const LayoutBoxModelObject* ancestorLayoutObject = ancestorLayer ? ancestorL ayer->layoutObject() : 0; |
| 246 pushMappingsToAncestor(layoutObject, ancestorLayoutObject); | 247 pushMappingsToAncestor(layoutObject, ancestorLayoutObject); |
| 247 } | 248 } |
| 248 | 249 |
| 249 void LayoutGeometryMap::push(const LayoutObject* layoutObject, const LayoutSize& offsetFromContainer, bool accumulatingTransform, bool isNonUniform, bool isFixe dPosition, bool hasTransform, LayoutSize offsetForFixedPosition) | 250 void LayoutGeometryMap::push(const LayoutObject* layoutObject, const LayoutSize& offsetFromContainer, bool accumulatingTransform, bool isNonUniform, bool isView portConstrained, bool hasTransform, LayoutSize offsetForViewportConstrained) |
| 250 { | 251 { |
| 251 // fprintf(stderr, "LayoutGeometryMap::push %p %d,%d isNonUniform=%d\n", layo utObject, offsetFromContainer.width().toInt(), offsetFromContainer.height().toIn t(), isNonUniform); | 252 // fprintf(stderr, "LayoutGeometryMap::push %p %d,%d isNonUniform=%d\n", layo utObject, offsetFromContainer.width().toInt(), offsetFromContainer.height().toIn t(), isNonUniform); |
| 252 | 253 |
| 253 ASSERT(m_insertionPosition != kNotFound); | 254 ASSERT(m_insertionPosition != kNotFound); |
| 254 ASSERT(!layoutObject->isLayoutView() || !m_insertionPosition || m_mapCoordin atesFlags & TraverseDocumentBoundaries); | 255 ASSERT(!layoutObject->isLayoutView() || !m_insertionPosition || m_mapCoordin atesFlags & TraverseDocumentBoundaries); |
| 255 ASSERT(offsetForFixedPosition.isZero() || layoutObject->isLayoutView()); | 256 ASSERT(offsetForViewportConstrained.isZero() || layoutObject->isLayoutView() ); |
| 256 | 257 |
| 257 m_mapping.insert(m_insertionPosition, LayoutGeometryMapStep(layoutObject, ac cumulatingTransform, isNonUniform, isFixedPosition, hasTransform)); | 258 m_mapping.insert(m_insertionPosition, LayoutGeometryMapStep(layoutObject, ac cumulatingTransform, isNonUniform, isViewportConstrained, hasTransform)); |
| 258 | 259 |
| 259 LayoutGeometryMapStep& step = m_mapping[m_insertionPosition]; | 260 LayoutGeometryMapStep& step = m_mapping[m_insertionPosition]; |
| 260 step.m_offset = offsetFromContainer; | 261 step.m_offset = offsetFromContainer; |
| 261 step.m_offsetForFixedPosition = offsetForFixedPosition; | 262 step.m_offsetForViewportConstrained = offsetForViewportConstrained; |
| 262 | 263 |
| 263 stepInserted(step); | 264 stepInserted(step); |
| 264 } | 265 } |
| 265 | 266 |
| 266 void LayoutGeometryMap::push(const LayoutObject* layoutObject, const Transformat ionMatrix& t, bool accumulatingTransform, bool isNonUniform, bool isFixedPositio n, bool hasTransform, LayoutSize offsetForFixedPosition) | 267 void LayoutGeometryMap::push(const LayoutObject* layoutObject, const Transformat ionMatrix& t, bool accumulatingTransform, bool isNonUniform, bool isViewportCons trained, bool hasTransform, LayoutSize offsetForViewportConstrained) |
| 267 { | 268 { |
| 268 ASSERT(m_insertionPosition != kNotFound); | 269 ASSERT(m_insertionPosition != kNotFound); |
| 269 ASSERT(!layoutObject->isLayoutView() || !m_insertionPosition || m_mapCoordin atesFlags & TraverseDocumentBoundaries); | 270 ASSERT(!layoutObject->isLayoutView() || !m_insertionPosition || m_mapCoordin atesFlags & TraverseDocumentBoundaries); |
| 270 ASSERT(offsetForFixedPosition.isZero() || layoutObject->isLayoutView()); | 271 ASSERT(offsetForViewportConstrained.isZero() || layoutObject->isLayoutView() ); |
| 271 | 272 |
| 272 m_mapping.insert(m_insertionPosition, LayoutGeometryMapStep(layoutObject, ac cumulatingTransform, isNonUniform, isFixedPosition, hasTransform)); | 273 m_mapping.insert(m_insertionPosition, LayoutGeometryMapStep(layoutObject, ac cumulatingTransform, isNonUniform, isViewportConstrained, hasTransform)); |
| 273 | 274 |
| 274 LayoutGeometryMapStep& step = m_mapping[m_insertionPosition]; | 275 LayoutGeometryMapStep& step = m_mapping[m_insertionPosition]; |
| 275 step.m_offsetForFixedPosition = offsetForFixedPosition; | 276 step.m_offsetForViewportConstrained = offsetForViewportConstrained; |
| 276 | 277 |
| 277 if (!t.isIntegerTranslation()) | 278 if (!t.isIntegerTranslation()) |
| 278 step.m_transform = adoptPtr(new TransformationMatrix(t)); | 279 step.m_transform = adoptPtr(new TransformationMatrix(t)); |
| 279 else | 280 else |
| 280 step.m_offset = LayoutSize(t.e(), t.f()); | 281 step.m_offset = LayoutSize(t.e(), t.f()); |
| 281 | 282 |
| 282 stepInserted(step); | 283 stepInserted(step); |
| 283 } | 284 } |
| 284 | 285 |
| 285 void LayoutGeometryMap::popMappingsToAncestor(const LayoutBoxModelObject* ancest orLayoutObject) | 286 void LayoutGeometryMap::popMappingsToAncestor(const LayoutBoxModelObject* ancest orLayoutObject) |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 301 void LayoutGeometryMap::stepInserted(const LayoutGeometryMapStep& step) | 302 void LayoutGeometryMap::stepInserted(const LayoutGeometryMapStep& step) |
| 302 { | 303 { |
| 303 m_accumulatedOffset += step.m_offset; | 304 m_accumulatedOffset += step.m_offset; |
| 304 | 305 |
| 305 if (step.m_isNonUniform) | 306 if (step.m_isNonUniform) |
| 306 ++m_nonUniformStepsCount; | 307 ++m_nonUniformStepsCount; |
| 307 | 308 |
| 308 if (step.m_transform) | 309 if (step.m_transform) |
| 309 ++m_transformedStepsCount; | 310 ++m_transformedStepsCount; |
| 310 | 311 |
| 311 if (step.m_isFixedPosition) | 312 if (step.m_isViewportConstrained) |
| 312 ++m_fixedStepsCount; | 313 ++m_viewportConstrainedStepsCount; |
| 313 } | 314 } |
| 314 | 315 |
| 315 void LayoutGeometryMap::stepRemoved(const LayoutGeometryMapStep& step) | 316 void LayoutGeometryMap::stepRemoved(const LayoutGeometryMapStep& step) |
| 316 { | 317 { |
| 317 m_accumulatedOffset -= step.m_offset; | 318 m_accumulatedOffset -= step.m_offset; |
| 318 | 319 |
| 319 if (step.m_isNonUniform) { | 320 if (step.m_isNonUniform) { |
| 320 ASSERT(m_nonUniformStepsCount); | 321 ASSERT(m_nonUniformStepsCount); |
| 321 --m_nonUniformStepsCount; | 322 --m_nonUniformStepsCount; |
| 322 } | 323 } |
| 323 | 324 |
| 324 if (step.m_transform) { | 325 if (step.m_transform) { |
| 325 ASSERT(m_transformedStepsCount); | 326 ASSERT(m_transformedStepsCount); |
| 326 --m_transformedStepsCount; | 327 --m_transformedStepsCount; |
| 327 } | 328 } |
| 328 | 329 |
| 329 if (step.m_isFixedPosition) { | 330 if (step.m_isViewportConstrained) { |
| 330 ASSERT(m_fixedStepsCount); | 331 ASSERT(m_viewportConstrainedStepsCount); |
| 331 --m_fixedStepsCount; | 332 --m_viewportConstrainedStepsCount; |
| 332 } | 333 } |
| 333 } | 334 } |
| 334 | 335 |
| 335 #if ENABLE(ASSERT) | 336 #if ENABLE(ASSERT) |
| 336 bool LayoutGeometryMap::isTopmostLayoutView(const LayoutObject* layoutObject) co nst | 337 bool LayoutGeometryMap::isTopmostLayoutView(const LayoutObject* layoutObject) co nst |
| 337 { | 338 { |
| 338 if (!layoutObject->isLayoutView()) | 339 if (!layoutObject->isLayoutView()) |
| 339 return false; | 340 return false; |
| 340 | 341 |
| 341 // If we're not working with multiple LayoutViews, then any view is consider ed | 342 // If we're not working with multiple LayoutViews, then any view is consider ed |
| 342 // "topmost" (to preserve original behavior). | 343 // "topmost" (to preserve original behavior). |
| 343 if (!(m_mapCoordinatesFlags & TraverseDocumentBoundaries)) | 344 if (!(m_mapCoordinatesFlags & TraverseDocumentBoundaries)) |
| 344 return true; | 345 return true; |
| 345 | 346 |
| 346 return layoutObject->frame()->isMainFrame(); | 347 return layoutObject->frame()->isMainFrame(); |
| 347 } | 348 } |
| 348 #endif | 349 #endif |
| 349 | 350 |
| 350 } // namespace blink | 351 } // namespace blink |
| OLD | NEW |