Changeset 205163 in webkit


Ignore:
Timestamp:
Aug 29, 2016 5:44:21 PM (8 years ago)
Author:
Brent Fulgham
Message:

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.

Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

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

    r205111 r205163  
    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, UChar32 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);
     
    235275}
    236276
    237 bool MathOperator::calculateGlyphAssemblyFallback(const RenderStyle& style, const Vector<OpenTypeMathData::AssemblyPart>& assemblyParts, GlyphAssemblyData& assemblyData) const
     277bool MathOperator::calculateGlyphAssemblyFallback(const Vector<OpenTypeMathData::AssemblyPart>& assemblyParts, GlyphAssemblyData& assemblyData) const
    238278{
    239279    // 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.
     
    260300    };
    261301    PartType expectedPartType = Start;
    262     assemblyData.extension.glyph = 0;
    263     assemblyData.middle.glyph = 0;
     302    assemblyData.extensionCodePoint = 0;
     303    assemblyData.extensionFallbackGlyph = 0;
     304    assemblyData.middleCodePoint = 0;
     305    assemblyData.middleFallbackGlyph = 0;
    264306    for (auto& part : assemblyParts) {
    265307        if (nonExtenderCount < 3) {
     
    271313        }
    272314        if (part.isExtender) {
    273             if (!assemblyData.extension.glyph)
    274                 assemblyData.extension.glyph = part.glyph; // We copy the extender part.
    275             else if (assemblyData.extension.glyph != part.glyph)
     315            if (!assemblyData.extensionFallbackGlyph)
     316                assemblyData.extensionFallbackGlyph = part.glyph; // We copy the extender part.
     317            else if (assemblyData.extensionFallbackGlyph != part.glyph)
    276318                return false; // This is not supported: the assembly has different extenders.
    277319
     
    299341        case Start:
    300342            // We copy the left/bottom part.
    301             assemblyData.bottomOrLeft.glyph = part.glyph;
     343            assemblyData.bottomOrLeftFallbackGlyph = part.glyph;
     344            assemblyData.bottomOrLeftCodePoint = 0;
    302345            expectedPartType = ExtenderBetweenStartAndMiddle;
    303346            continue;
     
    305348        case Middle:
    306349            // We copy the middle part.
    307             assemblyData.middle.glyph = part.glyph;
     350            assemblyData.middleFallbackGlyph = part.glyph;
    308351            expectedPartType = ExtenderBetweenMiddleAndEnd;
    309352            continue;
     
    311354        case End:
    312355            // We copy the right/top part.
    313             assemblyData.topOrRight.glyph = part.glyph;
     356            assemblyData.topOrRightFallbackGlyph = part.glyph;
     357            assemblyData.topOrRightCodePoint = 0;
    314358            expectedPartType = None;
    315359            continue;
     
    320364    }
    321365
    322     if (!assemblyData.extension.glyph)
     366    if (!assemblyData.hasExtension())
    323367        return false; // This is not supported: we always assume that we have an extension glyph.
    324368
    325369    // If we don't have top/bottom glyphs, we use the extension glyph.
    326     if (!assemblyData.topOrRight.glyph)
    327         assemblyData.topOrRight.glyph = assemblyData.extension.glyph;
    328     if (!assemblyData.bottomOrLeft.glyph)
    329         assemblyData.bottomOrLeft.glyph = assemblyData.extension.glyph;
    330 
    331     assemblyData.topOrRight.font = &style.fontCascade().primaryFont();
    332     assemblyData.extension.font = assemblyData.topOrRight.font;
    333     assemblyData.bottomOrLeft.font = assemblyData.topOrRight.font;
    334     assemblyData.middle.font = assemblyData.middle.glyph ? assemblyData.topOrRight.font : nullptr;
     370    if (!assemblyData.topOrRightCodePoint && !assemblyData.topOrRightFallbackGlyph)
     371        assemblyData.topOrRightFallbackGlyph = assemblyData.extensionFallbackGlyph;
     372    if (!assemblyData.bottomOrLeftCodePoint && !assemblyData.bottomOrLeftFallbackGlyph)
     373        assemblyData.bottomOrLeftFallbackGlyph = assemblyData.extensionFallbackGlyph;
    335374
    336375    return true;
     
    373412
    374413        // We verify if there is a construction.
    375         if (!calculateGlyphAssemblyFallback(style, assemblyParts, assemblyData))
     414        if (!calculateGlyphAssemblyFallback(assemblyParts, assemblyData))
    376415            return;
    377416    } else {
     
    411450
    412451        // We convert the list of Unicode characters into a list of glyph data.
    413         assemblyData.topOrRight = style.fontCascade().glyphDataForCharacter(stretchyCharacter->topChar, false);
    414         assemblyData.extension = style.fontCascade().glyphDataForCharacter(stretchyCharacter->extensionChar, false);
    415         assemblyData.bottomOrLeft = style.fontCascade().glyphDataForCharacter(stretchyCharacter->bottomChar, false);
    416         assemblyData.middle = stretchyCharacter->middleChar ? style.fontCascade().glyphDataForCharacter(stretchyCharacter->middleChar, false) : GlyphData();
    417     }
     452        assemblyData.topOrRightCodePoint = stretchyCharacter->topChar;
     453        assemblyData.extensionCodePoint = stretchyCharacter->extensionChar;
     454        assemblyData.bottomOrLeftCodePoint = stretchyCharacter->bottomChar;
     455        assemblyData.middleCodePoint = stretchyCharacter->middleChar;
     456    }
     457
     458    auto topOrRight = glyphDataForCodePointOrFallbackGlyph(style, assemblyData.topOrRightCodePoint, assemblyData.topOrRightFallbackGlyph);
     459    auto extension = glyphDataForCodePointOrFallbackGlyph(style, assemblyData.extensionCodePoint, assemblyData.extensionFallbackGlyph);
     460    auto middle = glyphDataForCodePointOrFallbackGlyph(style, assemblyData.middleCodePoint, assemblyData.middleFallbackGlyph);
     461    auto bottomOrLeft = glyphDataForCodePointOrFallbackGlyph(style, assemblyData.bottomOrLeftCodePoint, assemblyData.bottomOrLeftFallbackGlyph);
    418462
    419463    // If we are measuring the maximum width, verify each component.
    420464    if (calculateMaxPreferredWidth) {
    421         m_maxPreferredWidth = std::max<LayoutUnit>(m_maxPreferredWidth, advanceWidthForGlyph(assemblyData.topOrRight));
    422         m_maxPreferredWidth = std::max<LayoutUnit>(m_maxPreferredWidth, advanceWidthForGlyph(assemblyData.extension));
    423         m_maxPreferredWidth = std::max<LayoutUnit>(m_maxPreferredWidth, advanceWidthForGlyph(assemblyData.middle));
    424         m_maxPreferredWidth = std::max<LayoutUnit>(m_maxPreferredWidth, advanceWidthForGlyph(assemblyData.bottomOrLeft));
     465        m_maxPreferredWidth = std::max<LayoutUnit>(m_maxPreferredWidth, advanceWidthForGlyph(topOrRight));
     466        m_maxPreferredWidth = std::max<LayoutUnit>(m_maxPreferredWidth, advanceWidthForGlyph(extension));
     467        m_maxPreferredWidth = std::max<LayoutUnit>(m_maxPreferredWidth, advanceWidthForGlyph(middle));
     468        m_maxPreferredWidth = std::max<LayoutUnit>(m_maxPreferredWidth, advanceWidthForGlyph(bottomOrLeft));
    425469        return;
    426470    }
     
    428472    // We ensure that the size is large enough to avoid glyph overlaps.
    429473    float minSize = isVertical ?
    430         heightForGlyph(assemblyData.topOrRight) + heightForGlyph(assemblyData.middle) + heightForGlyph(assemblyData.bottomOrLeft)
    431         : advanceWidthForGlyph(assemblyData.bottomOrLeft) + advanceWidthForGlyph(assemblyData.middle) + advanceWidthForGlyph(assemblyData.topOrRight);
     474        heightForGlyph(topOrRight) + heightForGlyph(middle) + heightForGlyph(bottomOrLeft)
     475        : advanceWidthForGlyph(bottomOrLeft) + advanceWidthForGlyph(middle) + advanceWidthForGlyph(topOrRight);
    432476    if (minSize > targetSize)
    433477        return;
    434478
    435     setGlyphAssembly(assemblyData);
     479    setGlyphAssembly(style, assemblyData);
    436480}
    437481
     
    505549    ASSERT(m_operatorType == Type::VerticalOperator);
    506550    ASSERT(m_stretchType == StretchType::GlyphAssembly);
    507     ASSERT(m_assembly.extension.font);
     551
     552    auto extension = glyphDataForCodePointOrFallbackGlyph(style, m_assembly.extensionCodePoint, m_assembly.extensionFallbackGlyph);
     553
     554    ASSERT(extension.font);
    508555    ASSERT(from.y() <= to.y());
    509556
     
    514561    GraphicsContextStateSaver stateSaver(info.context());
    515562
    516     FloatRect glyphBounds = boundsForGlyph(m_assembly.extension);
     563    FloatRect glyphBounds = boundsForGlyph(extension);
    517564
    518565    // Clipping the extender region here allows us to draw the bottom extender glyph into the
     
    530577    // In practice, only small stretch sizes are requested but we limit the number of glyphs to avoid hangs.
    531578    for (unsigned extensionCount = 0; lastPaintedGlyphRect.maxY() < to.y() && extensionCount < kMaximumExtensionCount; extensionCount++) {
    532         lastPaintedGlyphRect = paintGlyph(style, info, m_assembly.extension, glyphOrigin, TrimTopAndBottom);
     579        lastPaintedGlyphRect = paintGlyph(style, info, extension, glyphOrigin, TrimTopAndBottom);
    533580        glyphOrigin.setY(glyphOrigin.y() + lastPaintedGlyphRect.height());
    534581
     
    544591    ASSERT(m_operatorType == Type::HorizontalOperator);
    545592    ASSERT(m_stretchType == StretchType::GlyphAssembly);
    546     ASSERT(m_assembly.extension.font);
     593
     594    auto extension = glyphDataForCodePointOrFallbackGlyph(style, m_assembly.extensionCodePoint, m_assembly.extensionFallbackGlyph);
     595
     596    ASSERT(extension.font);
    547597    ASSERT(from.x() <= to.x());
    548598    ASSERT(from.y() == to.y());
     
    568618    // In practice, only small stretch sizes are requested but we limit the number of glyphs to avoid hangs.
    569619    for (unsigned extensionCount = 0; lastPaintedGlyphRect.maxX() < to.x() && extensionCount < kMaximumExtensionCount; extensionCount++) {
    570         lastPaintedGlyphRect = paintGlyph(style, info, m_assembly.extension, glyphOrigin, TrimLeftAndRight);
     620        lastPaintedGlyphRect = paintGlyph(style, info, extension, glyphOrigin, TrimLeftAndRight);
    571621        glyphOrigin.setX(glyphOrigin.x() + lastPaintedGlyphRect.width());
    572622
     
    582632    ASSERT(m_operatorType == Type::VerticalOperator);
    583633    ASSERT(m_stretchType == StretchType::GlyphAssembly);
    584     ASSERT(m_assembly.topOrRight.font);
    585     ASSERT(m_assembly.bottomOrLeft.font);
     634
     635    auto topOrRight = glyphDataForCodePointOrFallbackGlyph(style, m_assembly.topOrRightCodePoint, m_assembly.topOrRightFallbackGlyph);
     636    auto bottomOrLeft = glyphDataForCodePointOrFallbackGlyph(style, m_assembly.bottomOrLeftCodePoint, m_assembly.bottomOrLeftFallbackGlyph);
     637
     638    ASSERT(topOrRight.font);
     639    ASSERT(bottomOrLeft.font);
    586640
    587641    // We are positioning the glyphs so that the edge of the tight glyph bounds line up exactly with the edges of our paint box.
    588642    LayoutPoint operatorTopLeft = paintOffset;
    589     FloatRect topGlyphBounds = boundsForGlyph(m_assembly.topOrRight);
     643    FloatRect topGlyphBounds = boundsForGlyph(topOrRight);
    590644    LayoutPoint topGlyphOrigin(operatorTopLeft.x(), operatorTopLeft.y() - topGlyphBounds.y());
    591     LayoutRect topGlyphPaintRect = paintGlyph(style, info, m_assembly.topOrRight, topGlyphOrigin, TrimBottom);
    592 
    593     FloatRect bottomGlyphBounds = boundsForGlyph(m_assembly.bottomOrLeft);
     645    LayoutRect topGlyphPaintRect = paintGlyph(style, info, topOrRight, topGlyphOrigin, TrimBottom);
     646
     647    FloatRect bottomGlyphBounds = boundsForGlyph(bottomOrLeft);
    594648    LayoutPoint bottomGlyphOrigin(operatorTopLeft.x(), operatorTopLeft.y() + stretchSize() - (bottomGlyphBounds.height() + bottomGlyphBounds.y()));
    595     LayoutRect bottomGlyphPaintRect = paintGlyph(style, info, m_assembly.bottomOrLeft, bottomGlyphOrigin, TrimTop);
    596 
    597     if (m_assembly.middle.font) {
     649    LayoutRect bottomGlyphPaintRect = paintGlyph(style, info, bottomOrLeft, bottomGlyphOrigin, TrimTop);
     650
     651    if (m_assembly.hasMiddle()) {
     652        auto middle = glyphDataForCodePointOrFallbackGlyph(style, m_assembly.middleCodePoint, m_assembly.middleFallbackGlyph);
     653
    598654        // Center the glyph origin between the start and end glyph paint extents. Then shift it half the paint height toward the bottom glyph.
    599         FloatRect middleGlyphBounds = boundsForGlyph(m_assembly.middle);
     655        FloatRect middleGlyphBounds = boundsForGlyph(middle);
    600656        LayoutPoint middleGlyphOrigin(operatorTopLeft.x(), topGlyphOrigin.y());
    601657        middleGlyphOrigin.moveBy(LayoutPoint(0, (bottomGlyphPaintRect.y() - topGlyphPaintRect.maxY()) / 2.0));
    602658        middleGlyphOrigin.moveBy(LayoutPoint(0, middleGlyphBounds.height() / 2.0));
    603659
    604         LayoutRect middleGlyphPaintRect = paintGlyph(style, info, m_assembly.middle, middleGlyphOrigin, TrimTopAndBottom);
     660        LayoutRect middleGlyphPaintRect = paintGlyph(style, info, middle, middleGlyphOrigin, TrimTopAndBottom);
    605661        fillWithVerticalExtensionGlyph(style, info, topGlyphPaintRect.minXMaxYCorner(), middleGlyphPaintRect.minXMinYCorner());
    606662        fillWithVerticalExtensionGlyph(style, info, middleGlyphPaintRect.minXMaxYCorner(), bottomGlyphPaintRect.minXMinYCorner());
     
    613669    ASSERT(m_operatorType == Type::HorizontalOperator);
    614670    ASSERT(m_stretchType == StretchType::GlyphAssembly);
    615     ASSERT(m_assembly.bottomOrLeft.font);
    616     ASSERT(m_assembly.topOrRight.font);
     671
     672    auto topOrRight = glyphDataForCodePointOrFallbackGlyph(style, m_assembly.topOrRightCodePoint, m_assembly.topOrRightFallbackGlyph);
     673    auto bottomOrLeft = glyphDataForCodePointOrFallbackGlyph(style, m_assembly.bottomOrLeftCodePoint, m_assembly.bottomOrLeftFallbackGlyph);
     674
     675    ASSERT(bottomOrLeft.font);
     676    ASSERT(topOrRight.font);
    617677
    618678    // We are positioning the glyphs so that the edge of the tight glyph bounds line up exactly with the edges of our paint box.
     
    620680    LayoutUnit baselineY = operatorTopLeft.y() + m_ascent;
    621681    LayoutPoint leftGlyphOrigin(operatorTopLeft.x(), baselineY);
    622     LayoutRect leftGlyphPaintRect = paintGlyph(style, info, m_assembly.bottomOrLeft, leftGlyphOrigin, TrimRight);
    623 
    624     FloatRect rightGlyphBounds = boundsForGlyph(m_assembly.topOrRight);
     682    LayoutRect leftGlyphPaintRect = paintGlyph(style, info, bottomOrLeft, leftGlyphOrigin, TrimRight);
     683
     684    FloatRect rightGlyphBounds = boundsForGlyph(topOrRight);
    625685    LayoutPoint rightGlyphOrigin(operatorTopLeft.x() + stretchSize() - rightGlyphBounds.width(), baselineY);
    626     LayoutRect rightGlyphPaintRect = paintGlyph(style, info, m_assembly.topOrRight, rightGlyphOrigin, TrimLeft);
    627 
    628     if (m_assembly.middle.font) {
     686    LayoutRect rightGlyphPaintRect = paintGlyph(style, info, topOrRight, rightGlyphOrigin, TrimLeft);
     687
     688    if (m_assembly.hasMiddle()) {
     689        auto middle = glyphDataForCodePointOrFallbackGlyph(style, m_assembly.middleCodePoint, m_assembly.middleFallbackGlyph);
     690
    629691        // Center the glyph origin between the start and end glyph paint extents.
    630692        LayoutPoint middleGlyphOrigin(operatorTopLeft.x(), baselineY);
    631693        middleGlyphOrigin.moveBy(LayoutPoint((rightGlyphPaintRect.x() - leftGlyphPaintRect.maxX()) / 2.0, 0));
    632         LayoutRect middleGlyphPaintRect = paintGlyph(style, info, m_assembly.middle, middleGlyphOrigin, TrimLeftAndRight);
     694        LayoutRect middleGlyphPaintRect = paintGlyph(style, info, middle, middleGlyphOrigin, TrimLeftAndRight);
    633695        fillWithHorizontalExtensionGlyph(style, info, LayoutPoint(leftGlyphPaintRect.maxX(), baselineY), LayoutPoint(middleGlyphPaintRect.x(), baselineY));
    634696        fillWithHorizontalExtensionGlyph(style, info, LayoutPoint(middleGlyphPaintRect.maxX(), baselineY), LayoutPoint(rightGlyphPaintRect.x(), baselineY));
     
    667729    GlyphData glyphData;
    668730    ASSERT(m_stretchType == StretchType::Unstretched || m_stretchType == StretchType::SizeVariant);
    669     if (m_stretchType == StretchType::Unstretched) {
    670         if (!getBaseGlyph(style, glyphData))
    671             return;
    672     } else if (m_stretchType == StretchType::SizeVariant) {
    673         ASSERT(m_variant.font);
    674         glyphData = m_variant;
    675     }
     731    if (!getBaseGlyph(style, glyphData))
     732        return;
     733    if (m_stretchType == StretchType::SizeVariant)
     734        glyphData.glyph = m_variantGlyph;
     735
    676736    GlyphBuffer buffer;
    677737    buffer.add(glyphData.glyph, glyphData.font, advanceWidthForGlyph(glyphData));
  • trunk/Source/WebCore/rendering/mathml/MathOperator.h

    r205111 r205163  
    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
     
    4041class MathOperator {
    4142public:
    42     MathOperator() { }
     43    MathOperator();
    4344    enum class Type { NormalOperator, DisplayOperator, VerticalOperator, HorizontalOperator };
    4445    void setOperator(const RenderStyle&, UChar32 baseCharacter, Type);
     
    5859private:
    5960    struct GlyphAssemblyData {
    60         GlyphData topOrRight;
    61         GlyphData extension;
    62         GlyphData bottomOrLeft;
    63         GlyphData middle;
     61        UChar32 topOrRightCodePoint { 0 };
     62        Glyph topOrRightFallbackGlyph { 0 };
     63        UChar32 extensionCodePoint { 0 };
     64        Glyph extensionFallbackGlyph { 0 };
     65        UChar32 bottomOrLeftCodePoint { 0 };
     66        Glyph bottomOrLeftFallbackGlyph { 0 };
     67        UChar32 middleCodePoint { 0 };
     68        Glyph middleFallbackGlyph { 0 };
     69
     70        bool hasExtension() const { return extensionCodePoint || extensionFallbackGlyph; }
     71        bool hasMiddle() const { return middleCodePoint || middleFallbackGlyph; }
     72        void initialize();
    6473    };
    6574    enum class StretchType { Unstretched, SizeVariant, GlyphAssembly };
     
    7786    bool getBaseGlyph(const RenderStyle& style, GlyphData& baseGlyph) const { return getGlyph(style, m_baseCharacter, baseGlyph); }
    7887    void setSizeVariant(const GlyphData&);
    79     void setGlyphAssembly(const GlyphAssemblyData&);
     88    void setGlyphAssembly(const RenderStyle&, const GlyphAssemblyData&);
    8089    void getMathVariantsWithFallback(const RenderStyle&, bool isVertical, Vector<Glyph>&, Vector<OpenTypeMathData::AssemblyPart>&);
    8190    void calculateDisplayStyleLargeOperator(const RenderStyle&);
    8291    void calculateStretchyData(const RenderStyle&, bool calculateMaxPreferredWidth, LayoutUnit targetSize = 0);
    83     bool calculateGlyphAssemblyFallback(const RenderStyle&, const Vector<OpenTypeMathData::AssemblyPart>&, GlyphAssemblyData&) const;
     92    bool calculateGlyphAssemblyFallback(const Vector<OpenTypeMathData::AssemblyPart>&, GlyphAssemblyData&) const;
    8493
    8594    LayoutRect paintGlyph(const RenderStyle&, PaintInfo&, const GlyphData&, const LayoutPoint& origin, GlyphPaintTrimming);
     
    93102    StretchType m_stretchType { StretchType::Unstretched };
    94103    union {
    95         GlyphData m_variant;
     104        Glyph m_variantGlyph;
    96105        GlyphAssemblyData m_assembly;
    97106    };
Note: See TracChangeset for help on using the changeset viewer.