[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-10851-g50815da

mitz at apple.com mitz at apple.com
Wed Dec 22 18:42:36 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 28f527269ab16a5cd975dcfd46139f7bd588fb0b
Author: mitz at apple.com <mitz at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Dec 16 02:23:48 2010 +0000

    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().
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@74169 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 8e9d13a..6a0ec81 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,169 @@
+2010-12-15  Dan Bernstein  <mitz at apple.com>
+
+        Reviewed by Darin Adler.
+
+        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
+
+        * 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().
+
 2010-12-15  Beth Dakin  <bdakin at apple.com>
 
         Reviewed by Darin Adler.
diff --git a/WebCore/platform/graphics/Font.cpp b/WebCore/platform/graphics/Font.cpp
index 0c9ea39..8828a31 100644
--- a/WebCore/platform/graphics/Font.cpp
+++ b/WebCore/platform/graphics/Font.cpp
@@ -156,6 +156,26 @@ void Font::drawText(GraphicsContext* context, const TextRun& run, const FloatPoi
     return drawComplexText(context, run, point, from, to);
 }
 
+void Font::drawEmphasisMarks(GraphicsContext* context, const TextRun& run, const AtomicString& mark, const FloatPoint& point, int from, int to) const
+{
+    if (m_fontList && m_fontList->loadingCustomFonts())
+        return;
+
+    if (to < 0)
+        to = run.length();
+
+#if ENABLE(SVG_FONTS)
+    // FIXME: Implement for SVG fonts.
+    if (primaryFont()->isSVGFont())
+        return;
+#endif
+
+    if (codePath(run) != Complex)
+        drawEmphasisMarksForSimpleText(context, run, mark, point, from, to);
+    else
+        drawEmphasisMarksForComplexText(context, run, mark, point, from, to);
+}
+
 float Font::floatWidth(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
 {
 #if ENABLE(SVG_FONTS)
@@ -438,4 +458,18 @@ bool Font::isCJKIdeographOrSymbol(UChar32 c)
     return isCJKIdeograph(c);
 }
 
+bool Font::canReceiveTextEmphasis(UChar32 c)
+{
+    CharCategory category = Unicode::category(c);
+    if (category & (Separator_Space | Separator_Line | Separator_Paragraph | Other_NotAssigned | Other_Control | Other_Format))
+        return false;
+
+    // Additional word-separator characters listed in CSS Text Level 3 Editor's Draft 3 November 2010.
+    if (c == ethiopicWordspace || c == aegeanWordSeparatorLine || c == aegeanWordSeparatorDot
+        || c == ugariticWordDivider || c == tibetanMarkIntersyllabicTsheg || c == tibetanMarkDelimiterTshegBstar)
+        return false;
+
+    return true;
+}
+
 }
diff --git a/WebCore/platform/graphics/Font.h b/WebCore/platform/graphics/Font.h
index 56f6947..4097f1e 100644
--- a/WebCore/platform/graphics/Font.h
+++ b/WebCore/platform/graphics/Font.h
@@ -93,6 +93,7 @@ public:
     void update(PassRefPtr<FontSelector>) const;
 
     void drawText(GraphicsContext*, const TextRun&, const FloatPoint&, int from = 0, int to = -1) const;
+    void drawEmphasisMarks(GraphicsContext*, const TextRun&, const AtomicString& mark, const FloatPoint&, int from = 0, int to = -1) const;
 
     int width(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* glyphOverflow = 0) const { return lroundf(floatWidth(run, fallbackFonts, glyphOverflow)); }
     float floatWidth(const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* glyphOverflow = 0) const;
@@ -136,10 +137,13 @@ public:
     unsigned unitsPerEm() const { return primaryFont()->unitsPerEm(); }
     int spaceWidth() const { return (int)ceilf(primaryFont()->adjustedSpaceWidth() + m_letterSpacing); }
     float tabWidth(const SimpleFontData& fontData) const { return 8 * ceilf(fontData.adjustedSpaceWidth() + letterSpacing()); }
+    int emphasisMarkAscent(const AtomicString&) const;
+    int emphasisMarkDescent(const AtomicString&) const;
+    int emphasisMarkHeight(const AtomicString&) const;
 
     const SimpleFontData* primaryFont() const;
     const FontData* fontDataAt(unsigned) const;
-    GlyphData glyphDataForCharacter(UChar32, bool mirror, bool forceSmallCaps = false) const;
+    GlyphData glyphDataForCharacter(UChar32, bool mirror, FontDataVariant = AutoVariant) const;
     // Used for complex text, and does not utilize the glyph map cache.
     const FontData* fontDataForCharacters(const UChar*, int length) const;
 
@@ -164,17 +168,29 @@ private:
     int offsetForPositionForTextUsingSVGFont(const TextRun&, float position, bool includePartialGlyphs) const;
 #endif
 
+    enum ForTextEmphasisOrNot { NotForTextEmphasis, ForTextEmphasis };
+
+    // Returns the initial in-stream advance.
+    float getGlyphsAndAdvancesForSimpleText(const TextRun&, int from, int to, GlyphBuffer&, ForTextEmphasisOrNot = NotForTextEmphasis) const;
     void drawSimpleText(GraphicsContext*, const TextRun&, const FloatPoint&, int from, int to) const;
+    void drawEmphasisMarksForSimpleText(GraphicsContext*, const TextRun&, const AtomicString& mark, const FloatPoint&, int from, int to) const;
     void drawGlyphs(GraphicsContext*, const SimpleFontData*, const GlyphBuffer&, int from, int to, const FloatPoint&) const;
-    void drawGlyphBuffer(GraphicsContext*, const GlyphBuffer&, const TextRun&, const FloatPoint&) const;
+    void drawGlyphBuffer(GraphicsContext*, const GlyphBuffer&, const FloatPoint&) const;
+    void drawEmphasisMarks(GraphicsContext* context, const GlyphBuffer&, const AtomicString&, const FloatPoint&) const;
     float floatWidthForSimpleText(const TextRun&, GlyphBuffer*, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
     int offsetForPositionForSimpleText(const TextRun&, float position, bool includePartialGlyphs) const;
     FloatRect selectionRectForSimpleText(const TextRun&, const FloatPoint&, int h, int from, int to) const;
 
+    bool getEmphasisMarkGlyphData(const AtomicString&, GlyphData&) const;
+
     static bool canReturnFallbackFontsForComplexText();
 
     CodePath codePath(const TextRun&) const;
+
+    // Returns the initial in-stream advance.
+    float getGlyphsAndAdvancesForComplexText(const TextRun&, int from, int to, GlyphBuffer&, ForTextEmphasisOrNot = NotForTextEmphasis) const;
     void drawComplexText(GraphicsContext*, const TextRun&, const FloatPoint&, int from, int to) const;
+    void drawEmphasisMarksForComplexText(GraphicsContext*, const TextRun&, const AtomicString& mark, const FloatPoint&, int from, int to) const;
     float floatWidthForComplexText(const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
     int offsetForPositionForComplexText(const TextRun&, float position, bool includePartialGlyphs) const;
     FloatRect selectionRectForComplexText(const TextRun&, const FloatPoint&, int h, int from, int to) const;
@@ -196,6 +212,7 @@ public:
     FontSelector* fontSelector() const;
     static bool treatAsSpace(UChar c) { return c == ' ' || c == '\t' || c == '\n' || c == noBreakSpace; }
     static bool treatAsZeroWidthSpace(UChar c) { return c < 0x20 || (c >= 0x7F && c < 0xA0) || c == softHyphen || (c >= 0x200c && c <= 0x200f) || (c >= 0x202a && c <= 0x202e) || c == objectReplacementCharacter; }
+    static bool canReceiveTextEmphasis(UChar32 c);
 
     static inline UChar normalizeSpaces(UChar character)
     {
diff --git a/WebCore/platform/graphics/FontFastPath.cpp b/WebCore/platform/graphics/FontFastPath.cpp
index 1c3e571..fb3b107 100644
--- a/WebCore/platform/graphics/FontFastPath.cpp
+++ b/WebCore/platform/graphics/FontFastPath.cpp
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2003, 2006 Apple Computer, Inc.
+ * Copyright (C) 2003, 2006, 2010 Apple Inc. All rights reserved.
  * Copyright (C) 2008 Holger Hans Peter Freyther
  * Copyright (C) 2009 Torch Mobile, Inc.
  *
@@ -40,17 +40,20 @@ using namespace Unicode;
 
 namespace WebCore {
 
-GlyphData Font::glyphDataForCharacter(UChar32 c, bool mirror, bool forceSmallCaps) const
+GlyphData Font::glyphDataForCharacter(UChar32 c, bool mirror, FontDataVariant variant) const
 {
     ASSERT(isMainThread());
 
-    bool useSmallCapsFont = forceSmallCaps;
-    if (m_fontDescription.smallCaps()) {
-        UChar32 upperC = toUpper(c);
-        if (upperC != c) {
-            c = upperC;
-            useSmallCapsFont = true;
-        }
+    if (variant == AutoVariant) {
+        if (m_fontDescription.smallCaps()) {
+            UChar32 upperC = toUpper(c);
+            if (upperC != c) {
+                c = upperC;
+                variant = SmallCapsVariant;
+            } else
+                variant = NormalVariant;
+        } else
+            variant = NormalVariant;
     }
 
     if (mirror)
@@ -68,8 +71,8 @@ GlyphData Font::glyphDataForCharacter(UChar32 c, bool mirror, bool forceSmallCap
     }
 
     GlyphPage* page;
-    if (!useSmallCapsFont) {
-        // Fastest loop, for the common case (not small caps).
+    if (variant == NormalVariant) {
+        // Fastest loop, for the common case (normal variant).
         while (true) {
             page = node->page();
             if (page) {
@@ -108,23 +111,23 @@ GlyphData Font::glyphDataForCharacter(UChar32 c, bool mirror, bool forceSmallCap
             if (page) {
                 GlyphData data = page->glyphDataForCharacter(c);
                 if (data.fontData) {
-                    // The smallCapsFontData function should not normally return 0.
+                    // The variantFontData function should not normally return 0.
                     // But if it does, we will just render the capital letter big.
-                    const SimpleFontData* smallCapsFontData = data.fontData->smallCapsFontData(m_fontDescription);
-                    if (!smallCapsFontData)
+                    const SimpleFontData* variantFontData = data.fontData->variantFontData(m_fontDescription, variant);
+                    if (!variantFontData)
                         return data;
 
-                    GlyphPageTreeNode* smallCapsNode = GlyphPageTreeNode::getRootChild(smallCapsFontData, pageNumber);
-                    const GlyphPage* smallCapsPage = smallCapsNode->page();
-                    if (smallCapsPage) {
-                        GlyphData data = smallCapsPage->glyphDataForCharacter(c);
+                    GlyphPageTreeNode* variantNode = GlyphPageTreeNode::getRootChild(variantFontData, pageNumber);
+                    const GlyphPage* variantPage = variantNode->page();
+                    if (variantPage) {
+                        GlyphData data = variantPage->glyphDataForCharacter(c);
                         if (data.fontData)
                             return data;
                     }
 
-                    // Do not attempt system fallback off the smallCapsFontData. This is the very unlikely case that
+                    // Do not attempt system fallback off the variantFontData. This is the very unlikely case that
                     // a font has the lowercase character but the small caps font does not have its uppercase version.
-                    return smallCapsFontData->missingGlyphData();
+                    return variantFontData->missingGlyphData();
                 }
 
                 if (node->isSystemFallback())
@@ -157,14 +160,14 @@ GlyphData Font::glyphDataForCharacter(UChar32 c, bool mirror, bool forceSmallCap
         codeUnitsLength = 2;
     }
     const SimpleFontData* characterFontData = fontCache()->getFontDataForCharacters(*this, codeUnits, codeUnitsLength);
-    if (useSmallCapsFont && characterFontData)
-        characterFontData = characterFontData->smallCapsFontData(m_fontDescription);
+    if (variant != NormalVariant && characterFontData)
+        characterFontData = characterFontData->variantFontData(m_fontDescription, variant);
     if (characterFontData) {
         // Got the fallback glyph and font.
         GlyphPage* fallbackPage = GlyphPageTreeNode::getRootChild(characterFontData, pageNumber)->page();
         GlyphData data = fallbackPage && fallbackPage->fontDataForCharacter(c) ? fallbackPage->glyphDataForCharacter(c) : characterFontData->missingGlyphData();
         // Cache it so we don't have to do system fallback again next time.
-        if (!useSmallCapsFont) {
+        if (variant == NormalVariant) {
 #if OS(WINCE)
             // missingGlyphData returns a null character, which is not suitable for GDI to display.
             // Also, sometimes we cannot map a font for the character on WINCE, but GDI can still
@@ -182,7 +185,7 @@ GlyphData Font::glyphDataForCharacter(UChar32 c, bool mirror, bool forceSmallCap
     // Even system fallback can fail; use the missing glyph in that case.
     // FIXME: It would be nicer to use the missing glyph from the last resort font instead.
     GlyphData data = primaryFont()->missingGlyphData();
-    if (!useSmallCapsFont) {
+    if (variant == NormalVariant) {
 #if OS(WINCE)
         // See comment about WINCE GDI handling near setGlyphDataForCharacter above.
         page->setGlyphDataForCharacter(c, c, data.fontData);
@@ -194,42 +197,136 @@ GlyphData Font::glyphDataForCharacter(UChar32 c, bool mirror, bool forceSmallCap
     return data;
 }
 
-void Font::drawSimpleText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const
+// FIXME: This function may not work if the emphasis mark uses a complex script, but none of the
+// standard emphasis marks do so.
+bool Font::getEmphasisMarkGlyphData(const AtomicString& mark, GlyphData& glyphData) const
 {
-    // This glyph buffer holds our glyphs+advances+font data for each glyph.
-    GlyphBuffer glyphBuffer;
+    if (mark.isEmpty())
+        return false;
 
-    float startX = point.x();
-    WidthIterator it(this, run);
+#if ENABLE(SVG_FONTS)
+    // FIXME: Implement for SVG fonts.
+    if (primaryFont()->isSVGFont())
+        return false;
+#endif
+
+    UChar32 character = mark[0];
+
+    if (U16_IS_SURROGATE(character)) {
+        if (!U16_IS_SURROGATE_LEAD(character))
+            return false;
+
+        if (mark.length() < 2)
+            return false;
+
+        UChar low = mark[1];
+        if (!U16_IS_TRAIL(low))
+            return false;
+
+        character = U16_GET_SUPPLEMENTARY(character, low);
+    }
+
+    glyphData = glyphDataForCharacter(character, false, EmphasisMarkVariant);
+    return true;
+}
+
+int Font::emphasisMarkAscent(const AtomicString& mark) const
+{
+    GlyphData markGlyphData;
+    if (!getEmphasisMarkGlyphData(mark, markGlyphData))
+        return 0;
+
+    const SimpleFontData* markFontData = markGlyphData.fontData;
+    ASSERT(markFontData);
+    if (!markFontData)
+        return 0;
+
+    return markFontData->ascent();
+}
+
+int Font::emphasisMarkDescent(const AtomicString& mark) const
+{
+    GlyphData markGlyphData;
+    if (!getEmphasisMarkGlyphData(mark, markGlyphData))
+        return 0;
+
+    const SimpleFontData* markFontData = markGlyphData.fontData;
+    ASSERT(markFontData);
+    if (!markFontData)
+        return 0;
+
+    return markFontData->descent();
+}
+
+int Font::emphasisMarkHeight(const AtomicString& mark) const
+{
+    GlyphData markGlyphData;
+    if (!getEmphasisMarkGlyphData(mark, markGlyphData))
+        return 0;
+
+    const SimpleFontData* markFontData = markGlyphData.fontData;
+    ASSERT(markFontData);
+    if (!markFontData)
+        return 0;
+
+    return markFontData->height();
+}
+
+float Font::getGlyphsAndAdvancesForSimpleText(const TextRun& run, int from, int to, GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot forTextEmphasis) const
+{
+    float initialAdvance;
+
+    WidthIterator it(this, run, false, forTextEmphasis);
     it.advance(from);
     float beforeWidth = it.m_runWidthSoFar;
     it.advance(to, &glyphBuffer);
-    
-    // We couldn't generate any glyphs for the run.  Give up.
+
     if (glyphBuffer.isEmpty())
-        return;
-    
+        return 0;
+
     float afterWidth = it.m_runWidthSoFar;
 
     if (run.rtl()) {
         float finalRoundingWidth = it.m_finalRoundingWidth;
         it.advance(run.length());
-        startX += finalRoundingWidth + it.m_runWidthSoFar - afterWidth;
+        initialAdvance = finalRoundingWidth + it.m_runWidthSoFar - afterWidth;
     } else
-        startX += beforeWidth;
+        initialAdvance = beforeWidth;
 
-    // Swap the order of the glyphs if right-to-left.
-    if (run.rtl())
+    if (run.rtl()) {
         for (int i = 0, end = glyphBuffer.size() - 1; i < glyphBuffer.size() / 2; ++i, --end)
             glyphBuffer.swap(i, end);
+    }
+
+    return initialAdvance;
+}
+
+void Font::drawSimpleText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const
+{
+    // This glyph buffer holds our glyphs+advances+font data for each glyph.
+    GlyphBuffer glyphBuffer;
+
+    float startX = point.x() + getGlyphsAndAdvancesForSimpleText(run, from, to, glyphBuffer);
+
+    if (glyphBuffer.isEmpty())
+        return;
 
-    // Calculate the starting point of the glyphs to be displayed by adding
-    // all the advances up to the first glyph.
     FloatPoint startPoint(startX, point.y());
-    drawGlyphBuffer(context, glyphBuffer, run, startPoint);
+    drawGlyphBuffer(context, glyphBuffer, startPoint);
+}
+
+void Font::drawEmphasisMarksForSimpleText(GraphicsContext* context, const TextRun& run, const AtomicString& mark, const FloatPoint& point, int from, int to) const
+{
+    GlyphBuffer glyphBuffer;
+    float initialAdvance = getGlyphsAndAdvancesForSimpleText(run, from, to, glyphBuffer, ForTextEmphasis);
+
+    if (glyphBuffer.isEmpty())
+        return;
+
+    drawEmphasisMarks(context, glyphBuffer, mark, FloatPoint(point.x() + initialAdvance, point.y()));
 }
 
-void Font::drawGlyphBuffer(GraphicsContext* context, const GlyphBuffer& glyphBuffer, const TextRun&, const FloatPoint& point) const
+void Font::drawGlyphBuffer(GraphicsContext* context, const GlyphBuffer& glyphBuffer, const FloatPoint& point) const
 {   
     // Draw each contiguous run of glyphs that use the same font data.
     const SimpleFontData* fontData = glyphBuffer.fontDataAt(0);
@@ -256,6 +353,50 @@ void Font::drawGlyphBuffer(GraphicsContext* context, const GlyphBuffer& glyphBuf
     drawGlyphs(context, fontData, glyphBuffer, lastFrom, nextGlyph - lastFrom, startPoint);
 }
 
+inline static float offsetToMiddleOfGlyph(const SimpleFontData* fontData, Glyph glyph)
+{
+    if (fontData->orientation() == Horizontal) {
+        FloatRect bounds = fontData->boundsForGlyph(glyph);
+        return bounds.x() + bounds.width() / 2;
+    }
+    // FIXME: Use glyph bounds once they make sense for vertical fonts.
+    return fontData->widthForGlyph(glyph) / 2;
+}
+
+inline static float offsetToMiddleOfGlyphAtIndex(const GlyphBuffer& glyphBuffer, size_t i)
+{
+    return offsetToMiddleOfGlyph(glyphBuffer.fontDataAt(i), glyphBuffer.glyphAt(i));
+}
+
+void Font::drawEmphasisMarks(GraphicsContext* context, const GlyphBuffer& glyphBuffer, const AtomicString& mark, const FloatPoint& point) const
+{
+    GlyphData markGlyphData;
+    if (!getEmphasisMarkGlyphData(mark, markGlyphData))
+        return;
+
+    const SimpleFontData* markFontData = markGlyphData.fontData;
+    ASSERT(markFontData);
+    if (!markFontData)
+        return;
+
+    Glyph markGlyph = markGlyphData.glyph;
+    Glyph spaceGlyph = markFontData->spaceGlyph();
+
+    float middleOfLastGlyph = offsetToMiddleOfGlyphAtIndex(glyphBuffer, 0);
+    FloatPoint startPoint(point.x() + middleOfLastGlyph - offsetToMiddleOfGlyph(markFontData, markGlyph), point.y());
+
+    GlyphBuffer markBuffer;
+    for (int i = 0; i + 1 < glyphBuffer.size(); ++i) {
+        float middleOfNextGlyph = offsetToMiddleOfGlyphAtIndex(glyphBuffer, i + 1);
+        float advance = glyphBuffer.advanceAt(i) - middleOfLastGlyph + middleOfNextGlyph;
+        markBuffer.add(glyphBuffer.glyphAt(i) ? markGlyph : spaceGlyph, markFontData, advance);
+        middleOfLastGlyph = middleOfNextGlyph;
+    }
+    markBuffer.add(glyphBuffer.glyphAt(glyphBuffer.size() - 1) ? markGlyph : spaceGlyph, markFontData, 0);
+
+    drawGlyphBuffer(context, markBuffer, startPoint);
+}
+
 float Font::floatWidthForSimpleText(const TextRun& run, GlyphBuffer* glyphBuffer, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
 {
     WidthIterator it(this, run, fallbackFonts, glyphOverflow);
diff --git a/WebCore/platform/graphics/GraphicsContext.cpp b/WebCore/platform/graphics/GraphicsContext.cpp
index f7dcc62..9b621f8 100644
--- a/WebCore/platform/graphics/GraphicsContext.cpp
+++ b/WebCore/platform/graphics/GraphicsContext.cpp
@@ -355,6 +355,14 @@ void GraphicsContext::drawText(const Font& font, const TextRun& run, const IntPo
 }
 #endif
 
+void GraphicsContext::drawEmphasisMarks(const Font& font, const TextRun& run, const AtomicString& mark, const IntPoint& point, int from, int to)
+{
+    if (paintingDisabled())
+        return;
+
+    font.drawEmphasisMarks(this, run, mark, point, from, to);
+}
+
 void GraphicsContext::drawBidiText(const Font& font, const TextRun& run, const FloatPoint& point)
 {
     if (paintingDisabled())
diff --git a/WebCore/platform/graphics/GraphicsContext.h b/WebCore/platform/graphics/GraphicsContext.h
index a9b8cd9..8541e37 100644
--- a/WebCore/platform/graphics/GraphicsContext.h
+++ b/WebCore/platform/graphics/GraphicsContext.h
@@ -320,6 +320,7 @@ namespace WebCore {
         void setTextDrawingMode(TextDrawingModeFlags);
 
         void drawText(const Font&, const TextRun&, const IntPoint&, int from = 0, int to = -1);
+        void drawEmphasisMarks(const Font&, const TextRun& , const AtomicString& mark, const IntPoint&, int from = 0, int to = -1);
         void drawBidiText(const Font&, const TextRun&, const FloatPoint&);
         void drawHighlightForText(const Font&, const TextRun&, const IntPoint&, int h, const Color& backgroundColor, ColorSpace, int from = 0, int to = -1);
 
diff --git a/WebCore/platform/graphics/SimpleFontData.cpp b/WebCore/platform/graphics/SimpleFontData.cpp
index 391873a..e773880 100644
--- a/WebCore/platform/graphics/SimpleFontData.cpp
+++ b/WebCore/platform/graphics/SimpleFontData.cpp
@@ -57,8 +57,6 @@ SimpleFontData::SimpleFontData(const FontPlatformData& platformData, bool isCust
     , m_isCustomFont(isCustomFont)
     , m_isLoading(isLoading)
     , m_isBrokenIdeographFont(false)
-    , m_smallCapsFontData(0)
-    , m_brokenIdeographFontData(0)
 {
     platformInit();
     platformGlyphInit();
@@ -74,8 +72,6 @@ SimpleFontData::SimpleFontData(PassOwnPtr<SVGFontData> svgFontData, int size, bo
     , m_isCustomFont(true)
     , m_isLoading(false)
     , m_isBrokenIdeographFont(false)
-    , m_smallCapsFontData(0)
-    , m_brokenIdeographFontData(0)
 {
     SVGFontFaceElement* svgFontFaceElement = m_svgFontData->svgFontFaceElement();
     m_unitsPerEm = svgFontFaceElement->unitsPerEm();
@@ -186,16 +182,6 @@ SimpleFontData::~SimpleFontData()
 
     if (!isCustomFont())
         GlyphPageTreeNode::pruneTreeFontData(this);
-    else {
-        if (m_smallCapsFontData)
-            GlyphPageTreeNode::pruneTreeCustomFontData(m_smallCapsFontData);
-
-        if (m_brokenIdeographFontData)
-            GlyphPageTreeNode::pruneTreeCustomFontData(m_brokenIdeographFontData);
-    }
-
-    delete m_smallCapsFontData;
-    delete m_brokenIdeographFontData;
 }
 
 const SimpleFontData* SimpleFontData::fontDataForCharacter(UChar32) const
@@ -210,12 +196,14 @@ bool SimpleFontData::isSegmented() const
 
 SimpleFontData* SimpleFontData::brokenIdeographFontData() const
 {
-    if (!m_brokenIdeographFontData) {
-        m_brokenIdeographFontData = new SimpleFontData(m_platformData, isCustomFont(), false);
-        m_brokenIdeographFontData->m_orientation = Vertical;
-        m_brokenIdeographFontData->m_isBrokenIdeographFont = true;
+    if (!m_derivedFontData)
+        m_derivedFontData = DerivedFontData::create(isCustomFont());
+    if (!m_derivedFontData->brokenIdeograph) {
+        m_derivedFontData->brokenIdeograph = new SimpleFontData(m_platformData, isCustomFont(), false);
+        m_derivedFontData->brokenIdeograph->m_orientation = Vertical;
+        m_derivedFontData->brokenIdeograph->m_isBrokenIdeographFont = true;
     }
-    return m_brokenIdeographFontData;
+    return m_derivedFontData->brokenIdeograph.get();
 }
 
 #ifndef NDEBUG
@@ -230,4 +218,22 @@ String SimpleFontData::description() const
 }
 #endif
 
+PassOwnPtr<SimpleFontData::DerivedFontData> SimpleFontData::DerivedFontData::create(bool forCustomFont)
+{
+    return adoptPtr(new DerivedFontData(forCustomFont));
+}
+
+SimpleFontData::DerivedFontData::~DerivedFontData()
+{
+    if (!forCustomFont)
+        return;
+
+    if (smallCaps)
+        GlyphPageTreeNode::pruneTreeCustomFontData(smallCaps.get());
+    if (emphasisMark)
+        GlyphPageTreeNode::pruneTreeCustomFontData(emphasisMark.get());
+    if (brokenIdeograph)
+        GlyphPageTreeNode::pruneTreeCustomFontData(brokenIdeograph.get());
+}
+
 } // namespace WebCore
diff --git a/WebCore/platform/graphics/SimpleFontData.h b/WebCore/platform/graphics/SimpleFontData.h
index ea053cd..90713af 100644
--- a/WebCore/platform/graphics/SimpleFontData.h
+++ b/WebCore/platform/graphics/SimpleFontData.h
@@ -65,6 +65,7 @@ class FontDescription;
 class SharedBuffer;
 class SVGFontData;
 
+enum FontDataVariant { AutoVariant, NormalVariant, SmallCapsVariant, EmphasisMarkVariant };
 enum Pitch { UnknownPitch, FixedPitch, VariablePitch };
 
 class SimpleFontData : public FontData {
@@ -76,7 +77,24 @@ public:
     virtual ~SimpleFontData();
 
     const FontPlatformData& platformData() const { return m_platformData; }
-    SimpleFontData* smallCapsFontData(const FontDescription& fontDescription) const;
+
+    SimpleFontData* smallCapsFontData(const FontDescription&) const;
+    SimpleFontData* emphasisMarkFontData(const FontDescription&) const;
+
+    SimpleFontData* variantFontData(const FontDescription& description, FontDataVariant variant) const
+    {
+        switch (variant) {
+        case SmallCapsVariant:
+            return smallCapsFontData(description);
+        case EmphasisMarkVariant:
+            return emphasisMarkFontData(description);
+        case AutoVariant:
+        case NormalVariant:
+            break;
+        }
+        ASSERT_NOT_REACHED();
+        return const_cast<SimpleFontData*>(this);
+    }
 
     SimpleFontData* brokenIdeographFontData() const;
     
@@ -183,6 +201,8 @@ private:
 
     void commonInit();
 
+    SimpleFontData* scaledFontData(const FontDescription&, float scaleFactor) const;
+
 #if (PLATFORM(WIN) && !OS(WINCE)) \
     || (OS(WINDOWS) && PLATFORM(WX))
     void initGDIFont();
@@ -226,9 +246,23 @@ private:
 
     GlyphData m_missingGlyphData;
 
-    mutable SimpleFontData* m_smallCapsFontData;
+    struct DerivedFontData {
+        static PassOwnPtr<DerivedFontData> create(bool forCustomFont);
+        ~DerivedFontData();
+
+        bool forCustomFont;
+        OwnPtr<SimpleFontData> smallCaps;
+        OwnPtr<SimpleFontData> emphasisMark;
+        OwnPtr<SimpleFontData> brokenIdeograph;
+
+    private:
+        DerivedFontData(bool custom)
+            : forCustomFont(custom)
+        {
+        }
+    };
 
-    mutable SimpleFontData* m_brokenIdeographFontData;
+    mutable OwnPtr<DerivedFontData> m_derivedFontData;
 
 #if PLATFORM(CG) || PLATFORM(CAIRO) || PLATFORM(WX)
     float m_syntheticBoldOffset;
diff --git a/WebCore/platform/graphics/WidthIterator.cpp b/WebCore/platform/graphics/WidthIterator.cpp
index ae58918..2a951e8 100644
--- a/WebCore/platform/graphics/WidthIterator.cpp
+++ b/WebCore/platform/graphics/WidthIterator.cpp
@@ -40,7 +40,7 @@ namespace WebCore {
 // According to http://www.unicode.org/Public/UNIDATA/UCD.html#Canonical_Combining_Class_Values
 static const uint8_t hiraganaKatakanaVoicingMarksCombiningClass = 8;
 
-WidthIterator::WidthIterator(const Font* font, const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, bool accountForGlyphBounds)
+WidthIterator::WidthIterator(const Font* font, const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, bool accountForGlyphBounds, bool forTextEmphasis)
     : m_font(font)
     , m_run(run)
     , m_end(run.length())
@@ -53,6 +53,7 @@ WidthIterator::WidthIterator(const Font* font, const TextRun& run, HashSet<const
     , m_minGlyphBoundingBoxY(numeric_limits<float>::max())
     , m_firstGlyphOverflow(0)
     , m_lastGlyphOverflow(0)
+    , m_forTextEmphasis(forTextEmphasis)
 {
     // If the padding is non-zero, count the number of spaces in the run
     // and divide that by the padding for per space addition.
@@ -199,6 +200,9 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer)
                 m_firstGlyphOverflow = max<float>(0, -bounds.x());
         }
 
+        if (m_forTextEmphasis && !Font::canReceiveTextEmphasis(c))
+            glyph = 0;
+
         // Advance past the character we just dealt with.
         cp += clusterLength;
         currentCharacter += clusterLength;
diff --git a/WebCore/platform/graphics/WidthIterator.h b/WebCore/platform/graphics/WidthIterator.h
index d42a0c5..8b3c067 100644
--- a/WebCore/platform/graphics/WidthIterator.h
+++ b/WebCore/platform/graphics/WidthIterator.h
@@ -33,7 +33,7 @@ class SimpleFontData;
 class TextRun;
 
 struct WidthIterator {
-    WidthIterator(const Font*, const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0, bool accountForGlyphBounds = false);
+    WidthIterator(const Font*, const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0, bool accountForGlyphBounds = false, bool forTextEmphasis = false);
 
     void advance(int to, GlyphBuffer* = 0);
     bool advanceOneCharacter(float& width, GlyphBuffer* = 0);
@@ -63,6 +63,7 @@ private:
     float m_minGlyphBoundingBoxY;
     float m_firstGlyphOverflow;
     float m_lastGlyphOverflow;
+    bool m_forTextEmphasis;
 };
 
 }
diff --git a/WebCore/platform/graphics/chromium/FontChromiumWin.cpp b/WebCore/platform/graphics/chromium/FontChromiumWin.cpp
index 8a77501..0a6ff78 100644
--- a/WebCore/platform/graphics/chromium/FontChromiumWin.cpp
+++ b/WebCore/platform/graphics/chromium/FontChromiumWin.cpp
@@ -35,6 +35,7 @@
 #include "ChromiumBridge.h"
 #include "FontFallbackList.h"
 #include "GlyphBuffer.h"
+#include "NotImplemented.h"
 #include "PlatformContextSkia.h"
 #include "SimpleFontData.h"
 #include "SkiaFontWin.h"
@@ -505,6 +506,11 @@ void Font::drawComplexText(GraphicsContext* graphicsContext,
     context->canvas()->endPlatformPaint();
 }
 
+void Font::drawEmphasisMarksForComplexText(GraphicsContext* /* context */, const TextRun& /* run */, const AtomicString& /* mark */, const FloatPoint& /* point */, int /* from */, int /* to */) const
+{
+    notImplemented();
+}
+
 float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* /* fallbackFonts */, GlyphOverflow* /* glyphOverflow */) const
 {
     UniscribeHelperTextRun state(run, *this);
diff --git a/WebCore/platform/graphics/chromium/FontLinux.cpp b/WebCore/platform/graphics/chromium/FontLinux.cpp
index d1cfac6..4a4e53f 100644
--- a/WebCore/platform/graphics/chromium/FontLinux.cpp
+++ b/WebCore/platform/graphics/chromium/FontLinux.cpp
@@ -381,7 +381,7 @@ bool TextRunWalker::nextScriptRun()
         // (and the glyphs in each A, C and T section are backwards too)
         if (!hb_utf16_script_run_prev(&m_numCodePoints, &m_item.item, m_run.characters(), m_run.length(), &m_indexOfNextScriptRun))
             return false;
-        m_currentFontData = m_font->glyphDataForCharacter(m_item.string[m_item.item.pos], false, false).fontData;
+        m_currentFontData = m_font->glyphDataForCharacter(m_item.string[m_item.item.pos], false).fontData;
     } else {
         if (!hb_utf16_script_run_next(&m_numCodePoints, &m_item.item, m_run.characters(), m_run.length(), &m_indexOfNextScriptRun))
             return false;
@@ -393,10 +393,10 @@ bool TextRunWalker::nextScriptRun()
         // in the harfbuzz data structures to e.g. pick the correct script's shaper.
         // So we allow that to run first, then do a second pass over the range it
         // found and take the largest subregion that stays within a single font.
-        m_currentFontData = m_font->glyphDataForCharacter(m_item.string[m_item.item.pos], false, false).fontData;
+        m_currentFontData = m_font->glyphDataForCharacter(m_item.string[m_item.item.pos], false).fontData;
         unsigned endOfRun;
         for (endOfRun = 1; endOfRun < m_item.item.length; ++endOfRun) {
-            const SimpleFontData* nextFontData = m_font->glyphDataForCharacter(m_item.string[m_item.item.pos + endOfRun], false, false).fontData;
+            const SimpleFontData* nextFontData = m_font->glyphDataForCharacter(m_item.string[m_item.item.pos + endOfRun], false).fontData;
             if (nextFontData != m_currentFontData)
                 break;
         }
@@ -422,7 +422,7 @@ float TextRunWalker::widthOfFullRun()
 
 void TextRunWalker::setupFontForScriptRun()
 {
-    const FontData* fontData = m_font->glyphDataForCharacter(m_item.string[m_item.item.pos], false, false).fontData;
+    const FontData* fontData = m_font->glyphDataForCharacter(m_item.string[m_item.item.pos], false).fontData;
     const FontPlatformData& platformData = fontData->fontDataForCharacter(' ')->platformData();
     m_item.face = platformData.harfbuzzFace();
     void* opaquePlatformData = const_cast<FontPlatformData*>(&platformData);
@@ -690,6 +690,11 @@ void Font::drawComplexText(GraphicsContext* gc, const TextRun& run,
     }
 }
 
+void Font::drawEmphasisMarksForComplexText(GraphicsContext* /* context */, const TextRun& /* run */, const AtomicString& /* mark */, const FloatPoint& /* point */, int /* from */, int /* to */) const
+{
+    notImplemented();
+}
+
 float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* /* fallbackFonts */, GlyphOverflow* /* glyphOverflow */) const
 {
     TextRunWalker walker(run, 0, this);
diff --git a/WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp b/WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp
index bcef1fe..204c565 100644
--- a/WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp
+++ b/WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp
@@ -112,20 +112,34 @@ void SimpleFontData::platformDestroy()
 {
 }
 
+SimpleFontData* SimpleFontData::scaledFontData(const FontDescription& fontDescription, float scaleFactor) const
+{
+    LOGFONT winFont;
+    GetObject(m_platformData.hfont(), sizeof(LOGFONT), &winFont);
+    float scaledSize = scaleFactor * fontDescription.computedSize();
+    winFont.lfHeight = -lroundf(scaledSize);
+    HFONT hfont = CreateFontIndirect(&winFont);
+    return new SimpleFontData(FontPlatformData(hfont, scaledSize), isCustomFont(), false);
+}
+
 SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
 {
-    if (!m_smallCapsFontData) {
-        LOGFONT winFont;
-        GetObject(m_platformData.hfont(), sizeof(LOGFONT), &winFont);
-        float smallCapsSize = 0.70f * fontDescription.computedSize();
-        // Unlike WebKit trunk, we don't multiply the size by 32.  That seems
-        // to be some kind of artifact of their CG backend, or something.
-        winFont.lfHeight = -lroundf(smallCapsSize);
-        HFONT hfont = CreateFontIndirect(&winFont);
-        m_smallCapsFontData =
-            new SimpleFontData(FontPlatformData(hfont, smallCapsSize), isCustomFont(), false);
-    }
-    return m_smallCapsFontData;
+    if (!m_derivedFontData)
+        m_derivedFontData = DerivedFontData::create(isCustomFont());
+    if (!m_derivedFontData->smallCaps)
+        m_derivedFontData->smallCaps = scaledFontData(fontDescription, .7);
+
+    return m_derivedFontData->smallCaps.get();
+}
+
+SimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
+{
+    if (!m_derivedFontData)
+        m_derivedFontData = DerivedFontData::create(isCustomFont());
+    if (!m_derivedFontData->emphasisMark)
+        m_derivedFontData->emphasisMark = scaledFontData(fontDescription, .5);
+
+    return m_derivedFontData->emphasisMark.get();
 }
 
 bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
diff --git a/WebCore/platform/graphics/chromium/SimpleFontDataLinux.cpp b/WebCore/platform/graphics/chromium/SimpleFontDataLinux.cpp
index c5190fc..2a197b5 100644
--- a/WebCore/platform/graphics/chromium/SimpleFontDataLinux.cpp
+++ b/WebCore/platform/graphics/chromium/SimpleFontDataLinux.cpp
@@ -48,6 +48,7 @@ namespace WebCore {
 
 // Smallcaps versions of fonts are 70% the size of the normal font.
 static const float smallCapsFraction = 0.7f;
+static const float emphasisMarkFraction = .5;
 // This is the largest VDMX table which we'll try to load and parse.
 static const size_t maxVDMXTableSize = 1024 * 1024;  // 1 MB
 
@@ -141,14 +142,30 @@ void SimpleFontData::platformDestroy()
 {
 }
 
+SimpleFontData* SimpleFontData::scaledFontData(const FontDescription& fontDescription, float scaleFactor) const
+{
+    const float scaledSize = lroundf(fontDescription.computedSize() * scaleFactor);
+    return new SimpleFontData(FontPlatformData(m_platformData, scaledSize), isCustomFont(), false);
+}
+
 SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
 {
-    if (!m_smallCapsFontData) {
-        const float smallCapsSize = lroundf(fontDescription.computedSize() * smallCapsFraction);
-        m_smallCapsFontData = new SimpleFontData(FontPlatformData(m_platformData, smallCapsSize), isCustomFont(), false);
-    }
+    if (!m_derivedFontData)
+        m_derivedFontData = DerivedFontData::create(isCustomFont());
+    if (!m_derivedFontData->smallCaps)
+        m_derivedFontData->smallCaps = scaledFontData(fontDescription, smallCapsFraction);
+
+    return m_derivedFontData->smallCaps.get();
+}
+
+SimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
+{
+    if (!m_derivedFontData)
+        m_derivedFontData = DerivedFontData::create(isCustomFont());
+    if (!m_derivedFontData->emphasisMark)
+        m_derivedFontData->emphasisMark = scaledFontData(fontDescription, emphasisMarkFraction);
 
-    return m_smallCapsFontData;
+    return m_derivedFontData->emphasisMark.get();
 }
 
 bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
diff --git a/WebCore/platform/graphics/efl/FontEfl.cpp b/WebCore/platform/graphics/efl/FontEfl.cpp
index 96d6a7b..d3ca183 100644
--- a/WebCore/platform/graphics/efl/FontEfl.cpp
+++ b/WebCore/platform/graphics/efl/FontEfl.cpp
@@ -40,6 +40,11 @@ void Font::drawComplexText(GraphicsContext*, const TextRun&, const FloatPoint&,
     notImplemented();
 }
 
+void Font::drawEmphasisMarksForComplexText(GraphicsContext* /* context */, const TextRun& /* run */, const AtomicString& /* mark */, const FloatPoint& /* point */, int /* from */, int /* to */) const
+{
+    notImplemented();
+}
+
 bool Font::canReturnFallbackFontsForComplexText()
 {
     return false;
diff --git a/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp b/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp
index cb096c3..97fd81a 100644
--- a/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp
+++ b/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp
@@ -79,16 +79,32 @@ void SimpleFontData::platformDestroy()
 {
 }
 
+SimpleFontData* SimpleFontData::scaledFontData(const FontDescription& fontDescription, float scaleFactor) const
+{
+    return new SimpleFontData(FontPlatformData(cairo_scaled_font_get_font_face(m_platformData.scaledFont()),
+        scaleFactor * fontDescription.computedSize(), m_platformData.syntheticBold(), m_platformData.syntheticOblique()),
+        isCustomFont(), false);
+}
+
 SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
 {
+    if (!m_derivedFontData)
+        m_derivedFontData = DerivedFontData::create(isCustomFont());
     // FIXME: I think we want to ask FontConfig for the right font again.
-    if (!m_smallCapsFontData)
-        m_smallCapsFontData = new SimpleFontData(
-            FontPlatformData(cairo_scaled_font_get_font_face(m_platformData.scaledFont()),
-            0.70f * fontDescription.computedSize(), m_platformData.syntheticBold(), m_platformData.syntheticOblique()),
-            isCustomFont(), false);
+    if (!m_derivedFontData->smallCaps)
+        m_derivedFontData->smallCaps = scaledFontData(fontDescription, .7);
+
+    return m_derivedFontData->smallCaps.get();
+}
+
+SimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
+{
+    if (!m_derivedFontData)
+        m_derivedFontData = DerivedFontData::create(isCustomFont());
+    if (!m_derivedFontData->emphasisMark)
+        m_derivedFontData->emphasisMark = scaledFontData(fontDescription, .5);
 
-    return m_smallCapsFontData;
+    return m_derivedFontData->emphasisMark.get();
 }
 
 bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
diff --git a/WebCore/platform/graphics/gtk/FontGtk.cpp b/WebCore/platform/graphics/gtk/FontGtk.cpp
index f6c5f2a..a0d5c62 100644
--- a/WebCore/platform/graphics/gtk/FontGtk.cpp
+++ b/WebCore/platform/graphics/gtk/FontGtk.cpp
@@ -36,6 +36,7 @@
 #include "CairoUtilities.h"
 #include "ContextShadow.h"
 #include "GraphicsContext.h"
+#include "NotImplemented.h"
 #include "SimpleFontData.h"
 #include <cairo.h>
 #include <gdk/gdk.h>
@@ -319,6 +320,11 @@ void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const F
     cairo_restore(cr);
 }
 
+void Font::drawEmphasisMarksForComplexText(GraphicsContext* /* context */, const TextRun& /* run */, const AtomicString& /* mark */, const FloatPoint& /* point */, int /* from */, int /* to */) const
+{
+    notImplemented();
+}
+
 // We should create the layout with our actual context but we can't access it from here.
 static PangoLayout* getDefaultPangoLayout(const TextRun& run)
 {
diff --git a/WebCore/platform/graphics/haiku/FontHaiku.cpp b/WebCore/platform/graphics/haiku/FontHaiku.cpp
index a991bfc..819fecb 100644
--- a/WebCore/platform/graphics/haiku/FontHaiku.cpp
+++ b/WebCore/platform/graphics/haiku/FontHaiku.cpp
@@ -93,6 +93,10 @@ void Font::drawComplexText(GraphicsContext* ctx, const TextRun& run, const Float
     notImplemented();
 }
 
+void Font::drawEmphasisMarksForComplexText(GraphicsContext* /* context */, const TextRun& /* run */, const AtomicString& /* mark */, const FloatPoint& /* point */, int /* from */, int /* to */) const
+{
+    notImplemented();
+}
 
 float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
 {
diff --git a/WebCore/platform/graphics/haiku/SimpleFontDataHaiku.cpp b/WebCore/platform/graphics/haiku/SimpleFontDataHaiku.cpp
index a960972..b1e7082 100644
--- a/WebCore/platform/graphics/haiku/SimpleFontDataHaiku.cpp
+++ b/WebCore/platform/graphics/haiku/SimpleFontDataHaiku.cpp
@@ -66,15 +66,32 @@ void SimpleFontData::platformDestroy()
 {
 }
 
+SimpleFontData* SimpleFontData::scaledFontData(const FontDescription& fontDescription, float scaleFactor) const
+{
+    FontDescription desc = FontDescription(fontDescription);
+    desc.setSpecifiedSize(scaleFactor * fontDescription.computedSize());
+    FontPlatformData fontPlatformData(desc, desc.family().family());
+    return new SimpleFontData(fontPlatformData, isCustomFont(), false);
+}
+
 SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
 {
-    if (!m_smallCapsFontData) {
-        FontDescription desc = FontDescription(fontDescription);
-        desc.setSpecifiedSize(0.70f * fontDescription.computedSize());
-        FontPlatformData fontPlatformData(desc, desc.family().family());
-        m_smallCapsFontData = new SimpleFontData(fontPlatformData, isCustomFont(), false);
-    }
-    return m_smallCapsFontData;
+    if (!m_derivedFontData)
+        m_derivedFontData = DerivedFontData::create(isCustomFont());
+    if (!m_derivedFontData->smallCaps)
+        m_derivedFontData->smallCaps = scaledFontData(fontDescription, .7);
+
+    return m_derivedFontData->smallCaps.get();
+}
+
+SimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
+{
+    if (!m_derivedFontData)
+        m_derivedFontData = DerivedFontData::create(isCustomFont());
+    if (!m_derivedFontData->emphasisMark)
+        m_derivedFontData->emphasisMark = scaledFontData(fontDescription, .5);
+
+    return m_derivedFontData->emphasisMark.get();
 }
 
 bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
diff --git a/WebCore/platform/graphics/mac/ComplexTextController.cpp b/WebCore/platform/graphics/mac/ComplexTextController.cpp
index d353d55..206fd5f 100644
--- a/WebCore/platform/graphics/mac/ComplexTextController.cpp
+++ b/WebCore/platform/graphics/mac/ComplexTextController.cpp
@@ -56,10 +56,11 @@ static inline CGFloat ceilCGFloat(CGFloat f)
     return static_cast<CGFloat>(ceil(f));
 }
 
-ComplexTextController::ComplexTextController(const Font* font, const TextRun& run, bool mayUseNaturalWritingDirection, HashSet<const SimpleFontData*>* fallbackFonts)
+ComplexTextController::ComplexTextController(const Font* font, const TextRun& run, bool mayUseNaturalWritingDirection, HashSet<const SimpleFontData*>* fallbackFonts, bool forTextEmphasis)
     : m_font(*font)
     , m_run(run)
     , m_mayUseNaturalWritingDirection(mayUseNaturalWritingDirection)
+    , m_forTextEmphasis(forTextEmphasis)
     , m_currentCharacter(0)
     , m_end(run.length())
     , m_totalWidth(0)
@@ -240,7 +241,7 @@ void ComplexTextController::collectComplexTextRuns()
                 nextGlyphData = m_font.glyphDataForCharacter(U16_GET_SUPPLEMENTARY(curr[-1], curr[0]), false);
             }
         } else
-            nextGlyphData = m_font.glyphDataForCharacter(*curr, false, forceSmallCaps);
+            nextGlyphData = m_font.glyphDataForCharacter(*curr, false, forceSmallCaps ? SmallCapsVariant : AutoVariant);
 
         if (!isSurrogate && m_font.isSmallCaps()) {
             nextIsSmallCaps = forceSmallCaps || (newC = u_toupper(c)) != c;
@@ -536,6 +537,10 @@ void ComplexTextController::adjustGlyphsAndAdvances()
             } else
                 widthSinceLastRounding += advance.width;
 
+            // FIXME: Combining marks should receive a text emphasis mark if they are combine with a space.
+            if (m_forTextEmphasis && (!Font::canReceiveTextEmphasis(ch) || (U_GET_GC_MASK(ch) & U_GC_M_MASK)))
+                glyph = 0;
+
             advance.height *= -1;
             m_adjustedAdvances.append(advance);
             m_adjustedGlyphs.append(glyph);
diff --git a/WebCore/platform/graphics/mac/ComplexTextController.h b/WebCore/platform/graphics/mac/ComplexTextController.h
index 85407c7..9cf80a6 100644
--- a/WebCore/platform/graphics/mac/ComplexTextController.h
+++ b/WebCore/platform/graphics/mac/ComplexTextController.h
@@ -47,7 +47,7 @@ class TextRun;
 // OS Versions >= 10.6, ATSUI is used otherwise.
 class ComplexTextController {
 public:
-    ComplexTextController(const Font*, const TextRun&, bool mayUseNaturalWritingDirection = false, HashSet<const SimpleFontData*>* fallbackFonts = 0);
+    ComplexTextController(const Font*, const TextRun&, bool mayUseNaturalWritingDirection = false, HashSet<const SimpleFontData*>* fallbackFonts = 0, bool forTextEmphasis = false);
 
     // Advance and emit glyphs up to the specified character.
     void advance(unsigned to, GlyphBuffer* = 0);
@@ -156,6 +156,7 @@ private:
     const Font& m_font;
     const TextRun& m_run;
     bool m_mayUseNaturalWritingDirection;
+    bool m_forTextEmphasis;
 
     Vector<UChar, 256> m_smallCapsBuffer;
 
diff --git a/WebCore/platform/graphics/mac/FontComplexTextMac.cpp b/WebCore/platform/graphics/mac/FontComplexTextMac.cpp
index 05eae03..ca006d9 100644
--- a/WebCore/platform/graphics/mac/FontComplexTextMac.cpp
+++ b/WebCore/platform/graphics/mac/FontComplexTextMac.cpp
@@ -55,34 +55,55 @@ FloatRect Font::selectionRectForComplexText(const TextRun& run, const FloatPoint
     return FloatRect(point.x() + floorf(beforeWidth), point.y(), roundf(afterWidth) - floorf(beforeWidth), h);
 }
 
-void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point,
-                           int from, int to) const
+float Font::getGlyphsAndAdvancesForComplexText(const TextRun& run, int from, int to, GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot forTextEmphasis) const
 {
-    // This glyph buffer holds our glyphs + advances + font data for each glyph.
-    GlyphBuffer glyphBuffer;
+    float initialAdvance;
 
-    float startX = point.x();
-    ComplexTextController controller(this, run);
+    ComplexTextController controller(this, run, false, 0, forTextEmphasis);
     controller.advance(from);
     float beforeWidth = controller.runWidthSoFar();
     controller.advance(to, &glyphBuffer);
-    
-    // We couldn't generate any glyphs for the run.  Give up.
+
     if (glyphBuffer.isEmpty())
-        return;
-    
+        return 0;
+
     float afterWidth = controller.runWidthSoFar();
 
     if (run.rtl()) {
-        startX += controller.totalWidth() + controller.finalRoundingWidth() - afterWidth;
+        initialAdvance = controller.totalWidth() + controller.finalRoundingWidth() - afterWidth;
         for (int i = 0, end = glyphBuffer.size() - 1; i < glyphBuffer.size() / 2; ++i, --end)
             glyphBuffer.swap(i, end);
     } else
-        startX += beforeWidth;
+        initialAdvance = beforeWidth;
+
+    return initialAdvance;
+}
+
+void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const
+{
+    // This glyph buffer holds our glyphs + advances + font data for each glyph.
+    GlyphBuffer glyphBuffer;
+
+    float startX = point.x() + getGlyphsAndAdvancesForComplexText(run, from, to, glyphBuffer);
+
+    // We couldn't generate any glyphs for the run.  Give up.
+    if (glyphBuffer.isEmpty())
+        return;
 
     // Draw the glyph buffer now at the starting point returned in startX.
     FloatPoint startPoint(startX, point.y());
-    drawGlyphBuffer(context, glyphBuffer, run, startPoint);
+    drawGlyphBuffer(context, glyphBuffer, startPoint);
+}
+
+void Font::drawEmphasisMarksForComplexText(GraphicsContext* context, const TextRun& run, const AtomicString& mark, const FloatPoint& point, int from, int to) const
+{
+    GlyphBuffer glyphBuffer;
+    float initialAdvance = getGlyphsAndAdvancesForComplexText(run, from, to, glyphBuffer, ForTextEmphasis);
+
+    if (glyphBuffer.isEmpty())
+        return;
+
+    drawEmphasisMarks(context, glyphBuffer, mark, FloatPoint(point.x() + initialAdvance, point.y()));
 }
 
 float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
diff --git a/WebCore/platform/graphics/mac/SimpleFontDataMac.mm b/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
index e1d3f43..e1322de 100644
--- a/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
+++ b/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
@@ -357,9 +357,13 @@ void SimpleFontData::platformCharWidthInit()
 
 void SimpleFontData::platformDestroy()
 {
-    if (m_smallCapsFontData && !isCustomFont()) {
-        fontCache()->releaseFontData(m_smallCapsFontData);
-        m_smallCapsFontData = 0;
+    if (!isCustomFont() && m_derivedFontData) {
+        // These come from the cache.
+        if (m_derivedFontData->smallCaps)
+            fontCache()->releaseFontData(m_derivedFontData->smallCaps.leakPtr());
+
+        if (m_derivedFontData->emphasisMark)
+            fontCache()->releaseFontData(m_derivedFontData->emphasisMark.leakPtr());
     }
 
 #ifdef BUILDING_ON_TIGER
@@ -373,41 +377,60 @@ void SimpleFontData::platformDestroy()
 #endif
 }
 
-SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
+SimpleFontData* SimpleFontData::scaledFontData(const FontDescription& fontDescription, float scaleFactor) const
 {
-    if (!m_smallCapsFontData) {
-        if (isCustomFont()) {
-            FontPlatformData smallCapsFontData(m_platformData);
-            smallCapsFontData.m_size = smallCapsFontData.m_size * smallCapsFontSizeMultiplier;
-            m_smallCapsFontData = new SimpleFontData(smallCapsFontData, true, false);
-        } else {
-            BEGIN_BLOCK_OBJC_EXCEPTIONS;
-            float size = m_platformData.size() * smallCapsFontSizeMultiplier;
-            FontPlatformData smallCapsFont([[NSFontManager sharedFontManager] convertFont:m_platformData.font() toSize:size], size);
-            
-            // AppKit resets the type information (screen/printer) when you convert a font to a different size.
-            // We have to fix up the font that we're handed back.
-            smallCapsFont.setFont(fontDescription.usePrinterFont() ? [smallCapsFont.font() printerFont] : [smallCapsFont.font() screenFont]);
-
-            if (smallCapsFont.font()) {
-                NSFontManager *fontManager = [NSFontManager sharedFontManager];
-                NSFontTraitMask fontTraits = [fontManager traitsOfFont:m_platformData.font()];
-
-                if (m_platformData.m_syntheticBold)
-                    fontTraits |= NSBoldFontMask;
-                if (m_platformData.m_syntheticOblique)
-                    fontTraits |= NSItalicFontMask;
-
-                NSFontTraitMask smallCapsFontTraits = [fontManager traitsOfFont:smallCapsFont.font()];
-                smallCapsFont.m_syntheticBold = (fontTraits & NSBoldFontMask) && !(smallCapsFontTraits & NSBoldFontMask);
-                smallCapsFont.m_syntheticOblique = (fontTraits & NSItalicFontMask) && !(smallCapsFontTraits & NSItalicFontMask);
-
-                m_smallCapsFontData = fontCache()->getCachedFontData(&smallCapsFont);
-            }
-            END_BLOCK_OBJC_EXCEPTIONS;
-        }
+    if (isCustomFont()) {
+        FontPlatformData scaledFontData(m_platformData);
+        scaledFontData.m_size = scaledFontData.m_size * scaleFactor;
+        return new SimpleFontData(scaledFontData, true, false);
+    }
+
+    BEGIN_BLOCK_OBJC_EXCEPTIONS;
+    float size = m_platformData.size() * scaleFactor;
+    FontPlatformData scaledFontData([[NSFontManager sharedFontManager] convertFont:m_platformData.font() toSize:size], size);
+
+    // AppKit resets the type information (screen/printer) when you convert a font to a different size.
+    // We have to fix up the font that we're handed back.
+    scaledFontData.setFont(fontDescription.usePrinterFont() ? [scaledFontData.font() printerFont] : [scaledFontData.font() screenFont]);
+
+    if (scaledFontData.font()) {
+        NSFontManager *fontManager = [NSFontManager sharedFontManager];
+        NSFontTraitMask fontTraits = [fontManager traitsOfFont:m_platformData.font()];
+
+        if (m_platformData.m_syntheticBold)
+            fontTraits |= NSBoldFontMask;
+        if (m_platformData.m_syntheticOblique)
+            fontTraits |= NSItalicFontMask;
+
+        NSFontTraitMask scaledFontTraits = [fontManager traitsOfFont:scaledFontData.font()];
+        scaledFontData.m_syntheticBold = (fontTraits & NSBoldFontMask) && !(scaledFontTraits & NSBoldFontMask);
+        scaledFontData.m_syntheticOblique = (fontTraits & NSItalicFontMask) && !(scaledFontTraits & NSItalicFontMask);
+
+        return fontCache()->getCachedFontData(&scaledFontData);
     }
-    return m_smallCapsFontData;
+    END_BLOCK_OBJC_EXCEPTIONS;
+
+    return 0;
+}
+
+SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
+{
+    if (!m_derivedFontData)
+        m_derivedFontData = DerivedFontData::create(isCustomFont());
+    if (!m_derivedFontData->smallCaps)
+        m_derivedFontData->smallCaps = scaledFontData(fontDescription, smallCapsFontSizeMultiplier);
+
+    return m_derivedFontData->smallCaps.get();
+}
+
+SimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
+{
+    if (!m_derivedFontData)
+        m_derivedFontData = DerivedFontData::create(isCustomFont());
+    if (!m_derivedFontData->emphasisMark)
+        m_derivedFontData->emphasisMark = scaledFontData(fontDescription, .5);
+
+    return m_derivedFontData->emphasisMark.get();
 }
 
 bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
diff --git a/WebCore/platform/graphics/pango/SimpleFontDataPango.cpp b/WebCore/platform/graphics/pango/SimpleFontDataPango.cpp
index bdfe237..d0bf836 100644
--- a/WebCore/platform/graphics/pango/SimpleFontDataPango.cpp
+++ b/WebCore/platform/graphics/pango/SimpleFontDataPango.cpp
@@ -76,19 +76,34 @@ void SimpleFontData::platformCharWidthInit()
 
 void SimpleFontData::platformDestroy()
 {
-    delete m_smallCapsFontData;
-    m_smallCapsFontData = 0;
+}
+
+SimpleFontData* SimpleFontData::scaledFontData(const FontDescription& fontDescription, float scaleFactor) const
+{
+    FontDescription desc = FontDescription(fontDescription);
+    desc.setSpecifiedSize(scaleFactor * fontDescription.computedSize());
+    FontPlatformData platformData(desc, desc.family().family());
+    return new SimpleFontData(platformData);
 }
 
 SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
 {
-    if (!m_smallCapsFontData) {
-        FontDescription desc = FontDescription(fontDescription);
-        desc.setSpecifiedSize(0.70f * fontDescription.computedSize());
-        FontPlatformData platformData(desc, desc.family().family());
-        m_smallCapsFontData = new SimpleFontData(platformData);
-    }
-    return m_smallCapsFontData;
+    if (!m_derivedFontData)
+        m_derivedFontData = DerivedFontData::create(isCustomFont());
+    if (!m_derivedFontData->smallCaps)
+        m_derivedFontData->smallCaps = scaledFontData(fontDescription, .7);
+
+    return m_derivedFontData->smallCaps.get();
+}
+
+SimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
+{
+    if (!m_derivedFontData)
+        m_derivedFontData = DerivedFontData::create(isCustomFont());
+    if (!m_derivedFontData->emphasisMark)
+        m_derivedFontData->emphasisMark = scaledFontData(fontDescription, .5);
+
+    return m_derivedFontData->emphasisMark.get();
 }
 
 bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
diff --git a/WebCore/platform/graphics/qt/FontQt.cpp b/WebCore/platform/graphics/qt/FontQt.cpp
index c2810de..e89d330 100644
--- a/WebCore/platform/graphics/qt/FontQt.cpp
+++ b/WebCore/platform/graphics/qt/FontQt.cpp
@@ -29,6 +29,7 @@
 #include "FontSelector.h"
 #include "Gradient.h"
 #include "GraphicsContext.h"
+#include "NotImplemented.h"
 #include "Pattern.h"
 
 #include <QBrush>
@@ -260,6 +261,34 @@ void Font::drawComplexText(GraphicsContext* ctx, const TextRun& run, const Float
     drawTextCommon(ctx, run, point, from, to, font(), /* isComplexText = */true);
 }
 
+int Font::emphasisMarkAscent(const AtomicString&) const
+{
+    notImplemented();
+    return 0;
+}
+
+int Font::emphasisMarkDescent(const AtomicString&) const
+{
+    notImplemented();
+    return 0;
+}
+
+int Font::emphasisMarkHeight(const AtomicString&) const
+{
+    notImplemented();
+    return 0;
+}
+
+void Font::drawEmphasisMarksForSimpleText(GraphicsContext* /* context */, const TextRun& /* run */, const AtomicString& /* mark */, const FloatPoint& /* point */, int /* from */, int /* to */) const
+{
+    notImplemented();
+}
+
+void Font::drawEmphasisMarksForComplexText(GraphicsContext* /* context */, const TextRun& /* run */, const AtomicString& /* mark */, const FloatPoint& /* point */, int /* from */, int /* to */) const
+{
+    notImplemented();
+}
+
 float Font::floatWidthForSimpleText(const TextRun& run, GlyphBuffer* glyphBuffer, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
 {
     if (!primaryFont()->platformData().size())
diff --git a/WebCore/platform/graphics/win/FontWin.cpp b/WebCore/platform/graphics/win/FontWin.cpp
index 97971dc..2170954 100644
--- a/WebCore/platform/graphics/win/FontWin.cpp
+++ b/WebCore/platform/graphics/win/FontWin.cpp
@@ -30,6 +30,7 @@
 #include "GlyphBuffer.h"
 #include "GraphicsContext.h"
 #include "IntRect.h"
+#include "Logging.h"
 #include "SimpleFontData.h"
 #include "UniscribeController.h"
 #include <wtf/MathExtras.h>
@@ -62,33 +63,57 @@ FloatRect Font::selectionRectForComplexText(const TextRun& run, const FloatPoint
     return FloatRect(point.x() + floorf(beforeWidth), point.y(), roundf(afterWidth) - floorf(beforeWidth), h);
 }
 
-void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point,
-                           int from, int to) const
+float Font::getGlyphsAndAdvancesForComplexText(const TextRun& run, int from, int to, GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot forTextEmphasis) const
 {
-    // This glyph buffer holds our glyphs + advances + font data for each glyph.
-    GlyphBuffer glyphBuffer;
+    if (forTextEmphasis) {
+        // FIXME: Add forTextEmphasis paremeter to UniscribeController and use it.
+        LOG_ERROR("Not implemented for text emphasis.");
+        return 0;
+    }
 
-    float startX = point.x();
     UniscribeController controller(this, run);
     controller.advance(from);
     float beforeWidth = controller.runWidthSoFar();
     controller.advance(to, &glyphBuffer);
-    
-    // We couldn't generate any glyphs for the run.  Give up.
+
     if (glyphBuffer.isEmpty())
-        return;
-    
+        return 0;
+
     float afterWidth = controller.runWidthSoFar();
 
     if (run.rtl()) {
         controller.advance(run.length());
-        startX += controller.runWidthSoFar() - afterWidth;
-    } else
-        startX += beforeWidth;
+        return controller.runWidthSoFar() - afterWidth;
+    }
+    return beforeWidth;
+}
+
+void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point,
+                           int from, int to) const
+{
+    // This glyph buffer holds our glyphs + advances + font data for each glyph.
+    GlyphBuffer glyphBuffer;
+
+    float startX = point.x() + getGlyphsAndAdvancesForComplexText(run, from, to, glyphBuffer);
+
+    // We couldn't generate any glyphs for the run.  Give up.
+    if (glyphBuffer.isEmpty())
+        return;
 
     // Draw the glyph buffer now at the starting point returned in startX.
     FloatPoint startPoint(startX, point.y());
-    drawGlyphBuffer(context, glyphBuffer, run, startPoint);
+    drawGlyphBuffer(context, glyphBuffer, startPoint);
+}
+
+void Font::drawEmphasisMarksForComplexText(GraphicsContext* context, const TextRun& run, const AtomicString& mark, const FloatPoint& point, int from, int to) const
+{
+    GlyphBuffer glyphBuffer;
+    float initialAdvance = getGlyphsAndAdvancesForComplexText(run, from, to, glyphBuffer, ForTextEmphasis);
+
+    if (glyphBuffer.isEmpty())
+        return;
+
+    drawEmphasisMarks(context, glyphBuffer, mark, FloatPoint(point.x() + initialAdvance, point.y()));
 }
 
 float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
diff --git a/WebCore/platform/graphics/win/SimpleFontDataWin.cpp b/WebCore/platform/graphics/win/SimpleFontDataWin.cpp
index 6d1d777..60afe6a 100644
--- a/WebCore/platform/graphics/win/SimpleFontDataWin.cpp
+++ b/WebCore/platform/graphics/win/SimpleFontDataWin.cpp
@@ -110,24 +110,40 @@ void SimpleFontData::platformDestroy()
     delete m_scriptFontProperties;
 }
 
-SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
+SimpleFontData* SimpleFontData::scaledFontData(const FontDescription& fontDescription, float scaleFactor) const
 {
-    if (!m_smallCapsFontData) {
-        float smallCapsHeight = cSmallCapsFontSizeMultiplier * m_platformData.size();
+        float scaledSize = scaleFactor * m_platformData.size();
         if (isCustomFont()) {
-            FontPlatformData smallCapsFontData(m_platformData);
-            smallCapsFontData.setSize(smallCapsHeight);
-            m_smallCapsFontData = new SimpleFontData(smallCapsFontData, true, false);
-        } else {
-            LOGFONT winfont;
-            GetObject(m_platformData.hfont(), sizeof(LOGFONT), &winfont);
-            winfont.lfHeight = -lroundf(smallCapsHeight * (m_platformData.useGDI() ? 1 : 32));
-            HFONT hfont = CreateFontIndirect(&winfont);
-            m_smallCapsFontData = new SimpleFontData(FontPlatformData(hfont, smallCapsHeight, m_platformData.syntheticBold(), m_platformData.syntheticOblique(), m_platformData.useGDI()),
-                                                     isCustomFont(), false);
+            FontPlatformData scaledFont(m_platformData);
+            scaledFont.setSize(scaledSize);
+            return new SimpleFontData(scaledFont, true, false);
         }
-    }
-    return m_smallCapsFontData;
+
+        LOGFONT winfont;
+        GetObject(m_platformData.hfont(), sizeof(LOGFONT), &winfont);
+        winfont.lfHeight = -lroundf(scaledSize * (m_platformData.useGDI() ? 1 : 32));
+        HFONT hfont = CreateFontIndirect(&winfont);
+        return new SimpleFontData(FontPlatformData(hfont, scaledSize, m_platformData.syntheticBold(), m_platformData.syntheticOblique(), m_platformData.useGDI()), isCustomFont(), false);
+}
+
+SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
+{
+    if (!m_derivedFontData)
+        m_derivedFontData = DerivedFontData::create(isCustomFont());
+    if (!m_derivedFontData->smallCaps)
+        m_derivedFontData->smallCaps = scaledFontData(fontDescription, cSmallCapsFontSizeMultiplier);
+
+    return m_derivedFontData->smallCaps.get();
+}
+
+SimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
+{
+    if (!m_derivedFontData)
+        m_derivedFontData = DerivedFontData::create(isCustomFont());
+    if (!m_derivedFontData->emphasisMark)
+        m_derivedFontData->emphasisMark = scaledFontData(fontDescription, .5);
+
+    return m_derivedFontData->emphasisMark.get();
 }
 
 bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
diff --git a/WebCore/platform/graphics/win/UniscribeController.cpp b/WebCore/platform/graphics/win/UniscribeController.cpp
index d0acac2..ab32150 100644
--- a/WebCore/platform/graphics/win/UniscribeController.cpp
+++ b/WebCore/platform/graphics/win/UniscribeController.cpp
@@ -145,7 +145,7 @@ void UniscribeController::advance(unsigned offset, GlyphBuffer* glyphBuffer)
         UChar c = *curr;
 
         bool forceSmallCaps = isSmallCaps && (U_GET_GC_MASK(c) & U_GC_M_MASK);
-        nextFontData = m_font.glyphDataForCharacter(*curr, false, forceSmallCaps).fontData;
+        nextFontData = m_font.glyphDataForCharacter(*curr, false, forceSmallCaps ? SmallCapsVariant : AutoVariant).fontData;
         if (m_font.isSmallCaps()) {
             nextIsSmallCaps = forceSmallCaps || (newC = u_toupper(c)) != c;
             if (nextIsSmallCaps)
diff --git a/WebCore/platform/graphics/wince/FontWinCE.cpp b/WebCore/platform/graphics/wince/FontWinCE.cpp
index e2ff067..d636517 100644
--- a/WebCore/platform/graphics/wince/FontWinCE.cpp
+++ b/WebCore/platform/graphics/wince/FontWinCE.cpp
@@ -235,6 +235,11 @@ void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const F
     }
 }
 
+void Font::drawEmphasisMarksForComplexText(GraphicsContext* /* context */, const TextRun& /* run */, const AtomicString& /* mark */, const FloatPoint& /* point */, int /* from */, int /* to */) const
+{
+    notImplemented();
+}
+
 float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
 {
     TextRunComponents components;
diff --git a/WebCore/platform/graphics/wince/SimpleFontDataWinCE.cpp b/WebCore/platform/graphics/wince/SimpleFontDataWinCE.cpp
index c8c5474..27a021e 100644
--- a/WebCore/platform/graphics/wince/SimpleFontDataWinCE.cpp
+++ b/WebCore/platform/graphics/wince/SimpleFontDataWinCE.cpp
@@ -60,22 +60,36 @@ void SimpleFontData::platformInit()
 
 void SimpleFontData::platformDestroy()
 {
-    delete m_smallCapsFontData;
-    m_smallCapsFontData = 0;
+}
+
+SimpleFontData* SimpleFontData::scaledFontData(const FontDescription& fontDescription, float scaleFactor) const
+{
+    FontDescription fontDesc(fontDescription);
+    fontDesc.setComputedSize(lroundf(scaleFactor * fontDesc.computedSize()));
+    fontDesc.setSpecifiedSize(lroundf(scaleFactor * fontDesc.specifiedSize()));
+    fontDesc.setKeywordSize(lroundf(scaleFactor * fontDesc.keywordSize()));
+    FontPlatformData* result = fontCache()->getCachedFontPlatformData(fontDesc, m_platformData.family());
+    return result ? new SimpleFontData(*result) : 0;
 }
 
 SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
 {
-    if (!m_smallCapsFontData) {
-        FontDescription fontDesc(fontDescription);
-        fontDesc.setComputedSize(lroundf(0.70f * fontDesc.computedSize()));
-        fontDesc.setSpecifiedSize(lroundf(0.70f * fontDesc.specifiedSize()));
-        fontDesc.setKeywordSize(lroundf(0.70f * fontDesc.keywordSize()));
-        FontPlatformData* result = fontCache()->getCachedFontPlatformData(fontDesc, m_platformData.family());
-        if (result)
-            m_smallCapsFontData = new SimpleFontData(*result);
-    }
-    return m_smallCapsFontData;
+    if (!m_derivedFontData)
+        m_derivedFontData = DerivedFontData::create(isCustomFont());
+    if (!m_derivedFontData->smallCaps)
+        m_derivedFontData->smallCaps = scaledFontData(fontDescription, .7);
+
+    return m_derivedFontData->smallCaps.get();
+}
+
+SimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
+{
+    if (!m_derivedFontData)
+        m_derivedFontData = DerivedFontData::create(isCustomFont());
+    if (!m_derivedFontData->emphasisMark)
+        m_derivedFontData->emphasisMark = scaledFontData(fontDescription, .5);
+
+    return m_derivedFontData->emphasisMark.get();
 }
 
 DWORD getKnownFontCodePages(const wchar_t* family);
diff --git a/WebCore/platform/graphics/wx/FontWx.cpp b/WebCore/platform/graphics/wx/FontWx.cpp
index cc45ab0..c01e249 100644
--- a/WebCore/platform/graphics/wx/FontWx.cpp
+++ b/WebCore/platform/graphics/wx/FontWx.cpp
@@ -98,6 +98,14 @@ FloatRect Font::selectionRectForComplexText(const TextRun& run, const FloatPoint
 #endif
 }
 
+float Font::getGlyphsAndAdvancesForComplexText(const TextRun& /* run */, int /* from */, int /* to */, GlyphBuffer& /* glyphBuffer */, ForTextEmphasisOrNot /* forTextEmphasis */) const
+{
+    // FIXME: Implement this by moving most of the drawComplexText() implementation in here. Set up the
+    // ComplexTextController according to forTextEmphasis.
+    notImplemented();
+    return 0;
+}
+
 void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const
 {
 #if OS(WINDOWS) || OS(DARWIN)
@@ -130,12 +138,22 @@ void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const F
 
     // Draw the glyph buffer now at the starting point returned in startX.
     FloatPoint startPoint(startX, point.y());
-    drawGlyphBuffer(context, glyphBuffer, run, startPoint);
+    drawGlyphBuffer(context, glyphBuffer, startPoint);
 #else
     notImplemented();
 #endif
 }
 
+void Font::drawEmphasisMarksForComplexText(GraphicsContext* context, const TextRun& run, const AtomicString& mark, const FloatPoint& point, int from, int to) const
+{
+    GlyphBuffer glyphBuffer;
+    float initialAdvance = getGlyphsAndAdvancesForComplexText(run, from, to, glyphBuffer, ForTextEmphasis);
+
+    if (glyphBuffer.isEmpty())
+        return;
+
+    drawEmphasisMarks(context, glyphBuffer, mark, FloatPoint(point.x() + initialAdvance, point.y()));
+}
 
 float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow*) const
 {
diff --git a/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp b/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp
index 96129f9..0e24bfc 100644
--- a/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp
+++ b/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp
@@ -90,15 +90,32 @@ void SimpleFontData::platformDestroy()
 #endif
 }
 
+SimpleFontData* SimpleFontData::scaledFontData(const FontDescription& fontDescription, float scaleFactor) const
+{
+    FontDescription desc = FontDescription(fontDescription);
+    desc.setSpecifiedSize(scaleFactor * fontDescription.computedSize());
+    FontPlatformData platformData(desc, desc.family().family());
+    return new SimpleFontData(platformData, isCustomFont(), false);
+}
+
 SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
 {
-    if (!m_smallCapsFontData){
-        FontDescription desc = FontDescription(fontDescription);
-        desc.setSpecifiedSize(0.70f * fontDescription.computedSize());
-        FontPlatformData platformData(desc, desc.family().family());
-        m_smallCapsFontData = new SimpleFontData(platformData, isCustomFont(), false);
-    }
-    return m_smallCapsFontData;
+    if (!m_derivedFontData)
+        m_derivedFontData = DerivedFontData::create(isCustomFont());
+    if (!m_derivedFontData->smallCaps)
+        m_derivedFontData->smallCaps = scaledFontData(fontDescription, .7);
+
+    return m_derivedFontData->smallCaps.get();
+}
+
+SimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
+{
+    if (!m_derivedFontData)
+        m_derivedFontData = DerivedFontData::create(isCustomFont());
+    if (!m_derivedFontData->emphasisMark)
+        m_derivedFontData->emphasisMark = scaledFontData(fontDescription, .5);
+
+    return m_derivedFontData->emphasisMark.get();
 }
 
 bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
diff --git a/WebCore/platform/text/CharacterNames.h b/WebCore/platform/text/CharacterNames.h
index b05b09d..c4b496e 100644
--- a/WebCore/platform/text/CharacterNames.h
+++ b/WebCore/platform/text/CharacterNames.h
@@ -32,9 +32,11 @@ namespace WebCore {
 
 // Names here are taken from the Unicode standard.
 
-// Note, these are UChar constants, not UChar32, which makes them
+// Most of these are UChar constants, not UChar32, which makes them
 // more convenient for WebCore code that mostly uses UTF-16.
 
+const UChar32 aegeanWordSeparatorLine = 0x10100;
+const UChar32 aegeanWordSeparatorDot = 0x10101;
 const UChar blackCircle = 0x25CF;
 const UChar blackSquare = 0x25A0;
 const UChar blackUpPointingTriangle = 0x25B2;
@@ -42,6 +44,7 @@ const UChar bullet = 0x2022;
 const UChar bullseye = 0x25CE;
 const UChar carriageReturn = 0x000D;
 const UChar ethiopicPrefaceColon = 0x1366;
+const UChar ethiopicWordspace = 0x1361;
 const UChar fisheye = 0x25C9;
 const UChar hebrewPunctuationGeresh = 0x05F3;
 const UChar hebrewPunctuationGershayim = 0x05F4;
@@ -70,6 +73,9 @@ const UChar rightToLeftOverride = 0x202E;
 const UChar sesameDot = 0xFE45;
 const UChar softHyphen = 0x00AD;
 const UChar space = 0x0020;
+const UChar tibetanMarkIntersyllabicTsheg = 0x0F0B;
+const UChar tibetanMarkDelimiterTshegBstar = 0x0F0C;
+const UChar32 ugariticWordDivider = 0x1039F;
 const UChar whiteBullet = 0x25E6;
 const UChar whiteCircle = 0x25CB;
 const UChar whiteSesameDot = 0xFE46;

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list