Changeset 207272 in webkit


Ignore:
Timestamp:
Oct 12, 2016 7:28:49 PM (7 years ago)
Author:
matthew_hanson@apple.com
Message:

Merge r205163. rdar://problem/28216249

2016-08-29 Brent Fulgham <Brent Fulgham>

Avoid holding GlyphData in MathOperator
https://bugs.webkit.org/show_bug.cgi?id=161256
<rdar://problem/28033400>

Reviewed by Myles C. Maxfield.

Do not cache GlyphData in MathOperator elements, because the fonts referenced in the
GlyphData may be purged during low-memory conditions. Instead, we should store either
the relevant CodePoint, or the fallback Glyph (for the current system font).

Added an initialization function for GlyphAssemblyData, since unions containing structs
do not properly call constructors, resulting in garbage font/glyph content.

No new tests. Changes are covered by existing MathML test suite.

  • rendering/mathml/MathOperator.cpp: (WebCore::MathOperator::GlyphAssemblyData::initialize): Added. (WebCore::MathOperator::MathOperator): Initialize m_assembly/m_variant. (WebCore::MathOperator::setSizeVariant): Only store the glyph, not the font. (WebCore::glyphDataForCodePointOrFallbackGlyph): Added helper function. (WebCore::MathOperator::setGlyphAssembly): Do not rely on stored GlyphData. (WebCore::MathOperator::calculateGlyphAssemblyFallback): Remove unneeded argument. Check if a fallback glyph is being used and remember for later. (WebCore::MathOperator::calculateStretchyData): Do not rely on stored GlyphData. (WebCore::MathOperator::fillWithVerticalExtensionGlyph): Ditto. (WebCore::MathOperator::fillWithHorizontalExtensionGlyph): Ditto. (WebCore::MathOperator::paintVerticalGlyphAssembly): Ditto. (WebCore::MathOperator::paintHorizontalGlyphAssembly): Ditto. (WebCore::MathOperator::paint): Ditto.
  • rendering/mathml/MathOperator.h: (WebCore::MathOperator::GlyphAssemblyData::hasExtension): Added. (WebCore::MathOperator::GlyphAssemblyData::hasMiddle): Added. (WebCore::MathOperator::MathOperator): Deleted.

Patch by Brent Fulgham <Brent Fulgham> on 2016-08-25

