Changeset 74169 in webkit


Ignore:
Timestamp:
Dec 15, 2010 6:23:48 PM (13 years ago)
Author:
mitz@apple.com
Message:

Font support for the text-emphasis CSS property
Part of <rdar://problem/7720300> Support the CSS3 text-emphasis property
https://bugs.webkit.org/show_bug.cgi?id=48539

Reviewed by Darin Adler.

  • platform/graphics/Font.cpp:

(WebCore::Font::drawEmphasisMarks): Added. Calls through to drawEmphasisMarksFor{Simple,Complex}Text.
(WebCore::Font::canReceiveTextEmphasis): Added. For simple text, checks if the character should
have an emphasis mark.

  • platform/graphics/Font.h:
  • platform/graphics/FontFastPath.cpp:

(WebCore::Font::glyphDataForCharacter): Replaced the forceSmallCaps boolean with a FontDataVariant
parameter and made this function work with other variants.
(WebCore::Font::getEmphasisMarkGlyphData): Added. Returns glyph data for the first character of
the emphasis mark. This function may not work if the emphasis mark uses a complex script, but none
of the standard emphasis marks do so.
(WebCore::Font::emphasisMarkAscent): Added.
(WebCore::Font::emphasisMarkDescent): Added.
(WebCore::Font::emphasisMarkHeight): Added.
(WebCore::Font::getGlyphsAndAdvancesForSimpleText): Moved much of the logic from drawSimpleText()
into this new function, which also has a ForTextEmphasis parameter, which is passed along to the
WidthIterator.
(WebCore::Font::drawSimpleText): Left the drawing part here.
(WebCore::Font::drawEmphasisMarksForSimpleText): Added.
(WebCore::Font::drawGlyphBuffer): Removed the unused TextRun parameter.
(WebCore::offsetToMiddleOfGlyph): Added this helper.
(WebCore::offsetToMiddleOfGlyphAtIndex): Added this other helper.
(WebCore::Font::drawEmphasisMarks): Added. Draws emphasis marks for a given glyph buffer by placing
one mark centered above each glyph. Zero glyphs in the buffer indicate that no mark should be drawn.

  • platform/graphics/GraphicsContext.cpp:

(WebCore::GraphicsContext::drawEmphasisMarks): Added. Calls through to Font::drawEmphasisMarks().

  • platform/graphics/GraphicsContext.h:
  • platform/graphics/SimpleFontData.cpp:

(WebCore::SimpleFontData::SimpleFontData): Removed initialization of deleted members.
(WebCore::SimpleFontData::~SimpleFontData): Removed derived font data cleanup, which now happens
in ~DerivedFontData.
(WebCore::SimpleFontData::brokenIdeographFontData): Changed to use m_derivedFontData.
(WebCore::SimpleFontData::DerivedFontData::DerivedFontData): Added. This lazily-allocated struct
contains the SimpleFontData for small caps, broken ideograph and emphasis mark.
(WebCore::SimpleFontData::DerivedFontData::~DerivedFontData): Added.

  • platform/graphics/SimpleFontData.h:

(WebCore::SimpleFontData::variantFontData): Added. This is used by Font::glyphDataForCharacter().

  • platform/graphics/WidthIterator.cpp:

(WebCore::WidthIterator::WidthIterator): Added forTextEmphasis parameter.
(WebCore::WidthIterator::advance): When used for text emphasis, replace glyphs with the zero glyph
if they should not receive an emphasis mark.

  • platform/graphics/WidthIterator.h:
  • platform/graphics/chromium/FontChromiumWin.cpp:

(WebCore::Font::drawEmphasisMarksForComplexText): Added stub.

  • platform/graphics/chromium/FontLinux.cpp:

(WebCore::TextRunWalker::nextScriptRun): Updated for change to Font::glyphDataForCharacter().
(WebCore::TextRunWalker::setupFontForScriptRun): Ditto.
(WebCore::Font::drawEmphasisMarksForComplexText): Added stub.

  • platform/graphics/chromium/SimpleFontDataChromiumWin.cpp:

(WebCore::SimpleFontData::scaledFontData): Moved code from smallCapsFontData() here and generalized.
(WebCore::SimpleFontData::smallCapsFontData): Adopted m_derivedFontData and scaledFontData().
(WebCore::SimpleFontData::emphasisMarkFontData): Added.

  • platform/graphics/chromium/SimpleFontDataLinux.cpp:

(WebCore::SimpleFontData::scaledFontData): Moved code from smallCapsFontData() here and generalized.
(WebCore::SimpleFontData::smallCapsFontData): Adopted m_derivedFontData and scaledFontData().
(WebCore::SimpleFontData::emphasisMarkFontData): Added.

  • platform/graphics/efl/FontEfl.cpp:

(WebCore::Font::drawEmphasisMarksForComplexText): Added stub.

  • platform/graphics/freetype/SimpleFontDataFreeType.cpp:

(WebCore::SimpleFontData::scaledFontData): Moved code from smallCapsFontData() here and generalized.
(WebCore::SimpleFontData::smallCapsFontData): Adopted m_derivedFontData and scaledFontData().
(WebCore::SimpleFontData::emphasisMarkFontData): Added.

  • platform/graphics/gtk/FontGtk.cpp:

(WebCore::Font::drawEmphasisMarksForComplexText): Added stub.

  • platform/graphics/haiku/FontHaiku.cpp:

(WebCore::Font::drawEmphasisMarksForComplexText): Added stub.

  • platform/graphics/haiku/SimpleFontDataHaiku.cpp:

(WebCore::SimpleFontData::scaledFontData): Moved code from smallCapsFontData() here and generalized.
(WebCore::SimpleFontData::smallCapsFontData): Adopted m_derivedFontData and scaledFontData().
(WebCore::SimpleFontData::emphasisMarkFontData): Added.

  • platform/graphics/mac/ComplexTextController.cpp:

(WebCore::ComplexTextController::ComplexTextController): Added forTextEmphasis parameter.
(WebCore::ComplexTextController::collectComplexTextRuns): Updated for change to Font::glyphDataForCharacter().
(WebCore::ComplexTextController::adjustGlyphsAndAdvances): When used for text emphasis, replace glyphs with the zero glyph
if they should not receive an emphasis mark.

  • platform/graphics/mac/ComplexTextController.h:
  • platform/graphics/mac/FontComplexTextMac.cpp:

(WebCore::Font::getGlyphsAndAdvancesForComplexText): Moved much of the logic from drawComplexText()
into this new function, which also has a ForTextEmphasis parameter, which is passed along to the
ComplexTextController.
(WebCore::Font::drawComplexText): Left the drawing part here.
(WebCore::Font::drawEmphasisMarksForComplexText): Added.

  • platform/graphics/mac/SimpleFontDataMac.mm:

(WebCore::SimpleFontData::platformDestroy): Adopted m_derivedFontData.
(WebCore::SimpleFontData::scaledFontData): Moved code from smallCapsFontData() here and generalized.
(WebCore::SimpleFontData::smallCapsFontData): Adopted m_derivedFontData and scaledFontData().
(WebCore::SimpleFontData::emphasisMarkFontData): Added.

  • platform/graphics/pango/SimpleFontDataPango.cpp:

(WebCore::SimpleFontData::platformDestroy): Removed redundant clearing of derived font.
(WebCore::SimpleFontData::scaledFontData): Moved code from smallCapsFontData() here and generalized.
(WebCore::SimpleFontData::smallCapsFontData): Adopted m_derivedFontData and scaledFontData().
(WebCore::SimpleFontData::emphasisMarkFontData): Added.

  • platform/graphics/qt/FontQt.cpp:

(WebCore::Font::emphasisMarkAscent): Added stub.
(WebCore::Font::emphasisMarkDescent): Ditto.
(WebCore::Font::emphasisMarkHeight): Ditto.
(WebCore::Font::drawEmphasisMarksForSimpleText): Ditto.
(WebCore::Font::drawEmphasisMarksForComplexText): Ditto.

  • platform/graphics/win/FontWin.cpp:

(WebCore::Font::getGlyphsAndAdvancesForComplexText): Moved much of the logic from drawComplexText()
into this new function, which also has a ForTextEmphasis parameter. Currently returns an empty
glyph buffer for text emphasis.
(WebCore::Font::drawComplexText): Left the drawing part here.
(WebCore::Font::drawEmphasisMarksForComplexText): Added.

  • platform/graphics/win/SimpleFontDataWin.cpp:

(WebCore::SimpleFontData::scaledFontData): Moved code from smallCapsFontData() here and generalized.
(WebCore::SimpleFontData::smallCapsFontData): Adopted m_derivedFontData and scaledFontData().
(WebCore::SimpleFontData::emphasisMarkFontData): Added.

  • platform/graphics/win/UniscribeController.cpp:

(WebCore::UniscribeController::advance): Updated for change to Font::glyphDataForCharacter().

  • platform/graphics/wince/FontWinCE.cpp:

(WebCore::Font::drawEmphasisMarksForComplexText): Added stub.

  • platform/graphics/wince/SimpleFontDataWinCE.cpp:

(WebCore::SimpleFontData::platformDestroy): Removed redundant clearing of derived font.
(WebCore::SimpleFontData::scaledFontData): Moved code from smallCapsFontData() here and generalized.
(WebCore::SimpleFontData::smallCapsFontData): Adopted m_derivedFontData and scaledFontData().
(WebCore::SimpleFontData::emphasisMarkFontData): Added.

  • platform/graphics/wx/FontWx.cpp:

(WebCore::Font::getGlyphsAndAdvancesForComplexText): Added stub.
(WebCore::Font::drawComplexText): Updated for removal of unused TextRun parameter to drawGlyphBuffer().
(WebCore::Font::drawEmphasisMarksForComplexText): Added.

  • platform/graphics/wx/SimpleFontDataWx.cpp:

(WebCore::SimpleFontData::scaledFontData): Moved code from smallCapsFontData() here and generalized.
(WebCore::SimpleFontData::smallCapsFontData): Adopted m_derivedFontData and scaledFontData().
(WebCore::SimpleFontData::emphasisMarkFontData): Added.

  • platform/text/CharacterNames.h: Added characters used in Font::canReceiveTextEmphasis().
