Chromium Code Reviews| Index: Source/core/rendering/RenderCombineText.cpp |
| diff --git a/Source/core/rendering/RenderCombineText.cpp b/Source/core/rendering/RenderCombineText.cpp |
| index fb58e1ab932675aedca302c19fcd03567c36ee0b..968bbd42b00bb495b4ca0562ecd662a659f12147 100644 |
| --- a/Source/core/rendering/RenderCombineText.cpp |
| +++ b/Source/core/rendering/RenderCombineText.cpp |
| @@ -22,16 +22,18 @@ |
| #include "core/rendering/RenderCombineText.h" |
| #include "core/rendering/TextRunConstructor.h" |
| +#include "platform/graphics/GraphicsContext.h" |
| namespace blink { |
| const float textCombineMargin = 1.1f; // Allow em + 10% margin |
| RenderCombineText::RenderCombineText(Node* node, PassRefPtr<StringImpl> string) |
| - : RenderText(node, string) |
| - , m_combinedTextWidth(0) |
| - , m_isCombined(false) |
| - , m_needsFontUpdate(false) |
| + : RenderText(node, string) |
| + , m_combinedTextWidth(0) |
| + , m_scaleX(0) |
|
kouhei (in TOK)
2015/01/21 04:25:04
I prefer this default to 1.0f.
kojii
2015/01/21 07:00:24
Done.
|
| + , m_isCombined(false) |
| + , m_needsFontUpdate(false) |
| { |
| } |
| @@ -40,19 +42,15 @@ void RenderCombineText::styleDidChange(StyleDifference diff, const RenderStyle* |
| setStyleInternal(RenderStyle::clone(style())); |
| RenderText::styleDidChange(diff, oldStyle); |
| - if (m_isCombined) { |
| - RenderText::setTextInternal(originalText()); // This RenderCombineText has been combined once. Restore the original text for the next combineText(). |
| - m_isCombined = false; |
| - } |
| - |
| - m_needsFontUpdate = true; |
| + updateIsCombinedAndText(); |
| } |
| void RenderCombineText::setTextInternal(PassRefPtr<StringImpl> text) |
| { |
| RenderText::setTextInternal(text); |
| - m_needsFontUpdate = true; |
| + m_isCombined = false; // flag that text() holds the text to render |
| + updateIsCombinedAndText(); |
| } |
| float RenderCombineText::width(unsigned from, unsigned length, const Font& font, float xPosition, TextDirection direction, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const |
| @@ -71,13 +69,27 @@ float RenderCombineText::width(unsigned from, unsigned length, const Font& font, |
| void RenderCombineText::adjustTextOrigin(FloatPoint& textOrigin, const FloatRect& boxRect) const |
| { |
| - if (m_isCombined) |
| - textOrigin.move(boxRect.height() / 2 - ceilf(m_combinedTextWidth) / 2, style()->font().fontDescription().computedPixelSize()); |
| + ASSERT(!m_needsFontUpdate); |
| + if (!m_isCombined) |
| + return; |
| + auto renderingWidth = m_combinedTextWidth; |
|
kouhei (in TOK)
2015/01/21 04:25:04
float
kojii
2015/01/21 07:00:23
Done.
|
| + if (m_scaleX) |
| + renderingWidth /= m_scaleX; |
| + textOrigin.move(boxRect.height() / 2 - renderingWidth / 2, style()->font().fontDescription().computedPixelSize()); |
| +} |
| + |
| +void RenderCombineText::transform(GraphicsContext& context, const FloatRect& boxRect) const |
| +{ |
| + ASSERT(!m_needsFontUpdate); |
| + auto centerX = boxRect.x() + boxRect.width() / 2; |
| + AffineTransform transform(m_scaleX, 0, 0, 1, centerX * (1 - m_scaleX), 0); |
| + context.concatCTM(transform); |
| } |
| void RenderCombineText::getStringToRender(int start, StringView& string, int& length) const |
| { |
| ASSERT(start >= 0); |
| + ASSERT(!m_needsFontUpdate); |
| if (m_isCombined) { |
| string = StringView(m_renderingText.impl()); |
| length = string.length(); |
| @@ -87,36 +99,54 @@ void RenderCombineText::getStringToRender(int start, StringView& string, int& le |
| string = text().createView(start, length); |
| } |
| -void RenderCombineText::combineText() |
| +void RenderCombineText::updateIsCombinedAndText() |
| { |
| - if (!m_needsFontUpdate) |
| + // CSS3 spec says text-combine works only in vertical writing mode. |
| + bool shouldCombine = !style()->isHorizontalWritingMode() |
| + // Nothing to combine. |
| + && !(m_isCombined ? m_renderingText.isEmpty() : hasEmptyText()); |
| + if (shouldCombine == m_isCombined) |
| return; |
| - m_isCombined = false; |
| - m_needsFontUpdate = false; |
| + m_isCombined = shouldCombine; |
| - // CSS3 spec says text-combine works only in vertical writing mode. |
| - if (style()->isHorizontalWritingMode()) |
| + if (!shouldCombine) { |
| + RenderText::setTextInternal(m_renderingText.impl()); |
| + m_renderingText.releaseImpl(); |
| return; |
| + } |
| + DEFINE_STATIC_LOCAL(String, objectReplacementCharacterString, (&objectReplacementCharacter, 1)); |
| + m_renderingText = text(); |
| + RenderText::setTextInternal(objectReplacementCharacterString.impl()); |
| + m_needsFontUpdate = true; |
| +} |
| - // Nothing to combine. |
| - if (hasEmptyText()) |
| +void RenderCombineText::updateFont() |
| +{ |
| + if (!m_needsFontUpdate) |
| return; |
| - TextRun run = constructTextRun(this, originalFont(), this, style(), style()->direction()); |
| + m_needsFontUpdate = false; |
| + |
| + if (!m_isCombined) |
| + return; |
| + |
| + TextRun run = constructTextRun(this, originalFont(), m_renderingText, style(), style()->direction()); |
| FontDescription description = originalFont().fontDescription(); |
| - float emWidth = description.computedSize() * textCombineMargin; |
| - bool shouldUpdateFont = false; |
| + float emWidth = description.computedSize(); |
| + if (!(style()->textDecorationsInEffect() & (TextDecorationUnderline | TextDecorationOverline))) |
| + emWidth *= textCombineMargin; |
| description.setOrientation(Horizontal); // We are going to draw combined text horizontally. |
| m_combinedTextWidth = originalFont().width(run); |
| - m_isCombined = m_combinedTextWidth <= emWidth; |
| FontSelector* fontSelector = style()->font().fontSelector(); |
| - if (m_isCombined) |
| - shouldUpdateFont = style()->setFontDescription(description); // Need to change font orientation to horizontal. |
| - else { |
| + bool shouldUpdateFont = style()->setFontDescription(description); // Need to change font orientation to horizontal. |
| + |
| + if (m_combinedTextWidth <= emWidth) { |
| + m_scaleX = 0; |
| + } else { |
| // Need to try compressed glyphs. |
| static const FontWidthVariant widthVariants[] = { HalfWidth, ThirdWidth, QuarterWidth }; |
| for (size_t i = 0 ; i < WTF_ARRAY_LENGTH(widthVariants) ; ++i) { |
| @@ -126,26 +156,23 @@ void RenderCombineText::combineText() |
| float runWidth = compressedFont.width(run); |
| if (runWidth <= emWidth) { |
| m_combinedTextWidth = runWidth; |
| - m_isCombined = true; |
| // Replace my font with the new one. |
| shouldUpdateFont = style()->setFontDescription(description); |
| break; |
| } |
| } |
| - } |
| - if (!m_isCombined) |
| - shouldUpdateFont = style()->setFontDescription(originalFont().fontDescription()); |
| + if (m_combinedTextWidth <= emWidth) { |
| + m_scaleX = 0; |
| + } else { |
| + m_scaleX = emWidth / m_combinedTextWidth; |
| + m_combinedTextWidth = emWidth; |
| + } |
| + } |
| if (shouldUpdateFont) |
| style()->font().update(fontSelector); |
| - |
| - if (m_isCombined) { |
| - DEFINE_STATIC_LOCAL(String, objectReplacementCharacterString, (&objectReplacementCharacter, 1)); |
| - m_renderingText = text(); |
| - RenderText::setTextInternal(objectReplacementCharacterString.impl()); |
| - } |
| } |
| } // namespace blink |