Changeset 156608 in webkit
- Timestamp:
- Sep 28, 2013 11:30:16 AM (11 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 23 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r156607 r156608 1 2013-09-27 Antti Koivisto <antti@apple.com> 2 3 Clean up code for getting first line style 4 https://bugs.webkit.org/show_bug.cgi?id=122037 5 6 Reviewed by Andreas Kling. 7 8 We have confusing RenderObject::style(bool firstLine). Get rid of it in favour of 9 just using RenderObject::firstLineStyle() where appropriate. 10 11 Also switch to RenderStyle references in many places and move first line style caching 12 code down to RenderElement. 13 1 14 2013-09-28 Darin Adler <darin@apple.com> 2 15 -
trunk/Source/WebCore/rendering/EllipsisBox.cpp
r156095 r156608 45 45 { 46 46 GraphicsContext* context = paintInfo.context; 47 RenderStyle * style = renderer().style(isFirstLineStyle());48 Color textColor = style->visitedDependentColor(CSSPropertyWebkitTextFillColor);47 RenderStyle& lineStyle = this->lineStyle(); 48 Color textColor = lineStyle.visitedDependentColor(CSSPropertyWebkitTextFillColor); 49 49 if (textColor != context->fillColor()) 50 context->setFillColor(textColor, style->colorSpace());50 context->setFillColor(textColor, lineStyle.colorSpace()); 51 51 bool setShadow = false; 52 if ( style->textShadow()) {53 context->setShadow(LayoutSize( style->textShadow()->x(), style->textShadow()->y()),54 style->textShadow()->radius(), style->textShadow()->color(), style->colorSpace());52 if (lineStyle.textShadow()) { 53 context->setShadow(LayoutSize(lineStyle.textShadow()->x(), lineStyle.textShadow()->y()), 54 lineStyle.textShadow()->radius(), lineStyle.textShadow()->color(), lineStyle.colorSpace()); 55 55 setShadow = true; 56 56 } 57 57 58 const Font& font = style->font();58 const Font& font = lineStyle.font(); 59 59 if (selectionState() != RenderObject::SelectionNone) { 60 paintSelection(context, paintOffset, style, font);60 paintSelection(context, paintOffset, &lineStyle, font); 61 61 62 62 // Select the correct color for painting the text. 63 63 Color foreground = paintInfo.forceBlackText() ? Color::black : renderer().selectionForegroundColor(); 64 64 if (foreground.isValid() && foreground != textColor) 65 context->setFillColor(foreground, style->colorSpace());65 context->setFillColor(foreground, lineStyle.colorSpace()); 66 66 } 67 67 68 68 // FIXME: Why is this always LTR? Fix by passing correct text run flags below. 69 context->drawText(font, RenderBlock::constructTextRun(&renderer(), font, m_str, style, TextRun::AllowTrailingExpansion), LayoutPoint(x() + paintOffset.x(), y() + paintOffset.y() + style->fontMetrics().ascent()));69 context->drawText(font, RenderBlock::constructTextRun(&renderer(), font, m_str, &lineStyle, TextRun::AllowTrailingExpansion), LayoutPoint(x() + paintOffset.x(), y() + paintOffset.y() + lineStyle.fontMetrics().ascent())); 70 70 71 71 // Restore the regular fill color. 72 72 if (textColor != context->fillColor()) 73 context->setFillColor(textColor, style->colorSpace());73 context->setFillColor(textColor, lineStyle.colorSpace()); 74 74 75 75 if (setShadow) 76 76 context->clearShadow(); 77 77 78 paintMarkupBox(paintInfo, paintOffset, lineTop, lineBottom, style);78 paintMarkupBox(paintInfo, paintOffset, lineTop, lineBottom, &lineStyle); 79 79 } 80 80 … … 105 105 LayoutPoint adjustedPaintOffset = paintOffset; 106 106 adjustedPaintOffset.move(x() + m_logicalWidth - markupBox->x(), 107 y() + style->fontMetrics().ascent() - (markupBox->y() + markupBox-> renderer().style(isFirstLineStyle())->fontMetrics().ascent()));107 y() + style->fontMetrics().ascent() - (markupBox->y() + markupBox->lineStyle().fontMetrics().ascent())); 108 108 markupBox->paint(paintInfo, adjustedPaintOffset, lineTop, lineBottom); 109 109 } … … 111 111 IntRect EllipsisBox::selectionRect() 112 112 { 113 RenderStyle * style = renderer().style(isFirstLineStyle());114 const Font& font = style->font();113 RenderStyle& lineStyle = this->lineStyle(); 114 const Font& font = lineStyle.font(); 115 115 const RootInlineBox& rootBox = root(); 116 116 // FIXME: Why is this always LTR? Fix by passing correct text run flags below. 117 return enclosingIntRect(font.selectionRectForText(RenderBlock::constructTextRun(&renderer(), font, m_str, style, TextRun::AllowTrailingExpansion), IntPoint(x(), y() + rootBox.selectionTopAdjustedForPrecedingBlock()), rootBox.selectionHeightAdjustedForPrecedingBlock()));117 return enclosingIntRect(font.selectionRectForText(RenderBlock::constructTextRun(&renderer(), font, m_str, &lineStyle, TextRun::AllowTrailingExpansion), IntPoint(x(), y() + rootBox.selectionTopAdjustedForPrecedingBlock()), rootBox.selectionHeightAdjustedForPrecedingBlock())); 118 118 } 119 119 … … 148 148 // Hit test the markup box. 149 149 if (InlineBox* markupBox = this->markupBox()) { 150 RenderStyle * style = renderer().style(isFirstLineStyle());150 RenderStyle& lineStyle = this->lineStyle(); 151 151 LayoutUnit mtx = adjustedLocation.x() + m_logicalWidth - markupBox->x(); 152 LayoutUnit mty = adjustedLocation.y() + style->fontMetrics().ascent() - (markupBox->y() + markupBox->renderer().style(isFirstLineStyle())->fontMetrics().ascent());152 LayoutUnit mty = adjustedLocation.y() + lineStyle.fontMetrics().ascent() - (markupBox->y() + markupBox->lineStyle().fontMetrics().ascent()); 153 153 if (markupBox->nodeAtPoint(request, result, locationInContainer, LayoutPoint(mtx, mty), lineTop, lineBottom)) { 154 154 renderer().updateHitTestResult(result, locationInContainer.point() - LayoutSize(mtx, mty)); -
trunk/Source/WebCore/rendering/InlineBox.cpp
r156054 r156608 141 141 if (hasVirtualLogicalHeight()) 142 142 return virtualLogicalHeight(); 143 143 144 const RenderStyle& lineStyle = this->lineStyle(); 144 145 if (renderer().isTextOrLineBreak()) 145 return behavesLikeText() ? renderer().style(isFirstLineStyle())->fontMetrics().height() : 0;146 return behavesLikeText() ? lineStyle.fontMetrics().height() : 0; 146 147 if (renderer().isBox() && parent()) 147 148 return isHorizontal() ? toRenderBox(renderer()).height() : toRenderBox(renderer()).width(); … … 149 150 ASSERT(isInlineFlowBox()); 150 151 RenderBoxModelObject* flowObject = boxModelObject(); 151 const FontMetrics& fontMetrics = renderer().style(isFirstLineStyle())->fontMetrics();152 const FontMetrics& fontMetrics = lineStyle.fontMetrics(); 152 153 float result = fontMetrics.height(); 153 154 if (parent()) -
trunk/Source/WebCore/rendering/InlineBox.h
r156038 r156608 152 152 void setExtracted(bool extracted = true) { m_bitfields.setExtracted(extracted); } 153 153 154 void set FirstLineStyleBit(bool firstLine) { m_bitfields.setFirstLine(firstLine); }155 bool isFirstLine Style() const { return m_bitfields.firstLine(); }154 void setIsFirstLine(bool firstLine) { m_bitfields.setFirstLine(firstLine); } 155 bool isFirstLine() const { return m_bitfields.firstLine(); } 156 156 157 157 void remove(); … … 280 280 281 281 bool visibleToHitTesting() const { return renderer().style()->visibility() == VISIBLE && renderer().style()->pointerEvents() != PE_NONE; } 282 283 EVerticalAlign verticalAlign() const { return renderer().style(m_bitfields.firstLine())->verticalAlign(); } 282 283 RenderStyle& lineStyle() const { return m_bitfields.firstLine() ? *renderer().firstLineStyle() : *renderer().style(); } 284 285 EVerticalAlign verticalAlign() const { return lineStyle().verticalAlign(); } 284 286 285 287 // Use with caution! The type is not checked! -
trunk/Source/WebCore/rendering/InlineFlowBox.cpp
r156285 r156608 110 110 m_lastChild = child; 111 111 } 112 child->set FirstLineStyleBit(isFirstLineStyle());112 child->setIsFirstLine(isFirstLine()); 113 113 child->setIsHorizontal(isHorizontal()); 114 114 if (child->behavesLikeText()) { … … 122 122 123 123 if (descendantsHaveSameLineHeightAndBaseline() && !child->renderer().isOutOfFlowPositioned()) { 124 RenderStyle* parentStyle = renderer().style(isFirstLineStyle());125 RenderStyle* childStyle = child->renderer().style(isFirstLineStyle());124 const RenderStyle& parentStyle = lineStyle(); 125 const RenderStyle& childStyle = child->lineStyle(); 126 126 bool shouldClearDescendantsHaveSameLineHeightAndBaseline = false; 127 127 if (child->renderer().isReplaced()) … … 129 129 else if (child->behavesLikeText()) { 130 130 if (child->renderer().isLineBreak() || child->renderer().parent() != &renderer()) { 131 if (!parentStyle ->font().fontMetrics().hasIdenticalAscentDescentAndLineGap(childStyle->font().fontMetrics())132 || parentStyle ->lineHeight() != childStyle->lineHeight()133 || (parentStyle ->verticalAlign() != BASELINE && !isRootInlineBox()) || childStyle->verticalAlign() != BASELINE)131 if (!parentStyle.font().fontMetrics().hasIdenticalAscentDescentAndLineGap(childStyle.font().fontMetrics()) 132 || parentStyle.lineHeight() != childStyle.lineHeight() 133 || (parentStyle.verticalAlign() != BASELINE && !isRootInlineBox()) || childStyle.verticalAlign() != BASELINE) 134 134 shouldClearDescendantsHaveSameLineHeightAndBaseline = true; 135 135 } 136 if (childStyle ->hasTextCombine() || childStyle->textEmphasisMark() != TextEmphasisMarkNone)136 if (childStyle.hasTextCombine() || childStyle.textEmphasisMark() != TextEmphasisMarkNone) 137 137 shouldClearDescendantsHaveSameLineHeightAndBaseline = true; 138 138 } else { … … 146 146 // Check the child's bit, and then also check for differences in font, line-height, vertical-align 147 147 if (!childFlowBox->descendantsHaveSameLineHeightAndBaseline() 148 || !parentStyle ->font().fontMetrics().hasIdenticalAscentDescentAndLineGap(childStyle->font().fontMetrics())149 || parentStyle ->lineHeight() != childStyle->lineHeight()150 || (parentStyle ->verticalAlign() != BASELINE && !isRootInlineBox()) || childStyle->verticalAlign() != BASELINE151 || childStyle ->hasBorder() || childStyle->hasPadding() || childStyle->hasTextCombine())148 || !parentStyle.font().fontMetrics().hasIdenticalAscentDescentAndLineGap(childStyle.font().fontMetrics()) 149 || parentStyle.lineHeight() != childStyle.lineHeight() 150 || (parentStyle.verticalAlign() != BASELINE && !isRootInlineBox()) || childStyle.verticalAlign() != BASELINE 151 || childStyle.hasBorder() || childStyle.hasPadding() || childStyle.hasTextCombine()) 152 152 shouldClearDescendantsHaveSameLineHeightAndBaseline = true; 153 153 } … … 159 159 160 160 if (!child->renderer().isOutOfFlowPositioned()) { 161 const RenderStyle& childStyle = child->lineStyle(); 161 162 if (child->behavesLikeText()) { 162 RenderStyle* childStyle = child->renderer().style(isFirstLineStyle());163 RenderStyle* childStyle = &child->lineStyle(); 163 164 if (childStyle->letterSpacing() < 0 || childStyle->textShadow() || childStyle->textEmphasisMark() != TextEmphasisMarkNone || childStyle->textStrokeWidth()) 164 165 child->clearKnownToHaveNoOverflow(); … … 167 168 if (box.hasRenderOverflow() || box.hasSelfPaintingLayer()) 168 169 child->clearKnownToHaveNoOverflow(); 169 } else if (!child->renderer().isLineBreak() && (child ->renderer().style(isFirstLineStyle())->boxShadow() || child->boxModelObject()->hasSelfPaintingLayer()170 171 || child->renderer().style(isFirstLineStyle())->hasBorderImageOutsets()))170 } else if (!child->renderer().isLineBreak() && (childStyle.boxShadow() || child->boxModelObject()->hasSelfPaintingLayer() 171 || (child->renderer().isListMarker() && !toRenderListMarker(child->renderer()).isInside()) 172 || childStyle.hasBorderImageOutsets())) 172 173 child->clearKnownToHaveNoOverflow(); 173 174 … … 392 393 if (rt.textLength()) { 393 394 if (needsWordSpacing && isSpaceOrNewline(rt.characterAt(text->start()))) 394 logicalLeft += rt.style(isFirstLineStyle())->font().wordSpacing();395 logicalLeft += text->lineStyle().font().wordSpacing(); 395 396 needsWordSpacing = !isSpaceOrNewline(rt.characterAt(text->end())); 396 397 } … … 447 448 if (isHorizontal()) 448 449 return false; 449 450 if (renderer().style(isFirstLineStyle())->fontDescription().nonCJKGlyphOrientation() == NonCJKGlyphOrientationUpright 451 || renderer().style(isFirstLineStyle())->font().primaryFont()->hasVerticalGlyphs()) 450 451 const RenderStyle& lineStyle = this->lineStyle(); 452 if (lineStyle.fontDescription().nonCJKGlyphOrientation() == NonCJKGlyphOrientationUpright 453 || lineStyle.font().primaryFont()->hasVerticalGlyphs()) 452 454 return true; 453 455 … … 460 462 return true; 461 463 } else { 462 if (curr-> renderer().style(isFirstLineStyle())->font().primaryFont()->hasVerticalGlyphs())464 if (curr->lineStyle().font().primaryFont()->hasVerticalGlyphs()) 463 465 return true; 464 466 … … 618 620 bool isRootBox = isRootInlineBox(); 619 621 if (isRootBox) { 620 const FontMetrics& fontMetrics = renderer().style(isFirstLineStyle())->fontMetrics();622 const FontMetrics& fontMetrics = lineStyle().fontMetrics(); 621 623 // RootInlineBoxes are always placed on at pixel boundaries in their logical y direction. Not doing 622 624 // so results in incorrect rendering of text decorations, most notably underlines. … … 659 661 LayoutUnit boxHeight = curr->logicalHeight(); 660 662 LayoutUnit boxHeightIncludingMargins = boxHeight; 661 663 664 RenderStyle& childLineStyle = curr->lineStyle(); 662 665 if (curr->behavesLikeText() || curr->isInlineFlowBox()) { 663 const FontMetrics& fontMetrics = c urr->renderer().style(isFirstLineStyle())->fontMetrics();666 const FontMetrics& fontMetrics = childLineStyle.fontMetrics(); 664 667 newLogicalTop += curr->baselinePosition(baselineType) - fontMetrics.ascent(baselineType); 665 668 if (curr->isInlineFlowBox()) { 666 669 RenderBoxModelObject& boxObject = toRenderBoxModelObject(curr->renderer()); 667 newLogicalTop -= boxObject.style(isFirstLineStyle())->isHorizontalWritingMode()670 newLogicalTop -= childLineStyle.isHorizontalWritingMode() 668 671 ? boxObject.borderTop() + boxObject.paddingTop() 669 672 : boxObject.borderRight() + boxObject.paddingRight(); … … 701 704 if (curr->isInlineTextBox()) { 702 705 TextEmphasisPosition emphasisMarkPosition; 703 if (toInlineTextBox(curr)->getEmphasisMarkPosition( curr->renderer().style(isFirstLineStyle()), emphasisMarkPosition)) {706 if (toInlineTextBox(curr)->getEmphasisMarkPosition(&childLineStyle, emphasisMarkPosition)) { 704 707 bool emphasisMarkIsOver = emphasisMarkPosition == TextEmphasisPositionOver; 705 if (emphasisMarkIsOver != c urr->renderer().style(isFirstLineStyle())->isFlippedLinesWritingMode())708 if (emphasisMarkIsOver != childLineStyle.isFlippedLinesWritingMode()) 706 709 hasAnnotationsBefore = true; 707 710 else … … 789 792 return; 790 793 791 RenderStyle* style = renderer().style(isFirstLineStyle());792 if (! style->boxShadow())794 const RenderStyle& lineStyle = this->lineStyle(); 795 if (!lineStyle.boxShadow()) 793 796 return; 794 797 795 798 LayoutUnit boxShadowLogicalTop; 796 799 LayoutUnit boxShadowLogicalBottom; 797 style->getBoxShadowBlockDirectionExtent(boxShadowLogicalTop, boxShadowLogicalBottom);800 lineStyle.getBoxShadowBlockDirectionExtent(boxShadowLogicalTop, boxShadowLogicalBottom); 798 801 799 802 // Similar to how glyph overflow works, if our lines are flipped, then it's actually the opposite shadow that applies, since 800 803 // the line is "upside down" in terms of block coordinates. 801 LayoutUnit shadowLogicalTop = style->isFlippedLinesWritingMode() ? -boxShadowLogicalBottom : boxShadowLogicalTop;802 LayoutUnit shadowLogicalBottom = style->isFlippedLinesWritingMode() ? -boxShadowLogicalTop : boxShadowLogicalBottom;804 LayoutUnit shadowLogicalTop = lineStyle.isFlippedLinesWritingMode() ? -boxShadowLogicalBottom : boxShadowLogicalTop; 805 LayoutUnit shadowLogicalBottom = lineStyle.isFlippedLinesWritingMode() ? -boxShadowLogicalTop : boxShadowLogicalBottom; 803 806 804 807 LayoutUnit logicalTopVisualOverflow = min(pixelSnappedLogicalTop() + shadowLogicalTop, logicalVisualOverflow.y()); … … 807 810 LayoutUnit boxShadowLogicalLeft; 808 811 LayoutUnit boxShadowLogicalRight; 809 style->getBoxShadowInlineDirectionExtent(boxShadowLogicalLeft, boxShadowLogicalRight);812 lineStyle.getBoxShadowInlineDirectionExtent(boxShadowLogicalLeft, boxShadowLogicalRight); 810 813 811 814 LayoutUnit logicalLeftVisualOverflow = min(pixelSnappedLogicalLeft() + boxShadowLogicalLeft, logicalVisualOverflow.x()); … … 822 825 return; 823 826 824 RenderStyle* style = renderer().style(isFirstLineStyle());825 if (! style->hasBorderImageOutsets())826 return; 827 828 LayoutBoxExtent borderOutsets = style->borderImageOutsets();829 830 LayoutUnit borderOutsetLogicalTop = borderOutsets.logicalTop( style->writingMode());831 LayoutUnit borderOutsetLogicalBottom = borderOutsets.logicalBottom( style->writingMode());832 LayoutUnit borderOutsetLogicalLeft = borderOutsets.logicalLeft( style->writingMode());833 LayoutUnit borderOutsetLogicalRight = borderOutsets.logicalRight( style->writingMode());827 const RenderStyle& lineStyle = this->lineStyle(); 828 if (!lineStyle.hasBorderImageOutsets()) 829 return; 830 831 LayoutBoxExtent borderOutsets = lineStyle.borderImageOutsets(); 832 833 LayoutUnit borderOutsetLogicalTop = borderOutsets.logicalTop(lineStyle.writingMode()); 834 LayoutUnit borderOutsetLogicalBottom = borderOutsets.logicalBottom(lineStyle.writingMode()); 835 LayoutUnit borderOutsetLogicalLeft = borderOutsets.logicalLeft(lineStyle.writingMode()); 836 LayoutUnit borderOutsetLogicalRight = borderOutsets.logicalRight(lineStyle.writingMode()); 834 837 835 838 // Similar to how glyph overflow works, if our lines are flipped, then it's actually the opposite border that applies, since 836 839 // the line is "upside down" in terms of block coordinates. vertical-rl and horizontal-bt are the flipped line modes. 837 LayoutUnit outsetLogicalTop = style->isFlippedLinesWritingMode() ? borderOutsetLogicalBottom : borderOutsetLogicalTop;838 LayoutUnit outsetLogicalBottom = style->isFlippedLinesWritingMode() ? borderOutsetLogicalTop : borderOutsetLogicalBottom;840 LayoutUnit outsetLogicalTop = lineStyle.isFlippedLinesWritingMode() ? borderOutsetLogicalBottom : borderOutsetLogicalTop; 841 LayoutUnit outsetLogicalBottom = lineStyle.isFlippedLinesWritingMode() ? borderOutsetLogicalTop : borderOutsetLogicalBottom; 839 842 840 843 LayoutUnit logicalTopVisualOverflow = min(pixelSnappedLogicalTop() - outsetLogicalTop, logicalVisualOverflow.y()); … … 856 859 return; 857 860 858 RenderStyle * style = textBox->renderer().style(isFirstLineStyle());861 RenderStyle& lineStyle = this->lineStyle(); 859 862 860 863 GlyphOverflowAndFallbackFontsMap::iterator it = textBoxDataMap.find(textBox); 861 864 GlyphOverflow* glyphOverflow = it == textBoxDataMap.end() ? 0 : &it->value.second; 862 bool isFlippedLine = style->isFlippedLinesWritingMode();865 bool isFlippedLine = lineStyle.isFlippedLinesWritingMode(); 863 866 864 867 int topGlyphEdge = glyphOverflow ? (isFlippedLine ? glyphOverflow->bottom : glyphOverflow->top) : 0; … … 867 870 int rightGlyphEdge = glyphOverflow ? glyphOverflow->right : 0; 868 871 869 int strokeOverflow = static_cast<int>(ceilf( style->textStrokeWidth() / 2.0f));872 int strokeOverflow = static_cast<int>(ceilf(lineStyle.textStrokeWidth() / 2.0f)); 870 873 int topGlyphOverflow = -strokeOverflow - topGlyphEdge; 871 874 int bottomGlyphOverflow = strokeOverflow + bottomGlyphEdge; … … 874 877 875 878 TextEmphasisPosition emphasisMarkPosition; 876 if ( style->textEmphasisMark() != TextEmphasisMarkNone && textBox->getEmphasisMarkPosition(style, emphasisMarkPosition)) {877 int emphasisMarkHeight = style->font().emphasisMarkHeight(style->textEmphasisMarkString());878 if ((emphasisMarkPosition == TextEmphasisPositionOver) == (! style->isFlippedLinesWritingMode()))879 if (lineStyle.textEmphasisMark() != TextEmphasisMarkNone && textBox->getEmphasisMarkPosition(&lineStyle, emphasisMarkPosition)) { 880 int emphasisMarkHeight = lineStyle.font().emphasisMarkHeight(lineStyle.textEmphasisMarkString()); 881 if ((emphasisMarkPosition == TextEmphasisPositionOver) == (!lineStyle.isFlippedLinesWritingMode())) 879 882 topGlyphOverflow = min(topGlyphOverflow, -emphasisMarkHeight); 880 883 else … … 884 887 // If letter-spacing is negative, we should factor that into right layout overflow. (Even in RTL, letter-spacing is 885 888 // applied to the right, so this is not an issue with left overflow. 886 rightGlyphOverflow -= min(0, (int) style->font().letterSpacing());889 rightGlyphOverflow -= min(0, (int)lineStyle.font().letterSpacing()); 887 890 888 891 LayoutUnit textShadowLogicalTop; 889 892 LayoutUnit textShadowLogicalBottom; 890 style->getTextShadowBlockDirectionExtent(textShadowLogicalTop, textShadowLogicalBottom);893 lineStyle.getTextShadowBlockDirectionExtent(textShadowLogicalTop, textShadowLogicalBottom); 891 894 892 895 LayoutUnit childOverflowLogicalTop = min<LayoutUnit>(textShadowLogicalTop + topGlyphOverflow, topGlyphOverflow); … … 895 898 LayoutUnit textShadowLogicalLeft; 896 899 LayoutUnit textShadowLogicalRight; 897 style->getTextShadowInlineDirectionExtent(textShadowLogicalLeft, textShadowLogicalRight);900 lineStyle.getTextShadowInlineDirectionExtent(textShadowLogicalLeft, textShadowLogicalRight); 898 901 899 902 LayoutUnit childOverflowLogicalLeft = min<LayoutUnit>(textShadowLogicalLeft + leftGlyphOverflow, leftGlyphOverflow); … … 1307 1310 LayoutRect localRect(frameRect); 1308 1311 flipForWritingMode(localRect); 1309 LayoutPoint adjustedPaintoffset = paintOffset + localRect.location(); 1310 1311 GraphicsContext* context = paintInfo.context; 1312 1312 1313 1313 // You can use p::first-line to specify a background. If so, the root line boxes for 1314 1314 // a line may actually have to paint a background. 1315 RenderStyle* styleToUse = renderer().style(isFirstLineStyle()); 1316 if ((!parent() && isFirstLineStyle() && styleToUse != renderer().style()) || (parent() && renderer().hasBoxDecorations())) { 1317 LayoutRect paintRect = LayoutRect(adjustedPaintoffset, frameRect.size()); 1318 // Shadow comes first and is behind the background and border. 1319 if (!boxModelObject()->boxShadowShouldBeAppliedToBackground(BackgroundBleedNone, this)) 1320 paintBoxShadow(paintInfo, styleToUse, Normal, paintRect); 1321 1322 Color c = styleToUse->visitedDependentColor(CSSPropertyBackgroundColor); 1323 paintFillLayers(paintInfo, c, styleToUse->backgroundLayers(), paintRect); 1324 paintBoxShadow(paintInfo, styleToUse, Inset, paintRect); 1325 1326 // :first-line cannot be used to put borders on a line. Always paint borders with our 1327 // non-first-line style. 1328 if (parent() && renderer().style()->hasBorder()) { 1329 const NinePieceImage& borderImage = renderer().style()->borderImage(); 1330 StyleImage* borderImageSource = borderImage.image(); 1331 bool hasBorderImage = borderImageSource && borderImageSource->canRender(&renderer(), styleToUse->effectiveZoom()); 1332 if (hasBorderImage && !borderImageSource->isLoaded()) 1333 return; // Don't paint anything while we wait for the image to load. 1334 1335 // The simple case is where we either have no border image or we are the only box for this object. In those 1336 // cases only a single call to draw is required. 1337 if (!hasBorderImage || (!prevLineBox() && !nextLineBox())) 1338 boxModelObject()->paintBorder(paintInfo, paintRect, renderer().style(isFirstLineStyle()), BackgroundBleedNone, includeLogicalLeftEdge(), includeLogicalRightEdge()); 1339 else { 1340 // We have a border image that spans multiple lines. 1341 // We need to adjust tx and ty by the width of all previous lines. 1342 // Think of border image painting on inlines as though you had one long line, a single continuous 1343 // strip. Even though that strip has been broken up across multiple lines, you still paint it 1344 // as though you had one single line. This means each line has to pick up the image where 1345 // the previous line left off. 1346 // FIXME: What the heck do we do with RTL here? The math we're using is obviously not right, 1347 // but it isn't even clear how this should work at all. 1348 LayoutUnit logicalOffsetOnLine = 0; 1349 for (InlineFlowBox* curr = prevLineBox(); curr; curr = curr->prevLineBox()) 1350 logicalOffsetOnLine += curr->logicalWidth(); 1351 LayoutUnit totalLogicalWidth = logicalOffsetOnLine; 1352 for (InlineFlowBox* curr = this; curr; curr = curr->nextLineBox()) 1353 totalLogicalWidth += curr->logicalWidth(); 1354 LayoutUnit stripX = adjustedPaintoffset.x() - (isHorizontal() ? logicalOffsetOnLine : LayoutUnit()); 1355 LayoutUnit stripY = adjustedPaintoffset.y() - (isHorizontal() ? LayoutUnit() : logicalOffsetOnLine); 1356 LayoutUnit stripWidth = isHorizontal() ? totalLogicalWidth : frameRect.width(); 1357 LayoutUnit stripHeight = isHorizontal() ? frameRect.height() : totalLogicalWidth; 1358 1359 LayoutRect clipRect = clipRectForNinePieceImageStrip(this, borderImage, paintRect); 1360 GraphicsContextStateSaver stateSaver(*context); 1361 context->clip(clipRect); 1362 boxModelObject()->paintBorder(paintInfo, LayoutRect(stripX, stripY, stripWidth, stripHeight), renderer().style(isFirstLineStyle())); 1363 } 1364 } 1315 if (parent() && !renderer().hasBoxDecorations()) 1316 return; 1317 RenderStyle& lineStyle = this->lineStyle(); 1318 if (!parent() && (!isFirstLine() || &lineStyle == renderer().style())) 1319 return; 1320 1321 LayoutPoint adjustedPaintoffset = paintOffset + localRect.location(); 1322 GraphicsContext* context = paintInfo.context; 1323 LayoutRect paintRect = LayoutRect(adjustedPaintoffset, frameRect.size()); 1324 // Shadow comes first and is behind the background and border. 1325 if (!boxModelObject()->boxShadowShouldBeAppliedToBackground(BackgroundBleedNone, this)) 1326 paintBoxShadow(paintInfo, &lineStyle, Normal, paintRect); 1327 1328 Color c = lineStyle.visitedDependentColor(CSSPropertyBackgroundColor); 1329 paintFillLayers(paintInfo, c, lineStyle.backgroundLayers(), paintRect); 1330 paintBoxShadow(paintInfo, &lineStyle, Inset, paintRect); 1331 1332 // :first-line cannot be used to put borders on a line. Always paint borders with our 1333 // non-first-line style. 1334 if (!parent() || !renderer().style()->hasBorder()) 1335 return; 1336 const NinePieceImage& borderImage = renderer().style()->borderImage(); 1337 StyleImage* borderImageSource = borderImage.image(); 1338 bool hasBorderImage = borderImageSource && borderImageSource->canRender(&renderer(), lineStyle.effectiveZoom()); 1339 if (hasBorderImage && !borderImageSource->isLoaded()) 1340 return; // Don't paint anything while we wait for the image to load. 1341 1342 // The simple case is where we either have no border image or we are the only box for this object. In those 1343 // cases only a single call to draw is required. 1344 if (!hasBorderImage || (!prevLineBox() && !nextLineBox())) 1345 boxModelObject()->paintBorder(paintInfo, paintRect, &lineStyle, BackgroundBleedNone, includeLogicalLeftEdge(), includeLogicalRightEdge()); 1346 else { 1347 // We have a border image that spans multiple lines. 1348 // We need to adjust tx and ty by the width of all previous lines. 1349 // Think of border image painting on inlines as though you had one long line, a single continuous 1350 // strip. Even though that strip has been broken up across multiple lines, you still paint it 1351 // as though you had one single line. This means each line has to pick up the image where 1352 // the previous line left off. 1353 // FIXME: What the heck do we do with RTL here? The math we're using is obviously not right, 1354 // but it isn't even clear how this should work at all. 1355 LayoutUnit logicalOffsetOnLine = 0; 1356 for (InlineFlowBox* curr = prevLineBox(); curr; curr = curr->prevLineBox()) 1357 logicalOffsetOnLine += curr->logicalWidth(); 1358 LayoutUnit totalLogicalWidth = logicalOffsetOnLine; 1359 for (InlineFlowBox* curr = this; curr; curr = curr->nextLineBox()) 1360 totalLogicalWidth += curr->logicalWidth(); 1361 LayoutUnit stripX = adjustedPaintoffset.x() - (isHorizontal() ? logicalOffsetOnLine : LayoutUnit()); 1362 LayoutUnit stripY = adjustedPaintoffset.y() - (isHorizontal() ? LayoutUnit() : logicalOffsetOnLine); 1363 LayoutUnit stripWidth = isHorizontal() ? totalLogicalWidth : frameRect.width(); 1364 LayoutUnit stripHeight = isHorizontal() ? frameRect.height() : totalLogicalWidth; 1365 1366 LayoutRect clipRect = clipRectForNinePieceImageStrip(this, borderImage, paintRect); 1367 GraphicsContextStateSaver stateSaver(*context); 1368 context->clip(clipRect); 1369 boxModelObject()->paintBorder(paintInfo, LayoutRect(stripX, stripY, stripWidth, stripHeight), &lineStyle); 1365 1370 } 1366 1371 } … … 1537 1542 1538 1543 if (curr->isInlineTextBox()) { 1539 RenderStyle * style = curr->renderer().style(isFirstLineStyle());1544 RenderStyle& childLineStyle = curr->lineStyle(); 1540 1545 TextEmphasisPosition emphasisMarkPosition; 1541 if ( style->textEmphasisMark() != TextEmphasisMarkNone && toInlineTextBox(curr)->getEmphasisMarkPosition(style, emphasisMarkPosition) && emphasisMarkPosition == TextEmphasisPositionOver) {1542 if (! style->isFlippedLinesWritingMode()) {1543 int topOfEmphasisMark = curr->logicalTop() - style->font().emphasisMarkHeight(style->textEmphasisMarkString());1546 if (childLineStyle.textEmphasisMark() != TextEmphasisMarkNone && toInlineTextBox(curr)->getEmphasisMarkPosition(&childLineStyle, emphasisMarkPosition) && emphasisMarkPosition == TextEmphasisPositionOver) { 1547 if (!childLineStyle.isFlippedLinesWritingMode()) { 1548 int topOfEmphasisMark = curr->logicalTop() - childLineStyle.font().emphasisMarkHeight(childLineStyle.textEmphasisMarkString()); 1544 1549 result = max(result, allowedPosition - topOfEmphasisMark); 1545 1550 } else { 1546 int bottomOfEmphasisMark = curr->logicalBottom() + style->font().emphasisMarkHeight(style->textEmphasisMarkString());1551 int bottomOfEmphasisMark = curr->logicalBottom() + childLineStyle.font().emphasisMarkHeight(childLineStyle.textEmphasisMarkString()); 1547 1552 result = max(result, bottomOfEmphasisMark - allowedPosition); 1548 1553 } … … 1585 1590 1586 1591 if (curr->isInlineTextBox()) { 1587 RenderStyle * style = curr->renderer().style(isFirstLineStyle());1588 if ( style->textEmphasisMark() != TextEmphasisMarkNone && style->textEmphasisPosition() == TextEmphasisPositionUnder) {1589 if (! style->isFlippedLinesWritingMode()) {1590 LayoutUnit bottomOfEmphasisMark = curr->logicalBottom() + style->font().emphasisMarkHeight(style->textEmphasisMarkString());1592 RenderStyle& childLineStyle = curr->lineStyle(); 1593 if (childLineStyle.textEmphasisMark() != TextEmphasisMarkNone && childLineStyle.textEmphasisPosition() == TextEmphasisPositionUnder) { 1594 if (!childLineStyle.isFlippedLinesWritingMode()) { 1595 LayoutUnit bottomOfEmphasisMark = curr->logicalBottom() + childLineStyle.font().emphasisMarkHeight(childLineStyle.textEmphasisMarkString()); 1591 1596 result = max(result, bottomOfEmphasisMark - allowedPosition); 1592 1597 } else { 1593 LayoutUnit topOfEmphasisMark = curr->logicalTop() - style->font().emphasisMarkHeight(style->textEmphasisMarkString());1598 LayoutUnit topOfEmphasisMark = curr->logicalTop() - childLineStyle.font().emphasisMarkHeight(childLineStyle.textEmphasisMarkString()); 1594 1599 result = max(result, allowedPosition - topOfEmphasisMark); 1595 1600 } -
trunk/Source/WebCore/rendering/InlineFlowBox.h
r156092 r156608 74 74 75 75 RenderBoxModelObject& renderer() const { return toRenderBoxModelObject(InlineBox::renderer()); } 76 RenderStyle& lineStyle() const { return isFirstLine() ? *renderer().firstLineStyle() : *renderer().style(); } 76 77 77 78 InlineFlowBox* prevLineBox() const { return m_prevLineBox; } … … 143 144 if (!includeLogicalLeftEdge()) 144 145 return 0; 145 return isHorizontal() ? renderer().style(isFirstLineStyle())->borderLeftWidth() : renderer().style(isFirstLineStyle())->borderTopWidth();146 return isHorizontal() ? lineStyle().borderLeftWidth() : lineStyle().borderTopWidth(); 146 147 } 147 148 int borderLogicalRight() const … … 149 150 if (!includeLogicalRightEdge()) 150 151 return 0; 151 return isHorizontal() ? renderer().style(isFirstLineStyle())->borderRightWidth() : renderer().style(isFirstLineStyle())->borderBottomWidth();152 return isHorizontal() ? lineStyle().borderRightWidth() : lineStyle().borderBottomWidth(); 152 153 } 153 154 int paddingLogicalLeft() const -
trunk/Source/WebCore/rendering/InlineTextBox.cpp
r156500 r156608 103 103 if (&parent()->renderer() == renderer().parent()) 104 104 return parent()->baselinePosition(baselineType); 105 return toRenderBoxModelObject(renderer().parent())->baselinePosition(baselineType, isFirstLine Style(), isHorizontal() ? HorizontalLine : VerticalLine, PositionOnContainingLine);105 return toRenderBoxModelObject(renderer().parent())->baselinePosition(baselineType, isFirstLine(), isHorizontal() ? HorizontalLine : VerticalLine, PositionOnContainingLine); 106 106 } 107 107 … … 112 112 if (&parent()->renderer() == renderer().parent()) 113 113 return parent()->lineHeight(); 114 return toRenderBoxModelObject(renderer().parent())->lineHeight(isFirstLine Style(), isHorizontal() ? HorizontalLine : VerticalLine, PositionOnContainingLine);114 return toRenderBoxModelObject(renderer().parent())->lineHeight(isFirstLine(), isHorizontal() ? HorizontalLine : VerticalLine, PositionOnContainingLine); 115 115 } 116 116 … … 212 212 LayoutUnit selTop = selectionTop(); 213 213 LayoutUnit selHeight = selectionHeight(); 214 RenderStyle * styleToUse = renderer().style(isFirstLineStyle());215 const Font& font = fontToUse( *styleToUse, renderer());214 RenderStyle& lineStyle = this->lineStyle(); 215 const Font& font = fontToUse(lineStyle, renderer()); 216 216 217 217 BufferForAppendingHyphen charactersWithHyphen; 218 218 bool respectHyphen = ePos == m_len && hasHyphen(); 219 TextRun textRun = constructTextRun( styleToUse, font, respectHyphen ? &charactersWithHyphen : 0);219 TextRun textRun = constructTextRun(&lineStyle, font, respectHyphen ? &charactersWithHyphen : 0); 220 220 if (respectHyphen) 221 221 endPos = textRun.length(); … … 314 314 // If we got here that means that we were only partially truncated and we need to return the pixel offset at which 315 315 // to place the ellipsis. 316 float widthOfVisibleText = renderer().width(m_start, offset, textPos(), isFirstLine Style());316 float widthOfVisibleText = renderer().width(m_start, offset, textPos(), isFirstLine()); 317 317 318 318 // The ellipsis needs to be placed just after the last visible character. … … 393 393 // Make sure truncated text is ignored while hittesting. 394 394 if (m_truncation != cNoTruncation) { 395 LayoutUnit widthOfVisibleText = renderer().width(m_start, m_truncation, textPos(), isFirstLine Style());395 LayoutUnit widthOfVisibleText = renderer().width(m_start, m_truncation, textPos(), isFirstLine()); 396 396 397 397 if (isHorizontal()) … … 556 556 // NOTE: WebKit's behavior differs from that of IE which appears to just overlay the ellipsis on top of the 557 557 // truncated string i.e. |Hello|CBA| -> |...lo|CBA| 558 LayoutUnit widthOfVisibleText = renderer().width(m_start, m_truncation, textPos(), isFirstLine Style());558 LayoutUnit widthOfVisibleText = renderer().width(m_start, m_truncation, textPos(), isFirstLine()); 559 559 LayoutUnit widthOfHiddenText = m_logicalWidth - widthOfVisibleText; 560 560 LayoutSize truncationOffset(isLeftToRightDirection() ? widthOfHiddenText : -widthOfHiddenText, 0); … … 565 565 GraphicsContext* context = paintInfo.context; 566 566 567 RenderStyle * styleToUse = renderer().style(isFirstLineStyle());568 569 adjustedPaintOffset.move(0, styleToUse->isHorizontalWritingMode() ? 0 : -logicalHeight());567 RenderStyle& lineStyle = this->lineStyle(); 568 569 adjustedPaintOffset.move(0, lineStyle.isHorizontalWritingMode() ? 0 : -logicalHeight()); 570 570 571 571 FloatPoint boxOrigin = locationIncludingFlipping(); … … 573 573 FloatRect boxRect(boxOrigin, LayoutSize(logicalWidth(), logicalHeight())); 574 574 575 RenderCombineText* combinedText = styleToUse->hasTextCombine() && renderer().isCombineText() && toRenderCombineText(renderer()).isCombined() ? &toRenderCombineText(renderer()) : 0;575 RenderCombineText* combinedText = lineStyle.hasTextCombine() && renderer().isCombineText() && toRenderCombineText(renderer()).isCombined() ? &toRenderCombineText(renderer()) : 0; 576 576 577 577 bool shouldRotate = !isHorizontal() && !combinedText; … … 587 587 Color textStrokeColor; 588 588 Color emphasisMarkColor; 589 float textStrokeWidth = styleToUse->textStrokeWidth();590 const ShadowData* textShadow = paintInfo.forceBlackText() ? 0 : styleToUse->textShadow();589 float textStrokeWidth = lineStyle.textStrokeWidth(); 590 const ShadowData* textShadow = paintInfo.forceBlackText() ? 0 : lineStyle.textShadow(); 591 591 592 592 if (paintInfo.forceBlackText()) { … … 595 595 emphasisMarkColor = Color::black; 596 596 } else { 597 textFillColor = styleToUse->visitedDependentColor(CSSPropertyWebkitTextFillColor);597 textFillColor = lineStyle.visitedDependentColor(CSSPropertyWebkitTextFillColor); 598 598 599 599 bool forceBackgroundToWhite = false; 600 600 if (isPrinting) { 601 if ( styleToUse->printColorAdjust() == PrintColorAdjustEconomy)601 if (lineStyle.printColorAdjust() == PrintColorAdjustEconomy) 602 602 forceBackgroundToWhite = true; 603 603 if (renderer().frame().settings().shouldPrintBackgrounds()) … … 609 609 textFillColor = correctedTextColor(textFillColor, Color::white); 610 610 611 textStrokeColor = styleToUse->visitedDependentColor(CSSPropertyWebkitTextStrokeColor);611 textStrokeColor = lineStyle.visitedDependentColor(CSSPropertyWebkitTextStrokeColor); 612 612 613 613 // Make the text stroke color legible against a white background … … 615 615 textStrokeColor = correctedTextColor(textStrokeColor, Color::white); 616 616 617 emphasisMarkColor = styleToUse->visitedDependentColor(CSSPropertyWebkitTextEmphasisColor);617 emphasisMarkColor = lineStyle.visitedDependentColor(CSSPropertyWebkitTextEmphasisColor); 618 618 619 619 // Make the text stroke color legible against a white background … … 671 671 672 672 // Set our font. 673 const Font& font = fontToUse( *styleToUse, renderer());673 const Font& font = fontToUse(lineStyle, renderer()); 674 674 675 675 FloatPoint textOrigin = FloatPoint(boxOrigin.x(), boxOrigin.y() + font.fontMetrics().ascent()); … … 683 683 #if PLATFORM(MAC) 684 684 // Custom highlighters go behind everything else. 685 if ( styleToUse->highlight() != nullAtom && !context->paintingDisabled())686 paintCustomHighlight(adjustedPaintOffset, styleToUse->highlight());685 if (lineStyle.highlight() != nullAtom && !context->paintingDisabled()) 686 paintCustomHighlight(adjustedPaintOffset, lineStyle.highlight()); 687 687 #endif 688 688 689 689 if (containsComposition && !useCustomUnderlines) 690 paintCompositionBackground(context, boxOrigin, styleToUse, font,690 paintCompositionBackground(context, boxOrigin, &lineStyle, font, 691 691 renderer().frame().editor().compositionStart(), 692 692 renderer().frame().editor().compositionEnd()); 693 693 694 paintDocumentMarkers(context, boxOrigin, styleToUse, font, true);694 paintDocumentMarkers(context, boxOrigin, &lineStyle, font, true); 695 695 696 696 if (haveSelection && !useCustomUnderlines) 697 paintSelection(context, boxOrigin, styleToUse, font, selectionFillColor);697 paintSelection(context, boxOrigin, &lineStyle, font, selectionFillColor); 698 698 } 699 699 … … 724 724 725 725 BufferForAppendingHyphen charactersWithHyphen; 726 TextRun textRun = constructTextRun( styleToUse, font, string, maximumLength, hasHyphen() ? &charactersWithHyphen : 0);726 TextRun textRun = constructTextRun(&lineStyle, font, string, maximumLength, hasHyphen() ? &charactersWithHyphen : 0); 727 727 if (hasHyphen()) 728 728 length = textRun.length(); … … 741 741 int emphasisMarkOffset = 0; 742 742 TextEmphasisPosition emphasisMarkPosition; 743 bool hasTextEmphasis = getEmphasisMarkPosition( styleToUse, emphasisMarkPosition);744 const AtomicString& emphasisMark = hasTextEmphasis ? styleToUse->textEmphasisMarkString() : nullAtom;743 bool hasTextEmphasis = getEmphasisMarkPosition(&lineStyle, emphasisMarkPosition); 744 const AtomicString& emphasisMark = hasTextEmphasis ? lineStyle.textEmphasisMarkString() : nullAtom; 745 745 if (!emphasisMark.isEmpty()) 746 746 emphasisMarkOffset = emphasisMarkPosition == TextEmphasisPositionOver ? -font.fontMetrics().ascent() - font.emphasisMarkDescent(emphasisMark) : font.fontMetrics().descent() + font.emphasisMarkAscent(emphasisMark); … … 751 751 GraphicsContextStateSaver stateSaver(*context, textStrokeWidth > 0); 752 752 753 updateGraphicsContext(context, textFillColor, textStrokeColor, textStrokeWidth, styleToUse->colorSpace());753 updateGraphicsContext(context, textFillColor, textStrokeColor, textStrokeWidth, lineStyle.colorSpace()); 754 754 if (!paintSelectedTextSeparately || ePos <= sPos) { 755 755 // FIXME: Truncate right-to-left text correctly. … … 759 759 760 760 if (!emphasisMark.isEmpty()) { 761 updateGraphicsContext(context, emphasisMarkColor, textStrokeColor, textStrokeWidth, styleToUse->colorSpace());761 updateGraphicsContext(context, emphasisMarkColor, textStrokeColor, textStrokeWidth, lineStyle.colorSpace()); 762 762 763 763 DEFINE_STATIC_LOCAL(TextRun, objectReplacementCharacterTextRun, (&objectReplacementCharacter, 1)); … … 782 782 GraphicsContextStateSaver stateSaver(*context, selectionStrokeWidth > 0); 783 783 784 updateGraphicsContext(context, selectionFillColor, selectionStrokeColor, selectionStrokeWidth, styleToUse->colorSpace());784 updateGraphicsContext(context, selectionFillColor, selectionStrokeColor, selectionStrokeWidth, lineStyle.colorSpace()); 785 785 paintTextWithShadows(context, font, textRun, nullAtom, 0, sPos, ePos, length, textOrigin, boxRect, selectionShadow, selectionStrokeWidth > 0, isHorizontal()); 786 786 if (!emphasisMark.isEmpty()) { 787 updateGraphicsContext(context, selectionEmphasisMarkColor, textStrokeColor, textStrokeWidth, styleToUse->colorSpace());787 updateGraphicsContext(context, selectionEmphasisMarkColor, textStrokeColor, textStrokeWidth, lineStyle.colorSpace()); 788 788 789 789 DEFINE_STATIC_LOCAL(TextRun, objectReplacementCharacterTextRun, (&objectReplacementCharacter, 1)); … … 801 801 802 802 // Paint decorations 803 TextDecoration textDecorations = styleToUse->textDecorationsInEffect();803 TextDecoration textDecorations = lineStyle.textDecorationsInEffect(); 804 804 if (textDecorations != TextDecorationNone && paintInfo.phase != PaintPhaseSelection) { 805 updateGraphicsContext(context, textFillColor, textStrokeColor, textStrokeWidth, styleToUse->colorSpace());805 updateGraphicsContext(context, textFillColor, textStrokeColor, textStrokeWidth, lineStyle.colorSpace()); 806 806 if (combinedText) 807 807 context->concatCTM(rotation(boxRect, Clockwise)); 808 paintDecoration(context, boxOrigin, textDecorations, styleToUse->textDecorationStyle(), textShadow);808 paintDecoration(context, boxOrigin, textDecorations, lineStyle.textDecorationStyle(), textShadow); 809 809 if (combinedText) 810 810 context->concatCTM(rotation(boxRect, Counterclockwise)); … … 812 812 813 813 if (paintInfo.phase == PaintPhaseForeground) { 814 paintDocumentMarkers(context, boxOrigin, styleToUse, font, false);814 paintDocumentMarkers(context, boxOrigin, &lineStyle, font, false); 815 815 816 816 if (useCustomUnderlines) { … … 1151 1151 float width = m_logicalWidth; 1152 1152 if (m_truncation != cNoTruncation) { 1153 width = renderer().width(m_start, m_truncation, textPos(), isFirstLine Style());1153 width = renderer().width(m_start, m_truncation, textPos(), isFirstLine()); 1154 1154 if (!isLeftToRightDirection()) 1155 1155 localOrigin.move(m_logicalWidth - width, 0); … … 1159 1159 Color underline, overline, linethrough; 1160 1160 renderer().getTextDecorationColors(deco, underline, overline, linethrough, true); 1161 if (isFirstLine Style())1161 if (isFirstLine()) 1162 1162 renderer().getTextDecorationColors(deco, underline, overline, linethrough, true, true); 1163 1163 … … 1168 1168 bool linesAreOpaque = !isPrinting && (!(deco & TextDecorationUnderline) || underline.alpha() == 255) && (!(deco & TextDecorationOverline) || overline.alpha() == 255) && (!(deco & TextDecorationLineThrough) || linethrough.alpha() == 255); 1169 1169 1170 RenderStyle * styleToUse = renderer().style(isFirstLineStyle());1171 int baseline = styleToUse->fontMetrics().ascent();1170 RenderStyle& lineStyle = this->lineStyle(); 1171 int baseline = lineStyle.fontMetrics().ascent(); 1172 1172 1173 1173 bool setClip = false; … … 1217 1217 context->setStrokeColor(underline, colorSpace); 1218 1218 #if ENABLE(CSS3_TEXT) 1219 TextUnderlinePosition underlinePosition = styleToUse->textUnderlinePosition();1220 const int underlineOffset = computeUnderlineOffset(underlinePosition, styleToUse->fontMetrics(), this, textDecorationThickness);1219 TextUnderlinePosition underlinePosition = lineStyle.textUnderlinePosition(); 1220 const int underlineOffset = computeUnderlineOffset(underlinePosition, lineStyle.fontMetrics(), this, textDecorationThickness); 1221 1221 1222 1222 switch (decorationStyle) { … … 1357 1357 // we pin to two pixels under the baseline. 1358 1358 int lineThickness = cMisspellingLineThickness; 1359 int baseline = renderer().style(isFirstLineStyle())->fontMetrics().ascent();1359 int baseline = lineStyle().fontMetrics().ascent(); 1360 1360 int descent = logicalHeight() - baseline; 1361 1361 int underlineOffset; … … 1491 1491 paintStart = underline.startOffset; 1492 1492 useWholeWidth = false; 1493 start = renderer().width(m_start, paintStart - m_start, textPos(), isFirstLine Style());1493 start = renderer().width(m_start, paintStart - m_start, textPos(), isFirstLine()); 1494 1494 } 1495 1495 if (paintEnd != underline.endOffset) { // end points at the last char, not past it … … 1502 1502 } 1503 1503 if (!useWholeWidth) { 1504 width = renderer().width(paintStart, paintEnd - paintStart, textPos() + start, isFirstLine Style());1504 width = renderer().width(paintStart, paintEnd - paintStart, textPos() + start, isFirstLine()); 1505 1505 } 1506 1506 … … 1509 1509 // If there's not enough space the underline will touch or overlap characters. 1510 1510 int lineThickness = 1; 1511 int baseline = renderer().style(isFirstLineStyle())->fontMetrics().ascent();1511 int baseline = lineStyle().fontMetrics().ascent(); 1512 1512 if (underline.thick && logicalHeight() - baseline >= 2) 1513 1513 lineThickness = 2; … … 1554 1554 FontCachePurgePreventer fontCachePurgePreventer; 1555 1555 1556 RenderStyle * style = renderer().style(isFirstLineStyle());1557 const Font& font = fontToUse( *style, renderer());1558 return font.offsetForPosition(constructTextRun( style, font), lineOffset - logicalLeft(), includePartialGlyphs);1556 RenderStyle& lineStyle = this->lineStyle(); 1557 const Font& font = fontToUse(lineStyle, renderer()); 1558 return font.offsetForPosition(constructTextRun(&lineStyle, font), lineOffset - logicalLeft(), includePartialGlyphs); 1559 1559 } 1560 1560 … … 1569 1569 FontCachePurgePreventer fontCachePurgePreventer; 1570 1570 1571 RenderStyle* styleToUse = renderer().style(isFirstLineStyle()); 1572 ASSERT(styleToUse); 1573 const Font& font = fontToUse(*styleToUse, renderer()); 1571 RenderStyle& lineStyle = this->lineStyle(); 1572 const Font& font = fontToUse(lineStyle, renderer()); 1574 1573 int from = !isLeftToRightDirection() ? offset - m_start : 0; 1575 1574 int to = !isLeftToRightDirection() ? m_len : offset - m_start; 1576 1575 // FIXME: Do we need to add rightBearing here? 1577 return font.selectionRectForText(constructTextRun( styleToUse, font), IntPoint(logicalLeft(), 0), 0, from, to).maxX();1576 return font.selectionRectForText(constructTextRun(&lineStyle, font), IntPoint(logicalLeft(), 0), 0, from, to).maxX(); 1578 1577 } 1579 1578 -
trunk/Source/WebCore/rendering/InlineTextBox.h
r156094 r156608 59 59 60 60 RenderText& renderer() const { return toRenderText(InlineBox::renderer()); } 61 RenderStyle& lineStyle() const { return isFirstLine() ? *renderer().firstLineStyle() : *renderer().style(); } 61 62 62 63 virtual void destroy(RenderArena&) OVERRIDE FINAL; -
trunk/Source/WebCore/rendering/RenderBlock.cpp
r156557 r156608 5616 5616 5617 5617 if (firstLine && document().styleSheetCollection().usesFirstLineRules()) { 5618 RenderStyle* s = style(firstLine);5618 RenderStyle* s = firstLine ? firstLineStyle() : style(); 5619 5619 if (s != style()) 5620 5620 return s->computedLineHeight(&view()); … … 5659 5659 } 5660 5660 5661 const FontMetrics& fontMetrics = style(firstLine)->fontMetrics(); 5661 const RenderStyle* style = firstLine ? firstLineStyle() : this->style(); 5662 const FontMetrics& fontMetrics = style->fontMetrics(); 5662 5663 return fontMetrics.ascent(baselineType) + (lineHeight(firstLine, direction, linePositionMode) - fontMetrics.height()) / 2; 5663 5664 } … … 5668 5669 return replacedHeight; 5669 5670 5670 if (!(style(isFirstLine)->lineBoxContain() & LineBoxContainBlock)) 5671 const RenderStyle* style = isFirstLine ? firstLineStyle() : this->style(); 5672 if (!(style->lineBoxContain() & LineBoxContainBlock)) 5671 5673 return 0; 5672 5674 … … 5681 5683 if (childrenInline()) { 5682 5684 if (firstLineBox()) 5683 return firstLineBox()->logicalTop() + style(true)->fontMetrics().ascent(firstRootBox()->baselineType());5685 return firstLineBox()->logicalTop() + firstLineStyle()->fontMetrics().ascent(firstRootBox()->baselineType()); 5684 5686 else 5685 5687 return -1; … … 5715 5717 + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight()); 5716 5718 } 5717 if (lastLineBox()) 5718 return lastLineBox()->logicalTop() + style(lastLineBox() == firstLineBox())->fontMetrics().ascent(lastRootBox()->baselineType()); 5719 if (lastLineBox()) { 5720 bool isFirstLine = lastLineBox() == firstLineBox(); 5721 RenderStyle* style = isFirstLine ? firstLineStyle() : this->style(); 5722 return lastLineBox()->logicalTop() + style->fontMetrics().ascent(lastRootBox()->baselineType()); 5723 } 5719 5724 return -1; 5720 5725 } else { -
trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp
r156557 r156608 382 382 ASSERT_WITH_SECURITY_IMPLICATION(newBox->isInlineFlowBox()); 383 383 parentBox = toInlineFlowBox(newBox); 384 parentBox->set FirstLineStyleBit(lineInfo.isFirstLine());384 parentBox->setIsFirstLine(lineInfo.isFirstLine()); 385 385 parentBox->setIsHorizontal(isHorizontalWritingMode()); 386 386 if (!hasDefaultLineBoxContain) … … 623 623 }; 624 624 625 static inline RenderStyle& lineStyle(RenderElement& renderer, const LineInfo& lineInfo) 626 { 627 return lineInfo.isFirstLine() ? *renderer.firstLineStyle() : *renderer.style(); 628 } 629 625 630 static inline void setLogicalWidthForTextRun(RootInlineBox* lineBox, BidiRun* run, RenderText* renderer, float xPos, const LineInfo& lineInfo, 626 631 GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& verticalPositionCache, WordMeasurements& wordMeasurements) … … 628 633 HashSet<const SimpleFontData*> fallbackFonts; 629 634 GlyphOverflow glyphOverflow; 630 631 const Font& font = renderer->style(lineInfo.isFirstLine())->font();635 636 const Font& font = lineStyle(*renderer->parent(), lineInfo).font(); 632 637 // Always compute glyph overflow if the block's line-box-contain value is "glyphs". 633 638 if (lineBox->fitsToGlyphs()) { … … 645 650 646 651 LayoutUnit hyphenWidth = 0; 647 if (toInlineTextBox(run->m_box)->hasHyphen()) { 648 const Font& font = renderer->style(lineInfo.isFirstLine())->font(); 652 if (toInlineTextBox(run->m_box)->hasHyphen()) 649 653 hyphenWidth = measureHyphenWidth(renderer, font, &fallbackFonts); 650 } 654 651 655 float measuredWidth = 0; 652 656 … … 913 917 if (int length = rt->textLength()) { 914 918 if (!r->m_start && needsWordSpacing && isSpaceOrNewline(rt->characterAt(r->m_start))) 915 totalLogicalWidth += rt->style(lineInfo.isFirstLine())->font().wordSpacing();919 totalLogicalWidth += lineStyle(*rt->parent(), lineInfo).font().wordSpacing(); 916 920 needsWordSpacing = !isSpaceOrNewline(rt->characterAt(r->m_stop - 1)) && r->m_stop == length; 917 921 } … … 2215 2219 static bool requiresLineBoxForContent(RenderInline* flow, const LineInfo& lineInfo) 2216 2220 { 2217 RenderObject* parent = flow->parent(); 2218 if (flow->document().inNoQuirksMode() 2219 && (flow->style(lineInfo.isFirstLine())->lineHeight() != parent->style(lineInfo.isFirstLine())->lineHeight() 2220 || flow->style()->verticalAlign() != parent->style()->verticalAlign() 2221 || !parent->style()->font().fontMetrics().hasIdenticalAscentDescentAndLineGap(flow->style()->font().fontMetrics()))) 2221 RenderElement* parent = flow->parent(); 2222 if (flow->document().inNoQuirksMode()) { 2223 const RenderStyle& flowStyle = lineStyle(*flow, lineInfo); 2224 const RenderStyle& parentStyle = lineStyle(*parent, lineInfo); 2225 if (flowStyle.lineHeight() != parentStyle.lineHeight() 2226 || flowStyle.verticalAlign() != parentStyle.verticalAlign() 2227 || !parentStyle.font().fontMetrics().hasIdenticalAscentDescentAndLineGap(flowStyle.font().fontMetrics())) 2222 2228 return true; 2229 } 2223 2230 return false; 2224 2231 } … … 2906 2913 } 2907 2914 2908 RenderStyle * style = t->style(lineInfo.isFirstLine());2909 const Font& f = style ->font();2915 RenderStyle& style = lineStyle(*t->parent(), lineInfo); 2916 const Font& f = style.font(); 2910 2917 bool isFixedPitch = f.isFixedPitch(); 2911 bool canHyphenate = style ->hyphens() == HyphensAuto && WebCore::canHyphenate(style->locale());2918 bool canHyphenate = style.hyphens() == HyphensAuto && WebCore::canHyphenate(style.locale()); 2912 2919 2913 2920 unsigned lastSpace = current.m_pos; … … 2937 2944 renderTextInfo.m_font = &f; 2938 2945 renderTextInfo.m_layout = f.createLayout(t, width.currentWidth(), collapseWhiteSpace); 2939 renderTextInfo.m_lineBreakIterator.resetStringAndReleaseIterator(t->text(), style ->locale());2946 renderTextInfo.m_lineBreakIterator.resetStringAndReleaseIterator(t->text(), style.locale()); 2940 2947 } else if (renderTextInfo.m_layout && renderTextInfo.m_font != &f) { 2941 2948 renderTextInfo.m_font = &f; … … 2948 2955 // words with their trailing space, then subtract its width. 2949 2956 HashSet<const SimpleFontData*> fallbackFonts; 2950 float wordTrailingSpaceWidth = (f.typesettingFeatures() & Kerning) && !textLayout ? f.width(RenderBlock::constructTextRun(t, f, &space, 1, style), &fallbackFonts) + wordSpacing : 0;2957 float wordTrailingSpaceWidth = (f.typesettingFeatures() & Kerning) && !textLayout ? f.width(RenderBlock::constructTextRun(t, f, &space, 1, &style), &fallbackFonts) + wordSpacing : 0; 2951 2958 2952 2959 UChar lastCharacter = renderTextInfo.m_lineBreakIterator.lastCharacter(); … … 2961 2968 lineInfo.setEmpty(false, m_block, &width); 2962 2969 2963 if (c == softHyphen && autoWrap && !hyphenWidth && style ->hyphens() != HyphensNone) {2970 if (c == softHyphen && autoWrap && !hyphenWidth && style.hyphens() != HyphensNone) { 2964 2971 hyphenWidth = measureHyphenWidth(t, f, &fallbackFonts); 2965 2972 width.addUncommittedWidth(hyphenWidth, *current.m_obj); … … 2978 2985 2979 2986 bool betweenWords = c == '\n' || (currWS != PRE && !atStart && isBreakable(renderTextInfo.m_lineBreakIterator, current.m_pos, current.m_nextBreakablePosition, breakNBSP) 2980 && (style ->hyphens() != HyphensNone || (current.previousInSameNode() != softHyphen)));2987 && (style.hyphens() != HyphensNone || (current.previousInSameNode() != softHyphen))); 2981 2988 2982 2989 if (betweenWords || midWordBreak) { … … 3055 3062 if (lineWasTooWide || !width.fitsOnLine()) { 3056 3063 if (canHyphenate && !width.fitsOnLine()) { 3057 tryHyphenating(t, f, style ->locale(), consecutiveHyphenatedLines, blockStyle->hyphenationLimitLines(), style->hyphenationLimitBefore(), style->hyphenationLimitAfter(), lastSpace, current.m_pos, width.currentWidth() - additionalTempWidth, width.availableWidth(), isFixedPitch, collapseWhiteSpace, lastSpaceWordSpacing, lBreak, current.m_nextBreakablePosition, m_hyphenated);3064 tryHyphenating(t, f, style.locale(), consecutiveHyphenatedLines, blockStyle->hyphenationLimitLines(), style.hyphenationLimitBefore(), style.hyphenationLimitAfter(), lastSpace, current.m_pos, width.currentWidth() - additionalTempWidth, width.availableWidth(), isFixedPitch, collapseWhiteSpace, lastSpaceWordSpacing, lBreak, current.m_nextBreakablePosition, m_hyphenated); 3058 3065 if (m_hyphenated) 3059 3066 goto end; … … 3066 3073 wordMeasurement.endOffset = lBreak.m_pos; 3067 3074 } 3068 if (lBreak.m_obj && lBreak.m_pos && lBreak.m_obj->isText() && toRenderText(lBreak.m_obj)->textLength() && toRenderText(lBreak.m_obj)->characterAt(lBreak.m_pos - 1) == softHyphen && style ->hyphens() != HyphensNone)3075 if (lBreak.m_obj && lBreak.m_pos && lBreak.m_obj->isText() && toRenderText(lBreak.m_obj)->textLength() && toRenderText(lBreak.m_obj)->characterAt(lBreak.m_pos - 1) == softHyphen && style.hyphens() != HyphensNone) 3069 3076 m_hyphenated = true; 3070 3077 if (lBreak.m_pos && lBreak.m_pos != (unsigned)wordMeasurement.endOffset && !wordMeasurement.width) { … … 3207 3214 if (!width.fitsOnLine()) { 3208 3215 if (canHyphenate) 3209 tryHyphenating(t, f, style ->locale(), consecutiveHyphenatedLines, blockStyle->hyphenationLimitLines(), style->hyphenationLimitBefore(), style->hyphenationLimitAfter(), lastSpace, current.m_pos, width.currentWidth() - additionalTempWidth, width.availableWidth(), isFixedPitch, collapseWhiteSpace, lastSpaceWordSpacing, lBreak, current.m_nextBreakablePosition, m_hyphenated);3210 3211 if (!m_hyphenated && lBreak.previousInSameNode() == softHyphen && style ->hyphens() != HyphensNone)3216 tryHyphenating(t, f, style.locale(), consecutiveHyphenatedLines, blockStyle->hyphenationLimitLines(), style.hyphenationLimitBefore(), style.hyphenationLimitAfter(), lastSpace, current.m_pos, width.currentWidth() - additionalTempWidth, width.availableWidth(), isFixedPitch, collapseWhiteSpace, lastSpaceWordSpacing, lBreak, current.m_nextBreakablePosition, m_hyphenated); 3217 3218 if (!m_hyphenated && lBreak.previousInSameNode() == softHyphen && style.hyphens() != HyphensNone) 3212 3219 m_hyphenated = true; 3213 3220 -
trunk/Source/WebCore/rendering/RenderDeprecatedFlexibleBox.cpp
r155689 r156608 1009 1009 DEFINE_STATIC_LOCAL(AtomicString, ellipsisAndSpaceStr, (ellipsisAndSpace, 2)); 1010 1010 DEFINE_STATIC_LOCAL(AtomicString, ellipsisStr, (&horizontalEllipsis, 1)); 1011 const Font& font = style(numVisibleLines == 1)->font(); 1011 const RenderStyle& lineStyle = numVisibleLines == 1 ? *firstLineStyle() : *style(); 1012 const Font& font = lineStyle.font(); 1012 1013 1013 1014 // Get ellipsis width, and if the last child is an anchor, it will go after the ellipsis, so add in a space and the anchor width too -
trunk/Source/WebCore/rendering/RenderElement.cpp
r156527 r156608 54 54 #include "RenderView.h" 55 55 #include "SVGRenderSupport.h" 56 #include "StyleResolver.h" 56 57 57 58 #if USE(ACCELERATED_COMPOSITING) … … 176 177 } 177 178 179 enum StyleCacheState { 180 Cached, 181 Uncached 182 }; 183 184 static PassRefPtr<RenderStyle> firstLineStyleForCachedUncachedType(StyleCacheState type, const RenderObject* renderer, RenderStyle* style) 185 { 186 const RenderObject* rendererForFirstLineStyle = renderer; 187 if (renderer->isBeforeOrAfterContent()) 188 rendererForFirstLineStyle = renderer->parent(); 189 190 if (rendererForFirstLineStyle->isRenderBlockFlow() || rendererForFirstLineStyle->isRenderButton()) { 191 if (RenderBlock* firstLineBlock = rendererForFirstLineStyle->firstLineBlock()) { 192 if (type == Cached) 193 return firstLineBlock->getCachedPseudoStyle(FIRST_LINE, style); 194 return firstLineBlock->getUncachedPseudoStyle(PseudoStyleRequest(FIRST_LINE), style, firstLineBlock == renderer ? style : 0); 195 } 196 } else if (!rendererForFirstLineStyle->isAnonymous() && rendererForFirstLineStyle->isRenderInline()) { 197 RenderStyle* parentStyle = rendererForFirstLineStyle->parent()->firstLineStyle(); 198 if (parentStyle != rendererForFirstLineStyle->parent()->style()) { 199 if (type == Cached) { 200 // A first-line style is in effect. Cache a first-line style for ourselves. 201 rendererForFirstLineStyle->style()->setHasPseudoStyle(FIRST_LINE_INHERITED); 202 return rendererForFirstLineStyle->getCachedPseudoStyle(FIRST_LINE_INHERITED, parentStyle); 203 } 204 return rendererForFirstLineStyle->getUncachedPseudoStyle(PseudoStyleRequest(FIRST_LINE_INHERITED), parentStyle, style); 205 } 206 } 207 return 0; 208 } 209 210 PassRefPtr<RenderStyle> RenderElement::uncachedFirstLineStyle(RenderStyle* style) const 211 { 212 if (!document().styleSheetCollection().usesFirstLineRules()) 213 return 0; 214 215 return firstLineStyleForCachedUncachedType(Uncached, this, style); 216 } 217 218 RenderStyle* RenderElement::cachedFirstLineStyle() const 219 { 220 ASSERT(document().styleSheetCollection().usesFirstLineRules()); 221 222 RenderStyle* style = this->style(); 223 if (RefPtr<RenderStyle> firstLineStyle = firstLineStyleForCachedUncachedType(Cached, this, style)) 224 return firstLineStyle.get(); 225 226 return style; 227 } 228 178 229 StyleDifference RenderElement::adjustStyleDifference(StyleDifference diff, unsigned contextSensitiveProperties) const 179 230 { -
trunk/Source/WebCore/rendering/RenderElement.h
r156527 r156608 35 35 36 36 RenderStyle* style() const { return m_style.get(); } 37 RenderStyle* style(bool firstLine) const { return firstLine ? firstLineStyle() : style(); }37 RenderStyle* firstLineStyle() const; 38 38 39 39 virtual void setStyle(PassRefPtr<RenderStyle>); … … 73 73 RenderElement* rendererForRootBackground(); 74 74 75 // Used only by Element::pseudoStyleCacheIsInvalid to get a first line style based off of a 76 // given new style, without accessing the cache. 77 PassRefPtr<RenderStyle> uncachedFirstLineStyle(RenderStyle*) const; 78 75 79 // Updates only the local style ptr of the object. Does not update the state of the object, 76 80 // and so only should be called when the style is known not to have changed (or from setStyle). … … 119 123 120 124 StyleDifference adjustStyleDifference(StyleDifference, unsigned contextSensitiveProperties) const; 125 RenderStyle* cachedFirstLineStyle() const; 121 126 122 127 RenderObject* m_firstChild; … … 131 136 }; 132 137 138 inline RenderStyle* RenderElement::firstLineStyle() const 139 { 140 return document().styleSheetCollection().usesFirstLineRules() ? cachedFirstLineStyle() : style(); 141 } 142 133 143 inline LayoutUnit RenderElement::valueForLength(const Length& length, LayoutUnit maximumValue, bool roundPercentages) const 134 144 { … … 176 186 } 177 187 188 inline RenderStyle* RenderObject::firstLineStyle() const 189 { 190 if (isText()) 191 return m_parent->firstLineStyle(); 192 return toRenderElement(this)->firstLineStyle(); 193 } 194 178 195 inline RenderElement* Element::renderer() const 179 196 { -
trunk/Source/WebCore/rendering/RenderInline.cpp
r156527 r156608 225 225 if (!alwaysCreateLineBoxes && checkFonts && document().styleSheetCollection().usesFirstLineRules()) { 226 226 // Have to check the first line style as well. 227 parentStyle = parent()-> style(true);228 RenderStyle* childStyle = style(true);227 parentStyle = parent()->firstLineStyle(); 228 RenderStyle* childStyle = firstLineStyle(); 229 229 alwaysCreateLineBoxes = !parentStyle->font().fontMetrics().hasIdenticalAscentDescentAndLineGap(childStyle->font().fontMetrics()) 230 || childStyle->verticalAlign() != BASELINE231 || parentStyle->lineHeight() != childStyle->lineHeight();230 || childStyle->verticalAlign() != BASELINE 231 || parentStyle->lineHeight() != childStyle->lineHeight(); 232 232 } 233 233 … … 571 571 if (currBox->inlineBoxWrapper()) { 572 572 const RootInlineBox& rootBox = currBox->inlineBoxWrapper()->root(); 573 int logicalTop = rootBox.logicalTop() + (rootBox.renderer().style(rootBox.isFirstLineStyle())->font().fontMetrics().ascent() - container->style(rootBox.isFirstLineStyle())->font().fontMetrics().ascent()); 574 int logicalHeight = container->style(rootBox.isFirstLineStyle())->font().fontMetrics().height(); 573 const RenderStyle& containerStyle = rootBox.isFirstLine() ? *container->firstLineStyle() : *container->style(); 574 int logicalTop = rootBox.logicalTop() + (rootBox.lineStyle().font().fontMetrics().ascent() - containerStyle.font().fontMetrics().ascent()); 575 int logicalHeight = containerStyle.font().fontMetrics().height(); 575 576 if (isHorizontal) 576 577 yield(FloatRect(currBox->inlineBoxWrapper()->x() - currBox->marginLeft(), logicalTop, currBox->width() + currBox->marginWidth(), logicalHeight)); … … 586 587 for (InlineFlowBox* childLine = currInline->firstLineBox(); childLine; childLine = childLine->nextLineBox()) { 587 588 const RootInlineBox& rootBox = childLine->root(); 588 int logicalTop = rootBox.logicalTop() + (rootBox.renderer().style(rootBox.isFirstLineStyle())->font().fontMetrics().ascent() - container->style(rootBox.isFirstLineStyle())->font().fontMetrics().ascent()); 589 int logicalHeight = container->style(rootBox.isFirstLineStyle())->font().fontMetrics().height(); 589 const RenderStyle& containerStyle = rootBox.isFirstLine() ? *container->firstLineStyle() : *container->style(); 590 int logicalTop = rootBox.logicalTop() + (rootBox.lineStyle().font().fontMetrics().ascent() - containerStyle.font().fontMetrics().ascent()); 591 int logicalHeight = containerStyle.fontMetrics().height(); 590 592 if (isHorizontal) 591 593 yield(FloatRect(childLine->x() - childLine->marginLogicalLeft(), … … 604 606 for (InlineTextBox* childText = currText->firstTextBox(); childText; childText = childText->nextTextBox()) { 605 607 const RootInlineBox& rootBox = childText->root(); 606 int logicalTop = rootBox.logicalTop() + (rootBox.renderer().style(rootBox.isFirstLineStyle())->font().fontMetrics().ascent() - container->style(rootBox.isFirstLineStyle())->font().fontMetrics().ascent()); 607 int logicalHeight = container->style(rootBox.isFirstLineStyle())->font().fontMetrics().height(); 608 const RenderStyle& containerStyle = rootBox.isFirstLine() ? *container->firstLineStyle() : *container->style(); 609 int logicalTop = rootBox.logicalTop() + (rootBox.lineStyle().font().fontMetrics().ascent() - containerStyle.font().fontMetrics().ascent()); 610 int logicalHeight = containerStyle.font().fontMetrics().height(); 608 611 if (isHorizontal) 609 612 yield(FloatRect(childText->x(), logicalTop, childText->logicalWidth(), logicalHeight)); … … 615 618 // FIXME: This could use a helper to share these with text path. 616 619 const RootInlineBox& rootBox = inlineBox->root(); 617 int logicalTop = rootBox.logicalTop() + (rootBox.renderer().style(rootBox.isFirstLineStyle())->font().fontMetrics().ascent() - container->style(rootBox.isFirstLineStyle())->font().fontMetrics().ascent()); 618 int logicalHeight = container->style(rootBox.isFirstLineStyle())->font().fontMetrics().height(); 620 const RenderStyle& containerStyle = rootBox.isFirstLine() ? *container->firstLineStyle() : *container->style(); 621 int logicalTop = rootBox.logicalTop() + (rootBox.lineStyle().font().fontMetrics().ascent() - containerStyle.font().fontMetrics().ascent()); 622 int logicalHeight = containerStyle.fontMetrics().height(); 619 623 if (isHorizontal) 620 624 yield(FloatRect(inlineBox->x(), logicalTop, inlineBox->logicalWidth(), logicalHeight)); … … 1353 1357 { 1354 1358 if (firstLine && document().styleSheetCollection().usesFirstLineRules()) { 1355 RenderStyle* s = style(firstLine);1356 if ( s!= style())1357 return s->computedLineHeight(&view());1359 const RenderStyle& firstLineStyle = *this->firstLineStyle(); 1360 if (&firstLineStyle != style()) 1361 return firstLineStyle.computedLineHeight(&view()); 1358 1362 } 1359 1363 … … 1363 1367 int RenderInline::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const 1364 1368 { 1365 const FontMetrics& fontMetrics = style(firstLine)->fontMetrics(); 1369 const RenderStyle& style = firstLine ? *firstLineStyle() : *this->style(); 1370 const FontMetrics& fontMetrics = style.fontMetrics(); 1366 1371 return fontMetrics.ascent(baselineType) + (lineHeight(firstLine, direction, linePositionMode) - fontMetrics.height()) / 2; 1367 1372 } -
trunk/Source/WebCore/rendering/RenderLineBreak.cpp
r156422 r156608 51 51 { 52 52 if (firstLine && document().styleSheetCollection().usesFirstLineRules()) { 53 RenderStyle* s = style(firstLine);54 if ( s!= style())55 return s->computedLineHeight(&view());53 const RenderStyle& firstLineStyle = *this->firstLineStyle(); 54 if (&firstLineStyle != style()) 55 return firstLineStyle.computedLineHeight(&view()); 56 56 } 57 57 … … 64 64 int RenderLineBreak::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const 65 65 { 66 const FontMetrics& fontMetrics = style(firstLine)->fontMetrics(); 66 const RenderStyle& style = firstLine ? *firstLineStyle() : *this->style(); 67 const FontMetrics& fontMetrics = style.fontMetrics(); 67 68 return fontMetrics.ascent(baselineType) + (lineHeight(firstLine, direction, linePositionMode) - fontMetrics.height()) / 2; 68 69 } -
trunk/Source/WebCore/rendering/RenderObject.cpp
r156527 r156608 2233 2233 } 2234 2234 2235 enum StyleCacheState {2236 Cached,2237 Uncached2238 };2239 2240 static PassRefPtr<RenderStyle> firstLineStyleForCachedUncachedType(StyleCacheState type, const RenderObject* renderer, RenderStyle* style)2241 {2242 const RenderObject* rendererForFirstLineStyle = renderer;2243 if (renderer->isBeforeOrAfterContent())2244 rendererForFirstLineStyle = renderer->parent();2245 2246 if (rendererForFirstLineStyle->isRenderBlockFlow() || rendererForFirstLineStyle->isRenderButton()) {2247 if (RenderBlock* firstLineBlock = rendererForFirstLineStyle->firstLineBlock()) {2248 if (type == Cached)2249 return firstLineBlock->getCachedPseudoStyle(FIRST_LINE, style);2250 return firstLineBlock->getUncachedPseudoStyle(PseudoStyleRequest(FIRST_LINE), style, firstLineBlock == renderer ? style : 0);2251 }2252 } else if (!rendererForFirstLineStyle->isAnonymous() && rendererForFirstLineStyle->isRenderInline()) {2253 RenderStyle* parentStyle = rendererForFirstLineStyle->parent()->firstLineStyle();2254 if (parentStyle != rendererForFirstLineStyle->parent()->style()) {2255 if (type == Cached) {2256 // A first-line style is in effect. Cache a first-line style for ourselves.2257 rendererForFirstLineStyle->style()->setHasPseudoStyle(FIRST_LINE_INHERITED);2258 return rendererForFirstLineStyle->getCachedPseudoStyle(FIRST_LINE_INHERITED, parentStyle);2259 }2260 return rendererForFirstLineStyle->getUncachedPseudoStyle(PseudoStyleRequest(FIRST_LINE_INHERITED), parentStyle, style);2261 }2262 }2263 return 0;2264 }2265 2266 PassRefPtr<RenderStyle> RenderObject::uncachedFirstLineStyle(RenderStyle* style) const2267 {2268 if (!document().styleSheetCollection().usesFirstLineRules())2269 return 0;2270 2271 ASSERT(!isText());2272 2273 return firstLineStyleForCachedUncachedType(Uncached, this, style);2274 }2275 2276 RenderStyle* RenderObject::cachedFirstLineStyle() const2277 {2278 ASSERT(document().styleSheetCollection().usesFirstLineRules());2279 2280 RenderStyle* style = this->style();2281 if (RefPtr<RenderStyle> firstLineStyle = firstLineStyleForCachedUncachedType(Cached, isText() ? parent() : this, style))2282 return firstLineStyle.get();2283 2284 return style;2285 }2286 2287 2235 RenderStyle* RenderObject::getCachedPseudoStyle(PseudoId pseudo, RenderStyle* parentStyle) const 2288 2236 { … … 2355 2303 Color resultColor; 2356 2304 do { 2357 styleToUse = curr->style(firstlineStyle);2305 styleToUse = firstlineStyle ? curr->firstLineStyle() : curr->style(); 2358 2306 currDecs = styleToUse->textDecoration(); 2359 2307 resultColor = decorationColor(styleToUse); … … 2382 2330 // If we bailed out, use the element we bailed out at (typically a <font> or <a> element). 2383 2331 if (decorations && curr) { 2384 styleToUse = curr->style(firstlineStyle);2332 styleToUse = firstlineStyle ? curr->firstLineStyle() : curr->style(); 2385 2333 resultColor = decorationColor(styleToUse); 2386 2334 if (decorations & TextDecorationUnderline) -
trunk/Source/WebCore/rendering/RenderObject.h
r156527 r156608 760 760 761 761 RenderStyle* style() const; 762 RenderStyle* firstLineStyle() const { return document().styleSheetCollection().usesFirstLineRules() ? cachedFirstLineStyle() : style(); } 763 RenderStyle* style(bool firstLine) const { return firstLine ? firstLineStyle() : style(); } 764 765 // Used only by Element::pseudoStyleCacheIsInvalid to get a first line style based off of a 766 // given new style, without accessing the cache. 767 PassRefPtr<RenderStyle> uncachedFirstLineStyle(RenderStyle*) const; 762 RenderStyle* firstLineStyle() const; 768 763 769 764 // Anonymous blocks that are part of of a continuation chain will return their inline continuation's outline style instead. … … 971 966 void removeFromRenderFlowThread(); 972 967 void removeFromRenderFlowThreadRecursive(RenderFlowThread*); 973 974 RenderStyle* cachedFirstLineStyle() const;975 968 976 969 Color selectionColor(int colorProperty) const; -
trunk/Source/WebCore/rendering/RenderRubyRun.cpp
r156151 r156608 277 277 } 278 278 279 static bool shouldOverhang(bool firstLine, const RenderObject* renderer, const RenderRubyBase& rubyBase) 280 { 281 if (!renderer || !renderer->isText()) 282 return false; 283 const RenderStyle& rubyBaseStyle = firstLine ? *rubyBase.firstLineStyle() : *rubyBase.style(); 284 const RenderStyle& style = firstLine ? *renderer->firstLineStyle() : *renderer->style(); 285 return style.fontSize() <= rubyBaseStyle.fontSize(); 286 } 287 279 288 void RenderRubyRun::getOverhang(bool firstLine, RenderObject* startRenderer, RenderObject* endRenderer, int& startOverhang, int& endOverhang) const 280 289 { … … 304 313 endOverhang = style()->isLeftToRightDirection() ? logicalRightOverhang : logicalLeftOverhang; 305 314 306 if (!s tartRenderer || !startRenderer->isText() || startRenderer->style(firstLine)->fontSize() > rubyBase->style(firstLine)->fontSize())315 if (!shouldOverhang(firstLine, startRenderer, *rubyBase)) 307 316 startOverhang = 0; 308 309 if (!endRenderer || !endRenderer->isText() || endRenderer->style(firstLine)->fontSize() > rubyBase->style(firstLine)->fontSize()) 317 if (!shouldOverhang(firstLine, endRenderer, *rubyBase)) 310 318 endOverhang = 0; 311 319 … … 313 321 // We can overhang the ruby by no more than half the width of the neighboring text 314 322 // and no more than half the font size. 315 int halfWidthOfFontSize = rubyText->style(firstLine)->fontSize() / 2; 323 const RenderStyle& rubyTextStyle = firstLine ? *rubyText->firstLineStyle() : *rubyText->style(); 324 int halfWidthOfFontSize = rubyTextStyle.fontSize() / 2; 316 325 if (startOverhang) 317 326 startOverhang = min<int>(startOverhang, min<int>(toRenderText(startRenderer)->minLogicalWidth(), halfWidthOfFontSize)); -
trunk/Source/WebCore/rendering/RenderText.cpp
r156527 r156608 1480 1480 len = textLength() - from; 1481 1481 1482 return width(from, len, style(firstLine)->font(), xPos, fallbackFonts, glyphOverflow); 1482 const RenderStyle& lineStyle = firstLine ? *firstLineStyle() : *style(); 1483 return width(from, len, lineStyle.font(), xPos, fallbackFonts, glyphOverflow); 1483 1484 } 1484 1485 -
trunk/Source/WebCore/rendering/RenderText.h
r156527 r156608 48 48 49 49 RenderStyle* style() const; 50 RenderStyle* style(bool firstLine) const { return firstLine ? firstLineStyle() : style(); }50 RenderStyle* firstLineStyle() const; 51 51 52 52 virtual String originalText() const; … … 250 250 } 251 251 252 inline RenderStyle* RenderText::firstLineStyle() const 253 { 254 return parent()->firstLineStyle(); 255 } 256 252 257 #ifdef NDEBUG 253 258 inline void RenderText::checkConsistency() const -
trunk/Source/WebCore/rendering/RootInlineBox.cpp
r156557 r156608 109 109 int RootInlineBox::baselinePosition(FontBaseline baselineType) const 110 110 { 111 return boxModelObject()->baselinePosition(baselineType, isFirstLine Style(), isHorizontal() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes);111 return boxModelObject()->baselinePosition(baselineType, isFirstLine(), isHorizontal() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes); 112 112 } 113 113 114 114 LayoutUnit RootInlineBox::lineHeight() const 115 115 { 116 return boxModelObject()->lineHeight(isFirstLine Style(), isHorizontal() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes);116 return boxModelObject()->lineHeight(isFirstLine(), isHorizontal() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes); 117 117 } 118 118 … … 212 212 paintEllipsisBox(paintInfo, paintOffset, lineTop, lineBottom); 213 213 #if PLATFORM(MAC) 214 RenderStyle* styleToUse = renderer().style(isFirstLineStyle());215 if ( styleToUse->highlight() != nullAtom && !paintInfo.context->paintingDisabled())216 paintCustomHighlight(paintInfo, paintOffset, styleToUse->highlight());214 const RenderStyle& lineStyle = this->lineStyle(); 215 if (lineStyle.highlight() != nullAtom && !paintInfo.context->paintingDisabled()) 216 paintCustomHighlight(paintInfo, paintOffset, lineStyle.highlight()); 217 217 #endif 218 218 } … … 833 833 // not to be included. 834 834 if (box->renderer().isReplaced()) { 835 if ( renderer().style(isFirstLineStyle())->lineBoxContain() & LineBoxContainReplaced) {835 if (lineStyle().lineBoxContain() & LineBoxContainReplaced) { 836 836 ascent = box->baselinePosition(baselineType()); 837 837 descent = box->lineHeight() - ascent; … … 858 858 bool setUsedFontWithLeading = false; 859 859 860 if (usedFonts && !usedFonts->isEmpty() && (includeFont || (box->renderer().style(isFirstLineStyle())->lineHeight().isNegative() && includeLeading))) { 861 usedFonts->append(box->renderer().style(isFirstLineStyle())->font().primaryFont()); 860 const RenderStyle& boxLineStyle = box->lineStyle(); 861 if (usedFonts && !usedFonts->isEmpty() && (includeFont || (boxLineStyle.lineHeight().isNegative() && includeLeading))) { 862 usedFonts->append(boxLineStyle.font().primaryFont()); 862 863 for (size_t i = 0; i < usedFonts->size(); ++i) { 863 864 const FontMetrics& fontMetrics = usedFonts->at(i)->fontMetrics(); … … 897 898 898 899 if (includeFontForBox(box) && !setUsedFont) { 899 int fontAscent = box ->renderer().style(isFirstLineStyle())->fontMetrics().ascent(baselineType());900 int fontDescent = box ->renderer().style(isFirstLineStyle())->fontMetrics().descent(baselineType());900 int fontAscent = boxLineStyle.fontMetrics().ascent(baselineType()); 901 int fontDescent = boxLineStyle.fontMetrics().descent(baselineType()); 901 902 setAscentAndDescent(ascent, descent, fontAscent, fontDescent, ascentDescentSet); 902 903 affectsAscent = fontAscent - box->logicalTop() > 0; … … 908 909 affectsAscent = glyphOverflow->top - box->logicalTop() > 0; 909 910 affectsDescent = glyphOverflow->bottom + box->logicalTop() > 0; 910 glyphOverflow->top = min(glyphOverflow->top, max(0, glyphOverflow->top - box ->renderer().style(isFirstLineStyle())->fontMetrics().ascent(baselineType())));911 glyphOverflow->bottom = min(glyphOverflow->bottom, max(0, glyphOverflow->bottom - box ->renderer().style(isFirstLineStyle())->fontMetrics().descent(baselineType())));911 glyphOverflow->top = min(glyphOverflow->top, max(0, glyphOverflow->top - boxLineStyle.fontMetrics().ascent(baselineType()))); 912 glyphOverflow->bottom = min(glyphOverflow->bottom, max(0, glyphOverflow->bottom - boxLineStyle.fontMetrics().descent(baselineType()))); 912 913 } 913 914 914 915 if (includeMarginForBox(box)) { 915 LayoutUnit ascentWithMargin = box ->renderer().style(isFirstLineStyle())->fontMetrics().ascent(baselineType());916 LayoutUnit descentWithMargin = box ->renderer().style(isFirstLineStyle())->fontMetrics().descent(baselineType());916 LayoutUnit ascentWithMargin = boxLineStyle.fontMetrics().ascent(baselineType()); 917 LayoutUnit descentWithMargin = boxLineStyle.fontMetrics().descent(baselineType()); 917 918 if (box->parent() && !box->renderer().isTextOrLineBreak()) { 918 919 ascentWithMargin += box->boxModelObject()->borderAndPaddingBefore() + box->boxModelObject()->marginBefore(); … … 938 939 939 940 // This method determines the vertical position for inline elements. 940 bool firstLine = isFirstLine Style();941 bool firstLine = isFirstLine(); 941 942 if (firstLine && !renderer->document().styleSheetCollection().usesFirstLineRules()) 942 943 firstLine = false; … … 955 956 return 0; 956 957 957 Render Object* parent = renderer->parent();958 RenderElement* parent = renderer->parent(); 958 959 if (parent->isRenderInline() && parent->style()->verticalAlign() != TOP && parent->style()->verticalAlign() != BOTTOM) 959 960 verticalPosition = box->parent()->logicalTop(); 960 961 961 962 if (verticalAlign != BASELINE) { 962 const Font& font = parent->style(firstLine)->font(); 963 const RenderStyle& parentLineStyle = firstLine ? *parent->firstLineStyle() : *parent->style(); 964 const Font& font = parentLineStyle.font(); 963 965 const FontMetrics& fontMetrics = font.fontMetrics(); 964 966 int fontSize = font.pixelSize(); -
trunk/Source/WebCore/rendering/style/RenderStyle.h
r156347 r156608 798 798 void getBoxShadowHorizontalExtent(LayoutUnit& left, LayoutUnit& right) const { getShadowHorizontalExtent(boxShadow(), left, right); } 799 799 void getBoxShadowVerticalExtent(LayoutUnit& top, LayoutUnit& bottom) const { getShadowVerticalExtent(boxShadow(), top, bottom); } 800 void getBoxShadowInlineDirectionExtent(LayoutUnit& logicalLeft, LayoutUnit& logicalRight) { getShadowInlineDirectionExtent(boxShadow(), logicalLeft, logicalRight); }801 void getBoxShadowBlockDirectionExtent(LayoutUnit& logicalTop, LayoutUnit& logicalBottom) { getShadowBlockDirectionExtent(boxShadow(), logicalTop, logicalBottom); }800 void getBoxShadowInlineDirectionExtent(LayoutUnit& logicalLeft, LayoutUnit& logicalRight) const { getShadowInlineDirectionExtent(boxShadow(), logicalLeft, logicalRight); } 801 void getBoxShadowBlockDirectionExtent(LayoutUnit& logicalTop, LayoutUnit& logicalBottom) const { getShadowBlockDirectionExtent(boxShadow(), logicalTop, logicalBottom); } 802 802 803 803 #if ENABLE(CSS_BOX_DECORATION_BREAK) -
trunk/Source/WebCore/style/StyleResolveTree.cpp
r156527 r156608 546 546 } 547 547 548 static bool pseudoStyleCacheIsInvalid(Render Object* renderer, RenderStyle* newStyle)548 static bool pseudoStyleCacheIsInvalid(RenderElement* renderer, RenderStyle* newStyle) 549 549 { 550 550 const RenderStyle* currentStyle = renderer->style();
Note: See TracChangeset
for help on using the changeset viewer.