Location:
trunk/WebCore
Files:
33 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r74168 r74169  
     12010-12-15  Dan Bernstein  <mitz@apple.com>
     2
     3        Reviewed by Darin Adler.
     4
     5        Font support for the text-emphasis CSS property
     6        Part of <rdar://problem/7720300> Support the CSS3 text-emphasis property
     7        https://bugs.webkit.org/show_bug.cgi?id=48539
     8
     9        * platform/graphics/Font.cpp:
     10        (WebCore::Font::drawEmphasisMarks): Added. Calls through to drawEmphasisMarksFor{Simple,Complex}Text.
     11        (WebCore::Font::canReceiveTextEmphasis): Added. For simple text, checks if the character should
     12        have an emphasis mark.
     13
     14        * platform/graphics/Font.h:
     15
     16        * platform/graphics/FontFastPath.cpp:
     17        (WebCore::Font::glyphDataForCharacter): Replaced the forceSmallCaps boolean with a FontDataVariant
     18        parameter and made this function work with other variants.
     19        (WebCore::Font::getEmphasisMarkGlyphData): Added. Returns glyph data for the first character of
     20        the emphasis mark. This function may not work if the emphasis mark uses a complex script, but none
     21        of the standard emphasis marks do so.
     22        (WebCore::Font::emphasisMarkAscent): Added.
     23        (WebCore::Font::emphasisMarkDescent): Added.
     24        (WebCore::Font::emphasisMarkHeight): Added.
     25        (WebCore::Font::getGlyphsAndAdvancesForSimpleText): Moved much of the logic from drawSimpleText()
     26        into this new function, which also has a ForTextEmphasis parameter, which is passed along to the
     27        WidthIterator.
     28        (WebCore::Font::drawSimpleText): Left the drawing part here.
     29        (WebCore::Font::drawEmphasisMarksForSimpleText): Added.
     30        (WebCore::Font::drawGlyphBuffer): Removed the unused TextRun parameter.
     31        (WebCore::offsetToMiddleOfGlyph): Added this helper.
     32        (WebCore::offsetToMiddleOfGlyphAtIndex): Added this other helper.
     33        (WebCore::Font::drawEmphasisMarks): Added. Draws emphasis marks for a given glyph buffer by placing
     34        one mark centered above each glyph. Zero glyphs in the buffer indicate that no mark should be drawn.
     35
     36        * platform/graphics/GraphicsContext.cpp:
     37        (WebCore::GraphicsContext::drawEmphasisMarks): Added. Calls through to Font::drawEmphasisMarks().
     38
     39        * platform/graphics/GraphicsContext.h:
     40
     41        * platform/graphics/SimpleFontData.cpp:
     42        (WebCore::SimpleFontData::SimpleFontData): Removed initialization of deleted members.
     43        (WebCore::SimpleFontData::~SimpleFontData): Removed derived font data cleanup, which now happens
     44        in ~DerivedFontData.
     45        (WebCore::SimpleFontData::brokenIdeographFontData): Changed to use m_derivedFontData.
     46        (WebCore::SimpleFontData::DerivedFontData::DerivedFontData): Added. This lazily-allocated struct
     47        contains the SimpleFontData for small caps, broken ideograph and emphasis mark.
     48        (WebCore::SimpleFontData::DerivedFontData::~DerivedFontData): Added.
     49
     50        * platform/graphics/SimpleFontData.h:
     51        (WebCore::SimpleFontData::variantFontData): Added. This is used by Font::glyphDataForCharacter().
     52
     53        * platform/graphics/WidthIterator.cpp:
     54        (WebCore::WidthIterator::WidthIterator): Added forTextEmphasis parameter.
     55        (WebCore::WidthIterator::advance): When used for text emphasis, replace glyphs with the zero glyph
     56        if they should not receive an emphasis mark.
     57
     58        * platform/graphics/WidthIterator.h:
     59
     60        * platform/graphics/chromium/FontChromiumWin.cpp:
     61        (WebCore::Font::drawEmphasisMarksForComplexText): Added stub.
     62
     63        * platform/graphics/chromium/FontLinux.cpp:
     64        (WebCore::TextRunWalker::nextScriptRun): Updated for change to Font::glyphDataForCharacter().
     65        (WebCore::TextRunWalker::setupFontForScriptRun): Ditto.
     66        (WebCore::Font::drawEmphasisMarksForComplexText): Added stub.
     67
     68        * platform/graphics/chromium/SimpleFontDataChromiumWin.cpp:
     69        (WebCore::SimpleFontData::scaledFontData): Moved code from smallCapsFontData() here and generalized.
     70        (WebCore::SimpleFontData::smallCapsFontData): Adopted m_derivedFontData and scaledFontData().
     71        (WebCore::SimpleFontData::emphasisMarkFontData): Added.
     72
     73        * platform/graphics/chromium/SimpleFontDataLinux.cpp:
     74        (WebCore::SimpleFontData::scaledFontData): Moved code from smallCapsFontData() here and generalized.
     75        (WebCore::SimpleFontData::smallCapsFontData): Adopted m_derivedFontData and scaledFontData().
     76        (WebCore::SimpleFontData::emphasisMarkFontData): Added.
     77
     78        * platform/graphics/efl/FontEfl.cpp:
     79        (WebCore::Font::drawEmphasisMarksForComplexText): Added stub.
     80
     81        * platform/graphics/freetype/SimpleFontDataFreeType.cpp:
     82        (WebCore::SimpleFontData::scaledFontData): Moved code from smallCapsFontData() here and generalized.
     83        (WebCore::SimpleFontData::smallCapsFontData): Adopted m_derivedFontData and scaledFontData().
     84        (WebCore::SimpleFontData::emphasisMarkFontData): Added.
     85
     86        * platform/graphics/gtk/FontGtk.cpp:
     87        (WebCore::Font::drawEmphasisMarksForComplexText): Added stub.
     88
     89        * platform/graphics/haiku/FontHaiku.cpp:
     90        (WebCore::Font::drawEmphasisMarksForComplexText): Added stub.
     91
     92        * platform/graphics/haiku/SimpleFontDataHaiku.cpp:
     93        (WebCore::SimpleFontData::scaledFontData): Moved code from smallCapsFontData() here and generalized.
     94        (WebCore::SimpleFontData::smallCapsFontData): Adopted m_derivedFontData and scaledFontData().
     95        (WebCore::SimpleFontData::emphasisMarkFontData): Added.
     96
     97        * platform/graphics/mac/ComplexTextController.cpp:
     98        (WebCore::ComplexTextController::ComplexTextController): Added forTextEmphasis parameter.
     99        (WebCore::ComplexTextController::collectComplexTextRuns): Updated for change to Font::glyphDataForCharacter().
     100        (WebCore::ComplexTextController::adjustGlyphsAndAdvances): When used for text emphasis, replace glyphs with the zero glyph
     101        if they should not receive an emphasis mark.
     102
     103        * platform/graphics/mac/ComplexTextController.h:
     104
     105        * platform/graphics/mac/FontComplexTextMac.cpp:
     106        (WebCore::Font::getGlyphsAndAdvancesForComplexText): Moved much of the logic from drawComplexText()
     107        into this new function, which also has a ForTextEmphasis parameter, which is passed along to the
     108        ComplexTextController.
     109        (WebCore::Font::drawComplexText): Left the drawing part here.
     110        (WebCore::Font::drawEmphasisMarksForComplexText): Added.
     111
     112        * platform/graphics/mac/SimpleFontDataMac.mm:
     113        (WebCore::SimpleFontData::platformDestroy): Adopted m_derivedFontData.
     114        (WebCore::SimpleFontData::scaledFontData): Moved code from smallCapsFontData() here and generalized.
     115        (WebCore::SimpleFontData::smallCapsFontData): Adopted m_derivedFontData and scaledFontData().
     116        (WebCore::SimpleFontData::emphasisMarkFontData): Added.
     117
     118        * platform/graphics/pango/SimpleFontDataPango.cpp:
     119        (WebCore::SimpleFontData::platformDestroy): Removed redundant clearing of derived font.
     120        (WebCore::SimpleFontData::scaledFontData): Moved code from smallCapsFontData() here and generalized.
     121        (WebCore::SimpleFontData::smallCapsFontData): Adopted m_derivedFontData and scaledFontData().
     122        (WebCore::SimpleFontData::emphasisMarkFontData): Added.
     123
     124        * platform/graphics/qt/FontQt.cpp:
     125        (WebCore::Font::emphasisMarkAscent): Added stub.
     126        (WebCore::Font::emphasisMarkDescent): Ditto.
     127        (WebCore::Font::emphasisMarkHeight): Ditto.
     128        (WebCore::Font::drawEmphasisMarksForSimpleText): Ditto.
     129        (WebCore::Font::drawEmphasisMarksForComplexText): Ditto.
     130
     131        * platform/graphics/win/FontWin.cpp:
     132        (WebCore::Font::getGlyphsAndAdvancesForComplexText): Moved much of the logic from drawComplexText()
     133        into this new function, which also has a ForTextEmphasis parameter. Currently returns an empty
     134        glyph buffer for text emphasis.
     135        (WebCore::Font::drawComplexText): Left the drawing part here.
     136        (WebCore::Font::drawEmphasisMarksForComplexText): Added.
     137
     138        * platform/graphics/win/SimpleFontDataWin.cpp:
     139        (WebCore::SimpleFontData::scaledFontData): Moved code from smallCapsFontData() here and generalized.
     140        (WebCore::SimpleFontData::smallCapsFontData): Adopted m_derivedFontData and scaledFontData().
     141        (WebCore::SimpleFontData::emphasisMarkFontData): Added.
     142
     143        * platform/graphics/win/UniscribeController.cpp:
     144        (WebCore::UniscribeController::advance): Updated for change to Font::glyphDataForCharacter().
     145
     146        * platform/graphics/wince/FontWinCE.cpp:
     147        (WebCore::Font::drawEmphasisMarksForComplexText): Added stub.
     148
     149        * platform/graphics/wince/SimpleFontDataWinCE.cpp:
     150        (WebCore::SimpleFontData::platformDestroy): Removed redundant clearing of derived font.
     151        (WebCore::SimpleFontData::scaledFontData): Moved code from smallCapsFontData() here and generalized.
     152        (WebCore::SimpleFontData::smallCapsFontData): Adopted m_derivedFontData and scaledFontData().
     153        (WebCore::SimpleFontData::emphasisMarkFontData): Added.
     154
     155        * platform/graphics/wx/FontWx.cpp:
     156        (WebCore::Font::getGlyphsAndAdvancesForComplexText): Added stub.
     157        (WebCore::Font::drawComplexText): Updated for removal of unused TextRun parameter to drawGlyphBuffer().
     158        (WebCore::Font::drawEmphasisMarksForComplexText): Added.
     159
     160        * platform/graphics/wx/SimpleFontDataWx.cpp:
     161        (WebCore::SimpleFontData::scaledFontData): Moved code from smallCapsFontData() here and generalized.
     162        (WebCore::SimpleFontData::smallCapsFontData): Adopted m_derivedFontData and scaledFontData().
     163        (WebCore::SimpleFontData::emphasisMarkFontData): Added.
     164
     165        * platform/text/CharacterNames.h: Added characters used in Font::canReceiveTextEmphasis().
     166
    11672010-12-15  Beth Dakin  <bdakin@apple.com>
    2168
  • trunk/WebCore/platform/graphics/Font.cpp

    r74096 r74169  
    157157}
    158158
     159void Font::drawEmphasisMarks(GraphicsContext* context, const TextRun& run, const AtomicString& mark, const FloatPoint& point, int from, int to) const
     160{
     161    if (m_fontList && m_fontList->loadingCustomFonts())
     162        return;
     163
     164    if (to < 0)
     165        to = run.length();
     166
     167#if ENABLE(SVG_FONTS)
     168    // FIXME: Implement for SVG fonts.
     169    if (primaryFont()->isSVGFont())
     170        return;
     171#endif
     172
     173    if (codePath(run) != Complex)
     174        drawEmphasisMarksForSimpleText(context, run, mark, point, from, to);
     175    else
     176        drawEmphasisMarksForComplexText(context, run, mark, point, from, to);
     177}
     178
    159179float Font::floatWidth(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
    160180{
     
    439459}
    440460
    441 }
     461bool Font::canReceiveTextEmphasis(UChar32 c)
     462{
     463    CharCategory category = Unicode::category(c);
     464    if (category & (Separator_Space | Separator_Line | Separator_Paragraph | Other_NotAssigned | Other_Control | Other_Format))
     465        return false;
     466
     467    // Additional word-separator characters listed in CSS Text Level 3 Editor's Draft 3 November 2010.
     468    if (c == ethiopicWordspace || c == aegeanWordSeparatorLine || c == aegeanWordSeparatorDot
     469        || c == ugariticWordDivider || c == tibetanMarkIntersyllabicTsheg || c == tibetanMarkDelimiterTshegBstar)
     470        return false;
     471
     472    return true;
     473}
     474
     475}
  • trunk/WebCore/platform/graphics/Font.h

    r74005 r74169  
    9494
    9595    void drawText(GraphicsContext*, const TextRun&, const FloatPoint&, int from = 0, int to = -1) const;
     96    void drawEmphasisMarks(GraphicsContext*, const TextRun&, const AtomicString& mark, const FloatPoint&, int from = 0, int to = -1) const;
    9697
    9798    int width(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* glyphOverflow = 0) const { return lroundf(floatWidth(run, fallbackFonts, glyphOverflow)); }
     
    137138    int spaceWidth() const { return (int)ceilf(primaryFont()->adjustedSpaceWidth() + m_letterSpacing); }
    138139    float tabWidth(const SimpleFontData& fontData) const { return 8 * ceilf(fontData.adjustedSpaceWidth() + letterSpacing()); }
     140    int emphasisMarkAscent(const AtomicString&) const;
     141    int emphasisMarkDescent(const AtomicString&) const;
     142    int emphasisMarkHeight(const AtomicString&) const;
    139143
    140144    const SimpleFontData* primaryFont() const;
    141145    const FontData* fontDataAt(unsigned) const;
    142     GlyphData glyphDataForCharacter(UChar32, bool mirror, bool forceSmallCaps = false) const;
     146    GlyphData glyphDataForCharacter(UChar32, bool mirror, FontDataVariant = AutoVariant) const;
    143147    // Used for complex text, and does not utilize the glyph map cache.
    144148    const FontData* fontDataForCharacters(const UChar*, int length) const;
     
    165169#endif
    166170
     171    enum ForTextEmphasisOrNot { NotForTextEmphasis, ForTextEmphasis };
     172
     173    // Returns the initial in-stream advance.
     174    float getGlyphsAndAdvancesForSimpleText(const TextRun&, int from, int to, GlyphBuffer&, ForTextEmphasisOrNot = NotForTextEmphasis) const;
    167175    void drawSimpleText(GraphicsContext*, const TextRun&, const FloatPoint&, int from, int to) const;
     176    void drawEmphasisMarksForSimpleText(GraphicsContext*, const TextRun&, const AtomicString& mark, const FloatPoint&, int from, int to) const;
    168177    void drawGlyphs(GraphicsContext*, const SimpleFontData*, const GlyphBuffer&, int from, int to, const FloatPoint&) const;
    169     void drawGlyphBuffer(GraphicsContext*, const GlyphBuffer&, const TextRun&, const FloatPoint&) const;
     178    void drawGlyphBuffer(GraphicsContext*, const GlyphBuffer&, const FloatPoint&) const;
     179    void drawEmphasisMarks(GraphicsContext* context, const GlyphBuffer&, const AtomicString&, const FloatPoint&) const;
    170180    float floatWidthForSimpleText(const TextRun&, GlyphBuffer*, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
    171181    int offsetForPositionForSimpleText(const TextRun&, float position, bool includePartialGlyphs) const;
    172182    FloatRect selectionRectForSimpleText(const TextRun&, const FloatPoint&, int h, int from, int to) const;
    173183
     184    bool getEmphasisMarkGlyphData(const AtomicString&, GlyphData&) const;
     185
    174186    static bool canReturnFallbackFontsForComplexText();
    175187
    176188    CodePath codePath(const TextRun&) const;
     189
     190    // Returns the initial in-stream advance.
     191    float getGlyphsAndAdvancesForComplexText(const TextRun&, int from, int to, GlyphBuffer&, ForTextEmphasisOrNot = NotForTextEmphasis) const;
    177192    void drawComplexText(GraphicsContext*, const TextRun&, const FloatPoint&, int from, int to) const;
     193    void drawEmphasisMarksForComplexText(GraphicsContext*, const TextRun&, const AtomicString& mark, const FloatPoint&, int from, int to) const;
    178194    float floatWidthForComplexText(const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
    179195    int offsetForPositionForComplexText(const TextRun&, float position, bool includePartialGlyphs) const;
     
    197213    static bool treatAsSpace(UChar c) { return c == ' ' || c == '\t' || c == '\n' || c == noBreakSpace; }
    198214    static bool treatAsZeroWidthSpace(UChar c) { return c < 0x20 || (c >= 0x7F && c < 0xA0) || c == softHyphen || (c >= 0x200c && c <= 0x200f) || (c >= 0x202a && c <= 0x202e) || c == objectReplacementCharacter; }
     215    static bool canReceiveTextEmphasis(UChar32 c);
    199216
    200217    static inline UChar normalizeSpaces(UChar character)
  • trunk/WebCore/platform/graphics/FontFastPath.cpp

    r74005 r74169  
    11/**
    2  * Copyright (C) 2003, 2006 Apple Computer, Inc.
     2 * Copyright (C) 2003, 2006, 2010 Apple Inc. All rights reserved.
    33 * Copyright (C) 2008 Holger Hans Peter Freyther
    44 * Copyright (C) 2009 Torch Mobile, Inc.
     
    4141namespace WebCore {
    4242
    43 GlyphData Font::glyphDataForCharacter(UChar32 c, bool mirror, bool forceSmallCaps) const
     43GlyphData Font::glyphDataForCharacter(UChar32 c, bool mirror, FontDataVariant variant) const
    4444{
    4545    ASSERT(isMainThread());
    4646
    47     bool useSmallCapsFont = forceSmallCaps;
    48     if (m_fontDescription.smallCaps()) {
    49         UChar32 upperC = toUpper(c);
    50         if (upperC != c) {
    51             c = upperC;
    52             useSmallCapsFont = true;
    53         }
     47    if (variant == AutoVariant) {
     48        if (m_fontDescription.smallCaps()) {
     49            UChar32 upperC = toUpper(c);
     50            if (upperC != c) {
     51                c = upperC;
     52                variant = SmallCapsVariant;
     53            } else
     54                variant = NormalVariant;
     55        } else
     56            variant = NormalVariant;
    5457    }
    5558
     
    6972
    7073    GlyphPage* page;
    71     if (!useSmallCapsFont) {
    72         // Fastest loop, for the common case (not small caps).
     74    if (variant == NormalVariant) {
     75        // Fastest loop, for the common case (normal variant).
    7376        while (true) {
    7477            page = node->page();
     
    109112                GlyphData data = page->glyphDataForCharacter(c);
    110113                if (data.fontData) {
    111                     // The smallCapsFontData function should not normally return 0.
     114                    // The variantFontData function should not normally return 0.
    112115                    // But if it does, we will just render the capital letter big.
    113                     const SimpleFontData* smallCapsFontData = data.fontData->smallCapsFontData(m_fontDescription);
    114                     if (!smallCapsFontData)
     116                    const SimpleFontData* variantFontData = data.fontData->variantFontData(m_fontDescription, variant);
     117                    if (!variantFontData)
    115118                        return data;
    116119
    117                     GlyphPageTreeNode* smallCapsNode = GlyphPageTreeNode::getRootChild(smallCapsFontData, pageNumber);
    118                     const GlyphPage* smallCapsPage = smallCapsNode->page();
    119                     if (smallCapsPage) {
    120                         GlyphData data = smallCapsPage->glyphDataForCharacter(c);
     120                    GlyphPageTreeNode* variantNode = GlyphPageTreeNode::getRootChild(variantFontData, pageNumber);
     121                    const GlyphPage* variantPage = variantNode->page();
     122                    if (variantPage) {
     123                        GlyphData data = variantPage->glyphDataForCharacter(c);
    121124                        if (data.fontData)
    122125                            return data;
    123126                    }
    124127
    125                     // Do not attempt system fallback off the smallCapsFontData. This is the very unlikely case that
     128                    // Do not attempt system fallback off the variantFontData. This is the very unlikely case that
    126129                    // a font has the lowercase character but the small caps font does not have its uppercase version.
    127                     return smallCapsFontData->missingGlyphData();
     130                    return variantFontData->missingGlyphData();
    128131                }
    129132
     
    158161    }
    159162    const SimpleFontData* characterFontData = fontCache()->getFontDataForCharacters(*this, codeUnits, codeUnitsLength);
    160     if (useSmallCapsFont && characterFontData)
    161         characterFontData = characterFontData->smallCapsFontData(m_fontDescription);
     163    if (variant != NormalVariant && characterFontData)
     164        characterFontData = characterFontData->variantFontData(m_fontDescription, variant);
    162165    if (characterFontData) {
    163166        // Got the fallback glyph and font.
     
    165168        GlyphData data = fallbackPage && fallbackPage->fontDataForCharacter(c) ? fallbackPage->glyphDataForCharacter(c) : characterFontData->missingGlyphData();
    166169        // Cache it so we don't have to do system fallback again next time.
    167         if (!useSmallCapsFont) {
     170        if (variant == NormalVariant) {
    168171#if OS(WINCE)
    169172            // missingGlyphData returns a null character, which is not suitable for GDI to display.
     
    183186    // FIXME: It would be nicer to use the missing glyph from the last resort font instead.
    184187    GlyphData data = primaryFont()->missingGlyphData();
    185     if (!useSmallCapsFont) {
     188    if (variant == NormalVariant) {
    186189#if OS(WINCE)
    187190        // See comment about WINCE GDI handling near setGlyphDataForCharacter above.
     
    195198}
    196199
    197 void Font::drawSimpleText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const
    198 {
    199     // This glyph buffer holds our glyphs+advances+font data for each glyph.
    200     GlyphBuffer glyphBuffer;
    201 
    202     float startX = point.x();
    203     WidthIterator it(this, run);
     200// FIXME: This function may not work if the emphasis mark uses a complex script, but none of the
     201// standard emphasis marks do so.
     202bool Font::getEmphasisMarkGlyphData(const AtomicString& mark, GlyphData& glyphData) const
     203{
     204    if (mark.isEmpty())
     205        return false;
     206
     207#if ENABLE(SVG_FONTS)
     208    // FIXME: Implement for SVG fonts.
     209    if (primaryFont()->isSVGFont())
     210        return false;
     211#endif
     212
     213    UChar32 character = mark[0];
     214
     215    if (U16_IS_SURROGATE(character)) {
     216        if (!U16_IS_SURROGATE_LEAD(character))
     217            return false;
     218
     219        if (mark.length() < 2)
     220            return false;
     221
     222        UChar low = mark[1];
     223        if (!U16_IS_TRAIL(low))
     224            return false;
     225
     226        character = U16_GET_SUPPLEMENTARY(character, low);
     227    }
     228
     229    glyphData = glyphDataForCharacter(character, false, EmphasisMarkVariant);
     230    return true;
     231}
     232
     233int Font::emphasisMarkAscent(const AtomicString& mark) const
     234{
     235    GlyphData markGlyphData;
     236    if (!getEmphasisMarkGlyphData(mark, markGlyphData))
     237        return 0;
     238
     239    const SimpleFontData* markFontData = markGlyphData.fontData;
     240    ASSERT(markFontData);
     241    if (!markFontData)
     242        return 0;
     243
     244    return markFontData->ascent();
     245}
     246
     247int Font::emphasisMarkDescent(const AtomicString& mark) const
     248{
     249    GlyphData markGlyphData;
     250    if (!getEmphasisMarkGlyphData(mark, markGlyphData))
     251        return 0;
     252
     253    const SimpleFontData* markFontData = markGlyphData.fontData;
     254    ASSERT(markFontData);
     255    if (!markFontData)
     256        return 0;
     257
     258    return markFontData->descent();
     259}
     260
     261int Font::emphasisMarkHeight(const AtomicString& mark) const
     262{
     263    GlyphData markGlyphData;
     264    if (!getEmphasisMarkGlyphData(mark, markGlyphData))
     265        return 0;
     266
     267    const SimpleFontData* markFontData = markGlyphData.fontData;
     268    ASSERT(markFontData);
     269    if (!markFontData)
     270        return 0;
     271
     272    return markFontData->height();
     273}
     274
     275float Font::getGlyphsAndAdvancesForSimpleText(const TextRun& run, int from, int to, GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot forTextEmphasis) const
     276{
     277    float initialAdvance;
     278
     279    WidthIterator it(this, run, false, forTextEmphasis);
    204280    it.advance(from);
    205281    float beforeWidth = it.m_runWidthSoFar;
    206282    it.advance(to, &glyphBuffer);
    207    
    208     // We couldn't generate any glyphs for the run.  Give up.
     283
    209284    if (glyphBuffer.isEmpty())
    210         return;
    211    
     285        return 0;
     286
    212287    float afterWidth = it.m_runWidthSoFar;
    213288
     
    215290        float finalRoundingWidth = it.m_finalRoundingWidth;
    216291        it.advance(run.length());
    217         startX += finalRoundingWidth + it.m_runWidthSoFar - afterWidth;
     292        initialAdvance = finalRoundingWidth + it.m_runWidthSoFar - afterWidth;
    218293    } else
    219         startX += beforeWidth;
    220 
    221     // Swap the order of the glyphs if right-to-left.
    222     if (run.rtl())
     294        initialAdvance = beforeWidth;
     295
     296    if (run.rtl()) {
    223297        for (int i = 0, end = glyphBuffer.size() - 1; i < glyphBuffer.size() / 2; ++i, --end)
    224298            glyphBuffer.swap(i, end);
    225 
    226     // Calculate the starting point of the glyphs to be displayed by adding
    227     // all the advances up to the first glyph.
     299    }
     300
     301    return initialAdvance;
     302}
     303
     304void Font::drawSimpleText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const
     305{
     306    // This glyph buffer holds our glyphs+advances+font data for each glyph.
     307    GlyphBuffer glyphBuffer;
     308
     309    float startX = point.x() + getGlyphsAndAdvancesForSimpleText(run, from, to, glyphBuffer);
     310
     311    if (glyphBuffer.isEmpty())
     312        return;
     313
    228314    FloatPoint startPoint(startX, point.y());
    229     drawGlyphBuffer(context, glyphBuffer, run, startPoint);
    230 }
    231 
    232 void Font::drawGlyphBuffer(GraphicsContext* context, const GlyphBuffer& glyphBuffer, const TextRun&, const FloatPoint& point) const
     315    drawGlyphBuffer(context, glyphBuffer, startPoint);
     316}
     317
     318void Font::drawEmphasisMarksForSimpleText(GraphicsContext* context, const TextRun& run, const AtomicString& mark, const FloatPoint& point, int from, int to) const
     319{
     320    GlyphBuffer glyphBuffer;
     321    float initialAdvance = getGlyphsAndAdvancesForSimpleText(run, from, to, glyphBuffer, ForTextEmphasis);
     322
     323    if (glyphBuffer.isEmpty())
     324        return;
     325
     326    drawEmphasisMarks(context, glyphBuffer, mark, FloatPoint(point.x() + initialAdvance, point.y()));
     327}
     328
     329void Font::drawGlyphBuffer(GraphicsContext* context, const GlyphBuffer& glyphBuffer, const FloatPoint& point) const
    233330{   
    234331    // Draw each contiguous run of glyphs that use the same font data.
     
    257354}
    258355
     356inline static float offsetToMiddleOfGlyph(const SimpleFontData* fontData, Glyph glyph)
     357{
     358    if (fontData->orientation() == Horizontal) {
     359        FloatRect bounds = fontData->boundsForGlyph(glyph);
     360        return bounds.x() + bounds.width() / 2;
     361    }
     362    // FIXME: Use glyph bounds once they make sense for vertical fonts.
     363    return fontData->widthForGlyph(glyph) / 2;
     364}
     365
     366inline static float offsetToMiddleOfGlyphAtIndex(const GlyphBuffer& glyphBuffer, size_t i)
     367{
     368    return offsetToMiddleOfGlyph(glyphBuffer.fontDataAt(i), glyphBuffer.glyphAt(i));
     369}
     370
     371void Font::drawEmphasisMarks(GraphicsContext* context, const GlyphBuffer& glyphBuffer, const AtomicString& mark, const FloatPoint& point) const
     372{
     373    GlyphData markGlyphData;
     374    if (!getEmphasisMarkGlyphData(mark, markGlyphData))
     375        return;
     376
     377    const SimpleFontData* markFontData = markGlyphData.fontData;
     378    ASSERT(markFontData);
     379    if (!markFontData)
     380        return;
     381
     382    Glyph markGlyph = markGlyphData.glyph;
     383    Glyph spaceGlyph = markFontData->spaceGlyph();
     384
     385    float middleOfLastGlyph = offsetToMiddleOfGlyphAtIndex(glyphBuffer, 0);
     386    FloatPoint startPoint(point.x() + middleOfLastGlyph - offsetToMiddleOfGlyph(markFontData, markGlyph), point.y());
     387
     388    GlyphBuffer markBuffer;
     389    for (int i = 0; i + 1 < glyphBuffer.size(); ++i) {
     390        float middleOfNextGlyph = offsetToMiddleOfGlyphAtIndex(glyphBuffer, i + 1);
     391        float advance = glyphBuffer.advanceAt(i) - middleOfLastGlyph + middleOfNextGlyph;
     392        markBuffer.add(glyphBuffer.glyphAt(i) ? markGlyph : spaceGlyph, markFontData, advance);
     393        middleOfLastGlyph = middleOfNextGlyph;
     394    }
     395    markBuffer.add(glyphBuffer.glyphAt(glyphBuffer.size() - 1) ? markGlyph : spaceGlyph, markFontData, 0);
     396
     397    drawGlyphBuffer(context, markBuffer, startPoint);
     398}
     399
    259400float Font::floatWidthForSimpleText(const TextRun& run, GlyphBuffer* glyphBuffer, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
    260401{
  • trunk/WebCore/platform/graphics/GraphicsContext.cpp

    r74151 r74169  
    356356#endif
    357357
     358void GraphicsContext::drawEmphasisMarks(const Font& font, const TextRun& run, const AtomicString& mark, const IntPoint& point, int from, int to)
     359{
     360    if (paintingDisabled())
     361        return;
     362
     363    font.drawEmphasisMarks(this, run, mark, point, from, to);
     364}
     365
    358366void GraphicsContext::drawBidiText(const Font& font, const TextRun& run, const FloatPoint& point)
    359367{
  • trunk/WebCore/platform/graphics/GraphicsContext.h

    r74151 r74169  
    321321
    322322        void drawText(const Font&, const TextRun&, const IntPoint&, int from = 0, int to = -1);
     323        void drawEmphasisMarks(const Font&, const TextRun& , const AtomicString& mark, const IntPoint&, int from = 0, int to = -1);
    323324        void drawBidiText(const Font&, const TextRun&, const FloatPoint&);
    324325        void drawHighlightForText(const Font&, const TextRun&, const IntPoint&, int h, const Color& backgroundColor, ColorSpace, int from = 0, int to = -1);
  • trunk/WebCore/platform/graphics/SimpleFontData.cpp

    r71975 r74169  
    5858    , m_isLoading(isLoading)
    5959    , m_isBrokenIdeographFont(false)
    60     , m_smallCapsFontData(0)
    61     , m_brokenIdeographFontData(0)
    6260{
    6361    platformInit();
     
    7573    , m_isLoading(false)
    7674    , m_isBrokenIdeographFont(false)
    77     , m_smallCapsFontData(0)
    78     , m_brokenIdeographFontData(0)
    7975{
    8076    SVGFontFaceElement* svgFontFaceElement = m_svgFontData->svgFontFaceElement();
     
    187183    if (!isCustomFont())
    188184        GlyphPageTreeNode::pruneTreeFontData(this);
    189     else {
    190         if (m_smallCapsFontData)
    191             GlyphPageTreeNode::pruneTreeCustomFontData(m_smallCapsFontData);
    192 
    193         if (m_brokenIdeographFontData)
    194             GlyphPageTreeNode::pruneTreeCustomFontData(m_brokenIdeographFontData);
    195     }
    196 
    197     delete m_smallCapsFontData;
    198     delete m_brokenIdeographFontData;
    199185}
    200186
     
    211197SimpleFontData* SimpleFontData::brokenIdeographFontData() const
    212198{
    213     if (!m_brokenIdeographFontData) {
    214         m_brokenIdeographFontData = new SimpleFontData(m_platformData, isCustomFont(), false);
    215         m_brokenIdeographFontData->m_orientation = Vertical;
    216         m_brokenIdeographFontData->m_isBrokenIdeographFont = true;
    217     }
    218     return m_brokenIdeographFontData;
     199    if (!m_derivedFontData)
     200        m_derivedFontData = DerivedFontData::create(isCustomFont());
     201    if (!m_derivedFontData->brokenIdeograph) {
     202        m_derivedFontData->brokenIdeograph = new SimpleFontData(m_platformData, isCustomFont(), false);
     203        m_derivedFontData->brokenIdeograph->m_orientation = Vertical;
     204        m_derivedFontData->brokenIdeograph->m_isBrokenIdeographFont = true;
     205    }
     206    return m_derivedFontData->brokenIdeograph.get();
    219207}
    220208
     
    231219#endif
    232220
     221PassOwnPtr<SimpleFontData::DerivedFontData> SimpleFontData::DerivedFontData::create(bool forCustomFont)
     222{
     223    return adoptPtr(new DerivedFontData(forCustomFont));
     224}
     225
     226SimpleFontData::DerivedFontData::~DerivedFontData()
     227{
     228    if (!forCustomFont)
     229        return;
     230
     231    if (smallCaps)
     232        GlyphPageTreeNode::pruneTreeCustomFontData(smallCaps.get());
     233    if (emphasisMark)
     234        GlyphPageTreeNode::pruneTreeCustomFontData(emphasisMark.get());
     235    if (brokenIdeograph)
     236        GlyphPageTreeNode::pruneTreeCustomFontData(brokenIdeograph.get());
     237}
     238
    233239} // namespace WebCore
  • trunk/WebCore/platform/graphics/SimpleFontData.h

    r72459 r74169  
    6666class SVGFontData;
    6767
     68enum FontDataVariant { AutoVariant, NormalVariant, SmallCapsVariant, EmphasisMarkVariant };
    6869enum Pitch { UnknownPitch, FixedPitch, VariablePitch };
    6970
     
    7778
    7879    const FontPlatformData& platformData() const { return m_platformData; }
    79     SimpleFontData* smallCapsFontData(const FontDescription& fontDescription) const;
     80
     81    SimpleFontData* smallCapsFontData(const FontDescription&) const;
     82    SimpleFontData* emphasisMarkFontData(const FontDescription&) const;
     83
     84    SimpleFontData* variantFontData(const FontDescription& description, FontDataVariant variant) const
     85    {
     86        switch (variant) {
     87        case SmallCapsVariant:
     88            return smallCapsFontData(description);
     89        case EmphasisMarkVariant:
     90            return emphasisMarkFontData(description);
     91        case AutoVariant:
     92        case NormalVariant:
     93            break;
     94        }
     95        ASSERT_NOT_REACHED();
     96        return const_cast<SimpleFontData*>(this);
     97    }
    8098
    8199    SimpleFontData* brokenIdeographFontData() const;
     
    184202    void commonInit();
    185203
     204    SimpleFontData* scaledFontData(const FontDescription&, float scaleFactor) const;
     205
    186206#if (PLATFORM(WIN) && !OS(WINCE)) \
    187207    || (OS(WINDOWS) && PLATFORM(WX))
     
    227247    GlyphData m_missingGlyphData;
    228248
    229     mutable SimpleFontData* m_smallCapsFontData;
    230 
    231     mutable SimpleFontData* m_brokenIdeographFontData;
     249    struct DerivedFontData {
     250        static PassOwnPtr<DerivedFontData> create(bool forCustomFont);
     251        ~DerivedFontData();
     252
     253        bool forCustomFont;
     254        OwnPtr<SimpleFontData> smallCaps;
     255        OwnPtr<SimpleFontData> emphasisMark;
     256        OwnPtr<SimpleFontData> brokenIdeograph;
     257
     258    private:
     259        DerivedFontData(bool custom)
     260            : forCustomFont(custom)
     261        {
     262        }
     263    };
     264
     265    mutable OwnPtr<DerivedFontData> m_derivedFontData;
    232266
    233267#if PLATFORM(CG) || PLATFORM(CAIRO) || PLATFORM(WX)
  • trunk/WebCore/platform/graphics/WidthIterator.cpp

    r68148 r74169  
    4141static const uint8_t hiraganaKatakanaVoicingMarksCombiningClass = 8;
    4242
    43 WidthIterator::WidthIterator(const Font* font, const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, bool accountForGlyphBounds)
     43WidthIterator::WidthIterator(const Font* font, const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, bool accountForGlyphBounds, bool forTextEmphasis)
    4444    : m_font(font)
    4545    , m_run(run)
     
    5454    , m_firstGlyphOverflow(0)
    5555    , m_lastGlyphOverflow(0)
     56    , m_forTextEmphasis(forTextEmphasis)
    5657{
    5758    // If the padding is non-zero, count the number of spaces in the run
     
    200201        }
    201202
     203        if (m_forTextEmphasis && !Font::canReceiveTextEmphasis(c))
     204            glyph = 0;
     205
    202206        // Advance past the character we just dealt with.
    203207        cp += clusterLength;
  • trunk/WebCore/platform/graphics/WidthIterator.h

    r58585 r74169  
    3434
    3535struct WidthIterator {
    36     WidthIterator(const Font*, const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0, bool accountForGlyphBounds = false);
     36    WidthIterator(const Font*, const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0, bool accountForGlyphBounds = false, bool forTextEmphasis = false);
    3737
    3838    void advance(int to, GlyphBuffer* = 0);
     
    6464    float m_firstGlyphOverflow;
    6565    float m_lastGlyphOverflow;
     66    bool m_forTextEmphasis;
    6667};
    6768
  • trunk/WebCore/platform/graphics/chromium/FontChromiumWin.cpp

    r66788 r74169  
    3636#include "FontFallbackList.h"
    3737#include "GlyphBuffer.h"
     38#include "NotImplemented.h"
    3839#include "PlatformContextSkia.h"
    3940#include "SimpleFontData.h"
     
    506507}
    507508
     509void Font::drawEmphasisMarksForComplexText(GraphicsContext* /* context */, const TextRun& /* run */, const AtomicString& /* mark */, const FloatPoint& /* point */, int /* from */, int /* to */) const
     510{
     511    notImplemented();
     512}
     513
    508514float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* /* fallbackFonts */, GlyphOverflow* /* glyphOverflow */) const
    509515{
  • trunk/WebCore/platform/graphics/chromium/FontLinux.cpp

    r73284 r74169  
    382382        if (!hb_utf16_script_run_prev(&m_numCodePoints, &m_item.item, m_run.characters(), m_run.length(), &m_indexOfNextScriptRun))
    383383            return false;
    384         m_currentFontData = m_font->glyphDataForCharacter(m_item.string[m_item.item.pos], false, false).fontData;
     384        m_currentFontData = m_font->glyphDataForCharacter(m_item.string[m_item.item.pos], false).fontData;
    385385    } else {
    386386        if (!hb_utf16_script_run_next(&m_numCodePoints, &m_item.item, m_run.characters(), m_run.length(), &m_indexOfNextScriptRun))
     
    394394        // So we allow that to run first, then do a second pass over the range it
    395395        // found and take the largest subregion that stays within a single font.
    396         m_currentFontData = m_font->glyphDataForCharacter(m_item.string[m_item.item.pos], false, false).fontData;
     396        m_currentFontData = m_font->glyphDataForCharacter(m_item.string[m_item.item.pos], false).fontData;
    397397        unsigned endOfRun;
    398398        for (endOfRun = 1; endOfRun < m_item.item.length; ++endOfRun) {
    399             const SimpleFontData* nextFontData = m_font->glyphDataForCharacter(m_item.string[m_item.item.pos + endOfRun], false, false).fontData;
     399            const SimpleFontData* nextFontData = m_font->glyphDataForCharacter(m_item.string[m_item.item.pos + endOfRun], false).fontData;
    400400            if (nextFontData != m_currentFontData)
    401401                break;
     
    423423void TextRunWalker::setupFontForScriptRun()
    424424{
    425     const FontData* fontData = m_font->glyphDataForCharacter(m_item.string[m_item.item.pos], false, false).fontData;
     425    const FontData* fontData = m_font->glyphDataForCharacter(m_item.string[m_item.item.pos], false).fontData;
    426426    const FontPlatformData& platformData = fontData->fontDataForCharacter(' ')->platformData();
    427427    m_item.face = platformData.harfbuzzFace();
     
    691691}
    692692
     693void Font::drawEmphasisMarksForComplexText(GraphicsContext* /* context */, const TextRun& /* run */, const AtomicString& /* mark */, const FloatPoint& /* point */, int /* from */, int /* to */) const
     694{
     695    notImplemented();
     696}
     697
    693698float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* /* fallbackFonts */, GlyphOverflow* /* glyphOverflow */) const
    694699{
  • trunk/WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp

    r72567 r74169  
    113113}
    114114
     115SimpleFontData* SimpleFontData::scaledFontData(const FontDescription& fontDescription, float scaleFactor) const
     116{
     117    LOGFONT winFont;
     118    GetObject(m_platformData.hfont(), sizeof(LOGFONT), &winFont);
     119    float scaledSize = scaleFactor * fontDescription.computedSize();
     120    winFont.lfHeight = -lroundf(scaledSize);
     121    HFONT hfont = CreateFontIndirect(&winFont);
     122    return new SimpleFontData(FontPlatformData(hfont, scaledSize), isCustomFont(), false);
     123}
     124
    115125SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
    116126{
    117     if (!m_smallCapsFontData) {
    118         LOGFONT winFont;
    119         GetObject(m_platformData.hfont(), sizeof(LOGFONT), &winFont);
    120         float smallCapsSize = 0.70f * fontDescription.computedSize();
    121         // Unlike WebKit trunk, we don't multiply the size by 32.  That seems
    122         // to be some kind of artifact of their CG backend, or something.
    123         winFont.lfHeight = -lroundf(smallCapsSize);
    124         HFONT hfont = CreateFontIndirect(&winFont);
    125         m_smallCapsFontData =
    126             new SimpleFontData(FontPlatformData(hfont, smallCapsSize), isCustomFont(), false);
    127     }
    128     return m_smallCapsFontData;
     127    if (!m_derivedFontData)
     128        m_derivedFontData = DerivedFontData::create(isCustomFont());
     129    if (!m_derivedFontData->smallCaps)
     130        m_derivedFontData->smallCaps = scaledFontData(fontDescription, .7);
     131
     132    return m_derivedFontData->smallCaps.get();
     133}
     134
     135SimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
     136{
     137    if (!m_derivedFontData)
     138        m_derivedFontData = DerivedFontData::create(isCustomFont());
     139    if (!m_derivedFontData->emphasisMark)
     140        m_derivedFontData->emphasisMark = scaledFontData(fontDescription, .5);
     141
     142    return m_derivedFontData->emphasisMark.get();
    129143}
    130144
  • trunk/WebCore/platform/graphics/chromium/SimpleFontDataLinux.cpp

    r72567 r74169  
    4949// Smallcaps versions of fonts are 70% the size of the normal font.
    5050static const float smallCapsFraction = 0.7f;
     51static const float emphasisMarkFraction = .5;
    5152// This is the largest VDMX table which we'll try to load and parse.
    5253static const size_t maxVDMXTableSize = 1024 * 1024;  // 1 MB
     
    142143}
    143144
     145SimpleFontData* SimpleFontData::scaledFontData(const FontDescription& fontDescription, float scaleFactor) const
     146{
     147    const float scaledSize = lroundf(fontDescription.computedSize() * scaleFactor);
     148    return new SimpleFontData(FontPlatformData(m_platformData, scaledSize), isCustomFont(), false);
     149}
     150
    144151SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
    145152{
    146     if (!m_smallCapsFontData) {
    147         const float smallCapsSize = lroundf(fontDescription.computedSize() * smallCapsFraction);
    148         m_smallCapsFontData = new SimpleFontData(FontPlatformData(m_platformData, smallCapsSize), isCustomFont(), false);
    149     }
    150 
    151     return m_smallCapsFontData;
     153    if (!m_derivedFontData)
     154        m_derivedFontData = DerivedFontData::create(isCustomFont());
     155    if (!m_derivedFontData->smallCaps)
     156        m_derivedFontData->smallCaps = scaledFontData(fontDescription, smallCapsFraction);
     157
     158    return m_derivedFontData->smallCaps.get();
     159}
     160
     161SimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
     162{
     163    if (!m_derivedFontData)
     164        m_derivedFontData = DerivedFontData::create(isCustomFont());
     165    if (!m_derivedFontData->emphasisMark)
     166        m_derivedFontData->emphasisMark = scaledFontData(fontDescription, emphasisMarkFraction);
     167
     168    return m_derivedFontData->emphasisMark.get();
    152169}
    153170
  • trunk/WebCore/platform/graphics/efl/FontEfl.cpp

    r61253 r74169  
    4141}
    4242
     43void Font::drawEmphasisMarksForComplexText(GraphicsContext* /* context */, const TextRun& /* run */, const AtomicString& /* mark */, const FloatPoint& /* point */, int /* from */, int /* to */) const
     44{
     45    notImplemented();
     46}
     47
    4348bool Font::canReturnFallbackFontsForComplexText()
    4449{
  • trunk/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp

    r71975 r74169  
    8080}
    8181
     82SimpleFontData* SimpleFontData::scaledFontData(const FontDescription& fontDescription, float scaleFactor) const
     83{
     84    return new SimpleFontData(FontPlatformData(cairo_scaled_font_get_font_face(m_platformData.scaledFont()),
     85        scaleFactor * fontDescription.computedSize(), m_platformData.syntheticBold(), m_platformData.syntheticOblique()),
     86        isCustomFont(), false);
     87}
     88
    8289SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
    8390{
     91    if (!m_derivedFontData)
     92        m_derivedFontData = DerivedFontData::create(isCustomFont());
    8493    // FIXME: I think we want to ask FontConfig for the right font again.
    85     if (!m_smallCapsFontData)
    86         m_smallCapsFontData = new SimpleFontData(
    87             FontPlatformData(cairo_scaled_font_get_font_face(m_platformData.scaledFont()),
    88             0.70f * fontDescription.computedSize(), m_platformData.syntheticBold(), m_platformData.syntheticOblique()),
    89             isCustomFont(), false);
     94    if (!m_derivedFontData->smallCaps)
     95        m_derivedFontData->smallCaps = scaledFontData(fontDescription, .7);
    9096
    91     return m_smallCapsFontData;
     97    return m_derivedFontData->smallCaps.get();
     98}
     99
     100SimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
     101{
     102    if (!m_derivedFontData)
     103        m_derivedFontData = DerivedFontData::create(isCustomFont());
     104    if (!m_derivedFontData->emphasisMark)
     105        m_derivedFontData->emphasisMark = scaledFontData(fontDescription, .5);
     106
     107    return m_derivedFontData->emphasisMark.get();
    92108}
    93109
  • trunk/WebCore/platform/graphics/gtk/FontGtk.cpp

    r73284 r74169  
    3737#include "ContextShadow.h"
    3838#include "GraphicsContext.h"
     39#include "NotImplemented.h"
    3940#include "SimpleFontData.h"
    4041#include <cairo.h>
     
    320321}
    321322
     323void Font::drawEmphasisMarksForComplexText(GraphicsContext* /* context */, const TextRun& /* run */, const AtomicString& /* mark */, const FloatPoint& /* point */, int /* from */, int /* to */) const
     324{
     325    notImplemented();
     326}
     327
    322328// We should create the layout with our actual context but we can't access it from here.
    323329static PangoLayout* getDefaultPangoLayout(const TextRun& run)
  • trunk/WebCore/platform/graphics/haiku/FontHaiku.cpp

    r61253 r74169  
    9494}
    9595
     96void Font::drawEmphasisMarksForComplexText(GraphicsContext* /* context */, const TextRun& /* run */, const AtomicString& /* mark */, const FloatPoint& /* point */, int /* from */, int /* to */) const
     97{
     98    notImplemented();
     99}
    96100
    97101float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
  • trunk/WebCore/platform/graphics/haiku/SimpleFontDataHaiku.cpp

    r71975 r74169  
    6767}
    6868
     69SimpleFontData* SimpleFontData::scaledFontData(const FontDescription& fontDescription, float scaleFactor) const
     70{
     71    FontDescription desc = FontDescription(fontDescription);
     72    desc.setSpecifiedSize(scaleFactor * fontDescription.computedSize());
     73    FontPlatformData fontPlatformData(desc, desc.family().family());
     74    return new SimpleFontData(fontPlatformData, isCustomFont(), false);
     75}
     76
    6977SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
    7078{
    71     if (!m_smallCapsFontData) {
    72         FontDescription desc = FontDescription(fontDescription);
    73         desc.setSpecifiedSize(0.70f * fontDescription.computedSize());
    74         FontPlatformData fontPlatformData(desc, desc.family().family());
    75         m_smallCapsFontData = new SimpleFontData(fontPlatformData, isCustomFont(), false);
    76     }
    77     return m_smallCapsFontData;
     79    if (!m_derivedFontData)
     80        m_derivedFontData = DerivedFontData::create(isCustomFont());
     81    if (!m_derivedFontData->smallCaps)
     82        m_derivedFontData->smallCaps = scaledFontData(fontDescription, .7);
     83
     84    return m_derivedFontData->smallCaps.get();
     85}
     86
     87SimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
     88{
     89    if (!m_derivedFontData)
     90        m_derivedFontData = DerivedFontData::create(isCustomFont());
     91    if (!m_derivedFontData->emphasisMark)
     92        m_derivedFontData->emphasisMark = scaledFontData(fontDescription, .5);
     93
     94    return m_derivedFontData->emphasisMark.get();
    7895}
    7996
  • trunk/WebCore/platform/graphics/mac/ComplexTextController.cpp

    r73032 r74169  
    5757}
    5858
    59 ComplexTextController::ComplexTextController(const Font* font, const TextRun& run, bool mayUseNaturalWritingDirection, HashSet<const SimpleFontData*>* fallbackFonts)
     59ComplexTextController::ComplexTextController(const Font* font, const TextRun& run, bool mayUseNaturalWritingDirection, HashSet<const SimpleFontData*>* fallbackFonts, bool forTextEmphasis)
    6060    : m_font(*font)
    6161    , m_run(run)
    6262    , m_mayUseNaturalWritingDirection(mayUseNaturalWritingDirection)
     63    , m_forTextEmphasis(forTextEmphasis)
    6364    , m_currentCharacter(0)
    6465    , m_end(run.length())
     
    241242            }
    242243        } else
    243             nextGlyphData = m_font.glyphDataForCharacter(*curr, false, forceSmallCaps);
     244            nextGlyphData = m_font.glyphDataForCharacter(*curr, false, forceSmallCaps ? SmallCapsVariant : AutoVariant);
    244245
    245246        if (!isSurrogate && m_font.isSmallCaps()) {
     
    537538                widthSinceLastRounding += advance.width;
    538539
     540            // FIXME: Combining marks should receive a text emphasis mark if they are combine with a space.
     541            if (m_forTextEmphasis && (!Font::canReceiveTextEmphasis(ch) || (U_GET_GC_MASK(ch) & U_GC_M_MASK)))
     542                glyph = 0;
     543
    539544            advance.height *= -1;
    540545            m_adjustedAdvances.append(advance);
  • trunk/WebCore/platform/graphics/mac/ComplexTextController.h

    r71800 r74169  
    4848class ComplexTextController {
    4949public:
    50     ComplexTextController(const Font*, const TextRun&, bool mayUseNaturalWritingDirection = false, HashSet<const SimpleFontData*>* fallbackFonts = 0);
     50    ComplexTextController(const Font*, const TextRun&, bool mayUseNaturalWritingDirection = false, HashSet<const SimpleFontData*>* fallbackFonts = 0, bool forTextEmphasis = false);
    5151
    5252    // Advance and emit glyphs up to the specified character.
     
    157157    const TextRun& m_run;
    158158    bool m_mayUseNaturalWritingDirection;
     159    bool m_forTextEmphasis;
    159160
    160161    Vector<UChar, 256> m_smallCapsBuffer;
  • trunk/WebCore/platform/graphics/mac/FontComplexTextMac.cpp

    r61253 r74169  
    5656}
    5757
    58 void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point,
    59                            int from, int to) const
     58float Font::getGlyphsAndAdvancesForComplexText(const TextRun& run, int from, int to, GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot forTextEmphasis) const
     59{
     60    float initialAdvance;
     61
     62    ComplexTextController controller(this, run, false, 0, forTextEmphasis);
     63    controller.advance(from);
     64    float beforeWidth = controller.runWidthSoFar();
     65    controller.advance(to, &glyphBuffer);
     66
     67    if (glyphBuffer.isEmpty())
     68        return 0;
     69
     70    float afterWidth = controller.runWidthSoFar();
     71
     72    if (run.rtl()) {
     73        initialAdvance = controller.totalWidth() + controller.finalRoundingWidth() - afterWidth;
     74        for (int i = 0, end = glyphBuffer.size() - 1; i < glyphBuffer.size() / 2; ++i, --end)
     75            glyphBuffer.swap(i, end);
     76    } else
     77        initialAdvance = beforeWidth;
     78
     79    return initialAdvance;
     80}
     81
     82void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const
    6083{
    6184    // This glyph buffer holds our glyphs + advances + font data for each glyph.
    6285    GlyphBuffer glyphBuffer;
    6386
    64     float startX = point.x();
    65     ComplexTextController controller(this, run);
    66     controller.advance(from);
    67     float beforeWidth = controller.runWidthSoFar();
    68     controller.advance(to, &glyphBuffer);
    69    
     87    float startX = point.x() + getGlyphsAndAdvancesForComplexText(run, from, to, glyphBuffer);
     88
    7089    // We couldn't generate any glyphs for the run.  Give up.
    7190    if (glyphBuffer.isEmpty())
    7291        return;
    73    
    74     float afterWidth = controller.runWidthSoFar();
    75 
    76     if (run.rtl()) {
    77         startX += controller.totalWidth() + controller.finalRoundingWidth() - afterWidth;
    78         for (int i = 0, end = glyphBuffer.size() - 1; i < glyphBuffer.size() / 2; ++i, --end)
    79             glyphBuffer.swap(i, end);
    80     } else
    81         startX += beforeWidth;
    8292
    8393    // Draw the glyph buffer now at the starting point returned in startX.
    8494    FloatPoint startPoint(startX, point.y());
    85     drawGlyphBuffer(context, glyphBuffer, run, startPoint);
     95    drawGlyphBuffer(context, glyphBuffer, startPoint);
     96}
     97
     98void Font::drawEmphasisMarksForComplexText(GraphicsContext* context, const TextRun& run, const AtomicString& mark, const FloatPoint& point, int from, int to) const
     99{
     100    GlyphBuffer glyphBuffer;
     101    float initialAdvance = getGlyphsAndAdvancesForComplexText(run, from, to, glyphBuffer, ForTextEmphasis);
     102
     103    if (glyphBuffer.isEmpty())
     104        return;
     105
     106    drawEmphasisMarks(context, glyphBuffer, mark, FloatPoint(point.x() + initialAdvance, point.y()));
    86107}
    87108
  • trunk/WebCore/platform/graphics/mac/SimpleFontDataMac.mm

    r72141 r74169  
    358358void SimpleFontData::platformDestroy()
    359359{
    360     if (m_smallCapsFontData && !isCustomFont()) {
    361         fontCache()->releaseFontData(m_smallCapsFontData);
    362         m_smallCapsFontData = 0;
     360    if (!isCustomFont() && m_derivedFontData) {
     361        // These come from the cache.
     362        if (m_derivedFontData->smallCaps)
     363            fontCache()->releaseFontData(m_derivedFontData->smallCaps.leakPtr());
     364
     365        if (m_derivedFontData->emphasisMark)
     366            fontCache()->releaseFontData(m_derivedFontData->emphasisMark.leakPtr());
    363367    }
    364368
     
    374378}
    375379
     380SimpleFontData* SimpleFontData::scaledFontData(const FontDescription& fontDescription, float scaleFactor) const
     381{
     382    if (isCustomFont()) {
     383        FontPlatformData scaledFontData(m_platformData);
     384        scaledFontData.m_size = scaledFontData.m_size * scaleFactor;
     385        return new SimpleFontData(scaledFontData, true, false);
     386    }
     387
     388    BEGIN_BLOCK_OBJC_EXCEPTIONS;
     389    float size = m_platformData.size() * scaleFactor;
     390    FontPlatformData scaledFontData([[NSFontManager sharedFontManager] convertFont:m_platformData.font() toSize:size], size);
     391
     392    // AppKit resets the type information (screen/printer) when you convert a font to a different size.
     393    // We have to fix up the font that we're handed back.
     394    scaledFontData.setFont(fontDescription.usePrinterFont() ? [scaledFontData.font() printerFont] : [scaledFontData.font() screenFont]);
     395
     396    if (scaledFontData.font()) {
     397        NSFontManager *fontManager = [NSFontManager sharedFontManager];
     398        NSFontTraitMask fontTraits = [fontManager traitsOfFont:m_platformData.font()];
     399
     400        if (m_platformData.m_syntheticBold)
     401            fontTraits |= NSBoldFontMask;
     402        if (m_platformData.m_syntheticOblique)
     403            fontTraits |= NSItalicFontMask;
     404
     405        NSFontTraitMask scaledFontTraits = [fontManager traitsOfFont:scaledFontData.font()];
     406        scaledFontData.m_syntheticBold = (fontTraits & NSBoldFontMask) && !(scaledFontTraits & NSBoldFontMask);
     407        scaledFontData.m_syntheticOblique = (fontTraits & NSItalicFontMask) && !(scaledFontTraits & NSItalicFontMask);
     408
     409        return fontCache()->getCachedFontData(&scaledFontData);
     410    }
     411    END_BLOCK_OBJC_EXCEPTIONS;
     412
     413    return 0;
     414}
     415
    376416SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
    377417{
    378     if (!m_smallCapsFontData) {
    379         if (isCustomFont()) {
    380             FontPlatformData smallCapsFontData(m_platformData);
    381             smallCapsFontData.m_size = smallCapsFontData.m_size * smallCapsFontSizeMultiplier;
    382             m_smallCapsFontData = new SimpleFontData(smallCapsFontData, true, false);
    383         } else {
    384             BEGIN_BLOCK_OBJC_EXCEPTIONS;
    385             float size = m_platformData.size() * smallCapsFontSizeMultiplier;
    386             FontPlatformData smallCapsFont([[NSFontManager sharedFontManager] convertFont:m_platformData.font() toSize:size], size);
    387            
    388             // AppKit resets the type information (screen/printer) when you convert a font to a different size.
    389             // We have to fix up the font that we're handed back.
    390             smallCapsFont.setFont(fontDescription.usePrinterFont() ? [smallCapsFont.font() printerFont] : [smallCapsFont.font() screenFont]);
    391 
    392             if (smallCapsFont.font()) {
    393                 NSFontManager *fontManager = [NSFontManager sharedFontManager];
    394                 NSFontTraitMask fontTraits = [fontManager traitsOfFont:m_platformData.font()];
    395 
    396                 if (m_platformData.m_syntheticBold)
    397                     fontTraits |= NSBoldFontMask;
    398                 if (m_platformData.m_syntheticOblique)
    399                     fontTraits |= NSItalicFontMask;
    400 
    401                 NSFontTraitMask smallCapsFontTraits = [fontManager traitsOfFont:smallCapsFont.font()];
    402                 smallCapsFont.m_syntheticBold = (fontTraits & NSBoldFontMask) && !(smallCapsFontTraits & NSBoldFontMask);
    403                 smallCapsFont.m_syntheticOblique = (fontTraits & NSItalicFontMask) && !(smallCapsFontTraits & NSItalicFontMask);
    404 
    405                 m_smallCapsFontData = fontCache()->getCachedFontData(&smallCapsFont);
    406             }
    407             END_BLOCK_OBJC_EXCEPTIONS;
    408         }
    409     }
    410     return m_smallCapsFontData;
     418    if (!m_derivedFontData)
     419        m_derivedFontData = DerivedFontData::create(isCustomFont());
     420    if (!m_derivedFontData->smallCaps)
     421        m_derivedFontData->smallCaps = scaledFontData(fontDescription, smallCapsFontSizeMultiplier);
     422
     423    return m_derivedFontData->smallCaps.get();
     424}
     425
     426SimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
     427{
     428    if (!m_derivedFontData)
     429        m_derivedFontData = DerivedFontData::create(isCustomFont());
     430    if (!m_derivedFontData->emphasisMark)
     431        m_derivedFontData->emphasisMark = scaledFontData(fontDescription, .5);
     432
     433    return m_derivedFontData->emphasisMark.get();
    411434}
    412435
  • trunk/WebCore/platform/graphics/pango/SimpleFontDataPango.cpp

    r71816 r74169  
    7777void SimpleFontData::platformDestroy()
    7878{
    79     delete m_smallCapsFontData;
    80     m_smallCapsFontData = 0;
     79}
     80
     81SimpleFontData* SimpleFontData::scaledFontData(const FontDescription& fontDescription, float scaleFactor) const
     82{
     83    FontDescription desc = FontDescription(fontDescription);
     84    desc.setSpecifiedSize(scaleFactor * fontDescription.computedSize());
     85    FontPlatformData platformData(desc, desc.family().family());
     86    return new SimpleFontData(platformData);
    8187}
    8288
    8389SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
    8490{
    85     if (!m_smallCapsFontData) {
    86         FontDescription desc = FontDescription(fontDescription);
    87         desc.setSpecifiedSize(0.70f * fontDescription.computedSize());
    88         FontPlatformData platformData(desc, desc.family().family());
    89         m_smallCapsFontData = new SimpleFontData(platformData);
    90     }
    91     return m_smallCapsFontData;
     91    if (!m_derivedFontData)
     92        m_derivedFontData = DerivedFontData::create(isCustomFont());
     93    if (!m_derivedFontData->smallCaps)
     94        m_derivedFontData->smallCaps = scaledFontData(fontDescription, .7);
     95
     96    return m_derivedFontData->smallCaps.get();
     97}
     98
     99SimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
     100{
     101    if (!m_derivedFontData)
     102        m_derivedFontData = DerivedFontData::create(isCustomFont());
     103    if (!m_derivedFontData->emphasisMark)
     104        m_derivedFontData->emphasisMark = scaledFontData(fontDescription, .5);
     105
     106    return m_derivedFontData->emphasisMark.get();
    92107}
    93108
  • trunk/WebCore/platform/graphics/qt/FontQt.cpp

    r73352 r74169  
    3030#include "Gradient.h"
    3131#include "GraphicsContext.h"
     32#include "NotImplemented.h"
    3233#include "Pattern.h"
    3334
     
    261262}
    262263
     264int Font::emphasisMarkAscent(const AtomicString&) const
     265{
     266    notImplemented();
     267    return 0;
     268}
     269
     270int Font::emphasisMarkDescent(const AtomicString&) const
     271{
     272    notImplemented();
     273    return 0;
     274}
     275
     276int Font::emphasisMarkHeight(const AtomicString&) const
     277{
     278    notImplemented();
     279    return 0;
     280}
     281
     282void Font::drawEmphasisMarksForSimpleText(GraphicsContext* /* context */, const TextRun& /* run */, const AtomicString& /* mark */, const FloatPoint& /* point */, int /* from */, int /* to */) const
     283{
     284    notImplemented();
     285}
     286
     287void Font::drawEmphasisMarksForComplexText(GraphicsContext* /* context */, const TextRun& /* run */, const AtomicString& /* mark */, const FloatPoint& /* point */, int /* from */, int /* to */) const
     288{
     289    notImplemented();
     290}
     291
    263292float Font::floatWidthForSimpleText(const TextRun& run, GlyphBuffer* glyphBuffer, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
    264293{
  • trunk/WebCore/platform/graphics/win/FontWin.cpp

    r61253 r74169  
    3131#include "GraphicsContext.h"
    3232#include "IntRect.h"
     33#include "Logging.h"
    3334#include "SimpleFontData.h"
    3435#include "UniscribeController.h"
     
    6364}
    6465
     66float Font::getGlyphsAndAdvancesForComplexText(const TextRun& run, int from, int to, GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot forTextEmphasis) const
     67{
     68    if (forTextEmphasis) {
     69        // FIXME: Add forTextEmphasis paremeter to UniscribeController and use it.
     70        LOG_ERROR("Not implemented for text emphasis.");
     71        return 0;
     72    }
     73
     74    UniscribeController controller(this, run);
     75    controller.advance(from);
     76    float beforeWidth = controller.runWidthSoFar();
     77    controller.advance(to, &glyphBuffer);
     78
     79    if (glyphBuffer.isEmpty())
     80        return 0;
     81
     82    float afterWidth = controller.runWidthSoFar();
     83
     84    if (run.rtl()) {
     85        controller.advance(run.length());
     86        return controller.runWidthSoFar() - afterWidth;
     87    }
     88    return beforeWidth;
     89}
     90
    6591void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point,
    6692                           int from, int to) const
     
    6995    GlyphBuffer glyphBuffer;
    7096
    71     float startX = point.x();
    72     UniscribeController controller(this, run);
    73     controller.advance(from);
    74     float beforeWidth = controller.runWidthSoFar();
    75     controller.advance(to, &glyphBuffer);
    76    
     97    float startX = point.x() + getGlyphsAndAdvancesForComplexText(run, from, to, glyphBuffer);
     98
    7799    // We couldn't generate any glyphs for the run.  Give up.
    78100    if (glyphBuffer.isEmpty())
    79101        return;
    80    
    81     float afterWidth = controller.runWidthSoFar();
    82 
    83     if (run.rtl()) {
    84         controller.advance(run.length());
    85         startX += controller.runWidthSoFar() - afterWidth;
    86     } else
    87         startX += beforeWidth;
    88102
    89103    // Draw the glyph buffer now at the starting point returned in startX.
    90104    FloatPoint startPoint(startX, point.y());
    91     drawGlyphBuffer(context, glyphBuffer, run, startPoint);
     105    drawGlyphBuffer(context, glyphBuffer, startPoint);
     106}
     107
     108void Font::drawEmphasisMarksForComplexText(GraphicsContext* context, const TextRun& run, const AtomicString& mark, const FloatPoint& point, int from, int to) const
     109{
     110    GlyphBuffer glyphBuffer;
     111    float initialAdvance = getGlyphsAndAdvancesForComplexText(run, from, to, glyphBuffer, ForTextEmphasis);
     112
     113    if (glyphBuffer.isEmpty())
     114        return;
     115
     116    drawEmphasisMarks(context, glyphBuffer, mark, FloatPoint(point.x() + initialAdvance, point.y()));
    92117}
    93118
  • trunk/WebCore/platform/graphics/win/SimpleFontDataWin.cpp

    r72270 r74169  
    111111}
    112112
     113SimpleFontData* SimpleFontData::scaledFontData(const FontDescription& fontDescription, float scaleFactor) const
     114{
     115        float scaledSize = scaleFactor * m_platformData.size();
     116        if (isCustomFont()) {
     117            FontPlatformData scaledFont(m_platformData);
     118            scaledFont.setSize(scaledSize);
     119            return new SimpleFontData(scaledFont, true, false);
     120        }
     121
     122        LOGFONT winfont;
     123        GetObject(m_platformData.hfont(), sizeof(LOGFONT), &winfont);
     124        winfont.lfHeight = -lroundf(scaledSize * (m_platformData.useGDI() ? 1 : 32));
     125        HFONT hfont = CreateFontIndirect(&winfont);
     126        return new SimpleFontData(FontPlatformData(hfont, scaledSize, m_platformData.syntheticBold(), m_platformData.syntheticOblique(), m_platformData.useGDI()), isCustomFont(), false);
     127}
     128
    113129SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
    114130{
    115     if (!m_smallCapsFontData) {
    116         float smallCapsHeight = cSmallCapsFontSizeMultiplier * m_platformData.size();
    117         if (isCustomFont()) {
    118             FontPlatformData smallCapsFontData(m_platformData);
    119             smallCapsFontData.setSize(smallCapsHeight);
    120             m_smallCapsFontData = new SimpleFontData(smallCapsFontData, true, false);
    121         } else {
    122             LOGFONT winfont;
    123             GetObject(m_platformData.hfont(), sizeof(LOGFONT), &winfont);
    124             winfont.lfHeight = -lroundf(smallCapsHeight * (m_platformData.useGDI() ? 1 : 32));
    125             HFONT hfont = CreateFontIndirect(&winfont);
    126             m_smallCapsFontData = new SimpleFontData(FontPlatformData(hfont, smallCapsHeight, m_platformData.syntheticBold(), m_platformData.syntheticOblique(), m_platformData.useGDI()),
    127                                                      isCustomFont(), false);
    128         }
    129     }
    130     return m_smallCapsFontData;
     131    if (!m_derivedFontData)
     132        m_derivedFontData = DerivedFontData::create(isCustomFont());
     133    if (!m_derivedFontData->smallCaps)
     134        m_derivedFontData->smallCaps = scaledFontData(fontDescription, cSmallCapsFontSizeMultiplier);
     135
     136    return m_derivedFontData->smallCaps.get();
     137}
     138
     139SimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
     140{
     141    if (!m_derivedFontData)
     142        m_derivedFontData = DerivedFontData::create(isCustomFont());
     143    if (!m_derivedFontData->emphasisMark)
     144        m_derivedFontData->emphasisMark = scaledFontData(fontDescription, .5);
     145
     146    return m_derivedFontData->emphasisMark.get();
    131147}
    132148
  • trunk/WebCore/platform/graphics/win/UniscribeController.cpp

    r71870 r74169  
    146146
    147147        bool forceSmallCaps = isSmallCaps && (U_GET_GC_MASK(c) & U_GC_M_MASK);
    148         nextFontData = m_font.glyphDataForCharacter(*curr, false, forceSmallCaps).fontData;
     148        nextFontData = m_font.glyphDataForCharacter(*curr, false, forceSmallCaps ? SmallCapsVariant : AutoVariant).fontData;
    149149        if (m_font.isSmallCaps()) {
    150150            nextIsSmallCaps = forceSmallCaps || (newC = u_toupper(c)) != c;
  • trunk/WebCore/platform/graphics/wince/FontWinCE.cpp

    r67788 r74169  
    236236}
    237237
     238void Font::drawEmphasisMarksForComplexText(GraphicsContext* /* context */, const TextRun& /* run */, const AtomicString& /* mark */, const FloatPoint& /* point */, int /* from */, int /* to */) const
     239{
     240    notImplemented();
     241}
     242
    238243float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
    239244{
  • trunk/WebCore/platform/graphics/wince/SimpleFontDataWinCE.cpp

    r67788 r74169  
    6161void SimpleFontData::platformDestroy()
    6262{
    63     delete m_smallCapsFontData;
    64     m_smallCapsFontData = 0;
     63}
     64
     65SimpleFontData* SimpleFontData::scaledFontData(const FontDescription& fontDescription, float scaleFactor) const
     66{
     67    FontDescription fontDesc(fontDescription);
     68    fontDesc.setComputedSize(lroundf(scaleFactor * fontDesc.computedSize()));
     69    fontDesc.setSpecifiedSize(lroundf(scaleFactor * fontDesc.specifiedSize()));
     70    fontDesc.setKeywordSize(lroundf(scaleFactor * fontDesc.keywordSize()));
     71    FontPlatformData* result = fontCache()->getCachedFontPlatformData(fontDesc, m_platformData.family());
     72    return result ? new SimpleFontData(*result) : 0;
    6573}
    6674
    6775SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
    6876{
    69     if (!m_smallCapsFontData) {
    70         FontDescription fontDesc(fontDescription);
    71         fontDesc.setComputedSize(lroundf(0.70f * fontDesc.computedSize()));
    72         fontDesc.setSpecifiedSize(lroundf(0.70f * fontDesc.specifiedSize()));
    73         fontDesc.setKeywordSize(lroundf(0.70f * fontDesc.keywordSize()));
    74         FontPlatformData* result = fontCache()->getCachedFontPlatformData(fontDesc, m_platformData.family());
    75         if (result)
    76             m_smallCapsFontData = new SimpleFontData(*result);
    77     }
    78     return m_smallCapsFontData;
     77    if (!m_derivedFontData)
     78        m_derivedFontData = DerivedFontData::create(isCustomFont());
     79    if (!m_derivedFontData->smallCaps)
     80        m_derivedFontData->smallCaps = scaledFontData(fontDescription, .7);
     81
     82    return m_derivedFontData->smallCaps.get();
     83}
     84
     85SimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
     86{
     87    if (!m_derivedFontData)
     88        m_derivedFontData = DerivedFontData::create(isCustomFont());
     89    if (!m_derivedFontData->emphasisMark)
     90        m_derivedFontData->emphasisMark = scaledFontData(fontDescription, .5);
     91
     92    return m_derivedFontData->emphasisMark.get();
    7993}
    8094
  • trunk/WebCore/platform/graphics/wx/FontWx.cpp

    r61253 r74169  
    9999}
    100100
     101float Font::getGlyphsAndAdvancesForComplexText(const TextRun& /* run */, int /* from */, int /* to */, GlyphBuffer& /* glyphBuffer */, ForTextEmphasisOrNot /* forTextEmphasis */) const
     102{
     103    // FIXME: Implement this by moving most of the drawComplexText() implementation in here. Set up the
     104    // ComplexTextController according to forTextEmphasis.
     105    notImplemented();
     106    return 0;
     107}
     108
    101109void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const
    102110{
     
    131139    // Draw the glyph buffer now at the starting point returned in startX.
    132140    FloatPoint startPoint(startX, point.y());
    133     drawGlyphBuffer(context, glyphBuffer, run, startPoint);
     141    drawGlyphBuffer(context, glyphBuffer, startPoint);
    134142#else
    135143    notImplemented();
     
    137145}
    138146
     147void Font::drawEmphasisMarksForComplexText(GraphicsContext* context, const TextRun& run, const AtomicString& mark, const FloatPoint& point, int from, int to) const
     148{
     149    GlyphBuffer glyphBuffer;
     150    float initialAdvance = getGlyphsAndAdvancesForComplexText(run, from, to, glyphBuffer, ForTextEmphasis);
     151
     152    if (glyphBuffer.isEmpty())
     153        return;
     154
     155    drawEmphasisMarks(context, glyphBuffer, mark, FloatPoint(point.x() + initialAdvance, point.y()));
     156}
    139157
    140158float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow*) const
  • trunk/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp

    r71975 r74169  
    9191}
    9292
     93SimpleFontData* SimpleFontData::scaledFontData(const FontDescription& fontDescription, float scaleFactor) const
     94{
     95    FontDescription desc = FontDescription(fontDescription);
     96    desc.setSpecifiedSize(scaleFactor * fontDescription.computedSize());
     97    FontPlatformData platformData(desc, desc.family().family());
     98    return new SimpleFontData(platformData, isCustomFont(), false);
     99}
     100
    93101SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
    94102{
    95     if (!m_smallCapsFontData){
    96         FontDescription desc = FontDescription(fontDescription);
    97         desc.setSpecifiedSize(0.70f * fontDescription.computedSize());
    98         FontPlatformData platformData(desc, desc.family().family());
    99         m_smallCapsFontData = new SimpleFontData(platformData, isCustomFont(), false);
    100     }
    101     return m_smallCapsFontData;
     103    if (!m_derivedFontData)
     104        m_derivedFontData = DerivedFontData::create(isCustomFont());
     105    if (!m_derivedFontData->smallCaps)
     106        m_derivedFontData->smallCaps = scaledFontData(fontDescription, .7);
     107
     108    return m_derivedFontData->smallCaps.get();
     109}
     110
     111SimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
     112{
     113    if (!m_derivedFontData)
     114        m_derivedFontData = DerivedFontData::create(isCustomFont());
     115    if (!m_derivedFontData->emphasisMark)
     116        m_derivedFontData->emphasisMark = scaledFontData(fontDescription, .5);
     117
     118    return m_derivedFontData->emphasisMark.get();
    102119}
    103120
  • trunk/WebCore/platform/text/CharacterNames.h

    r74095 r74169  
    3333// Names here are taken from the Unicode standard.
    3434
    35 // Note, these are UChar constants, not UChar32, which makes them
     35// Most of these are UChar constants, not UChar32, which makes them
    3636// more convenient for WebCore code that mostly uses UTF-16.
    3737
     38const UChar32 aegeanWordSeparatorLine = 0x10100;
     39const UChar32 aegeanWordSeparatorDot = 0x10101;
    3840const UChar blackCircle = 0x25CF;
    3941const UChar blackSquare = 0x25A0;
     
    4345const UChar carriageReturn = 0x000D;
    4446const UChar ethiopicPrefaceColon = 0x1366;
     47const UChar ethiopicWordspace = 0x1361;
    4548const UChar fisheye = 0x25C9;
    4649const UChar hebrewPunctuationGeresh = 0x05F3;
     
    7174const UChar softHyphen = 0x00AD;
    7275const UChar space = 0x0020;
     76const UChar tibetanMarkIntersyllabicTsheg = 0x0F0B;
     77const UChar tibetanMarkDelimiterTshegBstar = 0x0F0C;
     78const UChar32 ugariticWordDivider = 0x1039F;
    7379const UChar whiteBullet = 0x25E6;
    7480const UChar whiteCircle = 0x25CB;
Note: See TracChangeset for help on using the changeset viewer.