OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2000 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 2000 Lars Knoll (knoll@kde.org) |
3 * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r
ight reserved. | 3 * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r
ight reserved. |
4 * Copyright (C) 2010 Google Inc. All rights reserved. | 4 * Copyright (C) 2010 Google Inc. All rights reserved. |
5 * | 5 * |
6 * This library is free software; you can redistribute it and/or | 6 * This library is free software; you can redistribute it and/or |
7 * modify it under the terms of the GNU Library General Public | 7 * modify it under the terms of the GNU Library General Public |
8 * License as published by the Free Software Foundation; either | 8 * License as published by the Free Software Foundation; either |
9 * version 2 of the License, or (at your option) any later version. | 9 * version 2 of the License, or (at your option) any later version. |
10 * | 10 * |
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
412 setMarginStartForChild(renderer, -startOverhang); | 412 setMarginStartForChild(renderer, -startOverhang); |
413 setMarginEndForChild(renderer, -endOverhang); | 413 setMarginEndForChild(renderer, -endOverhang); |
414 } | 414 } |
415 | 415 |
416 static inline void setLogicalWidthForTextRun(RootInlineBox* lineBox, BidiRun* ru
n, RenderText* renderer, float xPos, const LineInfo& lineInfo, | 416 static inline void setLogicalWidthForTextRun(RootInlineBox* lineBox, BidiRun* ru
n, RenderText* renderer, float xPos, const LineInfo& lineInfo, |
417 GlyphOverflowAndFallbackFontsMap& t
extBoxDataMap, VerticalPositionCache& verticalPositionCache, WordMeasurements& w
ordMeasurements) | 417 GlyphOverflowAndFallbackFontsMap& t
extBoxDataMap, VerticalPositionCache& verticalPositionCache, WordMeasurements& w
ordMeasurements) |
418 { | 418 { |
419 HashSet<const SimpleFontData*> fallbackFonts; | 419 HashSet<const SimpleFontData*> fallbackFonts; |
420 GlyphOverflow glyphOverflow; | 420 GlyphOverflow glyphOverflow; |
421 | 421 |
422 const Font& font = renderer->style(lineInfo.isFirstLine())->font(); | 422 const Font& font = renderer->style(lineInfo.isFirstLine() ? FirstLineStyle :
OwnStyle)->font(); |
423 // Always compute glyph overflow if the block's line-box-contain value is "g
lyphs". | 423 // Always compute glyph overflow if the block's line-box-contain value is "g
lyphs". |
424 if (lineBox->fitsToGlyphs()) { | 424 if (lineBox->fitsToGlyphs()) { |
425 // If we don't stick out of the root line's font box, then don't bother
computing our glyph overflow. This optimization | 425 // If we don't stick out of the root line's font box, then don't bother
computing our glyph overflow. This optimization |
426 // will keep us from computing glyph bounds in nearly all cases. | 426 // will keep us from computing glyph bounds in nearly all cases. |
427 bool includeRootLine = lineBox->includesRootLineBoxFontOrLeading(); | 427 bool includeRootLine = lineBox->includesRootLineBoxFontOrLeading(); |
428 int baselineShift = lineBox->verticalPositionForBox(run->m_box, vertical
PositionCache); | 428 int baselineShift = lineBox->verticalPositionForBox(run->m_box, vertical
PositionCache); |
429 int rootDescent = includeRootLine ? font.fontMetrics().descent() : 0; | 429 int rootDescent = includeRootLine ? font.fontMetrics().descent() : 0; |
430 int rootAscent = includeRootLine ? font.fontMetrics().ascent() : 0; | 430 int rootAscent = includeRootLine ? font.fontMetrics().ascent() : 0; |
431 int boxAscent = font.fontMetrics().ascent() - baselineShift; | 431 int boxAscent = font.fontMetrics().ascent() - baselineShift; |
432 int boxDescent = font.fontMetrics().descent() + baselineShift; | 432 int boxDescent = font.fontMetrics().descent() + baselineShift; |
433 if (boxAscent > rootDescent || boxDescent > rootAscent) | 433 if (boxAscent > rootDescent || boxDescent > rootAscent) |
434 glyphOverflow.computeBounds = true; | 434 glyphOverflow.computeBounds = true; |
435 } | 435 } |
436 | 436 |
437 LayoutUnit hyphenWidth = 0; | 437 LayoutUnit hyphenWidth = 0; |
438 if (toInlineTextBox(run->m_box)->hasHyphen()) { | 438 if (toInlineTextBox(run->m_box)->hasHyphen()) { |
439 const Font& font = renderer->style(lineInfo.isFirstLine())->font(); | 439 const Font& font = renderer->style(lineInfo.isFirstLine() ? FirstLineSty
le : OwnStyle)->font(); |
440 hyphenWidth = measureHyphenWidth(renderer, font, run->direction()); | 440 hyphenWidth = measureHyphenWidth(renderer, font, run->direction()); |
441 } | 441 } |
442 float measuredWidth = 0; | 442 float measuredWidth = 0; |
443 | 443 |
444 bool kerningIsEnabled = font.fontDescription().typesettingFeatures() & Kerni
ng; | 444 bool kerningIsEnabled = font.fontDescription().typesettingFeatures() & Kerni
ng; |
445 | 445 |
446 #if OS(MACOSX) | 446 #if OS(MACOSX) |
447 // FIXME: Having any font feature settings enabled can lead to selection gap
s on | 447 // FIXME: Having any font feature settings enabled can lead to selection gap
s on |
448 // Chromium-mac. https://bugs.webkit.org/show_bug.cgi?id=113418 | 448 // Chromium-mac. https://bugs.webkit.org/show_bug.cgi?id=113418 |
449 bool canUseSimpleFontCodePath = renderer->canUseSimpleFontCodePath() && !fon
t.fontDescription().featureSettings(); | 449 bool canUseSimpleFontCodePath = renderer->canUseSimpleFontCodePath() && !fon
t.fontDescription().featureSettings(); |
450 #else | 450 #else |
451 bool canUseSimpleFontCodePath = renderer->canUseSimpleFontCodePath(); | 451 bool canUseSimpleFontCodePath = renderer->canUseSimpleFontCodePath(); |
452 #endif | 452 #endif |
453 | 453 |
454 // Since we don't cache glyph overflows, we need to re-measure the run if | 454 // Since we don't cache glyph overflows, we need to re-measure the run if |
455 // the style is linebox-contain: glyph. | 455 // the style is linebox-contain: glyph. |
456 | 456 |
457 if (!lineBox->fitsToGlyphs() && canUseSimpleFontCodePath) { | 457 if (!lineBox->fitsToGlyphs() && canUseSimpleFontCodePath) { |
458 int lastEndOffset = run->m_start; | 458 int lastEndOffset = run->m_start; |
459 for (size_t i = 0, size = wordMeasurements.size(); i < size && lastEndOf
fset < run->m_stop; ++i) { | 459 for (size_t i = 0, size = wordMeasurements.size(); i < size && lastEndOf
fset < run->m_stop; ++i) { |
460 const WordMeasurement& wordMeasurement = wordMeasurements[i]; | 460 const WordMeasurement& wordMeasurement = wordMeasurements[i]; |
461 if (wordMeasurement.width <=0 || wordMeasurement.startOffset == word
Measurement.endOffset) | 461 if (wordMeasurement.width <=0 || wordMeasurement.startOffset == word
Measurement.endOffset) |
462 continue; | 462 continue; |
463 if (wordMeasurement.renderer != renderer || wordMeasurement.startOff
set != lastEndOffset || wordMeasurement.endOffset > run->m_stop) | 463 if (wordMeasurement.renderer != renderer || wordMeasurement.startOff
set != lastEndOffset || wordMeasurement.endOffset > run->m_stop) |
464 continue; | 464 continue; |
465 | 465 |
466 lastEndOffset = wordMeasurement.endOffset; | 466 lastEndOffset = wordMeasurement.endOffset; |
467 if (kerningIsEnabled && lastEndOffset == run->m_stop) { | 467 if (kerningIsEnabled && lastEndOffset == run->m_stop) { |
468 int wordLength = lastEndOffset - wordMeasurement.startOffset; | 468 int wordLength = lastEndOffset - wordMeasurement.startOffset; |
469 measuredWidth += renderer->width(wordMeasurement.startOffset, wo
rdLength, xPos, run->direction(), lineInfo.isFirstLine()); | 469 measuredWidth += renderer->width(wordMeasurement.startOffset, wo
rdLength, xPos, run->direction(), lineInfo.isFirstLine() ? FirstLineStyle : OwnS
tyle); |
470 if (i > 0 && wordLength == 1 && renderer->characterAt(wordMeasur
ement.startOffset) == ' ') | 470 if (i > 0 && wordLength == 1 && renderer->characterAt(wordMeasur
ement.startOffset) == ' ') |
471 measuredWidth += renderer->style()->wordSpacing(); | 471 measuredWidth += renderer->style()->wordSpacing(); |
472 } else | 472 } else |
473 measuredWidth += wordMeasurement.width; | 473 measuredWidth += wordMeasurement.width; |
474 if (!wordMeasurement.fallbackFonts.isEmpty()) { | 474 if (!wordMeasurement.fallbackFonts.isEmpty()) { |
475 HashSet<const SimpleFontData*>::const_iterator end = wordMeasure
ment.fallbackFonts.end(); | 475 HashSet<const SimpleFontData*>::const_iterator end = wordMeasure
ment.fallbackFonts.end(); |
476 for (HashSet<const SimpleFontData*>::const_iterator it = wordMea
surement.fallbackFonts.begin(); it != end; ++it) | 476 for (HashSet<const SimpleFontData*>::const_iterator it = wordMea
surement.fallbackFonts.begin(); it != end; ++it) |
477 fallbackFonts.add(*it); | 477 fallbackFonts.add(*it); |
478 } | 478 } |
479 } | 479 } |
480 if (measuredWidth && lastEndOffset != run->m_stop) { | 480 if (measuredWidth && lastEndOffset != run->m_stop) { |
481 // If we don't have enough cached data, we'll measure the run again. | 481 // If we don't have enough cached data, we'll measure the run again. |
482 measuredWidth = 0; | 482 measuredWidth = 0; |
483 fallbackFonts.clear(); | 483 fallbackFonts.clear(); |
484 } | 484 } |
485 } | 485 } |
486 | 486 |
487 if (!measuredWidth) | 487 if (!measuredWidth) |
488 measuredWidth = renderer->width(run->m_start, run->m_stop - run->m_start
, xPos, run->direction(), lineInfo.isFirstLine(), &fallbackFonts, &glyphOverflow
); | 488 measuredWidth = renderer->width(run->m_start, run->m_stop - run->m_start
, xPos, run->direction(), lineInfo.isFirstLine() ? FirstLineStyle : OwnStyle, &f
allbackFonts, &glyphOverflow); |
489 | 489 |
490 run->m_box->setLogicalWidth(measuredWidth + hyphenWidth); | 490 run->m_box->setLogicalWidth(measuredWidth + hyphenWidth); |
491 if (!fallbackFonts.isEmpty()) { | 491 if (!fallbackFonts.isEmpty()) { |
492 ASSERT(run->m_box->isText()); | 492 ASSERT(run->m_box->isText()); |
493 GlyphOverflowAndFallbackFontsMap::ValueType* it = textBoxDataMap.add(toI
nlineTextBox(run->m_box), std::make_pair(Vector<const SimpleFontData*>(), GlyphO
verflow())).storedValue; | 493 GlyphOverflowAndFallbackFontsMap::ValueType* it = textBoxDataMap.add(toI
nlineTextBox(run->m_box), std::make_pair(Vector<const SimpleFontData*>(), GlyphO
verflow())).storedValue; |
494 ASSERT(it->value.first.isEmpty()); | 494 ASSERT(it->value.first.isEmpty()); |
495 copyToVector(fallbackFonts, it->value.first); | 495 copyToVector(fallbackFonts, it->value.first); |
496 run->m_box->parent()->clearDescendantsHaveSameLineHeightAndBaseline(); | 496 run->m_box->parent()->clearDescendantsHaveSameLineHeightAndBaseline(); |
497 } | 497 } |
498 if ((glyphOverflow.top || glyphOverflow.bottom || glyphOverflow.left || glyp
hOverflow.right)) { | 498 if ((glyphOverflow.top || glyphOverflow.bottom || glyphOverflow.left || glyp
hOverflow.right)) { |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
579 else | 579 else |
580 updateLogicalWidthForLeftAlignedBlock(style()->isLeftToRightDirectio
n(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth); | 580 updateLogicalWidthForLeftAlignedBlock(style()->isLeftToRightDirectio
n(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth); |
581 break; | 581 break; |
582 } | 582 } |
583 if (style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) | 583 if (style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) |
584 logicalLeft += verticalScrollbarWidth(); | 584 logicalLeft += verticalScrollbarWidth(); |
585 } | 585 } |
586 | 586 |
587 static void updateLogicalInlinePositions(RenderBlockFlow* block, float& lineLogi
calLeft, float& lineLogicalRight, float& availableLogicalWidth, bool firstLine,
IndentTextOrNot shouldIndentText, LayoutUnit boxLogicalHeight) | 587 static void updateLogicalInlinePositions(RenderBlockFlow* block, float& lineLogi
calLeft, float& lineLogicalRight, float& availableLogicalWidth, bool firstLine,
IndentTextOrNot shouldIndentText, LayoutUnit boxLogicalHeight) |
588 { | 588 { |
589 LayoutUnit lineLogicalHeight = block->minLineHeightForReplacedRenderer(first
Line, boxLogicalHeight); | 589 LayoutUnit lineLogicalHeight = block->minLineHeightForReplacedRenderer(first
Line ? FirstLineStyle : OwnStyle, boxLogicalHeight); |
590 lineLogicalLeft = block->logicalLeftOffsetForLine(block->logicalHeight(), sh
ouldIndentText == IndentText, lineLogicalHeight).toFloat(); | 590 lineLogicalLeft = block->logicalLeftOffsetForLine(block->logicalHeight(), sh
ouldIndentText == IndentText, lineLogicalHeight).toFloat(); |
591 lineLogicalRight = block->logicalRightOffsetForLine(block->logicalHeight(),
shouldIndentText == IndentText, lineLogicalHeight).toFloat(); | 591 lineLogicalRight = block->logicalRightOffsetForLine(block->logicalHeight(),
shouldIndentText == IndentText, lineLogicalHeight).toFloat(); |
592 availableLogicalWidth = lineLogicalRight - lineLogicalLeft; | 592 availableLogicalWidth = lineLogicalRight - lineLogicalLeft; |
593 } | 593 } |
594 | 594 |
595 void RenderBlockFlow::computeInlineDirectionPositionsForLine(RootInlineBox* line
Box, const LineInfo& lineInfo, BidiRun* firstRun, BidiRun* trailingSpaceRun, boo
l reachedEnd, | 595 void RenderBlockFlow::computeInlineDirectionPositionsForLine(RootInlineBox* line
Box, const LineInfo& lineInfo, BidiRun* firstRun, BidiRun* trailingSpaceRun, boo
l reachedEnd, |
596 GlyphOverflowAndFallbac
kFontsMap& textBoxDataMap, VerticalPositionCache& verticalPositionCache, WordMea
surements& wordMeasurements) | 596 GlyphOverflowAndFallbac
kFontsMap& textBoxDataMap, VerticalPositionCache& verticalPositionCache, WordMea
surements& wordMeasurements) |
597 { | 597 { |
598 ETextAlign textAlign = textAlignmentForLine(!reachedEnd && !lineBox->endsWit
hBreak()); | 598 ETextAlign textAlign = textAlignmentForLine(!reachedEnd && !lineBox->endsWit
hBreak()); |
599 | 599 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
649 if (rt->is8Bit()) | 649 if (rt->is8Bit()) |
650 opportunitiesInRun = Character::expansionOpportunityCount(rt
->characters8() + r->m_start, r->m_stop - r->m_start, r->m_box->direction(), isA
fterExpansion); | 650 opportunitiesInRun = Character::expansionOpportunityCount(rt
->characters8() + r->m_start, r->m_stop - r->m_start, r->m_box->direction(), isA
fterExpansion); |
651 else | 651 else |
652 opportunitiesInRun = Character::expansionOpportunityCount(rt
->characters16() + r->m_start, r->m_stop - r->m_start, r->m_box->direction(), is
AfterExpansion); | 652 opportunitiesInRun = Character::expansionOpportunityCount(rt
->characters16() + r->m_start, r->m_stop - r->m_start, r->m_box->direction(), is
AfterExpansion); |
653 expansionOpportunities.append(opportunitiesInRun); | 653 expansionOpportunities.append(opportunitiesInRun); |
654 expansionOpportunityCount += opportunitiesInRun; | 654 expansionOpportunityCount += opportunitiesInRun; |
655 } | 655 } |
656 | 656 |
657 if (rt->textLength()) { | 657 if (rt->textLength()) { |
658 if (!r->m_start && needsWordSpacing && isSpaceOrNewline(rt->char
acterAt(r->m_start))) | 658 if (!r->m_start && needsWordSpacing && isSpaceOrNewline(rt->char
acterAt(r->m_start))) |
659 totalLogicalWidth += rt->style(lineInfo.isFirstLine())->font
().fontDescription().wordSpacing(); | 659 totalLogicalWidth += rt->style(lineInfo.isFirstLine() ? Firs
tLineStyle : OwnStyle)->font().fontDescription().wordSpacing(); |
660 needsWordSpacing = !isSpaceOrNewline(rt->characterAt(r->m_stop -
1)); | 660 needsWordSpacing = !isSpaceOrNewline(rt->characterAt(r->m_stop -
1)); |
661 } | 661 } |
662 | 662 |
663 setLogicalWidthForTextRun(lineBox, r, rt, totalLogicalWidth, lineInf
o, textBoxDataMap, verticalPositionCache, wordMeasurements); | 663 setLogicalWidthForTextRun(lineBox, r, rt, totalLogicalWidth, lineInf
o, textBoxDataMap, verticalPositionCache, wordMeasurements); |
664 } else { | 664 } else { |
665 isAfterExpansion = false; | 665 isAfterExpansion = false; |
666 if (!r->m_object->isRenderInline()) { | 666 if (!r->m_object->isRenderInline()) { |
667 RenderBox* renderBox = toRenderBox(r->m_object); | 667 RenderBox* renderBox = toRenderBox(r->m_object); |
668 if (renderBox->isRubyRun()) | 668 if (renderBox->isRubyRun()) |
669 setMarginsForRubyRun(r, toRenderRubyRun(renderBox), previous
Object, lineInfo); | 669 setMarginsForRubyRun(r, toRenderRubyRun(renderBox), previous
Object, lineInfo); |
(...skipping 1064 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1734 if (!style()->isFlippedLinesWritingMode()) | 1734 if (!style()->isFlippedLinesWritingMode()) |
1735 lastLineAnnotationsAdjustment = lastRootBox()->computeUnderAnnotatio
nAdjustment(lowestAllowedPosition); | 1735 lastLineAnnotationsAdjustment = lastRootBox()->computeUnderAnnotatio
nAdjustment(lowestAllowedPosition); |
1736 else | 1736 else |
1737 lastLineAnnotationsAdjustment = lastRootBox()->computeOverAnnotation
Adjustment(lowestAllowedPosition); | 1737 lastLineAnnotationsAdjustment = lastRootBox()->computeOverAnnotation
Adjustment(lowestAllowedPosition); |
1738 } | 1738 } |
1739 | 1739 |
1740 // Now add in the bottom border/padding. | 1740 // Now add in the bottom border/padding. |
1741 setLogicalHeight(logicalHeight() + lastLineAnnotationsAdjustment + afterEdge
); | 1741 setLogicalHeight(logicalHeight() + lastLineAnnotationsAdjustment + afterEdge
); |
1742 | 1742 |
1743 if (!firstLineBox() && hasLineIfEmpty()) | 1743 if (!firstLineBox() && hasLineIfEmpty()) |
1744 setLogicalHeight(logicalHeight() + lineHeight(true, isHorizontalWritingM
ode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes)); | 1744 setLogicalHeight(logicalHeight() + lineHeight(FirstLineStyle, isHorizont
alWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes)); |
1745 | 1745 |
1746 // See if we have any lines that spill out of our block. If we do, then we
will possibly need to | 1746 // See if we have any lines that spill out of our block. If we do, then we
will possibly need to |
1747 // truncate text. | 1747 // truncate text. |
1748 if (hasTextOverflow) | 1748 if (hasTextOverflow) |
1749 checkLinesForTextOverflow(); | 1749 checkLinesForTextOverflow(); |
1750 | 1750 |
1751 // Ensure the new line boxes will be painted. | 1751 // Ensure the new line boxes will be painted. |
1752 if (isFullLayout && firstLineBox()) | 1752 if (isFullLayout && firstLineBox()) |
1753 setShouldDoFullPaintInvalidationAfterLayout(true); | 1753 setShouldDoFullPaintInvalidationAfterLayout(true); |
1754 } | 1754 } |
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2186 float logicalLeft = logicalLeftOffsetForLine(logicalHeight(), false).toFloat
(); | 2186 float logicalLeft = logicalLeftOffsetForLine(logicalHeight(), false).toFloat
(); |
2187 float availableLogicalWidth = logicalRightOffsetForLine(logicalHeight(), fal
se) - logicalLeft; | 2187 float availableLogicalWidth = logicalRightOffsetForLine(logicalHeight(), fal
se) - logicalLeft; |
2188 updateLogicalWidthForAlignment(textAlign, 0, 0, logicalLeft, totalLogicalWid
th, availableLogicalWidth, 0); | 2188 updateLogicalWidthForAlignment(textAlign, 0, 0, logicalLeft, totalLogicalWid
th, availableLogicalWidth, 0); |
2189 | 2189 |
2190 if (!style()->isLeftToRightDirection()) | 2190 if (!style()->isLeftToRightDirection()) |
2191 return logicalWidth() - logicalLeft; | 2191 return logicalWidth() - logicalLeft; |
2192 return logicalLeft; | 2192 return logicalLeft; |
2193 } | 2193 } |
2194 | 2194 |
2195 } | 2195 } |
OLD | NEW |