diff options
Diffstat (limited to 'src/3rdparty/webkit/WebCore/platform/graphics')
16 files changed, 452 insertions, 227 deletions
diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/Font.cpp b/src/3rdparty/webkit/WebCore/platform/graphics/Font.cpp index 3d3ffe3..8e132e1 100644 --- a/src/3rdparty/webkit/WebCore/platform/graphics/Font.cpp +++ b/src/3rdparty/webkit/WebCore/platform/graphics/Font.cpp @@ -38,7 +38,6 @@ using namespace Unicode; namespace WebCore { -#if USE(FONT_FAST_PATH) const uint8_t Font::gRoundingHackCharacterTable[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 /*\t*/, 1 /*\n*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 /*space*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 /*-*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 /*?*/, @@ -51,7 +50,6 @@ const uint8_t Font::gRoundingHackCharacterTable[256] = { }; Font::CodePath Font::s_codePath = Auto; -#endif // ============================================================================================ // Font Implementation (Cross-Platform Portion) @@ -174,31 +172,28 @@ void Font::drawText(GraphicsContext* context, const TextRun& run, const FloatPoi } #endif -#if USE(FONT_FAST_PATH) - if (canUseGlyphCache(run)) + if (codePath(run) != Complex) return drawSimpleText(context, run, point, from, to); -#endif return drawComplexText(context, run, point, from, to); } -float Font::floatWidth(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts) const +float Font::floatWidth(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const { #if ENABLE(SVG_FONTS) if (primaryFont()->isSVGFont()) return floatWidthUsingSVGFont(run); #endif -#if USE(FONT_FAST_PATH) - if (canUseGlyphCache(run)) { + CodePath codePathToUse = codePath(run); + if (codePathToUse != Complex) { // If the complex text implementation cannot return fallback fonts, avoid // returning them for simple text as well. static bool returnFallbackFonts = canReturnFallbackFontsForComplexText(); - return floatWidthForSimpleText(run, 0, returnFallbackFonts ? fallbackFonts : 0); + return floatWidthForSimpleText(run, 0, returnFallbackFonts ? fallbackFonts : 0, codePathToUse == SimpleWithGlyphOverflow ? glyphOverflow : 0); } -#endif - return floatWidthForComplexText(run, fallbackFonts); + return floatWidthForComplexText(run, fallbackFonts, glyphOverflow); } float Font::floatWidth(const TextRun& run, int extraCharsAvailable, int& charsConsumed, String& glyphName) const @@ -213,10 +208,8 @@ float Font::floatWidth(const TextRun& run, int extraCharsAvailable, int& charsCo charsConsumed = run.length(); glyphName = ""; -#if USE(FONT_FAST_PATH) - if (canUseGlyphCache(run)) + if (codePath(run) != Complex) return floatWidthForSimpleText(run, 0); -#endif return floatWidthForComplexText(run); } @@ -230,10 +223,8 @@ FloatRect Font::selectionRectForText(const TextRun& run, const IntPoint& point, to = (to == -1 ? run.length() : to); -#if USE(FONT_FAST_PATH) - if (canUseGlyphCache(run)) + if (codePath(run) != Complex) return selectionRectForSimpleText(run, point, h, from, to); -#endif return selectionRectForComplexText(run, point, h, from, to); } @@ -245,10 +236,8 @@ int Font::offsetForPosition(const TextRun& run, int x, bool includePartialGlyphs return offsetForPositionForTextUsingSVGFont(run, x, includePartialGlyphs); #endif -#if USE(FONT_FAST_PATH) - if (canUseGlyphCache(run)) + if (codePath(run) != Complex) return offsetForPositionForSimpleText(run, x, includePartialGlyphs); -#endif return offsetForPositionForComplexText(run, x, includePartialGlyphs); } @@ -295,4 +284,79 @@ bool Font::shouldUseSmoothing() return shouldUseFontSmoothing; } +void Font::setCodePath(CodePath p) +{ + s_codePath = p; +} + +Font::CodePath Font::codePath() +{ + return s_codePath; +} + +Font::CodePath Font::codePath(const TextRun& run) const +{ + if (s_codePath != Auto) + return s_codePath; + +#if PLATFORM(QT) + if (run.padding() || run.rtl() || isSmallCaps() || wordSpacing() || letterSpacing()) + return Complex; +#endif + + // Start from 0 since drawing and highlighting also measure the characters before run->from + for (int i = 0; i < run.length(); i++) { + const UChar c = run[i]; + if (c < 0x300) // U+0300 through U+036F Combining diacritical marks + continue; + if (c <= 0x36F) + return Complex; + + if (c < 0x0591 || c == 0x05BE) // U+0591 through U+05CF excluding U+05BE Hebrew combining marks, Hebrew punctuation Paseq, Sof Pasuq and Nun Hafukha + continue; + if (c <= 0x05CF) + return Complex; + + if (c < 0x0600) // U+0600 through U+1059 Arabic, Syriac, Thaana, Devanagari, Bengali, Gurmukhi, Gujarati, Oriya, Tamil, Telugu, Kannada, Malayalam, Sinhala, Thai, Lao, Tibetan, Myanmar + continue; + if (c <= 0x1059) + return Complex; + + if (c < 0x1100) // U+1100 through U+11FF Hangul Jamo (only Ancient Korean should be left here if you precompose; Modern Korean will be precomposed as a result of step A) + continue; + if (c <= 0x11FF) + return Complex; + + if (c < 0x1780) // U+1780 through U+18AF Khmer, Mongolian + continue; + if (c <= 0x18AF) + return Complex; + + if (c < 0x1900) // U+1900 through U+194F Limbu (Unicode 4.0) + continue; + if (c <= 0x194F) + return Complex; + + if (c < 0x1E00) // U+1E00 through U+2000 characters with diacritics and stacked diacritics + continue; + if (c <= 0x2000) + return SimpleWithGlyphOverflow; + + if (c < 0x20D0) // U+20D0 through U+20FF Combining marks for symbols + continue; + if (c <= 0x20FF) + return Complex; + + if (c < 0xFE20) // U+FE20 through U+FE2F Combining half marks + continue; + if (c <= 0xFE2F) + return Complex; + } + + if (typesettingFeatures()) + return Complex; + + return Simple; +} + } diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/Font.h b/src/3rdparty/webkit/WebCore/platform/graphics/Font.h index 3c07be7..772ad93 100644 --- a/src/3rdparty/webkit/WebCore/platform/graphics/Font.h +++ b/src/3rdparty/webkit/WebCore/platform/graphics/Font.h @@ -56,6 +56,21 @@ struct GlyphData; const unsigned defaultUnitsPerEm = 1000; +struct GlyphOverflow { + GlyphOverflow() + : left(0) + , right(0) + , top(0) + , bottom(0) + { + } + + int left; + int right; + int top; + int bottom; +}; + class Font { public: Font(); @@ -81,8 +96,8 @@ public: void drawText(GraphicsContext*, const TextRun&, const FloatPoint&, int from = 0, int to = -1) const; - int width(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts = 0) const { return lroundf(floatWidth(run, fallbackFonts)); } - float floatWidth(const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0) 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; float floatWidth(const TextRun& run, int extraCharsAvailable, int& charsConsumed, String& glyphName) const; int offsetForPosition(const TextRun&, int position, bool includePartialGlyphs) const; @@ -137,6 +152,8 @@ public: static void setShouldUseSmoothing(bool); static bool shouldUseSmoothing(); + enum CodePath { Auto, Simple, Complex, SimpleWithGlyphOverflow }; + private: #if ENABLE(SVG_FONTS) void drawTextUsingSVGFont(GraphicsContext*, const TextRun&, const FloatPoint&, int from, int to) const; @@ -146,20 +163,18 @@ private: int offsetForPositionForTextUsingSVGFont(const TextRun&, int position, bool includePartialGlyphs) const; #endif -#if USE(FONT_FAST_PATH) - bool canUseGlyphCache(const TextRun&) const; void drawSimpleText(GraphicsContext*, const TextRun&, 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; - float floatWidthForSimpleText(const TextRun&, GlyphBuffer*, HashSet<const SimpleFontData*>* fallbackFonts = 0) const; + float floatWidthForSimpleText(const TextRun&, GlyphBuffer*, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const; int offsetForPositionForSimpleText(const TextRun&, int position, bool includePartialGlyphs) const; FloatRect selectionRectForSimpleText(const TextRun&, const IntPoint&, int h, int from, int to) const; static bool canReturnFallbackFontsForComplexText(); -#endif + CodePath codePath(const TextRun&) const; void drawComplexText(GraphicsContext*, const TextRun&, const FloatPoint&, int from, int to) const; - float floatWidthForComplexText(const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0) const; + float floatWidthForComplexText(const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const; int offsetForPositionForComplexText(const TextRun&, int position, bool includePartialGlyphs) const; FloatRect selectionRectForComplexText(const TextRun&, const IntPoint&, int h, int from, int to) const; @@ -167,8 +182,6 @@ private: public: // Useful for debugging the different font rendering code paths. -#if USE(FONT_FAST_PATH) - enum CodePath { Auto, Simple, Complex }; static void setCodePath(CodePath); static CodePath codePath(); static CodePath s_codePath; @@ -178,7 +191,6 @@ public: { return (((c & ~0xFF) == 0 && gRoundingHackCharacterTable[c])); } -#endif FontSelector* fontSelector() const; static bool treatAsSpace(UChar c) { return c == ' ' || c == '\t' || c == '\n' || c == 0x00A0; } diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/FontFastPath.cpp b/src/3rdparty/webkit/WebCore/platform/graphics/FontFastPath.cpp index 428e85e..b863e83 100644 --- a/src/3rdparty/webkit/WebCore/platform/graphics/FontFastPath.cpp +++ b/src/3rdparty/webkit/WebCore/platform/graphics/FontFastPath.cpp @@ -24,17 +24,17 @@ #include "Font.h" #include "CharacterNames.h" +#include "FloatRect.h" #include "FontCache.h" #include "FontFallbackList.h" -#include "FloatRect.h" #include "GlyphBuffer.h" #include "GlyphPageTreeNode.h" #include "IntPoint.h" #include "SimpleFontData.h" #include "WidthIterator.h" -#include <wtf/unicode/Unicode.h> #include <wtf/MathExtras.h> +#include <wtf/unicode/Unicode.h> using namespace WTF; using namespace Unicode; @@ -180,78 +180,6 @@ GlyphData Font::glyphDataForCharacter(UChar32 c, bool mirror, bool forceSmallCap return data; } -void Font::setCodePath(CodePath p) -{ - s_codePath = p; -} - -Font::CodePath Font::codePath() -{ - return s_codePath; -} - -bool Font::canUseGlyphCache(const TextRun& run) const -{ - switch (s_codePath) { - case Auto: - break; - case Simple: - return true; - case Complex: - return false; - } - - // Start from 0 since drawing and highlighting also measure the characters before run->from - for (int i = 0; i < run.length(); i++) { - const UChar c = run[i]; - if (c < 0x300) // U+0300 through U+036F Combining diacritical marks - continue; - if (c <= 0x36F) - return false; - - if (c < 0x0591 || c == 0x05BE) // U+0591 through U+05CF excluding U+05BE Hebrew combining marks, Hebrew punctuation Paseq, Sof Pasuq and Nun Hafukha - continue; - if (c <= 0x05CF) - return false; - - if (c < 0x0600) // U+0600 through U+1059 Arabic, Syriac, Thaana, Devanagari, Bengali, Gurmukhi, Gujarati, Oriya, Tamil, Telugu, Kannada, Malayalam, Sinhala, Thai, Lao, Tibetan, Myanmar - continue; - if (c <= 0x1059) - return false; - - if (c < 0x1100) // U+1100 through U+11FF Hangul Jamo (only Ancient Korean should be left here if you precompose; Modern Korean will be precomposed as a result of step A) - continue; - if (c <= 0x11FF) - return false; - - if (c < 0x1780) // U+1780 through U+18AF Khmer, Mongolian - continue; - if (c <= 0x18AF) - return false; - - if (c < 0x1900) // U+1900 through U+194F Limbu (Unicode 4.0) - continue; - if (c <= 0x194F) - return false; - - if (c < 0x20D0) // U+20D0 through U+20FF Combining marks for symbols - continue; - if (c <= 0x20FF) - return false; - - if (c < 0xFE20) // U+FE20 through U+FE2F Combining half marks - continue; - if (c <= 0xFE2F) - return false; - } - - if (typesettingFeatures()) - return false; - - return true; - -} - 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. @@ -314,10 +242,18 @@ void Font::drawGlyphBuffer(GraphicsContext* context, const GlyphBuffer& glyphBuf drawGlyphs(context, fontData, glyphBuffer, lastFrom, nextGlyph - lastFrom, startPoint); } -float Font::floatWidthForSimpleText(const TextRun& run, GlyphBuffer* glyphBuffer, HashSet<const SimpleFontData*>* fallbackFonts) const +float Font::floatWidthForSimpleText(const TextRun& run, GlyphBuffer* glyphBuffer, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const { - WidthIterator it(this, run, fallbackFonts); + WidthIterator it(this, run, fallbackFonts, glyphOverflow); it.advance(run.length(), glyphBuffer); + + if (glyphOverflow) { + glyphOverflow->top = max<int>(glyphOverflow->top, ceilf(-it.minGlyphBoundingBoxY()) - ascent()); + glyphOverflow->bottom = max<int>(glyphOverflow->bottom, ceilf(it.maxGlyphBoundingBoxY()) - descent()); + glyphOverflow->left = ceilf(it.firstGlyphOverflow()); + glyphOverflow->right = ceilf(it.lastGlyphOverflow()); + } + return it.m_runWidthSoFar; } diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/GlyphWidthMap.cpp b/src/3rdparty/webkit/WebCore/platform/graphics/GlyphMetricsMap.cpp index 43cab65..d3c3180 100644 --- a/src/3rdparty/webkit/WebCore/platform/graphics/GlyphWidthMap.cpp +++ b/src/3rdparty/webkit/WebCore/platform/graphics/GlyphMetricsMap.cpp @@ -27,14 +27,14 @@ */ #include "config.h" -#include "GlyphWidthMap.h" +#include "GlyphMetricsMap.h" namespace WebCore { -GlyphWidthMap::GlyphWidthPage* GlyphWidthMap::locatePageSlowCase(unsigned pageNumber) +GlyphMetricsMap::GlyphMetricsPage* GlyphMetricsMap::locatePageSlowCase(unsigned pageNumber) { - GlyphWidthPage* page; - if (pageNumber == 0) { + GlyphMetricsPage* page; + if (!pageNumber) { ASSERT(!m_filledPrimaryPage); page = &m_primaryPage; m_filledPrimaryPage = true; @@ -43,14 +43,18 @@ GlyphWidthMap::GlyphWidthPage* GlyphWidthMap::locatePageSlowCase(unsigned pageNu if ((page = m_pages->get(pageNumber))) return page; } else - m_pages.set(new HashMap<int, GlyphWidthPage*>); - page = new GlyphWidthPage; + m_pages.set(new HashMap<int, GlyphMetricsPage*>); + page = new GlyphMetricsPage; m_pages->set(pageNumber, page); } - // Fill in the whole page with the unknown glyph width value. - for (unsigned i = 0; i < GlyphWidthPage::size; i++) - page->setWidthForIndex(i, cGlyphWidthUnknown); + GlyphMetrics unknownMetrics; + unknownMetrics.horizontalAdvance = cGlyphSizeUnknown; + unknownMetrics.boundingBox.setWidth(cGlyphSizeUnknown); + unknownMetrics.boundingBox.setHeight(cGlyphSizeUnknown); + // Fill in the whole page with the unknown glyph information. + for (unsigned i = 0; i < GlyphMetricsPage::size; i++) + page->setMetricsForIndex(i, unknownMetrics); return page; } diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/GlyphWidthMap.h b/src/3rdparty/webkit/WebCore/platform/graphics/GlyphMetricsMap.h index 66dea1f..49854be 100644 --- a/src/3rdparty/webkit/WebCore/platform/graphics/GlyphWidthMap.h +++ b/src/3rdparty/webkit/WebCore/platform/graphics/GlyphMetricsMap.h @@ -26,9 +26,10 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef GlyphWidthMap_h -#define GlyphWidthMap_h +#ifndef GlyphMetricsMap_h +#define GlyphMetricsMap_h +#include "FloatRect.h" #include <wtf/HashMap.h> #include <wtf/OwnPtr.h> #include <wtf/unicode/Unicode.h> @@ -37,53 +38,67 @@ namespace WebCore { typedef unsigned short Glyph; -const float cGlyphWidthUnknown = -1; +const float cGlyphSizeUnknown = -1; -class GlyphWidthMap : public Noncopyable { +struct GlyphMetrics { + float horizontalAdvance; + FloatRect boundingBox; +}; + +class GlyphMetricsMap : public Noncopyable { public: - GlyphWidthMap() : m_filledPrimaryPage(false) { } - ~GlyphWidthMap() { if (m_pages) { deleteAllValues(*m_pages); } } + GlyphMetricsMap() : m_filledPrimaryPage(false) { } + ~GlyphMetricsMap() + { + if (m_pages) + deleteAllValues(*m_pages); + } + + GlyphMetrics metricsForGlyph(Glyph glyph) + { + return locatePage(glyph / GlyphMetricsPage::size)->metricsForGlyph(glyph); + } float widthForGlyph(Glyph glyph) { - return locatePage(glyph / GlyphWidthPage::size)->widthForGlyph(glyph); + return locatePage(glyph / GlyphMetricsPage::size)->metricsForGlyph(glyph).horizontalAdvance; } - void setWidthForGlyph(Glyph glyph, float width) + void setMetricsForGlyph(Glyph glyph, const GlyphMetrics& metrics) { - locatePage(glyph / GlyphWidthPage::size)->setWidthForGlyph(glyph, width); + locatePage(glyph / GlyphMetricsPage::size)->setMetricsForGlyph(glyph, metrics); } private: - struct GlyphWidthPage { + struct GlyphMetricsPage { static const size_t size = 256; // Usually covers Latin-1 in a single page. - float m_widths[size]; + GlyphMetrics m_metrics[size]; - float widthForGlyph(Glyph glyph) const { return m_widths[glyph % size]; } - void setWidthForGlyph(Glyph glyph, float width) + GlyphMetrics metricsForGlyph(Glyph glyph) const { return m_metrics[glyph % size]; } + void setMetricsForGlyph(Glyph glyph, const GlyphMetrics& metrics) { - setWidthForIndex(glyph % size, width); + setMetricsForIndex(glyph % size, metrics); } - void setWidthForIndex(unsigned index, float width) + void setMetricsForIndex(unsigned index, const GlyphMetrics& metrics) { - m_widths[index] = width; + m_metrics[index] = metrics; } }; - GlyphWidthPage* locatePage(unsigned pageNumber) + GlyphMetricsPage* locatePage(unsigned pageNumber) { if (!pageNumber && m_filledPrimaryPage) return &m_primaryPage; return locatePageSlowCase(pageNumber); } - GlyphWidthPage* locatePageSlowCase(unsigned pageNumber); + GlyphMetricsPage* locatePageSlowCase(unsigned pageNumber); bool m_filledPrimaryPage; - GlyphWidthPage m_primaryPage; // We optimize for the page that contains glyph indices 0-255. - OwnPtr<HashMap<int, GlyphWidthPage*> > m_pages; + GlyphMetricsPage m_primaryPage; // We optimize for the page that contains glyph indices 0-255. + OwnPtr<HashMap<int, GlyphMetricsPage*> > m_pages; }; -} +} // namespace WebCore #endif diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/SimpleFontData.cpp b/src/3rdparty/webkit/WebCore/platform/graphics/SimpleFontData.cpp index 2ec8abb..04b6ab1 100644 --- a/src/3rdparty/webkit/WebCore/platform/graphics/SimpleFontData.cpp +++ b/src/3rdparty/webkit/WebCore/platform/graphics/SimpleFontData.cpp @@ -157,9 +157,11 @@ void SimpleFontData::platformGlyphInit() // are mapped to the ZERO WIDTH SPACE glyph. Glyph zeroWidthSpaceGlyph = glyphPageZero->glyphDataForCharacter(0).glyph; if (zeroWidthSpaceGlyph) { - if (zeroWidthSpaceGlyph != m_spaceGlyph) - m_glyphToWidthMap.setWidthForGlyph(zeroWidthSpaceGlyph, 0); - else + if (zeroWidthSpaceGlyph != m_spaceGlyph) { + GlyphMetrics metrics; + metrics.horizontalAdvance = 0; + m_glyphToMetricsMap.setMetricsForGlyph(zeroWidthSpaceGlyph, metrics); + } else LOG_ERROR("Font maps SPACE and ZERO WIDTH SPACE to the same glyph. Glyph width not overridden."); } diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/SimpleFontData.h b/src/3rdparty/webkit/WebCore/platform/graphics/SimpleFontData.h index 0366e3b..efdbba4 100644 --- a/src/3rdparty/webkit/WebCore/platform/graphics/SimpleFontData.h +++ b/src/3rdparty/webkit/WebCore/platform/graphics/SimpleFontData.h @@ -26,8 +26,8 @@ #include "FontData.h" #include "FontPlatformData.h" +#include "GlyphMetricsMap.h" #include "GlyphPageTreeNode.h" -#include "GlyphWidthMap.h" #include "TypesettingFeatures.h" #include <wtf/OwnPtr.h> @@ -58,9 +58,9 @@ class FontDescription; class FontPlatformData; class SharedBuffer; class SVGFontData; -class WidthMap; enum Pitch { UnknownPitch, FixedPitch, VariablePitch }; +enum GlyphMetricsMode { GlyphBoundingBox, GlyphWidthOnly }; class SimpleFontData : public FontData { public: @@ -81,8 +81,9 @@ public: float xHeight() const { return m_xHeight; } unsigned unitsPerEm() const { return m_unitsPerEm; } - float widthForGlyph(Glyph) const; - float platformWidthForGlyph(Glyph) const; + float widthForGlyph(Glyph glyph) const { return metricsForGlyph(glyph, GlyphWidthOnly).horizontalAdvance; } + GlyphMetrics metricsForGlyph(Glyph, GlyphMetricsMode = GlyphBoundingBox) const; + GlyphMetrics platformMetricsForGlyph(Glyph, GlyphMetricsMode) const; float spaceWidth() const { return m_spaceWidth; } float adjustedSpaceWidth() const { return m_adjustedSpaceWidth; } @@ -167,7 +168,7 @@ private: || (OS(WINDOWS) && PLATFORM(WX)) void initGDIFont(); void platformCommonDestroy(); - float widthForGDIGlyph(Glyph glyph) const; + GlyphMetrics metricsForGDIGlyph(Glyph glyph) const; #endif int m_ascent; @@ -181,7 +182,7 @@ private: FontPlatformData m_platformData; - mutable GlyphWidthMap m_glyphToWidthMap; + mutable GlyphMetricsMap m_glyphToMetricsMap; bool m_treatAsFixedPitch; @@ -237,16 +238,16 @@ private: #if !PLATFORM(QT) -ALWAYS_INLINE float SimpleFontData::widthForGlyph(Glyph glyph) const +ALWAYS_INLINE GlyphMetrics SimpleFontData::metricsForGlyph(Glyph glyph, GlyphMetricsMode metricsMode) const { - float width = m_glyphToWidthMap.widthForGlyph(glyph); - if (width != cGlyphWidthUnknown) - return width; - - width = platformWidthForGlyph(glyph); - m_glyphToWidthMap.setWidthForGlyph(glyph, width); - - return width; + GlyphMetrics metrics = m_glyphToMetricsMap.metricsForGlyph(glyph); + if ((metricsMode == GlyphWidthOnly && metrics.horizontalAdvance != cGlyphSizeUnknown) || (metricsMode == GlyphBoundingBox && metrics.boundingBox.width() != cGlyphSizeUnknown)) + return metrics; + + metrics = platformMetricsForGlyph(glyph, metricsMode); + m_glyphToMetricsMap.setMetricsForGlyph(glyph, metrics); + + return metrics; } #endif diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/WidthIterator.cpp b/src/3rdparty/webkit/WebCore/platform/graphics/WidthIterator.cpp index 9157310..996ce40 100644 --- a/src/3rdparty/webkit/WebCore/platform/graphics/WidthIterator.cpp +++ b/src/3rdparty/webkit/WebCore/platform/graphics/WidthIterator.cpp @@ -33,13 +33,14 @@ using namespace WTF; using namespace Unicode; +using namespace std; 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) +WidthIterator::WidthIterator(const Font* font, const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, bool accountForGlyphBounds) : m_font(font) , m_run(run) , m_end(run.length()) @@ -47,6 +48,11 @@ WidthIterator::WidthIterator(const Font* font, const TextRun& run, HashSet<const , m_runWidthSoFar(0) , m_finalRoundingWidth(0) , m_fallbackFonts(fallbackFonts) + , m_accountForGlyphBounds(accountForGlyphBounds) + , m_maxGlyphBoundingBoxY(numeric_limits<float>::min()) + , m_minGlyphBoundingBoxY(numeric_limits<float>::max()) + , m_firstGlyphOverflow(0) + , m_lastGlyphOverflow(0) { // If the padding is non-zero, count the number of spaces in the run // and divide that by the padding for per space addition. @@ -79,6 +85,7 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer) float runWidthSoFar = m_runWidthSoFar; float lastRoundingWidth = m_finalRoundingWidth; + FloatRect bounds; const SimpleFontData* primaryFont = m_font->primaryFont(); const SimpleFontData* lastFontData = primaryFont; @@ -175,6 +182,12 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer) } } + if (m_accountForGlyphBounds) { + bounds = fontData->boundsForGlyph(glyph); + if (!currentCharacter) + m_firstGlyphOverflow = max<float>(0, -bounds.x()); + } + // Advance past the character we just dealt with. cp += clusterLength; currentCharacter += clusterLength; @@ -205,6 +218,12 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer) glyphBuffer->add(glyph, fontData, (rtl ? oldWidth + lastRoundingWidth : width)); lastRoundingWidth = width - oldWidth; + + if (m_accountForGlyphBounds) { + m_maxGlyphBoundingBoxY = max(m_maxGlyphBoundingBoxY, bounds.bottom()); + m_minGlyphBoundingBoxY = min(m_minGlyphBoundingBoxY, bounds.y()); + m_lastGlyphOverflow = max<float>(0, bounds.right() - width); + } } m_currentCharacter = currentCharacter; diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/WidthIterator.h b/src/3rdparty/webkit/WebCore/platform/graphics/WidthIterator.h index 7ca4198..d42a0c5 100644 --- a/src/3rdparty/webkit/WebCore/platform/graphics/WidthIterator.h +++ b/src/3rdparty/webkit/WebCore/platform/graphics/WidthIterator.h @@ -33,11 +33,16 @@ class SimpleFontData; class TextRun; struct WidthIterator { - WidthIterator(const Font*, const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0); + WidthIterator(const Font*, const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0, bool accountForGlyphBounds = false); void advance(int to, GlyphBuffer* = 0); bool advanceOneCharacter(float& width, GlyphBuffer* = 0); + float maxGlyphBoundingBoxY() const { ASSERT(m_accountForGlyphBounds); return m_maxGlyphBoundingBoxY; } + float minGlyphBoundingBoxY() const { ASSERT(m_accountForGlyphBounds); return m_minGlyphBoundingBoxY; } + float firstGlyphOverflow() const { ASSERT(m_accountForGlyphBounds); return m_firstGlyphOverflow; } + float lastGlyphOverflow() const { ASSERT(m_accountForGlyphBounds); return m_lastGlyphOverflow; } + const Font* m_font; const TextRun& m_run; @@ -51,7 +56,13 @@ struct WidthIterator { private: UChar32 normalizeVoicingMarks(int currentCharacter); + HashSet<const SimpleFontData*>* m_fallbackFonts; + bool m_accountForGlyphBounds; + float m_maxGlyphBoundingBoxY; + float m_minGlyphBoundingBoxY; + float m_firstGlyphOverflow; + float m_lastGlyphOverflow; }; } diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/qt/FontQt.cpp b/src/3rdparty/webkit/WebCore/platform/graphics/qt/FontQt.cpp index ae1033e..06885ba 100644 --- a/src/3rdparty/webkit/WebCore/platform/graphics/qt/FontQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/graphics/qt/FontQt.cpp @@ -44,11 +44,15 @@ namespace WebCore { -static const QString fromRawDataWithoutRef(const String& string) +static const QString fromRawDataWithoutRef(const String& string, int start = 0, int len = -1) { + if (len < 0) + len = string.length() - start; + Q_ASSERT(start + len <= string.length()); + // We don't detach. This assumes the WebCore string data will stay valid for the // lifetime of the QString we pass back, since we don't ref the WebCore string. - return QString::fromRawData(reinterpret_cast<const QChar*>(string.characters()), string.length()); + return QString::fromRawData(reinterpret_cast<const QChar*>(string.characters() + start), len); } static QTextLine setupLayout(QTextLayout* layout, const TextRun& style) @@ -66,7 +70,7 @@ static QTextLine setupLayout(QTextLayout* layout, const TextRun& style) return line; } -void Font::drawComplexText(GraphicsContext* ctx, const TextRun& run, const FloatPoint& point, int from, int to) const +static void drawTextCommon(GraphicsContext* ctx, const TextRun& run, const FloatPoint& point, int from, int to, const QFont& font, bool isComplexText) { if (to < 0) to = run.length(); @@ -102,6 +106,7 @@ void Font::drawComplexText(GraphicsContext* ctx, const TextRun& run, const Float String sanitized = Font::normalizeSpaces(String(run.characters(), run.length())); QString string = fromRawDataWithoutRef(sanitized); + QPointF pt(point.x(), point.y()); // text shadow IntSize shadowSize; @@ -110,52 +115,63 @@ void Font::drawComplexText(GraphicsContext* ctx, const TextRun& run, const Float bool hasShadow = ctx->textDrawingMode() == cTextFill && ctx->getShadow(shadowSize, shadowBlur, shadowColor); if (from > 0 || to < run.length()) { - QTextLayout layout(string, font()); - QTextLine line = setupLayout(&layout, run); - float x1 = line.cursorToX(from); - float x2 = line.cursorToX(to); - if (x2 < x1) - qSwap(x1, x2); - - QFontMetrics fm(font()); - int ascent = fm.ascent(); - QRectF clip(point.x() + x1, point.y() - ascent, x2 - x1, fm.height()); - - if (hasShadow) { - // TODO: when blur support is added, the clip will need to account - // for the blur radius - qreal dx1 = 0, dx2 = 0, dy1 = 0, dy2 = 0; - if (shadowSize.width() > 0) - dx2 = shadowSize.width(); - else - dx1 = -shadowSize.width(); - if (shadowSize.height() > 0) - dy2 = shadowSize.height(); - else - dy1 = -shadowSize.height(); - // expand the clip rect to include the text shadow as well - clip.adjust(dx1, dx2, dy1, dy2); - } - p->save(); - p->setClipRect(clip.toRect(), Qt::IntersectClip); - QPointF pt(point.x(), point.y() - ascent); - if (hasShadow) { + if (isComplexText) { + QTextLayout layout(string, font); + QTextLine line = setupLayout(&layout, run); + float x1 = line.cursorToX(from); + float x2 = line.cursorToX(to); + if (x2 < x1) + qSwap(x1, x2); + + QFontMetrics fm(font); + int ascent = fm.ascent(); + QRectF clip(point.x() + x1, point.y() - ascent, x2 - x1, fm.height()); + + if (hasShadow) { + // TODO: when blur support is added, the clip will need to account + // for the blur radius + qreal dx1 = 0, dx2 = 0, dy1 = 0, dy2 = 0; + if (shadowSize.width() > 0) + dx2 = shadowSize.width(); + else + dx1 = -shadowSize.width(); + if (shadowSize.height() > 0) + dy2 = shadowSize.height(); + else + dy1 = -shadowSize.height(); + // expand the clip rect to include the text shadow as well + clip.adjust(dx1, dx2, dy1, dy2); + } p->save(); - p->setPen(QColor(shadowColor)); - p->translate(shadowSize.width(), shadowSize.height()); + p->setClipRect(clip.toRect(), Qt::IntersectClip); + pt.setY(pt.y() - ascent); + if (hasShadow) { + p->save(); + p->setPen(QColor(shadowColor)); + p->translate(shadowSize.width(), shadowSize.height()); + line.draw(p, pt); + p->restore(); + } + p->setPen(textFillPen); line.draw(p, pt); p->restore(); + return; } - p->setPen(textFillPen); - line.draw(p, pt); - p->restore(); - return; +#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) + int skipWidth = QFontMetrics(font).width(string, from, Qt::TextBypassShaping); + pt.setX(pt.x() + skipWidth); + string = fromRawDataWithoutRef(sanitized, from, to - from); +#endif } - p->setFont(font()); + p->setFont(font); - QPointF pt(point.x(), point.y()); int flags = run.rtl() ? Qt::TextForceRightToLeft : Qt::TextForceLeftToRight; +#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) + // See QWebPagePrivate::QWebPagePrivate() where the default path is set to Complex for Qt 4.6 and earlier. + if (!isComplexText) + flags |= Qt::TextBypassShaping; +#endif if (hasShadow) { // TODO: text shadow blur support p->save(); @@ -166,7 +182,7 @@ void Font::drawComplexText(GraphicsContext* ctx, const TextRun& run, const Float } if (ctx->textDrawingMode() & cTextStroke) { QPainterPath path; - path.addText(pt, font(), string); + path.addText(pt, font, string); p->setPen(textStrokePen); p->strokePath(path, p->pen()); } @@ -176,13 +192,49 @@ void Font::drawComplexText(GraphicsContext* ctx, const TextRun& run, const Float } } -float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>*) const +void Font::drawSimpleText(GraphicsContext* ctx, const TextRun& run, const FloatPoint& point, int from, int to) const +{ +#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) + drawTextCommon(ctx, run, point, from, to, font(), /* isComplexText = */false); +#else + Q_ASSERT(false); +#endif +} + +void Font::drawComplexText(GraphicsContext* ctx, const TextRun& run, const FloatPoint& point, int from, int to) const +{ + drawTextCommon(ctx, run, point, from, to, font(), /* isComplexText = */true); +} + +float Font::floatWidthForSimpleText(const TextRun& run, GlyphBuffer* glyphBuffer, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const +{ +#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) + if (!run.length()) + return 0; + + String sanitized = Font::normalizeSpaces(String(run.characters(), run.length())); + QString string = fromRawDataWithoutRef(sanitized); + + int w = QFontMetrics(font()).width(string, -1, Qt::TextBypassShaping); + + // WebKit expects us to ignore word spacing on the first character (as opposed to what Qt does) + if (treatAsSpace(run[0])) + w -= m_wordSpacing; + + return w + run.padding(); +#else + Q_ASSERT(false); + return 0.0f; +#endif +} + +float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>*, GlyphOverflow*) const { if (!run.length()) return 0; if (run.length() == 1 && treatAsSpace(run[0])) - return QFontMetrics(font()).width(run[0]) - m_wordSpacing + run.padding(); + return QFontMetrics(font()).width(run[0]) + run.padding(); String sanitized = Font::normalizeSpaces(String(run.characters(), run.length())); QString string = fromRawDataWithoutRef(sanitized); @@ -195,6 +247,34 @@ float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFon return w + run.padding(); } +int Font::offsetForPositionForSimpleText(const TextRun& run, int position, bool includePartialGlyphs) const +{ +#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) + String sanitized = Font::normalizeSpaces(String(run.characters(), run.length())); + QString string = fromRawDataWithoutRef(sanitized); + + QFontMetrics fm(font()); + float delta = (float)position; + int curPos = 0; + do { + float charWidth = fm.width(string[curPos]); + delta -= charWidth; + if (includePartialGlyphs) { + if (delta + charWidth / 2 <= 0) + break; + } else { + if (delta + charWidth <= 0) + break; + } + } while (++curPos < string.size()); + + return curPos; +#else + Q_ASSERT(false); + return 0; +#endif +} + int Font::offsetForPositionForComplexText(const TextRun& run, int position, bool) const { String sanitized = Font::normalizeSpaces(String(run.characters(), run.length())); @@ -205,6 +285,23 @@ int Font::offsetForPositionForComplexText(const TextRun& run, int position, bool return line.xToCursor(position); } +FloatRect Font::selectionRectForSimpleText(const TextRun& run, const IntPoint& pt, int h, int from, int to) const +{ +#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) + String sanitized = Font::normalizeSpaces(String(run.characters(), run.length())); + QString wholeText = fromRawDataWithoutRef(sanitized); + QString selectedText = fromRawDataWithoutRef(sanitized, from, to - from); + + int startX = QFontMetrics(font()).width(wholeText, from, Qt::TextBypassShaping); + int width = QFontMetrics(font()).width(selectedText, -1, Qt::TextBypassShaping); + + return FloatRect(pt.x() + startX, pt.y(), width, h); +#else + Q_ASSERT(false); + return FloatRect(); +#endif +} + FloatRect Font::selectionRectForComplexText(const TextRun& run, const IntPoint& pt, int h, int from, int to) const { String sanitized = Font::normalizeSpaces(String(run.characters(), run.length())); @@ -221,6 +318,11 @@ FloatRect Font::selectionRectForComplexText(const TextRun& run, const IntPoint& return FloatRect(pt.x() + x1, pt.y(), x2 - x1, h); } +bool Font::canReturnFallbackFontsForComplexText() +{ + return false; +} + QFont Font::font() const { QFont f = primaryFont()->getQtFont(); diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/qt/ImageDecoderQt.cpp b/src/3rdparty/webkit/WebCore/platform/graphics/qt/ImageDecoderQt.cpp index cc707da..fb3d621 100644 --- a/src/3rdparty/webkit/WebCore/platform/graphics/qt/ImageDecoderQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/graphics/qt/ImageDecoderQt.cpp @@ -78,9 +78,6 @@ void ImageDecoderQt::setData(SharedBuffer* data, bool allDataReceived) m_buffer->open(QIODevice::ReadOnly | QIODevice::Unbuffered); m_reader.set(new QImageReader(m_buffer.get(), m_format)); - // This will force the JPEG decoder to use JDCT_IFAST - m_reader->setQuality(49); - // QImageReader only allows retrieving the format before reading the image m_format = m_reader->format(); } @@ -188,9 +185,21 @@ void ImageDecoderQt::internalReadImage(size_t frameIndex) bool ImageDecoderQt::internalHandleCurrentImage(size_t frameIndex) { - // Now get the QImage from Qt and place it in the RGBA32Buffer - QImage img; - if (!m_reader->read(&img)) { + QPixmap pixmap; + bool pixmapLoaded; + const int imageCount = m_reader->imageCount(); + if (imageCount == 0 || imageCount == 1) + pixmapLoaded = pixmap.loadFromData((const uchar*)(m_data->data()), m_data->size(), m_format); + else { + QImage img; + const bool imageLoaded = m_reader->read(&img); + if (imageLoaded) { + pixmap = QPixmap::fromImage(img); + pixmapLoaded = true; + } + } + + if (!pixmapLoaded) { frameCount(); repetitionCount(); clearPointers(); @@ -198,12 +207,11 @@ bool ImageDecoderQt::internalHandleCurrentImage(size_t frameIndex) } // now into the RGBA32Buffer - even if the image is not - QSize imageSize = img.size(); RGBA32Buffer* const buffer = &m_frameBufferCache[frameIndex]; buffer->setRect(m_reader->currentImageRect()); buffer->setStatus(RGBA32Buffer::FrameComplete); buffer->setDuration(m_reader->nextImageDelay()); - buffer->setDecodedImage(img); + buffer->setPixmap(pixmap); return true; } diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/win/FontWin.cpp b/src/3rdparty/webkit/WebCore/platform/graphics/win/FontWin.cpp index 27d8dee..717171f 100644 --- a/src/3rdparty/webkit/WebCore/platform/graphics/win/FontWin.cpp +++ b/src/3rdparty/webkit/WebCore/platform/graphics/win/FontWin.cpp @@ -34,6 +34,8 @@ #include "UniscribeController.h" #include <wtf/MathExtras.h> +using namespace std; + namespace WebCore { bool Font::canReturnFallbackFontsForComplexText() @@ -89,10 +91,16 @@ void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const F drawGlyphBuffer(context, glyphBuffer, run, startPoint); } -float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts) const +float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const { UniscribeController controller(this, run, fallbackFonts); controller.advance(run.length()); + if (glyphOverflow) { + glyphOverflow->top = max<int>(glyphOverflow->top, ceilf(-controller.minGlyphBoundingBoxY()) - ascent()); + glyphOverflow->bottom = max<int>(glyphOverflow->bottom, ceilf(controller.maxGlyphBoundingBoxY()) - descent()); + glyphOverflow->left = max<int>(0, ceilf(-controller.minGlyphBoundingBoxX())); + glyphOverflow->right = max<int>(0, ceilf(controller.maxGlyphBoundingBoxX() - controller.runWidthSoFar())); + } return controller.runWidthSoFar(); } diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp b/src/3rdparty/webkit/WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp index 6b3a96e..ee3a980 100644 --- a/src/3rdparty/webkit/WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp +++ b/src/3rdparty/webkit/WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp @@ -126,10 +126,10 @@ void SimpleFontData::platformCharWidthInit() } } -float SimpleFontData::platformWidthForGlyph(Glyph glyph) const +GlyphMetrics SimpleFontData::platformMetricsForGlyph(Glyph glyph, GlyphMetricsMode metricsMode) const { if (m_platformData.useGDI()) - return widthForGDIGlyph(glyph); + return metricsForGDIGlyph(glyph); CGFontRef font = m_platformData.cgFont(); float pointSize = m_platformData.size(); @@ -139,8 +139,18 @@ float SimpleFontData::platformWidthForGlyph(Glyph glyph) const // FIXME: Need to add real support for printer fonts. bool isPrinterFont = false; wkGetGlyphAdvances(font, m, m_isSystemFont, isPrinterFont, glyph, advance); - - return advance.width + m_syntheticBoldOffset; + GlyphMetrics metrics; + metrics.horizontalAdvance = advance.width + m_syntheticBoldOffset; + + if (metricsMode == GlyphBoundingBox) { + CGRect boundingBox; + CGFontGetGlyphBBoxes(font, &glyph, 1, &boundingBox); + CGFloat scale = pointSize / unitsPerEm(); + metrics.boundingBox = CGRectApplyAffineTransform(boundingBox, CGAffineTransformMakeScale(scale, -scale)); + if (m_syntheticBoldOffset) + metrics.boundingBox.setWidth(metrics.boundingBox.width() + m_syntheticBoldOffset); + } + return metrics; } } diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/win/SimpleFontDataWin.cpp b/src/3rdparty/webkit/WebCore/platform/graphics/win/SimpleFontDataWin.cpp index 5a3244c..f85f9ba 100644 --- a/src/3rdparty/webkit/WebCore/platform/graphics/win/SimpleFontDataWin.cpp +++ b/src/3rdparty/webkit/WebCore/platform/graphics/win/SimpleFontDataWin.cpp @@ -179,16 +179,25 @@ void SimpleFontData::determinePitch() ReleaseDC(0, dc); } -float SimpleFontData::widthForGDIGlyph(Glyph glyph) const +GlyphMetrics SimpleFontData::metricsForGDIGlyph(Glyph glyph) const { HDC hdc = GetDC(0); SetGraphicsMode(hdc, GM_ADVANCED); HGDIOBJ oldFont = SelectObject(hdc, m_platformData.hfont()); - int width; - GetCharWidthI(hdc, glyph, 1, 0, &width); + + GLYPHMETRICS gdiMetrics; + static const MAT2 identity = { 0, 1, 0, 0, 0, 0, 0, 1 }; + GetGlyphOutline(hdc, glyph, GGO_METRICS | GGO_GLYPH_INDEX, &gdiMetrics, 0, 0, &identity); + SelectObject(hdc, oldFont); ReleaseDC(0, hdc); - return width + m_syntheticBoldOffset; + + GlyphMetrics glyphMetrics; + glyphMetrics.horizontalAdvance = gdiMetrics.gmCellIncX + m_syntheticBoldOffset; + glyphMetrics.boundingBox = FloatRect(gdiMetrics.gmptGlyphOrigin.x, -gdiMetrics.gmptGlyphOrigin.y, + gdiMetrics.gmBlackBoxX + m_syntheticBoldOffset, gdiMetrics.gmBlackBoxY); + + return glyphMetrics; } SCRIPT_FONTPROPERTIES* SimpleFontData::scriptFontProperties() const diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/win/UniscribeController.cpp b/src/3rdparty/webkit/WebCore/platform/graphics/win/UniscribeController.cpp index f382857..cfa15a2 100644 --- a/src/3rdparty/webkit/WebCore/platform/graphics/win/UniscribeController.cpp +++ b/src/3rdparty/webkit/WebCore/platform/graphics/win/UniscribeController.cpp @@ -32,6 +32,8 @@ #include "SimpleFontData.h" #include <wtf/MathExtras.h> +using namespace std; + namespace WebCore { // FIXME: Rearchitect this to be more like WidthIterator in Font.cpp. Have an advance() method @@ -39,16 +41,20 @@ namespace WebCore { // take the GlyphBuffer as an arg so that we don't have to populate the glyph buffer when // measuring. UniscribeController::UniscribeController(const Font* font, const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts) -: m_font(*font) -, m_run(run) -, m_fallbackFonts(fallbackFonts) -, m_end(run.length()) -, m_currentCharacter(0) -, m_runWidthSoFar(0) -, m_computingOffsetPosition(false) -, m_includePartialGlyphs(false) -, m_offsetX(0) -, m_offsetPosition(0) + : m_font(*font) + , m_run(run) + , m_fallbackFonts(fallbackFonts) + , m_minGlyphBoundingBoxX(numeric_limits<float>::max()) + , m_maxGlyphBoundingBoxX(numeric_limits<float>::min()) + , m_minGlyphBoundingBoxY(numeric_limits<float>::max()) + , m_maxGlyphBoundingBoxY(numeric_limits<float>::min()) + , m_end(run.length()) + , m_currentCharacter(0) + , m_runWidthSoFar(0) + , m_computingOffsetPosition(false) + , m_includePartialGlyphs(false) + , m_offsetX(0) + , m_offsetPosition(0) { m_padding = m_run.padding(); if (!m_padding) @@ -374,6 +380,14 @@ bool UniscribeController::shapeAndPlaceItem(const UChar* cp, unsigned i, const S glyphBuffer->add(glyph, fontData, advance, &size); } + GlyphMetrics glyphMetrics = fontData->metricsForGlyph(glyph); + glyphMetrics.boundingBox.move(m_glyphOrigin.x(), m_glyphOrigin.y()); + m_minGlyphBoundingBoxX = min(m_minGlyphBoundingBoxX, glyphMetrics.boundingBox.x()); + m_maxGlyphBoundingBoxX = max(m_maxGlyphBoundingBoxX, glyphMetrics.boundingBox.right()); + m_minGlyphBoundingBoxY = min(m_minGlyphBoundingBoxY, glyphMetrics.boundingBox.y()); + m_maxGlyphBoundingBoxY = max(m_maxGlyphBoundingBoxY, glyphMetrics.boundingBox.bottom()); + m_glyphOrigin.move(advance + offsetX, -offsetY); + // Mutate the glyph array to contain our altered advances. if (m_computingOffsetPosition) advances[k] = advance; diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/win/UniscribeController.h b/src/3rdparty/webkit/WebCore/platform/graphics/win/UniscribeController.h index 23b8108..09203b5 100644 --- a/src/3rdparty/webkit/WebCore/platform/graphics/win/UniscribeController.h +++ b/src/3rdparty/webkit/WebCore/platform/graphics/win/UniscribeController.h @@ -49,6 +49,11 @@ public: // Returns the width of everything we've consumed so far. float runWidthSoFar() const { return m_runWidthSoFar; } + float minGlyphBoundingBoxX() const { return m_minGlyphBoundingBoxX; } + float maxGlyphBoundingBoxX() const { return m_maxGlyphBoundingBoxX; } + float minGlyphBoundingBoxY() const { return m_minGlyphBoundingBoxY; } + float maxGlyphBoundingBoxY() const { return m_maxGlyphBoundingBoxY; } + private: void resetControlAndState(); @@ -61,6 +66,11 @@ private: const Font& m_font; const TextRun& m_run; HashSet<const SimpleFontData*>* m_fallbackFonts; + FloatPoint m_glyphOrigin; + float m_minGlyphBoundingBoxX; + float m_maxGlyphBoundingBoxX; + float m_minGlyphBoundingBoxY; + float m_maxGlyphBoundingBoxY; SCRIPT_CONTROL m_control; SCRIPT_STATE m_state; |