summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/graphics
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/platform/graphics')
-rw-r--r--WebCore/platform/graphics/BitmapImage.cpp2
-rw-r--r--WebCore/platform/graphics/BitmapImage.h10
-rw-r--r--WebCore/platform/graphics/Color.cpp35
-rw-r--r--WebCore/platform/graphics/Color.h1
-rw-r--r--WebCore/platform/graphics/FloatQuad.cpp39
-rw-r--r--WebCore/platform/graphics/FloatQuad.h8
-rw-r--r--WebCore/platform/graphics/Font.cpp30
-rw-r--r--WebCore/platform/graphics/Font.h21
-rw-r--r--WebCore/platform/graphics/FontCache.cpp7
-rw-r--r--WebCore/platform/graphics/FontCache.h1
-rw-r--r--WebCore/platform/graphics/FontDescription.h6
-rw-r--r--WebCore/platform/graphics/FontFallbackList.cpp4
-rw-r--r--WebCore/platform/graphics/FontFallbackList.h2
-rw-r--r--WebCore/platform/graphics/FontFastPath.cpp20
-rw-r--r--WebCore/platform/graphics/GeneratedImage.cpp2
-rw-r--r--WebCore/platform/graphics/GlyphPageTreeNode.cpp27
-rw-r--r--WebCore/platform/graphics/GlyphPageTreeNode.h67
-rw-r--r--WebCore/platform/graphics/Gradient.cpp1
-rw-r--r--WebCore/platform/graphics/GraphicsContext.cpp3
-rw-r--r--WebCore/platform/graphics/GraphicsContext.h1
-rw-r--r--WebCore/platform/graphics/GraphicsLayer.h6
-rw-r--r--WebCore/platform/graphics/Image.h9
-rw-r--r--WebCore/platform/graphics/ImageBuffer.h14
-rw-r--r--WebCore/platform/graphics/ImageSource.h5
-rw-r--r--WebCore/platform/graphics/IntPoint.h1
-rw-r--r--WebCore/platform/graphics/IntSize.h6
-rw-r--r--WebCore/platform/graphics/MediaPlayer.cpp36
-rw-r--r--WebCore/platform/graphics/MediaPlayer.h15
-rw-r--r--WebCore/platform/graphics/MediaPlayerPrivate.h6
-rw-r--r--WebCore/platform/graphics/Path.cpp2
-rw-r--r--WebCore/platform/graphics/SimpleFontData.cpp62
-rw-r--r--WebCore/platform/graphics/SimpleFontData.h37
-rw-r--r--WebCore/platform/graphics/WidthIterator.cpp35
-rw-r--r--WebCore/platform/graphics/WidthIterator.h5
-rw-r--r--WebCore/platform/graphics/android/FontAndroid.cpp7
-rw-r--r--WebCore/platform/graphics/android/FontDataAndroid.cpp15
-rw-r--r--WebCore/platform/graphics/cairo/FontCairo.cpp26
-rw-r--r--WebCore/platform/graphics/cairo/GradientCairo.cpp4
-rw-r--r--WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp1
-rw-r--r--WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h2
-rw-r--r--WebCore/platform/graphics/cairo/ImageBufferCairo.cpp1
-rw-r--r--WebCore/platform/graphics/cairo/ImageCairo.cpp31
-rw-r--r--WebCore/platform/graphics/cairo/ImageSourceCairo.cpp4
-rw-r--r--WebCore/platform/graphics/cairo/PathCairo.cpp1
-rw-r--r--WebCore/platform/graphics/cg/GraphicsContextCG.cpp42
-rw-r--r--WebCore/platform/graphics/cg/ImageSourceCG.cpp43
-rw-r--r--WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp15
-rw-r--r--WebCore/platform/graphics/chromium/FontCacheLinux.cpp42
-rw-r--r--WebCore/platform/graphics/chromium/FontChromiumWin.cpp45
-rw-r--r--WebCore/platform/graphics/chromium/FontCustomPlatformData.cpp6
-rw-r--r--WebCore/platform/graphics/chromium/FontLinux.cpp7
-rw-r--r--WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp5
-rw-r--r--WebCore/platform/graphics/chromium/FontPlatformDataLinux.h7
-rw-r--r--WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp94
-rw-r--r--WebCore/platform/graphics/chromium/GlyphPageTreeNodeChromiumWin.cpp10
-rw-r--r--WebCore/platform/graphics/chromium/MediaPlayerPrivateChromium.h59
-rw-r--r--WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp19
-rw-r--r--WebCore/platform/graphics/chromium/SimpleFontDataLinux.cpp51
-rw-r--r--WebCore/platform/graphics/chromium/TransparencyWin.cpp2
-rw-r--r--WebCore/platform/graphics/chromium/VDMXParser.cpp203
-rw-r--r--WebCore/platform/graphics/chromium/VDMXParser.h40
-rw-r--r--WebCore/platform/graphics/filters/FEBlend.cpp8
-rw-r--r--WebCore/platform/graphics/filters/FEBlend.h10
-rw-r--r--WebCore/platform/graphics/filters/FEColorMatrix.cpp8
-rw-r--r--WebCore/platform/graphics/filters/FEColorMatrix.h10
-rw-r--r--WebCore/platform/graphics/filters/FEComponentTransfer.cpp8
-rw-r--r--WebCore/platform/graphics/filters/FEComponentTransfer.h11
-rw-r--r--WebCore/platform/graphics/filters/FEComposite.cpp8
-rw-r--r--WebCore/platform/graphics/filters/FEComposite.h10
-rw-r--r--WebCore/platform/graphics/filters/Filter.h52
-rw-r--r--WebCore/platform/graphics/filters/FilterEffect.cpp46
-rw-r--r--WebCore/platform/graphics/filters/FilterEffect.h81
-rw-r--r--WebCore/platform/graphics/filters/SourceAlpha.cpp54
-rw-r--r--WebCore/platform/graphics/filters/SourceAlpha.h47
-rw-r--r--WebCore/platform/graphics/filters/SourceGraphic.cpp54
-rw-r--r--WebCore/platform/graphics/filters/SourceGraphic.h48
-rw-r--r--WebCore/platform/graphics/gtk/FontCacheGtk.cpp2
-rw-r--r--WebCore/platform/graphics/gtk/FontGtk.cpp16
-rw-r--r--WebCore/platform/graphics/gtk/FontPlatformData.h2
-rw-r--r--WebCore/platform/graphics/gtk/FontPlatformDataGtk.cpp6
-rw-r--r--WebCore/platform/graphics/gtk/GlyphPageTreeNodeGtk.cpp4
-rw-r--r--WebCore/platform/graphics/gtk/GlyphPageTreeNodePango.cpp4
-rw-r--r--WebCore/platform/graphics/gtk/IconGtk.cpp1
-rw-r--r--WebCore/platform/graphics/gtk/ImageGtk.cpp73
-rw-r--r--WebCore/platform/graphics/gtk/SimpleFontDataGtk.cpp30
-rw-r--r--WebCore/platform/graphics/gtk/SimpleFontDataPango.cpp26
-rw-r--r--WebCore/platform/graphics/mac/ColorMac.h2
-rw-r--r--WebCore/platform/graphics/mac/ColorMac.mm48
-rw-r--r--WebCore/platform/graphics/mac/CoreTextController.cpp32
-rw-r--r--WebCore/platform/graphics/mac/CoreTextController.h4
-rw-r--r--WebCore/platform/graphics/mac/FontCacheMac.mm16
-rw-r--r--WebCore/platform/graphics/mac/FontMac.mm16
-rw-r--r--WebCore/platform/graphics/mac/FontMacATSUI.mm49
-rw-r--r--WebCore/platform/graphics/mac/FontMacCoreText.cpp4
-rw-r--r--WebCore/platform/graphics/mac/FontPlatformData.h2
-rw-r--r--WebCore/platform/graphics/mac/GraphicsContextMac.mm11
-rw-r--r--WebCore/platform/graphics/mac/GraphicsLayerCA.h3
-rw-r--r--WebCore/platform/graphics/mac/GraphicsLayerCA.mm98
-rw-r--r--WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h6
-rw-r--r--WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm294
-rw-r--r--WebCore/platform/graphics/mac/SimpleFontDataMac.mm105
-rw-r--r--WebCore/platform/graphics/mac/WebLayer.mm1
-rw-r--r--WebCore/platform/graphics/opentype/OpenTypeUtilities.cpp46
-rw-r--r--WebCore/platform/graphics/opentype/OpenTypeUtilities.h21
-rw-r--r--WebCore/platform/graphics/qt/FontCacheQt.cpp35
-rw-r--r--WebCore/platform/graphics/qt/FontFallbackListQt.cpp12
-rw-r--r--WebCore/platform/graphics/qt/FontQt.cpp2
-rw-r--r--WebCore/platform/graphics/qt/GraphicsContextQt.cpp26
-rw-r--r--WebCore/platform/graphics/qt/IconQt.cpp1
-rw-r--r--WebCore/platform/graphics/qt/ImageBufferQt.cpp19
-rw-r--r--WebCore/platform/graphics/qt/ImageDecoderQt.cpp13
-rw-r--r--WebCore/platform/graphics/qt/ImageDecoderQt.h3
-rw-r--r--WebCore/platform/graphics/qt/ImageQt.cpp8
-rw-r--r--WebCore/platform/graphics/qt/ImageSourceQt.cpp1
-rw-r--r--WebCore/platform/graphics/qt/PathQt.cpp5
-rw-r--r--WebCore/platform/graphics/qt/SimpleFontDataQt.cpp11
-rw-r--r--WebCore/platform/graphics/skia/GradientSkia.cpp4
-rw-r--r--WebCore/platform/graphics/skia/GraphicsContextSkia.cpp40
-rw-r--r--WebCore/platform/graphics/skia/ImageBufferSkia.cpp1
-rw-r--r--WebCore/platform/graphics/skia/ImageSkia.cpp16
-rw-r--r--WebCore/platform/graphics/skia/PathSkia.cpp12
-rw-r--r--WebCore/platform/graphics/skia/PlatformContextSkia.cpp13
-rw-r--r--WebCore/platform/graphics/skia/PlatformContextSkia.h1
-rw-r--r--WebCore/platform/graphics/skia/SkiaFontWin.cpp12
-rw-r--r--WebCore/platform/graphics/skia/SkiaFontWin.h6
-rw-r--r--WebCore/platform/graphics/skia/SkiaUtils.cpp9
-rw-r--r--WebCore/platform/graphics/transforms/TransformationMatrix.cpp65
-rw-r--r--WebCore/platform/graphics/transforms/TransformationMatrix.h21
-rw-r--r--WebCore/platform/graphics/win/ColorSafari.cpp1
-rw-r--r--WebCore/platform/graphics/win/FontCGWin.cpp26
-rw-r--r--WebCore/platform/graphics/win/FontCustomPlatformData.cpp6
-rw-r--r--WebCore/platform/graphics/win/FontWin.cpp10
-rw-r--r--WebCore/platform/graphics/win/GraphicsContextCGWin.cpp1
-rw-r--r--WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp180
-rw-r--r--WebCore/platform/graphics/win/ImageCairoWin.cpp20
-rw-r--r--WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp54
-rw-r--r--WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h3
-rw-r--r--WebCore/platform/graphics/win/QTMovieWin.cpp94
-rw-r--r--WebCore/platform/graphics/win/QTMovieWin.h4
-rw-r--r--WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp26
-rw-r--r--WebCore/platform/graphics/win/SimpleFontDataCairoWin.cpp30
-rw-r--r--WebCore/platform/graphics/win/SimpleFontDataWin.cpp22
-rw-r--r--WebCore/platform/graphics/win/UniscribeController.cpp25
-rw-r--r--WebCore/platform/graphics/win/UniscribeController.h3
-rw-r--r--WebCore/platform/graphics/wx/FontWx.cpp7
-rw-r--r--WebCore/platform/graphics/wx/ImageSourceWx.cpp10
-rw-r--r--WebCore/platform/graphics/wx/ImageWx.cpp46
-rw-r--r--WebCore/platform/graphics/wx/PathWx.cpp5
-rw-r--r--WebCore/platform/graphics/wx/SimpleFontDataWx.cpp15
-rw-r--r--WebCore/platform/graphics/wx/TransformationMatrixWx.cpp2
150 files changed, 2714 insertions, 897 deletions
diff --git a/WebCore/platform/graphics/BitmapImage.cpp b/WebCore/platform/graphics/BitmapImage.cpp
index 1d97632..2f9412d 100644
--- a/WebCore/platform/graphics/BitmapImage.cpp
+++ b/WebCore/platform/graphics/BitmapImage.cpp
@@ -95,7 +95,7 @@ void BitmapImage::destroyDecodedDataIfNecessary(bool destroyAll)
// Animated images >5MB are considered large enough that we'll only hang on
// to one frame at a time.
static const unsigned cLargeAnimationCutoff = 5242880;
- if (frameCount() * frameBytes(m_size) > cLargeAnimationCutoff)
+ if (m_frames.size() * frameBytes(m_size) > cLargeAnimationCutoff)
destroyDecodedData(destroyAll);
}
diff --git a/WebCore/platform/graphics/BitmapImage.h b/WebCore/platform/graphics/BitmapImage.h
index db05d1c..a2de5d7 100644
--- a/WebCore/platform/graphics/BitmapImage.h
+++ b/WebCore/platform/graphics/BitmapImage.h
@@ -44,11 +44,6 @@ class NSImage;
typedef struct HBITMAP__ *HBITMAP;
#endif
-#if PLATFORM(SGL)
-class SkBitmap;
-class SkBitmapRef;
-#endif
-
namespace WebCore {
struct FrameData;
}
@@ -146,10 +141,13 @@ public:
#endif
#if PLATFORM(SGL)
-// virtual SkBitmapRef* getBitmap();
virtual void setURL(const String& str);
#endif
+#if PLATFORM(GTK)
+ virtual GdkPixbuf* getGdkPixbuf();
+#endif
+
virtual NativeImagePtr nativeImageForCurrentFrame() { return frameAtIndex(currentFrame()); }
protected:
diff --git a/WebCore/platform/graphics/Color.cpp b/WebCore/platform/graphics/Color.cpp
index e85ac00..d98b202 100644
--- a/WebCore/platform/graphics/Color.cpp
+++ b/WebCore/platform/graphics/Color.cpp
@@ -321,6 +321,41 @@ void Color::getRGBA(double& r, double& g, double& b, double& a) const
a = alpha() / 255.0;
}
+void Color::getHSL(double& hue, double& saturation, double& lightness) const
+{
+ // http://en.wikipedia.org/wiki/HSL_color_space. This is a direct copy of
+ // the algorithm therein, although it's 360^o based and we end up wanting
+ // [0...1) based. It's clearer if we stick to 360^o until the end.
+ double r = static_cast<double>(red()) / 255.0;
+ double g = static_cast<double>(green()) / 255.0;
+ double b = static_cast<double>(blue()) / 255.0;
+ double max = std::max(std::max(r, g), b);
+ double min = std::min(std::min(r, g), b);
+
+ if (max == min)
+ hue = 0.0;
+ else if (max == r)
+ hue = (60.0 * ((g - b) / (max - min))) + 360.0;
+ else if (max == g)
+ hue = (60.0 * ((b - r) / (max - min))) + 120.0;
+ else
+ hue = (60.0 * ((r - g) / (max - min))) + 240.0;
+
+ if (hue >= 360.0)
+ hue -= 360.0;
+
+ // makeRGBAFromHSLA assumes that hue is in [0...1).
+ hue /= 360.0;
+
+ lightness = 0.5 * (max + min);
+ if (max == min)
+ saturation = 0.0;
+ else if (lightness <= 0.5)
+ saturation = ((max - min) / (max + min));
+ else
+ saturation = ((max - min) / (2.0 - (max + min)));
+}
+
Color colorFromPremultipliedARGB(unsigned pixelColor)
{
RGBA32 rgba;
diff --git a/WebCore/platform/graphics/Color.h b/WebCore/platform/graphics/Color.h
index 3c889f9..3b815d2 100644
--- a/WebCore/platform/graphics/Color.h
+++ b/WebCore/platform/graphics/Color.h
@@ -94,6 +94,7 @@ public:
void setRGB(RGBA32 rgb) { m_color = rgb; m_valid = true; }
void getRGBA(float& r, float& g, float& b, float& a) const;
void getRGBA(double& r, double& g, double& b, double& a) const;
+ void getHSL(double& h, double& s, double& l) const;
Color light() const;
Color dark() const;
diff --git a/WebCore/platform/graphics/FloatQuad.cpp b/WebCore/platform/graphics/FloatQuad.cpp
index a32d8ab..427230d 100644
--- a/WebCore/platform/graphics/FloatQuad.cpp
+++ b/WebCore/platform/graphics/FloatQuad.cpp
@@ -46,6 +46,34 @@ static inline float max4(float a, float b, float c, float d)
return max(max(a, b), max(c, d));
}
+inline float dot(const FloatSize& a, const FloatSize& b)
+{
+ return a.width() * b.width() + a.height() * b.height();
+}
+
+inline bool isPointInTriangle(const FloatPoint& p, const FloatPoint& t1, const FloatPoint& t2, const FloatPoint& t3)
+{
+ // Compute vectors
+ FloatSize v0 = t3 - t1;
+ FloatSize v1 = t2 - t1;
+ FloatSize v2 = p - t1;
+
+ // Compute dot products
+ float dot00 = dot(v0, v0);
+ float dot01 = dot(v0, v1);
+ float dot02 = dot(v0, v2);
+ float dot11 = dot(v1, v1);
+ float dot12 = dot(v1, v2);
+
+ // Compute barycentric coordinates
+ float invDenom = 1.0f / (dot00 * dot11 - dot01 * dot01);
+ float u = (dot11 * dot02 - dot01 * dot12) * invDenom;
+ float v = (dot00 * dot12 - dot01 * dot02) * invDenom;
+
+ // Check if point is in triangle
+ return (u >= 0) && (v >= 0) && (u + v <= 1);
+}
+
FloatRect FloatQuad::boundingBox() const
{
float left = min4(m_p1.x(), m_p2.x(), m_p3.x(), m_p4.x());
@@ -57,4 +85,15 @@ FloatRect FloatQuad::boundingBox() const
return FloatRect(left, top, right - left, bottom - top);
}
+bool FloatQuad::containsPoint(const FloatPoint& p) const
+{
+ return isPointInTriangle(p, m_p1, m_p2, m_p3) || isPointInTriangle(p, m_p1, m_p3, m_p4);
+}
+
+// Note that we only handle convex quads here.
+bool FloatQuad::containsQuad(const FloatQuad& other) const
+{
+ return containsPoint(other.p1()) && containsPoint(other.p2()) && containsPoint(other.p3()) && containsPoint(other.p4());
+}
+
} // namespace WebCore
diff --git a/WebCore/platform/graphics/FloatQuad.h b/WebCore/platform/graphics/FloatQuad.h
index e05b27d..5982967 100644
--- a/WebCore/platform/graphics/FloatQuad.h
+++ b/WebCore/platform/graphics/FloatQuad.h
@@ -74,6 +74,14 @@ public:
// "slanted" empty quads.
bool isEmpty() const { return boundingBox().isEmpty(); }
+ // Tests whether the given point is inside, or on an edge or corner of this quad.
+ bool containsPoint(const FloatPoint&) const;
+
+ // Tests whether the four corners of other are inside, or coincident with the sides of this quad.
+ // Note that this only works for convex quads, but that includes all quads that originate
+ // from transformed rects.
+ bool containsQuad(const FloatQuad&) const;
+
FloatRect boundingBox() const;
IntRect enclosingBoundingBox() const
{
diff --git a/WebCore/platform/graphics/Font.cpp b/WebCore/platform/graphics/Font.cpp
index f8bec82..85fe882 100644
--- a/WebCore/platform/graphics/Font.cpp
+++ b/WebCore/platform/graphics/Font.cpp
@@ -32,6 +32,7 @@
#include "GlyphBuffer.h"
#include "WidthIterator.h"
#include <wtf/MathExtras.h>
+#include <wtf/UnusedParam.h>
using namespace WTF;
using namespace Unicode;
@@ -198,7 +199,7 @@ void Font::drawText(GraphicsContext* context, const TextRun& run, const FloatPoi
return drawComplexText(context, run, point, from, to);
}
-float Font::floatWidth(const TextRun& run) const
+float Font::floatWidth(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts) const
{
#if ENABLE(SVG_FONTS)
if (primaryFont()->isSVGFont())
@@ -206,16 +207,22 @@ float Font::floatWidth(const TextRun& run) const
#endif
#if USE(FONT_FAST_PATH)
- if (canUseGlyphCache(run))
- return floatWidthForSimpleText(run, 0);
+ if (canUseGlyphCache(run)) {
+ // 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);
+ }
#endif
- return floatWidthForComplexText(run);
+ return floatWidthForComplexText(run, fallbackFonts);
}
float Font::floatWidth(const TextRun& run, int extraCharsAvailable, int& charsConsumed, String& glyphName) const
{
-#if ENABLE(SVG_FONTS)
+#if !ENABLE(SVG_FONTS)
+ UNUSED_PARAM(extraCharsAvailable);
+#else
if (primaryFont()->isSVGFont())
return floatWidthUsingSVGFont(run, extraCharsAvailable, charsConsumed, glyphName);
#endif
@@ -275,4 +282,17 @@ FontSelector* Font::fontSelector() const
return m_fontList ? m_fontList->fontSelector() : 0;
}
+static bool shouldUseFontSmoothing = true;
+
+void Font::setShouldUseSmoothing(bool shouldUseSmoothing)
+{
+ ASSERT(isMainThread());
+ shouldUseFontSmoothing = shouldUseSmoothing;
+}
+
+bool Font::shouldUseSmoothing()
+{
+ return shouldUseFontSmoothing;
+}
+
}
diff --git a/WebCore/platform/graphics/Font.h b/WebCore/platform/graphics/Font.h
index 1bfee8f..8d85d8b 100644
--- a/WebCore/platform/graphics/Font.h
+++ b/WebCore/platform/graphics/Font.h
@@ -78,8 +78,8 @@ public:
void drawText(GraphicsContext*, const TextRun&, const FloatPoint&, int from = 0, int to = -1) const;
- int width(const TextRun& run) const { return lroundf(floatWidth(run)); }
- float floatWidth(const TextRun&) 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;
float floatWidth(const TextRun& run, int extraCharsAvailable, int& charsConsumed, String& glyphName) const;
int offsetForPosition(const TextRun&, int position, bool includePartialGlyphs) const;
@@ -112,17 +112,19 @@ public:
int lineGap() const { return primaryFont()->lineGap(); }
float xHeight() const { return primaryFont()->xHeight(); }
unsigned unitsPerEm() const { return primaryFont()->unitsPerEm(); }
- int spaceWidth() const { return (int)ceilf(primaryFont()->m_adjustedSpaceWidth + m_letterSpacing); }
+ int spaceWidth() const { return (int)ceilf(primaryFont()->adjustedSpaceWidth() + m_letterSpacing); }
int tabWidth() const { return 8 * spaceWidth(); }
- const SimpleFontData* primaryFont() const {
+ const SimpleFontData* primaryFont() const
+ {
+ ASSERT(isMainThread());
if (!m_cachedPrimaryFont)
cachePrimaryFont();
return m_cachedPrimaryFont;
}
const FontData* fontDataAt(unsigned) const;
- const GlyphData& glyphDataForCharacter(UChar32, bool mirror, bool forceSmallCaps = false) const;
+ GlyphData glyphDataForCharacter(UChar32, bool mirror, bool forceSmallCaps = false) const;
// Used for complex text, and does not utilize the glyph map cache.
const FontData* fontDataForCharacters(const UChar*, int length) const;
@@ -130,6 +132,9 @@ public:
QFont font() const;
#endif
+ static void setShouldUseSmoothing(bool);
+ static bool shouldUseSmoothing();
+
private:
#if ENABLE(SVG_FONTS)
void drawTextUsingSVGFont(GraphicsContext*, const TextRun&, const FloatPoint&, int from, int to) const;
@@ -144,13 +149,15 @@ private:
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*) const;
+ float floatWidthForSimpleText(const TextRun&, GlyphBuffer*, HashSet<const SimpleFontData*>* fallbackFonts = 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
void drawComplexText(GraphicsContext*, const TextRun&, const FloatPoint&, int from, int to) const;
- float floatWidthForComplexText(const TextRun&) const;
+ float floatWidthForComplexText(const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0) const;
int offsetForPositionForComplexText(const TextRun&, int position, bool includePartialGlyphs) const;
FloatRect selectionRectForComplexText(const TextRun&, const IntPoint&, int h, int from, int to) const;
void cachePrimaryFont() const;
diff --git a/WebCore/platform/graphics/FontCache.cpp b/WebCore/platform/graphics/FontCache.cpp
index 130313d..d9b4b28 100644
--- a/WebCore/platform/graphics/FontCache.cpp
+++ b/WebCore/platform/graphics/FontCache.cpp
@@ -307,12 +307,13 @@ void FontCache::purgeInactiveFontData(int count)
isPurging = true;
+ Vector<const SimpleFontData*, 20> fontDataToDelete;
ListHashSet<const SimpleFontData*>::iterator end = gInactiveFontData->end();
ListHashSet<const SimpleFontData*>::iterator it = gInactiveFontData->begin();
for (int i = 0; i < count && it != end; ++it, ++i) {
const SimpleFontData* fontData = *it.get();
gFontDataCache->remove(fontData->platformData());
- delete fontData;
+ fontDataToDelete.append(fontData);
}
if (it == end) {
@@ -323,6 +324,10 @@ void FontCache::purgeInactiveFontData(int count)
gInactiveFontData->remove(gInactiveFontData->begin());
}
+ size_t fontDataToDeleteCount = fontDataToDelete.size();
+ for (size_t i = 0; i < fontDataToDeleteCount; ++i)
+ delete fontDataToDelete[i];
+
Vector<FontPlatformDataCacheKey> keysToRemove;
keysToRemove.reserveInitialCapacity(gFontPlatformDataCache->size());
FontPlatformDataCache::iterator platformDataEnd = gFontPlatformDataCache->end();
diff --git a/WebCore/platform/graphics/FontCache.h b/WebCore/platform/graphics/FontCache.h
index 8820045..3c0f2d9 100644
--- a/WebCore/platform/graphics/FontCache.h
+++ b/WebCore/platform/graphics/FontCache.h
@@ -85,6 +85,7 @@ public:
private:
FontCache();
+ ~FontCache();
// These methods are implemented by each platform.
FontPlatformData* getSimilarFontPlatformData(const Font&);
diff --git a/WebCore/platform/graphics/FontDescription.h b/WebCore/platform/graphics/FontDescription.h
index d13e86a..c893b8a 100644
--- a/WebCore/platform/graphics/FontDescription.h
+++ b/WebCore/platform/graphics/FontDescription.h
@@ -81,7 +81,7 @@ public:
GenericFamilyType genericFamily() const { return static_cast<GenericFamilyType>(m_genericFamily); }
bool usePrinterFont() const { return m_usePrinterFont; }
FontRenderingMode renderingMode() const { return static_cast<FontRenderingMode>(m_renderingMode); }
- int keywordSize() const { return m_keywordSize; }
+ unsigned keywordSize() const { return m_keywordSize; }
FontTraitsMask traitsMask() const;
@@ -95,7 +95,7 @@ public:
void setGenericFamily(GenericFamilyType genericFamily) { m_genericFamily = genericFamily; }
void setUsePrinterFont(bool p) { m_usePrinterFont = p; }
void setRenderingMode(FontRenderingMode mode) { m_renderingMode = mode; }
- void setKeywordSize(int s) { m_keywordSize = s; }
+ void setKeywordSize(unsigned s) { m_keywordSize = s; }
private:
FontFamily m_familyList; // The list of font families to be used.
@@ -114,7 +114,7 @@ private:
unsigned m_renderingMode : 1; // Used to switch between CG and GDI text on Windows.
- int m_keywordSize : 4; // We cache whether or not a font is currently represented by a CSS keyword (e.g., medium). If so,
+ unsigned m_keywordSize : 4; // We cache whether or not a font is currently represented by a CSS keyword (e.g., medium). If so,
// then we can accurately translate across different generic families to adjust for different preference settings
// (e.g., 13px monospace vs. 16px everything else). Sizes are 1-8 (like the HTML size values for <font>).
};
diff --git a/WebCore/platform/graphics/FontFallbackList.cpp b/WebCore/platform/graphics/FontFallbackList.cpp
index 06d52d7..decacc5 100644
--- a/WebCore/platform/graphics/FontFallbackList.cpp
+++ b/WebCore/platform/graphics/FontFallbackList.cpp
@@ -36,10 +36,10 @@
namespace WebCore {
FontFallbackList::FontFallbackList()
- : m_familyIndex(0)
+ : m_fontSelector(0)
+ , m_familyIndex(0)
, m_pitch(UnknownPitch)
, m_loadingCustomFonts(false)
- , m_fontSelector(0)
, m_generation(fontCache()->generation())
{
}
diff --git a/WebCore/platform/graphics/FontFallbackList.h b/WebCore/platform/graphics/FontFallbackList.h
index a23b32c..07938ae 100644
--- a/WebCore/platform/graphics/FontFallbackList.h
+++ b/WebCore/platform/graphics/FontFallbackList.h
@@ -66,10 +66,10 @@ private:
void releaseFontData();
mutable Vector<pair<const FontData*, bool>, 1> m_fontList;
+ RefPtr<FontSelector> m_fontSelector;
mutable int m_familyIndex;
mutable Pitch m_pitch;
mutable bool m_loadingCustomFonts;
- RefPtr<FontSelector> m_fontSelector;
unsigned m_generation;
friend class Font;
diff --git a/WebCore/platform/graphics/FontFastPath.cpp b/WebCore/platform/graphics/FontFastPath.cpp
index 635aba9..deac1b6 100644
--- a/WebCore/platform/graphics/FontFastPath.cpp
+++ b/WebCore/platform/graphics/FontFastPath.cpp
@@ -39,11 +39,13 @@ using namespace Unicode;
namespace WebCore {
-const GlyphData& Font::glyphDataForCharacter(UChar32 c, bool mirror, bool forceSmallCaps) const
+GlyphData Font::glyphDataForCharacter(UChar32 c, bool mirror, bool forceSmallCaps) const
{
+ ASSERT(isMainThread());
+
bool useSmallCapsFont = forceSmallCaps;
if (m_fontDescription.smallCaps()) {
- UChar32 upperC = Unicode::toUpper(c);
+ UChar32 upperC = toUpper(c);
if (upperC != c) {
c = upperC;
useSmallCapsFont = true;
@@ -70,7 +72,7 @@ const GlyphData& Font::glyphDataForCharacter(UChar32 c, bool mirror, bool forceS
while (true) {
page = node->page();
if (page) {
- const GlyphData& data = page->glyphDataForCharacter(c);
+ GlyphData data = page->glyphDataForCharacter(c);
if (data.fontData)
return data;
if (node->isSystemFallback())
@@ -88,7 +90,7 @@ const GlyphData& Font::glyphDataForCharacter(UChar32 c, bool mirror, bool forceS
while (true) {
page = node->page();
if (page) {
- const GlyphData& data = page->glyphDataForCharacter(c);
+ GlyphData data = page->glyphDataForCharacter(c);
if (data.fontData) {
// The smallCapsFontData function should not normally return 0.
// But if it does, we will just render the capital letter big.
@@ -99,7 +101,7 @@ const GlyphData& Font::glyphDataForCharacter(UChar32 c, bool mirror, bool forceS
GlyphPageTreeNode* smallCapsNode = GlyphPageTreeNode::getRootChild(smallCapsFontData, pageNumber);
const GlyphPage* smallCapsPage = smallCapsNode->page();
if (smallCapsPage) {
- const GlyphData& data = smallCapsPage->glyphDataForCharacter(c);
+ GlyphData data = smallCapsPage->glyphDataForCharacter(c);
if (data.fontData)
return data;
}
@@ -150,7 +152,7 @@ const GlyphData& Font::glyphDataForCharacter(UChar32 c, bool mirror, bool forceS
if (characterFontData) {
// Got the fallback glyph and font.
GlyphPage* fallbackPage = GlyphPageTreeNode::getRootChild(characterFontData, pageNumber)->page();
- const GlyphData& data = fallbackPage && fallbackPage->glyphDataForCharacter(c).fontData ? fallbackPage->glyphDataForCharacter(c) : characterFontData->missingGlyphData();
+ 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)
page->setGlyphDataForCharacter(c, data.glyph, data.fontData);
@@ -159,7 +161,7 @@ const GlyphData& Font::glyphDataForCharacter(UChar32 c, bool mirror, bool forceS
// 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.
- const GlyphData& data = primaryFont()->missingGlyphData();
+ GlyphData data = primaryFont()->missingGlyphData();
if (!useSmallCapsFont)
page->setGlyphDataForCharacter(c, data.glyph, data.fontData);
return data;
@@ -296,9 +298,9 @@ void Font::drawGlyphBuffer(GraphicsContext* context, const GlyphBuffer& glyphBuf
drawGlyphs(context, fontData, glyphBuffer, lastFrom, nextGlyph - lastFrom, startPoint);
}
-float Font::floatWidthForSimpleText(const TextRun& run, GlyphBuffer* glyphBuffer) const
+float Font::floatWidthForSimpleText(const TextRun& run, GlyphBuffer* glyphBuffer, HashSet<const SimpleFontData*>* fallbackFonts) const
{
- WidthIterator it(this, run);
+ WidthIterator it(this, run, fallbackFonts);
it.advance(run.length(), glyphBuffer);
return it.m_runWidthSoFar;
}
diff --git a/WebCore/platform/graphics/GeneratedImage.cpp b/WebCore/platform/graphics/GeneratedImage.cpp
index 15e27d7..c40a40a 100644
--- a/WebCore/platform/graphics/GeneratedImage.cpp
+++ b/WebCore/platform/graphics/GeneratedImage.cpp
@@ -51,7 +51,7 @@ void GeneratedImage::drawPattern(GraphicsContext* context, const FloatRect& srcR
const FloatPoint& phase, CompositeOperator compositeOp, const FloatRect& destRect)
{
// Create a BitmapImage and call drawPattern on it.
- auto_ptr<ImageBuffer> imageBuffer = ImageBuffer::create(m_size, false);
+ OwnPtr<ImageBuffer> imageBuffer = ImageBuffer::create(m_size, false);
ASSERT(imageBuffer.get());
// Fill with the gradient.
diff --git a/WebCore/platform/graphics/GlyphPageTreeNode.cpp b/WebCore/platform/graphics/GlyphPageTreeNode.cpp
index bd838de..a34a192 100644
--- a/WebCore/platform/graphics/GlyphPageTreeNode.cpp
+++ b/WebCore/platform/graphics/GlyphPageTreeNode.cpp
@@ -220,8 +220,8 @@ void GlyphPageTreeNode::initializePage(const FontData* fontData, unsigned pageNu
if (scratchPage) {
ASSERT(to <= static_cast<int>(GlyphPage::size));
for (int j = from; j < to; j++) {
- if (!m_page->m_glyphs[j].glyph && pageToFill->m_glyphs[j].glyph)
- m_page->m_glyphs[j] = pageToFill->m_glyphs[j];
+ if (!m_page->glyphAt(j) && pageToFill->glyphAt(j))
+ m_page->setGlyphDataForIndex(j, pageToFill->glyphDataForIndex(j));
}
}
}
@@ -265,15 +265,13 @@ void GlyphPageTreeNode::initializePage(const FontData* fontData, unsigned pageNu
// has added anything.
bool newGlyphs = false;
for (unsigned i = 0; i < GlyphPage::size; i++) {
- if (parentPage->m_glyphs[i].glyph)
- m_page->m_glyphs[i] = parentPage->m_glyphs[i];
- else if (fallbackPage->m_glyphs[i].glyph) {
- m_page->m_glyphs[i] = fallbackPage->m_glyphs[i];
+ if (parentPage->glyphAt(i))
+ m_page->setGlyphDataForIndex(i, parentPage->glyphDataForIndex(i));
+ else if (fallbackPage->glyphAt(i)) {
+ m_page->setGlyphDataForIndex(i, fallbackPage->glyphDataForIndex(i));
newGlyphs = true;
- } else {
- const GlyphData data = { 0, 0 };
- m_page->m_glyphs[i] = data;
- }
+ } else
+ m_page->setGlyphDataForIndex(i, 0, 0);
}
if (!newGlyphs)
@@ -288,12 +286,9 @@ void GlyphPageTreeNode::initializePage(const FontData* fontData, unsigned pageNu
// ever finds it needs a glyph out of the system fallback page, it will
// ask the system for the best font to use and fill that glyph in for us.
if (parentPage)
- memcpy(m_page->m_glyphs, parentPage->m_glyphs, GlyphPage::size * sizeof(m_page->m_glyphs[0]));
- else {
- const GlyphData data = { 0, 0 };
- for (unsigned i = 0; i < GlyphPage::size; i++)
- m_page->m_glyphs[i] = data;
- }
+ m_page->copyFrom(*parentPage);
+ else
+ m_page->clear();
}
}
diff --git a/WebCore/platform/graphics/GlyphPageTreeNode.h b/WebCore/platform/graphics/GlyphPageTreeNode.h
index 240b492..80e87aa 100644
--- a/WebCore/platform/graphics/GlyphPageTreeNode.h
+++ b/WebCore/platform/graphics/GlyphPageTreeNode.h
@@ -29,6 +29,7 @@
#ifndef GlyphPageTreeNode_h
#define GlyphPageTreeNode_h
+#include <string.h>
#include <wtf/HashMap.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
@@ -45,6 +46,11 @@ typedef unsigned short Glyph;
// Holds the glyph index and the corresponding SimpleFontData information for a given
// character.
struct GlyphData {
+ GlyphData(Glyph g = 0, const SimpleFontData* f = 0)
+ : glyph(g)
+ , fontData(f)
+ {
+ }
Glyph glyph;
const SimpleFontData* fontData;
};
@@ -54,30 +60,69 @@ struct GlyphData {
// starting from 0 and incrementing for each 256 glyphs.
//
// One page may actually include glyphs from other fonts if the characters are
-// missing in the parimary font. It is owned by exactly one GlyphPageTreeNode,
+// missing in the primary font. It is owned by exactly one GlyphPageTreeNode,
// although multiple nodes may reference it as their "page" if they are supposed
// to be overriding the parent's node, but provide no additional information.
-struct GlyphPage : public RefCounted<GlyphPage> {
+class GlyphPage : public RefCounted<GlyphPage> {
+public:
static PassRefPtr<GlyphPage> create(GlyphPageTreeNode* owner)
{
return adoptRef(new GlyphPage(owner));
}
static const size_t size = 256; // Covers Latin-1 in a single page.
- GlyphData m_glyphs[size];
- GlyphPageTreeNode* m_owner;
- const GlyphData& glyphDataForCharacter(UChar32 c) const { return m_glyphs[c % size]; }
+ unsigned indexForCharacter(UChar32 c) const { return c % size; }
+ GlyphData glyphDataForCharacter(UChar32 c) const
+ {
+ unsigned index = indexForCharacter(c);
+ return GlyphData(m_glyphs[index], m_glyphFontData[index]);
+ }
+
+ GlyphData glyphDataForIndex(unsigned index) const
+ {
+ ASSERT(index < size);
+ return GlyphData(m_glyphs[index], m_glyphFontData[index]);
+ }
+
+ Glyph glyphAt(unsigned index) const
+ {
+ ASSERT(index < size);
+ return m_glyphs[index];
+ }
+
+ const SimpleFontData* fontDataForCharacter(UChar32 c) const
+ {
+ return m_glyphFontData[indexForCharacter(c)];
+ }
+
void setGlyphDataForCharacter(UChar32 c, Glyph g, const SimpleFontData* f)
{
- setGlyphDataForIndex(c % size, g, f);
+ setGlyphDataForIndex(indexForCharacter(c), g, f);
}
void setGlyphDataForIndex(unsigned index, Glyph g, const SimpleFontData* f)
{
ASSERT(index < size);
- m_glyphs[index].glyph = g;
- m_glyphs[index].fontData = f;
+ m_glyphs[index] = g;
+ m_glyphFontData[index] = f;
+ }
+ void setGlyphDataForIndex(unsigned index, const GlyphData& glyphData)
+ {
+ setGlyphDataForIndex(index, glyphData.glyph, glyphData.fontData);
+ }
+
+ void copyFrom(const GlyphPage& other)
+ {
+ memcpy(m_glyphs, other.m_glyphs, sizeof(m_glyphs));
+ memcpy(m_glyphFontData, other.m_glyphFontData, sizeof(m_glyphFontData));
+ }
+
+ void clear()
+ {
+ memset(m_glyphs, 0, sizeof(m_glyphs));
+ memset(m_glyphFontData, 0, sizeof(m_glyphFontData));
}
+
GlyphPageTreeNode* owner() const { return m_owner; }
// Implemented by the platform.
@@ -88,6 +133,12 @@ private:
: m_owner(owner)
{
}
+
+ // Separate arrays, rather than array of GlyphData, to save space.
+ Glyph m_glyphs[size];
+ const SimpleFontData* m_glyphFontData[size];
+
+ GlyphPageTreeNode* m_owner;
};
// The glyph page tree is a data structure that maps (FontData, glyph page number)
diff --git a/WebCore/platform/graphics/Gradient.cpp b/WebCore/platform/graphics/Gradient.cpp
index 24e8bbf..51c7162 100644
--- a/WebCore/platform/graphics/Gradient.cpp
+++ b/WebCore/platform/graphics/Gradient.cpp
@@ -52,6 +52,7 @@ Gradient::Gradient(const FloatPoint& p0, float r0, const FloatPoint& p1, float r
, m_r1(r1)
, m_stopsSorted(false)
, m_lastStop(0)
+ , m_spreadMethod(SpreadMethodPad)
{
platformInit();
}
diff --git a/WebCore/platform/graphics/GraphicsContext.cpp b/WebCore/platform/graphics/GraphicsContext.cpp
index 8cad794..4dae3d2 100644
--- a/WebCore/platform/graphics/GraphicsContext.cpp
+++ b/WebCore/platform/graphics/GraphicsContext.cpp
@@ -30,7 +30,6 @@
#include "Generator.h"
#include "GraphicsContextPrivate.h"
#include "Font.h"
-#include "NotImplemented.h"
using namespace std;
@@ -337,7 +336,7 @@ void GraphicsContext::drawBidiText(const Font& font, const TextRun& run, const F
BidiResolver<TextRunIterator, BidiCharacterRun> bidiResolver;
WTF::Unicode::Direction paragraphDirection = run.ltr() ? WTF::Unicode::LeftToRight : WTF::Unicode::RightToLeft;
- bidiResolver.setStatus(BidiStatus(paragraphDirection, paragraphDirection, paragraphDirection, new BidiContext(run.ltr() ? 0 : 1, paragraphDirection, run.directionalOverride())));
+ bidiResolver.setStatus(BidiStatus(paragraphDirection, paragraphDirection, paragraphDirection, BidiContext::create(run.ltr() ? 0 : 1, paragraphDirection, run.directionalOverride())));
bidiResolver.setPosition(TextRunIterator(&run, 0));
bidiResolver.createBidiRunsForLine(TextRunIterator(&run, run.length()));
diff --git a/WebCore/platform/graphics/GraphicsContext.h b/WebCore/platform/graphics/GraphicsContext.h
index 7c1c4b0..3fdafad 100644
--- a/WebCore/platform/graphics/GraphicsContext.h
+++ b/WebCore/platform/graphics/GraphicsContext.h
@@ -374,6 +374,7 @@ namespace WebCore {
#if PLATFORM(QT) && defined(Q_WS_WIN)
HDC getWindowsContext(const IntRect&, bool supportAlphaBlend = true, bool mayCreateBitmap = true);
void releaseWindowsContext(HDC, const IntRect&, bool supportAlphaBlend = true, bool mayCreateBitmap = true);
+ bool shouldIncludeChildWindows() const { return false; }
#endif
#if PLATFORM(QT)
diff --git a/WebCore/platform/graphics/GraphicsLayer.h b/WebCore/platform/graphics/GraphicsLayer.h
index f928ce8..ae51951 100644
--- a/WebCore/platform/graphics/GraphicsLayer.h
+++ b/WebCore/platform/graphics/GraphicsLayer.h
@@ -288,8 +288,10 @@ public:
int incrementRepaintCount() { return ++m_repaintCount; }
#endif
- // Platform behaviors
- static bool graphicsContextsFlipped();
+ // Report whether the underlying compositing system uses a top-down
+ // or a bottom-up coordinate system.
+ enum CompositingCoordinatesOrientation { CompositingCoordinatesTopDown, CompositingCoordinatesBottomUp };
+ static CompositingCoordinatesOrientation compositingCoordinatesOrientation();
#ifndef NDEBUG
static bool showDebugBorders();
diff --git a/WebCore/platform/graphics/Image.h b/WebCore/platform/graphics/Image.h
index 70f6d49..cff8b22 100644
--- a/WebCore/platform/graphics/Image.h
+++ b/WebCore/platform/graphics/Image.h
@@ -61,8 +61,8 @@ class NativeImageSkia;
#include <QPixmap>
#endif
-#if PLATFORM(SGL)
-class SkBitmapRef;
+#if PLATFORM(GTK)
+typedef struct _GdkPixbuf GdkPixbuf;
#endif
namespace WebCore {
@@ -147,10 +147,13 @@ public:
#endif
#if PLATFORM(SGL)
- virtual SkBitmapRef* getBitmap() { return 0; }
virtual void setURL(const String& str) {}
#endif
+#if PLATFORM(GTK)
+ virtual GdkPixbuf* getGdkPixbuf() { return 0; }
+#endif
+
protected:
Image(ImageObserver* = 0);
diff --git a/WebCore/platform/graphics/ImageBuffer.h b/WebCore/platform/graphics/ImageBuffer.h
index 14f7461..573e274 100644
--- a/WebCore/platform/graphics/ImageBuffer.h
+++ b/WebCore/platform/graphics/ImageBuffer.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
- * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -32,8 +32,8 @@
#include "IntSize.h"
#include "ImageBufferData.h"
#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
#include <wtf/PassRefPtr.h>
-#include <memory>
namespace WebCore {
@@ -46,13 +46,13 @@ namespace WebCore {
class ImageBuffer : Noncopyable {
public:
// Will return a null pointer on allocation failure.
- static std::auto_ptr<ImageBuffer> create(const IntSize& size, bool grayScale)
+ static PassOwnPtr<ImageBuffer> create(const IntSize& size, bool grayScale)
{
bool success = false;
- std::auto_ptr<ImageBuffer> buf(new ImageBuffer(size, grayScale, success));
+ OwnPtr<ImageBuffer> buf(new ImageBuffer(size, grayScale, success));
if (success)
- return buf;
- return std::auto_ptr<ImageBuffer>();
+ return buf.release();
+ return 0;
}
~ImageBuffer();
@@ -80,7 +80,7 @@ namespace WebCore {
OwnPtr<GraphicsContext> m_context;
mutable RefPtr<Image> m_image;
- // This constructor will place its succes into the given out-variable
+ // This constructor will place its success into the given out-variable
// so that create() knows when it should return failure.
ImageBuffer(const IntSize&, bool grayScale, bool& success);
};
diff --git a/WebCore/platform/graphics/ImageSource.h b/WebCore/platform/graphics/ImageSource.h
index 07cc2c2..d4a1658 100644
--- a/WebCore/platform/graphics/ImageSource.h
+++ b/WebCore/platform/graphics/ImageSource.h
@@ -31,6 +31,7 @@
#if PLATFORM(WX)
class wxBitmap;
+class wxGraphicsBitmap;
#elif PLATFORM(CG)
typedef struct CGImageSource* CGImageSourceRef;
typedef struct CGImage* CGImageRef;
@@ -61,7 +62,11 @@ class String;
class ImageDecoder;
typedef ImageDecoder* NativeImageSourcePtr;
typedef const Vector<char>* NativeBytePtr;
+#if USE(WXGC)
+typedef wxGraphicsBitmap* NativeImagePtr;
+#else
typedef wxBitmap* NativeImagePtr;
+#endif
#elif PLATFORM(CG)
typedef CGImageSourceRef NativeImageSourcePtr;
typedef CGImageRef NativeImagePtr;
diff --git a/WebCore/platform/graphics/IntPoint.h b/WebCore/platform/graphics/IntPoint.h
index a05b1f0..1bfeeaa 100644
--- a/WebCore/platform/graphics/IntPoint.h
+++ b/WebCore/platform/graphics/IntPoint.h
@@ -70,6 +70,7 @@ class IntPoint {
public:
IntPoint() : m_x(0), m_y(0) { }
IntPoint(int x, int y) : m_x(x), m_y(y) { }
+ explicit IntPoint(const IntSize& size) : m_x(size.width()), m_y(size.height()) { }
int x() const { return m_x; }
int y() const { return m_y; }
diff --git a/WebCore/platform/graphics/IntSize.h b/WebCore/platform/graphics/IntSize.h
index 4d36545..cac0bd1 100644
--- a/WebCore/platform/graphics/IntSize.h
+++ b/WebCore/platform/graphics/IntSize.h
@@ -73,6 +73,12 @@ public:
m_height += height;
}
+ void scale(float scale)
+ {
+ m_width = static_cast<int>(static_cast<float>(m_width) * scale);
+ m_height = static_cast<int>(static_cast<float>(m_height) * scale);
+ }
+
IntSize expandedTo(const IntSize& other) const
{
return IntSize(m_width > other.m_width ? m_width : other.m_width,
diff --git a/WebCore/platform/graphics/MediaPlayer.cpp b/WebCore/platform/graphics/MediaPlayer.cpp
index 99d6aa4..b580474 100644
--- a/WebCore/platform/graphics/MediaPlayer.cpp
+++ b/WebCore/platform/graphics/MediaPlayer.cpp
@@ -183,6 +183,7 @@ MediaPlayer::MediaPlayer(MediaPlayerClient* client)
, m_visible(false)
, m_rate(1.0f)
, m_volume(1.0f)
+ , m_autobuffer(false)
#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
, m_playerProxy(0)
#endif
@@ -206,11 +207,20 @@ void MediaPlayer::load(const String& url, const ContentType& contentType)
String type = contentType.type();
String codecs = contentType.parameter("codecs");
- // if we don't know the MIME type, see if the path can help
- if (type.isEmpty())
- type = MIMETypeRegistry::getMIMETypeForPath(url);
+ // if we don't know the MIME type, see if the extension can help
+ if (type.isEmpty() || type == "application/octet-stream" || type == "text/plain") {
+ int pos = url.reverseFind('.');
+ if (pos >= 0) {
+ String extension = url.substring(pos + 1);
+ String mediaType = MIMETypeRegistry::getMediaMIMETypeForExtension(extension);
+ if (!mediaType.isEmpty())
+ type = mediaType;
+ }
+ }
- MediaPlayerFactory* engine = chooseBestEngineForTypeAndCodecs(type, codecs);
+ MediaPlayerFactory* engine = 0;
+ if (!type.isEmpty())
+ engine = chooseBestEngineForTypeAndCodecs(type, codecs);
// if we didn't find an engine that claims the MIME type, just use the first engine
if (!engine)
@@ -260,6 +270,11 @@ float MediaPlayer::duration() const
return m_private->duration();
}
+float MediaPlayer::startTime() const
+{
+ return m_private->startTime();
+}
+
float MediaPlayer::currentTime() const
{
return m_private->currentTime();
@@ -382,6 +397,19 @@ void MediaPlayer::setVisible(bool b)
m_private->setVisible(b);
}
+bool MediaPlayer::autobuffer() const
+{
+ return m_autobuffer;
+}
+
+void MediaPlayer::setAutobuffer(bool b)
+{
+ if (m_autobuffer != b) {
+ m_autobuffer = b;
+ m_private->setAutobuffer(b);
+ }
+}
+
void MediaPlayer::paint(GraphicsContext* p, const IntRect& r)
{
m_private->paint(p, r);
diff --git a/WebCore/platform/graphics/MediaPlayer.h b/WebCore/platform/graphics/MediaPlayer.h
index 7d90e44..9b2f685 100644
--- a/WebCore/platform/graphics/MediaPlayer.h
+++ b/WebCore/platform/graphics/MediaPlayer.h
@@ -76,6 +76,11 @@ public:
// the movie size has changed
virtual void mediaPlayerSizeChanged(MediaPlayer*) { }
+
+ // The MediaPlayer has found potentially problematic media content.
+ // This is used internally to trigger swapping from a <video>
+ // element to an <embed> in standalone documents
+ virtual void mediaPlayerSawUnsupportedTracks(MediaPlayer*) { }
};
class MediaPlayer : Noncopyable {
@@ -88,7 +93,7 @@ public:
static MediaPlayer::SupportsType supportsType(ContentType contentType);
static void getSupportedTypes(HashSet<String>&);
static bool isAvailable();
-
+
IntSize naturalSize();
bool hasVideo();
@@ -114,6 +119,8 @@ public:
float duration() const;
float currentTime() const;
void seek(float time);
+
+ float startTime() const;
void setEndTime(float time);
@@ -131,7 +138,10 @@ public:
void setVolume(float);
int dataRate() const;
-
+
+ bool autobuffer() const;
+ void setAutobuffer(bool);
+
void paint(GraphicsContext*, const IntRect&);
enum NetworkState { Empty, Idle, Loading, Loaded, FormatError, NetworkError, DecodeError };
@@ -169,6 +179,7 @@ private:
bool m_visible;
float m_rate;
float m_volume;
+ bool m_autobuffer;
#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
WebMediaPlayerProxy* m_playerProxy; // not owned or used, passed to m_private
#endif
diff --git a/WebCore/platform/graphics/MediaPlayerPrivate.h b/WebCore/platform/graphics/MediaPlayerPrivate.h
index 2e73e7e..e17259c 100644
--- a/WebCore/platform/graphics/MediaPlayerPrivate.h
+++ b/WebCore/platform/graphics/MediaPlayerPrivate.h
@@ -58,7 +58,9 @@ public:
virtual void seek(float time) = 0;
virtual bool seeking() const = 0;
- virtual void setEndTime(float time) = 0;
+ virtual float startTime() const { return 0; }
+
+ virtual void setEndTime(float) = 0;
virtual void setRate(float) = 0;
virtual bool paused() const = 0;
@@ -81,6 +83,8 @@ public:
virtual void paint(GraphicsContext*, const IntRect&) = 0 ;
+ virtual void setAutobuffer(bool) { };
+
#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
virtual void setPoster(const String& url) = 0;
virtual void deliverNotification(MediaPlayerProxyNotificationType) = 0;
diff --git a/WebCore/platform/graphics/Path.cpp b/WebCore/platform/graphics/Path.cpp
index f3450be..e30703c 100644
--- a/WebCore/platform/graphics/Path.cpp
+++ b/WebCore/platform/graphics/Path.cpp
@@ -35,7 +35,7 @@
#include <math.h>
#include <wtf/MathExtras.h>
-const float QUARTER = 0.552f; // approximation of control point positions on a bezier
+static const float QUARTER = 0.552f; // approximation of control point positions on a bezier
// to simulate a quarter of a circle.
namespace WebCore {
diff --git a/WebCore/platform/graphics/SimpleFontData.cpp b/WebCore/platform/graphics/SimpleFontData.cpp
index 9f51037..bab7d99 100644
--- a/WebCore/platform/graphics/SimpleFontData.cpp
+++ b/WebCore/platform/graphics/SimpleFontData.cpp
@@ -32,18 +32,24 @@
#include "Font.h"
#include "FontCache.h"
+
#if ENABLE(SVG_FONTS)
#include "SVGFontData.h"
+#include "SVGFontElement.h"
#include "SVGFontFaceElement.h"
+#include "SVGGlyphElement.h"
#endif
#include <wtf/MathExtras.h>
+#include <wtf/UnusedParam.h>
+
+using namespace std;
namespace WebCore {
SimpleFontData::SimpleFontData(const FontPlatformData& f, bool customFont, bool loading, SVGFontData* svgFontData)
: m_unitsPerEm(defaultUnitsPerEm)
- , m_font(f)
+ , m_platformData(f)
, m_treatAsFixedPitch(false)
#if ENABLE(SVG_FONTS)
, m_svgFontData(svgFontData)
@@ -52,24 +58,40 @@ SimpleFontData::SimpleFontData(const FontPlatformData& f, bool customFont, bool
, m_isLoading(loading)
, m_smallCapsFontData(0)
{
-#if ENABLE(SVG_FONTS)
+#if !ENABLE(SVG_FONTS)
+ UNUSED_PARAM(svgFontData);
+#else
if (SVGFontFaceElement* svgFontFaceElement = svgFontData ? svgFontData->svgFontFaceElement() : 0) {
- m_unitsPerEm = svgFontFaceElement->unitsPerEm();
+ m_unitsPerEm = svgFontFaceElement->unitsPerEm();
- double scale = f.size();
- if (m_unitsPerEm)
- scale /= m_unitsPerEm;
+ double scale = f.size();
+ if (m_unitsPerEm)
+ scale /= m_unitsPerEm;
m_ascent = static_cast<int>(svgFontFaceElement->ascent() * scale);
m_descent = static_cast<int>(svgFontFaceElement->descent() * scale);
m_xHeight = static_cast<int>(svgFontFaceElement->xHeight() * scale);
m_lineGap = 0.1f * f.size();
m_lineSpacing = m_ascent + m_descent + m_lineGap;
-
+
+ SVGFontElement* associatedFontElement = svgFontFaceElement->associatedFontElement();
+
+ Vector<SVGGlyphIdentifier> spaceGlyphs;
+ associatedFontElement->getGlyphIdentifiersForString(String(" ", 1), spaceGlyphs);
+ m_spaceWidth = spaceGlyphs.isEmpty() ? m_xHeight : static_cast<float>(spaceGlyphs.first().horizontalAdvanceX * scale);
+
+ Vector<SVGGlyphIdentifier> numeralZeroGlyphs;
+ associatedFontElement->getGlyphIdentifiersForString(String("0", 1), numeralZeroGlyphs);
+ m_avgCharWidth = numeralZeroGlyphs.isEmpty() ? m_spaceWidth : static_cast<float>(numeralZeroGlyphs.first().horizontalAdvanceX * scale);
+
+ Vector<SVGGlyphIdentifier> letterWGlyphs;
+ associatedFontElement->getGlyphIdentifiersForString(String("W", 1), letterWGlyphs);
+ m_maxCharWidth = letterWGlyphs.isEmpty() ? m_ascent : static_cast<float>(letterWGlyphs.first().horizontalAdvanceX * scale);
+
+ // FIXME: is there a way we can get the space glyph from the SVGGlyphIdentifier above?
m_spaceGlyph = 0;
- m_spaceWidth = 0;
- m_adjustedSpaceWidth = 0;
determinePitch();
+ m_adjustedSpaceWidth = roundf(m_spaceWidth);
m_missingGlyphData.fontData = this;
m_missingGlyphData.glyph = 0;
return;
@@ -78,9 +100,31 @@ SimpleFontData::SimpleFontData(const FontPlatformData& f, bool customFont, bool
platformInit();
platformGlyphInit();
+ platformCharWidthInit();
}
#if !PLATFORM(QT)
+// Estimates of avgCharWidth and maxCharWidth for platforms that don't support accessing these values from the font.
+void SimpleFontData::initCharWidths()
+{
+ GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page();
+
+ // Treat the width of a '0' as the avgCharWidth.
+ if (m_avgCharWidth <= 0.f && glyphPageZero) {
+ static const UChar32 digitZeroChar = '0';
+ Glyph digitZeroGlyph = glyphPageZero->glyphDataForCharacter(digitZeroChar).glyph;
+ if (digitZeroGlyph)
+ m_avgCharWidth = widthForGlyph(digitZeroGlyph);
+ }
+
+ // If we can't retrieve the width of a '0', fall back to the x height.
+ if (m_avgCharWidth <= 0.f)
+ m_avgCharWidth = m_xHeight;
+
+ if (m_maxCharWidth <= 0.f)
+ m_maxCharWidth = max<float>(m_avgCharWidth, m_ascent);
+}
+
void SimpleFontData::platformGlyphInit()
{
GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page();
diff --git a/WebCore/platform/graphics/SimpleFontData.h b/WebCore/platform/graphics/SimpleFontData.h
index d2dd0b9..aab6429 100644
--- a/WebCore/platform/graphics/SimpleFontData.h
+++ b/WebCore/platform/graphics/SimpleFontData.h
@@ -61,7 +61,7 @@ public:
virtual ~SimpleFontData();
public:
- const FontPlatformData& platformData() const { return m_font; }
+ const FontPlatformData& platformData() const { return m_platformData; }
SimpleFontData* smallCapsFontData(const FontDescription& fontDescription) const;
// vertical metrics
@@ -69,12 +69,23 @@ public:
int descent() const { return m_descent; }
int lineSpacing() const { return m_lineSpacing; }
int lineGap() const { return m_lineGap; }
+ float maxCharWidth() const { return m_maxCharWidth; }
+ float avgCharWidth() const { return m_avgCharWidth; }
float xHeight() const { return m_xHeight; }
unsigned unitsPerEm() const { return m_unitsPerEm; }
float widthForGlyph(Glyph) const;
float platformWidthForGlyph(Glyph) const;
+ float spaceWidth() const { return m_spaceWidth; }
+ float adjustedSpaceWidth() const { return m_adjustedSpaceWidth; }
+
+#if PLATFORM(CG) || PLATFORM(CAIRO)
+ float syntheticBoldOffset() const { return m_syntheticBoldOffset; }
+#endif
+
+ Glyph spaceGlyph() const { return m_spaceGlyph; }
+
virtual const SimpleFontData* fontDataForCharacter(UChar32) const;
virtual bool containsCharacters(const UChar*, int length) const;
@@ -95,7 +106,7 @@ public:
const GlyphData& missingGlyphData() const { return m_missingGlyphData; }
#if PLATFORM(MAC)
- NSFont* getNSFont() const { return m_font.font(); }
+ NSFont* getNSFont() const { return m_platformData.font(); }
#endif
#if USE(CORE_TEXT)
@@ -114,7 +125,7 @@ public:
#endif
#if PLATFORM(QT)
- QFont getQtFont() const { return m_font.font(); }
+ QFont getQtFont() const { return m_platformData.font(); }
#endif
#if PLATFORM(WIN)
@@ -131,14 +142,17 @@ public:
#endif
#if PLATFORM(WX)
- wxFont* getWxFont() const { return m_font.font(); }
+ wxFont* getWxFont() const { return m_platformData.font(); }
#endif
private:
void platformInit();
void platformGlyphInit();
+ void platformCharWidthInit();
void platformDestroy();
+ void initCharWidths();
+
void commonInit();
#if PLATFORM(WIN)
@@ -147,15 +161,16 @@ private:
float widthForGDIGlyph(Glyph glyph) const;
#endif
-public:
int m_ascent;
int m_descent;
int m_lineSpacing;
int m_lineGap;
+ float m_maxCharWidth;
+ float m_avgCharWidth;
float m_xHeight;
unsigned m_unitsPerEm;
- FontPlatformData m_font;
+ FontPlatformData m_platformData;
mutable GlyphWidthMap m_glyphToWidthMap;
@@ -176,22 +191,26 @@ public:
mutable SimpleFontData* m_smallCapsFontData;
-#if PLATFORM(CG) || PLATFORM(WIN)
+#if PLATFORM(CG) || PLATFORM(CAIRO)
float m_syntheticBoldOffset;
#endif
-#if PLATFORM(MAC)
#ifdef BUILDING_ON_TIGER
+public:
void* m_styleGroup;
-#endif
+
+private:
#endif
#if USE(ATSUI)
+public:
mutable ATSUStyle m_ATSUStyle;
mutable bool m_ATSUStyleInitialized;
mutable bool m_ATSUMirrors;
mutable bool m_checkedShapesArabic;
mutable bool m_shapesArabic;
+
+private:
#endif
#if USE(CORE_TEXT)
diff --git a/WebCore/platform/graphics/WidthIterator.cpp b/WebCore/platform/graphics/WidthIterator.cpp
index a16d739..9157310 100644
--- a/WebCore/platform/graphics/WidthIterator.cpp
+++ b/WebCore/platform/graphics/WidthIterator.cpp
@@ -39,13 +39,14 @@ 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)
+WidthIterator::WidthIterator(const Font* font, const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts)
: m_font(font)
, m_run(run)
, m_end(run.length())
, m_currentCharacter(0)
, m_runWidthSoFar(0)
, m_finalRoundingWidth(0)
+ , m_fallbackFonts(fallbackFonts)
{
// If the padding is non-zero, count the number of spaces in the run
// and divide that by the padding for per space addition.
@@ -78,7 +79,10 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer)
float runWidthSoFar = m_runWidthSoFar;
float lastRoundingWidth = m_finalRoundingWidth;
-
+
+ const SimpleFontData* primaryFont = m_font->primaryFont();
+ const SimpleFontData* lastFontData = primaryFont;
+
while (currentCharacter < offset) {
UChar32 c = *cp;
unsigned clusterLength = 1;
@@ -126,16 +130,29 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer)
// First, we round spaces to an adjusted width in all fonts.
// Second, in fixed-pitch fonts we ensure that all characters that
// match the width of the space character have the same width as the space character.
- if (width == fontData->m_spaceWidth && (fontData->m_treatAsFixedPitch || glyph == fontData->m_spaceGlyph) && m_run.applyWordRounding()) {
- width = fontData->m_adjustedSpaceWidth;
+ if (width == fontData->spaceWidth() && (fontData->pitch() == FixedPitch || glyph == fontData->spaceGlyph()) && m_run.applyWordRounding())
+ width = fontData->adjustedSpaceWidth();
+ }
+
+ if (fontData != lastFontData && width) {
+ lastFontData = fontData;
+ if (m_fallbackFonts && fontData != primaryFont) {
+ // FIXME: This does a little extra work that could be avoided if
+ // glyphDataForCharacter() returned whether it chose to use a small caps font.
+ if (!m_font->isSmallCaps() || c == toUpper(c))
+ m_fallbackFonts->add(fontData);
+ else {
+ const GlyphData& uppercaseGlyphData = m_font->glyphDataForCharacter(toUpper(c), rtl);
+ if (uppercaseGlyphData.fontData != primaryFont)
+ m_fallbackFonts->add(uppercaseGlyphData.fontData);
+ }
}
}
if (hasExtraSpacing) {
// Account for letter-spacing.
- if (width && m_font->letterSpacing()) {
+ if (width && m_font->letterSpacing())
width += m_font->letterSpacing();
- }
if (Font::treatAsSpace(c)) {
// Account for padding. WebCore uses space padding to justify text.
@@ -153,9 +170,8 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer)
// Account for word spacing.
// We apply additional space between "words" by adding width to the space character.
- if (currentCharacter != 0 && !Font::treatAsSpace(cp[-1]) && m_font->wordSpacing()) {
+ if (currentCharacter != 0 && !Font::treatAsSpace(cp[-1]) && m_font->wordSpacing())
width += m_font->wordSpacing();
- }
}
}
@@ -172,9 +188,8 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer)
// Force characters that are used to determine word boundaries for the rounding hack
// to be integer width, so following words will start on an integer boundary.
- if (m_run.applyWordRounding() && Font::isRoundingHackCharacter(c)) {
+ if (m_run.applyWordRounding() && Font::isRoundingHackCharacter(c))
width = ceilf(width);
- }
// Check to see if the next character is a "rounding hack character", if so, adjust
// width so that the total run width will be on an integer boundary.
diff --git a/WebCore/platform/graphics/WidthIterator.h b/WebCore/platform/graphics/WidthIterator.h
index 5706d1e..7ca4198 100644
--- a/WebCore/platform/graphics/WidthIterator.h
+++ b/WebCore/platform/graphics/WidthIterator.h
@@ -22,16 +22,18 @@
#ifndef WidthIterator_h
#define WidthIterator_h
+#include <wtf/HashSet.h>
#include <wtf/unicode/Unicode.h>
namespace WebCore {
class Font;
class GlyphBuffer;
+class SimpleFontData;
class TextRun;
struct WidthIterator {
- WidthIterator(const Font*, const TextRun&);
+ WidthIterator(const Font*, const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0);
void advance(int to, GlyphBuffer* = 0);
bool advanceOneCharacter(float& width, GlyphBuffer* = 0);
@@ -49,6 +51,7 @@ struct WidthIterator {
private:
UChar32 normalizeVoicingMarks(int currentCharacter);
+ HashSet<const SimpleFontData*>* m_fallbackFonts;
};
}
diff --git a/WebCore/platform/graphics/android/FontAndroid.cpp b/WebCore/platform/graphics/android/FontAndroid.cpp
index ca2fca1..a430b07 100644
--- a/WebCore/platform/graphics/android/FontAndroid.cpp
+++ b/WebCore/platform/graphics/android/FontAndroid.cpp
@@ -107,6 +107,11 @@ static bool setupForText(SkPaint* paint, GraphicsContext* gc,
return true;
}
+bool Font::canReturnFallbackFontsForComplexText()
+{
+ return false;
+}
+
void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
const GlyphBuffer& glyphBuffer, int from, int numGlyphs,
const FloatPoint& point) const
@@ -206,7 +211,7 @@ void Font::drawComplexText(GraphicsContext* gc, TextRun const& run,
paint);
}
-float Font::floatWidthForComplexText(const TextRun& run) const
+float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>*) const
{
SkPaint paint;
diff --git a/WebCore/platform/graphics/android/FontDataAndroid.cpp b/WebCore/platform/graphics/android/FontDataAndroid.cpp
index 3d31eaf..2bb53e4 100644
--- a/WebCore/platform/graphics/android/FontDataAndroid.cpp
+++ b/WebCore/platform/graphics/android/FontDataAndroid.cpp
@@ -48,7 +48,7 @@ void SimpleFontData::platformInit()
SkPaint paint;
SkPaint::FontMetrics metrics;
- m_font.setupPaint(&paint);
+ m_platformData.setupPaint(&paint);
(void)paint.getFontMetrics(&metrics);
// use ceil instead of round to favor descent, given a lot of accidental
@@ -64,6 +64,13 @@ void SimpleFontData::platformInit()
m_lineGap = SkScalarRound(metrics.fLeading);
}
+void SimpleFontData::platformCharWidthInit()
+{
+ m_avgCharWidth = 0.f;
+ m_maxCharWidth = 0.f;
+ initCharWidths();
+}
+
void SimpleFontData::platformDestroy()
{
delete m_smallCapsFontData;
@@ -72,7 +79,7 @@ void SimpleFontData::platformDestroy()
SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
{
if (!m_smallCapsFontData) {
- m_smallCapsFontData = new SimpleFontData(FontPlatformData(m_font, fontDescription.computedSize() * 0.7f));
+ m_smallCapsFontData = new SimpleFontData(FontPlatformData(m_platformData, fontDescription.computedSize() * 0.7f));
}
return m_smallCapsFontData;
}
@@ -84,7 +91,7 @@ bool SimpleFontData::containsCharacters(const UChar* characters, int length) con
SkPaint paint;
uint16_t glyphs[kMaxBufferCount];
- m_font.setupPaint(&paint);
+ m_platformData.setupPaint(&paint);
paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
while (length > 0) {
@@ -114,7 +121,7 @@ float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
SkPaint paint;
- m_font.setupPaint(&paint);
+ m_platformData.setupPaint(&paint);
if (EmojiFont::IsEmojiGlyph(glyph))
return EmojiFont::GetAdvanceWidth(glyph, paint);
diff --git a/WebCore/platform/graphics/cairo/FontCairo.cpp b/WebCore/platform/graphics/cairo/FontCairo.cpp
index b23182d..0f7ae79 100644
--- a/WebCore/platform/graphics/cairo/FontCairo.cpp
+++ b/WebCore/platform/graphics/cairo/FontCairo.cpp
@@ -36,6 +36,8 @@
#include "SimpleFontData.h"
#include "TransformationMatrix.h"
+#define SYNTHETIC_OBLIQUE_ANGLE 14
+
namespace WebCore {
void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, const GlyphBuffer& glyphBuffer,
@@ -48,15 +50,23 @@ void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, cons
GlyphBufferGlyph* glyphs = (GlyphBufferGlyph*)glyphBuffer.glyphs(from);
- float offset = point.x();
+ float offset = 0.0f;
for (int i = 0; i < numGlyphs; i++) {
glyphs[i].x = offset;
- glyphs[i].y = point.y();
+ glyphs[i].y = 0.0f;
offset += glyphBuffer.advanceAt(from + i);
}
Color fillColor = context->fillColor();
+ // Synthetic Oblique
+ if(font->platformData().syntheticOblique()) {
+ cairo_matrix_t mat = {1, 0, -tanf(SYNTHETIC_OBLIQUE_ANGLE * acosf(0) / 90), 1, point.x(), point.y()};
+ cairo_transform(cr, &mat);
+ } else {
+ cairo_translate(cr, point.x(), point.y());
+ }
+
// Text shadow, inspired by FontMac
IntSize shadowSize;
int shadowBlur = 0;
@@ -77,6 +87,12 @@ void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, cons
cairo_translate(cr, shadowSize.width(), shadowSize.height());
cairo_show_glyphs(cr, glyphs, numGlyphs);
+ if (font->syntheticBoldOffset()) {
+ cairo_save(cr);
+ cairo_translate(cr, font->syntheticBoldOffset(), 0);
+ cairo_show_glyphs(cr, glyphs, numGlyphs);
+ cairo_restore(cr);
+ }
cairo_restore(cr);
}
@@ -103,6 +119,12 @@ void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, cons
cairo_set_source_rgba(cr, red, green, blue, alpha * context->getAlpha());
}
cairo_show_glyphs(cr, glyphs, numGlyphs);
+ if (font->syntheticBoldOffset()) {
+ cairo_save(cr);
+ cairo_translate(cr, font->syntheticBoldOffset(), 0);
+ cairo_show_glyphs(cr, glyphs, numGlyphs);
+ cairo_restore(cr);
+ }
}
if (context->textDrawingMode() & cTextStroke) {
diff --git a/WebCore/platform/graphics/cairo/GradientCairo.cpp b/WebCore/platform/graphics/cairo/GradientCairo.cpp
index 72fb0c5..0aada55 100644
--- a/WebCore/platform/graphics/cairo/GradientCairo.cpp
+++ b/WebCore/platform/graphics/cairo/GradientCairo.cpp
@@ -80,11 +80,11 @@ void Gradient::fill(GraphicsContext* context, const FloatRect& rect)
{
cairo_t* cr = context->platformContext();
- cairo_save(cr);
+ context->save();
cairo_set_source(cr, platformGradient());
cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());
cairo_fill(cr);
- cairo_restore(cr);
+ context->restore();
}
} //namespace
diff --git a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
index 35ebd3c..23f30f3 100644
--- a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
+++ b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
@@ -92,6 +92,7 @@ GraphicsContext::GraphicsContext(PlatformGraphicsContext* cr)
, m_data(new GraphicsContextPlatformPrivate)
{
m_data->cr = cairo_reference(cr);
+ m_data->syncContext(cr);
setPaintingDisabled(!cr);
}
diff --git a/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h b/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h
index 55b2e25..531ebf4 100644
--- a/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h
+++ b/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h
@@ -73,6 +73,7 @@ public:
void concatCTM(const TransformationMatrix&);
void beginTransparencyLayer() { m_transparencyCount++; }
void endTransparencyLayer() { m_transparencyCount--; }
+ void syncContext(PlatformGraphicsContext* cr);
#else
// On everything else, we do nothing.
void save() {}
@@ -85,6 +86,7 @@ public:
void concatCTM(const TransformationMatrix&) {}
void beginTransparencyLayer() {}
void endTransparencyLayer() {}
+ void syncContext(PlatformGraphicsContext* cr) {}
#endif
cairo_t* cr;
diff --git a/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp b/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
index dff39b7..d2652d6 100644
--- a/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
+++ b/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
@@ -34,7 +34,6 @@
#include "GraphicsContext.h"
#include "ImageData.h"
#include "MIMETypeRegistry.h"
-#include "NotImplemented.h"
#include "Pattern.h"
#include "PlatformString.h"
diff --git a/WebCore/platform/graphics/cairo/ImageCairo.cpp b/WebCore/platform/graphics/cairo/ImageCairo.cpp
index 224154e..7c34e6f 100644
--- a/WebCore/platform/graphics/cairo/ImageCairo.cpp
+++ b/WebCore/platform/graphics/cairo/ImageCairo.cpp
@@ -33,10 +33,12 @@
#include "Color.h"
#include "FloatRect.h"
#include "GraphicsContext.h"
+#include "ImageBuffer.h"
#include "ImageObserver.h"
#include "TransformationMatrix.h"
#include <cairo.h>
#include <math.h>
+#include <wtf/OwnPtr.h>
namespace WebCore {
@@ -89,15 +91,19 @@ BitmapImage::BitmapImage(cairo_surface_t* surface, ImageObserver* observer)
void BitmapImage::draw(GraphicsContext* context, const FloatRect& dst, const FloatRect& src, CompositeOperator op)
{
+ FloatRect srcRect(src);
+ FloatRect dstRect(dst);
+
+ if (dstRect.width() == 0.0f || dstRect.height() == 0.0f ||
+ srcRect.width() == 0.0f || srcRect.height() == 0.0f)
+ return;
+
startAnimation();
cairo_surface_t* image = frameAtIndex(m_currentFrame);
if (!image) // If it's too early we won't have an image yet.
return;
- FloatRect srcRect(src);
- FloatRect dstRect(dst);
-
if (mayFillWithSolidColor()) {
fillWithSolidColor(context, dstRect, solidColor(), op);
return;
@@ -106,7 +112,7 @@ void BitmapImage::draw(GraphicsContext* context, const FloatRect& dst, const Flo
IntSize selfSize = size();
cairo_t* cr = context->platformContext();
- cairo_save(cr);
+ context->save();
// Set the compositing operation.
if (op == CompositeSourceOver && !frameHasAlphaAtIndex(m_currentFrame))
@@ -138,7 +144,7 @@ void BitmapImage::draw(GraphicsContext* context, const FloatRect& dst, const Flo
cairo_clip(cr);
cairo_paint_with_alpha(cr, context->getAlpha());
- cairo_restore(cr);
+ context->restore();
if (imageObserver())
imageObserver()->didDraw(this);
@@ -154,7 +160,18 @@ void Image::drawPattern(GraphicsContext* context, const FloatRect& tileRect, con
cairo_t* cr = context->platformContext();
context->save();
- // TODO: Make use of tileRect.
+ IntRect imageSize = enclosingIntRect(tileRect);
+ OwnPtr<ImageBuffer> imageSurface = ImageBuffer::create(imageSize.size(), false);
+
+ if (!imageSurface)
+ return;
+
+ if (tileRect.size() != size()) {
+ cairo_t* clippedImageContext = imageSurface->context()->platformContext();
+ cairo_set_source_surface(clippedImageContext, image, -tileRect.x(), -tileRect.y());
+ cairo_paint(clippedImageContext);
+ image = imageSurface->image()->nativeImageForCurrentFrame();
+ }
cairo_pattern_t* pattern = cairo_pattern_create_for_surface(image);
cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
@@ -163,7 +180,7 @@ void Image::drawPattern(GraphicsContext* context, const FloatRect& tileRect, con
cairo_pattern_set_filter(pattern, CAIRO_FILTER_NEAREST);
cairo_matrix_t pattern_matrix = cairo_matrix_t(patternTransform);
- cairo_matrix_t phase_matrix = {1, 0, 0, 1, phase.x(), phase.y()};
+ cairo_matrix_t phase_matrix = {1, 0, 0, 1, phase.x() + tileRect.x() * patternTransform.a(), phase.y() + tileRect.y() * patternTransform.d()};
cairo_matrix_t combined;
cairo_matrix_multiply(&combined, &pattern_matrix, &phase_matrix);
cairo_matrix_invert(&combined);
diff --git a/WebCore/platform/graphics/cairo/ImageSourceCairo.cpp b/WebCore/platform/graphics/cairo/ImageSourceCairo.cpp
index c6d54f2..b51caf6 100644
--- a/WebCore/platform/graphics/cairo/ImageSourceCairo.cpp
+++ b/WebCore/platform/graphics/cairo/ImageSourceCairo.cpp
@@ -190,13 +190,13 @@ NativeImagePtr ImageSource::createFrameAtIndex(size_t index)
// Cairo does not like zero height images.
// If we have a zero height image, just pretend we don't have enough data yet.
- if (!buffer->height())
+ if (!size().height())
return 0;
return cairo_image_surface_create_for_data((unsigned char*)buffer->bytes().data(),
CAIRO_FORMAT_ARGB32,
size().width(),
- buffer->height(),
+ size().height(),
size().width()*4);
}
diff --git a/WebCore/platform/graphics/cairo/PathCairo.cpp b/WebCore/platform/graphics/cairo/PathCairo.cpp
index 24354d2..13ca1e2 100644
--- a/WebCore/platform/graphics/cairo/PathCairo.cpp
+++ b/WebCore/platform/graphics/cairo/PathCairo.cpp
@@ -29,7 +29,6 @@
#include "CairoPath.h"
#include "FloatRect.h"
#include "GraphicsContext.h"
-#include "NotImplemented.h"
#include "PlatformString.h"
#include "StrokeStyleApplier.h"
diff --git a/WebCore/platform/graphics/cg/GraphicsContextCG.cpp b/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
index 4b8a555..ab8eb3c 100644
--- a/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
+++ b/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
@@ -116,10 +116,9 @@ void GraphicsContext::drawRect(const IntRect& rect)
CGContextRef context = platformContext();
- if (fillColor().alpha())
- CGContextFillRect(context, rect);
+ CGContextFillRect(context, rect);
- if (strokeStyle() != NoStroke && strokeColor().alpha()) {
+ if (strokeStyle() != NoStroke) {
// We do a fill of four rects to simulate the stroke of a border.
Color oldFillColor = fillColor();
if (oldFillColor != strokeColor())
@@ -142,7 +141,7 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
if (paintingDisabled())
return;
- if (strokeStyle() == NoStroke || !strokeColor().alpha())
+ if (strokeStyle() == NoStroke)
return;
float width = strokeThickness();
@@ -277,7 +276,7 @@ void GraphicsContext::drawEllipse(const IntRect& rect)
void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSpan)
{
- if (paintingDisabled() || strokeStyle() == NoStroke || strokeThickness() <= 0.0f || !strokeColor().alpha())
+ if (paintingDisabled() || strokeStyle() == NoStroke || strokeThickness() <= 0.0f)
return;
CGContextRef context = platformContext();
@@ -366,7 +365,7 @@ void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSp
void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points, bool antialiased)
{
- if (paintingDisabled() || !fillColor().alpha() && (strokeThickness() <= 0 || strokeStyle() == NoStroke))
+ if (paintingDisabled())
return;
if (npoints <= 1)
@@ -491,8 +490,7 @@ void GraphicsContext::fillPath()
CGContextRef context = platformContext();
switch (m_common->state.fillColorSpace) {
case SolidColorSpace:
- if (fillColor().alpha())
- fillPathWithFillRule(context, fillRule());
+ fillPathWithFillRule(context, fillRule());
break;
case PatternColorSpace:
applyFillPattern();
@@ -519,8 +517,7 @@ void GraphicsContext::strokePath()
CGContextRef context = platformContext();
switch (m_common->state.strokeColorSpace) {
case SolidColorSpace:
- if (strokeColor().alpha())
- CGContextStrokePath(context);
+ CGContextStrokePath(context);
break;
case PatternColorSpace:
applyStrokePattern();
@@ -544,8 +541,7 @@ void GraphicsContext::fillRect(const FloatRect& rect)
CGContextRef context = platformContext();
switch (m_common->state.fillColorSpace) {
case SolidColorSpace:
- if (fillColor().alpha())
- CGContextFillRect(context, rect);
+ CGContextFillRect(context, rect);
break;
case PatternColorSpace:
applyFillPattern();
@@ -565,20 +561,18 @@ void GraphicsContext::fillRect(const FloatRect& rect, const Color& color)
{
if (paintingDisabled())
return;
- if (color.alpha()) {
- CGContextRef context = platformContext();
- Color oldFillColor = fillColor();
- if (oldFillColor != color)
- setCGFillColor(context, color);
- CGContextFillRect(context, rect);
- if (oldFillColor != color)
- setCGFillColor(context, oldFillColor);
- }
+ CGContextRef context = platformContext();
+ Color oldFillColor = fillColor();
+ if (oldFillColor != color)
+ setCGFillColor(context, color);
+ CGContextFillRect(context, rect);
+ if (oldFillColor != color)
+ setCGFillColor(context, oldFillColor);
}
void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color)
{
- if (paintingDisabled() || !color.alpha())
+ if (paintingDisabled())
return;
CGContextRef context = platformContext();
@@ -782,8 +776,7 @@ void GraphicsContext::strokeRect(const FloatRect& r, float lineWidth)
CGContextRef context = platformContext();
switch (m_common->state.strokeColorSpace) {
case SolidColorSpace:
- if (strokeColor().alpha())
- CGContextStrokeRectWithWidth(context, r, lineWidth);
+ CGContextStrokeRectWithWidth(context, r, lineWidth);
break;
case PatternColorSpace:
applyStrokePattern();
@@ -1199,4 +1192,3 @@ void GraphicsContext::setCompositeOperation(CompositeOperator mode)
#endif
}
-
diff --git a/WebCore/platform/graphics/cg/ImageSourceCG.cpp b/WebCore/platform/graphics/cg/ImageSourceCG.cpp
index c059985..7cb8799 100644
--- a/WebCore/platform/graphics/cg/ImageSourceCG.cpp
+++ b/WebCore/platform/graphics/cg/ImageSourceCG.cpp
@@ -33,10 +33,12 @@
#include "MIMETypeRegistry.h"
#include "SharedBuffer.h"
#include <ApplicationServices/ApplicationServices.h>
+#include <wtf/UnusedParam.h>
namespace WebCore {
static const CFStringRef kCGImageSourceShouldPreferRGB32 = CFSTR("kCGImageSourceShouldPreferRGB32");
+static const CFStringRef kCGImageSourceDoNotCacheImageBlocks = CFSTR("kCGImageSourceDoNotCacheImageBlocks");
ImageSource::ImageSource()
: m_decoder(0)
@@ -48,11 +50,24 @@ ImageSource::~ImageSource()
clear(true);
}
-void ImageSource::clear(bool, size_t, SharedBuffer* data, bool allDataReceived)
+void ImageSource::clear(bool destroyAllFrames, size_t, SharedBuffer* data, bool allDataReceived)
{
- // We always destroy the decoder, because there is no API to get it to
- // selectively release some of the frames it's holding, and if we don't
- // release any of them, we use too much memory on large images.
+#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+ // Recent versions of ImageIO discard previously decoded image frames if the client
+ // application no longer holds references to them, so there's no need to throw away
+ // the decoder unless we're explicitly asked to destroy all of the frames.
+
+ if (!destroyAllFrames)
+ return;
+#else
+ // Older versions of ImageIO hold references to previously decoded image frames.
+ // There is no API to selectively release some of the frames it is holding, and
+ // if we don't release the frames we use too much memory on large images.
+ // Destroying the decoder is the only way to release previous frames.
+
+ UNUSED_PARAM(destroyAllFrames);
+#endif
+
if (m_decoder) {
CFRelease(m_decoder);
m_decoder = 0;
@@ -66,9 +81,9 @@ static CFDictionaryRef imageSourceOptions()
static CFDictionaryRef options;
if (!options) {
- const void* keys[2] = { kCGImageSourceShouldCache, kCGImageSourceShouldPreferRGB32 };
- const void* values[2] = { kCFBooleanTrue, kCFBooleanTrue };
- options = CFDictionaryCreate(NULL, keys, values, 2,
+ const void* keys[3] = { kCGImageSourceShouldCache, kCGImageSourceShouldPreferRGB32, kCGImageSourceDoNotCacheImageBlocks };
+ const void* values[3] = { kCFBooleanTrue, kCFBooleanTrue, kCFBooleanTrue };
+ options = CFDictionaryCreate(NULL, keys, values, 3,
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
}
return options;
@@ -227,9 +242,17 @@ float ImageSource::frameDurationAtIndex(size_t index)
bool ImageSource::frameHasAlphaAtIndex(size_t)
{
- // Might be interesting to do this optimization on Mac some day, but for now we're just using this
- // for the Cairo source, since it uses our decoders, and our decoders can answer this question.
- // FIXME: Could return false for JPEG and other non-transparent image formats.
+ if (!m_decoder)
+ return false;
+
+ CFStringRef imageType = CGImageSourceGetType(m_decoder);
+
+ // Return false if there is no image type or the image type is JPEG, because
+ // JPEG does not support alpha transparency.
+ if (!imageType || CFEqual(imageType, CFSTR("public.jpeg")))
+ return false;
+
+ // FIXME: Could return false for other non-transparent image formats.
// FIXME: Could maybe return false for a GIF Frame if we have enough info in the GIF properties dictionary
// to determine whether or not a transparent color was defined.
return true;
diff --git a/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp b/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp
index 129776e..bf1cd2e 100644
--- a/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp
+++ b/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp
@@ -414,14 +414,6 @@ FontPlatformData* FontCache::getSimilarFontPlatformData(const Font& font)
FontPlatformData* FontCache::getLastResortFallbackFont(const FontDescription& description)
{
FontDescription::GenericFamilyType generic = description.genericFamily();
- // FIXME: Mapping webkit generic to GenericFamilyType needs to
- // be more intelligent.
- // This spot rarely gets reached. GetFontDataForCharacters() gets hit a lot
- // more often (see FIXME comment there).
- const wchar_t* family = getFontFamilyForScript(description.dominantScript(), generic);
-
- if (family)
- return getCachedFontPlatformData(description, AtomicString(family, wcslen(family)));
// FIXME: Would be even better to somehow get the user's default font here.
// For now we'll pick the default that the user would get without changing
@@ -455,13 +447,6 @@ static LONG toGDIFontWeight(FontWeight fontWeight)
return gdiFontWeights[fontWeight];
}
-// FIXME: This may not be the best place to put this function
-AtomicString FontCache::getGenericFontForScript(UScriptCode script, const FontDescription& description)
-{
- const wchar_t* scriptFont = getFontFamilyForScript( script, description.genericFamily());
- return scriptFont ? AtomicString(scriptFont, wcslen(scriptFont)) : emptyAtom;
-}
-
static void FillLogFont(const FontDescription& fontDescription, LOGFONT* winfont)
{
// The size here looks unusual. The negative number is intentional.
diff --git a/WebCore/platform/graphics/chromium/FontCacheLinux.cpp b/WebCore/platform/graphics/chromium/FontCacheLinux.cpp
index 89433e1..797825e 100644
--- a/WebCore/platform/graphics/chromium/FontCacheLinux.cpp
+++ b/WebCore/platform/graphics/chromium/FontCacheLinux.cpp
@@ -46,6 +46,8 @@
#include "SkTypeface.h"
#include "SkUtils.h"
+#include <wtf/Assertions.h>
+
namespace WebCore {
void FontCache::platformInit()
@@ -79,9 +81,8 @@ const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font,
if (match) {
FcChar8* family;
if (FcPatternGetString(match, FC_FAMILY, 0, &family) == FcResultMatch) {
- FontPlatformData* fpd =
- createFontPlatformData(font.fontDescription(), AtomicString((char*) family));
- ret = new SimpleFontData(*fpd);
+ AtomicString fontFamily(reinterpret_cast<char*>(family));
+ ret = getCachedFontData(getCachedFontPlatformData(font.fontDescription(), fontFamily, false));
}
FcPatternDestroy(match);
}
@@ -98,8 +99,26 @@ FontPlatformData* FontCache::getSimilarFontPlatformData(const Font& font)
FontPlatformData* FontCache::getLastResortFallbackFont(const FontDescription& description)
{
- static AtomicString arialStr("Arial");
- return getCachedFontPlatformData(description, arialStr);
+ static const AtomicString sansStr("Sans");
+ static const AtomicString serifStr("Serif");
+ static const AtomicString monospaceStr("Monospace");
+
+ FontPlatformData* fontPlatformData = 0;
+ switch (description.genericFamily()) {
+ case FontDescription::SerifFamily:
+ fontPlatformData = getCachedFontPlatformData(description, serifStr);
+ break;
+ case FontDescription::MonospaceFamily:
+ fontPlatformData = getCachedFontPlatformData(description, monospaceStr);
+ break;
+ case FontDescription::SansSerifFamily:
+ default:
+ fontPlatformData = getCachedFontPlatformData(description, sansStr);
+ break;
+ }
+
+ ASSERT(fontPlatformData);
+ return fontPlatformData;
}
void FontCache::getTraitsInFamily(const AtomicString& familyName,
@@ -146,7 +165,13 @@ FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontD
if (fontDescription.italic())
style |= SkTypeface::kItalic;
+ // FIXME: This #ifdef can go away once we're firmly using the new Skia.
+ // During the transition, this makes the code compatible with both versions.
+#ifdef SK_USE_OLD_255_TO_256
+ SkTypeface* tf = SkTypeface::CreateFromName(name, static_cast<SkTypeface::Style>(style));
+#else
SkTypeface* tf = SkTypeface::Create(name, static_cast<SkTypeface::Style>(style));
+#endif
if (!tf)
return 0;
@@ -159,11 +184,4 @@ FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontD
return result;
}
-AtomicString FontCache::getGenericFontForScript(UScriptCode script,
- const FontDescription& descript)
-{
- notImplemented();
- return AtomicString();
-}
-
} // namespace WebCore
diff --git a/WebCore/platform/graphics/chromium/FontChromiumWin.cpp b/WebCore/platform/graphics/chromium/FontChromiumWin.cpp
index 1b71946..4710245 100644
--- a/WebCore/platform/graphics/chromium/FontChromiumWin.cpp
+++ b/WebCore/platform/graphics/chromium/FontChromiumWin.cpp
@@ -249,10 +249,28 @@ bool TransparencyAwareGlyphPainter::drawGlyphs(int numGlyphs,
// to subtract off the font ascent to get it.
int x = lroundf(m_point.x() + startAdvance);
int y = lroundf(m_point.y() - m_font->ascent());
+
+ // If there is a non-blur shadow and both the fill color and shadow color
+ // are opaque, handle without skia.
+ IntSize shadowSize;
+ int shadowBlur;
+ Color shadowColor;
+ if (m_graphicsContext->getShadow(shadowSize, shadowBlur, shadowColor)) {
+ // If there is a shadow and this code is reached, windowsCanHandleDrawTextShadow()
+ // will have already returned true during the ctor initiatization of m_useGDI
+ ASSERT(shadowColor.alpha() == 255);
+ ASSERT(m_graphicsContext->fillColor().alpha() == 255);
+ ASSERT(shadowBlur == 0);
+ COLORREF textColor = skia::SkColorToCOLORREF(SkColorSetARGB(255, shadowColor.red(), shadowColor.green(), shadowColor.blue()));
+ COLORREF savedTextColor = GetTextColor(m_hdc);
+ SetTextColor(m_hdc, textColor);
+ ExtTextOut(m_hdc, x + shadowSize.width(), y + shadowSize.height(), ETO_GLYPH_INDEX, 0, reinterpret_cast<const wchar_t*>(&glyphs[0]), numGlyphs, &advances[0]);
+ SetTextColor(m_hdc, savedTextColor);
+ }
+
return !!ExtTextOut(m_hdc, x, y, ETO_GLYPH_INDEX, 0, reinterpret_cast<const wchar_t*>(&glyphs[0]), numGlyphs, &advances[0]);
}
-
class TransparencyAwareUniscribePainter : public TransparencyAwareFontPainter {
public:
TransparencyAwareUniscribePainter(GraphicsContext*,
@@ -305,6 +323,10 @@ IntRect TransparencyAwareUniscribePainter::estimateTextBounds()
UniscribeHelperTextRun state(m_run, *m_font);
int left = lroundf(m_point.x()) + state.characterToX(m_from);
int right = lroundf(m_point.x()) + state.characterToX(m_to);
+
+ // Adjust for RTL script since we just want to know the text bounds.
+ if (left > right)
+ std::swap(left, right);
// This algorithm for estimating how much extra space we need (the text may
// go outside the selection rect) is based roughly on
@@ -317,6 +339,11 @@ IntRect TransparencyAwareUniscribePainter::estimateTextBounds()
} // namespace
+bool Font::canReturnFallbackFontsForComplexText()
+{
+ return false;
+}
+
void Font::drawGlyphs(GraphicsContext* graphicsContext,
const SimpleFontData* font,
const GlyphBuffer& glyphBuffer,
@@ -416,6 +443,20 @@ void Font::drawComplexText(GraphicsContext* graphicsContext,
SetTextColor(hdc, skia::SkColorToCOLORREF(color));
SetBkMode(hdc, TRANSPARENT);
+ // If there is a non-blur shadow and both the fill color and shadow color
+ // are opaque, handle without skia.
+ IntSize shadowSize;
+ int shadowBlur;
+ Color shadowColor;
+ if (graphicsContext->getShadow(shadowSize, shadowBlur, shadowColor) && windowsCanHandleDrawTextShadow(graphicsContext)) {
+ COLORREF textColor = skia::SkColorToCOLORREF(SkColorSetARGB(255, shadowColor.red(), shadowColor.green(), shadowColor.blue()));
+ COLORREF savedTextColor = GetTextColor(hdc);
+ SetTextColor(hdc, textColor);
+ state.draw(graphicsContext, hdc, static_cast<int>(point.x()) + shadowSize.width(),
+ static_cast<int>(point.y() - ascent()) + shadowSize.height(), from, to);
+ SetTextColor(hdc, savedTextColor);
+ }
+
// Uniscribe counts the coordinates from the upper left, while WebKit uses
// the baseline, so we have to subtract off the ascent.
state.draw(graphicsContext, hdc, static_cast<int>(point.x()),
@@ -424,7 +465,7 @@ void Font::drawComplexText(GraphicsContext* graphicsContext,
context->canvas()->endPlatformPaint();
}
-float Font::floatWidthForComplexText(const TextRun& run) const
+float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* /* fallbackFonts */) const
{
UniscribeHelperTextRun state(run, *this);
return static_cast<float>(state.width());
diff --git a/WebCore/platform/graphics/chromium/FontCustomPlatformData.cpp b/WebCore/platform/graphics/chromium/FontCustomPlatformData.cpp
index 1e923ac..e99c12a 100644
--- a/WebCore/platform/graphics/chromium/FontCustomPlatformData.cpp
+++ b/WebCore/platform/graphics/chromium/FontCustomPlatformData.cpp
@@ -116,7 +116,7 @@ FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, b
// Streams the concatenation of a header and font data.
class EOTStream {
public:
- EOTStream(const Vector<uint8_t, 512>& eotHeader, const SharedBuffer* fontData, size_t overlayDst, size_t overlaySrc, size_t overlayLength)
+ EOTStream(const EOTHeader& eotHeader, const SharedBuffer* fontData, size_t overlayDst, size_t overlaySrc, size_t overlayLength)
: m_eotHeader(eotHeader)
, m_fontData(fontData)
, m_overlayDst(overlayDst)
@@ -130,7 +130,7 @@ public:
size_t read(void* buffer, size_t count);
private:
- const Vector<uint8_t, 512>& m_eotHeader;
+ const EOTHeader& m_eotHeader;
const SharedBuffer* m_fontData;
size_t m_overlayDst;
size_t m_overlaySrc;
@@ -200,7 +200,7 @@ FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
// TTLoadEmbeddedFont works only with Embedded OpenType (.eot) data,
// so we need to create an EOT header and prepend it to the font data.
- Vector<uint8_t, 512> eotHeader;
+ EOTHeader eotHeader;
size_t overlayDst;
size_t overlaySrc;
size_t overlayLength;
diff --git a/WebCore/platform/graphics/chromium/FontLinux.cpp b/WebCore/platform/graphics/chromium/FontLinux.cpp
index 2b7c562..a952685 100644
--- a/WebCore/platform/graphics/chromium/FontLinux.cpp
+++ b/WebCore/platform/graphics/chromium/FontLinux.cpp
@@ -46,6 +46,11 @@
namespace WebCore {
+bool Font::canReturnFallbackFontsForComplexText()
+{
+ return false;
+}
+
void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
const GlyphBuffer& glyphBuffer, int from, int numGlyphs,
const FloatPoint& point) const {
@@ -111,7 +116,7 @@ void Font::drawComplexText(GraphicsContext* context, const TextRun& run,
notImplemented();
}
-float Font::floatWidthForComplexText(const TextRun& run) const
+float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* /* fallbackFonts */) const
{
notImplemented();
return 0;
diff --git a/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp b/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp
index 7b7d197..e6a61f6 100644
--- a/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp
+++ b/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp
@@ -95,6 +95,11 @@ void FontPlatformData::setupPaint(SkPaint* paint) const
paint->setTextEncoding(SkPaint::kUTF16_TextEncoding);
}
+SkFontID FontPlatformData::uniqueID() const
+{
+ return m_typeface->uniqueID();
+}
+
bool FontPlatformData::operator==(const FontPlatformData& a) const
{
// If either of the typeface pointers are invalid (either NULL or the
diff --git a/WebCore/platform/graphics/chromium/FontPlatformDataLinux.h b/WebCore/platform/graphics/chromium/FontPlatformDataLinux.h
index ec7d837..c63a860 100644
--- a/WebCore/platform/graphics/chromium/FontPlatformDataLinux.h
+++ b/WebCore/platform/graphics/chromium/FontPlatformDataLinux.h
@@ -36,6 +36,7 @@
class SkPaint;
class SkTypeface;
+typedef uint32_t SkFontID;
namespace WebCore {
@@ -90,6 +91,12 @@ public:
// -------------------------------------------------------------------------
void setupPaint(SkPaint*) const;
+ // -------------------------------------------------------------------------
+ // Return Skia's unique id for this font. This encodes both the style and
+ // the font's file name so refers to a single face.
+ // -------------------------------------------------------------------------
+ SkFontID uniqueID() const;
+
unsigned hash() const;
float size() const { return m_textSize; }
diff --git a/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp b/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp
index ed326c8..9596a4c 100644
--- a/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp
+++ b/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp
@@ -120,6 +120,52 @@ void initializeScriptFontMap(ScriptToFontMap& scriptFontMap)
scriptFontMap[USCRIPT_HAN] = localeFamily;
}
+// There are a lot of characters in USCRIPT_COMMON that can be covered
+// by fonts for scripts closely related to them. See
+// http://unicode.org/cldr/utility/list-unicodeset.jsp?a=[:Script=Common:]
+// FIXME: make this more efficient with a wider coverage
+UScriptCode getScriptBasedOnUnicodeBlock(int ucs4)
+{
+ UBlockCode block = ublock_getCode(ucs4);
+ switch (block) {
+ case UBLOCK_CJK_SYMBOLS_AND_PUNCTUATION:
+ return USCRIPT_HAN;
+ case UBLOCK_HIRAGANA:
+ case UBLOCK_KATAKANA:
+ return USCRIPT_HIRAGANA;
+ case UBLOCK_ARABIC:
+ return USCRIPT_ARABIC;
+ case UBLOCK_THAI:
+ return USCRIPT_THAI;
+ case UBLOCK_GREEK:
+ return USCRIPT_GREEK;
+ case UBLOCK_DEVANAGARI:
+ // For Danda and Double Danda (U+0964, U+0965), use a Devanagari
+ // font for now although they're used by other scripts as well.
+ // Without a context, we can't do any better.
+ return USCRIPT_DEVANAGARI;
+ case UBLOCK_ARMENIAN:
+ return USCRIPT_ARMENIAN;
+ case UBLOCK_GEORGIAN:
+ return USCRIPT_GEORGIAN;
+ case UBLOCK_KANNADA:
+ return USCRIPT_KANNADA;
+ default:
+ return USCRIPT_COMMON;
+ }
+}
+
+UScriptCode getScript(int ucs4)
+{
+ UErrorCode err = U_ZERO_ERROR;
+ UScriptCode script = uscript_getScript(ucs4, &err);
+ // If script is invalid, common or inherited or there's an error,
+ // infer a script based on the unicode block of a character.
+ if (script <= USCRIPT_INHERITED || U_FAILURE(err))
+ script = getScriptBasedOnUnicodeBlock(ucs4);
+ return script;
+}
+
const int kUndefinedAscent = std::numeric_limits<int>::min();
// Given an HFONT, return the ascent. If GetTextMetrics fails,
@@ -209,11 +255,9 @@ const UChar* getFallbackFamily(const UChar* characters,
// to get a font required to render the string.
int i = 0;
UChar32 ucs4 = 0;
- while (i < length && script == USCRIPT_COMMON || script == USCRIPT_INVALID_CODE) {
+ while (i < length && script == USCRIPT_COMMON) {
U16_NEXT(characters, i, length, ucs4);
- UErrorCode err = U_ZERO_ERROR;
- script = uscript_getScript(ucs4, &err);
- // silently ignore the error
+ script = getScript(ucs4);
}
// For the full-width ASCII characters (U+FF00 - U+FF5E), use the font for
@@ -223,46 +267,8 @@ const UChar* getFallbackFamily(const UChar* characters,
if (0xFF00 < ucs4 && ucs4 < 0xFF5F)
script = USCRIPT_HAN;
- // There are a lot of characters in USCRIPT_COMMON that can be covered
- // by fonts for scripts closely related to them. See
- // http://unicode.org/cldr/utility/list-unicodeset.jsp?a=[:Script=Common:]
- // FIXME: make this more efficient with a wider coverage
- if (script == USCRIPT_COMMON || script == USCRIPT_INHERITED) {
- UBlockCode block = ublock_getCode(ucs4);
- switch (block) {
- case UBLOCK_BASIC_LATIN:
- script = USCRIPT_LATIN;
- break;
- case UBLOCK_CJK_SYMBOLS_AND_PUNCTUATION:
- script = USCRIPT_HAN;
- break;
- case UBLOCK_HIRAGANA:
- case UBLOCK_KATAKANA:
- script = USCRIPT_HIRAGANA;
- break;
- case UBLOCK_ARABIC:
- script = USCRIPT_ARABIC;
- break;
- case UBLOCK_GREEK:
- script = USCRIPT_GREEK;
- break;
- case UBLOCK_DEVANAGARI:
- // For Danda and Double Danda (U+0964, U+0965), use a Devanagari
- // font for now although they're used by other scripts as well.
- // Without a context, we can't do any better.
- script = USCRIPT_DEVANAGARI;
- break;
- case UBLOCK_ARMENIAN:
- script = USCRIPT_ARMENIAN;
- break;
- case UBLOCK_GEORGIAN:
- script = USCRIPT_GEORGIAN;
- break;
- case UBLOCK_KANNADA:
- script = USCRIPT_KANNADA;
- break;
- }
- }
+ if (script == USCRIPT_COMMON)
+ script = getScriptBasedOnUnicodeBlock(ucs4);
// Another lame work-around to cover non-BMP characters.
const UChar* family = getFontFamilyForScript(script, generic);
diff --git a/WebCore/platform/graphics/chromium/GlyphPageTreeNodeChromiumWin.cpp b/WebCore/platform/graphics/chromium/GlyphPageTreeNodeChromiumWin.cpp
index 31c5256..2cb1cc5 100644
--- a/WebCore/platform/graphics/chromium/GlyphPageTreeNodeChromiumWin.cpp
+++ b/WebCore/platform/graphics/chromium/GlyphPageTreeNodeChromiumWin.cpp
@@ -72,7 +72,7 @@ static bool fillBMPGlyphs(unsigned offset,
bool recurse)
{
HDC dc = GetDC((HWND)0);
- HGDIOBJ oldFont = SelectObject(dc, fontData->m_font.hfont());
+ HGDIOBJ oldFont = SelectObject(dc, fontData->platformData().hfont());
TEXTMETRIC tm = {0};
if (!GetTextMetrics(dc, &tm)) {
@@ -80,7 +80,7 @@ static bool fillBMPGlyphs(unsigned offset,
ReleaseDC(0, dc);
if (recurse) {
- if (ChromiumBridge::ensureFontLoaded(fontData->m_font.hfont()))
+ if (ChromiumBridge::ensureFontLoaded(fontData->platformData().hfont()))
return fillBMPGlyphs(offset, length, buffer, page, fontData, false);
else {
fillEmptyGlyphs(page);
@@ -191,9 +191,9 @@ static bool fillNonBMPGlyphs(unsigned offset,
bool haveGlyphs = false;
UniscribeHelperTextRun state(buffer, length * 2, false,
- fontData->m_font.hfont(),
- fontData->m_font.scriptCache(),
- fontData->m_font.scriptFontProperties());
+ fontData->platformData().hfont(),
+ fontData->platformData().scriptCache(),
+ fontData->platformData().scriptFontProperties());
state.setInhibitLigate(true);
state.setDisableFontFallback(true);
state.init();
diff --git a/WebCore/platform/graphics/chromium/MediaPlayerPrivateChromium.h b/WebCore/platform/graphics/chromium/MediaPlayerPrivateChromium.h
index e8ba0ad..534244d 100644
--- a/WebCore/platform/graphics/chromium/MediaPlayerPrivateChromium.h
+++ b/WebCore/platform/graphics/chromium/MediaPlayerPrivateChromium.h
@@ -37,67 +37,12 @@
namespace WebCore {
-class MediaPlayerPrivate : public MediaPlayerPrivateInterface {
+class MediaPlayerPrivate {
public:
static void registerMediaEngine(MediaEngineRegistrar);
- ~MediaPlayerPrivate();
-
- IntSize naturalSize() const;
- bool hasVideo() const;
-
- void load(const String& url);
- void cancelLoad();
-
- void play();
- void pause();
-
- bool paused() const;
- bool seeking() const;
-
- float duration() const;
- float currentTime() const;
- void seek(float time);
- void setEndTime(float);
-
- void setRate(float);
- void setVolume(float);
-
- int dataRate() const;
-
- MediaPlayer::NetworkState networkState() const;
- MediaPlayer::ReadyState readyState() const;
-
- float maxTimeBuffered() const;
- float maxTimeSeekable() const;
- unsigned bytesLoaded() const;
- bool totalBytesKnown() const;
- unsigned totalBytes() const;
-
- void setVisible(bool);
- void setSize(const IntSize&);
-
- void paint(GraphicsContext*, const IntRect&);
-
- // Public methods to be called by WebMediaPlayer
- FrameView* frameView();
- void networkStateChanged();
- void readyStateChanged();
- void timeChanged();
- void volumeChanged();
- void repaint();
-
-private:
- MediaPlayerPrivate(MediaPlayer*);
- static MediaPlayerPrivateInterface* create(MediaPlayer* player);
- static void getSupportedTypes(HashSet<String>&);
- static MediaPlayer::SupportsType supportsType(const String& type, const String& codecs);
- static bool isAvailable();
-
- MediaPlayer* m_player;
- void* m_data;
};
-} // namespace WebCore
+} // namespace WebCore
#endif
diff --git a/WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp b/WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp
index 06e997f..6f5ce90 100644
--- a/WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp
+++ b/WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp
@@ -54,11 +54,11 @@ static inline float scaleEmToUnits(float x, int unitsPerEm)
void SimpleFontData::platformInit()
{
HDC dc = GetDC(0);
- HGDIOBJ oldFont = SelectObject(dc, m_font.hfont());
+ HGDIOBJ oldFont = SelectObject(dc, m_platformData.hfont());
TEXTMETRIC textMetric = {0};
if (!GetTextMetrics(dc, &textMetric)) {
- if (ChromiumBridge::ensureFontLoaded(m_font.hfont())) {
+ if (ChromiumBridge::ensureFontLoaded(m_platformData.hfont())) {
// Retry GetTextMetrics.
// FIXME: Handle gracefully the error if this call also fails.
// See http://crbug.com/6401.
@@ -91,6 +91,11 @@ void SimpleFontData::platformInit()
ReleaseDC(0, dc);
}
+void SimpleFontData::platformCharWidthInit()
+{
+ // charwidths are set in platformInit.
+}
+
void SimpleFontData::platformDestroy()
{
// We don't hash this on Win32, so it's effectively owned by us.
@@ -102,7 +107,7 @@ SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDes
{
if (!m_smallCapsFontData) {
LOGFONT winFont;
- GetObject(m_font.hfont(), sizeof(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.
@@ -125,13 +130,13 @@ void SimpleFontData::determinePitch()
{
// TEXTMETRICS have this. Set m_treatAsFixedPitch based off that.
HDC dc = GetDC(0);
- HGDIOBJ oldFont = SelectObject(dc, m_font.hfont());
+ HGDIOBJ oldFont = SelectObject(dc, m_platformData.hfont());
// Yes, this looks backwards, but the fixed pitch bit is actually set if the font
// is *not* fixed pitch. Unbelievable but true.
TEXTMETRIC textMetric = {0};
if (!GetTextMetrics(dc, &textMetric)) {
- if (ChromiumBridge::ensureFontLoaded(m_font.hfont())) {
+ if (ChromiumBridge::ensureFontLoaded(m_platformData.hfont())) {
// Retry GetTextMetrics.
// FIXME: Handle gracefully the error if this call also fails.
// See http://crbug.com/6401.
@@ -149,12 +154,12 @@ void SimpleFontData::determinePitch()
float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
{
HDC dc = GetDC(0);
- HGDIOBJ oldFont = SelectObject(dc, m_font.hfont());
+ HGDIOBJ oldFont = SelectObject(dc, m_platformData.hfont());
int width = 0;
if (!GetCharWidthI(dc, glyph, 1, 0, &width)) {
// Ask the browser to preload the font and retry.
- if (ChromiumBridge::ensureFontLoaded(m_font.hfont())) {
+ if (ChromiumBridge::ensureFontLoaded(m_platformData.hfont())) {
// FIXME: Handle gracefully the error if this call also fails.
// See http://crbug.com/6401.
if (!GetCharWidthI(dc, glyph, 1, 0, &width))
diff --git a/WebCore/platform/graphics/chromium/SimpleFontDataLinux.cpp b/WebCore/platform/graphics/chromium/SimpleFontDataLinux.cpp
index 8200175..3bff83f 100644
--- a/WebCore/platform/graphics/chromium/SimpleFontDataLinux.cpp
+++ b/WebCore/platform/graphics/chromium/SimpleFontDataLinux.cpp
@@ -36,33 +36,54 @@
#include "FloatRect.h"
#include "FontDescription.h"
#include "Logging.h"
-#include "NotImplemented.h"
+#include "VDMXParser.h"
+#include "SkFontHost.h"
#include "SkPaint.h"
-#include "SkTypeface.h"
#include "SkTime.h"
+#include "SkTypeface.h"
+#include "SkTypes.h"
namespace WebCore {
// Smallcaps versions of fonts are 70% the size of the normal font.
static const float smallCapsFraction = 0.7f;
+// This is the largest VDMX table which we'll try to load and parse.
+static const size_t maxVDMXTableSize = 1024 * 1024; // 1 MB
void SimpleFontData::platformInit()
{
SkPaint paint;
SkPaint::FontMetrics metrics;
- m_font.setupPaint(&paint);
+ m_platformData.setupPaint(&paint);
paint.getFontMetrics(&metrics);
+ const SkFontID fontID = m_platformData.uniqueID();
+
+ static const uint32_t vdmxTag = SkSetFourByteTag('V', 'D', 'M', 'X');
+ int pixelSize = m_platformData.size() + 0.5;
+ int vdmxAscent, vdmxDescent;
+ bool isVDMXValid = false;
+
+ size_t vdmxSize = SkFontHost::GetTableSize(fontID, vdmxTag);
+ if (vdmxSize && vdmxSize < maxVDMXTableSize) {
+ uint8_t* vdmxTable = (uint8_t*) fastMalloc(vdmxSize);
+ if (vdmxTable
+ && SkFontHost::GetTableData(fontID, vdmxTag, 0, vdmxSize, vdmxTable) == vdmxSize
+ && parseVDMX(&vdmxAscent, &vdmxDescent, vdmxTable, vdmxSize, pixelSize))
+ isVDMXValid = true;
+ fastFree(vdmxTable);
+ }
// Beware those who step here: This code is designed to match Win32 font
// metrics *exactly*.
- if (metrics.fVDMXMetricsValid) {
- m_ascent = metrics.fVDMXAscent;
- m_descent = metrics.fVDMXDescent;
+ if (isVDMXValid) {
+ m_ascent = vdmxAscent;
+ m_descent = -vdmxDescent;
} else {
+ SkScalar height = -metrics.fAscent + metrics.fDescent + metrics.fLeading;
m_ascent = SkScalarRound(-metrics.fAscent);
- m_descent = SkScalarRound(metrics.fHeight) - m_ascent;
+ m_descent = SkScalarRound(height) - m_ascent;
}
if (metrics.fXHeight)
@@ -79,7 +100,8 @@ void SimpleFontData::platformInit()
// calculated for us, but we need to calculate m_maxCharWidth and
// m_avgCharWidth in order for text entry widgets to be sized correctly.
- m_maxCharWidth = SkScalarRound(metrics.fXRange * SkScalarRound(m_font.size()));
+ SkScalar xRange = metrics.fXMax - metrics.fXMin;
+ m_maxCharWidth = SkScalarRound(xRange * SkScalarRound(m_platformData.size()));
if (metrics.fAvgCharWidth)
m_avgCharWidth = SkScalarRound(metrics.fAvgCharWidth);
@@ -98,6 +120,11 @@ void SimpleFontData::platformInit()
}
}
+void SimpleFontData::platformCharWidthInit()
+{
+ // charwidths are set in platformInit.
+}
+
void SimpleFontData::platformDestroy()
{
delete m_smallCapsFontData;
@@ -108,7 +135,7 @@ SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDes
{
if (!m_smallCapsFontData) {
const float smallCapsSize = lroundf(fontDescription.computedSize() * smallCapsFraction);
- m_smallCapsFontData = new SimpleFontData(FontPlatformData(m_font, smallCapsSize));
+ m_smallCapsFontData = new SimpleFontData(FontPlatformData(m_platformData, smallCapsSize));
}
return m_smallCapsFontData;
@@ -120,7 +147,7 @@ bool SimpleFontData::containsCharacters(const UChar* characters, int length) con
static const unsigned maxBufferCount = 64;
uint16_t glyphs[maxBufferCount];
- m_font.setupPaint(&paint);
+ m_platformData.setupPaint(&paint);
paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
while (length > 0) {
@@ -151,11 +178,11 @@ float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
SkPaint paint;
- m_font.setupPaint(&paint);
+ m_platformData.setupPaint(&paint);
paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
SkScalar width = paint.measureText(&glyph, 2);
-
+
return SkScalarToFloat(width);
}
diff --git a/WebCore/platform/graphics/chromium/TransparencyWin.cpp b/WebCore/platform/graphics/chromium/TransparencyWin.cpp
index 8c790af..d3ced81 100644
--- a/WebCore/platform/graphics/chromium/TransparencyWin.cpp
+++ b/WebCore/platform/graphics/chromium/TransparencyWin.cpp
@@ -109,7 +109,7 @@ class TransparencyWin::OwnedBuffers {
public:
OwnedBuffers(const IntSize& size, bool needReferenceBuffer)
{
- m_destBitmap.adopt(ImageBuffer::create(size, false));
+ m_destBitmap = ImageBuffer::create(size, false);
if (needReferenceBuffer) {
m_referenceBitmap.setConfig(SkBitmap::kARGB_8888_Config, size.width(), size.height());
diff --git a/WebCore/platform/graphics/chromium/VDMXParser.cpp b/WebCore/platform/graphics/chromium/VDMXParser.cpp
new file mode 100644
index 0000000..3347226
--- /dev/null
+++ b/WebCore/platform/graphics/chromium/VDMXParser.cpp
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2008, 2009, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+
+// For htons/ntohs
+#include <arpa/inet.h>
+
+// Buffer helper class
+//
+// This class perform some trival buffer operations while checking for
+// out-of-bounds errors. As a family they return false if anything is amiss,
+// updating the current offset otherwise.
+class Buffer {
+public:
+ Buffer(const uint8_t* buffer, size_t length)
+ : m_buffer(buffer)
+ , m_length(length)
+ , m_offset(0) { }
+
+ bool skip(size_t numBytes)
+ {
+ if (m_offset + numBytes > m_length)
+ return false;
+ m_offset += numBytes;
+ return true;
+ }
+
+ bool readU8(uint8_t* value)
+ {
+ if (m_offset + sizeof(uint8_t) > m_length)
+ return false;
+ *value = m_buffer[m_offset];
+ m_offset += sizeof(uint8_t);
+ return true;
+ }
+
+ bool readU16(uint16_t* value)
+ {
+ if (m_offset + sizeof(uint16_t) > m_length)
+ return false;
+ memcpy(value, m_buffer + m_offset, sizeof(uint16_t));
+ *value = ntohs(*value);
+ m_offset += sizeof(uint16_t);
+ return true;
+ }
+
+ bool readS16(int16_t* value)
+ {
+ return readU16(reinterpret_cast<uint16_t*>(value));
+ }
+
+ size_t offset() const
+ {
+ return m_offset;
+ }
+
+ void setOffset(size_t newoffset)
+ {
+ m_offset = newoffset;
+ }
+
+private:
+ const uint8_t *const m_buffer;
+ const size_t m_length;
+ size_t m_offset;
+};
+
+// VDMX parsing code.
+//
+// VDMX tables are found in some TrueType/OpenType fonts and contain
+// ascender/descender overrides for certain (usually small) sizes. This is
+// needed in order to match font metrics on Windows.
+//
+// Freetype does not parse these tables so we do so here.
+
+namespace WebCore {
+
+// Parse a TrueType VDMX table.
+// yMax: (output) the ascender value from the table
+// yMin: (output) the descender value from the table (negative!)
+// vdmx: the table bytes
+// vdmxLength: length of @vdmx, in bytes
+// targetPixelSize: the pixel size of the font (e.g. 16)
+//
+// Returns true iff a suitable match are found. Otherwise, *yMax and *yMin are
+// untouched. size_t must be 32-bits to avoid overflow.
+//
+// See http://www.microsoft.com/opentype/otspec/vdmx.htm
+bool parseVDMX(int* yMax, int* yMin,
+ const uint8_t* vdmx, size_t vdmxLength,
+ unsigned targetPixelSize)
+{
+ Buffer buf(vdmx, vdmxLength);
+
+ // We ignore the version. Future tables should be backwards compatible with
+ // this layout.
+ uint16_t numRatios;
+ if (!buf.skip(4) || !buf.readU16(&numRatios))
+ return false;
+
+ // Now we have two tables. Firstly we have @numRatios Ratio records, then a
+ // matching array of @numRatios offsets. We save the offset of the beginning
+ // of this second table.
+ //
+ // Range 6 <= x <= 262146
+ unsigned long offsetTableOffset =
+ buf.offset() + 4 /* sizeof struct ratio */ * numRatios;
+
+ unsigned desiredRatio = 0xffffffff;
+ // We read 4 bytes per record, so the offset range is
+ // 6 <= x <= 524286
+ for (unsigned i = 0; i < numRatios; ++i) {
+ uint8_t xRatio, yRatio1, yRatio2;
+
+ if (!buf.skip(1)
+ || !buf.readU8(&xRatio)
+ || !buf.readU8(&yRatio1)
+ || !buf.readU8(&yRatio2))
+ return false;
+
+ // This either covers 1:1, or this is the default entry (0, 0, 0)
+ if ((xRatio == 1 && yRatio1 <= 1 && yRatio2 >= 1)
+ || (xRatio == 0 && yRatio1 == 0 && yRatio2 == 0)) {
+ desiredRatio = i;
+ break;
+ }
+ }
+
+ if (desiredRatio == 0xffffffff) // no ratio found
+ return false;
+
+ // Range 10 <= x <= 393216
+ buf.setOffset(offsetTableOffset + sizeof(uint16_t) * desiredRatio);
+
+ // Now we read from the offset table to get the offset of another array
+ uint16_t groupOffset;
+ if (!buf.readU16(&groupOffset))
+ return false;
+ // Range 0 <= x <= 65535
+ buf.setOffset(groupOffset);
+
+ uint16_t numRecords;
+ if (!buf.readU16(&numRecords) || !buf.skip(sizeof(uint16_t)))
+ return false;
+
+ // We read 6 bytes per record, so the offset range is
+ // 4 <= x <= 458749
+ for (unsigned i = 0; i < numRecords; ++i) {
+ uint16_t pixelSize;
+ if (!buf.readU16(&pixelSize))
+ return false;
+ // the entries are sorted, so we can abort early if need be
+ if (pixelSize > targetPixelSize)
+ return false;
+
+ if (pixelSize == targetPixelSize) {
+ int16_t tempYMax, tempYMin;
+ if (!buf.readS16(&tempYMax)
+ || !buf.readS16(&tempYMin))
+ return false;
+ *yMin = tempYMin;
+ *yMax = tempYMax;
+ return true;
+ }
+ if (!buf.skip(2 * sizeof(int16_t)))
+ return false;
+ }
+
+ return false;
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/graphics/chromium/VDMXParser.h b/WebCore/platform/graphics/chromium/VDMXParser.h
new file mode 100644
index 0000000..ef625b7
--- /dev/null
+++ b/WebCore/platform/graphics/chromium/VDMXParser.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2009, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef VDMXParser_h
+#define VDMXParser_h
+
+namespace WebCore {
+ bool parseVDMX(int* ymax, int* ymin,
+ const uint8_t* vdmx, size_t vdmxLength,
+ unsigned targetPixelSize);
+} // namespace WebCore
+
+#endif
diff --git a/WebCore/platform/graphics/filters/FEBlend.cpp b/WebCore/platform/graphics/filters/FEBlend.cpp
index 7210367..86b702f 100644
--- a/WebCore/platform/graphics/filters/FEBlend.cpp
+++ b/WebCore/platform/graphics/filters/FEBlend.cpp
@@ -21,9 +21,11 @@
#include "config.h"
-#if ENABLE(SVG) && ENABLE(SVG_FILTERS)
+#if ENABLE(FILTERS)
#include "FEBlend.h"
+#include "Filter.h"
+
namespace WebCore {
FEBlend::FEBlend(FilterEffect* in, FilterEffect* in2, BlendModeType mode)
@@ -59,7 +61,7 @@ void FEBlend::setBlendMode(BlendModeType mode)
m_mode = mode;
}
-void FEBlend::apply()
+void FEBlend::apply(Filter*)
{
}
@@ -69,4 +71,4 @@ void FEBlend::dump()
} // namespace WebCore
-#endif // ENABLE(SVG) && ENABLE(SVG_FILTERS)
+#endif // ENABLE(FILTERS)
diff --git a/WebCore/platform/graphics/filters/FEBlend.h b/WebCore/platform/graphics/filters/FEBlend.h
index b2835e8..dec04ac 100644
--- a/WebCore/platform/graphics/filters/FEBlend.h
+++ b/WebCore/platform/graphics/filters/FEBlend.h
@@ -22,9 +22,11 @@
#ifndef SVGFEBlend_h
#define SVGFEBlend_h
-#if ENABLE(SVG) && ENABLE(SVG_FILTERS)
+#if ENABLE(FILTERS)
#include "FilterEffect.h"
+#include "Filter.h"
+
namespace WebCore {
enum BlendModeType {
@@ -46,8 +48,8 @@ namespace WebCore {
BlendModeType blendMode() const;
void setBlendMode(BlendModeType);
- virtual void apply();
- virtual void dump();
+ void apply(Filter*);
+ void dump();
private:
FEBlend(FilterEffect*, FilterEffect*, BlendModeType);
@@ -59,6 +61,6 @@ namespace WebCore {
} // namespace WebCore
-#endif // ENABLE(SVG) && ENABLE(SVG_FILTERS)
+#endif // ENABLE(FILTERS)
#endif // SVGFEBlend_h
diff --git a/WebCore/platform/graphics/filters/FEColorMatrix.cpp b/WebCore/platform/graphics/filters/FEColorMatrix.cpp
index f783106..8704e64 100644
--- a/WebCore/platform/graphics/filters/FEColorMatrix.cpp
+++ b/WebCore/platform/graphics/filters/FEColorMatrix.cpp
@@ -21,9 +21,11 @@
#include "config.h"
-#if ENABLE(SVG) && ENABLE(SVG_FILTERS)
+#if ENABLE(FILTERS)
#include "FEColorMatrix.h"
+#include "Filter.h"
+
namespace WebCore {
FEColorMatrix::FEColorMatrix(FilterEffect* in, ColorMatrixType type, const Vector<float>& values)
@@ -59,7 +61,7 @@ void FEColorMatrix::setValues(const Vector<float> &values)
m_values = values;
}
-void FEColorMatrix::apply()
+void FEColorMatrix::apply(Filter*)
{
}
@@ -69,4 +71,4 @@ void FEColorMatrix::dump()
} // namespace WebCore
-#endif // ENABLE(SVG) && ENABLE(SVG_FILTERS)
+#endif // ENABLE(FILTERS)
diff --git a/WebCore/platform/graphics/filters/FEColorMatrix.h b/WebCore/platform/graphics/filters/FEColorMatrix.h
index d8193ed..eeb3557 100644
--- a/WebCore/platform/graphics/filters/FEColorMatrix.h
+++ b/WebCore/platform/graphics/filters/FEColorMatrix.h
@@ -22,8 +22,10 @@
#ifndef SVGFEColorMatrix_h
#define SVGFEColorMatrix_h
-#if ENABLE(SVG) && ENABLE(SVG_FILTERS)
+#if ENABLE(FILTERS)
#include "FilterEffect.h"
+
+#include "Filter.h"
#include <wtf/Vector.h>
namespace WebCore {
@@ -46,8 +48,8 @@ namespace WebCore {
const Vector<float>& values() const;
void setValues(const Vector<float>&);
- virtual void apply();
- virtual void dump();
+ void apply(Filter*);
+ void dump();
private:
FEColorMatrix(FilterEffect*, ColorMatrixType, const Vector<float>&);
@@ -59,6 +61,6 @@ namespace WebCore {
} // namespace WebCore
-#endif // ENABLE(SVG) && ENABLE(SVG_FILTERS)
+#endif // ENABLE(FILTERS)
#endif // SVGFEColorMatrix_h
diff --git a/WebCore/platform/graphics/filters/FEComponentTransfer.cpp b/WebCore/platform/graphics/filters/FEComponentTransfer.cpp
index 708ea3e..54ac123 100644
--- a/WebCore/platform/graphics/filters/FEComponentTransfer.cpp
+++ b/WebCore/platform/graphics/filters/FEComponentTransfer.cpp
@@ -21,9 +21,11 @@
#include "config.h"
-#if ENABLE(SVG) && ENABLE(SVG_FILTERS)
+#if ENABLE(FILTERS)
#include "FEComponentTransfer.h"
+#include "Filter.h"
+
namespace WebCore {
FEComponentTransfer::FEComponentTransfer(FilterEffect* in, const ComponentTransferFunction& redFunc,
@@ -83,7 +85,7 @@ void FEComponentTransfer::setAlphaFunction(const ComponentTransferFunction& func
m_alphaFunc = func;
}
-void FEComponentTransfer::apply()
+void FEComponentTransfer::apply(Filter*)
{
}
@@ -93,4 +95,4 @@ void FEComponentTransfer::dump()
} // namespace WebCore
-#endif // ENABLE(SVG) && ENABLE(SVG_FILTERS)
+#endif // ENABLE(FILTERS)
diff --git a/WebCore/platform/graphics/filters/FEComponentTransfer.h b/WebCore/platform/graphics/filters/FEComponentTransfer.h
index 20d70c0..cc1d1f8 100644
--- a/WebCore/platform/graphics/filters/FEComponentTransfer.h
+++ b/WebCore/platform/graphics/filters/FEComponentTransfer.h
@@ -22,10 +22,11 @@
#ifndef SVGFEComponentTransfer_h
#define SVGFEComponentTransfer_h
-#if ENABLE(SVG) && ENABLE(SVG_FILTERS)
+#if ENABLE(FILTERS)
#include "FilterEffect.h"
-#include "SVGFEDisplacementMap.h"
+#include "SVGFEDisplacementMap.h"
+#include "Filter.h"
#include <wtf/Vector.h>
namespace WebCore {
@@ -78,8 +79,8 @@ namespace WebCore {
ComponentTransferFunction alphaFunction() const;
void setAlphaFunction(const ComponentTransferFunction&);
- virtual void apply();
- virtual void dump();
+ void apply(Filter*);
+ void dump();
private:
FEComponentTransfer(FilterEffect*,const ComponentTransferFunction&, const ComponentTransferFunction&,
@@ -94,6 +95,6 @@ namespace WebCore {
} // namespace WebCore
-#endif // ENABLE(SVG) && ENABLE(SVG_FILTERS)
+#endif // ENABLE(FILTERS)
#endif // SVGFEComponentTransfer_h
diff --git a/WebCore/platform/graphics/filters/FEComposite.cpp b/WebCore/platform/graphics/filters/FEComposite.cpp
index 0b5ce94..0706358 100644
--- a/WebCore/platform/graphics/filters/FEComposite.cpp
+++ b/WebCore/platform/graphics/filters/FEComposite.cpp
@@ -21,9 +21,11 @@
#include "config.h"
-#if ENABLE(SVG) && ENABLE(SVG_FILTERS)
+#if ENABLE(FILTERS)
#include "FEComposite.h"
+#include "Filter.h"
+
namespace WebCore {
FEComposite::FEComposite(FilterEffect* in, FilterEffect* in2, const CompositeOperationType& type,
@@ -95,7 +97,7 @@ void FEComposite::setK4(float k4)
m_k4 = k4;
}
-void FEComposite::apply()
+void FEComposite::apply(Filter*)
{
}
@@ -105,4 +107,4 @@ void FEComposite::dump()
} // namespace WebCore
-#endif // ENABLE(SVG) && ENABLE(SVG_FILTERS)
+#endif // ENABLE(FILTERS)
diff --git a/WebCore/platform/graphics/filters/FEComposite.h b/WebCore/platform/graphics/filters/FEComposite.h
index d205395..b623cce 100644
--- a/WebCore/platform/graphics/filters/FEComposite.h
+++ b/WebCore/platform/graphics/filters/FEComposite.h
@@ -22,9 +22,11 @@
#ifndef SVGFEComposite_h
#define SVGFEComposite_h
-#if ENABLE(SVG) && ENABLE(SVG_FILTERS)
+#if ENABLE(FILTERS)
#include "FilterEffect.h"
+
#include "PlatformString.h"
+#include "Filter.h"
namespace WebCore {
@@ -58,8 +60,8 @@ namespace WebCore {
float k4() const;
void setK4(float);
- virtual void apply();
- virtual void dump();
+ void apply(Filter*);
+ void dump();
private:
FEComposite(FilterEffect*, FilterEffect*, const CompositeOperationType&,
@@ -76,6 +78,6 @@ namespace WebCore {
} // namespace WebCore
-#endif // ENABLE(SVG) && ENABLE(SVG_FILTERS)
+#endif // ENABLE(FILTERS)
#endif // SVGFEComposite_h
diff --git a/WebCore/platform/graphics/filters/Filter.h b/WebCore/platform/graphics/filters/Filter.h
new file mode 100644
index 0000000..84909da
--- /dev/null
+++ b/WebCore/platform/graphics/filters/Filter.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * aint with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef Filter_h
+#define Filter_h
+
+#if ENABLE(FILTERS)
+#include "Image.h"
+#include "StringHash.h"
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+ class FilterEffect;
+
+ class Filter : public RefCounted<Filter> {
+ public:
+ virtual ~Filter() { }
+
+ void setSourceImage(PassRefPtr<Image> image) { m_image = image; }
+ Image* sourceImage() { return m_image.get(); }
+
+ virtual void calculateEffectSubRegion(FilterEffect*) = 0;
+
+ private:
+ RefPtr<Image> m_image;
+ };
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // Filter_h
diff --git a/WebCore/platform/graphics/filters/FilterEffect.cpp b/WebCore/platform/graphics/filters/FilterEffect.cpp
new file mode 100644
index 0000000..cd74992
--- /dev/null
+++ b/WebCore/platform/graphics/filters/FilterEffect.cpp
@@ -0,0 +1,46 @@
+/*
+ Copyright (C) Alex Mathews <possessedpenguinbob@gmail.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ aint with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "FilterEffect.h"
+
+namespace WebCore {
+
+FilterEffect::FilterEffect()
+ : m_xBBoxMode(false)
+ , m_yBBoxMode(false)
+ , m_widthBBoxMode(false)
+ , m_heightBBoxMode(false)
+{
+}
+
+FilterEffect::~FilterEffect()
+{
+}
+
+TextStream& FilterEffect::externalRepresentation(TextStream& ts) const
+{
+ return ts;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/WebCore/platform/graphics/filters/FilterEffect.h b/WebCore/platform/graphics/filters/FilterEffect.h
new file mode 100644
index 0000000..e2a058d
--- /dev/null
+++ b/WebCore/platform/graphics/filters/FilterEffect.h
@@ -0,0 +1,81 @@
+/*
+ Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com>
+ 2009 Dirk Schulze <krit@webkit.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ aint with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef FilterEffect_h
+#define FilterEffect_h
+
+#if ENABLE(FILTERS)
+#include "Filter.h"
+#include "FloatRect.h"
+#include "ImageBuffer.h"
+#include "TextStream.h"
+
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+ class FilterEffect : public RefCounted<FilterEffect> {
+ public:
+ virtual ~FilterEffect();
+
+ bool xBoundingBoxMode() const { return m_xBBoxMode; }
+ void setXBoundingBoxMode(bool bboxMode) { m_xBBoxMode = bboxMode; }
+
+ bool yBoundingBoxMode() const { return m_yBBoxMode; }
+ void setYBoundingBoxMode(bool bboxMode) { m_yBBoxMode = bboxMode; }
+
+ bool widthBoundingBoxMode() const { return m_widthBBoxMode; }
+ void setWidthBoundingBoxMode(bool bboxMode) { m_widthBBoxMode = bboxMode; }
+
+ bool heightBoundingBoxMode() const { return m_heightBBoxMode; }
+ void setHeightBoundingBoxMode(bool bboxMode) { m_heightBBoxMode = bboxMode; }
+
+ FloatRect subRegion() const { return m_subRegion; }
+ void setSubRegion(const FloatRect& subRegion) { m_subRegion = subRegion; }
+
+ // The result is bounded by the size of the filter primitive to save resources
+ ImageBuffer* resultImage() { return m_effectBuffer.get(); }
+ void setEffectBuffer(ImageBuffer* effectBuffer) { m_effectBuffer.set(effectBuffer); }
+
+ virtual void apply(Filter*) = 0;
+ virtual void dump() = 0;
+
+ virtual TextStream& externalRepresentation(TextStream&) const;
+ protected:
+ FilterEffect();
+
+ private:
+
+ bool m_xBBoxMode : 1;
+ bool m_yBBoxMode : 1;
+ bool m_widthBBoxMode : 1;
+ bool m_heightBBoxMode : 1;
+
+ FloatRect m_subRegion;
+
+ mutable OwnPtr<ImageBuffer> m_effectBuffer;
+ };
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // FilterEffect_h
diff --git a/WebCore/platform/graphics/filters/SourceAlpha.cpp b/WebCore/platform/graphics/filters/SourceAlpha.cpp
new file mode 100644
index 0000000..646a57b
--- /dev/null
+++ b/WebCore/platform/graphics/filters/SourceAlpha.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * aint with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "SourceAlpha.h"
+
+#include "GraphicsContext.h"
+#include "PlatformString.h"
+#include "Filter.h"
+
+#include <wtf/StdLibExtras.h>
+
+namespace WebCore {
+
+PassRefPtr<SourceAlpha> SourceAlpha::create()
+{
+ return adoptRef(new SourceAlpha);
+}
+
+const AtomicString& SourceAlpha::effectName()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, s_effectName, ("SourceAlpha"));
+ return s_effectName;
+}
+
+void SourceAlpha::apply(Filter*)
+{
+}
+
+void SourceAlpha::dump()
+{
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/WebCore/platform/graphics/filters/SourceAlpha.h b/WebCore/platform/graphics/filters/SourceAlpha.h
new file mode 100644
index 0000000..21497aa
--- /dev/null
+++ b/WebCore/platform/graphics/filters/SourceAlpha.h
@@ -0,0 +1,47 @@
+/*
+ Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ aint with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef SourceAlpha_h
+#define SourceAlpha_h
+
+#if ENABLE(FILTERS)
+#include "FilterEffect.h"
+
+#include "PlatformString.h"
+#include "Filter.h"
+
+namespace WebCore {
+
+ class SourceAlpha : public FilterEffect {
+ public:
+ static PassRefPtr<SourceAlpha> create();
+
+ static const AtomicString& effectName();
+
+ void apply(Filter*);
+ void dump();
+
+ private:
+ SourceAlpha() { }
+ };
+} //namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // SourceAlpha_h
diff --git a/WebCore/platform/graphics/filters/SourceGraphic.cpp b/WebCore/platform/graphics/filters/SourceGraphic.cpp
new file mode 100644
index 0000000..39d4810
--- /dev/null
+++ b/WebCore/platform/graphics/filters/SourceGraphic.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * aint with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "SourceGraphic.h"
+
+#include "GraphicsContext.h"
+#include "PlatformString.h"
+#include "Filter.h"
+
+#include <wtf/StdLibExtras.h>
+
+namespace WebCore {
+
+PassRefPtr<SourceGraphic> SourceGraphic::create()
+{
+ return adoptRef(new SourceGraphic);
+}
+
+const AtomicString& SourceGraphic::effectName()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, s_effectName, ("SourceGraphic"));
+ return s_effectName;
+}
+
+void SourceGraphic::apply(Filter*)
+{
+}
+
+void SourceGraphic::dump()
+{
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/WebCore/platform/graphics/filters/SourceGraphic.h b/WebCore/platform/graphics/filters/SourceGraphic.h
new file mode 100644
index 0000000..363fb97
--- /dev/null
+++ b/WebCore/platform/graphics/filters/SourceGraphic.h
@@ -0,0 +1,48 @@
+/*
+ Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com>
+ 2009 Dirk Schulze <krit@webkit.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ aint with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef SourceGraphic_h
+#define SourceGrahpic_h
+
+#if ENABLE(FILTERS)
+#include "FilterEffect.h"
+
+#include "PlatformString.h"
+#include "Filter.h"
+
+namespace WebCore {
+
+ class SourceGraphic : public FilterEffect {
+ public:
+ static PassRefPtr<SourceGraphic> create();
+
+ static const AtomicString& effectName();
+
+ void apply(Filter*);
+ void dump();
+
+ private:
+ SourceGraphic() { }
+ };
+} //namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // SourceGraphic_h
diff --git a/WebCore/platform/graphics/gtk/FontCacheGtk.cpp b/WebCore/platform/graphics/gtk/FontCacheGtk.cpp
index d2b43cc..e0b88da 100644
--- a/WebCore/platform/graphics/gtk/FontCacheGtk.cpp
+++ b/WebCore/platform/graphics/gtk/FontCacheGtk.cpp
@@ -37,7 +37,7 @@ const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, cons
{
#if defined(USE_FREETYPE)
FcResult fresult;
- FontPlatformData* prim = const_cast<FontPlatformData*>(&font.primaryFont()->m_font);
+ FontPlatformData* prim = const_cast<FontPlatformData*>(&font.primaryFont()->platformData());
if (!prim->m_fallbacks)
prim->m_fallbacks = FcFontSort(NULL, prim->m_pattern, FcTrue, NULL, &fresult);
diff --git a/WebCore/platform/graphics/gtk/FontGtk.cpp b/WebCore/platform/graphics/gtk/FontGtk.cpp
index 288ba91..6561f02 100644
--- a/WebCore/platform/graphics/gtk/FontGtk.cpp
+++ b/WebCore/platform/graphics/gtk/FontGtk.cpp
@@ -34,7 +34,6 @@
#include "Font.h"
#include "GraphicsContext.h"
-#include "NotImplemented.h"
#include "SimpleFontData.h"
#include <cairo.h>
@@ -145,14 +144,14 @@ static gchar* convertUniCharToUTF8(const UChar* characters, gint length, int fro
static void setPangoAttributes(const Font* font, const TextRun& run, PangoLayout* layout)
{
#if defined(USE_FREETYPE)
- if (font->primaryFont()->m_font.m_pattern) {
- PangoFontDescription* desc = pango_fc_font_description_from_pattern(font->primaryFont()->m_font.m_pattern, FALSE);
+ if (font->primaryFont()->platformData().m_pattern) {
+ PangoFontDescription* desc = pango_fc_font_description_from_pattern(font->primaryFont()->platformData().m_pattern, FALSE);
pango_layout_set_font_description(layout, desc);
pango_font_description_free(desc);
}
#elif defined(USE_PANGO)
- if (font->primaryFont()->m_font.m_font) {
- PangoFontDescription* desc = pango_font_describe(font->primaryFont()->m_font.m_font);
+ if (font->primaryFont()->platformData().m_font) {
+ PangoFontDescription* desc = pango_font_describe(font->primaryFont()->platformData().m_font);
pango_layout_set_font_description(layout, desc);
pango_font_description_free(desc);
}
@@ -183,6 +182,11 @@ static void setPangoAttributes(const Font* font, const TextRun& run, PangoLayout
pango_attr_list_unref(list);
}
+bool Font::canReturnFallbackFontsForComplexText()
+{
+ return false;
+}
+
void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const
{
cairo_t* cr = context->platformContext();
@@ -290,7 +294,7 @@ static PangoLayout* getDefaultPangoLayout(const TextRun& run)
return layout;
}
-float Font::floatWidthForComplexText(const TextRun& run) const
+float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* /* fallbackFonts */) const
{
if (run.length() == 0)
return 0.0f;
diff --git a/WebCore/platform/graphics/gtk/FontPlatformData.h b/WebCore/platform/graphics/gtk/FontPlatformData.h
index 20c52e5..ae1f134 100644
--- a/WebCore/platform/graphics/gtk/FontPlatformData.h
+++ b/WebCore/platform/graphics/gtk/FontPlatformData.h
@@ -82,6 +82,8 @@ public:
bool isFixedPitch();
float size() const { return m_size; }
+ bool syntheticBold() const { return m_syntheticBold; }
+ bool syntheticOblique() const { return m_syntheticOblique; }
void setFont(cairo_t*) const;
diff --git a/WebCore/platform/graphics/gtk/FontPlatformDataGtk.cpp b/WebCore/platform/graphics/gtk/FontPlatformDataGtk.cpp
index 68685e9..f0f0dd5 100644
--- a/WebCore/platform/graphics/gtk/FontPlatformDataGtk.cpp
+++ b/WebCore/platform/graphics/gtk/FontPlatformDataGtk.cpp
@@ -109,10 +109,9 @@ FontPlatformData::FontPlatformData(const FontDescription& fontDescription, const
cairo_matrix_init_scale(&fontMatrix, fontDescription.computedPixelSize(), fontDescription.computedPixelSize());
cairo_matrix_init_identity(&ctm);
-#if GTK_CHECK_VERSION(2,10,0)
if (GdkScreen* screen = gdk_screen_get_default())
options = gdk_screen_get_font_options(screen);
-#endif
+
// gdk_screen_get_font_options() returns NULL if no default options are
// set, so we always have to check.
if (!options)
@@ -150,10 +149,9 @@ FontPlatformData::FontPlatformData(cairo_font_face_t* fontFace, int size, bool b
static const cairo_font_options_t* defaultOptions = cairo_font_options_create();
const cairo_font_options_t* options = NULL;
-#if GTK_CHECK_VERSION(2,10,0)
if (GdkScreen* screen = gdk_screen_get_default())
options = gdk_screen_get_font_options(screen);
-#endif
+
// gdk_screen_get_font_options() returns NULL if no default options are
// set, so we always have to check.
if (!options)
diff --git a/WebCore/platform/graphics/gtk/GlyphPageTreeNodeGtk.cpp b/WebCore/platform/graphics/gtk/GlyphPageTreeNodeGtk.cpp
index 24ad864..7c9ffe6 100644
--- a/WebCore/platform/graphics/gtk/GlyphPageTreeNodeGtk.cpp
+++ b/WebCore/platform/graphics/gtk/GlyphPageTreeNodeGtk.cpp
@@ -42,7 +42,7 @@ bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned b
if (bufferLength > GlyphPage::size)
return false;
- FT_Face face = cairo_ft_scaled_font_lock_face(fontData->m_font.m_scaledFont);
+ FT_Face face = cairo_ft_scaled_font_lock_face(fontData->platformData().m_scaledFont);
if (!face)
return false;
@@ -57,7 +57,7 @@ bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned b
}
}
- cairo_ft_scaled_font_unlock_face(fontData->m_font.m_scaledFont);
+ cairo_ft_scaled_font_unlock_face(fontData->platformData().m_scaledFont);
return haveGlyphs;
}
diff --git a/WebCore/platform/graphics/gtk/GlyphPageTreeNodePango.cpp b/WebCore/platform/graphics/gtk/GlyphPageTreeNodePango.cpp
index 8fada5c..8d0baa6 100644
--- a/WebCore/platform/graphics/gtk/GlyphPageTreeNodePango.cpp
+++ b/WebCore/platform/graphics/gtk/GlyphPageTreeNodePango.cpp
@@ -78,12 +78,12 @@ bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned b
if (bufferLength > GlyphPage::size)
return false;
- if (!fontData->m_font.m_font || fontData->m_font.m_font == reinterpret_cast<PangoFont*>(-1))
+ if (!fontData->platformData().m_font || fontData->platformData().m_font == reinterpret_cast<PangoFont*>(-1))
return false;
bool haveGlyphs = false;
for (unsigned i = 0; i < length; i++) {
- Glyph glyph = pango_font_get_glyph(fontData->m_font.m_font, fontData->m_font.m_context, buffer[i]);
+ Glyph glyph = pango_font_get_glyph(fontData->platformData().m_font, fontData->platformData().m_context, buffer[i]);
if (!glyph)
setGlyphDataForIndex(offset + i, 0, 0);
else {
diff --git a/WebCore/platform/graphics/gtk/IconGtk.cpp b/WebCore/platform/graphics/gtk/IconGtk.cpp
index d8b38a0..e08c1ab 100644
--- a/WebCore/platform/graphics/gtk/IconGtk.cpp
+++ b/WebCore/platform/graphics/gtk/IconGtk.cpp
@@ -33,7 +33,6 @@
#include "CString.h"
#include "GraphicsContext.h"
#include "MIMETypeRegistry.h"
-#include "NotImplemented.h"
#include "PassRefPtr.h"
#include <gtk/gtk.h>
diff --git a/WebCore/platform/graphics/gtk/ImageGtk.cpp b/WebCore/platform/graphics/gtk/ImageGtk.cpp
index b745209..0e92d6c 100644
--- a/WebCore/platform/graphics/gtk/ImageGtk.cpp
+++ b/WebCore/platform/graphics/gtk/ImageGtk.cpp
@@ -26,12 +26,52 @@
#include "config.h"
#include "BitmapImage.h"
+#include "CString.h"
+#include "GOwnPtr.h"
-// This function loads resources from WebKit
-Vector<char> loadResourceIntoArray(const char*);
+#include <cairo.h>
+#include <gtk/gtk.h>
+
+namespace WTF {
+
+template <> void freeOwnedGPtr<GtkIconInfo>(GtkIconInfo* info)
+{
+ if (info)
+ gtk_icon_info_free(info);
+}
+
+}
namespace WebCore {
+static CString getIconFileNameOrFallback(const char* name, const char* fallback)
+{
+ GOwnPtr<GtkIconInfo> info(gtk_icon_theme_lookup_icon(gtk_icon_theme_get_default(),
+ name, 16, GTK_ICON_LOOKUP_NO_SVG));
+ if (!info)
+ return String::format("%s/webkit-1.0/images/%s.png", DATA_DIR, fallback).utf8();
+
+ return CString(gtk_icon_info_get_filename(info.get()));
+}
+
+static PassRefPtr<SharedBuffer> loadResourceSharedBuffer(const char* name)
+{
+ CString fileName;
+
+ // Find the path for the image
+ if (strcmp("missingImage", name) == 0)
+ fileName = getIconFileNameOrFallback(GTK_STOCK_MISSING_IMAGE, "missingImage");
+ else
+ fileName = String::format("%s/webkit-1.0/images/%s.png", DATA_DIR, name).utf8();
+
+ GOwnPtr<gchar> content;
+ gsize length;
+ if (!g_file_get_contents(fileName.data(), &content.outPtr(), &length, 0))
+ return SharedBuffer::create();
+
+ return SharedBuffer::create(content.get(), length);
+}
+
void BitmapImage::initPlatformData()
{
}
@@ -40,13 +80,34 @@ void BitmapImage::invalidatePlatformData()
{
}
-PassRefPtr<Image> Image::loadPlatformResource(const char *name)
+PassRefPtr<Image> Image::loadPlatformResource(const char* name)
{
- Vector<char> arr = loadResourceIntoArray(name);
RefPtr<BitmapImage> img = BitmapImage::create();
- RefPtr<SharedBuffer> buffer = SharedBuffer::create(arr.data(), arr.size());
- img->setData(buffer, true);
+ RefPtr<SharedBuffer> buffer = loadResourceSharedBuffer(name);
+ img->setData(buffer.release(), true);
return img.release();
}
+GdkPixbuf* BitmapImage::getGdkPixbuf()
+{
+ int width = cairo_image_surface_get_width(frameAtIndex(currentFrame()));
+ int height = cairo_image_surface_get_height(frameAtIndex(currentFrame()));
+
+ int bestDepth = gdk_visual_get_best_depth();
+ GdkColormap* cmap = gdk_colormap_new(gdk_visual_get_best_with_depth(bestDepth), true);
+
+ GdkPixmap* pixmap = gdk_pixmap_new(0, width, height, bestDepth);
+ gdk_drawable_set_colormap(GDK_DRAWABLE(pixmap), cmap);
+ cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(pixmap));
+ cairo_set_source_surface(cr, frameAtIndex(currentFrame()), 0, 0);
+ cairo_paint(cr);
+ cairo_destroy(cr);
+
+ GdkPixbuf* pixbuf = gdk_pixbuf_get_from_drawable(0, GDK_DRAWABLE(pixmap), 0, 0, 0, 0, 0, width, height);
+ g_object_unref(pixmap);
+ g_object_unref(cmap);
+
+ return pixbuf;
+}
+
}
diff --git a/WebCore/platform/graphics/gtk/SimpleFontDataGtk.cpp b/WebCore/platform/graphics/gtk/SimpleFontDataGtk.cpp
index 4203a3c..6684108 100644
--- a/WebCore/platform/graphics/gtk/SimpleFontDataGtk.cpp
+++ b/WebCore/platform/graphics/gtk/SimpleFontDataGtk.cpp
@@ -49,7 +49,7 @@ void SimpleFontData::platformInit()
{
cairo_font_extents_t font_extents;
cairo_text_extents_t text_extents;
- cairo_scaled_font_extents(m_font.m_scaledFont, &font_extents);
+ cairo_scaled_font_extents(m_platformData.m_scaledFont, &font_extents);
m_ascent = static_cast<int>(font_extents.ascent);
m_descent = static_cast<int>(font_extents.descent);
m_lineSpacing = static_cast<int>(font_extents.height);
@@ -60,11 +60,19 @@ void SimpleFontData::platformInit()
// while we figure out what's going on.
if (m_lineSpacing < m_ascent + m_descent)
m_lineSpacing = m_ascent + m_descent;
- cairo_scaled_font_text_extents(m_font.m_scaledFont, "x", &text_extents);
+ cairo_scaled_font_text_extents(m_platformData.m_scaledFont, "x", &text_extents);
m_xHeight = text_extents.height;
- cairo_scaled_font_text_extents(m_font.m_scaledFont, " ", &text_extents);
+ cairo_scaled_font_text_extents(m_platformData.m_scaledFont, " ", &text_extents);
m_spaceWidth = static_cast<int>(text_extents.x_advance);
m_lineGap = m_lineSpacing - m_ascent - m_descent;
+ m_syntheticBoldOffset = m_platformData.syntheticBold() ? 1.0f : 0.f;
+}
+
+void SimpleFontData::platformCharWidthInit()
+{
+ m_avgCharWidth = 0.f;
+ m_maxCharWidth = 0.f;
+ initCharWidths();
}
void SimpleFontData::platformDestroy()
@@ -86,38 +94,38 @@ SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDes
bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
{
- FT_Face face = cairo_ft_scaled_font_lock_face(m_font.m_scaledFont);
+ FT_Face face = cairo_ft_scaled_font_lock_face(m_platformData.m_scaledFont);
if (!face)
return false;
for (unsigned i = 0; i < length; i++) {
if (FcFreeTypeCharIndex(face, characters[i]) == 0) {
- cairo_ft_scaled_font_unlock_face(m_font.m_scaledFont);
+ cairo_ft_scaled_font_unlock_face(m_platformData.m_scaledFont);
return false;
}
}
- cairo_ft_scaled_font_unlock_face(m_font.m_scaledFont);
+ cairo_ft_scaled_font_unlock_face(m_platformData.m_scaledFont);
return true;
}
void SimpleFontData::determinePitch()
{
- m_treatAsFixedPitch = m_font.isFixedPitch();
+ m_treatAsFixedPitch = m_platformData.isFixedPitch();
}
float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
{
- ASSERT(m_font.m_scaledFont);
+ ASSERT(m_platformData.m_scaledFont);
cairo_glyph_t cglyph = { glyph, 0, 0 };
cairo_text_extents_t extents;
- cairo_scaled_font_glyph_extents(m_font.m_scaledFont, &cglyph, 1, &extents);
+ cairo_scaled_font_glyph_extents(m_platformData.m_scaledFont, &cglyph, 1, &extents);
float w = (float)m_spaceWidth;
- if (cairo_scaled_font_status(m_font.m_scaledFont) == CAIRO_STATUS_SUCCESS && extents.x_advance != 0)
+ if (cairo_scaled_font_status(m_platformData.m_scaledFont) == CAIRO_STATUS_SUCCESS && extents.x_advance != 0)
w = (float)extents.x_advance;
return w;
}
@@ -125,7 +133,7 @@ float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
void SimpleFontData::setFont(cairo_t* cr) const
{
ASSERT(cr);
- m_font.setFont(cr);
+ m_platformData.setFont(cr);
}
}
diff --git a/WebCore/platform/graphics/gtk/SimpleFontDataPango.cpp b/WebCore/platform/graphics/gtk/SimpleFontDataPango.cpp
index e345a8c..e57d9e6 100644
--- a/WebCore/platform/graphics/gtk/SimpleFontDataPango.cpp
+++ b/WebCore/platform/graphics/gtk/SimpleFontDataPango.cpp
@@ -48,7 +48,7 @@ void SimpleFontData::platformInit()
{
cairo_font_extents_t font_extents;
cairo_text_extents_t text_extents;
- cairo_scaled_font_extents(m_font.m_scaledFont, &font_extents);
+ cairo_scaled_font_extents(m_platformData.m_scaledFont, &font_extents);
m_ascent = static_cast<int>(font_extents.ascent);
m_descent = static_cast<int>(font_extents.descent);
m_lineSpacing = static_cast<int>(font_extents.height);
@@ -59,11 +59,19 @@ void SimpleFontData::platformInit()
// while we figure out what's going on.
if (m_lineSpacing < m_ascent + m_descent)
m_lineSpacing = m_ascent + m_descent;
- cairo_scaled_font_text_extents(m_font.m_scaledFont, "x", &text_extents);
+ cairo_scaled_font_text_extents(m_platformData.m_scaledFont, "x", &text_extents);
m_xHeight = text_extents.height;
- cairo_scaled_font_text_extents(m_font.m_scaledFont, " ", &text_extents);
+ cairo_scaled_font_text_extents(m_platformData.m_scaledFont, " ", &text_extents);
m_spaceWidth = static_cast<int>(text_extents.x_advance);
m_lineGap = m_lineSpacing - m_ascent - m_descent;
+ m_syntheticBoldOffset = m_platformData.syntheticBold() ? 1.0f : 0.f;
+}
+
+void SimpleFontData::platformCharWidthInit()
+{
+ m_avgCharWidth = 0.f;
+ m_maxCharWidth = 0.f;
+ initCharWidths();
}
void SimpleFontData::platformDestroy()
@@ -87,7 +95,7 @@ bool SimpleFontData::containsCharacters(const UChar* characters, int length) con
{
bool result = true;
- PangoCoverage* coverage = pango_font_get_coverage(m_font.m_font, pango_language_get_default());
+ PangoCoverage* coverage = pango_font_get_coverage(m_platformData.m_font, pango_language_get_default());
for (int i = 0; i < length; i++) {
if (PANGO_COVERAGE_NONE == pango_coverage_get(coverage, characters[i])) {
@@ -108,19 +116,19 @@ void SimpleFontData::determinePitch()
return;
}
- m_treatAsFixedPitch = m_font.isFixedPitch();
+ m_treatAsFixedPitch = m_platformData.isFixedPitch();
}
float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
{
- ASSERT(m_font.m_scaledFont);
+ ASSERT(m_platformData.m_scaledFont);
cairo_glyph_t cglyph = { glyph, 0, 0 };
cairo_text_extents_t extents;
- cairo_scaled_font_glyph_extents(m_font.m_scaledFont, &cglyph, 1, &extents);
+ cairo_scaled_font_glyph_extents(m_platformData.m_scaledFont, &cglyph, 1, &extents);
float w = (float)m_spaceWidth;
- if (cairo_scaled_font_status(m_font.m_scaledFont) == CAIRO_STATUS_SUCCESS && extents.x_advance != 0)
+ if (cairo_scaled_font_status(m_platformData.m_scaledFont) == CAIRO_STATUS_SUCCESS && extents.x_advance != 0)
w = (float)extents.x_advance;
return w;
}
@@ -128,7 +136,7 @@ float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
void SimpleFontData::setFont(cairo_t* cr) const
{
ASSERT(cr);
- m_font.setFont(cr);
+ m_platformData.setFont(cr);
}
}
diff --git a/WebCore/platform/graphics/mac/ColorMac.h b/WebCore/platform/graphics/mac/ColorMac.h
index 830e9d9..8a5ce31 100644
--- a/WebCore/platform/graphics/mac/ColorMac.h
+++ b/WebCore/platform/graphics/mac/ColorMac.h
@@ -41,7 +41,7 @@ namespace WebCore {
// These functions assume NSColors are in DeviceRGB colorspace
Color colorFromNSColor(NSColor *);
- NSColor* nsColor(const Color&);
+ NSColor *nsColor(const Color&);
bool usesTestModeFocusRingColor();
void setUsesTestModeFocusRingColor(bool);
diff --git a/WebCore/platform/graphics/mac/ColorMac.mm b/WebCore/platform/graphics/mac/ColorMac.mm
index 1c4350c..05dd78d 100644
--- a/WebCore/platform/graphics/mac/ColorMac.mm
+++ b/WebCore/platform/graphics/mac/ColorMac.mm
@@ -24,13 +24,10 @@
*/
#import "config.h"
-#import "Color.h"
#import "ColorMac.h"
-#import <AppKit/AppKit.h>
-#import <wtf/Assertions.h>
-#import <wtf/StdLibExtras.h>
#import <wtf/RetainPtr.h>
+#import <wtf/StdLibExtras.h>
@interface WebCoreControlTintObserver : NSObject
+ (void)controlTintDidChange;
@@ -47,7 +44,13 @@ static bool useOldAquaFocusRingColor;
static RGBA32 makeRGBAFromNSColor(NSColor *c)
{
- return makeRGBA((int)(255 * [c redComponent]), (int)(255 * [c greenComponent]), (int)(255 * [c blueComponent]), (int)(255 * [c alphaComponent]));
+ CGFloat redComponent;
+ CGFloat greenComponent;
+ CGFloat blueComponent;
+ CGFloat alpha;
+ [c getRed:&redComponent green:&greenComponent blue:&blueComponent alpha:&alpha];
+
+ return makeRGBA(255 * redComponent, 255 * greenComponent, 255 * blueComponent, 255 * alpha);
}
Color colorFromNSColor(NSColor *c)
@@ -55,21 +58,21 @@ Color colorFromNSColor(NSColor *c)
return Color(makeRGBAFromNSColor(c));
}
-NSColor* nsColor(const Color& color)
+NSColor *nsColor(const Color& color)
{
- unsigned c = color.rgb();
+ RGBA32 c = color.rgb();
switch (c) {
case 0: {
// Need this to avoid returning nil because cachedRGBAValues will default to 0.
- DEFINE_STATIC_LOCAL(RetainPtr<NSColor>, clearColor, ([NSColor colorWithDeviceRed:0.0f green:0.0f blue:0.0f alpha:0.0f]));
+ DEFINE_STATIC_LOCAL(RetainPtr<NSColor>, clearColor, ([NSColor colorWithDeviceRed:0 green:0 blue:0 alpha:0]));
return clearColor.get();
}
case Color::black: {
- DEFINE_STATIC_LOCAL(RetainPtr<NSColor>, blackColor, ([NSColor colorWithDeviceRed:0.0f green:0.0f blue:0.0f alpha:1.0f]));
+ DEFINE_STATIC_LOCAL(RetainPtr<NSColor>, blackColor, ([NSColor colorWithDeviceRed:0 green:0 blue:0 alpha:1]));
return blackColor.get();
}
case Color::white: {
- DEFINE_STATIC_LOCAL(RetainPtr<NSColor>, whiteColor, ([NSColor colorWithDeviceRed:1.0f green:1.0f blue:1.0f alpha:1.0f]));
+ DEFINE_STATIC_LOCAL(RetainPtr<NSColor>, whiteColor, ([NSColor colorWithDeviceRed:1 green:1 blue:1 alpha:1]));
return whiteColor.get();
}
default: {
@@ -81,10 +84,10 @@ NSColor* nsColor(const Color& color)
if (cachedRGBAValues[i] == c)
return cachedColors[i].get();
- NSColor* result = [NSColor colorWithDeviceRed:color.red() / 255.0f
- green:color.green() / 255.0f
- blue:color.blue() / 255.0f
- alpha:color.alpha() /255.0f];
+ NSColor *result = [NSColor colorWithDeviceRed:static_cast<CGFloat>(color.red()) / 255
+ green:static_cast<CGFloat>(color.green()) / 255
+ blue:static_cast<CGFloat>(color.blue()) / 255
+ alpha:static_cast<CGFloat>(color.alpha()) /255];
static int cursor;
cachedRGBAValues[cursor] = c;
@@ -96,16 +99,13 @@ NSColor* nsColor(const Color& color)
}
}
-static CGColorRef CGColorFromNSColor(NSColor* color)
+static CGColorRef CGColorFromNSColor(NSColor *color)
{
// This needs to always use device colorspace so it can de-calibrate the color for
// CGColor to possibly recalibrate it.
- NSColor* deviceColor = [color colorUsingColorSpaceName:NSDeviceRGBColorSpace];
- CGFloat red = [deviceColor redComponent];
- CGFloat green = [deviceColor greenComponent];
- CGFloat blue = [deviceColor blueComponent];
- CGFloat alpha = [deviceColor alphaComponent];
- const CGFloat components[4] = { red, green, blue, alpha };
+ CGFloat components[4];
+ NSColor *deviceColor = [color colorUsingColorSpaceName:NSDeviceRGBColorSpace];
+ [deviceColor getRed:&components[0] green:&components[1] blue:&components[2] alpha:&components[3]];
static CGColorSpaceRef deviceRGBColorSpace = CGColorSpaceCreateDeviceRGB();
CGColorRef cgColor = CGColorCreate(deviceRGBColorSpace, components);
return cgColor;
@@ -130,10 +130,10 @@ Color focusRingColor()
[WebCoreControlTintObserver controlTintDidChange];
tintIsKnown = true;
}
-
+
if (usesTestModeFocusRingColor())
return oldAquaFocusRingColor;
-
+
return systemFocusRingColor;
}
@@ -153,7 +153,7 @@ void setUsesTestModeFocusRingColor(bool newValue)
+ (void)controlTintDidChange
{
- NSColor* color = [[NSColor keyboardFocusIndicatorColor] colorUsingColorSpaceName:NSDeviceRGBColorSpace];
+ NSColor *color = [[NSColor keyboardFocusIndicatorColor] colorUsingColorSpaceName:NSDeviceRGBColorSpace];
WebCore::systemFocusRingColor = WebCore::makeRGBAFromNSColor(color);
}
diff --git a/WebCore/platform/graphics/mac/CoreTextController.cpp b/WebCore/platform/graphics/mac/CoreTextController.cpp
index 49e83c4..05f29b5 100644
--- a/WebCore/platform/graphics/mac/CoreTextController.cpp
+++ b/WebCore/platform/graphics/mac/CoreTextController.cpp
@@ -100,7 +100,7 @@ CoreTextController::CoreTextRun::CoreTextRun(const SimpleFontData* fontData, con
m_indices = reinterpret_cast<const CFIndex*>(CFDataGetBytePtr(m_indicesData.get()));
}
-CoreTextController::CoreTextController(const Font* font, const TextRun& run, bool mayUseNaturalWritingDirection)
+CoreTextController::CoreTextController(const Font* font, const TextRun& run, bool mayUseNaturalWritingDirection, HashSet<const SimpleFontData*>* fallbackFonts)
: m_font(*font)
, m_run(run)
, m_mayUseNaturalWritingDirection(mayUseNaturalWritingDirection)
@@ -112,6 +112,7 @@ CoreTextController::CoreTextController(const Font* font, const TextRun& run, boo
, m_currentRun(0)
, m_glyphInCurrentRun(0)
, m_finalRoundingWidth(0)
+ , m_fallbackFonts(fallbackFonts)
, m_lastRoundingGlyph(0)
{
m_padding = m_run.padding();
@@ -156,12 +157,12 @@ int CoreTextController::offsetForPosition(int h, bool includePartialGlyphs)
if (x <= adjustedAdvance) {
CFIndex hitIndex = coreTextRun.indexAt(j);
int stringLength = coreTextRun.stringLength();
- TextBreakIterator* characterIterator = characterBreakIterator(coreTextRun.characters(), stringLength);
+ TextBreakIterator* cursorPositionIterator = cursorMovementIterator(coreTextRun.characters(), stringLength);
int clusterStart;
- if (isTextBreak(characterIterator, hitIndex))
+ if (isTextBreak(cursorPositionIterator, hitIndex))
clusterStart = hitIndex;
else {
- clusterStart = textBreakPreceding(characterIterator, hitIndex);
+ clusterStart = textBreakPreceding(cursorPositionIterator, hitIndex);
if (clusterStart == TextBreakDone)
clusterStart = 0;
}
@@ -169,7 +170,7 @@ int CoreTextController::offsetForPosition(int h, bool includePartialGlyphs)
if (!includePartialGlyphs)
return coreTextRun.stringLocation() + clusterStart;
- int clusterEnd = textBreakFollowing(characterIterator, hitIndex);
+ int clusterEnd = textBreakFollowing(cursorPositionIterator, hitIndex);
if (clusterEnd == TextBreakDone)
clusterEnd = stringLength;
@@ -179,7 +180,7 @@ int CoreTextController::offsetForPosition(int h, bool includePartialGlyphs)
// reordering and on font fallback should occur within a CTLine.
if (clusterEnd - clusterStart > 1) {
int firstGlyphBeforeCluster = j - 1;
- while (firstGlyphBeforeCluster && coreTextRun.indexAt(firstGlyphBeforeCluster) >= clusterStart && coreTextRun.indexAt(firstGlyphBeforeCluster) < clusterEnd) {
+ while (firstGlyphBeforeCluster >= 0 && coreTextRun.indexAt(firstGlyphBeforeCluster) >= clusterStart && coreTextRun.indexAt(firstGlyphBeforeCluster) < clusterEnd) {
CGFloat width = m_adjustedAdvances[offsetIntoAdjustedGlyphs + firstGlyphBeforeCluster].width;
clusterWidth += width;
x += width;
@@ -359,6 +360,9 @@ void CoreTextController::collectCoreTextRunsForCharacters(const UChar* cp, unsig
return;
}
+ if (m_fallbackFonts && fontData != m_font.primaryFont())
+ m_fallbackFonts->add(fontData);
+
RetainPtr<CFStringRef> string(AdoptCF, CFStringCreateWithCharactersNoCopy(NULL, cp, length, kCFAllocatorNull));
RetainPtr<CFAttributedStringRef> attributedString(AdoptCF, CFAttributedStringCreate(NULL, string.get(), fontData->getCFStringAttributes()));
@@ -426,7 +430,7 @@ void CoreTextController::adjustGlyphsAndAdvances()
bool lastRun = r + 1 == runCount;
const UChar* cp = coreTextRun.characters();
- CGFloat roundedSpaceWidth = roundCGFloat(fontData->m_spaceWidth);
+ CGFloat roundedSpaceWidth = roundCGFloat(fontData->spaceWidth());
bool roundsAdvances = !m_font.isPrinterFont() && fontData->platformData().roundsGlyphAdvances();
bool hasExtraSpacing = (m_font.letterSpacing() || m_font.wordSpacing() || m_padding) && !m_run.spacingDisabled();
@@ -444,29 +448,29 @@ void CoreTextController::adjustGlyphsAndAdvances()
nextCh = *(m_coreTextRuns[r + 1].characters() + m_coreTextRuns[r + 1].indexAt(0));
bool treatAsSpace = Font::treatAsSpace(ch);
- CGGlyph glyph = treatAsSpace ? fontData->m_spaceGlyph : glyphs[i];
- CGSize advance = treatAsSpace ? CGSizeMake(fontData->m_spaceWidth, advances[i].height) : advances[i];
+ CGGlyph glyph = treatAsSpace ? fontData->spaceGlyph() : glyphs[i];
+ CGSize advance = treatAsSpace ? CGSizeMake(fontData->spaceWidth(), advances[i].height) : advances[i];
if (ch == '\t' && m_run.allowTabs()) {
float tabWidth = m_font.tabWidth();
advance.width = tabWidth - fmodf(m_run.xPos() + m_totalWidth, tabWidth);
} else if (ch == zeroWidthSpace || Font::treatAsZeroWidthSpace(ch) && !treatAsSpace) {
advance.width = 0;
- glyph = fontData->m_spaceGlyph;
+ glyph = fontData->spaceGlyph();
}
float roundedAdvanceWidth = roundf(advance.width);
if (roundsAdvances)
advance.width = roundedAdvanceWidth;
- advance.width += fontData->m_syntheticBoldOffset;
+ advance.width += fontData->syntheticBoldOffset();
// We special case spaces in two ways when applying word rounding.
// First, we round spaces to an adjusted width in all fonts.
// Second, in fixed-pitch fonts we ensure that all glyphs that
// match the width of the space glyph have the same width as the space glyph.
- if (roundedAdvanceWidth == roundedSpaceWidth && (fontData->m_treatAsFixedPitch || glyph == fontData->m_spaceGlyph) && m_run.applyWordRounding())
- advance.width = fontData->m_adjustedSpaceWidth;
+ if (roundedAdvanceWidth == roundedSpaceWidth && (fontData->pitch() == FixedPitch || glyph == fontData->spaceGlyph()) && m_run.applyWordRounding())
+ advance.width = fontData->adjustedSpaceWidth();
if (hasExtraSpacing) {
// If we're a glyph with an advance, go ahead and add in letter-spacing.
@@ -475,7 +479,7 @@ void CoreTextController::adjustGlyphsAndAdvances()
advance.width += m_font.letterSpacing();
// Handle justification and word-spacing.
- if (glyph == fontData->m_spaceGlyph) {
+ if (glyph == fontData->spaceGlyph()) {
// Account for padding. WebCore uses space padding to justify text.
// We distribute the specified padding over the available spaces in the run.
if (m_padding) {
diff --git a/WebCore/platform/graphics/mac/CoreTextController.h b/WebCore/platform/graphics/mac/CoreTextController.h
index 8dbb7fb..4dd6f93 100644
--- a/WebCore/platform/graphics/mac/CoreTextController.h
+++ b/WebCore/platform/graphics/mac/CoreTextController.h
@@ -37,7 +37,7 @@ namespace WebCore {
class CoreTextController {
public:
- CoreTextController(const Font*, const TextRun&, bool mayUseNaturalWritingDirection = false);
+ CoreTextController(const Font*, const TextRun&, bool mayUseNaturalWritingDirection = false, HashSet<const SimpleFontData*>* fallbackFonts = 0);
// Advance and emit glyphs up to the specified character.
void advance(unsigned to, GlyphBuffer* = 0);
@@ -106,6 +106,8 @@ private:
float m_padding;
float m_padPerSpace;
+ HashSet<const SimpleFontData*>* m_fallbackFonts;
+
unsigned m_lastRoundingGlyph;
};
diff --git a/WebCore/platform/graphics/mac/FontCacheMac.mm b/WebCore/platform/graphics/mac/FontCacheMac.mm
index 2202459..2730d5a 100644
--- a/WebCore/platform/graphics/mac/FontCacheMac.mm
+++ b/WebCore/platform/graphics/mac/FontCacheMac.mm
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com>
*
* Redistribution and use in source and binary forms, with or without
@@ -44,16 +44,30 @@ typedef int NSInteger;
namespace WebCore {
+#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+static void fontCacheRegisteredFontsChangedNotificationCallback(CFNotificationCenterRef, void* observer, CFStringRef name, const void *, CFDictionaryRef)
+{
+ ASSERT_UNUSED(observer, observer == fontCache());
+ ASSERT_UNUSED(name, CFEqual(name, kCTFontManagerRegisteredFontsChangedNotification));
+ fontCache()->invalidate();
+}
+#else
static void fontCacheATSNotificationCallback(ATSFontNotificationInfoRef, void*)
{
fontCache()->invalidate();
}
+#endif
void FontCache::platformInit()
{
wkSetUpFontCache();
+#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+ CFNotificationCenterAddObserver(CFNotificationCenterGetLocalCenter(), this, fontCacheRegisteredFontsChangedNotificationCallback, kCTFontManagerRegisteredFontsChangedNotification, 0, CFNotificationSuspensionBehaviorDeliverImmediately);
+#else
+ // kCTFontManagerRegisteredFontsChangedNotification does not exist on Leopard and earlier.
// FIXME: Passing kATSFontNotifyOptionReceiveWhileSuspended may be an overkill and does not seem to work anyway.
ATSFontNotificationSubscribe(fontCacheATSNotificationCallback, kATSFontNotifyOptionReceiveWhileSuspended, 0, 0);
+#endif
}
static int toAppKitFontWeight(FontWeight fontWeight)
diff --git a/WebCore/platform/graphics/mac/FontMac.mm b/WebCore/platform/graphics/mac/FontMac.mm
index dc86c4b..df9494a 100644
--- a/WebCore/platform/graphics/mac/FontMac.mm
+++ b/WebCore/platform/graphics/mac/FontMac.mm
@@ -28,7 +28,6 @@
#import "Logging.h"
#import "SimpleFontData.h"
#import "WebCoreSystemInterface.h"
-#import "WebCoreTextRenderer.h"
#import <AppKit/AppKit.h>
#define SYNTHETIC_OBLIQUE_ANGLE 14
@@ -43,12 +42,17 @@ using namespace std;
namespace WebCore {
+bool Font::canReturnFallbackFontsForComplexText()
+{
+ return true;
+}
+
void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point) const
{
CGContextRef cgContext = context->platformContext();
bool originalShouldUseFontSmoothing = wkCGContextGetShouldSmoothFonts(cgContext);
- bool newShouldUseFontSmoothing = WebCoreShouldUseFontSmoothing();
+ bool newShouldUseFontSmoothing = shouldUseSmoothing();
if (originalShouldUseFontSmoothing != newShouldUseFontSmoothing)
CGContextSetShouldSmoothFonts(cgContext, newShouldUseFontSmoothing);
@@ -99,8 +103,8 @@ void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, cons
context->setFillColor(shadowFillColor);
CGContextSetTextPosition(cgContext, point.x() + shadowSize.width(), point.y() + shadowSize.height());
CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
- if (font->m_syntheticBoldOffset) {
- CGContextSetTextPosition(cgContext, point.x() + shadowSize.width() + font->m_syntheticBoldOffset, point.y() + shadowSize.height());
+ if (font->syntheticBoldOffset()) {
+ CGContextSetTextPosition(cgContext, point.x() + shadowSize.width() + font->syntheticBoldOffset(), point.y() + shadowSize.height());
CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
}
context->setFillColor(fillColor);
@@ -108,8 +112,8 @@ void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, cons
CGContextSetTextPosition(cgContext, point.x(), point.y());
CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
- if (font->m_syntheticBoldOffset) {
- CGContextSetTextPosition(cgContext, point.x() + font->m_syntheticBoldOffset, point.y());
+ if (font->syntheticBoldOffset()) {
+ CGContextSetTextPosition(cgContext, point.x() + font->syntheticBoldOffset(), point.y());
CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
}
diff --git a/WebCore/platform/graphics/mac/FontMacATSUI.mm b/WebCore/platform/graphics/mac/FontMacATSUI.mm
index 3794149..051abb7 100644
--- a/WebCore/platform/graphics/mac/FontMacATSUI.mm
+++ b/WebCore/platform/graphics/mac/FontMacATSUI.mm
@@ -47,13 +47,15 @@ namespace WebCore {
struct ATSULayoutParameters : Noncopyable
{
- ATSULayoutParameters(const TextRun& run)
+ ATSULayoutParameters(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts = 0)
: m_run(run)
, m_font(0)
, m_hasSyntheticBold(false)
, m_syntheticBoldPass(false)
, m_padPerSpace(0)
- {}
+ , m_fallbackFonts(fallbackFonts)
+ {
+ }
~ATSULayoutParameters()
{
@@ -73,6 +75,7 @@ struct ATSULayoutParameters : Noncopyable
bool m_hasSyntheticBold;
bool m_syntheticBoldPass;
float m_padPerSpace;
+ HashSet<const SimpleFontData*>* m_fallbackFonts;
};
static TextRun copyRunForDirectionalOverrideIfNecessary(const TextRun& run, OwnArrayPtr<UChar>& charactersWithOverride)
@@ -124,7 +127,7 @@ static void initializeATSUStyle(const SimpleFontData* fontData)
ATSUFontID fontID = fontData->platformData().m_atsuFontID;
if (!fontID) {
- LOG_ERROR("unable to get ATSUFontID for %@", fontData->m_font.font());
+ LOG_ERROR("unable to get ATSUFontID for %@", fontData->platformData().font());
return;
}
@@ -134,7 +137,7 @@ static void initializeATSUStyle(const SimpleFontData* fontData)
LOG_ERROR("ATSUCreateStyle failed (%d)", status);
CGAffineTransform transform = CGAffineTransformMakeScale(1, -1);
- if (fontData->m_font.m_syntheticOblique)
+ if (fontData->platformData().m_syntheticOblique)
transform = CGAffineTransformConcat(transform, CGAffineTransformMake(1, 0, -tanf(SYNTHETIC_OBLIQUE_ANGLE * acosf(0) / 90), 1, 0, 0));
Fixed fontSize = FloatToFixed(fontData->platformData().m_size);
ByteCount styleSizes[4] = { sizeof(Fixed), sizeof(ATSUFontID), sizeof(CGAffineTransform), sizeof(Fract) };
@@ -180,7 +183,6 @@ static OSStatus overrideLayoutOperation(ATSULayoutOperationSelector, ATSULineRef
bool shouldRound = false;
bool syntheticBoldPass = params->m_syntheticBoldPass;
Fixed syntheticBoldOffset = 0;
- ATSGlyphRef spaceGlyph = 0;
bool hasExtraSpacing = (params->m_font->letterSpacing() || params->m_font->wordSpacing() || params->m_run.padding()) && !params->m_run.spacingDisabled();
float padding = params->m_run.padding();
// In the CoreGraphics code path, the rounding hack is applied in logical order.
@@ -190,27 +192,28 @@ static OSStatus overrideLayoutOperation(ATSULayoutOperationSelector, ATSULineRef
for (i = 1; i < count; i++) {
bool isLastChar = i == count - 1;
renderer = renderers[offset / 2];
- if (renderer != lastRenderer) {
- lastRenderer = renderer;
- spaceGlyph = renderer->m_spaceGlyph;
- // The CoreGraphics interpretation of NSFontAntialiasedIntegerAdvancementsRenderingMode seems
- // to be "round each glyph's width to the nearest integer". This is not the same as ATSUI
- // does in any of its device-metrics modes.
- shouldRound = renderer->platformData().roundsGlyphAdvances();
- if (syntheticBoldPass)
- syntheticBoldOffset = FloatToFixed(renderer->m_syntheticBoldOffset);
- }
float width;
if (nextCh == zeroWidthSpace || Font::treatAsZeroWidthSpace(nextCh) && !Font::treatAsSpace(nextCh)) {
width = 0;
- layoutRecords[i-1].glyphID = spaceGlyph;
+ layoutRecords[i-1].glyphID = renderer->spaceGlyph();
} else {
width = FixedToFloat(layoutRecords[i].realPos - lastNativePos);
+ if (renderer != lastRenderer && width) {
+ lastRenderer = renderer;
+ // The CoreGraphics interpretation of NSFontAntialiasedIntegerAdvancementsRenderingMode seems
+ // to be "round each glyph's width to the nearest integer". This is not the same as ATSUI
+ // does in any of its device-metrics modes.
+ shouldRound = renderer->platformData().roundsGlyphAdvances();
+ if (syntheticBoldPass)
+ syntheticBoldOffset = FloatToFixed(renderer->syntheticBoldOffset());
+ if (params->m_fallbackFonts && renderer != params->m_font->primaryFont())
+ params->m_fallbackFonts->add(renderer);
+ }
if (shouldRound)
width = roundf(width);
- width += renderer->m_syntheticBoldOffset;
- if (renderer->m_treatAsFixedPitch ? width == renderer->m_spaceWidth : (layoutRecords[i-1].flags & kATSGlyphInfoIsWhiteSpace))
- width = renderer->m_adjustedSpaceWidth;
+ width += renderer->syntheticBoldOffset();
+ if (renderer->pitch() == FixedPitch ? width == renderer->spaceWidth() : (layoutRecords[i-1].flags & kATSGlyphInfoIsWhiteSpace))
+ width = renderer->adjustedSpaceWidth();
}
lastNativePos = layoutRecords[i].realPos;
@@ -258,7 +261,7 @@ static OSStatus overrideLayoutOperation(ATSULayoutOperationSelector, ATSULineRef
if (syntheticBoldOffset)
layoutRecords[i-1].realPos += syntheticBoldOffset;
else
- layoutRecords[i-1].glyphID = spaceGlyph;
+ layoutRecords[i-1].glyphID = renderer->spaceGlyph();
}
layoutRecords[i].realPos = FloatToFixed(lastAdjustedPos);
}
@@ -460,7 +463,7 @@ void ATSULayoutParameters::initialize(const Font* font, const GraphicsContext* g
}
} else
m_fonts[i] = r;
- if (m_fonts[i]->m_syntheticBoldOffset)
+ if (m_fonts[i]->syntheticBoldOffset())
m_hasSyntheticBold = true;
}
substituteOffset += substituteLength;
@@ -570,12 +573,12 @@ void Font::drawComplexText(GraphicsContext* graphicsContext, const TextRun& run,
graphicsContext->setShadow(shadowSize, shadowBlur, shadowColor);
}
-float Font::floatWidthForComplexText(const TextRun& run) const
+float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts) const
{
if (run.length() == 0)
return 0;
- ATSULayoutParameters params(run);
+ ATSULayoutParameters params(run, fallbackFonts);
params.initialize(this);
OSStatus status;
diff --git a/WebCore/platform/graphics/mac/FontMacCoreText.cpp b/WebCore/platform/graphics/mac/FontMacCoreText.cpp
index 5fb9d5d..9dffc7a 100644
--- a/WebCore/platform/graphics/mac/FontMacCoreText.cpp
+++ b/WebCore/platform/graphics/mac/FontMacCoreText.cpp
@@ -86,9 +86,9 @@ void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const F
drawGlyphBuffer(context, glyphBuffer, run, startPoint);
}
-float Font::floatWidthForComplexText(const TextRun& run) const
+float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts) const
{
- CoreTextController controller(this, run, true);
+ CoreTextController controller(this, run, true, fallbackFonts);
return controller.totalWidth();
}
diff --git a/WebCore/platform/graphics/mac/FontPlatformData.h b/WebCore/platform/graphics/mac/FontPlatformData.h
index e911867..1b7b884 100644
--- a/WebCore/platform/graphics/mac/FontPlatformData.h
+++ b/WebCore/platform/graphics/mac/FontPlatformData.h
@@ -82,6 +82,8 @@ struct FontPlatformData {
bool isHashTableDeletedValue() const { return m_font == hashTableDeletedFontValue(); }
float size() const { return m_size; }
+ bool syntheticBold() const { return m_syntheticBold; }
+ bool syntheticOblique() const { return m_syntheticOblique; }
bool m_syntheticBold;
bool m_syntheticOblique;
diff --git a/WebCore/platform/graphics/mac/GraphicsContextMac.mm b/WebCore/platform/graphics/mac/GraphicsContextMac.mm
index 4e11602..2404319 100644
--- a/WebCore/platform/graphics/mac/GraphicsContextMac.mm
+++ b/WebCore/platform/graphics/mac/GraphicsContextMac.mm
@@ -96,27 +96,28 @@ static NSColor* createPatternColor(NSString* name, NSColor* defaultColor, bool&
color = defaultColor;
return color;
}
-
+
+// WebKit on Mac is a standard platform component, so it must use the standard platform artwork for underline.
void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint& point, int width, bool grammar)
{
if (paintingDisabled())
return;
- // These are the same for misspelling or bad grammar
+ // These are the same for misspelling or bad grammar.
int patternHeight = cMisspellingLineThickness;
int patternWidth = cMisspellingLinePatternWidth;
bool usingDot;
NSColor *patternColor;
if (grammar) {
- // Constants for grammar pattern color
+ // Constants for grammar pattern color.
static bool usingDotForGrammar = false;
DEFINE_STATIC_LOCAL(RetainPtr<NSColor>, grammarPatternColor, (createPatternColor(@"GrammarDot", [NSColor greenColor], usingDotForGrammar)));
usingDot = usingDotForGrammar;
patternColor = grammarPatternColor.get();
} else {
- // Constants for spelling pattern color
+ // Constants for spelling pattern color.
static bool usingDotForSpelling = false;
DEFINE_STATIC_LOCAL(RetainPtr<NSColor>, spellingPatternColor, (createPatternColor(@"SpellingDot", [NSColor redColor], usingDotForSpelling)));
@@ -141,7 +142,7 @@ void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint& point,
// FIXME: This code should not be using wkSetPatternPhaseInUserSpace, as this approach is wrong
// for transforms.
- // Draw underline
+ // Draw underline.
NSGraphicsContext *currentContext = [NSGraphicsContext currentContext];
CGContextRef context = (CGContextRef)[currentContext graphicsPort];
CGContextSaveGState(context);
diff --git a/WebCore/platform/graphics/mac/GraphicsLayerCA.h b/WebCore/platform/graphics/mac/GraphicsLayerCA.h
index 3a692d3..50138d5 100644
--- a/WebCore/platform/graphics/mac/GraphicsLayerCA.h
+++ b/WebCore/platform/graphics/mac/GraphicsLayerCA.h
@@ -117,9 +117,8 @@ private:
bool requiresTiledLayer(const FloatSize&) const;
void swapFromOrToTiledLayer(bool useTiledLayer);
- void setHasContentsLayer(bool);
void setContentsLayer(WebLayer*);
- void setContentsLayerFlipped(bool);
+ WebLayer* contentsLayer() const { return m_contentsLayer.get(); }
RetainPtr<WebLayer> m_layer;
RetainPtr<WebLayer> m_transformLayer;
diff --git a/WebCore/platform/graphics/mac/GraphicsLayerCA.mm b/WebCore/platform/graphics/mac/GraphicsLayerCA.mm
index f3f2d7f..f361437 100644
--- a/WebCore/platform/graphics/mac/GraphicsLayerCA.mm
+++ b/WebCore/platform/graphics/mac/GraphicsLayerCA.mm
@@ -271,9 +271,9 @@ static bool forceSoftwareAnimation()
return forceSoftwareAnimation;
}
-bool GraphicsLayer::graphicsContextsFlipped()
+GraphicsLayer::CompositingCoordinatesOrientation GraphicsLayer::compositingCoordinatesOrientation()
{
- return true;
+ return CompositingCoordinatesBottomUp;
}
#ifndef NDEBUG
@@ -746,8 +746,10 @@ void GraphicsLayerCA::setDrawsContent(bool drawsContent)
swapFromOrToTiledLayer(needTiledLayer);
BEGIN_BLOCK_OBJC_EXCEPTIONS
- // Clobber any existing content. If necessary, CA will create backing store on the next display.
- [m_layer.get() setContents:nil];
+ if (m_drawsContent)
+ [m_layer.get() setNeedsDisplay];
+ else
+ [m_layer.get() setContents:nil];
#ifndef NDEBUG
updateDebugIndicators();
@@ -761,7 +763,14 @@ void GraphicsLayerCA::setBackgroundColor(const Color& color, const Animation* tr
GraphicsLayer::setBackgroundColor(color, transition, beginTime);
BEGIN_BLOCK_OBJC_EXCEPTIONS
- setHasContentsLayer(true);
+
+ if (!m_contentsLayer.get()) {
+ WebLayer* colorLayer = [WebLayer layer];
+#ifndef NDEBUG
+ [colorLayer setName:@"Color Layer"];
+#endif
+ setContentsLayer(colorLayer);
+ }
if (transition && !transition->isEmptyOrZeroDuration()) {
CALayer* presLayer = [m_contentsLayer.get() presentationLayer];
@@ -777,7 +786,6 @@ void GraphicsLayerCA::setBackgroundColor(const Color& color, const Animation* tr
CGColorRelease(bgColor);
} else {
removeAllAnimationsForProperty(AnimatedPropertyBackgroundColor);
- setHasContentsLayer(true);
setLayerBackgroundColor(m_contentsLayer.get(), m_backgroundColor);
}
@@ -787,7 +795,7 @@ void GraphicsLayerCA::setBackgroundColor(const Color& color, const Animation* tr
void GraphicsLayerCA::clearBackgroundColor()
{
if (!m_contentLayerForImageOrVideo)
- setHasContentsLayer(false);
+ setContentsLayer(0);
else
clearLayerBackgroundColor(m_contentsLayer.get());
}
@@ -1082,35 +1090,27 @@ bool GraphicsLayerCA::animateFloat(AnimatedPropertyID property, const FloatValue
void GraphicsLayerCA::setContentsToImage(Image* image)
{
if (image) {
- setHasContentsLayer(true);
-
- // FIXME: is image flipping really a property of the graphics context?
- bool needToFlip = GraphicsLayer::graphicsContextsFlipped();
- CGPoint anchorPoint = needToFlip ? CGPointMake(0.0f, 1.0f) : CGPointZero;
-
BEGIN_BLOCK_OBJC_EXCEPTIONS
{
- CGImageRef theImage = image->nativeImageForCurrentFrame();
+ if (!m_contentsLayer.get()) {
+ WebLayer* imageLayer = [WebLayer layer];
+#ifndef NDEBUG
+ [imageLayer setName:@"Image Layer"];
+#endif
+ setContentsLayer(imageLayer);
+ }
+
// FIXME: maybe only do trilinear if the image is being scaled down,
// but then what if the layer size changes?
-#if HAVE_MODERN_QUARTZCORE
+#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
[m_contentsLayer.get() setMinificationFilter:kCAFilterTrilinear];
#endif
- if (needToFlip) {
- CATransform3D flipper = {
- 1.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, -1.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 1.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f};
- [m_contentsLayer.get() setTransform:flipper];
- }
-
- [m_contentsLayer.get() setAnchorPoint:anchorPoint];
+ CGImageRef theImage = image->nativeImageForCurrentFrame();
[m_contentsLayer.get() setContents:(id)theImage];
}
END_BLOCK_OBJC_EXCEPTIONS
} else
- setHasContentsLayer(false);
+ setContentsLayer(0);
m_contentLayerForImageOrVideo = (image != 0);
}
@@ -1124,7 +1124,7 @@ void GraphicsLayerCA::setContentsToVideo(PlatformLayer* videoLayer)
void GraphicsLayerCA::clearContents()
{
if (m_contentLayerForImageOrVideo) {
- setHasContentsLayer(false);
+ setContentsLayer(0);
m_contentLayerForImageOrVideo = false;
}
}
@@ -1431,7 +1431,7 @@ void GraphicsLayerCA::swapFromOrToTiledLayer(bool userTiledLayer)
[tiledLayer setLevelsOfDetail:1];
[tiledLayer setLevelsOfDetailBias:0];
- if (GraphicsLayer::graphicsContextsFlipped())
+ if (GraphicsLayer::compositingCoordinatesOrientation() == GraphicsLayer::CompositingCoordinatesBottomUp)
[tiledLayer setContentsGravity:@"bottomLeft"];
else
[tiledLayer setContentsGravity:@"topLeft"];
@@ -1476,24 +1476,6 @@ void GraphicsLayerCA::swapFromOrToTiledLayer(bool userTiledLayer)
#endif
}
-void GraphicsLayerCA::setHasContentsLayer(bool hasLayer)
-{
- BEGIN_BLOCK_OBJC_EXCEPTIONS
-
- if (hasLayer && !m_contentsLayer) {
- // create the inner layer
- WebLayer* contentsLayer = [WebLayer layer];
-#ifndef NDEBUG
- [contentsLayer setName:@"Contents Layer"];
-#endif
- setContentsLayer(contentsLayer);
-
- } else if (!hasLayer && m_contentsLayer)
- setContentsLayer(0);
-
- END_BLOCK_OBJC_EXCEPTIONS
-}
-
void GraphicsLayerCA::setContentsLayer(WebLayer* contentsLayer)
{
if (contentsLayer == m_contentsLayer)
@@ -1511,14 +1493,26 @@ void GraphicsLayerCA::setContentsLayer(WebLayer* contentsLayer)
[contentsLayer setStyle:[NSDictionary dictionaryWithObject:nullActionsDictionary() forKey:@"actions"]];
m_contentsLayer.adoptNS([contentsLayer retain]);
- [m_contentsLayer.get() setAnchorPoint:CGPointZero];
- [m_layer.get() addSublayer:m_contentsLayer.get()];
- updateContentsRect();
+ bool needToFlip = GraphicsLayer::compositingCoordinatesOrientation() == GraphicsLayer::CompositingCoordinatesBottomUp;
+ CGPoint anchorPoint = needToFlip ? CGPointMake(0.0f, 1.0f) : CGPointZero;
- // Set contents to nil if the layer does not draw its own content.
- if (m_client && !drawsContent())
- [m_layer.get() setContents:nil];
+ // If the layer world is flipped, we need to un-flip the contents layer
+ if (needToFlip) {
+ CATransform3D flipper = {
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, -1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f};
+ [m_contentsLayer.get() setTransform:flipper];
+ }
+ [m_contentsLayer.get() setAnchorPoint:anchorPoint];
+
+ // Insert the content layer first. Video elements require this, because they have
+ // shadow content that must display in front of the video.
+ [m_layer.get() insertSublayer:m_contentsLayer.get() atIndex:0];
+
+ updateContentsRect();
#ifndef NDEBUG
if (showDebugBorders()) {
diff --git a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h
index 677c31a..f90f258 100644
--- a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h
+++ b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h
@@ -30,6 +30,7 @@
#include "MediaPlayerPrivate.h"
#include "Timer.h"
+#include "FloatSize.h"
#include <wtf/RetainPtr.h>
#ifdef __OBJC__
@@ -127,6 +128,8 @@ private:
float maxTimeLoaded() const;
void disableUnsupportedTracks();
+ void sawUnsupportedTracks();
+ void cacheMovieScale();
bool metaDataAvailable() const { return m_qtMovie && m_readyState >= MediaPlayer::HaveMetadata; }
MediaPlayer* m_player;
@@ -142,7 +145,10 @@ private:
bool m_isStreaming;
bool m_visible;
IntRect m_rect;
+ FloatSize m_scaleFactor;
unsigned m_enabledTrackCount;
+ unsigned m_totalTrackCount;
+ bool m_hasUnsupportedTracks;
float m_duration;
#if DRAW_FRAME_RATE
int m_frameCountWhilePlaying;
diff --git a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
index 74a9ff9..dd41ed3 100644
--- a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
+++ b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
@@ -37,6 +37,7 @@
#import "FrameView.h"
#import "GraphicsContext.h"
#import "KURL.h"
+#import "MIMETypeRegistry.h"
#import "SoftLinking.h"
#import "WebCoreSystemInterface.h"
#import <QTKit/QTKit.h>
@@ -67,6 +68,7 @@ SOFT_LINK(QTKit, QTMakeTime, QTTime, (long long timeValue, long timeScale), (tim
SOFT_LINK_CLASS(QTKit, QTMovie)
SOFT_LINK_CLASS(QTKit, QTMovieView)
+SOFT_LINK_POINTER(QTKit, QTTrackMediaTypeAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTMediaTypeAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTMediaTypeBase, NSString *)
SOFT_LINK_POINTER(QTKit, QTMediaTypeMPEG, NSString *)
@@ -81,6 +83,7 @@ SOFT_LINK_POINTER(QTKit, QTMovieIsActiveAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieLoadStateAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieLoadStateDidChangeNotification, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieNaturalSizeAttribute, NSString *)
+SOFT_LINK_POINTER(QTKit, QTMovieCurrentSizeAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTMoviePreventExternalURLLinksAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieRateDidChangeNotification, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieSizeDidChangeNotification, NSString *)
@@ -90,10 +93,15 @@ SOFT_LINK_POINTER(QTKit, QTMovieURLAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieVolumeDidChangeNotification, NSString *)
SOFT_LINK_POINTER(QTKit, QTSecurityPolicyNoCrossSiteAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTVideoRendererWebKitOnlyNewImageAvailableNotification, NSString *)
+#ifndef BUILDING_ON_TIGER
+SOFT_LINK_POINTER(QTKit, QTMovieApertureModeClean, NSString *)
+SOFT_LINK_POINTER(QTKit, QTMovieApertureModeAttribute, NSString *)
+#endif
#define QTMovie getQTMovieClass()
#define QTMovieView getQTMovieViewClass()
+#define QTTrackMediaTypeAttribute getQTTrackMediaTypeAttribute()
#define QTMediaTypeAttribute getQTMediaTypeAttribute()
#define QTMediaTypeBase getQTMediaTypeBase()
#define QTMediaTypeMPEG getQTMediaTypeMPEG()
@@ -108,6 +116,7 @@ SOFT_LINK_POINTER(QTKit, QTVideoRendererWebKitOnlyNewImageAvailableNotification,
#define QTMovieLoadStateAttribute getQTMovieLoadStateAttribute()
#define QTMovieLoadStateDidChangeNotification getQTMovieLoadStateDidChangeNotification()
#define QTMovieNaturalSizeAttribute getQTMovieNaturalSizeAttribute()
+#define QTMovieCurrentSizeAttribute getQTMovieCurrentSizeAttribute()
#define QTMoviePreventExternalURLLinksAttribute getQTMoviePreventExternalURLLinksAttribute()
#define QTMovieRateDidChangeNotification getQTMovieRateDidChangeNotification()
#define QTMovieSizeDidChangeNotification getQTMovieSizeDidChangeNotification()
@@ -117,6 +126,10 @@ SOFT_LINK_POINTER(QTKit, QTVideoRendererWebKitOnlyNewImageAvailableNotification,
#define QTMovieVolumeDidChangeNotification getQTMovieVolumeDidChangeNotification()
#define QTSecurityPolicyNoCrossSiteAttribute getQTSecurityPolicyNoCrossSiteAttribute()
#define QTVideoRendererWebKitOnlyNewImageAvailableNotification getQTVideoRendererWebKitOnlyNewImageAvailableNotification()
+#ifndef BUILDING_ON_TIGER
+#define QTMovieApertureModeClean getQTMovieApertureModeClean()
+#define QTMovieApertureModeAttribute getQTMovieApertureModeAttribute()
+#endif
// Older versions of the QTKit header don't have these constants.
#if !defined QTKIT_VERSION_MAX_ALLOWED || QTKIT_VERSION_MAX_ALLOWED <= QTKIT_VERSION_7_0
@@ -184,7 +197,10 @@ MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
, m_isStreaming(false)
, m_visible(false)
, m_rect()
+ , m_scaleFactor(1, 1)
, m_enabledTrackCount(0)
+ , m_totalTrackCount(0)
+ , m_hasUnsupportedTracks(false)
, m_duration(-1.0f)
#if DRAW_FRAME_RATE
, m_frameCountWhilePlaying(0)
@@ -221,10 +237,15 @@ void MediaPlayerPrivate::createQTMovie(const String& url)
[NSNumber numberWithBool:YES], QTMoviePreventExternalURLLinksAttribute,
[NSNumber numberWithBool:YES], QTSecurityPolicyNoCrossSiteAttribute,
[NSNumber numberWithBool:NO], QTMovieAskUnresolvedDataRefsAttribute,
- [NSNumber numberWithBool:YES], @"QTMovieOpenForPlaybackAttribute", // FIXME: Use defined attribute when required version of QT supports this attribute
+#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+ [NSNumber numberWithBool:YES], @"QTMovieOpenForPlaybackAttribute",
+#endif
+#ifndef BUILDING_ON_TIGER
+ QTMovieApertureModeClean, QTMovieApertureModeAttribute,
+#endif
nil];
- NSError* error = nil;
+ NSError *error = nil;
m_qtMovie.adoptNS([[QTMovie alloc] initWithAttributes:movieAttributes error:&error]);
// FIXME: Find a proper way to detect streaming content.
@@ -239,6 +260,17 @@ void MediaPlayerPrivate::createQTMovie(const String& url)
selector:@selector(loadStateChanged:)
name:QTMovieLoadStateDidChangeNotification
object:m_qtMovie.get()];
+
+ // In updateState(), we track when maxTimeLoaded() == duration().
+ // In newer version of QuickTime, a notification is emitted when maxTimeLoaded changes.
+ // In older version of QuickTime, QTMovieLoadStateDidChangeNotification be fired.
+ if (NSString *maxTimeLoadedChangeNotification = wkQTMovieMaxTimeLoadedChangeNotification()) {
+ [[NSNotificationCenter defaultCenter] addObserver:m_objcObserver.get()
+ selector:@selector(loadStateChanged:)
+ name:maxTimeLoadedChangeNotification
+ object:m_qtMovie.get()];
+ }
+
[[NSNotificationCenter defaultCenter] addObserver:m_objcObserver.get()
selector:@selector(rateChanged:)
name:QTMovieRateDidChangeNotification
@@ -545,7 +577,16 @@ IntSize MediaPlayerPrivate::naturalSize() const
{
if (!metaDataAvailable())
return IntSize();
- return IntSize([[m_qtMovie.get() attributeForKey:QTMovieNaturalSizeAttribute] sizeValue]);
+
+ // In spite of the name of this method, return QTMovieNaturalSizeAttribute transformed by the
+ // initial movie scale because the spec says intrinsic size is:
+ //
+ // ... the dimensions of the resource in CSS pixels after taking into account the resource's
+ // dimensions, aspect ratio, clean aperture, resolution, and so forth, as defined for the
+ // format used by the resource
+
+ NSSize naturalSize = [[m_qtMovie.get() attributeForKey:QTMovieNaturalSizeAttribute] sizeValue];
+ return IntSize(naturalSize.width * m_scaleFactor.width(), naturalSize.height * m_scaleFactor.height());
}
bool MediaPlayerPrivate::hasVideo() const
@@ -586,8 +627,14 @@ float MediaPlayerPrivate::maxTimeBuffered() const
float MediaPlayerPrivate::maxTimeSeekable() const
{
+ if (!metaDataAvailable())
+ return 0;
+
// infinite duration means live stream
- return isinf(duration()) ? 0 : maxTimeLoaded();
+ if (isinf(duration()))
+ return 0;
+
+ return wkQTMovieMaxTimeSeekable(m_qtMovie.get());
}
float MediaPlayerPrivate::maxTimeLoaded() const
@@ -629,6 +676,31 @@ void MediaPlayerPrivate::cancelLoad()
updateStates();
}
+void MediaPlayerPrivate::cacheMovieScale()
+{
+ NSSize initialSize = NSZeroSize;
+ NSSize naturalSize = [[m_qtMovie.get() attributeForKey:QTMovieNaturalSizeAttribute] sizeValue];
+
+#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+ // QTMovieCurrentSizeAttribute is not allowed with instances of QTMovie that have been
+ // opened with QTMovieOpenForPlaybackAttribute, so ask for the display transform attribute instead.
+ NSAffineTransform *displayTransform = [m_qtMovie.get() attributeForKey:@"QTMoviePreferredTransformAttribute"];
+ if (displayTransform)
+ initialSize = [displayTransform transformSize:naturalSize];
+ else {
+ initialSize.width = naturalSize.width;
+ initialSize.height = naturalSize.height;
+ }
+#else
+ initialSize = [[m_qtMovie.get() attributeForKey:QTMovieCurrentSizeAttribute] sizeValue];
+#endif
+
+ if (naturalSize.width)
+ m_scaleFactor.setWidth(initialSize.width / naturalSize.width);
+ if (naturalSize.height)
+ m_scaleFactor.setHeight(initialSize.height / naturalSize.height);
+}
+
void MediaPlayerPrivate::updateStates()
{
MediaPlayer::NetworkState oldNetworkState = m_networkState;
@@ -636,18 +708,37 @@ void MediaPlayerPrivate::updateStates()
long loadState = m_qtMovie ? [[m_qtMovie.get() attributeForKey:QTMovieLoadStateAttribute] longValue] : static_cast<long>(QTMovieLoadStateError);
- if (loadState >= QTMovieLoadStateLoaded && m_readyState < MediaPlayer::HaveMetadata && !m_player->inMediaDocument()) {
+ if (loadState >= QTMovieLoadStateLoaded && m_readyState < MediaPlayer::HaveMetadata) {
disableUnsupportedTracks();
- if (!m_enabledTrackCount)
+ if (m_player->inMediaDocument()) {
+ if (!m_enabledTrackCount || m_enabledTrackCount != m_totalTrackCount) {
+ // This is a type of media that we do not handle directly with a <video>
+ // element, likely streamed media or QuickTime VR. Tell the MediaPlayerClient
+ // that we noticed.
+ sawUnsupportedTracks();
+ return;
+ }
+ } else if (!m_enabledTrackCount) {
loadState = QTMovieLoadStateError;
+ }
+
+ if (loadState != QTMovieLoadStateError)
+ cacheMovieScale();
}
- if (loadState >= QTMovieLoadStateComplete && !m_isStreaming) {
+ BOOL completelyLoaded = !m_isStreaming && (loadState >= QTMovieLoadStateComplete);
+
+ // Note: QT indicates that we are fully loaded with QTMovieLoadStateComplete.
+ // However newer versions of QT do not, so we check maxTimeLoaded against duration.
+ if (!completelyLoaded && !m_isStreaming && metaDataAvailable())
+ completelyLoaded = maxTimeLoaded() == duration();
+
+ if (completelyLoaded) {
// "Loaded" is reserved for fully buffered movies, never the case when streaming
m_networkState = MediaPlayer::Loaded;
m_readyState = MediaPlayer::HaveEnoughData;
} else if (loadState >= QTMovieLoadStatePlaythroughOK) {
- m_readyState = MediaPlayer::HaveFutureData;
+ m_readyState = MediaPlayer::HaveEnoughData;
m_networkState = MediaPlayer::Loading;
} else if (loadState >= QTMovieLoadStatePlayable) {
// FIXME: This might not work correctly in streaming case, <rdar://problem/5693967>
@@ -657,11 +748,17 @@ void MediaPlayerPrivate::updateStates()
m_readyState = MediaPlayer::HaveMetadata;
m_networkState = MediaPlayer::Loading;
} else if (loadState > QTMovieLoadStateError) {
- m_readyState = MediaPlayer::HaveNothing;
+ m_readyState = MediaPlayer::HaveNothing;
m_networkState = MediaPlayer::Loading;
} else {
- float loaded = maxTimeLoaded();
+ if (m_player->inMediaDocument()) {
+ // Something went wrong in the loading of media within a standalone file.
+ // This can occur with chained refmovies pointing to streamed media.
+ sawUnsupportedTracks();
+ return;
+ }
+ float loaded = maxTimeLoaded();
if (!loaded)
m_readyState = MediaPlayer::HaveNothing;
@@ -684,7 +781,7 @@ void MediaPlayerPrivate::updateStates()
if (m_readyState != oldReadyState)
m_player->readyStateChanged();
- if (loadState >= QTMovieLoadStateLoaded && oldReadyState < MediaPlayer::HaveMetadata && m_player->visible())
+ if (loadState >= QTMovieLoadStateLoaded && (!m_qtMovieView && !m_qtVideoRenderer) && m_player->visible())
setUpVideoRendering();
if (loadState >= QTMovieLoadStateLoaded) {
@@ -699,28 +796,39 @@ void MediaPlayerPrivate::updateStates()
void MediaPlayerPrivate::loadStateChanged()
{
- updateStates();
+ if (!m_hasUnsupportedTracks)
+ updateStates();
}
void MediaPlayerPrivate::rateChanged()
{
+ if (m_hasUnsupportedTracks)
+ return;
+
updateStates();
m_player->rateChanged();
}
void MediaPlayerPrivate::sizeChanged()
{
- m_player->sizeChanged();
+ if (!m_hasUnsupportedTracks)
+ m_player->sizeChanged();
}
void MediaPlayerPrivate::timeChanged()
{
+ if (m_hasUnsupportedTracks)
+ return;
+
updateStates();
m_player->timeChanged();
}
void MediaPlayerPrivate::didEnd()
{
+ if (m_hasUnsupportedTracks)
+ return;
+
m_startedPlaying = false;
#if DRAW_FRAME_RATE
m_timeStoppedPlaying = [NSDate timeIntervalSinceReferenceDate];
@@ -729,22 +837,15 @@ void MediaPlayerPrivate::didEnd()
m_player->timeChanged();
}
-void MediaPlayerPrivate::setSize(const IntSize& size)
+void MediaPlayerPrivate::setSize(const IntSize&)
{
- if (!m_qtMovieView)
- return;
-
- m_rect.setSize(size);
- if (m_player->inMediaDocument())
- // We need the QTMovieView to be placed in the proper location for document mode.
- [m_qtMovieView.get() setFrame:m_rect];
- else {
- // We don't really need the QTMovieView in any specific location so let's just get it out of the way
- // where it won't intercept events or try to bring up the context menu.
- IntRect farAwayButCorrectSize(m_rect);
- farAwayButCorrectSize.move(-1000000, -1000000);
- [m_qtMovieView.get() setFrame:farAwayButCorrectSize];
- }
+ // Don't resize the view now because [view setFrame] also resizes the movie itself, and because
+ // the renderer calls this function immediately when we report a size change (QTMovieSizeDidChangeNotification)
+ // we can get into a feedback loop observing the size change and resetting the size, and this can cause
+ // QuickTime to miss resetting a movie's size when the media size changes (as happens with an rtsp movie
+ // once the rtsp server sends the track sizes). Instead we remember the size passed to paint() and resize
+ // the view when it changes.
+ // <rdar://problem/6336092> REGRESSION: rtsp movie does not resize correctly
}
void MediaPlayerPrivate::setVisible(bool b)
@@ -761,6 +862,9 @@ void MediaPlayerPrivate::setVisible(bool b)
void MediaPlayerPrivate::repaint()
{
+ if (m_hasUnsupportedTracks)
+ return;
+
#if DRAW_FRAME_RATE
if (m_startedPlaying) {
m_frameCountWhilePlaying++;
@@ -775,7 +879,7 @@ void MediaPlayerPrivate::repaint()
void MediaPlayerPrivate::paint(GraphicsContext* context, const IntRect& r)
{
- if (context->paintingDisabled())
+ if (context->paintingDisabled() || m_hasUnsupportedTracks)
return;
NSView *view = m_qtMovieView.get();
id qtVideoRenderer = m_qtVideoRenderer.get();
@@ -802,12 +906,28 @@ void MediaPlayerPrivate::paint(GraphicsContext* context, const IntRect& r)
[(id<WebKitVideoRenderingDetails>)qtVideoRenderer drawInRect:paintRect];
[NSGraphicsContext restoreGraphicsState];
} else {
- if (m_player->inMediaDocument() && r != m_rect) {
- // the QTMovieView needs to be placed in the proper location for document mode
- m_rect = r;
- [view setFrame:m_rect];
+ if (m_rect != r) {
+ m_rect = r;
+ if (m_player->inMediaDocument()) {
+ // the QTMovieView needs to be placed in the proper location for document mode
+ [view setFrame:m_rect];
+ }
+ else {
+ // We don't really need the QTMovieView in any specific location so let's just get it out of the way
+ // where it won't intercept events or try to bring up the context menu.
+ IntRect farAwayButCorrectSize(m_rect);
+ farAwayButCorrectSize.move(-1000000, -1000000);
+ [view setFrame:farAwayButCorrectSize];
+ }
}
- [view displayRectIgnoringOpacity:paintRect inContext:newContext];
+
+ if (m_player->inMediaDocument()) {
+ // If we're using a QTMovieView in a media document, the view may get layer-backed. AppKit won't update
+ // the layer hosting correctly if we call displayRectIgnoringOpacity:inContext:, so use displayRectIgnoringOpacity:
+ // in this case. See <rdar://problem/6702882>.
+ [view displayRectIgnoringOpacity:paintRect];
+ } else
+ [view displayRectIgnoringOpacity:paintRect inContext:newContext];
}
#if DRAW_FRAME_RATE
@@ -839,25 +959,57 @@ void MediaPlayerPrivate::paint(GraphicsContext* context, const IntRect& r)
[m_objcObserver.get() setDelayCallbacks:NO];
}
-static HashSet<String> mimeTypeCache()
+static void addFileTypesToCache(NSArray * fileTypes, HashSet<String> &cache)
+{
+ int count = [fileTypes count];
+ for (int n = 0; n < count; n++) {
+ CFStringRef ext = reinterpret_cast<CFStringRef>([fileTypes objectAtIndex:n]);
+ RetainPtr<CFStringRef> uti(AdoptCF, UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, ext, NULL));
+ if (!uti)
+ continue;
+ RetainPtr<CFStringRef> mime(AdoptCF, UTTypeCopyPreferredTagWithClass(uti.get(), kUTTagClassMIMEType));
+
+ // UTI types are missing many media related MIME types supported by QTKit, see rdar://6434168,
+ // and not all third party movie importers register their types, so if we didn't find a type for
+ // this extension look it up in the hard coded table in the MIME type regsitry.
+ if (!mime) {
+ // -movieFileTypes: returns both file extensions and OSTypes. The later are surrounded by single
+ // quotes, eg. 'MooV', so don't bother looking at those.
+ if (CFStringGetCharacterAtIndex(ext, 0) != '\'') {
+ String mediaType = MIMETypeRegistry::getMediaMIMETypeForExtension(String(ext));
+ if (!mediaType.isEmpty())
+ mime.adoptCF(mediaType.createCFString());
+ }
+ }
+ if (!mime)
+ continue;
+ cache.add(mime.get());
+ }
+}
+
+static HashSet<String> mimeCommonTypesCache()
{
DEFINE_STATIC_LOCAL(HashSet<String>, cache, ());
static bool typeListInitialized = false;
if (!typeListInitialized) {
+ typeListInitialized = true;
NSArray* fileTypes = [QTMovie movieFileTypes:QTIncludeCommonTypes];
- int count = [fileTypes count];
- for (int n = 0; n < count; n++) {
- CFStringRef ext = reinterpret_cast<CFStringRef>([fileTypes objectAtIndex:n]);
- RetainPtr<CFStringRef> uti(AdoptCF, UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, ext, NULL));
- if (!uti)
- continue;
- RetainPtr<CFStringRef> mime(AdoptCF, UTTypeCopyPreferredTagWithClass(uti.get(), kUTTagClassMIMEType));
- if (!mime)
- continue;
- cache.add(mime.get());
- }
+ addFileTypesToCache(fileTypes, cache);
+ }
+
+ return cache;
+}
+
+static HashSet<String> mimeModernTypesCache()
+{
+ DEFINE_STATIC_LOCAL(HashSet<String>, cache, ());
+ static bool typeListInitialized = false;
+
+ if (!typeListInitialized) {
typeListInitialized = true;
+ NSArray* fileTypes = [QTMovie movieFileTypes:(QTMovieFileTypeOptions)wkQTIncludeOnlyModernMediaFileTypes()];
+ addFileTypesToCache(fileTypes, cache);
}
return cache;
@@ -865,14 +1017,21 @@ static HashSet<String> mimeTypeCache()
void MediaPlayerPrivate::getSupportedTypes(HashSet<String>& types)
{
- types = mimeTypeCache();
+ // Note: this method starts QTKitServer if it isn't already running when in 64-bit because it has to return the list
+ // of every MIME type supported by QTKit.
+ types = mimeCommonTypesCache();
}
MediaPlayer::SupportsType MediaPlayerPrivate::supportsType(const String& type, const String& codecs)
{
- // only return "IsSupported" if there is no codecs parameter for now as there is no way to ask QT if it supports an
- // extended MIME type yet
- return mimeTypeCache().contains(type) ? (codecs && !codecs.isEmpty() ? MediaPlayer::MayBeSupported : MediaPlayer::IsSupported) : MediaPlayer::IsNotSupported;
+ // Only return "IsSupported" if there is no codecs parameter for now as there is no way to ask QT if it supports an
+ // extended MIME type yet.
+
+ // We check the "modern" type cache first, as it doesn't require QTKitServer to start.
+ if (mimeModernTypesCache().contains(type) || mimeCommonTypesCache().contains(type))
+ return (codecs && !codecs.isEmpty() ? MediaPlayer::MayBeSupported : MediaPlayer::IsSupported);
+
+ return MediaPlayer::IsNotSupported;
}
bool MediaPlayerPrivate::isAvailable()
@@ -900,6 +1059,7 @@ void MediaPlayerPrivate::disableUnsupportedTracks()
{
if (!m_qtMovie) {
m_enabledTrackCount = 0;
+ m_totalTrackCount = 0;
return;
}
@@ -911,15 +1071,19 @@ void MediaPlayerPrivate::disableUnsupportedTracks()
allowedTrackTypes->add(QTMediaTypeText);
allowedTrackTypes->add(QTMediaTypeBase);
allowedTrackTypes->add(QTMediaTypeMPEG);
- allowedTrackTypes->add("clcp");
- allowedTrackTypes->add("sbtl");
+ allowedTrackTypes->add("clcp"); // Closed caption
+ allowedTrackTypes->add("sbtl"); // Subtitle
+ allowedTrackTypes->add("odsm"); // MPEG-4 object descriptor stream
+ allowedTrackTypes->add("sdsm"); // MPEG-4 scene description stream
+ allowedTrackTypes->add("tmcd"); // timecode
+ allowedTrackTypes->add("tc64"); // timcode-64
}
NSArray *tracks = [m_qtMovie.get() tracks];
- unsigned trackCount = [tracks count];
- m_enabledTrackCount = trackCount;
- for (unsigned trackIndex = 0; trackIndex < trackCount; trackIndex++) {
+ m_totalTrackCount = [tracks count];
+ m_enabledTrackCount = m_totalTrackCount;
+ for (unsigned trackIndex = 0; trackIndex < m_totalTrackCount; trackIndex++) {
// Grab the track at the current index. If there isn't one there, then
// we can move onto the next one.
QTTrack *track = [tracks objectAtIndex:trackIndex];
@@ -931,24 +1095,18 @@ void MediaPlayerPrivate::disableUnsupportedTracks()
if (![track isEnabled])
continue;
- // Grab the track's media. We're going to check to see if we need to
- // disable the tracks. They could be unsupported.
- QTMedia *trackMedia = [track media];
- if (!trackMedia)
- continue;
-
- // Grab the media type for this track.
- NSString *mediaType = [trackMedia attributeForKey:QTMediaTypeAttribute];
+ // Get the track's media type.
+ NSString *mediaType = [track attributeForKey:QTTrackMediaTypeAttribute];
if (!mediaType)
continue;
-
+
// Test whether the media type is in our white list.
if (!allowedTrackTypes->contains(mediaType)) {
// If this track type is not allowed, then we need to disable it.
[track setEnabled:NO];
--m_enabledTrackCount;
}
-
+
// Disable chapter tracks. These are most likely to lead to trouble, as
// they will be composited under the video tracks, forcing QT to do extra
// work.
@@ -982,6 +1140,12 @@ void MediaPlayerPrivate::disableUnsupportedTracks()
}
}
+void MediaPlayerPrivate::sawUnsupportedTracks()
+{
+ m_hasUnsupportedTracks = true;
+ m_player->mediaPlayerClient()->mediaPlayerSawUnsupportedTracks(m_player);
+}
+
}
@implementation WebCoreMovieObserver
diff --git a/WebCore/platform/graphics/mac/SimpleFontDataMac.mm b/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
index a3c10fa..cdde7cf 100644
--- a/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
+++ b/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
@@ -58,7 +58,7 @@ static inline float scaleEmToUnits(float x, unsigned unitsPerEm) { return x * (c
static bool initFontData(SimpleFontData* fontData)
{
- if (!fontData->m_font.cgFont())
+ if (!fontData->platformData().cgFont())
return false;
#ifdef BUILDING_ON_TIGER
@@ -66,7 +66,7 @@ static bool initFontData(SimpleFontData* fontData)
if (ATSUCreateStyle(&fontStyle) != noErr)
return false;
- ATSUFontID fontId = fontData->m_font.m_atsuFontID;
+ ATSUFontID fontId = fontData->platformData().m_atsuFontID;
if (!fontId) {
ATSUDisposeStyle(fontStyle);
return false;
@@ -153,7 +153,7 @@ void SimpleFontData::platformInit()
m_shapesArabic = false;
#endif
- m_syntheticBoldOffset = m_font.m_syntheticBold ? 1.0f : 0.f;
+ m_syntheticBoldOffset = m_platformData.m_syntheticBold ? 1.0f : 0.f;
bool failedSetup = false;
if (!initFontData(this)) {
@@ -165,7 +165,7 @@ void SimpleFontData::platformInit()
// It overrides the normal "Times" family font.
// It also appears to have a corrupt regular variant.
NSString *fallbackFontFamily;
- if ([[m_font.font() familyName] isEqual:@"Times"])
+ if ([[m_platformData.font() familyName] isEqual:@"Times"])
fallbackFontFamily = @"Times New Roman";
else
fallbackFontFamily = webFallbackFontFamily();
@@ -173,12 +173,12 @@ void SimpleFontData::platformInit()
// Try setting up the alternate font.
// This is a last ditch effort to use a substitute font when something has gone wrong.
#if !ERROR_DISABLED
- RetainPtr<NSFont> initialFont = m_font.font();
+ RetainPtr<NSFont> initialFont = m_platformData.font();
#endif
- if (m_font.font())
- m_font.setFont([[NSFontManager sharedFontManager] convertFont:m_font.font() toFamily:fallbackFontFamily]);
+ if (m_platformData.font())
+ m_platformData.setFont([[NSFontManager sharedFontManager] convertFont:m_platformData.font() toFamily:fallbackFontFamily]);
else
- m_font.setFont([NSFont fontWithName:fallbackFontFamily size:m_font.size()]);
+ m_platformData.setFont([NSFont fontWithName:fallbackFontFamily size:m_platformData.size()]);
#if !ERROR_DISABLED
NSString *filePath = pathFromFont(initialFont.get());
if (!filePath)
@@ -188,7 +188,7 @@ void SimpleFontData::platformInit()
if ([fallbackFontFamily isEqual:@"Times New Roman"]) {
// OK, couldn't setup Times New Roman as an alternate to Times, fallback
// on the system font. If this fails we have no alternative left.
- m_font.setFont([[NSFontManager sharedFontManager] convertFont:m_font.font() toFamily:webFallbackFontFamily()]);
+ m_platformData.setFont([[NSFontManager sharedFontManager] convertFont:m_platformData.font() toFamily:webFallbackFontFamily()]);
if (!initFontData(this)) {
// We tried, Times, Times New Roman, and the system font. No joy. We have to give up.
LOG_ERROR("unable to initialize with font %@ at %@", initialFont.get(), filePath);
@@ -203,14 +203,14 @@ void SimpleFontData::platformInit()
// Report the problem.
LOG_ERROR("Corrupt font detected, using %@ in place of %@ located at \"%@\".",
- [m_font.font() familyName], [initialFont.get() familyName], filePath);
+ [m_platformData.font() familyName], [initialFont.get() familyName], filePath);
}
// If all else fails, try to set up using the system font.
// This is probably because Times and Times New Roman are both unavailable.
if (failedSetup) {
- m_font.setFont([NSFont systemFontOfSize:[m_font.font() pointSize]]);
- LOG_ERROR("failed to set up font, using system font %s", m_font.font());
+ m_platformData.setFont([NSFont systemFontOfSize:[m_platformData.font() pointSize]]);
+ LOG_ERROR("failed to set up font, using system font %s", m_platformData.font());
initFontData(this);
}
@@ -218,15 +218,15 @@ void SimpleFontData::platformInit()
int iDescent;
int iLineGap;
#ifdef BUILDING_ON_TIGER
- wkGetFontMetrics(m_font.cgFont(), &iAscent, &iDescent, &iLineGap, &m_unitsPerEm);
+ wkGetFontMetrics(m_platformData.cgFont(), &iAscent, &iDescent, &iLineGap, &m_unitsPerEm);
#else
- iAscent = CGFontGetAscent(m_font.cgFont());
- iDescent = CGFontGetDescent(m_font.cgFont());
- iLineGap = CGFontGetLeading(m_font.cgFont());
- m_unitsPerEm = CGFontGetUnitsPerEm(m_font.cgFont());
+ iAscent = CGFontGetAscent(m_platformData.cgFont());
+ iDescent = CGFontGetDescent(m_platformData.cgFont());
+ iLineGap = CGFontGetLeading(m_platformData.cgFont());
+ m_unitsPerEm = CGFontGetUnitsPerEm(m_platformData.cgFont());
#endif
- float pointSize = m_font.m_size;
+ float pointSize = m_platformData.m_size;
float fAscent = scaleEmToUnits(iAscent, m_unitsPerEm) * pointSize;
float fDescent = -scaleEmToUnits(iDescent, m_unitsPerEm) * pointSize;
float fLineGap = scaleEmToUnits(iLineGap, m_unitsPerEm) * pointSize;
@@ -236,7 +236,7 @@ void SimpleFontData::platformInit()
// web standard. The AppKit adjustment of 20% is too big and is
// incorrectly added to line spacing, so we use a 15% adjustment instead
// and add it to the ascent.
- NSString *familyName = [m_font.font() familyName];
+ NSString *familyName = [m_platformData.font() familyName];
if ([familyName isEqualToString:@"Times"] || [familyName isEqualToString:@"Helvetica"] || [familyName isEqualToString:@"Courier"])
fAscent += floorf(((fAscent + fDescent) * 0.15f) + 0.5f);
else if ([familyName isEqualToString:@"Geeza Pro"]) {
@@ -264,14 +264,49 @@ void SimpleFontData::platformInit()
GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page();
NSGlyph xGlyph = glyphPageZero ? glyphPageZero->glyphDataForCharacter('x').glyph : 0;
if (xGlyph) {
- NSRect xBox = [m_font.font() boundingRectForGlyph:xGlyph];
+ NSRect xBox = [m_platformData.font() boundingRectForGlyph:xGlyph];
// Use the maximum of either width or height because "x" is nearly square
// and web pages that foolishly use this metric for width will be laid out
// poorly if we return an accurate height. Classic case is Times 13 point,
// which has an "x" that is 7x6 pixels.
m_xHeight = MAX(NSMaxX(xBox), NSMaxY(xBox));
} else
- m_xHeight = [m_font.font() xHeight];
+ m_xHeight = [m_platformData.font() xHeight];
+}
+
+void SimpleFontData::platformCharWidthInit()
+{
+ m_avgCharWidth = 0.f;
+
+ // Calculate avgCharWidth according to http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6OS2.html
+ // We can try grabbing it out of the OS/2 table or via ATSFontGetHorizontalMetrics, but
+ // ATSFontGetHorizontalMetrics never seems to return a non-zero value and the OS/2 table
+ // contains zero for a large number of fonts.
+ GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page();
+ if (glyphPageZero) {
+ static int weights[] = { 64, 14, 27, 35, 100, 20, 14, 42, 63, 3, 6, 35, 20, 56, 56, 17, 4, 49, 56, 71, 31, 10, 18, 3, 18, 2, 166 };
+ int numGlyphs = 27;
+ ASSERT(numGlyphs == sizeof(weights) / sizeof(int));
+ // Compute the weighted sum of the space character and the lowercase letters in the Latin alphabet.
+ float sum = 0.f;
+ int totalWeight = 0;
+ for (int i = 0; i < numGlyphs; i++) {
+ Glyph glyph = glyphPageZero->glyphDataForCharacter((i < 26 ? i + 'a' : ' ')).glyph;
+ if (glyph) {
+ totalWeight += weights[i];
+ sum += widthForGlyph(glyph) * weights[i];
+ }
+ }
+ if (sum > 0.f && totalWeight > 0)
+ m_avgCharWidth = sum / totalWeight;
+ }
+
+ m_maxCharWidth = 0.f;
+ if (m_platformData.font())
+ m_maxCharWidth = [m_platformData.font() maximumAdvancement].width;
+
+ // Fallback to a cross-platform estimate, which will populate these values if they are non-positive.
+ initCharWidths();
}
void SimpleFontData::platformDestroy()
@@ -290,13 +325,13 @@ SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDes
{
if (!m_smallCapsFontData) {
if (isCustomFont()) {
- FontPlatformData smallCapsFontData(m_font);
+ 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_font.font() pointSize] * smallCapsFontSizeMultiplier;
- FontPlatformData smallCapsFont([[NSFontManager sharedFontManager] convertFont:m_font.font() toSize:size]);
+ float size = [m_platformData.font() pointSize] * smallCapsFontSizeMultiplier;
+ FontPlatformData smallCapsFont([[NSFontManager sharedFontManager] convertFont:m_platformData.font() toSize: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.
@@ -304,11 +339,11 @@ SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDes
if (smallCapsFont.font()) {
NSFontManager *fontManager = [NSFontManager sharedFontManager];
- NSFontTraitMask fontTraits = [fontManager traitsOfFont:m_font.font()];
+ NSFontTraitMask fontTraits = [fontManager traitsOfFont:m_platformData.font()];
- if (m_font.m_syntheticBold)
+ if (m_platformData.m_syntheticBold)
fontTraits |= NSBoldFontMask;
- if (m_font.m_syntheticOblique)
+ if (m_platformData.m_syntheticOblique)
fontTraits |= NSItalicFontMask;
NSFontTraitMask smallCapsFontTraits = [fontManager traitsOfFont:smallCapsFont.font()];
@@ -326,7 +361,7 @@ SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDes
bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
{
NSString *string = [[NSString alloc] initWithCharactersNoCopy:const_cast<unichar*>(characters) length:length freeWhenDone:NO];
- NSCharacterSet *set = [[m_font.font() coveredCharacterSet] invertedSet];
+ NSCharacterSet *set = [[m_platformData.font() coveredCharacterSet] invertedSet];
bool result = set && [string rangeOfCharacterFromSet:set].location == NSNotFound;
[string release];
return result;
@@ -334,7 +369,7 @@ bool SimpleFontData::containsCharacters(const UChar* characters, int length) con
void SimpleFontData::determinePitch()
{
- NSFont* f = m_font.font();
+ NSFont* f = m_platformData.font();
// Special case Osaka-Mono.
// According to <rdar://problem/3999467>, we should treat Osaka-Mono as fixed pitch.
// Note that the AppKit does not report Osaka-Mono as fixed pitch.
@@ -356,11 +391,11 @@ void SimpleFontData::determinePitch()
float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
{
- NSFont* font = m_font.font();
- float pointSize = m_font.m_size;
+ NSFont* font = m_platformData.font();
+ float pointSize = m_platformData.m_size;
CGAffineTransform m = CGAffineTransformMakeScale(pointSize, pointSize);
CGSize advance;
- if (!wkGetGlyphTransformedAdvances(m_font.cgFont(), font, &m, &glyph, &advance)) {
+ if (!wkGetGlyphTransformedAdvances(m_platformData.cgFont(), font, &m, &glyph, &advance)) {
LOG_ERROR("Unable to cache glyph widths for %@ %f", [font displayName], pointSize);
advance.width = 0;
}
@@ -374,9 +409,9 @@ void SimpleFontData::checkShapesArabic() const
m_checkedShapesArabic = true;
- ATSUFontID fontID = m_font.m_atsuFontID;
+ ATSUFontID fontID = m_platformData.m_atsuFontID;
if (!fontID) {
- LOG_ERROR("unable to get ATSUFontID for %@", m_font.font());
+ LOG_ERROR("unable to get ATSUFontID for %@", m_platformData.font());
return;
}
@@ -404,7 +439,7 @@ CTFontRef SimpleFontData::getCTFont() const
if (getNSFont())
return toCTFontRef(getNSFont());
if (!m_CTFont)
- m_CTFont.adoptCF(CTFontCreateWithGraphicsFont(m_font.cgFont(), m_font.size(), NULL, NULL));
+ m_CTFont.adoptCF(CTFontCreateWithGraphicsFont(m_platformData.cgFont(), m_platformData.size(), NULL, NULL));
return m_CTFont.get();
}
diff --git a/WebCore/platform/graphics/mac/WebLayer.mm b/WebCore/platform/graphics/mac/WebLayer.mm
index 267b5bc..fad3916 100644
--- a/WebCore/platform/graphics/mac/WebLayer.mm
+++ b/WebCore/platform/graphics/mac/WebLayer.mm
@@ -32,7 +32,6 @@
#import "GraphicsContext.h"
#import "GraphicsLayer.h"
#import <QuartzCore/QuartzCore.h>
-#import "WebCoreTextRenderer.h"
#import <wtf/UnusedParam.h>
using namespace WebCore;
diff --git a/WebCore/platform/graphics/opentype/OpenTypeUtilities.cpp b/WebCore/platform/graphics/opentype/OpenTypeUtilities.cpp
index 16c3c00..895887f 100644
--- a/WebCore/platform/graphics/opentype/OpenTypeUtilities.cpp
+++ b/WebCore/platform/graphics/opentype/OpenTypeUtilities.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -161,11 +161,21 @@ struct nameTable {
#pragma pack()
-static void appendBigEndianStringToEOTHeader(Vector<uint8_t, 512>& eotHeader, const BigEndianUShort* string, unsigned short length)
+EOTHeader::EOTHeader()
{
- size_t size = eotHeader.size();
- eotHeader.resize(size + length + 2 * sizeof(unsigned short));
- UChar* dst = reinterpret_cast<UChar*>(eotHeader.data() + size);
+ m_buffer.resize(sizeof(EOTPrefix));
+}
+
+void EOTHeader::updateEOTSize(size_t fontDataSize)
+{
+ prefix()->eotSize = m_buffer.size() + fontDataSize;
+}
+
+void EOTHeader::appendBigEndianString(const BigEndianUShort* string, unsigned short length)
+{
+ size_t oldSize = m_buffer.size();
+ m_buffer.resize(oldSize + length + 2 * sizeof(unsigned short));
+ UChar* dst = reinterpret_cast<UChar*>(m_buffer.data() + oldSize);
unsigned i = 0;
dst[i++] = length;
unsigned numCharacters = length / 2;
@@ -174,7 +184,13 @@ static void appendBigEndianStringToEOTHeader(Vector<uint8_t, 512>& eotHeader, co
dst[i] = 0;
}
-bool getEOTHeader(SharedBuffer* fontData, Vector<uint8_t, 512>& eotHeader, size_t& overlayDst, size_t& overlaySrc, size_t& overlayLength)
+void EOTHeader::appendPaddingShort()
+{
+ unsigned short padding = 0;
+ m_buffer.append(reinterpret_cast<uint8_t*>(&padding), sizeof(padding));
+}
+
+bool getEOTHeader(SharedBuffer* fontData, EOTHeader& eotHeader, size_t& overlayDst, size_t& overlaySrc, size_t& overlayLength)
{
overlayDst = 0;
overlaySrc = 0;
@@ -183,8 +199,7 @@ bool getEOTHeader(SharedBuffer* fontData, Vector<uint8_t, 512>& eotHeader, size_
size_t dataLength = fontData->size();
const char* data = fontData->data();
- eotHeader.resize(sizeof(EOTPrefix));
- EOTPrefix* prefix = reinterpret_cast<EOTPrefix*>(eotHeader.data());
+ EOTPrefix* prefix = eotHeader.prefix();
prefix->fontDataSize = dataLength;
prefix->version = 0x00020001;
@@ -306,9 +321,9 @@ bool getEOTHeader(SharedBuffer* fontData, Vector<uint8_t, 512>& eotHeader, size_
prefix->reserved[3] = 0;
prefix->padding1 = 0;
- appendBigEndianStringToEOTHeader(eotHeader, familyName, familyNameLength);
- appendBigEndianStringToEOTHeader(eotHeader, subfamilyName, subfamilyNameLength);
- appendBigEndianStringToEOTHeader(eotHeader, versionString, versionStringLength);
+ eotHeader.appendBigEndianString(familyName, familyNameLength);
+ eotHeader.appendBigEndianString(subfamilyName, subfamilyNameLength);
+ eotHeader.appendBigEndianString(versionString, versionStringLength);
// If possible, ensure that the family name is a prefix of the full name.
if (fullNameLength >= familyNameLength && memcmp(familyName, fullName, familyNameLength)) {
@@ -316,13 +331,10 @@ bool getEOTHeader(SharedBuffer* fontData, Vector<uint8_t, 512>& eotHeader, size_
overlayDst = reinterpret_cast<const char*>(familyName) - data;
overlayLength = familyNameLength;
}
+ eotHeader.appendBigEndianString(fullName, fullNameLength);
- appendBigEndianStringToEOTHeader(eotHeader, fullName, fullNameLength);
-
- unsigned short padding = 0;
- eotHeader.append(reinterpret_cast<uint8_t*>(&padding), sizeof(padding));
-
- prefix->eotSize = eotHeader.size() + fontData->size();
+ eotHeader.appendPaddingShort();
+ eotHeader.updateEOTSize(fontData->size());
return true;
}
diff --git a/WebCore/platform/graphics/opentype/OpenTypeUtilities.h b/WebCore/platform/graphics/opentype/OpenTypeUtilities.h
index a67ffc7..13dad6f 100644
--- a/WebCore/platform/graphics/opentype/OpenTypeUtilities.h
+++ b/WebCore/platform/graphics/opentype/OpenTypeUtilities.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,9 +31,26 @@
namespace WebCore {
+struct BigEndianUShort;
+struct EOTPrefix;
class SharedBuffer;
-bool getEOTHeader(SharedBuffer* fontData, Vector<uint8_t, 512>& eotHeader, size_t& overlayDst, size_t& overlaySrc, size_t& overlayLength);
+struct EOTHeader {
+ EOTHeader();
+
+ size_t size() const { return m_buffer.size(); }
+ const uint8_t* data() const { return m_buffer.data(); }
+
+ EOTPrefix* prefix() { return reinterpret_cast<EOTPrefix*>(m_buffer.data()); }
+ void updateEOTSize(size_t);
+ void appendBigEndianString(const BigEndianUShort*, unsigned short length);
+ void appendPaddingShort();
+
+private:
+ Vector<uint8_t, 512> m_buffer;
+};
+
+bool getEOTHeader(SharedBuffer* fontData, EOTHeader& eotHeader, size_t& overlayDst, size_t& overlaySrc, size_t& overlayLength);
HANDLE renameAndActivateFont(SharedBuffer*, const String&);
} // namespace WebCore
diff --git a/WebCore/platform/graphics/qt/FontCacheQt.cpp b/WebCore/platform/graphics/qt/FontCacheQt.cpp
index 114f073..668912e 100644
--- a/WebCore/platform/graphics/qt/FontCacheQt.cpp
+++ b/WebCore/platform/graphics/qt/FontCacheQt.cpp
@@ -26,8 +26,11 @@
#include "FontDescription.h"
#include "FontPlatformData.h"
#include "Font.h"
+#include "StringHash.h"
#include <wtf/StdLibExtras.h>
+#include <QHash>
+
namespace WebCore {
FontCache* fontCache()
@@ -44,9 +47,31 @@ void FontCache::getTraitsInFamily(const AtomicString& familyName, Vector<unsigne
{
}
+typedef QHash<FontDescription, FontPlatformData*> FontPlatformDataCache;
+
+// using Q_GLOBAL_STATIC leads to crash. TODO investigate the way to fix this.
+static FontPlatformDataCache* gFontPlatformDataCache;
+
+uint qHash(const FontDescription& key)
+{
+ uint value = CaseFoldingHash::hash(key.family().family());
+ value ^= key.computedPixelSize();
+ value ^= static_cast<int>(key.weight());
+ return value;
+}
+
FontPlatformData* FontCache::getCachedFontPlatformData(const FontDescription& description, const AtomicString& family, bool checkingAlternateName)
{
- return new FontPlatformData(description);
+ if (!gFontPlatformDataCache)
+ gFontPlatformDataCache = new FontPlatformDataCache;
+
+ FontPlatformData* fontData = gFontPlatformDataCache->value(description, 0);
+ if (!fontData) {
+ fontData = new FontPlatformData(description);
+ gFontPlatformDataCache->insert(description, fontData);
+ }
+
+ return fontData;
}
SimpleFontData* FontCache::getCachedFontData(const FontPlatformData*)
@@ -71,4 +96,12 @@ void FontCache::removeClient(FontSelector*)
{
}
+void FontCache::invalidate()
+{
+ if (!gFontPlatformDataCache)
+ return;
+
+ gFontPlatformDataCache->clear();
+}
+
} // namespace WebCore
diff --git a/WebCore/platform/graphics/qt/FontFallbackListQt.cpp b/WebCore/platform/graphics/qt/FontFallbackListQt.cpp
index 22ae205..50627b7 100644
--- a/WebCore/platform/graphics/qt/FontFallbackListQt.cpp
+++ b/WebCore/platform/graphics/qt/FontFallbackListQt.cpp
@@ -42,8 +42,6 @@ FontFallbackList::FontFallbackList()
void FontFallbackList::invalidate(WTF::PassRefPtr<WebCore::FontSelector> fontSelector)
{
- releaseFontData();
- m_fontList.clear();
m_familyIndex = 0;
m_pitch = UnknownPitch;
m_loadingCustomFonts = false;
@@ -53,6 +51,9 @@ void FontFallbackList::invalidate(WTF::PassRefPtr<WebCore::FontSelector> fontSel
void FontFallbackList::releaseFontData()
{
+ if (m_fontList.size())
+ delete m_fontList[0].first;
+ m_fontList.clear();
}
void FontFallbackList::determinePitch(const WebCore::Font* font) const
@@ -90,7 +91,12 @@ const FontData* FontFallbackList::fontDataAt(const WebCore::Font* _font, unsigne
family = family->next();
}
- return new SimpleFontData(FontPlatformData(description), _font->wordSpacing(), _font->letterSpacing());
+ if (m_fontList.size())
+ return m_fontList[0].first;
+
+ const FontData* result = new SimpleFontData(FontPlatformData(description), _font->wordSpacing(), _font->letterSpacing());
+ m_fontList.append(pair<const FontData*, bool>(result, result->isCustomFont()));
+ return result;
}
const FontData* FontFallbackList::fontDataForCharacters(const WebCore::Font* font, const UChar*, int) const
diff --git a/WebCore/platform/graphics/qt/FontQt.cpp b/WebCore/platform/graphics/qt/FontQt.cpp
index 9ed5915..5a4b7b2 100644
--- a/WebCore/platform/graphics/qt/FontQt.cpp
+++ b/WebCore/platform/graphics/qt/FontQt.cpp
@@ -183,7 +183,7 @@ void Font::drawComplexText(GraphicsContext* ctx, const TextRun& run, const Float
p->drawText(pt, string, flags, run.padding());
}
-float Font::floatWidthForComplexText(const TextRun& run) const
+float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>*) const
{
if (!run.length())
return 0;
diff --git a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
index ccf4b06..ed7ac47 100644
--- a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
+++ b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
@@ -99,7 +99,7 @@ static inline QPainter::CompositionMode toQtCompositionMode(CompositeOperator op
case CompositeHighlight:
return QPainter::CompositionMode_SourceOver;
case CompositePlusLighter:
- return QPainter::CompositionMode_SourceOver;
+ return QPainter::CompositionMode_Plus;
}
return QPainter::CompositionMode_SourceOver;
@@ -153,6 +153,18 @@ static Qt::PenStyle toQPenStyle(StrokeStyle style)
return Qt::NoPen;
}
+static inline Qt::FillRule toQtFillRule(WindRule rule)
+{
+ switch(rule) {
+ case RULE_EVENODD:
+ return Qt::OddEvenFill;
+ case RULE_NONZERO:
+ return Qt::WindingFill;
+ }
+ qDebug("Qt: unrecognized wind rule!");
+ return Qt::OddEvenFill;
+}
+
struct TransparencyLayer
{
TransparencyLayer(const QPainter* p, const QRect &rect)
@@ -563,7 +575,7 @@ void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSp
QPainter *p = m_data->p();
const bool antiAlias = p->testRenderHint(QPainter::Antialiasing);
- p->setRenderHint(QPainter::Antialiasing, m_data->antiAliasingForRectsAndLines);
+ p->setRenderHint(QPainter::Antialiasing, true);
p->drawArc(rect, startAngle * 16, angleSpan * 16);
@@ -606,6 +618,7 @@ void GraphicsContext::fillPath()
QPainter *p = m_data->p();
QPainterPath path = m_data->currentPath;
+ path.setFillRule(toQtFillRule(fillRule()));
switch (m_common->state.fillColorSpace) {
case SolidColorSpace:
@@ -634,6 +647,7 @@ void GraphicsContext::strokePath()
QPainter *p = m_data->p();
QPen pen = p->pen();
QPainterPath path = m_data->currentPath;
+ path.setFillRule(toQtFillRule(fillRule()));
switch (m_common->state.strokeColorSpace) {
case SolidColorSpace:
@@ -1097,7 +1111,13 @@ void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect,
rect.width() - (thickness * 2), rect.height() - (thickness * 2)));
path.setFillRule(Qt::OddEvenFill);
- m_data->p()->setClipPath(path, Qt::IntersectClip);
+
+ QPainter *p = m_data->p();
+
+ const bool antiAlias = p->testRenderHint(QPainter::Antialiasing);
+ p->setRenderHint(QPainter::Antialiasing, true);
+ p->setClipPath(path, Qt::IntersectClip);
+ p->setRenderHint(QPainter::Antialiasing, antiAlias);
}
void GraphicsContext::concatCTM(const TransformationMatrix& transform)
diff --git a/WebCore/platform/graphics/qt/IconQt.cpp b/WebCore/platform/graphics/qt/IconQt.cpp
index b04668c..c9f3ced 100644
--- a/WebCore/platform/graphics/qt/IconQt.cpp
+++ b/WebCore/platform/graphics/qt/IconQt.cpp
@@ -24,7 +24,6 @@
#include "GraphicsContext.h"
#include "PlatformString.h"
#include "IntRect.h"
-#include "NotImplemented.h"
#include <qpainter.h>
#include <qpixmap.h>
diff --git a/WebCore/platform/graphics/qt/ImageBufferQt.cpp b/WebCore/platform/graphics/qt/ImageBufferQt.cpp
index d748305..506a8ea 100644
--- a/WebCore/platform/graphics/qt/ImageBufferQt.cpp
+++ b/WebCore/platform/graphics/qt/ImageBufferQt.cpp
@@ -47,7 +47,24 @@ ImageBufferData::ImageBufferData(const IntSize& size)
: m_pixmap(size)
{
m_pixmap.fill(QColor(Qt::transparent));
- m_painter.set(new QPainter(&m_pixmap));
+
+ QPainter* painter = new QPainter(&m_pixmap);
+ m_painter.set(painter);
+
+ // Since ImageBuffer is used mainly for Canvas, explicitly initialize
+ // its painter's pen and brush with the corresponding canvas defaults
+ // NOTE: keep in sync with CanvasRenderingContext2D::State
+ QPen pen = painter->pen();
+ pen.setColor(Qt::black);
+ pen.setWidth(1);
+ pen.setCapStyle(Qt::FlatCap);
+ pen.setJoinStyle(Qt::MiterJoin);
+ pen.setMiterLimit(10);
+ painter->setPen(pen);
+ QBrush brush = painter->brush();
+ brush.setColor(Qt::black);
+ painter->setBrush(brush);
+ painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
}
ImageBuffer::ImageBuffer(const IntSize& size, bool grayScale, bool& success)
diff --git a/WebCore/platform/graphics/qt/ImageDecoderQt.cpp b/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
index 394c7a7..cd32428 100644
--- a/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
+++ b/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
@@ -197,7 +197,8 @@ ImageDecoderQt* ImageDecoderQt::create(const SharedBuffer& data)
}
ImageDecoderQt::ImageDecoderQt(const QString &imageFormat)
- : m_imageFormat(imageFormat)
+ : m_hasAlphaChannel(false)
+ , m_imageFormat(imageFormat)
{
}
@@ -212,6 +213,7 @@ bool ImageDecoderQt::hasFirstImageHeader() const
void ImageDecoderQt::reset()
{
+ m_hasAlphaChannel = false;
m_failed = false;
m_imageList.clear();
m_pixmapCache.clear();
@@ -230,6 +232,9 @@ void ImageDecoderQt::setData(const IncomingData &data, bool allDataReceived)
const ReadContext::ReadResult readResult = readContext.read(allDataReceived);
+ if (hasFirstImageHeader())
+ m_hasAlphaChannel = m_imageList[0].m_image.hasAlphaChannel();
+
if (debugImageDecoderQt)
qDebug() << " read returns " << readResult;
@@ -280,7 +285,7 @@ int ImageDecoderQt::repetitionCount() const
bool ImageDecoderQt::supportsAlpha() const
{
- return hasFirstImageHeader() && m_imageList[0].m_image.hasAlphaChannel();
+ return m_hasAlphaChannel;
}
int ImageDecoderQt::duration(size_t index) const
@@ -314,6 +319,10 @@ QPixmap* ImageDecoderQt::imageAtIndex(size_t index) const
if (!m_pixmapCache.contains(index)) {
m_pixmapCache.insert(index,
QPixmap::fromImage(m_imageList[index].m_image));
+
+ // store null image since the converted pixmap is already in pixmap cache
+ Q_ASSERT(m_imageList[index].m_imageState == ImageComplete);
+ m_imageList[index].m_image = QImage();
}
return &m_pixmapCache[index];
}
diff --git a/WebCore/platform/graphics/qt/ImageDecoderQt.h b/WebCore/platform/graphics/qt/ImageDecoderQt.h
index a2eb6aa..b8c3edd 100644
--- a/WebCore/platform/graphics/qt/ImageDecoderQt.h
+++ b/WebCore/platform/graphics/qt/ImageDecoderQt.h
@@ -81,8 +81,9 @@ private:
int m_duration;
};
+ bool m_hasAlphaChannel;
typedef QList<ImageData> ImageList;
- ImageList m_imageList;
+ mutable ImageList m_imageList;
mutable QHash<int, QPixmap> m_pixmapCache;
int m_loopCount;
QString m_imageFormat;
diff --git a/WebCore/platform/graphics/qt/ImageQt.cpp b/WebCore/platform/graphics/qt/ImageQt.cpp
index 3bc67ae..a2e96f3 100644
--- a/WebCore/platform/graphics/qt/ImageQt.cpp
+++ b/WebCore/platform/graphics/qt/ImageQt.cpp
@@ -31,12 +31,12 @@
#include "config.h"
#include "Image.h"
+#include "ImageObserver.h"
#include "BitmapImage.h"
#include "FloatRect.h"
#include "PlatformString.h"
#include "GraphicsContext.h"
#include "TransformationMatrix.h"
-#include "NotImplemented.h"
#include "StillImageQt.h"
#include "qwebsettings.h"
@@ -117,6 +117,9 @@ void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const
p->setBrushOrigin(phase);
p->fillRect(destRect, b);
ctxt->restore();
+
+ if (imageObserver())
+ imageObserver()->didDraw(this);
}
void BitmapImage::initPlatformData()
@@ -159,6 +162,9 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst,
painter->drawPixmap(dst, *image, src);
ctxt->restore();
+
+ if (imageObserver())
+ imageObserver()->didDraw(this);
}
void BitmapImage::checkForSolidColor()
diff --git a/WebCore/platform/graphics/qt/ImageSourceQt.cpp b/WebCore/platform/graphics/qt/ImageSourceQt.cpp
index 84de443..621728e 100644
--- a/WebCore/platform/graphics/qt/ImageSourceQt.cpp
+++ b/WebCore/platform/graphics/qt/ImageSourceQt.cpp
@@ -29,7 +29,6 @@
#include "config.h"
#include "ImageSource.h"
#include "ImageDecoderQt.h"
-#include "NotImplemented.h"
#include "SharedBuffer.h"
#include <QBuffer>
diff --git a/WebCore/platform/graphics/qt/PathQt.cpp b/WebCore/platform/graphics/qt/PathQt.cpp
index a8a3ea2..7569031 100644
--- a/WebCore/platform/graphics/qt/PathQt.cpp
+++ b/WebCore/platform/graphics/qt/PathQt.cpp
@@ -39,6 +39,7 @@
#include <QPainterPath>
#include <QTransform>
#include <QString>
+#include <wtf/OwnPtr.h>
#define _USE_MATH_DEFINES
#include <math.h>
@@ -91,7 +92,7 @@ bool Path::strokeContains(StrokeStyleApplier* applier, const FloatPoint& point)
// FIXME: We should try to use a 'shared Context' instead of creating a new ImageBuffer
// on each call.
- std::auto_ptr<ImageBuffer> scratchImage = ImageBuffer::create(IntSize(1, 1), false);
+ OwnPtr<ImageBuffer> scratchImage = ImageBuffer::create(IntSize(1, 1), false);
GraphicsContext* gc = scratchImage->context();
QPainterPathStroker stroke;
applier->strokeStyle(gc);
@@ -123,7 +124,7 @@ FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier)
{
// FIXME: We should try to use a 'shared Context' instead of creating a new ImageBuffer
// on each call.
- std::auto_ptr<ImageBuffer> scratchImage = ImageBuffer::create(IntSize(1, 1), false);
+ OwnPtr<ImageBuffer> scratchImage = ImageBuffer::create(IntSize(1, 1), false);
GraphicsContext* gc = scratchImage->context();
QPainterPathStroker stroke;
if (applier) {
diff --git a/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp b/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp
index 6cf4e55..f823f84 100644
--- a/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp
+++ b/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp
@@ -30,7 +30,7 @@ namespace WebCore {
void SimpleFontData::determinePitch()
{
- m_treatAsFixedPitch = m_font.font().fixedPitch();
+ m_treatAsFixedPitch = m_platformData.font().fixedPitch();
}
bool SimpleFontData::containsCharacters(const UChar*, int length) const
@@ -40,7 +40,7 @@ bool SimpleFontData::containsCharacters(const UChar*, int length) const
void SimpleFontData::platformInit()
{
- QFontMetrics fm(m_font.font());
+ QFontMetrics fm(m_platformData.font());
m_ascent = fm.ascent();
m_descent = fm.descent();
@@ -59,6 +59,13 @@ void SimpleFontData::platformGlyphInit()
m_missingGlyphData.glyph = 0;
}
+void SimpleFontData::platformCharWidthInit()
+{
+ QFontMetrics fm(m_platformData.font());
+ m_avgCharWidth = fm.averageCharWidth();
+ m_maxCharWidth = fm.maxWidth();
+}
+
void SimpleFontData::platformDestroy()
{
}
diff --git a/WebCore/platform/graphics/skia/GradientSkia.cpp b/WebCore/platform/graphics/skia/GradientSkia.cpp
index 2d2000c..ac7366c 100644
--- a/WebCore/platform/graphics/skia/GradientSkia.cpp
+++ b/WebCore/platform/graphics/skia/GradientSkia.cpp
@@ -60,12 +60,14 @@ static SkColor makeSkColor(float a, float r, float g, float b)
// ends as necessary.
static size_t totalStopsNeeded(const Gradient::ColorStop* stopData, size_t count)
{
+ // N.B.: The tests in this function should kept in sync with the ones in
+ // fillStops(), or badness happens.
const Gradient::ColorStop* stop = stopData;
size_t countUsed = count;
if (count < 1 || stop->stop > 0.0)
countUsed++;
stop += count - 1;
- if (count < 2 || stop->stop < 1.0)
+ if (count < 1 || stop->stop < 1.0)
countUsed++;
return countUsed;
}
diff --git a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
index 376fa4b..33ca23a 100644
--- a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
+++ b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
@@ -449,10 +449,8 @@ void GraphicsContext::drawConvexPolygon(size_t numPoints,
return;
SkPaint paint;
- if (fillColor().alpha() > 0) {
- platformContext()->setupPaintForFilling(&paint);
- platformContext()->canvas()->drawPath(path, paint);
- }
+ platformContext()->setupPaintForFilling(&paint);
+ platformContext()->canvas()->drawPath(path, paint);
if (strokeStyle() != NoStroke) {
paint.reset();
@@ -472,10 +470,8 @@ void GraphicsContext::drawEllipse(const IntRect& elipseRect)
return;
SkPaint paint;
- if (fillColor().alpha() > 0) {
- platformContext()->setupPaintForFilling(&paint);
- platformContext()->canvas()->drawOval(rect, paint);
- }
+ platformContext()->setupPaintForFilling(&paint);
+ platformContext()->canvas()->drawOval(rect, paint);
if (strokeStyle() != NoStroke) {
paint.reset();
@@ -685,9 +681,6 @@ void GraphicsContext::fillPath()
const GraphicsContextState& state = m_common->state;
ColorSpace colorSpace = state.fillColorSpace;
- if (colorSpace == SolidColorSpace && !fillColor().alpha())
- return;
-
path.setFillType(state.fillRule == RULE_EVENODD ?
SkPath::kEvenOdd_FillType : SkPath::kWinding_FillType);
@@ -718,9 +711,6 @@ void GraphicsContext::fillRect(const FloatRect& rect)
const GraphicsContextState& state = m_common->state;
ColorSpace colorSpace = state.fillColorSpace;
- if (colorSpace == SolidColorSpace && !fillColor().alpha())
- return;
-
SkPaint paint;
platformContext()->setupPaintForFilling(&paint);
@@ -739,9 +729,6 @@ void GraphicsContext::fillRect(const FloatRect& rect, const Color& color)
if (paintingDisabled())
return;
- if (!color.alpha())
- return;
-
SkRect r = rect;
if (!isRectSkiaSafe(getCTM(), r)) {
// Special case when the rectangle overflows fixed point. This is a
@@ -907,8 +894,13 @@ void GraphicsContext::setLineDash(const DashArray& dashes, float dashOffset)
// FIXME: This is lifted directly off SkiaSupport, lines 49-74
// so it is not guaranteed to work correctly.
size_t dashLength = dashes.size();
- if (!dashLength)
+ if (!dashLength) {
+ // If no dash is set, revert to solid stroke
+ // FIXME: do we need to set NoStroke in some cases?
+ platformContext()->setStrokeStyle(SolidStroke);
+ platformContext()->setDashPathEffect(0);
return;
+ }
size_t count = (dashLength % 2) == 0 ? dashLength : dashLength * 2;
SkScalar* intervals = new SkScalar[count];
@@ -962,6 +954,12 @@ void GraphicsContext::setPlatformShadow(const IntSize& size,
if (paintingDisabled())
return;
+ // Detect when there's no effective shadow and clear the looper.
+ if (size.width() == 0 && size.height() == 0 && blurInt == 0) {
+ platformContext()->setDrawLooper(NULL);
+ return;
+ }
+
double width = size.width();
double height = size.height();
double blur = blurInt;
@@ -1076,9 +1074,6 @@ void GraphicsContext::strokePath()
const GraphicsContextState& state = m_common->state;
ColorSpace colorSpace = state.strokeColorSpace;
- if (colorSpace == SolidColorSpace && !strokeColor().alpha())
- return;
-
SkPaint paint;
platformContext()->setupPaintForStroking(&paint, 0, 0);
@@ -1103,9 +1098,6 @@ void GraphicsContext::strokeRect(const FloatRect& rect, float lineWidth)
const GraphicsContextState& state = m_common->state;
ColorSpace colorSpace = state.strokeColorSpace;
- if (colorSpace == SolidColorSpace && !strokeColor().alpha())
- return;
-
SkPaint paint;
platformContext()->setupPaintForStroking(&paint, 0, 0);
paint.setStrokeWidth(WebCoreFloatToSkScalar(lineWidth));
diff --git a/WebCore/platform/graphics/skia/ImageBufferSkia.cpp b/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
index 5e90491..600882d 100644
--- a/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
+++ b/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
@@ -36,7 +36,6 @@
#include "BitmapImageSingleFrameSkia.h"
#include "GraphicsContext.h"
#include "ImageData.h"
-#include "NotImplemented.h"
#include "PlatformContextSkia.h"
#include "PNGImageEncoder.h"
#include "SkiaUtils.h"
diff --git a/WebCore/platform/graphics/skia/ImageSkia.cpp b/WebCore/platform/graphics/skia/ImageSkia.cpp
index d7f2830..cb089bb 100644
--- a/WebCore/platform/graphics/skia/ImageSkia.cpp
+++ b/WebCore/platform/graphics/skia/ImageSkia.cpp
@@ -38,7 +38,6 @@
#include "GraphicsContext.h"
#include "Logging.h"
#include "NativeImageSkia.h"
-#include "NotImplemented.h"
#include "PlatformContextSkia.h"
#include "PlatformString.h"
#include "SkiaUtils.h"
@@ -226,6 +225,12 @@ static void paintSkBitmap(PlatformContextSkia* platformContext, const NativeImag
SkPaint paint;
paint.setPorterDuffXfermode(compOp);
paint.setFilterBitmap(true);
+ int alpha = roundf(platformContext->getAlpha() * 256);
+ if (alpha > 255)
+ alpha = 255;
+ else if (alpha < 0)
+ alpha = 0;
+ paint.setAlpha(alpha);
skia::PlatformCanvas* canvas = platformContext->canvas();
@@ -305,7 +310,8 @@ void Image::drawPattern(GraphicsContext* context,
CompositeOperator compositeOp,
const FloatRect& destRect)
{
- if (destRect.isEmpty() || floatSrcRect.isEmpty())
+ FloatRect normSrcRect = normalizeRect(floatSrcRect);
+ if (destRect.isEmpty() || normSrcRect.isEmpty())
return; // nothing to draw
NativeImageSkia* bitmap = nativeImageForCurrentFrame();
@@ -316,7 +322,7 @@ void Image::drawPattern(GraphicsContext* context,
// it will internally reference the old bitmap's pixels, adjusting the row
// stride so the extra pixels appear as padding to the subsetted bitmap.
SkBitmap srcSubset;
- SkIRect srcRect = enclosingIntRect(floatSrcRect);
+ SkIRect srcRect = enclosingIntRect(normSrcRect);
bitmap->extractSubset(&srcSubset, srcRect);
SkBitmap resampled;
@@ -363,9 +369,9 @@ void Image::drawPattern(GraphicsContext* context,
// origin of the destination rect, which is what WebKit expects. Skia uses
// the coordinate system origin as the base for the patter. If WebKit wants
// a shifted image, it will shift it from there using the patternTransform.
- float adjustedX = phase.x() + floatSrcRect.x() *
+ float adjustedX = phase.x() + normSrcRect.x() *
narrowPrecisionToFloat(patternTransform.a());
- float adjustedY = phase.y() + floatSrcRect.y() *
+ float adjustedY = phase.y() + normSrcRect.y() *
narrowPrecisionToFloat(patternTransform.d());
matrix.postTranslate(SkFloatToScalar(adjustedX),
SkFloatToScalar(adjustedY));
diff --git a/WebCore/platform/graphics/skia/PathSkia.cpp b/WebCore/platform/graphics/skia/PathSkia.cpp
index 2700da8..9d9df52 100644
--- a/WebCore/platform/graphics/skia/PathSkia.cpp
+++ b/WebCore/platform/graphics/skia/PathSkia.cpp
@@ -81,9 +81,15 @@ void Path::translate(const FloatSize& size)
FloatRect Path::boundingRect() const
{
+ // FIXME: This #ifdef can go away once we're firmly using the new Skia.
+ // During the transition, this makes the code compatible with both versions.
+#ifdef SK_USE_OLD_255_TO_256
+ return m_path->getBounds();
+#else
SkRect rect;
m_path->computeBounds(&rect, SkPath::kExact_BoundsType);
return rect;
+#endif
}
void Path::moveTo(const FloatPoint& point)
@@ -275,9 +281,15 @@ static FloatRect boundingBoxForCurrentStroke(const GraphicsContext* context)
context->platformContext()->setupPaintForStroking(&paint, 0, 0);
SkPath boundingPath;
paint.getFillPath(context->platformContext()->currentPathInLocalCoordinates(), &boundingPath);
+ // FIXME: This #ifdef can go away once we're firmly using the new Skia.
+ // During the transition, this makes the code compatible with both versions.
+#ifdef SK_USE_OLD_255_TO_256
+ return boundingPath.getBounds();
+#else
SkRect r;
boundingPath.computeBounds(&r, SkPath::kExact_BoundsType);
return r;
+#endif
}
FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier)
diff --git a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
index 6c633f2..74b2bfe 100644
--- a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
+++ b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
@@ -277,13 +277,13 @@ void PlatformContextSkia::drawRect(SkRect rect)
if (oldFillColor != m_state->m_strokeColor)
setFillColor(m_state->m_strokeColor);
setupPaintForFilling(&paint);
- SkRect topBorder = { rect.fLeft, rect.fTop, rect.width(), 1 };
+ SkRect topBorder = { rect.fLeft, rect.fTop, rect.fRight, rect.fTop + 1 };
canvas()->drawRect(topBorder, paint);
- SkRect bottomBorder = { rect.fLeft, rect.fBottom - 1, rect.width(), 1 };
+ SkRect bottomBorder = { rect.fLeft, rect.fBottom - 1, rect.fRight, rect.fBottom };
canvas()->drawRect(bottomBorder, paint);
- SkRect leftBorder = { rect.fLeft, rect.fTop + 1, 1, rect.height() - 2 };
+ SkRect leftBorder = { rect.fLeft, rect.fTop + 1, rect.fLeft + 1, rect.fBottom - 1 };
canvas()->drawRect(leftBorder, paint);
- SkRect rightBorder = { rect.fRight - 1, rect.fTop + 1, 1, rect.height() - 2 };
+ SkRect rightBorder = { rect.fRight - 1, rect.fTop + 1, rect.fRight, rect.fBottom - 1 };
canvas()->drawRect(rightBorder, paint);
if (oldFillColor != m_state->m_strokeColor)
setFillColor(oldFillColor);
@@ -428,6 +428,11 @@ int PlatformContextSkia::getTextDrawingMode() const
return m_state->m_textDrawingMode;
}
+float PlatformContextSkia::getAlpha() const
+{
+ return m_state->m_alpha;
+}
+
void PlatformContextSkia::setTextDrawingMode(int mode)
{
// cTextClip is never used, so we assert that it isn't set:
diff --git a/WebCore/platform/graphics/skia/PlatformContextSkia.h b/WebCore/platform/graphics/skia/PlatformContextSkia.h
index 8850a6a..25495aa 100644
--- a/WebCore/platform/graphics/skia/PlatformContextSkia.h
+++ b/WebCore/platform/graphics/skia/PlatformContextSkia.h
@@ -130,6 +130,7 @@ public:
WebCore::StrokeStyle getStrokeStyle() const;
float getStrokeThickness() const;
int getTextDrawingMode() const;
+ float getAlpha() const;
void beginPath();
void addPath(const SkPath&);
diff --git a/WebCore/platform/graphics/skia/SkiaFontWin.cpp b/WebCore/platform/graphics/skia/SkiaFontWin.cpp
index d0cd4c5..7f12508 100644
--- a/WebCore/platform/graphics/skia/SkiaFontWin.cpp
+++ b/WebCore/platform/graphics/skia/SkiaFontWin.cpp
@@ -220,6 +220,16 @@ void SkiaWinOutlineCache::removePathsForFont(HFONT hfont)
deleteOutline(outlineCache.find(*i));
}
+bool windowsCanHandleDrawTextShadow(WebCore::GraphicsContext *context)
+{
+ IntSize shadowSize;
+ int shadowBlur;
+ Color shadowColor;
+
+ bool hasShadow = context->getShadow(shadowSize, shadowBlur, shadowColor);
+ return (hasShadow && (shadowBlur == 0) && (shadowColor.alpha() == 255) && (context->fillColor().alpha() == 255));
+}
+
bool windowsCanHandleTextDrawing(GraphicsContext* context)
{
// Check for non-translation transforms. Sometimes zooms will look better in
@@ -244,7 +254,7 @@ bool windowsCanHandleTextDrawing(GraphicsContext* context)
return false;
// Check for shadow effects.
- if (context->platformContext()->getDrawLooper())
+ if (context->platformContext()->getDrawLooper() && (!windowsCanHandleDrawTextShadow(context)))
return false;
return true;
diff --git a/WebCore/platform/graphics/skia/SkiaFontWin.h b/WebCore/platform/graphics/skia/SkiaFontWin.h
index 0e0c953..0bad30f 100644
--- a/WebCore/platform/graphics/skia/SkiaFontWin.h
+++ b/WebCore/platform/graphics/skia/SkiaFontWin.h
@@ -68,8 +68,12 @@ private:
// Remember that Skia's text drawing origin is the baseline, like WebKit, not
// the top, like Windows.
+// Returns true if the fillColor and shadowColor are opaque and the text-shadow
+// is not blurred.
+bool windowsCanHandleDrawTextShadow(GraphicsContext*);
+
// Returns true if advanced font rendering is recommended.
-bool windowsCanHandleTextDrawing(GraphicsContext* context);
+bool windowsCanHandleTextDrawing(GraphicsContext*);
// Note that the offsets parameter is optional. If not NULL it represents a
// per glyph offset (such as returned by ScriptPlace Windows API function).
diff --git a/WebCore/platform/graphics/skia/SkiaUtils.cpp b/WebCore/platform/graphics/skia/SkiaUtils.cpp
index 55cba37..4242e7d 100644
--- a/WebCore/platform/graphics/skia/SkiaUtils.cpp
+++ b/WebCore/platform/graphics/skia/SkiaUtils.cpp
@@ -47,7 +47,7 @@ static const struct CompositOpToPorterDuffMode {
uint8_t mPorterDuffMode;
} gMapCompositOpsToPorterDuffModes[] = {
{ CompositeClear, SkPorterDuff::kClear_Mode },
- { CompositeCopy, SkPorterDuff::kSrcOver_Mode }, // TODO
+ { CompositeCopy, SkPorterDuff::kSrc_Mode },
{ CompositeSourceOver, SkPorterDuff::kSrcOver_Mode },
{ CompositeSourceIn, SkPorterDuff::kSrcIn_Mode },
{ CompositeSourceOut, SkPorterDuff::kSrcOut_Mode },
@@ -59,7 +59,7 @@ static const struct CompositOpToPorterDuffMode {
{ CompositeXOR, SkPorterDuff::kXor_Mode },
{ CompositePlusDarker, SkPorterDuff::kDarken_Mode },
{ CompositeHighlight, SkPorterDuff::kSrcOver_Mode }, // TODO
- { CompositePlusLighter, SkPorterDuff::kLighten_Mode }
+ { CompositePlusLighter, SkPorterDuff::kAdd_Mode }
};
SkPorterDuff::Mode WebCoreCompositeToSkiaComposite(CompositeOperator op)
@@ -135,12 +135,7 @@ bool SkPathContainsPoint(SkPath* originalPath, const FloatPoint& point, SkPath::
int scale = 1;
SkRect bounds;
-#if PLATFORM(SGL)
- // this is the API from skia/trunk
bounds = originalPath->getBounds();
-#else
- originalPath->computeBounds(&bounds, SkPath::kFast_BoundsType);
-#endif
// We can immediately return false if the point is outside the bounding rect
if (!bounds.contains(SkFloatToScalar(point.x()), SkFloatToScalar(point.y())))
diff --git a/WebCore/platform/graphics/transforms/TransformationMatrix.cpp b/WebCore/platform/graphics/transforms/TransformationMatrix.cpp
index 63a7b8e..a358aaf 100644
--- a/WebCore/platform/graphics/transforms/TransformationMatrix.cpp
+++ b/WebCore/platform/graphics/transforms/TransformationMatrix.cpp
@@ -31,6 +31,7 @@
#include "FloatQuad.h"
#include "IntRect.h"
+#include <wtf/Assertions.h>
#include <wtf/MathExtras.h>
namespace WebCore {
@@ -556,6 +557,9 @@ FloatQuad TransformationMatrix::projectQuad(const FloatQuad& q) const
FloatPoint TransformationMatrix::mapPoint(const FloatPoint& p) const
{
+ if (isIdentityOrTranslation())
+ return FloatPoint(p.x() + static_cast<float>(m_matrix[3][0]), p.y() + static_cast<float>(m_matrix[3][1]));
+
double x, y;
multVecMatrix(p.x(), p.y(), x, y);
return FloatPoint(static_cast<float>(x), static_cast<float>(y));
@@ -563,20 +567,16 @@ FloatPoint TransformationMatrix::mapPoint(const FloatPoint& p) const
FloatPoint3D TransformationMatrix::mapPoint(const FloatPoint3D& p) const
{
+ if (isIdentityOrTranslation())
+ return FloatPoint3D(p.x() + static_cast<float>(m_matrix[3][0]),
+ p.y() + static_cast<float>(m_matrix[3][1]),
+ p.z() + static_cast<float>(m_matrix[3][2]));
+
double x, y, z;
multVecMatrix(p.x(), p.y(), p.z(), x, y, z);
return FloatPoint3D(static_cast<float>(x), static_cast<float>(y), static_cast<float>(z));
}
-IntPoint TransformationMatrix::mapPoint(const IntPoint& point) const
-{
- double x, y;
- multVecMatrix(point.x(), point.y(), x, y);
-
- // Round the point.
- return IntPoint(lround(x), lround(y));
-}
-
IntRect TransformationMatrix::mapRect(const IntRect &rect) const
{
return enclosingIntRect(mapRect(FloatRect(rect)));
@@ -584,12 +584,24 @@ IntRect TransformationMatrix::mapRect(const IntRect &rect) const
FloatRect TransformationMatrix::mapRect(const FloatRect& r) const
{
+ if (isIdentityOrTranslation()) {
+ FloatRect mappedRect(r);
+ mappedRect.move(static_cast<float>(m_matrix[3][0]), static_cast<float>(m_matrix[3][1]));
+ return mappedRect;
+ }
+
FloatQuad resultQuad = mapQuad(FloatQuad(r));
return resultQuad.boundingBox();
}
FloatQuad TransformationMatrix::mapQuad(const FloatQuad& q) const
{
+ if (isIdentityOrTranslation()) {
+ FloatQuad mappedQuad(q);
+ mappedQuad.move(static_cast<float>(m_matrix[3][0]), static_cast<float>(m_matrix[3][1]));
+ return mappedQuad;
+ }
+
FloatQuad result;
result.setP1(mapPoint(q.p1()));
result.setP2(mapPoint(q.p2()));
@@ -781,38 +793,19 @@ TransformationMatrix& TransformationMatrix::rotate3d(double rx, double ry, doubl
TransformationMatrix& TransformationMatrix::translate(double tx, double ty)
{
-#ifdef ANDROID_FASTER_MATRIX
m_matrix[3][0] += tx * m_matrix[0][0] + ty * m_matrix[1][0];
m_matrix[3][1] += tx * m_matrix[0][1] + ty * m_matrix[1][1];
m_matrix[3][2] += tx * m_matrix[0][2] + ty * m_matrix[1][2];
m_matrix[3][3] += tx * m_matrix[0][3] + ty * m_matrix[1][3];
-#else
- // FIXME: optimize to avoid matrix copy
- TransformationMatrix mat;
- mat.m_matrix[3][0] = tx;
- mat.m_matrix[3][1] = ty;
-
- multLeft(mat);
-#endif
return *this;
}
TransformationMatrix& TransformationMatrix::translate3d(double tx, double ty, double tz)
{
-#ifdef ANDROID_FASTER_MATRIX
m_matrix[3][0] += tx * m_matrix[0][0] + ty * m_matrix[1][0] + tz * m_matrix[2][0];
m_matrix[3][1] += tx * m_matrix[0][1] + ty * m_matrix[1][1] + tz * m_matrix[2][1];
m_matrix[3][2] += tx * m_matrix[0][2] + ty * m_matrix[1][2] + tz * m_matrix[2][2];
m_matrix[3][3] += tx * m_matrix[0][3] + ty * m_matrix[1][3] + tz * m_matrix[2][3];
-#else
- // FIXME: optimize to avoid matrix copy
- TransformationMatrix mat;
- mat.m_matrix[3][0] = tx;
- mat.m_matrix[3][1] = ty;
- mat.m_matrix[3][2] = tz;
-
- multLeft(mat);
-#endif
return *this;
}
@@ -945,6 +938,9 @@ void TransformationMatrix::multVecMatrix(double x, double y, double z, double& r
bool TransformationMatrix::isInvertible() const
{
+ if (isIdentityOrTranslation())
+ return true;
+
double det = WebCore::determinant4x4(m_matrix);
if (fabs(det) < SMALL_NUMBER)
@@ -955,8 +951,19 @@ bool TransformationMatrix::isInvertible() const
TransformationMatrix TransformationMatrix::inverse() const
{
- TransformationMatrix invMat;
+ if (isIdentityOrTranslation()) {
+ // identity matrix
+ if (m_matrix[3][0] == 0 && m_matrix[3][1] == 0 && m_matrix[3][2] == 0)
+ return TransformationMatrix();
+
+ // translation
+ return TransformationMatrix(1, 0, 0, 0,
+ 0, 1, 0, 0,
+ 0, 0, 1, 0,
+ -m_matrix[3][0], -m_matrix[3][1], -m_matrix[3][2], 1);
+ }
+ TransformationMatrix invMat;
bool inverted = WebCore::inverse(m_matrix, invMat.m_matrix);
if (!inverted)
return TransformationMatrix();
diff --git a/WebCore/platform/graphics/transforms/TransformationMatrix.h b/WebCore/platform/graphics/transforms/TransformationMatrix.h
index 62e4eb8..7b93e04 100644
--- a/WebCore/platform/graphics/transforms/TransformationMatrix.h
+++ b/WebCore/platform/graphics/transforms/TransformationMatrix.h
@@ -26,6 +26,10 @@
#ifndef TransformationMatrix_h
#define TransformationMatrix_h
+#include "FloatPoint.h"
+#include "IntPoint.h"
+#include <string.h> //for memcpy
+
#if PLATFORM(CG)
#include <CoreGraphics/CGAffineTransform.h>
#elif PLATFORM(CAIRO)
@@ -38,13 +42,9 @@
#include <wx/graphics.h>
#endif
-#include <string.h> //for memcpy
-
namespace WebCore {
-class IntPoint;
class IntRect;
-class FloatPoint;
class FloatPoint3D;
class FloatRect;
class FloatQuad;
@@ -114,7 +114,10 @@ public:
FloatPoint mapPoint(const FloatPoint&) const;
// Like the version above, except that it rounds the mapped point to the nearest integer value.
- IntPoint mapPoint(const IntPoint&) const;
+ IntPoint mapPoint(const IntPoint& p) const
+ {
+ return roundedIntPoint(mapPoint(FloatPoint(p)));
+ }
// If the matrix has 3D components, the z component of the result is
// dropped, effectively projecting the rect into the z=0 plane
@@ -313,6 +316,14 @@ private:
memcpy(m_matrix, m, sizeof(Matrix4));
}
+ bool isIdentityOrTranslation() const
+ {
+ return m_matrix[0][0] == 1 && m_matrix[0][1] == 0 && m_matrix[0][2] == 0 && m_matrix[0][3] == 0 &&
+ m_matrix[1][0] == 0 && m_matrix[1][1] == 1 && m_matrix[1][2] == 0 && m_matrix[1][3] == 0 &&
+ m_matrix[2][0] == 0 && m_matrix[2][1] == 0 && m_matrix[2][2] == 1 && m_matrix[2][3] == 0 &&
+ m_matrix[3][3] == 1;
+ }
+
Matrix4 m_matrix;
};
diff --git a/WebCore/platform/graphics/win/ColorSafari.cpp b/WebCore/platform/graphics/win/ColorSafari.cpp
index a04fd81..25b6b89 100644
--- a/WebCore/platform/graphics/win/ColorSafari.cpp
+++ b/WebCore/platform/graphics/win/ColorSafari.cpp
@@ -29,7 +29,6 @@
#include "config.h"
#include "Color.h"
-#include "NotImplemented.h"
#include <CoreGraphics/CGColor.h>
#include <SafariTheme/SafariTheme.h>
#include <wtf/Assertions.h>
diff --git a/WebCore/platform/graphics/win/FontCGWin.cpp b/WebCore/platform/graphics/win/FontCGWin.cpp
index feeb2ae..803f5db 100644
--- a/WebCore/platform/graphics/win/FontCGWin.cpp
+++ b/WebCore/platform/graphics/win/FontCGWin.cpp
@@ -181,7 +181,7 @@ static void drawGDIGlyphs(GraphicsContext* graphicsContext, const SimpleFontData
SetWorldTransform(hdc, &xform);
}
- SelectObject(hdc, font->m_font.hfont());
+ SelectObject(hdc, font->platformData().hfont());
// Set the correct color.
if (drawIntoBitmap)
@@ -215,9 +215,9 @@ static void drawGDIGlyphs(GraphicsContext* graphicsContext, const SimpleFontData
xform.eDy = point.y();
ModifyWorldTransform(hdc, &xform, MWT_LEFTMULTIPLY);
ExtTextOut(hdc, 0, 0, ETO_GLYPH_INDEX, 0, reinterpret_cast<const WCHAR*>(glyphBuffer.glyphs(from)), numGlyphs, gdiAdvances.data());
- if (font->m_syntheticBoldOffset) {
+ if (font->syntheticBoldOffset()) {
xform.eM21 = 0;
- xform.eDx = font->m_syntheticBoldOffset;
+ xform.eDx = font->syntheticBoldOffset();
xform.eDy = 0;
ModifyWorldTransform(hdc, &xform, MWT_LEFTMULTIPLY);
ExtTextOut(hdc, 0, 0, ETO_GLYPH_INDEX, 0, reinterpret_cast<const WCHAR*>(glyphBuffer.glyphs(from)), numGlyphs, gdiAdvances.data());
@@ -250,21 +250,21 @@ static void drawGDIGlyphs(GraphicsContext* graphicsContext, const SimpleFontData
if (drawingMode & cTextFill) {
CGContextAddPath(cgContext, glyphPath.get());
CGContextFillPath(cgContext);
- if (font->m_syntheticBoldOffset) {
- CGContextTranslateCTM(cgContext, font->m_syntheticBoldOffset, 0);
+ if (font->syntheticBoldOffset()) {
+ CGContextTranslateCTM(cgContext, font->syntheticBoldOffset(), 0);
CGContextAddPath(cgContext, glyphPath.get());
CGContextFillPath(cgContext);
- CGContextTranslateCTM(cgContext, -font->m_syntheticBoldOffset, 0);
+ CGContextTranslateCTM(cgContext, -font->syntheticBoldOffset(), 0);
}
}
if (drawingMode & cTextStroke) {
CGContextAddPath(cgContext, glyphPath.get());
CGContextStrokePath(cgContext);
- if (font->m_syntheticBoldOffset) {
- CGContextTranslateCTM(cgContext, font->m_syntheticBoldOffset, 0);
+ if (font->syntheticBoldOffset()) {
+ CGContextTranslateCTM(cgContext, font->syntheticBoldOffset(), 0);
CGContextAddPath(cgContext, glyphPath.get());
CGContextStrokePath(cgContext);
- CGContextTranslateCTM(cgContext, -font->m_syntheticBoldOffset, 0);
+ CGContextTranslateCTM(cgContext, -font->syntheticBoldOffset(), 0);
}
}
@@ -341,8 +341,8 @@ void Font::drawGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* fo
graphicsContext->setFillColor(shadowFillColor);
CGContextSetTextPosition(cgContext, point.x() + translation.width() + shadowSize.width(), point.y() + translation.height() + shadowSize.height());
CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
- if (font->m_syntheticBoldOffset) {
- CGContextSetTextPosition(cgContext, point.x() + translation.width() + shadowSize.width() + font->m_syntheticBoldOffset, point.y() + translation.height() + shadowSize.height());
+ if (font->syntheticBoldOffset()) {
+ CGContextSetTextPosition(cgContext, point.x() + translation.width() + shadowSize.width() + font->syntheticBoldOffset(), point.y() + translation.height() + shadowSize.height());
CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
}
graphicsContext->setFillColor(fillColor);
@@ -350,8 +350,8 @@ void Font::drawGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* fo
CGContextSetTextPosition(cgContext, point.x() + translation.width(), point.y() + translation.height());
CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
- if (font->m_syntheticBoldOffset) {
- CGContextSetTextPosition(cgContext, point.x() + translation.width() + font->m_syntheticBoldOffset, point.y() + translation.height());
+ if (font->syntheticBoldOffset()) {
+ CGContextSetTextPosition(cgContext, point.x() + translation.width() + font->syntheticBoldOffset(), point.y() + translation.height());
CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
}
diff --git a/WebCore/platform/graphics/win/FontCustomPlatformData.cpp b/WebCore/platform/graphics/win/FontCustomPlatformData.cpp
index 1ac3359..24db173 100644
--- a/WebCore/platform/graphics/win/FontCustomPlatformData.cpp
+++ b/WebCore/platform/graphics/win/FontCustomPlatformData.cpp
@@ -116,7 +116,7 @@ size_t getBytesWithOffset(void *info, void* buffer, size_t offset, size_t count)
// Streams the concatenation of a header and font data.
class EOTStream {
public:
- EOTStream(const Vector<uint8_t, 512>& eotHeader, const SharedBuffer* fontData, size_t overlayDst, size_t overlaySrc, size_t overlayLength)
+ EOTStream(const EOTHeader& eotHeader, const SharedBuffer* fontData, size_t overlayDst, size_t overlaySrc, size_t overlayLength)
: m_eotHeader(eotHeader)
, m_fontData(fontData)
, m_overlayDst(overlayDst)
@@ -130,7 +130,7 @@ public:
size_t read(void* buffer, size_t count);
private:
- const Vector<uint8_t, 512>& m_eotHeader;
+ const EOTHeader& m_eotHeader;
const SharedBuffer* m_fontData;
size_t m_overlayDst;
size_t m_overlaySrc;
@@ -206,7 +206,7 @@ FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
// TTLoadEmbeddedFont works only with Embedded OpenType (.eot) data, so we need to create an EOT header
// and prepend it to the font data.
- Vector<uint8_t, 512> eotHeader;
+ EOTHeader eotHeader;
size_t overlayDst;
size_t overlaySrc;
size_t overlayLength;
diff --git a/WebCore/platform/graphics/win/FontWin.cpp b/WebCore/platform/graphics/win/FontWin.cpp
index 5e423e0..27d8dee 100644
--- a/WebCore/platform/graphics/win/FontWin.cpp
+++ b/WebCore/platform/graphics/win/FontWin.cpp
@@ -30,13 +30,17 @@
#include "GlyphBuffer.h"
#include "GraphicsContext.h"
#include "IntRect.h"
-#include "NotImplemented.h"
#include "SimpleFontData.h"
#include "UniscribeController.h"
#include <wtf/MathExtras.h>
namespace WebCore {
+bool Font::canReturnFallbackFontsForComplexText()
+{
+ return true;
+}
+
FloatRect Font::selectionRectForComplexText(const TextRun& run, const IntPoint& point, int h,
int from, int to) const
{
@@ -85,9 +89,9 @@ void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const F
drawGlyphBuffer(context, glyphBuffer, run, startPoint);
}
-float Font::floatWidthForComplexText(const TextRun& run) const
+float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts) const
{
- UniscribeController controller(this, run);
+ UniscribeController controller(this, run, fallbackFonts);
controller.advance(run.length());
return controller.runWidthSoFar();
}
diff --git a/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp b/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp
index da5b503..917631b 100644
--- a/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp
+++ b/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp
@@ -27,7 +27,6 @@
#include "GraphicsContext.h"
#include "TransformationMatrix.h"
-#include "NotImplemented.h"
#include "Path.h"
#include <CoreGraphics/CGBitmapContext.h>
diff --git a/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp b/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp
index 1980d18..ca3cb5d 100644
--- a/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp
+++ b/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp
@@ -27,7 +27,6 @@
#include "GraphicsContext.h"
#include "TransformationMatrix.h"
-#include "NotImplemented.h"
#include "Path.h"
#include <cairo-win32.h>
@@ -37,13 +36,61 @@ using namespace std;
namespace WebCore {
+static cairo_t* createCairoContextWithHDC(HDC hdc, bool hasAlpha)
+{
+ // Put the HDC In advanced mode so it will honor affine transforms.
+ SetGraphicsMode(hdc, GM_ADVANCED);
+
+ HBITMAP bitmap = static_cast<HBITMAP>(GetCurrentObject(hdc, OBJ_BITMAP));
+
+ BITMAP info;
+ GetObject(bitmap, sizeof(info), &info);
+ ASSERT(info.bmBitsPixel == 32);
+
+ cairo_surface_t* image = cairo_image_surface_create_for_data((unsigned char*)info.bmBits,
+ CAIRO_FORMAT_ARGB32,
+ info.bmWidth,
+ info.bmHeight,
+ info.bmWidthBytes);
+
+ cairo_t* context = cairo_create(image);
+ cairo_surface_destroy(image);
+
+ return context;
+}
+
+static BITMAPINFO bitmapInfoForSize(const IntSize& size)
+{
+ BITMAPINFO bitmapInfo;
+ bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bitmapInfo.bmiHeader.biWidth = size.width();
+ bitmapInfo.bmiHeader.biHeight = size.height();
+ bitmapInfo.bmiHeader.biPlanes = 1;
+ bitmapInfo.bmiHeader.biBitCount = 32;
+ bitmapInfo.bmiHeader.biCompression = BI_RGB;
+ bitmapInfo.bmiHeader.biSizeImage = 0;
+ bitmapInfo.bmiHeader.biXPelsPerMeter = 0;
+ bitmapInfo.bmiHeader.biYPelsPerMeter = 0;
+ bitmapInfo.bmiHeader.biClrUsed = 0;
+ bitmapInfo.bmiHeader.biClrImportant = 0;
+
+ return bitmapInfo;
+}
+
+static void fillWithClearColor(HBITMAP bitmap)
+{
+ BITMAP bmpInfo;
+ GetObject(bitmap, sizeof(bmpInfo), &bmpInfo);
+ int bufferSize = bmpInfo.bmWidthBytes * bmpInfo.bmHeight;
+ memset(bmpInfo.bmBits, 0, bufferSize);
+}
+
GraphicsContext::GraphicsContext(HDC dc, bool hasAlpha)
: m_common(createGraphicsContextPrivate())
, m_data(new GraphicsContextPlatformPrivate)
{
if (dc) {
- cairo_surface_t* surface = cairo_win32_surface_create(dc);
- m_data->cr = cairo_create(surface);
+ m_data->cr = createCairoContextWithHDC(dc, hasAlpha);
m_data->m_hdc = dc;
} else {
setPaintingDisabled(true);
@@ -60,52 +107,95 @@ GraphicsContext::GraphicsContext(HDC dc, bool hasAlpha)
HDC GraphicsContext::getWindowsContext(const IntRect& dstRect, bool supportAlphaBlend, bool mayCreateBitmap)
{
- // FIXME: We aren't really doing anything with the 'mayCreateBitmap' flag. This needs
- // to be addressed.
- if (dstRect.isEmpty())
- return 0;
-
- // This is probably wrong, and definitely out of date. Pulled from old SVN
- cairo_surface_t* surface = cairo_get_target(platformContext());
- HDC hdc = cairo_win32_surface_get_dc(surface);
- SaveDC(hdc);
-
- // FIXME: We need to make sure a clip is really set on the HDC.
- // Call SetWorldTransform to honor the current Cairo transform.
- SetGraphicsMode(hdc, GM_ADVANCED); // We need this call for themes to honor world transforms.
- cairo_matrix_t mat;
- cairo_get_matrix(platformContext(), &mat);
- XFORM xform;
- xform.eM11 = mat.xx;
- xform.eM12 = mat.xy;
- xform.eM21 = mat.yx;
- xform.eM22 = mat.yy;
- xform.eDx = mat.x0;
- xform.eDy = mat.y0;
- ::SetWorldTransform(hdc, &xform);
-
- return hdc;
+ // FIXME: Should a bitmap be created also when a shadow is set?
+ if (mayCreateBitmap && inTransparencyLayer()) {
+ if (dstRect.isEmpty())
+ return 0;
+
+ // Create a bitmap DC in which to draw.
+ BITMAPINFO bitmapInfo = bitmapInfoForSize(dstRect.size());
+
+ void* pixels = 0;
+ HBITMAP bitmap = ::CreateDIBSection(NULL, &bitmapInfo, DIB_RGB_COLORS, &pixels, 0, 0);
+ if (!bitmap)
+ return 0;
+
+ HDC bitmapDC = ::CreateCompatibleDC(m_data->m_hdc);
+ ::SelectObject(bitmapDC, bitmap);
+
+ // Fill our buffer with clear if we're going to alpha blend.
+ if (supportAlphaBlend)
+ fillWithClearColor(bitmap);
+
+ // Make sure we can do world transforms.
+ SetGraphicsMode(bitmapDC, GM_ADVANCED);
+
+ // Apply a translation to our context so that the drawing done will be at (0,0) of the bitmap.
+ XFORM xform;
+ xform.eM11 = 1.0f;
+ xform.eM12 = 0.0f;
+ xform.eM21 = 0.0f;
+ xform.eM22 = 1.0f;
+ xform.eDx = -dstRect.x();
+ xform.eDy = -dstRect.y();
+ ::SetWorldTransform(bitmapDC, &xform);
+
+ return bitmapDC;
+ }
+
+ cairo_surface_t* surface = cairo_win32_surface_create(m_data->m_hdc);
+ cairo_surface_flush(surface);
+ cairo_surface_destroy(surface);
+
+ m_data->save();
+
+ return m_data->m_hdc;
}
void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect& dstRect, bool supportAlphaBlend, bool mayCreateBitmap)
{
- // FIXME: We aren't really doing anything with the 'mayCreateBitmap' flag. This needs
- // to be addressed.
- if (dstRect.isEmpty())
- return;
+ if (!mayCreateBitmap || !hdc || !inTransparencyLayer()) {
+ m_data->restore();
+ return;
+ }
- cairo_surface_t* surface = cairo_get_target(platformContext());
- HDC hdc2 = cairo_win32_surface_get_dc(surface);
- RestoreDC(hdc2, -1);
- cairo_surface_mark_dirty(surface);
+ if (dstRect.isEmpty())
+ return;
+
+ HBITMAP bitmap = static_cast<HBITMAP>(GetCurrentObject(hdc, OBJ_BITMAP));
+
+ BITMAP info;
+ GetObject(bitmap, sizeof(info), &info);
+ ASSERT(info.bmBitsPixel == 32);
+
+ // Need to make a cairo_surface_t out of the bitmap's pixel buffer and then draw
+ // it into our context.
+ cairo_surface_t* image = cairo_image_surface_create_for_data((unsigned char*)info.bmBits,
+ CAIRO_FORMAT_ARGB32,
+ info.bmWidth,
+ info.bmHeight,
+ info.bmWidthBytes);
+
+ // Scale the target surface to the new image size, and flip it
+ // so that when we set the srcImage as the surface it will draw
+ // right-side-up.
+ cairo_translate(m_data->cr, 0, dstRect.height());
+ cairo_scale(m_data->cr, dstRect.width(), -dstRect.height());
+ cairo_set_source_surface (m_data->cr, image, dstRect.x(), dstRect.y());
+
+ if (m_data->layers.size())
+ cairo_paint_with_alpha(m_data->cr, m_data->layers.last());
+ else
+ cairo_paint(m_data->cr);
+
+ // Delete all our junk.
+ cairo_surface_destroy(image);
+ ::DeleteDC(hdc);
+ ::DeleteObject(bitmap);
}
void GraphicsContextPlatformPrivate::concatCTM(const TransformationMatrix& transform)
{
- cairo_surface_t* surface = cairo_get_target(cr);
- HDC hdc = cairo_win32_surface_get_dc(surface);
- SaveDC(hdc);
-
const cairo_matrix_t* matrix = reinterpret_cast<const cairo_matrix_t*>(&transform);
XFORM xform;
@@ -116,7 +206,15 @@ void GraphicsContextPlatformPrivate::concatCTM(const TransformationMatrix& trans
xform.eDx = matrix->x0;
xform.eDy = matrix->y0;
- ModifyWorldTransform(hdc, &xform, MWT_LEFTMULTIPLY);
+ ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY);
+}
+
+void GraphicsContextPlatformPrivate::syncContext(PlatformGraphicsContext* cr)
+{
+ cairo_surface_t* surface = cairo_get_target(cr);
+ m_hdc = cairo_win32_surface_get_dc(surface);
+
+ SetGraphicsMode(m_hdc, GM_ADVANCED); // We need this call for themes to honor world transforms.
}
}
diff --git a/WebCore/platform/graphics/win/ImageCairoWin.cpp b/WebCore/platform/graphics/win/ImageCairoWin.cpp
index 95bb7bc..06428b8 100644
--- a/WebCore/platform/graphics/win/ImageCairoWin.cpp
+++ b/WebCore/platform/graphics/win/ImageCairoWin.cpp
@@ -47,13 +47,17 @@ bool BitmapImage::getHBITMAPOfSize(HBITMAP bmp, LPSIZE size)
memset(bmpInfo.bmBits, 255, bufferSize);
}
- HDC tempDC = CreateCompatibleDC(0);
- if (!tempDC) {
- LOG_ERROR("Failed to create in-memory DC for Image::blit()");
- return false;
- }
- SelectObject(tempDC, bmp);
- GraphicsContext gc(tempDC);
+ cairo_surface_t* image = cairo_image_surface_create_for_data((unsigned char*)bmpInfo.bmBits,
+ CAIRO_FORMAT_ARGB32,
+ bmpInfo.bmWidth,
+ bmpInfo.bmHeight,
+ bmpInfo.bmWidthBytes);
+
+
+ cairo_t* targetRef = cairo_create(image);
+ cairo_surface_destroy(image);
+
+ GraphicsContext gc(targetRef);
IntSize imageSize = BitmapImage::size();
if (size)
@@ -62,7 +66,7 @@ bool BitmapImage::getHBITMAPOfSize(HBITMAP bmp, LPSIZE size)
draw(&gc, FloatRect(0.0f, 0.0f, bmpInfo.bmWidth, bmpInfo.bmHeight), FloatRect(0.0f, 0.0f, imageSize.width(), imageSize.height()), CompositeCopy);
// Do cleanup
- DeleteDC(tempDC);
+ cairo_destroy(targetRef);
return true;
}
diff --git a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp
index c293f49..35ea786 100644
--- a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp
+++ b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp
@@ -70,6 +70,8 @@ MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
, m_networkState(MediaPlayer::Empty)
, m_readyState(MediaPlayer::HaveNothing)
, m_enabledTrackCount(0)
+ , m_totalTrackCount(0)
+ , m_hasUnsupportedTracks(false)
, m_startedPlaying(false)
, m_isStreaming(false)
#if DRAW_FRAME_RATE
@@ -320,9 +322,17 @@ void MediaPlayerPrivate::updateStates()
long loadState = m_qtMovie ? m_qtMovie->loadState() : QTMovieLoadStateError;
- if (loadState >= QTMovieLoadStateLoaded && m_readyState < MediaPlayer::HaveMetadata && !m_player->inMediaDocument()) {
- m_qtMovie->disableUnsupportedTracks(m_enabledTrackCount);
- if (!m_enabledTrackCount)
+ if (loadState >= QTMovieLoadStateLoaded && m_readyState < MediaPlayer::HaveMetadata) {
+ m_qtMovie->disableUnsupportedTracks(m_enabledTrackCount, m_totalTrackCount);
+ if (m_player->inMediaDocument()) {
+ if (!m_enabledTrackCount || m_enabledTrackCount != m_totalTrackCount) {
+ // This is a type of media that we do not handle directly with a <video>
+ // element, eg. QuickTime VR, a movie with a sprite track, etc. Tell the
+ // MediaPlayerClient that we won't support it.
+ sawUnsupportedTracks();
+ return;
+ }
+ } else if (!m_enabledTrackCount)
loadState = QTMovieLoadStateError;
}
@@ -341,6 +351,14 @@ void MediaPlayerPrivate::updateStates()
m_networkState = MediaPlayer::Loading;
m_readyState = MediaPlayer::HaveNothing;
} else {
+ if (m_player->inMediaDocument()) {
+ // Something went wrong in the loading of media within a standalone file.
+ // This can occur with chained ref movies that eventually resolve to a
+ // file we don't support.
+ sawUnsupportedTracks();
+ return;
+ }
+
float loaded = maxTimeLoaded();
if (!loaded)
m_readyState = MediaPlayer::HaveNothing;
@@ -365,9 +383,18 @@ void MediaPlayerPrivate::updateStates()
m_player->readyStateChanged();
}
+void MediaPlayerPrivate::sawUnsupportedTracks()
+{
+ m_qtMovie->setDisabled(true);
+ m_hasUnsupportedTracks = true;
+ m_player->mediaPlayerClient()->mediaPlayerSawUnsupportedTracks(m_player);
+}
void MediaPlayerPrivate::didEnd()
{
+ if (m_hasUnsupportedTracks)
+ return;
+
m_startedPlaying = false;
#if DRAW_FRAME_RATE
m_timeStoppedPlaying = GetTickCount();
@@ -378,20 +405,21 @@ void MediaPlayerPrivate::didEnd()
void MediaPlayerPrivate::setSize(const IntSize& size)
{
- if (m_qtMovie)
- m_qtMovie->setSize(size.width(), size.height());
+ if (m_hasUnsupportedTracks || !m_qtMovie)
+ return;
+ m_qtMovie->setSize(size.width(), size.height());
}
void MediaPlayerPrivate::setVisible(bool b)
{
- if (!m_qtMovie)
+ if (m_hasUnsupportedTracks || !m_qtMovie)
return;
m_qtMovie->setVisible(b);
}
void MediaPlayerPrivate::paint(GraphicsContext* p, const IntRect& r)
{
- if (p->paintingDisabled() || !m_qtMovie)
+ if (p->paintingDisabled() || !m_qtMovie || m_hasUnsupportedTracks)
return;
HDC hdc = p->getWindowsContext(r);
m_qtMovie->paint(hdc, r.x(), r.y());
@@ -463,18 +491,27 @@ MediaPlayer::SupportsType MediaPlayerPrivate::supportsType(const String& type, c
void MediaPlayerPrivate::movieEnded(QTMovieWin* movie)
{
+ if (m_hasUnsupportedTracks)
+ return;
+
ASSERT(m_qtMovie.get() == movie);
didEnd();
}
void MediaPlayerPrivate::movieLoadStateChanged(QTMovieWin* movie)
{
+ if (m_hasUnsupportedTracks)
+ return;
+
ASSERT(m_qtMovie.get() == movie);
updateStates();
}
void MediaPlayerPrivate::movieTimeChanged(QTMovieWin* movie)
{
+ if (m_hasUnsupportedTracks)
+ return;
+
ASSERT(m_qtMovie.get() == movie);
updateStates();
m_player->timeChanged();
@@ -482,6 +519,9 @@ void MediaPlayerPrivate::movieTimeChanged(QTMovieWin* movie)
void MediaPlayerPrivate::movieNewImageAvailable(QTMovieWin* movie)
{
+ if (m_hasUnsupportedTracks)
+ return;
+
ASSERT(m_qtMovie.get() == movie);
#if DRAW_FRAME_RATE
if (m_startedPlaying) {
diff --git a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h
index 63aa62b..3207867 100644
--- a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h
+++ b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h
@@ -98,6 +98,7 @@ private:
void cancelSeek();
void seekTimerFired(Timer<MediaPlayerPrivate>*);
float maxTimeLoaded() const;
+ void sawUnsupportedTracks();
virtual void movieEnded(QTMovieWin*);
virtual void movieLoadStateChanged(QTMovieWin*);
@@ -118,6 +119,8 @@ private:
MediaPlayer::NetworkState m_networkState;
MediaPlayer::ReadyState m_readyState;
unsigned m_enabledTrackCount;
+ unsigned m_totalTrackCount;
+ bool m_hasUnsupportedTracks;
bool m_startedPlaying;
bool m_isStreaming;
#if DRAW_FRAME_RATE
diff --git a/WebCore/platform/graphics/win/QTMovieWin.cpp b/WebCore/platform/graphics/win/QTMovieWin.cpp
index 3f23698..1d10006 100644
--- a/WebCore/platform/graphics/win/QTMovieWin.cpp
+++ b/WebCore/platform/graphics/win/QTMovieWin.cpp
@@ -91,6 +91,7 @@ public:
void createGWorld();
void deleteGWorld();
void clearGWorld();
+ void cacheMovieScale();
void setSize(int, int);
@@ -112,6 +113,11 @@ public:
int m_gWorldHeight;
GWorldPtr m_savedGWorld;
long m_loadError;
+ float m_widthScaleFactor;
+ float m_heightScaleFactor;
+#if !ASSERT_DISABLED
+ bool m_scaleCached;
+#endif
};
QTMovieWinPrivate::QTMovieWinPrivate()
@@ -133,6 +139,11 @@ QTMovieWinPrivate::QTMovieWinPrivate()
, m_gWorldHeight(0)
, m_savedGWorld(0)
, m_loadError(0)
+ , m_widthScaleFactor(1)
+ , m_heightScaleFactor(1)
+#if !ASSERT_DISABLED
+ , m_scaleCached(false)
+#endif
{
}
@@ -179,6 +190,26 @@ void QTMovieWinPrivate::endTask()
updateTaskTimer();
}
+void QTMovieWinPrivate::cacheMovieScale()
+{
+ Rect naturalRect;
+ Rect initialRect;
+
+ GetMovieNaturalBoundsRect(m_movie, &naturalRect);
+ GetMovieBox(m_movie, &initialRect);
+
+ int naturalWidth = naturalRect.right - naturalRect.left;
+ int naturalHeight = naturalRect.bottom - naturalRect.top;
+
+ if (naturalWidth)
+ m_widthScaleFactor = (initialRect.right - initialRect.left) / naturalWidth;
+ if (naturalHeight)
+ m_heightScaleFactor = (initialRect.bottom - initialRect.top) / naturalHeight;
+#if !ASSERT_DISABLED
+ m_scaleCached = true;;
+#endif
+}
+
void QTMovieWinPrivate::task()
{
ASSERT(m_tasking);
@@ -192,20 +223,27 @@ void QTMovieWinPrivate::task()
// GetMovieLoadState documentation says that you should not call it more often than every quarter of a second.
if (systemTime() >= m_lastLoadStateCheckTime + 0.25 || m_loadError) {
- // If load fails QT's load state is kMovieLoadStateComplete.
+ // If load fails QT's load state is QTMovieLoadStateComplete.
// This is different from QTKit API and seems strange.
- long loadState = m_loadError ? kMovieLoadStateError : GetMovieLoadState(m_movie);
+ long loadState = m_loadError ? QTMovieLoadStateError : GetMovieLoadState(m_movie);
if (loadState != m_loadState) {
// we only need to erase the movie gworld when the load state changes to loaded while it
// is visible as the gworld is destroyed/created when visibility changes
- if (loadState >= QTMovieLoadStateLoaded && m_loadState < QTMovieLoadStateLoaded && m_visible)
- clearGWorld();
+ if (loadState >= QTMovieLoadStateLoaded && m_loadState < QTMovieLoadStateLoaded) {
+ if (m_visible)
+ clearGWorld();
+ cacheMovieScale();
+ }
m_loadState = loadState;
- if (!m_movieController && m_loadState >= kMovieLoadStateLoaded)
+ if (!m_movieController && m_loadState >= QTMovieLoadStateLoaded)
createMovieController();
m_client->movieLoadStateChanged(m_movieWin);
+ if (m_movieWin->m_disabled) {
+ endTask();
+ return;
+ }
}
m_lastLoadStateCheckTime = systemTime();
}
@@ -259,7 +297,7 @@ void QTMovieWinPrivate::registerDrawingCallback()
void QTMovieWinPrivate::drawingComplete()
{
- if (!m_gWorld || m_loadState < kMovieLoadStateLoaded)
+ if (!m_gWorld || m_movieWin->m_disabled || m_loadState < QTMovieLoadStateLoaded)
return;
m_client->movieNewImageAvailable(m_movieWin);
}
@@ -284,7 +322,7 @@ void QTMovieWinPrivate::updateGWorld()
void QTMovieWinPrivate::createGWorld()
{
ASSERT(!m_gWorld);
- if (!m_movie)
+ if (!m_movie || m_loadState < QTMovieLoadStateLoaded)
return;
m_gWorldWidth = max(cGWorldMinWidth, m_width);
@@ -334,8 +372,17 @@ void QTMovieWinPrivate::setSize(int width, int height)
return;
m_width = width;
m_height = height;
- if (!m_movie)
+
+ // Do not change movie box before reaching load state loaded as we grab
+ // the initial size when task() sees that state for the first time, and
+ // we need the initial size to be able to scale movie properly.
+ if (!m_movie || m_loadState < QTMovieLoadStateLoaded)
return;
+
+#if !ASSERT_DISABLED
+ ASSERT(m_scaleCached);
+#endif
+
Rect bounds;
bounds.top = 0;
bounds.left = 0;
@@ -364,6 +411,7 @@ void QTMovieWinPrivate::deleteGWorld()
QTMovieWin::QTMovieWin(QTMovieWinClient* client)
: m_private(new QTMovieWinPrivate())
+ , m_disabled(false)
{
m_private->m_movieWin = this;
m_private->m_client = client;
@@ -478,8 +526,8 @@ void QTMovieWin::getNaturalSize(int& width, int& height)
if (m_private->m_movie)
GetMovieNaturalBoundsRect(m_private->m_movie, &rect);
- width = rect.right;
- height = rect.bottom;
+ width = (rect.right - rect.left) * m_private->m_widthScaleFactor;
+ height = (rect.bottom - rect.top) * m_private->m_heightScaleFactor;
}
void QTMovieWin::setSize(int width, int height)
@@ -593,6 +641,7 @@ void QTMovieWin::load(const UChar* url, int len)
movieProps[moviePropCount].propStatus = 0;
moviePropCount++;
+ ASSERT(moviePropCount <= sizeof(movieProps)/sizeof(movieProps[0]));
m_private->m_loadError = NewMovieFromProperties(moviePropCount, movieProps, 0, NULL, &m_private->m_movie);
CFRelease(urlRef);
@@ -601,15 +650,24 @@ end:
// get the load fail callback quickly
if (m_private->m_loadError)
updateTaskTimer(0);
- else
+ else {
+ OSType mode = kQTApertureMode_CleanAperture;
+
+ // Set the aperture mode property on a movie to signal that we want aspect ratio
+ // and clean aperture dimensions. Don't worry about errors, we can't do anything if
+ // the installed version of QT doesn't support it and it isn't serious enough to
+ // warrant failing.
+ QTSetMovieProperty(m_private->m_movie, kQTPropertyClass_Visual, kQTVisualPropertyID_ApertureMode, sizeof(mode), &mode);
m_private->registerDrawingCallback();
+ }
CFRelease(urlStringRef);
}
-void QTMovieWin::disableUnsupportedTracks(unsigned& enabledTrackCount)
+void QTMovieWin::disableUnsupportedTracks(unsigned& enabledTrackCount, unsigned& totalTrackCount)
{
if (!m_private->m_movie) {
+ totalTrackCount = 0;
enabledTrackCount = 0;
return;
}
@@ -623,11 +681,16 @@ void QTMovieWin::disableUnsupportedTracks(unsigned& enabledTrackCount)
allowedTrackTypes->add(BaseMediaType);
allowedTrackTypes->add('clcp'); // Closed caption
allowedTrackTypes->add('sbtl'); // Subtitle
+ allowedTrackTypes->add('odsm'); // MPEG-4 object descriptor stream
+ allowedTrackTypes->add('sdsm'); // MPEG-4 scene description stream
+ allowedTrackTypes->add(TimeCodeMediaType);
+ allowedTrackTypes->add(TimeCode64MediaType);
}
long trackCount = GetMovieTrackCount(m_private->m_movie);
enabledTrackCount = trackCount;
-
+ totalTrackCount = trackCount;
+
// Track indexes are 1-based. yuck. These things must descend from old-
// school mac resources or something.
for (long trackIndex = 1; trackIndex <= trackCount; trackIndex++) {
@@ -716,6 +779,11 @@ void QTMovieWin::disableUnsupportedTracks(unsigned& enabledTrackCount)
}
}
+void QTMovieWin::setDisabled(bool b)
+{
+ m_disabled = b;
+}
+
bool QTMovieWin::hasVideo() const
{
diff --git a/WebCore/platform/graphics/win/QTMovieWin.h b/WebCore/platform/graphics/win/QTMovieWin.h
index 2186974..70cbef5 100644
--- a/WebCore/platform/graphics/win/QTMovieWin.h
+++ b/WebCore/platform/graphics/win/QTMovieWin.h
@@ -84,7 +84,8 @@ public:
void setVisible(bool);
void paint(HDC, int x, int y);
- void disableUnsupportedTracks(unsigned& enabledTrackCount);
+ void disableUnsupportedTracks(unsigned& enabledTrackCount, unsigned& totalTrackCount);
+ void setDisabled(bool);
bool hasVideo() const;
@@ -93,6 +94,7 @@ public:
private:
QTMovieWinPrivate* m_private;
+ bool m_disabled;
friend class QTMovieWinPrivate;
};
diff --git a/WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp b/WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp
index 8b5ab87..aaa089a 100644
--- a/WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp
+++ b/WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp
@@ -52,27 +52,27 @@ static inline float scaleEmToUnits(float x, unsigned unitsPerEm) { return unitsP
void SimpleFontData::platformInit()
{
- m_syntheticBoldOffset = m_font.syntheticBold() ? 1.0f : 0.f;
+ m_syntheticBoldOffset = m_platformData.syntheticBold() ? 1.0f : 0.f;
m_scriptCache = 0;
m_scriptFontProperties = 0;
m_isSystemFont = false;
- if (m_font.useGDI())
+ if (m_platformData.useGDI())
return initGDIFont();
- CGFontRef font = m_font.cgFont();
+ CGFontRef font = m_platformData.cgFont();
int iAscent = CGFontGetAscent(font);
int iDescent = CGFontGetDescent(font);
int iLineGap = CGFontGetLeading(font);
m_unitsPerEm = CGFontGetUnitsPerEm(font);
- float pointSize = m_font.size();
+ float pointSize = m_platformData.size();
float fAscent = scaleEmToUnits(iAscent, m_unitsPerEm) * pointSize;
float fDescent = -scaleEmToUnits(iDescent, m_unitsPerEm) * pointSize;
float fLineGap = scaleEmToUnits(iLineGap, m_unitsPerEm) * pointSize;
if (!isCustomFont()) {
HDC dc = GetDC(0);
- HGDIOBJ oldFont = SelectObject(dc, m_font.hfont());
+ HGDIOBJ oldFont = SelectObject(dc, m_platformData.hfont());
int faceLength = GetTextFace(dc, 0, 0);
Vector<TCHAR> faceName(faceLength);
GetTextFace(dc, faceLength, faceName.data());
@@ -116,6 +116,16 @@ void SimpleFontData::platformInit()
}
}
+void SimpleFontData::platformCharWidthInit()
+{
+ // GDI Fonts init charwidths in initGDIFont.
+ if (!m_platformData.useGDI()) {
+ m_avgCharWidth = 0.f;
+ m_maxCharWidth = 0.f;
+ initCharWidths();
+ }
+}
+
void SimpleFontData::platformDestroy()
{
platformCommonDestroy();
@@ -123,11 +133,11 @@ void SimpleFontData::platformDestroy()
float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
{
- if (m_font.useGDI())
+ if (m_platformData.useGDI())
return widthForGDIGlyph(glyph);
- CGFontRef font = m_font.cgFont();
- float pointSize = m_font.size();
+ CGFontRef font = m_platformData.cgFont();
+ float pointSize = m_platformData.size();
CGSize advance;
CGAffineTransform m = CGAffineTransformMakeScale(pointSize, pointSize);
diff --git a/WebCore/platform/graphics/win/SimpleFontDataCairoWin.cpp b/WebCore/platform/graphics/win/SimpleFontDataCairoWin.cpp
index 07d5305..2e51621 100644
--- a/WebCore/platform/graphics/win/SimpleFontDataCairoWin.cpp
+++ b/WebCore/platform/graphics/win/SimpleFontDataCairoWin.cpp
@@ -35,7 +35,6 @@
#include "FontCache.h"
#include "FontDescription.h"
#include "MathExtras.h"
-#include "NotImplemented.h"
#include <cairo.h>
#include <cairo-win32.h>
#include <mlang.h>
@@ -50,14 +49,16 @@ void SimpleFontData::platformInit()
m_isSystemFont = false;
m_syntheticBoldOffset = 0;
- if (m_font.useGDI())
+ m_syntheticBoldOffset = m_platformData.syntheticBold() ? 1.0f : 0.f;
+
+ if (m_platformData.useGDI())
return initGDIFont();
HDC hdc = GetDC(0);
SaveDC(hdc);
- cairo_scaled_font_t* scaledFont = m_font.scaledFont();
- const double metricsMultiplier = cairo_win32_scaled_font_get_metrics_factor(scaledFont) * m_font.size();
+ cairo_scaled_font_t* scaledFont = m_platformData.scaledFont();
+ const double metricsMultiplier = cairo_win32_scaled_font_get_metrics_factor(scaledFont) * m_platformData.size();
cairo_win32_scaled_font_select_font(scaledFont, hdc);
@@ -68,6 +69,8 @@ void SimpleFontData::platformInit()
m_xHeight = m_ascent * 0.56f; // Best guess for xHeight for non-Truetype fonts.
m_lineGap = lroundf(textMetrics.tmExternalLeading * metricsMultiplier);
m_lineSpacing = m_ascent + m_descent + m_lineGap;
+ m_avgCharWidth = lroundf(textMetrics.tmAveCharWidth * metricsMultiplier);
+ m_maxCharWidth = lroundf(textMetrics.tmMaxCharWidth * metricsMultiplier);
OUTLINETEXTMETRIC metrics;
if (GetOutlineTextMetrics(hdc, sizeof(metrics), &metrics) > 0) {
@@ -89,25 +92,30 @@ void SimpleFontData::platformInit()
ReleaseDC(0, hdc);
}
+void SimpleFontData::platformCharWidthInit()
+{
+ // charwidths are set in platformInit.
+}
+
void SimpleFontData::platformDestroy()
{
- cairo_font_face_destroy(m_font.fontFace());
- cairo_scaled_font_destroy(m_font.scaledFont());
+ cairo_font_face_destroy(m_platformData.fontFace());
+ cairo_scaled_font_destroy(m_platformData.scaledFont());
- DeleteObject(m_font.hfont());
+ DeleteObject(m_platformData.hfont());
platformCommonDestroy();
}
float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
{
- if (m_font.useGDI())
+ if (m_platformData.useGDI())
return widthForGDIGlyph(glyph);
HDC hdc = GetDC(0);
SaveDC(hdc);
- cairo_scaled_font_t* scaledFont = m_font.scaledFont();
+ cairo_scaled_font_t* scaledFont = m_platformData.scaledFont();
cairo_win32_scaled_font_select_font(scaledFont, hdc);
int width;
@@ -118,14 +126,14 @@ float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
RestoreDC(hdc, -1);
ReleaseDC(0, hdc);
- const double metricsMultiplier = cairo_win32_scaled_font_get_metrics_factor(scaledFont) * m_font.size();
+ const double metricsMultiplier = cairo_win32_scaled_font_get_metrics_factor(scaledFont) * m_platformData.size();
return width * metricsMultiplier;
}
void SimpleFontData::setFont(cairo_t* cr) const
{
ASSERT(cr);
- m_font.setFont(cr);
+ m_platformData.setFont(cr);
}
}
diff --git a/WebCore/platform/graphics/win/SimpleFontDataWin.cpp b/WebCore/platform/graphics/win/SimpleFontDataWin.cpp
index 9d5c3b9..9835e9f 100644
--- a/WebCore/platform/graphics/win/SimpleFontDataWin.cpp
+++ b/WebCore/platform/graphics/win/SimpleFontDataWin.cpp
@@ -63,7 +63,7 @@ bool SimpleFontData::shouldApplyMacAscentHack()
void SimpleFontData::initGDIFont()
{
HDC hdc = GetDC(0);
- HGDIOBJ oldFont = SelectObject(hdc, m_font.hfont());
+ HGDIOBJ oldFont = SelectObject(hdc, m_platformData.hfont());
OUTLINETEXTMETRIC metrics;
GetOutlineTextMetrics(hdc, sizeof(metrics), &metrics);
TEXTMETRIC& textMetrics = metrics.otmTextMetrics;
@@ -71,6 +71,8 @@ void SimpleFontData::initGDIFont()
m_descent = textMetrics.tmDescent;
m_lineGap = textMetrics.tmExternalLeading;
m_lineSpacing = m_ascent + m_descent + m_lineGap;
+ m_avgCharWidth = textMetrics.tmAveCharWidth;
+ m_maxCharWidth = textMetrics.tmMaxCharWidth;
m_xHeight = m_ascent * 0.56f; // Best guess for xHeight if no x glyph is present.
GLYPHMETRICS gm;
@@ -100,17 +102,17 @@ void SimpleFontData::platformCommonDestroy()
SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
{
if (!m_smallCapsFontData) {
- float smallCapsHeight = cSmallCapsFontSizeMultiplier * m_font.size();
+ float smallCapsHeight = cSmallCapsFontSizeMultiplier * m_platformData.size();
if (isCustomFont()) {
- FontPlatformData smallCapsFontData(m_font);
+ FontPlatformData smallCapsFontData(m_platformData);
smallCapsFontData.setSize(smallCapsHeight);
m_smallCapsFontData = new SimpleFontData(smallCapsFontData, true, false);
} else {
LOGFONT winfont;
- GetObject(m_font.hfont(), sizeof(LOGFONT), &winfont);
- winfont.lfHeight = -lroundf(smallCapsHeight * (m_font.useGDI() ? 1 : 32));
+ 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_font.syntheticBold(), m_font.syntheticOblique(), m_font.useGDI()));
+ m_smallCapsFontData = new SimpleFontData(FontPlatformData(hfont, smallCapsHeight, m_platformData.syntheticBold(), m_platformData.syntheticOblique(), m_platformData.useGDI()));
}
}
return m_smallCapsFontData;
@@ -135,7 +137,7 @@ bool SimpleFontData::containsCharacters(const UChar* characters, int length) con
langFontLink->CodePageToCodePages(CP_ACP, &acpCodePages);
DWORD fontCodePages;
- langFontLink->GetFontCodePages(dc, m_font.hfont(), &fontCodePages);
+ langFontLink->GetFontCodePages(dc, m_platformData.hfont(), &fontCodePages);
DWORD actualCodePages;
long numCharactersProcessed;
@@ -162,7 +164,7 @@ void SimpleFontData::determinePitch()
// TEXTMETRICS have this. Set m_treatAsFixedPitch based off that.
HDC dc = GetDC(0);
SaveDC(dc);
- SelectObject(dc, m_font.hfont());
+ SelectObject(dc, m_platformData.hfont());
// Yes, this looks backwards, but the fixed pitch bit is actually set if the font
// is *not* fixed pitch. Unbelievable but true.
@@ -178,7 +180,7 @@ float SimpleFontData::widthForGDIGlyph(Glyph glyph) const
{
HDC hdc = GetDC(0);
SetGraphicsMode(hdc, GM_ADVANCED);
- HGDIOBJ oldFont = SelectObject(hdc, m_font.hfont());
+ HGDIOBJ oldFont = SelectObject(hdc, m_platformData.hfont());
int width;
GetCharWidthI(hdc, glyph, 1, 0, &width);
SelectObject(hdc, oldFont);
@@ -196,7 +198,7 @@ SCRIPT_FONTPROPERTIES* SimpleFontData::scriptFontProperties() const
if (result == E_PENDING) {
HDC dc = GetDC(0);
SaveDC(dc);
- SelectObject(dc, m_font.hfont());
+ SelectObject(dc, m_platformData.hfont());
ScriptGetFontProperties(dc, scriptCache(), m_scriptFontProperties);
RestoreDC(dc, -1);
ReleaseDC(0, dc);
diff --git a/WebCore/platform/graphics/win/UniscribeController.cpp b/WebCore/platform/graphics/win/UniscribeController.cpp
index 371bc51..f382857 100644
--- a/WebCore/platform/graphics/win/UniscribeController.cpp
+++ b/WebCore/platform/graphics/win/UniscribeController.cpp
@@ -38,9 +38,10 @@ namespace WebCore {
// that does stuff in that method instead of doing everything in the constructor. Have advance()
// 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)
+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)
@@ -147,6 +148,9 @@ void UniscribeController::advance(unsigned offset, GlyphBuffer* glyphBuffer)
smallCapsBuffer[index] = forceSmallCaps ? c : newC;
}
+ if (m_fallbackFonts && nextFontData != fontData && fontData != m_font.primaryFont())
+ m_fallbackFonts->add(fontData);
+
if (nextFontData != fontData || nextIsSmallCaps != isSmallCaps) {
int itemStart = m_run.rtl() ? index + 1 : indexOfFontTransition;
int itemLength = m_run.rtl() ? indexOfFontTransition - index : index - indexOfFontTransition;
@@ -158,6 +162,9 @@ void UniscribeController::advance(unsigned offset, GlyphBuffer* glyphBuffer)
int itemLength = m_run.rtl() ? indexOfFontTransition + 1 : length - indexOfFontTransition;
if (itemLength) {
+ if (m_fallbackFonts && nextFontData != m_font.primaryFont())
+ m_fallbackFonts->add(nextFontData);
+
int itemStart = m_run.rtl() ? 0 : indexOfFontTransition;
m_currentCharacter = baseCharacter + itemStart;
itemizeShapeAndPlace((nextIsSmallCaps ? smallCapsBuffer.data() : cp) + itemStart, itemLength, nextFontData, glyphBuffer);
@@ -258,16 +265,16 @@ bool UniscribeController::shapeAndPlaceItem(const UChar* cp, unsigned i, const S
Vector<int> roundingHackWordBoundaries(glyphs.size());
roundingHackWordBoundaries.fill(-1);
- const float cLogicalScale = fontData->m_font.useGDI() ? 1.0f : 32.0f;
- unsigned logicalSpaceWidth = fontData->m_spaceWidth * cLogicalScale;
- float roundedSpaceWidth = roundf(fontData->m_spaceWidth);
+ const float cLogicalScale = fontData->platformData().useGDI() ? 1.0f : 32.0f;
+ unsigned logicalSpaceWidth = fontData->spaceWidth() * cLogicalScale;
+ float roundedSpaceWidth = roundf(fontData->spaceWidth());
for (int k = 0; k < len; k++) {
UChar ch = *(str + k);
if (Font::treatAsSpace(ch)) {
// Substitute in the space glyph at the appropriate place in the glyphs
// array.
- glyphs[clusters[k]] = fontData->m_spaceGlyph;
+ glyphs[clusters[k]] = fontData->spaceGlyph();
advances[clusters[k]] = logicalSpaceWidth;
spaceCharacters[clusters[k]] = m_currentCharacter + k + item.iCharPos;
}
@@ -300,15 +307,15 @@ bool UniscribeController::shapeAndPlaceItem(const UChar* cp, unsigned i, const S
offsetY = roundf(offsetY);
}
- advance += fontData->m_syntheticBoldOffset;
+ advance += fontData->syntheticBoldOffset();
// We special case spaces in two ways when applying word rounding.
// First, we round spaces to an adjusted width in all fonts.
// Second, in fixed-pitch fonts we ensure that all glyphs that
// match the width of the space glyph have the same width as the space glyph.
- if (roundedAdvance == roundedSpaceWidth && (fontData->m_treatAsFixedPitch || glyph == fontData->m_spaceGlyph) &&
+ if (roundedAdvance == roundedSpaceWidth && (fontData->pitch() == FixedPitch || glyph == fontData->spaceGlyph()) &&
m_run.applyWordRounding())
- advance = fontData->m_adjustedSpaceWidth;
+ advance = fontData->adjustedSpaceWidth();
if (hasExtraSpacing) {
// If we're a glyph with an advance, go ahead and add in letter-spacing.
@@ -317,7 +324,7 @@ bool UniscribeController::shapeAndPlaceItem(const UChar* cp, unsigned i, const S
advance += m_font.letterSpacing();
// Handle justification and word-spacing.
- if (glyph == fontData->m_spaceGlyph) {
+ if (glyph == fontData->spaceGlyph()) {
// Account for padding. WebCore uses space padding to justify text.
// We distribute the specified padding over the available spaces in the run.
if (m_padding) {
diff --git a/WebCore/platform/graphics/win/UniscribeController.h b/WebCore/platform/graphics/win/UniscribeController.h
index 6ea45e1..23b8108 100644
--- a/WebCore/platform/graphics/win/UniscribeController.h
+++ b/WebCore/platform/graphics/win/UniscribeController.h
@@ -38,7 +38,7 @@ namespace WebCore {
class UniscribeController {
public:
- UniscribeController(const Font*, const TextRun&);
+ UniscribeController(const Font*, const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0);
// Advance and measure/place up to the specified character.
void advance(unsigned to, GlyphBuffer* = 0);
@@ -60,6 +60,7 @@ private:
const Font& m_font;
const TextRun& m_run;
+ HashSet<const SimpleFontData*>* m_fallbackFonts;
SCRIPT_CONTROL m_control;
SCRIPT_STATE m_state;
diff --git a/WebCore/platform/graphics/wx/FontWx.cpp b/WebCore/platform/graphics/wx/FontWx.cpp
index 07223e9..04b2ec4 100644
--- a/WebCore/platform/graphics/wx/FontWx.cpp
+++ b/WebCore/platform/graphics/wx/FontWx.cpp
@@ -39,6 +39,11 @@
namespace WebCore {
+bool Font::canReturnFallbackFontsForComplexText()
+{
+ return false;
+}
+
void Font::drawGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* font, const GlyphBuffer& glyphBuffer,
int from, int numGlyphs, const FloatPoint& point) const
{
@@ -63,7 +68,7 @@ void Font::drawComplexText(GraphicsContext* graphicsContext, const TextRun& run,
notImplemented();
}
-float Font::floatWidthForComplexText(const TextRun& run) const
+float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* /* fallbackFonts */) const
{
notImplemented();
return 0;
diff --git a/WebCore/platform/graphics/wx/ImageSourceWx.cpp b/WebCore/platform/graphics/wx/ImageSourceWx.cpp
index fc8ce71..2f71d62 100644
--- a/WebCore/platform/graphics/wx/ImageSourceWx.cpp
+++ b/WebCore/platform/graphics/wx/ImageSourceWx.cpp
@@ -37,6 +37,9 @@
#include <wx/defs.h>
#include <wx/bitmap.h>
+#if USE(WXGC)
+#include <wx/graphics.h>
+#endif
#include <wx/image.h>
#include <wx/rawbmp.h>
@@ -224,7 +227,14 @@ NativeImagePtr ImageSource::createFrameAtIndex(size_t index)
bmp->UseAlpha();
#endif
ASSERT(bmp->IsOk());
+
+#if USE(WXGC)
+ wxGraphicsBitmap* bitmap = new wxGraphicsBitmap(wxGraphicsRenderer::GetDefaultRenderer()->CreateBitmap(*bmp));
+ delete bmp;
+ return bitmap;
+#else
return bmp;
+#endif
}
float ImageSource::frameDurationAtIndex(size_t index)
diff --git a/WebCore/platform/graphics/wx/ImageWx.cpp b/WebCore/platform/graphics/wx/ImageWx.cpp
index e1d435e..b0a993e 100644
--- a/WebCore/platform/graphics/wx/ImageWx.cpp
+++ b/WebCore/platform/graphics/wx/ImageWx.cpp
@@ -26,11 +26,12 @@
#include "config.h"
#include "Image.h"
-#include "TransformationMatrix.h"
#include "BitmapImage.h"
+#include "FloatConversion.h"
#include "FloatRect.h"
#include "GraphicsContext.h"
-#include "NotImplemented.h"
+#include "ImageObserver.h"
+#include "TransformationMatrix.h"
#include <math.h>
#include <stdio.h>
@@ -98,13 +99,13 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst, const FloatR
#if USE(WXGC)
wxGCDC* context = (wxGCDC*)ctxt->platformContext();
wxGraphicsContext* gc = context->GetGraphicsContext();
+ wxGraphicsBitmap* bitmap = frameAtIndex(m_currentFrame);
#else
wxWindowDC* context = ctxt->platformContext();
+ wxBitmap* bitmap = frameAtIndex(m_currentFrame);
#endif
startAnimation();
-
- wxBitmap* bitmap = frameAtIndex(m_currentFrame);
if (!bitmap) // If it's too early we won't have an image yet.
return;
@@ -129,17 +130,15 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst, const FloatR
adjustedDestRect.setLocation(FloatPoint(dst.x() - src.x() / scaleX, dst.y() - src.y() / scaleY));
adjustedDestRect.setSize(FloatSize(selfSize.width() / scaleX, selfSize.height() / scaleY));
}
-
- // If the image is only partially loaded, then shrink the destination rect that we're drawing into accordingly.
- int currHeight = bitmap->GetHeight();
- if (currHeight < selfSize.height())
- adjustedDestRect.setHeight(adjustedDestRect.height() * currHeight / selfSize.height());
- gc->PushState();
gc->Clip(dst.x(), dst.y(), dst.width(), dst.height());
+#if wxCHECK_VERSION(2,9,0)
gc->DrawBitmap(*bitmap, adjustedDestRect.x(), adjustedDestRect.y(), adjustedDestRect.width(), adjustedDestRect.height());
- gc->PopState();
#else
+ gc->DrawGraphicsBitmap(*bitmap, adjustedDestRect.x(), adjustedDestRect.y(), adjustedDestRect.width(), adjustedDestRect.height());
+#endif
+
+#else // USE(WXGC)
IntRect srcIntRect(src);
IntRect dstIntRect(dst);
bool rescaling = false;
@@ -172,6 +171,9 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst, const FloatR
#endif
ctxt->restore();
+
+ if (ImageObserver* observer = imageObserver())
+ observer->didDraw(this);
}
void BitmapImage::drawPattern(GraphicsContext* ctxt, const FloatRect& srcRect, const TransformationMatrix& patternTransform, const FloatPoint& phase, CompositeOperator, const FloatRect& dstRect)
@@ -181,21 +183,29 @@ void BitmapImage::drawPattern(GraphicsContext* ctxt, const FloatRect& srcRect, c
#if USE(WXGC)
wxGCDC* context = (wxGCDC*)ctxt->platformContext();
+ wxGraphicsBitmap* bitmap = frameAtIndex(m_currentFrame);
#else
wxWindowDC* context = ctxt->platformContext();
+ wxBitmap* bitmap = frameAtIndex(m_currentFrame);
#endif
- ctxt->save();
- ctxt->clip(IntRect(dstRect.x(), dstRect.y(), dstRect.width(), dstRect.height()));
- wxBitmap* bitmap = frameAtIndex(m_currentFrame);
if (!bitmap) // If it's too early we won't have an image yet.
return;
+
+ ctxt->save();
+ ctxt->clip(IntRect(dstRect.x(), dstRect.y(), dstRect.width(), dstRect.height()));
float currentW = 0;
float currentH = 0;
#if USE(WXGC)
wxGraphicsContext* gc = context->GetGraphicsContext();
+
+ float adjustedX = phase.x() + srcRect.x() *
+ narrowPrecisionToFloat(patternTransform.a());
+ float adjustedY = phase.y() + srcRect.y() *
+ narrowPrecisionToFloat(patternTransform.d());
+
gc->ConcatTransform(patternTransform);
#else
wxMemoryDC mydc;
@@ -208,7 +218,11 @@ void BitmapImage::drawPattern(GraphicsContext* ctxt, const FloatRect& srcRect, c
while ( currentW < dstRect.width() && currentW < clientSize.x - origin.x ) {
while ( currentH < dstRect.height() && currentH < clientSize.y - origin.y) {
#if USE(WXGC)
- gc->DrawBitmap(*bitmap, (wxDouble)dstRect.x() + currentW, (wxDouble)dstRect.y() + currentH, (wxDouble)srcRect.width(), (wxDouble)srcRect.height());
+#if wxCHECK_VERSION(2,9,0)
+ gc->DrawBitmap(*bitmap, adjustedX + currentW, adjustedY + currentH, (wxDouble)srcRect.width(), (wxDouble)srcRect.height());
+#else
+ gc->DrawGraphicsBitmap(*bitmap, adjustedX + currentW, adjustedY + currentH, (wxDouble)srcRect.width(), (wxDouble)srcRect.height());
+#endif
#else
context->Blit((wxCoord)dstRect.x() + currentW, (wxCoord)dstRect.y() + currentH,
(wxCoord)srcRect.width(), (wxCoord)srcRect.height(), &mydc,
@@ -233,6 +247,8 @@ void BitmapImage::drawPattern(GraphicsContext* ctxt, const FloatRect& srcRect, c
startAnimation();
+ if (ImageObserver* observer = imageObserver())
+ observer->didDraw(this);
}
void BitmapImage::checkForSolidColor()
diff --git a/WebCore/platform/graphics/wx/PathWx.cpp b/WebCore/platform/graphics/wx/PathWx.cpp
index 60c71d5..04a952d 100644
--- a/WebCore/platform/graphics/wx/PathWx.cpp
+++ b/WebCore/platform/graphics/wx/PathWx.cpp
@@ -66,11 +66,12 @@ Path::Path()
Path::~Path()
{
+ clear();
}
Path::Path(const Path& path)
{
- m_path = (PlatformPath*)&path.m_path;
+ m_path = new wxGraphicsPath(*path.m_path);
}
bool Path::contains(const FloatPoint& point, const WindRule rule) const
@@ -89,7 +90,7 @@ bool Path::contains(const FloatPoint& point, const WindRule rule) const
void Path::translate(const FloatSize&)
{
- notImplemented();
+ notImplemented();
}
FloatRect Path::boundingRect() const
diff --git a/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp b/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp
index ab50518..2368f83 100644
--- a/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp
+++ b/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp
@@ -45,7 +45,7 @@ namespace WebCore
void SimpleFontData::platformInit()
{
- wxFont *font = m_font.font();
+ wxFont *font = m_platformData.font();
if (font && font->IsOk()) {
wxFontProperties props = wxFontProperties(font);
m_ascent = props.GetAscent();
@@ -57,6 +57,13 @@ void SimpleFontData::platformInit()
}
}
+void SimpleFontData::platformCharWidthInit()
+{
+ m_avgCharWidth = 0.f;
+ m_maxCharWidth = 0.f;
+ initCharWidths();
+}
+
void SimpleFontData::platformDestroy()
{
delete m_smallCapsFontData;
@@ -81,8 +88,8 @@ bool SimpleFontData::containsCharacters(const UChar* characters, int length) con
void SimpleFontData::determinePitch()
{
- if (m_font.font() && m_font.font()->Ok())
- m_treatAsFixedPitch = m_font.font()->IsFixedWidth();
+ if (m_platformData.font() && m_platformData.font()->Ok())
+ m_treatAsFixedPitch = m_platformData.font()->IsFixedWidth();
else
m_treatAsFixedPitch = false;
}
@@ -91,7 +98,7 @@ float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
{
// TODO: fix this! Make GetTextExtents a method of wxFont in 2.9
int width = 10;
- GetTextExtent(*m_font.font(), (wxChar)glyph, &width, NULL);
+ GetTextExtent(*m_platformData.font(), (wxChar)glyph, &width, NULL);
return width;
}
diff --git a/WebCore/platform/graphics/wx/TransformationMatrixWx.cpp b/WebCore/platform/graphics/wx/TransformationMatrixWx.cpp
index f21dc17..9684a3c 100644
--- a/WebCore/platform/graphics/wx/TransformationMatrixWx.cpp
+++ b/WebCore/platform/graphics/wx/TransformationMatrixWx.cpp
@@ -26,9 +26,9 @@
#include "config.h"
#include "TransformationMatrix.h"
+#include "Assertions.h"
#include "FloatRect.h"
#include "IntRect.h"
-#include "NotImplemented.h"
#include <stdio.h>
#include <wx/defs.h>