WebFontDescription::WebFontDescription(const FontDescription& desc)
{
    family = desc.family().family();
    genericFamily = static_cast<GenericFamily>(desc.genericFamily());
    size = desc.specifiedSize();
    italic = desc.style() == FontStyleItalic;
    smallCaps = desc.variant() == FontVariantSmallCaps;
    weight = static_cast<Weight>(desc.weight());
    smoothing = static_cast<Smoothing>(desc.fontSmoothing());
    letterSpacing = desc.letterSpacing();
    wordSpacing = desc.wordSpacing();
}
ShapeResultSpacing::ShapeResultSpacing(const TextRun& run,
    const FontDescription& fontDescription)
    : m_textRun(run)
    , m_letterSpacing(fontDescription.letterSpacing())
    , m_wordSpacing(fontDescription.wordSpacing())
    , m_expansion(run.expansion())
    , m_expansionPerOpportunity(0)
    , m_expansionOpportunityCount(0)
    , m_textJustify(TextJustify::TextJustifyAuto)
    , m_hasSpacing(false)
    , m_normalizeSpace(run.normalizeSpace())
    , m_allowTabs(run.allowTabs())
    , m_isAfterExpansion(false)
    , m_isVerticalOffset(fontDescription.isVerticalAnyUpright())
{
    if (m_textRun.spacingDisabled())
        return;

    if (!m_letterSpacing && !m_wordSpacing && !m_expansion)
        return;

    m_hasSpacing = true;

    if (!m_expansion)
        return;

    // Setup for justifications (expansions.)
    m_textJustify = run.getTextJustify();
    m_isAfterExpansion = !run.allowsLeadingExpansion();

    bool isAfterExpansion = m_isAfterExpansion;
    m_expansionOpportunityCount = Character::expansionOpportunityCount(run,
        isAfterExpansion);
    if (isAfterExpansion && !run.allowsTrailingExpansion()) {
        ASSERT(m_expansionOpportunityCount > 0);
        --m_expansionOpportunityCount;
    }

    if (m_expansionOpportunityCount)
        m_expansionPerOpportunity = m_expansion / m_expansionOpportunityCount;
}