Changeset 203714 in webkit


Ignore:
Timestamp:
Jul 26, 2016 12:46:58 AM (8 years ago)
Author:
fred.wang@free.fr
Message:

MathOperator: Add a mapping from combining to non-combining equivalents
https://bugs.webkit.org/show_bug.cgi?id=159513

Patch by Frederic Wang <fwang@igalia.com> on 2016-07-25
Reviewed by Darin Adler.

Source/WebCore:

Many math fonts provide stretch variants and assemblies for combining characters but not for
their non-combining equivalent. In the MathML recommendation, it is suggested to use
non-combining charaters, so we allow the operator stretching code to look for constructions
associated to these non-combining characters in order to still be able to stretch the
combining ones.

Test: mathml/presentation/bug159513.html

  • rendering/mathml/MathOperator.cpp:

(WebCore::MathOperator::getGlyph): New function extending getBaseGlyph to retrieve the glyph
data for an arbitrary character.
(WebCore::MathOperator::getMathVariantsWithFallback): This helper function calls
getMathVariants for the base glyph. If no constructions are available, it calls
getMathVariants for the glyph associated to equivalent fallback characters as listed in the
small characterFallback table.
(WebCore::MathOperator::calculateStretchyData): Call getMathVariantsWithFallback instead of
getMathVariants. Note that we do not need to do that for calculateDisplayStyleLargeOperator
as we do not use fallback for large operators.

  • rendering/mathml/MathOperator.h:

(WebCore::MathOperator::getBaseGlyph): Use getGlyph to implement this function.

LayoutTests:

  • mathml/presentation/bug159513.html: Added.
  • platform/gtk/mathml/presentation/bug159513-expected.png: Added.
  • platform/gtk/mathml/presentation/bug159513-expected.txt: Added.
  • platform/ios-simulator/TestExpectations: Skip this test on iOS.
  • platform/mac/TestExpectations: Skip this test on Mac.
