Changeset 76743 in webkit


Ignore:
Timestamp:
Jan 26, 2011 5:39:27 PM (13 years ago)
Author:
mitz@apple.com
Message:

<rdar://problem/8446709> Allow inter-ideograph justification for CJK
https://bugs.webkit.org/show_bug.cgi?id=53184

Reviewed by Dave Hyatt.

Source/WebCore:

Tests: fast/text/justify-ideograph-complex.html

fast/text/justify-ideograph-simple.html
fast/text/justify-ideograph-vertical.html

  • html/canvas/CanvasRenderingContext2D.cpp:

(WebCore::CanvasRenderingContext2D::drawTextInternal): Corrected the type of the third parameter
passed to the TextRun constructor and added the trailingExpansionBehavior parameter.

  • platform/graphics/Font.cpp:

(WebCore::Font::expansionOpportunityCount): Added. Returns the number of expansion opportunities
for text justification. On entry, isAfterExpansion says whether an expansion opportunity exists
before the first character. On return, isAfterExpansion says whether an expansion opportunity
exists after the last character.

  • platform/graphics/Font.h:
  • platform/graphics/GlyphBuffer.h:

(WebCore::GlyphBuffer::expandLastAdvance): Added.

  • platform/graphics/TextRun.h:

(WebCore::TextRun::TextRun): Added a TrailingExpansionBehavior parameter to the constructors.
Renamed padding to expansion.
(WebCore::TextRun::expansion): Renamed padding() to this.
(WebCore::TextRun::allowsTrailingExpansion): Added this accessor.

  • platform/graphics/WidthIterator.cpp:

(WebCore::WidthIterator::WidthIterator): Initialize m_isAfterExpansion. Use Font::expansionOpportunityCount()
and adjust the count if it includes a trailing expansion opportunity but the run disallows trailing
expansion.
(WebCore::WidthIterator::advance): Apply expansion before and after CJK ideographs.
(WebCore::WidthIterator::advanceOneCharacter): Changed to not clear the GlyphBuffer so that advance()
can expand the last advance if it is followed by a CJK ideograph.

  • platform/graphics/WidthIterator.h: Renamed m_padding to m_expansion and m_padPerSpace

to m_expansionPerOpportunity.

  • platform/graphics/chromium/FontChromiumWin.cpp:

(WebCore::Font::canExpandAroundIdeographsInComplexText): Added.

  • platform/graphics/chromium/FontLinux.cpp:

(WebCore::Font::canExpandAroundIdeographsInComplexText): Added.

  • platform/graphics/efl/FontEfl.cpp:

(WebCore::Font::canExpandAroundIdeographsInComplexText): Added.

  • platform/graphics/gtk/FontGtk.cpp:

(WebCore::Font::canExpandAroundIdeographsInComplexText): Added.

  • platform/graphics/haiku/FontHaiku.cpp:

(WebCore::Font::canExpandAroundIdeographsInComplexText): Added.

  • platform/graphics/mac/ComplexTextController.cpp:

(WebCore::ComplexTextController::ComplexTextController): Initialize m_isAfterExpansion. Use
Font::expansionOpportunityCount() and adjust the count if it includes a trailing expansion
opportunity but the run disallows trailing expansion.
(WebCore::ComplexTextController::adjustGlyphsAndAdvances): Moved the definition and initialization
of hasExtraSpacing outside the loop. Apply expansion before and after CJK ideographs.

  • platform/graphics/mac/ComplexTextController.h: Renamed m_padding to m_expansion and m_padPerSpace

to m_expansionPerOpportunity.

  • platform/graphics/mac/FontMac.mm:

(WebCore::Font::canExpandAroundIdeographsInComplexText): Added.

  • platform/graphics/qt/FontQt.cpp:

(WebCore::Font::canExpandAroundIdeographsInComplexText): Added.

  • platform/graphics/win/FontWin.cpp:

(WebCore::Font::canExpandAroundIdeographsInComplexText): Added.

  • platform/graphics/win/UniscribeController.cpp:

(WebCore::UniscribeController::UniscribeController): Updated for rename.

  • platform/graphics/wince/FontWinCE.cpp:

(WebCore::Font::canExpandAroundIdeographsInComplexText): Added.

  • platform/graphics/wx/FontWx.cpp:

(WebCore::Font::canExpandAroundIdeographsInComplexText): Added.

  • rendering/EllipsisBox.cpp:

(WebCore::EllipsisBox::paint): Pass a TrailingExpansionBehavior to the TextRun constructor.
(WebCore::EllipsisBox::selectionRect): Ditto.
(WebCore::EllipsisBox::paintSelection): Ditto.

  • rendering/InlineBox.h:

(WebCore::InlineBox::InlineBox): Renamed m_toAdd to m_expansion.
(WebCore::InlineBox::expansion): Renamed toAdd() to this.

  • rendering/InlineTextBox.cpp:

(WebCore::InlineTextBox::selectionRect): Pass a TrailingExpansionBehavior to the TextRun constructor.
(WebCore::InlineTextBox::paint): Ditto.
(WebCore::InlineTextBox::paintSelection): Ditto.
(WebCore::InlineTextBox::paintCompositionBackground): Ditto.
(WebCore::InlineTextBox::paintSpellingOrGrammarMarker): Ditto.
(WebCore::InlineTextBox::paintTextMatchMarker): Ditto.
(WebCore::InlineTextBox::computeRectForReplacementMarker): Ditto.
(WebCore::InlineTextBox::offsetForPosition): Ditto.
(WebCore::InlineTextBox::positionForOffset): Ditto.

  • rendering/InlineTextBox.h:

(WebCore::InlineTextBox::setExpansion): Renamed setSpaceAdd() to this.
(WebCore::InlineTextBox::trailingExpansionBehavior): Added. Trailing expansion is allowed if this
is not the last leaf box on the line.

  • rendering/RenderBlockLineLayout.cpp:

(WebCore::RenderBlock::computeInlineDirectionPositionsForLine): Keep expansion opportunity counts
in a vector instead of computing them twice. Discard the trailing expansion opportunity in the
last text box.

  • rendering/RenderFileUploadControl.cpp:

(WebCore::RenderFileUploadControl::paintObject): Pass a TrailingExpansionBehavior to the TextRun constructor.
(WebCore::RenderFileUploadControl::computePreferredLogicalWidths): Ditto.

  • rendering/RenderListBox.cpp:

(WebCore::RenderListBox::updateFromElement): Ditto.
(WebCore::RenderListBox::paintItemForeground): Ditto. Also corrected the type of the second parameter.

  • rendering/RenderTextControl.cpp:

(WebCore::RenderTextControl::getAvgCharWidth): Ditto.
(WebCore::RenderTextControl::paintPlaceholder): Ditto.

  • rendering/svg/SVGInlineTextBox.cpp:

(WebCore::SVGInlineTextBox::constructTextRun): Ditto.

Source/WebKit/chromium:

  • src/WebTextRun.cpp:

(WebKit::WebTextRun::operator WebCore::TextRun): Added a TrailingExpansionBehavior parameter to the
RenderText constructor.

Source/WebKit2:

  • WebProcess/WebCoreSupport/win/WebPopupMenuWin.cpp:

(WebKit::WebPopupMenu::setUpPlatformData): Added a TrailingExpansionBehavior parameter to the
RenderText constructor.

LayoutTests:

  • fast/text/justify-ideograph-complex.html: Added.
  • fast/text/justify-ideograph-simple.html: Added.
  • fast/text/justify-ideograph-vertical.html: Added.
  • platform/mac/fast/text/justify-ideograph-complex-expected.checksum: Added.
  • platform/mac/fast/text/justify-ideograph-complex-expected.png: Added.
  • platform/mac/fast/text/justify-ideograph-complex-expected.txt: Added.
  • platform/mac/fast/text/justify-ideograph-simple-expected.checksum: Added.
  • platform/mac/fast/text/justify-ideograph-simple-expected.png: Added.
  • platform/mac/fast/text/justify-ideograph-simple-expected.txt: Added.
  • platform/mac/fast/text/justify-ideograph-vertical-expected.checksum: Added.
  • platform/mac/fast/text/justify-ideograph-vertical-expected.png: Added.
  • platform/mac/fast/text/justify-ideograph-vertical-expected.txt: Added.