Location:
branches/safari-602-branch/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/safari-602-branch/Source/WebCore/ChangeLog

    r207271 r207272  
     12016-08-25  Brent Fulgham  <bfulgham@apple.com>
     2
     3        Merge r205163. rdar://problem/28216249
     4
     5    2016-08-29  Brent Fulgham  <bfulgham@apple.com>
     6
     7            Avoid holding GlyphData in MathOperator
     8            https://bugs.webkit.org/show_bug.cgi?id=161256
     9            <rdar://problem/28033400>
     10
     11            Reviewed by Myles C. Maxfield.
     12
     13            Do not cache GlyphData in MathOperator elements, because the fonts referenced in the
     14            GlyphData may be purged during low-memory conditions. Instead, we should store either
     15            the relevant CodePoint, or the fallback Glyph (for the current system font).
     16
     17            Added an initialization function for GlyphAssemblyData, since unions containing structs
     18            do not properly call constructors, resulting in garbage font/glyph content.
     19
     20            No new tests. Changes are covered by existing MathML test suite.
     21
     22            * rendering/mathml/MathOperator.cpp:
     23            (WebCore::MathOperator::GlyphAssemblyData::initialize): Added.
     24            (WebCore::MathOperator::MathOperator): Initialize m_assembly/m_variant.
     25            (WebCore::MathOperator::setSizeVariant): Only store the glyph, not the font.
     26            (WebCore::glyphDataForCodePointOrFallbackGlyph): Added helper function.
     27            (WebCore::MathOperator::setGlyphAssembly): Do not rely on stored GlyphData.
     28            (WebCore::MathOperator::calculateGlyphAssemblyFallback): Remove unneeded argument. Check
     29            if a fallback glyph is being used and remember for later.
     30            (WebCore::MathOperator::calculateStretchyData): Do not rely on stored GlyphData.
     31            (WebCore::MathOperator::fillWithVerticalExtensionGlyph): Ditto.
     32            (WebCore::MathOperator::fillWithHorizontalExtensionGlyph): Ditto.
     33            (WebCore::MathOperator::paintVerticalGlyphAssembly): Ditto.
     34            (WebCore::MathOperator::paintHorizontalGlyphAssembly): Ditto.
     35            (WebCore::MathOperator::paint): Ditto.
     36            * rendering/mathml/MathOperator.h:
     37            (WebCore::MathOperator::GlyphAssemblyData::hasExtension): Added.
     38            (WebCore::MathOperator::GlyphAssemblyData::hasMiddle): Added.
     39            (WebCore::MathOperator::MathOperator): Deleted.
     40
    1412016-08-25  Brent Fulgham  <bfulgham@apple.com>
    242
  • branches/safari-602-branch/Source/WebCore/rendering/mathml/MathOperator.cpp

    r203289 r207272  
    11/*
    22 * Copyright (C) 2016 Igalia S.L. All rights reserved.
     3 * Copyright (C) 2016 Apple Inc.  All rights reserved.
    34 *
    45 * Redistribution and use in source and binary forms, with or without
     
    8687};
    8788
     89void MathOperator::GlyphAssemblyData::initialize()
     90{
     91    topOrRightCodePoint = 0;
     92    topOrRightFallbackGlyph = 0;
     93    extensionCodePoint = 0;
     94    extensionFallbackGlyph = 0;
     95    bottomOrLeftCodePoint = 0;
     96    bottomOrLeftFallbackGlyph = 0;
     97    middleCodePoint = 0;
     98    middleFallbackGlyph = 0;
     99}
     100   
     101MathOperator::MathOperator()
     102{
     103    m_assembly.initialize();
     104    m_variantGlyph = 0;
     105}
     106
    88107void MathOperator::setOperator(const RenderStyle& style, UChar baseCharacter, Type operatorType)
    89108{
     
    133152    ASSERT(sizeVariant.font->mathData());
    134153    m_stretchType = StretchType::SizeVariant;
    135     m_variant = sizeVariant;
     154    m_variantGlyph = sizeVariant.glyph;
    136155    m_width = advanceWidthForGlyph(sizeVariant);
    137156    getAscentAndDescentForGlyph(sizeVariant, m_ascent, m_descent);
    138157}
    139158
    140 void MathOperator::setGlyphAssembly(const GlyphAssemblyData& assemblyData)
     159static GlyphData glyphDataForCodePointOrFallbackGlyph(const RenderStyle& style, UChar32 codePoint, Glyph fallbackGlyph)
     160{
     161    if (codePoint)
     162        return style.fontCascade().glyphDataForCharacter(codePoint, false);
     163   
     164    GlyphData fallback;
     165   
     166    if (fallbackGlyph) {
     167        fallback.glyph = fallbackGlyph;
     168        fallback.font = &style.fontCascade().primaryFont();
     169    }
     170   
     171    return fallback;
     172}
     173
     174void MathOperator::setGlyphAssembly(const RenderStyle& style, const GlyphAssemblyData& assemblyData)
    141175{
    142176    ASSERT(m_operatorType == Type::VerticalOperator || m_operatorType == Type::HorizontalOperator);
    143177    m_stretchType = StretchType::GlyphAssembly;
    144178    m_assembly = assemblyData;
     179
     180    auto topOrRight = glyphDataForCodePointOrFallbackGlyph(style, m_assembly.topOrRightCodePoint, m_assembly.topOrRightFallbackGlyph);
     181    auto extension = glyphDataForCodePointOrFallbackGlyph(style, m_assembly.extensionCodePoint, m_assembly.extensionFallbackGlyph);
     182    auto middle = glyphDataForCodePointOrFallbackGlyph(style, m_assembly.middleCodePoint, m_assembly.middleFallbackGlyph);
     183    auto bottomOrLeft = glyphDataForCodePointOrFallbackGlyph(style, m_assembly.bottomOrLeftCodePoint, m_assembly.bottomOrLeftFallbackGlyph);
     184
    145185    if (m_operatorType == Type::VerticalOperator) {
    146186        m_width = 0;
    147         m_width = std::max<LayoutUnit>(m_width, advanceWidthForGlyph(m_assembly.topOrRight));
    148         m_width = std::max<LayoutUnit>(m_width, advanceWidthForGlyph(m_assembly.extension));
    149         m_width = std::max<LayoutUnit>(m_width, advanceWidthForGlyph(m_assembly.bottomOrLeft));
    150         m_width = std::max<LayoutUnit>(m_width, advanceWidthForGlyph(m_assembly.middle));
     187        m_width = std::max<LayoutUnit>(m_width, advanceWidthForGlyph(topOrRight));
     188        m_width = std::max<LayoutUnit>(m_width, advanceWidthForGlyph(extension));
     189        m_width = std::max<LayoutUnit>(m_width, advanceWidthForGlyph(bottomOrLeft));
     190        m_width = std::max<LayoutUnit>(m_width, advanceWidthForGlyph(middle));
    151191    } else {
    152192        m_ascent = 0;
    153193        m_descent = 0;
    154194        LayoutUnit ascent, descent;
    155         getAscentAndDescentForGlyph(m_assembly.bottomOrLeft, ascent, descent);
     195        getAscentAndDescentForGlyph(bottomOrLeft, ascent, descent);
    156196        m_ascent = std::max(m_ascent, ascent);
    157197        m_descent = std::max(m_descent, descent);
    158         getAscentAndDescentForGlyph(m_assembly.extension, ascent, descent);
     198        getAscentAndDescentForGlyph(extension, ascent, descent);
    159199        m_ascent = std::max(m_ascent, ascent);
    160200        m_descent = std::max(m_descent, descent);
    161         getAscentAndDescentForGlyph(m_assembly.topOrRight, ascent, descent);
     201        getAscentAndDescentForGlyph(topOrRight, ascent, descent);
    162202        m_ascent = std::max(m_ascent, ascent);
    163203        m_descent = std::max(m_descent, descent);
    164         getAscentAndDescentForGlyph(m_assembly.middle, ascent, descent);
     204        getAscentAndDescentForGlyph(middle, ascent, descent);
    165205        m_ascent = std::max(m_ascent, ascent);
    166206        m_descent = std::max(m_descent, descent);
     
    194234}
    195235
    196 bool MathOperator::calculateGlyphAssemblyFallback(const RenderStyle& style, const Vector<OpenTypeMathData::AssemblyPart>& assemblyParts, GlyphAssemblyData& assemblyData) const
     236bool MathOperator::calculateGlyphAssemblyFallback(const Vector<OpenTypeMathData::AssemblyPart>& assemblyParts, GlyphAssemblyData& assemblyData) const
    197237{
    198238    // The structure of the Open Type Math table is a bit more general than the one currently used by the MathOperator code, so we try to fallback in a reasonable way.
     
    219259    };
    220260    PartType expectedPartType = Start;
    221     assemblyData.extension.glyph = 0;
    222     assemblyData.middle.glyph = 0;
     261    assemblyData.extensionCodePoint = 0;
     262    assemblyData.extensionFallbackGlyph = 0;
     263    assemblyData.middleCodePoint = 0;
     264    assemblyData.middleFallbackGlyph = 0;
    223265    for (auto& part : assemblyParts) {
    224266        if (nonExtenderCount < 3) {
     
    230272        }
    231273        if (part.isExtender) {
    232             if (!assemblyData.extension.glyph)
    233                 assemblyData.extension.glyph = part.glyph; // We copy the extender part.
    234             else if (assemblyData.extension.glyph != part.glyph)
     274            if (!assemblyData.extensionFallbackGlyph)
     275                assemblyData.extensionFallbackGlyph = part.glyph; // We copy the extender part.
     276            else if (assemblyData.extensionFallbackGlyph != part.glyph)
    235277                return false; // This is not supported: the assembly has different extenders.
    236278
     
    258300        case Start:
    259301            // We copy the left/bottom part.
    260             assemblyData.bottomOrLeft.glyph = part.glyph;
     302            assemblyData.bottomOrLeftFallbackGlyph = part.glyph;
     303            assemblyData.bottomOrLeftCodePoint = 0;
    261304            expectedPartType = ExtenderBetweenStartAndMiddle;
    262305            continue;
     
    264307        case Middle:
    265308            // We copy the middle part.
    266             assemblyData.middle.glyph = part.glyph;
     309            assemblyData.middleFallbackGlyph = part.glyph;
    267310            expectedPartType = ExtenderBetweenMiddleAndEnd;
    268311            continue;
     
    270313        case End:
    271314            // We copy the right/top part.
    272             assemblyData.topOrRight.glyph = part.glyph;
     315            assemblyData.topOrRightFallbackGlyph = part.glyph;
     316            assemblyData.topOrRightCodePoint = 0;
    273317            expectedPartType = None;
    274318            continue;
     
    279323    }
    280324
    281     if (!assemblyData.extension.glyph)
     325    if (!assemblyData.hasExtension())
    282326        return false; // This is not supported: we always assume that we have an extension glyph.
    283327
    284328    // If we don't have top/bottom glyphs, we use the extension glyph.
    285     if (!assemblyData.topOrRight.glyph)
    286         assemblyData.topOrRight.glyph = assemblyData.extension.glyph;
    287     if (!assemblyData.bottomOrLeft.glyph)
    288         assemblyData.bottomOrLeft.glyph = assemblyData.extension.glyph;
    289 
    290     assemblyData.topOrRight.font = &style.fontCascade().primaryFont();
    291     assemblyData.extension.font = assemblyData.topOrRight.font;
    292     assemblyData.bottomOrLeft.font = assemblyData.topOrRight.font;
    293     assemblyData.middle.font = assemblyData.middle.glyph ? assemblyData.topOrRight.font : nullptr;
     329    if (!assemblyData.topOrRightCodePoint && !assemblyData.topOrRightFallbackGlyph)
     330        assemblyData.topOrRightFallbackGlyph = assemblyData.extensionFallbackGlyph;
     331    if (!assemblyData.bottomOrLeftCodePoint && !assemblyData.bottomOrLeftFallbackGlyph)
     332        assemblyData.bottomOrLeftFallbackGlyph = assemblyData.extensionFallbackGlyph;
    294333
    295334    return true;
     
    332371
    333372        // We verify if there is a construction.
    334         if (!calculateGlyphAssemblyFallback(style, assemblyParts, assemblyData))
     373        if (!calculateGlyphAssemblyFallback(assemblyParts, assemblyData))
    335374            return;
    336375    } else {
     
    370409
    371410        // We convert the list of Unicode characters into a list of glyph data.
    372         assemblyData.topOrRight = style.fontCascade().glyphDataForCharacter(stretchyCharacter->topChar, false);
    373         assemblyData.extension = style.fontCascade().glyphDataForCharacter(stretchyCharacter->extensionChar, false);
    374         assemblyData.bottomOrLeft = style.fontCascade().glyphDataForCharacter(stretchyCharacter->bottomChar, false);
    375         assemblyData.middle = stretchyCharacter->middleChar ? style.fontCascade().glyphDataForCharacter(stretchyCharacter->middleChar, false) : GlyphData();
    376     }
     411        assemblyData.topOrRightCodePoint = stretchyCharacter->topChar;
     412        assemblyData.extensionCodePoint = stretchyCharacter->extensionChar;
     413        assemblyData.bottomOrLeftCodePoint = stretchyCharacter->bottomChar;
     414        assemblyData.middleCodePoint = stretchyCharacter->middleChar;
     415    }
     416
     417    auto topOrRight = glyphDataForCodePointOrFallbackGlyph(style, assemblyData.topOrRightCodePoint, assemblyData.topOrRightFallbackGlyph);
     418    auto extension = glyphDataForCodePointOrFallbackGlyph(style, assemblyData.extensionCodePoint, assemblyData.extensionFallbackGlyph);
     419    auto middle = glyphDataForCodePointOrFallbackGlyph(style, assemblyData.middleCodePoint, assemblyData.middleFallbackGlyph);
     420    auto bottomOrLeft = glyphDataForCodePointOrFallbackGlyph(style, assemblyData.bottomOrLeftCodePoint, assemblyData.bottomOrLeftFallbackGlyph);
    377421
    378422    // If we are measuring the maximum width, verify each component.
    379423    if (calculateMaxPreferredWidth) {
    380         m_maxPreferredWidth = std::max<LayoutUnit>(m_maxPreferredWidth, advanceWidthForGlyph(assemblyData.topOrRight));
    381         m_maxPreferredWidth = std::max<LayoutUnit>(m_maxPreferredWidth, advanceWidthForGlyph(assemblyData.extension));
    382         m_maxPreferredWidth = std::max<LayoutUnit>(m_maxPreferredWidth, advanceWidthForGlyph(assemblyData.middle));
    383         m_maxPreferredWidth = std::max<LayoutUnit>(m_maxPreferredWidth, advanceWidthForGlyph(assemblyData.bottomOrLeft));
     424        m_maxPreferredWidth = std::max<LayoutUnit>(m_maxPreferredWidth, advanceWidthForGlyph(topOrRight));
     425        m_maxPreferredWidth = std::max<LayoutUnit>(m_maxPreferredWidth, advanceWidthForGlyph(extension));
     426        m_maxPreferredWidth = std::max<LayoutUnit>(m_maxPreferredWidth, advanceWidthForGlyph(middle));
     427        m_maxPreferredWidth = std::max<LayoutUnit>(m_maxPreferredWidth, advanceWidthForGlyph(bottomOrLeft));
    384428        return;
    385429    }
     
    387431    // We ensure that the size is large enough to avoid glyph overlaps.
    388432    float minSize = isVertical ?
    389         heightForGlyph(assemblyData.topOrRight) + heightForGlyph(assemblyData.middle) + heightForGlyph(assemblyData.bottomOrLeft)
    390         : advanceWidthForGlyph(assemblyData.bottomOrLeft) + advanceWidthForGlyph(assemblyData.middle) + advanceWidthForGlyph(assemblyData.topOrRight);
     433        heightForGlyph(topOrRight) + heightForGlyph(middle) + heightForGlyph(bottomOrLeft)
     434        : advanceWidthForGlyph(bottomOrLeft) + advanceWidthForGlyph(middle) + advanceWidthForGlyph(topOrRight);
    391435    if (minSize > targetSize)
    392436        return;
    393437
    394     setGlyphAssembly(assemblyData);
     438    setGlyphAssembly(style, assemblyData);
    395439}
    396440
     
    464508    ASSERT(m_operatorType == Type::VerticalOperator);
    465509    ASSERT(m_stretchType == StretchType::GlyphAssembly);
    466     ASSERT(m_assembly.extension.font);
     510
     511    auto extension = glyphDataForCodePointOrFallbackGlyph(style, m_assembly.extensionCodePoint, m_assembly.extensionFallbackGlyph);
     512
     513    ASSERT(extension.font);
    467514    ASSERT(from.y() <= to.y());
    468515
     
    473520    GraphicsContextStateSaver stateSaver(info.context());
    474521
    475     FloatRect glyphBounds = boundsForGlyph(m_assembly.extension);
     522    FloatRect glyphBounds = boundsForGlyph(extension);
    476523
    477524    // Clipping the extender region here allows us to draw the bottom extender glyph into the
     
    489536    // In practice, only small stretch sizes are requested but we limit the number of glyphs to avoid hangs.
    490537    for (unsigned extensionCount = 0; lastPaintedGlyphRect.maxY() < to.y() && extensionCount < kMaximumExtensionCount; extensionCount++) {
    491         lastPaintedGlyphRect = paintGlyph(style, info, m_assembly.extension, glyphOrigin, TrimTopAndBottom);
     538        lastPaintedGlyphRect = paintGlyph(style, info, extension, glyphOrigin, TrimTopAndBottom);
    492539        glyphOrigin.setY(glyphOrigin.y() + lastPaintedGlyphRect.height());
    493540
     
    503550    ASSERT(m_operatorType == Type::HorizontalOperator);
    504551    ASSERT(m_stretchType == StretchType::GlyphAssembly);
    505     ASSERT(m_assembly.extension.font);
     552
     553    auto extension = glyphDataForCodePointOrFallbackGlyph(style, m_assembly.extensionCodePoint, m_assembly.extensionFallbackGlyph);
     554
     555    ASSERT(extension.font);
    506556    ASSERT(from.x() <= to.x());
    507557    ASSERT(from.y() == to.y());
     
    527577    // In practice, only small stretch sizes are requested but we limit the number of glyphs to avoid hangs.
    528578    for (unsigned extensionCount = 0; lastPaintedGlyphRect.maxX() < to.x() && extensionCount < kMaximumExtensionCount; extensionCount++) {
    529         lastPaintedGlyphRect = paintGlyph(style, info, m_assembly.extension, glyphOrigin, TrimLeftAndRight);
     579        lastPaintedGlyphRect = paintGlyph(style, info, extension, glyphOrigin, TrimLeftAndRight);
    530580        glyphOrigin.setX(glyphOrigin.x() + lastPaintedGlyphRect.width());
    531581
     
    541591    ASSERT(m_operatorType == Type::VerticalOperator);
    542592    ASSERT(m_stretchType == StretchType::GlyphAssembly);
    543     ASSERT(m_assembly.topOrRight.font);
    544     ASSERT(m_assembly.bottomOrLeft.font);
     593
     594    auto topOrRight = glyphDataForCodePointOrFallbackGlyph(style, m_assembly.topOrRightCodePoint, m_assembly.topOrRightFallbackGlyph);
     595    auto bottomOrLeft = glyphDataForCodePointOrFallbackGlyph(style, m_assembly.bottomOrLeftCodePoint, m_assembly.bottomOrLeftFallbackGlyph);
     596
     597    ASSERT(topOrRight.font);
     598    ASSERT(bottomOrLeft.font);
    545599
    546600    // We are positioning the glyphs so that the edge of the tight glyph bounds line up exactly with the edges of our paint box.
    547601    LayoutPoint operatorTopLeft = paintOffset;
    548     FloatRect topGlyphBounds = boundsForGlyph(m_assembly.topOrRight);
     602    FloatRect topGlyphBounds = boundsForGlyph(topOrRight);
    549603    LayoutPoint topGlyphOrigin(operatorTopLeft.x(), operatorTopLeft.y() - topGlyphBounds.y());
    550     LayoutRect topGlyphPaintRect = paintGlyph(style, info, m_assembly.topOrRight, topGlyphOrigin, TrimBottom);
    551 
    552     FloatRect bottomGlyphBounds = boundsForGlyph(m_assembly.bottomOrLeft);
     604    LayoutRect topGlyphPaintRect = paintGlyph(style, info, topOrRight, topGlyphOrigin, TrimBottom);
     605
     606    FloatRect bottomGlyphBounds = boundsForGlyph(bottomOrLeft);
    553607    LayoutPoint bottomGlyphOrigin(operatorTopLeft.x(), operatorTopLeft.y() + stretchSize() - (bottomGlyphBounds.height() + bottomGlyphBounds.y()));
    554     LayoutRect bottomGlyphPaintRect = paintGlyph(style, info, m_assembly.bottomOrLeft, bottomGlyphOrigin, TrimTop);
    555 
    556     if (m_assembly.middle.font) {
     608    LayoutRect bottomGlyphPaintRect = paintGlyph(style, info, bottomOrLeft, bottomGlyphOrigin, TrimTop);
     609
     610    if (m_assembly.hasMiddle()) {
     611        auto middle = glyphDataForCodePointOrFallbackGlyph(style, m_assembly.middleCodePoint, m_assembly.middleFallbackGlyph);
     612
    557613        // Center the glyph origin between the start and end glyph paint extents. Then shift it half the paint height toward the bottom glyph.
    558         FloatRect middleGlyphBounds = boundsForGlyph(m_assembly.middle);
     614        FloatRect middleGlyphBounds = boundsForGlyph(middle);
    559615        LayoutPoint middleGlyphOrigin(operatorTopLeft.x(), topGlyphOrigin.y());
    560616        middleGlyphOrigin.moveBy(LayoutPoint(0, (bottomGlyphPaintRect.y() - topGlyphPaintRect.maxY()) / 2.0));
    561617        middleGlyphOrigin.moveBy(LayoutPoint(0, middleGlyphBounds.height() / 2.0));
    562618
    563         LayoutRect middleGlyphPaintRect = paintGlyph(style, info, m_assembly.middle, middleGlyphOrigin, TrimTopAndBottom);
     619        LayoutRect middleGlyphPaintRect = paintGlyph(style, info, middle, middleGlyphOrigin, TrimTopAndBottom);
    564620        fillWithVerticalExtensionGlyph(style, info, topGlyphPaintRect.minXMaxYCorner(), middleGlyphPaintRect.minXMinYCorner());
    565621        fillWithVerticalExtensionGlyph(style, info, middleGlyphPaintRect.minXMaxYCorner(), bottomGlyphPaintRect.minXMinYCorner());
     
    572628    ASSERT(m_operatorType == Type::HorizontalOperator);
    573629    ASSERT(m_stretchType == StretchType::GlyphAssembly);
    574     ASSERT(m_assembly.bottomOrLeft.font);
    575     ASSERT(m_assembly.topOrRight.font);
     630
     631    auto topOrRight = glyphDataForCodePointOrFallbackGlyph(style, m_assembly.topOrRightCodePoint, m_assembly.topOrRightFallbackGlyph);
     632    auto bottomOrLeft = glyphDataForCodePointOrFallbackGlyph(style, m_assembly.bottomOrLeftCodePoint, m_assembly.bottomOrLeftFallbackGlyph);
     633
     634    ASSERT(bottomOrLeft.font);
     635    ASSERT(topOrRight.font);
    576636
    577637    // We are positioning the glyphs so that the edge of the tight glyph bounds line up exactly with the edges of our paint box.
     
    579639    LayoutUnit baselineY = operatorTopLeft.y() + m_ascent;
    580640    LayoutPoint leftGlyphOrigin(operatorTopLeft.x(), baselineY);
    581     LayoutRect leftGlyphPaintRect = paintGlyph(style, info, m_assembly.bottomOrLeft, leftGlyphOrigin, TrimRight);
    582 
    583     FloatRect rightGlyphBounds = boundsForGlyph(m_assembly.topOrRight);
     641    LayoutRect leftGlyphPaintRect = paintGlyph(style, info, bottomOrLeft, leftGlyphOrigin, TrimRight);
     642
     643    FloatRect rightGlyphBounds = boundsForGlyph(topOrRight);
    584644    LayoutPoint rightGlyphOrigin(operatorTopLeft.x() + stretchSize() - rightGlyphBounds.width(), baselineY);
    585     LayoutRect rightGlyphPaintRect = paintGlyph(style, info, m_assembly.topOrRight, rightGlyphOrigin, TrimLeft);
    586 
    587     if (m_assembly.middle.font) {
     645    LayoutRect rightGlyphPaintRect = paintGlyph(style, info, topOrRight, rightGlyphOrigin, TrimLeft);
     646
     647    if (m_assembly.hasMiddle()) {
     648        auto middle = glyphDataForCodePointOrFallbackGlyph(style, m_assembly.middleCodePoint, m_assembly.middleFallbackGlyph);
     649
    588650        // Center the glyph origin between the start and end glyph paint extents.
    589651        LayoutPoint middleGlyphOrigin(operatorTopLeft.x(), baselineY);
    590652        middleGlyphOrigin.moveBy(LayoutPoint((rightGlyphPaintRect.x() - leftGlyphPaintRect.maxX()) / 2.0, 0));
    591         LayoutRect middleGlyphPaintRect = paintGlyph(style, info, m_assembly.middle, middleGlyphOrigin, TrimLeftAndRight);
     653        LayoutRect middleGlyphPaintRect = paintGlyph(style, info, middle, middleGlyphOrigin, TrimLeftAndRight);
    592654        fillWithHorizontalExtensionGlyph(style, info, LayoutPoint(leftGlyphPaintRect.maxX(), baselineY), LayoutPoint(middleGlyphPaintRect.x(), baselineY));
    593655        fillWithHorizontalExtensionGlyph(style, info, LayoutPoint(middleGlyphPaintRect.maxX(), baselineY), LayoutPoint(rightGlyphPaintRect.x(), baselineY));
     
    624686    GlyphData glyphData;
    625687    ASSERT(m_stretchType == StretchType::Unstretched || m_stretchType == StretchType::SizeVariant);
    626     if (m_stretchType == StretchType::Unstretched) {
    627         if (!getBaseGlyph(style, glyphData))
    628             return;
    629     } else if (m_stretchType == StretchType::SizeVariant) {
    630         ASSERT(m_variant.font);
    631         glyphData = m_variant;
    632     }
     688    if (!getBaseGlyph(style, glyphData))
     689        return;
     690    if (m_stretchType == StretchType::SizeVariant)
     691        glyphData.glyph = m_variantGlyph;
     692
    633693    GlyphBuffer buffer;
    634694    buffer.add(glyphData.glyph, glyphData.font, advanceWidthForGlyph(glyphData));
  • branches/safari-602-branch/Source/WebCore/rendering/mathml/MathOperator.h

    r203228 r207272  
    11/*
    22 * Copyright (C) 2016 Igalia S.L. All rights reserved.
     3 * Copyright (C) 2016 Apple Inc.  All rights reserved.
    34 *
    45 * Redistribution and use in source and binary forms, with or without
     
    3940class MathOperator {
    4041public:
    41     MathOperator() { }
     42    MathOperator();
    4243    enum class Type { NormalOperator, DisplayOperator, VerticalOperator, HorizontalOperator };
    4344    void setOperator(const RenderStyle&, UChar baseCharacter, Type);
     
    5758private:
    5859    struct GlyphAssemblyData {
    59         GlyphData topOrRight;
    60         GlyphData extension;
    61         GlyphData bottomOrLeft;
    62         GlyphData middle;
     60        UChar32 topOrRightCodePoint { 0 };
     61        Glyph topOrRightFallbackGlyph { 0 };
     62        UChar32 extensionCodePoint { 0 };
     63        Glyph extensionFallbackGlyph { 0 };
     64        UChar32 bottomOrLeftCodePoint { 0 };
     65        Glyph bottomOrLeftFallbackGlyph { 0 };
     66        UChar32 middleCodePoint { 0 };
     67        Glyph middleFallbackGlyph { 0 };
     68
     69        bool hasExtension() const { return extensionCodePoint || extensionFallbackGlyph; }
     70        bool hasMiddle() const { return middleCodePoint || middleFallbackGlyph; }
     71        void initialize();
    6372    };
    6473    enum class StretchType { Unstretched, SizeVariant, GlyphAssembly };
     
    7584    bool getBaseGlyph(const RenderStyle&, GlyphData&) const;
    7685    void setSizeVariant(const GlyphData&);
    77     void setGlyphAssembly(const GlyphAssemblyData&);
     86    void setGlyphAssembly(const RenderStyle&, const GlyphAssemblyData&);
    7887    void calculateDisplayStyleLargeOperator(const RenderStyle&);
    7988    void calculateStretchyData(const RenderStyle&, bool calculateMaxPreferredWidth, LayoutUnit targetSize = 0);
    80     bool calculateGlyphAssemblyFallback(const RenderStyle&, const Vector<OpenTypeMathData::AssemblyPart>&, GlyphAssemblyData&) const;
     89    bool calculateGlyphAssemblyFallback(const Vector<OpenTypeMathData::AssemblyPart>&, GlyphAssemblyData&) const;
     90
    8191
    8292    LayoutRect paintGlyph(const RenderStyle&, PaintInfo&, const GlyphData&, const LayoutPoint& origin, GlyphPaintTrimming);
     
    90100    StretchType m_stretchType { StretchType::Unstretched };
    91101    union {
    92         GlyphData m_variant;
     102        Glyph m_variantGlyph;
    93103        GlyphAssemblyData m_assembly;
    94104    };
Note: See TracChangeset for help on using the changeset viewer.