OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2003, 2006, 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2003, 2006, 2008 Apple Inc. All rights reserved. |
3 * | 3 * |
4 * This library is free software; you can redistribute it and/or | 4 * This library is free software; you can redistribute it and/or |
5 * modify it under the terms of the GNU Library General Public | 5 * modify it under the terms of the GNU Library General Public |
6 * License as published by the Free Software Foundation; either | 6 * License as published by the Free Software Foundation; either |
7 * version 2 of the License, or (at your option) any later version. | 7 * version 2 of the License, or (at your option) any later version. |
8 * | 8 * |
9 * This library is distributed in the hope that it will be useful, | 9 * This library is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
589 } else { | 589 } else { |
590 ascent = std::max(ascent, newAscent); | 590 ascent = std::max(ascent, newAscent); |
591 descent = std::max(descent, newDescent); | 591 descent = std::max(descent, newDescent); |
592 } | 592 } |
593 } | 593 } |
594 | 594 |
595 void RootInlineBox::ascentAndDescentForBox(InlineBox* box, GlyphOverflowAndFallb
ackFontsMap& textBoxDataMap, int& ascent, int& descent, bool& affectsAscent, boo
l& affectsDescent) const | 595 void RootInlineBox::ascentAndDescentForBox(InlineBox* box, GlyphOverflowAndFallb
ackFontsMap& textBoxDataMap, int& ascent, int& descent, bool& affectsAscent, boo
l& affectsDescent) const |
596 { | 596 { |
597 bool ascentDescentSet = false; | 597 bool ascentDescentSet = false; |
598 | 598 |
599 // Replaced boxes will return 0 for the line-height if line-box-contain says
they are | |
600 // not to be included. | |
601 if (box->layoutObject().isReplaced()) { | 599 if (box->layoutObject().isReplaced()) { |
602 if (layoutObject().style(isFirstLineStyle())->lineBoxContain() & LineBox
ContainReplaced) { | 600 ascent = box->baselinePosition(baselineType()); |
603 ascent = box->baselinePosition(baselineType()); | 601 descent = box->lineHeight() - ascent; |
604 descent = box->lineHeight() - ascent; | |
605 | 602 |
606 // Replaced elements always affect both the ascent and descent. | 603 // Replaced elements always affect both the ascent and descent. |
607 affectsAscent = true; | 604 affectsAscent = true; |
608 affectsDescent = true; | 605 affectsDescent = true; |
609 } | |
610 return; | 606 return; |
611 } | 607 } |
612 | 608 |
613 Vector<const SimpleFontData*>* usedFonts = nullptr; | 609 Vector<const SimpleFontData*>* usedFonts = nullptr; |
614 GlyphOverflow* glyphOverflow = nullptr; | |
615 if (box->isText()) { | 610 if (box->isText()) { |
616 GlyphOverflowAndFallbackFontsMap::iterator it = textBoxDataMap.find(toIn
lineTextBox(box)); | 611 GlyphOverflowAndFallbackFontsMap::iterator it = textBoxDataMap.find(toIn
lineTextBox(box)); |
617 usedFonts = it == textBoxDataMap.end() ? 0 : &it->value.first; | 612 usedFonts = it == textBoxDataMap.end() ? 0 : &it->value.first; |
618 glyphOverflow = it == textBoxDataMap.end() ? 0 : &it->value.second; | |
619 } | 613 } |
620 | 614 |
621 bool includeLeading = includeLeadingForBox(box); | 615 bool includeLeading = includeLeadingForBox(box); |
622 bool includeFont = includeFontForBox(box); | |
623 | |
624 bool setUsedFont = false; | |
625 bool setUsedFontWithLeading = false; | 616 bool setUsedFontWithLeading = false; |
626 | 617 |
627 if (usedFonts && !usedFonts->isEmpty() && (includeFont || (box->lineLayoutIt
em().style(isFirstLineStyle())->lineHeight().isNegative() && includeLeading))) { | 618 if (usedFonts && !usedFonts->isEmpty() && (box->lineLayoutItem().style(isFir
stLineStyle())->lineHeight().isNegative() && includeLeading)) { |
628 usedFonts->append(box->lineLayoutItem().style(isFirstLineStyle())->font(
).primaryFont()); | 619 usedFonts->append(box->lineLayoutItem().style(isFirstLineStyle())->font(
).primaryFont()); |
629 for (size_t i = 0; i < usedFonts->size(); ++i) { | 620 for (size_t i = 0; i < usedFonts->size(); ++i) { |
630 const FontMetrics& fontMetrics = usedFonts->at(i)->fontMetrics(); | 621 const FontMetrics& fontMetrics = usedFonts->at(i)->fontMetrics(); |
631 int usedFontAscent = fontMetrics.ascent(baselineType()); | 622 int usedFontAscent = fontMetrics.ascent(baselineType()); |
632 int usedFontDescent = fontMetrics.descent(baselineType()); | 623 int usedFontDescent = fontMetrics.descent(baselineType()); |
633 int halfLeading = (fontMetrics.lineSpacing() - fontMetrics.height())
/ 2; | 624 int halfLeading = (fontMetrics.lineSpacing() - fontMetrics.height())
/ 2; |
634 int usedFontAscentAndLeading = usedFontAscent + halfLeading; | 625 int usedFontAscentAndLeading = usedFontAscent + halfLeading; |
635 int usedFontDescentAndLeading = fontMetrics.lineSpacing() - usedFont
AscentAndLeading; | 626 int usedFontDescentAndLeading = fontMetrics.lineSpacing() - usedFont
AscentAndLeading; |
636 if (includeFont) { | |
637 setAscentAndDescent(ascent, descent, usedFontAscent, usedFontDes
cent, ascentDescentSet); | |
638 setUsedFont = true; | |
639 } | |
640 if (includeLeading) { | 627 if (includeLeading) { |
641 setAscentAndDescent(ascent, descent, usedFontAscentAndLeading, u
sedFontDescentAndLeading, ascentDescentSet); | 628 setAscentAndDescent(ascent, descent, usedFontAscentAndLeading, u
sedFontDescentAndLeading, ascentDescentSet); |
642 setUsedFontWithLeading = true; | 629 setUsedFontWithLeading = true; |
643 } | 630 } |
644 if (!affectsAscent) | 631 if (!affectsAscent) |
645 affectsAscent = usedFontAscent - box->logicalTop() > 0; | 632 affectsAscent = usedFontAscent - box->logicalTop() > 0; |
646 if (!affectsDescent) | 633 if (!affectsDescent) |
647 affectsDescent = usedFontDescent + box->logicalTop() > 0; | 634 affectsDescent = usedFontDescent + box->logicalTop() > 0; |
648 } | 635 } |
649 } | 636 } |
650 | 637 |
651 // If leading is included for the box, then we compute that box. | 638 // If leading is included for the box, then we compute that box. |
652 if (includeLeading && !setUsedFontWithLeading) { | 639 if (includeLeading && !setUsedFontWithLeading) { |
653 int ascentWithLeading = box->baselinePosition(baselineType()); | 640 int ascentWithLeading = box->baselinePosition(baselineType()); |
654 int descentWithLeading = box->lineHeight() - ascentWithLeading; | 641 int descentWithLeading = box->lineHeight() - ascentWithLeading; |
655 setAscentAndDescent(ascent, descent, ascentWithLeading, descentWithLeadi
ng, ascentDescentSet); | 642 setAscentAndDescent(ascent, descent, ascentWithLeading, descentWithLeadi
ng, ascentDescentSet); |
656 | 643 |
657 // Examine the font box for inline flows and text boxes to see if any pa
rt of it is above the baseline. | 644 // Examine the font box for inline flows and text boxes to see if any pa
rt of it is above the baseline. |
658 // If the top of our font box relative to the root box baseline is above
the root box baseline, then | 645 // If the top of our font box relative to the root box baseline is above
the root box baseline, then |
659 // we are contributing to the maxAscent value. Descent is similar. If an
y part of our font box is below | 646 // we are contributing to the maxAscent value. Descent is similar. If an
y part of our font box is below |
660 // the root box's baseline, then we contribute to the maxDescent value. | 647 // the root box's baseline, then we contribute to the maxDescent value. |
661 affectsAscent = ascentWithLeading - box->logicalTop() > 0; | 648 affectsAscent = ascentWithLeading - box->logicalTop() > 0; |
662 affectsDescent = descentWithLeading + box->logicalTop() > 0; | 649 affectsDescent = descentWithLeading + box->logicalTop() > 0; |
663 } | 650 } |
664 | |
665 if (includeFontForBox(box) && !setUsedFont) { | |
666 int fontAscent = box->lineLayoutItem().style(isFirstLineStyle())->fontMe
trics().ascent(baselineType()); | |
667 int fontDescent = box->lineLayoutItem().style(isFirstLineStyle())->fontM
etrics().descent(baselineType()); | |
668 setAscentAndDescent(ascent, descent, fontAscent, fontDescent, ascentDesc
entSet); | |
669 affectsAscent = fontAscent - box->logicalTop() > 0; | |
670 affectsDescent = fontDescent + box->logicalTop() > 0; | |
671 } | |
672 | |
673 if (includeGlyphsForBox(box) && glyphOverflow && glyphOverflow->computeBound
s) { | |
674 setAscentAndDescent(ascent, descent, glyphOverflow->top, glyphOverflow->
bottom, ascentDescentSet); | |
675 affectsAscent = glyphOverflow->top - box->logicalTop() > 0; | |
676 affectsDescent = glyphOverflow->bottom + box->logicalTop() > 0; | |
677 } | |
678 | |
679 if (includeMarginForBox(box)) { | |
680 LayoutUnit ascentWithMargin = box->lineLayoutItem().style(isFirstLineSty
le())->fontMetrics().ascent(baselineType()); | |
681 LayoutUnit descentWithMargin = box->lineLayoutItem().style(isFirstLineSt
yle())->fontMetrics().descent(baselineType()); | |
682 if (box->parent() && !box->lineLayoutItem().isText()) { | |
683 ascentWithMargin += box->boxModelObject().borderBefore() + box->boxM
odelObject().paddingBefore() + box->boxModelObject().marginBefore(); | |
684 descentWithMargin += box->boxModelObject().borderAfter() + box->boxM
odelObject().paddingAfter() + box->boxModelObject().marginAfter(); | |
685 } | |
686 setAscentAndDescent(ascent, descent, ascentWithMargin, descentWithMargin
, ascentDescentSet); | |
687 | |
688 // Treat like a replaced element, since we're using the margin box. | |
689 affectsAscent = true; | |
690 affectsDescent = true; | |
691 } | |
692 } | 651 } |
693 | 652 |
694 LayoutUnit RootInlineBox::verticalPositionForBox(InlineBox* box, VerticalPositio
nCache& verticalPositionCache) | 653 LayoutUnit RootInlineBox::verticalPositionForBox(InlineBox* box, VerticalPositio
nCache& verticalPositionCache) |
695 { | 654 { |
696 if (box->lineLayoutItem().isText()) | 655 if (box->lineLayoutItem().isText()) |
697 return box->parent()->logicalTop(); | 656 return box->parent()->logicalTop(); |
698 | 657 |
699 LineLayoutBoxModel boxModel = box->boxModelObject(); | 658 LineLayoutBoxModel boxModel = box->boxModelObject(); |
700 ASSERT(boxModel.isInline()); | 659 ASSERT(boxModel.isInline()); |
701 if (!boxModel.isInline()) | 660 if (!boxModel.isInline()) |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
758 | 717 |
759 // Store the cached value. | 718 // Store the cached value. |
760 if (isLayoutInline && !firstLine) | 719 if (isLayoutInline && !firstLine) |
761 verticalPositionCache.set(boxModel, baselineType(), verticalPosition); | 720 verticalPositionCache.set(boxModel, baselineType(), verticalPosition); |
762 | 721 |
763 return verticalPosition; | 722 return verticalPosition; |
764 } | 723 } |
765 | 724 |
766 bool RootInlineBox::includeLeadingForBox(InlineBox* box) const | 725 bool RootInlineBox::includeLeadingForBox(InlineBox* box) const |
767 { | 726 { |
768 if (box->lineLayoutItem().isReplaced() || (box->lineLayoutItem().isText() &&
!box->isText())) | 727 return !(box->lineLayoutItem().isReplaced() || (box->lineLayoutItem().isText
() && !box->isText())); |
769 return false; | |
770 | |
771 LineBoxContain lineBoxContain = lineLayoutItem().style()->lineBoxContain(); | |
772 return (lineBoxContain & LineBoxContainInline) || (box == this && (lineBoxCo
ntain & LineBoxContainBlock)); | |
773 } | |
774 | |
775 bool RootInlineBox::includeFontForBox(InlineBox* box) const | |
776 { | |
777 if (box->lineLayoutItem().isReplaced() || (box->lineLayoutItem().isText() &&
!box->isText())) | |
778 return false; | |
779 | |
780 if (!box->isText() && box->isInlineFlowBox() && !toInlineFlowBox(box)->hasTe
xtChildren()) | |
781 return false; | |
782 | |
783 // For now map "glyphs" to "font" in vertical text mode until the bounds ret
urned by glyphs aren't garbage. | |
784 LineBoxContain lineBoxContain = lineLayoutItem().style()->lineBoxContain(); | |
785 return (lineBoxContain & LineBoxContainFont) || (!isHorizontal() && (lineBox
Contain & LineBoxContainGlyphs)); | |
786 } | |
787 | |
788 bool RootInlineBox::includeGlyphsForBox(InlineBox* box) const | |
789 { | |
790 if (box->lineLayoutItem().isReplaced() || (box->lineLayoutItem().isText() &&
!box->isText())) | |
791 return false; | |
792 | |
793 if (!box->isText() && box->isInlineFlowBox() && !toInlineFlowBox(box)->hasTe
xtChildren()) | |
794 return false; | |
795 | |
796 // FIXME: We can't fit to glyphs yet for vertical text, since the bounds ret
urned are garbage. | |
797 LineBoxContain lineBoxContain = lineLayoutItem().style()->lineBoxContain(); | |
798 return isHorizontal() && (lineBoxContain & LineBoxContainGlyphs); | |
799 } | |
800 | |
801 bool RootInlineBox::includeMarginForBox(InlineBox* box) const | |
802 { | |
803 if (box->lineLayoutItem().isReplaced() || (box->lineLayoutItem().isText() &&
!box->isText())) | |
804 return false; | |
805 | |
806 LineBoxContain lineBoxContain = lineLayoutItem().style()->lineBoxContain(); | |
807 return lineBoxContain & LineBoxContainInlineBox; | |
808 } | |
809 | |
810 | |
811 bool RootInlineBox::fitsToGlyphs() const | |
812 { | |
813 // FIXME: We can't fit to glyphs yet for vertical text, since the bounds ret
urned are garbage. | |
814 LineBoxContain lineBoxContain = lineLayoutItem().style()->lineBoxContain(); | |
815 return isHorizontal() && (lineBoxContain & LineBoxContainGlyphs); | |
816 } | 728 } |
817 | 729 |
818 Node* RootInlineBox::getLogicalStartBoxWithNode(InlineBox*& startBox) const | 730 Node* RootInlineBox::getLogicalStartBoxWithNode(InlineBox*& startBox) const |
819 { | 731 { |
820 Vector<InlineBox*> leafBoxesInLogicalOrder; | 732 Vector<InlineBox*> leafBoxesInLogicalOrder; |
821 collectLeafBoxesInLogicalOrder(leafBoxesInLogicalOrder); | 733 collectLeafBoxesInLogicalOrder(leafBoxesInLogicalOrder); |
822 for (size_t i = 0; i < leafBoxesInLogicalOrder.size(); ++i) { | 734 for (size_t i = 0; i < leafBoxesInLogicalOrder.size(); ++i) { |
823 if (leafBoxesInLogicalOrder[i]->lineLayoutItem().nonPseudoNode()) { | 735 if (leafBoxesInLogicalOrder[i]->lineLayoutItem().nonPseudoNode()) { |
824 startBox = leafBoxesInLogicalOrder[i]; | 736 startBox = leafBoxesInLogicalOrder[i]; |
825 return startBox->lineLayoutItem().nonPseudoNode(); | 737 return startBox->lineLayoutItem().nonPseudoNode(); |
(...skipping 16 matching lines...) Expand all Loading... |
842 endBox = nullptr; | 754 endBox = nullptr; |
843 return nullptr; | 755 return nullptr; |
844 } | 756 } |
845 | 757 |
846 const char* RootInlineBox::boxName() const | 758 const char* RootInlineBox::boxName() const |
847 { | 759 { |
848 return "RootInlineBox"; | 760 return "RootInlineBox"; |
849 } | 761 } |
850 | 762 |
851 } // namespace blink | 763 } // namespace blink |
OLD | NEW |