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 |