summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/webkit/WebCore/platform/graphics
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/webkit/WebCore/platform/graphics')
-rw-r--r--src/3rdparty/webkit/WebCore/platform/graphics/Font.cpp104
-rw-r--r--src/3rdparty/webkit/WebCore/platform/graphics/Font.h32
-rw-r--r--src/3rdparty/webkit/WebCore/platform/graphics/FontFastPath.cpp88
-rw-r--r--src/3rdparty/webkit/WebCore/platform/graphics/GlyphMetricsMap.cpp (renamed from src/3rdparty/webkit/WebCore/platform/graphics/GlyphWidthMap.cpp)22
-rw-r--r--src/3rdparty/webkit/WebCore/platform/graphics/GlyphMetricsMap.h (renamed from src/3rdparty/webkit/WebCore/platform/graphics/GlyphWidthMap.h)57
-rw-r--r--src/3rdparty/webkit/WebCore/platform/graphics/SimpleFontData.cpp8
-rw-r--r--src/3rdparty/webkit/WebCore/platform/graphics/SimpleFontData.h31
-rw-r--r--src/3rdparty/webkit/WebCore/platform/graphics/WidthIterator.cpp21
-rw-r--r--src/3rdparty/webkit/WebCore/platform/graphics/WidthIterator.h13
-rw-r--r--src/3rdparty/webkit/WebCore/platform/graphics/qt/FontQt.cpp190
-rw-r--r--src/3rdparty/webkit/WebCore/platform/graphics/qt/ImageDecoderQt.cpp24
-rw-r--r--src/3rdparty/webkit/WebCore/platform/graphics/win/FontWin.cpp10
-rw-r--r--src/3rdparty/webkit/WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp18
-rw-r--r--src/3rdparty/webkit/WebCore/platform/graphics/win/SimpleFontDataWin.cpp17
-rw-r--r--src/3rdparty/webkit/WebCore/platform/graphics/win/UniscribeController.cpp34
-rw-r--r--src/3rdparty/webkit/WebCore/platform/graphics/win/UniscribeController.h10
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;