Chromium Code Reviews| 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 * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) | 4 * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) |
| 5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com) | 5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com) |
| 6 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserv ed. | 6 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserv ed. |
| 7 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved. | 7 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved. |
| 8 * | 8 * |
| 9 * This library is free software; you can redistribute it and/or | 9 * This library is free software; you can redistribute it and/or |
| 10 * modify it under the terms of the GNU Library General Public | 10 * modify it under the terms of the GNU Library General Public |
| (...skipping 2941 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2952 LayoutUnit heightResult; | 2952 LayoutUnit heightResult; |
| 2953 LayoutRect boundingBox(flow->linesBoundingBox()); | 2953 LayoutRect boundingBox(flow->linesBoundingBox()); |
| 2954 if (containingBlock->isHorizontalWritingMode()) | 2954 if (containingBlock->isHorizontalWritingMode()) |
| 2955 heightResult = boundingBox.height(); | 2955 heightResult = boundingBox.height(); |
| 2956 else | 2956 else |
| 2957 heightResult = boundingBox.width(); | 2957 heightResult = boundingBox.width(); |
| 2958 heightResult -= (containingBlock->borderBefore() + containingBlock->borderAf ter()); | 2958 heightResult -= (containingBlock->borderBefore() + containingBlock->borderAf ter()); |
| 2959 return heightResult; | 2959 return heightResult; |
| 2960 } | 2960 } |
| 2961 | 2961 |
| 2962 static void computeInlineStaticDistance(Length& logicalLeft, Length& logicalRigh t, const LayoutBox* child, const LayoutBoxModelObject* containerBlock, LayoutUni t containerLogicalWidth) | 2962 void LayoutBox::computeInlineStaticDistance(Length& logicalLeft, Length& logical Right, const LayoutBox* child, const LayoutBoxModelObject* containerBlock, Layou tUnit containerLogicalWidth) |
| 2963 { | 2963 { |
| 2964 if (!logicalLeft.isAuto() || !logicalRight.isAuto()) | 2964 if (!logicalLeft.isAuto() || !logicalRight.isAuto()) |
| 2965 return; | 2965 return; |
| 2966 | 2966 |
| 2967 // FIXME: The static distance computation has not been patched for mixed wri ting modes yet. | 2967 // FIXME: The static distance computation has not been patched for mixed wri ting modes yet. |
| 2968 if (child->parent()->style()->direction() == LTR) { | 2968 if (child->parent()->style()->direction() == LTR) { |
| 2969 LayoutUnit staticPosition = child->layer()->staticInlinePosition() - con tainerBlock->borderLogicalLeft(); | 2969 LayoutUnit staticPosition = child->layer()->staticInlinePosition() - con tainerBlock->borderLogicalLeft(); |
| 2970 for (LayoutObject* curr = child->parent(); curr && curr != containerBloc k; curr = curr->container()) { | 2970 for (LayoutObject* curr = child->parent(); curr && curr != containerBloc k; curr = curr->container()) { |
| 2971 if (curr->isBox()) { | 2971 if (curr->isBox()) { |
| 2972 staticPosition += toLayoutBox(curr)->logicalLeft(); | 2972 staticPosition += toLayoutBox(curr)->logicalLeft(); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3004 } | 3004 } |
| 3005 if (curr == containerBlock) | 3005 if (curr == containerBlock) |
| 3006 break; | 3006 break; |
| 3007 } | 3007 } |
| 3008 logicalRight.setValue(Fixed, staticPosition); | 3008 logicalRight.setValue(Fixed, staticPosition); |
| 3009 } | 3009 } |
| 3010 } | 3010 } |
| 3011 | 3011 |
| 3012 void LayoutBox::computePositionedLogicalWidth(LogicalExtentComputedValues& compu tedValues) const | 3012 void LayoutBox::computePositionedLogicalWidth(LogicalExtentComputedValues& compu tedValues) const |
| 3013 { | 3013 { |
| 3014 if (isAtomicInlineLevel()) { | |
|
mstensho (USE GERRIT)
2016/01/21 18:50:46
Yeah, this became absurd, with the isReplaced -> i
| |
| 3015 computePositionedLogicalWidthReplaced(computedValues); | |
| 3016 return; | |
| 3017 } | |
| 3018 | |
| 3019 // QUESTIONS | 3014 // QUESTIONS |
| 3020 // FIXME 1: Should we still deal with these the cases of 'left' or 'right' h aving | 3015 // FIXME 1: Should we still deal with these the cases of 'left' or 'right' h aving |
| 3021 // the type 'static' in determining whether to calculate the static distance ? | 3016 // the type 'static' in determining whether to calculate the static distance ? |
| 3022 // NOTE: 'static' is not a legal value for 'left' or 'right' as of CSS 2.1. | 3017 // NOTE: 'static' is not a legal value for 'left' or 'right' as of CSS 2.1. |
| 3023 | 3018 |
| 3024 // FIXME 2: Can perhaps optimize out cases when max-width/min-width are grea ter | 3019 // FIXME 2: Can perhaps optimize out cases when max-width/min-width are grea ter |
| 3025 // than or less than the computed width(). Be careful of box-sizing and | 3020 // than or less than the computed width(). Be careful of box-sizing and |
| 3026 // percentage issues. | 3021 // percentage issues. |
| 3027 | 3022 |
| 3028 // The following is based off of the W3C Working Draft from April 11, 2006 o f | 3023 // The following is based off of the W3C Working Draft from April 11, 2006 o f |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3118 computedValues.m_margins.m_end = minValues.m_margins.m_end; | 3113 computedValues.m_margins.m_end = minValues.m_margins.m_end; |
| 3119 } | 3114 } |
| 3120 } | 3115 } |
| 3121 | 3116 |
| 3122 if (!style()->hasStaticInlinePosition(isHorizontal)) | 3117 if (!style()->hasStaticInlinePosition(isHorizontal)) |
| 3123 computedValues.m_position += extraInlineOffset(); | 3118 computedValues.m_position += extraInlineOffset(); |
| 3124 | 3119 |
| 3125 computedValues.m_extent += bordersPlusPadding; | 3120 computedValues.m_extent += bordersPlusPadding; |
| 3126 } | 3121 } |
| 3127 | 3122 |
| 3128 static void computeLogicalLeftPositionedOffset(LayoutUnit& logicalLeftPos, const LayoutBox* child, LayoutUnit logicalWidthValue, const LayoutBoxModelObject* con tainerBlock, LayoutUnit containerLogicalWidth) | 3123 void LayoutBox::computeLogicalLeftPositionedOffset(LayoutUnit& logicalLeftPos, c onst LayoutBox* child, LayoutUnit logicalWidthValue, const LayoutBoxModelObject* containerBlock, LayoutUnit containerLogicalWidth) |
| 3129 { | 3124 { |
| 3130 // Deal with differing writing modes here. Our offset needs to be in the co ntaining block's coordinate space. If the containing block is flipped | 3125 // Deal with differing writing modes here. Our offset needs to be in the co ntaining block's coordinate space. If the containing block is flipped |
| 3131 // along this axis, then we need to flip the coordinate. This can only happ en if the containing block is both a flipped mode and perpendicular to us. | 3126 // along this axis, then we need to flip the coordinate. This can only happ en if the containing block is both a flipped mode and perpendicular to us. |
| 3132 if (containerBlock->isHorizontalWritingMode() != child->isHorizontalWritingM ode() && containerBlock->style()->isFlippedBlocksWritingMode()) { | 3127 if (containerBlock->isHorizontalWritingMode() != child->isHorizontalWritingM ode() && containerBlock->style()->isFlippedBlocksWritingMode()) { |
| 3133 logicalLeftPos = containerLogicalWidth - logicalWidthValue - logicalLeft Pos; | 3128 logicalLeftPos = containerLogicalWidth - logicalWidthValue - logicalLeft Pos; |
| 3134 logicalLeftPos += (child->isHorizontalWritingMode() ? containerBlock->bo rderRight() : containerBlock->borderBottom()); | 3129 logicalLeftPos += (child->isHorizontalWritingMode() ? containerBlock->bo rderRight() : containerBlock->borderBottom()); |
| 3135 } else { | 3130 } else { |
| 3136 logicalLeftPos += (child->isHorizontalWritingMode() ? containerBlock->bo rderLeft() : containerBlock->borderTop()); | 3131 logicalLeftPos += (child->isHorizontalWritingMode() ? containerBlock->bo rderLeft() : containerBlock->borderTop()); |
| 3137 } | 3132 } |
| 3138 } | 3133 } |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3315 } | 3310 } |
| 3316 | 3311 |
| 3317 if (containerBlock->isBox() && toLayoutBox(containerBlock)->scrollsOverflowY () && toLayoutBox(containerBlock)->shouldPlaceBlockDirectionScrollbarOnLogicalLe ft()) { | 3312 if (containerBlock->isBox() && toLayoutBox(containerBlock)->scrollsOverflowY () && toLayoutBox(containerBlock)->shouldPlaceBlockDirectionScrollbarOnLogicalLe ft()) { |
| 3318 logicalLeftValue = logicalLeftValue + toLayoutBox(containerBlock)->verti calScrollbarWidth(); | 3313 logicalLeftValue = logicalLeftValue + toLayoutBox(containerBlock)->verti calScrollbarWidth(); |
| 3319 } | 3314 } |
| 3320 | 3315 |
| 3321 computedValues.m_position = logicalLeftValue + marginLogicalLeftValue; | 3316 computedValues.m_position = logicalLeftValue + marginLogicalLeftValue; |
| 3322 computeLogicalLeftPositionedOffset(computedValues.m_position, this, computed Values.m_extent, containerBlock, containerLogicalWidth); | 3317 computeLogicalLeftPositionedOffset(computedValues.m_position, this, computed Values.m_extent, containerBlock, containerLogicalWidth); |
| 3323 } | 3318 } |
| 3324 | 3319 |
| 3325 static void computeBlockStaticDistance(Length& logicalTop, Length& logicalBottom , const LayoutBox* child, const LayoutBoxModelObject* containerBlock) | 3320 void LayoutBox::computeBlockStaticDistance(Length& logicalTop, Length& logicalBo ttom, const LayoutBox* child, const LayoutBoxModelObject* containerBlock) |
| 3326 { | 3321 { |
| 3327 if (!logicalTop.isAuto() || !logicalBottom.isAuto()) | 3322 if (!logicalTop.isAuto() || !logicalBottom.isAuto()) |
| 3328 return; | 3323 return; |
| 3329 | 3324 |
| 3330 // FIXME: The static distance computation has not been patched for mixed wri ting modes. | 3325 // FIXME: The static distance computation has not been patched for mixed wri ting modes. |
| 3331 LayoutUnit staticLogicalTop = child->layer()->staticBlockPosition() - contai nerBlock->borderBefore(); | 3326 LayoutUnit staticLogicalTop = child->layer()->staticBlockPosition() - contai nerBlock->borderBefore(); |
| 3332 for (LayoutObject* curr = child->parent(); curr && curr != containerBlock; c urr = curr->container()) { | 3327 for (LayoutObject* curr = child->parent(); curr && curr != containerBlock; c urr = curr->container()) { |
| 3333 if (curr->isBox() && !curr->isTableRow()) | 3328 if (curr->isBox() && !curr->isTableRow()) |
| 3334 staticLogicalTop += toLayoutBox(curr)->logicalTop(); | 3329 staticLogicalTop += toLayoutBox(curr)->logicalTop(); |
| 3335 } | 3330 } |
| 3336 logicalTop.setValue(Fixed, staticLogicalTop); | 3331 logicalTop.setValue(Fixed, staticLogicalTop); |
| 3337 } | 3332 } |
| 3338 | 3333 |
| 3339 void LayoutBox::computePositionedLogicalHeight(LogicalExtentComputedValues& comp utedValues) const | 3334 void LayoutBox::computePositionedLogicalHeight(LogicalExtentComputedValues& comp utedValues) const |
| 3340 { | 3335 { |
| 3341 if (isAtomicInlineLevel()) { | |
| 3342 computePositionedLogicalHeightReplaced(computedValues); | |
| 3343 return; | |
| 3344 } | |
| 3345 | |
| 3346 // The following is based off of the W3C Working Draft from April 11, 2006 o f | 3336 // The following is based off of the W3C Working Draft from April 11, 2006 o f |
| 3347 // CSS 2.1: Section 10.6.4 "Absolutely positioned, non-replaced elements" | 3337 // CSS 2.1: Section 10.6.4 "Absolutely positioned, non-replaced elements" |
| 3348 // <http://www.w3.org/TR/2005/WD-CSS21-20050613/visudet.html#abs-non-replace d-height> | 3338 // <http://www.w3.org/TR/2005/WD-CSS21-20050613/visudet.html#abs-non-replace d-height> |
| 3349 // (block-style-comments in this function and in computePositionedLogicalHei ghtUsing() | 3339 // (block-style-comments in this function and in computePositionedLogicalHei ghtUsing() |
| 3350 // correspond to text from the spec) | 3340 // correspond to text from the spec) |
| 3351 | 3341 |
| 3352 | 3342 |
| 3353 // We don't use containingBlock(), since we may be positioned by an enclosin g relpositioned inline. | 3343 // We don't use containingBlock(), since we may be positioned by an enclosin g relpositioned inline. |
| 3354 const LayoutBoxModelObject* containerBlock = toLayoutBoxModelObject(containe r()); | 3344 const LayoutBoxModelObject* containerBlock = toLayoutBoxModelObject(containe r()); |
| 3355 | 3345 |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3424 } | 3414 } |
| 3425 } | 3415 } |
| 3426 | 3416 |
| 3427 if (!style()->hasStaticBlockPosition(isHorizontalWritingMode())) | 3417 if (!style()->hasStaticBlockPosition(isHorizontalWritingMode())) |
| 3428 computedValues.m_position += extraBlockOffset(); | 3418 computedValues.m_position += extraBlockOffset(); |
| 3429 | 3419 |
| 3430 // Set final height value. | 3420 // Set final height value. |
| 3431 computedValues.m_extent += bordersPlusPadding; | 3421 computedValues.m_extent += bordersPlusPadding; |
| 3432 } | 3422 } |
| 3433 | 3423 |
| 3434 static void computeLogicalTopPositionedOffset(LayoutUnit& logicalTopPos, const L ayoutBox* child, LayoutUnit logicalHeightValue, const LayoutBoxModelObject* cont ainerBlock, LayoutUnit containerLogicalHeight) | 3424 void LayoutBox::computeLogicalTopPositionedOffset(LayoutUnit& logicalTopPos, con st LayoutBox* child, LayoutUnit logicalHeightValue, const LayoutBoxModelObject* containerBlock, LayoutUnit containerLogicalHeight) |
| 3435 { | 3425 { |
| 3436 // Deal with differing writing modes here. Our offset needs to be in the co ntaining block's coordinate space. If the containing block is flipped | 3426 // Deal with differing writing modes here. Our offset needs to be in the co ntaining block's coordinate space. If the containing block is flipped |
| 3437 // along this axis, then we need to flip the coordinate. This can only happ en if the containing block is both a flipped mode and perpendicular to us. | 3427 // along this axis, then we need to flip the coordinate. This can only happ en if the containing block is both a flipped mode and perpendicular to us. |
| 3438 if ((child->style()->isFlippedBlocksWritingMode() && child->isHorizontalWrit ingMode() != containerBlock->isHorizontalWritingMode()) | 3428 if ((child->style()->isFlippedBlocksWritingMode() && child->isHorizontalWrit ingMode() != containerBlock->isHorizontalWritingMode()) |
| 3439 || (child->style()->isFlippedBlocksWritingMode() != containerBlock->styl e()->isFlippedBlocksWritingMode() && child->isHorizontalWritingMode() == contain erBlock->isHorizontalWritingMode())) | 3429 || (child->style()->isFlippedBlocksWritingMode() != containerBlock->styl e()->isFlippedBlocksWritingMode() && child->isHorizontalWritingMode() == contain erBlock->isHorizontalWritingMode())) |
| 3440 logicalTopPos = containerLogicalHeight - logicalHeightValue - logicalTop Pos; | 3430 logicalTopPos = containerLogicalHeight - logicalHeightValue - logicalTop Pos; |
| 3441 | 3431 |
| 3442 // Our offset is from the logical bottom edge in a flipped environment, e.g. , right for vertical-rl and bottom for horizontal-bt. | 3432 // Our offset is from the logical bottom edge in a flipped environment, e.g. , right for vertical-rl and bottom for horizontal-bt. |
| 3443 if (containerBlock->style()->isFlippedBlocksWritingMode() && child->isHorizo ntalWritingMode() == containerBlock->isHorizontalWritingMode()) { | 3433 if (containerBlock->style()->isFlippedBlocksWritingMode() && child->isHorizo ntalWritingMode() == containerBlock->isHorizontalWritingMode()) { |
| 3444 if (child->isHorizontalWritingMode()) | 3434 if (child->isHorizontalWritingMode()) |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3580 logicalTopValue = valueForLength(logicalTop, containerLogicalHeight) ; | 3570 logicalTopValue = valueForLength(logicalTop, containerLogicalHeight) ; |
| 3581 } | 3571 } |
| 3582 } | 3572 } |
| 3583 computedValues.m_extent = logicalHeightValue; | 3573 computedValues.m_extent = logicalHeightValue; |
| 3584 | 3574 |
| 3585 // Use computed values to calculate the vertical position. | 3575 // Use computed values to calculate the vertical position. |
| 3586 computedValues.m_position = logicalTopValue + computedValues.m_margins.m_bef ore; | 3576 computedValues.m_position = logicalTopValue + computedValues.m_margins.m_bef ore; |
| 3587 computeLogicalTopPositionedOffset(computedValues.m_position, this, logicalHe ightValue, containerBlock, containerLogicalHeight); | 3577 computeLogicalTopPositionedOffset(computedValues.m_position, this, logicalHe ightValue, containerBlock, containerLogicalHeight); |
| 3588 } | 3578 } |
| 3589 | 3579 |
| 3590 void LayoutBox::computePositionedLogicalWidthReplaced(LogicalExtentComputedValue s& computedValues) const | |
| 3591 { | |
| 3592 // The following is based off of the W3C Working Draft from April 11, 2006 o f | |
| 3593 // CSS 2.1: Section 10.3.8 "Absolutely positioned, replaced elements" | |
| 3594 // <http://www.w3.org/TR/2005/WD-CSS21-20050613/visudet.html#abs-replaced-wi dth> | |
| 3595 // (block-style-comments in this function correspond to text from the spec a nd | |
| 3596 // the numbers correspond to numbers in spec) | |
| 3597 | |
| 3598 // We don't use containingBlock(), since we may be positioned by an enclosin g | |
| 3599 // relative positioned inline. | |
| 3600 const LayoutBoxModelObject* containerBlock = toLayoutBoxModelObject(containe r()); | |
| 3601 | |
| 3602 const LayoutUnit containerLogicalWidth = containingBlockLogicalWidthForPosit ioned(containerBlock); | |
| 3603 const LayoutUnit containerRelativeLogicalWidth = containingBlockLogicalWidth ForPositioned(containerBlock, false); | |
| 3604 | |
| 3605 // To match WinIE, in quirks mode use the parent's 'direction' property | |
| 3606 // instead of the the container block's. | |
| 3607 TextDirection containerDirection = containerBlock->style()->direction(); | |
| 3608 | |
| 3609 // Variables to solve. | |
| 3610 bool isHorizontal = isHorizontalWritingMode(); | |
| 3611 Length logicalLeft = style()->logicalLeft(); | |
| 3612 Length logicalRight = style()->logicalRight(); | |
| 3613 Length marginLogicalLeft = isHorizontal ? style()->marginLeft() : style()->m arginTop(); | |
| 3614 Length marginLogicalRight = isHorizontal ? style()->marginRight() : style()- >marginBottom(); | |
| 3615 LayoutUnit& marginLogicalLeftAlias = style()->isLeftToRightDirection() ? com putedValues.m_margins.m_start : computedValues.m_margins.m_end; | |
| 3616 LayoutUnit& marginLogicalRightAlias = style()->isLeftToRightDirection() ? co mputedValues.m_margins.m_end : computedValues.m_margins.m_start; | |
| 3617 | |
| 3618 /*-----------------------------------------------------------------------*\ | |
| 3619 * 1. The used value of 'width' is determined as for inline replaced | |
| 3620 * elements. | |
| 3621 \*-----------------------------------------------------------------------*/ | |
| 3622 // NOTE: This value of width is final in that the min/max width calculations | |
| 3623 // are dealt with in computeReplacedWidth(). This means that the steps to p roduce | |
| 3624 // correct max/min in the non-replaced version, are not necessary. | |
| 3625 computedValues.m_extent = computeReplacedLogicalWidth() + borderAndPaddingLo gicalWidth(); | |
| 3626 | |
| 3627 const LayoutUnit availableSpace = containerLogicalWidth - computedValues.m_e xtent; | |
| 3628 | |
| 3629 /*-----------------------------------------------------------------------*\ | |
| 3630 * 2. If both 'left' and 'right' have the value 'auto', then if 'direction' | |
| 3631 * of the containing block is 'ltr', set 'left' to the static position; | |
| 3632 * else if 'direction' is 'rtl', set 'right' to the static position. | |
| 3633 \*-----------------------------------------------------------------------*/ | |
| 3634 // see FIXME 1 | |
| 3635 computeInlineStaticDistance(logicalLeft, logicalRight, this, containerBlock, containerLogicalWidth); | |
| 3636 | |
| 3637 /*-----------------------------------------------------------------------*\ | |
| 3638 * 3. If 'left' or 'right' are 'auto', replace any 'auto' on 'margin-left' | |
| 3639 * or 'margin-right' with '0'. | |
| 3640 \*-----------------------------------------------------------------------*/ | |
| 3641 if (logicalLeft.isAuto() || logicalRight.isAuto()) { | |
| 3642 if (marginLogicalLeft.isAuto()) | |
| 3643 marginLogicalLeft.setValue(Fixed, 0); | |
| 3644 if (marginLogicalRight.isAuto()) | |
| 3645 marginLogicalRight.setValue(Fixed, 0); | |
| 3646 } | |
| 3647 | |
| 3648 /*-----------------------------------------------------------------------*\ | |
| 3649 * 4. If at this point both 'margin-left' and 'margin-right' are still | |
| 3650 * 'auto', solve the equation under the extra constraint that the two | |
| 3651 * margins must get equal values, unless this would make them negative, | |
| 3652 * in which case when the direction of the containing block is 'ltr' | |
| 3653 * ('rtl'), set 'margin-left' ('margin-right') to zero and solve for | |
| 3654 * 'margin-right' ('margin-left'). | |
| 3655 \*-----------------------------------------------------------------------*/ | |
| 3656 LayoutUnit logicalLeftValue = 0; | |
| 3657 LayoutUnit logicalRightValue = 0; | |
| 3658 | |
| 3659 if (marginLogicalLeft.isAuto() && marginLogicalRight.isAuto()) { | |
| 3660 // 'left' and 'right' cannot be 'auto' due to step 3 | |
| 3661 ASSERT(!(logicalLeft.isAuto() && logicalRight.isAuto())); | |
| 3662 | |
| 3663 logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth); | |
| 3664 logicalRightValue = valueForLength(logicalRight, containerLogicalWidth); | |
| 3665 | |
| 3666 LayoutUnit difference = availableSpace - (logicalLeftValue + logicalRigh tValue); | |
| 3667 if (difference > 0) { | |
| 3668 marginLogicalLeftAlias = difference / 2; // split the difference | |
| 3669 marginLogicalRightAlias = difference - marginLogicalLeftAlias; // ac count for odd valued differences | |
| 3670 } else { | |
| 3671 // Use the containing block's direction rather than the parent block 's | |
| 3672 // per CSS 2.1 reference test abspos-replaced-width-margin-000. | |
| 3673 if (containerDirection == LTR) { | |
| 3674 marginLogicalLeftAlias = 0; | |
| 3675 marginLogicalRightAlias = difference; // will be negative | |
| 3676 } else { | |
| 3677 marginLogicalLeftAlias = difference; // will be negative | |
| 3678 marginLogicalRightAlias = 0; | |
| 3679 } | |
| 3680 } | |
| 3681 | |
| 3682 /*-----------------------------------------------------------------------*\ | |
| 3683 * 5. If at this point there is an 'auto' left, solve the equation for | |
| 3684 * that value. | |
| 3685 \*-----------------------------------------------------------------------*/ | |
| 3686 } else if (logicalLeft.isAuto()) { | |
| 3687 marginLogicalLeftAlias = valueForLength(marginLogicalLeft, containerRela tiveLogicalWidth); | |
| 3688 marginLogicalRightAlias = valueForLength(marginLogicalRight, containerRe lativeLogicalWidth); | |
| 3689 logicalRightValue = valueForLength(logicalRight, containerLogicalWidth); | |
| 3690 | |
| 3691 // Solve for 'left' | |
| 3692 logicalLeftValue = availableSpace - (logicalRightValue + marginLogicalLe ftAlias + marginLogicalRightAlias); | |
| 3693 } else if (logicalRight.isAuto()) { | |
| 3694 marginLogicalLeftAlias = valueForLength(marginLogicalLeft, containerRela tiveLogicalWidth); | |
| 3695 marginLogicalRightAlias = valueForLength(marginLogicalRight, containerRe lativeLogicalWidth); | |
| 3696 logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth); | |
| 3697 | |
| 3698 // Solve for 'right' | |
| 3699 logicalRightValue = availableSpace - (logicalLeftValue + marginLogicalLe ftAlias + marginLogicalRightAlias); | |
| 3700 } else if (marginLogicalLeft.isAuto()) { | |
| 3701 marginLogicalRightAlias = valueForLength(marginLogicalRight, containerRe lativeLogicalWidth); | |
| 3702 logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth); | |
| 3703 logicalRightValue = valueForLength(logicalRight, containerLogicalWidth); | |
| 3704 | |
| 3705 // Solve for 'margin-left' | |
| 3706 marginLogicalLeftAlias = availableSpace - (logicalLeftValue + logicalRig htValue + marginLogicalRightAlias); | |
| 3707 } else if (marginLogicalRight.isAuto()) { | |
| 3708 marginLogicalLeftAlias = valueForLength(marginLogicalLeft, containerRela tiveLogicalWidth); | |
| 3709 logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth); | |
| 3710 logicalRightValue = valueForLength(logicalRight, containerLogicalWidth); | |
| 3711 | |
| 3712 // Solve for 'margin-right' | |
| 3713 marginLogicalRightAlias = availableSpace - (logicalLeftValue + logicalRi ghtValue + marginLogicalLeftAlias); | |
| 3714 } else { | |
| 3715 // Nothing is 'auto', just calculate the values. | |
| 3716 marginLogicalLeftAlias = valueForLength(marginLogicalLeft, containerRela tiveLogicalWidth); | |
| 3717 marginLogicalRightAlias = valueForLength(marginLogicalRight, containerRe lativeLogicalWidth); | |
| 3718 logicalRightValue = valueForLength(logicalRight, containerLogicalWidth); | |
| 3719 logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth); | |
| 3720 // If the containing block is right-to-left, then push the left position as far to the right as possible | |
| 3721 if (containerDirection == RTL) { | |
| 3722 int totalLogicalWidth = computedValues.m_extent + logicalLeftValue + logicalRightValue + marginLogicalLeftAlias + marginLogicalRightAlias; | |
| 3723 logicalLeftValue = containerLogicalWidth - (totalLogicalWidth - logi calLeftValue); | |
| 3724 } | |
| 3725 } | |
| 3726 | |
| 3727 /*-----------------------------------------------------------------------*\ | |
| 3728 * 6. If at this point the values are over-constrained, ignore the value | |
| 3729 * for either 'left' (in case the 'direction' property of the | |
| 3730 * containing block is 'rtl') or 'right' (in case 'direction' is | |
| 3731 * 'ltr') and solve for that value. | |
| 3732 \*-----------------------------------------------------------------------*/ | |
| 3733 // NOTE: Constraints imposed by the width of the containing block and its co ntent have already been accounted for above. | |
| 3734 | |
| 3735 // FIXME: Deal with differing writing modes here. Our offset needs to be in the containing block's coordinate space, so that | |
| 3736 // can make the result here rather complicated to compute. | |
| 3737 | |
| 3738 // Use computed values to calculate the horizontal position. | |
| 3739 | |
| 3740 // FIXME: This hack is needed to calculate the logical left position for a ' rtl' relatively | |
| 3741 // positioned, inline containing block because right now, it is using the lo gical left position | |
| 3742 // of the first line box when really it should use the last line box. When | |
| 3743 // this is fixed elsewhere, this block should be removed. | |
| 3744 if (containerBlock->isLayoutInline() && !containerBlock->style()->isLeftToRi ghtDirection()) { | |
| 3745 const LayoutInline* flow = toLayoutInline(containerBlock); | |
| 3746 InlineFlowBox* firstLine = flow->firstLineBox(); | |
| 3747 InlineFlowBox* lastLine = flow->lastLineBox(); | |
| 3748 if (firstLine && lastLine && firstLine != lastLine) { | |
| 3749 computedValues.m_position = logicalLeftValue + marginLogicalLeftAlia s + lastLine->borderLogicalLeft() + (lastLine->logicalLeft() - firstLine->logica lLeft()); | |
| 3750 return; | |
| 3751 } | |
| 3752 } | |
| 3753 | |
| 3754 LayoutUnit logicalLeftPos = logicalLeftValue + marginLogicalLeftAlias; | |
| 3755 computeLogicalLeftPositionedOffset(logicalLeftPos, this, computedValues.m_ex tent, containerBlock, containerLogicalWidth); | |
| 3756 computedValues.m_position = logicalLeftPos; | |
| 3757 } | |
| 3758 | |
| 3759 void LayoutBox::computePositionedLogicalHeightReplaced(LogicalExtentComputedValu es& computedValues) const | |
| 3760 { | |
| 3761 // The following is based off of the W3C Working Draft from April 11, 2006 o f | |
| 3762 // CSS 2.1: Section 10.6.5 "Absolutely positioned, replaced elements" | |
| 3763 // <http://www.w3.org/TR/2005/WD-CSS21-20050613/visudet.html#abs-replaced-he ight> | |
| 3764 // (block-style-comments in this function correspond to text from the spec a nd | |
| 3765 // the numbers correspond to numbers in spec) | |
| 3766 | |
| 3767 // We don't use containingBlock(), since we may be positioned by an enclosin g relpositioned inline. | |
| 3768 const LayoutBoxModelObject* containerBlock = toLayoutBoxModelObject(containe r()); | |
| 3769 | |
| 3770 const LayoutUnit containerLogicalHeight = containingBlockLogicalHeightForPos itioned(containerBlock); | |
| 3771 const LayoutUnit containerRelativeLogicalWidth = containingBlockLogicalWidth ForPositioned(containerBlock, false); | |
| 3772 | |
| 3773 // Variables to solve. | |
| 3774 Length marginBefore = style()->marginBefore(); | |
| 3775 Length marginAfter = style()->marginAfter(); | |
| 3776 LayoutUnit& marginBeforeAlias = computedValues.m_margins.m_before; | |
| 3777 LayoutUnit& marginAfterAlias = computedValues.m_margins.m_after; | |
| 3778 | |
| 3779 Length logicalTop = style()->logicalTop(); | |
| 3780 Length logicalBottom = style()->logicalBottom(); | |
| 3781 | |
| 3782 /*-----------------------------------------------------------------------*\ | |
| 3783 * 1. The used value of 'height' is determined as for inline replaced | |
| 3784 * elements. | |
| 3785 \*-----------------------------------------------------------------------*/ | |
| 3786 // NOTE: This value of height is final in that the min/max height calculatio ns | |
| 3787 // are dealt with in computeReplacedHeight(). This means that the steps to produce | |
| 3788 // correct max/min in the non-replaced version, are not necessary. | |
| 3789 computedValues.m_extent = computeReplacedLogicalHeight() + borderAndPaddingL ogicalHeight(); | |
| 3790 const LayoutUnit availableSpace = containerLogicalHeight - computedValues.m_ extent; | |
| 3791 | |
| 3792 /*-----------------------------------------------------------------------*\ | |
| 3793 * 2. If both 'top' and 'bottom' have the value 'auto', replace 'top' | |
| 3794 * with the element's static position. | |
| 3795 \*-----------------------------------------------------------------------*/ | |
| 3796 // see FIXME 1 | |
| 3797 computeBlockStaticDistance(logicalTop, logicalBottom, this, containerBlock); | |
| 3798 | |
| 3799 /*-----------------------------------------------------------------------*\ | |
| 3800 * 3. If 'bottom' is 'auto', replace any 'auto' on 'margin-top' or | |
| 3801 * 'margin-bottom' with '0'. | |
| 3802 \*-----------------------------------------------------------------------*/ | |
| 3803 // FIXME: The spec. says that this step should only be taken when bottom is | |
| 3804 // auto, but if only top is auto, this makes step 4 impossible. | |
| 3805 if (logicalTop.isAuto() || logicalBottom.isAuto()) { | |
| 3806 if (marginBefore.isAuto()) | |
| 3807 marginBefore.setValue(Fixed, 0); | |
| 3808 if (marginAfter.isAuto()) | |
| 3809 marginAfter.setValue(Fixed, 0); | |
| 3810 } | |
| 3811 | |
| 3812 /*-----------------------------------------------------------------------*\ | |
| 3813 * 4. If at this point both 'margin-top' and 'margin-bottom' are still | |
| 3814 * 'auto', solve the equation under the extra constraint that the two | |
| 3815 * margins must get equal values. | |
| 3816 \*-----------------------------------------------------------------------*/ | |
| 3817 LayoutUnit logicalTopValue = 0; | |
| 3818 LayoutUnit logicalBottomValue = 0; | |
| 3819 | |
| 3820 if (marginBefore.isAuto() && marginAfter.isAuto()) { | |
| 3821 // 'top' and 'bottom' cannot be 'auto' due to step 2 and 3 combined. | |
| 3822 ASSERT(!(logicalTop.isAuto() || logicalBottom.isAuto())); | |
| 3823 | |
| 3824 logicalTopValue = valueForLength(logicalTop, containerLogicalHeight); | |
| 3825 logicalBottomValue = valueForLength(logicalBottom, containerLogicalHeigh t); | |
| 3826 | |
| 3827 LayoutUnit difference = availableSpace - (logicalTopValue + logicalBotto mValue); | |
| 3828 // NOTE: This may result in negative values. | |
| 3829 marginBeforeAlias = difference / 2; // split the difference | |
| 3830 marginAfterAlias = difference - marginBeforeAlias; // account for odd va lued differences | |
| 3831 | |
| 3832 /*-----------------------------------------------------------------------*\ | |
| 3833 * 5. If at this point there is only one 'auto' left, solve the equation | |
| 3834 * for that value. | |
| 3835 \*-----------------------------------------------------------------------*/ | |
| 3836 } else if (logicalTop.isAuto()) { | |
| 3837 marginBeforeAlias = valueForLength(marginBefore, containerRelativeLogica lWidth); | |
| 3838 marginAfterAlias = valueForLength(marginAfter, containerRelativeLogicalW idth); | |
| 3839 logicalBottomValue = valueForLength(logicalBottom, containerLogicalHeigh t); | |
| 3840 | |
| 3841 // Solve for 'top' | |
| 3842 logicalTopValue = availableSpace - (logicalBottomValue + marginBeforeAli as + marginAfterAlias); | |
| 3843 } else if (logicalBottom.isAuto()) { | |
| 3844 marginBeforeAlias = valueForLength(marginBefore, containerRelativeLogica lWidth); | |
| 3845 marginAfterAlias = valueForLength(marginAfter, containerRelativeLogicalW idth); | |
| 3846 logicalTopValue = valueForLength(logicalTop, containerLogicalHeight); | |
| 3847 | |
| 3848 // Solve for 'bottom' | |
| 3849 // NOTE: It is not necessary to solve for 'bottom' because we don't ever | |
| 3850 // use the value. | |
| 3851 } else if (marginBefore.isAuto()) { | |
| 3852 marginAfterAlias = valueForLength(marginAfter, containerRelativeLogicalW idth); | |
| 3853 logicalTopValue = valueForLength(logicalTop, containerLogicalHeight); | |
| 3854 logicalBottomValue = valueForLength(logicalBottom, containerLogicalHeigh t); | |
| 3855 | |
| 3856 // Solve for 'margin-top' | |
| 3857 marginBeforeAlias = availableSpace - (logicalTopValue + logicalBottomVal ue + marginAfterAlias); | |
| 3858 } else if (marginAfter.isAuto()) { | |
| 3859 marginBeforeAlias = valueForLength(marginBefore, containerRelativeLogica lWidth); | |
| 3860 logicalTopValue = valueForLength(logicalTop, containerLogicalHeight); | |
| 3861 logicalBottomValue = valueForLength(logicalBottom, containerLogicalHeigh t); | |
| 3862 | |
| 3863 // Solve for 'margin-bottom' | |
| 3864 marginAfterAlias = availableSpace - (logicalTopValue + logicalBottomValu e + marginBeforeAlias); | |
| 3865 } else { | |
| 3866 // Nothing is 'auto', just calculate the values. | |
| 3867 marginBeforeAlias = valueForLength(marginBefore, containerRelativeLogica lWidth); | |
| 3868 marginAfterAlias = valueForLength(marginAfter, containerRelativeLogicalW idth); | |
| 3869 logicalTopValue = valueForLength(logicalTop, containerLogicalHeight); | |
| 3870 // NOTE: It is not necessary to solve for 'bottom' because we don't ever | |
| 3871 // use the value. | |
| 3872 } | |
| 3873 | |
| 3874 /*-----------------------------------------------------------------------*\ | |
| 3875 * 6. If at this point the values are over-constrained, ignore the value | |
| 3876 * for 'bottom' and solve for that value. | |
| 3877 \*-----------------------------------------------------------------------*/ | |
| 3878 // NOTE: It is not necessary to do this step because we don't end up using | |
| 3879 // the value of 'bottom' regardless of whether the values are over-constrain ed | |
| 3880 // or not. | |
| 3881 | |
| 3882 // Use computed values to calculate the vertical position. | |
| 3883 LayoutUnit logicalTopPos = logicalTopValue + marginBeforeAlias; | |
| 3884 computeLogicalTopPositionedOffset(logicalTopPos, this, computedValues.m_exte nt, containerBlock, containerLogicalHeight); | |
| 3885 computedValues.m_position = logicalTopPos; | |
| 3886 } | |
| 3887 | |
| 3888 LayoutRect LayoutBox::localCaretRect(InlineBox* box, int caretOffset, LayoutUnit * extraWidthToEndOfLine) | 3580 LayoutRect LayoutBox::localCaretRect(InlineBox* box, int caretOffset, LayoutUnit * extraWidthToEndOfLine) |
| 3889 { | 3581 { |
| 3890 // VisiblePositions at offsets inside containers either a) refer to the posi tions before/after | 3582 // VisiblePositions at offsets inside containers either a) refer to the posi tions before/after |
| 3891 // those containers (tables and select elements) or b) refer to the position inside an empty block. | 3583 // those containers (tables and select elements) or b) refer to the position inside an empty block. |
| 3892 // They never refer to children. | 3584 // They never refer to children. |
| 3893 // FIXME: Paint the carets inside empty blocks differently than the carets b efore/after elements. | 3585 // FIXME: Paint the carets inside empty blocks differently than the carets b efore/after elements. |
| 3894 | 3586 |
| 3895 LayoutRect rect(location(), LayoutSize(caretWidth(), size().height())); | 3587 LayoutRect rect(location(), LayoutSize(caretWidth(), size().height())); |
| 3896 bool ltr = box ? box->isLeftToRightDirection() : style()->isLeftToRightDirec tion(); | 3588 bool ltr = box ? box->isLeftToRightDirection() : style()->isLeftToRightDirec tion(); |
| 3897 | 3589 |
| (...skipping 996 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4894 } | 4586 } |
| 4895 | 4587 |
| 4896 void LayoutBox::clearPreviousPaintInvalidationRects() | 4588 void LayoutBox::clearPreviousPaintInvalidationRects() |
| 4897 { | 4589 { |
| 4898 LayoutBoxModelObject::clearPreviousPaintInvalidationRects(); | 4590 LayoutBoxModelObject::clearPreviousPaintInvalidationRects(); |
| 4899 if (PaintLayerScrollableArea* scrollableArea = this->scrollableArea()) | 4591 if (PaintLayerScrollableArea* scrollableArea = this->scrollableArea()) |
| 4900 scrollableArea->clearPreviousPaintInvalidationRects(); | 4592 scrollableArea->clearPreviousPaintInvalidationRects(); |
| 4901 } | 4593 } |
| 4902 | 4594 |
| 4903 } // namespace blink | 4595 } // namespace blink |
| OLD | NEW |