summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/graphics/mac
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/platform/graphics/mac')
-rw-r--r--Source/WebCore/platform/graphics/mac/ComplexTextController.cpp24
-rw-r--r--Source/WebCore/platform/graphics/mac/ComplexTextController.h1
-rw-r--r--Source/WebCore/platform/graphics/mac/ComplexTextControllerATSUI.cpp2
-rw-r--r--Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.cpp6
-rw-r--r--Source/WebCore/platform/graphics/mac/FontCacheMac.mm2
-rw-r--r--Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp4
-rw-r--r--Source/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp4
-rw-r--r--Source/WebCore/platform/graphics/mac/FontCustomPlatformData.h3
-rw-r--r--Source/WebCore/platform/graphics/mac/FontMac.mm86
-rw-r--r--Source/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp4
-rw-r--r--Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm12
-rw-r--r--Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h6
-rw-r--r--Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm88
-rw-r--r--Source/WebCore/platform/graphics/mac/SimpleFontDataCoreText.cpp10
-rw-r--r--Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm56
-rw-r--r--Source/WebCore/platform/graphics/mac/WebLayer.h3
-rw-r--r--Source/WebCore/platform/graphics/mac/WebLayer.mm6
-rw-r--r--Source/WebCore/platform/graphics/mac/WebTiledLayer.mm2
18 files changed, 213 insertions, 106 deletions
diff --git a/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp b/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp
index 1a56664..07bc3ec 100644
--- a/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp
+++ b/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp
@@ -63,7 +63,8 @@ ComplexTextController::ComplexTextController(const Font* font, const TextRun& ru
, m_glyphInCurrentRun(0)
, m_characterInCurrentGlyph(0)
, m_expansion(run.expansion())
- , m_afterExpansion(true)
+ , m_leadingExpansion(0)
+ , m_afterExpansion(!run.allowsLeadingExpansion())
, m_fallbackFonts(fallbackFonts)
, m_minGlyphBoundingBoxX(numeric_limits<float>::max())
, m_maxGlyphBoundingBoxX(numeric_limits<float>::min())
@@ -73,7 +74,7 @@ ComplexTextController::ComplexTextController(const Font* font, const TextRun& ru
if (!m_expansion)
m_expansionPerOpportunity = 0;
else {
- bool isAfterExpansion = true;
+ bool isAfterExpansion = m_afterExpansion;
unsigned expansionOpportunityCount = Font::expansionOpportunityCount(m_run.characters(), m_end, m_run.ltr() ? LTR : RTL, isAfterExpansion);
if (isAfterExpansion && !m_run.allowsTrailingExpansion())
expansionOpportunityCount--;
@@ -86,12 +87,16 @@ ComplexTextController::ComplexTextController(const Font* font, const TextRun& ru
collectComplexTextRuns();
adjustGlyphsAndAdvances();
+
+ m_runWidthSoFar = m_leadingExpansion;
}
int ComplexTextController::offsetForPosition(float h, bool includePartialGlyphs)
{
if (h >= m_totalWidth)
return m_run.ltr() ? m_end : 0;
+
+ h -= m_leadingExpansion;
if (h < 0)
return m_run.ltr() ? 0 : m_end;
@@ -472,16 +477,21 @@ void ComplexTextController::adjustGlyphsAndAdvances()
// Handle justification and word-spacing.
if (treatAsSpace || Font::isCJKIdeographOrSymbol(ch)) {
// Distribute the run's total expansion evenly over all expansion opportunities in the run.
- if (m_expansion && (!lastGlyph || m_run.allowsTrailingExpansion())) {
+ if (m_expansion) {
if (!treatAsSpace && !m_afterExpansion) {
// Take the expansion opportunity before this ideograph.
m_expansion -= m_expansionPerOpportunity;
m_totalWidth += m_expansionPerOpportunity;
- m_adjustedAdvances.last().width += m_expansionPerOpportunity;
+ if (m_adjustedAdvances.isEmpty())
+ m_leadingExpansion = m_expansionPerOpportunity;
+ else
+ m_adjustedAdvances.last().width += m_expansionPerOpportunity;
+ }
+ if (!lastGlyph || m_run.allowsTrailingExpansion()) {
+ m_expansion -= m_expansionPerOpportunity;
+ advance.width += m_expansionPerOpportunity;
+ m_afterExpansion = true;
}
- m_expansion -= m_expansionPerOpportunity;
- advance.width += m_expansionPerOpportunity;
- m_afterExpansion = true;
} else
m_afterExpansion = false;
diff --git a/Source/WebCore/platform/graphics/mac/ComplexTextController.h b/Source/WebCore/platform/graphics/mac/ComplexTextController.h
index 7373bfe..44a7994 100644
--- a/Source/WebCore/platform/graphics/mac/ComplexTextController.h
+++ b/Source/WebCore/platform/graphics/mac/ComplexTextController.h
@@ -175,6 +175,7 @@ private:
unsigned m_characterInCurrentGlyph;
float m_expansion;
float m_expansionPerOpportunity;
+ float m_leadingExpansion;
bool m_afterExpansion;
HashSet<const SimpleFontData*>* m_fallbackFonts;
diff --git a/Source/WebCore/platform/graphics/mac/ComplexTextControllerATSUI.cpp b/Source/WebCore/platform/graphics/mac/ComplexTextControllerATSUI.cpp
index b367fdf..d965ada 100644
--- a/Source/WebCore/platform/graphics/mac/ComplexTextControllerATSUI.cpp
+++ b/Source/WebCore/platform/graphics/mac/ComplexTextControllerATSUI.cpp
@@ -264,7 +264,7 @@ static void disableLigatures(const SimpleFontData* fontData, ATSUStyle atsuStyle
// Don't be too aggressive: if the font doesn't contain 'a', then assume that any ligatures it contains are
// in characters that always go through ATSUI, and therefore allow them. Geeza Pro is an example.
// See bugzilla 5166.
- if ((typesettingFeatures & Ligatures) || (fontData->orientation() == Horizontal && fontData->platformData().allowsLigatures()))
+ if ((typesettingFeatures & Ligatures) || (fontData->platformData().orientation() == Horizontal && fontData->platformData().allowsLigatures()))
return;
ATSUFontFeatureType featureTypes[] = { kLigaturesType };
diff --git a/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.cpp b/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.cpp
index 239113f..d2fbaf5 100644
--- a/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.cpp
+++ b/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.cpp
@@ -144,17 +144,17 @@ void ComplexTextController::collectComplexTextRunsForCharactersCoreText(const UC
static CFDictionaryRef rtlTypesetterOptions = CFDictionaryCreate(kCFAllocatorDefault, optionKeys, rtlOptionValues, WTF_ARRAY_LENGTH(optionKeys), &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
- ProviderInfo info = { cp, length, fontData->getCFStringAttributes(m_font.typesettingFeatures()) };
+ ProviderInfo info = { cp, length, fontData->getCFStringAttributes(m_font.typesettingFeatures(), fontData->platformData().orientation()) };
RetainPtr<CTTypesetterRef> typesetter(AdoptCF, wkCreateCTTypesetterWithUniCharProviderAndOptions(&provideStringAndAttributes, 0, &info, m_run.ltr() ? ltrTypesetterOptions : rtlTypesetterOptions));
#else
RetainPtr<CFStringRef> string(AdoptCF, CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault, cp, length, kCFAllocatorNull));
- RetainPtr<CFAttributedStringRef> attributedString(AdoptCF, CFAttributedStringCreate(kCFAllocatorDefault, string.get(), fontData->getCFStringAttributes(m_font.typesettingFeatures())));
+ RetainPtr<CFAttributedStringRef> attributedString(AdoptCF, CFAttributedStringCreate(kCFAllocatorDefault, string.get(), fontData->getCFStringAttributes(m_font.typesettingFeatures(), fontData->platformData().orientation())));
RetainPtr<CTTypesetterRef> typesetter(AdoptCF, CTTypesetterCreateWithAttributedStringAndOptions(attributedString.get(), m_run.ltr() ? ltrTypesetterOptions : rtlTypesetterOptions));
#endif
line.adoptCF(CTTypesetterCreateLine(typesetter.get(), CFRangeMake(0, 0)));
} else {
- ProviderInfo info = { cp, length, fontData->getCFStringAttributes(m_font.typesettingFeatures()) };
+ ProviderInfo info = { cp, length, fontData->getCFStringAttributes(m_font.typesettingFeatures(), fontData->platformData().orientation()) };
line.adoptCF(wkCreateCTLineWithUniCharProvider(&provideStringAndAttributes, 0, &info));
}
diff --git a/Source/WebCore/platform/graphics/mac/FontCacheMac.mm b/Source/WebCore/platform/graphics/mac/FontCacheMac.mm
index c254906..f7ae6b7 100644
--- a/Source/WebCore/platform/graphics/mac/FontCacheMac.mm
+++ b/Source/WebCore/platform/graphics/mac/FontCacheMac.mm
@@ -211,7 +211,7 @@ FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontD
bool syntheticBold = isAppKitFontWeightBold(weight) && !isAppKitFontWeightBold(actualWeight);
bool syntheticOblique = (traits & NSFontItalicTrait) && !(actualTraits & NSFontItalicTrait);
- return new FontPlatformData(platformFont, size, syntheticBold, syntheticOblique, fontDescription.orientation(), fontDescription.widthVariant());
+ return new FontPlatformData(platformFont, size, syntheticBold, syntheticOblique, fontDescription.orientation(), fontDescription.textOrientation(), fontDescription.widthVariant());
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp b/Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp
index eed49a5..fe2a22c 100644
--- a/Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp
+++ b/Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp
@@ -111,8 +111,8 @@ float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFon
{
ComplexTextController controller(this, run, true, fallbackFonts);
if (glyphOverflow) {
- glyphOverflow->top = max<int>(glyphOverflow->top, ceilf(-controller.minGlyphBoundingBoxY()) - fontMetrics().ascent());
- glyphOverflow->bottom = max<int>(glyphOverflow->bottom, ceilf(controller.maxGlyphBoundingBoxY()) - fontMetrics().descent());
+ glyphOverflow->top = max<int>(glyphOverflow->top, ceilf(-controller.minGlyphBoundingBoxY()) - (glyphOverflow->computeBounds ? 0 : fontMetrics().ascent()));
+ glyphOverflow->bottom = max<int>(glyphOverflow->bottom, ceilf(controller.maxGlyphBoundingBoxY()) - (glyphOverflow->computeBounds ? 0 : fontMetrics().descent()));
glyphOverflow->left = max<int>(0, ceilf(-controller.minGlyphBoundingBoxX()));
glyphOverflow->right = max<int>(0, ceilf(controller.maxGlyphBoundingBoxX() - controller.totalWidth()));
}
diff --git a/Source/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp b/Source/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp
index f2bc33d..383adef 100644
--- a/Source/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp
+++ b/Source/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp
@@ -38,9 +38,9 @@ FontCustomPlatformData::~FontCustomPlatformData()
CGFontRelease(m_cgFont);
}
-FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation orientation, FontWidthVariant widthVariant, FontRenderingMode)
+FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation orientation, TextOrientation textOrientation, FontWidthVariant widthVariant, FontRenderingMode)
{
- return FontPlatformData(m_cgFont, size, bold, italic, orientation, widthVariant);
+ return FontPlatformData(m_cgFont, size, bold, italic, orientation, textOrientation, widthVariant);
}
FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
diff --git a/Source/WebCore/platform/graphics/mac/FontCustomPlatformData.h b/Source/WebCore/platform/graphics/mac/FontCustomPlatformData.h
index c7ae1ca..c625304 100644
--- a/Source/WebCore/platform/graphics/mac/FontCustomPlatformData.h
+++ b/Source/WebCore/platform/graphics/mac/FontCustomPlatformData.h
@@ -24,6 +24,7 @@
#include "FontOrientation.h"
#include "FontRenderingMode.h"
#include "FontWidthVariant.h"
+#include "TextOrientation.h"
#include <CoreFoundation/CFBase.h>
#include <wtf/Forward.h>
#include <wtf/Noncopyable.h>
@@ -48,7 +49,7 @@ public:
~FontCustomPlatformData();
- FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, FontWidthVariant = RegularWidth, FontRenderingMode = NormalRenderingMode);
+ FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontOrientation = Horizontal, TextOrientation = TextOrientationVerticalRight, FontWidthVariant = RegularWidth, FontRenderingMode = NormalRenderingMode);
static bool supportsFormat(const String&);
diff --git a/Source/WebCore/platform/graphics/mac/FontMac.mm b/Source/WebCore/platform/graphics/mac/FontMac.mm
index acd7562..4c28ead 100644
--- a/Source/WebCore/platform/graphics/mac/FontMac.mm
+++ b/Source/WebCore/platform/graphics/mac/FontMac.mm
@@ -52,28 +52,72 @@ bool Font::canExpandAroundIdeographsInComplexText()
return true;
}
-static void showGlyphsWithAdvances(const SimpleFontData* font, CGContextRef context, const CGGlyph* glyphs, const CGSize* advances, size_t count)
+// CTFontGetVerticalTranslationsForGlyphs is different on Snow Leopard. It returns values for a font-size of 1
+// without unitsPerEm applied. We have to apply a transform that scales up to the point size and that also
+// divides by unitsPerEm.
+static bool hasBrokenCTFontGetVerticalTranslationsForGlyphs()
{
+// Chromium runs the same binary on both Leopard and Snow Leopard, so the check has to happen at runtime.
+#if PLATFORM(CHROMIUM)
+ static bool isCached = false;
+ static bool result;
+
+ if (!isCached) {
+ SInt32 majorVersion = 0;
+ SInt32 minorVersion = 0;
+ Gestalt(gestaltSystemVersionMajor, &majorVersion);
+ Gestalt(gestaltSystemVersionMinor, &minorVersion);
+ result = majorVersion == 10 && minorVersion == 6;
+ isCached = true;
+ }
+ return result;
+#elif defined(BUILDING_ON_SNOW_LEOPARD)
+ return true;
+#else
+ return false;
+#endif
+}
+
+static void showGlyphsWithAdvances(const FloatPoint& point, const SimpleFontData* font, CGContextRef context, const CGGlyph* glyphs, const CGSize* advances, size_t count)
+{
+ CGContextSetTextPosition(context, point.x(), point.y());
+
const FontPlatformData& platformData = font->platformData();
if (!platformData.isColorBitmapFont()) {
CGAffineTransform savedMatrix;
- bool isVertical = font->orientation() == Vertical;
-
+ bool isVertical = font->platformData().orientation() == Vertical;
if (isVertical) {
CGAffineTransform rotateLeftTransform = CGAffineTransformMake(0, -1, 1, 0, 0, 0);
-
savedMatrix = CGContextGetTextMatrix(context);
CGAffineTransform runMatrix = CGAffineTransformConcat(savedMatrix, rotateLeftTransform);
- // Move start point to put glyphs into original region.
- runMatrix.tx = savedMatrix.tx + font->fontMetrics().ascent();
- runMatrix.ty = savedMatrix.ty + font->fontMetrics().descent();
CGContextSetTextMatrix(context, runMatrix);
- }
-
- CGContextShowGlyphsWithAdvances(context, glyphs, advances, count);
-
- if (isVertical)
+
+ CGAffineTransform translationsTransform;
+ if (hasBrokenCTFontGetVerticalTranslationsForGlyphs()) {
+ translationsTransform = CGAffineTransformMake(platformData.m_size, 0, 0, platformData.m_size, 0, 0);
+ translationsTransform = CGAffineTransformConcat(translationsTransform, rotateLeftTransform);
+ CGFloat unitsPerEm = CGFontGetUnitsPerEm(platformData.cgFont());
+ translationsTransform = CGAffineTransformConcat(translationsTransform, CGAffineTransformMakeScale(1 / unitsPerEm, 1 / unitsPerEm));
+ } else {
+ translationsTransform = rotateLeftTransform;
+ }
+ Vector<CGSize, 256> translations(count);
+ CTFontGetVerticalTranslationsForGlyphs(platformData.ctFont(), glyphs, translations.data(), count);
+
+ CGAffineTransform transform = CGAffineTransformInvert(CGContextGetTextMatrix(context));
+
+ CGPoint position = FloatPoint(point.x(), point.y() + font->fontMetrics().floatAscent(IdeographicBaseline) - font->fontMetrics().floatAscent());
+ Vector<CGPoint, 256> positions(count);
+ for (size_t i = 0; i < count; ++i) {
+ CGSize translation = CGSizeApplyAffineTransform(translations[i], translationsTransform);
+ positions[i] = CGPointApplyAffineTransform(CGPointMake(position.x - translation.width, position.y + translation.height), transform);
+ position.x += advances[i].width;
+ position.y += advances[i].height;
+ }
+ CGContextShowGlyphsAtPositions(context, glyphs, positions.data(), count);
CGContextSetTextMatrix(context, savedMatrix);
+ } else
+ CGContextShowGlyphsWithAdvances(context, glyphs, advances, count);
}
#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
else {
@@ -188,21 +232,15 @@ void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, cons
float shadowTextX = point.x() + shadowOffset.width();
// If shadows are ignoring transforms, then we haven't applied the Y coordinate flip yet, so down is negative.
float shadowTextY = point.y() + shadowOffset.height() * (context->shadowsIgnoreTransforms() ? -1 : 1);
- CGContextSetTextPosition(cgContext, shadowTextX, shadowTextY);
- showGlyphsWithAdvances(font, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
- if (font->syntheticBoldOffset()) {
- CGContextSetTextPosition(cgContext, shadowTextX + font->syntheticBoldOffset(), shadowTextY);
- showGlyphsWithAdvances(font, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
- }
+ showGlyphsWithAdvances(FloatPoint(shadowTextX, shadowTextY), font, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
+ if (font->syntheticBoldOffset())
+ showGlyphsWithAdvances(FloatPoint(shadowTextX + font->syntheticBoldOffset(), shadowTextY), font, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
context->setFillColor(fillColor, fillColorSpace);
}
- CGContextSetTextPosition(cgContext, point.x(), point.y());
- showGlyphsWithAdvances(font, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
- if (font->syntheticBoldOffset()) {
- CGContextSetTextPosition(cgContext, point.x() + font->syntheticBoldOffset(), point.y());
- showGlyphsWithAdvances(font, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
- }
+ showGlyphsWithAdvances(point, font, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
+ if (font->syntheticBoldOffset())
+ showGlyphsWithAdvances(FloatPoint(point.x() + font->syntheticBoldOffset(), point.y()), font, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
if (hasSimpleShadow)
context->setShadow(shadowOffset, shadowBlur, shadowColor, shadowColorSpace);
diff --git a/Source/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp b/Source/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp
index fe2b33a..18d0dc5 100644
--- a/Source/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp
+++ b/Source/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp
@@ -39,7 +39,7 @@ namespace WebCore {
#ifndef BUILDING_ON_TIGER
static bool shouldUseCoreText(UChar* buffer, unsigned bufferLength, const SimpleFontData* fontData)
{
- if (fontData->platformData().widthVariant() != RegularWidth || (fontData->orientation() == Vertical && !fontData->isBrokenIdeographFont())) {
+ if (fontData->platformData().widthVariant() != RegularWidth || fontData->hasVerticalGlyphs()) {
// Ideographs don't have a vertical variant or width variants.
for (unsigned i = 0; i < bufferLength; ++i) {
if (!Font::isCJKIdeograph(buffer[i]))
@@ -70,7 +70,7 @@ bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned b
} else {
// We ask CoreText for possible vertical variant glyphs
RetainPtr<CFStringRef> string(AdoptCF, CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault, buffer, bufferLength, kCFAllocatorNull));
- RetainPtr<CFAttributedStringRef> attributedString(AdoptCF, CFAttributedStringCreate(kCFAllocatorDefault, string.get(), fontData->getCFStringAttributes(0)));
+ RetainPtr<CFAttributedStringRef> attributedString(AdoptCF, CFAttributedStringCreate(kCFAllocatorDefault, string.get(), fontData->getCFStringAttributes(0, fontData->hasVerticalGlyphs() ? Vertical : Horizontal)));
RetainPtr<CTLineRef> line(AdoptCF, CTLineCreateWithAttributedString(attributedString.get()));
CFArrayRef runArray = CTLineGetGlyphRuns(line.get());
diff --git a/Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm b/Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm
index aaa250b..997c976 100644
--- a/Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm
+++ b/Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm
@@ -93,9 +93,14 @@ GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs, HostWi
, m_attrs(attrs)
, m_contextObj(0)
, m_texture(0)
+ , m_compositorTexture(0)
, m_fbo(0)
, m_depthStencilBuffer(0)
+ , m_layerComposited(false)
+ , m_internalColorFormat(0)
, m_boundFBO(0)
+ , m_activeTexture(0)
+ , m_boundTexture0(0)
, m_multisampleFBO(0)
, m_multisampleDepthStencilBuffer(0)
, m_multisampleColorBuffer(0)
@@ -166,6 +171,12 @@ GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs, HostWi
::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ ::glGenTextures(1, &m_compositorTexture);
+ ::glBindTexture(GL_TEXTURE_2D, m_compositorTexture);
+ ::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ ::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
::glBindTexture(GL_TEXTURE_2D, 0);
// create an FBO
@@ -215,6 +226,7 @@ GraphicsContext3D::~GraphicsContext3D()
if (m_contextObj) {
CGLSetCurrentContext(m_contextObj);
::glDeleteTextures(1, &m_texture);
+ ::glDeleteTextures(1, &m_compositorTexture);
if (m_attrs.antialias) {
::glDeleteRenderbuffersEXT(1, &m_multisampleColorBuffer);
if (m_attrs.stencil || m_attrs.depth)
diff --git a/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h b/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h
index 80bc94e..7bdc064 100644
--- a/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h
+++ b/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h
@@ -54,6 +54,8 @@ class WebCoreMovieObserver;
#endif
namespace WebCore {
+
+class ApplicationCacheResource;
class MediaPlayerPrivateQTKit : public MediaPlayerPrivateInterface {
public:
@@ -139,6 +141,7 @@ private:
void createQTMovie(const String& url);
void createQTMovie(NSURL *, NSDictionary *movieAttributes);
+ void createQTMovie(ApplicationCacheResource*);
enum MediaRenderingMode { MediaRenderingNone, MediaRenderingMovieView, MediaRenderingSoftwareRenderer, MediaRenderingMovieLayer };
MediaRenderingMode currentRenderingMode() const;
@@ -178,6 +181,8 @@ private:
virtual double maximumDurationToCacheMediaTime() const { return 5; }
virtual void setPrivateBrowsingMode(bool);
+
+ NSMutableDictionary* commonMovieAttributes();
MediaPlayer* m_player;
RetainPtr<QTMovie> m_qtMovie;
@@ -211,6 +216,7 @@ private:
double m_timeStartedPlaying;
double m_timeStoppedPlaying;
#endif
+ mutable FloatSize m_cachedNaturalSize;
};
}
diff --git a/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm b/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
index ecb7d9f..400fdfb 100644
--- a/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
+++ b/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
@@ -29,11 +29,18 @@
#import "MediaPlayerPrivateQTKit.h"
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+#include "ApplicationCacheHost.h"
+#include "ApplicationCacheResource.h"
+#include "DocumentLoader.h"
+#endif
+
#ifdef BUILDING_ON_TIGER
#import "AutodrainedPool.h"
#endif
#import "BlockExceptions.h"
+#import "DocumentLoader.h"
#import "FrameView.h"
#import "GraphicsContext.h"
#import "KURL.h"
@@ -83,6 +90,7 @@ SOFT_LINK_POINTER(QTKit, QTMediaTypeText, NSString *)
SOFT_LINK_POINTER(QTKit, QTMediaTypeVideo, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieAskUnresolvedDataRefsAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieLoopsAttribute, NSString *)
+SOFT_LINK_POINTER(QTKit, QTMovieDataAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieDataSizeAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieDidEndNotification, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieHasVideoAttribute, NSString *)
@@ -120,6 +128,7 @@ SOFT_LINK_POINTER(QTKit, QTMovieApertureModeAttribute, NSString *)
#define QTMediaTypeVideo getQTMediaTypeVideo()
#define QTMovieAskUnresolvedDataRefsAttribute getQTMovieAskUnresolvedDataRefsAttribute()
#define QTMovieLoopsAttribute getQTMovieLoopsAttribute()
+#define QTMovieDataAttribute getQTMovieDataAttribute()
#define QTMovieDataSizeAttribute getQTMovieDataSizeAttribute()
#define QTMovieDidEndNotification getQTMovieDidEndNotification()
#define QTMovieHasVideoAttribute getQTMovieHasVideoAttribute()
@@ -241,21 +250,26 @@ MediaPlayerPrivateQTKit::~MediaPlayerPrivateQTKit()
[m_objcObserver.get() disconnect];
}
-void MediaPlayerPrivateQTKit::createQTMovie(const String& url)
+NSMutableDictionary* MediaPlayerPrivateQTKit::commonMovieAttributes()
{
- NSURL *cocoaURL = KURL(ParsedURLString, url);
- NSMutableDictionary *movieAttributes = [NSMutableDictionary dictionaryWithObjectsAndKeys:
- cocoaURL, QTMovieURLAttribute,
- [NSNumber numberWithBool:m_player->preservesPitch()], QTMovieRateChangesPreservePitchAttribute,
- [NSNumber numberWithBool:YES], QTMoviePreventExternalURLLinksAttribute,
- [NSNumber numberWithBool:YES], QTSecurityPolicyNoCrossSiteAttribute,
- [NSNumber numberWithBool:NO], QTMovieAskUnresolvedDataRefsAttribute,
- [NSNumber numberWithBool:NO], QTMovieLoopsAttribute,
- [NSNumber numberWithBool:!m_privateBrowsing], @"QTMovieAllowPersistentCacheAttribute",
+ return [NSMutableDictionary dictionaryWithObjectsAndKeys:
+ [NSNumber numberWithBool:m_player->preservesPitch()], QTMovieRateChangesPreservePitchAttribute,
+ [NSNumber numberWithBool:YES], QTMoviePreventExternalURLLinksAttribute,
+ [NSNumber numberWithBool:YES], QTSecurityPolicyNoCrossSiteAttribute,
+ [NSNumber numberWithBool:NO], QTMovieAskUnresolvedDataRefsAttribute,
+ [NSNumber numberWithBool:NO], QTMovieLoopsAttribute,
+ [NSNumber numberWithBool:!m_privateBrowsing], @"QTMovieAllowPersistentCacheAttribute",
#ifndef BUILDING_ON_TIGER
- QTMovieApertureModeClean, QTMovieApertureModeAttribute,
+ QTMovieApertureModeClean, QTMovieApertureModeAttribute,
#endif
- nil];
+ nil];
+}
+
+void MediaPlayerPrivateQTKit::createQTMovie(const String& url)
+{
+ NSURL *cocoaURL = KURL(ParsedURLString, url);
+ NSMutableDictionary *movieAttributes = commonMovieAttributes();
+ [movieAttributes setValue:cocoaURL forKey:QTMovieURLAttribute];
#if !defined(BUILDING_ON_LEOPARD)
CFDictionaryRef proxySettings = CFNetworkCopySystemProxySettings();
@@ -291,6 +305,33 @@ void MediaPlayerPrivateQTKit::createQTMovie(const String& url)
createQTMovie(cocoaURL, movieAttributes);
}
+void MediaPlayerPrivateQTKit::createQTMovie(ApplicationCacheResource* resource)
+{
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ ASSERT(resource);
+
+ NSMutableDictionary *movieAttributes = commonMovieAttributes();
+ [movieAttributes setObject:[NSNumber numberWithBool:YES] forKey:@"QTMovieOpenForPlaybackAttribute"];
+
+ // ApplicationCacheResources can supply either a data pointer, or a path to a locally cached
+ // flat file. We would prefer the path over the data, but QTKit can handle either:
+ String localPath = resource->path();
+ NSURL* cocoaURL = !localPath.isEmpty() ? [NSURL fileURLWithPath:localPath isDirectory:NO] : nil;
+ if (cocoaURL)
+ [movieAttributes setValue:cocoaURL forKey:QTMovieURLAttribute];
+ else {
+ NSData* movieData = resource->data()->createNSData();
+ [movieAttributes setValue:movieData forKey:QTMovieDataAttribute];
+ [movieData release];
+ }
+
+ createQTMovie(cocoaURL, movieAttributes);
+
+#else
+ ASSERT_NOT_REACHED();
+#endif
+}
+
static void disableComponentsOnce()
{
static bool sComponentsDisabled = false;
@@ -658,6 +699,14 @@ void MediaPlayerPrivateQTKit::loadInternal(const String& url)
[m_objcObserver.get() setDelayCallbacks:YES];
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ Frame* frame = m_player->frameView() ? m_player->frameView()->frame() : NULL;
+ ApplicationCacheHost* cacheHost = frame ? frame->loader()->documentLoader()->applicationCacheHost() : NULL;
+ ApplicationCacheResource* resource = NULL;
+ if (cacheHost && cacheHost->shouldLoadResourceFromApplicationCache(ResourceRequest(url), resource) && resource)
+ createQTMovie(resource);
+ else
+#endif
createQTMovie(url);
[m_objcObserver.get() loadStateChanged:nil];
@@ -827,8 +876,19 @@ IntSize MediaPlayerPrivateQTKit::naturalSize() const
// 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());
+ FloatSize naturalSize([[m_qtMovie.get() attributeForKey:QTMovieNaturalSizeAttribute] sizeValue]);
+ if (naturalSize.isEmpty() && m_isStreaming) {
+ // HTTP Live Streams will occasionally return {0,0} natural sizes while scrubbing.
+ // Work around this problem (<rdar://problem/9078563>) by returning the last valid
+ // cached natural size:
+ naturalSize = m_cachedNaturalSize;
+ } else {
+ // Unfortunately, due to another QTKit bug (<rdar://problem/9082071>) we won't get a sizeChanged
+ // event when this happens, so we must cache the last valid naturalSize here:
+ m_cachedNaturalSize = naturalSize;
+ }
+
+ return IntSize(naturalSize.width() * m_scaleFactor.width(), naturalSize.height() * m_scaleFactor.height());
}
bool MediaPlayerPrivateQTKit::hasVideo() const
diff --git a/Source/WebCore/platform/graphics/mac/SimpleFontDataCoreText.cpp b/Source/WebCore/platform/graphics/mac/SimpleFontDataCoreText.cpp
index 452bd54..832bb9d 100644
--- a/Source/WebCore/platform/graphics/mac/SimpleFontDataCoreText.cpp
+++ b/Source/WebCore/platform/graphics/mac/SimpleFontDataCoreText.cpp
@@ -39,15 +39,17 @@ using namespace std;
namespace WebCore {
-CFDictionaryRef SimpleFontData::getCFStringAttributes(TypesettingFeatures typesettingFeatures) const
+CFDictionaryRef SimpleFontData::getCFStringAttributes(TypesettingFeatures typesettingFeatures, FontOrientation orientation) const
{
unsigned key = typesettingFeatures + 1;
pair<HashMap<unsigned, RetainPtr<CFDictionaryRef> >::iterator, bool> addResult = m_CFStringAttributes.add(key, RetainPtr<CFDictionaryRef>());
RetainPtr<CFDictionaryRef>& attributesDictionary = addResult.first->second;
if (!addResult.second)
return attributesDictionary.get();
+
+ bool treatLineAsVertical = orientation == Vertical;
- bool allowLigatures = (orientation() == Horizontal && platformData().allowsLigatures()) || (typesettingFeatures & Ligatures);
+ bool allowLigatures = (!treatLineAsVertical && platformData().allowsLigatures()) || (typesettingFeatures & Ligatures);
static const int ligaturesNotAllowedValue = 0;
static CFNumberRef ligaturesNotAllowed = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &ligaturesNotAllowedValue);
@@ -60,13 +62,13 @@ CFDictionaryRef SimpleFontData::getCFStringAttributes(TypesettingFeatures typese
static CFNumberRef kerningAdjustment = CFNumberCreate(kCFAllocatorDefault, kCFNumberFloatType, &kerningAdjustmentValue);
static const void* keysWithKerningDisabled[] = { kCTFontAttributeName, kCTKernAttributeName, kCTLigatureAttributeName, kCTVerticalFormsAttributeName };
const void* valuesWithKerningDisabled[] = { platformData().ctFont(), kerningAdjustment, allowLigatures
- ? ligaturesAllowed : ligaturesNotAllowed, orientation() == Vertical ? kCFBooleanTrue : kCFBooleanFalse };
+ ? ligaturesAllowed : ligaturesNotAllowed, treatLineAsVertical ? kCFBooleanTrue : kCFBooleanFalse };
attributesDictionary.adoptCF(CFDictionaryCreate(0, keysWithKerningDisabled, valuesWithKerningDisabled,
WTF_ARRAY_LENGTH(keysWithKerningDisabled), &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
} else {
// By omitting the kCTKernAttributeName attribute, we get Core Text's standard kerning.
static const void* keysWithKerningEnabled[] = { kCTFontAttributeName, kCTLigatureAttributeName, kCTVerticalFormsAttributeName };
- const void* valuesWithKerningEnabled[] = { platformData().ctFont(), allowLigatures ? ligaturesAllowed : ligaturesNotAllowed, orientation() == Vertical ? kCFBooleanTrue : kCFBooleanFalse };
+ const void* valuesWithKerningEnabled[] = { platformData().ctFont(), allowLigatures ? ligaturesAllowed : ligaturesNotAllowed, treatLineAsVertical ? kCFBooleanTrue : kCFBooleanFalse };
attributesDictionary.adoptCF(CFDictionaryCreate(0, keysWithKerningEnabled, valuesWithKerningEnabled,
WTF_ARRAY_LENGTH(keysWithKerningEnabled), &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
}
diff --git a/Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm b/Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
index 3094498..cd34000 100644
--- a/Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
+++ b/Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
@@ -259,49 +259,32 @@ void SimpleFontData::platformInit()
descent = 3;
}
- if (m_orientation == Vertical) {
- // Ignore vertical orientation when the font doesn't support vertical metrics.
+ if (platformData().orientation() == Vertical && !isTextOrientationFallback()) {
// The check doesn't look neat but this is what AppKit does for vertical writing...
RetainPtr<CFArrayRef> tableTags(AdoptCF, CTFontCopyAvailableTables(m_platformData.ctFont(), kCTFontTableOptionExcludeSynthetic));
CFIndex numTables = CFArrayGetCount(tableTags.get());
- bool found = false;
for (CFIndex index = 0; index < numTables; ++index) {
CTFontTableTag tag = (CTFontTableTag)(uintptr_t)CFArrayGetValueAtIndex(tableTags.get(), index);
if (tag == kCTFontTableVhea || tag == kCTFontTableVORG) {
- found = true;
+ m_hasVerticalGlyphs = true;
break;
}
}
-
- if (found == false)
- m_orientation = Horizontal;
}
float xHeight;
- // Measure the actual character "x", because AppKit synthesizes X height rather than getting it from the font.
- // Unfortunately, NSFont will round this for us so we don't quite get the right value.
- GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page();
- NSGlyph xGlyph = glyphPageZero ? glyphPageZero->glyphDataForCharacter('x').glyph : 0;
- if (xGlyph) {
- CGRect xBox = platformBoundsForGlyph(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.
- xHeight = static_cast<float>(max(CGRectGetMaxX(xBox), -CGRectGetMinY(xBox)));
- } else {
-#ifndef BUILDING_ON_TIGER
- xHeight = static_cast<float>(CGFontGetXHeight(m_platformData.cgFont())) / unitsPerEm;
-#else
- xHeight = m_platformData.font() ? [m_platformData.font() xHeight] : 0;
-#endif
- // CGFontGetXHeight() returns a wrong value for "Apple Symbols" font (a float close to 0, but not strictly 0).
- // The following code makes a guess for xHeight in that case.
- // The int cast is a workaround for the "almost" zero value returned by CGFontGetXHeight().
- if (!static_cast<int>(xHeight) && ascent)
- xHeight = 2 * ascent / 3;
- }
+ if (platformData().orientation() == Horizontal) {
+ // Measure the actual character "x", since it's possible for it to extend below the baseline, and we need the
+ // reported x-height to only include the portion of the glyph that is above the baseline.
+ GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page();
+ NSGlyph xGlyph = glyphPageZero ? glyphPageZero->glyphDataForCharacter('x').glyph : 0;
+ if (xGlyph)
+ xHeight = -CGRectGetMinY(platformBoundsForGlyph(xGlyph));
+ else
+ xHeight = scaleEmToUnits(CGFontGetXHeight(m_platformData.cgFont()), unitsPerEm) * pointSize;
+ } else
+ xHeight = verticalRightOrientationFontData()->fontMetrics().xHeight();
m_fontMetrics.setUnitsPerEm(unitsPerEm);
m_fontMetrics.setAscent(ascent);
@@ -474,17 +457,8 @@ void SimpleFontData::determinePitch()
FloatRect SimpleFontData::platformBoundsForGlyph(Glyph glyph) const
{
FloatRect boundingBox;
-#ifndef BUILDING_ON_TIGER
- boundingBox = CTFontGetBoundingRectsForGlyphs(m_platformData.ctFont(),
- orientation() == Vertical ? kCTFontVerticalOrientation : kCTFontHorizontalOrientation, &glyph, 0, 1);
+ boundingBox = CTFontGetBoundingRectsForGlyphs(m_platformData.ctFont(), platformData().orientation() == Vertical ? kCTFontVerticalOrientation : kCTFontHorizontalOrientation, &glyph, 0, 1);
boundingBox.setY(-boundingBox.maxY());
-#else
- // FIXME: Custom fonts don't have NSFonts, so this function doesn't compute correct bounds for these on Tiger.
- if (!m_platformData.font())
- return boundingBox;
- boundingBox = [m_platformData.font() boundingRectForGlyph:glyph];
- boundingBox.setY(-boundingBox.maxY());
-#endif
if (m_syntheticBoldOffset)
boundingBox.setWidth(boundingBox.width() + m_syntheticBoldOffset);
@@ -494,7 +468,7 @@ FloatRect SimpleFontData::platformBoundsForGlyph(Glyph glyph) const
float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
{
CGSize advance;
- if (orientation() == Horizontal || m_isBrokenIdeographFont) {
+ if (platformData().orientation() == Horizontal || m_isBrokenIdeographFallback) {
NSFont* font = platformData().font();
float pointSize = platformData().m_size;
CGAffineTransform m = CGAffineTransformMakeScale(pointSize, pointSize);
diff --git a/Source/WebCore/platform/graphics/mac/WebLayer.h b/Source/WebCore/platform/graphics/mac/WebLayer.h
index 30bf55b..2e9bea0 100644
--- a/Source/WebCore/platform/graphics/mac/WebLayer.h
+++ b/Source/WebCore/platform/graphics/mac/WebLayer.h
@@ -32,6 +32,7 @@
namespace WebCore {
class GraphicsLayer;
+ class PlatformCALayer;
class PlatformCALayerClient;
}
@@ -48,7 +49,7 @@ namespace WebCore {
@end
// Functions allows us to share implementation across WebTiledLayer and WebLayer
-void drawLayerContents(CGContextRef, CALayer *, WebCore::PlatformCALayerClient*);
+void drawLayerContents(CGContextRef, CALayer *, WebCore::PlatformCALayer*);
void setLayerNeedsDisplayInRect(CALayer *, WebCore::PlatformCALayerClient*, CGRect);
#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/mac/WebLayer.mm b/Source/WebCore/platform/graphics/mac/WebLayer.mm
index 414a75f..c9705d0 100644
--- a/Source/WebCore/platform/graphics/mac/WebLayer.mm
+++ b/Source/WebCore/platform/graphics/mac/WebLayer.mm
@@ -40,8 +40,9 @@ using namespace WebCore;
@implementation WebLayer
-void drawLayerContents(CGContextRef context, CALayer *layer, WebCore::PlatformCALayerClient* layerContents)
+void drawLayerContents(CGContextRef context, CALayer *layer, WebCore::PlatformCALayer* platformLayer)
{
+ WebCore::PlatformCALayerClient* layerContents = platformLayer->owner();
if (!layerContents)
return;
@@ -62,6 +63,7 @@ void drawLayerContents(CGContextRef context, CALayer *layer, WebCore::PlatformCA
GraphicsContext graphicsContext(context);
graphicsContext.setIsCALayerContext(true);
+ graphicsContext.setIsAcceleratedContext(platformLayer->acceleratesDrawing());
if (!layerContents->platformCALayerContentsOpaque()) {
// Turn off font smoothing to improve the appearance of text rendered onto a transparent background.
@@ -167,7 +169,7 @@ void setLayerNeedsDisplayInRect(CALayer *layer, WebCore::PlatformCALayerClient*
{
PlatformCALayer* layer = PlatformCALayer::platformCALayer(self);
if (layer)
- drawLayerContents(context, self, layer->owner());
+ drawLayerContents(context, self, layer);
}
@end // implementation WebLayer
diff --git a/Source/WebCore/platform/graphics/mac/WebTiledLayer.mm b/Source/WebCore/platform/graphics/mac/WebTiledLayer.mm
index e9fa5b7..9bcdd54 100644
--- a/Source/WebCore/platform/graphics/mac/WebTiledLayer.mm
+++ b/Source/WebCore/platform/graphics/mac/WebTiledLayer.mm
@@ -83,7 +83,7 @@ using namespace WebCore;
{
PlatformCALayer* layer = PlatformCALayer::platformCALayer(self);
if (layer)
- drawLayerContents(context, self, layer->owner());
+ drawLayerContents(context, self, layer);
}
@end // implementation WebTiledLayer