| 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 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 | 81 |
| 82 // If this box has a transform, it acts as a fixed position container | 82 // If this box has a transform, it acts as a fixed position container |
| 83 // for fixed descendants, which prevents the propagation of 'fixed' | 83 // for fixed descendants, which prevents the propagation of 'fixed' |
| 84 // unless the layer itself is also fixed position. | 84 // unless the layer itself is also fixed position. |
| 85 if (i && currentStep.m_flags & ContainsFixedPosition && | 85 if (i && currentStep.m_flags & ContainsFixedPosition && |
| 86 !(currentStep.m_flags & IsFixedPosition)) | 86 !(currentStep.m_flags & IsFixedPosition)) |
| 87 inFixed = false; | 87 inFixed = false; |
| 88 else if (currentStep.m_flags & IsFixedPosition) | 88 else if (currentStep.m_flags & IsFixedPosition) |
| 89 inFixed = true; | 89 inFixed = true; |
| 90 | 90 |
| 91 ASSERT(!i == isTopmostLayoutView(currentStep.m_layoutObject)); | 91 #if DCHECK_IS_ON() |
| 92 DCHECK_EQ(!i, isTopmostLayoutView(currentStep.m_layoutObject)); |
| 93 #endif |
| 92 | 94 |
| 93 if (!i) { | 95 if (!i) { |
| 94 // A null container indicates mapping through the root LayoutView, so | 96 // A null container indicates mapping through the root LayoutView, so |
| 95 // including its transform (the page scale). | 97 // including its transform (the page scale). |
| 96 if (!ancestor && currentStep.m_transform) | 98 if (!ancestor && currentStep.m_transform) |
| 97 transformState.applyTransform(*currentStep.m_transform.get()); | 99 transformState.applyTransform(*currentStep.m_transform.get()); |
| 98 } else { | 100 } else { |
| 99 TransformState::TransformAccumulation accumulate = | 101 TransformState::TransformAccumulation accumulate = |
| 100 currentStep.m_flags & AccumulatingTransform | 102 currentStep.m_flags & AccumulatingTransform |
| 101 ? TransformState::AccumulateTransform | 103 ? TransformState::AccumulateTransform |
| 102 : TransformState::FlattenTransform; | 104 : TransformState::FlattenTransform; |
| 103 if (currentStep.m_transform) | 105 if (currentStep.m_transform) |
| 104 transformState.applyTransform(*currentStep.m_transform.get(), | 106 transformState.applyTransform(*currentStep.m_transform.get(), |
| 105 accumulate); | 107 accumulate); |
| 106 else | 108 else |
| 107 transformState.move(currentStep.m_offset.width(), | 109 transformState.move(currentStep.m_offset.width(), |
| 108 currentStep.m_offset.height(), accumulate); | 110 currentStep.m_offset.height(), accumulate); |
| 109 } | 111 } |
| 110 | 112 |
| 111 if (inFixed && !currentStep.m_offsetForFixedPosition.isZero()) { | 113 if (inFixed && !currentStep.m_offsetForFixedPosition.isZero()) { |
| 112 ASSERT(currentStep.m_layoutObject->isLayoutView()); | 114 DCHECK(currentStep.m_layoutObject->isLayoutView()); |
| 113 transformState.move(currentStep.m_offsetForFixedPosition); | 115 transformState.move(currentStep.m_offsetForFixedPosition); |
| 114 } | 116 } |
| 115 } | 117 } |
| 116 | 118 |
| 117 ASSERT(foundAncestor); | 119 #if DCHECK_IS_ON() |
| 120 DCHECK(foundAncestor); |
| 121 #endif |
| 118 transformState.flatten(); | 122 transformState.flatten(); |
| 119 } | 123 } |
| 120 | 124 |
| 121 #ifndef NDEBUG | 125 #ifndef NDEBUG |
| 122 // Handy function to call from gdb while debugging mismatched point/rect errors. | 126 // Handy function to call from gdb while debugging mismatched point/rect errors. |
| 123 void LayoutGeometryMap::dumpSteps() const { | 127 void LayoutGeometryMap::dumpSteps() const { |
| 124 fprintf(stderr, "LayoutGeometryMap::dumpSteps accumulatedOffset=%d,%d\n", | 128 fprintf(stderr, "LayoutGeometryMap::dumpSteps accumulatedOffset=%d,%d\n", |
| 125 m_accumulatedOffset.width().toInt(), | 129 m_accumulatedOffset.width().toInt(), |
| 126 m_accumulatedOffset.height().toInt()); | 130 m_accumulatedOffset.height().toInt()); |
| 127 for (int i = m_mapping.size() - 1; i >= 0; --i) { | 131 for (int i = m_mapping.size() - 1; i >= 0; --i) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 158 const LayoutObject* lastLayoutObject = m_mapping.back().m_layoutObject; | 162 const LayoutObject* lastLayoutObject = m_mapping.back().m_layoutObject; |
| 159 | 163 |
| 160 FloatRect layoutObjectMappedResult = | 164 FloatRect layoutObjectMappedResult = |
| 161 lastLayoutObject | 165 lastLayoutObject |
| 162 ->localToAncestorQuad(rect, ancestor, m_mapCoordinatesFlags) | 166 ->localToAncestorQuad(rect, ancestor, m_mapCoordinatesFlags) |
| 163 .boundingBox(); | 167 .boundingBox(); |
| 164 | 168 |
| 165 // Inspector creates layoutObjects with negative width | 169 // Inspector creates layoutObjects with negative width |
| 166 // <https://bugs.webkit.org/show_bug.cgi?id=87194>. | 170 // <https://bugs.webkit.org/show_bug.cgi?id=87194>. |
| 167 // Taking FloatQuad bounds avoids spurious assertions because of that. | 171 // Taking FloatQuad bounds avoids spurious assertions because of that. |
| 168 ASSERT(enclosingIntRect(layoutObjectMappedResult) == | 172 DCHECK(enclosingIntRect(layoutObjectMappedResult) == |
| 169 enclosingIntRect(result.boundingBox()) || | 173 enclosingIntRect(result.boundingBox()) || |
| 170 layoutObjectMappedResult.mayNotHaveExactIntRectRepresentation() || | 174 layoutObjectMappedResult.mayNotHaveExactIntRectRepresentation() || |
| 171 result.boundingBox().mayNotHaveExactIntRectRepresentation()); | 175 result.boundingBox().mayNotHaveExactIntRectRepresentation()); |
| 172 } | 176 } |
| 173 #endif | 177 #endif |
| 174 | 178 |
| 175 return result; | 179 return result; |
| 176 } | 180 } |
| 177 | 181 |
| 178 void LayoutGeometryMap::pushMappingsToAncestor( | 182 void LayoutGeometryMap::pushMappingsToAncestor( |
| 179 const LayoutObject* layoutObject, | 183 const LayoutObject* layoutObject, |
| 180 const LayoutBoxModelObject* ancestorLayoutObject) { | 184 const LayoutBoxModelObject* ancestorLayoutObject) { |
| 181 // We need to push mappings in reverse order here, so do insertions rather | 185 // We need to push mappings in reverse order here, so do insertions rather |
| 182 // than appends. | 186 // than appends. |
| 183 AutoReset<size_t> positionChange(&m_insertionPosition, m_mapping.size()); | 187 AutoReset<size_t> positionChange(&m_insertionPosition, m_mapping.size()); |
| 184 do { | 188 do { |
| 185 layoutObject = | 189 layoutObject = |
| 186 layoutObject->pushMappingToContainer(ancestorLayoutObject, *this); | 190 layoutObject->pushMappingToContainer(ancestorLayoutObject, *this); |
| 187 } while (layoutObject && layoutObject != ancestorLayoutObject); | 191 } while (layoutObject && layoutObject != ancestorLayoutObject); |
| 188 | 192 |
| 189 ASSERT(m_mapping.isEmpty() || | 193 #if DCHECK_IS_ON() |
| 194 DCHECK(m_mapping.isEmpty() || |
| 190 isTopmostLayoutView(m_mapping[0].m_layoutObject)); | 195 isTopmostLayoutView(m_mapping[0].m_layoutObject)); |
| 196 #endif |
| 191 } | 197 } |
| 192 | 198 |
| 193 static bool canMapBetweenLayoutObjects(const LayoutObject& layoutObject, | 199 static bool canMapBetweenLayoutObjects(const LayoutObject& layoutObject, |
| 194 const LayoutObject& ancestor) { | 200 const LayoutObject& ancestor) { |
| 195 for (const LayoutObject* current = &layoutObject;; | 201 for (const LayoutObject* current = &layoutObject;; |
| 196 current = current->parent()) { | 202 current = current->parent()) { |
| 197 const ComputedStyle& style = current->styleRef(); | 203 const ComputedStyle& style = current->styleRef(); |
| 198 if (style.position() == EPosition::kFixed || | 204 if (style.position() == EPosition::kFixed || |
| 199 style.isFlippedBlocksWritingMode() || | 205 style.isFlippedBlocksWritingMode() || |
| 200 style.hasTransformRelatedProperty()) | 206 style.hasTransformRelatedProperty()) |
| (...skipping 14 matching lines...) Expand all Loading... |
| 215 } | 221 } |
| 216 | 222 |
| 217 void LayoutGeometryMap::pushMappingsToAncestor( | 223 void LayoutGeometryMap::pushMappingsToAncestor( |
| 218 const PaintLayer* layer, | 224 const PaintLayer* layer, |
| 219 const PaintLayer* ancestorLayer) { | 225 const PaintLayer* ancestorLayer) { |
| 220 const LayoutObject& layoutObject = layer->layoutObject(); | 226 const LayoutObject& layoutObject = layer->layoutObject(); |
| 221 | 227 |
| 222 bool crossDocument = | 228 bool crossDocument = |
| 223 ancestorLayer && | 229 ancestorLayer && |
| 224 layoutObject.frame() != ancestorLayer->layoutObject().frame(); | 230 layoutObject.frame() != ancestorLayer->layoutObject().frame(); |
| 225 ASSERT(!crossDocument || m_mapCoordinatesFlags & TraverseDocumentBoundaries); | 231 DCHECK(!crossDocument || m_mapCoordinatesFlags & TraverseDocumentBoundaries); |
| 226 | 232 |
| 227 // We have to visit all the layoutObjects to detect flipped blocks. This might | 233 // We have to visit all the layoutObjects to detect flipped blocks. This might |
| 228 // defeat the gains from mapping via layers. | 234 // defeat the gains from mapping via layers. |
| 229 bool canConvertInLayerTree = | 235 bool canConvertInLayerTree = |
| 230 (ancestorLayer && !crossDocument) | 236 (ancestorLayer && !crossDocument) |
| 231 ? canMapBetweenLayoutObjects(layoutObject, | 237 ? canMapBetweenLayoutObjects(layoutObject, |
| 232 ancestorLayer->layoutObject()) | 238 ancestorLayer->layoutObject()) |
| 233 : false; | 239 : false; |
| 234 | 240 |
| 235 LAYOUT_GEOMETRY_MAP_LOG( | 241 LAYOUT_GEOMETRY_MAP_LOG( |
| (...skipping 25 matching lines...) Expand all Loading... |
| 261 } | 267 } |
| 262 | 268 |
| 263 void LayoutGeometryMap::push(const LayoutObject* layoutObject, | 269 void LayoutGeometryMap::push(const LayoutObject* layoutObject, |
| 264 const LayoutSize& offsetFromContainer, | 270 const LayoutSize& offsetFromContainer, |
| 265 GeometryInfoFlags flags, | 271 GeometryInfoFlags flags, |
| 266 LayoutSize offsetForFixedPosition) { | 272 LayoutSize offsetForFixedPosition) { |
| 267 LAYOUT_GEOMETRY_MAP_LOG("LayoutGeometryMap::push %p %d,%d isNonUniform=%d\n", | 273 LAYOUT_GEOMETRY_MAP_LOG("LayoutGeometryMap::push %p %d,%d isNonUniform=%d\n", |
| 268 layoutObject, offsetFromContainer.width().toInt(), | 274 layoutObject, offsetFromContainer.width().toInt(), |
| 269 offsetFromContainer.height().toInt(), isNonUniform); | 275 offsetFromContainer.height().toInt(), isNonUniform); |
| 270 | 276 |
| 271 ASSERT(m_insertionPosition != kNotFound); | 277 DCHECK_NE(m_insertionPosition, kNotFound); |
| 272 ASSERT(!layoutObject->isLayoutView() || !m_insertionPosition || | 278 DCHECK(!layoutObject->isLayoutView() || !m_insertionPosition || |
| 273 m_mapCoordinatesFlags & TraverseDocumentBoundaries); | 279 m_mapCoordinatesFlags & TraverseDocumentBoundaries); |
| 274 ASSERT(offsetForFixedPosition.isZero() || layoutObject->isLayoutView()); | 280 DCHECK(offsetForFixedPosition.isZero() || layoutObject->isLayoutView()); |
| 275 | 281 |
| 276 m_mapping.insert(m_insertionPosition, | 282 m_mapping.insert(m_insertionPosition, |
| 277 LayoutGeometryMapStep(layoutObject, flags)); | 283 LayoutGeometryMapStep(layoutObject, flags)); |
| 278 | 284 |
| 279 LayoutGeometryMapStep& step = m_mapping[m_insertionPosition]; | 285 LayoutGeometryMapStep& step = m_mapping[m_insertionPosition]; |
| 280 step.m_offset = offsetFromContainer; | 286 step.m_offset = offsetFromContainer; |
| 281 step.m_offsetForFixedPosition = offsetForFixedPosition; | 287 step.m_offsetForFixedPosition = offsetForFixedPosition; |
| 282 | 288 |
| 283 stepInserted(step); | 289 stepInserted(step); |
| 284 } | 290 } |
| 285 | 291 |
| 286 void LayoutGeometryMap::push(const LayoutObject* layoutObject, | 292 void LayoutGeometryMap::push(const LayoutObject* layoutObject, |
| 287 const TransformationMatrix& t, | 293 const TransformationMatrix& t, |
| 288 GeometryInfoFlags flags, | 294 GeometryInfoFlags flags, |
| 289 LayoutSize offsetForFixedPosition) { | 295 LayoutSize offsetForFixedPosition) { |
| 290 ASSERT(m_insertionPosition != kNotFound); | 296 DCHECK_NE(m_insertionPosition, kNotFound); |
| 291 ASSERT(!layoutObject->isLayoutView() || !m_insertionPosition || | 297 DCHECK(!layoutObject->isLayoutView() || !m_insertionPosition || |
| 292 m_mapCoordinatesFlags & TraverseDocumentBoundaries); | 298 m_mapCoordinatesFlags & TraverseDocumentBoundaries); |
| 293 ASSERT(offsetForFixedPosition.isZero() || layoutObject->isLayoutView()); | 299 DCHECK(offsetForFixedPosition.isZero() || layoutObject->isLayoutView()); |
| 294 | 300 |
| 295 m_mapping.insert(m_insertionPosition, | 301 m_mapping.insert(m_insertionPosition, |
| 296 LayoutGeometryMapStep(layoutObject, flags)); | 302 LayoutGeometryMapStep(layoutObject, flags)); |
| 297 | 303 |
| 298 LayoutGeometryMapStep& step = m_mapping[m_insertionPosition]; | 304 LayoutGeometryMapStep& step = m_mapping[m_insertionPosition]; |
| 299 step.m_offsetForFixedPosition = offsetForFixedPosition; | 305 step.m_offsetForFixedPosition = offsetForFixedPosition; |
| 300 | 306 |
| 301 if (!t.isIntegerTranslation()) | 307 if (!t.isIntegerTranslation()) |
| 302 step.m_transform = TransformationMatrix::create(t); | 308 step.m_transform = TransformationMatrix::create(t); |
| 303 else | 309 else |
| 304 step.m_offset = LayoutSize(LayoutUnit(t.e()), LayoutUnit(t.f())); | 310 step.m_offset = LayoutSize(LayoutUnit(t.e()), LayoutUnit(t.f())); |
| 305 | 311 |
| 306 stepInserted(step); | 312 stepInserted(step); |
| 307 } | 313 } |
| 308 | 314 |
| 309 void LayoutGeometryMap::popMappingsToAncestor( | 315 void LayoutGeometryMap::popMappingsToAncestor( |
| 310 const LayoutBoxModelObject* ancestorLayoutObject) { | 316 const LayoutBoxModelObject* ancestorLayoutObject) { |
| 311 ASSERT(m_mapping.size()); | 317 DCHECK(m_mapping.size()); |
| 312 | 318 |
| 313 bool mightBeSaturated = false; | 319 bool mightBeSaturated = false; |
| 314 while (m_mapping.size() && | 320 while (m_mapping.size() && |
| 315 m_mapping.back().m_layoutObject != ancestorLayoutObject) { | 321 m_mapping.back().m_layoutObject != ancestorLayoutObject) { |
| 316 mightBeSaturated = | 322 mightBeSaturated = |
| 317 mightBeSaturated || m_accumulatedOffset.width().mightBeSaturated(); | 323 mightBeSaturated || m_accumulatedOffset.width().mightBeSaturated(); |
| 318 mightBeSaturated = | 324 mightBeSaturated = |
| 319 mightBeSaturated || m_accumulatedOffset.height().mightBeSaturated(); | 325 mightBeSaturated || m_accumulatedOffset.height().mightBeSaturated(); |
| 320 stepRemoved(m_mapping.back()); | 326 stepRemoved(m_mapping.back()); |
| 321 m_mapping.pop_back(); | 327 m_mapping.pop_back(); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 343 ++m_transformedStepsCount; | 349 ++m_transformedStepsCount; |
| 344 | 350 |
| 345 if (step.m_flags & IsFixedPosition) | 351 if (step.m_flags & IsFixedPosition) |
| 346 ++m_fixedStepsCount; | 352 ++m_fixedStepsCount; |
| 347 } | 353 } |
| 348 | 354 |
| 349 void LayoutGeometryMap::stepRemoved(const LayoutGeometryMapStep& step) { | 355 void LayoutGeometryMap::stepRemoved(const LayoutGeometryMapStep& step) { |
| 350 m_accumulatedOffset -= step.m_offset; | 356 m_accumulatedOffset -= step.m_offset; |
| 351 | 357 |
| 352 if (step.m_flags & IsNonUniform) { | 358 if (step.m_flags & IsNonUniform) { |
| 353 ASSERT(m_nonUniformStepsCount); | 359 DCHECK(m_nonUniformStepsCount); |
| 354 --m_nonUniformStepsCount; | 360 --m_nonUniformStepsCount; |
| 355 } | 361 } |
| 356 | 362 |
| 357 if (step.m_transform) { | 363 if (step.m_transform) { |
| 358 ASSERT(m_transformedStepsCount); | 364 DCHECK(m_transformedStepsCount); |
| 359 --m_transformedStepsCount; | 365 --m_transformedStepsCount; |
| 360 } | 366 } |
| 361 | 367 |
| 362 if (step.m_flags & IsFixedPosition) { | 368 if (step.m_flags & IsFixedPosition) { |
| 363 ASSERT(m_fixedStepsCount); | 369 DCHECK(m_fixedStepsCount); |
| 364 --m_fixedStepsCount; | 370 --m_fixedStepsCount; |
| 365 } | 371 } |
| 366 } | 372 } |
| 367 | 373 |
| 368 #if DCHECK_IS_ON() | 374 #if DCHECK_IS_ON() |
| 369 bool LayoutGeometryMap::isTopmostLayoutView( | 375 bool LayoutGeometryMap::isTopmostLayoutView( |
| 370 const LayoutObject* layoutObject) const { | 376 const LayoutObject* layoutObject) const { |
| 371 if (!layoutObject->isLayoutView()) | 377 if (!layoutObject->isLayoutView()) |
| 372 return false; | 378 return false; |
| 373 | 379 |
| 374 // If we're not working with multiple LayoutViews, then any view is considered | 380 // If we're not working with multiple LayoutViews, then any view is considered |
| 375 // "topmost" (to preserve original behavior). | 381 // "topmost" (to preserve original behavior). |
| 376 if (!(m_mapCoordinatesFlags & TraverseDocumentBoundaries)) | 382 if (!(m_mapCoordinatesFlags & TraverseDocumentBoundaries)) |
| 377 return true; | 383 return true; |
| 378 | 384 |
| 379 return layoutObject->frame()->isMainFrame(); | 385 return layoutObject->frame()->isMainFrame(); |
| 380 } | 386 } |
| 381 #endif | 387 #endif |
| 382 | 388 |
| 383 } // namespace blink | 389 } // namespace blink |
| OLD | NEW |