Location:
trunk
Files:
12 added
38 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r76740 r76743  
     12011-01-26  Dan Bernstein  <mitz@apple.com>
     2
     3        Reviewed by Dave Hyatt.
     4
     5        <rdar://problem/8446709> Allow inter-ideograph justification for CJK
     6        https://bugs.webkit.org/show_bug.cgi?id=53184
     7
     8        * fast/text/justify-ideograph-complex.html: Added.
     9        * fast/text/justify-ideograph-simple.html: Added.
     10        * fast/text/justify-ideograph-vertical.html: Added.
     11        * platform/mac/fast/text/justify-ideograph-complex-expected.checksum: Added.
     12        * platform/mac/fast/text/justify-ideograph-complex-expected.png: Added.
     13        * platform/mac/fast/text/justify-ideograph-complex-expected.txt: Added.
     14        * platform/mac/fast/text/justify-ideograph-simple-expected.checksum: Added.
     15        * platform/mac/fast/text/justify-ideograph-simple-expected.png: Added.
     16        * platform/mac/fast/text/justify-ideograph-simple-expected.txt: Added.
     17        * platform/mac/fast/text/justify-ideograph-vertical-expected.checksum: Added.
     18        * platform/mac/fast/text/justify-ideograph-vertical-expected.png: Added.
     19        * platform/mac/fast/text/justify-ideograph-vertical-expected.txt: Added.
     20
    1212011-01-26  Martin Robinson  <mrobinson@igalia.com>
    222
  • trunk/Source/WebCore/ChangeLog

    r76733 r76743  
     12011-01-26  Dan Bernstein  <mitz@apple.com>
     2
     3        Reviewed by Dave Hyatt.
     4
     5        <rdar://problem/8446709> Allow inter-ideograph justification for CJK
     6        https://bugs.webkit.org/show_bug.cgi?id=53184
     7
     8        Tests: fast/text/justify-ideograph-complex.html
     9               fast/text/justify-ideograph-simple.html
     10               fast/text/justify-ideograph-vertical.html
     11
     12        * html/canvas/CanvasRenderingContext2D.cpp:
     13        (WebCore::CanvasRenderingContext2D::drawTextInternal): Corrected the type of the third parameter
     14        passed to the TextRun constructor and added the trailingExpansionBehavior parameter.
     15        * platform/graphics/Font.cpp:
     16        (WebCore::Font::expansionOpportunityCount): Added. Returns the number of expansion opportunities
     17        for text justification. On entry, isAfterExpansion says whether an expansion opportunity exists
     18        before the first character. On return, isAfterExpansion says whether an expansion opportunity
     19        exists after the last character.
     20        * platform/graphics/Font.h:
     21        * platform/graphics/GlyphBuffer.h:
     22        (WebCore::GlyphBuffer::expandLastAdvance): Added.
     23        * platform/graphics/TextRun.h:
     24        (WebCore::TextRun::TextRun): Added a TrailingExpansionBehavior parameter to the constructors.
     25        Renamed padding to expansion.
     26        (WebCore::TextRun::expansion): Renamed padding() to this.
     27        (WebCore::TextRun::allowsTrailingExpansion): Added this accessor.
     28        * platform/graphics/WidthIterator.cpp:
     29        (WebCore::WidthIterator::WidthIterator): Initialize m_isAfterExpansion. Use Font::expansionOpportunityCount()
     30        and adjust the count if it includes a trailing expansion opportunity but the run disallows trailing
     31        expansion.
     32        (WebCore::WidthIterator::advance): Apply expansion before and after CJK ideographs.
     33        (WebCore::WidthIterator::advanceOneCharacter): Changed to not clear the GlyphBuffer so that advance()
     34        can expand the last advance if it is followed by a CJK ideograph.
     35        * platform/graphics/WidthIterator.h: Renamed m_padding to m_expansion and m_padPerSpace
     36        to m_expansionPerOpportunity.
     37        * platform/graphics/chromium/FontChromiumWin.cpp:
     38        (WebCore::Font::canExpandAroundIdeographsInComplexText): Added.
     39        * platform/graphics/chromium/FontLinux.cpp:
     40        (WebCore::Font::canExpandAroundIdeographsInComplexText): Added.
     41        * platform/graphics/efl/FontEfl.cpp:
     42        (WebCore::Font::canExpandAroundIdeographsInComplexText): Added.
     43        * platform/graphics/gtk/FontGtk.cpp:
     44        (WebCore::Font::canExpandAroundIdeographsInComplexText): Added.
     45        * platform/graphics/haiku/FontHaiku.cpp:
     46        (WebCore::Font::canExpandAroundIdeographsInComplexText): Added.
     47        * platform/graphics/mac/ComplexTextController.cpp:
     48        (WebCore::ComplexTextController::ComplexTextController): Initialize m_isAfterExpansion. Use
     49        Font::expansionOpportunityCount() and adjust the count if it includes a trailing expansion
     50        opportunity but the run disallows trailing expansion.
     51        (WebCore::ComplexTextController::adjustGlyphsAndAdvances): Moved the definition and initialization
     52        of hasExtraSpacing outside the loop. Apply expansion before and after CJK ideographs.
     53        * platform/graphics/mac/ComplexTextController.h: Renamed m_padding to m_expansion and m_padPerSpace
     54        to m_expansionPerOpportunity.
     55        * platform/graphics/mac/FontMac.mm:
     56        (WebCore::Font::canExpandAroundIdeographsInComplexText): Added.
     57        * platform/graphics/qt/FontQt.cpp:
     58        (WebCore::Font::canExpandAroundIdeographsInComplexText): Added.
     59        * platform/graphics/win/FontWin.cpp:
     60        (WebCore::Font::canExpandAroundIdeographsInComplexText): Added.
     61        * platform/graphics/win/UniscribeController.cpp:
     62        (WebCore::UniscribeController::UniscribeController): Updated for rename.
     63        * platform/graphics/wince/FontWinCE.cpp:
     64        (WebCore::Font::canExpandAroundIdeographsInComplexText): Added.
     65        * platform/graphics/wx/FontWx.cpp:
     66        (WebCore::Font::canExpandAroundIdeographsInComplexText): Added.
     67        * rendering/EllipsisBox.cpp:
     68        (WebCore::EllipsisBox::paint): Pass a TrailingExpansionBehavior to the TextRun constructor.
     69        (WebCore::EllipsisBox::selectionRect): Ditto.
     70        (WebCore::EllipsisBox::paintSelection): Ditto.
     71        * rendering/InlineBox.h:
     72        (WebCore::InlineBox::InlineBox): Renamed m_toAdd to m_expansion.
     73        (WebCore::InlineBox::expansion): Renamed toAdd() to this.
     74        * rendering/InlineTextBox.cpp:
     75        (WebCore::InlineTextBox::selectionRect): Pass a TrailingExpansionBehavior to the TextRun constructor.
     76        (WebCore::InlineTextBox::paint): Ditto.
     77        (WebCore::InlineTextBox::paintSelection): Ditto.
     78        (WebCore::InlineTextBox::paintCompositionBackground): Ditto.
     79        (WebCore::InlineTextBox::paintSpellingOrGrammarMarker): Ditto.
     80        (WebCore::InlineTextBox::paintTextMatchMarker): Ditto.
     81        (WebCore::InlineTextBox::computeRectForReplacementMarker): Ditto.
     82        (WebCore::InlineTextBox::offsetForPosition): Ditto.
     83        (WebCore::InlineTextBox::positionForOffset): Ditto.
     84        * rendering/InlineTextBox.h:
     85        (WebCore::InlineTextBox::setExpansion): Renamed setSpaceAdd() to this.
     86        (WebCore::InlineTextBox::trailingExpansionBehavior): Added. Trailing expansion is allowed if this
     87        is not the last leaf box on the line.
     88        * rendering/RenderBlockLineLayout.cpp:
     89        (WebCore::RenderBlock::computeInlineDirectionPositionsForLine): Keep expansion opportunity counts
     90        in a vector instead of computing them twice. Discard the trailing expansion opportunity in the
     91        last text box.
     92        * rendering/RenderFileUploadControl.cpp:
     93        (WebCore::RenderFileUploadControl::paintObject): Pass a TrailingExpansionBehavior to the TextRun constructor.
     94        (WebCore::RenderFileUploadControl::computePreferredLogicalWidths): Ditto.
     95        * rendering/RenderListBox.cpp:
     96        (WebCore::RenderListBox::updateFromElement): Ditto.
     97        (WebCore::RenderListBox::paintItemForeground): Ditto. Also corrected the type of the second parameter.
     98        * rendering/RenderTextControl.cpp:
     99        (WebCore::RenderTextControl::getAvgCharWidth): Ditto.
     100        (WebCore::RenderTextControl::paintPlaceholder): Ditto.
     101        * rendering/svg/SVGInlineTextBox.cpp:
     102        (WebCore::SVGInlineTextBox::constructTextRun): Ditto.
     103
    11042011-01-26  Andy Estes  <aestes@apple.com>
    2105
  • trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp

    r76442 r76743  
    17721772    unsigned length = text.length();
    17731773    const UChar* string = text.characters();
    1774     TextRun textRun(string, length, 0, 0, 0, rtl, override, false, false);
     1774    TextRun textRun(string, length, false, 0, 0, TextRun::AllowTrailingExpansion, rtl, override, false, false);
    17751775
    17761776    // Draw the item text at the correct point.
     
    17941794    }
    17951795
    1796     float width = font.width(TextRun(text, false, 0, 0, rtl, override));
     1796    float width = font.width(TextRun(text, false, 0, 0, TextRun::AllowTrailingExpansion, rtl, override));
    17971797
    17981798    TextAlign align = state().m_textAlign;
  • trunk/Source/WebCore/platform/chromium/PopupMenuChromium.cpp

    r76442 r76743  
    974974             PopupContainerSettings::FirstStrongDirectionalCharacterDirection)
    975975        rtl = itemText.defaultWritingDirection() == WTF::Unicode::RightToLeft;
    976     TextRun textRun(itemText.characters(), itemText.length(), false, 0, 0, rtl);
     976    TextRun textRun(itemText.characters(), itemText.length(), false, 0, 0, TextRun::AllowTrailingExpansion, rtl);
    977977    // If the text is right-to-left, make it right-aligned by adjusting its
    978978    // beginning position.
     
    10021002    if (itemLabel.isEmpty())
    10031003        return;
    1004     TextRun labelTextRun(itemLabel.characters(), itemLabel.length(), false, 0, 0, rtl);
     1004    TextRun labelTextRun(itemLabel.characters(), itemLabel.length(), false, 0, 0, TextRun::AllowTrailingExpansion, rtl);
    10051005    if (rightAligned)
    10061006        textX = max(0, m_popupClient->clientPaddingLeft() - m_popupClient->clientInsetLeft());
  • trunk/Source/WebCore/platform/graphics/Font.cpp

    r76170 r76743  
    33 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
    44 *           (C) 2000 Dirk Mueller (mueller@kde.org)
    5  * Copyright (C) 2003, 2006, 2010 Apple Inc. All rights reserved.
     5 * Copyright (C) 2003, 2006, 2010, 2011 Apple Inc. All rights reserved.
    66 *
    77 * This library is free software; you can redistribute it and/or
     
    294294
    295295#if PLATFORM(QT)
    296     if (run.padding() || run.rtl() || isSmallCaps() || wordSpacing() || letterSpacing())
     296    if (run.expansion() || run.rtl() || isSmallCaps() || wordSpacing() || letterSpacing())
    297297        return Complex;
    298298#endif
     
    459459}
    460460
     461unsigned Font::expansionOpportunityCount(const UChar* characters, size_t length, bool& isAfterExpansion)
     462{
     463    static bool expandAroundIdeographs = canExpandAroundIdeographsInComplexText();
     464    unsigned count = 0;
     465    for (size_t i = 0; i < length; ++i) {
     466        UChar32 character = characters[i];
     467        if (treatAsSpace(character)) {
     468            count++;
     469            isAfterExpansion = true;
     470            continue;
     471        }
     472        if (U16_IS_LEAD(character) && i + 1 < length && U16_IS_TRAIL(characters[i + 1])) {
     473            character = U16_GET_SUPPLEMENTARY(character, characters[i + 1]);
     474            i++;
     475        }
     476        if (expandAroundIdeographs && isCJKIdeograph(character)) {
     477            if (!isAfterExpansion)
     478                count++;
     479            count++;
     480            isAfterExpansion = true;
     481            continue;
     482        }
     483        isAfterExpansion = false;
     484    }
     485    return count;
     486}
     487
    461488bool Font::canReceiveTextEmphasis(UChar32 c)
    462489{
  • trunk/Source/WebCore/platform/graphics/Font.h

    r76442 r76743  
    33 *           (C) 2000 Antti Koivisto (koivisto@kde.org)
    44 *           (C) 2000 Dirk Mueller (mueller@kde.org)
    5  * Copyright (C) 2003, 2006, 2007, 2010 Apple Inc. All rights reserved.
     5 * Copyright (C) 2003, 2006, 2007, 2010, 2011 Apple Inc. All rights reserved.
    66 * Copyright (C) 2008 Holger Hans Peter Freyther
    77 *
     
    143143    static bool isCJKIdeograph(UChar32);
    144144    static bool isCJKIdeographOrSymbol(UChar32);
    145    
     145
     146    static unsigned expansionOpportunityCount(const UChar*, size_t length, bool& isAfterExpansion);
     147
    146148#if PLATFORM(QT)
    147149    QFont font() const;
     
    178180
    179181    static bool canReturnFallbackFontsForComplexText();
     182    static bool canExpandAroundIdeographsInComplexText();
    180183
    181184    CodePath codePath(const TextRun&) const;
  • trunk/Source/WebCore/platform/graphics/GlyphBuffer.h

    r58707 r76743  
    11/*
    2  * Copyright (C) 2006, 2009 Apple Inc. All rights reserved.
     2 * Copyright (C) 2006, 2009, 2011 Apple Inc. All rights reserved.
    33 * Copyright (C) 2007-2008 Torch Mobile Inc.
    44 *
     
    188188    }
    189189#endif
    190    
     190
     191    void expandLastAdvance(float width)
     192    {
     193        ASSERT(!isEmpty());
     194        GlyphBufferAdvance& lastAdvance = m_advances.last();
     195#if PLATFORM(CG) || (PLATFORM(WX) && OS(DARWIN))
     196        lastAdvance.width += width;
     197#elif OS(WINCE)
     198        lastAdvance += width;
     199#else
     200        lastAdvance += FloatSize(width, 0);
     201#endif
     202    }
     203
    191204private:
    192205    Vector<const SimpleFontData*, 2048> m_fontData;
  • trunk/Source/WebCore/platform/graphics/TextRun.h

    r72847 r76743  
    33 *           (C) 2000 Antti Koivisto (koivisto@kde.org)
    44 *           (C) 2000 Dirk Mueller (mueller@kde.org)
    5  * Copyright (C) 2003, 2006, 2007 Apple Computer, Inc.
     5 * Copyright (C) 2003, 2006, 2007, 2011 Apple Inc. All rights reserved.
    66 *
    77 * This library is free software; you can redistribute it and/or
     
    3434class TextRun {
    3535public:
    36     TextRun(const UChar* c, int len, bool allowTabs = false, int xpos = 0, int padding = 0, bool rtl = false, bool directionalOverride = false,
     36    enum TrailingExpansionBehavior {
     37        AllowTrailingExpansion,
     38        ForbidTrailingExpansion
     39    };
     40
     41    TextRun(const UChar* c, int len, bool allowTabs = false, int xpos = 0, int expansion = 0, TrailingExpansionBehavior trailingExpansionBehavior = AllowTrailingExpansion, bool rtl = false, bool directionalOverride = false,
    3742              bool applyRunRounding = true, bool applyWordRounding = true)
    3843        : m_characters(c)
    3944        , m_len(len)
    4045        , m_xpos(xpos)
    41         , m_padding(padding)
     46        , m_expansion(expansion)
     47        , m_trailingExpansionBehavior(trailingExpansionBehavior)
    4248#if ENABLE(SVG)
    4349        , m_horizontalGlyphStretch(1)
     
    5662    }
    5763
    58     TextRun(const String& s, bool allowTabs = false, int xpos = 0, int padding = 0, bool rtl = false, bool directionalOverride = false,
     64    TextRun(const String& s, bool allowTabs = false, int xpos = 0, int expansion = 0, TrailingExpansionBehavior trailingExpansionBehavior = AllowTrailingExpansion, bool rtl = false, bool directionalOverride = false,
    5965              bool applyRunRounding = true, bool applyWordRounding = true)
    6066        : m_characters(s.characters())
    6167        , m_len(s.length())
    6268        , m_xpos(xpos)
    63         , m_padding(padding)
     69        , m_expansion(expansion)
     70        , m_trailingExpansionBehavior(trailingExpansionBehavior)
    6471#if ENABLE(SVG)
    6572        , m_horizontalGlyphStretch(1)
     
    93100    bool allowTabs() const { return m_allowTabs; }
    94101    int xPos() const { return m_xpos; }
    95     int padding() const { return m_padding; }
     102    int expansion() const { return m_expansion; }
     103    bool allowsTrailingExpansion() const { return m_trailingExpansionBehavior == AllowTrailingExpansion; }
    96104    bool rtl() const { return m_rtl; }
    97105    bool ltr() const { return !m_rtl; }
     
    122130    // the text line is not the same as left start of the containing block.
    123131    int m_xpos; 
    124     int m_padding;
     132    int m_expansion;
     133    TrailingExpansionBehavior m_trailingExpansionBehavior;
    125134#if ENABLE(SVG)
    126135    float m_horizontalGlyphStretch;
  • trunk/Source/WebCore/platform/graphics/WidthIterator.cpp

    r76170 r76743  
    11/*
    2  * Copyright (C) 2003, 2006, 2008, 2009, 2010 Apple Inc. All rights reserved.
     2 * Copyright (C) 2003, 2006, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
    33 * Copyright (C) 2008 Holger Hans Peter Freyther
    44 *
     
    4848    , m_currentCharacter(0)
    4949    , m_runWidthSoFar(0)
     50    , m_isAfterExpansion(true)
    5051    , m_finalRoundingWidth(0)
    5152    , m_fallbackFonts(fallbackFonts)
     
    5960    // If the padding is non-zero, count the number of spaces in the run
    6061    // and divide that by the padding for per space addition.
    61     m_padding = m_run.padding();
    62     if (!m_padding)
    63         m_padPerSpace = 0;
     62    m_expansion = m_run.expansion();
     63    if (!m_expansion)
     64        m_expansionPerOpportunity = 0;
    6465    else {
    65         int numSpaces = 0;
    66         for (int i = 0; i < run.length(); i++) {
    67             if (Font::treatAsSpace(m_run[i]))
    68                 numSpaces++;
    69         }
    70 
    71         if (!numSpaces)
    72             m_padPerSpace = 0;
     66        bool isAfterExpansion = true;
     67        unsigned expansionOpportunityCount = Font::expansionOpportunityCount(m_run.characters(), m_end, isAfterExpansion);
     68        if (isAfterExpansion && !m_run.allowsTrailingExpansion())
     69            expansionOpportunityCount--;
     70
     71        if (!expansionOpportunityCount)
     72            m_expansionPerOpportunity = 0;
    7373        else
    74             m_padPerSpace = m_padding / numSpaces;
     74            m_expansionPerOpportunity = m_expansion / expansionOpportunityCount;
    7575    }
    7676}
     
    8585
    8686    bool rtl = m_run.rtl();
    87     bool hasExtraSpacing = (m_font->letterSpacing() || m_font->wordSpacing() || m_padding) && !m_run.spacingDisabled();
     87    bool hasExtraSpacing = (m_font->letterSpacing() || m_font->wordSpacing() || m_expansion) && !m_run.spacingDisabled();
    8888
    8989    float widthSinceLastRounding = m_runWidthSoFar;
     
    174174                width += m_font->letterSpacing();
    175175
    176             if (Font::treatAsSpace(c)) {
    177                 // Account for padding. WebCore uses space padding to justify text.
    178                 // We distribute the specified padding over the available spaces in the run.
    179                 if (m_padding) {
    180                     // Use left over padding if not evenly divisible by number of spaces.
    181                     if (m_padding < m_padPerSpace) {
    182                         width += m_padding;
    183                         m_padding = 0;
    184                     } else {
    185                         float previousPadding = m_padding;
    186                         m_padding -= m_padPerSpace;
    187                         width += roundf(previousPadding) - roundf(m_padding);
     176            static bool expandAroundIdeographs = Font::canExpandAroundIdeographsInComplexText();
     177            bool treatAsSpace = Font::treatAsSpace(c);
     178            if (treatAsSpace || (expandAroundIdeographs && Font::isCJKIdeograph(c))) {
     179                // Distribute the run's total expansion evenly over all expansion opportunities in the run.
     180                if (m_expansion && (m_run.allowsTrailingExpansion() || currentCharacter + clusterLength < static_cast<size_t>(m_run.length()))) {
     181                    float previousExpansion = m_expansion;
     182                    if (!treatAsSpace && !m_isAfterExpansion) {
     183                        // Take the expansion opportunity before this ideograph.
     184                        m_expansion -= m_expansionPerOpportunity;
     185                        int expansion = roundf(previousExpansion) - roundf(m_expansion);
     186                        m_runWidthSoFar += expansion;
     187                        if (glyphBuffer)
     188                            glyphBuffer->expandLastAdvance(expansion);
     189                        previousExpansion = m_expansion;
    188190                    }
    189                 }
     191                    m_expansion -= m_expansionPerOpportunity;
     192                    width += roundf(previousExpansion) - roundf(m_expansion);
     193                    m_isAfterExpansion = true;
     194                } else
     195                    m_isAfterExpansion = false;
    190196
    191197                // Account for word spacing.
    192198                // We apply additional space between "words" by adding width to the space character.
    193                 if (currentCharacter != 0 && !Font::treatAsSpace(cp[-1]) && m_font->wordSpacing())
     199                if (treatAsSpace && currentCharacter && !Font::treatAsSpace(cp[-1]) && m_font->wordSpacing())
    194200                    width += m_font->wordSpacing();
    195             }
     201            } else
     202                m_isAfterExpansion = false;
    196203        }
    197204
     
    261268bool WidthIterator::advanceOneCharacter(float& width, GlyphBuffer* glyphBuffer)
    262269{
    263     glyphBuffer->clear();
     270    int oldSize = glyphBuffer->size();
    264271    advance(m_currentCharacter + 1, glyphBuffer);
    265272    float w = 0;
    266     for (int i = 0; i < glyphBuffer->size(); ++i)
     273    for (int i = oldSize; i < glyphBuffer->size(); ++i)
    267274        w += glyphBuffer->advanceAt(i);
    268275    width = w;
    269     return !glyphBuffer->isEmpty();
     276    return glyphBuffer->size() > oldSize;
    270277}
    271278
  • trunk/Source/WebCore/platform/graphics/WidthIterator.h

    r74169 r76743  
    11/*
    2  * Copyright (C) 2003, 2006, 2008 Apple Inc. All rights reserved.
     2 * Copyright (C) 2003, 2006, 2008, 2011 Apple Inc. All rights reserved.
    33 * Copyright (C) 2008 Holger Hans Peter Freyther
    44 *
     
    5151    unsigned m_currentCharacter;
    5252    float m_runWidthSoFar;
    53     float m_padding;
    54     float m_padPerSpace;
     53    float m_expansion;
     54    float m_expansionPerOpportunity;
     55    bool m_isAfterExpansion;
    5556    float m_finalRoundingWidth;
    5657
  • trunk/Source/WebCore/platform/graphics/chromium/FontChromiumWin.cpp

    r76442 r76743  
    370370}
    371371
     372bool Font::canExpandAroundIdeographsInComplexText()
     373{
     374    return false;
     375}
     376
    372377void Font::drawGlyphs(GraphicsContext* graphicsContext,
    373378                      const SimpleFontData* font,
  • trunk/Source/WebCore/platform/graphics/chromium/FontLinux.cpp

    r76137 r76743  
    5656}
    5757
     58bool Font::canExpandAroundIdeographsInComplexText()
     59{
     60    return false;
     61}
     62
    5863static bool isCanvasMultiLayered(SkCanvas* canvas)
    5964{
     
    205210    controller.setWordSpacingAdjustment(wordSpacing());
    206211    controller.setLetterSpacingAdjustment(letterSpacing());
    207     controller.setPadding(run.padding());
     212    controller.setPadding(run.expansion());
    208213
    209214    if (run.rtl()) {
     
    214219        // We need to set the padding again because ComplexTextController layout consumed the value.
    215220        // Fixing the above problem would help here too.
    216         controller.setPadding(run.padding());
     221        controller.setPadding(run.expansion());
    217222    }
    218223
     
    242247    controller.setWordSpacingAdjustment(wordSpacing());
    243248    controller.setLetterSpacingAdjustment(letterSpacing());
    244     controller.setPadding(run.padding());
     249    controller.setPadding(run.expansion());
    245250    return controller.widthOfFullRun();
    246251}
     
    276281    controller.setWordSpacingAdjustment(wordSpacing());
    277282    controller.setLetterSpacingAdjustment(letterSpacing());
    278     controller.setPadding(run.padding());
     283    controller.setPadding(run.expansion());
    279284    if (run.rtl()) {
    280285        // See FIXME in drawComplexText.
    281286        controller.reset(controller.widthOfFullRun());
    282         controller.setPadding(run.padding());
     287        controller.setPadding(run.expansion());
    283288    }
    284289
     
    327332    controller.setWordSpacingAdjustment(wordSpacing());
    328333    controller.setLetterSpacingAdjustment(letterSpacing());
    329     controller.setPadding(run.padding());
     334    controller.setPadding(run.expansion());
    330335    if (run.rtl()) {
    331336        // See FIXME in drawComplexText.
    332337        controller.reset(controller.widthOfFullRun());
    333         controller.setPadding(run.padding());
     338        controller.setPadding(run.expansion());
    334339    }
    335340
  • trunk/Source/WebCore/platform/graphics/chromium/UniscribeHelperTextRun.cpp

    r76443 r76743  
    5656    init();
    5757
    58     // Padding is the amount to add to make justification happen. This
     58    // Expansion is the amount to add to make justification happen. This
    5959    // should be done after Init() so all the runs are already measured.
    60     if (run.padding() > 0)
    61         justify(run.padding());
     60    if (run.expansion() > 0)
     61        justify(run.expansion());
    6262}
    6363
  • trunk/Source/WebCore/platform/graphics/efl/FontEfl.cpp

    r74169 r76743  
    5151}
    5252
     53bool Font::canExpandAroundIdeographsInComplexText()
     54{
     55    return false;
     56}
     57
    5358float Font::floatWidthForComplexText(const TextRun&, HashSet<const SimpleFontData*>*, GlyphOverflow*) const
    5459{
  • trunk/Source/WebCore/platform/graphics/gtk/FontGtk.cpp

    r76170 r76743  
    216216}
    217217
     218bool Font::canExpandAroundIdeographsInComplexText()
     219{
     220    return false;
     221}
     222
    218223static void drawGlyphsShadow(GraphicsContext* graphicsContext, cairo_t* context, const FloatPoint& point, PangoLayoutLine* layoutLine, PangoRegionType renderRegion)
    219224{
  • trunk/Source/WebCore/platform/graphics/haiku/FontHaiku.cpp

    r74169 r76743  
    6666}
    6767
     68bool Font::canExpandAroundIdeographsInComplexText()
     69{
     70    return false;
     71}
     72
    6873void Font::drawGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* font,
    6974                      const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point) const
  • trunk/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp

    r76676 r76743  
    11/*
    2  * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
     2 * Copyright (C) 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    7272    , m_characterInCurrentGlyph(0)
    7373    , m_finalRoundingWidth(0)
    74     , m_padding(run.padding())
     74    , m_expansion(run.expansion())
     75    , m_afterExpansion(true)
    7576    , m_fallbackFonts(fallbackFonts)
    7677    , m_minGlyphBoundingBoxX(numeric_limits<float>::max())
     
    8081    , m_lastRoundingGlyph(0)
    8182{
    82     if (!m_padding)
    83         m_padPerSpace = 0;
     83    if (!m_expansion)
     84        m_expansionPerOpportunity = 0;
    8485    else {
    85         int numSpaces = 0;
    86         for (int s = 0; s < m_run.length(); s++) {
    87             if (Font::treatAsSpace(m_run[s]))
    88                 numSpaces++;
    89         }
    90 
    91         if (!numSpaces)
    92             m_padPerSpace = 0;
     86        bool isAfterExpansion = true;
     87        unsigned expansionOpportunityCount = Font::expansionOpportunityCount(m_run.characters(), m_end, isAfterExpansion);
     88        if (isAfterExpansion && !m_run.allowsTrailingExpansion())
     89            expansionOpportunityCount--;
     90
     91        if (!expansionOpportunityCount)
     92            m_expansionPerOpportunity = 0;
    9393        else
    94             m_padPerSpace = m_padding / numSpaces;
     94            m_expansionPerOpportunity = m_expansion / expansionOpportunityCount;
    9595    }
    9696
     
    423423    CGFloat widthSinceLastRounding = 0;
    424424    size_t runCount = m_complexTextRuns.size();
     425    bool hasExtraSpacing = (m_font.letterSpacing() || m_font.wordSpacing() || m_expansion) && !m_run.spacingDisabled();
    425426    for (size_t r = 0; r < runCount; ++r) {
    426427        ComplexTextRun& complexTextRun = *m_complexTextRuns[r];
     
    435436        CGFloat roundedSpaceWidth = roundCGFloat(fontData->spaceWidth());
    436437        bool roundsAdvances = !m_font.isPrinterFont() && fontData->platformData().roundsGlyphAdvances();
    437         bool hasExtraSpacing = (m_font.letterSpacing() || m_font.wordSpacing() || m_padding) && !m_run.spacingDisabled();
    438438        CGPoint glyphOrigin = CGPointZero;
    439439        CFIndex lastCharacterIndex = m_run.ltr() ? numeric_limits<CFIndex>::min() : numeric_limits<CFIndex>::max();
     
    491491
    492492                // Handle justification and word-spacing.
    493                 if (treatAsSpace) {
    494                     // Account for padding. WebCore uses space padding to justify text.
    495                     // We distribute the specified padding over the available spaces in the run.
    496                     if (m_padding) {
    497                         // Use leftover padding if not evenly divisible by number of spaces.
    498                         if (m_padding < m_padPerSpace) {
    499                             advance.width += m_padding;
    500                             m_padding = 0;
    501                         } else {
    502                             float previousPadding = m_padding;
    503                             m_padding -= m_padPerSpace;
    504                             advance.width += roundf(previousPadding) - roundf(m_padding);
     493                if (treatAsSpace || Font::isCJKIdeograph(ch)) {
     494                    // Distribute the run's total expansion evenly over all expansion opportunities in the run.
     495                    if (m_expansion && (!lastGlyph || m_run.allowsTrailingExpansion())) {
     496                        float previousExpansion = m_expansion;
     497                        if (!treatAsSpace && !m_afterExpansion) {
     498                            // Take the expansion opportunity before this ideograph.
     499                            m_expansion -= m_expansionPerOpportunity;
     500                            int expansion = roundf(previousExpansion) - roundf(m_expansion);
     501                            m_totalWidth += expansion;
     502                            m_adjustedAdvances.last().width += expansion;
     503                            previousExpansion = m_expansion;
    505504                        }
    506                     }
     505                        m_expansion -= m_expansionPerOpportunity;
     506                        advance.width += roundf(previousExpansion) - roundf(m_expansion);
     507                        m_afterExpansion = true;
     508                    } else
     509                        m_afterExpansion = false;
    507510
    508511                    // Account for word-spacing.
    509                     if (characterIndex > 0 && !Font::treatAsSpace(*m_run.data(characterIndex - 1)) && m_font.wordSpacing())
     512                    if (treatAsSpace && characterIndex > 0 && !Font::treatAsSpace(*m_run.data(characterIndex - 1)) && m_font.wordSpacing())
    510513                        advance.width += m_font.wordSpacing();
    511                 }
     514                } else
     515                    m_afterExpansion = false;
    512516            }
    513517
  • trunk/Source/WebCore/platform/graphics/mac/ComplexTextController.h

    r76674 r76743  
    11/*
    2  * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
     2 * Copyright (C) 2007, 2008, 2009, 2011 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    178178    unsigned m_characterInCurrentGlyph;
    179179    float m_finalRoundingWidth;
    180     float m_padding;
    181     float m_padPerSpace;
     180    float m_expansion;
     181    float m_expansionPerOpportunity;
     182    bool m_afterExpansion;
    182183
    183184    HashSet<const SimpleFontData*>* m_fallbackFonts;
  • trunk/Source/WebCore/platform/graphics/mac/FontMac.mm

    r76442 r76743  
    4848}
    4949
     50bool Font::canExpandAroundIdeographsInComplexText()
     51{
     52    return true;
     53}
     54
    5055static void showGlyphsWithAdvances(const SimpleFontData* font, CGContextRef context, const CGGlyph* glyphs, const CGSize* advances, size_t count)
    5156{
  • trunk/Source/WebCore/platform/graphics/qt/FontQt.cpp

    r76170 r76743  
    6262{
    6363    int flags = style.rtl() ? Qt::TextForceRightToLeft : Qt::TextForceLeftToRight;
    64     if (style.padding())
     64    if (style.expansion())
    6565        flags |= Qt::TextJustificationForced;
    6666    layout->setFlags(flags);
     
    6868    QTextLine line = layout->createLine();
    6969    line.setLineWidth(INT_MAX/256);
    70     if (style.padding())
    71         line.setLineWidth(line.naturalTextWidth() + style.padding());
     70    if (style.expansion())
     71        line.setLineWidth(line.naturalTextWidth() + style.expansion());
    7272    layout->endLayout();
    7373    return line;
     
    197197                p->setPen(ctxShadow->m_color);
    198198                p->translate(ctxShadow->offset());
    199                 p->drawText(pt, string, flags, run.padding());
     199                p->drawText(pt, string, flags, run.expansion());
    200200                p->restore();
    201201            } else {
     
    211211                    shadowPainter->setFont(p->font());
    212212                    shadowPainter->setPen(ctxShadow->m_color);
    213                     shadowPainter->drawText(pt, string, flags, run.padding());
     213                    shadowPainter->drawText(pt, string, flags, run.expansion());
    214214                    ctxShadow->endShadowLayer(ctx);
    215215                }
     
    244244        QPen previousPen = p->pen();
    245245        p->setPen(textFillPen);
    246         p->drawText(pt, string, flags, run.padding());
     246        p->drawText(pt, string, flags, run.expansion());
    247247        p->setPen(previousPen);
    248248    }
     
    309309        w -= m_wordSpacing;
    310310
    311     return w + run.padding();
     311    return w + run.expansion();
    312312#else
    313313    Q_ASSERT(false);
     
    325325
    326326    if (run.length() == 1 && treatAsSpace(run[0]))
    327         return QFontMetrics(font()).width(space) + run.padding();
     327        return QFontMetrics(font()).width(space) + run.expansion();
    328328
    329329    String sanitized = Font::normalizeSpaces(String(run.characters(), run.length()));
     
    335335        w -= m_wordSpacing;
    336336
    337     return w + run.padding();
     337    return w + run.expansion();
    338338}
    339339
     
    414414}
    415415
     416bool Font::canExpandAroundIdeographsInComplexText()
     417{
     418    return false;
     419}
     420
    416421bool Font::primaryFontHasGlyphForCharacter(UChar32) const
    417422{
  • trunk/Source/WebCore/platform/graphics/win/FontWin.cpp

    r76442 r76743  
    4444{
    4545    return true;
     46}
     47
     48bool Font::canExpandAroundIdeographsInComplexText()
     49{
     50    return false;
    4651}
    4752
  • trunk/Source/WebCore/platform/graphics/win/UniscribeController.cpp

    r76170 r76743  
    5050    , m_currentCharacter(0)
    5151    , m_runWidthSoFar(0)
    52     , m_padding(run.padding())
     52    , m_padding(run.expansion())
    5353    , m_computingOffsetPosition(false)
    5454    , m_includePartialGlyphs(false)
  • trunk/Source/WebCore/platform/graphics/wince/FontWinCE.cpp

    r76282 r76743  
    113113    int letterSpacing = font.letterSpacing();
    114114    int wordSpacing = font.wordSpacing();
    115     int padding = run.padding();
     115    int padding = run.expansion();
    116116    int numSpaces = 0;
    117117    if (padding) {
     
    341341}
    342342
     343bool Font::canExpandAroundIdeographsInComplexText()
     344{
     345    return false;
     346}
     347
    343348} // namespace WebCore
  • trunk/Source/WebCore/platform/graphics/wx/FontWx.cpp

    r74169 r76743  
    5252{
    5353#if OS(WINDOWS) || OS(DARWIN)
     54    return true;
     55#else
     56    return false;
     57#endif
     58}
     59
     60bool Font::canExpandAroundIdeographsInComplexText()
     61{
     62#if OS(DARWIN)
    5463    return true;
    5564#else
  • trunk/Source/WebCore/platform/win/PopupMenuWin.cpp

    r76442 r76743  
    633633        unsigned length = itemText.length();
    634634        const UChar* string = itemText.characters();
    635         TextRun textRun(string, length, false, 0, 0, itemText.defaultWritingDirection() == WTF::Unicode::RightToLeft);
     635        TextRun textRun(string, length, false, 0, 0, TextRun::AllowTrailingExpansion, itemText.defaultWritingDirection() == WTF::Unicode::RightToLeft);
    636636
    637637        context.setFillColor(optionTextColor, ColorSpaceDeviceRGB);
  • trunk/Source/WebCore/rendering/EllipsisBox.cpp

    r76442 r76743  
    5454
    5555    const String& str = m_str;
    56     context->drawText(style->font(), TextRun(str.characters(), str.length(), false, 0, 0, false, style->visuallyOrdered()), IntPoint(m_x + tx, m_y + ty + style->fontMetrics().ascent()));
     56    context->drawText(style->font(), TextRun(str.characters(), str.length(), false, 0, 0, TextRun::AllowTrailingExpansion, false, style->visuallyOrdered()), IntPoint(m_x + tx, m_y + ty + style->fontMetrics().ascent()));
    5757
    5858    // Restore the regular fill color.
     
    7575    RenderStyle* style = m_renderer->style(m_firstLine);
    7676    const Font& f = style->font();
    77     return enclosingIntRect(f.selectionRectForText(TextRun(m_str.characters(), m_str.length(), false, 0, 0, false, style->visuallyOrdered()),
     77    return enclosingIntRect(f.selectionRectForText(TextRun(m_str.characters(), m_str.length(), false, 0, 0, TextRun::AllowTrailingExpansion, false, style->visuallyOrdered()),
    7878            IntPoint(m_x + tx, m_y + ty + root()->selectionTop()), root()->selectionHeight()));
    7979}
     
    9595    int h = root()->selectionHeight();
    9696    context->clip(IntRect(m_x + tx, y + ty, m_logicalWidth, h));
    97     context->drawHighlightForText(font, TextRun(m_str.characters(), m_str.length(), false, 0, 0, false, style->visuallyOrdered()),
     97    context->drawHighlightForText(font, TextRun(m_str.characters(), m_str.length(), false, 0, 0, TextRun::AllowTrailingExpansion, false, style->visuallyOrdered()),
    9898        IntPoint(m_x + tx, m_y + ty + y), h, c, style->colorSpace());
    9999    context->restore();
  • trunk/Source/WebCore/rendering/InlineBox.h

    r74145 r76743  
    11/*
    2  * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
     2 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009, 2010, 2011 Apple Inc. All rights reserved.
    33 *
    44 * This library is free software; you can redistribute it and/or
     
    6262        , m_nextOnLineExists(false)
    6363        , m_prevOnLineExists(false)
    64         , m_toAdd(0)
     64        , m_expansion(0)
    6565#ifndef NDEBUG
    6666        , m_hasBadParent(false)
     
    9696        , m_nextOnLineExists(false)
    9797        , m_prevOnLineExists(false)
    98         , m_toAdd(0)
     98        , m_expansion(0)
    9999#ifndef NDEBUG
    100100        , m_hasBadParent(false)
     
    291291    void setHasBadParent();
    292292
    293     int toAdd() const { return m_toAdd; }
     293    int expansion() const { return m_expansion; }
    294294   
    295295    bool visibleToHitTesting() const { return renderer()->style()->visibility() == VISIBLE && renderer()->style()->pointerEvents() != PE_NONE; }
     
    349349    mutable bool m_nextOnLineExists : 1;
    350350    mutable bool m_prevOnLineExists : 1;
    351     int m_toAdd : 11; // for justified text
     351    int m_expansion : 11; // for justified text
    352352
    353353#ifndef NDEBUG
  • trunk/Source/WebCore/rendering/InlineTextBox.cpp

    r76442 r76743  
    22 * (C) 1999 Lars Knoll (knoll@kde.org)
    33 * (C) 2000 Dirk Mueller (mueller@kde.org)
    4  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
     4 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
    55 *
    66 * This library is free software; you can redistribute it and/or
     
    4141#include "RenderTheme.h"
    4242#include "Text.h"
    43 #include "TextRun.h"
    4443#include "break_lines.h"
    4544#include <wtf/AlwaysInline.h>
     
    164163    }
    165164
    166     IntRect r = enclosingIntRect(f.selectionRectForText(TextRun(characters, len, textObj->allowTabs(), textPos(), m_toAdd, !isLeftToRightDirection(), m_dirOverride),
     165    IntRect r = enclosingIntRect(f.selectionRectForText(TextRun(characters, len, textObj->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(), !isLeftToRightDirection(), m_dirOverride),
    167166                                                        IntPoint(), selHeight, sPos, ePos));
    168167                                                       
     
    609608        adjustCharactersAndLengthForHyphen(charactersWithHyphen, styleToUse, characters, length);
    610609
    611     TextRun textRun(characters, length, textRenderer()->allowTabs(), textPos(), m_toAdd, !isLeftToRightDirection(), m_dirOverride || styleToUse->visuallyOrdered());
     610    TextRun textRun(characters, length, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(), !isLeftToRightDirection(), m_dirOverride || styleToUse->visuallyOrdered());
    612611
    613612    int sPos = 0;
     
    763762    IntPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY);
    764763    context->clip(IntRect(localOrigin, IntSize(m_logicalWidth, selHeight)));
    765     context->drawHighlightForText(font, TextRun(characters, length, textRenderer()->allowTabs(), textPos(), m_toAdd,
     764    context->drawHighlightForText(font, TextRun(characters, length, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(),
    766765                                  !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered()),
    767766                                  localOrigin, selHeight, c, style->colorSpace(), sPos, ePos);
     
    787786    int selHeight = selectionHeight();
    788787    IntPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY);
    789     context->drawHighlightForText(font, TextRun(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd,
     788    context->drawHighlightForText(font, TextRun(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(),
    790789                                  !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered()),
    791790                                  localOrigin, selHeight, c, style->colorSpace(), sPos, ePos);
     
    949948        int selHeight = selectionHeight();
    950949        IntPoint startPoint(boxOrigin.x(), boxOrigin.y() - deltaY);
    951         TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered());
     950        TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(), !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered());
    952951         
    953952        IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, startPoint, selHeight, startPosition, endPosition));
     
    993992    int sPos = max(marker.startOffset - m_start, (unsigned)0);
    994993    int ePos = min(marker.endOffset - m_start, (unsigned)m_len);   
    995     TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered());
     994    TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(), !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered());
    996995   
    997996    // Always compute and store the rect associated with this marker. The computed rect is in absolute coordinates.
     
    10211020    int sPos = max(marker.startOffset - m_start, (unsigned)0);
    10221021    int ePos = min(marker.endOffset - m_start, (unsigned)m_len);   
    1023     TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered());
     1022    TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(), !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered());
    10241023    IntPoint startPoint = IntPoint(m_x, y);
    10251024   
     
    11861185    const Font* f = &style->font();
    11871186    int offset = f->offsetForPosition(TextRun(textRenderer()->text()->characters() + m_start, m_len,
    1188         textRenderer()->allowTabs(), textPos(), m_toAdd, !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered()),
     1187        textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(), !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered()),
    11891188        lineOffset - logicalLeft(), includePartialGlyphs);
    11901189    if (blockIsInOppositeDirection && (!offset || offset == m_len))
     
    12061205    int to = !isLeftToRightDirection() ? m_len : offset - m_start;
    12071206    // FIXME: Do we need to add rightBearing here?
    1208     return enclosingIntRect(f.selectionRectForText(TextRun(text->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, !isLeftToRightDirection(), m_dirOverride),
     1207    return enclosingIntRect(f.selectionRectForText(TextRun(text->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(), !isLeftToRightDirection(), m_dirOverride),
    12091208                                                   IntPoint(logicalLeft(), 0), 0, from, to)).right();
    12101209}
  • trunk/Source/WebCore/rendering/InlineTextBox.h

    r76726 r76743  
    22 * (C) 1999 Lars Knoll (knoll@kde.org)
    33 * (C) 2000 Dirk Mueller (mueller@kde.org)
    4  * Copyright (C) 2004, 2005, 2006, 2009 Apple Inc. All rights reserved.
     4 * Copyright (C) 2004, 2005, 2006, 2009, 2010, 2011 Apple Inc. All rights reserved.
    55 *
    66 * This library is free software; you can redistribute it and/or
     
    2626#include "InlineBox.h"
    2727#include "RenderText.h" // so textRenderer() can be inline
     28#include "TextRun.h"
    2829
    2930namespace WebCore {
     
    110111    virtual bool isLineBreak() const;
    111112
    112     void setSpaceAdd(int add) { m_logicalWidth -= m_toAdd; m_toAdd = add; m_logicalWidth += m_toAdd; }
     113    void setExpansion(int expansion) { m_logicalWidth -= m_expansion; m_expansion = expansion; m_logicalWidth += m_expansion; }
    113114
    114115private:
     
    157158    void paintTextMatchMarker(GraphicsContext*, const IntPoint& boxOrigin, const DocumentMarker&, RenderStyle*, const Font&);
    158159    void computeRectForReplacementMarker(const DocumentMarker&, RenderStyle*, const Font&);
     160
     161    TextRun::TrailingExpansionBehavior trailingExpansionBehavior() const { return m_expansion && nextLeafChild() ? TextRun::AllowTrailingExpansion : TextRun::ForbidTrailingExpansion; }
    159162};
    160163
  • trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp

    r76726 r76743  
    11/*
    22 * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
    3  * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010 Apple Inc. All right reserved.
     3 * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All right reserved.
    44 * Copyright (C) 2010 Google Inc. All rights reserved.
    55 *
     
    311311    int totalLogicalWidth = lineBox->getFlowSpacingLogicalWidth();
    312312    bool needsWordSpacing = false;
    313     unsigned numSpaces = 0;
     313    unsigned expansionOpportunityCount = 0;
     314    bool isAfterExpansion = true;
     315    Vector<unsigned, 16> expansionOpportunities;
    314316    ETextAlign textAlign = style()->textAlign();
    315317
     
    323325
    324326            if (textAlign == JUSTIFY && r != trailingSpaceRun) {
    325                 const UChar* characters = rt->characters();
    326                 for (int i = r->m_start; i < r->m_stop; i++) {
    327                     UChar c = characters[i];
    328                     if (Font::treatAsSpace(c))
    329                         numSpaces++;
    330                 }
     327                unsigned opportunitiesInRun = Font::expansionOpportunityCount(rt->characters() + r->m_start, r->m_stop - r->m_start, isAfterExpansion);
     328                expansionOpportunities.append(opportunitiesInRun);
     329                expansionOpportunityCount += opportunitiesInRun;
    331330            }
    332331
     
    355354                it->second.second = glyphOverflow;
    356355            }
    357         } else if (!r->m_object->isRenderInline()) {
    358             RenderBox* renderBox = toRenderBox(r->m_object);
    359             renderBox->computeLogicalWidth();
    360             r->m_box->setLogicalWidth(logicalWidthForChild(renderBox));
    361             totalLogicalWidth += marginStartForChild(renderBox) + marginEndForChild(renderBox);
     356        } else {
     357            isAfterExpansion = false;
     358            if (!r->m_object->isRenderInline()) {
     359                RenderBox* renderBox = toRenderBox(r->m_object);
     360                renderBox->computeLogicalWidth();
     361                r->m_box->setLogicalWidth(logicalWidthForChild(renderBox));
     362                totalLogicalWidth += marginStartForChild(renderBox) + marginEndForChild(renderBox);
     363            }
    362364        }
    363365
    364366        totalLogicalWidth += r->m_box->logicalWidth();
     367    }
     368
     369    if (isAfterExpansion && !expansionOpportunities.isEmpty()) {
     370        expansionOpportunities.last()--;
     371        expansionOpportunityCount--;
    365372    }
    366373
     
    386393            break;
    387394        case JUSTIFY:
    388             if (numSpaces && !reachedEnd && !lineBox->endsWithBreak()) {
     395            if (expansionOpportunityCount && !reachedEnd && !lineBox->endsWithBreak()) {
    389396                if (trailingSpaceRun) {
    390397                    totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth();
     
    395402            // fall through
    396403        case TAAUTO:
    397             numSpaces = 0;
     404            expansionOpportunityCount = 0;
    398405            // for right to left fall through to right aligned
    399406            if (style()->isLeftToRightDirection()) {
     
    437444    }
    438445
    439     if (numSpaces) {
     446    if (expansionOpportunityCount) {
     447        size_t i = 0;
    440448        for (BidiRun* r = firstRun; r; r = r->next()) {
    441449            if (!r->m_box || r == trailingSpaceRun)
    442450                continue;
    443451
    444             int spaceAdd = 0;
    445452            if (r->m_object->isText()) {
    446                 unsigned spaces = 0;
    447                 const UChar* characters = toRenderText(r->m_object)->characters();
    448                 for (int i = r->m_start; i < r->m_stop; i++) {
    449                     UChar c = characters[i];
    450                     if (Font::treatAsSpace(c))
    451                         spaces++;
    452                 }
    453 
    454                 ASSERT(spaces <= numSpaces);
     453                unsigned opportunitiesInRun = expansionOpportunities[i++];
     454
     455                ASSERT(opportunitiesInRun <= expansionOpportunityCount);
    455456
    456457                // Only justify text if whitespace is collapsed.
    457458                if (r->m_object->style()->collapseWhiteSpace()) {
    458                     spaceAdd = (availableLogicalWidth - totalLogicalWidth) * spaces / numSpaces;
    459                     static_cast<InlineTextBox*>(r->m_box)->setSpaceAdd(spaceAdd);
    460                     totalLogicalWidth += spaceAdd;
    461                 }
    462                 numSpaces -= spaces;
    463                 if (!numSpaces)
     459                    InlineTextBox* textBox = static_cast<InlineTextBox*>(r->m_box);
     460                    int expansion = (availableLogicalWidth - totalLogicalWidth) * opportunitiesInRun / expansionOpportunityCount;
     461                    textBox->setExpansion(expansion);
     462                    totalLogicalWidth += expansion;
     463                }
     464                expansionOpportunityCount -= opportunitiesInRun;
     465                if (!expansionOpportunityCount)
    464466                    break;
    465467            }
  • trunk/Source/WebCore/rendering/RenderFileUploadControl.cpp

    r76170 r76743  
    217217        unsigned length = displayedFilename.length();
    218218        const UChar* string = displayedFilename.characters();
    219         TextRun textRun(string, length, false, 0, 0, !style()->isLeftToRightDirection(), style()->unicodeBidi() == Override);
     219        TextRun textRun(string, length, false, 0, 0, TextRun::AllowTrailingExpansion, !style()->isLeftToRightDirection(), style()->unicodeBidi() == Override);
    220220       
    221221        // Determine where the filename should be placed
     
    274274        // (using "0" as the nominal character).
    275275        const UChar ch = '0';
    276         float charWidth = style()->font().floatWidth(TextRun(&ch, 1, false, 0, 0, false, false, false));
     276        float charWidth = style()->font().floatWidth(TextRun(&ch, 1, false, 0, 0, TextRun::AllowTrailingExpansion, false, false, false));
    277277        m_maxPreferredLogicalWidth = (int)ceilf(charWidth * defaultWidthNumChars);
    278278    }
  • trunk/Source/WebCore/rendering/RenderListBox.cpp

    r76442 r76743  
    113113               
    114114            if (!text.isEmpty()) {
    115                 float textWidth = itemFont.floatWidth(TextRun(text.impl(), 0, 0, 0, false, false, false, false));
     115                float textWidth = itemFont.floatWidth(TextRun(text.impl(), false, 0, 0, TextRun::AllowTrailingExpansion, false, false, false, false));
    116116                width = max(width, textWidth);
    117117            }
     
    332332    unsigned length = itemText.length();
    333333    const UChar* string = itemText.characters();
    334     TextRun textRun(string, length, 0, 0, 0, !itemStyle->isLeftToRightDirection(), itemStyle->unicodeBidi() == Override, false, false);
     334    TextRun textRun(string, length, false, 0, 0, TextRun::AllowTrailingExpansion, !itemStyle->isLeftToRightDirection(), itemStyle->unicodeBidi() == Override, false, false);
    335335
    336336    // Draw the item text
  • trunk/Source/WebCore/rendering/RenderTextControl.cpp

    r76442 r76743  
    545545
    546546    const UChar ch = '0';
    547     return style()->font().floatWidth(TextRun(&ch, 1, false, 0, 0, false, false, false));
     547    return style()->font().floatWidth(TextRun(&ch, 1, false, 0, 0, TextRun::AllowTrailingExpansion, false, false, false));
    548548}
    549549
     
    640640   
    641641    String placeholderText = static_cast<HTMLTextFormControlElement*>(node())->strippedPlaceholder();
    642     TextRun textRun(placeholderText.characters(), placeholderText.length(), 0, 0, 0, !placeholderStyle->isLeftToRightDirection(), placeholderStyle->unicodeBidi() == Override, false, false);
     642    TextRun textRun(placeholderText.characters(), placeholderText.length(), false, 0, 0, TextRun::AllowTrailingExpansion, !placeholderStyle->isLeftToRightDirection(), placeholderStyle->unicodeBidi() == Override, false, false);
    643643   
    644644    RenderBox* textRenderer = innerTextElement() ? innerTextElement()->renderBox() : 0;
  • trunk/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp

    r76442 r76743  
    365365                , 0 /* xPos, only relevant with allowTabs=true */
    366366                , 0 /* padding, only relevant for justified text, not relevant for SVG */
     367                , TextRun::AllowTrailingExpansion
    367368                , direction() == RTL
    368369                , m_dirOverride || style->visuallyOrdered() /* directionalOverride */);
  • trunk/Source/WebKit/chromium/ChangeLog

    r76717 r76743  
     12011-01-26  Dan Bernstein  <mitz@apple.com>
     2
     3        Reviewed by Dave Hyatt.
     4
     5        <rdar://problem/8446709> Allow inter-ideograph justification for CJK
     6        https://bugs.webkit.org/show_bug.cgi?id=53184
     7
     8        * src/WebTextRun.cpp:
     9        (WebKit::WebTextRun::operator WebCore::TextRun): Added a TrailingExpansionBehavior parameter to the
     10        RenderText constructor.
     11
    1122011-01-26  Kenneth Russell  <kbr@google.com>
    213
  • trunk/Source/WebKit/chromium/src/WebTextRun.cpp

    r64160 r76743  
    4040WebTextRun::operator WebCore::TextRun() const
    4141{
    42     return TextRun(text, false, 0, 0, rtl, directionalOverride);
     42    return TextRun(text, false, 0, 0, TextRun::AllowTrailingExpansion, rtl, directionalOverride);
    4343}
    4444
  • trunk/Source/WebKit2/ChangeLog

    r76742 r76743  
     12011-01-26  Dan Bernstein  <mitz@apple.com>
     2
     3        Reviewed by Dave Hyatt.
     4
     5        <rdar://problem/8446709> Allow inter-ideograph justification for CJK
     6        https://bugs.webkit.org/show_bug.cgi?id=53184
     7
     8        * WebProcess/WebCoreSupport/win/WebPopupMenuWin.cpp:
     9        (WebKit::WebPopupMenu::setUpPlatformData): Added a TrailingExpansionBehavior parameter to the
     10        RenderText constructor.
     11
    1122011-01-26  Jing Jin  <jjin@apple.com>
    213
  • trunk/Source/WebKit2/WebProcess/WebCoreSupport/win/WebPopupMenuWin.cpp

    r76442 r76743  
    116116        unsigned length = itemText.length();
    117117        const UChar* string = itemText.characters();
    118         TextRun textRun(string, length, false, 0, 0, itemText.defaultWritingDirection() == WTF::Unicode::RightToLeft);
     118        TextRun textRun(string, length, false, 0, 0, TextRun::AllowTrailingExpansion, itemText.defaultWritingDirection() == WTF::Unicode::RightToLeft);
    119119
    120120        notSelectedBackingStoreContext->setFillColor(optionTextColor, ColorSpaceDeviceRGB);
Note: See TracChangeset for help on using the changeset viewer.