Location:
trunk
Files:
3 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r203713 r203714  
     12016-07-25  Frederic Wang  <fwang@igalia.com>
     2
     3        MathOperator: Add a mapping from combining to non-combining equivalents
     4        https://bugs.webkit.org/show_bug.cgi?id=159513
     5
     6        Reviewed by Darin Adler.
     7
     8        * mathml/presentation/bug159513.html: Added.
     9        * platform/gtk/mathml/presentation/bug159513-expected.png: Added.
     10        * platform/gtk/mathml/presentation/bug159513-expected.txt: Added.
     11        * platform/ios-simulator/TestExpectations: Skip this test on iOS.
     12        * platform/mac/TestExpectations: Skip this test on Mac.
     13
    1142016-07-25  Chris Dumez  <cdumez@apple.com>
    215
  • trunk/LayoutTests/platform/ios-simulator/TestExpectations

    r203522 r203714  
    672672mathml/presentation/fractions-linethickness.html [ Skip ]
    673673mathml/opentype/large-operators-italic-correction.html [ Skip ]
     674mathml/presentation/bug159513.html [ Skip ]
    674675
    675676# These reftests require a font with Mathematical Alphanumeric Symbols.
  • trunk/LayoutTests/platform/mac/TestExpectations

    r203602 r203714  
    805805mathml/presentation/fractions-linethickness.html [ Skip ]
    806806mathml/opentype/large-operators-italic-correction.html [ Skip ]
     807mathml/presentation/bug159513.html [ Skip ]
    807808
    808809# These tests use key navigation to test MathML links but do not seem to work on Mac.
  • trunk/Source/WebCore/ChangeLog

    r203713 r203714  
     12016-07-25  Frederic Wang  <fwang@igalia.com>
     2
     3        MathOperator: Add a mapping from combining to non-combining equivalents
     4        https://bugs.webkit.org/show_bug.cgi?id=159513
     5
     6        Reviewed by Darin Adler.
     7
     8        Many math fonts provide stretch variants and assemblies for combining characters but not for
     9        their non-combining equivalent. In the MathML recommendation, it is suggested to use
     10        non-combining charaters, so we allow the operator stretching code to look for constructions
     11        associated to these non-combining characters in order to still be able to stretch the
     12        combining ones.
     13
     14        Test: mathml/presentation/bug159513.html
     15
     16        * rendering/mathml/MathOperator.cpp:
     17        (WebCore::MathOperator::getGlyph): New function extending getBaseGlyph to retrieve the glyph
     18        data for an arbitrary character.
     19        (WebCore::MathOperator::getMathVariantsWithFallback): This helper function calls
     20        getMathVariants for the base glyph. If no constructions are available, it calls
     21        getMathVariants for the glyph associated to equivalent fallback characters as listed in the
     22        small characterFallback table.
     23        (WebCore::MathOperator::calculateStretchyData): Call getMathVariantsWithFallback instead of
     24        getMathVariants. Note that we do not need to do that for calculateDisplayStyleLargeOperator
     25        as we do not use fallback for large operators.
     26        * rendering/mathml/MathOperator.h:
     27        (WebCore::MathOperator::getBaseGlyph): Use getGlyph to implement this function.
     28
    1292016-07-25  Chris Dumez  <cdumez@apple.com>
    230
  • trunk/Source/WebCore/rendering/mathml/MathOperator.cpp

    r203639 r203714  
    122122}
    123123
    124 bool MathOperator::getBaseGlyph(const RenderStyle& style, GlyphData& baseGlyph) const
    125 {
    126     baseGlyph = style.fontCascade().glyphDataForCharacter(m_baseCharacter, !style.isLeftToRightDirection());
    127     return baseGlyph.font && baseGlyph.font == &style.fontCascade().primaryFont();
     124bool MathOperator::getGlyph(const RenderStyle& style, UChar character, GlyphData& glyph) const
     125{
     126    glyph = style.fontCascade().glyphDataForCharacter(character, !style.isLeftToRightDirection());
     127    return glyph.font && glyph.font == &style.fontCascade().primaryFont();
    128128}
    129129
     
    168168}
    169169
     170// The MathML specification recommends avoiding combining characters.
     171// See https://www.w3.org/TR/MathML/chapter7.html#chars.comb-chars
     172// However, many math fonts do not provide constructions for the non-combining equivalent.
     173const unsigned maxFallbackPerCharacter = 3;
     174static const UChar characterFallback[][maxFallbackPerCharacter] = {
     175    { 0x005E, 0x0302, 0 }, // CIRCUMFLEX ACCENT
     176    { 0x005F, 0x0332, 0 }, // LOW LINE
     177    { 0x007E, 0x0303, 0 }, // TILDE
     178    { 0x00AF, 0x0304, 0x0305 }, // MACRON
     179    { 0x02C6, 0x0302, 0 }, // MODIFIER LETTER CIRCUMFLEX ACCENT
     180    { 0x02C7, 0x030C, 0 } // CARON
     181};
     182const unsigned characterFallbackSize = WTF_ARRAY_LENGTH(characterFallback);
     183
     184void MathOperator::getMathVariantsWithFallback(const RenderStyle& style, bool isVertical, Vector<Glyph>& sizeVariants, Vector<OpenTypeMathData::AssemblyPart>& assemblyParts)
     185{
     186    // In general, we first try and find contruction for the base glyph.
     187    GlyphData baseGlyph;
     188    if (!getBaseGlyph(style, baseGlyph) || !baseGlyph.font->mathData())
     189        return;
     190    baseGlyph.font->mathData()->getMathVariants(baseGlyph.glyph, isVertical, sizeVariants, assemblyParts);
     191    if (!sizeVariants.isEmpty() || !assemblyParts.isEmpty())
     192        return;
     193
     194    // Otherwise, we try and find fallback constructions using similar characters.
     195    for (unsigned i = 0; i < characterFallbackSize; i++) {
     196        unsigned j = 0;
     197        if (characterFallback[i][j] == m_baseCharacter) {
     198            for (j++; j < maxFallbackPerCharacter && characterFallback[i][j]; j++) {
     199                GlyphData glyphData;
     200                if (!getGlyph(style, characterFallback[i][j], glyphData))
     201                    continue;
     202                glyphData.font->mathData()->getMathVariants(glyphData.glyph, isVertical, sizeVariants, assemblyParts);
     203                if (!sizeVariants.isEmpty() || !assemblyParts.isEmpty())
     204                    return;
     205            }
     206            break;
     207        }
     208    }
     209}
     210
    170211void MathOperator::calculateDisplayStyleLargeOperator(const RenderStyle& style)
    171212{
     
    317358        Vector<Glyph> sizeVariants;
    318359        Vector<OpenTypeMathData::AssemblyPart> assemblyParts;
    319         baseGlyph.font->mathData()->getMathVariants(baseGlyph.glyph, isVertical, sizeVariants, assemblyParts);
     360        getMathVariantsWithFallback(style, isVertical, sizeVariants, assemblyParts);
    320361        // We verify the size variants.
    321362        for (auto& sizeVariant : sizeVariants) {
  • trunk/Source/WebCore/rendering/mathml/MathOperator.h

    r203228 r203714  
    7373
    7474    LayoutUnit stretchSize() const;
    75     bool getBaseGlyph(const RenderStyle&, GlyphData&) const;
     75    bool getGlyph(const RenderStyle&, UChar character, GlyphData&) const;
     76    bool getBaseGlyph(const RenderStyle& style, GlyphData& baseGlyph) const { return getGlyph(style, m_baseCharacter, baseGlyph); }
    7677    void setSizeVariant(const GlyphData&);
    7778    void setGlyphAssembly(const GlyphAssemblyData&);
     79    void getMathVariantsWithFallback(const RenderStyle&, bool isVertical, Vector<Glyph>&, Vector<OpenTypeMathData::AssemblyPart>&);
    7880    void calculateDisplayStyleLargeOperator(const RenderStyle&);
    7981    void calculateStretchyData(const RenderStyle&, bool calculateMaxPreferredWidth, LayoutUnit targetSize = 0);
Note: See TracChangeset for help on using the changeset viewer.